使用 NetUserGetInfo 和类似 API 的应用程序依赖于对某些 AD 对象的读取访问权限

本文讨论以下问题:使用 NetUser 或 NetGroup 类的下级 API 的应用程序(如 NetUserGetInfoNetGroupGetInfo )失败并出现 ACCESS DENIED 错误。

原始 KB 编号: 2281774

摘要

你有一个应用程序使用 NetUser 或 NetGroup 类的下层 API,例如 NetUserGetInfo、、NetUserSetInfoNetGroupGetInfoNetUserEnumNetGroupEnumNetGroupSetInfoNetLocalGroupGetInfoNetLocalGroupSetInfo和 。NetLocalGroupEnum 在此方案中,NetUser 类 API 也用于管理计算机帐户。

调用 ADSI WINNT 提供程序时使用相同的 API。

尽管调用帐户对目标帐户具有足够的权限,但这些 API 可能会失败并拒绝访问。 原因是客户端 API 实现与安全帐户管理器 (SAM) RPC API 没有 1:1 关系。 客户端对这些需要 Active Directory 中其他权限的调用执行其他检查和准备。

使用这些 API 的一个应用程序是群集服务,在群集服务日志中,你将看到:

00000a78.000021b8::2010/06/15-00:00:47.911 警告 [RES] 网络名称 <群集-resource1>:无法确定计算机帐户 cluster-resource1 是否已禁用。 status 5

如果为调用帐户启用了成功或失败的访问审核,则这种效果的另一个症状可能是 DC 的安全事件日志中针对这些 API 调用和下面引用的对象中的审核记录过多。

更多信息

API 的实现使用针对域控制器的多个 RPC 调用来设置会话并验证域。 它以读取访问权限访问以下对象:

  • 域根对象:它会查找域控制器的主域并打开要读取的域,后者又打开域的 AD 对象,如 DC=contoso,dc=com。

  • 内置容器:这是内置域的根对象。 当调用方想要验证它是否存在时,它将打开。 因此,调用方需要对容器 CN=Builtin,DC=contoso,dc=com 进行读取访问。

  • SAM 服务器对象:此对象存储有关常规 SAM 帐户访问和枚举的常规权限。 它仅用于某些调用。 对象名称为 cn=server,cn=system,DC=contoso,dc=com。

在大多数 Active Directory 域中,基于泛型组中的成员身份(如经过身份验证的用户、所有人或 Windows 2000 之前的兼容访问组)授予对这些对象的权限。 触发问题的更改可能是用户已从最后一个组中删除, (可能与 Everyone 一起删除,并且/或删除了对列出的对象的权限,以强化 Active Directory 权限。

解决此问题的方法包括授予所需的读取权限,或者将应用程序更改为使用 LDAP,而不是较旧的 API 或 ADSI WINNT 提供程序。 LDAP 不会接触上述对象,它还支持你可能已对目标对象设置的精细权限。

过度审核

在这些对象上启用了审核后,最多会看到上述对象的三条审核记录,用于打开和关闭对象,以及实际的目标对象访问权限。 如果事件记录过多,则有必要删除审核 ACL 中的条目,以便不再记录这些泛型访问类型。 问题是域根对象和内置容器继承到许多从属对象。

若要解决此问题,需要中断内置容器的继承,并将继承的 ACE 重新定义为仅应用于此对象。 还需要触摸域根对象上的 ACE,以便问题 SACE 不再应用于域根对象。 具体步骤取决于环境中有效的实际 SACL 设置。