向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,我被困住了。有什么好的建议吗?

向AD组中添加受信任域的成员

按照你的代码,我看到你得到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对象,已经是impersonatedDirectorySearcher找到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中。