ReactOS  0.4.15-dev-5120-gfb68e76
token.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 access token implementation base support routines
5  * COPYRIGHT: Copyright David Welch <welch@cwcom.net>
6  * Copyright 2021-2022 George BiČ™oc <george.bisoc@reactos.org>
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* GLOBALS ********************************************************************/
16 
18 
19 TOKEN_SOURCE SeSystemTokenSource = {"*SYSTEM*", {0}};
22 
24  TOKEN_READ,
28 };
29 
30 /* PRIVATE FUNCTIONS *****************************************************************/
31 
47 {
48  PAGED_CODE();
49 
51  sizeof(ERESOURCE),
53  if (Token->TokenLock == NULL)
54  {
55  DPRINT1("SepCreateTokenLock(): Failed to allocate memory!\n");
57  }
58 
59  ExInitializeResourceLite(Token->TokenLock);
60  return STATUS_SUCCESS;
61 }
62 
73 VOID
76 {
77  PAGED_CODE();
78 
79  ExDeleteResourceLite(Token->TokenLock);
81 }
82 
105 static
106 BOOLEAN
108  _In_ PSID_AND_ATTRIBUTES SidArrayToken1,
109  _In_ ULONG CountSidArray1,
110  _In_ PSID_AND_ATTRIBUTES SidArrayToken2,
111  _In_ ULONG CountSidArray2)
112 {
113  ULONG FirstCount, SecondCount;
114  PSID_AND_ATTRIBUTES FirstSidArray, SecondSidArray;
115  PAGED_CODE();
116 
117  /* Bail out if index counters provided are not equal */
118  if (CountSidArray1 != CountSidArray2)
119  {
120  DPRINT("SepCompareSidAndAttributesFromTokens(): Index counters are not the same!\n");
121  return FALSE;
122  }
123 
124  /* Loop over the SID arrays and compare them */
125  for (FirstCount = 0; FirstCount < CountSidArray1; FirstCount++)
126  {
127  for (SecondCount = 0; SecondCount < CountSidArray2; SecondCount++)
128  {
129  FirstSidArray = &SidArrayToken1[FirstCount];
130  SecondSidArray = &SidArrayToken2[SecondCount];
131 
132  if (RtlEqualSid(FirstSidArray->Sid, SecondSidArray->Sid) &&
133  FirstSidArray->Attributes == SecondSidArray->Attributes)
134  {
135  break;
136  }
137  }
138 
139  /* We've exhausted the array of the second token without finding this one */
140  if (SecondCount == CountSidArray2)
141  {
142  DPRINT("SepCompareSidAndAttributesFromTokens(): No matching elements could be found in either token!\n");
143  return FALSE;
144  }
145  }
146 
147  return TRUE;
148 }
149 
172 static
173 BOOLEAN
175  _In_ PLUID_AND_ATTRIBUTES PrivArrayToken1,
176  _In_ ULONG CountPrivArray1,
177  _In_ PLUID_AND_ATTRIBUTES PrivArrayToken2,
178  _In_ ULONG CountPrivArray2)
179 {
180  ULONG FirstCount, SecondCount;
181  PLUID_AND_ATTRIBUTES FirstPrivArray, SecondPrivArray;
182  PAGED_CODE();
183 
184  /* Bail out if index counters provided are not equal */
185  if (CountPrivArray1 != CountPrivArray2)
186  {
187  DPRINT("SepComparePrivilegeAndAttributesFromTokens(): Index counters are not the same!\n");
188  return FALSE;
189  }
190 
191  /* Loop over the privilege arrays and compare them */
192  for (FirstCount = 0; FirstCount < CountPrivArray1; FirstCount++)
193  {
194  for (SecondCount = 0; SecondCount < CountPrivArray2; SecondCount++)
195  {
196  FirstPrivArray = &PrivArrayToken1[FirstCount];
197  SecondPrivArray = &PrivArrayToken2[SecondCount];
198 
199  if (RtlEqualLuid(&FirstPrivArray->Luid, &SecondPrivArray->Luid) &&
200  FirstPrivArray->Attributes == SecondPrivArray->Attributes)
201  {
202  break;
203  }
204  }
205 
206  /* We've exhausted the array of the second token without finding this one */
207  if (SecondCount == CountPrivArray2)
208  {
209  DPRINT("SepComparePrivilegeAndAttributesFromTokens(): No matching elements could be found in either token!\n");
210  return FALSE;
211  }
212  }
213 
214  return TRUE;
215 }
216 
241 static
242 NTSTATUS
244  _In_ PTOKEN FirstToken,
245  _In_ PTOKEN SecondToken,
246  _Out_ PBOOLEAN Equal)
247 {
249  PAGED_CODE();
250 
251  ASSERT(FirstToken != SecondToken);
252 
253  /* Lock the tokens */
254  SepAcquireTokenLockShared(FirstToken);
255  SepAcquireTokenLockShared(SecondToken);
256 
257  /* Check if every SID that is present in either token is also present in the other one */
258  if (!SepCompareSidAndAttributesFromTokens(FirstToken->UserAndGroups,
259  FirstToken->UserAndGroupCount,
260  SecondToken->UserAndGroups,
261  SecondToken->UserAndGroupCount))
262  {
263  goto Quit;
264  }
265 
266  /* Is one token restricted but the other isn't? */
267  Restricted = SeTokenIsRestricted(FirstToken);
268  if (Restricted != SeTokenIsRestricted(SecondToken))
269  {
270  /* If that's the case then bail out */
271  goto Quit;
272  }
273 
274  /*
275  * If both tokens are restricted check if every SID
276  * that is restricted in either token is also restricted
277  * in the other one.
278  */
279  if (Restricted)
280  {
281  if (!SepCompareSidAndAttributesFromTokens(FirstToken->RestrictedSids,
282  FirstToken->RestrictedSidCount,
283  SecondToken->RestrictedSids,
284  SecondToken->RestrictedSidCount))
285  {
286  goto Quit;
287  }
288  }
289 
290  /* Check if every privilege present in either token is also present in the other one */
291  if (!SepComparePrivilegeAndAttributesFromTokens(FirstToken->Privileges,
292  FirstToken->PrivilegeCount,
293  SecondToken->Privileges,
294  SecondToken->PrivilegeCount))
295  {
296  goto Quit;
297  }
298 
299  /* If we're here then the tokens are equal */
300  IsEqual = TRUE;
301  DPRINT("SepCompareTokens(): Tokens are equal!\n");
302 
303 Quit:
304  /* Unlock the tokens */
305  SepReleaseTokenLock(SecondToken);
306  SepReleaseTokenLock(FirstToken);
307 
308  *Equal = IsEqual;
309  return STATUS_SUCCESS;
310 }
311 
332 static
333 NTSTATUS
337 {
339  PTOKEN TokenToImpersonate, ProcessToken;
340  ULONG IncludeEveryoneValueData;
341  PAGED_CODE();
342 
343  /*
344  * We must check first which kind of token
345  * shall we assign for the thread to impersonate,
346  * the one with Everyone Group SID or the other
347  * without. Invoke the registry helper to
348  * return the data value for us.
349  */
350  Status = SepRegQueryHelper(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Lsa",
351  L"EveryoneIncludesAnonymous",
352  REG_DWORD,
353  sizeof(IncludeEveryoneValueData),
354  &IncludeEveryoneValueData);
355  if (!NT_SUCCESS(Status))
356  {
357  DPRINT1("SepRegQueryHelper(): Failed to query the registry value (Status 0x%lx)\n", Status);
358  return Status;
359  }
360 
361  if (IncludeEveryoneValueData == 0)
362  {
363  DPRINT("SepImpersonateAnonymousToken(): Assigning the token not including the Everyone Group SID...\n");
364  TokenToImpersonate = SeAnonymousLogonTokenNoEveryone;
365  }
366  else
367  {
368  DPRINT("SepImpersonateAnonymousToken(): Assigning the token including the Everyone Group SID...\n");
369  TokenToImpersonate = SeAnonymousLogonToken;
370  }
371 
372  /*
373  * Tell the object manager that we're going to use this token
374  * object now by incrementing the reference count.
375  */
376  Status = ObReferenceObjectByPointer(TokenToImpersonate,
379  PreviousMode);
380  if (!NT_SUCCESS(Status))
381  {
382  DPRINT1("SepImpersonateAnonymousToken(): Couldn't be able to use the token, bail out...\n");
383  return Status;
384  }
385 
386  /*
387  * Reference the primary token of the current process that the anonymous
388  * logon token impersonation procedure is being performed. We'll be going
389  * to use the process' token to figure out if the process is actually
390  * restricted or not.
391  */
393  if (!ProcessToken)
394  {
395  DPRINT1("SepImpersonateAnonymousToken(): Couldn't be able to get the process' primary token, bail out...\n");
396  ObDereferenceObject(TokenToImpersonate);
397  return STATUS_UNSUCCESSFUL;
398  }
399 
400  /* Now, is the token from the current process restricted? */
401  if (SeTokenIsRestricted(ProcessToken))
402  {
403  DPRINT1("SepImpersonateAnonymousToken(): The process is restricted, can't do anything. Bail out...\n");
404  PsDereferencePrimaryToken(ProcessToken);
405  ObDereferenceObject(TokenToImpersonate);
406  return STATUS_ACCESS_DENIED;
407  }
408 
409  /*
410  * Finally it's time to impersonate! But first, fast dereference the
411  * process' primary token as we no longer need it.
412  */
415  if (!NT_SUCCESS(Status))
416  {
417  DPRINT1("SepImpersonateAnonymousToken(): Failed to impersonate, bail out...\n");
418  ObDereferenceObject(TokenToImpersonate);
419  return Status;
420  }
421 
422  return Status;
423 }
424 
441 VOID
444  _In_ ULONG Index)
445 {
446  ULONG TokenFlag;
447  ASSERT(Index < Token->PrivilegeCount);
448 
449  /* The high part of all values we are interested in is 0 */
450  if (Token->Privileges[Index].Luid.HighPart != 0)
451  {
452  return;
453  }
454 
455  /* Check for certain privileges to update flags */
456  if (Token->Privileges[Index].Luid.LowPart == SE_CHANGE_NOTIFY_PRIVILEGE)
457  {
458  TokenFlag = TOKEN_HAS_TRAVERSE_PRIVILEGE;
459  }
460  else if (Token->Privileges[Index].Luid.LowPart == SE_BACKUP_PRIVILEGE)
461  {
462  TokenFlag = TOKEN_HAS_BACKUP_PRIVILEGE;
463  }
464  else if (Token->Privileges[Index].Luid.LowPart == SE_RESTORE_PRIVILEGE)
465  {
466  TokenFlag = TOKEN_HAS_RESTORE_PRIVILEGE;
467  }
468  else if (Token->Privileges[Index].Luid.LowPart == SE_IMPERSONATE_PRIVILEGE)
469  {
471  }
472  else
473  {
474  /* Nothing to do */
475  return;
476  }
477 
478  /* Check if the specified privilege is enabled */
479  if (Token->Privileges[Index].Attributes & SE_PRIVILEGE_ENABLED)
480  {
481  /* It is enabled, so set the flag */
482  Token->TokenFlags |= TokenFlag;
483  }
484  else
485  {
486  /* Is is disabled, so remove the flag */
487  Token->TokenFlags &= ~TokenFlag;
488  }
489 }
490 
509 BOOLEAN
510 NTAPI
512  _In_ PACCESS_TOKEN _Token,
514  _In_ BOOLEAN TokenLocked)
515 {
516  PSID Sid;
517  BOOLEAN Result;
518  PTOKEN Token = _Token;
519 
520  /* Get the owner SID */
522  ASSERT(Sid != NULL);
523 
524  /* Lock the token if needed */
525  if (!TokenLocked) SepAcquireTokenLockShared(Token);
526 
527  /* Check if the owner SID is found, handling restricted case as well */
529  if ((Result) && (Token->TokenFlags & TOKEN_IS_RESTRICTED))
530  {
532  }
533 
534  /* Release the lock if we had acquired it */
535  if (!TokenLocked) SepReleaseTokenLock(Token);
536 
537  /* Return the result */
538  return Result;
539 }
540 
553 VOID
556 {
557  ULONG i;
558 
559  /* Loop all privileges */
560  for (i = 0; i < Token->PrivilegeCount; i++)
561  {
562  /* Updates the flags for this privilege */
564  }
565 }
566 
581 VOID
584  _In_ ULONG Index)
585 {
586  ULONG MoveCount;
587  ASSERT(Index < Token->PrivilegeCount);
588 
589  /* Calculate the number of trailing privileges */
590  MoveCount = Token->PrivilegeCount - Index - 1;
591  if (MoveCount != 0)
592  {
593  /* Move them one location ahead */
594  RtlMoveMemory(&Token->Privileges[Index],
595  &Token->Privileges[Index + 1],
596  MoveCount * sizeof(LUID_AND_ATTRIBUTES));
597  }
598 
599  /* Update privilege count */
600  Token->PrivilegeCount--;
601 }
602 
617 VOID
620  _In_ ULONG Index)
621 {
622  ULONG MoveCount;
623  ASSERT(Index < Token->UserAndGroupCount);
624 
625  /* Calculate the number of trailing groups */
626  MoveCount = Token->UserAndGroupCount - Index - 1;
627  if (MoveCount != 0)
628  {
629  /* Time to remove the group by moving one location ahead */
630  RtlMoveMemory(&Token->UserAndGroups[Index],
631  &Token->UserAndGroups[Index + 1],
632  MoveCount * sizeof(SID_AND_ATTRIBUTES));
633  }
634 
635  /* Remove one group count */
636  Token->UserAndGroupCount--;
637 }
638 
658 ULONG
660  _In_ ULONG DynamicCharged,
662  _In_opt_ PACL DefaultDacl)
663 {
664  ULONG DynamicAvailable;
665 
666  PAGED_CODE();
667 
668  /* A token's dynamic area is always charged */
669  ASSERT(DynamicCharged != 0);
670 
671  /*
672  * Take into account the default DACL if
673  * the token has one. Otherwise the occupied
674  * space is just the present primary group.
675  */
676  DynamicAvailable = DynamicCharged - RtlLengthSid(PrimaryGroup);
677  if (DefaultDacl)
678  {
679  DynamicAvailable -= DefaultDacl->AclSize;
680  }
681 
682  return DynamicAvailable;
683 }
684 
714 NTSTATUS
716  _Inout_ PTOKEN AccessToken,
717  _In_ ULONG NewDynamicPartSize)
718 {
719  PVOID NewDynamicPart;
720  PVOID PreviousDynamicPart;
721  ULONG CurrentDynamicLength;
722 
723  PAGED_CODE();
724 
725  /* Sanity checks */
726  ASSERT(AccessToken);
727  ASSERT(NewDynamicPartSize != 0);
728 
729  /*
730  * Compute the exact length of the available
731  * dynamic part of the access token.
732  */
733  CurrentDynamicLength = AccessToken->DynamicAvailable + RtlLengthSid(AccessToken->PrimaryGroup);
734  if (AccessToken->DefaultDacl)
735  {
736  CurrentDynamicLength += AccessToken->DefaultDacl->AclSize;
737  }
738 
739  /*
740  * Figure out if the current dynamic part is too small
741  * to fit new contents inside the said dynamic part.
742  * Rebuild the dynamic area and expand it if necessary.
743  */
744  if (CurrentDynamicLength < NewDynamicPartSize)
745  {
746  NewDynamicPart = ExAllocatePoolWithTag(PagedPool,
747  NewDynamicPartSize,
749  if (NewDynamicPart == NULL)
750  {
751  DPRINT1("SepRebuildDynamicPartOfToken(): Insufficient resources to allocate new dynamic part!\n");
753  }
754 
755  /* Copy the existing dynamic part */
756  PreviousDynamicPart = AccessToken->DynamicPart;
757  RtlCopyMemory(NewDynamicPart, PreviousDynamicPart, CurrentDynamicLength);
758 
759  /* Update the available dynamic area and assign new dynamic */
760  AccessToken->DynamicAvailable += NewDynamicPartSize - CurrentDynamicLength;
761  AccessToken->DynamicPart = NewDynamicPart;
762 
763  /* Move the contents (primary group and default DACL) addresses as well */
764  AccessToken->PrimaryGroup = (PSID)((ULONG_PTR)AccessToken->DynamicPart +
765  ((ULONG_PTR)AccessToken->PrimaryGroup - (ULONG_PTR)PreviousDynamicPart));
766  if (AccessToken->DefaultDacl != NULL)
767  {
768  AccessToken->DefaultDacl = (PACL)((ULONG_PTR)AccessToken->DynamicPart +
769  ((ULONG_PTR)AccessToken->DefaultDacl - (ULONG_PTR)PreviousDynamicPart));
770  }
771 
772  /* And discard the previous dynamic part */
773  DPRINT("SepRebuildDynamicPartOfToken(): The dynamic part has been re-built with success!\n");
774  ExFreePoolWithTag(PreviousDynamicPart, TAG_TOKEN_DYNAMIC);
775  }
776 
777  return STATUS_SUCCESS;
778 }
779 
791 VOID
792 NTAPI
794  _Inout_ PVOID ProxyData)
795 {
797 }
798 
813 NTSTATUS
814 NTAPI
816  _Out_ PVOID* Dest,
817  _In_ PVOID Src)
818 {
820  return STATUS_NOT_IMPLEMENTED;
821 }
822 
844 NTSTATUS
845 NTAPI
848  _In_ PACCESS_TOKEN NewAccessToken,
849  _Out_ PACCESS_TOKEN* OldAccessToken)
850 {
851  PTOKEN OldToken;
852  PTOKEN NewToken = (PTOKEN)NewAccessToken;
853 
854  PAGED_CODE();
855 
856  if (NewToken->TokenType != TokenPrimary)
857  return STATUS_BAD_TOKEN_TYPE;
858 
859  if (NewToken->TokenInUse)
860  {
863 
864  /* Maybe we're trying to set the same token */
865  OldToken = PsReferencePrimaryToken(Process);
866  if (OldToken == NewToken)
867  {
868  /* So it's a nop. */
869  *OldAccessToken = OldToken;
870  return STATUS_SUCCESS;
871  }
872 
873  Status = SepCompareTokens(OldToken, NewToken, &IsEqual);
874  if (!NT_SUCCESS(Status))
875  {
876  PsDereferencePrimaryToken(OldToken);
877  *OldAccessToken = NULL;
878  return Status;
879  }
880 
881  if (!IsEqual)
882  {
883  PsDereferencePrimaryToken(OldToken);
884  *OldAccessToken = NULL;
886  }
887  /* Silently return STATUS_SUCCESS but do not set the new token,
888  * as it's already in use elsewhere. */
889  *OldAccessToken = OldToken;
890  return STATUS_SUCCESS;
891  }
892 
893  /* Lock the new token */
895 
896  /* Mark new token in use */
897  NewToken->TokenInUse = TRUE;
898 
899  /* Set the session ID for the new token */
900  NewToken->SessionId = MmGetSessionId(Process);
901 
902  /* Unlock the new token */
903  SepReleaseTokenLock(NewToken);
904 
905  /* Reference the new token */
906  ObReferenceObject(NewToken);
907 
908  /* Replace the old with the new */
909  OldToken = ObFastReplaceObject(&Process->Token, NewToken);
910 
911  /* Lock the old token */
913 
914  /* Mark the old token as free */
915  OldToken->TokenInUse = FALSE;
916 
917  /* Unlock the old token */
918  SepReleaseTokenLock(OldToken);
919 
920  *OldAccessToken = (PACCESS_TOKEN)OldToken;
921  return STATUS_SUCCESS;
922 }
923 
934 VOID
935 NTAPI
938 {
939  PTOKEN OldToken;
940 
941  /* Remove the Token */
942  OldToken = ObFastReplaceObject(&Process->Token, NULL);
943 
944  /* Mark the Old Token as free */
945  OldToken->TokenInUse = FALSE;
946 
947  /* Dereference the Token */
948  ObDereferenceObject(OldToken);
949 }
950 
964 ULONG
966  _In_ ULONG Count,
968 {
969  ULONG i;
970  ULONG uLength;
971 
972  PAGED_CODE();
973 
974  uLength = Count * sizeof(SID_AND_ATTRIBUTES);
975  for (i = 0; i < Count; i++)
976  uLength += RtlLengthSid(Src[i].Sid);
977 
978  return uLength;
979 }
980 
1010 NTSTATUS
1012  _In_ PTOKEN Token,
1014  _In_opt_ PSID DefaultOwner,
1015  _Out_opt_ PULONG PrimaryGroupIndex,
1016  _Out_opt_ PULONG DefaultOwnerIndex)
1017 {
1018  ULONG i;
1019 
1020  /* We should return at least a search result */
1021  if (!PrimaryGroupIndex && !DefaultOwnerIndex)
1022  return STATUS_INVALID_PARAMETER;
1023 
1024  if (PrimaryGroupIndex)
1025  {
1026  /* Initialize with an invalid index */
1027  // Token->PrimaryGroup = NULL;
1028  *PrimaryGroupIndex = Token->UserAndGroupCount;
1029  }
1030 
1031  if (DefaultOwnerIndex)
1032  {
1033  if (DefaultOwner)
1034  {
1035  /* An owner is specified: check whether this is actually the user */
1036  if (RtlEqualSid(Token->UserAndGroups[0].Sid, DefaultOwner))
1037  {
1038  /*
1039  * It's the user (first element in array): set it
1040  * as the owner and stop the search for it.
1041  */
1042  *DefaultOwnerIndex = 0;
1043  DefaultOwnerIndex = NULL;
1044  }
1045  else
1046  {
1047  /* An owner is specified: initialize with an invalid index */
1048  *DefaultOwnerIndex = Token->UserAndGroupCount;
1049  }
1050  }
1051  else
1052  {
1053  /*
1054  * No owner specified: set the user (first element in array)
1055  * as the owner and stop the search for it.
1056  */
1057  *DefaultOwnerIndex = 0;
1058  DefaultOwnerIndex = NULL;
1059  }
1060  }
1061 
1062  /* Validate and set the primary group and default owner indices */
1063  for (i = 0; i < Token->UserAndGroupCount; i++)
1064  {
1065  /* Stop the search if we have found what we searched for */
1066  if (!PrimaryGroupIndex && !DefaultOwnerIndex)
1067  break;
1068 
1069  if (DefaultOwnerIndex && DefaultOwner &&
1070  RtlEqualSid(Token->UserAndGroups[i].Sid, DefaultOwner) &&
1071  (Token->UserAndGroups[i].Attributes & SE_GROUP_OWNER))
1072  {
1073  /* Owner is found, stop the search for it */
1074  *DefaultOwnerIndex = i;
1075  DefaultOwnerIndex = NULL;
1076  }
1077 
1078  if (PrimaryGroupIndex &&
1079  RtlEqualSid(Token->UserAndGroups[i].Sid, PrimaryGroup))
1080  {
1081  /* Primary group is found, stop the search for it */
1082  // Token->PrimaryGroup = Token->UserAndGroups[i].Sid;
1083  *PrimaryGroupIndex = i;
1084  PrimaryGroupIndex = NULL;
1085  }
1086  }
1087 
1088  if (DefaultOwnerIndex)
1089  {
1090  if (*DefaultOwnerIndex == Token->UserAndGroupCount)
1091  return STATUS_INVALID_OWNER;
1092  }
1093 
1094  if (PrimaryGroupIndex)
1095  {
1096  if (*PrimaryGroupIndex == Token->UserAndGroupCount)
1097  // if (Token->PrimaryGroup == NULL)
1099  }
1100 
1101  return STATUS_SUCCESS;
1102 }
1103 
1125 NTSTATUS
1126 NTAPI
1128  _In_ PTOKEN ParentToken,
1129  _Out_ PTOKEN *Token,
1130  _In_ BOOLEAN InUse,
1132 {
1133  PTOKEN NewToken;
1135  NTSTATUS Status;
1136 
1137  /* Initialize the attributes and duplicate it */
1139  Status = SepDuplicateToken(ParentToken,
1141  FALSE,
1142  TokenPrimary,
1143  ParentToken->ImpersonationLevel,
1144  KernelMode,
1145  &NewToken);
1146  if (NT_SUCCESS(Status))
1147  {
1148  /* Insert it */
1149  Status = ObInsertObject(NewToken,
1150  NULL,
1151  0,
1152  0,
1153  NULL,
1154  NULL);
1155  if (NT_SUCCESS(Status))
1156  {
1157  /* Set the session ID */
1158  NewToken->SessionId = SessionId;
1159  NewToken->TokenInUse = InUse;
1160 
1161  /* Return the token */
1162  *Token = NewToken;
1163  }
1164  }
1165 
1166  /* Return status */
1167  return Status;
1168 }
1169 
1185 NTSTATUS
1186 NTAPI
1188  _In_ PTOKEN Token,
1190 {
1191  PTOKEN ProcessToken;
1192  LUID ProcessTokenId, CallerParentId;
1193 
1194  /* Assume failure */
1195  *IsChild = FALSE;
1196 
1197  /* Reference the process token */
1198  ProcessToken = PsReferencePrimaryToken(PsGetCurrentProcess());
1199  if (!ProcessToken)
1200  return STATUS_UNSUCCESSFUL;
1201 
1202  /* Get its token ID */
1203  ProcessTokenId = ProcessToken->TokenId;
1204 
1205  /* Dereference the token */
1207 
1208  /* Get our parent token ID */
1209  CallerParentId = Token->ParentTokenId;
1210 
1211  /* Compare the token IDs */
1212  if (RtlEqualLuid(&CallerParentId, &ProcessTokenId))
1213  *IsChild = TRUE;
1214 
1215  /* Return success */
1216  return STATUS_SUCCESS;
1217 }
1218 
1234 NTSTATUS
1235 NTAPI
1237  _In_ PTOKEN Token,
1238  _Out_ PBOOLEAN IsSibling)
1239 {
1240  PTOKEN ProcessToken;
1241  LUID ProcessParentId, ProcessAuthId;
1242  LUID CallerParentId, CallerAuthId;
1243 
1244  /* Assume failure */
1245  *IsSibling = FALSE;
1246 
1247  /* Reference the process token */
1248  ProcessToken = PsReferencePrimaryToken(PsGetCurrentProcess());
1249  if (!ProcessToken)
1250  return STATUS_UNSUCCESSFUL;
1251 
1252  /* Get its parent and authentication IDs */
1253  ProcessParentId = ProcessToken->ParentTokenId;
1254  ProcessAuthId = ProcessToken->AuthenticationId;
1255 
1256  /* Dereference the token */
1258 
1259  /* Get our parent and authentication IDs */
1260  CallerParentId = Token->ParentTokenId;
1261  CallerAuthId = Token->AuthenticationId;
1262 
1263  /* Compare the token IDs */
1264  if (RtlEqualLuid(&CallerParentId, &ProcessParentId) &&
1265  RtlEqualLuid(&CallerAuthId, &ProcessAuthId))
1266  {
1267  *IsSibling = TRUE;
1268  }
1269 
1270  /* Return success */
1271  return STATUS_SUCCESS;
1272 }
1273 
1294 NTSTATUS
1295 NTAPI
1300  _Out_ PACCESS_TOKEN* NewToken)
1301 {
1302  NTSTATUS Status;
1304 
1305  PAGED_CODE();
1306 
1308  NULL,
1309  0,
1310  NULL,
1311  NULL);
1312 
1315  FALSE,
1317  Level,
1318  PreviousMode,
1319  (PTOKEN*)NewToken);
1320 
1321  return Status;
1322 }
1323 
1335 BOOLEAN
1336 NTAPI
1338  _In_ PTOKEN Token)
1339 {
1340  PAGED_CODE();
1341 
1342  return (((PTOKEN)Token)->TokenFlags & TOKEN_SANDBOX_INERT) != 0;
1343 }
1344 
1357 VOID
1358 NTAPI
1360  _In_ PVOID ObjectBody)
1361 {
1362  NTSTATUS Status;
1363  PTOKEN AccessToken = (PTOKEN)ObjectBody;
1364 
1365  DPRINT("SepDeleteToken()\n");
1366 
1367  /* Remove the referenced logon session from token */
1368  if (AccessToken->LogonSession)
1369  {
1371  if (!NT_SUCCESS(Status))
1372  {
1373  /* Something seriously went wrong */
1374  DPRINT1("SepDeleteToken(): Failed to remove the logon session from token (Status: 0x%lx)\n", Status);
1375  return;
1376  }
1377  }
1378 
1379  /* Dereference the logon session */
1380  if ((AccessToken->TokenFlags & TOKEN_SESSION_NOT_REFERENCED) == 0)
1382 
1383  /* Delete the token lock */
1384  if (AccessToken->TokenLock)
1385  SepDeleteTokenLock(AccessToken);
1386 
1387  /* Delete the dynamic information area */
1388  if (AccessToken->DynamicPart)
1390 }
1391 
1400 CODE_SEG("INIT")
1401 VOID
1402 NTAPI
1404 {
1406  OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
1407 
1408  DPRINT("Creating Token Object Type\n");
1409 
1410  /* Initialize the Token type */
1411  RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
1412  RtlInitUnicodeString(&Name, L"Token");
1413  ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
1414  ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
1415  ObjectTypeInitializer.SecurityRequired = TRUE;
1416  ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(TOKEN);
1417  ObjectTypeInitializer.GenericMapping = SepTokenMapping;
1418  ObjectTypeInitializer.PoolType = PagedPool;
1419  ObjectTypeInitializer.ValidAccessMask = TOKEN_ALL_ACCESS;
1420  ObjectTypeInitializer.UseDefaultObject = TRUE;
1421  ObjectTypeInitializer.DeleteProcedure = SepDeleteToken;
1422  ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &SeTokenObjectType);
1423 }
1424 
1438 VOID
1439 NTAPI
1442  _In_ PTOKEN Token)
1443 {
1444  PAGED_CODE();
1445 
1446  /* Sanity checks */
1447  ASSERT(Token->TokenType == TokenPrimary);
1448  ASSERT(!Token->TokenInUse);
1449 
1450  /* Clean any previous token */
1451  if (Process->Token.Object) SeDeassignPrimaryToken(Process);
1452 
1453  /* Set the new token */
1455  Token->TokenInUse = TRUE;
1457 }
1458 
1472 VOID
1473 NTAPI
1475  _In_ PACCESS_TOKEN _Token,
1476  _Out_ PTOKEN_CONTROL TokenControl)
1477 {
1478  PTOKEN Token = _Token;
1479  PAGED_CODE();
1480 
1481  /* Capture the main fields */
1482  TokenControl->AuthenticationId = Token->AuthenticationId;
1483  TokenControl->TokenId = Token->TokenId;
1484  TokenControl->TokenSource = Token->TokenSource;
1485 
1486  /* Lock the token */
1488 
1489  /* Capture the modified ID */
1490  TokenControl->ModifiedId = Token->ModifiedId;
1491 
1492  /* Unlock it */
1494 }
1495 
1504 CODE_SEG("INIT")
1505 PTOKEN
1506 NTAPI
1508 {
1510  ULONG GroupAttributes, OwnerAttributes;
1512  LARGE_INTEGER Expiration;
1513  SID_AND_ATTRIBUTES UserSid;
1514  ULONG GroupsLength;
1517  PSID Owner;
1518  ULONG i;
1519  PTOKEN Token;
1520  NTSTATUS Status;
1521 
1522  /* Don't ever expire */
1523  Expiration.QuadPart = -1;
1524 
1525  /* All groups mandatory and enabled */
1528 
1529  /* User is Local System */
1530  UserSid.Sid = SeLocalSystemSid;
1531  UserSid.Attributes = 0;
1532 
1533  /* Primary group is Local System */
1535 
1536  /* Owner is Administrators */
1538 
1539  /* Groups are Administrators, World, and Authenticated Users */
1540  Groups[0].Sid = SeAliasAdminsSid;
1541  Groups[0].Attributes = OwnerAttributes;
1542  Groups[1].Sid = SeWorldSid;
1543  Groups[1].Attributes = GroupAttributes;
1545  Groups[2].Attributes = GroupAttributes;
1546  GroupsLength = sizeof(SID_AND_ATTRIBUTES) +
1547  SeLengthSid(Groups[0].Sid) +
1548  SeLengthSid(Groups[1].Sid) +
1549  SeLengthSid(Groups[2].Sid);
1550  ASSERT(GroupsLength <= sizeof(Groups));
1551 
1552  /* Setup the privileges */
1553  i = 0;
1555  Privileges[i++].Luid = SeTcbPrivilege;
1556 
1557  Privileges[i].Attributes = 0;
1559 
1560  Privileges[i].Attributes = 0;
1562 
1565 
1568 
1569  Privileges[i].Attributes = 0;
1571 
1572  Privileges[i].Attributes = 0;
1574 
1577 
1580 
1582  Privileges[i++].Luid = SeDebugPrivilege;
1583 
1585  Privileges[i++].Luid = SeAuditPrivilege;
1586 
1587  Privileges[i].Attributes = 0;
1588  Privileges[i++].Luid = SeSecurityPrivilege;
1589 
1590  Privileges[i].Attributes = 0;
1592 
1595 
1596  Privileges[i].Attributes = 0;
1597  Privileges[i++].Luid = SeBackupPrivilege;
1598 
1599  Privileges[i].Attributes = 0;
1600  Privileges[i++].Luid = SeRestorePrivilege;
1601 
1602  Privileges[i].Attributes = 0;
1603  Privileges[i++].Luid = SeShutdownPrivilege;
1604 
1605  Privileges[i].Attributes = 0;
1607 
1610 
1611  Privileges[i].Attributes = 0;
1613  ASSERT(i == 20);
1614 
1615  /* Setup the object attributes */
1618 
1619  /* Create the token */
1621  KernelMode,
1622  0,
1624  TokenPrimary,
1627  &Expiration,
1628  &UserSid,
1629  3,
1630  Groups,
1631  GroupsLength,
1632  20,
1633  Privileges,
1634  Owner,
1635  PrimaryGroup,
1638  TRUE);
1640 
1641  /* Return the token */
1642  return Token;
1643 }
1644 
1655 CODE_SEG("INIT")
1656 PTOKEN
1658 {
1659  SID_AND_ATTRIBUTES Groups[32], UserSid;
1661  PTOKEN Token;
1662  ULONG GroupsLength;
1663  LARGE_INTEGER Expiration;
1665  NTSTATUS Status;
1666 
1667  /* The token never expires */
1668  Expiration.QuadPart = -1;
1669 
1670  /* The user is the anonymous logon */
1671  UserSid.Sid = SeAnonymousLogonSid;
1672  UserSid.Attributes = 0;
1673 
1674  /* The primary group is also the anonymous logon */
1676 
1677  /* The only group for the token is the World */
1678  Groups[0].Sid = SeWorldSid;
1680  GroupsLength = sizeof(SID_AND_ATTRIBUTES) +
1681  SeLengthSid(Groups[0].Sid);
1682  ASSERT(GroupsLength <= sizeof(Groups));
1683 
1684  /* Initialise the object attributes for the token */
1687 
1688  /* Create token */
1690  KernelMode,
1691  0,
1693  TokenPrimary,
1696  &Expiration,
1697  &UserSid,
1698  1,
1699  Groups,
1700  GroupsLength,
1701  0,
1702  NULL,
1703  NULL,
1704  PrimaryGroup,
1707  TRUE);
1709 
1710  /* Return the anonymous logon token */
1711  return Token;
1712 }
1713 
1723 CODE_SEG("INIT")
1724 PTOKEN
1726 {
1727  SID_AND_ATTRIBUTES UserSid;
1729  PTOKEN Token;
1730  LARGE_INTEGER Expiration;
1732  NTSTATUS Status;
1733 
1734  /* The token never expires */
1735  Expiration.QuadPart = -1;
1736 
1737  /* The user is the anonymous logon */
1738  UserSid.Sid = SeAnonymousLogonSid;
1739  UserSid.Attributes = 0;
1740 
1741  /* The primary group is also the anonymous logon */
1743 
1744  /* Initialise the object attributes for the token */
1747 
1748  /* Create token */
1750  KernelMode,
1751  0,
1753  TokenPrimary,
1756  &Expiration,
1757  &UserSid,
1758  0,
1759  NULL,
1760  0,
1761  0,
1762  NULL,
1763  NULL,
1764  PrimaryGroup,
1767  TRUE);
1769 
1770  /* Return the anonymous (not including everyone) logon token */
1771  return Token;
1772 }
1773 
1774 /* PUBLIC FUNCTIONS ***********************************************************/
1775 
1789 NTSTATUS
1790 NTAPI
1793  _Out_ PULONG pSessionId)
1794 {
1795  PAGED_CODE();
1796 
1797  /* Lock the token */
1799 
1800  *pSessionId = ((PTOKEN)Token)->SessionId;
1801 
1802  /* Unlock the token */
1804 
1805  return STATUS_SUCCESS;
1806 }
1807 
1821 NTSTATUS
1822 NTAPI
1826 {
1827  PAGED_CODE();
1828 
1829  *LogonId = ((PTOKEN)Token)->AuthenticationId;
1830 
1831  return STATUS_SUCCESS;
1832 }
1833 
1845 NTAPI
1848 {
1849  PAGED_CODE();
1850 
1851  return ((PTOKEN)Token)->ImpersonationLevel;
1852 }
1853 
1865 TOKEN_TYPE
1866 NTAPI
1869 {
1870  PAGED_CODE();
1871 
1872  return ((PTOKEN)Token)->TokenType;
1873 }
1874 
1888 BOOLEAN
1889 NTAPI
1892 {
1893  PAGED_CODE();
1894 
1895  // NOTE: Win7+ instead really checks the list of groups in the token
1896  // (since TOKEN_HAS_ADMIN_GROUP == TOKEN_WRITE_RESTRICTED ...)
1897  return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_ADMIN_GROUP) != 0;
1898 }
1899 
1911 BOOLEAN
1912 NTAPI
1915 {
1916  PAGED_CODE();
1917 
1918  return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0;
1919 }
1920 
1936 BOOLEAN
1937 NTAPI
1940 {
1941  PAGED_CODE();
1942 
1943  // NOTE: NT 5.1 SP2 x86 checks the SE_BACKUP_PRIVILEGES_CHECKED flag
1944  // while Vista+ checks the TOKEN_WRITE_RESTRICTED flag as one expects.
1945  return (((PTOKEN)Token)->TokenFlags & SE_BACKUP_PRIVILEGES_CHECKED) != 0;
1946 }
1947 
1967 BOOLEAN
1968 NTAPI
1970  _In_ PTOKEN ProcessToken,
1971  _In_ PTOKEN TokenToImpersonate,
1973 {
1974  BOOLEAN CanImpersonate;
1975  PAGED_CODE();
1976 
1977  /*
1978  * SecurityAnonymous and SecurityIdentification levels do not
1979  * allow impersonation.
1980  */
1983  {
1984  return FALSE;
1985  }
1986 
1987  /* Time to lock our tokens */
1988  SepAcquireTokenLockShared(ProcessToken);
1989  SepAcquireTokenLockShared(TokenToImpersonate);
1990 
1991  /* What kind of authentication ID does the token have? */
1992  if (RtlEqualLuid(&TokenToImpersonate->AuthenticationId,
1994  {
1995  /*
1996  * OK, it looks like the token has an anonymous
1997  * authentication. Is that token created by the system?
1998  */
1999  if (TokenToImpersonate->TokenSource.SourceName != SeSystemTokenSource.SourceName &&
2000  !RtlEqualLuid(&TokenToImpersonate->TokenSource.SourceIdentifier, &SeSystemTokenSource.SourceIdentifier))
2001  {
2002  /* It isn't, we can't impersonate regular tokens */
2003  DPRINT("SeTokenCanImpersonate(): Token has an anonymous authentication ID, can't impersonate!\n");
2004  CanImpersonate = FALSE;
2005  goto Quit;
2006  }
2007  }
2008 
2009  /* Are the SID values from both tokens equal? */
2010  if (!RtlEqualSid(ProcessToken->UserAndGroups->Sid,
2011  TokenToImpersonate->UserAndGroups->Sid))
2012  {
2013  /* They aren't, bail out */
2014  DPRINT("SeTokenCanImpersonate(): Tokens SIDs are not equal!\n");
2015  CanImpersonate = FALSE;
2016  goto Quit;
2017  }
2018 
2019  /*
2020  * Make sure the tokens aren't diverged in terms of
2021  * restrictions, that is, one token is restricted
2022  * but the other one isn't.
2023  */
2024  if (SeTokenIsRestricted(ProcessToken) !=
2025  SeTokenIsRestricted(TokenToImpersonate))
2026  {
2027  /*
2028  * One token is restricted so we cannot
2029  * continue further at this point, bail out.
2030  */
2031  DPRINT("SeTokenCanImpersonate(): One token is restricted, can't continue!\n");
2032  CanImpersonate = FALSE;
2033  goto Quit;
2034  }
2035 
2036  /* If we've reached that far then we can impersonate! */
2037  DPRINT("SeTokenCanImpersonate(): We can impersonate.\n");
2038  CanImpersonate = TRUE;
2039 
2040 Quit:
2041  /* We're done, unlock the tokens now */
2042  SepReleaseTokenLock(ProcessToken);
2043  SepReleaseTokenLock(TokenToImpersonate);
2044 
2045  return CanImpersonate;
2046 }
2047 
2048 /* SYSTEM CALLS ***************************************************************/
2049 
2077 NTSTATUS
2078 NTAPI
2080  _In_ HANDLE ThreadHandle,
2085 {
2086  PETHREAD Thread;
2087  HANDLE hToken;
2088  PTOKEN Token, NewToken = NULL, PrimaryToken;
2094  PACL Dacl = NULL;
2096  NTSTATUS Status;
2097  BOOLEAN RestoreImpersonation = FALSE;
2098 
2099  PAGED_CODE();
2100 
2102 
2103  if (PreviousMode != KernelMode)
2104  {
2105  _SEH2_TRY
2106  {
2108  }
2110  {
2111  /* Return the exception code */
2113  }
2114  _SEH2_END;
2115  }
2116 
2117  /* Validate object attributes */
2119 
2120  /*
2121  * At first open the thread token for information access and verify
2122  * that the token associated with thread is valid.
2123  */
2124 
2127  NULL);
2128  if (!NT_SUCCESS(Status))
2129  {
2130  return Status;
2131  }
2132 
2135  if (Token == NULL)
2136  {
2138  return STATUS_NO_TOKEN;
2139  }
2140 
2142  {
2146  }
2147 
2148  /*
2149  * Revert to self if OpenAsSelf is specified.
2150  */
2151 
2152  if (OpenAsSelf)
2153  {
2154  RestoreImpersonation = PsDisableImpersonation(PsGetCurrentThread(),
2156  }
2157 
2158  if (CopyOnOpen)
2159  {
2160  PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);
2161 
2162  Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl);
2163 
2164  ObFastDereferenceObject(&Thread->ThreadsProcess->Token, PrimaryToken);
2165 
2166  if (NT_SUCCESS(Status))
2167  {
2168  if (Dacl)
2169  {
2172  if (!NT_SUCCESS(Status))
2173  {
2174  DPRINT1("NtOpenThreadTokenEx(): Failed to create a security descriptor (Status 0x%lx)\n", Status);
2175  }
2176 
2178  FALSE);
2179  if (!NT_SUCCESS(Status))
2180  {
2181  DPRINT1("NtOpenThreadTokenEx(): Failed to set a DACL to the security descriptor (Status 0x%lx)\n", Status);
2182  }
2183  }
2184 
2187 
2190  KernelMode, &NewToken);
2191  if (!NT_SUCCESS(Status))
2192  {
2193  DPRINT1("NtOpenThreadTokenEx(): Failed to duplicate the token (Status 0x%lx)\n", Status);
2194  }
2195 
2196  ObReferenceObject(NewToken);
2197  Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL,
2198  &hToken);
2199  if (!NT_SUCCESS(Status))
2200  {
2201  DPRINT1("NtOpenThreadTokenEx(): Failed to insert the token object (Status 0x%lx)\n", Status);
2202  }
2203  }
2204  else
2205  {
2206  DPRINT1("NtOpenThreadTokenEx(): Failed to impersonate token from DACL (Status 0x%lx)\n", Status);
2207  }
2208  }
2209  else
2210  {
2213  PreviousMode, &hToken);
2214  if (!NT_SUCCESS(Status))
2215  {
2216  DPRINT1("NtOpenThreadTokenEx(): Failed to open the object (Status 0x%lx)\n", Status);
2217  }
2218  }
2219 
2221 
2222  if (RestoreImpersonation)
2223  {
2225  }
2226 
2228 
2229  if (NT_SUCCESS(Status) && CopyOnOpen)
2230  {
2232  if (!NT_SUCCESS(Status))
2233  {
2234  DPRINT1("NtOpenThreadTokenEx(): Failed to impersonate the client (Status 0x%lx)\n", Status);
2235  }
2236  }
2237 
2238  if (NewToken) ObDereferenceObject(NewToken);
2239 
2241 
2242  if (NT_SUCCESS(Status))
2243  {
2244  _SEH2_TRY
2245  {
2246  *TokenHandle = hToken;
2247  }
2249  {
2251  }
2252  _SEH2_END;
2253  }
2254 
2255  return Status;
2256 }
2257 
2279 NTSTATUS
2280 NTAPI
2282  _In_ HANDLE ThreadHandle,
2286 {
2287  return NtOpenThreadTokenEx(ThreadHandle, DesiredAccess, OpenAsSelf, 0,
2288  TokenHandle);
2289 }
2290 
2308 NTSTATUS
2309 NTAPI
2311  _In_ HANDLE FirstTokenHandle,
2312  _In_ HANDLE SecondTokenHandle,
2313  _Out_ PBOOLEAN Equal)
2314 {
2316  PTOKEN FirstToken, SecondToken;
2317  BOOLEAN IsEqual;
2318  NTSTATUS Status;
2319 
2320  PAGED_CODE();
2321 
2323 
2324  if (PreviousMode != KernelMode)
2325  {
2326  _SEH2_TRY
2327  {
2328  ProbeForWriteBoolean(Equal);
2329  }
2331  {
2332  /* Return the exception code */
2334  }
2335  _SEH2_END;
2336  }
2337 
2338  Status = ObReferenceObjectByHandle(FirstTokenHandle,
2339  TOKEN_QUERY,
2341  PreviousMode,
2342  (PVOID*)&FirstToken,
2343  NULL);
2344  if (!NT_SUCCESS(Status))
2345  {
2346  DPRINT1("ObReferenceObjectByHandle() failed (Status 0x%lx)\n", Status);
2347  return Status;
2348  }
2349 
2350  Status = ObReferenceObjectByHandle(SecondTokenHandle,
2351  TOKEN_QUERY,
2353  PreviousMode,
2354  (PVOID*)&SecondToken,
2355  NULL);
2356  if (!NT_SUCCESS(Status))
2357  {
2358  DPRINT1("ObReferenceObjectByHandle() failed (Status 0x%lx)\n", Status);
2359  ObDereferenceObject(FirstToken);
2360  return Status;
2361  }
2362 
2363  if (FirstToken != SecondToken)
2364  {
2365  Status = SepCompareTokens(FirstToken,
2366  SecondToken,
2367  &IsEqual);
2368  }
2369  else
2370  {
2371  IsEqual = TRUE;
2372  }
2373 
2374  ObDereferenceObject(SecondToken);
2375  ObDereferenceObject(FirstToken);
2376 
2377  if (NT_SUCCESS(Status))
2378  {
2379  _SEH2_TRY
2380  {
2381  *Equal = IsEqual;
2382  }
2384  {
2386  }
2387  _SEH2_END;
2388  }
2389 
2390  return Status;
2391 }
2392 
2417 NTSTATUS
2418 NTAPI
2420  _In_ HANDLE ThreadHandle)
2421 {
2422  PETHREAD Thread;
2424  NTSTATUS Status;
2425  PAGED_CODE();
2426 
2428 
2429  /* Obtain the thread object from the handle */
2430  Status = ObReferenceObjectByHandle(ThreadHandle,
2432  PsThreadType,
2433  PreviousMode,
2434  (PVOID*)&Thread,
2435  NULL);
2436  if (!NT_SUCCESS(Status))
2437  {
2438  DPRINT1("NtImpersonateAnonymousToken(): Failed to reference the object (Status 0x%lx)\n", Status);
2439  return Status;
2440  }
2441 
2442  /* Call the private routine to impersonate the token */
2444  if (!NT_SUCCESS(Status))
2445  {
2446  DPRINT1("NtImpersonateAnonymousToken(): Failed to impersonate the token (Status 0x%lx)\n", Status);
2447  }
2448 
2450  return Status;
2451 }
2452 
2453 /* EOF */
PTOKEN SeAnonymousLogonTokenNoEveryone
Definition: semgr.c:20
#define OBJ_OPENLINK
Definition: winternl.h:230
VOID SepDeleteTokenLock(_Inout_ PTOKEN Token)
Deletes a lock of a token.
Definition: token.c:74
TOKEN_TYPE TokenType
Definition: setypes.h:239
const LUID SeSystemEnvironmentPrivilege
Definition: priv.c:41
#define SepAcquireTokenLockExclusive(Token)
Definition: se.h:275
NTSTATUS NTAPI NtOpenThreadTokenEx(_In_ HANDLE ThreadHandle, _In_ ACCESS_MASK DesiredAccess, _In_ BOOLEAN OpenAsSelf, _In_ ULONG HandleAttributes, _Out_ PHANDLE TokenHandle)
Opens a token that is tied to a thread handle.
Definition: token.c:2079
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSTATUS NTAPI PsImpersonateClient(IN PETHREAD Thread, IN PACCESS_TOKEN Token, IN BOOLEAN CopyOnOpen, IN BOOLEAN EffectiveOnly, IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: security.c:610
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE _In_ ACCESS_MASK _In_ ULONG HandleAttributes
Definition: obfuncs.h:429
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
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1047
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
const LUID SeSystemtimePrivilege
Definition: priv.c:31
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TOKEN_SANDBOX_INERT
Definition: setypes.h:1181
#define _In_opt_
Definition: ms_sal.h:309
BOOLEAN NTAPI SeTokenCanImpersonate(_In_ PTOKEN ProcessToken, _In_ PTOKEN TokenToImpersonate, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Ensures that client impersonation can occur by checking if the token we're going to assign as the imp...
Definition: token.c:1969
_Inout_ PSE_IMPERSONATION_STATE ImpersonationState
Definition: psfuncs.h:189
#define _Inout_
Definition: ms_sal.h:378
const LUID SeIncreaseQuotaPrivilege
Definition: priv.c:24
#define TOKEN_WRITE
Definition: setypes.h:949
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
NTSTATUS NTAPI SepCreateToken(_Out_ PHANDLE TokenHandle, _In_ KPROCESSOR_MODE PreviousMode, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ TOKEN_TYPE TokenType, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, _In_ PLUID AuthenticationId, _In_ PLARGE_INTEGER ExpirationTime, _In_ PSID_AND_ATTRIBUTES User, _In_ ULONG GroupCount, _In_ PSID_AND_ATTRIBUTES Groups, _In_ ULONG GroupsLength, _In_ ULONG PrivilegeCount, _In_ PLUID_AND_ATTRIBUTES Privileges, _In_opt_ PSID Owner, _In_ PSID PrimaryGroup, _In_opt_ PACL DefaultDacl, _In_ PTOKEN_SOURCE TokenSource, _In_ BOOLEAN SystemToken)
Internal function responsible for access token object creation in the kernel. A fully created token o...
Definition: tokenlif.c:97
#define THREAD_IMPERSONATE
Definition: pstypes.h:151
const LUID SeCreateTokenPrivilege
Definition: priv.c:21
#define _Out_
Definition: ms_sal.h:345
const LUID SeCreatePermanentPrivilege
Definition: priv.c:35
BOOLEAN NTAPI SepTokenIsOwner(_In_ PACCESS_TOKEN _Token, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ BOOLEAN TokenLocked)
Checks if a token belongs to the main user, being the owner.
Definition: token.c:511
const LUID SeDebugPrivilege
Definition: priv.c:39
const LUID SeBackupPrivilege
Definition: priv.c:36
#define TRUE
Definition: types.h:120
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PACL SeSystemDefaultDacl
Definition: acl.c:17
LUID AuthenticationId
Definition: setypes.h:219
ULONG SessionId
Definition: dllmain.c:28
VOID SepRemovePrivilegeToken(_Inout_ PTOKEN Token, _In_ ULONG Index)
Removes a privilege from the token.
Definition: token.c:582
#define STATUS_CANT_OPEN_ANONYMOUS
Definition: ntstatus.h:402
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
#define SE_RESTORE_PRIVILEGE
Definition: security.c:672
static NTSTATUS SepImpersonateAnonymousToken(_In_ PETHREAD Thread, _In_ KPROCESSOR_MODE PreviousMode)
Private function that impersonates the system's anonymous logon token. The major bulk of the imperson...
Definition: token.c:334
NTSTATUS NTAPI NtCompareTokens(_In_ HANDLE FirstTokenHandle, _In_ HANDLE SecondTokenHandle, _Out_ PBOOLEAN Equal)
Compares tokens if they're equal or not.
Definition: token.c:2310
LUID SeSystemAuthenticationId
Definition: token.c:20
_Out_ PBOOLEAN CopyOnOpen
Definition: psfuncs.h:154
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
NTSTATUS NTAPI ExDeleteResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1456
PVOID PACCESS_TOKEN
Definition: setypes.h:11
PTOKEN SeAnonymousLogonToken
Definition: semgr.c:19
#define TOKEN_HAS_TRAVERSE_PRIVILEGE
Definition: setypes.h:1174
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3062
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
const LUID SeAssignPrimaryTokenPrivilege
Definition: priv.c:22
#define TOKEN_IMPERSONATE
Definition: setypes.h:923
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
FORCEINLINE PSID SepGetOwnerFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:99
PSID SeAuthenticatedUsersSid
Definition: sid.c:49
TOpcodeData Groups[17][8]
SECURITY_IMPERSONATION_LEVEL NTAPI SeTokenImpersonationLevel(_In_ PACCESS_TOKEN Token)
Gathers the security impersonation level of an access token.
Definition: token.c:1846
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2742
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
NTSTATUS NTAPI SeIsTokenSibling(_In_ PTOKEN Token, _Out_ PBOOLEAN IsSibling)
Checks if the token is a sibling of the other token of the current process that the calling thread is...
Definition: token.c:1236
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
ULONG TokenFlags
Definition: setypes.h:241
NTSTATUS NTAPI NtImpersonateAnonymousToken(_In_ HANDLE ThreadHandle)
Allows the calling thread to impersonate the system's anonymous logon token.
Definition: token.c:2419
NTSTATUS SepRmDereferenceLogonSession(_Inout_ PLUID LogonLuid)
return STATUS_NOT_IMPLEMENTED
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
LUID SourceIdentifier
Definition: imports.h:279
NTSTATUS NTAPI SeIsTokenChild(_In_ PTOKEN Token, _Out_ PBOOLEAN IsChild)
Checks if the token is a child of the other token of the current process that the calling thread is i...
Definition: token.c:1187
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define SE_GROUP_OWNER
Definition: setypes.h:93
#define FALSE
Definition: types.h:117
LUID SeAnonymousAuthenticationId
Definition: token.c:21
NTSTATUS NTAPI SepCopyProxyData(_Out_ PVOID *Dest, _In_ PVOID Src)
Copies the proxy data from the source into the destination of a token.
Definition: token.c:815
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
enum _SECURITY_IMPERSONATION_LEVEL SECURITY_IMPERSONATION_LEVEL
NTSTATUS SepCreateTokenLock(_Inout_ PTOKEN Token)
Creates a lock for the token.
Definition: token.c:45
struct NameRec_ * Name
Definition: cdprocs.h:459
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PTOKEN NTAPI SepCreateSystemProcessToken(VOID)
Creates the system process token.
Definition: token.c:1507
VOID NTAPI PsRestoreImpersonation(IN PETHREAD Thread, IN PSE_IMPERSONATION_STATE ImpersonationState)
Definition: security.c:965
unsigned char BOOLEAN
#define STATUS_BAD_TOKEN_TYPE
Definition: ntstatus.h:404
VOID SepUpdatePrivilegeFlagsToken(_Inout_ PTOKEN Token)
Updates the token's flags based upon the privilege that the token has been granted....
Definition: token.c:554
const LUID SeLoadDriverPrivilege
Definition: priv.c:29
POBJECT_TYPE SeTokenObjectType
Definition: token.c:17
#define SE_GROUP_ENABLED_BY_DEFAULT
Definition: setypes.h:91
const LUID SeTakeOwnershipPrivilege
Definition: priv.c:28
_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
LUID ParentTokenId
Definition: setypes.h:220
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1130
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
static BOOLEAN SepCompareSidAndAttributesFromTokens(_In_ PSID_AND_ATTRIBUTES SidArrayToken1, _In_ ULONG CountSidArray1, _In_ PSID_AND_ATTRIBUTES SidArrayToken2, _In_ ULONG CountSidArray2)
Compares the elements of SID arrays provided by tokens. The elements that are being compared for equa...
Definition: token.c:107
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:381
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSTATUS SepRebuildDynamicPartOfToken(_Inout_ PTOKEN AccessToken, _In_ ULONG NewDynamicPartSize)
Re-builds the dynamic part area of an access token during an a default DACL or primary group replacem...
Definition: token.c:715
ULONG RtlLengthSidAndAttributes(_In_ ULONG Count, _In_ PSID_AND_ATTRIBUTES Src)
Computes the length size of a SID.
Definition: token.c:965
ULONG SessionId
Definition: setypes.h:225
BOOLEAN NTAPI SeTokenIsAdmin(_In_ PACCESS_TOKEN Token)
Determines if a token is either an admin token or not. Such condition is checked based upon TOKEN_HAS...
Definition: token.c:1890
VOID SepUpdateSinglePrivilegeFlagToken(_Inout_ PTOKEN Token, _In_ ULONG Index)
Updates the token's flags based upon the privilege that the token has been granted....
Definition: token.c:442
#define ANONYMOUS_LOGON_LUID
Definition: setypes.h:701
BOOLEAN NTAPI PsDisableImpersonation(IN PETHREAD Thread, OUT PSE_IMPERSONATION_STATE ImpersonationState)
Definition: security.c:915
struct _ACL * PACL
Definition: security.c:104
UNICODE_STRING Restricted
Definition: utils.c:24
PULONG DynamicPart
Definition: setypes.h:237
Status
Definition: gdiplustypes.h:24
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID _Inout_ PULONG _Out_writes_bytes_to_opt_ PrimaryGroupSize PSID PrimaryGroup
Definition: rtlfuncs.h:1585
#define SE_CHANGE_NOTIFY_PRIVILEGE
Definition: security.c:677
#define SE_PRIVILEGE_ENABLED_BY_DEFAULT
Definition: setypes.h:62
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
int Count
Definition: noreturn.cpp:7
VOID NTAPI SeGetTokenControlInformation(_In_ PACCESS_TOKEN _Token, _Out_ PTOKEN_CONTROL TokenControl)
Retrieves token control information.
Definition: token.c:1474
#define STATUS_INVALID_PRIMARY_GROUP
Definition: ntstatus.h:327
#define TOKEN_HAS_RESTORE_PRIVILEGE
Definition: setypes.h:1176
const LUID SeCreatePagefilePrivilege
Definition: priv.c:34
NTSTATUS NTAPI NtOpenThreadToken(_In_ HANDLE ThreadHandle, _In_ ACCESS_MASK DesiredAccess, _In_ BOOLEAN OpenAsSelf, _Out_ PHANDLE TokenHandle)
Opens a token that is tied to a thread handle.
Definition: token.c:2281
#define TOKEN_QUERY
Definition: setypes.h:924
#define ASSERT(a)
Definition: mode.c:44
const LUID SeRestorePrivilege
Definition: priv.c:37
PVOID FASTCALL ObFastReplaceObject(IN PEX_FAST_REF FastRef, IN PVOID Object)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SE_GROUP_ENABLED
Definition: setypes.h:92
BOOLEAN TokenInUse
Definition: setypes.h:242
_In_ WDFCOLLECTION _In_ ULONG Index
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
struct _SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES
static NTSTATUS SepCompareTokens(_In_ PTOKEN FirstToken, _In_ PTOKEN SecondToken, _Out_ PBOOLEAN Equal)
Compares tokens if they're equal based on all the following properties. If all of the said conditions...
Definition: token.c:243
_Out_ PBOOLEAN _Out_ PBOOLEAN _Out_ PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: psfuncs.h:154
#define ObDereferenceObject
Definition: obfuncs.h:203
#define STATUS_TOKEN_ALREADY_IN_USE
Definition: ntstatus.h:535
#define TOKEN_ALL_ACCESS
Definition: setypes.h:942
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
#define ProbeForWriteBoolean(Ptr)
Definition: probe.h:31
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
static const LUID SeChangeNotifyPrivilege
Definition: authpackage.c:167
VOID FASTCALL ObInitializeFastReference(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: obref.c:107
#define SE_GROUP_MANDATORY
Definition: setypes.h:90
#define STATUS_NO_TOKEN
Definition: ntstatus.h:360
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
PTOKEN SepCreateSystemAnonymousLogonToken(VOID)
Creates the anonymous logon token for the system. The difference between this token and the other one...
Definition: token.c:1657
VOID NTAPI SepInitializeTokenImplementation(VOID)
Internal function that initializes critical kernel data for access token implementation in SRM.
Definition: token.c:1403
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:13
struct _SID * PSID
Definition: eventlog.c:35
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1579
char * PBOOLEAN
Definition: retypes.h:11
POBJECT_TYPE PsThreadType
Definition: thread.c:20
BOOLEAN NTAPI SeTokenIsWriteRestricted(_In_ PACCESS_TOKEN Token)
Determines if a token is write restricted, that is, nobody can write anything to it.
Definition: token.c:1938
#define TAG_SE_TOKEN_LOCK
Definition: tag.h:159
PSID SeAliasAdminsSid
Definition: sid.c:41
#define TOKEN_READ
Definition: setypes.h:947
TOKEN_SOURCE SeSystemTokenSource
Definition: token.c:19
#define SepReleaseTokenLock(Token)
Definition: se.h:286
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
static GENERIC_MAPPING SepTokenMapping
Definition: token.c:23
#define TAG_TOKEN_DYNAMIC
Definition: tag.h:155
BOOLEAN NTAPI SeTokenIsInert(_In_ PTOKEN Token)
Determines if a token is a sandbox inert token or not, based upon the token flags.
Definition: token.c:1337
PTOKEN SepCreateSystemAnonymousLogonTokenNoEveryone(VOID)
Creates the anonymous logon token for the system. This kind of token doesn't include the everyone SID...
Definition: token.c:1725
const LUID SeLockMemoryPrivilege
Definition: priv.c:23
static BOOLEAN SepComparePrivilegeAndAttributesFromTokens(_In_ PLUID_AND_ATTRIBUTES PrivArrayToken1, _In_ ULONG CountPrivArray1, _In_ PLUID_AND_ATTRIBUTES PrivArrayToken2, _In_ ULONG CountPrivArray2)
Compares the elements of privilege arrays provided by tokens. The elements that are being compared fo...
Definition: token.c:174
const LUID SeProfileSingleProcessPrivilege
Definition: priv.c:32
PACCESS_TOKEN NTAPI PsReferencePrimaryToken(PEPROCESS Process)
Definition: security.c:440
PSID SeWorldSid
Definition: sid.c:25
PSEP_LOGON_SESSION_REFERENCES LogonSession
Definition: setypes.h:245
const LUID SeIncreaseBasePriorityPrivilege
Definition: priv.c:33
enum _TOKEN_TYPE TOKEN_TYPE
#define SYSTEM_LUID
Definition: setypes.h:700
BOOLEAN NTAPI SepSidInTokenEx(_In_ PACCESS_TOKEN _Token, _In_ PSID PrincipalSelfSid, _In_ PSID _Sid, _In_ BOOLEAN Deny, _In_ BOOLEAN Restricted)
Checks if a SID is present in a token.
Definition: sid.c:443
CCHAR SourceName[TOKEN_SOURCE_LENGTH]
Definition: imports.h:278
PACCESS_TOKEN NTAPI PsReferenceImpersonationToken(IN PETHREAD Thread, OUT PBOOLEAN CopyOnOpen, OUT PBOOLEAN EffectiveOnly, OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: security.c:849
NTSTATUS NTAPI SepRmRemoveLogonSessionFromToken(_Inout_ PTOKEN Token)
Removes a logon session from an access token.
Definition: srm.c:449
const LUID SeTcbPrivilege
Definition: priv.c:26
FORCEINLINE ULONG ObpValidateAttributes(IN ULONG Attributes, IN KPROCESSOR_MODE PreviousMode)
Definition: ob_x.h:22
#define TAG_ACL
Definition: tag.h:148
#define SE_IMPERSONATE_PRIVILEGE
Definition: security.c:683
NTSTATUS NTAPI SeSubProcessToken(_In_ PTOKEN ParentToken, _Out_ PTOKEN *Token, _In_ BOOLEAN InUse, _In_ ULONG SessionId)
Subtracts a token in exchange of duplicating a new one.
Definition: token.c:1127
const LUID SeShutdownPrivilege
Definition: priv.c:38
_SEH2_END
Definition: create.c:4400
PERESOURCE TokenLock
Definition: setypes.h:222
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
#define TOKEN_HAS_ADMIN_GROUP
Definition: setypes.h:1178
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
BOOLEAN NTAPI SeTokenIsRestricted(_In_ PACCESS_TOKEN Token)
Determines if a token is restricted or not, based upon the token flags.
Definition: token.c:1913
struct _TOKEN * PTOKEN
ULONG SepComputeAvailableDynamicSpace(_In_ ULONG DynamicCharged, _In_ PSID PrimaryGroup, _In_opt_ PACL DefaultDacl)
Computes the exact available dynamic area of an access token whilst querying token statistics.
Definition: token.c:659
TOKEN_TYPE NTAPI SeTokenType(_In_ PACCESS_TOKEN Token)
Gathers the token type of an access token. A token ca be either a primary token or impersonation toke...
Definition: token.c:1867
#define SE_BACKUP_PRIVILEGES_CHECKED
Definition: setypes.h:1183
LUID TokenId
Definition: setypes.h:218
#define _Out_opt_
Definition: ms_sal.h:346
NTSTATUS NTAPI SeQueryAuthenticationIdToken(_In_ PACCESS_TOKEN Token, _Out_ PLUID LogonId)
Queries the authentication ID of an access token.
Definition: token.c:1823
unsigned int * PULONG
Definition: retypes.h:1
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1583
#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
#define STATUS_INVALID_OWNER
Definition: ntstatus.h:326
VOID NTAPI PsDereferencePrimaryToken(IN PACCESS_TOKEN PrimaryToken)
Definition: security.c:902
#define DPRINT1
Definition: precomp.h:8
BOOL WINAPI IsChild(_In_ HWND, _In_ HWND)
const LUID SeSecurityPrivilege
Definition: priv.c:27
VOID NTAPI SepFreeProxyData(_Inout_ PVOID ProxyData)
Frees (de-allocates) the proxy data memory block of a token.
Definition: token.c:793
VOID FASTCALL ObFastDereferenceObject(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: obref.c:167
PSID SeLocalSystemSid
Definition: sid.c:38
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
VOID NTAPI SepDeleteToken(_In_ PVOID ObjectBody)
Internal function that deals with access token object destruction and deletion. The function is used ...
Definition: token.c:1359
#define SepAcquireTokenLockShared(Token)
Definition: se.h:280
#define ObReferenceObject
Definition: obfuncs.h:204
BOOLEAN NTAPI SepSidInToken(_In_ PACCESS_TOKEN _Token, _In_ PSID Sid)
Checks if a SID is present in a token.
Definition: sid.c:547
NTSTATUS SepFindPrimaryGroupAndDefaultOwner(_In_ PTOKEN Token, _In_ PSID PrimaryGroup, _In_opt_ PSID DefaultOwner, _Out_opt_ PULONG PrimaryGroupIndex, _Out_opt_ PULONG DefaultOwnerIndex)
Finds the primary group and default owner entity based on the submitted primary group instance and an...
Definition: token.c:1011
#define THREAD_QUERY_INFORMATION
Definition: pstypes.h:149
#define TOKEN_HAS_IMPERSONATE_PRIVILEGE
Definition: setypes.h:1182
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
#define SE_BACKUP_PRIVILEGE
Definition: security.c:671
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:115
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ ACCESS_MASK _In_ BOOLEAN OpenAsSelf
Definition: zwfuncs.h:699
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSTATUS NTAPI SeCopyClientToken(_In_ PACCESS_TOKEN Token, _In_ SECURITY_IMPERSONATION_LEVEL Level, _In_ KPROCESSOR_MODE PreviousMode, _Out_ PACCESS_TOKEN *NewToken)
Copies an existing access token (technically duplicating a new one).
Definition: token.c:1296
ULONG NTAPI MmGetSessionId(IN PEPROCESS Process)
Definition: session.c:179
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
PSID SeAnonymousLogonSid
Definition: se.h:203
VOID NTAPI SeDeassignPrimaryToken(_Inout_ PEPROCESS Process)
Removes the primary token of a process.
Definition: token.c:936
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define TOKEN_HAS_BACKUP_PRIVILEGE
Definition: setypes.h:1175
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI SeQuerySessionIdToken(_In_ PACCESS_TOKEN Token, _Out_ PULONG pSessionId)
Queries the session ID of an access token.
Definition: token.c:1791
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN EffectiveOnly
Definition: sefuncs.h:401
VOID SepRemoveUserGroupToken(_Inout_ PTOKEN Token, _In_ ULONG Index)
Removes a group from the token.
Definition: token.c:618
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
#define SeLengthSid(Sid)
Definition: sefuncs.h:570
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define TOKEN_SESSION_NOT_REFERENCED
Definition: setypes.h:1180
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
NTSTATUS NTAPI SepDuplicateToken(_In_ PTOKEN Token, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ BOOLEAN EffectiveOnly, _In_ TOKEN_TYPE TokenType, _In_ SECURITY_IMPERSONATION_LEVEL Level, _In_ KPROCESSOR_MODE PreviousMode, _Out_ PTOKEN *NewAccessToken)
Duplicates an access token, from an existing valid token.
Definition: tokenlif.c:471
struct _TOKEN TOKEN
const LUID SeAuditPrivilege
Definition: priv.c:40
NTSTATUS NTAPI SeExchangePrimaryToken(_In_ PEPROCESS Process, _In_ PACCESS_TOKEN NewAccessToken, _Out_ PACCESS_TOKEN *OldAccessToken)
Replaces the old access token of a process (pointed by the EPROCESS kernel structure) with a new acce...
Definition: token.c:846
PACL SeSystemAnonymousLogonDacl
Definition: acl.c:22
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define TOKEN_EXECUTE
Definition: setypes.h:954
VOID NTAPI SeAssignPrimaryToken(_In_ PEPROCESS Process, _In_ PTOKEN Token)
Assigns a primary access token to a given process.
Definition: token.c:1440
NTSTATUS NTAPI SepCreateImpersonationTokenDacl(_In_ PTOKEN Token, _In_ PTOKEN PrimaryToken, _Out_ PACL *Dacl)
Allocates a discretionary access control list based on certain properties of a regular and primary ac...
Definition: acl.c:277
NTSYSAPI BOOLEAN NTAPI RtlEqualSid(_In_ PSID Sid1, _In_ PSID Sid2)
LONGLONG QuadPart
Definition: typedefs.h:114
#define TOKEN_IS_RESTRICTED
Definition: setypes.h:1179
#define PAGED_CODE()
VOID NTAPI PsDereferenceImpersonationToken(IN PACCESS_TOKEN ImpersonationToken)
Definition: security.c:888