【问题标题】:Can I match a user to a group accross different domains?我可以将用户与不同域的组匹配吗?
【发布时间】:2011-11-30 17:05:37
【问题描述】:

我正在尝试编写一个 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 服务器)内的组

有谁知道我怎样才能做到这一点?

【问题讨论】:

  • 当您搜索 via 全局目录时,您的基础对象路径是否为“GC://DC=rootdomain,DC=...”形式?如果您的基础对象是森林的根域,并且具有“GC://”前缀,并且您没有得到预期的结果,那么我的猜测是跨域搜索不适用于此 OID。跨度>
  • 嗯,我想我可能已经知道为什么我不能正确搜索 GC。微软说 GC 不包含有关域本地组的信息....因此,如果涉及 DMG,LDAP_MATCHING_RULE_IN_CHAIN 就无法跟踪链...真可惜。
  • 我不知道 cmets 是否以这种方式工作,但我想吸引@Brian Desmond 关注这个问题。
  • 你测试我发布的最后一个例子吗?
  • 我无法访问具有多个域的测试环境。但是,我已经研究过该方法,看起来其他人已经成功地使用它来进行跨域嵌套组搜索。谢谢!现在来弄清楚如何用 c++ 完成它......

标签: active-directory ldap ldap-query


【解决方案1】:

据我了解,一种方法是:

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

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

这是代码示例。

/* 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 Namespace 中给出的方法中找到。这是一种递归解决方案。这一次,我使用属于 group2(在第三个域中)的 group1(在另一个域中)的用户进行测试,它似乎可以工作。

/* 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);    
}

【讨论】:

  • 谢谢你,我现在无法测试它,但我明天会好好测试它。我实际上不相信它会起作用。我确实尝试了一些非常相似的方法,遍历森林中的域,对每个域执行 LDAP_MATCHING_RULE_IN_CHAIN。然而,这似乎还不够。几乎就像一个搜索必须能够匹配整个嵌套关系并包含其中的每个组,否则它根本不起作用......
  • 目前,我在虚拟机基础设施上进行了测试,它确实找到了用户直接或间接注册的每个组(本地、全局、宇宙)。
  • 这是一种查找所有要搜索的域的简洁方法,但单个组搜索遇到了与我现有代码相同的问题。 IE。它将找到用户和嵌套组位于同一域中的嵌套关​​系,但如果用户 1 是域 1 中组 1 的成员,并且组 1 是域 2 中组 2 的成员。它不会解析该用户1 是组 2 的成员。
  • 抱歉耽误了时间,我实际上并没有在我的虚拟机中完全重现您的问题。
  • 我已经找到了一种做我想做的事情的方法,但这并不理想。它涉及 LDAP 在每个域中搜索与查询匹配的组,获取它们的 SID 并将这些 SID 与从用户本地安全令牌获得的 SID 进行比较。这种方法可行,但它有一些限制,如果可能的话,我更愿意使用 LDAP 来完成整个事情。
猜你喜欢
  • 1970-01-01
  • 2020-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多