mkacct-ctrl 6.97 KB
Newer Older
1
2
#!/usr/local/bin/perl -wT

Kristin Wright's avatar
Kristin Wright committed
3
### $Id: mkacct-ctrl,v 1.8 2000-12-07 21:30:00 kwright Exp $
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
123
124

use English;
use Mysql;

my $me;                # alphanumeric username of $UID 

my $user;              # kwright
my $project;           # lkwbox
my $pid;               # 6009

my $dbh;               # database handle 
my $sth;               # statement handle
my @db_row;
my $db_query;

sanitize();
dbsetup();
check_credentials();
dowork();
exit(0);

sub dbsetup() {
    $dbh = Mysql->connect("localhost", "tbdb", "script", "none");
}

#
# Figure out who called us. There are 3 possible scenarios:
#
# 1) Called from web UI as some TB admin user from the database 
#    to create a project head's 
#    account for a new project (called from approveproject.php3). 
#
# 2) Called as user with group_root for project to create a user
#    account (from approveuser.php3).
#
# 3) Called from command line as user with group_root for project 
#    to create a user account. 
# 
# 4) Called from command line as root.
#
sub check_credentials() {

    print "Credential check: ";

    #
    # Make sure the UID is a valid UID in this machine's passwd file
    #
    my ($me) = getpwuid($UID) or die "$0: $UID not in passwd file";

    #
    # Check if we're root
    #
    if ($UID == 0) {
	print "Root user allowed.\n";
	return;
    } 
    
    #
    # User could be an admin user.
    #
    $sth    = $dbh->query("select admin from users where uid='$me'");
    @db_row = $sth->fetchrow_array();
    if ($db_row[0] == 1) {
	print "Testbed admin user allowed.\n";
	return;
    } 
    #
    # Last resort: check if group_root for $project
    #
    $db_query = "select trust from proj_memb where uid='$me' and pid='$project'";
    $sth      = $dbh->query($db_query);
    got_tuples($sth) or die "$0: Error selecting trust for $me in $project.\n";
    @db_row   = $sth->fetchrow_array();
    if ($db_row[0] eq "group_root") {
	print "Group_root privileges allowed.\n";
	return;
    }

    #
    # If  we're here, we do not have the correct credentials
    #
    print "Not root, a TB admin user, or group_root for $pid. Failed.\n";   
    exit(1);
}

### 
### Find the right control node. Create an account for given
### user with correct user info.
### 
sub dowork() {

    my $control_node;
    my $pswd;
    my $user_number;    # 1025
    my $fullname;       # Kristin Wright
    my $groupname;      # lkwbox (same as project)
    my $groupnumber;    # 6001

    #
    # Find control node.
    # Note: In the end, I simply assign to 'plastic' as control nodes
    #       not yet set in the database. 11/30/00 -lkw 
    #
    $db_query     = "select control_node from projects where pid='$project'";
    $sth          = $dbh->query($db_query);
    got_tuples($sth) or die "$0: Error selecting control_node.\n";
    @db_row       = $sth->fetchrow_array();
    $control_node = $db_row[0];
    $control_node = "plastic";           # see note above  

    # get user info
    $db_query       = "select usr_pswd,unix_uid,usr_name from users " .
      	              "where uid='$user'";
    $sth            = $dbh->query($db_query);
    got_tuples($sth) or die "$0: Error selecting user fields.\n";
    @db_row         = $sth->fetchrow_array();
    $pswd        = $db_row[0];
    $user_number = $db_row[1]; 
    $fullname    = $db_row[2];

    # get group number
Kristin Wright's avatar
Kristin Wright committed
125
    $db_query       = "select unix_gid from projects where pid='$project'";
126
127
128
129
130
    $sth            = $dbh->query($db_query);
    got_tuples($sth) or die "$0: Error selecting group number.\n";
    @db_row         = $sth->fetchrow_array();
    $group_number   = $db_row[0];

131
132
    # XXX: I assume FreeBSD for now. Its 
    # fairly firmly entrenched as our control node OS. -lkw
133

Kristin Wright's avatar
   
Kristin Wright committed
134
135

    # The following user/group creation commands must be done as root. 
136
137

    $UID       = $EUID;
Kristin Wright's avatar
   
Kristin Wright committed
138

Kristin Wright's avatar
   
Kristin Wright committed
139
140
141
142
143
144
145
146
147
148
149
150
151
    # 
    # Create group on paper.
    # 
    print "Adding group $project to paper.\n";
    open(ADDGROUPP, "/usr/sbin/pw groupadd $project -g $group_number 2>&1 |");
    while (<ADDGROUPP>) { print "$_"; }
    close(ADDGROUPP);    

    #
    # Make user on paper. We don't give them a password.
    #
    print "Adding user $user to paper.\n";
    my $cmd = "/usr/sbin/pw useradd $user -u $user_number " .
152
153
154
		  "-k /usr/share/skel -m " .
		      "-d /users/$user -g $project " .
			  "-s /usr/testbed/security/paperbag";
Kristin Wright's avatar
   
Kristin Wright committed
155
156
157
158
    open(PWADDP, "$cmd 2>&1 |") or die "$0: Could not open pw useradd on paper.";
    while (<PWADDP>) { print "$_"; }
    close(PWADDP);

159
    #
Kristin Wright's avatar
   
Kristin Wright committed
160
    # Make group on control node.
161
162
    #
    print "Adding group $project to $control_node.\n";
Kristin Wright's avatar
   
Kristin Wright committed
163
    open(ADDGROUP, "/usr/local/bin/sshtb $control_node /usr/sbin/pw groupadd $project -g $group_number 2>&1 |");
164
165
    while (<ADDGROUP>) { print "$_"; }
    close(ADDGROUP);
166
167
    
    #
Kristin Wright's avatar
   
Kristin Wright committed
168
169
170
171
    # Make user on control node. Note that we cannot get back any output from 
    # a command that we open for input so we divide acct creation into two 
    # pieces to maximize feedback. First we add the user account. Then we 
    # change the password.
172
173
    #
    print "Adding user $user to $control_node.\n";
Kristin Wright's avatar
   
Kristin Wright committed
174
175
    $cmd = "/usr/local/bin/sshtb $control_node " .
	      "/usr/sbin/pw useradd $user -u $user_number " .
176
		      "-d /users/$user -g $project -s /bin/tcsh"; 	  
177
178
    open(PWADD, "$cmd 2>&1 |") or die "$0: Could not open pw useradd.";
    while (<PWADD>) { print "$_"; }
Kristin Wright's avatar
   
Kristin Wright committed
179
    $cmd = "/usr/local/bin/sshtb $control_node " .
180
181
182
           "/usr/sbin/pw usermod $user -h 0"; 
    close(PWADD);
    
Kristin Wright's avatar
   
Kristin Wright committed
183
    open(CHPASS, "/usr/local/bin/sshtb $control_node " .
184
185
186
187
188
	         "/usr/bin/chpass -p $pswd $user 2>&1 |"); 
    while (<CHPASS>) { print "$_"; }
    close(CHPASS);

    #
189
    # Set up the ssh key
190
191
    #

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
    mkdir("/users/$user/.ssh", 0755);
    chown($user_number, $group_number, "/users/$user/.ssh");

    # Run commands below as the user
    $EUID = $user_number;
    $UID  = $EUID;

    print "EUID: $EUID UID:$UID\n";
    open(KEYGEN, "/usr/bin/ssh-keygen -P '' -f /users/$user/.ssh/identity 2>&1 |");
    while (<KEYGEN>) { print $_; }
    close(KEYGEN);

    open(CP, "/bin/cp /users/$user/.ssh/identity.pub /users/$user/.ssh/authorized_keys 2>&1 |");
    while (<CP>) { print $_; }
    close(CP); 

    chmod(0600, "/users/$user/.ssh/authorized_keys");
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
}

sub sanitize() {

    ## un-taint path
    $ENV{'PATH'} = '/bin:/usr/bin';
    delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

    ## check usage
    if ($#ARGV < 0) { 
	die("Usage: mkacct <project> <username>\n" .
	    "\tCreates given user account on appropriate control node.\n");
    }

    ## sanitize project
Kristin Wright's avatar
Kristin Wright committed
224
    if ( $ARGV[0] =~ /^([A-Za-z0-9-]+)$/ ) {
225
226
227
228
229
230
	$project = $1;
    } else {
	die "$0: Project argument $ARGV[0] has invalid characters.\n";
    }

    ## sanitize user 
Kristin Wright's avatar
Kristin Wright committed
231
    if ( $ARGV[1] =~ /^([a-z0-9]+)$/i ) {
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
	$user = $1;
    } else {
	die "$0: User argument $ARGV[1] has invalid characters.\n";
    }

    ## effective uid must be root
    if ($> != 0) {
	die("$0: Must have an EUID of 0 to create an account.\n");
    }

}


###
### Return non-zero if we got tuples; 0 if not.
###
sub got_tuples() {

    my $sth = $_[0];
    my $db_numrows = $sth->numrows;
    return $db_numrows;
}