convert DefaultSetInfoBufferCheck and DefaultQueryInfoBufferCheck to inlined functions
[reactos.git] / reactos / ntoskrnl / se / token.c
index ab4f269..009fa98 100644 (file)
@@ -4,7 +4,7 @@
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/se/token.c
  * PURPOSE:         Security manager
- * 
+ *
  * PROGRAMMERS:     David Welch <welch@cwcom.net>
  */
 
@@ -68,44 +68,62 @@ static const INFORMATION_CLASS_INFO SeTokenInformationClass[] = {
 
 /* FUNCTIONS *****************************************************************/
 
-VOID SepFreeProxyData(PVOID ProxyData)
+VOID
+NTAPI
+SepFreeProxyData(PVOID ProxyData)
 {
    UNIMPLEMENTED;
 }
 
-NTSTATUS SepCopyProxyData(PVOID* Dest, PVOID Src)
+NTSTATUS
+NTAPI
+SepCopyProxyData(PVOID* Dest, PVOID Src)
 {
    UNIMPLEMENTED;
    return(STATUS_NOT_IMPLEMENTED);
 }
 
-NTSTATUS SeExchangePrimaryToken(PEPROCESS Process,
-                               PACCESS_TOKEN NewTokenP,
-                               PACCESS_TOKEN* OldTokenP)
+NTSTATUS
+NTAPI
+SeExchangePrimaryToken(PEPROCESS Process,
+                       PACCESS_TOKEN NewTokenP,
+                       PACCESS_TOKEN* OldTokenP)
 {
-   PTOKEN OldToken;
-   PTOKEN NewToken = (PTOKEN)NewTokenP;
-   
-   PAGED_CODE();
-   
-   if (NewToken->TokenType != TokenPrimary)
-     {
-       return(STATUS_UNSUCCESSFUL);
-     }
-   if (NewToken->TokenInUse != 0)
-     {
-       return(STATUS_UNSUCCESSFUL);
-     }
-   OldToken = Process->Token;
-   Process->Token = NewToken;
-   NewToken->TokenInUse = 1;
-   ObReferenceObjectByPointer(NewToken,
-                             TOKEN_ALL_ACCESS,
-                             SepTokenObjectType,
-                             KernelMode);
-   OldToken->TokenInUse = 0;
-   *OldTokenP = (PACCESS_TOKEN)OldToken;
-   return(STATUS_SUCCESS);
+    PTOKEN OldToken;
+    PTOKEN NewToken = (PTOKEN)NewTokenP;
+
+    PAGED_CODE();
+
+    if (NewToken->TokenType != TokenPrimary) return(STATUS_BAD_TOKEN_TYPE);
+    if (NewToken->TokenInUse) return(STATUS_TOKEN_ALREADY_IN_USE);
+
+    /* Mark new token in use */
+    NewToken->TokenInUse = 1;
+
+    /* Reference the New Token */
+    ObReferenceObject(NewToken);
+
+    /* Replace the old with the new */
+    OldToken = ObFastReplaceObject(&Process->Token, NewToken);
+
+    /* Mark the Old Token as free */
+    OldToken->TokenInUse = 0;
+
+    *OldTokenP = (PACCESS_TOKEN)OldToken;
+    return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+SeDeassignPrimaryToken(PEPROCESS Process)
+{
+    PTOKEN OldToken;
+
+    /* Remove the Token */
+    OldToken = ObFastReplaceObject(&Process->Token, NULL);
+
+    /* Mark the Old Token as free */
+    OldToken->TokenInUse = 0;
 }
 
 static ULONG
@@ -114,7 +132,7 @@ RtlLengthSidAndAttributes(ULONG Count,
 {
   ULONG i;
   ULONG uLength;
-  
+
   PAGED_CODE();
 
   uLength = Count * sizeof(SID_AND_ATTRIBUTES);
@@ -126,6 +144,7 @@ RtlLengthSidAndAttributes(ULONG Count,
 
 
 NTSTATUS
+NTAPI
 SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token,
                                   PSID PrimaryGroup,
                                   PSID DefaultOwner)
@@ -183,7 +202,7 @@ SepDuplicateToken(PTOKEN Token,
   PVOID EndMem;
   PTOKEN AccessToken;
   NTSTATUS Status;
-  
+
   PAGED_CODE();
 
   Status = ObCreateObject(PreviousMode,
@@ -235,7 +254,7 @@ SepDuplicateToken(PTOKEN Token,
   for (i = 0; i < Token->UserAndGroupCount; i++)
     uLength += RtlLengthSid(Token->UserAndGroups[i].Sid);
 
-  AccessToken->UserAndGroups = 
+  AccessToken->UserAndGroups =
     (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
                                               uLength,
                                               TAG('T', 'O', 'K', 'u'));
@@ -271,7 +290,7 @@ SepDuplicateToken(PTOKEN Token,
        {
          RtlCopyLuid(&AccessToken->Privileges[i].Luid,
            &Token->Privileges[i].Luid);
-         AccessToken->Privileges[i].Attributes = 
+         AccessToken->Privileges[i].Attributes =
            Token->Privileges[i].Attributes;
        }
 
@@ -324,9 +343,9 @@ SeCopyClientToken(PACCESS_TOKEN Token,
 {
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
-   
+
    PAGED_CODE();
-     
+
    InitializeObjectAttributes(&ObjectAttributes,
                              NULL,
                              0,
@@ -339,7 +358,7 @@ SeCopyClientToken(PACCESS_TOKEN Token,
                                Level,
                                PreviousMode,
                                (PTOKEN*)NewToken);
-   
+
    return(Status);
 }
 
@@ -359,9 +378,9 @@ SeCreateClientSecurity(IN struct _ETHREAD *Thread,
    PACCESS_TOKEN Token;
    ULONG g;
    PACCESS_TOKEN NewToken;
-   
+
    PAGED_CODE();
-   
+
    Token = PsReferenceEffectiveToken(Thread,
                                     &TokenType,
                                     &b,
@@ -400,7 +419,7 @@ SeCreateClientSecurity(IN struct _ETHREAD *Thread,
             ClientContext->DirectAccessEffectiveOnly = FALSE;
          }
      }
-   
+
    if (Qos->ContextTrackingMode == 0)
      {
        ClientContext->DirectlyAccessClientToken = FALSE;
@@ -506,9 +525,9 @@ SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext,
                    IN PETHREAD ServerThread OPTIONAL)
 {
   UCHAR b;
-  
+
   PAGED_CODE();
-  
+
   if (ClientContext->DirectlyAccessClientToken == FALSE)
     {
       b = ClientContext->SecurityQos.EffectiveOnly;
@@ -545,34 +564,29 @@ SepDeleteToken(PVOID ObjectBody)
 }
 
 
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
 SepInitializeTokenImplementation(VOID)
 {
-  ExInitializeResource(&SepTokenLock);
-
-  SepTokenObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-
-  SepTokenObjectType->Tag = TAG('T', 'O', 'K', 'T');
-  SepTokenObjectType->PeakObjects = 0;
-  SepTokenObjectType->PeakHandles = 0;
-  SepTokenObjectType->TotalObjects = 0;
-  SepTokenObjectType->TotalHandles = 0;
-  SepTokenObjectType->PagedPoolCharge = 0;
-  SepTokenObjectType->NonpagedPoolCharge = sizeof(TOKEN);
-  SepTokenObjectType->Mapping = &SepTokenMapping;
-  SepTokenObjectType->Dump = NULL;
-  SepTokenObjectType->Open = NULL;
-  SepTokenObjectType->Close = NULL;
-  SepTokenObjectType->Delete = SepDeleteToken;
-  SepTokenObjectType->Parse = NULL;
-  SepTokenObjectType->Security = NULL;
-  SepTokenObjectType->QueryName = NULL;
-  SepTokenObjectType->OkayToClose = NULL;
-  SepTokenObjectType->Create = NULL;
-  SepTokenObjectType->DuplicationNotify = NULL;
-
-  RtlInitUnicodeString(&SepTokenObjectType->TypeName, L"Token");
-  ObpCreateTypeObject (SepTokenObjectType);
+    UNICODE_STRING Name;
+    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
+    
+    ExInitializeResource(&SepTokenLock);
+    
+    DPRINT("Creating Token Object Type\n");
+  
+    /*  Initialize the Token type  */
+    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
+    RtlInitUnicodeString(&Name, L"Token");
+    ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+    ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(TOKEN);
+    ObjectTypeInitializer.GenericMapping = SepTokenMapping;
+    ObjectTypeInitializer.PoolType = PagedPool;
+    ObjectTypeInitializer.ValidAccessMask = TOKEN_ALL_ACCESS;
+    ObjectTypeInitializer.UseDefaultObject = TRUE;
+    ObjectTypeInitializer.DeleteProcedure = SepDeleteToken;
+    ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &SepTokenObjectType);
 }
 
 
@@ -595,19 +609,19 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
   ULONG RequiredLength;
   KPROCESSOR_MODE PreviousMode;
   NTSTATUS Status = STATUS_SUCCESS;
-  
+
   PAGED_CODE();
-  
+
   PreviousMode = ExGetPreviousMode();
-  
+
   /* Check buffers and class validity */
-  DefaultQueryInfoBufferCheck(TokenInformationClass,
-                              SeTokenInformationClass,
-                              TokenInformation,
-                              TokenInformationLength,
-                              ReturnLength,
-                              PreviousMode,
-                              &Status);
+  Status = DefaultQueryInfoBufferCheck(TokenInformationClass,
+                                       SeTokenInformationClass,
+                                       sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]),
+                                       TokenInformation,
+                                       TokenInformationLength,
+                                       ReturnLength,
+                                       PreviousMode);
 
   if(!NT_SUCCESS(Status))
   {
@@ -628,7 +642,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
       case TokenUser:
       {
         PTOKEN_USER tu = (PTOKEN_USER)TokenInformation;
-        
+
         DPRINT("NtQueryInformationToken(TokenUser)\n");
         RequiredLength = sizeof(TOKEN_USER) +
                          RtlLengthSid(Token->UserAndGroups[0].Sid);
@@ -649,7 +663,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
           {
             Status = STATUS_BUFFER_TOO_SMALL;
           }
-          
+
           if(ReturnLength != NULL)
           {
             *ReturnLength = RequiredLength;
@@ -660,14 +674,14 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
           Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-        
+
         break;
       }
-       
+
       case TokenGroups:
       {
         PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
-        
+
         DPRINT("NtQueryInformationToken(TokenGroups)\n");
         RequiredLength = sizeof(tg->GroupCount) +
                          RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
@@ -705,14 +719,14 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
           Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-        
+
        break;
       }
-      
+
       case TokenPrivileges:
       {
         PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)TokenInformation;
-        
+
         DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
         RequiredLength = sizeof(tp->PrivilegeCount) +
                          (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
@@ -730,7 +744,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
           {
             Status = STATUS_BUFFER_TOO_SMALL;
           }
-          
+
           if(ReturnLength != NULL)
           {
             *ReturnLength = RequiredLength;
@@ -741,15 +755,15 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
           Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-        
+
         break;
       }
-      
+
       case TokenOwner:
       {
         ULONG SidLen;
         PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
-        
+
         DPRINT("NtQueryInformationToken(TokenOwner)\n");
         SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
         RequiredLength = sizeof(TOKEN_OWNER) + SidLen;
@@ -767,7 +781,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
           {
             Status = STATUS_BUFFER_TOO_SMALL;
           }
-          
+
           if(ReturnLength != NULL)
           {
             *ReturnLength = RequiredLength;
@@ -778,10 +792,10 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
           Status = _SEH_GetExceptionCode();
         }
         _SEH_END;
-        
+
         break;
       }
-      
+
       case TokenPrimaryGroup:
       {
         ULONG SidLen;
@@ -818,14 +832,14 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
         break;
       }
-      
+
       case TokenDefaultDacl:
       {
         PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
 
         DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
         RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
-        
+
         if(Token->DefaultDacl != NULL)
         {
           RequiredLength += Token->DefaultDacl->AclSize;
@@ -865,7 +879,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
         break;
       }
-      
+
       case TokenSource:
       {
         PTOKEN_SOURCE ts = (PTOKEN_SOURCE)TokenInformation;
@@ -897,7 +911,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
         break;
       }
-      
+
       case TokenType:
       {
         PTOKEN_TYPE tt = (PTOKEN_TYPE)TokenInformation;
@@ -929,7 +943,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
         break;
       }
-      
+
       case TokenImpersonationLevel:
       {
         PSECURITY_IMPERSONATION_LEVEL sil = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation;
@@ -961,7 +975,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
         break;
       }
-      
+
       case TokenStatistics:
       {
         PTOKEN_STATISTICS ts = (PTOKEN_STATISTICS)TokenInformation;
@@ -1002,7 +1016,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
 
         break;
       }
-      
+
       case TokenOrigin:
       {
         PTOKEN_ORIGIN to = (PTOKEN_ORIGIN)TokenInformation;
@@ -1042,9 +1056,49 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
        break;
 
       case TokenRestrictedSids:
-       DPRINT1("NtQueryInformationToken(TokenRestrictedSids) not implemented\n");
-       Status = STATUS_NOT_IMPLEMENTED;
+      {
+        PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
+
+        DPRINT("NtQueryInformationToken(TokenRestrictedSids)\n");
+        RequiredLength = sizeof(tg->GroupCount) +
+                         RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids);
+
+        _SEH_TRY
+        {
+          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)));
+
+            tg->GroupCount = Token->RestrictedSidCount;
+            Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount,
+                                                  Token->RestrictedSids,
+                                                  SidLen,
+                                                  &tg->Groups[0],
+                                                  (PSID)Sid,
+                                                  &Unused.Ptr,
+                                                  &Unused.Ulong);
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
+
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
        break;
+      }
 
       case TokenSandBoxInert:
        DPRINT1("NtQueryInformationToken(TokenSandboxInert) not implemented\n");
@@ -1056,7 +1110,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
         ULONG SessionId = 0;
 
         DPRINT("NtQueryInformationToken(TokenSessionId)\n");
-        
+
         Status = SeQuerySessionIdToken(Token,
                                        &SessionId);
 
@@ -1078,7 +1132,7 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
           }
           _SEH_END;
         }
-        
+
         break;
       }
 
@@ -1139,17 +1193,17 @@ NtSetInformationToken(IN HANDLE TokenHandle,
   KPROCESSOR_MODE PreviousMode;
   ULONG NeededAccess = TOKEN_ADJUST_DEFAULT;
   NTSTATUS Status = STATUS_SUCCESS;
-  
+
   PAGED_CODE();
-  
+
   PreviousMode = ExGetPreviousMode();
-  
-  DefaultSetInfoBufferCheck(TokenInformationClass,
-                            SeTokenInformationClass,
-                            TokenInformation,
-                            TokenInformationLength,
-                            PreviousMode,
-                            &Status);
+
+  Status = DefaultSetInfoBufferCheck(TokenInformationClass,
+                                     SeTokenInformationClass,
+                                     sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]),
+                                     TokenInformation,
+                                     TokenInformationLength,
+                                     PreviousMode);
 
   if(!NT_SUCCESS(Status))
   {
@@ -1157,7 +1211,7 @@ NtSetInformationToken(IN HANDLE TokenHandle,
     DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status);
     return Status;
   }
-  
+
   if(TokenInformationClass == TokenSessionId)
   {
     NeededAccess |= TOKEN_ADJUST_SESSIONID;
@@ -1179,7 +1233,7 @@ NtSetInformationToken(IN HANDLE TokenHandle,
         {
           PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
           PSID InputSid = NULL;
-          
+
           _SEH_TRY
           {
             InputSid = to->Owner;
@@ -1189,11 +1243,11 @@ NtSetInformationToken(IN HANDLE TokenHandle,
             Status = _SEH_GetExceptionCode();
           }
           _SEH_END;
-          
+
           if(NT_SUCCESS(Status))
           {
             PSID CapturedSid;
-            
+
             Status = SepCaptureSid(InputSid,
                                    PreviousMode,
                                    PagedPool,
@@ -1216,7 +1270,7 @@ NtSetInformationToken(IN HANDLE TokenHandle,
         }
         break;
       }
-      
+
       case TokenPrimaryGroup:
       {
         if(TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP))
@@ -1260,7 +1314,7 @@ NtSetInformationToken(IN HANDLE TokenHandle,
         }
         break;
       }
-      
+
       case TokenDefaultDacl:
       {
         if(TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL))
@@ -1297,7 +1351,7 @@ NtSetInformationToken(IN HANDLE TokenHandle,
                 {
                   ExFreePool(Token->DefaultDacl);
                 }
-                
+
                 /* set the new dacl */
                 Token->DefaultDacl = CapturedAcl;
               }
@@ -1319,7 +1373,7 @@ NtSetInformationToken(IN HANDLE TokenHandle,
         }
         break;
       }
-      
+
       case TokenSessionId:
       {
         ULONG SessionId = 0;
@@ -1386,18 +1440,16 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
   PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService;
   BOOLEAN QoSPresent;
   NTSTATUS Status = STATUS_SUCCESS;
-  
+
   PAGED_CODE();
 
   PreviousMode = KeGetPreviousMode();
-  
+
   if(PreviousMode != KernelMode)
   {
     _SEH_TRY
     {
-      ProbeForWrite(NewTokenHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
+      ProbeForWriteHandle(NewTokenHandle);
     }
     _SEH_HANDLE
     {
@@ -1410,7 +1462,7 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
       return Status;
     }
   }
-  
+
   Status = SepCaptureSecurityQualityOfService(ObjectAttributes,
                                               PreviousMode,
                                               PagedPool,
@@ -1422,7 +1474,7 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
     DPRINT1("NtDuplicateToken() failed to capture QoS! Status: 0x%x\n", Status);
     return Status;
   }
-  
+
   Status = ObReferenceObjectByHandle(ExistingTokenHandle,
                                     TOKEN_DUPLICATE,
                                     SepTokenObjectType,
@@ -1466,7 +1518,7 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
       }
     }
   }
-  
+
   /* free the captured structure */
   SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
                                      PreviousMode,
@@ -1505,17 +1557,17 @@ NtAdjustGroupsToken(IN HANDLE TokenHandle,
    ULONG a;
    ULONG b;
    ULONG c;
-   
+
    PAGED_CODE();
-   
+
    Status = ObReferenceObjectByHandle(TokenHandle,
                                      ?,
                                      SepTokenObjectType,
                                      UserMode,
                                      (PVOID*)&Token,
                                      NULL);
-   
-   
+
+
    SepAdjustGroups(Token,
                   0,
                   ResetToDefault,
@@ -1613,7 +1665,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
    ULONG c;
 #endif
   NTSTATUS Status;
-  
+
   PAGED_CODE();
 
   DPRINT ("NtAdjustPrivilegesToken() called\n");
@@ -1739,7 +1791,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
 
                      /* Update current privlege */
                      Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
-                     Token->Privileges[i].Attributes |= 
+                     Token->Privileges[i].Attributes |=
                        (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED);
                      DPRINT ("New attributes %lx\n",
                              Token->Privileges[i].Attributes);
@@ -1775,18 +1827,20 @@ SepCreateSystemProcessToken(VOID)
   NTSTATUS Status;
   ULONG uSize;
   ULONG i;
-  
-  PAGED_CODE();
-
-  ULONG uLocalSystemLength = RtlLengthSid(SeLocalSystemSid);
-  ULONG uWorldLength       = RtlLengthSid(SeWorldSid);
-  ULONG uAuthUserLength    = RtlLengthSid(SeAuthenticatedUserSid);
-  ULONG uAdminsLength      = RtlLengthSid(SeAliasAdminsSid);
-
+  ULONG uLocalSystemLength;
+  ULONG uWorldLength;
+  ULONG uAuthUserLength;
+  ULONG uAdminsLength;
   PTOKEN AccessToken;
-
   PVOID SidArea;
 
+  PAGED_CODE();
+
+  uLocalSystemLength = RtlLengthSid(SeLocalSystemSid);
+  uWorldLength       = RtlLengthSid(SeWorldSid);
+  uAuthUserLength    = RtlLengthSid(SeAuthenticatedUserSid);
+  uAdminsLength      = RtlLengthSid(SeAliasAdminsSid);
+
  /*
   * Initialize the token
   */
@@ -1803,6 +1857,12 @@ SepCreateSystemProcessToken(VOID)
     {
       return NULL;
     }
+  Status = ObInsertObject(AccessToken,
+                          NULL,
+                          TOKEN_ALL_ACCESS,
+                          0,
+                          NULL,
+                          NULL);
 
   Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId);
   if (!NT_SUCCESS(Status))
@@ -1841,8 +1901,8 @@ SepCreateSystemProcessToken(VOID)
   uSize += uAuthUserLength;
   uSize += uAdminsLength;
 
-  AccessToken->UserAndGroups = 
-    (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(NonPagedPool,
+  AccessToken->UserAndGroups =
+    (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
                                               uSize,
                                               TAG('T', 'O', 'K', 'u'));
   SidArea = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
@@ -1874,7 +1934,7 @@ SepCreateSystemProcessToken(VOID)
 
   uSize = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
   AccessToken->Privileges =
-       (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(NonPagedPool,
+       (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
                                                    uSize,
                                                    TAG('T', 'O', 'K', 'p'));
 
@@ -1887,55 +1947,55 @@ SepCreateSystemProcessToken(VOID)
 
   AccessToken->Privileges[i].Attributes = 0;
   AccessToken->Privileges[i++].Luid = SeTakeOwnershipPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
   AccessToken->Privileges[i++].Luid = SeCreatePagefilePrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
   AccessToken->Privileges[i++].Luid = SeLockMemoryPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = 0;
   AccessToken->Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = 0;
   AccessToken->Privileges[i++].Luid = SeIncreaseQuotaPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
   AccessToken->Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
   AccessToken->Privileges[i++].Luid = SeCreatePermanentPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
   AccessToken->Privileges[i++].Luid = SeDebugPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
   AccessToken->Privileges[i++].Luid = SeAuditPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = 0;
   AccessToken->Privileges[i++].Luid = SeSecurityPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = 0;
   AccessToken->Privileges[i++].Luid = SeSystemEnvironmentPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
   AccessToken->Privileges[i++].Luid = SeChangeNotifyPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = 0;
   AccessToken->Privileges[i++].Luid = SeBackupPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = 0;
   AccessToken->Privileges[i++].Luid = SeRestorePrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = 0;
   AccessToken->Privileges[i++].Luid = SeShutdownPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = 0;
   AccessToken->Privileges[i++].Luid = SeLoadDriverPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
   AccessToken->Privileges[i++].Luid = SeProfileSingleProcessPrivilege;
-  
+
   AccessToken->Privileges[i].Attributes = 0;
   AccessToken->Privileges[i++].Luid = SeSystemtimePrivilege;
 #if 0
@@ -1953,7 +2013,7 @@ SepCreateSystemProcessToken(VOID)
   uSize += sizeof(ACE) + uAdminsLength;
   uSize = (uSize & (~3)) + 8;
   AccessToken->DefaultDacl =
-    (PACL) ExAllocatePoolWithTag(NonPagedPool,
+    (PACL) ExAllocatePoolWithTag(PagedPool,
                                 uSize,
                                 TAG('T', 'O', 'K', 'd'));
   Status = RtlCreateAcl(AccessToken->DefaultDacl, uSize, ACL_REVISION);
@@ -1999,26 +2059,24 @@ NtCreateToken(OUT PHANDLE TokenHandle,
   PVOID EndMem;
   ULONG uLength;
   ULONG i;
+  ULONG nTokenPrivileges = 0;
+  LARGE_INTEGER LocalExpirationTime = {};
   KPROCESSOR_MODE PreviousMode;
   NTSTATUS Status = STATUS_SUCCESS;
-  
+
   PAGED_CODE();
-  
+
   PreviousMode = ExGetPreviousMode();
-  
+
   if(PreviousMode != KernelMode)
   {
     _SEH_TRY
     {
-      ProbeForWrite(TokenHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
+      ProbeForWriteHandle(TokenHandle);
       ProbeForRead(AuthenticationId,
                    sizeof(LUID),
                    sizeof(ULONG));
-      ProbeForRead(ExpirationTime,
-                   sizeof(LARGE_INTEGER),
-                   sizeof(ULONG));
+      LocalExpirationTime = ProbeForReadLargeInteger(ExpirationTime);
       ProbeForRead(TokenUser,
                    sizeof(TOKEN_USER),
                    sizeof(ULONG));
@@ -2040,18 +2098,24 @@ NtCreateToken(OUT PHANDLE TokenHandle,
       ProbeForRead(TokenSource,
                    sizeof(TOKEN_SOURCE),
                    sizeof(ULONG));
+      nTokenPrivileges = TokenPrivileges->PrivilegeCount;
     }
     _SEH_HANDLE
     {
       Status = _SEH_GetExceptionCode();
     }
     _SEH_END;
-    
+
     if(!NT_SUCCESS(Status))
     {
       return Status;
     }
   }
+  else
+  {
+    nTokenPrivileges = TokenPrivileges->PrivilegeCount;
+    LocalExpirationTime = *ExpirationTime;
+  }
 
   Status = ZwAllocateLocallyUniqueId(&TokenId);
   if (!NT_SUCCESS(Status))
@@ -2109,7 +2173,7 @@ NtCreateToken(OUT PHANDLE TokenHandle,
   for (i = 0; i < TokenGroups->GroupCount; i++)
     uLength += RtlLengthSid(TokenGroups->Groups[i].Sid);
 
-  AccessToken->UserAndGroups = 
+  AccessToken->UserAndGroups =
     (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
                                               uLength,
                                               TAG('T', 'O', 'K', 'u'));
@@ -2137,7 +2201,7 @@ NtCreateToken(OUT PHANDLE TokenHandle,
   if (NT_SUCCESS(Status))
     {
       Status = SepFindPrimaryGroupAndDefaultOwner(
-       AccessToken, 
+       AccessToken,
        TokenPrimaryGroup->PrimaryGroup,
        TokenOwner->Owner);
     }
@@ -2150,14 +2214,26 @@ NtCreateToken(OUT PHANDLE TokenHandle,
                                                    uLength,
                                                    TAG('T', 'O', 'K', 'p'));
 
-      for (i = 0; i < TokenPrivileges->PrivilegeCount; i++)
-       {
-         Status = MmCopyFromCaller(&AccessToken->Privileges[i],
-                                   &TokenPrivileges->Privileges[i],
-                                   sizeof(LUID_AND_ATTRIBUTES));
-         if (!NT_SUCCESS(Status))
-           break;
-       }
+      if (PreviousMode != KernelMode)
+        {
+          _SEH_TRY
+            {
+              RtlCopyMemory(AccessToken->Privileges,
+                            TokenPrivileges->Privileges,
+                            nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
+            }
+          _SEH_HANDLE
+            {
+              Status = _SEH_GetExceptionCode();
+            }
+          _SEH_END;
+        }
+      else
+        {
+          RtlCopyMemory(AccessToken->Privileges,
+                        TokenPrivileges->Privileges,
+                        nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
+        }
     }
 
   if (NT_SUCCESS(Status))
@@ -2209,7 +2285,7 @@ SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token,
                             OUT PLUID LogonId)
 {
   PAGED_CODE();
-  
+
   *LogonId = ((PTOKEN)Token)->AuthenticationId;
 
   return STATUS_SUCCESS;
@@ -2224,7 +2300,7 @@ STDCALL
 SeTokenImpersonationLevel(IN PACCESS_TOKEN Token)
 {
   PAGED_CODE();
-  
+
   return ((PTOKEN)Token)->ImpersonationLevel;
 }
 
@@ -2236,7 +2312,7 @@ TOKEN_TYPE STDCALL
 SeTokenType(IN PACCESS_TOKEN Token)
 {
   PAGED_CODE();
-  
+
   return ((PTOKEN)Token)->TokenType;
 }
 
@@ -2303,25 +2379,23 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
   PACL Dacl = NULL;
   KPROCESSOR_MODE PreviousMode;
   NTSTATUS Status = STATUS_SUCCESS;
-  
+
   PAGED_CODE();
-  
+
   PreviousMode = ExGetPreviousMode();
-  
+
   if(PreviousMode != KernelMode)
   {
     _SEH_TRY
     {
-      ProbeForWrite(TokenHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
+      ProbeForWriteHandle(TokenHandle);
     }
     _SEH_HANDLE
     {
       Status = _SEH_GetExceptionCode();
     }
     _SEH_END;
-    
+
     if(!NT_SUCCESS(Status))
     {
       return Status;
@@ -2380,7 +2454,7 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
             }
           return Status;
         }
-   
+
       PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);
       Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl);
       ObfDereferenceObject(PrimaryToken);
@@ -2394,7 +2468,7 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
             }
           return Status;
         }
-      
+
       RtlCreateSecurityDescriptor(&SecurityDescriptor,
                                   SECURITY_DESCRIPTOR_REVISION);
       RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl,