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

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

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

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

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

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

    
178
function local_user_set(& $user) {
179
	global $g, $debug;
180

    
181
	$home_base = $g['platform'] == "pfSense" ? "/home" : "/var/home";
182
	if (!is_dir($home_base))
183
		mkdir($home_base, 0755);
184

    
185
	$user_uid = $user['uid'];
186
	$user_name = $user['name'];
187
	$user_home = "{$home_base}/$user_name";
188
	$user_shell = "/etc/rc.initial";
189
	$user_group = "nobody";
190

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

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

    
210
	/* read from pw db */
211
	$fd = popen("/usr/sbin/pw usershow {$user_name} 2>&1", "r");
212
	$pwread = fgets($fd);
213
	pclose($fd);
214

    
215
	/* determine add or mod */
216
	if (!strncmp($pwread, "pw:", 3))
217
		$user_op = "useradd";
218
	else
219
		$user_op = "usermod";
220

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

    
226
	if($debug)
227
		log_error("Running: {$cmd}");
228
	$fd = popen($cmd, "r+");
229
	fwrite($fd, $user['password']);
230
	pclose($fd);
231

    
232
	/* create user directory if required */
233
	if (!is_dir($user_home))
234
		mkdir($user_home, 0700);
235
	chown($user_home, $user_name);
236
	chgrp($user_home, $user_group);
237

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

    
247
function local_user_del($user) {
248
	global $debug;
249
	
250
	/* remove all memberships */
251
	local_user_get_groups($user);
252

    
253
	/* delete from pw db */
254
	$cmd = "/usr/sbin/pw userdel {$user['name']}";
255

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

    
263
function local_user_set_password(& $user, $password) {
264

    
265
	$user['password'] = crypt($password);
266
	$user['md5-hash'] = md5($password);
267

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

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

    
280
function local_user_get_groups($user, $all = false) {
281
	global $debug, $config;
282

    
283
	$groups = array();
284
	if (!is_array($config['system']['group']))
285
		return $groups;
286

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

    
293
	sort($groups);
294

    
295
	return $groups;
296
}
297

    
298
function local_user_set_groups($user, $new_groups = NULL ) {
299
	global $debug, $config, $groupindex;
300

    
301
	if (!is_array($config['system']['group']))
302
		return;
303

    
304
	$cur_groups = local_user_get_groups($user);
305
	$mod_groups = array();
306

    
307
	if (!is_array($new_groups))
308
		$new_groups = array();
309

    
310
	if (!is_array($cur_groups))
311
		$cur_groups = array();
312

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

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

    
332
	/* sync all modified groups */
333
	foreach ($mod_groups as $group)
334
		local_group_set($group);
335
}
336

    
337
function local_group_set($group, $reset = false) {
338
	global $debug;
339
	
340
	$group_name = $group['name'];
341
	$group_gid = $group['gid'];
342
	$group_members = "''";
343
	if (!$reset && count($group['member']))
344
		$group_members = implode(",",$group['member']);
345

    
346
	/* read from group db */
347
	$fd = popen("/usr/sbin/pw groupshow {$group_name} 2>&1", "r");
348
	$pwread = fgets($fd);
349
	pclose($fd);
350

    
351
	/* determine add or mod */
352
	if (!strncmp($pwread, "pw:", 3))
353
		$group_op = "groupadd";
354
	else
355
		$group_op = "groupmod";
356

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

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

    
367
function local_group_del($group) {
368
	global $debug;
369

    
370
	/* delete from group db */
371
	$cmd = "/usr/sbin/pw groupdel {$group['name']}";
372

    
373
	if($debug)
374
		log_error("Running: {$cmd}");
375
	$fd = popen($cmd, "w");
376
	fwrite($fd, $user['password']);
377
	pclose($fd);
378
}
379

    
380
function ldap_test_connection() {
381
	global $debug, $config, $g;
382

    
383
	$ldapserver = $config['system']['webgui']['ldapserver'];
384
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
385
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
386

    
387
	if (!($ldap = ldap_connect($ldapserver)))
388
		return false;
389

    
390
	return true;
391
}
392

    
393
function ldap_test_bind() {
394
	global $debug, $config, $g;
395

    
396
	$ldapserver = $config['system']['webgui']['ldapserver'];
397
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
398
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
399
    
400
	if (!($ldap = ldap_connect($ldapserver)))
401
		return false;
402

    
403
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
404
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
405
    
406
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
407
		return false;
408

    
409
	return true;
410
}
411

    
412
function ldap_get_user_ous($show_complete_ou=true) {
413
	global $debug, $config, $g;
414

    
415
	if(!function_exists("ldap_connect"))
416
		return;
417

    
418
	$ldapserver     = $config['system']['webgui']['ldapserver'];
419
	$ldapbindun     = $config['system']['webgui']['ldapbindun'];
420
	$ldapbindpw     = $config['system']['webgui']['ldapbindpw'];
421
	$ldapsearchbase = "{$config['system']['webgui']['ldapsearchbase']}";
422
	$ldaptype       = $config['system']['webgui']['backend'];
423

    
424
	$ldapfilter = "(ou=*)";
425
	putenv('LDAPTLS_REQCERT=never');
426
	if (!($ldap = ldap_connect($ldapserver))) {
427
		log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in local_backed()");
428
		$status = local_backed($username, $passwd);
429
		return $status;
430
	}
431

    
432
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
433
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
434

    
435
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
436
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
437
		$status = local_backed($username, $passwd);
438
		return $status;
439
	}
440

    
441
	$search = ldap_search($ldap, $ldapsearchbase, $ldapfilter);
442

    
443
	$info = ldap_get_entries($ldap, $search);
444

    
445
	$ous = array();
446

    
447
	if (is_array($info)) {
448
		foreach ($info as $inf) {
449
			if (!$show_complete_ou) {
450
				$inf_split = split(",", $inf['dn']);
451
				$ou = $inf_split[0];
452
				$ou = str_replace("OU=","", $ou);
453
			} else
454
				if($inf['dn'])
455
					$ou = $inf['dn'];
456
			if($ou)
457
				$ous[] = $ou;
458
		}
459
	}
460

    
461
	//Tack on the default Users container for AD since its non-standard
462
	if($ldaptype == 'ldap')
463
		$ous[] = "CN=Users,".$ldapsearchbase;
464

    
465
	return $ous;
466
}
467

    
468
function ldap_get_groups($username) {
469
	global $debug, $config;
470
	
471
	if(!function_exists("ldap_connect"))
472
		return;
473
	
474
	if(!$username) 
475
		return false;
476

    
477
	if(stristr($username, "@")) {
478
		$username_split=split("\@", $username);
479
		$username = $username_split[0];		
480
	}
481

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

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

    
511
	/* bind as user that has rights to read group attributes */
512
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
513
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
514
		$status = local_backed($username, $passwd);
515
		return $status;
516
	}
517

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

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

    
548
function ldap_backed($username, $passwd) {
549
	global $debug, $config;
550
	
551
	if(!$username) 
552
		return;
553

    
554
	if(!function_exists("ldap_connect"))
555
		return;
556

    
557
	$adbindas = $username;
558
    
559
	if(stristr($username, "@")) {
560
		$username_split=split("\@", $username);
561
		$username = $username_split[0];        
562
	}
563
	if(stristr($username, "\\")) {
564
		$username_split=split("\\", $username);
565
		$username = $username_split[0];        
566
	}
567

    
568
	$ldapserver         = $config['system']['webgui']['ldapserver'];
569
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
570
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
571
	$ldapauthcont       = $config['system']['webgui']['ldapauthcontainers'];   
572
	$ldapnameattribute  = $config['system']['webgui']['ldapnameattribute'];  
573
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
574
	$ldaptype           = $config['system']['webgui']['backend'];
575
	$ldapfilter = str_replace("\$username", $username, $ldapfilter);
576

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

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

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

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

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

    
711
	log_error("$binduser succesfully logged in via LDAP.");
712

    
713
	/* At this point we are bound to LDAP so the user was auth'd okay. */
714
	return true;
715
}
716

    
717
function radius_backed($username, $passwd){
718
	global $debug, $config, $debug;
719
	$ret = false;
720
	$radiusservers = $config['system']['radius']['servers'];
721

    
722
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
723
	/* Add a new servers to our instance */
724
	foreach ($radiusservers as $radsrv)
725
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
726

    
727
	if (!$rauth->start()) {
728
		$retvalue['auth_val'] = 1;
729
		$retvalue['error'] = $rauth->getError();
730
		if ($debug)
731
			printf("Radius start: %s<br>\n", $retvalue['error']);
732
	}
733

    
734
	// XXX - billm - somewhere in here we need to handle securid challenge/response
735

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

    
754
	// close OO RADIUS_AUTHENTICATION
755
	$rauth->close();
756

    
757
	return $ret;
758
}
759

    
760
function session_auth($backing) {
761
	global $g, $debug, $HTTP_SERVER_VARS, $userindex, $config;
762

    
763
	session_start();
764

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

    
792
	/* Show login page if they aren't logged in */
793
	if (empty($_SESSION['Logged_In'])) {
794
		/* Don't display login forms to AJAX */
795
		if (isAjax())
796
			return false;
797
		require_once("authgui.inc");
798
		display_login_form();
799
		return false;
800
	}
801

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

    
819
	/* obtain user object */
820
	$user = getUserEntry($_SESSION['Username']);
821

    
822
	/* user hit the logout button */
823
	if (isset($_GET['logout'])) {
824

    
825
		if ($_SESSION['Logout'])
826
			log_error("Session timed out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
827
		else
828
			log_error("User logged out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
829

    
830
		/* wipe out $_SESSION */
831
		$_SESSION = array();
832

    
833
		if (isset($_COOKIE[session_name()]))
834
			setcookie(session_name(), '', time()-42000, '/');
835

    
836
		/* and destroy it */
837
		session_destroy();
838

    
839
		$scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
840
		$scriptElms = count($scriptName);
841
		$scriptName = $scriptName[$scriptElms-1];
842

    
843
		if (isAjax())
844
			return false;
845

    
846
		/* redirect to page the user is on, it'll prompt them to login again */
847
		pfSenseHeader($scriptName);
848

    
849
		return false;
850
	}
851

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

    
863
	/*
864
	 * Same to re-enable Ajax.
865
	 */
866
	if ($_GET['enable_ajax']) {
867
		unset($_SESSION['NO_AJAX']);
868
		$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
869
		return true;
870
	}
871

    
872
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
873
	return true;
874
}
875

    
876
?>
(3-3/37)