1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: See COPYING in the top level directory 4 * PURPOSE: Test for RtlRemovePrivileges 5 * PROGRAMMER: Ratin Gao <ratin@knsoft.org> 6 */ 7 8 #include "precomp.h" 9 10 START_TEST(RtlRemovePrivileges) 11 { 12 #if (NTDDI_VERSION >= NTDDI_VISTA) 13 NTSTATUS Status; 14 HANDLE TokenHandle, TestTokenHandle; 15 ULONG ReturnLength; 16 UCHAR Buffer 17 [sizeof(TOKEN_PRIVILEGES) + 18 sizeof(LUID_AND_ATTRIBUTES) * (SE_MAX_WELL_KNOWN_PRIVILEGE - SE_MIN_WELL_KNOWN_PRIVILEGE)]; 19 PTOKEN_PRIVILEGES Privileges; 20 ULONG PrivilegesToKeep[2]; 21 22 /* Duplicate current process token to run this test */ 23 Status = NtOpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &TokenHandle); 24 if (!NT_SUCCESS(Status)) 25 { 26 ok(0, "Failed to open current process token with TOKEN_DUPLICATE access (Status code %lx)!\n", Status); 27 return; 28 } 29 30 Status = NtDuplicateToken(TokenHandle, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, &TestTokenHandle); 31 NtClose(TokenHandle); 32 if (!NT_SUCCESS(Status)) 33 { 34 ok(0, "Failed to duplicate current process token (Status code %lx)!\n", Status); 35 return; 36 } 37 38 /* Retrieve token privileges, we need at least 3 privileges to run following tests */ 39 Status = NtQueryInformationToken(TestTokenHandle, TokenPrivileges, Buffer, sizeof(Buffer), &ReturnLength); 40 if (!NT_SUCCESS(Status)) 41 { 42 NtClose(TestTokenHandle); 43 ok(0, "Failed to retrieve token privileges (Status code %lx)!\n", Status); 44 return; 45 } 46 Privileges = (PTOKEN_PRIVILEGES)Buffer; 47 if (Privileges->PrivilegeCount < 3) 48 { 49 NtClose(TestTokenHandle); 50 ok(0, "No enough privileges to run the test (Number of privilege: %lu)!\n", Privileges->PrivilegeCount); 51 return; 52 } 53 54 /* Remove all privileges except 2nd and 3rd privileges, this should succeed */ 55 PrivilegesToKeep[0] = Privileges->Privileges[1].Luid.LowPart; 56 PrivilegesToKeep[1] = Privileges->Privileges[2].Luid.LowPart; 57 Status = RtlRemovePrivileges(TestTokenHandle, PrivilegesToKeep, ARRAYSIZE(PrivilegesToKeep)); 58 59 /* Do not use NT_SUCCESS, RtlRemovePrivileges may returns STATUS_NOT_ALL_ASSIGNED */ 60 if (Status != STATUS_SUCCESS) 61 { 62 NtClose(TestTokenHandle); 63 ok_ntstatus(Status, STATUS_SUCCESS); 64 return; 65 } 66 67 /* Now, only two privileges we kept should be present */ 68 Status = NtQueryInformationToken(TestTokenHandle, TokenPrivileges, Buffer, sizeof(Buffer), &ReturnLength); 69 if (!NT_SUCCESS(Status)) 70 { 71 NtClose(TestTokenHandle); 72 ok(0, "Failed to retrieve token privileges (Status code %lx)!\n", Status); 73 return; 74 } 75 ok(Privileges->PrivilegeCount == ARRAYSIZE(PrivilegesToKeep), 76 "Number of privileges after RtlRemovePrivileges is %lu, expected %u\n", Privileges->PrivilegeCount, 77 ARRAYSIZE(PrivilegesToKeep)); 78 ok(PrivilegesToKeep[0] + PrivilegesToKeep[1] == 79 Privileges->Privileges[0].Luid.LowPart + Privileges->Privileges[1].Luid.LowPart, 80 "Incorrect privileges kept by RtlRemovePrivileges: %lu and %lu, expected %lu and %lu", 81 Privileges->Privileges[0].Luid.LowPart, Privileges->Privileges[1].Luid.LowPart, PrivilegesToKeep[0], 82 PrivilegesToKeep[1]); 83 84 /* Remove all privileges, this should succeed */ 85 Status = RtlRemovePrivileges(TestTokenHandle, NULL, 0); 86 87 /* Do not use NT_SUCCESS, RtlRemovePrivileges may returns STATUS_NOT_ALL_ASSIGNED */ 88 if (Status != STATUS_SUCCESS) 89 { 90 NtClose(TestTokenHandle); 91 ok_ntstatus(Status, STATUS_SUCCESS); 92 return; 93 } 94 95 /* Now, no privilege should be present */ 96 Status = NtQueryInformationToken(TestTokenHandle, TokenPrivileges, Buffer, sizeof(Buffer), &ReturnLength); 97 if (!NT_SUCCESS(Status)) 98 { 99 NtClose(TestTokenHandle); 100 ok(0, "Failed to retrieve token privileges (Status code %lx)!\n", Status); 101 return; 102 } 103 ok(Privileges->PrivilegeCount == 0, "There are %lu privileges still exist after RtlRemovePrivileges\n", 104 Privileges->PrivilegeCount); 105 106 NtClose(TestTokenHandle); 107 return; 108 #else 109 skip("RtlRemovePrivileges available on NT6.0+ (NTDDI_VERSION >= NTDDI_VISTA)"); 110 #endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ 111 } 112