7b260b24eaf0d28a1b6b01194dc0927c26e3dce7
[reactos.git] / reactos / ntoskrnl / config / cmse.c
1 /*
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)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "ntoskrnl.h"
12 #define NDEBUG
13 #include "debug.h"
14
15 /* GLOBALS *******************************************************************/
16
17 /* FUNCTIONS *****************************************************************/
18
19 PSECURITY_DESCRIPTOR
20 NTAPI
21 INIT_FUNCTION
22 CmpHiveRootSecurityDescriptor(VOID)
23 {
24 NTSTATUS Status;
25 PSECURITY_DESCRIPTOR SecurityDescriptor;
26 PACL Acl, AclCopy;
27 PSID Sid[4];
28 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
29 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
30 ULONG AceLength, AclLength, SidLength;
31 PACE_HEADER AceHeader;
32 ULONG i;
33 PAGED_CODE();
34
35 /* Phase 1: Allocate SIDs */
36 SidLength = RtlLengthRequiredSid(1);
37 Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
38 Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
39 Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
40 SidLength = RtlLengthRequiredSid(2);
41 Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
42
43 /* Make sure all SIDs were allocated */
44 if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))
45 {
46 /* Bugcheck */
47 KeBugCheckEx(REGISTRY_ERROR, 11, 1, 0, 0);
48 }
49
50 /* Phase 2: Initialize all SIDs */
51 Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1);
52 Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1);
53 Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1);
54 Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2);
55 if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 2, 0, 0);
56
57 /* Phase 2: Setup SID Sub Authorities */
58 *RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID;
59 *RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID;
60 *RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID;
61 *RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID;
62 *RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS;
63
64 /* Make sure all SIDs are valid */
65 ASSERT(RtlValidSid(Sid[0]));
66 ASSERT(RtlValidSid(Sid[1]));
67 ASSERT(RtlValidSid(Sid[2]));
68 ASSERT(RtlValidSid(Sid[3]));
69
70 /* Phase 3: Calculate ACL Length */
71 AclLength = sizeof(ACL);
72 for (i = 0; i < 4; i++)
73 {
74 /* This is what MSDN says to do */
75 AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
76 AceLength += SeLengthSid(Sid[i]);
77 AclLength += AceLength;
78 }
79
80 /* Phase 3: Allocate the ACL */
81 Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM);
82 if (!Acl) KeBugCheckEx(REGISTRY_ERROR, 11, 3, 0, 0);
83
84 /* Phase 4: Create the ACL */
85 Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);
86 if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 4, Status, 0);
87
88 /* Phase 5: Build the ACL */
89 Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]);
90 Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[1]);
91 Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]);
92 Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]);
93 if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 5, Status, 0);
94
95 /* Phase 5: Make the ACEs inheritable */
96 Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);
97 ASSERT(NT_SUCCESS(Status));
98 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
99 Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);
100 ASSERT(NT_SUCCESS(Status));
101 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
102 Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader);
103 ASSERT(NT_SUCCESS(Status));
104 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
105 Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader);
106 ASSERT(NT_SUCCESS(Status));
107 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
108
109 /* Phase 6: Allocate the security descriptor and make space for the ACL */
110 SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
111 sizeof(SECURITY_DESCRIPTOR) +
112 AclLength,
113 TAG_CM);
114 if (!SecurityDescriptor) KeBugCheckEx(REGISTRY_ERROR, 11, 6, 0, 0);
115
116 /* Phase 6: Make a copy of the ACL */
117 AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1);
118 RtlCopyMemory(AclCopy, Acl, AclLength);
119
120 /* Phase 7: Create the security descriptor */
121 Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
122 SECURITY_DESCRIPTOR_REVISION);
123 if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 7, Status, 0);
124
125 /* Phase 8: Set the ACL as a DACL */
126 Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
127 TRUE,
128 AclCopy,
129 FALSE);
130 if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 8, Status, 0);
131
132 /* Free the SIDs and original ACL */
133 for (i = 0; i < 4; i++) ExFreePoolWithTag(Sid[i], TAG_CM);
134 ExFreePoolWithTag(Acl, TAG_CM);
135
136 /* Return the security descriptor */
137 return SecurityDescriptor;
138 }
139
140 NTSTATUS
141 CmpQuerySecurityDescriptor(IN PCM_KEY_BODY KeyBody,
142 IN SECURITY_INFORMATION SecurityInformation,
143 OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
144 IN OUT PULONG BufferLength)
145 {
146 PISECURITY_DESCRIPTOR_RELATIVE RelSd;
147 PUCHAR Current;
148 ULONG SidSize;
149 ULONG SdSize;
150 NTSTATUS Status;
151
152 DBG_UNREFERENCED_PARAMETER(KeyBody);
153
154 if (SecurityInformation == 0)
155 {
156 return STATUS_ACCESS_DENIED;
157 }
158
159 SidSize = RtlLengthSid(SeWorldSid);
160 SdSize = sizeof(*RelSd) + 2 * SidSize;
161 RelSd = SecurityDescriptor;
162
163 if (*BufferLength < SdSize)
164 {
165 *BufferLength = SdSize;
166 return STATUS_BUFFER_TOO_SMALL;
167 }
168
169 *BufferLength = SdSize;
170
171 Status = RtlCreateSecurityDescriptorRelative(RelSd,
172 SECURITY_DESCRIPTOR_REVISION);
173 if (!NT_SUCCESS(Status))
174 return Status;
175
176 Current = (PUCHAR)(RelSd + 1);
177 ASSERT((ULONG_PTR)Current - (ULONG_PTR)RelSd <= SdSize);
178
179 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
180 {
181 RtlCopyMemory(Current, SeWorldSid, SidSize);
182 RelSd->Owner = Current - (PUCHAR)RelSd;
183 Current += SidSize;
184 ASSERT((ULONG_PTR)Current - (ULONG_PTR)RelSd <= SdSize);
185 }
186
187 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
188 {
189 RtlCopyMemory(Current, SeWorldSid, SidSize);
190 RelSd->Group = Current - (PUCHAR)RelSd;
191 Current += SidSize;
192 ASSERT((ULONG_PTR)Current - (ULONG_PTR)RelSd <= SdSize);
193 }
194
195 if (SecurityInformation & DACL_SECURITY_INFORMATION)
196 {
197 RelSd->Control |= SE_DACL_PRESENT;
198 }
199
200 if (SecurityInformation & SACL_SECURITY_INFORMATION)
201 {
202 RelSd->Control |= SE_SACL_PRESENT;
203 }
204
205 return STATUS_SUCCESS;
206 }
207
208 NTSTATUS
209 NTAPI
210 CmpSecurityMethod(IN PVOID ObjectBody,
211 IN SECURITY_OPERATION_CODE OperationCode,
212 IN PSECURITY_INFORMATION SecurityInformation,
213 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
214 IN OUT PULONG BufferLength,
215 IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
216 IN POOL_TYPE PoolType,
217 IN PGENERIC_MAPPING GenericMapping)
218 {
219 DBG_UNREFERENCED_PARAMETER(OldSecurityDescriptor);
220 DBG_UNREFERENCED_PARAMETER(GenericMapping);
221
222 switch (OperationCode)
223 {
224 case SetSecurityDescriptor:
225 DPRINT("Set security descriptor\n");
226 ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool));
227 /* HACK */
228 break;
229
230 case QuerySecurityDescriptor:
231 DPRINT("Query security descriptor\n");
232 return CmpQuerySecurityDescriptor(ObjectBody,
233 *SecurityInformation,
234 SecurityDescriptor,
235 BufferLength);
236
237 case DeleteSecurityDescriptor:
238 DPRINT("Delete security descriptor\n");
239 /* HACK */
240 break;
241
242 case AssignSecurityDescriptor:
243 DPRINT("Assign security descriptor\n");
244 /* HACK */
245 break;
246
247 default:
248 KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0);
249 }
250
251 /* HACK */
252 return STATUS_SUCCESS;
253 }