Project

General

Profile

Feature #1009 » auth.inc

Included logic to query for extended parameters Query: (&(_ORIGINAL_)(New)) - Andy I., 08/27/2011 04:38 AM

 
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
        /* connect and see if server is up */
624
        putenv('LDAPTLS_REQCERT=never');
625
        $error = false;
626
        if (empty($ldapport)) {
627
                if (!($ldap = ldap_connect($ldapserver)))
628
                        $error = true;
629
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
630
                $error = true;
631

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

    
637
	return true;
638
}
639

    
640
function ldap_test_bind($authcfg) {
641
	global $debug, $config, $g;
642

    
643
	if ($authcfg) {
644
                if (strstr($authcfg['ldap_urltype'], "Standard"))
645
                        $ldapproto = "ldap";
646
                else
647
                        $ldapproto = "ldaps";
648
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
649
                $ldapport           = $authcfg['ldap_port'];
650
                $ldapbasedn         = $authcfg['ldap_basedn'];
651
                $ldapbindun         = $authcfg['ldap_binddn'];
652
                $ldapbindpw         = $authcfg['ldap_bindpw'];
653
                $ldapver            = $authcfg['ldap_protver'];
654
		if (empty($ldapbndun) || empty($ldapbindpw))
655
                        $ldapanon = true;
656
                else
657
                        $ldapanon = false;
658
	} else
659
		return false;
660

    
661
	/* first check if there is even an LDAP server populated */
662
        if(!$ldapserver)
663
                return false;
664

    
665
        /* connect and see if server is up */
666
        putenv('LDAPTLS_REQCERT=never');
667
        $error = false;
668
        if (empty($ldapport)) {
669
                if (!($ldap = ldap_connect($ldapserver)))
670
                        $error = true;
671
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
672
                $error = true;
673

    
674
        if ($error == true) {
675
                log_error("ERROR!  Could not connect to server {$ldapname}.");
676
                return false;
677
        }
678

    
679
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
680
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
681
 
682
	if ($ldapanon == true) {
683
		if (!($res = @ldap_bind($ldap))) {
684
			@ldap_close($ldap);
685
			return false;
686
		}
687
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
688
		@ldap_close($ldap);
689
		return false;
690
	}
691

    
692
	@ldap_unbind($ldap);
693

    
694
	return true;
695
}
696

    
697
function ldap_get_user_ous($show_complete_ou=true, $authcfg) {
698
	global $debug, $config, $g;
699

    
700
	if(!function_exists("ldap_connect"))
701
		return;
702

    
703
	$ous = array();
704

    
705
	if ($authcfg) {
706
                if (strstr($authcfg['ldap_urltype'], "Standard"))
707
                        $ldapproto = "ldap";
708
                else
709
                        $ldapproto = "ldaps";
710
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
711
                $ldapport           = $authcfg['ldap_port'];
712
                $ldapbasedn         = $authcfg['ldap_basedn'];
713
                $ldapbindun         = $authcfg['ldap_binddn'];
714
                $ldapbindpw         = $authcfg['ldap_bindpw'];
715
                $ldapver            = $authcfg['ldap_protver'];
716
		if (empty($ldapbindun) || empty($ldapbindpw))
717
                        $ldapanon = true;
718
                else
719
                        $ldapanon = false;
720
                $ldapname           = $authcfg['name'];
721
                $ldapfallback       = false;
722
		$ldapscope          = $authcfg['ldap_scope'];
723
        } else
724
		return false;
725

    
726
        /* first check if there is even an LDAP server populated */
727
        if(!$ldapserver) {
728
                log_error("ERROR!  ldap_get_user_ous() backed selected with no LDAP authentication server defined.");
729
                return $ous;
730
        }
731

    
732
	/* connect and see if server is up */
733
        putenv('LDAPTLS_REQCERT=never');
734
        $error = false;
735
        if (empty($ldapport)) {
736
                if (!($ldap = ldap_connect($ldapserver)))
737
                        $error = true;
738
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
739
                $error = true;
740

    
741
        if ($error == true) {
742
		log_error("ERROR!  Could not connect to server {$ldapname}.");
743
                return $ous;
744
        }
745

    
746
	$ldapfilter = "(|(ou=*)(cn=Users))";
747

    
748
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
749
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
750

    
751
	if ($ldapanon == true) {
752
                if (!($res = @ldap_bind($ldap))) {
753
			log_error("ERROR! ldap_get_user_ous() could not bind anonymously to server {$ldapname}.");
754
			@ldap_close($ldap);
755
                        return $ous;
756
		}
757
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
758
		log_error("ERROR! ldap_get_user_ous() could not bind to server {$ldapname}.");
759
		@ldap_close($ldap);
760
		return $ous;
761
	}
762

    
763
	if ($ldapscope == "one")
764
		$ldapfunc = "ldap_list";
765
	else
766
		$ldapfunc = "ldap_search";
767

    
768
	$search = @$ldapfunc($ldap, $ldapbasedn, $ldapfilter);
769
	$info = @ldap_get_entries($ldap, $search);
770

    
771
	if (is_array($info)) {
772
		foreach ($info as $inf) {
773
			if (!$show_complete_ou) {
774
				$inf_split = split(",", $inf['dn']);
775
				$ou = $inf_split[0];
776
				$ou = str_replace("OU=","", $ou);
777
				$ou = str_replace("CN=","", $ou);
778
			} else
779
				if($inf['dn'])
780
					$ou = $inf['dn'];
781
			if($ou)
782
				$ous[] = $ou;
783
		}
784
	}
785

    
786
	@ldap_unbind($ldap);
787

    
788
	return $ous;
789
}
790

    
791
function ldap_get_groups($username, $authcfg) {
792
	global $debug, $config;
793
	
794
	if(!function_exists("ldap_connect"))
795
		return;
796
	
797
	if(!$username) 
798
		return false;
799

    
800
	if(stristr($username, "@")) {
801
		$username_split=split("\@", $username);
802
		$username = $username_split[0];		
803
	}
804

    
805
	if(stristr($username, "\\")) {
806
		$username_split=split("\\", $username);
807
		$username = $username_split[0];        
808
	}    
809
	
810
	//log_error("Getting LDAP groups for {$username}.");
811
        if ($authcfg) {
812
                if (strstr($authcfg['ldap_urltype'], "Standard"))
813
                        $ldapproto = "ldap";
814
                else
815
                        $ldapproto = "ldaps";
816
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
817
                $ldapport           = $authcfg['ldap_port'];
818
                $ldapbasedn         = $authcfg['ldap_basedn'];
819
                $ldapbindun         = $authcfg['ldap_binddn'];
820
                $ldapbindpw         = $authcfg['ldap_bindpw'];
821
                $ldapauthcont       = $authcfg['ldap_authcn'];
822
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
823
                $ldapgroupattribute  = strtolower($authcfg['ldap_attr_member']);
824
                $ldapfilter         = "({$ldapnameattribute}={$username})";
825
                $ldaptype           = "";
826
                $ldapver            = $authcfg['ldap_protver'];
827
		if (empty($ldapbindun) || empty($ldapbindpw))
828
                        $ldapanon = true;
829
                else
830
                        $ldapanon = false;
831
                $ldapname           = $authcfg['name'];
832
                $ldapfallback       = false;
833
		$ldapscope          = $authcfg['ldap_scope'];
834
	} else
835
		return false;
836

    
837
	$ldapdn             = $_SESSION['ldapdn'];
838

    
839
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
840
	$ldapgroupattribute = strtolower($ldapgroupattribute);
841
	$memberof = array();
842

    
843
	/* connect and see if server is up */
844
	putenv('LDAPTLS_REQCERT=never');
845
	$error = false;
846
        if (empty($ldapport)) {
847
                if (!($ldap = ldap_connect($ldapserver)))
848
                        $error = true;
849
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
850
                $error = true;
851

    
852
	if ($error == true) {
853
		log_error("ERROR! ldap_get_groups() Could not connect to server {$ldapname}.");
854
                return memberof;
855
        }
856
    
857
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
858
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
859

    
860
	/* bind as user that has rights to read group attributes */
861
	if ($ldapanon == true) {
862
                if (!($res = @ldap_bind($ldap))) {
863
			log_error("ERROR! ldap_get_groups() could not bind anonymously to server {$ldapname}.");
864
			@ldap_close($ldap);
865
                        return false;
866
		}
867
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
868
		log_error("ERROR! ldap_get_groups() could not bind to server {$ldapname}.");
869
		@ldap_close($ldap);
870
		return memberof;
871
	}
872

    
873
	/* get groups from DN found */
874
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
875
	/* since we know the DN is in $_SESSION['ldapdn'] */
876
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
877
	if ($ldapscope == "one")
878
                $ldapfunc = "ldap_list";
879
        else
880
                $ldapfunc = "ldap_search";
881

    
882
	$search    = @$ldapfunc($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
883
	$info      = @ldap_get_entries($ldap, $search);
884

    
885
	$countem = $info["count"];	
886
	
887
	if(is_array($info[0][$ldapgroupattribute])) {
888
		/* Iterate through the groups and throw them into an array */
889
		foreach ($info[0][$ldapgroupattribute] as $member) {
890
			if (stristr($member, "CN=") !== false) {
891
				$membersplit = split(",", $member);
892
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
893
			}
894
		}
895
	}
896
	
897
	/* Time to close LDAP connection */
898
	@ldap_unbind($ldap);
899
	
900
	$groups = print_r($memberof,true);
901
	
902
	//log_error("Returning groups ".$groups." for user $username");
903
	
904
	return $memberof;
905
}
906

    
907
function ldap_backed($username, $passwd, $authcfg) {
908
	global $debug, $config;
909
	
910
	if(!$username) 
911
		return;
912

    
913
	if(!function_exists("ldap_connect"))
914
		return;
915

    
916
	if(stristr($username, "@")) {
917
		$username_split=split("\@", $username);
918
		$username = $username_split[0];        
919
	}
920
	if(stristr($username, "\\")) {
921
		$username_split=split("\\", $username);
922
		$username = $username_split[0];        
923
	}
924

    
925
	if ($authcfg) {
926
		if (strstr($authcfg['ldap_urltype'], "Standard"))
927
			$ldapproto = "ldap";
928
		else
929
			$ldapproto = "ldaps";
930
		$ldapserver         = "{$ldapproto}://{$authcfg['host']}";
931
		$ldapport	    = $authcfg['ldap_port'];
932
                $ldapbasedn         = $authcfg['ldap_basedn'];
933
                $ldapbindun         = $authcfg['ldap_binddn'];
934
                $ldapbindpw         = $authcfg['ldap_bindpw'];
935
		if (empty($ldapbindun) || empty($ldapbindpw))
936
			$ldapanon = true;
937
		else
938
			$ldapanon = false;
939
                $ldapauthcont       = $authcfg['ldap_authcn'];
940
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
941
                $ldapextendedqueryenabled  = $authcfg['ldap_extended_enabled'];
942
                $ldapextendedquery = $authcfg['ldap_extended_query'];
943
                $ldapfilter = "";
944
                if(!$ldapextendedqueryenabled)
945
                {
946
                        $ldapfilter = "({$ldapnameattribute}={$username})";
947
                }
948
                else
949
                {
950
                        $ldapfilter = 
951
"(&({$ldapnameattribute}={$username})({$ldapextendedquery}))";
952
                } 
953
               $ldaptype           = "";
954
                $ldapver            = $authcfg['ldap_protver'];
955
		$ldapname	    = $authcfg['name'];
956
		$ldapscope	    = $authcfg['ldap_scope'];
957
	} else
958
		return false;
959

    
960
	/* first check if there is even an LDAP server populated */ 
961
	if(!$ldapserver) {
962
		if ($ldapfallback) {
963
			log_error("ERROR! ldap_backed() called with no LDAP authentication server defined.  Defaulting to local user database. Visit System -> User Manager.");
964
			return local_backed($username, $passwd);
965
		} else
966
			log_error("ERROR! ldap_backed() called with no LDAP authentication server defined.");
967

    
968
		return false;
969
	}
970
	
971
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
972
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
973

    
974
	/* Make sure we can connect to LDAP */
975
	putenv('LDAPTLS_REQCERT=never');
976
	$error = false;
977
	if (empty($ldapport)) {
978
		if (!($ldap = ldap_connect($ldapserver)))
979
			$error = true;
980
	} else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
981
		$error = true;
982

    
983
	if ($error == true) {
984
		log_error("ERROR!  Could not connect to server {$ldapname}.");
985
		return false;
986
	}
987

    
988
	/* ok, its up.  now, lets bind as the bind user so we can search it */
989
	$error = false;
990
	if ($ldapanon == true) {
991
                if (!($res = @ldap_bind($ldap)))
992
                        $error = true;
993
	} else if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
994
		$error = true;
995

    
996
	if ($error == true) {
997
		@ldap_close($ldap);
998
		log_error("ERROR! Could not bind to server {$ldapname}.");
999
		return false;
1000
	}
1001
	
1002
	/* Get LDAP Authcontainers and split em up. */
1003
	$ldac_splits = split(";", $ldapauthcont);
1004
	
1005
	/* setup the usercount so we think we havn't found anyone yet */
1006
	$usercount  = 0;
1007

    
1008
	/*****************************************************************/
1009
	/*  We First find the user based on username and filter          */
1010
	/*  Then, once we find the first occurance of that person        */
1011
	/*  We set seesion variables to ponit to the OU and DN of the    */
1012
	/*  Person.  To later be used by ldap_get_groups.                */
1013
	/*  that way we don't have to search twice.                      */
1014
	/*****************************************************************/
1015
	log_error("Now Searching for {$username} in directory.");
1016
	/* Iterate through the user containers for search */
1017
	foreach ($ldac_splits as $i => $ldac_split) {
1018
		/* Make sure we just use the first user we find */
1019
		log_error("Now Searching in server {$ldapname}, container {$ldac_split} with filter {$ldapfilter}.");
1020
		if ($ldapscope == "one")
1021
			$ldapfunc = "ldap_list";
1022
		else
1023
			$ldapfunc = "ldap_search";
1024
		/* Support legacy auth container specification. */
1025
		if (stristr($ldac_split, "DC=") || empty($ldapbasedn))
1026
			$search	 = @$ldapfunc($ldap,$ldac_split,$ldapfilter);
1027
		else
1028
			$search  = @$ldapfunc($ldap,"{$ldac_split},{$ldapbasedn}",$ldapfilter);
1029
		if (!$search) {
1030
			log_error("Search resulted in error: " . ldap_error($ldap));
1031
			continue;
1032
		}
1033
		$info	 = ldap_get_entries($ldap,$search);
1034
		$matches = $info['count'];
1035
		if ($matches == 1){
1036
			$userdn = $_SESSION['ldapdn'] = $info[0]['dn'];
1037
			$_SESSION['ldapou'] = $ldac_split[$i];
1038
			$_SESSION['ldapon'] = "true";
1039
			$usercount = 1;
1040
			break;
1041
		}
1042
	}
1043

    
1044
	if ($usercount != 1){
1045
		@ldap_unbind($ldap);
1046
		log_error("ERROR! Either LDAP search failed, or multiple users were found.");
1047
		return false;                         
1048
	}
1049

    
1050
	/* Now lets bind as the user we found */
1051
	if (!($res = @ldap_bind($ldap, $userdn, $passwd))) {
1052
		log_error("ERROR! Could not login to server {$ldapname} as user {$username}.");
1053
		@ldap_unbind($ldap);
1054
		return false;
1055
	}
1056

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

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

    
1062
	return true;
1063
}
1064

    
1065
function radius_backed($username, $passwd, $authcfg){
1066
	global $debug, $config;
1067
	$ret = false;
1068

    
1069
	require_once("radius.inc");
1070

    
1071
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
1072
	if ($authcfg) {
1073
		$radiusservers = array();
1074
		$radiusservers[0]['ipaddr'] = $authcfg['host'];
1075
		$radiusservers[0]['port'] = $authcfg['radius_auth_port'];
1076
		$radiusservers[0]['sharedsecret'] = $authcfg['radius_secret'];
1077
	} else
1078
		return false;
1079

    
1080
	/* Add a new servers to our instance */
1081
	foreach ($radiusservers as $radsrv)
1082
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
1083

    
1084
	if (PEAR::isError($rauth->start())) {
1085
		$retvalue['auth_val'] = 1;
1086
		$retvalue['error'] = $rauth->getError();
1087
		if ($debug)
1088
			printf("Radius start: %s<br>\n", $retvalue['error']);
1089
	}
1090

    
1091
	// XXX - billm - somewhere in here we need to handle securid challenge/response
1092

    
1093
	/* Send request */
1094
	$result = $rauth->send();
1095
	if (PEAR::isError($result)) {
1096
		$retvalue['auth_val'] = 1;
1097
		$retvalue['error'] = $result->getMessage();
1098
		if ($debug)
1099
			printf("Radius send failed: %s<br>\n", $retvalue['error']);
1100
	} else if ($result === true) {
1101
		$retvalue['auth_val'] = 2;
1102
		if ($debug)
1103
			printf(gettext("Radius Auth succeeded")."<br>\n");
1104
		$ret = true;
1105
	} else {
1106
		$retvalue['auth_val'] = 3;
1107
		if ($debug)
1108
			printf(gettext("Radius Auth rejected")."<br>\n");
1109
	}
1110

    
1111
	// close OO RADIUS_AUTHENTICATION
1112
	$rauth->close();
1113

    
1114
	return $ret;
1115
}
1116

    
1117
function get_user_expiration_date($username) {
1118
	$user = getUserEntry($username);
1119
	if ($user['expires']) 
1120
		return $user['expires'];
1121
}
1122

    
1123
function is_account_expired($username) {
1124
	$expirydate = get_user_expiration_date($username);
1125
	if ($expirydate) {
1126
		if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($expirydate))))
1127
			return true;
1128
	}
1129

    
1130
	return false;
1131
}
1132

    
1133
function is_account_disabled($username) {
1134
	$user = getUserEntry($username);
1135
	if (isset($user['disabled']))
1136
		return true;
1137

    
1138
	return false;
1139
}
1140

    
1141
function auth_get_authserver($name) {
1142
        global $config;
1143

    
1144
        if (is_array($config['system']['authserver'])) {
1145
                foreach ($config['system']['authserver'] as $authcfg) {
1146
                        if ($authcfg['name'] == $name)
1147
                                return $authcfg;
1148
                }
1149
        }
1150
	if ($name == "Local Database")
1151
		return array("name" => "Local Database", "type" => "Local Auth", "host" => $config['system']['hostname']);
1152
}
1153

    
1154
function auth_get_authserver_list() {
1155
        global $config;
1156

    
1157
	$list = array();
1158

    
1159
        if (is_array($config['system']['authserver'])) {
1160
                foreach ($config['system']['authserver'] as $authcfg) {
1161
			/* Add support for disabled entries? */
1162
			$list[$authcfg['name']] = $authcfg;
1163
                }
1164
        }
1165

    
1166
	$list["Local Database"] = array( "name" => "Local Database", "type" => "Local Auth", "host" => $config['system']['hostname']);
1167
	return $list;
1168
}
1169

    
1170
function getUserGroups($username, $authcfg) {
1171
	global $config;
1172

    
1173
	$allowed_groups = array();
1174

    
1175
	switch($authcfg['type']) {
1176
        case 'ldap':
1177
		$allowed_groups = @ldap_get_groups($username, $authcfg);
1178
		break;
1179
	case 'radius':
1180
		break;
1181
	default:
1182
		$user = getUserEntry($username);
1183
		$allowed_groups = @local_user_get_groups($user, true);
1184
		break;
1185
	}
1186

    
1187
	$member_groups = array();
1188
        if (is_array($config['system']['group'])) {
1189
                foreach ($config['system']['group'] as $group)
1190
                        if (in_array($group['name'], $allowed_groups))
1191
				$member_groups[] = $group['name'];
1192
	}
1193

    
1194
	return $member_groups;
1195
}
1196

    
1197
function authenticate_user($username, $password, $authcfg = NULL) {
1198

    
1199
	if (!$authcfg) {
1200
		return local_backed($username, $password);
1201
	}
1202

    
1203
	$authenticated = false;
1204
	switch($authcfg['type']) {
1205
        case 'ldap':
1206
                if (ldap_backed($username, $password, $authcfg))
1207
                        $authenticated = true;
1208
                break;
1209
        case 'radius':
1210
                if (radius_backed($username, $password, $authcfg))
1211
                        $authenticated = true;
1212
                break;
1213
        default:
1214
                /* lookup user object by name */
1215
                if (local_backed($username, $password))
1216
                        $authenticated = true;
1217
                break;
1218
        }
1219

    
1220
	return $authenticated;
1221
}
1222

    
1223
function session_auth() {
1224
	global $HTTP_SERVER_VARS, $config, $_SESSION, $page;
1225

    
1226
	session_start();
1227

    
1228
	/* Validate incoming login request */
1229
	if (isset($_POST['login'])) {
1230
		$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
1231
		if (authenticate_user($_POST['usernamefld'], $_POST['passwordfld'], $authcfg) || 
1232
		    authenticate_user($_POST['usernamefld'], $_POST['passwordfld'])) {
1233
			$_SESSION['Logged_In'] = "True";
1234
			$_SESSION['Username'] = $_POST['usernamefld'];
1235
			$_SESSION['last_access'] = time();
1236
			if(! isset($config['system']['webgui']['quietlogin'])) {
1237
				log_auth("Successful webConfigurator login for user '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}");
1238
			}
1239
			$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1240
			if (isset($_POST['postafterlogin']))
1241
				return true;
1242
			else {
1243
				if (empty($page))
1244
					$page = "/";
1245
				header("Location: {$page}");
1246
			}
1247
			exit;
1248
		} else {
1249
			/* give the user an error message */
1250
			$_SESSION['Login_Error'] = "Username or Password incorrect";
1251
			log_auth("webConfigurator authentication error for '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}");
1252
			if(isAjax()) {
1253
				echo "showajaxmessage('{$_SESSION['Login_Error']}');";
1254
				return;
1255
			}
1256
		}
1257
	}
1258

    
1259
	/* Show login page if they aren't logged in */
1260
	if (empty($_SESSION['Logged_In']))
1261
		return false;
1262

    
1263
	/* If session timeout isn't set, we don't mark sessions stale */
1264
	if (!isset($config['system']['webgui']['session_timeout'])) {
1265
		/* Default to 4 hour timeout if one is not set */
1266
		if ($_SESSION['last_access'] < (time() - 14400)) {
1267
			$_GET['logout'] = true;
1268
			$_SESSION['Logout'] = true;
1269
		} else
1270
			$_SESSION['last_access'] = time();	
1271
	} else if (intval($config['system']['webgui']['session_timeout']) == 0) {
1272
		/* only update if it wasn't ajax */
1273
		if (!isAjax())
1274
			$_SESSION['last_access'] = time();
1275
	} else {
1276
		/* Check for stale session */
1277
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
1278
			$_GET['logout'] = true;
1279
			$_SESSION['Logout'] = true;
1280
		} else {
1281
			/* only update if it wasn't ajax */
1282
			if (!isAjax())
1283
				$_SESSION['last_access'] = time();
1284
		}
1285
	}
1286

    
1287
	/* user hit the logout button */
1288
	if (isset($_GET['logout'])) {
1289

    
1290
		if ($_SESSION['Logout'])
1291
			log_error("Session timed out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
1292
		else
1293
			log_error("User logged out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
1294

    
1295
		/* wipe out $_SESSION */
1296
		$_SESSION = array();
1297

    
1298
		if (isset($_COOKIE[session_name()]))
1299
			setcookie(session_name(), '', time()-42000, '/');
1300

    
1301
		/* and destroy it */
1302
		session_destroy();
1303

    
1304
		$scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
1305
		$scriptElms = count($scriptName);
1306
		$scriptName = $scriptName[$scriptElms-1];
1307

    
1308
		if (isAjax())
1309
			return false;
1310

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

    
1314
		return false;
1315
	}
1316

    
1317
	/*
1318
	 * this is for debugging purpose if you do not want to use Ajax
1319
	 * to submit a HTML form. It basically diables the observation
1320
	 * of the submit event and hence does not trigger Ajax.
1321
	 */
1322
	if ($_GET['disable_ajax'])
1323
		$_SESSION['NO_AJAX'] = "True";
1324

    
1325
	/*
1326
	 * Same to re-enable Ajax.
1327
	 */
1328
	if ($_GET['enable_ajax'])
1329
		unset($_SESSION['NO_AJAX']);
1330

    
1331
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1332
	return true;
1333
}
1334

    
1335
?>
(2-2/4)