https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5222eae73085ed04404d2d712868a1b2c784faaf

commit 5222eae73085ed04404d2d712868a1b2c784faaf
Author:     George Bișoc <[email protected]>
AuthorDate: Fri Mar 26 13:38:04 2021 +0100
Commit:     George Bișoc <[email protected]>
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 <[email protected]>
+ */
+
+#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 },

Reply via email to