X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fps%2Fsecurity.c;h=619ff56d2472d578f5c5acaf49d7b13a26c32038;hp=4a9c0916d821efcf4041ce6e1e1e2ead82d143a1;hb=f8a4d31da489660d48975a685da49fb1f4748685;hpb=43c7fc0c8d67f5c3bb0ceb5bc877192b5e7fcdc3 diff --git a/ntoskrnl/ps/security.c b/ntoskrnl/ps/security.c index 4a9c0916d82..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,35 +713,19 @@ 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); /* Check if we don't have impersonation info */ Process = Thread->ThreadsProcess; - if (!Thread->ActiveImpersonationInfo) - { - /* Fast Reference the Token */ - Token = ObFastReferenceObject(&Process->Token); - - /* Check if we got the Token or if we got locked */ - if (!Token) - { - /* Lock the Process */ - PspLockProcessSecurityShared(Process); - - /* Do a Locked Fast Reference */ - Token = ObFastReferenceObjectLocked(&Process->Token); - - /* Unlock the Process */ - PspUnlockProcessSecurityShared(Process); - } - } - else + if (Thread->ActiveImpersonationInfo) { /* Lock the Process */ PspLockProcessSecurityShared(Process); @@ -731,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); @@ -742,9 +751,26 @@ PsReferenceEffectiveToken(IN PETHREAD Thread, PspUnlockProcessSecurityShared(Process); } + /* Fast Reference the Token */ + Token = ObFastReferenceObject(&Process->Token); + + /* Check if we got the Token or if we got locked */ + if (!Token) + { + /* Lock the Process */ + PspLockProcessSecurityShared(Process); + + /* Do a Locked Fast Reference */ + Token = ObFastReferenceObjectLocked(&Process->Token); + + /* Unlock the Process */ + PspUnlockProcessSecurityShared(Process); + } + /* Return the token */ *TokenType = TokenPrimary; *EffectiveOnly = FALSE; + // NOTE: ImpersonationLevel is left untouched on purpose! return Token; } @@ -820,10 +846,10 @@ PsDereferencePrimaryToken(IN PACCESS_TOKEN PrimaryToken) BOOLEAN NTAPI PsDisableImpersonation(IN PETHREAD Thread, - IN PSE_IMPERSONATION_STATE ImpersonationState) + OUT PSE_IMPERSONATION_STATE ImpersonationState) { PPS_IMPERSONATION_INFORMATION Impersonation = NULL; - LONG NewValue, OldValue; + LONG OldFlags; PAGED_CODE(); PSTRACE(PS_SECURITY_DEBUG, "Thread: %p State: %p\n", Thread, ImpersonationState); @@ -835,19 +861,11 @@ PsDisableImpersonation(IN PETHREAD Thread, PspLockThreadSecurityExclusive(Thread); /* Disable impersonation */ - OldValue = Thread->CrossThreadFlags; - do - { - /* Attempt to change the flag */ - NewValue = - InterlockedCompareExchange((PLONG)&Thread->CrossThreadFlags, - OldValue &~ - CT_ACTIVE_IMPERSONATION_INFO_BIT, - OldValue); - } while (NewValue != OldValue); + OldFlags = PspClearCrossThreadFlag(Thread, + CT_ACTIVE_IMPERSONATION_INFO_BIT); /* Make sure nobody disabled it behind our back */ - if (NewValue & CT_ACTIVE_IMPERSONATION_INFO_BIT) + if (OldFlags & CT_ACTIVE_IMPERSONATION_INFO_BIT) { /* Copy the old state */ Impersonation = Thread->ImpersonationInfo;