none
System.DirectoryServices.AccountManagement and cross domain references RRS feed

  • Question

  • Hi

    I am using Lingqpad (equivalent to C#) and the System.DirectoryServices.AccountManagement library.

    I can lookup an AD group, but if this group has cross domain references, i get an exception when it references an object which is in another domain, e.g. group members

    at System.DirectoryServices.AccountManagement.ADStoreCtx.ResolveCrossStoreRefToPrincipal(Object o)
       at System.DirectoryServices.AccountManagement.ADUtils.DirectoryEntryAsPrincipal(DirectoryEntry de, ADStoreCtx storeCtx)
       at System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet.get_CurrentAsPrincipal()
       at System.DirectoryServices.AccountManagement.PrincipalCollectionEnumerator.MoveNext()
       at System.DirectoryServices.AccountManagement.PrincipalCollectionEnumerator.System.Collections.IEnumerator.MoveNext()

    >> What i want to know is if there is a way to tell the PrincipleContext object to check in additional ADs ?

          PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "ourdomain.com");
          // would like to add also search "otherdomain1", "otherdomain2"
         GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, System.DirectoryServices.AccountManagement.IdentityType.SamAccountName, "an ad group");

    In our case these ADs are trusted and can be read.

    As there is a "ResolveCrossStoreRefToPrincipal" function, i am hoping there is a way to prime the system to handle this issue.

    Thanks in advance !!


    Friday, February 8, 2013 5:19 AM

Answers

  • Hi Greg,

    Welcome to the MSDN Forum.

    Here is an article about this topic: http://technet.microsoft.com/en-us/library/cc787646(v=ws.10).aspx 

    and this similar thread provided a non-verified solution: http://stackoverflow.com/questions/7372240/active-directory-cross-domain-search 

    Would you like to try it?

    Thank you.


    Mike Feng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Greg B Roberts Tuesday, February 12, 2013 5:50 AM
    Monday, February 11, 2013 6:18 AM
    Moderator
  • OK it turns out that we don't have one of these. "Global Catalog running"

    Using http://stackoverflow.com/questions/4960557/counting-active-directory-security-group-members 

    and adapting i found this comes close.

    Still this code finds some group objects where it throws exceptions.

    // NB Namespaces needed
    // System.Directory.AccountManagement
    // System.DirectoryServices
    // System.Security
    GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, System.DirectoryServices.AccountManagement.IdentityType.SamAccountName, "our ad groupname");
    adgroup.Name = grp.Name;
    Console.WriteLine("Sid: {0}", grp.Sid);
    string sec = string.Format("{0}", grp.Sid);
    SecurityIdentifier sidToFind = new SecurityIdentifier(sec);
    string path = "LDAP://" + "ourdomain.com" + string.Format("/<SID={0}>", sidToFind);
                Console.WriteLine("Path: {0}", path);
                var de = new DirectoryEntry(path);
                object  themembers = de.Invoke("Members");
                foreach (object member in (IEnumerable)themembers)
                {
                      DirectoryEntry memberEntry = new DirectoryEntry(member);
                      SecurityIdentifier sid = new SecurityIdentifier((byte[])memberEntry.InvokeGet("objectSid"), 0);
                      Type t = typeof(NTAccount);
     
    	  Console.WriteLine("Name: {0}", memberEntry.Name);				  
    	  Console.WriteLine("Options: {0}", memberEntry.Options);
      	  Console.WriteLine("AccountSid: {0}", sid.AccountDomainSid);
    	  // sid.Dump(1);
    	  
    	  try
    	  {
                            NTAccount account = (NTAccount)sid.Translate(t);
    	   		Console.WriteLine("Value: {0}\n", account.Value);
    		// Do stuff in here to look up other ADs
    	   }
    	   catch
    	   {
    	   		Console.WriteLine("Exception on account\n");
    	   }
    	   
                       //This will give you the username in format //domainName\userName
                } 


    Tuesday, February 12, 2013 5:50 AM

All replies

  • Hi Greg,

    Welcome to the MSDN Forum.

    Here is an article about this topic: http://technet.microsoft.com/en-us/library/cc787646(v=ws.10).aspx 

    and this similar thread provided a non-verified solution: http://stackoverflow.com/questions/7372240/active-directory-cross-domain-search 

    Would you like to try it?

    Thank you.


    Mike Feng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Greg B Roberts Tuesday, February 12, 2013 5:50 AM
    Monday, February 11, 2013 6:18 AM
    Moderator
  • Thanks

    The first URL is the generic uses of ADs / Forests so does not help the coding issue.

    The 2nd URL has a solution i have not come across and will look at.

    I will give it a try and get back.

    Cheers

    Tuesday, February 12, 2013 12:11 AM
  • OK it turns out that we don't have one of these. "Global Catalog running"

    Using http://stackoverflow.com/questions/4960557/counting-active-directory-security-group-members 

    and adapting i found this comes close.

    Still this code finds some group objects where it throws exceptions.

    // NB Namespaces needed
    // System.Directory.AccountManagement
    // System.DirectoryServices
    // System.Security
    GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, System.DirectoryServices.AccountManagement.IdentityType.SamAccountName, "our ad groupname");
    adgroup.Name = grp.Name;
    Console.WriteLine("Sid: {0}", grp.Sid);
    string sec = string.Format("{0}", grp.Sid);
    SecurityIdentifier sidToFind = new SecurityIdentifier(sec);
    string path = "LDAP://" + "ourdomain.com" + string.Format("/<SID={0}>", sidToFind);
                Console.WriteLine("Path: {0}", path);
                var de = new DirectoryEntry(path);
                object  themembers = de.Invoke("Members");
                foreach (object member in (IEnumerable)themembers)
                {
                      DirectoryEntry memberEntry = new DirectoryEntry(member);
                      SecurityIdentifier sid = new SecurityIdentifier((byte[])memberEntry.InvokeGet("objectSid"), 0);
                      Type t = typeof(NTAccount);
     
    	  Console.WriteLine("Name: {0}", memberEntry.Name);				  
    	  Console.WriteLine("Options: {0}", memberEntry.Options);
      	  Console.WriteLine("AccountSid: {0}", sid.AccountDomainSid);
    	  // sid.Dump(1);
    	  
    	  try
    	  {
                            NTAccount account = (NTAccount)sid.Translate(t);
    	   		Console.WriteLine("Value: {0}\n", account.Value);
    		// Do stuff in here to look up other ADs
    	   }
    	   catch
    	   {
    	   		Console.WriteLine("Exception on account\n");
    	   }
    	   
                       //This will give you the username in format //domainName\userName
                } 


    Tuesday, February 12, 2013 5:50 AM