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

Winapi 为什么AccessCheck不将GenericMapping应用于DACL?,winapi,permissions,dacl,Winapi,Permissions,Dacl,AccessCheck函数获取一个GenericMapping参数。此参数用于什么?它不用于DesiredAccess参数,因为之前必须将MapGenericMask应用于DesiredAccess 它也不适用于SecurityDescriptor中包含的DACL,因为我使用C程序执行以下操作时发现: 打开当前线程令牌 从令牌和DACL中创建一个具有所有者和默认组的安全描述符,并向所有者“D:(a;;GA;;;ownerId)”授予GENERIC_ALL 设置GENERIC_映射,它将Gene

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

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

  • 打开当前线程令牌
  • 从令牌和DACL中创建一个具有所有者和默认组的安全描述符,并向所有者“D:(a;;GA;;;ownerId)”授予GENERIC_ALL
  • 设置GENERIC_映射,它将GenericAll映射到我自己的_READ | OWN_WRITE(定义为0x0001和0x0002)
  • 使用上面创建的安全描述符、线程令牌、OWN_READ as DesiredAccess、所述的通用_映射调用AccessCheck
但是,此操作失败,并出现“拒绝访问”错误。当我将安全描述符更改为“D:(A;;0x0001;;;ownerSID)”时,将授予访问权限。这表明AccessCheck没有使用GenericMapping参数将DACL中的通用访问标志(GA/GW/GR/GX)转换为特定的访问权限。为什么?我做错什么了吗


没有给出关于如何设置安全描述符的任何提示。

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

每个对象-都关联了包含和存在的对象
GENERIC\u映射GenericMapping和此
通用映射
(对于每种类型的对象都是唯一的),用于将
访问\u掩码
中的通用标志转换为非通用标志

对于测试,我使用next
SD
-
创建文件“D:p(A;;GA;;;WD)”(10000000-通用调用S-1-1-0所有人)
。然后我从创建的文件中查询
DACL
,并查看
S-1-1-0
001F01FF
,而不是
10000000

当我使用
“D:p(A;;GX;;;WD)”(GenericExecute-20000000用于S-1-1-0)
-在最终文件中,我查看
001200A0
用于
S-1-1-0

因此,真正的内核对象在
ACCESS\u MASK
中没有通用位,而您的
DACL
的格式完全不能指定给任何对象

为什么AccessCheck不将GenericMapping应用于DACL

AccessCheck
假设
DACL
中的
ACCESS\u MASK
已转换(无通用位)

我认为这是一种性能优化——最好将通用位转换一次(在创建对象或将
SD
分配给它时),而不是每次有人尝试打开对象时进行转换)

关于如何使用
GenericMapping
参数

真的很弱-仅当对象没有
DACL
(或者
PreviousMode==KernelMode
)并且您请求
允许的最大访问次数
作为
所需访问次数
-系统授予您
GenericMapping->GenericAll
。这是基于从
WRK
accessck.c
)中查找源代码


没有
DACL
允许的最大\u
这是罕见的情况,但在这种情况下,系统如何计算需要授予调用方的具体访问权限?他要求的不是具体的访问(比如读/写/删除),而是“全部”。因此,如果AccessCheck()函数不使用,
GenericMapping->GenericAll

这并不能真正解释为什么
GenericMapping
参数存在。也许早期版本的Windows表现有所不同?@HarryJohnston—我最后的写作方式—它用于请求的
MAXIMUM_ALLOWED
,并且对象没有DACL(或者以前的模式是内核)。是的,非常弱的用法。但由于没有DACL和
允许的最大值
这是罕见的情况,但在这种情况下,系统如何计算需要授予调用方的具体访问权限?他要求的不是具体的访问(比如读/写/删除),而是“全部”。因此,系统会给他
GenericMapping->GenericAll
。另一个我没有发现的用法非常感谢你给我指出这个!事实上,设置SD最终会导致调用RtlpSetSecurityObject(base/ntos/rtl/sertl.c),其中GenericMapping使用RtlpApplyAclToObject/RTLMapGenericTask应用于DACL和SACL。然而,它并没有解决我的问题,我现在在另一个问题中描述了这个问题。请检查@dannyM-好的,我看看这个,什么时候有空。谢谢你提出有趣的问题