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?
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:
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.
Following your code, I see that you're getting
de
as a parameter, which is inDomain A
. Then you're creatingDirectoryEntry
objectdom
, which is gettingimpersonated
, but never getting used. However, you're trying to add an object fromDomain B
tode
directly usingLDAP
. This line:is not getting
impersonated
.Assuming your
impersonation
works correctly, usedom
object which is alreadyimpersonated
withDirectorySearcher
to find the user inDomain B
and then add the user object fromDomain B
tode
.UDPATE
This example will show you how to get user
SID
from one domain, search group from another domain and add user to group usingSID
.Please note that I skipped all the
impersonation
in the above code.