mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-13 08:09:41 +00:00
Warning: The type attribute is unnecessary for JavaScript resources. HTML5: Edition for Web Authors http://www.w3.org/TR/2014/REC-html5-20141028/scripting-1.html The default, which is used if the attribute is absent, is "text/javascript". The Script element https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script HTML5 specification urges authors to omit the attribute rather than provide a redundant MIME type.
1041 lines
47 KiB
PHP
1041 lines
47 KiB
PHP
<?php
|
|
|
|
/*
|
|
Copyright (C) 2014-2016 Deciso B.V.
|
|
Copyright (C) 2008 Shrew Soft Inc. <mgrooms@shrew.net>
|
|
Copyright (C) 2005 Paul Taylor <paultaylor@winn-dixie.com>
|
|
Copyright (C) 2003-2005 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 '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;
|
|
}
|
|
|
|
// link user section
|
|
$a_user = &config_read_array('system', 'user');
|
|
|
|
// reset errors and action
|
|
$input_errors = array();
|
|
$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', 'ipsecpsk', 'lifetime', 'otp_seed', 'email', 'comment');
|
|
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['lifetime'] = 365;
|
|
$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;
|
|
|
|
if ($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();
|
|
$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();
|
|
$savemsg = sprintf(gettext('The certificate association "%s" was successfully removed.'), $certdeleted);
|
|
header(url_safe('Location: /system_usermanager.php?savemsg=%s&act=edit&userid=%s', 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=%s', array($savemsg, $id)));
|
|
exit;
|
|
} elseif (isset($pconfig['save']) || isset($pconfig['save_close'])) {
|
|
// save user
|
|
/* input validation */
|
|
$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 ($pconfig['passwordfld1'] != $pconfig['passwordfld2']) {
|
|
$input_errors[] = gettext('The passwords do not match.');
|
|
}
|
|
|
|
if (!empty($pconfig['passwordfld1']) && !empty($pconfig['gen_new_password'])) {
|
|
$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".
|
|
* Otherwhise 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 (count($input_errors)==0) {
|
|
$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']));
|
|
$userent['ipsecpsk'] = $pconfig['ipsecpsk'];
|
|
if (!empty($pconfig['gen_otp_seed'])) {
|
|
// generate 160bit base32 encoded secret
|
|
$userent['otp_seed'] = Base32\Base32::encode(openssl_random_pseudo_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 (isset($id)) {
|
|
$a_user[$id] = $userent;
|
|
} else {
|
|
$userent['uid'] = $config['system']['nextuid']++;
|
|
$a_user[] = $userent;
|
|
}
|
|
|
|
local_user_set($userent);
|
|
local_user_set_groups($userent, $pconfig['groups']);
|
|
write_config();
|
|
|
|
if (!empty($pconfig['chkNewCert'])) {
|
|
// redirect to cert manager when a new cert is requested for this user
|
|
header(url_safe('Location: /system_certmanager.php?act=new&userid=%s', 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())));
|
|
} else {
|
|
header(url_safe('Location: /system_usermanager.php?act=edit&userid=%s&savemsg=%s', array(isset($id) ? $id : count($a_user) - 1, get_std_save_message())));
|
|
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");
|
|
|
|
?>
|
|
<script src="/ui/js/jquery.qrcode.js"></script>
|
|
<script src="/ui/js/qrcode.js"></script>
|
|
|
|
<body>
|
|
|
|
<?php include("fbegin.inc"); ?>
|
|
|
|
<script>
|
|
$( document ).ready(function() {
|
|
// unhide otp QR code if found
|
|
$('#otp_unhide').click(function () {
|
|
$(this).hide();
|
|
$('#otp_qrcode').show();
|
|
});
|
|
// remove certificate association
|
|
$(".act-del-cert").click(function(event){
|
|
var certid = $(this).data('certid');
|
|
event.preventDefault();
|
|
BootstrapDialog.show({
|
|
type:BootstrapDialog.TYPE_DANGER,
|
|
title: "<?= html_safe(gettext('Certificate')) ?>",
|
|
message: "<?= html_safe(gettext('Do you really want to remove this certificate association?')) .'\n'. html_safe(gettext('(Certificate will not be deleted)')) ?>",
|
|
buttons: [{
|
|
label: "<?= html_safe(gettext('No')) ?>",
|
|
action: function(dialogRef) {
|
|
dialogRef.close();
|
|
}}, {
|
|
label: "<?= html_safe(gettext('Yes')) ?>",
|
|
action: function(dialogRef) {
|
|
$("#certid").val(certid);
|
|
$("#act").val("delcert");
|
|
$("#iform").submit();
|
|
}
|
|
}]
|
|
});
|
|
});
|
|
|
|
// remove user
|
|
$(".act-del-user").click(function(event){
|
|
var userid = $(this).data('userid');
|
|
var username = $(this).data('username');
|
|
event.preventDefault();
|
|
BootstrapDialog.show({
|
|
type:BootstrapDialog.TYPE_DANGER,
|
|
title: "<?= html_safe(gettext('User')) ?>",
|
|
message: "<?= html_safe(gettext('Do you really want to delete this user?')) ?>" + "<br/>("+username+")",
|
|
buttons: [{
|
|
label: "<?= html_safe(gettext('No')) ?>",
|
|
action: function(dialogRef) {
|
|
dialogRef.close();
|
|
}}, {
|
|
label: "<?= html_safe(gettext('Yes')) ?>",
|
|
action: function(dialogRef) {
|
|
$("#userid").val(userid);
|
|
$("#act2").val("deluser");
|
|
$("#iform2").submit();
|
|
}
|
|
}]
|
|
});
|
|
});
|
|
|
|
// expand ssh key section on click
|
|
$("#authorizedkeys").click(function(){
|
|
$(this).attr('rows', '7');
|
|
});
|
|
|
|
// import ldap users
|
|
$("#import_ldap_users").click(function(){
|
|
url="system_usermanager_import_ldap.php";
|
|
var oWin = window.open(url,"OPNsense","width=620,height=400,top=150,left=150,scrollbars=yes");
|
|
if (oWin==null || typeof(oWin)=="undefined") {
|
|
alert("<?= html_safe(gettext('Popup blocker detected. Action aborted.')) ?>");
|
|
}
|
|
});
|
|
|
|
|
|
// generate a new API key for this user
|
|
$("#newApiKey").click(function(event){
|
|
event.preventDefault();
|
|
$.post(window.location, {act: 'newApiKey', userid: $("#userid").val() }, function(data) {
|
|
if (data['key'] != undefined) {
|
|
// only generate a key file if there's data
|
|
output_data = 'key='+data['key'] +'\n' + 'secret='+data['secret'] +'\n';
|
|
// create link, click and send to client
|
|
$('<a></a>')
|
|
.attr('id','downloadFile')
|
|
.attr('href','data:text/plain;charset=utf8,' + encodeURIComponent(output_data))
|
|
.attr('download','apikey.txt')
|
|
.appendTo('body');
|
|
|
|
$('#downloadFile').ready(function() {
|
|
$('#downloadFile').get(0).click();
|
|
});
|
|
// reload form
|
|
location.reload();
|
|
}
|
|
},'json');
|
|
});
|
|
|
|
// delete API key
|
|
$(".act-del-api-key").click(function(event){
|
|
event.preventDefault();
|
|
var apiKey = $(this).data('key');
|
|
BootstrapDialog.show({
|
|
type:BootstrapDialog.TYPE_DANGER,
|
|
title: "<?= html_safe(gettext('User')) ?>",
|
|
message: '<?= html_safe(gettext('Do you really want to delete this API key?')) ?>' + '<br/><small>('+apiKey.substring(0,40)+"...)</small>",
|
|
buttons: [{
|
|
label: "<?= html_safe(gettext('No')) ?>",
|
|
action: function(dialogRef) {
|
|
dialogRef.close();
|
|
}}, {
|
|
label: "<?= html_safe(gettext('Yes')) ?>",
|
|
action: function(dialogRef) {
|
|
$("#act").val("delApiKey");
|
|
$("#api_delete").val(apiKey);
|
|
$("#iform").submit();
|
|
}
|
|
}]
|
|
});
|
|
});
|
|
|
|
$('.datepicker').datepicker();
|
|
|
|
$("#add_groups").click(function(){
|
|
$("#groups").append($("#notgroups option:selected"));
|
|
$("#notgroups option:selected").remove();
|
|
$("#groups option:selected").prop('selected', false);
|
|
});
|
|
$("#remove_groups").click(function(){
|
|
$("#notgroups").append($("#groups option:selected"));
|
|
$("#groups option:selected").remove();
|
|
$("#notgroups option:selected").prop('selected', false);
|
|
});
|
|
$("#save").click(function(){
|
|
$("#groups > option").prop('selected', true);
|
|
$("#notgroups > option").prop('selected', false);
|
|
});
|
|
$("#save_close").click(function(){
|
|
$("#groups > option").prop('selected', true);
|
|
$("#notgroups > option").prop('selected', false);
|
|
});
|
|
});
|
|
</script>
|
|
|
|
|
|
<section class="page-content-main">
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<?php
|
|
if (isset($input_errors) && count($input_errors) > 0) {
|
|
print_input_errors($input_errors);
|
|
}
|
|
if (isset($savemsg)) {
|
|
print_info_box($savemsg);
|
|
}
|
|
?>
|
|
<section class="col-xs-12">
|
|
<div class="tab-content content-box col-xs-12 table-responsive">
|
|
<?php
|
|
if ($act == "new" || $act == "edit" ) :?>
|
|
<form method="post" name="iform" id="iform">
|
|
<input type="hidden" id="act" name="act" value="<?=$act;?>" />
|
|
<input type="hidden" id="userid" name="userid" value="<?=(isset($id) ? $id : '');?>" />
|
|
<input type="hidden" id="priv_delete" name="priv_delete" value="" /> <!-- delete priv action -->
|
|
<input type="hidden" id="api_delete" name="api_delete" value="" /> <!-- delete api ke action -->
|
|
<input type="hidden" id="certid" name="certid" value="" /> <!-- remove cert association action -->
|
|
<table class="table table-striped opnsense_standard_table_form">
|
|
<tr>
|
|
<td style="width:22%"></td>
|
|
<td style="width:78%; text-align:right">
|
|
<small><?=gettext("full help"); ?> </small>
|
|
<i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page"></i>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><?=gettext("Defined by");?></td>
|
|
<td>
|
|
<strong><?=strtoupper($pconfig['scope']);?></strong>
|
|
<input name="scope" type="hidden" value="<?=$pconfig['scope']?>" />
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Disabled");?></td>
|
|
<td>
|
|
<input name="disabled" type="checkbox" id="disabled" <?= $pconfig['disabled'] ? "checked=\"checked\"" : "" ?> />
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Username");?></td>
|
|
<td>
|
|
<input name="usernamefld" type="text" class="formfld user" id="usernamefld" size="20" maxlength="32" value="<?=$pconfig['usernamefld'];?>" <?= $pconfig['scope'] == "system" || !empty($pconfig['user_dn']) ? "readonly=\"readonly\"" : "";?> />
|
|
<input name="oldusername" type="hidden" id="oldusername" value="<?=$pconfig['usernamefld'];?>" />
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
if (!empty($pconfig['user_dn'])):?>
|
|
<tr>
|
|
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("User distinguished name");?></td>
|
|
<td>
|
|
<input name="user_dn" type="text" class="formfld user" id="user_dn" size="20" value="<?=$pconfig['user_dn'];?>" readonly="readonly" />
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
endif;?>
|
|
<tr>
|
|
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Password");?></td>
|
|
<td>
|
|
<input name="passwordfld1" type="password" class="formfld pwd" id="passwordfld1" size="20" value="" /><br/>
|
|
<input name="passwordfld2" type="password" class="formfld pwd" id="passwordfld2" size="20" value="" />
|
|
<small><?= gettext("(confirmation)"); ?></small><br/><br/>
|
|
<input type="checkbox" name="gen_new_password" <?= !empty($pconfig['gen_new_password']) ? 'checked="checked"' : '' ?>/> <small><?=gettext('Generate a scrambled password to prevent local database logins for this user.') ?></small>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a id="help_for_fullname" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Full name");?></td>
|
|
<td>
|
|
<input name="descr" type="text" value="<?=$pconfig['descr'];?>" <?= $pconfig['scope'] == "system" || !empty($pconfig['user_dn']) ? "readonly=\"readonly\"" : "";?> />
|
|
<output class="hidden" for="help_for_fullname">
|
|
<?=gettext("User's full name, for your own information only");?>
|
|
</output>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a id="help_for_email" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("E-Mail");?></td>
|
|
<td>
|
|
<input name="email" type="text" value="<?= $pconfig['email'] ?>" />
|
|
<output class="hidden" for="help_for_email">
|
|
<?= gettext('User\'s e-mail address, for your own information only') ?>
|
|
</output>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a id="help_for_comment" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Comment");?></td>
|
|
<td>
|
|
<textarea name="comment" id="comment" class="form-control" cols="65" rows="3"><?= $pconfig['comment'] ?></textarea>
|
|
<output class="hidden" for="help_for_comment">
|
|
<?= gettext('User comment, for your own information only') ?>
|
|
</output>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Language");?></td>
|
|
<td>
|
|
<input name="language" type="hidden" value="<?= $pconfig['language'] ?>" />
|
|
<?= $pconfig['language'] ?>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a id="help_for_expires" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Expiration date"); ?></td>
|
|
<td>
|
|
<input name="expires" type="text" id="expires" class="datepicker" data-date-format="mm/dd/yyyy" value="<?=$pconfig['expires'];?>" />
|
|
<output class="hidden" for="help_for_expires">
|
|
<?=gettext("Leave blank if the account shouldn't expire, otherwise enter the expiration date in the following format: mm/dd/yyyy"); ?>
|
|
</output>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a id="help_for_groups" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Group Memberships");?></td>
|
|
<td>
|
|
<table class="table" style="width:100%; border:0; cellpadding:0; cellspacing:0">
|
|
<thead>
|
|
<tr>
|
|
<th><?=gettext("Not Member Of"); ?></th>
|
|
<th> </th>
|
|
<th><?=gettext("Member Of"); ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>
|
|
<select size="10" name="notgroups[]" id="notgroups" onchange="clear_selected('groups')" multiple="multiple">
|
|
<?php
|
|
foreach ($config['system']['group'] as $group) :
|
|
if (!empty($pconfig['groups']) && in_array($group['name'], $pconfig['groups'])) {
|
|
continue;
|
|
}
|
|
?>
|
|
<option value="<?=$group['name'];?>">
|
|
<?=htmlspecialchars($group['name']);?>
|
|
</option>
|
|
<?php
|
|
endforeach;?>
|
|
</select>
|
|
</td>
|
|
<td class="text-center">
|
|
<br />
|
|
<a id="add_groups" class="btn btn-default btn-xs" data-toggle="tooltip" title="<?=gettext("Add groups"); ?>">
|
|
<span class="glyphicon glyphicon-arrow-right"></span>
|
|
</a>
|
|
<br /><br />
|
|
<a id="remove_groups" class="btn btn-default btn-xs" data-toggle="tooltip" title="<?=gettext("Remove groups"); ?>">
|
|
<span class="glyphicon glyphicon-arrow-left"></span>
|
|
</a>
|
|
</td>
|
|
<td>
|
|
<select size="10" name="groups[]" id="groups" onchange="clear_selected('notgroups')" multiple="multiple">
|
|
<?php
|
|
if (!empty($pconfig['groups'])) :
|
|
foreach ($config['system']['group'] as $group) :
|
|
if (!in_array($group['name'], $pconfig['groups'])) {
|
|
continue;
|
|
}
|
|
?>
|
|
<option value="<?=$group['name'];?>">
|
|
<?=htmlspecialchars($group['name']);?>
|
|
</option>
|
|
<?php
|
|
endforeach;
|
|
endif;
|
|
?>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<output class="hidden" for="help_for_groups">
|
|
<?=gettext("Hold down CTRL (pc)/COMMAND (mac) key to select multiple items");?>
|
|
</output>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
if ($pconfig['uid'] != "") :?>
|
|
<tr>
|
|
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Effective Privileges");?></td>
|
|
<td>
|
|
<table class="table table-hover table-condensed">
|
|
<tr>
|
|
<td><b><?=gettext("Inherited from");?></b></td>
|
|
<td><b><?=gettext("Type");?></b></td>
|
|
<td><b><?=gettext("Name");?></b></td>
|
|
</tr>
|
|
<?php
|
|
foreach (get_user_privdesc($a_user[$id]) as $priv) :?>
|
|
<tr>
|
|
<td><?=!empty($priv['group']) ? $priv['group'] : ''?></td>
|
|
<td>
|
|
<?php
|
|
switch (substr($priv['id'], 0, 5)) {
|
|
case 'page-':
|
|
echo gettext('GUI');
|
|
break;
|
|
case 'user-':
|
|
echo gettext('User');
|
|
break;
|
|
default:
|
|
echo gettext('N/A');
|
|
break;
|
|
} ?>
|
|
</td>
|
|
<td><?=$priv['name']?></td>
|
|
</tr>
|
|
<?php
|
|
endforeach;?>
|
|
<tr>
|
|
<td colspan="3">
|
|
<a href="system_usermanager_addprivs.php?userid=<?=$id?>" class="btn btn-xs btn-default"
|
|
title="<?=gettext("edit privileges");?>" data-toggle="tooltip">
|
|
<span class="fa fa-pencil"></span>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("User Certificates");?></td>
|
|
<td>
|
|
<table class="table table-condensed">
|
|
<tr>
|
|
<td><?=gettext("Name");?></td>
|
|
<td><?=gettext("CA");?></td>
|
|
<td></td>
|
|
</tr>
|
|
<?php
|
|
if (isset($a_user[$id]['cert']) && is_array($a_user[$id]['cert'])) :
|
|
$i = 0;
|
|
foreach ($a_user[$id]['cert'] as $certref) :
|
|
$cert = lookup_cert($certref);
|
|
$ca = lookup_ca($cert['caref']);
|
|
?>
|
|
<tr>
|
|
<td><?=htmlspecialchars($cert['descr']);?>
|
|
<?=is_cert_revoked($cert) ? "(<b>".gettext('Revoked')."</b>)" : "";?>
|
|
</td>
|
|
<td>
|
|
<?=htmlspecialchars($ca['descr']);?>
|
|
</td>
|
|
<td>
|
|
<a href="system_usermanager.php?act=expckey&certid=<?=$i?>&userid=<?=$id?>"
|
|
class="btn btn-default btn-xs" data-toggle="tooltip" title="<?=gettext("export private key");?>">
|
|
<span class="glyphicon glyphicon-arrow-down"></span>
|
|
</a>
|
|
<a href="system_usermanager.php?act=expcert&certid=<?=$i?>&userid=<?=$id?>"
|
|
class="btn btn-default btn-xs" data-toggle="tooltip" title="<?=gettext("export certificate");?>">
|
|
<span class="glyphicon glyphicon-arrow-down"></span>
|
|
</a>
|
|
<button type="submit" data-certid="<?=$i;?>" class="btn btn-default btn-xs act-del-cert"
|
|
title="<?=gettext("unlink certificate");?>" data-toggle="tooltip">
|
|
<span class="fa fa-trash text-muted"></span>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
$i++;
|
|
endforeach;
|
|
endif;?>
|
|
<tr>
|
|
<td colspan="3">
|
|
<a href="system_certmanager.php?act=new&userid=<?=$id?>" class="btn btn-default btn-xs"
|
|
title="<?=gettext("create or link user certificate");?>" data-toggle="tooltip">
|
|
<span class="glyphicon glyphicon-plus"></span>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a id="help_for_apikeys" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("API keys");?> </td>
|
|
<td>
|
|
<!-- -->
|
|
<table class="table table-condensed">
|
|
<thead>
|
|
<tr>
|
|
<th>
|
|
<?=gettext('key');?>
|
|
</th>
|
|
<th>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php
|
|
if (isset($a_user[$id]['apikeys']['item'])):
|
|
foreach ($a_user[$id]['apikeys']['item'] as $userApiKey):?>
|
|
<tr>
|
|
<td>
|
|
<small>
|
|
<?php // listtags always changes our key item to an array.. ?>
|
|
<?php // don't want to change "key" to something less sane. ?>
|
|
<?=$userApiKey['key'][0];?>
|
|
</small>
|
|
</td>
|
|
<td>
|
|
<button data-key="<?=$userApiKey['key'][0];?>" type="button" class="btn btn-default btn-xs act-del-api-key"
|
|
title="<?=gettext("delete API key");?>" data-toggle="tooltip">
|
|
<span class="glyphicon glyphicon-trash"></span>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
endforeach;
|
|
endif;?>
|
|
</tbody>
|
|
<tfoot>
|
|
<tr>
|
|
<td colspan="2">
|
|
<button type="button" class="btn btn-default btn-xs" id="newApiKey"
|
|
title="<?=gettext('Create API key');?>" data-toggle="tooltip">
|
|
<span class="glyphicon glyphicon-plus"></span>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
<output class="hidden" for="help_for_apikeys">
|
|
<hr/>
|
|
<?=gettext('Manage API keys here for machine to machine interaction using this user\'s credentials.');?>
|
|
</output>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
else :?>
|
|
<tr id="usercertchck">
|
|
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Certificate");?></td>
|
|
<td>
|
|
<input type="checkbox" id="chkNewCert" name="chkNewCert" /> <?= gettext('Click to create a user certificate.') ?>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
endif;?>
|
|
<tr>
|
|
<td><a id="help_for_otp_seed" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('OTP seed') ?></td>
|
|
<td>
|
|
<input name="otp_seed" type="text" value="<?=$pconfig['otp_seed'];?>"/>
|
|
<input type="checkbox" name="gen_otp_seed"/> <small><?= gettext('Generate new secret (160 bit)') ?></small>
|
|
<output class="hidden" for="help_for_otp_seed">
|
|
<?=gettext("OTP (base32) seed to use when a one time password authenticator is used");?><br/>
|
|
</output>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
if (!empty($pconfig['otp_seed'])):
|
|
// construct google url, using token, username and this machines hostname
|
|
$otp_url = "otpauth://totp/";
|
|
$otp_url .= $pconfig['usernamefld']."@".htmlspecialchars($config['system']['hostname'])."?secret=";
|
|
$otp_url .= $pconfig['otp_seed'];
|
|
?>
|
|
<tr>
|
|
<td><a id="help_for_otp_code" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('OTP QR code') ?></td>
|
|
<td>
|
|
<label class="btn btn-primary" id="otp_unhide"><?= gettext('Click to unhide') ?></label>
|
|
<div style="display:none;" id="otp_qrcode"></div>
|
|
<script>
|
|
$('#otp_qrcode').qrcode('<?= $otp_url ?>');
|
|
</script>
|
|
</div>
|
|
<output class="hidden" for="help_for_otp_code">
|
|
<?= gettext('Scan this QR code for easy setup with external apps.') ?>
|
|
</output>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
endif;?>
|
|
<tr>
|
|
<tr>
|
|
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Authorized keys");?></td>
|
|
<td>
|
|
<textarea name="authorizedkeys" id="authorizedkeys" class="form-control" cols="65" rows="1" placeholder="<?=gettext("Paste an authorized keys file here.");?>" wrap='off'><?=$pconfig['authorizedkeys'];?></textarea>
|
|
</td>
|
|
</tr>
|
|
<tr id="ipsecpskrow">
|
|
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("IPsec Pre-Shared Key");?></td>
|
|
<td>
|
|
<input name="ipsecpsk" type="text" size="65" value="<?=$pconfig['ipsecpsk'];?>" />
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> </td>
|
|
<td>
|
|
<button name="save" id="save" type="submit" class="btn btn-primary" value="save" /><?= gettext('Save') ?></button>
|
|
<button name="save_close" id="save_close" type="submit" class="btn btn-primary" value="save_close" /><?= gettext('Save and go back') ?></button>
|
|
<button name="cancel" id="cancel" type="submit" class="btn btn-default" value="cancel" /><?= gettext('Cancel') ?></button>
|
|
<?php
|
|
if (isset($id) && !empty($a_user[$id])) :?>
|
|
<input name="id" type="hidden" value="<?=htmlspecialchars($id);?>" />
|
|
<?php
|
|
endif;?>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</form>
|
|
<?php
|
|
else :?>
|
|
<form method="post" name="iform2" id="iform2">
|
|
<input type="hidden" id="act2" name="act" value="" />
|
|
<input type="hidden" id="userid" name="userid" value="<?=(isset($id) ? $id : '');?>" />
|
|
<input type="hidden" id="username" name="username" value="" />
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th><?=gettext("Username"); ?></th>
|
|
<th><?=gettext("Full name"); ?></th>
|
|
<th><?=gettext("Groups"); ?></th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php
|
|
$i = 0;
|
|
foreach ($a_user as $userent) :?>
|
|
<tr>
|
|
<td>
|
|
<?php
|
|
if ($userent['scope'] != "user") {
|
|
$usrimg = "glyphicon glyphicon-user text-danger";
|
|
} elseif (isset($userent['disabled'])) {
|
|
$usrimg = "glyphicon glyphicon-user text-muted";
|
|
} else {
|
|
$usrimg = "glyphicon glyphicon-user text-info";
|
|
}?>
|
|
<span class="<?=$usrimg;?>"></span> <?=$userent['name'];?>
|
|
</td>
|
|
<td><?=$userent['descr'];?></td>
|
|
<td>
|
|
<?=implode(",", local_user_get_groups($userent));?>
|
|
</td>
|
|
<td>
|
|
<a href="system_usermanager.php?act=edit&userid=<?=$i?>"
|
|
class="btn btn-default btn-xs" data-toggle="tooltip" title="<?=gettext("edit user");?>">
|
|
<span class="glyphicon glyphicon-pencil"></span>
|
|
</a>
|
|
<?php
|
|
if ($userent['scope'] != "system") :?>
|
|
<button type="button" class="btn btn-default btn-xs act-del-user"
|
|
data-username="<?=$userent['name'];?>"
|
|
data-userid="<?=$i?>" title="<?=gettext("delete user");?>" data-toggle="tooltip">
|
|
<span class="fa fa-trash text-muted"></span>
|
|
</button>
|
|
<?php
|
|
endif;?>
|
|
</td>
|
|
</tr>
|
|
<?php
|
|
$i++;
|
|
endforeach;
|
|
?>
|
|
<tr>
|
|
<td colspan="3">
|
|
<table>
|
|
<tr>
|
|
<td></td>
|
|
<td style="width:20px"></td>
|
|
<td style="width:20px"><span class="glyphicon glyphicon-user text-danger"></span></td>
|
|
<td style="width:200px"><?= gettext('System Administrator') ?></td>
|
|
<td style="width:20px"><span class="glyphicon glyphicon-user text-muted"></span></td>
|
|
<td style="width:200px"><?= gettext('Disabled User') ?></td>
|
|
<td style="width:20px"><span class="glyphicon glyphicon-user text-info"></span></td>
|
|
<td style="width:200px"><?= gettext('Normal User') ?></td>
|
|
<td></td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td>
|
|
<a href="system_usermanager.php?act=new" class="btn btn-default btn-xs"
|
|
title="<?=gettext("add user");?>" data-toggle="tooltip">
|
|
<span class="glyphicon glyphicon-plus"></span>
|
|
</a>
|
|
<?php
|
|
$authcfg_type = auth_get_authserver($config['system']['webgui']['authmode'])['type'];
|
|
if ($authcfg_type == 'ldap') :?>
|
|
<button type="submit" name="import"
|
|
id="import_ldap_users"
|
|
class="btn btn-default btn-xs"
|
|
title="<?=gettext("import users")?>">
|
|
<i class="fa fa-cloud-download"></i>
|
|
</button>
|
|
<?php
|
|
endif;?>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="4">
|
|
<?=gettext("Additional users can be added here. User permissions for accessing " .
|
|
"the web GUI or other subsystems can be assigned directly or inherited from group memberships. " .
|
|
"An icon that appears grey indicates that it is a system defined object. " .
|
|
"Some system object properties can be modified but they cannot be deleted."); ?>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</form>
|
|
<?php
|
|
endif;?>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<?php include("foot.inc");
|