From dfc4dcb9b5c30a1de568eb82677763743dc663f1 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 30 May 2010 19:46:02 +0000 Subject: [PATCH] [NTOSKRNL] Make NtDuplicateToken fail if the caller tries to create a new impersonation token with a raised impersonation level. This fixes a winetest. svn path=/trunk/; revision=47456 --- reactos/ntoskrnl/se/token.c | 74 ++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/reactos/ntoskrnl/se/token.c b/reactos/ntoskrnl/se/token.c index 30f7fc84bef..04fe7c2a5b0 100644 --- a/reactos/ntoskrnl/se/token.c +++ b/reactos/ntoskrnl/se/token.c @@ -1844,39 +1844,61 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle, PreviousMode, (PVOID*)&Token, NULL); - if (NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { - Status = SepDuplicateToken(Token, - ObjectAttributes, - EffectiveOnly, - TokenType, - (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous), - PreviousMode, - &NewToken); + SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService, + PreviousMode, + FALSE); + return Status; + } - ObDereferenceObject(Token); + /* + * 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 = 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; } } -- 2.17.1