Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Retrieving NTFS Permissions with C++ : Page 3

There are plenty of handy things you can do if you have programmatic access to the permissions set in the NT File System. Learn to employ C++ and Win32 APIs to query the Access Control Lists that hold security settings for files or folders and use that information however you like.




Application Security Testing: An Integral Part of DevOps

The ACLInfo Sample
The sample program that accompanies this article is a console application that accepts a file or directory path as its command line argument and then retrieves and displays the ACL information for that file. This will only work correctly if the file or folder resides on an NTFS-formatted partition and you have Read access permissions to ACL information.

Listing 1 shows the interface definition of the ACLInfo class as it appears in the ACLInfo.h header file. You should construct an ACLInfo object supplying the path to the file or folder. Then call the Query method that loads the corresponding ACEs and places them into the linked list (m_sAceList) of the ace_list* type (the definition of ace_list appears in Listing 1 as well). Finally, call the Output method to display the ACL. The Main.cpp file (Listing 2) is the sample usage of the ACLInfo class.

The Query Method
The Query method (Listing 3) calls the GetFileSecurityW function twice. In the first call it obtains the size required to store the security descriptor. Then you allocate the required memory and call the function again, this time supplying the pointer to the BYTE* buffer that will hold the security descriptor. Note that I pass DACL_SECURITY_INFORMATION as the second argument. This way, I inform the API that I want Discretionary Access Control List information. The second argument may be any valid combination of different flags that specify the type of security information you are querying. Read the MSDN documentation for GetFileSecurity to learn more about its arguments.

The next fragment retrieves DACL from the security descriptor:

// 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 ("; cout << dwError << ")\n"; return E_FAIL; }

This code checks that DACL is actually present in the security descriptor. If there is no DACL present then GetSecurityDescriptorDacl sets bDaclPresent to False.

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

After verifying that DACL was successfully retrieved you can iterate through its ACEs and fill in the linked list from ACLInfo. The following loop does just this:

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; } HRESULT hr = AddAceToList((ACE_HEADER*)pAce); if (FAILED(hr)) { cout << "Failed to add ace " << i << "to list.\n"; continue; } }

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date