Printout Header
RSS Feed

LDAP-Filter


Dieser Abschnitt des SelfADSI Tutorials beschäftigt sich mit LDAP-Filtern. Folgende Inhalte stehen in diesem Abschnitt zur Verfügung:


Definition von LDAP-Filtern
Syntax und Operatoren
Filtern nach Hex-Zahlen und Binärwerten
Filtern nach Bit-Feldern
Filtern mit der Ambigous Name Resolution (ANR)
 
Beispiele für LDAP-Filtern im Active Directory
Beispiele für LDAP-Filtern im Exchange 5.5 Verzeichnis



Definition von LDAP Filtern


Mit LDAP-Filtern können Kriterien angegeben werden, nach denen im Verzeichnis bestimmte Objekte gesucht werden können. Umgangsprachlich könnte man für bestimmte LDAP-Filter auch folgende Kriterien spezifizieren:

LDAP Filter werden in vielen Situationen benötigt. Sie können an mehreren Stellen der grafischen ADS- bzw. Exchange-Verwaltungstools entweder mit Wizard-Unterstützung oder auch direkt von Hand eingegeben verwendet werden. Ein Beispiel für die Verwendung eines LDAP-Filters bei einer Abfrage, die im Tool "AD User and Computer" definiert werden kann:



Bei ADSI Scripting benötigen wir Filter in erster Linie bei der ADO-Suche nach Objekten im Verzeichnis.


LDAP-Filter werden in folgenden RFCs definiert:

RFC 1588: A String Representation of LDAP Search Filters
RFC 1960: A String Representation of LDAP Search Filters (replaces RFC 1588)
RFC 2254: The String Representation of LDAP Search Filters (replaces RFC 1960)
RFC 4515: Lightweight Directory Access Protocol (LDAP): String Representation of Search Filters (replaces RFC 2254)

Syntax und Operatoren


LDAP-Filter bestehen aus einem oder mehreren Kriterien, die mittels UND- bzw. ODER-Operatoren miteinander verknüpft werden. Dabei stehen die Operatoren stets am Anfang und dann kommen die Operanden (also die Suchkriterien). Dies nennt man die "polnische Notation". Die Suchkriterien werden dabei in runden Klammern aufgeführt - das ganze kommt dann nochmals ingesamt in runde Klammern.



UND-Verknüpfung:

(& (...K1...) (...K2...))      oder auch mit mehr als zwei Kriterien:       (& (...K1...) (...K2...) (...K3...) (...K4...))


ODER-Verknüpfung:


(| (...K1...) (...K2...))      oder auch mit mehr als zwei Kriterien:       (| (...K1...) (...K2...) (...K3...) (...K4...)) 



Verschachtelte Verknüpfungen:

Jede UND/ODER-Verknüpfung kann insgesamt wieder als einzelnes Kriterium aufgefasst werden:


(|(& (...K1...) (...K2...))(& (...K3...) (...K4...)))        bedeutet:        (K1 AND K2) OR (K3 AND K4)




Die Suchkriterien bestehen dann aus einer Forderung an ein LDAP-Attribut, z.B (givenName=Philipp). Man beachte folgende Regeln:


Gleichheit: (attribute=abc)    , z.B. (&(objectclass=user)(displayName=Föckeler))
Ungleichheit: (!(attribute=abc)) , z.B. (!objectClass=group)
Vorhandensein: (attribute=*)        , z.B. (mailNickName=*)
Nichtvorhandensein: (!(attribute=*))    , z.B. (!proxyAddresses=*)
Größer-Vergleich: (attribute>=abc)    , z.B. (mdbStorageQuota>=100000)
Kleiner-Vergleich: (attribute<=abc)    , z.B. (mdbStorageQuota<=100000)
Ungefähr-Vergleich: (attribute~=abc)    , z.B. (displayName~=Fockeler) Achtung: ~= Wird in ADS-Umgebungen wie = behandelt !!
Wildcards: z.B. (sn=F*) oder (mail=*@cerrotorre.de) oder (givenName=*Paul*)


Weitere Regeln:


Nur echte Attribute......... Es können lediglich normale Attribute für einen LDAP-Filter herangezogen werden. Nicht zulässig für die Angabe in einem LDAP-Suchfilter sind Objekt-Properties der ADSI-Objekte, bei denen es sich gar nicht um LDAP-Datenbank-Attribute handelt, sondern nur um Schnittstellen-Eigenschaften des betreffenden Objektes. Eine Liste der davon betroffenen Properties können Sie im Abschnitt "API Properties von ADSI-Objekten" einsehen.

Keine Hochkommata...... Eventuell zu vergleichende Strings werden NICHT in Hochkommas erscheinen. Ein Filter für den AnzeigeNamen "Philipp Föckeler" würde also lauten (displayName=Philipp Föckeler).

Groß-/Kleinschreibung... Diese ist speziell für Boolean-Attribute (Ja/Nein-Attribute) entscheidend, z.B. müssen Sie unbedingt TRUE oder FALSE verwenden, wenn Sie derartige Attribute filtern wollen. Die meisten Zeichenketten-Attribute sind jedoch Case-Insensitiv, d.h. es wird ein Treffer gefunden, auch wenn sich die Groß-/Kleinschreibung von Ihrem Suchfilter unterscheidet.

Speziell bei Exchange 5.5-Verzeichnissen sind die meisten Attribute Case-Sensitiv, d.h. Groß- und Kleinschreibung ist entscheidend bei der Suche. Eine Liste der wenigen Ausnahmen können Sie im Abschnitt "Verzeichnisattribute des Typs CaseIgnoreString" einsehen.

DN-String-Attribute........
LDAP-Verzeichnisdienste übernehmen bei der Festlegung der Match-Algorithmen für die LDAP-Filter die Spezifikationen der ursprünglichen X.500 Standards. Für Attribute, die einen LDAP-DistinguishedName enthalten (Attribute vom Typ DN-String / ADSI Attribut-Datentyp ADSTYPE_DN_STRING = 1) , können laut diesen Matching Rules in LDAP-Filtern leider keine Wildcards vergeben werden. Auch Active Directory verhält sich so, dass Filter nicht funktionieren, in denen DN-Attribute mit Wildcards gesucht werden.
Das ist teilweise sehr ärgerlich, denn so können Sie z.B. keine Suche nach allen Benutzern durchführen, die in Gruppen Mitglied sind, die eine bestimmte Zeichenkette im Namen enthalten. Denn das User-Atribut memberOf ist vom Datentype DN-String.

Noch wichtiger wäre es oft, mit einem Filter Objekte zu suchen, die in einer bestimmten OU enthalten sind - nämlich immer dann, wenn man keine Möglichkeit hat, die SearchBase einer LDAP-Suche zu bestimmen, sondern ausschließlich den Filterstring setzen darf. Dies ist z.B. bei der Definition von Empfängerrichtlinien (Recipient Policies) bei Exchange Servern der Fall. Ein Filter der folgenden Form

   (distinguishedName=*,ou=Karlsruhe,dc=cerrotorre,dc=de)

funktioniert also nicht! Hier müssen wir auf eine skriptbasierte Lösung aufsetzen. Eine der vielen denkbaren Möglichkeiten habe ich hier ausgeführt: FAQ - Empfängeradressen für alle Benutzer einer bestimmmten OU per Script setzen.

Sonderzeichen................ LDAP-Filter können mit Unicode-Zeichen definiert werden. Sie können z.B. ohne Probleme deutsche Umlaute verwenden - wenn dies Sinn macht (wenn also das gefilterte Attribut ein Unicode-String ist). Allerdings spielen die Zeichen ( ) & | = ! > < ~ * / \ ein besondere Rolle bei der Definition von LDAP-Filtern.

Wenn diese Zeichen innerhalb eines Attribut-Strings gesucht oder verglichen werden sollen, dann müssen Sie diese mit einem vorangestellten Backslash und deren hexadezimalem ASCII-Code angeben:

( \28   ) \29   & \26   | \7c   = \3d
> \3e   < \3c   ~ \7e   * \2a   / \2f
\ \5c                        

Ein Beispiel: Wir wollen alle Objeke haben, deren Attribut "displayName" mit "*" beginnt:

   (displayName=\2a)

Gelegentlich wird auch das Null-Zeichen (\00) benötigt.

Multivalued Attribute...... Sie können auch nach bestimmten Werten in Multivalue-Attributen filtern. Ein gutes Beispiel hierfür ist das Attribut objectClass. Durch den hierarchischen Aufbau des Verzeichnis-Schemas wird hier ein Objekt stets mehrere Objektklassen besitzen. Ein ADS-Benutzer hat z.B. die ererbten Objektklassen top, person, organizationalPerson und user. Ein Filter könnte jetzt ohne weiteres so lauten:

   (objectClass=user)

Sie müssen sich allerdings bewußt sein, dass eine derartige Filterung am Server immer mehr Performance frißt als ein Filter nach einem normalen "eindimensionalen" Attribut.


Filtern nach Hex-Zahlen und Binär-Werten


Hex-Zahlen...................... Wenn Attribute vom Typ Integer oder Long Integer auf bestimmte Hex-Zahlenwerte hin verglichen und gefiltert werden sollen, dann muss der entsprechende Wert im LDAP-Filter stets als Dezimalzahl angegeben werden. Will man z.B. im Active Directory nach lokalen Sicherheits-Gruppen suchen, dann müssen für das groupType Attribute folgende Flags beide gesetzt sein:

ADS_GROUP_TYPE_LOCAL_GROUP (0x00000004)
ADS_GROUP_TYPE_SECURITY_ENABLED (0x80000000)

Dies ergibt in Addition den Hex-Wert 0x80000004, hier lautet der dezimale Wert 2147483652 - dieser wird dann im LDAP-Filter verwendet:

   (groupType=2147483652)

Binär-Werte....................

Eine ganz andere Sache ist es, wenn Filter für Attribute gebildet werden, die von ihrem Datentyp als binärer Hex-Wert vorliegen (oft wird der entsprechende Datentyp auch "Octet String" genannt).

Wenn Sie nach derartigen Binär-Attributen filtern wollen, dann müssen Sie unbedingt jedes zu vergleichende Byte als Hexadezimalcode angeben. Sollen z.B. Objekte mit einem Beispielattribut "Inventory" gesucht werden, dessen Wert auf 0x01AAF5EF steht, dann muss der entsprechende Filter so aussehen:

   (Inventory=\01\aa\f5\ef)


Für binäre Werte kann leider keine Wildcard-Suche verwendet werden!

Octet String Attribute sind allgemein mit VBScript nicht leicht auszulesen und in einen umgänglicheren Datentyp umzuwandeln - die notwendige Technik können Sie im SelfADSI Artikel "Verzeichnis-Attribute des Typs Octet String" erlernen.


Filtern nach Bits in Bit-Feldern


Man kann mit LDAP-Filtern auch Objekte finden, bei denen ein bestimmtes Bit in einem Bit-Feld gesetzt oder eben nicht gesetzt ist. In diesem Fall muss man eine seltsam anmutende Syntax einhalten:


   <Attributname>:<BitFilterRegel-ID>:=<Dezimal-Vergleichswert>


Es gibt genau 2 BitFilterRegel-IDs: Eine für Bit-weisen AND-Vergleich und einen für Bit-weisen OR-Vergleich:


   LDAP_MATCHING_RULE_BIT_AND           1.2.840.113556.1.4.803
   LDAP_MATCHING_RULE_BIT_OR             1.2.840.113556.1.4.804 

Beim AND-Filter werden nur Objekte gefunden, deren Attribut mit allen Bits des Filterwertes übereinstimmt. Für den OR-Vergleich muß für einen Treffer nur mindestens eines der Filter-Bits gesetzt sein.

Ein Beispiel:


Für das Attribut groupType bei Gruppen-Objekten im Active Directory ist folgende Bitmaske wichtig:


ADS_GROUP_TYPE_GLOBAL_GROUP     = 0x00000002
ADS_GROUP_TYPE_LOCAL_GROUP      = 0x00000004
ADS_GROUP_TYPE_UNIVERSAL_GROUP  = 0x00000008


Ein Filter für universelle Gruppen muss nun diejenigen Objekte suchen, in deren Attribut das 4. Bit "von unten" gesetzt haben. Dies kann man nachprüfen, indem man das Attribut mit dem Wert 0x00000008 (dieser repräsentiert das 4. Bit) in einem AND-Filter gleichsetzt:


(groupType:1.2.840.113556.1.4.803:=8) 'Alle universellen Gruppen

Vorsicht: In LDAP-Filtern muss an dieser Stelle der Hex-Wert des Bit-Filters stets dezimal angegeben werden! Will man also alle Security-Gruppen (und nicht die Verteiler-Gruppen) finden, so muss man nach dem 8. Bit filtern (0x80000000 = 2147483648):


(groupType:1.2.840.113556.1.4.803:=2147483648) 'Alle Security-enabled Gruppen

Ein Beispiel für einen OR-Filter: Wir suchen nach Benutzern die entweder kein Passwort benötigen (userAccountControl hat das Bit 0x20 - 32 gesetzt) oder deren Password nie abläuft (userAccountControl hat das Bit 0x10000 = 65536 gesetzt). Also müssen wir einen Filter bauen, der den Wert 65568 (=65536 + 32) verwendet:


(userAccountControl:1.2.840.113556.1.4.804:=65568) 'Alle Accounts, die kein Passwort benötigen ODER deren Passwort nie abläuft


Anmerkung: Beachten Sie, dass die Bit-weise Filterung am Server einen erhöhten Aufwand verursacht. Erwägen Sie deswegen auch den Einsatz von normalen Gleichheitskriterien. Wenn man z.B. nach universellen Sicherheitsgruppen sucht, kann man auch die beiden Flags 0x80000000 und 0x00000008 zusammenzählen und dann nach dem entsprechenden Dezimalwert 2147483656 filtern:


(groupType=2147483656) 'Alle universellen Sicherheitsgruppen

Filtern mit der Ambigous Name Resolution (ANR)


Die Ambigous Name Resolution kann in Active Directory Services Umgebungen Benutzer oder Kontakte finden, deren Name nur teilweise bekannt ist. Dabei wird nicht nur der Objektname, sondern auch der Anzeigename, der Vor- und Nachname sowie die diversen Mail-Adressierungen mit in die Suche einbezogen. Die ANR-Filtersuche können Sie als Outlook-Benutzer live beobachten, wenn Sie z.B. die Option "Namen überprüfen" verwenden, um den besten Treffer für eine Adresse ausfindig zu machen.


Welche Attribute genau in die ANR-Suche einbezogen werden, wird durch die Search-Flags der Attribut-Eigenschaften im Verzeichnis-Schema bestimmt. Dadurch wird ein sogenanntes ANR-Set von Attributen bestimmt. Folgende Attribute gehören standardmäßig zum ANR-Set:


   - Relative Distinguished Name (RDN), dies könnten z.B. die Werter für cn=.... oder ou=.... sein.
   - givenName (Vorname)
   - sn (Nachname)

   - displayName (Anzeigename)

   - legacyExchangeDN (nach Migrationen steht hier der Exchange 5.5-Verzeichnisname des alten Postfachs)

   - proxyAddresses (Mail-Adressen)

   - physicalDeliveryOfficeName (Büroadresse)


Die Syntax des ANR-Filters ist folgende


   (anr=Philipp) oder (anr=p f) oder (anr=Föck)

Alle diese Filter würden den Benutzer "Föckeler, Philipp" finden. Die zweite Form findet übrigens sowohl "Philipp Föckeler" als auch z.B. "Fritz Paul". Dies klappt deswegen, weil der ANR-Filter sowohl Vor- als auch Nachname prüft.


Beispiele für LDAP-Filter in Active Directory Umgebungen


Alle User:
    (&(objectCategory=person)(objectClass=user))

Alle User (komplizierter, aber effektiver):
    (sAMAccountType=805306368)

Alle Gruppen:
    (objectClass=group)

Alle Kontakte:
    (objectClass=contact)

Alle User und Kontakte:
    (objectClass=user)

Alle Sicherheitsgruppen (lokal, global und universal):
    (groupType:1.2.840.113556.1.4.803:=2147483648)

Alle leeren Gruppen:
    (&(objectClass=group)(!member=*))

Alle Gruppen, die nach dem 31.12.2008 geändert wurden:
    (&(objectClass=group)(whenChanged>=20081231000000.0Z))

Alle Benutzer, die sich seit dem 31.12.2008 nicht mehr angemeldet haben:
    (&(&(objectCategory=person)(objectClass=user))(lastLogonTimestamp<=128752108510000000))

Alle Benutzer mit der Einstellung "Passwort läuft nie ab":
    (&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))

All Computer-Konten, die disabled sind:
    (&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=2))

Alle PostfachUser auf Exchange-Server "KUNGUR":
    (msExchangeHomeserverName=/o=MAILOrg/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=KUNGUR)

Alle Benutzer mit der Einstellung "Disabled":
    (&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))

Alle Objekte, die nicht gelöscht werden können:
    (systemFlags:1.2.840.113556.1.4.803:=-2147483648)

All Objekte, die nicht umbenannt werden können:
    (systemFlags:1.2.840.113556.1.4.803:=134217728)

Alle versteckten Exchange Mail-Empfänger:
    (msExchHideFromAddressLists=TRUE)

Alle versteckten Exchange Mail-Empfänger (ohne Public Folder-Objekte):
    (&(msExchHideFromAddressLists=TRUE)(!objectClass=publicFolder))

Alle Mail-Empfänger mit Fax-Adresse:
    (proxyAddresses=FAX:*)

Alel Domänencontroller:
    (&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))

Alle Global Catalog Server (LDAP Suche in der Configuration Partition):
    (&(objectClass=nTDSDSA)(options:1.2.840.113556.1.4.803:=1))


Beispiele für LDAP-Filter im Exchange 5.5-Verzeichnis


Alle Postfächer:
    (objectClass=organizationalPerson)

Alle Verteilerlisten:
    (objectClass=groupOfNames)

Alle Benutzerdefinierten Empfänger:
    (objectClass=Remote-Address)

Alle Postfächer auf dem Server "TRANGO" im Standort "Site1" ind der Organisation "MAIL":
    (Home-MTA=cn=Microsoft MTA,cn=TRANGO,cn=Servers,cn=Configuration,ou=Site1,o=MAIL=Remote-Address)

Alle versteckten Exchange Mail-Empfänger (erfordert Anmeldung als "cn=USER,dc=DOM,cn=admin"):
    (Hide-From-Address-Book=TRUE)

Alle Empfänger, deren Anzeigenamen mit "F" beginnt:
    (cn=F*)