diff options
author | Arthur Schiwon <blizzz@arthur-schiwon.de> | 2021-12-12 14:09:16 +0100 |
---|---|---|
committer | Carl Schwan <carl@carlschwan.eu> | 2022-10-20 12:08:09 +0200 |
commit | 1e4ac22c946969088a2265730095775e8fc5c645 (patch) | |
tree | 53b92f0ab673bf2c8e1fd7a33a43a2e2c2ee7d7d /apps/user_ldap | |
parent | 53b6d67bc19dfb75b6be64cae9ffeaf6fbfbdd6d (diff) | |
download | nextcloud-server-1e4ac22c946969088a2265730095775e8fc5c645.tar.gz nextcloud-server-1e4ac22c946969088a2265730095775e8fc5c645.zip |
Make it possible to return nested records whem walking over groups
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
Diffstat (limited to 'apps/user_ldap')
-rw-r--r-- | apps/user_ldap/lib/Group_LDAP.php | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/apps/user_ldap/lib/Group_LDAP.php b/apps/user_ldap/lib/Group_LDAP.php index 5072f9d3f74..3db3c6c7664 100644 --- a/apps/user_ldap/lib/Group_LDAP.php +++ b/apps/user_ldap/lib/Group_LDAP.php @@ -360,7 +360,7 @@ class Group_LDAP extends BackendUtility implements GroupInterface, IGroupLDAP, I $nesting = (int)$this->access->connection->ldapNestedGroups; // depending on the input, we either have a list of DNs or a list of LDAP records // also, the output expects either DNs or records. Testing the first element should suffice. - $recordMode = is_array($list) && isset($list[0]) && is_array($list[0]) && isset($list[0]['dn'][0]); + $recordMode = isset($list[0]) && is_array($list[0]) && isset($list[0]['dn'][0]); if ($nesting !== 1) { if ($recordMode) { @@ -392,6 +392,36 @@ class Group_LDAP extends BackendUtility implements GroupInterface, IGroupLDAP, I return $recordMode ? array_filter($seen, 'is_array') : array_keys($seen); } + private function walkNestedGroupsReturnRecords(string $dn, Closure $fetcher, array $list, array &$seen = []): array { + $nesting = (int)$this->access->connection->ldapNestedGroups; + + if ($nesting !== 1) { + // the keys are numeric, but should hold the DN + return array_reduce($list, function ($transformed, $record) use ($dn) { + if ($record['dn'][0] != $dn) { + $transformed[$record['dn'][0]] = $record; + } + return $transformed; + }, []); + } + + while ($record = array_shift($list)) { + $recordDN = $record['dn'][0] ?? $record; + if ($recordDN === $dn || array_key_exists($recordDN, $seen)) { + // Prevent loops + continue; + } + $fetched = $fetcher($record); + $list = array_merge($list, $fetched); + if (!isset($seen[$recordDN]) || is_bool($seen[$recordDN]) && is_array($record)) { + $seen[$recordDN] = $record; + } + } + + // on record mode, filter out intermediate state + return array_filter($seen, 'is_array'); + } + /** * translates a gidNumber into an ownCloud internal name * @@ -848,6 +878,9 @@ class Group_LDAP extends BackendUtility implements GroupInterface, IGroupLDAP, I // avoid loops return []; } + if ($this->cachedGroupsByMember[$dn]) { + return $this->cachedGroupsByMember[$dn]; + } $allGroups = []; $seen[$dn] = true; $filter = $this->access->connection->ldapGroupMemberAssocAttr . '=' . $dn; @@ -875,9 +908,11 @@ class Group_LDAP extends BackendUtility implements GroupInterface, IGroupLDAP, I $dn = ""; } - $allGroups = $this->walkNestedGroups($dn, $fetcher, $groups, $seen); + $allGroups = $this->walkNestedGroupsReturnRecords($dn, $fetcher, $groups, $seen); $visibleGroups = $this->filterValidGroups($allGroups); - return array_intersect_key($allGroups, $visibleGroups); + $effectiveGroups = array_intersect_key($allGroups, $visibleGroups); + $this->cachedGroupsByMember[$dn] = $effectiveGroups; + return $effectiveGroups; } /** @@ -1183,7 +1218,11 @@ class Group_LDAP extends BackendUtility implements GroupInterface, IGroupLDAP, I $validGroupDNs = []; foreach ($listOfGroups as $key => $item) { $dn = is_string($item) ? $item : $item['dn'][0]; - $gid = $this->access->dn2groupname($dn); + if(is_array($item) && !isset($item[$this->access->connection->ldapGroupDisplayName][0])) { + continue; + } + $name = $item[$this->access->connection->ldapGroupDisplayName][0] ?? null; + $gid = $this->access->dn2groupname($dn, $name); if (!$gid) { continue; } |