我想知道使用这些的常见用例是什么。具体来说,如果我想获得最大程度的宽容,我不应该使用GENERIC_ALL吗?尽管它在描述中说它不包括 MAXIMUM_ALLOWED,但因为它包括前面提到的访问标志,因此 GENERIC_ALL 不会也包含 MAXIMUM_ALLOWED 吗?我有一种感觉,我错过了一些重要的概念。
好吧,从技术上讲,这是一个 Windows 问题,不确定为什么缺少该标签。这两个值的含义不同,但您也应该了解另一个相关概念:GENERIC_MAPPING。
通用映射允许将通用访问掩码(用于读取、写入和所有)转换为特定于对象类型的访问掩码。顾名思义,这些是特定于对象类型的,即文件、管道、内存映射文件(“Section”)、互斥体(“Mutant”)等。您可以使用 Sysinternals 中的WinObj 来了解对象Windows 中可用的类型。但是,您只需要“意识到”它的存在即可,无需了解所有细节。仅当您使用 ACL 编辑器并且需要自己进行映射时,这才有意义。每个对象类型基本上都带有这样的映射。 获得对象的句柄后,您可以查询
OBJECT_BASIC_INFORMATION
(公共原型
此处;替代)以查看授予了何种级别的特定于对象类型访问权限。 获取句柄是进行访问检查的部分。这就是为什么传递或继承句柄有时会成为问题的原因。因此,如果 SD/DACL 说您没有所请求的访问级别或完全拒绝它,您甚至不会获得句柄,而是会看到
STATUS_ACCESS_DENIED
。
区别GENERIC_ALL
和
MAXIMUM_ALLOWED
之间的区别。如果您注意上面的内容,您可能已经明白为什么它们在语义上不同。
MAXIMUM_ALLOWED
——顾名思义——请求您拥有的任何可用访问权限,
OBJECT_BASIC_INFORMATION::GrantedAccess
可以告诉您那是什么。如果您没有获得句柄而是看到 STATUS_ACCESS_DENIED
,则您根本无法访问该对象。GENERIC_ALL
而是根据通用映射请求实际的
最大访问权限。如果您没有请求的所有访问类型,它仍然会失败。 所以结论:
MAXIMUM_ALLOWED
任何访问级别的句柄(它也可以是实际最大值)
GENERIC_ALL
all访问类型的句柄... 如果其中任何 “all” 失败,您将不会获得句柄,而是会看到
STATUS_ACCESS_DENIED
。
如果你想最大程度地宽容(按照我的理解),你会想使用:MAXIMUM_ALLOWED
GENERIC_ALL
在很多情况下甚至无法为你提供句柄
MAXIMUM_ALLOWED
产生一个。
在最好的情况下——考虑到您的意图——您将被授予相当于
GENERIC_ALL
的访问权限,而无需冒根本无法获取句柄的风险。
或者,您可以请求以您的所需访问级别(例如
GENERIC_ALL
)访问该对象,并交错回退到GENERIC_WRITE
等,并作为最后的努力尝试
MAXIMUM_ALLOWED
。优点是,通过具体的所需访问掩码 -如果并且当您获得句柄时!
- 您知道访问级别。使用
MAXIMUM_ALLOWED
,您仍然需要查询 OBJECT_BASIC_INFORMATION::GrantedAccess
才能找到答案(或者尝试执行某个操作并获得
STATUS_ACCESS_DENIED
或
ERROR_ACCESS_DENIED
)。