Interroger un annuaire LDAP en visual basic 6

Je dois lire des informations d’un annuaire LDAP à partir d’un programme VB. Je cherche comment lire la structure d’un annuaire et faire une recherche des informations sur un utilisateurs en particulier. Je sais déjà me connecter à l’annuaire, lister les OU principales, lister les utilisateurs d’une OU mais je ne sais pas lire la totalité des informations disponible pour cet utilisateur. Merci pour toute info ou bout de code.
Thierry
PS : Mon annuaire n’est pas un active directory

tu ne peux pas activer l’arborescence pour les les sous OU?

Je veux bien tenter n’importe quoi, mais je ne sais pas faire et toutes mes tentatives arrivent dans un mur (pas de résultat).
Je ne suis pas admin du Ldap mais j’ai un droit de lecture. Un programme comme ldap browser 2.6 arrive a lister tout ça sans soucis (presque sans soucis) et je souhaite faire la même chose à des fins de traitement automatique (controle de validité d’adresse mail) pour un grand nombre d’utilisateurs. Si je n’automatise pas le truc ça va être l’enfer car le probleme est régulier (beaucoup de mouvement de personnes).
Je sais donc que la base LDAP est capable de répondre a cette requette (peut etre un LDAP V3 qui diffuse son shéma) mais je ne sais pas le programmer en VB, j’arrive donc jusqu’a la liste des utilisateurs mais après… le blanc.
Je n’y connais pas grand chose en LDAP, je débute vraiment et ça me gêne d’être coincé pour un truc qui doit être tout con.
Thierrry

Code VBA a coller dans une macro excel, lancement avec un bouton situé en ligne 1
Ligne de titre en 2, extraction commence en ligne 3
Remplacer ControleurDomaine… avec tes paramètres.

Private Sub Cde_Recup_Click()

Dim strLDAP, sDomain, oRoot, objConnection, objCommand, objRecordSet, strUserName, accountcontrol, Ligne
Dim intLLTS, intReqCompare, objLogon, strWeeks, strDays, intLogonTime
Const ADS_ACEFLAG_INHERIT_ACE = 2
Const ADS_RIGHT_DS_CREATE_CHILD = 1
Const ADS_ACETYPE_ACCESS_ALLOWED = 0
Const ADS_ACETYPE_ACCESS_DENIED = 1
Const ADS_ACETYPE_SYSTEM_AUDIT = 2
Const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = 5
Const ADS_ACETYPE_ACCESS_DENIED_OBJECT = 6
Const ADS_ACETYPE_SYSTEM_AUDIT_OBJECT = 7
Const ADS_ACETYPE_SYSTEM_ALARM_OBJECT = 8
Const ADS_SCOPE_SUBTREE = 2
Set oRoot = GetObject(“LDAP://rootDSE”)
sDomain = oRoot.Get(“defaultNamingContext”)
strLDAP = “LDAP://” & sDomain
Set objConnection = CreateObject(“ADODB.Connection”)
Set objCommand = CreateObject(“ADODB.Command”)
objConnection.Provider = “ADsDSOObject”
objConnection.Open “Active Directory Provider”
Set objCommand.ActiveConnection = objConnection
objCommand.Properties(“Page Size”) = 10000
objCommand.Properties(“Searchscope”) = ADS_SCOPE_SUBTREE

Range("A3:BZ8000").ClearContents
Range("A3:BZ8000").Interior.ColorIndex = xlNone
Application.ScreenUpdating = False

Ligne = 3
objCommand.CommandText = "SELECT distinguishedName, lastLogonTimeStamp, TelephoneNumber, Description, Mailnickname, CN, GivenName, SN, DisplayName, Initials, userAccountControl, SamAccountName FROM 'LDAP://ControleurDomaine/OU=Utilisateurs,OU=TonOU,DC=TonDomaine,DC=FR' WHERE objectCategory='User'AND objectClass='user'"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
On Error Resume Next
Do Until objRecordSet.EOF
Cells(Ligne, 1) = objRecordSet.Fields("SN").Value 'NOM
Cells(Ligne, 2) = objRecordSet.Fields("GivenName").Value 'Prénom
Cells(Ligne, 3) = objRecordSet.Fields("SamAccountName").Value 
Cells(Ligne, 4) = objRecordSet.Fields("CN").Value 'CN
Cells(Ligne, 5) = objRecordSet.Fields("Initials").Value 'Initiales
Cells(Ligne, 6) = objRecordSet.Fields("DisplayName").Value 'Nom affiché
Cells(Ligne, 7) = objRecordSet.Fields("Mailnickname").Value
Cells(Ligne, 8) = objRecordSet.Fields("Description").Value
Cells(Ligne, 9) = objRecordSet.Fields("TelephoneNumber").Value
dtmAccountExpiration = objUser.AccountExpirationDate
If Err.Number = -2147467259 Or dtmAccountExpiration = #1/1/1970# Then
Cells(Ligne, 10) = "N/A"
Else
Cells(Ligne, 10) = objUser.AccountExpirationDate
End If
Set objLastLogon = objRecordSet.Fields("LastLogonTimeStamp").Value
intLastLogonTime = objLastLogon.HighPart * (2 ^ 32) + objLastLogon.LowPart
intLastLogonTime = intLastLogonTime / (60 * 10000000)
intLastLogonTime = intLastLogonTime / 1440
Cells(Ligne, 11) = intLastLogonTime + #1/1/1601#

Cells(Ligne, 13) = objRecordSet.Fields("distinguishedName").Value 'DN

accountcontrol = objRecordSet.Fields("userAccountControl").Value
If accountcontrol And 2 Then
Cells(Ligne, 1).EntireRow.Interior.ColorIndex = 17
Cells(Ligne, 12) = "D"
Cells(Ligne, 11) = ""
End If

objRecordSet.MoveNext
Ligne = Ligne + 1
Loop
objConnection.Close


Cells.EntireColumn.AutoFit
Cells.EntireRow.AutoFit
Range("A2:CZ5000").Select
Selection.Sort Key1:=Range("A3"), Order1:=xlAscending, Header:=xlYes, _
    OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
    DataOption1:=xlSortNormal
    Range("A2").Select
Range("A1").RowHeight = 36
Range("A2").RowHeight = 30

Application.ScreenUpdating = True

MsgBox “Extraction terminée”

End Sub

Yop

Re…
Il bloque sur Set oRoot = GetObject(“LDAP://rootDSE”) avec une erreur automation (le domaine n’existe pas ou n’a pu être contacté)
De plus la macro excel semble lister un nombre d’attribut bien défini et non me donner la liste de tous les attributs existants.
Je continue de chercher.

Thierry

Lut

QQs pistes:

www.microsoft.com… (RootDse)

www.kouti.com… (idées de scripts)

Yop

Je cherche toujours…

Je n’ai pas de réponse aux requettes RootDse, le système est en LDAP V2.
Je pense que beaucoup utilise le LDAP pour attaquer un ActiveDirectory et que les outils sont fait pour des attributs particulier à MS. Du coup je peux lire certain champ standard (champ Nom, CN) mais aucun champ spécifique au LDAP qui m’interesse.

Je vais donc indiquer ce qui marche bien actuellement voir si ça vous donne une idée

Le programme suivant m’affiche correctement toute les OU à la racine du LDAP :
Set objDomain = GetObject(“LDAP://ldap.srvldap.fr:389/dc=srvldap,dc=fr”)
objDomain.Filter = Array(“organizationalUnit”)

' Result est un simple controle LIST
For Each objOU In objDomain
    strNames = strNames & objOU.Name & vbCrLf
    Results.AddItem objOU.Name
    ShowOUs objOU.ADsPath
Next

Le programme suivant affiche les utilisateurs définis dans l’OU UTILISATEURS
Set objOU = GetObject(“LDAP://ldap.srvldap.fr:389//ou=utilisateurs,dc=srvldap,dc=fr”)

For Each objUser In objOU
    Results.AddItem objUser.Name
Next

Chaque utilisateur est défini par un UID, j’ai donc toute une liste de UID=Numéro qui s’affiche

Maintenant si je fais une requette du type
Set objOU = GetObject(“LDAP://ldap.srvldap.fr:389//uid=345,ou=utilisateurs,dc=srvldap,dc=fr”)
MsgBox objOU.sn

Je peux afficher les infos sn, cn, name de cet utilisateur, mais aucun champ spécifique comme le champ horaire1
le objOU.horaire1 n’existe pas (logique), un for Each ne trouve rien et des commandes du type MsgBox objOU.Fields(“horaire1”) provoque une erreur (je sais, mais c’est pour monter l’idée générale)

Voila, j’ai testé un tas de trucs et je seche toujours.:@

Help…

Thierry

J’ai du nouveau et de nouveaux ennuis.

Le programme suivant liste TOUS les attributs de l’utilisateur MAIS n’affiche qu’une partie des valeurs.
Je précise que LDAPBROWSER affiche tout, sans filtre ou droit particulier (connexion anonyme), je ne me bute donc pas sur une histoire de droit.
On Error Resume Next

Set objUSER = GetObject("LDAP://ldap.srvldap.fr:389//uid=345,ou=utilisateurs,dc=srvldap,dc=fr")

objUSER.GetInfo ' affiche l'UID et le numéro associé
i = objUSER.PropertyCount
For cpt = 0 To (i - 1)
    champ = objUSER.Item(cpt).Name
    valeur$ = "champ non lisible"
    valeur$ = objUSER.Get(champ)
    Results.AddItem champ & "=" & valeur$
Next

J’ai une partie des valeurs (UID, CN, SN, Mail, GivenName, TelephoneNumber etc…) et pour les autres une erreur (8000500c) indiquant que “Le type de donnée répertoire ne peut pas être converti à partir/vers un type de donnée de service d’annuaire natif”.

Le programme affiche donc bien le nom du champ mais pas de valeur, en gros il affiche “horaire1=champ non lisible” dans ma listbox.

Bien obscur cette erreur, j’ai lu que c’était normal et qu’il y avait une solution, j’en ai essayé une sans succès, encore une fois ça semble tout simple (on ne peut pas dire que le programme trouvé soit complexe) mais la solution me nargue, si proche du but…

Thierry

Je laisse tomber. Si quelqu’un a une solution qu’il la donne mais je vais chercher ailleurs.

Ma conclusion est que Mircosoft ne peut pas lire des LDAP qui ne soit pas de chez lui. Si on tombe sur un schéma personnalisé alors il est incapable de remonter les valeurs. Bref, en dehors de l’active directory point de salut…

Je pense installer un serveur PHP sur mon windows 2003 car il a toute les fonctions pour interroger un LDAP. Ca va être tordu comme solution mais bon.

Thierry

Si ton champ LDAP est sous forme de date, voici la syntaxe pour le lire

Set objpwdLastSet = objRecordSet.Fields(“pwdLastSet”).Value
intpwdLastSet = objpwdLastSet.HighPart * (2 ^ 32) + objpwdLastSet.LowPart
intpwdLastSet = intpwdLastSet / (60 * 10000000)
intpwdLastSet = intpwdLastSet / 1440
Cells(Ligne, 11) = intpwdLastSet + #1/1/1601#

Interroger active directory
www.microsoft.com…

Interroger un LDAP non microsoft, post assez long ici
www.tek-tips.com…

Yop