I have a set up of two domains A and B where there is a one-way trust from B to A (B can essentially query A's active directory).
But when I'm trying to query A's to retrieve a user's email address using the following code:
var context = new PrincipalContext(ContextType.Domain, "A's DOMAIN"); var searchPrincipal = new UserPrincipal(context) { SamAccountName = "USERNAME" }; var searcher = new PrincipalSearcher(searchPrincipal) { QueryFilter = searchPrincipal }; var user = searcher.FindOne() as UserPrincipal; var emailAddress = user != null ? user.EmailAddress : string.Empty;
It throws the following exception:
Exception: An operations error occurred. StackTrace: at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) at System.DirectoryServices.DirectoryEntry.Bind() at System.DirectoryServices.DirectoryEntry.get_AdsObject() at System.DirectoryServices.PropertyValueCollection.PopulateList() at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName) at System.DirectoryServices.PropertyCollection.get_Item(String propertyName) at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer() at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit() at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize() at System.DirectoryServices.AccountManagement.PrincipalContext.ContextForType(Type t) at System.DirectoryServices.AccountManagement.Principal.GetStoreCtxToUse() at System.DirectoryServices.AccountManagement.Principal.set_SamAccountName(String value)
I then debugged with Visual Studio and I found the following message in the ExtendedErrorMessage for context.ConnectedServer:
000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1
I don't understand why this is happening. I cast the incoming http request's User Identity as a WindowsIdentity and impersonated the user. After impersonation, System.Security.Principal.WindowsIdentity.GetCurrent().Name did show the current user to be the HttpContext user so the application currently would be running under the user's profile. But the UserPrincipal query still throws the exception even though the user in question does have read/write permissions.
Though when creating the PrincipalContext object, if I pass in the username and the password of the user it works quite well. But this cannot be a solution for me as the user details will be taken from the incoming http request.
The MSDN page for PrincipalContext says "If the username and password parameters are both null, the default credentials of the current principal are used." But considering that the current principal is the impersonated user, shouldn't the PrincipalContext be obtained even withoutproviding the username/password?
I guess if I change the identity of my application's pool to a user who has access rights to the AD the query would work. But I need to keep it as NETWORK SERVICE to facilitate some other aspects of my application. So I was wondering, is there any other way to query the AD without providing the username/password in this situation?
Thanks.