summaryrefslogtreecommitdiffstats
path: root/apps
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
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')
-rw-r--r--apps/user_ldap/appinfo/database.xml16
-rw-r--r--apps/user_ldap/appinfo/update.php42
-rw-r--r--apps/user_ldap/appinfo/version2
-rw-r--r--apps/user_ldap/lib/access.php81
-rw-r--r--apps/user_ldap/lib/connection.php25
5 files changed, 140 insertions, 26 deletions
diff --git a/apps/user_ldap/appinfo/database.xml b/apps/user_ldap/appinfo/database.xml
index 3bbd2b09a49..a785bbf4221 100644
--- a/apps/user_ldap/appinfo/database.xml
+++ b/apps/user_ldap/appinfo/database.xml
@@ -28,6 +28,14 @@
<default></default>
</field>
+ <field>
+ <name>directory_uuid</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>255</length>
+ <default></default>
+ </field>
+
<index>
<name>ldap_dn_users</name>
<unique>true</unique>
@@ -71,6 +79,14 @@
<default></default>
</field>
+ <field>
+ <name>directory_uuid</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>255</length>
+ <default></default>
+ </field>
+
<index>
<name>ldap_dn_groups</name>
<unique>true</unique>
diff --git a/apps/user_ldap/appinfo/update.php b/apps/user_ldap/appinfo/update.php
index badceb378d1..9cf1814cf6f 100644
--- a/apps/user_ldap/appinfo/update.php
+++ b/apps/user_ldap/appinfo/update.php
@@ -2,6 +2,11 @@
//from version 0.1 to 0.2
+//ATTENTION
+//Upgrade from ownCloud 3 (LDAP backend 0.1) to ownCloud 4.5 (LDAP backend 0.3) is not supported!!
+//You must do upgrade to ownCloud 4.0 first!
+//The upgrade stuff in the section from 0.1 to 0.2 is just to minimize the bad efffects.
+
//settings
$pw = OCP\Config::getAppValue('user_ldap', 'ldap_password');
if(!is_null($pw)) {
@@ -12,33 +17,25 @@ if(!is_null($pw)) {
//detect if we can switch on naming guidelines. We won't do it on conflicts.
//it's a bit spaghetti, but hey.
-$state = OCP\Config::getSystemValue('ldapIgnoreNamingRules', 'doCheck');
-if($state == 'doCheck'){
- $sqlCleanMap = 'DELETE FROM *PREFIX*ldap_user_mapping';
-
- OCP\Config::setSystemValue('ldapIgnoreNamingRules', true);
- $LDAP_USER = new OC_USER_LDAP();
- $users_old = $LDAP_USER->getUsers();
- $query = OCP\DB::prepare($sqlCleanMap);
- $query->execute();
+$state = OCP\Config::getSystemValue('ldapIgnoreNamingRules', 'unset');
+if($state == 'unset'){
OCP\Config::setSystemValue('ldapIgnoreNamingRules', false);
- OC_LDAP::init(true);
- $users_new = $LDAP_USER->getUsers();
- $query = OCP\DB::prepare($sqlCleanMap);
- $query->execute();
- if($users_old !== $users_new) {
- //we don't need to check Groups, because they were not supported in 3'
- OCP\Config::setSystemValue('ldapIgnoreNamingRules', true);
- }
}
+// ### SUPPORTED upgrade path starts here ###
-//from version 0.2 to 0.2.1
+//from version 0.2 to 0.3 (0.2.0.x dev version)
$objects = array('user', 'group');
+$connector = new \OCA\user_ldap\lib\Connection('user_ldap');
+$userBE = new \OCA\user_ldap\USER_LDAP();
+$userBE->setConnector($connector);
+$groupBE = new \OCA\user_ldap\GROUP_LDAP();
+$groupBE->setConnector($connector);
+
foreach($objects as $object) {
$fetchDNSql = 'SELECT ldap_dn from *PREFIX*ldap_'.$object.'_mapping';
- $updateSql = 'UPDATE *PREFIX*ldap_'.$object.'_mapping SET ldap_DN = ? WHERE ldap_dn = ?';
+ $updateSql = 'UPDATE *PREFIX*ldap_'.$object.'_mapping SET ldap_DN = ?, directory_uuid = ? WHERE ldap_dn = ?';
$query = OCP\DB::prepare($fetchDNSql);
$res = $query->execute();
@@ -46,6 +43,11 @@ foreach($objects as $object) {
$updateQuery = OCP\DB::prepare($updateSql);
foreach($DNs as $dn) {
$newDN = mb_strtolower($dn['ldap_dn'], 'UTF-8');
- $updateQuery->execute(array($newDN, $dn['ldap_dn']));
+ if($object == 'user') {
+ $uuid = $userBE->getUUID($newDN);
+ } else {
+ $uuid = $groupBE->getUUID($newDN);
+ }
+ $updateQuery->execute(array($newDN, $uuid, $dn['ldap_dn']));
}
}
diff --git a/apps/user_ldap/appinfo/version b/apps/user_ldap/appinfo/version
index 1683a266156..e689e4949ef 100644
--- a/apps/user_ldap/appinfo/version
+++ b/apps/user_ldap/appinfo/version
@@ -1 +1 @@
-0.2.0.8 \ No newline at end of file
+0.2.0.26 \ No newline at end of file
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;