[FORMATTING]
[reactos.git] / reactos / ntoskrnl / se / token.c
index 86bfc44..30f7fc8 100644 (file)
 POBJECT_TYPE SepTokenObjectType = NULL;
 ERESOURCE SepTokenLock;
 
-static GENERIC_MAPPING SepTokenMapping = {TOKEN_READ,
+TOKEN_SOURCE SeSystemTokenSource = {"*SYSTEM*", {0}};
+LUID SeSystemAuthenticationId = SYSTEM_LUID;
+
+static GENERIC_MAPPING SepTokenMapping = {
+    TOKEN_READ,
     TOKEN_WRITE,
     TOKEN_EXECUTE,
-TOKEN_ALL_ACCESS};
+    TOKEN_ALL_ACCESS
+};
 
 static const INFORMATION_CLASS_INFO SeTokenInformationClass[] = {
-    
+
     /* Class 0 not used, blame M$! */
     ICI_SQ_SAME( 0, 0, 0),
-    
+
     /* TokenUser */
     ICI_SQ_SAME( sizeof(TOKEN_USER),                   sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
     /* TokenGroups */
@@ -76,11 +81,11 @@ SepCompareTokens(IN PTOKEN FirstToken,
                  OUT PBOOLEAN Equal)
 {
     BOOLEAN Restricted, IsEqual = FALSE;
-    
+
     ASSERT(FirstToken != SecondToken);
-    
+
     /* FIXME: Check if every SID that is present in either token is also present in the other one */
-    
+
     Restricted = SeTokenIsRestricted(FirstToken);
     if (Restricted == SeTokenIsRestricted(SecondToken))
     {
@@ -88,10 +93,10 @@ SepCompareTokens(IN PTOKEN FirstToken,
         {
             /* FIXME: Check if every SID that is restricted in either token is also restricted in the other one */
         }
-        
+
         /* FIXME: Check if every privilege that is present in either token is also present in the other one */
     }
-    
+
     *Equal = IsEqual;
     return STATUS_SUCCESS;
 }
@@ -105,10 +110,11 @@ SepFreeProxyData(PVOID ProxyData)
 
 NTSTATUS
 NTAPI
-SepCopyProxyData(PVOID* Dest, PVOID Src)
+SepCopyProxyData(PVOID* Dest,
+                 PVOID Src)
 {
     UNIMPLEMENTED;
-    return(STATUS_NOT_IMPLEMENTED);
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 NTSTATUS
@@ -119,24 +125,24 @@ SeExchangePrimaryToken(PEPROCESS Process,
 {
     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;
 }
@@ -146,10 +152,10 @@ NTAPI
 SeDeassignPrimaryToken(PEPROCESS Process)
 {
     PTOKEN OldToken;
-    
+
     /* Remove the Token */
     OldToken = ObFastReplaceObject(&Process->Token, NULL);
-    
+
     /* Mark the Old Token as free */
     OldToken->TokenInUse = 0;
 }
@@ -160,14 +166,14 @@ RtlLengthSidAndAttributes(ULONG Count,
 {
     ULONG i;
     ULONG uLength;
-    
+
     PAGED_CODE();
-    
+
     uLength = Count * sizeof(SID_AND_ATTRIBUTES);
     for (i = 0; i < Count; i++)
         uLength += RtlLengthSid(Src[i].Sid);
-    
-    return(uLength);
+
+    return uLength;
 }
 
 
@@ -178,14 +184,14 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token,
                                    PSID DefaultOwner)
 {
     ULONG i;
-    
+
     Token->PrimaryGroup = 0;
-    
+
     if (DefaultOwner)
     {
         Token->DefaultOwnerIndex = Token->UserAndGroupCount;
     }
-    
+
     /* Validate and set the primary group and user pointers */
     for (i = 0; i < Token->UserAndGroupCount; i++)
     {
@@ -194,24 +200,24 @@ SepFindPrimaryGroupAndDefaultOwner(PTOKEN Token,
         {
             Token->DefaultOwnerIndex = i;
         }
-        
+
         if (RtlEqualSid(Token->UserAndGroups[i].Sid, PrimaryGroup))
         {
             Token->PrimaryGroup = Token->UserAndGroups[i].Sid;
         }
     }
-    
+
     if (Token->DefaultOwnerIndex == Token->UserAndGroupCount)
     {
         return(STATUS_INVALID_OWNER);
     }
-    
+
     if (Token->PrimaryGroup == 0)
     {
         return(STATUS_INVALID_PRIMARY_GROUP);
     }
-    
-    return(STATUS_SUCCESS);
+
+    return STATUS_SUCCESS;
 }
 
 
@@ -230,9 +236,9 @@ SepDuplicateToken(PTOKEN Token,
     PVOID EndMem;
     PTOKEN AccessToken;
     NTSTATUS Status;
-    
+
     PAGED_CODE();
-    
+
     Status = ObCreateObject(PreviousMode,
                             SepTokenObjectType,
                             ObjectAttributes,
@@ -244,8 +250,8 @@ SepDuplicateToken(PTOKEN Token,
                             (PVOID*)&AccessToken);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("ObCreateObject() failed (Status %lx)\n");
-        return(Status);
+        DPRINT1("ObCreateObject() failed (Status %lx)\n", Status);
+        return Status;
     }
 
     /* Zero out the buffer */
@@ -255,22 +261,22 @@ SepDuplicateToken(PTOKEN Token,
     if (!NT_SUCCESS(Status))
     {
         ObDereferenceObject(AccessToken);
-        return(Status);
+        return Status;
     }
-    
+
     Status = ZwAllocateLocallyUniqueId(&AccessToken->ModifiedId);
     if (!NT_SUCCESS(Status))
     {
         ObDereferenceObject(AccessToken);
-        return(Status);
+        return Status;
     }
-    
+
     AccessToken->TokenLock = &SepTokenLock;
-    
+
     AccessToken->TokenType  = TokenType;
     AccessToken->ImpersonationLevel = Level;
     RtlCopyLuid(&AccessToken->AuthenticationId, &Token->AuthenticationId);
-    
+
     AccessToken->TokenSource.SourceIdentifier.LowPart = Token->TokenSource.SourceIdentifier.LowPart;
     AccessToken->TokenSource.SourceIdentifier.HighPart = Token->TokenSource.SourceIdentifier.HighPart;
     memcpy(AccessToken->TokenSource.SourceName,
@@ -279,18 +285,18 @@ SepDuplicateToken(PTOKEN Token,
     AccessToken->ExpirationTime.QuadPart = Token->ExpirationTime.QuadPart;
     AccessToken->UserAndGroupCount = Token->UserAndGroupCount;
     AccessToken->DefaultOwnerIndex = Token->DefaultOwnerIndex;
-    
+
     uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount;
     for (i = 0; i < Token->UserAndGroupCount; i++)
         uLength += RtlLengthSid(Token->UserAndGroups[i].Sid);
-    
+
     AccessToken->UserAndGroups =
     (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
                                                uLength,
                                                'uKOT');
-    
+
     EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
-    
+
     Status = RtlCopySidAndAttributesArray(AccessToken->UserAndGroupCount,
                                           Token->UserAndGroups,
                                           uLength,
@@ -305,17 +311,17 @@ SepDuplicateToken(PTOKEN Token,
                                                     Token->PrimaryGroup,
                                                     0);
     }
-    
+
     if (NT_SUCCESS(Status))
     {
         AccessToken->PrivilegeCount = Token->PrivilegeCount;
-        
+
         uLength = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
         AccessToken->Privileges =
         (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
                                                     uLength,
                                                     'pKOT');
-        
+
         for (i = 0; i < AccessToken->PrivilegeCount; i++)
         {
             RtlCopyLuid(&AccessToken->Privileges[i].Luid,
@@ -323,8 +329,8 @@ SepDuplicateToken(PTOKEN Token,
             AccessToken->Privileges[i].Attributes =
             Token->Privileges[i].Attributes;
         }
-        
-        if ( Token->DefaultDacl )
+
+        if (Token->DefaultDacl)
         {
             AccessToken->DefaultDacl =
             (PACL) ExAllocatePoolWithTag(PagedPool,
@@ -335,14 +341,14 @@ SepDuplicateToken(PTOKEN Token,
                    Token->DefaultDacl->AclSize);
         }
     }
-    
-    if ( NT_SUCCESS(Status) )
+
+    if (NT_SUCCESS(Status))
     {
         *NewAccessToken = AccessToken;
         return(STATUS_SUCCESS);
     }
-    
-    return(Status);
+
+    return Status;
 }
 
 NTSTATUS
@@ -355,7 +361,7 @@ SeSubProcessToken(IN PTOKEN ParentToken,
     PTOKEN NewToken;
     OBJECT_ATTRIBUTES ObjectAttributes;
     NTSTATUS Status;
-    
+
     /* Initialize the attributes and duplicate it */
     InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
     Status = SepDuplicateToken(ParentToken,
@@ -379,12 +385,12 @@ SeSubProcessToken(IN PTOKEN ParentToken,
             /* Set the session ID */
             NewToken->SessionId = SessionId;
             NewToken->TokenInUse = InUse;
-            
+
             /* Return the token */
             *Token = NewToken;
         }
     }
-    
+
     /* Return status */
     return Status;
 }
@@ -396,25 +402,25 @@ SeIsTokenChild(IN PTOKEN Token,
 {
     PTOKEN ProcessToken;
     LUID ProcessLuid, CallerLuid;
-    
+
     /* Assume failure */
     *IsChild = FALSE;
-    
+
     /* Reference the process token */
     ProcessToken = PsReferencePrimaryToken(PsGetCurrentProcess());
-    
+
     /* Get the ID */
     ProcessLuid = ProcessToken->TokenId;
-    
+
     /* Dereference the token */
     ObFastDereferenceObject(&PsGetCurrentProcess()->Token, ProcessToken);
-    
+
     /* Get our LUID */
     CallerLuid = Token->TokenId;
-    
+
     /* Compare the LUIDs */
     if (RtlEqualLuid(&CallerLuid, &ProcessLuid)) *IsChild = TRUE;
-    
+
     /* Return success */
     return STATUS_SUCCESS;
 }
@@ -428,9 +434,9 @@ SeCopyClientToken(IN PACCESS_TOKEN Token,
 {
     NTSTATUS Status;
     OBJECT_ATTRIBUTES ObjectAttributes;
-    
+
     PAGED_CODE();
-    
+
     InitializeObjectAttributes(&ObjectAttributes,
                                NULL,
                                0,
@@ -443,21 +449,22 @@ SeCopyClientToken(IN PACCESS_TOKEN Token,
                                Level,
                                PreviousMode,
                                (PTOKEN*)NewToken);
-    
-    return(Status);
+
+    return Status;
 }
 
-VOID NTAPI
+VOID
+NTAPI
 SepDeleteToken(PVOID ObjectBody)
 {
     PTOKEN AccessToken = (PTOKEN)ObjectBody;
-    
+
     if (AccessToken->UserAndGroups)
         ExFreePool(AccessToken->UserAndGroups);
-    
+
     if (AccessToken->Privileges)
         ExFreePool(AccessToken->Privileges);
-    
+
     if (AccessToken->DefaultDacl)
         ExFreePool(AccessToken->DefaultDacl);
 }
@@ -470,12 +477,12 @@ SepInitializeTokenImplementation(VOID)
 {
     UNICODE_STRING Name;
     OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
-    
+
     ExInitializeResource(&SepTokenLock);
-    
+
     DPRINT("Creating Token Object Type\n");
-    
-    /*  Initialize the Token type  */
+
+    /* Initialize the Token type */
     RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
     RtlInitUnicodeString(&Name, L"Token");
     ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
@@ -496,48 +503,94 @@ SeAssignPrimaryToken(IN PEPROCESS Process,
                      IN PTOKEN Token)
 {
     PAGED_CODE();
-    
+
     /* Sanity checks */
     ASSERT(Token->TokenType == TokenPrimary);
     ASSERT(!Token->TokenInUse);
-    
+
     /* Clean any previous token */
     if (Process->Token.Object) SeDeassignPrimaryToken(Process);
-    
+
     /* Set the new token */
     ObReferenceObject(Token);
     Token->TokenInUse = TRUE;
     ObInitializeFastReference(&Process->Token, Token);
 }
 
-PTOKEN
+
+NTSTATUS
 NTAPI
-SepCreateSystemProcessToken(VOID)
+SepCreateToken(OUT PHANDLE TokenHandle,
+               IN KPROCESSOR_MODE PreviousMode,
+               IN ACCESS_MASK DesiredAccess,
+               IN POBJECT_ATTRIBUTES ObjectAttributes,
+               IN TOKEN_TYPE TokenType,
+               IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
+               IN PLUID AuthenticationId,
+               IN PLARGE_INTEGER ExpirationTime,
+               IN PSID_AND_ATTRIBUTES User,
+               IN ULONG GroupCount,
+               IN PSID_AND_ATTRIBUTES Groups,
+               IN ULONG GroupLength,
+               IN ULONG PrivilegeCount,
+               IN PLUID_AND_ATTRIBUTES Privileges,
+               IN PSID Owner,
+               IN PSID PrimaryGroup,
+               IN PACL DefaultDacl,
+               IN PTOKEN_SOURCE TokenSource,
+               IN BOOLEAN SystemToken)
 {
-    NTSTATUS Status;
-    ULONG uSize;
-    ULONG i;
-    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
-     */
-    Status = ObCreateObject(KernelMode,
+    LUID TokenId;
+    LUID ModifiedId;
+    PVOID EndMem;
+    ULONG uLength;
+    ULONG i;
+    NTSTATUS Status;
+    ULONG TokenFlags = 0;
+
+    /* Loop all groups */
+    for (i = 0; i < GroupCount; i++)
+    {
+        /* Check for mandatory groups */
+        if (Groups[i].Attributes & SE_GROUP_MANDATORY)
+        {
+            /* Force them to be enabled */
+            Groups[i].Attributes |= (SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT);
+        }
+
+        /* Check of the group is an admin group */
+        if (RtlEqualSid(SeAliasAdminsSid, Groups[i].Sid))
+        {
+            /* Remember this so we can optimize queries later */
+            TokenFlags |= TOKEN_HAS_ADMIN_GROUP;
+        }
+    }
+
+    /* Loop all privileges */
+    for (i = 0; i < PrivilegeCount; i++)
+    {
+        /* For optimization, check for change notify and impersonate rights */
+        if (((RtlEqualLuid(&Privileges[i].Luid, &SeChangeNotifyPrivilege)) &&
+            (Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)))
+        {
+            /* Remember token has traverse */
+            TokenFlags |= TOKEN_HAS_TRAVERSE_PRIVILEGE;
+        }
+    }
+
+    Status = ZwAllocateLocallyUniqueId(&TokenId);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    Status = ZwAllocateLocallyUniqueId(&ModifiedId);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    Status = ObCreateObject(PreviousMode,
                             SepTokenObjectType,
-                            NULL,
-                            KernelMode,
+                            ObjectAttributes,
+                            PreviousMode,
                             NULL,
                             sizeof(TOKEN),
                             0,
@@ -545,184 +598,282 @@ SepCreateSystemProcessToken(VOID)
                             (PVOID*)&AccessToken);
     if (!NT_SUCCESS(Status))
     {
-        return NULL;
+        DPRINT1("ObCreateObject() failed (Status %lx)\n");
+        return Status;
     }
 
     /* Zero out the buffer */
     RtlZeroMemory(AccessToken, sizeof(TOKEN));
-    
-    Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId);
-    if (!NT_SUCCESS(Status))
+
+    AccessToken->TokenLock = &SepTokenLock;
+
+    RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier,
+                &TokenSource->SourceIdentifier);
+    memcpy(AccessToken->TokenSource.SourceName,
+           TokenSource->SourceName,
+           sizeof(TokenSource->SourceName));
+
+    RtlCopyLuid(&AccessToken->TokenId, &TokenId);
+    RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId);
+    AccessToken->ExpirationTime = *ExpirationTime;
+    RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId);
+
+    AccessToken->UserAndGroupCount = GroupCount + 1;
+    AccessToken->PrivilegeCount = PrivilegeCount;
+
+    AccessToken->TokenFlags = TokenFlags;
+    AccessToken->TokenType = TokenType;
+    AccessToken->ImpersonationLevel = ImpersonationLevel;
+
+    /*
+     * Normally we would just point these members into the variable information
+     * area; however, our ObCreateObject() call can't allocate a variable information
+     * area, so we allocate them seperately and provide a destroy function.
+     */
+
+    uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount;
+    uLength += RtlLengthSid(User);
+    for (i = 0; i < GroupCount; i++)
+        uLength += RtlLengthSid(Groups[i].Sid);
+
+    AccessToken->UserAndGroups =
+    (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
+                                               uLength,
+                                               'uKOT');
+
+    EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
+
+    Status = RtlCopySidAndAttributesArray(1,
+                                          User,
+                                          uLength,
+                                          AccessToken->UserAndGroups,
+                                          EndMem,
+                                          &EndMem,
+                                          &uLength);
+    if (NT_SUCCESS(Status))
     {
-        ObDereferenceObject(AccessToken);
-        return NULL;
+        Status = RtlCopySidAndAttributesArray(GroupCount,
+                                              Groups,
+                                              uLength,
+                                              &AccessToken->UserAndGroups[1],
+                                              EndMem,
+                                              &EndMem,
+                                              &uLength);
     }
-    
-    Status = ExpAllocateLocallyUniqueId(&AccessToken->ModifiedId);
-    if (!NT_SUCCESS(Status))
+
+    if (NT_SUCCESS(Status))
     {
-        ObDereferenceObject(AccessToken);
-        return NULL;
+        Status = SepFindPrimaryGroupAndDefaultOwner(
+                                                    AccessToken,
+                                                    PrimaryGroup,
+                                                    Owner);
     }
-    
-    Status = ExpAllocateLocallyUniqueId(&AccessToken->AuthenticationId);
-    if (!NT_SUCCESS(Status))
+
+    if (NT_SUCCESS(Status))
     {
-        ObDereferenceObject(AccessToken);
-        return NULL;
+        uLength = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
+        AccessToken->Privileges =
+        (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
+                                                    uLength,
+                                                    'pKOT');
+
+        if (PreviousMode != KernelMode)
+        {
+            _SEH2_TRY
+            {
+                RtlCopyMemory(AccessToken->Privileges,
+                              Privileges,
+                              PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END;
+        }
+        else
+        {
+            RtlCopyMemory(AccessToken->Privileges,
+                          Privileges,
+                          PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+        }
     }
-    
-    AccessToken->TokenLock = &SepTokenLock;
-    
-    AccessToken->TokenType = TokenPrimary;
-    AccessToken->ImpersonationLevel = SecurityDelegation;
-    memcpy(AccessToken->TokenSource.SourceName, "SeMgr\0\0\0", 8);
-    AccessToken->ExpirationTime.QuadPart = -1;
-    AccessToken->UserAndGroupCount = 4;
-    
-    uSize = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount;
-    uSize += uLocalSystemLength;
-    uSize += uWorldLength;
-    uSize += uAuthUserLength;
-    uSize += uAdminsLength;
-    
-    AccessToken->UserAndGroups =
-    (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
-                                               uSize,
-                                               'uKOT');
-    SidArea = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
-    
-    i = 0;
-    AccessToken->UserAndGroups[i].Sid = (PSID) SidArea;
-    AccessToken->UserAndGroups[i++].Attributes = 0;
-    RtlCopySid(uLocalSystemLength, SidArea, SeLocalSystemSid);
-    SidArea = (char*)SidArea + uLocalSystemLength;
-    
-    AccessToken->DefaultOwnerIndex = i;
-    AccessToken->UserAndGroups[i].Sid = (PSID) SidArea;
-    AccessToken->PrimaryGroup = (PSID) SidArea;
-    AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT;
-    Status = RtlCopySid(uAdminsLength, SidArea, SeAliasAdminsSid);
-    SidArea = (char*)SidArea + uAdminsLength;
-    
-    AccessToken->UserAndGroups[i].Sid = (PSID) SidArea;
-    AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY;
-    RtlCopySid(uWorldLength, SidArea, SeWorldSid);
-    SidArea = (char*)SidArea + uWorldLength;
-    
-    AccessToken->UserAndGroups[i].Sid = (PSID) SidArea;
-    AccessToken->UserAndGroups[i++].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY;
-    RtlCopySid(uAuthUserLength, SidArea, SeAuthenticatedUserSid);
-    SidArea = (char*)SidArea + uAuthUserLength;
-    
-    AccessToken->PrivilegeCount = 20;
-    
-    uSize = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
-    AccessToken->Privileges =
-    (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
-                                                uSize,
-                                                'pKOT');
-    
-    i = 0;
-    AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
-    AccessToken->Privileges[i++].Luid = SeTcbPrivilege;
-    
-    AccessToken->Privileges[i].Attributes = 0;
-    AccessToken->Privileges[i++].Luid = SeCreateTokenPrivilege;
-    
-    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
-    AccessToken->Privileges[i].Attributes = 0;
-    AccessToken->Privileges[i++].Luid = SeUndockPrivilege;
-    
-    AccessToken->Privileges[i].Attributes = 0;
-    AccessToken->Privileges[i++].Luid = SeManageVolumePrivilege;
-#endif
-    
-    ASSERT(i == 20);
-    
-    uSize = sizeof(ACL);
-    uSize += sizeof(ACE) + uLocalSystemLength;
-    uSize += sizeof(ACE) + uAdminsLength;
-    uSize = (uSize & (~3)) + 8;
-    AccessToken->DefaultDacl =
-    (PACL) ExAllocatePoolWithTag(PagedPool,
-                                 uSize,
-                                 'kDOT');
-    Status = RtlCreateAcl(AccessToken->DefaultDacl, uSize, ACL_REVISION);
-    if ( NT_SUCCESS(Status) )
+
+    if (NT_SUCCESS(Status))
     {
-        Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_ALL, SeLocalSystemSid);
+        AccessToken->DefaultDacl =
+        (PACL) ExAllocatePoolWithTag(PagedPool,
+                                     DefaultDacl->AclSize,
+                                     'kDOT');
+        memcpy(AccessToken->DefaultDacl,
+               DefaultDacl,
+               DefaultDacl->AclSize);
     }
-    
-    if ( NT_SUCCESS(Status) )
+
+    if (!SystemToken)
     {
-        Status = RtlAddAccessAllowedAce(AccessToken->DefaultDacl, ACL_REVISION, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE|READ_CONTROL, SeAliasAdminsSid);
+        Status = ObInsertObject((PVOID)AccessToken,
+                                NULL,
+                                DesiredAccess,
+                                0,
+                                NULL,
+                                TokenHandle);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("ObInsertObject() failed (Status %lx)\n", Status);
+        }
     }
-    
-    if ( ! NT_SUCCESS(Status) )
+    else
     {
-        ObDereferenceObject(AccessToken);
-        return NULL;
+        /* Return pointer instead of handle */
+        *TokenHandle = (HANDLE)AccessToken;
     }
-    
-    return AccessToken;
+
+    return Status;
+}
+
+PTOKEN
+NTAPI
+SepCreateSystemProcessToken(VOID)
+{
+    LUID_AND_ATTRIBUTES Privileges[25];
+    ULONG GroupAttributes, OwnerAttributes;
+    SID_AND_ATTRIBUTES Groups[32];
+    LARGE_INTEGER Expiration;
+    SID_AND_ATTRIBUTES UserSid;
+    ULONG GroupLength;
+    PSID PrimaryGroup;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    PSID Owner;
+    ULONG i;
+    PTOKEN Token;
+    NTSTATUS Status;
+
+    /* Don't ever expire */
+    Expiration.QuadPart = -1;
+
+    /* All groups mandatory and enabled */
+    GroupAttributes = SE_GROUP_ENABLED | SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT;
+    OwnerAttributes = SE_GROUP_ENABLED | SE_GROUP_OWNER | SE_GROUP_ENABLED_BY_DEFAULT;
+
+    /* User is system */
+    UserSid.Sid = SeLocalSystemSid;
+    UserSid.Attributes = 0;
+
+    /* Primary group is local system */
+    PrimaryGroup = SeLocalSystemSid;
+
+    /* Owner is admins */
+    Owner = SeAliasAdminsSid;
+
+    /* Groups are admins, world, and authenticated users */
+    Groups[0].Sid = SeAliasAdminsSid;
+    Groups[0].Attributes = OwnerAttributes;
+    Groups[1].Sid = SeWorldSid;
+    Groups[1].Attributes = GroupAttributes;
+    Groups[2].Sid = SeAuthenticatedUserSid;
+    Groups[2].Attributes = OwnerAttributes;
+    GroupLength = sizeof(SID_AND_ATTRIBUTES) +
+                  SeLengthSid(Groups[0].Sid) +
+                  SeLengthSid(Groups[1].Sid) +
+                  SeLengthSid(Groups[2].Sid);
+    ASSERT(GroupLength <= sizeof(Groups));
+
+    /* Setup the privileges */
+    i = 0;
+    Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED;
+    Privileges[i++].Luid = SeTcbPrivilege;
+
+    Privileges[i].Attributes = 0;
+    Privileges[i++].Luid = SeCreateTokenPrivilege;
+
+    Privileges[i].Attributes = 0;
+    Privileges[i++].Luid = SeTakeOwnershipPrivilege;
+
+    Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED;
+    Privileges[i++].Luid = SeCreatePagefilePrivilege;
+
+    Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED;
+    Privileges[i++].Luid = SeLockMemoryPrivilege;
+
+    Privileges[i].Attributes = 0;
+    Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege;
+
+    Privileges[i].Attributes = 0;
+    Privileges[i++].Luid = SeIncreaseQuotaPrivilege;
+
+    Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED;
+    Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege;
+
+    Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED;
+    Privileges[i++].Luid = SeCreatePermanentPrivilege;
+
+    Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED;
+    Privileges[i++].Luid = SeDebugPrivilege;
+
+    Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED;
+    Privileges[i++].Luid = SeAuditPrivilege;
+
+    Privileges[i].Attributes = 0;
+    Privileges[i++].Luid = SeSecurityPrivilege;
+
+    Privileges[i].Attributes = 0;
+    Privileges[i++].Luid = SeSystemEnvironmentPrivilege;
+
+    Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED;
+    Privileges[i++].Luid = SeChangeNotifyPrivilege;
+
+    Privileges[i].Attributes = 0;
+    Privileges[i++].Luid = SeBackupPrivilege;
+
+    Privileges[i].Attributes = 0;
+    Privileges[i++].Luid = SeRestorePrivilege;
+
+    Privileges[i].Attributes = 0;
+    Privileges[i++].Luid = SeShutdownPrivilege;
+
+    Privileges[i].Attributes = 0;
+    Privileges[i++].Luid = SeLoadDriverPrivilege;
+
+    Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED;
+    Privileges[i++].Luid = SeProfileSingleProcessPrivilege;
+
+    Privileges[i].Attributes = 0;
+    Privileges[i++].Luid = SeSystemtimePrivilege;
+    ASSERT(i == 20);
+
+    /* Setup the object attributes */
+    InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
+    ASSERT(SeSystemDefaultDacl != NULL);
+
+    /* Create the token */
+    Status = SepCreateToken((PHANDLE)&Token,
+                            KernelMode,
+                            0,
+                            &ObjectAttributes,
+                            TokenPrimary,
+                            0,
+                            &SeSystemAuthenticationId,
+                            &Expiration,
+                            &UserSid,
+                            3,
+                            Groups,
+                            GroupLength,
+                            20,
+                            Privileges,
+                            Owner,
+                            PrimaryGroup,
+                            SeSystemDefaultDacl,
+                            &SeSystemTokenSource,
+                            TRUE);
+    ASSERT(Status == STATUS_SUCCESS);
+
+    /* Return the token */
+    return Token;
 }
 
 /* PUBLIC FUNCTIONS ***********************************************************/
+
 /*
  * @unimplemented
  */
@@ -767,14 +918,15 @@ SeQuerySessionIdToken(IN PACCESS_TOKEN Token,
 /*
  * @implemented
  */
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 SeQueryAuthenticationIdToken(IN PACCESS_TOKEN Token,
                              OUT PLUID LogonId)
 {
     PAGED_CODE();
-    
+
     *LogonId = ((PTOKEN)Token)->AuthenticationId;
-    
+
     return STATUS_SUCCESS;
 }
 
@@ -787,7 +939,7 @@ NTAPI
 SeTokenImpersonationLevel(IN PACCESS_TOKEN Token)
 {
     PAGED_CODE();
-    
+
     return ((PTOKEN)Token)->ImpersonationLevel;
 }
 
@@ -799,7 +951,7 @@ TOKEN_TYPE NTAPI
 SeTokenType(IN PACCESS_TOKEN Token)
 {
     PAGED_CODE();
-    
+
     return ((PTOKEN)Token)->TokenType;
 }
 
@@ -812,6 +964,7 @@ NTAPI
 SeTokenIsAdmin(IN PACCESS_TOKEN Token)
 {
     PAGED_CODE();
+
     return (((PTOKEN)Token)->TokenFlags & TOKEN_WRITE_RESTRICTED) != 0;
 }
 
@@ -823,6 +976,7 @@ NTAPI
 SeTokenIsRestricted(IN PACCESS_TOKEN Token)
 {
     PAGED_CODE();
+
     return (((PTOKEN)Token)->TokenFlags & TOKEN_IS_RESTRICTED) != 0;
 }
 
@@ -834,6 +988,7 @@ NTAPI
 SeTokenIsWriteRestricted(IN PACCESS_TOKEN Token)
 {
     PAGED_CODE();
+
     return (((PTOKEN)Token)->TokenFlags & TOKEN_HAS_RESTORE_PRIVILEGE) != 0;
 }
 
@@ -858,11 +1013,11 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
     ULONG RequiredLength;
     KPROCESSOR_MODE PreviousMode;
     NTSTATUS Status = STATUS_SUCCESS;
-    
+
     PAGED_CODE();
-    
+
     PreviousMode = ExGetPreviousMode();
-    
+
     /* Check buffers and class validity */
     Status = DefaultQueryInfoBufferCheck(TokenInformationClass,
                                          SeTokenInformationClass,
@@ -870,14 +1025,14 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                                          TokenInformation,
                                          TokenInformationLength,
                                          ReturnLength,
+                                         NULL,
                                          PreviousMode);
-    
-    if(!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
         DPRINT("NtQueryInformationToken() failed, Status: 0x%x\n", Status);
         return Status;
     }
-    
+
     Status = ObReferenceObjectByHandle(TokenHandle,
                                        (TokenInformationClass == TokenSource) ? TOKEN_QUERY_SOURCE : TOKEN_QUERY,
                                        SepTokenObjectType,
@@ -891,14 +1046,14 @@ 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);
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    if (TokenInformationLength >= RequiredLength)
                     {
                         Status = RtlCopySidAndAttributesArray(1,
                                                               &Token->UserAndGroups[0],
@@ -912,8 +1067,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -923,27 +1078,27 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_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]);
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    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)));
-                        
+
                         tg->GroupCount = Token->UserAndGroupCount - 1;
                         Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
                                                               &Token->UserAndGroups[1],
@@ -957,8 +1112,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -968,21 +1123,21 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_END;
-                
+
                 break;
             }
-                
+
             case TokenPrivileges:
             {
                 PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)TokenInformation;
-                
+
                 DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
                 RequiredLength = sizeof(tp->PrivilegeCount) +
                 (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    if (TokenInformationLength >= RequiredLength)
                     {
                         tp->PrivilegeCount = Token->PrivilegeCount;
                         RtlCopyLuidAndAttributesArray(Token->PrivilegeCount,
@@ -993,8 +1148,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -1004,22 +1159,22 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_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;
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    if (TokenInformationLength >= RequiredLength)
                     {
                         to->Owner = (PSID)(to + 1);
                         Status = RtlCopySid(SidLen,
@@ -1030,8 +1185,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -1041,22 +1196,22 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_END;
-                
+
                 break;
             }
-                
+
             case TokenPrimaryGroup:
             {
                 ULONG SidLen;
                 PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
-                
+
                 DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n");
                 SidLen = RtlLengthSid(Token->PrimaryGroup);
                 RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen;
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    if (TokenInformationLength >= RequiredLength)
                     {
                         tpg->PrimaryGroup = (PSID)(tpg + 1);
                         Status = RtlCopySid(SidLen,
@@ -1067,8 +1222,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -1078,27 +1233,27 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_END;
-                
+
                 break;
             }
-                
+
             case TokenDefaultDacl:
             {
                 PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
-                
+
                 DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
                 RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
-                
-                if(Token->DefaultDacl != NULL)
+
+                if (Token->DefaultDacl != NULL)
                 {
                     RequiredLength += Token->DefaultDacl->AclSize;
                 }
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    if (TokenInformationLength >= RequiredLength)
                     {
-                        if(Token->DefaultDacl != NULL)
+                        if (Token->DefaultDacl != NULL)
                         {
                             tdd->DefaultDacl = (PACL)(tdd + 1);
                             RtlCopyMemory(tdd->DefaultDacl,
@@ -1114,8 +1269,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -1125,20 +1280,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_END;
-                
+
                 break;
             }
-                
+
             case TokenSource:
             {
                 PTOKEN_SOURCE ts = (PTOKEN_SOURCE)TokenInformation;
-                
+
                 DPRINT("NtQueryInformationToken(TokenSource)\n");
                 RequiredLength = sizeof(TOKEN_SOURCE);
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    if (TokenInformationLength >= RequiredLength)
                     {
                         *ts = Token->TokenSource;
                     }
@@ -1146,8 +1301,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -1157,20 +1312,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_END;
-                
+
                 break;
             }
-                
+
             case TokenType:
             {
                 PTOKEN_TYPE tt = (PTOKEN_TYPE)TokenInformation;
-                
+
                 DPRINT("NtQueryInformationToken(TokenType)\n");
                 RequiredLength = sizeof(TOKEN_TYPE);
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    if (TokenInformationLength >= RequiredLength)
                     {
                         *tt = Token->TokenType;
                     }
@@ -1178,8 +1333,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -1189,20 +1344,28 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_END;
-                
+
                 break;
             }
-                
+
             case TokenImpersonationLevel:
             {
                 PSECURITY_IMPERSONATION_LEVEL sil = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation;
-                
+
                 DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n");
+
+                /* Fail if the token is not an impersonation token */
+                if (Token->TokenType != TokenImpersonation)
+                {
+                    Status = STATUS_INVALID_INFO_CLASS;
+                    break;
+                }
+
                 RequiredLength = sizeof(SECURITY_IMPERSONATION_LEVEL);
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    if (TokenInformationLength >= RequiredLength)
                     {
                         *sil = Token->ImpersonationLevel;
                     }
@@ -1210,8 +1373,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -1221,20 +1384,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_END;
-                
+
                 break;
             }
-                
+
             case TokenStatistics:
             {
                 PTOKEN_STATISTICS ts = (PTOKEN_STATISTICS)TokenInformation;
-                
+
                 DPRINT("NtQueryInformationToken(TokenStatistics)\n");
                 RequiredLength = sizeof(TOKEN_STATISTICS);
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    if (TokenInformationLength >= RequiredLength)
                     {
                         ts->TokenId = Token->TokenId;
                         ts->AuthenticationId = Token->AuthenticationId;
@@ -1251,8 +1414,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -1262,20 +1425,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_END;
-                
+
                 break;
             }
-                
+
             case TokenOrigin:
             {
                 PTOKEN_ORIGIN to = (PTOKEN_ORIGIN)TokenInformation;
-                
+
                 DPRINT("NtQueryInformationToken(TokenOrigin)\n");
                 RequiredLength = sizeof(TOKEN_ORIGIN);
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    if (TokenInformationLength >= RequiredLength)
                     {
                         RtlCopyLuid(&to->OriginatingLogonSession,
                                     &Token->AuthenticationId);
@@ -1284,8 +1447,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -1295,32 +1458,32 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_END;
-                
+
                 break;
             }
-                
+
             case TokenGroupsAndPrivileges:
                 DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n");
                 Status = STATUS_NOT_IMPLEMENTED;
                 break;
-                
+
             case TokenRestrictedSids:
             {
                 PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
-                
+
                 DPRINT("NtQueryInformationToken(TokenRestrictedSids)\n");
                 RequiredLength = sizeof(tg->GroupCount) +
                 RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids);
-                
+
                 _SEH2_TRY
                 {
-                    if(TokenInformationLength >= RequiredLength)
+                    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,
@@ -1334,8 +1497,8 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     {
                         Status = STATUS_BUFFER_TOO_SMALL;
                     }
-                    
-                    if(ReturnLength != NULL)
+
+                    if (ReturnLength != NULL)
                     {
                         *ReturnLength = RequiredLength;
                     }
@@ -1345,32 +1508,32 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     Status = _SEH2_GetExceptionCode();
                 }
                 _SEH2_END;
-                
+
                 break;
             }
-                
+
             case TokenSandBoxInert:
                 DPRINT1("NtQueryInformationToken(TokenSandboxInert) not implemented\n");
                 Status = STATUS_NOT_IMPLEMENTED;
                 break;
-                
+
             case TokenSessionId:
             {
                 ULONG SessionId = 0;
-                
+
                 DPRINT("NtQueryInformationToken(TokenSessionId)\n");
-                
+
                 Status = SeQuerySessionIdToken(Token,
                                                &SessionId);
-                
-                if(NT_SUCCESS(Status))
+
+                if (NT_SUCCESS(Status))
                 {
                     _SEH2_TRY
                     {
                         /* buffer size was already verified, no need to check here again */
                         *(PULONG)TokenInformation = SessionId;
-                        
-                        if(ReturnLength != NULL)
+
+                        if (ReturnLength != NULL)
                         {
                             *ReturnLength = sizeof(ULONG);
                         }
@@ -1381,20 +1544,20 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                     }
                     _SEH2_END;
                 }
-                
+
                 break;
             }
-                
+
             default:
                 DPRINT1("NtQueryInformationToken(%d) invalid information class\n", TokenInformationClass);
                 Status = STATUS_INVALID_INFO_CLASS;
                 break;
         }
-        
+
         ObDereferenceObject(Token);
     }
-    
-    return(Status);
+
+    return Status;
 }
 
 
@@ -1413,31 +1576,30 @@ NtSetInformationToken(IN HANDLE TokenHandle,
     PTOKEN Token;
     KPROCESSOR_MODE PreviousMode;
     ULONG NeededAccess = TOKEN_ADJUST_DEFAULT;
-    NTSTATUS Status = STATUS_SUCCESS;
-    
+    NTSTATUS Status;
+
     PAGED_CODE();
-    
+
     PreviousMode = ExGetPreviousMode();
-    
+
     Status = DefaultSetInfoBufferCheck(TokenInformationClass,
                                        SeTokenInformationClass,
                                        sizeof(SeTokenInformationClass) / sizeof(SeTokenInformationClass[0]),
                                        TokenInformation,
                                        TokenInformationLength,
                                        PreviousMode);
-    
-    if(!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
         /* Invalid buffers */
         DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status);
         return Status;
     }
-    
-    if(TokenInformationClass == TokenSessionId)
+
+    if (TokenInformationClass == TokenSessionId)
     {
         NeededAccess |= TOKEN_ADJUST_SESSIONID;
     }
-    
+
     Status = ObReferenceObjectByHandle(TokenHandle,
                                        NeededAccess,
                                        SepTokenObjectType,
@@ -1450,39 +1612,34 @@ NtSetInformationToken(IN HANDLE TokenHandle,
         {
             case TokenOwner:
             {
-                if(TokenInformationLength >= sizeof(TOKEN_OWNER))
+                if (TokenInformationLength >= sizeof(TOKEN_OWNER))
                 {
                     PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
-                    PSID InputSid = NULL;
-                    
+                    PSID InputSid = NULL, CapturedSid;
+
                     _SEH2_TRY
                     {
                         InputSid = to->Owner;
                     }
                     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                     {
-                        Status = _SEH2_GetExceptionCode();
+                        _SEH2_YIELD(return _SEH2_GetExceptionCode());
                     }
                     _SEH2_END;
-                    
-                    if(NT_SUCCESS(Status))
+
+                    Status = SepCaptureSid(InputSid,
+                                           PreviousMode,
+                                           PagedPool,
+                                           FALSE,
+                                           &CapturedSid);
+                    if (NT_SUCCESS(Status))
                     {
-                        PSID CapturedSid;
-                        
-                        Status = SepCaptureSid(InputSid,
-                                               PreviousMode,
-                                               PagedPool,
-                                               FALSE,
-                                               &CapturedSid);
-                        if(NT_SUCCESS(Status))
-                        {
-                            RtlCopySid(RtlLengthSid(CapturedSid),
-                                       Token->UserAndGroups[Token->DefaultOwnerIndex].Sid,
-                                       CapturedSid);
-                            SepReleaseSid(CapturedSid,
-                                          PreviousMode,
-                                          FALSE);
-                        }
+                        RtlCopySid(RtlLengthSid(CapturedSid),
+                                   Token->UserAndGroups[Token->DefaultOwnerIndex].Sid,
+                                   CapturedSid);
+                        SepReleaseSid(CapturedSid,
+                                      PreviousMode,
+                                      FALSE);
                     }
                 }
                 else
@@ -1491,42 +1648,37 @@ NtSetInformationToken(IN HANDLE TokenHandle,
                 }
                 break;
             }
-                
+
             case TokenPrimaryGroup:
             {
-                if(TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP))
+                if (TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP))
                 {
                     PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
-                    PSID InputSid = NULL;
-                    
+                    PSID InputSid = NULL, CapturedSid;
+
                     _SEH2_TRY
                     {
                         InputSid = tpg->PrimaryGroup;
                     }
                     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                     {
-                        Status = _SEH2_GetExceptionCode();
+                        _SEH2_YIELD(return _SEH2_GetExceptionCode());
                     }
                     _SEH2_END;
-                    
-                    if(NT_SUCCESS(Status))
+
+                    Status = SepCaptureSid(InputSid,
+                                           PreviousMode,
+                                           PagedPool,
+                                           FALSE,
+                                           &CapturedSid);
+                    if (NT_SUCCESS(Status))
                     {
-                        PSID CapturedSid;
-                        
-                        Status = SepCaptureSid(InputSid,
-                                               PreviousMode,
-                                               PagedPool,
-                                               FALSE,
-                                               &CapturedSid);
-                        if(NT_SUCCESS(Status))
-                        {
-                            RtlCopySid(RtlLengthSid(CapturedSid),
-                                       Token->PrimaryGroup,
-                                       CapturedSid);
-                            SepReleaseSid(CapturedSid,
-                                          PreviousMode,
-                                          FALSE);
-                        }
+                        RtlCopySid(RtlLengthSid(CapturedSid),
+                                   Token->PrimaryGroup,
+                                   CapturedSid);
+                        SepReleaseSid(CapturedSid,
+                                      PreviousMode,
+                                      FALSE);
                     }
                 }
                 else
@@ -1535,56 +1687,53 @@ NtSetInformationToken(IN HANDLE TokenHandle,
                 }
                 break;
             }
-                
+
             case TokenDefaultDacl:
             {
-                if(TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL))
+                if (TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL))
                 {
                     PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
                     PACL InputAcl = NULL;
-                    
+
                     _SEH2_TRY
                     {
                         InputAcl = tdd->DefaultDacl;
                     }
                     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                     {
-                        Status = _SEH2_GetExceptionCode();
+                        _SEH2_YIELD(return _SEH2_GetExceptionCode());
                     }
                     _SEH2_END;
-                    
-                    if(NT_SUCCESS(Status))
+
+                    if (InputAcl != NULL)
                     {
-                        if(InputAcl != NULL)
-                        {
-                            PACL CapturedAcl;
-                            
-                            /* capture and copy the dacl */
-                            Status = SepCaptureAcl(InputAcl,
-                                                   PreviousMode,
-                                                   PagedPool,
-                                                   TRUE,
-                                                   &CapturedAcl);
-                            if(NT_SUCCESS(Status))
-                            {
-                                /* free the previous dacl if present */
-                                if(Token->DefaultDacl != NULL)
-                                {
-                                    ExFreePool(Token->DefaultDacl);
-                                }
-                                
-                                /* set the new dacl */
-                                Token->DefaultDacl = CapturedAcl;
-                            }
-                        }
-                        else
+                        PACL CapturedAcl;
+
+                        /* Capture and copy the dacl */
+                        Status = SepCaptureAcl(InputAcl,
+                                               PreviousMode,
+                                               PagedPool,
+                                               TRUE,
+                                               &CapturedAcl);
+                        if (NT_SUCCESS(Status))
                         {
-                            /* clear and free the default dacl if present */
+                            /* Free the previous dacl if present */
                             if(Token->DefaultDacl != NULL)
                             {
                                 ExFreePool(Token->DefaultDacl);
-                                Token->DefaultDacl = NULL;
                             }
+
+                            /* Set the new dacl */
+                            Token->DefaultDacl = CapturedAcl;
+                        }
+                    }
+                    else
+                    {
+                        /* Clear and free the default dacl if present */
+                        if (Token->DefaultDacl != NULL)
+                        {
+                            ExFreePool(Token->DefaultDacl);
+                            Token->DefaultDacl = NULL;
                         }
                     }
                 }
@@ -1594,47 +1743,44 @@ NtSetInformationToken(IN HANDLE TokenHandle,
                 }
                 break;
             }
-                
+
             case TokenSessionId:
             {
                 ULONG SessionId = 0;
-                
+
                 _SEH2_TRY
                 {
-                    /* buffer size was already verified, no need to check here again */
+                    /* Buffer size was already verified, no need to check here again */
                     SessionId = *(PULONG)TokenInformation;
                 }
                 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                 {
-                    Status = _SEH2_GetExceptionCode();
+                    _SEH2_YIELD(return _SEH2_GetExceptionCode());
                 }
                 _SEH2_END;
-                
-                if(NT_SUCCESS(Status))
+
+                if (!SeSinglePrivilegeCheck(SeTcbPrivilege,
+                                            PreviousMode))
                 {
-                    if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
-                                               PreviousMode))
-                    {
-                        Status = STATUS_PRIVILEGE_NOT_HELD;
-                        break;
-                    }
-                    
-                    Token->SessionId = SessionId;
+                    Status = STATUS_PRIVILEGE_NOT_HELD;
+                    break;
                 }
+
+                Token->SessionId = SessionId;
                 break;
             }
-                
+
             default:
             {
                 Status = STATUS_NOT_IMPLEMENTED;
                 break;
             }
         }
-        
+
         ObDereferenceObject(Token);
     }
-    
-    return(Status);
+
+    return Status;
 }
 
 
@@ -1660,13 +1806,13 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
     PTOKEN NewToken;
     PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService;
     BOOLEAN QoSPresent;
-    NTSTATUS Status = STATUS_SUCCESS;
-    
+    NTSTATUS Status;
+
     PAGED_CODE();
-    
+
     PreviousMode = KeGetPreviousMode();
-    
-    if(PreviousMode != KernelMode)
+
+    if (PreviousMode != KernelMode)
     {
         _SEH2_TRY
         {
@@ -1674,28 +1820,24 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        
-        if(!NT_SUCCESS(Status))
-        {
-            return Status;
-        }
     }
-    
+
     Status = SepCaptureSecurityQualityOfService(ObjectAttributes,
                                                 PreviousMode,
                                                 PagedPool,
                                                 FALSE,
                                                 &CapturedSecurityQualityOfService,
                                                 &QoSPresent);
-    if(!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
         DPRINT1("NtDuplicateToken() failed to capture QoS! Status: 0x%x\n", Status);
         return Status;
     }
-    
+
     Status = ObReferenceObjectByHandle(ExistingTokenHandle,
                                        TOKEN_DUPLICATE,
                                        SepTokenObjectType,
@@ -1711,9 +1853,9 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
                                    (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous),
                                    PreviousMode,
                                    &NewToken);
-        
+
         ObDereferenceObject(Token);
-        
+
         if (NT_SUCCESS(Status))
         {
             Status = ObInsertObject((PVOID)NewToken,
@@ -1722,7 +1864,7 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
                                     0,
                                     NULL,
                                     &hToken);
-            
+
             if (NT_SUCCESS(Status))
             {
                 _SEH2_TRY
@@ -1737,12 +1879,12 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
             }
         }
     }
-    
-    /* free the captured structure */
+
+    /* Free the captured structure */
     SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
                                        PreviousMode,
                                        FALSE);
-    
+
     return Status;
 }
 
@@ -1762,12 +1904,12 @@ NtAdjustGroupsToken(IN HANDLE TokenHandle,
  * @implemented
  */
 NTSTATUS NTAPI
-NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
-                         IN BOOLEAN DisableAllPrivileges,
-                         IN PTOKEN_PRIVILEGES NewState,
-                         IN ULONG BufferLength,
-                         OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL,
-                         OUT PULONG ReturnLength OPTIONAL)
+NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
+                        IN BOOLEAN DisableAllPrivileges,
+                        IN PTOKEN_PRIVILEGES NewState,
+                        IN ULONG BufferLength,
+                        OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL,
+                        OUT PULONG ReturnLength OPTIONAL)
 {
     //  PLUID_AND_ATTRIBUTES Privileges;
     KPROCESSOR_MODE PreviousMode;
@@ -1784,11 +1926,11 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
     ULONG c;
 #endif
     NTSTATUS Status;
-    
+
     PAGED_CODE();
-    
+
     DPRINT ("NtAdjustPrivilegesToken() called\n");
-    
+
     //  PrivilegeCount = NewState->PrivilegeCount;
     PreviousMode = KeGetPreviousMode ();
     //  SeCaptureLuidAndAttributesArray(NewState->Privileges,
@@ -1800,7 +1942,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
     //                                  1,
     //                                  &Privileges,
     //                                  &Length);
-    
+
     Status = ObReferenceObjectByHandle (TokenHandle,
                                         TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0),
                                         SepTokenObjectType,
@@ -1815,8 +1957,8 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
         //                                      0);
         return Status;
     }
-    
-    
+
+
 #if 0
     SepAdjustPrivileges(Token,
                         0,
@@ -1828,13 +1970,13 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
                         &b,
                         &c);
 #endif
-    
+
     PrivilegeCount = (BufferLength - FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges)) /
     sizeof(LUID_AND_ATTRIBUTES);
-    
+
     if (PreviousState != NULL)
         PreviousState->PrivilegeCount = 0;
-    
+
     k = 0;
     if (DisableAllPrivileges == TRUE)
     {
@@ -1843,7 +1985,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
             if (Token->Privileges[i].Attributes != 0)
             {
                 DPRINT ("Attributes differ\n");
-                
+
                 /* Save current privilege */
                 if (PreviousState != NULL)
                 {
@@ -1855,18 +1997,21 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
                     }
                     else
                     {
-                        /* FIXME: Should revert all the changes, calculate how
+                        /*
+                         * FIXME: Should revert all the changes, calculate how
                          * much space would be needed, set ResultLength
                          * accordingly and fail.
                          */
                     }
+
                     k++;
                 }
-                
+
                 /* Update current privlege */
                 Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
             }
         }
+
         Status = STATUS_SUCCESS;
     }
     else
@@ -1880,7 +2025,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
                     Token->Privileges[i].Luid.HighPart == NewState->Privileges[j].Luid.HighPart)
                 {
                     DPRINT ("Found privilege\n");
-                    
+
                     if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) !=
                         (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED))
                     {
@@ -1888,7 +2033,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
                         DPRINT ("Current attributes %lx  desired attributes %lx\n",
                                 Token->Privileges[i].Attributes,
                                 NewState->Privileges[j].Attributes);
-                        
+
                         /* Save current privilege */
                         if (PreviousState != NULL)
                         {
@@ -1900,14 +2045,16 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
                             }
                             else
                             {
-                                /* FIXME: Should revert all the changes, calculate how
+                                /*
+                                 * FIXME: Should revert all the changes, calculate how
                                  * much space would be needed, set ResultLength
                                  * accordingly and fail.
                                  */
                             }
+
                             k++;
                         }
-                        
+
                         /* Update current privlege */
                         Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
                         Token->Privileges[i].Attributes |=
@@ -1915,31 +2062,34 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
                         DPRINT ("New attributes %lx\n",
                                 Token->Privileges[i].Attributes);
                     }
+
                     Count++;
                 }
             }
         }
+
         Status = Count < NewState->PrivilegeCount ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS;
     }
-    
+
     if (ReturnLength != NULL)
     {
         *ReturnLength = sizeof(TOKEN_PRIVILEGES) +
         (sizeof(LUID_AND_ATTRIBUTES) * (k - 1));
     }
-    
+
     ObDereferenceObject (Token);
-    
+
     //  SeReleaseLuidAndAttributesArray(Privileges,
     //                                  PreviousMode,
     //                                  0);
-    
+
     DPRINT ("NtAdjustPrivilegesToken() done\n");
-    
+
     return Status;
 }
 
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 NtCreateToken(OUT PHANDLE TokenHandle,
               IN ACCESS_MASK DesiredAccess,
               IN POBJECT_ATTRIBUTES ObjectAttributes,
@@ -1955,22 +2105,16 @@ NtCreateToken(OUT PHANDLE TokenHandle,
               IN PTOKEN_SOURCE TokenSource)
 {
     HANDLE hToken;
-    PTOKEN AccessToken;
-    LUID TokenId;
-    LUID ModifiedId;
-    PVOID EndMem;
-    ULONG uLength;
-    ULONG i;
     KPROCESSOR_MODE PreviousMode;
     ULONG nTokenPrivileges = 0;
     LARGE_INTEGER LocalExpirationTime = {{0, 0}};
-    NTSTATUS Status = STATUS_SUCCESS;
-    
+    NTSTATUS Status;
+
     PAGED_CODE();
-    
+
     PreviousMode = ExGetPreviousMode();
-    
-    if(PreviousMode != KernelMode)
+
+    if (PreviousMode != KernelMode)
     {
         _SEH2_TRY
         {
@@ -2004,163 +2148,36 @@ NtCreateToken(OUT PHANDLE TokenHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        
-        if(!NT_SUCCESS(Status))
-        {
-            return Status;
-        }
     }
     else
     {
         nTokenPrivileges = TokenPrivileges->PrivilegeCount;
         LocalExpirationTime = *ExpirationTime;
     }
-    
-    Status = ZwAllocateLocallyUniqueId(&TokenId);
-    if (!NT_SUCCESS(Status))
-        return(Status);
-    
-    Status = ZwAllocateLocallyUniqueId(&ModifiedId);
-    if (!NT_SUCCESS(Status))
-        return(Status);
-    
-    Status = ObCreateObject(PreviousMode,
-                            SepTokenObjectType,
-                            ObjectAttributes,
-                            PreviousMode,
-                            NULL,
-                            sizeof(TOKEN),
-                            0,
-                            0,
-                            (PVOID*)&AccessToken);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("ObCreateObject() failed (Status %lx)\n");
-        return(Status);
-    }
 
-    /* Zero out the buffer */
-    RtlZeroMemory(AccessToken, sizeof(TOKEN));
-    
-    AccessToken->TokenLock = &SepTokenLock;
-    
-    RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier,
-                &TokenSource->SourceIdentifier);
-    memcpy(AccessToken->TokenSource.SourceName,
-           TokenSource->SourceName,
-           sizeof(TokenSource->SourceName));
-    
-    RtlCopyLuid(&AccessToken->TokenId, &TokenId);
-    RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId);
-    AccessToken->ExpirationTime = *ExpirationTime;
-    RtlCopyLuid(&AccessToken->ModifiedId, &ModifiedId);
-    
-    AccessToken->UserAndGroupCount = TokenGroups->GroupCount + 1;
-    AccessToken->PrivilegeCount    = TokenPrivileges->PrivilegeCount;
-    
-    AccessToken->TokenType = TokenType;
-    AccessToken->ImpersonationLevel = ((PSECURITY_QUALITY_OF_SERVICE)
-                                       (ObjectAttributes->SecurityQualityOfService))->ImpersonationLevel;
-    
-    /*
-     * Normally we would just point these members into the variable information
-     * area; however, our ObCreateObject() call can't allocate a variable information
-     * area, so we allocate them seperately and provide a destroy function.
-     */
-    
-    uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount;
-    uLength += RtlLengthSid(TokenUser->User.Sid);
-    for (i = 0; i < TokenGroups->GroupCount; i++)
-        uLength += RtlLengthSid(TokenGroups->Groups[i].Sid);
-    
-    AccessToken->UserAndGroups =
-    (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
-                                               uLength,
-                                               'uKOT');
-    
-    EndMem = &AccessToken->UserAndGroups[AccessToken->UserAndGroupCount];
-    
-    Status = RtlCopySidAndAttributesArray(1,
-                                          &TokenUser->User,
-                                          uLength,
-                                          AccessToken->UserAndGroups,
-                                          EndMem,
-                                          &EndMem,
-                                          &uLength);
-    if (NT_SUCCESS(Status))
-    {
-        Status = RtlCopySidAndAttributesArray(TokenGroups->GroupCount,
-                                              TokenGroups->Groups,
-                                              uLength,
-                                              &AccessToken->UserAndGroups[1],
-                                              EndMem,
-                                              &EndMem,
-                                              &uLength);
-    }
-    
-    if (NT_SUCCESS(Status))
-    {
-        Status = SepFindPrimaryGroupAndDefaultOwner(
-                                                    AccessToken,
-                                                    TokenPrimaryGroup->PrimaryGroup,
-                                                    TokenOwner->Owner);
-    }
-    
-    if (NT_SUCCESS(Status))
-    {
-        uLength = TokenPrivileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
-        AccessToken->Privileges =
-        (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
-                                                    uLength,
-                                                    'pKOT');
-        
-        if (PreviousMode != KernelMode)
-        {
-            _SEH2_TRY
-            {
-                RtlCopyMemory(AccessToken->Privileges,
-                              TokenPrivileges->Privileges,
-                              nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
-            }
-            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-            {
-                Status = _SEH2_GetExceptionCode();
-            }
-            _SEH2_END;
-        }
-        else
-        {
-            RtlCopyMemory(AccessToken->Privileges,
-                          TokenPrivileges->Privileges,
-                          nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
-        }
-    }
-    
-    if (NT_SUCCESS(Status))
-    {
-        AccessToken->DefaultDacl =
-        (PACL) ExAllocatePoolWithTag(PagedPool,
-                                     TokenDefaultDacl->DefaultDacl->AclSize,
-                                     'kDOT');
-        memcpy(AccessToken->DefaultDacl,
-               TokenDefaultDacl->DefaultDacl,
-               TokenDefaultDacl->DefaultDacl->AclSize);
-    }
-    
-    Status = ObInsertObject ((PVOID)AccessToken,
-                             NULL,
-                             DesiredAccess,
-                             0,
-                             NULL,
-                             &hToken);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("ObInsertObject() failed (Status %lx)\n", Status);
-    }
-    
+    Status = SepCreateToken(&hToken,
+                            PreviousMode,
+                            DesiredAccess,
+                            ObjectAttributes,
+                            TokenType,
+                            ((PSECURITY_QUALITY_OF_SERVICE)(ObjectAttributes->SecurityQualityOfService))->ImpersonationLevel,
+                            AuthenticationId,
+                            &LocalExpirationTime,
+                            &TokenUser->User,
+                            TokenGroups->GroupCount,
+                            TokenGroups->Groups,
+                            0, // FIXME: Should capture
+                            nTokenPrivileges,
+                            TokenPrivileges->Privileges,
+                            TokenOwner->Owner,
+                            TokenPrimaryGroup->PrimaryGroup,
+                            TokenDefaultDacl->DefaultDacl,
+                            TokenSource,
+                            FALSE);
     if (NT_SUCCESS(Status))
     {
         _SEH2_TRY
@@ -2173,7 +2190,7 @@ NtCreateToken(OUT PHANDLE TokenHandle,
         }
         _SEH2_END;
     }
-    
+
     return Status;
 }
 
@@ -2188,9 +2205,9 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
                     IN ULONG HandleAttributes,
                     OUT PHANDLE TokenHandle)
 {
-    PETHREAD Thread;
+    PETHREAD Thread, NewThread;
     HANDLE hToken;
-    PTOKEN Token, NewToken, PrimaryToken;
+    PTOKEN Token, NewToken = NULL, PrimaryToken;
     BOOLEAN CopyOnOpen, EffectiveOnly;
     SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
     SE_IMPERSONATION_STATE ImpersonationState;
@@ -2198,13 +2215,13 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
     SECURITY_DESCRIPTOR SecurityDescriptor;
     PACL Dacl = NULL;
     KPROCESSOR_MODE PreviousMode;
-    NTSTATUS Status = STATUS_SUCCESS;
-    
+    NTSTATUS Status;
+
     PAGED_CODE();
-    
+
     PreviousMode = ExGetPreviousMode();
-    
-    if(PreviousMode != KernelMode)
+
+    if (PreviousMode != KernelMode)
     {
         _SEH2_TRY
         {
@@ -2212,21 +2229,17 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        
-        if(!NT_SUCCESS(Status))
-        {
-            return Status;
-        }
     }
-    
+
     /*
      * At first open the thread token for information access and verify
      * that the token associated with thread is valid.
      */
-    
+
     Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION,
                                        PsThreadType, PreviousMode, (PVOID*)&Thread,
                                        NULL);
@@ -2234,7 +2247,7 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
     {
         return Status;
     }
-    
+
     Token = PsReferenceImpersonationToken(Thread, &CopyOnOpen, &EffectiveOnly,
                                           &ImpersonationLevel);
     if (Token == NULL)
@@ -2242,79 +2255,61 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
         ObDereferenceObject(Thread);
         return STATUS_NO_TOKEN;
     }
-    
-    ObDereferenceObject(Thread);
-    
+
     if (ImpersonationLevel == SecurityAnonymous)
     {
-        ObDereferenceObject(Token);
+        PsDereferenceImpersonationToken(Token);
+        ObDereferenceObject(Thread);
         return STATUS_CANT_OPEN_ANONYMOUS;
     }
-    
+
     /*
      * Revert to self if OpenAsSelf is specified.
      */
-    
+
     if (OpenAsSelf)
     {
         PsDisableImpersonation(PsGetCurrentThread(), &ImpersonationState);
     }
-    
+
     if (CopyOnOpen)
     {
         Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS,
-                                           PsThreadType, PreviousMode,
-                                           (PVOID*)&Thread, NULL);
-        if (!NT_SUCCESS(Status))
-        {
-            ObDereferenceObject(Token);
-            if (OpenAsSelf)
-            {
-                PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
-            }
-            return Status;
-        }
-        
-        PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);
-        Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl);
-        ASSERT(FALSE);
-        ObDereferenceObject(PrimaryToken);
-        ObDereferenceObject(Thread);
-        if (!NT_SUCCESS(Status))
-        {
-            ObDereferenceObject(Token);
-            if (OpenAsSelf)
-            {
-                PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
-            }
-            return Status;
-        }
-        
-        RtlCreateSecurityDescriptor(&SecurityDescriptor,
-                                    SECURITY_DESCRIPTOR_REVISION);
-        RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl,
-                                     FALSE);
-        
-        InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes,
-                                   NULL, &SecurityDescriptor);
-        
-        Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly,
-                                   TokenImpersonation, ImpersonationLevel,
-                                   KernelMode, &NewToken);
-        ExFreePool(Dacl);
-        if (!NT_SUCCESS(Status))
+                                           PsThreadType, KernelMode,
+                                           (PVOID*)&NewThread, NULL);
+        if (NT_SUCCESS(Status))
         {
-            ObDereferenceObject(Token);
-            if (OpenAsSelf)
+            PrimaryToken = PsReferencePrimaryToken(NewThread->ThreadsProcess);
+
+            Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl);
+
+            ObFastDereferenceObject(&NewThread->ThreadsProcess->Token, PrimaryToken);
+
+            if (NT_SUCCESS(Status))
             {
-                PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
+                if (Dacl)
+                {
+                    RtlCreateSecurityDescriptor(&SecurityDescriptor,
+                                                SECURITY_DESCRIPTOR_REVISION);
+                    RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl,
+                                                 FALSE);
+                }
+
+                InitializeObjectAttributes(&ObjectAttributes, NULL, HandleAttributes,
+                                           NULL, Dacl ? &SecurityDescriptor : NULL);
+
+
+                Status = SepDuplicateToken(Token, &ObjectAttributes, EffectiveOnly,
+                                           TokenImpersonation, ImpersonationLevel,
+                                           KernelMode, &NewToken);
+                if (NT_SUCCESS(Status))
+                {
+                    ObReferenceObject(NewToken);
+                    Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL,
+                                            &hToken);
+                }
             }
-            return Status;
         }
-        
-        Status = ObInsertObject(NewToken, NULL, DesiredAccess, 0, NULL,
-                                &hToken);
-        
     }
     else
     {
@@ -2322,15 +2317,26 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
                                        NULL, DesiredAccess, SepTokenObjectType,
                                        PreviousMode, &hToken);
     }
-    
-    ObDereferenceObject(Token);
-    
+
+    if (Dacl) ExFreePool(Dacl);
+
     if (OpenAsSelf)
     {
         PsRestoreImpersonation(PsGetCurrentThread(), &ImpersonationState);
     }
-    
-    if(NT_SUCCESS(Status))
+
+    ObDereferenceObject(Token);
+
+    if (NT_SUCCESS(Status) && CopyOnOpen)
+    {
+        PsImpersonateClient(Thread, NewToken, FALSE, EffectiveOnly, ImpersonationLevel);
+    }
+
+    if (NewToken) ObDereferenceObject(NewToken);
+
+    if (CopyOnOpen && NewThread) ObDereferenceObject(NewThread);
+
+    if (NT_SUCCESS(Status))
     {
         _SEH2_TRY
         {
@@ -2342,7 +2348,7 @@ NtOpenThreadTokenEx(IN HANDLE ThreadHandle,
         }
         _SEH2_END;
     }
-    
+
     return Status;
 }
 
@@ -2373,12 +2379,12 @@ NtCompareTokens(IN HANDLE FirstTokenHandle,
     KPROCESSOR_MODE PreviousMode;
     PTOKEN FirstToken, SecondToken;
     BOOLEAN IsEqual;
-    NTSTATUS Status = STATUS_SUCCESS;
-    
+    NTSTATUS Status;
+
     PAGED_CODE();
-    
+
     PreviousMode = ExGetPreviousMode();
-    
+
     if (PreviousMode != KernelMode)
     {
         _SEH2_TRY
@@ -2387,14 +2393,12 @@ NtCompareTokens(IN HANDLE FirstTokenHandle,
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            Status = _SEH2_GetExceptionCode();
+            /* Return the exception code */
+            _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
-        
-        if (!NT_SUCCESS(Status))
-            return Status;
     }
-    
+
     Status = ObReferenceObjectByHandle(FirstTokenHandle,
                                        TOKEN_QUERY,
                                        SepTokenObjectType,
@@ -2403,7 +2407,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle,
                                        NULL);
     if (!NT_SUCCESS(Status))
         return Status;
-    
+
     Status = ObReferenceObjectByHandle(SecondTokenHandle,
                                        TOKEN_QUERY,
                                        SepTokenObjectType,
@@ -2415,7 +2419,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle,
         ObDereferenceObject(FirstToken);
         return Status;
     }
-    
+
     if (FirstToken != SecondToken)
     {
         Status = SepCompareTokens(FirstToken,
@@ -2424,10 +2428,10 @@ NtCompareTokens(IN HANDLE FirstTokenHandle,
     }
     else
         IsEqual = TRUE;
-    
+
     ObDereferenceObject(FirstToken);
     ObDereferenceObject(SecondToken);
-    
+
     if (NT_SUCCESS(Status))
     {
         _SEH2_TRY
@@ -2440,7 +2444,7 @@ NtCompareTokens(IN HANDLE FirstTokenHandle,
         }
         _SEH2_END;
     }
-    
+
     return Status;
 }