@ -64,39 +64,53 @@ class Wizard extends LDAPUtility {
}
/**
* @return WizardResult
* @throws \Exception
* counts entries in the LDAP directory
* @param string $filter the LDAP search filter
* @param string $type a string being either 'users' or 'groups';
* @return int|bool
*/
public function countGroups() {
if(!$this->checkRequirements(array('ldapHost',
'ldapPort',
'ldapBase',
))) {
return false;
public function countEntries($filter, $type) {
$reqs = array('ldapHost', 'ldapPort', 'ldapBase');
if($type === 'users') {
$reqs[] = 'ldapUserFilter';
}
if(!$this->checkRequirements($reqs)) {
throw new \Exception('Requirements not met', 400);
}
$base = $this->configuration->ldapBase[0];
$ldapAccess = $this->getAccess();
if($type === 'groups') {
$result = $ldapAccess->countGroups($filter);
} else if($type === 'users') {
$result = $ldapAccess->countUsers($filter);
} else {
throw new \Exception('internal error: invald object type', 500);
}
return $result;
}
public function countGroups() {
$filter = $this->configuration->ldapGroupFilter;
\OCP\Util::writeLog('user_ldap', 'Wiz: g filter '. print_r($filter, true), \OCP\Util::DEBUG);
$l = \OC_L10N::get('user_ldap');
if(empty($filter)) {
$output = $l->n('%s group found', '%s groups found', 0, array(0));
$output = self:: $l->n('%s group found', '%s groups found', 0, array(0));
$this->result->addChange('ldap_group_count', $output);
return $this->result;
}
$cr = $this->getConnection();
if(!$cr) {
throw new \Exception('Could not connect to LDAP');
}
$rr = $this->ldap->search($cr, $base, $filter, array('dn'));
if(!$this->ldap->isResource($rr)) {
try {
$groupsTotal = $this->countEntries($filter, 'groups');
} catch (\Exception $e) {
//400 can be ignored, 500 is forwarded
if($e->getCode() === 500) {
throw $e;
}
return false;
}
$entries = $this->ldap->countEntries($cr, $rr);
$entries = ($entries !== false) ? $entries : 0;
$output = $l->n('%s group found', '%s groups found', $entries, $entries);
$groupsTotal = ($groupsTotal !== false) ? $groupsTotal : 0;
$output = self::$l->n('%s group found', '%s groups found', $groupsTotal, $groupsTotal);
$this->result->addChange('ldap_group_count', $output);
return $this->result;
}
@ -105,31 +119,12 @@ class Wizard extends LDAPUtility {
* @throws \Exception
*/
public function countUsers() {
if(!$this->checkRequirements(array('ldapHost',
'ldapPort',
'ldapBase',
'ldapUserFilter',
))) {
return false;
}
$cr = $this->getConnection();
if(!$cr) {
throw new \Exception('Could not connect to LDAP');
}
$base = $this->configuration->ldapBase[0];
$filter = $this->configuration->ldapUserFilter;
$rr = $this->ldap->search($cr, $base, $filter, array('dn'));
if(!$this->ldap->isResource($rr)) {
return false;
}
$entries = $this->ldap->countEntries($cr, $rr);
$entries = ($entries !== false) ? $entries : 0;
$l = \OC_L10N::get('user_ldap');
$output = $l->n('%s user found', '%s users found', $entries, $entries);
$this->result->addChange('ldap_user_count', $output);
$usersTotal = $this->countEntries($filter, 'users');
$usersTotal = ($usersTotal !== false) ? $usersTotal : 0;
$output = self::$l->n('%s user found', '%s users found', $usersTotal, $usersTotal);
$this->result->addChange('ldap_user_count', $output);
return $this->result;
}
@ -273,8 +268,7 @@ class Wizard extends LDAPUtility {
throw new \Exception('Could not connect to LDAP');
}
$obClasses = array('posixGroup', 'group', 'zimbraDistributionList', '*');
$this->determineFeature($obClasses, 'cn', $dbKey, $confKey);
$this->fetchGroups($dbKey, $confKey);
if($testMemberOf) {
$this->configuration->hasMemberOfFilterSupport = $this->testMemberOf();
@ -288,9 +282,48 @@ class Wizard extends LDAPUtility {
}
/**
* @return bool|WizardResult
* @throws \Exception
* fetches all groups from LDAP
* @param string $dbKey
* @param string $confKey
*/
public function fetchGroups($dbKey, $confKey) {
$obclasses = array('posixGroup', 'group', 'zimbraDistributionList', 'groupOfNames');
$ldapAccess = $this->getAccess();
$filterParts = array();
foreach($obclasses as $obclass) {
$filterParts[] = 'objectclass='.$obclass;
}
//we filter for everything
//- that looks like a group and
//- has the group display name set
$filter = $ldapAccess->combineFilterWithOr($filterParts);
$filter = $ldapAccess->combineFilterWithAnd(array($filter, 'cn=*'));
$limit = 400;
$offset = 0;
do {
$result = $ldapAccess->searchGroups($filter, array('cn'), $limit, $offset);
foreach($result as $item) {
$groups[] = $item[0];
}
$offset += $limit;
} while (count($groups) > 0 & & count($groups) % $limit === 0);
if(count($groups) > 0) {
natsort($groups);
$this->result->addOptions($dbKey, array_values($groups));
} else {
throw new \Exception(self::$l->t('Could not find the desired feature'));
}
$setFeatures = $this->configuration->$confKey;
if(is_array($setFeatures) & & !empty($setFeatures)) {
//something is already configured? pre-select it.
$this->result->addChange($dbKey, $setFeatures);
}
}
public function determineGroupMemberAssoc() {
if(!$this->checkRequirements(array('ldapHost',
'ldapPort',
@ -909,15 +942,13 @@ class Wizard extends LDAPUtility {
* specified attribute
* @param string[] $filters array, the filters that shall be used in the search
* @param string $attr the attribute of which a list of values shall be returned
* @param bool $lfw whether the last filter is a wildcard which shall not
* be processed if there were already findings, defaults to true
* @param int $dnReadLimit the amount of how many DNs should be analyzed.
* The lower, the faster
* @param string $maxF string. if not null, this variable will have the filter that
* yields most result entries
* @return array|false an array with the values on success, false otherwise
*/
public function cumulativeSearchOnAttribute($filters, $attr, $lfw = true, $ dnReadLimit = 3, & $maxF = null) {
public function cumulativeSearchOnAttribute($filters, $attr, $dnReadLimit = 3, & $maxF = null) {
$dnRead = array();
$foundItems = array();
$maxEntries = 0;
@ -935,7 +966,7 @@ class Wizard extends LDAPUtility {
$lastFilter = $filters[count($filters)-1];
}
foreach($filters as $filter) {
if($lfw & & $l astFilter === $filter & & count($foundItems) > 0) {
if($lastFilter === $filter & & count($foundItems) > 0) {
//skip when the filter is a wildcard and results were found
continue;
}
@ -1005,16 +1036,11 @@ class Wizard extends LDAPUtility {
//how deep to dig?
//When looking for objectclasses, testing few entries is sufficient,
//when looking for group we need to get all names, though.
if(strtolower($attr) === 'objectclass') {
$dig = 3;
} else {
$dig = 0;
}
$dig = 3;
$availableFeatures =
$this->cumulativeSearchOnAttribute($objectclasses, $attr,
true, $dig, $maxEntryObjC);
$dig, $maxEntryObjC);
if(is_array($availableFeatures)
& & count($availableFeatures) > 0) {
natcasesort($availableFeatures);
@ -1072,6 +1098,19 @@ class Wizard extends LDAPUtility {
}
}
/**
* creates and returns an Access instance
* @return \OCA\user_ldap\lib\Access
*/
private function getAccess() {
$con = new Connection($this->ldap, '', null);
$con->setConfiguration($this->configuration->getConfiguration());
$con->ldapConfigurationActive = true;
$con->setIgnoreValidation(true);
$ldapAccess = new Access($con, $this->ldap);
return $ldapAccess;
}
/**
* @return bool|mixed
*/