Can I match a user to a group accross different domains?

后端 未结 1 448
小蘑菇
小蘑菇 2020-12-06 08:16

I\'m trying to write an LDAP query which will discover if a user is a member of a group which matches a wildcard query and I\'m trying to use the LDAP_MATCHING_RULE_IN_CHAIN

1条回答
  •  失恋的感觉
    2020-12-06 08:29

    As far as I understand, one way of doing that is :

    1. From the RootDSE, look for the configuration NamingContext.
    2. In the configuration NamingContext looking for objects of class crossRef with an attribute nETBIOSName existing.
    3. From these entries use the algorithm you are discribing by using dnsRoot and nCName attributs. A working forest DNS allows you to join a domain controler of dnsRoot. nCName allows to search from the root.

    Be careful to do this as a member of the enterpreise administrators group.

    Here is an example of the code.

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

    This is just a proof of concept, you have to complete with :

    using using(){} form for disposing DirectoryEntry objects

    Exception management


    Edited (2011-10-18 13:25)

    Your comment about the way you solve the problem can be found in a method given in System.DirectoryServices.AccountManagement Namespace. It's a kind of recursive solution. This time, I test with a user belonging to group1 (in an other domain) which belongs to group2 (in a third domain) and it seems to work.

    /* 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 a =  aUser.GetAuthorizationGroups();
    
    foreach (GroupPrincipal gTmp in a)
    {
      Console.WriteLine(gTmp.Name);    
    }
    

    0 讨论(0)
提交回复
热议问题