1 /* 2 * PROJECT: Local Security Authority Server DLL 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: LSA policy change notifications 5 * COPYRIGHT: Eric Kohl 2018 6 */ 7 8 #include "lsasrv.h" 9 10 typedef struct _LSA_NOTIFICATION_ENTRY 11 { 12 LIST_ENTRY Entry; 13 POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass; 14 HANDLE EventHandle; 15 } LSA_NOTIFICATION_ENTRY, *PLSA_NOTIFICATION_ENTRY; 16 17 /* GLOBALS *****************************************************************/ 18 19 static LIST_ENTRY NotificationListHead; 20 static RTL_RESOURCE NotificationListLock; 21 22 23 /* FUNCTIONS ***************************************************************/ 24 25 VOID 26 LsapInitNotificationList(VOID) 27 { 28 InitializeListHead(&NotificationListHead); 29 RtlInitializeResource(&NotificationListLock); 30 } 31 32 33 static 34 PLSA_NOTIFICATION_ENTRY 35 LsapGetNotificationEntry( 36 HANDLE EventHandle, 37 POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass) 38 { 39 PLIST_ENTRY NotificationEntry; 40 PLSA_NOTIFICATION_ENTRY CurrentNotification; 41 42 NotificationEntry = NotificationListHead.Flink; 43 while (NotificationEntry != &NotificationListHead) 44 { 45 CurrentNotification = CONTAINING_RECORD(NotificationEntry, LSA_NOTIFICATION_ENTRY, Entry); 46 47 if ((CurrentNotification->EventHandle == EventHandle) && 48 (CurrentNotification->InformationClass == InformationClass)) 49 return CurrentNotification; 50 51 NotificationEntry = NotificationEntry->Flink; 52 } 53 54 return NULL; 55 } 56 57 58 NTSTATUS 59 LsapRegisterNotification( 60 PLSA_API_MSG pRequestMsg) 61 { 62 PLSA_NOTIFICATION_ENTRY pEntry; 63 NTSTATUS Status = STATUS_SUCCESS; 64 65 FIXME("LsapRegisterNotification(%p)\n", pRequestMsg); 66 67 /* Acquire the notification list lock exclusively */ 68 RtlAcquireResourceExclusive(&NotificationListLock, TRUE); 69 70 if (pRequestMsg->PolicyChangeNotify.Request.Register) 71 { 72 /* Register the notification event */ 73 pEntry = RtlAllocateHeap(RtlGetProcessHeap(), 74 HEAP_ZERO_MEMORY, 75 sizeof(LSA_NOTIFICATION_ENTRY)); 76 if (pEntry == NULL) 77 { 78 Status = STATUS_INSUFFICIENT_RESOURCES; 79 goto done; 80 } 81 82 pEntry->InformationClass = pRequestMsg->PolicyChangeNotify.Request.InformationClass; 83 pEntry->EventHandle = pRequestMsg->PolicyChangeNotify.Request.NotificationEventHandle; 84 85 InsertHeadList(&NotificationListHead, 86 &pEntry->Entry); 87 } 88 else 89 { 90 /* Unregister the notification event */ 91 pEntry = LsapGetNotificationEntry(pRequestMsg->PolicyChangeNotify.Request.NotificationEventHandle, 92 pRequestMsg->PolicyChangeNotify.Request.InformationClass); 93 if (pEntry == NULL) 94 { 95 Status = STATUS_INVALID_HANDLE; 96 goto done; 97 } 98 99 RemoveEntryList(&pEntry->Entry); 100 RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry); 101 } 102 103 done: 104 /* Release the notification list lock */ 105 RtlReleaseResource(&NotificationListLock); 106 107 return Status; 108 } 109 110 111 VOID 112 LsapNotifyPolicyChange( 113 POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass) 114 { 115 PLIST_ENTRY NotificationEntry; 116 PLSA_NOTIFICATION_ENTRY CurrentNotification; 117 118 FIXME("LsapNotifyPolicyChange(%lu)\n", InformationClass); 119 120 /* Acquire the notification list lock shared */ 121 RtlAcquireResourceShared(&NotificationListLock, TRUE); 122 123 NotificationEntry = NotificationListHead.Flink; 124 while (NotificationEntry != &NotificationListHead) 125 { 126 CurrentNotification = CONTAINING_RECORD(NotificationEntry, LSA_NOTIFICATION_ENTRY, Entry); 127 128 if (CurrentNotification->InformationClass == InformationClass) 129 { 130 FIXME("Notify event %p\n", CurrentNotification->EventHandle); 131 132 } 133 134 NotificationEntry = NotificationEntry->Flink; 135 } 136 137 /* Release the notification list lock */ 138 RtlReleaseResource(&NotificationListLock); 139 } 140 141 /* EOF */ 142