cwinapiwin32-process

Program to get all local users and their permission for the given file using win32 api in C programming


I'm trying to get all the users details and the privileges of the users for the given file. Something like thisoutput like this

How I'm supposed to print this using the GetSecurityInfo() provided by win32 api in C programming? I'm right now just able to get the file owner by using the following code:

#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include "accctrl.h"
#include "aclapi.h"
#pragma comment(lib, "advapi32.lib")

int main(void)
{
DWORD dwRtnCode = 0;
PSID pSidOwner = NULL;
BOOL bRtnBool = TRUE;
LPTSTR AcctName = NULL;
LPTSTR DomainName = NULL;
DWORD dwAcctName = 1, dwDomainName = 1;
SID_NAME_USE eUse = SidTypeUnknown;
HANDLE hFile;
PSECURITY_DESCRIPTOR pSD = NULL;

// Get the handle of the file object.
hFile = CreateFile(
                  TEXT("C:/Users/Vicky/Documents/Software/abc.txt"),
                  GENERIC_READ,
                  FILE_SHARE_READ,
                  NULL,
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL,
                  NULL);
                  
// Check GetLastError for CreateFile error code.
if (hFile == INVALID_HANDLE_VALUE) {
          DWORD dwErrorCode = 0;
          dwErrorCode = GetLastError();
          _tprintf(TEXT("CreateFile error = %d\n"), dwErrorCode);
          return -1;
}

// Get the owner SID of the file.
dwRtnCode = GetSecurityInfo(
                  hFile,
                  SE_FILE_OBJECT,
                  OWNER_SECURITY_INFORMATION,
                  &pSidOwner,
                  NULL,
                  NULL,
                  NULL,
                  &pSD);

// Check GetLastError for GetSecurityInfo error condition.
if (dwRtnCode != ERROR_SUCCESS) {
          DWORD dwErrorCode = 0;
          dwErrorCode = GetLastError();
          _tprintf(TEXT("GetSecurityInfo error = %d\n"), dwErrorCode);
          return -1;
}

// First call to LookupAccountSid to get the buffer sizes.
bRtnBool = LookupAccountSid(
                  NULL,           // local computer
                  pSidOwner,
                  AcctName,
                  (LPDWORD)&dwAcctName,
                  DomainName,
                  (LPDWORD)&dwDomainName,
                  &eUse);

// Reallocate memory for the buffers.
AcctName = (LPTSTR)GlobalAlloc(
          GMEM_FIXED,
          dwAcctName);

// Check GetLastError for GlobalAlloc error condition.
if (AcctName == NULL) {
          DWORD dwErrorCode = 0;
          dwErrorCode = GetLastError();
          _tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
          return -1;
}

    DomainName = (LPTSTR)GlobalAlloc(
           GMEM_FIXED,
           dwDomainName);

    // Check GetLastError for GlobalAlloc error condition.
    if (DomainName == NULL) {
          DWORD dwErrorCode = 0;
          dwErrorCode = GetLastError();
          _tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
          return -1;

    }

    // Second call to LookupAccountSid to get the account name.
    bRtnBool = LookupAccountSid(
          NULL,                   // name of local or remote computer
          pSidOwner,              // security identifier
          AcctName,               // account name buffer
          (LPDWORD)&dwAcctName,   // size of account name buffer 
          DomainName,             // domain name
          (LPDWORD)&dwDomainName, // size of domain name buffer
          &eUse);                 // SID type

    // Check GetLastError for LookupAccountSid error condition.
    if (bRtnBool == FALSE) {
          DWORD dwErrorCode = 0;
          dwErrorCode = GetLastError();

          if (dwErrorCode == ERROR_NONE_MAPPED)
              _tprintf(TEXT
                  ("Account owner not found for specified SID.\n"));
          else 
              _tprintf(TEXT("Error in LookupAccountSid.\n"));
          return -1;

    } else if (bRtnBool == TRUE) 

        // Print the account name.
        _tprintf(TEXT("Account owner = %s\n"), AcctName);

    return 0;
}

Solution

  • If you want to get a file's permission entries like below snapshot shows:

    enter image description here

    This is an example you can refer to:

    // Get the DACL of the file.
    PACL pDACL;
    dwRtnCode = GetSecurityInfo(hFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, NULL);
    if (dwRtnCode != ERROR_SUCCESS)
    {
        return dwRtnCode;
    }
    PACL pAcl = pDACL;
    int aceNum = pDACL->AceCount;
    for (int i = 0; i < aceNum; i++)
    {
        ACE_HEADER *aceAddr = NULL;
        if (GetAce(pAcl, i, (void**)(&aceAddr)))
        {
            if (ACCESS_ALLOWED_ACE_TYPE == aceAddr->AceType)
            {
                printf("ACE type: Allow, "); 
    
                ACCESS_MASK access = ((ACCESS_ALLOWED_ACE *)aceAddr)->Mask;
    
                // Get size of SID
                DWORD size = ((ACCESS_ALLOWED_ACE *)aceAddr)->Header.AceSize - sizeof(ACE_HEADER) - sizeof(ACCESS_MASK);
                if (!size)
                    return FALSE;
    
                BYTE *tempAddr = (BYTE *)aceAddr;
    
                //Find SID start address
                tempAddr += sizeof(ACE_HEADER) + sizeof(ACCESS_MASK);
    
                BYTE * pSid = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
                RtlCopyMemory(pSid, tempAddr, size);
    
                // First call to LookupAccountSid to get the buffer sizes.
                bRtnBool = LookupAccountSid(
                    NULL,           
                    pSid,
                    AcctName,
                    (LPDWORD)&dwAcctName,
                    DomainName,
                    (LPDWORD)&dwDomainName,
                    &eUse);
    
                // Reallocate memory for the buffers.
                AcctName = (LPTSTR)GlobalAlloc(
                    GMEM_FIXED,
                    dwAcctName);
    
                // Check GetLastError for GlobalAlloc error condition.
                if (AcctName == NULL) {
                    DWORD dwErrorCode = 0;
                    dwErrorCode = GetLastError();
                    _tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
                    return -1;
                }
    
                DomainName = (LPTSTR)GlobalAlloc(
                    GMEM_FIXED,
                    dwDomainName);
    
                // Check GetLastError for GlobalAlloc error condition.
                if (DomainName == NULL) {
                    DWORD dwErrorCode = 0;
                    dwErrorCode = GetLastError();
                    _tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
                    return -1;
    
                }
    
                // Second call to LookupAccountSid to get the account name.
                bRtnBool = LookupAccountSid(
                    NULL,                   // name of local or remote computer
                    pSid,              // security identifier
                    AcctName,               // account name buffer
                    (LPDWORD)&dwAcctName,   // size of account name buffer 
                    DomainName,             // domain name
                    (LPDWORD)&dwDomainName, // size of domain name buffer
                    &eUse);                 // SID type
    
                // Check GetLastError for LookupAccountSid error condition.
                if (bRtnBool == FALSE) {
                    DWORD dwErrorCode = 0;
                    dwErrorCode = GetLastError();
    
                    if (dwErrorCode == ERROR_NONE_MAPPED)
                        _tprintf(TEXT
                        ("Account owner not found for specified SID.\n"));
                    else
                        _tprintf(TEXT("Error in LookupAccountSid.\n"));
                    return -1;
    
                }
                else if (bRtnBool == TRUE)
                {
                    // Print the account name.
                    _tprintf(TEXT("Account name = %s, "), AcctName);
                }
    
                //HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, pSid);
    
                // Check access permissions
                printf("Access: ");
                if (access & SYNCHRONIZE)
                    printf("SYNCHRONIZE/ ");
    
                if(access & READ_CONTROL)
                    printf("READ_CONTROL \n");
            }
        }
    }
    

    Example result:

    enter image description here