[LSASRV][SECUR32]

- Implement a first version of LsaGetLogonSessionData.
- Add a simple way to disable LsaEnumerateLogonSessions and LsaGetLogonSessionData in case they cause problems.

svn path=/trunk/; revision=64384
This commit is contained in:
Eric Kohl 2014-09-28 23:02:09 +00:00
parent 90d370dbb6
commit 104e42625b
5 changed files with 231 additions and 9 deletions

View file

@ -237,6 +237,11 @@ AuthPortThreadRoutine(PVOID Param)
ReplyMsg = &RequestMsg;
break;
case LSASS_REQUEST_GET_LOGON_SESSION_DATA:
RequestMsg.Status = LsapGetLogonSessionData(&RequestMsg);
ReplyMsg = &RequestMsg;
break;
default:
RequestMsg.Status = STATUS_INVALID_SYSTEM_SERVICE;
ReplyMsg = &RequestMsg;

View file

@ -407,6 +407,9 @@ LsapSetLogonSessionData(IN PLUID LogonId);
NTSTATUS
LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg);
NTSTATUS
LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg);
/* utils.c */
INT
LsapLoadString(HINSTANCE hInstance,

View file

@ -12,6 +12,16 @@ typedef struct _LSAP_LOGON_SESSION
{
LIST_ENTRY Entry;
LUID LogonId;
ULONG LogonType;
ULONG Session;
LARGE_INTEGER LogonTime;
PSID Sid;
UNICODE_STRING UserName;
UNICODE_STRING LogonDomain;
UNICODE_STRING AuthenticationPackage;
UNICODE_STRING LogonServer;
UNICODE_STRING DnsDomainName;
UNICODE_STRING Upn;
} LSAP_LOGON_SESSION, *PLSAP_LOGON_SESSION;
@ -58,7 +68,7 @@ LsapSetLogonSessionData(IN PLUID LogonId)
{
PLSAP_LOGON_SESSION Session;
TRACE("()\n");
TRACE("LsapSetLogonSessionData()\n");
Session = LsapGetLogonSession(LogonId);
if (Session == NULL)
@ -92,7 +102,7 @@ LsapCreateLogonSession(IN PLUID LogonId)
RtlCopyLuid(&Session->LogonId, LogonId);
/* Insert the new session into the session list */
InsertTailList(&SessionListHead, &Session->Entry);
InsertHeadList(&SessionListHead, &Session->Entry);
SessionCount++;
return STATUS_SUCCESS;
@ -116,6 +126,28 @@ LsapDeleteLogonSession(IN PLUID LogonId)
RemoveEntryList(&Session->Entry);
SessionCount--;
/* Free the session data */
if (Session->Sid != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Session->Sid);
if (Session->UserName.Buffer != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Session->UserName.Buffer);
if (Session->LogonDomain.Buffer != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Session->LogonDomain.Buffer);
if (Session->AuthenticationPackage.Buffer != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Session->AuthenticationPackage.Buffer);
if (Session->LogonServer.Buffer != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Session->LogonServer.Buffer);
if (Session->DnsDomainName.Buffer != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Session->DnsDomainName.Buffer);
if (Session->Upn.Buffer != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, Session->Upn.Buffer);
/* Free the session entry */
RtlFreeHeap(RtlGetProcessHeap(), 0, Session);
@ -135,7 +167,7 @@ LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg)
PVOID ClientBaseAddress = NULL;
NTSTATUS Status;
TRACE("LsapEnumLogonSessions()\n");
TRACE("LsapEnumLogonSessions(%p)\n", RequestMsg);
Length = SessionCount * sizeof(LUID);
SessionList = RtlAllocateHeap(RtlGetProcessHeap(),
@ -166,7 +198,7 @@ LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg)
NULL);
Status = NtOpenProcess(&ProcessHandle,
PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE,
PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
&ObjectAttributes,
&RequestMsg->h.ClientId);
if (!NT_SUCCESS(Status))
@ -175,6 +207,8 @@ LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg)
goto done;
}
TRACE("Length: %lu\n", Length);
MemSize = Length;
Status = NtAllocateVirtualMemory(ProcessHandle,
&ClientBaseAddress,
@ -188,6 +222,9 @@ LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg)
goto done;
}
TRACE("MemSize: %lu\n", MemSize);
TRACE("ClientBaseAddress: %p\n", ClientBaseAddress);
Status = NtWriteVirtualMemory(ProcessHandle,
ClientBaseAddress,
SessionList,
@ -212,4 +249,110 @@ done:
return Status;
}
NTSTATUS
LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg)
{
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE ProcessHandle = NULL;
PLSAP_LOGON_SESSION Session;
PSECURITY_LOGON_SESSION_DATA LocalSessionData;
PVOID ClientBaseAddress = NULL;
ULONG Length, MemSize;
LPWSTR Ptr;
NTSTATUS Status;
TRACE("LsapGetLogonSessionData(%p)\n", RequestMsg);
TRACE("LogonId: %lx\n", RequestMsg->GetLogonSessionData.Request.LogonId.LowPart);
Session = LsapGetLogonSession(&RequestMsg->GetLogonSessionData.Request.LogonId);
if (Session == NULL)
return STATUS_NO_SUCH_LOGON_SESSION;
Length = sizeof(SECURITY_LOGON_SESSION_DATA);
/*
Session->UserName.MaximumLength +
Session->LogonDomain.MaximumLength +
Session->AuthenticationPackage.MaximumLength +
Session->LogonServer.MaximumLength +
Session->DnsDomainName.MaximumLength +
Session->Upn.MaximumLength;
if (Session->Sid != NULL)
RtlLengthSid(Session->Sid);
*/
TRACE("Length: %lu\n", Length);
LocalSessionData = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
Length);
if (LocalSessionData == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Ptr = (LPWSTR)((ULONG_PTR)LocalSessionData + sizeof(SECURITY_LOGON_SESSION_DATA));
TRACE("LocalSessionData: %p Ptr: %p\n", LocalSessionData, Ptr);
LocalSessionData->Size = sizeof(SECURITY_LOGON_SESSION_DATA);
RtlCopyLuid(&LocalSessionData->LogonId,
&RequestMsg->GetLogonSessionData.Request.LogonId);
InitializeObjectAttributes(&ObjectAttributes,
NULL,
0,
NULL,
NULL);
Status = NtOpenProcess(&ProcessHandle,
PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
&ObjectAttributes,
&RequestMsg->h.ClientId);
if (!NT_SUCCESS(Status))
{
TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
goto done;
}
TRACE("MemSize: %lu\n", MemSize);
MemSize = Length;
Status = NtAllocateVirtualMemory(ProcessHandle,
&ClientBaseAddress,
0,
&MemSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
goto done;
}
TRACE("MemSize: %lu\n", MemSize);
TRACE("ClientBaseAddress: %p\n", ClientBaseAddress);
Status = NtWriteVirtualMemory(ProcessHandle,
ClientBaseAddress,
LocalSessionData,
Length,
NULL);
if (!NT_SUCCESS(Status))
{
TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status);
goto done;
}
RequestMsg->GetLogonSessionData.Reply.SessionDataBuffer = ClientBaseAddress;
done:
if (ProcessHandle != NULL)
NtClose(ProcessHandle);
if (LocalSessionData != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSessionData);
return Status;
}
/* EOF */

View file

@ -108,9 +108,11 @@ LsapOpenLsaPort(VOID)
*/
NTSTATUS
NTAPI
LsaEnumerateLogonSessions(PULONG LogonSessionCount,
PLUID *LogonSessionList)
LsaEnumerateLogonSessions(
PULONG LogonSessionCount,
PLUID *LogonSessionList)
{
#if 1
LSA_API_MSG ApiMessage;
NTSTATUS Status;
@ -144,6 +146,10 @@ LsaEnumerateLogonSessions(PULONG LogonSessionCount,
*LogonSessionList = ApiMessage.EnumLogonSessions.Reply.LogonSessionBuffer;
return Status;
#else
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
#endif
}
@ -152,11 +158,59 @@ LsaEnumerateLogonSessions(PULONG LogonSessionCount,
*/
NTSTATUS
NTAPI
LsaGetLogonSessionData(PLUID LogonId,
PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData)
LsaGetLogonSessionData(
PLUID LogonId,
PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData)
{
#if 1
LSA_API_MSG ApiMessage;
PSECURITY_LOGON_SESSION_DATA SessionData;
NTSTATUS Status;
TRACE("LsaGetLogonSessionData(%p %p)\n", LogonId, ppLogonSessionData);
Status = LsapOpenLsaPort();
if (!NT_SUCCESS(Status))
return Status;
ApiMessage.ApiNumber = LSASS_REQUEST_GET_LOGON_SESSION_DATA;
ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.GetLogonSessionData);
ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
ApiMessage.h.u2.ZeroInit = 0;
RtlCopyLuid(&ApiMessage.GetLogonSessionData.Request.LogonId,
LogonId);
Status = NtRequestWaitReplyPort(LsaPortHandle,
(PPORT_MESSAGE)&ApiMessage,
(PPORT_MESSAGE)&ApiMessage);
if (!NT_SUCCESS(Status))
{
ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
return Status;
}
if (!NT_SUCCESS(ApiMessage.Status))
{
ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
return ApiMessage.Status;
}
SessionData = ApiMessage.GetLogonSessionData.Reply.SessionDataBuffer;
if (SessionData->UserName.Buffer != NULL)
SessionData->UserName.Buffer = (LPWSTR)((ULONG_PTR)&SessionData->UserName.Buffer + (ULONG_PTR)SessionData->UserName.Buffer);
if (SessionData->Sid != NULL)
SessionData->Sid = (LPWSTR)((ULONG_PTR)&SessionData->Sid + (ULONG_PTR)SessionData->Sid);
*ppLogonSessionData = SessionData;
return Status;
#else
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
#endif
}

View file

@ -22,6 +22,7 @@ typedef enum _LSA_API_NUMBER
LSASS_REQUEST_LOGON_USER,
LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE,
LSASS_REQUEST_ENUM_LOGON_SESSIONS,
LSASS_REQUEST_GET_LOGON_SESSION_DATA,
LSASS_REQUEST_MAXIMUM
} LSA_API_NUMBER, *PLSA_API_NUMBER;
@ -129,13 +130,28 @@ typedef struct _LSA_ENUM_LOGON_SESSIONS_MSG
struct
{
ULONG LogonSessionCount;
ULONG LogonSessionBufferLength;
PVOID LogonSessionBuffer;
} Reply;
};
} LSA_ENUM_LOGON_SESSIONS_MSG, *PLSA_ENUM_LOGON_SESSIONS_MSG;
typedef struct _LSA_GET_LOGON_SESSION_DATA_MSG
{
union
{
struct
{
LUID LogonId;
} Request;
struct
{
PVOID SessionDataBuffer;
} Reply;
};
} LSA_GET_LOGON_SESSION_DATA_MSG, *PLSA_GET_LOGON_SESSION_DATA_MSG;
typedef struct _LSA_API_MSG
{
PORT_MESSAGE h;
@ -153,6 +169,7 @@ typedef struct _LSA_API_MSG
LSA_DEREGISTER_LOGON_PROCESS_MSG DeregisterLogonProcess;
LSA_LOOKUP_AUTHENTICATION_PACKAGE_MSG LookupAuthenticationPackage;
LSA_ENUM_LOGON_SESSIONS_MSG EnumLogonSessions;
LSA_GET_LOGON_SESSION_DATA_MSG GetLogonSessionData;
};
};
};