Project

General

Profile

Download (27.3 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
	}
267

    
268
	/* admin user special handling */
269
	if ($user_uid == 0) {
270
		$cmd = "/usr/sbin/pw usermod -q -n admin -s /bin/sh -H 0";
271
		if($debug)
272
			log_error("Running: {$cmd}");
273
		$fd = popen($cmd, "w");
274
		fwrite($fd, $user['password']);
275
		pclose($fd);
276
		$user_group = "wheel";
277
	}
278

    
279
	/* read from pw db */
280
	$fd = popen("/usr/sbin/pw usershow {$user_name} 2>&1", "r");
281
	$pwread = fgets($fd);
282
	pclose($fd);
283

    
284
	/* determine add or mod */
285
	if (!strncmp($pwread, "pw:", 3))
286
		$user_op = "useradd";
287
	else
288
		$user_op = "usermod";
289

    
290
	/* add or mod pw db */
291
	$cmd = "/usr/sbin/pw {$user_op} -q -u {$user_uid} -n {$user_name}".
292
			" -g {$user_group} -G all -s {$user_shell} -d {$user_home}".
293
			" -c ".escapeshellarg($user['fullname'])." -H 0 2>&1";
294

    
295
	if($debug)
296
		log_error("Running: {$cmd}");
297
	$fd = popen($cmd, "w");
298
	fwrite($fd, $user['password']);
299
	pclose($fd);
300

    
301
	/* create user directory if required */
302
	if (!is_dir($user_home)) {
303
		mkdir($user_home, 0700);
304
		mwexec("cp /root/.* {$home_base}/");
305
	}
306
	chown($user_home, $user_name);
307
	chgrp($user_home, $user_group);
308

    
309
	/* write out ssh authorized key file */
310
	if($user['authorizedkeys']) {
311
		if (!is_dir("{$user_home}/.ssh")) {
312
			mkdir("{$user_home}/.ssh", 0700);
313
			chown("{$user_home}/.ssh", $user_name);
314
		}
315
		$keys = base64_decode($user['authorizedkeys']);
316
		file_put_contents("{$user_home}/.ssh/authorized_keys", $keys);
317
		chown("{$user_home}/.ssh/authorized_keys", $user_name);
318
	}
319
	
320
	conf_mount_ro();
321
}
322

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

    
326
	/* remove all memberships */
327
	local_user_get_groups($user);
328

    
329
	/* delete from pw db */
330
	$cmd = "/usr/sbin/pw userdel {$user['name']}";
331

    
332
	if($debug)
333
		log_error("Running: {$cmd}");
334
	$fd = popen($cmd, "w");
335
	fwrite($fd, $user['password']);
336
	pclose($fd);
337

    
338
}
339

    
340
function local_user_set_password(& $user, $password) {
341

    
342
	$user['password'] = crypt($password);
343
	$user['md5-hash'] = md5($password);
344

    
345
	// Converts ascii to unicode.
346
	$astr = (string) $password;
347
	$ustr = '';
348
	for ($i = 0; $i < strlen($astr); $i++) {
349
		$a = ord($astr{$i}) << 8;
350
		$ustr.= sprintf("%X", $a);
351
	}
352

    
353
	// Generate the NT-HASH from the unicode string
354
	$user['nt-hash'] = bin2hex(mhash(MHASH_MD4, $ustr));
355
}
356

    
357
function local_user_get_groups($user, $all = false) {
358
	global $debug, $config;
359

    
360
	$groups = array();
361
	if (!is_array($config['system']['group']))
362
		return $groups;
363

    
364
	foreach ($config['system']['group'] as $group)
365
		if ( $all || ( !$all && ($group['name'] != "all")))
366
			if (is_array($group['member']))
367
				if (in_array($user['uid'], $group['member']))
368
					$groups[] = $group['name'];
369

    
370
	sort($groups);
371

    
372
	return $groups;
373
	
374
}
375

    
376
function local_user_set_groups($user, $new_groups = NULL ) {
377
	global $debug, $config, $groupindex;
378

    
379
	if (!is_array($config['system']['group']))
380
		return;
381

    
382
	$cur_groups = local_user_get_groups($user);
383
	$mod_groups = array();
384

    
385
	if (!is_array($new_groups))
386
		$new_groups = array();
387

    
388
	if (!is_array($cur_groups))
389
		$cur_groups = array();
390

    
391
	/* determine which memberships to add */
392
	foreach ($new_groups as $groupname) {
393
		if (in_array($groupname,$cur_groups))
394
			continue;
395
		$group = & $config['system']['group'][$groupindex[$groupname]];
396
		$group['member'][] = $user['uid'];
397
		$mod_groups[] = $group;
398
	}
399

    
400
	/* determine which memberships to remove */
401
	foreach ($cur_groups as $groupname) {
402
		if (in_array($groupname,$new_groups))
403
		continue;
404
		$group = & $config['system']['group'][$groupindex[$groupname]];
405
		$index = array_search($user['uid'], $group['member']);
406
		array_splice($group['member'], $index, 1);
407
		$mod_groups[] = $group;
408
	}
409

    
410
	/* sync all modified groups */
411
	foreach ($mod_groups as $group)
412
		local_group_set($group);
413
}
414

    
415
function local_group_set($group, $reset = false) {
416
	global $debug;
417

    
418
	$group_name = $group['name'];
419
	$group_gid = $group['gid'];
420
	$group_members = "''";
421
	if (!$reset && count($group['member']))
422
		$group_members = implode(",",$group['member']);
423

    
424
	/* read from group db */
425
	$fd = popen("/usr/sbin/pw groupshow {$group_name} 2>&1", "r");
426
	$pwread = fgets($fd);
427
	pclose($fd);
428

    
429
	/* determine add or mod */
430
	if (!strncmp($pwread, "pw:", 3))
431
		$group_op = "groupadd";
432
	else
433
		$group_op = "groupmod";
434

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

    
438
	if($debug)
439
		log_error("Running: {$cmd}");
440
	$fd = popen($cmd, "w");
441
	fwrite($fd, $user['password']);
442
	pclose($fd);
443

    
444
}
445

    
446
function local_group_del($group) {
447
	global $debug;
448

    
449
	/* delete from group db */
450
	$cmd = "/usr/sbin/pw groupdel {$group['name']}";
451

    
452
	if($debug)
453
		log_error("Running: {$cmd}");
454
	$fd = popen($cmd, "w");
455
	fwrite($fd, $user['password']);
456
	pclose($fd);
457

    
458
}
459

    
460
function ldap_test_connection() {
461
	global $debug, $config, $g;
462

    
463
	$ldapserver = $config['system']['webgui']['ldapserver'];
464
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
465
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
466

    
467
	if (!($ldap = ldap_connect($ldapserver)))
468
		return false;
469

    
470
	return true;
471
}
472

    
473
function ldap_test_bind() {
474
	global $debug, $config, $g;
475

    
476
	$ldapserver = $config['system']['webgui']['ldapserver'];
477
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
478
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
479
    
480
	if (!($ldap = ldap_connect($ldapserver)))
481
		return false;
482

    
483
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
484
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
485
    
486
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
487
		return false;
488

    
489
	return true;
490
}
491

    
492
function ldap_get_user_ous($show_complete_ou=true) {
493
	global $debug, $config, $g;
494

    
495
	if(!function_exists("ldap_connect"))
496
		return;
497

    
498
	$ldapserver     = $config['system']['webgui']['ldapserver'];
499
	$ldapbindun     = $config['system']['webgui']['ldapbindun'];
500
	$ldapbindpw     = $config['system']['webgui']['ldapbindpw'];
501
	$ldapsearchbase = "{$config['system']['webgui']['ldapsearchbase']}";
502
	$ldaptype       = $config['system']['webgui']['backend'];
503

    
504
	$ldapfilter = "(ou=*)";
505
	putenv('LDAPTLS_REQCERT=never');
506
	if (!($ldap = ldap_connect($ldapserver))) {
507
		log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in local_backed()");
508
		$status = local_backed($username, $passwd);
509
		return $status;
510
	}
511

    
512
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
513
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
514

    
515
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
516
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
517
		$status = local_backed($username, $passwd);
518
		return $status;
519
	}
520

    
521
	$search = ldap_search($ldap, $ldapsearchbase, $ldapfilter);
522

    
523
	$info = ldap_get_entries($ldap, $search);
524

    
525
	$ous = array();
526

    
527
	if (is_array($info)) {
528
		foreach ($info as $inf) {
529
			if (!$show_complete_ou) {
530
				$inf_split = split(",", $inf['dn']);
531
				$ou = $inf_split[0];
532
				$ou = str_replace("OU=","", $ou);
533
			} else
534
				if($inf['dn'])
535
					$ou = $inf['dn'];
536
			if($ou)
537
				$ous[] = $ou;
538
		}
539
	}
540

    
541
	//Tack on the default Users container for AD since its non-standard
542
	if($ldaptype == 'ldap')
543
		$ous[] = "CN=Users,".$ldapsearchbase;
544

    
545
	return $ous;
546
}
547

    
548
function ldap_get_groups($username) {
549
	global $debug, $config;
550
	
551
	if(!function_exists("ldap_connect"))
552
		return;
553
	
554
	if(!$username) 
555
		return false;
556

    
557
	if(stristr($username, "@")) {
558
		$username_split=split("\@", $username);
559
		$username = $username_split[0];		
560
	}
561

    
562
	if(stristr($username, "\\")) {
563
		$username_split=split("\\", $username);
564
		$username = $username_split[0];        
565
	}    
566
	
567
	//log_error("Getting LDAP groups for {$username}.");
568
	
569
	$ldapserver         = $config['system']['webgui']['ldapserver'];
570
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
571
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
572
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
573
	$ldapfilter         = str_replace("\$username", $username, $ldapfilter);
574
	$ldapgroupattribute = $config['system']['webgui']['ldapgroupattribute'];
575
	$ldapdn             = $_SESSION['ldapdn'];
576
	 
577
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
578
	$ldapgroupattribute = strtolower($ldapgroupattribute);
579

    
580
	/* connect and see if server is up */
581
	putenv('LDAPTLS_REQCERT=never');
582
	if (!($ldap = ldap_connect($ldapserver))) {
583
		log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in local_backed()");
584
		$status = local_backed($username, $passwd);
585
		return $status;	
586
	}
587
    
588
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
589
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
590

    
591
	/* bind as user that has rights to read group attributes */
592
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
593
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
594
		$status = local_backed($username, $passwd);
595
		return $status;
596
	}
597

    
598
	/* get groups from DN found */
599
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
600
	/* since we know the DN is in $_SESSION['ldapdn'] */
601
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
602
	$search    = ldap_read($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
603
	$info      = ldap_get_entries($ldap, $search);
604

    
605
	$countem = $info["count"];	
606
	$memberof = array();
607
	
608
	if(is_array($info[0][$ldapgroupattribute])) {
609
		/* Iterate through the groups and throw them into an array */
610
		foreach ($info[0][$ldapgroupattribute] as $member) {
611
			if (stristr($member, "CN=") !== false) {
612
				$membersplit = split(",", $member);
613
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
614
			}
615
		}
616
	}
617
	
618
	/* Time to close LDAP connection */
619
	ldap_close($ldap);
620
	
621
	$groups = print_r($memberof,true);
622
	
623
	//log_error("Returning groups ".$groups." for user $username");
624
	
625
	return $memberof;
626
}
627

    
628
function ldap_backed($username, $passwd) {
629
	global $debug, $config;
630
	
631
	if(!$username) 
632
		return;
633

    
634
	if(!function_exists("ldap_connect"))
635
		return;
636

    
637
	$adbindas = $username;
638
    
639
	if(stristr($username, "@")) {
640
		$username_split=split("\@", $username);
641
		$username = $username_split[0];        
642
	}
643
	if(stristr($username, "\\")) {
644
		$username_split=split("\\", $username);
645
		$username = $username_split[0];        
646
	}
647

    
648
	$ldapserver         = $config['system']['webgui']['ldapserver'];
649
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
650
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
651
	$ldapauthcont       = $config['system']['webgui']['ldapauthcontainers'];   
652
	$ldapnameattribute  = $config['system']['webgui']['ldapnameattribute'];  
653
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
654
	$ldaptype           = $config['system']['webgui']['backend'];
655
	$ldapfilter = str_replace("\$username", $username, $ldapfilter);
656

    
657
	/* first check if there is even an LDAP server populated */ 
658
	if(!$ldapserver) {
659
		log_error("ERROR!  ldap_backed() backed selected with no LDAP authentication server defined.  Defaulting to built-in local_backed().     Visit System -> User Manager -> Settings.");
660
		$status = local_backed($username, $passwd);
661
		return $status;
662
	}
663
	
664
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
665
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
666

    
667
	/* Make sure we can connect to LDAP */
668
	putenv('LDAPTLS_REQCERT=never');
669
	if (!($ldap = ldap_connect($ldapserver))) {
670
		log_error("ERROR!  ldap_backed() could not connect to server {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed().     Visit System -> User Manager -> Settings.");
671
		$status = local_backed($username, $passwd);		
672
		return $status;	
673
	}
674
	/* ok, its up.  now, lets bind as the bind user so we can search it */
675
	if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
676
		log_error("ERROR! ldap_backed() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
677
		ldap_close($ldap);
678
		$status = local_backed($username, $passwd);
679
		return $status;
680
	}
681
	
682
	/* Get LDAP Authcontainers and split em up. */
683
	$ldac_split = split(";", $ldapauthcont);
684
	
685
	/* now count how many there are */
686
	$containers = count($ldac_split);
687
	log_error("Number of Authentication Containers to search for $username is {$containers}");
688
	
689
	/* setup the usercount so we think we havn't found anyone yet */
690
	$usercount  = 0;
691

    
692
	/******************************/
693
	/* Currently LDAP Types are   */
694
	/* LDAP = Active Directory    */
695
	/* LDAPOTHER = eDir/Openldap  */
696
	/******************************/      
697
        
698
	/*****************************************************************/
699
	/* Now Active Directory We keep this seperate for future addons. */
700
	/*****************************************************************/
701
	/* Now LDAP other.  eDirectory or Netscape or Sunone or OpenLDAP */
702
	/*****************************************************************/
703
	/*  We First find the user based on username and filter          */
704
	/*  Then, once we find the first occurance of that person        */
705
	/*  We set seesion variables to ponit to the OU and DN of the    */
706
	/*  Person.  To later be used by ldap_get_groups.                */
707
	/*  that way we don't have to search twice.                      */
708
	/*****************************************************************/
709
	if ($ldaptype == 'ldap'){
710
		log_error("Now Searching for {$username} in Active directory.");
711
		/* Iterate through the user containers for search */
712
		for ($i=0;$i<$containers;$i++){
713
			/* Make sure we just use the first user we find */
714
			log_error("Now Searching in {$ldac_split[$i]} for {$ldapfilter}.");
715
			$search	 = ldap_search($ldap,$ldac_split[$i],$ldapfilter);
716
			$info	 = ldap_get_entries($ldap,$search);
717
			$matches = $info['count'];
718
			log_error("Matches Found = {$matches}");
719
			if ($matches == 1){
720
				$_SESSION['ldapdn'] = $info[0]['dn'];
721
				$_SESSION['ldapou'] = $ldac_split[$i];
722
				$_SESSION['ldapon'] = "true";
723
				$ldapdn = $_SESSION['ldapdn'];
724
				$userou = $_SESSION['ldapou'];
725
				break;
726
			}
727
		}
728

    
729
		if ($matches == 1){
730
			$binduser = $adbindas;
731
			log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
732
		}
733
		if ($matches != 1){
734
			log_error("ERROR! Either LDAP search failed, or multiple users were found");
735
			$status = local_backed($username, $passwd);
736
			$_SESSION['ldapon'] = "false";
737
			ldap_close($ldap);
738
			return $status;                         
739
		}
740
	}
741

    
742
	/*****************************************************************/
743
	/* Now LDAP other.  eDirectory or Netscape or Sunone or OpenLDAP */
744
	/*****************************************************************/
745
	/*  We First find the user based on username and filter          */
746
	/*  Then, once we find the first occurance of that person        */
747
	/*  We set seesion variables to ponit to the OU and DN of the    */
748
	/*  Person.  To later be used by ldap_get_groups.                */
749
	/*  that way we don't have to search twice.                      */
750
	/*****************************************************************/
751
	if ($ldaptype == 'ldapother'){
752
		log_error("Now Searching for {$username} in LDAP.");
753
		/* Iterate through the user containers for search */
754
		for ($i=0;$i<$containers;$i++){
755
			/* Make sure we just use the first user we find */
756
			log_error("Now searching in {$ldac_split[$i]} for {$ldapfilter}.");
757
			$search  = ldap_search($ldap,$ldac_split[$i],$ldapfilter);
758
            $info    = ldap_get_entries($ldap,$search);
759
            $matches = $info['count'];
760
            log_error("Matches Found = {$matches}.");
761
                                      
762
			if ($matches == 1){
763
				$_SESSION['ldapdn'] = $info[0]['dn'];
764
				$_SESSION['ldapou'] = $ldac_split[$i];
765
				$_SESSION['ldapon'] = "true";
766
				$ldapdn = $_SESSION['ldapdn'];
767
				$userou = $_SESSION['ldapou'];
768
				break;
769
			}
770
		}
771
		if($matches == 1){
772
			$binduser = $ldapnameattribute."=".$username.",".$userou;
773
			log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
774
		}
775
		if($matches != 1){
776
			log_error("ERROR! Either LDAP search failed, or multiple users were found");
777
			$status = local_backed($username, $passwd);
778
			ldap_close($ldap);
779
			$_SESSION['ldapon'] = "false";
780
			return $status;                         
781
		}
782
	}
783
	
784
	/* Now lets bind as the user we found */
785
	if (!($res = @ldap_bind($ldap, $binduser, $passwd))) {
786
		log_error("ERROR!  ldap_backed() could not bind to {$ldapserver} - {$username} - {$passwd}.  Defaulting to built-in local_backed().    Visit System -> User Manager -> Settings.");
787
		$status = local_backed($username, $passwd);
788
		return $status;
789
	}
790

    
791
	log_error("$binduser succesfully logged in via LDAP.");
792

    
793
	/* At this point we are bound to LDAP so the user was auth'd okay. */
794
	return true;
795
}
796

    
797
function radius_backed($username, $passwd){
798
	global $debug, $config, $debug;
799
	$ret = false;
800
	$radiusservers = $config['system']['radius']['servers'];
801

    
802
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
803
	/* Add a new servers to our instance */
804
	foreach ($radiusservers as $radsrv)
805
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
806

    
807
	if (!$rauth->start()) {
808
		$retvalue['auth_val'] = 1;
809
		$retvalue['error'] = $rauth->getError();
810
		if ($debug)
811
			printf("Radius start: %s<br>\n", $retvalue['error']);
812
	}
813

    
814
	// XXX - billm - somewhere in here we need to handle securid challenge/response
815

    
816
	/* Send request */
817
	$result = $rauth->send();
818
	if (PEAR::isError($result)) {
819
		$retvalue['auth_val'] = 1;
820
		$retvalue['error'] = $result->getMessage();
821
		if ($debug)
822
			printf("Radius send failed: %s<br>\n", $retvalue['error']);
823
	} else if ($result === true) {
824
		$retvalue['auth_val'] = 2;
825
		if ($debug)
826
			printf(gettext("Radius Auth succeeded")."<br>\n");
827
		$ret = true;
828
	} else {
829
		$retvalue['auth_val'] = 3;
830
		if ($debug)
831
			printf(gettext("Radius Auth rejected")."<br>\n");
832
	}
833

    
834
	// close OO RADIUS_AUTHENTICATION
835
	$rauth->close();
836

    
837
	return $ret;
838
}
839

    
840
function session_auth($backing) {
841
	global $g, $debug, $HTTP_SERVER_VARS, $userindex, $config;
842

    
843
	session_start();
844

    
845
	/* Validate incoming login request */
846
	if (isset($_POST['login'])) {
847
		if ($backing($_POST['usernamefld'], $_POST['passwordfld'])) {
848
			$_SESSION['Logged_In'] = "True";
849
			$_SESSION['Username'] = $_POST['usernamefld'];
850
			$_SESSION['last_access'] = time();
851
			log_error("Successful login for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
852
		} else {
853
			/* give the user a more detailed error message */
854
			if (isset($userindex[$_POST['usernamefld']])) {
855
				$_SESSION['Login_Error'] = "Username or Password incorrect";
856
				log_error("Wrong password entered for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
857
				if(isAjax()) {
858
					echo "showajaxmessage('{$_SESSION['Login_Error']}');";
859
					return;
860
				}
861
			} else {
862
				$_SESSION['Login_Error'] = "Username or Password incorrect";
863
				log_error("Attempted login for invalid user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
864
				if(isAjax()) {
865
					echo "showajaxmessage('{$_SESSION['Login_Error']}');";
866
					return;
867
				}
868
			}
869
		}
870
	}
871

    
872
	/* Show login page if they aren't logged in */
873
	if (empty($_SESSION['Logged_In'])) {
874
		/* Don't display login forms to AJAX */
875
		if (isAjax())
876
			return false;
877
		require_once("authgui.inc");
878
		display_login_form();
879
		return false;
880
	}
881

    
882
	/* If session timeout isn't set, we don't mark sessions stale */
883
	if (!isset($config['system']['webgui']['session_timeout']) ||
884
		$config['system']['webgui']['session_timeout'] == 0 ||
885
		$config['system']['webgui']['session_timeout'] == "")
886
		$_SESSION['last_access'] = time();
887
	else {
888
		/* Check for stale session */
889
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
890
			$_GET['logout'] = true;
891
			$_SESSION['Logout'] = true;
892
		} else {
893
			/* only update if it wasn't ajax */
894
			if (!isAjax())
895
				$_SESSION['last_access'] = time();
896
		}
897
	}
898

    
899
	/* obtain user object */
900
	$user = getUserEntry($_SESSION['Username']);
901

    
902
	/* user hit the logout button */
903
	if (isset($_GET['logout'])) {
904

    
905
		if ($_SESSION['Logout'])
906
			log_error("Session timed out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
907
		else
908
			log_error("User logged out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
909

    
910
		/* wipe out $_SESSION */
911
		$_SESSION = array();
912

    
913
		if (isset($_COOKIE[session_name()]))
914
			setcookie(session_name(), '', time()-42000, '/');
915

    
916
		/* and destroy it */
917
		session_destroy();
918

    
919
		$scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
920
		$scriptElms = count($scriptName);
921
		$scriptName = $scriptName[$scriptElms-1];
922

    
923
		if (isAjax())
924
			return false;
925

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

    
929
		return false;
930
	}
931

    
932
	/*
933
	 * this is for debugging purpose if you do not want to use Ajax
934
	 * to submit a HTML form. It basically diables the observation
935
	 * of the submit event and hence does not trigger Ajax.
936
	 */
937
	if ($_GET['disable_ajax']) {
938
		$_SESSION['NO_AJAX'] = "True";
939
		$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
940
		return true;
941
	}
942

    
943
	/*
944
	 * Same to re-enable Ajax.
945
	 */
946
	if ($_GET['enable_ajax']) {
947
		unset($_SESSION['NO_AJAX']);
948
		$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
949
		return true;
950
	}
951

    
952
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
953
	return true;
954
}
955

    
956
?>
(4-4/46)