为什么 AccessCheck 不将 GenericMapping 应用到 DACL?

dan*_*nyM 5 permissions winapi dacl

AccessCheck 函数获取一个 GenericMapping 参数。这个参数是干什么用的?它不用于 DesiredAccess 参数,因为之前必须将 MapGenericMask 应用于 DesiredAccess。

它也不适用于包含在 SecurityDescriptor 中的 DACL,因为我发现使用 C 程序执行此操作:

  • 打开当前线程令牌
  • 使用令牌中的所有者和默认组创建安全描述符,以及将 GENERIC_ALL 授予所有者“D:(A;;GA;;;ownerSID)”的 DACL
  • 设置 GENERIC_MAPPING,它将(以及其他)GenericAll 映射到我的 OWN_READ | OWN_WRITE(定义为 0x0001 和 0x0002)
  • 使用上面创建的安全描述符调用 AccessCheck,线程令牌,OWN_READ 作为 DesiredAccess,描述的 GENERIC_MAPPING

但是,这会因访问被拒绝错误而失败。当我将安全描述符更改为“D:(A;;0x0001;;;ownerSID)”时,访问被授予。这表明 AccessCheck 没有使用 GenericMapping 参数将 DACL 中的通用访问标志 (GA/GW/GR/GX) 转换为特定访问权限。为什么?难道我做错了什么?

https://msdn.microsoft.com/de-de/library/windows/desktop/aa374815(v=vs.85).aspx没有给出关于如何设置安全描述符的任何提示。

RbM*_*bMm 1

您几乎全部正确,但您没有考虑到当您尝试将安全描述符(SD)分配给内核对象时 - 系统不完全“按原样”分配给您SD,而是首先GenericMapping应用。ACEs

每个对象 - 都关联了_OBJECT_TYPE其中包含_OBJECT_TYPE_INITIALIZER和此处存在的内容GENERIC_MAPPING GenericMapping;,并且 this GenericMapping(对于每种类型的对象都是唯一的)用于将通用标志转换为非ACCESS_MASK通用标志。

SD为了测试,我使用 next -创建文件"D:P(A;;GA;;;WD)" (10000000 - GenericAll for S-1-1-0 EveryOne)。然后我DACL从创建的文件中查询 - 并看到真正001F01FFS-1-1-0但不是10000000

"D:P(A;;GX;;;WD)" (GenericExecute - 20000000 for S-1-1-0)当我在最终文件中使用- 我001200A0查看时S-1-1-0

因此,真正的内核对象没有通用位,ACCESS_MASK并且您的DACL形式完全相同,您不能分配给任何对象。

为什么 AccessCheck 不将 GenericMapping 应用于 DACL?

AccessCheck假设ACCESS_MASK已经DACL 转换(没有通用位)

我认为这是性能优化 - 更好地转换通用位一次(在对象创建或分配SD给它时 - 比每次有人尝试打开对象时都进行此转换)

关于GenericMapping参数如何使用?

真的非常弱 - 仅当对象没有DACL(或如果PreviousMode == KernelMode)并且您请求MAXIMUM_ALLOWED系统DesiredAccess授予您的情况下GenericMapping->GenericAll。这是基于从WRK( accessck.c)查看源代码

DACLMAXIMUM_ALLOWED这是罕见的情况,但在这种情况下,系统如何计算需要授予调用者哪些具体访问权限?他不询问具体的访问权限(如读/写/删除) - 而是“全部”。所以系统并给他GenericMapping->GenericAll