Reputation: 11903
Here is some sample code:
var ctx = new PrincipalContext(ContextType.Domain);
var up1 = AuthenticablePrincipal.FindByIdentity(ctx, IdentityType.Sid, "S-1-5-21-.......");
var up2 = AuthenticablePrincipal.FindByIdentity(ctx, IdentityType.UserPrincipalName, "[email protected]");
If the user is in the same domain where this code is executing, it finds the user in both cases. If the user is in another, two-way trusted forest, both return null.
When I create a domain-local group on the current domain and put users from other forests in it, and I list the members of the group with GroupPrincipal.GetMembers
, it does find and it does resolve the foreign objects as well. So this task is certainly possible and our infrastructure is also working fine.
How to find a user from another forest with UserPrincipal.FindByIdentity
? Or with any other method that uses PrincipalContext
?
Upvotes: 1
Views: 3115
Reputation: 11903
Here's an ugly solution with reflection:
var ctx = new PrincipalContext(ContextType.Domain);
var queryCtx = ctx.GetType().GetProperty("QueryCtx", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(ctx, null);
var ctxBase = (DirectoryEntry)queryCtx.GetType().GetField("ctxBase", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(queryCtx);
var srch = new DirectorySearcher(ctxBase);
srch.Filter = "(objectSid=S-1-5-21-.......)";
var result = srch.FindOne().GetDirectoryEntry();
var adUtils = queryCtx.GetType().Assembly.GetType("System.DirectoryServices.AccountManagement.ADUtils");
var up = (UserPrincipal)adUtils.GetMethod("DirectoryEntryAsPrincipal", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { result, queryCtx });
Upvotes: 1
Reputation: 7878
Use the PrincipalContext
constructor that allows you to specify the name of the target context - the DNS name of the target forest/domain.
Upvotes: 1