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 = "/home/";
186
	
187
	if (!is_dir($home_base))
188
		mkdir($home_base, 0755);
189

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
297
	sort($groups);
298

    
299
	return $groups;
300
	
301
}
302

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
371
}
372

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

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

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

    
385
}
386

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

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

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

    
397
	return true;
398
}
399

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

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

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

    
416
	return true;
417
}
418

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

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

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

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

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

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

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

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

    
452
	$ous = array();
453

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

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

    
472
	return $ous;
473
}
474

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
764
	return $ret;
765
}
766

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

    
770
	session_start();
771

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

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

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

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

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

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

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

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

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

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

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

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

    
856
		return false;
857
	}
858

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

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

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

    
883
?>
(3-3/37)