* Copyright (C) 2005 Paul Taylor * Copyright (C) 2003-2005 Manuel Kasper * 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 'guiconfig.inc'; require_once 'system.inc'; require_once 'base32/Base32.php'; function get_user_privdesc(& $user) { global $priv_list; $privs = array(); if (!isset($user['priv']) || !is_array($user['priv'])) { $user_privs = array(); } else { $user_privs = $user['priv']; } $names = local_user_get_groups($user); foreach ($names as $name) { $group = getGroupEntry($name); if (isset($group['priv']) && is_array($group['priv'])) { foreach ($group['priv'] as $pname) { if (in_array($pname, $user_privs)) { continue; } if (empty($priv_list[$pname])) { continue; } $priv = $priv_list[$pname]; $priv['group'] = $group['name']; $priv['id'] = $pname; $privs[] = $priv; } } } foreach ($user_privs as $pname) { if (!empty($priv_list[$pname])) { $priv_list[$pname]['id'] = $pname; $privs[] = $priv_list[$pname]; } } legacy_html_escape_form_data($privs); return $privs; } $a_user = &config_read_array('system', 'user'); // reset errors and action $act = null; if ($_SERVER['REQUEST_METHOD'] === 'GET') { // process get type actions if (isset($_GET['userid']) && isset($a_user[$_GET['userid']])) { $id = $_GET['userid']; } if (isset($_GET['act'])) { $act = $_GET['act']; } if (isset($_GET['savemsg'])) { $savemsg = htmlspecialchars($_GET['savemsg']); } if ($act == "expcert" && isset($id)) { // export certificate $cert = &lookup_cert($a_user[$id]['cert'][$_GET['certid']]); $exp_name = urlencode("{$a_user[$id]['name']}-{$cert['descr']}.crt"); $exp_data = base64_decode($cert['crt']); $exp_size = strlen($exp_data); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename={$exp_name}"); header("Content-Length: $exp_size"); echo $exp_data; exit; } elseif ($act == "expckey" && isset($id)) { // export private key $cert = &lookup_cert($a_user[$id]['cert'][$_GET['certid']]); $exp_name = urlencode("{$a_user[$id]['name']}-{$cert['descr']}.key"); $exp_data = base64_decode($cert['prv']); $exp_size = strlen($exp_data); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename={$exp_name}"); header("Content-Length: $exp_size"); echo $exp_data; exit; } elseif ($act == 'new' || $act == 'edit') { // edit user, load or init data $fieldnames = array('user_dn', 'descr', 'expires', 'scope', 'uid', 'priv', 'otp_seed', 'email', 'shell', 'comment', 'landing_page'); if (isset($id)) { if (isset($a_user[$id]['authorizedkeys'])) { $pconfig['authorizedkeys'] = base64_decode($a_user[$id]['authorizedkeys']); } if (isset($a_user[$id]['name'])) { $pconfig['usernamefld'] = $a_user[$id]['name']; } $pconfig['groups'] = local_user_get_groups($a_user[$id]); $pconfig['disabled'] = isset($a_user[$id]['disabled']); foreach ($fieldnames as $fieldname) { if (isset($a_user[$id][$fieldname])) { $pconfig[$fieldname] = $a_user[$id][$fieldname]; } else { $pconfig[$fieldname] = null; } } foreach (get_locale_list() as $lcode => $ldesc) { if ($a_user[$id]['language'] == $lcode) { $pconfig['language'] = $ldesc; break; } } } else { // set defaults $pconfig['groups'] = null; $pconfig['disabled'] = false; $pconfig['scope'] = "user"; $pconfig['usernamefld'] = null; foreach ($fieldnames as $fieldname) { if (!isset($pconfig[$fieldname])) { $pconfig[$fieldname] = null; } } } } if (empty($pconfig['language'])) { $pconfig['language'] = gettext('Default'); } } elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { // process post type requests if (isset($_POST['userid']) && isset($a_user[$_POST['userid']])) { $id = $_POST['userid']; } if (isset($_POST['act'])) { $act = $_POST['act']; } $pconfig = $_POST; $input_errors = array(); $user = getUserEntry($_SESSION['Username']); if (userHasPrivilege($user, 'user-config-readonly')) { $input_errors[] = gettext('You do not have the permission to perform this action.'); } elseif ($act == "deluser" && isset($id)) { // drop user if ($_SESSION['Username'] === $a_user[$id]['name']) { $input_errors[] = gettext('You cannot delete yourself.'); } else { local_user_del($a_user[$id]); $userdeleted = $a_user[$id]['name']; unset($a_user[$id]); write_config(sprintf('The user "%s" was successfully removed.', $userdeleted)); $savemsg = sprintf(gettext('The user "%s" was successfully removed.'), $userdeleted); header(url_safe('Location: /system_usermanager.php?savemsg=%s', array($savemsg))); exit; } } elseif ($act == "delcert" && isset($id)) { // remove certificate association $certdeleted = lookup_cert($a_user[$id]['cert'][$pconfig['certid']]); $certdeleted = $certdeleted['descr']; unset($a_user[$id]['cert'][$pconfig['certid']]); write_config(sprintf('The certificate association "%s" was successfully removed.', $certdeleted)); $savemsg = sprintf(gettext('The certificate association "%s" was successfully removed.'), $certdeleted); header(url_safe('Location: /system_usermanager.php?savemsg=%s&act=edit&userid=%d', array($savemsg, $id))); exit; } elseif ($act == "newApiKey" && isset($id)) { // every action is using the sequence of the user, to keep it understandable, we will use // the same strategy here (although we need a username to work with) // // the client side is (jquery) generates the actual download file. $username = $a_user[$id]['name']; $authFactory = new \OPNsense\Auth\AuthenticationFactory(); $authenticator = $authFactory->get("Local API"); $keyData = $authenticator->createKey($username); if ($keyData != null) { echo json_encode($keyData); } exit; } elseif ($act =='delApiKey' && isset($id)) { $username = $a_user[$id]['name']; if (!empty($pconfig['api_delete'])) { $authFactory = new \OPNsense\Auth\AuthenticationFactory(); $authenticator = $authFactory->get("Local API"); $authenticator->dropKey($username, $pconfig['api_delete']); $savemsg = sprintf(gettext('The API key "%s" was successfully removed.'), $pconfig['api_delete']); } else { $savemsg = gettext('No API key found'); } // redirect header(url_safe('Location: /system_usermanager.php?savemsg=%s&act=edit&userid=%d', array($savemsg, $id))); exit; } elseif (isset($pconfig['save']) || isset($pconfig['save_close'])) { $reqdfields = explode(' ', 'usernamefld'); $reqdfieldsn = array(gettext('Username')); do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors); if (preg_match("/[^a-zA-Z0-9\.\-_]/", $pconfig['usernamefld'])) { $input_errors[] = gettext("The username contains invalid characters."); } if (strlen($pconfig['usernamefld']) > 32) { $input_errors[] = gettext("The username is longer than 32 characters."); } if (!empty($pconfig['passwordfld1']) || !empty($pconfig['passwordfld2'])) { if ($pconfig['passwordfld1'] != $pconfig['passwordfld2']) { $input_errors[] = gettext('The passwords do not match.'); } elseif (empty($pconfig['gen_new_password'])) { // check against local password policy $authenticator = get_authenticator(); $input_errors = array_merge( $input_errors, $authenticator->checkPolicy($pconfig['usernamefld'], null, $pconfig['passwordfld1']) ); } else { $input_errors[] = gettext('Cannot set random password due to explicit input.'); } } if (!empty($pconfig['disabled']) && $_SESSION['Username'] === $a_user[$id]['name']) { $input_errors[] = gettext('You cannot disable yourself.'); } if (isset($id)) { $oldusername = $a_user[$id]['name']; } else { $oldusername = ''; if (empty($pconfig['passwordfld1']) && empty($pconfig['gen_new_password'])) { $input_errors[] = gettext('A password is required.'); } } /* make sure this user name is unique */ if (count($input_errors) == 0) { foreach ($a_user as $userent) { if ($userent['name'] == $pconfig['usernamefld'] && $oldusername != $pconfig['usernamefld']) { $input_errors[] = gettext("Another entry with the same username already exists."); break; } } } /* also make sure it is not reserved */ if (count($input_errors) == 0) { $system_users = explode("\n", file_get_contents("/etc/passwd")); foreach ($system_users as $s_user) { $ent = explode(":", $s_user); if ($ent[0] == $pconfig['usernamefld'] && $oldusername != $pconfig['usernamefld']) { $input_errors[] = gettext("That username is reserved by the system."); break; } } } /* * Check for a valid expirationdate if one is set at all (valid means, * DateTime puts out a time stamp so any DateTime compatible time * format may be used. to keep it simple for the enduser, we only * claim to accept MM/DD/YYYY as inputs. Advanced users may use inputs * like "+1 day", which will be converted to MM/DD/YYYY based on "now". * Otherwise such an entry would lead to an invalid expiration data. */ if (!empty($pconfig['expires'])) { try { $expdate = new DateTime($pconfig['expires']); //convert from any DateTime compatible date to MM/DD/YYYY $pconfig['expires'] = $expdate->format("m/d/Y"); } catch (Exception $ex) { $input_errors[] = gettext("Invalid expiration date format; use MM/DD/YYYY instead."); } } if (!empty($pconfig['name'])) { $ca = lookup_ca($pconfig['caref']); if (!$ca) { $input_errors[] = gettext("Invalid internal Certificate Authority") . "\n"; } } if (!empty($pconfig['shell']) && !in_array($pconfig['shell'], auth_get_shells(isset($id) ? $a_user[$id]['uid'] : $config['system']['nextuid']))) { $input_errors[] = gettext('Invalid login shell provided.'); } if (!count($input_errors)) { $userent = array(); if (isset($id)) { $userent = $a_user[$id]; /* the user name was modified */ if ($pconfig['usernamefld'] != $pconfig['oldusername']) { local_user_del($userent); } } /* the user password was modified */ if (!empty($pconfig['passwordfld1'])) { local_user_set_password($userent, $pconfig['passwordfld1']); } elseif (!empty($pconfig['gen_new_password'])) { local_user_set_password($userent); } isset($pconfig['scope']) ? $userent['scope'] = $pconfig['scope'] : $userent['scope'] = "system"; $userent['name'] = $pconfig['usernamefld']; $userent['descr'] = $pconfig['descr']; $userent['expires'] = $pconfig['expires']; $userent['authorizedkeys'] = base64_encode(trim($pconfig['authorizedkeys'])); if (!empty($pconfig['gen_otp_seed'])) { // generate 160bit base32 encoded secret $userent['otp_seed'] = Base32\Base32::encode(random_bytes(20)); } else { $userent['otp_seed'] = trim($pconfig['otp_seed']); } if (!empty($pconfig['disabled'])) { $userent['disabled'] = true; } elseif (isset($userent['disabled'])) { unset($userent['disabled']); } if (!empty($pconfig['email'])) { $userent['email'] = $pconfig['email']; } elseif (isset($userent['email'])) { unset($userent['email']); } if (!empty($pconfig['comment'])) { $userent['comment'] = $pconfig['comment']; } elseif (isset($userent['comment'])) { unset($userent['comment']); } if (!empty($pconfig['landing_page'])) { $userent['landing_page'] = $pconfig['landing_page']; } elseif (isset($userent['landing_page'])) { unset($userent['landing_page']); } if (!empty($pconfig['shell'])) { $userent['shell'] = $pconfig['shell']; } elseif (isset($userent['shell'])) { unset($userent['shell']); } if (isset($id)) { $a_user[$id] = $userent; } else { $userent['uid'] = $config['system']['nextuid']++; $a_user[] = $userent; } local_user_set_groups($userent, $pconfig['groups']); local_user_set($userent); if (isset($id)) { $audit_msg = sprintf("user \"%s\" changed", $userent['name']); } else { $audit_msg = sprintf("user \"%s\" created", $userent['name']); } write_config($audit_msg); // XXX: signal backend that the user has changed. configdp_run('auth user changed', [$userent['name']]); if (!empty($pconfig['chkNewCert'])) { header(url_safe('Location: /system_certmanager.php?act=new&userid=%d', array(isset($id) ? $id : count($a_user) - 1))); } elseif (isset($pconfig['save_close'])) { header(url_safe('Location: /system_usermanager.php?savemsg=%s', array(get_std_save_message(true)))); } else { header(url_safe('Location: /system_usermanager.php?act=edit&userid=%d&savemsg=%s', array(isset($id) ? $id : count($a_user) - 1, get_std_save_message(true)))); } exit; } } else { header(url_safe('Location: /system_usermanager.php')); exit; } } legacy_html_escape_form_data($pconfig); legacy_html_escape_form_data($a_user); include("head.inc"); ?>
/>
/>



/>
/>
 

">

">
" data-toggle="tooltip">
".gettext('Revoked').")" : "";?> "> ">
" data-toggle="tooltip">
 
$userent): ?>