• 什么是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

  • 相关阅读:
    centos8.2安装Rabbitmq-3.8.12
    绝对好文C#调用C++DLL传递结构体数组的终极解决方案
    c++到c#数据类型的转换
    WPF中timer的使用
    接收Dialog的值
    WPF子界面向父界面传递带参数的委托
    2015上海居住证和积分办理流程
    Discuz! X3.2重置管理员账号
    winServer2008下安装SqlServer2008数据库
    jodd cache实现缓存超时
  • 原文地址:https://www.cnblogs.com/zpchcbd/p/12374668.html
Copyright © 2020-2023  润新知