mirror of
https://github.com/nuxsmin/sysPass.git
synced 2026-03-06 00:24:08 +01:00
* [DEV] LDAP improvements
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
use SP\Auth\Ldap;
|
||||
use SP\Auth\Ldap\Ldap;
|
||||
use SP\Core\Init;
|
||||
use SP\Core\SessionUtil;
|
||||
use SP\Http\Request;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
use SP\Auth\Auth;
|
||||
use SP\Auth\Ldap;
|
||||
use SP\Auth\Ldap\Ldap;
|
||||
use SP\Core\CryptMasterPass;
|
||||
use SP\Core\Init;
|
||||
use SP\Core\Language;
|
||||
@@ -36,7 +36,6 @@ use SP\DataModel\UserData;
|
||||
use SP\DataModel\UserPassRecoverData;
|
||||
use SP\Http\JsonResponse;
|
||||
use SP\Http\Request;
|
||||
use SP\Http\Response;
|
||||
use SP\Log\Log;
|
||||
use SP\Mgmt\Groups\Group;
|
||||
use SP\Mgmt\Profiles\Profile;
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
namespace SP\Auth;
|
||||
|
||||
use SP\Auth\Ldap\Ldap;
|
||||
use SP\Auth\Ldap\LdapADS;
|
||||
use SP\Config\Config;
|
||||
use SP\Core\Exceptions\SPException;
|
||||
use SP\DataModel\UserData;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace SP\Auth;
|
||||
namespace SP\Auth\Ldap;
|
||||
|
||||
use SP\Config\Config;
|
||||
use SP\Log\Log;
|
||||
@@ -23,8 +23,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace SP\Auth;
|
||||
namespace SP\Auth\Ldap;
|
||||
|
||||
use SP\Auth\Ldap\Ldap;
|
||||
use SP\Config\Config;
|
||||
use SP\Log\Log;
|
||||
|
||||
248
inc/SP/Auth/Ldap/LdapBase.class.php
Normal file
248
inc/SP/Auth/Ldap/LdapBase.class.php
Normal file
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
|
||||
namespace Auth\Ldap;
|
||||
|
||||
use SP\Config\Config;
|
||||
use SP\Log\Log;
|
||||
|
||||
abstract class LdapBase implements LdapInterface
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $ldapHandler;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $server;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $searchBase;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $bindDn;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $bindPass;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $group;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $searchData;
|
||||
|
||||
/**
|
||||
* Comprobar si los parámetros necesario de LDAP están establecidos.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkParams()
|
||||
{
|
||||
// self::$isADS = Config::getConfig()->isLdapAds();
|
||||
$this->searchBase = Config::getConfig()->getLdapBase();
|
||||
// $this->server = (!self::$isADS) ? Config::getConfig()->getLdapServer() : LdapADS::getADServer(Config::getConfig()->getLdapServer());
|
||||
$this->server = $this->pickServer();
|
||||
$this->bindDn = Config::getConfig()->getLdapBindUser();
|
||||
$this->bindPass = Config::getConfig()->getLdapBindPass();
|
||||
$this->group = Config::getConfig()->getLdapGroup();
|
||||
|
||||
if (!$this->searchBase || !$this->server || !$this->bindDn || !$this->bindPass) {
|
||||
Log::writeNewLog(__FUNCTION__, _('Los parámetros de LDAP no están configurados'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener el RDN del grupo.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @return string con el RDN del grupo
|
||||
*/
|
||||
protected function searchGroupDN()
|
||||
{
|
||||
$Log = new Log(__FUNCTION__);
|
||||
$filter = $this->searchGroupDN() ?: $this->group;
|
||||
$filter = '(cn=' . $filter . ')';
|
||||
$filterAttr = ["dn", "cn"];
|
||||
|
||||
$searchRes = @ldap_search($this->ldapHandler, $this->searchBase, $filter, $filterAttr);
|
||||
|
||||
if (!$searchRes) {
|
||||
$Log->setLogLevel(Log::ERROR);
|
||||
$Log->addDescription(_('Error al buscar RDN de grupo'));
|
||||
$Log->addDetails(_('Grupo'), $filter);
|
||||
$Log->addDetails('LDAP ERROR', sprintf('%s (%d)', ldap_error($this->ldapHandler), ldap_errno($this->ldapHandler)));
|
||||
$Log->addDetails('LDAP FILTER', $filter);
|
||||
$Log->writeLog();
|
||||
|
||||
throw new \Exception(_('Error al buscar RDN de grupo'));
|
||||
}
|
||||
|
||||
if (@ldap_count_entries($this->ldapHandler, $searchRes) === 1) {
|
||||
$ldapSearchData = @ldap_get_entries($this->ldapHandler, $searchRes);
|
||||
|
||||
if (!$ldapSearchData) {
|
||||
$Log->setLogLevel(Log::ERROR);
|
||||
$Log->addDescription(_('Error al buscar RDN de grupo'));
|
||||
$Log->addDetails(_('Grupo'), $filter);
|
||||
$Log->addDetails('LDAP ERROR', sprintf('%s (%d)', ldap_error($this->ldapHandler), ldap_errno($this->ldapHandler)));
|
||||
$Log->writeLog();
|
||||
|
||||
throw new \Exception(_('Error al buscar RDN de grupo'));
|
||||
}
|
||||
|
||||
return $ldapSearchData[0]["dn"];
|
||||
} else {
|
||||
$Log->setLogLevel(Log::ERROR);
|
||||
$Log->addDescription(_('Error al buscar RDN de grupo'));
|
||||
$Log->addDetails(_('Grupo'), $filter);
|
||||
$Log->addDetails('LDAP FILTER', $filter);
|
||||
$Log->writeLog();
|
||||
|
||||
throw new \Exception(_('Error al buscar RDN de grupo'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener el nombre del grupo a partir del CN
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function getGroupName()
|
||||
{
|
||||
if (isset($this->group) && preg_match('/^cn=([\w\s-]+),.*/i', $this->group, $groupName)) {
|
||||
return $groupName[1];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapar carácteres especiales en el RDN de LDAP.
|
||||
*
|
||||
* @param string $dn con el RDN del usuario
|
||||
* @return string
|
||||
*/
|
||||
protected function escapeLdapDN($dn)
|
||||
{
|
||||
$chars = array('/(,)(?!uid|cn|ou|dc)/i', '/(?<!uid|cn|ou|dc)(=)/i', '/(")/', '/(;)/', '/(>)/', '/(<)/', '/(\+)/', '/(#)/', '/\G(\s)/', '/(\s)(?=\s*$)/', '/(\/)/');
|
||||
return preg_replace($chars, '\\\$1', $dn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Realizar la desconexión del servidor de LDAP.
|
||||
*/
|
||||
public function unbind()
|
||||
{
|
||||
@ldap_unbind($this->ldapHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener el filtro para buscar el usuario
|
||||
*
|
||||
* @param string $userLogin Login del usuario
|
||||
* @return mixed
|
||||
*/
|
||||
protected abstract function getUserDnFilter($userLogin);
|
||||
|
||||
/**
|
||||
* Obtener el RDN del usuario que realiza el login.
|
||||
*
|
||||
* @param string $userLogin Login del usuario
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getUserDN($userLogin)
|
||||
{
|
||||
$Log = new Log(__FUNCTION__);
|
||||
|
||||
// if (self::$isADS === true) {
|
||||
// $filter = '(&(|(samaccountname=' . $userLogin . ')(cn=' . $userLogin . ')(uid=' . $userLogin . '))(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject))(objectCategory=person))';
|
||||
// } else {
|
||||
// $filter = '(&(|(samaccountname=' . $userLogin . ')(cn=' . $userLogin . ')(uid=' . $userLogin . '))(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject)))';
|
||||
// }
|
||||
|
||||
$filterAttr = array("dn", "displayname", "samaccountname", "mail", "memberof", "lockouttime", "fullname", "groupmembership", "mail");
|
||||
|
||||
$searchRes = @ldap_search($this->ldapHandler, $this->searchBase, $this->getUserDnFilter($userLogin), $filterAttr);
|
||||
|
||||
if (!$searchRes) {
|
||||
$Log->setLogLevel(Log::ERROR);
|
||||
$Log->addDescription(_('Error al buscar el DN del usuario'));
|
||||
$Log->addDetails(_('Usuario'), $userLogin);
|
||||
$Log->addDetails('LDAP ERROR', sprintf('%s (%d)', ldap_error($this->ldapHandler), ldap_errno($this->ldapHandler)));
|
||||
$Log->addDetails('LDAP FILTER', $this->getUserDnFilter());
|
||||
$Log->writeLog();
|
||||
|
||||
throw new \Exception(_('Error al buscar el DN del usuario'));
|
||||
}
|
||||
|
||||
if (@ldap_count_entries($this->ldapHandler, $searchRes) === 1) {
|
||||
$ldapSearchData = @ldap_get_entries($this->ldapHandler, $searchRes);
|
||||
|
||||
if (!$ldapSearchData) {
|
||||
$Log->setLogLevel(Log::ERROR);
|
||||
$Log->addDescription(_('Error al localizar el usuario en LDAP'));
|
||||
$Log->addDetails(_('Usuario'), $userLogin);
|
||||
$Log->addDetails('LDAP ERROR', sprintf('%s (%d)', ldap_error($this->ldapHandler), ldap_errno($this->ldapHandler)));
|
||||
$Log->writeLog();
|
||||
|
||||
throw new \Exception(_('Error al localizar el usuario en LDAP'));
|
||||
}
|
||||
} else {
|
||||
$Log->setLogLevel(Log::ERROR);
|
||||
$Log->addDescription(_('Error al buscar el DN del usuario'));
|
||||
$Log->addDetails(_('Usuario'), $userLogin);
|
||||
$Log->addDetails('LDAP FILTER', $this->getUserDnFilter());
|
||||
$Log->writeLog();
|
||||
|
||||
throw new \Exception(_('Error al buscar el DN del usuario'));
|
||||
}
|
||||
|
||||
return $ldapSearchData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener el servidor de LDAP a utilizar
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected abstract function pickServer();
|
||||
|
||||
/**
|
||||
* Realizar una búsqueda de objetos en la ruta indicada.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @return int El número de resultados
|
||||
*/
|
||||
protected function searchBase()
|
||||
{
|
||||
$Log = new Log(__FUNCTION__);
|
||||
|
||||
$groupDN = (!empty($this->group)) ? $this->searchGroupDN() : '*';
|
||||
$filter = '(&(|(memberOf=' . $groupDN . ')(groupMembership=' . $groupDN . '))(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject)))';
|
||||
$filterAttr = ["dn"];
|
||||
|
||||
$searchRes = @ldap_search($this->ldapHandler, $this->searchBase, $filter, $filterAttr);
|
||||
|
||||
if (!$searchRes) {
|
||||
$Log->setLogLevel(Log::ERROR);
|
||||
$Log->addDescription(_('Error al buscar objetos en DN base'));
|
||||
$Log->addDetails('LDAP ERROR', sprintf('%s (%d)', ldap_error($this->ldapHandler), ldap_errno($this->ldapHandler)));
|
||||
$Log->addDetails('LDAP FILTER', $filter);
|
||||
$Log->writeLog();
|
||||
|
||||
throw new \Exception(_('Error al buscar objetos en DN base'));
|
||||
}
|
||||
|
||||
return @ldap_count_entries($this->ldapHandler, $searchRes);
|
||||
}
|
||||
}
|
||||
58
inc/SP/Auth/Ldap/LdapInterface.class.php
Normal file
58
inc/SP/Auth/Ldap/LdapInterface.class.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Auth\Ldap;
|
||||
|
||||
interface LdapInterface
|
||||
{
|
||||
/**
|
||||
* Realizar la autentificación con el servidor de LDAP.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function bind();
|
||||
|
||||
/**
|
||||
* Comprobar la conexión al servidor de LDAP.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkConnection();
|
||||
|
||||
/**
|
||||
* Realizar la conexión al servidor de LDAP.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function connect();
|
||||
|
||||
/**
|
||||
* Comprobar si los parámetros necesarios de LDAP están establecidos.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkParams();
|
||||
|
||||
/**
|
||||
* Obtener el RDN del usuario que realiza el login.
|
||||
*
|
||||
* @param string $userLogin Login del usuario
|
||||
* @return string
|
||||
*/
|
||||
public function getUserDN($userLogin);
|
||||
|
||||
public function unbind();
|
||||
|
||||
/**
|
||||
* Obtener los atributos del usuario.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes();
|
||||
|
||||
/**
|
||||
* Buscar al usuario en un grupo.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function searchUsrInGroup();
|
||||
}
|
||||
Reference in New Issue
Block a user