[KMTESTS:SE]

- Add a test for SeAssignSecurity[Ex]
CORE-8745

svn path=/trunk/; revision=65258
This commit is contained in:
Thomas Faber 2014-11-04 22:42:15 +00:00
parent 71606f1035
commit 418629f6a9
5 changed files with 1141 additions and 0 deletions

View file

@ -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}

View file

@ -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 },

View 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);
}

View 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);
}

View 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_ */