https://git.reactos.org/?p=reactos.git;a=commitdiff;h=69ca7258d010ae68c1899…
commit 69ca7258d010ae68c18990a3e8a735dd0b351341
Author: George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Sat Feb 6 18:22:03 2021 +0100
Commit: Victor Perevertkin <victor(a)perevertkin.ru>
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 <george.bisoc(a)reactos.org>
+ */
+
+#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 },