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

烂漫一生 提交于 2019-11-27 23:15:19

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<Principal> a =  aUser.GetAuthorizationGroups();

foreach (GroupPrincipal gTmp in a)
{
  Console.WriteLine(gTmp.Name);    
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!