unixgroups.in 3.79 KB
Newer Older
1
#!/usr/bin/perl -w
Leigh Stoller's avatar
Leigh Stoller committed
2 3

#
4
# Copyright (c) 2000-2002, 2010 University of Utah and the Flux Group.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
Leigh Stoller's avatar
Leigh Stoller committed
24
#
25 26 27 28
use English;
use Getopt::Std;
use strict;

29 30 31 32 33
#
# Function prototypes
#
sub checkGroup ($$);

34 35 36 37 38
#
# Configure variables
#
use lib '@prefix@/lib';
use libdb;
39
use User;
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

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);

62
my ($uid, $uid_idx, @gid);
63 64 65 66 67 68
if ($opt{a} || $opt{r}) {
    if (@ARGV < 2) {
	die "Not enough arguments - see '$0 -h' for help\n";
    }
    $uid = shift @ARGV;
    @gid = @ARGV;
69 70 71 72 73 74

    my $target_user = User->Lookup($uid);
    if (!defined($target_user)) {
	die "No such active user $uid exists\n";
    }
    $uid_idx = $target_user->uid_idx();
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
} 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";
101
	if (checkGroup($uid_idx,$gid)) {
102 103 104
	    warn "User $uid is already in group $gid, skipping ...\n";
	    next;
	} else {
105 106
	    DBQueryFatal("INSERT INTO unixgroup_membership SET ".
			 "  uid='$uid', uid_idx='$uid_idx', gid='$gid'");
107 108 109 110 111 112 113 114 115 116 117 118 119 120
	}
    }

    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";
121
	if (!checkGroup($uid_idx,$gid)) {
122 123 124
	    warn "User $uid is not in group $gid, skipping ...\n";
	    next;
	} else {
125 126
	    DBQueryFatal("DELETE FROM unixgroup_membership ".
			 "WHERE uid_idx='$uid_idx' AND gid='$gid'");
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
	}
    }
    
    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 ($$) {
153 154
    my ($uid_idx,$gid) = @_;
    
155
    my $result = DBQueryFatal("SELECT gid,uid FROM unixgroup_membership WHERE ".
156
				"uid_idx='$uid_idx' AND gid='$gid'");
157 158
    return ($result->num_rows() > 0);
}