Page 1 of 1

[SOLVED] LDAP and ComatePlus

Posted: Fri Jan 28, 2011 6:43 pm
by em_uk
*sob sob sob*

Ok, I just cannot get my head around this at all. Can someone please help me out and tell me how I can get info from Active Directory/LDAP from within COMatePLUS. I have seen other examples on the site but they no longer work with the current versions.

If someone could start me off, I would then be able to figure out the rest. For example, how would I achieve the following with COMatePLUS :

Code: Select all

Set objUser = GetObject _
("LDAP://CN=Dude,OU=Users,OU=LOP,OU=UK,DC=WAGGLE,DC=intranet")
objUser.GetInfo

strMail = objUser.Get("mail")
WScript.Echo "Email: " & objUser.mail 
I have managed to figure out using COMatePLUS with WMI, but with AD... It's just too hard for me!!

Re: LDAP and ComatePlus

Posted: Mon Jan 31, 2011 12:00 pm
by em_uk
Ah haaa!!

Managed to chop and slap some code together that seems to work! :

Code: Select all

XIncludeFile "COMatePLUS.pbi"
XIncludeFile "VariantHelper_Include.pb"
EnableExplicit
Define.COMateObject oConnection, oDSE
Define.s sDNSDomain, sHostServer, sConfiguration, email
#False = 0
#True = 1
#ADS_SCOPE_SUBTREE = 2

Declare.s ADGetUserGroups(user$ = "")


oConnection = COMate_CreateObject("ADODB.Connection")

If oConnection
  oConnection\SetProperty("Provider='ADsDSOObject;'")
  oConnection\invoke("Open('Active Directory Provider')")
  oDSE = COMate_GetObject("LDAP://RootDSE")
  If oDSE
    sHostServer = oDSE\GetStringProperty("dnsHostName")
    sConfiguration = oDSE\GetStringProperty("ConfigurationNamingContext")
    sDNSDomain = oDSE\GetStringProperty("defaultNamingContext")
   Debug ADGetUserGroups("") ; leave blank for current user
    oDSE\Release()
  EndIf
  oConnection\Release()
EndIf


Procedure.s ADGetUserGroups( user$ = "")

  If user$=""
    user$ = GetEnvironmentVariable("USERNAME")
  EndIf
  Shared sHostServer, sDNSDomain, oConnection, email
  user$=LTrim(user$)
  user$ = ReplaceString(user$, "cn=", "",#PB_String_NoCase,1)
  Protected query$, recordCount, member
  Protected.COMateObject oRecordSet, oFields, oValue, oUser, oEnum
  query$ = "<LDAP://" + sHostServer + "/" + sDNSDomain + ">;(sAMAccountName=" + user$ + ");ADsPath;subtree"

  If oConnection
    oRecordSet = oConnection\GetObjectProperty("Execute('" + query$ + "')")

    If oRecordSet
      recordCount = oRecordSet\GetIntegerProperty("RecordCount")

      If recordCount
        oFields = oRecordSet\GetObjectProperty("fields(0)")

        If oFields
          Protected Value$ = oFields\GetStringProperty("value")

          oUser = COMate_GetObject(Value$)

          If oUser

            email=oUser\GetStringProperty("mail")

            oUser\Release()
          EndIf
          oFields\Release()
        EndIf
      EndIf
      oRecordSet\Release()
      ;ProcedureReturn recordCount
    Else
      ; problem querying AD
      ;ProcedureReturn 0
    EndIf
  Else
    ; problem with AD connection
   ; ProcedureReturn 0
  EndIf
  
  ProcedureReturn email
EndProcedure

Re: LDAP and ComatePlus

Posted: Mon Jan 31, 2011 12:54 pm
by flaith
Thanks for the code :D
For me it works if i use mail instead of Email :

Code: Select all

email=oUser\GetStringProperty("mail")

Re: LDAP and ComatePlus

Posted: Mon Jan 31, 2011 1:10 pm
by em_uk
Oops - I changed that at the last minute, fixed.

All other object properties can be retrieved in the same way.

Must give thanks to the person who originally did most of the code.

Orginal post here : http://www.purebasic.fr/english/viewtop ... dap+comate

Re: [SOLVED] LDAP and ComatePlus

Posted: Mon Jan 31, 2011 2:38 pm
by flaith
Thanks again for the code, if you don't mind, i've just added info about getting last logon :wink:

Code: Select all

IncludePath #PB_Compiler_Home+"Includes"
XIncludeFile "COMatePLUS.pbi"
XIncludeFile "VariantHelper_Include.pb"
EnableExplicit
Define.COMateObject oConnection, oDSE
Define.s sDNSDomain, sHostServer, sConfiguration, email
#False = 0
#True = 1
#ADS_SCOPE_SUBTREE = 2

Structure CS_SYSTEMTIME
	wYear.w
	wMonth.w
	wDayOfWeek.w
	wDay.w
	wHour.w
	wMinute.w
	wSecond.w
	wMilliseconds.w
EndStructure

Global LocalSystemTime.CS_SYSTEMTIME, LocalTime.CS_SYSTEMTIME

Declare.s ADGetUserGroups(user$ = "")


oConnection = COMate_CreateObject("ADODB.Connection")

If oConnection
  oConnection\SetProperty("Provider='ADsDSOObject;'")
  oConnection\invoke("Open('Active Directory Provider')")
  oDSE = COMate_GetObject("LDAP://RootDSE")
  If oDSE
    sHostServer = oDSE\GetStringProperty("dnsHostName")
    sConfiguration = oDSE\GetStringProperty("ConfigurationNamingContext")
    sDNSDomain = oDSE\GetStringProperty("defaultNamingContext")
    Debug ADGetUserGroups("") ; leave blank for current user
    oDSE\Release()
  Else
    Debug "No LDAP !!!"
  EndIf
  oConnection\Release()
EndIf


Procedure.s ADGetUserGroups( user$ = "")

  If user$=""
    user$ = GetEnvironmentVariable("USERNAME")
  EndIf

  Shared sHostServer, sDNSDomain, oConnection, email
  user$=LTrim(user$)
  user$ = ReplaceString(user$, "cn=", "",#PB_String_NoCase,1)
  Protected query$, recordCount, member
  Protected.q LastLogon
  Protected.COMateObject oRecordSet, oFields, oValue, oUser, oEnum, oLastLogon
  query$ = "<LDAP://" + sHostServer + "/" + sDNSDomain + ">;(sAMAccountName=" + user$ + ");ADsPath;subtree"

  If oConnection
    oRecordSet = oConnection\GetObjectProperty("Execute('" + query$ + "')")

    If oRecordSet
      recordCount = oRecordSet\GetIntegerProperty("RecordCount")

      If recordCount
        oFields = oRecordSet\GetObjectProperty("fields(0)")

        If oFields
          Protected Value$ = oFields\GetStringProperty("value")

          oUser = COMate_GetObject(Value$)
          If oUser
            oLastLogon = oUser\GetObjectProperty("lastLogon"); same with "lastLogonTimestamp")
            If oLastLogon
              LastLogon = oLastLogon\GetIntegerProperty("HighPart") * Pow(2,32) + oLastLogon\GetIntegerProperty("LowPart")
              FileTimeToLocalFileTime_(@Lastlogon, @LocalSystemTime)
              If LocalSystemTime <> 0
                FileTimeToSystemTime_(@LocalSystemTime, @LocalTime)
                Debug "LastLogOn : "+Str(LocalTime\wDay)+"/"+Str(Localtime\wMonth)+"/"+Str(Localtime\wYear)
                Debug "       at : "+Str(Localtime\wHour)+":"+Str(Localtime\wMinute)+":"+Str(Localtime\wSecond)
              EndIf
              oLastLogon\Release()
            EndIf
            email=oUser\GetStringProperty("mail")
            oUser\Release()
          EndIf
          oFields\Release()
        EndIf
      EndIf
      oRecordSet\Release()
      ;ProcedureReturn recordCount
    Else
      ; problem querying AD
      ;ProcedureReturn 0
    EndIf
  Else
    ; problem with AD connection
   ; ProcedureReturn 0
  EndIf
 
  ProcedureReturn email
EndProcedure

Re: [SOLVED] LDAP and ComatePlus

Posted: Mon Jan 31, 2011 5:59 pm
by em_uk
Cool. I am going to update the first post with something a little more modular if people want me to.

cheers

Re: [SOLVED] LDAP and ComatePlus

Posted: Mon Jan 31, 2011 9:11 pm
by srod
Might be worth taking a look at ADOmate; see if that can help in this case?

Re: [SOLVED] LDAP and ComatePlus

Posted: Mon Jan 31, 2011 10:32 pm
by flaith
srod wrote:Might be worth taking a look at ADOmate; see if that can help in this case?
As i'm using APIs for getting Groups in AD (http://www.purebasic.fr/english/viewtopic.php?p=304878)
If ADOMate can help, of course :D (i'll find a way to do it)

Re: [SOLVED] LDAP and ComatePlus

Posted: Tue Feb 01, 2011 1:46 am
by em_uk
This was the original code I chopped up to get my result. http://www.purebasic.fr/english/viewtop ... ingContext+ by Amundo

It works really well for getting groups.

Code: Select all

EnableExplicit

IncludePath #PB_Compiler_Home + "INCLUDES\"
XIncludeFile "COMatePLUS.pbi"
XIncludeFile "VariantHelper_Include.pb"

#False = 0
#True = 1
#ADS_SCOPE_SUBTREE = 2

Declare ADObjectExists(object$, property$ = "sAMAccountName")
Declare ADGetUserGroups(Array group$(1), user$ = "")

Define.COMateObject oConnection, oDSE
Define.s sDNSDomain, sHostServer, sConfiguration

oConnection = COMate_CreateObject("ADODB.Connection")
Debug "COMate_CreateObject('ADODB.Connection')=" + COMate_GetLastErrorDescription()

If oConnection
  oConnection\SetProperty("Provider='ADsDSOObject;'")
  Debug "oConnection\SetProperty('Provider = ADsDSOObject')=" + COMate_GetLastErrorDescription()
 
  oConnection\invoke("Open('Active Directory Provider')")
  Debug "oConnection\invoke('Open('Active Directory Provider'')=" + COMate_GetLastErrorDescription()
 
  oDSE = COMate_GetObject("LDAP://RootDSE")
  Debug "COMate_GetObject('LDAP://RootDSE')=" + COMate_GetLastErrorDescription()
  If oDSE
    sHostServer = oDSE\GetStringProperty("dnsHostName")
    Debug "oDSE\GetStringProperty('dnsHostName')=" + sHostServer
    sConfiguration = oDSE\GetStringProperty("ConfigurationNamingContext")
    Debug "oDSE\GetStringProperty('ConfigurationNamingContext')=" + sConfiguration
    sDNSDomain = oDSE\GetStringProperty("defaultNamingContext")
    Debug "oDSE\GetStringProperty('defaultNamingContext')=" + sDNSDomain
   
    Dim userGroups$(10)
    Debug "ADGetUserGroups="+Hex(ADGetUserGroups(userGroups$(), "stowera"))
    Debug "after ArraySize(userGroups$())="+ Str(ArraySize(userGroups$()))
    Define i
    For i = 0 To ArraySize(userGroups$())-1
      Debug "Group "+Str(i)+": "+userGroups$(i)
    Next i
    oDSE\Release()
  EndIf
  oConnection\Release()
EndIf

End

Procedure ADObjectExists(object$, property$ = "sAMAccountName")
  ; return >0 if object exists, 0 otherwise
  Shared sHostServer, sDNSDomain, oConnection
  object$=LTrim(object$)
  object$ = ReplaceString(object$, "cn=", "",#PB_String_NoCase,1)
  Debug "object$="+object$
  Protected query$, recordCount
  Protected.COMateObject oRecordSet
  query$ = "<LDAP://" + sHostServer + "/" + sDNSDomain + ">;(" + property$ + "=" + object$ + ");ADsPath;subtree"
  Debug "query$="+query$
 
  If oConnection
    oRecordSet = oConnection\GetObjectProperty("Execute('" + query$ + "')")
    Debug "oConnection\GetObjectProperty=" + COMate_GetLastErrorDescription()
    Debug "oRecordSet="+Hex(oRecordSet)
    If oRecordSet
      recordCount = oRecordSet\GetIntegerProperty("RecordCount")
      Debug "oRecordSet\GetIntegerProperty=" + COMate_GetLastErrorDescription()
      Debug "recordCount="+Hex(recordCount)
      oRecordSet\Release()
      ProcedureReturn recordCount
    Else
      ; problem querying AD
      ProcedureReturn 0
    EndIf
  Else
    ; problem with AD connection
    ProcedureReturn 0
  EndIf
EndProcedure

Procedure ADGetUserGroups(Array group$(1), user$ = "")
; pass a string array which will be resized and filled with all groups
; the user is an immediate member of - if no user specified, defaults
; to logged on user
  Debug "ArraySize(group$())="+ Str(ArraySize(group$()))
  If user$=""
    user$ = GetEnvironmentVariable("USERNAME")
  EndIf
  Debug "before user$="+user$
  Shared sHostServer, sDNSDomain, oConnection
  user$=LTrim(user$)
  user$ = ReplaceString(user$, "cn=", "",#PB_String_NoCase,1)
  Debug "after user$="+user$
  Protected query$, recordCount, member
  Protected.COMateObject oRecordSet, oFields, oValue, oUser, oEnum
  query$ = "<LDAP://" + sHostServer + "/" + sDNSDomain + ">;(sAMAccountName=" + user$ + ");ADsPath;subtree"
  Debug "query$="+query$
 
  If oConnection
    oRecordSet = oConnection\GetObjectProperty("Execute('" + query$ + "')")
    Debug "oConnection\GetObjectProperty=" + COMate_GetLastErrorDescription()
    Debug "oRecordSet="+Hex(oRecordSet)
    If oRecordSet
      recordCount = oRecordSet\GetIntegerProperty("RecordCount")
      Debug "oRecordSet\GetIntegerProperty=" + COMate_GetLastErrorDescription()
      Debug "recordCount="+Hex(recordCount)
      If recordCount
        oFields = oRecordSet\GetObjectProperty("fields(0)")
        Debug "oRecordSet\GetObjectProperty('fields(0)')=" + COMate_GetLastErrorDescription()
        Debug "oFields="+Hex(oFields)
        If oFields
          Protected Value$ = oFields\GetStringProperty("value")
          Debug "oFields\GetStringProperty('value')=" + COMate_GetLastErrorDescription()
          Debug "Value$="+Value$
          oUser = COMate_GetObject(Value$)
          Debug "COMate_GetObject(Value$)=" + COMate_GetLastErrorDescription()
          If oUser
            Protected.VARIANT *members = oUser\GetVariantProperty("memberof")
            Debug "oUser\GetVariantProperty('memberof')=" + COMate_GetLastErrorDescription()
            Debug "*members="+Hex(*members)
            Protected.SAFEARRAY *memberArray = VT_ARRAY(*members)
            Protected *varDD.VARIANT, i
            Debug saLBound(*memberArray)
            Debug saUBound(*memberArray)
            ReDim group$(saUBound(*memberArray)+1)
            For i = saLBound(*memberArray) To saUBound(*memberArray)
              *varDD = SA_VARIANT(*memberArray, i)
              If *varDD\vt <> #VT_BSTR
                VariantChangeType_(*varDD, *varDD, 0, #VT_BSTR)
              EndIf
              Protected name$ = PeekS(*varDD\bstrVal, -1, #PB_Unicode)
              Debug name$
              group$(i)=name$
              VariantClear(*varDD)
            Next
            saFreeSafeArray(*memberArray)
            VariantClear(*members)
            FreeMemory(*members)
            oUser\Release()
          EndIf
          oFields\Release()
        EndIf
      EndIf
      oRecordSet\Release()
      ProcedureReturn recordCount
    Else
      ; problem querying AD
      ProcedureReturn 0
    EndIf
  Else
    ; problem with AD connection
    ProcedureReturn 0
  EndIf
EndProcedure