ReactOS 0.4.16-dev-197-g92996da
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;
657
658 /* Query all components */
660 &Owner,
661 &OwnerLength,
662 &Group,
664 &Dacl,
665 &DaclLength,
666 &Sacl,
667 &SaclLength);
668
669 /* Calculate final length */
671 OwnerLength +
673 SaclLength +
674 DaclLength;
675
676 /* Is there enough space? */
678 {
679 /* Nope, return how much is needed */
682 }
683
684 /* Start fresh */
686
687 /* Copy the header fields */
688 RtlCopyMemory(RelSd,
691
692 /* Set the current copy pointer */
693 Current = (ULONG_PTR)(RelSd + 1);
694
695 /* Is there a SACL? */
696 if (SaclLength)
697 {
698 /* Copy it */
699 RtlCopyMemory((PVOID)Current, Sacl, SaclLength);
700 RelSd->Sacl = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
701 Current += SaclLength;
702 }
703
704 /* Is there a DACL? */
705 if (DaclLength)
706 {
707 /* Copy it */
708 RtlCopyMemory((PVOID)Current, Dacl, DaclLength);
709 RelSd->Dacl = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
710 Current += DaclLength;
711 }
712
713 /* Is there an owner? */
714 if (OwnerLength)
715 {
716 /* Copy it */
717 RtlCopyMemory((PVOID)Current, Owner, OwnerLength);
718 RelSd->Owner = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
719 Current += OwnerLength;
720 }
721
722 /* Is there a group? */
723 if (GroupLength)
724 {
725 /* Copy it */
727 RelSd->Group = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
728 }
729
730 /* Mark it as relative */
731 RelSd->Control |= SE_SELF_RELATIVE;
732
733 /* All good */
734 return STATUS_SUCCESS;
735}
736
737/*
738 * @implemented
739 */
741NTAPI
743 OUT PSECURITY_DESCRIPTOR AbsoluteSD,
744 IN PULONG AbsoluteSDSize,
745 IN PACL Dacl,
747 IN PACL Sacl,
749 IN PSID Owner,
753{
755 PISECURITY_DESCRIPTOR RelSd = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
756 ULONG OwnerLength, GroupLength, DaclLength, SaclLength;
757 PSID pOwner, pGroup;
758 PACL pDacl, pSacl;
760
761 /* Must be relative, otherwiise fail */
763
764 /* Get all the components */
766 &pOwner,
767 &OwnerLength,
768 &pGroup,
770 &pDacl,
771 &DaclLength,
772 &pSacl,
773 &SaclLength);
774
775 /* Fail if there's not enough space */
776 if (!(Sd) ||
777 (sizeof(SECURITY_DESCRIPTOR) > *AbsoluteSDSize) ||
778 (OwnerLength > *OwnerSize) ||
780 (DaclLength > *DaclSize) ||
781 (SaclLength > *SaclSize))
782 {
783 /* Return how much space is needed for each components */
784 *AbsoluteSDSize = sizeof(SECURITY_DESCRIPTOR);
785 *OwnerSize = OwnerLength;
787 *DaclSize = DaclLength;
788 *SaclSize = SaclLength;
790 }
791
792 /* Copy the header fields */
794
795 /* Wipe out the pointers and the relative flag */
796 Sd->Owner = NULL;
797 Sd->Group = NULL;
798 Sd->Sacl = NULL;
799 Sd->Dacl = NULL;
800 Sd->Control &= ~SE_SELF_RELATIVE;
801
802 /* Is there an owner? */
803 if (pOwner)
804 {
805 /* Copy it */
806 RtlMoveMemory(Owner, pOwner, RtlLengthSid(pOwner));
807 Sd->Owner = Owner;
808 }
809
810 /* Is there a group? */
811 if (pGroup)
812 {
813 /* Copy it */
814 RtlMoveMemory(PrimaryGroup, pGroup, RtlLengthSid(pGroup));
815 Sd->Group = PrimaryGroup;
816 }
817
818 /* Is there a DACL? */
819 if (pDacl)
820 {
821 /* Copy it */
822 RtlMoveMemory(Dacl, pDacl, pDacl->AclSize);
823 Sd->Dacl = Dacl;
824 }
825
826 /* Is there a SACL? */
827 if (pSacl)
828 {
829 /* Copy it */
830 RtlMoveMemory(Sacl, pSacl, pSacl->AclSize);
831 Sd->Sacl = Sacl;
832 }
833
834 /* All good */
835 return STATUS_SUCCESS;
836}
837
838/*
839 * @implemented
840 */
842NTAPI
845{
846 PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
848 PVOID DataStart, DataEnd;
849 LONG MoveDelta;
850 ULONG DataSize, OwnerLength, GroupLength, DaclLength, SaclLength;
851 PSID pOwner, pGroup;
852 PACL pDacl, pSacl;
854
855 /* Need input */
856 if (!RelSd) return STATUS_INVALID_PARAMETER_1;
857
858 /* Need to know how much space we have */
860
861 /* Input must be relative */
863
864 /* Query all the component sizes */
866 &pOwner,
867 &OwnerLength,
868 &pGroup,
870 &pDacl,
871 &DaclLength,
872 &pSacl,
873 &SaclLength);
874
875 /*
876 * Check if there's a difference in structure layout between relatiev and
877 * absolute descriptors. On 32-bit, there won't be, since an offset is the
878 * same size as a pointer (32-bit), but on 64-bit, the offsets remain 32-bit
879 * as they are not SIZE_T, but ULONG, while the pointers now become 64-bit
880 * and thus the structure is different */
881 MoveDelta = sizeof(SECURITY_DESCRIPTOR) - sizeof(SECURITY_DESCRIPTOR_RELATIVE);
882 if (!MoveDelta)
883 {
884 /* So on 32-bit, simply clear the flag... */
885 Sd->Control &= ~SE_SELF_RELATIVE;
886
887 /* Ensure we're *really* on 32-bit */
888 ASSERT(sizeof(Sd->Owner) == sizeof(RelSd->Owner));
889 ASSERT(sizeof(Sd->Group) == sizeof(RelSd->Group));
890 ASSERT(sizeof(Sd->Sacl) == sizeof(RelSd->Sacl));
891 ASSERT(sizeof(Sd->Dacl) == sizeof(RelSd->Dacl));
892
893 /* And simply set pointers where there used to be offsets */
894 Sd->Owner = pOwner;
895 Sd->Group = pGroup;
896 Sd->Sacl = pSacl;
897 Sd->Dacl = pDacl;
898 return STATUS_SUCCESS;
899 }
900
901 /*
902 * Calculate the start and end of the data area, we simply just move the
903 * data by the difference between the size of the relative and absolute
904 * security descriptor structure
905 */
906 DataStart = pOwner;
907 DataEnd = (PVOID)((ULONG_PTR)pOwner + OwnerLength);
908
909 /* Is there a group? */
910 if (pGroup)
911 {
912 /* Is the group higher than where we started? */
913 if (((ULONG_PTR)pGroup < (ULONG_PTR)DataStart) || !DataStart)
914 {
915 /* Update the start pointer */
916 DataStart = pGroup;
917 }
918
919 /* Is the group beyond where we ended? */
920 if (((ULONG_PTR)pGroup + GroupLength > (ULONG_PTR)DataEnd) || !DataEnd)
921 {
922 /* Update the end pointer */
923 DataEnd = (PVOID)((ULONG_PTR)pGroup + GroupLength);
924 }
925 }
926
927 /* Is there a DACL? */
928 if (pDacl)
929 {
930 /* Is the DACL higher than where we started? */
931 if (((ULONG_PTR)pDacl < (ULONG_PTR)DataStart) || !DataStart)
932 {
933 /* Update the start pointer */
934 DataStart = pDacl;
935 }
936
937 /* Is the DACL beyond where we ended? */
938 if (((ULONG_PTR)pDacl + DaclLength > (ULONG_PTR)DataEnd) || !DataEnd)
939 {
940 /* Update the end pointer */
941 DataEnd = (PVOID)((ULONG_PTR)pDacl + DaclLength);
942 }
943 }
944
945 /* Is there a SACL? */
946 if (pSacl)
947 {
948 /* Is the SACL higher than where we started? */
949 if (((ULONG_PTR)pSacl < (ULONG_PTR)DataStart) || !DataStart)
950 {
951 /* Update the start pointer */
952 DataStart = pSacl;
953 }
954
955 /* Is the SACL beyond where we ended? */
956 if (((ULONG_PTR)pSacl + SaclLength > (ULONG_PTR)DataEnd) || !DataEnd)
957 {
958 /* Update the end pointer */
959 DataEnd = (PVOID)((ULONG_PTR)pSacl + SaclLength);
960 }
961 }
962
963 /* Sanity check */
964 ASSERT((ULONG_PTR)DataEnd >= (ULONG_PTR)DataStart);
965
966 /* Now compute the difference between relative and absolute */
967 DataSize = (ULONG)((ULONG_PTR)DataEnd - (ULONG_PTR)DataStart);
968
969 /* Is the new buffer large enough for this difference? */
970 if (*BufferSize < sizeof(SECURITY_DESCRIPTOR) + DataSize)
971 {
972 /* Nope, bail out */
975 }
976
977 /* Is there anything actually to copy? */
978 if (DataSize)
979 {
980 /*
981 * There must be at least one SID or ACL in the security descriptor!
982 * Also the data area must be located somewhere after the end of the
983 * SECURITY_DESCRIPTOR_RELATIVE structure
984 */
985 ASSERT(DataStart != NULL);
986 ASSERT((ULONG_PTR)DataStart >= (ULONG_PTR)(RelSd + 1));
987
988 /* It's time to move the data */
989 RtlMoveMemory((PVOID)(Sd + 1),
990 DataStart,
991 DataSize);
992 }
993
994 /* Is there an owner? */
995 if (pOwner)
996 {
997 /* Set the pointer to the relative position */
998 Sd->Owner = (PSID)((LONG_PTR)pOwner + MoveDelta);
999 }
1000 else
1001 {
1002 /* No owner, clear the pointer */
1003 Sd->Owner = NULL;
1004 }
1005
1006 /* Is there a group */
1007 if (pGroup)
1008 {
1009 /* Set the pointer to the relative position */
1010 Sd->Group = (PSID)((LONG_PTR)pGroup + MoveDelta);
1011 }
1012 else
1013 {
1014 /* No group, clear the pointer */
1015 Sd->Group = NULL;
1016 }
1017
1018 /* Is there a SACL? */
1019 if (pSacl)
1020 {
1021 /* Set the pointer to the relative position */
1022 Sd->Sacl = (PACL)((LONG_PTR)pSacl + MoveDelta);
1023 }
1024 else
1025 {
1026 /* No SACL, clear the pointer */
1027 Sd->Sacl = NULL;
1028 }
1029
1030 /* Is there a DACL? */
1031 if (pDacl)
1032 {
1033 /* Set the pointer to the relative position */
1034 Sd->Dacl = (PACL)((LONG_PTR)pDacl + MoveDelta);
1035 }
1036 else
1037 {
1038 /* No DACL, clear the pointer */
1039 Sd->Dacl = NULL;
1040 }
1041
1042 /* Clear the self-relative flag */
1043 Sd->Control &= ~SE_SELF_RELATIVE;
1044
1045 /* All good */
1046 return STATUS_SUCCESS;
1047}
1048
1049/*
1050 * @implemented
1051 */
1052BOOLEAN
1053NTAPI
1055{
1057 PSID Owner, Group;
1058 PACL Sacl, Dacl;
1060
1061 _SEH2_TRY
1062 {
1063 /* Fail on bad revisions */
1065
1066 /* Owner SID must be valid if present */
1068 if ((Owner) && (!RtlValidSid(Owner))) _SEH2_YIELD(return FALSE);
1069
1070 /* Group SID must be valid if present */
1072 if ((Group) && (!RtlValidSid(Group))) _SEH2_YIELD(return FALSE);
1073
1074 /* DACL must be valid if present */
1076 if ((Dacl) && (!RtlValidAcl(Dacl))) _SEH2_YIELD(return FALSE);
1077
1078 /* SACL must be valid if present */
1080 if ((Sacl) && (!RtlValidAcl(Sacl))) _SEH2_YIELD(return FALSE);
1081 }
1083 {
1084 /* Access fault, bail out */
1085 _SEH2_YIELD(return FALSE);
1086 }
1087 _SEH2_END;
1088
1089 /* All good */
1090 return TRUE;
1091}
1092
1093/*
1094 * @implemented
1095 */
1096BOOLEAN
1097NTAPI
1101{
1103 PSID Owner, Group;
1104 PACL Dacl, Sacl;
1105 ULONG Length;
1107
1108 /* Note that Windows allows no DACL/SACL even if RequiredInfo wants it */
1109
1110 /* Do we have enough space, is the revision vaild, and is this SD relative? */
1113 !(Sd->Control & SE_SELF_RELATIVE))
1114 {
1115 /* Nope, bail out */
1116 return FALSE;
1117 }
1118
1119 /* Is there an owner? */
1120 if (Sd->Owner)
1121 {
1122 /* Try to access it */
1125 sizeof(SID),
1126 &Length))
1127 {
1128 /* It's beyond the buffer, fail */
1129 return FALSE;
1130 }
1131
1132 /* Read the owner, check if it's valid and if the buffer contains it */
1133 Owner = (PSID)((ULONG_PTR)Sd->Owner + (ULONG_PTR)Sd);
1134 if (!RtlValidSid(Owner) || (Length < RtlLengthSid(Owner))) return FALSE;
1135 }
1137 {
1138 /* No owner but the caller expects one, fail */
1139 return FALSE;
1140 }
1141
1142 /* Is there a group? */
1143 if (Sd->Group)
1144 {
1145 /* Try to access it */
1148 sizeof(SID),
1149 &Length))
1150 {
1151 /* It's beyond the buffer, fail */
1152 return FALSE;
1153 }
1154
1155 /* Read the group, check if it's valid and if the buffer contains it */
1156 Group = (PSID)((ULONG_PTR)Sd->Group + (ULONG_PTR)Sd);
1157 if (!RtlValidSid(Group) || (Length < RtlLengthSid(Group))) return FALSE;
1158 }
1160 {
1161 /* No group, but the caller expects one, fail */
1162 return FALSE;
1163 }
1164
1165 /* Is there a DACL? */
1167 {
1168 /* Try to access it */
1171 sizeof(ACL),
1172 &Length))
1173 {
1174 /* It's beyond the buffer, fail */
1175 return FALSE;
1176 }
1177
1178 /* Read the DACL, check if it's valid and if the buffer contains it */
1179 Dacl = (PSID)((ULONG_PTR)Sd->Dacl + (ULONG_PTR)Sd);
1180 if (!(RtlValidAcl(Dacl)) || (Length < Dacl->AclSize)) return FALSE;
1181 }
1182
1183 /* Is there a SACL? */
1185 {
1186 /* Try to access it */
1189 sizeof(ACL),
1190 &Length))
1191 {
1192 /* It's beyond the buffer, fail */
1193 return FALSE;
1194 }
1195
1196 /* Read the SACL, check if it's valid and if the buffer contains it */
1197 Sacl = (PSID)((ULONG_PTR)Sd->Sacl + (ULONG_PTR)Sd);
1198 if (!(RtlValidAcl(Sacl)) || (Length < Sacl->AclSize)) return FALSE;
1199 }
1200
1201 /* All good */
1202 return TRUE;
1203}
1204
1205/* 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:590
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#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:1605
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor
Definition: rtlfuncs.h:1603
_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:1610
_In_opt_ PSID Group
Definition: rtlfuncs.h:1658
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:1609
_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:1611
_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:1608
_In_opt_ PSID _In_opt_ BOOLEAN GroupDefaulted
Definition: rtlfuncs.h:1660
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
_In_ BOOLEAN DaclPresent
Definition: rtlfuncs.h:1647
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:1132
_In_opt_ PSID _In_opt_ BOOLEAN OwnerDefaulted
Definition: rtlfuncs.h:1684
_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:1607
_In_ ULONG _In_ SECURITY_INFORMATION RequiredInformation
Definition: rtlfuncs.h:1728
_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:1613
_In_ ULONG SecurityDescriptorLength
Definition: rtlfuncs.h:1726
_In_ ULONG Revision
Definition: rtlfuncs.h:1142
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:1606
_In_ BOOLEAN _In_opt_ PACL _In_opt_ BOOLEAN DaclDefaulted
Definition: rtlfuncs.h:1650
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
FORCEINLINE PSID SepGetOwnerFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:109
FORCEINLINE PSID SepGetGroupFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:89
FORCEINLINE PACL SepGetDaclFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:129
FORCEINLINE PACL SepGetSaclFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:151
#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_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:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#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 SecurityDescriptor, OUT PSECURITY_DESCRIPTOR SelfRelativeSD, IN OUT PULONG BufferLength)
Definition: sd.c:647
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:843
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:742
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:1054
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:1098
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
VOID NTAPI RtlpQuerySecurityDescriptor(IN PSECURITY_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
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:839
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:2427
_Out_ PBOOLEAN _Out_ PACL _Out_ PBOOLEAN SaclDefaulted
Definition: rtlfuncs.h:2429
#define SE_OWNER_DEFAULTED
Definition: setypes.h:819
#define SE_SACL_PROTECTED
Definition: setypes.h:832
#define SE_DACL_DEFAULTED
Definition: setypes.h:822
#define SE_DACL_PROTECTED
Definition: setypes.h:831
#define SE_DACL_AUTO_INHERITED
Definition: setypes.h:829
#define SE_SERVER_SECURITY
Definition: setypes.h:826
#define SE_DACL_AUTO_INHERIT_REQ
Definition: setypes.h:827
#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:834
#define SE_SACL_DEFAULTED
Definition: setypes.h:824
struct _SECURITY_DESCRIPTOR_RELATIVE SECURITY_DESCRIPTOR_RELATIVE
#define SE_SACL_AUTO_INHERITED
Definition: setypes.h:830
#define SE_DACL_UNTRUSTED
Definition: setypes.h:825
#define SE_SACL_PRESENT
Definition: setypes.h:823
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define SE_SACL_AUTO_INHERIT_REQ
Definition: setypes.h:828
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
#define SE_GROUP_DEFAULTED
Definition: setypes.h:820
#define SE_RM_CONTROL_VALID
Definition: setypes.h:833
#define SE_DACL_PRESENT
Definition: setypes.h:821