Project

General

Profile

Download (35.6 KB) Statistics
| Branch: | Tag: | Revision:
1 b0ed07d1 Scott Ullrich
<?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 a720f012 Scott Ullrich
	$ldapon = $_SESSION['ldapon'];
70 01764862 Scott Ullrich
	//log_error("Getting groups for {$logged_in_user}.");
71 b0ed07d1 Scott Ullrich
	
72 a720f012 Scott Ullrich
	
73
	
74 b0ed07d1 Scott Ullrich
	$local_user = false;
75
	
76 01764862 Scott Ullrich
	//log_error("Local_user = {$local_user}");
77 a720f012 Scott Ullrich
	
78 b0ed07d1 Scott Ullrich
	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 01764862 Scott Ullrich
		//log_error("Calling LDAP_GET_GROUPS from the first section");
85 b0ed07d1 Scott Ullrich
		$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 01764862 Scott Ullrich
		//log_error("Calling LDAP_GET_GROUPS from the first section");
103 b0ed07d1 Scott Ullrich
		$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 5a6df9fa Bill Marquette
      log_error("Successful login for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
437 b0ed07d1 Scott Ullrich
    } else {
438
      /* give the user a more detailed error message */
439
      if (isset($userindex[$_POST['usernamefld']])) {
440 5a6df9fa Bill Marquette
        $_SESSION['Login_Error'] = "Username or Password incorrect";
441
	log_error("Wrong password entered for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
442
        if(isAjax()) {
443
        	echo "showajaxmessage('{$_SESSION['Login_Error']}');";
444
        	return;
445 b0ed07d1 Scott Ullrich
        }
446
      } else {
447 5a6df9fa Bill Marquette
        $_SESSION['Login_Error'] = "Username or Password incorrect";
448
	log_error("Attempted login for invalid user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
449
        if(isAjax()) {
450
                echo "showajaxmessage('{$_SESSION['Login_Error']}');";
451
        	return;
452 b0ed07d1 Scott Ullrich
        }
453
      }
454
    }
455
  }
456
457
  /* Show login page if they aren't logged in */
458
  if (empty($_SESSION['Logged_In'])) {
459
    /* Don't display login forms to AJAX */
460
    if (isAjax())
461
      return false;
462
    require_once("authgui.inc");
463
    display_login_form();
464
    return false;
465
  } else {
466
    /* If session timeout isn't set, we don't mark sessions stale */
467
    if (!isset($config['system']['webgui']['session_timeout']) or
468
       $config['system']['webgui']['session_timeout'] == 0 or
469
       $config['system']['webgui']['session_timeout'] == "")
470
       $_SESSION['last_access'] = time();
471
     else
472
       /* Check for stale session */
473 5a6df9fa Bill Marquette
       if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
474 b0ed07d1 Scott Ullrich
         $_GET['logout'] = true;
475 5a6df9fa Bill Marquette
         $_SESSION['Logout'] = true;
476
       } else
477 b0ed07d1 Scott Ullrich
         /* only update if it wasn't ajax */
478
         if (!isAjax())
479
           $_SESSION['last_access'] = time();
480
481
    /* user hit the logout button */
482
    if (isset($_GET['logout'])) {
483 5a6df9fa Bill Marquette
      if ($_SESSION['Logout'])
484
        log_error("Session timed out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
485
      else
486
        log_error("User logged out for user '{$_SESSION['Username']}' from: {$_SERVER['REMOTE_ADDR']}");
487
      
488 b0ed07d1 Scott Ullrich
      if (hasLockAbility($_SESSION['Username'])) {
489
        unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
490
      }
491
492
      /* wipe out $_SESSION */
493
      $_SESSION = array();
494
495
      if (isset($_COOKIE[session_name()])) {
496
        setcookie(session_name(), '', time()-42000, '/');
497
      }
498
499
      /* and destroy it */
500
      session_destroy();
501
502
      $scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
503
      $scriptElms = count($scriptName);
504
      $scriptName = $scriptName[$scriptElms-1];
505
506
      if (isAjax())
507
        return false;
508
509
      /* redirect to page the user is on, it'll prompt them to login again */
510
      pfSenseHeader($scriptName);
511
512
      return false;
513
514
    /* user wants to explicitely delete the log file.
515
     * Requires a particular privilege.
516
     */
517
    } else if ($_GET['deletelock'] && hasLockAbility($_SESSION['Username'])) {
518
      unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
519
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
520
      return true;
521
522
    /* this is for debugging purpose if you do not want to use Ajax
523
     * to submit a HTML form. It basically diables the observation
524
     * of the submit event and hence does not trigger Ajax.
525
     */
526
    } else if ($_GET['disable_ajax']) {
527
      $_SESSION['NO_AJAX'] = "True";
528
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
529
      return true;
530
531
    /* Same to re-enable Ajax.
532
     */
533
    } else if ($_GET['enable_ajax']) {
534
      unset($_SESSION['NO_AJAX']);
535
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
536
      return true;
537
538
    /* user wants to explicitely create a lock.
539
     * Requires a particular privilege.
540
     */
541
    } else if ($_GET['createlock'] && hasLockAbility($_SESSION['Username'])) {
542
      $fd = fopen("{$g['tmp_path']}/webconfigurator.lock", "w");
543
      fputs($fd, "{$_SERVER['REMOTE_ADDR']} (" .
544
                 getRealName($_SESSION['Username']) . ")");
545
      fclose($fd);
546
      /* if the user did delete the lock manually, do not
547
       * re-create it while the session is valide.
548
       */
549
      $_SESSION['Lock_Created'] = "True";
550
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
551
      return true;
552
553
    /* proceed with the login process */
554
    } else {
555
      /* if the user is allowed to create a lock,
556
       * create it once per session.
557
       */
558
      if (hasLockAbility($_SESSION['Username']) &&
559
          ! isset($_SESSION['Lock_Created'])) {
560
561
        $fd = fopen("{$g['tmp_path']}/webconfigurator.lock", "w");
562
        fputs($fd, "{$_SERVER['REMOTE_ADDR']} (" .
563
                   getRealName($_SESSION['Username']) . ")");
564
        fclose($fd);
565
        /* if the user did delete the lock manually, do not
566
         * re-create it while the session is valide.
567
         */
568
        $_SESSION['Lock_Created'] = "True";
569
570
      /* give regular users a chance to automatically invalidate
571
       * a lock if its older than a particular time.
572
       */
573
      } else if (! hasLockAbility($_SESSION['Username']) &&
574
                 file_exists("{$g['tmp_path']}/webconfigurator.lock")) {
575
576
        $offset = 12; //hours
577
        $mtime = filemtime("{$g['tmp_path']}/webconfigurator.lock");
578
        $now_minus_offset = mktime(date("H") - $offset, 0, 0, date("m"), date("d"), date("Y"));
579
580
        if (($mtime - $now_minus_offset) < $mtime) {
581
          require_once("authgui.inc");
582
          display_login_form();
583
          return false;
584
        } else {
585
          /* file is older than mtime + offset which may
586
           * indicate a stale lockfile, hence we are going
587
           * to remove it.
588
           */
589
           unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
590
        }
591
      }
592
593
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
594
      return true;
595
    }
596
  }
597
}
598
599
function pam_backed($username = "", $password = "") {
600
  /* do not allow blank passwords */
601
  if ($username == "" || password == "") { return false; }
602
603
  if(! extension_loaded( 'pam_auth' )) {
604
    if(! @dl( 'pam_auth.so' )) {
605
      return false;
606
    } else {
607
      /* no php file no auth, sorry */
608
      if (! file_exists("/etc/pam.d/php")) {
609
        if (! file_exists("/etc/pam.d")) { mkdir("/etc/pam.d"); }
610
611
        $pam_php = <<<EOD
612
# /etc/pam.d/php
613
#
614
# note: both an auth and account entry are required
615
616
# auth
617
auth            required        pam_nologin.so          no_warn
618
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
619
auth            requisite       pam_opieaccess.so       no_warn allow_local
620
auth            required        pam_unix.so             no_warn try_first_pass
621
622
# account
623
account         required        pam_unix.so
624
625
# session
626
session         required        pam_permit.so
627
628
# password
629
password        required        pam_unix.so             no_warn try_first_pass
630
631
EOD;
632
633
        file_put_contents("/etc/pam.d/php", $pam_php);
634
      } // end if
635
636
      if (pam_auth($username, $password, &$error)) {
637
        return true;
638
      } else {
639
        return false;
640
      }
641
    }
642
  }
643
}
644
645
function passwd_backed($username, $passwd) {
646
  $authfile = file("/etc/master.passwd");
647
648
  $matches="";
649
650
  /* Check to see if user even exists */
651
  if(!($line = array_shift(preg_grep("/^$username:.*$/", $authfile))))
652
    return false;
653
654
  /* Get crypted password */
655
  preg_match("/^$username:((\\$1\\$[.\d\w_\/]{8}\\$)[.\d\w_\/]{22})$/", $line, $matches);
656
  $pass = $matches[1];
657
  $salt = $matches[2];
658
659
  /* Encrypt entered password with salt
660
   * And finally validate password
661
   */
662
  if ($pass == crypt($passwd, $salt))
663
    return true;
664
  else
665
    return false;
666
}
667
668
function ldap_test_connection() {
669
	global $config, $g;
670
671
	$ldapserver = $config['system']['webgui']['ldapserver'];
672
	$ldapbindun = $config['system']['webgui']['ldapbindun'];
673
	$ldapbindpw = $config['system']['webgui']['ldapbindpw'];
674
	if (!($ldap = ldap_connect($ldapserver))) {
675
		return false;
676
	}
677
678
	return true;
679
}
680
681
function ldap_test_bind() {
682
	global $config, $g;
683
684
    $ldapserver = $config['system']['webgui']['ldapserver'];
685
    $ldapbindun = $config['system']['webgui']['ldapbindun'];
686
    $ldapbindpw = $config['system']['webgui']['ldapbindpw'];
687 a720f012 Scott Ullrich
    
688 b0ed07d1 Scott Ullrich
    if (!($ldap = ldap_connect($ldapserver))) {
689
		return false;
690
    }
691
692
    ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
693
    ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
694 a720f012 Scott Ullrich
    
695 b0ed07d1 Scott Ullrich
    if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
696
		return false;
697
    }
698
699
	return true;
700
}
701
702 a720f012 Scott Ullrich
function ldap_get_user_ous($show_complete_ou=true) {
703 b0ed07d1 Scott Ullrich
	global $config, $g;
704
705
	if(!function_exists("ldap_connect"))
706
		return;
707
708 01764862 Scott Ullrich
    $ldapserver     = $config['system']['webgui']['ldapserver'];
709
    $ldapbindun     = $config['system']['webgui']['ldapbindun'];
710
    $ldapbindpw     = $config['system']['webgui']['ldapbindpw'];
711 4989bc66 Scott Ullrich
    $ldapsearchbase = "{$config['system']['webgui']['ldapsearchbase']}";
712 01764862 Scott Ullrich
    $ldaptype       = $config['system']['webgui']['backend'];
713 b0ed07d1 Scott Ullrich
714
    $ldapfilter = "(ou=*)";
715 01764862 Scott Ullrich
    putenv('LDAPTLS_REQCERT=never');
716 b0ed07d1 Scott Ullrich
    if (!($ldap = ldap_connect($ldapserver))) {
717
        log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in htpasswd_backed()");
718
            $status = htpasswd_backed($username, $passwd);
719
            return $status;
720
    }
721
722
    ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
723
    ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
724
725
    if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
726
        log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in htpasswd_backed()");
727
            $status = htpasswd_backed($username, $passwd);
728
            return $status;
729
    }
730
731
    $search = ldap_search($ldap, $ldapsearchbase, $ldapfilter);
732
733
    $info = ldap_get_entries($ldap, $search);
734
735
	$ous = array();
736
737
	if(is_array($info)) {
738
	    foreach($info as $inf) {
739
			if(!$show_complete_ou) {
740
	            $inf_split = split(",", $inf['dn']);
741
	            $ou = $inf_split[0];
742
	            $ou = str_replace("OU=","", $ou);
743
			} else {
744
				if($inf['dn'])
745
					$ou = $inf['dn'];
746
			}
747
			if($ou)
748
				$ous[] = $ou;
749
	    }
750
	}
751 01764862 Scott Ullrich
	//Tack on the default Users container for AD since its non-standard
752
	if($ldaptype == 'ldap'){
753
	     $ous[] = "CN=Users," . $ldapsearchbase;
754
        }
755
756 b0ed07d1 Scott Ullrich
	return $ous;
757
	
758
}
759
760
function ldap_get_groups($username) {
761
	global $config;
762
	
763
	if(!function_exists("ldap_connect"))
764
		return;
765
	
766
	if(!$username) 
767
		return false;
768
769
	if(stristr($username, "@")) {
770
		$username_split=split("\@", $username);
771
		$username = $username_split[0];		
772
	}
773 a720f012 Scott Ullrich
        if(stristr($username, "\\")) {
774
            $username_split=split("\\", $username);
775
            $username = $username_split[0];        
776
        }    
777 b0ed07d1 Scott Ullrich
	
778 01764862 Scott Ullrich
	//log_error("Getting LDAP groups for {$username}.");
779 b0ed07d1 Scott Ullrich
	
780 4989bc66 Scott Ullrich
	$ldapserver         = $config['system']['webgui']['ldapserver'];
781
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
782
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
783
	$ldapfilter         = $config['system']['webgui']['ldapfilter'];
784
	$ldapfilter         = str_replace("\$username", $username, $ldapfilter);
785 b0ed07d1 Scott Ullrich
	$ldapgroupattribute = $config['system']['webgui']['ldapgroupattribute'];
786 4989bc66 Scott Ullrich
	$ldapdn             = $_SESSION['ldapdn'];
787
	 
788 b0ed07d1 Scott Ullrich
        /*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
789
        $ldapgroupattribute = strtolower($ldapgroupattribute);
790
791 4989bc66 Scott Ullrich
	/* connect and see if server is up */
792 01764862 Scott Ullrich
	putenv('LDAPTLS_REQCERT=never');
793 b0ed07d1 Scott Ullrich
	if (!($ldap = ldap_connect($ldapserver))) {
794
	    log_error("ERROR!  ldap_get_groups() could not connect to server {$ldapserver}.  Defaulting to built-in htpasswd_backed()");
795
		$status = htpasswd_backed($username, $passwd);
796
		return $status;	
797
	}
798 4989bc66 Scott Ullrich
    
799
        ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
800
        ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
801 b0ed07d1 Scott Ullrich
802 4989bc66 Scott Ullrich
	/* bind as user that has rights to read group attributes */
803 b0ed07d1 Scott Ullrich
	if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
804
	    log_error("ERROR! ldap_get_groups() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in htpasswd_backed()");
805
		$status = htpasswd_backed($username, $passwd);
806
		return $status;
807
	}
808
809 4989bc66 Scott Ullrich
	/* get groups from DN found */
810
	/* use ldap_read instead of search so we don't have to do a bunch of extra work */
811
	/* since we know the DN is in $_SESSION['ldapdn'] */
812 01764862 Scott Ullrich
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
813
	$search    = ldap_read($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
814 4989bc66 Scott Ullrich
        $info      = ldap_get_entries($ldap, $search);
815 b0ed07d1 Scott Ullrich
816 4989bc66 Scott Ullrich
        $countem = $info["count"];	
817
        $memberof = array();
818 b0ed07d1 Scott Ullrich
	
819
	if(is_array($info[0][$ldapgroupattribute])) {
820 4989bc66 Scott Ullrich
821
    	/* Iterate through the groups and throw them into an array */
822 b0ed07d1 Scott Ullrich
    	foreach($info[0][$ldapgroupattribute] as $member) {
823
            	if(stristr($member, "CN=") !== false) {
824
                    	$membersplit = split(",", $member);
825
                    	$memberof[] = preg_replace("/CN=/i", "", $membersplit[0]);
826
            	}
827
    	}
828
	}
829
	
830
	/* Time to close LDAP connection */
831
	ldap_close($ldap);
832
	
833
	$groups = print_r($memberof,true);
834
	
835 01764862 Scott Ullrich
	//log_error("Returning groups " . $groups  . " for user $username");
836 b0ed07d1 Scott Ullrich
	
837
	return $memberof;
838
}
839
840
function ldap_backed($username, $passwd) {
841
	global $config;
842
	
843
	if(!$username) 
844
		return;
845
846
	if(!function_exists("ldap_connect"))
847
		return;
848 4989bc66 Scott Ullrich
    $adbindas = $username;
849
    
850
    if(stristr($username, "@")) {
851
        $username_split=split("\@", $username);
852
        $username = $username_split[0];        
853
    }
854 a720f012 Scott Ullrich
    if(stristr($username, "\\")) {
855
            $username_split=split("\\", $username);
856
            $username = $username_split[0];        
857
    }    
858 4989bc66 Scott Ullrich
	$ldapserver         = $config['system']['webgui']['ldapserver'];
859
	$ldapbindun         = $config['system']['webgui']['ldapbindun'];
860
	$ldapbindpw         = $config['system']['webgui']['ldapbindpw'];
861
        $ldapauthcont       = $config['system']['webgui']['ldapauthcontainers'];   
862
        $ldapnameattribute  = $config['system']['webgui']['ldapnameattribute'];  
863
        $ldapfilter         = $config['system']['webgui']['ldapfilter'];
864
        $ldaptype           = $config['system']['webgui']['backend'];
865
        $ldapfilter = str_replace("\$username", $username, $ldapfilter);
866
        
867
        /* first check if there is even an LDAP server populated */ 
868
        if(!$ldapserver) {
869 b0ed07d1 Scott Ullrich
		log_error("ERROR!  ldap_backed() backed selected with no LDAP authentication server defined.  Defaulting to built-in htpasswd_backed().     Visit System -> User Manager -> Settings.");
870
		$status = htpasswd_backed($username, $passwd);
871
		return $status;
872
	}
873
	
874 4989bc66 Scott Ullrich
	ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
875
    	ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
876
877
	/* Make sure we can connect to LDAP */
878 01764862 Scott Ullrich
	putenv('LDAPTLS_REQCERT=never');
879 b0ed07d1 Scott Ullrich
	if (!($ldap = ldap_connect($ldapserver))) {
880
	    log_error("ERROR!  ldap_backed() could not connect to server {$ldapserver} - {$ldapfilter}.  Defaulting to built-in htpasswd_backed().     Visit System -> User Manager -> Settings.");
881 4989bc66 Scott Ullrich
		$status = htpasswd_backed($username, $passwd);		
882 b0ed07d1 Scott Ullrich
		return $status;	
883
	}
884 4989bc66 Scott Ullrich
	/* ok, its up.  now, lets bind as the bind user so we can search it */
885
	if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
886 01764862 Scott Ullrich
	    log_error("ERROR! ldap_backed() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in htpasswd_backed()");
887 a720f012 Scott Ullrich
	        ldap_close($ldap);
888 b0ed07d1 Scott Ullrich
		$status = htpasswd_backed($username, $passwd);
889 a720f012 Scott Ullrich
	 	return $status;
890 b0ed07d1 Scott Ullrich
	}
891 a720f012 Scott Ullrich
	
892
	/* Get LDAP Authcontainers and split em up. */
893
        $ldac_split = split(";", $ldapauthcont);
894
	
895
	/* now count how many there are */
896
	$containers = count($ldac_split);
897 01764862 Scott Ullrich
	log_error("Number of Authentication Containers to search for $username is {$containers}");
898 a720f012 Scott Ullrich
	
899
	/* setup the usercount so we think we havn't found anyone yet */
900 4989bc66 Scott Ullrich
	$usercount  = 0;
901 a720f012 Scott Ullrich
        
902
        /******************************/
903 4989bc66 Scott Ullrich
        /* Currently LDAP Types are   */
904
        /* LDAP = Active Directory    */
905
        /* LDAPOTHER = eDir/Openldap  */
906 a720f012 Scott Ullrich
        /******************************/      
907
        
908
        /*****************************************************************/
909 4989bc66 Scott Ullrich
	/* Now Active Directory We keep this seperate for future addons. */
910
        /*****************************************************************/
911
        /* Now LDAP other.  eDirectory or Netscape or Sunone or OpenLDAP */
912
        /*****************************************************************/
913
        /*  We First find the user based on username and filter          */
914
        /*  Then, once we find the first occurance of that person        */
915
        /*  We set seesion variables to ponit to the OU and DN of the    */
916
        /*  Person.  To later be used by ldap_get_groups.                */
917
        /*  that way we don't have to search twice.                      */
918
        /*****************************************************************/
919
	if ($ldaptype == 'ldap'){
920
	   log_error("Now Searching for {$username} in Active directory.");
921
	   /* Iterate through the user containers for search */
922
	   for ($i=0;$i<$containers;$i++){
923
		/* Make sure we just use the first user we find */
924 01764862 Scott Ullrich
		   log_error("Now Searching in {$ldac_split[$i]} for {$ldapfilter}.");
925 4989bc66 Scott Ullrich
		   $search  = ldap_search($ldap,$ldac_split[$i],$ldapfilter);
926
                   $info    = ldap_get_entries($ldap,$search);
927
                   $matches = $info['count'];
928
                   log_error("Matches Found = {$matches}");
929
                   if ($matches == 1){
930
		      $_SESSION['ldapdn'] = $info[0]['dn'];
931
		      $_SESSION['ldapou'] = $ldac_split[$i];
932 a720f012 Scott Ullrich
		      $_SESSION['ldapon'] = "true";
933 4989bc66 Scott Ullrich
		      $ldapdn = $_SESSION['ldapdn'];
934
                      $userou = $_SESSION['ldapou'];
935
                      break;
936
	           }
937
	   }
938 a720f012 Scott Ullrich
           if($matches == 1){
939 4989bc66 Scott Ullrich
              $binduser = $adbindas;
940 01764862 Scott Ullrich
              log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
941 a720f012 Scott Ullrich
	      } 
942
	   if($matches != 1){
943 4989bc66 Scott Ullrich
	      log_error("ERROR! Either LDAP search failed, or multiple users were found");
944
	      $status = htpasswd_backed($username, $passwd);
945 a720f012 Scott Ullrich
	      $_SESSION['ldapon'] = "false";
946
	      ldap_close($ldap);
947 4989bc66 Scott Ullrich
	      return $status;                         
948
	   }	   
949
	}	
950
951
        /*****************************************************************/
952
        /* Now LDAP other.  eDirectory or Netscape or Sunone or OpenLDAP */
953
        /*****************************************************************/
954
        /*  We First find the user based on username and filter          */
955
        /*  Then, once we find the first occurance of that person        */
956
        /*  We set seesion variables to ponit to the OU and DN of the    */
957
        /*  Person.  To later be used by ldap_get_groups.                */
958
        /*  that way we don't have to search twice.                      */
959
        /*****************************************************************/
960
	if ($ldaptype == 'ldapother'){
961
	   log_error("Now Searching for {$username} in LDAP.");
962
	   /* Iterate through the user containers for search */
963
	   for ($i=0;$i<$containers;$i++){
964
		/* Make sure we just use the first user we find */
965 01764862 Scott Ullrich
		   log_error("Now searching in {$ldac_split[$i]} for {$ldapfilter}.");
966 4989bc66 Scott Ullrich
		   $search  = ldap_search($ldap,$ldac_split[$i],$ldapfilter);
967
                   $info    = ldap_get_entries($ldap,$search);
968
                   $matches = $info['count'];
969
                   log_error("Matches Found = {$matches}.");
970
                                      
971
                   if ($matches == 1){
972
		      $_SESSION['ldapdn'] = $info[0]['dn'];
973
		      $_SESSION['ldapou'] = $ldac_split[$i];
974 a720f012 Scott Ullrich
		      $_SESSION['ldapon'] = "true";
975 4989bc66 Scott Ullrich
		      $ldapdn = $_SESSION['ldapdn'];
976
                      $userou = $_SESSION['ldapou'];
977
                      break;
978
	           }
979
	   }
980
           if($matches == 1){
981
              $binduser = $ldapnameattribute."=".$username.",".$userou;
982 01764862 Scott Ullrich
              log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
983 a720f012 Scott Ullrich
	      }
984
	   if($matches != 1){
985 4989bc66 Scott Ullrich
	      log_error("ERROR! Either LDAP search failed, or multiple users were found");
986
	      $status = htpasswd_backed($username, $passwd);
987 a720f012 Scott Ullrich
	      ldap_close($ldap);
988
	      $_SESSION['ldapon'] = "false";
989 4989bc66 Scott Ullrich
	      return $status;                         
990
	   }	   
991
	}	
992
		 
993
       
994
       /* Now lets bind as the user we found */
995
       if (!($res = @ldap_bind($ldap, $binduser, $passwd))) {
996
	   	    log_error("ERROR!  ldap_backed() could not bind to {$ldapserver} - {$username} - {$passwd}.  Defaulting to built-in htpasswd_backed().    Visit System -> User Manager -> Settings.");
997
	   		$status = htpasswd_backed($username, $passwd);
998 a720f012 Scott Ullrich
	  		return $status;
999 4989bc66 Scott Ullrich
	}
1000 a720f012 Scott Ullrich
	
1001
1002 01764862 Scott Ullrich
	log_error("$binduser succesfully logged in via LDAP.");
1003 a720f012 Scott Ullrich
	/* At this point we are bound to LDAP so the user was auth'd okay. */
1004 b0ed07d1 Scott Ullrich
	return true;
1005
}
1006
1007
function htpasswd_backed($username, $passwd) {
1008
  $authfile = file("/var/run/htpasswd");
1009
1010
  /* sanity check to ensure that /usr/local/www/.htpasswd doesn't exist */
1011
  unlink_if_exists("/usr/local/www/.htpasswd");
1012
1013
  $matches="";
1014
  if(!($line = array_shift(preg_grep("/^$username:.*$/", $authfile))))
1015
          return false;
1016
1017
  /* Get crypted password */
1018
  preg_match("/^$username:((\\$1\\$[.\d\w_\/]{8}\\$)[.\d\w_\/]{22})$/", $line, $matches);
1019
  $pass = $matches[1];
1020
  $salt = $matches[2];
1021
1022
  /* Encrypt entered password with salt
1023
   * And finally validate password
1024
   */
1025
  if ($pass == crypt($passwd, $salt))
1026
    return true;
1027
  else
1028
    return false;
1029
}
1030
1031
function radius_backed($username, $passwd){
1032
  global $config, $debug;
1033
  $ret = false;
1034
  $radiusservers = $config['system']['radius']['servers'];
1035
1036
  $rauth = new Auth_RADIUS_PAP($username, $passwd);
1037
  foreach ($radiusservers as $radsrv) {
1038
    // Add a new server to our instance
1039
    $rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
1040
  }
1041
1042
  if (!$rauth->start()) {
1043
    $retvalue['auth_val'] = 1;
1044
    $retvalue['error'] = $rauth->getError();
1045
    if ($debug)
1046
      printf("Radius start: %s<br>\n", $retvalue['error']);
1047
  }
1048
1049
  // XXX - billm - somewhere in here we need to handle securid challenge/response
1050
1051
  // Send request
1052
  $result = $rauth->send();
1053
  if (PEAR::isError($result)) {
1054
    $retvalue['auth_val'] = 1;
1055
    $retvalue['error'] = $result->getMessage();
1056
    if ($debug)
1057
      printf("Radius send failed: %s<br>\n", $retvalue['error']);
1058
  } else if ($result === true) {
1059
    $retvalue['auth_val'] = 2;
1060
    if ($debug)
1061
      printf (gettext("Radius Auth succeeded") . "<br>\n");
1062
    $ret = true;
1063
  } else {
1064
      $retvalue['auth_val'] = 3;
1065
      if ($debug)
1066
        printf (gettext("Radius Auth rejected") . "<br>\n");
1067
  }
1068
  // close OO RADIUS_AUTHENTICATION
1069
  $rauth->close();
1070
1071
  return $ret;
1072
}
1073
1074
1075
function index_groups() {
1076
  global $g, $config, $groupindex;
1077
1078
  $groupindex = array();
1079
1080
  if (isset($config['system']['group'])) {
1081
    $i = 0;
1082
    foreach($config['system']['group'] as $groupent) {
1083
      $groupindex[$groupent['name']] = $i;
1084
      $i++;
1085
    }
1086
  }
1087
  return ($groupindex);
1088
}
1089
1090
function index_users() {
1091
  global $g, $config;
1092
1093
  if (isset($config['system']['user'])) {
1094
    $i = 0;
1095
    foreach($config['system']['user'] as $userent) {
1096
      $userindex[$userent['name']] = $i;
1097
      $i++;
1098
    }
1099
  }
1100
  return ($userindex);
1101
}
1102
1103 4989bc66 Scott Ullrich
?>