Fix compiling. Thanks to filip.
[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(PSECURITY_DESCRIPTOR _AbsSD,
429 PSECURITY_DESCRIPTOR _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 PISECURITY_DESCRIPTOR AbsSD = (PISECURITY_DESCRIPTOR)_AbsSD;
443 PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)_RelSD;
444
445 PAGED_CODE_RTL();
446
447 RtlpQuerySecurityDescriptor(AbsSD,
448 &Owner,
449 &OwnerLength,
450 &Group,
451 &GroupLength,
452 &Dacl,
453 &DaclLength,
454 &Sacl,
455 &SaclLength);
456
457 TotalLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) + OwnerLength + GroupLength + SaclLength + DaclLength;
458 if (*BufferLength < TotalLength)
459 {
460 *BufferLength = TotalLength;
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 NTAPI
516 RtlAbsoluteToSelfRelativeSD(PISECURITY_DESCRIPTOR AbsSD,
517 PISECURITY_DESCRIPTOR 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, (PSECURITY_DESCRIPTOR)RelSD, BufferLength);
528 }
529
530
531 /*
532 * @implemented
533 */
534 NTSTATUS NTAPI
535 RtlGetControlSecurityDescriptor(PISECURITY_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 NTAPI
558 RtlSetControlSecurityDescriptor(IN PISECURITY_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 NTAPI
583 RtlGetSaclSecurityDescriptor(PISECURITY_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 NTAPI
618 RtlSetSaclSecurityDescriptor(PISECURITY_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 NTAPI
658 RtlSelfRelativeToAbsoluteSD(PISECURITY_DESCRIPTOR RelSD,
659 PISECURITY_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 (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 * @implemented
733 */
734 NTSTATUS NTAPI
735 RtlSelfRelativeToAbsoluteSD2(PISECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
736 PULONG BufferSize)
737 {
738 PISECURITY_DESCRIPTOR AbsSD = SelfRelativeSecurityDescriptor;
739 PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSecurityDescriptor;
740 #ifdef _WIN64
741 PVOID DataStart, DataEnd;
742 ULONG DataSize;
743 LONG MoveDelta;
744 ULONG OwnerLength;
745 ULONG GroupLength;
746 ULONG DaclLength;
747 ULONG SaclLength;
748 #endif
749 PSID pOwner;
750 PSID pGroup;
751 PACL pDacl;
752 PACL pSacl;
753
754 PAGED_CODE_RTL();
755
756 if (SelfRelativeSecurityDescriptor == NULL)
757 {
758 return STATUS_INVALID_PARAMETER_1;
759 }
760 if (BufferSize == NULL)
761 {
762 return STATUS_INVALID_PARAMETER_2;
763 }
764
765 if (RelSD->Revision != SECURITY_DESCRIPTOR_REVISION1)
766 {
767 return STATUS_UNKNOWN_REVISION;
768 }
769 if (!(RelSD->Control & SE_SELF_RELATIVE))
770 {
771 return STATUS_BAD_DESCRIPTOR_FORMAT;
772 }
773
774 ASSERT(FIELD_OFFSET(SECURITY_DESCRIPTOR, Owner) ==
775 FIELD_OFFSET(SECURITY_DESCRIPTOR_RELATIVE, Owner));
776
777 #ifdef _WIN64
778
779 RtlpQuerySecurityDescriptor(SelfRelativeSecurityDescriptor,
780 &pOwner,
781 &OwnerLength,
782 &pGroup,
783 &GroupLength,
784 &pDacl,
785 &DaclLength,
786 &pSacl,
787 &SaclLength);
788
789 ASSERT(sizeof(SECURITY_DESCRIPTOR) > sizeof(SECURITY_DESCRIPTOR_RELATIVE));
790
791 /* calculate the start and end of the data area, we simply just move the
792 data by the difference between the size of the relative and absolute
793 security descriptor structure */
794 DataStart = pOwner;
795 DataEnd = (PVOID)((ULONG_PTR)pOwner + OwnerLength);
796 if (pGroup != NULL)
797 {
798 if (((ULONG_PTR)pGroup < (ULONG_PTR)DataStart) || DataStart == NULL)
799 DataStart = pGroup;
800 if (((ULONG_PTR)pGroup + GroupLength > (ULONG_PTR)DataEnd) || DataEnd == NULL)
801 DataEnd = (PVOID)((ULONG_PTR)pGroup + GroupLength);
802 }
803 if (pDacl != NULL)
804 {
805 if (((ULONG_PTR)pDacl < (ULONG_PTR)DataStart) || DataStart == NULL)
806 DataStart = pDacl;
807 if (((ULONG_PTR)pDacl + DaclLength > (ULONG_PTR)DataEnd) || DataEnd == NULL)
808 DataEnd = (PVOID)((ULONG_PTR)pDacl + DaclLength);
809 }
810 if (pSacl != NULL)
811 {
812 if (((ULONG_PTR)pSacl < (ULONG_PTR)DataStart) || DataStart == NULL)
813 DataStart = pSacl;
814 if (((ULONG_PTR)pSacl + DaclLength > (ULONG_PTR)DataEnd) || DataEnd == NULL)
815 DataEnd = (PVOID)((ULONG_PTR)pSacl + SaclLength);
816 }
817
818 ASSERT((ULONG_PTR)DataEnd >= (ULONG_PTR)DataStart);
819
820 DataSize = (ULONG)((ULONG_PTR)DataEnd - (ULONG_PTR)DataStart);
821
822 if (*BufferSize < sizeof(SECURITY_DESCRIPTOR) + DataSize)
823 {
824 *BufferSize = sizeof(SECURITY_DESCRIPTOR) + DataSize;
825 return STATUS_BUFFER_TOO_SMALL;
826 }
827
828 if (DataSize != 0)
829 {
830 /* if DataSize != 0 ther must be at least one SID or ACL in the security
831 descriptor! Also the data area must be located somewhere after the
832 end of the SECURITY_DESCRIPTOR_RELATIVE structure */
833 ASSERT(DataStart != NULL);
834 ASSERT((ULONG_PTR)DataStart >= (ULONG_PTR)(RelSD + 1));
835
836 /* it's time to move the data */
837 RtlMoveMemory((PVOID)(AbsSD + 1),
838 DataStart,
839 DataSize);
840
841 MoveDelta = (LONG)((LONG_PTR)(AbsSD + 1) - (LONG_PTR)DataStart);
842
843 /* adjust the pointers if neccessary */
844 if (pOwner != NULL)
845 AbsSD->Owner = (PSID)((LONG_PTR)pOwner + MoveDelta);
846 else
847 AbsSD->Owner = NULL;
848
849 if (pGroup != NULL)
850 AbsSD->Group = (PSID)((LONG_PTR)pGroup + MoveDelta);
851 else
852 AbsSD->Group = NULL;
853
854 if (pSacl != NULL)
855 AbsSD->Sacl = (PACL)((LONG_PTR)pSacl + MoveDelta);
856 else
857 AbsSD->Sacl = NULL;
858
859 if (pDacl != NULL)
860 AbsSD->Dacl = (PACL)((LONG_PTR)pDacl + MoveDelta);
861 else
862 AbsSD->Dacl = NULL;
863 }
864 else
865 {
866 /* all pointers must be NULL! */
867 ASSERT(pOwner == NULL);
868 ASSERT(pGroup == NULL);
869 ASSERT(pSacl == NULL);
870 ASSERT(pDacl == NULL);
871
872 AbsSD->Owner = NULL;
873 AbsSD->Group = NULL;
874 AbsSD->Sacl = NULL;
875 AbsSD->Dacl = NULL;
876 }
877
878 /* clear the self-relative flag */
879 AbsSD->Control &= ~SE_SELF_RELATIVE;
880
881 #else
882
883 RtlpQuerySecurityDescriptorPointers(SelfRelativeSecurityDescriptor,
884 &pOwner,
885 &pGroup,
886 &pSacl,
887 &pDacl);
888
889 ASSERT(sizeof(SECURITY_DESCRIPTOR) == sizeof(SECURITY_DESCRIPTOR_RELATIVE));
890
891 /* clear the self-relative flag and simply convert the offsets to pointers */
892 AbsSD->Control &= ~SE_SELF_RELATIVE;
893 AbsSD->Owner = pOwner;
894 AbsSD->Group = pGroup;
895 AbsSD->Sacl = pSacl;
896 AbsSD->Dacl = pDacl;
897
898 #endif
899
900 return STATUS_SUCCESS;
901 }
902
903
904 /*
905 * @implemented
906 */
907 BOOLEAN NTAPI
908 RtlValidRelativeSecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptorInput,
909 IN ULONG SecurityDescriptorLength,
910 IN SECURITY_INFORMATION RequiredInformation)
911 {
912 PAGED_CODE_RTL();
913
914 if (SecurityDescriptorLength < sizeof(SECURITY_DESCRIPTOR_RELATIVE) ||
915 SecurityDescriptorInput->Revision != SECURITY_DESCRIPTOR_REVISION1 ||
916 !(SecurityDescriptorInput->Control & SE_SELF_RELATIVE))
917 {
918 return FALSE;
919 }
920
921 if (SecurityDescriptorInput->Owner != 0)
922 {
923 PSID Owner = (PSID)((ULONG_PTR)SecurityDescriptorInput->Owner + (ULONG_PTR)SecurityDescriptorInput);
924 if (!RtlValidSid(Owner))
925 {
926 return FALSE;
927 }
928 }
929 else if (RequiredInformation & OWNER_SECURITY_INFORMATION)
930 {
931 return FALSE;
932 }
933
934 if (SecurityDescriptorInput->Group != 0)
935 {
936 PSID Group = (PSID)((ULONG_PTR)SecurityDescriptorInput->Group + (ULONG_PTR)SecurityDescriptorInput);
937 if (!RtlValidSid(Group))
938 {
939 return FALSE;
940 }
941 }
942 else if (RequiredInformation & GROUP_SECURITY_INFORMATION)
943 {
944 return FALSE;
945 }
946
947 if (SecurityDescriptorInput->Control & SE_DACL_PRESENT)
948 {
949 if (SecurityDescriptorInput->Dacl != 0 &&
950 !RtlValidAcl((PACL)((ULONG_PTR)SecurityDescriptorInput->Dacl + (ULONG_PTR)SecurityDescriptorInput)))
951 {
952 return FALSE;
953 }
954 }
955 else if (RequiredInformation & DACL_SECURITY_INFORMATION)
956 {
957 return FALSE;
958 }
959
960 if (SecurityDescriptorInput->Control & SE_SACL_PRESENT)
961 {
962 if (SecurityDescriptorInput->Sacl != 0 &&
963 !RtlValidAcl((PACL)((ULONG_PTR)SecurityDescriptorInput->Sacl + (ULONG_PTR)SecurityDescriptorInput)))
964 {
965 return FALSE;
966 }
967 }
968 else if (RequiredInformation & SACL_SECURITY_INFORMATION)
969 {
970 return FALSE;
971 }
972
973 return TRUE;
974 }
975
976
977 /*
978 * @implemented
979 */
980 BOOLEAN NTAPI
981 RtlGetSecurityDescriptorRMControl(PISECURITY_DESCRIPTOR SecurityDescriptor,
982 PUCHAR RMControl)
983 {
984 PAGED_CODE_RTL();
985
986 if (!(SecurityDescriptor->Control & SE_RM_CONTROL_VALID))
987 {
988 *RMControl = 0;
989 return FALSE;
990 }
991
992 *RMControl = SecurityDescriptor->Sbz1;
993
994 return TRUE;
995 }
996
997
998 /*
999 * @implemented
1000 */
1001 VOID NTAPI
1002 RtlSetSecurityDescriptorRMControl(PISECURITY_DESCRIPTOR SecurityDescriptor,
1003 PUCHAR RMControl)
1004 {
1005 PAGED_CODE_RTL();
1006
1007 if (RMControl == NULL)
1008 {
1009 SecurityDescriptor->Control &= ~SE_RM_CONTROL_VALID;
1010 SecurityDescriptor->Sbz1 = 0;
1011 }
1012 else
1013 {
1014 SecurityDescriptor->Control |= SE_RM_CONTROL_VALID;
1015 SecurityDescriptor->Sbz1 = *RMControl;
1016 }
1017 }
1018
1019
1020 /*
1021 * @implemented
1022 */
1023 NTSTATUS NTAPI
1024 RtlSetAttributesSecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptor,
1025 IN SECURITY_DESCRIPTOR_CONTROL Control,
1026 OUT PULONG Revision)
1027 {
1028 PAGED_CODE_RTL();
1029
1030 *Revision = SecurityDescriptor->Revision;
1031
1032 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
1033 return STATUS_UNKNOWN_REVISION;
1034
1035 Control &=
1036 ~(SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED | SE_DACL_PRESENT |
1037 SE_DACL_DEFAULTED | SE_SACL_PRESENT | SE_SACL_DEFAULTED |
1038 SE_RM_CONTROL_VALID | SE_SELF_RELATIVE);
1039
1040 return RtlSetControlSecurityDescriptor(SecurityDescriptor,
1041 Control,
1042 Control);
1043 }
1044
1045 /* EOF */