Merge branch 'release/1.4'

This commit is contained in:
Bill Zissimopoulos 2018-11-27 16:27:15 -08:00
commit e0a6312387
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
7 changed files with 181 additions and 33 deletions

View File

@ -111,7 +111,43 @@ enum
*/ */
FSP_API NTSTATUS FspLaunchCallLauncherPipe( FSP_API NTSTATUS FspLaunchCallLauncherPipe(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize, PULONG PLauncherError); PWSTR Buffer, PULONG PSize,
PULONG PLauncherError);
/**
* Call launcher pipe.
*
* This function is used to send a command to the launcher and receive a response.
*
* @param Command
* Launcher command to send. For example, the 'L' launcher command instructs
* the launcher to list all running service instances.
* @param Argc
* Command argument count. May be 0.
* @param Argv
* Command argument array. May be NULL.
* @param Argl
* Command argument length array. May be NULL. If this is NULL all command arguments
* are assumed to be NULL-terminated strings. It is also possible for specific arguments
* to be NULL-terminated; in this case pass -1 in the corresponding Argl position.
* @param Buffer
* Buffer that receives the command response. May be NULL.
* @param PSize
* Pointer to a ULONG. On input it contains the size of the Buffer. On output it
* contains the number of bytes transferred. May be NULL.
* @param AllowImpersonation
* Allow caller to be impersonated by launcher.
* @param PLauncherError
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
* @return
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher
* returns an error. Other status codes indicate a communication error. Launcher errors are
* reported through PLauncherError.
*/
FSP_API NTSTATUS FspLaunchCallLauncherPipeEx(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize,
BOOLEAN AllowImpersonation,
PULONG PLauncherError);
/** /**
* Start a service instance. * Start a service instance.
* *
@ -138,6 +174,35 @@ FSP_API NTSTATUS FspLaunchStart(
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv, PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv,
BOOLEAN HasSecret, BOOLEAN HasSecret,
PULONG PLauncherError); PULONG PLauncherError);
/**
* Start a service instance.
*
* @param ClassName
* Class name of the service instance to start.
* @param InstanceName
* Instance name of the service instance to start.
* @param Argc
* Service instance argument count. May be 0.
* @param Argv
* Service instance argument array. May be NULL.
* @param HasSecret
* Whether the last argument in Argv is assumed to be a secret (e.g. password) or not.
* Secrets are passed to service instances through standard input rather than the command
* line.
* @param AllowImpersonation
* Allow caller to be impersonated by launcher.
* @param PLauncherError
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
* @return
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher
* returns an error. Other status codes indicate a communication error. Launcher errors are
* reported through PLauncherError.
*/
FSP_API NTSTATUS FspLaunchStartEx(
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv,
BOOLEAN HasSecret,
BOOLEAN AllowImpersonation,
PULONG PLauncherError);
/** /**
* Stop a service instance. * Stop a service instance.
* *

View File

@ -1795,6 +1795,10 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize, PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize,
PULONG PBytesTransferred, ULONG Timeout, PULONG PBytesTransferred, ULONG Timeout,
PSID Sid); PSID Sid);
FSP_API NTSTATUS FspCallNamedPipeSecurelyEx(PWSTR PipeName,
PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize,
PULONG PBytesTransferred, ULONG Timeout, BOOLEAN AllowImpersonation,
PSID Sid);
FSP_API NTSTATUS FspVersion(PUINT32 PVersion); FSP_API NTSTATUS FspVersion(PUINT32 PVersion);
/* /*

View File

@ -23,7 +23,18 @@
FSP_API NTSTATUS FspLaunchCallLauncherPipe( FSP_API NTSTATUS FspLaunchCallLauncherPipe(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize, PULONG PLauncherError) PWSTR Buffer, PULONG PSize,
PULONG PLauncherError)
{
return FspLaunchCallLauncherPipeEx(
Command, Argc, Argv, Argl, Buffer, PSize, FALSE, PLauncherError);
}
FSP_API NTSTATUS FspLaunchCallLauncherPipeEx(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize,
BOOLEAN AllowImpersonation,
PULONG PLauncherError)
{ {
PWSTR PipeBuf = 0, P; PWSTR PipeBuf = 0, P;
ULONG Length, BytesTransferred; ULONG Length, BytesTransferred;
@ -53,9 +64,9 @@ FSP_API NTSTATUS FspLaunchCallLauncherPipe(
memcpy(P, Argv[I], Length * sizeof(WCHAR)); P += Length; *P++ = L'\0'; memcpy(P, Argv[I], Length * sizeof(WCHAR)); P += Length; *P++ = L'\0';
} }
Result = FspCallNamedPipeSecurely(L"" FSP_LAUNCH_PIPE_NAME, Result = FspCallNamedPipeSecurelyEx(L"" FSP_LAUNCH_PIPE_NAME,
PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE, PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE,
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, FSP_LAUNCH_PIPE_OWNER); &BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, AllowImpersonation, FSP_LAUNCH_PIPE_OWNER);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -102,8 +113,17 @@ exit:
} }
FSP_API NTSTATUS FspLaunchStart( FSP_API NTSTATUS FspLaunchStart(
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv,
BOOLEAN HasSecret,
PULONG PLauncherError)
{
return FspLaunchStartEx(ClassName, InstanceName, Argc, Argv, HasSecret, FALSE, PLauncherError);
}
FSP_API NTSTATUS FspLaunchStartEx(
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv0, PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv0,
BOOLEAN HasSecret, BOOLEAN HasSecret,
BOOLEAN AllowImpersonation,
PULONG PLauncherError) PULONG PLauncherError)
{ {
PWSTR Argv[9 + 2]; PWSTR Argv[9 + 2];
@ -115,9 +135,9 @@ FSP_API NTSTATUS FspLaunchStart(
Argv[1] = InstanceName; Argv[1] = InstanceName;
memcpy(Argv + 2, Argv0, Argc * sizeof(PWSTR)); memcpy(Argv + 2, Argv0, Argc * sizeof(PWSTR));
return FspLaunchCallLauncherPipe( return FspLaunchCallLauncherPipeEx(
HasSecret ? FspLaunchCmdStartWithSecret : FspLaunchCmdStart, HasSecret ? FspLaunchCmdStartWithSecret : FspLaunchCmdStart,
Argc + 2, Argv, 0, 0, 0, PLauncherError); Argc + 2, Argv, 0, 0, 0, AllowImpersonation, PLauncherError);
} }
FSP_API NTSTATUS FspLaunchStop( FSP_API NTSTATUS FspLaunchStop(

View File

@ -179,12 +179,14 @@ static inline BOOLEAN FspNpParseRemoteUserName(PWSTR RemoteName,
static inline DWORD FspNpCallLauncherPipe( static inline DWORD FspNpCallLauncherPipe(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize) PWSTR Buffer, PULONG PSize,
BOOLEAN AllowImpersonation)
{ {
NTSTATUS Result; NTSTATUS Result;
ULONG ErrorCode; ULONG ErrorCode;
Result = FspLaunchCallLauncherPipe(Command, Argc, Argv, Argl, Buffer, PSize, &ErrorCode); Result = FspLaunchCallLauncherPipeEx(Command, Argc, Argv, Argl, Buffer, PSize, AllowImpersonation,
&ErrorCode);
return !NT_SUCCESS(Result) ? return !NT_SUCCESS(Result) ?
WN_NO_NETWORK : WN_NO_NETWORK :
(ERROR_BROKEN_PIPE == ErrorCode ? WN_NO_NETWORK : ErrorCode); (ERROR_BROKEN_PIPE == ErrorCode ? WN_NO_NETWORK : ErrorCode);
@ -251,7 +253,8 @@ static WCHAR FspNpGetDriveLetter(PDWORD PLogicalDrives, PWSTR VolumeName)
return 0; return 0;
} }
static DWORD FspNpGetRemoteInfo(PWSTR RemoteName, PDWORD PCredentialsKind) static DWORD FspNpGetRemoteInfo(PWSTR RemoteName,
PDWORD PCredentialsKind, PBOOLEAN PAllowImpersonation)
{ {
PWSTR ClassName, InstanceName; PWSTR ClassName, InstanceName;
ULONG ClassNameLen, InstanceNameLen; ULONG ClassNameLen, InstanceNameLen;
@ -260,6 +263,7 @@ static DWORD FspNpGetRemoteInfo(PWSTR RemoteName, PDWORD PCredentialsKind)
NTSTATUS Result; NTSTATUS Result;
*PCredentialsKind = FSP_NP_CREDENTIALS_NONE; *PCredentialsKind = FSP_NP_CREDENTIALS_NONE;
*PAllowImpersonation = FALSE;
if (!FspNpParseRemoteName(RemoteName, if (!FspNpParseRemoteName(RemoteName,
&ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen)) &ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen))
@ -283,6 +287,9 @@ static DWORD FspNpGetRemoteInfo(PWSTR RemoteName, PDWORD PCredentialsKind)
break; break;
} }
*PAllowImpersonation = 0 != Record->RunAs &&
L'.' == Record->RunAs[0] && L'\0' == Record->RunAs[1];
FspLaunchRegFreeRecord(Record); FspLaunchRegFreeRecord(Record);
return WN_SUCCESS; return WN_SUCCESS;
@ -464,6 +471,7 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
PWSTR ClassName, InstanceName, RemoteName, P; PWSTR ClassName, InstanceName, RemoteName, P;
ULONG ClassNameLen, InstanceNameLen; ULONG ClassNameLen, InstanceNameLen;
DWORD CredentialsKind; DWORD CredentialsKind;
BOOLEAN AllowImpersonation;
ULONG Argc; ULONG Argc;
PWSTR Argv[6]; PWSTR Argv[6];
ULONG Argl[6]; ULONG Argl[6];
@ -493,7 +501,7 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
return WN_ALREADY_CONNECTED; return WN_ALREADY_CONNECTED;
} }
NpResult = FspNpGetRemoteInfo(lpRemoteName, &CredentialsKind); NpResult = FspNpGetRemoteInfo(lpRemoteName, &CredentialsKind, &AllowImpersonation);
if (WN_SUCCESS != NpResult) if (WN_SUCCESS != NpResult)
return NpResult; return NpResult;
@ -550,7 +558,8 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
NpResult = FspNpCallLauncherPipe( NpResult = FspNpCallLauncherPipe(
FSP_NP_CREDENTIALS_NONE != CredentialsKind ? FspLaunchCmdStartWithSecret : FspLaunchCmdStart, FSP_NP_CREDENTIALS_NONE != CredentialsKind ? FspLaunchCmdStartWithSecret : FspLaunchCmdStart,
Argc, Argv, Argl, 0, 0); Argc, Argv, Argl, 0, 0,
AllowImpersonation);
switch (NpResult) switch (NpResult)
{ {
case WN_SUCCESS: case WN_SUCCESS:
@ -602,7 +611,8 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
if (WN_SUCCESS != FspNpCallLauncherPipe( if (WN_SUCCESS != FspNpCallLauncherPipe(
FspLaunchCmdGetInfo, FspLaunchCmdGetInfo,
Argc, Argv, Argl, 0, 0)) Argc, Argv, Argl, 0, 0,
FALSE))
{ {
/* looks like the file system is gone! */ /* looks like the file system is gone! */
NpResult = WN_NO_NETWORK; NpResult = WN_NO_NETWORK;
@ -660,6 +670,7 @@ DWORD APIENTRY NPAddConnection3(HWND hwndOwner,
DWORD NpResult; DWORD NpResult;
PWSTR RemoteName = lpNetResource->lpRemoteName; PWSTR RemoteName = lpNetResource->lpRemoteName;
DWORD CredentialsKind; DWORD CredentialsKind;
BOOLEAN AIDummy;
WCHAR UserName[CREDUI_MAX_USERNAME_LENGTH + 1], Password[CREDUI_MAX_PASSWORD_LENGTH + 1]; WCHAR UserName[CREDUI_MAX_USERNAME_LENGTH + 1], Password[CREDUI_MAX_PASSWORD_LENGTH + 1];
#if defined(FSP_NP_CREDENTIAL_MANAGER) #if defined(FSP_NP_CREDENTIAL_MANAGER)
BOOL Save = TRUE; BOOL Save = TRUE;
@ -679,7 +690,7 @@ DWORD APIENTRY NPAddConnection3(HWND hwndOwner,
return NpResult; return NpResult;
} }
NpResult = FspNpGetRemoteInfo(RemoteName, &CredentialsKind); NpResult = FspNpGetRemoteInfo(RemoteName, &CredentialsKind, &AIDummy);
if (WN_SUCCESS != NpResult) if (WN_SUCCESS != NpResult)
return NpResult; return NpResult;
if (FSP_NP_CREDENTIALS_NONE == CredentialsKind) if (FSP_NP_CREDENTIALS_NONE == CredentialsKind)
@ -766,7 +777,8 @@ DWORD APIENTRY NPCancelConnection(LPWSTR lpName, BOOL fForce)
NpResult = FspNpCallLauncherPipe( NpResult = FspNpCallLauncherPipe(
FspLaunchCmdStop, FspLaunchCmdStop,
Argc, Argv, Argl, 0, 0); Argc, Argv, Argl, 0, 0,
FALSE);
switch (NpResult) switch (NpResult)
{ {
case WN_SUCCESS: case WN_SUCCESS:

View File

@ -67,6 +67,16 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize, PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize,
PULONG PBytesTransferred, ULONG Timeout, PULONG PBytesTransferred, ULONG Timeout,
PSID Sid) PSID Sid)
{
return FspCallNamedPipeSecurelyEx(PipeName,
InBuffer, InBufferSize, OutBuffer, OutBufferSize, PBytesTransferred, Timeout,
FALSE, Sid);
}
FSP_API NTSTATUS FspCallNamedPipeSecurelyEx(PWSTR PipeName,
PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize,
PULONG PBytesTransferred, ULONG Timeout, BOOLEAN AllowImpersonation,
PSID Sid)
{ {
NTSTATUS Result; NTSTATUS Result;
HANDLE Pipe = INVALID_HANDLE_VALUE; HANDLE Pipe = INVALID_HANDLE_VALUE;
@ -75,7 +85,8 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
Pipe = CreateFileW(PipeName, Pipe = CreateFileW(PipeName,
GENERIC_READ | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES, GENERIC_READ | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, 0); SECURITY_SQOS_PRESENT | (AllowImpersonation ? SECURITY_IMPERSONATION : SECURITY_IDENTIFICATION),
0);
if (INVALID_HANDLE_VALUE == Pipe) if (INVALID_HANDLE_VALUE == Pipe)
{ {
if (ERROR_PIPE_BUSY != GetLastError()) if (ERROR_PIPE_BUSY != GetLastError())
@ -89,7 +100,8 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
Pipe = CreateFileW(PipeName, Pipe = CreateFileW(PipeName,
GENERIC_READ | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES, GENERIC_READ | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, 0); SECURITY_SQOS_PRESENT | (AllowImpersonation ? SECURITY_IMPERSONATION : SECURITY_IDENTIFICATION),
0);
if (INVALID_HANDLE_VALUE == Pipe) if (INVALID_HANDLE_VALUE == Pipe)
{ {
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());

View File

@ -72,8 +72,8 @@ static int call_pipe_and_report(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize)
NTSTATUS Result; NTSTATUS Result;
DWORD LastError, BytesTransferred; DWORD LastError, BytesTransferred;
Result = FspCallNamedPipeSecurely(L"" FSP_LAUNCH_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize, Result = FspCallNamedPipeSecurelyEx(L"" FSP_LAUNCH_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize,
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, FSP_LAUNCH_PIPE_OWNER); &BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, TRUE, FSP_LAUNCH_PIPE_OWNER);
LastError = FspWin32FromNtStatus(Result); LastError = FspWin32FromNtStatus(Result);
if (0 != LastError) if (0 != LastError)

View File

@ -255,6 +255,7 @@ exit:
static BOOL LogonCreateProcess( static BOOL LogonCreateProcess(
PWSTR UserName, PWSTR UserName,
HANDLE Token,
LPCWSTR ApplicationName, LPCWSTR ApplicationName,
LPWSTR CommandLine, LPWSTR CommandLine,
LPSECURITY_ATTRIBUTES ProcessAttributes, LPSECURITY_ATTRIBUTES ProcessAttributes,
@ -271,11 +272,20 @@ static BOOL LogonCreateProcess(
if (0 != UserName) if (0 != UserName)
{ {
if (0 == invariant_wcsicmp(UserName, L"LocalSystem")) if (0 == invariant_wcsicmp(UserName, L"LocalSystem"))
{
UserName = 0; UserName = 0;
Token = 0;
}
else else
if (0 == invariant_wcsicmp(UserName, L"LocalService") || if (0 == invariant_wcsicmp(UserName, L"LocalService") ||
0 == invariant_wcsicmp(UserName, L"NetworkService")) 0 == invariant_wcsicmp(UserName, L"NetworkService"))
{
DomainName = L"NT AUTHORITY"; DomainName = L"NT AUTHORITY";
Token = 0;
}
else
if (0 == invariant_wcsicmp(UserName, L"."))
;
else else
{ {
SetLastError(ERROR_ACCESS_DENIED); SetLastError(ERROR_ACCESS_DENIED);
@ -299,18 +309,40 @@ static BOOL LogonCreateProcess(
HANDLE LogonToken = 0; HANDLE LogonToken = 0;
PVOID EnvironmentBlock = 0; PVOID EnvironmentBlock = 0;
DWORD SessionId;
DWORD LastError; DWORD LastError;
BOOL Success; BOOL Success;
Success = LogonUserW( if (0 == Token)
UserName, {
DomainName, Success = LogonUserW(
0, UserName,
LOGON32_LOGON_SERVICE, DomainName,
LOGON32_PROVIDER_DEFAULT, 0,
&LogonToken); LOGON32_LOGON_SERVICE,
if (!Success) LOGON32_PROVIDER_DEFAULT,
goto exit; &LogonToken);
if (!Success)
goto exit;
}
else
{
/* convert the impersonation token to a primary token */
Success = DuplicateTokenEx(Token,
TOKEN_ALL_ACCESS,
0,
SecurityAnonymous,
TokenPrimary,
&LogonToken);
if (!Success)
goto exit;
if (!ProcessIdToSessionId(GetCurrentProcessId(), &SessionId))
SessionId = 0;
/* place the duplicated token in the service session (session 0) */
Success = SetTokenInformation(LogonToken, TokenSessionId, &SessionId, sizeof SessionId);
if (!Success)
goto exit;
}
if (0 == Environment) if (0 == Environment)
{ {
@ -663,7 +695,7 @@ static NTSTATUS SvcInstanceAccessCheck(HANDLE ClientToken, ULONG DesiredAccess,
return Result; return Result;
} }
static NTSTATUS SvcInstanceCreateProcess(PWSTR UserName, static NTSTATUS SvcInstanceCreateProcess(PWSTR UserName, HANDLE ClientToken,
PWSTR Executable, PWSTR CommandLine, PWSTR WorkDirectory, PWSTR Executable, PWSTR CommandLine, PWSTR WorkDirectory,
HANDLE StdioHandles[2], HANDLE StdioHandles[2],
PPROCESS_INFORMATION ProcessInfo) PPROCESS_INFORMATION ProcessInfo)
@ -758,7 +790,7 @@ static NTSTATUS SvcInstanceCreateProcess(PWSTR UserName,
StartupInfoEx.StartupInfo.hStdOutput = ChildHandles[1]; StartupInfoEx.StartupInfo.hStdOutput = ChildHandles[1];
StartupInfoEx.StartupInfo.hStdError = ChildHandles[2]; StartupInfoEx.StartupInfo.hStdError = ChildHandles[2];
if (!LogonCreateProcess(UserName, if (!LogonCreateProcess(UserName, ClientToken,
Executable, CommandLine, 0, 0, TRUE, Executable, CommandLine, 0, 0, TRUE,
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP | EXTENDED_STARTUPINFO_PRESENT, CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP | EXTENDED_STARTUPINFO_PRESENT,
0, WorkDirectory, 0, WorkDirectory,
@ -779,7 +811,7 @@ static NTSTATUS SvcInstanceCreateProcess(PWSTR UserName,
* Not ideal, but... * Not ideal, but...
*/ */
StartupInfoEx.StartupInfo.cb = sizeof StartupInfoEx.StartupInfo; StartupInfoEx.StartupInfo.cb = sizeof StartupInfoEx.StartupInfo;
if (!LogonCreateProcess(UserName, if (!LogonCreateProcess(UserName, ClientToken,
Executable, CommandLine, 0, 0, TRUE, Executable, CommandLine, 0, 0, TRUE,
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP,
0, WorkDirectory, 0, WorkDirectory,
@ -792,7 +824,7 @@ static NTSTATUS SvcInstanceCreateProcess(PWSTR UserName,
} }
else else
{ {
if (!LogonCreateProcess(UserName, if (!LogonCreateProcess(UserName, ClientToken,
Executable, CommandLine, 0, 0, FALSE, Executable, CommandLine, 0, 0, FALSE,
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP,
0, WorkDirectory, 0, WorkDirectory,
@ -1009,7 +1041,7 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
Result = SvcInstanceCreateProcess(L'\0' != RunAsBuf[0] ? RunAsBuf : 0, Result = SvcInstanceCreateProcess(L'\0' != RunAsBuf[0] ? RunAsBuf : 0, ClientToken,
Executable, SvcInstance->CommandLine, L'\0' != WorkDirectory[0] ? WorkDirectory : 0, Executable, SvcInstance->CommandLine, L'\0' != WorkDirectory[0] ? WorkDirectory : 0,
RedirectStdio ? SvcInstance->StdioHandles : 0, &ProcessInfo); RedirectStdio ? SvcInstance->StdioHandles : 0, &ProcessInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
@ -1629,7 +1661,10 @@ static DWORD WINAPI SvcPipeServer(PVOID Context)
ClientToken = 0; ClientToken = 0;
if (!ImpersonateNamedPipeClient(SvcPipe) || if (!ImpersonateNamedPipeClient(SvcPipe) ||
!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &ClientToken) || (
!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_DUPLICATE, FALSE, &ClientToken) &&
!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &ClientToken)
) ||
!RevertToSelf()) !RevertToSelf())
{ {
LastError = GetLastError(); LastError = GetLastError();