Поиск пользователей, которые являются членами двух активных групп каталогов - PullRequest
2 голосов
/ 23 июня 2011

Мне нужно найти всех пользователей, которые являются членами двух групп (GroupA и GroupB). Мне также нужно учитывать вложенные группы. Каков наилучший способ сделать это?

Я знаю, что поиск ldap с использованием memberOf не учитывает вложенные группы. Я также мог бы специально найти две группы, получить список участников и выполнить итерацию по ним, сопоставляя группы, являющиеся членами обоих списков, но коллекция членов группы также не учитывает вложенные группы. Существуют ли методы, которые работают с вложенными группами, или мне нужно написать собственную рекурсивную логику?

Редактировать Вложенная группа: если у меня есть группа безопасности под названием GroupA. GroupA может иметь членов, которые являются пользователями или другими группами. GroupB - это то, что я называю «вложенной группой», если она является членом GroupA.

Ответы [ 3 ]

2 голосов
/ 25 июня 2011

Вот что работает в ActiveDirectory 2003 и 2008 R2. Я использую Microsoft LDAP_MATCHING_RULE_IN_CHAIN ​​ для:

1) Поиск рекурсивно (но в одном запросе) всех пользователей из первой группы (будьте осторожны, верните пользователей из группы безопасности и рассылки)

2) Для каждого пользователя из первого запроса я снова ищу рекурсивно (но в одном запросе), принадлежит ли пользователь ко второй группе.

static void Main(string[] args)
{
  //Connection to Active Directory
  string sFromWhere = "LDAP://SRVENTR2:389/dc=societe,dc=fr";
  DirectoryEntry deBase = new DirectoryEntry(sFromWhere, "societe\\administrateur", "test.2011");

  // To find all the users member of groups "Grp1"  :
  // Set the base to the groups container DN; for example root DN (dc=societe,dc=fr) 
  // Set the scope to subtree
  // Use the following filter :
  // (member:1.2.840.113556.1.4.1941:=CN=Grp1,OU=MonOu,DC=X)
  //
  DirectorySearcher dsLookFor = new DirectorySearcher(deBase);
  dsLookFor.Filter = "(&(memberof:1.2.840.113556.1.4.1941:=CN=Grp1,OU=MonOu,DC=societe,DC=fr)(objectCategory=user))";
  dsLookFor.SearchScope = SearchScope.Subtree;
  dsLookFor.PropertiesToLoad.Add("cn");

  SearchResultCollection srcUsers = dsLookFor.FindAll();

  // Just to know if user is present in an other group
  foreach (SearchResult srcUser in srcUsers)
  {
    Console.WriteLine("{0}", srcUser.Path);

    // To check if a user "user1" is a member of group "group1".
    // Set the base to the user DN (cn=user1, cn=users, dc=x)
    // Set the scope to base
    // Use the following filter :
    // (memberof:1.2.840.113556.1.4.1941:=(cn=Group1,OU=groupsOU,DC=x))
    DirectoryEntry deBaseUsr = new DirectoryEntry(srcUser.Path, "societe\\administrateur", "test.2011");
    DirectorySearcher dsVerify = new DirectorySearcher(deBaseUsr);
    dsVerify.Filter = "(memberof:1.2.840.113556.1.4.1941:=CN=Grp3,OU=MonOu,DC=societe,DC=fr)";
    dsVerify.SearchScope = SearchScope.Base;
    dsVerify.PropertiesToLoad.Add("cn");

    SearchResult srcTheUser = dsVerify.FindOne();

    if (srcTheUser != null)
    {
      Console.WriteLine("Bingo {0}", srcTheUser.Path);
    }
  }
  Console.ReadLine();
}
0 голосов
/ 24 июня 2011

Требуется ли для этого использование поиска ldap? Метод WindowsPrincipal.IsInRole () будет проверять членство как напрямую, так и через вложенную группу - по крайней мере, для теста, который я запускал.

Этот код проверяет идентичность текущего потока для GroupA и GroupB, но вы можете использовать аналогичный подход для перечисления членов GroupA, а затем протестировать каждого из них для GroupB, вызывая IsInRole ...

AppDomain myDomain = Thread.GetDomain();

myDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

WindowsPrincipal myPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal;

NTAccount groupA = new NTAccount("Domain\\GroupA");

SecurityIdentifier sidGroupA = (SecurityIdentifier)groupA.Translate(typeof(SecurityIdentifier));

bool inGroupA = myPrincipal.IsInRole(sidGroupA);

NTAccount groupB = new NTAccount("Domain\\GroupB");

SecurityIdentifier sidGroupB = (SecurityIdentifier)groupB.Translate(typeof(SecurityIdentifier));

bool inGroupB = myPrincipal.IsInRole(sidGroupB);

Console.WriteLine("{0}, {1}", groupA, inGroupA);

Console.WriteLine("{0}, {1}", groupB, inGroupB);

Console.ReadLine();
0 голосов
/ 23 июня 2011

Я не знаю ни одного способа сделать это, кроме как с помощью рекурсии. Получить членство в группе для группы а. Выполните цикл по списку, если элемент является пользователем, добавляемым во второй список, если элемент является группой, затем выполните рекурсию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...