user_ldap: really resolve nested groups

The previous patch fixed the problem only for one level of indirection
because groupsMatchFilter() had been applied on each recursive call (and
thus there would be no second level if the first level fails the check).

This new implementation replaces the recursive call with a stack that
iterates all nested groups before filtering with groupsMatchFilter().

Signed-off-by: Roland Tapken <roland@bitarbeiter.net>
This commit is contained in:
Roland Tapken 2018-02-07 15:49:40 +01:00 committed by Arthur Schiwon
parent fe169b021d
commit 0997fd999e
No known key found for this signature in database
GPG key ID: 7424F1874854DF23

View file

@ -252,28 +252,33 @@ class Group_LDAP extends BackendUtility implements \OCP\GroupInterface, IGroupLD
* @param array|null &$seen
* @return array
*/
private function _getGroupDNsFromMemberOf($DN, &$seen = null) {
if ($seen === null) {
$seen = array();
}
if (array_key_exists($DN, $seen)) {
// avoid loops
return array();
}
$seen[$DN] = 1;
private function _getGroupDNsFromMemberOf($DN) {
$groups = $this->access->readAttribute($DN, 'memberOf');
if (!is_array($groups)) {
return array();
}
$allGroups = $groups;
$nestedGroups = $this->access->connection->ldapNestedGroups;
if ((int)$nestedGroups === 1) {
foreach ($groups as $group) {
$subGroups = $this->_getGroupDNsFromMemberOf($group, $seen);
$allGroups = array_merge($allGroups, $subGroups);
$seen = array();
while ($group = array_pop($groups)) {
if ($group === $DN || array_key_exists($group, $seen)) {
// Prevent loops
continue;
}
$seen[$group] = 1;
// Resolve nested groups
$nestedGroups = $this->access->readAttribute($group, 'memberOf');
if (is_array($nestedGroups)) {
foreach ($nestedGroups as $nestedGroup) {
array_push($groups, $nestedGroup);
}
}
}
// Get unique group DN's from those we have visited in the loop
$groups = array_keys($seen);
}
return $this->access->groupsMatchFilter($allGroups);
return $this->access->groupsMatchFilter($groups);
}
/**