Project

General

Profile

Download (28.5 KB) Statistics
| Branch: | Tag: | Revision:
1 55eb9c44 --global
<?php
2
/* $Id$ */
3
/*
4
		Copyright (C) 2007, 2008 Scott Ullrich <sullrich@gmail.com>
5
		All rights reserved.
6
7
        Copyright (C) 2005-2006 Bill Marquette <bill.marquette@gmail.com>
8
        All rights reserved.
9
10
        Copyright (C) 2006 Paul Taylor <paultaylor@winn-dixie.com>.
11
        All rights reserved.
12
13
        Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
14
        All rights reserved.
15
16
        Redistribution and use in source and binary forms, with or without
17
        modification, are permitted provided that the following conditions are met:
18
19
        1. Redistributions of source code must retain the above copyright notice,
20
           this list of conditions and the following disclaimer.
21
22
        2. Redistributions in binary form must reproduce the above copyright
23
           notice, this list of conditions and the following disclaimer in the
24
           documentation and/or other materials provided with the distribution.
25
26
        THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
27
        INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28
        AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29
        AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
30
        OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31
        SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32
        INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33
        CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34
        ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
        POSSIBILITY OF SUCH DAMAGE.
36
37
		DISABLE_PHP_LINT_CHECKING
38 523855b0 Scott Ullrich
		pfSense_BUILDER_BINARIES:	/usr/sbin/pw	/bin/cp
39
		pfSense_MODULE:	auth
40 55eb9c44 --global
*/
41
42
/*
43
 * NOTE : Portions of the mschapv2 support was based on the BSD licensed CHAP.php
44
 * file courtesy of Michael Retterklieber.
45
 */
46
47 65e2c06c Erik
require_once("config.gui.inc");
48 55eb9c44 --global
49
$groupindex = index_groups();
50
$userindex = index_users();
51
52
function index_groups() {
53
	global $g, $debug, $config, $groupindex;
54
55
	$groupindex = array();
56
57
	if (isset($config['system']['group'])) {
58
		$i = 0;
59
		foreach($config['system']['group'] as $groupent) {
60
			$groupindex[$groupent['name']] = $i;
61
			$i++;
62
		}
63
	}
64
65
	return ($groupindex);
66
}
67
68
function index_users() {
69
	global $g, $debug, $config;
70
71
	if (isset($config['system']['user'])) {
72
		$i = 0;
73
		foreach($config['system']['user'] as $userent) {
74
			$userindex[$userent['name']] = $i;
75
			$i++;
76
		}
77
	}
78
79
	return ($userindex);
80
}
81
82
function & getUserEntry($name) {
83
	global $debug, $config, $userindex;
84
	if (isset($userindex[$name]))
85
		return $config['system']['user'][$userindex[$name]];
86
}
87
88
function & getUserEntryByUID($uid) {
89
	global $debug, $config;
90
	foreach ($config['system']['user'] as & $user)
91
		if ($user['uid'] == $uid)
92
			return $user;
93
94
	return false;
95
}
96
97
function & getGroupEntry($name) {
98
	global $debug, $config, $groupindex;
99
	if (isset($groupindex[$name]))
100
		return $config['system']['group'][$groupindex[$name]];
101
}
102
103
function & getGroupEntryByGID($gid) {
104
	global $debug, $config;
105
	foreach ($config['system']['group'] as & $group)
106
		if ($group['gid'] == $gid)
107
			return $group;
108
109
	return false;
110
}
111
112 6dc88d53 Ermal Luci
function get_user_privileges(& $user) {
113
114
        $privs = $user['priv'];
115
        if (!is_array($privs))
116
                $privs = array();
117
118
        $names = local_user_get_groups($user, true);
119
120
        foreach ($names as $name) {
121
                $group = getGroupEntry($name);
122
                if (is_array($group['priv']))
123
                        $privs = array_merge( $privs, $group['priv']);
124
        }
125
126
        return $privs;
127
}
128
129
function userHasPrivilege($userent, $privid = false) {
130
131
        if (!$privid || !is_array($userent))
132
                return false;
133
134
        $privs = get_user_privileges($userent);
135
136
        if (!is_array($privs))
137
                return false;
138
139
        if (!in_array($privid, $privs))
140
                return false;
141
142
        return true;
143
}
144
145 55eb9c44 --global
function local_backed($username, $passwd) {
146
147
	$user = getUserEntry($username);
148
	if (!$user)
149
		return false;
150
151
	if ($user['password'])
152
	{
153
		$passwd = crypt($passwd, $user['password']);
154
		if ($passwd == $user['password'])
155
			return true;
156
	}
157
158
	if ($user['md5-hash'])
159
	{
160
		$passwd = md5($passwd);
161
		if ($passwd == $user['md5-hash'])
162
			return true;
163
	}
164
165
	return false;
166
}
167
168
function local_sync_accounts() {
169
	global $debug, $config;
170
	conf_mount_rw();
171
172
	/* remove local users to avoid uid conflicts */
173
	$fd = popen("/usr/sbin/pw usershow -a", "r");
174
	if ($fd) {
175
		while (!feof($fd)) {
176
			$line = explode(":",fgets($fd));
177
			if (!strncmp($line[0], "_", 1))
178
				continue;
179
			if ($line[2] < 2000)
180
				continue;
181
			if ($line[2] > 65000)
182
				continue;
183
			$cmd = "/usr/sbin/pw userdel {$line[2]}";
184
			if($debug)
185
				log_error("Running: {$cmd}");
186
			mwexec($cmd);
187
		}
188
		pclose($fd);
189
	}
190
191
	/* remove local groups to avoid gid conflicts */
192
	$gids = array();
193
	$fd = popen("/usr/sbin/pw groupshow -a", "r");
194
	if ($fd) {
195
		while (!feof($fd)) {
196
			$line = explode(":",fgets($fd));
197
			if (!strncmp($line[0], "_", 1))
198
				continue;
199
			if ($line[2] < 2000)
200
				continue;
201
			if ($line[2] > 65000)
202
				continue;
203
			$cmd = "/usr/sbin/pw groupdel {$line[2]}";
204
			if($debug)
205
				log_error("Running: {$cmd}");
206
			mwexec($cmd);
207
		}
208
		pclose($fd);
209
	}
210
211
	/* make sure the all group exists */
212
	$allgrp = getGroupEntryByGID(1998);
213
	local_group_set($allgrp, true);
214
215
	/* sync all local users */
216
	if (is_array($config['system']['user']))
217
		foreach ($config['system']['user'] as $user)
218
			local_user_set($user);
219
220
	/* sync all local groups */
221
	if (is_array($config['system']['group']))
222
		foreach ($config['system']['group'] as $group)
223
			local_group_set($group);
224
225
	conf_mount_ro();
226
227
}
228
229
function local_user_set(& $user) {
230
	global $g, $debug;
231
232 2bb07efc Scott Ullrich
	conf_mount_rw();
233
234 55eb9c44 --global
	$home_base = "/home/";	
235
	$user_uid = $user['uid'];
236
	$user_name = $user['name'];
237
	$user_home = "{$home_base}/$user_name";
238
	$user_shell = "/etc/rc.initial";
239
	$user_group = "nobody";
240
241
	// Ensure $home_base exists and is writable
242
	if (!is_dir($home_base)) 
243
		mkdir($home_base, 0755);
244
245
	// Ensure $user_home exists and is writable
246
	if(!is_dir($user_home)) 
247
		mkdir($user_home, 0755);
248
249
	/* configure shell type */
250
	if (!userHasPrivilege($user, "user-shell-access")) {
251
		if (!userHasPrivilege($user, "user-copy-files"))
252
			$user_shell = "/sbin/nologin";
253
		else
254
			$user_shell = "/usr/local/bin/scponly";
255
	}
256
257
	/* root user special handling */
258
	if ($user_uid == 0) {
259
		$cmd = "/usr/sbin/pw usermod -q -n root -s /bin/sh -H 0";
260
		if($debug)
261
			log_error("Running: {$cmd}");
262
		$fd = popen($cmd, "w");
263
		fwrite($fd, $user['password']);
264
		pclose($fd);
265
		$user_group = "wheel";
266 5b631e88 pierrepomes
		$user_home = "/root";
267 55eb9c44 --global
	}
268
269 ca1cad0f Scott Ullrich
	/* admin user special handling */
270
	if ($user_uid == 0) {
271
		$cmd = "/usr/sbin/pw usermod -q -n admin -s /bin/sh -H 0";
272
		if($debug)
273
			log_error("Running: {$cmd}");
274
		$fd = popen($cmd, "w");
275
		fwrite($fd, $user['password']);
276
		pclose($fd);
277
		$user_group = "wheel";
278
	}
279
280 55eb9c44 --global
	/* read from pw db */
281
	$fd = popen("/usr/sbin/pw usershow {$user_name} 2>&1", "r");
282
	$pwread = fgets($fd);
283
	pclose($fd);
284
285
	/* determine add or mod */
286
	if (!strncmp($pwread, "pw:", 3))
287
		$user_op = "useradd";
288
	else
289
		$user_op = "usermod";
290
291
	/* add or mod pw db */
292
	$cmd = "/usr/sbin/pw {$user_op} -q -u {$user_uid} -n {$user_name}".
293
			" -g {$user_group} -G all -s {$user_shell} -d {$user_home}".
294
			" -c ".escapeshellarg($user['fullname'])." -H 0 2>&1";
295
296
	if($debug)
297
		log_error("Running: {$cmd}");
298
	$fd = popen($cmd, "w");
299
	fwrite($fd, $user['password']);
300
	pclose($fd);
301
302
	/* create user directory if required */
303
	if (!is_dir($user_home)) {
304
		mkdir($user_home, 0700);
305
		mwexec("cp /root/.* {$home_base}/");
306
	}
307
	chown($user_home, $user_name);
308
	chgrp($user_home, $user_group);
309
310
	/* write out ssh authorized key file */
311
	if($user['authorizedkeys']) {
312 a2286360 Ermal Lu?i
		if (!is_dir("{$user_home}/.ssh")) {
313
			mkdir("{$user_home}/.ssh", 0700);
314
			chown("{$user_home}/.ssh", $user_name);
315
		}
316
		$keys = base64_decode($user['authorizedkeys']);
317
		file_put_contents("{$user_home}/.ssh/authorized_keys", $keys);
318
		chown("{$user_home}/.ssh/authorized_keys", $user_name);
319 55eb9c44 --global
	}
320 2bb07efc Scott Ullrich
	
321
	conf_mount_ro();
322 55eb9c44 --global
}
323
324
function local_user_del($user) {
325
	global $debug;
326 2bb07efc Scott Ullrich
327 55eb9c44 --global
	/* remove all memberships */
328
	local_user_get_groups($user);
329
330
	/* delete from pw db */
331
	$cmd = "/usr/sbin/pw userdel {$user['name']}";
332
333
	if($debug)
334
		log_error("Running: {$cmd}");
335
	$fd = popen($cmd, "w");
336
	fwrite($fd, $user['password']);
337
	pclose($fd);
338 2bb07efc Scott Ullrich
339 55eb9c44 --global
}
340
341
function local_user_set_password(& $user, $password) {
342
343
	$user['password'] = crypt($password);
344
	$user['md5-hash'] = md5($password);
345
346
	// Converts ascii to unicode.
347
	$astr = (string) $password;
348
	$ustr = '';
349
	for ($i = 0; $i < strlen($astr); $i++) {
350
		$a = ord($astr{$i}) << 8;
351
		$ustr.= sprintf("%X", $a);
352
	}
353
354
	// Generate the NT-HASH from the unicode string
355
	$user['nt-hash'] = bin2hex(mhash(MHASH_MD4, $ustr));
356
}
357
358
function local_user_get_groups($user, $all = false) {
359
	global $debug, $config;
360
361
	$groups = array();
362
	if (!is_array($config['system']['group']))
363
		return $groups;
364
365
	foreach ($config['system']['group'] as $group)
366
		if ( $all || ( !$all && ($group['name'] != "all")))
367
			if (is_array($group['member']))
368
				if (in_array($user['uid'], $group['member']))
369
					$groups[] = $group['name'];
370
371
	sort($groups);
372
373
	return $groups;
374
	
375
}
376
377
function local_user_set_groups($user, $new_groups = NULL ) {
378
	global $debug, $config, $groupindex;
379
380
	if (!is_array($config['system']['group']))
381
		return;
382
383
	$cur_groups = local_user_get_groups($user);
384
	$mod_groups = array();
385
386
	if (!is_array($new_groups))
387
		$new_groups = array();
388
389
	if (!is_array($cur_groups))
390
		$cur_groups = array();
391
392
	/* determine which memberships to add */
393
	foreach ($new_groups as $groupname) {
394
		if (in_array($groupname,$cur_groups))
395
			continue;
396
		$group = & $config['system']['group'][$groupindex[$groupname]];
397
		$group['member'][] = $user['uid'];
398
		$mod_groups[] = $group;
399
	}
400
401
	/* determine which memberships to remove */
402
	foreach ($cur_groups as $groupname) {
403
		if (in_array($groupname,$new_groups))
404
		continue;
405
		$group = & $config['system']['group'][$groupindex[$groupname]];
406
		$index = array_search($user['uid'], $group['member']);
407
		array_splice($group['member'], $index, 1);
408
		$mod_groups[] = $group;
409
	}
410
411
	/* sync all modified groups */
412
	foreach ($mod_groups as $group)
413
		local_group_set($group);
414
}
415
416
function local_group_set($group, $reset = false) {
417
	global $debug;
418
419
	$group_name = $group['name'];
420
	$group_gid = $group['gid'];
421
	$group_members = "''";
422
	if (!$reset && count($group['member']))
423
		$group_members = implode(",",$group['member']);
424
425
	/* read from group db */
426
	$fd = popen("/usr/sbin/pw groupshow {$group_name} 2>&1", "r");
427
	$pwread = fgets($fd);
428
	pclose($fd);
429
430
	/* determine add or mod */
431
	if (!strncmp($pwread, "pw:", 3))
432
		$group_op = "groupadd";
433
	else
434
		$group_op = "groupmod";
435
436
	/* add or mod group db */
437
	$cmd = "/usr/sbin/pw {$group_op} {$group_name} -g {$group_gid} -M {$group_members} 2>&1";
438
439
	if($debug)
440
		log_error("Running: {$cmd}");
441
	$fd = popen($cmd, "w");
442
	fwrite($fd, $user['password']);
443
	pclose($fd);
444
445
}
446
447
function local_group_del($group) {
448
	global $debug;
449
450
	/* delete from group db */
451
	$cmd = "/usr/sbin/pw groupdel {$group['name']}";
452
453
	if($debug)
454
		log_error("Running: {$cmd}");
455
	$fd = popen($cmd, "w");
456
	fwrite($fd, $user['password']);
457
	pclose($fd);
458
459
}
460
461
function ldap_test_connection() {
462
	global $debug, $config, $g;
463
464
	$ldapserver = $config['system']['webgui']['ldapserver'];
465
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
466
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
467
468
	if (!($ldap = ldap_connect($ldapserver)))
469
		return false;
470
471
	return true;
472
}
473
474
function ldap_test_bind() {
475
	global $debug, $config, $g;
476
477
	$ldapserver = $config['system']['webgui']['ldapserver'];
478
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
479
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
480
    
481
	if (!($ldap = ldap_connect($ldapserver)))
482
		return false;
483
484
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
485
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
486
    
487
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
488
		return false;
489
490
	return true;
491
}
492
493
function ldap_get_user_ous($show_complete_ou=true) {
494
	global $debug, $config, $g;
495
496
	if(!function_exists("ldap_connect"))
497
		return;
498
499
	$ldapserver     = $config['system']['webgui']['ldapserver'];
500
	$ldapbindun     = $config['system']['webgui']['ldapbindun'];
501
	$ldapbindpw     = $config['system']['webgui']['ldapbindpw'];
502
	$ldapsearchbase = "{$config['system']['webgui']['ldapsearchbase']}";
503
	$ldaptype       = $config['system']['webgui']['backend'];
504
505
	$ldapfilter = "(ou=*)";
506
	putenv('LDAPTLS_REQCERT=never');
507
	if (!($ldap = ldap_connect($ldapserver))) {
508
		log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in local_backed()");
509
		$status = local_backed($username, $passwd);
510
		return $status;
511
	}
512
513
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
514
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
515
516
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
517
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
518
		$status = local_backed($username, $passwd);
519
		return $status;
520
	}
521
522
	$search = ldap_search($ldap, $ldapsearchbase, $ldapfilter);
523
524
	$info = ldap_get_entries($ldap, $search);
525
526
	$ous = array();
527
528
	if (is_array($info)) {
529
		foreach ($info as $inf) {
530
			if (!$show_complete_ou) {
531
				$inf_split = split(",", $inf['dn']);
532
				$ou = $inf_split[0];
533
				$ou = str_replace("OU=","", $ou);
534
			} else
535
				if($inf['dn'])
536
					$ou = $inf['dn'];
537
			if($ou)
538
				$ous[] = $ou;
539
		}
540
	}
541
542
	//Tack on the default Users container for AD since its non-standard
543
	if($ldaptype == 'ldap')
544
		$ous[] = "CN=Users,".$ldapsearchbase;
545
546
	return $ous;
547
}
548
549
function ldap_get_groups($username) {
550
	global $debug, $config;
551
	
552
	if(!function_exists("ldap_connect"))
553
		return;
554
	
555
	if(!$username) 
556
		return false;
557
558
	if(stristr($username, "@")) {
559
		$username_split=split("\@", $username);
560
		$username = $username_split[0];		
561
	}
562
563
	if(stristr($username, "\\")) {
564
		$username_split=split("\\", $username);
565
		$username = $username_split[0];        
566
	}    
567
	
568
	//log_error("Getting LDAP groups for {$username}.");
569
	
570
	$ldapserver         = $config['system']['webgui']['ldapserver'];
571
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
572
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
573
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
574
	$ldapfilter         = str_replace("\$username", $username, $ldapfilter);
575
	$ldapgroupattribute = $config['system']['webgui']['ldapgroupattribute'];
576
	$ldapdn             = $_SESSION['ldapdn'];
577
	 
578
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
579
	$ldapgroupattribute = strtolower($ldapgroupattribute);
580
581
	/* connect and see if server is up */
582
	putenv('LDAPTLS_REQCERT=never');
583
	if (!($ldap = ldap_connect($ldapserver))) {
584
		log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in local_backed()");
585
		$status = local_backed($username, $passwd);
586
		return $status;	
587
	}
588
    
589
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
590
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
591
592
	/* bind as user that has rights to read group attributes */
593
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
594
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
595
		$status = local_backed($username, $passwd);
596
		return $status;
597
	}
598
599
	/* get groups from DN found */
600
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
601
	/* since we know the DN is in $_SESSION['ldapdn'] */
602
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
603
	$search    = ldap_read($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
604
	$info      = ldap_get_entries($ldap, $search);
605
606
	$countem = $info["count"];	
607
	$memberof = array();
608
	
609
	if(is_array($info[0][$ldapgroupattribute])) {
610
		/* Iterate through the groups and throw them into an array */
611
		foreach ($info[0][$ldapgroupattribute] as $member) {
612
			if (stristr($member, "CN=") !== false) {
613
				$membersplit = split(",", $member);
614
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
615
			}
616
		}
617
	}
618
	
619
	/* Time to close LDAP connection */
620
	ldap_close($ldap);
621
	
622
	$groups = print_r($memberof,true);
623
	
624
	//log_error("Returning groups ".$groups." for user $username");
625
	
626
	return $memberof;
627
}
628
629
function ldap_backed($username, $passwd) {
630
	global $debug, $config;
631
	
632
	if(!$username) 
633
		return;
634
635
	if(!function_exists("ldap_connect"))
636
		return;
637
638
	$adbindas = $username;
639
    
640
	if(stristr($username, "@")) {
641
		$username_split=split("\@", $username);
642
		$username = $username_split[0];        
643
	}
644
	if(stristr($username, "\\")) {
645
		$username_split=split("\\", $username);
646
		$username = $username_split[0];        
647
	}
648
649
	$ldapserver         = $config['system']['webgui']['ldapserver'];
650
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
651
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
652
	$ldapauthcont       = $config['system']['webgui']['ldapauthcontainers'];   
653
	$ldapnameattribute  = $config['system']['webgui']['ldapnameattribute'];  
654
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
655
	$ldaptype           = $config['system']['webgui']['backend'];
656
	$ldapfilter = str_replace("\$username", $username, $ldapfilter);
657
658
	/* first check if there is even an LDAP server populated */ 
659
	if(!$ldapserver) {
660
		log_error("ERROR!  ldap_backed() backed selected with no LDAP authentication server defined.  Defaulting to built-in local_backed().     Visit System -> User Manager -> Settings.");
661
		$status = local_backed($username, $passwd);
662
		return $status;
663
	}
664
	
665
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
666
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
667
668
	/* Make sure we can connect to LDAP */
669
	putenv('LDAPTLS_REQCERT=never');
670
	if (!($ldap = ldap_connect($ldapserver))) {
671
		log_error("ERROR!  ldap_backed() could not connect to server {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed().     Visit System -> User Manager -> Settings.");
672
		$status = local_backed($username, $passwd);		
673
		return $status;	
674
	}
675
	/* ok, its up.  now, lets bind as the bind user so we can search it */
676
	if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
677
		log_error("ERROR! ldap_backed() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
678
		ldap_close($ldap);
679
		$status = local_backed($username, $passwd);
680
		return $status;
681
	}
682
	
683
	/* Get LDAP Authcontainers and split em up. */
684
	$ldac_split = split(";", $ldapauthcont);
685
	
686
	/* now count how many there are */
687
	$containers = count($ldac_split);
688
	log_error("Number of Authentication Containers to search for $username is {$containers}");
689
	
690
	/* setup the usercount so we think we havn't found anyone yet */
691
	$usercount  = 0;
692
693
	/******************************/
694
	/* Currently LDAP Types are   */
695
	/* LDAP = Active Directory    */
696
	/* LDAPOTHER = eDir/Openldap  */
697
	/******************************/      
698
        
699
	/*****************************************************************/
700
	/* Now Active Directory We keep this seperate for future addons. */
701
	/*****************************************************************/
702
	/* Now LDAP other.  eDirectory or Netscape or Sunone or OpenLDAP */
703
	/*****************************************************************/
704
	/*  We First find the user based on username and filter          */
705
	/*  Then, once we find the first occurance of that person        */
706
	/*  We set seesion variables to ponit to the OU and DN of the    */
707
	/*  Person.  To later be used by ldap_get_groups.                */
708
	/*  that way we don't have to search twice.                      */
709
	/*****************************************************************/
710
	if ($ldaptype == 'ldap'){
711
		log_error("Now Searching for {$username} in Active directory.");
712
		/* Iterate through the user containers for search */
713
		for ($i=0;$i<$containers;$i++){
714
			/* Make sure we just use the first user we find */
715
			log_error("Now Searching in {$ldac_split[$i]} for {$ldapfilter}.");
716
			$search	 = ldap_search($ldap,$ldac_split[$i],$ldapfilter);
717
			$info	 = ldap_get_entries($ldap,$search);
718
			$matches = $info['count'];
719
			log_error("Matches Found = {$matches}");
720
			if ($matches == 1){
721
				$_SESSION['ldapdn'] = $info[0]['dn'];
722
				$_SESSION['ldapou'] = $ldac_split[$i];
723
				$_SESSION['ldapon'] = "true";
724
				$ldapdn = $_SESSION['ldapdn'];
725
				$userou = $_SESSION['ldapou'];
726
				break;
727
			}
728
		}
729
730
		if ($matches == 1){
731
			$binduser = $adbindas;
732
			log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
733
		}
734
		if ($matches != 1){
735
			log_error("ERROR! Either LDAP search failed, or multiple users were found");
736
			$status = local_backed($username, $passwd);
737
			$_SESSION['ldapon'] = "false";
738
			ldap_close($ldap);
739
			return $status;                         
740
		}
741
	}
742
743
	/*****************************************************************/
744
	/* Now LDAP other.  eDirectory or Netscape or Sunone or OpenLDAP */
745
	/*****************************************************************/
746
	/*  We First find the user based on username and filter          */
747
	/*  Then, once we find the first occurance of that person        */
748
	/*  We set seesion variables to ponit to the OU and DN of the    */
749
	/*  Person.  To later be used by ldap_get_groups.                */
750
	/*  that way we don't have to search twice.                      */
751
	/*****************************************************************/
752
	if ($ldaptype == 'ldapother'){
753
		log_error("Now Searching for {$username} in LDAP.");
754
		/* Iterate through the user containers for search */
755
		for ($i=0;$i<$containers;$i++){
756
			/* Make sure we just use the first user we find */
757
			log_error("Now searching in {$ldac_split[$i]} for {$ldapfilter}.");
758
			$search  = ldap_search($ldap,$ldac_split[$i],$ldapfilter);
759
            $info    = ldap_get_entries($ldap,$search);
760
            $matches = $info['count'];
761
            log_error("Matches Found = {$matches}.");
762
                                      
763
			if ($matches == 1){
764
				$_SESSION['ldapdn'] = $info[0]['dn'];
765
				$_SESSION['ldapou'] = $ldac_split[$i];
766
				$_SESSION['ldapon'] = "true";
767
				$ldapdn = $_SESSION['ldapdn'];
768
				$userou = $_SESSION['ldapou'];
769
				break;
770
			}
771
		}
772
		if($matches == 1){
773
			$binduser = $ldapnameattribute."=".$username.",".$userou;
774
			log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
775
		}
776
		if($matches != 1){
777
			log_error("ERROR! Either LDAP search failed, or multiple users were found");
778
			$status = local_backed($username, $passwd);
779
			ldap_close($ldap);
780
			$_SESSION['ldapon'] = "false";
781
			return $status;                         
782
		}
783
	}
784
	
785
	/* Now lets bind as the user we found */
786
	if (!($res = @ldap_bind($ldap, $binduser, $passwd))) {
787
		log_error("ERROR!  ldap_backed() could not bind to {$ldapserver} - {$username} - {$passwd}.  Defaulting to built-in local_backed().    Visit System -> User Manager -> Settings.");
788
		$status = local_backed($username, $passwd);
789
		return $status;
790
	}
791
792
	log_error("$binduser succesfully logged in via LDAP.");
793
794
	/* At this point we are bound to LDAP so the user was auth'd okay. */
795
	return true;
796
}
797
798
function radius_backed($username, $passwd){
799
	global $debug, $config, $debug;
800
	$ret = false;
801
	$radiusservers = $config['system']['radius']['servers'];
802
803
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
804
	/* Add a new servers to our instance */
805
	foreach ($radiusservers as $radsrv)
806
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
807
808
	if (!$rauth->start()) {
809
		$retvalue['auth_val'] = 1;
810
		$retvalue['error'] = $rauth->getError();
811
		if ($debug)
812
			printf("Radius start: %s<br>\n", $retvalue['error']);
813
	}
814
815
	// XXX - billm - somewhere in here we need to handle securid challenge/response
816
817
	/* Send request */
818
	$result = $rauth->send();
819
	if (PEAR::isError($result)) {
820
		$retvalue['auth_val'] = 1;
821
		$retvalue['error'] = $result->getMessage();
822
		if ($debug)
823
			printf("Radius send failed: %s<br>\n", $retvalue['error']);
824
	} else if ($result === true) {
825
		$retvalue['auth_val'] = 2;
826
		if ($debug)
827
			printf(gettext("Radius Auth succeeded")."<br>\n");
828
		$ret = true;
829
	} else {
830
		$retvalue['auth_val'] = 3;
831
		if ($debug)
832
			printf(gettext("Radius Auth rejected")."<br>\n");
833
	}
834
835
	// close OO RADIUS_AUTHENTICATION
836
	$rauth->close();
837
838
	return $ret;
839
}
840
841 7dd044f2 sullrich
function get_user_expiration_date($username) {
842
	global $config;
843
	foreach($config['system']['user']  as $user) {
844 772d3121 sullrich
		if($user['name'] == $username) {
845 7dd044f2 sullrich
			if($user['expires']) 
846
				return $user['expires'];
847
		}
848
	}
849
}
850
851 b4bfd25d sullrich
function is_account_disabled($username) {
852
	global $config;
853 772d3121 sullrich
	foreach($config['system']['user'] as $user)
854
		if($user['name'] == $username) 
855 d2aa8cd6 sullrich
			if(isset($user['disabled'])) 
856
				return true;
857 b4bfd25d sullrich
	return false;
858
}
859
860 55eb9c44 --global
function session_auth($backing) {
861 8fdc621d sullrich
	global $g, $debug, $HTTP_SERVER_VARS, $userindex, $config, $_SESSION, $page;
862 55eb9c44 --global
863
	session_start();
864
865
	/* Validate incoming login request */
866
	if (isset($_POST['login'])) {
867
		if ($backing($_POST['usernamefld'], $_POST['passwordfld'])) {
868 7dd044f2 sullrich
			$acct_expires = get_user_expiration_date($_POST['usernamefld']);
869
			if($acct_expires) {
870
				if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($acct_expires)))) {
871 158d9aa6 sullrich
					log_error("Attempted login for invalid user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
872
					if(isAjax()) {
873
						echo "showajaxmessage('{$_SESSION['Login_Error']}');";
874
						return;
875
					}
876 7dd044f2 sullrich
				}
877
			} else {
878 b4bfd25d sullrich
				if(is_account_disabled($_POST['usernamefld'])) {
879 158d9aa6 sullrich
					log_error("Attempted login for invalid user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
880
					if(isAjax()) {
881
						echo "showajaxmessage('{$_SESSION['Login_Error']}');";
882
						return;
883
					}
884 b4bfd25d sullrich
				} else {
885
					$_SESSION['Logged_In'] = "True";
886
					$_SESSION['Username'] = $_POST['usernamefld'];
887
					$_SESSION['last_access'] = time();
888
					log_error("Successful login for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
889 5c15e649 sullrich
					require_once("functions.inc");
890
					pfSenseHeader("/{$page}");
891 b4bfd25d sullrich
				}
892 7dd044f2 sullrich
			}
893 55eb9c44 --global
		} else {
894
			/* give the user a more detailed error message */
895
			if (isset($userindex[$_POST['usernamefld']])) {
896
				$_SESSION['Login_Error'] = "Username or Password incorrect";
897
				log_error("Wrong password entered for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
898
				if(isAjax()) {
899
					echo "showajaxmessage('{$_SESSION['Login_Error']}');";
900
					return;
901
				}
902
			} else {
903
				$_SESSION['Login_Error'] = "Username or Password incorrect";
904
				log_error("Attempted login for invalid user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
905
				if(isAjax()) {
906
					echo "showajaxmessage('{$_SESSION['Login_Error']}');";
907
					return;
908
				}
909
			}
910
		}
911
	}
912
913
	/* Show login page if they aren't logged in */
914
	if (empty($_SESSION['Logged_In'])) {
915
		/* Don't display login forms to AJAX */
916
		if (isAjax())
917
			return false;
918
		require_once("authgui.inc");
919
		display_login_form();
920
		return false;
921
	}
922
923
	/* If session timeout isn't set, we don't mark sessions stale */
924
	if (!isset($config['system']['webgui']['session_timeout']) ||
925
		$config['system']['webgui']['session_timeout'] == 0 ||
926
		$config['system']['webgui']['session_timeout'] == "")
927
		$_SESSION['last_access'] = time();
928
	else {
929
		/* Check for stale session */
930
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
931
			$_GET['logout'] = true;
932
			$_SESSION['Logout'] = true;
933
		} else {
934
			/* only update if it wasn't ajax */
935
			if (!isAjax())
936
				$_SESSION['last_access'] = time();
937
		}
938
	}
939
940
	/* obtain user object */
941
	$user = getUserEntry($_SESSION['Username']);
942
943
	/* user hit the logout button */
944
	if (isset($_GET['logout'])) {
945
946
		if ($_SESSION['Logout'])
947
			log_error("Session timed out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
948
		else
949
			log_error("User logged out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
950
951
		/* wipe out $_SESSION */
952
		$_SESSION = array();
953
954
		if (isset($_COOKIE[session_name()]))
955
			setcookie(session_name(), '', time()-42000, '/');
956
957
		/* and destroy it */
958
		session_destroy();
959
960
		$scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
961
		$scriptElms = count($scriptName);
962
		$scriptName = $scriptName[$scriptElms-1];
963
964
		if (isAjax())
965
			return false;
966
967
		/* redirect to page the user is on, it'll prompt them to login again */
968 6dc88d53 Ermal Luci
		Header("Location: {$scriptName}");
969 55eb9c44 --global
970
		return false;
971
	}
972
973
	/*
974
	 * this is for debugging purpose if you do not want to use Ajax
975
	 * to submit a HTML form. It basically diables the observation
976
	 * of the submit event and hence does not trigger Ajax.
977
	 */
978
	if ($_GET['disable_ajax']) {
979
		$_SESSION['NO_AJAX'] = "True";
980
		$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
981
		return true;
982
	}
983
984
	/*
985
	 * Same to re-enable Ajax.
986
	 */
987
	if ($_GET['enable_ajax']) {
988
		unset($_SESSION['NO_AJAX']);
989
		$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
990
		return true;
991
	}
992
993
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
994
	return true;
995
}
996
997 a2286360 Ermal Lu?i
?>