Branch setupapi
[reactos.git] / reactos / ntoskrnl / se / sd.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
6 * FILE: kernel/se/sd.c
7 * PROGRAMER: David Welch <welch@cwcom.net>
8 * REVISION HISTORY:
9 * 26/07/98: Added stubs for security functions
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ntoskrnl.h>
15 #include <internal/debug.h>
16
17 /* GLOBALS ******************************************************************/
18
19 PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL;
20 PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd = NULL;
21 PSECURITY_DESCRIPTOR SePublicOpenSd = NULL;
22 PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd = NULL;
23 PSECURITY_DESCRIPTOR SeSystemDefaultSd = NULL;
24 PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL;
25
26 /* FUNCTIONS ***************************************************************/
27
28 BOOLEAN INIT_FUNCTION
29 SepInitSDs(VOID)
30 {
31 /* Create PublicDefaultSd */
32 SePublicDefaultSd = ExAllocatePool(NonPagedPool,
33 sizeof(SECURITY_DESCRIPTOR));
34 if (SePublicDefaultSd == NULL)
35 return FALSE;
36
37 RtlCreateSecurityDescriptor(SePublicDefaultSd,
38 SECURITY_DESCRIPTOR_REVISION);
39 RtlSetDaclSecurityDescriptor(SePublicDefaultSd,
40 TRUE,
41 SePublicDefaultDacl,
42 FALSE);
43
44 /* Create PublicDefaultUnrestrictedSd */
45 SePublicDefaultUnrestrictedSd = ExAllocatePool(NonPagedPool,
46 sizeof(SECURITY_DESCRIPTOR));
47 if (SePublicDefaultUnrestrictedSd == NULL)
48 return FALSE;
49
50 RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd,
51 SECURITY_DESCRIPTOR_REVISION);
52 RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd,
53 TRUE,
54 SePublicDefaultUnrestrictedDacl,
55 FALSE);
56
57 /* Create PublicOpenSd */
58 SePublicOpenSd = ExAllocatePool(NonPagedPool,
59 sizeof(SECURITY_DESCRIPTOR));
60 if (SePublicOpenSd == NULL)
61 return FALSE;
62
63 RtlCreateSecurityDescriptor(SePublicOpenSd,
64 SECURITY_DESCRIPTOR_REVISION);
65 RtlSetDaclSecurityDescriptor(SePublicOpenSd,
66 TRUE,
67 SePublicOpenDacl,
68 FALSE);
69
70 /* Create PublicOpenUnrestrictedSd */
71 SePublicOpenUnrestrictedSd = ExAllocatePool(NonPagedPool,
72 sizeof(SECURITY_DESCRIPTOR));
73 if (SePublicOpenUnrestrictedSd == NULL)
74 return FALSE;
75
76 RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd,
77 SECURITY_DESCRIPTOR_REVISION);
78 RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd,
79 TRUE,
80 SePublicOpenUnrestrictedDacl,
81 FALSE);
82
83 /* Create SystemDefaultSd */
84 SeSystemDefaultSd = ExAllocatePool(NonPagedPool,
85 sizeof(SECURITY_DESCRIPTOR));
86 if (SeSystemDefaultSd == NULL)
87 return FALSE;
88
89 RtlCreateSecurityDescriptor(SeSystemDefaultSd,
90 SECURITY_DESCRIPTOR_REVISION);
91 RtlSetDaclSecurityDescriptor(SeSystemDefaultSd,
92 TRUE,
93 SeSystemDefaultDacl,
94 FALSE);
95
96 /* Create UnrestrictedSd */
97 SeUnrestrictedSd = ExAllocatePool(NonPagedPool,
98 sizeof(SECURITY_DESCRIPTOR));
99 if (SeUnrestrictedSd == NULL)
100 return FALSE;
101
102 RtlCreateSecurityDescriptor(SeUnrestrictedSd,
103 SECURITY_DESCRIPTOR_REVISION);
104 RtlSetDaclSecurityDescriptor(SeUnrestrictedSd,
105 TRUE,
106 SeUnrestrictedDacl,
107 FALSE);
108
109 return TRUE;
110 }
111
112 /*
113 * @unimplemented
114 */
115 NTSTATUS
116 STDCALL
117 SeCaptureSecurityDescriptor(
118 IN PSECURITY_DESCRIPTOR OriginalSecurityDescriptor,
119 IN KPROCESSOR_MODE CurrentMode,
120 IN POOL_TYPE PoolType,
121 IN BOOLEAN CaptureIfKernel,
122 OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor
123 )
124 {
125 UNIMPLEMENTED;
126 return STATUS_NOT_IMPLEMENTED;
127 }
128
129 /*
130 * @implemented
131 */
132 NTSTATUS STDCALL
133 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
134 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
135 IN OUT PULONG Length,
136 IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL)
137 {
138 PSECURITY_DESCRIPTOR ObjectSd;
139 PSID Owner = 0;
140 PSID Group = 0;
141 PACL Dacl = 0;
142 PACL Sacl = 0;
143 ULONG OwnerLength = 0;
144 ULONG GroupLength = 0;
145 ULONG DaclLength = 0;
146 ULONG SaclLength = 0;
147 ULONG Control = 0;
148 ULONG_PTR Current;
149 ULONG SdLength;
150
151 if (*ObjectsSecurityDescriptor == NULL)
152 {
153 if (*Length < sizeof(SECURITY_DESCRIPTOR))
154 {
155 *Length = sizeof(SECURITY_DESCRIPTOR);
156 return STATUS_BUFFER_TOO_SMALL;
157 }
158
159 *Length = sizeof(SECURITY_DESCRIPTOR);
160 RtlCreateSecurityDescriptor(SecurityDescriptor,
161 SECURITY_DESCRIPTOR_REVISION);
162 SecurityDescriptor->Control |= SE_SELF_RELATIVE;
163 return STATUS_SUCCESS;
164 }
165
166 ObjectSd = *ObjectsSecurityDescriptor;
167
168 /* Calculate the required security descriptor length */
169 Control = SE_SELF_RELATIVE;
170 if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) &&
171 (ObjectSd->Owner != NULL))
172 {
173 Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
174 OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
175 Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
176 }
177
178 if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) &&
179 (ObjectSd->Group != NULL))
180 {
181 Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
182 GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
183 Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
184 }
185
186 if ((*SecurityInformation & DACL_SECURITY_INFORMATION) &&
187 (ObjectSd->Control & SE_DACL_PRESENT))
188 {
189 if (ObjectSd->Dacl != NULL)
190 {
191 Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
192 DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
193 }
194 Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
195 }
196
197 if ((*SecurityInformation & SACL_SECURITY_INFORMATION) &&
198 (ObjectSd->Control & SE_SACL_PRESENT))
199 {
200 if (ObjectSd->Sacl != NULL)
201 {
202 Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
203 SaclLength = ROUND_UP(Sacl->AclSize, 4);
204 }
205 Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
206 }
207
208 SdLength = OwnerLength + GroupLength + DaclLength +
209 SaclLength + sizeof(SECURITY_DESCRIPTOR);
210 if (*Length < sizeof(SECURITY_DESCRIPTOR))
211 {
212 *Length = SdLength;
213 return STATUS_BUFFER_TOO_SMALL;
214 }
215
216 /* Build the new security descrtiptor */
217 RtlCreateSecurityDescriptor(SecurityDescriptor,
218 SECURITY_DESCRIPTOR_REVISION);
219 SecurityDescriptor->Control = Control;
220
221 Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR);
222
223 if (OwnerLength != 0)
224 {
225 RtlCopyMemory((PVOID)Current,
226 Owner,
227 OwnerLength);
228 SecurityDescriptor->Owner = (PSID)(Current - (ULONG_PTR)SecurityDescriptor);
229 Current += OwnerLength;
230 }
231
232 if (GroupLength != 0)
233 {
234 RtlCopyMemory((PVOID)Current,
235 Group,
236 GroupLength);
237 SecurityDescriptor->Group = (PSID)(Current - (ULONG_PTR)SecurityDescriptor);
238 Current += GroupLength;
239 }
240
241 if (DaclLength != 0)
242 {
243 RtlCopyMemory((PVOID)Current,
244 Dacl,
245 DaclLength);
246 SecurityDescriptor->Dacl = (PACL)(Current - (ULONG_PTR)SecurityDescriptor);
247 Current += DaclLength;
248 }
249
250 if (SaclLength != 0)
251 {
252 RtlCopyMemory((PVOID)Current,
253 Sacl,
254 SaclLength);
255 SecurityDescriptor->Sacl = (PACL)(Current - (ULONG_PTR)SecurityDescriptor);
256 Current += SaclLength;
257 }
258
259 *Length = SdLength;
260
261 return STATUS_SUCCESS;
262 }
263
264 /*
265 * @unimplemented
266 */
267 NTSTATUS
268 STDCALL
269 SeReleaseSecurityDescriptor(
270 IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
271 IN KPROCESSOR_MODE CurrentMode,
272 IN BOOLEAN CaptureIfKernelMode
273 )
274 {
275 UNIMPLEMENTED;
276 return STATUS_NOT_IMPLEMENTED;
277 }
278
279 /*
280 * @unimplemented
281 */
282 NTSTATUS STDCALL
283 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
284 IN PSECURITY_INFORMATION SecurityInformation,
285 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
286 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
287 IN POOL_TYPE PoolType,
288 IN PGENERIC_MAPPING GenericMapping)
289 {
290 UNIMPLEMENTED;
291 return STATUS_NOT_IMPLEMENTED;
292 }
293
294 /*
295 * @unimplemented
296 */
297 NTSTATUS
298 STDCALL
299 SeSetSecurityDescriptorInfoEx(
300 IN PVOID Object OPTIONAL,
301 IN PSECURITY_INFORMATION SecurityInformation,
302 IN PSECURITY_DESCRIPTOR ModificationDescriptor,
303 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
304 IN ULONG AutoInheritFlags,
305 IN POOL_TYPE PoolType,
306 IN PGENERIC_MAPPING GenericMapping
307 )
308 {
309 UNIMPLEMENTED;
310 return STATUS_NOT_IMPLEMENTED;
311 }
312
313
314 /*
315 * @implemented
316 */
317 BOOLEAN STDCALL
318 SeValidSecurityDescriptor(IN ULONG Length,
319 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
320 {
321 ULONG SdLength;
322 PSID Sid;
323 PACL Acl;
324
325 if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH)
326 {
327 DPRINT1("Invalid Security Descriptor revision\n");
328 return FALSE;
329 }
330
331 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
332 {
333 DPRINT1("Invalid Security Descriptor revision\n");
334 return FALSE;
335 }
336
337 if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE))
338 {
339 DPRINT1("No self-relative Security Descriptor\n");
340 return FALSE;
341 }
342
343 SdLength = sizeof(SECURITY_DESCRIPTOR);
344
345 /* Check Owner SID */
346 if (SecurityDescriptor->Owner == NULL)
347 {
348 DPRINT1("No Owner SID\n");
349 return FALSE;
350 }
351
352 if ((ULONG_PTR)SecurityDescriptor->Owner % sizeof(ULONG))
353 {
354 DPRINT1("Invalid Owner SID alignment\n");
355 return FALSE;
356 }
357
358 Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Owner);
359 if (Sid->Revision != SID_REVISION)
360 {
361 DPRINT1("Invalid Owner SID revision\n");
362 return FALSE;
363 }
364
365 SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
366 if (Length < SdLength)
367 {
368 DPRINT1("Invalid Owner SID size\n");
369 return FALSE;
370 }
371
372 /* Check Group SID */
373 if (SecurityDescriptor->Group != NULL)
374 {
375 if ((ULONG_PTR)SecurityDescriptor->Group % sizeof(ULONG))
376 {
377 DPRINT1("Invalid Group SID alignment\n");
378 return FALSE;
379 }
380
381 Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Group);
382 if (Sid->Revision != SID_REVISION)
383 {
384 DPRINT1("Invalid Group SID revision\n");
385 return FALSE;
386 }
387
388 SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
389 if (Length < SdLength)
390 {
391 DPRINT1("Invalid Group SID size\n");
392 return FALSE;
393 }
394 }
395
396 /* Check DACL */
397 if (SecurityDescriptor->Dacl != NULL)
398 {
399 if ((ULONG_PTR)SecurityDescriptor->Dacl % sizeof(ULONG))
400 {
401 DPRINT1("Invalid DACL alignment\n");
402 return FALSE;
403 }
404
405 Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Dacl);
406 if ((Acl->AclRevision < MIN_ACL_REVISION) &&
407 (Acl->AclRevision > MAX_ACL_REVISION))
408 {
409 DPRINT1("Invalid DACL revision\n");
410 return FALSE;
411 }
412
413 SdLength += Acl->AclSize;
414 if (Length < SdLength)
415 {
416 DPRINT1("Invalid DACL size\n");
417 return FALSE;
418 }
419 }
420
421 /* Check SACL */
422 if (SecurityDescriptor->Sacl != NULL)
423 {
424 if ((ULONG_PTR)SecurityDescriptor->Sacl % sizeof(ULONG))
425 {
426 DPRINT1("Invalid SACL alignment\n");
427 return FALSE;
428 }
429
430 Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Sacl);
431 if ((Acl->AclRevision < MIN_ACL_REVISION) ||
432 (Acl->AclRevision > MAX_ACL_REVISION))
433 {
434 DPRINT1("Invalid SACL revision\n");
435 return FALSE;
436 }
437
438 SdLength += Acl->AclSize;
439 if (Length < SdLength)
440 {
441 DPRINT1("Invalid SACL size\n");
442 return FALSE;
443 }
444 }
445
446 return TRUE;
447 }
448
449 /* EOF */