diff options
author | Arthur Schiwon <blizzz@owncloud.com> | 2012-08-23 18:29:43 +0200 |
---|---|---|
committer | Arthur Schiwon <blizzz@owncloud.com> | 2012-08-23 18:29:43 +0200 |
commit | d5c111a984278a097025d267f3461c01983ca0c2 (patch) | |
tree | 95d9f8f5cbdb92b4cf731bb60d114da18f592408 /apps/user_ldap/lib | |
parent | c90c358f0d315c8cf755ec670b7d7738ab15148a (diff) | |
download | nextcloud-server-d5c111a984278a097025d267f3461c01983ca0c2.tar.gz nextcloud-server-d5c111a984278a097025d267f3461c01983ca0c2.zip |
LDAP: identify (map) users with their directory UUID. Fixes the issue, that usernames for owncloud will change, when the DN changes (which happens rarely, but it happens).
Diffstat (limited to 'apps/user_ldap/lib')
-rw-r--r-- | apps/user_ldap/lib/access.php | 81 | ||||
-rw-r--r-- | apps/user_ldap/lib/connection.php | 25 |
2 files changed, 101 insertions, 5 deletions
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index 4e7215525de..be9aa21c3d2 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -50,11 +50,12 @@ abstract class Access { $cr = $this->connection->getConnectionResource(); if(!is_resource($cr)) { //LDAP not available + \OCP\Util::writeLog('user_ldap', 'LDAP resource not available.', \OCP\Util::DEBUG); return false; } $rr = @ldap_read($cr, $dn, 'objectClass=*', array($attr)); if(!is_resource($rr)) { - \OCP\Util::writeLog('user_ldap', 'readAttribute failed for DN '.$dn, \OCP\Util::DEBUG); + \OCP\Util::writeLog('user_ldap', 'readAttribute '.$attr.' failed for DN '.$dn, \OCP\Util::DEBUG); //in case an error occurs , e.g. object does not exist return false; } @@ -70,6 +71,7 @@ abstract class Access { } return $values; } + \OCP\Util::writeLog('user_ldap', 'Requested attribute '.$attr.' not found for '.$dn, \OCP\Util::DEBUG); return false; } @@ -226,11 +228,32 @@ abstract class Access { WHERE ldap_dn = ? '); + //let's try to retrieve the ownCloud name from the mappings table $component = $query->execute(array($dn))->fetchOne(); if($component) { return $component; } + //second try: get the UUID and check if it is known. Then, update the DN and return the name. + $uuid = $this->getUUID($dn); + if($uuid) { + $query = \OCP\DB::prepare(' + SELECT owncloud_name + FROM '.$table.' + WHERE directory_uuid = ? + '); + $component = $query->execute(array($uuid))->fetchOne(); + if($component) { + $query = \OCP\DB::prepare(' + UPDATE '.$table.' + SET ldap_dn = ? + WHERE directory_uuid = ? + '); + $query->execute(array($dn, $uuid)); + return $component; + } + } + if(is_null($ldapname)) { $ldapname = $this->readAttribute($dn, $nameAttribute); if(!isset($ldapname[0]) && empty($ldapname[0])) { @@ -389,17 +412,18 @@ abstract class Access { } $insert = \OCP\DB::prepare(' - INSERT INTO '.$table.' (ldap_dn, owncloud_name) - SELECT ?,? + INSERT INTO '.$table.' (ldap_dn, owncloud_name, directory_uuid) + SELECT ?,?,? '.$sqlAdjustment.' WHERE NOT EXISTS ( SELECT 1 FROM '.$table.' WHERE ldap_dn = ? - OR owncloud_name = ? ) + OR owncloud_name = ?) '); - $res = $insert->execute(array($dn, $ocname, $dn, $ocname)); + //feed the DB + $res = $insert->execute(array($dn, $ocname, $this->getUUID($dn), $dn, $ocname)); if(\OCP\DB::isError($res)) { return false; @@ -602,4 +626,51 @@ abstract class Access { } return $testConnection->bind(); } + + /** + * @brief auto-detects the directory's UUID attribute + * @param $dn a known DN used to check against + * @param $force the detection should be run, even if it is not set to auto + * @returns true on success, false otherwise + */ + private function detectUuidAttribute($dn, $force = false) { + if(($this->connection->ldapUuidAttribute != 'auto') && !$force) { + return true; + } + + //for now, supported (known) attributes are entryUUID, nsuniqueid, objectGUID + $testAttributes = array('entryuuid', 'nsuniqueid', 'objectguid'); + + foreach($testAttributes as $attribute) { + \OCP\Util::writeLog('user_ldap', 'Testing '.$attribute.' as UUID attr', \OCP\Util::DEBUG); + + $value = $this->readAttribute($dn, $attribute); + if(is_array($value) && isset($value[0]) && !empty($value[0])) { + \OCP\Util::writeLog('user_ldap', 'Setting '.$attribute.' as UUID attr', \OCP\Util::DEBUG); + $this->connection->ldapUuidAttribute = $attribute; + return true; + } + \OCP\Util::writeLog('user_ldap', 'The looked for uuid attr is not '.$attribute.', result was '.print_r($value,true), \OCP\Util::DEBUG); + } + + return false; + } + + public function getUUID($dn) { + if($this->detectUuidAttribute($dn)) { + $uuid = $this->readAttribute($dn, $this->connection->ldapUuidAttribute); + if(!is_array($uuid) && $this->connection->ldapOverrideUuidAttribute) { + $this->detectUuidAttribute($dn, true); + $uuid = $this->readAttribute($dn, $this->connection->ldapUuidAttribute); + } + if(is_array($uuid) && isset($uuid[0]) && !empty($uuid[0])) { + $uuid = $uuid[0]; + } else { + $uuid = false; + } + } else { + $uuid = false; + } + return $uuid; + } }
\ No newline at end of file diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index 9bb012e910e..dc160a1642d 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -53,6 +53,8 @@ class Connection { 'ldapQuotaDefault' => null, 'ldapEmailAttribute' => null, 'ldapCacheTTL' => null, + 'ldapUuidAttribute' => null, + 'ldapOverrideUuidAttribute' => null, ); public function __construct($configID = 'user_ldap') { @@ -74,6 +76,22 @@ class Connection { } } + public function __set($name, $value) { + $changed = false; + //omly few options are writable + if($name == 'ldapUuidAttribute') { + \OCP\Util::writeLog('user_ldap', 'Set config ldapUuidAttribute to '.$value, \OCP\Util::DEBUG); + $this->config[$name] = $value; + if(!empty($this->configID)) { + \OCP\Config::getAppValue($this->configID, 'ldap_uuid_attribute', $value); + } + $changed = true; + } + if($changed) { + $this->validateConfiguration(); + } + } + /** * @brief initializes the LDAP backend * @param $force read the config settings no matter what @@ -180,6 +198,8 @@ class Connection { $this->config['ldapGroupMemberAssocAttr'] = \OCP\Config::getAppValue($this->configID, 'ldap_group_member_assoc_attribute', 'uniqueMember'); $this->config['ldapIgnoreNamingRules'] = \OCP\Config::getSystemValue('ldapIgnoreNamingRules', false); $this->config['ldapCacheTTL'] = \OCP\Config::getAppValue($this->configID, 'ldap_cache_ttl', 10*60); + $this->config['ldapUuidAttribute'] = \OCP\Config::getAppValue($this->configID, 'ldap_uuid_attribute', 'auto'); + $this->config['ldapOverrideUuidAttribute'] = \OCP\Config::getAppValue($this->configID, 'ldap_override_uuid_attribute', 0); $this->configured = $this->validateConfiguration(); } @@ -236,6 +256,11 @@ class Connection { if(empty($this->config['ldapGroupFilter']) && empty($this->config['ldapGroupMemberAssocAttr'])) { \OCP\Util::writeLog('user_ldap', 'No group filter is specified, LDAP group feature will not be used.', \OCP\Util::INFO); } + if(!in_array($this->config['ldapUuidAttribute'], array('auto','entryuuid', 'nsuniqueid', 'objectguid'))) { + \OCP\Config::setAppValue($this->configID, 'ldap_uuid_attribute', 'auto'); + \OCP\Util::writeLog('user_ldap', 'Illegal value for the UUID Attribute, reset to autodetect.', \OCP\Util::INFO); + } + //second step: critical checks. If left empty or filled wrong, set as unconfigured and give a warning. $configurationOK = true; |