Project

General

Profile

Download (39.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	Copyright (C) 2010 Ermal Lu?i
5
	All rights reserved.
6

    
7
	Copyright (C) 2007, 2008 Scott Ullrich <sullrich@gmail.com>
8
	All rights reserved.
9

    
10
        Copyright (C) 2005-2006 Bill Marquette <bill.marquette@gmail.com>
11
        All rights reserved.
12

    
13
        Copyright (C) 2006 Paul Taylor <paultaylor@winn-dixie.com>.
14
        All rights reserved.
15

    
16
        Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
17
        All rights reserved.
18

    
19
        Redistribution and use in source and binary forms, with or without
20
        modification, are permitted provided that the following conditions are met:
21

    
22
        1. Redistributions of source code must retain the above copyright notice,
23
           this list of conditions and the following disclaimer.
24

    
25
        2. Redistributions in binary form must reproduce the above copyright
26
           notice, this list of conditions and the following disclaimer in the
27
           documentation and/or other materials provided with the distribution.
28

    
29
        THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
30
        INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
31
        AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
        AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
33
        OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34
        SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35
        INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36
        CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
        ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
        POSSIBILITY OF SUCH DAMAGE.
39

    
40
		DISABLE_PHP_LINT_CHECKING
41
		pfSense_BUILDER_BINARIES:	/usr/sbin/pw	/bin/cp
42
		pfSense_MODULE:	auth
43
*/
44

    
45
/*
46
 * NOTE : Portions of the mschapv2 support was based on the BSD licensed CHAP.php
47
 * file courtesy of Michael Retterklieber.
48
 */
49
if(!$do_not_include_config_gui_inc)
50
	require_once("config.gui.inc");
51

    
52
// Will be changed to false if security checks fail
53
$security_passed = true;
54

    
55
/* If this function doesn't exist, we're being called from Captive Portal or 
56
   another internal subsystem which does not include authgui.inc */
57
if (function_exists("display_error_form") && !isset($config['system']['webgui']['nodnsrebindcheck'])) {
58
	/* DNS ReBinding attack prevention.  http://redmine.pfsense.org/issues/708 */
59
	$found_host = false;
60
	if(strstr($_SERVER['HTTP_HOST'], ":")) {
61
		$http_host_port = explode(":", $_SERVER['HTTP_HOST']);
62
		$http_host = $http_host_port[0];
63
	} else {
64
		$http_host = $_SERVER['HTTP_HOST'];
65
	}
66
	if(is_ipaddr($http_host) or $_SERVER['SERVER_ADDR'] == "127.0.0.1" or
67
			strcasecmp($http_host, "localhost") == 0)
68
		$found_host = true;
69
	if(strcasecmp($http_host, $config['system']['hostname'] . "." . $config['system']['domain']) == 0 or
70
			strcasecmp($http_host, $config['system']['hostname']) == 0)
71
		$found_host = true;
72

    
73
	if(is_array($config['dyndnses']['dyndns']) && !$found_host)
74
		foreach($config['dyndnses']['dyndns'] as $dyndns)
75
			if(strcasecmp($dyndns['host'], $http_host) == 0) {
76
				$found_host = true;
77
				break;
78
			}
79

    
80
	if(!empty($config['system']['webgui']['althostnames']) && !$found_host) {
81
		$althosts = explode(" ", $config['system']['webgui']['althostnames']);
82
		foreach ($althosts as $ah)
83
			if(strcasecmp($ah, $http_host) == 0 or strcasecmp($ah, $_SERVER['SERVER_ADDR']) == 0) {
84
				$found_host = true;
85
				break;
86
			}
87
	}
88

    
89
	if($found_host == false) {
90
		if(!security_checks_disabled()) {
91
			display_error_form("501", "Potential DNS Rebind attack detected, see http://en.wikipedia.org/wiki/DNS_rebinding<br/>Try accessing the router by IP address instead of by hostname.");
92
			exit;
93
		}
94
		$security_passed = false;
95
	}
96
}
97

    
98
// If the HTTP_REFERER is something other than ourselves then disallow.
99
if(function_exists("display_error_form") && !isset($config['system']['webgui']['nohttpreferercheck'])) {
100
	if($_SERVER['HTTP_REFERER']) {
101
		if(file_exists("{$g['tmp_path']}/setupwizard_lastreferrer")) {
102
			if($_SERVER['HTTP_REFERER'] == file_get_contents("{$g['tmp_path']}/setupwizard_lastreferrer")) {
103
				unlink("{$g['tmp_path']}/setupwizard_lastreferrer");
104
				header("Refresh: 1; url=index.php");
105
				echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
106
				echo "<html><head><title>" . gettext("Redirecting...") . "</title></head><body>" . gettext("Redirecting to the dashboard...") . "</body></html>";
107
				exit;
108
			}
109
		}
110
		$found_host = false;
111
		$referrer_host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
112
		if($referrer_host) {
113
			if(strcasecmp($referrer_host, $config['system']['hostname'] . "." . $config['system']['domain']) == 0
114
					|| strcasecmp($referrer_host, $config['system']['hostname']) == 0)
115
				$found_host = true;
116
			if(!empty($config['system']['webgui']['althostnames']) && !$found_host) {
117
				$althosts = explode(" ", $config['system']['webgui']['althostnames']);
118
				foreach ($althosts as $ah) {
119
					if(strcasecmp($referrer_host, $ah) == 0) {
120
						$found_host = true;
121
						break;
122
					}
123
				}
124
			}
125
			if(!$found_host) {
126
				$interface_list_ips = get_configured_ip_addresses();
127
				foreach($interface_list_ips as $ilips) {
128
					if(strcasecmp($referrer_host, $ilips) == 0) {
129
						$found_host = true;
130
						break;
131
					}
132
				}
133
				if($referrer_host == "127.0.0.1" || $referrer_host == "localhost") {
134
					// allow SSH port forwarded connections and links from localhost
135
					$found_host = true;
136
				}
137
			}
138
		}
139
		if($found_host == false) {
140
			if(!security_checks_disabled()) {
141
				display_error_form("501", "An HTTP_REFERER was detected other than what is defined in System -> Advanced (" . htmlspecialchars($_SERVER['HTTP_REFERER']) . ").  You can disable this check if needed in System -> Advanced -> Admin.");
142
				exit;
143
			}
144
			$security_passed = false;
145
		}
146
	} else
147
		$security_passed = false;
148
}
149

    
150
if (function_exists("display_error_form") && $security_passed)
151
	/* Security checks passed, so it should be OK to turn them back on */
152
	restore_security_checks();
153
unset($security_passed);
154

    
155
$groupindex = index_groups();
156
$userindex = index_users();
157

    
158
function index_groups() {
159
	global $g, $debug, $config, $groupindex;
160

    
161
	$groupindex = array();
162

    
163
	if (is_array($config['system']['group'])) {
164
		$i = 0;
165
		foreach($config['system']['group'] as $groupent) {
166
			$groupindex[$groupent['name']] = $i;
167
			$i++;
168
		}
169
	}
170

    
171
	return ($groupindex);
172
}
173

    
174
function index_users() {
175
	global $g, $debug, $config;
176

    
177
	if (is_array($config['system']['user'])) {
178
		$i = 0;
179
		foreach($config['system']['user'] as $userent) {
180
			$userindex[$userent['name']] = $i;
181
			$i++;
182
		}
183
	}
184

    
185
	return ($userindex);
186
}
187

    
188
function & getUserEntry($name) {
189
	global $debug, $config, $userindex;
190
	if (isset($userindex[$name]))
191
		return $config['system']['user'][$userindex[$name]];
192
}
193

    
194
function & getUserEntryByUID($uid) {
195
	global $debug, $config;
196

    
197
	if (is_array($config['system']['user']))
198
		foreach ($config['system']['user'] as & $user)
199
			if ($user['uid'] == $uid)
200
				return $user;
201

    
202
	return false;
203
}
204

    
205
function & getGroupEntry($name) {
206
	global $debug, $config, $groupindex;
207
	if (isset($groupindex[$name]))
208
		return $config['system']['group'][$groupindex[$name]];
209
}
210

    
211
function & getGroupEntryByGID($gid) {
212
	global $debug, $config;
213

    
214
	if (is_array($config['system']['group']))
215
		foreach ($config['system']['group'] as & $group)
216
			if ($group['gid'] == $gid)
217
				return $group;
218

    
219
	return false;
220
}
221

    
222
function get_user_privileges(& $user) {
223

    
224
        $privs = $user['priv'];
225
        if (!is_array($privs))
226
                $privs = array();
227

    
228
        $names = local_user_get_groups($user, true);
229

    
230
        foreach ($names as $name) {
231
                $group = getGroupEntry($name);
232
                if (is_array($group['priv']))
233
                        $privs = array_merge( $privs, $group['priv']);
234
        }
235

    
236
        return $privs;
237
}
238

    
239
function userHasPrivilege($userent, $privid = false) {
240

    
241
        if (!$privid || !is_array($userent))
242
                return false;
243

    
244
        $privs = get_user_privileges($userent);
245

    
246
        if (!is_array($privs))
247
                return false;
248

    
249
        if (!in_array($privid, $privs))
250
                return false;
251

    
252
        return true;
253
}
254

    
255
function local_backed($username, $passwd) {
256

    
257
	$user = getUserEntry($username);
258
	if (!$user)
259
		return false;
260

    
261
	if (is_account_disabled($username) || is_account_expired($username))
262
		return false;
263

    
264
	if ($user['password'])
265
	{
266
		$passwd = crypt($passwd, $user['password']);
267
		if ($passwd == $user['password'])
268
			return true;
269
	}
270

    
271
	if ($user['md5-hash'])
272
	{
273
		$passwd = md5($passwd);
274
		if ($passwd == $user['md5-hash'])
275
			return true;
276
	}
277

    
278
	return false;
279
}
280

    
281
function local_sync_accounts() {
282
	global $debug, $config;
283
	conf_mount_rw();
284

    
285
	/* remove local users to avoid uid conflicts */
286
	$fd = popen("/usr/sbin/pw usershow -a", "r");
287
	if ($fd) {
288
		while (!feof($fd)) {
289
			$line = explode(":",fgets($fd));
290
			if (!strncmp($line[0], "_", 1))
291
				continue;
292
			if ($line[2] < 2000)
293
				continue;
294
			if ($line[2] > 65000)
295
				continue;
296
			$cmd = "/usr/sbin/pw userdel {$line[2]}";
297
			if($debug)
298
				log_error("Running: {$cmd}");
299
			mwexec($cmd);
300
		}
301
		pclose($fd);
302
	}
303

    
304
	/* remove local groups to avoid gid conflicts */
305
	$gids = array();
306
	$fd = popen("/usr/sbin/pw groupshow -a", "r");
307
	if ($fd) {
308
		while (!feof($fd)) {
309
			$line = explode(":",fgets($fd));
310
			if (!strncmp($line[0], "_", 1))
311
				continue;
312
			if ($line[2] < 2000)
313
				continue;
314
			if ($line[2] > 65000)
315
				continue;
316
			$cmd = "/usr/sbin/pw groupdel {$line[2]}";
317
			if($debug)
318
				log_error("Running: {$cmd}");
319
			mwexec($cmd);
320
		}
321
		pclose($fd);
322
	}
323

    
324
	/* make sure the all group exists */
325
	$allgrp = getGroupEntryByGID(1998);
326
	local_group_set($allgrp, true);
327

    
328
	/* sync all local users */
329
	if (is_array($config['system']['user']))
330
		foreach ($config['system']['user'] as $user)
331
			local_user_set($user);
332

    
333
	/* sync all local groups */
334
	if (is_array($config['system']['group']))
335
		foreach ($config['system']['group'] as $group)
336
			local_group_set($group);
337

    
338
	conf_mount_ro();
339

    
340
}
341

    
342
function local_user_set(& $user) {
343
	global $g, $debug;
344

    
345
	conf_mount_rw();
346

    
347
	$home_base = "/home/";	
348
	$user_uid = $user['uid'];
349
	$user_name = $user['name'];
350
	$user_home = "{$home_base}{$user_name}";
351
	$user_shell = "/etc/rc.initial";
352
	$user_group = "nobody";
353

    
354
	// Ensure $home_base exists and is writable
355
	if (!is_dir($home_base)) 
356
		mkdir($home_base, 0755);
357

    
358
	$lock_account = false;
359
	/* configure shell type */
360
	/* Cases here should be ordered by most privileged to least privileged. */
361
	if (userHasPrivilege($user, "user-shell-access") || userHasPrivilege($user, "page-all")) {
362
		$user_shell = "/bin/tcsh";
363
	} elseif (userHasPrivilege($user, "user-copy-files")) {
364
		$user_shell = "/usr/local/bin/scponly";
365
	} elseif (userHasPrivilege($user, "user-ssh-tunnel")) {
366
		$user_shell = "/usr/local/sbin/ssh_tunnel_shell";
367
	} elseif (userHasPrivilege($user, "user-ipsec-xauth-dialin")) {
368
		$user_shell = "/sbin/nologin";
369
	} else {
370
		$user_shell = "/sbin/nologin";
371
		$lock_account = true;
372
	}
373

    
374
	/* Lock out disabled or expired users, unless it's root/admin. */
375
	if ((is_account_disabled($user_name) || is_account_expired($user_name)) && ($user_uid != 0)) {
376
		$user_shell = "/sbin/nologin";
377
		$lock_account = true;
378
	}
379

    
380
	/* root user special handling */
381
	if ($user_uid == 0) {
382
		$cmd = "/usr/sbin/pw usermod -q -n root -s /bin/sh -H 0";
383
		if($debug)
384
			log_error("Running: {$cmd}");
385
		$fd = popen($cmd, "w");
386
		fwrite($fd, $user['password']);
387
		pclose($fd);
388
		$user_group = "wheel";
389
		$user_home = "/root";
390
		$user_shell = "/etc/rc.initial";
391
	}
392

    
393
	/* read from pw db */
394
	$fd = popen("/usr/sbin/pw usershow {$user_name} 2>&1", "r");
395
	$pwread = fgets($fd);
396
	pclose($fd);
397

    
398
	/* determine add or mod */
399
	if (!strncmp($pwread, "pw:", 3)) {
400
		$user_op = "useradd -m -k /etc/skel -o";
401
	} else {
402
		$user_op = "usermod";
403
	}
404

    
405
	/* add or mod pw db */
406
	$cmd = "/usr/sbin/pw {$user_op} -q -u {$user_uid} -n {$user_name}".
407
			" -g {$user_group} -s {$user_shell} -d {$user_home}".
408
			" -c ".escapeshellarg($user['descr'])." -H 0 2>&1";
409

    
410
	if($debug)
411
		log_error("Running: {$cmd}");
412
	$fd = popen($cmd, "w");
413
	fwrite($fd, $user['password']);
414
	pclose($fd);
415

    
416
	/* create user directory if required */
417
	if (!is_dir($user_home)) {
418
		mkdir($user_home, 0700);
419
		mwexec("/bin/cp /root/.* {$home_base}/", true);
420
	}
421
	chown($user_home, $user_name);
422
	chgrp($user_home, $user_group);
423

    
424
	/* write out ssh authorized key file */
425
	if($user['authorizedkeys']) {
426
		if (!is_dir("{$user_home}/.ssh")) {
427
			mkdir("{$user_home}/.ssh", 0700);
428
			chown("{$user_home}/.ssh", $user_name);
429
		}
430
		$keys = base64_decode($user['authorizedkeys']);
431
		file_put_contents("{$user_home}/.ssh/authorized_keys", $keys);
432
		chown("{$user_home}/.ssh/authorized_keys", $user_name);
433
	} else
434
		unlink_if_exists("{$user_home}/.ssh/authorized_keys");
435

    
436
	$un = $lock_account ? "" : "un";
437
	exec("/usr/sbin/pw {$un}lock {$user_name} -q");
438
	
439
	conf_mount_ro();
440
}
441

    
442
function local_user_del($user) {
443
	global $debug;
444

    
445
	/* remove all memberships */
446
	local_user_set_groups($user);
447

    
448
	/* Don't remove /root */
449
	if ($user['uid'] != 0)
450
		$rmhome = "-r";
451

    
452
	/* delete from pw db */
453
	$cmd = "/usr/sbin/pw userdel {$user['name']} {$rmhome}";
454

    
455
	if($debug)
456
		log_error("Running: {$cmd}");
457
	mwexec($cmd);
458

    
459
	/* Delete user from groups needs a call to write_config() */
460
	local_group_del_user($user);
461
}
462

    
463
function local_user_set_password(& $user, $password) {
464

    
465
	$user['password'] = crypt($password);
466
	$user['md5-hash'] = md5($password);
467

    
468
	// Converts ascii to unicode.
469
	$astr = (string) $password;
470
	$ustr = '';
471
	for ($i = 0; $i < strlen($astr); $i++) {
472
		$a = ord($astr{$i}) << 8;
473
		$ustr.= sprintf("%X", $a);
474
	}
475

    
476
	// Generate the NT-HASH from the unicode string
477
	$user['nt-hash'] = bin2hex(mhash(MHASH_MD4, $ustr));
478
}
479

    
480
function local_user_get_groups($user, $all = false) {
481
	global $debug, $config;
482

    
483
	$groups = array();
484
	if (!is_array($config['system']['group']))
485
		return $groups;
486

    
487
	foreach ($config['system']['group'] as $group)
488
		if ( $all || ( !$all && ($group['name'] != "all")))
489
			if (is_array($group['member']))
490
				if (in_array($user['uid'], $group['member']))
491
					$groups[] = $group['name'];
492

    
493
	if ( $all )
494
		$groups[] = "all";
495

    
496
	sort($groups);
497

    
498
	return $groups;
499
	
500
}
501

    
502
function local_user_set_groups($user, $new_groups = NULL ) {
503
	global $debug, $config, $groupindex;
504

    
505
	if (!is_array($config['system']['group']))
506
		return;
507

    
508
	$cur_groups = local_user_get_groups($user, true);
509
	$mod_groups = array();
510

    
511
	if (!is_array($new_groups))
512
		$new_groups = array();
513

    
514
	if (!is_array($cur_groups))
515
		$cur_groups = array();
516

    
517
	/* determine which memberships to add */
518
	foreach ($new_groups as $groupname) {
519
		if (in_array($groupname,$cur_groups))
520
			continue;
521
		$group = & $config['system']['group'][$groupindex[$groupname]];
522
		$group['member'][] = $user['uid'];
523
		$mod_groups[] = $group;
524
	}
525
	unset($group);
526

    
527
	/* determine which memberships to remove */
528
	foreach ($cur_groups as $groupname) {
529
		if (in_array($groupname,$new_groups))
530
			continue;
531
		if (!isset($config['system']['group'][$groupindex[$groupname]]))
532
			continue;
533
		$group = & $config['system']['group'][$groupindex[$groupname]];
534
		if (is_array($group['member'])) {
535
			$index = array_search($user['uid'], $group['member']);
536
			array_splice($group['member'], $index, 1);
537
			$mod_groups[] = $group;
538
		}
539
	}
540
	unset($group);
541

    
542
	/* sync all modified groups */
543
	foreach ($mod_groups as $group)
544
		local_group_set($group);
545
}
546

    
547
function local_group_del_user($user) {
548
	global $config;
549

    
550
	if (!is_array($config['system']['group']))
551
                return;
552

    
553
        foreach ($config['system']['group'] as $group) {
554
		if (is_array($group['member'])) {
555
			foreach ($group['member'] as $idx => $uid) {
556
				if ($user['uid'] == $uid)
557
					unset($config['system']['group']['member'][$idx]);
558
			}
559
		}
560
	}
561
}
562

    
563
function local_group_set($group, $reset = false) {
564
	global $debug;
565

    
566
	$group_name = $group['name'];
567
	$group_gid = $group['gid'];
568
	$group_members = "''";
569
	if (!$reset && !empty($group['member']) && count($group['member']) > 0)
570
		$group_members = implode(",",$group['member']);
571

    
572
	/* read from group db */
573
	$fd = popen("/usr/sbin/pw groupshow {$group_name} 2>&1", "r");
574
	$pwread = fgets($fd);
575
	pclose($fd);
576

    
577
	/* determine add or mod */
578
	if (!strncmp($pwread, "pw:", 3))
579
		$group_op = "groupadd";
580
	else
581
		$group_op = "groupmod";
582

    
583
	/* add or mod group db */
584
	$cmd = "/usr/sbin/pw {$group_op} {$group_name} -g {$group_gid} -M {$group_members} 2>&1";
585

    
586
	if($debug)
587
		log_error("Running: {$cmd}");
588
	mwexec($cmd);
589

    
590
}
591

    
592
function local_group_del($group) {
593
	global $debug;
594

    
595
	/* delete from group db */
596
	$cmd = "/usr/sbin/pw groupdel {$group['name']}";
597

    
598
	if($debug)
599
		log_error("Running: {$cmd}");
600
	mwexec($cmd);
601
}
602

    
603
function ldap_test_connection($authcfg) {
604
	global $debug, $config, $g;
605

    
606
	if ($authcfg) {
607
                if (strstr($authcfg['ldap_urltype'], "Standard"))
608
                        $ldapproto = "ldap";
609
                else
610
                        $ldapproto = "ldaps";
611
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
612
                $ldapport           = $authcfg['ldap_port'];
613
                $ldapbasedn         = $authcfg['ldap_basedn'];
614
                $ldapbindun         = $authcfg['ldap_binddn'];
615
                $ldapbindpw         = $authcfg['ldap_bindpw'];
616
        } else
617
		return false;
618

    
619
        /* first check if there is even an LDAP server populated */
620
        if(!$ldapserver)
621
                return false;
622

    
623
        /* Setup CA environment if needed. */
624
        ldap_setup_caenv($authcfg);
625

    
626
        /* connect and see if server is up */
627
        $error = false;
628
        if (empty($ldapport)) {
629
                if (!($ldap = ldap_connect($ldapserver)))
630
                        $error = true;
631
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
632
                $error = true;
633

    
634
        if ($error == true) {
635
                log_error("ERROR!  Could not connect to server {$ldapname}.");
636
                return false;
637
        }
638

    
639
	return true;
640
}
641

    
642
function ldap_setup_caenv($authcfg) {
643
	global $g;
644

    
645
	unset($caref);
646
	if (empty($authcfg['ldap_cacert']) || !strstr($authcfg['ldap_urltype'], "SSL")) {
647
		putenv('LDAPTLS_REQCERT=never');
648
		return;
649
	} else {
650
		$caref = lookup_ca($authcfg['ldap_cacert']);
651
		if (!$caref) {
652
			log_error(sprintf(gettext("LDAP: Could not lookup CA by reference for host %s."), $authcfg['ldap_cacert']));
653
			/* XXX: Prevent for credential leaking since we cannot setup the CA env. Better way? */
654
			putenv('LDAPTLS_REQCERT=hard');
655
			return;
656
		}
657
		if (!is_dir("{$g['varrun_path']}/certs"))
658
			@mkdir("{$g['varrun_path']}/certs");
659
		if (file_exists("{$g['varrun_path']}/certs/{$authcfg['name']}.ca"))
660
			@unlink("{$g['varrun_path']}/certs/{$authcfg['name']}.ca");
661
		file_put_contents("{$g['varrun_path']}/certs/{$authcfg['name']}.ca", base64_decode($caref['crt']));
662
		@chmod("{$g['varrun_path']}/certs/{$authcfg['name']}.ca", 0600);
663
		putenv('LDAPTLS_REQCERT=hard');
664
		/* XXX: Probably even the hashed link should be created for this? */
665
		putenv("TLS_CACERTDIR={$g['varrun_path']}/certs");
666
		putenv("TLS_CACERT={$g['varrun_path']}/certs/{$authcfg['name']}.ca");
667
	}
668
}
669

    
670
function ldap_test_bind($authcfg) {
671
	global $debug, $config, $g;
672

    
673
	if ($authcfg) {
674
                if (strstr($authcfg['ldap_urltype'], "Standard"))
675
                        $ldapproto = "ldap";
676
                else
677
                        $ldapproto = "ldaps";
678
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
679
                $ldapport           = $authcfg['ldap_port'];
680
                $ldapbasedn         = $authcfg['ldap_basedn'];
681
                $ldapbindun         = $authcfg['ldap_binddn'];
682
                $ldapbindpw         = $authcfg['ldap_bindpw'];
683
                $ldapver            = $authcfg['ldap_protver'];
684
		if (empty($ldapbndun) || empty($ldapbindpw))
685
                        $ldapanon = true;
686
                else
687
                        $ldapanon = false;
688
	} else
689
		return false;
690

    
691
	/* first check if there is even an LDAP server populated */
692
        if(!$ldapserver)
693
                return false;
694

    
695
	/* Setup CA environment if needed. */
696
	ldap_setup_caenv($authcfg);
697

    
698
        /* connect and see if server is up */
699
        $error = false;
700
        if (empty($ldapport)) {
701
                if (!($ldap = ldap_connect($ldapserver)))
702
                        $error = true;
703
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
704
                $error = true;
705

    
706
        if ($error == true) {
707
                log_error("ERROR!  Could not connect to server {$ldapname}.");
708
                return false;
709
        }
710

    
711
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
712
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
713
 
714
	if ($ldapanon == true) {
715
		if (!($res = @ldap_bind($ldap))) {
716
			@ldap_close($ldap);
717
			return false;
718
		}
719
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
720
		@ldap_close($ldap);
721
		return false;
722
	}
723

    
724
	@ldap_unbind($ldap);
725

    
726
	return true;
727
}
728

    
729
function ldap_get_user_ous($show_complete_ou=true, $authcfg) {
730
	global $debug, $config, $g;
731

    
732
	if(!function_exists("ldap_connect"))
733
		return;
734

    
735
	$ous = array();
736

    
737
	if ($authcfg) {
738
                if (strstr($authcfg['ldap_urltype'], "Standard"))
739
                        $ldapproto = "ldap";
740
                else
741
                        $ldapproto = "ldaps";
742
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
743
                $ldapport           = $authcfg['ldap_port'];
744
                $ldapbasedn         = $authcfg['ldap_basedn'];
745
                $ldapbindun         = $authcfg['ldap_binddn'];
746
                $ldapbindpw         = $authcfg['ldap_bindpw'];
747
                $ldapver            = $authcfg['ldap_protver'];
748
		if (empty($ldapbindun) || empty($ldapbindpw))
749
                        $ldapanon = true;
750
                else
751
                        $ldapanon = false;
752
                $ldapname           = $authcfg['name'];
753
                $ldapfallback       = false;
754
		$ldapscope          = $authcfg['ldap_scope'];
755
        } else
756
		return false;
757

    
758
        /* first check if there is even an LDAP server populated */
759
        if(!$ldapserver) {
760
                log_error("ERROR!  ldap_get_user_ous() backed selected with no LDAP authentication server defined.");
761
                return $ous;
762
        }
763

    
764
	/* Setup CA environment if needed. */
765
	ldap_setup_caenv($authcfg);
766

    
767
	/* connect and see if server is up */
768
        $error = false;
769
        if (empty($ldapport)) {
770
                if (!($ldap = ldap_connect($ldapserver)))
771
                        $error = true;
772
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
773
                $error = true;
774

    
775
        if ($error == true) {
776
		log_error("ERROR!  Could not connect to server {$ldapname}.");
777
                return $ous;
778
        }
779

    
780
	$ldapfilter = "(|(ou=*)(cn=Users))";
781

    
782
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
783
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
784

    
785
	if ($ldapanon == true) {
786
                if (!($res = @ldap_bind($ldap))) {
787
			log_error("ERROR! ldap_get_user_ous() could not bind anonymously to server {$ldapname}.");
788
			@ldap_close($ldap);
789
                        return $ous;
790
		}
791
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
792
		log_error("ERROR! ldap_get_user_ous() could not bind to server {$ldapname}.");
793
		@ldap_close($ldap);
794
		return $ous;
795
	}
796

    
797
	if ($ldapscope == "one")
798
		$ldapfunc = "ldap_list";
799
	else
800
		$ldapfunc = "ldap_search";
801

    
802
	$search = @$ldapfunc($ldap, $ldapbasedn, $ldapfilter);
803
	$info = @ldap_get_entries($ldap, $search);
804

    
805
	if (is_array($info)) {
806
		foreach ($info as $inf) {
807
			if (!$show_complete_ou) {
808
				$inf_split = split(",", $inf['dn']);
809
				$ou = $inf_split[0];
810
				$ou = str_replace("OU=","", $ou);
811
				$ou = str_replace("CN=","", $ou);
812
			} else
813
				if($inf['dn'])
814
					$ou = $inf['dn'];
815
			if($ou)
816
				$ous[] = $ou;
817
		}
818
	}
819

    
820
	@ldap_unbind($ldap);
821

    
822
	return $ous;
823
}
824

    
825
function ldap_get_groups($username, $authcfg) {
826
	global $debug, $config;
827
	
828
	if(!function_exists("ldap_connect"))
829
		return;
830
	
831
	if(!$username) 
832
		return false;
833

    
834
	if(stristr($username, "@")) {
835
		$username_split=split("\@", $username);
836
		$username = $username_split[0];		
837
	}
838

    
839
	if(stristr($username, "\\")) {
840
		$username_split=split("\\", $username);
841
		$username = $username_split[0];        
842
	}    
843
	
844
	//log_error("Getting LDAP groups for {$username}.");
845
        if ($authcfg) {
846
                if (strstr($authcfg['ldap_urltype'], "Standard"))
847
                        $ldapproto = "ldap";
848
                else
849
                        $ldapproto = "ldaps";
850
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
851
                $ldapport           = $authcfg['ldap_port'];
852
                $ldapbasedn         = $authcfg['ldap_basedn'];
853
                $ldapbindun         = $authcfg['ldap_binddn'];
854
                $ldapbindpw         = $authcfg['ldap_bindpw'];
855
                $ldapauthcont       = $authcfg['ldap_authcn'];
856
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
857
                $ldapgroupattribute  = strtolower($authcfg['ldap_attr_member']);
858
                $ldapfilter         = "({$ldapnameattribute}={$username})";
859
                $ldaptype           = "";
860
                $ldapver            = $authcfg['ldap_protver'];
861
		if (empty($ldapbindun) || empty($ldapbindpw))
862
                        $ldapanon = true;
863
                else
864
                        $ldapanon = false;
865
                $ldapname           = $authcfg['name'];
866
                $ldapfallback       = false;
867
		$ldapscope          = $authcfg['ldap_scope'];
868
	} else
869
		return false;
870

    
871
	$ldapdn             = $_SESSION['ldapdn'];
872

    
873
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
874
	$ldapgroupattribute = strtolower($ldapgroupattribute);
875
	$memberof = array();
876

    
877
        /* Setup CA environment if needed. */
878
        ldap_setup_caenv($authcfg);
879

    
880
	/* connect and see if server is up */
881
	$error = false;
882
        if (empty($ldapport)) {
883
                if (!($ldap = ldap_connect($ldapserver)))
884
                        $error = true;
885
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
886
                $error = true;
887

    
888
	if ($error == true) {
889
		log_error("ERROR! ldap_get_groups() Could not connect to server {$ldapname}.");
890
                return memberof;
891
        }
892
    
893
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
894
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
895

    
896
	/* bind as user that has rights to read group attributes */
897
	if ($ldapanon == true) {
898
                if (!($res = @ldap_bind($ldap))) {
899
			log_error("ERROR! ldap_get_groups() could not bind anonymously to server {$ldapname}.");
900
			@ldap_close($ldap);
901
                        return false;
902
		}
903
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
904
		log_error("ERROR! ldap_get_groups() could not bind to server {$ldapname}.");
905
		@ldap_close($ldap);
906
		return memberof;
907
	}
908

    
909
	/* get groups from DN found */
910
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
911
	/* since we know the DN is in $_SESSION['ldapdn'] */
912
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
913
	if ($ldapscope == "one")
914
                $ldapfunc = "ldap_list";
915
        else
916
                $ldapfunc = "ldap_search";
917

    
918
	$search    = @$ldapfunc($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
919
	$info      = @ldap_get_entries($ldap, $search);
920

    
921
	$countem = $info["count"];	
922
	
923
	if(is_array($info[0][$ldapgroupattribute])) {
924
		/* Iterate through the groups and throw them into an array */
925
		foreach ($info[0][$ldapgroupattribute] as $member) {
926
			if (stristr($member, "CN=") !== false) {
927
				$membersplit = split(",", $member);
928
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
929
			}
930
		}
931
	}
932
	
933
	/* Time to close LDAP connection */
934
	@ldap_unbind($ldap);
935
	
936
	$groups = print_r($memberof,true);
937
	
938
	//log_error("Returning groups ".$groups." for user $username");
939
	
940
	return $memberof;
941
}
942

    
943
function ldap_backed($username, $passwd, $authcfg) {
944
	global $debug, $config;
945
	
946
	if(!$username) 
947
		return;
948

    
949
	if(!function_exists("ldap_connect"))
950
		return;
951

    
952
	if(stristr($username, "@")) {
953
		$username_split=split("\@", $username);
954
		$username = $username_split[0];        
955
	}
956
	if(stristr($username, "\\")) {
957
		$username_split=split("\\", $username);
958
		$username = $username_split[0];        
959
	}
960

    
961
	if ($authcfg) {
962
		if (strstr($authcfg['ldap_urltype'], "Standard"))
963
			$ldapproto = "ldap";
964
		else
965
			$ldapproto = "ldaps";
966
		$ldapserver         = "{$ldapproto}://{$authcfg['host']}";
967
		$ldapport	    = $authcfg['ldap_port'];
968
                $ldapbasedn         = $authcfg['ldap_basedn'];
969
                $ldapbindun         = $authcfg['ldap_binddn'];
970
                $ldapbindpw         = $authcfg['ldap_bindpw'];
971
		if (empty($ldapbindun) || empty($ldapbindpw))
972
			$ldapanon = true;
973
		else
974
			$ldapanon = false;
975
                $ldapauthcont       = $authcfg['ldap_authcn'];
976
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
977
                $ldapfilter         = "({$ldapnameattribute}={$username})";
978
                $ldaptype           = "";
979
                $ldapver            = $authcfg['ldap_protver'];
980
		$ldapname	    = $authcfg['name'];
981
		$ldapscope	    = $authcfg['ldap_scope'];
982
	} else
983
		return false;
984

    
985
	/* first check if there is even an LDAP server populated */ 
986
	if(!$ldapserver) {
987
		if ($ldapfallback) {
988
			log_error("ERROR! ldap_backed() called with no LDAP authentication server defined.  Defaulting to local user database. Visit System -> User Manager.");
989
			return local_backed($username, $passwd);
990
		} else
991
			log_error("ERROR! ldap_backed() called with no LDAP authentication server defined.");
992

    
993
		return false;
994
	}
995
	
996
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
997
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
998

    
999
        /* Setup CA environment if needed. */
1000
        ldap_setup_caenv($authcfg);
1001

    
1002
	/* Make sure we can connect to LDAP */
1003
	$error = false;
1004
	if (empty($ldapport)) {
1005
		if (!($ldap = ldap_connect($ldapserver)))
1006
			$error = true;
1007
	} else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
1008
		$error = true;
1009

    
1010
	if ($error == true) {
1011
		log_error("ERROR!  Could not connect to server {$ldapname}.");
1012
		return false;
1013
	}
1014

    
1015
	/* ok, its up.  now, lets bind as the bind user so we can search it */
1016
	$error = false;
1017
	if ($ldapanon == true) {
1018
                if (!($res = @ldap_bind($ldap)))
1019
                        $error = true;
1020
	} else if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
1021
		$error = true;
1022

    
1023
	if ($error == true) {
1024
		@ldap_close($ldap);
1025
		log_error("ERROR! Could not bind to server {$ldapname}.");
1026
		return false;
1027
	}
1028
	
1029
	/* Get LDAP Authcontainers and split em up. */
1030
	$ldac_splits = split(";", $ldapauthcont);
1031
	
1032
	/* setup the usercount so we think we havn't found anyone yet */
1033
	$usercount  = 0;
1034

    
1035
	/*****************************************************************/
1036
	/*  We First find the user based on username and filter          */
1037
	/*  Then, once we find the first occurance of that person        */
1038
	/*  We set seesion variables to ponit to the OU and DN of the    */
1039
	/*  Person.  To later be used by ldap_get_groups.                */
1040
	/*  that way we don't have to search twice.                      */
1041
	/*****************************************************************/
1042
	log_error("Now Searching for {$username} in directory.");
1043
	/* Iterate through the user containers for search */
1044
	foreach ($ldac_splits as $i => $ldac_split) {
1045
		/* Make sure we just use the first user we find */
1046
		log_error("Now Searching in server {$ldapname}, container {$ldac_split} with filter {$ldapfilter}.");
1047
		if ($ldapscope == "one")
1048
			$ldapfunc = "ldap_list";
1049
		else
1050
			$ldapfunc = "ldap_search";
1051
		/* Support legacy auth container specification. */
1052
		if (stristr($ldac_split, "DC=") || empty($ldapbasedn))
1053
			$search	 = @$ldapfunc($ldap,$ldac_split,$ldapfilter);
1054
		else
1055
			$search  = @$ldapfunc($ldap,"{$ldac_split},{$ldapbasedn}",$ldapfilter);
1056
		if (!$search) {
1057
			log_error("Search resulted in error: " . ldap_error($ldap));
1058
			continue;
1059
		}
1060
		$info	 = ldap_get_entries($ldap,$search);
1061
		$matches = $info['count'];
1062
		if ($matches == 1){
1063
			$userdn = $_SESSION['ldapdn'] = $info[0]['dn'];
1064
			$_SESSION['ldapou'] = $ldac_split[$i];
1065
			$_SESSION['ldapon'] = "true";
1066
			$usercount = 1;
1067
			break;
1068
		}
1069
	}
1070

    
1071
	if ($usercount != 1){
1072
		@ldap_unbind($ldap);
1073
		log_error("ERROR! Either LDAP search failed, or multiple users were found.");
1074
		return false;                         
1075
	}
1076

    
1077
	/* Now lets bind as the user we found */
1078
	if (!($res = @ldap_bind($ldap, $userdn, $passwd))) {
1079
		log_error("ERROR! Could not login to server {$ldapname} as user {$username}.");
1080
		@ldap_unbind($ldap);
1081
		return false;
1082
	}
1083

    
1084
	log_error("Logged in successfully as {$username} via LDAP server {$ldapname} with DN = {$userdn}.");
1085

    
1086
	/* At this point we are bound to LDAP so the user was auth'd okay. Close connection. */
1087
	@ldap_unbind($ldap);
1088

    
1089
	return true;
1090
}
1091

    
1092
function radius_backed($username, $passwd, $authcfg){
1093
	global $debug, $config;
1094
	$ret = false;
1095

    
1096
	require_once("radius.inc");
1097

    
1098
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
1099
	if ($authcfg) {
1100
		$radiusservers = array();
1101
		$radiusservers[0]['ipaddr'] = $authcfg['host'];
1102
		$radiusservers[0]['port'] = $authcfg['radius_auth_port'];
1103
		$radiusservers[0]['sharedsecret'] = $authcfg['radius_secret'];
1104
	} else
1105
		return false;
1106

    
1107
	/* Add a new servers to our instance */
1108
	foreach ($radiusservers as $radsrv)
1109
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
1110

    
1111
	if (PEAR::isError($rauth->start())) {
1112
		$retvalue['auth_val'] = 1;
1113
		$retvalue['error'] = $rauth->getError();
1114
		if ($debug)
1115
			printf("Radius start: %s<br>\n", $retvalue['error']);
1116
	}
1117

    
1118
	// XXX - billm - somewhere in here we need to handle securid challenge/response
1119

    
1120
	/* Send request */
1121
	$result = $rauth->send();
1122
	if (PEAR::isError($result)) {
1123
		$retvalue['auth_val'] = 1;
1124
		$retvalue['error'] = $result->getMessage();
1125
		if ($debug)
1126
			printf("Radius send failed: %s<br>\n", $retvalue['error']);
1127
	} else if ($result === true) {
1128
		$retvalue['auth_val'] = 2;
1129
		if ($debug)
1130
			printf(gettext("Radius Auth succeeded")."<br>\n");
1131
		$ret = true;
1132
	} else {
1133
		$retvalue['auth_val'] = 3;
1134
		if ($debug)
1135
			printf(gettext("Radius Auth rejected")."<br>\n");
1136
	}
1137

    
1138
	// close OO RADIUS_AUTHENTICATION
1139
	$rauth->close();
1140

    
1141
	return $ret;
1142
}
1143

    
1144
function get_user_expiration_date($username) {
1145
	$user = getUserEntry($username);
1146
	if ($user['expires']) 
1147
		return $user['expires'];
1148
}
1149

    
1150
function is_account_expired($username) {
1151
	$expirydate = get_user_expiration_date($username);
1152
	if ($expirydate) {
1153
		if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($expirydate))))
1154
			return true;
1155
	}
1156

    
1157
	return false;
1158
}
1159

    
1160
function is_account_disabled($username) {
1161
	$user = getUserEntry($username);
1162
	if (isset($user['disabled']))
1163
		return true;
1164

    
1165
	return false;
1166
}
1167

    
1168
function auth_get_authserver($name) {
1169
        global $config;
1170

    
1171
        if (is_array($config['system']['authserver'])) {
1172
                foreach ($config['system']['authserver'] as $authcfg) {
1173
                        if ($authcfg['name'] == $name)
1174
                                return $authcfg;
1175
                }
1176
        }
1177
	if ($name == "Local Database")
1178
		return array("name" => "Local Database", "type" => "Local Auth", "host" => $config['system']['hostname']);
1179
}
1180

    
1181
function auth_get_authserver_list() {
1182
        global $config;
1183

    
1184
	$list = array();
1185

    
1186
        if (is_array($config['system']['authserver'])) {
1187
                foreach ($config['system']['authserver'] as $authcfg) {
1188
			/* Add support for disabled entries? */
1189
			$list[$authcfg['name']] = $authcfg;
1190
                }
1191
        }
1192

    
1193
	$list["Local Database"] = array( "name" => "Local Database", "type" => "Local Auth", "host" => $config['system']['hostname']);
1194
	return $list;
1195
}
1196

    
1197
function getUserGroups($username, $authcfg) {
1198
	global $config;
1199

    
1200
	$allowed_groups = array();
1201

    
1202
	switch($authcfg['type']) {
1203
        case 'ldap':
1204
		$allowed_groups = @ldap_get_groups($username, $authcfg);
1205
		break;
1206
	case 'radius':
1207
		break;
1208
	default:
1209
		$user = getUserEntry($username);
1210
		$allowed_groups = @local_user_get_groups($user, true);
1211
		break;
1212
	}
1213

    
1214
	$member_groups = array();
1215
        if (is_array($config['system']['group'])) {
1216
                foreach ($config['system']['group'] as $group)
1217
                        if (in_array($group['name'], $allowed_groups))
1218
				$member_groups[] = $group['name'];
1219
	}
1220

    
1221
	return $member_groups;
1222
}
1223

    
1224
function authenticate_user($username, $password, $authcfg = NULL) {
1225

    
1226
	if (!$authcfg) {
1227
		return local_backed($username, $password);
1228
	}
1229

    
1230
	$authenticated = false;
1231
	switch($authcfg['type']) {
1232
        case 'ldap':
1233
                if (ldap_backed($username, $password, $authcfg))
1234
                        $authenticated = true;
1235
                break;
1236
        case 'radius':
1237
                if (radius_backed($username, $password, $authcfg))
1238
                        $authenticated = true;
1239
                break;
1240
        default:
1241
                /* lookup user object by name */
1242
                if (local_backed($username, $password))
1243
                        $authenticated = true;
1244
                break;
1245
        }
1246

    
1247
	return $authenticated;
1248
}
1249

    
1250
function session_auth() {
1251
	global $HTTP_SERVER_VARS, $config, $_SESSION, $page;
1252

    
1253
	session_start();
1254

    
1255
	/* Validate incoming login request */
1256
	if (isset($_POST['login'])) {
1257
		$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
1258
		if (authenticate_user($_POST['usernamefld'], $_POST['passwordfld'], $authcfg) || 
1259
		    authenticate_user($_POST['usernamefld'], $_POST['passwordfld'])) {
1260
			$_SESSION['Logged_In'] = "True";
1261
			$_SESSION['Username'] = $_POST['usernamefld'];
1262
			$_SESSION['last_access'] = time();
1263
			if(! isset($config['system']['webgui']['quietlogin'])) {
1264
				log_auth("Successful webConfigurator login for user '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}");
1265
			}
1266
			$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1267
			if (isset($_POST['postafterlogin']))
1268
				return true;
1269
			else {
1270
				if (empty($page))
1271
					$page = "/";
1272
				header("Location: {$page}");
1273
			}
1274
			exit;
1275
		} else {
1276
			/* give the user an error message */
1277
			$_SESSION['Login_Error'] = "Username or Password incorrect";
1278
			log_auth("webConfigurator authentication error for '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}");
1279
			if(isAjax()) {
1280
				echo "showajaxmessage('{$_SESSION['Login_Error']}');";
1281
				return;
1282
			}
1283
		}
1284
	}
1285

    
1286
	/* Show login page if they aren't logged in */
1287
	if (empty($_SESSION['Logged_In']))
1288
		return false;
1289

    
1290
	/* If session timeout isn't set, we don't mark sessions stale */
1291
	if (!isset($config['system']['webgui']['session_timeout'])) {
1292
		/* Default to 4 hour timeout if one is not set */
1293
		if ($_SESSION['last_access'] < (time() - 14400)) {
1294
			$_GET['logout'] = true;
1295
			$_SESSION['Logout'] = true;
1296
		} else
1297
			$_SESSION['last_access'] = time();	
1298
	} else if (intval($config['system']['webgui']['session_timeout']) == 0) {
1299
		/* only update if it wasn't ajax */
1300
		if (!isAjax())
1301
			$_SESSION['last_access'] = time();
1302
	} else {
1303
		/* Check for stale session */
1304
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
1305
			$_GET['logout'] = true;
1306
			$_SESSION['Logout'] = true;
1307
		} else {
1308
			/* only update if it wasn't ajax */
1309
			if (!isAjax())
1310
				$_SESSION['last_access'] = time();
1311
		}
1312
	}
1313

    
1314
	/* user hit the logout button */
1315
	if (isset($_GET['logout'])) {
1316

    
1317
		if ($_SESSION['Logout'])
1318
			log_error("Session timed out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
1319
		else
1320
			log_error("User logged out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
1321

    
1322
		/* wipe out $_SESSION */
1323
		$_SESSION = array();
1324

    
1325
		if (isset($_COOKIE[session_name()]))
1326
			setcookie(session_name(), '', time()-42000, '/');
1327

    
1328
		/* and destroy it */
1329
		session_destroy();
1330

    
1331
		$scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
1332
		$scriptElms = count($scriptName);
1333
		$scriptName = $scriptName[$scriptElms-1];
1334

    
1335
		if (isAjax())
1336
			return false;
1337

    
1338
		/* redirect to page the user is on, it'll prompt them to login again */
1339
		Header("Location: {$scriptName}");
1340

    
1341
		return false;
1342
	}
1343

    
1344
	/*
1345
	 * this is for debugging purpose if you do not want to use Ajax
1346
	 * to submit a HTML form. It basically diables the observation
1347
	 * of the submit event and hence does not trigger Ajax.
1348
	 */
1349
	if ($_GET['disable_ajax'])
1350
		$_SESSION['NO_AJAX'] = "True";
1351

    
1352
	/*
1353
	 * Same to re-enable Ajax.
1354
	 */
1355
	if ($_GET['enable_ajax'])
1356
		unset($_SESSION['NO_AJAX']);
1357

    
1358
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1359
	return true;
1360
}
1361

    
1362
?>
(4-4/61)