implement MakeAbsoluteSD2 by forwarding to RtlSelfRelativeToAbsoluteSD2
[reactos.git] / reactos / lib / rtl / sd.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * PURPOSE: Security descriptor functions
5 * FILE: lib/rtl/sd.c
6 * PROGRAMER: David Welch <welch@cwcom.net>
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <rtl.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS ***************************************************************/
17
18
19 static VOID
20 RtlpQuerySecurityDescriptorPointers(IN PISECURITY_DESCRIPTOR SecurityDescriptor,
21 OUT PSID *Owner OPTIONAL,
22 OUT PSID *Group OPTIONAL,
23 OUT PACL *Sacl OPTIONAL,
24 OUT PACL *Dacl OPTIONAL)
25 {
26 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
27 {
28 PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
29 if(Owner != NULL)
30 {
31 *Owner = ((RelSD->Owner != 0) ? (PSID)((ULONG_PTR)RelSD + RelSD->Owner) : NULL);
32 }
33 if(Group != NULL)
34 {
35 *Group = ((RelSD->Group != 0) ? (PSID)((ULONG_PTR)RelSD + RelSD->Group) : NULL);
36 }
37 if(Sacl != NULL)
38 {
39 *Sacl = (((RelSD->Control & SE_SACL_PRESENT) && (RelSD->Sacl != 0)) ?
40 (PSID)((ULONG_PTR)RelSD + RelSD->Sacl) : NULL);
41 }
42 if(Dacl != NULL)
43 {
44 *Dacl = (((RelSD->Control & SE_DACL_PRESENT) && (RelSD->Dacl != 0)) ?
45 (PSID)((ULONG_PTR)RelSD + RelSD->Dacl) : NULL);
46 }
47 }
48 else
49 {
50 if(Owner != NULL)
51 {
52 *Owner = SecurityDescriptor->Owner;
53 }
54 if(Group != NULL)
55 {
56 *Group = SecurityDescriptor->Group;
57 }
58 if(Sacl != NULL)
59 {
60 *Sacl = ((SecurityDescriptor->Control & SE_SACL_PRESENT) ? SecurityDescriptor->Sacl : NULL);
61 }
62 if(Dacl != NULL)
63 {
64 *Dacl = ((SecurityDescriptor->Control & SE_DACL_PRESENT) ? SecurityDescriptor->Dacl : NULL);
65 }
66 }
67 }
68
69 static VOID
70 RtlpQuerySecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
71 PSID* Owner,
72 PULONG OwnerLength,
73 PSID* Group,
74 PULONG GroupLength,
75 PACL* Dacl,
76 PULONG DaclLength,
77 PACL* Sacl,
78 PULONG SaclLength)
79 {
80 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
81 Owner,
82 Group,
83 Sacl,
84 Dacl);
85
86 if (Owner != NULL)
87 {
88 *OwnerLength = ((*Owner != NULL) ? ROUND_UP(RtlLengthSid(*Owner), 4) : 0);
89 }
90
91 if (Group != NULL)
92 {
93 *GroupLength = ((*Group != NULL) ? ROUND_UP(RtlLengthSid(*Group), 4) : 0);
94 }
95
96 if (Dacl != NULL)
97 {
98 *DaclLength = ((*Dacl != NULL) ? ROUND_UP((*Dacl)->AclSize, 4) : 0);
99 }
100
101 if (Sacl != NULL)
102 {
103 *SaclLength = ((*Sacl != NULL) ? ROUND_UP((*Sacl)->AclSize, 4) : 0);
104 }
105 }
106
107 /*
108 * @implemented
109 */
110 NTSTATUS NTAPI
111 RtlCreateSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
112 ULONG Revision)
113 {
114 PAGED_CODE_RTL();
115
116 if (Revision != SECURITY_DESCRIPTOR_REVISION1)
117 {
118 return STATUS_UNKNOWN_REVISION;
119 }
120
121 SecurityDescriptor->Revision = Revision;
122 SecurityDescriptor->Sbz1 = 0;
123 SecurityDescriptor->Control = 0;
124 SecurityDescriptor->Owner = NULL;
125 SecurityDescriptor->Group = NULL;
126 SecurityDescriptor->Sacl = NULL;
127 SecurityDescriptor->Dacl = NULL;
128
129 return STATUS_SUCCESS;
130 }
131
132
133 NTSTATUS NTAPI
134 RtlCreateSecurityDescriptorRelative (PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor,
135 ULONG Revision)
136 {
137 PAGED_CODE_RTL();
138
139 if (Revision != SECURITY_DESCRIPTOR_REVISION1)
140 {
141 return STATUS_UNKNOWN_REVISION;
142 }
143
144 SecurityDescriptor->Revision = Revision;
145 SecurityDescriptor->Sbz1 = 0;
146 SecurityDescriptor->Control = SE_SELF_RELATIVE;
147 SecurityDescriptor->Owner = 0;
148 SecurityDescriptor->Group = 0;
149 SecurityDescriptor->Sacl = 0;
150 SecurityDescriptor->Dacl = 0;
151
152 return STATUS_SUCCESS;
153 }
154
155
156 /*
157 * @implemented
158 */
159 ULONG NTAPI
160 RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
161 {
162 PSID Owner, Group;
163 PACL Sacl, Dacl;
164 ULONG Length = sizeof(SECURITY_DESCRIPTOR);
165
166 PAGED_CODE_RTL();
167
168 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
169 &Owner,
170 &Group,
171 &Sacl,
172 &Dacl);
173
174 if (Owner != NULL)
175 {
176 Length += ROUND_UP(RtlLengthSid(Owner), 4);
177 }
178
179 if (Group != NULL)
180 {
181 Length += ROUND_UP(RtlLengthSid(Group), 4);
182 }
183
184 if (Dacl != NULL)
185 {
186 Length += ROUND_UP(Dacl->AclSize, 4);
187 }
188
189 if (Sacl != NULL)
190 {
191 Length += ROUND_UP(Sacl->AclSize, 4);
192 }
193
194 return Length;
195 }
196
197
198 /*
199 * @implemented
200 */
201 NTSTATUS NTAPI
202 RtlGetDaclSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
203 PBOOLEAN DaclPresent,
204 PACL* Dacl,
205 PBOOLEAN DaclDefaulted)
206 {
207 PAGED_CODE_RTL();
208
209 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
210 {
211 return STATUS_UNKNOWN_REVISION;
212 }
213
214 if (!(SecurityDescriptor->Control & SE_DACL_PRESENT))
215 {
216 *DaclPresent = FALSE;
217 return STATUS_SUCCESS;
218 }
219 *DaclPresent = TRUE;
220
221 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
222 NULL,
223 NULL,
224 NULL,
225 Dacl);
226
227 *DaclDefaulted = ((SecurityDescriptor->Control & SE_DACL_DEFAULTED) ? TRUE : FALSE);
228
229 return STATUS_SUCCESS;
230 }
231
232
233 /*
234 * @implemented
235 */
236 NTSTATUS NTAPI
237 RtlSetDaclSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
238 BOOLEAN DaclPresent,
239 PACL Dacl,
240 BOOLEAN DaclDefaulted)
241 {
242 PAGED_CODE_RTL();
243
244 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
245 {
246 return STATUS_UNKNOWN_REVISION;
247 }
248
249 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
250 {
251 return STATUS_BAD_DESCRIPTOR_FORMAT;
252 }
253
254 if (!DaclPresent)
255 {
256 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_PRESENT);
257 return STATUS_SUCCESS;
258 }
259
260 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_PRESENT;
261 SecurityDescriptor->Dacl = Dacl;
262 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_DEFAULTED);
263
264 if (DaclDefaulted)
265 {
266 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_DEFAULTED;
267 }
268
269 return STATUS_SUCCESS;
270 }
271
272
273 /*
274 * @implemented
275 */
276 BOOLEAN NTAPI
277 RtlValidSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor)
278 {
279 PSID Owner, Group;
280 PACL Sacl, Dacl;
281
282 PAGED_CODE_RTL();
283
284 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
285 {
286 return FALSE;
287 }
288
289 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
290 &Owner,
291 &Group,
292 &Sacl,
293 &Dacl);
294
295 if ((Owner != NULL && !RtlValidSid(Owner)) ||
296 (Group != NULL && !RtlValidSid(Group)) ||
297 (Sacl != NULL && !RtlValidAcl(Sacl)) ||
298 (Dacl != NULL && !RtlValidAcl(Dacl)))
299 {
300 return FALSE;
301 }
302
303 return TRUE;
304 }
305
306
307 /*
308 * @implemented
309 */
310 NTSTATUS NTAPI
311 RtlSetOwnerSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
312 PSID Owner,
313 BOOLEAN OwnerDefaulted)
314 {
315 PAGED_CODE_RTL();
316
317 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
318 {
319 return STATUS_UNKNOWN_REVISION;
320 }
321
322 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
323 {
324 return STATUS_BAD_DESCRIPTOR_FORMAT;
325 }
326
327 SecurityDescriptor->Owner = Owner;
328 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_OWNER_DEFAULTED);
329
330 if (OwnerDefaulted)
331 {
332 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_OWNER_DEFAULTED;
333 }
334
335 return STATUS_SUCCESS;
336 }
337
338
339 /*
340 * @implemented
341 */
342 NTSTATUS NTAPI
343 RtlGetOwnerSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
344 PSID* Owner,
345 PBOOLEAN OwnerDefaulted)
346 {
347 PAGED_CODE_RTL();
348
349 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
350 {
351 return STATUS_UNKNOWN_REVISION;
352 }
353
354 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
355 Owner,
356 NULL,
357 NULL,
358 NULL);
359
360 *OwnerDefaulted = ((SecurityDescriptor->Control & SE_OWNER_DEFAULTED) ? TRUE : FALSE);
361
362 return STATUS_SUCCESS;
363 }
364
365
366 /*
367 * @implemented
368 */
369 NTSTATUS NTAPI
370 RtlSetGroupSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
371 PSID Group,
372 BOOLEAN GroupDefaulted)
373 {
374 PAGED_CODE_RTL();
375
376 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
377 {
378 return STATUS_UNKNOWN_REVISION;
379 }
380
381 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
382 {
383 return STATUS_BAD_DESCRIPTOR_FORMAT;
384 }
385
386 SecurityDescriptor->Group = Group;
387 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_GROUP_DEFAULTED);
388 if (GroupDefaulted)
389 {
390 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_GROUP_DEFAULTED;
391 }
392
393 return STATUS_SUCCESS;
394 }
395
396
397 /*
398 * @implemented
399 */
400 NTSTATUS NTAPI
401 RtlGetGroupSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
402 PSID* Group,
403 PBOOLEAN GroupDefaulted)
404 {
405 PAGED_CODE_RTL();
406
407 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
408 {
409 return STATUS_UNKNOWN_REVISION;
410 }
411
412 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
413 NULL,
414 Group,
415 NULL,
416 NULL);
417
418 *GroupDefaulted = ((SecurityDescriptor->Control & SE_GROUP_DEFAULTED) ? TRUE : FALSE);
419
420 return STATUS_SUCCESS;
421 }
422
423
424 /*
425 * @implemented
426 */
427 NTSTATUS NTAPI
428 RtlMakeSelfRelativeSD(PISECURITY_DESCRIPTOR AbsSD,
429 PISECURITY_DESCRIPTOR_RELATIVE RelSD,
430 PULONG BufferLength)
431 {
432 PSID Owner;
433 PSID Group;
434 PACL Sacl;
435 PACL Dacl;
436 ULONG OwnerLength;
437 ULONG GroupLength;
438 ULONG SaclLength;
439 ULONG DaclLength;
440 ULONG TotalLength;
441 ULONG_PTR Current;
442
443 PAGED_CODE_RTL();
444
445 RtlpQuerySecurityDescriptor(AbsSD,
446 &Owner,
447 &OwnerLength,
448 &Group,
449 &GroupLength,
450 &Dacl,
451 &DaclLength,
452 &Sacl,
453 &SaclLength);
454
455 TotalLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) + OwnerLength + GroupLength + SaclLength + DaclLength;
456 if (*BufferLength < TotalLength)
457 {
458 return STATUS_BUFFER_TOO_SMALL;
459 }
460
461 RtlZeroMemory(RelSD,
462 TotalLength);
463
464 RelSD->Revision = AbsSD->Revision;
465 RelSD->Sbz1 = AbsSD->Sbz1;
466 RelSD->Control = AbsSD->Control | SE_SELF_RELATIVE;
467
468 Current = (ULONG_PTR)(RelSD + 1);
469
470 if (SaclLength != 0)
471 {
472 RtlCopyMemory((PVOID)Current,
473 Sacl,
474 SaclLength);
475 RelSD->Sacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
476 Current += SaclLength;
477 }
478
479 if (DaclLength != 0)
480 {
481 RtlCopyMemory((PVOID)Current,
482 Dacl,
483 DaclLength);
484 RelSD->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
485 Current += DaclLength;
486 }
487
488 if (OwnerLength != 0)
489 {
490 RtlCopyMemory((PVOID)Current,
491 Owner,
492 OwnerLength);
493 RelSD->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
494 Current += OwnerLength;
495 }
496
497 if (GroupLength != 0)
498 {
499 RtlCopyMemory((PVOID)Current,
500 Group,
501 GroupLength);
502 RelSD->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)RelSD);
503 }
504
505 return STATUS_SUCCESS;
506 }
507
508
509 /*
510 * @implemented
511 */
512 NTSTATUS NTAPI
513 RtlAbsoluteToSelfRelativeSD(PISECURITY_DESCRIPTOR AbsSD,
514 PISECURITY_DESCRIPTOR RelSD,
515 PULONG BufferLength)
516 {
517 PAGED_CODE_RTL();
518
519 if (AbsSD->Control & SE_SELF_RELATIVE)
520 {
521 return STATUS_BAD_DESCRIPTOR_FORMAT;
522 }
523
524 return RtlMakeSelfRelativeSD(AbsSD, (PISECURITY_DESCRIPTOR_RELATIVE)RelSD, BufferLength);
525 }
526
527
528 /*
529 * @implemented
530 */
531 NTSTATUS NTAPI
532 RtlGetControlSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
533 PSECURITY_DESCRIPTOR_CONTROL Control,
534 PULONG Revision)
535 {
536 PAGED_CODE_RTL();
537
538 *Revision = SecurityDescriptor->Revision;
539
540 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
541 {
542 return STATUS_UNKNOWN_REVISION;
543 }
544
545 *Control = SecurityDescriptor->Control;
546
547 return STATUS_SUCCESS;
548 }
549
550
551 /*
552 * @implemented
553 */
554 NTSTATUS NTAPI
555 RtlSetControlSecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptor,
556 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
557 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet)
558 {
559 PAGED_CODE_RTL();
560
561 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
562 {
563 return STATUS_UNKNOWN_REVISION;
564 }
565
566 /* Zero the 'bits of interest' */
567 SecurityDescriptor->Control &= ~ControlBitsOfInterest;
568
569 /* Set the 'bits to set' */
570 SecurityDescriptor->Control |= (ControlBitsToSet & ControlBitsOfInterest);
571
572 return STATUS_SUCCESS;
573 }
574
575
576 /*
577 * @implemented
578 */
579 NTSTATUS NTAPI
580 RtlGetSaclSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
581 PBOOLEAN SaclPresent,
582 PACL *Sacl,
583 PBOOLEAN SaclDefaulted)
584 {
585 PAGED_CODE_RTL();
586
587 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
588 {
589 return STATUS_UNKNOWN_REVISION;
590 }
591
592 if (!(SecurityDescriptor->Control & SE_SACL_PRESENT))
593 {
594 *SaclPresent = FALSE;
595 return STATUS_SUCCESS;
596 }
597 *SaclPresent = TRUE;
598
599 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor,
600 NULL,
601 NULL,
602 Sacl,
603 NULL);
604
605 *SaclDefaulted = ((SecurityDescriptor->Control & SE_SACL_DEFAULTED) ? TRUE : FALSE);
606
607 return STATUS_SUCCESS;
608 }
609
610
611 /*
612 * @implemented
613 */
614 NTSTATUS NTAPI
615 RtlSetSaclSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor,
616 BOOLEAN SaclPresent,
617 PACL Sacl,
618 BOOLEAN SaclDefaulted)
619 {
620 PAGED_CODE_RTL();
621
622 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
623 {
624 return STATUS_UNKNOWN_REVISION;
625 }
626
627 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
628 {
629 return STATUS_BAD_DESCRIPTOR_FORMAT;
630 }
631
632 if (!SaclPresent)
633 {
634 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_PRESENT);
635 return STATUS_SUCCESS;
636 }
637
638 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_PRESENT;
639 SecurityDescriptor->Sacl = Sacl;
640 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_DEFAULTED);
641
642 if (SaclDefaulted)
643 {
644 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_DEFAULTED;
645 }
646
647 return STATUS_SUCCESS;
648 }
649
650
651 /*
652 * @implemented
653 */
654 NTSTATUS NTAPI
655 RtlSelfRelativeToAbsoluteSD(PISECURITY_DESCRIPTOR RelSD,
656 PISECURITY_DESCRIPTOR AbsSD,
657 PDWORD AbsSDSize,
658 PACL Dacl,
659 PDWORD DaclSize,
660 PACL Sacl,
661 PDWORD SaclSize,
662 PSID Owner,
663 PDWORD OwnerSize,
664 PSID Group,
665 PDWORD GroupSize)
666 {
667 ULONG OwnerLength;
668 ULONG GroupLength;
669 ULONG DaclLength;
670 ULONG SaclLength;
671 PSID pOwner;
672 PSID pGroup;
673 PACL pDacl;
674 PACL pSacl;
675
676 PAGED_CODE_RTL();
677
678 if (RelSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
679 {
680 return STATUS_UNKNOWN_REVISION;
681 }
682
683 if (!(RelSD->Control & SE_SELF_RELATIVE))
684 {
685 return STATUS_BAD_DESCRIPTOR_FORMAT;
686 }
687
688 RtlpQuerySecurityDescriptor (RelSD,
689 &pOwner,
690 &OwnerLength,
691 &pGroup,
692 &GroupLength,
693 &pDacl,
694 &DaclLength,
695 &pSacl,
696 &SaclLength);
697
698 if (OwnerLength > *OwnerSize ||
699 GroupLength > *GroupSize ||
700 DaclLength > *DaclSize ||
701 SaclLength > *SaclSize)
702 {
703 return STATUS_BUFFER_TOO_SMALL;
704 }
705
706 RtlCopyMemory (Owner, pOwner, OwnerLength);
707 RtlCopyMemory (Group, pGroup, GroupLength);
708 RtlCopyMemory (Dacl, pDacl, DaclLength);
709 RtlCopyMemory (Sacl, pSacl, SaclLength);
710
711 AbsSD->Revision = RelSD->Revision;
712 AbsSD->Sbz1 = RelSD->Sbz1;
713 AbsSD->Control = RelSD->Control & ~SE_SELF_RELATIVE;
714 AbsSD->Owner = Owner;
715 AbsSD->Group = Group;
716 AbsSD->Dacl = Dacl;
717 AbsSD->Sacl = Sacl;
718
719 *OwnerSize = OwnerLength;
720 *GroupSize = GroupLength;
721 *DaclSize = DaclLength;
722 *SaclSize = SaclLength;
723
724 return STATUS_SUCCESS;
725 }
726
727
728 /*
729 * @unimplemented
730 */
731 NTSTATUS NTAPI
732 RtlSelfRelativeToAbsoluteSD2(PISECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
733 PULONG BufferSize)
734 {
735 UNIMPLEMENTED;
736 return STATUS_NOT_IMPLEMENTED;
737 }
738
739
740 /*
741 * @implemented
742 */
743 BOOLEAN NTAPI
744 RtlValidRelativeSecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptorInput,
745 IN ULONG SecurityDescriptorLength,
746 IN SECURITY_INFORMATION RequiredInformation)
747 {
748 PAGED_CODE_RTL();
749
750 if (SecurityDescriptorLength < sizeof(SECURITY_DESCRIPTOR_RELATIVE) ||
751 SecurityDescriptorInput->Revision != SECURITY_DESCRIPTOR_REVISION1 ||
752 !(SecurityDescriptorInput->Control & SE_SELF_RELATIVE))
753 {
754 return FALSE;
755 }
756
757 if (SecurityDescriptorInput->Owner != 0)
758 {
759 PSID Owner = (PSID)((ULONG_PTR)SecurityDescriptorInput->Owner + (ULONG_PTR)SecurityDescriptorInput);
760 if (!RtlValidSid(Owner))
761 {
762 return FALSE;
763 }
764 }
765 else if (RequiredInformation & OWNER_SECURITY_INFORMATION)
766 {
767 return FALSE;
768 }
769
770 if (SecurityDescriptorInput->Group != 0)
771 {
772 PSID Group = (PSID)((ULONG_PTR)SecurityDescriptorInput->Group + (ULONG_PTR)SecurityDescriptorInput);
773 if (!RtlValidSid(Group))
774 {
775 return FALSE;
776 }
777 }
778 else if (RequiredInformation & GROUP_SECURITY_INFORMATION)
779 {
780 return FALSE;
781 }
782
783 if (SecurityDescriptorInput->Control & SE_DACL_PRESENT)
784 {
785 if (SecurityDescriptorInput->Dacl != 0 &&
786 !RtlValidAcl((PACL)((ULONG_PTR)SecurityDescriptorInput->Dacl + (ULONG_PTR)SecurityDescriptorInput)))
787 {
788 return FALSE;
789 }
790 }
791 else if (RequiredInformation & DACL_SECURITY_INFORMATION)
792 {
793 return FALSE;
794 }
795
796 if (SecurityDescriptorInput->Control & SE_SACL_PRESENT)
797 {
798 if (SecurityDescriptorInput->Sacl != 0 &&
799 !RtlValidAcl((PACL)((ULONG_PTR)SecurityDescriptorInput->Sacl + (ULONG_PTR)SecurityDescriptorInput)))
800 {
801 return FALSE;
802 }
803 }
804 else if (RequiredInformation & SACL_SECURITY_INFORMATION)
805 {
806 return FALSE;
807 }
808
809 return TRUE;
810 }
811
812
813 /*
814 * @implemented
815 */
816 BOOLEAN NTAPI
817 RtlGetSecurityDescriptorRMControl(PISECURITY_DESCRIPTOR SecurityDescriptor,
818 PUCHAR RMControl)
819 {
820 PAGED_CODE_RTL();
821
822 if (!(SecurityDescriptor->Control & SE_RM_CONTROL_VALID))
823 {
824 *RMControl = 0;
825 return FALSE;
826 }
827
828 *RMControl = SecurityDescriptor->Sbz1;
829
830 return TRUE;
831 }
832
833
834 /*
835 * @implemented
836 */
837 VOID NTAPI
838 RtlSetSecurityDescriptorRMControl(PISECURITY_DESCRIPTOR SecurityDescriptor,
839 PUCHAR RMControl)
840 {
841 PAGED_CODE_RTL();
842
843 if (RMControl == NULL)
844 {
845 SecurityDescriptor->Control &= ~SE_RM_CONTROL_VALID;
846 SecurityDescriptor->Sbz1 = 0;
847 }
848 else
849 {
850 SecurityDescriptor->Control |= SE_RM_CONTROL_VALID;
851 SecurityDescriptor->Sbz1 = *RMControl;
852 }
853 }
854
855
856 /*
857 * @implemented
858 */
859 NTSTATUS NTAPI
860 RtlSetAttributesSecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptor,
861 IN SECURITY_DESCRIPTOR_CONTROL Control,
862 OUT PULONG Revision)
863 {
864 PAGED_CODE_RTL();
865
866 *Revision = SecurityDescriptor->Revision;
867
868 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
869 return STATUS_UNKNOWN_REVISION;
870
871 Control &=
872 ~(SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED | SE_DACL_PRESENT |
873 SE_DACL_DEFAULTED | SE_SACL_PRESENT | SE_SACL_DEFAULTED |
874 SE_RM_CONTROL_VALID | SE_SELF_RELATIVE);
875
876 return RtlSetControlSecurityDescriptor(SecurityDescriptor,
877 Control,
878 Control);
879 }
880
881 /* EOF */