From 4020d5b77a249e75ae81f5c3646db5692488a812 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 11 Dec 2015 01:56:53 +0100 Subject: [PATCH] look for DN changes before marking a user as deleted --- apps/user_ldap/lib/access.php | 52 +++++++++++++++++++ .../user_ldap/lib/mapping/abstractmapping.php | 12 ++++- apps/user_ldap/user_ldap.php | 15 +++++- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index 667f1076235..3be0b6818d0 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -1276,6 +1276,58 @@ class Access extends LDAPUtility implements user\IUserTools { return $result; } + /** + * reverse lookup of a DN given a known UUID + * + * @param string $uuid + * @return string + * @throws \Exception + */ + public function getUserDnByUuid($uuid) { + $uuidOverride = $this->connection->ldapExpertUUIDUserAttr; + $filter = $this->connection->ldapUserFilter; + $base = $this->connection->ldapBaseUsers; + + if($this->connection->ldapUuidUserAttribute === 'auto' && empty($uuidOverride)) { + // Sacrebleu! The UUID attribute is unknown :( We need first an + // existing DN to be able to reliably detect it. + $result = $this->search($filter, $base, ['dn'], 1); + if(!isset($result[0]) || !isset($result[0]['dn'])) { + throw new \Exception('Cannot determine UUID attribute'); + } + $dn = $result[0]['dn'][0]; + if(!$this->detectUuidAttribute($dn, true)) { + throw new \Exception('Cannot determine UUID attribute'); + } + } else { + // The UUID attribute is either known or an override is given. + // By calling this method we ensure that $this->connection->$uuidAttr + // is definitely set + if(!$this->detectUuidAttribute('', true)) { + throw new \Exception('Cannot determine UUID attribute'); + } + } + + $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]; + } + } + + throw new \Exception('Cannot determine UUID attribute'); + } + /** * auto-detects the directory's UUID attribute * @param string $dn a known DN used to check against diff --git a/apps/user_ldap/lib/mapping/abstractmapping.php b/apps/user_ldap/lib/mapping/abstractmapping.php index f0f0f6df75e..c3d38ce8b71 100644 --- a/apps/user_ldap/lib/mapping/abstractmapping.php +++ b/apps/user_ldap/lib/mapping/abstractmapping.php @@ -158,7 +158,7 @@ abstract class AbstractMapping { } /** - * Gets the name based on the provided LDAP DN. + * Gets the name based on the provided LDAP UUID. * @param string $uuid * @return string|false */ @@ -166,6 +166,16 @@ abstract class AbstractMapping { return $this->getXbyY('owncloud_name', 'directory_uuid', $uuid); } + /** + * Gets the UUID based on the provided LDAP DN + * @param string $dn + * @return false|string + * @throws \Exception + */ + public function getUUIDByDN($dn) { + return $this->getXbyY('directory_uuid', 'ldap_dn', $dn); + } + /** * gets a piece of the mapping list * @param int $offset diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index fc62c168575..a266be7b7f7 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -213,7 +213,18 @@ class USER_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn if(is_null($lcr)) { throw new \Exception('No LDAP Connection to server ' . $this->access->connection->ldapHost); } - return false; + + try { + $uuid = $this->access->getUserMapper()->getUUIDByDN($dn); + if(!$uuid) { + return false; + } + $newDn = $this->access->getUserDnByUuid($uuid); + $this->access->getUserMapper()->setDNbyUUID($newDn, $uuid); + return true; + } catch (\Exception $e) { + return false; + } } if($user instanceof OfflineUser) { @@ -306,7 +317,7 @@ class USER_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn } $user = $this->access->userManager->get($uid); - if(is_null($user) || ($user instanceof OfflineUser && !$this->userExistsOnLDAP($user->getUID()))) { + if(is_null($user) || ($user instanceof OfflineUser && !$this->userExistsOnLDAP($user->getOCName()))) { throw new NoUserException($uid . ' is not a valid user anymore'); } if($user instanceof OfflineUser) { -- 2.39.5