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
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:
- Alle globalen Gruppen der Domäne.
- Alle Benutzer und Kontakte in einer bestimmten OU.
- Alle Benutzer, deren PLZ mit einer bestimmten Nummer anfängt und die das Attribut Anzeigename nicht gesetzt haben.
- Alle Benutzer, deren Vorname mit "P" anfängt.
- Alle Domänen-Controller.
- Alle Benutzer mit Postfach auf einem bestimmten Server, die nicht im Adressbuch angezeigt werden.
- Die Server, die die Replica einer bestimmten ADAM-Partition speichern.
- Der ADS-SiteLink, für den ein bestimmter Domänen-Controller Bridgehead ist.
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:
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). Für binäre Werte kann leider keine Wildcard-Suche verwendet
werden! |
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:
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):
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:
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:
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: |
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*) |