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,
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;
}
}
}
/* Dereference the token */
- if (TokenHandle) ObDereferenceObject(NewToken);
+ if (!Token) ObDereferenceObject(NewToken);
return Status;
}
_SEH2_END;
}
+ /* Validate object attributes */
+ HandleAttributes = ObpValidateAttributes(HandleAttributes, PreviousMode);
+
/* Open the process token */
Status = PsOpenTokenOfProcess(ProcessHandle, &Token);
if (NT_SUCCESS(Status))
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);
/* Return data to caller */
*TokenType = TokenImpersonation;
*EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
- *Level = Thread->ImpersonationInfo->ImpersonationLevel;
+ *ImpersonationLevel = Thread->ImpersonationInfo->ImpersonationLevel;
/* Unlock the Process */
PspUnlockProcessSecurityShared(Process);
/* Return the token */
*TokenType = TokenPrimary;
*EffectiveOnly = FALSE;
+ // NOTE: ImpersonationLevel is left untouched on purpose!
return Token;
}