首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Windows ACL 遍歷與訪問權限檢查編程實戰

     編輯:關於C++

Windows 訪問控制模型 (ACM) 速覽

  • Access Token:主體(進程)持有,含用戶 SID、群組 SID、Privileges。
  • Security Descriptor (SD):客體(文件等)持有,含 Owner SID、Group SID、DACL、SACL。
  • DACL:由多個 ACE 組成,順序決定優先級。訪問檢查:拿 Token 與 ACE 逐一比對,直到 Allow 或 Deny。

核心 API 流程

  1. GetFileSecurity 獲取 SD(兩次調用:先查大小,再分配內存取數據)。
  2. OpenProcessToken 獲取進程 Token,DuplicateToken 產生 Impersonation Token(必須,否則無法正確檢查)。
  3. GENERIC_MAPPING 映射通用權限(GENERIC_READ 等)為對象特定權限(FILE_GENERIC_READ 等),需手動填寫 GenericRead/Write/Execute/All 後呼叫 MapGenericMask。
  4. AccessCheck 核心檢查:傳入 SD、Impersonation Token、DesiredAccess、GenericMapping,輸出 AccessStatus (BOOL) 與 GrantedAccess。

關鍵代碼片段

// 1. 獲取 SD
SECURITY_INFORMATION si = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
GetFileSecurity(lpFileName, si, NULL, 0, &dwSizeNeeded); // 獲取大小
psd = (PSECURITY_DESCRIPTOR)AllocMem(dwSizeNeeded);
GetFileSecurity(lpFileName, si, psd, dwSizeNeeded, &dwSizeNeeded);

// 2. 獲取並模擬 Token
OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
DuplicateToken(hToken, SecurityImpersonation, &hImpersonatedToken);

// 3. 映射權限
GENERIC_MAPPING genMap = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS };
DWORD dwGenericAccessMask = GENERIC_READ | GENERIC_WRITE;
MapGenericMask(&dwGenericAccessMask, &genMap);

// 4. 檢查
PRIVILEGE_SET privileges = {0};
DWORD grantAccess = 0, privLength = sizeof(privileges);
BOOL bGrantAccess = FALSE;
AccessCheck(psd, hImpersonatedToken, dwGenericAccessMask, &genMap,
            &privileges, &privLength, &grantAccess, &bGrantAccess);
// bGrantAccess 即結果

難點總結

  • MSDN 文檔含糊、缺乏代碼範例。
  • GENERIC_MAPPING 結構體用法極易誤解(需手動對應對象特定權限常數)。
  • Impersonation Token 是正確檢查的關鍵,直接用 Process Token 會失敗。

完整測試截圖見原文。希望能為 Windows 安全編程開發者提供參考。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved