3

我注意到我的应用程序没有正确检索某些文件的 NTFS ACL 继承。这些文件位于我的个人资料的子文件夹中。使用 ICACLS.EXE 时,它会为这些文件正确输出 (I)。但是当ACCESS_ALLOWED_ACE->Header.AceFlags使用GetFileSecurity()这些文件检索时,它总是为零。但是,这适用于我系统上的许多其他文件。文件夹也不受影响,但我的个人资料目录及其子文件夹中的所有文件。

这是允许重现问题的示例 C++ 代码:

#include <windows.h>
#include <iostream>
#include <comdef.h>

using namespace std;

int main(int argc, TCHAR** argv)
{
    // Check Input Arguments
    if (2 != argc)
    {
        // Output usage information in case of wrong arguments
        cout << "Usage: ACLInfo.exe <path to file or directory>" << endl;
        return 0;
    }

    // Get the path from supplied arguments
    _bstr_t strPath = argv[1];

    // Find out size of needed buffer for security descriptor with DACL
    // DACL = Discretionary Access Control List
    DWORD dwSizeNeeded = 0;
    BOOL bSuccess = GetFileSecurityW(strPath,
                                DACL_SECURITY_INFORMATION,
                                NULL,
                                0,
                                &dwSizeNeeded);

    if (0 == dwSizeNeeded)
    {
        return E_FAIL;
    }
    BYTE* pSecDescriptorBuf = new BYTE[dwSizeNeeded];

    // Retrieve security descriptor with DACL information
    bSuccess = GetFileSecurityW((BSTR)strPath,
                                DACL_SECURITY_INFORMATION,
                                pSecDescriptorBuf,
                                dwSizeNeeded,
                                &dwSizeNeeded);

    // Check if we successfully retrieved security descriptor with DACL 
information
    if (!bSuccess)
    {
        DWORD dwError = GetLastError();
        cout << "Failed to get file security information (" << dwError << ")\n";
        return E_FAIL;
    }

    // Getting DACL from Security Descriptor
    PACL pacl;
    BOOL bDaclPresent, bDaclDefaulted;
    bSuccess = 
GetSecurityDescriptorDacl((SECURITY_DESCRIPTOR*)pSecDescriptorBuf,
                                         &bDaclPresent, &pacl, &bDaclDefaulted);

    // Check if we successfully retrieved DACL
    if (!bSuccess)
    {
        DWORD dwError = GetLastError();
        cout << "Failed to retrieve DACL from security descriptor (" << dwError 
<< ")\n";
        return E_FAIL;
    }

    // Check if DACL present in security descriptor
    if (!bDaclPresent)
    {
        cout << "DACL was not found.\n";
        return E_FAIL;
    }

    // DACL for specified file was retrieved successfully
    // Now, we should fill in the linked list of ACEs
    // Iterate through ACEs (Access Control Entries) of DACL
    for (USHORT i = 0; i < pacl->AceCount; i++)
    {
        LPVOID pAce;
        bSuccess = GetAce(pacl, i, &pAce);
        if (!bSuccess)
        {
            DWORD dwError = GetLastError();
            cout << "Failed to get ace " << i << " (" << dwError << ")\n";
            continue;
        }
        BYTE AceFlags = ((ACCESS_ALLOWED_ACE*)pAce)->Header.AceFlags;
        BOOL Inherited = (AceFlags && (INHERITED_ACE || OBJECT_INHERIT_ACE || CONTAINER_INHERIT_ACE)) != 0;
        if (!Inherited)  
          cout << "not ";
        cout << "Inherited";

    }

    return 0;
}

对于受影响的文件,AceFlags 始终为 0。那么判断这些ACL是否被继承的正确方法是什么呢?

4

0 回答 0