You are here

public function LdapGroupManager::groupMembersRecursive in Lightweight Directory Access Protocol (LDAP) 8.4

Recurse through all child groups and add members.

Parameters

\Symfony\Component\Ldap\Entry[] $entries: Entries of LDAP group entries that are starting point. Should include at least 1 entry and must include 'objectclass'.

array $all_member_dns: All member DN as an array of all groups the user is a member of. Mixed case values.

array $tested_group_dns: Tested group IDs as an array array of tested group dn, cn, uid, etc. Mixed case values. Whether these value are dn, cn, uid, etc depends on what attribute members, uniquemember, memberUid contains whatever attribute is in $this->$tested_group_ids to avoid redundant recursion.

int $level: Current level of recursion.

int $max_levels: Maximum number of recursion levels allowed.

array|null $object_classes: You can set the object class evaluated for recursion here, otherwise derived from group configuration.

1 call to LdapGroupManager::groupMembersRecursive()
LdapGroupManager::groupAllMembers in ldap_servers/src/LdapGroupManager.php
Get all members of a group.

File

ldap_servers/src/LdapGroupManager.php, line 384

Class

LdapGroupManager
LDAP Group Manager.

Namespace

Drupal\ldap_servers

Code

public function groupMembersRecursive(array $entries, array &$all_member_dns, array $tested_group_dns, int $level, int $max_levels, ?array $object_classes = NULL) : void {
  if (!$this
    ->checkAvailability()) {
    return;
  }
  if (!$this
    ->groupGroupEntryMembershipsConfigured()) {
    return;
  }
  foreach ($entries as $entry) {

    // Add entry itself if of the correct type to $all_member_dns.
    $lowercased_object_class = array_map('strtolower', array_values($entry
      ->getAttribute('objectClass', FALSE)));
    $object_is_group = in_array($this->server
      ->get('grp_object_cat'), $lowercased_object_class, TRUE);
    $object_class_match = !$object_classes || count(array_intersect(array_values($entry
      ->getAttribute('objectClass', FALSE)), $object_classes)) > 0;
    if ($object_class_match && !in_array($entry
      ->getDn(), $all_member_dns, TRUE)) {
      $all_member_dns[] = $entry
        ->getDn();
    }

    // If its a group, keep recurse the group for descendants.
    if ($object_is_group && $level < $max_levels) {
      if ($this->server
        ->get('grp_memb_attr_match_user_attr') === 'dn') {
        $group_id = $entry
          ->getDn();
      }
      else {
        $group_id = $entry
          ->getAttribute($this->server
          ->get('grp_memb_attr_match_user_attr'), FALSE)[0];
      }

      // 3. skip any groups that have already been tested.
      if (!in_array($group_id, $tested_group_dns, TRUE)) {
        $tested_group_dns[] = $group_id;
        $member_ids = $entry
          ->getAttribute($this->server
          ->get('grp_memb_attr'), FALSE);
        if (count($member_ids)) {

          // Example 1: (|(cn=group1)(cn=group2))
          // Example 2: (|(dn=cn=group1,ou=blah...)(dn=cn=group2,ou=blah...))
          $query_for_child_members = sprintf('(|(%s))', implode(')(', $member_ids));

          // Add or on object classes, otherwise get all object classes.
          if ($object_classes && count($object_classes)) {
            $object_classes_ors = [
              sprintf('(objectClass=%s)', $this->server
                ->get('grp_object_cat')),
            ];
            foreach ($object_classes as $object_class) {
              $object_classes_ors[] = sprintf('(objectClass=%s)', $object_class);
            }
            $query_for_child_members = sprintf('&(|%s)(%s)', implode('', $object_classes_ors), $query_for_child_members);
          }
          $child_member_entries = $this
            ->searchAllBaseDns($query_for_child_members, [
            'objectClass',
            $this->server
              ->get('grp_memb_attr'),
            $this->server
              ->get('grp_memb_attr_match_user_attr'),
          ]);
          if (!empty($child_member_entries)) {
            $this
              ->groupMembersRecursive($child_member_entries, $all_member_dns, $tested_group_dns, $level + 1, $max_levels, $object_classes);
          }
        }
      }
    }
  }
}