DavidXanatos
DavidXanatos

Reputation: 139

How to check if a process has access to a securable object in windows

Scenario: I have a service that can create, start, stop other services and offers this through IPC to user processes.

How can I check in my service if the calling process has permissions to access the SCM?

So on a more abstract level I have some securable object, in this case the SCM but it can be really anything an other process a thread, a file, folder or reg key, etc... And I have some user process that may or may not have the permissions to access that resource. How can I in a 3rd party process determine if said user process has access to a given securable object?

Upvotes: 1

Views: 294

Answers (1)

DavidXanatos
DavidXanatos

Reputation: 139

okay I have it :D that seams to do what I need it to, its based on http://blog.aaronballman.com/2011/08/how-to-check-access-rights/

bool CanAccessSCM(HANDLE idProcess)
{
    bool bRet = false;

    DWORD genericAccessRights = SC_MANAGER_ALL_ACCESS;
    SC_HANDLE scHandle = OpenSCManager(NULL, NULL, READ_CONTROL);
    if (scHandle != NULL) {
        PSECURITY_DESCRIPTOR securityDescriptor;
        if (NT_SUCCESS(GetSecurityInfo(scHandle, SE_SERVICE, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
            , NULL, NULL, NULL, NULL, &securityDescriptor))) {
            HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)(ULONG_PTR)idProcess);
            if (hProcess != NULL) {
                HANDLE hToken = NULL;
                if (OpenProcessToken(hProcess, TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &hToken)) {
                    HANDLE hImpersonatedToken = NULL;
                    if (DuplicateToken(hToken, SecurityImpersonation, &hImpersonatedToken)) {
                        GENERIC_MAPPING mapping = { 0xFFFFFFFF };
                        PRIVILEGE_SET privileges = { 0 };
                        DWORD grantedAccess = 0, privilegesLength = sizeof(privileges);
                        BOOL result = FALSE;
                        /*
                        mapping.GenericRead = FILE_GENERIC_READ;
                        mapping.GenericWrite = FILE_GENERIC_WRITE;
                        mapping.GenericExecute = FILE_GENERIC_EXECUTE;
                        mapping.GenericAll = FILE_ALL_ACCESS;
                        ::MapGenericMask( &genericAccessRights, &mapping );*/
                        if (::AccessCheck(securityDescriptor, hToken, genericAccessRights,
                            &mapping, &privileges, &privilegesLength, &grantedAccess, &result)) {
                            bRet = (result == TRUE);
                        }
                        CloseHandle(hImpersonatedToken);
                    }
                    CloseHandle(hToken);
                }
                CloseHandle(hProcess);
            }
            LocalFree(securityDescriptor);
        }
        CloseHandle(scHandle);
    }

    return bRet;
}
´´´

Upvotes: 0

Related Questions