Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to search in multiple domains using System.DirectoryServices.AccountManagement?

I have three or more domains like main.com, sub.main.com, sub2.main.com and etc

I have a code:

using (PrincipalContext ctx = 
    new PrincipalContext(ContextType.Domain, "ADServer", 
    "dc=main,dc=com", ContextOptions.Negotiate))
{
    UserPrincipal u = new UserPrincipal(ctx);
    u.UserPrincipalName = "*" + mask + "*";

    using (PrincipalSearcher ps = new PrincipalSearcher(u))
    {
       PrincipalSearchResult<Principal> results = ps.FindAll();
       List<ADUser> lst = new List<ADUser>();

       foreach (var item in results.Cast<UserPrincipal>().Take(15))
       {
           byte[] sid = new byte[item.Sid.BinaryLength];
           item.Sid.GetBinaryForm(sid, 0);

           ADUser us = new ADUser()
           {
               Sid = sid,
               Account = item.SamAccountName,
               FullName = item.DisplayName
           };

           lst.Add(us);
       }

    }

    return lst;
}

But it searches within only one domain: main.com.

How can I search records in all domains at one time?

like image 665
Yuriy Vikulov Avatar asked May 05 '12 06:05

Yuriy Vikulov


People also ask

Can Active Directory have multiple domains?

Although Active Directory may contain multiple domains and trees, most single Active Directory configurations only house a single domain forest. However, in certain situations, it can be advantageous to create multiple Active Directory forests due to a given network's autonomy or isolation requirements.

What is collection multiple domains?

In simple terms, a forest is a collection of data partitions and domains; a domain is a hierarchy of objects in a data partition that is replicated between one or more domain controllers; and a trust is an agreement between two domains or forests to allow security principals (i.e., users, groups, and computers) from ...


2 Answers

You should use GC instead of LDAP. It searches along whole Domain Forest

var path = "GC://DC=main,DC=com";

try
{
    using (var root = new DirectoryEntry(path, username, password))
    {
        var searchFilter = string.Format("(&(anr={0})(objectCategory=user)(objectClass=user))", mask);
        using (var searcher = new DirectorySearcher(root, searchFilter, new[] { "objectSid", "userPrincipalName" }))
        {
            var results = searcher.FindAll();
            foreach (SearchResult item in results)
            {
                //What ever you do
            }
        }
    }
}

catch (DirectoryServicesCOMException)
{
    // username or password are wrong
}
like image 84
Roman Korneev Avatar answered Sep 20 '22 11:09

Roman Korneev


Here is a way to find all your domains from the root one :

/* Retreiving RootDSE
 */
string ldapBase = "LDAP://DC_DNS_NAME:389/";
string sFromWhere = ldapBase + "rootDSE";
DirectoryEntry root = new DirectoryEntry(sFromWhere, "AdminLogin", "PWD");
string configurationNamingContext = root.Properties["configurationNamingContext"][0].ToString();

/* Retreiving the root of all the domains
 */
sFromWhere = ldapBase + configurationNamingContext;
DirectoryEntry deBase = new DirectoryEntry(sFromWhere, "AdminLogin", "PWD");

DirectorySearcher dsLookForDomain = new DirectorySearcher(deBase);
dsLookForDomain.Filter = "(&(objectClass=crossRef)(nETBIOSName=*))";
dsLookForDomain.SearchScope = SearchScope.Subtree;
dsLookForDomain.PropertiesToLoad.Add("nCName");
dsLookForDomain.PropertiesToLoad.Add("dnsRoot");

SearchResultCollection srcDomains = dsLookForDomain.FindAll();

foreach (SearchResult aSRDomain in srcDomains)
{
}

Then foreach domain, you can look for what you need.

like image 30
JPBlanc Avatar answered Sep 16 '22 11:09

JPBlanc