Es gibt außer den von ts-soft aufgezählten Möglichkeiten des LDAP-Zugriffs mit COMatePLUS oder ADOmate auch noch zumindest diese beiden Möglichkeiten:
- Eine limitierte Abfrage von Informationen des Domänen Controllers mit den Windows API-Funktionen NetUserGetInfo() und NetUserGetGroups()
- Eine Abfrage mit Hilfe der Bibliotheken WLDAP32.DLL (gehört bei Windows XP bis Windows 8.1 zum Betriebssystemumfang) und LDAPSDK.DLL (von Novell)
Zunächst einmal ein stark gekürztes Beispiel auf der Grundlage
dieses Beispiels von flaith aus dem englischen Forum zum Auslesen diverser Infos des Domain Controllers mit NetUserGetInfo() und NetUserGetGroups():
Code: Alles auswählen
EnableExplicit
#UserID = "DeineUserID"
Define *Buffer = AllocateMemory(1024)
Define *DCName
Define DCName.S
Define Entries.I
Define EntriesTotal.I
Define *Groups
Define i.I
Define *UserInfo.USER_INFO_3
If NetGetDCName_(0, 0, @*DCName) <> 0
MessageRequester("Fehler", "Die Namensabfrage des Domain Controllers ist fehlgeschlagen!", #MB_ICONERROR)
End
Else
DCName = PeekS(*DCName, -1, #PB_Unicode)
If Left(DCName, 2) = "\\"
DCName = Mid(dcname, 3)
EndIf
Debug "DCName = " + DCName
EndIf
PokeS(*Buffer, #UserID, -1, #PB_Unicode)
If NetUserGetInfo_(*DCName, *Buffer, 3, @*UserInfo) <> 0
MessageRequester("Fehler", "Die NetUserGetInfo-Abfrage ist fehlgeschlagen!", #MB_ICONERROR)
Else
Debug "Fullname = " + #DQUOTE$ + PeekS(*UserInfo\usri3_full_name, -1, #PB_Unicode) + #DQUOTE$
Debug "Comment = " + #DQUOTE$ + PeekS(*UserInfo\usri3_comment, -1, #PB_Unicode) + #DQUOTE$
Debug "Account expiration date = " + *UserInfo\usri3_acct_expires
Debug "Home directory = " + #DQUOTE$ + PeekS(*UserInfo\usri3_home_dir, -1, #PB_Unicode) + #DQUOTE$
Debug "Script path = " + #DQUOTE$ + PeekS(*UserInfo\usri3_script_path, -1, #PB_Unicode) + #DQUOTE$
Debug "Home drive = " + #DQUOTE$ + PeekS(*UserInfo\usri3_home_dir_drive, -1, #PB_Unicode) + #DQUOTE$
Debug "Password expiration date: " + *UserInfo\usri3_password_expired
Debug "Flags: " + *UserInfo\usri3_flags
Debug "Privilege: " + *UserInfo\usri3_priv
Debug "Logon hours: " + *UserInfo\usri3_logon_hours
If NetUserGetGroups_(*DCName, *Buffer, 0, @*Groups, -1, @Entries, @EntriesTotal) <> 0
MessageRequester("Fehler", "Die NetUserGetGroups-Abfrage ist fehlgeschlagen!", #MB_ICONERROR)
Else
Debug ""
Debug "Gruppenmitgliedschaften:"
Entries = (Entries * SizeOf(Integer)) - SizeOf(Integer)
For i = 0 To Entries Step SizeOf(Integer)
Debug "- " + PeekS(PeekI(*Groups + i), -1, #PB_Unicode)
Next
NetApiBufferFree_(*Groups)
EndIf
EndIf
Das folgende Beispiel zeigt, wie man mit der WLDAP32.DLL ein Attribut für eine User-ID in einem Active Directory ausliest, konkret als Beispiel das Attribut "PwdLastSet" (Datum der letzten Passwort-Änderung). Leider gehört die WLDAP32.Lib nicht zum Betriebssystemumfang von Windows. Ich habe sie mir aus dem Windows Platform SDK February 2003 extrahiert. Erfolgreich getestet habe ich dieses Beispiel mit PB 5.31 x86 unter Windows XP SP3 und Windows 8.1 x64 (vorher müssen die Konstanten #DCName, #SearchBase und der Pfad zur WLDAP32.Lib an die eigene Umgebung angepasst werden).
Code: Alles auswählen
EnableExplicit
#DCName = "10.11.12.13" ; <-- Name oder IP-Adresse des Domain Controllers
#Port = 389
#SearchBase = "DC=example,DC=de" ; <-- Name des Eintrags, an dem die Suche beginnen soll
#LDAP_AUTH_NEGOTIATE = $486
#LDAP_OPT_PROTOCOL_VERSION = $11
#LDAP_SCOPE_SUBTREE = $02
#LDAP_SUCCESS = 0
ImportC "X:\WLDAP\WLDAP32.Lib" ; <-- Pfad zur WLDAP32.Lib
ldap_bind_s(SessionHandle.I, DistinguishedName.S, *AuthCredentials, AuthMethod.I)
ldap_first_attribute(SessionHandle.I, *Entry, *Position)
ldap_first_entry(SessionHandle.I, *SearchResult)
ldap_get_values(SessionHandle.I, *Entry, *AttributeName)
ldap_init(HostName.S, PortNumber.I)
ldap_msgfree(*Msg)
ldap_next_attribute(SessionHandle.I, *Entry, *Position)
ldap_search_s(SessionHandle.I, DistinguishedName.S, Scope.I, Filter.S,
*AttributeArray, AttributesOnly.I, *SearchResult)
ldap_set_option(SessionHandle.I, Option.I, *OptionValue)
ldap_simple_bind_s(SessionHandle.I, UserName.S, Password.S)
ldap_unbind(SessionHandle.I)
EndImport
Procedure.S GetAttributeValue(UserID.S, AttributeName.S)
Protected *AttributeName
Protected AttributeValue.S
Protected *Entry
Protected LoginUserID.S
Protected Password.S
Protected *Position
Protected ProtocolVersion.I = 3
Protected Result.I
Protected SearchResult.I
Protected SessionHandle.I
Protected *Value
Protected *ValueList
; ----- Anmeldung am LDAP-Server durchführen
SessionHandle = ldap_init(#DCName, #Port)
If SessionHandle
; ----- LDAP-Protokollversion setzen
If ldap_set_option(SessionHandle, #LDAP_OPT_PROTOCOL_VERSION,
@ProtocolVersion) = #LDAP_SUCCESS
Result = ldap_bind_s(SessionHandle, "", 0, #LDAP_AUTH_NEGOTIATE)
If Result = #LDAP_SUCCESS
; ----- Gewünschte User-ID suchen und alle Attributnamen und -werte für
; diesen Eintrag einlesen
If ldap_search_s(SessionHandle, #SearchBase, #LDAP_SCOPE_SUBTREE,
"SAMAccountName=" + UserID, 0, #False, @SearchResult) = #LDAP_SUCCESS
*Entry = ldap_first_entry(SessionHandle, SearchResult)
*AttributeName = ldap_first_attribute(SessionHandle, *Entry,
@*Position)
; ----- Alle Attributnamen nach dem gewünschten Attributnamen
; durchsuchen
Result = #False
While *AttributeName
If UCase(PeekS(*AttributeName)) = UCase(AttributeName)
Result = #True
Break
EndIf
*AttributeName = ldap_next_attribute(SessionHandle, *Entry,
*Position)
Wend
; ----- Wenn der gewünschte Attributname gefunden wurde, den
; Attributwert auslesen
If Result
*ValueList = ldap_get_values(SessionHandle, *Entry, *AttributeName)
If *ValueList
*Value = PeekI(*ValueList)
If *Value
AttributeValue = PeekS(*Value)
EndIf
EndIf
EndIf
If SearchResult
ldap_msgfree(SearchResult)
EndIf
EndIf
EndIf
EndIf
ldap_unbind(SessionHandle)
EndIf
ProcedureReturn AttributeValue
EndProcedure
Define AttributeName.S = "PwdLastSet"
Define AttributeValue.S
Define FileTime.Q
Define LastPasswordChange.S
Define SystemTime.SYSTEMTIME
Define UserID.S = UserName()
AttributeValue = GetAttributeValue(UserName(), AttributeName)
If Trim(AttributeValue) = ""
MessageRequester("Fehler bei AD-Abfrage für " + UserID,
"Die Abfrage von Attribut '" + AttributeName + "' ist fehlgeschlagen!",
#MB_ICONEXCLAMATION)
Else
; ----- Attributwert im FILETIME-Format ins SYSTEMTIME-Format umwandeln und
; einen Ausgabe-String erstellen
FileTime = Val(AttributeValue)
If FileTimeToSystemTime_(@FileTime, @SystemTime)
LastPasswordChange = Str(SystemTime\wDay) + "." + Str(SystemTime\wMonth) +
"." + Str(SystemTime\wYear) + " " + Str(SystemTime\wHour) + ":" +
Str(SystemTime\wMinute)
MessageRequester("AD-Abfrage für " + UserID, AttributeName + " = " +
LastPasswordChange, #MB_ICONINFORMATION)
EndIf
EndIf
Ich selbst habe schon eine Reihe von Auswerteprogrammen mit LDAP-Zugriff über die WLDAP32.DLL auf das eDirectory von Novell geschrieben. Ein Beispiel von TeddyLM für den Zugriff auf die AD findet man
hier im englischen Forum.
Hier sind noch zwei Beispiele aus dem englischen Forum für den Einsatz von COMatePLUS: von Amundo (
Ermittlung aller Top Level Gruppen einer User-ID) und von em_uk (
Ermittlung der eMail-Adresse einer User-ID).
Amor_2001 hat geschrieben:Was ich über Comateplus gefunden habe, ist nur lesender Zugriff. Leider möchte/muss ich auch schreiben können.
Das mit dem Schreiben ist höchstens ein Rechte-Problem. Wenn Du selbst keine DC-Administratorrechte hast, wirst Du Dir die Rechte von Deinem DC-Administrator zuteilen lassen müssen, falls er überhaupt dazu bereit ist, denn mit DC-Administratorrechten steht Dir das komplette System offen wie ein Scheunentor...
