#
if (!preg_match("/^http[s]?:\\/\\/([-\\w\\.]*)\\//", $redirect_to, $matches)) {
    PAGEARGERROR("Invalid redirection argument!");
}
$redirect_host = $matches[1];
#
# Right now all we allow is www.datapository.net, and that is really
# nfs.emulab.net.
#
if ($redirect_host != "www.datapository.net" && $redirect_host != "nfs.emulab.net") {
    PAGEARGERROR("Invalid redirection host '{$redirect_host}'");
}
#
# Okay, now see if the user is logged in. If not, the user will be
# be brought back here after logging in.
#
$this_user = CheckLoginOrDie();
$uid = $this_user->uid();
$isadmin = ISADMIN();
#
# Generate a cookie.
#
$authhash = GENHASH();
#
# Send it over to the server where it will save it.
#
SUEXEC("nobody", "nobody", "xlogin {$redirect_host} {$uid} {$authhash}", SUEXEC_ACTION_DIE);
#
# Now redirect the user over, passing along the hash in the URL.
#
header("Location: {$redirect_to}?user={$uid}&auth={$authhash}");
 function NewUser($uid, $flags, $args)
 {
     global $TBBASE, $TBMAIL_APPROVAL, $TBMAIL_AUDIT, $TBMAIL_WWW;
     global $MIN_UNIX_UID;
     $isleader = $flags & TBDB_NEWACCOUNT_PROJLEADER ? 1 : 0;
     $wikionly = $flags & TBDB_NEWACCOUNT_WIKIONLY ? 1 : 0;
     $webonly = $flags & TBDB_NEWACCOUNT_WEBONLY ? 1 : 0;
     #
     # If no uid, we need to generate a unique one for the user.
     #
     if (!$uid) {
         #
         # Take the first 5 letters of the email to form a root. That gives
         # us 3 digits to make it unique, since unix uids are limited to 8
         # chars, sheesh!
         #
         $email = $args["usr_email"];
         if (!preg_match('/^([-\\w\\+\\.]+)\\@([-\\w\\.]+)$/', $email, $matches)) {
             return null;
         }
         $token = $matches[1];
         # Squeeze out any dots or dashes.
         $token = preg_replace('/\\./', '', $token);
         $token = preg_replace('/\\-/', '', $token);
         # Trim off any trailing numbers or +foo tokens.
         if (!preg_match('/^([a-zA-Z]+)/', $token, $matches)) {
             return null;
         }
         $token = $matches[1];
         # First 5 chars, at most.
         $token = substr($token, 0, 5);
         # Grab all root matches from the DB.
         $query_result = DBQueryFatal("select uid from users " . "where uid like '{$token}%'");
         if (!$query_result) {
             return null;
         }
         # Easy; no matches at all!
         if (!mysql_num_rows($query_result)) {
             $uid = "{$token}" . "001";
         } else {
             $max = 0;
             #
             # Find unused slot. Must be a better way to do this!
             #
             while ($row = mysql_fetch_array($query_result)) {
                 $foo = $row[0];
                 # Split name from number
                 if (!preg_match('/^([a-zA-Z]+)(\\d*)$/', $foo, $matches)) {
                     return null;
                 }
                 $name = $matches[1];
                 $number = $matches[2];
                 # Must be exact root
                 if ($name != $token) {
                     continue;
                 }
                 # Backwards compatability; might not have appended number.
                 if (isset($number) && intval($number) > $max) {
                     $max = intval($number);
                 }
             }
             $max++;
             $uid = $token . sprintf("%03d", $max);
         }
     }
     #
     # The array of inserts is assumed to be safe already. Generate
     # a list of actual insert clauses to be joined below.
     #
     $insert_data = array();
     foreach ($args as $name => $value) {
         $insert_data[] = "{$name}='{$value}'";
     }
     # Every user gets a new unique index.
     $uid_idx = TBGetUniqueIndex('next_uid');
     # Get me an unused unix id. Nice query, eh? Basically, find
     # unused numbers by looking at existing numbers plus one, and check
     # to see if that number is taken.
     $query_result = DBQueryFatal("select u.unix_uid + 1 as start from users as u " . "left outer join users as r on " . "  u.unix_uid + 1 = r.unix_uid " . "where u.unix_uid>={$MIN_UNIX_UID} and " . "      u.unix_uid<60000 and " . "      r.unix_uid is null limit 1");
     if (!$query_result || !mysql_num_rows($query_result)) {
         TBERROR("Could not find an unused unix_uid!", 1);
     }
     $row = mysql_fetch_row($query_result);
     $unix_uid = $row[0];
     # Initial mailman_password.
     $mailman_password = substr(GENHASH(), 0, 10);
     # And a verification key.
     $verify_key = md5(uniqid(rand(), 1));
     # Now tack on other stuff we need.
     if ($wikionly) {
         $insert_data[] = "wikionly='1'";
     }
     if ($webonly) {
         $insert_data[] = "webonly='1'";
     }
     $insert_data[] = "usr_created=now()";
     $insert_data[] = "usr_modified=now()";
     $insert_data[] = "pswd_expires=date_add(now(), interval 1 year)";
     $insert_data[] = "unix_uid={$unix_uid}";
     $insert_data[] = "status='newuser'";
     $insert_data[] = "mailman_password='******'";
     $insert_data[] = "verify_key='{$verify_key}'";
     $insert_data[] = "uid_idx='{$uid_idx}'";
     $insert_data[] = "uid='{$uid}'";
     # Insert into DB. Should probably lock the table ...
     if (!DBQueryWarn("insert into users set " . implode(",", $insert_data))) {
         return null;
     }
     if (!DBQueryWarn("insert into user_stats (uid, uid_idx) " . "VALUES ('{$uid}', {$uid_idx})")) {
         DBQueryFatal("delete from users where uid_idx='{$uid_idx}'");
         return null;
     }
     $newuser = User::Lookup($uid_idx);
     if (!$newuser) {
         return null;
     }
     #
     # See if we are in an initial Emulab setup.
     #
     $FirstInitState = TBGetFirstInitState() == "createproject";
     if ($FirstInitState) {
         return $newuser;
     }
     # stuff for email message.
     $key = $newuser->verify_key();
     $usr_name = $newuser->name();
     $usr_email = $newuser->email();
     # Email to user.
     TBMAIL("{$usr_name} '{$uid}' <{$usr_email}>", "Your New User Key", "\n" . "Dear {$usr_name} ({$uid}):\n\n" . "This is your account verification key: {$key}\n\n" . "Please use this link to verify your user account:\n" . "\n" . "    {$TBBASE}/login.php3?vuid={$uid}&key={$key}\n" . "\n" . ($wikionly ? "Once you have verified your account, you will be able to access\n" . "the Wiki. You MUST verify your account first!" : ($webonly ? "Once you have verified your account, Testbed Operations will be\n" . "able to approve you. You MUST verify your account first!" : ($isleader ? "You will then be verified as a user. When you have been both\n" . "verified and approved by Testbed Operations, you will be marked\n" . "as an active user and granted full access to your account.\n" . "You MUST verify your account before your project can be approved!\n" : "Once you have verified your account, the project leader will be\n" . "able to approve you.\n\n" . "You MUST verify your account before the project leader can " . "approve you\n" . "After project approval, you will be marked as an active user, and\n" . "will be granted full access to your user account."))) . "\n\n" . "Thanks,\n" . "Testbed Operations\n", "From: {$TBMAIL_APPROVAL}\n" . "Bcc: {$TBMAIL_AUDIT}\n" . "Errors-To: {$TBMAIL_WWW}");
     return $newuser;
 }