mkproj.in 4.85 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-2003 University of Utah and the Flux Group.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
6 7 8
# All rights reserved.
#

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
use English;

#
# Make a project directory hierarchy. Must be called as tbroot.
# Creates a directory rooted /proj/pid. The directory is setuid
# to the project leader, and setgid to the project gid. We get
# this info from the database.
#
# usage: mkproj <pid>
#

#
# Configure variables
#
my $TB       = "@prefix@";
my $TBOPS    = "@TBOPSEMAIL@";
my $MKGROUP  = "$TB/sbin/mkgroup";
26
my $MKACCT   = "$TB/sbin/tbacct add";
27 28

my $PROJROOT = "/proj";
29
my $GRPROOT  = "/groups";
30 31 32
my $TFTPROOT = "/tftpboot";
my @DIRLIST  = ("exp", "images", "logs", "deltas", "tarfiles", "rpms",
		"groups", "tiplogs");
33
my $projhead;
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

#
# 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";
50
use libaudit;
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
use libdb;
use libtestbed;

#
# We don't want to run this script unless its the real version.
#
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");
}

#
# Check args.
#
if ($#ARGV < 0) {
    die("Usage: mkprojdir <pid>\n");
}
my $pid = $ARGV[0];

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

#
# Figure out who called us. Only with admin status in the DB can run
# this script.
#
if (!TBAdmin($UID)) {
    die("*** $0:\n".
	"    You must be a TB administrator to run this script!\n");
}

#
# We need the project leader name.
#
if (! ($projhead = ProjLeader($pid))) {
    die("*** $0:\n".
	"    Could not get project leader for project $pid!\n");
}

106 107 108 109 110 111 112 113 114 115
#
# This script is always audited. Mail is sent automatically upon exit.
#
if (AuditStart(0)) {
    #
    # Parent exits normally
    #
    exit(0);
}

116 117 118 119
#
# Before we can proceed, we need to create the project (unix) group
# and then create an account for the project leader. We pass this off
# to sub scripts, but because they are also setuid, we need to flip
120
# our UID (perl sillyness).
121
#
122
$EUID = $UID;
123

124 125
system("$MKGROUP $pid $pid") == 0 or
    fatal("$MKGROUP $pid failed!");
126

127 128 129 130
system("$MKACCT $projhead") == 0 or
    fatal("$MKACCT $projhead failed!");

$EUID = 0;
131 132 133 134 135 136 137 138 139 140 141 142 143

#
# This acts as check (and we need the numeric uid) in case mkacct failed!
# 
my (undef,undef,$uid) = getpwnam($projhead)
    or fatal("$projhead not in passwd file");

my (undef,undef,$gid) = getgrnam($pid)
    or fatal("$pid not in group file");

#
# Okay, do it.
#
144 145 146 147
if (! -e "$PROJROOT/$pid") {
    if (! mkdir("$PROJROOT/$pid", 0770)) {
	fatal("Could not make directory $PROJROOT/$pid: $!");
    }
148

149 150 151
    if (! chmod(0770, "$PROJROOT/$pid")) {
	fatal("Could not chmod directory $PROJROOT/$pid: $!");
    }
152

153 154 155
    if (! chown($uid, $gid, "$PROJROOT/$pid")) {
	fatal("Could not chown $PROJROOT/$pid to $uid/$gid: $!");
    }
156 157 158 159 160 161
}

#
# Make project subdirs.
#
foreach my $dir (@DIRLIST) {
162 163 164 165 166 167 168 169 170 171
    if (! -e "$PROJROOT/$pid/$dir") {
	if (! mkdir("$PROJROOT/$pid/$dir", 0770)) {
	    fatal("Could not make directory $PROJROOT/$pid/$dir: $!");
	}
	if (! chmod(0770, "$PROJROOT/$pid/$dir")) {
	    fatal("Could not chmod directory $PROJROOT/$pid/$dir: $!");
	}
	if (! chown($uid, $gid, "$PROJROOT/$pid/$dir")) {
	    fatal("Could not chown $PROJROOT/$pid/$dir to $uid/$gid: $!");
	}
172 173 174 175 176
    }
}

#
# Create a tftp directory for oskit kernels.
177 178 179 180 181 182 183 184 185 186 187
#
if (! -e "$TFTPROOT/proj/$pid") {
    if (! mkdir("$TFTPROOT/proj/$pid", 0770)) {
	fatal("Could not make directory $TFTPROOT/proj/$pid: $!");
    }
    if (! chmod(0777, "$TFTPROOT/proj/$pid")) {
	fatal("Could not chmod directory $TFTPROOT/proj/$pid: $!");
    }
    if (! chown($uid, $gid, "$TFTPROOT/proj/$pid")) {
	fatal("Could not chown $TFTPROOT/proj/$pid to $uid/$gid: $!");
    }
188 189
}

190 191
#
# Create groups directory.
192 193 194 195 196
#
if (! -e "$GRPROOT/$pid") {
    if (! mkdir("$GRPROOT/$pid", 0770)) {
	fatal("Could not make directory $GRPROOT/$pid: $!");
    }
197
    if (! chmod(0770, "$GRPROOT/$pid")) {
198 199 200 201 202
	fatal("Could not chmod directory $GRPROOT/$pid: $!");
    }
    if (! chown($uid, $gid, "$GRPROOT/$pid")) {
	fatal("Could not chown $GRPROOT/$pid to $uid/$gid: $!");
    }
203 204
}

205 206 207
#
# Create experiment working directory.
#
Leigh B. Stoller's avatar
Leigh B. Stoller committed
208
my $workdir = TBDB_EXPT_WORKDIR() . "/$pid";
209

210
if (! -e $workdir) {
211
    if (! mkdir("$workdir", 0775)) {
212 213
	fatal("Could not make directory $workdir: $!");
    }
214
    if (! chmod(0775, "$workdir")) {
215 216 217 218 219
	fatal("Could not chmod directory $workdir: $!");
    }
    if (! chown($uid, $gid, "$workdir")) {
	fatal("Could not chown $workdir to $uid/$gid: $!");
    }
220 221
}

222
print "Project Creation Completed!\n";
223 224
exit(0);

225 226
sub fatal($) {
    my($mesg) = $_[0];
227

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