This blog post is a contribution from Aaron Miao, an engineer with the SharePoint Developer Support team.
When developing a custom claims provider, you may need to retrieve user information from Active Directory (AD) with LDAP query programmatically. You can add custom attributes by extending the AD schema. Those custom attributes should be usually in global catalog.
Following is the code used to retrieve user information with LDAP query. This works fine if you retrieve the info from the same domain where the custom attributes reside. However it does not work if you retrieve the same user information from a user or machine that is in different domain.
DirectoryEntry root = new DirectoryEntry("LDAP://" + ldap);
DirectorySearcher ds = new DirectorySearcher(root);
ds.Filter = "samAccountName=" + samAccountName;
ds.SearchScope = SearchScope.Subtree;
SearchResult result = ds.FindOne();
The reason is that if one wants to access an AD custom attribute from a machine that is not part of the domain where the custom attributes reside, one needs to pass the fully qualified name of the object to access it. Otherwise the schema cache on the client machine is not properly refreshed even the schema.refresh() is called.
Changing the first line of above code like below should make it work.
DirectoryEntry root = new DirectoryEntry("LDAP://" + domain + "/" + ldap);
The above line generates something like:
Domain is needed to properly get the DirectoryEntry for the object to query from another domain. LDAP://OU=55Users,DC=companydev,DC=com only represents an object in same domain.
Note that you don't have to pass the full controller name like below:
Notes: to AD/LDAP expert (which I am not), the information looks obvious. It took quite a while to figure out and find right information on this topic in SharePoint development space. So, I shared the information here