Question

I need just the commonName of the groups a user is a member of.

DirectoryEntry user = new DirectoryEntry("LDAP://cn=myuser....");
foreach(string path in user.Properties["memberOf"])
    Console.WriteLine(path);

then the memberOf property contains a set of strings, the full paths of the groups. That's makes sense, but it's not what I want.

I'm pretty sure I shoudn't new up a DirectoryEntry for each of those paths to get the common name, but is it the best idea to simply parse out the cn from the path? (that seems rather brutish)

There must be a better way to get a SearchResults of groups a users is a member of.

BTW, this is .NET 2, so I can't do any of the fancy LINQ to AD stuff nor do I have access to the new bits in DirectoryServices for ActiveDirectory.

Was it helpful?

Solution

The CN is not necessarily equal to the name of the group. Parsing it out of the DN is not recommendable, since the DN is escaped. You would need to query the directory for the objects.

To retrieve a single object, set the search base to it's distinguished name, the search scope to "base" and issue the query.

Caching the query results in your app to avoid issuing the same LDAP query more than once is advisable (in case you retrieve the memberOf of more than one object in a row).

Sample code (right off the MSDN, only slightly modified):

string dn = "LDAP://CN=Group Name,ON=Groups,DC=fabrikam,DC=com";

// Bind to a specific group.
DirectoryEntry entry = new DirectoryEntry(dn);

// Create a DirectorySearcher object.
DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.SearchScope = SearchScope.Base;
mySearcher.PropertiesToLoad.Add("displayName"); 

// Use the FindOne method to find the group object.
SearchResult resEnt = mySearcher.FindOne();

OTHER TIPS

Unfortunately there is no better way in .NET 2.0 than what you describe. The memberOf attribute simply contains the full distinguished names of all groups the user is a member of so your best solution is to parse each distinguished name.

Found this old thread in the "Related" section.

Got two other suggestions to this question.
Each of them can get objects in memberOf attribute directly as SearchResult in one search.

All code are in C#.

Attribute Scope Query (ASQ):

DirectoryEntry userEntry = new DirectoryEntry("LDAP://<server>/<user DN>", "user", "pwd");

DirectorySearcher searcher = new DirectorySearcher(userEntry);
searcher.SearchScope = SearchScope.Base;
searcher.AttributeScopeQuery = "memberOf";
searcher.PropertiesToLoad.Clear();
// just load any attributes you want, not limited to cn
searcher.PropertiesToLoad.Add("cn");

foreach (SearchResult result in searcher.FindAll())
{
    Console.WriteLine(result.Path);
}

Limitations:

  • Don't handle primary group membership
  • Requires functional level of 2003 (forgot domain/forest)
  • ASQ don't work across domain (at least System.DirectoryServices cannot, it will throw exception for any object in another domain)

LDAP_MATCHING_RULE_IN_CHAIN matching rule:

DirectoryEntry rootEntry = new DirectoryEntry("GC://<GC server>", "user", "pwd");

DirectorySearcher searcher = new DirectorySearcher(rootEntry);
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = "(member:1.2.840.113556.1.4.1941:=<user DN>)";
searcher.PropertiesToLoad.Clear();
// just load any attributes you want, not limited to cn
searcher.PropertiesToLoad.Add("cn");

foreach (SearchResult result in searcher.FindAll())
{
    Console.WriteLine(result.Path);
}

Limitations:

  • Don't handle primary group membership
  • Requires functional level of 2008 R2 (forgot domain/forest)
  • it get nested group membership, not only one level of memberOf
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top