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 NtImpersonateAnonymousToken API 5 * COPYRIGHT: Copyright 2021 George Bișoc <george.bisoc@reactos.org> 6 */ 7 8 #include "precomp.h" 9 #include <winreg.h> 10 11 #define TOKEN_WITH_EVERYONE_GROUP 1 12 #define TOKEN_WITHOUT_EVERYONE_GROUP 0 13 14 static 15 HANDLE 16 GetThreadFromCurrentProcess(_In_ DWORD DesiredAccess) 17 { 18 HANDLE Thread; 19 20 Thread = OpenThread(DesiredAccess, FALSE, GetCurrentThreadId()); 21 if (!Thread) 22 { 23 skip("OpenThread() has failed to open the current process' thread (error code: %lu)\n", GetLastError()); 24 return NULL; 25 } 26 27 return Thread; 28 } 29 30 static 31 VOID 32 ImpersonateTokenWithEveryoneOrWithout(_In_ DWORD Value) 33 { 34 LONG Result; 35 HKEY Key; 36 37 Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 38 L"SYSTEM\\CurrentControlSet\\Control\\Lsa", 39 0, 40 KEY_SET_VALUE, 41 &Key); 42 if (Result != ERROR_SUCCESS) 43 { 44 skip("RegOpenKeyExW() has failed to open the key (error code: %li)\n", Result); 45 return; 46 } 47 48 Result = RegSetValueExW(Key, 49 L"EveryoneIncludesAnonymous", 50 0, 51 REG_DWORD, 52 (PBYTE)&Value, 53 sizeof(Value)); 54 if (Result != ERROR_SUCCESS) 55 { 56 skip("RegSetValueExW() has failed to set the value (error code: %li)\n", Result); 57 RegCloseKey(Key); 58 return; 59 } 60 61 RegCloseKey(Key); 62 } 63 64 START_TEST(NtImpersonateAnonymousToken) 65 { 66 NTSTATUS Status; 67 BOOL Success; 68 HANDLE ThreadHandle; 69 70 ThreadHandle = GetThreadFromCurrentProcess(THREAD_IMPERSONATE); 71 72 /* We give an invalid thread handle */ 73 Status = NtImpersonateAnonymousToken(NULL); 74 ok_hex(Status, STATUS_INVALID_HANDLE); 75 76 /* We want to impersonate the token including Everyone Group SID */ 77 ImpersonateTokenWithEveryoneOrWithout(TOKEN_WITH_EVERYONE_GROUP); 78 79 /* Impersonate the anonymous logon token */ 80 Status = NtImpersonateAnonymousToken(ThreadHandle); 81 ok_hex(Status, STATUS_SUCCESS); 82 83 /* Now revert to the previous security properties */ 84 Success = RevertToSelf(); 85 ok(Success == TRUE, "We should have terminated the impersonation but we couldn't (error code: %lu)\n", GetLastError()); 86 87 /* Return to default setting -- token without Everyone Group SID */ 88 ImpersonateTokenWithEveryoneOrWithout(TOKEN_WITHOUT_EVERYONE_GROUP); 89 90 /* Impersonate the anonymous logon token again */ 91 Status = NtImpersonateAnonymousToken(ThreadHandle); 92 ok_hex(Status, STATUS_SUCCESS); 93 94 /* Now revert to the previous security properties */ 95 Success = RevertToSelf(); 96 ok(Success == TRUE, "We should have terminated the impersonation but we couldn't (error code: %lu)\n", GetLastError()); 97 98 /* 99 * Invalidate the handle and open a new one. This time 100 * with the wrong access right mask, the function will 101 * outright fail on impersonating the token. 102 */ 103 CloseHandle(ThreadHandle); 104 ThreadHandle = GetThreadFromCurrentProcess(SYNCHRONIZE); 105 106 /* The thread handle has incorrect right access */ 107 Status = NtImpersonateAnonymousToken(ThreadHandle); 108 ok_hex(Status, STATUS_ACCESS_DENIED); 109 110 /* We're done with the tests */ 111 CloseHandle(ThreadHandle); 112 } 113