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
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?
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 });
}
}
...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With