10.1.4 存取控制.htm
来自「Windows2000后台服务程序开发手册」· HTM 代码 · 共 526 行 · 第 1/4 页
HTM
526 行
size=2>如果这个标记是从父对象继承过来的,则在ACE中设定这个标记,这可让系统区别直接作用的ACEs及因为继承而自动作用的ACEs。</FONT></TD></TR>
<TR style="LINE-HEIGHT: 25px">
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>CONTAINER_INHERIT_ACE</FONT></TD>
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>拥有这个ACE的对象,其子系的容器对象将会继承这个ACE,以做为有效的ACE。</FONT></TD></TR>
<TR style="LINE-HEIGHT: 25px">
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
face=arial size=2> </FONT></TD>
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>这种继承为预设的,然而,如果也有设定NO_PROPAGATE_INHERIT_ACE标记的话,直系的子系可以设定为停止继承。假如这个位元没有被设定,但是有设定OBJECT_INHERIT_ACE位元,则ACE将会继承容器对象,并为容器的ACE设定INHERIT_ONLY_ACE标记。</FONT></TD></TR>
<TR style="LINE-HEIGHT: 25px">
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>OBJECT_INHERIT_ACE</FONT></TD>
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>这个ACE被继承且作用于自有对象的非容器及子对象。对于容器的子对象,除非也有设定CONTAINER_INHERIT_ACE标记,否则ACE只能如继承ACE一样被继承。</FONT></TD></TR>
<TR style="LINE-HEIGHT: 25px">
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
face=arial size=2> </FONT></TD>
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>假如设定了NO_PROPAGATE_INHERIT_ACE标记及CONTAINER_INHERIT_ACE标记,有设定OBJECT_
NHERIT_ACE位元的ACE将不会继承容器对象。</FONT></TD></TR>
<TR style="LINE-HEIGHT: 25px">
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>INHERIT_ONLY_ACE</FONT></TD>
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>这个ACE在拥有ACE的对象上无作用,不过它在子容器或非容器子对象上可能有效。</FONT></TD></TR>
<TR style="LINE-HEIGHT: 25px">
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
face=arial size=2> </FONT></TD>
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>它对于有设定INHERIT_ONLY_ACE标记的ACE是无效的,除非CONTAINER_INHERIT_ACE及OBJECT_INHERIT_ACE标记的其中一个或两个有被设定。</FONT></TD></TR>
<TR style="LINE-HEIGHT: 25px">
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>NO_PROPAGATE_INHERIT_ACE</FONT></TD>
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>在ACE中设定这个标记会使它只能被继承一次。继承的ACEs将清除它们的OBJECT_INHERIT_
ACE及CONTAINER_INHERIT_ACE标记,以至于新的ACEs不会被继承。</FONT></TD></TR>
<TR style="LINE-HEIGHT: 25px">
<TD style="LINE-HEIGHT: 25px" colSpan=2><FONT
style="LINE-HEIGHT: 25px" size=2>稽核标记</FONT></TD></TR>
<TR style="LINE-HEIGHT: 25px">
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>FAILED_ACCESS_ACE_FLAG</FONT></TD>
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>在SACL中,假如存取被要求,且结果是ACCESS_DENIED时,设定这个位元的ACE将产生稽核事件。</FONT></TD></TR>
<TR style="LINE-HEIGHT: 25px">
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>SUCCESSFUL_ACCESS_ACE_FLAG</FONT></TD>
<TD style="LINE-HEIGHT: 25px"><FONT style="LINE-HEIGHT: 25px"
size=2>与SACL中的系统稽核ACEs一起使用,为成功的存取尝试产生稽核讯息。</FONT></TD></TR></TBODY></TABLE></CENTER>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>除了ACE类型及标记之外,ACE_HEADER结构的AceSize成员会指出讨论中的ACE大小。如您所见的,ACE_HEADER包含了关于ACE的丰富资讯数量。事实上,在呼叫GetAce时,如果您只要撷取有关ACE的继承及类型资讯时,可以不用看到太深入的ACE_HEADER结构。以下的程序代码片段显示了如何呼叫GetAce,以撷取ACE的类型:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">ACE_HEADER* pACEHeader ; <BR>GetAce(pDACL, 0, (PVOID*)&pACEHeader); <BR>switch(pACEHeader->AceType ){ <BR> // 根据ACE的类型作用 <BR>}</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>既然您在ACE中通常不只要求类型及继承式样的资讯,您必须探寻ACE_HEADER的内容。有两种主要的ACEs类型—标准及对象,标准ACEs不是对象ACEs的ACEs;对象ACEs只与Active
Directory一起使用。它们被称为对象ACEs是因为它们包含了GUIDs,GUIDs使它们与目录服务可得的许多对象类型一起工作成为可能。标准ACEs无疑是最常见的,所以我们将首先讨论。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e80d7
size=2><B
style="LINE-HEIGHT: 25px"> 标准ACEs </B></FONT>系统中大部分的安全对象专门处理标准ACEs。存在于Active
Directory的对象是例外的情形,它被称为<FONT style="LINE-HEIGHT: 25px" face=arial
color=#3e80d7 size=2><B
style="LINE-HEIGHT: 25px"> 目录服务对象 </B></FONT>。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>就像所有的ACEs一般,标准ACEs由叁种结构来表示,分别是允许存取、拒绝存取及稽核。以下是每个结构的定义:</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 _ACCESS_DENIED_ACE { <BR> ACE_HEADER Header; <BR> ACCESS_MASK Mask; <BR> DWORD SidStart; <BR>}ACCESS_DENIED_ACE; <BR>typedef struct _ACCESS_ALLOWED_ACE { <BR> ACE_HEADER Header; <BR> ACCESS_ MASK Mask; <BR> DWORD SidStart; <BR>}ACCESS_ALLOWED_ACE; <BR>typedef struct _SYSTEM_AUDIT_ACE { <BR> ACE_HEADER Header; <BR> ACCESS_ MASK Mask; <BR> DWORD SidStart; <BR>}SYSTEM_AUDIT_ACE;</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>每个结构的定义是完全相同的,都包括允诺的Header成员,即目前熟悉的ACE_HEADER类型。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>剩下的两个成员相当容易了解。第一个是遮罩,是一个指出存取权利被拒绝、允许或稽核的32位元遮罩。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>接下来将立即讨论存取权利的重要细节,但是请记得对一个给定的对象类型,其存取权利被分为通用、标准及特殊权利,并被组合成个别的32位元值。这个32位元值是ACE的<FONT
style="LINE-HEIGHT: 25px" face=arial color=#3e80d7 size=2><B
style="LINE-HEIGHT: 25px"> 遮罩 </B></FONT>成员。有关存取遮罩格式,请看 </FONT></A><FONT
style="LINE-HEIGHT: 25px" face=arial color=#000000 size=2><A
style="LINE-HEIGHT: 25px"
href="http://www.acejoy.com/doc/serverside/10.htm#485_1"
target=_new>图10-2</A> 。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>ACE结构的最后一个成员是SidStart,它指出ACE拒绝、允许或稽核存取这个对象的信任成员帐户的SID起点。这个成员需要稍作讨论。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>请记得SID(在第九章讨论过)是个可变长度的二进制结构,它指出系统的信任成员帐户。因为每个ACE包含SID,ACE结构也是一个可变长度的结构。SidStart成员是一个包含在ACE中的SID起点的预留位置。SidStart值(及类型)是不恰当且不应该被存取的,因为它实际上是SID结构的第一对位元组。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>您可能会发现以下的巨集指令对于从ACE结构取得SID是很有用的:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">#define PSIDFromPACE(pACE)((PSID)(&((pACE)->SidStart)))</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>这个特殊的巨集指令取得指向任何ACE结构的指标-即对象或标准ACE-并且传回指向ACE的SID结构的指标。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>标准ACE类型被分成叁种不同的结构,当您为ACL建立ACEs时,主要被用来作为逻辑的预留位置。然而,因为每个ACE结构是完全相同的,从DACL读取ACEs时,常见的情形是只编写使用其中一个ACE类型的程序代码,而不使用ACE_HEADER结构的AceType成员来维护ACE类型。以下的函数使用了此种技巧,并印出DACL中每个ACE的资讯:</FONT></P><A
style="LINE-HEIGHT: 25px" name=414_1>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">void DumpACL( PACL pACL ){ <BR> __try{ <BR> if (pACL == NULL){ <BR> _tprintf(TEXT("NULL DACL\n")); <BR> __leave; <BR> } <BR> ACL_SIZE_INFORMATION aclSize = {0}; <BR> if (!GetAclInformation(pACL, &aclSize, sizeof(aclSize), <BR> AclSizeInformation)) <BR> __leave; <BR> _tprintf(TEXT("ACL ACE count: %d\n"), aclSize.AceCount); <BR> struct{ <BR> BYTE lACEType; <BR> PTSTR pszTypeName; <BR> }aceTypes[6] == { <BR> {ACCESS_ALLOWED_ACE_TYPE, TEXT("ACCESS_ALLOWED_ACE_TYPE")}, <BR> {ACCESS_DENIED_ACE_TYPE, TEXT("ACCESS_DENIED_ACE_TYPE")}, <BR> {SYSTEM_AUDIT_ACE_TYPE,TEXT("SYSTEM_AUDIT_ACE_TYPE")}, <BR> {ACCESS_ALLOWED_OBJECT_ACE_TYPE, <BR> TEXT("ACCESS_ALLOWED_OBJECT_ACE_TYPE")}, <BR> {ACCESS_DENIED_OBJECT_ACE_TYPE, <BR> TEXT("ACCESS_DENIED_OBJECT_ACE_TYPE")}, <BR> {SYSTEM_AUDIT_OBJECT_ACE_TYPE, <BR> TEXT("SYSTEM_AUDIT_OBJECT_ACE_TYPE")}}; <BR> struct{ <BR> ULONG lACEFlag; <BR> PTSTR pszFlagName; <BR> }aceFlags [7 ] =={ <BR> {INHERITED_ACE, TEXT("INHERITED_ACE")}, <BR> {CONTAINER_INHERIT_ACE, TEXT("CONTAINER_INHERIT_ACE")}, <BR> {OBJECT_INHERIT_ACE, TEXT("OBJECT_INHERIT_ACE")}, <BR> {INHERIT_ONLY_ACE, TEXT("INHERIT_ONLY_ACE")}, <BR> {NO_PROPAGATE_INHERIT_ACE, TEXT("NO_PROPAGATE_INHERIT_ACE")}, <BR> {FAILED_ACCESS_ACE_FLAG, TEXT("FAILED_ACCESS_ACE_FLAG")}, <BR> {SUCCESSFUL_ACCESS_ACE_FLAG, <BR> TEXT("SUCCESSFUL_ACCESS_ACE_FLAG")}}; <BR> for (ULONG lIndex = 0; lIndex < aclSize.AceCount; lIndex++){ <BR> ACCESS_ALLOWED_ACE* pACE; <BR> if (!GetAce(pACL, lIndex, (PVOID*)&pACE)) <BR> __leave; <BR> _tprintf(TEXT("\nACE #%d\n"), lIndex); <BR> ULONG lIndex2 = 6; <BR> PTSTR pszString = TEXT("Unknown ACE Type"); <BR> while (lIndex2--){ <BR> if(pACE->Header.AceType == aceTypes [lIndex2 ].lACEType){ <BR> pszString = aceTypes[lIndex2].pszTypeName; <BR> } <BR> } <BR> _tprintf(TEXT(" ACE Type =\n \t%s\n"), pszString); <BR> _tprintf(TEXT(" ACE Flags = \n")); <BR> lIndex2 = 7; <BR> while (lIndex2--){ <BR> if ((pACE->Header.AceFlags &aceFlags [lIndex2 ].lACEFlag) <BR> !=0) <BR> _tprintf(TEXT(" \t%s\n"), <BR> aceFlags[lIndex2].pszFlagName); <BR> } <BR> _tprintf(TEXT(" ACE Mask ((32->0)=\n \t ")); <BR> lIndex2 = (ULONG)1<<31; <BR> while (lIndex2){ <BR> _tprintf(((pACE->Mask &lIndex2) != 0)?TEXT("1"):TEXT("0")); <BR> lIndex2>>=1; <BR> } <BR> TCHAR szName[1024]; <BR> TCHAR szDom[1024]; <BR> PSID pSID = PSIDFromPACE(pACE); <BR> SID_NAME_USE sidUse; <BR> ULONG lLen1 = 1024, lLen2 = 1024; <BR> if (!LookupAccountSid(NULL, pSID, <BR> szName, &lLen1, szDom, &lLen2, &sidUse)) <BR> lstrcpy(szName, TEXT("Unknown")); <BR> PTSTR pszSID; <BR> if (!ConvertSidToStringSid(pSID, &pszSID)) <BR> __leave; <BR> _tprintf(TEXT("\n ACE SID = \n \t%s (%s)\n"), pszSID, szName); <BR> LocalFree(pszSID); <BR> } <BR> }__finally{} <BR>}</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>ACEs的所有ACE类型倾印了ACCESS_ALLOWED_ACE结构,这个结构对任何标准ACE类型(尽管这个函数对对象ACEs将失去作用)都能作用,因为所有标准ACE结构都相同。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>以下的程序片段可以与DumpACL函数一起被用来显示NTFS共享目录中的ACEs:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">PSECURITY_DESCRIPTOR pSD; <BR>PACL pDACL; <BR>ULONG lErr = GetNamedSecurityInfo(TEXT("C:\\Test\\Test"), <BR> SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, <BR> &pDACL, NULL, &pSD); <BR>if (lErr == ERROR_SUCCESS){ <BR> DumpACL(pDACL); <BR>}</PRE></FONT></DIV>
<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>DumpACL范例函数说明了如何读取DACL中的ACE资讯。您会在自己编写的程序代码中发现像这样有用的程序代码。您也会发现以DumpACL函数作为除错工具是很有帮助的,尤其是当您开始编写程序代码去修改安全对象的DACL时。在您作了修改的前后,使用它来倾印对象的DACL内容,以查看您的程序代码是否产生了所要求的结果。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>这种技巧胜过使用浏览器的安全属性页检视安全性,因为系统的使用者介面不会逐字显示对象的ACE资讯。事实上,使用者介面不会显示没有事先在DACL中适当地安排ACEs顺序的DACL。</FONT></P>
<HR style="LINE-HEIGHT: 25px">
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>因为ACE结构的性质可让您发现它对定义一个表示每个ACE类型的Union很有帮助。于是就一个指向Union类型的指标来说,您可以处理从GetAce传回的ACEs。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>以下的程序代码显示一个使用此类技巧的范例:</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 union _ACE_UNION{ <BR> ACE_HEADER aceHeader; <BR> ACCESS_ALLOWED_ACE aceAllowed; <BR> ACCESS_DENIED_ACE aceDenied; <BR> SYSTEM_AUDIT_ACE aceAudit; <BR>}*PACE_UNION; <BR>PACE_UNION pACE ; <BR>GetAce(pDACL, 0, (PVOID*)&pACE); <BR>switch (pACE->aceHeader.AceType){ <BR>. <BR>. <BR>.</PRE></FONT></DIV></A><A
style="LINE-HEIGHT: 25px" name=521_1>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e80d7
size=2><B
style="LINE-HEIGHT: 25px"> 对象ACEs </B></FONT>除非您要编写保护及修改Active
Directory对象安全性的程序代码,否则您不可能会在自己的应用程序中使用对象ACEs。然而,Active
Directory是Windows
2000的一个重要元件,了解它保护对象安全的方法并没有害处。我们不会花太多时间在这个主题上,此处的说明只是为了避免混淆您对标准ACEs的认识。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>就像标准ACES一样,对象ACEs有叁种结构:拒绝、允许及稽核信任成员存取权利。以下是对象ACEs的结构:</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 _ACCESS_ALLOWED_OBJECT_ACE { <BR> ACE_HEADER Header; <BR> ACCESS_ MASK Mask; <BR> DWORD Flags; <BR> GUID ObjectType; <BR> GUID InheritedObjectType; <BR> DWORD SidStart; <BR>} ACCESS_ALLOWED_OBJECT_ACE, *PACCESS_ALLOWED_OBJECT_ACE; <BR>typedef struct _ACCESS_DENIED_OBJECT_ACE { <BR> ACE_HEADER Header; <BR> ACCESS_MASK Mask; <BR> DWORD Flags; <BR> GUID ObjectType; <BR> GUID InheritedObjectType; <BR> DWORD SidStart; <BR>} ACCESS_DENIED_OBJECT_ACE, *PACCESS_DENIED_OBJECT_ACE; <BR>typedef struct _SYSTEM_AUDIT_OBJECT_ACE { <BR> ACE_HEADER Header; <BR> ACCESS_MASK Mask; <BR> DWORD Flags; <BR> GUID ObjectType; <BR> GUID InheritedObjectType; <BR> DWORD SidStart; <BR>} SYSTEM_AUDIT_OBJECT_ACE, *PSYSTEM_AUDIT_OBJECT_ACE;</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>就像标准ACEs一样,除了附加的Flags、ObjectType及InheritedObjectType成员外,每个结构类型及结构的成员都相同。</FONT></P>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?