Reputation:
I have a problem with C# accessing AD objects. The goal of the code is to retrieve a users's groups. We have 2 domains involved - the domain where the application and many users reside, plus a trusted domain that also contains users so the code must be able to get groups from both domains.
I am using a DirectorySearcher object and filtering it based on the user SID. It's packaged into a DLL to be used by applications. The application currently uses the same code and it works, but when it calls the DLL, the DLL won't return anything from AD. It cannot retrieve any users from the FindOne() call.
We ran into a similar problem when using a search for users before when we only had 1 domain involved, but found a workaround - we could open the user object directly, and didn't search for the object. Now that we have a second domain involved, we have to use the user's SID, and we can't just open the object.
The DLL works in one test environment, but will not work in 2 other test environments. What could be causing this type of behavior? Is this a problem with the DLL? AD Security? Application security? How do we determine if the user has access to search?
Alternatively (if we can't find a solution to this problem), how else can I get a user's groups based on their SID without using a search?
Upvotes: 1
Views: 675
Reputation: 46813
Generically speaking, using a DLL won't change how System.DirectoryServices works. I've used a plugin assembly approach to searching AD, and it works the same as running the actual assembly itself.
There are several questions (which you should ask yourself) that might shed some light:
There are a couple ways to debug this.
If FindOne is not returning anything (and no exception is being thrown) then it's telling you that FindOne is not finding any results that match your criteria.
Or, FindOne is throwing an exception (usually a ComException), and you can use the comexception errorcode to lookup what is happening.
You can fire up WireShark, disable, Sealing and Secure bind, and sniff the packets from your application. You will see the LDAP responses to your search.
Upvotes: 0
Reputation: 754220
Are you on .NET 3.5 ? The AD stuff for group and user management ("principal management") has been improved quite a bit in 3.5.
There's a new System.DirectoryServices.AccountManagement
namespace which is extremely helpful - read all about it here on MSDN Magazine in an article by Ethan Wilansky and Joe Kaplan.
The .NET 3.5 stuff finally allows you to get the user's groups easily, programmatically, and include the user's primary group and any nested group memberships.
If you are on .NET 3.5, you can use code like this:
using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
using(p = Principal.FindByIdentity(ctx, "yourUserName"))
{
var groups = p.GetGroups();
using (groups)
{
foreach (Principal group in groups)
{
Console.WriteLine(group.SamAccountName + "-" + group.DisplayName);
}
}
}
}
S.AD.AM also includes new methods on the "Principal" class to find principals (users, groups, computers) by a variety of search criteria, e.g. by name, SID, GUID:
FindByIdentity contains two overloads, both of which take a PrincipalContext and value to find. For the value, you can specify any of the supported identity types: SamAccountName, Name, UserPrincipalName, DistinguishedName, Sid, or Guid.
Pretty neat, eh? :-)
Marc
Upvotes: 2