- 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
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;
#endif /* (VER_PRODUCTBUILD >= 2195) */
+
+#define SeLengthSid( Sid ) \
+ (8 + (4 * ((SID *)Sid)->SubAuthorityCount))
+
#define SeDeleteClientSecurity(C) { \
if (SeTokenType((C)->ClientToken) == TokenPrimary) { \
PsDereferencePrimaryToken( (C)->ClientToken ); \
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)
{
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,
UNICODE_STRING KeyName;
PEREGISTRY_HIVE SystemHive;
UNICODE_STRING HiveName = RTL_CONSTANT_STRING(L"SYSTEM");
+ PSECURITY_DESCRIPTOR SecurityDescriptor;
PAGED_CODE();
/* Setup the ansi string */
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! */
PEREGISTRY_HIVE HardwareHive;
PVOID BaseAddress;
ULONG Length;
+ PSECURITY_DESCRIPTOR SecurityDescriptor;
PAGED_CODE();
/* Initialize the hive list */
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,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
- NULL);
+ SecurityDescriptor);
Status = NtCreateKey(&KeyHandle,
KEY_READ | KEY_WRITE,
&ObjectAttributes,
/* 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))
return Status;\r
}\r
\r
+NTSTATUS\r
+NTAPI\r
+CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)\r
+{\r
+ NTSTATUS Status;\r
+ OBJECT_ATTRIBUTES ObjectAttributes;\r
+ HANDLE KeyHandle;\r
+ ULONG Disposition;\r
+ UNICODE_STRING KeyName;\r
+\r
+ /* Setup the key name */\r
+ RtlInitUnicodeString(&KeyName,\r
+ L"\\Registry\\Machine\\Hardware\\DeviceMap");\r
+ InitializeObjectAttributes(&ObjectAttributes,\r
+ &KeyName,\r
+ OBJ_CASE_INSENSITIVE,\r
+ NULL,\r
+ NULL);\r
+\r
+ /* Create the device map key */\r
+ Status = NtCreateKey(&KeyHandle,\r
+ KEY_READ | KEY_WRITE,\r
+ &ObjectAttributes,\r
+ 0,\r
+ NULL,\r
+ 0,\r
+ &Disposition);\r
+ if (!NT_SUCCESS(Status)) return Status;\r
+ NtClose(KeyHandle);\r
+\r
+ /* Nobody should've created this key yet! */\r
+ //ASSERT(Disposition == REG_CREATED_NEW_KEY);\r
+\r
+ /* Setup the key name */\r
+ RtlInitUnicodeString(&KeyName,\r
+ L"\\Registry\\Machine\\Hardware\\Description");\r
+ InitializeObjectAttributes(&ObjectAttributes,\r
+ &KeyName,\r
+ OBJ_CASE_INSENSITIVE,\r
+ NULL,\r
+ NULL);\r
+\r
+ /* Create the description key */\r
+ Status = NtCreateKey(&KeyHandle,\r
+ KEY_READ | KEY_WRITE,\r
+ &ObjectAttributes,\r
+ 0,\r
+ NULL,\r
+ 0,\r
+ &Disposition);\r
+ if (!NT_SUCCESS(Status)) return Status;\r
+\r
+ /* Nobody should've created this key yet! */\r
+ //ASSERT(Disposition == REG_CREATED_NEW_KEY);\r
+\r
+ /* Allocate the configuration data buffer */\r
+ CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,\r
+ CmpConfigurationAreaSize,\r
+ TAG_CM);\r
+ if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;\r
+\r
+ /* Check if we got anything from NTLDR */\r
+ if (LoaderBlock->ConfigurationRoot)\r
+ {\r
+ ASSERTMSG("NTLDR ARC Hardware Tree Not Supported!\n", FALSE);\r
+ }\r
+ else\r
+ {\r
+ /* Nothing else to do */\r
+ Status = STATUS_SUCCESS;\r
+ }\r
+\r
+ /* Close our handle, free the buffer and return status */\r
+ ExFreePool(CmpConfigurationData);\r
+ NtClose(KeyHandle);\r
+ return Status;\r
+}\r
+\r
--- /dev/null
+/*\r
+ * PROJECT: ReactOS Kernel\r
+ * LICENSE: GPL - See COPYING in the top level directory\r
+ * FILE: ntoskrnl/config/cmse.c\r
+ * PURPOSE: Configuration Manager - Security Subsystem Interface\r
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include "ntoskrnl.h"\r
+#include "cm.h"\r
+#define NDEBUG\r
+#include "debug.h"\r
+\r
+/* GLOBALS *******************************************************************/\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+PSECURITY_DESCRIPTOR\r
+NTAPI\r
+CmpHiveRootSecurityDescriptor(VOID)\r
+{\r
+ NTSTATUS Status;\r
+ PSECURITY_DESCRIPTOR SecurityDescriptor;\r
+ PACL Acl, AclCopy;\r
+ PSID Sid[3];\r
+ SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};\r
+ SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};\r
+ ULONG AceLength, AclLength, SidLength;\r
+ PACE_HEADER AceHeader;\r
+ ULONG i;\r
+ PAGED_CODE();\r
+\r
+ /* Phase 1: Allocate SIDs */\r
+ SidLength = RtlLengthRequiredSid(1);\r
+ Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);\r
+ Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);\r
+ Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);\r
+ SidLength = RtlLengthRequiredSid(2);\r
+ Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);\r
+\r
+ /* Make sure all SIDs were allocated */\r
+ if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))\r
+ {\r
+ /* Bugcheck */\r
+ KEBUGCHECKEX(REGISTRY_ERROR, 2, 1, 0, 0);\r
+ }\r
+\r
+ /* Phase 2: Initialize all SIDs */\r
+ Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1);\r
+ Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1);\r
+ Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1);\r
+ Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2);\r
+ if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 2, 0, 0);\r
+\r
+ /* Phase 2: Setup SID Sub Authorities */\r
+ *RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID;\r
+ *RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID;\r
+ *RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID;\r
+ *RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID;\r
+ *RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS;\r
+\r
+ /* Make sure all SIDs are valid */\r
+ ASSERT(RtlValidSid(Sid[0]));\r
+ ASSERT(RtlValidSid(Sid[1]));\r
+ ASSERT(RtlValidSid(Sid[2]));\r
+ ASSERT(RtlValidSid(Sid[3]));\r
+\r
+ /* Phase 3: Calculate ACL Length */\r
+ AclLength = sizeof(ACL);\r
+ for (i = 0; i < 4; i++)\r
+ {\r
+ /* This is what MSDN says to do */\r
+ AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);\r
+ AceLength += SeLengthSid(Sid[i]);\r
+ AclLength += AceLength;\r
+ }\r
+\r
+ /* Phase 3: Allocate the ACL */\r
+ Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM);\r
+ if (!Acl) KEBUGCHECKEX(REGISTRY_ERROR, 2, 3, 0, 0);\r
+\r
+ /* Phase 4: Create the ACL */\r
+ Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);\r
+ if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 4, Status, 0);\r
+\r
+ /* Phase 5: Build the ACL */\r
+ Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]);\r
+ Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[1]);\r
+ Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]);\r
+ Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]);\r
+ if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 5, Status, 0);\r
+\r
+ /* Phase 5: Make the ACEs inheritable */\r
+ Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);\r
+ ASSERT(NT_SUCCESS(Status));\r
+ AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;\r
+ Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);\r
+ ASSERT(NT_SUCCESS(Status));\r
+ AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;\r
+ Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader);\r
+ ASSERT(NT_SUCCESS(Status));\r
+ AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;\r
+ Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader);\r
+ ASSERT(NT_SUCCESS(Status));\r
+ AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;\r
+\r
+ /* Phase 6: Allocate the security descriptor and make space for the ACL */\r
+ SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,\r
+ sizeof(SECURITY_DESCRIPTOR) + \r
+ AclLength,\r
+ TAG_CM);\r
+ if (!SecurityDescriptor) KEBUGCHECKEX(REGISTRY_ERROR, 2, 6, 0, 0);\r
+\r
+ /* Phase 6: Make a copy of the ACL */\r
+ AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1);\r
+ RtlCopyMemory(AclCopy, Acl, AclLength);\r
+\r
+ /* Phase 7: Create the security descriptor */\r
+ Status = RtlCreateSecurityDescriptor(SecurityDescriptor,\r
+ SECURITY_DESCRIPTOR_REVISION);\r
+ if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 7, Status, 0);\r
+\r
+ /* Phase 8: Set the ACL as a DACL */\r
+ Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,\r
+ TRUE,\r
+ AclCopy,\r
+ FALSE);\r
+ if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 2, 8, Status, 0);\r
+\r
+ /* Free the SIDs and original ACL */\r
+ for (i = 0; i < 4; i++) ExFreePool(Sid[i]);\r
+ ExFreePool(Acl);\r
+\r
+ /* Return the security descriptor */\r
+ return SecurityDescriptor;\r
+}\r
<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>