You are here

public function LdapServer::groupMembershipsFromEntryRecursive in Lightweight Directory Access Protocol (LDAP) 7.2

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

Parameters

array $current_group_entries: of ldap group entries that are starting point. should include at least 1 entry.

array $all_group_dns: as array of all groups user is a member of. MIXED CASE VALUES.

array $tested_group_ids: as 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 recursing.

int $level: of recursion.

int $max_levels: as max recursion allowed

given set of groups entries ($current_group_entries such as it, hr, accounting), find parent groups (such as staff, people, users) and add them to list of group memberships ($all_group_dns)

(&(objectClass=[$this->groupObjectClass])(|([$this->groupMembershipsAttr]=groupid1)([$this->groupMembershipsAttr]=groupid2))

Return value

FALSE for error or misconfiguration, otherwise TRUE. results are passed by reference.

2 calls to LdapServer::groupMembershipsFromEntryRecursive()
LdapServer::groupUserMembershipsFromEntry in ldap_servers/LdapServer.class.php
Get list of all groups that a user is a member of by querying groups.
LdapServer::groupUserMembershipsFromUserAttr in ldap_servers/LdapServer.class.php
Get list of all groups that a user is a member of by using memberOf attribute first, then if nesting is true, using group entries to find parent groups.

File

ldap_servers/LdapServer.class.php, line 1962
Defines server classes and related functions.

Class

LdapServer
LDAP Server Class.

Code

public function groupMembershipsFromEntryRecursive($current_group_entries, &$all_group_dns, &$tested_group_ids, $level, $max_levels) {
  if (!$this->groupGroupEntryMembershipsConfigured || !is_array($current_group_entries) || count($current_group_entries) == 0) {
    return FALSE;
  }
  if (isset($current_group_entries['count'])) {
    unset($current_group_entries['count']);
  }
  $ors = [];
  foreach ($current_group_entries as $i => $group_entry) {
    if ($this->groupMembershipsAttrMatchingUserAttr == 'dn') {
      $member_id = $group_entry['dn'];
    }
    else {
      $member_id = ldap_servers_get_first_rdn_value_from_dn($group_entry['dn'], $this->groupMembershipsAttrMatchingUserAttr);
      if (!$member_id) {
        if ($this->detailed_watchdog_log) {
          watchdog('ldap_servers', 'group_entry: %ge', [
            '%ge' => pretty_print_ldap_entry($group_entry),
          ]);
        }

        // Group not identified by simple checks yet!
        // examine the entry and see if it matches the configured groupObjectClass
        // TODO do we need to ensure such entry is there?
        $goc = $group_entry['objectclass'];

        // TODO is it always an array?
        if (is_array($goc)) {
          foreach ($goc as $g) {
            $g = drupal_strtolower($g);
            if ($g == $this->groupObjectClass) {

              // Found a group, current user must be member in it - so:
              if ($this->detailed_watchdog_log) {
                watchdog('ldap_servers', 'adding %mi', [
                  '%mi' => $member_id,
                ]);
              }
              $member_id = $group_entry['dn'];
              break;
            }
          }
        }
      }
    }
    if ($member_id && !in_array($member_id, $tested_group_ids)) {
      $tested_group_ids[] = $member_id;
      $all_group_dns[] = $group_entry['dn'];

      // Add $group_id (dn, cn, uid) to query.
      $ors[] = $this->groupMembershipsAttr . '=' . ldap_pear_escape_filter_value($member_id);
    }
  }
  if ($level < $max_levels && count($ors)) {
    $count = count($ors);

    // Only 50 or so per query.
    for ($i = 0; $i < $count; $i = $i + LDAP_SERVER_LDAP_QUERY_CHUNK) {
      $current_ors = array_slice($ors, $i, LDAP_SERVER_LDAP_QUERY_CHUNK);

      // e.g. (|(cn=group1)(cn=group2)) or   (|(dn=cn=group1,ou=blah...)(dn=cn=group2,ou=blah...))
      $or = '(|(' . join(")(", $current_ors) . '))';
      $query_for_parent_groups = '(&(objectClass=' . $this->groupObjectClass . ')' . $or . ')';

      // Need to search on all basedns one at a time.
      foreach ($this->basedn as $base_dn) {

        // No attributes, just dns needed.
        $group_entries = $this
          ->search($base_dn, $query_for_parent_groups);
        if ($group_entries !== FALSE) {
          $this
            ->groupMembershipsFromEntryRecursive($group_entries, $all_group_dns, $tested_group_ids, $level + 1, $max_levels);
        }
      }
    }
  }
  return TRUE;
}