Index: fedkit/fed-tun.ucb.pl
===================================================================
--- fedkit/fed-tun.ucb.pl	(revision f3691ff3ae25d3b83c09aa21905fb9320e79cad2)
+++ fedkit/fed-tun.ucb.pl	(revision f3691ff3ae25d3b83c09aa21905fb9320e79cad2)
@@ -0,0 +1,379 @@
+#!/usr/bin/perl -w
+
+# Kevin Lahey, lahey@isi.edu
+# July 11, 2007
+
+# Set up ssh tunnel infrastructure for federation:
+# 
+# * Parse the configuration file provided.
+#
+# * Figure out whether we're the initiator or the reciever;  if we're 
+#   the receiver, we just need to set up ssh keys and exit.
+#
+# * Pick out the experimental interface, remove the IP address
+# 
+# * Create a layer 2 ssh tunnel, set up bridging, and hang loose.
+#
+
+use strict;
+use Getopt::Std;
+use POSIX qw(strftime);
+use Sys::Hostname;
+use IO::File;
+use IO::Pipe;
+
+my $IFCONFIG = "/sbin/ifconfig";
+my $TMCC = "/usr/local/etc/emulab/tmcc";
+my $SSH = "/usr/local/bin/ssh";
+my $NC = "/usr/bin/nc";
+my $SSH_PORT = 22;
+my $ROUTE_GET = "/sbin/route get";  # XXX:  works on FreeBSD, but should
+				    #       should be 'ip route get' for Linux
+
+# Ports that are forwarded between testbeds
+my $TMCD_PORT = 7777;
+my $SMBFS_PORT = 139;
+my $PUBSUB_PORT = 16505;
+
+
+my $remote_pubsub_port = $PUBSUB_PORT - 1;  # There will be a local
+					    # pubsubd running, so we
+					    # dodge the port on the
+					    # remote tunnel node.
+sub setup_bridging;
+sub setup_tunnel_cfg;
+sub parse_config;
+
+# Option use is as follows:
+#    -f         filename containing config file
+#    -d         turn on debugging output
+#    -r		remotely invoked
+#               (if remotely invoked the last two args are the tun interface
+#               number and the remote address of the tunnel)
+
+my $usage = "Usage: fed-tun.pl [-r] [-d] [-f config-filename] [count addr]\n";
+
+my %opts;	# Note that this is used for both getops and the options file
+my @expected_opts = qw(active tunnelcfg bossname fsname type 
+		       peer pubkeys privkeys);
+my $filename;
+my $remote;
+my $debug = 1;
+my $count;
+my $addr;
+my $active;
+my $type;
+my $tunnelcfg;
+my $ssh_port_fwds = "";
+my $remote_script_dir;		# location of the other sides fed-tun.pl
+my $event_repeater;		# The pathname of the event repeater
+my $remote_config_file;		# Config file for the other side
+
+if ($#ARGV != 0 && !getopts('df:r', \%opts)) {
+    die "$usage";
+}
+
+if (defined($opts{'d'})) {
+    $debug = 1;
+}
+
+if (defined($opts{'f'})) {
+    $filename = $opts{'f'};
+}
+
+if (defined($opts{'r'})) {
+    $remote = 1;
+    die "$usage" if ($#ARGV != 1);
+    
+    $count = pop @ARGV;
+    $addr = pop @ARGV;
+}
+
+die "$usage" if (!defined($remote) && !defined($filename));
+
+if (defined($filename)) {
+    &parse_config("$filename", \%opts) || 
+	die "Cannot read config file $filename: $!\n";
+
+    foreach my $opt (@expected_opts) {
+	warn "Missing $opt option\n" if (!defined($opts{$opt}));
+    }
+
+    $active = 1 if ($opts{'active'} =~ /true/i);
+    $tunnelcfg = 1 if ($opts{'tunnelcfg'} =~ /true/i);
+    $type = $opts{'type'};
+    $type =~ tr/A-Z/a-z/;
+    $remote_script_dir = $opts{'remotescriptdir'} || ".";
+    $event_repeater = $opts{'eventrepeater'};
+    $remote_config_file = $opts{'remoteconfigfile'};
+    $remote_config_file = "-f $remote_config_file" if $remote_config_file;
+
+    if (defined($opts{'fsname'})) {
+	$ssh_port_fwds = "-R :$SMBFS_PORT:$opts{'fsname'}:$SMBFS_PORT ";
+    }
+
+    if (defined($opts{'bossname'})) {
+	$ssh_port_fwds .= "-R :$TMCD_PORT:$opts{'bossname'}:$TMCD_PORT ";
+    }
+
+    if (defined($opts{'eventservername'})) {
+	$ssh_port_fwds .= "-R :$remote_pubsub_port:$opts{'eventservername'}:" . 
+	    "$PUBSUB_PORT ";
+    }
+    if (defined($opts{'remoteeventservername'})) {
+	$ssh_port_fwds .= "-L :$remote_pubsub_port:" . 
+	    "$opts{'remoteeventservername'}:$PUBSUB_PORT ";
+    }
+
+    $ssh_port_fwds = "" if ($opts{'type'} eq 'experiment');
+
+    print "ssh_port_fwds = $ssh_port_fwds\n" if ($debug);
+}
+
+# Need these to make the Ethernet tap and bridge to work...
+
+system("kldload /boot/kernel/if_bridge.ko");
+system("kldload /boot/kernel/if_tap.ko");
+
+if (!$remote) {
+    # At the Berkeley federant, the outgoing addresses are fixed and based on
+    # the control net.  We do set up a host route to the peer.  This is a
+    # simplified version of the DETER setup.
+
+    &setup_tunnel_cfg(%opts);
+}
+
+if (!$remote) {
+    system("umask 077 && cp $opts{'privkeys'} /root/.ssh/id_rsa");
+    system("umask 077 && cp $opts{'pubkeys'} /root/.ssh/id_rsa.pub");
+    system("umask 077 && cat $opts{'pubkeys'} >> /root/.ssh/authorized_keys");
+}
+
+if ($active) {
+    # If we're the initiator, open up a separate tunnel to the remote 
+    # host for each of the different experiment net interfaces on this 
+    # machine.  Execute this startup script on the far end, but with 
+    # the -r option to indicate that it's getting invoked remotely and 
+    # we should just handle the remote-end tasks.
+
+    # Set up synchronization, so that the various user machines won't try to
+    # contact boss before the tunnels are set up.  (Thanks jjh!)
+
+    do {
+	system("$NC -z $opts{'peer'} $SSH_PORT");
+    } until (!$?);
+
+    # XXX:  Do we need to clear out previously created bridge interfaces?
+
+    my $count = 0;
+    my @SSHCMD;
+
+    # If we are just setting up a control net connection, just fire up
+    # ssh with the null command, and hang loose.
+
+    if ($type eq "control") {
+	system("$SSH $ssh_port_fwds -Nno \"StrictHostKeyChecking no\" $opts{'peer'} &"); #or die "Failed to run ssh";
+
+	exit;
+    }
+
+    open(IFFILE, "/var/emulab/boot/ifmap") || die "couldn't open ifmap\n";
+    while (<IFFILE>) {
+	my @a = split(' ');
+	my $iface = $a[0];
+	my $addr = $a[1];
+	my $bridge = "bridge" . $count;
+	my $tun = "tap" . $count;
+
+	print "Found $iface, $addr, to bridge on $bridge\n" if ($debug);
+
+	# Note that we're going to fire off an ssh which will never return;
+	# we need the connection to stay up to keep the tunnel up.
+	# In order to check for problems, we open it this way and read
+	# the expected single line of output when the tunnel is connected.
+
+	print "$SSH -w $count:$count $ssh_port_fwds -o \"StrictHostKeyChecking no\" $opts{'peer'}  \"$remote_script_dir/fed-tun.pl $remote_config_file -r $addr $count\"\n" if $debug;
+	open($SSHCMD[$count], "$SSH -w $count:$count $ssh_port_fwds -o \"StrictHostKeyChecking no\" $opts{'peer'}  \"$remote_script_dir/fed-tun.pl $remote_config_file -r $addr $count\" |") or die "Failed to run ssh";
+
+	my $check = <$SSHCMD[$count]>;  # Make sure something ran...
+	print "Got line [$check] from remote side\n" if ($debug);
+
+	&setup_bridging($tun, $bridge, $iface, $addr);
+	$count++;
+	$ssh_port_fwds = "";  # only do this on the first connection
+    }
+    close(IFFILE);
+
+    # Start a local event repeater (unless we're missing parameters 
+    die "Missing event repeater params (No config file ?)\n"
+	unless $event_repeater && $opts{'remoteexperiment'} && 
+	$opts{'localexperiment'};
+
+    print "Starting event repeater\n" if $debug;
+    
+    print("$event_repeater -M -P $remote_pubsub_port -S localhost " . 
+	"-E $opts{'remoteexperiment'} -e $opts{'localexperiment'}\n") 
+	if $debug;
+    # Connect to the forwarded pubsub port on this host to listen to the
+    # other experiment's events, and to the local experiment to forward
+    # events.
+    system("$event_repeater -M -P $remote_pubsub_port -S localhost " . 
+	"-E $opts{'remoteexperiment'} -e $opts{'localexperiment'}");
+    warn "Event repeater returned $?\n" if $?;
+} elsif ($remote) {
+    # We're on the remote system;  figure out which interface to 
+    # tweak, based on the IP address passed in.
+
+    my $iter = 0;
+    my $iface;
+
+    open(RTFILE, "$ROUTE_GET $addr |") || die "couldn't do $ROUTE_GET\n";
+    while (<RTFILE>) {
+        if (/interface: (\w+)/) {
+	    $iface = $1;
+	}
+    }
+    close(RTFILE);
+
+    die "Couldn't find interface to use." if (!defined($iface));
+    my $bridge = "bridge" . $count;
+    my $tun = "tap" . $count;
+
+    &setup_bridging($tun, $bridge, $iface, $addr);
+    print "Remote connection all set up!\n";  # Trigger other end with output
+
+    # If this is the first remote invocation on a control gateway, start the
+    # event repeater.
+
+    my $file = new IO::File(">/tmp/remote");
+    print($file "hello!!!\n") if $file;
+    if ( $count == 0 && $type ne "experiment" ) {
+	my $remote_pubsub_port = $PUBSUB_PORT - 1;  # There will be a local
+						    # pubsubd running, so we
+						    # dodge the port on the
+						    # remote tunnel node.
+	print($file "In here!\n");
+	# Make sure we have the relevant parameters
+	die "Missing event repeater params (No config file ?)\n"
+	    unless $event_repeater && $opts{'remoteexperiment'} && 
+	    $opts{'localexperiment'};
+
+	print "Starting event repeater\n" if $debug;
+	
+	print($file "$event_repeater -P $remote_pubsub_port -S localhost " . 
+	    "-E $opts{'remoteexperiment'} -e $opts{'localexperiment'}\n") 
+	    if $file;
+	# Connect to the forwarded pubsub port on this host to listen to the
+	# other experiment's events, and to the local experiment to forward
+	# events.
+	system("$event_repeater -P $remote_pubsub_port -S localhost " . 
+	    "-E $opts{'remoteexperiment'} -e $opts{'localexperiment'}");
+	warn "Event repeater returned $?\n" if $?;
+    }
+    $file->close() if $file;
+} else {
+    print "inactive end of a connection, finishing" if ($debug);
+}
+
+print "all done!\n" if ($debug);
+exit;
+
+
+# Set up the bridging for the new stuff...
+
+sub setup_bridging($; $; $; $) {
+    my ($tun, $bridge, $iface, $addr) = @_;
+
+    print "Waiting to see if new iface $tun is up\n" if ($debug);
+
+    do {
+	sleep 1;
+	system("$IFCONFIG $tun");
+    } until (!$?);
+
+    print "setting up $bridge with $iface and nuking $addr\n" if ($debug);
+
+    system("ifconfig $bridge create");
+    system("ifconfig $iface delete $addr");
+    system("ifconfig $bridge addm $iface up");
+    system("ifconfig $bridge addm $tun");
+}
+
+# Set up tunnel info for UCB testbed
+
+sub setup_tunnel_cfg {
+    my (%opts) = @_;
+    my $tunnel_iface = "em5";
+    my $control_iface = "em4";
+    my $tunnel_prefix = "192.154.6.";
+    my $tunnel_router = "192.154.6.1";
+    my $netmask = "255.255.255.0";
+    my $ipipe = new IO::Pipe();
+    my $pcnum;
+
+    $ipipe->reader("$IFCONFIG $control_iface");
+
+    while (<$ipipe>) {
+	/inet\s+\d+\.\d+\.\d+\.(\d+)/ && do {
+	    $pcnum = $1;
+	    last;
+	};
+    }
+    $ipipe->close();
+    $pcnum += 50;
+    $pcnum &=0xff if $pcnum > 255;
+
+    system("ifconfig $tunnel_iface $tunnel_prefix$pcnum netmask $netmask up");
+    warn "configuration of tunnel interface failed" if ($?);
+
+    # Sometimes the insertion of DNS names lags a bit.  Retry this
+    # configuration a few times to let DNS catch up.  Might want to really
+    # check the DNS name before we try this...
+    my $config_succeeded = 0;
+    my $tries = 0;
+    my $max_retries = 6;
+
+    do {
+	system("route add $opts{'peer'} $tunnel_router");
+	if ( $? ) {
+	    warn "configuration routes via tunnel interface failed";
+	    $tries++;
+	    sleep(10);
+	}
+	else { $config_succeeded = 1; }
+    } until ( $config_succeeded || $tries > $max_retries );
+
+    print "setup_tunnel_cfg done\n" if ($debug);
+}
+
+# Trick config-file parsing code from Ted Faber:
+
+# Parse the config file.  The format is a colon-separated parameter name
+# followed by the value of that parameter to the end of the line.  This parses
+# that format and puts the parameters into the referenced hash.  Parameter
+# names are mapped to lower case, parameter values are unchanged.  Returns 0 on
+# failure (e.g. file open) and 1 on success.
+sub parse_config {
+    my($file, $href) = @_;
+    my($fh) = new IO::File($file);
+	
+    unless ($fh) {
+	warn "Can't open $file: $!\n";
+	return 0;
+    }
+
+    while (<$fh>) {
+	next if /^\s*#/ || /^\s*$/;	# Skip comments & blanks
+	chomp;
+	/^([^:]+):\s*(.*)/ && do {
+	    my($key) = $1; 
+
+	    $key =~ tr/A-Z/a-z/;
+	    $href->{$key} = $2;
+	    next;
+	};
+	warn "Unparasble line in $file: $_\n";
+    }
+    $fh->close();   # It will close when it goes out of scope, but...
+    return 1;
+}
Index: fedkit/fed_bootstrap
===================================================================
--- fedkit/fed_bootstrap	(revision 2396559e3a4242e7e6b7a769d4b129b47685634a)
+++ fedkit/fed_bootstrap	(revision f3691ff3ae25d3b83c09aa21905fb9320e79cad2)
@@ -22,5 +22,5 @@
 
 # The copy
-for f in federate.sh smbmount.pl; do 
+for f in federate.sh smbmount*.pl *.patch; do 
 	cp $SCRIPTDIR/$f /tmp && chmod 755 /tmp/$f
 done
Index: fedkit/federate.sh
===================================================================
--- fedkit/federate.sh	(revision 2396559e3a4242e7e6b7a769d4b129b47685634a)
+++ fedkit/federate.sh	(revision f3691ff3ae25d3b83c09aa21905fb9320e79cad2)
@@ -21,5 +21,27 @@
 # automount process.
 RCACCT="rc.accounts"
-SMBMOUNT="smbmount.pl"
+SMBMOUNT="smbmount.`uname`.pl"
+
+# Find the right version of pkill.  For killing.
+if [ -x "/usr/bin/pkill" ] ; then 
+	PKILL="/usr/bin/pkill"
+else
+	if [ -x "/bin/pkill" ] ; then 
+		PKILL="/bin/pkill"
+	else
+		PKILL="echo"
+	fi
+fi
+
+if [ -x "/usr/bin/perl" ]; then
+    PERL="/usr/bin/perl"
+else
+    if [ -x "/usr/local/bin/perl" ]; then
+	PERL="/usr/local/bin/perl"
+    else
+	# Wing it...
+	PERL="perl"
+    fi
+fi
 
 # Find somewhere safe to stop
@@ -34,5 +56,5 @@
 
 # Find this experiment's stashed scripts.  (Perl for advanced parsing)
-SCRIPTDIR=`$EMUDIR/tmcc -b status | perl -ne '/ALLOCATED=([^\/]+)\/([^\s]+)/ && print "/proj/$1/exp/$2/tmp\n";'`
+SCRIPTDIR=`$EMUDIR/tmcc -b status | $PERL -ne '/ALLOCATED=([^\/]+)\/([^\s]+)/ && print "/proj/$1/exp/$2/tmp\n";'`
 
 # Die if Scripts are not where they should be.  NB, this is checked by the
@@ -53,7 +75,17 @@
 # Get our gateway, share, and mount user from the configuration file.
 # There's probably a way to get all three at once, but this works.
-GATEWAY=`perl -ne '/ControlGateway:\s+(.*)/i && print "$1\n";' $SCRIPTDIR/client.conf`
-SHARE=`perl -ne '/SMBShare:\s+(.*)/i && print "$1\n";' $SCRIPTDIR/client.conf`
-SMBUSER=`perl -ne '/ProjectUser:\s+(.*)/i && print "$1\n";' $SCRIPTDIR/client.conf`
+GATEWAY=`$PERL -ne '/ControlGateway:\s+(.*)/i && print "$1\n";' $SCRIPTDIR/client.conf`
+SHARE=`$PERL -ne '/SMBShare:\s+(.*)/i && print "$1\n";' $SCRIPTDIR/client.conf`
+SMBUSER=`$PERL -ne '/ProjectUser:\s+(.*)/i && print "$1\n";' $SCRIPTDIR/client.conf`
+SMBPROJECT=`$PERL -ne '/ProjectName:\s+(.*)/i && print "$1\n";' $SCRIPTDIR/client.conf`
+
+# XXX:
+# The standard emulab rc.accounts script won't replace existing user accounts
+# with our new ones, so we have to patch it to do so.  This is obviously pretty
+# fragile and needs to change.  To make matters worse, our FBSD62-SMB images
+# contain the patched rc.accounts, so this patching step will fail there.
+cd "$EMUDIR/rc"
+patch -f < /tmp/rc.accounts.patch
+cd /tmp
 
 #
@@ -80,20 +112,25 @@
 
 #
-# Unmount stuff before messing with accounts
+# Unmount stuff before messing with accounts 
+# Linux doesn't believe in -A so run umount without it if the first fails
 #
-umount -A -f -t nfs,smbfs
 
+umount -A -f -t nfs,smbfs,cifs  || umount -a -f -t nfs,smbfs,cifs
 
 #
 # Setup new accounts
 #
+
+# Clear the cache, just in case:
+rm -f /var/emulab/boot/tmcc/accounts
+
 $RCDIR/rc.accounts reconfig
 
 #
-# Call the smbmount perl script, this invokes the automounter to mount teh
+# Call the smbmount perl script, this invokes the automounter to mount the
 # needed smb filesystems.
 #
 echo "Mounting via SMB."
-"/tmp/$SMBMOUNT" $SHARE $GATEWAY $SMBUSER 
+$PERL "/tmp/$SMBMOUNT" $SHARE $GATEWAY $SMBUSER $SMBPROJECT
 
 echo "Restoring old bossnode"
@@ -108,6 +145,13 @@
 # partial topology -e.g. failed or partial bridging - that might have confused
 # the router should be gone.
-/bin/pkill ospf
-/bin/pkill gated
+$PKILL ospf
+$PKILL gated
+# XXX Danger, hack ahead.  Apparently our FC6-SMB image and emulab disagree
+# about where gated lives.  This will alias it.
+if [ ! -x /usr/sbin/gated ] ; then 
+	if [ -x /sbin/gated ] ; then
+		ln /sbin/gated /usr/sbin/gated
+	fi
+fi
 /usr/local/etc/emulab/rc/rc.route boot
 
Index: fedkit/rc.accounts.patch
===================================================================
--- fedkit/rc.accounts.patch	(revision f3691ff3ae25d3b83c09aa21905fb9320e79cad2)
+++ fedkit/rc.accounts.patch	(revision f3691ff3ae25d3b83c09aa21905fb9320e79cad2)
@@ -0,0 +1,14 @@
+--- ./rc.accounts.bak	2008-05-16 09:47:14.000000000 -0700
++++ ./rc.accounts	2008-05-16 09:45:54.000000000 -0700
+@@ -375,6 +375,11 @@
+ 		# Windows uses its own UID and GID numbers. 
+ 		if ($curuid != $uid  && ! WINDOWS()) {
+ 		    warning("$login/$uid uid mismatch with existing login!");
++                    os_userdel($login);
++                    if (os_useradd($login, $uid, $gid, $pswd,
++                                   "$glist", $hdir, $name, $root, $shell)) {
++                       warning("Error adding new user $login");
++                    }
+ 		    next;
+ 		}
+ 		if ($doupdate) {
Index: fedkit/smbmount.FreeBSD.pl
===================================================================
--- fedkit/smbmount.FreeBSD.pl	(revision f3691ff3ae25d3b83c09aa21905fb9320e79cad2)
+++ fedkit/smbmount.FreeBSD.pl	(revision f3691ff3ae25d3b83c09aa21905fb9320e79cad2)
@@ -0,0 +1,110 @@
+#!/usr/bin/perl
+
+#############################################################################
+# smbmounts.pl: Setup Automounter to mount via SMB for federated experiments
+# $Id: smbmount.FreeBSD.pl,v 1.1 2008-05-18 00:09:31 faber Exp $
+#
+
+$SHARE=shift || "USERS";
+$ADDR=shift || `cat /usr/local/etc/emulab/bossnode`;
+$PUSER=shift || "jhickey";
+$PNAME=shift || "emulab-ops";
+$FSTAB="/etc/fstab";
+$HOMEROOT="/users";
+$PROJROOT="/proj";
+$AMDROOT="/auto";
+$AMDMAP="/etc/amd.users";
+$PAMDMAP="/etc/amd.proj";
+
+chomp $ADDR;
+
+$TMCC="/usr/local/etc/emulab/tmcc";
+$UMOUNT="/sbin/umount";
+$MOUNT="/sbin/mount";
+$MKDIR="/bin/mkdir";
+$CP="/bin/cp";
+$KILLALL="/usr/bin/killall";
+$AMD="/usr/sbin/amd";
+
+print "Killing amd.\n";
+system("$KILLALL amd");
+
+print "Unmounting all nfs and smb filesystems.\n";
+system("$UMOUNT -A -f -t nfs,smbfs"); # or die("Failed to unmount NFS");
+
+# Backup the fstab so we can run multiple times
+if (! -f "$FSTAB.bak") {
+	system("$CP $FSTAB $FSTAB.bak") && die("Unable to backup $FSTAB");
+} else {
+	system("$CP $FSTAB.bak $FSTAB") && die("Unable to restore $FSTAB");
+}
+
+open(TM, "$TMCC accounts windows |") or die("Failed to execute TMCC");
+open(CONFIG, ">/etc/nsmb.conf") or die("Failed to open /etc/nsmb.conf");
+open(MAP, ">$AMDMAP") or die("Failed to open $AMDMAP");
+open(PMAP, ">$PAMDMAP") or die("Failed to open $PAMDMAP");
+open(FSTAB,">>$FSTAB") or die("Cannot Open File $FSTAB");
+
+print FSTAB "\n# SMB Configuration Generated by smbmount.pl\n";
+print MAP "# AMD Configuration Generated by smbmount.pl\n";
+print CONFIG "# SMB Configuration Generated by smbmount.pl\n\n";
+print CONFIG "[$SHARE]\naddr=$ADDR\n\n";
+
+while(<TM>) {
+        if (/ADDUSER LOGIN=(\S+) PSWD=(\S+) UID=(\d+) GID=(\d+).*HOMEDIR=(\S+) / ) {
+                $user = $1;
+                $pswd = $2;
+                $uid  = $3;
+                $gid  = $4;
+                $homedir = $5;
+
+		$userlc = $user;
+		# SMB demands upper case.
+		$user =~  tr/a-z/A-Z/;
+		my $pass = `smbutil crypt '$pswd'`;
+
+                print CONFIG "[$SHARE:$user]\npassword=$pass\n";
+		
+		if(! -d "$AMDROOT$homedir") {
+			system("$MKDIR -p $AMDROOT$homedir") && die("Failed to make directory");
+		}
+
+		print FSTAB "//$user\@$SHARE/$user\t";
+		print FSTAB "$AMDROOT$homedir\tsmbfs\t";
+ 		print FSTAB "noauto,rw,-N,-f744,-d755,-u$uid,-g$gid\t0\t0\n";
+
+		print MAP "\n$userlc type:=program;fs:=$AMDROOT$homedir;\\\n";
+		print MAP "mount:=\"$MOUNT mount $AMDROOT$homedir\";\\\n";
+		print MAP "unmount:=\"$UMOUNT unmount $AMDROOT$homedir\";";
+
+		#
+		# If we are PUSER, the user assigned to mount the project directory,
+		# then we add in the mount for that.  The share is called proj-$PNAME
+		# where PNAME is the name of the project at the mothership.  We need
+ 		# a second map for this since we will be mounting under /proj.
+		# We should really not use share in federation.
+		#
+
+		if($user =~ m/$PUSER/i) {
+			print FSTAB "//$user\@$SHARE/proj-$PNAME\t";
+			print FSTAB "$AMDROOT/proj\tsmbfs\t";
+			print FSTAB "noauto,rw,-N,-f774,-d775,-u$uid,-g$gid\t0\t0\n";
+
+			print PMAP "$PNAME type:=program;fs:=$AMDROOT/proj;\\\n";
+			print PMAP "mount:=\"$MOUNT mount $AMDROOT/proj\";\\\n";
+			print PMAP "unmount:=\"$UMOUNT unmount $AMDROOT/proj\";\n";
+
+			if(! -d "$AMDROOT/proj") {
+				system("$MKDIR -p $AMDROOT/proj") && die("Failed to make directory");
+			}
+		}
+        }
+}
+
+close(CONFIG);
+close(FSTAB);
+close(MAP);
+close(PMAP);
+
+print "Starting the automounter: $AMD -l syslog -a $AMDROOT $HOMEROOT $AMDMAP $PROJROOT $PAMDMAP\n";
+system("$AMD -l syslog -a $AMDROOT $HOMEROOT $AMDMAP $PROJROOT $PAMDMAP") && die("Unable to start amd");
Index: fedkit/smbmount.Linux.pl
===================================================================
--- fedkit/smbmount.Linux.pl	(revision f3691ff3ae25d3b83c09aa21905fb9320e79cad2)
+++ fedkit/smbmount.Linux.pl	(revision f3691ff3ae25d3b83c09aa21905fb9320e79cad2)
@@ -0,0 +1,88 @@
+#!/usr/bin/perl
+
+#############################################################################
+# smbmounts.pl: Setup Automounter to mount via SMB for federated experiments
+# $Id: smbmount.Linux.pl,v 1.1 2008-05-18 00:09:31 faber Exp $
+#
+
+$SHARE=shift || "USERS";
+$ADDR=shift || `cat /usr/local/etc/emulab/bossnode`;
+$PUSER=shift || "jhickey";
+$PNAME=shift || "emulab-ops";
+$FSTAB="/etc/fstab";
+$HOMEROOT="/users";
+$PROJROOT="/proj";
+
+chomp $ADDR;
+
+# ADDR is probably a DNS name (and we assume so if it has letters.  mount cifs
+# wants an IP address, so this hex dereferences the DNS name and converts the
+# first address into the string representation of the IP.  It is, perhaps, a
+# but terse.
+if ($ADDR =~ /[a-z]/ ) {
+    my @addrs = (gethostbyname($ADDR))[4];
+    $ADDR = join(".", unpack("C4", @addrs[0]))
+	if @addrs;
+}
+
+
+$TMCC="/usr/local/etc/emulab/tmcc";
+$UMOUNT="/bin/umount";
+$MOUNT="/bin/mount";
+$MKDIR="/bin/mkdir";
+$CP="/bin/cp";
+
+print "Unmounting all nfs and cifs filesystems.\n";
+system("$UMOUNT -a -f -t nfs,cifs"); # or die("Failed to unmount NFS");
+
+# Backup the fstab so we can run multiple times
+if (! -f "$FSTAB.bak") {
+	system("$CP $FSTAB $FSTAB.bak") && die("Unable to backup $FSTAB");
+} else {
+	system("$CP $FSTAB.bak $FSTAB") && die("Unable to restore $FSTAB");
+}
+
+open(TM, "$TMCC accounts windows |") or die("Failed to execute TMCC");
+open(FSTAB,">>$FSTAB") or die("Cannot Open File $FSTAB");
+
+print FSTAB "\n# SMB Configuration Generated by smbmount.pl\n";
+
+while(<TM>) {
+        if (/ADDUSER LOGIN=(\S+) PSWD=(\S+) UID=(\d+) GID=(\d+).*HOMEDIR=(\S+) / ) {
+		($user, $pswd, $uid, $gid, $homedir) = ($1, $2, $3, $4, $5);
+
+
+		open(PWDFILE, ">/tmp/$user.cifs_creds") || 
+		    warn "Can't create credentials for $user:$!\n";
+		print PWDFILE "username=$user\npassword=$pswd\n";
+		close(PWDFILE);
+		chmod(0600, "/tmp/$user.cifs_creds") == 1 || 
+		    warn "Credential file /tmp/$user.cifs_creds may have " .
+			"bad permissions:$!\n";
+
+		print FSTAB "//$SHARE/$user\t";
+		print FSTAB "$homedir\tcifs\t";
+ 		print FSTAB "auto,rw,credentials=/tmp/$user.cifs_creds,ip=$ADDR\t0\t0\n";
+
+		#
+		# If we are PUSER, the user assigned to mount the project
+		# directory, then we add in the mount for that.  The share is
+		# called proj-$PNAME where PNAME is the name of the project at
+		# the mothership.  We need a second map for this since we will
+		# be mounting under /proj.  We should really not use share in
+		# federation.
+		#
+
+		if($user =~ m/$PUSER/i) {
+			print FSTAB "//$SHARE/proj-$PNAME\t";
+			print FSTAB "$PROJROOT/$PNAME\tcifs\t";
+			print FSTAB "rw,credentials=/tmp/$user.cifs_creds\t0\t0\n";
+
+		}
+        }
+}
+
+close(FSTAB);
+
+print("Mounting the cifs versions of everything\n");
+system("$MOUNT -a -t cifs");
Index: fedkit/smbmount.pl
===================================================================
--- fedkit/smbmount.pl	(revision 2396559e3a4242e7e6b7a769d4b129b47685634a)
+++ 	(revision )
@@ -1,110 +1,0 @@
-#!/usr/local/bin/perl
-
-#############################################################################
-# smbmounts.pl: Setup Automounter to mount via SMB for federated experiments
-# $Id: smbmount.pl,v 1.4 2007-09-27 20:53:16 jhickey Exp $
-#
-
-$SHARE=shift || "USERS";
-$ADDR=shift || `cat /usr/local/etc/emulab/bossnode`;
-$PUSER=shift || "jhickey";
-$PNAME=shift || "emulab-ops";
-$FSTAB="/etc/fstab";
-$HOMEROOT="/users";
-$PROJROOT="/proj";
-$AMDROOT="/auto";
-$AMDMAP="/etc/amd.users";
-$PAMDMAP="/etc/amd.proj";
-
-chomp $ADDR;
-
-$TMCC="/usr/local/etc/emulab/tmcc";
-$UMOUNT="/sbin/umount";
-$MOUNT="/sbin/mount";
-$MKDIR="/bin/mkdir";
-$CP="/bin/cp";
-$KILLALL="/usr/bin/killall";
-$AMD="/usr/sbin/amd";
-
-print "Killing amd.\n";
-system("$KILLALL amd");
-
-print "Unmounting all nfs and smb filesystems.\n";
-system("$UMOUNT -A -f -t nfs,smbfs"); # or die("Failed to unmount NFS");
-
-# Backup the fstab so we can run multiple times
-if (! -f "$FSTAB.bak") {
-	system("$CP $FSTAB $FSTAB.bak") && die("Unable to backup $FSTAB");
-} else {
-	system("$CP $FSTAB.bak $FSTAB") && die("Unable to restore $FSTAB");
-}
-
-open(TM, "$TMCC accounts windows |") or die("Failed to execute TMCC");
-open(CONFIG, ">/etc/nsmb.conf") or die("Failed to open /etc/nsmb.conf");
-open(MAP, ">$AMDMAP") or die("Failed to open $AMDMAP");
-open(PMAP, ">$PAMDMAP") or die("Failed to open $PAMDMAP");
-open(FSTAB,">>$FSTAB") or die("Cannot Open File $FSTAB");
-
-print FSTAB "\n# SMB Configuration Generated by smbmount.pl\n";
-print MAP "# AMD Configuration Generated by smbmount.pl\n";
-print CONFIG "# SMB Configuration Generated by smbmount.pl\n\n";
-print CONFIG "[$SHARE]\naddr=$ADDR\n\n";
-
-while(<TM>) {
-        if (/ADDUSER LOGIN=(\S+) PSWD=(\S+) UID=(\d+) GID=(\d+).*HOMEDIR=(\S+) / ) {
-                $user = $1;
-                $pswd = $2;
-                $uid  = $3;
-                $gid  = $4;
-                $homedir = $5;
-
-		$userlc = $user;
-		# SMB demands upper case.
-		$user =~  tr/a-z/A-Z/;
-		my $pass = `smbutil crypt '$pswd'`;
-
-                print CONFIG "[$SHARE:$user]\npassword=$pass\n";
-		
-		if(! -d "$AMDROOT$homedir") {
-			system("$MKDIR -p $AMDROOT$homedir") && die("Failed to make directory");
-		}
-
-		print FSTAB "//$user\@$SHARE/$user\t";
-		print FSTAB "$AMDROOT$homedir\tsmbfs\t";
- 		print FSTAB "noauto,rw,-N,-f744,-d755,-u$uid,-g$gid\t0\t0\n";
-
-		print MAP "\n$userlc type:=program;fs:=$AMDROOT$homedir;\\\n";
-		print MAP "mount:=\"$MOUNT mount $AMDROOT$homedir\";\\\n";
-		print MAP "unmount:=\"$UMOUNT unmount $AMDROOT$homedir\";";
-
-		#
-		# If we are PUSER, the user assigned to mount the project directory,
-		# then we add in the mount for that.  The share is called proj-$PNAME
-		# where PNAME is the name of the project at the mothership.  We need
- 		# a second map for this since we will be mounting under /proj.
-		# We should really not use share in federation.
-		#
-
-		if($user =~ m/$PUSER/i) {
-			print FSTAB "//$user\@$SHARE/proj-$PNAME\t";
-			print FSTAB "$AMDROOT/proj\tsmbfs\t";
-			print FSTAB "noauto,rw,-N,-f774,-d775,-u$uid,-g$gid\t0\t0\n";
-
-			print PMAP "$PNAME type:=program;fs:=$AMDROOT/proj;\\\n";
-			print PMAP "mount:=\"$MOUNT mount $AMDROOT/proj\";\\\n";
-			print PMAP "unmount:=\"$UMOUNT unmount $AMDROOT/proj\";\n";
-
-			if(! -d "$AMDROOT/proj") {
-				system("$MKDIR -p $AMDROOT/proj") && die("Failed to make directory");
-			}
-		}
-        }
-}
-
-close(CONFIG);
-close(FSTAB);
-close(MAP);
-close(PMAP);
-
-print "Starting the automounter: $AMD -l syslog -a $AMDROOT $HOMEROOT $AMDMAP $PROJROOT $PAMDMAP\n";
-system("$AMD -l syslog -a $AMDROOT $HOMEROOT $AMDMAP $PROJROOT $PAMDMAP") && die("Unable to start amd");
Index: fedkit/splitter.pl
===================================================================
--- fedkit/splitter.pl	(revision 2396559e3a4242e7e6b7a769d4b129b47685634a)
+++ fedkit/splitter.pl	(revision f3691ff3ae25d3b83c09aa21905fb9320e79cad2)
@@ -9,6 +9,7 @@
 use File::Copy;
 
-my @scripts = ("fed_bootstrap", "federate.sh", "smbmount.pl", 
-    "make_hosts", "fed-tun.pl", "fed_evrepeater" );
+my @scripts = ("fed_bootstrap", "federate.sh", "smbmount.FreeBSD.pl", 
+    "smbmount.Linux.pl", "make_hosts", "fed-tun.pl", "fed_evrepeater",
+    "rc.accounts.patch");
 my $local_script_dir = ".";
 my($pid, $gid);			# Process and group IDs for calling parse.tcl
@@ -492,5 +493,5 @@
 $project_user = $opts{'smbuser'} ||	# User to mount project dirs as
     die "Must give an SMB user\n";
-$auth_proj = $opts{'P'} || die "Must give an authentication project (-P)\n";
+$auth_proj = $opts{'P'};
 
 # tcl program to split experiments (changed during devel)
@@ -574,7 +575,8 @@
 	# If this testbed has not had its access parameters read from fedd, try
 	# to read them, if we have a way to talk to fedd
-	unless ($tbparams->{$tb}->{'access'} && $fedd_client) { 
+	unless ($tbparams->{$tb}->{'access'} || !$fedd_client) { 
 	    my $access_pipe = new IO::Pipe || 
 		die "Can't open pipe to fedd:$!\n";
+	    my $proj = $auth_proj ? " -p $auth_proj " : "";
 
 	    print("Checking access to $tb using " . $tbparams->{$tb}->{'uri'}
@@ -583,5 +585,5 @@
 	    my $cmd = "$fedd_client -t " . 
 		$tbparams->{$tb}->{'uri'} .  " -T $ENV{HOME}/cacert.pem ".
-		"-l $tb -p $auth_proj | /usr/bin/tee fedd.$tb ";
+		"-l $tb $proj | /usr/bin/tee fedd.$tb ";
 	    print "$cmd\n" if $verbose;
 
