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
= SECURITY_DESCRIPTOR_REVISION1
;
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
= SECURITY_DESCRIPTOR_REVISION1
;
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
)
257 if (((PISECURITY_DESCRIPTOR
)SecurityDescriptor
)->Control
& SE_SELF_RELATIVE
)
258 Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
260 Length
= sizeof(SECURITY_DESCRIPTOR
);
262 RtlpQuerySecurityDescriptorPointers((PISECURITY_DESCRIPTOR
)SecurityDescriptor
,
270 Length
+= ROUND_UP(RtlLengthSid(Owner
), 4);
275 Length
+= ROUND_UP(RtlLengthSid(Group
), 4);
280 Length
+= ROUND_UP(Dacl
->AclSize
, 4);
285 Length
+= ROUND_UP(Sacl
->AclSize
, 4);
296 RtlGetDaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
297 OUT PBOOLEAN DaclPresent
,
299 OUT PBOOLEAN DaclDefaulted
)
301 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
305 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
307 return STATUS_UNKNOWN_REVISION
;
310 if (!(pSD
->Control
& SE_DACL_PRESENT
))
312 *DaclPresent
= FALSE
;
313 return STATUS_SUCCESS
;
317 RtlpQuerySecurityDescriptorPointers(pSD
,
323 *DaclDefaulted
= ((pSD
->Control
& SE_DACL_DEFAULTED
) ? TRUE
: FALSE
);
325 return STATUS_SUCCESS
;
333 RtlSetDaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
334 IN BOOLEAN DaclPresent
,
336 IN BOOLEAN DaclDefaulted
)
338 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
342 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
344 return STATUS_UNKNOWN_REVISION
;
347 if (pSD
->Control
& SE_SELF_RELATIVE
)
349 return STATUS_BAD_DESCRIPTOR_FORMAT
;
354 pSD
->Control
= pSD
->Control
& ~(SE_DACL_PRESENT
);
355 return STATUS_SUCCESS
;
359 pSD
->Control
|= SE_DACL_PRESENT
;
360 pSD
->Control
&= ~(SE_DACL_DEFAULTED
);
364 pSD
->Control
|= SE_DACL_DEFAULTED
;
367 return STATUS_SUCCESS
;
375 RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
377 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
383 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
388 RtlpQuerySecurityDescriptorPointers(pSD
,
394 if ((Owner
!= NULL
&& !RtlValidSid(Owner
)) ||
395 (Group
!= NULL
&& !RtlValidSid(Group
)) ||
396 (Sacl
!= NULL
&& !RtlValidAcl(Sacl
)) ||
397 (Dacl
!= NULL
&& !RtlValidAcl(Dacl
)))
410 RtlSetOwnerSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
412 IN BOOLEAN OwnerDefaulted
)
414 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
418 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
420 return STATUS_UNKNOWN_REVISION
;
423 if (pSD
->Control
& SE_SELF_RELATIVE
)
425 return STATUS_BAD_DESCRIPTOR_FORMAT
;
429 pSD
->Control
&= ~(SE_OWNER_DEFAULTED
);
433 pSD
->Control
|= SE_OWNER_DEFAULTED
;
436 return STATUS_SUCCESS
;
444 RtlGetOwnerSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
446 OUT PBOOLEAN OwnerDefaulted
)
448 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
452 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
454 return STATUS_UNKNOWN_REVISION
;
457 RtlpQuerySecurityDescriptorPointers(pSD
,
463 *OwnerDefaulted
= ((pSD
->Control
& SE_OWNER_DEFAULTED
) ? TRUE
: FALSE
);
465 return STATUS_SUCCESS
;
473 RtlSetGroupSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
475 IN BOOLEAN GroupDefaulted
)
477 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
481 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
483 return STATUS_UNKNOWN_REVISION
;
486 if (pSD
->Control
& SE_SELF_RELATIVE
)
488 return STATUS_BAD_DESCRIPTOR_FORMAT
;
492 pSD
->Control
&= ~(SE_GROUP_DEFAULTED
);
495 pSD
->Control
|= SE_GROUP_DEFAULTED
;
498 return STATUS_SUCCESS
;
506 RtlGetGroupSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
508 OUT PBOOLEAN GroupDefaulted
)
510 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
514 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
516 return STATUS_UNKNOWN_REVISION
;
519 RtlpQuerySecurityDescriptorPointers(pSD
,
525 *GroupDefaulted
= ((pSD
->Control
& SE_GROUP_DEFAULTED
) ? TRUE
: FALSE
);
527 return STATUS_SUCCESS
;
535 RtlMakeSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSD
,
536 OUT PSECURITY_DESCRIPTOR SelfRelativeSD
,
537 IN OUT PULONG BufferLength
)
549 PISECURITY_DESCRIPTOR pAbsSD
= (PISECURITY_DESCRIPTOR
)AbsoluteSD
;
550 PISECURITY_DESCRIPTOR_RELATIVE pRelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SelfRelativeSD
;
554 RtlpQuerySecurityDescriptor(pAbsSD
,
564 TotalLength
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
) + OwnerLength
+ GroupLength
+ SaclLength
+ DaclLength
;
565 if (*BufferLength
< TotalLength
)
567 *BufferLength
= TotalLength
;
568 return STATUS_BUFFER_TOO_SMALL
;
571 RtlZeroMemory(pRelSD
,
574 pRelSD
->Revision
= pAbsSD
->Revision
;
575 pRelSD
->Sbz1
= pAbsSD
->Sbz1
;
576 pRelSD
->Control
= pAbsSD
->Control
| SE_SELF_RELATIVE
;
578 Current
= (ULONG_PTR
)(pRelSD
+ 1);
582 RtlCopyMemory((PVOID
)Current
,
585 pRelSD
->Sacl
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)pRelSD
);
586 Current
+= SaclLength
;
591 RtlCopyMemory((PVOID
)Current
,
594 pRelSD
->Dacl
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)pRelSD
);
595 Current
+= DaclLength
;
598 if (OwnerLength
!= 0)
600 RtlCopyMemory((PVOID
)Current
,
603 pRelSD
->Owner
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)pRelSD
);
604 Current
+= OwnerLength
;
607 if (GroupLength
!= 0)
609 RtlCopyMemory((PVOID
)Current
,
612 pRelSD
->Group
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)pRelSD
);
615 return STATUS_SUCCESS
;
623 RtlAbsoluteToSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor
,
624 IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor
,
625 IN PULONG BufferLength
)
627 PISECURITY_DESCRIPTOR pAbsSD
= (PISECURITY_DESCRIPTOR
)AbsoluteSecurityDescriptor
;
631 if (pAbsSD
->Control
& SE_SELF_RELATIVE
)
633 return STATUS_BAD_DESCRIPTOR_FORMAT
;
636 return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor
,
637 SelfRelativeSecurityDescriptor
,
646 RtlGetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
647 OUT PSECURITY_DESCRIPTOR_CONTROL Control
,
650 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
654 *Revision
= pSD
->Revision
;
656 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
658 return STATUS_UNKNOWN_REVISION
;
661 *Control
= pSD
->Control
;
663 return STATUS_SUCCESS
;
671 RtlSetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
672 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest
,
673 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet
)
675 SECURITY_DESCRIPTOR_CONTROL
const immutable
676 = SE_OWNER_DEFAULTED
| SE_GROUP_DEFAULTED
677 | SE_DACL_PRESENT
| SE_DACL_DEFAULTED
678 | SE_SACL_PRESENT
| SE_SACL_DEFAULTED
679 | SE_RM_CONTROL_VALID
| SE_SELF_RELATIVE
682 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
686 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
688 return STATUS_UNKNOWN_REVISION
;
691 if ((ControlBitsOfInterest
| ControlBitsToSet
) & immutable
)
692 return STATUS_INVALID_PARAMETER
;
694 /* Zero the 'bits of interest' */
695 pSD
->Control
&= ~ControlBitsOfInterest
;
697 /* Set the 'bits to set' */
698 pSD
->Control
|= (ControlBitsToSet
& ControlBitsOfInterest
);
700 return STATUS_SUCCESS
;
708 RtlGetSaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
709 OUT PBOOLEAN SaclPresent
,
711 OUT PBOOLEAN SaclDefaulted
)
713 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
717 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
719 return STATUS_UNKNOWN_REVISION
;
722 if (!(pSD
->Control
& SE_SACL_PRESENT
))
724 *SaclPresent
= FALSE
;
725 return STATUS_SUCCESS
;
729 RtlpQuerySecurityDescriptorPointers(pSD
,
735 *SaclDefaulted
= ((pSD
->Control
& SE_SACL_DEFAULTED
) ? TRUE
: FALSE
);
737 return STATUS_SUCCESS
;
745 RtlSetSaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
746 IN BOOLEAN SaclPresent
,
748 IN BOOLEAN SaclDefaulted
)
750 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
754 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
756 return STATUS_UNKNOWN_REVISION
;
759 if (pSD
->Control
& SE_SELF_RELATIVE
)
761 return STATUS_BAD_DESCRIPTOR_FORMAT
;
766 pSD
->Control
&= ~(SE_SACL_PRESENT
);
767 return STATUS_SUCCESS
;
771 pSD
->Control
|= SE_SACL_PRESENT
;
772 pSD
->Control
&= ~(SE_SACL_DEFAULTED
);
776 pSD
->Control
|= SE_SACL_DEFAULTED
;
779 return STATUS_SUCCESS
;
787 RtlSelfRelativeToAbsoluteSD(IN PSECURITY_DESCRIPTOR SelfRelativeSD
,
788 OUT PSECURITY_DESCRIPTOR AbsoluteSD
,
789 IN PULONG AbsoluteSDSize
,
796 IN PSID PrimaryGroup
,
797 IN PULONG PrimaryGroupSize
)
799 PISECURITY_DESCRIPTOR pAbsSD
= (PISECURITY_DESCRIPTOR
)AbsoluteSD
;
800 PISECURITY_DESCRIPTOR pRelSD
= (PISECURITY_DESCRIPTOR
)SelfRelativeSD
;
812 if (pRelSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
814 return STATUS_UNKNOWN_REVISION
;
817 if (!(pRelSD
->Control
& SE_SELF_RELATIVE
))
819 return STATUS_BAD_DESCRIPTOR_FORMAT
;
822 RtlpQuerySecurityDescriptor (pRelSD
,
832 if (OwnerLength
> *OwnerSize
||
833 GroupLength
> *PrimaryGroupSize
||
834 DaclLength
> *DaclSize
||
835 SaclLength
> *SaclSize
)
837 *OwnerSize
= OwnerLength
;
838 *PrimaryGroupSize
= GroupLength
;
839 *DaclSize
= DaclLength
;
840 *SaclSize
= SaclLength
;
841 return STATUS_BUFFER_TOO_SMALL
;
844 RtlCopyMemory (Owner
, pOwner
, OwnerLength
);
845 RtlCopyMemory (PrimaryGroup
, pGroup
, GroupLength
);
846 RtlCopyMemory (Dacl
, pDacl
, DaclLength
);
847 RtlCopyMemory (Sacl
, pSacl
, SaclLength
);
849 pAbsSD
->Revision
= pRelSD
->Revision
;
850 pAbsSD
->Sbz1
= pRelSD
->Sbz1
;
851 pAbsSD
->Control
= pRelSD
->Control
& ~SE_SELF_RELATIVE
;
852 pAbsSD
->Owner
= Owner
;
853 pAbsSD
->Group
= PrimaryGroup
;
857 *OwnerSize
= OwnerLength
;
858 *PrimaryGroupSize
= GroupLength
;
859 *DaclSize
= DaclLength
;
860 *SaclSize
= SaclLength
;
862 return STATUS_SUCCESS
;
870 RtlSelfRelativeToAbsoluteSD2(IN OUT PSECURITY_DESCRIPTOR SelfRelativeSD
,
871 OUT PULONG BufferSize
)
873 PISECURITY_DESCRIPTOR pAbsSD
= (PISECURITY_DESCRIPTOR
)SelfRelativeSD
;
874 PISECURITY_DESCRIPTOR_RELATIVE pRelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SelfRelativeSD
;
876 PVOID DataStart
, DataEnd
;
891 if (SelfRelativeSD
== NULL
)
893 return STATUS_INVALID_PARAMETER_1
;
895 if (BufferSize
== NULL
)
897 return STATUS_INVALID_PARAMETER_2
;
900 if (pRelSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
902 return STATUS_UNKNOWN_REVISION
;
904 if (!(pRelSD
->Control
& SE_SELF_RELATIVE
))
906 return STATUS_BAD_DESCRIPTOR_FORMAT
;
911 RtlpQuerySecurityDescriptor((PISECURITY_DESCRIPTOR
)pRelSD
,
921 /* calculate the start and end of the data area, we simply just move the
922 data by the difference between the size of the relative and absolute
923 security descriptor structure */
925 DataEnd
= (PVOID
)((ULONG_PTR
)pOwner
+ OwnerLength
);
928 if (((ULONG_PTR
)pGroup
< (ULONG_PTR
)DataStart
) || DataStart
== NULL
)
930 if (((ULONG_PTR
)pGroup
+ GroupLength
> (ULONG_PTR
)DataEnd
) || DataEnd
== NULL
)
931 DataEnd
= (PVOID
)((ULONG_PTR
)pGroup
+ GroupLength
);
935 if (((ULONG_PTR
)pDacl
< (ULONG_PTR
)DataStart
) || DataStart
== NULL
)
937 if (((ULONG_PTR
)pDacl
+ DaclLength
> (ULONG_PTR
)DataEnd
) || DataEnd
== NULL
)
938 DataEnd
= (PVOID
)((ULONG_PTR
)pDacl
+ DaclLength
);
942 if (((ULONG_PTR
)pSacl
< (ULONG_PTR
)DataStart
) || DataStart
== NULL
)
944 if (((ULONG_PTR
)pSacl
+ SaclLength
> (ULONG_PTR
)DataEnd
) || DataEnd
== NULL
)
945 DataEnd
= (PVOID
)((ULONG_PTR
)pSacl
+ SaclLength
);
948 ASSERT((ULONG_PTR
)DataEnd
>= (ULONG_PTR
)DataStart
);
950 DataSize
= (ULONG
)((ULONG_PTR
)DataEnd
- (ULONG_PTR
)DataStart
);
952 if (*BufferSize
< sizeof(SECURITY_DESCRIPTOR
) + DataSize
)
954 *BufferSize
= sizeof(SECURITY_DESCRIPTOR
) + DataSize
;
955 return STATUS_BUFFER_TOO_SMALL
;
960 /* if DataSize != 0 ther must be at least one SID or ACL in the security
961 descriptor! Also the data area must be located somewhere after the
962 end of the SECURITY_DESCRIPTOR_RELATIVE structure */
963 ASSERT(DataStart
!= NULL
);
964 ASSERT((ULONG_PTR
)DataStart
>= (ULONG_PTR
)(pRelSD
+ 1));
966 /* it's time to move the data */
967 RtlMoveMemory((PVOID
)(pAbsSD
+ 1),
971 MoveDelta
= (LONG
)((LONG_PTR
)(pAbsSD
+ 1) - (LONG_PTR
)DataStart
);
973 /* adjust the pointers if neccessary */
975 pAbsSD
->Owner
= (PSID
)((LONG_PTR
)pOwner
+ MoveDelta
);
977 pAbsSD
->Owner
= NULL
;
980 pAbsSD
->Group
= (PSID
)((LONG_PTR
)pGroup
+ MoveDelta
);
982 pAbsSD
->Group
= NULL
;
985 pAbsSD
->Sacl
= (PACL
)((LONG_PTR
)pSacl
+ MoveDelta
);
990 pAbsSD
->Dacl
= (PACL
)((LONG_PTR
)pDacl
+ MoveDelta
);
996 /* all pointers must be NULL! */
997 ASSERT(pOwner
== NULL
);
998 ASSERT(pGroup
== NULL
);
999 ASSERT(pSacl
== NULL
);
1000 ASSERT(pDacl
== NULL
);
1002 pAbsSD
->Owner
= NULL
;
1003 pAbsSD
->Group
= NULL
;
1004 pAbsSD
->Sacl
= NULL
;
1005 pAbsSD
->Dacl
= NULL
;
1008 /* clear the self-relative flag */
1009 pAbsSD
->Control
&= ~SE_SELF_RELATIVE
;
1013 RtlpQuerySecurityDescriptorPointers((PISECURITY_DESCRIPTOR
)pRelSD
,
1019 /* clear the self-relative flag and simply convert the offsets to pointers */
1020 pAbsSD
->Control
&= ~SE_SELF_RELATIVE
;
1021 pAbsSD
->Owner
= pOwner
;
1022 pAbsSD
->Group
= pGroup
;
1023 pAbsSD
->Sacl
= pSacl
;
1024 pAbsSD
->Dacl
= pDacl
;
1028 return STATUS_SUCCESS
;
1036 RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInput
,
1037 IN ULONG SecurityDescriptorLength
,
1038 IN SECURITY_INFORMATION RequiredInformation
)
1040 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptorInput
;
1044 if (SecurityDescriptorLength
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
) ||
1045 pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
||
1046 !(pSD
->Control
& SE_SELF_RELATIVE
))
1051 if (pSD
->Owner
!= 0)
1053 PSID Owner
= (PSID
)((ULONG_PTR
)pSD
->Owner
+ (ULONG_PTR
)pSD
);
1054 if (!RtlValidSid(Owner
))
1059 else if (RequiredInformation
& OWNER_SECURITY_INFORMATION
)
1064 if (pSD
->Group
!= 0)
1066 PSID Group
= (PSID
)((ULONG_PTR
)pSD
->Group
+ (ULONG_PTR
)pSD
);
1067 if (!RtlValidSid(Group
))
1072 else if (RequiredInformation
& GROUP_SECURITY_INFORMATION
)
1077 if (pSD
->Control
& SE_DACL_PRESENT
)
1079 if (pSD
->Dacl
!= 0 &&
1080 !RtlValidAcl((PACL
)((ULONG_PTR
)pSD
->Dacl
+ (ULONG_PTR
)pSD
)))
1085 else if (RequiredInformation
& DACL_SECURITY_INFORMATION
)
1090 if (pSD
->Control
& SE_SACL_PRESENT
)
1092 if (pSD
->Sacl
!= 0 &&
1093 !RtlValidAcl((PACL
)((ULONG_PTR
)pSD
->Sacl
+ (ULONG_PTR
)pSD
)))
1098 else if (RequiredInformation
& SACL_SECURITY_INFORMATION
)
1111 RtlGetSecurityDescriptorRMControl(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1112 OUT PUCHAR RMControl
)
1114 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
1118 if (!(pSD
->Control
& SE_RM_CONTROL_VALID
))
1124 *RMControl
= pSD
->Sbz1
;
1134 RtlSetSecurityDescriptorRMControl(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
1135 IN PUCHAR RMControl
)
1137 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
1141 if (RMControl
== NULL
)
1143 pSD
->Control
&= ~SE_RM_CONTROL_VALID
;
1148 pSD
->Control
|= SE_RM_CONTROL_VALID
;
1149 pSD
->Sbz1
= *RMControl
;
1158 RtlSetAttributesSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
1159 IN SECURITY_DESCRIPTOR_CONTROL Control
,
1160 OUT PULONG Revision
)
1162 PISECURITY_DESCRIPTOR pSD
= (PISECURITY_DESCRIPTOR
)SecurityDescriptor
;
1166 *Revision
= pSD
->Revision
;
1168 if (pSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
1169 return STATUS_UNKNOWN_REVISION
;
1172 ~(SE_OWNER_DEFAULTED
| SE_GROUP_DEFAULTED
| SE_DACL_PRESENT
|
1173 SE_DACL_DEFAULTED
| SE_SACL_PRESENT
| SE_SACL_DEFAULTED
|
1174 SE_RM_CONTROL_VALID
| SE_SELF_RELATIVE
);
1176 return RtlSetControlSecurityDescriptor(SecurityDescriptor
,