As I understand it, one way to do this is:
- In RootDSE, find the NamingContext configuration.
- In the configuration, NamingContext looks for objects of the
crossRef class with the nETBIOSName existing attribute. - From these entries, use the algorithm that you describe using the
dnsRoot and nCName . The working DNS forest allows you to join the dnsRoot domain dnsRoot . nCName allows you to search from the root.
Be careful, do this as a member of the enterpreise admin group.
Here is a sample code.
string ldapBase = "LDAP://WM2008R2ENT:389/"; string sFromWhere = ldapBase + "rootDSE"; DirectoryEntry root = new DirectoryEntry(sFromWhere, "dom\\jpb", "PWD"); string configurationNamingContext = root.Properties["configurationNamingContext"][0].ToString(); sFromWhere = ldapBase + configurationNamingContext; DirectoryEntry deBase = new DirectoryEntry(sFromWhere, "dom\\jpb", "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) { string nCName = aSRDomain.Properties["nCName"][0].ToString(); string dnsRoot = aSRDomain.Properties["dnsRoot"][0].ToString(); sFromWhere = "LDAP://" + dnsRoot + "/" + nCName; deBase = new DirectoryEntry(sFromWhere, "dom\\jpb", "PWD"); DirectorySearcher dsLookFor = new DirectorySearcher(deBase);
This is just a proof of concept, you have to do:
using the using(){} form to host DirectoryEntry objects
Exception management
Edited (2011-10-18 13:25)
Your comment on how you solve the problem can be found in the method specified in System.DirectoryServices.AccountManagement Namespace . This is a kind of recursive solution. This time I am testing a user belonging to group 1 (in another domain) who belongs to group 2 (in the third domain) and it seems to be working.
Console.WriteLine("Retreiving a principal context"); PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, "WM2008R2ENT:389", "dc=dom,dc=fr", "jpb", "PWD"); UserPrincipal aUser = UserPrincipal.FindByIdentity(domainContext, "user1"); PrincipalSearchResult<Principal> a = aUser.GetAuthorizationGroups(); foreach (GroupPrincipal gTmp in a) { Console.WriteLine(gTmp.Name); }
source share