sagar yadwad
sagar yadwad

Reputation: 153

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)

Upvotes: 0

Views: 3726

Answers (2)

sagar yadwad
sagar yadwad

Reputation: 153

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.

Upvotes: 0

jwilleke
jwilleke

Reputation: 11026

I think you are making this too hard. Assuming you are using Microsoft Active Directory and your desire is to get the Groups that are members of an existing group, I think you can use a filter such as:

(&(objectCategory=group)(memberOf:1.2.840.113556.1.4.1941:=CN=GroupOne,OU=Security Groups,OU=Groups,DC=YOURDOMAIN,DC=NET))

If you want all the members, including users:

(memberOf:1.2.840.113556.1.4.1941:=CN=GroupOne,OU=Security Groups,OU=Groups,DC=YOURDOMAIN,DC=NET) 

Or to retrieve only users:

(&(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=CN=GroupOne,OU=Security Groups,OU=Groups,DC=YOURDOMAIN,DC=NET)

Got most of this from ldapwiki

Let us know if this works.

Upvotes: 0

Related Questions