https://git.reactos.org/?p=reactos.git;a=commitdiff;h=69ca7258d010ae68c18990a3e8a735dd0b351341

commit 69ca7258d010ae68c18990a3e8a735dd0b351341
Author:     George Bișoc <[email protected]>
AuthorDate: Sat Feb 6 18:22:03 2021 +0100
Commit:     Victor Perevertkin <[email protected]>
CommitDate: Thu Mar 4 16:22:56 2021 +0300

    [NTDLL_APITEST] Implement testcase for NtCompareTokens
---
 modules/rostests/apitests/ntdll/CMakeLists.txt    |   1 +
 modules/rostests/apitests/ntdll/NtCompareTokens.c | 109 ++++++++++++++++++++++
 modules/rostests/apitests/ntdll/testlist.c        |   2 +
 3 files changed, 112 insertions(+)

diff --git a/modules/rostests/apitests/ntdll/CMakeLists.txt 
b/modules/rostests/apitests/ntdll/CMakeLists.txt
index 0ed66a9fed6..c8f9cbc207e 100644
--- a/modules/rostests/apitests/ntdll/CMakeLists.txt
+++ b/modules/rostests/apitests/ntdll/CMakeLists.txt
@@ -10,6 +10,7 @@ list(APPEND SOURCE
     NtAcceptConnectPort.c
     NtAllocateVirtualMemory.c
     NtApphelpCacheControl.c
+    NtCompareTokens.c
     NtContinue.c
     NtCreateFile.c
     NtCreateKey.c
diff --git a/modules/rostests/apitests/ntdll/NtCompareTokens.c 
b/modules/rostests/apitests/ntdll/NtCompareTokens.c
new file mode 100644
index 00000000000..5b8af9aebb8
--- /dev/null
+++ b/modules/rostests/apitests/ntdll/NtCompareTokens.c
@@ -0,0 +1,109 @@
+/*
+ * PROJECT:         ReactOS API tests
+ * LICENSE:         GPL-2.0-or-later 
(https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:         Tests for the NtCompareTokens API
+ * COPYRIGHT:       Copyright 2021 George Bișoc <[email protected]>
+ */
+
+#include "precomp.h"
+
+static
+HANDLE
+GetTokenFromCurrentProcess(VOID)
+{
+    BOOL Success;
+    HANDLE Token;
+
+    Success = OpenProcessToken(GetCurrentProcess(),
+                               TOKEN_READ | TOKEN_ADJUST_PRIVILEGES | 
TOKEN_DUPLICATE,
+                               &Token);
+    if (!Success)
+    {
+        skip("OpenProcessToken() has failed to get the process' token (error 
code: %lu)!\n", GetLastError());
+        return NULL;
+    }
+
+    return Token;
+}
+
+static
+HANDLE
+GetDuplicateToken(_In_ HANDLE Token)
+{
+    BOOL Success;
+    HANDLE ReturnedToken;
+
+    Success = DuplicateToken(Token, SecurityIdentification, &ReturnedToken);
+    if (!Success)
+    {
+        skip("DuplicateToken() has failed to get the process' token (error 
code: %lu)!\n", GetLastError());
+        return NULL;
+    }
+
+    return ReturnedToken;
+}
+
+static
+VOID
+DisableTokenPrivileges(_In_ HANDLE Token)
+{
+    BOOL Success;
+
+    Success = AdjustTokenPrivileges(Token, TRUE, NULL, 0, NULL, NULL);
+    if (!Success)
+    {
+        skip("AdjustTokenPrivileges() has failed to disable the privileges 
(error code: %lu)!\n", GetLastError());
+        return;
+    }
+}
+
+START_TEST(NtCompareTokens)
+{
+    NTSTATUS Status;
+    HANDLE ProcessToken = NULL;
+    HANDLE DuplicatedToken = NULL;
+    BOOLEAN IsEqual = FALSE;
+
+    /* Obtain some tokens from current process */
+    ProcessToken = GetTokenFromCurrentProcess();
+    DuplicatedToken = GetDuplicateToken(ProcessToken);
+
+    /*
+     * Give invalid token handles and don't output
+     * the returned value in the last parameter.
+     */
+    Status = NtCompareTokens(NULL, NULL, NULL);
+    ok_hex(Status, STATUS_ACCESS_VIOLATION);
+
+    /*
+     * Token handles are valid but don't output
+     * the returned value.
+     */
+    Status = NtCompareTokens(ProcessToken, ProcessToken, NULL);
+    ok_hex(Status, STATUS_ACCESS_VIOLATION);
+
+    /* The tokens are the same */
+    Status = NtCompareTokens(ProcessToken, ProcessToken, &IsEqual);
+    ok_hex(Status, STATUS_SUCCESS);
+    ok(IsEqual == TRUE, "Equal tokens expected but they aren't (current value: 
%u)!\n", IsEqual);
+
+    /* A token is duplicated with equal SIDs and privileges */
+    Status = NtCompareTokens(ProcessToken, DuplicatedToken, &IsEqual);
+    ok_hex(Status, STATUS_SUCCESS);
+    ok(IsEqual == TRUE, "Equal tokens expected but they aren't (current value: 
%u)!\n", IsEqual);
+
+    /* Disable all the privileges for token. */
+    DisableTokenPrivileges(ProcessToken);
+
+    /*
+     * The main token has privileges disabled but the
+     * duplicated one has them enabled still.
+     */
+    Status = NtCompareTokens(ProcessToken, DuplicatedToken, &IsEqual);
+    ok_hex(Status, STATUS_SUCCESS);
+    ok(IsEqual == FALSE, "Tokens mustn't be equal (current value: %u)!\n", 
IsEqual);
+
+    /* We finished our tests, close the tokens */
+    CloseHandle(ProcessToken);
+    CloseHandle(DuplicatedToken);
+}
diff --git a/modules/rostests/apitests/ntdll/testlist.c 
b/modules/rostests/apitests/ntdll/testlist.c
index a1de8c81629..a65d6770dcd 100644
--- a/modules/rostests/apitests/ntdll/testlist.c
+++ b/modules/rostests/apitests/ntdll/testlist.c
@@ -8,6 +8,7 @@ extern void func_load_notifications(void);
 extern void func_NtAcceptConnectPort(void);
 extern void func_NtAllocateVirtualMemory(void);
 extern void func_NtApphelpCacheControl(void);
+extern void func_NtCompareTokens(void);
 extern void func_NtContinue(void);
 extern void func_NtCreateFile(void);
 extern void func_NtCreateKey(void);
@@ -84,6 +85,7 @@ const struct test winetest_testlist[] =
     { "NtAcceptConnectPort",            func_NtAcceptConnectPort },
     { "NtAllocateVirtualMemory",        func_NtAllocateVirtualMemory },
     { "NtApphelpCacheControl",          func_NtApphelpCacheControl },
+    { "NtCompareTokens",                func_NtCompareTokens },
     { "NtContinue",                     func_NtContinue },
     { "NtCreateFile",                   func_NtCreateFile },
     { "NtCreateKey",                    func_NtCreateKey },

Reply via email to