2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/config/cmse.c
5 * PURPOSE: Configuration Manager - Security Subsystem Interface
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
15 /* GLOBALS *******************************************************************/
17 /* FUNCTIONS *****************************************************************/
21 CmpHiveRootSecurityDescriptor(VOID
)
24 PSECURITY_DESCRIPTOR SecurityDescriptor
;
27 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
28 SID_IDENTIFIER_AUTHORITY NtAuthority
= {SECURITY_NT_AUTHORITY
};
29 ULONG AceLength
, AclLength
, SidLength
;
30 PACE_HEADER AceHeader
;
34 /* Phase 1: Allocate SIDs */
35 SidLength
= RtlLengthRequiredSid(1);
36 Sid
[0] = ExAllocatePoolWithTag(PagedPool
, SidLength
, TAG_CM
);
37 Sid
[1] = ExAllocatePoolWithTag(PagedPool
, SidLength
, TAG_CM
);
38 Sid
[2] = ExAllocatePoolWithTag(PagedPool
, SidLength
, TAG_CM
);
39 SidLength
= RtlLengthRequiredSid(2);
40 Sid
[3] = ExAllocatePoolWithTag(PagedPool
, SidLength
, TAG_CM
);
42 /* Make sure all SIDs were allocated */
43 if (!(Sid
[0]) || !(Sid
[1]) || !(Sid
[2]) || !(Sid
[3]))
46 KeBugCheckEx(REGISTRY_ERROR
, 11, 1, 0, 0);
49 /* Phase 2: Initialize all SIDs */
50 Status
= RtlInitializeSid(Sid
[0], &WorldAuthority
, 1);
51 Status
|= RtlInitializeSid(Sid
[1], &NtAuthority
, 1);
52 Status
|= RtlInitializeSid(Sid
[2], &NtAuthority
, 1);
53 Status
|= RtlInitializeSid(Sid
[3], &NtAuthority
, 2);
54 if (!NT_SUCCESS(Status
)) KeBugCheckEx(REGISTRY_ERROR
, 11, 2, 0, 0);
56 /* Phase 2: Setup SID Sub Authorities */
57 *RtlSubAuthoritySid(Sid
[0], 0) = SECURITY_WORLD_RID
;
58 *RtlSubAuthoritySid(Sid
[1], 0) = SECURITY_RESTRICTED_CODE_RID
;
59 *RtlSubAuthoritySid(Sid
[2], 0) = SECURITY_LOCAL_SYSTEM_RID
;
60 *RtlSubAuthoritySid(Sid
[3], 0) = SECURITY_BUILTIN_DOMAIN_RID
;
61 *RtlSubAuthoritySid(Sid
[3], 1) = DOMAIN_ALIAS_RID_ADMINS
;
63 /* Make sure all SIDs are valid */
64 ASSERT(RtlValidSid(Sid
[0]));
65 ASSERT(RtlValidSid(Sid
[1]));
66 ASSERT(RtlValidSid(Sid
[2]));
67 ASSERT(RtlValidSid(Sid
[3]));
69 /* Phase 3: Calculate ACL Length */
70 AclLength
= sizeof(ACL
);
71 for (i
= 0; i
< 4; i
++)
73 /* This is what MSDN says to do */
74 AceLength
= FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
);
75 AceLength
+= SeLengthSid(Sid
[i
]);
76 AclLength
+= AceLength
;
79 /* Phase 3: Allocate the ACL */
80 Acl
= ExAllocatePoolWithTag(PagedPool
, AclLength
, TAG_CM
);
81 if (!Acl
) KeBugCheckEx(REGISTRY_ERROR
, 11, 3, 0, 0);
83 /* Phase 4: Create the ACL */
84 Status
= RtlCreateAcl(Acl
, AclLength
, ACL_REVISION
);
85 if (!NT_SUCCESS(Status
)) KeBugCheckEx(REGISTRY_ERROR
, 11, 4, Status
, 0);
87 /* Phase 5: Build the ACL */
88 Status
= RtlAddAccessAllowedAce(Acl
, ACL_REVISION
, KEY_ALL_ACCESS
, Sid
[0]);
89 Status
|= RtlAddAccessAllowedAce(Acl
, ACL_REVISION
, KEY_ALL_ACCESS
, Sid
[1]);
90 Status
|= RtlAddAccessAllowedAce(Acl
, ACL_REVISION
, KEY_READ
, Sid
[2]);
91 Status
|= RtlAddAccessAllowedAce(Acl
, ACL_REVISION
, KEY_READ
, Sid
[3]);
92 if (!NT_SUCCESS(Status
)) KeBugCheckEx(REGISTRY_ERROR
, 11, 5, Status
, 0);
94 /* Phase 5: Make the ACEs inheritable */
95 Status
= RtlGetAce(Acl
, 0,( PVOID
*)&AceHeader
);
96 ASSERT(NT_SUCCESS(Status
));
97 AceHeader
->AceFlags
|= CONTAINER_INHERIT_ACE
;
98 Status
= RtlGetAce(Acl
, 1, (PVOID
*)&AceHeader
);
99 ASSERT(NT_SUCCESS(Status
));
100 AceHeader
->AceFlags
|= CONTAINER_INHERIT_ACE
;
101 Status
= RtlGetAce(Acl
, 2, (PVOID
*)&AceHeader
);
102 ASSERT(NT_SUCCESS(Status
));
103 AceHeader
->AceFlags
|= CONTAINER_INHERIT_ACE
;
104 Status
= RtlGetAce(Acl
, 3, (PVOID
*)&AceHeader
);
105 ASSERT(NT_SUCCESS(Status
));
106 AceHeader
->AceFlags
|= CONTAINER_INHERIT_ACE
;
108 /* Phase 6: Allocate the security descriptor and make space for the ACL */
109 SecurityDescriptor
= ExAllocatePoolWithTag(PagedPool
,
110 sizeof(SECURITY_DESCRIPTOR
) +
113 if (!SecurityDescriptor
) KeBugCheckEx(REGISTRY_ERROR
, 11, 6, 0, 0);
115 /* Phase 6: Make a copy of the ACL */
116 AclCopy
= (PACL
)((PISECURITY_DESCRIPTOR
)SecurityDescriptor
+ 1);
117 RtlCopyMemory(AclCopy
, Acl
, AclLength
);
119 /* Phase 7: Create the security descriptor */
120 Status
= RtlCreateSecurityDescriptor(SecurityDescriptor
,
121 SECURITY_DESCRIPTOR_REVISION
);
122 if (!NT_SUCCESS(Status
)) KeBugCheckEx(REGISTRY_ERROR
, 11, 7, Status
, 0);
124 /* Phase 8: Set the ACL as a DACL */
125 Status
= RtlSetDaclSecurityDescriptor(SecurityDescriptor
,
129 if (!NT_SUCCESS(Status
)) KeBugCheckEx(REGISTRY_ERROR
, 11, 8, Status
, 0);
131 /* Free the SIDs and original ACL */
132 for (i
= 0; i
< 4; i
++) ExFreePoolWithTag(Sid
[i
], TAG_CM
);
133 ExFreePoolWithTag(Acl
, TAG_CM
);
135 /* Return the security descriptor */
136 return SecurityDescriptor
;
141 CmpSecurityMethod(IN PVOID ObjectBody
,
142 IN SECURITY_OPERATION_CODE OperationCode
,
143 IN PSECURITY_INFORMATION SecurityInformation
,
144 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
145 IN OUT PULONG BufferLength
,
146 IN OUT PSECURITY_DESCRIPTOR
*OldSecurityDescriptor
,
147 IN POOL_TYPE PoolType
,
148 IN PGENERIC_MAPPING GenericMapping
)
151 return STATUS_SUCCESS
;