Perl or Python script to remove user from group
Question
I am putting together a Samba-based server as a Primary Domain Controller, and ran into a cute little problem that should have been solved many times over. But a number of searches did not yield a result. I need to be able to remove an existing user from an existing group with a command line script. It appears that the usermod easily allows me to add a user to a supplementary group with this command:
usermod -a -G supgroup1,supgroup2 username
Without the "-a" option, if the user is currently a member of a group which is not listed, the user will be removed from the group. Does anyone have a perl (or Python) script that allows the specification of a user and group for removal? Am I missing an obvious existing command, or well-known solution forthis? Thanks in advance!
Thanks to J.J. for the pointer to the Unix::Group module, which is part of Unix-ConfigFile. It looks like the command deluser would do what I want, but was not in any of my existing repositories. I went ahead and wrote the perl script using the Unix:Group Module. Here is the script for your sysadmining pleasure.
#!/usr/bin/perl
#
# Usage: removegroup.pl login group
# Purpose: Removes a user from a group while retaining current primary and
# supplementary groups.
# Notes: There is a Debian specific utility that can do this called deluser,
# but I did not want any cross-distribution dependencies
#
# Date: 25 September 2008
# Validate Arguments (correct number, format etc.)
if ( ($#ARGV < 1) || (2 < $#ARGV) ) {
print "\nUsage: removegroup.pl login group\n\n";
print "EXIT VALUES\n";
print " The removeuser.pl script exits with the following values:\n\n";
print " 0 success\n\n";
print " 1 Invalid number of arguments\n\n";
print " 2 Login or Group name supplied greater than 16 characters\n\n";
print " 3 Login and/or Group name contains invalid characters\n\n";
exit 1;
}
# Check for well formed group and login names
if ((16 < length($ARGV[0])) ||(16 < length($ARGV[1])))
{
print "Usage: removegroup.pl login group\n";
print "ERROR: Login and Group names must be less than 16 Characters\n";
exit 2;
}
if ( ( $ARGV[0] !~ m{^[a-z_]+[a-z0-9_-]*$}) || ( $ARGV[0] !~ m{^[a-z_]+[a-z0-9_-]*$} ) )
{
print "Usage: removegroup.pl login group\n";
print "ERROR: Login and/or Group name contains invalid characters\n";
exit 3;
}
# Set some variables for readability
$login=$ARGV[0];
$group=$ARGV[1];
# Requires the GroupFile interface from perl-Unix-Configfile
use Unix::GroupFile;
$grp = new Unix::GroupFile "/etc/group";
$grp->remove_user("$group", "$login");
$grp->commit();
undef $grp;
exit 0;
Solution
Web Link: http://www.ibm.com/developerworks/linux/library/l-roadmap4/
To add members to the group, use the gpasswd command with the -a switch and the user id you wish to add:
gpasswd -a userid mygroup
Remove users from a group with the same command, but a -d switch rather than -a:
gpasswd -d userid mygroup
"man gpasswd" for more info...
I looked for ages to find this. Sometimes it takes too much effort not to reinvent the wheel...
OTHER TIPS
I found This for you. It should do what you need. As far as I can tell Perl does not have any built in functions for removing users from a group. It has several for seeing the group id of a user or process.
It looks like deluser --group [groupname] should do it.
If not, the groups command lists the groups that a user belongs to. It should be fairly straightforward to come up with some Perl to capture that list into an array (or map it into a hash), delete the unwanted group(s), and feed that back to usermod.
Here's a very simple little Perl script that should give you the list of groups you need:
my $user = 'user';
my $groupNoMore = 'somegroup';
my $groups = join ',', grep { $_ ne $groupNoMore } split /\s/, `groups $user`;
Getting and sanitizing the required arguments is left as an execrcise for the reader.