summaryrefslogtreecommitdiffstats
path: root/apps/user_ldap/lib
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@owncloud.com>2012-08-23 18:29:43 +0200
committerArthur Schiwon <blizzz@owncloud.com>2012-08-23 18:29:43 +0200
commitd5c111a984278a097025d267f3461c01983ca0c2 (patch)
tree95d9f8f5cbdb92b4cf731bb60d114da18f592408 /apps/user_ldap/lib
parentc90c358f0d315c8cf755ec670b7d7738ab15148a (diff)
downloadnextcloud-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.php81
-rw-r--r--apps/user_ldap/lib/connection.php25
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;