ich möchte mich von einem PC außerhalb meiner AD-DOMAIN am LDAP mit Benutzername und Kennwort anmelden und benötige die erweiterten Rückmeldungen wie z.B.:
525 - user not found
52e - invalid credentials
530 - not permitted to logon at this time
532 - password expired
533 - account disabled
701 - account expired
773 - user must reset password
um einen LDAP-CONNECT hinzubekommen, habe ich bislang drei Varianten gefunden:
1. per ADSDSOObject – dies gibt mir aber im Fehlerfall nicht die nötigen Infos zurück - ich hab zumindest keine Möglichkeit gefunden
2. per $objDSO.OpenDSObject – dies gibt mir ebenfalls keine erweiterten RETURN-Meldungen zurück - ich hab zumindest keine Möglichkeit gefunden
3. per DLLCALL auf die WLAPD32.DLL
hierzu habe ich mit folgenden Quellcode experimentiert
[autoit]
#include <array.au3>
#include <WinAPIError.au3>
#include <WINAPI.au3>
$oMyError = ObjEvent("AutoIt.Error", "ComError")
Global $objDSO = ObjGet ("LDAP:")
Global $Host = "xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx"
Global $Port = "389"
Global $fkt
Const $ADS_SECURE_AUTHENTICATION = 1
Const $ADS_USE_SEALING = 64 ;'0x40
Const $ADS_USE_SIGNING = 128 ;'0x80
Const $ADS_SERVER_BIND= 512 ;0x200
Const $LDAP_OPT_ERROR_NUMBER = 0x31
Const $LDAP_OPT_ERROR_STRING = 0x32
Const $LDAP_OPT_SERVER_ERROR = 0x33
Const $LDAP_OPT_SERVER_EXT_ERROR = 0x34
Const $LDAP_OPT_PROTOCOL_VERSION = 0x11
Const $LDAP_AUTH_NEGOTIATE = 0x0400
Const $LDAP_AUTH_DIGEST = 0x4000
Const $LDAP_AUTH_OTHERKIND = 0x86
Const $LDAP_AUTH_SIMPLE = 0x80
Const $LDAP_AUTH_NTLM = 0x01000
Const $SEC_WINNT_AUTH_IDENTITY_UNICODE = 0x2
Const $SEC_WINNT_AUTH_IDENTITY_ANSI = 0x1
Global $username = "username"
Global $Passwort = "secret"
Global $domain = "DOMAIN"
Global $ldapldll = DllOpen("WLDAP32.DLL")
[/autoit][autoit][/autoit][autoit]$ldapinit = ldapinit()
;errorpruefung($ldapinit, $fkt)
$ldapsetOption = ldap_set_option()
;errorpruefung($ldapsetOption, $fkt)
$ldapcon = ldap_simple_bind_s()
errorpruefung($ldapcon, $fkt)
$ldapgetoption = ldap_get_option()
errorpruefung($ldapcon, $fkt)
ldap_unbind()
DllClose("WLDAP32.DLL")
ConsoleWrite(@CRLF)
exit
Func ldapinit()
$Hostptr = DllStructCreate("char[" & (StringLen($Host) + 1) & "]")
DllStructSetData($Hostptr,1,$Host)
$fkt = "ldap_open"
Return DllCall($ldapldll, "ptr", $fkt, "ptr",DllStructGetPtr($Hostptr), "ULONG", "")
EndFunc
Func ldap_simple_bind_s()
$fkt = "ldap_simple_bind_s"
$dn = DllStructCreate("char[" & (StringLen($domain & "\" & $username) + 1) & "]")
DllStructSetData($dn,1, $domain & "\" & $username)
$passwd = DllStructCreate("char[" & (StringLen($Passwort) + 1) & "]")
DllStructSetData($passwd,1, $Passwort)
Return DllCall($ldapldll, "ULONG", $fkt, "ptr", $ldapinit[0], "ptr",DllStructGetPtr($dn), "ptr",DllStructGetPtr($passwd), "ULONG", $LDAP_AUTH_SIMPLE)
;_WinAPI_ShowError(Hex(_WinAPI_GetLastError()) & ": " & _WinAPI_GetLastErrorMessage())
;Return $ldapcon
EndFunc
Func ldap_get_option()
;If $ldapcon[0] <> 0 Then
$ldaperr = DllStructCreate("char[255]")
DllStructSetData($ldaperr,1, 0)
$fkt = "ldap_get_option"
$ergebnis = DllCall($ldapldll, "ULONG", $fkt, "ptr", $ldapinit[0], "int", $LDAP_OPT_SERVER_ERROR, "ptr", DllStructGetPtr($ldaperr))
;$fkt = "LdapGetLastError"
;$lasterror = DllCall($ldapldll, "ULONG", $fkt)
;errorpruefung($lasterror, $fkt)
;ConsoleWrite(Hex(_WinAPI_GetLastError()) & ": " & _WinAPI_GetLastErrorMessage())
$b = DllStructCreate("DWORD",DllStructGetPtr($ldaperr,1))
errorpruefung($ldaperr, $fkt)
errorpruefung($b, $fkt)
Return $ergebnis
;_ArrayDisplay($ergebnis)
;EndIf
EndFunc
Func ldap_set_option()
;If $ldapcon[0] <> 0 Then
$ldaperr = DllStructCreate("ULONG")
DllStructSetData($ldaperr,1, 3)
$fkt = "ldap_set_option"
;$ldaperr = 0
$ergebnis = DllCall($ldapldll, "ULONG", $fkt, "ptr", $ldapinit[0], "int", $LDAP_OPT_PROTOCOL_VERSION, "ptr", DllStructGetPtr($ldaperr))
If @error <> 0 Then ConsoleWrite(Hex(_WinAPI_GetLastError()) & ": " & _WinAPI_GetLastErrorMessage())
errorpruefung($ldaperr, $fkt)
Return $ergebnis
;_ArrayDisplay($ergebnis)
;EndIf
EndFunc
Func ldap_unbind()
$fkt = "ldap_unbind"
$ldapunbind = DllCall($ldapldll, "ULONG", $fkt, "ptr", $ldapinit[0])
EndFunc
;$ldapfree = DllStructCreate("char[" & (StringLen($LDAP_OPT_SERVER_ERROR) + 1) & "]")
;DllStructSetData($ldapfree,1, $LDAP_OPT_SERVER_ERROR)
;$fkt = "ldap_memfree"
;DllCall($ldapldll, "ptr", $fkt, "ptr", DllStructGetPtr($ldapfree))
;$fkt = "LdapGetLastError"
;$lasterror = DllCall($ldapldll, "ULONG", $fkt)
;errorpruefung($lasterror, $fkt)
Func errorpruefung($ID, $Name = "")
If IsArray($ID) THEN
ConsoleWrite(@CRLF & $Name & " ")
For $I = 0 To UBound($ID)-1
ConsoleWrite(@CRLF & $I & ": " & $ID[$I] & " - " & hex($ID[$I],8) & " - " & dec(hex($ID[$I],8)) & " " & DllStructGetData($ID, $I))
Next
ConsoleWrite(@CRLF)
;_ArrayDisplay($ID)
Else
ConsoleWrite(@CRLF & $Name & " " & DllStructGetData($ID, 1) & " - " & hex(DllStructGetData($ID, 1),8) & " " & DllStructGetData($ID, 2) & " - " & hex(DllStructGetData($ID, 2),8) & @CRLF)
EndIf
EndFunc
Func ComError()
if IsObj($oMyError) then
$Fehlertext = ("Name: " & @TAB & $oMyError.description & @CRLF & _
"Beschreibung: " & @TAB & $oMyError.windescription & @CRLF & _
"Fehlernummer: " & @TAB & hex($oMyError.number,8) & @CRLF & _
"Fehlernummer1: " & @TAB & $oMyError.number & @CRLF & _
"Letzter Fehler: " & @TAB & $oMyError.lastdllerror & @CRLF & _
"Zeile: " & @TAB & $oMyError.scriptline & @CRLF & _
"Quelle: " & @TAB & $oMyError.source & @CRLF & _
"err.helpfile is: " & @TAB & $oMyError.helpfile & @CRLF & _
"err.helpcontext is: " & @TAB & $oMyError.helpcontext )
SetError($Fehlertext)
ConsoleWrite(@CRLF & $Fehlertext & @CRLF)
;SetError(Hex($oError.Number))
else
SetError(1)
endif
EndFunc
- bei Eingabe eines richtigen Usernamens + Kennwort bekomme ich ERROR 0x0 zurück – also alles OK.
- bei Falscheingabe bekomme ich ERROR 0x31 zurück – also LDAP_INVALID_CREDENTIALS – also auch OK.
Wenn ich nun ldap_get_option mit LDAP_OPT_SERVER_ERROR abfrage, bekomme ich leider keine auswertbare Antwort – die letzen 4 HEX-Werte sind immer 1828, egal, ob der Benutzer nicht existiert oder das Passwort falsch ist oder der Benutzer deaktiviert wurde oder oder… Ich bekomme auch keinen String zurück, sondern nur einen HEX-Wert
Wie komme ich zu dem erweiterten Rückgabestring, der z.B. bei Java oder PHP so aussieht:
javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 525, v893
Hier steht fast ganz hinten der Wert 525 - also in dem Bsp. User not found
Die Microsoftseiten sind z.B. hier für ldap_get_option und hier für LDAP_OPT_SERVER_ERROR
Ich muss nicht mit DLL-CALL arbeiten, ich benötige nur den erweiterten Rückgabestring in AUTOIT. Gibt’s noch andere Methoden, mit AUTOIT auf LDAP von extern zuzugreifen UND den erweiterten Rückgabestring zu bekommen?
Der LDAP-Server muss die Antwort geben, da ein Linux-System von unserem LDAP auch die Antwort bekommt.
Mir scheint hier, daß ich ein Problem habe, den TCHAR-Rückgabestring auszuwerten - an den komm ich einfach nicht ran...
Ich bitte um Hilfe…
Sorry, wenn mein Quellcode nicht gleich verständlich ist - ich bin Anfänger auf dem Gebiet DLLCall - das ist alles mein Werk der letzten 5 verzweifelten Tage...