mirror of
https://github.com/reactos/reactos.git
synced 2025-03-30 17:10:22 +00:00
[NTDLL_APITEST] Write NtAccessCheck testcase that tests for empty generic mapping scenario
See b79aadd50bb7d5d6f08532284941c0334514c477 for further information.
This commit is contained in:
parent
4b4638dc55
commit
fefb1b7745
3 changed files with 191 additions and 0 deletions
|
@ -10,6 +10,7 @@ list(APPEND SOURCE
|
||||||
load_notifications.c
|
load_notifications.c
|
||||||
locale.c
|
locale.c
|
||||||
NtAcceptConnectPort.c
|
NtAcceptConnectPort.c
|
||||||
|
NtAccessCheck.c
|
||||||
NtAccessCheckByType.c
|
NtAccessCheckByType.c
|
||||||
NtAccessCheckByTypeResultList.c
|
NtAccessCheckByTypeResultList.c
|
||||||
NtAdjustGroupsToken.c
|
NtAdjustGroupsToken.c
|
||||||
|
|
188
modules/rostests/apitests/ntdll/NtAccessCheck.c
Normal file
188
modules/rostests/apitests/ntdll/NtAccessCheck.c
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS API tests
|
||||||
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
|
* PURPOSE: Tests for the NtAccessCheck API
|
||||||
|
* COPYRIGHT: Copyright 2023 George Bișoc <george.bisoc@reactos.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precomp.h"
|
||||||
|
|
||||||
|
static
|
||||||
|
HANDLE
|
||||||
|
GetToken(VOID)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE Token;
|
||||||
|
HANDLE DuplicatedToken;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
SECURITY_QUALITY_OF_SERVICE Sqos;
|
||||||
|
|
||||||
|
Status = NtOpenProcessToken(NtCurrentProcess(),
|
||||||
|
TOKEN_QUERY | TOKEN_DUPLICATE,
|
||||||
|
&Token);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
trace("Failed to get current process token (Status 0x%08lx)\n", Status);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
|
||||||
|
Sqos.ImpersonationLevel = SecurityImpersonation;
|
||||||
|
Sqos.ContextTrackingMode = 0;
|
||||||
|
Sqos.EffectiveOnly = FALSE;
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
ObjectAttributes.SecurityQualityOfService = &Sqos;
|
||||||
|
|
||||||
|
Status = NtDuplicateToken(Token,
|
||||||
|
TOKEN_QUERY | TOKEN_DUPLICATE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
FALSE,
|
||||||
|
TokenImpersonation,
|
||||||
|
&DuplicatedToken);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
trace("Failed to duplicate token (Status 0x%08lx)\n", Status);
|
||||||
|
NtClose(Token);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DuplicatedToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
AccessCheckEmptyMappingTest(VOID)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
NTSTATUS AccessStatus;
|
||||||
|
ACCESS_MASK GrantedAccess;
|
||||||
|
PPRIVILEGE_SET PrivilegeSet = NULL;
|
||||||
|
ULONG PrivilegeSetLength;
|
||||||
|
HANDLE Token = NULL;
|
||||||
|
PACL Dacl = NULL;
|
||||||
|
ULONG DaclSize;
|
||||||
|
SECURITY_DESCRIPTOR Sd;
|
||||||
|
PSID WorldSid = NULL;
|
||||||
|
static SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
|
||||||
|
static GENERIC_MAPPING EmptyMapping = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
/* Allocate all the stuff we need */
|
||||||
|
PrivilegeSetLength = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
|
||||||
|
PrivilegeSet = RtlAllocateHeap(RtlGetProcessHeap(), 0, PrivilegeSetLength);
|
||||||
|
if (PrivilegeSet == NULL)
|
||||||
|
{
|
||||||
|
skip("Failed to allocate PrivilegeSet, skipping tests\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = RtlAllocateAndInitializeSid(&WorldAuthority,
|
||||||
|
1,
|
||||||
|
SECURITY_WORLD_RID,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&WorldSid);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
skip("Failed to create World SID, skipping tests\n");
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token = GetToken();
|
||||||
|
if (Token == NULL)
|
||||||
|
{
|
||||||
|
skip("Failed to get token, skipping tests\n");
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = RtlCreateSecurityDescriptor(&Sd, SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
skip("Failed to create a security descriptor, skipping tests\n");
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
DaclSize = sizeof(ACL) +
|
||||||
|
sizeof(ACCESS_ALLOWED_OBJECT_ACE) + RtlLengthSid(WorldSid);
|
||||||
|
Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
DaclSize);
|
||||||
|
if (Dacl == NULL)
|
||||||
|
{
|
||||||
|
skip("Failed to allocate memory for DACL, skipping tests\n");
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup a ACL and give full access to everyone */
|
||||||
|
Status = RtlCreateAcl(Dacl,
|
||||||
|
DaclSize,
|
||||||
|
ACL_REVISION);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
skip("Failed to create DACL, skipping tests\n");
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = RtlAddAccessAllowedAce(Dacl,
|
||||||
|
ACL_REVISION,
|
||||||
|
GENERIC_ALL,
|
||||||
|
WorldSid);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
skip("Failed to add allowed ACE for World SID, skipping tests\n");
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup the descriptor */
|
||||||
|
RtlSetGroupSecurityDescriptor(&Sd, WorldSid, FALSE);
|
||||||
|
RtlSetOwnerSecurityDescriptor(&Sd, WorldSid, FALSE);
|
||||||
|
RtlSetDaclSecurityDescriptor(&Sd, TRUE, Dacl, FALSE);
|
||||||
|
|
||||||
|
/* Do an access check with empty mapping */
|
||||||
|
Status = NtAccessCheck(&Sd,
|
||||||
|
Token,
|
||||||
|
MAXIMUM_ALLOWED,
|
||||||
|
&EmptyMapping,
|
||||||
|
PrivilegeSet,
|
||||||
|
&PrivilegeSetLength,
|
||||||
|
&GrantedAccess,
|
||||||
|
&AccessStatus);
|
||||||
|
ok_hex(Status, STATUS_SUCCESS);
|
||||||
|
ok(AccessStatus == STATUS_SUCCESS, "Expected a success status but got 0x%08lx\n", AccessStatus);
|
||||||
|
trace("GrantedAccess == 0x%08lx\n", GrantedAccess);
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
if (Dacl)
|
||||||
|
{
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Token)
|
||||||
|
{
|
||||||
|
NtClose(Token);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WorldSid)
|
||||||
|
{
|
||||||
|
RtlFreeSid(WorldSid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PrivilegeSet)
|
||||||
|
{
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, PrivilegeSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(NtAccessCheck)
|
||||||
|
{
|
||||||
|
AccessCheckEmptyMappingTest();
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
extern void func_LdrEnumResources(void);
|
extern void func_LdrEnumResources(void);
|
||||||
extern void func_load_notifications(void);
|
extern void func_load_notifications(void);
|
||||||
extern void func_NtAcceptConnectPort(void);
|
extern void func_NtAcceptConnectPort(void);
|
||||||
|
extern void func_NtAccessCheck(void);
|
||||||
extern void func_NtAccessCheckByType(void);
|
extern void func_NtAccessCheckByType(void);
|
||||||
extern void func_NtAccessCheckByTypeResultList(void);
|
extern void func_NtAccessCheckByTypeResultList(void);
|
||||||
extern void func_NtAdjustGroupsToken(void);
|
extern void func_NtAdjustGroupsToken(void);
|
||||||
|
@ -102,6 +103,7 @@ const struct test winetest_testlist[] =
|
||||||
{ "LdrEnumResources", func_LdrEnumResources },
|
{ "LdrEnumResources", func_LdrEnumResources },
|
||||||
{ "load_notifications", func_load_notifications },
|
{ "load_notifications", func_load_notifications },
|
||||||
{ "NtAcceptConnectPort", func_NtAcceptConnectPort },
|
{ "NtAcceptConnectPort", func_NtAcceptConnectPort },
|
||||||
|
{ "NtAccessCheck", func_NtAccessCheck },
|
||||||
{ "NtAccessCheckByType", func_NtAccessCheckByType },
|
{ "NtAccessCheckByType", func_NtAccessCheckByType },
|
||||||
{ "NtAccessCheckByTypeResultList", func_NtAccessCheckByTypeResultList },
|
{ "NtAccessCheckByTypeResultList", func_NtAccessCheckByTypeResultList },
|
||||||
{ "NtAdjustGroupsToken", func_NtAdjustGroupsToken },
|
{ "NtAdjustGroupsToken", func_NtAdjustGroupsToken },
|
||||||
|
|
Loading…
Reference in a new issue