我可以将用户与不同域中的组匹配吗?

Ben*_*enj 5 ldap active-directory ldap-query

我正在尝试编写一个LDAP查询,它将发现用户是否是与通配符查询匹配的组的成员,并且我正在尝试使用LDAP_MATCHING_RULE_IN_CHAIN OID来执行此操作.我基本上按照这个页面上的示例2:

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

我发现这个方法在域内运行良好,即如果user1在group1中,group1在group2中,那么我可以编写一个匹配"*2"的查询,LDAP查询将找到嵌套关系并将用户与组匹配.

但是,现在我被要求支持同一个林中域之间的关系.所以现在我有:

  • user1是域1中group1的成员
  • 域1中的group1是域2中group2的成员

我希望能够将user1与group2相匹配....我无法弄清楚如何使LDAP_MATCHING_RULE_IN_CHAIN执行此操作:

我已经尝试将查询的基础设置为以下内容:

  1. 域1,但这只返回域1中的组
  2. 域1和域2的父域,但不返回任何结果.
  3. GC,通过查询"rootDSE"属性找到,但这只返回域1内的组(这是GC服务器)

谁知道我怎么能做这个工作?

JPB*_*anc 3

据我了解,这样做的一种方法是:

  1. 从 RootDSE 中查找配置 NamingContext。
  2. 在配置 NamingContext 中查找crossRef具有现有属性的类的对象nETBIOSName
  3. dnsRoot从这些条目中使用您通过使用和属性描述的算法nCName。工作林 DNS 允许您加入 的域控制器dnsRootnCName允许从根开始搜索。

作为企业管理员组的成员,请小心执行此操作。

这是代码示例。

/* 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

这只是一个概念证明,您必须完成:

使用using(){}表单来处理 DirectoryEntry 对象

异常管理


已编辑 (2011-10-18 13:25)

您对解决问题的方式的评论可以在System.DirectoryServices.AccountManagement Namespace中给出的方法中找到。这是一种递归解决方案。这次,我使用属于 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);    
}
Run Code Online (Sandbox Code Playgroud)