2016-11-10 1 views
1

Мой клиент имеет огромный Active Directory forerst. Например:Как я могу программно получить корень леса Active Directory с помощью C#

Коренного

company.com 
    de.company.com 
    us.company.com 
    in.company.com 
    xx.company.com 

Когда я получить текущий пользователь я получить domainname\username. Когда я захвачу доменное имя и хочу искать в этом домене для других пользователей в мире, я не могу заставить меня знать company.com для поиска каталога.

Есть ли способ в C# получить корневой объект, который я использую с DirectorySearcher или любым другим методом C# для запроса AD?

+0

Вы пытались использовать выдающееся имя? – hofmeister

+0

Уважаемый nAme? – STORM

ответ

1

корень имя леса может быть ontained из RootDSE раздела. Посмотрите на атрибут rootDomainNamingContext. Этот wiil возвращает вам лесной корневой домен. Я не рекомендую извлекать имя леса из DN пользователя, так как оно не будет работать, если у вас есть два дерева домена в одном лесу. Второй вариант - поиск пользователей в глобальном каталоге текущего домена. Глобальный каталог содержит частичную копию всех пользователей из всего леса

Код ниже выполняет поиск по глобальному каталогу. У меня 2 домена, в моем лесу, поэтому он возвращает мне 2 пользователя. Имейте в виду, что вам придется иметь дело с несколькими результатами вернулись:

 var forest = Forest.GetCurrentForest(); 
     var globalCatalog = GlobalCatalog.FindOne(new DirectoryContext(DirectoryContextType.Forest, forest.Name)); 

     using (var connection = new LdapConnection(new LdapDirectoryIdentifier(globalCatalog.Name, 3268))) 
     { 
      var entries = new List<SearchResultEntry>(); 

      var searchRequest = new SearchRequest(string.Empty, "(samaccountname=administrator)", SearchScope.Subtree, null); 
      var searchOptionsControl = new SearchOptionsControl(System.DirectoryServices.Protocols.SearchOption.DomainScope); 

      searchRequest.Controls.Add(searchOptionsControl); 

      var pageResultRequestControl = new PageResultRequestControl(1000); 

      searchRequest.Controls.Add(pageResultRequestControl); 

      do 
      { 
       var response = (SearchResponse)connection.SendRequest(searchRequest); 

       if (response != null) 
       { 
        if (response.ResultCode != ResultCode.Success) 
        { 
         throw new ActiveDirectoryOperationException(response.ErrorMessage, (int) response.ResultCode); 
        } 

        foreach (var c in response.Controls.OfType<PageResultResponseControl>()) 
        { 
         pageResultRequestControl.Cookie = c.Cookie; 
         break; 
        } 

        entries.AddRange(response.Entries.Cast<SearchResultEntry>()); 
       } 
      } 
      while (pageResultRequestControl.Cookie != null && pageResultRequestControl.Cookie.Length > 0); 
     } 

Несколько заметок по этому коду: 1. Конечно, этот код не производство один. Вы можете написать более общий LdapSearcher, например, можно найти here. При необходимости вы можете сделать синхронную версию этого поисковика. 2. Я настоятельно рекомендую использовать LdapConnection вместо DirectorySearcher в приложениях, основанных на обслуживании, потому что использование DirectorySearcher в корпоративной среде приводит к утечкам памяти и другим issues

+0

Хм, хорошо, я попробую его с rootDomainNamingContext. Это звучит хорошо, и образцы в сети прозрачны/понятны и, возможно, то, что я ищу, но не могли бы вы дать немного больше информации о глобальном каталоге? – STORM

+1

Глобальный каталог - это контроллер домена, в котором хранятся определенные атрибуты всех объектов леса. Для каждого атрибута схема Active Directory указывает, хранится ли этот атрибут в глобальном каталоге. Вы можете посмотреть класс System.DirectoryServices.ActiveDirectory.Forest, который предоставляет вам информацию обо всех доступных глобальных каталогах. Этот метод работает в том случае, если вы не знаете, к кому принадлежит доменное имя. Чтобы запросить глобальный каталог, вам нужно указать GC: // вместо LDAP: // – oldovets

+0

В случае отсутствия искомых атрибутов в глобальном каталоге вы все равно можете создать класс Forest, затем получите список доменов леса из этого класса и выполните поиск пользователя в каждый домен – oldovets

0

Чтобы получить корневой объект пользователя, используйте свойство или атрибут distinguished name, чтобы определить полный путь в Active Direcotry. Прочтите структуру справа и извлеките корневой элемент.

E. g. cn=John Doe, ou=People, dc=sun.com

enter image description here

+0

Но что, если у вас есть что-то вроде 'dc = de, dc = eu, dc = company, dc = com' (de.eu.company.com), и вам нужно только root:' dc = company, dc = com' (company.com)? – STORM

+0

@STORM Просто прочтите отличительное имя текущего пользователя и 'RegEx',' Split' или 'Substring' значение. – hofmeister

Смежные вопросы