929 lines
32 KiB
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");
|
|
|
|
|
|
}
|
|
|
|
}
|