向AD组中添加受信任域的成员
本文关键字:信任 成员 添加 AD | 更新日期: 2023-09-27 18:07:55
我有两个域,在一个信任的关系中,我试图从c# web应用程序管理。要做到这一点,我必须模拟两个不同的技术用户,但这很好,所以我不会强调这部分代码。
要为文件系统构建适当且易于管理的acl,我必须
- 在domainA中创建组(OK!)
- 查找domainB中的用户(OK!)
- 将用户添加到组(提交更改时失败,错误信息:
There is no such object on the server. (Exception from HRESULT: 0x80072030)
)
如果我要添加来自同一域的用户,代码工作完美,所以我相信我在这里只缺少一小部分信息。我用这个文档作为参考,也看到了这个问题(还有一些引用这个错误信息),但它们都没有帮助。
代码(删除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,我被困住了。有什么好的建议吗?
按照你的代码,我看到你得到de
作为一个参数,这是在Domain A
。然后您创建DirectoryEntry
对象dom
,它正在获得impersonated
,但从未被使用。但是,您正在尝试直接使用LDAP
将对象从Domain B
添加到de
。这一行:
de.Invoke("Add", new object[{"LDAP://domainB.company.com/CN=theUserIWantToAdd,OU=MyOU,DC=domainB,DC=company,DC=com" });
没有得到impersonated
。
假设你的impersonation
工作正常,使用dom
对象,已经是impersonated
与DirectorySearcher
找到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 });
}
}
...
UDPATE
这个示例将向您展示如何从一个域中获取用户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
。
最终成功的方法是按照Burzum的建议使用principal。您可以在问题中链接的MSDN文章中看到的原始代码示例在这里不起作用。因此,基于原则的方法是必须的,但还不够。在提交新组的更改之前,您需要再写一行:
group.Properties["groupType"].Value = (-2147483644);
默认值是0x8000000,我必须将其更改为0x80000004以使其能够接受来自另一个域的FSPs。
现在这个组存在了,它有成员,它被添加到文件夹的ACL中。