Windows2000/private/ntos/se/ctaccess.c

929 lines
32 KiB
C

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
ctaccess.c
Abstract:
Common access validation test routines
These routines are used in both kernel and user mode tests.
This test assumes the security runtime library routines are functioning correctly.
Author:
Robert Reichel (robertre) 12/14/90
Environment:
Test of access validation routines
Revision History:
v1: robertre
Created
--*/
#include "tsecomm.c" // Mode dependent macros and routines.
// Define the local macros and procedure for this module
// Return a pointer to the first Ace in an Acl (even if the Acl is empty).
// PACE_HEADER
// FirstAce (
// IN PACL Acl
// );
#define FirstAce(Acl) ((PVOID)((PUCHAR)(Acl) + sizeof(ACL)))
// Return a pointer to the next Ace in a sequence (even if the input
// Ace is the one in the sequence).
// PACE_HEADER
// NextAce (
// IN PACE_HEADER Ace
// );
#define NextAce(Ace) ((PVOID)((PUCHAR)(Ace) + ((PACE_HEADER)(Ace))->AceSize))
VOID
DumpAcl (
IN PACL Acl
);
// Module wide variables //
#define DEFAULT_DACL_LENGTH (1024L)
#define GROUP_IDS_LENGTH (1024L)
#define NEW_GROUP_STATE_LENGTH (1024L)
#define PRIVILEGES_LENGTH (128L)
#define TOO_BIG_ACL_SIZE (2048L)
// definitions related to TokenWithGroups
#define FLINTSTONE_INDEX (0L)
#define CHILD_INDEX (1L)
#define NEANDERTHOL_INDEX (2L)
#define WORLD_INDEX (3L)
#define GROUP_COUNT (4L)
// Definitions related to TokenWithPrivileges
#define UNSOLICITED_INDEX (0L)
#define SECURITY_INDEX (1L)
#define PRIVILEGE_COUNT (2L)
// Access types
#define SET_WIDGET_COLOR 0x00000001
#define SET_WIDGET_SIZE 0x00000002
#define GET_WIDGET_COLOR 0x00000004
#define GET_WIDGET_SIZE 0x00000008
#define START_WIDGET 0x00000010
#define STOP_WIDGET 0x00000020
#define GIVE_WIDGET 0x00000040
#define TAKE_WIDGET 0x00000080
NTSTATUS Status;
HANDLE SimpleToken;
HANDLE TokenWithGroups;
HANDLE TokenWithDefaultOwner;
HANDLE TokenWithPrivileges;
HANDLE TokenWithDefaultDacl;
HANDLE Token;
HANDLE ImpersonationToken;
HANDLE PrimaryToken;
HANDLE AnonymousToken;
OBJECT_ATTRIBUTES PrimaryTokenAttributes;
PSECURITY_DESCRIPTOR PrimarySecurityDescriptor;
SECURITY_QUALITY_OF_SERVICE PrimarySecurityQos;
OBJECT_ATTRIBUTES ImpersonationTokenAttributes;
PSECURITY_DESCRIPTOR ImpersonationSecurityDescriptor;
SECURITY_QUALITY_OF_SERVICE ImpersonationSecurityQos;
OBJECT_ATTRIBUTES AnonymousTokenAttributes;
PSECURITY_DESCRIPTOR AnonymousSecurityDescriptor;
SECURITY_QUALITY_OF_SERVICE AnonymousSecurityQos;
ULONG DisabledGroupAttributes;
ULONG OptionalGroupAttributes;
ULONG NormalGroupAttributes;
ULONG OwnerGroupAttributes;
ULONG LengthAvailable;
ULONG CurrentLength;
TIME_FIELDS TempTimeFields = {3000, 1, 1, 1, 1, 1, 1, 1};
LARGE_INTEGER NoExpiration;
LUID DummyAuthenticationId;
LUID SystemAuthenticationId = SYSTEM_LUID;
TOKEN_SOURCE TestSource = {"SE: TEST", 0};
PSID Owner;
PSID Group;
PACL Dacl;
PSID TempOwner;
PSID TempGroup;
PACL TempDacl;
// Initialization Routine //
BOOLEAN
TestTokenInitialize()
{
TSeVariableInitialization(); // Initialize global variables
DisabledGroupAttributes = (SE_GROUP_ENABLED_BY_DEFAULT);
OptionalGroupAttributes = (SE_GROUP_ENABLED_BY_DEFAULT |
SE_GROUP_ENABLED
);
NormalGroupAttributes = (SE_GROUP_MANDATORY |
SE_GROUP_ENABLED_BY_DEFAULT |
SE_GROUP_ENABLED
);
OwnerGroupAttributes = (SE_GROUP_MANDATORY |
SE_GROUP_ENABLED_BY_DEFAULT |
SE_GROUP_ENABLED |
SE_GROUP_OWNER
);
PrimarySecurityDescriptor =
(PSECURITY_DESCRIPTOR)TstAllocatePool( PagedPool, 1024 );
InitializeObjectAttributes(
&PrimaryTokenAttributes,
NULL,
OBJ_INHERIT,
NULL,
NULL
);
ImpersonationSecurityDescriptor =
(PSECURITY_DESCRIPTOR)TstAllocatePool( PagedPool, 1024 );
ImpersonationSecurityQos.Length = (ULONG)sizeof(SECURITY_QUALITY_OF_SERVICE);
ImpersonationSecurityQos.ImpersonationLevel = SecurityImpersonation;
ImpersonationSecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
ImpersonationSecurityQos.EffectiveOnly = FALSE;
InitializeObjectAttributes(
&ImpersonationTokenAttributes,
NULL,
OBJ_INHERIT,
NULL,
NULL
);
ImpersonationTokenAttributes.SecurityQualityOfService =
&ImpersonationSecurityQos;
AnonymousSecurityDescriptor =
(PSECURITY_DESCRIPTOR)TstAllocatePool( PagedPool, 1024 );
AnonymousSecurityQos.Length = (ULONG)sizeof(SECURITY_QUALITY_OF_SERVICE);
AnonymousSecurityQos.ImpersonationLevel = SecurityAnonymous;
AnonymousSecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
AnonymousSecurityQos.EffectiveOnly = FALSE;
InitializeObjectAttributes(
&AnonymousTokenAttributes,
NULL,
OBJ_INHERIT,
NULL,
NULL
);
AnonymousTokenAttributes.SecurityQualityOfService =
&AnonymousSecurityQos;
// Build an ACL for use.
Dacl = (PACL)TstAllocatePool( PagedPool, 256 );
Dacl->AclRevision=ACL_REVISION;
Dacl->Sbz1=0;
Dacl->Sbz2=0;
Dacl->AclSize=256;
Dacl->AceCount=0;
// Set up expiration times
TempTimeFields.Year = 3000;
TempTimeFields.Month = 1;
TempTimeFields.Day = 1;
TempTimeFields.Hour = 1;
TempTimeFields.Minute = 1;
TempTimeFields.Second = 1;
TempTimeFields.Milliseconds = 1;
TempTimeFields.Weekday = 1;
RtlTimeFieldsToTime( &TempTimeFields, &NoExpiration );
// Use a dummy authentication ID for a while.
DummyAuthenticationId = FredLuid;
// Use a token source specific to security test
NtAllocateLocallyUniqueId( &(TestSource.SourceIdentifier) );
DbgPrint("Done.\n");
return TRUE;
}
BOOLEAN
CreateDAclToken()
{
BOOLEAN CompletionStatus = TRUE;
TOKEN_USER UserId;
TOKEN_PRIMARY_GROUP PrimaryGroup;
PTOKEN_GROUPS GroupIds;
PTOKEN_PRIVILEGES Privileges;
TOKEN_DEFAULT_DACL DefaultDacl;
TOKEN_OWNER Owner;
PSECURITY_DESCRIPTOR Widget1SecurityDescriptor;
NTSTATUS AccessStatus;
ACCESS_MASK GrantedAccess;
PACCESS_ALLOWED_ACE AllowBarneySetColor;
PACCESS_ALLOWED_ACE AllowFredSetColor;
PACCESS_DENIED_ACE DenyPebblesSetColor;
PACCESS_ALLOWED_ACE AllowPebblesSetColor;
PACCESS_DENIED_ACE DenyFredSetColor;
PACCESS_ALLOWED_ACE AllowBarneySetSize;
PACCESS_ALLOWED_ACE AllowPebblesSetSize;
PACCESS_ALLOWED_ACE AllowPebblesGetColor;
PACCESS_ALLOWED_ACE AllowPebblesGetSize;
USHORT AllowBarneySetColorLength;
USHORT AllowFredSetColorLength;
USHORT DenyPebblesSetColorLength;
USHORT AllowPebblesSetColorLength;
USHORT DenyFredSetColorLength;
USHORT AllowBarneySetSizeLength;
USHORT AllowPebblesSetSizeLength;
USHORT AllowPebblesGetColorLength;
USHORT AllowPebblesGetSizeLength;
DbgPrint("\n");
GroupIds = (PTOKEN_GROUPS)TstAllocatePool( PagedPool,
GROUP_IDS_LENGTH
);
Privileges = (PTOKEN_PRIVILEGES)TstAllocatePool( PagedPool,
PRIVILEGES_LENGTH
);
DefaultDacl.DefaultDacl = (PACL)TstAllocatePool( PagedPool,
DEFAULT_DACL_LENGTH
);
// Create a token with default DACL
DbgPrint("Se: Create Token With Default Dacl ... ");
GroupIds->GroupCount = GROUP_COUNT;
GroupIds->Groups[FLINTSTONE_INDEX].Sid = FlintstoneSid;
GroupIds->Groups[CHILD_INDEX].Sid = ChildSid;
GroupIds->Groups[NEANDERTHOL_INDEX].Sid = NeandertholSid;
GroupIds->Groups[WORLD_INDEX].Sid = WorldSid;
GroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes;
GroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes;
GroupIds->Groups[NEANDERTHOL_INDEX].Attributes = OptionalGroupAttributes;
GroupIds->Groups[WORLD_INDEX].Attributes = NormalGroupAttributes;
UserId.User.Sid = PebblesSid;
UserId.User.Attributes = 0;
Owner.Owner = FlintstoneSid;
Privileges->PrivilegeCount = PRIVILEGE_COUNT;
Privileges->Privileges[UNSOLICITED_INDEX].Luid = UnsolicitedInputPrivilege;
Privileges->Privileges[SECURITY_INDEX].Luid = SecurityPrivilege;
Privileges->Privileges[UNSOLICITED_INDEX].Attributes = 0;
Privileges->Privileges[SECURITY_INDEX].Attributes = 0;
PrimaryGroup.PrimaryGroup = FlintstoneSid;
Status = RtlCreateAcl( DefaultDacl.DefaultDacl, DEFAULT_DACL_LENGTH, ACL_REVISION);
ASSERT(NT_SUCCESS(Status) );
Status = NtCreateToken(
&PrimaryToken, // Handle
(TOKEN_ALL_ACCESS), // DesiredAccess
&PrimaryTokenAttributes, // ObjectAttributes
TokenPrimary, // TokenType
&DummyAuthenticationId, // Authentication LUID
&NoExpiration, // Expiration Time
&UserId, // Owner ID
GroupIds, // Group IDs
Privileges, // Privileges
&Owner, // Owner
&PrimaryGroup, // Primary Group
&DefaultDacl, // Default Dacl
&TestSource // TokenSource
);
if (NT_SUCCESS(Status)) {
DbgPrint("Succeeded.\n");
} else {
DbgPrint("********** Failed ************\n");
DbgPrint("Status is: 0x%lx \n", Status);
CompletionStatus = FALSE;
}
ASSERT(NT_SUCCESS(Status));
// Create an impersonation token, Impersonation level = Impersonation
DbgPrint("Se: Create an impersonation token ... ");
GroupIds->GroupCount = GROUP_COUNT;
GroupIds->Groups[FLINTSTONE_INDEX].Sid = FlintstoneSid;
GroupIds->Groups[CHILD_INDEX].Sid = ChildSid;
GroupIds->Groups[NEANDERTHOL_INDEX].Sid = NeandertholSid;
GroupIds->Groups[WORLD_INDEX].Sid = WorldSid;
GroupIds->Groups[FLINTSTONE_INDEX].Attributes = OwnerGroupAttributes;
GroupIds->Groups[CHILD_INDEX].Attributes = OptionalGroupAttributes;
GroupIds->Groups[NEANDERTHOL_INDEX].Attributes = OptionalGroupAttributes;
GroupIds->Groups[WORLD_INDEX].Attributes = NormalGroupAttributes;
UserId.User.Sid = PebblesSid;
UserId.User.Attributes = 0;
Owner.Owner = FlintstoneSid;
Privileges->PrivilegeCount = PRIVILEGE_COUNT;
Privileges->Privileges[UNSOLICITED_INDEX].Luid = UnsolicitedInputPrivilege;
Privileges->Privileges[SECURITY_INDEX].Luid = SecurityPrivilege;
Privileges->Privileges[UNSOLICITED_INDEX].Attributes = 0;
Privileges->Privileges[SECURITY_INDEX].Attributes = 0;
PrimaryGroup.PrimaryGroup = FlintstoneSid;
Status = RtlCreateAcl( DefaultDacl.DefaultDacl, DEFAULT_DACL_LENGTH, ACL_REVISION);
ASSERT(NT_SUCCESS(Status) );
Status = NtCreateToken(
&ImpersonationToken, // Handle
(TOKEN_ALL_ACCESS), // DesiredAccess
&ImpersonationTokenAttributes, // ObjectAttributes
TokenImpersonation, // TokenType
&DummyAuthenticationId, // Authentication LUID
&NoExpiration, // Expiration Time
&UserId, // Owner ID
GroupIds, // Group IDs
Privileges, // Privileges
&Owner, // Owner
&PrimaryGroup, // Primary Group
&DefaultDacl, // Default Dacl
&TestSource // TokenSource
);
if (NT_SUCCESS(Status)) {
DbgPrint("Succeeded.\n");
} else {
DbgPrint("********** Failed ************\n");
DbgPrint("Status is: 0x%lx \n", Status);
CompletionStatus = FALSE;
}
ASSERT(NT_SUCCESS(Status));
// Attach tokens to process
NtSetInformationProcess(NtCurrentProcess(), ProcessAccessToken, &PrimaryToken, sizeof( PHANDLE ));
NtSetInformationThread(NtCurrentThread(), ThreadImpersonationToken, &ImpersonationToken, sizeof( PHANDLE ));
// Create some ACEs
// AllowBarneySetColor
AllowBarneySetColorLength = (USHORT)(sizeof( ACCESS_ALLOWED_ACE ) - sizeof( ULONG ) + SeLengthSid( BarneySid ));
AllowBarneySetColor = (PVOID) TstAllocatePool ( PagedPool, AllowBarneySetColorLength );
AllowBarneySetColor->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
AllowBarneySetColor->Header.AceSize = AllowBarneySetColorLength;
AllowBarneySetColor->Header.AceFlags = 0;
AllowBarneySetColor->Mask = SET_WIDGET_COLOR;
RtlCopySid(SeLengthSid( BarneySid ), &(AllowBarneySetColor->SidStart), BarneySid );
// DenyPebblesSetColor
DenyPebblesSetColorLength = (USHORT)(sizeof( ACCESS_DENIED_ACE ) - sizeof( ULONG ) + SeLengthSid( BarneySid ));
DenyPebblesSetColor = (PVOID) TstAllocatePool ( PagedPool, DenyPebblesSetColorLength );
DenyPebblesSetColor->Header.AceType = ACCESS_DENIED_ACE_TYPE;
DenyPebblesSetColor->Header.AceSize = DenyPebblesSetColorLength;
DenyPebblesSetColor->Header.AceFlags = 0;
DenyPebblesSetColor->Mask = SET_WIDGET_COLOR;
RtlCopySid(SeLengthSid( PebblesSid ), &(DenyPebblesSetColor->SidStart), PebblesSid );
// AllowFredSetColor
AllowFredSetColorLength = (USHORT)(sizeof( ACCESS_ALLOWED_ACE ) - sizeof( ULONG ) + SeLengthSid( FredSid ));
AllowFredSetColor = (PVOID) TstAllocatePool ( PagedPool, AllowFredSetColorLength );
AllowFredSetColor->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
AllowFredSetColor->Header.AceSize = AllowFredSetColorLength;
AllowFredSetColor->Header.AceFlags = 0;
AllowFredSetColor->Mask = SET_WIDGET_COLOR;
RtlCopySid(SeLengthSid( FredSid ), &(AllowFredSetColor->SidStart), FredSid );
// AllowPebblesSetColor
AllowPebblesSetColorLength = (USHORT)(sizeof( ACCESS_ALLOWED_ACE ) - sizeof( ULONG ) + SeLengthSid( PebblesSid ));
AllowPebblesSetColor = (PVOID) TstAllocatePool ( PagedPool, AllowPebblesSetColorLength );
AllowPebblesSetColor->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
AllowPebblesSetColor->Header.AceSize = AllowPebblesSetColorLength;
AllowPebblesSetColor->Header.AceFlags = 0;
AllowPebblesSetColor->Mask = SET_WIDGET_COLOR;
RtlCopySid(SeLengthSid( PebblesSid ), &(AllowPebblesSetColor->SidStart), PebblesSid );
// DenyFredSetColor
DenyFredSetColorLength = (USHORT)(sizeof( ACCESS_DENIED_ACE ) - sizeof( ULONG ) + SeLengthSid( FredSid ));
DenyFredSetColor = (PVOID) TstAllocatePool ( PagedPool, DenyFredSetColorLength );
DenyFredSetColor->Header.AceType = ACCESS_DENIED_ACE_TYPE;
DenyFredSetColor->Header.AceSize = DenyFredSetColorLength;
DenyFredSetColor->Header.AceFlags = 0;
DenyFredSetColor->Mask = SET_WIDGET_COLOR;
RtlCopySid(SeLengthSid( FredSid ), &(DenyFredSetColor->SidStart), FredSid );
// AllowBarneySetSize
AllowBarneySetSizeLength = (USHORT)(sizeof( ACCESS_ALLOWED_ACE ) - sizeof( ULONG ) + SeLengthSid( BarneySid ));
AllowBarneySetSize = (PVOID) TstAllocatePool ( PagedPool, AllowBarneySetSizeLength );
AllowBarneySetSize->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
AllowBarneySetSize->Header.AceSize = AllowBarneySetSizeLength;
AllowBarneySetSize->Header.AceFlags = 0;
AllowBarneySetSize->Mask = SET_WIDGET_SIZE;
RtlCopySid(SeLengthSid( BarneySid ), &(AllowBarneySetSize->SidStart), BarneySid );
// AllowPebblesSetSize
AllowPebblesSetSizeLength = (USHORT)(sizeof( ACCESS_ALLOWED_ACE ) - sizeof( ULONG ) + SeLengthSid( PebblesSid ));
AllowPebblesSetSize = (PVOID) TstAllocatePool ( PagedPool, AllowPebblesSetSizeLength );
AllowPebblesSetSize->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
AllowPebblesSetSize->Header.AceSize = AllowPebblesSetSizeLength;
AllowPebblesSetSize->Header.AceFlags = 0;
AllowPebblesSetSize->Mask = SET_WIDGET_SIZE;
RtlCopySid(SeLengthSid( PebblesSid ), &(AllowPebblesSetSize->SidStart), PebblesSid );
// AllowPebblesGetSize
AllowPebblesGetSizeLength = (USHORT)(sizeof( ACCESS_ALLOWED_ACE ) - sizeof( ULONG ) + SeLengthSid( PebblesSid ));
AllowPebblesGetSize = (PVOID) TstAllocatePool ( PagedPool, AllowPebblesGetSizeLength );
AllowPebblesGetSize->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
AllowPebblesGetSize->Header.AceSize = AllowPebblesGetSizeLength;
AllowPebblesGetSize->Header.AceFlags = 0;
AllowPebblesGetSize->Mask = SET_WIDGET_SIZE;
RtlCopySid(SeLengthSid( PebblesSid ), &(AllowPebblesGetSize->SidStart), PebblesSid );
// AllowPebblesGetColor
AllowPebblesGetColorLength = (USHORT)(sizeof( ACCESS_ALLOWED_ACE ) - sizeof( ULONG ) + SeLengthSid( PebblesSid ));
AllowPebblesGetColor = (PVOID) TstAllocatePool ( PagedPool, AllowPebblesGetColorLength );
AllowPebblesGetColor->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
AllowPebblesGetColor->Header.AceSize = AllowPebblesGetColorLength;
AllowPebblesGetColor->Header.AceFlags = 0;
AllowPebblesGetColor->Mask = SET_WIDGET_COLOR;
RtlCopySid(SeLengthSid( PebblesSid ), &(AllowPebblesGetColor->SidStart), PebblesSid );
// Create some ACLs that we can put into a Security Descriptor
DbgBreakPoint();
// Dacl
// +----------------+ +----------------+ +----------------+
// | 1st ACE | | 2nd ACE | | 3rd ACE |
// +----------------+ +----------------+ +----------------+
// | AccessAllowed | | AccessDenied | | AccessAllowed |
// +----------------+ +----------------+ +----------------+
// | BARNEY | | PEBBLES | | FRED |
// +----------------+ +----------------+ +----------------+
// | SetWidgeColor | | SetWidgeColor | | SetWidgeColor |
// +----------------+ +----------------+ +----------------+
Dacl = (PACL) TstAllocatePool ( PagedPool, 2048 );
RtlCreateAcl( Dacl, 2048, ACL_REVISION);
RtlAddAce ( Dacl, ACL_REVISION, 0, AllowBarneySetColor, AllowBarneySetColorLength );
RtlAddAce ( Dacl, ACL_REVISION, 1, DenyPebblesSetColor, DenyPebblesSetColorLength );
RtlAddAce ( Dacl, ACL_REVISION, 2, DenyFredSetColor, AllowFredSetColorLength );
DumpAcl (Dacl);
// Create a security descriptor
// Owner = Pebbles
// Group = Flintstone
// Dacl = Dacl
// Sacl = NULL
Widget1SecurityDescriptor = (PSECURITY_DESCRIPTOR)TstAllocatePool( PagedPool, 1024 );
RtlCreateSecurityDescriptor( Widget1SecurityDescriptor, 1 );
RtlSetOwnerSecurityDescriptor( Widget1SecurityDescriptor, PebblesSid, FALSE );
RtlSetGroupSecurityDescriptor( Widget1SecurityDescriptor, FlintstoneSid, FALSE );
RtlSetDaclSecurityDescriptor( Widget1SecurityDescriptor, TRUE, Dacl, FALSE );
RtlSetSaclSecurityDescriptor( Widget1SecurityDescriptor, FALSE, NULL, NULL );
// See if Pebbles is allowed SET_WIDGET_COLOR (should be denied)
Status = NtAccessCheck( Widget1SecurityDescriptor, PrimaryToken, (ACCESS_MASK) SET_WIDGET_COLOR, &GrantedAccess, &AccessStatus );
// DbgBreakPoint();
ASSERT(NT_SUCCESS(Status));
ASSERT(!NT_SUCCESS(AccessStatus));
ASSERT(GrantedAccess == NULL);
// Update Dacl to be the following:
// Dacl2
// +----------------+ +----------------+ +----------------+
// | 1st ACE | | 2nd ACE | | 3rd ACE |
// +----------------+ +----------------+ +----------------+
// | AccessAllowed | | AccessAllowed | | AccessDenied |
// +----------------+ +----------------+ +----------------+
// | BARNEY | | PEBBLES | | FRED |
// +----------------+ +----------------+ +----------------+
// | SetWidgeColor | | SetWidgeColor | | SetWidgeColor |
// +----------------+ +----------------+ +----------------+
// Delete 2nd Ace
RtlDeleteAce (Dacl, 1);
RtlAddAce ( Dacl, ACL_REVISION, 1, AllowPebblesSetColor, AllowPebblesSetColorLength );
RtlDeleteAce ( Dacl, 2 );
RtlAddAce ( Dacl, ACL_REVISION, 1, DenyFredSetColor, DenyFredSetColorLength );
// Change the security descriptor to use updated Dacl
// Owner = Pebbles
// Group = Flintstone
// Dacl = Dacl2
// Sacl = NULL
RtlSetDaclSecurityDescriptor( Widget1SecurityDescriptor, TRUE, Dacl, FALSE );
// See if Pebbles is allowed SET_WIDGET_COLOR (should be permitted)
Status = NtAccessCheck( Widget1SecurityDescriptor, PrimaryToken, (ACCESS_MASK) SET_WIDGET_COLOR, &GrantedAccess, &AccessStatus );
ASSERT(NT_SUCCESS(Status));
ASSERT(NT_SUCCESS(AccessStatus));
ASSERT(GrantedAccess == (ACCESS_MASK)SET_WIDGET_COLOR);
// Dacl3
// +----------------+ +----------------+ +----------------+
// | 1st ACE | | 2nd ACE | | 3rd ACE |
// +----------------+ +----------------+ +----------------+
// | AccessAllowed | | AccessAllowed | | AccessDenied |
// +----------------+ +----------------+ +----------------+
// | BARNEY | | PEBBLES | | FRED |
// +----------------+ +----------------+ +----------------+
// | SetWidgeColor | | SetWidgeColor | | SetWidgeColor |
// +----------------+ +----------------+ +----------------+
// +----------------+ +----------------+
// | 4th ACE | | 5th ACE |
// +----------------+ +----------------+
// | AccessAllowed | | AccessAllowed |
// +----------------+ +----------------+
// | BARNEY | | PEBBLES |
// +----------------+ +----------------+
// | SetWidgeSize | | SetWidgeSize |
// +----------------+ +----------------+
RtlAddAce ( Dacl, ACL_REVISION, MAXULONG, AllowBarneySetSize, AllowBarneySetSizeLength );
RtlAddAce ( Dacl, ACL_REVISION, MAXULONG, AllowPebblesSetSize, AllowPebblesSetSizeLength );
// Change the security descriptor to use Dacl3
// Owner = Pebbles
// Group = Flintstone
// Dacl = Dacl3
// Sacl = NULL
RtlSetDaclSecurityDescriptor( Widget1SecurityDescriptor, TRUE, Dacl, FALSE );
// Request MAXIMUM_ACCESS for Pebbles. Should get back SetWidgetSize
// and SetWidgetColor
Status = NtAccessCheck( Widget1SecurityDescriptor, PrimaryToken, (ACCESS_MASK) MAXIMUM_ALLOWED, &GrantedAccess, &AccessStatus );
ASSERT(NT_SUCCESS(Status));
ASSERT(NT_SUCCESS(AccessStatus));
ASSERT(GrantedAccess == (ACCESS_MASK) (SET_WIDGET_COLOR | SET_WIDGET_SIZE));
// Dacl4
// +----------------+ +----------------+ +----------------+
// | 1st ACE | | 2nd ACE | | 3rd ACE |
// +----------------+ +----------------+ +----------------+
// | AccessAllowed | | AccessAllowed | | AccessDenied |
// +----------------+ +----------------+ +----------------+
// | BARNEY | | PEBBLES | | FRED |
// +----------------+ +----------------+ +----------------+
// | SetWidgeColor | | SetWidgeColor | | SetWidgeColor |
// +----------------+ +----------------+ +----------------+
// +----------------+ +----------------+ +----------------+
// | 4th ACE | | 5th ACE | | 6th ACE |
// +----------------+ +----------------+ +----------------+
// | AccessAllowed | | AccessAllowed | | AccessDenied |
// +----------------+ +----------------+ +----------------+
// | BARNEY | | PEBBLES | | PEBBLES |
// +----------------+ +----------------+ +----------------+
// | SetWidgeSize | | SetWidgeSize | | SetWidgeColor |
// +----------------+ +----------------+ +----------------+
RtlAddAce ( Dacl, ACL_REVISION, MAXULONG, DenyPebblesSetColor, DenyPebblesSetColorLength );
RtlSetDaclSecurityDescriptor( Widget1SecurityDescriptor, TRUE, Dacl, FALSE );
// Request MAXIMUM_ACCESS for Pebbles. Should get back SetWidgetSize
// and SetWidgetColor
Status = NtAccessCheck( Widget1SecurityDescriptor, PrimaryToken, (ACCESS_MASK) MAXIMUM_ALLOWED, &GrantedAccess, &AccessStatus );
ASSERT(NT_SUCCESS(Status));
ASSERT(NT_SUCCESS(AccessStatus));
ASSERT(GrantedAccess == (ACCESS_MASK) (SET_WIDGET_COLOR | SET_WIDGET_SIZE));
// Dacl5
// +----------------+ +----------------+ +----------------+
// | 1st ACE | | 2nd ACE | | 3rd ACE |
// +----------------+ +----------------+ +----------------+
// | AccessAllowed | | AccessDenied | | AccessDenied |
// +----------------+ +----------------+ +----------------+
// | BARNEY | | PEBBLES | | FRED |
// +----------------+ +----------------+ +----------------+
// | SetWidgeColor | | SetWidgeColor | | SetWidgeColor |
// +----------------+ +----------------+ +----------------+
// +----------------+ +----------------+ +----------------+
// | 4th ACE | | 5th ACE | | 6th ACE |
// +----------------+ +----------------+ +----------------+
// | AccessAllowed | | AccessAllowed | | AccessAllowed |
// +----------------+ +----------------+ +----------------+
// | BARNEY | | PEBBLES | | PEBBLES |
// +----------------+ +----------------+ +----------------+
// | SetWidgeSize | | SetWidgeSize | | SetWidgeColor |
// +----------------+ +----------------+ +----------------+
RtlDeleteAce (Dacl, 1);
RtlAddAce ( Dacl, ACL_REVISION, 1, DenyPebblesSetColor, DenyPebblesSetColorLength );
RtlDeleteAce (Dacl, 5);
RtlAddAce ( Dacl, ACL_REVISION, MAXULONG, AllowPebblesSetColor, AllowPebblesSetColorLength );
DumpAcl ( Dacl );
RtlSetDaclSecurityDescriptor( Widget1SecurityDescriptor, TRUE, Dacl, FALSE );
// Request MAXIMUM_ACCESS for Pebbles. Should get back SetWidgetSize
Status = NtAccessCheck( Widget1SecurityDescriptor, PrimaryToken, (ACCESS_MASK) MAXIMUM_ALLOWED, &GrantedAccess, &AccessStatus );
ASSERT(NT_SUCCESS(Status));
ASSERT(NT_SUCCESS(AccessStatus));
ASSERT(GrantedAccess == (ACCESS_MASK) SET_WIDGET_SIZE);
// Dacl6
// +----------------+ +----------------+ +----------------+
// | 1st ACE | | 2nd ACE | | 3rd ACE |
// +----------------+ +----------------+ +----------------+
// | AccessAllowed | | AccessDenied | | AccessDenied |
// +----------------+ +----------------+ +----------------+
// | BARNEY | | PEBBLES | | FRED |
// +----------------+ +----------------+ +----------------+
// | SetWidgeColor | | SetWidgeColor | | SetWidgeColor |
// +----------------+ +----------------+ +----------------+
// +----------------+ +----------------+ +----------------+
// | 4th ACE | | 5th ACE | | 6th ACE |
// +----------------+ +----------------+ +----------------+
// | AccessAllowed | | AccessAllowed | | AccessAllowed |
// +----------------+ +----------------+ +----------------+
// | BARNEY | | PEBBLES | | PEBBLES |
// +----------------+ +----------------+ +----------------+
// | SetWidgeSize | | SetWidgeSize | | SetWidgeColor |
// +----------------+ +----------------+ +----------------+
// +----------------+ +----------------+
// | 7th ACE | | 8th ACE |
// +----------------+ +----------------+
// | AccessAllowed | | AccessAllowed |
// +----------------+ +----------------+
// | PEBBLES | | PEBBLES |
// +----------------+ +----------------+
// | GetWidgeSize | | GetWidgeColor |
// +----------------+ +----------------+
RtlAddAce ( Dacl, ACL_REVISION, MAXULONG, AllowPebblesGetSize, AllowPebblesGetSizeLength );
RtlAddAce ( Dacl, ACL_REVISION, MAXULONG, AllowPebblesGetColor, AllowPebblesGetColorLength );
DumpAcl ( Dacl );
RtlSetDaclSecurityDescriptor( Widget1SecurityDescriptor, TRUE, Dacl, FALSE );
// Request MAXIMUM_ACCESS for Pebbles. Should get back SetWidgetSize
Status = NtAccessCheck( Widget1SecurityDescriptor, PrimaryToken, (ACCESS_MASK) MAXIMUM_ALLOWED, &GrantedAccess, &AccessStatus );
ASSERT(NT_SUCCESS(Status));
ASSERT(NT_SUCCESS(AccessStatus));
ASSERT(GrantedAccess == (ACCESS_MASK) SET_WIDGET_SIZE);
return(TRUE);
}
// Main test entry point //
BOOLEAN CTAccess()
{
BOOLEAN Result = TRUE;
if (!TSeVariableInitialization()) {
DbgPrint("Se: Failed to initialize global test variables.\n");
return FALSE;
}
DbgPrint("Se: Initialization...");
TestTokenInitialize();
CreateDAclToken();
}
// Debug support routine
typedef struct _STANDARD_ACE {
ACE_HEADER Header;
ACCESS_MASK Mask;
PSID Sid;
} STANDARD_ACE;
typedef STANDARD_ACE *PSTANDARD_ACE;
VOID DumpAcl (IN PACL Acl)
/*++
Routine Description:
This routine dumps via (DbgPrint) an Acl for debug purposes. It is specialized to dump standard aces.
Arguments:
Acl - Supplies the Acl to dump
Return Value:
None
--*/
{
ULONG i;
PSTANDARD_ACE Ace;
DbgPrint("DumpAcl @ %8lx", Acl);
// Check if the Acl is null
if (Acl == NULL) {
return;
}
// Dump the Acl header
DbgPrint(" Revision: %02x", Acl->AclRevision);
DbgPrint(" Size: %04x", Acl->AclSize);
DbgPrint(" AceCount: %04x\n", Acl->AceCount);
// Now for each Ace we want do dump it
for (i = 0, Ace = FirstAce(Acl); i < Acl->AceCount; i++, Ace = NextAce(Ace) ) {
// print out the ace header
DbgPrint(" AceHeader: %08lx ", *(PULONG)Ace);
// special case on the standard ace types
if ((Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) || (Ace->Header.AceType == ACCESS_DENIED_ACE_TYPE) || (Ace->Header.AceType == SYSTEM_AUDIT_ACE_TYPE) || (Ace->Header.AceType == SYSTEM_ALARM_ACE_TYPE)) {
// The following array is indexed by ace types and must
// follow the allowed, denied, audit, alarm seqeuence
static PCHAR AceTypes[] = { "Access Allowed",
"Access Denied ",
"System Audit ",
"System Alarm "
};
DbgPrint(AceTypes[Ace->Header.AceType]);
DbgPrint("\nAccess Mask: %08lx ", Ace->Mask);
} else {
DbgPrint("Unknown Ace Type\n");
}
DbgPrint("\n");
DbgPrint("AceSize = %d\n",Ace->Header.AceSize);
DbgPrint("Ace Flags = ");
if (Ace->Header.AceFlags & OBJECT_INHERIT_ACE) {
DbgPrint("OBJECT_INHERIT_ACE\n");
DbgPrint(" ");
}
if (Ace->Header.AceFlags & CONTAINER_INHERIT_ACE) {
DbgPrint("CONTAINER_INHERIT_ACE\n");
DbgPrint(" ");
}
if (Ace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE) {
DbgPrint("NO_PROPAGATE_INHERIT_ACE\n");
DbgPrint(" ");
}
if (Ace->Header.AceFlags & INHERIT_ONLY_ACE) {
DbgPrint("INHERIT_ONLY_ACE\n");
DbgPrint(" ");
}
if (Ace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) {
DbgPrint("SUCCESSFUL_ACCESS_ACE_FLAG\n");
DbgPrint(" ");
}
if (Ace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG) {
DbgPrint("FAILED_ACCESS_ACE_FLAG\n");
DbgPrint(" ");
}
DbgPrint("\n");
}
}