diff --git a/ajax/ajax_checkLdap.php b/ajax/ajax_checkLdap.php new file mode 100644 index 00000000..59066ff4 --- /dev/null +++ b/ajax/ajax_checkLdap.php @@ -0,0 +1,53 @@ +. +* +*/ + +define('APP_ROOT', '..'); +include_once (APP_ROOT."/inc/init.php"); + +SP_Util::checkReferer('POST'); + +if ( ! SP_Init::isLoggedIn() ) { + SP_Common::printJSON(_('La sesión no se ha iniciado o ha caducado'), 10); +} + +$sk = SP_Common::parseParams('p', 'sk', FALSE); + +if (!$sk || !SP_Common::checkSessionKey($sk)) { + SP_Common::printJSON(_('CONSULTA INVÁLIDA')); +} + +$frmLdapServer = SP_Common::parseParams('p', 'ldapserver'); +$frmLdapBase = SP_Common::parseParams('p', 'ldapbase'); +$frmLdapGroup = SP_Common::parseParams('p', 'ldapgroup'); +$frmLdapBindUser = SP_Common::parseParams('p', 'ldapbinduser'); +$frmLdapBindPass = SP_Common::parseParams('p', 'ldapbindpass'); + +$resCheckLdap = SP_LDAP::checkLDAPConn($frmLdapServer,$frmLdapBindUser,$frmLdapBindPass,$frmLdapBase,$frmLdapGroup); + +if ( $resCheckLdap === FALSE ){ + SP_Common::printJSON(_('Error de conexión a LDAP').';;'._('Revise el registro de eventos para más detalles')); +} else{ + SP_Common::printJSON(_('Conexión a LDAP correcta').';;'._('Objetos encontrados').': '.$resCheckLdap,0); +} \ No newline at end of file diff --git a/imgs/refresh.png b/imgs/refresh.png new file mode 100644 index 00000000..8cac11a6 Binary files /dev/null and b/imgs/refresh.png differ diff --git a/inc/auth.class.php b/inc/auth.class.php index e7c08d39..7e071a52 100644 --- a/inc/auth.class.php +++ b/inc/auth.class.php @@ -51,8 +51,8 @@ class SP_Auth { // Conectamos al servidor realizamos la conexión con el usuario proxy try { - SP_LDAP::connect(); - SP_LDAP::bind(); + SP_LDAP::ldapConnect(); + SP_LDAP::ldapBind(); SP_LDAP::getUserDN($userLogin); } catch (Exception $e) { return FALSE; @@ -70,7 +70,7 @@ class SP_Auth { // Realizamos la conexión con el usuario real y obtenemos los atributos try{ - SP_LDAP::bind($userDN, $userPass); + SP_LDAP::ldapBind($userDN, $userPass); SP_LDAP::unbind(); $attribs = SP_LDAP::getLDAPAttr($attribsMap); } catch (Exception $e) { diff --git a/inc/ldap.class.php b/inc/ldap.class.php index 52a5f609..d7413316 100644 --- a/inc/ldap.class.php +++ b/inc/ldap.class.php @@ -29,38 +29,57 @@ defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo' * Esta clase es la encargada de realizar la autentificación de usuarios de sysPass. */ class SP_LDAP { + private static $ldapConn; private static $ldapServer; private static $searchBase; private static $bindDN; private static $bindPass; private static $ldapGroup; - public static $ldapSearchData; /** * @brief Obtener el recurso de conexión a LDAP * @return resource */ - public static function getConn(){ - if (is_resource(self::$ldapConn)){ + public static function getConn() { + if (is_resource(self::$ldapConn)) { return self::$ldapConn; } } - + /** * @brief Comprobar la conexión al servidor de LDAP + * @param string $ldapServer con la dirección del servidor + * @param string $bindDN con el usuario de conexión + * @param string $bindPass con la clave del usuario de conexión + * @param string $searchBase con la base para las búsquedas + * @param string $ldapGroup con el grupo con los usuarios de acceso * @return bool */ - public static function checkLDAPConn(){ + public static function checkLDAPConn($ldapServer, $bindDN, $bindPass, $searchBase, $ldapGroup) { + self::$ldapServer = $ldapServer; + self::$bindDN = $bindDN; + self::$bindPass = $bindPass; + self::$searchBase = $searchBase; + self::$ldapGroup = $ldapGroup; + try { + self::ldapConnect(); + self::ldapBind(); + $numObjects = self::searchBase(); + } catch (Exception $e) { + return FALSE; + } + + return $numObjects; } - + /** * @brief Comprobar si los parámetros necesario de LDAP están establecidos * @return bool */ - public static function checkLDAPParams(){ + public static function checkLDAPParams() { self::$searchBase = SP_Config::getValue('ldapbase'); self::$ldapServer = SP_Config::getValue('ldapserver'); self::$bindDN = SP_Config::getValue('ldapbinduser'); @@ -70,12 +89,12 @@ class SP_LDAP { if (!self::$searchBase || !self::$ldapServer || !self::$ldapGroup || !self::$bindDN || !self::$bindPass) { $message['action'] = __FUNCTION__; $message['text'][] = _('Los parámetros de LDAP no están configurados'); - + SP_Common::wrLogInfo($message); - + return FALSE; } - + return TRUE; } @@ -84,22 +103,22 @@ class SP_LDAP { * @param string $server con la dirección del servidor * @return bool */ - public static function connect(){ + public static function ldapConnect() { $message['action'] = __FUNCTION__; - + // Conexión al servidor LDAP if (!self::$ldapConn = @ldap_connect(self::$ldapServer)) { $message['text'][] = _('No es posible conectar con el servidor de LDAP') . " '" . self::$ldapServer . "'"; $message['text'][] = 'LDAP ERROR: ' . ldap_error(self::$ldapConn) . '(' . ldap_errno(self::$ldapConn) . ')'; - + SP_Common::wrLogInfo($message); - + throw new Exception(_('No es posible conectar con el servidor de LDAP')); } - + @ldap_set_option(self::$ldapConn, LDAP_OPT_NETWORK_TIMEOUT, 10); // Set timeout @ldap_set_option(self::$ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3); // Set LDAP version - + return TRUE; } @@ -109,33 +128,33 @@ class SP_LDAP { * @param string $pass con la clave del usuario * @return bool */ - public static function bind($userDN = '', $userPass = ''){ + public static function ldapBind($userDN = '', $userPass = '') { $message['action'] = __FUNCTION__; - + $dn = ( $userDN ) ? $userDN : self::$bindDN; $pass = ( $userPass ) ? $userPass : self::$bindPass; - + if (!@ldap_bind(self::$ldapConn, $dn, $pass)) { $message['text'][] = _('Error al conectar (BIND)'); $message['text'][] = 'LDAP ERROR: ' . ldap_error(self::$ldapConn) . '(' . ldap_errno(self::$ldapConn) . ')'; $message['text'][] = 'LDAP DN: ' . $dn; SP_Common::wrLogInfo($message); - + throw new Exception(_('Error al conectar (BIND)')); } - + return TRUE; } - + /** * @brief Obtener el RDN del usuario que realiza el login * @param string $userLogin con el login del usuario * @return none */ - public static function getUserDN($userLogin){ + public static function getUserDN($userLogin) { $message['action'] = __FUNCTION__; - + $filter = '(&(|(samaccountname=' . $userLogin . ')(cn=' . $userLogin . ')(uid=' . $userLogin . '))(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject)))'; $filterAttr = array("dn", "displayname", "samaccountname", "mail", "memberof", "lockouttime", "fullname", "groupmembership", "mail"); @@ -147,7 +166,7 @@ class SP_LDAP { $message['text'][] = 'LDAP FILTER: ' . $filter; SP_Common::wrLogInfo($message); - + throw new Exception(_('Error al buscar el DN del usuario')); } @@ -159,40 +178,43 @@ class SP_LDAP { $message['text'][] = 'LDAP ERROR: ' . ldap_error(self::$ldapConn) . '(' . ldap_errno(self::$ldapConn) . ')'; SP_Common::wrLogInfo($message); - + throw new Exception(_('Error al localizar el usuario en LDAP')); } - - //return $searchUser[0]["dn"]; } else { $message['text'][] = _('Error al buscar el DN del usuario'); $message['text'][] = 'LDAP FILTER: ' . $filter; SP_Common::wrLogInfo($message); - + throw new Exception(_('Error al buscar el DN del usuario')); } } - + /** * @brief Realizar la desconexión del servidor de LDAP * @return none */ - public static function unbind(){ + public static function unbind() { @ldap_unbind(self::$ldapConn); } - - public static function getLDAPAttr($attribs){ + + /** + * @brief Obtener los atributos del usuario + * @param array $attribs con los atributos a obtener + * @return array con los atributos disponibles y sus valores + */ + public static function getLDAPAttr($attribs) { $res = array(); - + foreach (self::$ldapSearchData as $entryValue) { if (is_array($entryValue)) { foreach ($entryValue as $entryAttr => $attrValue) { if (is_array($attrValue)) { - if (array_key_exists($entryAttr, $attribs)){ - if ( $attrValue['count'] > 1 ){ + if (array_key_exists($entryAttr, $attribs)) { + if ($attrValue['count'] > 1) { $res[$attribs[$entryAttr]] = $attrValue; - } else{ + } else { $res[$attribs[$entryAttr]] = $attrValue[0]; } } @@ -200,7 +222,84 @@ class SP_LDAP { } } } - + return $res; } -} \ No newline at end of file + + /** + * @brief Realizar una búsqueda de objetos en la ruta indicada + * @return int con el número de resultados + */ + private static function searchBase() { + $message['action'] = __FUNCTION__; + + $groupDN = self::searchGroupDN(); + $filter = '(&(memberOf=' . $groupDN . ')(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject)))'; + $filterAttr = array("dn"); + + $searchRes = @ldap_search(self::$ldapConn, self::$searchBase, $filter, $filterAttr); + + if (!$searchRes) { + $message['text'][] = _('Error al buscar objetos en DN base'); + $message['text'][] = 'LDAP ERROR: ' . ldap_error(self::$ldapConn) . '(' . ldap_errno(self::$ldapConn) . ')'; + $message['text'][] = 'LDAP FILTER: ' . $filter; + + SP_Common::wrLogInfo($message); + + throw new Exception(_('Error al buscar objetos en DN base')); + } + + return @ldap_count_entries(self::$ldapConn, $searchRes); + } + + /** + * @brief Obtener el RDN del grupo + * @return string con el RDN del grupo + */ + private static function searchGroupDN() { + $message['action'] = __FUNCTION__; + + $filter = '(cn=' . self::$ldapGroup . ')'; + $filterAttr = array("dn"); + + $searchRes = @ldap_search(self::$ldapConn, self::$searchBase, $filter, $filterAttr); + + if (!$searchRes) { + $message['text'][] = _('Error al buscar RDN de grupo'); + $message['text'][] = 'LDAP ERROR: ' . ldap_error(self::$ldapConn) . '(' . ldap_errno(self::$ldapConn) . ')'; + $message['text'][] = 'LDAP FILTER: ' . $filter; + + SP_Common::wrLogInfo($message); + + throw new Exception(_('Error al buscar RDN de grupo')); + } + + if (@ldap_count_entries(self::$ldapConn, $searchRes) === 1) { + $ldapSearchData = @ldap_get_entries(self::$ldapConn, $searchRes); + + if (!$ldapSearchData) { + $message['text'][] = _('Error al buscar RDN de grupo'); + $message['text'][] = 'LDAP ERROR: ' . ldap_error(self::$ldapConn) . '(' . ldap_errno(self::$ldapConn) . ')'; + + SP_Common::wrLogInfo($message); + + throw new Exception(_('Error al buscar RDN de grupo')); + } + + $message['text'][] = _('RDN de grupo encontrado'); + $message['text'][] = 'RDN: ' . $ldapSearchData[0]["dn"]; + + SP_Common::wrLogInfo($message); + + return $ldapSearchData[0]["dn"]; + } else { + $message['text'][] = _('Error al buscar RDN de grupo'); + $message['text'][] = 'LDAP FILTER: ' . $filter; + + SP_Common::wrLogInfo($message); + + throw new Exception(_('Error al buscar RDN de grupo')); + } + } + +} diff --git a/inc/locales/en_US/LC_MESSAGES/messages.mo b/inc/locales/en_US/LC_MESSAGES/messages.mo index 62f08220..661df5f9 100644 Binary files a/inc/locales/en_US/LC_MESSAGES/messages.mo and b/inc/locales/en_US/LC_MESSAGES/messages.mo differ diff --git a/inc/tpl/config.php b/inc/tpl/config.php index 4a71c193..bc78302c 100644 --- a/inc/tpl/config.php +++ b/inc/tpl/config.php @@ -293,6 +293,14 @@ $allowedExts = SP_Config::getValue('allowed_exts'); + + + + + + + + diff --git a/js/functions.js b/js/functions.js index 9ac1859f..3b4e6759 100644 --- a/js/functions.js +++ b/js/functions.js @@ -1004,4 +1004,50 @@ function resMsg(type, txt, url, action){ $.fancybox(html,{afterLoad: function(){ $('.fancybox-skin,.fancybox-outer,.fancybox-inner').css({'border-radius':'25px','-moz-border-radius':'25px','-webkit-border-radius':'25px'}); },afterClose : function() { if ( typeof(action) !== "undefined" ) eval(action);} }); +} + +// Función para comprobar la conexión con LDAP +function checkLdapConn(){ + var ldapServer = $('#frmConfig [name=ldapserver]').val(); + var ldapBase = $('#frmConfig [name=ldapbase]').val(); + var ldapGroup = $('#frmConfig [name=ldapgroup]').val(); + var ldapBindUser = $('#frmConfig [name=ldapbinduser]').val(); + var ldapBindPass = $('#frmConfig [name=ldapbindpass]').val(); + var sk = $('#frmConfig [name=sk]').val(); + + $.fancybox.showLoading(); + + $.ajax({ + type: 'POST', + dataType: 'json', + url: APP_ROOT + '/ajax/ajax_checkLdap.php', + data: {'ldapserver' : ldapServer, 'ldapbase' : ldapBase, 'ldapgroup' : ldapGroup, 'ldapbinduser' : ldapBindUser, 'ldapbindpass' : ldapBindPass, 'is_ajax' : 1, 'sk' : sk}, + success: function(json){ + var status = json.status; + var description = json.description; + + description = description.replace(/;;/g,"
"); + + switch(status){ + case 0: + $.fancybox.close(); + resMsg("ok", description); + break; + case 1: + $.fancybox.close(); + resMsg("error", description); + break; + case 10: + doLogout(); + break; + default: + return; + } + }, + error:function(jqXHR, textStatus, errorThrown){ + var txt = LANG[1] + '

' + errorThrown + textStatus + '

'; + resMsg("error", txt); + }, + complete: function(){$.fancybox.hideLoading();} + }); } \ No newline at end of file