Skip to content

Commit 7eb6d8d

Browse files
committed
do not flip available state to unavailable, allow empty results
- the detection relies that the first, requested result is not empty - it might be empty though – groups without members - protect switching from available to unavailable - switching the other way around was also not envisaged either Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
1 parent 7ea262d commit 7eb6d8d

File tree

3 files changed

+41
-13
lines changed

3 files changed

+41
-13
lines changed

apps/user_ldap/lib/Connection.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
* @property string ldapGidNumber
7373
* @property int hasMemberOfFilterSupport
7474
* @property int useMemberOfToDetectMembership
75+
* @property string ldapMatchingRuleInChainState
7576
*/
7677
class Connection extends LDAPUtility {
7778
private $ldapConnectionRes = null;

apps/user_ldap/lib/Group_LDAP.php

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -254,21 +254,27 @@ private function _groupMembers(string $dnGroup, ?array &$seen = null): array {
254254
) {
255255
$attemptedLdapMatchingRuleInChain = true;
256256
// compatibility hack with servers supporting :1.2.840.113556.1.4.1941:, and others)
257-
$filter = $this->access->combineFilterWithAnd([$this->access->connection->ldapUserFilter, 'memberof:1.2.840.113556.1.4.1941:=' . $dnGroup]);
257+
$filter = $this->access->combineFilterWithAnd([
258+
$this->access->connection->ldapUserFilter,
259+
$this->access->connection->ldapUserDisplayName . '=*',
260+
'memberof:1.2.840.113556.1.4.1941:=' . $dnGroup
261+
]);
258262
$memberRecords = $this->access->fetchListOfUsers(
259263
$filter,
260264
$this->access->userManager->getAttributes(true)
261265
);
262-
if (!empty($memberRecords)) {
263-
if ($this->access->connection->ldapMatchingRuleInChainState === Configuration::LDAP_SERVER_FEATURE_UNKNOWN) {
264-
$this->access->connection->ldapMatchingRuleInChainState = Configuration::LDAP_SERVER_FEATURE_AVAILABLE;
265-
$this->access->connection->saveConfiguration();
266-
}
267-
return array_reduce($memberRecords, function ($carry, $record) {
268-
$carry[] = $record['dn'][0];
269-
return $carry;
270-
}, []);
266+
$result = array_reduce($memberRecords, function ($carry, $record) {
267+
$carry[] = $record['dn'][0];
268+
return $carry;
269+
}, []);
270+
if ($this->access->connection->ldapMatchingRuleInChainState === Configuration::LDAP_SERVER_FEATURE_AVAILABLE) {
271+
return $result;
272+
} elseif (!empty($memberRecords)) {
273+
$this->access->connection->ldapMatchingRuleInChainState = Configuration::LDAP_SERVER_FEATURE_AVAILABLE;
274+
$this->access->connection->saveConfiguration();
275+
return $result;
271276
}
277+
// when feature availability is unknown, and the result is empty, continue and test with original approach
272278
}
273279

274280
$seen[$dnGroup] = 1;
@@ -283,7 +289,10 @@ private function _groupMembers(string $dnGroup, ?array &$seen = null): array {
283289
$allMembers += $this->getDynamicGroupMembers($dnGroup);
284290

285291
$this->access->connection->writeToCache($cacheKey, $allMembers);
286-
if (isset($attemptedLdapMatchingRuleInChain) && !empty($allMembers)) {
292+
if (isset($attemptedLdapMatchingRuleInChain)
293+
&& $this->access->connection->ldapMatchingRuleInChainState === Configuration::LDAP_SERVER_FEATURE_UNKNOWN
294+
&& !empty($allMembers)
295+
) {
287296
$this->access->connection->ldapMatchingRuleInChainState = Configuration::LDAP_SERVER_FEATURE_UNAVAILABLE;
288297
$this->access->connection->saveConfiguration();
289298
}

apps/user_ldap/tests/Group_LDAPTest.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ public function testCountEmptySearchString() {
129129
->method('countUsers')
130130
->willReturn(2);
131131

132+
$access->userManager->expects($this->any())
133+
->method('getAttributes')
134+
->willReturn(['displayName', 'mail']);
135+
132136
$groupBackend = new GroupLDAP($access, $pluginManager);
133137
$users = $groupBackend->countUsersInGroup('group');
134138

@@ -172,6 +176,10 @@ public function testCountWithSearchString() {
172176
->method('escapeFilterPart')
173177
->willReturnArgument(0);
174178

179+
$access->userManager->expects($this->any())
180+
->method('getAttributes')
181+
->willReturn(['displayName', 'mail']);
182+
175183
$groupBackend = new GroupLDAP($access, $pluginManager);
176184
$users = $groupBackend->countUsersInGroup('group', '3');
177185

@@ -546,7 +554,10 @@ public function testUsersInGroupPrimaryMembersOnly() {
546554
$access->expects($this->any())
547555
->method('combineFilterWithAnd')
548556
->willReturn('pseudo=filter');
549-
$access->userManager = $this->createMock(Manager::class);
557+
558+
$access->userManager->expects($this->any())
559+
->method('getAttributes')
560+
->willReturn(['displayName', 'mail']);
550561

551562
$groupBackend = new GroupLDAP($access, $pluginManager);
552563
$users = $groupBackend->usersInGroup('foobar');
@@ -587,7 +598,10 @@ public function testUsersInGroupPrimaryAndUnixMembers() {
587598
$access->expects($this->any())
588599
->method('combineFilterWithAnd')
589600
->willReturn('pseudo=filter');
590-
$access->userManager = $this->createMock(Manager::class);
601+
602+
$access->userManager->expects($this->any())
603+
->method('getAttributes')
604+
->willReturn(['displayName', 'mail']);
591605

592606
$groupBackend = new GroupLDAP($access, $pluginManager);
593607
$users = $groupBackend->usersInGroup('foobar');
@@ -627,6 +641,10 @@ public function testCountUsersInGroupPrimaryMembersOnly() {
627641
->method('isDNPartOfBase')
628642
->willReturn(true);
629643

644+
$access->userManager->expects($this->any())
645+
->method('getAttributes')
646+
->willReturn(['displayName', 'mail']);
647+
630648
$groupBackend = new GroupLDAP($access, $pluginManager);
631649
$users = $groupBackend->countUsersInGroup('foobar');
632650

0 commit comments

Comments
 (0)