ReactOS 0.4.15-dev-6055-g36cdd34
sd.c
Go to the documentation of this file.
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#include "../../ntoskrnl/include/internal/se.h"
13#define NDEBUG
14#include <debug.h>
15
16/* PRIVATE FUNCTIONS **********************************************************/
17
22 IN ULONG MinLength,
23 OUT PULONG MaxLength)
24{
25 /* Assume failure */
26 *MaxLength = 0;
27
28 /* Reject out of bounds lengths */
29 if (Offset < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) return FALSE;
30 if (Offset >= Length) return FALSE;
31
32 /* Reject insufficient lengths */
33 if ((Length - Offset) < MinLength) return FALSE;
34
35 /* Reject unaligned offsets */
36 if (ALIGN_DOWN(Offset, ULONG) != Offset) return FALSE;
37
38 /* Return length that is safe to read */
39 *MaxLength = Length - Offset;
40 return TRUE;
41}
42
43VOID
46 OUT PSID *Owner,
50 OUT PACL *Dacl,
52 OUT PACL *Sacl,
54{
56
57 /* Get the owner */
59 if (*Owner)
60 {
61 /* There's an owner, so align the size */
63 }
64 else
65 {
66 /* No owner, no size */
67 *OwnerSize = 0;
68 }
69
70 /* Get the group */
72 if (*PrimaryGroup)
73 {
74 /* There's a group, so align the size */
76 }
77 else
78 {
79 /* No group, no size */
81 }
82
83 /* Get the DACL */
85 if (*Dacl)
86 {
87 /* There's a DACL, align the size */
88 *DaclSize = ROUND_UP((*Dacl)->AclSize, sizeof(ULONG));
89 }
90 else
91 {
92 /* No DACL, no size */
93 *DaclSize = 0;
94 }
95
96 /* Get the SACL */
98 if (*Sacl)
99 {
100 /* There's a SACL, align the size */
101 *SaclSize = ROUND_UP((*Sacl)->AclSize, sizeof(ULONG));
102 }
103 else
104 {
105 /* No SACL, no size */
106 *SaclSize = 0;
107 }
108}
109
110/* PUBLIC FUNCTIONS ***********************************************************/
111
112/*
113 * @implemented
114 */
116NTAPI
119{
122
123 /* Fail on invalid revisions */
125
126 /* Setup an empty SD */
127 RtlZeroMemory(Sd, sizeof(*Sd));
129
130 /* All good */
131 return STATUS_SUCCESS;
132}
133
134/*
135 * @implemented
136 */
138NTAPI
141{
143
144 /* Fail on invalid revisions */
146
147 /* Setup an empty SD */
151
152 /* All good */
153 return STATUS_SUCCESS;
154}
155
156/*
157 * @implemented
158 */
159ULONG
160NTAPI
162{
165 PACL Sacl, Dacl;
168
169 /* Start with the initial length of the SD itself */
171 if (Sd->Control & SE_SELF_RELATIVE)
172 {
174 }
175 else
176 {
177 Length = sizeof(SECURITY_DESCRIPTOR);
178 }
179
180 /* Add the length of the individual subcomponents */
182 if (Owner) Length += ROUND_UP(RtlLengthSid(Owner), sizeof(ULONG));
184 if (Group) Length += ROUND_UP(RtlLengthSid(Group), sizeof(ULONG));
186 if (Dacl) Length += ROUND_UP(Dacl->AclSize, sizeof(ULONG));
188 if (Sacl) Length += ROUND_UP(Sacl->AclSize, sizeof(ULONG));
189
190 /* Return the final length */
191 return Length;
192}
193
194/*
195 * @implemented
196 */
198NTAPI
201 OUT PACL* Dacl,
203{
206
207 /* Fail on invalid revisions */
209
210 /* Is there a DACL? */
212 if (*DaclPresent)
213 {
214 /* Yes, return it, and check if defaulted */
217 }
218
219 /* All good */
220 return STATUS_SUCCESS;
221}
222
223/*
224 * @implemented
225 */
227NTAPI
230 OUT PACL* Sacl,
232{
235
236 /* Fail on invalid revisions */
238
239 /* Is there a SACL? */
241 if (*SaclPresent)
242 {
243 /* Yes, return it, and check if defaulted */
246 }
247
248 /* All good */
249 return STATUS_SUCCESS;
250}
251
252/*
253 * @implemented
254 */
256NTAPI
258 OUT PSID* Owner,
260{
263
264 /* Fail on invalid revision */
266
267 /* Get the owner and if defaulted */
270
271 /* All good */
272 return STATUS_SUCCESS;
273}
274
275/*
276 * @implemented
277 */
279NTAPI
281 OUT PSID* Group,
283{
286
287 /* Fail on invalid revision */
289
290 /* Get the group and if defaulted */
293
294 /* All good */
295 return STATUS_SUCCESS;
296}
297
298/*
299 * @implemented
300 */
302NTAPI
305 IN PACL Dacl,
307{
310
311 /* Fail on invalid revision */
313
314 /* Fail on relative descriptors */
316
317 /* Is there a DACL? */
318 if (!DaclPresent)
319 {
320 /* Caller is destroying the DACL, unset the flag and we're done */
321 Sd->Control = Sd->Control & ~SE_DACL_PRESENT;
322 return STATUS_SUCCESS;
323 }
324
325 /* Caller is setting a new DACL, set the pointer and flag */
326 Sd->Dacl = Dacl;
328
329 /* Set if defaulted */
330 Sd->Control &= ~SE_DACL_DEFAULTED;
332
333 /* All good */
334 return STATUS_SUCCESS;
335}
336
337/*
338 * @implemented
339 */
341NTAPI
344 IN PACL Sacl,
346{
349
350 /* Fail on invalid revision */
352
353 /* Fail on relative descriptors */
355
356 /* Is there a SACL? */
357 if (!SaclPresent)
358 {
359 /* Caller is clearing the SACL, unset the flag and we're done */
360 Sd->Control = Sd->Control & ~SE_SACL_PRESENT;
361 return STATUS_SUCCESS;
362 }
363
364 /* Caller is setting a new SACL, set it and the flag */
365 Sd->Sacl = Sacl;
367
368 /* Set if defaulted */
369 Sd->Control &= ~SE_SACL_DEFAULTED;
371
372 /* All good */
373 return STATUS_SUCCESS;
374}
375
376/*
377 * @implemented
378 */
380NTAPI
382 IN PSID Owner,
384{
387
388 /* Fail on invalid revision */
390
391 /* Fail on relative descriptors */
393
394 /* Owner being set or cleared */
395 Sd->Owner = Owner;
396
397 /* Set if defaulted */
398 Sd->Control &= ~SE_OWNER_DEFAULTED;
400
401 /* All good */
402 return STATUS_SUCCESS;
403}
404
405/*
406 * @implemented
407 */
409NTAPI
411 IN PSID Group,
413{
416
417 /* Fail on invalid revision */
419
420 /* Fail on relative descriptors */
422
423 /* Group being set or cleared */
424 Sd->Group = Group;
425
426 /* Set if defaulted */
427 Sd->Control &= ~SE_GROUP_DEFAULTED;
429
430 /* All good */
431 return STATUS_SUCCESS;
432}
433
434/*
435 * @implemented
436 */
438NTAPI
442{
445
446 /* Read current revision, even if invalid */
447 *Revision = Sd->Revision;
448
449 /* Fail on invalid revision */
451
452 /* Read current control */
453 *Control = Sd->Control;
454
455 /* All good */
456 return STATUS_SUCCESS;
457}
458
459/*
460 * @implemented
461 */
463NTAPI
465 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
466 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet)
467{
469
470 /* Check for invalid bits */
471 if ((ControlBitsOfInterest & ~(SE_DACL_UNTRUSTED |
479 (ControlBitsToSet & ~ControlBitsOfInterest))
480 {
481 /* Fail */
483 }
484
485 /* Zero the 'bits of interest' */
486 Sd->Control &= ~ControlBitsOfInterest;
487
488 /* Set the 'bits to set' */
489 Sd->Control |= (ControlBitsToSet & ControlBitsOfInterest);
490
491 /* All good */
492 return STATUS_SUCCESS;
493}
494
495/*
496 * @implemented
497 */
499NTAPI
501 OUT PUCHAR RMControl)
502{
505
506 /* Check if there's no valid RM control */
507 if (!(Sd->Control & SE_RM_CONTROL_VALID))
508 {
509 /* Fail and return nothing */
510 *RMControl = 0;
511 return FALSE;
512 }
513
514 /* Return it, ironically the member is "should be zero" */
515 *RMControl = Sd->Sbz1;
516 return TRUE;
517}
518
519/*
520 * @implemented
521 */
522VOID
523NTAPI
525 IN PUCHAR RMControl)
526{
529
530 /* RM Control is being cleared or set */
531 if (!RMControl)
532 {
533 /* Clear it */
534 Sd->Control &= ~SE_RM_CONTROL_VALID;
535 Sd->Sbz1 = 0;
536 }
537 else
538 {
539 /* Set it */
541 Sd->Sbz1 = *RMControl;
542 }
543}
544
545/*
546 * @implemented
547 */
549NTAPI
553{
556
557 /* Always return revision, even if invalid */
558 *Revision = Sd->Revision;
559
560 /* Fail on invalid revision */
562
563 /* Mask out flags which are not attributes */
572
573 /* Call the newer API */
575}
576
577/*
578 * @implemented
579 */
581NTAPI
583 OUT PSECURITY_DESCRIPTOR *pDestinationSecurityDescriptor)
584{
586 PACL Dacl, Sacl;
587 DWORD OwnerLength, GroupLength, DaclLength, SaclLength, TotalLength;
588 PISECURITY_DESCRIPTOR Sd = pSourceSecurityDescriptor;
589
590 /* Get all the components */
592 &Owner,
593 &OwnerLength,
594 &Group,
596 &Dacl,
597 &DaclLength,
598 &Sacl,
599 &SaclLength);
600
601 /* Add up their lengths */
603 OwnerLength +
605 DaclLength +
606 SaclLength;
607
608 /* Allocate a copy */
609 *pDestinationSecurityDescriptor = RtlAllocateHeap(RtlGetProcessHeap(),
610 0,
612 if (*pDestinationSecurityDescriptor == NULL) return STATUS_NO_MEMORY;
613
614 /* Copy the old in the new */
615 RtlCopyMemory(*pDestinationSecurityDescriptor, Sd, TotalLength);
616
617 /* All good */
618 return STATUS_SUCCESS;
619}
620
621/*
622 * @implemented
623 */
625NTAPI
629{
632
633 /* Can't already be relative */
635
636 /* Call the other API */
640}
641
642/*
643 * @implemented
644 */
646NTAPI
648 OUT PSECURITY_DESCRIPTOR SelfRelativeSD,
650{
652 PACL Sacl, Dacl;
653 ULONG OwnerLength, GroupLength, SaclLength, DaclLength, TotalLength;
654 ULONG_PTR Current;
658
659 /* Query all components */
661 &Owner,
662 &OwnerLength,
663 &Group,
665 &Dacl,
666 &DaclLength,
667 &Sacl,
668 &SaclLength);
669
670 /* Calculate final length */
672 OwnerLength +
674 SaclLength +
675 DaclLength;
676
677 /* Is there enough space? */
679 {
680 /* Nope, return how much is needed */
683 }
684
685 /* Start fresh */
687
688 /* Copy the header fields */
689 RtlCopyMemory(RelSd,
690 Sd,
692
693 /* Set the current copy pointer */
694 Current = (ULONG_PTR)(RelSd + 1);
695
696 /* Is there a SACL? */
697 if (SaclLength)
698 {
699 /* Copy it */
700 RtlCopyMemory((PVOID)Current, Sacl, SaclLength);
701 RelSd->Sacl = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
702 Current += SaclLength;
703 }
704
705 /* Is there a DACL? */
706 if (DaclLength)
707 {
708 /* Copy it */
709 RtlCopyMemory((PVOID)Current, Dacl, DaclLength);
710 RelSd->Dacl = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
711 Current += DaclLength;
712 }
713
714 /* Is there an owner? */
715 if (OwnerLength)
716 {
717 /* Copy it */
718 RtlCopyMemory((PVOID)Current, Owner, OwnerLength);
719 RelSd->Owner = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
720 Current += OwnerLength;
721 }
722
723 /* Is there a group? */
724 if (GroupLength)
725 {
726 /* Copy it */
728 RelSd->Group = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
729 }
730
731 /* Mark it as relative */
732 RelSd->Control |= SE_SELF_RELATIVE;
733
734 /* All good */
735 return STATUS_SUCCESS;
736}
737
738/*
739 * @implemented
740 */
742NTAPI
744 OUT PSECURITY_DESCRIPTOR AbsoluteSD,
745 IN PULONG AbsoluteSDSize,
746 IN PACL Dacl,
748 IN PACL Sacl,
750 IN PSID Owner,
754{
756 PISECURITY_DESCRIPTOR RelSd = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
757 ULONG OwnerLength, GroupLength, DaclLength, SaclLength;
758 PSID pOwner, pGroup;
759 PACL pDacl, pSacl;
761
762 /* Must be relative, otherwiise fail */
764
765 /* Get all the components */
767 &pOwner,
768 &OwnerLength,
769 &pGroup,
771 &pDacl,
772 &DaclLength,
773 &pSacl,
774 &SaclLength);
775
776 /* Fail if there's not enough space */
777 if (!(Sd) ||
778 (sizeof(SECURITY_DESCRIPTOR) > *AbsoluteSDSize) ||
779 (OwnerLength > *OwnerSize) ||
781 (DaclLength > *DaclSize) ||
782 (SaclLength > *SaclSize))
783 {
784 /* Return how much space is needed for each components */
785 *AbsoluteSDSize = sizeof(SECURITY_DESCRIPTOR);
786 *OwnerSize = OwnerLength;
788 *DaclSize = DaclLength;
789 *SaclSize = SaclLength;
791 }
792
793 /* Copy the header fields */
795
796 /* Wipe out the pointers and the relative flag */
797 Sd->Owner = NULL;
798 Sd->Group = NULL;
799 Sd->Sacl = NULL;
800 Sd->Dacl = NULL;
801 Sd->Control &= ~SE_SELF_RELATIVE;
802
803 /* Is there an owner? */
804 if (pOwner)
805 {
806 /* Copy it */
807 RtlMoveMemory(Owner, pOwner, RtlLengthSid(pOwner));
808 Sd->Owner = Owner;
809 }
810
811 /* Is there a group? */
812 if (pGroup)
813 {
814 /* Copy it */
815 RtlMoveMemory(PrimaryGroup, pGroup, RtlLengthSid(pGroup));
816 Sd->Group = PrimaryGroup;
817 }
818
819 /* Is there a DACL? */
820 if (pDacl)
821 {
822 /* Copy it */
823 RtlMoveMemory(Dacl, pDacl, pDacl->AclSize);
824 Sd->Dacl = Dacl;
825 }
826
827 /* Is there a SACL? */
828 if (pSacl)
829 {
830 /* Copy it */
831 RtlMoveMemory(Sacl, pSacl, pSacl->AclSize);
832 Sd->Sacl = Sacl;
833 }
834
835 /* All good */
836 return STATUS_SUCCESS;
837}
838
839/*
840 * @implemented
841 */
843NTAPI
846{
847 PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
849 PVOID DataStart, DataEnd;
850 LONG MoveDelta;
851 ULONG DataSize, OwnerLength, GroupLength, DaclLength, SaclLength;
852 PSID pOwner, pGroup;
853 PACL pDacl, pSacl;
855
856 /* Need input */
857 if (!RelSd) return STATUS_INVALID_PARAMETER_1;
858
859 /* Need to know how much space we have */
861
862 /* Input must be relative */
864
865 /* Query all the component sizes */
867 &pOwner,
868 &OwnerLength,
869 &pGroup,
871 &pDacl,
872 &DaclLength,
873 &pSacl,
874 &SaclLength);
875
876 /*
877 * Check if there's a difference in structure layout between relatiev and
878 * absolute descriptors. On 32-bit, there won't be, since an offset is the
879 * same size as a pointer (32-bit), but on 64-bit, the offsets remain 32-bit
880 * as they are not SIZE_T, but ULONG, while the pointers now become 64-bit
881 * and thus the structure is different */
882 MoveDelta = sizeof(SECURITY_DESCRIPTOR) - sizeof(SECURITY_DESCRIPTOR_RELATIVE);
883 if (!MoveDelta)
884 {
885 /* So on 32-bit, simply clear the flag... */
886 Sd->Control &= ~SE_SELF_RELATIVE;
887
888 /* Ensure we're *really* on 32-bit */
889 ASSERT(sizeof(Sd->Owner) == sizeof(RelSd->Owner));
890 ASSERT(sizeof(Sd->Group) == sizeof(RelSd->Group));
891 ASSERT(sizeof(Sd->Sacl) == sizeof(RelSd->Sacl));
892 ASSERT(sizeof(Sd->Dacl) == sizeof(RelSd->Dacl));
893
894 /* And simply set pointers where there used to be offsets */
895 Sd->Owner = pOwner;
896 Sd->Group = pGroup;
897 Sd->Sacl = pSacl;
898 Sd->Dacl = pDacl;
899 return STATUS_SUCCESS;
900 }
901
902 /*
903 * Calculate the start and end of the data area, we simply just move the
904 * data by the difference between the size of the relative and absolute
905 * security descriptor structure
906 */
907 DataStart = pOwner;
908 DataEnd = (PVOID)((ULONG_PTR)pOwner + OwnerLength);
909
910 /* Is there a group? */
911 if (pGroup)
912 {
913 /* Is the group higher than where we started? */
914 if (((ULONG_PTR)pGroup < (ULONG_PTR)DataStart) || !DataStart)
915 {
916 /* Update the start pointer */
917 DataStart = pGroup;
918 }
919
920 /* Is the group beyond where we ended? */
921 if (((ULONG_PTR)pGroup + GroupLength > (ULONG_PTR)DataEnd) || !DataEnd)
922 {
923 /* Update the end pointer */
924 DataEnd = (PVOID)((ULONG_PTR)pGroup + GroupLength);
925 }
926 }
927
928 /* Is there a DACL? */
929 if (pDacl)
930 {
931 /* Is the DACL higher than where we started? */
932 if (((ULONG_PTR)pDacl < (ULONG_PTR)DataStart) || !DataStart)
933 {
934 /* Update the start pointer */
935 DataStart = pDacl;
936 }
937
938 /* Is the DACL beyond where we ended? */
939 if (((ULONG_PTR)pDacl + DaclLength > (ULONG_PTR)DataEnd) || !DataEnd)
940 {
941 /* Update the end pointer */
942 DataEnd = (PVOID)((ULONG_PTR)pDacl + DaclLength);
943 }
944 }
945
946 /* Is there a SACL? */
947 if (pSacl)
948 {
949 /* Is the SACL higher than where we started? */
950 if (((ULONG_PTR)pSacl < (ULONG_PTR)DataStart) || !DataStart)
951 {
952 /* Update the start pointer */
953 DataStart = pSacl;
954 }
955
956 /* Is the SACL beyond where we ended? */
957 if (((ULONG_PTR)pSacl + SaclLength > (ULONG_PTR)DataEnd) || !DataEnd)
958 {
959 /* Update the end pointer */
960 DataEnd = (PVOID)((ULONG_PTR)pSacl + SaclLength);
961 }
962 }
963
964 /* Sanity check */
965 ASSERT((ULONG_PTR)DataEnd >= (ULONG_PTR)DataStart);
966
967 /* Now compute the difference between relative and absolute */
968 DataSize = (ULONG)((ULONG_PTR)DataEnd - (ULONG_PTR)DataStart);
969
970 /* Is the new buffer large enough for this difference? */
971 if (*BufferSize < sizeof(SECURITY_DESCRIPTOR) + DataSize)
972 {
973 /* Nope, bail out */
976 }
977
978 /* Is there anything actually to copy? */
979 if (DataSize)
980 {
981 /*
982 * There must be at least one SID or ACL in the security descriptor!
983 * Also the data area must be located somewhere after the end of the
984 * SECURITY_DESCRIPTOR_RELATIVE structure
985 */
986 ASSERT(DataStart != NULL);
987 ASSERT((ULONG_PTR)DataStart >= (ULONG_PTR)(RelSd + 1));
988
989 /* It's time to move the data */
990 RtlMoveMemory((PVOID)(Sd + 1),
991 DataStart,
992 DataSize);
993 }
994
995 /* Is there an owner? */
996 if (pOwner)
997 {
998 /* Set the pointer to the relative position */
999 Sd->Owner = (PSID)((LONG_PTR)pOwner + MoveDelta);
1000 }
1001 else
1002 {
1003 /* No owner, clear the pointer */
1004 Sd->Owner = NULL;
1005 }
1006
1007 /* Is there a group */
1008 if (pGroup)
1009 {
1010 /* Set the pointer to the relative position */
1011 Sd->Group = (PSID)((LONG_PTR)pGroup + MoveDelta);
1012 }
1013 else
1014 {
1015 /* No group, clear the pointer */
1016 Sd->Group = NULL;
1017 }
1018
1019 /* Is there a SACL? */
1020 if (pSacl)
1021 {
1022 /* Set the pointer to the relative position */
1023 Sd->Sacl = (PACL)((LONG_PTR)pSacl + MoveDelta);
1024 }
1025 else
1026 {
1027 /* No SACL, clear the pointer */
1028 Sd->Sacl = NULL;
1029 }
1030
1031 /* Is there a DACL? */
1032 if (pDacl)
1033 {
1034 /* Set the pointer to the relative position */
1035 Sd->Dacl = (PACL)((LONG_PTR)pDacl + MoveDelta);
1036 }
1037 else
1038 {
1039 /* No DACL, clear the pointer */
1040 Sd->Dacl = NULL;
1041 }
1042
1043 /* Clear the self-relative flag */
1044 Sd->Control &= ~SE_SELF_RELATIVE;
1045
1046 /* All good */
1047 return STATUS_SUCCESS;
1048}
1049
1050/*
1051 * @implemented
1052 */
1053BOOLEAN
1054NTAPI
1056{
1058 PSID Owner, Group;
1059 PACL Sacl, Dacl;
1061
1062 _SEH2_TRY
1063 {
1064 /* Fail on bad revisions */
1066
1067 /* Owner SID must be valid if present */
1069 if ((Owner) && (!RtlValidSid(Owner))) _SEH2_YIELD(return FALSE);
1070
1071 /* Group SID must be valid if present */
1073 if ((Group) && (!RtlValidSid(Group))) _SEH2_YIELD(return FALSE);
1074
1075 /* DACL must be valid if present */
1077 if ((Dacl) && (!RtlValidAcl(Dacl))) _SEH2_YIELD(return FALSE);
1078
1079 /* SACL must be valid if present */
1081 if ((Sacl) && (!RtlValidAcl(Sacl))) _SEH2_YIELD(return FALSE);
1082 }
1084 {
1085 /* Access fault, bail out */
1086 _SEH2_YIELD(return FALSE);
1087 }
1088 _SEH2_END;
1089
1090 /* All good */
1091 return TRUE;
1092}
1093
1094/*
1095 * @implemented
1096 */
1097BOOLEAN
1098NTAPI
1102{
1104 PSID Owner, Group;
1105 PACL Dacl, Sacl;
1106 ULONG Length;
1108
1109 /* Note that Windows allows no DACL/SACL even if RequiredInfo wants it */
1110
1111 /* Do we have enough space, is the revision vaild, and is this SD relative? */
1114 !(Sd->Control & SE_SELF_RELATIVE))
1115 {
1116 /* Nope, bail out */
1117 return FALSE;
1118 }
1119
1120 /* Is there an owner? */
1121 if (Sd->Owner)
1122 {
1123 /* Try to access it */
1126 sizeof(SID),
1127 &Length))
1128 {
1129 /* It's beyond the buffer, fail */
1130 return FALSE;
1131 }
1132
1133 /* Read the owner, check if it's valid and if the buffer contains it */
1134 Owner = (PSID)((ULONG_PTR)Sd->Owner + (ULONG_PTR)Sd);
1135 if (!RtlValidSid(Owner) || (Length < RtlLengthSid(Owner))) return FALSE;
1136 }
1138 {
1139 /* No owner but the caller expects one, fail */
1140 return FALSE;
1141 }
1142
1143 /* Is there a group? */
1144 if (Sd->Group)
1145 {
1146 /* Try to access it */
1149 sizeof(SID),
1150 &Length))
1151 {
1152 /* It's beyond the buffer, fail */
1153 return FALSE;
1154 }
1155
1156 /* Read the group, check if it's valid and if the buffer contains it */
1157 Group = (PSID)((ULONG_PTR)Sd->Group + (ULONG_PTR)Sd);
1158 if (!RtlValidSid(Group) || (Length < RtlLengthSid(Group))) return FALSE;
1159 }
1161 {
1162 /* No group, but the caller expects one, fail */
1163 return FALSE;
1164 }
1165
1166 /* Is there a DACL? */
1168 {
1169 /* Try to access it */
1172 sizeof(ACL),
1173 &Length))
1174 {
1175 /* It's beyond the buffer, fail */
1176 return FALSE;
1177 }
1178
1179 /* Read the DACL, check if it's valid and if the buffer contains it */
1180 Dacl = (PSID)((ULONG_PTR)Sd->Dacl + (ULONG_PTR)Sd);
1181 if (!(RtlValidAcl(Dacl)) || (Length < Dacl->AclSize)) return FALSE;
1182 }
1183
1184 /* Is there a SACL? */
1186 {
1187 /* Try to access it */
1190 sizeof(ACL),
1191 &Length))
1192 {
1193 /* It's beyond the buffer, fail */
1194 return FALSE;
1195 }
1196
1197 /* Read the SACL, check if it's valid and if the buffer contains it */
1198 Sacl = (PSID)((ULONG_PTR)Sd->Sacl + (ULONG_PTR)Sd);
1199 if (!(RtlValidAcl(Sacl)) || (Length < Sacl->AclSize)) return FALSE;
1200 }
1201
1202 /* All good */
1203 return TRUE;
1204}
1205
1206/* EOF */
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ULONG_PTR
Definition: config.h:101
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned long DWORD
Definition: ntddk_ex.h:95
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSYSAPI ULONG WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
WORD SECURITY_DESCRIPTOR_CONTROL
Definition: lsa.idl:37
WORD * PSECURITY_DESCRIPTOR_CONTROL
Definition: lsa.idl:37
#define ASSERT(a)
Definition: mode.c:44
struct _SID * PSID
Definition: eventlog.c:35
DWORD SECURITY_INFORMATION
Definition: ms-dtyp.idl:311
struct _SECURITY_DESCRIPTOR SECURITY_DESCRIPTOR
struct _ACL * PACL
Definition: security.c:105
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1593
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor
Definition: rtlfuncs.h:1591
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID _Inout_ PULONG OwnerSize
Definition: rtlfuncs.h:1598
_In_opt_ PSID Group
Definition: rtlfuncs.h:1646
NTSYSAPI BOOLEAN NTAPI RtlValidAcl(PACL Acl)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1597
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID _Inout_ PULONG _Out_writes_bytes_to_opt_ PrimaryGroupSize PSID PrimaryGroup
Definition: rtlfuncs.h:1599
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG SaclSize
Definition: rtlfuncs.h:1596
_In_opt_ PSID _In_opt_ BOOLEAN GroupDefaulted
Definition: rtlfuncs.h:1648
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
_In_ BOOLEAN DaclPresent
Definition: rtlfuncs.h:1635
NTSYSAPI BOOLEAN NTAPI RtlValidSid(IN PSID Sid)
Definition: sid.c:21
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
_Out_writes_bytes_to_opt_ BufferLength PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor
Definition: rtlfuncs.h:1120
_In_opt_ PSID _In_opt_ BOOLEAN OwnerDefaulted
Definition: rtlfuncs.h:1672
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL Sacl
Definition: rtlfuncs.h:1595
_In_ ULONG _In_ SECURITY_INFORMATION RequiredInformation
Definition: rtlfuncs.h:1716
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID _Inout_ PULONG _Out_writes_bytes_to_opt_ PrimaryGroupSize PSID _Inout_ PULONG PrimaryGroupSize
Definition: rtlfuncs.h:1601
_In_ ULONG SecurityDescriptorLength
Definition: rtlfuncs.h:1714
_In_ ULONG Revision
Definition: rtlfuncs.h:1130
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptorRelative(_Out_ PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor, _In_ ULONG Revision)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1594
_In_ BOOLEAN _In_opt_ PACL _In_opt_ BOOLEAN DaclDefaulted
Definition: rtlfuncs.h:1638
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
FORCEINLINE PSID SepGetOwnerFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:99
FORCEINLINE PACL SepGetSaclFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:141
FORCEINLINE PSID SepGetGroupFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:79
FORCEINLINE PACL SepGetDaclFromDescriptor(_Inout_ PVOID _Descriptor)
Definition: se.h:119
#define STATUS_UNKNOWN_REVISION
Definition: ntstatus.h:324
#define STATUS_BAD_DESCRIPTOR_FORMAT
Definition: ntstatus.h:467
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_INVALID_SECURITY_DESCR
Definition: ntstatus.h:357
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:475
long LONG
Definition: pedump.c:60
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define PAGED_CODE_RTL()
Definition: rtlp.h:16
NTSTATUS NTAPI RtlSetAttributesSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN SECURITY_DESCRIPTOR_CONTROL Control, OUT PULONG Revision)
Definition: sd.c:550
NTSTATUS NTAPI RtlGetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PSECURITY_DESCRIPTOR_CONTROL Control, OUT PULONG Revision)
Definition: sd.c:439
NTSTATUS NTAPI RtlSetOwnerSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSID Owner, IN BOOLEAN OwnerDefaulted)
Definition: sd.c:381
VOID NTAPI RtlSetSecurityDescriptorRMControl(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PUCHAR RMControl)
Definition: sd.c:524
NTSTATUS NTAPI RtlMakeSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSD, OUT PSECURITY_DESCRIPTOR SelfRelativeSD, IN OUT PULONG BufferLength)
Definition: sd.c:647
VOID NTAPI RtlpQuerySecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptor, OUT PSID *Owner, OUT PULONG OwnerSize, OUT PSID *PrimaryGroup, OUT PULONG PrimaryGroupSize, OUT PACL *Dacl, OUT PULONG DaclSize, OUT PACL *Sacl, OUT PULONG SaclSize)
Definition: sd.c:45
BOOLEAN NTAPI RtlpValidateSDOffsetAndSize(IN ULONG Offset, IN ULONG Length, IN ULONG MinLength, OUT PULONG MaxLength)
Definition: sd.c:20
NTSTATUS NTAPI RtlSelfRelativeToAbsoluteSD2(IN OUT PSECURITY_DESCRIPTOR SelfRelativeSD, OUT PULONG BufferSize)
Definition: sd.c:844
NTSTATUS NTAPI RtlSetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest, IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet)
Definition: sd.c:464
NTSTATUS NTAPI RtlSetSaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN SaclPresent, IN PACL Sacl, IN BOOLEAN SaclDefaulted)
Definition: sd.c:342
NTSTATUS NTAPI RtlSelfRelativeToAbsoluteSD(IN PSECURITY_DESCRIPTOR SelfRelativeSD, OUT PSECURITY_DESCRIPTOR AbsoluteSD, IN PULONG AbsoluteSDSize, IN PACL Dacl, IN PULONG DaclSize, IN PACL Sacl, IN PULONG SaclSize, IN PSID Owner, IN PULONG OwnerSize, IN PSID PrimaryGroup, IN PULONG PrimaryGroupSize)
Definition: sd.c:743
NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PBOOLEAN DaclPresent, OUT PACL *Dacl, OUT PBOOLEAN DaclDefaulted)
Definition: sd.c:199
NTSTATUS NTAPI RtlCopySecurityDescriptor(IN PSECURITY_DESCRIPTOR pSourceSecurityDescriptor, OUT PSECURITY_DESCRIPTOR *pDestinationSecurityDescriptor)
Definition: sd.c:582
BOOLEAN NTAPI RtlGetSecurityDescriptorRMControl(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PUCHAR RMControl)
Definition: sd.c:500
BOOLEAN NTAPI RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: sd.c:1055
NTSTATUS NTAPI RtlGetSaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PBOOLEAN SaclPresent, OUT PACL *Sacl, OUT PBOOLEAN SaclDefaulted)
Definition: sd.c:228
NTSTATUS NTAPI RtlGetOwnerSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PSID *Owner, OUT PBOOLEAN OwnerDefaulted)
Definition: sd.c:257
BOOLEAN NTAPI RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInput, IN ULONG SecurityDescriptorLength, IN SECURITY_INFORMATION RequiredInformation)
Definition: sd.c:1099
NTSTATUS NTAPI RtlSetGroupSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSID Group, IN BOOLEAN GroupDefaulted)
Definition: sd.c:410
NTSTATUS NTAPI RtlGetGroupSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PSID *Group, OUT PBOOLEAN GroupDefaulted)
Definition: sd.c:280
NTSTATUS NTAPI RtlAbsoluteToSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, IN PULONG BufferLength)
Definition: sd.c:626
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
USHORT AclSize
Definition: ms-dtyp.idl:296
SECURITY_DESCRIPTOR_CONTROL Control
Definition: setypes.h:835
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define ALIGN_DOWN(size, type)
Definition: umtypes.h:88
_In_ ULONG TotalLength
Definition: usbdlib.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
_In_ ULONG _In_ CONST SOCKADDR _In_ int GroupLength
Definition: ws2tcpip.h:712
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
_Out_ PBOOLEAN SaclPresent
Definition: rtlfuncs.h:2413
_Out_ PBOOLEAN _Out_ PACL _Out_ PBOOLEAN SaclDefaulted
Definition: rtlfuncs.h:2415
#define SE_OWNER_DEFAULTED
Definition: setypes.h:815
#define SE_SACL_PROTECTED
Definition: setypes.h:828
#define SE_DACL_DEFAULTED
Definition: setypes.h:818
#define SE_DACL_PROTECTED
Definition: setypes.h:827
#define SE_DACL_AUTO_INHERITED
Definition: setypes.h:825
#define SE_SERVER_SECURITY
Definition: setypes.h:822
#define SE_DACL_AUTO_INHERIT_REQ
Definition: setypes.h:823
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
struct _SECURITY_DESCRIPTOR_RELATIVE * PISECURITY_DESCRIPTOR_RELATIVE
struct _SECURITY_DESCRIPTOR * PISECURITY_DESCRIPTOR
#define SE_SELF_RELATIVE
Definition: setypes.h:830
#define SE_SACL_DEFAULTED
Definition: setypes.h:820
struct _SECURITY_DESCRIPTOR_RELATIVE SECURITY_DESCRIPTOR_RELATIVE
#define SE_SACL_AUTO_INHERITED
Definition: setypes.h:826
#define SE_DACL_UNTRUSTED
Definition: setypes.h:821
#define SE_SACL_PRESENT
Definition: setypes.h:819
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define SE_SACL_AUTO_INHERIT_REQ
Definition: setypes.h:824
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
#define SE_GROUP_DEFAULTED
Definition: setypes.h:816
#define SE_RM_CONTROL_VALID
Definition: setypes.h:829
#define SE_DACL_PRESENT
Definition: setypes.h:817