mirror of
https://github.com/reactos/reactos.git
synced 2025-02-21 16:04:57 +00:00
[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.
This commit is contained in:
parent
8571c26a71
commit
0625eb3746
4 changed files with 139 additions and 55 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
dwServiceCurrent++;
|
||||
}
|
||||
|
||||
dwError = RegSetValueExW(hServiceCurrentKey,
|
||||
L"",
|
||||
0,
|
||||
REG_DWORD,
|
||||
(BYTE*)&dwServiceCurrent,
|
||||
sizeof(dwServiceCurrent));
|
||||
|
||||
RegCloseKey(hServiceCurrentKey);
|
||||
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegSetValueExW() failed (Error %lu)\n", dwError);
|
||||
return dwError;
|
||||
}
|
||||
}
|
||||
|
||||
dwError = RegSetValueExW(hServiceCurrentKey, L"", 0, REG_DWORD, (BYTE*)&ServiceCurrent, sizeof(ServiceCurrent));
|
||||
|
||||
RegCloseKey(hServiceCurrentKey);
|
||||
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -256,6 +256,7 @@ ScmCreateDefaultServiceSD(
|
|||
/* services.c */
|
||||
|
||||
VOID PrintString(LPCSTR fmt, ...);
|
||||
DWORD SetSecurityServicesEvent(VOID);
|
||||
VOID ScmLogEvent(DWORD dwEventId,
|
||||
WORD wType,
|
||||
WORD wStrings,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue