[LSALIB/LSASRV]

Make the call sequence LsaRegisterLogonProcess, LsaLookupAuthenticationPackage, LsaDeregisterLogonProcess work without failures or loss of connection. WIP.

svn path=/trunk/; revision=58303
This commit is contained in:
Eric Kohl 2013-02-09 22:56:26 +00:00
parent 7121ae2525
commit 9cdf574f39
3 changed files with 232 additions and 95 deletions

View file

@ -20,16 +20,26 @@ static HANDLE AuthPortHandle = NULL;
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
static NTSTATUS
LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg)
{
RequestMsg->LookupAuthenticationPackage.Reply.Package = 0x12345678;
return STATUS_SUCCESS;
}
NTSTATUS WINAPI NTSTATUS WINAPI
AuthPortThreadRoutine(PVOID Param) AuthPortThreadRoutine(PVOID Param)
{ {
LSASS_REQUEST Request; PLSA_API_MSG ReplyMsg = NULL;
PPORT_MESSAGE Reply = NULL; LSA_API_MSG RequestMsg;
NTSTATUS Status; NTSTATUS Status;
HANDLE ConnectionHandle = NULL; HANDLE ConnectionHandle = NULL;
PVOID Context = NULL; PVOID Context = NULL;
BOOLEAN Accept; BOOLEAN Accept;
REMOTE_PORT_VIEW RemotePortView;
TRACE("AuthPortThreadRoutine() called\n"); TRACE("AuthPortThreadRoutine() called\n");
@ -39,8 +49,8 @@ AuthPortThreadRoutine(PVOID Param)
{ {
Status = NtReplyWaitReceivePort(AuthPortHandle, Status = NtReplyWaitReceivePort(AuthPortHandle,
0, 0,
Reply, &ReplyMsg->h,
&Request.Header); &RequestMsg.h);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
TRACE("NtReplyWaitReceivePort() failed (Status %lx)\n", Status); TRACE("NtReplyWaitReceivePort() failed (Status %lx)\n", Status);
@ -49,42 +59,62 @@ AuthPortThreadRoutine(PVOID Param)
TRACE("Received message\n"); TRACE("Received message\n");
if (Request.Header.u2.s2.Type == LPC_CONNECTION_REQUEST) switch (RequestMsg.h.u2.s2.Type)
{ {
TRACE("Port connection request\n"); case LPC_CONNECTION_REQUEST:
TRACE("Port connection request\n");
Accept = TRUE; RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
NtAcceptConnectPort(&ConnectionHandle,
&Context,
&Request.Header,
Accept,
NULL,
NULL);
Accept = TRUE;
Status = NtAcceptConnectPort(&ConnectionHandle,
&Context,
&RequestMsg.h,
Accept,
NULL,
&RemotePortView);
if (!NT_SUCCESS(Status))
{
ERR("NtAcceptConnectPort failed (Status 0x%lx)\n", Status);
return Status;
}
NtCompleteConnectPort(ConnectionHandle); Status = NtCompleteConnectPort(ConnectionHandle);
if (!NT_SUCCESS(Status))
{
ERR("NtCompleteConnectPort failed (Status 0x%lx)\n", Status);
return Status;
}
} ReplyMsg = NULL;
else if (Request.Header.u2.s2.Type == LPC_PORT_CLOSED || break;
Request.Header.u2.s2.Type == LPC_CLIENT_DIED)
{
TRACE("Port closed or client died request\n");
// return STATUS_UNSUCCESSFUL; case LPC_PORT_CLOSED:
} TRACE("Port closed\n");
else if (Request.Header.u2.s2.Type == LPC_REQUEST) ReplyMsg = NULL;
{ break;
TRACE("Received request (Type: %lu)\n", Request.Type);
} case LPC_CLIENT_DIED:
else if (Request.Header.u2.s2.Type == LPC_DATAGRAM) TRACE("Client died\n");
{ ReplyMsg = NULL;
TRACE("Received datagram\n"); break;
default:
TRACE("Received request (ApiNumber: %lu)\n", RequestMsg.ApiNumber);
if (RequestMsg.ApiNumber == LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE)
{
RequestMsg.Status = LsapLookupAuthenticationPackage(&RequestMsg);
}
else
RequestMsg.Status = STATUS_SUCCESS;
ReplyMsg = &RequestMsg;
break;
} }
} }
return Status; return STATUS_SUCCESS;
} }
@ -107,9 +137,9 @@ StartAuthenticationPort(VOID)
Status = NtCreatePort(&AuthPortHandle, Status = NtCreatePort(&AuthPortHandle,
&ObjectAttributes, &ObjectAttributes,
0, sizeof(LSA_CONNECTION_INFO),
0x100, sizeof(LSA_API_MSG),
0x2000); sizeof(LSA_API_MSG) * 32);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
TRACE("NtCreatePort() failed (Status %lx)\n", Status); TRACE("NtCreatePort() failed (Status %lx)\n", Status);

View file

@ -14,14 +14,19 @@
#include <ntsecapi.h> #include <ntsecapi.h>
#define LSASS_MAX_LOGON_PROCESS_NAME_LENGTH 127 #define LSASS_MAX_LOGON_PROCESS_NAME_LENGTH 127
#define LSASS_MAX_PACKAGE_NAME_LENGTH 127
#define LSASS_REQUEST_REGISTER_LOGON_PROCESS (1) typedef enum _LSA_API_NUMBER
#define LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE (2) {
#define LSASS_REQUEST_DEREGISTER_LOGON_PROCESS (3) LSASS_REQUEST_REGISTER_LOGON_PROCESS,
#define LSASS_REQUEST_LOGON_USER (4) LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE,
#define LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE (5) LSASS_REQUEST_DEREGISTER_LOGON_PROCESS,
#define LSASS_REQUEST_MAXIMUM (6) LSASS_REQUEST_LOGON_USER,
LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE,
LSASS_REQUEST_MAXIMUM
} LSA_API_NUMBER, *PLSA_API_NUMBER;
#if 0
typedef struct _LSASS_LOOKUP_AUTHENTICATION_PACKAGE_REQUEST typedef struct _LSASS_LOOKUP_AUTHENTICATION_PACKAGE_REQUEST
{ {
ULONG PackageNameLength; ULONG PackageNameLength;
@ -46,6 +51,7 @@ typedef struct _LSASS_DEREGISTER_LOGON_PROCESS_REPLY
ULONG Dummy; ULONG Dummy;
} LSASS_DEREGISTER_LOGON_PROCESS_REPLY, } LSASS_DEREGISTER_LOGON_PROCESS_REPLY,
*PLSASS_DEREGISTER_LOGON_PROCESS_REPLY; *PLSASS_DEREGISTER_LOGON_PROCESS_REPLY;
#endif
typedef struct _LSASS_CALL_AUTHENTICATION_PACKAGE_REQUEST typedef struct _LSASS_CALL_AUTHENTICATION_PACKAGE_REQUEST
{ {
@ -87,6 +93,7 @@ typedef struct _LSASS_LOGON_USER_REPLY
UCHAR Data[1]; UCHAR Data[1];
} LSASS_LOGON_USER_REPLY, *PLSASS_LOGON_USER_REPLY; } LSASS_LOGON_USER_REPLY, *PLSASS_LOGON_USER_REPLY;
#if 0
typedef struct _LSASS_REGISTER_LOGON_PROCESS_REQUEST typedef struct _LSASS_REGISTER_LOGON_PROCESS_REQUEST
{ {
ULONG Length; ULONG Length;
@ -97,17 +104,17 @@ typedef struct _LSASS_REGISTER_LOGON_PROCESS_REPLY
{ {
LSA_OPERATIONAL_MODE OperationalMode; LSA_OPERATIONAL_MODE OperationalMode;
} LSASS_REGISTER_LOGON_PROCESS_REPLY, *PLSASS_REGISTER_LOGON_PROCESS_REPLY; } LSASS_REGISTER_LOGON_PROCESS_REPLY, *PLSASS_REGISTER_LOGON_PROCESS_REPLY;
#endif
typedef struct _LSA_CONNECTION_INFO
typedef struct _LSASS_CONNECT_DATA
{ {
NTSTATUS Status; NTSTATUS Status;
LSA_OPERATIONAL_MODE OperationalMode; LSA_OPERATIONAL_MODE OperationalMode;
ULONG Length; ULONG Length;
CHAR LogonProcessNameBuffer[LSASS_MAX_LOGON_PROCESS_NAME_LENGTH + 1]; CHAR LogonProcessNameBuffer[LSASS_MAX_LOGON_PROCESS_NAME_LENGTH + 1];
} LSASS_CONNECT_DATA, *PLSASS_CONNECT_DATA; } LSA_CONNECTION_INFO, *PLSA_CONNECTION_INFO;
#if 0
typedef union _LSASS_REQUEST typedef union _LSASS_REQUEST
{ {
PORT_MESSAGE Header; PORT_MESSAGE Header;
@ -141,5 +148,77 @@ typedef struct _LSASS_REPLY
LookupAuthenticationPackageReply; LookupAuthenticationPackageReply;
} d; } d;
} LSASS_REPLY, *PLSASS_REPLY; } LSASS_REPLY, *PLSASS_REPLY;
#endif
typedef struct _LSA_REGISTER_LOGON_PROCESS_MSG
{
union
{
struct
{
ULONG Length;
CHAR LogonProcessNameBuffer[LSASS_MAX_LOGON_PROCESS_NAME_LENGTH + 1];
} Request;
struct
{
LSA_OPERATIONAL_MODE OperationalMode;
} Reply;
};
} LSA_REGISTER_LOGON_PROCESS_MSG, *PLSA_REGISTER_LOGON_PROCESS_MSG;
typedef struct _LSA_DEREGISTER_LOGON_PROCESS_MSG
{
union
{
struct
{
ULONG Dummy;
} Request;
struct
{
ULONG Dummy;
} Reply;
};
} LSA_DEREGISTER_LOGON_PROCESS_MSG, *PLSA_DEREGISTER_LOGON_PROCESS_MSG;
typedef struct _LSA_LOOKUP_AUTHENTICATION_PACKAGE_MSG
{
union
{
struct
{
ULONG PackageNameLength;
CHAR PackageName[LSASS_MAX_PACKAGE_NAME_LENGTH + 1];
} Request;
struct
{
ULONG Package;
} Reply;
};
} LSA_LOOKUP_AUTHENTICATION_PACKAGE_MSG, *PLSA_LOOKUP_AUTHENTICATION_PACKAGE_MSG;
typedef struct _LSA_API_MSG
{
PORT_MESSAGE h;
struct
{
LSA_API_NUMBER ApiNumber;
NTSTATUS Status;
union
{
LSA_REGISTER_LOGON_PROCESS_MSG RegisterLogonProcess;
// LSA_LOGON_USER_MSG LogonUser;
// LSA_CALL_AUTHENTICATION_PACKAGE_MSG CallAuthenticationPackage;
LSA_DEREGISTER_LOGON_PROCESS_MSG DeregisterLogonProcess;
LSA_LOOKUP_AUTHENTICATION_PACKAGE_MSG LookupAuthenticationPackage;
};
};
} LSA_API_MSG, *PLSA_API_MSG;
#define LSA_PORT_DATA_SIZE(c) (sizeof(ULONG)+sizeof(NTSTATUS)+sizeof(c))
#define LSA_PORT_MESSAGE_SIZE (sizeof(LSA_API_MSG))
#endif /* __INCLUDE_LSASS_LSASS_H */ #endif /* __INCLUDE_LSASS_LSASS_H */

View file

@ -12,6 +12,7 @@
#include <ndk/lpctypes.h> #include <ndk/lpctypes.h>
#include <ndk/lpcfuncs.h> #include <ndk/lpcfuncs.h>
#include <ndk/rtlfuncs.h> #include <ndk/rtlfuncs.h>
#include <ndk/obfuncs.h>
#include <psdk/ntsecapi.h> #include <psdk/ntsecapi.h>
#include <lsass/lsass.h> #include <lsass/lsass.h>
@ -30,26 +31,35 @@ extern HANDLE Secur32Heap;
NTSTATUS WINAPI NTSTATUS WINAPI
LsaDeregisterLogonProcess(HANDLE LsaHandle) LsaDeregisterLogonProcess(HANDLE LsaHandle)
{ {
LSASS_REQUEST Request; LSA_API_MSG ApiMessage;
LSASS_REPLY Reply;
NTSTATUS Status; NTSTATUS Status;
Request.Header.u1.s1.DataLength = 0; DPRINT1("LsaDeregisterLogonProcess()\n");
Request.Header.u1.s1.TotalLength = sizeof(LSASS_REQUEST);
Request.Type = LSASS_REQUEST_DEREGISTER_LOGON_PROCESS; ApiMessage.ApiNumber = LSASS_REQUEST_DEREGISTER_LOGON_PROCESS;
ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.DeregisterLogonProcess.Request);
ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
ApiMessage.h.u2.ZeroInit = 0;
Status = ZwRequestWaitReplyPort(LsaHandle, Status = ZwRequestWaitReplyPort(LsaHandle,
&Request.Header, (PPORT_MESSAGE)&ApiMessage,
&Reply.Header); (PPORT_MESSAGE)&ApiMessage);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("ZwRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
return Status; return Status;
} }
if (!NT_SUCCESS(Reply.Status)) if (!NT_SUCCESS(ApiMessage.Status))
{ {
return Reply.Status; DPRINT1("ZwRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
return ApiMessage.Status;
} }
NtClose(LsaHandle);
DPRINT1("LsaDeregisterLogonProcess() done (Status 0x%08lx)\n", Status);
return Status; return Status;
} }
@ -77,6 +87,7 @@ LsaCallAuthenticationPackage(HANDLE LsaHandle,
PULONG ReturnBufferLength, PULONG ReturnBufferLength,
PNTSTATUS ProtocolStatus) PNTSTATUS ProtocolStatus)
{ {
#if 0
PLSASS_REQUEST Request; PLSASS_REQUEST Request;
PLSASS_REPLY Reply; PLSASS_REPLY Reply;
LSASS_REQUEST RawRequest; LSASS_REQUEST RawRequest;
@ -123,6 +134,9 @@ LsaCallAuthenticationPackage(HANDLE LsaHandle,
*ReturnBufferLength); *ReturnBufferLength);
return Status; return Status;
#endif
return 0;
} }
@ -144,34 +158,42 @@ LsaLookupAuthenticationPackage(HANDLE LsaHandle,
PLSA_STRING PackageName, PLSA_STRING PackageName,
PULONG AuthenticationPackage) PULONG AuthenticationPackage)
{ {
LSA_API_MSG ApiMessage;
NTSTATUS Status; NTSTATUS Status;
PLSASS_REQUEST Request;
LSASS_REQUEST RawRequest;
LSASS_REPLY Reply;
Request = (PLSASS_REQUEST)&RawRequest; /* Check the package name length */
Request->Header.u1.s1.DataLength = sizeof(LSASS_REQUEST) + PackageName->Length - if (PackageName->Length > LSASS_MAX_PACKAGE_NAME_LENGTH)
sizeof(PORT_MESSAGE); {
Request->Header.u1.s1.TotalLength = Request->Header.u1.s1.DataLength + return STATUS_NAME_TOO_LONG;
sizeof(PORT_MESSAGE); }
Request->Type = LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE;
ApiMessage.ApiNumber = LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE;
ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.LookupAuthenticationPackage.Request);
ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
ApiMessage.h.u2.ZeroInit = 0;
ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength = PackageName->Length;
strncpy(ApiMessage.LookupAuthenticationPackage.Request.PackageName,
PackageName->Buffer,
ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength);
ApiMessage.LookupAuthenticationPackage.Request.PackageName[ApiMessage.LookupAuthenticationPackage.Request.PackageNameLength] = '\0';
Status = ZwRequestWaitReplyPort(LsaHandle, Status = ZwRequestWaitReplyPort(LsaHandle,
&Request->Header, (PPORT_MESSAGE)&ApiMessage,
&Reply.Header); (PPORT_MESSAGE)&ApiMessage);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; return Status;
} }
if (!NT_SUCCESS(Reply.Status)) if (!NT_SUCCESS(ApiMessage.Status))
{ {
return Reply.Status; return ApiMessage.Status;
} }
*AuthenticationPackage = Reply.d.LookupAuthenticationPackageReply.Package; *AuthenticationPackage = ApiMessage.LookupAuthenticationPackage.Reply.Package;
return Reply.Status; return Status;
} }
@ -194,6 +216,7 @@ LsaLogonUser(HANDLE LsaHandle,
PQUOTA_LIMITS Quotas, PQUOTA_LIMITS Quotas,
PNTSTATUS SubStatus) PNTSTATUS SubStatus)
{ {
#if 0
ULONG RequestLength; ULONG RequestLength;
ULONG CurrentLength; ULONG CurrentLength;
PLSASS_REQUEST Request; PLSASS_REQUEST Request;
@ -276,6 +299,8 @@ LsaLogonUser(HANDLE LsaHandle,
sizeof(Reply->d.LogonUserReply.Quotas)); sizeof(Reply->d.LogonUserReply.Quotas));
return Status; return Status;
#endif
return 0;
} }
@ -289,33 +314,35 @@ LsaRegisterLogonProcess(PLSA_STRING LsaLogonProcessName,
{ {
UNICODE_STRING PortName; // = RTL_CONSTANT_STRING(L"\\LsaAuthenticationPort"); UNICODE_STRING PortName; // = RTL_CONSTANT_STRING(L"\\LsaAuthenticationPort");
SECURITY_QUALITY_OF_SERVICE SecurityQos; SECURITY_QUALITY_OF_SERVICE SecurityQos;
ULONG ConnectInfoLength; LSA_CONNECTION_INFO ConnectInfo;
ULONG ConnectInfoLength = sizeof(ConnectInfo);
LSA_API_MSG ApiMessage;
HANDLE PortHandle = NULL;
NTSTATUS Status; NTSTATUS Status;
LSASS_CONNECT_DATA ConnectInfo;
// LSASS_REQUEST Request; DPRINT1("LsaRegisterLogonProcess()\n");
// LSASS_REPLY Reply;
/* Check the logon process name length */ /* Check the logon process name length */
if (LsaLogonProcessName->Length > LSASS_MAX_LOGON_PROCESS_NAME_LENGTH) if (LsaLogonProcessName->Length > LSASS_MAX_LOGON_PROCESS_NAME_LENGTH)
return STATUS_NAME_TOO_LONG; return STATUS_NAME_TOO_LONG;
*Handle = NULL;
RtlInitUnicodeString(&PortName, RtlInitUnicodeString(&PortName,
L"\\LsaAuthenticationPort"); L"\\LsaAuthenticationPort");
SecurityQos.Length = sizeof (SecurityQos); SecurityQos.Length = sizeof(SecurityQos);
SecurityQos.ImpersonationLevel = SecurityIdentification; SecurityQos.ImpersonationLevel = SecurityIdentification;
SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
SecurityQos.EffectiveOnly = TRUE; SecurityQos.EffectiveOnly = TRUE;
ConnectInfoLength = sizeof(LSASS_CONNECT_DATA);
strncpy(ConnectInfo.LogonProcessNameBuffer, strncpy(ConnectInfo.LogonProcessNameBuffer,
LsaLogonProcessName->Buffer, LsaLogonProcessName->Buffer,
LsaLogonProcessName->Length); LsaLogonProcessName->Length);
ConnectInfo.Length = LsaLogonProcessName->Length; ConnectInfo.Length = LsaLogonProcessName->Length;
ConnectInfo.LogonProcessNameBuffer[ConnectInfo.Length] = '\0'; ConnectInfo.LogonProcessNameBuffer[ConnectInfo.Length] = '\0';
Status = ZwConnectPort(Handle, Status = ZwConnectPort(&PortHandle,
&PortName, &PortName,
&SecurityQos, &SecurityQos,
NULL, NULL,
@ -325,42 +352,43 @@ LsaRegisterLogonProcess(PLSA_STRING LsaLogonProcessName,
&ConnectInfoLength); &ConnectInfoLength);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("ZwConnectPort failed (Status 0x%08lx)\n", Status);
return Status; return Status;
} }
return Status; ApiMessage.ApiNumber = LSASS_REQUEST_REGISTER_LOGON_PROCESS;
#if 0 ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.RegisterLogonProcess.Request);
Request.Type = LSASS_REQUEST_REGISTER_LOGON_PROCESS; ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
Request.Header.u1.s1.DataLength = sizeof(LSASS_REQUEST) - ApiMessage.h.u2.ZeroInit = 0;
sizeof(PORT_MESSAGE);
Request.Header.u1.s1.TotalLength = sizeof(LSASS_REQUEST);
Request.d.RegisterLogonProcessRequest.Length = LsaLogonProcessName->Length; ApiMessage.RegisterLogonProcess.Request.Length = LsaLogonProcessName->Length;
memcpy(Request.d.RegisterLogonProcessRequest.LogonProcessNameBuffer, memcpy(ApiMessage.RegisterLogonProcess.Request.LogonProcessNameBuffer,
LsaLogonProcessName->Buffer, LsaLogonProcessName->Buffer,
Request.d.RegisterLogonProcessRequest.Length); ApiMessage.RegisterLogonProcess.Request.Length);
Status = ZwRequestWaitReplyPort(*Handle, Status = ZwRequestWaitReplyPort(PortHandle,
&Request.Header, (PPORT_MESSAGE)&ApiMessage,
&Reply.Header); (PPORT_MESSAGE)&ApiMessage);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// NtClose(*Handle); DPRINT1("ZwRequestWaitReplyPort failed (Status 0x%08lx)\n", Status);
// *Handle = NULL; NtClose(PortHandle);
return Status; return Status;
} }
if (!NT_SUCCESS(Reply.Status)) if (!NT_SUCCESS(ApiMessage.Status))
{ {
// NtClose(*Handle); DPRINT1("ZwRequestWaitReplyPort failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
// *Handle = NULL; NtClose(PortHandle);
return Status; return ApiMessage.Status;
} }
*OperationalMode = Reply.d.RegisterLogonProcessReply.OperationalMode; *Handle = PortHandle;
*OperationalMode = ApiMessage.RegisterLogonProcess.Reply.OperationalMode;
return Reply.Status; DPRINT1("LsaRegisterLogonProcess() done (Status 0x%08lx)\n", Status);
#endif
return Status;
} }