diff --git a/tmcd/decls.h b/tmcd/decls.h
index a99d03862c003c20fbd9921bdb50fef7ec918c0a..e2c2e46999eb95a50e82e2c2e75e1e9acf974b2e 100644
--- a/tmcd/decls.h
+++ b/tmcd/decls.h
@@ -4,9 +4,10 @@
  * All rights reserved.
  */
 
-#define TBSERVER_PORT	 7777
-#define TBSERVER_PORT2   14443
-#define MYBUFSIZE	 2048
+#define TBSERVER_PORT		7777
+#define TBSERVER_PORT2		14443
+#define MYBUFSIZE		2048
+#define BOSSNODE_FILENAME	"bossnode"
 
 /*
  * As the tmcd changes, incompatable changes with older version of
diff --git a/tmcd/tmcc.c b/tmcd/tmcc.c
index e2571f1efaac1e4f14159f4bac690e5238155c1f..53324ab0a06adcb5477af1b4fea574c8bf4dea7f 100644
--- a/tmcd/tmcc.c
+++ b/tmcd/tmcc.c
@@ -28,18 +28,22 @@
 #include "config.h"
 #endif
 
-#ifndef STANDALONE
-#undef BOSSNODE
-#endif
-#ifdef BOSSNODE
-#define DEFAULT_BOSSNODE BOSSNODE
-#else
-#define DEFAULT_BOSSNODE NULL
-#endif
-#ifndef BOSSNODEFILE
-#define BOSSNODEFILE	 "/usr/local/etc/testbed/bossnode"
+#undef  BOSSNODE
+#ifndef KEYFILE
+#define KEYFILE		"/etc/emulab.pkey"
 #endif
 
+/*
+ * We search a couple of dirs for the bossnode file.
+ */
+static char *bossnodedirs[] = {
+	"/etc/testbed",
+	"/etc/rc.d/testbed",
+	"/usr/local/etc/testbed",
+	"/usr/local/etc/emulab",
+	0
+};
+
 /*
  * Need to try several ports cause of firewalling. 
  */
@@ -61,6 +65,7 @@ char *usagestr =
  " -p portnum	   Specify a port number to connect to\n"
  " -v versnum	   Specify a version number for tmcd\n"
  " -n vnodeid	   Specify the vnodeid\n"
+ " -k keyfile	   Specify the private keyfile\n"
  " -u		   Use UDP instead of TCP\n"
  " -t timeout	   Timeout waiting for the controller.\n"
  "\n";
@@ -81,10 +86,13 @@ main(int argc, char **argv)
 	struct hostent		*he;
 	struct in_addr		serverip;
 	char			buf[MYBUFSIZE], *bp, *response = "";
-	char			*bossnode = DEFAULT_BOSSNODE;
+	char			*bossnode = NULL;
 	int			version = CURRENT_VERSION;
 	char			*vnodeid = NULL;
+	char			*keyfile = NULL;
+	char			*privkey = NULL;
 	int			waitfor = 0;
+	FILE			*fp;
 #ifdef UDP
 	int			useudp  = 0;
 #endif
@@ -101,6 +109,9 @@ main(int argc, char **argv)
 		case 'n':
 			vnodeid = optarg;
 			break;
+		case 'k':
+			keyfile = optarg;
+			break;
 		case 'v':
 			version = atoi(optarg);
 			break;
@@ -126,20 +137,30 @@ main(int argc, char **argv)
 	 * How do we find our bossnode?
 	 *
 	 * 1. Command line.
-	 * 2. Compiled in.
-	 * 3. /usr/local/etc/bossnode
-	 * 4. nameserver goo below.
+	 * 2. From a file in the list above.
+	 * 3. nameserver goo below.
 	 */
 	if (!bossnode) {
-		FILE	*fp;
-		
-		if ((fp = fopen(BOSSNODEFILE, "r")) != NULL) {
-			if (fgets(buf, sizeof(buf), fp)) {
-				if ((bp = strchr(buf, '\n')))
-					*bp = (char) NULL;
-				bossnode = strdup(buf);
+		/*
+		 * Search for the file.
+		 */
+		char **cp = bossnodedirs;
+		while (*cp) {
+			sprintf(buf, "%s/%s", *cp, BOSSNODE_FILENAME);
+
+			if (access(buf, R_OK) == 0)
+				break;
+			cp++;
+		}
+		if (*cp) {
+			if ((fp = fopen(buf, "r")) != NULL) {
+				if (fgets(buf, sizeof(buf), fp)) {
+					if ((bp = strchr(buf, '\n')))
+						*bp = (char) NULL;
+					bossnode = strdup(buf);
+				}
+				fclose(fp);
 			}
-			fclose(fp);
 		}
 	}
 	if (!bossnode)
@@ -152,6 +173,28 @@ main(int argc, char **argv)
 		exit(1);
 	}
 
+	/*
+	 * Grab the key. Its not an error if we do not find it.
+	 */
+	if (keyfile) {
+		/* Well, if one was specifed it has to exist. */
+		if (access(keyfile, R_OK) < 0) {
+			perror("keyfile"); 
+			exit(1);
+		}
+	}
+	else
+		keyfile = KEYFILE;
+
+	if ((fp = fopen(keyfile, "r")) != NULL) {
+	    if (fgets(buf, sizeof(buf), fp)) {
+		if ((bp = strchr(buf, '\n')))
+		    *bp = (char) NULL;
+		privkey = strdup(buf);
+	    }
+	    fclose(fp);
+	}
+
 	if (waitfor) {
 		alarm(waitfor);
 	}
@@ -226,6 +269,11 @@ main(int argc, char **argv)
 		sprintf(&buf[strlen(buf)], "VNODEID=%s ", vnodeid);
 	}
 
+	/* Tack on privkey */
+	if (privkey) {
+		sprintf(&buf[strlen(buf)], "PRIVKEY=%s ", privkey);
+	}
+
 	/*
 	 * Since we've gone through a getopt() pass, argv[0] is now the
 	 * first argument
diff --git a/tmcd/tmcd.c b/tmcd/tmcd.c
index 7b12060c9614a4cefe4daf278a27b61aa2f74a3a..54d32b9786d543fcb2c48911273fc753d9b9e95c 100644
--- a/tmcd/tmcd.c
+++ b/tmcd/tmcd.c
@@ -66,6 +66,7 @@ static int	iptonodeid(struct in_addr, char *,char *,char *,char *,int *);
 static int	nodeidtonickname(char *nodeid, char *nickname);
 static int	nodeidtocontrolnet(char *nodeid, int *net);
 static int	checkdbredirect(char *nodeid);
+static int	checkprivkey(struct in_addr, char *);
 static void	tcpserver(int sock);
 static void	udpserver(int sock);
 static int      handle_request(int, struct sockaddr_in *, char *, int);
@@ -262,6 +263,9 @@ main(int argc, char **argv)
 			fgets(fshostid, HOSTID_SIZE, fp);
 			if (rindex(fshostid, '\n')) {
 				*rindex(fshostid, '\n') = 0;
+				if (debug) {
+				    info("fshostid: %s\n", fshostid);
+				}
 			}
 			else {
 				error("fshostid from %s may be corrupt: %s",
@@ -489,11 +493,12 @@ static int
 handle_request(int sock, struct sockaddr_in *client, char *rdata, int istcp)
 {
 	struct sockaddr_in redirect_client;
-	int		   redirect = 0, isvnode = 0;
+	int		   redirect = 0, isvnode = 0, havekey = 0;
 	char		   buf[BUFSIZ], *bp, *cp;
 	char		   nodeid[TBDB_FLEN_NODEID];
 	char		   vnodeid[TBDB_FLEN_NODEID];
 	char		   class[TBDB_FLEN_NODECLASS];
+	char		   privkey[TBDB_FLEN_PRIVKEY];
 	char		   type[TBDB_FLEN_NODETYPE];
 	int		   i, islocal, err = 0;
 	int		   version = DEFAULT_VERSION;
@@ -503,6 +508,20 @@ handle_request(int sock, struct sockaddr_in *client, char *rdata, int istcp)
 	 */
 	bp = rdata;
 	while ((bp = strsep(&rdata, " ")) != NULL) {
+		/*
+		 * Look for PRIVKEY. 
+		 */
+		if (sscanf(bp, "PRIVKEY=%64s", buf)) {
+			havekey = 1;
+			strncpy(privkey, buf, sizeof(privkey));
+
+			if (debug) {
+				info("PRIVKEY %s\n", buf);
+			}
+			continue;
+		}
+
+
 		/*
 		 * Look for VERSION. 
 		 */
@@ -651,6 +670,26 @@ handle_request(int sock, struct sockaddr_in *client, char *rdata, int istcp)
 		goto skipit;
 	}
 
+	/*
+	 * Do private key check. widearea nodes must report a private key
+	 * It comes over ssl of course. At present we skip this check for
+	 * ron nodes. 
+	 */
+	if (!islocal) {
+		if (!havekey) {
+			error("%s: No privkey sent!\n", nodeid);
+			/*
+			 * Skip. Okay, the problem is that the nodes out
+			 * there are not reporting the key!
+			goto skipit;
+			 */
+		}
+		else if (checkprivkey(client->sin_addr, privkey)) {
+			error("%s: privkey mismatch: %s!\n", nodeid, privkey);
+			goto skipit;
+		}
+	}
+
 	/*
 	 * Figure out what command was given.
 	 */
@@ -2297,9 +2336,10 @@ COMMAND_PROTOTYPE(dosfshostid)
 		signal(SIGALRM, dosfshostiddead);
 		alarm(1);
 
-		unlink(dspath);
-		if (symlink(sfspath, dspath) < 0)
+		if (unlink(dspath) < 0 ||
+		    symlink(sfspath, dspath) < 0) {
 			sfshostiddeadfl = 1;
+		}
 	}
 	alarm(0);
 	if (sfshostiddeadfl) {
@@ -3217,6 +3257,37 @@ checkdbredirect(char *nodeid)
 	return 0;
 }
 
+/*
+ * Check private key. 
+ */
+static int
+checkprivkey(struct in_addr ipaddr, char *privkey)
+{
+	MYSQL_RES	*res;
+	MYSQL_ROW	row;
+
+	res = mydb_query("select privkey from widearea_privkeys "
+			 "where IP='%s'",
+			 1, inet_ntoa(ipaddr));
+	
+	if (!res) {
+		error("checkprivkey: %s: DB Error getting privkey!\n",
+		      inet_ntoa(ipaddr));
+		return 1;
+	}
+
+	if (! (int)mysql_num_rows(res)) {
+		mysql_free_result(res);
+		return 1;
+	}
+	row = mysql_fetch_row(res);
+	mysql_free_result(res);
+	if (! row[0] || !row[0][0])
+		return 1;
+
+	return strcmp(privkey, row[0]);
+}
+ 
 #ifdef EVENTSYS
 /*
  * Connect to the event system. It's not an error to call this function if