10

We got a special multivalue attribute. Let's call it ourOwnManagedBy which can contain users or groups (their DN) that manages the current group.

How can I retrieve a list of all groups that a specific user manages (with the help of managedBy and ourOwnManagedBy)?

For instance. Let's say that the user is member of the group GlobalAdministrators and that the group ApplicationAdministrators has GlobalAdministrations as a member. And finally the group MyApplication which has ApplicationAdministrators in the ourOwnManagedBy attribute.

  • User is member of GlobalAdministrators
  • GlobalAdministrators is member of ApplicationAdministrators
  • MyApplication got ApplicationAdministrators in ourOwnManagedBy

How do I use that information to find all groups that a specific user manages? Is it possible to do some kind of recursive check in custom attributes (that contains DNs of users and groups)?

Update

I've tried to use a directory search filter like this:

string.Format("(ourOwnManagedBy:1.2.840.113556.1.4.1941:={0})", dn);

but I might have missunderstood what 1.2.840.113556.1.4.1941 does? (MSDN page)

jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • This is dumb, but the code sample on the linked site encloses its DN within braces. Have you tried the same? I wouldn't expect it to make a difference, but I've not tried it. – JDB Aug 28 '12 at 20:37
  • yep, tried it. But thanks for the suggestion – jgauffin Aug 29 '12 at 05:04

3 Answers3

1

This is, I'm afraid, not possible to accomplish with only one LDAP query. You will have to split it into subqueries and run the each separately, which in turn will choke the domain controller if there's a lot to iterate over.

I tried to do it the way I described, and the performance was horrible, at least doing it using the available modules for .NET.

westin
  • 326
  • 1
  • 4
0

The following page says 3.1.1.3.4.4 LDAP Matching Rules (extensibleMatch) says that the LDAP_MATCHING_RULE_TRANSITIVE_EVAL that you are using does work in Windows 2008 and higher editions. If you are using 2003, it may not work.

Roland
  • 972
  • 7
  • 15
0

No recursion, no idea on how it will do performance wise, may have bugs.

        string user = "username";
        //get domain
        DirectoryEntry de = System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain().GetDirectoryEntry();
        //get users dn first
        string userDN;
        using (var searcher = new DirectorySearcher(de))
        {
            searcher.Filter = String.Format("(&(objectCategory=person)(objectClass=user)(sAMAccountName={0}))", user);
            searcher.PropertiesToLoad.Add("distinguishedName");
            userDN = searcher.FindOne().Properties["distinguishedName"][0].ToString();
        }

        //get list of all users groups
        List<string> groups;
        //see http://stackoverflow.com/questions/6252819/find-recursive-group-membership-active-directory-using-c-sharp
        using (var searcher2 = new DirectorySearcher(de))
        {
            searcher2.Filter = String.Format("(member:1.2.840.113556.1.4.1941:={0})", userDN);
            searcher2.SearchScope = SearchScope.Subtree;
            searcher2.PropertiesToLoad.Add("distinguishedName");

            SearchResultCollection src = searcher2.FindAll();

            groups = (from SearchResult c in src
                      select c.Properties["distinguishedName"][0].ToString()).ToList();
        }

        //build giant search query
        SearchResultCollection srcGroups;
        using (var searcher = new DirectorySearcher(de))
        {
            string baseString = "(|{0})";
            string managedbybase = "(managedBy={0})";
            //I've read that you can search multivalued lists using a standard ='s.
            string ourOwnManagedByBase = "(ourOwnManagedBy={0})";

            StringBuilder sb = new StringBuilder();

            //add user DN to list of group dn's
            groups.Add(userDN);

            foreach (string g in groups)
            {
                sb.AppendFormat(managedbybase, g);
                sb.AppendFormat(ourOwnManagedByBase, g);
            }

            searcher.Filter = string.Format(baseString, sb.ToString());
            srcGroups = searcher.FindAll();
        }

I'll be honest and say that this doesn't actually work for me :) But I think it's because of the way our domain is configured. If nothing else maybe it will push you in the right direciton.

Peter
  • 9,643
  • 6
  • 61
  • 108
  • 1
    @jgauffin - It looks like the limit is commonly in the 400 character range ( http://stackoverflow.com/a/1883259/328968 ). It wouldn't surprise me if it was similar in .Net/AD. – Peter Aug 30 '12 at 20:12