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(PSECURITY_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(PISECURITY_DESCRIPTOR SecurityDescriptor
,
116 if (Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
118 return STATUS_UNKNOWN_REVISION
;
121 SecurityDescriptor
->Revision
= Revision
;
122 SecurityDescriptor
->Sbz1
= 0;
123 SecurityDescriptor
->Control
= 0;
124 SecurityDescriptor
->Owner
= NULL
;
125 SecurityDescriptor
->Group
= NULL
;
126 SecurityDescriptor
->Sacl
= NULL
;
127 SecurityDescriptor
->Dacl
= NULL
;
129 return STATUS_SUCCESS
;
134 RtlCreateSecurityDescriptorRelative (PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor
,
139 if (Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
141 return STATUS_UNKNOWN_REVISION
;
144 SecurityDescriptor
->Revision
= Revision
;
145 SecurityDescriptor
->Sbz1
= 0;
146 SecurityDescriptor
->Control
= SE_SELF_RELATIVE
;
147 SecurityDescriptor
->Owner
= 0;
148 SecurityDescriptor
->Group
= 0;
149 SecurityDescriptor
->Sacl
= 0;
150 SecurityDescriptor
->Dacl
= 0;
152 return STATUS_SUCCESS
;
160 RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
)
164 ULONG Length
= sizeof(SECURITY_DESCRIPTOR
);
168 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
176 Length
+= ROUND_UP(RtlLengthSid(Owner
), 4);
181 Length
+= ROUND_UP(RtlLengthSid(Group
), 4);
186 Length
+= ROUND_UP(Dacl
->AclSize
, 4);
191 Length
+= ROUND_UP(Sacl
->AclSize
, 4);
202 RtlGetDaclSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor
,
203 PBOOLEAN DaclPresent
,
205 PBOOLEAN DaclDefaulted
)
209 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
211 return STATUS_UNKNOWN_REVISION
;
214 if (!(SecurityDescriptor
->Control
& SE_DACL_PRESENT
))
216 *DaclPresent
= FALSE
;
217 return STATUS_SUCCESS
;
221 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
227 *DaclDefaulted
= ((SecurityDescriptor
->Control
& SE_DACL_DEFAULTED
) ? TRUE
: FALSE
);
229 return STATUS_SUCCESS
;
237 RtlSetDaclSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor
,
240 BOOLEAN DaclDefaulted
)
244 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
246 return STATUS_UNKNOWN_REVISION
;
249 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
251 return STATUS_BAD_DESCRIPTOR_FORMAT
;
256 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_DACL_PRESENT
);
257 return STATUS_SUCCESS
;
260 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_DACL_PRESENT
;
261 SecurityDescriptor
->Dacl
= Dacl
;
262 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_DACL_DEFAULTED
);
266 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_DACL_DEFAULTED
;
269 return STATUS_SUCCESS
;
277 RtlValidSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor
)
284 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
289 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
295 if ((Owner
!= NULL
&& !RtlValidSid(Owner
)) ||
296 (Group
!= NULL
&& !RtlValidSid(Group
)) ||
297 (Sacl
!= NULL
&& !RtlValidAcl(Sacl
)) ||
298 (Dacl
!= NULL
&& !RtlValidAcl(Dacl
)))
311 RtlSetOwnerSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor
,
313 BOOLEAN OwnerDefaulted
)
317 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
319 return STATUS_UNKNOWN_REVISION
;
322 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
324 return STATUS_BAD_DESCRIPTOR_FORMAT
;
327 SecurityDescriptor
->Owner
= Owner
;
328 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_OWNER_DEFAULTED
);
332 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_OWNER_DEFAULTED
;
335 return STATUS_SUCCESS
;
343 RtlGetOwnerSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor
,
345 PBOOLEAN OwnerDefaulted
)
349 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
351 return STATUS_UNKNOWN_REVISION
;
354 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
360 *OwnerDefaulted
= ((SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
) ? TRUE
: FALSE
);
362 return STATUS_SUCCESS
;
370 RtlSetGroupSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor
,
372 BOOLEAN GroupDefaulted
)
376 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
378 return STATUS_UNKNOWN_REVISION
;
381 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
383 return STATUS_BAD_DESCRIPTOR_FORMAT
;
386 SecurityDescriptor
->Group
= Group
;
387 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_GROUP_DEFAULTED
);
390 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_GROUP_DEFAULTED
;
393 return STATUS_SUCCESS
;
401 RtlGetGroupSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor
,
403 PBOOLEAN GroupDefaulted
)
407 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
409 return STATUS_UNKNOWN_REVISION
;
412 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
418 *GroupDefaulted
= ((SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
) ? TRUE
: FALSE
);
420 return STATUS_SUCCESS
;
428 RtlMakeSelfRelativeSD(PISECURITY_DESCRIPTOR AbsSD
,
429 PISECURITY_DESCRIPTOR_RELATIVE RelSD
,
445 RtlpQuerySecurityDescriptor(AbsSD
,
455 TotalLength
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
) + OwnerLength
+ GroupLength
+ SaclLength
+ DaclLength
;
456 if (*BufferLength
< TotalLength
)
458 return STATUS_BUFFER_TOO_SMALL
;
464 RelSD
->Revision
= AbsSD
->Revision
;
465 RelSD
->Sbz1
= AbsSD
->Sbz1
;
466 RelSD
->Control
= AbsSD
->Control
| SE_SELF_RELATIVE
;
468 Current
= (ULONG_PTR
)(RelSD
+ 1);
472 RtlCopyMemory((PVOID
)Current
,
475 RelSD
->Sacl
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)RelSD
);
476 Current
+= SaclLength
;
481 RtlCopyMemory((PVOID
)Current
,
484 RelSD
->Dacl
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)RelSD
);
485 Current
+= DaclLength
;
488 if (OwnerLength
!= 0)
490 RtlCopyMemory((PVOID
)Current
,
493 RelSD
->Owner
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)RelSD
);
494 Current
+= OwnerLength
;
497 if (GroupLength
!= 0)
499 RtlCopyMemory((PVOID
)Current
,
502 RelSD
->Group
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)RelSD
);
505 return STATUS_SUCCESS
;
513 RtlAbsoluteToSelfRelativeSD(PISECURITY_DESCRIPTOR AbsSD
,
514 PISECURITY_DESCRIPTOR RelSD
,
519 if (AbsSD
->Control
& SE_SELF_RELATIVE
)
521 return STATUS_BAD_DESCRIPTOR_FORMAT
;
524 return RtlMakeSelfRelativeSD(AbsSD
, (PISECURITY_DESCRIPTOR_RELATIVE
)RelSD
, BufferLength
);
532 RtlGetControlSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor
,
533 PSECURITY_DESCRIPTOR_CONTROL Control
,
538 *Revision
= SecurityDescriptor
->Revision
;
540 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
542 return STATUS_UNKNOWN_REVISION
;
545 *Control
= SecurityDescriptor
->Control
;
547 return STATUS_SUCCESS
;
555 RtlSetControlSecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptor
,
556 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest
,
557 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet
)
561 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
563 return STATUS_UNKNOWN_REVISION
;
566 /* Zero the 'bits of interest' */
567 SecurityDescriptor
->Control
&= ~ControlBitsOfInterest
;
569 /* Set the 'bits to set' */
570 SecurityDescriptor
->Control
|= (ControlBitsToSet
& ControlBitsOfInterest
);
572 return STATUS_SUCCESS
;
580 RtlGetSaclSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor
,
581 PBOOLEAN SaclPresent
,
583 PBOOLEAN SaclDefaulted
)
587 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
589 return STATUS_UNKNOWN_REVISION
;
592 if (!(SecurityDescriptor
->Control
& SE_SACL_PRESENT
))
594 *SaclPresent
= FALSE
;
595 return STATUS_SUCCESS
;
599 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
605 *SaclDefaulted
= ((SecurityDescriptor
->Control
& SE_SACL_DEFAULTED
) ? TRUE
: FALSE
);
607 return STATUS_SUCCESS
;
615 RtlSetSaclSecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor
,
618 BOOLEAN SaclDefaulted
)
622 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
624 return STATUS_UNKNOWN_REVISION
;
627 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
629 return STATUS_BAD_DESCRIPTOR_FORMAT
;
634 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_SACL_PRESENT
);
635 return STATUS_SUCCESS
;
638 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_SACL_PRESENT
;
639 SecurityDescriptor
->Sacl
= Sacl
;
640 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_SACL_DEFAULTED
);
644 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_SACL_DEFAULTED
;
647 return STATUS_SUCCESS
;
655 RtlSelfRelativeToAbsoluteSD(PISECURITY_DESCRIPTOR RelSD
,
656 PISECURITY_DESCRIPTOR AbsSD
,
678 if (RelSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
680 return STATUS_UNKNOWN_REVISION
;
683 if (!(RelSD
->Control
& SE_SELF_RELATIVE
))
685 return STATUS_BAD_DESCRIPTOR_FORMAT
;
688 RtlpQuerySecurityDescriptor (RelSD
,
698 if (OwnerLength
> *OwnerSize
||
699 GroupLength
> *GroupSize
||
700 DaclLength
> *DaclSize
||
701 SaclLength
> *SaclSize
)
703 return STATUS_BUFFER_TOO_SMALL
;
706 RtlCopyMemory (Owner
, pOwner
, OwnerLength
);
707 RtlCopyMemory (Group
, pGroup
, GroupLength
);
708 RtlCopyMemory (Dacl
, pDacl
, DaclLength
);
709 RtlCopyMemory (Sacl
, pSacl
, SaclLength
);
711 AbsSD
->Revision
= RelSD
->Revision
;
712 AbsSD
->Sbz1
= RelSD
->Sbz1
;
713 AbsSD
->Control
= RelSD
->Control
& ~SE_SELF_RELATIVE
;
714 AbsSD
->Owner
= Owner
;
715 AbsSD
->Group
= Group
;
719 *OwnerSize
= OwnerLength
;
720 *GroupSize
= GroupLength
;
721 *DaclSize
= DaclLength
;
722 *SaclSize
= SaclLength
;
724 return STATUS_SUCCESS
;
732 RtlSelfRelativeToAbsoluteSD2(PISECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor
,
736 return STATUS_NOT_IMPLEMENTED
;
744 RtlValidRelativeSecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptorInput
,
745 IN ULONG SecurityDescriptorLength
,
746 IN SECURITY_INFORMATION RequiredInformation
)
750 if (SecurityDescriptorLength
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
) ||
751 SecurityDescriptorInput
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
||
752 !(SecurityDescriptorInput
->Control
& SE_SELF_RELATIVE
))
757 if (SecurityDescriptorInput
->Owner
!= 0)
759 PSID Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptorInput
->Owner
+ (ULONG_PTR
)SecurityDescriptorInput
);
760 if (!RtlValidSid(Owner
))
765 else if (RequiredInformation
& OWNER_SECURITY_INFORMATION
)
770 if (SecurityDescriptorInput
->Group
!= 0)
772 PSID Group
= (PSID
)((ULONG_PTR
)SecurityDescriptorInput
->Group
+ (ULONG_PTR
)SecurityDescriptorInput
);
773 if (!RtlValidSid(Group
))
778 else if (RequiredInformation
& GROUP_SECURITY_INFORMATION
)
783 if (SecurityDescriptorInput
->Control
& SE_DACL_PRESENT
)
785 if (SecurityDescriptorInput
->Dacl
!= 0 &&
786 !RtlValidAcl((PACL
)((ULONG_PTR
)SecurityDescriptorInput
->Dacl
+ (ULONG_PTR
)SecurityDescriptorInput
)))
791 else if (RequiredInformation
& DACL_SECURITY_INFORMATION
)
796 if (SecurityDescriptorInput
->Control
& SE_SACL_PRESENT
)
798 if (SecurityDescriptorInput
->Sacl
!= 0 &&
799 !RtlValidAcl((PACL
)((ULONG_PTR
)SecurityDescriptorInput
->Sacl
+ (ULONG_PTR
)SecurityDescriptorInput
)))
804 else if (RequiredInformation
& SACL_SECURITY_INFORMATION
)
817 RtlGetSecurityDescriptorRMControl(PISECURITY_DESCRIPTOR SecurityDescriptor
,
822 if (!(SecurityDescriptor
->Control
& SE_RM_CONTROL_VALID
))
828 *RMControl
= SecurityDescriptor
->Sbz1
;
838 RtlSetSecurityDescriptorRMControl(PISECURITY_DESCRIPTOR SecurityDescriptor
,
843 if (RMControl
== NULL
)
845 SecurityDescriptor
->Control
&= ~SE_RM_CONTROL_VALID
;
846 SecurityDescriptor
->Sbz1
= 0;
850 SecurityDescriptor
->Control
|= SE_RM_CONTROL_VALID
;
851 SecurityDescriptor
->Sbz1
= *RMControl
;
860 RtlSetAttributesSecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptor
,
861 IN SECURITY_DESCRIPTOR_CONTROL Control
,
866 *Revision
= SecurityDescriptor
->Revision
;
868 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
869 return STATUS_UNKNOWN_REVISION
;
872 ~(SE_OWNER_DEFAULTED
| SE_GROUP_DEFAULTED
| SE_DACL_PRESENT
|
873 SE_DACL_DEFAULTED
| SE_SACL_PRESENT
| SE_SACL_DEFAULTED
|
874 SE_RM_CONTROL_VALID
| SE_SELF_RELATIVE
);
876 return RtlSetControlSecurityDescriptor(SecurityDescriptor
,