Add member to AD group from a trusted domain

萝らか妹 提交于 2019-11-28 07:16:24

问题


I have two domains, in a trusted relationship, that I'm trying to manage from a C# web application. To do that, I have to impersonate two different technical users, but that works good, so I will not emphasize that part of the code.

To build proper and easy to manage ACLs for the file system, I must

  • Create a group in domainA (OK!)
  • Find a user in domainB (OK!)
  • Add the user to the group (FAILS when committing changes, error message: There is no such object on the server. (Exception from HRESULT: 0x80072030))

If I'm adding a user from the same domain, the code works perfectly, so I believe I'm only missing a small partial info here. I used this document as a reference and saw this question as well (and a few more citing this error message) but neither of them helped.

Code (try-catch block removed to make it simpler)

// de is a DirectoryEntry object of the AD group, received by the method as a parameter
// first impersonation to search in domainB
// works all right
if (impersonator.impersonateUser("techUser1", "domainB", "pass")) {
    DirectoryEntry dom = new DirectoryEntry("LDAP://domainB.company.com/OU=MyOU,DC=domainB,DC=company,DC=com", "techUser1", "pass");
    de.Invoke("Add", new object[] { "LDAP://domainB.company.com/CN=theUserIWantToAdd,OU=MyOU,DC=domainB,DC=company,DC=com" });
    // de.Invoke("Add", new object[] { "LDAP://domainA.company.com/CN=anotherUserFromDomainA,OU=AnotherOU,DC=domainB,DC=company,DC=com" });
    impersonator.undoImpersonation();
}

// second impersonation because the group (de) is in domainA
// and techUser2 has account operator privileges there
if (impersonator.impersonateUser("techUser2", "domainA", "pass"))
{
    de.CommitChanges();
    impersonator.undoImpersonation();
    return true;
}
else
{
    // second impersonation was unsuccessful, so return an empty object
    return false;
}

Line 6 works, if I debug it or force the properties to be written to HttpResponse, it is clearly there. So the LDAP queries seem to be OK.

Also, if I comment out line 6 and uncomment 7, so basically I add a user from the same domain, the whole thing works miraculously. With domainB, I'm stuck. Any good piece of advice?


回答1:


Following your code, I see that you're getting de as a parameter, which is in Domain A. Then you're creating DirectoryEntry object dom, which is getting impersonated, but never getting used. However, you're trying to add an object from Domain B to de directly using LDAP. This line:

de.Invoke("Add", new object[{"LDAP://domainB.company.com/CN=theUserIWantToAdd,OU=MyOU,DC=domainB,DC=company,DC=com" }); 

is not getting impersonated.

Assuming your impersonation works correctly, use dom object which is already impersonated with DirectorySearcher to find the user in Domain B and then add the user object from Domain B to de.

...
using (DirectoryEntry dom = new DirectoryEntry("LDAP://domainB.company.com/OU=MyOU,DC=domainB,DC=company,DC=com", "techUser1", "pass"))
{
    using (DirectorySearcher searcher = new DirectorySearcher(dom))
    {
        searcher.Filter = "(&(objectClass=user)(CN=theUserIWantToAdd))";
        SearchResult result = searcher.FindOne();
        de.Invoke("Add", new object[] { result.Path });
    }
}
...

UDPATE

This example will show you how to get user SID from one domain, search group from another domain and add user to group using SID.

//GET THE USER FROM DOMAIN B
using (UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(domainContext, UPN))
{
    if (userPrincipal != null)
    {
       //FIND THE GROUP IN DOMAIN A
       using (GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(domainContext, groupName))
       {
          if (groupPrincipal != null)
          {
             //CHECK TO MAKE SURE USER IS NOT IN THAT GROUP
             if (!userPrincipal.IsMemberOf(groupPrincipal))
             {
                string userSid = string.Format("<SID={0}>", userPrincipal.SID.ToString());
                DirectoryEntry groupDirectoryEntry = (DirectoryEntry)groupPrincipal.GetUnderlyingObject();
                groupDirectoryEntry.Properties["member"].Add(userSid);
                groupDirectoryEntry.CommitChanges();
              }
           }
        }
     }
 }

Please note that I skipped all the impersonation in the above code.




回答2:


What finally worked was using principals as Burzum suggested. The original code samples you can see in the MSDN article linked in the question did not work here. So the Principal-based approach is a must nut not enough. You need one more line before committing changes of the new group:

group.Properties["groupType"].Value = (-2147483644);

The default was 0x8000000 and I had to change it to 0x80000004 to enable it to accept FSPs from another domain.

So now the group exists, it has members, it is added to the ACL of the folder.



来源:https://stackoverflow.com/questions/31984105/add-member-to-ad-group-from-a-trusted-domain

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