https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0625eb374634510238dc3…
commit 0625eb374634510238dc3f36761f63428733190c
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sat Aug 31 17:24:47 2019 +0200
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sat Aug 31 17:24:47 2019 +0200
[SERVICES][ADVAPI32] Support the security process aka lsass.exe
- Reserve the pipe NtControlPipe0 for the security process.
- Count regular service control pipes from 1.
- Use I_ScIsSecurityProcess to identify the security process.
- Services.exe uses the SECURITY_SERVICES_STARTED event to notify the security process
that NtControlPipe0 is ready for use.
---
base/system/services/database.c | 108 +++++++++++++++++++++++++------------
base/system/services/services.c | 36 +++++++++++++
base/system/services/services.h | 1 +
dll/win32/advapi32/service/sctrl.c | 45 +++++++++-------
4 files changed, 137 insertions(+), 53 deletions(-)
diff --git a/base/system/services/database.c b/base/system/services/database.c
index 622bdf0c847..fc3d673c347 100644
--- a/base/system/services/database.c
+++ b/base/system/services/database.c
@@ -40,61 +40,89 @@ static DWORD PipeTimeout = 30000; /* 30 Seconds */
/* FUNCTIONS *****************************************************************/
+static
+BOOL
+ScmIsSecurityService(
+ _In_ PSERVICE_IMAGE pServiceImage)
+{
+ return (wcsstr(pServiceImage->pszImagePath, L"\\system32\\lsass.exe") !=
NULL);
+}
+
+
static DWORD
-ScmCreateNewControlPipe(PSERVICE_IMAGE pServiceImage)
+ScmCreateNewControlPipe(
+ _In_ PSERVICE_IMAGE pServiceImage,
+ _In_ BOOL bSecurityServiceProcess)
{
WCHAR szControlPipeName[MAX_PATH + 1];
SECURITY_ATTRIBUTES SecurityAttributes;
HKEY hServiceCurrentKey = INVALID_HANDLE_VALUE;
- DWORD ServiceCurrent = 0;
- DWORD KeyDisposition;
+ DWORD dwServiceCurrent = 1;
+ DWORD dwKeyDisposition;
DWORD dwKeySize;
DWORD dwError;
/* Get the service number */
- /* TODO: Create registry entry with correct write access */
- dwError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
-
L"SYSTEM\\CurrentControlSet\\Control\\ServiceCurrent", 0, NULL,
- REG_OPTION_VOLATILE,
- KEY_WRITE | KEY_READ,
- NULL,
- &hServiceCurrentKey,
- &KeyDisposition);
- if (dwError != ERROR_SUCCESS)
+ if (bSecurityServiceProcess == FALSE)
{
- DPRINT1("RegCreateKeyEx() failed with error %lu\n", dwError);
- return dwError;
- }
-
- if (KeyDisposition == REG_OPENED_EXISTING_KEY)
- {
- dwKeySize = sizeof(DWORD);
- dwError = RegQueryValueExW(hServiceCurrentKey,
- L"", 0, NULL, (BYTE*)&ServiceCurrent,
&dwKeySize);
-
+ /* TODO: Create registry entry with correct write access */
+ dwError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
+
L"SYSTEM\\CurrentControlSet\\Control\\ServiceCurrent",
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ KEY_WRITE | KEY_READ,
+ NULL,
+ &hServiceCurrentKey,
+ &dwKeyDisposition);
if (dwError != ERROR_SUCCESS)
{
- RegCloseKey(hServiceCurrentKey);
- DPRINT1("RegQueryValueEx() failed with error %lu\n", dwError);
+ DPRINT1("RegCreateKeyEx() failed with error %lu\n", dwError);
return dwError;
}
- ServiceCurrent++;
- }
+ if (dwKeyDisposition == REG_OPENED_EXISTING_KEY)
+ {
+ dwKeySize = sizeof(DWORD);
+ dwError = RegQueryValueExW(hServiceCurrentKey,
+ L"",
+ 0,
+ NULL,
+ (BYTE*)&dwServiceCurrent,
+ &dwKeySize);
+ if (dwError != ERROR_SUCCESS)
+ {
+ RegCloseKey(hServiceCurrentKey);
+ DPRINT1("RegQueryValueEx() failed with error %lu\n", dwError);
+ return dwError;
+ }
- dwError = RegSetValueExW(hServiceCurrentKey, L"", 0, REG_DWORD,
(BYTE*)&ServiceCurrent, sizeof(ServiceCurrent));
+ dwServiceCurrent++;
+ }
- RegCloseKey(hServiceCurrentKey);
+ dwError = RegSetValueExW(hServiceCurrentKey,
+ L"",
+ 0,
+ REG_DWORD,
+ (BYTE*)&dwServiceCurrent,
+ sizeof(dwServiceCurrent));
- if (dwError != ERROR_SUCCESS)
+ RegCloseKey(hServiceCurrentKey);
+
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT1("RegSetValueExW() failed (Error %lu)\n", dwError);
+ return dwError;
+ }
+ }
+ else
{
- DPRINT1("RegSetValueExW() failed (Error %lu)\n", dwError);
- return dwError;
+ dwServiceCurrent = 0;
}
/* Create '\\.\pipe\net\NtControlPipeXXX' instance */
StringCchPrintfW(szControlPipeName, ARRAYSIZE(szControlPipeName),
- L"\\\\.\\pipe\\net\\NtControlPipe%lu", ServiceCurrent);
+ L"\\\\.\\pipe\\net\\NtControlPipe%lu", dwServiceCurrent);
DPRINT("PipeName: %S\n", szControlPipeName);
@@ -437,6 +465,7 @@ ScmCreateOrReferenceServiceImage(PSERVICE pService)
DWORD dwError = ERROR_SUCCESS;
DWORD dwRecordSize;
LPWSTR pString;
+ BOOL bSecurityService;
DPRINT("ScmCreateOrReferenceServiceImage(%p)\n", pService);
@@ -518,8 +547,11 @@ ScmCreateOrReferenceServiceImage(PSERVICE pService)
goto done;
}
+ bSecurityService = ScmIsSecurityService(pServiceImage);
+
/* Create the control pipe */
- dwError = ScmCreateNewControlPipe(pServiceImage);
+ dwError = ScmCreateNewControlPipe(pServiceImage,
+ bSecurityService);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmCreateNewControlPipe() failed (Error %lu)\n",
dwError);
@@ -542,6 +574,11 @@ ScmCreateOrReferenceServiceImage(PSERVICE pService)
goto done;
}
+ if (bSecurityService)
+ {
+ SetSecurityServicesEvent();
+ }
+
/* FIXME: Add more initialization code here */
@@ -1806,7 +1843,8 @@ ScmWaitForServiceConnect(PSERVICE Service)
}
}
- if (dwProcessId != Service->lpImage->dwProcessId)
+ if ((ScmIsSecurityService(Service->lpImage) == FALSE)&&
+ (dwProcessId != Service->lpImage->dwProcessId))
{
#if 0
_ultow(Service->lpImage->dwProcessId, szBuffer1, 10);
@@ -1916,7 +1954,7 @@ ScmStartUserModeService(PSERVICE Service,
StartupInfo.lpDesktop = L"WinSta0\\Default";
}
- if (wcsstr(Service->lpImage->pszImagePath,
L"\\system32\\lsass.exe") == NULL)
+ if (!ScmIsSecurityService(Service->lpImage))
{
Result = CreateProcessW(NULL,
Service->lpImage->pszImagePath,
diff --git a/base/system/services/services.c b/base/system/services/services.c
index 75bfeeb195e..81725260253 100644
--- a/base/system/services/services.c
+++ b/base/system/services/services.c
@@ -28,6 +28,7 @@ int WINAPI RegisterServicesProcess(DWORD ServicesProcessId);
BOOL ScmInitialize = FALSE;
BOOL ScmShutdown = FALSE;
static HANDLE hScmShutdownEvent = NULL;
+static HANDLE hScmSecurityServicesEvent = NULL;
/* FUNCTIONS *****************************************************************/
@@ -48,6 +49,38 @@ PrintString(LPCSTR fmt, ...)
}
+DWORD
+SetSecurityServicesEvent(VOID)
+{
+ DWORD dwError;
+
+ if (hScmSecurityServicesEvent != NULL)
+ return ERROR_SUCCESS;
+
+ /* Create or open the SECURITY_SERVICES_STARTED event */
+ hScmSecurityServicesEvent = CreateEventW(NULL,
+ TRUE,
+ FALSE,
+ L"SECURITY_SERVICES_STARTED");
+ if (hScmSecurityServicesEvent == NULL)
+ {
+ dwError = GetLastError();
+ if (dwError != ERROR_ALREADY_EXISTS)
+ return dwError;
+
+ hScmSecurityServicesEvent = OpenEventW(EVENT_MODIFY_STATE,
+ FALSE,
+ L"SECURITY_SERVICES_STARTED");
+ if (hScmSecurityServicesEvent == NULL)
+ return GetLastError();
+ }
+
+ SetEvent(hScmSecurityServicesEvent);
+
+ return ERROR_SUCCESS;
+}
+
+
VOID
ScmLogEvent(DWORD dwEventId,
WORD wType,
@@ -258,6 +291,9 @@ done:
if (bCanDeleteNamedPipeCriticalSection != FALSE)
ScmDeleteNamedPipeCriticalSection();
+ if (hScmSecurityServicesEvent != NULL)
+ CloseHandle(hScmSecurityServicesEvent);
+
/* Close the shutdown event */
if (hScmShutdownEvent != NULL)
CloseHandle(hScmShutdownEvent);
diff --git a/base/system/services/services.h b/base/system/services/services.h
index 6e3ca20e11b..845ea020da1 100644
--- a/base/system/services/services.h
+++ b/base/system/services/services.h
@@ -256,6 +256,7 @@ ScmCreateDefaultServiceSD(
/* services.c */
VOID PrintString(LPCSTR fmt, ...);
+DWORD SetSecurityServicesEvent(VOID);
VOID ScmLogEvent(DWORD dwEventId,
WORD wType,
WORD wStrings,
diff --git a/dll/win32/advapi32/service/sctrl.c b/dll/win32/advapi32/service/sctrl.c
index 68ec2a6ac63..c0cf0f42288 100644
--- a/dll/win32/advapi32/service/sctrl.c
+++ b/dll/win32/advapi32/service/sctrl.c
@@ -58,6 +58,7 @@ typedef struct _ACTIVE_SERVICE
static DWORD dwActiveServiceCount = 0;
static PACTIVE_SERVICE lpActiveServices = NULL;
static handle_t hStatusBinding = NULL;
+static BOOL bSecurityServiceProcess = FALSE;
/* FUNCTIONS *****************************************************************/
@@ -227,7 +228,7 @@ ScConnectControlPipe(HANDLE *hPipe)
{
DWORD dwBytesWritten;
DWORD dwState;
- DWORD dwServiceCurrent = 0;
+ DWORD dwServiceCurrent = 1;
NTSTATUS Status;
WCHAR NtControlPipeName[MAX_PATH + 1];
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
@@ -237,25 +238,32 @@ ScConnectControlPipe(HANDLE *hPipe)
hPipe);
/* Get the service number and create the named pipe */
- RtlZeroMemory(&QueryTable,
- sizeof(QueryTable));
-
- QueryTable[0].Name = L"";
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
- QueryTable[0].EntryContext = &dwServiceCurrent;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
- L"ServiceCurrent",
- QueryTable,
- NULL,
- NULL);
- if (!NT_SUCCESS(Status))
+ if (bSecurityServiceProcess == FALSE)
{
- ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
- return RtlNtStatusToDosError(Status);
+ RtlZeroMemory(&QueryTable, sizeof(QueryTable));
+
+ QueryTable[0].Name = L"";
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
+ QueryTable[0].EntryContext = &dwServiceCurrent;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"ServiceCurrent",
+ QueryTable,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+ return RtlNtStatusToDosError(Status);
+ }
+ }
+ else
+ {
+ dwServiceCurrent = 0;
}
swprintf(NtControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u",
dwServiceCurrent);
+ TRACE("PipeName: %S\n", NtControlPipeName);
if (!WaitNamedPipeW(NtControlPipeName, 30000))
{
@@ -836,13 +844,14 @@ RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName,
*
* Undocumented
*
- * @unimplemented
+ * @implemented
*/
VOID
WINAPI
I_ScIsSecurityProcess(VOID)
{
- FIXME("I_ScIsSecurityProcess()\n");
+ TRACE("I_ScIsSecurityProcess()\n");
+ bSecurityServiceProcess = TRUE;
}