All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

rmgroup.in 7.06 KB
Newer Older
1
#!/usr/bin/perl -wT
Leigh B. Stoller's avatar
Leigh B. Stoller committed
2
#
3
# Copyright (c) 2000-2018 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{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 B. Stoller's avatar
Leigh B. Stoller committed
23
#
Leigh B. Stoller's avatar
Leigh B. Stoller committed
24
use English;
25
use strict;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
26 27 28

#
# Remove a group. We delete the group directory and the we remove the
29 30 31 32 33 34 35
# 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()
{
36
    print STDOUT "Usage: rmgroup <gid>\n";
37 38
    exit(-1);
}
39
sub fatal($);
40 41
my  $optlist = "";

Leigh B. Stoller's avatar
Leigh B. Stoller committed
42
#
43
# We don't want to run this script unless its the real version.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
44
#
45 46 47 48 49 50 51 52 53 54 55 56 57
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
58 59 60 61

#
# Configure variables
#
62 63 64 65
my $TB            = "@prefix@";
my $TBOPS         = "@TBOPSEMAIL@";
my $CONTROL       = "@USERNODE@";
my $BOSSNODE      = "@BOSSNODE@";
66
my $ELABINELAB    = @ELABINELAB@;
67
my $MAILMANSUPPORT= @MAILMANSUPPORT@;
68 69
my $BUGDBSUPPORT  = @BUGDBSUPPORT@;
my $OPSDBSUPPORT  = @OPSDBSUPPORT@;
70
my $OPSVM_ENABLE  = @OPSVM_ENABLE@;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
71

72 73 74 75 76
my $SSH           = "$TB/bin/sshtb";
my $GROUPDEL      = "/usr/sbin/pw groupdel";
my $DELMMLIST     = "$TB/sbin/delmmlist";
my $MODGROUPS     = "$TB/sbin/modgroups";
my $OPSDBCONTROL  = "$TB/sbin/opsdb_control";
77
my $ACCOUNTPROXY  = "$TB/sbin/accountsetup";
78
my $EXPORTSSETUP  = "$TB/sbin/exports_setup";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94

#
# 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";
95
use libaudit;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
96
use libdb;
97
use emutil;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
98
use libtestbed;
Mike Hibler's avatar
Mike Hibler committed
99
use User;
100
use Project;
Mike Hibler's avatar
Mike Hibler committed
101
use Group;
102
use EmulabFeatures;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
103

104
# Defined in libtestbed;
105 106 107
my $PROJROOT    = PROJROOT();
my $GRPROOT     = GROUPROOT();

Leigh B. Stoller's avatar
Leigh B. Stoller committed
108 109 110
#
# Check args.
#
111
if (@ARGV != 1) {
112
    usage();
Leigh B. Stoller's avatar
Leigh B. Stoller committed
113 114
}

115 116 117 118
# Map invoking user to object.
my $this_user = User->ThisUser();
if (! defined($this_user)) {
    fatal("You ($UID) do not exist!");
Leigh B. Stoller's avatar
Leigh B. Stoller committed
119
}
120 121 122 123 124 125 126 127
my $user_name  = $this_user->name();
my $user_email = $this_user->email();
my $user_uid   = $this_user->uid();

# Map the group to its object.
my $group = Group->Lookup($ARGV[0]);
if (!defined($group)) {
    fatal("Could not lookup group object for $ARGV[0]");
Leigh B. Stoller's avatar
Leigh B. Stoller committed
128
}
129
my $project    = $group->GetProject();
130 131 132 133 134
my $unix_gid   = $group->unix_gid();
my $unix_name  = $group->unix_name();
my $pid        = $group->pid();
my $gid        = $group->gid();
my $gid_idx    = $group->gid_idx();
Leigh B. Stoller's avatar
Leigh B. Stoller committed
135 136

#
137
# Figure out who called us. 
Leigh B. Stoller's avatar
Leigh B. Stoller committed
138
#
139
if (!TBAdmin()) {
140 141 142 143
    #
    # Only admin types can remove the project group. Typically, you won't
    # do this directly, but use rmproj instead.
    #
144
    if ($group->IsProjectGroup()) {
145 146 147
	die("*** $0:\n".
	    "    You do not have permission to remove a project group!\n");
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
148

149
    if (! $group->AccessCheck($this_user, TB_PROJECT_DELGROUP())) {
150
	die("*** $0:\n".
151
	    "    You do not have permission to remove group $group!\n");
Leigh B. Stoller's avatar
Leigh B. Stoller committed
152 153 154 155
    }
}

#
156 157 158 159 160 161 162
# 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
163 164
}

165
#
166
# Removing group-related directories is handled by accountsetup on ops.
167
#
Leigh B. Stoller's avatar
Leigh B. Stoller committed
168

169 170 171
#
# Remove all members from the group.
# If there was an error, the DB state is left so that this script can
172
# be run again.
173 174 175 176
#
# Must find out what users/groups to delete so that we can pass off to
# modgroups.
#
177 178 179 180
my @userlist = ();
$group->MemberList(\@userlist,
		   $Group::MEMBERLIST_FLAGS_ALLUSERS |
		   $Group::MEMBERLIST_FLAGS_UIDSONLY);
181

182
foreach my $uid (@userlist) {
183 184 185 186 187 188 189 190
    # For perl
    $EUID = $UID;
    if (system("$MODGROUPS -r $pid:$gid $uid")) {
	fatal("$MODGROUPS -r $pid:$gid $uid failed!");
    }
    $EUID = 0;
}

191 192 193 194 195 196
# If the group isn't in /etc/group yet, it wasn't approved and created.
if (system("grep -q '^${unix_gid}:' /etc/group")) {
    #
    # Now remove the group from the group file on both plastic and paper.
    #
    print "Removing group $unix_name ($unix_gid) on local node.\n";
197

198
    if (runBusyLoop("$GROUPDEL $unix_name")) {
199 200 201
	if (($? >> 8) != 65) {
	    fatal("Could not remove group $unix_name from local node!");
	}
202
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
203

204 205
    if ($MAILMANSUPPORT && !$ELABINELAB) {
	my $listname = ($pid eq $gid ? "${pid}-users" : "${pid}-${gid}-users");
206

207 208 209 210 211 212
	# For perl
	$EUID = $UID;
	system("$DELMMLIST -a $listname") == 0 or
	    fatal("$DELMMLIST -a $listname failed!");
	$EUID = 0;
    }
213

214 215 216 217 218 219 220
    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
221

222 223 224 225
    #
    # Be real root for ssh.
    # 
    $UID = 0;
226

227
    if ($OPSVM_ENABLE) {
228
	if ($pid eq $gid) {
229 230 231 232
	    emutil::ClearNoDelete("$PROJROOT/$pid");
	    emutil::ClearNoDelete("$GRPROOT/$pid");
	    # Also the symlink.
	    emutil::ClearNoDelete("$GRPROOT/$pid/$pid");
233

234 235 236
	    foreach my $dir (@Project::PROJDIRECTORIES) {
		emutil::ClearNoDelete("$PROJROOT/$pid/$dir");
	    }
237
	}
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
	else {
	    emutil::ClearNoDelete("$GRPROOT/$pid/$gid");
	    
	    foreach my $dir (@Project::GROUPDIRECTORIES) {
		emutil::ClearNoDelete("$GRPROOT/$pid/$gid/$dir")
	    }
	}
    }

    print "Removing group $unix_name ($unix_gid) on $CONTROL.\n";

    my $cmdstr;
    if ($pid eq $gid) {
	$cmdstr = "delproject $gid $unix_name";
    } else {
	$cmdstr = "delgroup $gid $unix_name $pid";
    }

    print "Removing group $unix_name ($unix_gid) on $CONTROL.\n";
    if (system("$SSH -host $CONTROL $ACCOUNTPROXY $cmdstr")) {
	fatal("Could not remove group $unix_name from $CONTROL!");
259
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
260

261 262 263 264 265
    #
    # Remove group on the tip servers. 
    #
    foreach my $tipserver ( TBTipServers() ) {
	print "Removing group $unix_name ($unix_gid) on $tipserver.\n";
266

267 268 269 270
	if (system("$SSH -host $tipserver $GROUPDEL $unix_name")) {
	    if (($? >> 8) != 65) {
		fatal("Could not remove group $unix_name from $tipserver!");
	    }
271
	}
272 273 274
    }
}

275 276 277 278 279 280
#
# Kill any features
#
EmulabFeatures->DeleteAll($group) == 0 or
    fatal("Could not delete all features for $group");

281 282 283
# Last step, so we can repeat above actions on failures.
$group->Delete() == 0 or
    fatal("Could not delete group $group");
284

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

288 289 290 291 292 293
sub fatal($) {
    my($mesg) = $_[0];

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