#!/usr/bin/perl -wT # # EMULAB-COPYRIGHT # Copyright (c) 2000-2003 University of Utah and the Flux Group. # All rights reserved. # 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 # # # Configure variables # my $TB = "@prefix@"; my $TBOPS = "@TBOPSEMAIL@"; my $MKGROUP = "$TB/sbin/mkgroup"; my $MKACCT = "$TB/sbin/tbacct add"; my $PROJROOT = "/proj"; my $GRPROOT = "/groups"; my $TFTPROOT = "/tftpboot"; my @DIRLIST = ("exp", "images", "logs", "deltas", "tarfiles", "rpms", "groups", "tiplogs"); my $projhead; # # 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"; use libaudit; 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 \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"); } # # This script is always audited. Mail is sent automatically upon exit. # if (AuditStart(0)) { # # Parent exits normally # exit(0); } # # 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 # our UID (perl sillyness). # $EUID = $UID; system("$MKGROUP $pid $pid") == 0 or fatal("$MKGROUP $pid failed!"); system("$MKACCT $projhead") == 0 or fatal("$MKACCT $projhead failed!"); $EUID = 0; # # 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. # if (! -e "$PROJROOT/$pid") { if (! mkdir("$PROJROOT/$pid", 0770)) { fatal("Could not make directory $PROJROOT/$pid: $!"); } if (! chmod(0770, "$PROJROOT/$pid")) { fatal("Could not chmod directory $PROJROOT/$pid: $!"); } if (! chown($uid, $gid, "$PROJROOT/$pid")) { fatal("Could not chown $PROJROOT/$pid to $uid/$gid: $!"); } } # # Make project subdirs. # foreach my $dir (@DIRLIST) { 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: $!"); } } } # # Create a tftp directory for oskit kernels. # 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: $!"); } } # # Create groups directory. # if (! -e "$GRPROOT/$pid") { if (! mkdir("$GRPROOT/$pid", 0770)) { fatal("Could not make directory $GRPROOT/$pid: $!"); } if (! chmod(0777, "$GRPROOT/$pid")) { fatal("Could not chmod directory $GRPROOT/$pid: $!"); } if (! chown($uid, $gid, "$GRPROOT/$pid")) { fatal("Could not chown $GRPROOT/$pid to $uid/$gid: $!"); } } # # Create experiment working directory. # my $workdir = TBDB_EXPT_WORKDIR() . "/$pid"; if (! -e $workdir) { if (! mkdir("$workdir", 0770)) { fatal("Could not make directory $workdir: $!"); } if (! chmod(0770, "$workdir")) { fatal("Could not chmod directory $workdir: $!"); } if (! chown($uid, $gid, "$workdir")) { fatal("Could not chown $workdir to $uid/$gid: $!"); } } print "Project Creation Completed!\n"; exit(0); sub fatal($) { my($mesg) = $_[0]; die("*** $0:\n". " $mesg\n"); }