ReactOS 0.4.15-dev-8348-gc1b9bb5
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-2023 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
22
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
60 return STATUS_SUCCESS;
61}
62
73VOID
76{
77 PAGED_CODE();
78
79 ExDeleteResourceLite(Token->TokenLock);
81}
82
105static
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
172static
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
241static
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
303Quit:
304 /* Unlock the tokens */
305 SepReleaseTokenLock(SecondToken);
306 SepReleaseTokenLock(FirstToken);
307
308 *Equal = IsEqual;
309 return STATUS_SUCCESS;
310}
311
332static
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,
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);
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
441VOID
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 {
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
510NTAPI
512 _In_ PACCESS_TOKEN _Token,
514 _In_ BOOLEAN TokenLocked)
515{
516 PSID Sid;
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
553VOID
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
581VOID
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
617VOID
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
658ULONG
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
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
791VOID
792NTAPI
794 _Inout_ PVOID ProxyData)
795{
797}
798
814NTAPI
816 _Out_ PVOID* Dest,
817 _In_ PVOID Src)
818{
821}
822
845NTAPI
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)
858
859 if (NewToken->TokenInUse)
860 {
863
864 /* Maybe we're trying to set the same token */
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 {
877 *OldAccessToken = NULL;
878 return Status;
879 }
880
881 if (!IsEqual)
882 {
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
934VOID
935NTAPI
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
964ULONG
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
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)
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
1168static
1172 _In_ HANDLE ThreadHandle,
1173 _In_ PTOKEN ThreadToken,
1180 _Out_ PHANDLE OpenedTokenHandle)
1181{
1186 PTOKEN NewToken, PrimaryToken;
1188 PACL Dacl;
1189
1190 PAGED_CODE();
1191
1192 /* Assume no opened token handle at first */
1193 *OpenedTokenHandle = NULL;
1194
1195 /* Check if we have to do a copy of the token on open or not */
1196 if (!CopyOnOpen)
1197 {
1198 /* Just open the thread's token directly */
1199 Status = ObOpenObjectByPointer(ThreadToken,
1201 NULL,
1205 &TokenHandle);
1206 if (!NT_SUCCESS(Status))
1207 {
1208 DPRINT1("Failed to open the thread's token object (Status 0x%lx)\n", Status);
1209 return Status;
1210 }
1211
1212 /* Give it to caller */
1213 *OpenedTokenHandle = TokenHandle;
1214 return STATUS_SUCCESS;
1215 }
1216
1217 /*
1218 * The caller asks to do a copy of that token whilst it's opened.
1219 * Obtain a thread object again but this time we have to obtain
1220 * it in our side, kernel mode, and request all the access needed
1221 * to do a copy of the token because the original thread only has
1222 * query access needed for access token validation.
1223 */
1224 Status = ObReferenceObjectByHandle(ThreadHandle,
1227 KernelMode,
1228 (PVOID*)&Thread2,
1229 NULL);
1230 if (!NT_SUCCESS(Status))
1231 {
1232 DPRINT1("Failed to reference the object thread (Status 0x%lx)\n", Status);
1233 return Status;
1234 }
1235
1236 /* Check that one of the threads hasn't diverged */
1237 if (Thread != Thread2)
1238 {
1239 DPRINT1("One of the threads aren't the same (original thread 0x%p, thread 0x%p)\n", Thread, Thread2);
1242 }
1243
1244 /* Reference the primary token of the process' thread */
1245 PrimaryToken = PsReferencePrimaryToken(Thread2->ThreadsProcess);
1246 if (!PrimaryToken)
1247 {
1248 DPRINT1("Failed to reference the primary token of thread\n");
1250 return STATUS_NO_TOKEN;
1251 }
1252
1253 /* Create an impersonation DACL from the tokens we got */
1254 Status = SepCreateImpersonationTokenDacl(ThreadToken, PrimaryToken, &Dacl);
1255 ObFastDereferenceObject(&Thread2->ThreadsProcess->Token, PrimaryToken);
1256 if (!NT_SUCCESS(Status))
1257 {
1258 DPRINT1("Failed to create an impersonation token DACL (Status 0x%lx)\n", Status);
1260 return Status;
1261 }
1262
1263 /* Create a security descriptor with the DACL we got */
1266 if (!NT_SUCCESS(Status))
1267 {
1268 DPRINT1("Failed to create a security descriptor (Status 0x%lx)\n", Status);
1271 return Status;
1272 }
1273
1274 /* Attach the DACL to that security descriptor */
1276 TRUE,
1277 Dacl,
1278 FALSE);
1279 if (!NT_SUCCESS(Status))
1280 {
1281 DPRINT1("Failed to set the DACL to the security descriptor (Status 0x%lx)\n", Status);
1284 return Status;
1285 }
1286
1287 /*
1288 * Initialize the object attributes for the token we
1289 * are going to duplicate.
1290 */
1292 NULL,
1294 NULL,
1296
1297 /* Duplicate (copy) it now */
1298 Status = SepDuplicateToken(ThreadToken,
1303 KernelMode,
1304 &NewToken);
1305 if (!NT_SUCCESS(Status))
1306 {
1307 DPRINT1("Failed to duplicate the token (Status 0x%lx)\n", Status);
1310 return Status;
1311 }
1312
1313 /* Insert that copied token into the handle now */
1314 ObReferenceObject(NewToken);
1315 Status = ObInsertObject(NewToken,
1316 NULL,
1318 0,
1319 NULL,
1320 &TokenHandle);
1321 if (!NT_SUCCESS(Status))
1322 {
1323 DPRINT1("Failed to insert the token object (Status 0x%lx)\n", Status);
1325 ObDereferenceObject(NewToken);
1327 return Status;
1328 }
1329
1330 /* We're almost done, free the DACL if we got one */
1332
1333 /* Impersonate the client finally */
1335 if (!NT_SUCCESS(Status))
1336 {
1337 DPRINT1("Failed to impersonate the client (Status 0x%lx)\n", Status);
1338 ObDereferenceObject(NewToken);
1340 return Status;
1341 }
1342
1343 /* Give the newly opened token handle to caller */
1344 *OpenedTokenHandle = TokenHandle;
1345 ObDereferenceObject(NewToken);
1347 return Status;
1348}
1349
1372NTAPI
1374 _In_ PTOKEN ParentToken,
1376 _In_ BOOLEAN InUse,
1378{
1379 PTOKEN NewToken;
1382
1383 /* Initialize the attributes and duplicate it */
1385 Status = SepDuplicateToken(ParentToken,
1387 FALSE,
1389 ParentToken->ImpersonationLevel,
1390 KernelMode,
1391 &NewToken);
1392 if (NT_SUCCESS(Status))
1393 {
1394 /* Insert it */
1395 Status = ObInsertObject(NewToken,
1396 NULL,
1397 0,
1398 0,
1399 NULL,
1400 NULL);
1401 if (NT_SUCCESS(Status))
1402 {
1403 /* Set the session ID */
1404 NewToken->SessionId = SessionId;
1405 NewToken->TokenInUse = InUse;
1406
1407 /* Return the token */
1408 *Token = NewToken;
1409 }
1410 }
1411
1412 /* Return status */
1413 return Status;
1414}
1415
1432NTAPI
1436{
1437 PTOKEN ProcessToken;
1438 LUID ProcessTokenId, CallerParentId;
1439
1440 /* Assume failure */
1441 *IsChild = FALSE;
1442
1443 /* Reference the process token */
1445 if (!ProcessToken)
1446 return STATUS_UNSUCCESSFUL;
1447
1448 /* Get its token ID */
1449 ProcessTokenId = ProcessToken->TokenId;
1450
1451 /* Dereference the token */
1453
1454 /* Get our parent token ID */
1455 CallerParentId = Token->ParentTokenId;
1456
1457 /* Compare the token IDs */
1458 if (RtlEqualLuid(&CallerParentId, &ProcessTokenId))
1459 *IsChild = TRUE;
1460
1461 /* Return success */
1462 return STATUS_SUCCESS;
1463}
1464
1481NTAPI
1484 _Out_ PBOOLEAN IsSibling)
1485{
1486 PTOKEN ProcessToken;
1487 LUID ProcessParentId, ProcessAuthId;
1488 LUID CallerParentId, CallerAuthId;
1489
1490 /* Assume failure */
1491 *IsSibling = FALSE;
1492
1493 /* Reference the process token */
1495 if (!ProcessToken)
1496 return STATUS_UNSUCCESSFUL;
1497
1498 /* Get its parent and authentication IDs */
1499 ProcessParentId = ProcessToken->ParentTokenId;
1500 ProcessAuthId = ProcessToken->AuthenticationId;
1501
1502 /* Dereference the token */
1504
1505 /* Get our parent and authentication IDs */
1506 CallerParentId = Token->ParentTokenId;
1507 CallerAuthId = Token->AuthenticationId;
1508
1509 /* Compare the token IDs */
1510 if (RtlEqualLuid(&CallerParentId, &ProcessParentId) &&
1511 RtlEqualLuid(&CallerAuthId, &ProcessAuthId))
1512 {
1513 *IsSibling = TRUE;
1514 }
1515
1516 /* Return success */
1517 return STATUS_SUCCESS;
1518}
1519
1541NTAPI
1546 _Out_ PACCESS_TOKEN* NewToken)
1547{
1550
1551 PAGED_CODE();
1552
1554 NULL,
1555 0,
1556 NULL,
1557 NULL);
1558
1561 FALSE,
1563 Level,
1565 (PTOKEN*)NewToken);
1566
1567 return Status;
1568}
1569
1581BOOLEAN
1582NTAPI
1585{
1586 PAGED_CODE();
1587
1588 return (((PTOKEN)Token)->TokenFlags & TOKEN_SANDBOX_INERT) != 0;
1589}
1590
1603VOID
1604NTAPI
1606 _In_ PVOID ObjectBody)
1607{
1609 PTOKEN AccessToken = (PTOKEN)ObjectBody;
1610
1611 DPRINT("SepDeleteToken()\n");
1612
1613 /* Remove the referenced logon session from token */
1614 if (AccessToken->LogonSession)
1615 {
1617 if (!NT_SUCCESS(Status))
1618 {
1619 /* Something seriously went wrong */
1620 DPRINT1("SepDeleteToken(): Failed to remove the logon session from token (Status: 0x%lx)\n", Status);
1621 return;
1622 }
1623 }
1624
1625 /* Dereference the logon session */
1626 if ((AccessToken->TokenFlags & TOKEN_SESSION_NOT_REFERENCED) == 0)
1628
1629 /* Delete the token lock */
1630 if (AccessToken->TokenLock)
1631 SepDeleteTokenLock(AccessToken);
1632
1633 /* Delete the dynamic information area */
1634 if (AccessToken->DynamicPart)
1636}
1637
1646CODE_SEG("INIT")
1647VOID
1648NTAPI
1650{
1652 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
1653
1654 DPRINT("Creating Token Object Type\n");
1655
1656 /* Initialize the Token type */
1657 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
1658 RtlInitUnicodeString(&Name, L"Token");
1659 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
1660 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
1661 ObjectTypeInitializer.SecurityRequired = TRUE;
1662 ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(TOKEN);
1663 ObjectTypeInitializer.GenericMapping = SepTokenMapping;
1664 ObjectTypeInitializer.PoolType = PagedPool;
1665 ObjectTypeInitializer.ValidAccessMask = TOKEN_ALL_ACCESS;
1666 ObjectTypeInitializer.UseDefaultObject = TRUE;
1667 ObjectTypeInitializer.DeleteProcedure = SepDeleteToken;
1668 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &SeTokenObjectType);
1669}
1670
1684VOID
1685NTAPI
1689{
1690 PAGED_CODE();
1691
1692 /* Sanity checks */
1693 ASSERT(Token->TokenType == TokenPrimary);
1694 ASSERT(!Token->TokenInUse);
1695
1696 /* Clean any previous token */
1697 if (Process->Token.Object) SeDeassignPrimaryToken(Process);
1698
1699 /* Set the new token */
1701 Token->TokenInUse = TRUE;
1703}
1704
1718VOID
1719NTAPI
1721 _In_ PACCESS_TOKEN _Token,
1722 _Out_ PTOKEN_CONTROL TokenControl)
1723{
1724 PTOKEN Token = _Token;
1725 PAGED_CODE();
1726
1727 /* Capture the main fields */
1728 TokenControl->AuthenticationId = Token->AuthenticationId;
1729 TokenControl->TokenId = Token->TokenId;
1730 TokenControl->TokenSource = Token->TokenSource;
1731
1732 /* Lock the token */
1734
1735 /* Capture the modified ID */
1736 TokenControl->ModifiedId = Token->ModifiedId;
1737
1738 /* Unlock it */
1740}
1741
1750CODE_SEG("INIT")
1751PTOKEN
1752NTAPI
1754{
1755 ULONG GroupAttributes, OwnerAttributes;
1756 LARGE_INTEGER Expiration;
1757 SID_AND_ATTRIBUTES UserSid;
1758 ULONG GroupsLength;
1761 PSID Owner;
1762 PTOKEN Token;
1764
1765 /* Don't ever expire */
1766 Expiration.QuadPart = -1;
1767
1768 /* All groups mandatory and enabled */
1771
1772 /* User is Local System */
1773 UserSid.Sid = SeLocalSystemSid;
1774 UserSid.Attributes = 0;
1775
1776 /* Primary group is Local System */
1778
1779 /* Owner is Administrators */
1781
1782 /* Groups are Administrators, World, and Authenticated Users */
1783 SID_AND_ATTRIBUTES Groups[] =
1784 {
1785 {SeAliasAdminsSid, OwnerAttributes},
1786 {SeWorldSid, GroupAttributes},
1787 {SeAuthenticatedUsersSid, GroupAttributes},
1788 {SeLocalSid, SE_GROUP_ENABLED} // HACK: Temporarily add the local group. See CORE-18250.
1789 };
1790 GroupsLength = sizeof(SID_AND_ATTRIBUTES) +
1791 SeLengthSid(Groups[0].Sid) +
1792 SeLengthSid(Groups[1].Sid) +
1793 SeLengthSid(Groups[2].Sid) +
1794 SeLengthSid(Groups[3].Sid); // HACK
1795 ASSERT(GroupsLength <= (sizeof(Groups) * sizeof(ULONG)));
1796
1797 /* Setup the privileges */
1799 {
1814 {SeBackupPrivilege, 0},
1815 {SeRestorePrivilege, 0},
1820 {SeUndockPrivilege, 0},
1824 };
1825
1826 /* Setup the object attributes */
1829
1830 /* Create the token */
1832 KernelMode,
1833 0,
1838 &Expiration,
1839 &UserSid,
1840 RTL_NUMBER_OF(Groups),
1841 Groups,
1842 GroupsLength,
1844 Privileges,
1845 Owner,
1849 TRUE);
1851
1852 /* Return the token */
1853 return Token;
1854}
1855
1866CODE_SEG("INIT")
1867PTOKEN
1869{
1870 SID_AND_ATTRIBUTES UserSid;
1872 PTOKEN Token;
1873 ULONG GroupsLength;
1874 LARGE_INTEGER Expiration;
1877
1878 /* The token never expires */
1879 Expiration.QuadPart = -1;
1880
1881 /* The user is the anonymous logon */
1882 UserSid.Sid = SeAnonymousLogonSid;
1883 UserSid.Attributes = 0;
1884
1885 /* The primary group is also the anonymous logon */
1887
1888 /* The only group for the token is the World */
1889 SID_AND_ATTRIBUTES Groups[] =
1890 {
1892 };
1893 GroupsLength = sizeof(SID_AND_ATTRIBUTES) +
1894 SeLengthSid(Groups[0].Sid);
1895 ASSERT(GroupsLength <= (sizeof(Groups) * sizeof(ULONG)));
1896
1897 /* Initialise the object attributes for the token */
1900
1901 /* Create token */
1903 KernelMode,
1904 0,
1909 &Expiration,
1910 &UserSid,
1911 RTL_NUMBER_OF(Groups),
1912 Groups,
1913 GroupsLength,
1914 0,
1915 NULL,
1916 NULL,
1920 TRUE);
1922
1923 /* Return the anonymous logon token */
1924 return Token;
1925}
1926
1936CODE_SEG("INIT")
1937PTOKEN
1939{
1940 SID_AND_ATTRIBUTES UserSid;
1942 PTOKEN Token;
1943 LARGE_INTEGER Expiration;
1946
1947 /* The token never expires */
1948 Expiration.QuadPart = -1;
1949
1950 /* The user is the anonymous logon */
1951 UserSid.Sid = SeAnonymousLogonSid;
1952 UserSid.Attributes = 0;
1953
1954 /* The primary group is also the anonymous logon */
1956
1957 /* Initialise the object attributes for the token */
1960
1961 /* Create token */
1963 KernelMode,
1964 0,
1969 &Expiration,
1970 &UserSid,
1971 0,
1972 NULL,
1973 0,
1974 0,
1975 NULL,
1976 NULL,
1980 TRUE);
1982
1983 /* Return the anonymous (not including everyone) logon token */
1984 return Token;
1985}
1986
1987/* PUBLIC FUNCTIONS ***********************************************************/
1988
2003NTAPI
2006 _Out_ PULONG pSessionId)
2007{
2008 PAGED_CODE();
2009
2010 /* Lock the token */
2012
2013 *pSessionId = ((PTOKEN)Token)->SessionId;
2014
2015 /* Unlock the token */
2017
2018 return STATUS_SUCCESS;
2019}
2020
2035NTAPI
2039{
2040 PAGED_CODE();
2041
2042 *LogonId = ((PTOKEN)Token)->AuthenticationId;
2043
2044 return STATUS_SUCCESS;
2045}
2046
2058NTAPI
2061{
2062 PAGED_CODE();
2063
2064 return ((PTOKEN)Token)->ImpersonationLevel;
2065}
2066
2079NTAPI
2082{
2083 PAGED_CODE();
2084
2085 return ((PTOKEN)Token)->TokenType;
2086}
2087
2101BOOLEAN
2102NTAPI
2105{
2106 PAGED_CODE();
2107
2108 // NOTE: Win7+ instead really checks the list of groups in the token
2109 // (since TOKEN_HAS_ADMIN_GROUP == TOKEN_WRITE_RESTRICTED ...)
2110 return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_ADMIN_GROUP) != 0;
2111}
2112
2124BOOLEAN
2125NTAPI
2128{
2129 PAGED_CODE();
2130
2131 return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0;
2132}
2133
2149BOOLEAN
2150NTAPI
2153{
2154 PAGED_CODE();
2155
2156 // NOTE: NT 5.1 SP2 x86 checks the SE_BACKUP_PRIVILEGES_CHECKED flag
2157 // while Vista+ checks the TOKEN_WRITE_RESTRICTED flag as one expects.
2158 return (((PTOKEN)Token)->TokenFlags & SE_BACKUP_PRIVILEGES_CHECKED) != 0;
2159}
2160
2205BOOLEAN
2206NTAPI
2208 _In_ PTOKEN ProcessToken,
2209 _In_ PTOKEN TokenToImpersonate,
2211{
2212 BOOLEAN CanImpersonate;
2213 PAGED_CODE();
2214
2215 /*
2216 * The server may want to obtain identification details of a client
2217 * instead of impersonating so just give the server a pass.
2218 */
2220 {
2221 DPRINT("The server doesn't ask for impersonation\n");
2222 return TRUE;
2223 }
2224
2225 /* Time to lock our tokens */
2226 SepAcquireTokenLockShared(ProcessToken);
2227 SepAcquireTokenLockShared(TokenToImpersonate);
2228
2229 /*
2230 * As the name implies, an anonymous token has invisible security
2231 * identification details. By the general rule these tokens do not
2232 * pose a danger in terms of power escalation so give the server a pass.
2233 */
2234 if (RtlEqualLuid(&TokenToImpersonate->AuthenticationId,
2236 {
2237 DPRINT("The token to impersonate has an anonymous authentication ID, allow impersonation either way\n");
2238 CanImpersonate = TRUE;
2239 goto Quit;
2240 }
2241
2242 /* Allow impersonation for the process server if it's granted the impersonation privilege */
2243 if ((ProcessToken->TokenFlags & TOKEN_HAS_IMPERSONATE_PRIVILEGE) != 0)
2244 {
2245 DPRINT("The process is granted the impersonation privilege, allow impersonation\n");
2246 CanImpersonate = TRUE;
2247 goto Quit;
2248 }
2249
2250 /*
2251 * Deny impersonation for the server if it wants to impersonate a client
2252 * beyond what the impersonation level originally permits.
2253 */
2254 if (ImpersonationLevel > TokenToImpersonate->ImpersonationLevel)
2255 {
2256 DPRINT1("Cannot impersonate a client above the permitted impersonation level!\n");
2257 CanImpersonate = FALSE;
2258 goto Quit;
2259 }
2260
2261 /* Is the server authenticated on the same client originating session? */
2262 if (!RtlEqualLuid(&ProcessToken->AuthenticationId,
2263 &TokenToImpersonate->OriginatingLogonSession))
2264 {
2265 /* It's not, check that at least both the server and client are the same user */
2266 if (!RtlEqualSid(ProcessToken->UserAndGroups[0].Sid,
2267 TokenToImpersonate->UserAndGroups[0].Sid))
2268 {
2269 DPRINT1("Server and client aren't the same user!\n");
2270 CanImpersonate = FALSE;
2271 goto Quit;
2272 }
2273
2274 /*
2275 * Make sure the tokens haven't diverged in terms of restrictions
2276 * that is one token is restricted but the other one isn't. If that
2277 * would have been the case then the server would have impersonated
2278 * a less restricted client thus potentially triggering an elevation,
2279 * which is not what we want.
2280 */
2281 if (SeTokenIsRestricted(ProcessToken) !=
2282 SeTokenIsRestricted(TokenToImpersonate))
2283 {
2284 DPRINT1("Attempting to impersonate a less restricted client token, bail out!\n");
2285 CanImpersonate = FALSE;
2286 goto Quit;
2287 }
2288 }
2289
2290 /* If we've reached that far then we can impersonate! */
2291 DPRINT("We can impersonate\n");
2292 CanImpersonate = TRUE;
2293
2294Quit:
2295 SepReleaseTokenLock(TokenToImpersonate);
2296 SepReleaseTokenLock(ProcessToken);
2297 return CanImpersonate;
2298}
2299
2300/* SYSTEM CALLS ***************************************************************/
2301
2330NTAPI
2332 _In_ HANDLE ThreadHandle,
2337{
2339 HANDLE hToken;
2340 PTOKEN Token;
2346 BOOLEAN RestoreImpersonation = FALSE;
2347
2348 PAGED_CODE();
2349
2351
2352 /* Ensure that we can give the handle to the caller */
2353 if (PreviousMode != KernelMode)
2354 {
2355 _SEH2_TRY
2356 {
2358 }
2360 {
2361 /* Return the exception code */
2363 }
2364 _SEH2_END;
2365 }
2366
2367 /* Validate object attributes */
2369
2370 /*
2371 * At first open the thread token for information access and verify
2372 * that the token associated with the thread is valid.
2373 */
2376 NULL);
2377 if (!NT_SUCCESS(Status))
2378 {
2379 DPRINT1("Failed to reference the object thread (Status 0x%lx)\n", Status);
2380 return Status;
2381 }
2382
2383 /* Reference the token from the thread */
2386 if (Token == NULL)
2387 {
2388 DPRINT("Failed to reference the thread's impersonation token, thread has no token\n");
2390 return STATUS_NO_TOKEN;
2391 }
2392
2393 /* Ensure the token has no anonymous security */
2395 {
2396 DPRINT1("The thread token has anonymous security, can't open it\n");
2400 }
2401
2402 /* Revert to self if OpenAsSelf is specified */
2403 if (OpenAsSelf)
2404 {
2405 RestoreImpersonation = PsDisableImpersonation(PsGetCurrentThread(),
2407 }
2408
2409 /* Call the private function to do the job */
2411 ThreadHandle,
2412 Token,
2416 CopyOnOpen,
2419 &hToken);
2420
2421 /* Restore the impersonation back if needed */
2422 if (RestoreImpersonation)
2423 {
2425 }
2426
2427 /* Dereference the access token and the associated thread */
2430
2431 if (!NT_SUCCESS(Status))
2432 {
2433 DPRINT1("Failed to open the thread's token (Status 0x%lx)\n", Status);
2434 return Status;
2435 }
2436
2437 /* Give the opened token handle to the caller */
2438 _SEH2_TRY
2439 {
2440 *TokenHandle = hToken;
2441 }
2443 {
2445 }
2446 _SEH2_END;
2447
2448 return Status;
2449}
2450
2473NTAPI
2475 _In_ HANDLE ThreadHandle,
2479{
2480 return NtOpenThreadTokenEx(ThreadHandle, DesiredAccess, OpenAsSelf, 0,
2481 TokenHandle);
2482}
2483
2502NTAPI
2504 _In_ HANDLE FirstTokenHandle,
2505 _In_ HANDLE SecondTokenHandle,
2506 _Out_ PBOOLEAN Equal)
2507{
2509 PTOKEN FirstToken, SecondToken;
2512
2513 PAGED_CODE();
2514
2516
2517 if (PreviousMode != KernelMode)
2518 {
2519 _SEH2_TRY
2520 {
2521 ProbeForWriteBoolean(Equal);
2522 }
2524 {
2525 /* Return the exception code */
2527 }
2528 _SEH2_END;
2529 }
2530
2531 Status = ObReferenceObjectByHandle(FirstTokenHandle,
2535 (PVOID*)&FirstToken,
2536 NULL);
2537 if (!NT_SUCCESS(Status))
2538 {
2539 DPRINT1("ObReferenceObjectByHandle() failed (Status 0x%lx)\n", Status);
2540 return Status;
2541 }
2542
2543 Status = ObReferenceObjectByHandle(SecondTokenHandle,
2547 (PVOID*)&SecondToken,
2548 NULL);
2549 if (!NT_SUCCESS(Status))
2550 {
2551 DPRINT1("ObReferenceObjectByHandle() failed (Status 0x%lx)\n", Status);
2552 ObDereferenceObject(FirstToken);
2553 return Status;
2554 }
2555
2556 if (FirstToken != SecondToken)
2557 {
2558 Status = SepCompareTokens(FirstToken,
2559 SecondToken,
2560 &IsEqual);
2561 }
2562 else
2563 {
2564 IsEqual = TRUE;
2565 }
2566
2567 ObDereferenceObject(SecondToken);
2568 ObDereferenceObject(FirstToken);
2569
2570 if (NT_SUCCESS(Status))
2571 {
2572 _SEH2_TRY
2573 {
2574 *Equal = IsEqual;
2575 }
2577 {
2579 }
2580 _SEH2_END;
2581 }
2582
2583 return Status;
2584}
2585
2611NTAPI
2613 _In_ HANDLE ThreadHandle)
2614{
2618 PAGED_CODE();
2619
2621
2622 /* Obtain the thread object from the handle */
2623 Status = ObReferenceObjectByHandle(ThreadHandle,
2627 (PVOID*)&Thread,
2628 NULL);
2629 if (!NT_SUCCESS(Status))
2630 {
2631 DPRINT1("NtImpersonateAnonymousToken(): Failed to reference the object (Status 0x%lx)\n", Status);
2632 return Status;
2633 }
2634
2635 /* Call the private routine to impersonate the token */
2637 if (!NT_SUCCESS(Status))
2638 {
2639 DPRINT1("NtImpersonateAnonymousToken(): Failed to impersonate the token (Status 0x%lx)\n", Status);
2640 }
2641
2643 return Status;
2644}
2645
2646/* EOF */
#define PAGED_CODE()
#define CODE_SEG(...)
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
static DWORD WINAPI Thread2(_Inout_opt_ PVOID Parameter)
struct NameRec_ * Name
Definition: cdprocs.h:460
TOKEN_TYPE
Definition: asmpp.cpp:29
static const LUID SeCreateGlobalPrivilege
Definition: authpackage.c:168
static const LUID SeChangeNotifyPrivilege
Definition: authpackage.c:167
static const LUID SeImpersonatePrivilege
Definition: authpackage.c:169
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:118
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
ULONG SessionId
Definition: dllmain.c:28
UNICODE_STRING Restricted
Definition: utils.c:24
#define ULONG_PTR
Definition: config.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
#define NonPagedPool
Definition: env_spec_w32.h:307
ULONG ERESOURCE
Definition: env_spec_w32.h:594
#define PagedPool
Definition: env_spec_w32.h:308
#define ExGetPreviousMode
Definition: ex.h:140
@ IsEqual
Definition: fatprocs.h:1886
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
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
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define THREAD_IMPERSONATE
Definition: pstypes.h:151
#define THREAD_QUERY_INFORMATION
Definition: pstypes.h:149
#define OBJ_OPENLINK
Definition: winternl.h:230
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
enum _SECURITY_IMPERSONATION_LEVEL SECURITY_IMPERSONATION_LEVEL
@ SecurityImpersonation
Definition: lsa.idl:57
@ SecurityAnonymous
Definition: lsa.idl:55
@ SecurityIdentification
Definition: lsa.idl:56
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
@ TokenImpersonation
Definition: imports.h:274
@ TokenPrimary
Definition: imports.h:273
#define PsDereferencePrimaryToken(T)
Definition: imports.h:301
#define PsDereferenceImpersonationToken(T)
Definition: imports.h:298
#define SE_IMPERSONATE_PRIVILEGE
Definition: security.c:683
#define SE_BACKUP_PRIVILEGE
Definition: security.c:671
#define SE_RESTORE_PRIVILEGE
Definition: security.c:672
#define SE_CHANGE_NOTIFY_PRIVILEGE
Definition: security.c:677
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
struct _SID * PSID
Definition: eventlog.c:35
struct _ACL * PACL
Definition: security.c:105
#define _Out_opt_
Definition: ms_sal.h:346
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
#define KernelMode
Definition: asm.h:34
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE _In_ ACCESS_MASK _In_ ULONG HandleAttributes
Definition: obfuncs.h:433
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:726
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1605
_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:1609
_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:1611
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1145
NTSYSAPI BOOLEAN NTAPI RtlEqualSid(_In_ PSID Sid1, _In_ PSID Sid2)
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN EffectiveOnly
Definition: sefuncs.h:410
#define SE_GROUP_OWNER
Definition: setypes.h:93
struct _TOKEN * PTOKEN
#define SE_GROUP_MANDATORY
Definition: setypes.h:90
#define SE_GROUP_ENABLED_BY_DEFAULT
Definition: setypes.h:91
struct _TOKEN TOKEN
#define SE_GROUP_ENABLED
Definition: setypes.h:92
int Count
Definition: noreturn.cpp:7
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_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
ULONG NTAPI MmGetSessionId(IN PEPROCESS Process)
Definition: session.c:179
PSID SeLocalSystemSid
Definition: sid.c:38
NTSTATUS NTAPI SepRmRemoveLogonSessionFromToken(_Inout_ PTOKEN Token)
Removes a logon session from an access token.
Definition: srm.c:449
const LUID SeDebugPrivilege
Definition: priv.c:39
PTOKEN SeAnonymousLogonToken
Definition: semgr.c:19
NTSTATUS SepRmDereferenceLogonSession(_Inout_ PLUID LogonLuid)
const LUID SeCreateTokenPrivilege
Definition: priv.c:21
const LUID SeBackupPrivilege
Definition: priv.c:36
const LUID SeAssignPrimaryTokenPrivilege
Definition: priv.c:22
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
FORCEINLINE PSID SepGetOwnerFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:109
BOOLEAN NTAPI SepSidInToken(_In_ PACCESS_TOKEN _Token, _In_ PSID Sid)
Checks if a SID is present in a token.
Definition: sid.c:547
#define SepAcquireTokenLockShared(Token)
Definition: se.h:290
PACL SeSystemAnonymousLogonDacl
Definition: acl.c:22
const LUID SeSystemtimePrivilege
Definition: priv.c:31
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
PSID SeAliasAdminsSid
Definition: sid.c:41
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
PSID SeAnonymousLogonSid
Definition: se.h:213
const LUID SeTcbPrivilege
Definition: priv.c:26
PSID SeWorldSid
Definition: sid.c:25
const LUID SeManageVolumePrivilege
Definition: priv.c:47
const LUID SeRestorePrivilege
Definition: priv.c:37
PTOKEN SeAnonymousLogonTokenNoEveryone
Definition: semgr.c:20
const LUID SeLoadDriverPrivilege
Definition: priv.c:29
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
const LUID SeIncreaseBasePriorityPrivilege
Definition: priv.c:33
const LUID SeLockMemoryPrivilege
Definition: priv.c:23
const LUID SeCreatePermanentPrivilege
Definition: priv.c:35
PSID SeLocalSid
Definition: sid.c:26
#define SepAcquireTokenLockExclusive(Token)
Definition: se.h:285
const LUID SeUndockPrivilege
Definition: priv.c:44
const LUID SeCreatePagefilePrivilege
Definition: priv.c:34
const LUID SeTakeOwnershipPrivilege
Definition: priv.c:28
const LUID SeProfileSingleProcessPrivilege
Definition: priv.c:32
const LUID SeShutdownPrivilege
Definition: priv.c:38
const LUID SeSystemEnvironmentPrivilege
Definition: priv.c:41
const LUID SeSecurityPrivilege
Definition: priv.c:27
#define SepReleaseTokenLock(Token)
Definition: se.h:296
PSID SeAuthenticatedUsersSid
Definition: sid.c:49
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
const LUID SeAuditPrivilege
Definition: priv.c:40
const LUID SeIncreaseQuotaPrivilege
Definition: priv.c:24
BOOLEAN NTAPI PsDisableImpersonation(IN PETHREAD Thread, OUT PSE_IMPERSONATION_STATE ImpersonationState)
Definition: security.c:937
VOID NTAPI PsRestoreImpersonation(IN PETHREAD Thread, IN PSE_IMPERSONATION_STATE ImpersonationState)
Definition: security.c:987
PACCESS_TOKEN NTAPI PsReferencePrimaryToken(PEPROCESS Process)
Definition: security.c:440
PACCESS_TOKEN NTAPI PsReferenceImpersonationToken(IN PETHREAD Thread, OUT PBOOLEAN CopyOnOpen, OUT PBOOLEAN EffectiveOnly, OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: security.c:871
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
POBJECT_TYPE PsThreadType
Definition: thread.c:20
PACL SeSystemDefaultDacl
Definition: acl.c:17
BOOLEAN NTAPI SeTokenCanImpersonate(_In_ PTOKEN ProcessToken, _In_ PTOKEN TokenToImpersonate, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Determines whether the server is allowed to impersonate on behalf of a client or not....
Definition: token.c:2207
NTSTATUS NTAPI SeQueryAuthenticationIdToken(_In_ PACCESS_TOKEN Token, _Out_ PLUID LogonId)
Queries the authentication ID of an access token.
Definition: token.c:2036
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
SECURITY_IMPERSONATION_LEVEL NTAPI SeTokenImpersonationLevel(_In_ PACCESS_TOKEN Token)
Gathers the security impersonation level of an access token.
Definition: token.c:2059
VOID SepRemovePrivilegeToken(_Inout_ PTOKEN Token, _In_ ULONG Index)
Removes a privilege from the token.
Definition: token.c:582
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
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:1583
VOID NTAPI SepInitializeTokenImplementation(VOID)
Internal function that initializes critical kernel data for access token implementation in SRM.
Definition: token.c:1649
TOKEN_SOURCE SeSystemTokenSource
Definition: token.c:19
PTOKEN NTAPI SepCreateSystemProcessToken(VOID)
Creates the system process token.
Definition: token.c:1753
NTSTATUS SepCreateTokenLock(_Inout_ PTOKEN Token)
Creates a lock for the token.
Definition: token.c:45
VOID NTAPI SepDeleteToken(_In_ PVOID ObjectBody)
Internal function that deals with access token object destruction and deletion. The function is used ...
Definition: token.c:1605
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:1542
static NTSTATUS SepOpenThreadToken(_In_ PETHREAD Thread, _In_ HANDLE ThreadHandle, _In_ PTOKEN ThreadToken, _In_ ACCESS_MASK DesiredAccess, _In_ ULONG HandleAttributes, _In_ BOOLEAN EffectiveOnly, _In_ BOOLEAN CopyOnOpen, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, _In_ KPROCESSOR_MODE PreviousMode, _Out_ PHANDLE OpenedTokenHandle)
Internal private function that returns an opened handle of an access token associated with a thread.
Definition: token.c:1170
VOID NTAPI SepFreeProxyData(_Inout_ PVOID ProxyData)
Frees (de-allocates) the proxy data memory block of a token.
Definition: token.c:793
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:1482
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:1373
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:2474
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:2151
VOID NTAPI SeAssignPrimaryToken(_In_ PEPROCESS Process, _In_ PTOKEN Token)
Assigns a primary access token to a given process.
Definition: token.c:1686
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
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
ULONG RtlLengthSidAndAttributes(_In_ ULONG Count, _In_ PSID_AND_ATTRIBUTES Src)
Computes the length size of a SID.
Definition: token.c:965
PTOKEN SepCreateSystemAnonymousLogonTokenNoEveryone(VOID)
Creates the anonymous logon token for the system. This kind of token doesn't include the everyone SID...
Definition: token.c:1938
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
VOID SepUpdatePrivilegeFlagsToken(_Inout_ PTOKEN Token)
Updates the token's flags based upon the privilege that the token has been granted....
Definition: token.c:554
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
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:2080
LUID SeSystemAuthenticationId
Definition: token.c:20
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
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:2103
VOID NTAPI SeGetTokenControlInformation(_In_ PACCESS_TOKEN _Token, _Out_ PTOKEN_CONTROL TokenControl)
Retrieves token control information.
Definition: token.c:1720
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:1433
VOID NTAPI SeDeassignPrimaryToken(_Inout_ PEPROCESS Process)
Removes the primary token of a process.
Definition: token.c:936
PTOKEN SepCreateSystemAnonymousLogonToken(VOID)
Creates the anonymous logon token for the system. The difference between this token and the other one...
Definition: token.c:1868
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
VOID SepRemoveUserGroupToken(_Inout_ PTOKEN Token, _In_ ULONG Index)
Removes a group from the token.
Definition: token.c:618
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
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
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:2331
LUID SeAnonymousAuthenticationId
Definition: token.c:21
POBJECT_TYPE SeTokenObjectType
Definition: token.c:17
VOID SepDeleteTokenLock(_Inout_ PTOKEN Token)
Deletes a lock of a token.
Definition: token.c:74
NTSTATUS NTAPI NtImpersonateAnonymousToken(_In_ HANDLE ThreadHandle)
Allows the calling thread to impersonate the system's anonymous logon token.
Definition: token.c:2612
NTSTATUS NTAPI SeQuerySessionIdToken(_In_ PACCESS_TOKEN Token, _Out_ PULONG pSessionId)
Queries the session ID of an access token.
Definition: token.c:2004
BOOLEAN NTAPI SeTokenIsRestricted(_In_ PACCESS_TOKEN Token)
Determines if a token is restricted or not, based upon the token flags.
Definition: token.c:2126
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 NtCompareTokens(_In_ HANDLE FirstTokenHandle, _In_ HANDLE SecondTokenHandle, _Out_ PBOOLEAN Equal)
Compares tokens if they're equal or not.
Definition: token.c:2503
static GENERIC_MAPPING SepTokenMapping
Definition: token.c:23
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_NO_TOKEN
Definition: ntstatus.h:360
#define STATUS_TOKEN_ALREADY_IN_USE
Definition: ntstatus.h:535
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_BAD_TOKEN_TYPE
Definition: ntstatus.h:404
#define STATUS_CANT_OPEN_ANONYMOUS
Definition: ntstatus.h:402
#define STATUS_INVALID_PRIMARY_GROUP
Definition: ntstatus.h:327
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
#define STATUS_INVALID_OWNER
Definition: ntstatus.h:326
#define L(x)
Definition: ntvdm.h:50
VOID FASTCALL ObInitializeFastReference(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: obref.c:107
PVOID FASTCALL ObFastReplaceObject(IN PEX_FAST_REF FastRef, IN PVOID Object)
VOID FASTCALL ObFastDereferenceObject(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: obref.c:167
FORCEINLINE ULONG ObpValidateAttributes(IN ULONG Attributes, IN KPROCESSOR_MODE PreviousMode)
Definition: ob_x.h:22
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
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
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
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 ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:381
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define REG_DWORD
Definition: sdbapi.c:596
#define ProbeForWriteHandle(Ptr)
Definition: probe.h:43
#define ProbeForWriteBoolean(Ptr)
Definition: probe.h:31
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
LUID AuthenticationId
Definition: setypes.h:219
ULONG SessionId
Definition: setypes.h:225
TOKEN_TYPE TokenType
Definition: setypes.h:239
ULONG TokenFlags
Definition: setypes.h:241
LUID ParentTokenId
Definition: setypes.h:220
BOOLEAN TokenInUse
Definition: setypes.h:242
LUID TokenId
Definition: setypes.h:218
PERESOURCE TokenLock
Definition: setypes.h:222
PULONG DynamicPart
Definition: setypes.h:237
PSEP_LOGON_SESSION_REFERENCES LogonSession
Definition: setypes.h:245
#define TAG_TOKEN_DYNAMIC
Definition: tag.h:158
#define TAG_ACL
Definition: tag.h:151
#define TAG_SE_TOKEN_LOCK
Definition: tag.h:162
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
BOOL WINAPI IsChild(_In_ HWND, _In_ HWND)
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
_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:191
_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:409
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
_Out_ PBOOLEAN CopyOnOpen
Definition: psfuncs.h:154
_Inout_ PSE_IMPERSONATION_STATE ImpersonationState
Definition: psfuncs.h:189
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_Out_ PBOOLEAN _Out_ PBOOLEAN _Out_ PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: psfuncs.h:156
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:17
#define SeLengthSid(Sid)
Definition: sefuncs.h:570
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define TOKEN_SESSION_NOT_REFERENCED
Definition: setypes.h:1184
#define TOKEN_HAS_TRAVERSE_PRIVILEGE
Definition: setypes.h:1178
#define TOKEN_QUERY
Definition: setypes.h:928
#define TOKEN_HAS_BACKUP_PRIVILEGE
Definition: setypes.h:1179
#define TOKEN_HAS_IMPERSONATE_PRIVILEGE
Definition: setypes.h:1186
#define TOKEN_WRITE
Definition: setypes.h:953
#define TOKEN_HAS_RESTORE_PRIVILEGE
Definition: setypes.h:1180
#define SYSTEM_LUID
Definition: setypes.h:700
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define TOKEN_READ
Definition: setypes.h:951
struct _SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES
#define TOKEN_SANDBOX_INERT
Definition: setypes.h:1185
#define TOKEN_IMPERSONATE
Definition: setypes.h:927
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
#define TOKEN_IS_RESTRICTED
Definition: setypes.h:1183
#define SE_BACKUP_PRIVILEGES_CHECKED
Definition: setypes.h:1187
#define SE_PRIVILEGE_ENABLED_BY_DEFAULT
Definition: setypes.h:62
PVOID PACCESS_TOKEN
Definition: setypes.h:11
#define TOKEN_HAS_ADMIN_GROUP
Definition: setypes.h:1182
#define TOKEN_EXECUTE
Definition: setypes.h:958
#define TOKEN_ALL_ACCESS
Definition: setypes.h:946
#define ANONYMOUS_LOGON_LUID
Definition: setypes.h:701
_In_ ACCESS_MASK _In_ BOOLEAN OpenAsSelf
Definition: zwfuncs.h:700