Author: ekohl Date: Sun May 30 21:46:02 2010 New Revision: 47456 URL: http://svn.reactos.org/svn/reactos?rev=47456&view=rev Log: [NTOSKRNL] Make NtDuplicateToken fail if the caller tries to create a new impersonation token with a raised impersonation level. This fixes a winetest.
Modified: trunk/reactos/ntoskrnl/se/token.c Modified: trunk/reactos/ntoskrnl/se/token.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/token.c?rev=47456&r1=47455&r2=47456&view=diff ============================================================================== --- trunk/reactos/ntoskrnl/se/token.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/se/token.c [iso-8859-1] Sun May 30 21:46:02 2010 @@ -1844,39 +1844,61 @@ PreviousMode, (PVOID*)&Token, NULL); + if (!NT_SUCCESS(Status)) + { + SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, + PreviousMode, + FALSE); + return Status; + } + + /* + * Fail, if the original token is an impersonation token and the caller + * tries to raise the impersonation level of the new token above the + * impersonation level of the original token. + */ + if (Token->TokenType == TokenImpersonation) + { + if (QoSPresent && + CapturedSecurityQualityOfService->ImpersonationLevel >Token->ImpersonationLevel) + { + ObDereferenceObject(Token); + SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, + PreviousMode, + FALSE); + return STATUS_BAD_IMPERSONATION_LEVEL; + } + } + + Status = SepDuplicateToken(Token, + ObjectAttributes, + EffectiveOnly, + TokenType, + (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous), + PreviousMode, + &NewToken); + + ObDereferenceObject(Token); + if (NT_SUCCESS(Status)) { - Status = SepDuplicateToken(Token, - ObjectAttributes, - EffectiveOnly, - TokenType, - (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous), - PreviousMode, - &NewToken); - - ObDereferenceObject(Token); - + Status = ObInsertObject((PVOID)NewToken, + NULL, + DesiredAccess, + 0, + NULL, + &hToken); if (NT_SUCCESS(Status)) { - Status = ObInsertObject((PVOID)NewToken, - NULL, - DesiredAccess, - 0, - NULL, - &hToken); - - if (NT_SUCCESS(Status)) + _SEH2_TRY { - _SEH2_TRY - { - *NewTokenHandle = hToken; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; + *NewTokenHandle = hToken; } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; } }