[RTL][NTDLL_APITEST] Implement RtlRemovePrivileges (#4614)

Vista+ API, compile-time guarded.
Add tests for it.
This commit is contained in:
Ratin Gao 2022-10-05 20:31:39 +08:00 committed by GitHub
parent 967f5b9898
commit badd97043f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 231 additions and 1 deletions

View file

@ -85,6 +85,7 @@ list(APPEND SOURCE
RtlpEnsureBufferSize.c
RtlQueryTimeZoneInfo.c
RtlReAllocateHeap.c
RtlRemovePrivileges.c
RtlUnicodeStringToAnsiString.c
RtlUnicodeStringToCountedOemString.c
RtlUnicodeToOemN.c

View file

@ -0,0 +1,111 @@
/*
* PROJECT: ReactOS api tests
* LICENSE: See COPYING in the top level directory
* PURPOSE: Test for RtlRemovePrivileges
* PROGRAMMER: Ratin Gao <ratin@knsoft.org>
*/
#include "precomp.h"
START_TEST(RtlRemovePrivileges)
{
#if (NTDDI_VERSION >= NTDDI_VISTA)
NTSTATUS Status;
HANDLE TokenHandle, TestTokenHandle;
ULONG ReturnLength;
UCHAR Buffer
[sizeof(TOKEN_PRIVILEGES) +
sizeof(LUID_AND_ATTRIBUTES) * (SE_MAX_WELL_KNOWN_PRIVILEGE - SE_MIN_WELL_KNOWN_PRIVILEGE)];
PTOKEN_PRIVILEGES Privileges;
ULONG PrivilegesToKeep[2];
/* Duplicate current process token to run this test */
Status = NtOpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &TokenHandle);
if (!NT_SUCCESS(Status))
{
ok(0, "Failed to open current process token with TOKEN_DUPLICATE access (Status code %lx)!\n", Status);
return;
}
Status = NtDuplicateToken(TokenHandle, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, &TestTokenHandle);
NtClose(TokenHandle);
if (!NT_SUCCESS(Status))
{
ok(0, "Failed to duplicate current process token (Status code %lx)!\n", Status);
return;
}
/* Retrieve token privileges, we need at least 3 privileges to run following tests */
Status = NtQueryInformationToken(TestTokenHandle, TokenPrivileges, Buffer, sizeof(Buffer), &ReturnLength);
if (!NT_SUCCESS(Status))
{
NtClose(TestTokenHandle);
ok(0, "Failed to retrieve token privileges (Status code %lx)!\n", Status);
return;
}
Privileges = (PTOKEN_PRIVILEGES)Buffer;
if (Privileges->PrivilegeCount < 3)
{
NtClose(TestTokenHandle);
ok(0, "No enough privileges to run the test (Number of privilege: %lu)!\n", Privileges->PrivilegeCount);
return;
}
/* Remove all privileges except 2nd and 3rd privileges, this should succeed */
PrivilegesToKeep[0] = Privileges->Privileges[1].Luid.LowPart;
PrivilegesToKeep[1] = Privileges->Privileges[2].Luid.LowPart;
Status = RtlRemovePrivileges(TestTokenHandle, PrivilegesToKeep, ARRAYSIZE(PrivilegesToKeep));
/* Do not use NT_SUCCESS, RtlRemovePrivileges may returns STATUS_NOT_ALL_ASSIGNED */
if (Status != STATUS_SUCCESS)
{
NtClose(TestTokenHandle);
ok_ntstatus(Status, STATUS_SUCCESS);
return;
}
/* Now, only two privileges we kept should be present */
Status = NtQueryInformationToken(TestTokenHandle, TokenPrivileges, Buffer, sizeof(Buffer), &ReturnLength);
if (!NT_SUCCESS(Status))
{
NtClose(TestTokenHandle);
ok(0, "Failed to retrieve token privileges (Status code %lx)!\n", Status);
return;
}
ok(Privileges->PrivilegeCount == ARRAYSIZE(PrivilegesToKeep),
"Number of privileges after RtlRemovePrivileges is %lu, expected %u\n", Privileges->PrivilegeCount,
ARRAYSIZE(PrivilegesToKeep));
ok(PrivilegesToKeep[0] + PrivilegesToKeep[1] ==
Privileges->Privileges[0].Luid.LowPart + Privileges->Privileges[1].Luid.LowPart,
"Incorrect privileges kept by RtlRemovePrivileges: %lu and %lu, expected %lu and %lu",
Privileges->Privileges[0].Luid.LowPart, Privileges->Privileges[1].Luid.LowPart, PrivilegesToKeep[0],
PrivilegesToKeep[1]);
/* Remove all privileges, this should succeed */
Status = RtlRemovePrivileges(TestTokenHandle, NULL, 0);
/* Do not use NT_SUCCESS, RtlRemovePrivileges may returns STATUS_NOT_ALL_ASSIGNED */
if (Status != STATUS_SUCCESS)
{
NtClose(TestTokenHandle);
ok_ntstatus(Status, STATUS_SUCCESS);
return;
}
/* Now, no privilege should be present */
Status = NtQueryInformationToken(TestTokenHandle, TokenPrivileges, Buffer, sizeof(Buffer), &ReturnLength);
if (!NT_SUCCESS(Status))
{
NtClose(TestTokenHandle);
ok(0, "Failed to retrieve token privileges (Status code %lx)!\n", Status);
return;
}
ok(Privileges->PrivilegeCount == 0, "There are %lu privileges still exist after RtlRemovePrivileges\n",
Privileges->PrivilegeCount);
NtClose(TestTokenHandle);
return;
#else
skip("RtlRemovePrivileges available on NT6.0+ (NTDDI_VERSION >= NTDDI_VISTA)");
#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
}

View file

@ -81,6 +81,7 @@ extern void func_RtlpApplyLengthFunction(void);
extern void func_RtlpEnsureBufferSize(void);
extern void func_RtlQueryTimeZoneInformation(void);
extern void func_RtlReAllocateHeap(void);
extern void func_RtlRemovePrivileges(void);
extern void func_RtlUnicodeStringToAnsiString(void);
extern void func_RtlUnicodeStringToCountedOemString(void);
extern void func_RtlUnicodeToOemN(void);
@ -172,6 +173,7 @@ const struct test winetest_testlist[] =
{ "RtlpEnsureBufferSize", func_RtlpEnsureBufferSize },
{ "RtlQueryTimeZoneInformation", func_RtlQueryTimeZoneInformation },
{ "RtlReAllocateHeap", func_RtlReAllocateHeap },
{ "RtlRemovePrivileges", func_RtlRemovePrivileges },
{ "RtlUnicodeStringToAnsiSize", func_RtlxUnicodeStringToAnsiSize }, /* For some reason, starting test name with Rtlx hides it */
{ "RtlUnicodeStringToAnsiString", func_RtlUnicodeStringToAnsiString },
{ "RtlUnicodeStringToCountedOemString", func_RtlUnicodeStringToCountedOemString },