开发者

AssignProcessToJobObject with JOB_OBJECT_UILIMIT_HANDLES fails when called from service

I have a service from which I want to create a restricted process for a currently logged user. If I try to assign the process to job object which has JOB_OBJECT_UILIMIT_HANDLES set the call fails with ERROR_ACCESS_DENIED. If I remove JOB_OBJECT_UILIMIT_HANDLES from the job settings everything works fine. It also works if I execute this code in the context of the user.

Any idea on what it is wrong?

Thank you.

Edit:

Here is a sample program which reproduces the issue. The program launches a process with the same token as a specified process and assigns that process to a job object.

If you launch the process as system (you can create a service with the executable path set to cmd.exe and then you can switch to the system session and launch the program from there), specify the source process to any user process and set limit UI to true the call to AssignProcessToJobObject will fail with status ERROR_ACCESS_DENIED. If limit UI is set to false everything is working fine.

# define _CRT_SECURE_NO_WARNINGS

# include "stdafx.h"

# include <windows.h>

# include <stdio.h>
# include <assert.h>
# include <conio.h>

void main()
{   
    HANDLE job = NULL;
    STARTUPINFO startupInfo = { 0 };
    PROCESS_INFORMATION processInformation = { 0 };
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION eli = { 0 };
    JOBOBJECT_BASIC_UI_RESTRICTIONS bur = { 0 };
    HANDLE token = NULL;
    HANDLE process = NULL;
    BOOL limitUI = TRUE;

    DWORD sourcePid = 0;
    printf("Enter source pid: ");
    scanf("%u", &sourcePid);

   process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, sourcePid);
   if(process == NULL)
   {
        printf("OpenProcess failed\n");
        goto cleanup;
    }

    if(!OpenProcessToken(process, TOKEN_ALL_ACCESS, &token))   
    {
        printf("OpenProcessToken failed\n");
        goto cleanup;
    }

    job = CreateJobObject(NULL, NULL);
    if(job == NULL)    
    {
        printf("CreateJobObject failed\n");
        goto cleanup;
    }

    eli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
    eli.BasicLimitInformation.PriorityClass = NORMAL_PRIORITY_CLASS;
    if(!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &eli, sizeof(eli)))   
    {
        printf("SetInformationJobObject failed\n");
        goto cleanup;
    }

    printf("Limit UI: ");
    scanf("%u", &limitUI);

    if(limitUI)
    {
        bur.UIRestrictionsClass = JOB_OBJECT_UILIMIT_HANDLES;
        if(!SetInformationJobObject(job, JobObjectBasicUIRestrictions, &bur, sizeof(bur)))   
        {
            printf("SetInformationJobObject failed\n");
            goto cleanup;
        }
    }

    if(!CreateProcessAsUser(token, L"c:\\windows\\system32\\notepad.exe", L"", NULL, NULL, FALSE,
        CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInformation))   
    {
        printf("CreateProcessAsUser failed\n");
        goto cleanup;
    }

    if(!AssignProcessToJobObject(job, processInformation.hProcess))   
    {
        printf("AssignProcessToJobObject failed\n");
        goto cleanup;
    }

    if(ResumeThread(processInformation.hThread) == (DWORD)-1)   
    {
        printf("ResumeThread failed\n");
        goto cleanup;
    }

    WaitForSingleObject(processInformation.hProcess, INFINITE);

cleanup:
    if(processInformation.hThread != NULL)
        CloseHandle(processInformation.hThread);
    if(processInformation.hProcess != NULL)
        CloseHandle(processInformation.hProcess);
    if(job 开发者_高级运维!= NULL)
        CloseHandle(job);
    if(token != NULL)
        CloseHandle(token);
    if(process != NULL)
        CloseHandle(process);

    printf("Last Error: %d\n", GetLastError());
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜