https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5222eae73085ed04404d2…
commit 5222eae73085ed04404d2d712868a1b2c784faaf
Author: George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Fri Mar 26 13:38:04 2021 +0100
Commit: George Bișoc <george.bisoc(a)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(a)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 },