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