code/services/LDAPService.php
public function getNestedGroups($dn, $attributes = [])
    {
        if (isset(self::$_cache_nested_groups[$dn])) {
            return self::$_cache_nested_groups[$dn];
        }

        $searchLocations = $this->config()->groups_search_locations ?: [null];
        $results = [];
        foreach ($searchLocations as $searchLocation) {
            $records = $this->gateway->getNestedGroups($dn, $searchLocation, Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes);
            foreach ($records as $record) {
                $results[$record['dn']] = $record;
            }
        }

        self::$_cache_nested_groups[$dn] = $results;
        return $results;
    }
public function getNestedGroups($dn, $attributes = [])
    {
        if (isset(self::$_cache_nested_groups[$dn])) {
            return self::$_cache_nested_groups[$dn];
        }

        $searchLocations = $this->config()->groups_search_locations ?: [null];
        $results = [];
        foreach ($searchLocations as $searchLocation) {
            $records = $this->gateway->getNestedGroups($dn, $searchLocation, Zend\Ldap\Ldap::SEARCH_SCOPE_SUB, $attributes);
            foreach ($records as $record) {
                $results[$record['dn']] = $record;
            }
        }

        self::$_cache_nested_groups[$dn] = $results;
        return $results;
    }
Return all member groups (and members of those, recursively) underneath a specific group DN.
Note that these get cached in-memory per-request for performance to avoid re-querying for the same results.

@param string $dn
@param array $attributes List of specific AD attributes to return. Empty array means return everything.
@return array