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:
parent
c2d8a36d9a
commit
afb182650e
|
@ -252,28 +252,33 @@ class Group_LDAP extends BackendUtility implements \OCP\GroupInterface, IGroupLD
|
||||||
* @param array|null &$seen
|
* @param array|null &$seen
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function _getGroupDNsFromMemberOf($DN, &$seen = null) {
|
private function _getGroupDNsFromMemberOf($DN) {
|
||||||
if ($seen === null) {
|
|
||||||
$seen = array();
|
|
||||||
}
|
|
||||||
if (array_key_exists($DN, $seen)) {
|
|
||||||
// avoid loops
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
$seen[$DN] = 1;
|
|
||||||
$groups = $this->access->readAttribute($DN, 'memberOf');
|
$groups = $this->access->readAttribute($DN, 'memberOf');
|
||||||
if (!is_array($groups)) {
|
if (!is_array($groups)) {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
$allGroups = $groups;
|
|
||||||
$nestedGroups = $this->access->connection->ldapNestedGroups;
|
$nestedGroups = $this->access->connection->ldapNestedGroups;
|
||||||
if ((int)$nestedGroups === 1) {
|
if ((int)$nestedGroups === 1) {
|
||||||
foreach ($groups as $group) {
|
$seen = array();
|
||||||
$subGroups = $this->_getGroupDNsFromMemberOf($group, $seen);
|
while ($group = array_pop($groups)) {
|
||||||
$allGroups = array_merge($allGroups, $subGroups);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $this->access->groupsMatchFilter($allGroups);
|
}
|
||||||
|
// Get unique group DN's from those we have visited in the loop
|
||||||
|
$groups = array_keys($seen);
|
||||||
|
}
|
||||||
|
return $this->access->groupsMatchFilter($groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue