首页 > 解决方案 > ACL 中的 EXPLICIT_ACCESS 数组 - WIN32 API

问题描述

void main() {

    PSID UserSID = NULL;
    PSID GroupSID = NULL;
    PSECURITY_DESCRIPTOR SD = NULL;
    ACL *pDACL = new ACL ;

    string input, ext = "";
    wcout << "Enter the location : " << endl;
    std::getline(cin, input);
    LPCSTR file = input.c_str();

    HANDLE hFile = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);

    if (hFile == INVALID_HANDLE_VALUE)
    {
        if (GetLastError() == ERROR_ACCESS_DENIED)
        {
            cout << "Access Denied : System Files" << endl;
            return;
        }
        else if (GetLastError() == ERROR_PATH_NOT_FOUND)
        {
            cout << "Path Name Not Found" << endl;
            return;
        }
        else if (GetLastError() == ERROR_FILE_NOT_FOUND)
        {
            cout << "File Not Found" << endl;
            return;
        }
        else
        {
            cout << GetLastError() << endl;
            return;                                                                                                                                                                                                                                                                     
        }
    }

    ULONG Count = NULL;
    PEXPLICIT_ACCESS_W *pExplicitEntries = new PEXPLICIT_ACCESS_W;


    if (GetSecurityInfo(hFile,SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &SD) == ERROR_SUCCESS)
    {
        cout << "GetSecInfo Success " << pDACL->AceCount << endl;
        cout << GetLastError() << endl;
    }

    if (GetExplicitEntriesFromAclW(pDACL, &Count, pExplicitEntries) == ERROR_SUCCESS)
    {
        cout << Count << endl;
        cout << GetLastError() << endl;
    }

    if (pExplicitEntries[0]->Trustee.TrusteeForm == TRUSTEE_IS_SID)
    {
        TCHAR AccountBuff[80];
        TCHAR DomainBuff[80];
        DWORD AccountBufflength = 40;
        DWORD DomainBufflength = 40;
        PSID_NAME_USE peUse = new SID_NAME_USE;
        PSID Sid = pExplicitEntries[0]->Trustee.ptstrName;

        LookupAccountSidW(NULL, Sid, AccountBuff, &AccountBufflength, DomainBuff, &DomainBufflength, peUse);

        wcout << AccountBuff << endl;

        DWORD pAccessRights;

        if (GetEffectiveRightsFromAclW(pDACL, &pExplicitEntries[0]->Trustee, &pAccessRights) == ERROR_SUCCESS)
        {
            DisplayAccessMask(pAccessRights);
        }
    }
}

目前,数组索引为 0,如果我切换到 1 或 2 等其他索引,则会导致异常:访问位置。请帮助,请有人给我解决方案来访问ACL中的所有受托人并获取文件的每个受托人的访问权限和用户名

标签: c++winapi

解决方案


GetSecurityInfo 给我的 ACE 计数为 4 ,但当涉及到 GetExplicitEntriesFromAclW 时,计数值保持为 0。

当我的测试目标文件是新创建的(例如 TXT 文件)时,我可以重现此问题。是的,GetSecurityInfo给我ACEcount as 4,但是当谈到价值时GetExplicitEntriesFromAclWCount仍然是0

使用函数检查ACE类型,发现所有类型都是0: ACCESS_MIN_MS_ACE_TYPE \ ACCESS_ALLOWED_ACE_TYPE

if (GetSecurityInfo(hFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &SD) == ERROR_SUCCESS)
{
    cout << "GetSecInfo Success " << pDACL->AceCount << endl;
    cout << GetLastError() << endl;
}
PACL pAcl = pDACL;
int aceNum = pDACL->AceCount;
for (int i = 0; i < aceNum; i++)
{
    ACE_HEADER *aceAddr = NULL;
    if (GetAce(pAcl, i, (void**)(&aceAddr)))
    {
        printf("ACE type: %d \n",aceAddr->AceType); ACCESS_ALLOWED_ACE_TYPE;
        printf("ACE flags: %d \n", aceAddr->AceFlags);
        printf("ACE size: %d \n", aceAddr->AceSize);
    }
}

如果您像这样为当前用户设置拒绝写入操作:

在此处输入图像描述

然后ACE键入1( ACCESS_DENIED_ACE_TYPE) 出现。并且从Count返回的值GetExplicitEntriesFromAclW等于ACE类型为的条目数1请参阅以下快照:

在此处输入图像描述


推荐阅读