Project

General

Profile

Download (35.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

    
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
      log_error("Successful login for user '{$_POST['usernamefld']}' from: {$_SERVER['REMOTE_ADDR']}");
437
    } else {
438
      /* give the user a more detailed error message */
439
      if (isset($userindex[$_POST['usernamefld']])) {
440
        $_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
        }
446
      } else {
447
        $_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
        }
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
       if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) {
474
         $_GET['logout'] = true;
475
         $_SESSION['Logout'] = true;
476
       } else
477
         /* 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
      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
      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
    
688
    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
    
695
    if (!($res = @ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
696
		return false;
697
    }
698

    
699
	return true;
700
}
701

    
702
function ldap_get_user_ous($show_complete_ou=true) {
703
	global $config, $g;
704

    
705
	if(!function_exists("ldap_connect"))
706
		return;
707

    
708
    $ldapserver     = $config['system']['webgui']['ldapserver'];
709
    $ldapbindun     = $config['system']['webgui']['ldapbindun'];
710
    $ldapbindpw     = $config['system']['webgui']['ldapbindpw'];
711
    $ldapsearchbase = "{$config['system']['webgui']['ldapsearchbase']}";
712
    $ldaptype       = $config['system']['webgui']['backend'];
713

    
714
    $ldapfilter = "(ou=*)";
715
    putenv('LDAPTLS_REQCERT=never');
716
    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
	//Tack on the default Users container for AD since its non-standard
752
	if($ldaptype == 'ldap'){
753
	     $ous[] = "CN=Users," . $ldapsearchbase;
754
        }
755

    
756
	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
        if(stristr($username, "\\")) {
774
            $username_split=split("\\", $username);
775
            $username = $username_split[0];        
776
        }    
777
	
778
	//log_error("Getting LDAP groups for {$username}.");
779
	
780
	$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
	$ldapgroupattribute = $config['system']['webgui']['ldapgroupattribute'];
786
	$ldapdn             = $_SESSION['ldapdn'];
787
	 
788
        /*Convert attribute to lowercase.  php ldap arrays put everything in lowercase */
789
        $ldapgroupattribute = strtolower($ldapgroupattribute);
790

    
791
	/* connect and see if server is up */
792
	putenv('LDAPTLS_REQCERT=never');
793
	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
    
799
        ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
800
        ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
801

    
802
	/* bind as user that has rights to read group attributes */
803
	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
	/* 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
	//$search    = ldap_read($ldap, $ldapdn, "(objectclass=*)", array($ldapgroupattribute));
813
	$search    = ldap_read($ldap, $ldapdn, $ldapfilter, array($ldapgroupattribute));
814
        $info      = ldap_get_entries($ldap, $search);
815

    
816
        $countem = $info["count"];	
817
        $memberof = array();
818
	
819
	if(is_array($info[0][$ldapgroupattribute])) {
820

    
821
    	/* Iterate through the groups and throw them into an array */
822
    	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
	//log_error("Returning groups " . $groups  . " for user $username");
836
	
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
    $adbindas = $username;
849
    
850
    if(stristr($username, "@")) {
851
        $username_split=split("\@", $username);
852
        $username = $username_split[0];        
853
    }
854
    if(stristr($username, "\\")) {
855
            $username_split=split("\\", $username);
856
            $username = $username_split[0];        
857
    }    
858
	$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
		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
	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
	putenv('LDAPTLS_REQCERT=never');
879
	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
		$status = htpasswd_backed($username, $passwd);		
882
		return $status;	
883
	}
884
	/* ok, its up.  now, lets bind as the bind user so we can search it */
885
	if (!($res = ldap_bind($ldap, $ldapbindun, $ldapbindpw))) {
886
	    log_error("ERROR! ldap_backed() could not bind to {$ldapserver} - {$ldapfilter}.  Defaulting to built-in htpasswd_backed()");
887
	        ldap_close($ldap);
888
		$status = htpasswd_backed($username, $passwd);
889
	 	return $status;
890
	}
891
	
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
	log_error("Number of Authentication Containers to search for $username is {$containers}");
898
	
899
	/* setup the usercount so we think we havn't found anyone yet */
900
	$usercount  = 0;
901
        
902
        /******************************/
903
        /* Currently LDAP Types are   */
904
        /* LDAP = Active Directory    */
905
        /* LDAPOTHER = eDir/Openldap  */
906
        /******************************/      
907
        
908
        /*****************************************************************/
909
	/* 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
		   log_error("Now Searching in {$ldac_split[$i]} for {$ldapfilter}.");
925
		   $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
		      $_SESSION['ldapon'] = "true";
933
		      $ldapdn = $_SESSION['ldapdn'];
934
                      $userou = $_SESSION['ldapou'];
935
                      break;
936
	           }
937
	   }
938
           if($matches == 1){
939
              $binduser = $adbindas;
940
              log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
941
	      } 
942
	   if($matches != 1){
943
	      log_error("ERROR! Either LDAP search failed, or multiple users were found");
944
	      $status = htpasswd_backed($username, $passwd);
945
	      $_SESSION['ldapon'] = "false";
946
	      ldap_close($ldap);
947
	      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
		   log_error("Now searching in {$ldac_split[$i]} for {$ldapfilter}.");
966
		   $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
		      $_SESSION['ldapon'] = "true";
975
		      $ldapdn = $_SESSION['ldapdn'];
976
                      $userou = $_SESSION['ldapou'];
977
                      break;
978
	           }
979
	   }
980
           if($matches == 1){
981
              $binduser = $ldapnameattribute."=".$username.",".$userou;
982
              log_error("Going to login as {$username} - DN = {$_SESSION['ldapdn']}");
983
	      }
984
	   if($matches != 1){
985
	      log_error("ERROR! Either LDAP search failed, or multiple users were found");
986
	      $status = htpasswd_backed($username, $passwd);
987
	      ldap_close($ldap);
988
	      $_SESSION['ldapon'] = "false";
989
	      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
	  		return $status;
999
	}
1000
	
1001

    
1002
	log_error("$binduser succesfully logged in via LDAP.");
1003
	/* At this point we are bound to LDAP so the user was auth'd okay. */
1004
	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
?>
(3-3/29)