c++ - 使用 AddAccessAllowedAceEx 在 DACL 中进行 ACE 排序

标签 c++ winapi windows-security

我需要在 C++ 程序中授予对 Windows 上文件的访问权限。我四处浏览并从 MSDN 复制/粘贴代码并提出以下内容。据我所知,它一直在工作。

但是今天我在 MSDN 中偶然发现了一条关于使用 AddAccessAllowedAceEx 的警告,它说:“调用者必须确保 ACE 以正确的顺序添加到 DACL。”。然后它向读者推荐这个:http://msdn.microsoft.com/en-us/library/windows/desktop/aa379298(v=vs.85).aspx

因此,我的请求是让任何经验丰富的 Windows 程序员检查我下面的代码,并告诉我我是否会遇到我正在修改的文件的 DACL 中的 ACE 排序问题(通过szPath 在我的函数中)。我会说我只是将我的新 ACE 添加到 DACL 的末尾。如果这会成为一个问题,我是否真的必须从 DACL 中读出所有 ACE,检查它们,然后一次添加一个,确保将我的新 ACE 插入正确的位置以遵守正确的顺序?

char* whoOps::ACLAmigo::AddACEToDACL(char* szPath, char* szSecurityPrincipal, DWORD dwPermission)
{
ACL_SIZE_INFORMATION ACLInfo; 
memset(&ACLInfo, 0, sizeof(ACL_SIZE_INFORMATION));
UCHAR   BuffSid[256];
PSID pSID = (PSID)BuffSid;
int returnCode = ResolveSID(szSecurityPrincipal, pSID);
SE_OBJECT_TYPE SEObjType = SE_FILE_OBJECT;
PACL pOldDACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
SECURITY_INFORMATION ACLSecInfo = DACL_SECURITY_INFORMATION;
returnCode = GetNamedSecurityInfoA(szPath, SEObjType, ACLSecInfo, NULL, NULL, &pOldDACL, NULL, &pSD);  
char* szReturn = NULL;
if (returnCode != ERROR_SUCCESS) {
    szReturn = "GetNamedSecurityInfoA() failed.";
} else {
    BOOL getACLResult = GetAclInformation(pOldDACL, &ACLInfo, sizeof(ACLInfo), AclSizeInformation); 
    if (!getACLResult) {
        szReturn = "GetAclInformation() failed.";
    } else {
        DWORD cb = 0;
        DWORD cbExtra = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSID); 
        cb = ACLInfo.AclBytesInUse + cbExtra; 
        PACL pNewDACL = static_cast<PACL>(HeapAlloc(GetProcessHeap(),0,cb)); 
        BOOL initACLResult = InitializeAcl(pNewDACL, cb, ACL_REVISION); 
        if (!initACLResult) {
            szReturn = "InitializeAcl() failed.";
        } else {
            for (DWORD i = 0; i < ACLInfo.AceCount; ++i)  { 
                ACE_HEADER * pACE = 0; 
                GetAce(pOldDACL, i, reinterpret_cast<void**>(&pACE)); 
                pACE->AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
                pACE->AceType = ACCESS_ALLOWED_ACE_TYPE;
                AddAce(pNewDACL, ACL_REVISION, MAXDWORD, pACE, pACE->AceSize); 
            } 
            BOOL addACEResult = AddAccessAllowedAceEx(pNewDACL, ACL_REVISION, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, dwPermission, pSID);
            if (!addACEResult) {
                szReturn = "AddAccessAllowedAceEx() failed.";
            } else {
                DWORD setSIResult = SetNamedSecurityInfoA(szPath, SEObjType, ACLSecInfo, NULL, NULL, pNewDACL, NULL); 
                if (!setSIResult) {
                    szReturn = "SetNamedSecurityInfoA() failed.";
                } else {
                    szReturn = "AddACEToDACL() succesful.";
                }
            }
        }
        if (pNewDACL) HeapFree(GetProcessHeap(),0, pNewDACL);
    }
    if (pSD) LocalFree(pSD);
}
return szReturn;

最佳答案

ACE 排序真的很重要!是的,最好的解决方案是

  1. 修改前阅读ACL的内容
  2. 以编程方式检查安全描述符中的每个元素 (ACE)
  3. 适本地放置您的条目(在允许之前拒绝)

serie有大量的样本。

关于c++ - 使用 AddAccessAllowedAceEx 在 DACL 中进行 ACE 排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10786696/

相关文章:

c++ - 继承类型强制

c++ - QByteArray::append() 导致内存重新分配

c# - 间歇性 401-SSRS 未经授权的响应

c++ - ResumeThread 有时不唤醒线程

c++ - 为什么我的程序会在拥有线程的情况下生成 LdrpLoaderLock 死锁?

x509certificate - Windows 检测证书作为根证书颁发机构

windows - 哪种类型的特定访问权限 (ACCESS_MASK) 对 SE_LMSHARE 有效?

c++ - undefined reference SDL with Code::Blocks

c++ - 插入 map<string, STRUCT> 错误

c++ - 如何使用 C++ 更改 Windows 10 壁纸?