我有两个域,在一个受信任的关系中,我试图从C#Web应用程序进行管理。要做到这一点,我必须冒充两个不同的技术用户,但这样做很好,所以我不会强调代码的那一部分。
要为文件系统构建正确且易于管理的ACL,我必须
There is no such object on the server. (Exception from HRESULT: 0x80072030)
)如果我在同一个域中添加用户,代码就能完美运行,所以我相信我在这里只缺少一小部分信息。我使用了this document作为参考,并且也看到了this question(还有一些引用了此错误消息),但它们都没有帮助。
代码(删除try-catch块以使其更简单)
// 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;
}
第6行工作,如果我调试它或强制将属性写入HttpResponse,它显然就在那里。所以LDAP查询似乎没问题。
另外,如果我评论第6行并取消注释7,那么基本上我添加来自同一域的用户,整个事情奇迹般地。有了domainB,我就陷入了困境。有什么好建议吗?
答案 0 :(得分:5)
根据您的代码,我看到您将de
作为参数获取,该参数位于Domain A
。然后,您正在创建DirectoryEntry
对象dom
,它正在获取impersonated
,但从未被使用过。但是,您尝试使用Domain B
直接从de
添加对象LDAP
。这一行:
de.Invoke("Add", new object[{"LDAP://domainB.company.com/CN=theUserIWantToAdd,OU=MyOU,DC=domainB,DC=company,DC=com" });
未获得impersonated
。
假设您的impersonation
工作正常,请使用已dom
impersonated
DirectorySearcher
的{{1}}对象在Domain B
中找到该用户然后将用户对象从Domain B
添加到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 });
}
}
...
此示例将向您展示如何从一个域获取用户SID
,从另一个域搜索组,并使用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();
}
}
}
}
}
请注意,我跳过了上述代码中的所有impersonation
。
答案 1 :(得分:0)
最终有效的是使用校长,如Burzum建议的那样。您可以在问题中链接的MSDN文章中看到的原始代码示例在此处不起作用。因此,基于委托人的方法是必须坚持不够的。在提交新组的更改之前,您还需要一行:
group.Properties["groupType"].Value = (-2147483644);
默认值为0x8000000,我必须将其更改为0x80000004 ,以使其能够接受来自其他域的FSP。
所以现在该组存在,它有成员,它被添加到文件夹的ACL中。