Project

General

Profile

Download (41.7 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
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
643
                $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
		if (file_exists("{$g['varrun_path']}/certs/{$authcfg['name']}.ca"))
691
			@unlink("{$g['varrun_path']}/certs/{$authcfg['name']}.ca");
692
		file_put_contents("{$g['varrun_path']}/certs/{$authcfg['name']}.ca", base64_decode($caref['crt']));
693
		@chmod("{$g['varrun_path']}/certs/{$authcfg['name']}.ca", 0600);
694
		putenv('LDAPTLS_REQCERT=hard');
695
		/* XXX: Probably even the hashed link should be created for this? */
696 906daddc Ermal
		putenv("LDAPTLS_CACERTDIR={$g['varrun_path']}/certs");
697
		putenv("LDAPTLS_CACERT={$g['varrun_path']}/certs/{$authcfg['name']}.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
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
710
                $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
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
773
                $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
                $ldapserver         = "{$ldapproto}://{$authcfg['host']}";
880
                $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 6306b5dd Ermal Lu?i
function ldap_backed($username, $passwd, $authcfg) {
972 55eb9c44 --global
	global $debug, $config;
973
	
974
	if(!$username) 
975
		return;
976
977
	if(!function_exists("ldap_connect"))
978
		return;
979
980
	if(stristr($username, "@")) {
981 2ce660ad smos
		$username_split = explode("@", $username);
982 55eb9c44 --global
		$username = $username_split[0];        
983
	}
984
	if(stristr($username, "\\")) {
985 cfbfd941 smos
		$username_split = explode("\\", $username);
986 55eb9c44 --global
		$username = $username_split[0];        
987
	}
988
989 c61e4626 Ermal Lu?i
	if ($authcfg) {
990
		if (strstr($authcfg['ldap_urltype'], "Standard"))
991
			$ldapproto = "ldap";
992
		else
993
			$ldapproto = "ldaps";
994
		$ldapserver         = "{$ldapproto}://{$authcfg['host']}";
995
		$ldapport	    = $authcfg['ldap_port'];
996 9f27de6d jim-p
		if (!empty($ldapport))
997
			$ldapserver .= ":{$ldapport}";
998 c61e4626 Ermal Lu?i
                $ldapbasedn         = $authcfg['ldap_basedn'];
999
                $ldapbindun         = $authcfg['ldap_binddn'];
1000
                $ldapbindpw         = $authcfg['ldap_bindpw'];
1001
		if (empty($ldapbindun) || empty($ldapbindpw))
1002
			$ldapanon = true;
1003
		else
1004
			$ldapanon = false;
1005
                $ldapauthcont       = $authcfg['ldap_authcn'];
1006
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
1007 d1b69106 namezero111111
                $ldapextendedqueryenabled  = $authcfg['ldap_extended_enabled'];
1008
                $ldapextendedquery = $authcfg['ldap_extended_query'];
1009
                $ldapfilter         = "";
1010
                if(!$ldapextendedqueryenabled)
1011
                {
1012
                        $ldapfilter = "({$ldapnameattribute}={$username})";
1013
                }
1014
                else
1015
                {
1016
                        $ldapfilter = 
1017
"(&({$ldapnameattribute}={$username})({$ldapextendedquery}))";
1018
                } 
1019 c61e4626 Ermal Lu?i
                $ldaptype           = "";
1020
                $ldapver            = $authcfg['ldap_protver'];
1021
		$ldapname	    = $authcfg['name'];
1022
		$ldapscope	    = $authcfg['ldap_scope'];
1023 6306b5dd Ermal Lu?i
	} else
1024
		return false;
1025 55eb9c44 --global
1026
	/* first check if there is even an LDAP server populated */ 
1027
	if(!$ldapserver) {
1028 c61e4626 Ermal Lu?i
		if ($ldapfallback) {
1029 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."));
1030 c61e4626 Ermal Lu?i
			return local_backed($username, $passwd);
1031
		} else
1032 94021404 Carlos Eduardo Ramos
			log_error(gettext("ERROR! ldap_backed() called with no LDAP authentication server defined."));
1033 c61e4626 Ermal Lu?i
1034
		return false;
1035 55eb9c44 --global
	}
1036
	
1037 fe2031ab Ermal
        /* Setup CA environment if needed. */
1038
        ldap_setup_caenv($authcfg);
1039
1040 906daddc Ermal
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
1041
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
1042
1043 55eb9c44 --global
	/* Make sure we can connect to LDAP */
1044 c61e4626 Ermal Lu?i
	$error = false;
1045 9f27de6d jim-p
	if (!($ldap = ldap_connect($ldapserver)))
1046 c61e4626 Ermal Lu?i
		$error = true;
1047
1048
	if ($error == true) {
1049 94021404 Carlos Eduardo Ramos
		log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
1050 c61e4626 Ermal Lu?i
		return false;
1051 55eb9c44 --global
	}
1052 c61e4626 Ermal Lu?i
1053 55eb9c44 --global
	/* ok, its up.  now, lets bind as the bind user so we can search it */
1054 c61e4626 Ermal Lu?i
	$error = false;
1055
	if ($ldapanon == true) {
1056
                if (!($res = @ldap_bind($ldap)))
1057
                        $error = true;
1058
	} else if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
1059
		$error = true;
1060
1061
	if ($error == true) {
1062 6306b5dd Ermal Lu?i
		@ldap_close($ldap);
1063 94021404 Carlos Eduardo Ramos
		log_error(sprintf(gettext("ERROR! Could not bind to server %s."), $ldapname));
1064 c61e4626 Ermal Lu?i
		return false;
1065 55eb9c44 --global
	}
1066
	
1067
	/* Get LDAP Authcontainers and split em up. */
1068 cfbfd941 smos
	$ldac_splits = explode(";", $ldapauthcont);
1069 55eb9c44 --global
	
1070
	/* setup the usercount so we think we havn't found anyone yet */
1071
	$usercount  = 0;
1072
1073
	/*****************************************************************/
1074
	/*  We First find the user based on username and filter          */
1075
	/*  Then, once we find the first occurance of that person        */
1076
	/*  We set seesion variables to ponit to the OU and DN of the    */
1077
	/*  Person.  To later be used by ldap_get_groups.                */
1078
	/*  that way we don't have to search twice.                      */
1079
	/*****************************************************************/
1080 94021404 Carlos Eduardo Ramos
	log_error(sprintf(gettext("Now Searching for %s in directory."), $username));
1081 c61e4626 Ermal Lu?i
	/* Iterate through the user containers for search */
1082
	foreach ($ldac_splits as $i => $ldac_split) {
1083
		/* Make sure we just use the first user we find */
1084 addc0439 Renato Botelho
		log_error(sprintf(gettext('Now Searching in server %1$s, container %2$s with filter %3$s.'), $ldapname, $ldac_split, $ldapfilter));
1085 c61e4626 Ermal Lu?i
		if ($ldapscope == "one")
1086
			$ldapfunc = "ldap_list";
1087
		else
1088
			$ldapfunc = "ldap_search";
1089
		/* Support legacy auth container specification. */
1090 9ae11a62 Scott Ullrich
		if (stristr($ldac_split, "DC=") || empty($ldapbasedn))
1091
			$search	 = @$ldapfunc($ldap,$ldac_split,$ldapfilter);
1092
		else
1093
			$search  = @$ldapfunc($ldap,"{$ldac_split},{$ldapbasedn}",$ldapfilter);
1094 c61e4626 Ermal Lu?i
		if (!$search) {
1095 94021404 Carlos Eduardo Ramos
			log_error(sprintf(gettext("Search resulted in error: %s"), ldap_error($ldap)));
1096 c61e4626 Ermal Lu?i
			continue;
1097 55eb9c44 --global
		}
1098 c61e4626 Ermal Lu?i
		$info	 = ldap_get_entries($ldap,$search);
1099
		$matches = $info['count'];
1100 55eb9c44 --global
		if ($matches == 1){
1101 c61e4626 Ermal Lu?i
			$userdn = $_SESSION['ldapdn'] = $info[0]['dn'];
1102
			$_SESSION['ldapou'] = $ldac_split[$i];
1103
			$_SESSION['ldapon'] = "true";
1104
			$usercount = 1;
1105
			break;
1106 55eb9c44 --global
		}
1107
	}
1108
1109 c61e4626 Ermal Lu?i
	if ($usercount != 1){
1110 6306b5dd Ermal Lu?i
		@ldap_unbind($ldap);
1111 94021404 Carlos Eduardo Ramos
		log_error(gettext("ERROR! Either LDAP search failed, or multiple users were found."));
1112 c61e4626 Ermal Lu?i
		return false;                         
1113 55eb9c44 --global
	}
1114 c61e4626 Ermal Lu?i
1115 55eb9c44 --global
	/* Now lets bind as the user we found */
1116 c61e4626 Ermal Lu?i
	if (!($res = @ldap_bind($ldap, $userdn, $passwd))) {
1117 addc0439 Renato Botelho
		log_error(sprintf(gettext('ERROR! Could not login to server %1$s as user %2$s.'), $ldapname, $username));
1118 6306b5dd Ermal Lu?i
		@ldap_unbind($ldap);
1119 c61e4626 Ermal Lu?i
		return false;
1120 55eb9c44 --global
	}
1121
1122 addc0439 Renato Botelho
	log_error(sprintf(gettext('Logged in successfully as %1$s via LDAP server %2$s with DN = %3$s.'), $username, $ldapname, $userdn));
1123 c61e4626 Ermal Lu?i
1124
	/* At this point we are bound to LDAP so the user was auth'd okay. Close connection. */
1125 6306b5dd Ermal Lu?i
	@ldap_unbind($ldap);
1126 55eb9c44 --global
1127
	return true;
1128
}
1129
1130 6306b5dd Ermal Lu?i
function radius_backed($username, $passwd, $authcfg){
1131 a13ce628 Ermal Lu?i
	global $debug, $config;
1132 55eb9c44 --global
	$ret = false;
1133
1134 868c6826 Ermal
	require_once("radius.inc");
1135
1136 55eb9c44 --global
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
1137 c61e4626 Ermal Lu?i
	if ($authcfg) {
1138
		$radiusservers = array();
1139
		$radiusservers[0]['ipaddr'] = $authcfg['host'];
1140
		$radiusservers[0]['port'] = $authcfg['radius_auth_port'];
1141
		$radiusservers[0]['sharedsecret'] = $authcfg['radius_secret'];
1142
	} else
1143 6306b5dd Ermal Lu?i
		return false;
1144 c61e4626 Ermal Lu?i
1145 55eb9c44 --global
	/* Add a new servers to our instance */
1146
	foreach ($radiusservers as $radsrv)
1147
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
1148
1149 6e815096 Ermal
	if (PEAR::isError($rauth->start())) {
1150 55eb9c44 --global
		$retvalue['auth_val'] = 1;
1151
		$retvalue['error'] = $rauth->getError();
1152
		if ($debug)
1153 8e1fd4fe Renato Botelho
			printf(gettext("Radius start: %s<br>\n"), $retvalue['error']);
1154 55eb9c44 --global
	}
1155
1156
	// XXX - billm - somewhere in here we need to handle securid challenge/response
1157
1158
	/* Send request */
1159
	$result = $rauth->send();
1160
	if (PEAR::isError($result)) {
1161
		$retvalue['auth_val'] = 1;
1162
		$retvalue['error'] = $result->getMessage();
1163
		if ($debug)
1164 8e1fd4fe Renato Botelho
			printf(gettext("Radius send failed: %s<br>\n"), $retvalue['error']);
1165 55eb9c44 --global
	} else if ($result === true) {
1166
		$retvalue['auth_val'] = 2;
1167
		if ($debug)
1168
			printf(gettext("Radius Auth succeeded")."<br>\n");
1169
		$ret = true;
1170
	} else {
1171
		$retvalue['auth_val'] = 3;
1172
		if ($debug)
1173
			printf(gettext("Radius Auth rejected")."<br>\n");
1174
	}
1175
1176
	// close OO RADIUS_AUTHENTICATION
1177
	$rauth->close();
1178
1179
	return $ret;
1180
}
1181
1182 7dd044f2 sullrich
function get_user_expiration_date($username) {
1183 a13ce628 Ermal Lu?i
	$user = getUserEntry($username);
1184
	if ($user['expires']) 
1185
		return $user['expires'];
1186
}
1187
1188
function is_account_expired($username) {
1189
	$expirydate = get_user_expiration_date($username);
1190
	if ($expirydate) {
1191
		if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($expirydate))))
1192
			return true;
1193 7dd044f2 sullrich
	}
1194 a13ce628 Ermal Lu?i
1195
	return false;
1196 7dd044f2 sullrich
}
1197
1198 b4bfd25d sullrich
function is_account_disabled($username) {
1199 a13ce628 Ermal Lu?i
	$user = getUserEntry($username);
1200
	if (isset($user['disabled']))
1201
		return true;
1202
1203 b4bfd25d sullrich
	return false;
1204
}
1205
1206 c61e4626 Ermal Lu?i
function auth_get_authserver($name) {
1207
        global $config;
1208
1209
        if (is_array($config['system']['authserver'])) {
1210
                foreach ($config['system']['authserver'] as $authcfg) {
1211
                        if ($authcfg['name'] == $name)
1212
                                return $authcfg;
1213
                }
1214
        }
1215 6306b5dd Ermal Lu?i
	if ($name == "Local Database")
1216 94021404 Carlos Eduardo Ramos
		return array("name" => gettext("Local Database"), "type" => gettext("Local Auth"), "host" => $config['system']['hostname']);
1217 6306b5dd Ermal Lu?i
}
1218
1219
function auth_get_authserver_list() {
1220
        global $config;
1221
1222
	$list = array();
1223
1224
        if (is_array($config['system']['authserver'])) {
1225
                foreach ($config['system']['authserver'] as $authcfg) {
1226
			/* Add support for disabled entries? */
1227
			$list[$authcfg['name']] = $authcfg;
1228
                }
1229
        }
1230
1231 94021404 Carlos Eduardo Ramos
	$list["Local Database"] = array( "name" => gettext("Local Database"), "type" => gettext("Local Auth"), "host" => $config['system']['hostname']);
1232 6306b5dd Ermal Lu?i
	return $list;
1233 c61e4626 Ermal Lu?i
}
1234
1235 fb0f22c0 Ermal Lu?i
function getUserGroups($username, $authcfg) {
1236
	global $config;
1237
1238
	$allowed_groups = array();
1239
1240
	switch($authcfg['type']) {
1241
        case 'ldap':
1242
		$allowed_groups = @ldap_get_groups($username, $authcfg);
1243
		break;
1244
	case 'radius':
1245
		break;
1246
	default:
1247
		$user = getUserEntry($username);
1248
		$allowed_groups = @local_user_get_groups($user, true);
1249
		break;
1250
	}
1251
1252
	$member_groups = array();
1253
        if (is_array($config['system']['group'])) {
1254
                foreach ($config['system']['group'] as $group)
1255
                        if (in_array($group['name'], $allowed_groups))
1256
				$member_groups[] = $group['name'];
1257
	}
1258
1259
	return $member_groups;
1260
}
1261
1262 c61e4626 Ermal Lu?i
function authenticate_user($username, $password, $authcfg = NULL) {
1263
1264
	if (!$authcfg) {
1265
		return local_backed($username, $password);
1266
	}
1267
1268
	$authenticated = false;
1269
	switch($authcfg['type']) {
1270
        case 'ldap':
1271
                if (ldap_backed($username, $password, $authcfg))
1272
                        $authenticated = true;
1273
                break;
1274
        case 'radius':
1275
                if (radius_backed($username, $password, $authcfg))
1276
                        $authenticated = true;
1277
                break;
1278
        default:
1279
                /* lookup user object by name */
1280
                if (local_backed($username, $password))
1281
                        $authenticated = true;
1282
                break;
1283
        }
1284
1285
	return $authenticated;
1286
}
1287
1288 6306b5dd Ermal Lu?i
function session_auth() {
1289
	global $HTTP_SERVER_VARS, $config, $_SESSION, $page;
1290 55eb9c44 --global
1291 9252d093 Ermal
	if (!session_id())
1292
		session_start();
1293 55eb9c44 --global
1294
	/* Validate incoming login request */
1295
	if (isset($_POST['login'])) {
1296 6306b5dd Ermal Lu?i
		$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
1297
		if (authenticate_user($_POST['usernamefld'], $_POST['passwordfld'], $authcfg) || 
1298
		    authenticate_user($_POST['usernamefld'], $_POST['passwordfld'])) {
1299
			$_SESSION['Logged_In'] = "True";
1300
			$_SESSION['Username'] = $_POST['usernamefld'];
1301
			$_SESSION['last_access'] = time();
1302 4fc3855f smos
			if(! isset($config['system']['webgui']['quietlogin'])) {
1303 54bdff75 Vinicius Coque
				log_auth(sprintf(gettext("Successful login for user '%1\$s' from: %2\$s"), $_POST['usernamefld'], $_SERVER['REMOTE_ADDR']));
1304 4fc3855f smos
			}
1305 f23e6363 Ermal
			$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1306 92140621 Ermal
			if (isset($_POST['postafterlogin']))
1307
				return true;
1308 80b292f3 Ermal
			else {
1309
				if (empty($page))
1310
					$page = "/";
1311
				header("Location: {$page}");
1312
			}
1313 f23e6363 Ermal
			exit;
1314 a13ce628 Ermal Lu?i
		} else {
1315
			/* give the user an error message */
1316
			$_SESSION['Login_Error'] = "Username or Password incorrect";
1317 65f7fba8 Scott Ullrich
			log_auth("webConfigurator authentication error for '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}");
1318 a13ce628 Ermal Lu?i
			if(isAjax()) {
1319
				echo "showajaxmessage('{$_SESSION['Login_Error']}');";
1320
				return;
1321 55eb9c44 --global
			}
1322
		}
1323
	}
1324
1325
	/* Show login page if they aren't logged in */
1326 409105ec Ermal Lu?i
	if (empty($_SESSION['Logged_In']))
1327 55eb9c44 --global
		return false;
1328
1329
	/* If session timeout isn't set, we don't mark sessions stale */
1330 02647583 Ermal
	if (!isset($config['system']['webgui']['session_timeout'])) {
1331 bdadaf3c Chris Buechler
		/* Default to 4 hour timeout if one is not set */
1332
		if ($_SESSION['last_access'] < (time() - 14400)) {
1333
			$_GET['logout'] = true;
1334
			$_SESSION['Logout'] = true;
1335 9a985f9e Ermal
		} else
1336
			$_SESSION['last_access'] = time();	
1337 02647583 Ermal
	} else if (intval($config['system']['webgui']['session_timeout']) == 0) {
1338
		/* only update if it wasn't ajax */
1339
		if (!isAjax())
1340
			$_SESSION['last_access'] = time();
1341 bdadaf3c Chris Buechler
	} else {
1342 55eb9c44 --global
		/* Check for stale session */
1343
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
1344
			$_GET['logout'] = true;
1345
			$_SESSION['Logout'] = true;
1346
		} else {
1347
			/* only update if it wasn't ajax */
1348
			if (!isAjax())
1349
				$_SESSION['last_access'] = time();
1350
		}
1351
	}
1352
1353
	/* user hit the logout button */
1354
	if (isset($_GET['logout'])) {
1355
1356
		if ($_SESSION['Logout'])
1357 addc0439 Renato Botelho
			log_error(sprintf(gettext("Session timed out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1358 55eb9c44 --global
		else
1359 addc0439 Renato Botelho
			log_error(sprintf(gettext("User logged out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1360 55eb9c44 --global
1361
		/* wipe out $_SESSION */
1362
		$_SESSION = array();
1363
1364
		if (isset($_COOKIE[session_name()]))
1365
			setcookie(session_name(), '', time()-42000, '/');
1366
1367
		/* and destroy it */
1368
		session_destroy();
1369
1370 cfbfd941 smos
		$scriptName = explode("/", $_SERVER["SCRIPT_FILENAME"]);
1371 55eb9c44 --global
		$scriptElms = count($scriptName);
1372
		$scriptName = $scriptName[$scriptElms-1];
1373
1374
		if (isAjax())
1375
			return false;
1376
1377
		/* redirect to page the user is on, it'll prompt them to login again */
1378 6dc88d53 Ermal Luci
		Header("Location: {$scriptName}");
1379 55eb9c44 --global
1380
		return false;
1381
	}
1382
1383
	/*
1384
	 * this is for debugging purpose if you do not want to use Ajax
1385
	 * to submit a HTML form. It basically diables the observation
1386
	 * of the submit event and hence does not trigger Ajax.
1387
	 */
1388 f23e6363 Ermal
	if ($_GET['disable_ajax'])
1389 55eb9c44 --global
		$_SESSION['NO_AJAX'] = "True";
1390
1391
	/*
1392
	 * Same to re-enable Ajax.
1393
	 */
1394 f23e6363 Ermal
	if ($_GET['enable_ajax'])
1395 55eb9c44 --global
		unset($_SESSION['NO_AJAX']);
1396
1397
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1398
	return true;
1399
}
1400
1401 ee4fc984 Ermal
?>