unixgroups.in 2.72 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
#!/usr/bin/perl -w
use English;
use Getopt::Std;
use strict;

#
# Configure variables
#
use lib '@prefix@/lib';
use libdb;

my $TB        = "@prefix@";
my $SETGROUPS = "$TB/sbin/setgroups";

#
# Turn off line buffering on output
#
$| = 1;

#
# Only root or admin types!
# 
if (($UID != 0) && (!TBAdmin($UID))) {
    die("Only root or TB administrators can control UNIX groups.\n");
}

#
# Proccess command-line args
#
my %opt = ();
getopts('rhpa',\%opt);

my ($uid, @gid);
if ($opt{a} || $opt{r}) {
    if (@ARGV < 2) {
	die "Not enough arguments - see '$0 -h' for help\n";
    }
    $uid = shift @ARGV;
    @gid = @ARGV;
} else {
    if (@ARGV != 0) {
	die "Too many arguments - see '$0 -h' for help\n";
    }
}

if ($opt{p}) {
    #
    # Print out groups in a format that looks vaguely like the /etc/group
    # format
    #
    my %members = ();
    my $result = DBQueryFatal("SELECT gid,uid FROM unixgroup_membership");
    while (my ($gid,$uid) = $result->fetchrow() ) {
	push @{$members{$gid}},$uid;
    }

    while (my ($gid,$members) = each %members) {
	print "$gid:" . join(",",@$members) . "\n";
    }
} elsif ($opt{a}) {
    #
    # Add a user to the database
    #
    foreach my $gid (@gid) {
	print "Adding user $uid to group $gid in the database\n";
	if (checkGroup($uid,$gid)) {
	    warn "User $uid is already in group $gid, skipping ...\n";
	    next;
	} else {
	    DBQueryFatal("INSERT INTO unixgroup_membership SET uid='$uid', " .
	    			"gid='$gid'");
	}
    }

    print "Updating groups for $uid on control nodes\n";
    if (system "$SETGROUPS $uid" ) {
	warn "Group update for $uid failed\n";
    }

} elsif ($opt{r}) {
    #
    # Remove a user from the database
    #
    foreach my $gid (@gid) {
	print "Removing $uid from group $gid in the database\n";
	if (!checkGroup($uid,$gid)) {
	    warn "User $uid is not in group $gid, skipping ...\n";
	    next;
	} else {
	    DBQueryFatal("DELETE FROM unixgroup_membership WHERE uid='$uid' " .
	    			"AND gid='$gid'");
	}
    }
    
    print "Updating groups for $uid on control nodes\n";
    if (system "$SETGROUPS $uid" ) {
	warn "Group update for $uid failed\n";
    }

} else {
    #
    # Usage message
    #
    warn "Usage: $0 <-h | -p | < <-a | -r> uid gid...> >\n";
    warn "-h            This message\n";
    warn "-p            Print group information\n";
    warn "-a uid gid... Add a user to one (or more) groups\n";
    warn "-r uid gid... Remove a user from one (or more) groups\n";
    exit(-1);
}


#
# Check to see if the given uid is in the given gid. Return 1 if it is, 0
# if not.
#
sub checkGroup ($$) {
    my ($uid,$gid) = @_;
    my $result = DBQueryFatal("SELECT gid,uid FROM unixgroup_membership WHERE ".
				"uid='$uid' AND gid='$gid'");
    return ($result->num_rows() > 0);
}