launcher: SvcInstanceCreate: refactor to use FspLaunchRegGetRecord

This commit is contained in:
Bill Zissimopoulos 2020-04-24 17:49:29 -07:00
parent a0801674c4
commit 3eb115eb22
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3

View File

@ -890,13 +890,9 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
SVC_INSTANCE *SvcInstance = 0; SVC_INSTANCE *SvcInstance = 0;
PWSTR ClientUserName = 0; PWSTR ClientUserName = 0;
DWORD ClientTokenInformation = -1; DWORD ClientTokenInformation = -1;
HKEY RegKey = 0; FSP_LAUNCH_REG_RECORD *Record = 0;
DWORD RegResult, RegSize; WCHAR CommandLine[512], Security[512];
DWORD ClassNameSize, InstanceNameSize; DWORD Length, ClassNameSize, InstanceNameSize;
WCHAR Executable[MAX_PATH], CommandLineBuf[512], WorkDirectory[MAX_PATH],
SecurityBuf[512], RunAsBuf[64];
PWSTR CommandLine, Security;
DWORD Credentials, JobControl, Recovery;
PSECURITY_DESCRIPTOR SecurityDescriptor = 0, NewSecurityDescriptor; PSECURITY_DESCRIPTOR SecurityDescriptor = 0, NewSecurityDescriptor;
PWSTR Argv[10]; PWSTR Argv[10];
PROCESS_INFORMATION ProcessInfo; PROCESS_INFORMATION ProcessInfo;
@ -904,9 +900,6 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
*PSvcInstance = 0; *PSvcInstance = 0;
lstrcpyW(CommandLineBuf, L"%0 ");
lstrcpyW(SecurityBuf, L"O:SYG:SY");
if (Argc > sizeof Argv / sizeof Argv[0] - 1) if (Argc > sizeof Argv / sizeof Argv[0] - 1)
Argc = sizeof Argv / sizeof Argv[0] - 1; Argc = sizeof Argv / sizeof Argv[0] - 1;
memcpy(Argv + 1, Argv0, Argc * sizeof(PWSTR)); memcpy(Argv + 1, Argv0, Argc * sizeof(PWSTR));
@ -927,112 +920,45 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
RegResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"" FSP_LAUNCH_REGKEY, Result = FspLaunchRegGetRecord(ClassName, 0, &Record);
0, FSP_LAUNCH_REGKEY_WOW64 | KEY_READ, &RegKey); if (!NT_SUCCESS(Result))
if (ERROR_SUCCESS != RegResult)
{
Result = FspNtStatusFromWin32(RegResult);
goto exit; goto exit;
}
RegSize = sizeof Credentials; if ((!RedirectStdio && 0 != Record->Credentials) ||
Credentials = 0; ( RedirectStdio && 0 == Record->Credentials))
RegResult = RegGetValueW(RegKey, ClassName, L"Credentials", RRF_RT_REG_DWORD, 0,
&Credentials, &RegSize);
if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult)
{
Result = FspNtStatusFromWin32(RegResult);
goto exit;
}
if ((!RedirectStdio && 0 != Credentials) ||
( RedirectStdio && 0 == Credentials))
{ {
Result = STATUS_DEVICE_CONFIGURATION_ERROR; Result = STATUS_DEVICE_CONFIGURATION_ERROR;
goto exit; goto exit;
} }
RegSize = sizeof Executable; Argv[0] = Record->Executable;
Executable[0] = L'\0';
RegResult = RegGetValueW(RegKey, ClassName, L"Executable", RRF_RT_REG_SZ, 0,
Executable, &RegSize);
if (ERROR_SUCCESS != RegResult)
{
Result = FspNtStatusFromWin32(RegResult);
goto exit;
}
Argv[0] = Executable;
CommandLine = CommandLineBuf + lstrlenW(CommandLineBuf); lstrcpyW(CommandLine, L"%0 ");
RegSize = (DWORD)(sizeof CommandLineBuf - (CommandLine - CommandLineBuf) * sizeof(WCHAR)); if (0 != Record->CommandLine)
RegResult = RegGetValueW(RegKey, ClassName, L"CommandLine", RRF_RT_REG_SZ, 0,
CommandLine, &RegSize);
if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult)
{ {
Result = FspNtStatusFromWin32(RegResult); Length = lstrlenW(CommandLine);
goto exit; lstrcpynW(CommandLine + Length, Record->CommandLine,
} sizeof CommandLine / sizeof(WCHAR) - Length);
if (ERROR_FILE_NOT_FOUND == RegResult) CommandLine[sizeof CommandLine / sizeof(WCHAR) - 1] = L'\0';
CommandLine[-1] = L'\0';
CommandLine = CommandLineBuf;
RegSize = sizeof WorkDirectory;
WorkDirectory[0] = L'\0';
RegResult = RegGetValueW(RegKey, ClassName, L"WorkDirectory", RRF_RT_REG_SZ, 0,
WorkDirectory, &RegSize);
if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult)
{
Result = FspNtStatusFromWin32(RegResult);
goto exit;
} }
Security = SecurityBuf + lstrlenW(SecurityBuf); lstrcpyW(Security, L"O:SYG:SY");
RegSize = (DWORD)(sizeof SecurityBuf - (Security - SecurityBuf) * sizeof(WCHAR)); if (0 != Record->Security)
RegResult = RegGetValueW(RegKey, ClassName, L"Security", RRF_RT_REG_SZ, 0,
Security, &RegSize);
if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult)
{ {
Result = FspNtStatusFromWin32(RegResult); if (L'D' == Record->Security[0] && L':' == Record->Security[1])
goto exit; Length = lstrlenW(Security);
else
Length = 0;
lstrcpynW(Security + Length, Record->Security,
sizeof Security / sizeof(WCHAR) - Length);
Security[sizeof Security / sizeof(WCHAR) - 1] = L'\0';
} }
else
RegSize = sizeof RunAsBuf;
RunAsBuf[0] = L'\0';
RegResult = RegGetValueW(RegKey, ClassName, L"RunAs", RRF_RT_REG_SZ, 0,
RunAsBuf, &RegSize);
if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult)
{ {
Result = FspNtStatusFromWin32(RegResult); Length = lstrlenW(Security);
goto exit; lstrcpyW(Security + Length, L"" FSP_LAUNCH_SERVICE_DEFAULT_SDDL);
} }
RegSize = sizeof JobControl;
JobControl = 1; /* default is YES! */
RegResult = RegGetValueW(RegKey, ClassName, L"JobControl", RRF_RT_REG_DWORD, 0,
&JobControl, &RegSize);
if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult)
{
Result = FspNtStatusFromWin32(RegResult);
goto exit;
}
RegSize = sizeof Recovery;
Recovery = 0;
RegResult = RegGetValueW(RegKey, ClassName, L"Recovery", RRF_RT_REG_DWORD, 0,
&Recovery, &RegSize);
if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult)
{
Result = FspNtStatusFromWin32(RegResult);
goto exit;
}
RegCloseKey(RegKey);
RegKey = 0;
if (L'\0' == Security[0])
lstrcpyW(Security, L"" FSP_LAUNCH_SERVICE_DEFAULT_SDDL);
if (L'D' == Security[0] && L':' == Security[1])
Security = SecurityBuf;
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(Security, SDDL_REVISION_1, if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(Security, SDDL_REVISION_1,
&SecurityDescriptor, 0)) &SecurityDescriptor, 0))
{ {
@ -1040,8 +966,6 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
goto exit; goto exit;
} }
//FspDebugLogSD(__FUNCTION__ ": SDDL = %s\n", SecurityDescriptor);
Result = SvcInstanceAccessCheck(ClientToken, SERVICE_START, SecurityDescriptor); Result = SvcInstanceAccessCheck(ClientToken, SERVICE_START, SecurityDescriptor);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -1052,8 +976,6 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
LocalFree(SecurityDescriptor); LocalFree(SecurityDescriptor);
SecurityDescriptor = NewSecurityDescriptor; SecurityDescriptor = NewSecurityDescriptor;
//FspDebugLogSD(__FUNCTION__ ": SDDL = %s\n", SecurityDescriptor);
ClassNameSize = (lstrlenW(ClassName) + 1) * sizeof(WCHAR); ClassNameSize = (lstrlenW(ClassName) + 1) * sizeof(WCHAR);
InstanceNameSize = (lstrlenW(InstanceName) + 1) * sizeof(WCHAR); InstanceNameSize = (lstrlenW(InstanceName) + 1) * sizeof(WCHAR);
@ -1071,7 +993,7 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
HANDLE_FLAG_PROTECT_FROM_CLOSE | 0)) HANDLE_FLAG_PROTECT_FROM_CLOSE | 0))
{ {
ClientTokenInformation = -1; ClientTokenInformation = -1;
Result = FspNtStatusFromWin32(RegResult); Result = FspNtStatusFromWin32(GetLastError());
goto exit; goto exit;
} }
@ -1085,7 +1007,7 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
SvcInstance->SecurityDescriptor = SecurityDescriptor; SvcInstance->SecurityDescriptor = SecurityDescriptor;
SvcInstance->StdioHandles[0] = INVALID_HANDLE_VALUE; SvcInstance->StdioHandles[0] = INVALID_HANDLE_VALUE;
SvcInstance->StdioHandles[1] = INVALID_HANDLE_VALUE; SvcInstance->StdioHandles[1] = INVALID_HANDLE_VALUE;
SvcInstance->Recovery = Recovery; SvcInstance->Recovery = Record->Recovery;
Result = SvcInstanceReplaceArguments(CommandLine, Result = SvcInstanceReplaceArguments(CommandLine,
Argc, Argv, Argc, Argv,
@ -1094,9 +1016,14 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
Result = SvcInstanceCreateProcess(L'\0' != RunAsBuf[0] ? RunAsBuf : 0, ClientToken, Result = SvcInstanceCreateProcess(
Executable, SvcInstance->CommandLine, L'\0' != WorkDirectory[0] ? WorkDirectory : 0, Record->RunAs,
RedirectStdio ? SvcInstance->StdioHandles : 0, &ProcessInfo); ClientToken,
Record->Executable,
SvcInstance->CommandLine,
Record->WorkDirectory,
RedirectStdio ? SvcInstance->StdioHandles : 0,
&ProcessInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -1110,7 +1037,7 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
goto exit; goto exit;
} }
if (0 != Job && JobControl) if (0 != Job && Record->JobControl)
{ {
if (!AssignProcessToJobObject(Job, SvcInstance->Process)) if (!AssignProcessToJobObject(Job, SvcInstance->Process))
FspServiceLog(EVENTLOG_WARNING_TYPE, FspServiceLog(EVENTLOG_WARNING_TYPE,
@ -1166,8 +1093,8 @@ exit:
} }
} }
if (0 != RegKey) if (0 != Record)
RegCloseKey(RegKey); FspLaunchRegFreeRecord(Record);
MemFree(ClientUserName); MemFree(ClientUserName);