Project

General

Profile

Download (42.4 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/{$authcfg['name']}.ca"))
691
			@unlink("{$g['varrun_path']}/certs/{$authcfg['name']}.ca");
692
		file_put_contents("{$g['varrun_path']}/certs/{$authcfg['name']}.ca", base64_decode($caref['crt']));
693
		@chmod("{$g['varrun_path']}/certs/{$authcfg['name']}.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/{$authcfg['name']}.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_PROTOCOL_VERSION, (int)$ldapver);
743
 
744
	if ($ldapanon == true) {
745
		if (!($res = @ldap_bind($ldap))) {
746
			@ldap_close($ldap);
747
			return false;
748
		}
749
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
750
		@ldap_close($ldap);
751
		return false;
752
	}
753

    
754
	@ldap_unbind($ldap);
755

    
756
	return true;
757
}
758

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

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

    
765
	$ous = array();
766

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

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

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

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

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

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

    
811
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
812
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
813

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

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

    
831
	$search = @$ldapfunc($ldap, $ldapbasedn, $ldapfilter);
832
	$info = @ldap_get_entries($ldap, $search);
833

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

    
849
	@ldap_unbind($ldap);
850

    
851
	return $ous;
852
}
853

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

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

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

    
902
	$ldapdn             = $_SESSION['ldapdn'];
903

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

    
908
        /* Setup CA environment if needed. */
909
        ldap_setup_caenv($authcfg);
910

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

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

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

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

    
946
	$search    = @$ldapfunc($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
947
	$info      = @ldap_get_entries($ldap, $search);
948

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

    
971
function ldap_format_host($host) {
972
	return is_ipaddrv6($host) ? "[$host]" : $host ;
973
}
974

    
975
function ldap_backed($username, $passwd, $authcfg) {
976
	global $debug, $config;
977
	
978
	if(!$username) 
979
		return;
980

    
981
	if(!function_exists("ldap_connect"))
982
		return;
983

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

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

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

    
1038
		return false;
1039
	}
1040
	
1041
        /* Setup CA environment if needed. */
1042
        ldap_setup_caenv($authcfg);
1043

    
1044
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
1045
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
1046

    
1047
	/* Make sure we can connect to LDAP */
1048
	$error = false;
1049
	if (!($ldap = ldap_connect($ldapserver)))
1050
		$error = true;
1051

    
1052
	if ($error == true) {
1053
		log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
1054
		return false;
1055
	}
1056

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

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

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

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

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

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

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

    
1134
	return true;
1135
}
1136

    
1137
function radius_backed($username, $passwd, $authcfg, &$attributes = array()) {
1138
	global $debug, $config;
1139
	$ret = false;
1140

    
1141
	require_once("radius.inc");
1142

    
1143
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
1144
	if ($authcfg) {
1145
		$radiusservers = array();
1146
		$radiusservers[0]['ipaddr'] = $authcfg['host'];
1147
		$radiusservers[0]['port'] = $authcfg['radius_auth_port'];
1148
		$radiusservers[0]['sharedsecret'] = $authcfg['radius_secret'];
1149
	} else
1150
		return false;
1151

    
1152
	/* Add a new servers to our instance */
1153
	foreach ($radiusservers as $radsrv)
1154
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
1155

    
1156
	if (PEAR::isError($rauth->start())) {
1157
		$retvalue['auth_val'] = 1;
1158
		$retvalue['error'] = $rauth->getError();
1159
		if ($debug)
1160
			printf(gettext("Radius start: %s<br>\n"), $retvalue['error']);
1161
	}
1162

    
1163
	// XXX - billm - somewhere in here we need to handle securid challenge/response
1164

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

    
1185
	// close OO RADIUS_AUTHENTICATION
1186
	$rauth->close();
1187

    
1188
	return $ret;
1189
}
1190

    
1191
function get_user_expiration_date($username) {
1192
	$user = getUserEntry($username);
1193
	if ($user['expires']) 
1194
		return $user['expires'];
1195
}
1196

    
1197
function is_account_expired($username) {
1198
	$expirydate = get_user_expiration_date($username);
1199
	if ($expirydate) {
1200
		if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($expirydate))))
1201
			return true;
1202
	}
1203

    
1204
	return false;
1205
}
1206

    
1207
function is_account_disabled($username) {
1208
	$user = getUserEntry($username);
1209
	if (isset($user['disabled']))
1210
		return true;
1211

    
1212
	return false;
1213
}
1214

    
1215
function auth_get_authserver($name) {
1216
        global $config;
1217

    
1218
        if (is_array($config['system']['authserver'])) {
1219
                foreach ($config['system']['authserver'] as $authcfg) {
1220
                        if ($authcfg['name'] == $name)
1221
                                return $authcfg;
1222
                }
1223
        }
1224
	if ($name == "Local Database")
1225
		return array("name" => gettext("Local Database"), "type" => gettext("Local Auth"), "host" => $config['system']['hostname']);
1226
}
1227

    
1228
function auth_get_authserver_list() {
1229
        global $config;
1230

    
1231
	$list = array();
1232

    
1233
        if (is_array($config['system']['authserver'])) {
1234
                foreach ($config['system']['authserver'] as $authcfg) {
1235
			/* Add support for disabled entries? */
1236
			$list[$authcfg['name']] = $authcfg;
1237
                }
1238
        }
1239

    
1240
	$list["Local Database"] = array( "name" => gettext("Local Database"), "type" => gettext("Local Auth"), "host" => $config['system']['hostname']);
1241
	return $list;
1242
}
1243

    
1244
function getUserGroups($username, $authcfg) {
1245
	global $config;
1246

    
1247
	$allowed_groups = array();
1248

    
1249
	switch($authcfg['type']) {
1250
        case 'ldap':
1251
		$allowed_groups = @ldap_get_groups($username, $authcfg);
1252
		break;
1253
	case 'radius':
1254
		break;
1255
	default:
1256
		$user = getUserEntry($username);
1257
		$allowed_groups = @local_user_get_groups($user, true);
1258
		break;
1259
	}
1260

    
1261
	$member_groups = array();
1262
        if (is_array($config['system']['group'])) {
1263
                foreach ($config['system']['group'] as $group)
1264
                        if (in_array($group['name'], $allowed_groups))
1265
				$member_groups[] = $group['name'];
1266
	}
1267

    
1268
	return $member_groups;
1269
}
1270

    
1271
function authenticate_user($username, $password, $authcfg = NULL, &$attributes = array()) {
1272

    
1273
	if (!$authcfg) {
1274
		return local_backed($username, $password);
1275
	}
1276

    
1277
	$authenticated = false;
1278
	switch($authcfg['type']) {
1279
        case 'ldap':
1280
                if (ldap_backed($username, $password, $authcfg))
1281
                        $authenticated = true;
1282
                break;
1283
        case 'radius':
1284
                if (radius_backed($username, $password, $authcfg, $attributes))
1285
                        $authenticated = true;
1286
                break;
1287
        default:
1288
                /* lookup user object by name */
1289
                if (local_backed($username, $password))
1290
                        $authenticated = true;
1291
                break;
1292
        }
1293

    
1294
	return $authenticated;
1295
}
1296

    
1297
function session_auth() {
1298
	global $HTTP_SERVER_VARS, $config, $_SESSION, $page;
1299

    
1300
	// Handle HTTPS httponly and secure flags
1301
	if($config['system']['webgui']['protocol'] == "https") {
1302
		$currentCookieParams = session_get_cookie_params();
1303
		session_set_cookie_params(
1304
			$currentCookieParams["lifetime"],
1305
			$currentCookieParams["path"],
1306
			NULL,
1307
			true,
1308
			true
1309
		);
1310
	}
1311

    
1312
	if (!session_id())
1313
		session_start();
1314

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

    
1346
	/* Show login page if they aren't logged in */
1347
	if (empty($_SESSION['Logged_In']))
1348
		return false;
1349

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

    
1374
	/* user hit the logout button */
1375
	if (isset($_GET['logout'])) {
1376

    
1377
		if ($_SESSION['Logout'])
1378
			log_error(sprintf(gettext("Session timed out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1379
		else
1380
			log_error(sprintf(gettext("User logged out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1381

    
1382
		/* wipe out $_SESSION */
1383
		$_SESSION = array();
1384

    
1385
		if (isset($_COOKIE[session_name()]))
1386
			setcookie(session_name(), '', time()-42000, '/');
1387

    
1388
		/* and destroy it */
1389
		session_destroy();
1390

    
1391
		$scriptName = explode("/", $_SERVER["SCRIPT_FILENAME"]);
1392
		$scriptElms = count($scriptName);
1393
		$scriptName = $scriptName[$scriptElms-1];
1394

    
1395
		if (isAjax())
1396
			return false;
1397

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

    
1401
		return false;
1402
	}
1403

    
1404
	/*
1405
	 * this is for debugging purpose if you do not want to use Ajax
1406
	 * to submit a HTML form. It basically diables the observation
1407
	 * of the submit event and hence does not trigger Ajax.
1408
	 */
1409
	if ($_GET['disable_ajax'])
1410
		$_SESSION['NO_AJAX'] = "True";
1411

    
1412
	/*
1413
	 * Same to re-enable Ajax.
1414
	 */
1415
	if ($_GET['enable_ajax'])
1416
		unset($_SESSION['NO_AJAX']);
1417

    
1418
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1419
	return true;
1420
}
1421

    
1422
?>
(5-5/68)