mirror of
https://github.com/nuxsmin/sysPass.git
synced 2026-03-08 09:26:57 +01:00
* [ADD] ADS LDAP server selection by DNS records
This commit is contained in:
@@ -59,6 +59,7 @@ $Log = new \SP\Log(_('Inicio sesión'));
|
||||
// Autentificamos por LDAP
|
||||
if ($resLdap === true) {
|
||||
$Log->addDescription('(LDAP)');
|
||||
$Log->addDescription(sprintf('%s : %s', _('Servidor Login'), \SP\Ldap::getLdapServer()));
|
||||
|
||||
// Verificamos si el usuario existe en la BBDD
|
||||
if (!UserLdap::checkLDAPUserInDB($userLogin)) {
|
||||
@@ -163,9 +164,9 @@ if ($User->getUserMPass()) {
|
||||
// Establecemos las variables de sesión
|
||||
UserUtil::setUserSession($User);
|
||||
|
||||
$Log->addDescription(_('Usuario') . ": " . $userLogin);
|
||||
$Log->addDescription(_('Perfil') . ": " . SP\Profile::getProfileNameById($User->getUserProfileId()));
|
||||
$Log->addDescription(_('Grupo') . ": " . SP\Groups::getGroupNameById($User->getUserGroupId()));
|
||||
$Log->addDescription(sprintf('%s : %s', _('Usuario'), $userLogin));
|
||||
$Log->addDescription(sprintf('%s : %s', _('Perfil'), SP\Profile::getProfileNameById($User->getUserProfileId())));
|
||||
$Log->addDescription(sprintf('%s : %s', _('Grupo'), SP\Groups::getGroupNameById($User->getUserGroupId())));
|
||||
$Log->writeLog();
|
||||
} else {
|
||||
SP\Common::printJSON(_('Error interno'));
|
||||
|
||||
@@ -103,7 +103,7 @@ class Auth
|
||||
}
|
||||
// Comprobamos que el usuario está en el grupo indicado buscando en los atributos del grupo
|
||||
} else {
|
||||
$ldapGroupAccess = (Ldap::searchUserInGroup($userDN) || Ldap::searchADUserInGroup($userLogin));
|
||||
$ldapGroupAccess = (Ldap::searchUserInGroup($userDN) || LdapADS::searchADUserInGroup($userLogin));
|
||||
}
|
||||
|
||||
if ($ldapGroupAccess === false) {
|
||||
|
||||
@@ -35,17 +35,25 @@ class Ldap
|
||||
{
|
||||
// Variabla que contiene los datos de una búsqueda
|
||||
public static $ldapSearchData;
|
||||
|
||||
// Variable para determinar si conecta con Active Directory
|
||||
private static $_isADS = false;
|
||||
protected static $_isADS = false;
|
||||
|
||||
// Variables de conexión con LDAP
|
||||
private static $_ldapConn;
|
||||
private static $_ldapServer;
|
||||
private static $_searchBase;
|
||||
protected static $_ldapConn;
|
||||
protected static $_ldapServer;
|
||||
protected static $_searchBase;
|
||||
private static $_bindDN;
|
||||
private static $_bindPass;
|
||||
private static $_ldapGroup;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getLdapServer()
|
||||
{
|
||||
return self::$_ldapServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener el recurso de conexión a LDAP.
|
||||
*
|
||||
@@ -99,8 +107,8 @@ class Ldap
|
||||
|
||||
// Conexión al servidor LDAP
|
||||
if (!self::$_ldapConn = @ldap_connect(self::$_ldapServer)) {
|
||||
$log->addDescription(_('No es posible conectar con el servidor de LDAP') . " '" . self::$_ldapServer . "'");
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(self::$_ldapConn) . '(' . ldap_errno(self::$_ldapConn) . ')');
|
||||
$log->addDescription(sprintf('%s \'%s\'', _('No es posible conectar con el servidor de LDAP'), self::$_ldapServer));
|
||||
$log->addDescription(sprintf('LDAP ERROR: %s (%d)', ldap_error(self::$_ldapConn), ldap_errno(self::$_ldapConn)));
|
||||
$log->writeLog();
|
||||
|
||||
throw new \Exception(_('No es posible conectar con el servidor de LDAP'));
|
||||
@@ -129,7 +137,7 @@ class Ldap
|
||||
|
||||
if (!@ldap_bind(self::$_ldapConn, $dn, $pass)) {
|
||||
$log->addDescription(_('Error al conectar (BIND)'));
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(self::$_ldapConn) . '(' . ldap_errno(self::$_ldapConn) . ')');
|
||||
$log->addDescription(sprintf('LDAP ERROR: %s (%d)', ldap_error(self::$_ldapConn), ldap_errno(self::$_ldapConn)));
|
||||
$log->addDescription('LDAP DN: ' . $dn);
|
||||
$log->writeLog();
|
||||
|
||||
@@ -157,7 +165,7 @@ class Ldap
|
||||
|
||||
if (!$searchRes) {
|
||||
$log->addDescription(_('Error al buscar objetos en DN base'));
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(self::$_ldapConn) . '(' . ldap_errno(self::$_ldapConn) . ')');
|
||||
$log->addDescription(sprintf('LDAP ERROR: %s (%d)', ldap_error(self::$_ldapConn), ldap_errno(self::$_ldapConn)));
|
||||
$log->addDescription('LDAP FILTER: ' . $filter);
|
||||
$log->writeLog();
|
||||
|
||||
@@ -173,7 +181,7 @@ class Ldap
|
||||
* @throws \Exception
|
||||
* @return string con el RDN del grupo
|
||||
*/
|
||||
private static function searchGroupDN()
|
||||
protected static function searchGroupDN()
|
||||
{
|
||||
$log = new Log(__FUNCTION__);
|
||||
$groupName = array();
|
||||
@@ -190,7 +198,7 @@ class Ldap
|
||||
|
||||
if (!$searchRes) {
|
||||
$log->addDescription(_('Error al buscar RDN de grupo'));
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(self::$_ldapConn) . '(' . ldap_errno(self::$_ldapConn) . ')');
|
||||
$log->addDescription(sprintf('LDAP ERROR: %s (%d)', ldap_error(self::$_ldapConn), ldap_errno(self::$_ldapConn)));
|
||||
$log->addDescription('LDAP FILTER: ' . $filter);
|
||||
$log->writeLog();
|
||||
|
||||
@@ -202,7 +210,7 @@ class Ldap
|
||||
|
||||
if (!$ldapSearchData) {
|
||||
$log->addDescription(_('Error al buscar RDN de grupo'));
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(self::$_ldapConn) . '(' . ldap_errno(self::$_ldapConn) . ')');
|
||||
$log->addDescription(sprintf('LDAP ERROR: %s (%d)', ldap_error(self::$_ldapConn), ldap_errno(self::$_ldapConn)));
|
||||
$log->writeLog();
|
||||
|
||||
throw new \Exception(_('Error al buscar RDN de grupo'));
|
||||
@@ -229,12 +237,12 @@ class Ldap
|
||||
*/
|
||||
public static function checkLDAPParams()
|
||||
{
|
||||
self::$_isADS = Config::getValue('ldap_ads', false);
|
||||
self::$_searchBase = Config::getValue('ldap_base');
|
||||
self::$_ldapServer = Config::getValue('ldap_server');
|
||||
self::$_ldapServer = (!self::$_isADS) ? Config::getValue('ldap_server') : LdapADS::getADServer(Config::getValue('ldap_server'));
|
||||
self::$_bindDN = Config::getValue('ldap_binduser');
|
||||
self::$_bindPass = Config::getValue('ldap_bindpass');
|
||||
self::$_ldapGroup = Config::getValue('ldap_group', '*');
|
||||
self::$_isADS = Config::getValue('ldap_ads', false);
|
||||
|
||||
if (!self::$_searchBase || !self::$_ldapServer || !self::$_bindDN || !self::$_bindPass) {
|
||||
Log::writeNewLog(__FUNCTION__, _('Los parámetros de LDAP no están configurados'));
|
||||
@@ -268,7 +276,7 @@ class Ldap
|
||||
|
||||
if (!$searchRes) {
|
||||
$log->addDescription(_('Error al buscar el DN del usuario'));
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(self::$_ldapConn) . '(' . ldap_errno(self::$_ldapConn) . ')');
|
||||
$log->addDescription(sprintf('LDAP ERROR: %s (%d)', ldap_error(self::$_ldapConn), ldap_errno(self::$_ldapConn)));
|
||||
$log->addDescription('LDAP FILTER: ' . $filter);
|
||||
$log->writeLog();
|
||||
|
||||
@@ -280,7 +288,7 @@ class Ldap
|
||||
|
||||
if (!self::$ldapSearchData) {
|
||||
$log->addDescription(_('Error al localizar el usuario en LDAP'));
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(self::$_ldapConn) . '(' . ldap_errno(self::$_ldapConn) . ')');
|
||||
$log->addDescription(sprintf('LDAP ERROR: %s (%d)', ldap_error(self::$_ldapConn), ldap_errno(self::$_ldapConn)));
|
||||
$log->writeLog();
|
||||
|
||||
throw new \Exception(_('Error al localizar el usuario en LDAP'));
|
||||
@@ -365,7 +373,7 @@ class Ldap
|
||||
|
||||
if (!$searchRes) {
|
||||
$log->addDescription(_('Error al buscar el grupo de usuarios'));
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(self::$_ldapConn) . '(' . ldap_errno(self::$_ldapConn) . ')');
|
||||
$log->addDescription(sprintf('LDAP ERROR: %s (%d)', ldap_error(self::$_ldapConn), ldap_errno(self::$_ldapConn)));
|
||||
$log->addDescription('LDAP FILTER: ' . $filter);
|
||||
$log->writeLog();
|
||||
|
||||
@@ -394,62 +402,5 @@ class Ldap
|
||||
return preg_replace($chars, '\\\$1', $dn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Buscar al usuario en un grupo.
|
||||
*
|
||||
* @param string $userLogin con el login del usuario
|
||||
* @throws \Exception
|
||||
* @return bool
|
||||
*/
|
||||
public static function searchADUserInGroup($userLogin)
|
||||
{
|
||||
if (self::$_isADS === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$log = new Log(__FUNCTION__);
|
||||
|
||||
$ldapGroup = Config::getValue('ldap_group');
|
||||
|
||||
// El filtro de grupo no está establecido
|
||||
if (empty($ldapGroup)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Obtenemos el DN del grupo
|
||||
if (!$groupDN = self::searchGroupDN()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$filter = '(memberof:1.2.840.113556.1.4.1941:=' . $groupDN . ')';
|
||||
$filterAttr = array("sAMAccountName");
|
||||
|
||||
$searchRes = @ldap_search(self::$_ldapConn, self::$_searchBase, $filter, $filterAttr);
|
||||
|
||||
if (!$searchRes) {
|
||||
$log->addDescription(_('Error al buscar el grupo de usuarios'));
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(self::$_ldapConn) . '(' . ldap_errno(self::$_ldapConn) . ')');
|
||||
$log->addDescription('LDAP FILTER: ' . $filter);
|
||||
$log->writeLog();
|
||||
|
||||
throw new \Exception(_('Error al buscar el grupo de usuarios'));
|
||||
}
|
||||
|
||||
if (@ldap_count_entries(self::$_ldapConn, $searchRes) === 0) {
|
||||
$log->addDescription(_('No se encontró el grupo con ese nombre'));
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(self::$_ldapConn) . '(' . ldap_errno(self::$_ldapConn) . ')');
|
||||
$log->addDescription('LDAP FILTER: ' . $filter);
|
||||
$log->writeLog();
|
||||
|
||||
throw new \Exception(_('No se encontró el grupo con ese nombre'));
|
||||
}
|
||||
|
||||
foreach (ldap_get_entries(self::$_ldapConn, $searchRes) as $entry) {
|
||||
if ($userLogin === $entry['samaccountname'][0]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
119
inc/LdapADS.class.php
Normal file
119
inc/LdapADS.class.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
* sysPass
|
||||
*
|
||||
* @author nuxsmin
|
||||
* @link http://syspass.org
|
||||
* @copyright 2012-2015 Rubén Domínguez nuxsmin@syspass.org
|
||||
*
|
||||
* This file is part of sysPass.
|
||||
*
|
||||
* sysPass is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* sysPass is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace SP;
|
||||
|
||||
defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo'));
|
||||
|
||||
class LdapADS extends Ldap
|
||||
{
|
||||
/**
|
||||
* Obtener un servidor de AD aleatorio
|
||||
*
|
||||
* @param $server string El servidor de AD
|
||||
* @return string
|
||||
*/
|
||||
public static function getADServer($server)
|
||||
{
|
||||
$serverDomain = '';
|
||||
$serverFQDN = explode('.', $server);
|
||||
|
||||
for ($i = 1; $i <= count($serverFQDN) - 1; $i++){
|
||||
$serverDomain .= $serverFQDN[$i] . '.';
|
||||
}
|
||||
|
||||
$dnsServerQuery = '_msdcs.' . $serverDomain;
|
||||
$records = dns_get_record($dnsServerQuery, DNS_NS);
|
||||
|
||||
if (count($records) === 0) {
|
||||
return parent::$_ldapServer;
|
||||
}
|
||||
|
||||
foreach ($records as $record) {
|
||||
$ads[] = $record['target'];
|
||||
};
|
||||
|
||||
return $ads[rand(0, count($ads) - 1)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Buscar al usuario en un grupo.
|
||||
*
|
||||
* @param string $userLogin con el login del usuario
|
||||
* @throws \Exception
|
||||
* @return bool
|
||||
*/
|
||||
public static function searchADUserInGroup($userLogin)
|
||||
{
|
||||
if (Ldap::$_isADS === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$log = new Log(__FUNCTION__);
|
||||
|
||||
$ldapGroup = Config::getValue('ldap_group');
|
||||
|
||||
// El filtro de grupo no está establecido
|
||||
if (empty($ldapGroup)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Obtenemos el DN del grupo
|
||||
if (!$groupDN = Ldap::searchGroupDN()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$filter = '(memberof:1.2.840.113556.1.4.1941:=' . $groupDN . ')';
|
||||
$filterAttr = array("sAMAccountName");
|
||||
|
||||
$searchRes = @ldap_search(Ldap::$_ldapConn, Ldap::$_searchBase, $filter, $filterAttr);
|
||||
|
||||
if (!$searchRes) {
|
||||
$log->addDescription(_('Error al buscar el grupo de usuarios'));
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(Ldap::$_ldapConn) . '(' . ldap_errno(Ldap::$_ldapConn) . ')');
|
||||
$log->addDescription('LDAP FILTER: ' . $filter);
|
||||
$log->writeLog();
|
||||
|
||||
throw new \Exception(_('Error al buscar el grupo de usuarios'));
|
||||
}
|
||||
|
||||
if (@ldap_count_entries(Ldap::$_ldapConn, $searchRes) === 0) {
|
||||
$log->addDescription(_('No se encontró el grupo con ese nombre'));
|
||||
$log->addDescription('LDAP ERROR: ' . ldap_error(Ldap::$_ldapConn) . '(' . ldap_errno(Ldap::$_ldapConn) . ')');
|
||||
$log->addDescription('LDAP FILTER: ' . $filter);
|
||||
$log->writeLog();
|
||||
|
||||
throw new \Exception(_('No se encontró el grupo con ese nombre'));
|
||||
}
|
||||
|
||||
foreach (ldap_get_entries(Ldap::$_ldapConn, $searchRes) as $entry) {
|
||||
if ($userLogin === $entry['samaccountname'][0]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user