https://git.reactos.org/?p=reactos.git;a=commitdiff;h=620217cec9e3dea4bf6fa5...
commit 620217cec9e3dea4bf6fa504044ae616bc130796 Author: Eric Kohl eric.kohl@reactos.org AuthorDate: Sat Aug 4 22:17:52 2018 +0200 Commit: Eric Kohl eric.kohl@reactos.org CommitDate: Sat Aug 4 22:17:52 2018 +0200
[LSASRV][SECUR32] Implement LsaRegisterPolicyChangeNotification and LsaUnregisterPolicyChangeNotification --- dll/win32/lsasrv/CMakeLists.txt | 1 + dll/win32/lsasrv/authport.c | 5 ++ dll/win32/lsasrv/lsasrv.c | 3 + dll/win32/lsasrv/lsasrv.h | 8 +++ dll/win32/lsasrv/notify.c | 102 +++++++++++++++++++++++++++++++ dll/win32/secur32/lsalpc.c | 88 +++++++++++++++++++++++--- sdk/include/psdk/ntsecapi.h | 4 ++ sdk/include/reactos/subsys/lsass/lsass.h | 20 ++++++ 8 files changed, 221 insertions(+), 10 deletions(-)
diff --git a/dll/win32/lsasrv/CMakeLists.txt b/dll/win32/lsasrv/CMakeLists.txt index 9627fe8900..13d3ab4398 100644 --- a/dll/win32/lsasrv/CMakeLists.txt +++ b/dll/win32/lsasrv/CMakeLists.txt @@ -17,6 +17,7 @@ list(APPEND SOURCE lookup.c lsarpc.c lsasrv.c + notify.c policy.c privileges.c registry.c diff --git a/dll/win32/lsasrv/authport.c b/dll/win32/lsasrv/authport.c index 0475969642..8e0b128b0f 100644 --- a/dll/win32/lsasrv/authport.c +++ b/dll/win32/lsasrv/authport.c @@ -242,6 +242,11 @@ AuthPortThreadRoutine(PVOID Param) ReplyMsg = &RequestMsg; break;
+ case LSASS_REQUEST_POLICY_CHANGE_NOTIFY: + RequestMsg.Status = LsapRegisterNotification(&RequestMsg); + ReplyMsg = &RequestMsg; + break; + default: RequestMsg.Status = STATUS_INVALID_SYSTEM_SERVICE; ReplyMsg = &RequestMsg; diff --git a/dll/win32/lsasrv/lsasrv.c b/dll/win32/lsasrv/lsasrv.c index 206c10ec06..b92e0e6ff9 100644 --- a/dll/win32/lsasrv/lsasrv.c +++ b/dll/win32/lsasrv/lsasrv.c @@ -293,6 +293,9 @@ LsapInitLsa(VOID) /* Initialize logon sessions */ LsapInitLogonSessions();
+ /* Initialize the notification list */ + LsapInitNotificationList(); + /* Initialize registered authentication packages */ Status = LsapInitAuthPackages(); if (!NT_SUCCESS(Status)) diff --git a/dll/win32/lsasrv/lsasrv.h b/dll/win32/lsasrv/lsasrv.h index 8a772aba21..cbff5e2b86 100644 --- a/dll/win32/lsasrv/lsasrv.h +++ b/dll/win32/lsasrv/lsasrv.h @@ -209,6 +209,14 @@ LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer, NTSTATUS LsarStartRpcServer(VOID);
+/* notify.c */ +VOID +LsapInitNotificationList(VOID); + +NTSTATUS +LsapRegisterNotification( + PLSA_API_MSG RequestMsg); + /* policy.c */ NTSTATUS LsarQueryAuditLog(PLSA_DB_OBJECT PolicyObject, diff --git a/dll/win32/lsasrv/notify.c b/dll/win32/lsasrv/notify.c new file mode 100644 index 0000000000..48f09c7ecf --- /dev/null +++ b/dll/win32/lsasrv/notify.c @@ -0,0 +1,102 @@ +/* + * PROJECT: Local Security Authority Server DLL + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: LSA policy change notifications + * COPYRIGHT: Eric Kohl 2018 + */ + +#include "lsasrv.h" + +typedef struct _LSA_NOTIFICATION_ENTRY +{ + LIST_ENTRY Entry; + POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass; + HANDLE EventHandle; +} LSA_NOTIFICATION_ENTRY, *PLSA_NOTIFICATION_ENTRY; + +/* GLOBALS *****************************************************************/ + +static LIST_ENTRY NotificationListHead; +static RTL_RESOURCE NotificationListLock; + + +/* FUNCTIONS ***************************************************************/ + +VOID +LsapInitNotificationList(VOID) +{ + InitializeListHead(&NotificationListHead); + RtlInitializeResource(&NotificationListLock); +} + + +static +PLSA_NOTIFICATION_ENTRY +LsapGetNotificationEntryByHandle( + HANDLE EventHandle) +{ + PLIST_ENTRY NotificationEntry; + PLSA_NOTIFICATION_ENTRY CurrentNotification; + + NotificationEntry = NotificationListHead.Flink; + while (NotificationEntry != &NotificationListHead) + { + CurrentNotification = CONTAINING_RECORD(NotificationEntry, LSA_NOTIFICATION_ENTRY, Entry); + + if (CurrentNotification->EventHandle == EventHandle) + return CurrentNotification; + + NotificationEntry = NotificationEntry->Flink; + } + + return NULL; +} + + +NTSTATUS +LsapRegisterNotification( + PLSA_API_MSG pRequestMsg) +{ + PLSA_NOTIFICATION_ENTRY pEntry; + NTSTATUS Status = STATUS_SUCCESS; + + FIXME("LsapRegisterNotification(%p)\n", pRequestMsg); + + /* Acquire the notification list lock exclusively */ + RtlAcquireResourceExclusive(&NotificationListLock, TRUE); + + if (pRequestMsg->PolicyChangeNotify.Request.Register) + { + pEntry = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(LSA_NOTIFICATION_ENTRY)); + if (pEntry == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + pEntry->InformationClass = pRequestMsg->PolicyChangeNotify.Request.InformationClass; + pEntry->EventHandle = pRequestMsg->PolicyChangeNotify.Request.NotificationEventHandle; + + InsertHeadList(&NotificationListHead, + &pEntry->Entry); + } + else + { + pEntry = LsapGetNotificationEntryByHandle(pRequestMsg->PolicyChangeNotify.Request.NotificationEventHandle); + if (pEntry) + { + RemoveEntryList(&pEntry->Entry); + RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry); + } + } + +done: + /* Release the notification list lock */ + RtlReleaseResource(&NotificationListLock); + + return Status; +} + +/* EOF */ diff --git a/dll/win32/secur32/lsalpc.c b/dll/win32/secur32/lsalpc.c index ff44f69063..58a806cbb5 100644 --- a/dll/win32/secur32/lsalpc.c +++ b/dll/win32/secur32/lsalpc.c @@ -322,28 +322,96 @@ LsaGetLogonSessionData(
/* - * @unimplemented + * @implemented */ NTSTATUS NTAPI -LsaRegisterPolicyChangeNotification(POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass, - HANDLE NotificationEventHandle) +LsaRegisterPolicyChangeNotification( + POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass, + HANDLE NotificationEventHandle) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + LSA_API_MSG ApiMessage; + NTSTATUS Status; + + TRACE("LsaRegisterPolicyChangeNotification(%lu %p)\n", + InformationClass, NotificationEventHandle); + + Status = LsapOpenLsaPort(); + if (!NT_SUCCESS(Status)) + return Status; + + ApiMessage.ApiNumber = LSASS_REQUEST_POLICY_CHANGE_NOTIFY; + ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.PolicyChangeNotify); + ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE; + ApiMessage.h.u2.ZeroInit = 0; + + ApiMessage.PolicyChangeNotify.Request.InformationClass = InformationClass; + ApiMessage.PolicyChangeNotify.Request.NotificationEventHandle = NotificationEventHandle; + ApiMessage.PolicyChangeNotify.Request.Register = TRUE; + + 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; + } + + return Status; }
/* - * @unimplemented + * @implemented */ NTSTATUS NTAPI -LsaUnregisterPolicyChangeNotification(POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass, - HANDLE NotificationEventHandle) +LsaUnregisterPolicyChangeNotification( + POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass, + HANDLE NotificationEventHandle) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + LSA_API_MSG ApiMessage; + NTSTATUS Status; + + TRACE("LsaUnregisterPolicyChangeNotification(%lu %p)\n", + InformationClass, NotificationEventHandle); + + Status = LsapOpenLsaPort(); + if (!NT_SUCCESS(Status)) + return Status; + + ApiMessage.ApiNumber = LSASS_REQUEST_POLICY_CHANGE_NOTIFY; + ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.PolicyChangeNotify); + ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE; + ApiMessage.h.u2.ZeroInit = 0; + + ApiMessage.PolicyChangeNotify.Request.InformationClass = InformationClass; + ApiMessage.PolicyChangeNotify.Request.NotificationEventHandle = NotificationEventHandle; + ApiMessage.PolicyChangeNotify.Request.Register = FALSE; + + 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; + } + + return Status; }
/* EOF */ diff --git a/sdk/include/psdk/ntsecapi.h b/sdk/include/psdk/ntsecapi.h index 13d9d2c8ef..52e9407dc0 100644 --- a/sdk/include/psdk/ntsecapi.h +++ b/sdk/include/psdk/ntsecapi.h @@ -770,6 +770,8 @@ NTSTATUS NTAPI LsaQueryTrustedDomainInfo(LSA_HANDLE,PSID, NTSTATUS NTAPI LsaQueryTrustedDomainInfoByName(LSA_HANDLE,PLSA_UNICODE_STRING, TRUSTED_INFORMATION_CLASS,PVOID*); NTSTATUS NTAPI LsaRegisterLogonProcess(PLSA_STRING,PHANDLE,PLSA_OPERATIONAL_MODE); +NTSTATUS NTAPI LsaRegisterPolicyChangeNotification(POLICY_NOTIFICATION_INFORMATION_CLASS, + HANDLE); NTSTATUS NTAPI LsaRemoveAccountRights(LSA_HANDLE,PSID,BOOLEAN, PLSA_UNICODE_STRING,ULONG); NTSTATUS NTAPI LsaRemovePrivilegesFromAccount(LSA_HANDLE,BOOLEAN,PPRIVILEGE_SET); @@ -790,6 +792,8 @@ NTSTATUS NTAPI LsaSetTrustedDomainInfoByName(LSA_HANDLE,PLSA_UNICODE_STRING, TRUSTED_INFORMATION_CLASS,PVOID); NTSTATUS NTAPI LsaStorePrivateData(LSA_HANDLE,PLSA_UNICODE_STRING, PLSA_UNICODE_STRING); +NTSTATUS NTAPI LsaUnregisterPolicyChangeNotification(POLICY_NOTIFICATION_INFORMATION_CLASS, + HANDLE); typedef NTSTATUS (NTAPI *PSAM_PASSWORD_NOTIFICATION_ROUTINE)(PUNICODE_STRING, ULONG,PUNICODE_STRING); typedef BOOLEAN (NTAPI *PSAM_INIT_NOTIFICATION_ROUTINE)(VOID); diff --git a/sdk/include/reactos/subsys/lsass/lsass.h b/sdk/include/reactos/subsys/lsass/lsass.h index 2004288b01..4d889c0e6c 100644 --- a/sdk/include/reactos/subsys/lsass/lsass.h +++ b/sdk/include/reactos/subsys/lsass/lsass.h @@ -23,6 +23,7 @@ typedef enum _LSA_API_NUMBER LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE, LSASS_REQUEST_ENUM_LOGON_SESSIONS, LSASS_REQUEST_GET_LOGON_SESSION_DATA, + LSASS_REQUEST_POLICY_CHANGE_NOTIFY, LSASS_REQUEST_MAXIMUM } LSA_API_NUMBER, *PLSA_API_NUMBER;
@@ -152,6 +153,24 @@ typedef struct _LSA_GET_LOGON_SESSION_DATA_MSG } LSA_GET_LOGON_SESSION_DATA_MSG, *PLSA_GET_LOGON_SESSION_DATA_MSG;
+typedef struct _LSA_POLICY_CHANGE_NOTIFY_MSG +{ + union + { + struct + { + POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass; + HANDLE NotificationEventHandle; + BOOLEAN Register; + } Request; + struct + { + ULONG Dummy; + } Reply; + }; +} LSA_POLICY_CHANGE_NOTIFY_MSG, *PLSA_POLICY_CHANGE_NOTIFY_MSG; + + typedef struct _LSA_API_MSG { PORT_MESSAGE h; @@ -170,6 +189,7 @@ typedef struct _LSA_API_MSG LSA_LOOKUP_AUTHENTICATION_PACKAGE_MSG LookupAuthenticationPackage; LSA_ENUM_LOGON_SESSIONS_MSG EnumLogonSessions; LSA_GET_LOGON_SESSION_DATA_MSG GetLogonSessionData; + LSA_POLICY_CHANGE_NOTIFY_MSG PolicyChangeNotify; }; }; };