Поиск всех групп, которыми управляет пользователь
Мы получили специальный многозначный атрибут. Позвольте называть его 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();
}
Я буду честен и скажу, что это на самом деле не работает для меня:) Но я думаю, что это связано с тем, как настроен наш домен. Если ничто другое, возможно, это не подтолкнет вас в правильном направлении.