Merge pull request #18042 from GreenArchon/master

Properly nest groups when using memberOf to detect group membership, …
This commit is contained in:
Morris Jobke 2015-08-26 11:42:47 +02:00
commit 27af0e82dd
2 changed files with 35 additions and 7 deletions

View File

@ -181,6 +181,36 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
return $allMembers; return $allMembers;
} }
/**
* @param string $DN
* @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;
$groups = $this->access->readAttribute($DN, 'memberOf');
if (!is_array($groups)) {
return array();
}
$groups = $this->access->groupsMatchFilter($groups);
$allGroups = $groups;
$nestedGroups = $this->access->connection->ldapNestedGroups;
if (intval($nestedGroups) === 1) {
foreach ($groups as $group) {
$subGroups = $this->_getGroupDNsFromMemberOf($group, $seen);
$allGroups = array_merge($allGroups, $subGroups);
}
}
return $allGroups;
}
/** /**
* 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,10 +407,8 @@ 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) {
$groupName = $this->access->dn2groupname($dn); $groupName = $this->access->dn2groupname($dn);
if(is_string($groupName)) { if(is_string($groupName)) {
@ -390,6 +418,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
} }
} }
} }
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));