diff --git a/modules/rostests/apitests/ntdll/CMakeLists.txt b/modules/rostests/apitests/ntdll/CMakeLists.txt index ef5f6a61302..86613855448 100644 --- a/modules/rostests/apitests/ntdll/CMakeLists.txt +++ b/modules/rostests/apitests/ntdll/CMakeLists.txt @@ -10,6 +10,7 @@ list(APPEND SOURCE load_notifications.c locale.c NtAcceptConnectPort.c + NtAdjustPrivilegesToken.c NtAllocateVirtualMemory.c NtApphelpCacheControl.c NtCompareTokens.c diff --git a/modules/rostests/apitests/ntdll/NtAdjustPrivilegesToken.c b/modules/rostests/apitests/ntdll/NtAdjustPrivilegesToken.c new file mode 100644 index 00000000000..363609ad2f2 --- /dev/null +++ b/modules/rostests/apitests/ntdll/NtAdjustPrivilegesToken.c @@ -0,0 +1,87 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Tests for the NtAdjustPrivilegesToken API + * COPYRIGHT: Copyright 2021 George Bișoc + */ + +#include "precomp.h" + +static +BOOL +IsPrivilegeEnabled( + _In_ HANDLE TokenHandle, + _In_ ULONG Privilege) +{ + PRIVILEGE_SET PrivSet; + BOOL Result, Success; + LUID Priv; + + ConvertPrivLongToLuid(Privilege, &Priv); + + PrivSet.PrivilegeCount = 1; + PrivSet.Control = PRIVILEGE_SET_ALL_NECESSARY; + PrivSet.Privilege[0].Luid = Priv; + PrivSet.Privilege[0].Attributes = 0; + + Success = PrivilegeCheck(TokenHandle, &PrivSet, &Result); + if (!Success) + { + skip("Failed to check the privilege (error code: %lu)\n", GetLastError()); + return FALSE; + } + + return Result; +} + +static +VOID +AdjustEnableDefaultPriv(VOID) +{ + NTSTATUS Status; + HANDLE Token; + TOKEN_PRIVILEGES Priv; + BOOL Success, IsEnabled; + LUID PrivLuid; + + Success = OpenProcessToken(GetCurrentProcess(), + TOKEN_READ | TOKEN_ADJUST_PRIVILEGES, + &Token); + if (!Success) + { + skip("OpenProcessToken() has failed to get the process' token (error code: %lu)!\n", GetLastError()); + return; + } + + Success = LookupPrivilegeValueW(NULL, L"SeImpersonatePrivilege", &PrivLuid); + if (!Success) + { + skip("LookupPrivilegeValueW() has failed to locate the privilege value (error code: %lu)!\n", GetLastError()); + return; + } + + Priv.PrivilegeCount = 1; + Priv.Privileges[0].Luid = PrivLuid; + Priv.Privileges[0].Attributes = 0; + + IsEnabled = IsPrivilegeEnabled(Token, SE_IMPERSONATE_PRIVILEGE); + trace("The privilege is %s!\n", IsEnabled ? "enabled" : "disabled"); + + Status = NtAdjustPrivilegesToken(Token, + FALSE, + &Priv, + 0, + NULL, + NULL); + ok_hex(Status, STATUS_SUCCESS); + + IsEnabled = IsPrivilegeEnabled(Token, SE_IMPERSONATE_PRIVILEGE); + trace("The privilege is %s!\n", IsEnabled ? "enabled" : "disabled"); + + CloseHandle(Token); +} + +START_TEST(NtAdjustPrivilegesToken) +{ + AdjustEnableDefaultPriv(); +} diff --git a/modules/rostests/apitests/ntdll/precomp.h b/modules/rostests/apitests/ntdll/precomp.h index 4871076a873..6b8ea6e1b0a 100644 --- a/modules/rostests/apitests/ntdll/precomp.h +++ b/modules/rostests/apitests/ntdll/precomp.h @@ -41,4 +41,12 @@ SetupLocale( _In_ ULONG OemCode, _In_ ULONG Unicode); +#define ConvertPrivLongToLuid(PrivilegeVal, ConvertedPrivLuid) \ +do { \ + LUID Luid; \ + Luid.LowPart = PrivilegeVal; \ + Luid.HighPart = 0; \ + *ConvertedPrivLuid = Luid; \ +} while (0) + #endif /* _NTDLL_APITEST_PRECOMP_H_ */ diff --git a/modules/rostests/apitests/ntdll/testlist.c b/modules/rostests/apitests/ntdll/testlist.c index 5a56ec6e987..49458f43f09 100644 --- a/modules/rostests/apitests/ntdll/testlist.c +++ b/modules/rostests/apitests/ntdll/testlist.c @@ -6,6 +6,7 @@ extern void func_LdrEnumResources(void); extern void func_load_notifications(void); extern void func_NtAcceptConnectPort(void); +extern void func_NtAdjustPrivilegesToken(void); extern void func_NtAllocateVirtualMemory(void); extern void func_NtApphelpCacheControl(void); extern void func_NtCompareTokens(void); @@ -90,6 +91,7 @@ const struct test winetest_testlist[] = { "LdrEnumResources", func_LdrEnumResources }, { "load_notifications", func_load_notifications }, { "NtAcceptConnectPort", func_NtAcceptConnectPort }, + { "NtAdjustPrivilegesToken", func_NtAdjustPrivilegesToken }, { "NtAllocateVirtualMemory", func_NtAllocateVirtualMemory }, { "NtApphelpCacheControl", func_NtApphelpCacheControl }, { "NtCompareTokens", func_NtCompareTokens },