Project

General

Profile

Download (41.5 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

    
61
	/* Either a IPv6 address with or without a alternate port */
62
	if(strstr($_SERVER['HTTP_HOST'], "]")) {
63
		$http_host_port = explode("]", $_SERVER['HTTP_HOST']);
64
		/* v6 address has more parts, drop the last part */
65
		if(count($http_host_port) > 1) {
66
			array_pop($http_host_port);
67
			$http_host = str_replace(array("[", "]"), "", implode(":", $http_host_port));
68
		} else {
69
			$http_host = str_replace(array("[", "]"), "", implode(":", $http_host_port));
70
		}
71
	} else {
72
		$http_host = explode(":", $_SERVER['HTTP_HOST']);
73
		$http_host = $http_host[0];
74
	}
75
	if(is_ipaddr($http_host) or $_SERVER['SERVER_ADDR'] == "127.0.0.1" or
76
			strcasecmp($http_host, "localhost") == 0 or $_SERVER['SERVER_ADDR'] == "::1")
77
		$found_host = true;
78
	if(strcasecmp($http_host, $config['system']['hostname'] . "." . $config['system']['domain']) == 0 or
79
			strcasecmp($http_host, $config['system']['hostname']) == 0)
80
		$found_host = true;
81

    
82
	if(is_array($config['dyndnses']['dyndns']) && !$found_host)
83
		foreach($config['dyndnses']['dyndns'] as $dyndns)
84
			if(strcasecmp($dyndns['host'], $http_host) == 0) {
85
				$found_host = true;
86
				break;
87
			}
88

    
89
	if(!empty($config['system']['webgui']['althostnames']) && !$found_host) {
90
		$althosts = explode(" ", $config['system']['webgui']['althostnames']);
91
		foreach ($althosts as $ah)
92
			if(strcasecmp($ah, $http_host) == 0 or strcasecmp($ah, $_SERVER['SERVER_ADDR']) == 0) {
93
				$found_host = true;
94
				break;
95
			}
96
	}
97

    
98
	if($found_host == false) {
99
		if(!security_checks_disabled()) {
100
			display_error_form("501", gettext("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."));
101
			exit;
102
		}
103
		$security_passed = false;
104
	}
105
}
106

    
107
// If the HTTP_REFERER is something other than ourselves then disallow.
108
if(function_exists("display_error_form") && !isset($config['system']['webgui']['nohttpreferercheck'])) {
109
	if($_SERVER['HTTP_REFERER']) {
110
		if(file_exists("{$g['tmp_path']}/setupwizard_lastreferrer")) {
111
			if($_SERVER['HTTP_REFERER'] == file_get_contents("{$g['tmp_path']}/setupwizard_lastreferrer")) {
112
				unlink("{$g['tmp_path']}/setupwizard_lastreferrer");
113
				header("Refresh: 1; url=index.php");
114
				echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
115
				echo "<html><head><title>" . gettext("Redirecting...") . "</title></head><body>" . gettext("Redirecting to the dashboard...") . "</body></html>";
116
				exit;
117
			}
118
		}
119
		$found_host = false;
120
		$referrer_host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
121
		$referrer_host = str_replace(array("[", "]"), "", $referrer_host);
122
		if($referrer_host) {
123
			if(strcasecmp($referrer_host, $config['system']['hostname'] . "." . $config['system']['domain']) == 0
124
					|| strcasecmp($referrer_host, $config['system']['hostname']) == 0)
125
				$found_host = true;
126
			if(!empty($config['system']['webgui']['althostnames']) && !$found_host) {
127
				$althosts = explode(" ", $config['system']['webgui']['althostnames']);
128
				foreach ($althosts as $ah) {
129
					if(strcasecmp($referrer_host, $ah) == 0) {
130
						$found_host = true;
131
						break;
132
					}
133
				}
134
			}
135
			if(!$found_host) {
136
				$interface_list_ips = get_configured_ip_addresses();
137
				foreach($interface_list_ips as $ilips) {
138
					if(strcasecmp($referrer_host, $ilips) == 0) {
139
						$found_host = true;
140
						break;
141
					}
142
				}
143
				$interface_list_ipv6s = get_configured_ipv6_addresses();
144
				foreach($interface_list_ipv6s as $ilipv6s) {
145
					if(strcasecmp($referrer_host, $ilipv6s) == 0) {
146
						$found_host = true;
147
						break;
148
					}
149
				}
150
				if($referrer_host == "127.0.0.1" || $referrer_host == "localhost") {
151
					// allow SSH port forwarded connections and links from localhost
152
					$found_host = true;
153
				}
154
			}
155
		}
156
		if($found_host == false) {
157
			if(!security_checks_disabled()) {
158
				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.");
159
				exit;
160
			}
161
			$security_passed = false;
162
		}
163
	} else
164
		$security_passed = false;
165
}
166

    
167
if (function_exists("display_error_form") && $security_passed)
168
	/* Security checks passed, so it should be OK to turn them back on */
169
	restore_security_checks();
170
unset($security_passed);
171

    
172
$groupindex = index_groups();
173
$userindex = index_users();
174

    
175
function index_groups() {
176
	global $g, $debug, $config, $groupindex;
177

    
178
	$groupindex = array();
179

    
180
	if (is_array($config['system']['group'])) {
181
		$i = 0;
182
		foreach($config['system']['group'] as $groupent) {
183
			$groupindex[$groupent['name']] = $i;
184
			$i++;
185
		}
186
	}
187

    
188
	return ($groupindex);
189
}
190

    
191
function index_users() {
192
	global $g, $debug, $config;
193

    
194
	if (is_array($config['system']['user'])) {
195
		$i = 0;
196
		foreach($config['system']['user'] as $userent) {
197
			$userindex[$userent['name']] = $i;
198
			$i++;
199
		}
200
	}
201

    
202
	return ($userindex);
203
}
204

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

    
211
function & getUserEntryByUID($uid) {
212
	global $debug, $config;
213

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

    
219
	return false;
220
}
221

    
222
function & getGroupEntry($name) {
223
	global $debug, $config, $groupindex;
224
	if (isset($groupindex[$name]))
225
		return $config['system']['group'][$groupindex[$name]];
226
}
227

    
228
function & getGroupEntryByGID($gid) {
229
	global $debug, $config;
230

    
231
	if (is_array($config['system']['group']))
232
		foreach ($config['system']['group'] as & $group)
233
			if ($group['gid'] == $gid)
234
				return $group;
235

    
236
	return false;
237
}
238

    
239
function get_user_privileges(& $user) {
240

    
241
        $privs = $user['priv'];
242
        if (!is_array($privs))
243
                $privs = array();
244

    
245
        $names = local_user_get_groups($user, true);
246

    
247
        foreach ($names as $name) {
248
                $group = getGroupEntry($name);
249
                if (is_array($group['priv']))
250
                        $privs = array_merge( $privs, $group['priv']);
251
        }
252

    
253
        return $privs;
254
}
255

    
256
function userHasPrivilege($userent, $privid = false) {
257

    
258
        if (!$privid || !is_array($userent))
259
                return false;
260

    
261
        $privs = get_user_privileges($userent);
262

    
263
        if (!is_array($privs))
264
                return false;
265

    
266
        if (!in_array($privid, $privs))
267
                return false;
268

    
269
        return true;
270
}
271

    
272
function local_backed($username, $passwd) {
273

    
274
	$user = getUserEntry($username);
275
	if (!$user)
276
		return false;
277

    
278
	if (is_account_disabled($username) || is_account_expired($username))
279
		return false;
280

    
281
	if ($user['password'])
282
	{
283
		$passwd = crypt($passwd, $user['password']);
284
		if ($passwd == $user['password'])
285
			return true;
286
	}
287

    
288
	if ($user['md5-hash'])
289
	{
290
		$passwd = md5($passwd);
291
		if ($passwd == $user['md5-hash'])
292
			return true;
293
	}
294

    
295
	return false;
296
}
297

    
298
function local_sync_accounts() {
299
	global $debug, $config;
300
	conf_mount_rw();
301

    
302
	/* remove local users to avoid uid conflicts */
303
	$fd = popen("/usr/sbin/pw usershow -a", "r");
304
	if ($fd) {
305
		while (!feof($fd)) {
306
			$line = explode(":",fgets($fd));
307
			if (!strncmp($line[0], "_", 1))
308
				continue;
309
			if ($line[2] < 2000)
310
				continue;
311
			if ($line[2] > 65000)
312
				continue;
313
			$cmd = "/usr/sbin/pw userdel {$line[2]}";
314
			if($debug)
315
				log_error(sprintf(gettext("Running: %s"), $cmd));
316
			mwexec($cmd);
317
		}
318
		pclose($fd);
319
	}
320

    
321
	/* remove local groups to avoid gid conflicts */
322
	$gids = array();
323
	$fd = popen("/usr/sbin/pw groupshow -a", "r");
324
	if ($fd) {
325
		while (!feof($fd)) {
326
			$line = explode(":",fgets($fd));
327
			if (!strncmp($line[0], "_", 1))
328
				continue;
329
			if ($line[2] < 2000)
330
				continue;
331
			if ($line[2] > 65000)
332
				continue;
333
			$cmd = "/usr/sbin/pw groupdel {$line[2]}";
334
			if($debug)
335
				log_error(sprintf(gettext("Running: %s"), $cmd));
336
			mwexec($cmd);
337
		}
338
		pclose($fd);
339
	}
340

    
341
	/* make sure the all group exists */
342
	$allgrp = getGroupEntryByGID(1998);
343
	local_group_set($allgrp, true);
344

    
345
	/* sync all local users */
346
	if (is_array($config['system']['user']))
347
		foreach ($config['system']['user'] as $user)
348
			local_user_set($user);
349

    
350
	/* sync all local groups */
351
	if (is_array($config['system']['group']))
352
		foreach ($config['system']['group'] as $group)
353
			local_group_set($group);
354

    
355
	conf_mount_ro();
356

    
357
}
358

    
359
function local_user_set(& $user) {
360
	global $g, $debug;
361

    
362
	conf_mount_rw();
363

    
364
	$home_base = "/home/";	
365
	$user_uid = $user['uid'];
366
	$user_name = $user['name'];
367
	$user_home = "{$home_base}{$user_name}";
368
	$user_shell = "/etc/rc.initial";
369
	$user_group = "nobody";
370

    
371
	// Ensure $home_base exists and is writable
372
	if (!is_dir($home_base)) 
373
		mkdir($home_base, 0755);
374

    
375
	$lock_account = false;
376
	/* configure shell type */
377
	/* Cases here should be ordered by most privileged to least privileged. */
378
	if (userHasPrivilege($user, "user-shell-access") || userHasPrivilege($user, "page-all")) {
379
		$user_shell = "/bin/tcsh";
380
	} elseif (userHasPrivilege($user, "user-copy-files")) {
381
		$user_shell = "/usr/local/bin/scponly";
382
	} elseif (userHasPrivilege($user, "user-ssh-tunnel")) {
383
		$user_shell = "/usr/local/sbin/ssh_tunnel_shell";
384
	} elseif (userHasPrivilege($user, "user-ipsec-xauth-dialin")) {
385
		$user_shell = "/sbin/nologin";
386
	} else {
387
		$user_shell = "/sbin/nologin";
388
		$lock_account = true;
389
	}
390

    
391
	/* Lock out disabled or expired users, unless it's root/admin. */
392
	if ((is_account_disabled($user_name) || is_account_expired($user_name)) && ($user_uid != 0)) {
393
		$user_shell = "/sbin/nologin";
394
		$lock_account = true;
395
	}
396

    
397
	/* root user special handling */
398
	if ($user_uid == 0) {
399
		$cmd = "/usr/sbin/pw usermod -q -n root -s /bin/sh -H 0";
400
		if($debug)
401
			log_error(sprintf(gettext("Running: %s"), $cmd));
402
		$fd = popen($cmd, "w");
403
		fwrite($fd, $user['password']);
404
		pclose($fd);
405
		$user_group = "wheel";
406
		$user_home = "/root";
407
		$user_shell = "/etc/rc.initial";
408
	}
409

    
410
	/* read from pw db */
411
	$fd = popen("/usr/sbin/pw usershow {$user_name} 2>&1", "r");
412
	$pwread = fgets($fd);
413
	pclose($fd);
414

    
415
	/* determine add or mod */
416
	if (!strncmp($pwread, "pw:", 3)) {
417
		$user_op = "useradd -m -k /etc/skel -o";
418
	} else {
419
		$user_op = "usermod";
420
	}
421

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

    
427
	if($debug)
428
		log_error(sprintf(gettext("Running: %s"), $cmd));
429
	$fd = popen($cmd, "w");
430
	fwrite($fd, $user['password']);
431
	pclose($fd);
432

    
433
	/* create user directory if required */
434
	if (!is_dir($user_home)) {
435
		mkdir($user_home, 0700);
436
		mwexec("/bin/cp /root/.* {$home_base}/", true);
437
	}
438
	chown($user_home, $user_name);
439
	chgrp($user_home, $user_group);
440

    
441
	/* write out ssh authorized key file */
442
	if($user['authorizedkeys']) {
443
		if (!is_dir("{$user_home}/.ssh")) {
444
			mkdir("{$user_home}/.ssh", 0700);
445
			chown("{$user_home}/.ssh", $user_name);
446
		}
447
		$keys = base64_decode($user['authorizedkeys']);
448
		file_put_contents("{$user_home}/.ssh/authorized_keys", $keys);
449
		chown("{$user_home}/.ssh/authorized_keys", $user_name);
450
	} else
451
		unlink_if_exists("{$user_home}/.ssh/authorized_keys");
452

    
453
	$un = $lock_account ? "" : "un";
454
	exec("/usr/sbin/pw {$un}lock {$user_name} -q");
455
	
456
	conf_mount_ro();
457
}
458

    
459
function local_user_del($user) {
460
	global $debug;
461

    
462
	/* remove all memberships */
463
	local_user_set_groups($user);
464

    
465
	/* Don't remove /root */
466
	if ($user['uid'] != 0)
467
		$rmhome = "-r";
468

    
469
	/* delete from pw db */
470
	$cmd = "/usr/sbin/pw userdel {$user['name']} {$rmhome}";
471

    
472
	if($debug)
473
		log_error(sprintf(gettext("Running: %s"), $cmd));
474
	mwexec($cmd);
475

    
476
	/* Delete user from groups needs a call to write_config() */
477
	local_group_del_user($user);
478
}
479

    
480
function local_user_set_password(& $user, $password) {
481

    
482
	$user['password'] = crypt($password);
483
	$user['md5-hash'] = md5($password);
484

    
485
	// Converts ascii to unicode.
486
	$astr = (string) $password;
487
	$ustr = '';
488
	for ($i = 0; $i < strlen($astr); $i++) {
489
		$a = ord($astr{$i}) << 8;
490
		$ustr.= sprintf("%X", $a);
491
	}
492

    
493
	// Generate the NT-HASH from the unicode string
494
	$user['nt-hash'] = bin2hex(mhash(MHASH_MD4, $ustr));
495
}
496

    
497
function local_user_get_groups($user, $all = false) {
498
	global $debug, $config;
499

    
500
	$groups = array();
501
	if (!is_array($config['system']['group']))
502
		return $groups;
503

    
504
	foreach ($config['system']['group'] as $group)
505
		if ( $all || ( !$all && ($group['name'] != "all")))
506
			if (is_array($group['member']))
507
				if (in_array($user['uid'], $group['member']))
508
					$groups[] = $group['name'];
509

    
510
	if ( $all )
511
		$groups[] = "all";
512

    
513
	sort($groups);
514

    
515
	return $groups;
516
	
517
}
518

    
519
function local_user_set_groups($user, $new_groups = NULL ) {
520
	global $debug, $config, $groupindex;
521

    
522
	if (!is_array($config['system']['group']))
523
		return;
524

    
525
	$cur_groups = local_user_get_groups($user, true);
526
	$mod_groups = array();
527

    
528
	if (!is_array($new_groups))
529
		$new_groups = array();
530

    
531
	if (!is_array($cur_groups))
532
		$cur_groups = array();
533

    
534
	/* determine which memberships to add */
535
	foreach ($new_groups as $groupname) {
536
		if (in_array($groupname,$cur_groups))
537
			continue;
538
		$group = & $config['system']['group'][$groupindex[$groupname]];
539
		$group['member'][] = $user['uid'];
540
		$mod_groups[] = $group;
541
	}
542
	unset($group);
543

    
544
	/* determine which memberships to remove */
545
	foreach ($cur_groups as $groupname) {
546
		if (in_array($groupname,$new_groups))
547
			continue;
548
		if (!isset($config['system']['group'][$groupindex[$groupname]]))
549
			continue;
550
		$group = & $config['system']['group'][$groupindex[$groupname]];
551
		if (is_array($group['member'])) {
552
			$index = array_search($user['uid'], $group['member']);
553
			array_splice($group['member'], $index, 1);
554
			$mod_groups[] = $group;
555
		}
556
	}
557
	unset($group);
558

    
559
	/* sync all modified groups */
560
	foreach ($mod_groups as $group)
561
		local_group_set($group);
562
}
563

    
564
function local_group_del_user($user) {
565
	global $config;
566

    
567
	if (!is_array($config['system']['group']))
568
                return;
569

    
570
        foreach ($config['system']['group'] as $group) {
571
		if (is_array($group['member'])) {
572
			foreach ($group['member'] as $idx => $uid) {
573
				if ($user['uid'] == $uid)
574
					unset($config['system']['group']['member'][$idx]);
575
			}
576
		}
577
	}
578
}
579

    
580
function local_group_set($group, $reset = false) {
581
	global $debug;
582

    
583
	$group_name = $group['name'];
584
	$group_gid = $group['gid'];
585
	$group_members = "''";
586
	if (!$reset && !empty($group['member']) && count($group['member']) > 0)
587
		$group_members = implode(",",$group['member']);
588

    
589
	/* read from group db */
590
	$fd = popen("/usr/sbin/pw groupshow {$group_name} 2>&1", "r");
591
	$pwread = fgets($fd);
592
	pclose($fd);
593

    
594
	/* determine add or mod */
595
	if (!strncmp($pwread, "pw:", 3))
596
		$group_op = "groupadd";
597
	else
598
		$group_op = "groupmod";
599

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

    
603
	if($debug)
604
		log_error(sprintf(gettext("Running: %s"), $cmd));
605
	mwexec($cmd);
606

    
607
}
608

    
609
function local_group_del($group) {
610
	global $debug;
611

    
612
	/* delete from group db */
613
	$cmd = "/usr/sbin/pw groupdel {$group['name']}";
614

    
615
	if($debug)
616
		log_error(sprintf(gettext("Running: %s"), $cmd));
617
	mwexec($cmd);
618
}
619

    
620
function ldap_test_connection($authcfg) {
621
	global $debug, $config, $g;
622

    
623
	if ($authcfg) {
624
                if (strstr($authcfg['ldap_urltype'], "Standard"))
625
                        $ldapproto = "ldap";
626
                else
627
                        $ldapproto = "ldaps";
628
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
629
                $ldapport           = $authcfg['ldap_port'];
630
                $ldapbasedn         = $authcfg['ldap_basedn'];
631
                $ldapbindun         = $authcfg['ldap_binddn'];
632
                $ldapbindpw         = $authcfg['ldap_bindpw'];
633
        } else
634
		return false;
635

    
636
        /* first check if there is even an LDAP server populated */
637
        if(!$ldapserver)
638
                return false;
639

    
640
        /* Setup CA environment if needed. */
641
        ldap_setup_caenv($authcfg);
642

    
643
        /* connect and see if server is up */
644
        $error = false;
645
        if (empty($ldapport)) {
646
                if (!($ldap = ldap_connect($ldapserver)))
647
                        $error = true;
648
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
649
                $error = true;
650

    
651
        if ($error == true) {
652
                log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
653
                return false;
654
        }
655

    
656
	return true;
657
}
658

    
659
function ldap_setup_caenv($authcfg) {
660
	global $g;
661

    
662
	unset($caref);
663
	if (empty($authcfg['ldap_caref']) || !strstr($authcfg['ldap_urltype'], "SSL")) {
664
		putenv('LDAPTLS_REQCERT=never');
665
		return;
666
	} else {
667
		$caref = lookup_ca($authcfg['ldap_caref']);
668
		if (!$caref) {
669
			log_error(sprintf(gettext("LDAP: Could not lookup CA by reference for host %s."), $authcfg['ldap_caref']));
670
			/* XXX: Prevent for credential leaking since we cannot setup the CA env. Better way? */
671
			putenv('LDAPTLS_REQCERT=hard');
672
			return;
673
		}
674
		if (!is_dir("{$g['varrun_path']}/certs"))
675
			@mkdir("{$g['varrun_path']}/certs");
676
		if (file_exists("{$g['varrun_path']}/certs/{$authcfg['name']}.ca"))
677
			@unlink("{$g['varrun_path']}/certs/{$authcfg['name']}.ca");
678
		file_put_contents("{$g['varrun_path']}/certs/{$authcfg['name']}.ca", base64_decode($caref['crt']));
679
		@chmod("{$g['varrun_path']}/certs/{$authcfg['name']}.ca", 0600);
680
		putenv('LDAPTLS_REQCERT=hard');
681
		/* XXX: Probably even the hashed link should be created for this? */
682
		putenv("TLS_CACERTDIR={$g['varrun_path']}/certs");
683
		putenv("TLS_CACERT={$g['varrun_path']}/certs/{$authcfg['name']}.ca");
684
	}
685
}
686

    
687
function ldap_test_bind($authcfg) {
688
	global $debug, $config, $g;
689

    
690
	if ($authcfg) {
691
                if (strstr($authcfg['ldap_urltype'], "Standard"))
692
                        $ldapproto = "ldap";
693
                else
694
                        $ldapproto = "ldaps";
695
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
696
                $ldapport           = $authcfg['ldap_port'];
697
                $ldapbasedn         = $authcfg['ldap_basedn'];
698
                $ldapbindun         = $authcfg['ldap_binddn'];
699
                $ldapbindpw         = $authcfg['ldap_bindpw'];
700
                $ldapver            = $authcfg['ldap_protver'];
701
		if (empty($ldapbndun) || empty($ldapbindpw))
702
                        $ldapanon = true;
703
                else
704
                        $ldapanon = false;
705
	} else
706
		return false;
707

    
708
	/* first check if there is even an LDAP server populated */
709
        if(!$ldapserver)
710
                return false;
711

    
712
	/* Setup CA environment if needed. */
713
	ldap_setup_caenv($authcfg);
714

    
715
        /* connect and see if server is up */
716
        $error = false;
717
        if (empty($ldapport)) {
718
                if (!($ldap = ldap_connect($ldapserver)))
719
                        $error = true;
720
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
721
                $error = true;
722

    
723
        if ($error == true) {
724
                log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
725
                return false;
726
        }
727

    
728
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
729
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
730
 
731
	if ($ldapanon == true) {
732
		if (!($res = @ldap_bind($ldap))) {
733
			@ldap_close($ldap);
734
			return false;
735
		}
736
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
737
		@ldap_close($ldap);
738
		return false;
739
	}
740

    
741
	@ldap_unbind($ldap);
742

    
743
	return true;
744
}
745

    
746
function ldap_get_user_ous($show_complete_ou=true, $authcfg) {
747
	global $debug, $config, $g;
748

    
749
	if(!function_exists("ldap_connect"))
750
		return;
751

    
752
	$ous = array();
753

    
754
	if ($authcfg) {
755
                if (strstr($authcfg['ldap_urltype'], "Standard"))
756
                        $ldapproto = "ldap";
757
                else
758
                        $ldapproto = "ldaps";
759
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
760
                $ldapport           = $authcfg['ldap_port'];
761
                $ldapbasedn         = $authcfg['ldap_basedn'];
762
                $ldapbindun         = $authcfg['ldap_binddn'];
763
                $ldapbindpw         = $authcfg['ldap_bindpw'];
764
                $ldapver            = $authcfg['ldap_protver'];
765
		if (empty($ldapbindun) || empty($ldapbindpw))
766
                        $ldapanon = true;
767
                else
768
                        $ldapanon = false;
769
                $ldapname           = $authcfg['name'];
770
                $ldapfallback       = false;
771
		$ldapscope          = $authcfg['ldap_scope'];
772
        } else
773
		return false;
774

    
775
        /* first check if there is even an LDAP server populated */
776
        if(!$ldapserver) {
777
                log_error(gettext("ERROR!  ldap_get_user_ous() backed selected with no LDAP authentication server defined."));
778
                return $ous;
779
        }
780

    
781
	/* Setup CA environment if needed. */
782
	ldap_setup_caenv($authcfg);
783

    
784
	/* connect and see if server is up */
785
        $error = false;
786
        if (empty($ldapport)) {
787
                if (!($ldap = ldap_connect($ldapserver)))
788
                        $error = true;
789
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
790
                $error = true;
791

    
792
        if ($error == true) {
793
        log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
794
                return $ous;
795
        }
796

    
797
	$ldapfilter = "(|(ou=*)(cn=Users))";
798

    
799
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
800
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
801

    
802
	if ($ldapanon == true) {
803
                if (!($res = @ldap_bind($ldap))) {
804
			log_error(sprintf(gettext("ERROR! ldap_get_user_ous() could not bind anonymously to server %s."), $ldapname));
805
			@ldap_close($ldap);
806
                        return $ous;
807
		}
808
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
809
		log_error(sprintf(gettext("ERROR! ldap_get_user_ous() could not bind to server %s."), $ldapname));
810
		@ldap_close($ldap);
811
		return $ous;
812
	}
813

    
814
	if ($ldapscope == "one")
815
		$ldapfunc = "ldap_list";
816
	else
817
		$ldapfunc = "ldap_search";
818

    
819
	$search = @$ldapfunc($ldap, $ldapbasedn, $ldapfilter);
820
	$info = @ldap_get_entries($ldap, $search);
821

    
822
	if (is_array($info)) {
823
		foreach ($info as $inf) {
824
			if (!$show_complete_ou) {
825
				$inf_split = split(",", $inf['dn']);
826
				$ou = $inf_split[0];
827
				$ou = str_replace("OU=","", $ou);
828
				$ou = str_replace("CN=","", $ou);
829
			} else
830
				if($inf['dn'])
831
					$ou = $inf['dn'];
832
			if($ou)
833
				$ous[] = $ou;
834
		}
835
	}
836

    
837
	@ldap_unbind($ldap);
838

    
839
	return $ous;
840
}
841

    
842
function ldap_get_groups($username, $authcfg) {
843
	global $debug, $config;
844
	
845
	if(!function_exists("ldap_connect"))
846
		return;
847
	
848
	if(!$username) 
849
		return false;
850

    
851
	if(stristr($username, "@")) {
852
		$username_split=split("\@", $username);
853
		$username = $username_split[0];		
854
	}
855

    
856
	if(stristr($username, "\\")) {
857
		$username_split=split("\\", $username);
858
		$username = $username_split[0];        
859
	}    
860
	
861
	//log_error("Getting LDAP groups for {$username}.");
862
        if ($authcfg) {
863
                if (strstr($authcfg['ldap_urltype'], "Standard"))
864
                        $ldapproto = "ldap";
865
                else
866
                        $ldapproto = "ldaps";
867
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
868
                $ldapport           = $authcfg['ldap_port'];
869
                $ldapbasedn         = $authcfg['ldap_basedn'];
870
                $ldapbindun         = $authcfg['ldap_binddn'];
871
                $ldapbindpw         = $authcfg['ldap_bindpw'];
872
                $ldapauthcont       = $authcfg['ldap_authcn'];
873
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
874
                $ldapgroupattribute  = strtolower($authcfg['ldap_attr_member']);
875
                $ldapfilter         = "({$ldapnameattribute}={$username})";
876
                $ldaptype           = "";
877
                $ldapver            = $authcfg['ldap_protver'];
878
		if (empty($ldapbindun) || empty($ldapbindpw))
879
                        $ldapanon = true;
880
                else
881
                        $ldapanon = false;
882
                $ldapname           = $authcfg['name'];
883
                $ldapfallback       = false;
884
		$ldapscope          = $authcfg['ldap_scope'];
885
	} else
886
		return false;
887

    
888
	$ldapdn             = $_SESSION['ldapdn'];
889

    
890
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
891
	$ldapgroupattribute = strtolower($ldapgroupattribute);
892
	$memberof = array();
893

    
894
        /* Setup CA environment if needed. */
895
        ldap_setup_caenv($authcfg);
896

    
897
	/* connect and see if server is up */
898
	$error = false;
899
        if (empty($ldapport)) {
900
                if (!($ldap = ldap_connect($ldapserver)))
901
                        $error = true;
902
        } else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
903
                $error = true;
904

    
905
	if ($error == true) {
906
		log_error(sprintf(gettext("ERROR! ldap_get_groups() Could not connect to server %s."), $ldapname));
907
                return memberof;
908
        }
909
    
910
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
911
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
912

    
913
	/* bind as user that has rights to read group attributes */
914
	if ($ldapanon == true) {
915
                if (!($res = @ldap_bind($ldap))) {
916
			log_error(sprintf(gettext("ERROR! ldap_get_groups() could not bind anonymously to server %s."), $ldapname));
917
			@ldap_close($ldap);
918
                        return false;
919
		}
920
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
921
		log_error(sprintf(gettext("ERROR! ldap_get_groups() could not bind to server %s."), $ldapname));
922
		@ldap_close($ldap);
923
		return memberof;
924
	}
925

    
926
	/* get groups from DN found */
927
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
928
	/* since we know the DN is in $_SESSION['ldapdn'] */
929
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
930
	if ($ldapscope == "one")
931
                $ldapfunc = "ldap_list";
932
        else
933
                $ldapfunc = "ldap_search";
934

    
935
	$search    = @$ldapfunc($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
936
	$info      = @ldap_get_entries($ldap, $search);
937

    
938
	$countem = $info["count"];	
939
	
940
	if(is_array($info[0][$ldapgroupattribute])) {
941
		/* Iterate through the groups and throw them into an array */
942
		foreach ($info[0][$ldapgroupattribute] as $member) {
943
			if (stristr($member, "CN=") !== false) {
944
				$membersplit = split(",", $member);
945
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
946
			}
947
		}
948
	}
949
	
950
	/* Time to close LDAP connection */
951
	@ldap_unbind($ldap);
952
	
953
	$groups = print_r($memberof,true);
954
	
955
	//log_error("Returning groups ".$groups." for user $username");
956
	
957
	return $memberof;
958
}
959

    
960
function ldap_backed($username, $passwd, $authcfg) {
961
	global $debug, $config;
962
	
963
	if(!$username) 
964
		return;
965

    
966
	if(!function_exists("ldap_connect"))
967
		return;
968

    
969
	if(stristr($username, "@")) {
970
		$username_split=split("\@", $username);
971
		$username = $username_split[0];        
972
	}
973
	if(stristr($username, "\\")) {
974
		$username_split=split("\\", $username);
975
		$username = $username_split[0];        
976
	}
977

    
978
	if ($authcfg) {
979
		if (strstr($authcfg['ldap_urltype'], "Standard"))
980
			$ldapproto = "ldap";
981
		else
982
			$ldapproto = "ldaps";
983
		$ldapserver         = "{$ldapproto}://{$authcfg['host']}";
984
		$ldapport	    = $authcfg['ldap_port'];
985
                $ldapbasedn         = $authcfg['ldap_basedn'];
986
                $ldapbindun         = $authcfg['ldap_binddn'];
987
                $ldapbindpw         = $authcfg['ldap_bindpw'];
988
		if (empty($ldapbindun) || empty($ldapbindpw))
989
			$ldapanon = true;
990
		else
991
			$ldapanon = false;
992
                $ldapauthcont       = $authcfg['ldap_authcn'];
993
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
994
                $ldapextendedqueryenabled  = $authcfg['ldap_extended_enabled'];
995
                $ldapextendedquery = $authcfg['ldap_extended_query'];
996
                $ldapfilter         = "";
997
                if(!$ldapextendedqueryenabled)
998
                {
999
                        $ldapfilter = "({$ldapnameattribute}={$username})";
1000
                }
1001
                else
1002
                {
1003
                        $ldapfilter = 
1004
"(&({$ldapnameattribute}={$username})({$ldapextendedquery}))";
1005
                } 
1006
                $ldaptype           = "";
1007
                $ldapver            = $authcfg['ldap_protver'];
1008
		$ldapname	    = $authcfg['name'];
1009
		$ldapscope	    = $authcfg['ldap_scope'];
1010
	} else
1011
		return false;
1012

    
1013
	/* first check if there is even an LDAP server populated */ 
1014
	if(!$ldapserver) {
1015
		if ($ldapfallback) {
1016
			log_error(gettext("ERROR! ldap_backed() called with no LDAP authentication server defined.  Defaulting to local user database. Visit System -> User Manager."));
1017
			return local_backed($username, $passwd);
1018
		} else
1019
			log_error(gettext("ERROR! ldap_backed() called with no LDAP authentication server defined."));
1020

    
1021
		return false;
1022
	}
1023
	
1024
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
1025
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
1026

    
1027
        /* Setup CA environment if needed. */
1028
        ldap_setup_caenv($authcfg);
1029

    
1030
	/* Make sure we can connect to LDAP */
1031
	$error = false;
1032
	if (empty($ldapport)) {
1033
		if (!($ldap = ldap_connect($ldapserver)))
1034
			$error = true;
1035
	} else if (!($ldap = ldap_connect($ldapserver, $ldapport)))
1036
		$error = true;
1037

    
1038
	if ($error == true) {
1039
		log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
1040
		return false;
1041
	}
1042

    
1043
	/* ok, its up.  now, lets bind as the bind user so we can search it */
1044
	$error = false;
1045
	if ($ldapanon == true) {
1046
                if (!($res = @ldap_bind($ldap)))
1047
                        $error = true;
1048
	} else if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
1049
		$error = true;
1050

    
1051
	if ($error == true) {
1052
		@ldap_close($ldap);
1053
		log_error(sprintf(gettext("ERROR! Could not bind to server %s."), $ldapname));
1054
		return false;
1055
	}
1056
	
1057
	/* Get LDAP Authcontainers and split em up. */
1058
	$ldac_splits = split(";", $ldapauthcont);
1059
	
1060
	/* setup the usercount so we think we havn't found anyone yet */
1061
	$usercount  = 0;
1062

    
1063
	/*****************************************************************/
1064
	/*  We First find the user based on username and filter          */
1065
	/*  Then, once we find the first occurance of that person        */
1066
	/*  We set seesion variables to ponit to the OU and DN of the    */
1067
	/*  Person.  To later be used by ldap_get_groups.                */
1068
	/*  that way we don't have to search twice.                      */
1069
	/*****************************************************************/
1070
	log_error(sprintf(gettext("Now Searching for %s in directory."), $username));
1071
	/* Iterate through the user containers for search */
1072
	foreach ($ldac_splits as $i => $ldac_split) {
1073
		/* Make sure we just use the first user we find */
1074
		log_error(sprintf(gettext('Now Searching in server %1$s, container %2$s with filter %3$s.'), $ldapname, $ldac_split, $ldapfilter));
1075
		if ($ldapscope == "one")
1076
			$ldapfunc = "ldap_list";
1077
		else
1078
			$ldapfunc = "ldap_search";
1079
		/* Support legacy auth container specification. */
1080
		if (stristr($ldac_split, "DC=") || empty($ldapbasedn))
1081
			$search	 = @$ldapfunc($ldap,$ldac_split,$ldapfilter);
1082
		else
1083
			$search  = @$ldapfunc($ldap,"{$ldac_split},{$ldapbasedn}",$ldapfilter);
1084
		if (!$search) {
1085
			log_error(sprintf(gettext("Search resulted in error: %s"), ldap_error($ldap)));
1086
			continue;
1087
		}
1088
		$info	 = ldap_get_entries($ldap,$search);
1089
		$matches = $info['count'];
1090
		if ($matches == 1){
1091
			$userdn = $_SESSION['ldapdn'] = $info[0]['dn'];
1092
			$_SESSION['ldapou'] = $ldac_split[$i];
1093
			$_SESSION['ldapon'] = "true";
1094
			$usercount = 1;
1095
			break;
1096
		}
1097
	}
1098

    
1099
	if ($usercount != 1){
1100
		@ldap_unbind($ldap);
1101
		log_error(gettext("ERROR! Either LDAP search failed, or multiple users were found."));
1102
		return false;                         
1103
	}
1104

    
1105
	/* Now lets bind as the user we found */
1106
	if (!($res = @ldap_bind($ldap, $userdn, $passwd))) {
1107
		log_error(sprintf(gettext('ERROR! Could not login to server %1$s as user %2$s.'), $ldapname, $username));
1108
		@ldap_unbind($ldap);
1109
		return false;
1110
	}
1111

    
1112
	log_error(sprintf(gettext('Logged in successfully as %1$s via LDAP server %2$s with DN = %3$s.'), $username, $ldapname, $userdn));
1113

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

    
1117
	return true;
1118
}
1119

    
1120
function radius_backed($username, $passwd, $authcfg){
1121
	global $debug, $config;
1122
	$ret = false;
1123

    
1124
	require_once("radius.inc");
1125

    
1126
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
1127
	if ($authcfg) {
1128
		$radiusservers = array();
1129
		$radiusservers[0]['ipaddr'] = $authcfg['host'];
1130
		$radiusservers[0]['port'] = $authcfg['radius_auth_port'];
1131
		$radiusservers[0]['sharedsecret'] = $authcfg['radius_secret'];
1132
	} else
1133
		return false;
1134

    
1135
	/* Add a new servers to our instance */
1136
	foreach ($radiusservers as $radsrv)
1137
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
1138

    
1139
	if (PEAR::isError($rauth->start())) {
1140
		$retvalue['auth_val'] = 1;
1141
		$retvalue['error'] = $rauth->getError();
1142
		if ($debug)
1143
			printf(gettext("Radius start: %s<br>\n"), $retvalue['error']);
1144
	}
1145

    
1146
	// XXX - billm - somewhere in here we need to handle securid challenge/response
1147

    
1148
	/* Send request */
1149
	$result = $rauth->send();
1150
	if (PEAR::isError($result)) {
1151
		$retvalue['auth_val'] = 1;
1152
		$retvalue['error'] = $result->getMessage();
1153
		if ($debug)
1154
			printf(gettext("Radius send failed: %s<br>\n"), $retvalue['error']);
1155
	} else if ($result === true) {
1156
		$retvalue['auth_val'] = 2;
1157
		if ($debug)
1158
			printf(gettext("Radius Auth succeeded")."<br>\n");
1159
		$ret = true;
1160
	} else {
1161
		$retvalue['auth_val'] = 3;
1162
		if ($debug)
1163
			printf(gettext("Radius Auth rejected")."<br>\n");
1164
	}
1165

    
1166
	// close OO RADIUS_AUTHENTICATION
1167
	$rauth->close();
1168

    
1169
	return $ret;
1170
}
1171

    
1172
function get_user_expiration_date($username) {
1173
	$user = getUserEntry($username);
1174
	if ($user['expires']) 
1175
		return $user['expires'];
1176
}
1177

    
1178
function is_account_expired($username) {
1179
	$expirydate = get_user_expiration_date($username);
1180
	if ($expirydate) {
1181
		if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($expirydate))))
1182
			return true;
1183
	}
1184

    
1185
	return false;
1186
}
1187

    
1188
function is_account_disabled($username) {
1189
	$user = getUserEntry($username);
1190
	if (isset($user['disabled']))
1191
		return true;
1192

    
1193
	return false;
1194
}
1195

    
1196
function auth_get_authserver($name) {
1197
        global $config;
1198

    
1199
        if (is_array($config['system']['authserver'])) {
1200
                foreach ($config['system']['authserver'] as $authcfg) {
1201
                        if ($authcfg['name'] == $name)
1202
                                return $authcfg;
1203
                }
1204
        }
1205
	if ($name == "Local Database")
1206
		return array("name" => gettext("Local Database"), "type" => gettext("Local Auth"), "host" => $config['system']['hostname']);
1207
}
1208

    
1209
function auth_get_authserver_list() {
1210
        global $config;
1211

    
1212
	$list = array();
1213

    
1214
        if (is_array($config['system']['authserver'])) {
1215
                foreach ($config['system']['authserver'] as $authcfg) {
1216
			/* Add support for disabled entries? */
1217
			$list[$authcfg['name']] = $authcfg;
1218
                }
1219
        }
1220

    
1221
	$list["Local Database"] = array( "name" => gettext("Local Database"), "type" => gettext("Local Auth"), "host" => $config['system']['hostname']);
1222
	return $list;
1223
}
1224

    
1225
function getUserGroups($username, $authcfg) {
1226
	global $config;
1227

    
1228
	$allowed_groups = array();
1229

    
1230
	switch($authcfg['type']) {
1231
        case 'ldap':
1232
		$allowed_groups = @ldap_get_groups($username, $authcfg);
1233
		break;
1234
	case 'radius':
1235
		break;
1236
	default:
1237
		$user = getUserEntry($username);
1238
		$allowed_groups = @local_user_get_groups($user, true);
1239
		break;
1240
	}
1241

    
1242
	$member_groups = array();
1243
        if (is_array($config['system']['group'])) {
1244
                foreach ($config['system']['group'] as $group)
1245
                        if (in_array($group['name'], $allowed_groups))
1246
				$member_groups[] = $group['name'];
1247
	}
1248

    
1249
	return $member_groups;
1250
}
1251

    
1252
function authenticate_user($username, $password, $authcfg = NULL) {
1253

    
1254
	if (!$authcfg) {
1255
		return local_backed($username, $password);
1256
	}
1257

    
1258
	$authenticated = false;
1259
	switch($authcfg['type']) {
1260
        case 'ldap':
1261
                if (ldap_backed($username, $password, $authcfg))
1262
                        $authenticated = true;
1263
                break;
1264
        case 'radius':
1265
                if (radius_backed($username, $password, $authcfg))
1266
                        $authenticated = true;
1267
                break;
1268
        default:
1269
                /* lookup user object by name */
1270
                if (local_backed($username, $password))
1271
                        $authenticated = true;
1272
                break;
1273
        }
1274

    
1275
	return $authenticated;
1276
}
1277

    
1278
function session_auth() {
1279
	global $HTTP_SERVER_VARS, $config, $_SESSION, $page;
1280

    
1281
	session_start();
1282

    
1283
	/* Validate incoming login request */
1284
	if (isset($_POST['login'])) {
1285
		$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
1286
		if (authenticate_user($_POST['usernamefld'], $_POST['passwordfld'], $authcfg) || 
1287
		    authenticate_user($_POST['usernamefld'], $_POST['passwordfld'])) {
1288
			$_SESSION['Logged_In'] = "True";
1289
			$_SESSION['Username'] = $_POST['usernamefld'];
1290
			$_SESSION['last_access'] = time();
1291
			if(! isset($config['system']['webgui']['quietlogin'])) {
1292
				log_auth(sprintf(gettext("Successful login for user '%1\$s' from: %2\$s"), $_POST['usernamefld'], $_SERVER['REMOTE_ADDR']));
1293
			}
1294
			$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1295
			if (isset($_POST['postafterlogin']))
1296
				return true;
1297
			else {
1298
				if (empty($page))
1299
					$page = "/";
1300
				header("Location: {$page}");
1301
			}
1302
			exit;
1303
		} else {
1304
			/* give the user an error message */
1305
			$_SESSION['Login_Error'] = "Username or Password incorrect";
1306
			log_auth("webConfigurator authentication error for '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}");
1307
			if(isAjax()) {
1308
				echo "showajaxmessage('{$_SESSION['Login_Error']}');";
1309
				return;
1310
			}
1311
		}
1312
	}
1313

    
1314
	/* Show login page if they aren't logged in */
1315
	if (empty($_SESSION['Logged_In']))
1316
		return false;
1317

    
1318
	/* If session timeout isn't set, we don't mark sessions stale */
1319
	if (!isset($config['system']['webgui']['session_timeout'])) {
1320
		/* Default to 4 hour timeout if one is not set */
1321
		if ($_SESSION['last_access'] < (time() - 14400)) {
1322
			$_GET['logout'] = true;
1323
			$_SESSION['Logout'] = true;
1324
		} else
1325
			$_SESSION['last_access'] = time();	
1326
	} else if (intval($config['system']['webgui']['session_timeout']) == 0) {
1327
		/* only update if it wasn't ajax */
1328
		if (!isAjax())
1329
			$_SESSION['last_access'] = time();
1330
	} else {
1331
		/* Check for stale session */
1332
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
1333
			$_GET['logout'] = true;
1334
			$_SESSION['Logout'] = true;
1335
		} else {
1336
			/* only update if it wasn't ajax */
1337
			if (!isAjax())
1338
				$_SESSION['last_access'] = time();
1339
		}
1340
	}
1341

    
1342
	/* user hit the logout button */
1343
	if (isset($_GET['logout'])) {
1344

    
1345
		if ($_SESSION['Logout'])
1346
			log_error(sprintf(gettext("Session timed out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1347
		else
1348
			log_error(sprintf(gettext("User logged out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1349

    
1350
		/* wipe out $_SESSION */
1351
		$_SESSION = array();
1352

    
1353
		if (isset($_COOKIE[session_name()]))
1354
			setcookie(session_name(), '', time()-42000, '/');
1355

    
1356
		/* and destroy it */
1357
		session_destroy();
1358

    
1359
		$scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
1360
		$scriptElms = count($scriptName);
1361
		$scriptName = $scriptName[$scriptElms-1];
1362

    
1363
		if (isAjax())
1364
			return false;
1365

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

    
1369
		return false;
1370
	}
1371

    
1372
	/*
1373
	 * this is for debugging purpose if you do not want to use Ajax
1374
	 * to submit a HTML form. It basically diables the observation
1375
	 * of the submit event and hence does not trigger Ajax.
1376
	 */
1377
	if ($_GET['disable_ajax'])
1378
		$_SESSION['NO_AJAX'] = "True";
1379

    
1380
	/*
1381
	 * Same to re-enable Ajax.
1382
	 */
1383
	if ($_GET['enable_ajax'])
1384
		unset($_SESSION['NO_AJAX']);
1385

    
1386
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1387
	return true;
1388
}
1389

    
1390
?>
(4-4/61)