[LSASRV][SECUR32] Implement LsaRegisterPolicyChangeNotification and LsaUnregisterPoli...
authorEric Kohl <eric.kohl@reactos.org>
Sat, 4 Aug 2018 20:17:52 +0000 (22:17 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 4 Aug 2018 20:17:52 +0000 (22:17 +0200)
dll/win32/lsasrv/CMakeLists.txt
dll/win32/lsasrv/authport.c
dll/win32/lsasrv/lsasrv.c
dll/win32/lsasrv/lsasrv.h
dll/win32/lsasrv/notify.c [new file with mode: 0644]
dll/win32/secur32/lsalpc.c
sdk/include/psdk/ntsecapi.h
sdk/include/reactos/subsys/lsass/lsass.h

index 9627fe8..13d3ab4 100644 (file)
@@ -17,6 +17,7 @@ list(APPEND SOURCE
     lookup.c
     lsarpc.c
     lsasrv.c
+    notify.c
     policy.c
     privileges.c
     registry.c
index 0475969..8e0b128 100644 (file)
@@ -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;
index 206c10e..b92e0e6 100644 (file)
@@ -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))
index 8a772ab..cbff5e2 100644 (file)
@@ -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 (file)
index 0000000..48f09c7
--- /dev/null
@@ -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 */
index ff44f69..58a806c 100644 (file)
@@ -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 */
index 13d9d2c..52e9407 100644 (file)
@@ -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);
index 2004288..4d889c0 100644 (file)
@@ -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;
             };
         };
     };