From f2e92a1077b7b922e3911c932a754451d45a16ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Legastelois?= Date: Thu, 9 Sep 2021 09:56:56 +0200 Subject: [PATCH] First try on known LDAP server(s) to speed-up login --- inc/authldap.class.php | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/inc/authldap.class.php b/inc/authldap.class.php index b5f57c37841..e375cbc5efe 100644 --- a/inc/authldap.class.php +++ b/inc/authldap.class.php @@ -2844,12 +2844,41 @@ static function ldapAuth($auth, $login, $password, $ldap_method, $user_dn) { * @return object identification object */ static function tryLdapAuth($auth, $login, $password, $auths_id = 0, $user_dn = false, $break = true) { + global $DB; //If no specific source is given, test all ldap directories if ($auths_id <= 0) { $user_found = false; - foreach ($auth->authtypes["ldap"] as $ldap_method) { + $ldap_methods = $auth->authtypes["ldap"]; + + // Sort servers to first try on known servers for given login. + // It is necessary to still necessary to try to connect on all servers to handle following cases: + // - there are multiple users having same login on different LDAP servers, + // - a user has been migrated from a LDAP server to another one, but GLPI is not yet aware of this. + // Caveat: if user uses a wrong password, a login attempt will still be done on all active LDAP servers. + $known_servers = $DB->request( + [ + 'SELECT' => 'auths_id', + 'FROM' => User::getTable(), + 'WHERE' => ['name' => addslashes($login)], + ] + ); + $known_servers_id = array_column(iterator_to_array($known_servers), 'auths_id'); + usort( + $ldap_methods, + function (array $a, array $b) use ($known_servers_id) { + if (in_array($a['id'], $known_servers_id) && !in_array($b['id'], $known_servers_id)) { + return -1; + } + if (!in_array($a['id'], $known_servers_id) && in_array($b['id'], $known_servers_id)) { + return 1; + } + return $a['id'] <=> $b['id']; + } + ); + + foreach ($ldap_methods as $ldap_method) { if ($ldap_method['is_active']) { $auth = self::ldapAuth($auth, $login, $password, $ldap_method, $user_dn);