Contexte : L'utilisation de l'attribut MemberOf du directory service ne permet pas de lister les groupes imbriqués.
Problème : Connaitre tous les groupes de sécurités dont un utilisateur fait parti en incluant les groupes membres d'autres groupes.
Solution : en utilisant l'attribut "tokenGroups" de l'objet DirectoryEntry représentant un utilisateur, on a accés à un tableau de byte listant tous les groupes auxquels l'utilisateur est rattaché de façon direct ou indirect.
Source / Exemple :
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.DirectoryServices
Imports System.Collections
Public Class frmMain
Private Sub btnFind_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFind.Click
Dim groupList As List(Of String)
Dim currentItem As String
groupList = GetGroups(txtLOgin.Text, txtLdap.Text)
If groupList.Count > 0 Then
lboGroup.Items.Clear()
groupList.Sort()
For Each currentItem In groupList
lboGroup.Items.Add(currentItem)
Next
Else
MessageBox.Show("Aucun group trouvé !", "Recherche..", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End Sub
Public Function GetGroups(ByVal login As String, ByVal ldapConnexion As String) As List(Of String)
'Parameters
Dim _connectionAD As String = "LDAP://" & ldapConnexion
Dim _sb As StringBuilder
Dim _searchRoot As DirectoryEntry
Dim _retList As New List(Of String)
' AD connection
Dim ADEntry As New DirectoryEntry(_connectionAD)
' AD Query with email entry
Dim userSearch As New DirectorySearcher()
userSearch.SearchRoot = ADEntry
userSearch.Filter = "(&(objectClass=User)(samAccountName=" & login & "))"
'Result of AD query
userSearch.SearchScope = SearchScope.Subtree
Dim resultUser As SearchResult = userSearch.FindOne()
'verify if user exist
If resultUser IsNot Nothing Then
Dim resultsUser As DirectoryEntry = resultUser.GetDirectoryEntry()
'Retrieve token groups byt array
resultsUser.RefreshCache(New String() {"tokenGroups"})
'building the LDAP query
_sb = New StringBuilder()
_sb.Append("(|")
For Each sid As Byte() In resultsUser.Properties("tokenGroups")
'append each member into the filter
_sb.AppendFormat("(objectSid={0})", BuildOctetString(sid))
Next
'end our initial filter
_sb.Append(")")
'Search user group that match the seceurity group for creation
_searchRoot = New DirectoryEntry(_connectionAD)
Using ds As New DirectorySearcher(_searchRoot, _sb.ToString(), New String() {"samAccountName"})
Using src As SearchResultCollection = ds.FindAll()
Dim groups As String() = New String(src.Count - 1) {}
For i As Integer = 0 To src.Count - 1
If src(i).Properties("samAccountName").Count > 0 Then
_retList.Add(src(i).Properties("samAccountName")(0).ToString())
End If
Next
End Using
End Using
End If
Return _retList
End Function
#Region "Private Methods"
Private Function BuildOctetString(ByVal bytes As Byte()) As String
Dim _sb As New StringBuilder()
For i As Integer = 0 To bytes.Length - 1
_sb.AppendFormat("\{0}", bytes(i).ToString("X2"))
Next
Return _sb.ToString()
End Function
#End Region
End Class
Conclusion :
Pour toutes questions :
Arnaud Le Granché
http://www.weedo.ch
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.