Project

General

Profile

Download (40.3 KB) Statistics
| Branch: | Tag: | Revision:
1 55eb9c44 --global
<?php
2
/* $Id$ */
3
/*
4 8a6b0fbe Ermal Lu?i
	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 55eb9c44 --global
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 523855b0 Scott Ullrich
		pfSense_BUILDER_BINARIES:	/usr/sbin/pw	/bin/cp
42
		pfSense_MODULE:	auth
43 55eb9c44 --global
*/
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 052e65ef Scott Ullrich
if(!$do_not_include_config_gui_inc)
50
	require_once("config.gui.inc");
51 55eb9c44 --global
52 9ae11a62 Scott Ullrich
// Will be changed to false if security checks fail
53
$security_passed = true;
54
55 0321fa1b jim-p
/* 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 14eab6fb jim-p
if (function_exists("display_error_form") && !isset($config['system']['webgui']['nodnsrebindcheck'])) {
58 0321fa1b jim-p
	/* DNS ReBinding attack prevention.  http://redmine.pfsense.org/issues/708 */
59
	$found_host = false;
60 7319dc73 jim-p
	if(strstr($_SERVER['HTTP_HOST'], ":")) {
61
		$http_host_port = explode(":", $_SERVER['HTTP_HOST']);
62
		$http_host = $http_host_port[0];
63
	} else {
64
		$http_host = $_SERVER['HTTP_HOST'];
65
	}
66 f17f9f28 jim-p
	if(is_ipaddr($http_host) or $_SERVER['SERVER_ADDR'] == "127.0.0.1" or
67 9ae11a62 Scott Ullrich
			strcasecmp($http_host, "localhost") == 0)
68
		$found_host = true;
69
	if(strcasecmp($http_host, $config['system']['hostname'] . "." . $config['system']['domain']) == 0 or
70
			strcasecmp($http_host, $config['system']['hostname']) == 0)
71 d7bf3178 Erik Fonnesbeck
		$found_host = true;
72 9ae11a62 Scott Ullrich
73
	if(is_array($config['dyndnses']['dyndns']) && !$found_host)
74 0321fa1b jim-p
		foreach($config['dyndnses']['dyndns'] as $dyndns)
75 9ae11a62 Scott Ullrich
			if(strcasecmp($dyndns['host'], $http_host) == 0) {
76 0321fa1b jim-p
				$found_host = true;
77 9ae11a62 Scott Ullrich
				break;
78
			}
79 7319dc73 jim-p
80 9ae11a62 Scott Ullrich
	if(!empty($config['system']['webgui']['althostnames']) && !$found_host) {
81 86b21903 jim-p
		$althosts = explode(" ", $config['system']['webgui']['althostnames']);
82
		foreach ($althosts as $ah)
83 9ae11a62 Scott Ullrich
			if(strcasecmp($ah, $http_host) == 0 or strcasecmp($ah, $_SERVER['SERVER_ADDR']) == 0) {
84 86b21903 jim-p
				$found_host = true;
85 9ae11a62 Scott Ullrich
				break;
86
			}
87 9b13f84b Scott Ullrich
	}
88 ce46b5da Scott Ullrich
89 9ae11a62 Scott Ullrich
	if($found_host == false) {
90
		if(!security_checks_disabled()) {
91
			display_error_form("501", "Potential DNS Rebind attack detected, see http://en.wikipedia.org/wiki/DNS_rebinding<br/>Try accessing the router by IP address instead of by hostname.");
92
			exit;
93
		}
94
		$security_passed = false;
95
	}
96
}
97 ef173724 Scott Ullrich
98 9ae11a62 Scott Ullrich
// If the HTTP_REFERER is something other than ourselves then disallow.
99
if(function_exists("display_error_form") && !isset($config['system']['webgui']['nohttpreferercheck'])) {
100
	if($_SERVER['HTTP_REFERER']) {
101
		if(file_exists("{$g['tmp_path']}/setupwizard_lastreferrer")) {
102
			if($_SERVER['HTTP_REFERER'] == file_get_contents("{$g['tmp_path']}/setupwizard_lastreferrer")) {
103
				unlink("{$g['tmp_path']}/setupwizard_lastreferrer");
104
				header("Refresh: 1; url=index.php");
105
				echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
106
				echo "<html><head><title>" . gettext("Redirecting...") . "</title></head><body>" . gettext("Redirecting to the dashboard...") . "</body></html>";
107
				exit;
108
			}
109
		}
110
		$found_host = false;
111
		$referrer_host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
112
		if($referrer_host) {
113
			if(strcasecmp($referrer_host, $config['system']['hostname'] . "." . $config['system']['domain']) == 0
114
					|| strcasecmp($referrer_host, $config['system']['hostname']) == 0)
115
				$found_host = true;
116
			if(!empty($config['system']['webgui']['althostnames']) && !$found_host) {
117
				$althosts = explode(" ", $config['system']['webgui']['althostnames']);
118
				foreach ($althosts as $ah) {
119
					if(strcasecmp($referrer_host, $ah) == 0) {
120
						$found_host = true;
121
						break;
122
					}
123
				}
124
			}
125
			if(!$found_host) {
126
				$interface_list_ips = get_configured_ip_addresses();
127
				foreach($interface_list_ips as $ilips) {
128
					if(strcasecmp($referrer_host, $ilips) == 0) {
129
						$found_host = true;
130
						break;
131
					}
132
				}
133 17dd7ff3 Chris Buechler
				if($referrer_host == "127.0.0.1" || $referrer_host == "localhost") {
134
					// allow SSH port forwarded connections and links from localhost
135
					$found_host = true;
136
				}
137 9ae11a62 Scott Ullrich
			}
138
		}
139 4fe9c2dc Scott Ullrich
		if($found_host == false) {
140 9ae11a62 Scott Ullrich
			if(!security_checks_disabled()) {
141
				display_error_form("501", "An HTTP_REFERER was detected other than what is defined in System -> Advanced (" . htmlspecialchars($_SERVER['HTTP_REFERER']) . ").  You can disable this check if needed in System -> Advanced -> Admin.");
142 0f806eca Erik Fonnesbeck
				exit;
143
			}
144 9ae11a62 Scott Ullrich
			$security_passed = false;
145
		}
146
	} else
147
		$security_passed = false;
148 4fe9c2dc Scott Ullrich
}
149
150 9ae11a62 Scott Ullrich
if (function_exists("display_error_form") && $security_passed)
151
	/* Security checks passed, so it should be OK to turn them back on */
152
	restore_security_checks();
153
unset($security_passed);
154
155 55eb9c44 --global
$groupindex = index_groups();
156
$userindex = index_users();
157
158
function index_groups() {
159
	global $g, $debug, $config, $groupindex;
160
161
	$groupindex = array();
162
163 6dcd80af Ermal
	if (is_array($config['system']['group'])) {
164 55eb9c44 --global
		$i = 0;
165
		foreach($config['system']['group'] as $groupent) {
166
			$groupindex[$groupent['name']] = $i;
167
			$i++;
168
		}
169
	}
170
171
	return ($groupindex);
172
}
173
174
function index_users() {
175
	global $g, $debug, $config;
176
177 6dcd80af Ermal
	if (is_array($config['system']['user'])) {
178 55eb9c44 --global
		$i = 0;
179
		foreach($config['system']['user'] as $userent) {
180
			$userindex[$userent['name']] = $i;
181
			$i++;
182
		}
183
	}
184
185
	return ($userindex);
186
}
187
188
function & getUserEntry($name) {
189
	global $debug, $config, $userindex;
190
	if (isset($userindex[$name]))
191
		return $config['system']['user'][$userindex[$name]];
192
}
193
194
function & getUserEntryByUID($uid) {
195
	global $debug, $config;
196 84924e76 Ermal
197
	if (is_array($config['system']['user']))
198
		foreach ($config['system']['user'] as & $user)
199
			if ($user['uid'] == $uid)
200
				return $user;
201 55eb9c44 --global
202
	return false;
203
}
204
205
function & getGroupEntry($name) {
206
	global $debug, $config, $groupindex;
207
	if (isset($groupindex[$name]))
208
		return $config['system']['group'][$groupindex[$name]];
209
}
210
211
function & getGroupEntryByGID($gid) {
212
	global $debug, $config;
213 84924e76 Ermal
214
	if (is_array($config['system']['group']))
215
		foreach ($config['system']['group'] as & $group)
216
			if ($group['gid'] == $gid)
217
				return $group;
218 55eb9c44 --global
219
	return false;
220
}
221
222 6dc88d53 Ermal Luci
function get_user_privileges(& $user) {
223
224
        $privs = $user['priv'];
225
        if (!is_array($privs))
226
                $privs = array();
227
228
        $names = local_user_get_groups($user, true);
229
230
        foreach ($names as $name) {
231
                $group = getGroupEntry($name);
232
                if (is_array($group['priv']))
233
                        $privs = array_merge( $privs, $group['priv']);
234
        }
235
236
        return $privs;
237
}
238
239
function userHasPrivilege($userent, $privid = false) {
240
241
        if (!$privid || !is_array($userent))
242
                return false;
243
244
        $privs = get_user_privileges($userent);
245
246
        if (!is_array($privs))
247
                return false;
248
249
        if (!in_array($privid, $privs))
250
                return false;
251
252
        return true;
253
}
254
255 55eb9c44 --global
function local_backed($username, $passwd) {
256
257
	$user = getUserEntry($username);
258
	if (!$user)
259
		return false;
260
261 6306b5dd Ermal Lu?i
	if (is_account_disabled($username) || is_account_expired($username))
262 a13ce628 Ermal Lu?i
		return false;
263
264 55eb9c44 --global
	if ($user['password'])
265
	{
266
		$passwd = crypt($passwd, $user['password']);
267
		if ($passwd == $user['password'])
268
			return true;
269
	}
270
271
	if ($user['md5-hash'])
272
	{
273
		$passwd = md5($passwd);
274
		if ($passwd == $user['md5-hash'])
275
			return true;
276
	}
277
278
	return false;
279
}
280
281
function local_sync_accounts() {
282
	global $debug, $config;
283
	conf_mount_rw();
284
285
	/* remove local users to avoid uid conflicts */
286
	$fd = popen("/usr/sbin/pw usershow -a", "r");
287
	if ($fd) {
288
		while (!feof($fd)) {
289
			$line = explode(":",fgets($fd));
290 b357f0a6 jim-p
			if (((!strncmp($line[0], "_", 1)) || ($line[2] < 2000) || ($line[2] > 65000)) && ($line[0] != "admin"))
291 55eb9c44 --global
				continue;
292 b357f0a6 jim-p
			$cmd = "/usr/sbin/pw userdel -n '{$line[0]}'";
293 55eb9c44 --global
			if($debug)
294
				log_error("Running: {$cmd}");
295
			mwexec($cmd);
296
		}
297
		pclose($fd);
298
	}
299
300
	/* remove local groups to avoid gid conflicts */
301
	$gids = array();
302
	$fd = popen("/usr/sbin/pw groupshow -a", "r");
303
	if ($fd) {
304
		while (!feof($fd)) {
305
			$line = explode(":",fgets($fd));
306
			if (!strncmp($line[0], "_", 1))
307
				continue;
308
			if ($line[2] < 2000)
309
				continue;
310
			if ($line[2] > 65000)
311
				continue;
312
			$cmd = "/usr/sbin/pw groupdel {$line[2]}";
313
			if($debug)
314
				log_error("Running: {$cmd}");
315
			mwexec($cmd);
316
		}
317
		pclose($fd);
318
	}
319
320
	/* make sure the all group exists */
321
	$allgrp = getGroupEntryByGID(1998);
322
	local_group_set($allgrp, true);
323
324 5af2baf7 jim-p
	/* sync all local users */
325
	if (is_array($config['system']['user']))
326
		foreach ($config['system']['user'] as $user)
327
			local_user_set($user);
328
329 f3e0a111 jim-p
	/* sync all local groups */
330
	if (is_array($config['system']['group']))
331
		foreach ($config['system']['group'] as $group)
332
			local_group_set($group);
333
334 55eb9c44 --global
	conf_mount_ro();
335
336
}
337
338
function local_user_set(& $user) {
339
	global $g, $debug;
340
341 b015aa8c Ermal
	if (empty($user['password'])) {
342
		log_error("There is something wrong in your config because user {$user['name']} password is missing!");
343
		return;
344
	}
345
346 2bb07efc Scott Ullrich
	conf_mount_rw();
347
348 55eb9c44 --global
	$home_base = "/home/";	
349
	$user_uid = $user['uid'];
350
	$user_name = $user['name'];
351 461df7c0 jim-p
	$user_home = "{$home_base}{$user_name}";
352 55eb9c44 --global
	$user_shell = "/etc/rc.initial";
353
	$user_group = "nobody";
354
355
	// Ensure $home_base exists and is writable
356
	if (!is_dir($home_base)) 
357
		mkdir($home_base, 0755);
358
359 df8d74de jim-p
	$lock_account = false;
360 55eb9c44 --global
	/* configure shell type */
361 3e251b12 Erik Fonnesbeck
	/* Cases here should be ordered by most privileged to least privileged. */
362 a137fedd jim-p
	if (userHasPrivilege($user, "user-shell-access") || userHasPrivilege($user, "page-all")) {
363 29293dce jim-p
		$user_shell = "/bin/tcsh";
364 1ed86bc6 jim-p
	} elseif (userHasPrivilege($user, "user-copy-files")) {
365 a137fedd jim-p
		$user_shell = "/usr/local/bin/scponly";
366 3e251b12 Erik Fonnesbeck
	} elseif (userHasPrivilege($user, "user-ssh-tunnel")) {
367
		$user_shell = "/usr/local/sbin/ssh_tunnel_shell";
368 fbfd675a jim-p
	} elseif (userHasPrivilege($user, "user-ipsec-xauth-dialin")) {
369
		$user_shell = "/sbin/nologin";
370 1ed86bc6 jim-p
	} else {
371
		$user_shell = "/sbin/nologin";
372 df8d74de jim-p
		$lock_account = true;
373
	}
374
375
	/* Lock out disabled or expired users, unless it's root/admin. */
376
	if ((is_account_disabled($user_name) || is_account_expired($user_name)) && ($user_uid != 0)) {
377
		$user_shell = "/sbin/nologin";
378
		$lock_account = true;
379 55eb9c44 --global
	}
380
381
	/* root user special handling */
382
	if ($user_uid == 0) {
383
		$cmd = "/usr/sbin/pw usermod -q -n root -s /bin/sh -H 0";
384
		if($debug)
385
			log_error("Running: {$cmd}");
386
		$fd = popen($cmd, "w");
387
		fwrite($fd, $user['password']);
388
		pclose($fd);
389
		$user_group = "wheel";
390 2708e399 jim-p
		$user_home = "/root";
391 29293dce jim-p
		$user_shell = "/etc/rc.initial";
392 55eb9c44 --global
	}
393
394
	/* read from pw db */
395 a82b1ab1 jim-p
	$fd = popen("/usr/sbin/pw usershow -n {$user_name} 2>&1", "r");
396 55eb9c44 --global
	$pwread = fgets($fd);
397
	pclose($fd);
398 a82b1ab1 jim-p
	$userattrs = explode(":", trim($pwread));
399 55eb9c44 --global
400
	/* determine add or mod */
401 a82b1ab1 jim-p
	if (($userattrs[0] != $user['name']) || (!strncmp($pwread, "pw:", 3))) {
402 4b49a8a9 jim-p
		$user_op = "useradd -m -k /etc/skel -o";
403 38564fde smos
	} else {
404 55eb9c44 --global
		$user_op = "usermod";
405 38564fde smos
	}
406 55eb9c44 --global
407 a2463716 Ermal
	$comment = str_replace(array(":", "!", "@"), " ", $user['descr']); 
408 55eb9c44 --global
	/* add or mod pw db */
409
	$cmd = "/usr/sbin/pw {$user_op} -q -u {$user_uid} -n {$user_name}".
410 eb72845c jim-p
			" -g {$user_group} -s {$user_shell} -d {$user_home}".
411 a2463716 Ermal
			" -c ".escapeshellarg($comment)." -H 0 2>&1";
412 55eb9c44 --global
413
	if($debug)
414
		log_error("Running: {$cmd}");
415
	$fd = popen($cmd, "w");
416
	fwrite($fd, $user['password']);
417
	pclose($fd);
418
419
	/* create user directory if required */
420
	if (!is_dir($user_home)) {
421
		mkdir($user_home, 0700);
422 ee4fc984 Ermal
		mwexec("/bin/cp /root/.* {$home_base}/", true);
423 55eb9c44 --global
	}
424
	chown($user_home, $user_name);
425
	chgrp($user_home, $user_group);
426
427
	/* write out ssh authorized key file */
428
	if($user['authorizedkeys']) {
429 a2286360 Ermal Lu?i
		if (!is_dir("{$user_home}/.ssh")) {
430
			mkdir("{$user_home}/.ssh", 0700);
431
			chown("{$user_home}/.ssh", $user_name);
432
		}
433
		$keys = base64_decode($user['authorizedkeys']);
434
		file_put_contents("{$user_home}/.ssh/authorized_keys", $keys);
435
		chown("{$user_home}/.ssh/authorized_keys", $user_name);
436 cdab65cc Erik Fonnesbeck
	} else
437
		unlink_if_exists("{$user_home}/.ssh/authorized_keys");
438 df8d74de jim-p
439
	$un = $lock_account ? "" : "un";
440 7ac98d0b Erik Fonnesbeck
	exec("/usr/sbin/pw {$un}lock {$user_name} -q");
441 2bb07efc Scott Ullrich
	
442
	conf_mount_ro();
443 55eb9c44 --global
}
444
445
function local_user_del($user) {
446
	global $debug;
447 2bb07efc Scott Ullrich
448 55eb9c44 --global
	/* remove all memberships */
449 019e6c3f jim-p
	local_user_set_groups($user);
450 55eb9c44 --global
451 a39675ec jim-p
	/* Don't remove /root */
452
	if ($user['uid'] != 0)
453
		$rmhome = "-r";
454
455 a82b1ab1 jim-p
	/* read from pw db */
456
	$fd = popen("/usr/sbin/pw usershow -n {$user['name']} 2>&1", "r");
457
	$pwread = fgets($fd);
458
	pclose($fd);
459
	$userattrs = explode(":", trim($pwread));
460
461
	if ($userattrs[0] != $user['name']) {
462
		log_error("Tried to remove user {$user['name']} but got user {$userattrs[0]} instead. Bailing.");
463
		return;
464
	}
465
466 55eb9c44 --global
	/* delete from pw db */
467 a82b1ab1 jim-p
	$cmd = "/usr/sbin/pw userdel -n {$user['name']} {$rmhome}";
468 55eb9c44 --global
469
	if($debug)
470
		log_error("Running: {$cmd}");
471 0914b6bb Ermal
	mwexec($cmd);
472 2bb07efc Scott Ullrich
473 0914b6bb Ermal
	/* Delete user from groups needs a call to write_config() */
474
	local_group_del_user($user);
475 55eb9c44 --global
}
476
477
function local_user_set_password(& $user, $password) {
478
479
	$user['password'] = crypt($password);
480
	$user['md5-hash'] = md5($password);
481
482
	// Converts ascii to unicode.
483
	$astr = (string) $password;
484
	$ustr = '';
485
	for ($i = 0; $i < strlen($astr); $i++) {
486
		$a = ord($astr{$i}) << 8;
487
		$ustr.= sprintf("%X", $a);
488
	}
489
490
	// Generate the NT-HASH from the unicode string
491
	$user['nt-hash'] = bin2hex(mhash(MHASH_MD4, $ustr));
492
}
493
494
function local_user_get_groups($user, $all = false) {
495
	global $debug, $config;
496
497
	$groups = array();
498
	if (!is_array($config['system']['group']))
499
		return $groups;
500
501
	foreach ($config['system']['group'] as $group)
502
		if ( $all || ( !$all && ($group['name'] != "all")))
503
			if (is_array($group['member']))
504
				if (in_array($user['uid'], $group['member']))
505
					$groups[] = $group['name'];
506
507 b0c231e4 jim-p
	if ( $all )
508
		$groups[] = "all";
509
510 55eb9c44 --global
	sort($groups);
511
512
	return $groups;
513
	
514
}
515
516
function local_user_set_groups($user, $new_groups = NULL ) {
517
	global $debug, $config, $groupindex;
518
519
	if (!is_array($config['system']['group']))
520
		return;
521
522 739c78ac jim-p
	$cur_groups = local_user_get_groups($user, true);
523 55eb9c44 --global
	$mod_groups = array();
524
525
	if (!is_array($new_groups))
526
		$new_groups = array();
527
528
	if (!is_array($cur_groups))
529
		$cur_groups = array();
530
531
	/* determine which memberships to add */
532
	foreach ($new_groups as $groupname) {
533
		if (in_array($groupname,$cur_groups))
534
			continue;
535
		$group = & $config['system']['group'][$groupindex[$groupname]];
536
		$group['member'][] = $user['uid'];
537
		$mod_groups[] = $group;
538
	}
539 9ae11a62 Scott Ullrich
	unset($group);
540 55eb9c44 --global
541
	/* determine which memberships to remove */
542
	foreach ($cur_groups as $groupname) {
543
		if (in_array($groupname,$new_groups))
544 e879fc81 Ermal
			continue;
545 25fec9b3 jim-p
		if (!isset($config['system']['group'][$groupindex[$groupname]]))
546
			continue;
547 55eb9c44 --global
		$group = & $config['system']['group'][$groupindex[$groupname]];
548 7b5c56ea jim-p
		if (is_array($group['member'])) {
549
			$index = array_search($user['uid'], $group['member']);
550
			array_splice($group['member'], $index, 1);
551
			$mod_groups[] = $group;
552
		}
553 55eb9c44 --global
	}
554 9ae11a62 Scott Ullrich
	unset($group);
555 55eb9c44 --global
556
	/* sync all modified groups */
557
	foreach ($mod_groups as $group)
558
		local_group_set($group);
559
}
560
561 0914b6bb Ermal
function local_group_del_user($user) {
562
	global $config;
563
564
	if (!is_array($config['system']['group']))
565
                return;
566
567
        foreach ($config['system']['group'] as $group) {
568
		if (is_array($group['member'])) {
569
			foreach ($group['member'] as $idx => $uid) {
570
				if ($user['uid'] == $uid)
571
					unset($config['system']['group']['member'][$idx]);
572
			}
573
		}
574
	}
575
}
576
577 55eb9c44 --global
function local_group_set($group, $reset = false) {
578
	global $debug;
579
580
	$group_name = $group['name'];
581
	$group_gid = $group['gid'];
582
	$group_members = "''";
583 cbe49517 Ermal
	if (!$reset && !empty($group['member']) && count($group['member']) > 0)
584 55eb9c44 --global
		$group_members = implode(",",$group['member']);
585
586
	/* read from group db */
587
	$fd = popen("/usr/sbin/pw groupshow {$group_name} 2>&1", "r");
588
	$pwread = fgets($fd);
589
	pclose($fd);
590
591
	/* determine add or mod */
592
	if (!strncmp($pwread, "pw:", 3))
593
		$group_op = "groupadd";
594
	else
595
		$group_op = "groupmod";
596
597
	/* add or mod group db */
598
	$cmd = "/usr/sbin/pw {$group_op} {$group_name} -g {$group_gid} -M {$group_members} 2>&1";
599
600
	if($debug)
601
		log_error("Running: {$cmd}");
602 0914b6bb Ermal
	mwexec($cmd);
603 55eb9c44 --global
604
}
605
606
function local_group_del($group) {
607
	global $debug;
608
609
	/* delete from group db */
610
	$cmd = "/usr/sbin/pw groupdel {$group['name']}";
611
612
	if($debug)
613
		log_error("Running: {$cmd}");
614 0914b6bb Ermal
	mwexec($cmd);
615 55eb9c44 --global
}
616
617 6306b5dd Ermal Lu?i
function ldap_test_connection($authcfg) {
618 55eb9c44 --global
	global $debug, $config, $g;
619
620 c61e4626 Ermal Lu?i
	if ($authcfg) {
621
                if (strstr($authcfg['ldap_urltype'], "Standard"))
622
                        $ldapproto = "ldap";
623
                else
624
                        $ldapproto = "ldaps";
625
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
626
                $ldapport           = $authcfg['ldap_port'];
627 4d89e4d7 jim-p
		if (!empty($ldapport))
628
			$ldapserver .= ":{$ldapport}";
629 c61e4626 Ermal Lu?i
                $ldapbasedn         = $authcfg['ldap_basedn'];
630
                $ldapbindun         = $authcfg['ldap_binddn'];
631
                $ldapbindpw         = $authcfg['ldap_bindpw'];
632 6306b5dd Ermal Lu?i
        } else
633
		return false;
634 55eb9c44 --global
635 c61e4626 Ermal Lu?i
        /* first check if there is even an LDAP server populated */
636
        if(!$ldapserver)
637
                return false;
638
639 b473da5f Ermal
        /* Setup CA environment if needed. */
640
        ldap_setup_caenv($authcfg);
641
642 c61e4626 Ermal Lu?i
        /* connect and see if server is up */
643
        $error = false;
644 4d89e4d7 jim-p
	if (!($ldap = ldap_connect($ldapserver)))
645
		$error = true;
646 c61e4626 Ermal Lu?i
647
        if ($error == true) {
648
                log_error("ERROR!  Could not connect to server {$ldapname}.");
649
                return false;
650
        }
651 55eb9c44 --global
652
	return true;
653
}
654
655 b473da5f Ermal
function ldap_setup_caenv($authcfg) {
656
	global $g;
657 099e764a jim-p
	require_once("certs.inc");
658 b473da5f Ermal
659
	unset($caref);
660 5e17f20d Ermal
	if (empty($authcfg['ldap_caref']) || !strstr($authcfg['ldap_urltype'], "SSL")) {
661 b473da5f Ermal
		putenv('LDAPTLS_REQCERT=never');
662
		return;
663
	} else {
664 5e17f20d Ermal
		$caref = lookup_ca($authcfg['ldap_caref']);
665 b473da5f Ermal
		if (!$caref) {
666 5e17f20d Ermal
			log_error(sprintf(gettext("LDAP: Could not lookup CA by reference for host %s."), $authcfg['ldap_caref']));
667 b473da5f Ermal
			/* XXX: Prevent for credential leaking since we cannot setup the CA env. Better way? */
668
			putenv('LDAPTLS_REQCERT=hard');
669
			return;
670
		}
671
		if (!is_dir("{$g['varrun_path']}/certs"))
672
			@mkdir("{$g['varrun_path']}/certs");
673
		if (file_exists("{$g['varrun_path']}/certs/{$authcfg['name']}.ca"))
674
			@unlink("{$g['varrun_path']}/certs/{$authcfg['name']}.ca");
675
		file_put_contents("{$g['varrun_path']}/certs/{$authcfg['name']}.ca", base64_decode($caref['crt']));
676
		@chmod("{$g['varrun_path']}/certs/{$authcfg['name']}.ca", 0600);
677
		putenv('LDAPTLS_REQCERT=hard');
678
		/* XXX: Probably even the hashed link should be created for this? */
679 6daf497b Ermal
		putenv("LDAPTLS_CACERTDIR={$g['varrun_path']}/certs");
680
		putenv("LDAPTLS_CACERT={$g['varrun_path']}/certs/{$authcfg['name']}.ca");
681 b473da5f Ermal
	}
682
}
683
684 6306b5dd Ermal Lu?i
function ldap_test_bind($authcfg) {
685 55eb9c44 --global
	global $debug, $config, $g;
686
687 c61e4626 Ermal Lu?i
	if ($authcfg) {
688
                if (strstr($authcfg['ldap_urltype'], "Standard"))
689
                        $ldapproto = "ldap";
690
                else
691
                        $ldapproto = "ldaps";
692
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
693
                $ldapport           = $authcfg['ldap_port'];
694 4d89e4d7 jim-p
		if (!empty($ldapport))
695
			$ldapserver .= ":{$ldapport}";
696 c61e4626 Ermal Lu?i
                $ldapbasedn         = $authcfg['ldap_basedn'];
697
                $ldapbindun         = $authcfg['ldap_binddn'];
698
                $ldapbindpw         = $authcfg['ldap_bindpw'];
699
                $ldapver            = $authcfg['ldap_protver'];
700
		if (empty($ldapbndun) || empty($ldapbindpw))
701
                        $ldapanon = true;
702
                else
703
                        $ldapanon = false;
704 6306b5dd Ermal Lu?i
	} else
705
		return false;
706 c61e4626 Ermal Lu?i
707
	/* first check if there is even an LDAP server populated */
708
        if(!$ldapserver)
709
                return false;
710
711 b473da5f Ermal
	/* Setup CA environment if needed. */
712
	ldap_setup_caenv($authcfg);
713
714 c61e4626 Ermal Lu?i
        /* connect and see if server is up */
715
        $error = false;
716 4d89e4d7 jim-p
	if (!($ldap = ldap_connect($ldapserver)))
717
		$error = true;
718 c61e4626 Ermal Lu?i
719
        if ($error == true) {
720
                log_error("ERROR!  Could not connect to server {$ldapname}.");
721
                return false;
722
        }
723 55eb9c44 --global
724
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
725 c61e4626 Ermal Lu?i
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
726
 
727
	if ($ldapanon == true) {
728 6306b5dd Ermal Lu?i
		if (!($res = @ldap_bind($ldap))) {
729
			@ldap_close($ldap);
730 c61e4626 Ermal Lu?i
			return false;
731 6306b5dd Ermal Lu?i
		}
732
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
733
		@ldap_close($ldap);
734 55eb9c44 --global
		return false;
735 6306b5dd Ermal Lu?i
	}
736 55eb9c44 --global
737 6306b5dd Ermal Lu?i
	@ldap_unbind($ldap);
738 c61e4626 Ermal Lu?i
739 55eb9c44 --global
	return true;
740
}
741
742 6306b5dd Ermal Lu?i
function ldap_get_user_ous($show_complete_ou=true, $authcfg) {
743 55eb9c44 --global
	global $debug, $config, $g;
744
745
	if(!function_exists("ldap_connect"))
746
		return;
747
748 7a938f1b Ermal
	$ous = array();
749
750 c61e4626 Ermal Lu?i
	if ($authcfg) {
751
                if (strstr($authcfg['ldap_urltype'], "Standard"))
752
                        $ldapproto = "ldap";
753
                else
754
                        $ldapproto = "ldaps";
755
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
756
                $ldapport           = $authcfg['ldap_port'];
757 4d89e4d7 jim-p
		if (!empty($ldapport))
758
			$ldapserver .= ":{$ldapport}";
759 c61e4626 Ermal Lu?i
                $ldapbasedn         = $authcfg['ldap_basedn'];
760
                $ldapbindun         = $authcfg['ldap_binddn'];
761
                $ldapbindpw         = $authcfg['ldap_bindpw'];
762
                $ldapver            = $authcfg['ldap_protver'];
763
		if (empty($ldapbindun) || empty($ldapbindpw))
764
                        $ldapanon = true;
765
                else
766
                        $ldapanon = false;
767
                $ldapname           = $authcfg['name'];
768
                $ldapfallback       = false;
769
		$ldapscope          = $authcfg['ldap_scope'];
770 6306b5dd Ermal Lu?i
        } else
771
		return false;
772 55eb9c44 --global
773 c61e4626 Ermal Lu?i
        /* first check if there is even an LDAP server populated */
774
        if(!$ldapserver) {
775
                log_error("ERROR!  ldap_get_user_ous() backed selected with no LDAP authentication server defined.");
776
                return $ous;
777
        }
778
779 b473da5f Ermal
	/* Setup CA environment if needed. */
780
	ldap_setup_caenv($authcfg);
781
782 c61e4626 Ermal Lu?i
	/* connect and see if server is up */
783
        $error = false;
784 4d89e4d7 jim-p
	if (!($ldap = ldap_connect($ldapserver)))
785
		$error = true;
786 c61e4626 Ermal Lu?i
787
        if ($error == true) {
788
		log_error("ERROR!  Could not connect to server {$ldapname}.");
789
                return $ous;
790
        }
791
792
	$ldapfilter = "(|(ou=*)(cn=Users))";
793 55eb9c44 --global
794
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
795 c61e4626 Ermal Lu?i
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
796 55eb9c44 --global
797 c61e4626 Ermal Lu?i
	if ($ldapanon == true) {
798
                if (!($res = @ldap_bind($ldap))) {
799 6306b5dd Ermal Lu?i
			log_error("ERROR! ldap_get_user_ous() could not bind anonymously to server {$ldapname}.");
800
			@ldap_close($ldap);
801 c61e4626 Ermal Lu?i
                        return $ous;
802
		}
803
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
804
		log_error("ERROR! ldap_get_user_ous() could not bind to server {$ldapname}.");
805 6306b5dd Ermal Lu?i
		@ldap_close($ldap);
806 c61e4626 Ermal Lu?i
		return $ous;
807 55eb9c44 --global
	}
808
809 c61e4626 Ermal Lu?i
	if ($ldapscope == "one")
810
		$ldapfunc = "ldap_list";
811
	else
812
		$ldapfunc = "ldap_search";
813 55eb9c44 --global
814 7a938f1b Ermal
	$search = @$ldapfunc($ldap, $ldapbasedn, $ldapfilter);
815
	$info = @ldap_get_entries($ldap, $search);
816 55eb9c44 --global
817
	if (is_array($info)) {
818
		foreach ($info as $inf) {
819
			if (!$show_complete_ou) {
820
				$inf_split = split(",", $inf['dn']);
821
				$ou = $inf_split[0];
822
				$ou = str_replace("OU=","", $ou);
823 c61e4626 Ermal Lu?i
				$ou = str_replace("CN=","", $ou);
824 55eb9c44 --global
			} else
825
				if($inf['dn'])
826
					$ou = $inf['dn'];
827
			if($ou)
828
				$ous[] = $ou;
829
		}
830
	}
831
832 6306b5dd Ermal Lu?i
	@ldap_unbind($ldap);
833
834 55eb9c44 --global
	return $ous;
835
}
836
837 6306b5dd Ermal Lu?i
function ldap_get_groups($username, $authcfg) {
838 55eb9c44 --global
	global $debug, $config;
839
	
840
	if(!function_exists("ldap_connect"))
841
		return;
842
	
843
	if(!$username) 
844
		return false;
845
846
	if(stristr($username, "@")) {
847
		$username_split=split("\@", $username);
848
		$username = $username_split[0];		
849
	}
850
851
	if(stristr($username, "\\")) {
852
		$username_split=split("\\", $username);
853
		$username = $username_split[0];        
854
	}    
855
	
856
	//log_error("Getting LDAP groups for {$username}.");
857 c61e4626 Ermal Lu?i
        if ($authcfg) {
858
                if (strstr($authcfg['ldap_urltype'], "Standard"))
859
                        $ldapproto = "ldap";
860
                else
861
                        $ldapproto = "ldaps";
862
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
863
                $ldapport           = $authcfg['ldap_port'];
864 4d89e4d7 jim-p
		if (!empty($ldapport))
865
			$ldapserver .= ":{$ldapport}";
866 c61e4626 Ermal Lu?i
                $ldapbasedn         = $authcfg['ldap_basedn'];
867
                $ldapbindun         = $authcfg['ldap_binddn'];
868
                $ldapbindpw         = $authcfg['ldap_bindpw'];
869
                $ldapauthcont       = $authcfg['ldap_authcn'];
870
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
871
                $ldapgroupattribute  = strtolower($authcfg['ldap_attr_member']);
872
                $ldapfilter         = "({$ldapnameattribute}={$username})";
873
                $ldaptype           = "";
874
                $ldapver            = $authcfg['ldap_protver'];
875
		if (empty($ldapbindun) || empty($ldapbindpw))
876
                        $ldapanon = true;
877
                else
878
                        $ldapanon = false;
879
                $ldapname           = $authcfg['name'];
880
                $ldapfallback       = false;
881
		$ldapscope          = $authcfg['ldap_scope'];
882 6306b5dd Ermal Lu?i
	} else
883
		return false;
884 c61e4626 Ermal Lu?i
885 55eb9c44 --global
	$ldapdn             = $_SESSION['ldapdn'];
886 c61e4626 Ermal Lu?i
887 55eb9c44 --global
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
888
	$ldapgroupattribute = strtolower($ldapgroupattribute);
889 c61e4626 Ermal Lu?i
	$memberof = array();
890 55eb9c44 --global
891 b473da5f Ermal
        /* Setup CA environment if needed. */
892
        ldap_setup_caenv($authcfg);
893
894 55eb9c44 --global
	/* connect and see if server is up */
895 c61e4626 Ermal Lu?i
	$error = false;
896 4d89e4d7 jim-p
	if (!($ldap = ldap_connect($ldapserver)))
897
		$error = true;
898 c61e4626 Ermal Lu?i
899
	if ($error == true) {
900
		log_error("ERROR! ldap_get_groups() Could not connect to server {$ldapname}.");
901
                return memberof;
902
        }
903 55eb9c44 --global
    
904
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
905 c61e4626 Ermal Lu?i
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
906 55eb9c44 --global
907
	/* bind as user that has rights to read group attributes */
908 c61e4626 Ermal Lu?i
	if ($ldapanon == true) {
909 6306b5dd Ermal Lu?i
                if (!($res = @ldap_bind($ldap))) {
910
			log_error("ERROR! ldap_get_groups() could not bind anonymously to server {$ldapname}.");
911
			@ldap_close($ldap);
912 c61e4626 Ermal Lu?i
                        return false;
913 6306b5dd Ermal Lu?i
		}
914 c61e4626 Ermal Lu?i
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
915
		log_error("ERROR! ldap_get_groups() could not bind to server {$ldapname}.");
916 6306b5dd Ermal Lu?i
		@ldap_close($ldap);
917 c61e4626 Ermal Lu?i
		return memberof;
918 55eb9c44 --global
	}
919
920
	/* get groups from DN found */
921
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
922
	/* since we know the DN is in $_SESSION['ldapdn'] */
923
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
924 c61e4626 Ermal Lu?i
	if ($ldapscope == "one")
925
                $ldapfunc = "ldap_list";
926
        else
927
                $ldapfunc = "ldap_search";
928
929 7a938f1b Ermal
	$search    = @$ldapfunc($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
930
	$info      = @ldap_get_entries($ldap, $search);
931 55eb9c44 --global
932
	$countem = $info["count"];	
933
	
934
	if(is_array($info[0][$ldapgroupattribute])) {
935
		/* Iterate through the groups and throw them into an array */
936
		foreach ($info[0][$ldapgroupattribute] as $member) {
937
			if (stristr($member, "CN=") !== false) {
938
				$membersplit = split(",", $member);
939
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
940
			}
941
		}
942
	}
943
	
944
	/* Time to close LDAP connection */
945 6306b5dd Ermal Lu?i
	@ldap_unbind($ldap);
946 55eb9c44 --global
	
947
	$groups = print_r($memberof,true);
948
	
949
	//log_error("Returning groups ".$groups." for user $username");
950
	
951
	return $memberof;
952
}
953
954 6306b5dd Ermal Lu?i
function ldap_backed($username, $passwd, $authcfg) {
955 55eb9c44 --global
	global $debug, $config;
956
	
957
	if(!$username) 
958
		return;
959
960
	if(!function_exists("ldap_connect"))
961
		return;
962
963
	if(stristr($username, "@")) {
964
		$username_split=split("\@", $username);
965
		$username = $username_split[0];        
966
	}
967
	if(stristr($username, "\\")) {
968
		$username_split=split("\\", $username);
969
		$username = $username_split[0];        
970
	}
971
972 c61e4626 Ermal Lu?i
	if ($authcfg) {
973
		if (strstr($authcfg['ldap_urltype'], "Standard"))
974
			$ldapproto = "ldap";
975
		else
976
			$ldapproto = "ldaps";
977
		$ldapserver         = "{$ldapproto}://{$authcfg['host']}";
978
		$ldapport	    = $authcfg['ldap_port'];
979 4d89e4d7 jim-p
		if (!empty($ldapport))
980
			$ldapserver .= ":{$ldapport}";
981 c61e4626 Ermal Lu?i
                $ldapbasedn         = $authcfg['ldap_basedn'];
982
                $ldapbindun         = $authcfg['ldap_binddn'];
983
                $ldapbindpw         = $authcfg['ldap_bindpw'];
984
		if (empty($ldapbindun) || empty($ldapbindpw))
985
			$ldapanon = true;
986
		else
987
			$ldapanon = false;
988
                $ldapauthcont       = $authcfg['ldap_authcn'];
989
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
990
                $ldapfilter         = "({$ldapnameattribute}={$username})";
991
                $ldaptype           = "";
992
                $ldapver            = $authcfg['ldap_protver'];
993
		$ldapname	    = $authcfg['name'];
994
		$ldapscope	    = $authcfg['ldap_scope'];
995 6306b5dd Ermal Lu?i
	} else
996
		return false;
997 55eb9c44 --global
998
	/* first check if there is even an LDAP server populated */ 
999
	if(!$ldapserver) {
1000 c61e4626 Ermal Lu?i
		if ($ldapfallback) {
1001
			log_error("ERROR! ldap_backed() called with no LDAP authentication server defined.  Defaulting to local user database. Visit System -> User Manager.");
1002
			return local_backed($username, $passwd);
1003
		} else
1004
			log_error("ERROR! ldap_backed() called with no LDAP authentication server defined.");
1005
1006
		return false;
1007 55eb9c44 --global
	}
1008
	
1009 b473da5f Ermal
        /* Setup CA environment if needed. */
1010
        ldap_setup_caenv($authcfg);
1011
1012 6daf497b Ermal
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
1013
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
1014
1015 55eb9c44 --global
	/* Make sure we can connect to LDAP */
1016 c61e4626 Ermal Lu?i
	$error = false;
1017 4d89e4d7 jim-p
	if (!($ldap = ldap_connect($ldapserver)))
1018 c61e4626 Ermal Lu?i
		$error = true;
1019
1020
	if ($error == true) {
1021 6306b5dd Ermal Lu?i
		log_error("ERROR!  Could not connect to server {$ldapname}.");
1022 c61e4626 Ermal Lu?i
		return false;
1023 55eb9c44 --global
	}
1024 c61e4626 Ermal Lu?i
1025 55eb9c44 --global
	/* ok, its up.  now, lets bind as the bind user so we can search it */
1026 c61e4626 Ermal Lu?i
	$error = false;
1027
	if ($ldapanon == true) {
1028
                if (!($res = @ldap_bind($ldap)))
1029
                        $error = true;
1030
	} else if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
1031
		$error = true;
1032
1033
	if ($error == true) {
1034 6306b5dd Ermal Lu?i
		@ldap_close($ldap);
1035
		log_error("ERROR! Could not bind to server {$ldapname}.");
1036 c61e4626 Ermal Lu?i
		return false;
1037 55eb9c44 --global
	}
1038
	
1039
	/* Get LDAP Authcontainers and split em up. */
1040 c61e4626 Ermal Lu?i
	$ldac_splits = split(";", $ldapauthcont);
1041 55eb9c44 --global
	
1042
	/* setup the usercount so we think we havn't found anyone yet */
1043
	$usercount  = 0;
1044
1045
	/*****************************************************************/
1046
	/*  We First find the user based on username and filter          */
1047
	/*  Then, once we find the first occurance of that person        */
1048
	/*  We set seesion variables to ponit to the OU and DN of the    */
1049
	/*  Person.  To later be used by ldap_get_groups.                */
1050
	/*  that way we don't have to search twice.                      */
1051
	/*****************************************************************/
1052 c61e4626 Ermal Lu?i
	log_error("Now Searching for {$username} in directory.");
1053
	/* Iterate through the user containers for search */
1054
	foreach ($ldac_splits as $i => $ldac_split) {
1055
		/* Make sure we just use the first user we find */
1056
		log_error("Now Searching in server {$ldapname}, container {$ldac_split} with filter {$ldapfilter}.");
1057
		if ($ldapscope == "one")
1058
			$ldapfunc = "ldap_list";
1059
		else
1060
			$ldapfunc = "ldap_search";
1061
		/* Support legacy auth container specification. */
1062 9ae11a62 Scott Ullrich
		if (stristr($ldac_split, "DC=") || empty($ldapbasedn))
1063
			$search	 = @$ldapfunc($ldap,$ldac_split,$ldapfilter);
1064
		else
1065
			$search  = @$ldapfunc($ldap,"{$ldac_split},{$ldapbasedn}",$ldapfilter);
1066 c61e4626 Ermal Lu?i
		if (!$search) {
1067
			log_error("Search resulted in error: " . ldap_error($ldap));
1068
			continue;
1069 55eb9c44 --global
		}
1070 c61e4626 Ermal Lu?i
		$info	 = ldap_get_entries($ldap,$search);
1071
		$matches = $info['count'];
1072 55eb9c44 --global
		if ($matches == 1){
1073 c61e4626 Ermal Lu?i
			$userdn = $_SESSION['ldapdn'] = $info[0]['dn'];
1074
			$_SESSION['ldapou'] = $ldac_split[$i];
1075
			$_SESSION['ldapon'] = "true";
1076
			$usercount = 1;
1077
			break;
1078 55eb9c44 --global
		}
1079
	}
1080
1081 c61e4626 Ermal Lu?i
	if ($usercount != 1){
1082 6306b5dd Ermal Lu?i
		@ldap_unbind($ldap);
1083
		log_error("ERROR! Either LDAP search failed, or multiple users were found.");
1084 c61e4626 Ermal Lu?i
		return false;                         
1085 55eb9c44 --global
	}
1086 c61e4626 Ermal Lu?i
1087 55eb9c44 --global
	/* Now lets bind as the user we found */
1088 c61e4626 Ermal Lu?i
	if (!($res = @ldap_bind($ldap, $userdn, $passwd))) {
1089 6306b5dd Ermal Lu?i
		log_error("ERROR! Could not login to server {$ldapname} as user {$username}.");
1090
		@ldap_unbind($ldap);
1091 c61e4626 Ermal Lu?i
		return false;
1092 55eb9c44 --global
	}
1093
1094 95feeb92 Chris Buechler
	log_error("Logged in successfully as {$username} via LDAP server {$ldapname} with DN = {$userdn}.");
1095 c61e4626 Ermal Lu?i
1096
	/* At this point we are bound to LDAP so the user was auth'd okay. Close connection. */
1097 6306b5dd Ermal Lu?i
	@ldap_unbind($ldap);
1098 55eb9c44 --global
1099
	return true;
1100
}
1101
1102 6306b5dd Ermal Lu?i
function radius_backed($username, $passwd, $authcfg){
1103 a13ce628 Ermal Lu?i
	global $debug, $config;
1104 55eb9c44 --global
	$ret = false;
1105
1106 868c6826 Ermal
	require_once("radius.inc");
1107
1108 55eb9c44 --global
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
1109 c61e4626 Ermal Lu?i
	if ($authcfg) {
1110
		$radiusservers = array();
1111
		$radiusservers[0]['ipaddr'] = $authcfg['host'];
1112
		$radiusservers[0]['port'] = $authcfg['radius_auth_port'];
1113
		$radiusservers[0]['sharedsecret'] = $authcfg['radius_secret'];
1114
	} else
1115 6306b5dd Ermal Lu?i
		return false;
1116 c61e4626 Ermal Lu?i
1117 55eb9c44 --global
	/* Add a new servers to our instance */
1118
	foreach ($radiusservers as $radsrv)
1119
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
1120
1121 6e815096 Ermal
	if (PEAR::isError($rauth->start())) {
1122 55eb9c44 --global
		$retvalue['auth_val'] = 1;
1123
		$retvalue['error'] = $rauth->getError();
1124
		if ($debug)
1125
			printf("Radius start: %s<br>\n", $retvalue['error']);
1126
	}
1127
1128
	// XXX - billm - somewhere in here we need to handle securid challenge/response
1129
1130
	/* Send request */
1131
	$result = $rauth->send();
1132
	if (PEAR::isError($result)) {
1133
		$retvalue['auth_val'] = 1;
1134
		$retvalue['error'] = $result->getMessage();
1135
		if ($debug)
1136
			printf("Radius send failed: %s<br>\n", $retvalue['error']);
1137
	} else if ($result === true) {
1138
		$retvalue['auth_val'] = 2;
1139
		if ($debug)
1140
			printf(gettext("Radius Auth succeeded")."<br>\n");
1141
		$ret = true;
1142
	} else {
1143
		$retvalue['auth_val'] = 3;
1144
		if ($debug)
1145
			printf(gettext("Radius Auth rejected")."<br>\n");
1146
	}
1147
1148
	// close OO RADIUS_AUTHENTICATION
1149
	$rauth->close();
1150
1151
	return $ret;
1152
}
1153
1154 7dd044f2 sullrich
function get_user_expiration_date($username) {
1155 a13ce628 Ermal Lu?i
	$user = getUserEntry($username);
1156
	if ($user['expires']) 
1157
		return $user['expires'];
1158
}
1159
1160
function is_account_expired($username) {
1161
	$expirydate = get_user_expiration_date($username);
1162
	if ($expirydate) {
1163
		if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($expirydate))))
1164
			return true;
1165 7dd044f2 sullrich
	}
1166 a13ce628 Ermal Lu?i
1167
	return false;
1168 7dd044f2 sullrich
}
1169
1170 b4bfd25d sullrich
function is_account_disabled($username) {
1171 a13ce628 Ermal Lu?i
	$user = getUserEntry($username);
1172
	if (isset($user['disabled']))
1173
		return true;
1174
1175 b4bfd25d sullrich
	return false;
1176
}
1177
1178 c61e4626 Ermal Lu?i
function auth_get_authserver($name) {
1179
        global $config;
1180
1181
        if (is_array($config['system']['authserver'])) {
1182
                foreach ($config['system']['authserver'] as $authcfg) {
1183
                        if ($authcfg['name'] == $name)
1184
                                return $authcfg;
1185
                }
1186
        }
1187 6306b5dd Ermal Lu?i
	if ($name == "Local Database")
1188
		return array("name" => "Local Database", "type" => "Local Auth", "host" => $config['system']['hostname']);
1189
}
1190
1191
function auth_get_authserver_list() {
1192
        global $config;
1193
1194
	$list = array();
1195
1196
        if (is_array($config['system']['authserver'])) {
1197
                foreach ($config['system']['authserver'] as $authcfg) {
1198
			/* Add support for disabled entries? */
1199
			$list[$authcfg['name']] = $authcfg;
1200
                }
1201
        }
1202
1203
	$list["Local Database"] = array( "name" => "Local Database", "type" => "Local Auth", "host" => $config['system']['hostname']);
1204
	return $list;
1205 c61e4626 Ermal Lu?i
}
1206
1207 fb0f22c0 Ermal Lu?i
function getUserGroups($username, $authcfg) {
1208
	global $config;
1209
1210
	$allowed_groups = array();
1211
1212
	switch($authcfg['type']) {
1213
        case 'ldap':
1214
		$allowed_groups = @ldap_get_groups($username, $authcfg);
1215
		break;
1216
	case 'radius':
1217
		break;
1218
	default:
1219
		$user = getUserEntry($username);
1220
		$allowed_groups = @local_user_get_groups($user, true);
1221
		break;
1222
	}
1223
1224
	$member_groups = array();
1225
        if (is_array($config['system']['group'])) {
1226
                foreach ($config['system']['group'] as $group)
1227
                        if (in_array($group['name'], $allowed_groups))
1228
				$member_groups[] = $group['name'];
1229
	}
1230
1231
	return $member_groups;
1232
}
1233
1234 c61e4626 Ermal Lu?i
function authenticate_user($username, $password, $authcfg = NULL) {
1235
1236
	if (!$authcfg) {
1237
		return local_backed($username, $password);
1238
	}
1239
1240
	$authenticated = false;
1241
	switch($authcfg['type']) {
1242
        case 'ldap':
1243
                if (ldap_backed($username, $password, $authcfg))
1244
                        $authenticated = true;
1245
                break;
1246
        case 'radius':
1247
                if (radius_backed($username, $password, $authcfg))
1248
                        $authenticated = true;
1249
                break;
1250
        default:
1251
                /* lookup user object by name */
1252
                if (local_backed($username, $password))
1253
                        $authenticated = true;
1254
                break;
1255
        }
1256
1257
	return $authenticated;
1258
}
1259
1260 6306b5dd Ermal Lu?i
function session_auth() {
1261
	global $HTTP_SERVER_VARS, $config, $_SESSION, $page;
1262 55eb9c44 --global
1263 ddb71e4c Warren Baker
	// Handle HTTPS httponly and secure flags
1264
	if($config['system']['webgui']['protocol'] == "https") {
1265
		$currentCookieParams = session_get_cookie_params();
1266
		session_set_cookie_params(
1267
			$currentCookieParams["lifetime"],
1268
			$currentCookieParams["path"],
1269
			NULL,
1270
			true,
1271
			true
1272
		);
1273
	}
1274
1275 fa3ee91d Ermal
	if (!session_id())
1276
		session_start();
1277 55eb9c44 --global
1278
	/* Validate incoming login request */
1279
	if (isset($_POST['login'])) {
1280 6306b5dd Ermal Lu?i
		$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
1281
		if (authenticate_user($_POST['usernamefld'], $_POST['passwordfld'], $authcfg) || 
1282
		    authenticate_user($_POST['usernamefld'], $_POST['passwordfld'])) {
1283
			$_SESSION['Logged_In'] = "True";
1284
			$_SESSION['Username'] = $_POST['usernamefld'];
1285
			$_SESSION['last_access'] = time();
1286 4fc3855f smos
			if(! isset($config['system']['webgui']['quietlogin'])) {
1287
				log_auth("Successful webConfigurator login for user '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}");
1288
			}
1289 f23e6363 Ermal
			$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1290 92140621 Ermal
			if (isset($_POST['postafterlogin']))
1291
				return true;
1292 80b292f3 Ermal
			else {
1293
				if (empty($page))
1294
					$page = "/";
1295
				header("Location: {$page}");
1296
			}
1297 f23e6363 Ermal
			exit;
1298 a13ce628 Ermal Lu?i
		} else {
1299
			/* give the user an error message */
1300
			$_SESSION['Login_Error'] = "Username or Password incorrect";
1301 65f7fba8 Scott Ullrich
			log_auth("webConfigurator authentication error for '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}");
1302 a13ce628 Ermal Lu?i
			if(isAjax()) {
1303
				echo "showajaxmessage('{$_SESSION['Login_Error']}');";
1304
				return;
1305 55eb9c44 --global
			}
1306
		}
1307
	}
1308
1309
	/* Show login page if they aren't logged in */
1310 409105ec Ermal Lu?i
	if (empty($_SESSION['Logged_In']))
1311 55eb9c44 --global
		return false;
1312
1313
	/* If session timeout isn't set, we don't mark sessions stale */
1314 02647583 Ermal
	if (!isset($config['system']['webgui']['session_timeout'])) {
1315 bdadaf3c Chris Buechler
		/* Default to 4 hour timeout if one is not set */
1316
		if ($_SESSION['last_access'] < (time() - 14400)) {
1317
			$_GET['logout'] = true;
1318
			$_SESSION['Logout'] = true;
1319 9a985f9e Ermal
		} else
1320
			$_SESSION['last_access'] = time();	
1321 02647583 Ermal
	} else if (intval($config['system']['webgui']['session_timeout']) == 0) {
1322
		/* only update if it wasn't ajax */
1323
		if (!isAjax())
1324
			$_SESSION['last_access'] = time();
1325 bdadaf3c Chris Buechler
	} else {
1326 55eb9c44 --global
		/* Check for stale session */
1327
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
1328
			$_GET['logout'] = true;
1329
			$_SESSION['Logout'] = true;
1330
		} else {
1331
			/* only update if it wasn't ajax */
1332
			if (!isAjax())
1333
				$_SESSION['last_access'] = time();
1334
		}
1335
	}
1336
1337
	/* user hit the logout button */
1338
	if (isset($_GET['logout'])) {
1339
1340
		if ($_SESSION['Logout'])
1341
			log_error("Session timed out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
1342
		else
1343
			log_error("User logged out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
1344
1345
		/* wipe out $_SESSION */
1346
		$_SESSION = array();
1347
1348
		if (isset($_COOKIE[session_name()]))
1349
			setcookie(session_name(), '', time()-42000, '/');
1350
1351
		/* and destroy it */
1352
		session_destroy();
1353
1354
		$scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
1355
		$scriptElms = count($scriptName);
1356
		$scriptName = $scriptName[$scriptElms-1];
1357
1358
		if (isAjax())
1359
			return false;
1360
1361
		/* redirect to page the user is on, it'll prompt them to login again */
1362 6dc88d53 Ermal Luci
		Header("Location: {$scriptName}");
1363 55eb9c44 --global
1364
		return false;
1365
	}
1366
1367
	/*
1368
	 * this is for debugging purpose if you do not want to use Ajax
1369
	 * to submit a HTML form. It basically diables the observation
1370
	 * of the submit event and hence does not trigger Ajax.
1371
	 */
1372 f23e6363 Ermal
	if ($_GET['disable_ajax'])
1373 55eb9c44 --global
		$_SESSION['NO_AJAX'] = "True";
1374
1375
	/*
1376
	 * Same to re-enable Ajax.
1377
	 */
1378 f23e6363 Ermal
	if ($_GET['enable_ajax'])
1379 55eb9c44 --global
		unset($_SESSION['NO_AJAX']);
1380
1381
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1382
	return true;
1383
}
1384
1385 ee4fc984 Ermal
?>