joinproject.php3 29.7 KB
Newer Older
1
<?php
Leigh B. Stoller's avatar
Leigh B. Stoller committed
2 3
#
# EMULAB-COPYRIGHT
4
# Copyright (c) 2000-2003, 2005 University of Utah and the Flux Group.
Leigh B. Stoller's avatar
Leigh B. 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 26
    LOGGEDINORDIE($uid, CHECKLOGIN_UNAPPROVED|
		  CHECKLOGIN_WEBONLY|CHECKLOGIN_WIKIONLY);
27 28 29 30 31 32 33 34 35 36
    $joining_uid = $uid;
    $returning = 1;
}
else {
    #
    # No uid, so must be new.
    #
    $returning = 0;
}

37 38 39 40
if (!isset($forwikionly)) {
    $forwikionly = 0;
}

Leigh B. Stoller's avatar
Leigh B. Stoller committed
41 42 43 44
$ACCOUNTWARNING =
    "Before continuing, please make sure your username " .
    "reflects your normal login name. ".
    "Emulab accounts are not to be shared amongst users!";
45

Leigh B. Stoller's avatar
Leigh B. Stoller committed
46 47 48
$EMAILWARNING =
    "Before continuing, please make sure the email address you have ".
    "provided is current and non-pseudonymic. Redirections and anonymous ".
49 50
    "email addresses are not allowed.";

51 52 53 54 55 56
#
# Spit the form out using the array of data. 
# 
function SPITFORM($formfields, $returning, $errors)
{
    global $TBDB_UIDLEN, $TBDB_PIDLEN, $TBDB_GIDLEN;
57
    global $ACCOUNTWARNING, $EMAILWARNING;
58 59 60 61 62 63
    global $WIKISUPPORT, $forwikionly, $WIKIURL;

    if ($forwikionly)
	PAGEHEADER("Wiki Registration");
    else
	PAGEHEADER("Apply for Project Membership");
64

65
    if (! $returning) {
66 67 68 69 70 71 72
	echo "<center>\n";

	if ($forwikionly) {
	    echo "<font size=+2>Register for an Emulab Wiki account</font>
                  <br><br>\n";
	}
        echo "<font size=+1>
73 74 75
               If you already have an Emulab account,
               <a href=login.php3?refer=1>
               <font color=red>please log on first!</font></a>
76 77 78 79 80 81 82 83
              </font>\n";
	if ($forwikionly) {
	    echo "<br>(You will already have a wiki account)\n";
	}
	echo "</center><br>\n";	
    }
    elseif ($forwikionly) {
	USERERROR("You already have a Wiki account!", 1);
84 85
    }

86
    if ($errors) {
87 88
	echo "<table class=nogrid
                     align=center border=0 cellpadding=6 cellspacing=0>
89
              <tr>
90
                 <th align=center colspan=2>
91
                   <font size=+1 color=red>
92
                      &nbsp;Oops, please fix the following errors!&nbsp;
93 94 95 96 97 98
                   </font>
                 </td>
              </tr>\n";

	while (list ($name, $message) = each ($errors)) {
	    echo "<tr>
99 100 101 102
                     <td align=right>
                       <font color=red>$name:&nbsp;</font></td>
                     <td align=left>
                       <font color=red>$message</font></td>
103 104 105 106
                  </tr>\n";
	}
	echo "</table><br>\n";
    }
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
    echo "<SCRIPT LANGUAGE=JavaScript>
              function SetWikiName(theform) 
              {
	          var validchars = 'abcdefghijklmnopqrstuvwxyz0123456789';
                  var usrname    = theform['formfields[usr_name]'].value;
                  var wikiname   = '';
                  var docap      = 1;

		  for (var i = 0; i < usrname.length; i++) {
                      var letter = usrname.charAt(i).toLowerCase();

                      if (validchars.indexOf(letter) == -1) {
                          if (letter == ' ') {
                              docap = 1;
                          }
                          continue;
                      }
                      else {
                          if (docap == 1) {
                              letter = usrname.charAt(i).toUpperCase()
                              docap  = 0;
                          }
                          wikiname = wikiname + letter;
                      }
                  }
                  theform['formfields[wikiname]'].value = wikiname;
              }
          </SCRIPT>\n";
135 136 137

    echo "<table align=center border=1> 
          <tr>
138
            <td align=center colspan=3>
139
                Fields marked with * are required.
140 141 142
            </td>
          </tr>\n

143 144 145 146
          <form name=myform enctype=multipart/form-data
                action=" . ($forwikionly ?
			    "wikiregister.php3" : "joinproject.php3") . " " .
	        "method=post>\n";
147 148 149 150 151 152

    if (! $returning) {
        #
        # UserName:
        #
        echo "<tr>
153
                  <td colspan=2>*Username (alphanumeric, lowercase):</td>
154 155 156 157 158
                  <td class=left>
                      <input type=text
                             name=\"formfields[joining_uid]\"
                             value=\"" . $formfields[joining_uid] . "\"
	                     size=$TBDB_UIDLEN
159
                             onchange=\"alert('$ACCOUNTWARNING')\"
160 161 162 163 164 165 166 167
	                     maxlength=$TBDB_UIDLEN>
                  </td>
              </tr>\n";

	#
	# Full Name
	#
        echo "<tr>
168
                  <td colspan=2>*Full Name:</td>
169 170 171
                  <td class=left>
                      <input type=text
                             name=\"formfields[usr_name]\"
172
                             onchange=\"SetWikiName(myform);\"
173 174 175 176 177 178
                             value=\"" . $formfields[usr_name] . "\"
	                     size=30>
                  </td>
              </tr>\n";

	#
179
	# WikiName
180
	#
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
	if ($WIKISUPPORT) {
	    echo "<tr>
                      <td colspan=2>*
                          <a href=${WIKIURL}/TWiki/WikiName
                            target=_blank>WikiName</a>:<td class=left>
                          <input type=text
                                 name=\"formfields[wikiname]\"
                                 value=\"" . $formfields[wikiname] . "\"
	                         size=30>
                      </td>
                  </tr>\n";
	}

	if (! $forwikionly) {
            #
            # Title/Position:
	    #
	    echo "<tr>
                      <td colspan=2>*Title/Position:</td>
                      <td class=left>
                          <input type=text
                                 name=\"formfields[usr_title]\"
                                 value=\"" . $formfields[usr_title] . "\"
  	                         size=30>
                      </td>
                  </tr>\n";

            #
            # Affiliation:
            # 
	    echo "<tr>
                      <td colspan=2>*Institutional<br>Affiliation:</td>
                      <td class=left>
                          <input type=text
                                 name=\"formfields[usr_affil]\"
                                 value=\"" . $formfields[usr_affil] . "\"
	                         size=40>
                      </td>
                  </tr>\n";

	    #
	    # User URL
	    #
	        echo "<tr>
                      <td colspan=2>Home Page URL:</td>
                      <td class=left>
                          <input type=text
                                 name=\"formfields[usr_URL]\"
                                 value=\"" . $formfields[usr_URL] . "\"
	                         size=45>
                      </td>
                  </tr>\n";
	}
234 235 236 237 238

	#
	# Email:
	#
	echo "<tr>
239
                  <td colspan=2>*Email Address[<b>1</b>]:</td>
240 241 242 243
                  <td class=left>
                      <input type=text
                             name=\"formfields[usr_email]\"
                             value=\"" . $formfields[usr_email] . "\"
244
                             onchange=\"alert('$EMAILWARNING')\"
245 246 247 248
	                     size=30>
                  </td>
              </tr>\n";

249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
	if (! $forwikionly) {
	    #
	    # Postal Address
	    #
	    echo "<tr><td colspan=3>*Postal Address:<br /><center>
		    <table>
		      <tr><td>Line 1</td><td colspan=3>
                        <input type=text
                               name=\"formfields[usr_addr]\"
                               value=\"" . $formfields[usr_addr] . "\"
	                       size=45></td></tr>
		      <tr><td>Line 2</td><td colspan=3>
                        <input type=text
                               name=\"formfields[usr_addr2]\"
                               value=\"" . $formfields[usr_addr2] . "\"
	                       size=45></td></tr>
		      <tr><td>City</td><td>
                        <input type=text
                               name=\"formfields[usr_city]\"
                               value=\"" . $formfields[usr_city] . "\"
	                       size=25></td>
		          <td>State/Province</td><td>
                        <input type=text
                               name=\"formfields[usr_state]\"
                               value=\"" . $formfields[usr_state] . "\"
	                       size=2></td></tr>
		      <tr><td>ZIP/Postal Code</td><td>
                        <input type=text
                               name=\"formfields[usr_zip]\"
                               value=\"" . $formfields[usr_zip] . "\"
	                       size=10></td>
		          <td>Country</td><td>
                        <input type=text
                               name=\"formfields[usr_country]\"
                               value=\"" . $formfields[usr_country] . "\"
	                       size=15></td></tr>
                   </table></center></td></tr>";

	    #
	    # Phone
	    #
	    echo "<tr>
                      <td colspan=2>*Phone #:</td>
                      <td class=left>
                          <input type=text
                                 name=\"formfields[usr_phone]\"
                                 value=\"" . $formfields[usr_phone] . "\"
	                         size=15>
                      </td>
                  </tr>\n";
299

300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
	    #
	    # 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=\"" . $_FILES['usr_keyfile']['name'] .
		                       "\"
	                         size=50>
                          <br>
                          <br>
	                  <input type=text
                                 name=\"formfields[usr_key]\"
                                 value=\"$formfields[usr_key]\"
	                         size=50
	                         maxlength=1024>
                      </td>
                  </tr>\n";
	}
331

332 333 334 335 336
	#
	# Password. Note that we do not resend the password. User
	# must retype on error.
	#
	echo "<tr>
337
                  <td colspan=2>*Password[<b>1</b>]:</td>
338 339 340 341 342 343 344
                  <td class=left>
                      <input type=password
                             name=\"formfields[password1]\"
                             size=8></td>
              </tr>\n";

        echo "<tr>
345
                  <td colspan=2>*Retype Password:</td>
346 347 348 349 350 351 352
                  <td class=left>
                      <input type=password
                             name=\"formfields[password2]\"
                             size=8></td>
             </tr>\n";
    }

353 354 355 356 357 358 359 360 361 362 363 364 365
    if (! $forwikionly) {
        #
        # Project Name:
        #
	echo "<tr>
                  <td colspan=2>*Project Name:</td>
                  <td class=left>
                      <input type=text
                             name=\"formfields[pid]\"
                             value=\"" . $formfields[pid] . "\"
	                     size=$TBDB_PIDLEN maxlength=$TBDB_PIDLEN>
                  </td>
              </tr>\n";
366

367 368 369 370 371 372 373 374 375 376 377 378 379 380
        #
        # Group Name:
        #
	echo "<tr>
                  <td colspan=2>Group Name:<br>
                  (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";
    }
381 382

    echo "<tr>
383
              <td colspan=3 align=center>
384 385 386 387 388 389 390 391 392 393 394 395
                 <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
396
                 regarding passwords and email addresses.\n";
397
    if (!$returning && !$forwikionly) {
398 399
	echo "<li> If you want us to use your existing ssh public key,
                   then either paste it in or specify the path to your
400
                   your identity.pub file.  <font color=red>NOTE:</font>
Leigh B. Stoller's avatar
Leigh B. Stoller committed
401 402
                   We use the <a href=http://www.openssh.org>OpenSSH</a>
                   key format,
403 404
                   which has a slightly different protocol 2 public key format
                   than some of the commercial vendors such as
Leigh B. Stoller's avatar
Leigh B. Stoller committed
405
                   <a href=http://www.ssh.com>SSH Communications</a>. If you
406 407 408 409
                   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

410 411 412 413 414 415
              <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>
416 417 418 419 420 421 422
          </blockquote></blockquote>
          </h4>\n";
}

#
# The conclusion of a join request. See below.
# 
423
if (isset($_GET['finished'])) {
424 425 426 427
    if ($forwikionly) 
	PAGEHEADER("Wiki Registration");
    else
	PAGEHEADER("Apply for Project Membership");
428 429 430 431

    #
    # Generate some warm fuzzies.
    #
432 433 434 435 436 437 438
    if ($forwikionly) {
	echo "An email message has been sent to your account so we may verify
              your email address. Please follow the instructions contained in
              that message, which will verify your account, and grant you
              access to the Wiki.\n";
    }
    elseif (! $returning) {
439 440
	echo "<p>
              As a pending user of the Testbed you will receive a key via email.
441
              When you receive the message, please follow the instructions
442 443 444 445 446
              contained in the message, which will verify your identity.
	      <br>
	      <p>
	      When you have done that, the project leader will be
	      notified of your application. ";
447 448
    }
    else {
449 450
          echo "<p>
	  	The project leader has been notified of your application. ";
451 452
    }

453 454 455 456
    echo "He/She will make a decision and either approve or deny your
          application, and you will be notified via email as soon as
	  that happens.\n";

457 458 459 460 461 462 463
    PAGEFOOTER();
    return;
}

#
# On first load, display a virgin form and exit.
#
464
if (! isset($_POST['submit'])) {
465 466
    $defaults = array();
    $defaults[usr_URL] = "$HTTPTAG";
Chad Barb's avatar
Chad Barb committed
467
    $defaults[usr_country] = "USA";
468 469 470 471 472 473 474 475 476 477

    #
    # 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;
    }
478 479 480 481 482
    
    SPITFORM($defaults, $returning, 0);
    PAGEFOOTER();
    return;
}
483 484 485
else {
    # Form submitted. Make sure we have a formfields array and a target_uid.
    if (!isset($_POST['formfields']) ||
486
	!is_array($_POST['formfields'])) {
487 488 489 490
	PAGEARGERROR("Invalid form arguments.");
    }
    $formfields = $_POST['formfields'];
}
491 492 493 494 495 496 497 498 499 500 501 502 503 504

#
# 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";
    }
505 506
    elseif (!TBvalid_uid($formfields[joining_uid])) {
	$errors["UserName"] = TBFieldErrorString();
507
    }
508 509
    elseif (TBCurrentUser($formfields[joining_uid]) ||
	    posix_getpwnam($formfields[joining_uid])) {
510 511
	$errors["UserName"] = "Already in use. Pick another";
    }
512 513 514 515
    if (!isset($formfields[usr_name]) ||
	strcmp($formfields[usr_name], "") == 0) {
	$errors["Full Name"] = "Missing Field";
    }
516
    elseif (! TBvalid_usrname($formfields[usr_name])) {
517
	$errors["Full Name"] = TBFieldErrorString();
518
    }
519 520 521 522 523 524
    # Make sure user name has at least two tokens!
    $tokens = preg_split("/[\s]+/", $formfields[usr_name],
			 -1, PREG_SPLIT_NO_EMPTY);
    if (count($tokens) < 2) {
	$errors["Full Name"] = "Please provide a first and last name";
    }
525 526 527 528 529 530 531 532 533 534 535
    if ($WIKISUPPORT) {
	if (!isset($formfields[wikiname]) ||
	    strcmp($formfields[wikiname], "") == 0) {
	    $errors["WikiName"] = "Missing Field";
	}
	elseif (! TBvalid_wikiname($formfields[wikiname])) {
	    $errors["WikiName"] = TBFieldErrorString();
	}
	elseif (TBCurrentWikiName($formfields[wikiname])) {
	    $errors["WikiName"] = "Already in use. Pick another";
	}
536
    }
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
    if (!$forwikionly) {
	if (!isset($formfields[usr_title]) ||
	    strcmp($formfields[usr_title], "") == 0) {
	    $errors["Title/Position"] = "Missing Field";
	}
	elseif (! TBvalid_title($formfields[usr_title])) {
	    $errors["Title/Position"] = TBFieldErrorString();
	}
	if (!isset($formfields[usr_affil]) ||
	    strcmp($formfields[usr_affil], "") == 0) {
	    $errors["Affiliation"] = "Missing Field";
	}
	elseif (! TBvalid_affiliation($formfields[usr_affil])) {
	    $errors["Affiliation"] = TBFieldErrorString();
	}
    }	
553 554 555 556
    if (!isset($formfields[usr_email]) ||
	strcmp($formfields[usr_email], "") == 0) {
	$errors["Email Address"] = "Missing Field";
    }
557
    elseif (! TBvalid_email($formfields[usr_email])) {
558
	$errors["Email Address"] = TBFieldErrorString();
559
    }
560 561 562 563 564 565 566 567 568 569
    elseif (TBCurrentEmail($formfields[usr_email])) {
        #
        # Treat this error separate. Not allowed.
        #
	PAGEHEADER("Apply for Project Membership");
	USERERROR("The email address '$formfields[usr_email]' is already in ".
		  "use by another user.<br>Perhaps you have ".
		  "<a href='password.php3?email=$formfields[usr_email]'>".
		  "forgotten your username.</a>", 1);
    }
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
    if (! $forwikionly) {
	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["Address 1"] = "Missing Field";
	}
	elseif (! TBvalid_addr($formfields[usr_addr])) {
	    $errors["Address 1"] = TBFieldErrorString();
	}
        # Optional
	if (isset($formfields[usr_addr2]) &&
	    !TBvalid_addr($formfields[usr_addr2])) {
	    $errors["Address 2"] = TBFieldErrorString();
	}
	if (!isset($formfields[usr_city]) ||
	    strcmp($formfields[usr_city], "") == 0) {
	    $errors["City"] = "Missing Field";
	}
	elseif (! TBvalid_city($formfields[usr_city])) {
	    $errors["City"] = TBFieldErrorString();
	}
	if (!isset($formfields[usr_state]) ||
	    strcmp($formfields[usr_state], "") == 0) {
	    $errors["State"] = "Missing Field";
	}
	elseif (! TBvalid_state($formfields[usr_state])) {
	    $errors["State"] = TBFieldErrorString();
	}
	if (!isset($formfields[usr_zip]) ||
	    strcmp($formfields[usr_zip], "") == 0) {
	    $errors["ZIP/Postal Code"] = "Missing Field";
	}
	elseif (! TBvalid_zip($formfields[usr_zip])) {
	    $errors["Zip/Postal Code"] = TBFieldErrorString();
	}
	if (!isset($formfields[usr_country]) ||
	    strcmp($formfields[usr_country], "") == 0) {
	    $errors["Country"] = "Missing Field";
	}
	elseif (! TBvalid_country($formfields[usr_country])) {
	    $errors["Country"] = TBFieldErrorString();
	}
	if (!isset($formfields[usr_phone]) ||
	    strcmp($formfields[usr_phone], "") == 0) {
	    $errors["Phone #"] = "Missing Field";
	}
	elseif (!TBvalid_phone($formfields[usr_phone])) {
	    $errors["Phone #"] = TBFieldErrorString();
	}
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
    }
    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";
    }
}
643 644
if (!$forwikionly && (!isset($formfields[pid]) ||
		      strcmp($formfields[pid], "") == 0)) {
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662
    $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_name          = addslashes($formfields[usr_name]);
    $usr_email         = $formfields[usr_email];
    $password1         = $formfields[password1];
    $password2         = $formfields[password2];
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684
    $wikiname          = ($WIKISUPPORT ? $formfields[wikiname] : "");

    if (!$forwikionly) {
	$usr_affil         = addslashes($formfields[usr_affil]);
	$usr_title         = addslashes($formfields[usr_title]);
	$usr_addr          = addslashes($formfields[usr_addr]);
	$usr_city          = addslashes($formfields[usr_city]);
	$usr_state         = addslashes($formfields[usr_state]);
	$usr_zip           = addslashes($formfields[usr_zip]);
	$usr_country       = addslashes($formfields[usr_country]);
	$usr_phone         = $formfields[usr_phone];
    }
    else {
	$usr_affil         = "";
	$usr_title         = "";
	$usr_addr          = "";
	$usr_city          = "";
	$usr_state         = "";
	$usr_zip           = "";
	$usr_country       = "";
	$usr_phone         = "";
    }
685 686 687 688 689 690 691

    if (! isset($formfields[usr_URL]) ||
	strcmp($formfields[usr_URL], "") == 0 ||
	strcmp($formfields[usr_URL], $HTTPTAG) == 0) {
	$usr_URL = "";
    }
    else {
692
	$usr_URL = addslashes($formfields[usr_URL]);
693
    }
694

695 696 697 698 699 700 701
    if (! isset($formfields[usr_addr2])) {
	$usr_addr2 = "";
    }
    else {
	$usr_addr2 = addslashes($formfields[usr_addr2]);
    }

702
    #
703 704
    # Pub Key.
    #
705 706
    if (isset($formfields[usr_key]) &&
	strcmp($formfields[usr_key], "")) {
707
        #
708 709
        # This is passed off to the shell, so taint check it.
        # 
710 711 712 713
	if (! preg_match("/^[-\w\s\.\@\+\/\=]*$/", $formfields[usr_key])) {
	    $errors["PubKey"] = "Invalid characters";
	}
	else {
714 715 716 717 718 719 720
            #
            # 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' ";
721
	}
722
    }
723

724 725 726
    #
    # If usr provided a file for the key, it overrides the paste in text.
    #
727 728 729 730 731
    if (isset($_FILES['usr_keyfile']) &&
	$_FILES['usr_keyfile']['name'] != "" &&
	$_FILES['usr_keyfile']['name'] != "none") {

	$localfile = $_FILES['usr_keyfile']['tmp_name'];
732

733
	if (! stat($localfile)) {
734
	    $errors["PubKey File"] = "No such file";
735
	}
736 737 738 739
        # Taint check shell arguments always! 
	elseif (! preg_match("/^[-\w\.\/]*$/", $localfile)) {
	    $errors["PubKey File"] = "Invalid characters";
	}
740 741
	else {
	    $addpubkeyargs = "$joining_uid $usr_keyfile";
742
	    chmod($usr_keyfile, 0644);	
743 744
	}
    }
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759
}
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];
760 761 762 763
    $usr_addr2	= $row[usr_addr2];
    $usr_city	= $row[usr_city];
    $usr_state	= $row[usr_state];
    $usr_zip	= $row[usr_zip];
Chad Barb's avatar
Chad Barb committed
764
    $usr_country= $row[usr_country];
765 766 767 768
    $usr_phone	= $row[usr_phone];
    $usr_URL    = $row[usr_URL];
}
$usr_expires  = date("Y:m:d", time() + (86400 * 120));
769
$pid          = $formfields[pid];
770

771
if (isset($formfields[gid]) && $formfields[gid] != "") {
772 773 774 775 776 777
    $gid = $formfields[gid];
}
else {
    $gid = $pid;
}

778 779 780 781 782 783 784 785 786 787
if (!$forwikionly) {
    if (!TBvalid_pid($pid) || !TBValidProject($pid)) {
	$errors["Project Name"] = "Invalid Project Name";
    }
    elseif (!TBvalid_gid($gid) || !TBValidGroup($pid, $gid)) {
	$errors["Group Name"] = "Invalid Group Name";
    }
    elseif (TBGroupMember($joining_uid, $pid, $gid, $approved)) {
	$errors["Membership"] = "You are already a member";
    }
788 789
}

790 791 792 793
#
# Verify key format.
#
if (isset($addpubkeyargs) &&
794
    ADDPUBKEY($joining_uid, "webaddpubkey -n $addpubkeyargs")) {
795 796 797
    $errors["Pubkey Format"] = "Could not be parsed. Is it a public key?";
}

798 799 800 801 802 803 804 805 806 807 808 809 810 811 812
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");

813 814 815 816 817
    #
    # Must be done before user record is inserted!
    # XXX Since user does not exist, must run as nobody. Script checks. 
    # 
    if (isset($addpubkeyargs)) {
818
	ADDPUBKEY($joining_uid, "webaddpubkey $addpubkeyargs");
819 820
    }

821 822
    DBQueryFatal("INSERT INTO users ".
	"(uid,usr_created,usr_expires,usr_name,usr_email,usr_addr,".
Chad Barb's avatar
Chad Barb committed
823
	" usr_addr2,usr_city,usr_state,usr_zip,usr_country, ".
824
	" usr_URL,usr_phone,usr_shell,usr_title,usr_affil,usr_pswd,unix_uid,".
825
	" status,pswd_expires,usr_modified,wikionly,wikiname) ".
826 827
	"VALUES ('$joining_uid', now(), '$usr_expires', '$usr_name', ".
        "'$usr_email', ".
828
	"'$usr_addr', '$usr_addr2', '$usr_city', '$usr_state', '$usr_zip', ".
Chad Barb's avatar
Chad Barb committed
829
	"'$usr_country', ".
830
	"'$usr_URL', '$usr_phone', 'tcsh', '$usr_title', '$usr_affil', ".
831
        "'$encoding', NULL, 'newuser', ".
832
	"date_add(now(), interval 1 year), now(), $forwikionly, '$wikiname')");
833

834 835
    DBQueryFatal("INSERT INTO user_stats (uid) VALUES ('$joining_uid')");

836
    $key = TBGenVerificationKey($joining_uid);
837 838

    TBMAIL("$usr_name '$joining_uid' <$usr_email>",
839 840 841 842 843 844 845 846
      "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".
847 848 849 850 851 852 853 854 855 856 857
      ($forwikionly ?
       "Once you have verified your account, you will be able to access\n".
       "the Wiki. You MUST verify your account first!"
       :       
       "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".
858
      "Thanks,\n".
859
      "Testbed Operations\n",
860 861 862
      "From: $TBMAIL_APPROVAL\n".
      "Bcc: $TBMAIL_AUDIT\n".
      "Errors-To: $TBMAIL_WWW");
863 864
}

865 866 867 868 869 870 871 872
#
# For wikionly registration, we are done.
# 
if ($forwikionly) {
    header("Location: wikiregister.php3?finished=1");
    exit();
}

873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893
#
# 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())");
}

#
894
# Generate an email message to the proj/group leaders.
895 896 897 898 899 900 901 902 903 904 905 906
#
$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];

907
$allleaders = TBLeaderMailList($pid,$gid);
908

909
#
910 911 912
# 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.
913
#
914 915 916 917 918 919 920 921 922 923 924 925
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".
926 927 928 929
	   "Address 1:       $usr_addr\n".
	   "Address 2:       $usr_addr2\n".
	   "City:            $usr_city\n".
	   "State:           $usr_state\n".
Chad Barb's avatar
Chad Barb committed
930 931
	   "ZIP/Postal Code: $usr_zip\n".
	   "Country:         $usr_country\n".
932 933 934 935 936 937
	   "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".
938
	   "Testbed Operations\n",
939
	   "From: $TBMAIL_APPROVAL\n".
940
	   "Cc: $allleaders\n".
941 942 943
	   "Bcc: $TBMAIL_AUDIT\n".
	   "Errors-To: $TBMAIL_WWW");
}
944 945 946 947 948 949 950

#
# 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");