mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-16 01:24:38 +00:00
798 lines
24 KiB
PHP
798 lines
24 KiB
PHP
<?php
|
|
|
|
/*
|
|
* Copyright (C) 2014-2016 Deciso B.V.
|
|
* Copyright (C) 2010 Ermal Luçi
|
|
* Copyright (C) 2007-2008 Scott Ullrich <sullrich@gmail.com>
|
|
* Copyright (C) 2005-2006 Bill Marquette <bill.marquette@gmail.com>
|
|
* Copyright (C) 2006 Paul Taylor <paultaylor@winn-dixie.com>
|
|
* 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("interfaces.inc");
|
|
require_once("util.inc");
|
|
|
|
// Will be changed to false if security checks fail
|
|
$security_passed = true;
|
|
|
|
/* If this function doesn't exist, we're being called from Captive Portal or
|
|
another internal subsystem which does not include authgui.inc */
|
|
if (function_exists("display_error_form") && !isset($config['system']['webgui']['nodnsrebindcheck'])) {
|
|
/* DNS ReBinding attack prevention */
|
|
$found_host = false;
|
|
|
|
/* either an IPv6 address with or without an alternate port */
|
|
if (strstr($_SERVER['HTTP_HOST'], "]")) {
|
|
$http_host_port = explode("]", $_SERVER['HTTP_HOST']);
|
|
/* v6 address has more parts, drop the last part */
|
|
if (count($http_host_port) > 1) {
|
|
array_pop($http_host_port);
|
|
$http_host = str_replace(array("[", "]"), "", implode(":", $http_host_port));
|
|
} else {
|
|
$http_host = str_replace(array("[", "]"), "", implode(":", $http_host_port));
|
|
}
|
|
} else {
|
|
$http_host = explode(":", $_SERVER['HTTP_HOST']);
|
|
$http_host = $http_host[0];
|
|
}
|
|
if (
|
|
is_ipaddr($http_host) || $_SERVER['SERVER_ADDR'] == "127.0.0.1" ||
|
|
strcasecmp($http_host, "localhost") == 0 or $_SERVER['SERVER_ADDR'] == "::1"
|
|
) {
|
|
$found_host = true;
|
|
}
|
|
if (
|
|
strcasecmp($http_host, $config['system']['hostname'] . "." . $config['system']['domain']) == 0 ||
|
|
strcasecmp($http_host, $config['system']['hostname']) == 0
|
|
) {
|
|
$found_host = true;
|
|
}
|
|
|
|
if (isset($config['dyndnses']['dyndns']) && !$found_host) {
|
|
foreach ($config['dyndnses']['dyndns'] as $dyndns) {
|
|
if (strcasecmp($dyndns['host'], $http_host) == 0) {
|
|
$found_host = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isset($config['dnsupdates']['dnsupdate']) && !$found_host) {
|
|
foreach ($config['dnsupdates']['dnsupdate'] as $rfc2136) {
|
|
if (strcasecmp($rfc2136['host'], $http_host) == 0) {
|
|
$found_host = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!empty($config['system']['webgui']['althostnames']) && !$found_host) {
|
|
$althosts = explode(" ", $config['system']['webgui']['althostnames']);
|
|
foreach ($althosts as $ah) {
|
|
if (strcasecmp($ah, $http_host) == 0 or strcasecmp($ah, $_SERVER['SERVER_ADDR']) == 0) {
|
|
$found_host = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($found_host == false) {
|
|
if (!security_checks_disabled()) {
|
|
display_error_form("501", sprintf(gettext("A potential %sDNS Rebind attack%s has been detected.%sTry to access the router by IP address instead of by hostname."), '<a href="http://en.wikipedia.org/wiki/DNS_rebinding">', '</a>', '<br />'));
|
|
exit;
|
|
}
|
|
$security_passed = false;
|
|
}
|
|
}
|
|
|
|
// If the HTTP_REFERER is something other than ourselves then disallow.
|
|
if (function_exists("display_error_form") && !isset($config['system']['webgui']['nohttpreferercheck'])) {
|
|
if (isset($_SERVER['HTTP_REFERER'])) {
|
|
if (file_exists('/tmp/setupwizard_lastreferrer')) {
|
|
if ($_SERVER['HTTP_REFERER'] == file_get_contents('/tmp/setupwizard_lastreferrer')) {
|
|
unlink('/tmp/setupwizard_lastreferrer');
|
|
header("Refresh: 1; url=index.php");
|
|
echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
|
|
echo "<html><head><title>" . gettext("Redirecting...") . "</title></head><body>" . gettext("Redirecting to the dashboard...") . "</body></html>";
|
|
exit;
|
|
}
|
|
}
|
|
$found_host = false;
|
|
$referrer_host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
|
|
$referrer_host = str_replace(array("[", "]"), "", $referrer_host);
|
|
if ($referrer_host) {
|
|
if (
|
|
strcasecmp($referrer_host, $config['system']['hostname'] . "." . $config['system']['domain']) == 0 ||
|
|
strcasecmp($referrer_host, $config['system']['hostname']) == 0
|
|
) {
|
|
$found_host = true;
|
|
}
|
|
|
|
|
|
if (!empty($config['system']['webgui']['althostnames']) && !$found_host) {
|
|
$althosts = explode(" ", $config['system']['webgui']['althostnames']);
|
|
foreach ($althosts as $ah) {
|
|
if (strcasecmp($referrer_host, $ah) == 0) {
|
|
$found_host = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isset($config['dyndnses']['dyndns']) && !$found_host) {
|
|
foreach ($config['dyndnses']['dyndns'] as $dyndns) {
|
|
if (strcasecmp($dyndns['host'], $referrer_host) == 0) {
|
|
$found_host = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isset($config['dnsupdates']['dnsupdate']) && !$found_host) {
|
|
foreach ($config['dnsupdates']['dnsupdate'] as $rfc2136) {
|
|
if (strcasecmp($rfc2136['host'], $referrer_host) == 0) {
|
|
$found_host = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$found_host) {
|
|
$found_host = isAuthLocalIP($referrer_host);
|
|
if ($referrer_host == "127.0.0.1" || $referrer_host == "localhost") {
|
|
// allow SSH port forwarded connections and links from localhost
|
|
$found_host = true;
|
|
}
|
|
}
|
|
}
|
|
if ($found_host == false) {
|
|
if (!security_checks_disabled()) {
|
|
display_error_form('501', sprintf(
|
|
gettext('The HTTP_REFERER "%s" does not match the predefined settings. You can disable this check if needed under System: Settings: Administration.'),
|
|
html_safe($_SERVER['HTTP_REFERER'])
|
|
));
|
|
exit;
|
|
}
|
|
$security_passed = false;
|
|
}
|
|
} else {
|
|
$security_passed = false;
|
|
}
|
|
}
|
|
|
|
if (function_exists("display_error_form") && $security_passed) {
|
|
/* Security checks passed, so it should be OK to turn them back on */
|
|
restore_security_checks();
|
|
}
|
|
unset($security_passed);
|
|
|
|
$groupindex = index_groups();
|
|
$userindex = index_users();
|
|
|
|
|
|
/**
|
|
* check if $http_host is a local configured ip address
|
|
*/
|
|
function isAuthLocalIP($http_host)
|
|
{
|
|
global $config;
|
|
if (isset($config['virtualip']['vip'])) {
|
|
foreach ($config['virtualip']['vip'] as $vip) {
|
|
if ($vip['subnet'] == $http_host) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
$address_in_list = function ($interface_list_ips, $http_host) {
|
|
foreach ($interface_list_ips as $ilips => $ifname) {
|
|
if (strcasecmp($http_host, $ilips) == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
};
|
|
// try using cached addresses
|
|
$interface_list_ips = get_cached_json_content("/tmp/isAuthLocalIP.cache.json");
|
|
if (!empty($interface_list_ips) && $address_in_list($interface_list_ips, $http_host)) {
|
|
return true;
|
|
}
|
|
// fetch addresses and store in cache
|
|
$interface_list_ips = get_configured_ip_addresses();
|
|
file_put_contents("/tmp/isAuthLocalIP.cache.json", json_encode($interface_list_ips));
|
|
|
|
return $address_in_list($interface_list_ips, $http_host);
|
|
}
|
|
|
|
function index_groups()
|
|
{
|
|
global $config, $groupindex;
|
|
|
|
$groupindex = array();
|
|
if (isset($config['system']['group'])) {
|
|
$i = 0;
|
|
foreach ($config['system']['group'] as $groupent) {
|
|
if (isset($groupent['name'])) {
|
|
$groupindex[$groupent['name']] = $i;
|
|
$i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ($groupindex);
|
|
}
|
|
|
|
function index_users()
|
|
{
|
|
global $config;
|
|
|
|
$userindex = array();
|
|
|
|
if (is_array($config['system']['user'])) {
|
|
$i = 0;
|
|
foreach ($config['system']['user'] as $userent) {
|
|
$userindex[$userent['name']] = $i;
|
|
$i++;
|
|
}
|
|
}
|
|
|
|
return $userindex;
|
|
}
|
|
|
|
function getUserGroups($username)
|
|
{
|
|
global $config;
|
|
$member_groups = array();
|
|
$user = getUserEntry($username);
|
|
if ($user !== false) {
|
|
$allowed_groups = local_user_get_groups($user);
|
|
if (isset($config['system']['group'])) {
|
|
foreach ($config['system']['group'] as $group) {
|
|
if (in_array($group['name'], $allowed_groups)) {
|
|
$member_groups[] = $group['name'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $member_groups;
|
|
}
|
|
|
|
function &getUserEntry($name)
|
|
{
|
|
global $config, $userindex;
|
|
$false = false;
|
|
if (isset($userindex[$name])) {
|
|
return $config['system']['user'][$userindex[$name]];
|
|
} else {
|
|
return $false;
|
|
}
|
|
}
|
|
|
|
function &getUserEntryByUID($uid)
|
|
{
|
|
global $config;
|
|
|
|
if (is_array($config['system']['user'])) {
|
|
foreach ($config['system']['user'] as & $user) {
|
|
if ($user['uid'] == $uid) {
|
|
return $user;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function &getGroupEntry($name)
|
|
{
|
|
global $config, $groupindex;
|
|
|
|
if (isset($groupindex[$name])) {
|
|
return $config['system']['group'][$groupindex[$name]];
|
|
}
|
|
|
|
return array();
|
|
}
|
|
|
|
function &getGroupEntryByGID($gid)
|
|
{
|
|
global $config;
|
|
|
|
if (isset($config['system']['group'])) {
|
|
foreach ($config['system']['group'] as & $group) {
|
|
if ($group['gid'] == $gid) {
|
|
return $group;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function get_user_privileges(&$user)
|
|
{
|
|
if (!isset($user['priv']) || !is_array($user['priv'])) {
|
|
$privs = array();
|
|
} else {
|
|
$privs = $user['priv'];
|
|
}
|
|
|
|
$names = local_user_get_groups($user);
|
|
|
|
foreach ($names as $name) {
|
|
$group = getGroupEntry($name);
|
|
if (isset($group['priv']) && is_array($group['priv'])) {
|
|
$privs = array_merge($privs, $group['priv']);
|
|
}
|
|
}
|
|
return $privs;
|
|
}
|
|
|
|
function userHasPrivilege($userent, $privid = false)
|
|
{
|
|
if (!$privid || !is_array($userent)) {
|
|
return false;
|
|
}
|
|
|
|
$privs = get_user_privileges($userent);
|
|
|
|
if (!is_array($privs)) {
|
|
return false;
|
|
}
|
|
|
|
if (!in_array($privid, $privs)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function userIsAdmin($username)
|
|
{
|
|
$user = getUserEntry($username);
|
|
|
|
return userHasPrivilege($user, 'page-all');
|
|
}
|
|
|
|
function auth_get_shells($uid = 0)
|
|
{
|
|
$shells = array('' => '/sbin/nologin');
|
|
|
|
if ($uid == 0) {
|
|
$shells = array('' => '/usr/local/sbin/opnsense-shell');
|
|
}
|
|
|
|
$etc_shells = @file_get_contents('/etc/shells');
|
|
if (!empty($etc_shells)) {
|
|
$etc_shells = explode("\n", $etc_shells);
|
|
foreach ($etc_shells as $shell) {
|
|
$shell = trim($shell);
|
|
if (
|
|
!empty($shell) && strpos($shell, '#') !== 0 &&
|
|
strpos($shell, '/usr/local/sbin/opnsense-') !== 0
|
|
) {
|
|
$shells[$shell] = $shell;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $shells;
|
|
}
|
|
|
|
function local_sync_accounts()
|
|
{
|
|
global $config;
|
|
|
|
/* remove local users to avoid uid conflicts */
|
|
$fd = popen('/usr/sbin/pw usershow -a', 'r');
|
|
if ($fd) {
|
|
while (!feof($fd)) {
|
|
$line = explode(':', fgets($fd));
|
|
if (count($line) < 3 || !strncmp($line[0], '_', 1) || $line[2] < 2000 || $line[2] > 65000) {
|
|
continue;
|
|
}
|
|
/*
|
|
* If a crontab was created to user, pw userdel will be interactive and
|
|
* can cause issues. Just remove crontab before run it when necessary
|
|
*/
|
|
@unlink("/var/cron/tabs/{$line[0]}");
|
|
mwexecf('/usr/sbin/pw userdel -n %s', $line[0]);
|
|
}
|
|
pclose($fd);
|
|
}
|
|
|
|
/* remove local groups to avoid gid conflicts */
|
|
$fd = popen('/usr/sbin/pw groupshow -a', 'r');
|
|
if ($fd) {
|
|
while (!feof($fd)) {
|
|
$line = explode(':', fgets($fd));
|
|
if (count($line) < 3 || !strncmp($line[0], '_', 1) || $line[2] < 2000 || $line[2] > 65000) {
|
|
continue;
|
|
}
|
|
mwexecf('/usr/sbin/pw groupdel -g %s', $line[2]);
|
|
}
|
|
pclose($fd);
|
|
}
|
|
|
|
/* make sure the all group exists */
|
|
$allgrp = getGroupEntryByGID(1998);
|
|
local_group_set($allgrp, true);
|
|
|
|
/* sync all local users */
|
|
if (is_array($config['system']['user'])) {
|
|
foreach ($config['system']['user'] as $user) {
|
|
local_user_set($user);
|
|
}
|
|
}
|
|
|
|
/* sync all local groups */
|
|
if (is_array($config['system']['group'])) {
|
|
foreach ($config['system']['group'] as $group) {
|
|
local_group_set($group);
|
|
}
|
|
}
|
|
}
|
|
|
|
function local_user_set(&$user, $force_password = false)
|
|
{
|
|
global $config;
|
|
|
|
if (empty($user['password'])) {
|
|
log_error(sprintf(
|
|
gettext('There is something wrong in your config because user %s password is missing!'),
|
|
$user['name']
|
|
));
|
|
return;
|
|
}
|
|
|
|
@mkdir('/home', 0755);
|
|
|
|
$user_pass = $user['password'];
|
|
$user_name = $user['name'];
|
|
$user_uid = $user['uid'];
|
|
|
|
$lock_account = 'lock';
|
|
|
|
$is_expired = !empty($user['expires']) &&
|
|
strtotime('-1 day') > strtotime(date('m/d/Y', strtotime($user['expires'])));
|
|
|
|
$is_disabled = isset($user['disabled']);
|
|
|
|
$is_unlocked = !$is_disabled && !$is_expired;
|
|
|
|
if ($is_unlocked) {
|
|
$lock_account = 'unlock';
|
|
} elseif ($user_uid == 0) {
|
|
/*
|
|
* The root account should not be locked as this will have
|
|
* side-effects such as cron not working correctly. Set
|
|
* password to unreachable "*" instead. Our auth framework
|
|
* already checks for disabled elsewhere so we only need to
|
|
* prevent root login in the console when integrated
|
|
* authentication is off.
|
|
*/
|
|
$lock_account = 'unlock';
|
|
$user_pass = '*';
|
|
}
|
|
|
|
if ($user_uid == 0) {
|
|
$user_shell = isset($user['shell']) ? $user['shell'] : '/usr/local/sbin/opnsense-shell';
|
|
$user_group = 'wheel';
|
|
$user_home = '/root';
|
|
} else {
|
|
$user_shell = isset($user['shell']) ? $user['shell'] : '/sbin/nologin';
|
|
$user_home = "/home/{$user_name}";
|
|
$user_group = 'nobody';
|
|
}
|
|
|
|
/* admins access gives wheely rights */
|
|
if (userIsAdmin($user['name'])) {
|
|
$user_group = 'wheel';
|
|
}
|
|
|
|
/* passwords only when integrated auth is disabled or forced */
|
|
if (!$force_password && empty($config['system']['disableintegratedauth'])) {
|
|
$user_pass = '*';
|
|
}
|
|
|
|
/* read from pw db */
|
|
$fd = popen("/usr/sbin/pw usershow -n {$user_name} 2>&1", "r");
|
|
$pwread = fgets($fd);
|
|
pclose($fd);
|
|
$userattrs = explode(":", trim($pwread));
|
|
|
|
/* determine add or mod */
|
|
if (($userattrs[0] != $user['name']) || (!strncmp($pwread, 'pw:', 3))) {
|
|
$user_op = 'useradd -m -k /usr/share/skel -o';
|
|
} else {
|
|
$user_op = 'usermod';
|
|
}
|
|
|
|
$comment = str_replace(array(':', '!', '@'), ' ', $user['descr']);
|
|
/* add or mod pw db */
|
|
$cmd = "/usr/sbin/pw {$user_op} -q -u {$user_uid} -n {$user_name}" .
|
|
" -g {$user_group} -s {$user_shell} -d {$user_home}" .
|
|
" -c " . escapeshellarg($comment) . " -H 0 2>&1";
|
|
$fd = popen($cmd, 'w');
|
|
fwrite($fd, $user_pass);
|
|
pclose($fd);
|
|
|
|
/* create user directory if required */
|
|
@mkdir($user_home, 0700);
|
|
@chown($user_home, $user_name);
|
|
@chgrp($user_home, $user_group);
|
|
|
|
/* write out ssh authorized key file */
|
|
if ($is_unlocked && isset($user['authorizedkeys'])) {
|
|
@mkdir("{$user_home}/.ssh", 0700);
|
|
@chown("{$user_home}/.ssh", $user_name);
|
|
$keys = base64_decode($user['authorizedkeys']);
|
|
$keys = preg_split('/[\n\r]+/', $keys);
|
|
$keys[] = '';
|
|
$keys = implode($keys, "\n");
|
|
@file_put_contents("{$user_home}/.ssh/authorized_keys", $keys);
|
|
@chown("{$user_home}/.ssh/authorized_keys", $user_name);
|
|
} else {
|
|
@unlink("{$user_home}/.ssh/authorized_keys");
|
|
}
|
|
|
|
mwexecf('/usr/sbin/pw %s %s', array($lock_account, $user_name), true);
|
|
}
|
|
|
|
function local_user_del($user)
|
|
{
|
|
/* remove all memberships */
|
|
local_user_set_groups($user);
|
|
|
|
/* delete from pw db */
|
|
mwexecf('/usr/sbin/pw userdel -n %s -r', $user['name']);
|
|
|
|
/* Delete user from groups needs a call to write_config() */
|
|
local_group_del_user($user);
|
|
}
|
|
|
|
function local_user_set_password(&$user, $password = null)
|
|
{
|
|
$cost = 10;
|
|
|
|
if ($password == null) {
|
|
/* generate a random password */
|
|
$bytes = openssl_random_pseudo_bytes(50);
|
|
$password = pack('H*', bin2hex($bytes));
|
|
}
|
|
|
|
$hash = password_hash($password, PASSWORD_BCRYPT, [ 'cost' => $cost ]);
|
|
if ($hash !== false) {
|
|
$user['password'] = $hash;
|
|
}
|
|
}
|
|
|
|
function local_user_get_groups($user)
|
|
{
|
|
global $config;
|
|
|
|
$groups = array();
|
|
|
|
if (!isset($config['system']['group'])) {
|
|
return $groups;
|
|
}
|
|
|
|
foreach ($config['system']['group'] as $group) {
|
|
if (isset($group['member'])) {
|
|
if (in_array($user['uid'], $group['member'])) {
|
|
$groups[] = $group['name'];
|
|
}
|
|
}
|
|
}
|
|
|
|
sort($groups);
|
|
|
|
return $groups;
|
|
}
|
|
|
|
function local_user_set_groups($user, $new_groups = null)
|
|
{
|
|
global $config, $groupindex;
|
|
|
|
if (!isset($config['system']['group'])) {
|
|
return;
|
|
}
|
|
|
|
$cur_groups = local_user_get_groups($user);
|
|
$mod_groups = array();
|
|
|
|
if (!is_array($new_groups)) {
|
|
$new_groups = array();
|
|
}
|
|
|
|
if (!is_array($cur_groups)) {
|
|
$cur_groups = array();
|
|
}
|
|
|
|
/* determine which memberships to add */
|
|
foreach ($new_groups as $groupname) {
|
|
if (in_array($groupname, $cur_groups) || !isset($groupindex[$groupname])) {
|
|
// continue if group is already in current list or the groupname is invalid
|
|
continue;
|
|
}
|
|
$group = &config_read_array('system', 'group', $groupindex[$groupname]);
|
|
$group['member'][] = $user['uid'];
|
|
$mod_groups[] = $group;
|
|
}
|
|
|
|
/* determine which memberships to remove */
|
|
foreach ($cur_groups as $groupname) {
|
|
if (in_array($groupname, $new_groups)) {
|
|
continue;
|
|
}
|
|
if (!isset($config['system']['group'][$groupindex[$groupname]])) {
|
|
continue;
|
|
}
|
|
$group = &config_read_array('system', 'group', $groupindex[$groupname]);
|
|
if (is_array($group['member'])) {
|
|
$index = array_search($user['uid'], $group['member']);
|
|
array_splice($group['member'], $index, 1);
|
|
$mod_groups[] = $group;
|
|
}
|
|
}
|
|
|
|
/* sync all modified groups */
|
|
foreach ($mod_groups as $group) {
|
|
local_group_set($group);
|
|
}
|
|
}
|
|
|
|
function local_group_del_user($user)
|
|
{
|
|
global $config;
|
|
|
|
if (!isset($config['system']['group'])) {
|
|
return;
|
|
}
|
|
|
|
foreach ($config['system']['group'] as $group) {
|
|
if (isset($group['member'])) {
|
|
foreach ($group['member'] as $idx => $uid) {
|
|
if ($user['uid'] == $uid) {
|
|
unset($config['system']['group']['member'][$idx]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function local_group_set($group, $reset = false)
|
|
{
|
|
if (!isset($group['name']) || !isset($group['gid'])) {
|
|
return;
|
|
}
|
|
|
|
$group_name = $group['name'];
|
|
$group_gid = $group['gid'];
|
|
$group_members = '';
|
|
|
|
if (!$reset && !empty($group['member']) && count($group['member']) > 0) {
|
|
$group_members = implode(',', $group['member']);
|
|
}
|
|
|
|
$ret = mwexecf('/usr/sbin/pw groupshow %s', $group_name, true);
|
|
if ($ret) {
|
|
$group_op = 'groupadd';
|
|
} else {
|
|
$group_op = 'groupmod';
|
|
}
|
|
|
|
mwexecf('/usr/sbin/pw %s %s -g %s -M %s', array($group_op, $group_name, $group_gid, $group_members));
|
|
}
|
|
|
|
function local_group_del($group)
|
|
{
|
|
/* delete from group db */
|
|
mwexecf('/usr/sbin/pw groupdel %s', $group['name']);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $name string name of the authentication system configured on the authentication server page or 'Local Database' for local authentication
|
|
* @return array|bool false if the authentication server was not found, otherwise the configuration of the authentication server
|
|
*/
|
|
function auth_get_authserver($name)
|
|
{
|
|
global $config;
|
|
|
|
if ($name == "Local Database") {
|
|
return array(
|
|
"name" => gettext("Local Database"),
|
|
"type" => "local",
|
|
"host" => $config['system']['hostname']
|
|
);
|
|
}
|
|
|
|
if (isset($config['system']['authserver']) && is_array($config['system']['authserver'])) {
|
|
foreach ($config['system']['authserver'] as $authcfg) {
|
|
if ($authcfg['name'] == $name) {
|
|
if ($authcfg['type'] == 'ldap' || $authcfg['type'] == 'ldap-totp') {
|
|
// make sure a user and password entry exists and are null for anonymous usage
|
|
if (empty($authcfg['ldap_binddn'])) {
|
|
$authcfg['ldap_binddn'] = null;
|
|
}
|
|
if (empty($authcfg['ldap_bindpw'])) {
|
|
$authcfg['ldap_bindpw'] = null;
|
|
}
|
|
}
|
|
return $authcfg;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function auth_get_authserver_list()
|
|
{
|
|
global $config;
|
|
|
|
$list = array();
|
|
|
|
if (isset($config['system']['authserver']) && is_array($config['system']['authserver'])) {
|
|
foreach ($config['system']['authserver'] as $authcfg) {
|
|
/* Add support for disabled entries? */
|
|
$list[$authcfg['name']] = $authcfg;
|
|
}
|
|
}
|
|
|
|
$list["Local Database"] = array( "name" => gettext("Local Database"), "type" => "local", "host" => $config['system']['hostname']);
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* return authenticator object
|
|
* @param array|null $authcfg configuration
|
|
* @return Auth\Base type object
|
|
*/
|
|
function get_authenticator($authcfg = null)
|
|
{
|
|
if (empty($authcfg)) {
|
|
$authName = 'Local Database';
|
|
} else {
|
|
$authName = $authcfg['name'];
|
|
if ($authcfg['type'] == 'local') {
|
|
// avoid gettext type issues on Local Database, authenticator should always be named "Local Database"
|
|
$authName = 'Local Database';
|
|
}
|
|
}
|
|
|
|
$authFactory = new OPNsense\Auth\AuthenticationFactory();
|
|
return $authFactory->get($authName);
|
|
}
|
|
|
|
function authenticate_user($username, $password, $authcfg = null)
|
|
{
|
|
$authenticator = get_authenticator($authcfg);
|
|
if ($authenticator != null) {
|
|
return $authenticator->authenticate($username, $password);
|
|
} else {
|
|
log_error('Unable to retrieve authenticator for ' . $username);
|
|
return false;
|
|
}
|
|
}
|