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
ConvertSecurityDescriptorToStringSecurityDescriptor
和ConvertStringSecurityDescriptorToSecurityDescriptor
,這兩個函數都可以實現 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\n");
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\n");
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