1 /*
2  * PROJECT:         ReactOS API tests
3  * LICENSE:         GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:         Tests for the NtCompareTokens API
5  * COPYRIGHT:       Copyright 2021 George Bișoc <george.bisoc@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
10 static
11 HANDLE
GetTokenFromCurrentProcess(VOID)12 GetTokenFromCurrentProcess(VOID)
13 {
14     BOOL Success;
15     HANDLE Token;
16 
17     Success = OpenProcessToken(GetCurrentProcess(),
18                                TOKEN_READ | TOKEN_ADJUST_PRIVILEGES | TOKEN_DUPLICATE,
19                                &Token);
20     if (!Success)
21     {
22         skip("OpenProcessToken() has failed to get the process' token (error code: %lu)!\n", GetLastError());
23         return NULL;
24     }
25 
26     return Token;
27 }
28 
29 static
30 HANDLE
GetDuplicateToken(_In_ HANDLE Token)31 GetDuplicateToken(_In_ HANDLE Token)
32 {
33     BOOL Success;
34     HANDLE ReturnedToken;
35 
36     Success = DuplicateToken(Token, SecurityIdentification, &ReturnedToken);
37     if (!Success)
38     {
39         skip("DuplicateToken() has failed to get the process' token (error code: %lu)!\n", GetLastError());
40         return NULL;
41     }
42 
43     return ReturnedToken;
44 }
45 
46 static
47 VOID
DisableTokenPrivileges(_In_ HANDLE Token)48 DisableTokenPrivileges(_In_ HANDLE Token)
49 {
50     BOOL Success;
51 
52     Success = AdjustTokenPrivileges(Token, TRUE, NULL, 0, NULL, NULL);
53     if (!Success)
54     {
55         skip("AdjustTokenPrivileges() has failed to disable the privileges (error code: %lu)!\n", GetLastError());
56         return;
57     }
58 }
59 
START_TEST(NtCompareTokens)60 START_TEST(NtCompareTokens)
61 {
62     NTSTATUS Status;
63     HANDLE ProcessToken = NULL;
64     HANDLE DuplicatedToken = NULL;
65     BOOLEAN IsEqual = FALSE;
66 
67     /* Obtain some tokens from current process */
68     ProcessToken = GetTokenFromCurrentProcess();
69     DuplicatedToken = GetDuplicateToken(ProcessToken);
70 
71     /*
72      * Give invalid token handles and don't output
73      * the returned value in the last parameter.
74      */
75     Status = NtCompareTokens(NULL, NULL, NULL);
76     ok_hex(Status, STATUS_ACCESS_VIOLATION);
77 
78     /*
79      * Token handles are valid but don't output
80      * the returned value.
81      */
82     Status = NtCompareTokens(ProcessToken, ProcessToken, NULL);
83     ok_hex(Status, STATUS_ACCESS_VIOLATION);
84 
85     /* The tokens are the same */
86     Status = NtCompareTokens(ProcessToken, ProcessToken, &IsEqual);
87     ok_hex(Status, STATUS_SUCCESS);
88     ok(IsEqual == TRUE, "Equal tokens expected but they aren't (current value: %u)!\n", IsEqual);
89 
90     /* A token is duplicated with equal SIDs and privileges */
91     Status = NtCompareTokens(ProcessToken, DuplicatedToken, &IsEqual);
92     ok_hex(Status, STATUS_SUCCESS);
93     ok(IsEqual == TRUE, "Equal tokens expected but they aren't (current value: %u)!\n", IsEqual);
94 
95     /* Disable all the privileges for token. */
96     DisableTokenPrivileges(ProcessToken);
97 
98     /*
99      * The main token has privileges disabled but the
100      * duplicated one has them enabled still.
101      */
102     Status = NtCompareTokens(ProcessToken, DuplicatedToken, &IsEqual);
103     ok_hex(Status, STATUS_SUCCESS);
104     ok(IsEqual == FALSE, "Tokens mustn't be equal (current value: %u)!\n", IsEqual);
105 
106     /* We finished our tests, close the tokens */
107     CloseHandle(ProcessToken);
108     CloseHandle(DuplicatedToken);
109 }
110