From e39415c946338c3093257a21d09a7360e0c9ffd4 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Mon, 14 Dec 2015 22:42:27 +0100 Subject: [PATCH] fix find DN by UUID for AD --- apps/user_ldap/lib/access.php | 69 ++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index 3be0b6818d0..693a420a74d 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -1310,19 +1310,15 @@ class Access extends LDAPUtility implements user\IUserTools { $uuidAttr = $this->connection->ldapUuidUserAttribute; if($uuidAttr === 'guid' || $uuidAttr === 'objectguid') { - $dn = ''; - $result = $this->readAttribute($dn, 'dn'); - if(is_array($result) && isset($result[0])) { - return $result[0]; - } - } else { - $filter = $uuidAttr . '=' . $uuid; - $result = $this->searchUsers($filter, ['dn'], 2); - if(is_array($result) && isset($result[0]) && isset($result[0]['dn']) && count($result) === 1) { - // we put the count into account to make sure that this is - // really unique - return $result[0]['dn'][0]; - } + $uuid = $this->formatGuid2ForFilterUser($uuid); + } + + $filter = $uuidAttr . '=' . $uuid; + $result = $this->searchUsers($filter, ['dn'], 2); + if(is_array($result) && isset($result[0]) && isset($result[0]['dn']) && count($result) === 1) { + // we put the count into account to make sure that this is + // really unique + return $result[0]['dn'][0]; } throw new \Exception('Cannot determine UUID attribute'); @@ -1430,6 +1426,53 @@ class Access extends LDAPUtility implements user\IUserTools { return strtoupper($hex_guid_to_guid_str); } + /** + * the first three blocks of the string-converted GUID happen to be in + * reverse order. In order to use it in a filter, this needs to be + * corrected. Furthermore the dashes need to be replaced and \\ preprended + * to every two hax figures. + * + * If an invalid string is passed, it will be returned without change. + * + * @param string $guid + * @return string + */ + public function formatGuid2ForFilterUser($guid) { + if(!is_string($guid)) { + throw new \InvalidArgumentException('String expected'); + } + $blocks = explode('-', $guid); + if(count($blocks) !== 5) { + /* + * Why not throw an Exception instead? This method is a utility + * called only when trying to figure out whether a "missing" known + * LDAP user was or was not renamed on the LDAP server. And this + * even on the use case that a reverse lookup is needed (UUID known, + * not DN), i.e. when finding users (search dialog, users page, + * login, …) this will not be fired. This occurs only if shares from + * a users are supposed to be mounted who cannot be found. Throwing + * an exception here would kill the experience for a valid, acting + * user. Instead we write a log message. + */ + \OC::$server->getLogger()->info( + 'Passed string does not resemble a valid GUID. Known UUID ' . + '({uuid}) probably does not match UUID configuration.', + [ 'app' => 'user_ldap', 'uuid' => $guid ] + ); + return $guid; + } + for($i=0; $i < 3; $i++) { + $pairs = str_split($blocks[$i], 2); + $pairs = array_reverse($pairs); + $blocks[$i] = implode('', $pairs); + } + for($i=0; $i < 5; $i++) { + $pairs = str_split($blocks[$i], 2); + $blocks[$i] = '\\' . implode('\\', $pairs); + } + return implode('', $blocks); + } + /** * gets a SID of the domain of the given dn * @param string $dn -- 2.39.5