存取权利
存取权利起先看起来似乎是个需要理解的简单观点,但是有某些重点可能不够明显。要了解存取权利之细微差别的最好方法是讨论它们被使用在哪里并检查每个群组。让我们先复习已经知道的部分:
- 系统在代表信任成员的安全对象上执行任何安全性作业之前,信任成员必须持有存取权利的组合。
- 所有存取权利都被封装成一个32位元的存取遮罩(请察看
截至目前为止,我们已经讨论过储存在ACE中的存取遮罩之存取权利,它只是交易处理的其中一部份。我说过权利是执行工作所需的,但是并没有明确说明应如何向系统要求权利。要求权利是交易处理的另一部份。
通常当您在向系统要求一个对象的handle时,即是在要求一个权利。大部分传回安全对象handle的函数皆有一个必须的存取参数,您必须传递一个值以指出您打算如何使用此handle。请看以下的范例:
HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("MyEvent"));您可能已经非常熟悉像这样的程序代码,但是却怎么也没想到您是在向系统要求这个事件对象的特定存取权利。您传递到OpenEvent(及其他类似的函数)存取参数的标记位元与储存在保护对象安全之ACEs的位元是相同的。事实上,系统在传回事件的handle前就会执行存取检查。
说明
Windows中有许多安全对象皆是透过handles被存取。当这些对象的handle被要求时会检查其安全性,而您的权利会和此handle一起被储存。这意味着一旦您已经收到某个对象的handle时,对象本身的存取权利可能会改变,而经由handle提供给您的存取则仍是相同的,直到handle被结束为止。
某些在对象上执行安全活动的handle是您从未见过的。这个理想的范例即是呼叫GetNamedSecurityInfo,此函数在您不须先撷取某个对象handle时很方便。在这个实例中,系统内部在执行任何安全性活动前,会先执行存取检查。
您现在已经熟悉了ACE及存取权利的存取要求,让我们开始讨论更详细的存取权利类型。首先,我们需要在不同的存取遮罩中取得「奇数」位元。
稽核位元代表存取权利ACCESS_SYSTEM_SECURITY,在使用者可以修改对象的SACL前,它必须由信任成员持有(本章稍后将会更详细讨论稽核的内容)。
最大的允许位元代表「非存取权利」MAXIMUM_ ALLOWED,我称它为非存取权利是因为它从不会在储存于DACL的ACE中发现。只在呼叫函数要求存取时被使用。
例如,以下的程序代码片段在撷取指定事件对象的handle时使用MAXIMUM_ALLOWED标记:
HANDLE hEvent = OpenEvent(MAXIMUM_ALLOWED, FALSE, TEXT("MyEvent"));在这个实例中,系统会在对象上执行存取检查,而非允许或拒绝存取检查,它会传回授予您这个对象之最大权利的存取遮罩。这似乎是个非常方便的特色(在某些情况下它是),当要求一个handle时,它允许您总是传递MAXIMUM_ ALLOWED,而不强迫您正确地描绘所需对象的哪个权利。然而,有一个不用如此做的好理由。
当您取得对象的handle时,通常会被系统告知您被允许以某些方法使用这个对象。假如您在要求handle时被拒绝,通常即表示着您不被允许作所要求的任何事,此时您的软件可以采取适当的方法。
假如您每次需要存取时皆传递MAXIMUM_ALLOWED到对象上,那么您的程序代码在一段长时间内可能会运作良好。但是当您的程序第一次遇到没有授予足够存取的对象时,您的软件在撷取对象handle前,可能不会抓取错误。执行失败的函数可能甚至不传回ERROR_ACCESS_DENIED。函数会传回另一个错误,例如ERROR_INVALID_PARAMETER,是很有可能的事,因为您传递了一个handle以及对象的不充分存取权限给它。有这种问题的程序代码可能更难除错。
标准存取权利 系统定义了五个标准权利。除了这些之外,另外五个「复合的」存取权利则由系统定义对应到五个标准权利的某些组合。
并非所有的标准权利都与系统之所有安全对象有关,但是每个标准权利都是特殊的,因为其本身的涵义不是从对象变成对象。例如,不是所有的对象都能被删除,所以标准权利DELETE对某些对象来说没有意义。然而,对于可以被删除的对象来说,标准权利DELETE可从一个对象类型传递相同的涵义到下一个可删除对象权利的持有者。表10-13列出所有标准及复合权利。
| 表10-13 标准及复合权利 |
| 权利 | 说明 |
|---|---|
| 标准权利 | |
| DELETE (位元16) | 删除存取。 |
| READ_CONTROL (位元17) | 读取存取安全对象的安全性资讯,包括拥有者 SID、群组SID、DACL及安全描述项修正和控 制。它不包括要求读取安全对象SACL的存取。 |
| WRITE_DAC (位元18) | 写入存取安全对象的DACL及群组SID。WRITE_ DAC存取被暗示性地授予对象的拥有者。 |
| WRITE_OWNER (位元19) | 写入存取安全对象的拥有者SID。除非您也持有 SE_BACKUP_NAME权利,否则您只能写入只表 示使用者SID的SID或是群组SIDs的其中一个 到对象的拥有者SID。 |
| SYNCHRONIZE (位元20) | 同步存取可被想成是伺候对象的权利。此类对象 可以是同步化对象(例如,事件或Mutex),或 者它可以是可等待核心对象的其中之一(例如, 文件或处理程序handle)。 |
| 复合的标准权利 | |
| STANDARD_RIGHTS_READ STANDARD_RIGHTS_WRITE STANDARD_RIGHTS_EXECUTE | 对应到READ_CONTROL存取。 |
| STANDARD_RIGHTS_REQUIRED | 对应到位元16-19,或是DELETE、READ_ CONTROL、WRITE_DAC及WRITE_OWNER。 这种存取权利通常包括为特定对象定义的「所有 存取」,例如,EVENT_ALL_ACCESS或FILE_ ALL_ACCESS。 |
| STANDARD_RIGHTS_ALL | 定义为0x001F0000,这种存取权利包括所有标准权利。 |
如同表10-13所示,标准权利包括一些强大的权利。例如,假设您持有对对象的WRITE_OWNER存取权限,但却被所有其他的对象拒绝,表示您可能无法作这么多。但是如果您选择使用这个存取设定对象的拥有者SID为您的SID,您就拥有内含的WRITE_DAC存取。然后您可以使用这个存取修改对象的DACL,以允许您自己得到对这个对象所有想要的存取。
特定权利 特定权利占据了存取遮罩的位元15-0,因此每个系统中的安全对象可以拥有16位定义的不同存取权利。
因为特定权利和对象至对象的情形不同,与特定权利一起操作的最大挑战是找出对象可用之所有特定权利的广泛清单。您应该在两个地方寻找特定权利的详细说明:《Platform SDK》文件及《Platform SDK》标头档。您应该检查有兴趣之现存对象类型的handle函数。例如,假设您对于找出登录机码之可用特定权利感兴趣,则您会因为RegOpenKeyEx函数而查对《Platform SDK》文件,您会找到例如KEY_READ、KEY_SET_VALUE及KEY_ALL_ACCESS的权利叙述。在您有了某个对象的几个存取权利名称之后,便可以在《Platform SDK》所包含的目录中搜寻标头档,它定义了一个或更多个您知道的特定权利,然后您可以找出那个对象剩下的存取权利。
表10-14列出Windows最常见的安全对象之特定权利。