我注意到我的应用程序没有正确检索某些文件的 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是否被继承的正确方法是什么呢?