2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * PURPOSE: Security descriptor functions
6 * PROGRAMER: David Welch <welch@cwcom.net>
9 /* INCLUDES *****************************************************************/
16 /* FUNCTIONS ***************************************************************/
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
)
26 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
28 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
31 *Owner
= ((RelSD
->Owner
!= 0) ? (PSID
)((ULONG_PTR
)RelSD
+ RelSD
->Owner
) : NULL
);
35 *Group
= ((RelSD
->Group
!= 0) ? (PSID
)((ULONG_PTR
)RelSD
+ RelSD
->Group
) : NULL
);
39 *Sacl
= (((RelSD
->Control
& SE_SACL_PRESENT
) && (RelSD
->Sacl
!= 0)) ?
40 (PSID
)((ULONG_PTR
)RelSD
+ RelSD
->Sacl
) : NULL
);
44 *Dacl
= (((RelSD
->Control
& SE_DACL_PRESENT
) && (RelSD
->Dacl
!= 0)) ?
45 (PSID
)((ULONG_PTR
)RelSD
+ RelSD
->Dacl
) : NULL
);
52 *Owner
= SecurityDescriptor
->Owner
;
56 *Group
= SecurityDescriptor
->Group
;
60 *Sacl
= ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) ? SecurityDescriptor
->Sacl
: NULL
);
64 *Dacl
= ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) ? SecurityDescriptor
->Dacl
: NULL
);
70 RtlpQuerySecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor
,
80 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
88 *OwnerLength
= ((*Owner
!= NULL
) ? ROUND_UP(RtlLengthSid(*Owner
), 4) : 0);
93 *GroupLength
= ((*Group
!= NULL
) ? ROUND_UP(RtlLengthSid(*Group
), 4) : 0);
98 *DaclLength
= ((*Dacl
!= NULL
) ? ROUND_UP((*Dacl
)->AclSize
, 4) : 0);
103 *SaclLength
= ((*Sacl
!= NULL
) ? ROUND_UP((*Sacl
)->AclSize
, 4) : 0);
111 RtlCreateSecurityDescriptor(OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
114 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
118 if (Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
120 return STATUS_UNKNOWN_REVISION
;
123 pSD
->Revision
= Revision
;
131 return STATUS_SUCCESS
;
138 RtlCopySecurityDescriptor(IN PSECURITY_DESCRIPTOR pSourceSecurityDescriptor
,
139 OUT PSECURITY_DESCRIPTOR pDestinationSecurityDescriptor
)
141 PSID Owner
= NULL
, Group
= NULL
;
142 PACL Dacl
= NULL
, Sacl
= NULL
;
143 BOOLEAN Defaulted
, Present
;
144 DWORD OwnerLength
, GroupLength
;
145 PISECURITY_DESCRIPTOR srcSD
= pSourceSecurityDescriptor
;
146 PISECURITY_DESCRIPTOR destSD
= pDestinationSecurityDescriptor
;
148 if (srcSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
149 return STATUS_UNKNOWN_REVISION
;
151 /* Copy non relative dependent data */
152 destSD
->Revision
= srcSD
->Revision
;
153 destSD
->Sbz1
= srcSD
->Sbz1
;
154 destSD
->Control
= srcSD
->Control
;
156 /* Read relative data */
157 RtlGetOwnerSecurityDescriptor(srcSD
, &Owner
, &Defaulted
);
158 OwnerLength
= RtlLengthSid(Owner
);
159 RtlGetGroupSecurityDescriptor(srcSD
, &Group
, &Defaulted
);
160 GroupLength
= RtlLengthSid(Group
);
161 RtlGetDaclSecurityDescriptor(srcSD
, &Present
, &Dacl
, &Defaulted
);
162 RtlGetSaclSecurityDescriptor(srcSD
, &Present
, &Sacl
, &Defaulted
);
164 if (srcSD
->Control
& SE_SELF_RELATIVE
)
166 destSD
->Owner
= srcSD
->Owner
;
167 RtlCopySid(OwnerLength
, (LPBYTE
)destSD
+ (DWORD_PTR
)destSD
->Owner
, Owner
);
169 destSD
->Group
= srcSD
->Group
;
170 RtlCopySid(GroupLength
, (LPBYTE
)destSD
+ (DWORD_PTR
)destSD
->Group
, Group
);
172 if (srcSD
->Control
& SE_DACL_PRESENT
)
174 destSD
->Dacl
= srcSD
->Dacl
;
176 if(srcSD
->Dacl
!= NULL
&& RtlValidAcl(srcSD
->Dacl
))
178 RtlCopyMemory(((LPBYTE
)destSD
+ (DWORD_PTR
)destSD
->Dacl
), Dacl
, Dacl
->AclSize
);
182 if (srcSD
->Control
& SE_SACL_PRESENT
)
184 destSD
->Sacl
= srcSD
->Sacl
;
186 if(srcSD
->Sacl
!= NULL
&& RtlValidAcl(srcSD
->Sacl
))
188 RtlCopyMemory(((LPBYTE
)destSD
+ (DWORD_PTR
)destSD
->Sacl
), Sacl
, Sacl
->AclSize
);
194 RtlCopySid(OwnerLength
, destSD
->Owner
, Owner
);
195 RtlCopySid(GroupLength
, destSD
->Group
, Group
);
197 if (srcSD
->Control
& SE_DACL_PRESENT
)
199 destSD
->Dacl
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Dacl
->AclSize
);
201 if(srcSD
->Dacl
!= NULL
&& RtlValidAcl(srcSD
->Dacl
))
203 RtlCopyMemory(destSD
->Dacl
, Dacl
, Dacl
->AclSize
);
207 if (srcSD
->Control
& SE_SACL_PRESENT
)
209 destSD
->Sacl
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Sacl
->AclSize
);
211 if(srcSD
->Sacl
!= NULL
&& RtlValidAcl(srcSD
->Sacl
))
213 RtlCopyMemory(destSD
->Sacl
, Sacl
, Sacl
->AclSize
);
218 return STATUS_SUCCESS
;
223 RtlCreateSecurityDescriptorRelative (OUT PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor
,
228 if (Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
230 return STATUS_UNKNOWN_REVISION
;
233 SecurityDescriptor
->Revision
= Revision
;
234 SecurityDescriptor
->Sbz1
= 0;
235 SecurityDescriptor
->Control
= SE_SELF_RELATIVE
;
236 SecurityDescriptor
->Owner
= 0;
237 SecurityDescriptor
->Group
= 0;
238 SecurityDescriptor
->Sacl
= 0;
239 SecurityDescriptor
->Dacl
= 0;
241 return STATUS_SUCCESS
;
249 RtlLengthSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
253 ULONG Length
= sizeof(SECURITY_DESCRIPTOR
);
257 RtlpQuerySecurityDescriptorPointers((PISECURITY_DESCRIPTOR
)SecurityDescriptor
,
265 Length
+= ROUND_UP(RtlLengthSid(Owner
), 4);
270 Length
+= ROUND_UP(RtlLengthSid(Group
), 4);
275 Length
+= ROUND_UP(Dacl
->AclSize
, 4);
280 Length
+= ROUND_UP(Sacl
->AclSize
, 4);
291 RtlGetDaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
292 OUT PBOOLEAN DaclPresent
,
294 OUT PBOOLEAN DaclDefaulted
)
296 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
300 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
302 return STATUS_UNKNOWN_REVISION
;
305 if (!(pSD
->Control
& SE_DACL_PRESENT
))
307 *DaclPresent
= FALSE
;
308 return STATUS_SUCCESS
;
312 RtlpQuerySecurityDescriptorPointers(pSD
,
318 *DaclDefaulted
= ((pSD
->Control
& SE_DACL_DEFAULTED
) ? TRUE
: FALSE
);
320 return STATUS_SUCCESS
;
328 RtlSetDaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
329 IN BOOLEAN DaclPresent
,
331 IN BOOLEAN DaclDefaulted
)
333 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
337 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
339 return STATUS_UNKNOWN_REVISION
;
342 if (pSD
->Control
& SE_SELF_RELATIVE
)
344 return STATUS_BAD_DESCRIPTOR_FORMAT
;
349 pSD
->Control
= pSD
->Control
& ~(SE_DACL_PRESENT
);
350 return STATUS_SUCCESS
;
354 pSD
->Control
|= SE_DACL_PRESENT
;
355 pSD
->Control
&= ~(SE_DACL_DEFAULTED
);
359 pSD
->Control
|= SE_DACL_DEFAULTED
;
362 return STATUS_SUCCESS
;
370 RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
372 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
378 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
383 RtlpQuerySecurityDescriptorPointers(pSD
,
389 if ((Owner
!= NULL
&& !RtlValidSid(Owner
)) ||
390 (Group
!= NULL
&& !RtlValidSid(Group
)) ||
391 (Sacl
!= NULL
&& !RtlValidAcl(Sacl
)) ||
392 (Dacl
!= NULL
&& !RtlValidAcl(Dacl
)))
405 RtlSetOwnerSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
407 IN BOOLEAN OwnerDefaulted
)
409 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
413 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
415 return STATUS_UNKNOWN_REVISION
;
418 if (pSD
->Control
& SE_SELF_RELATIVE
)
420 return STATUS_BAD_DESCRIPTOR_FORMAT
;
424 pSD
->Control
&= ~(SE_OWNER_DEFAULTED
);
428 pSD
->Control
|= SE_OWNER_DEFAULTED
;
431 return STATUS_SUCCESS
;
439 RtlGetOwnerSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
441 OUT PBOOLEAN OwnerDefaulted
)
443 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
447 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
449 return STATUS_UNKNOWN_REVISION
;
452 RtlpQuerySecurityDescriptorPointers(pSD
,
458 *OwnerDefaulted
= ((pSD
->Control
& SE_OWNER_DEFAULTED
) ? TRUE
: FALSE
);
460 return STATUS_SUCCESS
;
468 RtlSetGroupSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
470 IN BOOLEAN GroupDefaulted
)
472 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
476 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
478 return STATUS_UNKNOWN_REVISION
;
481 if (pSD
->Control
& SE_SELF_RELATIVE
)
483 return STATUS_BAD_DESCRIPTOR_FORMAT
;
487 pSD
->Control
&= ~(SE_GROUP_DEFAULTED
);
490 pSD
->Control
|= SE_GROUP_DEFAULTED
;
493 return STATUS_SUCCESS
;
501 RtlGetGroupSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
503 OUT PBOOLEAN GroupDefaulted
)
505 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
509 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
511 return STATUS_UNKNOWN_REVISION
;
514 RtlpQuerySecurityDescriptorPointers(pSD
,
520 *GroupDefaulted
= ((pSD
->Control
& SE_GROUP_DEFAULTED
) ? TRUE
: FALSE
);
522 return STATUS_SUCCESS
;
530 RtlMakeSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSD
,
531 OUT PSECURITY_DESCRIPTOR SelfRelativeSD
,
532 IN OUT PULONG BufferLength
)
544 PISECURITY_DESCRIPTOR pAbsSD
= (PISECURITY_DESCRIPTOR
)AbsoluteSD
;
545 PISECURITY_DESCRIPTOR_RELATIVE pRelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SelfRelativeSD
;
549 RtlpQuerySecurityDescriptor(pAbsSD
,
559 TotalLength
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
) + OwnerLength
+ GroupLength
+ SaclLength
+ DaclLength
;
560 if (*BufferLength
< TotalLength
)
562 *BufferLength
= TotalLength
;
563 return STATUS_BUFFER_TOO_SMALL
;
566 RtlZeroMemory(pRelSD
,
569 pRelSD
->Revision
= pAbsSD
->Revision
;
570 pRelSD
->Sbz1
= pAbsSD
->Sbz1
;
571 pRelSD
->Control
= pAbsSD
->Control
| SE_SELF_RELATIVE
;
573 Current
= (ULONG_PTR
)(pRelSD
+ 1);
577 RtlCopyMemory((PVOID
)Current
,
580 pRelSD
->Sacl
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)pRelSD
);
581 Current
+= SaclLength
;
586 RtlCopyMemory((PVOID
)Current
,
589 pRelSD
->Dacl
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)pRelSD
);
590 Current
+= DaclLength
;
593 if (OwnerLength
!= 0)
595 RtlCopyMemory((PVOID
)Current
,
598 pRelSD
->Owner
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)pRelSD
);
599 Current
+= OwnerLength
;
602 if (GroupLength
!= 0)
604 RtlCopyMemory((PVOID
)Current
,
607 pRelSD
->Group
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)pRelSD
);
610 return STATUS_SUCCESS
;
618 RtlAbsoluteToSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor
,
619 IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor
,
620 IN PULONG BufferLength
)
622 PISECURITY_DESCRIPTOR pAbsSD
= (PISECURITY_DESCRIPTOR
)AbsoluteSecurityDescriptor
;
626 if (pAbsSD
->Control
& SE_SELF_RELATIVE
)
628 return STATUS_BAD_DESCRIPTOR_FORMAT
;
631 return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor
,
632 SelfRelativeSecurityDescriptor
,
641 RtlGetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
642 OUT PSECURITY_DESCRIPTOR_CONTROL Control
,
645 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
649 *Revision
= pSD
->Revision
;
651 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
653 return STATUS_UNKNOWN_REVISION
;
656 *Control
= pSD
->Control
;
658 return STATUS_SUCCESS
;
666 RtlSetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
667 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest
,
668 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet
)
670 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
674 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
676 return STATUS_UNKNOWN_REVISION
;
679 /* Zero the 'bits of interest' */
680 pSD
->Control
&= ~ControlBitsOfInterest
;
682 /* Set the 'bits to set' */
683 pSD
->Control
|= (ControlBitsToSet
& ControlBitsOfInterest
);
685 return STATUS_SUCCESS
;
693 RtlGetSaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
694 OUT PBOOLEAN SaclPresent
,
696 OUT PBOOLEAN SaclDefaulted
)
698 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
702 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
704 return STATUS_UNKNOWN_REVISION
;
707 if (!(pSD
->Control
& SE_SACL_PRESENT
))
709 *SaclPresent
= FALSE
;
710 return STATUS_SUCCESS
;
714 RtlpQuerySecurityDescriptorPointers(pSD
,
720 *SaclDefaulted
= ((pSD
->Control
& SE_SACL_DEFAULTED
) ? TRUE
: FALSE
);
722 return STATUS_SUCCESS
;
730 RtlSetSaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
731 IN BOOLEAN SaclPresent
,
733 IN BOOLEAN SaclDefaulted
)
735 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
739 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
741 return STATUS_UNKNOWN_REVISION
;
744 if (pSD
->Control
& SE_SELF_RELATIVE
)
746 return STATUS_BAD_DESCRIPTOR_FORMAT
;
751 pSD
->Control
&= ~(SE_SACL_PRESENT
);
752 return STATUS_SUCCESS
;
756 pSD
->Control
|= SE_SACL_PRESENT
;
757 pSD
->Control
&= ~(SE_SACL_DEFAULTED
);
761 pSD
->Control
|= SE_SACL_DEFAULTED
;
764 return STATUS_SUCCESS
;
772 RtlSelfRelativeToAbsoluteSD(IN PSECURITY_DESCRIPTOR SelfRelativeSD
,
773 OUT PSECURITY_DESCRIPTOR AbsoluteSD
,
774 IN PULONG AbsoluteSDSize
,
781 IN PSID PrimaryGroup
,
782 IN PULONG PrimaryGroupSize
)
784 PISECURITY_DESCRIPTOR pAbsSD
= (PISECURITY_DESCRIPTOR
)AbsoluteSD
;
785 PISECURITY_DESCRIPTOR pRelSD
= (PISECURITY_DESCRIPTOR
)SelfRelativeSD
;
797 if (pRelSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
799 return STATUS_UNKNOWN_REVISION
;
802 if (!(pRelSD
->Control
& SE_SELF_RELATIVE
))
804 return STATUS_BAD_DESCRIPTOR_FORMAT
;
807 RtlpQuerySecurityDescriptor (pRelSD
,
817 if (OwnerLength
> *OwnerSize
||
818 GroupLength
> *PrimaryGroupSize
||
819 DaclLength
> *DaclSize
||
820 SaclLength
> *SaclSize
)
822 *OwnerSize
= OwnerLength
;
823 *PrimaryGroupSize
= GroupLength
;
824 *DaclSize
= DaclLength
;
825 *SaclSize
= SaclLength
;
826 return STATUS_BUFFER_TOO_SMALL
;
829 RtlCopyMemory (Owner
, pOwner
, OwnerLength
);
830 RtlCopyMemory (PrimaryGroup
, pGroup
, GroupLength
);
831 RtlCopyMemory (Dacl
, pDacl
, DaclLength
);
832 RtlCopyMemory (Sacl
, pSacl
, SaclLength
);
834 pAbsSD
->Revision
= pRelSD
->Revision
;
835 pAbsSD
->Sbz1
= pRelSD
->Sbz1
;
836 pAbsSD
->Control
= pRelSD
->Control
& ~SE_SELF_RELATIVE
;
837 pAbsSD
->Owner
= Owner
;
838 pAbsSD
->Group
= PrimaryGroup
;
842 *OwnerSize
= OwnerLength
;
843 *PrimaryGroupSize
= GroupLength
;
844 *DaclSize
= DaclLength
;
845 *SaclSize
= SaclLength
;
847 return STATUS_SUCCESS
;
855 RtlSelfRelativeToAbsoluteSD2(IN OUT PSECURITY_DESCRIPTOR SelfRelativeSD
,
856 OUT PULONG BufferSize
)
858 PISECURITY_DESCRIPTOR pAbsSD
= (PISECURITY_DESCRIPTOR
)SelfRelativeSD
;
859 PISECURITY_DESCRIPTOR_RELATIVE pRelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SelfRelativeSD
;
861 PVOID DataStart
, DataEnd
;
876 if (SelfRelativeSD
== NULL
)
878 return STATUS_INVALID_PARAMETER_1
;
880 if (BufferSize
== NULL
)
882 return STATUS_INVALID_PARAMETER_2
;
885 if (pRelSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
887 return STATUS_UNKNOWN_REVISION
;
889 if (!(pRelSD
->Control
& SE_SELF_RELATIVE
))
891 return STATUS_BAD_DESCRIPTOR_FORMAT
;
896 RtlpQuerySecurityDescriptor((PISECURITY_DESCRIPTOR
)pRelSD
,
906 /* calculate the start and end of the data area, we simply just move the
907 data by the difference between the size of the relative and absolute
908 security descriptor structure */
910 DataEnd
= (PVOID
)((ULONG_PTR
)pOwner
+ OwnerLength
);
913 if (((ULONG_PTR
)pGroup
< (ULONG_PTR
)DataStart
) || DataStart
== NULL
)
915 if (((ULONG_PTR
)pGroup
+ GroupLength
> (ULONG_PTR
)DataEnd
) || DataEnd
== NULL
)
916 DataEnd
= (PVOID
)((ULONG_PTR
)pGroup
+ GroupLength
);
920 if (((ULONG_PTR
)pDacl
< (ULONG_PTR
)DataStart
) || DataStart
== NULL
)
922 if (((ULONG_PTR
)pDacl
+ DaclLength
> (ULONG_PTR
)DataEnd
) || DataEnd
== NULL
)
923 DataEnd
= (PVOID
)((ULONG_PTR
)pDacl
+ DaclLength
);
927 if (((ULONG_PTR
)pSacl
< (ULONG_PTR
)DataStart
) || DataStart
== NULL
)
929 if (((ULONG_PTR
)pSacl
+ SaclLength
> (ULONG_PTR
)DataEnd
) || DataEnd
== NULL
)
930 DataEnd
= (PVOID
)((ULONG_PTR
)pSacl
+ SaclLength
);
933 ASSERT((ULONG_PTR
)DataEnd
>= (ULONG_PTR
)DataStart
);
935 DataSize
= (ULONG
)((ULONG_PTR
)DataEnd
- (ULONG_PTR
)DataStart
);
937 if (*BufferSize
< sizeof(SECURITY_DESCRIPTOR
) + DataSize
)
939 *BufferSize
= sizeof(SECURITY_DESCRIPTOR
) + DataSize
;
940 return STATUS_BUFFER_TOO_SMALL
;
945 /* if DataSize != 0 ther must be at least one SID or ACL in the security
946 descriptor! Also the data area must be located somewhere after the
947 end of the SECURITY_DESCRIPTOR_RELATIVE structure */
948 ASSERT(DataStart
!= NULL
);
949 ASSERT((ULONG_PTR
)DataStart
>= (ULONG_PTR
)(pRelSD
+ 1));
951 /* it's time to move the data */
952 RtlMoveMemory((PVOID
)(pAbsSD
+ 1),
956 MoveDelta
= (LONG
)((LONG_PTR
)(pAbsSD
+ 1) - (LONG_PTR
)DataStart
);
958 /* adjust the pointers if neccessary */
960 pAbsSD
->Owner
= (PSID
)((LONG_PTR
)pOwner
+ MoveDelta
);
962 pAbsSD
->Owner
= NULL
;
965 pAbsSD
->Group
= (PSID
)((LONG_PTR
)pGroup
+ MoveDelta
);
967 pAbsSD
->Group
= NULL
;
970 pAbsSD
->Sacl
= (PACL
)((LONG_PTR
)pSacl
+ MoveDelta
);
975 pAbsSD
->Dacl
= (PACL
)((LONG_PTR
)pDacl
+ MoveDelta
);
981 /* all pointers must be NULL! */
982 ASSERT(pOwner
== NULL
);
983 ASSERT(pGroup
== NULL
);
984 ASSERT(pSacl
== NULL
);
985 ASSERT(pDacl
== NULL
);
987 pAbsSD
->Owner
= NULL
;
988 pAbsSD
->Group
= NULL
;
993 /* clear the self-relative flag */
994 pAbsSD
->Control
&= ~SE_SELF_RELATIVE
;
998 RtlpQuerySecurityDescriptorPointers((PISECURITY_DESCRIPTOR
)pRelSD
,
1004 /* clear the self-relative flag and simply convert the offsets to pointers */
1005 pAbsSD
->Control
&= ~SE_SELF_RELATIVE
;
1006 pAbsSD
->Owner
= pOwner
;
1007 pAbsSD
->Group
= pGroup
;
1008 pAbsSD
->Sacl
= pSacl
;
1009 pAbsSD
->Dacl
= pDacl
;
1013 return STATUS_SUCCESS
;
1021 RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInput
,
1022 IN ULONG SecurityDescriptorLength
,
1023 IN SECURITY_INFORMATION RequiredInformation
)
1025 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptorInput
;
1029 if (SecurityDescriptorLength
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
) ||
1030 pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
||
1031 !(pSD
->Control
& SE_SELF_RELATIVE
))
1036 if (pSD
->Owner
!= 0)
1038 PSID Owner
= (PSID
)((ULONG_PTR
)pSD
->Owner
+ (ULONG_PTR
)pSD
);
1039 if (!RtlValidSid(Owner
))
1044 else if (RequiredInformation
& OWNER_SECURITY_INFORMATION
)
1049 if (pSD
->Group
!= 0)
1051 PSID Group
= (PSID
)((ULONG_PTR
)pSD
->Group
+ (ULONG_PTR
)pSD
);
1052 if (!RtlValidSid(Group
))
1057 else if (RequiredInformation
& GROUP_SECURITY_INFORMATION
)
1062 if (pSD
->Control
& SE_DACL_PRESENT
)
1064 if (pSD
->Dacl
!= 0 &&
1065 !RtlValidAcl((PACL
)((ULONG_PTR
)pSD
->Dacl
+ (ULONG_PTR
)pSD
)))
1070 else if (RequiredInformation
& DACL_SECURITY_INFORMATION
)
1075 if (pSD
->Control
& SE_SACL_PRESENT
)
1077 if (pSD
->Sacl
!= 0 &&
1078 !RtlValidAcl((PACL
)((ULONG_PTR
)pSD
->Sacl
+ (ULONG_PTR
)pSD
)))
1083 else if (RequiredInformation
& SACL_SECURITY_INFORMATION
)
1096 RtlGetSecurityDescriptorRMControl(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1097 OUT PUCHAR RMControl
)
1099 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
1103 if (!(pSD
->Control
& SE_RM_CONTROL_VALID
))
1109 *RMControl
= pSD
->Sbz1
;
1119 RtlSetSecurityDescriptorRMControl(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
1120 IN PUCHAR RMControl
)
1122 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
1126 if (RMControl
== NULL
)
1128 pSD
->Control
&= ~SE_RM_CONTROL_VALID
;
1133 pSD
->Control
|= SE_RM_CONTROL_VALID
;
1134 pSD
->Sbz1
= *RMControl
;
1143 RtlSetAttributesSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
1144 IN SECURITY_DESCRIPTOR_CONTROL Control
,
1145 OUT PULONG Revision
)
1147 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
1151 *Revision
= pSD
->Revision
;
1153 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
1154 return STATUS_UNKNOWN_REVISION
;
1157 ~(SE_OWNER_DEFAULTED
| SE_GROUP_DEFAULTED
| SE_DACL_PRESENT
|
1158 SE_DACL_DEFAULTED
| SE_SACL_PRESENT
| SE_SACL_DEFAULTED
|
1159 SE_RM_CONTROL_VALID
| SE_SELF_RELATIVE
);
1161 return RtlSetControlSecurityDescriptor(SecurityDescriptor
,