diff options
Diffstat (limited to 'config/authng/pkg')
-rw-r--r-- | config/authng/pkg/authng.inc | 323 | ||||
-rw-r--r-- | config/authng/pkg/authng.xml | 194 | ||||
-rw-r--r-- | config/authng/pkg/authng_authgui.inc | 287 | ||||
-rw-r--r-- | config/authng/pkg/authng_authmethods.inc | 222 | ||||
-rw-r--r-- | config/authng/pkg/authng_backends.inc | 234 | ||||
-rw-r--r-- | config/authng/pkg/authng_classdefs.inc | 479 | ||||
-rw-r--r-- | config/authng/pkg/authng_peers.inc | 501 | ||||
-rw-r--r-- | config/authng/pkg/authng_usermanager.inc | 247 |
8 files changed, 2487 insertions, 0 deletions
diff --git a/config/authng/pkg/authng.inc b/config/authng/pkg/authng.inc new file mode 100644 index 00000000..06774acd --- /dev/null +++ b/config/authng/pkg/authng.inc @@ -0,0 +1,323 @@ +<?php +/* $Id$ */ +/* ========================================================================== */ +/* + authng.inc + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + +/* PHP classes like factories users, and groups */ +require_once("authng_classdefs.inc"); +/* PHP classes representing specific auth methods */ +require_once("authng_authmethods.inc"); +/* PHP classes representing specific backends */ +require_once("authng_backends.inc"); +/* PHP peer classes that are providing a persistence layer */ +require_once("authng_peers.inc"); + +// TODO: Define user- and groupindex array + +// get principal store type from config.xml +// TODO: needs to be defined in config.xml +//$principalStore = $config['system']['webgui']['principal_store']; +$principalStore = "xml"; +// get PeerFactory instance +$peerFactory =& PeerFactory::getInstance(); +// get the actual UserPeer that holds the user index +$userPeer =& $peerFactory->getUserPeerByPrincipalStore($principalStore); +// get the actual GroupPeer that holds the user index +$groupPeer =& $peerFactory->getGroupPeerByPrincipalStore($principalStore); +// get AuthMethodFactory instance +$authMethodFactory =& AuthMethodFactory::getInstance(); +// get BackendFactory instance +$backendFactory =& BackendFactory::getInstance(); +// get the actual auth method +$authMethod =& $authMethodFactory->getAuthMethodByName($config['system']['webgui']['auth_method']); +// get the actual backend +$backend =& $backendFactory->getBackendByName($config['system']['webgui']['backing_method']); + +function getUsermanagerPagetitle() { + global $userPeer; + + $result = ""; + + if ($userPeer->isSystemAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + // Page title for admins + $result = array(gettext("System"), gettext("User manager")); + } else { + // Page title for non-admins + $result = array(gettext("System"), gettext("User password")); + } + + return $result; +} + +function processUserManagerPostVars() { + global $input_errors, $savemsg, $config; + + if (isset($_POST['save'])) { + unset($input_errors); + + /* input validation */ + $reqdfields = explode(" ", "passwordfld1"); + $reqdfieldsn = explode(",", "Password"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + if ($_POST['passwordfld1'] != $_POST['passwordfld2']) + $input_errors[] = "The passwords do not match."; + + if (!$input_errors) { + // all values are okay --> saving changes + $config['system']['user'][$userindex[$HTTP_SERVER_VARS['AUTH_USER']]]['password'] = crypt(trim($_POST['passwordfld1'])); + + write_config(); + + sync_webgui_passwords(); + + $retval = system_password_configure(); + $savemsg = get_std_save_message($retval); + $savemsg = "Password successfully changed<br />"; + } + } +} + +function processUserManagerAdminPostVars() { + global $config; + + $id = $_GET['id']; + if (isset($_POST['id'])) + $id = $_POST['id']; + + if (!is_array($config['system']['user'])) { + $config['system']['user'] = array(); + } + + admin_users_sort(); + $a_user = &$config['system']['user']; + $t_privs = $a_user[$id]['priv']; + + if ($_GET['act'] == "del" && $_GET['what'] == "user") { + if ($a_user[$_GET['id']]) { + $userdeleted = $a_user[$_GET['id']]['name']; + unset($a_user[$_GET['id']]); + write_config(); + $retval = system_password_configure(); + $savemsg = get_std_save_message($retval); + $savemsg = gettext("User") . " " . $userdeleted . " " . gettext("successfully deleted") . "<br />"; + } + } else if ($_GET['act'] == "del" && $_GET['what'] == "priv") { + if ($t_privs[$_GET['privid']]) { + $privdeleted = $t_privs[$_GET['privid']]['id']; + unset($t_privs[$_GET['privid']]); + write_config(); + $_GET['act'] = "edit"; + $retval = 0; + $savemsg = get_std_save_message($retval); + $savemsg = gettext("Privilege") . " " . $privdeleted . " " . gettext("of user") . " " . $a_user[$_GET['id']]['name'] . " " . gettext("successfully deleted") . "<br />"; + } + } + + if ($_POST) { + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + if (isset($id) && ($a_user[$id])) { + $reqdfields = explode(" ", "usernamefld"); + $reqdfieldsn = explode(",", "Username"); + } else { + $reqdfields = explode(" ", "usernamefld passwordfld1"); + $reqdfieldsn = explode(",", "Username,Password"); + } + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + if (hasShellAccess($_POST['usernamefld'])) { + if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['usernamefld'])) + $input_errors[] = gettext("The username contains invalid characters."); + } else { + if (preg_match("/[^a-zA-Z0-9\@\.\-_]/", $_POST['usernamefld'])) + $input_errors[] = gettext("The username contains invalid characters."); + } + + if (($_POST['passwordfld1']) && ($_POST['passwordfld1'] != $_POST['passwordfld2'])) + $input_errors[] = gettext("The passwords do not match."); + + if (!$input_errors && !(isset($id) && $a_user[$id])) { + /* make sure there are no dupes */ + foreach ($a_user as $userent) { + if ($userent['name'] == $_POST['usernamefld']) { + $input_errors[] = gettext("Another entry with the same username already exists."); + break; + } + } + } + + if ($pconfig['utype'] <> "system" && !isset($groupindex[$_POST['groupname']])) { + $input_errors[] = gettext("group does not exist, please define the group before assigning users."); + } + + if (isset($config['system']['ssh']['sshdkeyonly']) && + empty($_POST['authorizedkeys'])) { + $input_errors[] = gettext("You must provide an authorized key otherwise you won't be able to login into this system."); + } + + /* if this is an AJAX caller then handle via JSON */ + if (isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + exit; + } + + if (!$input_errors) { + if (isset($id) && $a_user[$id]) + $userent = $a_user[$id]; + + /* the user did change his username */ + if ($_POST['usernamefld'] <> $_POST['oldusername']) { + $_SERVER['REMOTE_USER'] = $_POST['usernamefld']; + } + + $userent['name'] = $_POST['usernamefld']; + $userent['fullname'] = $_POST['fullname']; + if ($pconfig['utype'] <> "system") { + $userent['groupname'] = $_POST['groupname']; + } + isset($_POST['utype']) ? $userent['scope'] = $_POST['utype'] : $userent['scope'] = "system"; + + if ($_POST['passwordfld1']) + $userent['password'] = crypt($_POST['passwordfld1']); + + if(isset($config['system']['ssh']['sshdkeyonly'])) { + $userent['authorizedkeys'] = base64_encode($_POST['authorizedkeys']); + } + + if (isset($id) && $a_user[$id]) + $a_user[$id] = $userent; + else + $a_user[] = $userent; + + write_config(); + $retval = system_password_configure(); + sync_webgui_passwords(); + + pfSenseHeader("system_usermanager.php"); + } + } +} + +/** + * getWindowJSScriptRefs() + * + * @return + */ +function getWindowJSScriptRefs(){ + $result = array('<script type="text/javascript" src="/javascript/windows-js/javascript/window.js"></script>', + '<script type="text/javascript" src="/javascript/windows-js/javascript/window_effects.js"></script>', + '<script type="text/javascript" src="/javascript/windows-js/javascript/debug.js"></script>'); + + return $result; +} + +function gotNoUsers() { + global $config; + return empty($config['installedpackages']['authng']['config']); +} + +/** + * openNoUserDefsDialog() + * + * @param mixed $effectClass + * @return + */ +function openNoUserDefsDialog($effectClass) { + if (gotNoUsers()) { + $alertMessage = gettext("No users or groups found. You will be forwarded to the AuthNG wizard to be able to define users and groups."); + $dialogScript = " + <script type='text/javascript'> + var anchor = document.getElementById('popupanchor'); + + function forwardToWizard() { + window.location.href = '/wizard.php?xml=authng_wizard.xml'; + } + + function openNoUserDefsDialog(html) { + var effect = new PopupEffect(html, {className: '${effectClass}'}); + Dialog.alert('${alertMessage}',{className:'alphacube', top:150, width:400, height:null, showEffect:effect.show.bind(effect), hideEffect:effect.hide.bind(effect), onOk:forwardToWizard}); + } + + openNoUserDefsDialog(anchor); + </script> + "; + + return $dialogScript; + } +} + +/** + * getWindowJSStyleRefs() + * + * @return + */ +function getWindowJSStyleRefs(){ + $result = array('<link href="/javascript/windows-js/themes/default.css" rel="stylesheet" type="text/css" />', + '<link href="/javascript/windows-js/themes/alert.css" rel="stylesheet" type="text/css" />', + '<link href="/javascript/windows-js/themes/alphacube.css" rel="stylesheet" type="text/css" />'); + + return $result; +} + +/** + * installPackageAuthNG() + * + * @return + */ +function installPackageAuthNG() { + mwexec("cd / && /usr/bin/patch < /usr/local/pkg/authng-pfSenseHead.diff"); + mwexec("cd / && /usr/bin/patch < /usr/local/pkg/authng-fbegin.inc.diff"); + mwexec("cd / && /usr/bin/patch < /usr/local/pkg/authng-guiconfig.inc.diff"); + mwexec("cd / && /usr/bin/patch < /usr/local/pkg/authng-globals.inc.diff"); +} + +/** + * deinstallPackageAuthNG() + * + * @return + */ +function deinstallPackageAuthNG() { + mwexec("cd / && /usr/bin/patch -R < /usr/local/pkg/authng-pfSenseHead.diff"); + mwexec("cd / && /usr/bin/patch -R < /usr/local/pkg/authng-fbegin.inc.diff"); + mwexec("cd / && /usr/bin/patch -R < /usr/local/pkg/authng-guiconfig.inc.diff"); + mwexec("cd / && /usr/bin/patch -R < /usr/local/pkg/authng-globals.inc.diff"); +} +?>
\ No newline at end of file diff --git a/config/authng/pkg/authng.xml b/config/authng/pkg/authng.xml new file mode 100644 index 00000000..cebcea93 --- /dev/null +++ b/config/authng/pkg/authng.xml @@ -0,0 +1,194 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "../../schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="../../xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* $Id$ */ +/* ========================================================================== */ +/* + authng.xml + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + </copyright> + <description> + This package provides a user- and groupmanager which + allows to add arbitrary groups to the system and assign + them to a particular group. + + Permission control is provided on a per group basis. + </description> + <requirements> + This package is supposed to be run on RELENG based pfSense systems. + </requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>authng</name> + <version>1.0</version> + <title>System: User Manager</title> + <include_file>/usr/local/pkg/authng.inc</include_file> + <!-- Menu is where this packages menu will appear --> + <menu> + <name>Auth Manager</name> + <section>System</section> + <url>/system_usermanager.php</url> + </menu> + <!-- + <service> + <name>yourservice</name> + <rcfile>/usr/local/etc/rc.d/yourservice.sh</rcfile> + </service> + --> + <tabs /> + <!-- + configpath gets expanded out automatically and config items + will be stored in that location + --> + <configpath>['installedpackages']['authng']['config']</configpath> + <!-- + | + | PHP files (user management) + | + --> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/www/php/system_usermanager.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/www/php/system_usermanager_edit.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/www/php/system_usermanager_settings.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/www/php/system_groupmanager.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/www/php/head.inc</item> + </additional_files_needed> + <!-- + | + | Include files (class defs etc.) + | + --> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/pkg/authng_classdefs.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/pkg/authng_peers.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/pkg/authng.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/pkg/authng_backends.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/pkg/authng_authmethods.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/pkg/authng_authgui.inc</item> + </additional_files_needed> + <!-- + | + | Patch files + | + --> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/diff/authng-pfSenseHead.diff</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/diff/authng-fbegin.inc.diff</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/diff/authng-globals.inc.diff</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/diff/authng-guiconfig.inc.diff</item> + </additional_files_needed> + <!-- + | + | Binary files + | + --> + <additional_files_needed> + <prefix>/usr/bin/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/authng/bin/patch</item> + </additional_files_needed> + <!-- + fields gets invoked when the user adds or edits a item. The following items + will be parsed and rendered for the user as a gui with input, and selectboxes. + --> + <!-- + Arbitrary PHP Code, that gets executed if a certain event gets triggered. + --> + <custom_php_resync_config_command> + syncPackageAuthNG(); + </custom_php_resync_config_command> + <custom_php_install_command> + installPackageAuthNG(); + </custom_php_install_command> + <custom_php_deinstall_command> + deinstallPackageAuthNG(); + </custom_php_deinstall_command> +</packagegui> diff --git a/config/authng/pkg/authng_authgui.inc b/config/authng/pkg/authng_authgui.inc new file mode 100644 index 00000000..944c9b89 --- /dev/null +++ b/config/authng/pkg/authng_authgui.inc @@ -0,0 +1,287 @@ +<?php +/* $Id$ */ +/* ========================================================================== */ +/* + authng_authgui.inc + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + +require_once("authng.inc"); + +/* Authenticate user - exit if failed (we should have a callback for this maybe) */ +if (empty($authMethod)) { print "auth_method missing!\n"; } +if (empty($backend)) { print "backing_method missing!\n"; } +if (!$authMethod->authenticate($backend)) { exit; } + +/* scriptname is set in headjs.php if the user did try to access a page other + * than index.php without beeing logged in. + */ +if (isset($_POST['scriptname']) && $userPeer->isSystemAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + pfSenseHeader("{$_POST['scriptname']}"); + exit; +} + +$allowed = array(); + +// Once here, the user has authenticated with the web server. +// Now, we give them access only to the appropriate pages for their group. +if (!($userPeer->isSystemAdmin($HTTP_SERVER_VARS['AUTH_USER']))) { + $allowed[] = ''; + if (isset($config['system']['group'][$groupindex[$config['system']['user'][$userindex[$HTTP_SERVER_VARS['AUTH_USER']]]['groupname']]]['pages'][0]['page'])) { + $useridx = $userindex[$HTTP_SERVER_VARS['AUTH_USER']]; + $grouidx = $groupindex[$config['system']['user'][$useridx]]; + $allowed = &$config['system']['group'][$groupidx]['pages'][0]['page']; + } + + $group = $config['system']['user'][$userindex[$HTTP_SERVER_VARS['AUTH_USER']]]['groupname']; + /* get the group homepage, to be able to forward + * the user to this particular PHP page. + */ + $groupPeer->getGroupHomePage($group) == "" ? $home = "/index.php" : $home = "/" . $groupPeer->getGroupHomePage($group); + + /* okay but if the user realy tries to explicitely access a particular + * page, set $home to that page instead. + */ + if (isset($_POST['scriptname']) && $_POST['scriptname'] <> "/" && $_POST['scriptname'] <> "/index.php") + $home = basename($_POST['scriptname']); + + // If the user is attempting to hit the default page, set it to specifically look for /index.php. + // Without this, any user would have access to the index page. + //if ($_SERVER['SCRIPT_NAME'] == '/') + // $_SERVER['SCRIPT_NAME'] = $home; + + // Strip the leading / from the currently requested PHP page + if (!in_array(basename($_SERVER['SCRIPT_NAME']),$allowed)) { + // The currently logged in user is not allowed to access the page + // they are attempting to go to. Redirect them to an allowed page. + + if(stristr($_SERVER['SCRIPT_NAME'],"sajax")) { + echo "||Access to AJAX has been disallowed for this user."; + exit; + } + + if ($home <> "" && in_array($home, $allowed)) { + pfSenseHeader("{$home}"); + exit; + } else { + header("HTTP/1.0 401 Unauthorized"); + header("Status: 401 Unauthorized"); + + echo display_error_form("401", "401 Unauthorized. Authorization required."); + exit; + } + } + + if (isset($_SESSION['Logged_In'])) { + /* + * only forward if the user has just logged in + * TODO: session auth based - may be an issue. + */ + if ($_SERVER['SCRIPT_NAME'] <> $home && empty($_SESSION['First_Visit'])) { + $_SESSION['First_Visit'] = "False"; + pfSenseHeader("{$home}"); + exit; + } + } +} + +function display_error_form($http_code, $desc) { + global $g; + + $htmlstr = <<<EOD +<html> + <head> + <script type="text/javascript" src="/javascript/scriptaculous/prototype.js"></script> + <script type="text/javascript" src="/javascript/scriptaculous/scriptaculous.js"></script> + <title>An error occurred: {$http_code}</title> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <link rel="shortcut icon" href="/themes/{$g['theme']}/images/icons/favicon.ico" /> + <link rel="stylesheet" type="text/css" href="/themes/{$g['theme']}/all.css" media="all" /> + <style type="text/css"> + #errordesc { + background: #cccccc; + border: 0px solid #666666; + margin: 5em auto; + padding: 0em; + width: 340px; + } + #errordesc h1 { + background: url(/themes/{$g['theme']}/images/misc/logon.png) no-repeat top left; + margin-top: 0; + display: block; + text-indent: -1000px; + height: 50px; + border-bottom: none; + } + + #login p { + font-size: 1em; + font-weight: bold; + padding: 3px; + margin: 0em; + text-indent: 10px; + } + + #login span { + font-size: 1em; + font-weight: bold; + width: 20%; + padding: 3px; + margin: 0em; + text-indent: 10px; + } + + #login p#text { + font-size: 1em; + font-weight: normal; + padding: 3px; + margin: 0em; + text-indent: 10px; + } + </style> + + <script type="text/javascript"> + <!-- + function page_load() { + NiftyCheck(); + Rounded("div#errordesc","bl br","#333","#cccccc","smooth"); + Effect.Pulsate('errortext', { duration: 10 }); + } + <?php + require("headjs.php"); + echo getHeadJS(); + ?> + //--> + </script> + <script type="text/javascript" src="/themes/{$g['theme']}/javascript/niftyjsCode.js"></script> + </head> + <body onload="page_load();"> + <div id="errordesc"> + <h1> </h1> + <p id="errortext" style="vertical-align: middle; text-align: center;"><span style="color: #000000; font-weight: bold;">{$desc}</span></p> + </div> + </body> +</html> + +EOD; + + return $htmlstr; +} + +function display_login_form() { + require_once("globals.inc"); + global $g; + + if(isAjax()) { + if (isset($_POST['login'])) { + if($_SESSION['Logged_In'] <> "True") { + isset($_SESSION['Login_Error']) ? $login_error = $_SESSION['Login_Error'] : $login_error = "unknown reason"; + echo "showajaxmessage('Invalid login ({$login_error}).');"; + } + if (file_exists("{$g['tmp_path']}/webconfigurator.lock")) { + $whom = file_get_contents("{$g['tmp_path']}/webconfigurator.lock"); + echo "showajaxmessage('This device is currently beeing maintained by: {$whom}.');"; + } + } + exit; + } + +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + <head> + <script type="text/javascript" src="/javascript/scriptaculous/prototype.js"></script> + <script type="text/javascript" src="/javascript/scriptaculous/scriptaculous.js"></script> + <title><?=gettext("Login"); ?></title> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <link rel="shortcut icon" href="/themes/<?= $g['theme'] ?>/images/icons/favicon.ico" /> + <?php if (file_exists("{$g['www_path']}/themes/{$g['theme']}/login.css")): ?> + <link rel="stylesheet" type="text/css" href="/themes/<?= $g['theme'] ?>/login.css" media="all" /> + <?php else: ?> + <link rel="stylesheet" type="text/css" href="/themes/<?= $g['theme'] ?>/all.css" media="all" /> + <?php endif; ?> + <script type="text/javascript"> + <!-- + <?php if (file_exists("{$g['www_path']}/themes/{$g['theme']}/login.css")): ?> + var dontUseCustomBGColor = false; + <?php else: ?> + var dontUseCustomBGColor = true; + <?php endif; ?> + function page_load() { + NiftyCheck(); + Rounded("div#login","bl br","#333","#cccccc","smooth"); + document.login_iform.usernamefld.focus(); + } + function clearError() { + if($('inputerrors')) + $('inputerrors').innerHTML=''; + } + <?php +// require("headjs.php"); +// echo getHeadJS(); + ?> + //--> + </script> + <script type="text/javascript" src="/themes/<?= $g['theme'] ?>/javascript/niftyjsCode.js"></script> + </head> + <body onload="page_load()"> + <div id="login"> + <h1> </h1> + <form id="iform" name="login_iform" method="post" autocomplete="off" action="<?= $_SERVER['SCRIPT_NAME'] ?>"> + <div id="inputerrors"></div> + <p> + <span style="text-align: left;"> + <?=gettext("Username"); ?>: + </span> + <input onclick="clearError();" onchange="clearError();" id="usernamefld" type="text" name="usernamefld" class="formfld user" tabindex="1" /> + </p> + <p> + <span style="text-align: left;"> + <?=gettext("Password"); ?>: + </span> + <input onclick="clearError();" onchange="clearError();" id="passwordfld" type="password" name="passwordfld" class="formfld pwd" tabindex="2" /> + </p> + <table width="90%" style="margin-right: auto; margin-left: auto;"> + <tr> + <td valign="middle" align="right" style="font-style: italic;"><br /><?=gettext("Enter username and password to login."); ?></td> + <td valign="middle" align="left"><input type="submit" id="submit" name="login" class="formbtn" value="<?=gettext("Login"); ?>" tabindex="3" /></td> + </tr> + </table> + </form> + </div> + </body> +</html> +<?php +} // end function +?>
\ No newline at end of file diff --git a/config/authng/pkg/authng_authmethods.inc b/config/authng/pkg/authng_authmethods.inc new file mode 100644 index 00000000..15e15566 --- /dev/null +++ b/config/authng/pkg/authng_authmethods.inc @@ -0,0 +1,222 @@ +<?php +/* $Id$ */ +/* ========================================================================== */ +/* + authng_authmethods.inc + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + +class AbstractAuthMethod { + function authenticate($backend) { + trigger_error('AbstractAuthMethod::authenticate() needs to be overridden in a subclass.', E_USER_ERROR); + } +} + +class BasicAuthMethod extends AbstractAuthMethod { + function authenticate($backend) { + global $HTTP_SERVER_VARS; + + /* Check for AUTH_USER */ + if ($HTTP_SERVER_VARS['PHP_AUTH_USER'] <> "") { + $HTTP_SERVER_VARS['AUTH_USER'] = $HTTP_SERVER_VARS['PHP_AUTH_USER']; + $HTTP_SERVER_VARS['AUTH_PW'] = $HTTP_SERVER_VARS['PHP_AUTH_PW']; + } + if (!isset($HTTP_SERVER_VARS['AUTH_USER'])) { + require_once("authng_authgui.inc"); + header("WWW-Authenticate: Basic realm=\".\""); + header("HTTP/1.0 401 Unauthorized"); + display_error_form("401", gettext("You must enter valid credentials to access this resource.")); + exit; + } else { + return $backend($HTTP_SERVER_VARS['AUTH_USER'],$HTTP_SERVER_VARS['AUTH_PW']); + } + } +} + +class SessionAuthMethod extends AbstractAuthMethod { + function authenticate($backend) { + global $g, $HTTP_SERVER_VARS, $userindex, $config; + + session_start(); + + /* Validate incoming login request */ + if (isset($_POST['login'])) { + if ($backend($_POST['usernamefld'], $_POST['passwordfld'])) { + $_SESSION['Logged_In'] = "True"; + $_SESSION['Username'] = $_POST['usernamefld']; + $_SESSION['last_access'] = time(); + } else { + $_SESSION['Login_Error'] = "Username or password incorrect."; + } + } + + /* Show login page if they aren't logged in */ + if (empty($_SESSION['Logged_In'])) { + + /* Don't display login forms to AJAX */ + if (isAjax()) + return false; + + require_once("authng_authgui.inc"); + display_login_form(); + return false; + } else { + /* If session timeout isn't set, we don't mark sessions stale */ + if (!isset($config['system']['webgui']['session_timeout']) or + $config['system']['webgui']['session_timeout'] == 0 or + $config['system']['webgui']['session_timeout'] == "") + $_SESSION['last_access'] = time(); + else + /* Check for stale session */ + if ($_SESSION['last_access'] < (time() - ($config['system']['webgui']['session_timeout'] * 60))) + $_GET['logout'] = true; + else + /* only update if it wasn't ajax */ + if (!isAjax()) + $_SESSION['last_access'] = time(); + + /* user hit the logout button */ + if (isset($_GET['logout'])) { + if (hasLockAbility($_SESSION['Username'])) { + unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock"); + } + + /* wipe out $_SESSION */ + $_SESSION = array(); + + if (isset($_COOKIE[session_name()])) { + setcookie(session_name(), '', time()-42000, '/'); + } + + /* and destroy it */ + session_destroy(); + + $scriptName = split("/", $_SERVER["SCRIPT_FILENAME"]); + $scriptElms = count($scriptName); + $scriptName = $scriptName[$scriptElms-1]; + + if (isAjax()) + return false; + + /* redirect to page the user is on, it'll prompt them to login again */ + pfSenseHeader($scriptName); + + return false; + + /* user wants to explicitely delete the log file. + * Requires a particular privilege. + */ + } else if ($_GET['deletelock'] && hasLockAbility($_SESSION['Username'])) { + unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock"); + $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username']; + return true; + + /* this is for debugging purpose if you do not want to use Ajax + * to submit a HTML form. It basically disables the observation + * of the submit event and hence does not trigger Ajax. + */ + } else if ($_GET['disable_ajax']) { + $_SESSION['NO_AJAX'] = "True"; + $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username']; + return true; + + /* Same to re-enable Ajax. + */ + } else if ($_GET['enable_ajax']) { + unset($_SESSION['NO_AJAX']); + $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username']; + return true; + + /* user wants to explicitely create a lock. + * Requires a particular privilege. + */ + } else if ($_GET['createlock'] && hasLockAbility($_SESSION['Username'])) { + $fd = fopen("{$g['tmp_path']}/webconfigurator.lock", "w"); + fputs($fd, "{$_SERVER['REMOTE_ADDR']} (" . + getRealName($_SESSION['Username']) . ")"); + fclose($fd); + /* if the user did delete the lock manually, do not + * re-create it while the session is valide. + */ + $_SESSION['Lock_Created'] = "True"; + $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username']; + return true; + + /* proceed with the login process */ + } else { + /* if the user is allowed to create a lock, + * create it once per session. + */ + if (hasLockAbility($_SESSION['Username']) && + ! isset($_SESSION['Lock_Created'])) { + + $fd = fopen("{$g['tmp_path']}/webconfigurator.lock", "w"); + fputs($fd, "{$_SERVER['REMOTE_ADDR']} (" . + getRealName($_SESSION['Username']) . ")"); + fclose($fd); + /* if the user did delete the lock manually, do not + * re-create it while the session is valide. + */ + $_SESSION['Lock_Created'] = "True"; + + /* give regular users a chance to automatically invalidate + * a lock if its older than a particular time. + */ + } else if (! hasLockAbility($_SESSION['Username']) && + file_exists("{$g['tmp_path']}/webconfigurator.lock")) { + + $offset = 12; //hours + $mtime = filemtime("{$g['tmp_path']}/webconfigurator.lock"); + $now_minus_offset = mktime(date("H") - $offset, 0, 0, date("m"), date("d"), date("Y")); + + if (($mtime - $now_minus_offset) < $mtime) { + require_once("auth/authgui.inc"); + display_login_form(); + return false; + } else { + /* file is older than mtime + offset which may + * indicate a stale lockfile, hence we are going + * to remove it. + */ + unlink_if_exists("{$g['tmp_path']}/webconfigurator.lock"); + } + } + + $HTTP_SERVER_VARS['AUTH_USER'] = $_SESSION['Username']; + return true; + } // end if + } // end if + } // end function +} + +?>
\ No newline at end of file diff --git a/config/authng/pkg/authng_backends.inc b/config/authng/pkg/authng_backends.inc new file mode 100644 index 00000000..1b58e6c1 --- /dev/null +++ b/config/authng/pkg/authng_backends.inc @@ -0,0 +1,234 @@ +<?php +/* $Id$ */ +/* ========================================================================== */ +/* + authng_backends.inc + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + +class AbstractBackend { + function authenticate($username, $passwd) { + trigger_error('AbstractBackend::authenticate() needs to be overridden in a subclass.', E_USER_ERROR); + } +} + +class HtpasswdBackend extends AbstractBackend { + function HtpasswdBackend() { + } + + function authenticate($username, $passd) { + $authfile = file("/var/run/htpasswd"); + + /* sanity check to ensure that /usr/local/www/.htpasswd doesn't exist */ + unlink_if_exists("/usr/local/www/.htpasswd"); + + $matches=""; + if(!($line = array_shift(preg_grep("/^$username:.*$/", $authfile)))) + return false; + + /* Get crypted password */ + preg_match("/^$username:((\\$1\\$[.\d\w_\/]{8}\\$)[.\d\w_\/]{22})$/", $line, $matches); + $pass = $matches[1]; + $salt = $matches[2]; + + /* Encrypt entered password with salt + * And finally validate password + */ + if ($pass == crypt($passwd, $salt)) + return true; + else + return false; + } +} + +class PasswdBackend extends AbstractBackend { + function PasswdBackend() { + } + + function authenticate($username, $passd) { + $authfile = file("/etc/master.passwd"); + + $matches=""; + + /* Check to see if user even exists */ + if(!($line = array_shift(preg_grep("/^$username:.*$/", $authfile)))) + return false; + + /* Get crypted password */ + preg_match("/^$username:((\\$1\\$[.\d\w_\/]{8}\\$)[.\d\w_\/]{22})$/", $line, $matches); + $pass = $matches[1]; + $salt = $matches[2]; + + /* Encrypt entered password with salt + * And finally validate password + */ + if ($pass == crypt($passwd, $salt)) + return true; + else + return false; + } +} + +class PamBackend extends AbstractBackend { + function PamBackend() { + } + + function authenticate($username, $passd) { + /* we do not support blank pwds, don't we? */ + if ($username == "" || passwd == "") { return false; } + + if(! extension_loaded( 'pam_auth' )) { + if(! @dl( 'pam_auth.so' )) { + return false; + } else { + /* no php file no auth, sorry */ + if (! file_exists("/etc/pam.d/php")) { + if (! file_exists("/etc/pam.d")) { mkdir("/etc/pam.d"); } + + $pam_php = <<<EOD +# /etc/pam.d/php +# +# note: both an auth and account entry are required + +# auth +auth required pam_nologin.so no_warn +auth sufficient pam_opie.so no_warn no_fake_prompts +auth requisite pam_opieaccess.so no_warn allow_local +auth required pam_unix.so no_warn try_first_pass + +# account +account required pam_unix.so + +# session +session required pam_permit.so + +# password +password required pam_unix.so no_warn try_first_pass + +EOD; + + file_put_contents("/etc/pam.d/php", $pam_php); + } // end if + + if (pam_auth($username, $passwd, &$error)) { + return true; + } else { + return false; + } + } // end if + } // end if + } // end function +} + +class RadiusBackend extends AbstractBackend { + function RadiusBackend() { + } + + function authenticate($username, $passwd) { + global $config, $debug; + $ret = false; + $radiusservers = $config['system']['radius']['servers']; + + $rauth = new Auth_RADIUS_PAP($username, $passwd); + foreach ($radiusservers as $radsrv) { + // Add a new server to our instance + $rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['sharedsecret']); + } + + if (!$rauth->start()) { + $retvalue['auth_val'] = 1; + $retvalue['error'] = $rauth->getError(); + if ($debug) + printf("Radius start: %s", $retvalue['error']); + } + + // XXX - billm - somewhere in here we need to handle securid challenge/response + + // Send request + $result = $rauth->send(); + + if (PEAR::isError($result)) { + $retvalue['auth_val'] = 1; + $retvalue['error'] = $result->getMessage(); + if ($debug) + printf("Radius send failed: %s", $retvalue['error']); + } else if ($result === true) { + $retvalue['auth_val'] = 2; + if ($debug) + printf (gettext("Radius Auth succeeded")); + $ret = true; + } else { + $retvalue['auth_val'] = 3; + if ($debug) + printf (gettext("Radius Auth rejected")); + } + // close OO RADIUS_AUTHENTICATION + $rauth->close(); + + return $ret; + } // end function +} + +class LdapBackend extends AbstractBackend { + function LdapBackend() { + } + + function authenticate($username, $passwd) { + $ldapserver = $config['system']['ldap']['server']; + $ldapport = isset($config['system']['ldap']['port']) ? $config['system']['ldap']['server'] : 389; + $retval = false; + + $connection = ldap_connect($ldapserver, $ldapport) + or die("Could not connect to $ldaphost"); + + if ($connection) { + $bind = ldap_bind($connection); + + if ($bind) { + $basedn = $config['system']['ldap']['basedn']; + $result = ldap_search($connection, $basedn, "uid={$username}"); + $info = ldap_get_entries($connection, $result); + $userPassword = $info[0]['userPassword']; + + if ($userPassword == $passwd) { + $retval = true; + } else { + $retval = false; + } + } // end if + } // end if + + return $retval; + } +} +?>
\ No newline at end of file diff --git a/config/authng/pkg/authng_classdefs.inc b/config/authng/pkg/authng_classdefs.inc new file mode 100644 index 00000000..64f0ff14 --- /dev/null +++ b/config/authng/pkg/authng_classdefs.inc @@ -0,0 +1,479 @@ +<?php +/* $Id$ */ +/* ========================================================================== */ +/* + authng_classdefs.inc + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + +class Object { + function Object() { + $args = func_get_args(); + if (method_exists($this, '__destruct')) { + register_shutdown_function(array(&$this, '__destruct')); + } + call_user_func_array(array(&$this, '__construct'), $args); + } + + function __construct() { + } +} + +class SingletonInterface extends Object { + function __construct() { + // Perform object initialization here. + } + + function &__getInstanceImp($name) { + static $instances = array(); + if (!isset($instances[$name])) { + $instances[$name] = new $name(); // No changes necessary here. + } + return $instances[$name]; + } + + function &getInstance() { + trigger_error('SingletonInterface::getInstance() needs to be overridden in a subclass.', E_USER_ERROR); + } +} + +class BackendFactory extends SingletonInterface { + function __construct() { + // Perform object initialization here. + parent::__construct(); + } + + function &getInstance() { + return parent::__getInstanceImp('BackendFactory'); + } + + function &getBackendByName($name) { + $result = null; + + /* Each name links to an entry in config.xml + * Example: <auth_method>session</auth_method> + */ + switch ($name) { + case "htpasswd": + $result = new HtpasswdBackend(); + break; + case "pam": + $result = new PamBackend(); + break; + case "radius": + $result = new RadiusBackend(); + break; + case "passwd": + $result = new PasswdBackend(); + break; + case "ldap": + $result = new LdapBackend(); + break; + default: + } + + return $result; + } +} + +class AuthMethodFactory extends SingletonInterface { + function __construct() { + // Perform object initialization here. + parent::__construct(); + } + + function &getInstance() { + return parent::__getInstanceImp('AuthMethodFactory'); + } + + function &getAuthMethodByName($name) { + $result = null; + + /* Each name links to an entry in config.xml + * Example: <backing_method>htpasswd</backing_method> + */ + switch ($name) { + case "session": + $result = new SessionAuthMethod(); + break; + case "basic": + $result = new BasicAuthMethod(); + break; + default: + } + + return $result; + } +} + +class AuthngAuxiliary { + /* ========================================================================== */ + /* == Auxiliary Functions == */ + /* ========================================================================== */ + function &getSystemAdminNames() { + global $config, $g, $userindex; + $adminUsers = array(); + + if (is_array($config['system']['user'])) { + foreach($config['system']['user'] as $user){ + if (isSystemAdmin($user['name'])) { + $adminUsers[] = $user['name']; + } + } // end foreach + } // end if + + return $adminUsers; + } // end function + + function assignUID($username = "") { + global $userindex, $config, $g; + + if ($username == "") { return; } + + $nextuid = $config['system']['nextuid']; + $user =& $config['system']['user'][$userindex[$username]]; + + if (empty($user['uid'])) { + $user['uid'] = $nextuid; + $nextuid++; + $config['system']['nextuid'] = $nextuid; + + write_config(); + + return $user; + } // end if + } // end function +} + +class AuthngPrivilege { + /* ========================================================================== */ + /* == Class Members == */ + /* ========================================================================== */ + + var $id; + var $name; + var $description; + + /* ========================================================================== */ + /* == Constructor == */ + /* ========================================================================== */ + + function AuthngPrivilege() { + } + + /* ========================================================================== */ + /* == Accessors == */ + /* ========================================================================== */ + + function getId() { + return $this->id; + } + + function setId($id) { + $this->id = $id; + } + + function getName() { + return $this->name; + } + + function setName($name) { + $this->name = $name; + } + + function getDescription() { + return $this->description; + } + + function setDescription($desc) { + $this->description = $desc; + } +} + +class SystemPrivileges { + /* ========================================================================== */ + /* == Class Members == */ + /* ========================================================================== */ + + var $privileges = array(); + + /* ========================================================================== */ + /* == Constructor == */ + /* ========================================================================== */ + + function SystemPrivileges() { + $newPriv = new Privilege(); + $newPriv->setId("lockwc"); + $newPriv->setName("Lock webConfigurator"); + $newPriv->setDescription("Indicates whether this user will lock access to the webConfigurator for other users."); + + $this->privileges[$newPriv->getId()] = $newPriv; + + $newPriv = new Privilege(); + $newPriv->setId("lock-ipages"); + $newPriv->setName("Lock individual pages"); + $newPriv->setDescription("Indicates whether this user will lock individual " . + "HTML pages after having accessed a particular page" . + "(the lock will be freed if the user leaves or " . + "saves the page form)."); + + $this->privileges[$newPriv->getId()] = $newPriv; + + $newPriv = new Privilege(); + $newPriv->setId("hasshell"); + $newPriv->setName("Has shell access"); + $newPriv->setDescription("Indicates whether this user is able to login for " . + "example via SSH."); + + $this->privileges[$newPriv->getId()] = $newPriv; + + $newPriv = new Privilege(); + $newPriv->setId("copyfiles"); + $newPriv->setName("Is allowed to copy files"); + $newPriv->setDescription("Indicates whether this user is allowed to copy files " . + "onto the {$g['product_name']} appliance via SCP/SFTP. " . + "If you are going to use this privilege, you must install " . + "scponly on the appliance (Hint: pkg_add -r scponly)."); + + $this->privileges[$newPriv->getId()] = $newPriv; + + $newPriv = new Privilege(); + $newPriv->setId("isroot"); + $newPriv->setName("Is root user"); + $newPriv->setDescription("This user is associated with the UNIX root user " . + "(you should associate this privilege only with one " . + "single user)."); + + $this->privileges[$newPriv->getId()] = $newPriv; + } + + /* ========================================================================== */ + /* == Accessors == */ + /* ========================================================================== */ + + function getPrivileges() { + return $this->privileges; + } + + function setPrivileges($privs) { + $this->privileges = $privs; + } + + function getPrivilegeById($id) { + return $this->privileges[$id]; + } + + function setPrivilegeById($privilege, $id) { + return $this->privileges[$id] = $privilege; + } +} + +class AuthngUser { + /* ========================================================================== */ + /* == Class Members == */ + /* ========================================================================== */ + + var $name; + var $fullname; + var $scope; + var $groupname; + var $password; + var $uid; + var $systemAdmin = false; + var $unixRoot = false; + var $privileges = array(); + + /* ========================================================================== */ + /* == Constructor == */ + /* ========================================================================== */ + + function AuthngUser() { + } + + /* ========================================================================== */ + /* == Accessors == */ + /* ========================================================================== */ + + function isSystemAdmin() { + return $this->systemAdmin; + } + + function setIsSystemAdmin($flag = false) { + $this->systemAdmin = $flag; + } + + function isUNIXRoot() { + return $this->unixRoot; + } + + function setIsUNIXRoot($flag = false) { + $this->unixRoot = $flag; + } + + function getName() { + return $this->name; + } + + function setName($name) { + $this->name = $name; + } + + function getFullname() { + return $this->fullname; + } + + function setFullname($name) { + $this->fullname = $name; + } + + function getScope() { + return $this->scope; + } + + function setScope($scope) { + $this->scope = $scope; + } + + function getGroupname() { + return $this->groupname; + } + + function setGroupname($name) { + $this->groupname = $name; + } + + function getPassword() { + return $this->password; + } + + function setPassword($pwd) { + $this->password = $pwd; + } + + function getUid() { + return $this->uid; + } + + function setUid($uid) { + $this->uid = $uid; + } + + function getPrivileges() { + return $this->privileges; + } + + function setPrivileges($privs) { + $this->privileges = $privs; + } + + function addPrivilege($priv) { + $this->privileges[] = $priv; + } +} + +class AuthngGroup { + /* ========================================================================== */ + /* == Class Members == */ + /* ========================================================================== */ + + var $name; + var $description; + var $scope; + var $pages = array(); + var $home; + var $gid; + + /* ========================================================================== */ + /* == Constructor == */ + /* ========================================================================== */ + + function AuthngGroup() { + } + + /* ========================================================================== */ + /* == Accessors == */ + /* ========================================================================== */ + + function getName() { + return $this->name; + } + + function setName($name) { + $this->name = $name; + } + + function getDescription() { + return $this->description; + } + + function setDescription($desc) { + $this->description = $desc; + } + + function getScope() { + return $this->scope; + } + + function setScope($scope) { + $this->scope = $scope; + } + + function getPages() { + return $this->pages; + } + + function setPages($pages) { + $this->pages = $pages; + } + function getHome() { + return $this->home; + } + + function setHome($home) { + $this->home = $home; + } + + function getGid() { + return $this->gid; + } + + function setGid($gid) { + $this->gid = $gid; + } + + function addPage($page) { + $this->pages[] = $page; + } +} + +?>
\ No newline at end of file diff --git a/config/authng/pkg/authng_peers.inc b/config/authng/pkg/authng_peers.inc new file mode 100644 index 00000000..bce3c494 --- /dev/null +++ b/config/authng/pkg/authng_peers.inc @@ -0,0 +1,501 @@ +<?php +/* $Id$ */ +/* ========================================================================== */ +/* + authng_peers.inc + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + +class PeerFactory extends SingletonInterface { + function __construct() { + // Perform object initialization here. + parent::__construct(); + } + + function &getInstance() { + return parent::__getInstanceImp('PeerFactory'); + } + + function &getGroupPeerByPrincipalStore($store) { + $result = null; + + /* Each name links to an entry in config.xml + * Example: <principal_store>xml</principal_store> + */ + switch ($store) { + case "xml": + $result = new XMLGroupPeer(); + break; + case "ldap": + trigger_error('PeerFactory::getGroupPeerByPrincipal() LDAP peer type is not supported.', E_USER_ERROR); + break; + case "db": + trigger_error('PeerFactory::getGroupPeerByPrincipal() DB peer type is not supported.', E_USER_ERROR); + break; + default: + } + + return $result; + } + + function &getUserPeerByPrincipalStore($store) { + $result = null; + + /* Each name links to an entry in config.xml + * Example: <principal_store>xml</principal_store> + */ + switch ($store) { + case "xml": + $result = new XMLUserPeer(); + break; + case "ldap": + trigger_error('PeerFactory::getGroupPeerByPrincipal() LDAP peer type is not supported.', E_USER_ERROR); + break; + case "db": + trigger_error('PeerFactory::getGroupPeerByPrincipal() DB peer type is not supported.', E_USER_ERROR); + break; + default: + } + + return $result; + } +} + +/** + * @author Daniel S. Haischt <me@daniel.stefan.haischt.name> + * @abstract + */ +class AbstractPrivilegePeer { + /* ========================================================================== */ + /* == Class Members == */ + /* ========================================================================== */ + + var $privilege_index; + var $privileges; + var $userPeer; + + /* ========================================================================== */ + /* == Constructor == */ + /* ========================================================================== */ + + function AbstractPrivilegePeer() { + } + + /* ========================================================================== */ + /* == Accessors == */ + /* ========================================================================== */ + + function setUserPeer($peer) { + $this->userPeer = $peer; + } + + function getUserPeer() { + return $this->userPeer; + } + + /** + * @return mixed int array of priv indexes + */ + function getPrivilegeIndex() { + return $this->privilege_index; + } + + /** + * @param string a priv name + * @return int the index that corresponds to a username + */ + function getPrivilegeIndexByID($id) { + return $this->privilege_index[$id]; + } + + /** + * @param int an index + * @return mixed an instance of AuthngPrivilege + */ + function getPrivilegeByIndex($index) { + return $this->privileges[$index]; + } +} + +/** + * @author Daniel S. Haischt <me@daniel.stefan.haischt.name> + * @abstract + */ +class AbstractUserPeer { + /* ========================================================================== */ + /* == Class Members == */ + /* ========================================================================== */ + + var $user_index; + var $users; + + /* ========================================================================== */ + /* == Constructor == */ + /* ========================================================================== */ + + function AbstractUserPeer() { + } + + /* ========================================================================== */ + /* == Accessors == */ + /* ========================================================================== */ + + /** + * @return mixed int array of user indexes + */ + function getUserIndex() { + return $this->user_index; + } + + /** + * @param string a username + * @return int the index that corresponds to a username + */ + function getUserIndexByName($username) { + return $this->user_index[$username]; + } + + /** + * @param int an index + * @return mixed an instance of AuthngUser + */ + function getUserByIndex($index) { + return $this->users[$index]; + } + + function getUserByName($username) { + return $this->users[$username]; + } + + function isSystemAdmin($username) { + $result = false; + $user = $this->getUserByName($username); + + if ($user) { + $result = $user->isSystemAdmin(); + } + + return $result; + } +} + +/** + * @author Daniel S. Haischt <me@daniel.stefan.haischt.name> + * @abstract + */ +class AbstractGroupPeer { + /* ========================================================================== */ + /* == Class Members == */ + /* ========================================================================== */ + + var $group_index; + var $groups; + + /* ========================================================================== */ + /* == Constructor == */ + /* ========================================================================== */ + + function AbstractGroupPeer() { + } + + /* ========================================================================== */ + /* == Accessors == */ + /* ========================================================================== */ + + function getGroupIndex() { + return $this->group_index; + } + + function getGroupIndexByName($groupname) { + return $this->group_index[$groupname]; + } + + function getGroupByIndex($index) { + return $this->groups[$index]; + } + + function getGroupByName($groupname) { + return $this->groups[$groupname]; + } + + function getGroupHomePage($groupname) { + $result = false; + $group = $this->getGroupByName($groupname); + + if ($group) { + $result = $group->getHome(); + } + + return $result; + } +} + +/** + * @author Daniel S. Haischt <me@daniel.stefan.haischt.name> + */ +class XMLPrivilegePeer extends AbstractPrivilegePeer { + /* ========================================================================== */ + /* == Class Members == */ + /* ========================================================================== */ + + /* ========================================================================== */ + /* == Constructor == */ + /* ========================================================================== */ + + function XMLPrivilegePeer($userPeer) { + global $g, $config; + + parent::AbstractPrivilegePeer(); + + $this->setUserPeer($peer); + + foreach ($peer->users as $userent) { + foreach ($userent->getPrivileges() as $privent) { + $this->privileges[$userent->getName()] = $privent; + } + } + } + + /* ========================================================================== */ + /* == Accessors == */ + /* ========================================================================== */ + + /* ========================================================================== */ + /* == Helper Methods == */ + /* ========================================================================== */ + + function addPrivilegeFromEnt(&$ent) { + $newPrivilege = new AuthngUser(); + $newPrivilege->setId($ent['id']); + $newPrivilege->setName($ent['name']); + $newPrivilege->setDescription($ent['description']); + $newPrivilege->setPassword($ent['password']); + $newPrivilege->setUid($ent['uid']); + + $this->privileges[] = $newPrivilege; + } + + function setPrivilegeID($id, $name, $username) { + $userid = getPrivilegeIndexByName($username); + $user = $config['system']['user'][$userid]; + } + + function setFullName($id, $name) { + $userid = getUserIndexByName($id); + $config['system']['user'][$userid]['fullname'] = $name; + } + + function setGroupName($id, $name) { + $userid = getUserIndexByName($id); + $config['system']['user'][$userid]['groupname'] = $name; + } + + function setPassword($id, $pwd) { + $userid = getUserIndexByName($id); + $config['system']['user'][$userid]['password'] = $pwd; + } + + function setUid($id, $uid) { + $userid = getUserIndexByName($id); + $config['system']['user'][$userid]['uid'] = $uid; + } +} + +/** + * @author Daniel S. Haischt <me@daniel.stefan.haischt.name> + */ +class XMLUserPeer extends AbstractUserPeer { + /* ========================================================================== */ + /* == Class Members == */ + /* ========================================================================== */ + + /* ========================================================================== */ + /* == Constructor == */ + /* ========================================================================== */ + + function XMLUserPeer() { + global $g, $config; + + parent::AbstractUserPeer(); + + if (isset($config['system']['user'])) { + $i = 0; + + foreach($config['system']['user'] as $userent) { + $this->user_index[$userent['name']] = $i; + $this->addUserFromEnt($userent); + $i++; + } + } + } + + /* ========================================================================== */ + /* == Accessors == */ + /* ========================================================================== */ + + /* ========================================================================== */ + /* == Helper Methods == */ + /* ========================================================================== */ + + function addUserFromEnt(&$ent) { + print "HURTZ"; + $newUser = new AuthngUser(); + $newUser->setName($ent['name']); + $newUser->setFullname($ent['fullname']); + $newUser->setGroupname($ent['groupname']); + $newUser->setPassword($ent['password']); + $newUser->setUid($ent['uid']); + + if ($ent['priv'] && is_array($ent['priv'])) { + foreach ($ent['priv'] as $privent) { + $newPrivilege = new Privilege(); + $newPrivilege->setId($privent['id']); + $newPrivilege->setName($privent['name']); + $newPrivilege->setDescription($privent['description']); + + $newUser->addPrivilege($newPrivilege); + } + } + + $this->users["${ent['name']}"] = $newUser; + } + + function setUserName($id, $name) { + $userid = getUserIndexByName($id); + $config['system']['user'][$userid]['name'] = $name; + } + + function setFullName($id, $name) { + $userid = getUserIndexByName($id); + $config['system']['user'][$userid]['fullname'] = $name; + } + + function setGroupName($id, $name) { + $userid = getUserIndexByName($id); + $config['system']['user'][$userid]['groupname'] = $name; + } + + function setPassword($id, $pwd) { + $userid = getUserIndexByName($id); + $config['system']['user'][$userid]['password'] = $pwd; + } + + function setUid($id, $uid) { + $userid = getUserIndexByName($id); + $config['system']['user'][$userid]['uid'] = $uid; + } +} + +/** + * @author Daniel S. Haischt <me@daniel.stefan.haischt.name> + */ +class XMLGroupPeer extends AbstractGroupPeer { + /* ========================================================================== */ + /* == Class Members == */ + /* ========================================================================== */ + + /* ========================================================================== */ + /* == Constructor == */ + /* ========================================================================== */ + + function XMLGroupPeer() { + global $g, $config; + + parent::AbstractGroupPeer(); + + if (isset($config['system']['group'])) { + $i = 0; + + foreach($config['system']['group'] as $groupent) { + $this->group_index[$groupent['name']] = $i; + $i++; + } + } + } + + /* ========================================================================== */ + /* == Accessors == */ + /* ========================================================================== */ + + /* ========================================================================== */ + /* == Helper Methods == */ + /* ========================================================================== */ + + function addGroupFromEnt(&$ent) { + $newGoup = new AuthngGroup(); + $newGoup->setName($ent['name']); + $newGoup->setDescription($ent['description']); + $newGoup->setScope($ent['scope']); + $newGoup->setHome($ent['home']); + $newGoup->setGid($ent['gid']); + + if ($ent['pages'] && is_array($ent['gid'])) { + foreach ($ent['pages'] as $pageent) { + $newGoup->addPage($pageent); + } + } + + $this->groups["${ent['name']}"] = $newGoup; + } + + function setGroupName($id, $name) { + $groupid = getGroupIndexByName($id); + $config['system']['group'][$groupid]['name'] = $name; + } + + function setGroupDescription($id, $desc) { + $groupid = getGroupIndexByName($id); + $config['system']['group'][$groupid]['description'] = $desc; + } + + function setGroupScope($id, $scope) { + $groupid = getGroupIndexByName($id); + $config['system']['group'][$groupid]['scope'] = $scope; + } + + function setGroupHome($id, $home) { + $groupid = getGroupIndexByName($id); + $config['system']['group'][$groupid]['home'] = $home; + } + + function setGroupGid($id, $gid) { + $groupid = getGroupIndexByName($id); + $config['system']['group'][$groupid]['gid'] = $gid; + } + + function addPageToGroup($id, $page) { + $groupid = getGroupIndexByName($id); + $config['system']['group'][$groupid]['pages'][] = $page; + } +} +?> diff --git a/config/authng/pkg/authng_usermanager.inc b/config/authng/pkg/authng_usermanager.inc new file mode 100644 index 00000000..f96759fb --- /dev/null +++ b/config/authng/pkg/authng_usermanager.inc @@ -0,0 +1,247 @@ +<?php +/* $Id$ */ +/* ========================================================================== */ +/* + authng_usermanager.inc + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + +function initUserFromGetVars() { + if ($_GET['act'] == "edit") { + if (isset($id) && $a_user[$id]) { + $pconfig['usernamefld'] = $a_user[$id]['name']; + $pconfig['fullname'] = $a_user[$id]['fullname']; + $pconfig['groupname'] = $a_user[$id]['groupname']; + $pconfig['utype'] = $a_user[$id]['scope']; + $pconfig['authorizedkeys'] = base64_decode($a_user[$id]['authorizedkeys']); + } + } else if ($_GET['act'] == "new") { + /* set this value cause the text field is read only + * and the user should not be able to mess with this + * setting. + */ + $pconfig['utype'] = "user"; + } +} +function processUserManagerPostVarsUser() { + if (isset($_POST['save'])) { + unset($input_errors); + + /* input validation */ + $reqdfields = explode(" ", "passwordfld1"); + $reqdfieldsn = explode(",", "Password"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + if ($_POST['passwordfld1'] != $_POST['passwordfld2']) + $input_errors[] = "The passwords do not match."; + + if (!$input_errors) { + // all values are okay --> saving changes + $config['system']['user'][$userindex[$HTTP_SERVER_VARS['AUTH_USER']]]['password'] = crypt(trim($_POST['passwordfld1'])); + + write_config(); + + sync_webgui_passwords(); + + $retval = system_password_configure(); + $savemsg = get_std_save_message($retval); + $savemsg = "Password successfully changed<br />"; + } + } +} + +function processUserManagerPostVarsAdmin() { + $id = $_GET['id']; + if (isset($_POST['id'])) + $id = $_POST['id']; + + if (!is_array($config['system']['user'])) { + $config['system']['user'] = array(); + } + + admin_users_sort(); + $a_user = &$config['system']['user']; + $t_privs = $a_user[$id]['priv']; + + if ($_GET['act'] == "del" && $_GET['what'] == "user") { + if ($a_user[$_GET['id']]) { + $userdeleted = $a_user[$_GET['id']]['name']; + unset($a_user[$_GET['id']]); + write_config(); + $retval = system_password_configure(); + $savemsg = get_std_save_message($retval); + $savemsg = gettext("User") . " " . $userdeleted . " " . gettext("successfully deleted") . "<br />"; + } + } else if ($_GET['act'] == "del" && $_GET['what'] == "priv") { + if ($t_privs[$_GET['privid']]) { + $privdeleted = $t_privs[$_GET['privid']]['id']; + unset($t_privs[$_GET['privid']]); + write_config(); + $_GET['act'] = "edit"; + $retval = 0; + $savemsg = get_std_save_message($retval); + $savemsg = gettext("Privilege") . " " . $privdeleted . " " . gettext("of user") . " " . $a_user[$_GET['id']]['name'] . " " . gettext("successfully deleted") . "<br />"; + } + } + + if ($_POST) { + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + if (isset($id) && ($a_user[$id])) { + $reqdfields = explode(" ", "usernamefld"); + $reqdfieldsn = explode(",", "Username"); + } else { + $reqdfields = explode(" ", "usernamefld passwordfld1"); + $reqdfieldsn = explode(",", "Username,Password"); + } + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + if (hasShellAccess($_POST['usernamefld'])) { + if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['usernamefld'])) + $input_errors[] = gettext("The username contains invalid characters."); + } else { + if (preg_match("/[^a-zA-Z0-9\@\.\-_]/", $_POST['usernamefld'])) + $input_errors[] = gettext("The username contains invalid characters."); + } + + if (($_POST['passwordfld1']) && ($_POST['passwordfld1'] != $_POST['passwordfld2'])) + $input_errors[] = gettext("The passwords do not match."); + + if (!$input_errors && !(isset($id) && $a_user[$id])) { + /* make sure there are no dupes */ + foreach ($a_user as $userent) { + if ($userent['name'] == $_POST['usernamefld']) { + $input_errors[] = gettext("Another entry with the same username already exists."); + break; + } + } + } + + if ($pconfig['utype'] <> "system" && !isset($groupindex[$_POST['groupname']])) { + $input_errors[] = gettext("group does not exist, please define the group before assigning users."); + } + + if (isset($config['system']['ssh']['sshdkeyonly']) && + empty($_POST['authorizedkeys'])) { + $input_errors[] = gettext("You must provide an authorized key otherwise you won't be able to login into this system."); + } + + /* if this is an AJAX caller then handle via JSON */ + if (isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + exit; + } + + if (!$input_errors) { + if (isset($id) && $a_user[$id]) + $userent = $a_user[$id]; + + /* the user did change his username */ + if ($_POST['usernamefld'] <> $_POST['oldusername']) { + $_SERVER['REMOTE_USER'] = $_POST['usernamefld']; + } + + $userent['name'] = $_POST['usernamefld']; + $userent['fullname'] = $_POST['fullname']; + if ($pconfig['utype'] <> "system") { + $userent['groupname'] = $_POST['groupname']; + } + isset($_POST['utype']) ? $userent['scope'] = $_POST['utype'] : $userent['scope'] = "system"; + + if ($_POST['passwordfld1']) + $userent['password'] = crypt($_POST['passwordfld1']); + + if(isset($config['system']['ssh']['sshdkeyonly'])) { + $userent['authorizedkeys'] = base64_encode($_POST['authorizedkeys']); + } + + if (isset($id) && $a_user[$id]) + $a_user[$id] = $userent; + else + $a_user[] = $userent; + + write_config(); + $retval = system_password_configure(); + sync_webgui_passwords(); + + pfSenseHeader("system_usermanager.php"); + } + } +} + +/** + * getWindowJSScriptRefs() + * + * @return + */ +function getWindowJSScriptRefs(){ + $result = array('<script type="text/javascript" src="/javascripts/windows-js/javascript/effects.js"></script>', + '<script type="text/javascript" src="/javascripts/windows-js/javascript/window.js"></script>', + '<script type="text/javascript" src="/javascripts/windows-js/javascript/window_effects.js"></script>', + '<script type="text/javascript" src="/javascripts/windows-js/javascript/window_effects.js"></script>', + '<script type="text/javascript" src="/javascripts/windows-js/javascript/debug.js"></script>'); + + return $result; +} + +/** + * openNoUserDefsDialog() + * + * @param mixed $effectClass + * @return + */ +function openNoUserDefsDialog($effectClass) { + if (empty($config['installedpackages']['authng']['config'])) { + $alertMessage = gettext("No users or group found. You will be forwarded to the AuthNG wizard to be able to define users and groups."); + $dialogScript = " + <script type='text/javascript'> + function forwardToWizard() { + window.location.href = '/wizard.php?xml=authng_wizard.xml'; + } + + function openNoUserDefsDialog(html) { + var effect = new PopupEffect(html, {className: '${effectClass}'}); + Dialog.alert('${alertMessage},{className:'alphacube', width: 400, height:null, showEffect:effect.show.bind(effect), hideEffect:effect.hide.bind(effect), onOk:forwardToWizard}); + } + </script> + "; + + return $dialogScript; + } +} + +?>
\ No newline at end of file |