Properly nest groups when using memberOf to detect group membership, fixes #17759

This commit is contained in:
Frédéric Fortier 2015-08-03 20:15:22 -04:00
parent 11244736ae
commit 7604bcb3cb
2 changed files with 39 additions and 7 deletions

View File

@ -181,6 +181,39 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
return $allMembers; return $allMembers;
} }
/**
* @param string $dnGroup
* @param array &$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;
$groups = $this->access->readAttribute($DN, 'memberOf');
if (is_array($groups)) {
$groups = $this->access->groupsMatchFilter($groups);
$allGroups = $groups;
foreach ($groups as $group) {
$nestedGroups = $this->access->connection->ldapNestedGroups;
if (!empty($nestedGroups)) {
$subGroups = $this->_getGroupDNsFromMemberOf($group, $seen);
if ($subGroups) {
$allGroups = array_merge($allGroups, $subGroups);
}
}
}
return $allGroups;
} else {
return array();
}
}
/** /**
* translates a primary group ID into an ownCloud internal name * translates a primary group ID into an ownCloud internal name
* @param string $gid as given by primaryGroupID on AD * @param string $gid as given by primaryGroupID on AD
@ -377,14 +410,14 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
if(intval($this->access->connection->hasMemberOfFilterSupport) === 1 if(intval($this->access->connection->hasMemberOfFilterSupport) === 1
&& intval($this->access->connection->useMemberOfToDetectMembership) === 1 && intval($this->access->connection->useMemberOfToDetectMembership) === 1
) { ) {
$groupDNs = $this->access->readAttribute($userDN, 'memberOf'); $groupDNs = $this->_getGroupDNsFromMemberOf($userDN);
if (is_array($groupDNs)) { if (is_array($groupDNs)) {
$groupDNs = $this->access->groupsMatchFilter($groupDNs);
foreach ($groupDNs as $dn) { foreach ($groupDNs as $dn) {
$groups[] = $this->access->dn2groupname($dn); $groups[] = $this->access->dn2groupname($dn);
} }
} }
if($primaryGroup !== false) { if($primaryGroup !== false) {
$groups[] = $primaryGroup; $groups[] = $primaryGroup;
} }

View File

@ -395,16 +395,15 @@ class Test_Group_Ldap extends \Test\TestCase {
->method('username2dn') ->method('username2dn')
->will($this->returnValue($dn)); ->will($this->returnValue($dn));
$access->expects($this->once()) $access->expects($this->exactly(3))
->method('readAttribute') ->method('readAttribute')
->with($dn, 'memberOf') ->will($this->onConsecutiveCalls(['cn=groupA,dc=foobar', 'cn=groupB,dc=foobar'], [], []));
->will($this->returnValue(['cn=groupA,dc=foobar', 'cn=groupB,dc=foobar']));
$access->expects($this->exactly(2)) $access->expects($this->exactly(2))
->method('dn2groupname') ->method('dn2groupname')
->will($this->returnArgument(0)); ->will($this->returnArgument(0));
$access->expects($this->once()) $access->expects($this->exactly(3))
->method('groupsMatchFilter') ->method('groupsMatchFilter')
->will($this->returnArgument(0)); ->will($this->returnArgument(0));