From: Arthur Schiwon Date: Mon, 7 Oct 2013 23:19:37 +0000 (+0200) Subject: Ldap Wizard: find out whether server supports memberOf in LDAP Filter and disable... X-Git-Tag: v6.0.0beta2~46^2~21 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=162bfb231aa31d7aa8c22543edff8aa9ceade3bd;p=nextcloud-server.git Ldap Wizard: find out whether server supports memberOf in LDAP Filter and disable group chooser if not --- diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js index 8949f5002ca..837b79e329c 100644 --- a/apps/user_ldap/js/settings.js +++ b/apps/user_ldap/js/settings.js @@ -216,9 +216,10 @@ var LdapWizard = { } LdapWizard.applyChanges(result); $('#ldap_userfilter_groups').multiselect('refresh'); + $('#ldap_userfilter_groups').multiselect('enable'); }, function (result) { - //TODO: error handling + $('#ldap_userfilter_groups').multiselect('disable'); } ); }, diff --git a/apps/user_ldap/lib/wizard.php b/apps/user_ldap/lib/wizard.php index 69354c69229..0dbd8c92021 100644 --- a/apps/user_ldap/lib/wizard.php +++ b/apps/user_ldap/lib/wizard.php @@ -25,8 +25,10 @@ namespace OCA\user_ldap\lib; class Wizard extends LDAPUtility { static protected $l; + protected $cr; protected $configuration; protected $result; + protected $resultCache = array(); const LRESULT_PROCESSED_OK = 0; const LRESULT_PROCESSED_INVALID = 1; @@ -71,12 +73,51 @@ class Wizard extends LDAPUtility { } $obclasses = array('posixGroup', 'group', '*'); - return $this->determineFeature($obclasses, - 'cn', - 'ldap_userfilter_groups', - 'ldapUserFilterGroups'); + $groups = $this->determineFeature($obclasses, + 'cn', + 'ldap_userfilter_groups', + 'ldapUserFilterGroups'); - //TODO: Check, whether member-of-overlay is installed on the LDAP Server + $isMemberOfWorking = $this->testMemberOf($groups); + if(!$isMemberOfWorking) { + throw new \Exception('memberOf is not supported by the server'); + } + + return $this->result; + } + + private function testMemberOf($groups) { + $cr = $this->getConnection(); + if(!$cr) { + throw new \Excpetion('Could not connect to LDAP'); + } + if(!is_array($this->configuration->ldapBase) + || !isset($this->configuration->ldapBase[0])) { + return false; + } + $base = $this->configuration->ldapBase[0]; + $filterPrefix = '(&(objectclass=*)(memberOf='; + + foreach($this->resultCache as $dn => $properties) { + if(!isset($properties['cn'])) { + //assuming only groups have their cn cached :) + continue; + } + $filter = strtolower($filterPrefix . $dn.'))'); + $rr = $this->ldap->search($cr, $base, $filter, array('dn')); + if(!$this->ldap->isResource($rr)) { + continue; + } + $entries = $this->ldap->countEntries($cr, $rr); + //we do not know which groups are empty, so test any and return + //success on the first match that returns at least one user + if(($entries !== false) && ($entries > 0)) { + return true; + } + } + + + return false; } /** @@ -89,7 +130,6 @@ class Wizard extends LDAPUtility { 'ldapAgentName', 'ldapAgentPassword', 'ldapBase', - true ))) { return false; } @@ -100,10 +140,13 @@ class Wizard extends LDAPUtility { $obclasses = array('inetOrgPerson', 'person', 'organizationalPerson', 'user', 'posixAccount', '*'); - return $this->determineFeature($obclasses, - 'objectclass', - 'ldap_userfilter_objectclass', - 'ldapUserFilterObjectclass'); + $this->determineFeature($obclasses, + 'objectclass', + 'ldap_userfilter_objectclass', + 'ldapUserFilterObjectclass', + true); + + return $this->result; } /** @@ -375,9 +418,12 @@ class Wizard extends LDAPUtility { if($dn === false || in_array($dn, $dnRead)) { continue; } + $newItems = array(); $state = $this->getAttributeValuesFromEntry($attributes, $attr, - $foundItems); + $newItems); + $foundItems = array_merge($foundItems, $newItems); + $this->resultCache[$dn][$attr] = $newItems; $dnRead[] = $dn; $getEntryFunc = 'nextEntry'; $rr = $entry; //will be expected by nextEntry next round @@ -386,7 +432,7 @@ class Wizard extends LDAPUtility { } } - return $foundItems; + return array_unique($foundItems); } /** @@ -398,7 +444,7 @@ class Wizard extends LDAPUtility { * Configuration class * @param $po boolean, whether the objectClass with most result entries * shall be pre-selected via the result - * @returns the instance's WizardResult instance + * @returns array, list of found items. */ private function determineFeature($objectclasses, $attr, $dbkey, $confkey, $po = false) { $cr = $this->getConnection(); @@ -430,7 +476,7 @@ class Wizard extends LDAPUtility { $this->result->addChange($dbkey, $maxEntryObjC); } - return $this->result; + return $availableFeatures; } /** @@ -457,7 +503,6 @@ class Wizard extends LDAPUtility { continue; } if(!in_array($val, $known)) { - \OCP\Util::writeLog('user_ldap', 'Found objclass '.$val, \OCP\Util::DEBUG); $known[] = $val; } } @@ -468,6 +513,9 @@ class Wizard extends LDAPUtility { } private function getConnection() { + if(!is_null($this->cr)) { + return $cr; + } $cr = $this->ldap->connect( $this->configuration->ldapHost.':'.$this->configuration->ldapPort, $this->configuration->ldapPort); @@ -482,6 +530,7 @@ class Wizard extends LDAPUtility { $this->configuration->ldapAgentName, $this->configuration->ldapAgentPassword); if($lo === true) { + $this->$cr = $cr; return $cr; }