Project

General

Profile

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

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

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

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

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

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

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

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

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

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

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

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

    
55
/* If this function doesn't exist, we're being called from Captive Portal or 
56
   another internal subsystem which does not include authgui.inc */
57
if (function_exists("display_error_form") && !isset($config['system']['webgui']['nodnsrebindcheck'])) {
58
	/* DNS ReBinding attack prevention.  http://redmine.pfsense.org/issues/708 */
59
	$found_host = false;
60

    
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)) || ($line[2] < 2000) || ($line[2] > 65000)) && ($line[0] != "admin"))
308
				continue;
309
			$cmd = "/usr/sbin/pw userdel -n '{$line[0]}'";
310
			if($debug)
311
				log_error(sprintf(gettext("Running: %s"), $cmd));
312
			mwexec($cmd);
313
		}
314
		pclose($fd);
315
	}
316

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

    
337
	/* make sure the all group exists */
338
	$allgrp = getGroupEntryByGID(1998);
339
	local_group_set($allgrp, true);
340

    
341
	/* sync all local users */
342
	if (is_array($config['system']['user']))
343
		foreach ($config['system']['user'] as $user)
344
			local_user_set($user);
345

    
346
	/* sync all local groups */
347
	if (is_array($config['system']['group']))
348
		foreach ($config['system']['group'] as $group)
349
			local_group_set($group);
350

    
351
	conf_mount_ro();
352

    
353
}
354

    
355
function local_user_set(& $user) {
356
	global $g, $debug;
357

    
358
	if (empty($user['password'])) {
359
		log_error("There is something wrong in your config because user {$user['name']} password is missing!");
360
		return;
361
	}
362

    
363
	conf_mount_rw();
364

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

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

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

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

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

    
411
	/* read from pw db */
412
	$fd = popen("/usr/sbin/pw usershow -n {$user_name} 2>&1", "r");
413
	$pwread = fgets($fd);
414
	pclose($fd);
415
	$userattrs = explode(":", trim($pwread));
416

    
417
	/* determine add or mod */
418
	if (($userattrs[0] != $user['name']) || (!strncmp($pwread, "pw:", 3))) {
419
		$user_op = "useradd -m -k /etc/skel -o";
420
	} else {
421
		$user_op = "usermod";
422
	}
423

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

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

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

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

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

    
462
function local_user_del($user) {
463
	global $debug;
464

    
465
	/* remove all memberships */
466
	local_user_set_groups($user);
467

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

    
472
	/* read from pw db */
473
	$fd = popen("/usr/sbin/pw usershow -n {$user['name']} 2>&1", "r");
474
	$pwread = fgets($fd);
475
	pclose($fd);
476
	$userattrs = explode(":", trim($pwread));
477

    
478
	if ($userattrs[0] != $user['name']) {
479
		log_error("Tried to remove user {$user['name']} but got user {$userattrs[0]} instead. Bailing.");
480
		return;
481
	}
482

    
483
	/* delete from pw db */
484
	$cmd = "/usr/sbin/pw userdel -n {$user['name']} {$rmhome}";
485

    
486
	if($debug)
487
		log_error(sprintf(gettext("Running: %s"), $cmd));
488
	mwexec($cmd);
489

    
490
	/* Delete user from groups needs a call to write_config() */
491
	local_group_del_user($user);
492
}
493

    
494
function local_user_set_password(& $user, $password) {
495

    
496
	$user['password'] = crypt($password);
497
	$user['md5-hash'] = md5($password);
498

    
499
	// Converts ascii to unicode.
500
	$astr = (string) $password;
501
	$ustr = '';
502
	for ($i = 0; $i < strlen($astr); $i++) {
503
		$a = ord($astr{$i}) << 8;
504
		$ustr.= sprintf("%X", $a);
505
	}
506

    
507
	// Generate the NT-HASH from the unicode string
508
       $user['nt-hash'] = bin2hex(hash("md4", $ustr));
509
}
510

    
511
function local_user_get_groups($user, $all = false) {
512
	global $debug, $config;
513

    
514
	$groups = array();
515
	if (!is_array($config['system']['group']))
516
		return $groups;
517

    
518
	foreach ($config['system']['group'] as $group)
519
		if ( $all || ( !$all && ($group['name'] != "all")))
520
			if (is_array($group['member']))
521
				if (in_array($user['uid'], $group['member']))
522
					$groups[] = $group['name'];
523

    
524
	if ( $all )
525
		$groups[] = "all";
526

    
527
	sort($groups);
528

    
529
	return $groups;
530
	
531
}
532

    
533
function local_user_set_groups($user, $new_groups = NULL ) {
534
	global $debug, $config, $groupindex;
535

    
536
	if (!is_array($config['system']['group']))
537
		return;
538

    
539
	$cur_groups = local_user_get_groups($user, true);
540
	$mod_groups = array();
541

    
542
	if (!is_array($new_groups))
543
		$new_groups = array();
544

    
545
	if (!is_array($cur_groups))
546
		$cur_groups = array();
547

    
548
	/* determine which memberships to add */
549
	foreach ($new_groups as $groupname) {
550
		if (in_array($groupname,$cur_groups))
551
			continue;
552
		$group = & $config['system']['group'][$groupindex[$groupname]];
553
		$group['member'][] = $user['uid'];
554
		$mod_groups[] = $group;
555
	}
556
	unset($group);
557

    
558
	/* determine which memberships to remove */
559
	foreach ($cur_groups as $groupname) {
560
		if (in_array($groupname,$new_groups))
561
			continue;
562
		if (!isset($config['system']['group'][$groupindex[$groupname]]))
563
			continue;
564
		$group = & $config['system']['group'][$groupindex[$groupname]];
565
		if (is_array($group['member'])) {
566
			$index = array_search($user['uid'], $group['member']);
567
			array_splice($group['member'], $index, 1);
568
			$mod_groups[] = $group;
569
		}
570
	}
571
	unset($group);
572

    
573
	/* sync all modified groups */
574
	foreach ($mod_groups as $group)
575
		local_group_set($group);
576
}
577

    
578
function local_group_del_user($user) {
579
	global $config;
580

    
581
	if (!is_array($config['system']['group']))
582
                return;
583

    
584
        foreach ($config['system']['group'] as $group) {
585
		if (is_array($group['member'])) {
586
			foreach ($group['member'] as $idx => $uid) {
587
				if ($user['uid'] == $uid)
588
					unset($config['system']['group']['member'][$idx]);
589
			}
590
		}
591
	}
592
}
593

    
594
function local_group_set($group, $reset = false) {
595
	global $debug;
596

    
597
	$group_name = $group['name'];
598
	$group_gid = $group['gid'];
599
	$group_members = "''";
600
	if (!$reset && !empty($group['member']) && count($group['member']) > 0)
601
		$group_members = implode(",",$group['member']);
602

    
603
	/* read from group db */
604
	$fd = popen("/usr/sbin/pw groupshow {$group_name} 2>&1", "r");
605
	$pwread = fgets($fd);
606
	pclose($fd);
607

    
608
	/* determine add or mod */
609
	if (!strncmp($pwread, "pw:", 3))
610
		$group_op = "groupadd";
611
	else
612
		$group_op = "groupmod";
613

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

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

    
621
}
622

    
623
function local_group_del($group) {
624
	global $debug;
625

    
626
	/* delete from group db */
627
	$cmd = "/usr/sbin/pw groupdel {$group['name']}";
628

    
629
	if($debug)
630
		log_error(sprintf(gettext("Running: %s"), $cmd));
631
	mwexec($cmd);
632
}
633

    
634
function ldap_test_connection($authcfg) {
635
	global $debug, $config, $g;
636

    
637
	if ($authcfg) {
638
                if (strstr($authcfg['ldap_urltype'], "Standard"))
639
                        $ldapproto = "ldap";
640
                else
641
                        $ldapproto = "ldaps";
642
                $ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
643
                $ldapport           = $authcfg['ldap_port'];
644
		if (!empty($ldapport))
645
			$ldapserver .= ":{$ldapport}";
646
                $ldapbasedn         = $authcfg['ldap_basedn'];
647
                $ldapbindun         = $authcfg['ldap_binddn'];
648
                $ldapbindpw         = $authcfg['ldap_bindpw'];
649
        } else
650
		return false;
651

    
652
        /* first check if there is even an LDAP server populated */
653
        if(!$ldapserver)
654
                return false;
655

    
656
        /* Setup CA environment if needed. */
657
        ldap_setup_caenv($authcfg);
658

    
659
        /* connect and see if server is up */
660
        $error = false;
661
	if (!($ldap = ldap_connect($ldapserver)))
662
		$error = true;
663

    
664
        if ($error == true) {
665
                log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
666
                return false;
667
        }
668

    
669
	return true;
670
}
671

    
672
function ldap_setup_caenv($authcfg) {
673
	global $g;
674
	require_once("certs.inc");
675

    
676
	unset($caref);
677
	if (empty($authcfg['ldap_caref']) || !strstr($authcfg['ldap_urltype'], "SSL")) {
678
		putenv('LDAPTLS_REQCERT=never');
679
		return;
680
	} else {
681
		$caref = lookup_ca($authcfg['ldap_caref']);
682
		if (!$caref) {
683
			log_error(sprintf(gettext("LDAP: Could not lookup CA by reference for host %s."), $authcfg['ldap_caref']));
684
			/* XXX: Prevent for credential leaking since we cannot setup the CA env. Better way? */
685
			putenv('LDAPTLS_REQCERT=hard');
686
			return;
687
		}
688
		if (!is_dir("{$g['varrun_path']}/certs"))
689
			@mkdir("{$g['varrun_path']}/certs");
690
		if (file_exists("{$g['varrun_path']}/certs/{$caref['refid']}.ca"))
691
			@unlink("{$g['varrun_path']}/certs/{$caref['refid']}.ca");
692
		file_put_contents("{$g['varrun_path']}/certs/{$caref['refid']}.ca", base64_decode($caref['crt']));
693
		@chmod("{$g['varrun_path']}/certs/{$caref['refid']}.ca", 0600);
694
		putenv('LDAPTLS_REQCERT=hard');
695
		/* XXX: Probably even the hashed link should be created for this? */
696
		putenv("LDAPTLS_CACERTDIR={$g['varrun_path']}/certs");
697
		putenv("LDAPTLS_CACERT={$g['varrun_path']}/certs/{$caref['refid']}.ca");
698
	}
699
}
700

    
701
function ldap_test_bind($authcfg) {
702
	global $debug, $config, $g;
703

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

    
724
	/* first check if there is even an LDAP server populated */
725
        if(!$ldapserver)
726
                return false;
727

    
728
	/* Setup CA environment if needed. */
729
	ldap_setup_caenv($authcfg);
730

    
731
        /* connect and see if server is up */
732
        $error = false;
733
	if (!($ldap = ldap_connect($ldapserver)))
734
		$error = true;
735

    
736
        if ($error == true) {
737
                log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
738
                return false;
739
        }
740

    
741
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
742
	ldap_set_option($ldap, LDAP_OPT_DEREF, LDAP_DEREF_SEARCHING);
743
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
744
 
745
	if ($ldapanon == true) {
746
		if (!($res = @ldap_bind($ldap))) {
747
			@ldap_close($ldap);
748
			return false;
749
		}
750
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
751
		@ldap_close($ldap);
752
		return false;
753
	}
754

    
755
	@ldap_unbind($ldap);
756

    
757
	return true;
758
}
759

    
760
function ldap_get_user_ous($show_complete_ou=true, $authcfg) {
761
	global $debug, $config, $g;
762

    
763
	if(!function_exists("ldap_connect"))
764
		return;
765

    
766
	$ous = array();
767

    
768
	if ($authcfg) {
769
                if (strstr($authcfg['ldap_urltype'], "Standard"))
770
                        $ldapproto = "ldap";
771
                else
772
                        $ldapproto = "ldaps";
773
                $ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
774
                $ldapport           = $authcfg['ldap_port'];
775
		if (!empty($ldapport))
776
			$ldapserver .= ":{$ldapport}";
777
                $ldapbasedn         = $authcfg['ldap_basedn'];
778
                $ldapbindun         = $authcfg['ldap_binddn'];
779
                $ldapbindpw         = $authcfg['ldap_bindpw'];
780
                $ldapver            = $authcfg['ldap_protver'];
781
		if (empty($ldapbindun) || empty($ldapbindpw))
782
                        $ldapanon = true;
783
                else
784
                        $ldapanon = false;
785
                $ldapname           = $authcfg['name'];
786
                $ldapfallback       = false;
787
		$ldapscope          = $authcfg['ldap_scope'];
788
        } else
789
		return false;
790

    
791
        /* first check if there is even an LDAP server populated */
792
        if(!$ldapserver) {
793
                log_error(gettext("ERROR!  ldap_get_user_ous() backed selected with no LDAP authentication server defined."));
794
                return $ous;
795
        }
796

    
797
	/* Setup CA environment if needed. */
798
	ldap_setup_caenv($authcfg);
799

    
800
	/* connect and see if server is up */
801
        $error = false;
802
	if (!($ldap = ldap_connect($ldapserver)))
803
		$error = true;
804

    
805
        if ($error == true) {
806
        log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
807
                return $ous;
808
        }
809

    
810
	$ldapfilter = "(|(ou=*)(cn=Users))";
811

    
812
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
813
	ldap_set_option($ldap, LDAP_OPT_DEREF, LDAP_DEREF_SEARCHING);
814
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
815

    
816
	if ($ldapanon == true) {
817
                if (!($res = @ldap_bind($ldap))) {
818
			log_error(sprintf(gettext("ERROR! ldap_get_user_ous() could not bind anonymously to server %s."), $ldapname));
819
			@ldap_close($ldap);
820
                        return $ous;
821
		}
822
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
823
		log_error(sprintf(gettext("ERROR! ldap_get_user_ous() could not bind to server %s."), $ldapname));
824
		@ldap_close($ldap);
825
		return $ous;
826
	}
827

    
828
	if ($ldapscope == "one")
829
		$ldapfunc = "ldap_list";
830
	else
831
		$ldapfunc = "ldap_search";
832

    
833
	$search = @$ldapfunc($ldap, $ldapbasedn, $ldapfilter);
834
	$info = @ldap_get_entries($ldap, $search);
835

    
836
	if (is_array($info)) {
837
		foreach ($info as $inf) {
838
			if (!$show_complete_ou) {
839
				$inf_split = explode(",", $inf['dn']);
840
				$ou = $inf_split[0];
841
				$ou = str_replace("OU=","", $ou);
842
				$ou = str_replace("CN=","", $ou);
843
			} else
844
				if($inf['dn'])
845
					$ou = $inf['dn'];
846
			if($ou)
847
				$ous[] = $ou;
848
		}
849
	}
850

    
851
	@ldap_unbind($ldap);
852

    
853
	return $ous;
854
}
855

    
856
function ldap_get_groups($username, $authcfg) {
857
	global $debug, $config;
858
	
859
	if(!function_exists("ldap_connect"))
860
		return;
861
	
862
	if(!$username) 
863
		return false;
864

    
865
	if(stristr($username, "@")) {
866
		$username_split = explode("@", $username);
867
		$username = $username_split[0];		
868
	}
869

    
870
	if(stristr($username, "\\")) {
871
		$username_split = explode("\\", $username);
872
		$username = $username_split[0];        
873
	}    
874
	
875
	//log_error("Getting LDAP groups for {$username}.");
876
        if ($authcfg) {
877
                if (strstr($authcfg['ldap_urltype'], "Standard"))
878
                        $ldapproto = "ldap";
879
                else
880
                        $ldapproto = "ldaps";
881
                $ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
882
                $ldapport           = $authcfg['ldap_port'];
883
		if (!empty($ldapport))
884
			$ldapserver .= ":{$ldapport}";
885
                $ldapbasedn         = $authcfg['ldap_basedn'];
886
                $ldapbindun         = $authcfg['ldap_binddn'];
887
                $ldapbindpw         = $authcfg['ldap_bindpw'];
888
                $ldapauthcont       = $authcfg['ldap_authcn'];
889
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
890
                $ldapgroupattribute  = strtolower($authcfg['ldap_attr_member']);
891
                $ldapfilter         = "({$ldapnameattribute}={$username})";
892
                $ldaptype           = "";
893
                $ldapver            = $authcfg['ldap_protver'];
894
		if (empty($ldapbindun) || empty($ldapbindpw))
895
                        $ldapanon = true;
896
                else
897
                        $ldapanon = false;
898
                $ldapname           = $authcfg['name'];
899
                $ldapfallback       = false;
900
		$ldapscope          = $authcfg['ldap_scope'];
901
	} else
902
		return false;
903

    
904
	$ldapdn             = $_SESSION['ldapdn'];
905

    
906
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
907
	$ldapgroupattribute = strtolower($ldapgroupattribute);
908
	$memberof = array();
909

    
910
        /* Setup CA environment if needed. */
911
        ldap_setup_caenv($authcfg);
912

    
913
	/* connect and see if server is up */
914
	$error = false;
915
	if (!($ldap = ldap_connect($ldapserver)))
916
		$error = true;
917

    
918
	if ($error == true) {
919
		log_error(sprintf(gettext("ERROR! ldap_get_groups() Could not connect to server %s."), $ldapname));
920
                return memberof;
921
        }
922
    
923
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
924
	ldap_set_option($ldap, LDAP_OPT_DEREF, LDAP_DEREF_SEARCHING);
925
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
926

    
927
	/* bind as user that has rights to read group attributes */
928
	if ($ldapanon == true) {
929
                if (!($res = @ldap_bind($ldap))) {
930
			log_error(sprintf(gettext("ERROR! ldap_get_groups() could not bind anonymously to server %s."), $ldapname));
931
			@ldap_close($ldap);
932
                        return false;
933
		}
934
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
935
		log_error(sprintf(gettext("ERROR! ldap_get_groups() could not bind to server %s."), $ldapname));
936
		@ldap_close($ldap);
937
		return memberof;
938
	}
939

    
940
	/* get groups from DN found */
941
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
942
	/* since we know the DN is in $_SESSION['ldapdn'] */
943
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
944
	if ($ldapscope == "one")
945
                $ldapfunc = "ldap_list";
946
        else
947
                $ldapfunc = "ldap_search";
948

    
949
	$search    = @$ldapfunc($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
950
	$info      = @ldap_get_entries($ldap, $search);
951

    
952
	$countem = $info["count"];	
953
	
954
	if(is_array($info[0][$ldapgroupattribute])) {
955
		/* Iterate through the groups and throw them into an array */
956
		foreach ($info[0][$ldapgroupattribute] as $member) {
957
			if (stristr($member, "CN=") !== false) {
958
				$membersplit = explode(",", $member);
959
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
960
			}
961
		}
962
	}
963
	
964
	/* Time to close LDAP connection */
965
	@ldap_unbind($ldap);
966
	
967
	$groups = print_r($memberof,true);
968
	
969
	//log_error("Returning groups ".$groups." for user $username");
970
	
971
	return $memberof;
972
}
973

    
974
function ldap_format_host($host) {
975
	return is_ipaddrv6($host) ? "[$host]" : $host ;
976
}
977

    
978
function ldap_backed($username, $passwd, $authcfg) {
979
	global $debug, $config;
980
	
981
	if(!$username) 
982
		return;
983

    
984
	if(!function_exists("ldap_connect"))
985
		return;
986

    
987
	if(stristr($username, "@")) {
988
		$username_split = explode("@", $username);
989
		$username = $username_split[0];        
990
	}
991
	if(stristr($username, "\\")) {
992
		$username_split = explode("\\", $username);
993
		$username = $username_split[0];        
994
	}
995

    
996
	if ($authcfg) {
997
		if (strstr($authcfg['ldap_urltype'], "Standard"))
998
			$ldapproto = "ldap";
999
		else
1000
			$ldapproto = "ldaps";
1001
		$ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
1002
		$ldapport	    = $authcfg['ldap_port'];
1003
		if (!empty($ldapport))
1004
			$ldapserver .= ":{$ldapport}";
1005
                $ldapbasedn         = $authcfg['ldap_basedn'];
1006
                $ldapbindun         = $authcfg['ldap_binddn'];
1007
                $ldapbindpw         = $authcfg['ldap_bindpw'];
1008
		if (empty($ldapbindun) || empty($ldapbindpw))
1009
			$ldapanon = true;
1010
		else
1011
			$ldapanon = false;
1012
                $ldapauthcont       = $authcfg['ldap_authcn'];
1013
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
1014
                $ldapextendedqueryenabled  = $authcfg['ldap_extended_enabled'];
1015
                $ldapextendedquery = $authcfg['ldap_extended_query'];
1016
                $ldapfilter         = "";
1017
                if(!$ldapextendedqueryenabled)
1018
                {
1019
                        $ldapfilter = "({$ldapnameattribute}={$username})";
1020
                }
1021
                else
1022
                {
1023
                        $ldapfilter = 
1024
"(&({$ldapnameattribute}={$username})({$ldapextendedquery}))";
1025
                } 
1026
                $ldaptype           = "";
1027
                $ldapver            = $authcfg['ldap_protver'];
1028
		$ldapname	    = $authcfg['name'];
1029
		$ldapscope	    = $authcfg['ldap_scope'];
1030
	} else
1031
		return false;
1032

    
1033
	/* first check if there is even an LDAP server populated */ 
1034
	if(!$ldapserver) {
1035
		if ($ldapfallback) {
1036
			log_error(gettext("ERROR! ldap_backed() called with no LDAP authentication server defined.  Defaulting to local user database. Visit System -> User Manager."));
1037
			return local_backed($username, $passwd);
1038
		} else
1039
			log_error(gettext("ERROR! ldap_backed() called with no LDAP authentication server defined."));
1040

    
1041
		return false;
1042
	}
1043
	
1044
        /* Setup CA environment if needed. */
1045
        ldap_setup_caenv($authcfg);
1046

    
1047
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
1048
	ldap_set_option($ldap, LDAP_OPT_DEREF, LDAP_DEREF_SEARCHING);
1049
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
1050

    
1051
	/* Make sure we can connect to LDAP */
1052
	$error = false;
1053
	if (!($ldap = ldap_connect($ldapserver)))
1054
		$error = true;
1055

    
1056
	if ($error == true) {
1057
		log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
1058
		return false;
1059
	}
1060

    
1061
	/* ok, its up.  now, lets bind as the bind user so we can search it */
1062
	$error = false;
1063
	if ($ldapanon == true) {
1064
                if (!($res = @ldap_bind($ldap)))
1065
                        $error = true;
1066
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
1067
		$error = true;
1068

    
1069
	if ($error == true) {
1070
		@ldap_close($ldap);
1071
		log_error(sprintf(gettext("ERROR! Could not bind to server %s."), $ldapname));
1072
		return false;
1073
	}
1074
	
1075
	/* Get LDAP Authcontainers and split em up. */
1076
	$ldac_splits = explode(";", $ldapauthcont);
1077
	
1078
	/* setup the usercount so we think we havn't found anyone yet */
1079
	$usercount  = 0;
1080

    
1081
	/*****************************************************************/
1082
	/*  We First find the user based on username and filter          */
1083
	/*  Then, once we find the first occurance of that person        */
1084
	/*  We set seesion variables to ponit to the OU and DN of the    */
1085
	/*  Person.  To later be used by ldap_get_groups.                */
1086
	/*  that way we don't have to search twice.                      */
1087
	/*****************************************************************/
1088
	if ($debug)
1089
		log_auth(sprintf(gettext("Now Searching for %s in directory."), $username));
1090
	/* Iterate through the user containers for search */
1091
	foreach ($ldac_splits as $i => $ldac_split) {
1092
		/* Make sure we just use the first user we find */
1093
		if ($debug)
1094
			log_auth(sprintf(gettext('Now Searching in server %1$s, container %2$s with filter %3$s.'), $ldapname, $ldac_split, $ldapfilter));
1095
		if ($ldapscope == "one")
1096
			$ldapfunc = "ldap_list";
1097
		else
1098
			$ldapfunc = "ldap_search";
1099
		/* Support legacy auth container specification. */
1100
		if (stristr($ldac_split, "DC=") || empty($ldapbasedn))
1101
			$search	 = @$ldapfunc($ldap,$ldac_split,$ldapfilter);
1102
		else
1103
			$search  = @$ldapfunc($ldap,"{$ldac_split},{$ldapbasedn}",$ldapfilter);
1104
		if (!$search) {
1105
			log_error(sprintf(gettext("Search resulted in error: %s"), ldap_error($ldap)));
1106
			continue;
1107
		}
1108
		$info	 = ldap_get_entries($ldap,$search);
1109
		$matches = $info['count'];
1110
		if ($matches == 1){
1111
			$userdn = $_SESSION['ldapdn'] = $info[0]['dn'];
1112
			$_SESSION['ldapou'] = $ldac_split[$i];
1113
			$_SESSION['ldapon'] = "true";
1114
			$usercount = 1;
1115
			break;
1116
		}
1117
	}
1118

    
1119
	if ($usercount != 1){
1120
		@ldap_unbind($ldap);
1121
		log_error(gettext("ERROR! Either LDAP search failed, or multiple users were found."));
1122
		return false;                         
1123
	}
1124

    
1125
	/* Now lets bind as the user we found */
1126
	if (!($res = @ldap_bind($ldap, $userdn, $passwd))) {
1127
		log_error(sprintf(gettext('ERROR! Could not login to server %1$s as user %2$s: %3$s'), $ldapname, $username, ldap_error($ldap)));
1128
		@ldap_unbind($ldap);
1129
		return false;
1130
	}
1131

    
1132
	if ($debug)
1133
		log_auth(sprintf(gettext('Logged in successfully as %1$s via LDAP server %2$s with DN = %3$s.'), $username, $ldapname, $userdn));
1134

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

    
1138
	return true;
1139
}
1140

    
1141
function radius_backed($username, $passwd, $authcfg, &$attributes = array()) {
1142
	global $debug, $config;
1143
	$ret = false;
1144

    
1145
	require_once("radius.inc");
1146

    
1147
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
1148
	if ($authcfg) {
1149
		$radiusservers = array();
1150
		$radiusservers[0]['ipaddr'] = $authcfg['host'];
1151
		$radiusservers[0]['port'] = $authcfg['radius_auth_port'];
1152
		$radiusservers[0]['sharedsecret'] = $authcfg['radius_secret'];
1153
		$radiusservers[0]['timeout'] = $authcfg['radius_timeout'];
1154
	} else
1155
		return false;
1156

    
1157
	/* Add a new servers to our instance */
1158
	foreach ($radiusservers as $radsrv) {
1159
		$timeout = (is_numeric($radsrv['timeout'])) ? $radsrv['timeout'] : 5;
1160
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret'], $timeout);
1161
	}
1162

    
1163
	if (PEAR::isError($rauth->start())) {
1164
		$retvalue['auth_val'] = 1;
1165
		$retvalue['error'] = $rauth->getError();
1166
		if ($debug)
1167
			printf(gettext("Radius start: %s<br>\n"), $retvalue['error']);
1168
	}
1169

    
1170
	// XXX - billm - somewhere in here we need to handle securid challenge/response
1171

    
1172
	/* Send request */
1173
	$result = $rauth->send();
1174
	if (PEAR::isError($result)) {
1175
		$retvalue['auth_val'] = 1;
1176
		$retvalue['error'] = $result->getMessage();
1177
		if ($debug)
1178
			printf(gettext("Radius send failed: %s<br>\n"), $retvalue['error']);
1179
	} else if ($result === true) {
1180
		if ($rauth->getAttributes())
1181
			$attributes = $rauth->listAttributes();
1182
		$retvalue['auth_val'] = 2;
1183
		if ($debug)
1184
			printf(gettext("Radius Auth succeeded")."<br>\n");
1185
		$ret = true;
1186
	} else {
1187
		$retvalue['auth_val'] = 3;
1188
		if ($debug)
1189
			printf(gettext("Radius Auth rejected")."<br>\n");
1190
	}
1191

    
1192
	// close OO RADIUS_AUTHENTICATION
1193
	$rauth->close();
1194

    
1195
	return $ret;
1196
}
1197

    
1198
function get_user_expiration_date($username) {
1199
	$user = getUserEntry($username);
1200
	if ($user['expires']) 
1201
		return $user['expires'];
1202
}
1203

    
1204
function is_account_expired($username) {
1205
	$expirydate = get_user_expiration_date($username);
1206
	if ($expirydate) {
1207
		if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($expirydate))))
1208
			return true;
1209
	}
1210

    
1211
	return false;
1212
}
1213

    
1214
function is_account_disabled($username) {
1215
	$user = getUserEntry($username);
1216
	if (isset($user['disabled']))
1217
		return true;
1218

    
1219
	return false;
1220
}
1221

    
1222
function auth_get_authserver($name) {
1223
        global $config;
1224

    
1225
        if (is_array($config['system']['authserver'])) {
1226
                foreach ($config['system']['authserver'] as $authcfg) {
1227
                        if ($authcfg['name'] == $name)
1228
                                return $authcfg;
1229
                }
1230
        }
1231
	if ($name == "Local Database")
1232
		return array("name" => gettext("Local Database"), "type" => "Local Auth", "host" => $config['system']['hostname']);
1233
}
1234

    
1235
function auth_get_authserver_list() {
1236
        global $config;
1237

    
1238
	$list = array();
1239

    
1240
        if (is_array($config['system']['authserver'])) {
1241
                foreach ($config['system']['authserver'] as $authcfg) {
1242
			/* Add support for disabled entries? */
1243
			$list[$authcfg['name']] = $authcfg;
1244
                }
1245
        }
1246

    
1247
	$list["Local Database"] = array( "name" => gettext("Local Database"), "type" => "Local Auth", "host" => $config['system']['hostname']);
1248
	return $list;
1249
}
1250

    
1251
function getUserGroups($username, $authcfg) {
1252
	global $config;
1253

    
1254
	$allowed_groups = array();
1255

    
1256
	switch($authcfg['type']) {
1257
        case 'ldap':
1258
		$allowed_groups = @ldap_get_groups($username, $authcfg);
1259
		break;
1260
	case 'radius':
1261
		break;
1262
	default:
1263
		$user = getUserEntry($username);
1264
		$allowed_groups = @local_user_get_groups($user, true);
1265
		break;
1266
	}
1267

    
1268
	$member_groups = array();
1269
        if (is_array($config['system']['group'])) {
1270
                foreach ($config['system']['group'] as $group)
1271
                        if (in_array($group['name'], $allowed_groups))
1272
				$member_groups[] = $group['name'];
1273
	}
1274

    
1275
	return $member_groups;
1276
}
1277

    
1278
function authenticate_user($username, $password, $authcfg = NULL, &$attributes = array()) {
1279

    
1280
	if (!$authcfg) {
1281
		return local_backed($username, $password);
1282
	}
1283

    
1284
	$authenticated = false;
1285
	switch($authcfg['type']) {
1286
        case 'ldap':
1287
                if (ldap_backed($username, $password, $authcfg))
1288
                        $authenticated = true;
1289
                break;
1290
        case 'radius':
1291
                if (radius_backed($username, $password, $authcfg, $attributes))
1292
                        $authenticated = true;
1293
                break;
1294
        default:
1295
                /* lookup user object by name */
1296
                if (local_backed($username, $password))
1297
                        $authenticated = true;
1298
                break;
1299
        }
1300

    
1301
	return $authenticated;
1302
}
1303

    
1304
function session_auth() {
1305
	global $HTTP_SERVER_VARS, $config, $_SESSION, $page;
1306

    
1307
	// Handle HTTPS httponly and secure flags
1308
	if($config['system']['webgui']['protocol'] == "https") {
1309
		$currentCookieParams = session_get_cookie_params();
1310
		session_set_cookie_params(
1311
			$currentCookieParams["lifetime"],
1312
			$currentCookieParams["path"],
1313
			NULL,
1314
			true,
1315
			true
1316
		);
1317
	}
1318

    
1319
	if (!session_id())
1320
		session_start();
1321

    
1322
	/* Validate incoming login request */
1323
	if (isset($_POST['login']) && !empty($_POST['usernamefld']) && !empty($_POST['passwordfld'])) {
1324
		$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
1325
		if (authenticate_user($_POST['usernamefld'], $_POST['passwordfld'], $authcfg) || 
1326
		    authenticate_user($_POST['usernamefld'], $_POST['passwordfld'])) {
1327
			$_SESSION['Logged_In'] = "True";
1328
			$_SESSION['Username'] = $_POST['usernamefld'];
1329
			$_SESSION['last_access'] = time();
1330
			if(! isset($config['system']['webgui']['quietlogin'])) {
1331
				log_auth(sprintf(gettext("Successful login for user '%1\$s' from: %2\$s"), $_POST['usernamefld'], $_SERVER['REMOTE_ADDR']));
1332
			}
1333
			$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1334
			if (isset($_POST['postafterlogin']))
1335
				return true;
1336
			else {
1337
				if (empty($page))
1338
					$page = "/";
1339
				header("Location: {$page}");
1340
			}
1341
			exit;
1342
		} else {
1343
			/* give the user an error message */
1344
			$_SESSION['Login_Error'] = "Username or Password incorrect";
1345
			log_auth("webConfigurator authentication error for '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}");
1346
			if(isAjax()) {
1347
				echo "showajaxmessage('{$_SESSION['Login_Error']}');";
1348
				return;
1349
			}
1350
		}
1351
	}
1352

    
1353
	/* Show login page if they aren't logged in */
1354
	if (empty($_SESSION['Logged_In']))
1355
		return false;
1356

    
1357
	/* If session timeout isn't set, we don't mark sessions stale */
1358
	if (!isset($config['system']['webgui']['session_timeout'])) {
1359
		/* Default to 4 hour timeout if one is not set */
1360
		if ($_SESSION['last_access'] < (time() - 14400)) {
1361
			$_GET['logout'] = true;
1362
			$_SESSION['Logout'] = true;
1363
		} else
1364
			$_SESSION['last_access'] = time();	
1365
	} else if (intval($config['system']['webgui']['session_timeout']) == 0) {
1366
		/* only update if it wasn't ajax */
1367
		if (!isAjax())
1368
			$_SESSION['last_access'] = time();
1369
	} else {
1370
		/* Check for stale session */
1371
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
1372
			$_GET['logout'] = true;
1373
			$_SESSION['Logout'] = true;
1374
		} else {
1375
			/* only update if it wasn't ajax */
1376
			if (!isAjax())
1377
				$_SESSION['last_access'] = time();
1378
		}
1379
	}
1380

    
1381
	/* user hit the logout button */
1382
	if (isset($_GET['logout'])) {
1383

    
1384
		if ($_SESSION['Logout'])
1385
			log_error(sprintf(gettext("Session timed out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1386
		else
1387
			log_error(sprintf(gettext("User logged out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1388

    
1389
		/* wipe out $_SESSION */
1390
		$_SESSION = array();
1391

    
1392
		if (isset($_COOKIE[session_name()]))
1393
			setcookie(session_name(), '', time()-42000, '/');
1394

    
1395
		/* and destroy it */
1396
		session_destroy();
1397

    
1398
		$scriptName = explode("/", $_SERVER["SCRIPT_FILENAME"]);
1399
		$scriptElms = count($scriptName);
1400
		$scriptName = $scriptName[$scriptElms-1];
1401

    
1402
		if (isAjax())
1403
			return false;
1404

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

    
1408
		return false;
1409
	}
1410

    
1411
	/*
1412
	 * this is for debugging purpose if you do not want to use Ajax
1413
	 * to submit a HTML form. It basically diables the observation
1414
	 * of the submit event and hence does not trigger Ajax.
1415
	 */
1416
	if ($_GET['disable_ajax'])
1417
		$_SESSION['NO_AJAX'] = "True";
1418

    
1419
	/*
1420
	 * Same to re-enable Ajax.
1421
	 */
1422
	if ($_GET['enable_ajax'])
1423
		unset($_SESSION['NO_AJAX']);
1424

    
1425
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1426
	return true;
1427
}
1428

    
1429
?>
(5-5/66)