Project

General

Profile

Download (42.6 KB) Statistics
| Branch: | Tag: | Revision:
1 55eb9c44 --global
<?php
2
/* $Id$ */
3
/*
4 d1b69106 namezero111111
	Copyright (C) 2010 Ermal Lu�i
5 8a6b0fbe Ermal Lu?i
	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 209620ea Seth Mos
61 4cf79fdd smos
	/* 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 209620ea Seth Mos
		/* 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 4cf79fdd smos
			$http_host = str_replace(array("[", "]"), "", implode(":", $http_host_port));
70 209620ea Seth Mos
		}
71 7319dc73 jim-p
	} else {
72 4fcab77b smos
		$http_host = explode(":", $_SERVER['HTTP_HOST']);
73
		$http_host = $http_host[0];
74 7319dc73 jim-p
	}
75 f17f9f28 jim-p
	if(is_ipaddr($http_host) or $_SERVER['SERVER_ADDR'] == "127.0.0.1" or
76 209620ea Seth Mos
			strcasecmp($http_host, "localhost") == 0 or $_SERVER['SERVER_ADDR'] == "::1")
77 9ae11a62 Scott Ullrich
		$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 d7bf3178 Erik Fonnesbeck
		$found_host = true;
81 9ae11a62 Scott Ullrich
82
	if(is_array($config['dyndnses']['dyndns']) && !$found_host)
83 0321fa1b jim-p
		foreach($config['dyndnses']['dyndns'] as $dyndns)
84 9ae11a62 Scott Ullrich
			if(strcasecmp($dyndns['host'], $http_host) == 0) {
85 0321fa1b jim-p
				$found_host = true;
86 9ae11a62 Scott Ullrich
				break;
87
			}
88 7319dc73 jim-p
89 9ae11a62 Scott Ullrich
	if(!empty($config['system']['webgui']['althostnames']) && !$found_host) {
90 86b21903 jim-p
		$althosts = explode(" ", $config['system']['webgui']['althostnames']);
91
		foreach ($althosts as $ah)
92 9ae11a62 Scott Ullrich
			if(strcasecmp($ah, $http_host) == 0 or strcasecmp($ah, $_SERVER['SERVER_ADDR']) == 0) {
93 86b21903 jim-p
				$found_host = true;
94 9ae11a62 Scott Ullrich
				break;
95
			}
96 9b13f84b Scott Ullrich
	}
97 ce46b5da Scott Ullrich
98 9ae11a62 Scott Ullrich
	if($found_host == false) {
99
		if(!security_checks_disabled()) {
100 c92ccac7 Vinicius Coque
			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 9ae11a62 Scott Ullrich
			exit;
102
		}
103
		$security_passed = false;
104
	}
105
}
106 ef173724 Scott Ullrich
107 9ae11a62 Scott Ullrich
// 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 e6f7e0be smos
		$referrer_host = str_replace(array("[", "]"), "", $referrer_host);
122 9ae11a62 Scott Ullrich
		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 e6f7e0be smos
				$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 17dd7ff3 Chris Buechler
				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 9ae11a62 Scott Ullrich
			}
155
		}
156 4fe9c2dc Scott Ullrich
		if($found_host == false) {
157 9ae11a62 Scott Ullrich
			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 0f806eca Erik Fonnesbeck
				exit;
160
			}
161 9ae11a62 Scott Ullrich
			$security_passed = false;
162
		}
163
	} else
164
		$security_passed = false;
165 4fe9c2dc Scott Ullrich
}
166
167 9ae11a62 Scott Ullrich
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 55eb9c44 --global
$groupindex = index_groups();
173
$userindex = index_users();
174
175
function index_groups() {
176
	global $g, $debug, $config, $groupindex;
177
178
	$groupindex = array();
179
180 6dcd80af Ermal
	if (is_array($config['system']['group'])) {
181 55eb9c44 --global
		$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 6dcd80af Ermal
	if (is_array($config['system']['user'])) {
195 55eb9c44 --global
		$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 84924e76 Ermal
214
	if (is_array($config['system']['user']))
215
		foreach ($config['system']['user'] as & $user)
216
			if ($user['uid'] == $uid)
217
				return $user;
218 55eb9c44 --global
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 84924e76 Ermal
231
	if (is_array($config['system']['group']))
232
		foreach ($config['system']['group'] as & $group)
233
			if ($group['gid'] == $gid)
234
				return $group;
235 55eb9c44 --global
236
	return false;
237
}
238
239 6dc88d53 Ermal Luci
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 55eb9c44 --global
function local_backed($username, $passwd) {
273
274
	$user = getUserEntry($username);
275
	if (!$user)
276
		return false;
277
278 6306b5dd Ermal Lu?i
	if (is_account_disabled($username) || is_account_expired($username))
279 a13ce628 Ermal Lu?i
		return false;
280
281 55eb9c44 --global
	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 6763033d jim-p
			if (((!strncmp($line[0], "_", 1)) || ($line[2] < 2000) || ($line[2] > 65000)) && ($line[0] != "admin"))
308 55eb9c44 --global
				continue;
309 6763033d jim-p
			$cmd = "/usr/sbin/pw userdel -n '{$line[0]}'";
310 55eb9c44 --global
			if($debug)
311 94021404 Carlos Eduardo Ramos
				log_error(sprintf(gettext("Running: %s"), $cmd));
312 55eb9c44 --global
			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 94021404 Carlos Eduardo Ramos
				log_error(sprintf(gettext("Running: %s"), $cmd));
332 55eb9c44 --global
			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 5af2baf7 jim-p
	/* 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 f3e0a111 jim-p
	/* 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 55eb9c44 --global
	conf_mount_ro();
352
353
}
354
355
function local_user_set(& $user) {
356
	global $g, $debug;
357
358 b3c106a0 Ermal
	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 2bb07efc Scott Ullrich
	conf_mount_rw();
364
365 55eb9c44 --global
	$home_base = "/home/";	
366
	$user_uid = $user['uid'];
367
	$user_name = $user['name'];
368 461df7c0 jim-p
	$user_home = "{$home_base}{$user_name}";
369 55eb9c44 --global
	$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 df8d74de jim-p
	$lock_account = false;
377 55eb9c44 --global
	/* configure shell type */
378 3e251b12 Erik Fonnesbeck
	/* Cases here should be ordered by most privileged to least privileged. */
379 a137fedd jim-p
	if (userHasPrivilege($user, "user-shell-access") || userHasPrivilege($user, "page-all")) {
380 29293dce jim-p
		$user_shell = "/bin/tcsh";
381 1ed86bc6 jim-p
	} elseif (userHasPrivilege($user, "user-copy-files")) {
382 a137fedd jim-p
		$user_shell = "/usr/local/bin/scponly";
383 3e251b12 Erik Fonnesbeck
	} elseif (userHasPrivilege($user, "user-ssh-tunnel")) {
384
		$user_shell = "/usr/local/sbin/ssh_tunnel_shell";
385 fbfd675a jim-p
	} elseif (userHasPrivilege($user, "user-ipsec-xauth-dialin")) {
386
		$user_shell = "/sbin/nologin";
387 1ed86bc6 jim-p
	} else {
388
		$user_shell = "/sbin/nologin";
389 df8d74de jim-p
		$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 55eb9c44 --global
	}
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 94021404 Carlos Eduardo Ramos
			log_error(sprintf(gettext("Running: %s"), $cmd));
403 55eb9c44 --global
		$fd = popen($cmd, "w");
404
		fwrite($fd, $user['password']);
405
		pclose($fd);
406
		$user_group = "wheel";
407 2708e399 jim-p
		$user_home = "/root";
408 29293dce jim-p
		$user_shell = "/etc/rc.initial";
409 55eb9c44 --global
	}
410
411
	/* read from pw db */
412 9fd14591 jim-p
	$fd = popen("/usr/sbin/pw usershow -n {$user_name} 2>&1", "r");
413 55eb9c44 --global
	$pwread = fgets($fd);
414
	pclose($fd);
415 9fd14591 jim-p
	$userattrs = explode(":", trim($pwread));
416 55eb9c44 --global
417
	/* determine add or mod */
418 9fd14591 jim-p
	if (($userattrs[0] != $user['name']) || (!strncmp($pwread, "pw:", 3))) {
419 4b49a8a9 jim-p
		$user_op = "useradd -m -k /etc/skel -o";
420 38564fde smos
	} else {
421 55eb9c44 --global
		$user_op = "usermod";
422 38564fde smos
	}
423 55eb9c44 --global
424 1cb94b24 Ermal
	$comment = str_replace(array(":", "!", "@"), " ", $user['descr']); 
425 55eb9c44 --global
	/* add or mod pw db */
426
	$cmd = "/usr/sbin/pw {$user_op} -q -u {$user_uid} -n {$user_name}".
427 eb72845c jim-p
			" -g {$user_group} -s {$user_shell} -d {$user_home}".
428 1cb94b24 Ermal
			" -c ".escapeshellarg($comment)." -H 0 2>&1";
429 55eb9c44 --global
430
	if($debug)
431 94021404 Carlos Eduardo Ramos
		log_error(sprintf(gettext("Running: %s"), $cmd));
432 55eb9c44 --global
	$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 ee4fc984 Ermal
		mwexec("/bin/cp /root/.* {$home_base}/", true);
440 55eb9c44 --global
	}
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 a2286360 Ermal Lu?i
		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 cdab65cc Erik Fonnesbeck
	} else
454
		unlink_if_exists("{$user_home}/.ssh/authorized_keys");
455 df8d74de jim-p
456
	$un = $lock_account ? "" : "un";
457 7ac98d0b Erik Fonnesbeck
	exec("/usr/sbin/pw {$un}lock {$user_name} -q");
458 2bb07efc Scott Ullrich
	
459
	conf_mount_ro();
460 55eb9c44 --global
}
461
462
function local_user_del($user) {
463
	global $debug;
464 2bb07efc Scott Ullrich
465 55eb9c44 --global
	/* remove all memberships */
466 019e6c3f jim-p
	local_user_set_groups($user);
467 55eb9c44 --global
468 a39675ec jim-p
	/* Don't remove /root */
469
	if ($user['uid'] != 0)
470
		$rmhome = "-r";
471
472 9fd14591 jim-p
	/* 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 55eb9c44 --global
	/* delete from pw db */
484 9fd14591 jim-p
	$cmd = "/usr/sbin/pw userdel -n {$user['name']} {$rmhome}";
485 55eb9c44 --global
486
	if($debug)
487 94021404 Carlos Eduardo Ramos
		log_error(sprintf(gettext("Running: %s"), $cmd));
488 0914b6bb Ermal
	mwexec($cmd);
489 2bb07efc Scott Ullrich
490 0914b6bb Ermal
	/* Delete user from groups needs a call to write_config() */
491
	local_group_del_user($user);
492 55eb9c44 --global
}
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 6ac18f9d jim-p
       $user['nt-hash'] = bin2hex(hash("md4", $ustr));
509 55eb9c44 --global
}
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 b0c231e4 jim-p
	if ( $all )
525
		$groups[] = "all";
526
527 55eb9c44 --global
	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 739c78ac jim-p
	$cur_groups = local_user_get_groups($user, true);
540 55eb9c44 --global
	$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 9ae11a62 Scott Ullrich
	unset($group);
557 55eb9c44 --global
558
	/* determine which memberships to remove */
559
	foreach ($cur_groups as $groupname) {
560
		if (in_array($groupname,$new_groups))
561 e879fc81 Ermal
			continue;
562 25fec9b3 jim-p
		if (!isset($config['system']['group'][$groupindex[$groupname]]))
563
			continue;
564 55eb9c44 --global
		$group = & $config['system']['group'][$groupindex[$groupname]];
565 7b5c56ea jim-p
		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 55eb9c44 --global
	}
571 9ae11a62 Scott Ullrich
	unset($group);
572 55eb9c44 --global
573
	/* sync all modified groups */
574
	foreach ($mod_groups as $group)
575
		local_group_set($group);
576
}
577
578 0914b6bb Ermal
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 55eb9c44 --global
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 cbe49517 Ermal
	if (!$reset && !empty($group['member']) && count($group['member']) > 0)
601 55eb9c44 --global
		$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 94021404 Carlos Eduardo Ramos
		log_error(sprintf(gettext("Running: %s"), $cmd));
619 0914b6bb Ermal
	mwexec($cmd);
620 55eb9c44 --global
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 94021404 Carlos Eduardo Ramos
		log_error(sprintf(gettext("Running: %s"), $cmd));
631 0914b6bb Ermal
	mwexec($cmd);
632 55eb9c44 --global
}
633
634 6306b5dd Ermal Lu?i
function ldap_test_connection($authcfg) {
635 55eb9c44 --global
	global $debug, $config, $g;
636
637 c61e4626 Ermal Lu?i
	if ($authcfg) {
638
                if (strstr($authcfg['ldap_urltype'], "Standard"))
639
                        $ldapproto = "ldap";
640
                else
641
                        $ldapproto = "ldaps";
642 83e0d4c8 jim-p
                $ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
643 c61e4626 Ermal Lu?i
                $ldapport           = $authcfg['ldap_port'];
644 9f27de6d jim-p
		if (!empty($ldapport))
645
			$ldapserver .= ":{$ldapport}";
646 c61e4626 Ermal Lu?i
                $ldapbasedn         = $authcfg['ldap_basedn'];
647
                $ldapbindun         = $authcfg['ldap_binddn'];
648
                $ldapbindpw         = $authcfg['ldap_bindpw'];
649 6306b5dd Ermal Lu?i
        } else
650
		return false;
651 55eb9c44 --global
652 c61e4626 Ermal Lu?i
        /* first check if there is even an LDAP server populated */
653
        if(!$ldapserver)
654
                return false;
655
656 fe2031ab Ermal
        /* Setup CA environment if needed. */
657
        ldap_setup_caenv($authcfg);
658
659 c61e4626 Ermal Lu?i
        /* connect and see if server is up */
660
        $error = false;
661 9f27de6d jim-p
	if (!($ldap = ldap_connect($ldapserver)))
662
		$error = true;
663 c61e4626 Ermal Lu?i
664
        if ($error == true) {
665 94021404 Carlos Eduardo Ramos
                log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
666 c61e4626 Ermal Lu?i
                return false;
667
        }
668 55eb9c44 --global
669
	return true;
670
}
671
672 fe2031ab Ermal
function ldap_setup_caenv($authcfg) {
673
	global $g;
674 007e59d2 jim-p
	require_once("certs.inc");
675 fe2031ab Ermal
676
	unset($caref);
677 a7702ed5 Ermal
	if (empty($authcfg['ldap_caref']) || !strstr($authcfg['ldap_urltype'], "SSL")) {
678 fe2031ab Ermal
		putenv('LDAPTLS_REQCERT=never');
679
		return;
680
	} else {
681 a7702ed5 Ermal
		$caref = lookup_ca($authcfg['ldap_caref']);
682 fe2031ab Ermal
		if (!$caref) {
683 a7702ed5 Ermal
			log_error(sprintf(gettext("LDAP: Could not lookup CA by reference for host %s."), $authcfg['ldap_caref']));
684 fe2031ab Ermal
			/* 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 b2a0a8e9 jim-p
		if (file_exists("{$g['varrun_path']}/certs/{$caref['refid']}.ca"))
691
			@unlink("{$g['varrun_path']}/certs/{$caref['refid']}.ca");
692
		file_put_contents("{$g['varrun_path']}/certs/{$caref['refid']}.ca", base64_decode($caref['crt']));
693
		@chmod("{$g['varrun_path']}/certs/{$caref['refid']}.ca", 0600);
694 fe2031ab Ermal
		putenv('LDAPTLS_REQCERT=hard');
695
		/* XXX: Probably even the hashed link should be created for this? */
696 906daddc Ermal
		putenv("LDAPTLS_CACERTDIR={$g['varrun_path']}/certs");
697 b2a0a8e9 jim-p
		putenv("LDAPTLS_CACERT={$g['varrun_path']}/certs/{$caref['refid']}.ca");
698 fe2031ab Ermal
	}
699
}
700
701 6306b5dd Ermal Lu?i
function ldap_test_bind($authcfg) {
702 55eb9c44 --global
	global $debug, $config, $g;
703
704 c61e4626 Ermal Lu?i
	if ($authcfg) {
705
                if (strstr($authcfg['ldap_urltype'], "Standard"))
706
                        $ldapproto = "ldap";
707
                else
708
                        $ldapproto = "ldaps";
709 83e0d4c8 jim-p
                $ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
710 c61e4626 Ermal Lu?i
                $ldapport           = $authcfg['ldap_port'];
711 9f27de6d jim-p
		if (!empty($ldapport))
712
			$ldapserver .= ":{$ldapport}";
713 c61e4626 Ermal Lu?i
                $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 6306b5dd Ermal Lu?i
	} else
722
		return false;
723 c61e4626 Ermal Lu?i
724
	/* first check if there is even an LDAP server populated */
725
        if(!$ldapserver)
726
                return false;
727
728 fe2031ab Ermal
	/* Setup CA environment if needed. */
729
	ldap_setup_caenv($authcfg);
730
731 c61e4626 Ermal Lu?i
        /* connect and see if server is up */
732
        $error = false;
733 9f27de6d jim-p
	if (!($ldap = ldap_connect($ldapserver)))
734
		$error = true;
735 c61e4626 Ermal Lu?i
736
        if ($error == true) {
737 94021404 Carlos Eduardo Ramos
                log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
738 c61e4626 Ermal Lu?i
                return false;
739
        }
740 55eb9c44 --global
741
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
742 c61e4626 Ermal Lu?i
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
743
 
744
	if ($ldapanon == true) {
745 6306b5dd Ermal Lu?i
		if (!($res = @ldap_bind($ldap))) {
746
			@ldap_close($ldap);
747 c61e4626 Ermal Lu?i
			return false;
748 6306b5dd Ermal Lu?i
		}
749
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
750
		@ldap_close($ldap);
751 55eb9c44 --global
		return false;
752 6306b5dd Ermal Lu?i
	}
753 55eb9c44 --global
754 6306b5dd Ermal Lu?i
	@ldap_unbind($ldap);
755 c61e4626 Ermal Lu?i
756 55eb9c44 --global
	return true;
757
}
758
759 6306b5dd Ermal Lu?i
function ldap_get_user_ous($show_complete_ou=true, $authcfg) {
760 55eb9c44 --global
	global $debug, $config, $g;
761
762
	if(!function_exists("ldap_connect"))
763
		return;
764
765 7a938f1b Ermal
	$ous = array();
766
767 c61e4626 Ermal Lu?i
	if ($authcfg) {
768
                if (strstr($authcfg['ldap_urltype'], "Standard"))
769
                        $ldapproto = "ldap";
770
                else
771
                        $ldapproto = "ldaps";
772 83e0d4c8 jim-p
                $ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
773 c61e4626 Ermal Lu?i
                $ldapport           = $authcfg['ldap_port'];
774 9f27de6d jim-p
		if (!empty($ldapport))
775
			$ldapserver .= ":{$ldapport}";
776 c61e4626 Ermal Lu?i
                $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 6306b5dd Ermal Lu?i
        } else
788
		return false;
789 55eb9c44 --global
790 c61e4626 Ermal Lu?i
        /* first check if there is even an LDAP server populated */
791
        if(!$ldapserver) {
792 94021404 Carlos Eduardo Ramos
                log_error(gettext("ERROR!  ldap_get_user_ous() backed selected with no LDAP authentication server defined."));
793 c61e4626 Ermal Lu?i
                return $ous;
794
        }
795
796 fe2031ab Ermal
	/* Setup CA environment if needed. */
797
	ldap_setup_caenv($authcfg);
798
799 c61e4626 Ermal Lu?i
	/* connect and see if server is up */
800
        $error = false;
801 9f27de6d jim-p
	if (!($ldap = ldap_connect($ldapserver)))
802
		$error = true;
803 c61e4626 Ermal Lu?i
804
        if ($error == true) {
805 94021404 Carlos Eduardo Ramos
        log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
806 c61e4626 Ermal Lu?i
                return $ous;
807
        }
808
809
	$ldapfilter = "(|(ou=*)(cn=Users))";
810 55eb9c44 --global
811
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
812 c61e4626 Ermal Lu?i
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
813 55eb9c44 --global
814 c61e4626 Ermal Lu?i
	if ($ldapanon == true) {
815
                if (!($res = @ldap_bind($ldap))) {
816 94021404 Carlos Eduardo Ramos
			log_error(sprintf(gettext("ERROR! ldap_get_user_ous() could not bind anonymously to server %s."), $ldapname));
817 6306b5dd Ermal Lu?i
			@ldap_close($ldap);
818 c61e4626 Ermal Lu?i
                        return $ous;
819
		}
820
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
821 94021404 Carlos Eduardo Ramos
		log_error(sprintf(gettext("ERROR! ldap_get_user_ous() could not bind to server %s."), $ldapname));
822 6306b5dd Ermal Lu?i
		@ldap_close($ldap);
823 c61e4626 Ermal Lu?i
		return $ous;
824 55eb9c44 --global
	}
825
826 c61e4626 Ermal Lu?i
	if ($ldapscope == "one")
827
		$ldapfunc = "ldap_list";
828
	else
829
		$ldapfunc = "ldap_search";
830 55eb9c44 --global
831 7a938f1b Ermal
	$search = @$ldapfunc($ldap, $ldapbasedn, $ldapfilter);
832
	$info = @ldap_get_entries($ldap, $search);
833 55eb9c44 --global
834
	if (is_array($info)) {
835
		foreach ($info as $inf) {
836
			if (!$show_complete_ou) {
837 cfbfd941 smos
				$inf_split = explode(",", $inf['dn']);
838 55eb9c44 --global
				$ou = $inf_split[0];
839
				$ou = str_replace("OU=","", $ou);
840 c61e4626 Ermal Lu?i
				$ou = str_replace("CN=","", $ou);
841 55eb9c44 --global
			} else
842
				if($inf['dn'])
843
					$ou = $inf['dn'];
844
			if($ou)
845
				$ous[] = $ou;
846
		}
847
	}
848
849 6306b5dd Ermal Lu?i
	@ldap_unbind($ldap);
850
851 55eb9c44 --global
	return $ous;
852
}
853
854 6306b5dd Ermal Lu?i
function ldap_get_groups($username, $authcfg) {
855 55eb9c44 --global
	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 2ce660ad smos
		$username_split = explode("@", $username);
865 55eb9c44 --global
		$username = $username_split[0];		
866
	}
867
868
	if(stristr($username, "\\")) {
869 cfbfd941 smos
		$username_split = explode("\\", $username);
870 55eb9c44 --global
		$username = $username_split[0];        
871
	}    
872
	
873
	//log_error("Getting LDAP groups for {$username}.");
874 c61e4626 Ermal Lu?i
        if ($authcfg) {
875
                if (strstr($authcfg['ldap_urltype'], "Standard"))
876
                        $ldapproto = "ldap";
877
                else
878
                        $ldapproto = "ldaps";
879 83e0d4c8 jim-p
                $ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
880 c61e4626 Ermal Lu?i
                $ldapport           = $authcfg['ldap_port'];
881 9f27de6d jim-p
		if (!empty($ldapport))
882
			$ldapserver .= ":{$ldapport}";
883 c61e4626 Ermal Lu?i
                $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 6306b5dd Ermal Lu?i
	} else
900
		return false;
901 c61e4626 Ermal Lu?i
902 55eb9c44 --global
	$ldapdn             = $_SESSION['ldapdn'];
903 c61e4626 Ermal Lu?i
904 55eb9c44 --global
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
905
	$ldapgroupattribute = strtolower($ldapgroupattribute);
906 c61e4626 Ermal Lu?i
	$memberof = array();
907 55eb9c44 --global
908 fe2031ab Ermal
        /* Setup CA environment if needed. */
909
        ldap_setup_caenv($authcfg);
910
911 55eb9c44 --global
	/* connect and see if server is up */
912 c61e4626 Ermal Lu?i
	$error = false;
913 9f27de6d jim-p
	if (!($ldap = ldap_connect($ldapserver)))
914
		$error = true;
915 c61e4626 Ermal Lu?i
916
	if ($error == true) {
917 94021404 Carlos Eduardo Ramos
		log_error(sprintf(gettext("ERROR! ldap_get_groups() Could not connect to server %s."), $ldapname));
918 c61e4626 Ermal Lu?i
                return memberof;
919
        }
920 55eb9c44 --global
    
921
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
922 c61e4626 Ermal Lu?i
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
923 55eb9c44 --global
924
	/* bind as user that has rights to read group attributes */
925 c61e4626 Ermal Lu?i
	if ($ldapanon == true) {
926 6306b5dd Ermal Lu?i
                if (!($res = @ldap_bind($ldap))) {
927 94021404 Carlos Eduardo Ramos
			log_error(sprintf(gettext("ERROR! ldap_get_groups() could not bind anonymously to server %s."), $ldapname));
928 6306b5dd Ermal Lu?i
			@ldap_close($ldap);
929 c61e4626 Ermal Lu?i
                        return false;
930 6306b5dd Ermal Lu?i
		}
931 c61e4626 Ermal Lu?i
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
932 94021404 Carlos Eduardo Ramos
		log_error(sprintf(gettext("ERROR! ldap_get_groups() could not bind to server %s."), $ldapname));
933 6306b5dd Ermal Lu?i
		@ldap_close($ldap);
934 c61e4626 Ermal Lu?i
		return memberof;
935 55eb9c44 --global
	}
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 c61e4626 Ermal Lu?i
	if ($ldapscope == "one")
942
                $ldapfunc = "ldap_list";
943
        else
944
                $ldapfunc = "ldap_search";
945
946 7a938f1b Ermal
	$search    = @$ldapfunc($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
947
	$info      = @ldap_get_entries($ldap, $search);
948 55eb9c44 --global
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 cfbfd941 smos
				$membersplit = explode(",", $member);
956 55eb9c44 --global
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
957
			}
958
		}
959
	}
960
	
961
	/* Time to close LDAP connection */
962 6306b5dd Ermal Lu?i
	@ldap_unbind($ldap);
963 55eb9c44 --global
	
964
	$groups = print_r($memberof,true);
965
	
966
	//log_error("Returning groups ".$groups." for user $username");
967
	
968
	return $memberof;
969
}
970
971 83e0d4c8 jim-p
function ldap_format_host($host) {
972
	return is_ipaddrv6($host) ? "[$host]" : $host ;
973
}
974
975 6306b5dd Ermal Lu?i
function ldap_backed($username, $passwd, $authcfg) {
976 55eb9c44 --global
	global $debug, $config;
977
	
978
	if(!$username) 
979
		return;
980
981
	if(!function_exists("ldap_connect"))
982
		return;
983
984
	if(stristr($username, "@")) {
985 2ce660ad smos
		$username_split = explode("@", $username);
986 55eb9c44 --global
		$username = $username_split[0];        
987
	}
988
	if(stristr($username, "\\")) {
989 cfbfd941 smos
		$username_split = explode("\\", $username);
990 55eb9c44 --global
		$username = $username_split[0];        
991
	}
992
993 c61e4626 Ermal Lu?i
	if ($authcfg) {
994
		if (strstr($authcfg['ldap_urltype'], "Standard"))
995
			$ldapproto = "ldap";
996
		else
997
			$ldapproto = "ldaps";
998 83e0d4c8 jim-p
		$ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
999 c61e4626 Ermal Lu?i
		$ldapport	    = $authcfg['ldap_port'];
1000 9f27de6d jim-p
		if (!empty($ldapport))
1001
			$ldapserver .= ":{$ldapport}";
1002 c61e4626 Ermal Lu?i
                $ldapbasedn         = $authcfg['ldap_basedn'];
1003
                $ldapbindun         = $authcfg['ldap_binddn'];
1004
                $ldapbindpw         = $authcfg['ldap_bindpw'];
1005
		if (empty($ldapbindun) || empty($ldapbindpw))
1006
			$ldapanon = true;
1007
		else
1008
			$ldapanon = false;
1009
                $ldapauthcont       = $authcfg['ldap_authcn'];
1010
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
1011 d1b69106 namezero111111
                $ldapextendedqueryenabled  = $authcfg['ldap_extended_enabled'];
1012
                $ldapextendedquery = $authcfg['ldap_extended_query'];
1013
                $ldapfilter         = "";
1014
                if(!$ldapextendedqueryenabled)
1015
                {
1016
                        $ldapfilter = "({$ldapnameattribute}={$username})";
1017
                }
1018
                else
1019
                {
1020
                        $ldapfilter = 
1021
"(&({$ldapnameattribute}={$username})({$ldapextendedquery}))";
1022
                } 
1023 c61e4626 Ermal Lu?i
                $ldaptype           = "";
1024
                $ldapver            = $authcfg['ldap_protver'];
1025
		$ldapname	    = $authcfg['name'];
1026
		$ldapscope	    = $authcfg['ldap_scope'];
1027 6306b5dd Ermal Lu?i
	} else
1028
		return false;
1029 55eb9c44 --global
1030
	/* first check if there is even an LDAP server populated */ 
1031
	if(!$ldapserver) {
1032 c61e4626 Ermal Lu?i
		if ($ldapfallback) {
1033 94021404 Carlos Eduardo Ramos
			log_error(gettext("ERROR! ldap_backed() called with no LDAP authentication server defined.  Defaulting to local user database. Visit System -> User Manager."));
1034 c61e4626 Ermal Lu?i
			return local_backed($username, $passwd);
1035
		} else
1036 94021404 Carlos Eduardo Ramos
			log_error(gettext("ERROR! ldap_backed() called with no LDAP authentication server defined."));
1037 c61e4626 Ermal Lu?i
1038
		return false;
1039 55eb9c44 --global
	}
1040
	
1041 fe2031ab Ermal
        /* Setup CA environment if needed. */
1042
        ldap_setup_caenv($authcfg);
1043
1044 906daddc Ermal
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
1045
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
1046
1047 55eb9c44 --global
	/* Make sure we can connect to LDAP */
1048 c61e4626 Ermal Lu?i
	$error = false;
1049 9f27de6d jim-p
	if (!($ldap = ldap_connect($ldapserver)))
1050 c61e4626 Ermal Lu?i
		$error = true;
1051
1052
	if ($error == true) {
1053 94021404 Carlos Eduardo Ramos
		log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
1054 c61e4626 Ermal Lu?i
		return false;
1055 55eb9c44 --global
	}
1056 c61e4626 Ermal Lu?i
1057 55eb9c44 --global
	/* ok, its up.  now, lets bind as the bind user so we can search it */
1058 c61e4626 Ermal Lu?i
	$error = false;
1059
	if ($ldapanon == true) {
1060
                if (!($res = @ldap_bind($ldap)))
1061
                        $error = true;
1062 323dc2e7 Warren Baker
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
1063 c61e4626 Ermal Lu?i
		$error = true;
1064
1065
	if ($error == true) {
1066 6306b5dd Ermal Lu?i
		@ldap_close($ldap);
1067 94021404 Carlos Eduardo Ramos
		log_error(sprintf(gettext("ERROR! Could not bind to server %s."), $ldapname));
1068 c61e4626 Ermal Lu?i
		return false;
1069 55eb9c44 --global
	}
1070
	
1071
	/* Get LDAP Authcontainers and split em up. */
1072 cfbfd941 smos
	$ldac_splits = explode(";", $ldapauthcont);
1073 55eb9c44 --global
	
1074
	/* setup the usercount so we think we havn't found anyone yet */
1075
	$usercount  = 0;
1076
1077
	/*****************************************************************/
1078
	/*  We First find the user based on username and filter          */
1079
	/*  Then, once we find the first occurance of that person        */
1080
	/*  We set seesion variables to ponit to the OU and DN of the    */
1081
	/*  Person.  To later be used by ldap_get_groups.                */
1082
	/*  that way we don't have to search twice.                      */
1083
	/*****************************************************************/
1084 3ac8324f Ermal
	if ($debug)
1085
		log_auth(sprintf(gettext("Now Searching for %s in directory."), $username));
1086 c61e4626 Ermal Lu?i
	/* Iterate through the user containers for search */
1087
	foreach ($ldac_splits as $i => $ldac_split) {
1088
		/* Make sure we just use the first user we find */
1089 3ac8324f Ermal
		if ($debug)
1090
			log_auth(sprintf(gettext('Now Searching in server %1$s, container %2$s with filter %3$s.'), $ldapname, $ldac_split, $ldapfilter));
1091 c61e4626 Ermal Lu?i
		if ($ldapscope == "one")
1092
			$ldapfunc = "ldap_list";
1093
		else
1094
			$ldapfunc = "ldap_search";
1095
		/* Support legacy auth container specification. */
1096 9ae11a62 Scott Ullrich
		if (stristr($ldac_split, "DC=") || empty($ldapbasedn))
1097
			$search	 = @$ldapfunc($ldap,$ldac_split,$ldapfilter);
1098
		else
1099
			$search  = @$ldapfunc($ldap,"{$ldac_split},{$ldapbasedn}",$ldapfilter);
1100 c61e4626 Ermal Lu?i
		if (!$search) {
1101 94021404 Carlos Eduardo Ramos
			log_error(sprintf(gettext("Search resulted in error: %s"), ldap_error($ldap)));
1102 c61e4626 Ermal Lu?i
			continue;
1103 55eb9c44 --global
		}
1104 c61e4626 Ermal Lu?i
		$info	 = ldap_get_entries($ldap,$search);
1105
		$matches = $info['count'];
1106 55eb9c44 --global
		if ($matches == 1){
1107 c61e4626 Ermal Lu?i
			$userdn = $_SESSION['ldapdn'] = $info[0]['dn'];
1108
			$_SESSION['ldapou'] = $ldac_split[$i];
1109
			$_SESSION['ldapon'] = "true";
1110
			$usercount = 1;
1111
			break;
1112 55eb9c44 --global
		}
1113
	}
1114
1115 c61e4626 Ermal Lu?i
	if ($usercount != 1){
1116 6306b5dd Ermal Lu?i
		@ldap_unbind($ldap);
1117 94021404 Carlos Eduardo Ramos
		log_error(gettext("ERROR! Either LDAP search failed, or multiple users were found."));
1118 c61e4626 Ermal Lu?i
		return false;                         
1119 55eb9c44 --global
	}
1120 c61e4626 Ermal Lu?i
1121 55eb9c44 --global
	/* Now lets bind as the user we found */
1122 c61e4626 Ermal Lu?i
	if (!($res = @ldap_bind($ldap, $userdn, $passwd))) {
1123 3697adb2 jim-p
		log_error(sprintf(gettext('ERROR! Could not login to server %1$s as user %2$s: %3$s'), $ldapname, $username, ldap_error($ldap)));
1124 6306b5dd Ermal Lu?i
		@ldap_unbind($ldap);
1125 c61e4626 Ermal Lu?i
		return false;
1126 55eb9c44 --global
	}
1127
1128 2004def5 Ermal
	if ($debug)
1129
		log_auth(sprintf(gettext('Logged in successfully as %1$s via LDAP server %2$s with DN = %3$s.'), $username, $ldapname, $userdn));
1130 c61e4626 Ermal Lu?i
1131
	/* At this point we are bound to LDAP so the user was auth'd okay. Close connection. */
1132 6306b5dd Ermal Lu?i
	@ldap_unbind($ldap);
1133 55eb9c44 --global
1134
	return true;
1135
}
1136
1137 1492e02c Ermal
function radius_backed($username, $passwd, $authcfg, &$attributes = array()) {
1138 a13ce628 Ermal Lu?i
	global $debug, $config;
1139 55eb9c44 --global
	$ret = false;
1140
1141 868c6826 Ermal
	require_once("radius.inc");
1142
1143 55eb9c44 --global
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
1144 c61e4626 Ermal Lu?i
	if ($authcfg) {
1145
		$radiusservers = array();
1146
		$radiusservers[0]['ipaddr'] = $authcfg['host'];
1147
		$radiusservers[0]['port'] = $authcfg['radius_auth_port'];
1148
		$radiusservers[0]['sharedsecret'] = $authcfg['radius_secret'];
1149 bddd2be8 jim-p
		$radiusservers[0]['timeout'] = $authcfg['radius_timeout'];
1150 c61e4626 Ermal Lu?i
	} else
1151 6306b5dd Ermal Lu?i
		return false;
1152 c61e4626 Ermal Lu?i
1153 55eb9c44 --global
	/* Add a new servers to our instance */
1154 bddd2be8 jim-p
	foreach ($radiusservers as $radsrv) {
1155
		$timeout = (is_numeric($radsrv['timeout'])) ? $radsrv['timeout'] : 5;
1156
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret'], $timeout);
1157
	}
1158 55eb9c44 --global
1159 6e815096 Ermal
	if (PEAR::isError($rauth->start())) {
1160 55eb9c44 --global
		$retvalue['auth_val'] = 1;
1161
		$retvalue['error'] = $rauth->getError();
1162
		if ($debug)
1163 8e1fd4fe Renato Botelho
			printf(gettext("Radius start: %s<br>\n"), $retvalue['error']);
1164 55eb9c44 --global
	}
1165
1166
	// XXX - billm - somewhere in here we need to handle securid challenge/response
1167
1168
	/* Send request */
1169
	$result = $rauth->send();
1170
	if (PEAR::isError($result)) {
1171
		$retvalue['auth_val'] = 1;
1172
		$retvalue['error'] = $result->getMessage();
1173
		if ($debug)
1174 8e1fd4fe Renato Botelho
			printf(gettext("Radius send failed: %s<br>\n"), $retvalue['error']);
1175 55eb9c44 --global
	} else if ($result === true) {
1176 1492e02c Ermal
		if ($rauth->getAttributes())
1177
			$attributes = $rauth->listAttributes();
1178 55eb9c44 --global
		$retvalue['auth_val'] = 2;
1179
		if ($debug)
1180
			printf(gettext("Radius Auth succeeded")."<br>\n");
1181
		$ret = true;
1182
	} else {
1183
		$retvalue['auth_val'] = 3;
1184
		if ($debug)
1185
			printf(gettext("Radius Auth rejected")."<br>\n");
1186
	}
1187
1188
	// close OO RADIUS_AUTHENTICATION
1189
	$rauth->close();
1190
1191
	return $ret;
1192
}
1193
1194 7dd044f2 sullrich
function get_user_expiration_date($username) {
1195 a13ce628 Ermal Lu?i
	$user = getUserEntry($username);
1196
	if ($user['expires']) 
1197
		return $user['expires'];
1198
}
1199
1200
function is_account_expired($username) {
1201
	$expirydate = get_user_expiration_date($username);
1202
	if ($expirydate) {
1203
		if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($expirydate))))
1204
			return true;
1205 7dd044f2 sullrich
	}
1206 a13ce628 Ermal Lu?i
1207
	return false;
1208 7dd044f2 sullrich
}
1209
1210 b4bfd25d sullrich
function is_account_disabled($username) {
1211 a13ce628 Ermal Lu?i
	$user = getUserEntry($username);
1212
	if (isset($user['disabled']))
1213
		return true;
1214
1215 b4bfd25d sullrich
	return false;
1216
}
1217
1218 c61e4626 Ermal Lu?i
function auth_get_authserver($name) {
1219
        global $config;
1220
1221
        if (is_array($config['system']['authserver'])) {
1222
                foreach ($config['system']['authserver'] as $authcfg) {
1223
                        if ($authcfg['name'] == $name)
1224
                                return $authcfg;
1225
                }
1226
        }
1227 6306b5dd Ermal Lu?i
	if ($name == "Local Database")
1228 96568521 Vinicius Coque
		return array("name" => gettext("Local Database"), "type" => "Local Auth", "host" => $config['system']['hostname']);
1229 6306b5dd Ermal Lu?i
}
1230
1231
function auth_get_authserver_list() {
1232
        global $config;
1233
1234
	$list = array();
1235
1236
        if (is_array($config['system']['authserver'])) {
1237
                foreach ($config['system']['authserver'] as $authcfg) {
1238
			/* Add support for disabled entries? */
1239
			$list[$authcfg['name']] = $authcfg;
1240
                }
1241
        }
1242
1243 96568521 Vinicius Coque
	$list["Local Database"] = array( "name" => gettext("Local Database"), "type" => "Local Auth", "host" => $config['system']['hostname']);
1244 6306b5dd Ermal Lu?i
	return $list;
1245 c61e4626 Ermal Lu?i
}
1246
1247 fb0f22c0 Ermal Lu?i
function getUserGroups($username, $authcfg) {
1248
	global $config;
1249
1250
	$allowed_groups = array();
1251
1252
	switch($authcfg['type']) {
1253
        case 'ldap':
1254
		$allowed_groups = @ldap_get_groups($username, $authcfg);
1255
		break;
1256
	case 'radius':
1257
		break;
1258
	default:
1259
		$user = getUserEntry($username);
1260
		$allowed_groups = @local_user_get_groups($user, true);
1261
		break;
1262
	}
1263
1264
	$member_groups = array();
1265
        if (is_array($config['system']['group'])) {
1266
                foreach ($config['system']['group'] as $group)
1267
                        if (in_array($group['name'], $allowed_groups))
1268
				$member_groups[] = $group['name'];
1269
	}
1270
1271
	return $member_groups;
1272
}
1273
1274 1492e02c Ermal
function authenticate_user($username, $password, $authcfg = NULL, &$attributes = array()) {
1275 c61e4626 Ermal Lu?i
1276
	if (!$authcfg) {
1277
		return local_backed($username, $password);
1278
	}
1279
1280
	$authenticated = false;
1281
	switch($authcfg['type']) {
1282
        case 'ldap':
1283
                if (ldap_backed($username, $password, $authcfg))
1284
                        $authenticated = true;
1285
                break;
1286
        case 'radius':
1287 1492e02c Ermal
                if (radius_backed($username, $password, $authcfg, $attributes))
1288 c61e4626 Ermal Lu?i
                        $authenticated = true;
1289
                break;
1290
        default:
1291
                /* lookup user object by name */
1292
                if (local_backed($username, $password))
1293
                        $authenticated = true;
1294
                break;
1295
        }
1296
1297
	return $authenticated;
1298
}
1299
1300 6306b5dd Ermal Lu?i
function session_auth() {
1301
	global $HTTP_SERVER_VARS, $config, $_SESSION, $page;
1302 55eb9c44 --global
1303 49ddf9a1 Warren Baker
	// Handle HTTPS httponly and secure flags
1304
	if($config['system']['webgui']['protocol'] == "https") {
1305
		$currentCookieParams = session_get_cookie_params();
1306
		session_set_cookie_params(
1307
			$currentCookieParams["lifetime"],
1308
			$currentCookieParams["path"],
1309
			NULL,
1310
			true,
1311
			true
1312
		);
1313
	}
1314
1315 9252d093 Ermal
	if (!session_id())
1316
		session_start();
1317 55eb9c44 --global
1318
	/* Validate incoming login request */
1319 88165371 Ermal
	if (isset($_POST['login']) && !empty($_POST['usernamefld']) && !empty($_POST['passwordfld'])) {
1320 6306b5dd Ermal Lu?i
		$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
1321
		if (authenticate_user($_POST['usernamefld'], $_POST['passwordfld'], $authcfg) || 
1322
		    authenticate_user($_POST['usernamefld'], $_POST['passwordfld'])) {
1323
			$_SESSION['Logged_In'] = "True";
1324
			$_SESSION['Username'] = $_POST['usernamefld'];
1325
			$_SESSION['last_access'] = time();
1326 4fc3855f smos
			if(! isset($config['system']['webgui']['quietlogin'])) {
1327 54bdff75 Vinicius Coque
				log_auth(sprintf(gettext("Successful login for user '%1\$s' from: %2\$s"), $_POST['usernamefld'], $_SERVER['REMOTE_ADDR']));
1328 4fc3855f smos
			}
1329 f23e6363 Ermal
			$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1330 92140621 Ermal
			if (isset($_POST['postafterlogin']))
1331
				return true;
1332 80b292f3 Ermal
			else {
1333
				if (empty($page))
1334
					$page = "/";
1335
				header("Location: {$page}");
1336
			}
1337 f23e6363 Ermal
			exit;
1338 a13ce628 Ermal Lu?i
		} else {
1339
			/* give the user an error message */
1340
			$_SESSION['Login_Error'] = "Username or Password incorrect";
1341 65f7fba8 Scott Ullrich
			log_auth("webConfigurator authentication error for '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}");
1342 a13ce628 Ermal Lu?i
			if(isAjax()) {
1343
				echo "showajaxmessage('{$_SESSION['Login_Error']}');";
1344
				return;
1345 55eb9c44 --global
			}
1346
		}
1347
	}
1348
1349
	/* Show login page if they aren't logged in */
1350 409105ec Ermal Lu?i
	if (empty($_SESSION['Logged_In']))
1351 55eb9c44 --global
		return false;
1352
1353
	/* If session timeout isn't set, we don't mark sessions stale */
1354 02647583 Ermal
	if (!isset($config['system']['webgui']['session_timeout'])) {
1355 bdadaf3c Chris Buechler
		/* Default to 4 hour timeout if one is not set */
1356
		if ($_SESSION['last_access'] < (time() - 14400)) {
1357
			$_GET['logout'] = true;
1358
			$_SESSION['Logout'] = true;
1359 9a985f9e Ermal
		} else
1360
			$_SESSION['last_access'] = time();	
1361 02647583 Ermal
	} else if (intval($config['system']['webgui']['session_timeout']) == 0) {
1362
		/* only update if it wasn't ajax */
1363
		if (!isAjax())
1364
			$_SESSION['last_access'] = time();
1365 bdadaf3c Chris Buechler
	} else {
1366 55eb9c44 --global
		/* Check for stale session */
1367
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
1368
			$_GET['logout'] = true;
1369
			$_SESSION['Logout'] = true;
1370
		} else {
1371
			/* only update if it wasn't ajax */
1372
			if (!isAjax())
1373
				$_SESSION['last_access'] = time();
1374
		}
1375
	}
1376
1377
	/* user hit the logout button */
1378
	if (isset($_GET['logout'])) {
1379
1380
		if ($_SESSION['Logout'])
1381 addc0439 Renato Botelho
			log_error(sprintf(gettext("Session timed out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1382 55eb9c44 --global
		else
1383 addc0439 Renato Botelho
			log_error(sprintf(gettext("User logged out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1384 55eb9c44 --global
1385
		/* wipe out $_SESSION */
1386
		$_SESSION = array();
1387
1388
		if (isset($_COOKIE[session_name()]))
1389
			setcookie(session_name(), '', time()-42000, '/');
1390
1391
		/* and destroy it */
1392
		session_destroy();
1393
1394 cfbfd941 smos
		$scriptName = explode("/", $_SERVER["SCRIPT_FILENAME"]);
1395 55eb9c44 --global
		$scriptElms = count($scriptName);
1396
		$scriptName = $scriptName[$scriptElms-1];
1397
1398
		if (isAjax())
1399
			return false;
1400
1401
		/* redirect to page the user is on, it'll prompt them to login again */
1402 6dc88d53 Ermal Luci
		Header("Location: {$scriptName}");
1403 55eb9c44 --global
1404
		return false;
1405
	}
1406
1407
	/*
1408
	 * this is for debugging purpose if you do not want to use Ajax
1409
	 * to submit a HTML form. It basically diables the observation
1410
	 * of the submit event and hence does not trigger Ajax.
1411
	 */
1412 f23e6363 Ermal
	if ($_GET['disable_ajax'])
1413 55eb9c44 --global
		$_SESSION['NO_AJAX'] = "True";
1414
1415
	/*
1416
	 * Same to re-enable Ajax.
1417
	 */
1418 f23e6363 Ermal
	if ($_GET['enable_ajax'])
1419 55eb9c44 --global
		unset($_SESSION['NO_AJAX']);
1420
1421
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1422
	return true;
1423
}
1424
1425 88165371 Ermal
?>