Могу ли я сопоставить пользователя с группой в разных доменах? - PullRequest
5 голосов
/ 04 октября 2011

Я пытаюсь написать запрос LDAP, который обнаружит, является ли пользователь членом группы, соответствующей запросу с подстановочными знаками, и я пытаюсь использовать для этого OID LDAP_MATCHING_RULE_IN_CHAIN. Я в основном следую примеру 2 на этой странице:

http://support.microsoft.com/kb/914828

Я обнаружил, что этот метод хорошо работает в домене, то есть, если user1 находится в group1, а group1 в group2, тогда я могу написать запрос, соответствующий "* 2", и запрос LDAP найдет вложенные отношения и совпадет с пользователем против группы.

Однако теперь меня попросили поддержать отношения между доменами в одном лесу. Так что теперь у меня есть:

  • пользователь1 является членом группы 1 в домене 1
  • group1 в домене 1 является членом group2 в домене 2

И я хочу быть в состоянии сопоставить user1 с group2 .... Я не могу понять, как заставить LDAP_MATCHING_RULE_IN_CHAIN ​​сделать это:

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

  1. Домен 1, но это просто возвращает группы в домене 1
  2. Родительский домен домена 1 и домена 2, но это не возвращает результатов.
  3. GC, найденный путем запроса свойства "rootDSE", но это просто возвращает группы внутри домена 1 (который является сервером GC)

Кто-нибудь знает, как я могу сделать эту работу?

1 Ответ

3 голосов
/ 17 октября 2011

Насколько я понимаю, один из способов сделать это:

  1. Из RootDSE искать конфигурацию NamingContext.
  2. В конфигурации NamingContext искать объекты классаcrossRef с атрибутом nETBIOSName существующий.
  3. Из этих записей используйте алгоритм, который вы описываете, используя атрибуты dnsRoot и nCName.DNS рабочего леса позволяет вам присоединиться к контроллеру домена dnsRoot.nCName позволяет выполнять поиск из корня.

Будьте осторожны, делая это в качестве члена группы администраторов enterpreise.

Вот пример кода.

/* Retreiving RootDSE
 */
string ldapBase = "LDAP://WM2008R2ENT:389/";
string sFromWhere = ldapBase + "rootDSE";
DirectoryEntry root = new DirectoryEntry(sFromWhere, "dom\\jpb", "PWD");
string configurationNamingContext = root.Properties["configurationNamingContext"][0].ToString();

/* Retreiving the root of all the domains
 */
sFromWhere = ldapBase + configurationNamingContext;
DirectoryEntry deBase = new DirectoryEntry(sFromWhere, "dom\\jpb", "PWD");

DirectorySearcher dsLookForDomain = new DirectorySearcher(deBase);
dsLookForDomain.Filter = "(&(objectClass=crossRef)(nETBIOSName=*))";
dsLookForDomain.SearchScope = SearchScope.Subtree;
dsLookForDomain.PropertiesToLoad.Add("nCName");
dsLookForDomain.PropertiesToLoad.Add("dnsRoot");

SearchResultCollection srcDomains = dsLookForDomain.FindAll();

foreach (SearchResult aSRDomain in srcDomains)
{
  /* For each root look for the groups containing my user
   */
  string nCName = aSRDomain.Properties["nCName"][0].ToString();
  string dnsRoot = aSRDomain.Properties["dnsRoot"][0].ToString();

  /* To find all the groups that "user1" is a member of :
   * Set the base to the groups container DN; for example root DN (dc=dom,dc=fr) 
   * Set the scope to subtree
   * Use the following filter :
   * (member:1.2.840.113556.1.4.1941:=cn=user1,cn=users,DC=x)
   */
  /* Connection to Active Directory
   */
  sFromWhere = "LDAP://" + dnsRoot + "/" + nCName;
  deBase = new DirectoryEntry(sFromWhere, "dom\\jpb", "PWD");

  DirectorySearcher dsLookFor = new DirectorySearcher(deBase);
  // you cancomplete the filter here  (&(member:1.2.840.113556.1.4.1941:=CN=user1 Users,OU=MonOu,DC=dom,DC=fr)(cn=*2)
  dsLookFor.Filter = "(member:1.2.840.113556.1.4.1941:=CN=user1 Users,OU=MonOu,DC=dom,DC=fr)";
  dsLookFor.SearchScope = SearchScope.Subtree;
  dsLookFor.PropertiesToLoad.Add("cn");

  SearchResultCollection srcGroups = dsLookFor.FindAll();

  foreach (SearchResult srcGroup in srcGroups)
  {
    Console.WriteLine("{0}", srcGroup.Path);
  }
}

Это всего лишь подтверждение концепции, которую вы должны дополнить:

с использованием формы using(){} для утилизацииОбъекты DirectoryEntry

Управление исключениями


Отредактировано (2011-10-18 13:25)

Ваш комментарий о том, как вы решаете проблему, можно найти вметод, указанный в Пространстве имен System.DirectoryServices.AccountManagement .Это своего рода рекурсивное решение.На этот раз я тестирую пользователя, принадлежащего к group1 (в другом домене), который принадлежит к group2 (в третьем домене) и, похоже, работает.

/* Retreiving a principal context
 */
Console.WriteLine("Retreiving a principal context");
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, "WM2008R2ENT:389", "dc=dom,dc=fr", "jpb", "PWD");


/* Look for all the groups a user belongs to
 */
UserPrincipal aUser = UserPrincipal.FindByIdentity(domainContext, "user1");
PrincipalSearchResult<Principal> a =  aUser.GetAuthorizationGroups();

foreach (GroupPrincipal gTmp in a)
{
  Console.WriteLine(gTmp.Name);    
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...