You are here

private function LdapGroupManager::groupMembershipsFromEntryRecursive in Lightweight Directory Access Protocol (LDAP) 8.4

Recurse through all groups, adding parent groups to $all_group_dns array.

@todo See if we can do this with groupAllMembers().

Parameters

\Symfony\Component\Ldap\Adapter\CollectionInterface|Entry[] $current_group_entries: Entries of LDAP groups, which are that are starting point. Should include at least one entry.

array $all_group_dns: An array of all groups the user is a member of in mixed-case.

array $tested_group_ids: An array of tested group DN, CN, UID, etc. in mixed-case. Whether these value are DN, CN, UID, etc. depends on what attribute members, uniquemember, or memberUid contains whatever attribute in $this->$tested_group_ids to avoid redundant recursion.

int $level: Levels of recursion.

int $max_levels: Maximum levels of recursion allowed.

Return value

bool False for error or misconfiguration, otherwise TRUE. Results are passed by reference.

2 calls to LdapGroupManager::groupMembershipsFromEntryRecursive()
LdapGroupManager::getNestedGroupDnFilters in ldap_servers/src/LdapGroupManager.php
Search within the nested groups for further filters.
LdapGroupManager::groupUserMembershipsFromEntry in ldap_servers/src/LdapGroupManager.php
Get list of all groups that a user is a member of by querying groups.

File

ldap_servers/src/LdapGroupManager.php, line 621

Class

LdapGroupManager
LDAP Group Manager.

Namespace

Drupal\ldap_servers

Code

private function groupMembershipsFromEntryRecursive(CollectionInterface $current_group_entries, array &$all_group_dns, array &$tested_group_ids, int $level, int $max_levels) : bool {
  if (!$this
    ->groupGroupEntryMembershipsConfigured() || $current_group_entries
    ->count() === 0) {
    return FALSE;
  }
  $or_filters = [];

  /** @var \Symfony\Component\Ldap\Entry $group_entry */
  foreach ($current_group_entries
    ->toArray() as $group_entry) {
    if ($this->server
      ->get('grp_memb_attr_match_user_attr') === 'dn') {
      $member_id = $group_entry
        ->getDn();
    }
    else {
      $member_id = $this
        ->getFirstRdnValueFromDn($group_entry
        ->getDn());
    }
    if ($member_id && !in_array($member_id, $tested_group_ids, TRUE)) {
      $tested_group_ids[] = $member_id;
      $all_group_dns[] = $group_entry
        ->getDn();

      // Add $group_id (dn, cn, uid) to query.
      $or_filters[] = $this->server
        ->get('grp_memb_attr') . '=' . $this
        ->ldapEscapeDn($member_id);
    }
  }
  if (!empty($or_filters)) {

    // Example 1: (|(cn=group1)(cn=group2))
    // Example 2: (|(dn=cn=group1,ou=blah...)(dn=cn=group2,ou=blah...))
    $or = sprintf('(|(%s))', implode(')(', $or_filters));
    $query_for_parent_groups = sprintf('(&(objectClass=%s)%s)', $this->server
      ->get('grp_object_cat'), $or);

    // Need to search on all base DNs one at a time.
    foreach ($this->server
      ->getBaseDn() as $base_dn) {

      // No attributes, just dns needed.
      try {
        $ldap_result = $this->ldap
          ->query($base_dn, $query_for_parent_groups, [
          'filter' => [],
        ])
          ->execute();
      } catch (LdapException $e) {
        $this->logger
          ->critical('LDAP search error with %message', [
          '%message' => $e
            ->getMessage(),
        ]);
        continue;
      }
      if ($level < $max_levels && $ldap_result
        ->count() > 0) {
        $this
          ->groupMembershipsFromEntryRecursive($ldap_result, $all_group_dns, $tested_group_ids, $level + 1, $max_levels);
      }
    }
  }
  return TRUE;
}