ReactOS 0.4.15-dev-7918-g2a2556c
NtDuplicateToken.c
Go to the documentation of this file.
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 NtDuplicateToken API
5 * COPYRIGHT: Copyright 2021 George Bișoc <george.bisoc@reactos.org>
6 */
7
8#include "precomp.h"
9
10static
13{
16
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
29static
30VOID
33 _In_ LPCWSTR PrivilegeName)
34{
35 TOKEN_PRIVILEGES TokenPriv;
36 LUID PrivLuid;
38
39 Success = LookupPrivilegeValueW(NULL, PrivilegeName, &PrivLuid);
40 if (!Success)
41 {
42 skip("LookupPrivilegeValueW() has failed to locate the privilege value (error code: %lu)!\n", GetLastError());
43 return;
44 }
45
46 TokenPriv.PrivilegeCount = 1;
47 TokenPriv.Privileges[0].Luid = PrivLuid;
48 TokenPriv.Privileges[0].Attributes = 0;
49
51 FALSE,
52 &TokenPriv,
53 0,
54 NULL,
55 NULL);
56 if (!Success)
57 {
58 skip("AdjustTokenPrivileges() has failed to adjust privileges of token (error code: %lu)!\n", GetLastError());
59 return;
60 }
61}
62
63static
64VOID
66{
68 ULONG Size;
70 HANDLE DuplicatedTokenHandle;
72 PTOKEN_STATISTICS TokenStats;
73
74 /* Initialize the object attributes for token duplication */
76 NULL,
77 0,
78 NULL,
79 NULL);
80
81 /* Get the token from process and begin the tests */
83
84 /* We give a bogus invalid handle */
86 0,
87 NULL,
88 TRUE,
90 NULL);
92
93 /*
94 * Disable a privilege, the impersonation privilege for example.
95 * Why we're doing this is because such privilege is enabled
96 * by default and we'd want to know what the kernel does
97 * at the moment of removing disabled privileges during making
98 * the token effective, with this potential privilege being
99 * disabled by ourselves.
100 */
101 DisablePrivilege(TokenHandle, L"SeImpersonatePrivilege");
102
103 /* Query the total size of the token statistics structure */
106 {
107 skip("Failed to query the total size for token statistics structure! (Status -> 0x%lx)\n", Status);
108 return;
109 }
110
111 /* Total size queried, time to allocate our buffer based on that size */
112 TokenStats = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
113 if (TokenStats == NULL)
114 {
115 skip("Failed to allocate our token statistics buffer!\n");
116 return;
117 }
118
119 /* Time to query our token statistics, prior duplicating the token as effective */
121 if (!NT_SUCCESS(Status))
122 {
123 skip("Failed to query the token statistics! (Status -> 0x%lx)\n", Status);
124 return;
125 }
126
127 trace("Number of privileges of regular token -- %lu\n", TokenStats->PrivilegeCount);
128 trace("Number of groups of regular token -- %lu\n", TokenStats->GroupCount);
129
130 /* Duplicate the token as effective only */
132 0,
134 TRUE,
136 &DuplicatedTokenHandle);
138
139 /*
140 * Query the token statistics again, but now this time of
141 * the duplicated effective token. On this moment this token
142 * should have the disabled privileges (including the one we
143 * disabled ourselves) removed as well as the disabled groups
144 * that the duplicated token includes, whatever that is.
145 */
146 Status = NtQueryInformationToken(DuplicatedTokenHandle, TokenStatistics, TokenStats, Size, &Size);
147 if (!NT_SUCCESS(Status))
148 {
149 skip("Failed to query the token statistics! (Status -> 0x%lx)\n", Status);
150 return;
151 }
152
153 trace("Number of privileges of effective only token -- %lu\n", TokenStats->PrivilegeCount);
154 trace("Number of groups of effective only token -- %lu\n", TokenStats->GroupCount);
155
156 /*
157 * We finished our tests, free the memory
158 * block and close the handles now.
159 */
160 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenStats);
162 CloseHandle(DuplicatedTokenHandle);
163}
164
166{
168}
static VOID DisablePrivilege(_In_ HANDLE Token, _In_ LPCWSTR PrivilegeName)
static HANDLE OpenTokenFromProcess(VOID)
static VOID DuplicateTokenAsEffective(VOID)
#define ok_hex(expression, result)
Definition: atltest.h:94
#define trace
Definition: atltest.h:70
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOL WINAPI LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpPrivilegeName, PLUID lpLuid)
Definition: misc.c:782
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:374
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
#define CloseHandle
Definition: compat.h:739
#define GetCurrentProcess()
Definition: compat.h:759
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:25
@ TokenPrimary
Definition: imports.h:273
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _In_
Definition: ms_sal.h:308
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:726
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define L(x)
Definition: ntvdm.h:50
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
$ULONG PrivilegeCount
Definition: setypes.h:1023
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]
Definition: setypes.h:1024
$ULONG PrivilegeCount
Definition: setypes.h:1094
$ULONG GroupCount
Definition: setypes.h:1093
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtQueryInformationToken(_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Out_writes_bytes_to_opt_(TokenInformationLength, *ReturnLength) PVOID TokenInformation, _In_ ULONG TokenInformationLength, _Out_ PULONG ReturnLength)
Queries a specific type of information in regard of an access token based upon the information class....
Definition: tokencls.c:473
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtDuplicateToken(_In_ HANDLE ExistingTokenHandle, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ BOOLEAN EffectiveOnly, _In_ TOKEN_TYPE TokenType, _Out_ PHANDLE NewTokenHandle)
Duplicates a token.
Definition: tokenlif.c:1869
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define TOKEN_DUPLICATE
Definition: setypes.h:926
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:930
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenStatistics
Definition: setypes.h:975
#define TOKEN_ADJUST_GROUPS
Definition: setypes.h:931
#define TOKEN_READ
Definition: setypes.h:951
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185