mirror of
https://github.com/reactos/reactos.git
synced 2024-06-27 16:31:30 +00:00
[KMTESTS:SE]
- Add a test for SeAssignSecurity[Ex] CORE-8745 svn path=/trunk/; revision=65258
This commit is contained in:
parent
71606f1035
commit
418629f6a9
|
@ -71,6 +71,8 @@ list(APPEND KMTEST_DRV_SOURCE
|
|||
ntos_ob/ObType.c
|
||||
ntos_ob/ObTypes.c
|
||||
ntos_ps/PsNotify.c
|
||||
ntos_se/SeHelpers.c
|
||||
ntos_se/SeInheritance.c
|
||||
ntos_se/SeQueryInfoToken.c
|
||||
${COMMON_SOURCE}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ KMT_TESTFUNC Test_ObTypeClean;
|
|||
KMT_TESTFUNC Test_ObTypeNoClean;
|
||||
KMT_TESTFUNC Test_ObTypes;
|
||||
KMT_TESTFUNC Test_PsNotify;
|
||||
KMT_TESTFUNC Test_SeInheritance;
|
||||
KMT_TESTFUNC Test_SeQueryInfoToken;
|
||||
KMT_TESTFUNC Test_RtlAvlTree;
|
||||
KMT_TESTFUNC Test_RtlException;
|
||||
|
@ -107,6 +108,7 @@ const KMT_TEST TestList[] =
|
|||
{ "-ObTypeNoClean", Test_ObTypeNoClean },
|
||||
{ "ObTypes", Test_ObTypes },
|
||||
{ "PsNotify", Test_PsNotify },
|
||||
{ "SeInheritance", Test_SeInheritance },
|
||||
{ "-SeQueryInfoToken", Test_SeQueryInfoToken },
|
||||
{ "RtlAvlTreeKM", Test_RtlAvlTree },
|
||||
{ "RtlExceptionKM", Test_RtlException },
|
||||
|
|
194
rostests/kmtests/ntos_se/SeHelpers.c
Normal file
194
rostests/kmtests/ntos_se/SeHelpers.c
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* PROJECT: ReactOS kernel-mode tests
|
||||
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
|
||||
* PURPOSE: Kernel-Mode Test Suite Helper functions for Se tests
|
||||
* PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
|
||||
*/
|
||||
|
||||
#include <kmt_test.h>
|
||||
#include "se.h"
|
||||
|
||||
NTSTATUS
|
||||
RtlxAddAuditAccessAceEx(
|
||||
_Inout_ PACL Acl,
|
||||
_In_ ULONG Revision,
|
||||
_In_ ULONG Flags,
|
||||
_In_ ACCESS_MASK AccessMask,
|
||||
_In_ PSID Sid,
|
||||
_In_ BOOLEAN Success,
|
||||
_In_ BOOLEAN Failure)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
USHORT AceSize;
|
||||
PSYSTEM_AUDIT_ACE Ace;
|
||||
|
||||
if (Success) Flags |= SUCCESSFUL_ACCESS_ACE_FLAG;
|
||||
if (Failure) Flags |= FAILED_ACCESS_ACE_FLAG;
|
||||
|
||||
AceSize = FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + RtlLengthSid(Sid);
|
||||
Ace = ExAllocatePoolWithTag(PagedPool, AceSize, 'cAmK');
|
||||
if (!Ace)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
Ace->Header.AceType = SYSTEM_AUDIT_ACE_TYPE;
|
||||
Ace->Header.AceFlags = Flags;
|
||||
Ace->Header.AceSize = AceSize;
|
||||
Ace->Mask = AccessMask;
|
||||
Status = RtlCopySid(AceSize - FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart),
|
||||
(PSID)&Ace->SidStart,
|
||||
Sid);
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = RtlAddAce(Acl,
|
||||
Revision,
|
||||
MAXULONG,
|
||||
Ace,
|
||||
AceSize);
|
||||
}
|
||||
ExFreePoolWithTag(Ace, 'cAmK');
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
CheckSid__(
|
||||
_In_ PSID Sid,
|
||||
_In_ ULONG SidSize,
|
||||
_In_ PISID ExpectedSid,
|
||||
_In_ PCSTR FileAndLine)
|
||||
{
|
||||
BOOLEAN Okay;
|
||||
ULONG Length;
|
||||
|
||||
KmtOk(Sid != NULL, FileAndLine, "Sid is NULL\n");
|
||||
if (KmtSkip(Sid != NULL, FileAndLine, "No Sid\n"))
|
||||
return;
|
||||
if (KmtSkip(SidSize >= sizeof(ULONG), FileAndLine, "Sid too small: %lu\n", SidSize))
|
||||
return;
|
||||
Okay = RtlValidSid(Sid);
|
||||
KmtOk(Okay == TRUE, FileAndLine, "Invalid Sid\n");
|
||||
if (KmtSkip(Okay, FileAndLine, "Invalid Sid\n"))
|
||||
return;
|
||||
|
||||
Length = RtlLengthSid(Sid);
|
||||
KmtOk(SidSize >= Length, FileAndLine, "SidSize %lu too small, need %lu\n", SidSize, Length);
|
||||
if (KmtSkip(SidSize >= Length, FileAndLine, "Sid too small\n"))
|
||||
return;
|
||||
Okay = RtlEqualSid(Sid, ExpectedSid);
|
||||
KmtOk(Okay, FileAndLine, "Sids %p and %p not equal\n", Sid, ExpectedSid);
|
||||
if (!Okay)
|
||||
{
|
||||
WCHAR Buffer1[128];
|
||||
WCHAR Buffer2[128];
|
||||
UNICODE_STRING SidString1, SidString2;
|
||||
RtlInitEmptyUnicodeString(&SidString1, Buffer1, sizeof(Buffer1));
|
||||
RtlInitEmptyUnicodeString(&SidString2, Buffer2, sizeof(Buffer2));
|
||||
(void)RtlConvertSidToUnicodeString(&SidString1, Sid, FALSE);
|
||||
(void)RtlConvertSidToUnicodeString(&SidString2, ExpectedSid, FALSE);
|
||||
KmtOk(0, FileAndLine, "Got %wZ, expected %wZ\n", &SidString1, &SidString2);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
VCheckAcl__(
|
||||
_In_ PACL Acl,
|
||||
_In_ ULONG AceCount,
|
||||
_In_ PCSTR FileAndLine,
|
||||
_In_ va_list Arguments)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG Offset;
|
||||
PACE_HEADER AceHeader;
|
||||
INT AceType;
|
||||
INT AceFlags;
|
||||
ACCESS_MASK Mask;
|
||||
PISID Sid;
|
||||
PACCESS_ALLOWED_ACE AllowedAce;
|
||||
PACCESS_DENIED_ACE DeniedAce;
|
||||
PSYSTEM_AUDIT_ACE AuditAce;
|
||||
|
||||
KmtOk(Acl != NULL, FileAndLine, "Acl is NULL\n");
|
||||
if (KmtSkip(Acl != NULL, FileAndLine, "No ACL\n"))
|
||||
return;
|
||||
KmtOk((ULONG_PTR)Acl % sizeof(ULONG) == 0, FileAndLine, "Unaligned ACL %p\n", Acl);
|
||||
KmtOk(Acl->AclRevision == ACL_REVISION, FileAndLine, "AclRevision is %u\n", Acl->AclRevision);
|
||||
KmtOk(Acl->Sbz1 == 0, FileAndLine, "Sbz1 is %u\n", Acl->Sbz1);
|
||||
KmtOk(Acl->Sbz2 == 0, FileAndLine, "Sbz2 is %u\n", Acl->Sbz2);
|
||||
KmtOk(Acl->AclSize >= sizeof(*Acl), FileAndLine, "AclSize too small: %u\n", Acl->AclSize);
|
||||
KmtOk(Acl->AceCount == AceCount, FileAndLine, "AceCount is %u, expected %lu\n", Acl->AceCount, AceCount);
|
||||
Offset = sizeof(*Acl);
|
||||
for (i = 0; i < Acl->AceCount; i++)
|
||||
{
|
||||
KmtOk(Acl->AclSize >= Offset + sizeof(*AceHeader), FileAndLine, "AclSize too small (%u) at Offset %lu, ACE #%lu\n", Acl->AclSize, Offset, i);
|
||||
if (Acl->AclSize < Offset + sizeof(*AceHeader))
|
||||
break;
|
||||
AceHeader = (PACE_HEADER)((PUCHAR)Acl + Offset);
|
||||
KmtOk((ULONG_PTR)AceHeader % sizeof(ULONG) == 0, FileAndLine, "[%lu] Unaligned ACE %p\n", i, AceHeader);
|
||||
KmtOk(AceHeader->AceSize % sizeof(ULONG) == 0, FileAndLine, "[%lu] Unaligned ACE size %u\n", i, AceHeader->AceSize);
|
||||
KmtOk(Acl->AclSize >= Offset + AceHeader->AceSize, FileAndLine, "[%lu] AclSize too small (%u) at Offset %lu\n", i, Acl->AclSize, Offset);
|
||||
if (Acl->AclSize < Offset + AceHeader->AceSize)
|
||||
break;
|
||||
Offset += AceHeader->AceSize;
|
||||
if (i >= AceCount)
|
||||
continue;
|
||||
AceType = va_arg(Arguments, INT);
|
||||
AceFlags = va_arg(Arguments, INT);
|
||||
KmtOk(AceHeader->AceType == AceType, FileAndLine, "[%lu] AceType is %u, expected %u\n", i, AceHeader->AceType, AceType);
|
||||
KmtOk(AceHeader->AceFlags == AceFlags, FileAndLine, "[%lu] AceFlags is 0x%x, expected 0x%x\n", i, AceHeader->AceFlags, AceFlags);
|
||||
if (AceType == ACCESS_ALLOWED_ACE_TYPE)
|
||||
{
|
||||
Sid = va_arg(Arguments, PSID);
|
||||
Mask = va_arg(Arguments, INT);
|
||||
KmtOk(AceHeader->AceSize >= sizeof(*AllowedAce), FileAndLine, "[%lu] AllowedAce AceSize too small: %u\n", i, AceHeader->AceSize);
|
||||
if (AceHeader->AceSize < sizeof(*AllowedAce))
|
||||
continue;
|
||||
AllowedAce = (PACCESS_ALLOWED_ACE)AceHeader;
|
||||
KmtOk(AllowedAce->Mask == Mask, FileAndLine, "[%lu] AllowedAce Mask is 0x%lx, expected 0x%lx\n", i, AllowedAce->Mask, Mask);
|
||||
CheckSid__((PSID)&AllowedAce->SidStart,
|
||||
AceHeader->AceSize - FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart),
|
||||
Sid,
|
||||
FileAndLine);
|
||||
}
|
||||
else if (AceType == ACCESS_DENIED_ACE_TYPE)
|
||||
{
|
||||
Sid = va_arg(Arguments, PSID);
|
||||
Mask = va_arg(Arguments, INT);
|
||||
KmtOk(AceHeader->AceSize >= sizeof(*DeniedAce), FileAndLine, "[%lu] DeniedAce AceSize too small: %u\n", i, AceHeader->AceSize);
|
||||
if (AceHeader->AceSize < sizeof(*DeniedAce))
|
||||
continue;
|
||||
DeniedAce = (PACCESS_DENIED_ACE)AceHeader;
|
||||
KmtOk(DeniedAce->Mask == Mask, FileAndLine, "[%lu] DeniedAce Mask is 0x%lx, expected 0x%lx\n", i, DeniedAce->Mask, Mask);
|
||||
CheckSid__((PSID)&DeniedAce->SidStart,
|
||||
AceHeader->AceSize - FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart),
|
||||
Sid,
|
||||
FileAndLine);
|
||||
}
|
||||
else if (AceType == SYSTEM_AUDIT_ACE_TYPE)
|
||||
{
|
||||
Sid = va_arg(Arguments, PSID);
|
||||
Mask = va_arg(Arguments, INT);
|
||||
KmtOk(AceHeader->AceSize >= sizeof(*AuditAce), FileAndLine, "[%lu] AuditAce AceSize too small: %u\n", i, AceHeader->AceSize);
|
||||
if (AceHeader->AceSize < sizeof(*AuditAce))
|
||||
continue;
|
||||
AuditAce = (PSYSTEM_AUDIT_ACE)AceHeader;
|
||||
KmtOk(AuditAce->Mask == Mask, FileAndLine, "[%lu] AuditAce Mask is 0x%lx, expected 0x%lx\n", i, AuditAce->Mask, Mask);
|
||||
CheckSid__((PSID)&AuditAce->SidStart,
|
||||
AceHeader->AceSize - FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart),
|
||||
Sid,
|
||||
FileAndLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
CheckAcl__(
|
||||
_In_ PACL Acl,
|
||||
_In_ ULONG AceCount,
|
||||
_In_ PCSTR FileAndLine,
|
||||
...)
|
||||
{
|
||||
va_list Arguments;
|
||||
|
||||
va_start(Arguments, FileAndLine);
|
||||
VCheckAcl__(Acl, AceCount, FileAndLine, Arguments);
|
||||
va_end(Arguments);
|
||||
}
|
880
rostests/kmtests/ntos_se/SeInheritance.c
Normal file
880
rostests/kmtests/ntos_se/SeInheritance.c
Normal file
|
@ -0,0 +1,880 @@
|
|||
/*
|
||||
* PROJECT: ReactOS kernel-mode tests
|
||||
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
|
||||
* PURPOSE: Kernel-Mode Test for object security inheritance
|
||||
* PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
|
||||
*/
|
||||
|
||||
#include <kmt_test.h>
|
||||
#include "se.h"
|
||||
|
||||
static GENERIC_MAPPING GenericMapping =
|
||||
{
|
||||
STANDARD_RIGHTS_READ | 0x1001,
|
||||
STANDARD_RIGHTS_WRITE | 0x2002,
|
||||
STANDARD_RIGHTS_EXECUTE | 0x4004,
|
||||
STANDARD_RIGHTS_ALL | 0x800F,
|
||||
};
|
||||
|
||||
static
|
||||
VOID
|
||||
TestSeAssignSecurity(
|
||||
_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PTOKEN Token;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||
SECURITY_DESCRIPTOR ParentDescriptor;
|
||||
SECURITY_DESCRIPTOR ExplicitDescriptor;
|
||||
ACL EmptyAcl;
|
||||
PACL Acl;
|
||||
PACL Acl2;
|
||||
ULONG AclSize;
|
||||
ULONG UsingDefault;
|
||||
ULONG CanInherit;
|
||||
ULONG AceFlags;
|
||||
ULONG AceFlags2;
|
||||
ULONG Access;
|
||||
PSID GenericSid;
|
||||
PSID GenericSid2;
|
||||
ACCESS_MASK GenericMask;
|
||||
ACCESS_MASK GenericMask2;
|
||||
PSID SpecificSid;
|
||||
ACCESS_MASK SpecificMask;
|
||||
ACCESS_MASK SpecificMask2;
|
||||
BOOLEAN ParentUsable;
|
||||
|
||||
Token = SubjectContext->PrimaryToken;
|
||||
CheckAcl(Token->DefaultDacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, GENERIC_ALL,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, GENERIC_READ | GENERIC_EXECUTE | STANDARD_RIGHTS_READ);
|
||||
CheckSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid, NO_SIZE, SeExports->SeAliasAdminsSid);
|
||||
CheckSid(Token->PrimaryGroup, NO_SIZE, SeExports->SeLocalSystemSid);
|
||||
// Flags with no effect on current tests: SEF_SACL_AUTO_INHERIT, SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT
|
||||
#define StartTestAssign(Parent, Explicit, IsDir, GotDacl, GotSacl) \
|
||||
SecurityDescriptor = NULL; \
|
||||
Status = SeAssignSecurity (Parent, \
|
||||
Explicit, \
|
||||
&SecurityDescriptor, \
|
||||
/*NULL,*/ \
|
||||
IsDir, \
|
||||
/*0,*/ \
|
||||
SubjectContext, \
|
||||
&GenericMapping, \
|
||||
PagedPool); \
|
||||
ok_eq_hex(Status, STATUS_SUCCESS); \
|
||||
if (!skip(NT_SUCCESS(Status), "No security\n")) \
|
||||
{ \
|
||||
PACL Dacl, Sacl; \
|
||||
PSID Owner, Group; \
|
||||
BOOLEAN Present; \
|
||||
BOOLEAN DaclDefaulted, SaclDefaulted; \
|
||||
BOOLEAN OwnerDefaulted, GroupDefaulted; \
|
||||
Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, \
|
||||
&Present, \
|
||||
&Dacl, \
|
||||
&DaclDefaulted); \
|
||||
ok_eq_hex(Status, STATUS_SUCCESS); \
|
||||
ok_eq_uint(Present, GotDacl); \
|
||||
if (!NT_SUCCESS(Status) || !Present) \
|
||||
Dacl = NULL; \
|
||||
Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor, \
|
||||
&Present, \
|
||||
&Sacl, \
|
||||
&SaclDefaulted); \
|
||||
ok_eq_hex(Status, STATUS_SUCCESS); \
|
||||
ok_eq_uint(Present, GotSacl); \
|
||||
if (!NT_SUCCESS(Status) || !Present) \
|
||||
Sacl = NULL; \
|
||||
Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, \
|
||||
&Owner, \
|
||||
&OwnerDefaulted); \
|
||||
ok_eq_hex(Status, STATUS_SUCCESS); \
|
||||
if (skip(NT_SUCCESS(Status), "No owner\n")) \
|
||||
Owner = NULL; \
|
||||
Status = RtlGetGroupSecurityDescriptor(SecurityDescriptor, \
|
||||
&Group, \
|
||||
&GroupDefaulted); \
|
||||
ok_eq_hex(Status, STATUS_SUCCESS); \
|
||||
if (skip(NT_SUCCESS(Status), "No group\n")) \
|
||||
Group = NULL;
|
||||
|
||||
#define EndTestAssign() \
|
||||
SeDeassignSecurity(&SecurityDescriptor); \
|
||||
}
|
||||
#define StartTestAssignLoop(Parent, Explicit) \
|
||||
{ \
|
||||
BOOLEAN IsDir; \
|
||||
BOOLEAN UsingParent; \
|
||||
BOOLEAN UsingExplicit; \
|
||||
for (IsDir = FALSE; IsDir <= TRUE; IsDir++) \
|
||||
{ \
|
||||
for (UsingParent = FALSE; UsingParent <= TRUE; UsingParent++) \
|
||||
{ \
|
||||
for (UsingExplicit = FALSE; UsingExplicit <= TRUE; UsingExplicit++) \
|
||||
{ \
|
||||
StartTestAssign(UsingParent ? Parent : NULL, \
|
||||
UsingExplicit ? Explicit : NULL, \
|
||||
IsDir, \
|
||||
TRUE, \
|
||||
FALSE)
|
||||
#define EndTestAssignLoop() \
|
||||
EndTestAssign() \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
#define TestAssignExpectDefault(Parent, Explicit, IsDir) \
|
||||
StartTestAssign(Parent, Explicit, IsDir, TRUE, FALSE) \
|
||||
ok_eq_uint(DaclDefaulted, FALSE); \
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, \
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); \
|
||||
ok_eq_uint(OwnerDefaulted, FALSE); \
|
||||
CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); \
|
||||
ok_eq_uint(GroupDefaulted, FALSE); \
|
||||
CheckSid(Group, NO_SIZE, Token->PrimaryGroup); \
|
||||
EndTestAssign()
|
||||
#define TestAssignExpectDefaultAll() \
|
||||
TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE) \
|
||||
TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE) \
|
||||
TestAssignExpectDefault(NULL, &ExplicitDescriptor, FALSE) \
|
||||
TestAssignExpectDefault(NULL, &ExplicitDescriptor, TRUE) \
|
||||
TestAssignExpectDefault(&ParentDescriptor, &ExplicitDescriptor, FALSE) \
|
||||
TestAssignExpectDefault(&ParentDescriptor, &ExplicitDescriptor, TRUE)
|
||||
|
||||
TestAssignExpectDefault(NULL, NULL, FALSE)
|
||||
TestAssignExpectDefault(NULL, NULL, TRUE)
|
||||
|
||||
/* Empty parent/explicit descriptors */
|
||||
Status = RtlCreateSecurityDescriptor(&ParentDescriptor,
|
||||
SECURITY_DESCRIPTOR_REVISION);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlCreateSecurityDescriptor(&ExplicitDescriptor,
|
||||
SECURITY_DESCRIPTOR_REVISION);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
TestAssignExpectDefaultAll()
|
||||
|
||||
/* NULL DACL in parent/explicit descriptor */
|
||||
for (UsingDefault = FALSE; UsingDefault <= TRUE; UsingDefault++)
|
||||
{
|
||||
Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
|
||||
TRUE,
|
||||
NULL,
|
||||
UsingDefault);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
TRUE,
|
||||
NULL,
|
||||
UsingDefault);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
|
||||
//trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
if (UsingExplicit)
|
||||
{
|
||||
ok(Dacl == NULL, "Dacl = %p\n", Dacl);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
}
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
|
||||
EndTestAssignLoop()
|
||||
}
|
||||
|
||||
/* Empty default DACL in parent/explicit descriptor */
|
||||
for (UsingDefault = FALSE; UsingDefault <= TRUE; UsingDefault++)
|
||||
{
|
||||
Status = RtlCreateAcl(&EmptyAcl, sizeof(EmptyAcl), ACL_REVISION);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
|
||||
TRUE,
|
||||
&EmptyAcl,
|
||||
UsingDefault);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
TRUE,
|
||||
&EmptyAcl,
|
||||
UsingDefault);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
|
||||
//trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
if (UsingExplicit)
|
||||
{
|
||||
CheckAcl(Dacl, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
}
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
|
||||
EndTestAssignLoop()
|
||||
}
|
||||
|
||||
|
||||
AclSize = sizeof(ACL) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid(SeExports->SeWorldSid);
|
||||
Acl = ExAllocatePoolWithTag(PagedPool, AclSize, 'ASmK');
|
||||
if (skip(Acl != NULL, "Out of memory\n"))
|
||||
return;
|
||||
|
||||
Acl2 = ExAllocatePoolWithTag(PagedPool, AclSize, 'ASmK');
|
||||
if (skip(Acl2 != NULL, "Out of memory\n"))
|
||||
{
|
||||
ExFreePoolWithTag(Acl, 'ASmK');
|
||||
return;
|
||||
}
|
||||
|
||||
/* Simple DACL in parent/explicit descriptor */
|
||||
for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
|
||||
{
|
||||
Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, 0, READ_CONTROL, SeExports->SeWorldSid);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 1));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 2));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
|
||||
//trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
if (UsingExplicit)
|
||||
{
|
||||
CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid, READ_CONTROL);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
}
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
|
||||
EndTestAssignLoop()
|
||||
}
|
||||
|
||||
/* Object-inheritable DACL in parent/explicit descriptor */
|
||||
for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
|
||||
{
|
||||
Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, OBJECT_INHERIT_ACE, READ_CONTROL, SeExports->SeWorldSid);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 1));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 2));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
|
||||
//trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
if (UsingExplicit && (!UsingParent || !FlagOn(UsingDefault, 2)))
|
||||
{
|
||||
CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, OBJECT_INHERIT_ACE, SeExports->SeWorldSid, READ_CONTROL);
|
||||
}
|
||||
else if (UsingParent)
|
||||
{
|
||||
CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, IsDir ? INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE : 0, SeExports->SeWorldSid, READ_CONTROL);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
}
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
|
||||
EndTestAssignLoop()
|
||||
}
|
||||
|
||||
/* Container-inheritable DACL in parent/explicit descriptor */
|
||||
for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
|
||||
{
|
||||
Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, CONTAINER_INHERIT_ACE, READ_CONTROL, SeExports->SeWorldSid);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 1));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 2));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
|
||||
//trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
if (UsingExplicit || (UsingParent && IsDir))
|
||||
{
|
||||
CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeWorldSid, READ_CONTROL);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
}
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
|
||||
EndTestAssignLoop()
|
||||
}
|
||||
|
||||
/* Fully inheritable DACL in parent/explicit descriptor */
|
||||
for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
|
||||
{
|
||||
Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, READ_CONTROL, SeExports->SeWorldSid);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 1));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 2));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
|
||||
//trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault);
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
if (UsingExplicit && (!UsingParent || !FlagOn(UsingDefault, 2)))
|
||||
{
|
||||
CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, SeExports->SeWorldSid, READ_CONTROL);
|
||||
}
|
||||
else if (UsingParent)
|
||||
{
|
||||
CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, IsDir ? OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE : 0, SeExports->SeWorldSid, READ_CONTROL);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
}
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
|
||||
EndTestAssignLoop()
|
||||
}
|
||||
|
||||
/* Different DACLs in parent and explicit descriptors */
|
||||
for (Access = 0; Access <= 1; Access++)
|
||||
{
|
||||
if (Access == 1)
|
||||
{
|
||||
GenericSid = SeExports->SeCreatorOwnerSid;
|
||||
SpecificSid = SeExports->SeAliasAdminsSid;
|
||||
GenericMask = GENERIC_READ;
|
||||
SpecificMask = STANDARD_RIGHTS_READ | 0x0001;
|
||||
GenericSid2 = SeExports->SeCreatorGroupSid;
|
||||
GenericMask2 = GENERIC_EXECUTE;
|
||||
SpecificMask2 = STANDARD_RIGHTS_EXECUTE | 0x0004;
|
||||
}
|
||||
else
|
||||
{
|
||||
GenericSid = SeExports->SeWorldSid;
|
||||
SpecificSid = SeExports->SeWorldSid;
|
||||
GenericMask = READ_CONTROL;
|
||||
SpecificMask = READ_CONTROL;
|
||||
GenericSid2 = SeExports->SeLocalSystemSid;
|
||||
GenericMask2 = SYNCHRONIZE;
|
||||
SpecificMask2 = SYNCHRONIZE;
|
||||
}
|
||||
for (CanInherit = 0; CanInherit <= 255; CanInherit++)
|
||||
{
|
||||
for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
|
||||
{
|
||||
Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
AceFlags = CanInherit & 0xf;
|
||||
Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, AceFlags, GenericMask, GenericSid);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlCreateAcl(Acl2, AclSize, ACL_REVISION);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
AceFlags2 = CanInherit >> 4;
|
||||
Status = RtlAddAccessAllowedAceEx(Acl2, ACL_REVISION, AceFlags2, GenericMask2, GenericSid2);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 1));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
TRUE,
|
||||
Acl2,
|
||||
BooleanFlagOn(UsingDefault, 2));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor)
|
||||
//trace("Explicit %u, Parent %u, Dir %u, Default %u, Inherit %u, Access %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault, CanInherit, Access);
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
ParentUsable = UsingParent;
|
||||
if (!IsDir && !FlagOn(AceFlags, OBJECT_INHERIT_ACE))
|
||||
ParentUsable = FALSE;
|
||||
else if (IsDir && !FlagOn(AceFlags, CONTAINER_INHERIT_ACE) &&
|
||||
(!FlagOn(AceFlags, OBJECT_INHERIT_ACE) || FlagOn(AceFlags, NO_PROPAGATE_INHERIT_ACE)))
|
||||
ParentUsable = FALSE;
|
||||
|
||||
if (UsingExplicit && (!FlagOn(UsingDefault, 2) || !ParentUsable))
|
||||
{
|
||||
CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, AceFlags2, GenericSid2, FlagOn(AceFlags2, INHERIT_ONLY_ACE) ? GenericMask2 : SpecificMask2);
|
||||
}
|
||||
else if (ParentUsable)
|
||||
{
|
||||
if (IsDir && !FlagOn(AceFlags, NO_PROPAGATE_INHERIT_ACE))
|
||||
{
|
||||
if (FlagOn(AceFlags, CONTAINER_INHERIT_ACE) && (SpecificMask != GenericMask || SpecificSid != GenericSid))
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SpecificSid, SpecificMask,
|
||||
ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE | (AceFlags & OBJECT_INHERIT_ACE), GenericSid, GenericMask);
|
||||
else
|
||||
CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, (FlagOn(AceFlags, CONTAINER_INHERIT_ACE) ? 0 : INHERIT_ONLY_ACE) |
|
||||
(AceFlags & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE)), GenericSid, GenericMask);
|
||||
}
|
||||
else
|
||||
CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, 0, SpecificSid, SpecificMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
}
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid);
|
||||
EndTestAssignLoop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* NULL parameters */
|
||||
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
|
||||
KmtStartSeh()
|
||||
Status = SeAssignSecurity(NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
SubjectContext,
|
||||
&GenericMapping,
|
||||
PagedPool);
|
||||
KmtEndSeh(STATUS_ACCESS_VIOLATION);
|
||||
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
|
||||
|
||||
SecurityDescriptor = KmtInvalidPointer;
|
||||
KmtStartSeh()
|
||||
Status = SeAssignSecurity(NULL,
|
||||
NULL,
|
||||
&SecurityDescriptor,
|
||||
FALSE,
|
||||
NULL,
|
||||
&GenericMapping,
|
||||
PagedPool);
|
||||
ok_eq_hex(Status, STATUS_NO_TOKEN);
|
||||
KmtEndSeh(STATUS_SUCCESS);
|
||||
ok_eq_pointer(SecurityDescriptor, NULL);
|
||||
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
|
||||
|
||||
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
|
||||
KmtStartSeh()
|
||||
Status = SeAssignSecurity(NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
NULL,
|
||||
&GenericMapping,
|
||||
PagedPool);
|
||||
KmtEndSeh(STATUS_ACCESS_VIOLATION);
|
||||
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
|
||||
|
||||
/* Test with Token == NULL */
|
||||
if (1)
|
||||
{
|
||||
/* Crash in SeLockSubjectContext while holding a critical region */
|
||||
SubjectContext->PrimaryToken = NULL;
|
||||
KmtStartSeh()
|
||||
SecurityDescriptor = KmtInvalidPointer;
|
||||
Status = SeAssignSecurity(NULL,
|
||||
NULL,
|
||||
&SecurityDescriptor,
|
||||
FALSE,
|
||||
SubjectContext,
|
||||
&GenericMapping,
|
||||
PagedPool);
|
||||
KmtEndSeh(STATUS_ACCESS_VIOLATION)
|
||||
ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
|
||||
KeLeaveCriticalRegion();
|
||||
ok_eq_pointer(SecurityDescriptor, KmtInvalidPointer);
|
||||
SubjectContext->PrimaryToken = Token;
|
||||
}
|
||||
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
|
||||
|
||||
/* Test with NULL owner in Token */
|
||||
if (1)
|
||||
{
|
||||
/* Crash after locking the subject context */
|
||||
PSID OldOwner;
|
||||
OldOwner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
|
||||
Token->UserAndGroups[Token->DefaultOwnerIndex].Sid = NULL;
|
||||
KmtStartSeh()
|
||||
SecurityDescriptor = KmtInvalidPointer;
|
||||
Status = SeAssignSecurity(NULL,
|
||||
NULL,
|
||||
&SecurityDescriptor,
|
||||
FALSE,
|
||||
SubjectContext,
|
||||
&GenericMapping,
|
||||
PagedPool);
|
||||
KmtEndSeh(STATUS_ACCESS_VIOLATION)
|
||||
ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
|
||||
SeUnlockSubjectContext(SubjectContext);
|
||||
ok_eq_pointer(SecurityDescriptor, KmtInvalidPointer);
|
||||
Token->UserAndGroups[Token->DefaultOwnerIndex].Sid = OldOwner;
|
||||
}
|
||||
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
|
||||
|
||||
/* Test with NULL group in Token */
|
||||
if (1)
|
||||
{
|
||||
PSID OldGroup;
|
||||
OldGroup = Token->PrimaryGroup;
|
||||
Token->PrimaryGroup = NULL;
|
||||
KmtStartSeh()
|
||||
SecurityDescriptor = KmtInvalidPointer;
|
||||
Status = SeAssignSecurity(NULL,
|
||||
NULL,
|
||||
&SecurityDescriptor,
|
||||
FALSE,
|
||||
SubjectContext,
|
||||
&GenericMapping,
|
||||
PagedPool);
|
||||
ok_eq_hex(Status, STATUS_INVALID_PRIMARY_GROUP);
|
||||
ok_eq_pointer(SecurityDescriptor, NULL);
|
||||
SeDeassignSecurity(&SecurityDescriptor);
|
||||
KmtEndSeh(STATUS_SUCCESS);
|
||||
Token->PrimaryGroup = OldGroup;
|
||||
}
|
||||
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
|
||||
|
||||
/* Test with NULL DACL in Token */
|
||||
if (1)
|
||||
{
|
||||
PACL OldDacl;
|
||||
OldDacl = Token->DefaultDacl;
|
||||
Token->DefaultDacl = NULL;
|
||||
KmtStartSeh()
|
||||
StartTestAssign(NULL, NULL, FALSE, FALSE, FALSE)
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
|
||||
EndTestAssign()
|
||||
KmtEndSeh(STATUS_SUCCESS);
|
||||
Token->DefaultDacl = OldDacl;
|
||||
}
|
||||
ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
|
||||
|
||||
/* SEF_DEFAULT_OWNER_FROM_PARENT/SEF_DEFAULT_GROUP_FROM_PARENT */
|
||||
SecurityDescriptor = KmtInvalidPointer;
|
||||
Status = SeAssignSecurityEx(NULL,
|
||||
NULL,
|
||||
&SecurityDescriptor,
|
||||
NULL,
|
||||
FALSE,
|
||||
SEF_DEFAULT_OWNER_FROM_PARENT,
|
||||
SubjectContext,
|
||||
&GenericMapping,
|
||||
PagedPool);
|
||||
ok_eq_hex(Status, STATUS_INVALID_OWNER);
|
||||
ok_eq_pointer(SecurityDescriptor, NULL);
|
||||
SeDeassignSecurity(&SecurityDescriptor);
|
||||
SecurityDescriptor = KmtInvalidPointer;
|
||||
Status = SeAssignSecurityEx(NULL,
|
||||
NULL,
|
||||
&SecurityDescriptor,
|
||||
NULL,
|
||||
FALSE,
|
||||
SEF_DEFAULT_GROUP_FROM_PARENT,
|
||||
SubjectContext,
|
||||
&GenericMapping,
|
||||
PagedPool);
|
||||
ok_eq_hex(Status, STATUS_INVALID_PRIMARY_GROUP);
|
||||
ok_eq_pointer(SecurityDescriptor, NULL);
|
||||
SeDeassignSecurity(&SecurityDescriptor);
|
||||
SecurityDescriptor = KmtInvalidPointer;
|
||||
Status = SeAssignSecurityEx(NULL,
|
||||
NULL,
|
||||
&SecurityDescriptor,
|
||||
NULL,
|
||||
FALSE,
|
||||
SEF_DEFAULT_OWNER_FROM_PARENT | SEF_DEFAULT_GROUP_FROM_PARENT,
|
||||
SubjectContext,
|
||||
&GenericMapping,
|
||||
PagedPool);
|
||||
ok_eq_hex(Status, STATUS_INVALID_OWNER);
|
||||
ok_eq_pointer(SecurityDescriptor, NULL);
|
||||
SeDeassignSecurity(&SecurityDescriptor);
|
||||
|
||||
/* Quick test whether inheritance for SACLs behaves the same as DACLs */
|
||||
Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor,
|
||||
FALSE,
|
||||
NULL,
|
||||
FALSE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
FALSE,
|
||||
NULL,
|
||||
FALSE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
|
||||
{
|
||||
Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor,
|
||||
TRUE,
|
||||
NULL,
|
||||
BooleanFlagOn(UsingDefault, 1));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
TRUE,
|
||||
NULL,
|
||||
BooleanFlagOn(UsingDefault, 2));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE)
|
||||
TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE)
|
||||
StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE)
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
ok_eq_uint(SaclDefaulted, FALSE);
|
||||
ok_eq_pointer(Sacl, NULL);
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
|
||||
EndTestAssign()
|
||||
}
|
||||
|
||||
for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
|
||||
{
|
||||
Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor,
|
||||
TRUE,
|
||||
&EmptyAcl,
|
||||
BooleanFlagOn(UsingDefault, 1));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
TRUE,
|
||||
&EmptyAcl,
|
||||
BooleanFlagOn(UsingDefault, 2));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE)
|
||||
TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE)
|
||||
StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE)
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
ok_eq_uint(SaclDefaulted, FALSE);
|
||||
CheckAcl(Sacl, 0);
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
|
||||
EndTestAssign()
|
||||
}
|
||||
|
||||
for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
|
||||
{
|
||||
Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlxAddAuditAccessAceEx(Acl, ACL_REVISION, 0, READ_CONTROL, SeExports->SeWorldSid, TRUE, TRUE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 1));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 2));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE)
|
||||
TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE)
|
||||
StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE)
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
ok_eq_uint(SaclDefaulted, FALSE);
|
||||
CheckAcl(Sacl, 1, SYSTEM_AUDIT_ACE_TYPE, SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG, SeExports->SeWorldSid, READ_CONTROL);
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
|
||||
EndTestAssign()
|
||||
}
|
||||
|
||||
for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++)
|
||||
{
|
||||
Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlxAddAuditAccessAceEx(Acl, ACL_REVISION, OBJECT_INHERIT_ACE, READ_CONTROL, SeExports->SeCreatorOwnerSid, TRUE, TRUE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 1));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor,
|
||||
TRUE,
|
||||
Acl,
|
||||
BooleanFlagOn(UsingDefault, 2));
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
StartTestAssign(&ParentDescriptor, NULL, FALSE, TRUE, TRUE)
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
ok_eq_uint(SaclDefaulted, FALSE);
|
||||
CheckAcl(Sacl, 1, SYSTEM_AUDIT_ACE_TYPE, SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid, READ_CONTROL);
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
|
||||
EndTestAssign()
|
||||
StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE)
|
||||
ok_eq_uint(DaclDefaulted, FALSE);
|
||||
CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005);
|
||||
ok_eq_uint(SaclDefaulted, FALSE);
|
||||
CheckAcl(Sacl, 1, SYSTEM_AUDIT_ACE_TYPE, OBJECT_INHERIT_ACE | SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG, SeExports->SeCreatorOwnerSid, READ_CONTROL);
|
||||
ok_eq_uint(OwnerDefaulted, FALSE);
|
||||
CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
|
||||
ok_eq_uint(GroupDefaulted, FALSE);
|
||||
CheckSid(Group, NO_SIZE, Token->PrimaryGroup);
|
||||
EndTestAssign()
|
||||
}
|
||||
|
||||
/* TODO: Test duplicate ACEs */
|
||||
/* TODO: Test INHERITED_ACE flag */
|
||||
/* TODO: Test invalid ACE flags */
|
||||
/* TODO: Test more AutoInheritFlags values */
|
||||
|
||||
ExFreePoolWithTag(Acl2, 'ASmK');
|
||||
ExFreePoolWithTag(Acl, 'ASmK');
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
SystemThread(
|
||||
_In_ PVOID Context)
|
||||
{
|
||||
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
||||
ok_eq_pointer(Context, NULL);
|
||||
|
||||
SeCaptureSubjectContext(&SubjectContext);
|
||||
TestSeAssignSecurity(&SubjectContext);
|
||||
/* TODO: Test SeSetSecurityDescrptorInfo[Ex] */
|
||||
SeReleaseSubjectContext(&SubjectContext);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
TestObRootSecurity(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING ObjectPath = RTL_CONSTANT_STRING(L"\\");
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
HANDLE Handle;
|
||||
PVOID RootDirectory;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||
BOOLEAN MemoryAllocated;
|
||||
PACL Acl;
|
||||
BOOLEAN Present;
|
||||
BOOLEAN Defaulted;
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&ObjectPath,
|
||||
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenDirectoryObject(&Handle,
|
||||
0,
|
||||
&ObjectAttributes);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
if (skip(NT_SUCCESS(Status), "No handle\n"))
|
||||
return;
|
||||
Status = ObReferenceObjectByHandle(Handle,
|
||||
0,
|
||||
NULL,
|
||||
KernelMode,
|
||||
&RootDirectory,
|
||||
NULL);
|
||||
ObCloseHandle(Handle, KernelMode);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
if (skip(NT_SUCCESS(Status), "No object\n"))
|
||||
return;
|
||||
Status = ObGetObjectSecurity(RootDirectory,
|
||||
&SecurityDescriptor,
|
||||
&MemoryAllocated);
|
||||
ObDereferenceObject(RootDirectory);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
if (skip(NT_SUCCESS(Status), "No security\n"))
|
||||
return;
|
||||
Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
|
||||
&Present,
|
||||
&Acl,
|
||||
&Defaulted);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok_eq_uint(Present, TRUE);
|
||||
if (!skip(NT_SUCCESS(Status) && Present, "No DACL\n"))
|
||||
{
|
||||
ok_eq_uint(Defaulted, FALSE);
|
||||
CheckAcl(Acl, 4, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid, STANDARD_RIGHTS_READ | DIRECTORY_TRAVERSE | DIRECTORY_QUERY,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
|
||||
ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid, STANDARD_RIGHTS_READ | DIRECTORY_TRAVERSE | DIRECTORY_QUERY);
|
||||
}
|
||||
Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor,
|
||||
&Present,
|
||||
&Acl,
|
||||
&Defaulted);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok_eq_uint(Present, FALSE);
|
||||
ObReleaseObjectSecurity(SecurityDescriptor, MemoryAllocated);
|
||||
}
|
||||
|
||||
START_TEST(SeInheritance)
|
||||
{
|
||||
PKTHREAD Thread;
|
||||
|
||||
TestObRootSecurity();
|
||||
Thread = KmtStartThread(SystemThread, NULL);
|
||||
KmtFinishThread(Thread, NULL);
|
||||
}
|
63
rostests/kmtests/ntos_se/se.h
Normal file
63
rostests/kmtests/ntos_se/se.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* PROJECT: ReactOS kernel-mode tests
|
||||
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
|
||||
* PURPOSE: Kernel-Mode Test Suite Se helper declarations
|
||||
* PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
|
||||
*/
|
||||
|
||||
#ifndef _KMTEST_SE_H_
|
||||
#define _KMTEST_SE_H_
|
||||
|
||||
/* FIXME: belongs in ntifs.h or something */
|
||||
#define SEF_DACL_AUTO_INHERIT 1
|
||||
#define SEF_SACL_AUTO_INHERIT 2
|
||||
#define SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT 4
|
||||
#define SEF_AVOID_PRIVILEGE_CHECK 8
|
||||
#define SEF_AVOID_OWNER_CHECK 16
|
||||
#define SEF_DEFAULT_OWNER_FROM_PARENT 32
|
||||
#define SEF_DEFAULT_GROUP_FROM_PARENT 64
|
||||
#define SEF_MACL_NO_WRITE_UP 256
|
||||
#define SEF_MACL_NO_READ_UP 512
|
||||
#define SEF_MACL_NO_EXECUTE_UP 1024
|
||||
#define SEF_AI_USE_EXTRA_PARAMS 2048
|
||||
#define SEF_AVOID_OWNER_RESTRICTION 4096
|
||||
#define SEF_MACL_VALID_FLAGS (SEF_MACL_NO_WRITE_UP | SEF_MACL_NO_READ_UP | SEF_MACL_NO_EXECUTE_UP)
|
||||
|
||||
NTSTATUS
|
||||
RtlxAddAuditAccessAceEx(
|
||||
_Inout_ PACL Acl,
|
||||
_In_ ULONG Revision,
|
||||
_In_ ULONG Flags,
|
||||
_In_ ACCESS_MASK AccessMask,
|
||||
_In_ PSID Sid,
|
||||
_In_ BOOLEAN Success,
|
||||
_In_ BOOLEAN Failure);
|
||||
|
||||
#define NO_SIZE ((ULONG)-1)
|
||||
|
||||
#define CheckSid(Sid, SidSize, ExpectedSid) CheckSid_(Sid, SidSize, ExpectedSid, __FILE__, __LINE__)
|
||||
#define CheckSid_(Sid, SidSize, ExpectedSid, file, line) CheckSid__(Sid, SidSize, ExpectedSid, file ":" KMT_STRINGIZE(line))
|
||||
VOID
|
||||
CheckSid__(
|
||||
_In_ PSID Sid,
|
||||
_In_ ULONG SidSize,
|
||||
_In_ PISID ExpectedSid,
|
||||
_In_ PCSTR FileAndLine);
|
||||
|
||||
VOID
|
||||
VCheckAcl__(
|
||||
_In_ PACL Acl,
|
||||
_In_ ULONG AceCount,
|
||||
_In_ PCSTR FileAndLine,
|
||||
_In_ va_list Arguments);
|
||||
|
||||
#define CheckAcl(Acl, AceCount, ...) CheckAcl_(Acl, AceCount, __FILE__, __LINE__, ##__VA_ARGS__)
|
||||
#define CheckAcl_(Acl, AceCount, file, line, ...) CheckAcl__(Acl, AceCount, file ":" KMT_STRINGIZE(line), ##__VA_ARGS__)
|
||||
VOID
|
||||
CheckAcl__(
|
||||
_In_ PACL Acl,
|
||||
_In_ ULONG AceCount,
|
||||
_In_ PCSTR FileAndLine,
|
||||
...);
|
||||
|
||||
#endif /* !defined _KMTEST_SE_H_ */
|
Loading…
Reference in a new issue