mirror of
https://github.com/reactos/reactos.git
synced 2024-06-25 23:41:35 +00:00
[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:
parent
e9b79abb0f
commit
ebdf8b1700
|
@ -22,6 +22,7 @@ list(APPEND SOURCE
|
||||||
registry.c
|
registry.c
|
||||||
security.c
|
security.c
|
||||||
session.c
|
session.c
|
||||||
|
srm.c
|
||||||
utils.c
|
utils.c
|
||||||
lsasrv.h
|
lsasrv.h
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/dssetup_s.c
|
${CMAKE_CURRENT_BINARY_DIR}/dssetup_s.c
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
* COPYRIGHT: Copyright 2006-2009 Eric Kohl
|
* COPYRIGHT: Copyright 2006-2009 Eric Kohl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ****************************************************************/
|
||||||
|
|
||||||
#include "lsasrv.h"
|
#include "lsasrv.h"
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
@ -140,6 +142,14 @@ LsapInitLsa(VOID)
|
||||||
/* Initialize the well known SIDs */
|
/* Initialize the well known SIDs */
|
||||||
LsapInitSids();
|
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 */
|
/* Initialize the LSA database */
|
||||||
LsapInitDatabase();
|
LsapInitDatabase();
|
||||||
|
|
||||||
|
|
|
@ -421,6 +421,10 @@ LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg);
|
LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg);
|
||||||
|
|
||||||
|
/* srm.c */
|
||||||
|
NTSTATUS
|
||||||
|
LsapRmInitializeServer(VOID);
|
||||||
|
|
||||||
/* utils.c */
|
/* utils.c */
|
||||||
INT
|
INT
|
||||||
LsapLoadString(HINSTANCE hInstance,
|
LsapLoadString(HINSTANCE hInstance,
|
||||||
|
|
264
reactos/dll/win32/lsasrv/srm.c
Normal file
264
reactos/dll/win32/lsasrv/srm.c
Normal 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;
|
||||||
|
}
|
|
@ -1950,6 +1950,9 @@ Phase1InitializationDiscard(IN PVOID Context)
|
||||||
MmFreeLoaderBlock(LoaderBlock);
|
MmFreeLoaderBlock(LoaderBlock);
|
||||||
LoaderBlock = Context = NULL;
|
LoaderBlock = Context = NULL;
|
||||||
|
|
||||||
|
/* Initialize the SRM in phase 1 */
|
||||||
|
if (!SeRmInitPhase1()) KeBugCheck(PROCESS1_INITIALIZATION_FAILED);
|
||||||
|
|
||||||
/* Update progress bar */
|
/* Update progress bar */
|
||||||
InbvUpdateProgressBar(100);
|
InbvUpdateProgressBar(100);
|
||||||
|
|
||||||
|
|
|
@ -267,6 +267,10 @@ BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
SepInitSDs(VOID);
|
SepInitSDs(VOID);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
SeRmInitPhase1(VOID);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
SeDeassignPrimaryToken(struct _EPROCESS *Process);
|
SeDeassignPrimaryToken(struct _EPROCESS *Process);
|
||||||
|
|
|
@ -266,6 +266,7 @@ list(APPEND SOURCE
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/se/sd.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/se/sd.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/se/semgr.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/se/semgr.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/se/sid.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/se/token.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/vf/driver.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/vf/driver.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/guidobj.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/wmi/guidobj.c
|
||||||
|
|
623
reactos/ntoskrnl/se/srm.c
Normal file
623
reactos/ntoskrnl/se/srm.c
Normal 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);
|
||||||
|
}
|
Loading…
Reference in a new issue