diff --git a/wiki/GNUmakefile.in b/wiki/GNUmakefile.in
index cdf9536049e7c6913259768c7cf064e0888ad455..26000ecab9b7a99cf29d5d7e7ca5f67ed640f5a0 100644
--- a/wiki/GNUmakefile.in
+++ b/wiki/GNUmakefile.in
@@ -13,6 +13,7 @@ include $(OBJDIR)/Makeconf
 
 SBIN_SCRIPTS		= addwikiuser addwikiproj wikisetup delwikiuser \
 			  setwikigroups
+LIBEXEC_SCRIPTS		= wikixlogin
 
 CTRL_SBIN_SCRIPTS	= wikiproxy
 CTRL_LIB_FILES		= usertemplate webhometemplate
@@ -21,11 +22,13 @@ CTRL_LIB_FILES		= usertemplate webhometemplate
 # Force dependencies on the scripts so that they will be rerun through
 # configure if the .in file is changed.
 # 
-all:	$(SBIN_SCRIPTS) $(CTRL_SBIN_SCRIPTS) $(CTRL_LIB_FILES)
+all:	$(SBIN_SCRIPTS) $(CTRL_SBIN_SCRIPTS) $(CTRL_LIB_FILES) \
+	$(LIBEXEC_SCRIPTS)
 
 include $(TESTBED_SRCDIR)/GNUmakerules
 
 install: $(addprefix $(INSTALL_SBINDIR)/, $(SBIN_SCRIPTS)) \
+	 $(addprefix $(INSTALL_LIBEXECDIR)/, $(LIBEXEC_SCRIPTS)) \
 	 $(addprefix $(INSTALL_DIR)/opsdir/sbin/, $(CTRL_SBIN_SCRIPTS)) \
 	 $(addprefix $(INSTALL_DIR)/opsdir/lib/wiki/, $(CTRL_LIB_FILES))
 
@@ -42,6 +45,8 @@ post-install:
 	chmod u+s $(INSTALL_SBINDIR)/addwikiproj
 	chown root $(INSTALL_SBINDIR)/setwikigroups
 	chmod u+s $(INSTALL_SBINDIR)/setwikigroups
+	chown root $(INSTALL_LIBEXECDIR)/wikixlogin
+	chmod u+s $(INSTALL_LIBEXECDIR)/wikixlogin
 
 #
 # Control node installation (okay, plastic)
diff --git a/wiki/newlogon b/wiki/newlogon
index 1c9651fbf9fcf5f7f59718e627ed2457d698a2bb..8fc4e21ae3cd9354f6a6a143ea14611115e28d05 100755
--- a/wiki/newlogon
+++ b/wiki/newlogon
@@ -24,9 +24,18 @@ use TWiki;
 use TWiki::Plugins::SessionPlugin;
 
 my $oopsurl = "oopsloginfail";
+my $CREDDIR = "/var/db/cgisess";
 
 $query= new CGI;
 
+sub myerror($)
+{
+    my ($msg) = @_;
+
+    my $url = &TWiki::getOopsUrl(undef, "", $oopsurl, $msg);
+    TWiki::redirect($query, $url);
+}
+
 &main();
 
 sub main
@@ -34,17 +43,61 @@ sub main
     my $username = $query->param('username');
     my $password = $query->param('password');
     my $redurl   = $query->param('redurl');
+    my $bosscred = $query->param('bosscred');
 
-    chomp($username);
-    chomp($password);
+    #
+    # If bosscred provided, boss is trying to autologin the user using
+    # a key that it sent across via a backend script and stashed in the
+    # cookie dir. Find that file, compare the keys and if the key is not
+    # too terribly old, give the user the nod.
+    #
+    if (defined($bosscred)) {
+	if (!defined($username) || $username eq "") {
+	    myerror("Missing username argument");
+	    return;
+	}
+
+	my $file = "${CREDDIR}/$username";
+
+	if (! -e $file) {
+	    myerror("Cred file does not exist!");
+	    return;
+	}
+	if (!open(COK, $file)) {
+	    myerror("Cannot open cred file!");
+	    return;
+	}
+	my $cred  = <COK>;
+	my $stamp = <COK>;
+	close(COK);
+
+	# Compare credentials.
+	if (defined($cred)) {
+	    chomp($cred);
+	    if ($cred eq $bosscred) {
+		goto accepted;
+	    }
+	}
+	# Does not match. Redirect to login page.
+      dologon:
+	my $url = &TWiki::getViewUrl("TWiki", "DoLogin");
+	$url .= "?username=${username}";
+	$url .= "&redurl=${redurl}"
+	    if (defined($redurl) && $redurl ne "");
+	
+	TWiki::redirect($query, $url);
+	return;
+    }
 
+    #
+    # Normal login.
+    # 
     if (! ($username && $password)) {
-        my $url = &TWiki::getOopsUrl(undef, "", $oopsurl,
-			     "Missing arguments (username or password)");
-
-        TWiki::redirect( $query, $url );
+	myerror("Missing arguments (username or password)");
 	return;
     }
+    chomp($username);
+    chomp($password);
 
     #
     # Suck out the password entry.
@@ -63,9 +116,7 @@ sub main
     close(HTP);
 
     if (!defined($pwentry)) {
-        my $url = &TWiki::getOopsUrl(undef, "", $oopsurl,
-				     "No such user: '$username'");
-        TWiki::redirect( $query, $url );
+	myerror("No such user: '$username'");
 	return;
     }
 
@@ -78,15 +129,14 @@ sub main
     my $str = crypt($password, $encryptedpasswd);
 
     if ($str ne $encryptedpasswd) {
-        my $url = &TWiki::getOopsUrl(undef, "", $oopsurl,
-				     "Incorrect Password");
-        TWiki::redirect( $query, $url );
+	myerror("Incorrect Password");
 	return;
     }
-
+ 
     # This causes the query object to suddenly have a remote_user() value.
     # SessionPlugin uses that ...
-    $ENV{REMOTE_USER} = $username;
+ accepted:
+   $ENV{REMOTE_USER} = $username;
 
     #
     # Stuff we need to pass down. Note that I am not bothering with the
diff --git a/wiki/wikiproxy.in b/wiki/wikiproxy.in
index 3e0cde7b52dd7334764ccd6dd993b9acfb7a88e9..a2b80c89cfcd4068b3ab953f9db5c8a05cd82368 100644
--- a/wiki/wikiproxy.in
+++ b/wiki/wikiproxy.in
@@ -40,6 +40,7 @@ my $WIKIGROUPDIR = "$WIKIDATADIR/Main";
 my $WIKIARCHIVE  = "$WIKIDATADIR/_archive";
 my $WIKIPASSWD   = "$WIKIDIR/data/.htpasswd";
 my $USERMAPDB    = "$WIKIDIR/data/.usermap";
+my $COOKIEDIR    = "/var/db/cgisess";
 my $WIKIUSER     = "nobody";
 my $WIKIGROUP    = "nobody";
 my $CI		 = "ci";
@@ -99,6 +100,9 @@ elsif ($action eq "addproject") {
 elsif ($action eq "setgroups") {
     exit(SetWikiGroups(@ARGV));
 }
+elsif ($action eq "xlogin") {
+    exit(WikixLogin(@ARGV));
+}
 else {
     die("*** $0:\n".
 	"    Do not know what to do with '$action'!\n");
@@ -724,6 +728,31 @@ sub CI($$) {
     }
     return $? >> 8;
 }
+
+#
+# Backdoor Login
+#
+sub WikixLogin(@)
+{
+    usage()
+	if (@_ != 2);
+
+    my ($user, $secretkey) = @_;
+
+    #
+    # Create a little file that holds the secret key, named by the user.
+    # The TWiki login script will check for the existence of this file,
+    # and use the key inside it to match against the key provided by the
+    # client browser.
+    #
+    open(KEY, ">${COOKIEDIR}/$user") or
+	fatal("Could not open ${COOKIEDIR}/$user for writing!");
+
+    print KEY "$secretkey\n";
+    print KEY time() . "\n";
+    close(KEY);
+    return 0;
+}
      
 sub fatal($)
 {
diff --git a/wiki/wikixlogin.in b/wiki/wikixlogin.in
new file mode 100644
index 0000000000000000000000000000000000000000..6c865130a167826ae611300968af7000f96515f1
--- /dev/null
+++ b/wiki/wikixlogin.in
@@ -0,0 +1,127 @@
+#!/usr/bin/perl -wT
+#
+# EMULAB-COPYRIGHT
+# Copyright (c) 2005 University of Utah and the Flux Group.
+# All rights reserved.
+#
+use English;
+use Getopt::Std;
+use Fcntl ':flock';
+
+#
+# Add a user to the wiki on ops. Also allow update of password.
+#
+sub usage()
+{
+    print STDOUT "Usage: wikixlogin <uid> <key>\n";
+    exit(-1);
+}
+my $optlist = "d";
+my $debug   = 0;
+
+#
+# Configure variables
+#
+my $TB		= "@prefix@";
+my $TBOPS       = "@TBOPSEMAIL@";
+my $CONTROL     = "@USERNODE@";
+my $BOSSNODE	= "@BOSSNODE@";
+my $WIKISUPPORT = @WIKISUPPORT@;
+my $SSH         = "$TB/bin/sshtb";
+my $WIKIPROXY   = "$TB/sbin/wikiproxy";
+
+#
+# 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 libdb;
+use libtestbed;
+
+#
+# We do not 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");
+}
+
+#
+# If no wiki support, just exit. 
+#
+if (! $WIKISUPPORT) {
+    print "WIKI support is not enabled. Exit ...\n";
+    exit(0);
+}
+
+#
+# Parse command arguments. Once we return from getopts, all that should be
+# left are the required arguments.
+#
+%options = ();
+if (! getopts($optlist, \%options)) {
+    usage();
+}
+if (defined($options{"d"})) {
+    $debug = 1;
+}
+if (@ARGV != 2) {
+    usage();
+}
+my $user = $ARGV[0];
+my $key  = $ARGV[1];
+
+#
+# Untaint args.
+#
+if ($user =~ /^([-\w]+)$/) {
+    $user = $1;
+}
+else {
+    die("Bad data in user: $user.");
+}
+if ($key =~ /^([\w]+)$/) {
+    $key = $1;
+}
+else {
+    fatal("Bad data in secretkey!");
+}
+
+#
+# For ssh.
+#
+$UID = $EUID;
+
+if ($CONTROL ne $BOSSNODE) {
+    if (system("$SSH -host $CONTROL $WIKIPROXY xlogin $user '$key'")) {
+	fatal("$WIKIPROXY failed on $CONTROL!");
+    }
+}
+exit(0);
+
+sub fatal($)
+{
+    my($mesg) = $_[0];
+
+    die("*** $0:\n".
+	"    $mesg\n");
+}
diff --git a/www/defs.php3.in b/www/defs.php3.in
index 747746fb77daa4b1052c0919ad314a6fa9dc5462..031e1f649c4b381bbe4b3d8f8fb5df17991cf138 100644
--- a/www/defs.php3.in
+++ b/www/defs.php3.in
@@ -16,7 +16,8 @@ $TBWWW		= "@TBWWW@";
 $THISHOMEBASE	= "@THISHOMEBASE@";
 $ELABINELAB     = @ELABINELAB@;
 $WIKISUPPORT    = @WIKISUPPORT@;
-$WIKIURL        = "https://${USERNODE}/twiki/bin/view";
+$WIKIURL        = "https://${USERNODE}/twiki/bin/newlogon";
+$WIKICOOKIENAME = "WikiCookie";
 
 $TBMAILADDR_OPS		= "@TBOPSEMAIL_NOSLASH@";
 $TBMAILADDR_WWW		= "@TBWWWEMAIL_NOSLASH@";
diff --git a/www/gotowiki.php3 b/www/gotowiki.php3
new file mode 100644
index 0000000000000000000000000000000000000000..97d8346488840104dda5c5e28116dd111fe79610
--- /dev/null
+++ b/www/gotowiki.php3
@@ -0,0 +1,49 @@
+<?php
+#
+# EMULAB-COPYRIGHT
+# Copyright (c) 2000-2005 University of Utah and the Flux Group.
+# All rights reserved.
+#
+include("defs.php3");
+
+if (!$WIKISUPPORT) {
+    header("Location: index.php3");
+    return;
+}
+
+# No Pageheader since we spit out a redirection below.
+$uid = GETLOGIN();
+LOGGEDINORDIE($uid, CHECKLOGIN_USERSTATUS|
+	      CHECKLOGIN_WEBONLY|CHECKLOGIN_WIKIONLY);
+
+#
+# The page to zap to on the other side
+#
+if (isset($redurl) && $redurl == "") {
+    unset($redurl);
+}
+
+#
+# Look for our wikicookie. If the browser has it, then there is nothing
+# more to do; just redirect the user over to the wiki.
+#
+if (isset($_COOKIE[$WIKICOOKIENAME])) {
+    $wikihash = $_COOKIE[$WIKICOOKIENAME];
+    
+    header("Location: ${WIKIURL}?username=${uid}&bosscred=${wikihash}" .
+	   (isset($redurl) ? "&redurl=${redurl}" : ""));
+    return;
+}
+
+#
+# Generate a cookie. Send it over to the wiki server and stash it into
+# the users browser for subsequent requests (until logout).
+# 
+$wikihash = GENHASH();
+
+SUEXEC("nobody", "nobody", "wikixlogin $uid $wikihash", SUEXEC_ACTION_DIE);
+
+setcookie($WIKICOOKIENAME, $wikihash, 0, "/", $TBAUTHDOMAIN, $TBSECURECOOKIES);
+header("Location: ${WIKIURL}?username=${uid}&bosscred=${wikihash}" .
+	   (isset($redurl) ? "&redurl=${redurl}" : ""));
+?>
diff --git a/www/menu.php3 b/www/menu.php3
index 00e8527f80f5cb38e16213cac1598d8eaba67ba9..345d9f54aec7b9a6c6be69e6a001e2b3f1d636e5 100644
--- a/www/menu.php3
+++ b/www/menu.php3
@@ -366,8 +366,8 @@ function WRITESIDEBAR() {
 		    $wikiname = $CHECKLOGIN_WIKINAME;
 		
 		    WRITESIDEBARBUTTON_ABSCOOL("My Wikis",
-					       "${WIKIURL}/Main/$wikiname",
-					       "${WIKIURL}/Main/$wikiname");
+			       "gotowiki.php3?redurl=Main/$wikiname",
+			       "gotowiki.php3?redurl=Main/$wikiname");
 		}
 	    
 		WRITESIDEBARBUTTON("Update User Information",
@@ -391,8 +391,8 @@ function WRITESIDEBAR() {
 		    $wikiname = $CHECKLOGIN_WIKINAME;
 		
 		    WRITESIDEBARBUTTON_ABSCOOL("My Wikis",
-					       "${WIKIURL}/Main/$wikiname",
-					       "${WIKIURL}/Main/$wikiname");
+			       "gotowiki.php3?redurl=Main/$wikiname",
+			       "gotowiki.php3?redurl=Main/$wikiname");
 		}
 	    
                 # Since a user can be a member of more than one project,
diff --git a/www/showstuff.php3 b/www/showstuff.php3
index 9cab86341d0220733bcd93db6c3135b2e8c4b8c7..f2c80c87ced3214c65f9b169f0ada6d6c8db709d 100644
--- a/www/showstuff.php3
+++ b/www/showstuff.php3
@@ -14,7 +14,7 @@
 # A project
 #
 function SHOWPROJECT($pid, $thisuid) {
-    global $WIKISUPPORT, $WIKIURL;
+    global $WIKISUPPORT;
 
     $query_result =
 	DBQueryFatal("select p.*,g.wikiname from projects as p ".
@@ -92,7 +92,7 @@ function SHOWPROJECT($pid, $thisuid) {
           </tr>\n";
 
     if ($WIKISUPPORT && isset($wikiname)) {
-	$wikiurl = "${WIKIURL}/$wikiname/WebHome";
+	$wikiurl = "gotowiki.php3?redurl=$wikiname/WebHome";
 	
 	echo "<tr>
                   <td>Project Wiki:</td>
@@ -383,7 +383,7 @@ function SHOWGROUPMEMBERSHIP($uid) {
 # A User
 #
 function SHOWUSER($uid) {
-    global $WIKISUPPORT, $WIKIURL;
+    global $WIKISUPPORT;
 
     $userinfo_result =
 	DBQueryFatal("SELECT * from users where uid='$uid'");
@@ -468,7 +468,7 @@ function SHOWUSER($uid) {
           </tr>\n";
 
     if ($WIKISUPPORT && isset($wikiname)) {
-	$wikiurl = "${WIKIURL}/Main/$wikiname";
+	$wikiurl = "gotowiki.php3?redurl=Main/$wikiname";
 	
 	echo "<tr>
                   <td>Emulab Wiki Page:</td>
diff --git a/www/tbauth.php3 b/www/tbauth.php3
index 9424c7ff3071f2d4ea964182f68fe2b976a3540a..7e0185bbf694a61ea3b797e6e6c219c0bd6157c6 100644
--- a/www/tbauth.php3
+++ b/www/tbauth.php3
@@ -530,6 +530,7 @@ function DOLOGIN($token, $password, $adminmode = 0) {
     global $TBAUTHCOOKIE, $TBAUTHDOMAIN, $TBAUTHTIMEOUT;
     global $TBNAMECOOKIE, $TBLOGINCOOKIE, $TBSECURECOOKIES;
     global $TBMAIL_OPS, $TBMAIL_AUDIT, $TBMAIL_WWW;
+    global $WIKISUPPORT, $WIKICOOKIENAME;
     
     # Caller makes these checks too.
     if ((!TBvalid_uid($token) && !TBvalid_email($token)) ||
@@ -785,6 +786,7 @@ function VERIFYPASSWD($uid, $password) {
 #
 function DOLOGOUT($uid) {
     global $CHECKLOGIN_STATUS, $TBAUTHCOOKIE, $TBLOGINCOOKIE, $TBAUTHDOMAIN;
+    global $WIKISUPPORT, $WIKICOOKIENAME;
 
     # Pedantic check.
     if (!TBvalid_uid($uid)) {
@@ -811,6 +813,9 @@ function DOLOGOUT($uid) {
     #
     setcookie($TBAUTHCOOKIE, "", $timeout, "/", $TBAUTHDOMAIN, 0);
     setcookie($TBLOGINCOOKIE, "", $timeout, "/", $TBAUTHDOMAIN, 0);
+    if ($WIKISUPPORT) {
+	setcookie($WIKICOOKIENAME, "", $timeout, "/", $TBAUTHDOMAIN, 0);
+    }
 
     return 0;
 }