Project

General

Profile

Download (28.5 KB) Statistics
| Branch: | Tag: | Revision:
1
<?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
		pfSense_BUILDER_BINARIES:	/usr/sbin/pw	/bin/cp
39
		pfSense_MODULE:	auth
40
*/
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
require_once("config.gui.inc");
48

    
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
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
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
	conf_mount_rw();
233

    
234
	$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
		$user_home = "/root";
267
	}
268

    
269
	/* 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
	/* 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
		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
	}
320
	
321
	conf_mount_ro();
322
}
323

    
324
function local_user_del($user) {
325
	global $debug;
326

    
327
	/* 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

    
339
}
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
function get_user_expiration_date($username) {
842
	global $config;
843
	foreach($config['system']['user']  as $user) {
844
		if($user['name'] == $username) {
845
			if($user['expires']) 
846
				return $user['expires'];
847
		}
848
	}
849
}
850

    
851
function is_account_disabled($username) {
852
	global $config;
853
	foreach($config['system']['user'] as $user)
854
		if($user['name'] == $username) 
855
			if(isset($user['disabled'])) 
856
				return true;
857
	return false;
858
}
859

    
860
function session_auth($backing) {
861
	global $g, $debug, $HTTP_SERVER_VARS, $userindex, $config, $_SESSION, $page;
862

    
863
	session_start();
864

    
865
	/* Validate incoming login request */
866
	if (isset($_POST['login'])) {
867
		if ($backing($_POST['usernamefld'], $_POST['passwordfld'])) {
868
			$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
					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
				}
877
			} else {
878
				if(is_account_disabled($_POST['usernamefld'])) {
879
					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
				} 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
					require_once("functions.inc");
890
					pfSenseHeader("/{$page}");
891
				}
892
			}
893
		} 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
		Header("Location: {$scriptName}");
969

    
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
?>
(4-4/51)