- Add missing ACE structures to ntifs.h.
authorAlex Ionescu <aionescu@gmail.com>
Fri, 11 May 2007 18:15:13 +0000 (18:15 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Fri, 11 May 2007 18:15:13 +0000 (18:15 +0000)
- 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

reactos/include/ddk/ntifs.h
reactos/ntoskrnl/cm/cm.h
reactos/ntoskrnl/cm/registry.c
reactos/ntoskrnl/config/cmconfig.c
reactos/ntoskrnl/config/cmse.c [new file with mode: 0644]
reactos/ntoskrnl/ntoskrnl.rbuild

index 4614a46..36c2c0d 100644 (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 );                 \
index 8c1e867..a81d563 100644 (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)
 {
index de2753d..c35689b 100644 (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))
index cdad7d3..3040eca 100644 (file)
@@ -194,3 +194,81 @@ CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
     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
diff --git a/reactos/ntoskrnl/config/cmse.c b/reactos/ntoskrnl/config/cmse.c
new file mode 100644 (file)
index 0000000..c829960
--- /dev/null
@@ -0,0 +1,138 @@
+/*\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
index 4144176..2cf6348 100644 (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>