Search code examples
c#active-directoryldapdirectoryservicesldap-query

How to get nested groups (subgroups) in System.DirectoryServices.Protocol in c#


I have a function which gets parameter as Distringuished name of a group and returns the nested groups or groups within a given group using SearchRequest query and SearchResponse. The code works fine when I use DirectoryEntry but failed when I use LdapConnection class. It is necessary to work with LdapConnection class. Please find below the code snippet:

public static void GetNestedGroups(string strGroupDN)
{
    var _currentDomainofLoggedinUser = Domain.GetComputerDomain();

    var currentDomainofLoggedinUser = Domain.GetComputerDomain();
    var currentDomainController = currentDomainofLoggedinUser.FindDomainController(); //Gets the current Domain controller

    var domainName = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
    string strPath = "LDAP://" + currentDomainController.Name; //Gets the current domain controller name
    AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
    using (LdapConnection ldap = new LdapConnection(new LdapDirectoryIdentifier(domainName, 636)))
    {
        ldap.AuthType = AuthType.Basic;
        ldap.SessionOptions.SecureSocketLayer = false;
        var s = new SecureString();
        NetworkCredential network = new NetworkCredential(WindowsIdentity.GetCurrent().Name, s);

        string ldapSearchFilter = String.Format
              ("(&(memberOf={0})(objectClass=group))", strGroupDN);
        NetworkCredential cred = CredentialCache.DefaultNetworkCredentials;
        ldap.Bind(network);
        string[] attributesToReturn = new string[] { "distinguishedName" };


        SearchRequest searchRequest = new SearchRequest(strGroupDN, ldapSearchFilter, SearchScope.OneLevel, attributesToReturn);
        searchRequest.DistinguishedName =
            strGroupDN;


        searchRequest.Filter = String.Format
               ("(&(memberOf={0})(objectClass=group))", strGroupDN);
        SearchResponse response = (SearchResponse)ldap.SendRequest(searchRequest);
        if (response != null && response.Entries.Count > 0)
        {
            SearchResultEntry obj = response.Entries[0];

            var groupCount = ((System.Collections.CollectionBase)(obj.Attributes["memberOf"])).Count;
            foreach (SearchResultEntry entry in response.Entries)
            {
                var groupName = entry.DistinguishedName;
                _subGroupList.Add(groupName.ToString().Split('=')[1].Split(',')[0]);
                GetNestedGroups(groupName);
            }

        }
    }
}

In the response it doesn't give anything. (In case of DirectoryEntry, it does provide the result)


Solution

  • For any group , we can get a group object using the below query:-

    public static void GetUsersCorrespondingToGroupChild(string strGroupDN)
    {
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.DistinguishedName = strGroupDN;
        searchRequest.Filter = String.Format("(&(objectCategory=Group)(CN={0}))", strGroupDN.ToString().Split('=')[1].Split(',')[0]);
        SearchResponse response = (SearchResponse)ldap.SendRequest(searchRequest);
        if (response != null && response.Entries.Count > 0)
        {
            SearchResultEntry obj = response.Entries[0];//I get group object here
            if (obj.Attributes["member"] != null)
            {
                var childCount = ((System.Collections.CollectionBase)(obj.Attributes["member"])).Count;
    
                for (int i = 0; i < childCount; i++)
                {
                    string groupName = obj.Attributes["member"][i].ToString();//I get all members in which i have to find subgroups
                    List<string> localGroupList = new List<string>();
                    if (groupName.Contains("OU=Groups"))
                    {
                        var attributes = obj.Attributes.AttributeNames;
                        string attributesstr = string.Empty;
                        foreach (var item in attributes)
                        {
                            attributesstr = attributesstr + "," + item;
                        }
                        _subGroupList.Add(groupName.ToString().Split('=')[1].Split(',')[0] + "  :  " + attributesstr);
                        count_Children++;
                    }
                }
            }
        }
    }
    

    so for subgroups, i just have to get attributes["member"] query to return all the users and groups and then i have to retrive the groups corresponding to it.