rmgroup.in 5.99 KB
Newer Older
1
#!/usr/bin/perl -wT
Leigh B. Stoller's avatar
Leigh B. Stoller committed
2 3 4

#
# EMULAB-COPYRIGHT
5
# Copyright (c) 2000-2006 University of Utah and the Flux Group.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
6 7 8
# All rights reserved.
#

Leigh B. Stoller's avatar
Leigh B. Stoller committed
9 10 11 12
use English;

#
# Remove a group. We delete the group directory and the we remove the
13 14 15 16 17 18 19 20 21 22
# group from /etc/group. Actually, the group directory is *renamed*
# since we do not want to be so destructive. This scrip can be called
# with pid=gid, but in that case it has to be a tbadmin, and the
# directory is not renamed. The caller (rmproj) is responsible for that.
#
sub usage()
{
    print STDOUT "Usage: rmgroup <pid> <gid>\n";
    exit(-1);
}
23
sub fatal($);
24 25
my  $optlist = "";

Leigh B. Stoller's avatar
Leigh B. Stoller committed
26
#
27
# We don't want to run this script unless its the real version.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
28
#
29 30 31 32 33 34 35 36 37 38 39 40 41
if ($EUID != 0) {
    die("*** $0:\n".
	"    Must be setuid! Maybe its a development version?\n");
}

#
# This script is setuid, so please do not run it as root. Hard to track
# what has happened.
# 
if ($UID == 0) {
    die("*** $0:\n".
	"    Please do not run this as root! Its already setuid!\n");
}
Leigh B. Stoller's avatar
Leigh B. Stoller committed
42 43 44 45 46 47 48

#
# Configure variables
#
my $TB       = "@prefix@";
my $TBOPS    = "@TBOPSEMAIL@";
my $CONTROL  = "@USERNODE@";
49
my $BOSSNODE = "@BOSSNODE@";
50
my $ELABINELAB    = @ELABINELAB@;
51
my $MAILMANSUPPORT= @MAILMANSUPPORT@;
52 53
my $BUGDBSUPPORT  = @BUGDBSUPPORT@;
my $OPSDBSUPPORT  = @OPSDBSUPPORT@;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
54 55

my $PROJROOT = "/proj";
56
my $GRPROOT  = "/groups";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
57 58
my $SSH      = "$TB/bin/sshtb";
my $GROUPDEL = "/usr/sbin/pw groupdel";
59
my $DELMMLIST= "$TB/sbin/delmmlist";
60
my $MODGROUPS= "$TB/sbin/modgroups";
61
my $OPSDBCONTROL= "$TB/sbin/opsdb_control";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

#
# Untaint the path
# 
$ENV{'PATH'} = "/bin:/usr/bin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

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

#
# Load the Testbed support stuff. 
#
use lib "@prefix@/lib";
78
use libaudit;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
79 80 81 82 83 84 85
use libdb;
use libtestbed;

#
# Check args.
#
if (@ARGV != 2) {
86
    usage();
Leigh B. Stoller's avatar
Leigh B. Stoller committed
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
}
my $pid = $ARGV[0];
my $gid = $ARGV[1];

#
# Untaint the argument.
#
if ($pid =~ /^([-\@\w.]+)$/) {
    $pid = $1;
}
else {
    die("*** Invalid pid '$pid' contains illegal characters.\n");
}

if ($gid =~ /^([-\@\w.]+)$/) {
    $gid = $1;
}
else {
    die("*** Invalid gid '$gid' contains illegal characters.\n");
}

#
109
# Figure out who called us. 
Leigh B. Stoller's avatar
Leigh B. Stoller committed
110
#
111 112 113 114 115 116 117 118 119 120
if (!TBAdmin($UID)) {
    #
    # Only admin types can remove the project group. Typically, you won't
    # do this directly, but use rmproj instead.
    #
    if ($pid eq $gid) {
	die("*** $0:\n".
	    "    You do not have permission to remove a project group!\n");
    }
    
Leigh B. Stoller's avatar
Leigh B. Stoller committed
121 122 123
    my $dbuid;

    if (! UNIX2DBUID($UID, \$dbuid)) {
124 125
	die("*** $0:\n".
	    "    You are not a valid emulab user!\n");
Leigh B. Stoller's avatar
Leigh B. Stoller committed
126 127
    }

128
    if (! TBProjAccessCheck($dbuid, $pid, $pid, TB_PROJECT_DELGROUP())) {
129
	die("*** $0:\n".
130
	    "    You do not have permission to remove a project group!\n");
Leigh B. Stoller's avatar
Leigh B. Stoller committed
131 132 133 134 135 136 137 138 139 140 141 142 143 144
    }
}

#
# Unix info for the group
#
my $unix_gid;
my $unix_name;

if (! TBGroupUnixInfo($pid, $gid, \$unix_gid, \$unix_name)) {
    die("*** No info for project/group $pid/$gid!");
}

#
145 146 147 148 149 150 151
# This script is always audited. Mail is sent automatically upon exit.
#
if (AuditStart(0)) {
    #
    # Parent exits normally
    #
    exit(0);
Leigh B. Stoller's avatar
Leigh B. Stoller committed
152 153
}

154 155 156 157 158 159 160 161
#
# Rename the group directory as long as its not the proj directory!
#
if ($pid ne $gid) {
    my $groupdir  = "$GRPROOT/$pid";
    my $oldname   = "$groupdir/$gid";
    my $newname   = "$oldname-" . TBDateTimeFSSafe();
    my $grouplink = "$PROJROOT/$pid/groups/$gid";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
162

163 164
    if (-e $grouplink && !unlink($grouplink)) {
	fatal("Could not unlink $grouplink: $!");
Leigh B. Stoller's avatar
Leigh B. Stoller committed
165
    }
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184

    if (-e $oldname) {
	print "Renaming $oldname to $newname.\n";
    
	if (rename($oldname, $newname)) {
	    #
	    # Chown the owner/group to root and set the permissions so no
	    # one is allowed to look inside.
	    #
	    if (! chmod(0700, $newname)) {
		fatal("Could not chmod directory $newname to 0700: $!");
	    }
	    if (! chown(0, 0, $newname)) {
		fatal("Could not chown directory $newname to 0/0: $!");
	    }
	}
	else {
	    fatal("Could not rename $oldname to $newname: $!");
	}
Leigh B. Stoller's avatar
Leigh B. Stoller committed
185 186 187
    }
}

188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
#
# Remove all members from the group.
# If there was an error, the DB state is left so that this script can
# be run again!
#
# Must find out what users/groups to delete so that we can pass off to
# modgroups.
#
my $query_result =
    DBQueryFatal("select uid from group_membership ".
		 "where pid='$pid' and gid='$gid'");

while (my ($uid) = $query_result->fetchrow_array()) {
    # For perl
    $EUID = $UID;
    if (system("$MODGROUPS -r $pid:$gid $uid")) {
	fatal("$MODGROUPS -r $pid:$gid $uid failed!");
    }
    $EUID = 0;
}

Leigh B. Stoller's avatar
Leigh B. Stoller committed
209 210 211
#
# Now remove the group from the group file on both plastic and paper.
#
212 213
print "Removing group $unix_name ($unix_gid) on local node.\n";

Leigh B. Stoller's avatar
Leigh B. Stoller committed
214
if (system("$GROUPDEL $unix_name")) {
215 216 217
    if (($? >> 8) != 65) {
	fatal("Could not remove group $unix_name from local node!");
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
218 219
}

220
if ($MAILMANSUPPORT && !$ELABINELAB) {
221 222
    my $listname = ($pid eq $gid ? "${pid}-users" : "${pid}-${gid}-users");
    
223 224
    # For perl
    $EUID = $UID;
225 226
    system("$DELMMLIST -a $listname") == 0 or
	fatal("$DELMMLIST -a $listname failed!");
227 228 229
    $EUID = 0;
}

230 231 232 233 234 235 236 237
if ($OPSDBSUPPORT && !$ELABINELAB) {
    # For perl
    $EUID = $UID;
    system("$OPSDBCONTROL delgroup $pid $gid") == 0 or
	fatal("$OPSDBCONTROL delgroup $pid $gid failed!");
    $EUID = 0;
}

Leigh B. Stoller's avatar
Leigh B. Stoller committed
238 239 240 241 242
#
# Be real root for ssh.
# 
$UID = 0;

243 244
if ($CONTROL ne $BOSSNODE) {
    print "Removing group $unix_name ($unix_gid) on $CONTROL.\n";
245

246 247 248 249 250
    if (system("$SSH -host $CONTROL $GROUPDEL $unix_name")) {
	if (($? >> 8) != 65) {
	    fatal("Could not remove group $unix_name from $CONTROL!");
	}
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
251 252
}

253 254 255
#
# Remove group on the tip servers. 
#
256
foreach my $tipserver ( TBTipServers() ) {
257 258
    print "Removing group $unix_name ($unix_gid) on $tipserver.\n";

259
    if (system("$SSH -host $tipserver $GROUPDEL $unix_name")) {
260 261 262
	if (($? >> 8) != 65) {
	    fatal("Could not remove group $unix_name from $tipserver!");
	}
263 264 265
    }
}

266 267 268
DBQueryFatal("delete from group_stats ".
	     "where pid='$pid' and gid='$gid'");

269 270 271 272 273
DBQueryFatal("delete from groups ".
	     "where pid='$pid' and gid='$gid'");

print "Group $pid/$gid has been removed!\n";
exit(0);
Leigh B. Stoller's avatar
Leigh B. Stoller committed
274

275 276 277 278 279 280
sub fatal($) {
    my($mesg) = $_[0];

    die("*** $0:\n".
	"    $mesg\n");
}