https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6fe1b387c6f5a582fedeac7c17d84440a1df74d3

commit 6fe1b387c6f5a582fedeac7c17d84440a1df74d3
Author:     George Bișoc <[email protected]>
AuthorDate: Tue Oct 19 11:36:02 2021 +0200
Commit:     George Bișoc <[email protected]>
CommitDate: Sun Nov 7 14:14:18 2021 +0100

    [NTDLL_APITEST] Implement NtFilterToken testcase
---
 modules/rostests/apitests/ntdll/CMakeLists.txt  |   1 +
 modules/rostests/apitests/ntdll/NtFilterToken.c | 137 ++++++++++++++++++++++++
 modules/rostests/apitests/ntdll/testlist.c      |   2 +
 3 files changed, 140 insertions(+)

diff --git a/modules/rostests/apitests/ntdll/CMakeLists.txt 
b/modules/rostests/apitests/ntdll/CMakeLists.txt
index 403641119fb..1e69ecf4900 100644
--- a/modules/rostests/apitests/ntdll/CMakeLists.txt
+++ b/modules/rostests/apitests/ntdll/CMakeLists.txt
@@ -22,6 +22,7 @@ list(APPEND SOURCE
     NtDeleteKey.c
     NtDuplicateObject.c
     NtDuplicateToken.c
+    NtFilterToken.c
     NtFreeVirtualMemory.c
     NtImpersonateAnonymousToken.c
     NtLoadUnloadKey.c
diff --git a/modules/rostests/apitests/ntdll/NtFilterToken.c 
b/modules/rostests/apitests/ntdll/NtFilterToken.c
new file mode 100644
index 00000000000..60453c9bf87
--- /dev/null
+++ b/modules/rostests/apitests/ntdll/NtFilterToken.c
@@ -0,0 +1,137 @@
+/*
+ * PROJECT:         ReactOS API tests
+ * LICENSE:         GPL-2.0-or-later 
(https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:         Tests for the NtFilterToken API
+ * COPYRIGHT:       Copyright 2021 George Bișoc <[email protected]>
+ */
+
+#include "precomp.h"
+
+static
+HANDLE
+GetTokenProcess(VOID)
+{
+    BOOL Success;
+    HANDLE Token;
+
+    Success = OpenProcessToken(GetCurrentProcess(),
+                               TOKEN_DUPLICATE | TOKEN_QUERY,
+                               &Token);
+    if (!Success)
+    {
+        skip("GetTokenProcess() has failed to get the process' token (error 
code: %lu)!\n", GetLastError());
+        return NULL;
+    }
+
+    return Token;
+}
+
+START_TEST(NtFilterToken)
+{
+    NTSTATUS Status;
+    HANDLE FilteredToken, Token;
+    TOKEN_PRIVILEGES Priv;
+    LUID PrivLuid;
+    ULONG Size;
+    PTOKEN_STATISTICS TokenStats;
+
+    /* We don't give a token */
+    Status = NtFilterToken(NULL,
+                           0,
+                           NULL,
+                           NULL,
+                           NULL,
+                           &FilteredToken);
+    ok_hex(Status, STATUS_INVALID_HANDLE);
+
+    /* Get the token from process now */
+    Token = GetTokenProcess();
+
+    /* We don't give any privileges to delete */
+    Status = NtFilterToken(Token,
+                           0,
+                           NULL,
+                           NULL,
+                           NULL,
+                           &FilteredToken);
+    ok_hex(Status, STATUS_SUCCESS);
+
+    /* Query the total size to hold the statistics */
+    Status = NtQueryInformationToken(Token, TokenStatistics, NULL, 0, &Size);
+    if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
+    {
+        skip("Failed to query the total size for token statistics structure! 
(Status -> 0x%lx)\n", Status);
+        return;
+    }
+
+    /* Total size queried, time to allocate our buffer based on that size */
+    TokenStats = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
+    if (TokenStats == NULL)
+    {
+        skip("Failed to allocate our token statistics buffer!\n");
+        return;
+    }
+
+    /* Time to query our token statistics, prior disabling token's privileges 
*/
+    Status = NtQueryInformationToken(Token, TokenStatistics, TokenStats, Size, 
&Size);
+    if (!NT_SUCCESS(Status))
+    {
+        skip("Failed to query the token statistics! (Status -> 0x%lx)\n", 
Status);
+        return;
+    }
+
+    trace("Number of privileges before token filtering -- %lu\n\n", 
TokenStats->PrivilegeCount);
+
+    /* Disable the privileges and make the token a safer inert one */
+    Status = NtFilterToken(Token,
+                           DISABLE_MAX_PRIVILEGE | SANDBOX_INERT,
+                           NULL,
+                           NULL,
+                           NULL,
+                           &FilteredToken);
+    ok_hex(Status, STATUS_SUCCESS);
+
+    /* We've disabled privileges, query the stats again */
+    Status = NtQueryInformationToken(FilteredToken, TokenStatistics, 
TokenStats, Size, &Size);
+    if (!NT_SUCCESS(Status))
+    {
+        skip("Failed to query the token statistics! (Status -> 0x%lx)\n", 
Status);
+        return;
+    }
+
+    trace("Number of privileges after token filtering (privileges disabled 
with DISABLE_MAX_PRIVILEGE) -- %lu\n\n", TokenStats->PrivilegeCount);
+
+    /* Close the filtered token and do another test */
+    CloseHandle(FilteredToken);
+
+    /* Fill in a privilege to delete */
+    Priv.PrivilegeCount = 1;
+
+    ConvertPrivLongToLuid(SE_BACKUP_PRIVILEGE, &PrivLuid);
+    Priv.Privileges[0].Luid = PrivLuid;
+    Priv.Privileges[0].Attributes = 0;
+
+    /* Delete the privileges */
+    Status = NtFilterToken(Token,
+                           0,
+                           NULL,
+                           &Priv,
+                           NULL,
+                           &FilteredToken);
+    ok_hex(Status, STATUS_SUCCESS);
+
+    /* We've deleted a privilege, query the stats again */
+    Status = NtQueryInformationToken(FilteredToken, TokenStatistics, 
TokenStats, Size, &Size);
+    if (!NT_SUCCESS(Status))
+    {
+        skip("Failed to query the token statistics! (Status -> 0x%lx)\n", 
Status);
+        return;
+    }
+
+    trace("Number of privileges after token filtering (manually deleted 
privilege) -- %lu\n\n", TokenStats->PrivilegeCount);
+
+    /* We're done */
+    RtlFreeHeap(RtlGetProcessHeap(), 0, TokenStats);
+    CloseHandle(Token);
+    CloseHandle(FilteredToken);
+}
diff --git a/modules/rostests/apitests/ntdll/testlist.c 
b/modules/rostests/apitests/ntdll/testlist.c
index 9642602fd77..aff61fa3091 100644
--- a/modules/rostests/apitests/ntdll/testlist.c
+++ b/modules/rostests/apitests/ntdll/testlist.c
@@ -18,6 +18,7 @@ extern void func_NtCreateThread(void);
 extern void func_NtDeleteKey(void);
 extern void func_NtDuplicateObject(void);
 extern void func_NtDuplicateToken(void);
+extern void func_NtFilterToken(void);
 extern void func_NtFreeVirtualMemory(void);
 extern void func_NtImpersonateAnonymousToken(void);
 extern void func_NtLoadUnloadKey(void);
@@ -105,6 +106,7 @@ const struct test winetest_testlist[] =
     { "NtDeleteKey",                    func_NtDeleteKey },
     { "NtDuplicateObject",              func_NtDuplicateObject },
     { "NtDuplicateToken",               func_NtDuplicateToken },
+    { "NtFilterToken",                  func_NtFilterToken },
     { "NtFreeVirtualMemory",            func_NtFreeVirtualMemory },
     { "NtImpersonateAnonymousToken",    func_NtImpersonateAnonymousToken },
     { "NtLoadUnloadKey",                func_NtLoadUnloadKey },

Reply via email to