Windows2000 服务器端应用程序开发设计指南-存取控制(2)
您在本章稍早已学习到系统定义的叁种存取权利类型:即标准、特殊及通用权利。属于ACE一部份的存取遮罩是个32位元的值,每个对象的可能存取权利都与一个位元相对应。
说明
因为每个存取权利皆对应到ACE存取对应中的单一位元,所以一个个别的ACE可被用来指出信任成员帐户的多重存取权利。
存取遮罩被每个Windows系统支援的叁种存取类型划分成数个区段。图10-2即显示了这些位元及其用途。
图10-2 存取遮罩格式
ACEs指出了存在于父系—子系关系层级中的系统及私人对象之继承的规则。当我们开始有纲领的讨论ACLs操作时,我将会涵盖更详细的继承内容;然而,现在了解被允许的继承类型是有帮助的。以下的列表说明了这些可能性:
- 一个包含ACE的父对象不会影响到上层,但会影响子对象。相反地,ACE对父对象及子对象的影响是有可能的。
- 拥有ACE的父系会影响子对象,但不会继续让Grandchild、Great-grandchild等对象继承。您也可以指定一个无限继承的ACE。
- 一个让子(或Grandchild)对象继承的ACE,同时也是一个能影响容器对象的容器,或者它可以被设定成只影响非容器的子对象。
- ACE可以被定义为只被同为容器的子对象继承,或者被任何子对象继承。
这些决策方式的每一个都可以组成ACE,不管ACE的其他继承属性。所以如您所见,ACE可以用几种不同的方法继承。
说明
建立一个不允许从父系继承ACEs的对象安全描述项是可能的,这样的描述项称为 保护的安全描述项 ,它阻止对象和子对象的继承,不过却不影响父对象或任何其他父系子成员的安全描述项。
系统记录了哪个ACEs被继承及明确地指定给对象的内容。如此一来,如果安全描述项在对象被建立后即被设定为保护的安全描述项,那些系统会知道要从DACL及SACL中移除哪个ACEs。并且会明确指定对象的ACEs优先于被继承的ACEs。
存取检查
您现在应该对如何维持一个安全对象的防护有了概念。我们将很快地开始讨论安全API的部份,但是您必须先了解存取检查的内容。
当您登录执行Windows 2000的系统时,会输入您的使用者名称。系统会寻找您所属的成员使用者帐户及群组信任成员帐户,并储存每个信任成员帐户的SID到一个称为 权杖(Token) 的内部结构中。系统也储存指派给您的信任成员及群组信任成员帐户权限清单。您将在第十一章中学到更多关于权杖的内容,但您现在应该将权杖视为一个储存身分及权限的结构。
系统为您建立权杖及启动Shell处理后,会将您的权杖与Shell联系在一起。从此之后,Shell执行的任何处理程序皆会自动启动继承您的权杖副本。这就是系统维护身分识别的观念。
与您权杖相关的处理程序在您的使用者环境或安全性环境中执行。当安全性环境执行的程序试图在安全对象上执行安全动作时,系统首先会执行存取检查,以确定您或其中一个群组是否有足够的权利去执行这个任务。图10-3显示了包含在存取检查中的实体关系。
| 图10-3 存取安全对象的程序 |
说明
程序中的线程也有可能在使用者环境中执行,这与程序不同,称作 模拟 ,详细说明涵盖在下一章。
以下为系统执行存取检查时采取的步骤:
- 系统对应要求标准通用权利及特殊权利。
- 系统为这个存取检查中有关的权限检查您的权杖。大部分的存取检查不考虑权限。然而,如果您持有SeTakeOwnershipPrivilege权限,系统会永远通过WRITE_OWNER标准权利的存取检查(请参阅 表10-13 )。同样地,如果请求ACCESS_SYSTEM_SECURITY的话,您必须持有SeAuditPrivilege权限(有关权限的讨论请参阅 第九章 )。
- 系统将您权杖中的SID及群组SIDs与对象拥有者的SID作比较。假如您是对象的拥有者,而且要求了READ_CONTROL或WRITE_DAC的标准存取权利,则系统不会管DACL的内容即准予存取。
- 系统检查安全描述项中的DACL实体。假如不是当前的,则准予存取。
- 系统对照您权杖中的SIDs,并检查DACL之第一个ACE的SID。假如找到符合的内容,则对照存取检查所要求的存取权利而检查ACE的存取遮罩。
- 假如ACE是拒绝存取的ACE,且存取遮罩与任一个要求的存取权利相符,则存取检查会立即失败。
- 假如ACE是允许存取的ACE,并且满足任何或所有存取检查要求的存取权利,系统会把执行成功事件记录下来。
- 存取检查要求的所有权利都符合后,系统就通过存取检查。
- 假如DACL中最后一个ACE被检查,而且没有找到检查要求的所有权利,则系统的存取检查失败。
说明
-
您可以建立一个受额外存取权利限制的权杖,并任意地选择信任成员帐户。称为 受限权杖 。假如您的处理程序或线程与受限权杖相关,则可以改变存取检查的规则。这个主题的详细描述涵盖在第十一章。
此处理程序最重要的步骤是步骤四、步骤六、步骤八及步骤九。在步骤四中,假如系统发现对象的安全描述项不包括DACL,则每个人的存取检查成功。在步骤六中,假如拒绝存取的ACE与您的使用者或群组SIDs及存取检查的任一个存取权利相符合,则存取检查会立即失败,不管DACL以后的ACE是否已经通过存取检查。步骤八在所有要求的权利找到后,会通过存取检查,不管DACL以后的拒绝存取ACE是否已经使存取检查失败。最后,在步骤九中,若ACEs的数量不足以通过检查,则表示绝对失败。
如您所见的,在存取检查中,DACL中的ACEs顺序是非常重要的。您应该将DACL中拒绝存取的ACEs放置在允许存取的ACEs之前。Windows 2000的使用者介面实作了ACE的安排功能;然而,在您自己的软件中,可以使用任何的顺序放置ACEs。若在对象DACL中,您把拒绝存取的ACE放置在允许存取的ACE之后,则表示您有如此做的充分理由才会如此做!
说明
DACL末端的拒绝存取ACE是浪费的。假如ACE拒绝已经允许的存取动作,则存取检查连末端的拒绝ACE也不会看。而如果ACE拒绝没有明确的允许存取,那么一开始就拒绝存取是没有必要的-除非它被明确地允许,否则即表示它暗示地拒绝该存取动作。
Microsoft已经发表DACL中的ACEs惯用顺序,称为「惯用的」顺序,因为它不完全是强制执行的。表10-6显示了DACL中ACEs惯用的顺序。
表10-6 DACL中ACEs惯用的顺序 ACE类型 群组 拒绝存取的ACEs 拒绝存取对象的ACEs,适用于子对象或对象的属性
允许存取的ACEs
允许存取对象的ACEs,适用于子对象或对象的属性
明确地指派(非继承)ACEs 拒绝存取的ACEs 拒绝存取对象的ACEs,适用于子对象或对象的属性
允许存取的ACEs
允许存取对象的ACEs,适用于子对象或对象的属性
继承ACEs 表10-6中的顺序规则看起来可能有点复杂,但请记得,系统中除了目录服务对象(Active Directory中的对象)外,并非所有的安全对象都使用对象ACEs。忽视对象ACEs将会大大地简化ACEs的顺序。
认识自订或私人对象安全性
我们已经讨论过系统安全对象、保护对象安全的安全描述项结构,以及系统如何使用DACL检查安全性,以防备软件的请求。然而,我还未说明如何让软件使用Windows安全模组建立安全对象。Windows提出此功能为 安全私人对象 。
私人对象安全性是包含在Windows中的一个非常强大且具有弹性的特色。在本章的后续部分,将会讨论与私人对象一起使用的安全性API。此时,要先说明如何将私人对象安全性与Windows现有的安全模组结合。
除了您的软件外,您已学习之有关安全描述项、ACLs、DACLs及ACEs的每件事皆适用于私人对象上,并非系统,您必须决定哪个标准权利(列于表10-13)适用于您的对象。此外,您必须为您的对象定义特殊的权利,并将四个通用权利对应到适当标准及特殊权利的结合上。
您的软件经由呼叫系统函数来执行存取检查。通常,您的软件是个服务,它传递相关的客户端权杖到安全描述项的系统中。然后系统会指出是否拥有客户端要求的存取权利。根据存取检查的结果,您的服务应对执行或拒绝执行要求的动作负责。
系统为您的私人对象建立及删除内存中的安全描述项。您必须将安全描述项与他们保护的资料联系在一起。当服务结束时,它也应负责储存安全性与资料到永续性储存体(Persistent Storage)上(假设对象为持续的情形)。
说明
私人对象安全性不会自动地保护软件定义的对象资料安全性-假如您的对象储存在文件中,您还必须保护文件的安全。然而,私人对象安全性提供可让您以更细微的层级控制资料的机制,而不须受限于文件安全或Windows中其他储存机制的安全性。
浏览Windows的安全性
为了成为一个成功的安全性开发人员,了解及熟悉Windows 2000安全性是很重要的。花些时间在利用使用者介面修改系统对象的安全性上,将大大地使您增加有效地设计安全性软件的能力。
以下的章节将带领您贯穿Windows提供的工具,并帮助您熟悉安全性的内容。在Windows中,可使用登录机码、文件及目录(只在NTFS分割上)取得安全性。文件系统可能是熟悉安全性的最有效方法,因为它的继承模组包含容器对象(目录)及非容器对象(文件)。假如您没有可用NTFS分割区,则可以使用登录。
登录的存取控制
这些步骤叙述如何将安全性选项指定到登录中的方法:
- 以管理员或管理员群组的成员身分登录您的系统。
- 执行RegEdt32.exe公用程序,您将看到类似图10-4的画面。
图10-4 登录编辑器(RegEdt32.exe) - 选择标题为本机上的HKEY_LOCAL_MACHINE视窗,此视窗会显示您系统上储存的HKEY_LOCAL_MACHINE内容。
- 开启Software机码并从编辑功能表中选择新增机码选项,新增一个称为ANewKey的新机码(新机码将命名为ANewKey,以使它显示在接近Software下的机码清单顶端)。
- 点选新的机码,并从安全性功能表中选择使用权限选项,此时会出现一个权限对话方块。
- 取消核取允许来自父项的可继承权限传播至此对象的核取方块,如此会使您的新机码安全描述项被保护,不允许从父机码传播可继承权限。系统会询问您是否希望复制或移除目前继承的权限,如图10-5所示。
图10-5 为ANewKey设定继承的权限 - 点选移除按钮以移除存取清单。
- 现在新机码的DACL内容是空的。假如您点选对话方块中的确定钮,则除了您之外(因为您是此机码的拥有者),没有人可以对这个机码作任何事。而您唯一可作的事,将是读取或写入对象安全性。
- 点选新增钮以显示选择使用者、电脑或群组对话方块内容。从清单中选择Everyone,点选新增钮,然后按下确定按键。这表示为Everyone新增一个ACE到您机码的DACL中。
- 点选允许之下的完全控制核取方块,并点选确定按钮,登录编辑器会为您的机码建立一个新的安全描述项,以让Everyone完全控制这个机码。
- 选择ANewKey然后从编辑功能表中选择新增机码选项,对ANewKey新增两个子机码。(我将我的新机码取名为First及Second,但您可以用任何您喜欢的名字命名。)
- 登出您的机器,以内建的Guest帐户登入(您可能必须赋予这个帐户使用能力),然后重新执行RegEdt32.exe。除了您自己这部分外,可以使用任何信任成员帐户(另一个登出的选择是使用RunAs公用程序,以Guest帐户的身分启动RegEdt32.exe。例如:RunAs.exe /env /user:mymachine\Guest RegEdt32.exe)。
- 在HKEY_LOCAL_MACHINE\Software下找出您的新机码并且开启它,您应该会看到新的子机码。点选它然后从安全性功能表中选择使用权限选项,检查这两个子机码的权限,注意到这两个机码都已经从父机码继承了简单的Everyone\ 完全控制的安全性,此时不要核取允许继承权限核取方块。
- 由于是内建的Everyone群组成员的缘故,否则不会赋予Guest帐户可对这些机码作任何它想作的事,包括改变它们的权限。所以利用这个权力并且开启其中一个子机码的权限。
- 核取拒绝下方的完全控制核取方块,以拒绝对Everyone群组的完全控制。还不须点选确定钮。
- 您正在做的事是为子机码新增拒绝存取的ACE到DACL中。然而,请注意,允许下方的核取方块仍旧是被核取的。这是因为继承允许对Everyone完全控制的允许控制ACE仍出现在当前的DACL中。然而,您明确要求的ACE将优先于任何继承的ACEs。现在点选确定钮,然后在询问您是否想要继续的安全性对话方块中点选是。
- 现在您已经实际地拒绝每个人(包括您登录的这个帐户)对这个机码的任何存取权限。没有人可以在这个机码下建立子机码或值。只有拥有者(应该是您经常登录的帐户)可以修改允许权限的安全性。
- 在您登出并且以您标准的帐户重新登录之前,试着编辑刚修改的登录机码权限。系统应该会告诉您没有足够的存取权利去检视或编辑这个机码的安全性(然后系统将显示一个空的安全描述项,以防止您有存取这个机码的写入权利,而您确实没有这个权力)。
对NTFS分割区的存取控制
以下是说明NTFS分割上的文件权限运作范例:
- 为了检视文件的权限,在Windows浏览器中的文件或资料夹上点选右键,然后从环境功能表中选择属性,以显示属性对话方块,选择安全性页签以显示文件的权限。设定文件权限大部份是以同样的方法,也就是RegEdt32中的登录机码。
- 在属性对话方块中,点选进阶钮以显示存取控制设定对话方块,如图10-6所示。新增非继承的存取权限,或新增只继承到非容器(或文件)的存取权利。
图10-6 设定NTFS分割上的文件权限 - 在属性对话方块中,点选进阶钮。假如您是拥有者,则应该能够将自己或您的其中一个群组设定为拥有者。此外,如果您的帐户拥有SeTakeOwnership Privilege权限,则您应该能设定系统中任何对象的拥有者。要查看拥有者清单,请点选拥有者页签。
- 在浏览器中,建立几个目录层级,上层是您用受保护的安全描述项所建立的新目录,然后再新增足够的存取权利以继续建立目录。接着,经由新增更多允许存取或拒绝存取的ACEs来改变阶层中间目录的安全性。现在请查看阶层底端的目录或文件,并且注意它如何从多重父系中继承权限。请试着从阶层中的父系移除一些权限并注意它如何影响子系或Grandchild。您也可以使用登录机码的阶层做这类的测试。
此处强烈地建议您花更多时间来试验登录机码或文件的权限(假如您有NTFS分割)。浏览这些内容将有助于您具有成为一位安全性程序设计师的能力。
存取控制术语复习
假如您对Windows的安全性程序设计不熟悉,刚才已经连续向您提出了几个新术语及观念。所以在我们潜心研究安全性API的奥秘前,正好可以重新复习一下我们已经学习的部分。
- 存取检查 由系统(或您私人对象的软件)执行的检查,用来决定由权杖识别的使用者是否拥有某个对象之DACL允许的存取权利组。
- 存取控制 系统为了对对象安全性存取之管理及实施所提供的特色。
- 存取遮罩 ACE内部的32位元值,为对象的每个存取权利包含了一个位元,包括标准、特殊及通用权利。
- 存取权利 系统或软件定义的值,指出在安全对象上或与安全对象一起执行某些动作所须的权利。
- ACE 代表存取控制项目。ACE包含了一个识别系统信任成员的SID,以及指出存取权利的存取遮罩。ACE可以允许或拒绝存取某个对象。
- ACL 代表存取控制清单。ACL包含了定义安全性的ACEs或某个对象的安全性报告。
- DACL 代表判别存取控制清单。DACL包含了明确地允许及拒绝存取某个对象的ACEs。
- 通用存取权利 一般的「读取」、「写入」或「执行」某个对象的权利,以及通用的「所有」存取权利。每个通用权利皆对应到一组标准及特殊权利;这些对应会因为对象的每个类型而不同。
- 保护的安全描述项 一个具有控制标记的安全描述项,指出它和它的子系不该从它的父对象接受可继承的ACEs。
- SACL 代表系统存取控制清单。SACL包含了ACEs为相关的使用者指定应被记录到事件日志的事件。
- 安全的对象 任何被Windows存取控制模组保护的私人或系统对象。
- 安全描述项 与系统中每个安全对象关联的结构。安全描述项包括指出拥有者及主要群组的SID,以及非必需的DACL及SACL。
- SID 代表向系统识别信任成员帐户的安全识别项。第九章中有SIDs的详细讨论内容。
- 特殊的存取权利 由系统或软件定义只适用于特定的系统类型或私人安全对象的存取权利。
- 标准的存取权利 由系统定义的存取权利,其子集合将被应用到系统中的每个安全对象类型上。
- 权杖 一个与程序或线程相关联的结构,包含识别使用者及使用者群组的SIDs与使用者持有的权限。第十一章会对权杖做详细的讨论。
- 使用者内容 假如软件在您的权杖下执行,那就是表示在您的使用者环境中执行。
存取控制的程序设计
在这一节中,我们将讨论如何有计划地操作Windows中的安全性,我们将从相关步骤的概念开始谈起。
安全性任务的基本步骤
不管您处理的对象类型为何,其修改安全对象之安全性方法大致相同。您通常会执行两个工作中的其中一个:即建立一个具有安全性的新对象,或者变更现有对象的安全性。以下是您在建立具有安全性对象时将执行的基本步骤:
- 编辑SIDs清单,您将为SIDs建立拒绝及允许的ACEs。
- 建立及初始化安全描述项。
- 建立及初始化够大的DACL,以保存所要求的ACEs。
- 新增ACEs到DACL。
- 新增DACL到安全描述项。
- 使用新的安全描述项建立对象。
- 依照您所需的情形整理。
从一个安全对象类型到下一个类型的操作时,只有步骤六会不同。若要修改现有对象的安全性,请按照以下这些步骤执行:
- 编辑SIDs清单,您将为SIDs建立拒绝及允许的ACEs到对象的DACL。
- 取得对象的DACL。
- 为您想要移除的ACEs检查现有的DACL,然后移除它们。
- 为您新增的ACEs检查现有的DACL,以便您可以大量地避免再次新增它们及不必要的建立。
- 建立一个够大的DACL,以容纳除了新的ACEs外,还有修改过的「旧的」DACL。
- 复制旧的ACEs及新增的ACEs到「新的」DACL。
- 设定DACL给对象。
- 依照您所需的情形整理。
在这个处理程序中,从一个安全对象类型到下一个类型的操作,只有步骤二(取得DACL)及步骤七(请求DACL)会有所不同。
不要使自己被这些处理程序压垮。我将详细地讨论每个步骤,并且叙述选择的几个步骤。在此处提及这些程序的目的,是为Windows中的 任何一个 安全对象显示一般的方法。
如您所见,一旦熟悉了修改对象安全性的方法后,就会拥有修改任何对象安全性所需的技术(甚至是程序代码)。修改方法中的主要差别在于安全性的取得及设定部份。如果您已经知道与您相关的对象类型应使用哪个函数,则您已经准备好了。请看表10-7。







浙公网安备 33010602011771号