Project

General

Profile

Download (18 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 &getSystemAdminNames() {
40
  global $config, $g, $userindex;
41
  $adminUsers = array();
42

    
43
  if (is_array($config['system']['user'])) {
44
    foreach($config['system']['user'] as $user){
45
      if (isSystemAdmin($user['name'])) {
46
        $adminUsers[] = $user['name'];
47
      }
48
    }
49
  }
50

    
51
  return $adminUsers;
52
}
53

    
54
function &getSystemPrivs() {
55
  global $g;
56

    
57
  $privs = array();
58

    
59
  $privs[] = array("id" => "lockwc",
60
                   "name" => "Lock webConfigurator",
61
                   "desc" => "Indicates whether this user will lock access to " .
62
                             "the webConfigurator for other users.");
63
  $privs[] = array("id" => "lock-ipages",
64
                   "name" => "Lock individual pages",
65
                   "desc" => "Indicates whether this user will lock individual " .
66
                              "HTML pages after having accessed a particular page" .
67
                              "(the lock will be freed if the user leaves or " .
68
                              "saves the page form).");
69
  $privs[] = array("id" => "hasshell",
70
                   "name" => "Has shell access",
71
                   "desc" => "Indicates whether this user is able to login for " .
72
                   "example via SSH.");
73
  $privs[] = array("id" => "copyfiles",
74
                   "name" => "Is allowed to copy files",
75
                   "desc" => "Indicates whether this user is allowed to copy files " .
76
                             "onto the {$g['product_name']} appliance via SCP/SFTP. " .
77
                             "If you are going to use this privilege, you must install " .
78
                             "scponly on the appliance (Hint: pkg_add -r scponly).");
79
  $privs[] = array("id" => "isroot",
80
                   "name" => "Is root user",
81
                   "desc" => "This user is associated with the UNIX root user " .
82
                             "(you should associate this privilege only with one " .
83
                             "single user).");
84

    
85
  return $privs;
86
}
87

    
88
function assignUID($username = "") {
89
  global $userindex, $config, $g;
90

    
91
  if ($username == "") { return; }
92

    
93
  $nextuid = $config['system']['nextuid'];
94
  $user =& $config['system']['user'][$userindex[$username]];
95

    
96
  if (empty($user['uid'])) {
97
    $user['uid'] = $nextuid;
98
    $nextuid++;
99
    $config['system']['nextuid'] = $nextuid;
100

    
101
    write_config();
102

    
103
    return $user;
104
  }
105
}
106

    
107
function assignGID($groupname = "") {
108
  global $groupindex, $config, $g;
109

    
110
  if ($groupname == "") { return; }
111

    
112
  $nextgid = $config['system']['nextgid'];
113
  $group =& $config['system']['group'][$groupindex[$groupname]];
114

    
115
  if (empty($group['gid'])) {
116
    $group['gid'] = $nextgid;
117
    $nextgid++;
118
    $config['system']['nextgid'] = $nextgid;
119

    
120
    write_config();
121

    
122
    return $group;
123
  }
124
}
125

    
126
function hasPrivilege($user, $privid = "") {
127
  global $userindex, $config, $g;
128

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

    
131
  $privs = &$config['system']['user'][$userindex[$user]]['priv'];
132

    
133
  if (is_array($privs)) {
134
    foreach($privs as $priv){
135
      if ($priv['id'] == $privid) {
136
        return 1;
137
      }
138
    }
139
  }
140

    
141
  return 0;
142
}
143

    
144
function isAllowedToCopyFiles($username) {
145
  global $userindex, $config, $g;
146

    
147
  if ($username == "") { return 0; }
148

    
149
  return hasPrivilege($username, "copyfiles");
150
}
151

    
152
function hasLockAbility($username) {
153
  global $userindex, $config, $g;
154

    
155
  if ($username == "") { return 0; }
156

    
157
  return hasPrivilege($username, "lockwc");
158
}
159

    
160
function hasPageLockAbility($username) {
161
  global $userindex, $config, $g;
162

    
163
  if ($username == "") { return 0; }
164

    
165
  return hasPrivilege($username, "lock-ipages");
166
}
167

    
168
function hasShellAccess($username) {
169
  global $userindex, $config, $g;
170

    
171
  if ($username == "") { return 0; }
172

    
173
  return hasPrivilege($username, "hasshell");
174
}
175

    
176
function isUNIXRoot($username = "") {
177
  global $userindex, $config;
178

    
179
  if ($username == "") { return 0; }
180

    
181
  if (isSystemAdmin($username)) {
182
    return hasPrivilege($username, "isroot");
183
  }
184

    
185
  return 0;
186
}
187

    
188
function setUserFullName($name = "", $new_name = "") {
189
  global $config, $g, $userindex;
190

    
191
  if ($name == "" || $new_name == "") { return; }
192

    
193
  $user = &$config['system']['user'][$userindex[$name]];
194
  $user['fullname'] = $new_name;
195
}
196

    
197
function setUserName($name = "", $new_name = "") {
198
  global $config, $g, $userindex;
199

    
200
  if ($name == "" || $new_name == "") { return; }
201

    
202
  $user = &$config['system']['user'][$userindex[$name]];
203
  $user['name'] = $new_name;
204
}
205

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

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

    
211
  $user = &$config['system']['user'][$userindex[$name]];
212
  $user['password'] = crypt($password);
213
}
214

    
215
function setUserGroupName($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['groupname'] = $new_name;
222
}
223

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

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

    
229
  $user = &$config['system']['user'][$userindex[$name]];
230
  $user['scope'] = $new_type;
231
}
232

    
233
function getUNIXRoot() {
234
  global $config, $g, $userindex;
235

    
236
  if (is_array($config['system']['user'])) {
237
    foreach($config['system']['user'] as $user){
238
      if (isUNIXRoot($user['name'])) {
239
        $root = &$config['system']['user'][$userindex[$user['name']]];
240
        return $root;
241
      }
242
    }
243
  }
244

    
245
  return NULL;
246
}
247

    
248
function getUNIXRootName() {
249
  global $config, $g, $userindex;
250

    
251
  if (is_array($config['system']['user'])) {
252
    foreach($config['system']['user'] as $user){
253
      if (isUNIXRoot($user['name'])) {
254
        return $user['name'];
255
      }
256
    }
257
  }
258

    
259
  return NULL;
260
}
261

    
262
function getGroupHomePage($group = "") {
263
  global $groupindex, $config, $g;
264

    
265
  if ($group == "") { return ""; }
266

    
267
  $page = $config['system']['group'][$groupindex[$group]]['home'];
268
  if(empty($page)) { $page = ""; }
269
  return $page;
270
}
271

    
272
function isSystemAdmin($username = "") {
273
  global $groupindex, $userindex, $config, $g;
274

    
275
  if ($username == "") { return 0; }
276

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

    
279
  if (isset($gname)) {
280
    return ($gname === $g["admin_group"]);
281
  }
282

    
283
  return 0;
284
}
285

    
286
function getRealName($username = "") {
287
  global $userindex, $config;
288

    
289
  if ($username == "") { return ""; }
290

    
291
  return $config['system']['user'][$userindex[$username]]['fullname'];
292

    
293
}
294

    
295
function basic_auth($backing) {
296
  global $HTTP_SERVER_VARS;
297

    
298
  /* Check for AUTH_USER */
299
  if ($HTTP_SERVER_VARS['PHP_AUTH_USER'] <> "") {
300
    $HTTP_SERVER_VARS['AUTH_USER'] = $HTTP_SERVER_VARS['PHP_AUTH_USER'];
301
    $HTTP_SERVER_VARS['AUTH_PW'] = $HTTP_SERVER_VARS['PHP_AUTH_PW'];
302
  }
303
  if (!isset($HTTP_SERVER_VARS['AUTH_USER'])) {
304
    require_once("authgui.inc");
305
    header("WWW-Authenticate: Basic realm=\".\"");
306
    header("HTTP/1.0 401 Unauthorized");
307
    display_error_form("401", gettext("You must enter valid credentials to access this resource."));
308
    exit;
309
  } else {
310
    return $backing($HTTP_SERVER_VARS['AUTH_USER'],$HTTP_SERVER_VARS['AUTH_PW']);
311
  }
312
}
313

    
314
function session_auth($backing) {
315
  global $g, $HTTP_SERVER_VARS, $userindex, $config;
316

    
317
  session_start();
318

    
319
  /* Validate incoming login request */
320
  if (isset($_POST['login'])) {
321
    if ($backing($_POST['usernamefld'], $_POST['passwordfld'])) {
322
      $_SESSION['Logged_In'] = "True";
323
      $_SESSION['Username'] = $_POST['usernamefld'];
324
      $_SESSION['last_access'] = time();
325
    } else {
326
      /* give the user a more detailed error message */
327
      if (isset($userindex[$_POST['usernamefld']])) {
328
        $_SESSION['Login_Error'] = "Wrong password";
329
      } else {
330
        $_SESSION['Login_Error'] = "User does not exist";
331
      }
332
    }
333
  }
334

    
335
  /* Show login page if they aren't logged in */
336
  if (empty($_SESSION['Logged_In'])) {
337
    /* Don't display login forms to AJAX */
338
    if (isAjax())
339
      return false;
340
    require_once("authgui.inc");
341
    display_login_form();
342
    return false;
343
  } else {
344
    /* If session timeout isn't set, we don't mark sessions stale */
345
    if (!isset($config['system']['webgui']['session_timeout']) or
346
       $config['system']['webgui']['session_timeout'] == 0 or
347
       $config['system']['webgui']['session_timeout'] == "")
348
       $_SESSION['last_access'] = time();
349
     else
350
       /* Check for stale session */
351
       if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60)))
352
         $_GET['logout'] = true;
353
       else
354
         /* only update if it wasn't ajax */
355
         if (!isAjax())
356
           $_SESSION['last_access'] = time();
357

    
358
    /* user hit the logout button */
359
    if (isset($_GET['logout'])) {
360
      if (hasLockAbility($_SESSION['Username'])) {
361
        unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
362
      }
363

    
364
      /* wipe out $_SESSION */
365
      $_SESSION = array();
366

    
367
      if (isset($_COOKIE[session_name()])) {
368
        setcookie(session_name(), '', time()-42000, '/');
369
      }
370

    
371
      /* and destroy it */
372
      session_destroy();
373

    
374
      $scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]);
375
      $scriptElms = count($scriptName);
376
      $scriptName = $scriptName[$scriptElms-1];
377

    
378
      if (isAjax())
379
        return false;
380

    
381
      /* redirect to page the user is on, it'll prompt them to login again */
382
      pfSenseHeader($scriptName);
383

    
384
      return false;
385

    
386
    /* user wants to explicitely delete the log file.
387
     * Requires a particular privilege.
388
     */
389
    } else if ($_GET['deletelock'] && hasLockAbility($_SESSION['Username'])) {
390
      unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
391
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
392
      return true;
393

    
394
    /* this is for debugging purpose if you do not want to use Ajax
395
     * to submit a HTML form. It basically diables the observation
396
     * of the submit event and hence does not trigger Ajax.
397
     */
398
    } else if ($_GET['disable_ajax']) {
399
      $_SESSION['NO_AJAX'] = "True";
400
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
401
      return true;
402

    
403
    /* Same to re-enable Ajax.
404
     */
405
    } else if ($_GET['enable_ajax']) {
406
      unset($_SESSION['NO_AJAX']);
407
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
408
      return true;
409

    
410
    /* user wants to explicitely create a lock.
411
     * Requires a particular privilege.
412
     */
413
    } else if ($_GET['createlock'] && hasLockAbility($_SESSION['Username'])) {
414
      $fd = fopen("{$g['tmp_path']}/webconfigurator.lock", "w");
415
      fputs($fd, "{$_SERVER['REMOTE_ADDR']} (" .
416
                 getRealName($_SESSION['Username']) . ")");
417
      fclose($fd);
418
      /* if the user did delete the lock manually, do not
419
       * re-create it while the session is valide.
420
       */
421
      $_SESSION['Lock_Created'] = "True";
422
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
423
      return true;
424

    
425
    /* proceed with the login process */
426
    } else {
427
      /* if the user is allowed to create a lock,
428
       * create it once per session.
429
       */
430
      if (hasLockAbility($_SESSION['Username']) &&
431
          ! isset($_SESSION['Lock_Created'])) {
432

    
433
        $fd = fopen("{$g['tmp_path']}/webconfigurator.lock", "w");
434
        fputs($fd, "{$_SERVER['REMOTE_ADDR']} (" .
435
                   getRealName($_SESSION['Username']) . ")");
436
        fclose($fd);
437
        /* if the user did delete the lock manually, do not
438
         * re-create it while the session is valide.
439
         */
440
        $_SESSION['Lock_Created'] = "True";
441

    
442
      /* give regular users a chance to automatically invalidate
443
       * a lock if its older than a particular time.
444
       */
445
      } else if (! hasLockAbility($_SESSION['Username']) &&
446
                 file_exists("{$g['tmp_path']}/webconfigurator.lock")) {
447

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

    
452
        if (($mtime - $now_minus_offset) < $mtime) {
453
          require_once("authgui.inc");
454
          display_login_form();
455
          return false;
456
        } else {
457
          /* file is older than mtime + offset which may
458
           * indicate a stale lockfile, hence we are going
459
           * to remove it.
460
           */
461
           unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock");
462
        }
463
      }
464

    
465
      $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username'];
466
      return true;
467
    }
468
  }
469
}
470

    
471
function pam_backed($username = "", $password = "") {
472
  /* we do not support blank pwds, don't we? */
473
  if ($username == "" || password == "") { return false; }
474

    
475
  if(! extension_loaded( 'pam_auth' )) {
476
    if(! @dl( 'pam_auth.so' )) {
477
      return false;
478
    } else {
479
      /* no php file no auth, sorry */
480
      if (! file_exists("/etc/pam.d/php")) {
481
        if (! file_exists("/etc/pam.d")) { mkdir("/etc/pam.d"); }
482

    
483
        $pam_php = <<<EOD
484
# /etc/pam.d/php
485
#
486
# note: both an auth and account entry are required
487

    
488
# auth
489
auth            required        pam_nologin.so          no_warn
490
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
491
auth            requisite       pam_opieaccess.so       no_warn allow_local
492
auth            required        pam_unix.so             no_warn try_first_pass
493

    
494
# account
495
account         required        pam_unix.so
496

    
497
# session
498
session         required        pam_permit.so
499

    
500
# password
501
password        required        pam_unix.so             no_warn try_first_pass
502

    
503
EOD;
504

    
505
        file_put_contents("/etc/pam.d/php", $pam_php);
506
      } // end if
507

    
508
      if (pam_auth($username, $password, &$error)) {
509
        return true;
510
      } else {
511
        return false;
512
      }
513
    }
514
  }
515
}
516

    
517
function passwd_backed($username, $passwd) {
518
  $authfile = file("/etc/master.passwd");
519

    
520
  $matches="";
521

    
522
  /* Check to see if user even exists */
523
  if(!($line = array_shift(preg_grep("/^$username:.*$/", $authfile))))
524
    return false;
525

    
526
  /* Get crypted password */
527
  preg_match("/^$username:((\\$1\\$[.\d\w_\/]{8}\\$)[.\d\w_\/]{22})$/", $line, $matches);
528
  $pass = $matches[1];
529
  $salt = $matches[2];
530

    
531
  /* Encrypt entered password with salt
532
   * And finally validate password
533
   */
534
  if ($pass == crypt($passwd, $salt))
535
    return true;
536
  else
537
    return false;
538
}
539

    
540
function htpasswd_backed($username, $passwd) {
541
  $authfile = file("/var/run/htpasswd");
542

    
543
  /* sanity check to ensure that /usr/local/www/.htpasswd doesn't exist */
544
  unlink_if_exists("/usr/local/www/.htpasswd");
545

    
546
  $matches="";
547
  if(!($line = array_shift(preg_grep("/^$username:.*$/", $authfile))))
548
          return false;
549

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

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

    
564
function radius_backed($username, $passwd){
565
  global $config, $debug;
566
  $ret = false;
567
  $radiusservers = $config['system']['radius']['servers'];
568

    
569
  $rauth = new Auth_RADIUS_PAP($username, $passwd);
570
  foreach ($radiusservers as $radsrv) {
571
    // Add a new server to our instance
572
    $rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']);
573
  }
574

    
575
  if (!$rauth->start()) {
576
    $retvalue['auth_val'] = 1;
577
    $retvalue['error'] = $rauth->getError();
578
    if ($debug)
579
      printf("Radius start: %s<br>\n", $retvalue['error']);
580
  }
581

    
582
  // XXX - billm - somewhere in here we need to handle securid challenge/response
583

    
584
  // Send request
585
  $result = $rauth->send();
586
  if (PEAR::isError($result)) {
587
    $retvalue['auth_val'] = 1;
588
    $retvalue['error'] = $result->getMessage();
589
    if ($debug)
590
      printf("Radius send failed: %s<br>\n", $retvalue['error']);
591
  } else if ($result === true) {
592
    $retvalue['auth_val'] = 2;
593
    if ($debug)
594
      printf (gettext("Radius Auth succeeded") . "<br>\n");
595
    $ret = true;
596
  } else {
597
      $retvalue['auth_val'] = 3;
598
      if ($debug)
599
        printf (gettext("Radius Auth rejected") . "<br>\n");
600
  }
601
  // close OO RADIUS_AUTHENTICATION
602
  $rauth->close();
603

    
604
  return $ret;
605
}
606

    
607

    
608
function index_groups() {
609
  global $g, $config, $groupindex;
610

    
611
  $groupindex = array();
612

    
613
  if (isset($config['system']['group'])) {
614
    $i = 0;
615
    foreach($config['system']['group'] as $groupent) {
616
      $groupindex[$groupent['name']] = $i;
617
      $i++;
618
    }
619
  }
620
  return ($groupindex);
621
}
622

    
623
function index_users() {
624
  global $g, $config;
625

    
626
  if (isset($config['system']['user'])) {
627
    $i = 0;
628
    foreach($config['system']['user'] as $userent) {
629
      $userindex[$userent['name']] = $i;
630
      $i++;
631
    }
632
  }
633
  return ($userindex);
634
}
635

    
636
?>
(3-3/29)