Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I determine the owner of a file or directory using boost filesystem? [duplicate]

Possible Duplicate:
Get file's owner and group using boost

I'd like to use boost::filesystem to determine which files and directories/ folders are owned by a particular user.

I need to do this on both Linux (ext3) and Windows (NTFS) filesystems.

How can I get the user identifier for a specified path using boost::filesystem?

Thanks in advance.

Edit: Code derived from selected answer:

#include <iostream>
#include <string>

#ifdef LINUX
#include <pwd.h>
#include <grp.h>
#include <sys/stat.h>
#else
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include "accctrl.h"
#include "aclapi.h"
#pragma comment(lib, "advapi32.lib")
#endif

bool getOwner(const std::string &Filename, std::string &Owner)
{
#ifdef LINUX
    struct stat FileInfo;
    stat(Filename.c_str(), &FileInfo);
    struct passwd *UserDatabaseEntry  = getpwuid(FileInfo.st_uid);
    struct group  *GroupDatabaseEntry = getgrgid(FileInfo.st_gid);
    //
    if (UserDatabaseEntry != 0)
    {
        Owner = UserDatabaseEntry->pw_name;
        return true;
    }
    else
    {
        return false;
    }
#else
    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(Filename.c_str()),
        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 false;
    }

    // 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 false;
    }

    // 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 false;
    }

    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 false;

    }

    // 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 false;

    }
    else if (bRtnBool == TRUE)
    {

        // Print the account name.
        _tprintf(TEXT("Account owner = %s\n"), AcctName);
        Owner = AcctName;
        return true;
    }
#endif
    return false;
}

int main(int argc, char *argv[])
{
    std::string Filename = argv[0];
    if (argc > 1)
    {
        Filename = argv[1];
    }
    std::cout << "File " << Filename << " is owned by: ";
    //
    std::string Owner;
    bool OK = getOwner(Filename, Owner);
    if (OK)
    {
        std::cout << Owner << "." << std::endl;
    }
    else
    {
        std::cout << "Unknown." << std::endl;
    }
    return 0;
}
like image 735
pugdogfan Avatar asked Nov 03 '22 23:11

pugdogfan


1 Answers

I am afraid what you are trying to achieve is not covered by the boost::filesystem library. It is possible to retrieve file permissions, but for ownership you would have to resort to something else or write your own.

Here is an explanation how to do it for Windows and Linux.

like image 190
nijansen Avatar answered Nov 09 '22 08:11

nijansen