ReactOS  0.4.13-dev-563-g0561610
srm.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: ntoskrnl/se/srm.c
5  * PURPOSE: Security Reference Monitor Server
6  *
7  * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
8  * Pierre Schweitzer (pierre@reactos.org)
9  */
10 
11 /* INCLUDES *******************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 
19 
20 /* PRIVATE DEFINITIONS ********************************************************/
21 
22 #define SEP_LOGON_SESSION_TAG 'sLeS'
23 
25 {
33 
34 VOID
35 NTAPI
37  PVOID StartContext);
38 
39 static
42  PLUID LogonLuid);
43 
44 
45 /* GLOBALS ********************************************************************/
46 
49 
53 
55 
59 
60 #define POLICY_AUDIT_EVENT_TYPE_COUNT 9 // (AuditCategoryAccountLogon - AuditCategorySystem + 1)
62 
65 
66 
67 /* PRIVATE FUNCTIONS **********************************************************/
68 
70 NTAPI
77 {
78  UNICODE_STRING ValueNameString;
79  UNICODE_STRING KeyNameString;
83  struct
84  {
86  UCHAR Buffer[64];
87  } KeyValueInformation;
88  NTSTATUS Status, CloseStatus;
89  PAGED_CODE();
90 
91  RtlInitUnicodeString(&KeyNameString, KeyName);
93  &KeyNameString,
95  NULL,
96  NULL);
97 
99  if (!NT_SUCCESS(Status))
100  {
101  return Status;
102  }
103 
104  RtlInitUnicodeString(&ValueNameString, ValueName);
105  Status = ZwQueryValueKey(KeyHandle,
106  &ValueNameString,
108  &KeyValueInformation.Partial,
109  sizeof(KeyValueInformation),
110  &ResultLength);
111  if (!NT_SUCCESS(Status))
112  {
113  goto Cleanup;
114  }
115 
116  if ((KeyValueInformation.Partial.Type != ValueType) ||
117  (KeyValueInformation.Partial.DataLength != DataLength))
118  {
120  goto Cleanup;
121  }
122 
123 
124  if (ValueType == REG_BINARY)
125  {
126  RtlCopyMemory(ValueData, KeyValueInformation.Partial.Data, DataLength);
127  }
128  else if (ValueType == REG_DWORD)
129  {
130  *(PULONG)ValueData = *(PULONG)KeyValueInformation.Partial.Data;
131  }
132  else
133  {
135  }
136 
137 Cleanup:
138  CloseStatus = ZwClose(KeyHandle);
139  ASSERT(NT_SUCCESS( CloseStatus ));
140 
141  return Status;
142 }
143 
144 
145 BOOLEAN
146 NTAPI
148 {
150 
151  /* Initialize the database lock */
153 
154  /* Create the system logon session */
156  if (!NT_VERIFY(NT_SUCCESS(Status)))
157  {
158  return FALSE;
159  }
160 
161  /* Create the anonymous logon session */
163  if (!NT_VERIFY(NT_SUCCESS(Status)))
164  {
165  return FALSE;
166  }
167 
168  return TRUE;
169 }
170 
171 
172 BOOLEAN
173 NTAPI
175 {
178  HANDLE ThreadHandle;
180 
181  /* Create the SeRm command port */
182  RtlInitUnicodeString(&Name, L"\\SeRmCommandPort");
186  sizeof(ULONG),
188  2 * PAGE_SIZE);
189  if (!NT_SUCCESS(Status))
190  {
191  DPRINT1("Security: Rm Create Command Port failed 0x%lx\n", Status);
192  return FALSE;
193  }
194 
195  /* Create SeLsaInitEvent */
196  RtlInitUnicodeString(&Name, L"\\SeLsaInitEvent");
198  Status = ZwCreateEvent(&SeLsaInitEvent,
202  FALSE);
203  if (!NT_VERIFY((NT_SUCCESS(Status))))
204  {
205  DPRINT1("Security: LSA init event creation failed.0x%xl\n", Status);
206  return FALSE;
207  }
208 
209  /* Create the SeRm server thread */
210  Status = PsCreateSystemThread(&ThreadHandle,
212  NULL,
213  NULL,
214  NULL,
216  NULL);
217  if (!NT_SUCCESS(Status))
218  {
219  DPRINT1("Security: Rm Server Thread creation failed 0x%lx\n", Status);
220  return FALSE;
221  }
222 
223  ObCloseHandle(ThreadHandle, KernelMode);
224 
225  return TRUE;
226 }
227 
228 static
229 VOID
231 {
232  struct
233  {
234  ULONG MaxLength;
235  ULONG MinLength;
236  } ListBounds;
238  PAGED_CODE();
239 
240  Status = SepRegQueryHelper(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Lsa",
241  L"Bounds",
242  REG_BINARY,
243  sizeof(ListBounds),
244  &ListBounds);
245  if (!NT_SUCCESS(Status))
246  {
247  /* No registry values, so keep hardcoded defaults */
248  return;
249  }
250 
251  /* Check if the bounds are valid */
252  if ((ListBounds.MaxLength < ListBounds.MinLength) ||
253  (ListBounds.MinLength < 16) ||
254  (ListBounds.MaxLength - ListBounds.MinLength < 16))
255  {
256  DPRINT1("ListBounds are invalid: %u, %u\n",
257  ListBounds.MinLength, ListBounds.MaxLength);
258  return;
259  }
260 
261  /* Set the new bounds globally */
262  SepAdtMinListLength = ListBounds.MinLength;
263  SepAdtMaxListLength = ListBounds.MaxLength;
264 }
265 
266 
267 static
268 NTSTATUS
271 {
272  ULONG i;
273  PAGED_CODE();
274 
275  /* First re-initialize the bounds from the registry */
277 
278  /* Make sure we have the right message and clear */
279  ASSERT(Message->ApiNumber == RmAuditSetCommand);
280  Message->ApiNumber = 0;
281 
282  /* Store the enable flag in the global variable */
283  SepAdtAuditingEnabled = Message->u.SetAuditEvent.Enabled;
284 
285  /* Loop all audit event types */
286  for (i = 0; i < POLICY_AUDIT_EVENT_TYPE_COUNT; i++)
287  {
288  /* Save the provided flags in the global array */
289  SeAuditingState[i] = (UCHAR)Message->u.SetAuditEvent.Flags[i];
290  }
291 
292  return STATUS_SUCCESS;
293 }
294 
295 
296 static
297 NTSTATUS
299  PLUID LogonLuid)
300 {
301  PSEP_LOGON_SESSION_REFERENCES CurrentSession, NewSession;
303  PAGED_CODE();
304 
305  DPRINT("SepRmCreateLogonSession(%08lx:%08lx)\n",
306  LogonLuid->HighPart, LogonLuid->LowPart);
307 
308  /* Allocate a new session structure */
309  NewSession = ExAllocatePoolWithTag(PagedPool,
312  if (NewSession == NULL)
313  {
315  }
316 
317  /* Initialize it */
318  NewSession->LogonId = *LogonLuid;
319  NewSession->ReferenceCount = 0;
320  NewSession->Flags = 0;
321  NewSession->pDeviceMap = NULL;
322  InitializeListHead(&NewSession->TokenList);
323 
324  /* Acquire the database lock */
326 
327  /* Loop all existing sessions */
328  for (CurrentSession = SepLogonSessions;
329  CurrentSession != NULL;
330  CurrentSession = CurrentSession->Next)
331  {
332  /* Check if the LUID matches the new one */
333  if (RtlEqualLuid(&CurrentSession->LogonId, LogonLuid))
334  {
336  goto Leave;
337  }
338  }
339 
340  /* Insert the new session */
341  NewSession->Next = SepLogonSessions;
342  SepLogonSessions = NewSession;
343 
345 
346 Leave:
347  /* Release the database lock */
349 
350  if (!NT_SUCCESS(Status))
351  {
353  }
354 
355  return Status;
356 }
357 
358 static
359 NTSTATUS
361  PLUID LogonLuid)
362 {
363  DPRINT("SepRmDeleteLogonSession(%08lx:%08lx)\n",
364  LogonLuid->HighPart, LogonLuid->LowPart);
365 
367  NT_ASSERT(FALSE);
368  return STATUS_NOT_IMPLEMENTED;
369 }
370 
371 
372 NTSTATUS
374  PLUID LogonLuid)
375 {
376  PSEP_LOGON_SESSION_REFERENCES CurrentSession;
377 
378  PAGED_CODE();
379 
380  DPRINT("SepRmReferenceLogonSession(%08lx:%08lx)\n",
381  LogonLuid->HighPart, LogonLuid->LowPart);
382 
383  /* Acquire the database lock */
385 
386  /* Loop all existing sessions */
387  for (CurrentSession = SepLogonSessions;
388  CurrentSession != NULL;
389  CurrentSession = CurrentSession->Next)
390  {
391  /* Check if the LUID matches the new one */
392  if (RtlEqualLuid(&CurrentSession->LogonId, LogonLuid))
393  {
394  /* Reference the session */
395  ++CurrentSession->ReferenceCount;
396  DPRINT("ReferenceCount: %lu\n", CurrentSession->ReferenceCount);
397 
398  /* Release the database lock */
400 
401  return STATUS_SUCCESS;
402  }
403  }
404 
405  /* Release the database lock */
407 
409 }
410 
411 
412 NTSTATUS
414  PLUID LogonLuid)
415 {
416  BOOLEAN UseCurrentProc;
418  WCHAR Buffer[63];
419  UNICODE_STRING DirectoryName;
422  HANDLE DirectoryHandle, LinkHandle;
423  PHANDLE LinksBuffer;
424  POBJECT_DIRECTORY_INFORMATION DirectoryInfo;
425  ULONG LinksCount, LinksSize, DirInfoLength, ReturnLength, Context, CurrentLinks, i;
427 
428  PAGED_CODE();
429 
430  /* We need a logon LUID */
431  if (LogonLuid == NULL)
432  {
434  }
435 
436  /* Use current process */
437  UseCurrentProc = ObReferenceObjectSafe(PsGetCurrentProcess());
438  if (UseCurrentProc)
439  {
441  }
442  /* Unless it's gone, then use system process */
443  else
444  {
446  }
447 
448  /* Initialize our directory name */
450  sizeof(Buffer) / sizeof(WCHAR),
451  L"\\Sessions\\0\\DosDevices\\%08x-%08x",
452  LogonLuid->HighPart,
453  LogonLuid->LowPart);
454  RtlInitUnicodeString(&DirectoryName, Buffer);
455 
456  /* And open it */
458  &DirectoryName,
460  NULL,
461  NULL);
465  if (!NT_SUCCESS(Status))
466  {
467  if (!UseCurrentProc)
468  {
470  }
471 
472  return Status;
473  }
474 
475  /* Some initialization needed for browsing all our links... */
476  Context = 0;
477  DirectoryInfo = NULL;
478  DirInfoLength = 0;
479  /* In our buffer, we'll store at max 100 HANDLE */
480  LinksCount = 100;
481  CurrentLinks = 0;
482  /* Which gives a certain size */
483  LinksSize = LinksCount * sizeof(HANDLE);
484 
485  /*
486  * This label is hit if we need to store more than a hundred
487  * of links. In that case, we jump here after having cleaned
488  * and deleted previous buffer.
489  * All handles have been already closed
490  */
491 AllocateLinksAgain:
492  LinksBuffer = ExAllocatePoolWithTag(PagedPool,
493  LinksSize,
495  if (LinksBuffer == NULL)
496  {
497  /*
498  * Failure path: no need to clear handles:
499  * already closed and the buffer is already gone
500  */
502 
503  /*
504  * On the first round, DirectoryInfo is NULL,
505  * if we grow LinksBuffer, it has been allocated
506  */
507  if (DirectoryInfo != NULL)
508  {
509  ExFreePoolWithTag(DirectoryInfo, TAG_SE_DIR_BUFFER);
510  }
511 
512  if (!UseCurrentProc)
513  {
515  }
516 
517  return STATUS_NO_MEMORY;
518  }
519 
520  /*
521  * We always restart scan, but on the first loop
522  * if we couldn't fit everything in our buffer,
523  * then, we continue scan.
524  * But we restart if link buffer was too small
525  */
526  for (RestartScan = TRUE; ; RestartScan = FALSE)
527  {
528  /*
529  * Loop until our buffer is big enough to store
530  * one entry
531  */
532  while (TRUE)
533  {
534  Status = ZwQueryDirectoryObject(DirectoryHandle,
535  DirectoryInfo,
536  DirInfoLength,
537  TRUE,
538  RestartScan,
539  &Context,
540  &ReturnLength);
541  /* Only handle buffer growth in that loop */
543  {
544  break;
545  }
546 
547  /* Get output length as new length */
548  DirInfoLength = ReturnLength;
549  /* Delete old buffer if any */
550  if (DirectoryInfo != NULL)
551  {
552  ExFreePoolWithTag(DirectoryInfo, 'bDeS');
553  }
554 
555  /* And reallocate a bigger one */
556  DirectoryInfo = ExAllocatePoolWithTag(PagedPool,
557  DirInfoLength,
559  /* Fail if we cannot allocate */
560  if (DirectoryInfo == NULL)
561  {
563  break;
564  }
565  }
566 
567  /* If querying the entry failed, quit */
568  if (!NT_SUCCESS(Status))
569  {
570  break;
571  }
572 
573  /* We only look for symbolic links, the rest, we ignore */
574  if (wcscmp(DirectoryInfo->TypeName.Buffer, L"SymbolicLink"))
575  {
576  continue;
577  }
578 
579  /* If our link buffer is out of space, reallocate */
580  if (CurrentLinks >= LinksCount)
581  {
582  /* First, close the links */
583  for (i = 0; i < CurrentLinks; ++i)
584  {
585  ZwClose(LinksBuffer[i]);
586  }
587 
588  /* Allow 20 more HANDLEs */
589  LinksCount += 20;
590  CurrentLinks = 0;
592  LinksSize = LinksCount * sizeof(HANDLE);
593 
594  /* And reloop again */
595  goto AllocateLinksAgain;
596  }
597 
598  /* Open the found link */
600  &DirectoryInfo->Name,
603  NULL);
604  if (NT_SUCCESS(ZwOpenSymbolicLinkObject(&LinkHandle,
606  &ObjectAttributes)))
607  {
608  /* If we cannot make it temporary, just close the link handle */
609  if (!NT_SUCCESS(ZwMakeTemporaryObject(LinkHandle)))
610  {
611  ZwClose(LinkHandle);
612  }
613  /* Otherwise, store it to defer deletion */
614  else
615  {
616  LinksBuffer[CurrentLinks] = LinkHandle;
617  ++CurrentLinks;
618  }
619  }
620  }
621 
622  /* No more entries means we handled all links, that's not a failure */
624  {
626  }
627 
628  /* Close all the links we stored, this will like cause their deletion */
629  for (i = 0; i < CurrentLinks; ++i)
630  {
631  ZwClose(LinksBuffer[i]);
632  }
633  /* And free our links buffer */
635 
636  /* Free our directory info buffer - it might be NULL if we failed realloc */
637  if (DirectoryInfo != NULL)
638  {
639  ExFreePoolWithTag(DirectoryInfo, TAG_SE_DIR_BUFFER);
640  }
641 
642  /* Close our session directory */
644 
645  /* And detach from system */
646  if (!UseCurrentProc)
647  {
649  }
650 
651  return Status;
652 }
653 
654 
655 NTSTATUS
657  PLUID LogonLuid)
658 {
659  ULONG RefCount;
660  PDEVICE_MAP DeviceMap;
661  PSEP_LOGON_SESSION_REFERENCES CurrentSession;
662 
663  DPRINT("SepRmDereferenceLogonSession(%08lx:%08lx)\n",
664  LogonLuid->HighPart, LogonLuid->LowPart);
665 
666  /* Acquire the database lock */
668 
669  /* Loop all existing sessions */
670  for (CurrentSession = SepLogonSessions;
671  CurrentSession != NULL;
672  CurrentSession = CurrentSession->Next)
673  {
674  /* Check if the LUID matches the new one */
675  if (RtlEqualLuid(&CurrentSession->LogonId, LogonLuid))
676  {
677  /* Dereference the session */
678  RefCount = --CurrentSession->ReferenceCount;
679  DPRINT("ReferenceCount: %lu\n", CurrentSession->ReferenceCount);
680 
681  /* Release the database lock */
683 
684  /* We're done with the session */
685  if (RefCount == 0)
686  {
687  /* Get rid of the LUID device map */
688  DeviceMap = CurrentSession->pDeviceMap;
689  if (DeviceMap != NULL)
690  {
691  CurrentSession->pDeviceMap = NULL;
693  ObfDereferenceDeviceMap(DeviceMap);
694  }
695  }
696 
697  return STATUS_SUCCESS;
698  }
699  }
700 
701  /* Release the database lock */
703 
705 }
706 
707 
708 BOOLEAN
709 NTAPI
711 {
712  SECURITY_QUALITY_OF_SERVICE SecurityQos;
715  REMOTE_PORT_VIEW RemotePortView;
716  PORT_VIEW PortView;
717  LARGE_INTEGER SectionSize;
718  HANDLE SectionHandle;
719  HANDLE PortHandle;
721  BOOLEAN Result;
722 
723  SectionHandle = NULL;
724  PortHandle = NULL;
725 
726  /* Assume success */
727  Result = TRUE;
728 
729  /* Wait until LSASS is ready */
730  Status = ZwWaitForSingleObject(SeLsaInitEvent, FALSE, NULL);
731  if (!NT_SUCCESS(Status))
732  {
733  DPRINT1("Security Rm Init: Waiting for LSA Init Event failed 0x%lx\n", Status);
734  goto Cleanup;
735  }
736 
737  /* We don't need this event anymore */
739 
740  /* Initialize the connection message */
741  Message.Header.u1.s1.TotalLength = sizeof(Message);
742  Message.Header.u1.s1.DataLength = 0;
743 
744  /* Only LSASS can connect, so handle the connection right now */
746  if (!NT_SUCCESS(Status))
747  {
748  DPRINT1("Security Rm Init: Listen to Command Port failed 0x%lx\n", Status);
749  goto Cleanup;
750  }
751 
752  /* Set the Port View structure length */
753  RemotePortView.Length = sizeof(RemotePortView);
754 
755  /* Accept the connection */
757  NULL,
758  &Message.Header,
759  TRUE,
760  NULL,
761  &RemotePortView);
762  if (!NT_SUCCESS(Status))
763  {
764  DPRINT1("Security Rm Init: Accept Connect to Command Port failed 0x%lx\n", Status);
765  goto Cleanup;
766  }
767 
768  /* Complete the connection */
770  if (!NT_SUCCESS(Status))
771  {
772  DPRINT1("Security Rm Init: Complete Connect to Command Port failed 0x%lx\n", Status);
773  goto Cleanup;
774  }
775 
776  /* Create a section for messages */
777  SectionSize.QuadPart = PAGE_SIZE;
778  Status = ZwCreateSection(&SectionHandle,
780  NULL,
781  &SectionSize,
783  SEC_COMMIT,
784  NULL);
785  if (!NT_SUCCESS(Status))
786  {
787  DPRINT1("Security Rm Init: Create Memory Section for LSA port failed: %X\n", Status);
788  goto Cleanup;
789  }
790 
791  /* Setup the PORT_VIEW structure */
792  PortView.Length = sizeof(PortView);
793  PortView.SectionHandle = SectionHandle;
794  PortView.SectionOffset = 0;
795  PortView.ViewSize = SectionSize.LowPart;
796  PortView.ViewBase = NULL;
797  PortView.ViewRemoteBase = NULL;
798 
799  /* Setup security QOS */
800  SecurityQos.Length = sizeof(SecurityQos);
803  SecurityQos.EffectiveOnly = TRUE;
804 
805  /* Connect to LSASS */
806  RtlInitUnicodeString(&PortName, L"\\SeLsaCommandPort");
807  Status = ZwConnectPort(&PortHandle,
808  &PortName,
809  &SecurityQos,
810  &PortView,
811  NULL,
812  0,
813  0,
814  0);
815  if (!NT_SUCCESS(Status))
816  {
817  DPRINT1("Security Rm Init: Connect to LSA Port failed 0x%lx\n", Status);
818  goto Cleanup;
819  }
820 
821  /* Remember section base and view offset */
822  SepCommandPortViewBase = PortView.ViewBase;
826 
827  DPRINT("SepRmCommandServerThreadInit: done\n");
828 
829 Cleanup:
830  /* Check for failure */
831  if (!NT_SUCCESS(Status))
832  {
833  if (PortHandle != NULL)
834  {
835  ObCloseHandle(PortHandle, KernelMode);
836  }
837 
838  Result = FALSE;
839  }
840 
841  /* Did we create a section? */
842  if (SectionHandle != NULL)
843  {
844  ObCloseHandle(SectionHandle, KernelMode);
845  }
846 
847  return Result;
848 }
849 
850 VOID
851 NTAPI
853  PVOID StartContext)
854 {
857  HANDLE DummyPortHandle;
859 
860  /* Initialize the server thread */
862  {
863  DPRINT1("Security: Terminating Rm Command Server Thread\n");
864  return;
865  }
866 
867  /* No reply yet */
868  ReplyMessage = NULL;
869 
870  /* Start looping */
871  while (TRUE)
872  {
873  /* Wait for a message */
875  NULL,
876  ReplyMessage,
877  &Message.Header);
878  if (!NT_SUCCESS(Status))
879  {
880  DPRINT1("Failed to get message: 0x%lx", Status);
881  ReplyMessage = NULL;
882  continue;
883  }
884 
885  /* Check if this is a connection request */
886  if (Message.Header.u2.s2.Type == LPC_CONNECTION_REQUEST)
887  {
888  /* Reject connection request */
889  ZwAcceptConnectPort(&DummyPortHandle,
890  NULL,
891  &Message.Header,
892  FALSE,
893  NULL,
894  NULL);
895 
896  /* Start over */
897  ReplyMessage = NULL;
898  continue;
899  }
900 
901  /* Check if the port died */
902  if ((Message.Header.u2.s2.Type == LPC_PORT_CLOSED) ||
903  (Message.Header.u2.s2.Type == LPC_CLIENT_DIED))
904  {
905  /* LSASS is dead, so let's quit as well */
906  break;
907  }
908 
909  /* Check if this is an actual request */
910  if (Message.Header.u2.s2.Type != LPC_REQUEST)
911  {
912  DPRINT1("SepRmCommandServerThread: unexpected message type: 0x%lx\n",
913  Message.Header.u2.s2.Type);
914 
915  /* Restart without replying */
916  ReplyMessage = NULL;
917  continue;
918  }
919 
920  ReplyMessage = &Message.Header;
921 
922  switch (Message.ApiNumber)
923  {
924  case RmAuditSetCommand:
926  break;
927 
929  Status = SepRmCreateLogonSession(&Message.u.LogonLuid);
930  break;
931 
933  Status = SepRmDeleteLogonSession(&Message.u.LogonLuid);
934  break;
935 
936  default:
937  DPRINT1("SepRmDispatchRequest: invalid API number: 0x%lx\n",
938  Message.ApiNumber);
939  ReplyMessage = NULL;
940  }
941 
942  Message.u.ResultStatus = Status;
943  }
944 
945  /* Close the port handles */
948 }
949 
950 
951 /* PUBLIC FUNCTIONS ***********************************************************/
952 
953 /*
954  * @unimplemented
955  */
956 NTSTATUS
957 NTAPI
959  IN PLUID LogonId,
960  OUT PDEVICE_MAP * DeviceMap
961  )
962 {
964  WCHAR Buffer[63];
965  PDEVICE_MAP LocalMap;
966  HANDLE DirectoryHandle, LinkHandle;
968  PSEP_LOGON_SESSION_REFERENCES CurrentSession;
969  UNICODE_STRING DirectoryName, LinkName, TargetName;
970 
971  PAGED_CODE();
972 
973  if (LogonId == NULL ||
974  DeviceMap == NULL)
975  {
977  }
978 
979  /* Acquire the database lock */
981 
982  /* Loop all existing sessions */
983  for (CurrentSession = SepLogonSessions;
984  CurrentSession != NULL;
985  CurrentSession = CurrentSession->Next)
986  {
987  /* Check if the LUID matches the provided one */
988  if (RtlEqualLuid(&CurrentSession->LogonId, LogonId))
989  {
990  break;
991  }
992  }
993 
994  /* No session found, fail */
995  if (CurrentSession == NULL)
996  {
997  /* Release the database lock */
999 
1001  }
1002 
1003  /* The found session has a device map, return it! */
1004  if (CurrentSession->pDeviceMap != NULL)
1005  {
1006  *DeviceMap = CurrentSession->pDeviceMap;
1007 
1008  /* Release the database lock */
1010 
1011  return STATUS_SUCCESS;
1012  }
1013 
1014  /* At that point, we'll setup a new device map for the session */
1015  LocalMap = NULL;
1016 
1017  /* Reference the session so that it doesn't go away */
1018  CurrentSession->ReferenceCount += 1;
1019 
1020  /* Release the database lock */
1022 
1023  /* Create our object directory given the LUID */
1025  sizeof(Buffer) / sizeof(WCHAR),
1026  L"\\Sessions\\0\\DosDevices\\%08x-%08x",
1027  LogonId->HighPart,
1028  LogonId->LowPart);
1029  RtlInitUnicodeString(&DirectoryName, Buffer);
1030 
1032  &DirectoryName,
1034  NULL,
1035  NULL);
1038  &ObjectAttributes);
1039  if (NT_SUCCESS(Status))
1040  {
1041  /* Create the associated device map */
1043  if (NT_SUCCESS(Status))
1044  {
1045  /* Make Global point to \Global?? in the directory */
1046  RtlInitUnicodeString(&LinkName, L"Global");
1047  RtlInitUnicodeString(&TargetName, L"\\Global??");
1048 
1050  &LinkName,
1053  NULL);
1054  Status = ZwCreateSymbolicLinkObject(&LinkHandle,
1057  &TargetName);
1058  if (!NT_SUCCESS(Status))
1059  {
1060  ObfDereferenceDeviceMap(LocalMap);
1061  }
1062  else
1063  {
1064  ZwClose(LinkHandle);
1065  }
1066  }
1067 
1069  }
1070 
1071  /* Acquire the database lock */
1073 
1074  /* If we succeed... */
1075  if (NT_SUCCESS(Status))
1076  {
1077  /* The session now has a device map? We raced with someone else */
1078  if (CurrentSession->pDeviceMap != NULL)
1079  {
1080  /* Give up on our new device map */
1081  ObfDereferenceDeviceMap(LocalMap);
1082  }
1083  /* Otherwise use our newly allocated device map */
1084  else
1085  {
1086  CurrentSession->pDeviceMap = LocalMap;
1087  }
1088 
1089  /* Return the device map */
1090  *DeviceMap = CurrentSession->pDeviceMap;
1091  }
1092  /* Zero output */
1093  else
1094  {
1095  *DeviceMap = NULL;
1096  }
1097 
1098  /* Release the database lock */
1100 
1101  /* We're done with the session */
1102  SepRmDereferenceLogonSession(&CurrentSession->LogonId);
1103 
1104  return Status;
1105 }
1106 
1107 /*
1108  * @unimplemented
1109  */
1110 NTSTATUS
1111 NTAPI
1113  IN PLUID LogonId)
1114 {
1115  UNIMPLEMENTED;
1116  return STATUS_NOT_IMPLEMENTED;
1117 }
1118 
1119 
1120 /*
1121  * @unimplemented
1122  */
1123 NTSTATUS
1124 NTAPI
1127 {
1128  UNIMPLEMENTED;
1129  return STATUS_NOT_IMPLEMENTED;
1130 }
1131 
1132 
1133 /*
1134  * @unimplemented
1135  */
1136 NTSTATUS
1137 NTAPI
1140 {
1141  UNIMPLEMENTED;
1142  return STATUS_NOT_IMPLEMENTED;
1143 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
NTSYSAPI NTSTATUS NTAPI ZwListenPort(_In_ HANDLE PortHandle, _In_ PPORT_MESSAGE ConnectionRequest)
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
HANDLE SeRmCommandPort
Definition: srm.c:18
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
KAPC_STATE
Definition: ketypes.h:1273
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
BOOLEAN NTAPI SeRmInitPhase0(VOID)
Definition: srm.c:147
BOOLEAN SepAdtAuditingEnabled
Definition: srm.c:56
NTSTATUS NTAPI SeMarkLogonSessionForTerminationNotification(IN PLUID LogonId)
Definition: srm.c:1112
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN _In_ ULONG _In_opt_ PULONG _In_ BOOLEAN RestartScan
Definition: fltkernel.h:2298
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
NTSTATUS NTAPI SepRegQueryHelper(PCWSTR KeyName, PCWSTR ValueName, ULONG ValueType, ULONG DataLength, PVOID ValueData)
Definition: srm.c:71
NTSYSAPI NTSTATUS NTAPI ZwCompleteConnectPort(_In_ HANDLE PortHandle)
#define REG_BINARY
Definition: nt_native.h:1496
#define STATUS_NO_SUCH_LOGON_SESSION
Definition: ntstatus.h:317
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
VOID FASTCALL ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap)
Definition: devicemap.c:477
NTSTATUS NTAPI SeGetLogonIdDeviceMap(IN PLUID LogonId, OUT PDEVICE_MAP *DeviceMap)
Definition: srm.c:958
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)
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4000
ULONG SepAdtMinListLength
Definition: srm.c:57
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE DirectoryHandle
Definition: ObType.c:48
NTSYSAPI NTSTATUS NTAPI ZwOpenDirectoryObject(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
static NTSTATUS SepRmCreateLogonSession(PLUID LogonLuid)
Definition: srm.c:298
#define OBJ_PERMANENT
Definition: winternl.h:226
ULONG SectionOffset
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3289
NTSTATUS SepRmReferenceLogonSession(PLUID LogonLuid)
Definition: srm.c:373
PVOID SepCommandPortViewRemoteBase
Definition: srm.c:51
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
#define PAGED_CODE()
Definition: video.h:57
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
BOOLEAN FASTCALL ObReferenceObjectSafe(IN PVOID Object)
Definition: obref.c:24
uint32_t ULONG_PTR
Definition: typedefs.h:63
PVOID SepCommandPortViewBase
Definition: srm.c:50
_Must_inspect_result_ _In_ PFLT_GET_OPERATION_STATUS_CALLBACK CallbackRoutine
Definition: fltkernel.h:1035
#define OBJ_OPENIF
Definition: winternl.h:229
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
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
VOID NTAPI SepRmCommandServerThread(PVOID StartContext)
Definition: srm.c:852
ULONG SepAdtMaxListLength
Definition: srm.c:58
#define TAG_SE_DIR_BUFFER
Definition: tag.h:182
ULONG_PTR SepCommandPortViewBaseOffset
Definition: srm.c:52
static HANDLE SepRmCommandMessagePort
Definition: srm.c:54
#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
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:701
#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
struct NameRec_ * Name
Definition: cdprocs.h:464
#define PsGetCurrentProcess
Definition: psfuncs.h:17
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
unsigned char BOOLEAN
LPC_PVOID ViewRemoteBase
UCHAR SeAuditingState[POLICY_AUDIT_EVENT_TYPE_COUNT]
Definition: srm.c:61
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_LOGON_SESSION_EXISTS
Definition: ntstatus.h:460
_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
void DPRINT(...)
Definition: polytest.cpp:61
static NTSTATUS SepRmSetAuditEvent(PSEP_RM_API_MESSAGE Message)
Definition: srm.c:269
Definition: bufpool.h:45
BOOL WINAPI ReplyMessage(_In_ LRESULT)
#define POLICY_AUDIT_EVENT_TYPE_COUNT
Definition: srm.c:60
BOOLEAN NTAPI SepRmCommandServerThreadInit(VOID)
Definition: srm.c:710
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_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:259
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DWORD LowPart
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:1209
LUID SeAnonymousAuthenticationId
Definition: token.c:39
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
struct _SEP_LOGON_SESSION_REFERENCES * Next
Definition: srm.c:26
PVOID HANDLE
Definition: typedefs.h:71
LUID SeSystemAuthenticationId
Definition: token.c:38
#define TAG_SE_HANDLES_TAB
Definition: tag.h:181
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
CHAR Message[80]
Definition: alive.c:5
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
#define SECURITY_DYNAMIC_TRACKING
Definition: setypes.h:103
static const WCHAR L[]
Definition: oid.c:1250
LONG HighPart
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
NTSTATUS SepCleanupLUIDDeviceMapDirectory(PLUID LogonLuid)
Definition: srm.c:413
ULONG LowPart
Definition: typedefs.h:104
WCHAR TargetName[256]
Definition: arping.c:27
#define PAGE_SIZE
Definition: env_spec_w32.h:49
HANDLE SeLsaInitEvent
Definition: srm.c:48
NTSYSAPI NTSTATUS NTAPI ZwReplyWaitReceivePort(_In_ HANDLE PortHandle, _Out_opt_ PVOID *PortContext, _In_opt_ PPORT_MESSAGE ReplyMessage, _Out_ PPORT_MESSAGE ReceiveMessage)
Definition: typedefs.h:117
KPROCESS Pcb
Definition: pstypes.h:1193
static const WCHAR Cleanup[]
Definition: register.c:80
PDEVICE_MAP pDeviceMap
Definition: srm.c:30
Status
Definition: gdiplustypes.h:24
struct _SEP_LOGON_SESSION_REFERENCES SEP_LOGON_SESSION_REFERENCES
static NTSTATUS SepRmDeleteLogonSession(PLUID LogonLuid)
Definition: srm.c:360
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static VOID SepAdtInitializeBounds(VOID)
Definition: srm.c:230
LPC_PVOID ViewBase
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
#define SEP_LOGON_SESSION_TAG
Definition: srm.c:22
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:753
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
#define PORT_MAXIMUM_MESSAGE_LENGTH
Definition: iotypes.h:1985
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
PSEP_LOGON_SESSION_REFERENCES SepLogonSessions
Definition: srm.c:64
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:1488
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
unsigned int * PULONG
Definition: retypes.h:1
_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
#define OUT
Definition: typedefs.h:39
LIST_ENTRY TokenList
Definition: srm.c:31
BOOLEAN NTAPI SeRmInitPhase1(VOID)
Definition: srm.c:174
struct tagContext Context
Definition: acpixf.h:1012
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 UNIMPLEMENTED
Definition: debug.h:114
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSTATUS NTAPI SeUnregisterLogonSessionTerminatedRoutine(IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine)
Definition: srm.c:1138
NTSYSAPI NTSTATUS NTAPI ZwCreatePort(_Out_ PHANDLE PortHandle, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ ULONG MaxConnectionInfoLength, _In_ ULONG MaxMessageLength, _In_ ULONG MaxPoolUsage)
LPC_HANDLE SectionHandle
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSTATUS NTAPI SeRegisterLogonSessionTerminatedRoutine(IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine)
Definition: srm.c:1125
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
NTSTATUS SepRmDereferenceLogonSession(PLUID LogonLuid)
Definition: srm.c:656
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define REG_DWORD
Definition: sdbapi.c:596
NTSYSAPI NTSTATUS NTAPI ZwMakeTemporaryObject(_In_ HANDLE Handle)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
LONGLONG QuadPart
Definition: typedefs.h:112
UNICODE_STRING TypeName
Definition: obtypes.h:279
struct _SEP_LOGON_SESSION_REFERENCES * PSEP_LOGON_SESSION_REFERENCES
#define PAGE_READWRITE
Definition: nt_native.h:1304
IN PUNICODE_STRING PortName
Definition: conport.c:35
KGUARDED_MUTEX SepRmDbLock
Definition: srm.c:63
#define NT_ASSERT
Definition: rtlfuncs.h:3312