Project

General

Profile

Download (26.9 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
*/
39

    
40
/*
41
 * NOTE : Portions of the mschapv2 support was based on the BSD licensed CHAP.php
42
 * file courtesy of Michael Retterklieber.
43
 */
44

    
45
require_once("functions.inc");
46

    
47
$groupindex = index_groups();
48
$userindex = index_users();
49

    
50
function index_groups() {
51
	global $g, $debug, $config, $groupindex;
52

    
53
	$groupindex = array();
54

    
55
	if (isset($config['system']['group'])) {
56
		$i = 0;
57
		foreach($config['system']['group'] as $groupent) {
58
			$groupindex[$groupent['name']] = $i;
59
			$i++;
60
		}
61
	}
62

    
63
	return ($groupindex);
64
}
65

    
66
function index_users() {
67
	global $g, $debug, $config;
68

    
69
	if (isset($config['system']['user'])) {
70
		$i = 0;
71
		foreach($config['system']['user'] as $userent) {
72
			$userindex[$userent['name']] = $i;
73
			$i++;
74
		}
75
	}
76

    
77
	return ($userindex);
78
}
79

    
80
function & getUserEntry($name) {
81
	global $debug, $config, $userindex;
82
	if (isset($userindex[$name]))
83
		return $config['system']['user'][$userindex[$name]];
84
}
85

    
86
function & getUserEntryByUID($uid) {
87
	global $debug, $config;
88
	foreach ($config['system']['user'] as & $user)
89
		if ($user['uid'] == $uid)
90
			return $user;
91

    
92
	return false;
93
}
94

    
95
function & getGroupEntry($name) {
96
	global $debug, $config, $groupindex;
97
	if (isset($groupindex[$name]))
98
		return $config['system']['group'][$groupindex[$name]];
99
}
100

    
101
function & getGroupEntryByGID($gid) {
102
	global $debug, $config;
103
	foreach ($config['system']['group'] as & $group)
104
		if ($group['gid'] == $gid)
105
			return $group;
106

    
107
	return false;
108
}
109

    
110
function local_backed($username, $passwd) {
111

    
112
	$user = getUserEntry($username);
113
	if (!$user)
114
		return false;
115

    
116
	if ($user['password'])
117
	{
118
		$passwd = crypt($passwd, $user['password']);
119
		if ($passwd == $user['password'])
120
			return true;
121
	}
122

    
123
	if ($user['md5-hash'])
124
	{
125
		$passwd = md5($passwd);
126
		if ($passwd == $user['md5-hash'])
127
			return true;
128
	}
129

    
130
	return false;
131
}
132

    
133
function local_sync_accounts() {
134
	global $debug, $config;
135
	conf_mount_rw();
136

    
137
	/* remove local users to avoid uid conflicts */
138
	$fd = popen("/usr/sbin/pw usershow -a", "r");
139
	if ($fd) {
140
		while (!feof($fd)) {
141
			$line = explode(":",fgets($fd));
142
			if (!strncmp($line[0], "_", 1))
143
				continue;
144
			if ($line[2] < 2000)
145
				continue;
146
			if ($line[2] > 65000)
147
				continue;
148
			$cmd = "/usr/sbin/pw userdel {$line[2]}";
149
			if($debug)
150
				log_error("Running: {$cmd}");
151
			mwexec($cmd);
152
		}
153
		pclose($fd);
154
	}
155

    
156
	/* remove local groups to avoid gid conflicts */
157
	$gids = array();
158
	$fd = popen("/usr/sbin/pw groupshow -a", "r");
159
	if ($fd) {
160
		while (!feof($fd)) {
161
			$line = explode(":",fgets($fd));
162
			if (!strncmp($line[0], "_", 1))
163
				continue;
164
			if ($line[2] < 2000)
165
				continue;
166
			if ($line[2] > 65000)
167
				continue;
168
			$cmd = "/usr/sbin/pw groupdel {$line[2]}";
169
			if($debug)
170
				log_error("Running: {$cmd}");
171
			mwexec($cmd);
172
		}
173
		pclose($fd);
174
	}
175

    
176
	/* make sure the all group exists */
177
	$allgrp = getGroupEntryByGID(1998);
178
	local_group_set($allgrp, true);
179

    
180
	/* sync all local users */
181
	if (is_array($config['system']['user']))
182
		foreach ($config['system']['user'] as $user)
183
			local_user_set($user);
184

    
185
	/* sync all local groups */
186
	if (is_array($config['system']['group']))
187
		foreach ($config['system']['group'] as $group)
188
			local_group_set($group);
189

    
190
	conf_mount_ro();
191

    
192
}
193

    
194
function local_user_set(& $user) {
195
	global $g, $debug;
196

    
197
	$home_base = "/home/";	
198
	$user_uid = $user['uid'];
199
	$user_name = $user['name'];
200
	$user_home = "{$home_base}/$user_name";
201
	$user_shell = "/etc/rc.initial";
202
	$user_group = "nobody";
203

    
204
	// Ensure $home_base exists and is writable
205
	if (!is_dir($home_base)) 
206
		mkdir($home_base, 0755);
207

    
208
	// Ensure $user_home exists and is writable
209
	if(!is_dir($user_home)) 
210
		mkdir($user_home, 0755);
211

    
212
	/* configure shell type */
213
	if (!userHasPrivilege($user, "user-shell-access")) {
214
		if (!userHasPrivilege($user, "user-copy-files"))
215
			$user_shell = "/sbin/nologin";
216
		else
217
			$user_shell = "/usr/local/bin/scponly";
218
	}
219

    
220
	/* root user special handling */
221
	if ($user_uid == 0) {
222
		$cmd = "/usr/sbin/pw usermod -q -n root -s /bin/sh -H 0";
223
		if($debug)
224
			log_error("Running: {$cmd}");
225
		$fd = popen($cmd, "w");
226
		fwrite($fd, $user['password']);
227
		pclose($fd);
228
		$user_group = "wheel";
229
	}
230

    
231
	/* read from pw db */
232
	$fd = popen("/usr/sbin/pw usershow {$user_name} 2>&1", "r");
233
	$pwread = fgets($fd);
234
	pclose($fd);
235

    
236
	/* determine add or mod */
237
	if (!strncmp($pwread, "pw:", 3))
238
		$user_op = "useradd";
239
	else
240
		$user_op = "usermod";
241

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

    
247
	if($debug)
248
		log_error("Running: {$cmd}");
249
	$fd = popen($cmd, "w");
250
	fwrite($fd, $user['password']);
251
	pclose($fd);
252

    
253
	/* create user directory if required */
254
	if (!is_dir($user_home)) {
255
		mkdir($user_home, 0700);
256
		mwexec("cp /root/.* {$home_base}/");
257
	}
258
	chown($user_home, $user_name);
259
	chgrp($user_home, $user_group);
260

    
261
	/* write out ssh authorized key file */
262
	if($user['authorizedkeys']) {
263
		if (!is_dir("{$user_home}/.ssh"))
264
			mkdir("{$user_home}/.ssh", 0700);
265
		$keys = base64_decode($user['authorizedkeys']);
266
		file_put_contents("{$user_home}/.ssh/authorized_keys", $keys);
267
	}
268
}
269

    
270
function local_user_del($user) {
271
	global $debug;
272
	/* remove all memberships */
273
	local_user_get_groups($user);
274

    
275
	/* delete from pw db */
276
	$cmd = "/usr/sbin/pw userdel {$user['name']}";
277

    
278
	if($debug)
279
		log_error("Running: {$cmd}");
280
	$fd = popen($cmd, "w");
281
	fwrite($fd, $user['password']);
282
	pclose($fd);
283
}
284

    
285
function local_user_set_password(& $user, $password) {
286

    
287
	$user['password'] = crypt($password);
288
	$user['md5-hash'] = md5($password);
289

    
290
	// Converts ascii to unicode.
291
	$astr = (string) $password;
292
	$ustr = '';
293
	for ($i = 0; $i < strlen($astr); $i++) {
294
		$a = ord($astr{$i}) << 8;
295
		$ustr.= sprintf("%X", $a);
296
	}
297

    
298
	// Generate the NT-HASH from the unicode string
299
	$user['nt-hash'] = bin2hex(mhash(MHASH_MD4, $ustr));
300
}
301

    
302
function local_user_get_groups($user, $all = false) {
303
	global $debug, $config;
304

    
305
	$groups = array();
306
	if (!is_array($config['system']['group']))
307
		return $groups;
308

    
309
	foreach ($config['system']['group'] as $group)
310
		if ( $all || ( !$all && ($group['name'] != "all")))
311
			if (is_array($group['member']))
312
				if (in_array($user['uid'], $group['member']))
313
					$groups[] = $group['name'];
314

    
315
	sort($groups);
316

    
317
	return $groups;
318
	
319
}
320

    
321
function local_user_set_groups($user, $new_groups = NULL ) {
322
	global $debug, $config, $groupindex;
323

    
324
	if (!is_array($config['system']['group']))
325
		return;
326

    
327
	$cur_groups = local_user_get_groups($user);
328
	$mod_groups = array();
329

    
330
	if (!is_array($new_groups))
331
		$new_groups = array();
332

    
333
	if (!is_array($cur_groups))
334
		$cur_groups = array();
335

    
336
	/* determine which memberships to add */
337
	foreach ($new_groups as $groupname) {
338
		if (in_array($groupname,$cur_groups))
339
			continue;
340
		$group = & $config['system']['group'][$groupindex[$groupname]];
341
		$group['member'][] = $user['uid'];
342
		$mod_groups[] = $group;
343
	}
344

    
345
	/* determine which memberships to remove */
346
	foreach ($cur_groups as $groupname) {
347
		if (in_array($groupname,$new_groups))
348
		continue;
349
		$group = & $config['system']['group'][$groupindex[$groupname]];
350
		$index = array_search($user['uid'], $group['member']);
351
		array_splice($group['member'], $index, 1);
352
		$mod_groups[] = $group;
353
	}
354

    
355
	/* sync all modified groups */
356
	foreach ($mod_groups as $group)
357
		local_group_set($group);
358
}
359

    
360
function local_group_set($group, $reset = false) {
361
	global $debug;
362

    
363
	$group_name = $group['name'];
364
	$group_gid = $group['gid'];
365
	$group_members = "''";
366
	if (!$reset && count($group['member']))
367
		$group_members = implode(",",$group['member']);
368

    
369
	/* read from group db */
370
	$fd = popen("/usr/sbin/pw groupshow {$group_name} 2>&1", "r");
371
	$pwread = fgets($fd);
372
	pclose($fd);
373

    
374
	/* determine add or mod */
375
	if (!strncmp($pwread, "pw:", 3))
376
		$group_op = "groupadd";
377
	else
378
		$group_op = "groupmod";
379

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

    
383
	if($debug)
384
		log_error("Running: {$cmd}");
385
	$fd = popen($cmd, "w");
386
	fwrite($fd, $user['password']);
387
	pclose($fd);
388

    
389
}
390

    
391
function local_group_del($group) {
392
	global $debug;
393

    
394
	/* delete from group db */
395
	$cmd = "/usr/sbin/pw groupdel {$group['name']}";
396

    
397
	if($debug)
398
		log_error("Running: {$cmd}");
399
	$fd = popen($cmd, "w");
400
	fwrite($fd, $user['password']);
401
	pclose($fd);
402

    
403
}
404

    
405
function ldap_test_connection() {
406
	global $debug, $config, $g;
407

    
408
	$ldapserver = $config['system']['webgui']['ldapserver'];
409
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
410
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
411

    
412
	if (!($ldap = ldap_connect($ldapserver)))
413
		return false;
414

    
415
	return true;
416
}
417

    
418
function ldap_test_bind() {
419
	global $debug, $config, $g;
420

    
421
	$ldapserver = $config['system']['webgui']['ldapserver'];
422
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
423
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
424
    
425
	if (!($ldap = ldap_connect($ldapserver)))
426
		return false;
427

    
428
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
429
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
430
    
431
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
432
		return false;
433

    
434
	return true;
435
}
436

    
437
function ldap_get_user_ous($show_complete_ou=true) {
438
	global $debug, $config, $g;
439

    
440
	if(!function_exists("ldap_connect"))
441
		return;
442

    
443
	$ldapserver     = $config['system']['webgui']['ldapserver'];
444
	$ldapbindun     = $config['system']['webgui']['ldapbindun'];
445
	$ldapbindpw     = $config['system']['webgui']['ldapbindpw'];
446
	$ldapsearchbase = "{$config['system']['webgui']['ldapsearchbase']}";
447
	$ldaptype       = $config['system']['webgui']['backend'];
448

    
449
	$ldapfilter = "(ou=*)";
450
	putenv('LDAPTLS_REQCERT=never');
451
	if (!($ldap = ldap_connect($ldapserver))) {
452
		log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in local_backed()");
453
		$status = local_backed($username, $passwd);
454
		return $status;
455
	}
456

    
457
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
458
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
459

    
460
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
461
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
462
		$status = local_backed($username, $passwd);
463
		return $status;
464
	}
465

    
466
	$search = ldap_search($ldap, $ldapsearchbase, $ldapfilter);
467

    
468
	$info = ldap_get_entries($ldap, $search);
469

    
470
	$ous = array();
471

    
472
	if (is_array($info)) {
473
		foreach ($info as $inf) {
474
			if (!$show_complete_ou) {
475
				$inf_split = split(",", $inf['dn']);
476
				$ou = $inf_split[0];
477
				$ou = str_replace("OU=","", $ou);
478
			} else
479
				if($inf['dn'])
480
					$ou = $inf['dn'];
481
			if($ou)
482
				$ous[] = $ou;
483
		}
484
	}
485

    
486
	//Tack on the default Users container for AD since its non-standard
487
	if($ldaptype == 'ldap')
488
		$ous[] = "CN=Users,".$ldapsearchbase;
489

    
490
	return $ous;
491
}
492

    
493
function ldap_get_groups($username) {
494
	global $debug, $config;
495
	
496
	if(!function_exists("ldap_connect"))
497
		return;
498
	
499
	if(!$username) 
500
		return false;
501

    
502
	if(stristr($username, "@")) {
503
		$username_split=split("\@", $username);
504
		$username = $username_split[0];		
505
	}
506

    
507
	if(stristr($username, "\\")) {
508
		$username_split=split("\\", $username);
509
		$username = $username_split[0];        
510
	}    
511
	
512
	//log_error("Getting LDAP groups for {$username}.");
513
	
514
	$ldapserver         = $config['system']['webgui']['ldapserver'];
515
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
516
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
517
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
518
	$ldapfilter         = str_replace("\$username", $username, $ldapfilter);
519
	$ldapgroupattribute = $config['system']['webgui']['ldapgroupattribute'];
520
	$ldapdn             = $_SESSION['ldapdn'];
521
	 
522
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
523
	$ldapgroupattribute = strtolower($ldapgroupattribute);
524

    
525
	/* connect and see if server is up */
526
	putenv('LDAPTLS_REQCERT=never');
527
	if (!($ldap = ldap_connect($ldapserver))) {
528
		log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in local_backed()");
529
		$status = local_backed($username, $passwd);
530
		return $status;	
531
	}
532
    
533
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
534
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
535

    
536
	/* bind as user that has rights to read group attributes */
537
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
538
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
539
		$status = local_backed($username, $passwd);
540
		return $status;
541
	}
542

    
543
	/* get groups from DN found */
544
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
545
	/* since we know the DN is in $_SESSION['ldapdn'] */
546
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
547
	$search    = ldap_read($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
548
	$info      = ldap_get_entries($ldap, $search);
549

    
550
	$countem = $info["count"];	
551
	$memberof = array();
552
	
553
	if(is_array($info[0][$ldapgroupattribute])) {
554
		/* Iterate through the groups and throw them into an array */
555
		foreach ($info[0][$ldapgroupattribute] as $member) {
556
			if (stristr($member, "CN=") !== false) {
557
				$membersplit = split(",", $member);
558
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
559
			}
560
		}
561
	}
562
	
563
	/* Time to close LDAP connection */
564
	ldap_close($ldap);
565
	
566
	$groups = print_r($memberof,true);
567
	
568
	//log_error("Returning groups ".$groups." for user $username");
569
	
570
	return $memberof;
571
}
572

    
573
function ldap_backed($username, $passwd) {
574
	global $debug, $config;
575
	
576
	if(!$username) 
577
		return;
578

    
579
	if(!function_exists("ldap_connect"))
580
		return;
581

    
582
	$adbindas = $username;
583
    
584
	if(stristr($username, "@")) {
585
		$username_split=split("\@", $username);
586
		$username = $username_split[0];        
587
	}
588
	if(stristr($username, "\\")) {
589
		$username_split=split("\\", $username);
590
		$username = $username_split[0];        
591
	}
592

    
593
	$ldapserver         = $config['system']['webgui']['ldapserver'];
594
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
595
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
596
	$ldapauthcont       = $config['system']['webgui']['ldapauthcontainers'];   
597
	$ldapnameattribute  = $config['system']['webgui']['ldapnameattribute'];  
598
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
599
	$ldaptype           = $config['system']['webgui']['backend'];
600
	$ldapfilter = str_replace("\$username", $username, $ldapfilter);
601

    
602
	/* first check if there is even an LDAP server populated */ 
603
	if(!$ldapserver) {
604
		log_error("ERROR!  ldap_backed() backed selected with no LDAP authentication server defined.  Defaulting to built-in local_backed().     Visit System -> User Manager -> Settings.");
605
		$status = local_backed($username, $passwd);
606
		return $status;
607
	}
608
	
609
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
610
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
611

    
612
	/* Make sure we can connect to LDAP */
613
	putenv('LDAPTLS_REQCERT=never');
614
	if (!($ldap = ldap_connect($ldapserver))) {
615
		log_error("ERROR!  ldap_backed() could not connect to server {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed().     Visit System -> User Manager -> Settings.");
616
		$status = local_backed($username, $passwd);		
617
		return $status;	
618
	}
619
	/* ok, its up.  now, lets bind as the bind user so we can search it */
620
	if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
621
		log_error("ERROR! ldap_backed() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
622
		ldap_close($ldap);
623
		$status = local_backed($username, $passwd);
624
		return $status;
625
	}
626
	
627
	/* Get LDAP Authcontainers and split em up. */
628
	$ldac_split = split(";", $ldapauthcont);
629
	
630
	/* now count how many there are */
631
	$containers = count($ldac_split);
632
	log_error("Number of Authentication Containers to search for $username is {$containers}");
633
	
634
	/* setup the usercount so we think we havn't found anyone yet */
635
	$usercount  = 0;
636

    
637
	/******************************/
638
	/* Currently LDAP Types are   */
639
	/* LDAP = Active Directory    */
640
	/* LDAPOTHER = eDir/Openldap  */
641
	/******************************/      
642
        
643
	/*****************************************************************/
644
	/* Now Active Directory We keep this seperate for future addons. */
645
	/*****************************************************************/
646
	/* Now LDAP other.  eDirectory or Netscape or Sunone or OpenLDAP */
647
	/*****************************************************************/
648
	/*  We First find the user based on username and filter          */
649
	/*  Then, once we find the first occurance of that person        */
650
	/*  We set seesion variables to ponit to the OU and DN of the    */
651
	/*  Person.  To later be used by ldap_get_groups.                */
652
	/*  that way we don't have to search twice.                      */
653
	/*****************************************************************/
654
	if ($ldaptype == 'ldap'){
655
		log_error("Now Searching for {$username} in Active directory.");
656
		/* Iterate through the user containers for search */
657
		for ($i=0;$i<$containers;$i++){
658
			/* Make sure we just use the first user we find */
659
			log_error("Now Searching in {$ldac_split[$i]} for {$ldapfilter}.");
660
			$search	 = ldap_search($ldap,$ldac_split[$i],$ldapfilter);
661
			$info	 = ldap_get_entries($ldap,$search);
662
			$matches = $info['count'];
663
			log_error("Matches Found = {$matches}");
664
			if ($matches == 1){
665
				$_SESSION['ldapdn'] = $info[0]['dn'];
666
				$_SESSION['ldapou'] = $ldac_split[$i];
667
				$_SESSION['ldapon'] = "true";
668
				$ldapdn = $_SESSION['ldapdn'];
669
				$userou = $_SESSION['ldapou'];
670
				break;
671
			}
672
		}
673

    
674
		if ($matches == 1){
675
			$binduser = $adbindas;
676
			log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
677
		}
678
		if ($matches != 1){
679
			log_error("ERROR! Either LDAP search failed, or multiple users were found");
680
			$status = local_backed($username, $passwd);
681
			$_SESSION['ldapon'] = "false";
682
			ldap_close($ldap);
683
			return $status;                         
684
		}
685
	}
686

    
687
	/*****************************************************************/
688
	/* Now LDAP other.  eDirectory or Netscape or Sunone or OpenLDAP */
689
	/*****************************************************************/
690
	/*  We First find the user based on username and filter          */
691
	/*  Then, once we find the first occurance of that person        */
692
	/*  We set seesion variables to ponit to the OU and DN of the    */
693
	/*  Person.  To later be used by ldap_get_groups.                */
694
	/*  that way we don't have to search twice.                      */
695
	/*****************************************************************/
696
	if ($ldaptype == 'ldapother'){
697
		log_error("Now Searching for {$username} in LDAP.");
698
		/* Iterate through the user containers for search */
699
		for ($i=0;$i<$containers;$i++){
700
			/* Make sure we just use the first user we find */
701
			log_error("Now searching in {$ldac_split[$i]} for {$ldapfilter}.");
702
			$search  = ldap_search($ldap,$ldac_split[$i],$ldapfilter);
703
            $info    = ldap_get_entries($ldap,$search);
704
            $matches = $info['count'];
705
            log_error("Matches Found = {$matches}.");
706
                                      
707
			if ($matches == 1){
708
				$_SESSION['ldapdn'] = $info[0]['dn'];
709
				$_SESSION['ldapou'] = $ldac_split[$i];
710
				$_SESSION['ldapon'] = "true";
711
				$ldapdn = $_SESSION['ldapdn'];
712
				$userou = $_SESSION['ldapou'];
713
				break;
714
			}
715
		}
716
		if($matches == 1){
717
			$binduser = $ldapnameattribute."=".$username.",".$userou;
718
			log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
719
		}
720
		if($matches != 1){
721
			log_error("ERROR! Either LDAP search failed, or multiple users were found");
722
			$status = local_backed($username, $passwd);
723
			ldap_close($ldap);
724
			$_SESSION['ldapon'] = "false";
725
			return $status;                         
726
		}
727
	}
728
	
729
	/* Now lets bind as the user we found */
730
	if (!($res = @ldap_bind($ldap, $binduser, $passwd))) {
731
		log_error("ERROR!  ldap_backed() could not bind to {$ldapserver} - {$username} - {$passwd}.  Defaulting to built-in local_backed().    Visit System -> User Manager -> Settings.");
732
		$status = local_backed($username, $passwd);
733
		return $status;
734
	}
735

    
736
	log_error("$binduser succesfully logged in via LDAP.");
737

    
738
	/* At this point we are bound to LDAP so the user was auth'd okay. */
739
	return true;
740
}
741

    
742
function radius_backed($username, $passwd){
743
	global $debug, $config, $debug;
744
	$ret = false;
745
	$radiusservers = $config['system']['radius']['servers'];
746

    
747
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
748
	/* Add a new servers to our instance */
749
	foreach ($radiusservers as $radsrv)
750
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
751

    
752
	if (!$rauth->start()) {
753
		$retvalue['auth_val'] = 1;
754
		$retvalue['error'] = $rauth->getError();
755
		if ($debug)
756
			printf("Radius start: %s<br>\n", $retvalue['error']);
757
	}
758

    
759
	// XXX - billm - somewhere in here we need to handle securid challenge/response
760

    
761
	/* Send request */
762
	$result = $rauth->send();
763
	if (PEAR::isError($result)) {
764
		$retvalue['auth_val'] = 1;
765
		$retvalue['error'] = $result->getMessage();
766
		if ($debug)
767
			printf("Radius send failed: %s<br>\n", $retvalue['error']);
768
	} else if ($result === true) {
769
		$retvalue['auth_val'] = 2;
770
		if ($debug)
771
			printf(gettext("Radius Auth succeeded")."<br>\n");
772
		$ret = true;
773
	} else {
774
		$retvalue['auth_val'] = 3;
775
		if ($debug)
776
			printf(gettext("Radius Auth rejected")."<br>\n");
777
	}
778

    
779
	// close OO RADIUS_AUTHENTICATION
780
	$rauth->close();
781

    
782
	return $ret;
783
}
784

    
785
function session_auth($backing) {
786
	global $g, $debug, $HTTP_SERVER_VARS, $userindex, $config;
787

    
788
	session_start();
789

    
790
	/* Validate incoming login request */
791
	if (isset($_POST['login'])) {
792
		if ($backing($_POST['usernamefld'], $_POST['passwordfld'])) {
793
			$_SESSION['Logged_In'] = "True";
794
			$_SESSION['Username'] = $_POST['usernamefld'];
795
			$_SESSION['last_access'] = time();
796
			log_error("Successful login for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
797
		} else {
798
			/* give the user a more detailed error message */
799
			if (isset($userindex[$_POST['usernamefld']])) {
800
				$_SESSION['Login_Error'] = "Username or Password incorrect";
801
				log_error("Wrong password entered for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
802
				if(isAjax()) {
803
					echo "showajaxmessage('{$_SESSION['Login_Error']}');";
804
					return;
805
				}
806
			} else {
807
				$_SESSION['Login_Error'] = "Username or Password incorrect";
808
				log_error("Attempted login for invalid user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
809
				if(isAjax()) {
810
					echo "showajaxmessage('{$_SESSION['Login_Error']}');";
811
					return;
812
				}
813
			}
814
		}
815
	}
816

    
817
	/* Show login page if they aren't logged in */
818
	if (empty($_SESSION['Logged_In'])) {
819
		/* Don't display login forms to AJAX */
820
		if (isAjax())
821
			return false;
822
		require_once("authgui.inc");
823
		display_login_form();
824
		return false;
825
	}
826

    
827
	/* If session timeout isn't set, we don't mark sessions stale */
828
	if (!isset($config['system']['webgui']['session_timeout']) ||
829
		$config['system']['webgui']['session_timeout'] == 0 ||
830
		$config['system']['webgui']['session_timeout'] == "")
831
		$_SESSION['last_access'] = time();
832
	else {
833
		/* Check for stale session */
834
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
835
			$_GET['logout'] = true;
836
			$_SESSION['Logout'] = true;
837
		} else {
838
			/* only update if it wasn't ajax */
839
			if (!isAjax())
840
				$_SESSION['last_access'] = time();
841
		}
842
	}
843

    
844
	/* obtain user object */
845
	$user = getUserEntry($_SESSION['Username']);
846

    
847
	/* user hit the logout button */
848
	if (isset($_GET['logout'])) {
849

    
850
		if ($_SESSION['Logout'])
851
			log_error("Session timed out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
852
		else
853
			log_error("User logged out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
854

    
855
		/* wipe out $_SESSION */
856
		$_SESSION = array();
857

    
858
		if (isset($_COOKIE[session_name()]))
859
			setcookie(session_name(), '', time()-42000, '/');
860

    
861
		/* and destroy it */
862
		session_destroy();
863

    
864
		$scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
865
		$scriptElms = count($scriptName);
866
		$scriptName = $scriptName[$scriptElms-1];
867

    
868
		if (isAjax())
869
			return false;
870

    
871
		/* redirect to page the user is on, it'll prompt them to login again */
872
		pfSenseHeader($scriptName);
873

    
874
		return false;
875
	}
876

    
877
	/*
878
	 * this is for debugging purpose if you do not want to use Ajax
879
	 * to submit a HTML form. It basically diables the observation
880
	 * of the submit event and hence does not trigger Ajax.
881
	 */
882
	if ($_GET['disable_ajax']) {
883
		$_SESSION['NO_AJAX'] = "True";
884
		$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
885
		return true;
886
	}
887

    
888
	/*
889
	 * Same to re-enable Ajax.
890
	 */
891
	if ($_GET['enable_ajax']) {
892
		unset($_SESSION['NO_AJAX']);
893
		$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
894
		return true;
895
	}
896

    
897
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
898
	return true;
899
}
900

    
901
?>
(4-4/40)