Merge pull request #9385 from owncloud/fix-7052

support for AD primary groups
This commit is contained in:
blizzz 2014-07-08 21:33:50 +02:00
commit 51ee4fc5df
8 changed files with 516 additions and 44 deletions

View File

@ -50,20 +50,29 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
if(!$this->enabled) {
return false;
}
if($this->access->connection->isCached('inGroup'.$uid.':'.$gid)) {
return $this->access->connection->getFromCache('inGroup'.$uid.':'.$gid);
$cacheKey = 'inGroup'.$uid.':'.$gid;
if($this->access->connection->isCached($cacheKey)) {
return $this->access->connection->getFromCache($cacheKey);
}
$dn_user = $this->access->username2dn($uid);
$dn_group = $this->access->groupname2dn($gid);
$userDN = $this->access->username2dn($uid);
$groupDN = $this->access->groupname2dn($gid);
// just in case
if(!$dn_group || !$dn_user) {
$this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, false);
if(!$groupDN || !$userDN) {
$this->access->connection->writeToCache($cacheKey, false);
return false;
}
//check primary group first
if($gid === $this->getUserPrimaryGroup($userDN)) {
$this->access->connection->writeToCache($cacheKey, true);
return true;
}
//usually, LDAP attributes are said to be case insensitive. But there are exceptions of course.
$members = array_keys($this->_groupMembers($dn_group));
$members = array_keys($this->_groupMembers($groupDN));
if(!$members) {
$this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, false);
$this->access->connection->writeToCache($cacheKey, false);
return false;
}
@ -82,8 +91,8 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
$members = $dns;
}
$isInGroup = in_array($dn_user, $members);
$this->access->connection->writeToCache('inGroup'.$uid.':'.$gid, $isInGroup);
$isInGroup = in_array($userDN, $members);
$this->access->connection->writeToCache($cacheKey, $isInGroup);
return $isInGroup;
}
@ -91,6 +100,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
/**
* @param string $dnGroup
* @param array|null &$seen
* @return array|mixed|null
*/
private function _groupMembers($dnGroup, &$seen = null) {
if ($seen === null) {
@ -125,6 +135,125 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
return $allMembers;
}
/**
* translates a primary group ID into an ownCloud internal name
* @param string $gid as given by primaryGroupID on AD
* @param string $dn a DN that belongs to the same domain as the group
* @return string|bool
*/
public function primaryGroupID2Name($gid, $dn) {
$cacheKey = 'primaryGroupIDtoName';
if($this->access->connection->isCached($cacheKey)) {
$groupNames = $this->access->connection->getFromCache($cacheKey);
if(isset($groupNames[$gid])) {
return $groupNames[$gid];
}
}
$domainObjectSid = $this->access->getSID($dn);
if($domainObjectSid === false) {
return false;
}
//we need to get the DN from LDAP
$filter = $this->access->combineFilterWithAnd(array(
$this->access->connection->ldapGroupFilter,
'objectsid=' . $domainObjectSid . '-' . $gid
));
$result = $this->access->searchGroups($filter, array('dn'), 1);
if(empty($result)) {
return false;
}
$dn = $result[0];
//and now the group name
//NOTE once we have separate ownCloud group IDs and group names we can
//directly read the display name attribute instead of the DN
$name = $this->access->dn2groupname($dn);
$this->access->connection->writeToCache($cacheKey, $name);
return $name;
}
/**
* returns the entry's primary group ID
* @param string $dn
* @param string $attribute
* @return string|bool
*/
private function getEntryGroupID($dn, $attribute) {
$value = $this->access->readAttribute($dn, $attribute);
if(is_array($value) && !empty($value)) {
return $value[0];
}
return false;
}
/**
* returns the group's primary ID
* @param string $dn
* @return string|bool
*/
public function getGroupPrimaryGroupID($dn) {
return $this->getEntryGroupID($dn, 'primaryGroupToken');
}
/**
* returns the user's primary group ID
* @param string $dn
* @return string|bool
*/
public function getUserPrimaryGroupIDs($dn) {
return $this->getEntryGroupID($dn, 'primaryGroupID');
}
/**
* returns a list of users that have the given group as primary group
*
* @param string $groupDN
* @param $limit
* @param int $offset
* @return string[]
*/
public function getUsersInPrimaryGroup($groupDN, $limit = -1, $offset = 0) {
$groupID = $this->getGroupPrimaryGroupID($groupDN);
if($groupID === false) {
return array();
}
$filter = $this->access->combineFilterWithAnd(array(
$this->access->connection->ldapUserFilter,
'primaryGroupID=' . $groupID
));
$users = $this->access->fetchListOfUsers(
$filter,
array($this->access->connection->ldapUserDisplayName, 'dn'),
$limit,
$offset
);
return $users;
}
/**
* gets the primary group of a user
* @param string $dn
* @return string
*/
public function getUserPrimaryGroup($dn) {
$groupID = $this->getUserPrimaryGroupIDs($dn);
if($groupID !== false) {
$groupName = $this->primaryGroupID2Name($groupID, $dn);
if($groupName !== false) {
return $groupName;
}
}
return false;
}
/**
* Get all groups a user belongs to
* @param string $uid Name of the user
@ -161,7 +290,14 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
}
$groups = array_values($this->getGroupsByMember($uid));
$groups = array_unique($this->access->ownCloudGroupNames($groups), SORT_LOCALE_STRING);
$groups = $this->access->ownCloudGroupNames($groups);
$primaryGroup = $this->getUserPrimaryGroup($userDN);
if($primaryGroup !== false) {
$groups[] = $primaryGroup;
}
$groups = array_unique($groups, SORT_LOCALE_STRING);
$this->access->connection->writeToCache($cacheKey, $groups);
return $groups;
@ -170,6 +306,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
/**
* @param string $dn
* @param array|null &$seen
* @return array
*/
private function getGroupsByMember($dn, &$seen = null) {
if ($seen === null) {
@ -205,6 +342,11 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
/**
* get a list of all users in a group
*
* @param string $gid
* @param string $search
* @param int $limit
* @param int $offset
* @return array with user ids
*/
public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) {
@ -214,9 +356,9 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
if(!$this->groupExists($gid)) {
return array();
}
$cachekey = 'usersInGroup-'.$gid.'-'.$search.'-'.$limit.'-'.$offset;
$cacheKey = 'usersInGroup-'.$gid.'-'.$search.'-'.$limit.'-'.$offset;
// check for cache of the exact query
$groupUsers = $this->access->connection->getFromCache($cachekey);
$groupUsers = $this->access->connection->getFromCache($cacheKey);
if(!is_null($groupUsers)) {
return $groupUsers;
}
@ -225,7 +367,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
$groupUsers = $this->access->connection->getFromCache('usersInGroup-'.$gid.'-'.$search);
if(!is_null($groupUsers)) {
$groupUsers = array_slice($groupUsers, $offset, $limit);
$this->access->connection->writeToCache($cachekey, $groupUsers);
$this->access->connection->writeToCache($cacheKey, $groupUsers);
return $groupUsers;
}
@ -235,14 +377,14 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
$groupDN = $this->access->groupname2dn($gid);
if(!$groupDN) {
// group couldn't be found, return empty resultset
$this->access->connection->writeToCache($cachekey, array());
$this->access->connection->writeToCache($cacheKey, array());
return array();
}
$members = array_keys($this->_groupMembers($groupDN));
if(!$members) {
//in case users could not be retrieved, return empty resultset
$this->access->connection->writeToCache($cachekey, array());
//in case users could not be retrieved, return empty result set
$this->access->connection->writeToCache($cacheKey, array());
return array();
}
@ -250,7 +392,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
$isMemberUid = (strtolower($this->access->connection->ldapGroupMemberAssocAttr) === 'memberuid');
foreach($members as $member) {
if($isMemberUid) {
//we got uids, need to get their DNs to 'tranlsate' them to usernames
//we got uids, need to get their DNs to 'translate' them to user names
$filter = $this->access->combineFilterWithAnd(array(
\OCP\Util::mb_str_replace('%uid', $member,
$this->access->connection->ldapLoginFilter, 'UTF-8'),
@ -276,10 +418,16 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
}
}
}
natsort($groupUsers);
$this->access->connection->writeToCache('usersInGroup-'.$gid.'-'.$search, $groupUsers);
$groupUsers = array_slice($groupUsers, $offset, $limit);
$this->access->connection->writeToCache($cachekey, $groupUsers);
//and get users that have the group as primary
$primaryUsers = $this->getUsersInPrimaryGroup($groupDN, $limit, $offset);
$groupUsers = array_unique(array_merge($groupUsers, $primaryUsers));
$this->access->connection->writeToCache($cacheKey, $groupUsers);
return $groupUsers;
}
@ -291,32 +439,32 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
* @return int|bool
*/
public function countUsersInGroup($gid, $search = '') {
$cachekey = 'countUsersInGroup-'.$gid.'-'.$search;
$cacheKey = 'countUsersInGroup-'.$gid.'-'.$search;
if(!$this->enabled || !$this->groupExists($gid)) {
return false;
}
$groupUsers = $this->access->connection->getFromCache($cachekey);
$groupUsers = $this->access->connection->getFromCache($cacheKey);
if(!is_null($groupUsers)) {
return $groupUsers;
}
$groupDN = $this->access->groupname2dn($gid);
if(!$groupDN) {
// group couldn't be found, return empty resultset
$this->access->connection->writeToCache($cachekey, false);
// group couldn't be found, return empty result set
$this->access->connection->writeToCache($cacheKey, false);
return false;
}
$members = array_keys($this->_groupMembers($groupDN));
if(!$members) {
//in case users could not be retrieved, return empty resultset
$this->access->connection->writeToCache($cachekey, false);
//in case users could not be retrieved, return empty result set
$this->access->connection->writeToCache($cacheKey, false);
return false;
}
if(empty($search)) {
$groupUsers = count($members);
$this->access->connection->writeToCache($cachekey, $groupUsers);
$this->access->connection->writeToCache($cacheKey, $groupUsers);
return $groupUsers;
}
$isMemberUid =
@ -334,7 +482,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
$groupUsers = array();
foreach($members as $member) {
if($isMemberUid) {
//we got uids, need to get their DNs to 'tranlsate' them to usernames
//we got uids, need to get their DNs to 'translate' them to user names
$filter = $this->access->combineFilterWithAnd(array(
\OCP\Util::mb_str_replace('%uid', $member,
$this->access->connection->ldapLoginFilter, 'UTF-8'),
@ -359,11 +507,19 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
}
}
//and get users that have the group as primary
$primaryUsers = $this->getUsersInPrimaryGroup($groupDN);
$groupUsers = array_unique(array_merge($groupUsers, $primaryUsers));
return count($groupUsers);
}
/**
* get a list of all groups
*
* @param string $search
* @param $limit
* @param int $offset
* @return array with group names
*
* Returns a list with all groups (used by getGroups)
@ -372,11 +528,11 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
if(!$this->enabled) {
return array();
}
$cachekey = 'getGroups-'.$search.'-'.$limit.'-'.$offset;
$cacheKey = 'getGroups-'.$search.'-'.$limit.'-'.$offset;
//Check cache before driving unnecessary searches
\OCP\Util::writeLog('user_ldap', 'getGroups '.$cachekey, \OCP\Util::DEBUG);
$ldap_groups = $this->access->connection->getFromCache($cachekey);
\OCP\Util::writeLog('user_ldap', 'getGroups '.$cacheKey, \OCP\Util::DEBUG);
$ldap_groups = $this->access->connection->getFromCache($cacheKey);
if(!is_null($ldap_groups)) {
return $ldap_groups;
}
@ -397,26 +553,30 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
$offset);
$ldap_groups = $this->access->ownCloudGroupNames($ldap_groups);
$this->access->connection->writeToCache($cachekey, $ldap_groups);
$this->access->connection->writeToCache($cacheKey, $ldap_groups);
return $ldap_groups;
}
/**
* get a list of all groups using a paged search
*
* @param string $search
* @param int $limit
* @param int $offset
* @return array with group names
*
* Returns a list with all groups
* Uses a paged search if available to override a
* server side search limit.
* (active directory has a limit of 1000 by default)
* Uses a paged search if available to override a
* server side search limit.
* (active directory has a limit of 1000 by default)
*/
public function getGroups($search = '', $limit = -1, $offset = 0) {
if(!$this->enabled) {
return array();
}
$pagingsize = $this->access->connection->ldapPagingSize;
$pagingSize = $this->access->connection->ldapPagingSize;
if ((! $this->access->connection->hasPagedResultSupport)
|| empty($pagingsize)) {
|| empty($pagingSize)) {
return $this->getGroupsChunk($search, $limit, $offset);
}
$maxGroups = 100000; // limit max results (just for safety reasons)
@ -428,7 +588,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
$chunkOffset = $offset;
$allGroups = array();
while ($chunkOffset < $overallLimit) {
$chunkLimit = min($pagingsize, $overallLimit - $chunkOffset);
$chunkLimit = min($pagingSize, $overallLimit - $chunkOffset);
$ldapGroups = $this->getGroupsChunk($search, $chunkLimit, $chunkOffset);
$nread = count($ldapGroups);
\OCP\Util::writeLog('user_ldap', 'getGroups('.$search.'): read '.$nread.' at offset '.$chunkOffset.' (limit: '.$chunkLimit.')', \OCP\Util::DEBUG);
@ -445,6 +605,7 @@ class GROUP_LDAP extends BackendUtility implements \OCP\GroupInterface {
/**
* @param string $group
* @return bool
*/
public function groupMatchesFilter($group) {
return (strripos($group, $this->groupSearch) !== false);

View File

@ -28,6 +28,9 @@ namespace OCA\user_ldap\lib;
* @package OCA\user_ldap\lib
*/
class Access extends LDAPUtility implements user\IUserTools {
/**
* @var \OCA\user_ldap\lib\Connection
*/
public $connection;
public $userManager;
//never ever check this var directly, always use getPagedSearchResultState
@ -61,8 +64,8 @@ class Access extends LDAPUtility implements user\IUserTools {
/**
* reads a given attribute for an LDAP record identified by a DN
* @param $dn the record in question
* @param $attr the attribute that shall be retrieved
* @param string $dn the record in question
* @param string $attr the attribute that shall be retrieved
* if empty, just check the record's existence
* @param string $filter
* @return array|false an array of values on success or an empty
@ -180,6 +183,33 @@ class Access extends LDAPUtility implements user\IUserTools {
return $dn;
}
/**
* returns a DN-string that is cleaned from not domain parts, e.g.
* cn=foo,cn=bar,dc=foobar,dc=server,dc=org
* becomes dc=foobar,dc=server,dc=org
* @param string $dn
* @return string
*/
public function getDomainDNFromDN($dn) {
$allParts = $this->ldap->explodeDN($dn, 0);
if($allParts === false) {
//not a valid DN
return '';
}
$domainParts = array();
$dcFound = false;
foreach($allParts as $part) {
if(!$dcFound && strpos($part, 'dc=') === 0) {
$dcFound = true;
}
if($dcFound) {
$domainParts[] = $part;
}
}
$domainDN = implode(',', $domainParts);
return $domainDN;
}
/**
* gives back the database table for the query
* @param bool $isUser
@ -534,7 +564,7 @@ class Access extends LDAPUtility implements user\IUserTools {
if(!\OC_Group::groupExists($altName)) {
return $altName;
}
$altName = $name . '_' . $lastNo + $attempts;
$altName = $name . '_' . ($lastNo + $attempts);
$attempts++;
}
return false;
@ -581,6 +611,7 @@ class Access extends LDAPUtility implements user\IUserTools {
/**
* @param boolean $isUsers
* @return array
*/
private function mappedComponents($isUsers) {
$table = $this->getMapTable($isUsers);
@ -834,7 +865,7 @@ class Access extends LDAPUtility implements user\IUserTools {
private function count($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) {
\OCP\Util::writeLog('user_ldap', 'Count filter: '.print_r($filter, true), \OCP\Util::DEBUG);
if(is_null($limit)) {
if(is_null($limit) || $limit <= 0) {
$limit = intval($this->connection->ldapPagingSize);
}
@ -894,6 +925,10 @@ class Access extends LDAPUtility implements user\IUserTools {
* @return array with the search result
*/
private function search($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) {
if($limit <= 0) {
//otherwise search will fail
$limit = null;
}
$search = $this->executeSearch($filter, $base, $attr, $limit, $offset);
if($search === false) {
return array();
@ -908,7 +943,7 @@ class Access extends LDAPUtility implements user\IUserTools {
$this->processPagedSearchStatus($sr, $filter, $base, 1, $limit,
$offset, $pagedSearchOK,
$skipHandling);
return;
return array();
}
// Do the server-side sorting
@ -1232,6 +1267,55 @@ class Access extends LDAPUtility implements user\IUserTools {
return strtoupper($hex_guid_to_guid_str);
}
/**
* gets a SID of the domain of the given dn
* @param string $dn
* @return string|bool
*/
public function getSID($dn) {
$domainDN = $this->getDomainDNFromDN($dn);
$cacheKey = 'getSID-'.$domainDN;
if($this->connection->isCached($cacheKey)) {
return $this->connection->getFromCache($cacheKey);
}
$objectSid = $this->readAttribute($domainDN, 'objectsid');
if(!is_array($objectSid) || empty($objectSid)) {
$this->connection->writeToCache($cacheKey, false);
return false;
}
$domainObjectSid = $this->convertSID2Str($objectSid[0]);
$this->connection->writeToCache($cacheKey, $domainObjectSid);
return $domainObjectSid;
}
/**
* converts a binary SID into a string representation
* @param string $sid
* @return string
* @link http://blogs.freebsdish.org/tmclaugh/2010/07/21/finding-a-users-primary-group-in-ad/#comment-2855
*/
public function convertSID2Str($sid) {
try {
$srl = ord($sid[0]);
$numberSubID = ord($sid[1]);
$x = substr($sid, 2, 6);
$h = unpack('N', "\x0\x0" . substr($x,0,2));
$l = unpack('N', substr($x,2,6));
$iav = bcadd(bcmul($h[1], bcpow(2,32)), $l[1]);
$subIDs = array();
for ($i=0; $i<$numberSubID; $i++) {
$subID = unpack('V', substr($sid, 8+4*$i, 4));
$subIDs[] = $subID[1];
}
} catch (\Exception $e) {
return '';
}
return sprintf('S-%d-%d-%s', $srl, $iav, implode('-', $subIDs));
}
/**
* converts a stored DN so it can be used as base parameter for LDAP queries, internally we store them for usage in LDAP filters
* @param string $dn the DN

View File

@ -23,6 +23,13 @@
namespace OCA\user_ldap\lib;
//magic properties (incomplete)
/**
* responsible for LDAP connections in context with the provided configuration
* @property string ldapUserFilter
* @property string ldapUserDisplayName
* @property boolean hasPagedResultSupport
*/
class Connection extends LDAPUtility {
private $ldapConnectionRes = null;
private $configPrefix;

View File

@ -89,6 +89,15 @@ interface ILDAPWrapper {
*/
public function error($link);
/**
* Splits DN into its component parts
* @param string $dn
* @param int @withAttrib
* @return array|false
* @link http://www.php.net/manual/en/function.ldap-explode-dn.php
*/
public function explodeDN($dn, $withAttrib);
/**
* Return first result id
* @param resource $link LDAP link resource

View File

@ -98,6 +98,17 @@ class LDAP implements ILDAPWrapper {
return $this->invokeLDAPMethod('error', $link);
}
/**
* Splits DN into its component parts
* @param string $dn
* @param int @withAttrib
* @return array|false
* @link http://www.php.net/manual/en/function.ldap-explode-dn.php
*/
public function explodeDN($dn, $withAttrib) {
return $this->invokeLDAPMethod('ldap_explode_dn', $dn, $withAttrib);
}
/**
* @param LDAP $link
* @param LDAP $result

View File

@ -77,4 +77,54 @@ class Test_Access extends \PHPUnit_Framework_TestCase {
$expected = 'foo\\\\*bar';
$this->assertTrue($expected === $access->escapeFilterPart($input));
}
}
public function testConvertSID2StrSuccess() {
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
$access = new Access($con, $lw, $um);
$sidBinary = file_get_contents(__DIR__ . '/data/sid.dat');
$sidExpected = 'S-1-5-21-249921958-728525901-1594176202';
$this->assertSame($sidExpected, $access->convertSID2Str($sidBinary));
}
public function testConvertSID2StrInputError() {
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
$access = new Access($con, $lw, $um);
$sidIllegal = 'foobar';
$sidExpected = '';
$this->assertSame($sidExpected, $access->convertSID2Str($sidIllegal));
}
public function testGetDomainDNFromDNSuccess() {
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
$access = new Access($con, $lw, $um);
$inputDN = 'uid=zaphod,cn=foobar,dc=my,dc=server,dc=com';
$domainDN = 'dc=my,dc=server,dc=com';
$lw->expects($this->once())
->method('explodeDN')
->with($inputDN, 0)
->will($this->returnValue(explode(',', $inputDN)));
$this->assertSame($domainDN, $access->getDomainDNFromDN($inputDN));
}
public function testGetDomainDNFromDNError() {
list($lw, $con, $um) = $this->getConnecterAndLdapMock();
$access = new Access($con, $lw, $um);
$inputDN = 'foobar';
$expected = '';
$lw->expects($this->once())
->method('explodeDN')
->with($inputDN, 0)
->will($this->returnValue(false));
$this->assertSame($expected, $access->getDomainDNFromDN($inputDN));
}
}

Binary file not shown.

View File

@ -95,6 +95,10 @@ class Test_Group_Ldap extends \PHPUnit_Framework_TestCase {
->method('groupname2dn')
->will($this->returnValue('cn=group,dc=foo,dc=bar'));
$access->expects($this->any())
->method('fetchListOfUsers')
->will($this->returnValue(array()));
$access->expects($this->any())
->method('readAttribute')
->will($this->returnCallback(function($name) {
@ -111,7 +115,9 @@ class Test_Group_Ldap extends \PHPUnit_Framework_TestCase {
$access->expects($this->any())
->method('dn2username')
->will($this->returnValue('foobar'));
->will($this->returnCallback(function() {
return 'foobar' . \OCP\Util::generateRandomBytes(7);
}));
$groupBackend = new GroupLDAP($access);
$users = $groupBackend->countUsersInGroup('group', '3');
@ -119,4 +125,148 @@ class Test_Group_Ldap extends \PHPUnit_Framework_TestCase {
$this->assertSame(2, $users);
}
public function testPrimaryGroupID2NameSuccess() {
$access = $this->getAccessMock();
$this->enableGroups($access);
$userDN = 'cn=alice,cn=foo,dc=barfoo,dc=bar';
$access->expects($this->once())
->method('getSID')
->with($userDN)
->will($this->returnValue('S-1-5-21-249921958-728525901-1594176202'));
$access->expects($this->once())
->method('searchGroups')
->will($this->returnValue(array('cn=foo,dc=barfoo,dc=bar')));
$access->expects($this->once())
->method('dn2groupname')
->with('cn=foo,dc=barfoo,dc=bar')
->will($this->returnValue('MyGroup'));
$groupBackend = new GroupLDAP($access);
$group = $groupBackend->primaryGroupID2Name('3117', $userDN);
$this->assertSame('MyGroup', $group);
}
public function testPrimaryGroupID2NameNoSID() {
$access = $this->getAccessMock();
$this->enableGroups($access);
$userDN = 'cn=alice,cn=foo,dc=barfoo,dc=bar';
$access->expects($this->once())
->method('getSID')
->with($userDN)
->will($this->returnValue(false));
$access->expects($this->never())
->method('searchGroups');
$access->expects($this->never())
->method('dn2groupname');
$groupBackend = new GroupLDAP($access);
$group = $groupBackend->primaryGroupID2Name('3117', $userDN);
$this->assertSame(false, $group);
}
public function testPrimaryGroupID2NameNoGroup() {
$access = $this->getAccessMock();
$this->enableGroups($access);
$userDN = 'cn=alice,cn=foo,dc=barfoo,dc=bar';
$access->expects($this->once())
->method('getSID')
->with($userDN)
->will($this->returnValue('S-1-5-21-249921958-728525901-1594176202'));
$access->expects($this->once())
->method('searchGroups')
->will($this->returnValue(array()));
$access->expects($this->never())
->method('dn2groupname');
$groupBackend = new GroupLDAP($access);
$group = $groupBackend->primaryGroupID2Name('3117', $userDN);
$this->assertSame(false, $group);
}
public function testPrimaryGroupID2NameNoName() {
$access = $this->getAccessMock();
$this->enableGroups($access);
$userDN = 'cn=alice,cn=foo,dc=barfoo,dc=bar';
$access->expects($this->once())
->method('getSID')
->with($userDN)
->will($this->returnValue('S-1-5-21-249921958-728525901-1594176202'));
$access->expects($this->once())
->method('searchGroups')
->will($this->returnValue(array('cn=foo,dc=barfoo,dc=bar')));
$access->expects($this->once())
->method('dn2groupname')
->will($this->returnValue(false));
$groupBackend = new GroupLDAP($access);
$group = $groupBackend->primaryGroupID2Name('3117', $userDN);
$this->assertSame(false, $group);
}
public function testGetEntryGroupIDValue() {
//tests getEntryGroupID via getGroupPrimaryGroupID
//which is basically identical to getUserPrimaryGroupIDs
$access = $this->getAccessMock();
$this->enableGroups($access);
$dn = 'cn=foobar,cn=foo,dc=barfoo,dc=bar';
$attr = 'primaryGroupToken';
$access->expects($this->once())
->method('readAttribute')
->with($dn, $attr)
->will($this->returnValue(array('3117')));
$groupBackend = new GroupLDAP($access);
$gid = $groupBackend->getGroupPrimaryGroupID($dn);
$this->assertSame('3117', $gid);
}
public function testGetEntryGroupIDNoValue() {
//tests getEntryGroupID via getGroupPrimaryGroupID
//which is basically identical to getUserPrimaryGroupIDs
$access = $this->getAccessMock();
$this->enableGroups($access);
$dn = 'cn=foobar,cn=foo,dc=barfoo,dc=bar';
$attr = 'primaryGroupToken';
$access->expects($this->once())
->method('readAttribute')
->with($dn, $attr)
->will($this->returnValue(false));
$groupBackend = new GroupLDAP($access);
$gid = $groupBackend->getGroupPrimaryGroupID($dn);
$this->assertSame(false, $gid);
}
}