rmacct-ctrl.in 3.32 KB
Newer Older
1 2
#!/usr/local/bin/perl -wT
use English;
3 4 5 6 7 8 9 10 11

#
# Delete accounts. Note that groups are not deleted until a project is
# deleted via rmproj script.
#
# XXX - The control node is hardwired. Look for $CONTROL.
#
# usage: rmacct-ctrl <userid>
# 
12

13 14 15
#
# Configure variables
#
16 17 18 19
my $TB      = "@prefix@";
my $TBOPS   = "@TBOPSEMAIL@";

my $HOMEDIR = "/users";
Robert Ricci's avatar
Robert Ricci committed
20
my $SSH     = "$TB/bin/sshtb";
21 22
my $CONTROL = "users.emulab.net";
my $USERDEL = "/usr/sbin/pw userdel";
23
my $GENELISTS = "$TB/sbin/genelists";
24 25 26

my $user;
my $query_result;
27

28 29 30 31 32 33
#
# We don't want to run this script unless its the real version.
#
if ($EUID != 0) {
    die("Must be root! Maybe its a development version?");
}
34

35 36 37 38 39
#
# Untaint the path
# 
$ENV{'PATH'} = "/bin:/usr/bin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
40

41 42 43 44
#
# Turn off line buffering on output
#
$| = 1;
45

46
# Load the Testbed support stuff. 
47 48 49
use lib "@prefix@/lib";
use libdb;
use libtestbed;
50

51 52 53 54 55 56 57
#
# Check args.
#
if ($#ARGV < 0) {
    die("Usage: rmacct-ctrl <userid>\n");
}
$user = $ARGV[0];
58

59 60 61 62 63 64 65 66
#
# Untaint the argument.
#
if ($user =~ /^([a-z0-9]+)$/i) {
    $user = $1;
}
else {
    die("Invalid uid '$user' contains illegal characters.\n");
67 68 69
}

#
70
# Figure out who called us. Possible scenarios:
71
#
72 73
# 1) Called from web UI as some TB admin user to create a project head's 
#    account for a new project.
74
#
75 76
# 2) Called as user with group_root for project to create a user
#    account.
77 78
#
# 3) Called from command line as user with group_root for project 
79
#    to create a user account. 
80 81 82
# 
# 4) Called from command line as root.
#
83 84 85
if ($UID && !TBAdmin($UID)) {
    my ($me) = getpwuid($UID) or
	fatal("$UID not in passwd file");
86 87

    #
88
    # Check if group_root for the project.
89
    #
90 91 92 93 94
    $query_result =
	DBQueryFatal("select p1.trust from proj_memb as p1 ".
		     "left join proj_memb as p2 on p2.pid=p1.pid ".
		     "where p1.uid='$me' and ".
		     "p2.uid='$user' and p1.trust='group_root'");
95

96 97
    if ($query_result->numrows == 0) {
	die("$0: $me does not have enough permission in ${user}'s project");
98 99 100
    }
}

101 102 103 104 105 106 107
#
# Run genelists to update the email lists. This is a convenient
# spot to do this. Errors are non-fatal; the testbed list will
# will find out about problems via email from genelists.
#
system("$GENELISTS");

108 109
#
# Note hardwired control node. 
110
# 
111
my $control_node = $CONTROL;
112

113 114 115 116 117 118
#
# Remove user from both local and control node. We assume FreeBSD on both.
# 
# All this stuff must be done as root (ssh).
#
$UID = $EUID;
119

120 121 122
print "Removing user $user from local node.\n";
if (system("$USERDEL $user")) {
    fatal("Could not remove user $user from local node.");
123 124
}

125 126 127 128
print "Removing user $user from $control_node.\n";
if (system("$SSH $control_node '$USERDEL $user'")) {
    fatal("Could not remove user $user from $control_node.\n");
}
129

130 131 132 133
#
# Rename the user directory instead of deleting it.
# 
my $newname = "$HOMEDIR/$user-" . `date +20%y%m%d-%H.%M.%S`;
134

135 136 137 138 139 140 141 142 143
#
# Untaint the new name since it was constructed with date. Dopey.
#
if ($newname =~ /^([-\w.\/]+)$/) {
    $newname = $1;
}
else {
    fatal("Tainted newname $newname");
}
144

145 146 147
if (! -e "$HOMEDIR/$user") {
    fatal("User directory '$HOMEDIR/$user' does not exist!");
}
148

149 150
if (! rename("$HOMEDIR/$user", $newname)) {
    fatal("Could not rename user directory $user to $newname: $!");
151 152
}

153
exit(0);
154

155 156
sub fatal {
    local($msg) = $_[0];
157

158 159
    SENDMAIL($TBOPS, "TESTBED: rmacct-ctrl Failed", $msg);
    die("$0: $msg");
160
}