token.c (632fa1cf) token.c (6413009c)
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Security token implementation support
5 * COPYRIGHT: Copyright David Welch <welch@cwcom.net>
6 * Copyright 2021 George Bișoc <george.bisoc@reactos.org>
7 */
8

--- 453 unchanged lines hidden (view full) ---

462 DPRINT1("SepImpersonateAnonymousToken(): Failed to impersonate, bail out...\n");
463 ObDereferenceObject(TokenToImpersonate);
464 return Status;
465 }
466
467 return Status;
468}
469
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Security token implementation support
5 * COPYRIGHT: Copyright David Welch <welch@cwcom.net>
6 * Copyright 2021 George Bișoc <george.bisoc@reactos.org>
7 */
8

--- 453 unchanged lines hidden (view full) ---

462 DPRINT1("SepImpersonateAnonymousToken(): Failed to impersonate, bail out...\n");
463 ObDereferenceObject(TokenToImpersonate);
464 return Status;
465 }
466
467 return Status;
468}
469
470/**
471 * @brief
472 * Updates the token's flags based upon the privilege that the token
473 * has been granted. The flag can either be taken out or given to the token
474 * if the attributes of the specified privilege is enabled or not.
475 *
476 * @param[in,out] Token
477 * The token where the flags are to be changed.
478 *
479 * @param[in] Index
480 * The index count which represents the total sum of privileges. The count in question
481 * MUST NOT exceed the expected privileges count of the token.
482 *
483 * @return
484 * Nothing.
485 */
470static
471VOID
472SepUpdateSinglePrivilegeFlagToken(
473 _Inout_ PTOKEN Token,
474 _In_ ULONG Index)
475{
476 ULONG TokenFlag;
477 ASSERT(Index < Token->PrivilegeCount);

--- 35 unchanged lines hidden (view full) ---

513 }
514 else
515 {
516 /* Is is disabled, so remove the flag */
517 Token->TokenFlags &= ~TokenFlag;
518 }
519}
520
486static
487VOID
488SepUpdateSinglePrivilegeFlagToken(
489 _Inout_ PTOKEN Token,
490 _In_ ULONG Index)
491{
492 ULONG TokenFlag;
493 ASSERT(Index < Token->PrivilegeCount);

--- 35 unchanged lines hidden (view full) ---

529 }
530 else
531 {
532 /* Is is disabled, so remove the flag */
533 Token->TokenFlags &= ~TokenFlag;
534 }
535}
536
537/**
538 * @brief
539 * Updates the token's flags based upon the privilege that the token
540 * has been granted. The function uses the private helper, SepUpdateSinglePrivilegeFlagToken,
541 * in order to update the flags of a token.
542 *
543 * @param[in,out] Token
544 * The token where the flags are to be changed.
545 *
546 * @return
547 * Nothing.
548 */
521static
522VOID
523SepUpdatePrivilegeFlagsToken(
524 _Inout_ PTOKEN Token)
525{
526 ULONG i;
527
528 /* Loop all privileges */
529 for (i = 0; i < Token->PrivilegeCount; i++)
530 {
549static
550VOID
551SepUpdatePrivilegeFlagsToken(
552 _Inout_ PTOKEN Token)
553{
554 ULONG i;
555
556 /* Loop all privileges */
557 for (i = 0; i < Token->PrivilegeCount; i++)
558 {
531 /* Updates the flags dor this privilege */
559 /* Updates the flags for this privilege */
532 SepUpdateSinglePrivilegeFlagToken(Token, i);
533 }
534}
535
560 SepUpdateSinglePrivilegeFlagToken(Token, i);
561 }
562}
563
564/**
565 * @brief
566 * Removes a privilege from the token.
567 *
568 * @param[in,out] Token
569 * The token where the privilege is to be removed.
570 *
571 * @param[in] Index
572 * The index count which represents the number position of the privilege
573 * we want to remove.
574 *
575 * @return
576 * Nothing.
577 */
536static
537VOID
538SepRemovePrivilegeToken(
539 _Inout_ PTOKEN Token,
540 _In_ ULONG Index)
541{
542 ULONG MoveCount;
543 ASSERT(Index < Token->PrivilegeCount);

--- 7 unchanged lines hidden (view full) ---

551 &Token->Privileges[Index + 1],
552 MoveCount * sizeof(LUID_AND_ATTRIBUTES));
553 }
554
555 /* Update privilege count */
556 Token->PrivilegeCount--;
557}
558
578static
579VOID
580SepRemovePrivilegeToken(
581 _Inout_ PTOKEN Token,
582 _In_ ULONG Index)
583{
584 ULONG MoveCount;
585 ASSERT(Index < Token->PrivilegeCount);

--- 7 unchanged lines hidden (view full) ---

593 &Token->Privileges[Index + 1],
594 MoveCount * sizeof(LUID_AND_ATTRIBUTES));
595 }
596
597 /* Update privilege count */
598 Token->PrivilegeCount--;
599}
600
601/**
602 * @unimplemented
603 * @brief
604 * Frees (de-allocates) the proxy data memory block of a token.
605 *
606 * @param[in,out] ProxyData
607 * The proxy data to be freed.
608 *
609 * @return
610 * Nothing.
611 */
559VOID
560NTAPI
561SepFreeProxyData(PVOID ProxyData)
562{
563 UNIMPLEMENTED;
564}
565
612VOID
613NTAPI
614SepFreeProxyData(PVOID ProxyData)
615{
616 UNIMPLEMENTED;
617}
618
619/**
620 * @unimplemented
621 * @brief
622 * Copies the proxy data from the source into the destination of a token.
623 *
624 * @param[out] Dest
625 * The destination path where the proxy data is to be copied to.
626 *
627 * @param[out] Src
628 * The source path where the proxy data is be copied from.
629 *
630 * @return
631 * To be added...
632 */
566NTSTATUS
567NTAPI
568SepCopyProxyData(PVOID* Dest,
569 PVOID Src)
570{
571 UNIMPLEMENTED;
572 return STATUS_NOT_IMPLEMENTED;
573}
574
633NTSTATUS
634NTAPI
635SepCopyProxyData(PVOID* Dest,
636 PVOID Src)
637{
638 UNIMPLEMENTED;
639 return STATUS_NOT_IMPLEMENTED;
640}
641
642/**
643 * @brief
644 * Replaces the old access token of a process (pointed by the EPROCESS kernel structure) with a
645 * new access token. The new access token must be a primary token for use.
646 *
647 * @param[in] Process
648 * The process instance where its access token is about to be replaced.
649 *
650 * @param[in] NewAccessToken
651 * The new token that it's going to replace the old one.
652 *
653 * @param[out] OldAccessToken
654 * The returned old token that's been replaced, which the caller can do anything.
655 *
656 * @return
657 * Returns STATUS_SUCCESS if the exchange operation between tokens has completed successfully.
658 * STATUS_BAD_TOKEN_TYPE is returned if the new token is not a primary one so that we cannot
659 * exchange it with the old one from the process. STATUS_TOKEN_ALREADY_IN_USE is returned if
660 * both tokens aren't equal which means one of them has different properties (groups, privileges, etc.)
661 * and as such one of them is currently in use. A failure NTSTATUS code is returned otherwise.
662 */
575NTSTATUS
576NTAPI
577SeExchangePrimaryToken(
578 _In_ PEPROCESS Process,
579 _In_ PACCESS_TOKEN NewAccessToken,
580 _Out_ PACCESS_TOKEN* OldAccessToken)
581{
582 PTOKEN OldToken;

--- 64 unchanged lines hidden (view full) ---

647
648 /* Unlock the old token */
649 SepReleaseTokenLock(OldToken);
650
651 *OldAccessToken = (PACCESS_TOKEN)OldToken;
652 return STATUS_SUCCESS;
653}
654
663NTSTATUS
664NTAPI
665SeExchangePrimaryToken(
666 _In_ PEPROCESS Process,
667 _In_ PACCESS_TOKEN NewAccessToken,
668 _Out_ PACCESS_TOKEN* OldAccessToken)
669{
670 PTOKEN OldToken;

--- 64 unchanged lines hidden (view full) ---

735
736 /* Unlock the old token */
737 SepReleaseTokenLock(OldToken);
738
739 *OldAccessToken = (PACCESS_TOKEN)OldToken;
740 return STATUS_SUCCESS;
741}
742
743/**
744 * @brief
745 * Removes the primary token of a process.
746 *
747 * @param[in, out] Process
748 * The process instance with the access token to be removed.
749 *
750 * @return
751 * Nothing.
752 */
655VOID
656NTAPI
657SeDeassignPrimaryToken(PEPROCESS Process)
658{
659 PTOKEN OldToken;
660
661 /* Remove the Token */
662 OldToken = ObFastReplaceObject(&Process->Token, NULL);
663
664 /* Mark the Old Token as free */
665 OldToken->TokenInUse = FALSE;
666
667 /* Dereference the Token */
668 ObDereferenceObject(OldToken);
669}
670
753VOID
754NTAPI
755SeDeassignPrimaryToken(PEPROCESS Process)
756{
757 PTOKEN OldToken;
758
759 /* Remove the Token */
760 OldToken = ObFastReplaceObject(&Process->Token, NULL);
761
762 /* Mark the Old Token as free */
763 OldToken->TokenInUse = FALSE;
764
765 /* Dereference the Token */
766 ObDereferenceObject(OldToken);
767}
768
769/**
770 * @brief
771 * Computes the length size of a SID.
772 *
773 * @param[in] Count
774 * Total count of entries that have SIDs in them (that being PSID_AND_ATTRIBUTES in this context).
775 *
776 * @param[in] Src
777 * Source that points to the attributes and SID entry structure.
778 *
779 * @return
780 * Returns the total length of a SID size.
781 */
671static ULONG
672RtlLengthSidAndAttributes(ULONG Count,
673 PSID_AND_ATTRIBUTES Src)
674{
675 ULONG i;
676 ULONG uLength;
677
678 PAGED_CODE();
679
680 uLength = Count * sizeof(SID_AND_ATTRIBUTES);
681 for (i = 0; i < Count; i++)
682 uLength += RtlLengthSid(Src[i].Sid);
683
684 return uLength;
685}
686
782static ULONG
783RtlLengthSidAndAttributes(ULONG Count,
784 PSID_AND_ATTRIBUTES Src)
785{
786 ULONG i;
787 ULONG uLength;
788
789 PAGED_CODE();
790
791 uLength = Count * sizeof(SID_AND_ATTRIBUTES);
792 for (i = 0; i < Count; i++)
793 uLength += RtlLengthSid(Src[i].Sid);
794
795 return uLength;
796}
797
687
798/**
799 * @brief
800 * Finds the primary group and default owner entity based on the submitted primary group instance
801 * and an access token.
802 *
803 * @param[in] Token
804 * Access token to begin the search query of primary group and default owner.
805 *
806 * @param[in] PrimaryGroup
807 * A primary group SID to be used for search query, determining if user & groups of a token
808 * and the submitted primary group do match.
809 *
810 * @param[in] DefaultOwner
811 * The default owner. If specified, it's used to determine if the token belongs to the actual user,
812 * that is, being the owner himself.
813 *
814 * @param[out] PrimaryGroupIndex
815 * Returns the primary group index.
816 *
817 * @param[out] DefaultOwnerIndex
818 * Returns the default owner index.
819 *
820 * @return
821 * Returns STATUS_SUCCESS if the find query operation has completed successfully and that at least one
822 * search result is requested by the caller. STATUS_INVALID_PARAMETER is returned if the caller hasn't requested
823 * any search result. STATUS_INVALID_OWNER is returned if the specified default user owner does not match with the other
824 * user from the token. STATUS_INVALID_PRIMARY_GROUP is returned if the specified default primary group does not match with the
825 * other group from the token.
826 */
688static NTSTATUS
689SepFindPrimaryGroupAndDefaultOwner(
690 _In_ PTOKEN Token,
691 _In_ PSID PrimaryGroup,
692 _In_opt_ PSID DefaultOwner,
693 _Out_opt_ PULONG PrimaryGroupIndex,
694 _Out_opt_ PULONG DefaultOwnerIndex)
695{

--- 78 unchanged lines hidden (view full) ---

774 if (*PrimaryGroupIndex == Token->UserAndGroupCount)
775 // if (Token->PrimaryGroup == NULL)
776 return STATUS_INVALID_PRIMARY_GROUP;
777 }
778
779 return STATUS_SUCCESS;
780}
781
827static NTSTATUS
828SepFindPrimaryGroupAndDefaultOwner(
829 _In_ PTOKEN Token,
830 _In_ PSID PrimaryGroup,
831 _In_opt_ PSID DefaultOwner,
832 _Out_opt_ PULONG PrimaryGroupIndex,
833 _Out_opt_ PULONG DefaultOwnerIndex)
834{

--- 78 unchanged lines hidden (view full) ---

913 if (*PrimaryGroupIndex == Token->UserAndGroupCount)
914 // if (Token->PrimaryGroup == NULL)
915 return STATUS_INVALID_PRIMARY_GROUP;
916 }
917
918 return STATUS_SUCCESS;
919}
920
782
921/**
922 * @brief
923 * Duplicates an access token, from an existing valid token.
924 *
925 * @param[in] Token
926 * Access token to duplicate.
927 *
928 * @param[in] ObjectAttributes
929 * Object attributes for the new token.
930 *
931 * @param[in] EffectiveOnly
932 * If set to TRUE, the function removes all the disabled privileges and groups of the token
933 * to duplicate.
934 *
935 * @param[in] TokenType
936 * Type of token.
937 *
938 * @param[in] Level
939 * Security impersonation level of a token.
940 *
941 * @param[in] PreviousMode
942 * The processor request level mode.
943 *
944 * @param[out] NewAccessToken
945 * The duplicated token.
946 *
947 * @return
948 * Returns STATUS_SUCCESS if the token has been duplicated. STATUS_INSUFFICIENT_RESOURCES is returned
949 * if memory pool allocation of the dynamic part of the token for duplication has failed due to the lack
950 * of memory resources. A failure NTSTATUS code is returned otherwise.
951 */
783NTSTATUS
784NTAPI
785SepDuplicateToken(
786 _In_ PTOKEN Token,
787 _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
788 _In_ BOOLEAN EffectiveOnly,
789 _In_ TOKEN_TYPE TokenType,
790 _In_ SECURITY_IMPERSONATION_LEVEL Level,

--- 228 unchanged lines hidden (view full) ---

1019
1020 /* Dereference the token, the delete procedure will clean it up */
1021 ObDereferenceObject(AccessToken);
1022 }
1023
1024 return Status;
1025}
1026
952NTSTATUS
953NTAPI
954SepDuplicateToken(
955 _In_ PTOKEN Token,
956 _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
957 _In_ BOOLEAN EffectiveOnly,
958 _In_ TOKEN_TYPE TokenType,
959 _In_ SECURITY_IMPERSONATION_LEVEL Level,

--- 228 unchanged lines hidden (view full) ---

1188
1189 /* Dereference the token, the delete procedure will clean it up */
1190 ObDereferenceObject(AccessToken);
1191 }
1192
1193 return Status;
1194}
1195
1196/**
1197 * @brief
1198 * Subtracts a token in exchange of duplicating a new one.
1199 *
1200 * @param[in] ParentToken
1201 * The parent access token for duplication.
1202 *
1203 * @param[out] Token
1204 * The new duplicated token.
1205 *
1206 * @param[in] InUse
1207 * Set this to TRUE if the token is about to be used immediately after the call execution
1208 * of this function, FALSE otherwise.
1209 *
1210 * @param[in] SessionId
1211 * Session ID for the token to be assigned.
1212 *
1213 * @return
1214 * Returns STATUS_SUCCESS if token subtracting and duplication have completed successfully.
1215 * A failure NTSTATUS code is returned otherwise.
1216 */
1027NTSTATUS
1028NTAPI
1029SeSubProcessToken(IN PTOKEN ParentToken,
1030 OUT PTOKEN *Token,
1031 IN BOOLEAN InUse,
1032 IN ULONG SessionId)
1033{
1034 PTOKEN NewToken;

--- 28 unchanged lines hidden (view full) ---

1063 *Token = NewToken;
1064 }
1065 }
1066
1067 /* Return status */
1068 return Status;
1069}
1070
1217NTSTATUS
1218NTAPI
1219SeSubProcessToken(IN PTOKEN ParentToken,
1220 OUT PTOKEN *Token,
1221 IN BOOLEAN InUse,
1222 IN ULONG SessionId)
1223{
1224 PTOKEN NewToken;

--- 28 unchanged lines hidden (view full) ---

1253 *Token = NewToken;
1254 }
1255 }
1256
1257 /* Return status */
1258 return Status;
1259}
1260
1261/**
1262 * @brief
1263 * Checks if the token is a child of the other token
1264 * of the current process that the calling thread is invoking this function.
1265 *
1266 * @param[in] Token
1267 * An access token to determine if it's a child or not.
1268 *
1269 * @param[out] IsChild
1270 * The returned boolean result.
1271 *
1272 * @return
1273 * Returns STATUS_SUCCESS when the function finishes its operation. STATUS_UNSUCCESSFUL is
1274 * returned if primary token of the current calling process couldn't be referenced otherwise.
1275 */
1071NTSTATUS
1072NTAPI
1073SeIsTokenChild(IN PTOKEN Token,
1074 OUT PBOOLEAN IsChild)
1075{
1076 PTOKEN ProcessToken;
1077 LUID ProcessTokenId, CallerParentId;
1078

--- 17 unchanged lines hidden (view full) ---

1096 /* Compare the token IDs */
1097 if (RtlEqualLuid(&CallerParentId, &ProcessTokenId))
1098 *IsChild = TRUE;
1099
1100 /* Return success */
1101 return STATUS_SUCCESS;
1102}
1103
1276NTSTATUS
1277NTAPI
1278SeIsTokenChild(IN PTOKEN Token,
1279 OUT PBOOLEAN IsChild)
1280{
1281 PTOKEN ProcessToken;
1282 LUID ProcessTokenId, CallerParentId;
1283

--- 17 unchanged lines hidden (view full) ---

1301 /* Compare the token IDs */
1302 if (RtlEqualLuid(&CallerParentId, &ProcessTokenId))
1303 *IsChild = TRUE;
1304
1305 /* Return success */
1306 return STATUS_SUCCESS;
1307}
1308
1309/**
1310 * @brief
1311 * Checks if the token is a sibling of the other token of
1312 * the current process that the calling thread is invoking this function.
1313 *
1314 * @param[in] Token
1315 * An access token to determine if it's a sibling or not.
1316 *
1317 * @param[out] IsSibling
1318 * The returned boolean result.
1319 *
1320 * @return
1321 * Returns STATUS_SUCCESS when the function finishes its operation. STATUS_UNSUCCESSFUL is
1322 * returned if primary token of the current calling process couldn't be referenced otherwise.
1323 */
1104NTSTATUS
1105NTAPI
1106SeIsTokenSibling(IN PTOKEN Token,
1107 OUT PBOOLEAN IsSibling)
1108{
1109 PTOKEN ProcessToken;
1110 LUID ProcessParentId, ProcessAuthId;
1111 LUID CallerParentId, CallerAuthId;

--- 23 unchanged lines hidden (view full) ---

1135 {
1136 *IsSibling = TRUE;
1137 }
1138
1139 /* Return success */
1140 return STATUS_SUCCESS;
1141}
1142
1324NTSTATUS
1325NTAPI
1326SeIsTokenSibling(IN PTOKEN Token,
1327 OUT PBOOLEAN IsSibling)
1328{
1329 PTOKEN ProcessToken;
1330 LUID ProcessParentId, ProcessAuthId;
1331 LUID CallerParentId, CallerAuthId;

--- 23 unchanged lines hidden (view full) ---

1355 {
1356 *IsSibling = TRUE;
1357 }
1358
1359 /* Return success */
1360 return STATUS_SUCCESS;
1361}
1362
1363/**
1364 * @brief
1365 * Copies an existing access token (technically duplicating a new one).
1366 *
1367 * @param[in] Token
1368 * Token to copy.
1369 *
1370 * @param[in] Level
1371 * Impersonation security level to assign to the newly copied token.
1372 *
1373 * @param[in] PreviousMode
1374 * Processor request level mode.
1375 *
1376 * @param[out] NewToken
1377 * The newly copied token.
1378 *
1379 * @return
1380 * Returns STATUS_SUCCESS when token copying has finished successfully. A failure
1381 * NTSTATUS code is returned otherwise.
1382 */
1143NTSTATUS
1144NTAPI
1145SeCopyClientToken(IN PACCESS_TOKEN Token,
1146 IN SECURITY_IMPERSONATION_LEVEL Level,
1147 IN KPROCESSOR_MODE PreviousMode,
1148 OUT PACCESS_TOKEN* NewToken)
1149{
1150 NTSTATUS Status;

--- 13 unchanged lines hidden (view full) ---

1164 TokenImpersonation,
1165 Level,
1166 PreviousMode,
1167 (PTOKEN*)NewToken);
1168
1169 return Status;
1170}
1171
1383NTSTATUS
1384NTAPI
1385SeCopyClientToken(IN PACCESS_TOKEN Token,
1386 IN SECURITY_IMPERSONATION_LEVEL Level,
1387 IN KPROCESSOR_MODE PreviousMode,
1388 OUT PACCESS_TOKEN* NewToken)
1389{
1390 NTSTATUS Status;

--- 13 unchanged lines hidden (view full) ---

1404 TokenImpersonation,
1405 Level,
1406 PreviousMode,
1407 (PTOKEN*)NewToken);
1408
1409 return Status;
1410}
1411
1412/**
1413 * @brief
1414 * Internal function that deals with access token object destruction and deletion.
1415 * The function is used solely by the object manager mechanism that handles the life
1416 * management of a token object.
1417 *
1418 * @param[in] ObjectBody
1419 * The object body that represents an access token object.
1420 *
1421 * @return
1422 * Nothing.
1423 */
1172VOID
1173NTAPI
1174SepDeleteToken(PVOID ObjectBody)
1175{
1176 NTSTATUS Status;
1177 PTOKEN AccessToken = (PTOKEN)ObjectBody;
1178
1179 DPRINT("SepDeleteToken()\n");

--- 18 unchanged lines hidden (view full) ---

1198 if (AccessToken->TokenLock)
1199 SepDeleteTokenLock(AccessToken);
1200
1201 /* Delete the dynamic information area */
1202 if (AccessToken->DynamicPart)
1203 ExFreePoolWithTag(AccessToken->DynamicPart, TAG_TOKEN_DYNAMIC);
1204}
1205
1424VOID
1425NTAPI
1426SepDeleteToken(PVOID ObjectBody)
1427{
1428 NTSTATUS Status;
1429 PTOKEN AccessToken = (PTOKEN)ObjectBody;
1430
1431 DPRINT("SepDeleteToken()\n");

--- 18 unchanged lines hidden (view full) ---

1450 if (AccessToken->TokenLock)
1451 SepDeleteTokenLock(AccessToken);
1452
1453 /* Delete the dynamic information area */
1454 if (AccessToken->DynamicPart)
1455 ExFreePoolWithTag(AccessToken->DynamicPart, TAG_TOKEN_DYNAMIC);
1456}
1457
1206
1458/**
1459 * @brief
1460 * Internal function that initializes critical kernel data for access
1461 * token implementation in SRM.
1462 *
1463 * @return
1464 * Nothing.
1465 */
1207CODE_SEG("INIT")
1208VOID
1209NTAPI
1210SepInitializeTokenImplementation(VOID)
1211{
1212 UNICODE_STRING Name;
1213 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
1214

--- 9 unchanged lines hidden (view full) ---

1224 ObjectTypeInitializer.GenericMapping = SepTokenMapping;
1225 ObjectTypeInitializer.PoolType = PagedPool;
1226 ObjectTypeInitializer.ValidAccessMask = TOKEN_ALL_ACCESS;
1227 ObjectTypeInitializer.UseDefaultObject = TRUE;
1228 ObjectTypeInitializer.DeleteProcedure = SepDeleteToken;
1229 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &SeTokenObjectType);
1230}
1231
1466CODE_SEG("INIT")
1467VOID
1468NTAPI
1469SepInitializeTokenImplementation(VOID)
1470{
1471 UNICODE_STRING Name;
1472 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
1473

--- 9 unchanged lines hidden (view full) ---

1483 ObjectTypeInitializer.GenericMapping = SepTokenMapping;
1484 ObjectTypeInitializer.PoolType = PagedPool;
1485 ObjectTypeInitializer.ValidAccessMask = TOKEN_ALL_ACCESS;
1486 ObjectTypeInitializer.UseDefaultObject = TRUE;
1487 ObjectTypeInitializer.DeleteProcedure = SepDeleteToken;
1488 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &SeTokenObjectType);
1489}
1490
1491/**
1492 * @brief
1493 * Assigns a primary access token to a given process.
1494 *
1495 * @param[in] Process
1496 * Process where the token is about to be assigned.
1497 *
1498 * @param[in] Token
1499 * The token to be assigned.
1500 *
1501 * @return
1502 * Nothing.
1503 */
1232VOID
1233NTAPI
1234SeAssignPrimaryToken(IN PEPROCESS Process,
1235 IN PTOKEN Token)
1236{
1237 PAGED_CODE();
1238
1239 /* Sanity checks */

--- 4 unchanged lines hidden (view full) ---

1244 if (Process->Token.Object) SeDeassignPrimaryToken(Process);
1245
1246 /* Set the new token */
1247 ObReferenceObject(Token);
1248 Token->TokenInUse = TRUE;
1249 ObInitializeFastReference(&Process->Token, Token);
1250}
1251
1504VOID
1505NTAPI
1506SeAssignPrimaryToken(IN PEPROCESS Process,
1507 IN PTOKEN Token)
1508{
1509 PAGED_CODE();
1510
1511 /* Sanity checks */

--- 4 unchanged lines hidden (view full) ---

1516 if (Process->Token.Object) SeDeassignPrimaryToken(Process);
1517
1518 /* Set the new token */
1519 ObReferenceObject(Token);
1520 Token->TokenInUse = TRUE;
1521 ObInitializeFastReference(&Process->Token, Token);
1522}
1523
1524/**
1525 * @brief
1526 * Internal function responsible for access token object creation in the kernel.
1527 * A fully created token objected is inserted into the token handle, thus the handle
1528 * becoming a valid handle to an access token object and ready for use.
1529 *
1530 * @param[out] TokenHandle
1531 * Valid token handle that's ready for use after token creation and object insertion.
1532 *
1533 * @param[in] PreviousMode
1534 * Processor request level mode.
1535 *
1536 * @param[in] DesiredAccess
1537 * Desired access right for the token object to be granted. This kind of access right
1538 * impacts how the token can be used and who.
1539 *
1540 * @param[in] ObjectAttributes
1541 * Object attributes for the token to be created.
1542 *
1543 * @param[in] TokenType
1544 * Type of token to assign upon creation.
1545 *
1546 * @param[in] ImpersonationLevel
1547 * Security impersonation level of token to assign upon creation.
1548 *
1549 * @param[in] AuthenticationId
1550 * Authentication ID that represents the authentication information of the token.
1551 *
1552 * @param[in] ExpirationTime
1553 * Expiration time of the token to assign. A value of -1 means that the token never
1554 * expires and its life depends upon the amount of references this token object has.
1555 *
1556 * @param[in] User
1557 * User entry to assign to the token.
1558 *
1559 * @param[in] GroupCount
1560 * The total number of groups count for the token.
1561 *
1562 * @param[in] Groups
1563 * The group entries for the token.
1564 *
1565 * @param[in] GroupsLength
1566 * The length size of the groups array, pointed by the Groups parameter.
1567 *
1568 * @param[in] PrivilegeCount
1569 * The total number of priivleges that the newly created token has.
1570 *
1571 * @param[in] Privileges
1572 * The privileges for the token.
1573 *
1574 * @param[in] Owner
1575 * The main user (or also owner) that represents the token that we create.
1576 *
1577 * @param[in] PrimaryGroup
1578 * The main group that represents the token that we create.
1579 *
1580 * @param[in] DefaultDacl
1581 * A discretionary access control list for the token.
1582 *
1583 * @param[in] TokenSource
1584 * Source (or the origin) of the access token that creates it.
1585 *
1586 * @param[in] SystemToken
1587 * If set to TRUE, the newly created token is a system token and only in charge
1588 * by the internal system. The function directly returns a pointer to the
1589 * created token object for system kernel use. Otherwise if set to FALSE, the
1590 * function inserts the object to a handle making it a regular access token.
1591 *
1592 * @return
1593 * Returns STATUS_SUCCESS if token creation has completed successfully.
1594 * STATUS_INSUFFICIENT_RESOURCES is returned if the dynamic area of memory of the
1595 * token hasn't been allocated because of lack of memory resources. A failure
1596 * NTSTATUS code is returned otherwise.
1597 */
1252NTSTATUS
1253NTAPI
1254SepCreateToken(
1255 _Out_ PHANDLE TokenHandle,
1256 _In_ KPROCESSOR_MODE PreviousMode,
1257 _In_ ACCESS_MASK DesiredAccess,
1258 _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
1259 _In_ TOKEN_TYPE TokenType,

--- 539 unchanged lines hidden (view full) ---

1799 ASSERT(Status == STATUS_SUCCESS);
1800
1801 /* Return the anonymous (not including everyone) logon token */
1802 return Token;
1803}
1804
1805/* PUBLIC FUNCTIONS ***********************************************************/
1806
1598NTSTATUS
1599NTAPI
1600SepCreateToken(
1601 _Out_ PHANDLE TokenHandle,
1602 _In_ KPROCESSOR_MODE PreviousMode,
1603 _In_ ACCESS_MASK DesiredAccess,
1604 _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
1605 _In_ TOKEN_TYPE TokenType,

--- 539 unchanged lines hidden (view full) ---

2145 ASSERT(Status == STATUS_SUCCESS);
2146
2147 /* Return the anonymous (not including everyone) logon token */
2148 return Token;
2149}
2150
2151/* PUBLIC FUNCTIONS ***********************************************************/
2152
1807/*
2153/**
1808 * @unimplemented
2154 * @unimplemented
2155 * @brief
2156 * Filters an access token from an existing token, making it more restricted
2157 * than the previous one.
2158 *
2159 * @param[in] ExistingToken
2160 * An existing token for filtering.
2161 *
2162 * @param[in] Flags
2163 * Privilege flag options. This parameter argument influences how the token
2164 * is filtered. Such parameter can be 0.
2165 *
2166 * @param[in] SidsToDisable
2167 * Array of SIDs to disable.
2168 *
2169 * @param[in] PrivilegesToDelete
2170 * Array of privileges to delete.
2171 *
2172 * @param[in] RestrictedSids
2173 * An array of restricted SIDs for the new filtered token.
2174 *
2175 * @param[out] FilteredToken
2176 * The newly filtered token, returned to the caller.
2177 *
2178 * @return
2179 * To be added...
1809 */
1810NTSTATUS
1811NTAPI
1812SeFilterToken(IN PACCESS_TOKEN ExistingToken,
1813 IN ULONG Flags,
1814 IN PTOKEN_GROUPS SidsToDisable OPTIONAL,
1815 IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL,
1816 IN PTOKEN_GROUPS RestrictedSids OPTIONAL,

--- 367 unchanged lines hidden (view full) ---

2184 }
2185
2186 /* Release the lock of the token */
2187 SepReleaseTokenLock(Token);
2188
2189 return Status;
2190}
2191
2180 */
2181NTSTATUS
2182NTAPI
2183SeFilterToken(IN PACCESS_TOKEN ExistingToken,
2184 IN ULONG Flags,
2185 IN PTOKEN_GROUPS SidsToDisable OPTIONAL,
2186 IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL,
2187 IN PTOKEN_GROUPS RestrictedSids OPTIONAL,

--- 367 unchanged lines hidden (view full) ---

2555 }
2556
2557 /* Release the lock of the token */
2558 SepReleaseTokenLock(Token);
2559
2560 return Status;
2561}
2562
2192/*
2193 * @implemented
2563/**
2564 * @brief
2565 * Queries the session ID of an access token.
2566 *
2567 * @param[in] Token
2568 * A valid access token where the session ID has to be gathered.
2569 *
2570 * @param[out] pSessionId
2571 * The returned pointer to a session ID to the caller.
2572 *
2573 * @return
2574 * Returns STATUS_SUCCESS.
2194 */
2195NTSTATUS
2196NTAPI
2197SeQuerySessionIdToken(IN PACCESS_TOKEN Token,
2198 IN PULONG pSessionId)
2199{
2200 PAGED_CODE();
2201
2202 /* Lock the token */
2203 SepAcquireTokenLockShared(Token);
2204
2205 *pSessionId = ((PTOKEN)Token)->SessionId;
2206
2207 /* Unlock the token */
2208 SepReleaseTokenLock(Token);
2209
2210 return STATUS_SUCCESS;
2211}
2212
2575 */
2576NTSTATUS
2577NTAPI
2578SeQuerySessionIdToken(IN PACCESS_TOKEN Token,
2579 IN PULONG pSessionId)
2580{
2581 PAGED_CODE();
2582
2583 /* Lock the token */
2584 SepAcquireTokenLockShared(Token);
2585
2586 *pSessionId = ((PTOKEN)Token)->SessionId;
2587
2588 /* Unlock the token */
2589 SepReleaseTokenLock(Token);
2590
2591 return STATUS_SUCCESS;
2592}
2593
2213/*
2214 * @implemented
2594/**
2595 * @brief
2596 * Queries the authentication ID of an access token.
2597 *
2598 * @param[in] Token
2599 * A valid access token where the authentication ID has to be gathered.
2600 *
2601 * @param[out] pSessionId
2602 * The returned pointer to an authentication ID to the caller.
2603 *
2604 * @return
2605 * Returns STATUS_SUCCESS.
2215 */
2216NTSTATUS
2217NTAPI
2218SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token,
2219 OUT PLUID LogonId)
2220{
2221 PAGED_CODE();
2222
2223 *LogonId = ((PTOKEN)Token)->AuthenticationId;
2224
2225 return STATUS_SUCCESS;
2226}
2227
2606 */
2607NTSTATUS
2608NTAPI
2609SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token,
2610 OUT PLUID LogonId)
2611{
2612 PAGED_CODE();
2613
2614 *LogonId = ((PTOKEN)Token)->AuthenticationId;
2615
2616 return STATUS_SUCCESS;
2617}
2618
2228
2229/*
2230 * @implemented
2619/**
2620 * @brief
2621 * Gathers the security impersonation level of an access token.
2622 *
2623 * @param[in] Token
2624 * A valid access token where the impersonation level has to be gathered.
2625 *
2626 * @return
2627 * Returns the security impersonation level from a valid token.
2231 */
2232SECURITY_IMPERSONATION_LEVEL
2233NTAPI
2234SeTokenImpersonationLevel(IN PACCESS_TOKEN Token)
2235{
2236 PAGED_CODE();
2237
2238 return ((PTOKEN)Token)->ImpersonationLevel;
2239}
2240
2628 */
2629SECURITY_IMPERSONATION_LEVEL
2630NTAPI
2631SeTokenImpersonationLevel(IN PACCESS_TOKEN Token)
2632{
2633 PAGED_CODE();
2634
2635 return ((PTOKEN)Token)->ImpersonationLevel;
2636}
2637
2241
2242/*
2243 * @implemented
2638/**
2639 * @brief
2640 * Gathers the token type of an access token. A token ca be either
2641 * a primary token or impersonation token.
2642 *
2643 * @param[in] Token
2644 * A valid access token where the token type has to be gathered.
2645 *
2646 * @return
2647 * Returns the token type from a valid token.
2244 */
2245TOKEN_TYPE NTAPI
2246SeTokenType(IN PACCESS_TOKEN Token)
2247{
2248 PAGED_CODE();
2249
2250 return ((PTOKEN)Token)->TokenType;
2251}
2252
2648 */
2649TOKEN_TYPE NTAPI
2650SeTokenType(IN PACCESS_TOKEN Token)
2651{
2652 PAGED_CODE();
2653
2654 return ((PTOKEN)Token)->TokenType;
2655}
2656
2253
2254/*
2255 * @implemented
2657/**
2658 * @brief
2659 * Determines if a token is either an admin token or not. Such
2660 * condition is checked based upon TOKEN_HAS_ADMIN_GROUP flag,
2661 * which means if the respective access token belongs to an
2662 * administrator group or not.
2663 *
2664 * @param[in] Token
2665 * A valid access token to determine if such token is admin or not.
2666 *
2667 * @return
2668 * Returns TRUE if the token is an admin one, FALSE otherwise.
2256 */
2257BOOLEAN
2258NTAPI
2259SeTokenIsAdmin(IN PACCESS_TOKEN Token)
2260{
2261 PAGED_CODE();
2262
2263 // NOTE: Win7+ instead really checks the list of groups in the token
2264 // (since TOKEN_HAS_ADMIN_GROUP == TOKEN_WRITE_RESTRICTED ...)
2265 return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_ADMIN_GROUP) != 0;
2266}
2267
2669 */
2670BOOLEAN
2671NTAPI
2672SeTokenIsAdmin(IN PACCESS_TOKEN Token)
2673{
2674 PAGED_CODE();
2675
2676 // NOTE: Win7+ instead really checks the list of groups in the token
2677 // (since TOKEN_HAS_ADMIN_GROUP == TOKEN_WRITE_RESTRICTED ...)
2678 return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_ADMIN_GROUP) != 0;
2679}
2680
2268/*
2269 * @implemented
2681/**
2682 * @brief
2683 * Determines if a token is restricted or not, based upon the token
2684 * flags.
2685 *
2686 * @param[in] Token
2687 * A valid access token to determine if such token is restricted.
2688 *
2689 * @return
2690 * Returns TRUE if the token is restricted, FALSE otherwise.
2270 */
2271BOOLEAN
2272NTAPI
2273SeTokenIsRestricted(IN PACCESS_TOKEN Token)
2274{
2275 PAGED_CODE();
2276
2277 return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0;
2278}
2279
2691 */
2692BOOLEAN
2693NTAPI
2694SeTokenIsRestricted(IN PACCESS_TOKEN Token)
2695{
2696 PAGED_CODE();
2697
2698 return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0;
2699}
2700
2280/*
2281 * @implemented
2282 * @note First introduced in NT 5.1 SP2 x86 (5.1.2600.2622), absent in NT 5.2,
2283 * then finally re-introduced in Vista+.
2701/**
2702 * @brief
2703 * Determines if a token is write restricted, that is, nobody can write anything
2704 * to it.
2705 *
2706 * @param[in] Token
2707 * A valid access token to determine if such token is write restricted.
2708 *
2709 * @return
2710 * Returns TRUE if the token is write restricted, FALSE otherwise.
2711 *
2712 * @remarks
2713 * First introduced in NT 5.1 SP2 x86 (5.1.2600.2622), absent in NT 5.2,
2714 * then finally re-introduced in Vista+.
2284 */
2285BOOLEAN
2286NTAPI
2287SeTokenIsWriteRestricted(IN PACCESS_TOKEN Token)
2288{
2289 PAGED_CODE();
2290
2291 // NOTE: NT 5.1 SP2 x86 checks the SE_BACKUP_PRIVILEGES_CHECKED flag

--- 96 unchanged lines hidden (view full) ---

2388 SepReleaseTokenLock(ProcessToken);
2389 SepReleaseTokenLock(TokenToImpersonate);
2390
2391 return CanImpersonate;
2392}
2393
2394/* SYSTEM CALLS ***************************************************************/
2395
2715 */
2716BOOLEAN
2717NTAPI
2718SeTokenIsWriteRestricted(IN PACCESS_TOKEN Token)
2719{
2720 PAGED_CODE();
2721
2722 // NOTE: NT 5.1 SP2 x86 checks the SE_BACKUP_PRIVILEGES_CHECKED flag

--- 96 unchanged lines hidden (view full) ---

2819 SepReleaseTokenLock(ProcessToken);
2820 SepReleaseTokenLock(TokenToImpersonate);
2821
2822 return CanImpersonate;
2823}
2824
2825/* SYSTEM CALLS ***************************************************************/
2826
2396/*
2397 * @implemented
2827/**
2828 * @brief
2829 * Queries a specific type of information in regard of an access token based upon
2830 * the information class. The calling thread must have specific access rights in order
2831 * to obtain specific information about the token.
2832 *
2833 * @param[in] TokenHandle
2834 * A handle of a token where information is to be gathered.
2835 *
2836 * @param[in] TokenInformationClass
2837 * Token information class.
2838 *
2839 * @param[out] TokenInformation
2840 * A returned output buffer with token information, which information is arbitrarily upon
2841 * the information class chosen.
2842 *
2843 * @param[in] TokenInformationLength
2844 * Length of the token information buffer, in bytes.
2845 *
2846 * @param[out] ReturnLength
2847 * If specified in the call, the function returns the total length size of the token
2848 * information buffer..
2849 *
2850 * @return
2851 * Returns STATUS_SUCCESS if information querying has completed successfully.
2852 * STATUS_BUFFER_TOO_SMALL is returned if the information length that represents
2853 * the token information buffer is not greater than the required length.
2854 * STATUS_INVALID_HANDLE is returned if the token handle is not a valid one.
2855 * STATUS_INVALID_INFO_CLASS is returned if the information class is not a valid
2856 * one (that is, the class doesn't belong to TOKEN_INFORMATION_CLASS). A failure
2857 * NTSTATUS code is returned otherwise.
2398 */
2399_Must_inspect_result_
2400__kernel_entry
2401NTSTATUS
2402NTAPI
2403NtQueryInformationToken(
2404 _In_ HANDLE TokenHandle,
2405 _In_ TOKEN_INFORMATION_CLASS TokenInformationClass,

--- 555 unchanged lines hidden (view full) ---

2961 /* Unlock and dereference the token */
2962 SepReleaseTokenLock(Token);
2963 ObDereferenceObject(Token);
2964 }
2965
2966 return Status;
2967}
2968
2858 */
2859_Must_inspect_result_
2860__kernel_entry
2861NTSTATUS
2862NTAPI
2863NtQueryInformationToken(
2864 _In_ HANDLE TokenHandle,
2865 _In_ TOKEN_INFORMATION_CLASS TokenInformationClass,

--- 555 unchanged lines hidden (view full) ---

3421 /* Unlock and dereference the token */
3422 SepReleaseTokenLock(Token);
3423 ObDereferenceObject(Token);
3424 }
3425
3426 return Status;
3427}
3428
2969
2970/*
2971 * NtSetTokenInformation: Partly implemented.
2972 * Unimplemented:
2973 * TokenOrigin, TokenDefaultDacl
3429/**
3430 * @unimplemented
3431 * @brief
3432 * Sets (modifies) some specific information in regard of an access token. The
3433 * calling thread must have specific access rights in order to modify token's
3434 * information data.
3435 *
3436 * @param[in] TokenHandle
3437 * A handle of a token where information is to be modified.
3438 *
3439 * @param[in] TokenInformationClass
3440 * Token information class.
3441 *
3442 * @param[in] TokenInformation
3443 * An arbitrary pointer to a buffer with token information to set. Such
3444 * arbitrary buffer depends on the information class chosen that the caller
3445 * wants to modify such information data of a token.
3446 *
3447 * @param[in] TokenInformationLength
3448 * Length of the token information buffer, in bytes.
3449 *
3450 * @return
3451 * Returns STATUS_SUCCESS if information setting has completed successfully.
3452 * STATUS_INFO_LENGTH_MISMATCH is returned if the information length of the
3453 * buffer is less than the required length. STATUS_INSUFFICIENT_RESOURCES is
3454 * returned if memory pool allocation has failed. STATUS_PRIVILEGE_NOT_HELD
3455 * is returned if the calling thread hasn't the required privileges to perform
3456 * the operation in question. A failure NTSTATUS code is returned otherwise.
3457 *
3458 * @remarks
3459 * The function is partly implemented, mainly TokenOrigin and TokenDefaultDacl.
2974 */
2975_Must_inspect_result_
2976__kernel_entry
2977NTSTATUS
2978NTAPI
2979NtSetInformationToken(
2980 _In_ HANDLE TokenHandle,
2981 _In_ TOKEN_INFORMATION_CLASS TokenInformationClass,

--- 507 unchanged lines hidden (view full) ---

3489 if (!NT_SUCCESS(Status))
3490 {
3491 DPRINT1("NtSetInformationToken failed with Status 0x%lx\n", Status);
3492 }
3493
3494 return Status;
3495}
3496
3460 */
3461_Must_inspect_result_
3462__kernel_entry
3463NTSTATUS
3464NTAPI
3465NtSetInformationToken(
3466 _In_ HANDLE TokenHandle,
3467 _In_ TOKEN_INFORMATION_CLASS TokenInformationClass,

--- 507 unchanged lines hidden (view full) ---

3975 if (!NT_SUCCESS(Status))
3976 {
3977 DPRINT1("NtSetInformationToken failed with Status 0x%lx\n", Status);
3978 }
3979
3980 return Status;
3981}
3982
3497
3498/*
3499 * @implemented
3983/**
3984 * @brief
3985 * Duplicates a token.
3986 *
3987 * @param[in] ExistingTokenHandle
3988 * An existing token to duplicate.
3989 *
3990 * @param[in] DesiredAccess
3991 * The desired access rights for the new duplicated token.
3992 *
3993 * @param[in] ObjectAttributes
3994 * Object attributes for the new duplicated token.
3995 *
3996 * @param[in] EffectiveOnly
3997 * If set to TRUE, the function removes all the disabled privileges and groups
3998 * of the token to duplicate.
3999 *
4000 * @param[in] TokenType
4001 * Type of token to assign to the duplicated token.
4002 *
4003 * @param[out] NewTokenHandle
4004 * The returned duplicated token handle.
3500 *
4005 *
3501 * NOTE: Some sources claim 4th param is ImpersonationLevel, but on W2K
4006 * @return
4007 * STATUS_SUCCESS is returned if token duplication has completed successfully.
4008 * STATUS_BAD_IMPERSONATION_LEVEL is returned if the caller erroneously wants
4009 * to raise the impersonation level even though the conditions do not permit
4010 * it. A failure NTSTATUS code is returned otherwise.
4011 *
4012 * @remarks
4013 * Some sources claim 4th param is ImpersonationLevel, but on W2K
3502 * this is certainly NOT true, although I can't say for sure that EffectiveOnly
3503 * is correct either. -Gunnar
3504 * This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI
3505 * NOTE for readers: http://hex.pp.ua/nt/NtDuplicateToken.php is therefore
3506 * wrong in that regard, while MSDN documentation is correct.
3507 */
3508_Must_inspect_result_
3509__kernel_entry

--- 135 unchanged lines hidden (view full) ---

3645 /* Free the captured structure */
3646 SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
3647 PreviousMode,
3648 FALSE);
3649
3650 return Status;
3651}
3652
4014 * this is certainly NOT true, although I can't say for sure that EffectiveOnly
4015 * is correct either. -Gunnar
4016 * This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI
4017 * NOTE for readers: http://hex.pp.ua/nt/NtDuplicateToken.php is therefore
4018 * wrong in that regard, while MSDN documentation is correct.
4019 */
4020_Must_inspect_result_
4021__kernel_entry

--- 135 unchanged lines hidden (view full) ---

4157 /* Free the captured structure */
4158 SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
4159 PreviousMode,
4160 FALSE);
4161
4162 return Status;
4163}
4164
4165/**
4166 * @brief
4167 * Changes the groups list of SIDs of a token.
4168 *
4169 * @param[in] TokenHandle
4170 * Token handle where the list of groups SIDs are to be adjusted.
4171 *
4172 * @param[in] ResetToDefault
4173 * If set to TRUE, the function resets the list of groups SIDs to default.
4174 * All the rest of parameters are ignored.
4175 *
4176 * @param[in] NewState
4177 * A new list of groups SIDs that the function will use it accordingly to
4178 * modify the current list of groups SIDs of a token.
4179 *
4180 * @param[in] BufferLength
4181 * The length size of the buffer that is pointed by the NewState parameter
4182 * argument, in bytes.
4183 *
4184 * @param[out] PreviousState
4185 * If specified, the function will return to the caller the old list of groups
4186 * SIDs.
4187 *
4188 * @param[out] ReturnLength
4189 * If specified, the function will return the total size length of the old list
4190 * of groups SIDs, in bytes.
4191 *
4192 * @return
4193 * To be added...
4194 */
3653NTSTATUS NTAPI
3654NtAdjustGroupsToken(IN HANDLE TokenHandle,
3655 IN BOOLEAN ResetToDefault,
3656 IN PTOKEN_GROUPS NewState,
3657 IN ULONG BufferLength,
3658 OUT PTOKEN_GROUPS PreviousState OPTIONAL,
3659 OUT PULONG ReturnLength)
3660{
3661 UNIMPLEMENTED;
3662 return STATUS_NOT_IMPLEMENTED;
3663}
3664
4195NTSTATUS NTAPI
4196NtAdjustGroupsToken(IN HANDLE TokenHandle,
4197 IN BOOLEAN ResetToDefault,
4198 IN PTOKEN_GROUPS NewState,
4199 IN ULONG BufferLength,
4200 OUT PTOKEN_GROUPS PreviousState OPTIONAL,
4201 OUT PULONG ReturnLength)
4202{
4203 UNIMPLEMENTED;
4204 return STATUS_NOT_IMPLEMENTED;
4205}
4206
3665
4207/**
4208 * @brief
4209 * Removes a certain amount of privileges of a token based upon the request
4210 * by the caller.
4211 *
4212 * @param[in,out] Token
4213 * Token handle where the privileges are about to be modified.
4214 *
4215 * @param[in] DisableAllPrivileges
4216 * If set to TRUE, the function disables all the privileges.
4217 *
4218 * @param[in] NewState
4219 * A new list of privileges that the function will use it accordingly to
4220 * either disable or enable the said privileges and change them.
4221 *
4222 * @param[in] NewStateCount
4223 * The new total number count of privileges.
4224 *
4225 * @param[out] PreviousState
4226 * If specified, the function will return the previous state list of privileges.
4227 *
4228 * @param[in] ApplyChanges
4229 * If set to TRUE, the function will immediatelly apply the changes onto the
4230 * token's privileges.
4231 *
4232 * @param[out] ChangedPrivileges
4233 * The returned count number of changed privileges.
4234 *
4235 * @param[out] ChangesMade
4236 * If TRUE, the function has made changes to the token's privileges. FALSE
4237 * otherwise.
4238 *
4239 * @return
4240 * Returns STATUS_SUCCESS if the function has successfully changed the list
4241 * of privileges. STATUS_NOT_ALL_ASSIGNED is returned if not every privilege
4242 * has been changed.
4243 */
3666static
3667NTSTATUS
3668SepAdjustPrivileges(
3669 _Inout_ PTOKEN Token,
3670 _In_ BOOLEAN DisableAllPrivileges,
3671 _In_opt_ PLUID_AND_ATTRIBUTES NewState,
3672 _In_ ULONG NewStateCount,
3673 _Out_opt_ PTOKEN_PRIVILEGES PreviousState,

--- 100 unchanged lines hidden (view full) ---

3774 if (!DisableAllPrivileges && (PrivilegeCount < NewStateCount))
3775 {
3776 return STATUS_NOT_ALL_ASSIGNED;
3777 }
3778
3779 return STATUS_SUCCESS;
3780}
3781
4244static
4245NTSTATUS
4246SepAdjustPrivileges(
4247 _Inout_ PTOKEN Token,
4248 _In_ BOOLEAN DisableAllPrivileges,
4249 _In_opt_ PLUID_AND_ATTRIBUTES NewState,
4250 _In_ ULONG NewStateCount,
4251 _Out_opt_ PTOKEN_PRIVILEGES PreviousState,

--- 100 unchanged lines hidden (view full) ---

4352 if (!DisableAllPrivileges && (PrivilegeCount < NewStateCount))
4353 {
4354 return STATUS_NOT_ALL_ASSIGNED;
4355 }
4356
4357 return STATUS_SUCCESS;
4358}
4359
3782
3783/*
3784 * @implemented
4360/**
4361 * @brief
4362 * Removes a certain amount of privileges of a token based upon the request
4363 * by the caller.
4364 *
4365 * @param[in,out] Token
4366 * Token handle where the privileges are about to be modified.
4367 *
4368 * @param[in] DisableAllPrivileges
4369 * If set to TRUE, the function disables all the privileges.
4370 *
4371 * @param[in] NewState
4372 * A new list of privileges that the function will use it accordingly to
4373 * either disable or enable the said privileges and change them.
4374 *
4375 * @param[in] NewStateCount
4376 * The new total number count of privileges.
4377 *
4378 * @param[out] PreviousState
4379 * If specified, the function will return the previous state list of privileges.
4380 *
4381 * @param[in] ApplyChanges
4382 * If set to TRUE, the function will immediatelly apply the changes onto the
4383 * token's privileges.
4384 *
4385 * @param[out] ChangedPrivileges
4386 * The returned count number of changed privileges.
4387 *
4388 * @param[out] ChangesMade
4389 * If TRUE, the function has made changes to the token's privileges. FALSE
4390 * otherwise.
4391 *
4392 * @return
4393 * Returns STATUS_SUCCESS if the function has successfully changed the list
4394 * of privileges. STATUS_NOT_ALL_ASSIGNED is returned if not every privilege
4395 * has been changed.
3785 */
3786_Must_inspect_result_
3787__kernel_entry
3788NTSTATUS
3789NTAPI
3790NtAdjustPrivilegesToken(
3791 _In_ HANDLE TokenHandle,
3792 _In_ BOOLEAN DisableAllPrivileges,

--- 187 unchanged lines hidden (view full) ---

3980 PreviousMode,
3981 TRUE);
3982 }
3983
3984 DPRINT ("NtAdjustPrivilegesToken() done\n");
3985 return Status;
3986}
3987
4396 */
4397_Must_inspect_result_
4398__kernel_entry
4399NTSTATUS
4400NTAPI
4401NtAdjustPrivilegesToken(
4402 _In_ HANDLE TokenHandle,
4403 _In_ BOOLEAN DisableAllPrivileges,

--- 187 unchanged lines hidden (view full) ---

4591 PreviousMode,
4592 TRUE);
4593 }
4594
4595 DPRINT ("NtAdjustPrivilegesToken() done\n");
4596 return Status;
4597}
4598
4599/**
4600 * @brief
4601 * Creates an access token.
4602 *
4603 * @param[out] TokenHandle
4604 * The returned created token handle to the caller.
4605 *
4606 * @param[in] DesiredAccess
4607 * The desired access rights for the token that we're creating.
4608 *
4609 * @param[in] ObjectAttributes
4610 * The object attributes for the token object that we're creating.
4611 *
4612 * @param[in] TokenType
4613 * The type of token to assign for the newly created token.
4614 *
4615 * @param[in] AuthenticationId
4616 * Authentication ID that represents the token's identity.
4617 *
4618 * @param[in] ExpirationTime
4619 * Expiration time for the token. If set to -1, the token never expires.
4620 *
4621 * @param[in] TokenUser
4622 * The main user entity for the token to assign.
4623 *
4624 * @param[in] TokenGroups
4625 * Group list of SIDs for the token to assign.
4626 *
4627 * @param[in] TokenPrivileges
4628 * Privileges for the token.
4629 *
4630 * @param[in] TokenOwner
4631 * The main user that owns the newly created token.
4632 *
4633 * @param[in] TokenPrimaryGroup
4634 * The primary group that represents as the main group of the token.
4635 *
4636 * @param[in] TokenDefaultDacl
4637 * Discretionary access control list for the token. This limits on how
4638 * the token can be used, accessed and used by whom.
4639 *
4640 * @param[in] TokenSource
4641 * The source origin of the token who creates it.
4642 *
4643 * @return
4644 * Returns STATUS_SUCCESS if the function has successfully created the token.
4645 * A failure NTSTATUS code is returned otherwise.
4646 */
3988__kernel_entry
3989NTSTATUS
3990NTAPI
3991NtCreateToken(
3992 _Out_ PHANDLE TokenHandle,
3993 _In_ ACCESS_MASK DesiredAccess,
3994 _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
3995 _In_ TOKEN_TYPE TokenType,

--- 257 unchanged lines hidden (view full) ---

4253 SeReleaseLuidAndAttributesArray(CapturedPrivileges, PreviousMode, FALSE);
4254 SepReleaseSid(CapturedOwnerSid, PreviousMode, FALSE);
4255 SepReleaseSid(CapturedPrimaryGroupSid, PreviousMode, FALSE);
4256 SepReleaseAcl(CapturedDefaultDacl, PreviousMode, FALSE);
4257
4258 return Status;
4259}
4260
4647__kernel_entry
4648NTSTATUS
4649NTAPI
4650NtCreateToken(
4651 _Out_ PHANDLE TokenHandle,
4652 _In_ ACCESS_MASK DesiredAccess,
4653 _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
4654 _In_ TOKEN_TYPE TokenType,

--- 257 unchanged lines hidden (view full) ---

4912 SeReleaseLuidAndAttributesArray(CapturedPrivileges, PreviousMode, FALSE);
4913 SepReleaseSid(CapturedOwnerSid, PreviousMode, FALSE);
4914 SepReleaseSid(CapturedPrimaryGroupSid, PreviousMode, FALSE);
4915 SepReleaseAcl(CapturedDefaultDacl, PreviousMode, FALSE);
4916
4917 return Status;
4918}
4919
4261/*
4262 * @implemented
4920/**
4921 * @brief
4922 * Opens a token that is tied to a thread handle.
4923 *
4924 * @param[out] ThreadHandle
4925 * Thread handle where the token is about to be opened.
4926 *
4927 * @param[in] DesiredAccess
4928 * The request access right for the token.
4929 *
4930 * @param[in] OpenAsSelf
4931 * If set to TRUE, the access check will be made with the security context
4932 * of the process of the calling thread (opening as self). Otherwise the access
4933 * check will be made with the security context of the calling thread instead.
4934 *
4935 * @param[in] HandleAttributes
4936 * Handle attributes for the opened thread token handle.
4937 *
4938 * @param[out] TokenHandle
4939 * The opened token handle returned to the caller for use.
4940 *
4941 * @return
4942 * Returns STATUS_SUCCESS if the function has successfully opened the thread
4943 * token. STATUS_CANT_OPEN_ANONYMOUS is returned if a token has SecurityAnonymous
4944 * as impersonation level and we cannot open it. A failure NTSTATUS code is returned
4945 * otherwise.
4263 */
4264NTSTATUS
4265NTAPI
4266NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
4267 IN ACCESS_MASK DesiredAccess,
4268 IN BOOLEAN OpenAsSelf,
4269 IN ULONG HandleAttributes,
4270 OUT PHANDLE TokenHandle)

--- 165 unchanged lines hidden (view full) ---

4436 Status = _SEH2_GetExceptionCode();
4437 }
4438 _SEH2_END;
4439 }
4440
4441 return Status;
4442}
4443
4946 */
4947NTSTATUS
4948NTAPI
4949NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
4950 IN ACCESS_MASK DesiredAccess,
4951 IN BOOLEAN OpenAsSelf,
4952 IN ULONG HandleAttributes,
4953 OUT PHANDLE TokenHandle)

--- 165 unchanged lines hidden (view full) ---

5119 Status = _SEH2_GetExceptionCode();
5120 }
5121 _SEH2_END;
5122 }
5123
5124 return Status;
5125}
5126
4444/*
4445 * @implemented
5127/**
5128 * @brief
5129 * Opens a token that is tied to a thread handle.
5130 *
5131 * @param[out] ThreadHandle
5132 * Thread handle where the token is about to be opened.
5133 *
5134 * @param[in] DesiredAccess
5135 * The request access right for the token.
5136 *
5137 * @param[in] OpenAsSelf
5138 * If set to TRUE, the access check will be made with the security context
5139 * of the process of the calling thread (opening as self). Otherwise the access
5140 * check will be made with the security context of the calling thread instead.
5141 *
5142 * @param[out] TokenHandle
5143 * The opened token handle returned to the caller for use.
5144 *
5145 * @return
5146 * See NtOpenThreadTokenEx.
4446 */
4447NTSTATUS NTAPI
4448NtOpenThreadToken(IN HANDLE ThreadHandle,
4449 IN ACCESS_MASK DesiredAccess,
4450 IN BOOLEAN OpenAsSelf,
4451 OUT PHANDLE TokenHandle)
4452{
4453 return NtOpenThreadTokenEx(ThreadHandle, DesiredAccess, OpenAsSelf, 0,

--- 97 unchanged lines hidden (view full) ---

4551 Status = _SEH2_GetExceptionCode();
4552 }
4553 _SEH2_END;
4554 }
4555
4556 return Status;
4557}
4558
5147 */
5148NTSTATUS NTAPI
5149NtOpenThreadToken(IN HANDLE ThreadHandle,
5150 IN ACCESS_MASK DesiredAccess,
5151 IN BOOLEAN OpenAsSelf,
5152 OUT PHANDLE TokenHandle)
5153{
5154 return NtOpenThreadTokenEx(ThreadHandle, DesiredAccess, OpenAsSelf, 0,

--- 97 unchanged lines hidden (view full) ---

5252 Status = _SEH2_GetExceptionCode();
5253 }
5254 _SEH2_END;
5255 }
5256
5257 return Status;
5258}
5259
5260/**
5261 * @unimplemented
5262 * @brief
5263 * Opens a token that is tied to a thread handle.
5264 *
5265 * @param[in] ExistingTokenHandle
5266 * An existing token for filtering.
5267 *
5268 * @param[in] Flags
5269 * Privilege flag options. This parameter argument influences how the token
5270 * is filtered. Such parameter can be 0.
5271 *
5272 * @param[in] SidsToDisable
5273 * Array of SIDs to disable.
5274 *
5275 * @param[in] PrivilegesToDelete
5276 * Array of privileges to delete.
5277 *
5278 * @param[in] RestrictedSids
5279 * An array of restricted SIDs for the new filtered token.
5280 *
5281 * @param[out] NewTokenHandle
5282 * The newly filtered token, returned to the caller.
5283 *
5284 * @return
5285 * To be added...
5286 */
4559NTSTATUS
4560NTAPI
4561NtFilterToken(IN HANDLE ExistingTokenHandle,
4562 IN ULONG Flags,
4563 IN PTOKEN_GROUPS SidsToDisable OPTIONAL,
4564 IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL,
4565 IN PTOKEN_GROUPS RestrictedSids OPTIONAL,
4566 OUT PHANDLE NewTokenHandle)

--- 66 unchanged lines hidden ---
5287NTSTATUS
5288NTAPI
5289NtFilterToken(IN HANDLE ExistingTokenHandle,
5290 IN ULONG Flags,
5291 IN PTOKEN_GROUPS SidsToDisable OPTIONAL,
5292 IN PTOKEN_PRIVILEGES PrivilegesToDelete OPTIONAL,
5293 IN PTOKEN_GROUPS RestrictedSids OPTIONAL,
5294 OUT PHANDLE NewTokenHandle)

--- 66 unchanged lines hidden ---