Projet

Général

Profil

Télécharger (44,7 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / auth.inc @ ff9b30ec

1
<?php
2
/* $Id$ */
3
/*
4
	Copyright (C) 2010 Ermal Lu�i
5
	All rights reserved.
6

    
7
	Copyright (C) 2007, 2008 Scott Ullrich <sullrich@gmail.com>
8
	All rights reserved.
9

    
10
        Copyright (C) 2005-2006 Bill Marquette <bill.marquette@gmail.com>
11
        All rights reserved.
12

    
13
        Copyright (C) 2006 Paul Taylor <paultaylor@winn-dixie.com>.
14
        All rights reserved.
15

    
16
        Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
17
        All rights reserved.
18

    
19
        Redistribution and use in source and binary forms, with or without
20
        modification, are permitted provided that the following conditions are met:
21

    
22
        1. Redistributions of source code must retain the above copyright notice,
23
           this list of conditions and the following disclaimer.
24

    
25
        2. Redistributions in binary form must reproduce the above copyright
26
           notice, this list of conditions and the following disclaimer in the
27
           documentation and/or other materials provided with the distribution.
28

    
29
        THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
30
        INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
31
        AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
        AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
33
        OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34
        SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35
        INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36
        CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
        ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
        POSSIBILITY OF SUCH DAMAGE.
39

    
40
		DISABLE_PHP_LINT_CHECKING
41
		pfSense_BUILDER_BINARIES:	/usr/sbin/pw	/bin/cp
42
		pfSense_MODULE:	auth
43
*/
44

    
45
/*
46
 * NOTE : Portions of the mschapv2 support was based on the BSD licensed CHAP.php
47
 * file courtesy of Michael Retterklieber.
48
 */
49
if(!$do_not_include_config_gui_inc)
50
	require_once("config.gui.inc");
51

    
52
// Will be changed to false if security checks fail
53
$security_passed = true;
54

    
55
/* If this function doesn't exist, we're being called from Captive Portal or 
56
   another internal subsystem which does not include authgui.inc */
57
if (function_exists("display_error_form") && !isset($config['system']['webgui']['nodnsrebindcheck'])) {
58
	/* DNS ReBinding attack prevention.  https://redmine.pfsense.org/issues/708 */
59
	$found_host = false;
60

    
61
	/* Either a IPv6 address with or without a alternate port */
62
	if(strstr($_SERVER['HTTP_HOST'], "]")) {
63
		$http_host_port = explode("]", $_SERVER['HTTP_HOST']);
64
		/* v6 address has more parts, drop the last part */
65
		if(count($http_host_port) > 1) {
66
			array_pop($http_host_port);
67
			$http_host = str_replace(array("[", "]"), "", implode(":", $http_host_port));
68
		} else {
69
			$http_host = str_replace(array("[", "]"), "", implode(":", $http_host_port));
70
		}
71
	} else {
72
		$http_host = explode(":", $_SERVER['HTTP_HOST']);
73
		$http_host = $http_host[0];
74
	}
75
	if(is_ipaddr($http_host) or $_SERVER['SERVER_ADDR'] == "127.0.0.1" or
76
			strcasecmp($http_host, "localhost") == 0 or $_SERVER['SERVER_ADDR'] == "::1")
77
		$found_host = true;
78
	if(strcasecmp($http_host, $config['system']['hostname'] . "." . $config['system']['domain']) == 0 or
79
			strcasecmp($http_host, $config['system']['hostname']) == 0)
80
		$found_host = true;
81

    
82
	if(is_array($config['dyndnses']['dyndns']) && !$found_host)
83
		foreach($config['dyndnses']['dyndns'] as $dyndns)
84
			if(strcasecmp($dyndns['host'], $http_host) == 0) {
85
				$found_host = true;
86
				break;
87
			}
88

    
89
	if(is_array($config['dnsupdates']['dnsupdate']) && !$found_host)
90
		foreach($config['dnsupdates']['dnsupdate'] as $rfc2136)
91
			if(strcasecmp($rfc2136['host'], $http_host) == 0) {
92
				$found_host = true;
93
				break;
94
			}
95

    
96
	if(!empty($config['system']['webgui']['althostnames']) && !$found_host) {
97
		$althosts = explode(" ", $config['system']['webgui']['althostnames']);
98
		foreach ($althosts as $ah)
99
			if(strcasecmp($ah, $http_host) == 0 or strcasecmp($ah, $_SERVER['SERVER_ADDR']) == 0) {
100
				$found_host = true;
101
				break;
102
			}
103
	}
104

    
105
	if($found_host == false) {
106
		if(!security_checks_disabled()) {
107
			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."));
108
			exit;
109
		}
110
		$security_passed = false;
111
	}
112
}
113

    
114
// If the HTTP_REFERER is something other than ourselves then disallow.
115
if(function_exists("display_error_form") && !isset($config['system']['webgui']['nohttpreferercheck'])) {
116
	if($_SERVER['HTTP_REFERER']) {
117
		if(file_exists("{$g['tmp_path']}/setupwizard_lastreferrer")) {
118
			if($_SERVER['HTTP_REFERER'] == file_get_contents("{$g['tmp_path']}/setupwizard_lastreferrer")) {
119
				unlink("{$g['tmp_path']}/setupwizard_lastreferrer");
120
				header("Refresh: 1; url=index.php");
121
				echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
122
				echo "<html><head><title>" . gettext("Redirecting...") . "</title></head><body>" . gettext("Redirecting to the dashboard...") . "</body></html>";
123
				exit;
124
			}
125
		}
126
		$found_host = false;
127
		$referrer_host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
128
		$referrer_host = str_replace(array("[", "]"), "", $referrer_host);
129
		if($referrer_host) {
130
			if(strcasecmp($referrer_host, $config['system']['hostname'] . "." . $config['system']['domain']) == 0
131
					|| strcasecmp($referrer_host, $config['system']['hostname']) == 0)
132
				$found_host = true;
133

    
134
			if(!empty($config['system']['webgui']['althostnames']) && !$found_host) {
135
				$althosts = explode(" ", $config['system']['webgui']['althostnames']);
136
				foreach ($althosts as $ah) {
137
					if(strcasecmp($referrer_host, $ah) == 0) {
138
						$found_host = true;
139
						break;
140
					}
141
				}
142
			}
143

    
144
			if(is_array($config['dyndnses']['dyndns']) && !$found_host)
145
				foreach($config['dyndnses']['dyndns'] as $dyndns)
146
					if(strcasecmp($dyndns['host'], $referrer_host) == 0) {
147
						$found_host = true;
148
						break;
149
					}
150

    
151
			if(is_array($config['dnsupdates']['dnsupdate']) && !$found_host)
152
				foreach($config['dnsupdates']['dnsupdate'] as $rfc2136)
153
					if(strcasecmp($rfc2136['host'], $referrer_host) == 0) {
154
						$found_host = true;
155
						break;
156
					}
157

    
158
			if(!$found_host) {
159
				$interface_list_ips = get_configured_ip_addresses();
160
				foreach($interface_list_ips as $ilips) {
161
					if(strcasecmp($referrer_host, $ilips) == 0) {
162
						$found_host = true;
163
						break;
164
					}
165
				}
166
				$interface_list_ipv6s = get_configured_ipv6_addresses();
167
				foreach($interface_list_ipv6s as $ilipv6s) {
168
					if(strcasecmp($referrer_host, $ilipv6s) == 0) {
169
						$found_host = true;
170
						break;
171
					}
172
				}
173
				if($referrer_host == "127.0.0.1" || $referrer_host == "localhost") {
174
					// allow SSH port forwarded connections and links from localhost
175
					$found_host = true;
176
				}
177
			}
178
		}
179
		if($found_host == false) {
180
			if(!security_checks_disabled()) {
181
				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.");
182
				exit;
183
			}
184
			$security_passed = false;
185
		}
186
	} else
187
		$security_passed = false;
188
}
189

    
190
if (function_exists("display_error_form") && $security_passed)
191
	/* Security checks passed, so it should be OK to turn them back on */
192
	restore_security_checks();
193
unset($security_passed);
194

    
195
$groupindex = index_groups();
196
$userindex = index_users();
197

    
198
function index_groups() {
199
	global $g, $debug, $config, $groupindex;
200

    
201
	$groupindex = array();
202

    
203
	if (is_array($config['system']['group'])) {
204
		$i = 0;
205
		foreach($config['system']['group'] as $groupent) {
206
			$groupindex[$groupent['name']] = $i;
207
			$i++;
208
		}
209
	}
210

    
211
	return ($groupindex);
212
}
213

    
214
function index_users() {
215
	global $g, $debug, $config;
216

    
217
	if (is_array($config['system']['user'])) {
218
		$i = 0;
219
		foreach($config['system']['user'] as $userent) {
220
			$userindex[$userent['name']] = $i;
221
			$i++;
222
		}
223
	}
224

    
225
	return ($userindex);
226
}
227

    
228
function & getUserEntry($name) {
229
	global $debug, $config, $userindex;
230
	if (isset($userindex[$name]))
231
		return $config['system']['user'][$userindex[$name]];
232
}
233

    
234
function & getUserEntryByUID($uid) {
235
	global $debug, $config;
236

    
237
	if (is_array($config['system']['user']))
238
		foreach ($config['system']['user'] as & $user)
239
			if ($user['uid'] == $uid)
240
				return $user;
241

    
242
	return false;
243
}
244

    
245
function & getGroupEntry($name) {
246
	global $debug, $config, $groupindex;
247
	if (isset($groupindex[$name]))
248
		return $config['system']['group'][$groupindex[$name]];
249
}
250

    
251
function & getGroupEntryByGID($gid) {
252
	global $debug, $config;
253

    
254
	if (is_array($config['system']['group']))
255
		foreach ($config['system']['group'] as & $group)
256
			if ($group['gid'] == $gid)
257
				return $group;
258

    
259
	return false;
260
}
261

    
262
function get_user_privileges(& $user) {
263

    
264
        $privs = $user['priv'];
265
        if (!is_array($privs))
266
                $privs = array();
267

    
268
        $names = local_user_get_groups($user, true);
269

    
270
        foreach ($names as $name) {
271
                $group = getGroupEntry($name);
272
                if (is_array($group['priv']))
273
                        $privs = array_merge( $privs, $group['priv']);
274
        }
275

    
276
        return $privs;
277
}
278

    
279
function userHasPrivilege($userent, $privid = false) {
280

    
281
        if (!$privid || !is_array($userent))
282
                return false;
283

    
284
        $privs = get_user_privileges($userent);
285

    
286
        if (!is_array($privs))
287
                return false;
288

    
289
        if (!in_array($privid, $privs))
290
                return false;
291

    
292
        return true;
293
}
294

    
295
function local_backed($username, $passwd) {
296

    
297
	$user = getUserEntry($username);
298
	if (!$user)
299
		return false;
300

    
301
	if (is_account_disabled($username) || is_account_expired($username))
302
		return false;
303

    
304
	if ($user['password'])
305
	{
306
		$passwd = crypt($passwd, $user['password']);
307
		if ($passwd == $user['password'])
308
			return true;
309
	}
310

    
311
	if ($user['md5-hash'])
312
	{
313
		$passwd = md5($passwd);
314
		if ($passwd == $user['md5-hash'])
315
			return true;
316
	}
317

    
318
	return false;
319
}
320

    
321
function local_sync_accounts() {
322
	global $debug, $config;
323
	conf_mount_rw();
324

    
325
	/* remove local users to avoid uid conflicts */
326
	$fd = popen("/usr/sbin/pw usershow -a", "r");
327
	if ($fd) {
328
		while (!feof($fd)) {
329
			$line = explode(":",fgets($fd));
330
			if (((!strncmp($line[0], "_", 1)) || ($line[2] < 2000) || ($line[2] > 65000)) && ($line[0] != "admin"))
331
				continue;
332
			$cmd = "/usr/sbin/pw userdel -n '{$line[0]}'";
333
			if($debug)
334
				log_error(sprintf(gettext("Running: %s"), $cmd));
335
			mwexec($cmd);
336
		}
337
		pclose($fd);
338
	}
339

    
340
	/* remove local groups to avoid gid conflicts */
341
	$gids = array();
342
	$fd = popen("/usr/sbin/pw groupshow -a", "r");
343
	if ($fd) {
344
		while (!feof($fd)) {
345
			$line = explode(":",fgets($fd));
346
			if (!strncmp($line[0], "_", 1))
347
				continue;
348
			if ($line[2] < 2000)
349
				continue;
350
			if ($line[2] > 65000)
351
				continue;
352
			$cmd = "/usr/sbin/pw groupdel {$line[2]}";
353
			if($debug)
354
				log_error(sprintf(gettext("Running: %s"), $cmd));
355
			mwexec($cmd);
356
		}
357
		pclose($fd);
358
	}
359

    
360
	/* make sure the all group exists */
361
	$allgrp = getGroupEntryByGID(1998);
362
	local_group_set($allgrp, true);
363

    
364
	/* sync all local users */
365
	if (is_array($config['system']['user']))
366
		foreach ($config['system']['user'] as $user)
367
			local_user_set($user);
368

    
369
	/* sync all local groups */
370
	if (is_array($config['system']['group']))
371
		foreach ($config['system']['group'] as $group)
372
			local_group_set($group);
373

    
374
	conf_mount_ro();
375

    
376
}
377

    
378
function local_user_set(& $user) {
379
	global $g, $debug;
380

    
381
	if (empty($user['password'])) {
382
		log_error("There is something wrong in your config because user {$user['name']} password is missing!");
383
		return;
384
	}
385

    
386
	conf_mount_rw();
387

    
388
	$home_base = "/home/";	
389
	$user_uid = $user['uid'];
390
	$user_name = $user['name'];
391
	$user_home = "{$home_base}{$user_name}";
392
	$user_shell = "/etc/rc.initial";
393
	$user_group = "nobody";
394

    
395
	// Ensure $home_base exists and is writable
396
	if (!is_dir($home_base)) 
397
		mkdir($home_base, 0755);
398

    
399
	$lock_account = false;
400
	/* configure shell type */
401
	/* Cases here should be ordered by most privileged to least privileged. */
402
	if (userHasPrivilege($user, "user-shell-access") || userHasPrivilege($user, "page-all")) {
403
		$user_shell = "/bin/tcsh";
404
	} elseif (userHasPrivilege($user, "user-copy-files")) {
405
		$user_shell = "/usr/local/bin/scponly";
406
	} elseif (userHasPrivilege($user, "user-ssh-tunnel")) {
407
		$user_shell = "/usr/local/sbin/ssh_tunnel_shell";
408
	} elseif (userHasPrivilege($user, "user-ipsec-xauth-dialin")) {
409
		$user_shell = "/sbin/nologin";
410
	} else {
411
		$user_shell = "/sbin/nologin";
412
		$lock_account = true;
413
	}
414

    
415
	/* Lock out disabled or expired users, unless it's root/admin. */
416
	if ((is_account_disabled($user_name) || is_account_expired($user_name)) && ($user_uid != 0)) {
417
		$user_shell = "/sbin/nologin";
418
		$lock_account = true;
419
	}
420

    
421
	/* root user special handling */
422
	if ($user_uid == 0) {
423
		$cmd = "/usr/sbin/pw usermod -q -n root -s /bin/sh -H 0";
424
		if($debug)
425
			log_error(sprintf(gettext("Running: %s"), $cmd));
426
		$fd = popen($cmd, "w");
427
		fwrite($fd, $user['password']);
428
		pclose($fd);
429
		$user_group = "wheel";
430
		$user_home = "/root";
431
		$user_shell = "/etc/rc.initial";
432
	}
433

    
434
	/* read from pw db */
435
	$fd = popen("/usr/sbin/pw usershow -n {$user_name} 2>&1", "r");
436
	$pwread = fgets($fd);
437
	pclose($fd);
438
	$userattrs = explode(":", trim($pwread));
439

    
440
	/* determine add or mod */
441
	if (($userattrs[0] != $user['name']) || (!strncmp($pwread, "pw:", 3))) {
442
		$user_op = "useradd -m -k /etc/skel -o";
443
	} else {
444
		$user_op = "usermod";
445
	}
446

    
447
	$comment = str_replace(array(":", "!", "@"), " ", $user['descr']); 
448
	/* add or mod pw db */
449
	$cmd = "/usr/sbin/pw {$user_op} -q -u {$user_uid} -n {$user_name}".
450
			" -g {$user_group} -s {$user_shell} -d {$user_home}".
451
			" -c ".escapeshellarg($comment)." -H 0 2>&1";
452

    
453
	if($debug)
454
		log_error(sprintf(gettext("Running: %s"), $cmd));
455
	$fd = popen($cmd, "w");
456
	fwrite($fd, $user['password']);
457
	pclose($fd);
458

    
459
	/* create user directory if required */
460
	if (!is_dir($user_home)) {
461
		mkdir($user_home, 0700);
462
		mwexec("/bin/cp /root/.* {$home_base}/", true);
463
	}
464
	@chown($user_home, $user_name);
465
	@chgrp($user_home, $user_group);
466

    
467
	/* write out ssh authorized key file */
468
	if($user['authorizedkeys']) {
469
		if (!is_dir("{$user_home}/.ssh")) {
470
			@mkdir("{$user_home}/.ssh", 0700);
471
			@chown("{$user_home}/.ssh", $user_name);
472
		}
473
		$keys = base64_decode($user['authorizedkeys']);
474
		@file_put_contents("{$user_home}/.ssh/authorized_keys", $keys);
475
		@chown("{$user_home}/.ssh/authorized_keys", $user_name);
476
	} else
477
		unlink_if_exists("{$user_home}/.ssh/authorized_keys");
478

    
479
	$un = $lock_account ? "" : "un";
480
	exec("/usr/sbin/pw {$un}lock {$user_name} -q");
481
	
482
	conf_mount_ro();
483
}
484

    
485
function local_user_del($user) {
486
	global $debug;
487

    
488
	/* remove all memberships */
489
	local_user_set_groups($user);
490

    
491
	/* Don't remove /root */
492
	if ($user['uid'] != 0)
493
		$rmhome = "-r";
494

    
495
	/* read from pw db */
496
	$fd = popen("/usr/sbin/pw usershow -n {$user['name']} 2>&1", "r");
497
	$pwread = fgets($fd);
498
	pclose($fd);
499
	$userattrs = explode(":", trim($pwread));
500

    
501
	if ($userattrs[0] != $user['name']) {
502
		log_error("Tried to remove user {$user['name']} but got user {$userattrs[0]} instead. Bailing.");
503
		return;
504
	}
505

    
506
	/* delete from pw db */
507
	$cmd = "/usr/sbin/pw userdel -n {$user['name']} {$rmhome}";
508

    
509
	if($debug)
510
		log_error(sprintf(gettext("Running: %s"), $cmd));
511
	mwexec($cmd);
512

    
513
	/* Delete user from groups needs a call to write_config() */
514
	local_group_del_user($user);
515
}
516

    
517
function local_user_set_password(& $user, $password) {
518

    
519
	$user['password'] = crypt($password);
520
	$user['md5-hash'] = md5($password);
521

    
522
	// Converts ascii to unicode.
523
	$astr = (string) $password;
524
	$ustr = '';
525
	for ($i = 0; $i < strlen($astr); $i++) {
526
		$a = ord($astr{$i}) << 8;
527
		$ustr.= sprintf("%X", $a);
528
	}
529

    
530
	// Generate the NT-HASH from the unicode string
531
       $user['nt-hash'] = bin2hex(hash("md4", $ustr));
532
}
533

    
534
function local_user_get_groups($user, $all = false) {
535
	global $debug, $config;
536

    
537
	$groups = array();
538
	if (!is_array($config['system']['group']))
539
		return $groups;
540

    
541
	foreach ($config['system']['group'] as $group)
542
		if ( $all || ( !$all && ($group['name'] != "all")))
543
			if (is_array($group['member']))
544
				if (in_array($user['uid'], $group['member']))
545
					$groups[] = $group['name'];
546

    
547
	if ( $all )
548
		$groups[] = "all";
549

    
550
	sort($groups);
551

    
552
	return $groups;
553
	
554
}
555

    
556
function local_user_set_groups($user, $new_groups = NULL ) {
557
	global $debug, $config, $groupindex;
558

    
559
	if (!is_array($config['system']['group']))
560
		return;
561

    
562
	$cur_groups = local_user_get_groups($user, true);
563
	$mod_groups = array();
564

    
565
	if (!is_array($new_groups))
566
		$new_groups = array();
567

    
568
	if (!is_array($cur_groups))
569
		$cur_groups = array();
570

    
571
	/* determine which memberships to add */
572
	foreach ($new_groups as $groupname) {
573
		if (in_array($groupname,$cur_groups))
574
			continue;
575
		$group = & $config['system']['group'][$groupindex[$groupname]];
576
		$group['member'][] = $user['uid'];
577
		$mod_groups[] = $group;
578
	}
579
	unset($group);
580

    
581
	/* determine which memberships to remove */
582
	foreach ($cur_groups as $groupname) {
583
		if (in_array($groupname,$new_groups))
584
			continue;
585
		if (!isset($config['system']['group'][$groupindex[$groupname]]))
586
			continue;
587
		$group = & $config['system']['group'][$groupindex[$groupname]];
588
		if (is_array($group['member'])) {
589
			$index = array_search($user['uid'], $group['member']);
590
			array_splice($group['member'], $index, 1);
591
			$mod_groups[] = $group;
592
		}
593
	}
594
	unset($group);
595

    
596
	/* sync all modified groups */
597
	foreach ($mod_groups as $group)
598
		local_group_set($group);
599
}
600

    
601
function local_group_del_user($user) {
602
	global $config;
603

    
604
	if (!is_array($config['system']['group']))
605
                return;
606

    
607
        foreach ($config['system']['group'] as $group) {
608
		if (is_array($group['member'])) {
609
			foreach ($group['member'] as $idx => $uid) {
610
				if ($user['uid'] == $uid)
611
					unset($config['system']['group']['member'][$idx]);
612
			}
613
		}
614
	}
615
}
616

    
617
function local_group_set($group, $reset = false) {
618
	global $debug;
619

    
620
	$group_name = $group['name'];
621
	$group_gid = $group['gid'];
622
	$group_members = "''";
623
	if (!$reset && !empty($group['member']) && count($group['member']) > 0)
624
		$group_members = implode(",",$group['member']);
625

    
626
	/* read from group db */
627
	$fd = popen("/usr/sbin/pw groupshow {$group_name} 2>&1", "r");
628
	$pwread = fgets($fd);
629
	pclose($fd);
630

    
631
	/* determine add or mod */
632
	if (!strncmp($pwread, "pw:", 3))
633
		$group_op = "groupadd";
634
	else
635
		$group_op = "groupmod";
636

    
637
	/* add or mod group db */
638
	$cmd = "/usr/sbin/pw {$group_op} {$group_name} -g {$group_gid} -M {$group_members} 2>&1";
639

    
640
	if($debug)
641
		log_error(sprintf(gettext("Running: %s"), $cmd));
642
	mwexec($cmd);
643

    
644
}
645

    
646
function local_group_del($group) {
647
	global $debug;
648

    
649
	/* delete from group db */
650
	$cmd = "/usr/sbin/pw groupdel {$group['name']}";
651

    
652
	if($debug)
653
		log_error(sprintf(gettext("Running: %s"), $cmd));
654
	mwexec($cmd);
655
}
656

    
657
function ldap_test_connection($authcfg) {
658
	global $debug, $config, $g;
659

    
660
	if ($authcfg) {
661
                if (strstr($authcfg['ldap_urltype'], "Standard"))
662
                        $ldapproto = "ldap";
663
                else
664
                        $ldapproto = "ldaps";
665
                $ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
666
                $ldapport           = $authcfg['ldap_port'];
667
		if (!empty($ldapport))
668
			$ldapserver .= ":{$ldapport}";
669
                $ldapbasedn         = $authcfg['ldap_basedn'];
670
                $ldapbindun         = $authcfg['ldap_binddn'];
671
                $ldapbindpw         = $authcfg['ldap_bindpw'];
672
        } else
673
		return false;
674

    
675
        /* first check if there is even an LDAP server populated */
676
        if(!$ldapserver)
677
                return false;
678

    
679
        /* Setup CA environment if needed. */
680
        ldap_setup_caenv($authcfg);
681

    
682
        /* connect and see if server is up */
683
        $error = false;
684
	if (!($ldap = ldap_connect($ldapserver)))
685
		$error = true;
686

    
687
        if ($error == true) {
688
                log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
689
                return false;
690
        }
691

    
692
	return true;
693
}
694

    
695
function ldap_setup_caenv($authcfg) {
696
	global $g;
697
	require_once("certs.inc");
698

    
699
	unset($caref);
700
	if (empty($authcfg['ldap_caref']) || !strstr($authcfg['ldap_urltype'], "SSL")) {
701
		putenv('LDAPTLS_REQCERT=never');
702
		return;
703
	} else {
704
		$caref = lookup_ca($authcfg['ldap_caref']);
705
		if (!$caref) {
706
			log_error(sprintf(gettext("LDAP: Could not lookup CA by reference for host %s."), $authcfg['ldap_caref']));
707
			/* XXX: Prevent for credential leaking since we cannot setup the CA env. Better way? */
708
			putenv('LDAPTLS_REQCERT=hard');
709
			return;
710
		}
711
		if (!is_dir("{$g['varrun_path']}/certs"))
712
			@mkdir("{$g['varrun_path']}/certs");
713
		if (file_exists("{$g['varrun_path']}/certs/{$caref['refid']}.ca"))
714
			@unlink("{$g['varrun_path']}/certs/{$caref['refid']}.ca");
715
		file_put_contents("{$g['varrun_path']}/certs/{$caref['refid']}.ca", base64_decode($caref['crt']));
716
		@chmod("{$g['varrun_path']}/certs/{$caref['refid']}.ca", 0600);
717
		putenv('LDAPTLS_REQCERT=hard');
718
		/* XXX: Probably even the hashed link should be created for this? */
719
		putenv("LDAPTLS_CACERTDIR={$g['varrun_path']}/certs");
720
		putenv("LDAPTLS_CACERT={$g['varrun_path']}/certs/{$caref['refid']}.ca");
721
	}
722
}
723

    
724
function ldap_test_bind($authcfg) {
725
	global $debug, $config, $g;
726

    
727
	if ($authcfg) {
728
                if (strstr($authcfg['ldap_urltype'], "Standard"))
729
                        $ldapproto = "ldap";
730
                else
731
                        $ldapproto = "ldaps";
732
                $ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
733
                $ldapport           = $authcfg['ldap_port'];
734
		if (!empty($ldapport))
735
			$ldapserver .= ":{$ldapport}";
736
                $ldapbasedn         = $authcfg['ldap_basedn'];
737
                $ldapbindun         = $authcfg['ldap_binddn'];
738
                $ldapbindpw         = $authcfg['ldap_bindpw'];
739
                $ldapver            = $authcfg['ldap_protver'];
740
		if (empty($ldapbndun) || empty($ldapbindpw))
741
                        $ldapanon = true;
742
                else
743
                        $ldapanon = false;
744
	} else
745
		return false;
746

    
747
	/* first check if there is even an LDAP server populated */
748
        if(!$ldapserver)
749
                return false;
750

    
751
	/* Setup CA environment if needed. */
752
	ldap_setup_caenv($authcfg);
753

    
754
        /* connect and see if server is up */
755
        $error = false;
756
	if (!($ldap = ldap_connect($ldapserver)))
757
		$error = true;
758

    
759
        if ($error == true) {
760
                log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
761
                return false;
762
        }
763

    
764
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
765
	ldap_set_option($ldap, LDAP_OPT_DEREF, LDAP_DEREF_SEARCHING);
766
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
767
 
768
	$ldapbindun = isset($authcfg['ldap_utf8']) ? utf8_encode($ldapbindun) : $ldapbindun;
769
	$ldapbindpw = isset($authcfg['ldap_utf8']) ? utf8_encode($ldapbindpw) : $ldapbindpw;
770
	if ($ldapanon == true) {
771
		if (!($res = @ldap_bind($ldap))) {
772
			@ldap_close($ldap);
773
			return false;
774
		}
775
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
776
		@ldap_close($ldap);
777
		return false;
778
	}
779

    
780
	@ldap_unbind($ldap);
781

    
782
	return true;
783
}
784

    
785
function ldap_get_user_ous($show_complete_ou=true, $authcfg) {
786
	global $debug, $config, $g;
787

    
788
	if(!function_exists("ldap_connect"))
789
		return;
790

    
791
	$ous = array();
792

    
793
	if ($authcfg) {
794
                if (strstr($authcfg['ldap_urltype'], "Standard"))
795
                        $ldapproto = "ldap";
796
                else
797
                        $ldapproto = "ldaps";
798
                $ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
799
                $ldapport           = $authcfg['ldap_port'];
800
		if (!empty($ldapport))
801
			$ldapserver .= ":{$ldapport}";
802
                $ldapbasedn         = $authcfg['ldap_basedn'];
803
                $ldapbindun         = $authcfg['ldap_binddn'];
804
                $ldapbindpw         = $authcfg['ldap_bindpw'];
805
                $ldapver            = $authcfg['ldap_protver'];
806
		if (empty($ldapbindun) || empty($ldapbindpw))
807
                        $ldapanon = true;
808
                else
809
                        $ldapanon = false;
810
                $ldapname           = $authcfg['name'];
811
                $ldapfallback       = false;
812
		$ldapscope          = $authcfg['ldap_scope'];
813
        } else
814
		return false;
815

    
816
        /* first check if there is even an LDAP server populated */
817
        if(!$ldapserver) {
818
                log_error(gettext("ERROR!  ldap_get_user_ous() backed selected with no LDAP authentication server defined."));
819
                return $ous;
820
        }
821

    
822
	/* Setup CA environment if needed. */
823
	ldap_setup_caenv($authcfg);
824

    
825
	/* connect and see if server is up */
826
        $error = false;
827
	if (!($ldap = ldap_connect($ldapserver)))
828
		$error = true;
829

    
830
        if ($error == true) {
831
        log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
832
                return $ous;
833
        }
834

    
835
	$ldapfilter = "(|(ou=*)(cn=Users))";
836

    
837
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
838
	ldap_set_option($ldap, LDAP_OPT_DEREF, LDAP_DEREF_SEARCHING);
839
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
840

    
841
	$ldapbindun = isset($authcfg['ldap_utf8']) ? utf8_encode($ldapbindun) : $ldapbindun;
842
	$ldapbindpw = isset($authcfg['ldap_utf8']) ? utf8_encode($ldapbindpw) : $ldapbindpw;
843
	if ($ldapanon == true) {
844
                if (!($res = @ldap_bind($ldap))) {
845
			log_error(sprintf(gettext("ERROR! ldap_get_user_ous() could not bind anonymously to server %s."), $ldapname));
846
			@ldap_close($ldap);
847
                        return $ous;
848
		}
849
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
850
		log_error(sprintf(gettext("ERROR! ldap_get_user_ous() could not bind to server %s."), $ldapname));
851
		@ldap_close($ldap);
852
		return $ous;
853
	}
854

    
855
	if ($ldapscope == "one")
856
		$ldapfunc = "ldap_list";
857
	else
858
		$ldapfunc = "ldap_search";
859

    
860
	$search = @$ldapfunc($ldap, $ldapbasedn, $ldapfilter);
861
	$info = @ldap_get_entries($ldap, $search);
862

    
863
	if (is_array($info)) {
864
		foreach ($info as $inf) {
865
			if (!$show_complete_ou) {
866
				$inf_split = explode(",", $inf['dn']);
867
				$ou = $inf_split[0];
868
				$ou = str_replace("OU=","", $ou);
869
				$ou = str_replace("CN=","", $ou);
870
			} else
871
				if($inf['dn'])
872
					$ou = $inf['dn'];
873
			if($ou)
874
				$ous[] = $ou;
875
		}
876
	}
877

    
878
	@ldap_unbind($ldap);
879

    
880
	return $ous;
881
}
882

    
883
function ldap_get_groups($username, $authcfg) {
884
	global $debug, $config;
885
	
886
	if(!function_exists("ldap_connect"))
887
		return;
888
	
889
	if(!$username) 
890
		return false;
891

    
892
	if(!isset($authcfg['ldap_nostrip_at']) && stristr($username, "@")) {
893
		$username_split = explode("@", $username);
894
		$username = $username_split[0];		
895
	}
896

    
897
	if(stristr($username, "\\")) {
898
		$username_split = explode("\\", $username);
899
		$username = $username_split[0];        
900
	}    
901
	
902
	//log_error("Getting LDAP groups for {$username}.");
903
        if ($authcfg) {
904
                if (strstr($authcfg['ldap_urltype'], "Standard"))
905
                        $ldapproto = "ldap";
906
                else
907
                        $ldapproto = "ldaps";
908
                $ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
909
                $ldapport           = $authcfg['ldap_port'];
910
		if (!empty($ldapport))
911
			$ldapserver .= ":{$ldapport}";
912
                $ldapbasedn         = $authcfg['ldap_basedn'];
913
                $ldapbindun         = $authcfg['ldap_binddn'];
914
                $ldapbindpw         = $authcfg['ldap_bindpw'];
915
                $ldapauthcont       = $authcfg['ldap_authcn'];
916
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
917
                $ldapgroupattribute  = strtolower($authcfg['ldap_attr_member']);
918
                $ldapfilter         = "({$ldapnameattribute}={$username})";
919
                $ldaptype           = "";
920
                $ldapver            = $authcfg['ldap_protver'];
921
		if (empty($ldapbindun) || empty($ldapbindpw))
922
                        $ldapanon = true;
923
                else
924
                        $ldapanon = false;
925
                $ldapname           = $authcfg['name'];
926
                $ldapfallback       = false;
927
		$ldapscope          = $authcfg['ldap_scope'];
928
	} else
929
		return false;
930

    
931
	$ldapdn             = $_SESSION['ldapdn'];
932

    
933
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
934
	$ldapgroupattribute = strtolower($ldapgroupattribute);
935
	$memberof = array();
936

    
937
        /* Setup CA environment if needed. */
938
        ldap_setup_caenv($authcfg);
939

    
940
	/* connect and see if server is up */
941
	$error = false;
942
	if (!($ldap = ldap_connect($ldapserver)))
943
		$error = true;
944

    
945
	if ($error == true) {
946
		log_error(sprintf(gettext("ERROR! ldap_get_groups() Could not connect to server %s."), $ldapname));
947
                return memberof;
948
        }
949
    
950
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
951
	ldap_set_option($ldap, LDAP_OPT_DEREF, LDAP_DEREF_SEARCHING);
952
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
953

    
954
	/* bind as user that has rights to read group attributes */
955
	$ldapbindun = isset($authcfg['ldap_utf8']) ? utf8_encode($ldapbindun) : $ldapbindun;
956
	$ldapbindpw = isset($authcfg['ldap_utf8']) ? utf8_encode($ldapbindpw) : $ldapbindpw;
957
	if ($ldapanon == true) {
958
                if (!($res = @ldap_bind($ldap))) {
959
			log_error(sprintf(gettext("ERROR! ldap_get_groups() could not bind anonymously to server %s."), $ldapname));
960
			@ldap_close($ldap);
961
                        return false;
962
		}
963
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
964
		log_error(sprintf(gettext("ERROR! ldap_get_groups() could not bind to server %s."), $ldapname));
965
		@ldap_close($ldap);
966
		return memberof;
967
	}
968

    
969
	/* get groups from DN found */
970
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
971
	/* since we know the DN is in $_SESSION['ldapdn'] */
972
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
973
	if ($ldapscope == "one")
974
                $ldapfunc = "ldap_list";
975
        else
976
                $ldapfunc = "ldap_search";
977

    
978
	$search    = @$ldapfunc($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
979
	$info      = @ldap_get_entries($ldap, $search);
980

    
981
	$countem = $info["count"];	
982
	
983
	if(is_array($info[0][$ldapgroupattribute])) {
984
		/* Iterate through the groups and throw them into an array */
985
		foreach ($info[0][$ldapgroupattribute] as $member) {
986
			if (stristr($member, "CN=") !== false) {
987
				$membersplit = explode(",", $member);
988
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
989
			}
990
		}
991
	}
992
	
993
	/* Time to close LDAP connection */
994
	@ldap_unbind($ldap);
995
	
996
	$groups = print_r($memberof,true);
997
	
998
	//log_error("Returning groups ".$groups." for user $username");
999
	
1000
	return $memberof;
1001
}
1002

    
1003
function ldap_format_host($host) {
1004
	return is_ipaddrv6($host) ? "[$host]" : $host ;
1005
}
1006

    
1007
function ldap_backed($username, $passwd, $authcfg) {
1008
	global $debug, $config;
1009
	
1010
	if(!$username) 
1011
		return;
1012

    
1013
	if(!function_exists("ldap_connect"))
1014
		return;
1015

    
1016
	if(!isset($authcfg['ldap_nostrip_at']) && stristr($username, "@")) {
1017
		$username_split = explode("@", $username);
1018
		$username = $username_split[0];        
1019
	}
1020
	if(stristr($username, "\\")) {
1021
		$username_split = explode("\\", $username);
1022
		$username = $username_split[0];        
1023
	}
1024

    
1025
	if ($authcfg) {
1026
		if (strstr($authcfg['ldap_urltype'], "Standard"))
1027
			$ldapproto = "ldap";
1028
		else
1029
			$ldapproto = "ldaps";
1030
		$ldapserver         = "{$ldapproto}://" . ldap_format_host($authcfg['host']);
1031
		$ldapport	    = $authcfg['ldap_port'];
1032
		if (!empty($ldapport))
1033
			$ldapserver .= ":{$ldapport}";
1034
                $ldapbasedn         = $authcfg['ldap_basedn'];
1035
                $ldapbindun         = $authcfg['ldap_binddn'];
1036
                $ldapbindpw         = $authcfg['ldap_bindpw'];
1037
		if (empty($ldapbindun) || empty($ldapbindpw))
1038
			$ldapanon = true;
1039
		else
1040
			$ldapanon = false;
1041
                $ldapauthcont       = $authcfg['ldap_authcn'];
1042
                $ldapnameattribute  = strtolower($authcfg['ldap_attr_user']);
1043
                $ldapextendedqueryenabled  = $authcfg['ldap_extended_enabled'];
1044
                $ldapextendedquery = $authcfg['ldap_extended_query'];
1045
                $ldapfilter         = "";
1046
                if(!$ldapextendedqueryenabled)
1047
                {
1048
                        $ldapfilter = "({$ldapnameattribute}={$username})";
1049
                }
1050
                else
1051
                {
1052
                        $ldapfilter = 
1053
"(&({$ldapnameattribute}={$username})({$ldapextendedquery}))";
1054
                } 
1055
                $ldaptype           = "";
1056
                $ldapver            = $authcfg['ldap_protver'];
1057
		$ldapname	    = $authcfg['name'];
1058
		$ldapscope	    = $authcfg['ldap_scope'];
1059
	} else
1060
		return false;
1061

    
1062
	/* first check if there is even an LDAP server populated */ 
1063
	if(!$ldapserver) {
1064
		if ($ldapfallback) {
1065
			log_error(gettext("ERROR! ldap_backed() called with no LDAP authentication server defined.  Defaulting to local user database. Visit System -> User Manager."));
1066
			return local_backed($username, $passwd);
1067
		} else
1068
			log_error(gettext("ERROR! ldap_backed() called with no LDAP authentication server defined."));
1069

    
1070
		return false;
1071
	}
1072
	
1073
        /* Setup CA environment if needed. */
1074
        ldap_setup_caenv($authcfg);
1075

    
1076
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
1077
	ldap_set_option($ldap, LDAP_OPT_DEREF, LDAP_DEREF_SEARCHING);
1078
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, (int)$ldapver);
1079

    
1080
	/* Make sure we can connect to LDAP */
1081
	$error = false;
1082
	if (!($ldap = ldap_connect($ldapserver)))
1083
		$error = true;
1084

    
1085
	if ($error == true) {
1086
		log_error(sprintf(gettext("ERROR!  Could not connect to server %s."), $ldapname));
1087
		return false;
1088
	}
1089

    
1090
	/* ok, its up.  now, lets bind as the bind user so we can search it */
1091
	$error = false;
1092
	$ldapbindun = isset($authcfg['ldap_utf8']) ? utf8_encode($ldapbindun) : $ldapbindun;
1093
	$ldapbindpw = isset($authcfg['ldap_utf8']) ? utf8_encode($ldapbindpw) : $ldapbindpw;
1094
	if ($ldapanon == true) {
1095
                if (!($res = @ldap_bind($ldap)))
1096
                        $error = true;
1097
	} else if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
1098
		$error = true;
1099

    
1100
	if ($error == true) {
1101
		@ldap_close($ldap);
1102
		log_error(sprintf(gettext("ERROR! Could not bind to server %s."), $ldapname));
1103
		return false;
1104
	}
1105
	
1106
	/* Get LDAP Authcontainers and split em up. */
1107
	$ldac_splits = explode(";", $ldapauthcont);
1108
	
1109
	/* setup the usercount so we think we havn't found anyone yet */
1110
	$usercount  = 0;
1111

    
1112
	/*****************************************************************/
1113
	/*  We First find the user based on username and filter          */
1114
	/*  Then, once we find the first occurance of that person        */
1115
	/*  We set seesion variables to ponit to the OU and DN of the    */
1116
	/*  Person.  To later be used by ldap_get_groups.                */
1117
	/*  that way we don't have to search twice.                      */
1118
	/*****************************************************************/
1119
	if ($debug)
1120
		log_auth(sprintf(gettext("Now Searching for %s in directory."), $username));
1121
	/* Iterate through the user containers for search */
1122
	foreach ($ldac_splits as $i => $ldac_split) {
1123
		$ldac_split = isset($authcfg['ldap_utf8']) ? utf8_encode($ldac_split) : $ldac_split;
1124
		$ldapfilter = isset($authcfg['ldap_utf8']) ? utf8_encode($ldapfilter) : $ldapfilter;
1125
		$ldapsearchbasedn = isset($authcfg['ldap_utf8']) ? utf8_encode("{$ldac_split},{$ldapbasedn}") : "{$ldac_split},{$ldapbasedn}";
1126
		/* Make sure we just use the first user we find */
1127
		if ($debug)
1128
			log_auth(sprintf(gettext('Now Searching in server %1$s, container %2$s with filter %3$s.'), $ldapname, utf8_decode($ldac_split), utf8_decode($ldapfilter)));
1129
		if ($ldapscope == "one")
1130
			$ldapfunc = "ldap_list";
1131
		else
1132
			$ldapfunc = "ldap_search";
1133
		/* Support legacy auth container specification. */
1134
		if (stristr($ldac_split, "DC=") || empty($ldapbasedn))
1135
			$search	 = @$ldapfunc($ldap,$ldac_split,$ldapfilter);
1136
		else
1137
			$search  = @$ldapfunc($ldap,$ldapsearchbasedn,$ldapfilter);
1138
		if (!$search) {
1139
			log_error(sprintf(gettext("Search resulted in error: %s"), ldap_error($ldap)));
1140
			continue;
1141
		}
1142
		$info	 = ldap_get_entries($ldap,$search);
1143
		$matches = $info['count'];
1144
		if ($matches == 1){
1145
			$userdn = $_SESSION['ldapdn'] = $info[0]['dn'];
1146
			$_SESSION['ldapou'] = $ldac_split[$i];
1147
			$_SESSION['ldapon'] = "true";
1148
			$usercount = 1;
1149
			break;
1150
		}
1151
	}
1152

    
1153
	if ($usercount != 1){
1154
		@ldap_unbind($ldap);
1155
		log_error(gettext("ERROR! Either LDAP search failed, or multiple users were found."));
1156
		return false;                         
1157
	}
1158

    
1159
	/* Now lets bind as the user we found */
1160
	$passwd = isset($authcfg['ldap_utf8']) ? utf8_encode($passwd) : $passwd;
1161
	if (!($res = @ldap_bind($ldap, $userdn, $passwd))) {
1162
		log_error(sprintf(gettext('ERROR! Could not login to server %1$s as user %2$s: %3$s'), $ldapname, $username, ldap_error($ldap)));
1163
		@ldap_unbind($ldap);
1164
		return false;
1165
	}
1166

    
1167
	if ($debug) {
1168
		$userdn = isset($authcfg['ldap_utf8']) ? utf8_decode($userdn) : $userdn;
1169
		log_auth(sprintf(gettext('Logged in successfully as %1$s via LDAP server %2$s with DN = %3$s.'), $username, $ldapname, $userdn));
1170
	}
1171

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

    
1175
	return true;
1176
}
1177

    
1178
function radius_backed($username, $passwd, $authcfg, &$attributes = array()) {
1179
	global $debug, $config;
1180
	$ret = false;
1181

    
1182
	require_once("radius.inc");
1183

    
1184
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
1185
	if ($authcfg) {
1186
		$radiusservers = array();
1187
		$radiusservers[0]['ipaddr'] = $authcfg['host'];
1188
		$radiusservers[0]['port'] = $authcfg['radius_auth_port'];
1189
		$radiusservers[0]['sharedsecret'] = $authcfg['radius_secret'];
1190
		$radiusservers[0]['timeout'] = $authcfg['radius_timeout'];
1191
	} else
1192
		return false;
1193

    
1194
	/* Add a new servers to our instance */
1195
	foreach ($radiusservers as $radsrv) {
1196
		$timeout = (is_numeric($radsrv['timeout'])) ? $radsrv['timeout'] : 5;
1197
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret'], $timeout);
1198
	}
1199

    
1200
	if (PEAR::isError($rauth->start())) {
1201
		$retvalue['auth_val'] = 1;
1202
		$retvalue['error'] = $rauth->getError();
1203
		if ($debug)
1204
			printf(gettext("Radius start: %s<br>\n"), $retvalue['error']);
1205
	}
1206

    
1207
	// XXX - billm - somewhere in here we need to handle securid challenge/response
1208

    
1209
	/* Send request */
1210
	$result = $rauth->send();
1211
	if (PEAR::isError($result)) {
1212
		$retvalue['auth_val'] = 1;
1213
		$retvalue['error'] = $result->getMessage();
1214
		if ($debug)
1215
			printf(gettext("Radius send failed: %s<br>\n"), $retvalue['error']);
1216
	} else if ($result === true) {
1217
		if ($rauth->getAttributes())
1218
			$attributes = $rauth->listAttributes();
1219
		$retvalue['auth_val'] = 2;
1220
		if ($debug)
1221
			printf(gettext("Radius Auth succeeded")."<br>\n");
1222
		$ret = true;
1223
	} else {
1224
		$retvalue['auth_val'] = 3;
1225
		if ($debug)
1226
			printf(gettext("Radius Auth rejected")."<br>\n");
1227
	}
1228

    
1229
	// close OO RADIUS_AUTHENTICATION
1230
	$rauth->close();
1231

    
1232
	return $ret;
1233
}
1234

    
1235
function get_user_expiration_date($username) {
1236
	$user = getUserEntry($username);
1237
	if ($user['expires']) 
1238
		return $user['expires'];
1239
}
1240

    
1241
function is_account_expired($username) {
1242
	$expirydate = get_user_expiration_date($username);
1243
	if ($expirydate) {
1244
		if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($expirydate))))
1245
			return true;
1246
	}
1247

    
1248
	return false;
1249
}
1250

    
1251
function is_account_disabled($username) {
1252
	$user = getUserEntry($username);
1253
	if (isset($user['disabled']))
1254
		return true;
1255

    
1256
	return false;
1257
}
1258

    
1259
function auth_get_authserver($name) {
1260
        global $config;
1261

    
1262
        if (is_array($config['system']['authserver'])) {
1263
                foreach ($config['system']['authserver'] as $authcfg) {
1264
                        if ($authcfg['name'] == $name)
1265
                                return $authcfg;
1266
                }
1267
        }
1268
	if ($name == "Local Database")
1269
		return array("name" => gettext("Local Database"), "type" => "Local Auth", "host" => $config['system']['hostname']);
1270
}
1271

    
1272
function auth_get_authserver_list() {
1273
        global $config;
1274

    
1275
	$list = array();
1276

    
1277
        if (is_array($config['system']['authserver'])) {
1278
                foreach ($config['system']['authserver'] as $authcfg) {
1279
			/* Add support for disabled entries? */
1280
			$list[$authcfg['name']] = $authcfg;
1281
                }
1282
        }
1283

    
1284
	$list["Local Database"] = array( "name" => gettext("Local Database"), "type" => "Local Auth", "host" => $config['system']['hostname']);
1285
	return $list;
1286
}
1287

    
1288
function getUserGroups($username, $authcfg) {
1289
	global $config;
1290

    
1291
	$allowed_groups = array();
1292

    
1293
	switch($authcfg['type']) {
1294
        case 'ldap':
1295
		$allowed_groups = @ldap_get_groups($username, $authcfg);
1296
		break;
1297
	case 'radius':
1298
		break;
1299
	default:
1300
		$user = getUserEntry($username);
1301
		$allowed_groups = @local_user_get_groups($user, true);
1302
		break;
1303
	}
1304

    
1305
	$member_groups = array();
1306
        if (is_array($config['system']['group'])) {
1307
                foreach ($config['system']['group'] as $group)
1308
                        if (in_array($group['name'], $allowed_groups))
1309
				$member_groups[] = $group['name'];
1310
	}
1311

    
1312
	return $member_groups;
1313
}
1314

    
1315
function authenticate_user($username, $password, $authcfg = NULL, &$attributes = array()) {
1316

    
1317
	if (!$authcfg) {
1318
		return local_backed($username, $password);
1319
	}
1320

    
1321
	$authenticated = false;
1322
	switch($authcfg['type']) {
1323
        case 'ldap':
1324
                if (ldap_backed($username, $password, $authcfg))
1325
                        $authenticated = true;
1326
                break;
1327
        case 'radius':
1328
                if (radius_backed($username, $password, $authcfg, $attributes))
1329
                        $authenticated = true;
1330
                break;
1331
        default:
1332
                /* lookup user object by name */
1333
                if (local_backed($username, $password))
1334
                        $authenticated = true;
1335
                break;
1336
        }
1337

    
1338
	return $authenticated;
1339
}
1340

    
1341
function session_auth() {
1342
	global $HTTP_SERVER_VARS, $config, $_SESSION, $page;
1343

    
1344
	// Handle HTTPS httponly and secure flags
1345
	if($config['system']['webgui']['protocol'] == "https") {
1346
		$currentCookieParams = session_get_cookie_params();
1347
		session_set_cookie_params(
1348
			$currentCookieParams["lifetime"],
1349
			$currentCookieParams["path"],
1350
			NULL,
1351
			true,
1352
			true
1353
		);
1354
	}
1355

    
1356
	if (!session_id())
1357
		session_start();
1358

    
1359
	/* Validate incoming login request */
1360
	if (isset($_POST['login']) && !empty($_POST['usernamefld']) && !empty($_POST['passwordfld'])) {
1361
		$authcfg = auth_get_authserver($config['system']['webgui']['authmode']);
1362
		if (authenticate_user($_POST['usernamefld'], $_POST['passwordfld'], $authcfg) || 
1363
		    authenticate_user($_POST['usernamefld'], $_POST['passwordfld'])) {
1364
			session_regenerate_id();
1365
			$_SESSION['Logged_In'] = "True";
1366
			$_SESSION['Username'] = $_POST['usernamefld'];
1367
			$_SESSION['last_access'] = time();
1368
			if(! isset($config['system']['webgui']['quietlogin'])) {
1369
				log_auth(sprintf(gettext("Successful login for user '%1\$s' from: %2\$s"), $_POST['usernamefld'], $_SERVER['REMOTE_ADDR']));
1370
			}
1371
			$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1372
			if (isset($_POST['postafterlogin']))
1373
				return true;
1374
			else {
1375
				if (empty($page))
1376
					$page = "/";
1377
				header("Location: {$page}");
1378
			}
1379
			exit;
1380
		} else {
1381
			/* give the user an error message */
1382
			$_SESSION['Login_Error'] = "Username or Password incorrect";
1383
			log_auth("webConfigurator authentication error for '{$_POST['usernamefld']}' from {$_SERVER['REMOTE_ADDR']}");
1384
			if(isAjax()) {
1385
				echo "showajaxmessage('{$_SESSION['Login_Error']}');";
1386
				return;
1387
			}
1388
		}
1389
	}
1390

    
1391
	/* Show login page if they aren't logged in */
1392
	if (empty($_SESSION['Logged_In']))
1393
		return false;
1394

    
1395
	/* If session timeout isn't set, we don't mark sessions stale */
1396
	if (!isset($config['system']['webgui']['session_timeout'])) {
1397
		/* Default to 4 hour timeout if one is not set */
1398
		if ($_SESSION['last_access'] < (time() - 14400)) {
1399
			$_GET['logout'] = true;
1400
			$_SESSION['Logout'] = true;
1401
		} else
1402
			$_SESSION['last_access'] = time();	
1403
	} else if (intval($config['system']['webgui']['session_timeout']) == 0) {
1404
		/* only update if it wasn't ajax */
1405
		if (!isAjax())
1406
			$_SESSION['last_access'] = time();
1407
	} else {
1408
		/* Check for stale session */
1409
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
1410
			$_GET['logout'] = true;
1411
			$_SESSION['Logout'] = true;
1412
		} else {
1413
			/* only update if it wasn't ajax */
1414
			if (!isAjax())
1415
				$_SESSION['last_access'] = time();
1416
		}
1417
	}
1418

    
1419
	/* user hit the logout button */
1420
	if (isset($_GET['logout'])) {
1421

    
1422
		if ($_SESSION['Logout'])
1423
			log_error(sprintf(gettext("Session timed out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1424
		else
1425
			log_error(sprintf(gettext("User logged out for user '%1\$s' from: %2\$s"), $_SESSION['Username'], $_SERVER['REMOTE_ADDR']));
1426

    
1427
		/* wipe out $_SESSION */
1428
		$_SESSION = array();
1429

    
1430
		if (isset($_COOKIE[session_name()]))
1431
			setcookie(session_name(), '', time()-42000, '/');
1432

    
1433
		/* and destroy it */
1434
		session_destroy();
1435

    
1436
		$scriptName = explode("/", $_SERVER["SCRIPT_FILENAME"]);
1437
		$scriptElms = count($scriptName);
1438
		$scriptName = $scriptName[$scriptElms-1];
1439

    
1440
		if (isAjax())
1441
			return false;
1442

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

    
1446
		return false;
1447
	}
1448

    
1449
	/*
1450
	 * this is for debugging purpose if you do not want to use Ajax
1451
	 * to submit a HTML form. It basically diables the observation
1452
	 * of the submit event and hence does not trigger Ajax.
1453
	 */
1454
	if ($_GET['disable_ajax'])
1455
		$_SESSION['NO_AJAX'] = "True";
1456

    
1457
	/*
1458
	 * Same to re-enable Ajax.
1459
	 */
1460
	if ($_GET['enable_ajax'])
1461
		unset($_SESSION['NO_AJAX']);
1462

    
1463
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
1464
	return true;
1465
}
1466

    
1467
?>
(5-5/66)