[NTOSKRNL] Add a raw implementation of !irpfind in kdbg
[reactos.git] / ntoskrnl / ps / security.c
index 5c8e717..e245dde 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;
         }
     }
@@ -314,7 +328,7 @@ PspSetPrimaryToken(IN PEPROCESS Process,
     }
 
     /* Dereference the token */
-    if (TokenHandle) ObDereferenceObject(NewToken);
+    if (!Token) ObDereferenceObject(NewToken);
     return Status;
 }
 
@@ -371,6 +385,9 @@ NtOpenProcessTokenEx(IN HANDLE ProcessHandle,
         _SEH2_END;
     }
 
+    /* Validate object attributes */
+    HandleAttributes = ObpValidateAttributes(HandleAttributes, PreviousMode);
+
     /* Open the process token */
     Status = PsOpenTokenOfProcess(ProcessHandle, &Token);
     if (NT_SUCCESS(Status))
@@ -688,11 +705,13 @@ NTAPI
 PsReferenceEffectiveToken(IN PETHREAD Thread,
                           OUT IN PTOKEN_TYPE TokenType,
                           OUT PBOOLEAN EffectiveOnly,
-                          OUT PSECURITY_IMPERSONATION_LEVEL Level)
+                          OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
 {
     PEPROCESS Process;
     PACCESS_TOKEN Token = NULL;
+
     PAGED_CODE();
+
     PSTRACE(PS_SECURITY_DEBUG,
             "Thread: %p, TokenType: %p\n", Thread, TokenType);
 
@@ -713,7 +732,7 @@ PsReferenceEffectiveToken(IN PETHREAD Thread,
             /* Return data to caller */
             *TokenType = TokenImpersonation;
             *EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
-            *Level = Thread->ImpersonationInfo->ImpersonationLevel;
+            *ImpersonationLevel = Thread->ImpersonationInfo->ImpersonationLevel;
 
             /* Unlock the Process */
             PspUnlockProcessSecurityShared(Process);
@@ -743,6 +762,7 @@ PsReferenceEffectiveToken(IN PETHREAD Thread,
     /* Return the token */
     *TokenType = TokenPrimary;
     *EffectiveOnly = FALSE;
+    // NOTE: ImpersonationLevel is left untouched on purpose!
     return Token;
 }