Project

General

Profile

Download (26.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
*/
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, $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, $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 $config, $userindex;
82
	if (isset($userindex[$name]))
83
		return $config['system']['user'][$userindex[$name]];
84
}
85

    
86
function & getUserEntryByUID($uid) {
87
	global $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 $config, $groupindex;
97
	if (isset($groupindex[$name]))
98
		return $config['system']['group'][$groupindex[$name]];
99
}
100

    
101
function & getGroupEntryByGID($gid) {
102
	global $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 $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
			log_error("Running: {$cmd}");
137
			mwexec($cmd);
138
		}
139
		pclose($fd);
140
	}
141

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

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

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

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

    
176
function local_user_set(& $user) {
177
	global $g;
178

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

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

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

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

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

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

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

    
223
	log_error("Running: {$cmd}");
224
	$fd = popen($cmd, "r+");
225
	fwrite($fd, $user['password']);
226
	pclose($fd);
227

    
228
	/* create user directory if required */
229
	if (!is_dir($user_home))
230
		mkdir($user_home, 0700);
231
	chown($user_home, $user_name);
232
	chgrp($user_home, $user_group);
233

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

    
243
function local_user_del($user) {
244

    
245
	/* remove all memberships */
246
	local_user_get_groups($user);
247

    
248
	/* delete from pw db */
249
	$cmd = "/usr/sbin/pw userdel {$user['name']}";
250

    
251
	log_error("Running: {$cmd}");
252
	$fd = popen($cmd, "w");
253
	fwrite($fd, $user['password']);
254
	pclose($fd);
255
}
256

    
257
function local_user_set_password(& $user, $password) {
258

    
259
	$user['password'] = crypt($password);
260
	$user['md5-hash'] = md5($password);
261

    
262
	// Converts ascii to unicode.
263
	$astr = (string) $password;
264
	$ustr = '';
265
	for ($i = 0; $i < strlen($astr); $i++) {
266
		$a = ord($astr{$i}) << 8;
267
		$ustr.= sprintf("%X", $a);
268
	}
269

    
270
	// Generate the NT-HASH from the unicode string
271
	$user['nt-hash'] = bin2hex(mhash(MHASH_MD4, $ustr));
272
}
273

    
274
function local_user_get_groups($user, $all = false) {
275
	global $config;
276

    
277
	$groups = array();
278
	if (!is_array($config['system']['group']))
279
		return $groups;
280

    
281
	foreach ($config['system']['group'] as $group)
282
		if ( $all || ( !$all && ($group['name'] != "all")))
283
			if (is_array($group['member']))
284
				if (in_array($user['uid'], $group['member']))
285
					$groups[] = $group['name'];
286

    
287
	sort($groups);
288

    
289
	return $groups;
290
}
291

    
292
function local_user_set_groups($user, $new_groups = NULL ) {
293
	global $config, $groupindex;
294

    
295
	if (!is_array($config['system']['group']))
296
		return;
297

    
298
	$cur_groups = local_user_get_groups($user);
299
	$mod_groups = array();
300

    
301
	if (!is_array($new_groups))
302
		$new_groups = array();
303

    
304
	if (!is_array($cur_groups))
305
		$cur_groups = array();
306

    
307
	/* determine which memberships to add */
308
	foreach ($new_groups as $groupname) {
309
		if (in_array($groupname,$cur_groups))
310
			continue;
311
		$group = & $config['system']['group'][$groupindex[$groupname]];
312
		$group['member'][] = $user['uid'];
313
		$mod_groups[] = $group;
314
	}
315

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

    
326
	/* sync all modified groups */
327
	foreach ($mod_groups as $group)
328
		local_group_set($group);
329
}
330

    
331
function local_group_set($group, $reset = false) {
332

    
333
	$group_name = $group['name'];
334
	$group_gid = $group['gid'];
335
	$group_members = "''";
336
	if (!$reset && count($group['member']))
337
		$group_members = implode(",",$group['member']);
338

    
339
	/* read from group db */
340
	$fd = popen("/usr/sbin/pw groupshow {$group_name} 2>&1", "r");
341
	$pwread = fgets($fd);
342
	pclose($fd);
343

    
344
	/* determine add or mod */
345
	if (!strncmp($pwread, "pw:", 3))
346
		$group_op = "groupadd";
347
	else
348
		$group_op = "groupmod";
349

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

    
353
	log_error("Running: {$cmd}");
354
	$fd = popen($cmd, "r+");
355
	fwrite($fd, $user['password']);
356
	pclose($fd);
357
}
358

    
359
function local_group_del($group) {
360

    
361
	/* delete from group db */
362
	$cmd = "/usr/sbin/pw groupdel {$group['name']}";
363

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

    
370
function ldap_test_connection() {
371
	global $config, $g;
372

    
373
	$ldapserver = $config['system']['webgui']['ldapserver'];
374
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
375
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
376

    
377
	if (!($ldap = ldap_connect($ldapserver)))
378
		return false;
379

    
380
	return true;
381
}
382

    
383
function ldap_test_bind() {
384
	global $config, $g;
385

    
386
	$ldapserver = $config['system']['webgui']['ldapserver'];
387
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
388
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
389
    
390
	if (!($ldap = ldap_connect($ldapserver)))
391
		return false;
392

    
393
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
394
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
395
    
396
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw)))
397
		return false;
398

    
399
	return true;
400
}
401

    
402
function ldap_get_user_ous($show_complete_ou=true) {
403
	global $config, $g;
404

    
405
	if(!function_exists("ldap_connect"))
406
		return;
407

    
408
	$ldapserver     = $config['system']['webgui']['ldapserver'];
409
	$ldapbindun     = $config['system']['webgui']['ldapbindun'];
410
	$ldapbindpw     = $config['system']['webgui']['ldapbindpw'];
411
	$ldapsearchbase = "{$config['system']['webgui']['ldapsearchbase']}";
412
	$ldaptype       = $config['system']['webgui']['backend'];
413

    
414
	$ldapfilter = "(ou=*)";
415
	putenv('LDAPTLS_REQCERT=never');
416
	if (!($ldap = ldap_connect($ldapserver))) {
417
		log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in local_backed()");
418
		$status = local_backed($username, $passwd);
419
		return $status;
420
	}
421

    
422
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
423
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
424

    
425
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
426
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
427
		$status = local_backed($username, $passwd);
428
		return $status;
429
	}
430

    
431
	$search = ldap_search($ldap, $ldapsearchbase, $ldapfilter);
432

    
433
	$info = ldap_get_entries($ldap, $search);
434

    
435
	$ous = array();
436

    
437
	if (is_array($info)) {
438
		foreach ($info as $inf) {
439
			if (!$show_complete_ou) {
440
				$inf_split = split(",", $inf['dn']);
441
				$ou = $inf_split[0];
442
				$ou = str_replace("OU=","", $ou);
443
			} else
444
				if($inf['dn'])
445
					$ou = $inf['dn'];
446
			if($ou)
447
				$ous[] = $ou;
448
		}
449
	}
450

    
451
	//Tack on the default Users container for AD since its non-standard
452
	if($ldaptype == 'ldap')
453
		$ous[] = "CN=Users,".$ldapsearchbase;
454

    
455
	return $ous;
456
}
457

    
458
function ldap_get_groups($username) {
459
	global $config;
460
	
461
	if(!function_exists("ldap_connect"))
462
		return;
463
	
464
	if(!$username) 
465
		return false;
466

    
467
	if(stristr($username, "@")) {
468
		$username_split=split("\@", $username);
469
		$username = $username_split[0];		
470
	}
471

    
472
	if(stristr($username, "\\")) {
473
		$username_split=split("\\", $username);
474
		$username = $username_split[0];        
475
	}    
476
	
477
	//log_error("Getting LDAP groups for {$username}.");
478
	
479
	$ldapserver         = $config['system']['webgui']['ldapserver'];
480
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
481
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
482
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
483
	$ldapfilter         = str_replace("\$username", $username, $ldapfilter);
484
	$ldapgroupattribute = $config['system']['webgui']['ldapgroupattribute'];
485
	$ldapdn             = $_SESSION['ldapdn'];
486
	 
487
	/*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
488
	$ldapgroupattribute = strtolower($ldapgroupattribute);
489

    
490
	/* connect and see if server is up */
491
	putenv('LDAPTLS_REQCERT=never');
492
	if (!($ldap = ldap_connect($ldapserver))) {
493
		log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in local_backed()");
494
		$status = local_backed($username, $passwd);
495
		return $status;	
496
	}
497
    
498
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
499
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
500

    
501
	/* bind as user that has rights to read group attributes */
502
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
503
		log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in local_backed()");
504
		$status = local_backed($username, $passwd);
505
		return $status;
506
	}
507

    
508
	/* get groups from DN found */
509
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
510
	/* since we know the DN is in $_SESSION['ldapdn'] */
511
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
512
	$search    = ldap_read($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
513
	$info      = ldap_get_entries($ldap, $search);
514

    
515
	$countem = $info["count"];	
516
	$memberof = array();
517
	
518
	if(is_array($info[0][$ldapgroupattribute])) {
519
		/* Iterate through the groups and throw them into an array */
520
		foreach ($info[0][$ldapgroupattribute] as $member) {
521
			if (stristr($member, "CN=") !== false) {
522
				$membersplit = split(",", $member);
523
				$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
524
			}
525
		}
526
	}
527
	
528
	/* Time to close LDAP connection */
529
	ldap_close($ldap);
530
	
531
	$groups = print_r($memberof,true);
532
	
533
	//log_error("Returning groups ".$groups." for user $username");
534
	
535
	return $memberof;
536
}
537

    
538
function ldap_backed($username, $passwd) {
539
	global $config;
540
	
541
	if(!$username) 
542
		return;
543

    
544
	if(!function_exists("ldap_connect"))
545
		return;
546

    
547
	$adbindas = $username;
548
    
549
	if(stristr($username, "@")) {
550
		$username_split=split("\@", $username);
551
		$username = $username_split[0];        
552
	}
553
	if(stristr($username, "\\")) {
554
		$username_split=split("\\", $username);
555
		$username = $username_split[0];        
556
	}
557

    
558
	$ldapserver         = $config['system']['webgui']['ldapserver'];
559
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
560
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
561
	$ldapauthcont       = $config['system']['webgui']['ldapauthcontainers'];   
562
	$ldapnameattribute  = $config['system']['webgui']['ldapnameattribute'];  
563
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
564
	$ldaptype           = $config['system']['webgui']['backend'];
565
	$ldapfilter = str_replace("\$username", $username, $ldapfilter);
566

    
567
	/* first check if there is even an LDAP server populated */ 
568
	if(!$ldapserver) {
569
		log_error("ERROR!  ldap_backed() backed selected with no LDAP authentication server defined.  Defaulting to built-in local_backed().     Visit System -> User Manager -> Settings.");
570
		$status = local_backed($username, $passwd);
571
		return $status;
572
	}
573
	
574
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
575
	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
576

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

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

    
639
		if ($matches == 1){
640
			$binduser = $adbindas;
641
			log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
642
		}
643
		if ($matches != 1){
644
			log_error("ERROR! Either LDAP search failed, or multiple users were found");
645
			$status = local_backed($username, $passwd);
646
			$_SESSION['ldapon'] = "false";
647
			ldap_close($ldap);
648
			return $status;                         
649
		}
650
	}
651

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

    
701
	log_error("$binduser succesfully logged in via LDAP.");
702

    
703
	/* At this point we are bound to LDAP so the user was auth'd okay. */
704
	return true;
705
}
706

    
707
function radius_backed($username, $passwd){
708
	global $config, $debug;
709
	$ret = false;
710
	$radiusservers = $config['system']['radius']['servers'];
711

    
712
	$rauth = new Auth_RADIUS_PAP($username, $passwd);
713
	/* Add a new servers to our instance */
714
	foreach ($radiusservers as $radsrv)
715
		$rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
716

    
717
	if (!$rauth->start()) {
718
		$retvalue['auth_val'] = 1;
719
		$retvalue['error'] = $rauth->getError();
720
		if ($debug)
721
			printf("Radius start: %s<br>\n", $retvalue['error']);
722
	}
723

    
724
	// XXX - billm - somewhere in here we need to handle securid challenge/response
725

    
726
	/* Send request */
727
	$result = $rauth->send();
728
	if (PEAR::isError($result)) {
729
		$retvalue['auth_val'] = 1;
730
		$retvalue['error'] = $result->getMessage();
731
		if ($debug)
732
			printf("Radius send failed: %s<br>\n", $retvalue['error']);
733
	} else if ($result === true) {
734
		$retvalue['auth_val'] = 2;
735
		if ($debug)
736
			printf(gettext("Radius Auth succeeded")."<br>\n");
737
		$ret = true;
738
	} else {
739
		$retvalue['auth_val'] = 3;
740
		if ($debug)
741
			printf(gettext("Radius Auth rejected")."<br>\n");
742
	}
743

    
744
	// close OO RADIUS_AUTHENTICATION
745
	$rauth->close();
746

    
747
	return $ret;
748
}
749

    
750
function session_auth($backing) {
751
	global $g, $HTTP_SERVER_VARS, $userindex, $config;
752

    
753
	session_start();
754

    
755
	/* Validate incoming login request */
756
	if (isset($_POST['login'])) {
757
		if ($backing($_POST['usernamefld'], $_POST['passwordfld'])) {
758
			$_SESSION['Logged_In'] = "True";
759
			$_SESSION['Username'] = $_POST['usernamefld'];
760
			$_SESSION['last_access'] = time();
761
			log_error("Successful login for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
762
		} else {
763
			/* give the user a more detailed error message */
764
			if (isset($userindex[$_POST['usernamefld']])) {
765
				$_SESSION['Login_Error'] = "Username or Password incorrect";
766
				log_error("Wrong password entered for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
767
				if(isAjax()) {
768
					echo "showajaxmessage('{$_SESSION['Login_Error']}');";
769
					return;
770
				}
771
			} else {
772
				$_SESSION['Login_Error'] = "Username or Password incorrect";
773
				log_error("Attempted login for invalid user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
774
				if(isAjax()) {
775
					echo "showajaxmessage('{$_SESSION['Login_Error']}');";
776
					return;
777
				}
778
			}
779
		}
780
	}
781

    
782
	/* Show login page if they aren't logged in */
783
	if (empty($_SESSION['Logged_In'])) {
784
		/* Don't display login forms to AJAX */
785
		if (isAjax())
786
			return false;
787
		require_once("authgui.inc");
788
		display_login_form();
789
		return false;
790
	}
791

    
792
	/* If session timeout isn't set, we don't mark sessions stale */
793
	if (!isset($config['system']['webgui']['session_timeout']) ||
794
		$config['system']['webgui']['session_timeout'] == 0 ||
795
		$config['system']['webgui']['session_timeout'] == "")
796
		$_SESSION['last_access'] = time();
797
	else {
798
		/* Check for stale session */
799
		if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
800
			$_GET['logout'] = true;
801
			$_SESSION['Logout'] = true;
802
		} else {
803
			/* only update if it wasn't ajax */
804
			if (!isAjax())
805
				$_SESSION['last_access'] = time();
806
		}
807
	}
808

    
809
	/* obtain user object */
810
	$user = getUserEntry($_SESSION['Username']);
811

    
812
	/* user hit the logout button */
813
	if (isset($_GET['logout'])) {
814

    
815
		if ($_SESSION['Logout'])
816
			log_error("Session timed out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
817
		else
818
			log_error("User logged out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
819

    
820
		/* wipe out $_SESSION */
821
		$_SESSION = array();
822

    
823
		if (isset($_COOKIE[session_name()]))
824
			setcookie(session_name(), '', time()-42000, '/');
825

    
826
		/* and destroy it */
827
		session_destroy();
828

    
829
		$scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
830
		$scriptElms = count($scriptName);
831
		$scriptName = $scriptName[$scriptElms-1];
832

    
833
		if (isAjax())
834
			return false;
835

    
836
		/* redirect to page the user is on, it'll prompt them to login again */
837
		pfSenseHeader($scriptName);
838

    
839
		return false;
840
	}
841

    
842
	/*
843
	 * this is for debugging purpose if you do not want to use Ajax
844
	 * to submit a HTML form. It basically diables the observation
845
	 * of the submit event and hence does not trigger Ajax.
846
	 */
847
	if ($_GET['disable_ajax']) {
848
		$_SESSION['NO_AJAX'] = "True";
849
		$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
850
		return true;
851
	}
852

    
853
	/*
854
	 * Same to re-enable Ajax.
855
	 */
856
	if ($_GET['enable_ajax']) {
857
		unset($_SESSION['NO_AJAX']);
858
		$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
859
		return true;
860
	}
861

    
862
	$HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
863
	return true;
864
}
865

    
866
?>
(3-3/37)