.netwinapiwindows-7createprocessasusersecurity-context

CreateProcessAsUser not setting the user correctly


Calling a GUI app using

[DllImport(
    "advapi32.dll",
    EntryPoint = "CreateProcessAsUser",
    SetLastError = true,
    CharSet = CharSet.Ansi,
    CallingConvention = CallingConvention.StdCall)]
private static extern bool CreateProcessAsUser(
    IntPtr hToken,
    string lpApplicationName,
    string lpCommandLine,
    ref SECURITY_ATTRIBUTES lpProcessAttributes,
    ref SECURITY_ATTRIBUTES lpThreadAttributes,
    bool bInheritHandle,
    int dwCreationFlags,
    IntPtr lpEnvironment,
    string lpCurrentDirectory,
    ref STARTUPINFO lpStartupInfo,
    out PROCESS_INFORMATION lpProcessInformation);


bool result = CreateProcessAsUser(
    hUserTokenDup,
    null,
    applicationName + " " + arguments,
    ref sa,                 // pointer to process SECURITY_ATTRIBUTES
    ref sa,                 // pointer to thread SECURITY_ATTRIBUTES
    false,                  // handles are not inheritable
    NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,        // creation flags
    IntPtr.Zero,            // pointer to new environment block 
    null,                   // name of current directory 
    ref si,                 // pointer to STARTUPINFO structure
    out procInfo);          // receives information about new process

from a LocalSystem Windows Service works. The window pops up in the user screen, but the process user is still LocalSystem. Is there any way to change that?

PS As requested I get hUserTokenDup from

[DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")]
private static extern bool DuplicateTokenEx(
    IntPtr ExistingTokenHandle,
    uint dwDesiredAccess,
    ref SECURITY_ATTRIBUTES lpThreadAttributes,
    int TokenType,
    int ImpersonationLevel,
    ref IntPtr DuplicateTokenHandle);

 DuplicateTokenEx(
     hPToken,
     MAXIMUM_ALLOWED,
     ref sa,
     (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
     (int)TOKEN_TYPE.TokenPrimary,
     ref hUserTokenDup);

Solution

  • In my service, I use WTSGetActiveConsoleSessionId(), WTSQueryUserToken(), and DuplicationTokenEx() before calling CreateProcessAsUser(), and it works fine for me. The spawned process runs in the user account, not the service account.