什么是ACL SACL DACL ACE SDDL

DACL自由访问控制列表:对对象持有者控制访问对象,并标明特定的用户,特定的组是否能持有对象。简单一句话就是说,定义哪个用户,或哪个用户所属的组访问该对象的权限。

SACL系统访问控制列表:用来记录某个安全对象被访问的情况,也可以理解为当用户去访问的时候具有对该安全对象的权限!,比如读、写、运行等的存取控制权限细节的列表

ACL访问控制列表:DACL和SACL构成了整个存取控制列表Access Control List

ACE访问控制项:ACL中的每一项,我们叫做ACE(Access Control Entry)

安全对象Securable Object: 是拥有SD(安全描述符)的Windows的对象,所有的被命名的Windows的对象都是安全对象,但是一些没有命名的对象是安全对象,如:进程和线程,也有安全描述符SD。


DACL是如何控制访问对象的:

当一个线程想访问一个安全对象时候,系统要么允许访问,要拒绝访问。

举个例子,当一个进程试图访问一个安全对象的时候,系统就检查该安全对象的DACL的每个ACE项,逐个与该进程的访问令牌作对比,来决定是否授权访问给进程,详细流程如下

如果一个安全对象没有DACL,系统就会授予该对象的所有访问权限给任何用户,这里也就说明了当我们win32编程中安全描述符为什么都为NULL,其实就是DACL来创建一个Everyone的ACL列表,那么就是任意用户都可以进行访问!

如果一个安全对象有DACL,但是DACL里面没有ACE,那么系统会拒绝对该对象的任何访问。


创建DACL:

这里自己用到CreateFileW的API函数,该函数的定义如下:

HANDLE CreateFileW(
  LPCWSTR               lpFileName,
  DWORD                 dwDesiredAccess,
  DWORD                 dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD                 dwCreationDisposition,
  DWORD                 dwFlagsAndAttributes,
  HANDLE                hTemplateFile
);

其中我们需要自定义LPSECURITY_ATTRIBUTES结构体

typedef struct _SECURITY_ATTRIBUTES {
	DWORD nLength;
	LPVOID lpSecurityDescriptor; //安全描述符由一个SECURITY_DESCRIPTOR结构体组成
	BOOL bInheritHandle;
}

在定义lpSecurityDescriptor,我们需要使用ConvertStringSecurityDescriptorToSecurityDescriptor来进行字符串转换描述符的操作,该字符串就是安全描述符定义语言(SDDL),那么也就是我们需要用SDDL形式的字符串来转换为描述符,然后将该描述符作为参数,再去自定义一个安全描述符!

SDDL的定义:https://docs.microsoft.com/zh-tw/windows/win32/secauthz/security-descriptor-definition-language

ConvertSecurityDescriptorToStringSecurityDescriptorConvertStringSecurityDescriptorToSecurityDescriptor,这两个函数都可以实现 SDDL -> 安全描述符 !

描述符的实现格式:https://docs.microsoft.com/zh-tw/windows/win32/secauthz/security-descriptor-string-format

O:owner_sid
G:group_sid
D:dacl_flags(string_ace1)(string_ace2)... (string_acen)  //这里就是需要用到ACE访问控制来进行定义 
S:sacl_flags(string_ace1)(string_ace2)... (string_acen)  //这里就是需要用到ACE访问控制来进行定义 

关于ACE访问控制的定义:https://docs.microsoft.com/zh-tw/windows/win32/secauthz/ace-strings

创建DACL实现代码:

#include<stdio.h>
#include<Windows.h>
#include<sddl.h>

BOOL CreateMyDACL(SECURITY_ATTRIBUTES* sa){
	wchar_t* szSD = TEXT("D:(D;OICI;GRGW;;;BA)");
	/*
	D:是一个拒绝访问的用户
	OICI:是一个允许 对象继承还有容器继承的.
	GAGR:是有可读可写的属性的.
	BA:使用的BA 说明指定的是内置管理员用户
	*/
	if (sa == NULL)
		return FALSE;
	return ConvertStringSecurityDescriptorToSecurityDescriptor(szSD, SDDL_REVISION_1, &(sa->lpSecurityDescriptor), NULL);
}


int main(){
	HANDLE hFile;
	SECURITY_ATTRIBUTES lpSecurity_attr;

	lpSecurity_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
	lpSecurity_attr.bInheritHandle = FALSE;
	if (!CreateMyDACL(&lpSecurity_attr))
	{
		// Error encountered; generate message and exit.
		printf("Failed CreateMyDACL
");
		exit(1);
	}


	hFile = CreateFile(L"test.txt",
		GENERIC_READ | GENERIC_WRITE, //通用访问权限,应用程序定义的私有安全访问对象能使用通用访问权限。
		0,
		&lpSecurity_attr,
		CREATE_NEW,
		FILE_ATTRIBUTE_NORMAL,
		NULL);

	if (NULL != LocalFree(lpSecurity_attr.lpSecurityDescriptor))
	{
		// Error encountered; generate message and exit.
		printf("Failed LocalFree
");
		exit(1);
	}
	system("pause");
	return 0;
}

那么如果描述符的字符串是:A:(A;OICI;GRGW;;;BA)呢?

参考文章:https://www.cnblogs.com/guomeiran/p/4106071.html
参考文章:https://www.cnblogs.com/iBinary/p/11399114.html

原文地址:https://www.cnblogs.com/zpchcbd/p/12374668.html