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

时间:2011-10-04 13:31:31

标签: active-directory ldap 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服务器)
  4. 任何人都知道如何才能使这项工作?

1 个答案:

答案 0 :(得分:3)

据我了解,其中一种方法是:

  1. 从RootDSE中,查找配置NamingContext。
  2. 在配置NamingContext中查找已存在属性crossRef的类nETBIOSName的对象。
  3. 使用dnsRootnCName attributs,从这些条目中使用您要描述的算法。工作林DNS允许您加入dnsRoot的域控制器。 nCName允许从根目录进行搜索。
  4. 小心将此作为企业管理员组的成员执行此操作。

    以下是代码示例。

    /* 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中给出的方法中找到关于解决问题方式的评论。这是一种递归解决方案。这一次,我测试属于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);    
    }