views:

945

answers:

4

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;
+1  A: 

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.

Dave Sherohman
On the Centos 5 installation I am working with, there does not appear to be a "deluser" installed on the system. I am currently looking for it in the repositories. I have started working on a perl script, but it will probably take me an hour or two to get the perl side of my brain spooled back up.
Loren Charnley
Apparently deluser is Debian specific.
Loren Charnley
+2  A: 

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.

J.J.
+1  A: 

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.

innaM
+2  A: 

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...

Dave,Amazing - who'd thunk that the command would look like a password utility ...Thanks!Loren
Loren Charnley