Project

General

Profile

Download (42.1 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}://{$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}://{$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}://{$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}://{$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_backed($username, $passwd, $authcfg) {
972
	global $debug, $config;
973
	
974
	if(!$username) 
975
		return;
976

    
977
	if(!function_exists("ldap_connect"))
978
		return;
979

    
980
	if(stristr($username, "@")) {
981
		$username_split = explode("@", $username);
982
		$username = $username_split[0];        
983
	}
984
	if(stristr($username, "\\")) {
985
		$username_split = explode("\\", $username);
986
		$username = $username_split[0];        
987
	}
988

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

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

    
1034
		return false;
1035
	}
1036
	
1037
        /* Setup CA environment if needed. */
1038
        ldap_setup_caenv($authcfg);
1039

    
1040
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
1041
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
1042

    
1043
	/* Make sure we can connect to LDAP */
1044
	$error = false;
1045
	if (!($ldap = ldap_connect($ldapserver)))
1046
		$error = true;
1047

    
1048
	if ($error == true) {
1049
		log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
1050
		return false;
1051
	}
1052

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

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

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

    
1109
	if ($usercount != 1){
1110
		@ldap_unbind($ldap);
1111
		log_error(gettext("ERROR! Either LDAP search failed, or multiple users were found."));
1112
		return false;                         
1113
	}
1114

    
1115
	/* Now lets bind as the user we found */
1116
	if (!($res = @ldap_bind($ldap, $userdn, $passwd))) {
1117
		log_error(sprintf(gettext('ERROR! Could not login to server %1$s as user %2$s.'), $ldapname, $username));
1118
		@ldap_unbind($ldap);
1119
		return false;
1120
	}
1121

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

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

    
1127
	return true;
1128
}
1129

    
1130
function radius_backed($username, $passwd, $authcfg){
1131
	global $debug, $config;
1132
	$ret = false;
1133

    
1134
	require_once("radius.inc");
1135

    
1136
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
1137
	if ($authcfg) {
1138
		$radiusservers = array();
1139
		$radiusservers[0]['ipaddr'] = $authcfg['host'];
1140
		$radiusservers[0]['port'] = $authcfg['radius_auth_port'];
1141
		$radiusservers[0]['sharedsecret'] = $authcfg['radius_secret'];
1142
	} else
1143
		return false;
1144

    
1145
	/* Add a new servers to our instance */
1146
	foreach ($radiusservers as $radsrv)
1147
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
1148

    
1149
	if (PEAR::isError($rauth->start())) {
1150
		$retvalue['auth_val'] = 1;
1151
		$retvalue['error'] = $rauth->getError();
1152
		if ($debug)
1153
			printf(gettext("Radius start: %s<br>\n"), $retvalue['error']);
1154
	}
1155

    
1156
	// XXX - billm - somewhere in here we need to handle securid challenge/response
1157

    
1158
	/* Send request */
1159
	$result = $rauth->send();
1160
	if (PEAR::isError($result)) {
1161
		$retvalue['auth_val'] = 1;
1162
		$retvalue['error'] = $result->getMessage();
1163
		if ($debug)
1164
			printf(gettext("Radius send failed: %s<br>\n"), $retvalue['error']);
1165
	} else if ($result === true) {
1166
		$retvalue['auth_val'] = 2;
1167
		if ($debug)
1168
			printf(gettext("Radius Auth succeeded")."<br>\n");
1169
		$ret = true;
1170
	} else {
1171
		$retvalue['auth_val'] = 3;
1172
		if ($debug)
1173
			printf(gettext("Radius Auth rejected")."<br>\n");
1174
	}
1175

    
1176
	// close OO RADIUS_AUTHENTICATION
1177
	$rauth->close();
1178

    
1179
	return $ret;
1180
}
1181

    
1182
function get_user_expiration_date($username) {
1183
	$user = getUserEntry($username);
1184
	if ($user['expires']) 
1185
		return $user['expires'];
1186
}
1187

    
1188
function is_account_expired($username) {
1189
	$expirydate = get_user_expiration_date($username);
1190
	if ($expirydate) {
1191
		if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($expirydate))))
1192
			return true;
1193
	}
1194

    
1195
	return false;
1196
}
1197

    
1198
function is_account_disabled($username) {
1199
	$user = getUserEntry($username);
1200
	if (isset($user['disabled']))
1201
		return true;
1202

    
1203
	return false;
1204
}
1205

    
1206
function auth_get_authserver($name) {
1207
        global $config;
1208

    
1209
        if (is_array($config['system']['authserver'])) {
1210
                foreach ($config['system']['authserver'] as $authcfg) {
1211
                        if ($authcfg['name'] == $name)
1212
                                return $authcfg;
1213
                }
1214
        }
1215
	if ($name == "Local Database")
1216
		return array("name" => gettext("Local Database"), "type" => gettext("Local Auth"), "host" => $config['system']['hostname']);
1217
}
1218

    
1219
function auth_get_authserver_list() {
1220
        global $config;
1221

    
1222
	$list = array();
1223

    
1224
        if (is_array($config['system']['authserver'])) {
1225
                foreach ($config['system']['authserver'] as $authcfg) {
1226
			/* Add support for disabled entries? */
1227
			$list[$authcfg['name']] = $authcfg;
1228
                }
1229
        }
1230

    
1231
	$list["Local Database"] = array( "name" => gettext("Local Database"), "type" => gettext("Local Auth"), "host" => $config['system']['hostname']);
1232
	return $list;
1233
}
1234

    
1235
function getUserGroups($username, $authcfg) {
1236
	global $config;
1237

    
1238
	$allowed_groups = array();
1239

    
1240
	switch($authcfg['type']) {
1241
        case 'ldap':
1242
		$allowed_groups = @ldap_get_groups($username, $authcfg);
1243
		break;
1244
	case 'radius':
1245
		break;
1246
	default:
1247
		$user = getUserEntry($username);
1248
		$allowed_groups = @local_user_get_groups($user, true);
1249
		break;
1250
	}
1251

    
1252
	$member_groups = array();
1253
        if (is_array($config['system']['group'])) {
1254
                foreach ($config['system']['group'] as $group)
1255
                        if (in_array($group['name'], $allowed_groups))
1256
				$member_groups[] = $group['name'];
1257
	}
1258

    
1259
	return $member_groups;
1260
}
1261

    
1262
function authenticate_user($username, $password, $authcfg = NULL) {
1263

    
1264
	if (!$authcfg) {
1265
		return local_backed($username, $password);
1266
	}
1267

    
1268
	$authenticated = false;
1269
	switch($authcfg['type']) {
1270
        case 'ldap':
1271
                if (ldap_backed($username, $password, $authcfg))
1272
                        $authenticated = true;
1273
                break;
1274
        case 'radius':
1275
                if (radius_backed($username, $password, $authcfg))
1276
                        $authenticated = true;
1277
                break;
1278
        default:
1279
                /* lookup user object by name */
1280
                if (local_backed($username, $password))
1281
                        $authenticated = true;
1282
                break;
1283
        }
1284

    
1285
	return $authenticated;
1286
}
1287

    
1288
function session_auth() {
1289
	global $HTTP_SERVER_VARS, $config, $_SESSION, $page;
1290

    
1291
	// Handle HTTPS httponly and secure flags
1292
	if($config['system']['webgui']['protocol'] == "https") {
1293
		$currentCookieParams = session_get_cookie_params();
1294
		session_set_cookie_params(
1295
			$currentCookieParams["lifetime"],
1296
			$currentCookieParams["path"],
1297
			NULL,
1298
			true,
1299
			true
1300
		);
1301
	}
1302

    
1303
	if (!session_id())
1304
		session_start();
1305

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

    
1337
	/* Show login page if they aren't logged in */
1338
	if (empty($_SESSION['Logged_In']))
1339
		return false;
1340

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

    
1365
	/* user hit the logout button */
1366
	if (isset($_GET['logout'])) {
1367

    
1368
		if ($_SESSION['Logout'])
1369
			log_error(sprintf(gettext("Session timed out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1370
		else
1371
			log_error(sprintf(gettext("User logged out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1372

    
1373
		/* wipe out $_SESSION */
1374
		$_SESSION = array();
1375

    
1376
		if (isset($_COOKIE[session_name()]))
1377
			setcookie(session_name(), '', time()-42000, '/');
1378

    
1379
		/* and destroy it */
1380
		session_destroy();
1381

    
1382
		$scriptName = explode("/", $_SERVER["SCRIPT_FILENAME"]);
1383
		$scriptElms = count($scriptName);
1384
		$scriptName = $scriptName[$scriptElms-1];
1385

    
1386
		if (isAjax())
1387
			return false;
1388

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

    
1392
		return false;
1393
	}
1394

    
1395
	/*
1396
	 * this is for debugging purpose if you do not want to use Ajax
1397
	 * to submit a HTML form. It basically diables the observation
1398
	 * of the submit event and hence does not trigger Ajax.
1399
	 */
1400
	if ($_GET['disable_ajax'])
1401
		$_SESSION['NO_AJAX'] = "True";
1402

    
1403
	/*
1404
	 * Same to re-enable Ajax.
1405
	 */
1406
	if ($_GET['enable_ajax'])
1407
		unset($_SESSION['NO_AJAX']);
1408

    
1409
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1410
	return true;
1411
}
1412

    
1413
Header("X-Frame-Options: SAMEORIGIN");
1414

    
1415
?>
(5-5/65)