Start · Sprachen · PHP · Referenz · ldap_search

ldap_search

Funktion

Führt eine LDAP-Suche mit dem Scope <code>LDAP_SCOPE_SUBTREE</code> im angegebenen Basisverzeichnis durch und gibt ein Ergebnis-Handle zurück.

seit PHP 4.0.0 Kategorie: misc

Signatur

ldap_search(LDAP\Connection|array $ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false

Beschreibung

ldap_search durchsucht den LDAP-Verzeichnisbaum ab dem angegebenen Basis-DN (base) rekursiv nach Einträgen, die dem übergebenen Filter entsprechen. Der Suchbereich umfasst den Basisknoten selbst sowie alle seine Unterknoten (Scope subtree). Die Funktion ist das Arbeitspferd für typische Verzeichnisabfragen, etwa um Benutzer oder Gruppen in einem Active Directory oder OpenLDAP zu finden.

Das zurückgegebene LDAP\Result-Objekt (bzw. vor PHP 8.1 eine Ressource) kann anschließend mit ldap_get_entries, ldap_first_entry oder ähnlichen Funktionen ausgelesen werden. Über den Parameter $attributes lässt sich die Rückgabe auf bestimmte Attribute beschränken, was die übertragene Datenmenge erheblich reduziert.

Mit dem optionalen Parameter $sizelimit kann die maximale Anzahl zurückgegebener Einträge begrenzt werden. Zu beachten ist, dass der LDAP-Server selbst ebenfalls ein serverseitiges Limit setzen kann, das nicht überschritten werden kann. $timelimit schränkt die maximale Suchdauer in Sekunden ein. Der Parameter $deref steuert, wie LDAP-Aliase aufgelöst werden.

Sollen mehrere Verbindungen gleichzeitig durchsucht werden, kann als erster Parameter ein Array von LDAP\Connection-Objekten übergeben werden, wobei $base und $filter ebenfalls als Arrays übergeben werden müssen. In diesem Fall liefert die Funktion ein Array von LDAP\Result-Objekten zurück.

Parameter

Name Typ Default Beschreibung
$ldap Pflicht LDAP\Connection|array Eine gültige LDAP\Connection-Instanz (erzeugt von ldap_connect) oder ein Array solcher Instanzen für parallele Mehrfachsuchen.
$base Pflicht array|string Der Basis-DN (Distinguished Name), ab dem die Suche beginnt, z. B. "dc=example,dc=com". Bei Mehrfachsuchen ein Array von Basis-DNs.
$filter Pflicht array|string Der LDAP-Suchfilter gemäß RFC 4515, z. B. "(uid=jdoe)" oder "(&(objectClass=user)(sAMAccountName=admin))". Bei Mehrfachsuchen ein Array von Filtern.
$attributes array [] Array mit den Namen der zurückzugebenden Attribute, z. B. ["cn", "mail", "uid"]. Ein leeres Array (Standard) liefert alle Attribute des Eintrags.
$attributes_only int 0 Wenn auf 1 gesetzt, werden nur die Attributnamen ohne deren Werte zurückgegeben. Standard ist 0 (Attributnamen und -werte).
$sizelimit int -1 Maximale Anzahl zurückzugebender Einträge. -1 bedeutet, dass der Standardwert des LDAP-Servers verwendet wird. Das serverseitige Limit kann nicht überschritten werden.
$timelimit int -1 Maximale Suchdauer in Sekunden. -1 bedeutet, dass der Standardwert des LDAP-Servers gilt.
$deref int LDAP_DEREF_NEVER Steuert die Alias-Auflösung. Mögliche Werte: LDAP_DEREF_NEVER, LDAP_DEREF_SEARCHING, LDAP_DEREF_FINDING, LDAP_DEREF_ALWAYS.
$controls array|null null Array mit LDAP-Serversteuerungen (Server Controls), die mit der Anfrage gesendet werden sollen. Kann z. B. für Paginierung (LDAP_CONTROL_PAGEDRESULTS) verwendet werden.

Rückgabewert

Typ
LDAP\Result|array|false
Beschreibung
Bei Erfolg ein LDAP\Result-Objekt (ab PHP 8.1), das mit ldap_get_entries o. ä. ausgelesen werden kann. Bei Mehrfachsuchen ein Array von LDAP\Result-Objekten. Im Fehlerfall wird false zurückgegeben.

Beispiele

Einfache Benutzersuche im LDAP-Verzeichnis

<?php
$ldap = ldap_connect('ldap://ldap.example.com');
if (!$ldap) {
    die('Verbindung zum LDAP-Server fehlgeschlagen.');
}

ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);

// Anonymes Bind (oder mit Credentials: ldap_bind($ldap, 'cn=admin,dc=example,dc=com', 'geheim'))
if (!ldap_bind($ldap)) {
    die('LDAP-Bind fehlgeschlagen: ' . ldap_error($ldap));
}

$baseDn = 'dc=example,dc=com';
$filter = '(uid=jdoe)';
$attrs  = ['cn', 'mail', 'uid'];

$result = ldap_search($ldap, $baseDn, $filter, $attrs);

if ($result === false) {
    die('Suche fehlgeschlagen: ' . ldap_error($ldap));
}

$entries = ldap_get_entries($ldap, $result);
echo 'Gefundene Einträge: ' . $entries['count'] . PHP_EOL;

for ($i = 0; $i < $entries['count']; $i++) {
    echo 'CN   : ' . ($entries[$i]['cn'][0] ?? '-') . PHP_EOL;
    echo 'Mail : ' . ($entries[$i]['mail'][0] ?? '-') . PHP_EOL;
}

ldap_unbind($ldap);
?>
Gefundene Einträge: 1 CN : John Doe Mail : jdoe@example.com

Paginierte Suche mit LDAP_CONTROL_PAGEDRESULTS

<?php
$ldap = ldap_connect('ldap://ldap.example.com');
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_bind($ldap, 'cn=admin,dc=example,dc=com', 'geheim');

$baseDn  = 'dc=example,dc=com';
$filter  = '(objectClass=inetOrgPerson)';
$attrs   = ['cn', 'mail'];
$pageSize = 100;
$cookie  = '';

do {
    $controls = [
        [
            'oid'        => LDAP_CONTROL_PAGEDRESULTS,
            'iscritical' => false,
            'value'      => ['size' => $pageSize, 'cookie' => $cookie],
        ]
    ];

    $result = ldap_search($ldap, $baseDn, $filter, $attrs, 0, 0, 0, LDAP_DEREF_NEVER, $controls);

    if ($result === false) {
        echo 'Fehler: ' . ldap_error($ldap);
        break;
    }

    $entries = ldap_get_entries($ldap, $result);
    echo 'Seite enthält ' . $entries['count'] . ' Einträge.' . PHP_EOL;

    foreach (range(0, $entries['count'] - 1) as $i) {
        echo '  - ' . ($entries[$i]['cn'][0] ?? '?') . PHP_EOL;
    }

    // Cookie für nächste Seite auslesen
    ldap_parse_result($ldap, $result, $errcode, $matcheddn, $errmsg, $refs, $responseControls);
    $cookie = $responseControls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? '';

} while (!empty($cookie));

ldap_unbind($ldap);
?>
Seite enthält 100 Einträge. - Alice Müller - Bob Schmidt ...

// Wichtig · Fallstricke

Sicherheit: Benutzereingaben dürfen niemals ungeprüft in LDAP-Filter eingefügt werden, da dies zu LDAP-Injection führen kann. Sonderzeichen wie (, ), *, \ und das Null-Byte müssen mit ldap_escape($input, '', LDAP_ESCAPE_FILTER) maskiert werden.

Sizelimit: Wenn $sizelimit kleiner ist als das serverseitige Limit, wird der kleinere Wert verwendet. Das serverseitige Limit kann jedoch nicht durch den Client überschritten werden. Bei großen Verzeichnissen empfiehlt sich die paginierte Suche über LDAP_CONTROL_PAGEDRESULTS.

PHP 8.1: Ab PHP 8.1 gibt ldap_search ein LDAP\Result-Objekt statt einer Ressource zurück. Code, der explizit auf den Typ resource prüft, muss angepasst werden.

Encoding: LDAP verwendet UTF-8 als Zeichenkodierung. PHP-Strings müssen daher korrekt kodiert sein, bevor sie als Filter oder DN verwendet werden.