[NTOSKRNL][LSASRV]

- Add the SRM code from Timos kernel-fun branch.
- Move its lsasrv code to a separate file.
Thank you very much, Timo!

svn path=/trunk/; revision=69697
This commit is contained in:
Eric Kohl 2015-10-25 14:33:27 +00:00
parent e9b79abb0f
commit ebdf8b1700
8 changed files with 910 additions and 0 deletions

View file

@ -22,6 +22,7 @@ list(APPEND SOURCE
registry.c
security.c
session.c
srm.c
utils.c
lsasrv.h
${CMAKE_CURRENT_BINARY_DIR}/dssetup_s.c

View file

@ -6,6 +6,8 @@
* COPYRIGHT: Copyright 2006-2009 Eric Kohl
*/
/* INCLUDES ****************************************************************/
#include "lsasrv.h"
/* FUNCTIONS ***************************************************************/
@ -140,6 +142,14 @@ LsapInitLsa(VOID)
/* Initialize the well known SIDs */
LsapInitSids();
/* Initialize the SRM server */
Status = LsapRmInitializeServer();
if (!NT_SUCCESS(Status))
{
ERR("LsapRmInitializeServer() failed (Status 0x%08lx)\n", Status);
return Status;
}
/* Initialize the LSA database */
LsapInitDatabase();

View file

@ -421,6 +421,10 @@ LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg);
NTSTATUS
LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg);
/* srm.c */
NTSTATUS
LsapRmInitializeServer(VOID);
/* utils.c */
INT
LsapLoadString(HINSTANCE hInstance,

View file

@ -0,0 +1,264 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: Local Security Authority Server DLL
* FILE: dll/win32/lsasrv/srm.c
* PURPOSE: Security Reference Monitor Server
*
* PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ****************************************************************/
#include "lsasrv.h"
#include <ndk/ntndk.h>
typedef struct _LSAP_RM_API_MESSAGE
{
PORT_MESSAGE Header;
ULONG ApiNumber;
union
{
UCHAR Fill[PORT_MAXIMUM_MESSAGE_LENGTH - sizeof(PORT_MESSAGE)];
struct
{
ULONG Info1;
} WriteLog;
} u;
} LSAP_RM_API_MESSAGE, *PLSAP_RM_API_MESSAGE;
enum _LSAP_API_NUMBER
{
LsapAdtWriteLogApi = 1,
LsapComponentTestApi,
LsapAsyncApi
};
/* GLOBALS *****************************************************************/
HANDLE SeLsaCommandPort;
HANDLE SeRmCommandPort;
/* FUNCTIONS ***************************************************************/
static
VOID
LsapComponentTest(
PLSAP_RM_API_MESSAGE Message)
{
ERR("Security: LSA Component Test Command Received\n");
}
static
VOID
LsapAdtWriteLog(
PLSAP_RM_API_MESSAGE Message)
{
ERR("LsapAdtWriteLog\n");
}
static
VOID
LsapAsync(
PLSAP_RM_API_MESSAGE Message)
{
ERR("LsapAsync\n");
}
static
DWORD
WINAPI
LsapRmServerThread(
PVOID StartContext)
{
LSAP_RM_API_MESSAGE Message;
PPORT_MESSAGE ReplyMessage;
REMOTE_PORT_VIEW RemotePortView;
HANDLE MessagePort, DummyPortHandle;
NTSTATUS Status;
/* Initialize the port message */
Message.Header.u1.s1.TotalLength = sizeof(Message);
Message.Header.u1.s1.DataLength = 0;
/* Listen on the LSA command port */
Status = NtListenPort(SeLsaCommandPort, &Message.Header);
if (!NT_SUCCESS(Status))
{
ERR("LsapRmServerThread - Port Listen failed 0x%lx\n", Status);
return Status;
}
/* Setup the Port View Structure */
RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
RemotePortView.ViewSize = 0;
RemotePortView.ViewBase = NULL;
/* Accept the connection */
Status = NtAcceptConnectPort(&MessagePort,
0,
&Message.Header,
TRUE,
NULL,
&RemotePortView);
if (!NT_SUCCESS(Status))
{
ERR("LsapRmServerThread - Port Accept Connect failed 0x%lx\n", Status);
return Status;
}
/* Complete the connection */
Status = NtCompleteConnectPort(MessagePort);
if (!NT_SUCCESS(Status))
{
ERR("LsapRmServerThread - Port Complete Connect failed 0x%lx\n", Status);
return Status;
}
/* No reply yet */
ReplyMessage = NULL;
/* Start looping */
while (TRUE)
{
/* Wait for a message */
Status = NtReplyWaitReceivePort(MessagePort,
NULL,
ReplyMessage,
&Message.Header);
if (!NT_SUCCESS(Status))
{
ERR("LsapRmServerThread - Failed to get message: 0x%lx", Status);
ReplyMessage = NULL;
continue;
}
/* Check if this is a connection request */
if (Message.Header.u2.s2.Type == LPC_CONNECTION_REQUEST)
{
/* Reject connection request */
NtAcceptConnectPort(&DummyPortHandle,
NULL,
&Message.Header,
FALSE,
NULL,
NULL);
/* Start over */
ReplyMessage = NULL;
continue;
}
/* Check if this is an actual request */
if (Message.Header.u2.s2.Type == LPC_REQUEST)
{
ReplyMessage = &Message.Header;
switch (Message.ApiNumber)
{
case LsapAdtWriteLogApi:
LsapAdtWriteLog(&Message);
break;
case LsapAsyncApi:
LsapAsync(&Message);
break;
case LsapComponentTestApi:
LsapComponentTest(&Message);
break;
default:
ERR("LsapRmServerThread - invalid API number: 0x%lx\n",
Message.ApiNumber);
ReplyMessage = NULL;
}
continue;
}
ERR("LsapRmServerThread - unexpected message type: 0x%lx\n",
Message.Header.u2.s2.Type);
/* Start over */
ReplyMessage = NULL;
}
}
NTSTATUS
LsapRmInitializeServer(VOID)
{
UNICODE_STRING Name;
OBJECT_ATTRIBUTES ObjectAttributes;
SECURITY_QUALITY_OF_SERVICE SecurityQos;
HANDLE InitEvent;
HANDLE ThreadHandle;
DWORD ThreadId;
NTSTATUS Status;
/* Create the LSA command port */
RtlInitUnicodeString(&Name, L"\\SeLsaCommandPort");
InitializeObjectAttributes(&ObjectAttributes, &Name, 0, NULL, NULL);
Status = NtCreatePort(&SeLsaCommandPort,
&ObjectAttributes,
0,
PORT_MAXIMUM_MESSAGE_LENGTH,
2 * PAGE_SIZE);
if (!NT_SUCCESS(Status))
{
ERR("LsapRmInitializeServer - Port Create failed 0x%lx\n", Status);
return Status;
}
/* Open the LSA init event */
RtlInitUnicodeString(&Name, L"\\SeLsaInitEvent");
InitializeObjectAttributes(&ObjectAttributes, &Name, 0, NULL, NULL);
Status = NtOpenEvent(&InitEvent, 2, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
ERR("LsapRmInitializeServer - Lsa Init Event Open failed 0x%lx\n", Status);
return Status;
}
/* Signal the kernel, that we are ready */
Status = NtSetEvent(InitEvent, 0);
if (!NT_SUCCESS(Status))
{
ERR("LsapRmInitializeServer - Set Init Event failed 0x%lx\n", Status);
return Status;
}
/* Setup the QoS structure */
SecurityQos.ImpersonationLevel = SecurityIdentification;
SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
SecurityQos.EffectiveOnly = TRUE;
/* Connect to the kernel server */
RtlInitUnicodeString(&Name, L"\\SeRmCommandPort");
Status = NtConnectPort(&SeRmCommandPort,
&Name,
&SecurityQos,
NULL,
NULL,
NULL,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
ERR("LsapRmInitializeServer - Connect to Rm Command Port failed 0x%lx\n", Status);
return Status;
}
/* Create the server thread */
ThreadHandle = CreateThread(NULL, 0, LsapRmServerThread, NULL, 0, &ThreadId);
if (ThreadHandle == NULL)
{
ERR("LsapRmInitializeServer - Create Thread failed 0x%lx\n", Status);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Close the server thread handle */
CloseHandle(ThreadHandle);
return STATUS_SUCCESS;
}

View file

@ -1950,6 +1950,9 @@ Phase1InitializationDiscard(IN PVOID Context)
MmFreeLoaderBlock(LoaderBlock);
LoaderBlock = Context = NULL;
/* Initialize the SRM in phase 1 */
if (!SeRmInitPhase1()) KeBugCheck(PROCESS1_INITIALIZATION_FAILED);
/* Update progress bar */
InbvUpdateProgressBar(100);

View file

@ -267,6 +267,10 @@ BOOLEAN
NTAPI
SepInitSDs(VOID);
BOOLEAN
NTAPI
SeRmInitPhase1(VOID);
VOID
NTAPI
SeDeassignPrimaryToken(struct _EPROCESS *Process);

View file

@ -266,6 +266,7 @@ list(APPEND SOURCE
${REACTOS_SOURCE_DIR}/ntoskrnl/se/sd.c
${REACTOS_SOURCE_DIR}/ntoskrnl/se/semgr.c
${REACTOS_SOURCE_DIR}/ntoskrnl/se/sid.c
${REACTOS_SOURCE_DIR}/ntoskrnl/se/srm.c
${REACTOS_SOURCE_DIR}/ntoskrnl/se/token.c
${REACTOS_SOURCE_DIR}/ntoskrnl/vf/driver.c
${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/guidobj.c

623
reactos/ntoskrnl/se/srm.c Normal file
View file

@ -0,0 +1,623 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/srm.c
* PURPOSE: Security Reference Monitor Server
*
* PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
extern LUID SeSystemAuthenticationId;
extern LUID SeAnonymousAuthenticationId;
/* PRIVATE DEFINITIONS ********************************************************/
#define SEP_LOGON_SESSION_TAG 'sLeS'
enum _RM_API_NUMBER
{
RmAuditSetCommand = 1,
RmCreateLogonSession = 2,
RmDeleteLogonSession = 3
};
typedef struct _SEP_RM_API_MESSAGE
{
PORT_MESSAGE Header;
ULONG ApiNumber;
union
{
UCHAR Fill[PORT_MAXIMUM_MESSAGE_LENGTH - sizeof(PORT_MESSAGE)];
NTSTATUS ResultStatus;
struct
{
BOOLEAN Enabled;
ULONG Flags[9];
} SetAuditEvent;
LUID LogonLuid;
} u;
} SEP_RM_API_MESSAGE, *PSEP_RM_API_MESSAGE;
typedef struct _SEP_LOGON_SESSION_REFERENCES
{
struct _SEP_LOGON_SESSION_REFERENCES *Next;
LUID LogonId;
ULONG ReferenceCount;
ULONG Flags;
PDEVICE_MAP pDeviceMap;
LIST_ENTRY TokenList;
} SEP_LOGON_SESSION_REFERENCES, *PSEP_LOGON_SESSION_REFERENCES;
VOID
NTAPI
SepRmCommandServerThread(
PVOID StartContext);
static
NTSTATUS
SepRmCreateLogonSession(
PLUID LogonLuid);
/* GLOBALS ********************************************************************/
HANDLE SeRmCommandPort;
HANDLE SeLsaInitEvent;
PVOID SepCommandPortViewBase;
PVOID SepCommandPortViewRemoteBase;
ULONG_PTR SepCommandPortViewBaseOffset;
static HANDLE SepRmCommandMessagePort;
BOOLEAN SepAdtAuditingEnabled;
ULONG SepAdtMinListLength = 0x2000;
ULONG SepAdtMaxListLength = 0x3000;
#define POLICY_AUDIT_EVENT_TYPE_COUNT 9 // (AuditCategoryAccountLogon - AuditCategorySystem + 1)
UCHAR SeAuditingState[POLICY_AUDIT_EVENT_TYPE_COUNT];
KGUARDED_MUTEX SepRmDbLock;
PSEP_LOGON_SESSION_REFERENCES SepLogonSessions;
/* PRIVATE FUNCTIONS **********************************************************/
NTSTATUS
NTAPI
SepRegQueryHelper(
PCWSTR KeyName,
PCWSTR ValueName,
ULONG ValueType,
ULONG DataLength,
PVOID ValueData)
{
UNICODE_STRING ValueNameString;
UNICODE_STRING KeyNameString;
ULONG ResultLength;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE KeyHandle = NULL;
struct
{
KEY_VALUE_PARTIAL_INFORMATION Partial;
UCHAR Buffer[64];
} KeyValueInformation;
NTSTATUS Status, CloseStatus;
PAGED_CODE();
RtlInitUnicodeString(&KeyNameString, KeyName);
InitializeObjectAttributes(&ObjectAttributes,
&KeyNameString,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenKey(&KeyHandle, KEY_QUERY_VALUE, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
return Status;
}
RtlInitUnicodeString(&ValueNameString, ValueName);
Status = ZwQueryValueKey(KeyHandle,
&ValueNameString,
KeyValuePartialInformation,
&KeyValueInformation.Partial,
sizeof(KeyValueInformation),
&ResultLength);
if (!NT_SUCCESS(Status))
{
goto Cleanup;
}
if ((KeyValueInformation.Partial.Type != ValueType) ||
(KeyValueInformation.Partial.DataLength != DataLength))
{
Status = STATUS_OBJECT_TYPE_MISMATCH;
goto Cleanup;
}
if (ValueType == REG_BINARY)
{
RtlCopyMemory(ValueData, KeyValueInformation.Partial.Data, DataLength);
}
else if (ValueType == REG_DWORD)
{
*(PULONG)ValueData = *(PULONG)KeyValueInformation.Partial.Data;
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
Cleanup:
CloseStatus = ZwClose(KeyHandle);
ASSERT(NT_SUCCESS( CloseStatus ));
return Status;
}
BOOLEAN
NTAPI
SeRmInitPhase1(VOID)
{
UNICODE_STRING Name;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE ThreadHandle;
NTSTATUS Status;
// Windows does this in SeRmInitPhase0, but it should not matter
KeInitializeGuardedMutex(&SepRmDbLock);
Status = SepRmCreateLogonSession(&SeSystemAuthenticationId);
if (!NT_VERIFY(NT_SUCCESS(Status)))
{
return FALSE;
}
Status = SepRmCreateLogonSession(&SeAnonymousAuthenticationId);
if (!NT_VERIFY(NT_SUCCESS(Status)))
{
return FALSE;
}
/* Create the SeRm command port */
RtlInitUnicodeString(&Name, L"\\SeRmCommandPort");
InitializeObjectAttributes(&ObjectAttributes, &Name, 0, NULL, NULL);
Status = ZwCreatePort(&SeRmCommandPort,
&ObjectAttributes,
sizeof(ULONG),
PORT_MAXIMUM_MESSAGE_LENGTH,
2 * PAGE_SIZE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Security: Rm Create Command Port failed 0x%lx\n", Status);
return FALSE;
}
/* Create SeLsaInitEvent */
RtlInitUnicodeString(&Name, L"\\SeLsaInitEvent");
InitializeObjectAttributes(&ObjectAttributes, &Name, 0, NULL, NULL);
Status = ZwCreateEvent(&SeLsaInitEvent,
GENERIC_WRITE,
&ObjectAttributes,
NotificationEvent,
FALSE);
if (!NT_VERIFY((NT_SUCCESS(Status))))
{
DPRINT1("Security: LSA init event creation failed.0x%xl\n", Status);
return FALSE;
}
/* Create the SeRm server thread */
Status = PsCreateSystemThread(&ThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
SepRmCommandServerThread,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Security: Rm Server Thread creation failed 0x%lx\n", Status);
return FALSE;
}
ObCloseHandle(ThreadHandle, KernelMode);
return TRUE;
}
static
VOID
SepAdtInitializeBounds(VOID)
{
struct
{
ULONG MaxLength;
ULONG MinLength;
} ListBounds;
NTSTATUS Status;
PAGED_CODE();
Status = SepRegQueryHelper(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Lsa",
L"Bounds",
REG_BINARY,
sizeof(ListBounds),
&ListBounds);
if (!NT_SUCCESS(Status))
{
/* No registry values, so keep hardcoded defaults */
return;
}
/* Check if the bounds are valid */
if ((ListBounds.MaxLength < ListBounds.MinLength) ||
(ListBounds.MinLength < 16) ||
(ListBounds.MaxLength - ListBounds.MinLength < 16))
{
DPRINT1("ListBounds are invalid: %u, %u\n",
ListBounds.MinLength, ListBounds.MaxLength);
return;
}
/* Set the new bounds globally */
SepAdtMinListLength = ListBounds.MinLength;
SepAdtMaxListLength = ListBounds.MaxLength;
}
static
NTSTATUS
SepRmSetAuditEvent(
PSEP_RM_API_MESSAGE Message)
{
ULONG i;
PAGED_CODE();
/* First re-initialize the bounds from the registry */
SepAdtInitializeBounds();
/* Make sure we have the right message and clear */
ASSERT(Message->ApiNumber == RmAuditSetCommand);
Message->ApiNumber = 0;
/* Store the enable flag in the global variable */
SepAdtAuditingEnabled = Message->u.SetAuditEvent.Enabled;
/* Loop all audit event types */
for (i = 0; i < POLICY_AUDIT_EVENT_TYPE_COUNT; i++)
{
/* Save the provided flags in the global array */
SeAuditingState[i] = (UCHAR)Message->u.SetAuditEvent.Flags[i];
}
return STATUS_SUCCESS;
}
static
NTSTATUS
SepRmCreateLogonSession(
PLUID LogonLuid)
{
PSEP_LOGON_SESSION_REFERENCES CurrentSession, NewSession;
NTSTATUS Status;
PAGED_CODE();
DPRINT1("SepRmCreateLogonSession(<0x%lx,0x%lx>)\n",
LogonLuid->HighPart, LogonLuid->LowPart);
/* Allocate a new session structure */
NewSession = ExAllocatePoolWithTag(PagedPool,
sizeof(SEP_LOGON_SESSION_REFERENCES),
SEP_LOGON_SESSION_TAG);
if (NewSession == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Initialize it */
NewSession->LogonId = *LogonLuid;
NewSession->ReferenceCount = 0;
NewSession->Flags = 0;
NewSession->pDeviceMap = NULL;
InitializeListHead(&NewSession->TokenList);
/* Acquire the database lock */
KeAcquireGuardedMutex(&SepRmDbLock);
/* Loop all existing sessions */
for (CurrentSession = SepLogonSessions;
CurrentSession != NULL;
CurrentSession = CurrentSession->Next)
{
/* Check if the LUID matches the new one */
if (RtlEqualLuid(&CurrentSession->LogonId, LogonLuid))
{
Status = STATUS_LOGON_SESSION_EXISTS;
goto Leave;
}
}
/* Insert the new session */
NewSession->Next = SepLogonSessions;
SepLogonSessions = NewSession;
Status = STATUS_SUCCESS;
Leave:
/* Release the database lock */
KeReleaseGuardedMutex(&SepRmDbLock);
if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(NewSession, SEP_LOGON_SESSION_TAG);
}
return Status;
}
static
NTSTATUS
SepRmDeleteLogonSession(
PLUID LogonLuid)
{
DPRINT1("SepRmDeleteLogonSession(<0x%lx,0x%lx>)\n",
LogonLuid->HighPart, LogonLuid->LowPart);
UNIMPLEMENTED;
NT_ASSERT(FALSE);
return STATUS_NOT_IMPLEMENTED;
}
BOOLEAN
NTAPI
SepRmCommandServerThreadInit(VOID)
{
SECURITY_QUALITY_OF_SERVICE SecurityQos;
SEP_RM_API_MESSAGE Message;
UNICODE_STRING PortName;
REMOTE_PORT_VIEW RemotePortView;
PORT_VIEW PortView;
LARGE_INTEGER SectionSize;
HANDLE SectionHandle;
HANDLE PortHandle;
NTSTATUS Status;
BOOLEAN Result;
SectionHandle = NULL;
PortHandle = NULL;
/* Assume success */
Result = TRUE;
/* Wait until LSASS is ready */
Status = ZwWaitForSingleObject(SeLsaInitEvent, FALSE, NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Security Rm Init: Waiting for LSA Init Event failed 0x%lx\n", Status);
goto Cleanup;
}
/* We don't need this event anymore */
ObCloseHandle(SeLsaInitEvent, KernelMode);
/* Initialize the connection message */
Message.Header.u1.s1.TotalLength = sizeof(Message);
Message.Header.u1.s1.DataLength = 0;
/* Only LSASS can connect, so handle the connection right now */
Status = ZwListenPort(SeRmCommandPort, &Message.Header);
if (!NT_SUCCESS(Status))
{
DPRINT1("Security Rm Init: Listen to Command Port failed 0x%lx\n", Status);
goto Cleanup;
}
/* Set the Port View structure length */
RemotePortView.Length = sizeof(RemotePortView);
/* Accept the connection */
Status = ZwAcceptConnectPort(&SepRmCommandMessagePort,
NULL,
&Message.Header,
TRUE,
NULL,
&RemotePortView);
if (!NT_SUCCESS(Status))
{
DPRINT1("Security Rm Init: Accept Connect to Command Port failed 0x%lx\n", Status);
goto Cleanup;
}
/* Complete the connection */
Status = ZwCompleteConnectPort(SepRmCommandMessagePort);
if (!NT_SUCCESS(Status))
{
DPRINT1("Security Rm Init: Complete Connect to Command Port failed 0x%lx\n", Status);
goto Cleanup;
}
/* Create a section for messages */
SectionSize.QuadPart = PAGE_SIZE;
Status = ZwCreateSection(&SectionHandle,
SECTION_ALL_ACCESS,
NULL,
&SectionSize,
PAGE_READWRITE,
SEC_COMMIT,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Security Rm Init: Create Memory Section for LSA port failed: %X\n", Status);
goto Cleanup;
}
/* Setup the PORT_VIEW structure */
PortView.Length = sizeof(PortView);
PortView.SectionHandle = SectionHandle;
PortView.SectionOffset = 0;
PortView.ViewSize = SectionSize.LowPart;
PortView.ViewBase = NULL;
PortView.ViewRemoteBase = NULL;
/* Setup security QOS */
SecurityQos.Length = sizeof(SecurityQos);
SecurityQos.ImpersonationLevel = SecurityImpersonation;
SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
SecurityQos.EffectiveOnly = TRUE;
/* Connect to LSASS */
RtlInitUnicodeString(&PortName, L"\\SeLsaCommandPort");
Status = ZwConnectPort(&PortHandle,
&PortName,
&SecurityQos,
&PortView,
NULL,
0,
0,
0);
if (!NT_SUCCESS(Status))
{
DPRINT1("Security Rm Init: Connect to LSA Port failed 0x%lx\n", Status);
goto Cleanup;
}
/* Remember section base and view offset */
SepCommandPortViewBase = PortView.ViewBase;
SepCommandPortViewRemoteBase = PortView.ViewRemoteBase;
SepCommandPortViewBaseOffset = (ULONG_PTR)SepCommandPortViewRemoteBase -
(ULONG_PTR)SepCommandPortViewBase;
DPRINT("SepRmCommandServerThreadInit: done\n");
Cleanup:
/* Check for failure */
if (!NT_SUCCESS(Status))
{
if (PortHandle != NULL)
{
ObCloseHandle(PortHandle, KernelMode);
}
Result = FALSE;
}
/* Did we create a section? */
if (SectionHandle != NULL)
{
ObCloseHandle(SectionHandle, KernelMode);
}
return Result;
}
VOID
NTAPI
SepRmCommandServerThread(
PVOID StartContext)
{
SEP_RM_API_MESSAGE Message;
PPORT_MESSAGE ReplyMessage;
HANDLE DummyPortHandle;
NTSTATUS Status;
/* Initialize the server thread */
if (!SepRmCommandServerThreadInit())
{
DPRINT1("Security: Terminating Rm Command Server Thread\n");
return;
}
/* No reply yet */
ReplyMessage = NULL;
/* Start looping */
while (TRUE)
{
/* Wait for a message */
Status = ZwReplyWaitReceivePort(SepRmCommandMessagePort,
NULL,
ReplyMessage,
&Message.Header);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get message: 0x%lx", Status);
ReplyMessage = NULL;
continue;
}
/* Check if this is a connection request */
if (Message.Header.u2.s2.Type == LPC_CONNECTION_REQUEST)
{
/* Reject connection request */
ZwAcceptConnectPort(&DummyPortHandle,
NULL,
&Message.Header,
FALSE,
NULL,
NULL);
/* Start over */
ReplyMessage = NULL;
continue;
}
/* Check if the port died */
if ((Message.Header.u2.s2.Type == LPC_PORT_CLOSED) ||
(Message.Header.u2.s2.Type == LPC_CLIENT_DIED))
{
/* LSASS is dead, so let's quit as well */
break;
}
/* Check if this is an actual request */
if (Message.Header.u2.s2.Type != LPC_REQUEST)
{
DPRINT1("SepRmCommandServerThread: unexpected message type: 0x%lx\n",
Message.Header.u2.s2.Type);
/* Restart without replying */
ReplyMessage = NULL;
continue;
}
ReplyMessage = &Message.Header;
switch (Message.ApiNumber)
{
case RmAuditSetCommand:
Status = SepRmSetAuditEvent(&Message);
break;
case RmCreateLogonSession:
Status = SepRmCreateLogonSession(&Message.u.LogonLuid);
break;
case RmDeleteLogonSession:
Status = SepRmDeleteLogonSession(&Message.u.LogonLuid);
break;
default:
DPRINT1("SepRmDispatchRequest: invalid API number: 0x%lx\n",
Message.ApiNumber);
ReplyMessage = NULL;
}
Message.u.ResultStatus = Status;
}
/* Close the port handles */
ObCloseHandle(SepRmCommandMessagePort, KernelMode);
ObCloseHandle(SeRmCommandPort, KernelMode);
}