Project

General

Profile

Download (18.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
        Copyright (C) 2005-2006 Bill Marquette <bill.marquette@gmail.com>
5
        All rights reserved.
6

    
7
        Copyright (C) 2006 Paul Taylor <paultaylor@winn-dixie.com>.
8
        All rights reserved.
9

    
10
        Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
11
        All rights reserved.
12

    
13
        Redistribution and use in source and binary forms, with or without
14
        modification, are permitted provided that the following conditions are met:
15

    
16
        1. Redistributions of source code must retain the above copyright notice,
17
           this list of conditions and the following disclaimer.
18

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

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

    
35
require_once("functions.inc");
36
$groupindex = index_groups();
37
$userindex = index_users();
38

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

    
46
      /* wipe out $_SESSION */
47
      $_SESSION = array();
48

    
49
      /* and destroy it */
50
      session_destroy();
51

    
52
      $scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
53
      $scriptElms = count($scriptName);
54
      $scriptName = $scriptName[$scriptElms-1];
55
}
56

    
57
function &getSystemAdminNames() {
58
  global $config, $g, $userindex;
59
  $adminUsers = array();
60

    
61
  if (is_array($config['system']['user'])) {
62
    foreach($config['system']['user'] as $user){
63
      if (isSystemAdmin($user['name'])) {
64
        $adminUsers[] = $user['name'];
65
      }
66
    }
67
  }
68

    
69
  return $adminUsers;
70
}
71

    
72
function &getSystemPrivs() {
73
  global $g;
74

    
75
  $privs = array();
76

    
77
  $privs[] = array("id" => "lockwc",
78
                   "name" => "Lock webConfigurator",
79
                   "desc" => "Indicates whether this user will lock access to " .
80
                             "the webConfigurator for other users.");
81
  $privs[] = array("id" => "lock-ipages",
82
                   "name" => "Lock individual pages",
83
                   "desc" => "Indicates whether this user will lock individual " .
84
                              "HTML pages after having accessed a particular page" .
85
                              "(the lock will be freed if the user leaves or " .
86
                              "saves the page form).");
87
  $privs[] = array("id" => "hasshell",
88
                   "name" => "Has shell access",
89
                   "desc" => "Indicates whether this user is able to login for " .
90
                   "example via SSH.");
91
  $privs[] = array("id" => "copyfiles",
92
                   "name" => "Is allowed to copy files",
93
                   "desc" => "Indicates whether this user is allowed to copy files " .
94
                             "onto the {$g['product_name']} appliance via SCP/SFTP. " .
95
                             "If you are going to use this privilege, you must install " .
96
                             "scponly on the appliance (Hint: pkg_add -r scponly).");
97
  $privs[] = array("id" => "isroot",
98
                   "name" => "Is root user",
99
                   "desc" => "This user is associated with the UNIX root user " .
100
                             "(you should associate this privilege only with one " .
101
                             "single user).");
102

    
103
  return $privs;
104
}
105

    
106
function assignUID($username = "") {
107
  global $userindex, $config, $g;
108

    
109
  if ($username == "") { return; }
110

    
111
  $nextuid = $config['system']['nextuid'];
112
  $user =& $config['system']['user'][$userindex[$username]];
113

    
114
  if (empty($user['uid'])) {
115
    $user['uid'] = $nextuid;
116
    $nextuid++;
117
    $config['system']['nextuid'] = $nextuid;
118

    
119
    write_config();
120

    
121
    return $user;
122
  }
123
}
124

    
125
function assignGID($groupname = "") {
126
  global $groupindex, $config, $g;
127

    
128
  if ($groupname == "") { return; }
129

    
130
  $nextgid = $config['system']['nextgid'];
131
  $group =& $config['system']['group'][$groupindex[$groupname]];
132

    
133
  if (empty($group['gid'])) {
134
    $group['gid'] = $nextgid;
135
    $nextgid++;
136
    $config['system']['nextgid'] = $nextgid;
137

    
138
    write_config();
139

    
140
    return $group;
141
  }
142
}
143

    
144
function hasPrivilege($user, $privid = "") {
145
  global $userindex, $config, $g;
146

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

    
149
  $privs = &$config['system']['user'][$userindex[$user]]['priv'];
150

    
151
  if (is_array($privs)) {
152
    foreach($privs as $priv){
153
      if ($priv['id'] == $privid) {
154
        return 1;
155
      }
156
    }
157
  }
158

    
159
  return 0;
160
}
161

    
162
function isAllowedToCopyFiles($username) {
163
  global $userindex, $config, $g;
164

    
165
  if ($username == "") { return 0; }
166

    
167
  return hasPrivilege($username, "copyfiles");
168
}
169

    
170
function hasLockAbility($username) {
171
  global $userindex, $config, $g;
172

    
173
  if ($username == "") { return 0; }
174

    
175
  return hasPrivilege($username, "lockwc");
176
}
177

    
178
function hasPageLockAbility($username) {
179
  global $userindex, $config, $g;
180

    
181
  if ($username == "") { return 0; }
182

    
183
  return hasPrivilege($username, "lock-ipages");
184
}
185

    
186
function hasShellAccess($username) {
187
  global $userindex, $config, $g;
188

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

    
191
  return hasPrivilege($username, "hasshell");
192
}
193

    
194
function isUNIXRoot($username = "") {
195
  global $userindex, $config;
196

    
197
  if ($username == "") { return 0; }
198

    
199
  if (isSystemAdmin($username)) {
200
    return hasPrivilege($username, "isroot");
201
  }
202

    
203
  return 0;
204
}
205

    
206
function setUserFullName($name = "", $new_name = "") {
207
  global $config, $g, $userindex;
208

    
209
  if ($name == "" || $new_name == "") { return; }
210

    
211
  $user = &$config['system']['user'][$userindex[$name]];
212
  $user['fullname'] = $new_name;
213
}
214

    
215
function setUserName($name = "", $new_name = "") {
216
  global $config, $g, $userindex;
217

    
218
  if ($name == "" || $new_name == "") { return; }
219

    
220
  $user = &$config['system']['user'][$userindex[$name]];
221
  $user['name'] = $new_name;
222
}
223

    
224
function setUserPWD($name = "", $password = "") {
225
  global $config, $g, $userindex;
226

    
227
  if ($name == "" || $password == "") { return; }
228

    
229
  $user = &$config['system']['user'][$userindex[$name]];
230
  $user['password'] = crypt($password);
231
}
232

    
233
function setUserGroupName($name = "", $new_name = "") {
234
  global $config, $g, $userindex;
235

    
236
  if ($name == "" || $new_name == "") { return; }
237

    
238
  $user = &$config['system']['user'][$userindex[$name]];
239
  $user['groupname'] = $new_name;
240
}
241

    
242
function setUserType($name = "", $new_type = "") {
243
  global $config, $g, $userindex;
244

    
245
  if ($name == "" || $new_type == "") { return; }
246

    
247
  $user = &$config['system']['user'][$userindex[$name]];
248
  $user['scope'] = $new_type;
249
}
250

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

    
254
  if (is_array($config['system']['user'])) {
255
    foreach($config['system']['user'] as $user){
256
      if (isUNIXRoot($user['name'])) {
257
        $root = &$config['system']['user'][$userindex[$user['name']]];
258
        return $root;
259
      }
260
    }
261
  }
262

    
263
  return NULL;
264
}
265

    
266
function getUNIXRootName() {
267
  global $config, $g, $userindex;
268

    
269
  if (is_array($config['system']['user'])) {
270
    foreach($config['system']['user'] as $user){
271
      if (isUNIXRoot($user['name'])) {
272
        return $user['name'];
273
      }
274
    }
275
  }
276

    
277
  return NULL;
278
}
279

    
280
function getGroupHomePage($group = "") {
281
  global $groupindex, $config, $g;
282

    
283
  if ($group == "") { return ""; }
284

    
285
  $page = $config['system']['group'][$groupindex[$group]]['home'];
286
  if(empty($page)) { $page = ""; }
287
  return $page;
288
}
289

    
290
function isSystemAdmin($username = "") {
291
  global $groupindex, $userindex, $config, $g;
292

    
293
  if ($username == "") { return 0; }
294

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

    
297
  if (isset($gname)) {
298
    return ($gname === $g["admin_group"]);
299
  }
300

    
301
  return 0;
302
}
303

    
304
function getRealName($username = "") {
305
  global $userindex, $config;
306

    
307
  if ($username == "") { return ""; }
308

    
309
  return $config['system']['user'][$userindex[$username]]['fullname'];
310

    
311
}
312

    
313
function basic_auth($backing) {
314
  global $HTTP_SERVER_VARS;
315

    
316
  /* Check for AUTH_USER */
317
  if ($HTTP_SERVER_VARS['PHP_AUTH_USER'] <> "") {
318
    $HTTP_SERVER_VARS['AUTH_USER'] = $HTTP_SERVER_VARS['PHP_AUTH_USER'];
319
    $HTTP_SERVER_VARS['AUTH_PW'] = $HTTP_SERVER_VARS['PHP_AUTH_PW'];
320
  }
321
  if (!isset($HTTP_SERVER_VARS['AUTH_USER'])) {
322
    require_once("authgui.inc");
323
    header("WWW-Authenticate: Basic realm=\".\"");
324
    header("HTTP/1.0 401 Unauthorized");
325
    display_error_form("401", gettext("You must enter valid credentials to access this resource."));
326
    exit;
327
  } else {
328
    return $backing($HTTP_SERVER_VARS['AUTH_USER'],$HTTP_SERVER_VARS['AUTH_PW']);
329
  }
330
}
331

    
332
function session_auth($backing) {
333
  global $g, $HTTP_SERVER_VARS, $userindex, $config;
334

    
335
  session_start();
336

    
337
  /* Validate incoming login request */
338
  if (isset($_POST['login'])) {
339
    if ($backing($_POST['usernamefld'], $_POST['passwordfld'])) {
340
      $_SESSION['Logged_In'] = "True";
341
      $_SESSION['Username'] = $_POST['usernamefld'];
342
      $_SESSION['last_access'] = time();
343
    } else {
344
      /* give the user a more detailed error message */
345
      if (isset($userindex[$_POST['usernamefld']])) {
346
        $_SESSION['Login_Error'] = "Wrong password";
347
        if(isAjax()) {
348
        	echo "showajaxmessage('Wrong password');";
349
        	return;        	
350
        }
351
      } else {
352
        $_SESSION['Login_Error'] = "User does not exist";
353
        if(isAjax()) {
354
        	echo "showajaxmessage('User does not exist');";
355
        	return;
356
        }
357
      }
358
    }
359
  }
360

    
361
  /* Show login page if they aren't logged in */
362
  if (empty($_SESSION['Logged_In'])) {
363
    /* Don't display login forms to AJAX */
364
    if (isAjax())
365
      return false;
366
    require_once("authgui.inc");
367
    display_login_form();
368
    return false;
369
  } else {
370
    /* If session timeout isn't set, we don't mark sessions stale */
371
    if (!isset($config['system']['webgui']['session_timeout']) or
372
       $config['system']['webgui']['session_timeout'] == 0 or
373
       $config['system']['webgui']['session_timeout'] == "")
374
       $_SESSION['last_access'] = time();
375
     else
376
       /* Check for stale session */
377
       if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60)))
378
         $_GET['logout'] = true;
379
       else
380
         /* only update if it wasn't ajax */
381
         if (!isAjax())
382
           $_SESSION['last_access'] = time();
383

    
384
    /* user hit the logout button */
385
    if (isset($_GET['logout'])) {
386
      if (hasLockAbility($_SESSION['Username'])) {
387
        unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
388
      }
389

    
390
      /* wipe out $_SESSION */
391
      $_SESSION = array();
392

    
393
      if (isset($_COOKIE[session_name()])) {
394
        setcookie(session_name(), '', time()-42000, '/');
395
      }
396

    
397
      /* and destroy it */
398
      session_destroy();
399

    
400
      $scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
401
      $scriptElms = count($scriptName);
402
      $scriptName = $scriptName[$scriptElms-1];
403

    
404
      if (isAjax())
405
        return false;
406

    
407
      /* redirect to page the user is on, it'll prompt them to login again */
408
      pfSenseHeader($scriptName);
409

    
410
      return false;
411

    
412
    /* user wants to explicitely delete the log file.
413
     * Requires a particular privilege.
414
     */
415
    } else if ($_GET['deletelock'] && hasLockAbility($_SESSION['Username'])) {
416
      unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
417
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
418
      return true;
419

    
420
    /* this is for debugging purpose if you do not want to use Ajax
421
     * to submit a HTML form. It basically diables the observation
422
     * of the submit event and hence does not trigger Ajax.
423
     */
424
    } else if ($_GET['disable_ajax']) {
425
      $_SESSION['NO_AJAX'] = "True";
426
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
427
      return true;
428

    
429
    /* Same to re-enable Ajax.
430
     */
431
    } else if ($_GET['enable_ajax']) {
432
      unset($_SESSION['NO_AJAX']);
433
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
434
      return true;
435

    
436
    /* user wants to explicitely create a lock.
437
     * Requires a particular privilege.
438
     */
439
    } else if ($_GET['createlock'] && hasLockAbility($_SESSION['Username'])) {
440
      $fd = fopen("{$g['tmp_path']}/webconfigurator.lock", "w");
441
      fputs($fd, "{$_SERVER['REMOTE_ADDR']} (" .
442
                 getRealName($_SESSION['Username']) . ")");
443
      fclose($fd);
444
      /* if the user did delete the lock manually, do not
445
       * re-create it while the session is valide.
446
       */
447
      $_SESSION['Lock_Created'] = "True";
448
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
449
      return true;
450

    
451
    /* proceed with the login process */
452
    } else {
453
      /* if the user is allowed to create a lock,
454
       * create it once per session.
455
       */
456
      if (hasLockAbility($_SESSION['Username']) &&
457
          ! isset($_SESSION['Lock_Created'])) {
458

    
459
        $fd = fopen("{$g['tmp_path']}/webconfigurator.lock", "w");
460
        fputs($fd, "{$_SERVER['REMOTE_ADDR']} (" .
461
                   getRealName($_SESSION['Username']) . ")");
462
        fclose($fd);
463
        /* if the user did delete the lock manually, do not
464
         * re-create it while the session is valide.
465
         */
466
        $_SESSION['Lock_Created'] = "True";
467

    
468
      /* give regular users a chance to automatically invalidate
469
       * a lock if its older than a particular time.
470
       */
471
      } else if (! hasLockAbility($_SESSION['Username']) &&
472
                 file_exists("{$g['tmp_path']}/webconfigurator.lock")) {
473

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

    
478
        if (($mtime - $now_minus_offset) < $mtime) {
479
          require_once("authgui.inc");
480
          display_login_form();
481
          return false;
482
        } else {
483
          /* file is older than mtime + offset which may
484
           * indicate a stale lockfile, hence we are going
485
           * to remove it.
486
           */
487
           unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
488
        }
489
      }
490

    
491
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
492
      return true;
493
    }
494
  }
495
}
496

    
497
function pam_backed($username = "", $password = "") {
498
  /* we do not support blank pwds, don't we? */
499
  if ($username == "" || password == "") { return false; }
500

    
501
  if(! extension_loaded( 'pam_auth' )) {
502
    if(! @dl( 'pam_auth.so' )) {
503
      return false;
504
    } else {
505
      /* no php file no auth, sorry */
506
      if (! file_exists("/etc/pam.d/php")) {
507
        if (! file_exists("/etc/pam.d")) { mkdir("/etc/pam.d"); }
508

    
509
        $pam_php = <<<EOD
510
# /etc/pam.d/php
511
#
512
# note: both an auth and account entry are required
513

    
514
# auth
515
auth            required        pam_nologin.so          no_warn
516
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
517
auth            requisite       pam_opieaccess.so       no_warn allow_local
518
auth            required        pam_unix.so             no_warn try_first_pass
519

    
520
# account
521
account         required        pam_unix.so
522

    
523
# session
524
session         required        pam_permit.so
525

    
526
# password
527
password        required        pam_unix.so             no_warn try_first_pass
528

    
529
EOD;
530

    
531
        file_put_contents("/etc/pam.d/php", $pam_php);
532
      } // end if
533

    
534
      if (pam_auth($username, $password, &$error)) {
535
        return true;
536
      } else {
537
        return false;
538
      }
539
    }
540
  }
541
}
542

    
543
function passwd_backed($username, $passwd) {
544
  $authfile = file("/etc/master.passwd");
545

    
546
  $matches="";
547

    
548
  /* Check to see if user even exists */
549
  if(!($line = array_shift(preg_grep("/^$username:.*$/", $authfile))))
550
    return false;
551

    
552
  /* Get crypted password */
553
  preg_match("/^$username:((\\$1\\$[.\d\w_\/]{8}\\$)[.\d\w_\/]{22})$/", $line, $matches);
554
  $pass = $matches[1];
555
  $salt = $matches[2];
556

    
557
  /* Encrypt entered password with salt
558
   * And finally validate password
559
   */
560
  if ($pass == crypt($passwd, $salt))
561
    return true;
562
  else
563
    return false;
564
}
565

    
566
function htpasswd_backed($username, $passwd) {
567
  $authfile = file("/var/run/htpasswd");
568

    
569
  /* sanity check to ensure that /usr/local/www/.htpasswd doesn't exist */
570
  unlink_if_exists("/usr/local/www/.htpasswd");
571

    
572
  $matches="";
573
  if(!($line = array_shift(preg_grep("/^$username:.*$/", $authfile))))
574
          return false;
575

    
576
  /* Get crypted password */
577
  preg_match("/^$username:((\\$1\\$[.\d\w_\/]{8}\\$)[.\d\w_\/]{22})$/", $line, $matches);
578
  $pass = $matches[1];
579
  $salt = $matches[2];
580

    
581
  /* Encrypt entered password with salt
582
   * And finally validate password
583
   */
584
  if ($pass == crypt($passwd, $salt))
585
    return true;
586
  else
587
    return false;
588
}
589

    
590
function radius_backed($username, $passwd){
591
  global $config, $debug;
592
  $ret = false;
593
  $radiusservers = $config['system']['radius']['servers'];
594

    
595
  $rauth = new Auth_RADIUS_PAP($username, $passwd);
596
  foreach ($radiusservers as $radsrv) {
597
    // Add a new server to our instance
598
    $rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
599
  }
600

    
601
  if (!$rauth->start()) {
602
    $retvalue['auth_val'] = 1;
603
    $retvalue['error'] = $rauth->getError();
604
    if ($debug)
605
      printf("Radius start: %s<br>\n", $retvalue['error']);
606
  }
607

    
608
  // XXX - billm - somewhere in here we need to handle securid challenge/response
609

    
610
  // Send request
611
  $result = $rauth->send();
612
  if (PEAR::isError($result)) {
613
    $retvalue['auth_val'] = 1;
614
    $retvalue['error'] = $result->getMessage();
615
    if ($debug)
616
      printf("Radius send failed: %s<br>\n", $retvalue['error']);
617
  } else if ($result === true) {
618
    $retvalue['auth_val'] = 2;
619
    if ($debug)
620
      printf (gettext("Radius Auth succeeded") . "<br>\n");
621
    $ret = true;
622
  } else {
623
      $retvalue['auth_val'] = 3;
624
      if ($debug)
625
        printf (gettext("Radius Auth rejected") . "<br>\n");
626
  }
627
  // close OO RADIUS_AUTHENTICATION
628
  $rauth->close();
629

    
630
  return $ret;
631
}
632

    
633

    
634
function index_groups() {
635
  global $g, $config, $groupindex;
636

    
637
  $groupindex = array();
638

    
639
  if (isset($config['system']['group'])) {
640
    $i = 0;
641
    foreach($config['system']['group'] as $groupent) {
642
      $groupindex[$groupent['name']] = $i;
643
      $i++;
644
    }
645
  }
646
  return ($groupindex);
647
}
648

    
649
function index_users() {
650
  global $g, $config;
651

    
652
  if (isset($config['system']['user'])) {
653
    $i = 0;
654
    foreach($config['system']['user'] as $userent) {
655
      $userindex[$userent['name']] = $i;
656
      $i++;
657
    }
658
  }
659
  return ($userindex);
660
}
661

    
662
?>
(3-3/29)