[NTOS]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Fri, 4 Nov 2016 17:52:32 +0000 (17:52 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Fri, 4 Nov 2016 17:52:32 +0000 (17:52 +0000)
- accesschk.c: Remove redundant SepAccessCheck/SepAccessCheckEx pair of private functions; instead just rename SepAccessCheckEx into SepAccessCheck and use it directly in the code. NOTE: SepAccessCheck is *incomplete* (in particular it doesn't retrieve the information needed to initialize the 'Privileges' parameter).
- sid.c: Comments formatting fix.
- token.c:
  * Finish to implement SeQueryInformationToken . This function is really the same as NtQueryInformationToken but without all the stuff needed for user-mode buffer access protection.
  * Some code simplifications in NtQueryInformationToken.
  I need this to fix a "FIXME: Use SeQueryInformationToken" in some code I'm also fixing (& commit later).

[NDK]: Fix parameter types and add annotations to RtlCopySidAndAttributesArray.

[KMTESTS:NTOS_SE]
- Reenable the 'SeQueryInfoToken' test.
- Show that SeQueryInformationToken doesn't support 4 token information classes, which are supported only by NtQueryInformationToken.
- Fix calling of SeAccessCheck. In particular the 'Privileges' parameter is not allocated by the caller, but instead is allocated by SeAccessCheck *and* returned to the caller (who then must free the buffer using SeFreePrivileges). This fixes the encountered BSODs that leaded to disabling preventively the test in r59178.
- Minor code cleaning.

svn path=/trunk/; revision=73122

reactos/ntoskrnl/se/accesschk.c
reactos/ntoskrnl/se/sid.c
reactos/ntoskrnl/se/token.c
reactos/sdk/include/ndk/rtlfuncs.h
reactos/sdk/lib/rtl/sid.c
rostests/kmtests/kmtest_drv/testlist.c
rostests/kmtests/ntos_se/SeQueryInfoToken.c

index 9bfd17f..9b84b46 100644 (file)
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
+/*
+ * FIXME: Incomplete!
+ */
 BOOLEAN NTAPI
 BOOLEAN NTAPI
-SepAccessCheckEx(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
                IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
                IN ACCESS_MASK DesiredAccess,
                IN POBJECT_TYPE_LIST ObjectTypeList,
                IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
                IN ACCESS_MASK DesiredAccess,
                IN POBJECT_TYPE_LIST ObjectTypeList,
@@ -46,7 +49,7 @@ SepAccessCheckEx(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
     NTSTATUS Status;
     PAGED_CODE();
 
     NTSTATUS Status;
     PAGED_CODE();
 
-    DPRINT("SepAccessCheckEx()\n");
+    DPRINT("SepAccessCheck()\n");
 
     /* Check for no access desired */
     if (!DesiredAccess)
 
     /* Check for no access desired */
     if (!DesiredAccess)
@@ -283,31 +286,6 @@ ReturnCommonStatus:
     return NT_SUCCESS(Status);
 }
 
     return NT_SUCCESS(Status);
 }
 
-BOOLEAN NTAPI
-SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
-               IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
-               IN ACCESS_MASK DesiredAccess,
-               IN ACCESS_MASK PreviouslyGrantedAccess,
-               OUT PPRIVILEGE_SET* Privileges,
-               IN PGENERIC_MAPPING GenericMapping,
-               IN KPROCESSOR_MODE AccessMode,
-               OUT PACCESS_MASK GrantedAccess,
-               OUT PNTSTATUS AccessStatus)
-{
-    return SepAccessCheckEx(SecurityDescriptor,
-                            SubjectSecurityContext,
-                            DesiredAccess,
-                            NULL,
-                            0,
-                            PreviouslyGrantedAccess,
-                            Privileges,
-                            GenericMapping,
-                            AccessMode,
-                            GrantedAccess,
-                            AccessStatus,
-                            FALSE);
-}
-
 static PSID
 SepGetSDOwner(IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
 {
 static PSID
 SepGetSDOwner(IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
 {
@@ -443,12 +421,15 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
         ret = SepAccessCheck(SecurityDescriptor,
                              SubjectSecurityContext,
                              DesiredAccess,
         ret = SepAccessCheck(SecurityDescriptor,
                              SubjectSecurityContext,
                              DesiredAccess,
+                             NULL,
+                             0,
                              PreviouslyGrantedAccess,
                              Privileges,
                              GenericMapping,
                              AccessMode,
                              GrantedAccess,
                              PreviouslyGrantedAccess,
                              Privileges,
                              GenericMapping,
                              AccessMode,
                              GrantedAccess,
-                             AccessStatus);
+                             AccessStatus,
+                             FALSE);
     }
 
     /* Release the lock if needed */
     }
 
     /* Release the lock if needed */
@@ -687,12 +668,15 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
         SepAccessCheck(SecurityDescriptor, // FIXME: use CapturedSecurityDescriptor
                        &SubjectSecurityContext,
                        DesiredAccess,
         SepAccessCheck(SecurityDescriptor, // FIXME: use CapturedSecurityDescriptor
                        &SubjectSecurityContext,
                        DesiredAccess,
+                       NULL,
+                       0,
                        PreviouslyGrantedAccess,
                        &PrivilegeSet, //FIXME
                        GenericMapping,
                        PreviousMode,
                        GrantedAccess,
                        PreviouslyGrantedAccess,
                        &PrivilegeSet, //FIXME
                        GenericMapping,
                        PreviousMode,
                        GrantedAccess,
-                       AccessStatus);
+                       AccessStatus,
+                       FALSE);
     }
 
     /* Release subject context and unlock the token */
     }
 
     /* Release subject context and unlock the token */
index 007f6a9..d75dd78 100644 (file)
@@ -297,7 +297,7 @@ SepCaptureSid(IN PSID InputSid,
         }
         _SEH2_END;
 
         }
         _SEH2_END;
 
-        /* allocate a SID and copy it */
+        /* Allocate a SID and copy it */
         NewSid = ExAllocatePoolWithTag(PoolType, SidSize, TAG_SID);
         if (!NewSid)
             return STATUS_INSUFFICIENT_RESOURCES;
         NewSid = ExAllocatePoolWithTag(PoolType, SidSize, TAG_SID);
         if (!NewSid)
             return STATUS_INSUFFICIENT_RESOURCES;
@@ -324,7 +324,7 @@ SepCaptureSid(IN PSID InputSid,
     {
         SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount);
 
     {
         SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount);
 
-        /* allocate a SID and copy it */
+        /* Allocate a SID and copy it */
         NewSid = ExAllocatePoolWithTag(PoolType, SidSize, TAG_SID);
         if (NewSid == NULL)
             return STATUS_INSUFFICIENT_RESOURCES;
         NewSid = ExAllocatePoolWithTag(PoolType, SidSize, TAG_SID);
         if (NewSid == NULL)
             return STATUS_INSUFFICIENT_RESOURCES;
index cfdf0ae..46ab29b 100644 (file)
@@ -232,7 +232,7 @@ SeExchangePrimaryToken(PEPROCESS Process,
 
     PAGED_CODE();
 
 
     PAGED_CODE();
 
-    if (NewToken->TokenType != TokenPrimary) return(STATUS_BAD_TOKEN_TYPE);
+    if (NewToken->TokenType != TokenPrimary) return STATUS_BAD_TOKEN_TYPE;
     if (NewToken->TokenInUse)
     {
         BOOLEAN IsEqual;
     if (NewToken->TokenInUse)
     {
         BOOLEAN IsEqual;
@@ -348,12 +348,12 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token,
 
     if (Token->DefaultOwnerIndex == Token->UserAndGroupCount)
     {
 
     if (Token->DefaultOwnerIndex == Token->UserAndGroupCount)
     {
-        return(STATUS_INVALID_OWNER);
+        return STATUS_INVALID_OWNER;
     }
 
     if (Token->PrimaryGroup == 0)
     {
     }
 
     if (Token->PrimaryGroup == 0)
     {
-        return(STATUS_INVALID_PRIMARY_GROUP);
+        return STATUS_INVALID_PRIMARY_GROUP;
     }
 
     return STATUS_SUCCESS;
     }
 
     return STATUS_SUCCESS;
@@ -1060,16 +1060,26 @@ SeFilterToken(IN PACCESS_TOKEN ExistingToken,
 }
 
 /*
 }
 
 /*
- * @unimplemented
+ * @implemented
+ *
+ * NOTE: SeQueryInformationToken is just NtQueryInformationToken without all
+ * the bells and whistles needed for user-mode buffer access protection.
  */
 NTSTATUS
 NTAPI
  */
 NTSTATUS
 NTAPI
-SeQueryInformationToken(IN PACCESS_TOKEN Token,
+SeQueryInformationToken(IN PACCESS_TOKEN AccessToken,
                         IN TOKEN_INFORMATION_CLASS TokenInformationClass,
                         OUT PVOID *TokenInformation)
 {
     NTSTATUS Status;
                         IN TOKEN_INFORMATION_CLASS TokenInformationClass,
                         OUT PVOID *TokenInformation)
 {
     NTSTATUS Status;
-    PSECURITY_IMPERSONATION_LEVEL SeImpersonationLvl;
+    PTOKEN Token = (PTOKEN)AccessToken;
+    ULONG RequiredLength;
+    union
+    {
+        PSID PSid;
+        ULONG Ulong;
+    } Unused;
+
     PAGED_CODE();
 
     if (TokenInformationClass >= MaxTokenInfoClass)
     PAGED_CODE();
 
     if (TokenInformationClass >= MaxTokenInfoClass)
@@ -1080,32 +1090,396 @@ SeQueryInformationToken(IN PACCESS_TOKEN Token,
 
     switch (TokenInformationClass)
     {
 
     switch (TokenInformationClass)
     {
+        case TokenUser:
+        {
+            PTOKEN_USER tu;
+
+            DPRINT("SeQueryInformationToken(TokenUser)\n");
+            RequiredLength = sizeof(TOKEN_USER) +
+                RtlLengthSid(Token->UserAndGroups[0].Sid);
+
+            /* Allocate the output buffer */
+            tu = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (tu == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            Status = RtlCopySidAndAttributesArray(1,
+                                                  &Token->UserAndGroups[0],
+                                                  RequiredLength - sizeof(TOKEN_USER),
+                                                  &tu->User,
+                                                  (PSID)(tu + 1),
+                                                  &Unused.PSid,
+                                                  &Unused.Ulong);
+
+            /* Return the structure */
+            *TokenInformation = tu;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case TokenGroups:
+        {
+            PTOKEN_GROUPS tg;
+            ULONG SidLen;
+            PSID Sid;
+
+            DPRINT("SeQueryInformationToken(TokenGroups)\n");
+            RequiredLength = sizeof(tg->GroupCount) +
+                RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
+
+            SidLen = RequiredLength - sizeof(tg->GroupCount) -
+                ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES));
+
+            /* Allocate the output buffer */
+            tg = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (tg == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            Sid = (PSID)((ULONG_PTR)tg + sizeof(tg->GroupCount) +
+                         ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)));
+
+            tg->GroupCount = Token->UserAndGroupCount - 1;
+            Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
+                                                  &Token->UserAndGroups[1],
+                                                  SidLen,
+                                                  &tg->Groups[0],
+                                                  Sid,
+                                                  &Unused.PSid,
+                                                  &Unused.Ulong);
+
+            /* Return the structure */
+            *TokenInformation = tg;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case TokenPrivileges:
+        {
+            PTOKEN_PRIVILEGES tp;
+
+            DPRINT("SeQueryInformationToken(TokenPrivileges)\n");
+            RequiredLength = sizeof(tp->PrivilegeCount) +
+                (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+
+            /* Allocate the output buffer */
+            tp = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (tp == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            tp->PrivilegeCount = Token->PrivilegeCount;
+            RtlCopyLuidAndAttributesArray(Token->PrivilegeCount,
+                                          Token->Privileges,
+                                          &tp->Privileges[0]);
+
+            /* Return the structure */
+            *TokenInformation = tp;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case TokenOwner:
+        {
+            PTOKEN_OWNER to;
+            ULONG SidLen;
+
+            DPRINT("SeQueryInformationToken(TokenOwner)\n");
+            SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
+            RequiredLength = sizeof(TOKEN_OWNER) + SidLen;
+
+            /* Allocate the output buffer */
+            to = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (to == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            to->Owner = (PSID)(to + 1);
+            Status = RtlCopySid(SidLen,
+                                to->Owner,
+                                Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
+
+            /* Return the structure */
+            *TokenInformation = to;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case TokenPrimaryGroup:
+        {
+            PTOKEN_PRIMARY_GROUP tpg;
+            ULONG SidLen;
+
+            DPRINT("SeQueryInformationToken(TokenPrimaryGroup)\n");
+            SidLen = RtlLengthSid(Token->PrimaryGroup);
+            RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen;
+
+            /* Allocate the output buffer */
+            tpg = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (tpg == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            tpg->PrimaryGroup = (PSID)(tpg + 1);
+            Status = RtlCopySid(SidLen,
+                                tpg->PrimaryGroup,
+                                Token->PrimaryGroup);
+
+            /* Return the structure */
+            *TokenInformation = tpg;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case TokenDefaultDacl:
+        {
+            PTOKEN_DEFAULT_DACL tdd;
+
+            DPRINT("SeQueryInformationToken(TokenDefaultDacl)\n");
+            RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
+
+            if (Token->DefaultDacl != NULL)
+                RequiredLength += Token->DefaultDacl->AclSize;
+
+            /* Allocate the output buffer */
+            tdd = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (tdd == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            if (Token->DefaultDacl != NULL)
+            {
+                tdd->DefaultDacl = (PACL)(tdd + 1);
+                RtlCopyMemory(tdd->DefaultDacl,
+                              Token->DefaultDacl,
+                              Token->DefaultDacl->AclSize);
+            }
+            else
+            {
+                tdd->DefaultDacl = NULL;
+            }
+
+            /* Return the structure */
+            *TokenInformation = tdd;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case TokenSource:
+        {
+            PTOKEN_SOURCE ts;
+
+            DPRINT("SeQueryInformationToken(TokenSource)\n");
+            RequiredLength = sizeof(TOKEN_SOURCE);
+
+            /* Allocate the output buffer */
+            ts = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (ts == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            *ts = Token->TokenSource;
+
+            /* Return the structure */
+            *TokenInformation = ts;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case TokenType:
+        {
+            PTOKEN_TYPE tt;
+
+            DPRINT("SeQueryInformationToken(TokenType)\n");
+            RequiredLength = sizeof(TOKEN_TYPE);
+
+            /* Allocate the output buffer */
+            tt = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (tt == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            *tt = Token->TokenType;
+
+            /* Return the structure */
+            *TokenInformation = tt;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
         case TokenImpersonationLevel:
         case TokenImpersonationLevel:
-            /* It is mandatory to have an impersonation token */
-            if (((PTOKEN)Token)->TokenType != TokenImpersonation)
+        {
+            PSECURITY_IMPERSONATION_LEVEL sil;
+
+            DPRINT("SeQueryInformationToken(TokenImpersonationLevel)\n");
+            RequiredLength = sizeof(SECURITY_IMPERSONATION_LEVEL);
+
+            /* Fail if the token is not an impersonation token */
+            if (Token->TokenType != TokenImpersonation)
             {
                 Status = STATUS_INVALID_INFO_CLASS;
                 break;
             }
 
             /* Allocate the output buffer */
             {
                 Status = STATUS_INVALID_INFO_CLASS;
                 break;
             }
 
             /* Allocate the output buffer */
-            SeImpersonationLvl = ExAllocatePoolWithTag(PagedPool, sizeof(SECURITY_IMPERSONATION_LEVEL), TAG_SE);
-            if (SeImpersonationLvl == NULL)
+            sil = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (sil == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            *sil = Token->ImpersonationLevel;
+
+            /* Return the structure */
+            *TokenInformation = sil;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case TokenStatistics:
+        {
+            PTOKEN_STATISTICS ts;
+
+            DPRINT("SeQueryInformationToken(TokenStatistics)\n");
+            RequiredLength = sizeof(TOKEN_STATISTICS);
+
+            /* Allocate the output buffer */
+            ts = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (ts == NULL)
             {
                 Status = STATUS_INSUFFICIENT_RESOURCES;
                 break;
             }
 
             {
                 Status = STATUS_INSUFFICIENT_RESOURCES;
                 break;
             }
 
-            /* Set impersonation level and return the structure */
-            *SeImpersonationLvl = ((PTOKEN)Token)->ImpersonationLevel;
-            *TokenInformation = SeImpersonationLvl;
+            ts->TokenId = Token->TokenId;
+            ts->AuthenticationId = Token->AuthenticationId;
+            ts->ExpirationTime = Token->ExpirationTime;
+            ts->TokenType = Token->TokenType;
+            ts->ImpersonationLevel = Token->ImpersonationLevel;
+            ts->DynamicCharged = Token->DynamicCharged;
+            ts->DynamicAvailable = Token->DynamicAvailable;
+            ts->GroupCount = Token->UserAndGroupCount - 1;
+            ts->PrivilegeCount = Token->PrivilegeCount;
+            ts->ModifiedId = Token->ModifiedId;
+
+            /* Return the structure */
+            *TokenInformation = ts;
             Status = STATUS_SUCCESS;
             break;
             Status = STATUS_SUCCESS;
             break;
+        }
 
 
-        default:
-            UNIMPLEMENTED;
+/*
+ * The following 4 cases are only implemented in NtQueryInformationToken
+ */
+#if 0
+
+        case TokenOrigin:
+        {
+            PTOKEN_ORIGIN to;
+
+            DPRINT("SeQueryInformationToken(TokenOrigin)\n");
+            RequiredLength = sizeof(TOKEN_ORIGIN);
+
+            /* Allocate the output buffer */
+            to = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (to == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            RtlCopyLuid(&to->OriginatingLogonSession,
+                        &Token->AuthenticationId);
+
+            /* Return the structure */
+            *TokenInformation = to;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case TokenGroupsAndPrivileges:
+            DPRINT1("SeQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n");
             Status = STATUS_NOT_IMPLEMENTED;
             break;
             Status = STATUS_NOT_IMPLEMENTED;
             break;
+
+        case TokenRestrictedSids:
+        {
+            PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
+            ULONG SidLen;
+            PSID Sid;
+
+            DPRINT("SeQueryInformationToken(TokenRestrictedSids)\n");
+            RequiredLength = sizeof(tg->GroupCount) +
+            RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids);
+
+            SidLen = RequiredLength - sizeof(tg->GroupCount) -
+                (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES));
+
+            /* Allocate the output buffer */
+            tg = ExAllocatePoolWithTag(PagedPool, RequiredLength, TAG_SE);
+            if (tg == NULL)
+            {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                break;
+            }
+
+            Sid = (PSID)((ULONG_PTR)tg + sizeof(tg->GroupCount) +
+                         (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)));
+
+            tg->GroupCount = Token->RestrictedSidCount;
+            Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount,
+                                                  Token->RestrictedSids,
+                                                  SidLen,
+                                                  &tg->Groups[0],
+                                                  Sid,
+                                                  &Unused.PSid,
+                                                  &Unused.Ulong);
+
+            /* Return the structure */
+            *TokenInformation = tg;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case TokenSandBoxInert:
+            DPRINT1("SeQueryInformationToken(TokenSandboxInert) not implemented\n");
+            Status = STATUS_NOT_IMPLEMENTED;
+            break;
+
+#endif
+
+        case TokenSessionId:
+        {
+            DPRINT("SeQueryInformationToken(TokenSessionId)\n");
+
+            Status = SeQuerySessionIdToken(Token, (PULONG)TokenInformation);
+
+            // Status = STATUS_SUCCESS;
+            break;
+        }
+
+        default:
+            DPRINT1("SeQueryInformationToken(%d) invalid information class\n", TokenInformationClass);
+            Status = STATUS_INVALID_INFO_CLASS;
+            break;
     }
 
     return Status;
     }
 
     return Status;
@@ -1212,15 +1586,15 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                         IN ULONG TokenInformationLength,
                         OUT PULONG ReturnLength)
 {
                         IN ULONG TokenInformationLength,
                         OUT PULONG ReturnLength)
 {
+    NTSTATUS Status;
+    KPROCESSOR_MODE PreviousMode;
+    PTOKEN Token;
+    ULONG RequiredLength;
     union
     {
     union
     {
-        PVOID Ptr;
+        PSID PSid;
         ULONG Ulong;
     } Unused;
         ULONG Ulong;
     } Unused;
-    PTOKEN Token;
-    ULONG RequiredLength;
-    KPROCESSOR_MODE PreviousMode;
-    NTSTATUS Status;
 
     PAGED_CODE();
 
 
     PAGED_CODE();
 
@@ -1229,7 +1603,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
     /* Check buffers and class validity */
     Status = DefaultQueryInfoBufferCheck(TokenInformationClass,
                                          SeTokenInformationClass,
     /* Check buffers and class validity */
     Status = DefaultQueryInfoBufferCheck(TokenInformationClass,
                                          SeTokenInformationClass,
-                                         sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]),
+                                         RTL_NUMBER_OF(SeTokenInformationClass),
                                          TokenInformation,
                                          TokenInformationLength,
                                          ReturnLength,
                                          TokenInformation,
                                          TokenInformationLength,
                                          ReturnLength,
@@ -1257,7 +1631,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
                 DPRINT("NtQueryInformationToken(TokenUser)\n");
                 RequiredLength = sizeof(TOKEN_USER) +
 
                 DPRINT("NtQueryInformationToken(TokenUser)\n");
                 RequiredLength = sizeof(TOKEN_USER) +
-                RtlLengthSid(Token->UserAndGroups[0].Sid);
+                    RtlLengthSid(Token->UserAndGroups[0].Sid);
 
                 _SEH2_TRY
                 {
 
                 _SEH2_TRY
                 {
@@ -1268,7 +1642,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                                                               RequiredLength - sizeof(TOKEN_USER),
                                                               &tu->User,
                                                               (PSID)(tu + 1),
                                                               RequiredLength - sizeof(TOKEN_USER),
                                                               &tu->User,
                                                               (PSID)(tu + 1),
-                                                              &Unused.Ptr,
+                                                              &Unused.PSid,
                                                               &Unused.Ulong);
                     }
                     else
                                                               &Unused.Ulong);
                     }
                     else
@@ -1296,24 +1670,24 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
                 DPRINT("NtQueryInformationToken(TokenGroups)\n");
                 RequiredLength = sizeof(tg->GroupCount) +
 
                 DPRINT("NtQueryInformationToken(TokenGroups)\n");
                 RequiredLength = sizeof(tg->GroupCount) +
-                RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
+                    RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
 
                 _SEH2_TRY
                 {
                     if (TokenInformationLength >= RequiredLength)
                     {
                         ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
 
                 _SEH2_TRY
                 {
                     if (TokenInformationLength >= RequiredLength)
                     {
                         ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
-                        ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES));
-                        PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) +
-                                                                        ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)));
+                            ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES));
+                        PSID Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)tg + sizeof(tg->GroupCount) +
+                                                         ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)));
 
                         tg->GroupCount = Token->UserAndGroupCount - 1;
                         Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
                                                               &Token->UserAndGroups[1],
                                                               SidLen,
                                                               &tg->Groups[0],
 
                         tg->GroupCount = Token->UserAndGroupCount - 1;
                         Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
                                                               &Token->UserAndGroups[1],
                                                               SidLen,
                                                               &tg->Groups[0],
-                                                              (PSID)Sid,
-                                                              &Unused.Ptr,
+                                                              Sid,
+                                                              &Unused.PSid,
                                                               &Unused.Ulong);
                     }
                     else
                                                               &Unused.Ulong);
                     }
                     else
@@ -1341,7 +1715,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
                 DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
                 RequiredLength = sizeof(tp->PrivilegeCount) +
 
                 DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
                 RequiredLength = sizeof(tp->PrivilegeCount) +
-                (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+                    (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
 
                 _SEH2_TRY
                 {
 
                 _SEH2_TRY
                 {
@@ -1373,8 +1747,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
             case TokenOwner:
             {
 
             case TokenOwner:
             {
-                ULONG SidLen;
                 PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
                 PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
+                ULONG SidLen;
 
                 DPRINT("NtQueryInformationToken(TokenOwner)\n");
                 SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
 
                 DPRINT("NtQueryInformationToken(TokenOwner)\n");
                 SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
@@ -1410,8 +1784,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
             case TokenPrimaryGroup:
             {
 
             case TokenPrimaryGroup:
             {
-                ULONG SidLen;
                 PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
                 PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
+                ULONG SidLen;
 
                 DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n");
                 SidLen = RtlLengthSid(Token->PrimaryGroup);
 
                 DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n");
                 SidLen = RtlLengthSid(Token->PrimaryGroup);
@@ -1453,9 +1827,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                 RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
 
                 if (Token->DefaultDacl != NULL)
                 RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
 
                 if (Token->DefaultDacl != NULL)
-                {
                     RequiredLength += Token->DefaultDacl->AclSize;
                     RequiredLength += Token->DefaultDacl->AclSize;
-                }
 
                 _SEH2_TRY
                 {
 
                 _SEH2_TRY
                 {
@@ -1688,17 +2060,17 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     if (TokenInformationLength >= RequiredLength)
                     {
                         ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
                     if (TokenInformationLength >= RequiredLength)
                     {
                         ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
-                        (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES));
-                        PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) +
-                                                                        (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)));
+                            (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES));
+                        PSID Sid = (PSID)((ULONG_PTR)tg + sizeof(tg->GroupCount) +
+                                          (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)));
 
                         tg->GroupCount = Token->RestrictedSidCount;
                         Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount,
                                                               Token->RestrictedSids,
                                                               SidLen,
                                                               &tg->Groups[0],
 
                         tg->GroupCount = Token->RestrictedSidCount;
                         Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount,
                                                               Token->RestrictedSids,
                                                               SidLen,
                                                               &tg->Groups[0],
-                                                              (PSID)Sid,
-                                                              &Unused.Ptr,
+                                                              Sid,
+                                                              &Unused.PSid,
                                                               &Unused.Ulong);
                     }
                     else
                                                               &Unused.Ulong);
                     }
                     else
@@ -1731,14 +2103,12 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
                 DPRINT("NtQueryInformationToken(TokenSessionId)\n");
 
 
                 DPRINT("NtQueryInformationToken(TokenSessionId)\n");
 
-                Status = SeQuerySessionIdToken(Token,
-                                               &SessionId);
-
+                Status = SeQuerySessionIdToken(Token, &SessionId);
                 if (NT_SUCCESS(Status))
                 {
                     _SEH2_TRY
                     {
                 if (NT_SUCCESS(Status))
                 {
                     _SEH2_TRY
                     {
-                        /* buffer size was already verified, no need to check here again */
+                        /* Buffer size was already verified, no need to check here again */
                         *(PULONG)TokenInformation = SessionId;
 
                         if (ReturnLength != NULL)
                         *(PULONG)TokenInformation = SessionId;
 
                         if (ReturnLength != NULL)
@@ -1792,7 +2162,7 @@ NtSetInformationToken(IN HANDLE TokenHandle,
 
     Status = DefaultSetInfoBufferCheck(TokenInformationClass,
                                        SeTokenInformationClass,
 
     Status = DefaultSetInfoBufferCheck(TokenInformationClass,
                                        SeTokenInformationClass,
-                                       sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]),
+                                       RTL_NUMBER_OF(SeTokenInformationClass),
                                        TokenInformation,
                                        TokenInformationLength,
                                        PreviousMode);
                                        TokenInformation,
                                        TokenInformationLength,
                                        PreviousMode);
@@ -2179,14 +2549,16 @@ Cleanup:
  * @implemented
  *
  * NOTE: Some sources claim 4th param is ImpersonationLevel, but on W2K
  * @implemented
  *
  * NOTE: Some sources claim 4th param is ImpersonationLevel, but on W2K
- * this is certainly NOT true, thou i can't say for sure that EffectiveOnly
+ * this is certainly NOT true, although I can't say for sure that EffectiveOnly
  * is correct either. -Gunnar
  * This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI
  * is correct either. -Gunnar
  * This is true. EffectiveOnly overrides SQOS.EffectiveOnly. - IAI
+ * NOTE for readers: http://hex.pp.ua/nt/NtDuplicateToken.php is therefore
+ * wrong in that regard.
  */
 NTSTATUS NTAPI
 NtDuplicateToken(IN HANDLE ExistingTokenHandle,
                  IN ACCESS_MASK DesiredAccess,
  */
 NTSTATUS NTAPI
 NtDuplicateToken(IN HANDLE ExistingTokenHandle,
                  IN ACCESS_MASK DesiredAccess,
-                 IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+                 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
                  IN BOOLEAN EffectiveOnly,
                  IN TOKEN_TYPE TokenType,
                  OUT PHANDLE NewTokenHandle)
                  IN BOOLEAN EffectiveOnly,
                  IN TOKEN_TYPE TokenType,
                  OUT PHANDLE NewTokenHandle)
@@ -2330,7 +2702,7 @@ NtAdjustGroupsToken(IN HANDLE TokenHandle,
                     OUT PULONG ReturnLength)
 {
     UNIMPLEMENTED;
                     OUT PULONG ReturnLength)
 {
     UNIMPLEMENTED;
-    return(STATUS_NOT_IMPLEMENTED);
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 
 }
 
 
index 5b593f2..c563aef 100644 (file)
@@ -1279,13 +1279,13 @@ NTSYSAPI
 NTSTATUS
 NTAPI
 RtlCopySidAndAttributesArray(
 NTSTATUS
 NTAPI
 RtlCopySidAndAttributesArray(
-    ULONG Count,
-    PSID_AND_ATTRIBUTES Src,
-    ULONG SidAreaSize,
-    PSID_AND_ATTRIBUTES Dest,
-    PVOID SidArea,
-    PVOID* RemainingSidArea,
-    PULONG RemainingSidAreaSize
+    _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
 );
 
 _IRQL_requires_max_(APC_LEVEL)
 );
 
 _IRQL_requires_max_(APC_LEVEL)
index e57a6b1..093b96f 100644 (file)
@@ -250,8 +250,8 @@ RtlCopySidAndAttributesArray(IN ULONG Count,
                              IN PSID_AND_ATTRIBUTES Src,
                              IN ULONG SidAreaSize,
                              IN PSID_AND_ATTRIBUTES Dest,
                              IN PSID_AND_ATTRIBUTES Src,
                              IN ULONG SidAreaSize,
                              IN PSID_AND_ATTRIBUTES Dest,
-                             IN PVOID SidArea,
-                             OUT PVOID* RemainingSidArea,
+                             IN PSID SidArea,
+                             OUT PSID* RemainingSidArea,
                              OUT PULONG RemainingSidAreaSize)
 {
     ULONG SidLength, i;
                              OUT PULONG RemainingSidAreaSize)
 {
     ULONG SidLength, i;
@@ -273,7 +273,7 @@ RtlCopySidAndAttributesArray(IN ULONG Count,
         RtlCopySid(SidLength, SidArea, Src[i].Sid);
 
         /* Push the buffer area where the SID will reset */
         RtlCopySid(SidLength, SidArea, Src[i].Sid);
 
         /* Push the buffer area where the SID will reset */
-        SidArea = (PVOID)((ULONG_PTR)SidArea + SidLength);
+        SidArea = (PSID)((ULONG_PTR)SidArea + SidLength);
     }
 
     /* Return how much space is left, and where the buffer is at now */
     }
 
     /* Return how much space is left, and where the buffer is at now */
index 5574e89..74cb68f 100644 (file)
@@ -132,8 +132,6 @@ const KMT_TEST TestList[] =
     { "-ObTypeNoClean",                     Test_ObTypeNoClean },
     { "ObTypes",                            Test_ObTypes },
     { "PsNotify",                           Test_PsNotify },
     { "-ObTypeNoClean",                     Test_ObTypeNoClean },
     { "ObTypes",                            Test_ObTypes },
     { "PsNotify",                           Test_PsNotify },
-    { "SeInheritance",                      Test_SeInheritance },
-    { "-SeQueryInfoToken",                  Test_SeQueryInfoToken },
     { "RtlAvlTreeKM",                       Test_RtlAvlTree },
     { "RtlExceptionKM",                     Test_RtlException },
     { "RtlIntSafeKM",                       Test_RtlIntSafe },
     { "RtlAvlTreeKM",                       Test_RtlAvlTree },
     { "RtlExceptionKM",                     Test_RtlException },
     { "RtlIntSafeKM",                       Test_RtlIntSafe },
@@ -142,6 +140,8 @@ const KMT_TEST TestList[] =
     { "RtlRegistryKM",                      Test_RtlRegistry },
     { "RtlSplayTreeKM",                     Test_RtlSplayTree },
     { "RtlUnicodeStringKM",                 Test_RtlUnicodeString },
     { "RtlRegistryKM",                      Test_RtlRegistry },
     { "RtlSplayTreeKM",                     Test_RtlSplayTree },
     { "RtlUnicodeStringKM",                 Test_RtlUnicodeString },
+    { "SeInheritance",                      Test_SeInheritance },
+    { "SeQueryInfoToken",                   Test_SeQueryInfoToken },
     { "ZwAllocateVirtualMemory",            Test_ZwAllocateVirtualMemory },
     { "ZwCreateSection",                    Test_ZwCreateSection },
     { "ZwMapViewOfSection",                 Test_ZwMapViewOfSection },
     { "ZwAllocateVirtualMemory",            Test_ZwAllocateVirtualMemory },
     { "ZwCreateSection",                    Test_ZwCreateSection },
     { "ZwMapViewOfSection",                 Test_ZwMapViewOfSection },
index f9ba2a7..6e4f3b1 100644 (file)
@@ -44,10 +44,10 @@ void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
     if (Token == NULL) return;
 
     Status = SeQueryInformationToken(Token, TokenOwner, &Buffer);
     if (Token == NULL) return;
 
     Status = SeQueryInformationToken(Token, TokenOwner, &Buffer);
-    ok((Status == STATUS_SUCCESS), "SQIT with TokenOwner arg fails with status 0x%X\n", Status);
+    ok((Status == STATUS_SUCCESS), "SQIT with TokenOwner arg fails with status 0x%08X\n", Status);
     if (Status == STATUS_SUCCESS)
     {
     if (Status == STATUS_SUCCESS)
     {
-        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenOwner arg. But Buffer = NULL\n");
+        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenOwner arg. But Buffer == NULL\n");
 
         if (Buffer)
         {
 
         if (Buffer)
         {
@@ -62,10 +62,10 @@ void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
     
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenDefaultDacl, &Buffer);
     
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenDefaultDacl, &Buffer);
-    ok(Status == STATUS_SUCCESS, "SQIT with TokenDefaultDacl fails with status 0x%X\n", Status);
+    ok(Status == STATUS_SUCCESS, "SQIT with TokenDefaultDacl fails with status 0x%08X\n", Status);
     if (Status == STATUS_SUCCESS)
     {
     if (Status == STATUS_SUCCESS)
     {
-        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenDefaultDacl arg. But Buffer = NULL\n");
+        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenDefaultDacl arg. But Buffer == NULL\n");
         if (Buffer)
         {
             TDefDacl = (PTOKEN_DEFAULT_DACL)Buffer;
         if (Buffer)
         {
             TDefDacl = (PTOKEN_DEFAULT_DACL)Buffer;
@@ -79,10 +79,10 @@ void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
 
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenGroups, &Buffer);
 
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenGroups, &Buffer);
-    ok(Status == STATUS_SUCCESS, "SQIT with TokenGroups fails with status 0x%X\n", Status);
+    ok(Status == STATUS_SUCCESS, "SQIT with TokenGroups fails with status 0x%08X\n", Status);
     if (Status == STATUS_SUCCESS)
     {
     if (Status == STATUS_SUCCESS)
     {
-        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenGroups arg. But Buffer = NULL\n");
+        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenGroups arg. But Buffer == NULL\n");
         if (Buffer)
         {
             TGroups = (PTOKEN_GROUPS)Buffer;
         if (Buffer)
         {
             TGroups = (PTOKEN_GROUPS)Buffer;
@@ -107,58 +107,88 @@ void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
     // Call SQIT with TokenImpersonationLevel argument
     //
     // What's up? Why SQIT fails with right arg?
     // Call SQIT with TokenImpersonationLevel argument
     //
     // What's up? Why SQIT fails with right arg?
+    // Because your token has Token->TokenType != TokenImpersonation. -hbelusca
 
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
 
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
-    ok(Status == STATUS_SUCCESS, "SQIT with TokenImpersonationLevel fails with status 0x%X\n", Status);
+    ok(Status == STATUS_SUCCESS, "SQIT with TokenImpersonationLevel fails with status 0x%08X\n", Status);
+    if (Buffer) ExFreePool(Buffer);
 
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
 
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
-    ok(Status == STATUS_SUCCESS, "and again: SQIT with TokenImpersonationLevel fails with status 0x%X\n", Status);
+    ok(Status == STATUS_SUCCESS, "and again: SQIT with TokenImpersonationLevel fails with status 0x%08X\n", Status);
     if (Status == STATUS_SUCCESS)
     {
     if (Status == STATUS_SUCCESS)
     {
-        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenImpersonationLevel arg. But Buffer = NULL\n");
+        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenImpersonationLevel arg. But Buffer == NULL\n");
     } else {
     } else {
-        ok(Buffer == NULL, "Wrong. SQIT call is't success. But Buffer != NULL\n");
+        ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
     }
     }
+    if (Buffer) ExFreePool(Buffer);
+
+    //----------------------------------------------------------------//
+
+    // Call SQIT with the 4 classes (TokenOrigin, TokenGroupsAndPrivileges,
+    // TokenRestrictedSids and TokenSandBoxInert) are not supported by
+    // SeQueryInformationToken (only NtQueryInformationToken supports them).
+    //
+
+    Buffer = NULL;
+    Status = SeQueryInformationToken(Token, TokenOrigin, &Buffer);
+    ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenOrigin failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
+    ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
+
+    Buffer = NULL;
+    Status = SeQueryInformationToken(Token, TokenGroupsAndPrivileges, &Buffer);
+    ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenGroupsAndPrivileges failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
+    ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
+
+    Buffer = NULL;
+    Status = SeQueryInformationToken(Token, TokenRestrictedSids, &Buffer);
+    ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenRestrictedSids failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
+    ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
+
+    Buffer = NULL;
+    Status = SeQueryInformationToken(Token, TokenSandBoxInert, &Buffer);
+    ok(Status == STATUS_INVALID_INFO_CLASS, "SQIT with TokenSandBoxInert failed with Status 0x%08X; expected STATUS_INVALID_INFO_CLASS\n", Status);
+    ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
 
     //----------------------------------------------------------------//
 
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenStatistics, &Buffer);
 
     //----------------------------------------------------------------//
 
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenStatistics, &Buffer);
-    ok(Status == STATUS_SUCCESS, "SQIT with TokenStatistics fails with status 0x%X\n", Status);
+    ok(Status == STATUS_SUCCESS, "SQIT with TokenStatistics fails with status 0x%08X\n", Status);
     if (Status == STATUS_SUCCESS)
     {
     if (Status == STATUS_SUCCESS)
     {
-        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenStatistics arg. But Buffer = NULL\n");
+        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenStatistics arg. But Buffer == NULL\n");
         if (Buffer)
         {
             TStats = (PTOKEN_STATISTICS)Buffer;
         if (Buffer)
         {
             TStats = (PTOKEN_STATISTICS)Buffer;
-            // just put 0 into 1st arg or use trace to print TokenStatistics f
+            // just put 0 into 1st arg or use trace to print TokenStatistics
             ok(1, "print statistics:\n\tTokenID = %u_%d\n\tSecurityImperLevel = %d\n\tPrivCount = %d\n\tGroupCount = %d\n\n", TStats->TokenId.LowPart, 
                 TStats->TokenId.HighPart, 
                 TStats->ImpersonationLevel,
                 TStats->PrivilegeCount,
                 TStats->GroupCount
                 );
             ok(1, "print statistics:\n\tTokenID = %u_%d\n\tSecurityImperLevel = %d\n\tPrivCount = %d\n\tGroupCount = %d\n\n", TStats->TokenId.LowPart, 
                 TStats->TokenId.HighPart, 
                 TStats->ImpersonationLevel,
                 TStats->PrivilegeCount,
                 TStats->GroupCount
                 );
-            ExFreePool(TStats);
+            ExFreePool(Buffer);
         }
     } else {
         }
     } else {
-        ok(Buffer == NULL, "Wrong. SQIT call is't success. But Buffer != NULL\n");
+        ok(Buffer == NULL, "Wrong. SQIT call failed. But Buffer != NULL\n");
     }
 
     //----------------------------------------------------------------//
 
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenType, &Buffer);
     }
 
     //----------------------------------------------------------------//
 
     Buffer = NULL;
     Status = SeQueryInformationToken(Token, TokenType, &Buffer);
-    ok(Status == STATUS_SUCCESS, "SQIT with TokenType fails with status 0x%X\n", Status);
+    ok(Status == STATUS_SUCCESS, "SQIT with TokenType fails with status 0x%08X\n", Status);
     if (Status == STATUS_SUCCESS)
     {
     if (Status == STATUS_SUCCESS)
     {
-        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenType arg. But Buffer = NULL\n");
+        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenType arg. But Buffer == NULL\n");
         if (Buffer)
         {
             TType = (PTOKEN_TYPE)Buffer;
             ok((*TType == TokenPrimary || *TType == TokenImpersonation), "TokenType in not a primary nor impersonation. FAILED\n");
         if (Buffer)
         {
             TType = (PTOKEN_TYPE)Buffer;
             ok((*TType == TokenPrimary || *TType == TokenImpersonation), "TokenType in not a primary nor impersonation. FAILED\n");
-            ExFreePool(TType);
+            ExFreePool(Buffer);
         }
     }
 
         }
     }
 
@@ -169,12 +199,12 @@ void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
     ok(Status == STATUS_SUCCESS, "SQIT with TokenUser fails\n");
     if (Status == STATUS_SUCCESS)
     {
     ok(Status == STATUS_SUCCESS, "SQIT with TokenUser fails\n");
     if (Status == STATUS_SUCCESS)
     {
-        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenUser arg. But Buffer = NULL\n");
+        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenUser arg. But Buffer == NULL\n");
         if (Buffer)
         {
             TUser = (PTOKEN_USER)Buffer;
             ok(RtlValidSid(TUser->User.Sid), "TokenUser has an invalid Sid\n");
         if (Buffer)
         {
             TUser = (PTOKEN_USER)Buffer;
             ok(RtlValidSid(TUser->User.Sid), "TokenUser has an invalid Sid\n");
-            ExFreePool(TUser);
+            ExFreePool(Buffer);
         }
     }
 
         }
     }
 
@@ -237,7 +267,6 @@ START_TEST(SeQueryInfoToken)
 
     SeCaptureSubjectContext(&AccessState->SubjectSecurityContext);
     SeLockSubjectContext(&AccessState->SubjectSecurityContext);
 
     SeCaptureSubjectContext(&AccessState->SubjectSecurityContext);
     SeLockSubjectContext(&AccessState->SubjectSecurityContext);
-
     Token = SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext);
 
     // Testing SQIT with AccessState Token
     Token = SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext);
 
     // Testing SQIT with AccessState Token
@@ -295,8 +324,7 @@ START_TEST(SeQueryInfoToken)
     //      Testing SeFreePrivileges                                  //
     //----------------------------------------------------------------//
 
     //      Testing SeFreePrivileges                                  //
     //----------------------------------------------------------------//
 
-    Privileges = ExAllocatePool(PagedPool, AuxData->PrivilegeSet->PrivilegeCount*sizeof(PRIVILEGE_SET));
-
+    Privileges = NULL;
     Checker = SeAccessCheck(
         AccessState->SecurityDescriptor,
         &AccessState->SubjectSecurityContext,
     Checker = SeAccessCheck(
         AccessState->SecurityDescriptor,
         &AccessState->SubjectSecurityContext,
@@ -311,6 +339,11 @@ START_TEST(SeQueryInfoToken)
         );
     ok(Checker, "Checker is NULL\n");
     ok((Privileges != NULL), "Privileges is NULL\n");
         );
     ok(Checker, "Checker is NULL\n");
     ok((Privileges != NULL), "Privileges is NULL\n");
+    if (Privileges)
+    {
+        trace("AuxData->PrivilegeSet->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
+              AuxData->PrivilegeSet->PrivilegeCount, Privileges->PrivilegeCount);
+    }
     if (Privileges) SeFreePrivileges(Privileges);
 
 
     if (Privileges) SeFreePrivileges(Privileges);
 
 
@@ -326,7 +359,7 @@ START_TEST(SeQueryInfoToken)
     Status = SeQueryInformationToken(Token, TokenPrivileges, &Buffer);
     if (Status == STATUS_SUCCESS)
     {
     Status = SeQueryInformationToken(Token, TokenPrivileges, &Buffer);
     if (Status == STATUS_SUCCESS)
     {
-        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenPrivileges arg. But Buffer = NULL\n");
+        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenPrivileges arg. But Buffer == NULL\n");
         if (Buffer)
         {
             TPrivileges = (PTOKEN_PRIVILEGES)(Buffer);
         if (Buffer)
         {
             TPrivileges = (PTOKEN_PRIVILEGES)(Buffer);
@@ -351,8 +384,7 @@ START_TEST(SeQueryInfoToken)
 
     // Call SeFreePrivileges again
 
 
     // Call SeFreePrivileges again
 
-    Privileges = ExAllocatePool(PagedPool, 20*sizeof(PRIVILEGE_SET));
-
+    Privileges = NULL;
     Checker = SeAccessCheck(
         AccessState->SecurityDescriptor,
         &AccessState->SubjectSecurityContext,
     Checker = SeAccessCheck(
         AccessState->SecurityDescriptor,
         &AccessState->SubjectSecurityContext,
@@ -367,6 +399,11 @@ START_TEST(SeQueryInfoToken)
         );
     ok(Checker, "Checker is NULL\n");
     ok((Privileges != NULL), "Privileges is NULL\n");
         );
     ok(Checker, "Checker is NULL\n");
     ok((Privileges != NULL), "Privileges is NULL\n");
+    if (Privileges)
+    {
+        trace("AuxData->PrivilegeSet->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
+              AuxData->PrivilegeSet->PrivilegeCount, Privileges->PrivilegeCount);
+    }
     if (Privileges) SeFreePrivileges(Privileges);
 
     //----------------------------------------------------------------//
     if (Privileges) SeFreePrivileges(Privileges);
 
     //----------------------------------------------------------------//