Поиск всех групп, которыми управляет пользователь

Мы получили специальный многозначный атрибут. Позвольте называть его ourOwnManagedBy, который может содержать пользователей или группы (их DN), которые управляют текущей группой.

Как получить список всех групп, которыми управляет определенный пользователь (с помощью managedBy и ourOwnManagedBy)?

Например. Скажем, что пользователь является членом группы GlobalAdministrators и что в группе ApplicationAdministrators есть GlobalAdministrations в качестве участника. И, наконец, группа MyApplication, которая имеет ApplicationAdministrators в атрибуте ourOwnManagedBy.

  • User является членом GlobalAdministrators
  • GlobalAdministrators является членом ApplicationAdministrators
  • MyApplication получил ApplicationAdministrators в ourOwnManagedBy

Как использовать эту информацию для поиска всех групп, которыми управляет конкретный пользователь? Возможно ли выполнить какую-либо рекурсивную проверку в пользовательских атрибутах (содержащих DN пользователей и групп)?

Обновление

Я попытался использовать фильтр поиска каталогов следующим образом:

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

но я, возможно, не понял, что делает 1.2.840.113556.1.4.1941? (страница MSDN)

Ответ 1

Это, я боюсь, невозможно выполнить только с одним запросом LDAP. Вам придется разбить его на подзапросы и запустить каждый отдельно, что, в свою очередь, задержит контроллер домена, если будет много, чтобы перебрать.

Я попытался сделать это так, как я описал, и производительность была ужасной, по крайней мере, с использованием доступных модулей для .NET.

Ответ 2

На следующей странице 3.1.1.3.4.4 Правила соответствия LDAP (extensibleMatch) говорят, что LDAP_MATCHING_RULE_TRANSITIVE_EVAL, который вы используете, работает в Windows 2008 и более высокие выпуски. Если вы используете 2003, это может не сработать.

Ответ 3

Нет рекурсии, нет идеи о том, как она будет работать по производительности, могут быть ошибки.

        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/info/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();
        }

Я буду честен и скажу, что это на самом деле не работает для меня:) Но я думаю, что это связано с тем, как настроен наш домен. Если ничто другое, возможно, это не подтолкнет вас в правильном направлении.