ReactOS  0.4.15-dev-4934-gfd1e799
tokencls.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <ntlsa.h>
Include dependency graph for tokencls.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI SeQueryInformationToken (_In_ PACCESS_TOKEN AccessToken, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Outptr_result_buffer_(_Inexpressible_(token-dependent)) PVOID *TokenInformation)
 Queries information details about the given token to the call. The difference between NtQueryInformationToken and this routine is that the system call has user mode buffer data probing and additional protection checks whereas this routine doesn't have any of these. The routine is used exclusively in kernel mode. More...
 
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtQueryInformationToken (_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Out_writes_bytes_to_opt_(TokenInformationLength, *ReturnLength) PVOID TokenInformation, _In_ ULONG TokenInformationLength, _Out_ PULONG ReturnLength)
 Queries a specific type of information in regard of an access token based upon the information class. The calling thread must have specific access rights in order to obtain specific information about the token. More...
 
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtSetInformationToken (_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _In_reads_bytes_(TokenInformationLength) PVOID TokenInformation, _In_ ULONG TokenInformationLength)
 Sets (modifies) some specific information in regard of an access token. The calling thread must have specific access rights in order to modify token's information data. More...
 

Variables

static const INFORMATION_CLASS_INFO SeTokenInformationClass []
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file tokencls.c.

Function Documentation

◆ NtQueryInformationToken()

_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtQueryInformationToken ( _In_ HANDLE  TokenHandle,
_In_ TOKEN_INFORMATION_CLASS  TokenInformationClass,
_Out_writes_bytes_to_opt_(TokenInformationLength, *ReturnLength) PVOID  TokenInformation,
_In_ ULONG  TokenInformationLength,
_Out_ PULONG  ReturnLength 
)

Queries a specific type of information in regard of an access token based upon the information class. The calling thread must have specific access rights in order to obtain specific information about the token.

Parameters
[in]TokenHandleA handle of a token where information is to be gathered.
[in]TokenInformationClassToken information class.
[out]TokenInformationA returned output buffer with token information, which information is arbitrarily upon the information class chosen.
[in]TokenInformationLengthLength of the token information buffer, in bytes.
[out]ReturnLengthA pointer to a variable provided by the caller that receives the actual length of the buffer pointed by TokenInformation, in bytes. If TokenInformation is NULL and TokenInformationLength is 0, this parameter receives the required length needed to store the buffer information in memory. This parameter must not be NULL!
Returns
Returns STATUS_SUCCESS if information querying has completed successfully. STATUS_BUFFER_TOO_SMALL is returned if the information length that represents the token information buffer is not greater than the required length. STATUS_INVALID_HANDLE is returned if the token handle is not a valid one. STATUS_INVALID_INFO_CLASS is returned if the information class is not a valid one (that is, the class doesn't belong to TOKEN_INFORMATION_CLASS). STATUS_ACCESS_VIOLATION is returned if ReturnLength is NULL. A failure NTSTATUS code is returned otherwise.

Definition at line 473 of file tokencls.c.

480 {
483  PTOKEN Token;
484  ULONG RequiredLength = 0;
485  union
486  {
487  PSID PSid;
488  ULONG Ulong;
489  } Unused;
490 
491  PAGED_CODE();
492 
494 
495  /* Check buffers and class validity */
500  TokenInformation,
502  ReturnLength,
503  NULL,
504  PreviousMode);
505  if (!NT_SUCCESS(Status))
506  {
507  DPRINT("NtQueryInformationToken() failed, Status: 0x%x\n", Status);
508  return Status;
509  }
510 
514  PreviousMode,
515  (PVOID*)&Token,
516  NULL);
517  if (NT_SUCCESS(Status))
518  {
519  /* Lock the token */
521 
522  switch (TokenInformationClass)
523  {
524  case TokenUser:
525  {
526  PTOKEN_USER tu = (PTOKEN_USER)TokenInformation;
527 
528  DPRINT("NtQueryInformationToken(TokenUser)\n");
529  RequiredLength = sizeof(TOKEN_USER) +
530  RtlLengthSid(Token->UserAndGroups[0].Sid);
531 
532  _SEH2_TRY
533  {
535  {
537  &Token->UserAndGroups[0],
538  RequiredLength - sizeof(TOKEN_USER),
539  &tu->User,
540  (PSID)(tu + 1),
541  &Unused.PSid,
542  &Unused.Ulong);
543  }
544  else
545  {
547  }
548 
550  }
552  {
554  }
555  _SEH2_END;
556 
557  break;
558  }
559 
560  case TokenGroups:
561  {
562  PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
563 
564  DPRINT("NtQueryInformationToken(TokenGroups)\n");
565  RequiredLength = sizeof(tg->GroupCount) +
566  RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
567 
568  _SEH2_TRY
569  {
571  {
572  ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
573  ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES));
574  PSID Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)tg + sizeof(tg->GroupCount) +
575  ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)));
576 
577  tg->GroupCount = Token->UserAndGroupCount - 1;
578  Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
579  &Token->UserAndGroups[1],
580  SidLen,
581  &tg->Groups[0],
582  Sid,
583  &Unused.PSid,
584  &Unused.Ulong);
585  }
586  else
587  {
589  }
590 
592  }
594  {
596  }
597  _SEH2_END;
598 
599  break;
600  }
601 
602  case TokenPrivileges:
603  {
604  PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)TokenInformation;
605 
606  DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
607  RequiredLength = sizeof(tp->PrivilegeCount) +
608  (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
609 
610  _SEH2_TRY
611  {
613  {
614  tp->PrivilegeCount = Token->PrivilegeCount;
615  RtlCopyLuidAndAttributesArray(Token->PrivilegeCount,
616  Token->Privileges,
617  &tp->Privileges[0]);
618  }
619  else
620  {
622  }
623 
625  }
627  {
629  }
630  _SEH2_END;
631 
632  break;
633  }
634 
635  case TokenOwner:
636  {
637  PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
638  ULONG SidLen;
639 
640  DPRINT("NtQueryInformationToken(TokenOwner)\n");
641  SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
642  RequiredLength = sizeof(TOKEN_OWNER) + SidLen;
643 
644  _SEH2_TRY
645  {
647  {
648  to->Owner = (PSID)(to + 1);
649  Status = RtlCopySid(SidLen,
650  to->Owner,
651  Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
652  }
653  else
654  {
656  }
657 
659  }
661  {
663  }
664  _SEH2_END;
665 
666  break;
667  }
668 
669  case TokenPrimaryGroup:
670  {
671  PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
672  ULONG SidLen;
673 
674  DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n");
675  SidLen = RtlLengthSid(Token->PrimaryGroup);
676  RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen;
677 
678  _SEH2_TRY
679  {
681  {
682  tpg->PrimaryGroup = (PSID)(tpg + 1);
683  Status = RtlCopySid(SidLen,
684  tpg->PrimaryGroup,
685  Token->PrimaryGroup);
686  }
687  else
688  {
690  }
691 
693  }
695  {
697  }
698  _SEH2_END;
699 
700  break;
701  }
702 
703  case TokenDefaultDacl:
704  {
705  PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
706 
707  DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
709 
710  if (Token->DefaultDacl != NULL)
711  RequiredLength += Token->DefaultDacl->AclSize;
712 
713  _SEH2_TRY
714  {
716  {
717  if (Token->DefaultDacl != NULL)
718  {
719  tdd->DefaultDacl = (PACL)(tdd + 1);
721  Token->DefaultDacl,
722  Token->DefaultDacl->AclSize);
723  }
724  else
725  {
726  tdd->DefaultDacl = NULL;
727  }
728  }
729  else
730  {
732  }
733 
735  }
737  {
739  }
740  _SEH2_END;
741 
742  break;
743  }
744 
745  case TokenSource:
746  {
747  PTOKEN_SOURCE ts = (PTOKEN_SOURCE)TokenInformation;
748 
749  DPRINT("NtQueryInformationToken(TokenSource)\n");
750  RequiredLength = sizeof(TOKEN_SOURCE);
751 
752  _SEH2_TRY
753  {
755  {
756  *ts = Token->TokenSource;
757  }
758  else
759  {
761  }
762 
764  }
766  {
768  }
769  _SEH2_END;
770 
771  break;
772  }
773 
774  case TokenType:
775  {
776  PTOKEN_TYPE tt = (PTOKEN_TYPE)TokenInformation;
777 
778  DPRINT("NtQueryInformationToken(TokenType)\n");
779  RequiredLength = sizeof(TOKEN_TYPE);
780 
781  _SEH2_TRY
782  {
784  {
785  *tt = Token->TokenType;
786  }
787  else
788  {
790  }
791 
793  }
795  {
797  }
798  _SEH2_END;
799 
800  break;
801  }
802 
804  {
806 
807  DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n");
808 
809  /* Fail if the token is not an impersonation token */
810  if (Token->TokenType != TokenImpersonation)
811  {
813  break;
814  }
815 
817 
818  _SEH2_TRY
819  {
821  {
822  *sil = Token->ImpersonationLevel;
823  }
824  else
825  {
827  }
828 
830  }
832  {
834  }
835  _SEH2_END;
836 
837  break;
838  }
839 
840  case TokenStatistics:
841  {
842  PTOKEN_STATISTICS ts = (PTOKEN_STATISTICS)TokenInformation;
843 
844  DPRINT("NtQueryInformationToken(TokenStatistics)\n");
846 
847  _SEH2_TRY
848  {
850  {
851  ts->TokenId = Token->TokenId;
852  ts->AuthenticationId = Token->AuthenticationId;
853  ts->ExpirationTime = Token->ExpirationTime;
854  ts->TokenType = Token->TokenType;
855  ts->ImpersonationLevel = Token->ImpersonationLevel;
856  ts->DynamicCharged = Token->DynamicCharged;
857  ts->DynamicAvailable = SepComputeAvailableDynamicSpace(Token->DynamicCharged, Token->PrimaryGroup, Token->DefaultDacl);
858  ts->GroupCount = Token->UserAndGroupCount - 1;
859  ts->PrivilegeCount = Token->PrivilegeCount;
860  ts->ModifiedId = Token->ModifiedId;
861  }
862  else
863  {
865  }
866 
868  }
870  {
872  }
873  _SEH2_END;
874 
875  break;
876  }
877 
878  case TokenOrigin:
879  {
880  PTOKEN_ORIGIN to = (PTOKEN_ORIGIN)TokenInformation;
881 
882  DPRINT("NtQueryInformationToken(TokenOrigin)\n");
883  RequiredLength = sizeof(TOKEN_ORIGIN);
884 
885  _SEH2_TRY
886  {
888  {
889  to->OriginatingLogonSession = Token->AuthenticationId;
890  }
891  else
892  {
894  }
895 
897  }
899  {
901  }
902  _SEH2_END;
903 
904  break;
905  }
906 
908  {
909  PSID Sid, RestrictedSid;
910  ULONG SidLen, RestrictedSidLen;
911  ULONG UserGroupLength, RestrictedSidLength, PrivilegeLength;
912  PTOKEN_GROUPS_AND_PRIVILEGES GroupsAndPrivs = (PTOKEN_GROUPS_AND_PRIVILEGES)TokenInformation;
913 
914  DPRINT("NtQueryInformationToken(TokenGroupsAndPrivileges)\n");
915  UserGroupLength = RtlLengthSidAndAttributes(Token->UserAndGroupCount, Token->UserAndGroups);
916  RestrictedSidLength = RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids);
917  PrivilegeLength = Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
918 
920  UserGroupLength + RestrictedSidLength + PrivilegeLength;
921 
922  _SEH2_TRY
923  {
925  {
926  GroupsAndPrivs->SidCount = Token->UserAndGroupCount;
927  GroupsAndPrivs->SidLength = UserGroupLength;
928  GroupsAndPrivs->Sids = (PSID_AND_ATTRIBUTES)(GroupsAndPrivs + 1);
929 
930  Sid = (PSID)((ULONG_PTR)GroupsAndPrivs->Sids + (Token->UserAndGroupCount * sizeof(SID_AND_ATTRIBUTES)));
931  SidLen = UserGroupLength - (Token->UserAndGroupCount * sizeof(SID_AND_ATTRIBUTES));
932  Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount,
933  Token->UserAndGroups,
934  SidLen,
935  GroupsAndPrivs->Sids,
936  Sid,
937  &Unused.PSid,
938  &Unused.Ulong);
940 
941  GroupsAndPrivs->RestrictedSidCount = Token->RestrictedSidCount;
942  GroupsAndPrivs->RestrictedSidLength = RestrictedSidLength;
943  GroupsAndPrivs->RestrictedSids = NULL;
945  {
946  GroupsAndPrivs->RestrictedSids = (PSID_AND_ATTRIBUTES)((ULONG_PTR)GroupsAndPrivs->Sids + UserGroupLength);
947 
948  RestrictedSid = (PSID)((ULONG_PTR)GroupsAndPrivs->RestrictedSids + (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)));
949  RestrictedSidLen = RestrictedSidLength - (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES));
950  Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount,
951  Token->RestrictedSids,
952  RestrictedSidLen,
953  GroupsAndPrivs->RestrictedSids,
954  RestrictedSid,
955  &Unused.PSid,
956  &Unused.Ulong);
958  }
959 
960  GroupsAndPrivs->PrivilegeCount = Token->PrivilegeCount;
961  GroupsAndPrivs->PrivilegeLength = PrivilegeLength;
962  GroupsAndPrivs->Privileges = (PLUID_AND_ATTRIBUTES)((ULONG_PTR)(GroupsAndPrivs + 1) +
963  UserGroupLength + RestrictedSidLength);
964  RtlCopyLuidAndAttributesArray(Token->PrivilegeCount,
965  Token->Privileges,
966  GroupsAndPrivs->Privileges);
967 
968  GroupsAndPrivs->AuthenticationId = Token->AuthenticationId;
969  }
970  else
971  {
973  }
974 
976  }
978  {
980  }
981  _SEH2_END;
982 
983  break;
984  }
985 
986  case TokenRestrictedSids:
987  {
988  PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
989 
990  DPRINT("NtQueryInformationToken(TokenRestrictedSids)\n");
991  RequiredLength = sizeof(tg->GroupCount) +
992  RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids);
993 
994  _SEH2_TRY
995  {
997  {
998  ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
999  (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES));
1000  PSID Sid = (PSID)((ULONG_PTR)tg + sizeof(tg->GroupCount) +
1001  (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)));
1002 
1003  tg->GroupCount = Token->RestrictedSidCount;
1004  Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount,
1005  Token->RestrictedSids,
1006  SidLen,
1007  &tg->Groups[0],
1008  Sid,
1009  &Unused.PSid,
1010  &Unused.Ulong);
1011  }
1012  else
1013  {
1015  }
1016 
1018  }
1020  {
1022  }
1023  _SEH2_END;
1024 
1025  break;
1026  }
1027 
1028  case TokenSandBoxInert:
1029  {
1030  ULONG IsTokenSandBoxInert;
1031 
1032  DPRINT("NtQueryInformationToken(TokenSandBoxInert)\n");
1033 
1034  IsTokenSandBoxInert = SeTokenIsInert(Token);
1035  _SEH2_TRY
1036  {
1037  /* Buffer size was already verified, no need to check here again */
1038  *(PULONG)TokenInformation = IsTokenSandBoxInert;
1039  *ReturnLength = sizeof(ULONG);
1040  }
1042  {
1044  }
1045  _SEH2_END;
1046 
1047  break;
1048  }
1049 
1050  case TokenSessionId:
1051  {
1052  ULONG SessionId = 0;
1053 
1054  DPRINT("NtQueryInformationToken(TokenSessionId)\n");
1055 
1057  if (NT_SUCCESS(Status))
1058  {
1059  _SEH2_TRY
1060  {
1061  /* Buffer size was already verified, no need to check here again */
1062  *(PULONG)TokenInformation = SessionId;
1064  }
1066  {
1068  }
1069  _SEH2_END;
1070  }
1071 
1072  break;
1073  }
1074 
1075  default:
1076  DPRINT1("NtQueryInformationToken(%d) invalid information class\n", TokenInformationClass);
1078  break;
1079  }
1080 
1081  /* Unlock and dereference the token */
1084  }
1085 
1086  return Status;
1087 }
LUID AuthenticationId
Definition: setypes.h:1083
enum _SECURITY_IMPERSONATION_LEVEL * PSECURITY_IMPERSONATION_LEVEL
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
_Must_inspect_result_ typedef _In_ PVOID Unused
Definition: iotypes.h:1166
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
struct _LUID_AND_ATTRIBUTES * PLUID_AND_ATTRIBUTES
struct _TOKEN_PRIMARY_GROUP * PTOKEN_PRIMARY_GROUP
_In_ TOKEN_INFORMATION_CLASS _In_ ULONG TokenInformationLength
Definition: sefuncs.h:312
struct _TOKEN_DEFAULT_DACL TOKEN_DEFAULT_DACL
enum _TOKEN_TYPE * PTOKEN_TYPE
$ULONG GroupCount
Definition: setypes.h:1089
$ULONG DynamicCharged
Definition: setypes.h:1087
PLUID_AND_ATTRIBUTES Privileges
Definition: setypes.h:1044
ULONG SessionId
Definition: dllmain.c:28
NTSYSAPI NTSTATUS NTAPI RtlCopySidAndAttributesArray(_In_ ULONG Count, _In_ PSID_AND_ATTRIBUTES Src, _In_ ULONG SidAreaSize, _In_ PSID_AND_ATTRIBUTES Dest, _In_ PSID SidArea, _Out_ PSID *RemainingSidArea, _Out_ PULONG RemainingSidAreaSize)
LONG NTSTATUS
Definition: precomp.h:26
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
struct _LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3063
struct _TOKEN_USER TOKEN_USER
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
struct _TOKEN_GROUPS_AND_PRIVILEGES TOKEN_GROUPS_AND_PRIVILEGES
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
struct _TOKEN_DEFAULT_DACL * PTOKEN_DEFAULT_DACL
NTSYSAPI VOID NTAPI RtlCopyLuidAndAttributesArray(ULONG Count, PLUID_AND_ATTRIBUTES Src, PLUID_AND_ATTRIBUTES Dest)
Definition: luid.c:33
enum _SECURITY_IMPERSONATION_LEVEL SECURITY_IMPERSONATION_LEVEL
struct _TOKEN_GROUPS_AND_PRIVILEGES * PTOKEN_GROUPS_AND_PRIVILEGES
struct _TOKEN_ORIGIN * PTOKEN_ORIGIN
BOOLEAN NTAPI SeTokenIsInert(_In_ PTOKEN Token)
Determines if a token is a sandbox inert token or not, based upon the token flags.
Definition: token.c:1337
POBJECT_TYPE SeTokenObjectType
Definition: token.c:17
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1130
PSID Owner
Definition: setypes.h:1024
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
TOKEN_TYPE TokenType
Definition: setypes.h:1085
struct _TOKEN_GROUPS * PTOKEN_GROUPS
LUID OriginatingLogonSession
Definition: setypes.h:1103
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2965
struct _ACL * PACL
Definition: security.c:104
Status
Definition: gdiplustypes.h:24
struct _SID_AND_ATTRIBUTES * PSID_AND_ATTRIBUTES
Definition: security.c:129
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
LARGE_INTEGER ExpirationTime
Definition: setypes.h:1084
struct _TOKEN_SOURCE * PTOKEN_SOURCE
#define TOKEN_QUERY
Definition: setypes.h:924
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _TOKEN_OWNER TOKEN_OWNER
struct _TOKEN_SOURCE TOKEN_SOURCE
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
struct _SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES
#define ObDereferenceObject
Definition: obfuncs.h:203
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: setypes.h:1086
#define TOKEN_QUERY_SOURCE
Definition: setypes.h:925
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
struct _SID * PSID
Definition: eventlog.c:35
static __inline NTSTATUS DefaultQueryInfoBufferCheck(_In_ ULONG Class, _In_ const INFORMATION_CLASS_INFO *ClassList, _In_ ULONG ClassListEntries, _In_ ULONG Flags, _In_opt_ PVOID Buffer, _In_ ULONG BufferLength, _In_opt_ PULONG ReturnLength, _In_opt_ PULONG_PTR ReturnLengthPtr, _In_ KPROCESSOR_MODE PreviousMode)
Probe helper that validates the provided parameters whenever a NtQuery*** system call is invoked from...
Definition: probe.h:219
struct _TOKEN_OWNER * PTOKEN_OWNER
struct _TOKEN_PRIVILEGES * PTOKEN_PRIVILEGES
struct _TOKEN_STATISTICS * PTOKEN_STATISTICS
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define SepReleaseTokenLock(Token)
Definition: se.h:286
#define ICIF_PROBE_READ_WRITE
Definition: icif.h:24
NTSYSAPI BOOLEAN WINAPI RtlCopySid(DWORD, PSID, PSID)
static const INFORMATION_CLASS_INFO SeTokenInformationClass[]
Definition: tokencls.c:19
enum _TOKEN_TYPE TOKEN_TYPE
_SEH2_END
Definition: create.c:4400
$ULONG PrivilegeCount
Definition: setypes.h:1090
BOOLEAN NTAPI SeTokenIsRestricted(_In_ PACCESS_TOKEN Token)
Determines if a token is restricted or not, based upon the token flags.
Definition: token.c:1913
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define ICIF_FORCE_RETURN_LENGTH_PROBE
Definition: icif.h:26
SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]
Definition: setypes.h:1014
ULONG RtlLengthSidAndAttributes(_In_ ULONG Count, _In_ PSID_AND_ATTRIBUTES Src)
Computes the length size of a SID.
Definition: token.c:965
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
$ULONG GroupCount
Definition: setypes.h:1010
#define SepAcquireTokenLockShared(Token)
Definition: se.h:280
unsigned int ULONG
Definition: retypes.h:1
PSID_AND_ATTRIBUTES Sids
Definition: setypes.h:1038
struct _TOKEN_USER * PTOKEN_USER
SID_AND_ATTRIBUTES User
Definition: setypes.h:1006
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
PSID_AND_ATTRIBUTES RestrictedSids
Definition: setypes.h:1041
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI SeQuerySessionIdToken(_In_ PACCESS_TOKEN Token, _Out_ PULONG pSessionId)
Queries the session ID of an access token.
Definition: token.c:1791
$ULONG DynamicAvailable
Definition: setypes.h:1088
struct _TOKEN_STATISTICS TOKEN_STATISTICS
unsigned long Ulong
Definition: utypes.h:42
struct _TOKEN_PRIMARY_GROUP TOKEN_PRIMARY_GROUP
_In_ TOKEN_INFORMATION_CLASS TokenInformationClass
Definition: sefuncs.h:310
struct _TOKEN_ORIGIN TOKEN_ORIGIN
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ TOKEN_TYPE TokenType
Definition: sefuncs.h:401
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by CreateDefaultProcessSecurityCommon(), CreateProcessAsUserCommon(), CsrGetProcessLuid(), CsrSetProcessSecurity(), DoAdminUnlock(), DuplicateTokenAsEffective(), GetCallerLuid(), GetSiteSidFromToken(), GetTokenInformation(), GetUserSid(), GetUserSidStringFromToken(), ImpersonateLoggedOnUser(), IsTokenRestricted(), LsapIsTrustedClient(), PlayLogonSoundThread(), QueryOriginalDefaultDacl(), QueryTokenDefaultDaclTests(), QueryTokenGroupsTests(), QueryTokenImpersonationTests(), QueryTokenIsSandboxInert(), QueryTokenOriginTests(), QueryTokenOwnerTests(), QueryTokenPrimaryGroupTests(), QueryTokenPrivilegesAndGroupsTests(), QueryTokenPrivilegesTests(), QueryTokenRestrictedSidsTest(), QueryTokenSessionIdTests(), QueryTokenSourceTests(), QueryTokenStatisticsTests(), QueryTokenTypeTests(), QueryTokenUserTests(), RegOpenUserClassesRoot(), RtlDefaultNpAcl(), RtlNewInstanceSecurityObject(), RtlNewSecurityGrantedAccess(), and START_TEST().

◆ NtSetInformationToken()

_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtSetInformationToken ( _In_ HANDLE  TokenHandle,
_In_ TOKEN_INFORMATION_CLASS  TokenInformationClass,
_In_reads_bytes_(TokenInformationLength) PVOID  TokenInformation,
_In_ ULONG  TokenInformationLength 
)

Sets (modifies) some specific information in regard of an access token. The calling thread must have specific access rights in order to modify token's information data.

@unimplemented

Parameters
[in]TokenHandleA handle of a token where information is to be modified.
[in]TokenInformationClassToken information class.
[in]TokenInformationAn arbitrary pointer to a buffer with token information to set. Such arbitrary buffer depends on the information class chosen that the caller wants to modify such information data of a token.
[in]TokenInformationLengthLength of the token information buffer, in bytes.
Returns
Returns STATUS_SUCCESS if information setting has completed successfully. STATUS_INFO_LENGTH_MISMATCH is returned if the information length of the buffer is less than the required length. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation has failed. STATUS_PRIVILEGE_NOT_HELD is returned if the calling thread hasn't the required privileges to perform the operation in question. A failure NTSTATUS code is returned otherwise.
Remarks
The function is partly implemented, mainly TokenOrigin.

Definition at line 1125 of file tokencls.c.

1130 {
1131  NTSTATUS Status;
1132  PTOKEN Token;
1134  ULONG NeededAccess = TOKEN_ADJUST_DEFAULT;
1135 
1136  PAGED_CODE();
1137 
1139 
1143  TokenInformation,
1145  PreviousMode);
1146  if (!NT_SUCCESS(Status))
1147  {
1148  /* Invalid buffers */
1149  DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status);
1150  return Status;
1151  }
1152 
1154  {
1155  NeededAccess |= TOKEN_ADJUST_SESSIONID;
1156  }
1157 
1159  NeededAccess,
1161  PreviousMode,
1162  (PVOID*)&Token,
1163  NULL);
1164  if (NT_SUCCESS(Status))
1165  {
1166  switch (TokenInformationClass)
1167  {
1168  case TokenOwner:
1169  {
1170  if (TokenInformationLength >= sizeof(TOKEN_OWNER))
1171  {
1172  PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
1173  PSID InputSid = NULL, CapturedSid;
1174  ULONG DefaultOwnerIndex;
1175 
1176  _SEH2_TRY
1177  {
1178  InputSid = to->Owner;
1179  }
1181  {
1183  _SEH2_YIELD(goto Cleanup);
1184  }
1185  _SEH2_END;
1186 
1187  Status = SepCaptureSid(InputSid,
1188  PreviousMode,
1189  PagedPool,
1190  FALSE,
1191  &CapturedSid);
1192  if (NT_SUCCESS(Status))
1193  {
1194  /* Lock the token */
1196 
1197  /* Find the owner amongst the existing token user and groups */
1199  NULL,
1200  CapturedSid,
1201  NULL,
1202  &DefaultOwnerIndex);
1203  if (NT_SUCCESS(Status))
1204  {
1205  /* Found it */
1206  Token->DefaultOwnerIndex = DefaultOwnerIndex;
1207  ExAllocateLocallyUniqueId(&Token->ModifiedId);
1208  }
1209 
1210  /* Unlock the token */
1212 
1213  SepReleaseSid(CapturedSid,
1214  PreviousMode,
1215  FALSE);
1216  }
1217  }
1218  else
1219  {
1221  }
1222  break;
1223  }
1224 
1225  case TokenPrimaryGroup:
1226  {
1228  {
1229  PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
1230  ULONG AclSize;
1232  PSID InputSid = NULL, CapturedSid;
1233  ULONG PrimaryGroupIndex, NewDynamicLength;
1234 
1235  _SEH2_TRY
1236  {
1237  InputSid = tpg->PrimaryGroup;
1238  }
1240  {
1242  _SEH2_YIELD(goto Cleanup);
1243  }
1244  _SEH2_END;
1245 
1246  Status = SepCaptureSid(InputSid,
1247  PreviousMode,
1248  PagedPool,
1249  FALSE,
1250  &CapturedSid);
1251  if (NT_SUCCESS(Status))
1252  {
1253  /* Lock the token */
1255 
1256  /*
1257  * We can whack the token's primary group only if
1258  * the charged dynamic space boundary allows us
1259  * to do so. Exceeding this boundary and we're
1260  * busted out.
1261  */
1262  AclSize = Token->DefaultDacl ? Token->DefaultDacl->AclSize : 0;
1263  NewDynamicLength = RtlLengthSid(CapturedSid) + AclSize;
1264  if (NewDynamicLength > Token->DynamicCharged)
1265  {
1267  SepReleaseSid(CapturedSid, PreviousMode, FALSE);
1269  DPRINT1("NtSetInformationToken(): Couldn't assign new primary group, space exceeded (current length %u, new length %lu)\n",
1270  Token->DynamicCharged, NewDynamicLength);
1271  goto Cleanup;
1272  }
1273 
1274  /*
1275  * The dynamic part of the token may require a rebuild
1276  * if the current dynamic area is too small. If not then
1277  * we're pretty much good as is.
1278  */
1279  Status = SepRebuildDynamicPartOfToken(Token, NewDynamicLength);
1280  if (NT_SUCCESS(Status))
1281  {
1282  /* Find the primary group amongst the existing token user and groups */
1284  CapturedSid,
1285  NULL,
1286  &PrimaryGroupIndex,
1287  NULL);
1288  if (NT_SUCCESS(Status))
1289  {
1290  /*
1291  * We have found it. Add the length of
1292  * the previous primary group SID to the
1293  * available dynamic area.
1294  */
1295  Token->DynamicAvailable += RtlLengthSid(Token->PrimaryGroup);
1296 
1297  /*
1298  * Move the default DACL if it's not at the
1299  * head of the dynamic part.
1300  */
1301  if ((Token->DefaultDacl) &&
1302  ((PULONG)(Token->DefaultDacl) != Token->DynamicPart))
1303  {
1304  RtlMoveMemory(Token->DynamicPart,
1305  Token->DefaultDacl,
1306  RtlLengthSid(Token->PrimaryGroup));
1307  Token->DefaultDacl = (PACL)(Token->DynamicPart);
1308  }
1309 
1310  /* Take away available space from the dynamic area */
1311  Token->DynamicAvailable -= RtlLengthSid(Token->UserAndGroups[PrimaryGroupIndex].Sid);
1312 
1313  /*
1314  * And assign the new primary group. For that
1315  * we have to make sure where the primary group
1316  * is going to stay in memory, so if this token
1317  * has a default DACL then add up its size with
1318  * the address of the dynamic part.
1319  */
1320  PrimaryGroup = (ULONG_PTR)(Token->DynamicPart) + AclSize;
1321  RtlCopySid(RtlLengthSid(Token->UserAndGroups[PrimaryGroupIndex].Sid),
1323  Token->UserAndGroups[PrimaryGroupIndex].Sid);
1324  Token->PrimaryGroup = (PSID)PrimaryGroup;
1325 
1326  ExAllocateLocallyUniqueId(&Token->ModifiedId);
1327  }
1328  }
1329 
1330  /* Unlock the token */
1332 
1333  SepReleaseSid(CapturedSid,
1334  PreviousMode,
1335  FALSE);
1336  }
1337  }
1338  else
1339  {
1341  }
1342  break;
1343  }
1344 
1345  case TokenDefaultDacl:
1346  {
1348  {
1349  PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
1350  PACL InputAcl = NULL;
1351 
1352  _SEH2_TRY
1353  {
1354  InputAcl = tdd->DefaultDacl;
1355  }
1357  {
1359  _SEH2_YIELD(goto Cleanup);
1360  }
1361  _SEH2_END;
1362 
1363  if (InputAcl != NULL)
1364  {
1365  PACL CapturedAcl;
1366 
1367  /* Capture, validate, and copy the DACL */
1368  Status = SepCaptureAcl(InputAcl,
1369  PreviousMode,
1370  PagedPool,
1371  TRUE,
1372  &CapturedAcl);
1373  if (NT_SUCCESS(Status))
1374  {
1375  ULONG NewDynamicLength;
1376  ULONG_PTR Acl;
1377 
1378  /* Lock the token */
1380 
1381  /*
1382  * We can whack the token's default DACL only if
1383  * the charged dynamic space boundary allows us
1384  * to do so. Exceeding this boundary and we're
1385  * busted out.
1386  */
1387  NewDynamicLength = CapturedAcl->AclSize + RtlLengthSid(Token->PrimaryGroup);
1388  if (NewDynamicLength > Token->DynamicCharged)
1389  {
1391  SepReleaseAcl(CapturedAcl, PreviousMode, TRUE);
1393  DPRINT1("NtSetInformationToken(): Couldn't assign new default DACL, space exceeded (current length %u, new length %lu)\n",
1394  Token->DynamicCharged, NewDynamicLength);
1395  goto Cleanup;
1396  }
1397 
1398  /*
1399  * The dynamic part of the token may require a rebuild
1400  * if the current dynamic area is too small. If not then
1401  * we're pretty much good as is.
1402  */
1403  Status = SepRebuildDynamicPartOfToken(Token, NewDynamicLength);
1404  if (NT_SUCCESS(Status))
1405  {
1406  /*
1407  * Before setting up a new DACL for the
1408  * token object we add up the size of
1409  * the old DACL to the available dynamic
1410  * area
1411  */
1412  if (Token->DefaultDacl)
1413  {
1414  Token->DynamicAvailable += Token->DefaultDacl->AclSize;
1415  }
1416 
1417  /*
1418  * Move the primary group if it's not at the
1419  * head of the dynamic part.
1420  */
1421  if ((PULONG)(Token->PrimaryGroup) != Token->DynamicPart)
1422  {
1423  RtlMoveMemory(Token->DynamicPart,
1424  Token->PrimaryGroup,
1425  RtlLengthSid(Token->PrimaryGroup));
1426  Token->PrimaryGroup = (PSID)(Token->DynamicPart);
1427  }
1428 
1429  /* Take away available space from the dynamic area */
1430  Token->DynamicAvailable -= CapturedAcl->AclSize;
1431 
1432  /* Set the new dacl */
1433  Acl = (ULONG_PTR)(Token->DynamicPart) + RtlLengthSid(Token->PrimaryGroup);
1434  RtlCopyMemory((PVOID)Acl,
1435  CapturedAcl,
1436  CapturedAcl->AclSize);
1437  Token->DefaultDacl = (PACL)Acl;
1438 
1439  ExAllocateLocallyUniqueId(&Token->ModifiedId);
1440  }
1441 
1442  /* Unlock the token and release the ACL */
1444  SepReleaseAcl(CapturedAcl, PreviousMode, TRUE);
1445  }
1446  }
1447  else
1448  {
1449  /* Lock the token */
1451 
1452  /* Clear the default dacl if present */
1453  if (Token->DefaultDacl != NULL)
1454  {
1455  Token->DynamicAvailable += Token->DefaultDacl->AclSize;
1456  RtlZeroMemory(Token->DefaultDacl, Token->DefaultDacl->AclSize);
1457  Token->DefaultDacl = NULL;
1458 
1459  ExAllocateLocallyUniqueId(&Token->ModifiedId);
1460  }
1461 
1462  /* Unlock the token */
1464  }
1465  }
1466  else
1467  {
1469  }
1470  break;
1471  }
1472 
1473  case TokenSessionId:
1474  {
1475  ULONG SessionId = 0;
1476 
1477  _SEH2_TRY
1478  {
1479  /* Buffer size was already verified, no need to check here again */
1480  SessionId = *(PULONG)TokenInformation;
1481  }
1483  {
1485  _SEH2_YIELD(goto Cleanup);
1486  }
1487  _SEH2_END;
1488 
1489  /* Check for TCB privilege */
1491  {
1493  break;
1494  }
1495 
1496  /* Lock the token */
1498 
1499  Token->SessionId = SessionId;
1500  ExAllocateLocallyUniqueId(&Token->ModifiedId);
1501 
1502  /* Unlock the token */
1504 
1505  break;
1506  }
1507 
1508  case TokenSessionReference:
1509  {
1510  ULONG SessionReference;
1511 
1512  _SEH2_TRY
1513  {
1514  /* Buffer size was already verified, no need to check here again */
1515  SessionReference = *(PULONG)TokenInformation;
1516  }
1518  {
1520  _SEH2_YIELD(goto Cleanup);
1521  }
1522  _SEH2_END;
1523 
1524  /* Check for TCB privilege */
1526  {
1528  goto Cleanup;
1529  }
1530 
1531  /* Check if it is 0 */
1532  if (SessionReference == 0)
1533  {
1534  ULONG OldTokenFlags;
1535 
1536  /* Lock the token */
1538 
1539  /* Atomically set the flag in the token */
1540  OldTokenFlags = RtlInterlockedSetBits(&Token->TokenFlags,
1542  /*
1543  * If the flag was already set, do not dereference again
1544  * the logon session. Use SessionReference as an indicator
1545  * to know whether to really dereference the session.
1546  */
1547  if (OldTokenFlags == Token->TokenFlags)
1548  SessionReference = ULONG_MAX;
1549 
1550  /*
1551  * Otherwise if the flag was never set but just for this first time then
1552  * remove the referenced logon session data from the token and dereference
1553  * the logon session when needed.
1554  */
1555  if (SessionReference == 0)
1556  {
1558  SepRmDereferenceLogonSession(&Token->AuthenticationId);
1559  }
1560 
1561  /* Unlock the token */
1563  }
1564  break;
1565  }
1566 
1567  case TokenAuditPolicy:
1568  {
1569  PTOKEN_AUDIT_POLICY_INFORMATION PolicyInformation =
1570  (PTOKEN_AUDIT_POLICY_INFORMATION)TokenInformation;
1571  SEP_AUDIT_POLICY AuditPolicy;
1572  ULONG i;
1573 
1574  _SEH2_TRY
1575  {
1576  ProbeForRead(PolicyInformation,
1578  Policies[PolicyInformation->PolicyCount]),
1579  sizeof(ULONG));
1580 
1581  /* Loop all policies in the structure */
1582  for (i = 0; i < PolicyInformation->PolicyCount; i++)
1583  {
1584  /* Set the corresponding bits in the packed structure */
1585  switch (PolicyInformation->Policies[i].Category)
1586  {
1587  case AuditCategorySystem:
1588  AuditPolicy.PolicyElements.System = PolicyInformation->Policies[i].Value;
1589  break;
1590 
1591  case AuditCategoryLogon:
1592  AuditPolicy.PolicyElements.Logon = PolicyInformation->Policies[i].Value;
1593  break;
1594 
1596  AuditPolicy.PolicyElements.ObjectAccess = PolicyInformation->Policies[i].Value;
1597  break;
1598 
1600  AuditPolicy.PolicyElements.PrivilegeUse = PolicyInformation->Policies[i].Value;
1601  break;
1602 
1604  AuditPolicy.PolicyElements.DetailedTracking = PolicyInformation->Policies[i].Value;
1605  break;
1606 
1608  AuditPolicy.PolicyElements.PolicyChange = PolicyInformation->Policies[i].Value;
1609  break;
1610 
1612  AuditPolicy.PolicyElements.AccountManagement = PolicyInformation->Policies[i].Value;
1613  break;
1614 
1616  AuditPolicy.PolicyElements.DirectoryServiceAccess = PolicyInformation->Policies[i].Value;
1617  break;
1618 
1620  AuditPolicy.PolicyElements.AccountLogon = PolicyInformation->Policies[i].Value;
1621  break;
1622  }
1623  }
1624  }
1626  {
1628  _SEH2_YIELD(goto Cleanup);
1629  }
1630  _SEH2_END;
1631 
1632  /* Check for TCB privilege */
1634  {
1636  break;
1637  }
1638 
1639  /* Lock the token */
1641 
1642  /* Set the new audit policy */
1643  Token->AuditPolicy = AuditPolicy;
1644  ExAllocateLocallyUniqueId(&Token->ModifiedId);
1645 
1646  /* Unlock the token */
1648 
1649  break;
1650  }
1651 
1652  case TokenOrigin:
1653  {
1655 
1656  _SEH2_TRY
1657  {
1658  /* Copy the token origin */
1659  TokenOrigin = *(PTOKEN_ORIGIN)TokenInformation;
1660  }
1662  {
1664  _SEH2_YIELD(goto Cleanup);
1665  }
1666  _SEH2_END;
1667 
1668  /* Check for TCB privilege */
1670  {
1672  break;
1673  }
1674 
1675  /* Lock the token */
1677 
1678  /* Check if there is no token origin set yet */
1679  if (RtlIsZeroLuid(&Token->OriginatingLogonSession))
1680  {
1681  /* Set the token origin */
1682  Token->OriginatingLogonSession =
1683  TokenOrigin.OriginatingLogonSession;
1684 
1685  ExAllocateLocallyUniqueId(&Token->ModifiedId);
1686  }
1687 
1688  /* Unlock the token */
1690 
1691  break;
1692  }
1693 
1694  default:
1695  {
1696  DPRINT1("Invalid TokenInformationClass: 0x%lx\n",
1699  break;
1700  }
1701  }
1702 Cleanup:
1704  }
1705 
1706  if (!NT_SUCCESS(Status))
1707  {
1708  DPRINT1("NtSetInformationToken failed with Status 0x%lx\n", Status);
1709  }
1710 
1711  return Status;
1712 }
#define SepAcquireTokenLockExclusive(Token)
Definition: se.h:275
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
VOID NTAPI SepReleaseAcl(_In_ PACL CapturedAcl, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN CaptureIfKernel)
Releases (frees) a captured ACL from the memory pool.
Definition: acl.c:464
struct _TOKEN_PRIMARY_GROUP * PTOKEN_PRIMARY_GROUP
_In_ TOKEN_INFORMATION_CLASS _In_ ULONG TokenInformationLength
Definition: sefuncs.h:312
#define TRUE
Definition: types.h:120
USHORT AclSize
Definition: ms-dtyp.idl:296
NTSTATUS NTAPI SepCaptureSid(_In_ PSID InputSid, _In_ KPROCESSOR_MODE AccessMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSID *CapturedSid)
Captures a SID.
Definition: sid.c:314
ULONG SessionId
Definition: dllmain.c:28
LONG NTSTATUS
Definition: precomp.h:26
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3063
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
VOID NTAPI SepReleaseSid(_In_ PSID CapturedSid, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN CaptureIfKernel)
Releases a captured SID.
Definition: sid.c:400
_SEH2_TRY
Definition: create.c:4226
struct _TOKEN_AUDIT_POLICY_INFORMATION::@1762 Policies[1]
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS SepRmDereferenceLogonSession(_Inout_ PLUID LogonLuid)
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
struct _TOKEN_DEFAULT_DACL * PTOKEN_DEFAULT_DACL
#define FALSE
Definition: types.h:117
struct _TOKEN_ORIGIN * PTOKEN_ORIGIN
NTSTATUS NTAPI SepCaptureAcl(_In_ PACL InputAcl, _In_ KPROCESSOR_MODE AccessMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PACL *CapturedAcl)
Captures an access control list from an already valid input ACL.
Definition: acl.c:352
POBJECT_TYPE SeTokenObjectType
Definition: token.c:17
PSID Owner
Definition: setypes.h:1024
#define TOKEN_ADJUST_DEFAULT
Definition: setypes.h:928
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
struct _ACL * PACL
Definition: security.c:104
Status
Definition: gdiplustypes.h:24
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID _Inout_ PULONG _Out_writes_bytes_to_opt_ PrimaryGroupSize PSID PrimaryGroup
Definition: rtlfuncs.h:1585
static __inline NTSTATUS DefaultSetInfoBufferCheck(_In_ ULONG Class, _In_ const INFORMATION_CLASS_INFO *ClassList, _In_ ULONG ClassListEntries, _In_ PVOID Buffer, _In_ ULONG BufferLength, _In_ KPROCESSOR_MODE PreviousMode)
Probe helper that validates the provided parameters whenever a NtSet*** system call is invoked from u...
Definition: probe.h:70
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define STATUS_ALLOTTED_SPACE_EXCEEDED
Definition: ntstatus.h:389
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ObDereferenceObject
Definition: obfuncs.h:203
#define RtlIsZeroLuid(_L1)
Definition: rtlfuncs.h:753
SEP_AUDIT_POLICY_CATEGORIES PolicyElements
Definition: setypes.h:158
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
struct _SID * PSID
Definition: eventlog.c:35
struct _TOKEN_OWNER * PTOKEN_OWNER
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define SepReleaseTokenLock(Token)
Definition: se.h:286
NTSYSAPI BOOLEAN WINAPI RtlCopySid(DWORD, PSID, PSID)
static const WCHAR Cleanup[]
Definition: register.c:80
static const INFORMATION_CLASS_INFO SeTokenInformationClass[]
Definition: tokencls.c:19
NTSTATUS NTAPI SepRmRemoveLogonSessionFromToken(_Inout_ PTOKEN Token)
Removes a logon session from an access token.
Definition: srm.c:449
const LUID SeTcbPrivilege
Definition: priv.c:26
NTSTATUS SepRebuildDynamicPartOfToken(_In_ PTOKEN Token, _In_ ULONG NewDynamicPartSize)
_SEH2_END
Definition: create.c:4400
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
VOID NTAPI ExAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
Definition: uuid.c:335
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
struct _TOKEN_AUDIT_POLICY_INFORMATION * PTOKEN_AUDIT_POLICY_INFORMATION
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
#define RtlInterlockedSetBits(Flags, Flag)
Definition: rtlfuncs.h:3434
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define DPRINT
Definition: sndvol32.h:71
#define TOKEN_ADJUST_SESSIONID
Definition: setypes.h:929
#define TOKEN_SESSION_NOT_REFERENCED
Definition: setypes.h:1180
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
_In_ TOKEN_INFORMATION_CLASS TokenInformationClass
Definition: sefuncs.h:310
#define ULONG_MAX
Definition: limits.h:44
#define PAGED_CODE()

Referenced by SetTokenDefaultDaclTests(), SetTokenInformation(), SetTokenSessionIdTests(), and START_TEST().

◆ SeQueryInformationToken()

NTSTATUS NTAPI SeQueryInformationToken ( _In_ PACCESS_TOKEN  AccessToken,
_In_ TOKEN_INFORMATION_CLASS  TokenInformationClass,
_Outptr_result_buffer_(_Inexpressible_(token-dependent)) PVOID TokenInformation 
)

Queries information details about the given token to the call. The difference between NtQueryInformationToken and this routine is that the system call has user mode buffer data probing and additional protection checks whereas this routine doesn't have any of these. The routine is used exclusively in kernel mode.

Parameters
[in]AccessTokenAn access token to be given.
[in]TokenInformationClassToken information class.
[out]TokenInformationBuffer with retrieved information. Such information is arbitrary, depending on the requested information class.
Returns
Returns STATUS_SUCCESS if the operation to query the desired information has completed successfully. STATUS_INSUFFICIENT_RESOURCES is returned if pool memory allocation has failed to satisfy an operation. Otherwise STATUS_INVALID_INFO_CLASS is returned indicating that the information class provided is not supported by the routine.
Remarks
Only certain information classes are not implemented in this function and these are TokenOrigin, TokenGroupsAndPrivileges, TokenRestrictedSids and TokenSandBoxInert. The following classes are implemented in NtQueryInformationToken only.

Definition at line 95 of file tokencls.c.

99 {
101  PTOKEN Token = (PTOKEN)AccessToken;
103  union
104  {
105  PSID PSid;
106  ULONG Ulong;
107  } Unused;
108 
109  PAGED_CODE();
110 
111  /* Lock the token */
113 
114  switch (TokenInformationClass)
115  {
116  case TokenUser:
117  {
118  PTOKEN_USER tu;
119 
120  DPRINT("SeQueryInformationToken(TokenUser)\n");
121  RequiredLength = sizeof(TOKEN_USER) +
122  RtlLengthSid(Token->UserAndGroups[0].Sid);
123 
124  /* Allocate the output buffer */
126  if (tu == NULL)
127  {
129  break;
130  }
131 
133  &Token->UserAndGroups[0],
134  RequiredLength - sizeof(TOKEN_USER),
135  &tu->User,
136  (PSID)(tu + 1),
137  &Unused.PSid,
138  &Unused.Ulong);
139 
140  /* Return the structure */
141  *TokenInformation = tu;
143  break;
144  }
145 
146  case TokenGroups:
147  {
148  PTOKEN_GROUPS tg;
149  ULONG SidLen;
150  PSID Sid;
151 
152  DPRINT("SeQueryInformationToken(TokenGroups)\n");
153  RequiredLength = sizeof(tg->GroupCount) +
154  RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
155 
156  SidLen = RequiredLength - sizeof(tg->GroupCount) -
157  ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES));
158 
159  /* Allocate the output buffer */
161  if (tg == NULL)
162  {
164  break;
165  }
166 
167  Sid = (PSID)((ULONG_PTR)tg + sizeof(tg->GroupCount) +
168  ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)));
169 
170  tg->GroupCount = Token->UserAndGroupCount - 1;
171  Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
172  &Token->UserAndGroups[1],
173  SidLen,
174  &tg->Groups[0],
175  Sid,
176  &Unused.PSid,
177  &Unused.Ulong);
178 
179  /* Return the structure */
180  *TokenInformation = tg;
182  break;
183  }
184 
185  case TokenPrivileges:
186  {
188 
189  DPRINT("SeQueryInformationToken(TokenPrivileges)\n");
190  RequiredLength = sizeof(tp->PrivilegeCount) +
191  (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
192 
193  /* Allocate the output buffer */
195  if (tp == NULL)
196  {
198  break;
199  }
200 
201  tp->PrivilegeCount = Token->PrivilegeCount;
202  RtlCopyLuidAndAttributesArray(Token->PrivilegeCount,
203  Token->Privileges,
204  &tp->Privileges[0]);
205 
206  /* Return the structure */
207  *TokenInformation = tp;
209  break;
210  }
211 
212  case TokenOwner:
213  {
214  PTOKEN_OWNER to;
215  ULONG SidLen;
216 
217  DPRINT("SeQueryInformationToken(TokenOwner)\n");
218  SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
219  RequiredLength = sizeof(TOKEN_OWNER) + SidLen;
220 
221  /* Allocate the output buffer */
223  if (to == NULL)
224  {
226  break;
227  }
228 
229  to->Owner = (PSID)(to + 1);
230  Status = RtlCopySid(SidLen,
231  to->Owner,
232  Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
233 
234  /* Return the structure */
235  *TokenInformation = to;
237  break;
238  }
239 
240  case TokenPrimaryGroup:
241  {
243  ULONG SidLen;
244 
245  DPRINT("SeQueryInformationToken(TokenPrimaryGroup)\n");
246  SidLen = RtlLengthSid(Token->PrimaryGroup);
247  RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen;
248 
249  /* Allocate the output buffer */
251  if (tpg == NULL)
252  {
254  break;
255  }
256 
257  tpg->PrimaryGroup = (PSID)(tpg + 1);
258  Status = RtlCopySid(SidLen,
259  tpg->PrimaryGroup,
260  Token->PrimaryGroup);
261 
262  /* Return the structure */
263  *TokenInformation = tpg;
265  break;
266  }
267 
268  case TokenDefaultDacl:
269  {
271 
272  DPRINT("SeQueryInformationToken(TokenDefaultDacl)\n");
274 
275  if (Token->DefaultDacl != NULL)
276  RequiredLength += Token->DefaultDacl->AclSize;
277 
278  /* Allocate the output buffer */
280  if (tdd == NULL)
281  {
283  break;
284  }
285 
286  if (Token->DefaultDacl != NULL)
287  {
288  tdd->DefaultDacl = (PACL)(tdd + 1);
290  Token->DefaultDacl,
291  Token->DefaultDacl->AclSize);
292  }
293  else
294  {
295  tdd->DefaultDacl = NULL;
296  }
297 
298  /* Return the structure */
299  *TokenInformation = tdd;
301  break;
302  }
303 
304  case TokenSource:
305  {
306  PTOKEN_SOURCE ts;
307 
308  DPRINT("SeQueryInformationToken(TokenSource)\n");
309  RequiredLength = sizeof(TOKEN_SOURCE);
310 
311  /* Allocate the output buffer */
313  if (ts == NULL)
314  {
316  break;
317  }
318 
319  *ts = Token->TokenSource;
320 
321  /* Return the structure */
322  *TokenInformation = ts;
324  break;
325  }
326 
327  case TokenType:
328  {
329  PTOKEN_TYPE tt;
330 
331  DPRINT("SeQueryInformationToken(TokenType)\n");
332  RequiredLength = sizeof(TOKEN_TYPE);
333 
334  /* Allocate the output buffer */
336  if (tt == NULL)
337  {
339  break;
340  }
341 
342  *tt = Token->TokenType;
343 
344  /* Return the structure */
345  *TokenInformation = tt;
347  break;
348  }
349 
351  {
353 
354  DPRINT("SeQueryInformationToken(TokenImpersonationLevel)\n");
356 
357  /* Fail if the token is not an impersonation token */
358  if (Token->TokenType != TokenImpersonation)
359  {
361  break;
362  }
363 
364  /* Allocate the output buffer */
366  if (sil == NULL)
367  {
369  break;
370  }
371 
372  *sil = Token->ImpersonationLevel;
373 
374  /* Return the structure */
375  *TokenInformation = sil;
377  break;
378  }
379 
380  case TokenStatistics:
381  {
383 
384  DPRINT("SeQueryInformationToken(TokenStatistics)\n");
386 
387  /* Allocate the output buffer */
389  if (ts == NULL)
390  {
392  break;
393  }
394 
395  ts->TokenId = Token->TokenId;
396  ts->AuthenticationId = Token->AuthenticationId;
397  ts->ExpirationTime = Token->ExpirationTime;
398  ts->TokenType = Token->TokenType;
399  ts->ImpersonationLevel = Token->ImpersonationLevel;
400  ts->DynamicCharged = Token->DynamicCharged;
401  ts->DynamicAvailable = SepComputeAvailableDynamicSpace(Token->DynamicCharged, Token->PrimaryGroup, Token->DefaultDacl);
402  ts->GroupCount = Token->UserAndGroupCount - 1;
403  ts->PrivilegeCount = Token->PrivilegeCount;
404  ts->ModifiedId = Token->ModifiedId;
405 
406  /* Return the structure */
407  *TokenInformation = ts;
409  break;
410  }
411 
412  case TokenSessionId:
413  {
414  DPRINT("SeQueryInformationToken(TokenSessionId)\n");
415  Status = SeQuerySessionIdToken(Token, (PULONG)TokenInformation);
416  break;
417  }
418 
419  default:
420  DPRINT1("SeQueryInformationToken(%d) invalid information class\n", TokenInformationClass);
422  break;
423  }
424 
425  /* Release the lock of the token */
427 
428  return Status;
429 }
LUID AuthenticationId
Definition: setypes.h:1083
enum _SECURITY_IMPERSONATION_LEVEL * PSECURITY_IMPERSONATION_LEVEL
_Must_inspect_result_ typedef _In_ PVOID Unused
Definition: iotypes.h:1166
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
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
struct _TOKEN_DEFAULT_DACL TOKEN_DEFAULT_DACL
enum _TOKEN_TYPE * PTOKEN_TYPE
$ULONG GroupCount
Definition: setypes.h:1089
$ULONG DynamicCharged
Definition: setypes.h:1087
NTSYSAPI NTSTATUS NTAPI RtlCopySidAndAttributesArray(_In_ ULONG Count, _In_ PSID_AND_ATTRIBUTES Src, _In_ ULONG SidAreaSize, _In_ PSID_AND_ATTRIBUTES Dest, _In_ PSID SidArea, _Out_ PSID *RemainingSidArea, _Out_ PULONG RemainingSidAreaSize)
LONG NTSTATUS
Definition: precomp.h:26
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
struct _TOKEN_USER TOKEN_USER
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSYSAPI VOID NTAPI RtlCopyLuidAndAttributesArray(ULONG Count, PLUID_AND_ATTRIBUTES Src, PLUID_AND_ATTRIBUTES Dest)
Definition: luid.c:33
enum _SECURITY_IMPERSONATION_LEVEL SECURITY_IMPERSONATION_LEVEL
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1130
PSID Owner
Definition: setypes.h:1024
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
TOKEN_TYPE TokenType
Definition: setypes.h:1085
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2965
struct _ACL * PACL
Definition: security.c:104
Status
Definition: gdiplustypes.h:24
#define TAG_SE
Definition: tag.h:147
LARGE_INTEGER ExpirationTime
Definition: setypes.h:1084
struct _TOKEN_OWNER TOKEN_OWNER
struct _TOKEN_SOURCE TOKEN_SOURCE
struct _SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: setypes.h:1086
struct _SID * PSID
Definition: eventlog.c:35
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define SepReleaseTokenLock(Token)
Definition: se.h:286
NTSYSAPI BOOLEAN WINAPI RtlCopySid(DWORD, PSID, PSID)
enum _TOKEN_TYPE TOKEN_TYPE
$ULONG PrivilegeCount
Definition: setypes.h:1090
struct _TOKEN * PTOKEN
SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]
Definition: setypes.h:1014
ULONG RtlLengthSidAndAttributes(_In_ ULONG Count, _In_ PSID_AND_ATTRIBUTES Src)
Computes the length size of a SID.
Definition: token.c:965
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
$ULONG GroupCount
Definition: setypes.h:1010
#define SepAcquireTokenLockShared(Token)
Definition: se.h:280
unsigned int ULONG
Definition: retypes.h:1
SID_AND_ATTRIBUTES User
Definition: setypes.h:1006
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI SeQuerySessionIdToken(_In_ PACCESS_TOKEN Token, _Out_ PULONG pSessionId)
Queries the session ID of an access token.
Definition: token.c:1791
$ULONG DynamicAvailable
Definition: setypes.h:1088
struct _TOKEN_STATISTICS TOKEN_STATISTICS
unsigned long Ulong
Definition: utypes.h:42
struct _TOKEN_PRIMARY_GROUP TOKEN_PRIMARY_GROUP
_In_ TOKEN_INFORMATION_CLASS TokenInformationClass
Definition: sefuncs.h:310
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ TOKEN_TYPE TokenType
Definition: sefuncs.h:401
#define PAGED_CODE()

Referenced by find_gid(), NtSecureConnectPort(), START_TEST(), and TestsSeQueryInformationToken().

Variable Documentation

◆ SeTokenInformationClass

const INFORMATION_CLASS_INFO SeTokenInformationClass[]
static

Definition at line 19 of file tokencls.c.

Referenced by NtQueryInformationToken(), and NtSetInformationToken().