i needed a few functions to get informations from Active Directory.
Maybe it can be of use for someone else.
(A connection with SSL-encryption is strongely recommended - if available)
A+
TeddyLM
Code: Select all
#LDAP_PORT = 389
#LDAP_SSL_PORT = 636
#LDAP_SCOPE_BASE = 0 ;Searches the base entry only.
#LDAP_SCOPE_ONELEVEL = 1 ;Searches all entries in the first level below the base entry, excluding the base entry.
#LDAP_SCOPE_SUBTREE = 2 ;Searches the base entry and all entries in the tree below the base.
#LDAP_OPT_ON = 1
#LDAP_OPT_TIMELIMIT = 4 ;A limit on the number of seconds the server will wait To complete a bind. This also specifies the limit on the number of seconds the server spends on a search.
#LDAP_OPT_SIZELIMIT = 3 ;The limit on the number of entries To Return from a search.
#LDAP_OPT_SSL = 10
#LDAP_OPT_PROTOCOL_VERSION = 17
#LDAP_AUTH_SIMPLE = 128
#LDAP_OPT_SERVER_CERTIFICATE = 129
#LDAP_SUCCESS = 0 ;The call completed successfully.
PrototypeC.i Proto_ldap_getlasterror()
PrototypeC.i Proto_ldap_memfree(Block.l)
PrototypeC.i Proto_ldap_sslinit(Domainname$, PortNumber.l, Secure.l=#True)
PrototypeC.i Proto_ldap_init(Domainname$, PortNumber.l)
PrototypeC.i Proto_ldap_simple_bind(ld.l, Username$, Password$)
PrototypeC.i Proto_ldap_unbind(ld.l)
PrototypeC.i Proto_ldap_setoption(ld.l, option.l, invalue.l)
PrototypeC.i Proto_ldap_getoption(ld.l, option.l, outvalue.l)
PrototypeC.i Proto_ldap_search(ld.l, Base$, Scope.l, Filter$, Attrs.l, AttrsOnly.l, Result.l)
PrototypeC.i Proto_ldap_countentries(ld.l, res.l)
PrototypeC.i Proto_ldap_firstentry(ld.l, res.l)
PrototypeC.i Proto_ldap_nextentry(ld.l, res.l)
PrototypeC.i Proto_ldap_getdn(ld.l, entry.l)
PrototypeC.i Proto_ldap_firstattribute(ld.l, entry.l, ptr.l)
PrototypeC.i Proto_ldap_Nextattribute(ld.l, entry.l, ptr.l)
PrototypeC.i Proto_ldap_getvaluesstring(ld.l, entry.l, attr.l)
PrototypeC.i Proto_ldap_valuefree(vals.l)
PrototypeC.i Proto_ldap_getvaluesbinary(ld.l, entry.l, attr.l)
PrototypeC.i Proto_ldap_valuefreelen(vals.l)
PrototypeC.i Proto_ldap_countvalues(vals.l)
LibNr.i = OpenLibrary(#PB_Any, "wldap32.dll")
If LibNr
CompilerSelect #PB_Compiler_Unicode
CompilerCase 0
Global LdapGetLastError.Proto_ldap_getlasterror = GetFunction(LibNr, "LdapGetLastError")
Global LdapMemFree.Proto_ldap_memfree = GetFunction(LibNr, "Ldap_memfreeA")
Global LdapSslInit.Proto_ldap_sslinit = GetFunction(LibNr, "ldap_sslinitA")
Global LdapInit.Proto_ldap_init = GetFunction(LibNr, "ldap_initA")
Global LdapBind.Proto_ldap_simple_bind = GetFunction(LibNr, "ldap_simple_bind_sA")
Global LdapUnbind.Proto_ldap_unbind = GetFunction(LibNr, "ldap_unbind_s")
Global LdapSetOption.Proto_ldap_setoption = GetFunction(LibNr, "ldap_set_optionA")
Global LdapGetOption.Proto_ldap_getoption = GetFunction(LibNr, "ldap_get_option")
Global LdapSearch.Proto_ldap_search = GetFunction(LibNr, "ldap_search_sA")
Global LdapCountEntries.Proto_ldap_countentries = GetFunction(LibNr, "ldap_count_entries")
Global LdapFirstEntry.Proto_ldap_firstentry = GetFunction(LibNr, "ldap_first_entry")
Global LdapNextEntry.Proto_ldap_nextentry = GetFunction(LibNr, "ldap_next_entry")
Global LdapGetDN.Proto_ldap_getdn = GetFunction(LibNr, "ldap_get_dnA")
Global LdapFirstAttribute.Proto_ldap_firstattribute = GetFunction(LibNr, "ldap_first_attributeA")
Global LdapNextAttribute.Proto_ldap_nextattribute = GetFunction(LibNr, "ldap_next_attributeA")
Global LdapGetValuesString.Proto_ldap_getvaluesstring = GetFunction(LibNr, "ldap_get_valuesA")
Global LdapValueFree.Proto_ldap_valuefree = GetFunction(LibNr, "ldap_value_freeA")
Global LdapGetValuesBinary.Proto_ldap_getvaluesbinary = GetFunction(LibNr, "ldap_get_values_lenA")
Global LdapValueFreeLen.Proto_ldap_valuefreelen = GetFunction(LibNr, "ldap_value_free_len")
Global LdapCountValues.Proto_ldap_countvalues = GetFunction(LibNr, "ldap_count_valuesA")
CompilerCase 1
Global LdapGetLastError.Proto_ldap_getlasterror = GetFunction(LibNr, "LdapGetLastError")
Global LdapMemFree.Proto_ldap_memfree = GetFunction(LibNr, "Ldap_memfreeW")
Global LdapSslInit.Proto_ldap_sslinit = GetFunction(LibNr, "ldap_sslinitW")
Global LdapInit.Proto_ldap_init = GetFunction(LibNr, "ldap_initW")
Global LdapBind.Proto_ldap_simple_bind = GetFunction(LibNr, "ldap_simple_bind_sW")
Global LdapUnbind.Proto_ldap_unbind = GetFunction(LibNr, "ldap_unbind_s")
Global LdapSetOption.Proto_ldap_setoption = GetFunction(LibNr, "ldap_set_optionW")
Global LdapGetOption.Proto_ldap_getoption = GetFunction(LibNr, "ldap_get_optionW")
Global LdapSearch.Proto_ldap_search = GetFunction(LibNr, "ldap_search_sW")
Global LdapCountEntries.Proto_ldap_countentries = GetFunction(LibNr, "ldap_count_entries")
Global LdapFirstEntry.Proto_ldap_firstentry = GetFunction(LibNr, "ldap_first_entry")
Global LdapNextEntry.Proto_ldap_nextentry = GetFunction(LibNr, "ldap_next_entry")
Global LdapGetDN.Proto_ldap_getdn = GetFunction(LibNr, "ldap_get_dnW")
Global LdapFirstAttribute.Proto_ldap_firstattribute = GetFunction(LibNr, "ldap_first_attributeW")
Global LdapNextAttribute.Proto_ldap_nextattribute = GetFunction(LibNr, "ldap_next_attributeW")
Global LdapGetValuesString.Proto_ldap_getvaluesstring = GetFunction(LibNr, "ldap_get_valuesW")
Global LdapValueFree.Proto_ldap_valuefree = GetFunction(LibNr, "ldap_value_freeW")
Global LdapGetValuesBinary.Proto_ldap_getvaluesbinary = GetFunction(LibNr, "ldap_get_values_lenW")
Global LdapValueFreeLen.Proto_ldap_valuefreelen = GetFunction(LibNr, "ldap_value_free_len")
Global LdapCountValues.Proto_ldap_countvalues = GetFunction(LibNr, "ldap_count_valuesW")
CompilerEndSelect
Else
MessageRequester("Error", "Unable to open the LDAP library", 16) : End
EndIf
;UseJPEGImageDecoder()
Global NewList LDAP_ENTRIES.i()
Global NewList LDAP_ATTRIBUTES.s()
Global NewList LDAP_VALUES.s()
;========================================
;========================================
;========================================
Procedure.i LDAP_CONNECT(Domainname$, Username$, Password$, SecuredConnection.i=#True, PortNr.i=0)
*LDAP_HANDLE = 0
;INITIALIZE A SESSION WITH A LDAP SERVER
Select SecuredConnection
Case #True
If PortNr = 0 : PortNr = #LDAP_SSL_PORT : EndIf
*LDAP_HANDLE = LdapSslInit(Domainname$, PortNr)
Default
If PortNr = 0 : PortNr = #LDAP_PORT : EndIf
*LDAP_HANDLE = LdapInit(Domainname$, PortNr)
EndSelect
;AUTHENTICATE THE CLIENT TO THE LDAP SERVER
If *LDAP_HANDLE
If LdapBind(*LDAP_HANDLE, Username$, Password$) <> -1
;SET LDAP OPTIONS
LDAPVersion.l = 3 : LdapSetOption(*LDAP_HANDLE, #LDAP_OPT_PROTOCOL_VERSION, @Version)
TimeOut.i = 120 : LdapSetOption(*LDAP_HANDLE, #LDAP_OPT_TIMELIMIT, @TimeOut)
SizeLimit.i = 1000 : LdapSetOption(*LDAP_HANDLE, #LDAP_OPT_SIZELIMIT, @SizeLimit)
;FOR SECURED SESSION ONLY
If SecuredConnection = #True
;CHECK IF SSL IS ENABLED OTHERWISE ENABLE IT
SSL.l = 0
If LdapGetOption(*LDAP_HANDLE, #LDAP_OPT_SSL, @SSL) = #LDAP_SUCCESS
If SSL <> 1
Value.l = 1
LdapSetOption(*LDAP_HANDLE, #LDAP_OPT_SSL, @Value)
LdapGetOption(*LDAP_HANDLE, #LDAP_OPT_SSL, @SSL)
EndIf
EndIf
;STOP IF SSL IS NOT ENABLED
If SSL = 0
MessageRequester("Error", "SSL cound not be enabled.", 16) : End
Else
Result = #True
EndIf
EndIf
Else
MessageRequester("Error", "Unable to bind to the server.", 16)
EndIf
Else
MessageRequester("Error", "Incorrect LDAP session handle.", 16)
EndIf
ProcedureReturn *LDAP_HANDLE
EndProcedure
;========================================
Procedure.i LDAP_DISCONNECT(*LDAP_HANDLE)
If *LDAP_HANDLE : LdapUnbind(*LDAP_HANDLE) : EndIf
EndProcedure
;========================================
Procedure.i LDAP_GET_ENTRIES(*LDAP_HANDLE, Base$, Filter$, Scope.i)
ClearList(LDAP_ENTRIES())
If *LDAP_HANDLE
;SEARCH THE LDAP DIRECTORY FOR ENTRIES THAT MATCH THE 'SEARCH SCOPE' AND 'SEARCH FILTER'
If LdapSearch(*LDAP_HANDLE, Base$, Scope, Filter$, 0, 0, @*LDAP_RESULT) = #LDAP_SUCCESS
If *LDAP_RESULT
*LDAP_ENTRY = LdapFirstEntry(*LDAP_HANDLE, *LDAP_RESULT)
AddElement(LDAP_ENTRIES()) : LDAP_ENTRIES() = *LDAP_ENTRY
While *LDAP_ENTRY
*LDAP_ENTRY = LdapNextEntry(*LDAP_HANDLE, *LDAP_ENTRY)
If *LDAP_ENTRY : AddElement(LDAP_ENTRIES()) : LDAP_ENTRIES() = *LDAP_ENTRY : EndIf
Wend
EndIf
Else
MessageRequester("Error", "Unable to search for entries.", 16)
EndIf
Else
MessageRequester("Error", "Incorrect LDAP session handle.", 16)
EndIf
ProcedureReturn ListSize(LDAP_ENTRIES())
EndProcedure
;========================================
Procedure.s LDAP_GET_DISTINGUISHEDNAME(*LDAP_HANDLE, *LDAP_ENTRY)
If *LDAP_HANDLE
If *LDAP_ENTRY
*DN = LdapGetDN(*LDAP_HANDLE, *LDAP_ENTRY)
If *DN
ProcedureReturn PeekS(*DN)
EndIf
Else
MessageRequester("Error", "Incorrect result entry.", 16)
EndIf
Else
MessageRequester("Error", "Incorrect LDAP session handle.", 16)
EndIf
EndProcedure
;========================================
Procedure.i LDAP_GET_ATTRIBUTES(*LDAP_HANDLE, *LDAP_ENTRY)
ClearList(LDAP_ATTRIBUTES())
If *LDAP_HANDLE
If *LDAP_ENTRY
*BerElement = 0
*LDAP_ATTRIBUTE = LdapFirstAttribute(*LDAP_HANDLE, *LDAP_ENTRY, @*BerElement)
If *LDAP_ATTRIBUTE
AddElement(LDAP_ATTRIBUTES()) : LDAP_ATTRIBUTES() = PeekS(*LDAP_ATTRIBUTE)
While *LDAP_ATTRIBUTE And *BerElement
*LDAP_ATTRIBUTE = LdapNextAttribute(*LDAP_HANDLE, *LDAP_ENTRY, *BerElement)
If *LDAP_ATTRIBUTE
AddElement(LDAP_ATTRIBUTES()) : LDAP_ATTRIBUTES() = PeekS(*LDAP_ATTRIBUTE)
EndIf
Wend
EndIf
Else
MessageRequester("Error", "Incorrect result entry.", 16)
EndIf
Else
MessageRequester("Error", "Incorrect LDAP session handle.", 16)
EndIf
ProcedureReturn ListSize(LDAP_ATTRIBUTES())
EndProcedure
;========================================
Procedure.i LDAP_GET_VALUES_STR(*LDAP_HANDLE, *LDAP_ENTRY, Attributename$)
ClearList(LDAP_VALUES())
Attributename$ = UCase(Attributename$)
If *LDAP_HANDLE
If *LDAP_ENTRY
*BerElement = 0
*LDAP_ATTRIBUTE = LdapFirstAttribute(*LDAP_HANDLE, *LDAP_ENTRY, @*BerElement)
While *BerElement And *LDAP_ATTRIBUTE
If UCase(PeekS(*LDAP_ATTRIBUTE)) = Attributename$
*ValueArray = LdapGetValuesString(*LDAP_HANDLE, *LDAP_ENTRY, *LDAP_ATTRIBUTE)
If *ValueArray
NbrValues.i = LdapCountValues(*ValueArray)
If NbrValues
For counter = 0 To (NbrValues*4)-1 Step 4
Debug PeekL(*ValueArray + counter)
AddElement(LDAP_VALUES()) : LDAP_VALUES() = PeekS(PeekL(*ValueArray + counter))
Next
EndIf
LdapValueFree(*ValueArray)
EndIf
EndIf
*LDAP_ATTRIBUTE = LdapNextAttribute(*LDAP_HANDLE, *LDAP_ENTRY, *BerElement)
Wend
Else
MessageRequester("Error", "Incorrect result entry.", 16)
EndIf
Else
MessageRequester("Error", "Incorrect LDAP session handle.", 16)
EndIf
ProcedureReturn ListSize(LDAP_VALUES())
EndProcedure
;========================================
Procedure.i LDAP_GET_VALUES_BIN(*LDAP_HANDLE, *LDAP_ENTRY, Attributename$)
ClearList(LDAP_VALUES())
Attributename$ = UCase(Attributename$)
If *LDAP_HANDLE
If *LDAP_ENTRY
*BerElement = 0
*LDAP_ATTRIBUTE = LdapFirstAttribute(*LDAP_HANDLE, *LDAP_ENTRY, @*BerElement)
While *BerElement And *LDAP_ATTRIBUTE
If UCase(PeekS(*LDAP_ATTRIBUTE)) = Attributename$
*BerElementValArray = LdapGetValuesBinary(*LDAP_HANDLE, *LDAP_ENTRY, *LDAP_ATTRIBUTE)
If *BerElementValArray
NbrValues.i = LdapCountValues(*BerElementValArray)
If NbrValues
For counter = 0 To (NbrValues*8)-1 Step 8
OffsetBerval.i = PeekL(*BerElementValArray + counter)
Length.i = PeekL(OffsetBerval)
*Pointer = PeekL(OffsetBerval + 4)
If Length And *Pointer
*Buffer = AllocateMemory(Length)
If *Buffer
CopyMemory(*Pointer, *Buffer, Length)
AddElement(LDAP_VALUES()) : LDAP_VALUES() = Str(*Buffer) + ";" + Str(Length)
EndIf
EndIf
Next
Ldapvaluefreelen(*BerElementValArray)
EndIf
EndIf
EndIf
*LDAP_ATTRIBUTE = LdapNextAttribute(*LDAP_HANDLE, *LDAP_ENTRY, *BerElement)
Wend
Else
MessageRequester("Error", "Incorrect result entry.", 16)
EndIf
Else
MessageRequester("Error", "Incorrect LDAP session handle.", 16)
EndIf
ProcedureReturn ListSize(LDAP_VALUES())
EndProcedure
;========================================
;========================================
;========================================
Domainname$ = "xxxx"
Username$ = "xxxx"
Password$ = "xxxx"
Base$ = "dc=xxxx,dc=xxxx"
;Base$ = "ou=xxxx,dc=xxxx,dc=xxxx"
Scope.i = #LDAP_SCOPE_SUBTREE
Filter$ = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=e*))" ;All users with username starting with e
;Filter$ = "(&(objectCategory=person)(objectClass=user))" ;All users
;Filter$ = "(&(objectCategory=person)(objectClass=user)(cn=schm*))" ;All users with CN starting with schm...
;Filter$ = "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))" ;All users with "Password Never Expires" set
;Filter$ = "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))" ;All disabled user objects
;Filter$ = "(&(objectCategory=person)(objectClass=user)(accountExpires>=1)(accountExpires<=9223372036854775806))" ;Users with accounts that do expire
;Filter$ = "(&(objectCategory=person)(objectClass=user)(pwdLastSet=0))" ;All users that must change their password at next logon
;Filter$ = "(&(objectClass=user)(!lockoutTime>=1)(lockoutDuration=*))"
;Filter$ = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=a*)(lockoutTime>=1))"
;Filter$ = "(&(objectCategory=person)(objectClass=user)(lockoutTime>=1))" ;All users with locked account
;Filter$ = "(&(objectCategory=person)(objectClass=user)(thumbnailPhoto=*))" ;All users with photo
*LDAP_HANDLE = LDAP_CONNECT(Domainname$, Username$, Password$, #True) ;#True=SSL-encryption #False=NoEncryption
If *LDAP_HANDLE
LDAP_GET_ENTRIES(*LDAP_HANDLE, Base$, Filter$, Scope)
ForEach LDAP_ENTRIES()
;=============
;This function returns the DN for the current entry
DN$ = LDAP_GET_DISTINGUISHEDNAME(*LDAP_HANDLE, LDAP_ENTRIES())
Debug DN$
;=============
; ;This function returns a list of available attributes for the current entry
; LDAP_GET_ATTRIBUTES(*LDAP_HANDLE, LDAP_ENTRIES())
; ForEach LDAP_ATTRIBUTES() : Debug LDAP_ATTRIBUTES() : Next
;=============
; ;This function returns a list of string values for the provided attribute for the current entry
; LDAP_GET_VALUES_STR(*LDAP_HANDLE, LDAP_ENTRIES(), "memberof")
; ForEach LDAP_VALUES() : Debug LDAP_VALUES() : Next
;=============
; ;This function allocates a buffer for each binary value for the provided attribute for the current entry and returns the list of Bufferaddr and Bufferlength as a semicolon separated string.
; ;DON'T FORGET TO FREE THE BUFFERS AS SOON AS THEY ARE NOT NEEDED ANYMORE
; LDAP_GET_VALUES_BIN(*LDAP_HANDLE, LDAP_ENTRIES(), "thumbnailPhoto")
; ForEach LDAP_VALUES() : Debug LDAP_VALUES()
;
; ; EXAMPLE WITH THE ATTRIBUTE 'thumbnailPhoto' (JPEG)
; *Buffer = Val(StringField(LDAP_VALUES(),1,";"))
; Length = Val(StringField(LDAP_VALUES(),2,";"))
; If *Buffer
; If CatchImage(0, *Buffer)
; If OpenWindow(0, 0, 0, ImageWidth(0), ImageHeight(0), "thumbnailPhoto", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
; ImageGadget(0, 0, 0, ImageWidth(0), ImageHeight(0), ImageID(0))
; Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
; EndIf
; EndIf
; FreeMemory(*Buffer)
; EndIf
;
; Next
;=============
Next
LDAP_DISCONNECT(*LDAP_HANDLE)
EndIf
FreeList(LDAP_ENTRIES.i())
FreeList(LDAP_ATTRIBUTES.s())
FreeList(LDAP_VALUES.s())
End