- Add missing ACE structures to ntifs.h.

- Add missing SeLengthSid to ntifs.h.
- Implement CmpHiveRootSecurityDescriptor and use it in CmpInitializeSystemHive and CmInitSystem1 to properly secure system-created hives.
- Implement CmpInitializeHardwareConfiguration and call it. Its job is to populate the hardware hive, but FreeLDR already does this, so it doesn't do much at the moment.

svn path=/trunk/; revision=26701
This commit is contained in:
Alex Ionescu 2007-05-11 18:15:13 +00:00
parent 852a223ab9
commit 010910bc34
6 changed files with 344 additions and 58 deletions

View file

@ -1724,6 +1724,41 @@ typedef struct _ACE_HEADER
USHORT AceSize;
} ACE_HEADER, *PACE_HEADER;
typedef struct _ACCESS_ALLOWED_ACE
{
ACE_HEADER Header;
ACCESS_MASK Mask;
ULONG SidStart;
} ACCESS_ALLOWED_ACE, *PACCESS_ALLOWED_ACE;
typedef struct _ACCESS_DENIED_ACE
{
ACE_HEADER Header;
ACCESS_MASK Mask;
ULONG SidStart;
} ACCESS_DENIED_ACE, *PACCESS_DENIED_ACE;
typedef struct _SYSTEM_AUDIT_ACE
{
ACE_HEADER Header;
ACCESS_MASK Mask;
ULONG SidStart;
} SYSTEM_AUDIT_ACE, *PSYSTEM_AUDIT_ACE;
typedef struct _SYSTEM_ALARM_ACE
{
ACE_HEADER Header;
ACCESS_MASK Mask;
ULONG SidStart;
} SYSTEM_ALARM_ACE, *PSYSTEM_ALARM_ACE;
typedef struct _SYSTEM_MANDATORY_LABEL_ACE
{
ACE_HEADER Header;
ACCESS_MASK Mask;
ULONG SidStart;
} SYSTEM_MANDATORY_LABEL_ACE, *PSYSTEM_MANDATORY_LABEL_ACE;
typedef struct _TUNNEL {
FAST_MUTEX Mutex;
PRTL_SPLAY_LINKS Cache;
@ -4306,6 +4341,10 @@ SeCreateClientSecurityFromSubjectContext (
#endif /* (VER_PRODUCTBUILD >= 2195) */
#define SeLengthSid( Sid ) \
(8 + (4 * ((SID *)Sid)->SubAuthorityCount))
#define SeDeleteClientSecurity(C) { \
if (SeTokenType((C)->ClientToken) == TokenPrimary) { \
PsDereferencePrimaryToken( (C)->ClientToken ); \

View file

@ -418,6 +418,66 @@ CmpFileFlush(
PHHIVE RegistryHive,
ULONG FileType);
VOID
CmiCheckKey(BOOLEAN Verbose,
HANDLE Key);
BOOLEAN
INIT_FUNCTION
CmImportSystemHive(PCHAR ChunkBase,
ULONG ChunkSize,
OUT PEREGISTRY_HIVE *RegistryHive);
BOOLEAN
INIT_FUNCTION
CmImportHardwareHive(PCHAR ChunkBase,
ULONG ChunkSize,
OUT PEREGISTRY_HIVE *RegistryHive);
NTSTATUS
NTAPI
CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
NTSTATUS
NTAPI
CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
NTSTATUS
NTAPI
CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
NTSTATUS
NTAPI
CmpInitializeHive(PEREGISTRY_HIVE *RegistryHive,
ULONG OperationType,
ULONG HiveFlags,
ULONG FileType,
PVOID HiveData OPTIONAL,
HANDLE Primary,
HANDLE Log,
HANDLE External,
PUNICODE_STRING FileName OPTIONAL,
ULONG CheckFlags);
USHORT
NTAPI
CmpCopyName(IN PHHIVE Hive,
IN PWCHAR Destination,
IN PUNICODE_STRING Source);
USHORT
NTAPI
CmpNameSize(IN PHHIVE Hive,
IN PUNICODE_STRING Name);
NTSTATUS
NTAPI
CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
PSECURITY_DESCRIPTOR
NTAPI
CmpHiveRootSecurityDescriptor(VOID);
#if 0
static __inline PVOID xHvGetCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell)
{

View file

@ -49,60 +49,6 @@ KTIMER CmiHiveSyncTimer;
static GENERIC_MAPPING CmiKeyMapping =
{KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS};
VOID
CmiCheckKey(BOOLEAN Verbose,
HANDLE Key);
BOOLEAN
INIT_FUNCTION
CmImportSystemHive(PCHAR ChunkBase,
ULONG ChunkSize,
OUT PEREGISTRY_HIVE *RegistryHive);
BOOLEAN
INIT_FUNCTION
CmImportHardwareHive(PCHAR ChunkBase,
ULONG ChunkSize,
OUT PEREGISTRY_HIVE *RegistryHive);
NTSTATUS
NTAPI
CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
NTSTATUS
NTAPI
CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
NTSTATUS
NTAPI
CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
NTSTATUS
NTAPI
CmpInitializeHive(PEREGISTRY_HIVE *RegistryHive,
ULONG OperationType,
ULONG HiveFlags,
ULONG FileType,
PVOID HiveData OPTIONAL,
HANDLE Primary,
HANDLE Log,
HANDLE External,
PUNICODE_STRING FileName OPTIONAL,
ULONG CheckFlags);
USHORT
NTAPI
CmpCopyName(IN PHHIVE Hive,
IN PWCHAR Destination,
IN PUNICODE_STRING Source);
USHORT
NTAPI
CmpNameSize(IN PHHIVE Hive,
IN PUNICODE_STRING Name);
static VOID STDCALL
CmiHiveSyncDpcRoutine(PKDPC Dpc,
PVOID DeferredContext,
@ -253,6 +199,7 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
UNICODE_STRING KeyName;
PEREGISTRY_HIVE SystemHive;
UNICODE_STRING HiveName = RTL_CONSTANT_STRING(L"SYSTEM");
PSECURITY_DESCRIPTOR SecurityDescriptor;
PAGED_CODE();
/* Setup the ansi string */
@ -309,9 +256,16 @@ CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Allocate = TRUE;
}
/* Create the default security descriptor */
SecurityDescriptor = CmpHiveRootSecurityDescriptor();
/* Attach it to the system key */
RtlInitUnicodeString(&KeyName, REG_SYSTEM_KEY_NAME);
Status = CmpLinkHiveToMaster(&KeyName, NULL, SystemHive, Allocate, NULL);
Status = CmpLinkHiveToMaster(&KeyName,
NULL,
SystemHive,
Allocate,
SecurityDescriptor);
if (!NT_SUCCESS(Status)) return FALSE;
/* Success! */
@ -495,6 +449,7 @@ CmInitSystem1(VOID)
PEREGISTRY_HIVE HardwareHive;
PVOID BaseAddress;
ULONG Length;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PAGED_CODE();
/* Initialize the hive list */
@ -559,13 +514,16 @@ CmInitSystem1(VOID)
KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 3, 0, 0);
}
/* Create the default security descriptor */
SecurityDescriptor = CmpHiveRootSecurityDescriptor();
/* Create '\Registry\Machine' key. */
RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
SecurityDescriptor);
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
@ -588,7 +546,7 @@ CmInitSystem1(VOID)
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
SecurityDescriptor);
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
@ -642,13 +600,25 @@ CmInitSystem1(VOID)
/* Attach it to the machine key */
RtlInitUnicodeString(&KeyName, REG_HARDWARE_KEY_NAME);
Status = CmpLinkHiveToMaster(&KeyName, NULL, HardwareHive, FALSE, NULL);
Status = CmpLinkHiveToMaster(&KeyName,
NULL,
HardwareHive,
FALSE,
SecurityDescriptor);
if (!NT_SUCCESS(Status))
{
/* Bugcheck */
KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 12, Status, 0);
}
/* Fill out the Hardware key with the ARC Data from the Loader */
Status = CmpInitializeHardwareConfiguration(KeLoaderBlock);
if (!NT_SUCCESS(Status))
{
/* Bugcheck */
KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 13, Status, 0);
}
/* Initialize machine-dependent information into the registry */
Status = CmpInitializeMachineDependentConfiguration(KeLoaderBlock);
if (!NT_SUCCESS(Status))

View file

@ -194,3 +194,81 @@ CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
return Status;
}
NTSTATUS
NTAPI
CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE KeyHandle;
ULONG Disposition;
UNICODE_STRING KeyName;
/* Setup the key name */
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\Hardware\\DeviceMap");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Create the device map key */
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
if (!NT_SUCCESS(Status)) return Status;
NtClose(KeyHandle);
/* Nobody should've created this key yet! */
//ASSERT(Disposition == REG_CREATED_NEW_KEY);
/* Setup the key name */
RtlInitUnicodeString(&KeyName,
L"\\Registry\\Machine\\Hardware\\Description");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Create the description key */
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
if (!NT_SUCCESS(Status)) return Status;
/* Nobody should've created this key yet! */
//ASSERT(Disposition == REG_CREATED_NEW_KEY);
/* Allocate the configuration data buffer */
CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
CmpConfigurationAreaSize,
TAG_CM);
if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;
/* Check if we got anything from NTLDR */
if (LoaderBlock->ConfigurationRoot)
{
ASSERTMSG("NTLDR ARC Hardware Tree Not Supported!\n", FALSE);
}
else
{
/* Nothing else to do */
Status = STATUS_SUCCESS;
}
/* Close our handle, free the buffer and return status */
ExFreePool(CmpConfigurationData);
NtClose(KeyHandle);
return Status;
}

View file

@ -0,0 +1,138 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/config/cmse.c
* PURPOSE: Configuration Manager - Security Subsystem Interface
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include "ntoskrnl.h"
#include "cm.h"
#define NDEBUG
#include "debug.h"
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
PSECURITY_DESCRIPTOR
NTAPI
CmpHiveRootSecurityDescriptor(VOID)
{
NTSTATUS Status;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PACL Acl, AclCopy;
PSID Sid[3];
SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
ULONG AceLength, AclLength, SidLength;
PACE_HEADER AceHeader;
ULONG i;
PAGED_CODE();
/* Phase 1: Allocate SIDs */
SidLength = RtlLengthRequiredSid(1);
Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
SidLength = RtlLengthRequiredSid(2);
Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
/* Make sure all SIDs were allocated */
if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))
{
/* Bugcheck */
KEBUGCHECKEX(REGISTRY_ERROR, 2, 1, 0, 0);
}
/* Phase 2: Initialize all SIDs */
Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1);
Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1);
Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1);
Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 2, 0, 0);
/* Phase 2: Setup SID Sub Authorities */
*RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID;
*RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID;
*RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID;
*RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID;
*RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS;
/* Make sure all SIDs are valid */
ASSERT(RtlValidSid(Sid[0]));
ASSERT(RtlValidSid(Sid[1]));
ASSERT(RtlValidSid(Sid[2]));
ASSERT(RtlValidSid(Sid[3]));
/* Phase 3: Calculate ACL Length */
AclLength = sizeof(ACL);
for (i = 0; i < 4; i++)
{
/* This is what MSDN says to do */
AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
AceLength += SeLengthSid(Sid[i]);
AclLength += AceLength;
}
/* Phase 3: Allocate the ACL */
Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM);
if (!Acl) KEBUGCHECKEX(REGISTRY_ERROR, 2, 3, 0, 0);
/* Phase 4: Create the ACL */
Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 4, Status, 0);
/* Phase 5: Build the ACL */
Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[1]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]);
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 5, Status, 0);
/* Phase 5: Make the ACEs inheritable */
Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
/* Phase 6: Allocate the security descriptor and make space for the ACL */
SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
sizeof(SECURITY_DESCRIPTOR) +
AclLength,
TAG_CM);
if (!SecurityDescriptor) KEBUGCHECKEX(REGISTRY_ERROR, 2, 6, 0, 0);
/* Phase 6: Make a copy of the ACL */
AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1);
RtlCopyMemory(AclCopy, Acl, AclLength);
/* Phase 7: Create the security descriptor */
Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 7, Status, 0);
/* Phase 8: Set the ACL as a DACL */
Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
TRUE,
AclCopy,
FALSE);
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 8, Status, 0);
/* Free the SIDs and original ACL */
for (i = 0; i < 4; i++) ExFreePool(Sid[i]);
ExFreePool(Acl);
/* Return the security descriptor */
return SecurityDescriptor;
}

View file

@ -98,6 +98,7 @@
<file>cmmapvw.c</file>
<file>cmname.c</file>
<file>cmparse.c</file>
<file>cmse.c</file>
<file>cmsecach.c</file>
<file>cmsysini.c</file>
<file>cmvalue.c</file>