https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5222eae73085ed04404d2d...
commit 5222eae73085ed04404d2d712868a1b2c784faaf Author: George Bișoc george.bisoc@reactos.org AuthorDate: Fri Mar 26 13:38:04 2021 +0100 Commit: George Bișoc george.bisoc@reactos.org CommitDate: Tue Apr 27 12:25:03 2021 +0200
[NTDLL_APITEST] Implement NtImpersonateAnonymousToken testcase --- modules/rostests/apitests/ntdll/CMakeLists.txt | 1 + .../apitests/ntdll/NtImpersonateAnonymousToken.c | 112 +++++++++++++++++++++ modules/rostests/apitests/ntdll/testlist.c | 2 + 3 files changed, 115 insertions(+)
diff --git a/modules/rostests/apitests/ntdll/CMakeLists.txt b/modules/rostests/apitests/ntdll/CMakeLists.txt index c8f9cbc207e..24844b98f4b 100644 --- a/modules/rostests/apitests/ntdll/CMakeLists.txt +++ b/modules/rostests/apitests/ntdll/CMakeLists.txt @@ -18,6 +18,7 @@ list(APPEND SOURCE NtDeleteKey.c NtDuplicateObject.c NtFreeVirtualMemory.c + NtImpersonateAnonymousToken.c NtLoadUnloadKey.c NtMapViewOfSection.c NtMutant.c diff --git a/modules/rostests/apitests/ntdll/NtImpersonateAnonymousToken.c b/modules/rostests/apitests/ntdll/NtImpersonateAnonymousToken.c new file mode 100644 index 00000000000..22a81ba5785 --- /dev/null +++ b/modules/rostests/apitests/ntdll/NtImpersonateAnonymousToken.c @@ -0,0 +1,112 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Tests for the NtImpersonateAnonymousToken API + * COPYRIGHT: Copyright 2021 George Bișoc george.bisoc@reactos.org + */ + +#include "precomp.h" +#include <winreg.h> + +#define TOKEN_WITH_EVERYONE_GROUP 1 +#define TOKEN_WITHOUT_EVERYONE_GROUP 0 + +static +HANDLE +GetThreadFromCurrentProcess(_In_ DWORD DesiredAccess) +{ + HANDLE Thread; + + Thread = OpenThread(DesiredAccess, FALSE, GetCurrentThreadId()); + if (!Thread) + { + skip("OpenThread() has failed to open the current process' thread (error code: %lu)\n", GetLastError()); + return NULL; + } + + return Thread; +} + +static +VOID +ImpersonateTokenWithEveryoneOrWithout(_In_ DWORD Value) +{ + LONG Result; + HKEY Key; + + Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + L"SYSTEM\CurrentControlSet\Control\Lsa", + 0, + KEY_SET_VALUE, + &Key); + if (Result != ERROR_SUCCESS) + { + skip("RegOpenKeyExW() has failed to open the key (error code: %li)\n", Result); + return; + } + + Result = RegSetValueExW(Key, + L"EveryoneIncludesAnonymous", + 0, + REG_DWORD, + (PBYTE)&Value, + sizeof(Value)); + if (Result != ERROR_SUCCESS) + { + skip("RegSetValueExW() has failed to set the value (error code: %li)\n", Result); + RegCloseKey(Key); + return; + } + + RegCloseKey(Key); +} + +START_TEST(NtImpersonateAnonymousToken) +{ + NTSTATUS Status; + BOOL Success; + HANDLE ThreadHandle; + + ThreadHandle = GetThreadFromCurrentProcess(THREAD_IMPERSONATE); + + /* We give an invalid thread handle */ + Status = NtImpersonateAnonymousToken(NULL); + ok_hex(Status, STATUS_INVALID_HANDLE); + + /* We want to impersonate the token including Everyone Group SID */ + ImpersonateTokenWithEveryoneOrWithout(TOKEN_WITH_EVERYONE_GROUP); + + /* Impersonate the anonymous logon token */ + Status = NtImpersonateAnonymousToken(ThreadHandle); + ok_hex(Status, STATUS_SUCCESS); + + /* Now revert to the previous security properties */ + Success = RevertToSelf(); + ok(Success == TRUE, "We should have terminated the impersonation but we couldn't (error code: %lu)\n", GetLastError()); + + /* Return to default setting -- token without Everyone Group SID */ + ImpersonateTokenWithEveryoneOrWithout(TOKEN_WITHOUT_EVERYONE_GROUP); + + /* Impersonate the anonymous logon token again */ + Status = NtImpersonateAnonymousToken(ThreadHandle); + ok_hex(Status, STATUS_SUCCESS); + + /* Now revert to the previous security properties */ + Success = RevertToSelf(); + ok(Success == TRUE, "We should have terminated the impersonation but we couldn't (error code: %lu)\n", GetLastError()); + + /* + * Invalidate the handle and open a new one. This time + * with the wrong access right mask, the function will + * outright fail on impersonating the token. + */ + CloseHandle(ThreadHandle); + ThreadHandle = GetThreadFromCurrentProcess(SYNCHRONIZE); + + /* The thread handle has incorrect right access */ + Status = NtImpersonateAnonymousToken(ThreadHandle); + ok_hex(Status, STATUS_ACCESS_DENIED); + + /* We're done with the tests */ + CloseHandle(ThreadHandle); +} diff --git a/modules/rostests/apitests/ntdll/testlist.c b/modules/rostests/apitests/ntdll/testlist.c index a65d6770dcd..8b7df571591 100644 --- a/modules/rostests/apitests/ntdll/testlist.c +++ b/modules/rostests/apitests/ntdll/testlist.c @@ -16,6 +16,7 @@ extern void func_NtCreateThread(void); extern void func_NtDeleteKey(void); extern void func_NtDuplicateObject(void); extern void func_NtFreeVirtualMemory(void); +extern void func_NtImpersonateAnonymousToken(void); extern void func_NtLoadUnloadKey(void); extern void func_NtMapViewOfSection(void); extern void func_NtMutant(void); @@ -93,6 +94,7 @@ const struct test winetest_testlist[] = { "NtDeleteKey", func_NtDeleteKey }, { "NtDuplicateObject", func_NtDuplicateObject }, { "NtFreeVirtualMemory", func_NtFreeVirtualMemory }, + { "NtImpersonateAnonymousToken", func_NtImpersonateAnonymousToken }, { "NtLoadUnloadKey", func_NtLoadUnloadKey }, { "NtMapViewOfSection", func_NtMapViewOfSection }, { "NtMutant", func_NtMutant },