Windows安全描述符SECURITY_DESCRIPTOR

安全对象Securable Object是拥有SD的Windows的对象。
所有的被命名的Windows的对象都是安全对象。一些没有命名的对象是安全对象,如:进程和线程,也有安全描述符SD。安全对象Securable Object是拥有SD的Windows的对象。
在 Windows系统中,其是用一个安全描述符(Security Descriptors)的结构来保存其权限的设置信息,简称为SD,其在Windows SDK中的结构名是“SECURITY_DESCRIPTOR”,这是包括了安全设置信息的结构体。一个安全描述符包含以下信息:
? 一个安全标识符(Security identifiers),其标识了该信息是哪个对象的,也就是用于记录安全对象的ID。简称为:SID。
? 一个DACL(Discretionary Access Control List),其指出了允许和拒绝某用户或用户组的存取控制列表。 当一个进程需要访问安全对象,系统就会检查DACL来决定进程的访问权。如果一个对象没有DACL,那么就是说这个对象是任何人都可以拥有完全的访问权限。
? 一个SACL(System Access Control List),其指出了在该对象上的一组存取方式(如,读、写、运行等)的存取控制权限细节的列表。
? 还有其自身的一些控制位。
DACL和SACL构成了整个存取控制列表Access Control List,简称ACL,ACL中的每一项,我们叫做ACE(Access Control Entry),ACL中的每一个ACE

访问控制链表(ACL)
一个
ACL 是一个 ACE 链表。每个 ACL 中的 ACE 标示一个托管以及指定允许的访问权限、否定或托管的设计。一个对象的安全描述符号包含两种类型的 ACL ,一个是 DACL ,一个是 SACL

一个目录访问控制链表( DACL )标示允许或拒绝访问一个安全对象的托管。当一个进程常识访问一个安全对象的时候,系统检查对象的 DACL 中的 ACE 来决定是否赋予访问权限。如果对象没有 DACL ,系统赋予完全的访问权限,如果对象的 DACL 没有 ACE ,那么系统拒绝所有访问对象的尝试,因为 DACL 不允许任何访问权限。系统检查 ACE 序列直到找到一到多个 ACE ,或者直到任何请求的访问权限被否定。更多的信息参见: DACL 怎么样控制一个对象的。对于创建 DACL 的信息,见创建一个 DACL

一个系统访问控制链表( SACL )是管理员登录尝试访问一个安全对象。每个 ACE 指定一个指定的托管尝试的访问类型,这个访问会导致系统产生一个安全事件日志。一个 SACL 中的 ACE 能够产生访问尝试失败或成功的时候产生评估记录,在将来的 release 中,一个 SACL 在一个未授权用户尝试访问一个对象的时候发出一个警告。更多 SACL 的信息参见 Audit Generation SACL 访问权限。

不要尝试直接使用一个 ACL 来工作。为了确保 ACL 能够语义正确的,使用适当的函数来创建和操纵 ACL 。更多的信息参见:从 ACL 中取得信息和创建或修改一个 ACL

ACL 也提供访问控制微软的 Active Directory 目录服务对象。活动目录服务接口( ADSI )包括创建和修改 ACL 内容的程序。更多信息参见:控制访问活动目录对象

访问控制实体(ACE
一个访问控制实体(
ACE)是ACL中的一个元素。一个ACL可能包含0到多个ACE。每个ACE通过一个指定的托管来控制或监视一个对象。更多关于添加、删除、改变ACE,见修改ACL对象。

Window Me/98/95:不支持访问控制

6种类型的ACE,三种被所有的安全对象支持,其他类型是对象特定的ACE,由目录服务对象支持。

所有ACE类型都包含下面访问控制信息:

1.  一个安全标示符号(SID)来标示ACE应用的托管

2.  一个访问掩码指定ACE控制的访问权限

3.  一个指示ACE类型的标志位

4.  一系列位标志决定是否子容器或对象可以继承ACE从基本对象到ACL附着的对象。

下表列出了三个所有安全对象支持的ACE类型:

 

Type

Description

访问拒绝ACE

用在一个DACL中拒绝到一个托管的访问权限

访问允许ACE

用在一个DACL中允许到托管的访问权限

系统评估ACE

用在SACL中,当托管尝试检查指定访问权限时产生一个评估记录

对于对象指定的ACE,参见对象指定ACE

注意,系统警告ACE对象现在不支持。


托管

一个托管是一个用户帐户、组帐户或登录会话到一个ACE应用。每个ACL中的ACE都有一个SID来标示托管。用户帐户包含人使用的帐户或程序帐户(例如,Window服务用来登录到本地计算机的)。组帐户不能用来登录到计算机,但在ACE中非常有用,用来拒绝或允许一到多个用户帐户的访问权限。一个登录SID表示当前的登录会话用来允许和拒绝访问权限,直到用户登出。

NT4.0和后来版本中访问控制函数使用TRUSTEE结构体来表示一个托管。这个结构体能使你用一个字符串或一个SID来表示一个托管。如果你使用一个名字,从TRUSTEE结构创建ACE的函数执行SID缓冲区分配工作并且查询SID对应的帐户名称。有两个助手函数,BuildTrusteeWithSidBuildTrusteeWithName,可以用SID或名字来初始化一个TRUSTEE结构。BuildTrusteeWithObjectsAndSidBuildTrusteeWithObjectsAndName允许你使用一个对象指定的ACE信息来初始化一个TRUSTEE结构体。其他3个助手函数,GetTrusteeFrormGetTrusteeNameGetTrusteeType,返回TRUSTEE结构各成员的值。
Window XP/2000TRUSTEEptstrName成员可以是一个指向OBJECTS_AND_NAMEOBJECTS_AND_SID结构体的指针。这些结构体说明对象指定ACE的信息,除了托管的名字和SID之外。这可以象SetEntriesInAclGetExplicitEntriesFromAcl这样的函数存储对象指定ACE的信息到EXPLICIT_ACCESS结构体的Trustee成员中。

TRUSTEE结构体:

typedef struct _TRUSTEE {
  PTRUSTEE pMultipleTrustee;
  MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation;
  TRUSTEE_FORM TrusteeForm;
  TRUSTEE_TYPE TrusteeType;
  LPTSTR ptstrName;

} TRUSTEE, *PTRUSTEE;

访问权限和访问掩码

一个访问权限是一个标志位对应到一个特殊操作集合,这个集合表示线程可以在安全对象上执行的操作。例如:注册表键KEY_SET_VALUE访问权限,对应到线程在这个键下设置的值的能力。如果线程想在一个对象执行一个操作,但没有必要的访问权限,系统不执行操作。

一个访问掩码是一个32位的值,它对应到对象支持的访问权限。所有的Windows NT/2000/XP 安全对象使用一个Windows访问掩码格式,这个格式包含下面的访问权限位:

1.  通用访问权限

2.  标准访问权限

3.  SACL访问权限

4.  目录服务访问权限

当一个线程想打开一个对象的句柄,线程通常指定一个访问掩码来请求一系列的访问权限。例如,需要设置和查询注册表键的程序可以使用一个访问掩码来请求KEY_SET_VALUEKEY_QUERY_VALUE访问权限来打开该键。

下面表显示了操作每种类型安全对象的信息:

 

对象类型

安全描述符号函数

NTFS上的文件或目录系统

GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

命名管道和匿名管道

GetSecurityInfo, SetSecurityInfo

控制台屏幕缓冲区

Not supported.

进程和线程

GetSecurityInfo, SetSecurityInfo

文件映射对象

GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

Access tokens

SetKernelObjectSecurity, GetKernelObjectSecurity

Windows管理对象 (windows工作站和桌面)

GetSecurityInfo, SetSecurityInfo

注册表键

GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

Windows服务

GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

本地和远程打印机

GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

网络共享

GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

进程间同步对象 (事件, mutexes, semaphores, and waitable timers)

GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

作业对象

GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo


通用访问权限

安全对象使用Windows 访问掩码格式,四个高位说明通用访问权限。每个安全对象类型映射到这些位到一系列标准和对象特殊访问权限。例如:一个Window文件对象映射GENERIC_READ位到READ_CONTROLSYNCHRONIZE 标准访问权限和FILE_READ_DATAFILE_READ_EAFILE_READ_ATTRIBUTES对象指定访问权限。其他类型对象映射GENERIC_READ位到与类型对象适应的一些访问权限。

你可以在你打开一个对象句柄的时候使用通用访问权限来指定需要的访问类型;这通常比指定所有对应标准和特指权限要简单。

下表显示了通用访问权限定义的常量。

 

常量

解释

GENERIC_ALL

读、写和执行访问

GENERIC_EXECUTE

执行

GENERIC_READ

GENERIC_WRITE

应用程序定义的私有安全访问对象能使用通用访问权限。

安全描述符(SD)

安全描述符包含了安全对象相关的安全信息。安全描述父由一个SECURITY_DESCRIPTOR结构体组成,它关联到一个安全对象。一个安全描述符包含下面的安全信息:

1.  拥有者或基本组对象的安全IDSIDs

2.  DACL指定特殊用户或组的允许或拒绝的访问权限

3.  SACL指定对象通用评估记录尝试的访问类型

4.  一个控制位集合,说明安全描述符的含义或它每个成员

程序不需要直接操作安全描述符的内容。Windows API提供设置和返回安全描述符号的函数。另外,有用来创建和初始化一个新对象安全描述符号的函数。

Windows NT 3.51和更早的版本,Windows ME/98/95:参见:低级访问控制。

工作在活动目录对象上安全描述符程序能使用Windows的安全函数或ADSI(活动目录服务接口)提供的安全接口。更多ADSI的信息参见:访问控制如何在活动目录中工作?


DACL是怎么控制访问对象的?

当一个线程想访问一个安全对象时候,系统要么允许访问,要拒绝访问。如果对象没有DACL,系统赋予访问权限,否则系统查找DACL中的该线程的ACE。每个对象DACL中的ACE指定托管的访问允许或拒绝的访问权限,它可以是一个用户帐户、组帐户或登录会话。

系统比较ACE中的托管和线程访问标记的托管标示。一个访问标记包含SID来说明用户和用户输入的组帐户。一个标记也包含一个登录SID,来表示当前的登录会话。在访问检查期间,系统忽略不可用的组SID。更多可用不可用信息以及拒绝SID,见访问标记中的SID属性。

通常,系统使用现成饿基本访问标记来请求访问。然而,如果现成正在扮演其他用户,系统使用现成的扮演标记。

系统家产序列中的每个ACE,直到下面的情况发生:

1.  一个显式拒绝任何与线程访问标记中列出托管不同的访问ACE出现

2.  线程访问标记中列出的一个或多个允许访问的ACE出现,这个标记显式赋予所有权限。

3.  所有的ACE都检查过,并且至少一个访问权限没有显式的允许,这种情况下暗示拒绝。

下图描述一个DACL对象允许访问一个线程而拒绝访问另一个线程。

ACL.JPG


对于线程
A,系统读ACE1并且立即拒绝访问,因为访问拒绝ACE应用到线程访问标记中的用户。这种情况下,系统并没有检查ACE23。对于线程BACE1没有应用,因此系统处理ACE2,其允许写操作,并且ACE3允许读和执行操作。

因为系统在请求访问并显式允许或拒绝的时候停止检查,DACL中的ACE顺序非常重要。注意,如果ACE顺序与例子中的不同,系统可能分配访问权限给A。对于系统对象,操作系统定义一个首选的DACLACE的顺序。


创建一个DACL

创建适当的 DACL 是你程序开发中必要和重要的,因为一个 NULL DACL 允许所有用户所有访问权限,不要使用 NULL DACL

下面例子演示了如何正常创建一个 DACL 。例子,包含一个函数, CreateMyDACL ,用安全描述符定义语言( SDDL )来定义那些赋予的和拒绝的 DACL 中的访问控制。为了提供对你程序对象的不同访问,根据你的需要来修改 CreateMyDACL

在例子中:

1.       main 函数传递一个 SECURITY_ATTRIBUTES 结构体的地址给 CreateMyDACL 函数

2.       CreateMyDACL 函数使用 SDDL 字符串来:

?        拒绝 guest 和匿名登录用户访问

?        允许授权用户的读 / / 执行访问

?        允许管理员所有控制

3.       更多的 SDDL 字符串格式

4.       CreateMyDACL 函数调用 ConvertStringSecurityDescriptorToSecurityDescriptor 函数转换 SDDL 字符串为一个安全描述符。安全描述符号通过 SECURITY_ATTRIBUTES 结构体的 lpSecurityDescriptor 成员来指定。 CreateMyDACL 发送 ConvertStringSecurityDescriptorToSecurityDescriptor 的返回值给 main 函数。

5.       main 函数完成使用 SECURITY_ATTRIBUTES 结构体时, main 函数释放 lpSecurityDescriptor 成员的内存,调用 LocalFree 函数来完成。

注意,成功编译 SDDL 函数,例如: ConvertStringSecurityDescriptorToSecurityDescriptor, 你必须定义 _WIN32_WINNT 常量为 0x0500 或更大。 SDDL Windows 2003 家族 ,Windows XP 2000 操作系统上可用。

 

Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935
 1Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935#define _WIN32_WINNT 0x0500
 2Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935
 3Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935#include <windows.h>
 4Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935#include <sddl.h>
 5Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935#include <stdio.h>
 6Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935
 7Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935BOOL CreateMyDACL(SECURITY_ATTRIBUTES *);
 8Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935
 9Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935void main()
10Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935{
11Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     SECURITY_ATTRIBUTES  sa;
12Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
13Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     sa.bInheritHandle = FALSE;  
14Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     // Call function to set the DACL. The DACL
15Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     // is set in the SECURITY_ATTRIBUTES 
16Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     // lpSecurityDescriptor member.
17Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     if (!CreateMyDACL(&sa))
18Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935{
19Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935         // Error encountered; generate message and exit.
20Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935         printf("Failed CreateMyDACL/n");
21Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935         exit(1);
22Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     }

23 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935
24 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //  Use the updated SECURITY_ATTRIBUTES to specify
25 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //  security attributes for securable objects.
26 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //  This example uses security attributes during
27 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //  creation of a new directory.
28 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935       if  ( 0   ==  CreateDirectory(TEXT( " C://MyFolder " ),  & sa))
29 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 {
30 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935          //  Error encountered; generate message and exit.
31 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935          printf( " Failed CreateDirectory/n " );
32 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935         exit( 1 );
33 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     }
34 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935
35 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //  Free the memory allocated for the SECURITY_DESCRIPTOR.
36 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935       if  (NULL  !=  LocalFree(sa.lpSecurityDescriptor))
37 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 {
38 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935          //  Error encountered; generate message and exit.
39 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935          printf( " Failed LocalFree/n " );
40 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935         exit( 1 );
41 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     }
42 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935}
43 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935
44 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935
45 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //  CreateMyDACL.
46 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //     Create a security descriptor that contains the DACL you want.
47 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //     This function uses SDDL to make Deny and Allow ACEs.
48 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //
49 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //  Parameter:
50 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //     SECURITY_ATTRIBUTES * pSA
51 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //     Pointer to a SECURITY_ATTRIBUTES structure. It is the caller's
52 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //     responsibility to properly initialize the structure and to free 
53 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //     the structure's lpSecurityDescriptor member when the caller has
54 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //     finished using it. To free the structure's lpSecurityDescriptor 
55 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //     member, call the LocalFree function.
56 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //  
57 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //  Return value:
58 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //     FALSE if the address to the structure is NULL. 
59 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //     Otherwise, this function returns the value from the
60 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 //     ConvertStringSecurityDescriptorToSecurityDescriptor function.
61 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 BOOL CreateMyDACL(SECURITY_ATTRIBUTES  *  pSA)
62 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935 {
63 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //  Define the SDDL for the DACL. This example sets 
64 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //  the following access:
65 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //      Built-in guests are denied all access.
66 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //      Anonymous logon is denied all access.
67 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //      Authenticated users are allowed read/write/execute access.
68 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //      Administrators are allowed full control.
69 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //  Modify these values as needed to generate the proper
70 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      //  DACL for your application. 
71 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      TCHAR  *  szSD  =  TEXT( " D: " )        //  Discretionary ACL
72 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935         TEXT( " (D;OICI;GA;;BG) " )      //  Deny access to built-in guests
73 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935         TEXT( " (D;OICI;GA;;;AN) " )      //  Deny access to anonymous logon
74 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935         TEXT( " (A;OICI;GRGWGX;;;AU) " //  Allow read/write/execute to authenticated users
75 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935         TEXT( " (A;OICI;GA;;;BA) " );     //  Allow full control to administrators
76 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935
77 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935     if  (NULL  ==  pSA)
78 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935         return  FALSE;
79 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935      return  ConvertStringSecurityDescriptorToSecurityDescriptor(
80 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935                szSD,
81 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935                SDDL_REVISION_1,
82 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935                 & (pSA -> lpSecurityDescriptor),
83 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935                NULL);
84 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935}
85 Windows安全描述符SECURITY_DESCRIPTOR - ZhengHangJie - 41620935

可保安全对象

一个安全对象有一个安全描述符。所有有名字的 Windows 对象都是安全的。有些没有名字的对象,例如:进程和线程对象也有安全描述符。对于大多数安全对象来说,你可以在创建对象的时候指定一个对象的安全描述符。例如:你能在 CreateFile CreateProcess 函数中指定安全描述符。

另外, Windows 安全函数是你能够为操作系统创建的而不是 Windows 创建的安全对象得到和设置安全信息。 Windows 安全函数也提供支持私有使用安全描述符和程序定义对象。更多关于私有安全对象信息参见客户服务器访问控制。

每个安全对象定义它自己的一系列访问权限,并且它拥有的映射通用访问权限。更多关于指定和通用访问权限的信息,参见对象类型总览。

下表显示了函数来操作通用安全对象的安全信息:

 

对象类型

安全描述符函数

NTFS文件系统的文件和目录

GetNamedSecurityInfo , SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

Named pipes

Anonymous pipes

GetSecurityInfo , SetSecurityInfo

Processes

Threads

GetSecurityInfo , SetSecurityInfo

File-mapping objects

GetNamedSecurityInfo , SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

Access tokens

SetKernelObjectSecurity , GetKernelObjectSecurity

Window-management objects ( window stations and desktops)

GetSecurityInfo , SetSecurityInfo

Registry keys

GetNamedSecurityInfo , SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

Windows services

GetNamedSecurityInfo , SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

Local or remote printers

GetNamedSecurityInfo , SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

Network shares

GetNamedSecurityInfo , SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

Interprocess synchronization objects (events, mutexes, semaphores, and waitable timers)

GetNamedSecurityInfo , SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

Job objects

GetNamedSecurityInfo , SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo

Directory service objects

These objects are handled by Active Directory Objects. See Active Directory Service Interfaces.


登录会话

一个登录绘画从用户登录到计算机时候开始。所有登录会话中的进程有相同的基本访问标记。访问标记包含登录会话相关的安全上下文,包含用户的 SID 和登录标示以及登录 SID

 

登录 SID

一个安全标示符( SID )用来表示登录会话。你可以使用 DACL 中的登录 SID 来在登录会话过程中控制访问。登录 SID 只有在用户登出的时候无效。登录 SID 是计算机运行的时候唯一的。没有其他会话有系统的 SID 。然而,可能的登录 SID 集合在计算机启动的时候被复位。为了从访问标记中返回登录 SID ,为 TokenGroups 调用 GetTokenInformation 函数。

 

访问标记

一个访问标记包含登录会话的安全信息。系统在用户登录的时候创建一个安全标记,每个进程执行用户由于的标记副本。标记表示用户、用户组和用户权限。系统使用标记来控制访问安全对象和控制用户在本地计算机上执行各种系统相关操作。两种访问标记:私有的和伪装的。

 

伪装标记:

一个被创建来捕获客户进程安全信息、允许服务器在安全操作中伪装客户进程的访问标记。

 

主标记:

一个 Windows 内核创建的标记。可能分配给一个进程来表示默认的进程安全信息。

Windows 操作系统中,安全描述符Security Descriptor,简称 SD)是一种用于描述系统对象(如文件、文件夹、注册表项等)安全属性的数据结构。它包括了许多信息,如所有者、组、访问控制列表(Access Control List,简称 ACL)等。在使用 SD 时,需要先初始化一个 PSECURITY_DESCRIPTOR 结构体。 下面是一个 PSECURITY_DESCRIPTOR 结构体的定义: ```c typedef struct _SECURITY_DESCRIPTOR { UCHAR Revision; UCHAR Sbz1; SECURITY_DESCRIPTOR_CONTROL Control; PSID Owner; PSID Group; PACL Sacl; PACL Dacl; } SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR; ``` 其中,`Revision` 字段用于指定 SECURITY_DESCRIPTOR 结构体的版本号;`Control` 字段包含了一些标志位,例如是否启用了自相交的 ACL 等;`Owner` 和 `Group` 字段分别指定了对象的所有者和所属组;`Sacl` 和 `Dacl` 字段分别指定了系统访问控制列表和离散访问控制列表。 初始化一个 PSECURITY_DESCRIPTOR 结构体可以通过以下步骤: 1. 调用 `InitializeSecurityDescriptor` 函数初始化结构体: ```c PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); ``` `InitializeSecurityDescriptor` 函数会初始化一个空的 SECURITY_DESCRIPTOR 结构体,其中 `SECURITY_DESCRIPTOR_REVISION` 是版本号。 2. 指定所有者和所属组。可以使用 `AllocateAndInitializeSid` 函数创建一个新的 SID 对象,并将其分配给所有者和所属组: ```c PSID pSidOwner = NULL; PSID pSidGroup = NULL; SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY; if (!AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSidOwner) || !AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &pSidGroup)) { LocalFree(pSD); return FALSE; } SetSecurityDescriptorOwner(pSD, pSidOwner, FALSE); SetSecurityDescriptorGroup(pSD, pSidGroup, FALSE); ``` 首先,使用 `AllocateAndInitializeSid` 函数创建了两个 SID,一个是管理员组的 SID,另一个是用户组的 SID。然后使用 `SetSecurityDescriptorOwner` 和 `SetSecurityDescriptorGroup` 分别将它们赋值给 SECURITY_DESCRIPTOR 结构体的 `Owner` 和 `Group` 字段。 3. 添加 ACL。可以使用 `InitializeAcl` 函数初始化 ACL,再使用 `AddAccessAllowedAce` 函数向 ACL 中添加 ACE: ```c PACL pAcl = NULL; EXPLICIT_ACCESS ea; DWORD dwRes = 0; if (AllocateAndInitializeSid(&sidAuth, 1, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS, 0, 0, 0, 0, 0, 0, &ea.Trustee.ptstrName)) { ea.grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP; dwRes = SetEntriesInAcl(1, &ea, NULL, &pAcl); if (dwRes != ERROR_SUCCESS) { LocalFree(pSD); FreeSid(pSidOwner); FreeSid(pSidGroup); return FALSE; } SetSecurityDescriptorDacl(pSD, TRUE, pAcl, FALSE); FreeSid(ea.Trustee.ptstrName); } ``` 这里使用了一个 `EXPLICIT_ACCESS` 结构体来描述 ACE。`Trustee` 字段是一个 TRUSTEE 结构体,用于指定 ACE 的主体。这里将它设置为了访客组的 SID。`grfAccessPermissions` 字段指定了 ACE 的访问权限,这里设置了读写权限。`grfAccessMode` 字段指定了 ACL 的修改方式,这里设置为了 SET_ACCESS,表示覆盖原有 ACE。`grfInheritance` 字段指定了 ACE 是否应该被继承到子对象。最后,使用 `SetEntriesInAcl` 函数将 ACE 添加到 ACL 中,然后使用 `SetSecurityDescriptorDacl` 函数将 ACL 赋值给 SECURITY_DESCRIPTOR 结构体的 `Dacl` 字段。 4. 释放资源。完成后需要释放先前分配的资源: ```c LocalFree(pSD); FreeSid(pSidOwner); FreeSid(pSidGroup); ``` 这里使用了 `LocalFree` 函数释放 SECURITY_DESCRIPTOR 对象,和 `FreeSid` 函数释放所有者、所属组和 ACE 的 SID。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值