Merge 13159:13510 from trunk
[reactos.git] / reactos / ntoskrnl / se / sd.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/se/sd.c
6 * PURPOSE: Security manager
7 *
8 * PROGRAMMERS: David Welch <welch@cwcom.net>
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #include <internal/debug.h>
15
16 /* GLOBALS ******************************************************************/
17
18 PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL;
19 PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd = NULL;
20 PSECURITY_DESCRIPTOR SePublicOpenSd = NULL;
21 PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd = NULL;
22 PSECURITY_DESCRIPTOR SeSystemDefaultSd = NULL;
23 PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL;
24
25 /* FUNCTIONS ***************************************************************/
26
27 BOOLEAN INIT_FUNCTION
28 SepInitSDs(VOID)
29 {
30 /* Create PublicDefaultSd */
31 SePublicDefaultSd = ExAllocatePool(NonPagedPool,
32 sizeof(SECURITY_DESCRIPTOR));
33 if (SePublicDefaultSd == NULL)
34 return FALSE;
35
36 RtlCreateSecurityDescriptor(SePublicDefaultSd,
37 SECURITY_DESCRIPTOR_REVISION);
38 RtlSetDaclSecurityDescriptor(SePublicDefaultSd,
39 TRUE,
40 SePublicDefaultDacl,
41 FALSE);
42
43 /* Create PublicDefaultUnrestrictedSd */
44 SePublicDefaultUnrestrictedSd = ExAllocatePool(NonPagedPool,
45 sizeof(SECURITY_DESCRIPTOR));
46 if (SePublicDefaultUnrestrictedSd == NULL)
47 return FALSE;
48
49 RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd,
50 SECURITY_DESCRIPTOR_REVISION);
51 RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd,
52 TRUE,
53 SePublicDefaultUnrestrictedDacl,
54 FALSE);
55
56 /* Create PublicOpenSd */
57 SePublicOpenSd = ExAllocatePool(NonPagedPool,
58 sizeof(SECURITY_DESCRIPTOR));
59 if (SePublicOpenSd == NULL)
60 return FALSE;
61
62 RtlCreateSecurityDescriptor(SePublicOpenSd,
63 SECURITY_DESCRIPTOR_REVISION);
64 RtlSetDaclSecurityDescriptor(SePublicOpenSd,
65 TRUE,
66 SePublicOpenDacl,
67 FALSE);
68
69 /* Create PublicOpenUnrestrictedSd */
70 SePublicOpenUnrestrictedSd = ExAllocatePool(NonPagedPool,
71 sizeof(SECURITY_DESCRIPTOR));
72 if (SePublicOpenUnrestrictedSd == NULL)
73 return FALSE;
74
75 RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd,
76 SECURITY_DESCRIPTOR_REVISION);
77 RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd,
78 TRUE,
79 SePublicOpenUnrestrictedDacl,
80 FALSE);
81
82 /* Create SystemDefaultSd */
83 SeSystemDefaultSd = ExAllocatePool(NonPagedPool,
84 sizeof(SECURITY_DESCRIPTOR));
85 if (SeSystemDefaultSd == NULL)
86 return FALSE;
87
88 RtlCreateSecurityDescriptor(SeSystemDefaultSd,
89 SECURITY_DESCRIPTOR_REVISION);
90 RtlSetDaclSecurityDescriptor(SeSystemDefaultSd,
91 TRUE,
92 SeSystemDefaultDacl,
93 FALSE);
94
95 /* Create UnrestrictedSd */
96 SeUnrestrictedSd = ExAllocatePool(NonPagedPool,
97 sizeof(SECURITY_DESCRIPTOR));
98 if (SeUnrestrictedSd == NULL)
99 return FALSE;
100
101 RtlCreateSecurityDescriptor(SeUnrestrictedSd,
102 SECURITY_DESCRIPTOR_REVISION);
103 RtlSetDaclSecurityDescriptor(SeUnrestrictedSd,
104 TRUE,
105 SeUnrestrictedDacl,
106 FALSE);
107
108 return TRUE;
109 }
110
111 /*
112 * @implemented
113 */
114 NTSTATUS
115 STDCALL
116 SeCaptureSecurityDescriptor(
117 IN PSECURITY_DESCRIPTOR OriginalSecurityDescriptor,
118 IN KPROCESSOR_MODE CurrentMode,
119 IN POOL_TYPE PoolType,
120 IN BOOLEAN CaptureIfKernel,
121 OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor
122 )
123 {
124 SECURITY_DESCRIPTOR DescriptorCopy;
125 PSECURITY_DESCRIPTOR NewDescriptor;
126 ULONG OwnerSAC = 0, GroupSAC = 0;
127 ULONG OwnerSize = 0, GroupSize = 0;
128 ULONG SaclSize = 0, DaclSize = 0;
129 ULONG DescriptorSize = 0;
130 NTSTATUS Status = STATUS_SUCCESS;
131
132 if(OriginalSecurityDescriptor != NULL)
133 {
134 if(CurrentMode != KernelMode)
135 {
136 _SEH_TRY
137 {
138 /* first only probe and copy until the control field of the descriptor
139 to determine whether it's a self-relative descriptor */
140 DescriptorSize = (ULONG)((ULONG_PTR)&OriginalSecurityDescriptor->Control -
141 (ULONG_PTR)OriginalSecurityDescriptor) +
142 sizeof(OriginalSecurityDescriptor->Control);
143 ProbeForRead(OriginalSecurityDescriptor,
144 DescriptorSize,
145 sizeof(ULONG));
146
147 if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
148 {
149 Status = STATUS_UNKNOWN_REVISION;
150 _SEH_LEAVE;
151 }
152
153 /* make a copy on the stack */
154 DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
155 DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
156 DescriptorCopy.Control = OriginalSecurityDescriptor->Control;
157 DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ?
158 sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR));
159
160 /* probe and copy the entire security descriptor structure. The SIDs
161 and ACLs will be probed and copied later though */
162 ProbeForRead(OriginalSecurityDescriptor,
163 DescriptorSize,
164 sizeof(ULONG));
165 if(DescriptorCopy.Control & SE_SELF_RELATIVE)
166 {
167 PSECURITY_DESCRIPTOR_RELATIVE RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
168
169 DescriptorCopy.Owner = (PSID)RelSD->Owner;
170 DescriptorCopy.Group = (PSID)RelSD->Group;
171 DescriptorCopy.Sacl = (PACL)RelSD->Sacl;
172 DescriptorCopy.Dacl = (PACL)RelSD->Dacl;
173 }
174 else
175 {
176 DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner;
177 DescriptorCopy.Group = OriginalSecurityDescriptor->Group;
178 DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl;
179 DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl;
180 }
181 }
182 _SEH_HANDLE
183 {
184 Status = _SEH_GetExceptionCode();
185 }
186 _SEH_END;
187
188 if(!NT_SUCCESS(Status))
189 {
190 return Status;
191 }
192 }
193 else if(!CaptureIfKernel)
194 {
195 if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
196 {
197 return STATUS_UNKNOWN_REVISION;
198 }
199
200 *CapturedSecurityDescriptor = OriginalSecurityDescriptor;
201 return STATUS_SUCCESS;
202 }
203 else
204 {
205 if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
206 {
207 return STATUS_UNKNOWN_REVISION;
208 }
209
210 /* make a copy on the stack */
211 DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
212 DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
213 DescriptorCopy.Control = OriginalSecurityDescriptor->Control;
214 DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ?
215 sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR));
216 if(DescriptorCopy.Control & SE_SELF_RELATIVE)
217 {
218 PSECURITY_DESCRIPTOR_RELATIVE RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
219
220 DescriptorCopy.Owner = (PSID)RelSD->Owner;
221 DescriptorCopy.Group = (PSID)RelSD->Group;
222 DescriptorCopy.Sacl = (PACL)RelSD->Sacl;
223 DescriptorCopy.Dacl = (PACL)RelSD->Dacl;
224 }
225 else
226 {
227 DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner;
228 DescriptorCopy.Group = OriginalSecurityDescriptor->Group;
229 DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl;
230 DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl;
231 }
232 }
233
234 if(DescriptorCopy.Control & SE_SELF_RELATIVE)
235 {
236 /* in case we're dealing with a self-relative descriptor, do a basic convert
237 to an absolute descriptor. We do this so we can simply access the data
238 using the pointers without calculating them again. */
239 DescriptorCopy.Control &= ~SE_SELF_RELATIVE;
240 if(DescriptorCopy.Owner != NULL)
241 {
242 DescriptorCopy.Owner = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Owner);
243 }
244 if(DescriptorCopy.Group != NULL)
245 {
246 DescriptorCopy.Group = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Group);
247 }
248 if(DescriptorCopy.Dacl != NULL)
249 {
250 DescriptorCopy.Dacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Dacl);
251 }
252 if(DescriptorCopy.Sacl != NULL)
253 {
254 DescriptorCopy.Sacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Sacl);
255 }
256 }
257
258 /* determine the size of the SIDs */
259 #define DetermineSIDSize(SidType) \
260 do { \
261 if(DescriptorCopy.SidType != NULL) \
262 { \
263 SID *SidType = (SID*)DescriptorCopy.SidType; \
264 \
265 if(CurrentMode != KernelMode) \
266 { \
267 /* securely access the buffers! */ \
268 _SEH_TRY \
269 { \
270 ProbeForRead(&SidType->SubAuthorityCount, \
271 sizeof(SidType->SubAuthorityCount), \
272 1); \
273 SidType##SAC = SidType->SubAuthorityCount; \
274 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
275 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
276 ProbeForRead(SidType, \
277 SidType##Size, \
278 sizeof(ULONG)); \
279 if(!RtlValidSid(SidType)) \
280 { \
281 Status = STATUS_INVALID_SID; \
282 } \
283 } \
284 _SEH_HANDLE \
285 { \
286 Status = _SEH_GetExceptionCode(); \
287 } \
288 _SEH_END; \
289 \
290 if(!NT_SUCCESS(Status)) \
291 { \
292 return Status; \
293 } \
294 } \
295 else \
296 { \
297 SidType##SAC = SidType->SubAuthorityCount; \
298 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
299 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
300 } \
301 } \
302 } while(0)
303
304 DetermineSIDSize(Owner);
305 DetermineSIDSize(Group);
306
307 /* determine the size of the ACLs */
308 #define DetermineACLSize(AclType, AclFlag) \
309 do { \
310 if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \
311 DescriptorCopy.AclType != NULL) \
312 { \
313 PACL AclType = (PACL)DescriptorCopy.AclType; \
314 \
315 if(CurrentMode != KernelMode) \
316 { \
317 /* securely access the buffers! */ \
318 _SEH_TRY \
319 { \
320 ProbeForRead(&AclType->AclSize, \
321 sizeof(AclType->AclSize), \
322 1); \
323 AclType##Size = AclType->AclSize; \
324 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
325 ProbeForRead(AclType, \
326 AclType##Size, \
327 sizeof(ULONG)); \
328 if(!RtlValidAcl(AclType)) \
329 { \
330 Status = STATUS_INVALID_ACL; \
331 } \
332 } \
333 _SEH_HANDLE \
334 { \
335 Status = _SEH_GetExceptionCode(); \
336 } \
337 _SEH_END; \
338 \
339 if(!NT_SUCCESS(Status)) \
340 { \
341 return Status; \
342 } \
343 } \
344 else \
345 { \
346 AclType##Size = AclType->AclSize; \
347 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
348 } \
349 } \
350 else \
351 { \
352 DescriptorCopy.AclType = NULL; \
353 } \
354 } while(0)
355
356 DetermineACLSize(Sacl, SACL);
357 DetermineACLSize(Dacl, DACL);
358
359 /* allocate enough memory to store a complete copy of a self-relative
360 security descriptor */
361 NewDescriptor = ExAllocatePool(PoolType,
362 DescriptorSize);
363 if(NewDescriptor != NULL)
364 {
365 ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR);
366
367 NewDescriptor->Revision = DescriptorCopy.Revision;
368 NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
369 NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;
370
371 _SEH_TRY
372 {
373 /* setup the offsets and copy the SIDs and ACLs to the new
374 self-relative security descriptor. Probing the pointers is not
375 neccessary anymore as we did that when collecting the sizes! */
376 #define CopySIDOrACL(Type) \
377 do { \
378 if(DescriptorCopy.Type != NULL) \
379 { \
380 NewDescriptor->Type = (PVOID)Offset; \
381 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
382 (ULONG_PTR)NewDescriptor->Type), \
383 DescriptorCopy.Type, \
384 Type##Size); \
385 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
386 } \
387 } while(0)
388
389 CopySIDOrACL(Owner);
390 CopySIDOrACL(Group);
391 CopySIDOrACL(Sacl);
392 CopySIDOrACL(Dacl);
393 }
394 _SEH_HANDLE
395 {
396 Status = _SEH_GetExceptionCode();
397 }
398 _SEH_END;
399
400 if(NT_SUCCESS(Status))
401 {
402 /* we're finally done! copy the pointer to the captured descriptor to
403 to the caller */
404 *CapturedSecurityDescriptor = NewDescriptor;
405 return STATUS_SUCCESS;
406 }
407 else
408 {
409 /* we failed to copy the data to the new descriptor */
410 ExFreePool(NewDescriptor);
411 }
412 }
413 else
414 {
415 Status = STATUS_INSUFFICIENT_RESOURCES;
416 }
417 }
418 else
419 {
420 /* nothing to do... */
421 *CapturedSecurityDescriptor = NULL;
422 }
423
424 return Status;
425 }
426
427 /*
428 * @implemented
429 */
430 NTSTATUS STDCALL
431 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
432 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
433 IN OUT PULONG Length,
434 IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL)
435 {
436 PSECURITY_DESCRIPTOR ObjectSd;
437 PSECURITY_DESCRIPTOR_RELATIVE RelSD;
438 PSID Owner = NULL;
439 PSID Group = NULL;
440 PACL Dacl = NULL;
441 PACL Sacl = NULL;
442 ULONG OwnerLength = 0;
443 ULONG GroupLength = 0;
444 ULONG DaclLength = 0;
445 ULONG SaclLength = 0;
446 ULONG Control = 0;
447 ULONG_PTR Current;
448 ULONG SdLength;
449
450 RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
451
452 if (*ObjectsSecurityDescriptor == NULL)
453 {
454 if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE))
455 {
456 *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
457 return STATUS_BUFFER_TOO_SMALL;
458 }
459
460 *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
461 RtlCreateSecurityDescriptorRelative(RelSD,
462 SECURITY_DESCRIPTOR_REVISION);
463 return STATUS_SUCCESS;
464 }
465
466 ObjectSd = *ObjectsSecurityDescriptor;
467
468 /* Calculate the required security descriptor length */
469 Control = SE_SELF_RELATIVE;
470 if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) &&
471 (ObjectSd->Owner != NULL))
472 {
473 Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
474 OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
475 Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
476 }
477
478 if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) &&
479 (ObjectSd->Group != NULL))
480 {
481 Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
482 GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
483 Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
484 }
485
486 if ((*SecurityInformation & DACL_SECURITY_INFORMATION) &&
487 (ObjectSd->Control & SE_DACL_PRESENT))
488 {
489 if (ObjectSd->Dacl != NULL)
490 {
491 Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
492 DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
493 }
494 Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
495 }
496
497 if ((*SecurityInformation & SACL_SECURITY_INFORMATION) &&
498 (ObjectSd->Control & SE_SACL_PRESENT))
499 {
500 if (ObjectSd->Sacl != NULL)
501 {
502 Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
503 SaclLength = ROUND_UP(Sacl->AclSize, 4);
504 }
505 Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
506 }
507
508 SdLength = OwnerLength + GroupLength + DaclLength +
509 SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE);
510 if (*Length < SdLength)
511 {
512 *Length = SdLength;
513 return STATUS_BUFFER_TOO_SMALL;
514 }
515
516 /* Build the new security descrtiptor */
517 RtlCreateSecurityDescriptorRelative(RelSD,
518 SECURITY_DESCRIPTOR_REVISION);
519 RelSD->Control = Control;
520
521 Current = (ULONG_PTR)(RelSD + 1);
522
523 if (OwnerLength != 0)
524 {
525 RtlCopyMemory((PVOID)Current,
526 Owner,
527 OwnerLength);
528 RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
529 Current += OwnerLength;
530 }
531
532 if (GroupLength != 0)
533 {
534 RtlCopyMemory((PVOID)Current,
535 Group,
536 GroupLength);
537 RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
538 Current += GroupLength;
539 }
540
541 if (DaclLength != 0)
542 {
543 RtlCopyMemory((PVOID)Current,
544 Dacl,
545 DaclLength);
546 RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
547 Current += DaclLength;
548 }
549
550 if (SaclLength != 0)
551 {
552 RtlCopyMemory((PVOID)Current,
553 Sacl,
554 SaclLength);
555 RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
556 Current += SaclLength;
557 }
558
559 *Length = SdLength;
560
561 return STATUS_SUCCESS;
562 }
563
564 /*
565 * @implemented
566 */
567 NTSTATUS
568 STDCALL
569 SeReleaseSecurityDescriptor(
570 IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
571 IN KPROCESSOR_MODE CurrentMode,
572 IN BOOLEAN CaptureIfKernelMode
573 )
574 {
575 /* WARNING! You need to call this function with the same value for CurrentMode
576 and CaptureIfKernelMode that you previously passed to
577 SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
578 if(CapturedSecurityDescriptor != NULL &&
579 (CurrentMode == UserMode ||
580 (CurrentMode == KernelMode && CaptureIfKernelMode)))
581 {
582 /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
583 ExFreePool(CapturedSecurityDescriptor);
584 }
585
586 return STATUS_SUCCESS;
587 }
588
589 /*
590 * @unimplemented
591 */
592 NTSTATUS STDCALL
593 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
594 IN PSECURITY_INFORMATION SecurityInformation,
595 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
596 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
597 IN POOL_TYPE PoolType,
598 IN PGENERIC_MAPPING GenericMapping)
599 {
600 UNIMPLEMENTED;
601 return STATUS_NOT_IMPLEMENTED;
602 }
603
604 /*
605 * @unimplemented
606 */
607 NTSTATUS
608 STDCALL
609 SeSetSecurityDescriptorInfoEx(
610 IN PVOID Object OPTIONAL,
611 IN PSECURITY_INFORMATION SecurityInformation,
612 IN PSECURITY_DESCRIPTOR ModificationDescriptor,
613 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
614 IN ULONG AutoInheritFlags,
615 IN POOL_TYPE PoolType,
616 IN PGENERIC_MAPPING GenericMapping
617 )
618 {
619 UNIMPLEMENTED;
620 return STATUS_NOT_IMPLEMENTED;
621 }
622
623
624 /*
625 * @implemented
626 */
627 BOOLEAN STDCALL
628 SeValidSecurityDescriptor(IN ULONG Length,
629 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
630 {
631 ULONG SdLength;
632 PISID Sid;
633 PACL Acl;
634
635 if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH)
636 {
637 DPRINT1("Invalid Security Descriptor revision\n");
638 return FALSE;
639 }
640
641 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
642 {
643 DPRINT1("Invalid Security Descriptor revision\n");
644 return FALSE;
645 }
646
647 if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE))
648 {
649 DPRINT1("No self-relative Security Descriptor\n");
650 return FALSE;
651 }
652
653 SdLength = sizeof(SECURITY_DESCRIPTOR);
654
655 /* Check Owner SID */
656 if (SecurityDescriptor->Owner == NULL)
657 {
658 DPRINT1("No Owner SID\n");
659 return FALSE;
660 }
661
662 if ((ULONG_PTR)SecurityDescriptor->Owner % sizeof(ULONG))
663 {
664 DPRINT1("Invalid Owner SID alignment\n");
665 return FALSE;
666 }
667
668 Sid = (PISID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Owner);
669 if (Sid->Revision != SID_REVISION)
670 {
671 DPRINT1("Invalid Owner SID revision\n");
672 return FALSE;
673 }
674
675 SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
676 if (Length < SdLength)
677 {
678 DPRINT1("Invalid Owner SID size\n");
679 return FALSE;
680 }
681
682 /* Check Group SID */
683 if (SecurityDescriptor->Group != NULL)
684 {
685 if ((ULONG_PTR)SecurityDescriptor->Group % sizeof(ULONG))
686 {
687 DPRINT1("Invalid Group SID alignment\n");
688 return FALSE;
689 }
690
691 Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Group);
692 if (Sid->Revision != SID_REVISION)
693 {
694 DPRINT1("Invalid Group SID revision\n");
695 return FALSE;
696 }
697
698 SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
699 if (Length < SdLength)
700 {
701 DPRINT1("Invalid Group SID size\n");
702 return FALSE;
703 }
704 }
705
706 /* Check DACL */
707 if (SecurityDescriptor->Dacl != NULL)
708 {
709 if ((ULONG_PTR)SecurityDescriptor->Dacl % sizeof(ULONG))
710 {
711 DPRINT1("Invalid DACL alignment\n");
712 return FALSE;
713 }
714
715 Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Dacl);
716 if ((Acl->AclRevision < MIN_ACL_REVISION) &&
717 (Acl->AclRevision > MAX_ACL_REVISION))
718 {
719 DPRINT1("Invalid DACL revision\n");
720 return FALSE;
721 }
722
723 SdLength += Acl->AclSize;
724 if (Length < SdLength)
725 {
726 DPRINT1("Invalid DACL size\n");
727 return FALSE;
728 }
729 }
730
731 /* Check SACL */
732 if (SecurityDescriptor->Sacl != NULL)
733 {
734 if ((ULONG_PTR)SecurityDescriptor->Sacl % sizeof(ULONG))
735 {
736 DPRINT1("Invalid SACL alignment\n");
737 return FALSE;
738 }
739
740 Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Sacl);
741 if ((Acl->AclRevision < MIN_ACL_REVISION) ||
742 (Acl->AclRevision > MAX_ACL_REVISION))
743 {
744 DPRINT1("Invalid SACL revision\n");
745 return FALSE;
746 }
747
748 SdLength += Acl->AclSize;
749 if (Length < SdLength)
750 {
751 DPRINT1("Invalid SACL size\n");
752 return FALSE;
753 }
754 }
755
756 return TRUE;
757 }
758
759 /* EOF */