LDAP und ADSI

Seit meiner Schulzeit hatte ich immer wieder kleinere Progrämmchen geschrieben, sei es um Office-Arbeiten zu erleichtern oder Tools zum Suchen und Verwalten von Daten, Links oder Webseiten.
Und auch ein paar Webseiten selbst waren darunter.
Aber alles in allem keine weltbewegenden Sachen.

Das erste wirklich relevante “Programm” aus meinen Händen beschäftigte sich mit LDAP, dem Active Directory und ist auch heute noch auf SourceForge zu finden.


Es begann in meiner Tätigkeit als User-Administrator, wo ich großteils nur Benutzer auf Anfragen hin in Gruppen verschieben durfte, damit sie Rechte in anderen Abteilungen, Applikationen oder Projekten erhalten sollten.

Die Plattform war das Active Directory von Windows Server 2003.
Und damals lief auch die große Umstellung und Auflösung von Windows NT, wo alle User-Accounts ins Active Directory migriert werden mussten und dort im neuen System wieder alle ihre Rechte erhalten sollten.
Das waren so um die 8000 Benutzeraccounts.

Interessant dabei war, dass die Verantwortlichen im Unternehmen hierfür nur eine Lösung sahen:

Admins sollten die Accounts manuell verschieben, umbenennen und in neue Gruppen aufnehmen.

Anders gesagt: Eine riesige Verschwendung von Arbeitskräften.

Denn Microsoft hatte schon mit Windows 2000 eine neue LDAP Schnittstelle eingeführt, nämlich ADSI, das Active Directory Service Interface, womit alle Objekte in einer Domäne angesprochen und bearbeitet werden konnten.
Das war über einfachste VB-Scripts möglich und recht gut dokumentiert. Aber auch in VB6 und C++ war es leicht einsetzbar.

Zwar hatte ich anfangs weder von ADSI noch von LDAP Ahnung, doch schnell erkannte ich die Möglichkeit, dieses hirntötende manuelle Verschieben per Maus automatisch ablaufen zu lassen.

Eine Woche später konnte ich in meinem guten alten Visual Basic 6 ein kleines Formular vorstellen, dass auf Knopfdruck bei allen Accounts in einer Suchmaske bestimmte Aktionen auslöste, wie:

  • Passwort Reset
  • Vorname, Nachname, Displayname, E-Mail-Adresse auf ein neues Format korrigieren
  • Account in andere OUs (Organizational Units) verschieben

Das Resultat war durchaus beachtlich.
Während für ein paar tausend Accounts 4 Admins manuell ein Monat herumwerken mussten, wurden die restlichen paar tausend in 10 Minuten umgestellt.

Mission accomplished.


Doch nun hatte ich Blut geleckt und genoss es zunehmend, den LDAP Verzeichnisdienst so einfach unter Kontrolle zu haben.

Aber seien wir mal ehrlich, kompliziert war das ganze in VB nicht.

Dim obj
obj = GetObject("LDAP://CN=user,OU=org-branch,DC=domain,DC=com")
obj.Put "attributeName", "attributeValue"
obj.SetInfo

Also startete ich parallel zu Arbeit das Project “Active Director”, ein Tool mit dem man ADSI Objekte selektieren und Templates für Änderungen anlegen konnte, die im Anschluss auf die selektierten Objekte ausgerollen wurden.
Man nennt das auch gerne mal: Automation.

Denn wenn am Anfang jedes Monats eine Liste mit 30 Personen eintraf, die es zu Löschen/Deaktivieren galt und eine weitere Liste mit Vorname, Nachname und Personalnummer, die als Accounts neu angelegt werden sollten, so waren immer X Personen einige Tage beschäftigt, das manuell und mit gelangweiltem Blick umzusetzen.

Doch mit der Möglichkeit, dass diese Liste automatisch eingelesen wird und mit einer entsprechenden Vorlage binnen Sekunden ins Directory übertragen wird, waren die menschlichen Ressourcen freigespielt um “echte” Probleme zu lösen oder zu analysieren, die den Betrieb nebenbei schon lange störten.


Mit jenen Erfahrungen damals fiel mir auch die Nutzung der dotNet System.DirectoryServices einfacher, denn die wahre Komplexität steckt im Aufbau der Attribute eines LDAP Verzeichnisdienstes.

Und auch die Konfiguration von anderen Diensten und Servern fällt einem viel leichter, wenn man weiß, wo die gesamten LDAP Pfade herkommen.

ADSI selbst wird zu meinem Bedauern mehr und mehr von .NET verdängt, obwohl es neben LDAP einen ganz wichtigen anderen Aspekt hat:
Es ist eine offene Schnittstelle für unterschiedliche “Directories”.

Denn ADSI kann nicht nur Microsoft Active Directories ansprechen, sondern grundsätzlich jeden LDAP Server. Es wird auch standardmäßig mit dem WinNT Provider ausgeliefert, der lokale Benutzeraccounts und -gruppen verwalten kann, hier sehen einfach nur die Pfade anders aus:

Dim obj, flags
obj = GetObject("WinNT://PC-NAME/myaccount,user")
flags = obj.Get("UserFlags")
flags = flags Or ADS_UF_DONT_EXPIRE_PASSWD
obj.Put "UserFlags", flags
obj.AccountDisabled = False
obj.SetInfo

Eine ganz besondere Spezialität hat Microsoft leider ab Windows Vista wieder entfernt, nämlich der Zugriff auf Novel Netware Directories.
Hierfür gab es bis Server 2003 und Windows XP den NDS: und den NWCOMPAT: Provider um diese Systeme ebenso zu automatisieren.
Und ich konnte damals gar nicht anders als so lange im Netz zu suchen, bis ich eine eigene alte Novell Installation bei mir hatte … und … es funktionierte!


Ich bedauere etwas, dass mich mein Arbeitsweg von ADSI nun weggeführt hat und mein altes “Active Director” Projekt nun langsam auf SourceForge verwest.
Zumindest zeitweise konnte ich mit dem Tool mit Größen wie Hyena mithalten, weil neben ADSI auch WMI integriert wurde und damit fast alles konfigurierbar wird. Doch am Ende muss man solche Programme entweder kommerzialisieren oder sie beenden.

Doch trotz der alten (und aus heutiger Sicht hässlichen) VB6 Codebase, hat mich das Projekt viel über Verwaltung und Codeaufbau gelehrt. Schließlich waren einige verworfene Ansätze notwendig, bis das ganze schlüssig und lauffähig war.


Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!