Project

General

Profile

Download (26.6 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
	$passwd = crypt($passwd, $user['password']);
117

    
118
	return ($passwd == $user['password']);
119
}
120

    
121
function local_sync_accounts() {
122
	global $debug, $config;
123
	conf_mount_rw();
124

    
125
	/* remove local users to avoid uid conflicts */
126
	$fd = popen("/usr/sbin/pw usershow -a", "r");
127
	if ($fd) {
128
		while (!feof($fd)) {
129
			$line = explode(":",fgets($fd));
130
			if (!strncmp($line[0], "_", 1))
131
				continue;
132
			if ($line[2] < 2000)
133
				continue;
134
			if ($line[2] > 65000)
135
				continue;
136
			$cmd = "/usr/sbin/pw userdel {$line[2]}";
137
			if($debug)
138
				log_error("Running: {$cmd}");
139
			mwexec($cmd);
140
		}
141
		pclose($fd);
142
	}
143

    
144
	/* remove local groups to avoid gid conflicts */
145
	$gids = array();
146
	$fd = popen("/usr/sbin/pw groupshow -a", "r");
147
	if ($fd) {
148
		while (!feof($fd)) {
149
			$line = explode(":",fgets($fd));
150
			if (!strncmp($line[0], "_", 1))
151
				continue;
152
			if ($line[2] < 2000)
153
				continue;
154
			if ($line[2] > 65000)
155
				continue;
156
			$cmd = "/usr/sbin/pw groupdel {$line[2]}";
157
			if($debug)
158
				log_error("Running: {$cmd}");
159
			mwexec($cmd);
160
		}
161
		pclose($fd);
162
	}
163

    
164
	/* make sure the all group exists */
165
	$allgrp = getGroupEntryByGID(1998);
166
	local_group_set($allgrp, true);
167

    
168
	/* sync all local users */
169
	if (is_array($config['system']['user']))
170
		foreach ($config['system']['user'] as $user)
171
			local_user_set($user);
172

    
173
	/* sync all local groups */
174
	if (is_array($config['system']['group']))
175
		foreach ($config['system']['group'] as $group)
176
			local_group_set($group);
177

    
178
	conf_mount_ro();
179

    
180
}
181

    
182
function local_user_set(& $user) {
183
	global $g, $debug;
184

    
185
	$home_base = $g['platform'] == "pfSense" ? "/home" : "/var/home";
186
	if (!is_dir($home_base))
187
		mkdir($home_base, 0755);
188

    
189
	$user_uid = $user['uid'];
190
	$user_name = $user['name'];
191
	$user_home = "{$home_base}/$user_name";
192
	$user_shell = "/etc/rc.initial";
193
	$user_group = "nobody";
194

    
195
	/* configure shell type */
196
	if (!userHasPrivilege($user, "user-shell-access")) {
197
		if (!userHasPrivilege($user, "user-copy-files"))
198
			$user_shell = "/sbin/nologin";
199
		else
200
			$user_shell = "/usr/local/bin/scponly";
201
	}
202

    
203
	/* root user special handling */
204
	if ($user_uid == 0) {
205
		$cmd = "/usr/sbin/pw usermod -n root -s /bin/sh -H 0";
206
		if($debug)
207
			log_error("Running: {$cmd}");
208
		$fd = popen($cmd, "w");
209
		fwrite($fd, $user['password']);
210
		pclose($fd);
211
		$user_group = "wheel";
212
	}
213

    
214
	/* read from pw db */
215
	$fd = popen("/usr/sbin/pw usershow {$user_name} 2>&1", "r");
216
	$pwread = fgets($fd);
217
	pclose($fd);
218

    
219
	/* determine add or mod */
220
	if (!strncmp($pwread, "pw:", 3))
221
		$user_op = "useradd";
222
	else
223
		$user_op = "usermod";
224

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

    
230
	if($debug)
231
		log_error("Running: {$cmd}");
232
	$fd = popen($cmd, "r+");
233
	fwrite($fd, $user['password']);
234
	pclose($fd);
235

    
236
	/* create user directory if required */
237
	if (!is_dir($user_home))
238
		mkdir($user_home, 0700);
239
	chown($user_home, $user_name);
240
	chgrp($user_home, $user_group);
241

    
242
	/* write out ssh authorized key file */
243
	if($user['authorizedkeys']) {
244
		if (!is_dir("{$user_home}/.ssh"))
245
			mkdir("{$user_home}/.ssh", 0700);
246
		$keys = base64_decode($user['authorizedkeys']);
247
		file_put_contents("{$user_home}/.ssh/authorized_keys", $keys);
248
	}
249
}
250

    
251
function local_user_del($user) {
252
	global $debug;
253
	/* remove all memberships */
254
	local_user_get_groups($user);
255

    
256
	/* delete from pw db */
257
	$cmd = "/usr/sbin/pw userdel {$user['name']}";
258

    
259
	if($debug)
260
		log_error("Running: {$cmd}");
261
	$fd = popen($cmd, "w");
262
	fwrite($fd, $user['password']);
263
	pclose($fd);
264
}
265

    
266
function local_user_set_password(& $user, $password) {
267

    
268
	$user['password'] = crypt($password);
269
	$user['md5-hash'] = md5($password);
270

    
271
	// Converts ascii to unicode.
272
	$astr = (string) $password;
273
	$ustr = '';
274
	for ($i = 0; $i < strlen($astr); $i++) {
275
		$a = ord($astr{$i}) << 8;
276
		$ustr.= sprintf("%X", $a);
277
	}
278

    
279
	// Generate the NT-HASH from the unicode string
280
	$user['nt-hash'] = bin2hex(mhash(MHASH_MD4, $ustr));
281
}
282

    
283
function local_user_get_groups($user, $all = false) {
284
	global $debug, $config;
285

    
286
	$groups = array();
287
	if (!is_array($config['system']['group']))
288
		return $groups;
289

    
290
	foreach ($config['system']['group'] as $group)
291
		if ( $all || ( !$all && ($group['name'] != "all")))
292
			if (is_array($group['member']))
293
				if (in_array($user['uid'], $group['member']))
294
					$groups[] = $group['name'];
295

    
296
	sort($groups);
297

    
298
	return $groups;
299
	
300
}
301

    
302
function local_user_set_groups($user, $new_groups = NULL ) {
303
	global $debug, $config, $groupindex;
304

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

    
308
	$cur_groups = local_user_get_groups($user);
309
	$mod_groups = array();
310

    
311
	if (!is_array($new_groups))
312
		$new_groups = array();
313

    
314
	if (!is_array($cur_groups))
315
		$cur_groups = array();
316

    
317
	/* determine which memberships to add */
318
	foreach ($new_groups as $groupname) {
319
		if (in_array($groupname,$cur_groups))
320
			continue;
321
		$group = & $config['system']['group'][$groupindex[$groupname]];
322
		$group['member'][] = $user['uid'];
323
		$mod_groups[] = $group;
324
	}
325

    
326
	/* determine which memberships to remove */
327
	foreach ($cur_groups as $groupname) {
328
		if (in_array($groupname,$new_groups))
329
		continue;
330
		$group = & $config['system']['group'][$groupindex[$groupname]];
331
		$index = array_search($user['uid'], $group['member']);
332
		array_splice($group['member'], $index, 1);
333
		$mod_groups[] = $group;
334
	}
335

    
336
	/* sync all modified groups */
337
	foreach ($mod_groups as $group)
338
		local_group_set($group);
339
}
340

    
341
function local_group_set($group, $reset = false) {
342
	global $debug;
343

    
344
	$group_name = $group['name'];
345
	$group_gid = $group['gid'];
346
	$group_members = "''";
347
	if (!$reset && count($group['member']))
348
		$group_members = implode(",",$group['member']);
349

    
350
	/* read from group db */
351
	$fd = popen("/usr/sbin/pw groupshow {$group_name} 2>&1", "r");
352
	$pwread = fgets($fd);
353
	pclose($fd);
354

    
355
	/* determine add or mod */
356
	if (!strncmp($pwread, "pw:", 3))
357
		$group_op = "groupadd";
358
	else
359
		$group_op = "groupmod";
360

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

    
364
	if($debug)
365
		log_error("Running: {$cmd}");
366
	$fd = popen($cmd, "r+");
367
	fwrite($fd, $user['password']);
368
	pclose($fd);
369

    
370
}
371

    
372
function local_group_del($group) {
373
	global $debug;
374

    
375
	/* delete from group db */
376
	$cmd = "/usr/sbin/pw groupdel {$group['name']}";
377

    
378
	if($debug)
379
		log_error("Running: {$cmd}");
380
	$fd = popen($cmd, "w");
381
	fwrite($fd, $user['password']);
382
	pclose($fd);
383

    
384
}
385

    
386
function ldap_test_connection() {
387
	global $debug, $config, $g;
388

    
389
	$ldapserver = $config['system']['webgui']['ldapserver'];
390
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
391
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
392

    
393
	if (!($ldap = ldap_connect($ldapserver)))
394
		return false;
395

    
396
	return true;
397
}
398

    
399
function ldap_test_bind() {
400
	global $debug, $config, $g;
401

    
402
	$ldapserver = $config['system']['webgui']['ldapserver'];
403
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
404
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
405
    
406
	if (!($ldap = ldap_connect($ldapserver)))
407
		return false;
408

    
409
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
410
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
411
    
412
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
413
		return false;
414

    
415
	return true;
416
}
417

    
418
function ldap_get_user_ous($show_complete_ou=true) {
419
	global $debug, $config, $g;
420

    
421
	if(!function_exists("ldap_connect"))
422
		return;
423

    
424
	$ldapserver     = $config['system']['webgui']['ldapserver'];
425
	$ldapbindun     = $config['system']['webgui']['ldapbindun'];
426
	$ldapbindpw     = $config['system']['webgui']['ldapbindpw'];
427
	$ldapsearchbase = "{$config['system']['webgui']['ldapsearchbase']}";
428
	$ldaptype       = $config['system']['webgui']['backend'];
429

    
430
	$ldapfilter = "(ou=*)";
431
	putenv('LDAPTLS_REQCERT=never');
432
	if (!($ldap = ldap_connect($ldapserver))) {
433
		log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in local_backed()");
434
		$status = local_backed($username, $passwd);
435
		return $status;
436
	}
437

    
438
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
439
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
440

    
441
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
442
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
443
		$status = local_backed($username, $passwd);
444
		return $status;
445
	}
446

    
447
	$search = ldap_search($ldap, $ldapsearchbase, $ldapfilter);
448

    
449
	$info = ldap_get_entries($ldap, $search);
450

    
451
	$ous = array();
452

    
453
	if (is_array($info)) {
454
		foreach ($info as $inf) {
455
			if (!$show_complete_ou) {
456
				$inf_split = split(",", $inf['dn']);
457
				$ou = $inf_split[0];
458
				$ou = str_replace("OU=","", $ou);
459
			} else
460
				if($inf['dn'])
461
					$ou = $inf['dn'];
462
			if($ou)
463
				$ous[] = $ou;
464
		}
465
	}
466

    
467
	//Tack on the default Users container for AD since its non-standard
468
	if($ldaptype == 'ldap')
469
		$ous[] = "CN=Users,".$ldapsearchbase;
470

    
471
	return $ous;
472
}
473

    
474
function ldap_get_groups($username) {
475
	global $debug, $config;
476
	
477
	if(!function_exists("ldap_connect"))
478
		return;
479
	
480
	if(!$username) 
481
		return false;
482

    
483
	if(stristr($username, "@")) {
484
		$username_split=split("\@", $username);
485
		$username = $username_split[0];		
486
	}
487

    
488
	if(stristr($username, "\\")) {
489
		$username_split=split("\\", $username);
490
		$username = $username_split[0];        
491
	}    
492
	
493
	//log_error("Getting LDAP groups for {$username}.");
494
	
495
	$ldapserver         = $config['system']['webgui']['ldapserver'];
496
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
497
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
498
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
499
	$ldapfilter         = str_replace("\$username", $username, $ldapfilter);
500
	$ldapgroupattribute = $config['system']['webgui']['ldapgroupattribute'];
501
	$ldapdn             = $_SESSION['ldapdn'];
502
	 
503
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
504
	$ldapgroupattribute = strtolower($ldapgroupattribute);
505

    
506
	/* connect and see if server is up */
507
	putenv('LDAPTLS_REQCERT=never');
508
	if (!($ldap = ldap_connect($ldapserver))) {
509
		log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in local_backed()");
510
		$status = local_backed($username, $passwd);
511
		return $status;	
512
	}
513
    
514
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
515
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
516

    
517
	/* bind as user that has rights to read group attributes */
518
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
519
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
520
		$status = local_backed($username, $passwd);
521
		return $status;
522
	}
523

    
524
	/* get groups from DN found */
525
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
526
	/* since we know the DN is in $_SESSION['ldapdn'] */
527
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
528
	$search    = ldap_read($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
529
	$info      = ldap_get_entries($ldap, $search);
530

    
531
	$countem = $info["count"];	
532
	$memberof = array();
533
	
534
	if(is_array($info[0][$ldapgroupattribute])) {
535
		/* Iterate through the groups and throw them into an array */
536
		foreach ($info[0][$ldapgroupattribute] as $member) {
537
			if (stristr($member, "CN=") !== false) {
538
				$membersplit = split(",", $member);
539
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
540
			}
541
		}
542
	}
543
	
544
	/* Time to close LDAP connection */
545
	ldap_close($ldap);
546
	
547
	$groups = print_r($memberof,true);
548
	
549
	//log_error("Returning groups ".$groups." for user $username");
550
	
551
	return $memberof;
552
}
553

    
554
function ldap_backed($username, $passwd) {
555
	global $debug, $config;
556
	
557
	if(!$username) 
558
		return;
559

    
560
	if(!function_exists("ldap_connect"))
561
		return;
562

    
563
	$adbindas = $username;
564
    
565
	if(stristr($username, "@")) {
566
		$username_split=split("\@", $username);
567
		$username = $username_split[0];        
568
	}
569
	if(stristr($username, "\\")) {
570
		$username_split=split("\\", $username);
571
		$username = $username_split[0];        
572
	}
573

    
574
	$ldapserver         = $config['system']['webgui']['ldapserver'];
575
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
576
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
577
	$ldapauthcont       = $config['system']['webgui']['ldapauthcontainers'];   
578
	$ldapnameattribute  = $config['system']['webgui']['ldapnameattribute'];  
579
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
580
	$ldaptype           = $config['system']['webgui']['backend'];
581
	$ldapfilter = str_replace("\$username", $username, $ldapfilter);
582

    
583
	/* first check if there is even an LDAP server populated */ 
584
	if(!$ldapserver) {
585
		log_error("ERROR!  ldap_backed() backed selected with no LDAP authentication server defined.  Defaulting to built-in local_backed().     Visit System -> User Manager -> Settings.");
586
		$status = local_backed($username, $passwd);
587
		return $status;
588
	}
589
	
590
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
591
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
592

    
593
	/* Make sure we can connect to LDAP */
594
	putenv('LDAPTLS_REQCERT=never');
595
	if (!($ldap = ldap_connect($ldapserver))) {
596
		log_error("ERROR!  ldap_backed() could not connect to server {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed().     Visit System -> User Manager -> Settings.");
597
		$status = local_backed($username, $passwd);		
598
		return $status;	
599
	}
600
	/* ok, its up.  now, lets bind as the bind user so we can search it */
601
	if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
602
		log_error("ERROR! ldap_backed() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
603
		ldap_close($ldap);
604
		$status = local_backed($username, $passwd);
605
		return $status;
606
	}
607
	
608
	/* Get LDAP Authcontainers and split em up. */
609
	$ldac_split = split(";", $ldapauthcont);
610
	
611
	/* now count how many there are */
612
	$containers = count($ldac_split);
613
	log_error("Number of Authentication Containers to search for $username is {$containers}");
614
	
615
	/* setup the usercount so we think we havn't found anyone yet */
616
	$usercount  = 0;
617

    
618
	/******************************/
619
	/* Currently LDAP Types are   */
620
	/* LDAP = Active Directory    */
621
	/* LDAPOTHER = eDir/Openldap  */
622
	/******************************/      
623
        
624
	/*****************************************************************/
625
	/* Now Active Directory We keep this seperate for future addons. */
626
	/*****************************************************************/
627
	/* Now LDAP other.  eDirectory or Netscape or Sunone or OpenLDAP */
628
	/*****************************************************************/
629
	/*  We First find the user based on username and filter          */
630
	/*  Then, once we find the first occurance of that person        */
631
	/*  We set seesion variables to ponit to the OU and DN of the    */
632
	/*  Person.  To later be used by ldap_get_groups.                */
633
	/*  that way we don't have to search twice.                      */
634
	/*****************************************************************/
635
	if ($ldaptype == 'ldap'){
636
		log_error("Now Searching for {$username} in Active directory.");
637
		/* Iterate through the user containers for search */
638
		for ($i=0;$i<$containers;$i++){
639
			/* Make sure we just use the first user we find */
640
			log_error("Now Searching in {$ldac_split[$i]} for {$ldapfilter}.");
641
			$search	 = ldap_search($ldap,$ldac_split[$i],$ldapfilter);
642
			$info	 = ldap_get_entries($ldap,$search);
643
			$matches = $info['count'];
644
			log_error("Matches Found = {$matches}");
645
			if ($matches == 1){
646
				$_SESSION['ldapdn'] = $info[0]['dn'];
647
				$_SESSION['ldapou'] = $ldac_split[$i];
648
				$_SESSION['ldapon'] = "true";
649
				$ldapdn = $_SESSION['ldapdn'];
650
				$userou = $_SESSION['ldapou'];
651
				break;
652
			}
653
		}
654

    
655
		if ($matches == 1){
656
			$binduser = $adbindas;
657
			log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
658
		}
659
		if ($matches != 1){
660
			log_error("ERROR! Either LDAP search failed, or multiple users were found");
661
			$status = local_backed($username, $passwd);
662
			$_SESSION['ldapon'] = "false";
663
			ldap_close($ldap);
664
			return $status;                         
665
		}
666
	}
667

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

    
717
	log_error("$binduser succesfully logged in via LDAP.");
718

    
719
	/* At this point we are bound to LDAP so the user was auth'd okay. */
720
	return true;
721
}
722

    
723
function radius_backed($username, $passwd){
724
	global $debug, $config, $debug;
725
	$ret = false;
726
	$radiusservers = $config['system']['radius']['servers'];
727

    
728
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
729
	/* Add a new servers to our instance */
730
	foreach ($radiusservers as $radsrv)
731
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
732

    
733
	if (!$rauth->start()) {
734
		$retvalue['auth_val'] = 1;
735
		$retvalue['error'] = $rauth->getError();
736
		if ($debug)
737
			printf("Radius start: %s<br>\n", $retvalue['error']);
738
	}
739

    
740
	// XXX - billm - somewhere in here we need to handle securid challenge/response
741

    
742
	/* Send request */
743
	$result = $rauth->send();
744
	if (PEAR::isError($result)) {
745
		$retvalue['auth_val'] = 1;
746
		$retvalue['error'] = $result->getMessage();
747
		if ($debug)
748
			printf("Radius send failed: %s<br>\n", $retvalue['error']);
749
	} else if ($result === true) {
750
		$retvalue['auth_val'] = 2;
751
		if ($debug)
752
			printf(gettext("Radius Auth succeeded")."<br>\n");
753
		$ret = true;
754
	} else {
755
		$retvalue['auth_val'] = 3;
756
		if ($debug)
757
			printf(gettext("Radius Auth rejected")."<br>\n");
758
	}
759

    
760
	// close OO RADIUS_AUTHENTICATION
761
	$rauth->close();
762

    
763
	return $ret;
764
}
765

    
766
function session_auth($backing) {
767
	global $g, $debug, $HTTP_SERVER_VARS, $userindex, $config;
768

    
769
	session_start();
770

    
771
	/* Validate incoming login request */
772
	if (isset($_POST['login'])) {
773
		if ($backing($_POST['usernamefld'], $_POST['passwordfld'])) {
774
			$_SESSION['Logged_In'] = "True";
775
			$_SESSION['Username'] = $_POST['usernamefld'];
776
			$_SESSION['last_access'] = time();
777
			log_error("Successful login for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
778
		} else {
779
			/* give the user a more detailed error message */
780
			if (isset($userindex[$_POST['usernamefld']])) {
781
				$_SESSION['Login_Error'] = "Username or Password incorrect";
782
				log_error("Wrong password entered for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
783
				if(isAjax()) {
784
					echo "showajaxmessage('{$_SESSION['Login_Error']}');";
785
					return;
786
				}
787
			} else {
788
				$_SESSION['Login_Error'] = "Username or Password incorrect";
789
				log_error("Attempted login for invalid user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
790
				if(isAjax()) {
791
					echo "showajaxmessage('{$_SESSION['Login_Error']}');";
792
					return;
793
				}
794
			}
795
		}
796
	}
797

    
798
	/* Show login page if they aren't logged in */
799
	if (empty($_SESSION['Logged_In'])) {
800
		/* Don't display login forms to AJAX */
801
		if (isAjax())
802
			return false;
803
		require_once("authgui.inc");
804
		display_login_form();
805
		return false;
806
	}
807

    
808
	/* If session timeout isn't set, we don't mark sessions stale */
809
	if (!isset($config['system']['webgui']['session_timeout']) ||
810
		$config['system']['webgui']['session_timeout'] == 0 ||
811
		$config['system']['webgui']['session_timeout'] == "")
812
		$_SESSION['last_access'] = time();
813
	else {
814
		/* Check for stale session */
815
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
816
			$_GET['logout'] = true;
817
			$_SESSION['Logout'] = true;
818
		} else {
819
			/* only update if it wasn't ajax */
820
			if (!isAjax())
821
				$_SESSION['last_access'] = time();
822
		}
823
	}
824

    
825
	/* obtain user object */
826
	$user = getUserEntry($_SESSION['Username']);
827

    
828
	/* user hit the logout button */
829
	if (isset($_GET['logout'])) {
830

    
831
		if ($_SESSION['Logout'])
832
			log_error("Session timed out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
833
		else
834
			log_error("User logged out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
835

    
836
		/* wipe out $_SESSION */
837
		$_SESSION = array();
838

    
839
		if (isset($_COOKIE[session_name()]))
840
			setcookie(session_name(), '', time()-42000, '/');
841

    
842
		/* and destroy it */
843
		session_destroy();
844

    
845
		$scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
846
		$scriptElms = count($scriptName);
847
		$scriptName = $scriptName[$scriptElms-1];
848

    
849
		if (isAjax())
850
			return false;
851

    
852
		/* redirect to page the user is on, it'll prompt them to login again */
853
		pfSenseHeader($scriptName);
854

    
855
		return false;
856
	}
857

    
858
	/*
859
	 * this is for debugging purpose if you do not want to use Ajax
860
	 * to submit a HTML form. It basically diables the observation
861
	 * of the submit event and hence does not trigger Ajax.
862
	 */
863
	if ($_GET['disable_ajax']) {
864
		$_SESSION['NO_AJAX'] = "True";
865
		$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
866
		return true;
867
	}
868

    
869
	/*
870
	 * Same to re-enable Ajax.
871
	 */
872
	if ($_GET['enable_ajax']) {
873
		unset($_SESSION['NO_AJAX']);
874
		$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
875
		return true;
876
	}
877

    
878
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
879
	return true;
880
}
881

    
882
?>
(3-3/37)