ReactOS  0.4.15-dev-3331-g8ebe441
srm.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Security Reference Monitor Server
5  * COPYRIGHT: Copyright Timo Kreuzer <timo.kreuzer@reactos.org>
6  * Copyright Pierre Schweitzer <pierre@reactos.org>
7  * Copyright 2021 George BiČ™oc <george.bisoc@reactos.org>
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* PRIVATE DEFINITIONS ********************************************************/
17 
19 {
23 
24 VOID
25 NTAPI
27  _In_ PVOID StartContext);
28 
29 static
32  _In_ PLUID LogonLuid);
33 
34 static
37  _In_ PLUID LogonLuid);
38 
39 
40 /* GLOBALS ********************************************************************/
41 
44 
47 
51 
53 
57 
58 #define POLICY_AUDIT_EVENT_TYPE_COUNT 9 // (AuditCategoryAccountLogon - AuditCategorySystem + 1)
60 
64 
65 /* PRIVATE FUNCTIONS **********************************************************/
66 
92 NTAPI
99 {
100  UNICODE_STRING ValueNameString;
101  UNICODE_STRING KeyNameString;
105  struct
106  {
108  UCHAR Buffer[64];
109  } KeyValueInformation;
110  NTSTATUS Status, CloseStatus;
111  PAGED_CODE();
112 
113  RtlInitUnicodeString(&KeyNameString, KeyName);
115  &KeyNameString,
117  NULL,
118  NULL);
119 
121  if (!NT_SUCCESS(Status))
122  {
123  return Status;
124  }
125 
126  RtlInitUnicodeString(&ValueNameString, ValueName);
127  Status = ZwQueryValueKey(KeyHandle,
128  &ValueNameString,
130  &KeyValueInformation.Partial,
131  sizeof(KeyValueInformation),
132  &ResultLength);
133  if (!NT_SUCCESS(Status))
134  {
135  goto Cleanup;
136  }
137 
138  if ((KeyValueInformation.Partial.Type != ValueType) ||
139  (KeyValueInformation.Partial.DataLength != DataLength))
140  {
142  goto Cleanup;
143  }
144 
145  if (ValueType == REG_BINARY)
146  {
147  RtlCopyMemory(ValueData, KeyValueInformation.Partial.Data, DataLength);
148  }
149  else if (ValueType == REG_DWORD)
150  {
151  *(PULONG)ValueData = *(PULONG)KeyValueInformation.Partial.Data;
152  }
153  else
154  {
156  }
157 
158 Cleanup:
159  CloseStatus = ZwClose(KeyHandle);
160  ASSERT(NT_SUCCESS( CloseStatus ));
161 
162  return Status;
163 }
164 
174 BOOLEAN
175 NTAPI
177 {
179 
180  /* Initialize the database lock */
182 
183  /* Create the system logon session */
185  if (!NT_VERIFY(NT_SUCCESS(Status)))
186  {
187  return FALSE;
188  }
189 
190  /* Create the anonymous logon session */
192  if (!NT_VERIFY(NT_SUCCESS(Status)))
193  {
194  return FALSE;
195  }
196 
197  return TRUE;
198 }
199 
209 BOOLEAN
210 NTAPI
212 {
215  HANDLE ThreadHandle;
217 
218  /* Create the SeRm command port */
219  RtlInitUnicodeString(&Name, L"\\SeRmCommandPort");
223  sizeof(ULONG),
225  2 * PAGE_SIZE);
226  if (!NT_SUCCESS(Status))
227  {
228  DPRINT1("Security: Rm Create Command Port failed 0x%lx\n", Status);
229  return FALSE;
230  }
231 
232  /* Create SeLsaInitEvent */
233  RtlInitUnicodeString(&Name, L"\\SeLsaInitEvent");
235  Status = ZwCreateEvent(&SeLsaInitEvent,
239  FALSE);
240  if (!NT_VERIFY((NT_SUCCESS(Status))))
241  {
242  DPRINT1("Security: LSA init event creation failed.0x%xl\n", Status);
243  return FALSE;
244  }
245 
246  /* Create the SeRm server thread */
247  Status = PsCreateSystemThread(&ThreadHandle,
249  NULL,
250  NULL,
251  NULL,
253  NULL);
254  if (!NT_SUCCESS(Status))
255  {
256  DPRINT1("Security: Rm Server Thread creation failed 0x%lx\n", Status);
257  return FALSE;
258  }
259 
260  ObCloseHandle(ThreadHandle, KernelMode);
261 
262  return TRUE;
263 }
264 
272 static
273 VOID
275 {
276  struct
277  {
278  ULONG MaxLength;
279  ULONG MinLength;
280  } ListBounds;
282  PAGED_CODE();
283 
284  Status = SepRegQueryHelper(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Lsa",
285  L"Bounds",
286  REG_BINARY,
287  sizeof(ListBounds),
288  &ListBounds);
289  if (!NT_SUCCESS(Status))
290  {
291  /* No registry values, so keep hardcoded defaults */
292  return;
293  }
294 
295  /* Check if the bounds are valid */
296  if ((ListBounds.MaxLength < ListBounds.MinLength) ||
297  (ListBounds.MinLength < 16) ||
298  (ListBounds.MaxLength - ListBounds.MinLength < 16))
299  {
300  DPRINT1("ListBounds are invalid: %u, %u\n",
301  ListBounds.MinLength, ListBounds.MaxLength);
302  return;
303  }
304 
305  /* Set the new bounds globally */
306  SepAdtMinListLength = ListBounds.MinLength;
307  SepAdtMaxListLength = ListBounds.MaxLength;
308 }
309 
322 static
323 NTSTATUS
326 {
327  ULONG i;
328  PAGED_CODE();
329 
330  /* First re-initialize the bounds from the registry */
332 
333  /* Make sure we have the right message and clear */
334  ASSERT(Message->ApiNumber == RmAuditSetCommand);
335  Message->ApiNumber = 0;
336 
337  /* Store the enable flag in the global variable */
338  SepAdtAuditingEnabled = Message->u.SetAuditEvent.Enabled;
339 
340  /* Loop all audit event types */
341  for (i = 0; i < POLICY_AUDIT_EVENT_TYPE_COUNT; i++)
342  {
343  /* Save the provided flags in the global array */
344  SeAuditingState[i] = (UCHAR)Message->u.SetAuditEvent.Flags[i];
345  }
346 
347  return STATUS_SUCCESS;
348 }
349 
366 NTSTATUS
367 NTAPI
370 {
371  PSEP_LOGON_SESSION_REFERENCES LogonSession;
372  PAGED_CODE();
373 
374  /* Ensure that our token is not some plain garbage */
375  ASSERT(Token);
376 
377  /* Acquire the database lock */
379 
380  for (LogonSession = SepLogonSessions;
381  LogonSession != NULL;
382  LogonSession = LogonSession->Next)
383  {
384  /*
385  * The insertion of a logon session into the token has to be done
386  * only IF the authentication ID of the token matches with the ID
387  * of the logon itself.
388  */
389  if (RtlEqualLuid(&LogonSession->LogonId, &Token->AuthenticationId))
390  {
391  break;
392  }
393  }
394 
395  /* If we reach this then we cannot proceed further */
396  if (LogonSession == NULL)
397  {
398  DPRINT1("SepRmInsertLogonSessionIntoToken(): Couldn't insert the logon session into the specific access token!\n");
401  }
402 
403  /*
404  * Allocate the session that we are going
405  * to insert it to the token.
406  */
407  Token->LogonSession = ExAllocatePoolWithTag(PagedPool,
410  if (Token->LogonSession == NULL)
411  {
412  DPRINT1("SepRmInsertLogonSessionIntoToken(): Couldn't allocate new logon session into the memory pool!\n");
415  }
416 
417  /*
418  * Begin copying the logon session references data from the
419  * session whose ID matches with the token authentication ID to
420  * the new session we've allocated blocks of pool memory for it.
421  */
422  Token->LogonSession->Next = LogonSession->Next;
423  Token->LogonSession->LogonId = LogonSession->LogonId;
424  Token->LogonSession->ReferenceCount = LogonSession->ReferenceCount;
425  Token->LogonSession->Flags = LogonSession->Flags;
426  Token->LogonSession->pDeviceMap = LogonSession->pDeviceMap;
427  InsertHeadList(&LogonSession->TokenList, &Token->LogonSession->TokenList);
428 
429  /* Release the database lock and we're done */
431  return STATUS_SUCCESS;
432 }
433 
447 NTSTATUS
448 NTAPI
451 {
452  PSEP_LOGON_SESSION_REFERENCES LogonSession;
453  PAGED_CODE();
454 
455  /* Ensure that our token is not some plain garbage */
456  ASSERT(Token);
457 
458  /* Acquire the database lock */
460 
461  for (LogonSession = SepLogonSessions;
462  LogonSession != NULL;
463  LogonSession = LogonSession->Next)
464  {
465  /*
466  * Remove the logon session only when the IDs of the token and the
467  * logon match.
468  */
469  if (RtlEqualLuid(&LogonSession->LogonId, &Token->AuthenticationId))
470  {
471  break;
472  }
473  }
474 
475  /* They don't match */
476  if (LogonSession == NULL)
477  {
478  DPRINT1("SepRmRemoveLogonSessionFromToken(): Couldn't remove the logon session from the access token!\n");
481  }
482 
483  /* Now it's time to delete the logon session from the token */
484  RemoveEntryList(&Token->LogonSession->TokenList);
485  ExFreePoolWithTag(Token->LogonSession, TAG_LOGON_SESSION);
486 
487  /* Release the database lock and we're done */
489  return STATUS_SUCCESS;
490 }
491 
510 static
511 NTSTATUS
513  _In_ PLUID LogonLuid)
514 {
515  PSEP_LOGON_SESSION_REFERENCES CurrentSession, NewSession;
517  PAGED_CODE();
518 
519  DPRINT("SepRmCreateLogonSession(%08lx:%08lx)\n",
520  LogonLuid->HighPart, LogonLuid->LowPart);
521 
522  /* Allocate a new session structure */
523  NewSession = ExAllocatePoolWithTag(PagedPool,
526  if (NewSession == NULL)
527  {
529  }
530 
531  /* Initialize it */
532  NewSession->LogonId = *LogonLuid;
533  NewSession->ReferenceCount = 0;
534  NewSession->Flags = 0;
535  NewSession->pDeviceMap = NULL;
536  InitializeListHead(&NewSession->TokenList);
537 
538  /* Acquire the database lock */
540 
541  /* Loop all existing sessions */
542  for (CurrentSession = SepLogonSessions;
543  CurrentSession != NULL;
544  CurrentSession = CurrentSession->Next)
545  {
546  /* Check if the LUID matches the new one */
547  if (RtlEqualLuid(&CurrentSession->LogonId, LogonLuid))
548  {
550  goto Leave;
551  }
552  }
553 
554  /* Insert the new session */
555  NewSession->Next = SepLogonSessions;
556  SepLogonSessions = NewSession;
557 
559 
560 Leave:
561  /* Release the database lock */
563 
564  if (!NT_SUCCESS(Status))
565  {
567  }
568 
569  return Status;
570 }
571 
588 static
589 NTSTATUS
591  _In_ PLUID LogonLuid)
592 {
593  PSEP_LOGON_SESSION_REFERENCES SessionToDelete;
595  PAGED_CODE();
596 
597  DPRINT("SepRmDeleteLogonSession(%08lx:%08lx)\n",
598  LogonLuid->HighPart, LogonLuid->LowPart);
599 
600  /* Acquire the database lock */
602 
603  /* Loop over the existing logon sessions */
604  for (SessionToDelete = SepLogonSessions;
605  SessionToDelete != NULL;
606  SessionToDelete = SessionToDelete->Next)
607  {
608  /*
609  * Does the actual logon session exist in the
610  * saved logon sessions database with the LUID
611  * provided?
612  */
613  if (RtlEqualLuid(&SessionToDelete->LogonId, LogonLuid))
614  {
615  /* Did the caller supply one of these internal sessions? */
616  if (RtlEqualLuid(&SessionToDelete->LogonId, &SeSystemAuthenticationId) ||
617  RtlEqualLuid(&SessionToDelete->LogonId, &SeAnonymousAuthenticationId))
618  {
619  /* These logons are critical stuff, we can't delete them */
620  DPRINT1("SepRmDeleteLogonSession(): We're not allowed to delete anonymous/system sessions!\n");
622  goto Leave;
623  }
624  else
625  {
626  /* We found the logon as exactly as we wanted, break the loop */
627  break;
628  }
629  }
630  }
631 
632  /*
633  * If we reach this then that means we've exhausted all the logon
634  * sessions and couldn't find one with the desired LUID.
635  */
636  if (SessionToDelete == NULL)
637  {
638  DPRINT1("SepRmDeleteLogonSession(): The logon session with this LUID doesn't exist!\n");
640  goto Leave;
641  }
642 
643  /* Is somebody still using this logon session? */
644  if (SessionToDelete->ReferenceCount != 0)
645  {
646  /* The logon session is still in use, we cannot delete it... */
647  DPRINT1("SepRmDeleteLogonSession(): The logon session is still in use!\n");
649  goto Leave;
650  }
651 
652  /* If we have a LUID device map, clean it */
653  if (SessionToDelete->pDeviceMap != NULL)
654  {
656  if (!NT_SUCCESS(Status))
657  {
658  /*
659  * We had one job on cleaning the device map directory
660  * of the logon session but we failed, quit...
661  */
662  DPRINT1("SepRmDeleteLogonSession(): Failed to clean the LUID device map directory of the logon (Status: 0x%lx)\n", Status);
663  goto Leave;
664  }
665 
666  /* And dereference the device map of the logon */
667  ObfDereferenceDeviceMap(SessionToDelete->pDeviceMap);
668  }
669 
670  /* If we're here then we've deleted the logon session successfully */
671  DPRINT("SepRmDeleteLogonSession(): Logon session deleted with success!\n");
673  ExFreePoolWithTag(SessionToDelete, TAG_LOGON_SESSION);
674 
675 Leave:
676  /* Release the database lock */
678  return Status;
679 }
680 
694 NTSTATUS
696  _In_ PLUID LogonLuid)
697 {
698  PSEP_LOGON_SESSION_REFERENCES CurrentSession;
699 
700  PAGED_CODE();
701 
702  DPRINT("SepRmReferenceLogonSession(%08lx:%08lx)\n",
703  LogonLuid->HighPart, LogonLuid->LowPart);
704 
705  /* Acquire the database lock */
707 
708  /* Loop all existing sessions */
709  for (CurrentSession = SepLogonSessions;
710  CurrentSession != NULL;
711  CurrentSession = CurrentSession->Next)
712  {
713  /* Check if the LUID matches the new one */
714  if (RtlEqualLuid(&CurrentSession->LogonId, LogonLuid))
715  {
716  /* Reference the session */
717  ++CurrentSession->ReferenceCount;
718  DPRINT("ReferenceCount: %lu\n", CurrentSession->ReferenceCount);
719 
720  /* Release the database lock */
722 
723  return STATUS_SUCCESS;
724  }
725  }
726 
727  /* Release the database lock */
729 
731 }
732 
749 static
750 NTSTATUS
752  _In_ PLUID LogonLuid)
753 {
754  BOOLEAN UseCurrentProc;
756  WCHAR Buffer[63];
757  UNICODE_STRING DirectoryName;
760  HANDLE DirectoryHandle, LinkHandle;
761  PHANDLE LinksBuffer;
762  POBJECT_DIRECTORY_INFORMATION DirectoryInfo;
763  ULONG LinksCount, LinksSize, DirInfoLength, ReturnLength, Context, CurrentLinks, i;
765 
766  PAGED_CODE();
767 
768  /* We need a logon LUID */
769  if (LogonLuid == NULL)
770  {
772  }
773 
774  /* Use current process */
775  UseCurrentProc = ObReferenceObjectSafe(PsGetCurrentProcess());
776  if (UseCurrentProc)
777  {
779  }
780  /* Unless it's gone, then use system process */
781  else
782  {
784  }
785 
786  /* Initialize our directory name */
788  sizeof(Buffer) / sizeof(WCHAR),
789  L"\\Sessions\\0\\DosDevices\\%08x-%08x",
790  LogonLuid->HighPart,
791  LogonLuid->LowPart);
792  RtlInitUnicodeString(&DirectoryName, Buffer);
793 
794  /* And open it */
796  &DirectoryName,
798  NULL,
799  NULL);
803  if (!NT_SUCCESS(Status))
804  {
805  if (!UseCurrentProc)
806  {
808  }
809 
810  return Status;
811  }
812 
813  /* Some initialization needed for browsing all our links... */
814  Context = 0;
815  DirectoryInfo = NULL;
816  DirInfoLength = 0;
817  /* In our buffer, we'll store at max 100 HANDLE */
818  LinksCount = 100;
819  CurrentLinks = 0;
820  /* Which gives a certain size */
821  LinksSize = LinksCount * sizeof(HANDLE);
822 
823  /*
824  * This label is hit if we need to store more than a hundred
825  * of links. In that case, we jump here after having cleaned
826  * and deleted previous buffer.
827  * All handles have been already closed
828  */
829 AllocateLinksAgain:
830  LinksBuffer = ExAllocatePoolWithTag(PagedPool,
831  LinksSize,
833  if (LinksBuffer == NULL)
834  {
835  /*
836  * Failure path: no need to clear handles:
837  * already closed and the buffer is already gone
838  */
840 
841  /*
842  * On the first round, DirectoryInfo is NULL,
843  * if we grow LinksBuffer, it has been allocated
844  */
845  if (DirectoryInfo != NULL)
846  {
847  ExFreePoolWithTag(DirectoryInfo, TAG_SE_DIR_BUFFER);
848  }
849 
850  if (!UseCurrentProc)
851  {
853  }
854 
855  return STATUS_NO_MEMORY;
856  }
857 
858  /*
859  * We always restart scan, but on the first loop
860  * if we couldn't fit everything in our buffer,
861  * then, we continue scan.
862  * But we restart if link buffer was too small
863  */
864  for (RestartScan = TRUE; ; RestartScan = FALSE)
865  {
866  /*
867  * Loop until our buffer is big enough to store
868  * one entry
869  */
870  while (TRUE)
871  {
872  Status = ZwQueryDirectoryObject(DirectoryHandle,
873  DirectoryInfo,
874  DirInfoLength,
875  TRUE,
876  RestartScan,
877  &Context,
878  &ReturnLength);
879  /* Only handle buffer growth in that loop */
881  {
882  break;
883  }
884 
885  /* Get output length as new length */
886  DirInfoLength = ReturnLength;
887  /* Delete old buffer if any */
888  if (DirectoryInfo != NULL)
889  {
890  ExFreePoolWithTag(DirectoryInfo, 'bDeS');
891  }
892 
893  /* And reallocate a bigger one */
894  DirectoryInfo = ExAllocatePoolWithTag(PagedPool,
895  DirInfoLength,
897  /* Fail if we cannot allocate */
898  if (DirectoryInfo == NULL)
899  {
901  break;
902  }
903  }
904 
905  /* If querying the entry failed, quit */
906  if (!NT_SUCCESS(Status))
907  {
908  break;
909  }
910 
911  /* We only look for symbolic links, the rest, we ignore */
912  if (wcscmp(DirectoryInfo->TypeName.Buffer, L"SymbolicLink"))
913  {
914  continue;
915  }
916 
917  /* If our link buffer is out of space, reallocate */
918  if (CurrentLinks >= LinksCount)
919  {
920  /* First, close the links */
921  for (i = 0; i < CurrentLinks; ++i)
922  {
923  ZwClose(LinksBuffer[i]);
924  }
925 
926  /* Allow 20 more HANDLEs */
927  LinksCount += 20;
928  CurrentLinks = 0;
930  LinksSize = LinksCount * sizeof(HANDLE);
931 
932  /* And reloop again */
933  goto AllocateLinksAgain;
934  }
935 
936  /* Open the found link */
938  &DirectoryInfo->Name,
941  NULL);
942  if (NT_SUCCESS(ZwOpenSymbolicLinkObject(&LinkHandle,
944  &ObjectAttributes)))
945  {
946  /* If we cannot make it temporary, just close the link handle */
947  if (!NT_SUCCESS(ZwMakeTemporaryObject(LinkHandle)))
948  {
949  ZwClose(LinkHandle);
950  }
951  /* Otherwise, store it to defer deletion */
952  else
953  {
954  LinksBuffer[CurrentLinks] = LinkHandle;
955  ++CurrentLinks;
956  }
957  }
958  }
959 
960  /* No more entries means we handled all links, that's not a failure */
962  {
964  }
965 
966  /* Close all the links we stored, this will like cause their deletion */
967  for (i = 0; i < CurrentLinks; ++i)
968  {
969  ZwClose(LinksBuffer[i]);
970  }
971  /* And free our links buffer */
973 
974  /* Free our directory info buffer - it might be NULL if we failed realloc */
975  if (DirectoryInfo != NULL)
976  {
977  ExFreePoolWithTag(DirectoryInfo, TAG_SE_DIR_BUFFER);
978  }
979 
980  /* Close our session directory */
982 
983  /* And detach from system */
984  if (!UseCurrentProc)
985  {
987  }
988 
989  return Status;
990 }
991 
1007 NTSTATUS
1009  _In_ PLUID LogonLuid)
1010 {
1011  ULONG RefCount;
1012  PDEVICE_MAP DeviceMap;
1013  PSEP_LOGON_SESSION_REFERENCES CurrentSession;
1014 
1015  DPRINT("SepRmDereferenceLogonSession(%08lx:%08lx)\n",
1016  LogonLuid->HighPart, LogonLuid->LowPart);
1017 
1018  /* Acquire the database lock */
1020 
1021  /* Loop all existing sessions */
1022  for (CurrentSession = SepLogonSessions;
1023  CurrentSession != NULL;
1024  CurrentSession = CurrentSession->Next)
1025  {
1026  /* Check if the LUID matches the new one */
1027  if (RtlEqualLuid(&CurrentSession->LogonId, LogonLuid))
1028  {
1029  /* Dereference the session */
1030  RefCount = --CurrentSession->ReferenceCount;
1031  DPRINT("ReferenceCount: %lu\n", CurrentSession->ReferenceCount);
1032 
1033  /* Release the database lock */
1035 
1036  /* We're done with the session */
1037  if (RefCount == 0)
1038  {
1039  /* Get rid of the LUID device map */
1040  DeviceMap = CurrentSession->pDeviceMap;
1041  if (DeviceMap != NULL)
1042  {
1043  CurrentSession->pDeviceMap = NULL;
1045  ObfDereferenceDeviceMap(DeviceMap);
1046  }
1047 
1048  /* FIXME: Alert LSA and filesystems that a logon is about to be deleted */
1049  }
1050 
1051  return STATUS_SUCCESS;
1052  }
1053  }
1054 
1055  /* Release the database lock */
1057 
1059 }
1060 
1073 BOOLEAN
1074 NTAPI
1076 {
1077  SECURITY_QUALITY_OF_SERVICE SecurityQos;
1080  REMOTE_PORT_VIEW RemotePortView;
1081  PORT_VIEW PortView;
1082  LARGE_INTEGER SectionSize;
1083  HANDLE SectionHandle;
1084  HANDLE PortHandle;
1085  NTSTATUS Status;
1086  BOOLEAN Result;
1087 
1088  SectionHandle = NULL;
1089  PortHandle = NULL;
1090 
1091  /* Assume success */
1092  Result = TRUE;
1093 
1094  /* Wait until LSASS is ready */
1095  Status = ZwWaitForSingleObject(SeLsaInitEvent, FALSE, NULL);
1096  if (!NT_SUCCESS(Status))
1097  {
1098  DPRINT1("Security Rm Init: Waiting for LSA Init Event failed 0x%lx\n", Status);
1099  goto Cleanup;
1100  }
1101 
1102  /* We don't need this event anymore */
1104 
1105  /* Initialize the connection message */
1106  Message.Header.u1.s1.TotalLength = sizeof(Message);
1107  Message.Header.u1.s1.DataLength = 0;
1108 
1109  /* Only LSASS can connect, so handle the connection right now */
1111  if (!NT_SUCCESS(Status))
1112  {
1113  DPRINT1("Security Rm Init: Listen to Command Port failed 0x%lx\n", Status);
1114  goto Cleanup;
1115  }
1116 
1117  /* Set the Port View structure length */
1118  RemotePortView.Length = sizeof(RemotePortView);
1119 
1120  /* Accept the connection */
1122  NULL,
1123  &Message.Header,
1124  TRUE,
1125  NULL,
1126  &RemotePortView);
1127  if (!NT_SUCCESS(Status))
1128  {
1129  DPRINT1("Security Rm Init: Accept Connect to Command Port failed 0x%lx\n", Status);
1130  goto Cleanup;
1131  }
1132 
1133  /* Complete the connection */
1135  if (!NT_SUCCESS(Status))
1136  {
1137  DPRINT1("Security Rm Init: Complete Connect to Command Port failed 0x%lx\n", Status);
1138  goto Cleanup;
1139  }
1140 
1141  /* Create a section for messages */
1142  SectionSize.QuadPart = PAGE_SIZE;
1143  Status = ZwCreateSection(&SectionHandle,
1145  NULL,
1146  &SectionSize,
1148  SEC_COMMIT,
1149  NULL);
1150  if (!NT_SUCCESS(Status))
1151  {
1152  DPRINT1("Security Rm Init: Create Memory Section for LSA port failed: %X\n", Status);
1153  goto Cleanup;
1154  }
1155 
1156  /* Setup the PORT_VIEW structure */
1157  PortView.Length = sizeof(PortView);
1158  PortView.SectionHandle = SectionHandle;
1159  PortView.SectionOffset = 0;
1160  PortView.ViewSize = SectionSize.LowPart;
1161  PortView.ViewBase = NULL;
1162  PortView.ViewRemoteBase = NULL;
1163 
1164  /* Setup security QOS */
1165  SecurityQos.Length = sizeof(SecurityQos);
1168  SecurityQos.EffectiveOnly = TRUE;
1169 
1170  /* Connect to LSASS */
1171  RtlInitUnicodeString(&PortName, L"\\SeLsaCommandPort");
1172  Status = ZwConnectPort(&PortHandle,
1173  &PortName,
1174  &SecurityQos,
1175  &PortView,
1176  NULL,
1177  0,
1178  0,
1179  0);
1180  if (!NT_SUCCESS(Status))
1181  {
1182  DPRINT1("Security Rm Init: Connect to LSA Port failed 0x%lx\n", Status);
1183  goto Cleanup;
1184  }
1185 
1186  /* Remember section base and view offset */
1187  SepCommandPortViewBase = PortView.ViewBase;
1191 
1192  DPRINT("SepRmCommandServerThreadInit: done\n");
1193 
1194 Cleanup:
1195  /* Check for failure */
1196  if (!NT_SUCCESS(Status))
1197  {
1198  if (PortHandle != NULL)
1199  {
1200  ObCloseHandle(PortHandle, KernelMode);
1201  }
1202 
1203  Result = FALSE;
1204  }
1205 
1206  /* Did we create a section? */
1207  if (SectionHandle != NULL)
1208  {
1209  ObCloseHandle(SectionHandle, KernelMode);
1210  }
1211 
1212  return Result;
1213 }
1214 
1224 VOID
1225 NTAPI
1227  _In_ PVOID StartContext)
1228 {
1231  HANDLE DummyPortHandle;
1232  NTSTATUS Status;
1233 
1234  /* Initialize the server thread */
1236  {
1237  DPRINT1("Security: Terminating Rm Command Server Thread\n");
1238  return;
1239  }
1240 
1241  /* No reply yet */
1242  ReplyMessage = NULL;
1243 
1244  /* Start looping */
1245  while (TRUE)
1246  {
1247  /* Wait for a message */
1249  NULL,
1250  ReplyMessage,
1251  &Message.Header);
1252  if (!NT_SUCCESS(Status))
1253  {
1254  DPRINT1("Failed to get message: 0x%lx", Status);
1255  ReplyMessage = NULL;
1256  continue;
1257  }
1258 
1259  /* Check if this is a connection request */
1260  if (Message.Header.u2.s2.Type == LPC_CONNECTION_REQUEST)
1261  {
1262  /* Reject connection request */
1263  ZwAcceptConnectPort(&DummyPortHandle,
1264  NULL,
1265  &Message.Header,
1266  FALSE,
1267  NULL,
1268  NULL);
1269 
1270  /* Start over */
1271  ReplyMessage = NULL;
1272  continue;
1273  }
1274 
1275  /* Check if the port died */
1276  if ((Message.Header.u2.s2.Type == LPC_PORT_CLOSED) ||
1277  (Message.Header.u2.s2.Type == LPC_CLIENT_DIED))
1278  {
1279  /* LSASS is dead, so let's quit as well */
1280  break;
1281  }
1282 
1283  /* Check if this is an actual request */
1284  if (Message.Header.u2.s2.Type != LPC_REQUEST)
1285  {
1286  DPRINT1("SepRmCommandServerThread: unexpected message type: 0x%lx\n",
1287  Message.Header.u2.s2.Type);
1288 
1289  /* Restart without replying */
1290  ReplyMessage = NULL;
1291  continue;
1292  }
1293 
1294  ReplyMessage = &Message.Header;
1295 
1296  switch (Message.ApiNumber)
1297  {
1298  case RmAuditSetCommand:
1300  break;
1301 
1302  case RmCreateLogonSession:
1303  Status = SepRmCreateLogonSession(&Message.u.LogonLuid);
1304  break;
1305 
1306  case RmDeleteLogonSession:
1307  Status = SepRmDeleteLogonSession(&Message.u.LogonLuid);
1308  break;
1309 
1310  default:
1311  DPRINT1("SepRmDispatchRequest: invalid API number: 0x%lx\n",
1312  Message.ApiNumber);
1313  ReplyMessage = NULL;
1314  }
1315 
1316  Message.u.ResultStatus = Status;
1317  }
1318 
1319  /* Close the port handles */
1322 }
1323 
1324 
1325 /* PUBLIC FUNCTIONS ***********************************************************/
1326 
1345 NTSTATUS
1346 NTAPI
1348  _In_ PLUID LogonId,
1349  _Out_ PDEVICE_MAP *DeviceMap)
1350 {
1351  NTSTATUS Status;
1352  WCHAR Buffer[63];
1353  PDEVICE_MAP LocalMap;
1354  HANDLE DirectoryHandle, LinkHandle;
1356  PSEP_LOGON_SESSION_REFERENCES CurrentSession;
1357  UNICODE_STRING DirectoryName, LinkName, TargetName;
1358 
1359  PAGED_CODE();
1360 
1361  if (LogonId == NULL ||
1362  DeviceMap == NULL)
1363  {
1364  return STATUS_INVALID_PARAMETER;
1365  }
1366 
1367  /* Acquire the database lock */
1369 
1370  /* Loop all existing sessions */
1371  for (CurrentSession = SepLogonSessions;
1372  CurrentSession != NULL;
1373  CurrentSession = CurrentSession->Next)
1374  {
1375  /* Check if the LUID matches the provided one */
1376  if (RtlEqualLuid(&CurrentSession->LogonId, LogonId))
1377  {
1378  break;
1379  }
1380  }
1381 
1382  /* No session found, fail */
1383  if (CurrentSession == NULL)
1384  {
1385  /* Release the database lock */
1387 
1389  }
1390 
1391  /* The found session has a device map, return it! */
1392  if (CurrentSession->pDeviceMap != NULL)
1393  {
1394  *DeviceMap = CurrentSession->pDeviceMap;
1395 
1396  /* Release the database lock */
1398 
1399  return STATUS_SUCCESS;
1400  }
1401 
1402  /* At that point, we'll setup a new device map for the session */
1403  LocalMap = NULL;
1404 
1405  /* Reference the session so that it doesn't go away */
1406  CurrentSession->ReferenceCount += 1;
1407 
1408  /* Release the database lock */
1410 
1411  /* Create our object directory given the LUID */
1413  sizeof(Buffer) / sizeof(WCHAR),
1414  L"\\Sessions\\0\\DosDevices\\%08x-%08x",
1415  LogonId->HighPart,
1416  LogonId->LowPart);
1417  RtlInitUnicodeString(&DirectoryName, Buffer);
1418 
1420  &DirectoryName,
1422  NULL,
1423  NULL);
1426  &ObjectAttributes);
1427  if (NT_SUCCESS(Status))
1428  {
1429  /* Create the associated device map */
1431  if (NT_SUCCESS(Status))
1432  {
1433  /* Make Global point to \Global?? in the directory */
1434  RtlInitUnicodeString(&LinkName, L"Global");
1435  RtlInitUnicodeString(&TargetName, L"\\Global??");
1436 
1438  &LinkName,
1441  NULL);
1442  Status = ZwCreateSymbolicLinkObject(&LinkHandle,
1445  &TargetName);
1446  if (!NT_SUCCESS(Status))
1447  {
1448  ObfDereferenceDeviceMap(LocalMap);
1449  }
1450  else
1451  {
1452  ZwClose(LinkHandle);
1453  }
1454  }
1455 
1457  }
1458 
1459  /* Acquire the database lock */
1461 
1462  /* If we succeed... */
1463  if (NT_SUCCESS(Status))
1464  {
1465  /* The session now has a device map? We raced with someone else */
1466  if (CurrentSession->pDeviceMap != NULL)
1467  {
1468  /* Give up on our new device map */
1469  ObfDereferenceDeviceMap(LocalMap);
1470  }
1471  /* Otherwise use our newly allocated device map */
1472  else
1473  {
1474  CurrentSession->pDeviceMap = LocalMap;
1475  }
1476 
1477  /* Return the device map */
1478  *DeviceMap = CurrentSession->pDeviceMap;
1479  }
1480  /* Zero output */
1481  else
1482  {
1483  *DeviceMap = NULL;
1484  }
1485 
1486  /* Release the database lock */
1488 
1489  /* We're done with the session */
1490  SepRmDereferenceLogonSession(&CurrentSession->LogonId);
1491 
1492  return Status;
1493 }
1494 
1508 NTSTATUS
1509 NTAPI
1511  _In_ PLUID LogonId)
1512 {
1513  PSEP_LOGON_SESSION_REFERENCES SessionToMark;
1514  PAGED_CODE();
1515 
1516  DPRINT("SeMarkLogonSessionForTerminationNotification(%08lx:%08lx)\n",
1517  LogonId->HighPart, LogonId->LowPart);
1518 
1519  /* Acquire the database lock */
1521 
1522  /* Loop over the existing logon sessions */
1523  for (SessionToMark = SepLogonSessions;
1524  SessionToMark != NULL;
1525  SessionToMark = SessionToMark->Next)
1526  {
1527  /* Does the logon with the given ID exist? */
1528  if (RtlEqualLuid(&SessionToMark->LogonId, LogonId))
1529  {
1530  /* We found it */
1531  break;
1532  }
1533  }
1534 
1535  /*
1536  * We've exhausted all the remaining logon sessions and
1537  * couldn't find one with the provided ID.
1538  */
1539  if (SessionToMark == NULL)
1540  {
1541  DPRINT1("SeMarkLogonSessionForTerminationNotification(): Logon session couldn't be found!\n");
1543  return STATUS_NOT_FOUND;
1544  }
1545 
1546  /* Mark the logon session for termination */
1547  SessionToMark->Flags |= SEP_LOGON_SESSION_TERMINATION_NOTIFY;
1548  DPRINT("SeMarkLogonSessionForTerminationNotification(): Logon session marked for termination with success!\n");
1549 
1550  /* Release the database lock */
1552  return STATUS_SUCCESS;
1553 }
1554 
1570 NTSTATUS
1571 NTAPI
1574 {
1576  PAGED_CODE();
1577 
1578  /* Fail, if we don not have a callback routine */
1579  if (CallbackRoutine == NULL)
1580  return STATUS_INVALID_PARAMETER;
1581 
1582  /* Allocate a new notification item */
1586  if (Notification == NULL)
1588 
1589  /* Acquire the database lock */
1591 
1592  /* Set the callback routine */
1593  Notification->CallbackRoutine = CallbackRoutine;
1594 
1595  /* Insert the new notification item into the list */
1598 
1599  /* Release the database lock */
1601 
1602  return STATUS_SUCCESS;
1603 }
1604 
1619 NTSTATUS
1620 NTAPI
1623 {
1625  NTSTATUS Status;
1626  PAGED_CODE();
1627 
1628  /* Fail, if we don not have a callback routine */
1629  if (CallbackRoutine == NULL)
1630  return STATUS_INVALID_PARAMETER;
1631 
1632  /* Acquire the database lock */
1634 
1635  /* Loop all registered notification items */
1636  for (Current = SepLogonNotifications;
1637  Current != NULL;
1638  Current = Current->Next)
1639  {
1640  /* Check if the callback routine matches the provided one */
1641  if (Current->CallbackRoutine == CallbackRoutine)
1642  break;
1643 
1644  Previous = Current;
1645  }
1646 
1647  if (Current == NULL)
1648  {
1650  }
1651  else
1652  {
1653  /* Remove the current notification item from the list */
1654  if (Previous == NULL)
1655  SepLogonNotifications = Current->Next;
1656  else
1657  Previous->Next = Current->Next;
1658 
1659  /* Free the current notification item */
1660  ExFreePoolWithTag(Current,
1662 
1664  }
1665 
1666  /* Release the database lock */
1668 
1669  return Status;
1670 }
1671 
1672 /* EOF */
NTSTATUS NTAPI SeRegisterLogonSessionTerminatedRoutine(_In_ PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine)
Registers a callback that will be called once a logon session terminates.
Definition: srm.c:1572
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSTATUS SepRmReferenceLogonSession(_In_ PLUID LogonLuid)
References a logon session.
Definition: srm.c:695
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
const uint16_t * PCWSTR
Definition: typedefs.h:57
NTSYSAPI NTSTATUS NTAPI ZwListenPort(_In_ HANDLE PortHandle, _In_ PPORT_MESSAGE ConnectionRequest)
#define STATUS_BAD_LOGON_SESSION_STATE
Definition: ntstatus.h:496
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
HANDLE SeRmCommandPort
Definition: srm.c:18
struct _SEP_LOGON_SESSION_TERMINATED_NOTIFICATION SEP_LOGON_SESSION_TERMINATED_NOTIFICATION
KAPC_STATE
Definition: ketypes.h:1280
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
BOOLEAN NTAPI SeRmInitPhase0(VOID)
Manages the phase 0 initialization of the security reference monitoring module of the kernel.
Definition: srm.c:176
BOOLEAN SepAdtAuditingEnabled
Definition: srm.c:54
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define _Inout_
Definition: ms_sal.h:378
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN _In_ ULONG _In_opt_ PULONG _In_ BOOLEAN RestartScan
Definition: fltkernel.h:2297
static NTSTATUS SepRmCreateLogonSession(_In_ PLUID LogonLuid)
Creates a logon session. The security reference monitoring (SRM) module of Executive uses this as an ...
Definition: srm.c:512
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define SEP_LOGON_SESSION_TERMINATION_NOTIFY
Definition: setypes.h:695
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define _Out_
Definition: ms_sal.h:345
NTSYSAPI NTSTATUS NTAPI ZwCompleteConnectPort(_In_ HANDLE PortHandle)
#define REG_BINARY
Definition: nt_native.h:1496
#define STATUS_NO_SUCH_LOGON_SESSION
Definition: ntstatus.h:331
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
VOID FASTCALL ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap)
Definition: devicemap.c:477
NTSYSAPI NTSTATUS NTAPI ZwAcceptConnectPort(_Out_ PHANDLE PortHandle, _In_opt_ PVOID PortContext, _In_ PPORT_MESSAGE ConnectionRequest, _In_ BOOLEAN AcceptConnection, _In_opt_ PPORT_VIEW ServerView, _In_opt_ PREMOTE_PORT_VIEW ClientView)
ULONG SepAdtMinListLength
Definition: srm.c:55
LONG NTSTATUS
Definition: precomp.h:26
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
static HANDLE DirectoryHandle
Definition: ObType.c:48
NTSYSAPI NTSTATUS NTAPI ZwOpenDirectoryObject(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
ULONG SectionOffset
static NTSTATUS SepRmSetAuditEvent(_Inout_ PSEP_RM_API_MESSAGE Message)
Sets an audit event for future security auditing monitoring.
Definition: srm.c:324
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287
PVOID SepCommandPortViewRemoteBase
Definition: srm.c:49
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
static NTSTATUS SepRmDeleteLogonSession(_In_ PLUID LogonLuid)
Deletes a logon session from the logon sessions database.
Definition: srm.c:590
#define TAG_LOGON_SESSION
Definition: tag.h:186
#define OBJ_OPENIF
Definition: winternl.h:229
NTSTATUS NTAPI SeUnregisterLogonSessionTerminatedRoutine(_In_ PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine)
Un-registers a callback routine, previously registered by SeRegisterLogonSessionTerminatedRoutine fun...
Definition: srm.c:1621
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
BOOLEAN FASTCALL ObReferenceObjectSafe(IN PVOID Object)
Definition: obref.c:22
struct _SEP_LOGON_SESSION_TERMINATED_NOTIFICATION * PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID SepCommandPortViewBase
Definition: srm.c:48
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
_Must_inspect_result_ _In_ PFLT_GET_OPERATION_STATUS_CALLBACK CallbackRoutine
Definition: fltkernel.h:1035
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
ULONG SepAdtMaxListLength
Definition: srm.c:56
#define TAG_SE_DIR_BUFFER
Definition: tag.h:183
ULONG_PTR SepCommandPortViewBaseOffset
Definition: srm.c:50
static HANDLE SepRmCommandMessagePort
Definition: srm.c:52
#define SEC_COMMIT
Definition: mmtypes.h:99
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
NTSTATUS NTAPI ObSetDirectoryDeviceMap(OUT PDEVICE_MAP *DeviceMap, IN HANDLE DirectoryHandle)
Definition: devicemap.c:149
#define GENERIC_WRITE
Definition: nt_native.h:90
PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine
Definition: srm.c:21
struct NameRec_ * Name
Definition: cdprocs.h:459
#define PsGetCurrentProcess
Definition: psfuncs.h:17
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
unsigned char BOOLEAN
#define TAG_LOGON_NOTIFICATION
Definition: tag.h:187
LPC_PVOID ViewRemoteBase
UCHAR SeAuditingState[POLICY_AUDIT_EVENT_TYPE_COUNT]
Definition: srm.c:59
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define STATUS_LOGON_SESSION_EXISTS
Definition: ntstatus.h:474
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define _In_
Definition: ms_sal.h:308
NTSTATUS NTAPI SepRegQueryHelper(_In_ PCWSTR KeyName, _In_ PCWSTR ValueName, _In_ ULONG ValueType, _In_ ULONG DataLength, _Out_ PVOID ValueData)
A private registry helper that returns the desired value data based on the specifics requested by the...
Definition: srm.c:93
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1437
Definition: bufpool.h:45
BOOL WINAPI ReplyMessage(_In_ LRESULT)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
#define POLICY_AUDIT_EVENT_TYPE_COUNT
Definition: srm.c:58
NTSTATUS NTAPI SepRmRemoveLogonSessionFromToken(_Inout_ PTOKEN Token)
Removes a logon session from an access token.
Definition: srm.c:449
BOOLEAN NTAPI SepRmCommandServerThreadInit(VOID)
Main SRM server thread initialization function. It deals with security manager and LSASS port connect...
Definition: srm.c:1075
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI ZwConnectPort(_Out_ PHANDLE PortHandle, _In_ PUNICODE_STRING PortName, _In_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, _In_opt_ PPORT_VIEW ClientView, _In_opt_ PREMOTE_PORT_VIEW ServerView, _In_opt_ PULONG MaxMessageLength, _In_opt_ PVOID ConnectionInformation, _In_opt_ PULONG ConnectionInformationLength)
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LPC_SIZE_T ViewSize
NTSYSAPI NTSTATUS NTAPI ZwCreateSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ PUNICODE_STRING Name)
NTSTATUS(NTAPI * PSE_LOGON_SESSION_TERMINATED_ROUTINE)(IN PLUID LogonId)
Definition: setypes.h:1228
#define ObDereferenceObject
Definition: obfuncs.h:203
LUID SeAnonymousAuthenticationId
Definition: token.c:23
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
struct _SEP_LOGON_SESSION_REFERENCES * Next
Definition: setypes.h:159
PVOID HANDLE
Definition: typedefs.h:73
LUID SeSystemAuthenticationId
Definition: token.c:22
#define TAG_SE_HANDLES_TAB
Definition: tag.h:182
CHAR Message[80]
Definition: alive.c:5
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3375
#define SECURITY_DYNAMIC_TRACKING
Definition: setypes.h:103
PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION SepLogonNotifications
Definition: srm.c:63
static const WCHAR L[]
Definition: oid.c:1250
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
#define OBJ_PERMANENT
Definition: winternl.h:226
ULONG LowPart
Definition: typedefs.h:106
VOID NTAPI SepRmCommandServerThread(_In_ PVOID StartContext)
Manages the SRM server API commands, that is, receiving such API command messages from the user mode ...
Definition: srm.c:1226
WCHAR TargetName[256]
Definition: arping.c:27
#define PAGE_SIZE
Definition: env_spec_w32.h:49
HANDLE SeLsaInitEvent
Definition: srm.c:46
NTSYSAPI NTSTATUS NTAPI ZwReplyWaitReceivePort(_In_ HANDLE PortHandle, _Out_opt_ PVOID *PortContext, _In_opt_ PPORT_MESSAGE ReplyMessage, _Out_ PPORT_MESSAGE ReceiveMessage)
KPROCESS Pcb
Definition: pstypes.h:1262
static const WCHAR Cleanup[]
Definition: register.c:80
_In_ PWDFDEVICE_INIT _In_ PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION Notification
Definition: wdfcontrol.h:113
NTSTATUS NTAPI SepRmInsertLogonSessionIntoToken(_Inout_ PTOKEN Token)
Inserts a logon session into an access token specified by the caller.
Definition: srm.c:368
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static VOID SepAdtInitializeBounds(VOID)
Initializes the local security authority audit bounds.
Definition: srm.c:274
LPC_PVOID ViewBase
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
struct _SEP_LOGON_SESSION_TERMINATED_NOTIFICATION * Next
Definition: srm.c:20
#define PORT_MAXIMUM_MESSAGE_LENGTH
Definition: iotypes.h:2029
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
PSEP_LOGON_SESSION_REFERENCES SepLogonSessions
Definition: srm.c:62
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1679
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID LogonId
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
static NTSTATUS SepCleanupLUIDDeviceMapDirectory(_In_ PLUID LogonLuid)
Cleans the DOS device map directory of a logon session.
Definition: srm.c:751
struct tagContext Context
Definition: acpixf.h:1034
BOOLEAN NTAPI SeRmInitPhase1(VOID)
Manages the phase 1 initialization of the security reference monitoring module of the kernel.
Definition: srm.c:211
unsigned int ULONG
Definition: retypes.h:1
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSTATUS NTAPI SeMarkLogonSessionForTerminationNotification(_In_ PLUID LogonId)
Marks a logon session for future termination, given its logon ID. This triggers a callout (the regist...
Definition: srm.c:1510
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
NTSYSAPI NTSTATUS NTAPI ZwCreatePort(_Out_ PHANDLE PortHandle, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ ULONG MaxConnectionInfoLength, _In_ ULONG MaxMessageLength, _In_ ULONG MaxPoolUsage)
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
LPC_HANDLE SectionHandle
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSYSAPI NTSTATUS NTAPI ZwMakeTemporaryObject(_In_ HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSTATUS NTAPI SeGetLogonIdDeviceMap(_In_ PLUID LogonId, _Out_ PDEVICE_MAP *DeviceMap)
Retrieves the DOS device map from a logon session.
Definition: srm.c:1347
LONGLONG QuadPart
Definition: typedefs.h:114
NTSTATUS SepRmDereferenceLogonSession(_In_ PLUID LogonLuid)
De-references a logon session. If the session has a reference count of 0 by the time the function has...
Definition: srm.c:1008
UNICODE_STRING TypeName
Definition: obtypes.h:279
#define PAGE_READWRITE
Definition: nt_native.h:1304
IN PUNICODE_STRING PortName
Definition: conport.c:35
#define PAGED_CODE()
KGUARDED_MUTEX SepRmDbLock
Definition: srm.c:61