问题
I have the following AD forest with two trees:
- Domain1. Has two child domains Domain2 and Domain3
- Domain4. Doesn't have child domains.
DNS name of the Domain1 is domain1.local. DNS name of the Domain4 is domain4.local.
In each domain there is a domain controller with Global Catalog enabled.
I'm trying to get UserPrincipal for the user from Domain 4 by its SID. The program runs from a machine in Domain2.
I use the following code:
// Running on some machine from Domain2
PrincipalContext context = new PrincipalContext(
ContextType.Domain,
"dc2.domain2.domain1.local:3268", // Using Global Catalog port and local domain controller
"DC=domain1, DC=local", // I guess the problem is here
"domain1\\super-admin", // User has all necessary rights across all domains
"password");
UserPrincipal principal = UserPrincipal.FindByIdentity(context, "SID-OF-A-USER-FROM-DOMAIN-4");
In my case principal is null (the user was not found).
Searching within one tree (domain1 and its children) works fine with the code snippet above, but I have no idea how to modify the container parameter of the PrincipalContext constructor to really enable forest-wide searches.
Initially I thought that "DC=domain1, DC=local" points to the forest root, but it seems I have misunderstanding here.
And I know that if I change the container path to "DC=domain4, DC=local" then the search will work, but only for users in domain4.
But I really need such a container path that will point to the entire forest, so I could search for users from any domain within a forest using the same PrincipalContext.
Any help is appreciated, especially if anyone could clarify if my requirements are achievable.
回答1:
We could not find any other solution except switching to DirectorySearcher. So it appears that PrincipalContext class doesn't fully support searching in the whole forest.
I cannot say this solution is ideal. I guess it can be tuned for better performance. But we are really disappointed it could not be done using PrincipalContext.
Here is the rough idea how our code works now:
...
// Here is a list of SIDs of users we want to find (initialized somewhere above)
List<string> userSids;
// List of sample results.
List<string> loadedUsers = new List<string>();
using (DirectorySearcher searcher = new DirectorySearcher(new DirectoryEntry("GC://dc2.domain2.domain1.local")))
{
StringBuilder filterStringBuilder = new StringBuilder();
// Just create a single LDAP query for all user SIDs
filterStringBuilder.Append("(&(objectClass=user)(|");
foreach (string userSid in users)
{
filterStringBuilder.AppendFormat("({0}={1})", "objectSid", userSid);
}
filterStringBuilder.Append("))");
searcher.PageSize = 1000; // Very important to have it here. Otherwise you'll get only 1000 at all. Please refere to DirectorySearcher documentation
searcher.Filter = filterStringBuilder.ToString();
// We do not want to go beyond GC
searcher.ReferralChasing = ReferralChasingOption.None;
searcher.PropertiesToLoad.AddRange(
new[] { "DistinguishedName" });
SearchResultCollection results = searcher.FindAll();
foreach (SearchResult searchResult in results)
{
string distinguishedName = searchResult.Properties["DistinguishedName"][0].ToString();
loadedUsers.Add(distinguishedName);
}
}
...
来源:https://stackoverflow.com/questions/18694799/how-to-search-for-users-in-global-catalog-within-ad-forest-with-multiple-trees