defs.php3.in 22.1 KB
Newer Older
1
2
<?php
#
3
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
23
#
24
25
26

#
# Standard definitions.
27
#
28
$TBDIR          = "@prefix@/";
29
$OURDOMAIN      = "@OURDOMAIN@";
30
$BOSSNODE       = "@BOSSNODE@";
31
$USERNODE       = "@USERNODE@";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
32
$CVSNODE	= "cvs.${OURDOMAIN}";
33
$WIKINODE	= $USERNODE;
34
$TBADMINGROUP   = "@TBADMINGROUP@";
35
36
37
38
39
40
41
$WWWHOST	= "@WWWHOST@";
$WWW		= "@WWW@";
$TBAUTHDOMAIN	= "@TBAUTHDOMAIN@";
$TBBASE		= "@TBBASE@";
$TBDOCBASE	= "@TBDOCBASE@";
$TBWWW		= "@TBWWW@";
$THISHOMEBASE	= "@THISHOMEBASE@";
42
$ELABINELAB     = @ELABINELAB@;
43
$PLABSUPPORT    = @PLABSUPPORT@;
Kevin Atkinson's avatar
   
Kevin Atkinson committed
44
$PUBSUPPORT     = @PUBSUPPORT@;
45
$WIKISUPPORT    = @WIKISUPPORT@;
46
$TRACSUPPORT    = @TRACSUPPORT@;
47
$BUGDBSUPPORT   = @BUGDBSUPPORT@;
48
$CVSSUPPORT     = @CVSSUPPORT@;
49
$MAILMANSUPPORT = @MAILMANSUPPORT@;
50
$DOPROVENANCE   = @IMAGEPROVENANCE@;
51
$CHATSUPPORT    = @CHATSUPPORT@;
52
$PROTOGENI      = @PROTOGENI_SUPPORT@;
Leigh B Stoller's avatar
Leigh B Stoller committed
53
$GENIRACK       = @PROTOGENI_GENIRACK@;
54
$PROTOGENI_GENIWEBLOGIN = @PROTOGENI_GENIWEBLOGIN@;
55
$ISCLRHOUSE     = @PROTOGENI_ISCLEARINGHOUSE@;
56
$EXP_VIS        = @EXP_VIS_SUPPORT@;
57
$ISOLATEADMINS  = @ISOLATEADMINS@;
58
$CONTROL_NETWORK= "@CONTROL_NETWORK@";
59
$CONTROL_NETMASK= "@CONTROL_NETMASK@";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
60
61
$WIKIHOME       = "https://${USERNODE}/twiki";
$WIKIURL        = "${WIKIHOME}/bin/newlogon";
62
$WIKICOOKIENAME = "WikiCookie";
63
64
$BUGDBURL       = "https://${USERNODE}/flyspray";
$BUGDBCOOKIENAME= "FlysprayCookie";
65
$TRACCOOKIENAME = "TracCookie";
66
$MAILMANURL     = "http://${USERNODE}/mailman";
67
$OPSCVSURL      = "http://${USERNODE}/cvsweb/cvsweb.cgi";
68
$OPSJETIURL     = "http://${USERNODE}/jabber/jeti.php";
69
$WIKIDOCURL     = "http://${WIKINODE}/wikidocs/wiki";
70
$FORUMURL       = "http://groups.google.com/group/emulab-users";
71
72
$MIN_UNIX_UID   = @MIN_UNIX_UID@;
$MIN_UNIX_GID   = @MIN_UNIX_GID@;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
73
$EXPOSELINKTEST = 1;
74
$EXPOSESTATESAVE= 0;
75
$EXPOSEARCHIVE  = 0;
76
$EXPOSETEMPLATES= 0;
77
$USERSELECTUIDS = 1;
78
$REMOTEWIKIDOCS = @REMOTEWIKIDOCS@;
Kirk Webb's avatar
Kirk Webb committed
79
$FLAVOR         = "Emulab";
80
$GMAP_API_KEY   = "@GMAP_API_KEY@";
81
$NONAMEDSETUP	= @DISABLE_NAMED_SETUP@;
82
$OPS_VM		= @OPSVM_ENABLE@;
83
84
$PORTAL_ENABLE  = @PORTAL_ENABLE@;
$PORTAL_ISPRIMARY = @PORTAL_ISPRIMARY@;
85
$SPEWFROMOPS    = @SPEWFROMOPS@;
86
$BROWSER_CONSOLE_ENABLE = @BROWSER_CONSOLE_ENABLE@;
Leigh B Stoller's avatar
Leigh B Stoller committed
87
88
$IPV6_ENABLED       = @IPV6_ENABLED@;
$IPV6_SUBNET_PREFIX = "@IPV6_SUBNET_PREFIX@";
89
$TBMAILTAG      = $THISHOMEBASE;
90
91
$WITHZFS        = @WITHZFS@;
$ZFS_NOEXPORT   = @ZFS_NOEXPORT@;
92

93
94
95
96
97
98
$TBMAILADDR_OPS		= "@TBOPSEMAIL_NOSLASH@";
$TBMAILADDR_WWW		= "@TBWWWEMAIL_NOSLASH@";
$TBMAILADDR_APPROVAL	= "@TBAPPROVALEMAIL_NOSLASH@";
$TBMAILADDR_LOGS	= "@TBLOGSEMAIL_NOSLASH@";
$TBMAILADDR_AUDIT	= "@TBAUDITEMAIL_NOSLASH@";

99
100
101
102
103
# Can override this in the defs file. 
$TBAUTHTIMEOUT  = "@TBAUTHTIMEOUT@";
$TBMAINSITE     = "@TBMAINSITE@";
$TBSECURECOOKIES= "@TBSECURECOOKIES@";
$TBCOOKIESUFFIX = "@TBCOOKIESUFFIX@";
104
$FANCYBANNER    = "@FANCYBANNER@";
105

Leigh B. Stoller's avatar
Leigh B. Stoller committed
106
107
$TBWWW_DIR	= "$TBDIR"."www/";
$TBBIN_DIR	= "$TBDIR"."bin/";
108
$TBETC_DIR	= "$TBDIR"."etc/";
109
110
111
$TBLIBEXEC_DIR	= "$TBDIR"."libexec/";
$TBSUEXEC_PATH  = "$TBLIBEXEC_DIR/suexec";
$TBCHKPASS_PATH = "$TBLIBEXEC_DIR/checkpass";
112
$TBCSLOGINS     = "$TBETC_DIR/cslogins";
Mike Hibler's avatar
Mike Hibler committed
113
$UUIDGEN_PATH   = "@UUIDGEN@";
114

115
116
#
# Hardcoded check against $WWWHOST, to prevent anyone from accidentally setting
117
# $TBMAINSITE when it should not be
118
119
120
121
122
#
if ($WWWHOST != "www.emulab.net") {
    $TBMAINSITE = 0;
}

123
124
125
126
127
128
129
130
131
132
133
134
135
136
#
# The wiki docs either come from the local node, or in most cases
# they are redirected back to Utah's emulab.
#
if ($TBMAINSITE) {
    $WIKIDOCURL  = "https://${WIKINODE}/wikidocs/wiki";
}
elseif ($REMOTEWIKIDOCS) {
    $WIKIDOCURL  = "https://wiki.emulab.net/wikidocs/wiki";
}
else {
    $WIKIDOCURL  = "/wikidocs/wiki";
}

137
138
139
140
$TBPROJ_DIR     = "@PROJROOT_DIR@";
$TBUSER_DIR	= "@USERSROOT_DIR@";
$TBGROUP_DIR	= "@GROUPSROOT_DIR@";
$TBSCRATCH_DIR	= "@SCRATCHROOT_DIR@";
141
$TBCVSREPO_DIR  = "$TBPROJ_DIR/cvsrepos";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
142
$TBNSSUBDIR     = "nsdir";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
143

144
145
146
147
148
149
150
$TBVALIDDIRS	  = "$TBPROJ_DIR, $TBUSER_DIR, $TBGROUP_DIR";
$TBVALIDDIRS_HTML = "<code>$TBPROJ_DIR</code>, <code>$TBUSER_DIR</code>, <code>$TBGROUP_DIR</code>";
if ($TBSCRATCH_DIR) {
    $TBVALIDDIRS .= ", $TBSCRATCH_DIR";
    $TBVALIDDIRS_HTML .= ", <code>$TBSCRATCH_DIR</code>";
}

151
152
$TBAUTHCOOKIE   = "NewHashCookie" . $TBCOOKIESUFFIX;
$TBNAMECOOKIE   = "NewMyUidCookie" . $TBCOOKIESUFFIX;
153
$TBEMAILCOOKIE  = "MyEmailCookie" . $TBCOOKIESUFFIX;
154
$TBLOGINCOOKIE  = "NewLoginCookie" . $TBCOOKIESUFFIX;
155

156
$HTTPTAG        = "http://";
157
$HTTPSTAG       = "https://";
158

159
160
161
162
163
$TBMAIL_OPS		= "Testbed Ops <$TBMAILADDR_OPS>";
$TBMAIL_WWW		= "Testbed WWW <$TBMAILADDR_WWW>";
$TBMAIL_APPROVAL	= "Testbed Approval <$TBMAILADDR_APPROVAL>";
$TBMAIL_LOGS		= "Testbed Logs <$TBMAILADDR_LOGS>";
$TBMAIL_AUDIT		= "Testbed Audit <$TBMAILADDR_AUDIT>";
164
$TBMAIL_NOREPLY		= "no-reply@$OURDOMAIN";
165

166
#
167
168
169
# This just spits out an email address in a page, so it does not need
# to be configured per development tree. It could be though ...
# 
170
171
$TBMAILADDR     = "<a href=\"mailto:$TBMAILADDR_OPS\">
                      Testbed Operations ($TBMAILADDR_OPS)</a>";
172

173
174
175
# So subscripts always know ...
putenv("HTTP_SCRIPT=1");

176
177
178
179
180
181
#
# Special headers alterting browsers to the fact that there's an RSS feed
# available for the page. Intended to be passed as an $extra_headers argument
# to PAGEHEADER
#
$RSS_HEADER_NEWS = "<link rel=\"alternate\" type=\"application/rss+xml\" " .
182
           "title=\"Emulab News\" href=\"$TBDOCBASE/news-rss.php3?protogeni=0\" />";
183

184
185
186
$RSS_HEADER_PGENINEWS =
   "<link rel=\"alternate\" type=\"application/rss+xml\" " .
   "title=\"ProtoGeni News\" href=\"$TBDOCBASE/news-rss.php3?protogeni=1\"/>";
187

Kirk Webb's avatar
Kirk Webb committed
188
189
190
191
192
$RSS_HEADER_PNNEWS =
   "<link rel=\"alternate\" type=\"application/rss+xml\" " .
   "title=\"PhantomNet News\" href=\"$TBDOCBASE/news-rss.php3?phantomnet=1\"/>";

#
193
194
195
196
# See if we should override any of the global web variables based on the
# virtual domain.  We include a site-dependent definitions file.
#
$ALTERNATE_DOMAINS = array();
197
$ISALTDOMAIN       = 0;
198
199
200
201
$DOMVIEW           = NULL;
$altdomfile = strtolower("alternate_domains_${OURDOMAIN}.php");
if (file_exists($altdomfile)) {
    include($altdomfile);
Kirk Webb's avatar
Kirk Webb committed
202
}
203
SetDomainDefs();
Kirk Webb's avatar
Kirk Webb committed
204

205
206
207
208
#
# Database constants and the like.
#
include("dbdefs.php3");
209
include("url_defs.php");
210
211
212
include("user_defs.php");
include("group_defs.php");
include("project_defs.php");
213
include("experiment_defs.php");
214

215
216
217
218
219
220
221
222
#
# Control how error messages are returned to the user. If the session is
# not actually "interactive" then do not send any output to the browser.
# Just save it up and let the page deal with it. 
#
$session_interactive  = 1;
$session_errorhandler = 0;

223
224
225
226
227
228
229
230
#
# Wrap up the mail function so we can prepend a tag to the subject
# line that indicates what testbed. Useful when multiple testbed
# email to the same list.
#
# 
function TBMAIL($to, $subject, $message, $headers = 0)
{
231
    global $TBMAILTAG;
232

233
    $subject = strtoupper($TBMAILTAG) . ": $subject";
234

235
    $tag = "X-NetBed: " . basename($_SERVER["SCRIPT_NAME"]);
236
237
238
239
240
241
242
243
    
    if ($headers) {
	$headers = "$headers\n" . $tag;
    }
    else {
	$headers = $tag;
    }
    return mail($to, $subject, $message, $headers);
244
245
}

246
247
248
249
250
#
#
# Identical to perl function of the same name
#
#
251
252
function SendProjAdminMail($project, $from, $to,
			   $subject, $message, $headers = "")
253
{
254
    global $MAILMANSUPPORT, $TBMAIL_APPROVAL, $TBMAIL_AUDIT;
255
    global $OURDOMAIN, $TBMAIL_WWW, $TBMAILTAG;
256
257
258
259
    $pid = $project->pid();
    
    $projadminmail =
	($project->isAPT() ? "aptlab-approval@aptlab.net" :
260
261
262
	 ($project->isCloud() ? "cloudlab-approval@cloudlab.us" :
	  ($project->isPNet() ? "phantomnet-approval@phantomnet.org" :
	   $TBMAIL_APPROVAL)));
263
264
    $TBMAILTAG =
	($project->isAPT() ? "aptlab.net" :
265
266
267
	 ($project->isCloud() ? "cloudlab.us" : 
	  ($project->isPNet() ? "phantomnet.org" :
	   $TBMAILTAG)));
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
    if ($headers) {
        $headers .= "\n";
    }
    if ($from == 'ADMIN') {
	$from = $projadminmail;
	$headers .= "Bcc: $projadminmail\n";
    } elseif ($to == 'ADMIN') {
	$to = $projadminmail;
	$headers .= "Reply-To: $projadminmail\n";
    } else {
	$headers .= "Bcc: $projadminmail\n";
    }
    $headers .= "From: $from\n";
    if ($from == 'AUDIT') {
	$from = $TBMAIL_AUDIT;
	$headers .= "Bcc: $TBMAIL_AUDIT\n";
    } elseif ($to == "AUDIT") {
	$to = $TBMAIL_AUDIT;
    } else {
	$headers .= "Bcc: $TBMAIL_AUDIT\n";
    }
    $headers .= "Errors-To: $TBMAIL_WWW\n"; # FIXME: Why?
    $headers = substr($headers, 0, -1);
    TBMAIL($to, $subject, $message, $headers);
}

294
295
296
297
298
#
# Internal errors should be reported back to the user simply. The actual 
# error information should be emailed to the list for action. The script
# should then terminate if required to do so.
#
Leigh B. Stoller's avatar
Leigh B. Stoller committed
299
function TBERROR ($message, $death, $xmp = 0) {
300
301
302
    global $TBMAIL_WWW, $TBMAIL_OPS, $TBMAILADDR, $TBMAILADDR_OPS;
    global $session_interactive, $session_errorhandler;
    $script = urldecode($_SERVER['REQUEST_URI']);
303

304
305
    CLEARBUSY();

306
307
    TBMAIL($TBMAIL_OPS,
         "WEB ERROR REPORT",
308
         "\n".
309
	 "In $script\n\n".
310
311
312
         "$message\n\n".
         "Thanks,\n".
         "Testbed WWW\n",
313
         "From: $TBMAIL_OPS\n".
314
         "Errors-To: $TBMAIL_WWW");
315

316
    if ($death) {
317
318
319
320
321
322
323
	if ($session_interactive)
	    PAGEERROR("Could not continue. Please contact $TBMAILADDR");
	elseif ($session_errorhandler) {
	    $session_errorhandler("Could not continue. ".
				  "Please contact $TBMAILADDR_OPS", $death);
	}
	exit(1);
324
325
326
    }
    return 0;
}
Leigh B. Stoller's avatar
Leigh B. Stoller committed
327
328

#
329
330
331
332
333
# General user errors should print something warm and fuzzy.  If a
# header is not already printed and the dealth paramater is true, then
# assume the error is a precheck error and send an appropriate HTTP
# response to prevent robots from indexing the page.  This currently
# defaults to a "400 Bad Request", but that may change in the future.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
334
#
335
336
function USERERROR($message, $death = 1, 
	           $status_code = HTTP_400_BAD_REQUEST) {
337
    global $TBMAILADDR;
338
339
    global $session_interactive, $session_errorhandler;

340
341
    CLEARBUSY();

342
343
344
345
346
347
348
349
350
351
    if (! $session_interactive) {
	if ($session_errorhandler)
	    $session_errorhandler($message, $death);
	else
	    echo "$message";

	if ($death)
	    exit(1);
	return;
    }
352

353
    $msg = "<font size=+1><br>
354
            $message
355
      	    </font>
356
            <br><br><br>
357
358
359
            <font size=-1>
            Please contact $TBMAILADDR if you feel this message is an error.
            </font>\n";
360

Leigh B. Stoller's avatar
Leigh B. Stoller committed
361
    if ($death) {
362
	PAGEERROR($msg, $status_code);
Leigh B. Stoller's avatar
Leigh B. Stoller committed
363
    }
364
365
    else
        echo "$msg\n";
Leigh B. Stoller's avatar
Leigh B. Stoller committed
366
367
}

368
369
370
371
372
373
374
375
#
# A form error.
#
function FORMERROR($field) {
    USERERROR("Missing field; ".
              "Please go back and fill out the \"$field\" field!", 1);
}

376
377
378
#
# A page argument error. 
# 
379
function PAGEARGERROR($msg = 0) {
380
381
    $default = "Invalid page arguments: " .
          	htmlspecialchars($_SERVER['REQUEST_URI']);
382
383
384
385

    if ($msg) {
	$default = "$default<br><br>$msg";
    }
386
    USERERROR($default, 1, HTTP_400_BAD_REQUEST);
387
388
}

389
#
390
# SUEXEC stuff.
391
#
392
393
# Save this stuff so we can generate better error messages and such.
# 
394
395
396
397
$suexec_cmdandargs   = "";
$suexec_retval       = 0;
$suexec_output       = "";
$suexec_output_array = null;
398

399
400
401
402
403
404
405
#
# Actions for suexec. 
#
define("SUEXEC_ACTION_CONTINUE",	0);
define("SUEXEC_ACTION_DIE",		1);
define("SUEXEC_ACTION_USERERROR",	2);
define("SUEXEC_ACTION_IGNORE",		3);
406
define("SUEXEC_ACTION_DUPDIE",		4);
407
408
# SUEXEC_ACTION_MAIL_TBLOGS to be ored with one of the above actions
define("SUEXEC_ACTION_MAIL_TBLOGS",     64);
409

410
411
412
413
414
#
# An suexec error.
#
function SUEXECERROR($action)
{
415
    global $suexec_cmdandargs, $suexec_retval;
416
    global $suexec_output;
417

418
419
    $foo  = "Shell Program Error. Exit status: $suexec_retval\n";
    $foo .= "  '$suexec_cmdandargs'\n";
420
421
422
    $foo .= "\n";
    $foo .= $suexec_output;

423
424
    switch ($action) {
    case SUEXEC_ACTION_CONTINUE:
425
	TBERROR($foo, 0, 1);
426
427
428
429
430
431
432
433
434
        break;
    case SUEXEC_ACTION_DIE:
	TBERROR($foo, 1, 1);
        break;
    case SUEXEC_ACTION_USERERROR:
	USERERROR("<XMP>$foo</XMP>", 1);
        break;
    case SUEXEC_ACTION_IGNORE:
	break;
435
436
437
438
    case SUEXEC_ACTION_DUPDIE:
	TBERROR($foo, 0, 1);
	USERERROR("<XMP>$foo</XMP>", 1);
        break;
439
440
441
442
443
444
445
446
447
448
    default:
	TBERROR($foo, 1, 1);
    }
}

#
# Run a program as a user.
#
function SUEXEC($uid, $gid, $cmdandargs, $action) {
    global $TBSUEXEC_PATH;
449
450
    global $suexec_cmdandargs, $suexec_retval;
    global $suexec_output, $suexec_output_array;
451
452
453
454
455
456
457
    global $TBMAIL_LOGS;

    $mail_tblog = 0;
    if ($action & SUEXEC_ACTION_MAIL_TBLOGS) {
	$action &= ~SUEXEC_ACTION_MAIL_TBLOGS;
	$mail_tblog = 1;
    }
458
459
460

    ignore_user_abort(1);

461
462
463
464
    $suexec_cmdandargs   = "$uid $gid $cmdandargs";
    $suexec_output_array = array();
    $suexec_output       = "";
    $suexec_retval       = 0;
465
    
466
467
468
469
470
471
472
    exec("$TBSUEXEC_PATH $suexec_cmdandargs",
	 $suexec_output_array, $suexec_retval);

    # Yikes! Something is not doing integer conversion properly!
    if ($suexec_retval == 255) {
	$suexec_retval = -1;
    }
473
    #
474
    # suexec.c puts its error message between 101 and 125. Convert that
475
476
    # to an internal error and generate an error that says something useful.
    #
477
478
479
    # XXX Ignore 101, something in the geni-lib path uses it.
    #
    if (0 && $suexec_retval > 101 && $suexec_retval <= 125 &&
480
481
482
        !count($suexec_output_array)) {
        $suexec_output_array[0] =
            "Internal suexec error $suexec_retval. See the suexec log";
483
484
        $suexec_retval = -1;
    }
485
486
487
488
489
490

    if (count($suexec_output_array)) {
	for ($i = 0; $i < count($suexec_output_array); $i++) {
	    $suexec_output .= "$suexec_output_array[$i]\n";
	}
    }
491

492
493
494
495
496
497
498
499
500
    if ($mail_tblog) {
	$mesg  = "$TBSUEXEC_PATH $suexec_cmdandargs\n";
	$mesg .= "Return Value: $suexec_retval\n\n";
	$mesg .= "--------- OUTPUT ---------\n";
	$mesg .= $suexec_output;
	
	TBMAIL($TBMAIL_LOGS, "suexec: $cmdandargs", $mesg);
    }

501
502
503
504
505
506
507
    #
    # The output is still available of course, via $suexec_output.
    # 
    if ($suexec_retval == 0 || $action == SUEXEC_ACTION_IGNORE) {
	return $suexec_retval;
    }
    SUEXECERROR($action);
508
509
    # Must return the shell value!
    return $suexec_retval;
510
511
}

512
513
514
515
516
517
#
# We invoke addpubkey as user nobody all the time. The implied user is passed
# along in an HTTP_ variable (see tbauth). This avoids a bunch of confusion
# that results from new users who do not have a context yet. 
#
function ADDPUBKEY($cmdandargs) {
518
519
    global $TBSUEXEC_PATH;

520
521
    return SUEXEC("nobody", "nobody", "webaddpubkey $cmdandargs",
		  SUEXEC_ACTION_CONTINUE);
522
523
}

Leigh B. Stoller's avatar
Leigh B. Stoller committed
524
525
526
527
#
# Verify a URL.
#
function CHECKURL($url, &$error) {
528
    global $HTTPTAG, $HTTPSTAG;
Leigh B. Stoller's avatar
Leigh B. Stoller committed
529
530
531
532
533
534

    if (strlen($url)) {
	if (strstr($url, " ")) {
	    $error = "URL is malformed; spaces are not allowed!";
	    return 0;
	}
535
536
537
        #
        # We no longer fopen the url ... 
        #
Leigh B. Stoller's avatar
Leigh B. Stoller committed
538
539
540
541
542
543
544
545
546
547
    }
    return 1;
}

#
# Check a password.
#
function CHECKPASSWORD($uid, $password, $name, $email, &$error)
{
    global $TBCHKPASS_PATH;
548

549
550
    # Watch for caller errors since this calls to the shell.
    if (empty($uid) || empty($password) || empty($name) || empty($email)) {
551
	$error = "Internal Error";
552
553
	return 0;
    }
554
555
556
557
558
    # Ascii only.
    if (! TBvalid_userdata($password)) {
	$error = "Invalid characters; ascii only please";
	return 0;
    }
559

560
561
562
    $uid      = escapeshellarg($uid);
    $password = escapeshellarg($password);
    $stuff    = escapeshellarg("$name:$email");
Leigh B. Stoller's avatar
Leigh B. Stoller committed
563
    
564
    $mypipe = popen("$TBCHKPASS_PATH $password $uid $stuff", "w+");
Leigh B. Stoller's avatar
Leigh B. Stoller committed
565
566
567
568
569
570
571
572
573
574
575
576
577
    
    if ($mypipe) { 
        $retval=fgets($mypipe, 1024);
        if (strcmp($retval,"ok\n") != 0) {
	    $error = "$retval";
	    return 0;
	}
	return 1;
    }
    TBERROR("Checkpass Failure! Returned '$mypipe'.\n\n".
	    "$TBCHKPASS_PATH $password $uid '$name:$email'", 1);
}

578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
#
# Grab a UUID (universally unique identifier).
#
function NewUUID()
{
    global $UUIDGEN_PATH;

    $uuid = shell_exec($UUIDGEN_PATH);
    
    if (isset($uuid) && $uuid != "") {
	return rtrim($uuid);
    }
    TBERROR("$UUIDGEN_PATH Failure", 1);
}

Leigh B Stoller's avatar
Leigh B Stoller committed
593
594
595
596
597
598
599
600
601
# Check pattern.
function IsValidUUID($token)
{
    if (preg_match("/^\w+\-\w+\-\w+\-\w+\-\w+$/", $token)) {
	return 1;
    }
    return 0;
}

602
603
604
605
function LASTNODELOGIN($node)
{
}

606
607
608
609
610
611
612
613
function VALIDUSERPATH($path, $uid="", $pid="", $gid="", $eid="")
{
    global $TBPROJ_DIR, $TBUSER_DIR, $TBGROUP_DIR, $TBSCRATCH_DIR;

    #
    # No ids specified, just make sure it starts with an appropriate prefix.
    #
    if (!$uid && !$pid && !$gid && !$eid) {
Mike Hibler's avatar
Mike Hibler committed
614
615
616
	if (preg_match("#^$TBPROJ_DIR/.*#", $path) ||
	    preg_match("#^$TBUSER_DIR/.*#", $path) ||
	    preg_match("#^$TBGROUP_DIR/.*#", $path)) {
617
618
	    return 1;
	}
Mike Hibler's avatar
Mike Hibler committed
619
	if ($TBSCRATCH_DIR && preg_match("#^$TBSCRATCH_DIR/.*#", $path)) {
620
621
622
623
624
625
626
627
628
	    return 1;
	}
	return 0;
    }

    # XXX for now, see tbsetup/libtestbed.pm for what should happen
    return 0;
}

629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
#
# A function to print the contents of an array (recursively).
# Mostly useful for debugging.
#
function ARRAY_PRINT($arr) {
  if (!is_array($arr)) { echo "non-array '$arr'\n"; }
  foreach ($arr as $i => $val) {
    echo("'$i' - '$val'\n");
    if (is_array($val)) {
      echo "Sub-array $i:\n";
      array_print($val);
      echo "End Sub-array $i.\n";
    }
  }
}

645
646
647
648
649
650
651
#
# Return Yes or No given boolean
#
function YesNo($bool) {
    return ($bool ? "Yes" : "No");
}

Kirk Webb's avatar
Kirk Webb committed
652
653
654
#
# See if someone is logged in, and if they need to be redirected.
#
Kirk Webb's avatar
Kirk Webb committed
655
function CheckRedirect() {
Kirk Webb's avatar
Kirk Webb committed
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
    global $stayhome;

    if (($this_user = CheckLogin($check_status))) {
	$check_status = $check_status & CHECKLOGIN_STATUSMASK;
	if ($check_status == CHECKLOGIN_MAYBEVALID) {
            # Maybe the reason was because they where not using HTTPS ...
	    RedirectHTTPS();
	}
	
	if (($firstinitstate = TBGetFirstInitState())) {
	    unset($stayhome);
	}
	if (!isset($stayhome)) {
	    if ($check_status == CHECKLOGIN_LOGGEDIN) {
		if ($firstinitstate == "createproject") {
                    # Zap to NewProject Page,
Kirk Webb's avatar
Kirk Webb committed
672
		    header("Location: $TBBASE/newproject.php3");
Kirk Webb's avatar
Kirk Webb committed
673
674
675
		}
		else {
                    # Zap to My Emulab page.
Kirk Webb's avatar
Kirk Webb committed
676
		    header("Location: $TBBASE/".
Kirk Webb's avatar
Kirk Webb committed
677
678
679
680
681
682
683
684
			   CreateURL("showuser", $this_user));
		}
		exit;
	    }
	}
    }
}

685
686
687
688
689
690
691
692
693
694
695
#
# Loop over the $ALTERNATE_DOMAINS global array and see if the incoming
# request asked for a virtual domain for which we have an alternate set
# of definitions and/or view.
#
# Return 1 if a domain in the array matched, 0 otherwise.  Has MAJOR
# side effects: updates/overrides many top-level variables.
#
function SetDomainDefs()
{
    global $WWWHOST, $OURDOMAIN, $WWW, $THISHOMEBASE, $TBAUTHDOMAIN, $TBBASE;
696
    global $TBDOCBASE, $TBWWW, $WIKINODE, $WIKIDOCURL, $TBMAINSITE, $FORUMURL;
Kirk Webb's avatar
Kirk Webb committed
697
    global $ALTERNATE_DOMAINS, $FLAVOR, $DOMVIEW, $ISALTDOMAIN;
698

699
700
    foreach ($ALTERNATE_DOMAINS as $altdom) {
	list($dpat, $ovr) = $altdom;
701
	if (preg_match($dpat, $_SERVER['SERVER_NAME']) == 1) {
702
	    $ISALTDOMAIN  = 1;
703
704
705
	    # Replacement defs derived from the virtual domain itself.
	    $WWWHOST	  = $_SERVER['SERVER_NAME'];
	    $OURDOMAIN    = implode(".", array_slice(explode(".",$WWWHOST),1));
706
707
708
709
710
711
            # For devel trees
	    if (preg_match("/\/([\w\/]+)$/", $WWW, $matches)) {
	        $WWW      = $WWWHOST . "/" . $matches[1];
	    } else {
	        $WWW	  = $WWWHOST;
	    }
712
713
714
715
716
717
718
719
	    $TBAUTHDOMAIN = ".$OURDOMAIN";
	    $TBBASE	  = "https://$WWWHOST";
	    $TBDOCBASE	  = "http://$WWWHOST";
	    $TBWWW	  = "<$TBBASE/>";

	    # Defs that may be overriden in the domain's configuration array
	    if (isset($ovr['THISHOMEBASE'])) {
		$THISHOMEBASE = $ovr['THISHOMEBASE'];
Kirk Webb's avatar
Kirk Webb committed
720
		$FLAVOR       = $THISHOMEBASE;
721
722
723
724
725
726
	    }
	    if (isset($ovr['WIKINODE'])) {
		$WIKINODE     = $ovr['WIKINODE'];
	    } else {
		$WIKINODE     = "wiki.$OURDOMAIN";
	    }
727
728
	    if (isset($ovr['WIKIDOCURL'])) {
		$WIKIDOCURL   = $ovr['WIKIDOCURL'];
729
	    } else {
730
		$WIKIDOCURL   = "http://${WIKINODE}/wikidocs/wiki";
731
	    }
732
733
734
	    if (isset($ovr['FORUMURL'])) {
	        $FORUMURL     = $ovr['FORUMURL'];
	    }
735
736
737
738
739
740
741
742
743
744
745
746
747
748
	    if (isset($ovr['DOMVIEW'])) {
		$DOMVIEW      = $ovr['DOMVIEW'];
	    }

	    # Given that this is an alternate domain, clear TBMAINSITE
	    $TBMAINSITE = 0;
	    
	    # Bail after the first domain match.
	    return 1;
	}
    }
    return 0;
}

749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
#
# If the page was accessed via http redirect to https and exit
# otherwise do nothing
#
function RedirectHTTPS() {
    global $WWWHOST,$drewheader;
    if ($drewheader) {
	trigger_error(
	    "PAGEHEADER called before RedirectHTTPS ".
	    "Won't be able to redirect to HTTPS if necessary ".
	    "in ". $_SERVER['SCRIPT_FILENAME'] . ",",
	    E_USER_WARNING);
    } else if (!@$_SERVER['HTTPS'] && $_SERVER['REQUEST_METHOD'] == 'GET') {
	header("Location: https://$WWWHOST". $_SERVER['REQUEST_URI']);
	exit;
    }
}

767
768
769
770
771
772
773
774
#
# Clean out going string to be html safe.
#
function CleanString($string)
{
    return htmlspecialchars($string, ENT_QUOTES);
}

775
776
777
778
779
780
781
#
# Generate an authentication object to pass to the browser that
# is passed to the web server on boss. This is used to grant
# permission to the user to invoke ssh to a local node using their
# emulab generated (no passphrase) key. This is basically a clone
# of what GateOne does, but that code was a mess. 
#
Leigh B Stoller's avatar
Leigh B Stoller committed
782
function UnusedSSHAuthObject($uid)
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
{
    $file = "/usr/testbed/etc/sshauth.key";
    
    #
    # We need the secret that is shared with ops.
    #
    $fp = fopen($file, "r");
    if (! $fp) {
	TBERROR("Error opening $file", 0);
	return null;
    }
    list($api_key,$secret) = preg_split('/:/', fread($fp, 128));
    fclose($fp);
    if (!($secret && $api_key)) {
	TBERROR("Could not get key from $file", 0);
	return null;
    }
    $secret = chop($secret);

    $authobj = array(
	'api_key' => $api_key,
	'upn' => $uid,
	'timestamp' => time() . '000',
	'signature_method' => 'HMAC-SHA1',
	'api_version' => '1.0'
    );
    $authobj['signature'] = hash_hmac('sha1',
				      $authobj['api_key'] . $authobj['upn'] .
				      $authobj['timestamp'], $secret);
    $valid_json_auth_object = json_encode($authobj);

    return $valid_json_auth_object;
}

817
818
819
820
#
# Beware empty spaces (cookies)!
# 
require("tbauth.php3");
821
822
823
824

#
# Okay, this is what checks the login and spits out the menu.
#
825
require("Sajax.php");
826
require("menu.php3");
827
?>