X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fps%2Fsecurity.c;h=619ff56d2472d578f5c5acaf49d7b13a26c32038;hp=5c8e717607162d8511a7682157ea90bf95466160;hb=f8a4d31da489660d48975a685da49fb1f4748685;hpb=121bde3b8395efc794a463fcfc636cad7126d8cd diff --git a/ntoskrnl/ps/security.c b/ntoskrnl/ps/security.c index 5c8e7176071..619ff56d247 100644 --- a/ntoskrnl/ps/security.c +++ b/ntoskrnl/ps/security.c @@ -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; } @@ -371,6 +393,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 +713,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 +740,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 +770,7 @@ PsReferenceEffectiveToken(IN PETHREAD Thread, /* Return the token */ *TokenType = TokenPrimary; *EffectiveOnly = FALSE; + // NOTE: ImpersonationLevel is left untouched on purpose! return Token; }