Project

General

Profile

Download (34.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
		Copyright (C) 2007, 2008 Scott Ullrich <sullrich@gmail.com>
5
		All rights reserved.
6

    
7
        Copyright (C) 2005-2006 Bill Marquette <bill.marquette@gmail.com>
8
        All rights reserved.
9

    
10
        Copyright (C) 2006 Paul Taylor <paultaylor@winn-dixie.com>.
11
        All rights reserved.
12

    
13
        Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
14
        All rights reserved.
15

    
16
        Redistribution and use in source and binary forms, with or without
17
        modification, are permitted provided that the following conditions are met:
18

    
19
        1. Redistributions of source code must retain the above copyright notice,
20
           this list of conditions and the following disclaimer.
21

    
22
        2. Redistributions in binary form must reproduce the above copyright
23
           notice, this list of conditions and the following disclaimer in the
24
           documentation and/or other materials provided with the distribution.
25

    
26
        THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
27
        INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28
        AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29
        AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
30
        OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31
        SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32
        INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33
        CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34
        ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
        POSSIBILITY OF SUCH DAMAGE.
36
*/
37

    
38
require_once("functions.inc");
39
$groupindex = index_groups();
40
$userindex = index_users();
41

    
42
function logout_session() {
43
	global $_SESSION;
44
	
45
      if (hasLockAbility($_SESSION['Username'])) {
46
        unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
47
      }
48

    
49
      /* wipe out $_SESSION */
50
      $_SESSION = array();
51

    
52
      /* and destroy it */
53
      session_destroy();
54

    
55
      $scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
56
      $scriptElms = count($scriptName);
57
      $scriptName = $scriptName[$scriptElms-1];
58
}
59

    
60
function getAllowedGroups($logged_in_user) {
61
	global $g, $config;
62

    
63
	if(!function_exists("ldap_connect"))
64
		return;
65
	
66
	$allowed = array();
67
	$allowed_groups = array();
68
	
69
	$ldapon = $_SESSION['ldapon'];
70
	//log_error("Getting groups for {$logged_in_user}.");
71
	
72
	
73
	
74
	$local_user = false;
75
	
76
	//log_error("Local_user = {$local_user}");
77
	
78
	foreach($config['system']['user'] as $username) 
79
		if($username['name'] == $logged_in_user) 
80
			$local_user = true;
81
	
82
	/* return ldap groups if we are in ldap mode */
83
	if($config['system']['webgui']['backend'] == "ldap" && $local_user == false) {
84
		//log_error("Calling LDAP_GET_GROUPS from the first section");
85
		$allowed_groups = ldap_get_groups($logged_in_user);
86
		$fdny = fopen("/tmp/groups","w");
87
		fwrite($fdny, print_r($allowed, true));
88
		fclose($fdny);
89
		$allowed = array();
90
		if(is_array($config['system']['group']) && is_array($allowed_groups)) {
91
			foreach($config['system']['group'] as $group) {
92
				if(in_array($group['name'], $allowed_groups)) {
93
					foreach($group['pages'] as $page) {
94
						$allowed[] = $page;
95
					}				
96
				}
97
			}
98
		}
99
		return $allowed;
100
	}
101
	if($config['system']['webgui']['backend'] == "ldapother" && $local_user == false) {
102
		//log_error("Calling LDAP_GET_GROUPS from the first section");
103
		$allowed_groups = ldap_get_groups($logged_in_user);
104
		$fdny = fopen("/tmp/groups","w");
105
		fwrite($fdny, print_r($allowed, true));
106
		fclose($fdny);
107
		$allowed = array();
108
		if(is_array($config['system']['group']) && is_array($allowed_groups)) {
109
			foreach($config['system']['group'] as $group) {
110
				if(in_array($group['name'], $allowed_groups)) {
111
					foreach($group['pages'] as $page) {
112
						$allowed[] = $page;
113
					}				
114
				}
115
			}
116
		}
117
		return $allowed;
118
	}	
119
	
120
	$final_allowed = array();
121

    
122
	foreach($config['system']['user'] as $username) {
123
		if($username['name'] == $logged_in_user) 
124
			$allowed_groups  = explode(",", $username['groupname']);
125
	}
126
		
127
	foreach($config['system']['group'] as $group) {
128
		if(in_array($group['name'], $allowed_groups)) {
129
			foreach($group['pages'] as $page) {
130
				$allowed[] = $page;
131
			}
132
		}
133
	}
134
	
135
	return $allowed;
136
}
137

    
138
function &getSystemAdminNames() {
139
  global $config, $g, $userindex;
140
  $adminUsers = array();
141

    
142
  if (is_array($config['system']['user'])) {
143
    foreach($config['system']['user'] as $user){
144
      if (isSystemAdmin($user['name'])) {
145
        $adminUsers[] = $user['name'];
146
      }
147
    }
148
  }
149

    
150
  return $adminUsers;
151
}
152

    
153
function &getSystemPrivs() {
154
  global $g;
155

    
156
  $privs = array();
157

    
158
  $privs[] = array("id" => "lockwc",
159
                   "name" => "Lock webConfigurator",
160
                   "desc" => "Indicates whether this user will lock access to " .
161
                             "the webConfigurator for other users.");
162
  $privs[] = array("id" => "lock-ipages",
163
                   "name" => "Lock individual pages",
164
                   "desc" => "Indicates whether this user will lock individual " .
165
                              "HTML pages after having accessed a particular page" .
166
                              "(the lock will be freed if the user leaves or " .
167
                              "saves the page form).");
168
  $privs[] = array("id" => "hasshell",
169
                   "name" => "Has shell access",
170
                   "desc" => "Indicates whether this user is able to login for " .
171
                   "example via SSH.");
172
  $privs[] = array("id" => "copyfiles",
173
                   "name" => "Is allowed to copy files",
174
                   "desc" => "Indicates whether this user is allowed to copy files " .
175
                             "onto the {$g['product_name']} appliance via SCP/SFTP. " .
176
                             "If you are going to use this privilege, you must install " .
177
                             "scponly on the appliance (Hint: pkg_add -r scponly).");
178
  $privs[] = array("id" => "isroot",
179
                   "name" => "Is root user",
180
                   "desc" => "This user is associated with the UNIX root user " .
181
                             "(you should associate this privilege only with one " .
182
                             "single user).");
183

    
184
  return $privs;
185
}
186

    
187
function assignUID($username = "") {
188
  global $userindex, $config, $g;
189

    
190
  if ($username == "") { return; }
191

    
192
  $nextuid = $config['system']['nextuid'];
193
  $user =& $config['system']['user'][$userindex[$username]];
194

    
195
  if (empty($user['uid'])) {
196
    $user['uid'] = $nextuid;
197
    $nextuid++;
198
    $config['system']['nextuid'] = $nextuid;
199

    
200
    write_config();
201

    
202
    return $user;
203
  }
204
}
205

    
206
function assignGID($groupname = "") {
207
  global $groupindex, $config, $g;
208

    
209
  if ($groupname == "") { return; }
210

    
211
  $nextgid = $config['system']['nextgid'];
212
  $group =& $config['system']['group'][$groupindex[$groupname]];
213

    
214
  if (empty($group['gid'])) {
215
    $group['gid'] = $nextgid;
216
    $nextgid++;
217
    $config['system']['nextgid'] = $nextgid;
218

    
219
    write_config();
220

    
221
    return $group;
222
  }
223
}
224

    
225
function hasPrivilege($user, $privid = "") {
226
  global $userindex, $config, $g;
227

    
228
  if ($privid == "" || ! isset($userindex[$user])) { return 0; }
229

    
230
  $privs = &$config['system']['user'][$userindex[$user]]['priv'];
231

    
232
  if (is_array($privs)) {
233
    foreach($privs as $priv){
234
      if ($priv['id'] == $privid) {
235
        return 1;
236
      }
237
    }
238
  }
239

    
240
  return 0;
241
}
242

    
243
function isAllowedToCopyFiles($username) {
244
  global $userindex, $config, $g;
245

    
246
  if ($username == "") { return 0; }
247

    
248
  return hasPrivilege($username, "copyfiles");
249
}
250

    
251
function hasLockAbility($username) {
252
  global $userindex, $config, $g;
253

    
254
  if ($username == "") { return 0; }
255

    
256
  return hasPrivilege($username, "lockwc");
257
}
258

    
259
function hasPageLockAbility($username) {
260
  global $userindex, $config, $g;
261

    
262
  if ($username == "") { return 0; }
263

    
264
  return hasPrivilege($username, "lock-ipages");
265
}
266

    
267
function hasShellAccess($username) {
268
  global $userindex, $config, $g;
269

    
270
  if ($username == "") { return 0; }
271

    
272
  return hasPrivilege($username, "hasshell");
273
}
274

    
275
function isUNIXRoot($username = "") {
276
  global $userindex, $config;
277

    
278
  if ($username == "") { return 0; }
279

    
280
  if (isSystemAdmin($username)) {
281
    return hasPrivilege($username, "isroot");
282
  }
283

    
284
  return 0;
285
}
286

    
287
function setUserFullName($name = "", $new_name = "") {
288
  global $config, $g, $userindex;
289

    
290
  if ($name == "" || $new_name == "") { return; }
291

    
292
  $user = &$config['system']['user'][$userindex[$name]];
293
  $user['fullname'] = $new_name;
294
}
295

    
296
function setUserName($name = "", $new_name = "") {
297
  global $config, $g, $userindex;
298

    
299
  if ($name == "" || $new_name == "") { return; }
300

    
301
  $user = &$config['system']['user'][$userindex[$name]];
302
  $user['name'] = $new_name;
303
}
304

    
305
function setUserPWD($name = "", $password = "") {
306
  global $config, $g, $userindex;
307

    
308
  if ($name == "" || $password == "") { return; }
309

    
310
  $user = &$config['system']['user'][$userindex[$name]];
311
  $user['password'] = crypt($password);
312
}
313

    
314
function setUserGroupName($name = "", $new_name = "") {
315
  global $config, $g, $userindex;
316

    
317
  if ($name == "" || $new_name == "") { return; }
318

    
319
  $user = &$config['system']['user'][$userindex[$name]];
320
  $user['groupname'] = $new_name;
321
}
322

    
323
function setUserType($name = "", $new_type = "") {
324
  global $config, $g, $userindex;
325

    
326
  if ($name == "" || $new_type == "") { return; }
327

    
328
  $user = &$config['system']['user'][$userindex[$name]];
329
  $user['scope'] = $new_type;
330
}
331

    
332
function getUNIXRoot() {
333
  global $config, $g, $userindex;
334

    
335
  if (is_array($config['system']['user'])) {
336
    foreach($config['system']['user'] as $user){
337
      if (isUNIXRoot($user['name'])) {
338
        $root = &$config['system']['user'][$userindex[$user['name']]];
339
        return $root;
340
      }
341
    }
342
  }
343

    
344
  return NULL;
345
}
346

    
347
function getUNIXRootName() {
348
  global $config, $g, $userindex;
349

    
350
  if (is_array($config['system']['user'])) {
351
    foreach($config['system']['user'] as $user){
352
      if (isUNIXRoot($user['name'])) {
353
        return $user['name'];
354
      }
355
    }
356
  }
357

    
358
  return NULL;
359
}
360

    
361
function getGroupHomePage($group = "") {
362
  global $groupindex, $config, $g;
363

    
364
  if ($group == "") { return ""; }
365

    
366
  $page = $config['system']['group'][$groupindex[$group]]['home'];
367
  if(empty($page)) { $page = ""; }
368
  return $page;
369
}
370

    
371
function isSystemAdmin($username = "") {
372
  global $groupindex, $userindex, $config, $g, $_SESSION;
373

    
374
  if($_SESSION['isSystemAdmin']) 
375
	return $_SESSION['isSystemAdmin'];
376

    
377
  if(!function_exists("ldap_connect"))
378
	return;
379

    
380
  if ($username == "") { 
381
		$_SESSION['isSystemAdmin'] = false; 
382
		return 0; 
383
  }
384

    
385
  $gname = $config['system']['group'][$groupindex[$config['system']['user'][$userindex[$username]]['groupname']]]['name'];
386

    
387
  if (isset($gname)) {
388
	$_SESSION['isSystemAdmin'] = $gname === $g["admin_group"];
389
    return ($gname === $g["admin_group"]);
390
  }
391

    
392
  $_SESSION['isSystemAdmin'] = false; 
393

    
394
  return 0;
395
}
396

    
397
function getRealName($username = "") {
398
  global $userindex, $config;
399

    
400
  if ($username == "") { return ""; }
401

    
402
  return $config['system']['user'][$userindex[$username]]['fullname'];
403

    
404
}
405

    
406
function basic_auth($backing) {
407
  global $HTTP_SERVER_VARS;
408

    
409
  /* Check for AUTH_USER */
410
  if ($HTTP_SERVER_VARS['PHP_AUTH_USER'] <> "") {
411
    $HTTP_SERVER_VARS['AUTH_USER'] = $HTTP_SERVER_VARS['PHP_AUTH_USER'];
412
    $HTTP_SERVER_VARS['AUTH_PW'] = $HTTP_SERVER_VARS['PHP_AUTH_PW'];
413
  }
414
  if (!isset($HTTP_SERVER_VARS['AUTH_USER'])) {
415
    require_once("authgui.inc");
416
    header("WWW-Authenticate: Basic realm=\".\"");
417
    header("HTTP/1.0 401 Unauthorized");
418
    display_error_form("401", gettext("You must enter valid credentials to access this resource."));
419
    exit;
420
  } else {
421
    return $backing($HTTP_SERVER_VARS['AUTH_USER'],$HTTP_SERVER_VARS['AUTH_PW']);
422
  }
423
}
424

    
425
function session_auth($backing) {
426
  global $g, $HTTP_SERVER_VARS, $userindex, $config;
427

    
428
  session_start();
429

    
430
  /* Validate incoming login request */
431
  if (isset($_POST['login'])) {
432
    if ($backing($_POST['usernamefld'], $_POST['passwordfld'])) {
433
      $_SESSION['Logged_In'] = "True";
434
      $_SESSION['Username'] = $_POST['usernamefld'];
435
      $_SESSION['last_access'] = time();
436
    } else {
437
      /* give the user a more detailed error message */
438
      if (isset($userindex[$_POST['usernamefld']])) {
439
        $_SESSION['Login_Error'] = "Wrong password";
440
        if(isAjax()) {
441
        	echo "showajaxmessage('Wrong password');";
442
        	return;        	
443
        }
444
      } else {
445
        $_SESSION['Login_Error'] = "User does not exist";
446
        if(isAjax()) {
447
        	echo "showajaxmessage('User does not exist');";
448
        	return;
449
        }
450
      }
451
    }
452
  }
453

    
454
  /* Show login page if they aren't logged in */
455
  if (empty($_SESSION['Logged_In'])) {
456
    /* Don't display login forms to AJAX */
457
    if (isAjax())
458
      return false;
459
    require_once("authgui.inc");
460
    display_login_form();
461
    return false;
462
  } else {
463
    /* If session timeout isn't set, we don't mark sessions stale */
464
    if (!isset($config['system']['webgui']['session_timeout']) or
465
       $config['system']['webgui']['session_timeout'] == 0 or
466
       $config['system']['webgui']['session_timeout'] == "")
467
       $_SESSION['last_access'] = time();
468
     else
469
       /* Check for stale session */
470
       if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60)))
471
         $_GET['logout'] = true;
472
       else
473
         /* only update if it wasn't ajax */
474
         if (!isAjax())
475
           $_SESSION['last_access'] = time();
476

    
477
    /* user hit the logout button */
478
    if (isset($_GET['logout'])) {
479
      if (hasLockAbility($_SESSION['Username'])) {
480
        unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
481
      }
482

    
483
      /* wipe out $_SESSION */
484
      $_SESSION = array();
485

    
486
      if (isset($_COOKIE[session_name()])) {
487
        setcookie(session_name(), '', time()-42000, '/');
488
      }
489

    
490
      /* and destroy it */
491
      session_destroy();
492

    
493
      $scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
494
      $scriptElms = count($scriptName);
495
      $scriptName = $scriptName[$scriptElms-1];
496

    
497
      if (isAjax())
498
        return false;
499

    
500
      /* redirect to page the user is on, it'll prompt them to login again */
501
      pfSenseHeader($scriptName);
502

    
503
      return false;
504

    
505
    /* user wants to explicitely delete the log file.
506
     * Requires a particular privilege.
507
     */
508
    } else if ($_GET['deletelock'] && hasLockAbility($_SESSION['Username'])) {
509
      unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
510
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
511
      return true;
512

    
513
    /* this is for debugging purpose if you do not want to use Ajax
514
     * to submit a HTML form. It basically diables the observation
515
     * of the submit event and hence does not trigger Ajax.
516
     */
517
    } else if ($_GET['disable_ajax']) {
518
      $_SESSION['NO_AJAX'] = "True";
519
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
520
      return true;
521

    
522
    /* Same to re-enable Ajax.
523
     */
524
    } else if ($_GET['enable_ajax']) {
525
      unset($_SESSION['NO_AJAX']);
526
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
527
      return true;
528

    
529
    /* user wants to explicitely create a lock.
530
     * Requires a particular privilege.
531
     */
532
    } else if ($_GET['createlock'] && hasLockAbility($_SESSION['Username'])) {
533
      $fd = fopen("{$g['tmp_path']}/webconfigurator.lock", "w");
534
      fputs($fd, "{$_SERVER['REMOTE_ADDR']} (" .
535
                 getRealName($_SESSION['Username']) . ")");
536
      fclose($fd);
537
      /* if the user did delete the lock manually, do not
538
       * re-create it while the session is valide.
539
       */
540
      $_SESSION['Lock_Created'] = "True";
541
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
542
      return true;
543

    
544
    /* proceed with the login process */
545
    } else {
546
      /* if the user is allowed to create a lock,
547
       * create it once per session.
548
       */
549
      if (hasLockAbility($_SESSION['Username']) &&
550
          ! isset($_SESSION['Lock_Created'])) {
551

    
552
        $fd = fopen("{$g['tmp_path']}/webconfigurator.lock", "w");
553
        fputs($fd, "{$_SERVER['REMOTE_ADDR']} (" .
554
                   getRealName($_SESSION['Username']) . ")");
555
        fclose($fd);
556
        /* if the user did delete the lock manually, do not
557
         * re-create it while the session is valide.
558
         */
559
        $_SESSION['Lock_Created'] = "True";
560

    
561
      /* give regular users a chance to automatically invalidate
562
       * a lock if its older than a particular time.
563
       */
564
      } else if (! hasLockAbility($_SESSION['Username']) &&
565
                 file_exists("{$g['tmp_path']}/webconfigurator.lock")) {
566

    
567
        $offset = 12; //hours
568
        $mtime = filemtime("{$g['tmp_path']}/webconfigurator.lock");
569
        $now_minus_offset = mktime(date("H") - $offset, 0, 0, date("m"), date("d"), date("Y"));
570

    
571
        if (($mtime - $now_minus_offset) < $mtime) {
572
          require_once("authgui.inc");
573
          display_login_form();
574
          return false;
575
        } else {
576
          /* file is older than mtime + offset which may
577
           * indicate a stale lockfile, hence we are going
578
           * to remove it.
579
           */
580
           unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
581
        }
582
      }
583

    
584
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
585
      return true;
586
    }
587
  }
588
}
589

    
590
function pam_backed($username = "", $password = "") {
591
  /* do not allow blank passwords */
592
  if ($username == "" || password == "") { return false; }
593

    
594
  if(! extension_loaded( 'pam_auth' )) {
595
    if(! @dl( 'pam_auth.so' )) {
596
      return false;
597
    } else {
598
      /* no php file no auth, sorry */
599
      if (! file_exists("/etc/pam.d/php")) {
600
        if (! file_exists("/etc/pam.d")) { mkdir("/etc/pam.d"); }
601

    
602
        $pam_php = <<<EOD
603
# /etc/pam.d/php
604
#
605
# note: both an auth and account entry are required
606

    
607
# auth
608
auth            required        pam_nologin.so          no_warn
609
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
610
auth            requisite       pam_opieaccess.so       no_warn allow_local
611
auth            required        pam_unix.so             no_warn try_first_pass
612

    
613
# account
614
account         required        pam_unix.so
615

    
616
# session
617
session         required        pam_permit.so
618

    
619
# password
620
password        required        pam_unix.so             no_warn try_first_pass
621

    
622
EOD;
623

    
624
        file_put_contents("/etc/pam.d/php", $pam_php);
625
      } // end if
626

    
627
      if (pam_auth($username, $password, &$error)) {
628
        return true;
629
      } else {
630
        return false;
631
      }
632
    }
633
  }
634
}
635

    
636
function passwd_backed($username, $passwd) {
637
  $authfile = file("/etc/master.passwd");
638

    
639
  $matches="";
640

    
641
  /* Check to see if user even exists */
642
  if(!($line = array_shift(preg_grep("/^$username:.*$/", $authfile))))
643
    return false;
644

    
645
  /* Get crypted password */
646
  preg_match("/^$username:((\\$1\\$[.\d\w_\/]{8}\\$)[.\d\w_\/]{22})$/", $line, $matches);
647
  $pass = $matches[1];
648
  $salt = $matches[2];
649

    
650
  /* Encrypt entered password with salt
651
   * And finally validate password
652
   */
653
  if ($pass == crypt($passwd, $salt))
654
    return true;
655
  else
656
    return false;
657
}
658

    
659
function ldap_test_connection() {
660
	global $config, $g;
661

    
662
	$ldapserver = $config['system']['webgui']['ldapserver'];
663
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
664
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
665
	if (!($ldap = ldap_connect($ldapserver))) {
666
		return false;
667
	}
668

    
669
	return true;
670
}
671

    
672
function ldap_test_bind() {
673
	global $config, $g;
674

    
675
    $ldapserver = $config['system']['webgui']['ldapserver'];
676
    $ldapbindun = $config['system']['webgui']['ldapbindun'];
677
    $ldapbindpw = $config['system']['webgui']['ldapbindpw'];
678
    
679
    if (!($ldap = ldap_connect($ldapserver))) {
680
		return false;
681
    }
682

    
683
    ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
684
    ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
685
    
686
    if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
687
		return false;
688
    }
689

    
690
	return true;
691
}
692

    
693
function ldap_get_user_ous($show_complete_ou=true) {
694
	global $config, $g;
695

    
696
	if(!function_exists("ldap_connect"))
697
		return;
698

    
699
    $ldapserver     = $config['system']['webgui']['ldapserver'];
700
    $ldapbindun     = $config['system']['webgui']['ldapbindun'];
701
    $ldapbindpw     = $config['system']['webgui']['ldapbindpw'];
702
    $ldapsearchbase = "{$config['system']['webgui']['ldapsearchbase']}";
703
    $ldaptype       = $config['system']['webgui']['backend'];
704

    
705
    $ldapfilter = "(ou=*)";
706
    putenv('LDAPTLS_REQCERT=never');
707
    if (!($ldap = ldap_connect($ldapserver))) {
708
        log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in htpasswd_backed()");
709
            $status = htpasswd_backed($username, $passwd);
710
            return $status;
711
    }
712

    
713
    ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
714
    ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
715

    
716
    if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
717
        log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in htpasswd_backed()");
718
            $status = htpasswd_backed($username, $passwd);
719
            return $status;
720
    }
721

    
722
    $search = ldap_search($ldap, $ldapsearchbase, $ldapfilter);
723

    
724
    $info = ldap_get_entries($ldap, $search);
725

    
726
	$ous = array();
727

    
728
	if(is_array($info)) {
729
	    foreach($info as $inf) {
730
			if(!$show_complete_ou) {
731
	            $inf_split = split(",", $inf['dn']);
732
	            $ou = $inf_split[0];
733
	            $ou = str_replace("OU=","", $ou);
734
			} else {
735
				if($inf['dn'])
736
					$ou = $inf['dn'];
737
			}
738
			if($ou)
739
				$ous[] = $ou;
740
	    }
741
	}
742
	//Tack on the default Users container for AD since its non-standard
743
	if($ldaptype == 'ldap'){
744
	     $ous[] = "CN=Users," . $ldapsearchbase;
745
        }
746

    
747
	return $ous;
748
	
749
}
750

    
751
function ldap_get_groups($username) {
752
	global $config;
753
	
754
	if(!function_exists("ldap_connect"))
755
		return;
756
	
757
	if(!$username) 
758
		return false;
759

    
760
	if(stristr($username, "@")) {
761
		$username_split=split("\@", $username);
762
		$username = $username_split[0];		
763
	}
764
        if(stristr($username, "\\")) {
765
            $username_split=split("\\", $username);
766
            $username = $username_split[0];        
767
        }    
768
	
769
	//log_error("Getting LDAP groups for {$username}.");
770
	
771
	$ldapserver         = $config['system']['webgui']['ldapserver'];
772
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
773
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
774
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
775
	$ldapfilter         = str_replace("\$username", $username, $ldapfilter);
776
	$ldapgroupattribute = $config['system']['webgui']['ldapgroupattribute'];
777
	$ldapdn             = $_SESSION['ldapdn'];
778
	 
779
        /*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
780
        $ldapgroupattribute = strtolower($ldapgroupattribute);
781

    
782
	/* connect and see if server is up */
783
	putenv('LDAPTLS_REQCERT=never');
784
	if (!($ldap = ldap_connect($ldapserver))) {
785
	    log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in htpasswd_backed()");
786
		$status = htpasswd_backed($username, $passwd);
787
		return $status;	
788
	}
789
    
790
        ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
791
        ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
792

    
793
	/* bind as user that has rights to read group attributes */
794
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
795
	    log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in htpasswd_backed()");
796
		$status = htpasswd_backed($username, $passwd);
797
		return $status;
798
	}
799

    
800
	/* get groups from DN found */
801
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
802
	/* since we know the DN is in $_SESSION['ldapdn'] */
803
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
804
	$search    = ldap_read($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
805
        $info      = ldap_get_entries($ldap, $search);
806

    
807
        $countem = $info["count"];	
808
        $memberof = array();
809
	
810
	if(is_array($info[0][$ldapgroupattribute])) {
811

    
812
    	/* Iterate through the groups and throw them into an array */
813
    	foreach($info[0][$ldapgroupattribute] as $member) {
814
            	if(stristr($member, "CN=") !== false) {
815
                    	$membersplit = split(",", $member);
816
                    	$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
817
            	}
818
    	}
819
	}
820
	
821
	/* Time to close LDAP connection */
822
	ldap_close($ldap);
823
	
824
	$groups = print_r($memberof,true);
825
	
826
	//log_error("Returning groups " . $groups  . " for user $username");
827
	
828
	return $memberof;
829
}
830

    
831
function ldap_backed($username, $passwd) {
832
	global $config;
833
	
834
	if(!$username) 
835
		return;
836

    
837
	if(!function_exists("ldap_connect"))
838
		return;
839
    $adbindas = $username;
840
    
841
    if(stristr($username, "@")) {
842
        $username_split=split("\@", $username);
843
        $username = $username_split[0];        
844
    }
845
    if(stristr($username, "\\")) {
846
            $username_split=split("\\", $username);
847
            $username = $username_split[0];        
848
    }    
849
	$ldapserver         = $config['system']['webgui']['ldapserver'];
850
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
851
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
852
        $ldapauthcont       = $config['system']['webgui']['ldapauthcontainers'];   
853
        $ldapnameattribute  = $config['system']['webgui']['ldapnameattribute'];  
854
        $ldapfilter         = $config['system']['webgui']['ldapfilter'];
855
        $ldaptype           = $config['system']['webgui']['backend'];
856
        $ldapfilter = str_replace("\$username", $username, $ldapfilter);
857
        
858
        /* first check if there is even an LDAP server populated */ 
859
        if(!$ldapserver) {
860
		log_error("ERROR!  ldap_backed() backed selected with no LDAP authentication server defined.  Defaulting to built-in htpasswd_backed().     Visit System -> User Manager -> Settings.");
861
		$status = htpasswd_backed($username, $passwd);
862
		return $status;
863
	}
864
	
865
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
866
    	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
867

    
868
	/* Make sure we can connect to LDAP */
869
	putenv('LDAPTLS_REQCERT=never');
870
	if (!($ldap = ldap_connect($ldapserver))) {
871
	    log_error("ERROR!  ldap_backed() could not connect to server {$ldapserver} - {$ldapfilter}.  Defaulting to built-in htpasswd_backed().     Visit System -> User Manager -> Settings.");
872
		$status = htpasswd_backed($username, $passwd);		
873
		return $status;	
874
	}
875
	/* ok, its up.  now, lets bind as the bind user so we can search it */
876
	if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
877
	    log_error("ERROR! ldap_backed() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in htpasswd_backed()");
878
	        ldap_close($ldap);
879
		$status = htpasswd_backed($username, $passwd);
880
	 	return $status;
881
	}
882
	
883
	/* Get LDAP Authcontainers and split em up. */
884
        $ldac_split = split(";", $ldapauthcont);
885
	
886
	/* now count how many there are */
887
	$containers = count($ldac_split);
888
	log_error("Number of Authentication Containers to search for $username is {$containers}");
889
	
890
	/* setup the usercount so we think we havn't found anyone yet */
891
	$usercount  = 0;
892
        
893
        /******************************/
894
        /* Currently LDAP Types are   */
895
        /* LDAP = Active Directory    */
896
        /* LDAPOTHER = eDir/Openldap  */
897
        /******************************/      
898
        
899
        /*****************************************************************/
900
	/* Now Active Directory We keep this seperate for future addons. */
901
        /*****************************************************************/
902
        /* Now LDAP other.  eDirectory or Netscape or Sunone or OpenLDAP */
903
        /*****************************************************************/
904
        /*  We First find the user based on username and filter          */
905
        /*  Then, once we find the first occurance of that person        */
906
        /*  We set seesion variables to ponit to the OU and DN of the    */
907
        /*  Person.  To later be used by ldap_get_groups.                */
908
        /*  that way we don't have to search twice.                      */
909
        /*****************************************************************/
910
	if ($ldaptype == 'ldap'){
911
	   log_error("Now Searching for {$username} in Active directory.");
912
	   /* Iterate through the user containers for search */
913
	   for ($i=0;$i<$containers;$i++){
914
		/* Make sure we just use the first user we find */
915
		   log_error("Now Searching in {$ldac_split[$i]} for {$ldapfilter}.");
916
		   $search  = ldap_search($ldap,$ldac_split[$i],$ldapfilter);
917
                   $info    = ldap_get_entries($ldap,$search);
918
                   $matches = $info['count'];
919
                   log_error("Matches Found = {$matches}");
920
                   if ($matches == 1){
921
		      $_SESSION['ldapdn'] = $info[0]['dn'];
922
		      $_SESSION['ldapou'] = $ldac_split[$i];
923
		      $_SESSION['ldapon'] = "true";
924
		      $ldapdn = $_SESSION['ldapdn'];
925
                      $userou = $_SESSION['ldapou'];
926
                      break;
927
	           }
928
	   }
929
           if($matches == 1){
930
              $binduser = $adbindas;
931
              log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
932
	      } 
933
	   if($matches != 1){
934
	      log_error("ERROR! Either LDAP search failed, or multiple users were found");
935
	      $status = htpasswd_backed($username, $passwd);
936
	      $_SESSION['ldapon'] = "false";
937
	      ldap_close($ldap);
938
	      return $status;                         
939
	   }	   
940
	}	
941

    
942
        /*****************************************************************/
943
        /* Now LDAP other.  eDirectory or Netscape or Sunone or OpenLDAP */
944
        /*****************************************************************/
945
        /*  We First find the user based on username and filter          */
946
        /*  Then, once we find the first occurance of that person        */
947
        /*  We set seesion variables to ponit to the OU and DN of the    */
948
        /*  Person.  To later be used by ldap_get_groups.                */
949
        /*  that way we don't have to search twice.                      */
950
        /*****************************************************************/
951
	if ($ldaptype == 'ldapother'){
952
	   log_error("Now Searching for {$username} in LDAP.");
953
	   /* Iterate through the user containers for search */
954
	   for ($i=0;$i<$containers;$i++){
955
		/* Make sure we just use the first user we find */
956
		   log_error("Now searching in {$ldac_split[$i]} for {$ldapfilter}.");
957
		   $search  = ldap_search($ldap,$ldac_split[$i],$ldapfilter);
958
                   $info    = ldap_get_entries($ldap,$search);
959
                   $matches = $info['count'];
960
                   log_error("Matches Found = {$matches}.");
961
                                      
962
                   if ($matches == 1){
963
		      $_SESSION['ldapdn'] = $info[0]['dn'];
964
		      $_SESSION['ldapou'] = $ldac_split[$i];
965
		      $_SESSION['ldapon'] = "true";
966
		      $ldapdn = $_SESSION['ldapdn'];
967
                      $userou = $_SESSION['ldapou'];
968
                      break;
969
	           }
970
	   }
971
           if($matches == 1){
972
              $binduser = $ldapnameattribute."=".$username.",".$userou;
973
              log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
974
	      }
975
	   if($matches != 1){
976
	      log_error("ERROR! Either LDAP search failed, or multiple users were found");
977
	      $status = htpasswd_backed($username, $passwd);
978
	      ldap_close($ldap);
979
	      $_SESSION['ldapon'] = "false";
980
	      return $status;                         
981
	   }	   
982
	}	
983
		 
984
       
985
       /* Now lets bind as the user we found */
986
       if (!($res = @ldap_bind($ldap, $binduser, $passwd))) {
987
	   	    log_error("ERROR!  ldap_backed() could not bind to {$ldapserver} - {$username} - {$passwd}.  Defaulting to built-in htpasswd_backed().    Visit System -> User Manager -> Settings.");
988
	   		$status = htpasswd_backed($username, $passwd);
989
	  		return $status;
990
	}
991
	
992

    
993
	log_error("$binduser succesfully logged in via LDAP.");
994
	/* At this point we are bound to LDAP so the user was auth'd okay. */
995
	return true;
996
}
997

    
998
function htpasswd_backed($username, $passwd) {
999
  $authfile = file("/var/run/htpasswd");
1000

    
1001
  /* sanity check to ensure that /usr/local/www/.htpasswd doesn't exist */
1002
  unlink_if_exists("/usr/local/www/.htpasswd");
1003

    
1004
  $matches="";
1005
  if(!($line = array_shift(preg_grep("/^$username:.*$/", $authfile))))
1006
          return false;
1007

    
1008
  /* Get crypted password */
1009
  preg_match("/^$username:((\\$1\\$[.\d\w_\/]{8}\\$)[.\d\w_\/]{22})$/", $line, $matches);
1010
  $pass = $matches[1];
1011
  $salt = $matches[2];
1012

    
1013
  /* Encrypt entered password with salt
1014
   * And finally validate password
1015
   */
1016
  if ($pass == crypt($passwd, $salt))
1017
    return true;
1018
  else
1019
    return false;
1020
}
1021

    
1022
function radius_backed($username, $passwd){
1023
  global $config, $debug;
1024
  $ret = false;
1025
  $radiusservers = $config['system']['radius']['servers'];
1026

    
1027
  $rauth = new Auth_RADIUS_PAP($username, $passwd);
1028
  foreach ($radiusservers as $radsrv) {
1029
    // Add a new server to our instance
1030
    $rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
1031
  }
1032

    
1033
  if (!$rauth->start()) {
1034
    $retvalue['auth_val'] = 1;
1035
    $retvalue['error'] = $rauth->getError();
1036
    if ($debug)
1037
      printf("Radius start: %s<br>\n", $retvalue['error']);
1038
  }
1039

    
1040
  // XXX - billm - somewhere in here we need to handle securid challenge/response
1041

    
1042
  // Send request
1043
  $result = $rauth->send();
1044
  if (PEAR::isError($result)) {
1045
    $retvalue['auth_val'] = 1;
1046
    $retvalue['error'] = $result->getMessage();
1047
    if ($debug)
1048
      printf("Radius send failed: %s<br>\n", $retvalue['error']);
1049
  } else if ($result === true) {
1050
    $retvalue['auth_val'] = 2;
1051
    if ($debug)
1052
      printf (gettext("Radius Auth succeeded") . "<br>\n");
1053
    $ret = true;
1054
  } else {
1055
      $retvalue['auth_val'] = 3;
1056
      if ($debug)
1057
        printf (gettext("Radius Auth rejected") . "<br>\n");
1058
  }
1059
  // close OO RADIUS_AUTHENTICATION
1060
  $rauth->close();
1061

    
1062
  return $ret;
1063
}
1064

    
1065

    
1066
function index_groups() {
1067
  global $g, $config, $groupindex;
1068

    
1069
  $groupindex = array();
1070

    
1071
  if (isset($config['system']['group'])) {
1072
    $i = 0;
1073
    foreach($config['system']['group'] as $groupent) {
1074
      $groupindex[$groupent['name']] = $i;
1075
      $i++;
1076
    }
1077
  }
1078
  return ($groupindex);
1079
}
1080

    
1081
function index_users() {
1082
  global $g, $config;
1083

    
1084
  if (isset($config['system']['user'])) {
1085
    $i = 0;
1086
    foreach($config['system']['user'] as $userent) {
1087
      $userindex[$userent['name']] = $i;
1088
      $i++;
1089
    }
1090
  }
1091
  return ($userindex);
1092
}
1093

    
1094
?>
(3-3/29)