10.3.1 存取控制.htm

来自「Windows2000后台服务程序开发手册」· HTM 代码 · 共 483 行 · 第 1/5 页

HTM
483
字号
              <LI 
              style="LINE-HEIGHT: 25px">私人对象安全性要求您的软件使用权杖指出客户端之安全性环境。请记得权杖包含了一个信任帐户的SID与它的群组SIDs、权限及预设DACL(第十一章将会更详细讨论权杖的内容)。<BR 
              style="LINE-HEIGHT: 25px">  </LI></UL></FONT>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>建立一个私下被保护的对象时,您应该建立对象的安全描述项。可呼叫CreatePrivateObjectSecurity函数实作:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL CreatePrivateObjectSecurity( <BR> PSECURITY_DESCRIPTOR psdParentDescriptor, <BR> PSECURITY_DESCRIPTOR psdCreatorDescriptor, <BR> PSECURITY_DESCRIPTOR *ppsdNewDescriptor, <BR> BOOL fIsDirectoryObject, <BR> HANDLE hToken, <BR> PGENERIC_MAPPING gmGenericMapping);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>CreatePrivateObjectSecurity函数有一个非必要的父安全描述项与建立者描述项,这两个参数都可以为NULL。假如两者都没有提供的话,CreatePrivateObjectSecurity函数会透过所提供之权杖中找到的预设DACL而建立一个安全描述项。在预设DACL中找到的通用权利,可使用从被传递之GENERIC_MAPPING结构中找到的资讯,并将它们对应到对象的特定及标准权利。CreatePrivateObjectSecurity函数经由指派它的位址给PSECURITY_DESCRIPTOR变数,以传回新的安全描述项,您所传递的位址为ppsdNewDescriptor参数值。这是一个新的安全描述项,现在您应该把它与您的私有安全对象联系在一起。当您需要释放此函数所分配的内存时,应该传递指向想要释放之安全描述项的变数位址给DestroyPrivateObjectSecurity。</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL DestroyPrivateObjectSecurity( <BR> PSECURITY_DESCRIPTOR *ppsd ObjectDescriptor );</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>被您初始化及传递给CreatePrivateObjectSecurity的GENERIC_MAPPING结构定义如下:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">typedef struct _GENERIC_MAPPING { <BR> ACCESS_MASK GenericRead; <BR> ACCESS_MASK GenericWrite; <BR> ACCESS_MASK GenericExecute; <BR> ACCESS_MASK GenericAll; <BR>}GENERIC_MAPPING;</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>您可经由将每个成员设定到每个通用权利之适当的标准及特定权利组合,以填写这个简单的结构。从权杖的预设DACL建立DACL时,系统会使用这个资讯。</FONT></P>
            <HR style="LINE-HEIGHT: 25px">

            <P><FONT style="LINE-HEIGHT: 25px" face=Arial color=#3e77d7 size=3 
            Black><B style="LINE-HEIGHT: 25px">说明</B></FONT> </P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>您不应直接修改从CreatePrivateObjectSecurity传回的安全描述项。尽管系统提供从此描述项要求特定安全性资讯的函数,您的软件应该把这个传回的指标视为黑箱,犹如安全描述项被储存在系统内存一般。</FONT></P>
            <HR style="LINE-HEIGHT: 25px">

            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>当客户端试图对软件中的安全对象作用时,首先客户端必须接受存取检查。为此,您应传递执行安全工作所需的权利、安全描述项及客户端的权杖到AccessCheck函数中。</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL AccessCheck( <BR> PSECURITY_DESCRIPTOR pSecurityDescriptor, <BR> HANDLE hClientToken, <BR> DWORD dwDesiredAccess, <BR> PGENERIC_MAPPING gmGenericMapping, <BR> PPRIVILEGE_SET pPrivilegeSet, <BR> PDWORD pdwPrivilegeSetLength, <BR> PDWORD pdwGrantedAccess, <BR> PBOOL pfAccessStatus);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>您也必须包含此对象的GENERIC_MAPPING结构位址以及PRIVILEGE_SET结构阵列的位址。系统使用PRIVILEGE_SET结构来描述用来授予存取的权限。系统以几个实例来授予使用权限的存取权,而您应该提供够大的缓冲器以接收数个回传的权限。PRIVILEGE_SET结构定义如下:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">typedef struct _PRIVILEGE_SET { <BR> DWORD PrivilegeCount; <BR> DWORD Control; <BR> LUID_AND_ATTRIBUTES Privilege [ANYSIZE_ARRAY]; <BR>}PRIVILEGE_SET;</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>ANYSIZE_ARRAY值被定义为1,而您应该建立一个够大的缓冲器以接收有关的权限。一旦收到权限缓冲器要求的大小后,您可以呼叫AccessCheck,然后再配置一个够大的缓冲器。</FONT></P>
            <HR style="LINE-HEIGHT: 25px">

            <P><FONT style="LINE-HEIGHT: 25px" face=Arial color=#3e77d7 size=3 
            Black><B style="LINE-HEIGHT: 25px">说明</B></FONT> </P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>当您的客户端要求对象的WRITE_OWNER、READ_CONTROL、WRITE_DAC或ACCESS_SYSTEM_SECURITY的存取时,该权限可以被用来授予存取。假如这些权利没有明确地指派给您客户端的信任成员帐户,系统会为覆盖对象安全性的权限检查客户端的权杖。这种权限的一个例子为SE_TAKE_OWNERSHIP_NAME,它可让客户端设定系统中任何对象的拥有权。</FONT></P>
            <HR style="LINE-HEIGHT: 25px">

            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>您的客户端被授予的存取遮罩会经由pdwGrantedAccess参数传回,而经由pfAccessStatus参数传回的Boolean值会指出AccessCheck函数是否成功。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>在实作私有对象之安全性时,AccessCheck函数是其中心,假如您的软件是安全的,而它一定会在对象执行安全工作前呼叫AccessCheck,则当您软件的客户端被允许存取时,Windows会处理剩下的细节部份。</FONT></P>
            <HR style="LINE-HEIGHT: 25px">

            <P><FONT style="LINE-HEIGHT: 25px" face=Arial color=#3e77d7 size=3 
            Black><B style="LINE-HEIGHT: 25px">说明</B></FONT> </P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>您也可以使用AccessCheckAndAuditAlarm函数建立稽核事件及私有安全对象。稽核的内容将在本章稍后讨论。</FONT></P>
            <HR style="LINE-HEIGHT: 25px">

            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>到此为止,您已经知道如何建立及删除私有安全性的方法,您也知道如何及应在何时呼叫AccessCheck函数。所以私有对象主题唯一剩下的部分即是如何修改安全描述项的元件。为了修改私人对象的安全性,首先应该取得您要调整的安全描述项元件。这通常是DACL,它可以是对象的拥有者或SACL。可使用GetPrivateObjectSecurity实作。</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL GetPrivateObjectSecurity( <BR> PSECURITY_DESCRIPTOR psdObjectDescriptor, <BR> SECURITY_INFORMATION secInfo, <BR> PSECURITY_DESCRIPTOR psdResultantDescriptor, <BR> DWORD dwDescriptorLength, <BR> PDWORD pdwReturnLength);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>GetPrivateObjectSecurity函数取得一个指向私有安全对象的安全描述项指标,并传回所要求的安全描述项。您可以使用熟悉的secInfo参数以指出您想撷取对象安全描述项的哪个部分。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>您必须提供一个够大的缓冲器来包含持有要求资讯的安全描述项。一旦得到要求的缓冲器大小时,便可以呼叫GetPrivateObjectSecurity函数,并且再一次撷取资讯。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>在您拥有对象的安全描述项后,必须修改它,然后再使用SetPrivateObjectSecurity函数重新设定修改过的安全描述项给私有对象。</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL SetPrivateObjectSecurity{ <BR> SECURITY_INFORMATION secInfo, <BR> PSECURITY_DESCRIPTOR psdModificationDescriptor, <BR> PSECURITY_DESCRIPTOR *ppsdObjectsSecurityDescriptor, <BR> PGENERIC_MAPPING&nbsp;&nbsp;gmGenericMapping, <BR> HANDLE&nbsp;&nbsp; hClientToken);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>secInfo参数指出「修改安全描述项」中的哪些资讯已被设定到对象的私有安全描述项中。您可以传递PSECURITY_DESCRIPTOR变数的位址,它包含一个指向对象私有安全描述项的指标。SetPrivateObjectSecurity函数会释放安全描述项,并以新的安全描述项取代它,其位址从提供的指标变数中传回。您也必须传递hClientToken参数,以使系统可以确认对象拥有者的设定,及其通用的对应结构。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>安全描述项的修改通常会使用以下这些步骤执行:</FONT></P><FONT 
            style="LINE-HEIGHT: 25px" face=arial color=#000000 size=2>
            <OL style="LINE-HEIGHT: 25px">
              <LI style="LINE-HEIGHT: 25px">撷取对象的安全描述项。 
              <LI style="LINE-HEIGHT: 25px">建立及初始新的安全描述项(本章稍早曾示范)。 
              <LI style="LINE-HEIGHT: 25px">从原始的安全描述项复制安全性资讯到新的安全描述项。 
              <LI style="LINE-HEIGHT: 25px">修改新的安全描述项(使用遍及本章所叙述的技巧)。 
              <LI style="LINE-HEIGHT: 25px">把新的安全描述项放回私人对象。 </LI></OL></FONT>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>为了取得安全描述项的个别元件,您应该使用以下的函数:即GetSecurityDescriptorOwner、GetSecurityDescriptorDacl、GetSecurityDescriptorSacl及GetSecurityDescriptorGroup。为了设定新安全描述项的内部元件,您可以使用SetSecurityDescriptorOwner、SetSecurityDescriptorDacl、SetSecurity 
            DescriptorSacl、SetSecurityDescriptorGroup来设定。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>这些函数都很相似,所以我准备展示及讨论最常见与复杂GetSecurityDescriptorDacl及SetSecurityDescriptorDacl函数。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>以下是GetSecurityDescriptorDacl函数原型:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL GetSecurityDescriptorDacl( <BR> PSECURITY_DESCRIPTOR pSecurityDescriptor, <BR> PBOOL pfDACLPresent, <BR> PACL *pDACL,&nbsp;&nbsp;<BR> PBOOL pfDACLDefaulted);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>这个函数撷取一个指向安全描述项的DACL指标,也指出DACL是否为当前的,以及它起初是否已透过预设安全性建立。您所提供之安全描述项与Boolean值的位址会指出DACL是否为当前的,而PACL变数的位址则用来撷取DACL;另一个Boolean值位址,系统用它来指出DACL是否被设为预设值。</FONT></P>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>为了将DACL放回安全描述项,您可以使用SetSecurityDescriptorDacl函数:</FONT></P>
            <DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT 
            style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL SetSecurityDescriptorDacl( <BR> PSECURITY_DESCRIPTOR pSecurityDescriptor, <BR> BOOL bDaclPresent, <BR> PACL pDacl, <BR> BOOL bDaclDefaulted);</PRE></FONT></DIV>
            <P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000 
            size=2>这个函数仅取得指向您想修改之安全描述项对象的指标,而Boolean值则指出DACL是否为当前的,以及它是否为预设安全性的结果(您通常会传递FALSE值)。SetSecurityDescriptorDacl函数要求一个指向DACL的指标,这

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?