3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security descriptor functions
7 * PROGRAMER: David Welch <welch@cwcom.net>
9 * 26/07/98: Added stubs for security functions
12 /* INCLUDES *****************************************************************/
19 /* FUNCTIONS ***************************************************************/
23 RtlpQuerySecurityDescriptorPointers(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
24 OUT PSID
*Owner OPTIONAL
,
25 OUT PSID
*Group OPTIONAL
,
26 OUT PACL
*Sacl OPTIONAL
,
27 OUT PACL
*Dacl OPTIONAL
)
29 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
31 PSECURITY_DESCRIPTOR_RELATIVE RelSD
= (PSECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
34 *Owner
= ((RelSD
->Owner
!= 0) ? (PSID
)((ULONG_PTR
)RelSD
+ RelSD
->Owner
) : NULL
);
38 *Group
= ((RelSD
->Group
!= 0) ? (PSID
)((ULONG_PTR
)RelSD
+ RelSD
->Group
) : NULL
);
42 *Sacl
= (((RelSD
->Control
& SE_SACL_PRESENT
) && (RelSD
->Sacl
!= 0)) ?
43 (PSID
)((ULONG_PTR
)RelSD
+ RelSD
->Sacl
) : NULL
);
47 *Dacl
= (((RelSD
->Control
& SE_DACL_PRESENT
) && (RelSD
->Dacl
!= 0)) ?
48 (PSID
)((ULONG_PTR
)RelSD
+ RelSD
->Dacl
) : NULL
);
55 *Owner
= SecurityDescriptor
->Owner
;
59 *Group
= SecurityDescriptor
->Group
;
63 *Sacl
= ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) ? SecurityDescriptor
->Sacl
: NULL
);
67 *Dacl
= ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) ? SecurityDescriptor
->Dacl
: NULL
);
73 RtlpQuerySecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
,
83 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
91 *OwnerLength
= ((*Owner
!= NULL
) ? ROUND_UP(RtlLengthSid(*Owner
), 4) : 0);
96 *GroupLength
= ((*Group
!= NULL
) ? ROUND_UP(RtlLengthSid(*Group
), 4) : 0);
101 *DaclLength
= ((*Dacl
!= NULL
) ? ROUND_UP((*Dacl
)->AclSize
, 4) : 0);
106 *SaclLength
= ((*Sacl
!= NULL
) ? ROUND_UP((*Sacl
)->AclSize
, 4) : 0);
114 RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
,
119 if (Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
121 return STATUS_UNKNOWN_REVISION
;
124 SecurityDescriptor
->Revision
= Revision
;
125 SecurityDescriptor
->Sbz1
= 0;
126 SecurityDescriptor
->Control
= 0;
127 SecurityDescriptor
->Owner
= NULL
;
128 SecurityDescriptor
->Group
= NULL
;
129 SecurityDescriptor
->Sacl
= NULL
;
130 SecurityDescriptor
->Dacl
= NULL
;
132 return STATUS_SUCCESS
;
137 RtlCreateSecurityDescriptorRelative (PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor
,
142 if (Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
144 return STATUS_UNKNOWN_REVISION
;
147 SecurityDescriptor
->Revision
= Revision
;
148 SecurityDescriptor
->Sbz1
= 0;
149 SecurityDescriptor
->Control
= SE_SELF_RELATIVE
;
150 SecurityDescriptor
->Owner
= 0;
151 SecurityDescriptor
->Group
= 0;
152 SecurityDescriptor
->Sacl
= 0;
153 SecurityDescriptor
->Dacl
= 0;
155 return STATUS_SUCCESS
;
163 RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
)
167 ULONG Length
= sizeof(SECURITY_DESCRIPTOR
);
171 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
179 Length
+= ROUND_UP(RtlLengthSid(Owner
), 4);
184 Length
+= ROUND_UP(RtlLengthSid(Group
), 4);
189 Length
+= ROUND_UP(Dacl
->AclSize
, 4);
194 Length
+= ROUND_UP(Sacl
->AclSize
, 4);
205 RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
,
206 PBOOLEAN DaclPresent
,
208 PBOOLEAN DaclDefaulted
)
212 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
214 return STATUS_UNKNOWN_REVISION
;
217 if (!(SecurityDescriptor
->Control
& SE_DACL_PRESENT
))
219 *DaclPresent
= FALSE
;
220 return STATUS_SUCCESS
;
224 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
230 *DaclDefaulted
= ((SecurityDescriptor
->Control
& SE_DACL_DEFAULTED
) ? TRUE
: FALSE
);
232 return STATUS_SUCCESS
;
240 RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
,
243 BOOLEAN DaclDefaulted
)
247 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
249 return STATUS_UNKNOWN_REVISION
;
252 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
254 return STATUS_BAD_DESCRIPTOR_FORMAT
;
259 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_DACL_PRESENT
);
260 return STATUS_SUCCESS
;
263 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_DACL_PRESENT
;
264 SecurityDescriptor
->Dacl
= Dacl
;
265 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_DACL_DEFAULTED
);
269 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_DACL_DEFAULTED
;
272 return STATUS_SUCCESS
;
280 RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
)
287 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
292 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
298 if ((Owner
!= NULL
&& !RtlValidSid(Owner
)) ||
299 (Group
!= NULL
&& !RtlValidSid(Group
)) ||
300 (Sacl
!= NULL
&& !RtlValidAcl(Sacl
)) ||
301 (Dacl
!= NULL
&& !RtlValidAcl(Dacl
)))
314 RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
,
316 BOOLEAN OwnerDefaulted
)
320 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
322 return STATUS_UNKNOWN_REVISION
;
325 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
327 return STATUS_BAD_DESCRIPTOR_FORMAT
;
330 SecurityDescriptor
->Owner
= Owner
;
331 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_OWNER_DEFAULTED
);
335 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_OWNER_DEFAULTED
;
338 return STATUS_SUCCESS
;
346 RtlGetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
,
348 PBOOLEAN OwnerDefaulted
)
352 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
354 return STATUS_UNKNOWN_REVISION
;
357 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
363 *OwnerDefaulted
= ((SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
) ? TRUE
: FALSE
);
365 return STATUS_SUCCESS
;
373 RtlSetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
,
375 BOOLEAN GroupDefaulted
)
379 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
381 return STATUS_UNKNOWN_REVISION
;
384 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
386 return STATUS_BAD_DESCRIPTOR_FORMAT
;
389 SecurityDescriptor
->Group
= Group
;
390 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_GROUP_DEFAULTED
);
393 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_GROUP_DEFAULTED
;
396 return STATUS_SUCCESS
;
404 RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
,
406 PBOOLEAN GroupDefaulted
)
410 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
412 return STATUS_UNKNOWN_REVISION
;
415 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
421 *GroupDefaulted
= ((SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
) ? TRUE
: FALSE
);
423 return STATUS_SUCCESS
;
431 RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD
,
432 PSECURITY_DESCRIPTOR_RELATIVE RelSD
,
448 RtlpQuerySecurityDescriptor(AbsSD
,
458 TotalLength
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
) + OwnerLength
+ GroupLength
+ SaclLength
+ DaclLength
;
459 if (*BufferLength
< TotalLength
)
461 return STATUS_BUFFER_TOO_SMALL
;
467 RelSD
->Revision
= AbsSD
->Revision
;
468 RelSD
->Sbz1
= AbsSD
->Sbz1
;
469 RelSD
->Control
= AbsSD
->Control
| SE_SELF_RELATIVE
;
471 Current
= (ULONG_PTR
)(RelSD
+ 1);
475 RtlCopyMemory((PVOID
)Current
,
478 RelSD
->Sacl
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)RelSD
);
479 Current
+= SaclLength
;
484 RtlCopyMemory((PVOID
)Current
,
487 RelSD
->Dacl
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)RelSD
);
488 Current
+= DaclLength
;
491 if (OwnerLength
!= 0)
493 RtlCopyMemory((PVOID
)Current
,
496 RelSD
->Owner
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)RelSD
);
497 Current
+= OwnerLength
;
500 if (GroupLength
!= 0)
502 RtlCopyMemory((PVOID
)Current
,
505 RelSD
->Group
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)RelSD
);
508 return STATUS_SUCCESS
;
516 RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD
,
517 PSECURITY_DESCRIPTOR_RELATIVE RelSD
,
522 if (AbsSD
->Control
& SE_SELF_RELATIVE
)
524 return STATUS_BAD_DESCRIPTOR_FORMAT
;
527 return RtlMakeSelfRelativeSD(AbsSD
, RelSD
, BufferLength
);
535 RtlGetControlSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
,
536 PSECURITY_DESCRIPTOR_CONTROL Control
,
541 *Revision
= SecurityDescriptor
->Revision
;
543 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
545 return STATUS_UNKNOWN_REVISION
;
548 *Control
= SecurityDescriptor
->Control
;
550 return STATUS_SUCCESS
;
558 RtlSetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
559 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest
,
560 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet
)
564 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
566 return STATUS_UNKNOWN_REVISION
;
569 /* Zero the 'bits of interest' */
570 SecurityDescriptor
->Control
&= ~ControlBitsOfInterest
;
572 /* Set the 'bits to set' */
573 SecurityDescriptor
->Control
|= (ControlBitsToSet
& ControlBitsOfInterest
);
575 return STATUS_SUCCESS
;
583 RtlGetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
,
584 PBOOLEAN SaclPresent
,
586 PBOOLEAN SaclDefaulted
)
590 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
592 return STATUS_UNKNOWN_REVISION
;
595 if (!(SecurityDescriptor
->Control
& SE_SACL_PRESENT
))
597 *SaclPresent
= FALSE
;
598 return STATUS_SUCCESS
;
602 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor
,
608 *SaclDefaulted
= ((SecurityDescriptor
->Control
& SE_SACL_DEFAULTED
) ? TRUE
: FALSE
);
610 return STATUS_SUCCESS
;
618 RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
,
621 BOOLEAN SaclDefaulted
)
625 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
627 return STATUS_UNKNOWN_REVISION
;
630 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
632 return STATUS_BAD_DESCRIPTOR_FORMAT
;
637 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_SACL_PRESENT
);
638 return STATUS_SUCCESS
;
641 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_SACL_PRESENT
;
642 SecurityDescriptor
->Sacl
= Sacl
;
643 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
& ~(SE_SACL_DEFAULTED
);
647 SecurityDescriptor
->Control
= SecurityDescriptor
->Control
| SE_SACL_DEFAULTED
;
650 return STATUS_SUCCESS
;
658 RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR_RELATIVE RelSD
,
659 PSECURITY_DESCRIPTOR AbsSD
,
681 if (RelSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
683 return STATUS_UNKNOWN_REVISION
;
686 if (!(RelSD
->Control
& SE_SELF_RELATIVE
))
688 return STATUS_BAD_DESCRIPTOR_FORMAT
;
691 RtlpQuerySecurityDescriptor ((PSECURITY_DESCRIPTOR
)RelSD
,
701 if (OwnerLength
> *OwnerSize
||
702 GroupLength
> *GroupSize
||
703 DaclLength
> *DaclSize
||
704 SaclLength
> *SaclSize
)
706 return STATUS_BUFFER_TOO_SMALL
;
709 RtlCopyMemory (Owner
, pOwner
, OwnerLength
);
710 RtlCopyMemory (Group
, pGroup
, GroupLength
);
711 RtlCopyMemory (Dacl
, pDacl
, DaclLength
);
712 RtlCopyMemory (Sacl
, pSacl
, SaclLength
);
714 AbsSD
->Revision
= RelSD
->Revision
;
715 AbsSD
->Sbz1
= RelSD
->Sbz1
;
716 AbsSD
->Control
= RelSD
->Control
& ~SE_SELF_RELATIVE
;
717 AbsSD
->Owner
= Owner
;
718 AbsSD
->Group
= Group
;
722 *OwnerSize
= OwnerLength
;
723 *GroupSize
= GroupLength
;
724 *DaclSize
= DaclLength
;
725 *SaclSize
= SaclLength
;
727 return STATUS_SUCCESS
;
735 RtlSelfRelativeToAbsoluteSD2(PSECURITY_DESCRIPTOR_RELATIVE SelfRelativeSecurityDescriptor
,
739 return STATUS_NOT_IMPLEMENTED
;
747 RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptorInput
,
748 IN ULONG SecurityDescriptorLength
,
749 IN SECURITY_INFORMATION RequiredInformation
)
753 if (SecurityDescriptorLength
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
) ||
754 SecurityDescriptorInput
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
||
755 !(SecurityDescriptorInput
->Control
& SE_SELF_RELATIVE
))
760 if (SecurityDescriptorInput
->Owner
!= 0)
762 PSID Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptorInput
->Owner
+ (ULONG_PTR
)SecurityDescriptorInput
);
763 if (!RtlValidSid(Owner
))
768 else if (RequiredInformation
& OWNER_SECURITY_INFORMATION
)
773 if (SecurityDescriptorInput
->Group
!= 0)
775 PSID Group
= (PSID
)((ULONG_PTR
)SecurityDescriptorInput
->Group
+ (ULONG_PTR
)SecurityDescriptorInput
);
776 if (!RtlValidSid(Group
))
781 else if (RequiredInformation
& GROUP_SECURITY_INFORMATION
)
786 if (SecurityDescriptorInput
->Control
& SE_DACL_PRESENT
)
788 if (SecurityDescriptorInput
->Dacl
!= 0 &&
789 !RtlValidAcl((PACL
)((ULONG_PTR
)SecurityDescriptorInput
->Dacl
+ (ULONG_PTR
)SecurityDescriptorInput
)))
794 else if (RequiredInformation
& DACL_SECURITY_INFORMATION
)
799 if (SecurityDescriptorInput
->Control
& SE_SACL_PRESENT
)
801 if (SecurityDescriptorInput
->Sacl
!= 0 &&
802 !RtlValidAcl((PACL
)((ULONG_PTR
)SecurityDescriptorInput
->Sacl
+ (ULONG_PTR
)SecurityDescriptorInput
)))
807 else if (RequiredInformation
& SACL_SECURITY_INFORMATION
)
820 RtlGetSecurityDescriptorRMControl(PSECURITY_DESCRIPTOR SecurityDescriptor
,
825 if (!(SecurityDescriptor
->Control
& SE_RM_CONTROL_VALID
))
831 *RMControl
= SecurityDescriptor
->Sbz1
;
841 RtlSetSecurityDescriptorRMControl(PSECURITY_DESCRIPTOR SecurityDescriptor
,
846 if (RMControl
== NULL
)
848 SecurityDescriptor
->Control
&= ~SE_RM_CONTROL_VALID
;
849 SecurityDescriptor
->Sbz1
= 0;
853 SecurityDescriptor
->Control
|= SE_RM_CONTROL_VALID
;
854 SecurityDescriptor
->Sbz1
= *RMControl
;
863 RtlSetAttributesSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
864 IN SECURITY_DESCRIPTOR_CONTROL Control
,
869 *Revision
= SecurityDescriptor
->Revision
;
871 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
872 return STATUS_UNKNOWN_REVISION
;
875 ~(SE_OWNER_DEFAULTED
| SE_GROUP_DEFAULTED
| SE_DACL_PRESENT
|
876 SE_DACL_DEFAULTED
| SE_SACL_PRESENT
| SE_SACL_DEFAULTED
|
877 SE_RM_CONTROL_VALID
| SE_SELF_RELATIVE
);
879 return RtlSetControlSecurityDescriptor(SecurityDescriptor
,