acctfuncs.inc.php 21.2 KB
Newer Older
1
<?php
2

Dan McGee's avatar
Dan McGee committed
3
4
5
6
7
8
9
10
# Helper function- retrieve request param if available, "" otherwise
function in_request($name) {
	if (isset($_REQUEST[$name])) {
		return $_REQUEST[$name];
	}
	return "";
}

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Format PGP key fingerprint
function html_format_pgp_fingerprint($fingerprint) {
	if (strlen($fingerprint) != 40 || !ctype_xdigit($fingerprint)) {
		return $fingerprint;
	}

	return htmlspecialchars(substr($fingerprint, 0, 4) . " " .
		substr($fingerprint, 4, 4) . " " .
		substr($fingerprint, 8, 4) . " " .
		substr($fingerprint, 12, 4) . " " .
		substr($fingerprint, 16, 4) . "  " .
		substr($fingerprint, 20, 4) . " " .
		substr($fingerprint, 24, 4) . " " .
		substr($fingerprint, 28, 4) . " " .
		substr($fingerprint, 32, 4) . " " .
		substr($fingerprint, 36, 4) . " ", ENT_QUOTES);
}

29
# Display the standard Account form, pass in default values if any
30

eric's avatar
eric committed
31
function display_account_form($UTYPE,$A,$U="",$T="",$S="",
32
			$E="",$P="",$C="",$R="",$L="",$I="",$K="",$UID=0) {
eric's avatar
eric committed
33
	# UTYPE: what user type the form is being displayed for
34
35
36
37
38
39
40
41
42
43
44
	# A: what "form" name to use
	# U: value to display for username
	# T: value to display for account type
	# S: value to display for account suspended
	# E: value to display for email address
	# P: password value
	# C: confirm password value
	# R: value to display for RealName
	# L: value to display for Language preference
	# I: value to display for IRC nick
	# N: new package notify value
eric's avatar
eric committed
45
	# UID: Users.ID value in case form is used for editing
46
47
48

	global $SUPPORTED_LANGS;

49
	include("account_edit_form.php");
50
51
52
53
54
55
	return;
} # function display_account_form()


# process form input from a new/edit account form
#
eric's avatar
eric committed
56
function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="",
57
			$P="",$C="",$R="",$L="",$I="",$K="",$UID=0) {
eric's avatar
eric committed
58
	# UTYPE: The user's account type
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
	# TYPE: either "edit" or "new"
	# A: what parent "form" name to use
	# U: value to display for username
	# T: value to display for account type
	# S: value to display for account suspended
	# E: value to display for email address
	# P: password value
	# C: confirm password value
	# R: value to display for RealName
	# L: value to display for Language preference
	# I: value to display for IRC nick
	# N: new package notify value
	# UID: database Users.ID value

	# error check and process request for a new/modified account
	global $SUPPORTED_LANGS;

76
77
	$dbh = db_connect();

78
	if(isset($_COOKIE['AURSID'])) {
79
		$editor_user = uid_from_sid($_COOKIE['AURSID'], $dbh);
80
81
	}
	else {
82
		$editor_user = null;
83
	}
84

85
	$error = "";
86
	if (empty($E) || empty($U)) {
87
88
		$error = __("Missing a required field.");
	}
89

90
91
92
	if ($TYPE == "new") {
		# they need password fields for this type of action
		#
93
		if (empty($P) || empty($C)) {
94
95
96
97
98
99
100
			$error = __("Missing a required field.");
		}
	} else {
		if (!$UID) {
			$error = __("Missing User ID");
		}
	}
101

102
  if (!$error && !valid_username($U) && !user_is_privileged($editor_user, $dbh))
103
	$error = __("The username is invalid.") . "<ul>\n"
104
			."<li>" . __("It must be between %s and %s characters long",
105
106
			USERNAME_MIN_LEN,  USERNAME_MAX_LEN )
			. "</li>"
107
			. "<li>" . __("Start and end with a letter or number") . "</li>"
108
			. "<li>" . __("Can contain only one period, underscore or hyphen.")
109
110
			. "</li>\n</ul>";

111
112
113
	if (!$error && $P && $C && ($P != $C)) {
		$error = __("Password fields do not match.");
	}
114
	if (!$error && $P != '' && !good_passwd($P))
115
		$error = __("Your password must be at least %s characters.",PASSWD_MIN_LEN);
116

117
118
119
	if (!$error && !valid_email($E)) {
		$error = __("The email address is invalid.");
	}
120
121
122
123
124

	if (!$error && $K != '' && !valid_pgp_fingerprint($K)) {
		$error = __("The PGP key fingerprint is invalid.");
	}

eric's avatar
eric committed
125
126
127
	if ($UTYPE == "Trusted User" && $T == 3) {
		$error = __("A Trusted User cannot assign Developer status.");
	}
128
129
130
131
132
133
134
135
	if (!$error && !array_key_exists($L, $SUPPORTED_LANGS)) {
		$error = __("Language is not currently supported.");
	}
	if (!$error) {
		# check to see if this username is available
		# NOTE: a race condition exists here if we care...
		#
		$q = "SELECT COUNT(*) AS CNT FROM Users ";
136
		$q.= "WHERE Username = '".db_escape_string($U)."'";
eric's avatar
eric committed
137
138
139
		if ($TYPE == "edit") {
			$q.= " AND ID != ".intval($UID);
		}
140
141
142
143
		$result = db_query($q, $dbh);
		if ($result) {
			$row = mysql_fetch_array($result);
			if ($row[0]) {
144
				$error = __("The username, %s%s%s, is already in use.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
145
					"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>");
146
147
148
149
150
151
152
153
			}
		}
	}
	if (!$error) {
		# check to see if this email address is available
		# NOTE: a race condition exists here if we care...
		#
		$q = "SELECT COUNT(*) AS CNT FROM Users ";
154
		$q.= "WHERE Email = '".db_escape_string($E)."'";
eric's avatar
eric committed
155
156
157
		if ($TYPE == "edit") {
			$q.= " AND ID != ".intval($UID);
		}
158
159
160
161
		$result = db_query($q, $dbh);
		if ($result) {
			$row = mysql_fetch_array($result);
			if ($row[0]) {
162
				$error = __("The address, %s%s%s, is already in use.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
163
						"<b>", htmlspecialchars($E,ENT_QUOTES), "</b>");
164
165
166
167
168
			}
		}
	}
	if ($error) {
		print "<span class='error'>".$error."</span><br/>\n";
eric's avatar
eric committed
169
		display_account_form($UTYPE, $A, $U, $T, $S, $E, "", "",
170
				$R, $L, $I, $K, $UID);
171
172
173
	} else {
		if ($TYPE == "new") {
			# no errors, go ahead and create the unprivileged user
Denis's avatar
Denis committed
174
175
			$salt = generate_salt();
			$P = salted_hash($P, $salt);
176
			$escaped = array_map('db_escape_string',
177
				array($U, $E, $P, $salt, $R, $L, $I, str_replace(" ", "", $K)));
Denis's avatar
Denis committed
178
179
			$q = "INSERT INTO Users (" .
				"AccountTypeID, Suspended, Username, Email, Passwd, Salt" .
180
				", RealName, LangPreference, IRCNick, PGPKey) " .
181
				"VALUES (1, 0, '" . implode("', '", $escaped) . "')";
182
183
			$result = db_query($q, $dbh);
			if (!$result) {
184
				print __("Error trying to create account, %s%s%s: %s.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
185
						"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>", mysql_error($dbh));
186
			} else {
187
188
				# account created/modified, tell them so.
				#
189
				print __("The account, %s%s%s, has been successfully created.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
190
						"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>");
191
192
193
194
195
196
197
				print "<p>\n";
				print __("Click on the Home link above to login.");
				print "</p>\n";
			}

		} else {
			# no errors, go ahead and modify the user account
jchu's avatar
jchu committed
198

199
			$q = "UPDATE Users SET ";
200
			$q.= "Username = '".db_escape_string($U)."'";
eric's avatar
eric committed
201
202
203
204
205
206
207
208
			if ($T) {
				$q.= ", AccountTypeID = ".intval($T);
			}
			if ($S) {
				$q.= ", Suspended = 1";
			} else {
				$q.= ", Suspended = 0";
			}
209
			$q.= ", Email = '".db_escape_string($E)."'";
eric's avatar
eric committed
210
			if ($P) {
Denis's avatar
Denis committed
211
212
213
				$salt = generate_salt();
				$hash = salted_hash($P, $salt);
				$q .= ", Passwd = '$hash', Salt = '$salt'";
eric's avatar
eric committed
214
			}
215
216
217
			$q.= ", RealName = '".db_escape_string($R)."'";
			$q.= ", LangPreference = '".db_escape_string($L)."'";
			$q.= ", IRCNick = '".db_escape_string($I)."'";
218
			$q.= ", PGPKey = '".db_escape_string(str_replace(" ", "", $K))."'";
219
			$q.= " WHERE ID = ".intval($UID);
220
221
			$result = db_query($q, $dbh);
			if (!$result) {
222
				print __("Error trying to modify account, %s%s%s: %s.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
223
						"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>", mysql_error($dbh));
224
			} else {
225
				print __("The account, %s%s%s, has been successfully modified.",
Viktor Leonhardt's avatar
Viktor Leonhardt committed
226
						"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>");
227
228
229
230
231
232
233
234
235
			}
		}
	}
	return;
}

# search existing accounts
#
function search_accounts_form() {
236
	include("search_accounts_form.php");
237
238
239
240
241
242
	return;
}


# search results page
#
eric's avatar
eric committed
243
function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="",
244
		$S="",$E="",$R="",$I="",$K="") {
eric's avatar
eric committed
245
	# UTYPE: what account type the user belongs to
246
247
248
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
	# O: what row offset we're at
	# SB: how to sort the results
	# U: value to display for username
	# T: value to display for account type
	# S: value to display for account suspended
	# E: value to display for email address
	# R: value to display for RealName
	# I: value to display for IRC nick

	$HITS_PER_PAGE = 50;
	if ($O) {
		$OFFSET = intval($O);
	} else {
		$OFFSET = 0;
	}
	if ($OFFSET < 0) {
		$OFFSET = 0;
	}
	$search_vars = array();

	$q = "SELECT Users.*, AccountTypes.AccountType ";
	$q.= "FROM Users, AccountTypes ";
	$q.= "WHERE AccountTypes.ID = Users.AccountTypeID ";
	if ($T == "u") {
		$q.= "AND AccountTypes.ID = 1 ";
		$search_vars[] = "T";
	} elseif ($T == "t") {
		$q.= "AND AccountTypes.ID = 2 ";
		$search_vars[] = "T";
	} elseif ($T == "d") {
		$q.= "AND AccountTypes.ID = 3 ";
		$search_vars[] = "T";
	}
	if ($S) {
		$q.= "AND Users.Suspended = 1 ";
		$search_vars[] = "S";
	}
	if ($U) {
284
		$q.= "AND Username LIKE '%".db_escape_like($U)."%' ";
285
286
287
		$search_vars[] = "U";
	}
	if ($E) {
288
		$q.= "AND Email LIKE '%".db_escape_like($E)."%' ";
289
290
291
		$search_vars[] = "E";
	}
	if ($R) {
292
		$q.= "AND RealName LIKE '%".db_escape_like($R)."%' ";
293
294
295
		$search_vars[] = "R";
	}
	if ($I) {
296
		$q.= "AND IRCNick LIKE '%".db_escape_like($I)."%' ";
297
298
		$search_vars[] = "I";
	}
299
300
301
302
	if ($K) {
		$q.= "AND PGPKey LIKE '%".db_escape_like(str_replace(" ", "", $K))."%' ";
		$search_vars[] = "K";
	}
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
	switch ($SB) {
		case 't':
			$q.= "ORDER BY AccountTypeID, Username ";
			break;
		case 'r':
			$q.= "ORDER BY RealName, AccountTypeID ";
			break;
		case 'i':
			$q.= "ORDER BY IRCNick, AccountTypeID ";
			break;
		case 'v':
			$q.= "ORDER BY LastVoted, Username ";
			break;
		default:
			$q.= "ORDER BY Username, AccountTypeID ";
			break;
	}
	$search_vars[] = "SB";
321
	$q.= "LIMIT " . $HITS_PER_PAGE . " OFFSET " . $OFFSET;
322

323
324
	$dbh = db_connect();

325
326
327
328
329
330
	$result = db_query($q, $dbh);
	if (!$result) {
		print __("No results matched your search criteria.");
	} else {
		$num_rows = mysql_num_rows($result);
		if ($num_rows) {
331
			print "<table class='results'>\n";
Lukas Fleischer's avatar
Lukas Fleischer committed
332
			print "<tr>";
333
334
335
336
337
338
339
340
341
342
343
			print "<th class='header'>";
			print "<span class='f2'>".__("Username")."</span></th>";
			print "<th class='header'>";
			print "<span class='f2'>".__("Type")."</span></th>";
			print "<th class='header'>";
			print "<span class='f2'>".__("Status")."</span></th>";
			print "<th class='header'>";
			print "<span class='f2'>".__("Real Name")."</span></th>";
			print "<th class='header'>";
			print "<span class='f2'>".__("IRC Nick")."</span></th>";
			print "<th class='header'>";
344
345
			print "<span class='f2'>".__("PGP Key Fingerprint")."</span></th>";
			print "<th class='header'>";
346
347
348
349
350
351
352
353
354
355
356
357
358
			print "<span class='f2'>".__("Last Voted")."</span></th>";
			print "<th class='header'>";
			print "<span class='f2'>".__("Edit Account")."</span></th>";
			print "</tr>\n";
			$i = 0;
			while ($row = mysql_fetch_assoc($result)) {
				if ($i % 2) {
					$c = "data1";
				} else {
					$c = "data2";
				}
				print "<tr>";
				print "<td class='".$c."'>";
Lukas Fleischer's avatar
Lukas Fleischer committed
359
				print "<span class='f5'><a href='packages.php?SeB=m&amp;K=".$row["Username"]."'>".$row["Username"]."</a></span></td>";
360
361
362
363
364
365
366
367
368
369
370
				print "<td class='".$c."'>";
				print "<span class='f5'>".$row["AccountType"];
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
				if ($row["Suspended"]) {
					print __("Suspended");
				} else {
					print __("Active");
				}
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
Viktor Leonhardt's avatar
Viktor Leonhardt committed
371
				$row["RealName"] ? print htmlspecialchars($row["RealName"],ENT_QUOTES) : print "&nbsp;";
372
373
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
Viktor Leonhardt's avatar
Viktor Leonhardt committed
374
				$row["IRCNick"] ? print htmlspecialchars($row["IRCNick"],ENT_QUOTES) : print "&nbsp;";
375
376
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
377
378
379
				$row["PGPKey"] ? print html_format_pgp_fingerprint($row["PGPKey"]) : print "&nbsp;";
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
380
				$row["LastVoted"]
381
						? print date("Y-m-d", $row["LastVoted"])
382
383
384
						: print __("Never");
				print "</span></td>";
				print "<td class='".$c."'><span class='f5'>";
eric's avatar
eric committed
385
386
387
388
389
				if ($UTYPE == "Trusted User" && $row["AccountType"] == "Developer") {
					# TUs can't edit devs
					#
					print "&nbsp;</span></td>";
				} else {
Lukas Fleischer's avatar
Lukas Fleischer committed
390
					$edit_url = "account.php?Action=DisplayAccount&amp;ID=".$row["ID"];
eric's avatar
eric committed
391
392
393
					print "<a href='".$edit_url . "'>";
					print "Edit</a></span></td>";
				}
394
395
396
397
398
				print "</tr>\n";
				$i++;
			}
			print "</table>\n";

399
			print "<table class='results'>\n";
400
401
			print "<tr>";
			print "<td align='left'>";
402
			print "<form action='account.php' method='post'>\n";
Lukas Fleischer's avatar
Lukas Fleischer committed
403
404
			print "<fieldset>";
			print "<input type='hidden' name='Action' value='SearchAccounts' />\n";
405
			print "<input type='hidden' name='O'";
Lukas Fleischer's avatar
Lukas Fleischer committed
406
			print " value='".($OFFSET-$HITS_PER_PAGE)."' />\n";
407
408
409
			reset($search_vars);
			while (list($k, $ind) = each($search_vars)) {
				print "<input type='hidden' name='".$ind."'";
Lukas Fleischer's avatar
Lukas Fleischer committed
410
				print " value='".${$ind}."' />\n";
411
			}
eric's avatar
eric committed
412
			print "<input type='submit' class='button'";
Lukas Fleischer's avatar
Lukas Fleischer committed
413
414
			print " value='&lt;-- ".__("Less")."' />";
			print "</fieldset>";
415
416
417
			print "</form>\n";
			print "</td>";
			print "<td align='right'>";
418
			print "<form action='account.php' method='post'>\n";
Lukas Fleischer's avatar
Lukas Fleischer committed
419
420
			print "<fieldset>";
			print "<input type='hidden' name='Action' value='SearchAccounts' />\n";
421
			print "<input type='hidden' name='O'";
Lukas Fleischer's avatar
Lukas Fleischer committed
422
			print " value='".($OFFSET+$HITS_PER_PAGE)."' />\n";
423
424
425
			reset($search_vars);
			while (list($k, $ind) = each($search_vars)) {
				print "<input type='hidden' name='".$ind."'";
Lukas Fleischer's avatar
Lukas Fleischer committed
426
				print " value='".${$ind}."' />\n";
427
			}
eric's avatar
eric committed
428
			print "<input type='submit' class='button'";
Lukas Fleischer's avatar
Lukas Fleischer committed
429
430
			print " value='".__("More")." --&gt;' />";
			print "</fieldset>";
431
432
433
434
435
			print "</form>\n";
			print "</td>";
			print "</tr>\n";
			print "</table>\n";
		} else {
Lukas Fleischer's avatar
Lukas Fleischer committed
436
			print "<p style=\"text-align:center;\">\n";
437
			print __("No more results to display.");
Lukas Fleischer's avatar
Lukas Fleischer committed
438
			print "</p>\n";
439
440
441
442
443
		}
	}
	return;
}

444
445
# Display non-editable account info
#
446
function display_account_info($U="", $T="", $E="", $R="", $I="", $K="", $LV="") {
447
448
449
450
451
	# U: value to display for username
	# T: value to display for account type
	# E: value to display for email address
	# R: value to display for RealName
	# I: value to display for IRC nick
452
	# LV: value to display for last voted
453
454
455

	global $SUPPORTED_LANGS;

456
	print "<table>\n";
457
458
459
460
461
462
463
464
	print "  <tr>\n";
	print "    <td colspan='2'>&nbsp;</td>\n";
	print "  </tr>\n";

	print "  <tr>\n";
	print "    <td align='left'>".__("Username").":</td>\n";
	print "    <td align='left'>".$U."</td>\n";
	print "  </tr>\n";
465

466
467
468
469
470
471
472
	print "  <tr>\n";
	print "    <td align='left'>".__("Account Type").":</td>\n";
	print "    <td align='left'>";
	if ($T == "User") {
		print __("User");
	} elseif ($T == "Trusted User") {
		print __("Trusted User");
473
	} elseif ($T == "Developer") {
474
475
		print __("Developer");
	}
Lukas Fleischer's avatar
Lukas Fleischer committed
476
477
	print "    </td>\n";
	print "  </tr>\n";
478

479
480
	print "  <tr>\n";
	print "    <td align='left'>".__("Email Address").":</td>\n";
Viktor Leonhardt's avatar
Viktor Leonhardt committed
481
	print "    <td align='left'><a href='mailto:".htmlspecialchars($E,ENT_QUOTES)."'>".htmlspecialchars($E,ENT_QUOTES)."</a></td>\n";
482
483
484
485
	print "  </tr>\n";

	print "  <tr>\n";
	print "    <td align='left'>".__("Real Name").":</td>\n";
Viktor Leonhardt's avatar
Viktor Leonhardt committed
486
	print "    <td align='left'>".htmlspecialchars($R,ENT_QUOTES)."</td>\n";
487
488
489
490
	print "  </tr>\n";

	print "  <tr>\n";
	print "    <td align='left'>".__("IRC Nick").":</td>\n";
Viktor Leonhardt's avatar
Viktor Leonhardt committed
491
	print "    <td align='left'>".htmlspecialchars($I,ENT_QUOTES)."</td>\n";
492
493
	print "  </tr>\n";

494
495
496
497
498
	print "  <tr>\n";
	print "    <td align='left'>".__("PGP Key Fingerprint").":</td>\n";
	print "    <td align='left'>".html_format_pgp_fingerprint($K)."</td>\n";
	print "  </tr>\n";

499
500
501
502
503
504
505
	print "  <tr>\n";
	print "    <td align='left'>".__("Last Voted").":</td>\n";
	print "    <td align='left'>";
	print $LV ? date("Y-m-d", $LV) : __("Never");
	print "</td>\n";
	print "  </tr>\n";

506
	print "  <tr>\n";
Lukas Fleischer's avatar
Lukas Fleischer committed
507
	print "    <td colspan='2'><a href='packages.php?K=".$U."&amp;SeB=m'>".__("View this user's packages")."</a></td>\n";
508
509
	print "  </tr>\n";

510
511
512
513
	print "</table>\n";
	return;
}

514
515
516
517
518
/*
 * Returns SID (Session ID) and error (error message) in an array
 * SID of 0 means login failed.
 */
function try_login() {
519
	global $MAX_SESSIONS_PER_USER, $PERSISTENT_COOKIE_TIMEOUT;
520

Loui Chang's avatar
Loui Chang committed
521
	$login_error = "";
522
523
524
525
	$new_sid = "";
	$userID = null;

	if ( isset($_REQUEST['user']) || isset($_REQUEST['passwd']) ) {
526
527
		$dbh = db_connect();
		$userID = valid_user($_REQUEST['user'], $dbh);
528

529
		if ( user_suspended($userID, $dbh) ) {
530
531
532
			$login_error = "Account Suspended.";
		}
		elseif ( $userID && isset($_REQUEST['passwd'])
533
		  && valid_passwd($userID, $_REQUEST['passwd'], $dbh) ) {
534
535
536
537
538
539
540

			$logged_in = 0;
			$num_tries = 0;

			# Account looks good.  Generate a SID and store it.

			while (!$logged_in && $num_tries < 5) {
541
542
543
544
545
				if ($MAX_SESSIONS_PER_USER) {
					# Delete all user sessions except the
					# last ($MAX_SESSIONS_PER_USER - 1).
					$q = "DELETE s.* FROM Sessions s ";
					$q.= "LEFT JOIN (SELECT SessionID FROM Sessions ";
546
					$q.= "WHERE UsersId = " . $userID . " ";
547
548
549
					$q.= "ORDER BY LastUpdateTS DESC ";
					$q.= "LIMIT " . ($MAX_SESSIONS_PER_USER - 1) . ") q ";
					$q.= "ON s.SessionID = q.SessionID ";
550
					$q.= "WHERE s.UsersId = " . $userID . " ";
551
552
553
554
					$q.= "AND q.SessionID IS NULL;";
					db_query($q, $dbh);
				}

555
556
				$new_sid = new_sid();
				$q = "INSERT INTO Sessions (UsersID, SessionID, LastUpdateTS)"
557
				  ." VALUES (" . $userID . ", '" . $new_sid . "', UNIX_TIMESTAMP())";
558
				$result = db_query($q, $dbh);
559

560
561
562
563
564
				# Query will fail if $new_sid is not unique
				if ($result) {
					$logged_in = 1;
					break;
				}
565

566
				$num_tries++;
567
			}
568

569
			if ($logged_in) {
570
571
572
				$q = "UPDATE Users SET LastLogin = UNIX_TIMESTAMP() ";
				$q.= "WHERE ID = '$userID'";
				db_query($q, $dbh);
573

574
				# set our SID cookie
Dan McGee's avatar
Dan McGee committed
575
576
				if (isset($_POST['remember_me']) &&
					$_POST['remember_me'] == "on") {
577
					# Set cookies for 30 days.
578
					$cookie_time = time() + $PERSISTENT_COOKIE_TIMEOUT;
579
580
581
582
583
584

					# Set session for 30 days.
					$q = "UPDATE Sessions SET LastUpdateTS = $cookie_time ";
					$q.= "WHERE SessionID = '$new_sid'";
					db_query($q, $dbh);
				}
585
586
				else
					$cookie_time = 0;
587

588
				setcookie("AURSID", $new_sid, $cookie_time, "/", null, !empty($_SERVER['HTTPS']), true);
589
				header("Location: " . $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING']);
590
591
592
593
594
595
596
597
				$login_error = "";

			}
			else {
				$login_error = "Error trying to generate session id.";
			}
		}
		else {
598
			$login_error = __("Bad username or password.");
599
600
601
602
603
604
605
606
607
608
609
610
611
612
		}
	}
	return array('SID' => $new_sid, 'error' => $login_error);
}

/*
 * Only checks if the name itself is valid
 * Longer or equal to USERNAME_MIN_LEN
 * Shorter or equal to USERNAME_MAX_LEN
 * Starts and ends with a letter or number
 * Contains at most ONE dot, hyphen, or underscore
 * Returns the username if it is valid
 * Returns nothing if it isn't valid
 */
613
function valid_username($user) {
614
	if (!empty($user)) {
615

616
617
618
		#Is username at not too short or too long?
		if ( strlen($user) >= USERNAME_MIN_LEN &&
		  strlen($user) <= USERNAME_MAX_LEN ) {
619

620
			$user = strtolower($user);
621
			# Does username:
622
623
624
625
626
627
628
629
630
			# start and end with a letter or number
			# contain only letters and numbers,
			#  and at most has one dash, period, or underscore
			if ( preg_match("/^[a-z0-9]+[.\-_]?[a-z0-9]+$/", $user) ) {
				#All is good return the username
				return $user;
			}
		}
	}
631

632
633
634
635
636
637
638
	return;
}

/*
 * Checks if the username is valid and if it exists in the database
 * Returns the username ID or nothing
 */
639
function valid_user($user, $dbh) {
640
641
642
	/*	if ( $user = valid_username($user) ) { */
	if ( $user ) {
		$q = "SELECT ID FROM Users WHERE Username = '"
643
			. db_escape_string($user). "'";
644

645
		$result = db_query($q, $dbh);
646
		# Is the username in the database?
647
648
649
		if ($result) {
			$row = mysql_fetch_row($result);
			return $row[0];
650
651
652
653
654
		}
	}
	return;
}

655
function good_passwd($passwd) {
656
657
658
659
660
661
662
663
664
	if ( strlen($passwd) >= PASSWD_MIN_LEN ) {
		return true;
	}
	return false;
}

/* Verifies that the password is correct for the userID specified.
 * Returns true or false
 */
665
function valid_passwd($userID, $passwd, $dbh) {
666
	if ( strlen($passwd) > 0 ) {
Denis's avatar
Denis committed
667
668
669
670
671
		# get salt for this user
		$salt = get_salt($userID);
		if ($salt) {
			# use salt
			$passwd_q = "SELECT ID FROM Users" .
672
				" WHERE ID = " . $userID  . " AND Passwd = '" .
Denis's avatar
Denis committed
673
				salted_hash($passwd, $salt) . "'";
674
675
676
677
678
679
			$result = db_query($passwd_q, $dbh);
			if ($result) {
				$passwd_result = mysql_fetch_row($result);
				if ($passwd_result[0]) {
					return true;
				}
Denis's avatar
Denis committed
680
681
682
683
			}
		} else {
			# check without salt
			$nosalt_q = "SELECT ID FROM Users".
684
				" WHERE ID = " . $userID .
Denis's avatar
Denis committed
685
				" AND Passwd = '" . md5($passwd) . "'";
686
687
688
689
690
691
692
693
694
695
696
			$result = db_query($nosalt_q, $dbh);
			if ($result) {
				$nosalt_row = mysql_fetch_row($result);
				if ($nosalt_row[0]) {
					# password correct, but salt it first
					if (!save_salt($userID, $passwd)) {
						trigger_error("Unable to salt user's password;" .
							" ID " . $userID, E_USER_WARNING);
						return false;
					}
					return true;
Denis's avatar
Denis committed
697
698
				}
			}
699
700
701
702
703
		}
	}
	return false;
}

704
705
706
/*
 * Checks if the PGP key fingerprint is valid (must be 40 hexadecimal digits).
 */
707
function valid_pgp_fingerprint($fingerprint) {
708
709
710
711
	$fingerprint = str_replace(" ", "", $fingerprint);
	return (strlen($fingerprint) == 40 && ctype_xdigit($fingerprint));
}

712
713
714
/*
 * Is the user account suspended?
 */
715
function user_suspended($id, $dbh) {
elij's avatar
elij committed
716
717
718
	if (!$id) {
		return false;
	}
719
	$q = "SELECT Suspended FROM Users WHERE ID = " . $id;
720
721
722
723
724
725
	$result = db_query($q, $dbh);
	if ($result) {
		$row = mysql_fetch_row($result);
		if ($result[0] == 1 ) {
			return true;
		}
726
727
728
729
730
731
732
	}
	return false;
}

/*
 * This should be expanded to return something
 */
733
function user_delete($id, $dbh) {
734
	$q = "DELETE FROM Users WHERE ID = " . $id;
735
	db_query($q, $dbh);
736
737
738
739
740
741
742
	return;
}

/*
 * A different way of determining a user's privileges
 * rather than account_from_sid()
 */
743
function user_is_privileged($id, $dbh) {
744
	$q = "SELECT AccountTypeID FROM Users WHERE ID = " . $id;
745
746
747
748
749
750
	$result = db_query($q, $dbh);
	if ($result) {
		$row = mysql_fetch_row($result);
		if( $result[0] > 1) {
			return $result[0];
		}
751
	}
752
753
754
755
	return 0;

}

756
# Clear out old expired sessions.
757
function clear_expired_sessions( $dbh ) {
758
759
	global $LOGIN_TIMEOUT;

760
	$q = "DELETE FROM Sessions WHERE LastUpdateTS < (UNIX_TIMESTAMP() - $LOGIN_TIMEOUT)";
761
762
763
764
	db_query($q, $dbh);

	return;
}
765