Search code examples
windows-servicescreateprocessasuser

Why CreateProcessAsUser fails with "Access denied" when called from service child process


I am trying to run process as other user from my service using CreateProcessAsUser function. The example of code was found here CreateProcessAsUser from c++ service creates process but no console. OS - Windows 10

My code is working fine, when i run it in main service process. But I need run same code from child service process. And in this case CreateProcessAsUser returns 0 and GetLastError = 5 (Access Dennied).

Child service process is created by next call

CreateProcess(NULL, "d:\\child.exe", NULL, NULL, FALSE, 0u, NULL, NULL, &si.StartupInfo, &pi)

My code is working inside "child.exe" binary and should just create one more process, that starts "d:\test.exe" binary in this way

CreateProcessAsUser(hUserTokenDup,
        NULL,
        "d:\\test.exe",
        NULL,
        NULL,
        FALSE,
        CREATE_NEW_CONSOLE | /*CREATE_BREAKAWAY_FROM_JOB |*/ NORMAL_PRIORITY_CLASS,
        NULL,
        NULL,
        &si,
        &pi);

For test I moved code to start "test.exe" to same place where "child.exe" is starting (to service main process) and "test.exe" starts fine. For test I replaced CreateProcessAsUser on CreateProcess with same parameters (except user token) and test.exe also starts fine.

But I need start "test.exe" from service child process (from "child.exe") and start it by CreateProcessAsUser. I tryed a lot of solutions from internet (add CREATE_BREAKAWAY_FROM_JOB, use DuplicateTokenEx, use linkedToken, enable all possible privilegies and so on) but no solution helped. I do not expected any difference between service process and child process. But looks like something different and I cannot find what it is.

Can anybody advice, what is a difference between main server process and its child process?


Solution

  • My colleagues found the solution.

    I publish it here:

    Service child process could start sub-process after flags JOB_OBJECT_LIMIT_BREAKAWAY_OK|JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK has been passed to SetInformationJobObject function in server process before creating service child process. After that calls

    WTSGetActiveConsoleSessionId(..

    WTSQueryUserToken(...

    CreateProcessAsUser(...CREATE_BREAKAWAY_FROM_JOB

    work fine event without creating duplicate handle