You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
817 lines
21 KiB
817 lines
21 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
lsarm.c
|
|
|
|
Abstract:
|
|
|
|
Local Security Authority - Reference Monitor Communication
|
|
|
|
Author:
|
|
|
|
Scott Birrell (ScottBi) March 26, 1991
|
|
|
|
Environment:
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <lsapch2.h>
|
|
|
|
//
|
|
// LSA Global State
|
|
//
|
|
|
|
LSAP_STATE LsapState;
|
|
|
|
//
|
|
// Lsa Reference Monitor Server Command Dispatch Table
|
|
//
|
|
|
|
NTSTATUS
|
|
LsapAsyncWrkr(
|
|
IN PLSA_COMMAND_MESSAGE CommandMessage,
|
|
OUT PLSA_REPLY_MESSAGE ReplyMessage
|
|
);
|
|
|
|
PLSA_COMMAND_WORKER LsapCommandDispatch[] = {
|
|
|
|
LsapComponentTestWrkr,
|
|
LsapAdtWriteLogWrkr,
|
|
LsapComponentTestWrkr,
|
|
LsapAsyncWrkr // LogonSessionDelete handled async
|
|
|
|
};
|
|
|
|
PLSA_COMMAND_WORKER LsapAsyncCommandDispatch[] = {
|
|
LsapComponentTestWrkr,
|
|
LsapAdtWriteLogWrkr,
|
|
LsapComponentTestWrkr,
|
|
LsapLogonSessionDeletedWrkr
|
|
};
|
|
|
|
#if 0
|
|
DWORD
|
|
LsapRmServerWorker(
|
|
PVOID Ignored
|
|
)
|
|
{
|
|
PLSA_REPLY_MESSAGE Reply;
|
|
LSA_COMMAND_MESSAGE CommandMessage;
|
|
|
|
NTSTATUS Status;
|
|
|
|
//
|
|
// Initialize the LPC port message header type and data sizes for
|
|
// for the reply message.
|
|
//
|
|
|
|
ReplyMessage.MessageHeader.u2.ZeroInit = 0;
|
|
ReplyMessage.MessageHeader.u1.s1.TotalLength =
|
|
(CSHORT) sizeof(RM_COMMAND_MESSAGE);
|
|
ReplyMessage.MessageHeader.u1.s1.DataLength =
|
|
ReplyMessage.MessageHeader.u1.s1.TotalLength -
|
|
(CSHORT) sizeof(PORT_MESSAGE);
|
|
|
|
//
|
|
// Called whenever the port handle is signalled
|
|
//
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
#endif
|
|
|
|
NTSTATUS
|
|
LsapAsyncRmWorker(
|
|
IN PLSA_COMMAND_MESSAGE CommandMessage
|
|
)
|
|
{
|
|
LSA_REPLY_MESSAGE ReplyMessage;
|
|
NTSTATUS Status ;
|
|
|
|
Status = (LsapAsyncCommandDispatch[CommandMessage->CommandNumber])(
|
|
CommandMessage,
|
|
&ReplyMessage);
|
|
|
|
//
|
|
// only send a reply if it wasn't a datagram.
|
|
//
|
|
|
|
if (CommandMessage->MessageHeader.u2.s2.Type != LPC_DATAGRAM) {
|
|
|
|
ReplyMessage.MessageHeader = CommandMessage->MessageHeader ;
|
|
ReplyMessage.ReturnedStatus = Status ;
|
|
|
|
Status = NtReplyPort( LsapState.LsaCommandPortHandle,
|
|
(PPORT_MESSAGE) &ReplyMessage );
|
|
|
|
}
|
|
|
|
LsapFreePrivateHeap( CommandMessage );
|
|
|
|
return Status ;
|
|
|
|
|
|
}
|
|
|
|
NTSTATUS
|
|
LsapAsyncWrkr(
|
|
IN PLSA_COMMAND_MESSAGE CommandMessage,
|
|
OUT PLSA_REPLY_MESSAGE ReplyMessage
|
|
)
|
|
{
|
|
LsapAssignThread( LsapAsyncRmWorker,
|
|
CommandMessage,
|
|
pDefaultSession,
|
|
FALSE );
|
|
|
|
return STATUS_PENDING ;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
LsapRmServerThread(
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is executed by the LSA Reference Monitor Server Thread. This
|
|
thread receives messages from the Reference Monitor. Examples of messages
|
|
include Audit Messages,... The function is implemented as a for loop
|
|
which runs indefinitely unless an error occurs. Currently, any
|
|
error is fatal. On each iteration a message is received from the
|
|
Reference Monitor and dispatched to a handler.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None. Any return is a fatal error.
|
|
|
|
--*/
|
|
|
|
{
|
|
PLSA_REPLY_MESSAGE Reply;
|
|
// LSA_COMMAND_MESSAGE CommandMessage;
|
|
LSA_REPLY_MESSAGE ReplyMessage;
|
|
PLSA_COMMAND_MESSAGE CommandMessage = NULL;
|
|
|
|
NTSTATUS Status;
|
|
BOOLEAN PriorDatagram = FALSE;
|
|
|
|
//
|
|
// Initialize the LPC port message header type and data sizes for
|
|
// for the reply message.
|
|
//
|
|
|
|
ReplyMessage.MessageHeader.u2.ZeroInit = 0;
|
|
ReplyMessage.MessageHeader.u1.s1.TotalLength =
|
|
(CSHORT) sizeof(RM_COMMAND_MESSAGE);
|
|
ReplyMessage.MessageHeader.u1.s1.DataLength =
|
|
ReplyMessage.MessageHeader.u1.s1.TotalLength -
|
|
(CSHORT) sizeof(PORT_MESSAGE);
|
|
|
|
//
|
|
// First time through, there is no reply.
|
|
//
|
|
|
|
Reply = NULL;
|
|
|
|
//
|
|
// Now loop indefinitely, processing incoming Command Message Packets
|
|
//
|
|
|
|
for(;;) {
|
|
|
|
//
|
|
// Wait for and receive a message from the Reference Monitor through
|
|
// the Lsa Command LPC Port.
|
|
//
|
|
|
|
//
|
|
// If Reply is NULL, then this is either the first time through the
|
|
// loop, or we have spun the last command off async, so don't screw
|
|
// with its buffer. Otherwise, the pointer is valid, and ready to
|
|
// be reused.
|
|
//
|
|
|
|
if ( !Reply )
|
|
{
|
|
CommandMessage = LsapAllocatePrivateHeap(
|
|
sizeof( LSA_COMMAND_MESSAGE ) );
|
|
|
|
while ( !CommandMessage )
|
|
{
|
|
//
|
|
// A bit of a pickle. We need to have a buffer to receive on.
|
|
// Spin and retry:
|
|
//
|
|
|
|
Sleep( 100 );
|
|
|
|
CommandMessage = LsapAllocatePrivateHeap(
|
|
sizeof( LSA_COMMAND_MESSAGE ) );
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// if prior datagram, do not send a reply.
|
|
//
|
|
|
|
Status = NtReplyWaitReceivePort(
|
|
LsapState.LsaCommandPortHandle,
|
|
NULL,
|
|
(PPORT_MESSAGE) (!PriorDatagram ? Reply : NULL),
|
|
(PPORT_MESSAGE) CommandMessage
|
|
);
|
|
|
|
//
|
|
// assume not datagram.
|
|
//
|
|
|
|
PriorDatagram = FALSE;
|
|
|
|
|
|
if (Status != 0) {
|
|
if (!NT_SUCCESS( Status ) &&
|
|
Status != STATUS_INVALID_CID &&
|
|
Status != STATUS_UNSUCCESSFUL
|
|
) {
|
|
KdPrint(("LSASS: Lsa message receive from Rm failed x%lx\n", Status));
|
|
}
|
|
|
|
//
|
|
// Ignore if client went away.
|
|
//
|
|
|
|
Reply = NULL;
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// If an LPC request, process it.
|
|
//
|
|
|
|
if (CommandMessage->MessageHeader.u2.s2.Type == LPC_REQUEST ||
|
|
CommandMessage->MessageHeader.u2.s2.Type == LPC_DATAGRAM) {
|
|
|
|
//
|
|
//
|
|
// Now dispatch to a routine to handle the command. Allow
|
|
// command errors to occur without bringing system down.
|
|
//
|
|
|
|
Reply = &ReplyMessage;
|
|
Reply->MessageHeader = CommandMessage->MessageHeader ;
|
|
|
|
Status = (LsapCommandDispatch[CommandMessage->CommandNumber])(
|
|
CommandMessage,
|
|
Reply);
|
|
|
|
if ( Status == STATUS_PENDING )
|
|
{
|
|
//
|
|
// It has been sent off asynchronously. Set the reply
|
|
// to NULL so that we don't trip the LPC at the top of
|
|
// the loop, and the handler will do it when it is done.
|
|
//
|
|
|
|
Reply = NULL ;
|
|
}
|
|
else
|
|
{
|
|
ReplyMessage.ReturnedStatus = Status;
|
|
|
|
//
|
|
// datagram should not send a reply, and, we can re-use
|
|
// the prior buffer.
|
|
//
|
|
|
|
if(CommandMessage->MessageHeader.u2.s2.Type == LPC_DATAGRAM)
|
|
{
|
|
PriorDatagram = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Reply = NULL;
|
|
}
|
|
|
|
} // end_for
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
LsapRmInitializeServer(
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function initializes the Lsa Reference Monitor Server Thread.
|
|
The following steps are performed.
|
|
|
|
o Create the Lsa Command LPC Port
|
|
o Open the Lsa Init event created by the Reference Monitor
|
|
o Signal the Lsa Init Event, telling RM to go ahead and connect
|
|
to the port
|
|
o Connect to the Reference Monitor Command Port as client
|
|
o Listen for the Reference Monitor to connect to the port
|
|
o Accept the connection to the port
|
|
o Complete the connection to the port
|
|
o Create the LSA Reference Monitor Server Thread
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
PORT_MESSAGE ConnectionRequest;
|
|
REMOTE_PORT_VIEW ClientView;
|
|
|
|
HANDLE LsaInitEventHandle;
|
|
OBJECT_ATTRIBUTES LsaInitEventObjA;
|
|
UNICODE_STRING LsaInitEventName;
|
|
|
|
UNICODE_STRING RmCommandPortName, LsaCommandPortName;
|
|
|
|
OBJECT_ATTRIBUTES LsaCommandPortObjA;
|
|
SECURITY_QUALITY_OF_SERVICE DynamicQos;
|
|
|
|
HANDLE Thread;
|
|
DWORD Ignore;
|
|
|
|
//
|
|
// Create the Lsa Command LPC Port. This port will receive
|
|
// commands from the Reference Monitor.
|
|
//
|
|
|
|
RtlInitUnicodeString( &LsaCommandPortName, L"\\SeLsaCommandPort" );
|
|
|
|
//
|
|
// Setup to create LSA Command Port
|
|
//
|
|
|
|
InitializeObjectAttributes(
|
|
&LsaCommandPortObjA,
|
|
&LsaCommandPortName,
|
|
0,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
Status = NtCreatePort(
|
|
&LsapState.LsaCommandPortHandle,
|
|
&LsaCommandPortObjA,
|
|
0,
|
|
sizeof(LSA_COMMAND_MESSAGE),
|
|
sizeof(LSA_COMMAND_MESSAGE) * 32
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
KdPrint(("LsapRmInitializeServer - Port Create failed 0x%lx\n",Status));
|
|
goto InitServerError;
|
|
}
|
|
|
|
//
|
|
// Open the LSA Init Event created by the Reference Monitor
|
|
//
|
|
|
|
RtlInitUnicodeString( &LsaInitEventName, L"\\SeLsaInitEvent" );
|
|
|
|
InitializeObjectAttributes(
|
|
&LsaInitEventObjA,
|
|
&LsaInitEventName,
|
|
0,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
Status = NtOpenEvent(
|
|
&LsaInitEventHandle,
|
|
EVENT_MODIFY_STATE,
|
|
&LsaInitEventObjA
|
|
);
|
|
|
|
//
|
|
// If the LSA Init event could not be opened, the LSA cannot
|
|
// synchronize with the Reference Monitor so neither component will
|
|
// function correctly.
|
|
//
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
KdPrint(("LsapRmInitializeServer - Lsa Init Event Open failed 0x%lx\n",Status));
|
|
goto InitServerError;
|
|
}
|
|
|
|
//
|
|
// Signal the LSA Init Event. If the signalling fails, the LSA
|
|
// is not able to synchronize properly with the Reference Monitor.
|
|
// This is a serious error which prevents both components from
|
|
// functioning correctly.
|
|
//
|
|
|
|
Status = NtSetEvent( LsaInitEventHandle, NULL );
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
KdPrint(("LsapRmInitializeServer - Init Event Open failed 0x%lx\n",Status));
|
|
goto InitServerError;
|
|
}
|
|
|
|
//
|
|
// Set up the security quality of service parameters to use over the
|
|
// port. Use the most efficient (least overhead) - which is dynamic
|
|
// rather than static tracking.
|
|
//
|
|
|
|
DynamicQos.ImpersonationLevel = SecurityImpersonation;
|
|
DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
|
|
DynamicQos.EffectiveOnly = TRUE;
|
|
|
|
//
|
|
// Connect to the Reference Monitor Command Port. This port
|
|
// is used to send commands from the LSA to the Reference Monitor.
|
|
//
|
|
|
|
RtlInitUnicodeString( &RmCommandPortName, L"\\SeRmCommandPort" );
|
|
|
|
Status = NtConnectPort(
|
|
&LsapState.RmCommandPortHandle,
|
|
&RmCommandPortName,
|
|
&DynamicQos,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
KdPrint(("LsapRmInitializeServer - Connect to Rm Command Port failed 0x%lx\n",Status));
|
|
goto InitServerError;
|
|
}
|
|
|
|
//
|
|
// Listen for the Reference Monitor To Connect to the LSA
|
|
// Command Port.
|
|
//
|
|
|
|
ConnectionRequest.u1.s1.TotalLength = sizeof(ConnectionRequest);
|
|
ConnectionRequest.u1.s1.DataLength = (CSHORT)0;
|
|
Status = NtListenPort(
|
|
LsapState.LsaCommandPortHandle,
|
|
&ConnectionRequest
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
KdPrint(("LsapRmInitializeServer - Port Listen failed 0x%lx\n",Status));
|
|
goto InitServerError;
|
|
}
|
|
|
|
//
|
|
// Accept the connection to the Lsa Command Port.
|
|
//
|
|
|
|
ClientView.Length = sizeof(ClientView);
|
|
Status = NtAcceptConnectPort(
|
|
&LsapState.LsaCommandPortHandle,
|
|
NULL,
|
|
&ConnectionRequest,
|
|
TRUE,
|
|
NULL,
|
|
&ClientView
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
KdPrint(("LsapRmInitializeServer - Port Accept Connect failed 0x%lx\n",Status));
|
|
|
|
goto InitServerError;
|
|
}
|
|
|
|
//
|
|
// Complete the connection
|
|
//
|
|
|
|
Status = NtCompleteConnectPort(LsapState.LsaCommandPortHandle);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
KdPrint(("LsapRmInitializeServer - Port Complete Connect failed 0x%lx\n",Status));
|
|
goto InitServerError;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Create the LSA Reference Monitor Server Thread
|
|
//
|
|
|
|
Thread = CreateThread(
|
|
NULL,
|
|
0L,
|
|
(LPTHREAD_START_ROUTINE) LsapRmServerThread,
|
|
(LPVOID)0,
|
|
0L,
|
|
&Ignore
|
|
);
|
|
|
|
if (Thread == NULL) {
|
|
|
|
KdPrint(("LsapRmInitializeServer - Create Thread failed 0x%lx\n",Status));
|
|
} else {
|
|
CloseHandle(Thread);
|
|
Thread = NULL;
|
|
}
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
goto InitServerCleanup;
|
|
|
|
InitServerError:
|
|
|
|
//
|
|
// Perform cleanup needed only in error cases here.
|
|
//
|
|
|
|
InitServerCleanup:
|
|
|
|
//
|
|
// Perform cleanup needed in all cases here
|
|
//
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
LsapCallRm(
|
|
IN RM_COMMAND_NUMBER CommandNumber,
|
|
IN OPTIONAL PVOID CommandParams,
|
|
IN ULONG CommandParamsLength,
|
|
OUT OPTIONAL PVOID ReplyBuffer,
|
|
IN ULONG ReplyBufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function sends a command to the Reference Monitor from the LSA via
|
|
the LSA Command LPC Port. This function must only be called from within
|
|
Lsa code. If the command has parameters, they will be copied directly
|
|
into a message structure and sent via LPC, therefore, the supplied
|
|
parameters may not contain any absolute pointers. A caller must remove
|
|
pointers by "marshalling" them into the buffer CommandParams.
|
|
|
|
To implement a new RM command, do the following:
|
|
================================================
|
|
|
|
(1) Provide in the executive an RM worker routine called
|
|
SepRm<command>Wrkr to service the command. See file
|
|
ntos\se\rmmain.c for examples. NOTE: If the command takes
|
|
parameters, they must not contain any absolute pointers (addresses).
|
|
|
|
(2) In file private\inc\ntrmlsa.h, append the name of the new command to
|
|
the enumerated type RM_COMMAND_NUMBER. Change the #define for
|
|
RmMaximumCommand to reference the new command.
|
|
|
|
(3) Add the SepRm<command>Wrkr to the command dispatch table structure
|
|
SepRmCommandDispatch[] in file ntos\se\rmmain.c.
|
|
|
|
(4) Add function prototypes to lsap.h and sep.h.
|
|
|
|
Arguments:
|
|
|
|
CommandNumber - Specifies the command
|
|
|
|
CommandParams - Optional command-dependent parameters. The parameters
|
|
must be in marshalled format, that is, there must not be any
|
|
absolute address pointers in the buffer.
|
|
|
|
CommandParamsLength - Length in bytes of command parameters. Must be 0
|
|
if no command parameters supplied.
|
|
|
|
ReplyBuffer - Reply Buffer in which data (if any) from the command will
|
|
be returned.
|
|
|
|
ReplyBufferLength - Length of ReplyBuffer in bytes.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - Result Code. This is either a result code returned from
|
|
trying to send the command/receive the reply, or a status code
|
|
from the command itself.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
RM_COMMAND_MESSAGE CommandMessage;
|
|
RM_REPLY_MESSAGE ReplyMessage;
|
|
|
|
//
|
|
// Assert that the Command Number is valid.
|
|
//
|
|
|
|
ASSERT( CommandNumber >= RmMinimumCommand &&
|
|
CommandNumber <= RmMaximumCommand );
|
|
|
|
//
|
|
// If command parameters are supplied, assert that the length of the
|
|
// command parameters is positive and not too large. If no command
|
|
// parameters are supplied, assert that the length field is 0.
|
|
//
|
|
|
|
ASSERT( ( ARGUMENT_PRESENT( CommandParams ) &&
|
|
CommandParamsLength > 0 &&
|
|
CommandParamsLength <= RM_MAXIMUM_COMMAND_PARAM_SIZE ) ||
|
|
|
|
( !ARGUMENT_PRESENT( CommandParams ) &&
|
|
CommandParamsLength == 0 )
|
|
);
|
|
|
|
//
|
|
// If a Reply Buffer is provided, assert that its length is > 0
|
|
// and not too large.
|
|
//
|
|
|
|
ASSERT( ( ARGUMENT_PRESENT( ReplyBuffer ) &&
|
|
ReplyBufferLength > 0 &&
|
|
ReplyBufferLength <= LSA_MAXIMUM_REPLY_BUFFER_SIZE ) ||
|
|
|
|
( !ARGUMENT_PRESENT( ReplyBuffer ) &&
|
|
ReplyBufferLength == 0 )
|
|
);
|
|
|
|
//
|
|
// Construct a message for LPC. First, fill in the message header
|
|
// fields for LPC, specifying the message type and data sizes for
|
|
// the outgoing CommandMessage and the incoming ReplyMessage.
|
|
//
|
|
|
|
CommandMessage.MessageHeader.u2.ZeroInit = 0;
|
|
CommandMessage.MessageHeader.u1.s1.TotalLength =
|
|
((CSHORT) RM_COMMAND_MESSAGE_HEADER_SIZE +
|
|
(CSHORT) CommandParamsLength);
|
|
CommandMessage.MessageHeader.u1.s1.DataLength =
|
|
CommandMessage.MessageHeader.u1.s1.TotalLength -
|
|
(CSHORT) sizeof(PORT_MESSAGE);
|
|
|
|
ReplyMessage.MessageHeader.u2.ZeroInit = 0;
|
|
ReplyMessage.MessageHeader.u1.s1.DataLength = (CSHORT) ReplyBufferLength;
|
|
ReplyMessage.MessageHeader.u1.s1.TotalLength =
|
|
ReplyMessage.MessageHeader.u1.s1.DataLength +
|
|
(CSHORT) sizeof(PORT_MESSAGE);
|
|
|
|
//
|
|
// Next, fill in the header info needed by the Reference Monitor.
|
|
//
|
|
|
|
CommandMessage.CommandNumber = CommandNumber;
|
|
ReplyMessage.ReturnedStatus = STATUS_SUCCESS;
|
|
|
|
//
|
|
// Finally, copy the command parameters (if any) into the message buffer.
|
|
//
|
|
|
|
if (CommandParamsLength > 0) {
|
|
|
|
RtlCopyMemory(CommandMessage.CommandParams,CommandParams,CommandParamsLength);
|
|
}
|
|
|
|
// Send Message to the RM via the RM Command Server LPC Port
|
|
//
|
|
|
|
Status = NtRequestWaitReplyPort(
|
|
LsapState.RmCommandPortHandle,
|
|
(PPORT_MESSAGE) &CommandMessage,
|
|
(PPORT_MESSAGE) &ReplyMessage
|
|
);
|
|
|
|
//
|
|
// If the command was successful, copy the data back to the output
|
|
// buffer.
|
|
//
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
//
|
|
// Move output from command (if any) to buffer. Note that this
|
|
// is done even if the command returns status, because some status
|
|
// values are not errors.
|
|
//
|
|
|
|
if (ARGUMENT_PRESENT(ReplyBuffer)) {
|
|
|
|
RtlCopyMemory(
|
|
ReplyBuffer,
|
|
ReplyMessage.ReplyBuffer,
|
|
ReplyBufferLength
|
|
);
|
|
|
|
}
|
|
|
|
//
|
|
// Return status from command.
|
|
//
|
|
|
|
Status = ReplyMessage.ReturnedStatus;
|
|
|
|
} else {
|
|
|
|
KdPrint(("Security: Command sent from LSA to RM returned 0x%lx\n",Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
LsapComponentTestWrkr(
|
|
IN PLSA_COMMAND_MESSAGE CommandMessage,
|
|
OUT PLSA_REPLY_MESSAGE ReplyMessage
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function processes the Component Test LSA Rm Server command.
|
|
This is a temporary command that can be used to verifiey that the link
|
|
from RM to LSA is working.
|
|
|
|
Arguments:
|
|
|
|
CommandMessage - Pointer to structure containing LSA command message
|
|
information consisting of an LPC PORT_MESSAGE structure followed
|
|
by the command number (LsapComponentTestCommand). This command
|
|
currently has one parameter, the fixed value 0x1234567.
|
|
|
|
ReplyMessage - Pointer to structure containing LSA reply message
|
|
information consisting of an LPC PORT_MESSAGE structure followed
|
|
by the command ReturnedStatus field in which a status code from the
|
|
command will be returned.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - The test call has completed successfully.
|
|
|
|
STATUS_INVALID_PARAMETER - The argument value received was not the
|
|
expected argument value.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
//
|
|
// Strict check that command is correct.
|
|
//
|
|
|
|
ASSERT( CommandMessage->CommandNumber == LsapComponentTestCommand );
|
|
|
|
KdPrint(("Security: LSA Component Test Command Received\n"));
|
|
|
|
//
|
|
// Verify that the parameter value passed is as expected.
|
|
//
|
|
|
|
if (*((ULONG *) CommandMessage->CommandParams) !=
|
|
LSA_CT_COMMAND_PARAM_VALUE ) {
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
UNREFERENCED_PARAMETER(ReplyMessage); // Intentionally not referenced
|
|
return(Status);
|
|
}
|