[NTOSKRNL] On process primary token change, dereference device map
[reactos.git] / ntoskrnl / ps / security.c
index f696d0f..619ff56 100644 (file)
@@ -217,18 +217,18 @@ PspSetPrimaryToken(IN PEPROCESS Process,
                    IN PACCESS_TOKEN Token OPTIONAL)
 {
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
-    BOOLEAN IsChild;
+    BOOLEAN IsChildOrSibling;
     PACCESS_TOKEN NewToken = Token;
     NTSTATUS Status, AccessStatus;
     BOOLEAN Result, SdAllocated;
     PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
     SECURITY_SUBJECT_CONTEXT SubjectContext;
+
     PSTRACE(PS_SECURITY_DEBUG, "Process: %p Token: %p\n", Process, Token);
 
-    /* Make sure we got a handle */
-    if (TokenHandle)
+    /* Reference the token by handle if we don't already have a token object */
+    if (!Token)
     {
-        /* Reference it */
         Status = ObReferenceObjectByHandle(TokenHandle,
                                            TOKEN_ASSIGN_PRIMARY,
                                            SeTokenObjectType,
@@ -238,24 +238,38 @@ PspSetPrimaryToken(IN PEPROCESS Process,
         if (!NT_SUCCESS(Status)) return Status;
     }
 
-    /* Check if this is a child */
-    Status = SeIsTokenChild(NewToken, &IsChild);
+    /*
+     * Check whether this token is a child or sibling of the current process token.
+     * NOTE: On Windows Vista+ both of these checks (together with extra steps)
+     * are now performed by a new SeIsTokenAssignableToProcess() helper.
+     */
+    Status = SeIsTokenChild(NewToken, &IsChildOrSibling);
     if (!NT_SUCCESS(Status))
     {
         /* Failed, dereference */
-        if (TokenHandle) ObDereferenceObject(NewToken);
+        if (!Token) ObDereferenceObject(NewToken);
         return Status;
     }
+    if (!IsChildOrSibling)
+    {
+        Status = SeIsTokenSibling(NewToken, &IsChildOrSibling);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Failed, dereference */
+            if (!Token) ObDereferenceObject(NewToken);
+            return Status;
+        }
+    }
 
     /* Check if this was an independent token */
-    if (!IsChild)
+    if (!IsChildOrSibling)
     {
         /* Make sure we have the privilege to assign a new one */
         if (!SeSinglePrivilegeCheck(SeAssignPrimaryTokenPrivilege,
                                     PreviousMode))
         {
             /* Failed, dereference */
-            if (TokenHandle) ObDereferenceObject(NewToken);
+            if (!Token) ObDereferenceObject(NewToken);
             return STATUS_PRIVILEGE_NOT_HELD;
         }
     }
@@ -311,10 +325,18 @@ PspSetPrimaryToken(IN PEPROCESS Process,
                                        STANDARD_RIGHTS_ALL |
                                        PROCESS_SET_QUOTA);
         }
+
+        /*
+         * In case LUID device maps are enable, we may not be using
+         * system device map for this process, but a logon LUID based
+         * device map. Because we change primary token, this usage is
+         * no longer valid, so dereference the process device map
+         */
+        if (ObIsLUIDDeviceMapsEnabled()) ObDereferenceDeviceMap(Process);
     }
 
     /* Dereference the token */
-    if (TokenHandle) ObDereferenceObject(NewToken);
+    if (!Token) ObDereferenceObject(NewToken);
     return Status;
 }