joinproject.php3 21.2 KB
Newer Older
1
<?php
Leigh Stoller's avatar
Leigh Stoller committed
2 3
#
# EMULAB-COPYRIGHT
4
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
Leigh Stoller's avatar
Leigh Stoller committed
5 6
# All rights reserved.
#
7 8 9 10
include("defs.php3");

#
# No PAGEHEADER since we spit out a Location header later. See below.
11
#
12 13 14 15 16 17 18 19

#
# Get current user.
# 
$uid = GETLOGIN();

#
# If a uid came in, then we check to see if the login is valid.
20
# We require that the user be logged in to start a second project.
21 22
#
if ($uid) {
23 24
    # Allow unapproved users to join multiple groups ...
    # Must be verified though.
25
    LOGGEDINORDIE($uid, CHECKLOGIN_UNAPPROVED|CHECKLOGIN_WEBONLY);
26 27 28 29 30 31 32 33 34 35
    $joining_uid = $uid;
    $returning = 1;
}
else {
    #
    # No uid, so must be new.
    #
    $returning = 0;
}

Leigh Stoller's avatar
Leigh Stoller committed
36 37 38 39
$ACCOUNTWARNING =
    "Before continuing, please make sure your username " .
    "reflects your normal login name. ".
    "Emulab accounts are not to be shared amongst users!";
40

Leigh Stoller's avatar
Leigh Stoller committed
41 42 43
$EMAILWARNING =
    "Before continuing, please make sure the email address you have ".
    "provided is current and non-pseudonymic. Redirections and anonymous ".
44 45
    "email addresses are not allowed.";

46 47 48 49 50 51
#
# Spit the form out using the array of data. 
# 
function SPITFORM($formfields, $returning, $errors)
{
    global $TBDB_UIDLEN, $TBDB_PIDLEN, $TBDB_GIDLEN;
52
    global $usr_keyfile;
53
    global $ACCOUNTWARNING, $EMAILWARNING;
54 55 56
    
    PAGEHEADER("Apply for Project Membership");

57 58
    if (! $returning) {
	echo "<center><font size=+1>
59 60 61
               If you already have an Emulab account,
               <a href=login.php3?refer=1>
               <font color=red>please log on first!</font></a>
62 63 64
              </font></center><br>\n";
    }

65
    if ($errors) {
66 67
	echo "<table class=nogrid
                     align=center border=0 cellpadding=6 cellspacing=0>
68
              <tr>
69
                 <th align=center colspan=2>
70
                   <font size=+1 color=red>
71
                      &nbsp;Oops, please fix the following errors!&nbsp;
72 73 74 75 76 77
                   </font>
                 </td>
              </tr>\n";

	while (list ($name, $message) = each ($errors)) {
	    echo "<tr>
78 79 80 81
                     <td align=right>
                       <font color=red>$name:&nbsp;</font></td>
                     <td align=left>
                       <font color=red>$message</font></td>
82 83 84 85 86 87 88
                  </tr>\n";
	}
	echo "</table><br>\n";
    }

    echo "<table align=center border=1> 
          <tr>
89
            <td align=center colspan=3>
90 91 92 93 94
                Fields marked with * are required;
                those marked + are highly recommended.
            </td>
          </tr>\n

95 96
          <form enctype=multipart/form-data
                action=joinproject.php3 method=post>\n";
97 98 99 100 101 102

    if (! $returning) {
        #
        # UserName:
        #
        echo "<tr>
103
                  <td colspan=2>*Username (no blanks, lowercase):</td>
104 105 106 107 108
                  <td class=left>
                      <input type=text
                             name=\"formfields[joining_uid]\"
                             value=\"" . $formfields[joining_uid] . "\"
	                     size=$TBDB_UIDLEN
109
                             onchange=\"alert('$ACCOUNTWARNING')\"
110 111 112 113 114 115 116 117
	                     maxlength=$TBDB_UIDLEN>
                  </td>
              </tr>\n";

	#
	# Full Name
	#
        echo "<tr>
118
                  <td colspan=2>*Full Name:</td>
119 120 121 122 123 124 125 126 127 128 129 130
                  <td class=left>
                      <input type=text
                             name=\"formfields[usr_name]\"
                             value=\"" . $formfields[usr_name] . "\"
	                     size=30>
                  </td>
              </tr>\n";

        #
	# Title/Position:
	# 
	echo "<tr>
131
                  <td colspan=2>*Title/Position:</td>
132 133 134 135 136 137 138 139 140 141 142 143
                  <td class=left>
                      <input type=text
                             name=\"formfields[usr_title]\"
                             value=\"" . $formfields[usr_title] . "\"
	                     size=30>
                  </td>
              </tr>\n";

        #
	# Affiliation:
	# 
	echo "<tr>
144
                  <td colspan=2>*Institutional<br>Affiliation:</td>
145 146 147 148 149 150 151 152 153 154 155 156
                  <td class=left>
                      <input type=text
                             name=\"formfields[usr_affil]\"
                             value=\"" . $formfields[usr_affil] . "\"
	                     size=40>
                  </td>
              </tr>\n";

	#
	# User URL
	#
	echo "<tr>
157
                  <td colspan=2>Home Page URL:</td>
158 159 160 161 162 163 164 165 166 167 168 169
                  <td class=left>
                      <input type=text
                             name=\"formfields[usr_URL]\"
                             value=\"" . $formfields[usr_URL] . "\"
	                     size=45>
                  </td>
              </tr>\n";

	#
	# Email:
	#
	echo "<tr>
170
                  <td colspan=2>*Email Address[<b>1</b>]:</td>
171 172 173 174
                  <td class=left>
                      <input type=text
                             name=\"formfields[usr_email]\"
                             value=\"" . $formfields[usr_email] . "\"
175
                             onchange=\"alert('$EMAILWARNING')\"
176 177 178 179 180 181 182 183
	                     size=30>
                  </td>
              </tr>\n";

	#
	# Postal Address
	#
	echo "<tr>
184
                  <td colspan=2>*Postal Address:</td>
185 186 187 188 189 190 191 192 193 194 195 196
                  <td class=left>
                      <input type=text
                             name=\"formfields[usr_addr]\"
                             value=\"" . $formfields[usr_addr] . "\"
	                     size=40>
                  </td>
              </tr>\n";

	#
	# Phone
	#
	echo "<tr>
197
                  <td colspan=2>*Phone #:</td>
198 199 200 201 202 203 204 205
                  <td class=left>
                      <input type=text
                             name=\"formfields[usr_phone]\"
                             value=\"" . $formfields[usr_phone] . "\"
	                     size=15>
                  </td>
              </tr>\n";

206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
	#
	# SSH public key
	#
	echo "<tr>
                  <td rowspan><center>
                               Your SSH Pub Key: &nbsp<br>
                                    [<b>2</b>]
                              </center></td>

                  <td rowspan><center>Upload (1K max)[<b>3</b>]<br>
                                  <b>Or</b><br>
                               Insert Key
                             </center></td>

                  <td rowspan>
                      <input type=hidden name=MAX_FILE_SIZE value=1024>
                      <input type=file
                             name=usr_keyfile
                             value=\"" . $usr_keyfile . "\"
	                     size=50>
                      <br>
                      <br>
	              <input type=text
                             name=\"formfields[usr_key]\"
230
                             value=\"$formfields[usr_key]\"
231 232 233 234 235
	                     size=50
	                     maxlength=1024>
                  </td>
              </tr>\n";

236 237 238 239 240
	#
	# Password. Note that we do not resend the password. User
	# must retype on error.
	#
	echo "<tr>
241
                  <td colspan=2>*Password[<b>1</b>]:</td>
242 243 244 245 246 247 248
                  <td class=left>
                      <input type=password
                             name=\"formfields[password1]\"
                             size=8></td>
              </tr>\n";

        echo "<tr>
249
                  <td colspan=2>*Retype Password:</td>
250 251 252 253 254 255 256 257 258 259 260
                  <td class=left>
                      <input type=password
                             name=\"formfields[password2]\"
                             size=8></td>
             </tr>\n";
    }

    #
    # Project Name:
    #
    echo "<tr>
261
              <td colspan=2>*Project Name (no blanks):</td>
262 263 264 265 266 267 268 269 270 271 272 273
              <td class=left>
                  <input type=text
                         name=\"formfields[pid]\"
                         value=\"" . $formfields[pid] . "\"
	                 size=$TBDB_PIDLEN maxlength=$TBDB_PIDLEN>
              </td>
          </tr>\n";

    #
    # Group Name:
    #
    echo "<tr>
274
              <td colspan=2>Group Name:<br>
275 276 277 278 279 280 281 282 283 284
              (Leave blank unless you <em>know</em> the group name)</td>
              <td class=left>
                  <input type=text
                         name=\"formfields[gid]\"
                         value=\"" . $formfields[gid] . "\"
	                 size=$TBDB_GIDLEN maxlength=$TBDB_GIDLEN>
              </td>
          </tr>\n";

    echo "<tr>
285
              <td colspan=3 align=center>
286 287 288 289 290 291 292 293 294 295 296 297
                 <b><input type=submit name=submit value=Submit></b>
              </td>
          </tr>\n";

    echo "</form>
          </table>\n";

    echo "<h4><blockquote><blockquote>
          <ol>
            <li> Please consult our
                 <a href = 'docwrapper.php3?docname=security.html'>
                 security policies</a> for information
298 299 300 301
                 regarding passwords and email addresses.\n";
    if (! $returning) {
	echo "<li> If you want us to use your existing ssh public key,
                   then either paste it in or specify the path to your
302
                   your identity.pub file.  <font color=red>NOTE:</font>
303 304
                   We use the <a href=http://www.openssh.org>OpenSSH</a>
                   key format,
305 306
                   which has a slightly different protocol 2 public key format
                   than some of the commercial vendors such as
307
                   <a href=http://www.ssh.com>SSH Communications</a>. If you
308 309 310 311
                   use one of these commercial vendors, then please
                   upload the public  key file and we will convert it
                   for you. <i>Please do not paste it in.</i>\n

312 313 314 315 316 317
              <li> Note to <a href=http://www.opera.com><b>Opera 5</b></a>
                   users: The file upload mechanism is broken in Opera, so
                   you cannot specify a local file for upload. Instead,
                   please paste your public key in.\n";
    }
    echo "</ol>
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
          </blockquote></blockquote>
          </h4>\n";
}

#
# The conclusion of a join request. See below.
# 
if (isset($finished)) {
    PAGEHEADER("Apply for Project Membership");

    #
    # Generate some warm fuzzies.
    #
    echo "<p>
          The project leader has been notified of your application.
          He/She will make a decision and either approve or deny your
          application, and you will be notified via email as soon as a
          decision has been made.";

    if (! $returning) {
	echo "<br>
              <p>
              In the meantime, as a new user of the Testbed you will receive
              a key via email.
              When you receive the message, please follow the instructions
              contained in the message on how to verify your account.\n";
    }

    PAGEFOOTER();
    return;
}

#
# On first load, display a virgin form and exit.
#
if (! isset($submit)) {
    $defaults = array();
    $defaults[usr_URL] = "$HTTPTAG";
356 357 358 359 360 361 362 363 364 365

    #
    # These two allow presetting the pid/gid.
    # 
    if (isset($target_pid) && strcmp($target_pid, "")) {
	$defaults[pid] = $target_pid;
    }
    if (isset($target_gid) && strcmp($target_gid, "")) {
	$defaults[gid] = $target_gid;
    }
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
    
    SPITFORM($defaults, $returning, 0);
    PAGEFOOTER();
    return;
}

#
# Otherwise, must validate and redisplay if errors
#
$errors = array();

#
# These fields are required!
#
if (! $returning) {
    if (!isset($formfields[joining_uid]) ||
	strcmp($formfields[joining_uid], "") == 0) {
	$errors["Username"] = "Missing Field";
    }
    else {
	if (! ereg("^[a-zA-Z][-_a-zA-Z0-9]+$", $formfields[joining_uid])) {
	    $errors["UserName"] =
		"Must be lowercase alphanumeric only<br>".
		"and must begin with a lowercase alpha";
	}
	elseif (strlen($formfields[joining_uid]) > $TBDB_UIDLEN) {
	    $errors["UserName"] =
		"Too long! Must be less than or to $TBDB_UIDLEN";
	}
	elseif (TBCurrentUser($formfields[joining_uid])) {
	    $errors["UserName"] =
		"Already in use. Select another";
	}
    }
    if (!isset($formfields[usr_title]) ||
	strcmp($formfields[usr_title], "") == 0) {
	$errors["Title/Position"] = "Missing Field";
    }
    if (!isset($formfields[usr_name]) ||
	strcmp($formfields[usr_name], "") == 0) {
	$errors["Full Name"] = "Missing Field";
    }
408 409 410
    elseif (! preg_match("/^[-\w\. ]*$/", $formfields[usr_name])) {
	$errors["Full Name"] = "Invalid characters";
    }
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
    if (!isset($formfields[usr_affil]) ||
	strcmp($formfields[usr_affil], "") == 0) {
	$errors["Affiliation"] = "Missing Field";
    }
    if (!isset($formfields[usr_email]) ||
	strcmp($formfields[usr_email], "") == 0) {
	$errors["Email Address"] = "Missing Field";
    }
    else {
	$usr_email    = $formfields[usr_email];
	$email_domain = strstr($usr_email, "@");
    
	if (! $email_domain ||
	    strcmp($usr_email, $email_domain) == 0 ||
	    strlen($email_domain) <= 1 ||
	    ! strstr($email_domain, ".")) {
	    $errors["Email Address"] = "Looks invalid!";
	}
    }
    if (isset($formfields[usr_URL]) &&
	strcmp($formfields[usr_URL], "") &&
	strcmp($formfields[usr_URL], $HTTPTAG) &&
	! CHECKURL($formfields[usr_URL], $urlerror)) {
	$errors["Home Page URL"] = $urlerror;
    }
    if (!isset($formfields[usr_addr]) ||
	strcmp($formfields[usr_addr], "") == 0) {
	$errors["Postal Address"] = "Missing Field";
    }
    if (!isset($formfields[usr_phone]) ||
	strcmp($formfields[usr_phone], "") == 0) {
	$errors["Phone #"] = "Missing Field";
    }
444
    elseif (! ereg("^[\(]*[0-9][-\(\) 0-9ext]+$", $formfields[usr_phone])) {
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
	$errors["Phone"] = "Invalid characters";
    }
    if (!isset($formfields[password1]) ||
	strcmp($formfields[password1], "") == 0) {
	$errors["Password"] = "Missing Field";
    }
    if (!isset($formfields[password2]) ||
	strcmp($formfields[password2], "") == 0) {
	$errors["Confirm Password"] = "Missing Field";
    }
    elseif (strcmp($formfields[password1], $formfields[password2])) {
	$errors["Confirm Password"] = "Does not match Password";
    }
    elseif (! CHECKPASSWORD($formfields[joining_uid],
			    $formfields[password1],
			    $formfields[usr_name],
			    $formfields[usr_email], $checkerror)) {
	$errors["Password"] = "$checkerror";
    }
}
if (!isset($formfields[pid]) ||
    strcmp($formfields[pid], "") == 0) {
    $errors["Project Name"] = "Missing Field";
}

if (count($errors)) {
    SPITFORM($formfields, $returning, $errors);
    PAGEFOOTER();
    return;
}

#
# Certain of these values must be escaped or otherwise sanitized.
#
if (!$returning) {
    $joining_uid       = $formfields[joining_uid];
    $usr_title         = addslashes($formfields[usr_title]);
    $usr_name          = addslashes($formfields[usr_name]);
    $usr_affil         = addslashes($formfields[usr_affil]);
    $usr_email         = $formfields[usr_email];
    $usr_addr          = addslashes($formfields[usr_addr]);
    $usr_phone         = $formfields[usr_phone];
    $password1         = $formfields[password1];
    $password2         = $formfields[password2];

    if (! isset($formfields[usr_URL]) ||
	strcmp($formfields[usr_URL], "") == 0 ||
	strcmp($formfields[usr_URL], $HTTPTAG) == 0) {
	$usr_URL = "";
    }
    else {
	$usr_URL = $formfields[usr_URL];
    }
498 499

    #
500 501
    # Pub Key.
    #
502 503
    if (isset($formfields[usr_key]) &&
	strcmp($formfields[usr_key], "")) {
504
        #
505 506
        # This is passed off to the shell, so taint check it.
        # 
507 508 509 510
	if (! preg_match("/^[-\w\s\.\@\+\/\=]*$/", $formfields[usr_key])) {
	    $errors["PubKey"] = "Invalid characters";
	}
	else {
511 512 513 514 515 516 517
            #
            # Replace any embedded newlines first.
            #
	    $formfields[usr_key] =
		ereg_replace("[\n]", "", $formfields[usr_key]);
	    $usr_key = $formfields[usr_key];
	    $addpubkeyargs = "-k $joining_uid '$usr_key' ";
518
	}
519
    }
520

521 522 523 524 525 526 527
    #
    # If usr provided a file for the key, it overrides the paste in text.
    #
    if (isset($usr_keyfile) &&
	strcmp($usr_keyfile, "") &&
	strcmp($usr_keyfile, "none")) {

528 529
	if (! stat($usr_keyfile)) {
	    $errors["PubKey File"] = "No such file";
530
	}
531 532
	else {
	    $addpubkeyargs = "$joining_uid $usr_keyfile";
533
	    chmod($usr_keyfile, 0644);	
534 535
	}
    }
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
}
else {
    #
    # Grab info from the DB for the email message below. Kinda silly.
    #
    $query_result =
	DBQueryFatal("select * from users where uid='$joining_uid'");
    
    $row = mysql_fetch_array($query_result);
    
    $usr_title	= $row[usr_title];
    $usr_name	= $row[usr_name];
    $usr_affil	= $row[usr_affil];
    $usr_email	= $row[usr_email];
    $usr_addr	= $row[usr_addr];
    $usr_phone	= $row[usr_phone];
    $usr_URL    = $row[usr_URL];
}
$pid          = $formfields[pid];
$usr_expires  = date("Y:m:d", time() + (86400 * 120));

if (isset($formfields[gid]) && strcmp($formfields[gid], "")) {
    $gid = $formfields[gid];
}
else {
    $gid = $pid;
}

if (! ereg("^[a-zA-Z][-_a-zA-Z0-9]+$", $pid) ||
    strlen($pid) > $TBDB_PIDLEN || ! TBValidProject($pid)) {
    $errors["Project Name"] = "Invalid Project Name";
}
elseif (! ereg("^[a-zA-Z][-_a-zA-Z0-9]+$", $gid) ||
	strlen($gid) > $TBDB_GIDLEN ||
	!TBValidGroup($pid, $gid)) {
    $errors["Group Name"] = "Invalid Group Name";
}
elseif (TBGroupMember($joining_uid, $pid, $gid, $approved)) {
    $errors["Membership"] = "You are already a member";
}

577 578 579 580
#
# Verify key format.
#
if (isset($addpubkeyargs) &&
581
    ADDPUBKEY($joining_uid, "webaddpubkey -n $addpubkeyargs")) {
582 583 584
    $errors["Pubkey Format"] = "Could not be parsed. Is it a public key?";
}

585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
if (count($errors)) {
    SPITFORM($formfields, $returning, $errors);
    PAGEFOOTER();
    return;
}

#
# For a new user:
# * Create a new account in the database.
# * Add user email to the list of email address.
# * Generate a mail message to the user with the verification key.
#
if (! $returning) {
    $encoding = crypt("$password1");

600 601 602 603 604
    #
    # Must be done before user record is inserted!
    # XXX Since user does not exist, must run as nobody. Script checks. 
    # 
    if (isset($addpubkeyargs)) {
605
	ADDPUBKEY($joining_uid, "webaddpubkey $addpubkeyargs");
606 607
    }

608 609 610
    DBQueryFatal("INSERT INTO users ".
	"(uid,usr_created,usr_expires,usr_name,usr_email,usr_addr,".
	" usr_URL,usr_phone,usr_title,usr_affil,usr_pswd,unix_uid,".
611
	" status,pswd_expires,usr_modified) ".
612 613 614 615
	"VALUES ('$joining_uid', now(), '$usr_expires', '$usr_name', ".
        "'$usr_email', ".
	"'$usr_addr', '$usr_URL', '$usr_phone', '$usr_title', '$usr_affil', ".
        "'$encoding', NULL, 'newuser', ".
616
	"date_add(now(), interval 1 year), now())");
617

618
    $key = TBGenVerificationKey($joining_uid);
619 620

    TBMAIL("$usr_name '$joining_uid' <$usr_email>",
621 622 623 624 625 626 627 628 629 630 631 632 633 634
      "Your New User Key",
      "\n".
      "Dear $usr_name ($joining_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=$joining_uid&key=$key\n".
      "\n".
      "Once you have verified your account, the project leader will be\n".
      "able to approve you. You MUST verify your account before the project\n".
      "leader can approve you. After project approval, you will be\n".
      "marked as an active user, and will be granted full access to your\n".
      "user account.\n\n".
      "Thanks,\n".
635
      "Testbed Operations\n",
636 637 638
      "From: $TBMAIL_APPROVAL\n".
      "Bcc: $TBMAIL_AUDIT\n".
      "Errors-To: $TBMAIL_WWW");
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661
}

#
# Add to the group, but with trust=none. The project/group leader will have
# to upgrade the trust level, making the new user real.
#
$query_result =
    DBQueryFatal("insert into group_membership ".
		 "(uid,gid,pid,trust,date_applied) ".
		 "values ('$joining_uid','$gid','$pid','none', now())");

#
# This could be a new user or an old user trying to join a specific group
# in a project. If the user is new to the project too, then must insert
# a group_membership in the default group for the project. 
#
if (! TBGroupMember($joining_uid, $pid, $pid, $approved)) {
    DBQueryFatal("insert into group_membership ".
		 "(uid,gid,pid,trust,date_applied) ".
		 "values ('$joining_uid','$pid','$pid','none', now())");
}

#
662
# Generate an email message to the proj/group leaders.
663 664 665 666 667 668 669 670 671 672 673 674
#
$query_result =
    DBQueryFatal("select usr_name,usr_email,leader from users as u ".
		 "left join groups as g on u.uid=g.leader ".
		 "where g.pid='$pid' and g.gid='$gid'");
if (($row = mysql_fetch_row($query_result)) == 0) {
    TBERROR("DB Error getting email address for group leader $leader!", 1);
}
$leader_name = $row[0];
$leader_email = $row[1];
$leader_uid = $row[2];

675 676
$allleaders = TBLeaderMailList($pid,$gid);

677
#
678 679 680
# The mail message to the leader. We send this for returning users
# who are are also verified, since they could not use this page
# if they were not verified.
681
#
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700
if ($returning) {
    TBMAIL("$leader_name '$leader_uid' <$leader_email>",
	   "$joining_uid $pid Project Join Request",
	   "$usr_name is trying to join your group $gid in project $pid.\n".
	   "\n".
	   "Contact Info:\n".
	   "Name:            $usr_name\n".
	   "Emulab ID:       $joining_uid\n".
	   "Email:           $usr_email\n".
	   "User URL:        $usr_URL\n".
	   "Title:           $usr_title\n".
	   "Affiliation:     $usr_affil\n".
	   "Address:         $usr_addr\n".
	   "Phone:           $usr_phone\n".
	   "\n".
	   "Please return to $TBWWW,\n".
	   "log in, and select the 'New User Approval' page to enter your\n".
	   "decision regarding $usr_name's membership in your project.\n\n".
	   "Thanks,\n".
701
	   "Testbed Operations\n",
702
	   "From: $TBMAIL_APPROVAL\n".
703
	   "Cc: $allleaders\n".
704 705 706
	   "Bcc: $TBMAIL_AUDIT\n".
	   "Errors-To: $TBMAIL_WWW");
}
707 708 709 710 711 712 713 714 715

#
# Spit out a redirect so that the history does not include a post
# in it. The back button skips over the post and to the form.
# See above for conclusion.
# 
header("Location: joinproject.php3?finished=1");

?>