2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/se/sd.c
5 * PURPOSE: Security manager
7 * PROGRAMMERS: David Welch <welch@cwcom.net>
10 /* INCLUDES *******************************************************************/
16 #if defined (ALLOC_PRAGMA)
17 #pragma alloc_text(INIT, SepInitSDs)
20 /* GLOBALS ********************************************************************/
22 PSECURITY_DESCRIPTOR SePublicDefaultSd
= NULL
;
23 PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd
= NULL
;
24 PSECURITY_DESCRIPTOR SePublicOpenSd
= NULL
;
25 PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd
= NULL
;
26 PSECURITY_DESCRIPTOR SeSystemDefaultSd
= NULL
;
27 PSECURITY_DESCRIPTOR SeUnrestrictedSd
= NULL
;
29 /* PRIVATE FUNCTIONS **********************************************************/
33 SepGetGroupFromDescriptor(PVOID _Descriptor
)
35 PISECURITY_DESCRIPTOR Descriptor
= (PISECURITY_DESCRIPTOR
)_Descriptor
;
36 PISECURITY_DESCRIPTOR_RELATIVE SdRel
;
38 if (Descriptor
->Control
& SE_SELF_RELATIVE
)
40 SdRel
= (PISECURITY_DESCRIPTOR_RELATIVE
)Descriptor
;
41 if (!SdRel
->Group
) return NULL
;
42 return (PSID
)((ULONG_PTR
)Descriptor
+ SdRel
->Group
);
46 return Descriptor
->Group
;
52 SepGetOwnerFromDescriptor(PVOID _Descriptor
)
54 PISECURITY_DESCRIPTOR Descriptor
= (PISECURITY_DESCRIPTOR
)_Descriptor
;
55 PISECURITY_DESCRIPTOR_RELATIVE SdRel
;
57 if (Descriptor
->Control
& SE_SELF_RELATIVE
)
59 SdRel
= (PISECURITY_DESCRIPTOR_RELATIVE
)Descriptor
;
60 if (!SdRel
->Owner
) return NULL
;
61 return (PSID
)((ULONG_PTR
)Descriptor
+ SdRel
->Owner
);
65 return Descriptor
->Owner
;
71 SepGetDaclFromDescriptor(PVOID _Descriptor
)
73 PISECURITY_DESCRIPTOR Descriptor
= (PISECURITY_DESCRIPTOR
)_Descriptor
;
74 PISECURITY_DESCRIPTOR_RELATIVE SdRel
;
76 if (Descriptor
->Control
& SE_SELF_RELATIVE
)
78 SdRel
= (PISECURITY_DESCRIPTOR_RELATIVE
)Descriptor
;
79 if (!SdRel
->Dacl
) return NULL
;
80 return (PACL
)((ULONG_PTR
)Descriptor
+ SdRel
->Dacl
);
84 return Descriptor
->Dacl
;
90 SepGetSaclFromDescriptor(PVOID _Descriptor
)
92 PISECURITY_DESCRIPTOR Descriptor
= (PISECURITY_DESCRIPTOR
)_Descriptor
;
93 PISECURITY_DESCRIPTOR_RELATIVE SdRel
;
95 if (Descriptor
->Control
& SE_SELF_RELATIVE
)
97 SdRel
= (PISECURITY_DESCRIPTOR_RELATIVE
)Descriptor
;
98 if (!SdRel
->Sacl
) return NULL
;
99 return (PACL
)((ULONG_PTR
)Descriptor
+ SdRel
->Sacl
);
103 return Descriptor
->Sacl
;
112 /* Create PublicDefaultSd */
113 SePublicDefaultSd
= ExAllocatePoolWithTag(PagedPool
,
114 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
115 if (SePublicDefaultSd
== NULL
)
118 RtlCreateSecurityDescriptor(SePublicDefaultSd
,
119 SECURITY_DESCRIPTOR_REVISION
);
120 RtlSetDaclSecurityDescriptor(SePublicDefaultSd
,
125 /* Create PublicDefaultUnrestrictedSd */
126 SePublicDefaultUnrestrictedSd
= ExAllocatePoolWithTag(PagedPool
,
127 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
128 if (SePublicDefaultUnrestrictedSd
== NULL
)
131 RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd
,
132 SECURITY_DESCRIPTOR_REVISION
);
133 RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd
,
135 SePublicDefaultUnrestrictedDacl
,
138 /* Create PublicOpenSd */
139 SePublicOpenSd
= ExAllocatePoolWithTag(PagedPool
,
140 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
141 if (SePublicOpenSd
== NULL
)
144 RtlCreateSecurityDescriptor(SePublicOpenSd
,
145 SECURITY_DESCRIPTOR_REVISION
);
146 RtlSetDaclSecurityDescriptor(SePublicOpenSd
,
151 /* Create PublicOpenUnrestrictedSd */
152 SePublicOpenUnrestrictedSd
= ExAllocatePoolWithTag(PagedPool
,
153 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
154 if (SePublicOpenUnrestrictedSd
== NULL
)
157 RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd
,
158 SECURITY_DESCRIPTOR_REVISION
);
159 RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd
,
161 SePublicOpenUnrestrictedDacl
,
164 /* Create SystemDefaultSd */
165 SeSystemDefaultSd
= ExAllocatePoolWithTag(PagedPool
,
166 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
167 if (SeSystemDefaultSd
== NULL
)
170 RtlCreateSecurityDescriptor(SeSystemDefaultSd
,
171 SECURITY_DESCRIPTOR_REVISION
);
172 RtlSetDaclSecurityDescriptor(SeSystemDefaultSd
,
177 /* Create UnrestrictedSd */
178 SeUnrestrictedSd
= ExAllocatePoolWithTag(PagedPool
,
179 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
180 if (SeUnrestrictedSd
== NULL
)
183 RtlCreateSecurityDescriptor(SeUnrestrictedSd
,
184 SECURITY_DESCRIPTOR_REVISION
);
185 RtlSetDaclSecurityDescriptor(SeUnrestrictedSd
,
195 SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation
,
196 PISECURITY_DESCRIPTOR SecurityDescriptor
,
203 PISECURITY_DESCRIPTOR_RELATIVE SdRel
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
205 DPRINT("SeSetWorldSecurityDescriptor() called\n");
207 if (SecurityInformation
== 0)
209 return STATUS_ACCESS_DENIED
;
212 /* calculate the minimum size of the buffer */
213 SidSize
= RtlLengthSid(SeWorldSid
);
214 SdSize
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
215 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
217 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
219 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
221 SdSize
+= sizeof(ACL
) + sizeof(ACE
) + SidSize
;
224 if (*BufferLength
< SdSize
)
226 *BufferLength
= SdSize
;
227 return STATUS_BUFFER_TOO_SMALL
;
230 *BufferLength
= SdSize
;
232 Status
= RtlCreateSecurityDescriptorRelative(SdRel
,
233 SECURITY_DESCRIPTOR_REVISION
);
234 if (!NT_SUCCESS(Status
))
239 Current
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
241 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
243 RtlCopyMemory((PUCHAR
)SdRel
+ Current
, SeWorldSid
, SidSize
);
244 SdRel
->Owner
= Current
;
248 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
250 RtlCopyMemory((PUCHAR
)SdRel
+ Current
, SeWorldSid
, SidSize
);
251 SdRel
->Group
= Current
;
255 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
257 PACL Dacl
= (PACL
)((PUCHAR
)SdRel
+ Current
);
258 SdRel
->Control
|= SE_DACL_PRESENT
;
260 Status
= RtlCreateAcl(Dacl
,
261 sizeof(ACL
) + sizeof(ACE
) + SidSize
,
263 if (!NT_SUCCESS(Status
))
266 Status
= RtlAddAccessAllowedAce(Dacl
,
270 if (!NT_SUCCESS(Status
))
273 SdRel
->Dacl
= Current
;
276 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
278 /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */
281 return STATUS_SUCCESS
;
287 SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
288 IN KPROCESSOR_MODE AccessMode
,
289 IN POOL_TYPE PoolType
,
290 IN BOOLEAN CaptureIfKernel
,
291 OUT PSECURITY_QUALITY_OF_SERVICE
*CapturedSecurityQualityOfService
,
292 OUT PBOOLEAN Present
)
294 PSECURITY_QUALITY_OF_SERVICE CapturedQos
;
295 NTSTATUS Status
= STATUS_SUCCESS
;
299 ASSERT(CapturedSecurityQualityOfService
);
302 if (ObjectAttributes
!= NULL
)
304 if (AccessMode
!= KernelMode
)
306 SECURITY_QUALITY_OF_SERVICE SafeQos
;
310 ProbeForRead(ObjectAttributes
,
311 sizeof(OBJECT_ATTRIBUTES
),
313 if (ObjectAttributes
->Length
== sizeof(OBJECT_ATTRIBUTES
))
315 if (ObjectAttributes
->SecurityQualityOfService
!= NULL
)
317 ProbeForRead(ObjectAttributes
->SecurityQualityOfService
,
318 sizeof(SECURITY_QUALITY_OF_SERVICE
),
321 if (((PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
)->Length
==
322 sizeof(SECURITY_QUALITY_OF_SERVICE
))
325 * Don't allocate memory here because ExAllocate should bugcheck
326 * the system if it's buggy, SEH would catch that! So make a local
327 * copy of the qos structure.
329 RtlCopyMemory(&SafeQos
,
330 ObjectAttributes
->SecurityQualityOfService
,
331 sizeof(SECURITY_QUALITY_OF_SERVICE
));
336 Status
= STATUS_INVALID_PARAMETER
;
341 *CapturedSecurityQualityOfService
= NULL
;
347 Status
= STATUS_INVALID_PARAMETER
;
350 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
352 Status
= _SEH2_GetExceptionCode();
356 if (NT_SUCCESS(Status
))
360 CapturedQos
= ExAllocatePool(PoolType
,
361 sizeof(SECURITY_QUALITY_OF_SERVICE
));
362 if (CapturedQos
!= NULL
)
364 RtlCopyMemory(CapturedQos
,
366 sizeof(SECURITY_QUALITY_OF_SERVICE
));
367 *CapturedSecurityQualityOfService
= CapturedQos
;
371 Status
= STATUS_INSUFFICIENT_RESOURCES
;
376 *CapturedSecurityQualityOfService
= NULL
;
382 if (ObjectAttributes
->Length
== sizeof(OBJECT_ATTRIBUTES
))
386 if (ObjectAttributes
->SecurityQualityOfService
!= NULL
)
388 if (((PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
)->Length
==
389 sizeof(SECURITY_QUALITY_OF_SERVICE
))
391 CapturedQos
= ExAllocatePool(PoolType
,
392 sizeof(SECURITY_QUALITY_OF_SERVICE
));
393 if (CapturedQos
!= NULL
)
395 RtlCopyMemory(CapturedQos
,
396 ObjectAttributes
->SecurityQualityOfService
,
397 sizeof(SECURITY_QUALITY_OF_SERVICE
));
398 *CapturedSecurityQualityOfService
= CapturedQos
;
403 Status
= STATUS_INSUFFICIENT_RESOURCES
;
408 Status
= STATUS_INVALID_PARAMETER
;
413 *CapturedSecurityQualityOfService
= NULL
;
419 *CapturedSecurityQualityOfService
= (PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
;
420 *Present
= (ObjectAttributes
->SecurityQualityOfService
!= NULL
);
425 Status
= STATUS_INVALID_PARAMETER
;
431 *CapturedSecurityQualityOfService
= NULL
;
441 SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL
,
442 IN KPROCESSOR_MODE AccessMode
,
443 IN BOOLEAN CaptureIfKernel
)
447 if (CapturedSecurityQualityOfService
!= NULL
&&
448 (AccessMode
!= KernelMode
|| CaptureIfKernel
))
450 ExFreePool(CapturedSecurityQualityOfService
);
454 /* PUBLIC FUNCTIONS ***********************************************************/
461 KPROCESSOR_MODE ProcessorMode
)
471 if (ProcessorMode
!= KernelMode
)
473 /* Securely access the buffers! */
474 *OutSAC
= ProbeForReadUchar(&Sid
->SubAuthorityCount
);
475 Size
= RtlLengthRequiredSid(*OutSAC
);
476 ProbeForRead(Sid
, Size
, sizeof(ULONG
));
480 *OutSAC
= Sid
->SubAuthorityCount
;
481 Size
= RtlLengthRequiredSid(*OutSAC
);
491 KPROCESSOR_MODE ProcessorMode
)
497 if (ProcessorMode
== KernelMode
) return Acl
->AclSize
;
499 /* Probe the buffers! */
500 Size
= ProbeForReadUshort(&Acl
->AclSize
);
501 ProbeForRead(Acl
, Size
, sizeof(ULONG
));
508 SeCaptureSecurityDescriptor(
509 IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor
,
510 IN KPROCESSOR_MODE CurrentMode
,
511 IN POOL_TYPE PoolType
,
512 IN BOOLEAN CaptureIfKernel
,
513 OUT PSECURITY_DESCRIPTOR
*CapturedSecurityDescriptor
)
515 PISECURITY_DESCRIPTOR OriginalDescriptor
= _OriginalSecurityDescriptor
;
516 SECURITY_DESCRIPTOR DescriptorCopy
;
517 PISECURITY_DESCRIPTOR_RELATIVE NewDescriptor
;
518 ULONG OwnerSAC
= 0, GroupSAC
= 0;
519 ULONG OwnerSize
= 0, GroupSize
= 0;
520 ULONG SaclSize
= 0, DaclSize
= 0;
521 ULONG DescriptorSize
= 0;
524 if (!OriginalDescriptor
)
526 /* Nothing to do... */
527 *CapturedSecurityDescriptor
= NULL
;
528 return STATUS_SUCCESS
;
532 if (CurrentMode
== KernelMode
&& !CaptureIfKernel
)
534 /* Check descriptor version */
535 if (OriginalDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
537 return STATUS_UNKNOWN_REVISION
;
540 *CapturedSecurityDescriptor
= _OriginalSecurityDescriptor
;
541 return STATUS_SUCCESS
;
546 if (CurrentMode
!= KernelMode
)
548 ProbeForRead(OriginalDescriptor
,
549 sizeof(SECURITY_DESCRIPTOR_RELATIVE
),
553 /* Check the descriptor version */
554 if (OriginalDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
556 _SEH2_YIELD(return STATUS_UNKNOWN_REVISION
);
559 if (CurrentMode
!= KernelMode
)
561 /* Get the size of the descriptor */
562 DescriptorSize
= (OriginalDescriptor
->Control
& SE_SELF_RELATIVE
) ?
563 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
);
565 /* Probe the entire security descriptor structure. The SIDs
566 * and ACLs will be probed and copied later though */
567 ProbeForRead(OriginalDescriptor
, DescriptorSize
, sizeof(ULONG
));
570 /* Now capture all fields and convert to an absolute descriptor */
571 DescriptorCopy
.Revision
= OriginalDescriptor
->Revision
;
572 DescriptorCopy
.Sbz1
= OriginalDescriptor
->Sbz1
;
573 DescriptorCopy
.Control
= OriginalDescriptor
->Control
& ~SE_SELF_RELATIVE
;
574 DescriptorCopy
.Owner
= SepGetOwnerFromDescriptor(OriginalDescriptor
);
575 DescriptorCopy
.Group
= SepGetGroupFromDescriptor(OriginalDescriptor
);
576 DescriptorCopy
.Sacl
= SepGetSaclFromDescriptor(OriginalDescriptor
);
577 DescriptorCopy
.Dacl
= SepGetDaclFromDescriptor(OriginalDescriptor
);
578 DescriptorSize
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
580 /* Determine owner and group sizes */
581 OwnerSize
= DetermineSIDSize(DescriptorCopy
.Owner
, &OwnerSAC
, CurrentMode
);
582 DescriptorSize
+= ROUND_UP(OwnerSize
, sizeof(ULONG
));
583 GroupSize
= DetermineSIDSize(DescriptorCopy
.Group
, &GroupSAC
, CurrentMode
);
584 DescriptorSize
+= ROUND_UP(GroupSize
, sizeof(ULONG
));
586 /* Determine the size of the ACLs */
587 if (DescriptorCopy
.Control
& SE_SACL_PRESENT
)
589 /* Get the size and probe if user mode */
590 SaclSize
= DetermineACLSize(DescriptorCopy
.Sacl
, CurrentMode
);
591 DescriptorSize
+= ROUND_UP(SaclSize
, sizeof(ULONG
));
594 if (DescriptorCopy
.Control
& SE_DACL_PRESENT
)
596 /* Get the size and probe if user mode */
597 DaclSize
= DetermineACLSize(DescriptorCopy
.Dacl
, CurrentMode
);
598 DescriptorSize
+= ROUND_UP(DaclSize
, sizeof(ULONG
));
601 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
603 _SEH2_YIELD(return _SEH2_GetExceptionCode());
608 * Allocate enough memory to store a complete copy of a self-relative
609 * security descriptor
611 NewDescriptor
= ExAllocatePoolWithTag(PoolType
,
614 if (!NewDescriptor
) return STATUS_INSUFFICIENT_RESOURCES
;
616 RtlZeroMemory(NewDescriptor
, DescriptorSize
);
617 NewDescriptor
->Revision
= DescriptorCopy
.Revision
;
618 NewDescriptor
->Sbz1
= DescriptorCopy
.Sbz1
;
619 NewDescriptor
->Control
= DescriptorCopy
.Control
| SE_SELF_RELATIVE
;
624 * Setup the offsets and copy the SIDs and ACLs to the new
625 * self-relative security descriptor. Probing the pointers is not
626 * neccessary anymore as we did that when collecting the sizes!
627 * Make sure to validate the SIDs and ACLs *again* as they could have
628 * been modified in the meanwhile!
630 Offset
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
632 if (DescriptorCopy
.Owner
)
634 if (!RtlValidSid(DescriptorCopy
.Owner
)) RtlRaiseStatus(STATUS_INVALID_SID
);
635 NewDescriptor
->Owner
= Offset
;
636 RtlCopyMemory((PUCHAR
)NewDescriptor
+ Offset
,
637 DescriptorCopy
.Owner
,
639 Offset
+= ROUND_UP(OwnerSize
, sizeof(ULONG
));
642 if (DescriptorCopy
.Group
)
644 if (!RtlValidSid(DescriptorCopy
.Group
)) RtlRaiseStatus(STATUS_INVALID_SID
);
645 NewDescriptor
->Group
= Offset
;
646 RtlCopyMemory((PUCHAR
)NewDescriptor
+ Offset
,
647 DescriptorCopy
.Group
,
649 Offset
+= ROUND_UP(GroupSize
, sizeof(ULONG
));
652 if (DescriptorCopy
.Sacl
)
654 if (!RtlValidAcl(DescriptorCopy
.Sacl
)) RtlRaiseStatus(STATUS_INVALID_ACL
);
655 NewDescriptor
->Sacl
= Offset
;
656 RtlCopyMemory((PUCHAR
)NewDescriptor
+ Offset
,
659 Offset
+= ROUND_UP(SaclSize
, sizeof(ULONG
));
662 if (DescriptorCopy
.Dacl
)
664 if (!RtlValidAcl(DescriptorCopy
.Dacl
)) RtlRaiseStatus(STATUS_INVALID_ACL
);
665 NewDescriptor
->Dacl
= Offset
;
666 RtlCopyMemory((PUCHAR
)NewDescriptor
+ Offset
,
669 Offset
+= ROUND_UP(DaclSize
, sizeof(ULONG
));
672 /* Make sure the size was correct */
673 ASSERT(Offset
== DescriptorSize
);
675 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
677 /* We failed to copy the data to the new descriptor */
678 ExFreePoolWithTag(NewDescriptor
, TAG_SD
);
679 _SEH2_YIELD(return _SEH2_GetExceptionCode());
684 * We're finally done!
685 * Copy the pointer to the captured descriptor to to the caller.
687 *CapturedSecurityDescriptor
= NewDescriptor
;
688 return STATUS_SUCCESS
;
695 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation
,
696 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
697 IN OUT PULONG Length
,
698 IN PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor OPTIONAL
)
700 PISECURITY_DESCRIPTOR ObjectSd
;
701 PISECURITY_DESCRIPTOR_RELATIVE RelSD
;
706 ULONG OwnerLength
= 0;
707 ULONG GroupLength
= 0;
708 ULONG DaclLength
= 0;
709 ULONG SaclLength
= 0;
714 RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
716 if (*ObjectsSecurityDescriptor
== NULL
)
718 if (*Length
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
))
720 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
721 return STATUS_BUFFER_TOO_SMALL
;
724 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
725 RtlCreateSecurityDescriptorRelative(RelSD
,
726 SECURITY_DESCRIPTOR_REVISION
);
727 return STATUS_SUCCESS
;
730 ObjectSd
= *ObjectsSecurityDescriptor
;
732 /* Calculate the required security descriptor length */
733 Control
= SE_SELF_RELATIVE
;
734 if ((*SecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
735 (ObjectSd
->Owner
!= NULL
))
737 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
738 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
739 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
742 if ((*SecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
743 (ObjectSd
->Group
!= NULL
))
745 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
746 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
747 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
750 if ((*SecurityInformation
& DACL_SECURITY_INFORMATION
) &&
751 (ObjectSd
->Control
& SE_DACL_PRESENT
))
753 if (ObjectSd
->Dacl
!= NULL
)
755 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
756 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
759 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
762 if ((*SecurityInformation
& SACL_SECURITY_INFORMATION
) &&
763 (ObjectSd
->Control
& SE_SACL_PRESENT
))
765 if (ObjectSd
->Sacl
!= NULL
)
767 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
768 SaclLength
= ROUND_UP(Sacl
->AclSize
, 4);
771 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
774 SdLength
= OwnerLength
+ GroupLength
+ DaclLength
+
775 SaclLength
+ sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
776 if (*Length
< SdLength
)
779 return STATUS_BUFFER_TOO_SMALL
;
782 /* Build the new security descrtiptor */
783 RtlCreateSecurityDescriptorRelative(RelSD
,
784 SECURITY_DESCRIPTOR_REVISION
);
785 RelSD
->Control
= (USHORT
)Control
;
787 Current
= (ULONG_PTR
)(RelSD
+ 1);
789 if (OwnerLength
!= 0)
791 RtlCopyMemory((PVOID
)Current
,
794 RelSD
->Owner
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
795 Current
+= OwnerLength
;
798 if (GroupLength
!= 0)
800 RtlCopyMemory((PVOID
)Current
,
803 RelSD
->Group
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
804 Current
+= GroupLength
;
809 RtlCopyMemory((PVOID
)Current
,
812 RelSD
->Dacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
813 Current
+= DaclLength
;
818 RtlCopyMemory((PVOID
)Current
,
821 RelSD
->Sacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
822 Current
+= SaclLength
;
827 return STATUS_SUCCESS
;
835 SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor
,
836 IN KPROCESSOR_MODE CurrentMode
,
837 IN BOOLEAN CaptureIfKernelMode
)
842 * WARNING! You need to call this function with the same value for CurrentMode
843 * and CaptureIfKernelMode that you previously passed to
844 * SeCaptureSecurityDescriptor() in order to avoid memory leaks!
846 if (CapturedSecurityDescriptor
!= NULL
&&
847 (CurrentMode
!= KernelMode
||
848 (CurrentMode
== KernelMode
&& CaptureIfKernelMode
)))
850 /* Only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
851 ExFreePoolWithTag(CapturedSecurityDescriptor
, TAG_SD
);
854 return STATUS_SUCCESS
;
861 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL
,
862 IN PSECURITY_INFORMATION _SecurityInformation
,
863 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
,
864 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
865 IN POOL_TYPE PoolType
,
866 IN PGENERIC_MAPPING GenericMapping
)
868 PISECURITY_DESCRIPTOR_RELATIVE ObjectSd
;
869 PISECURITY_DESCRIPTOR_RELATIVE NewSd
;
870 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
871 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
876 ULONG OwnerLength
= 0;
877 ULONG GroupLength
= 0;
878 ULONG DaclLength
= 0;
879 ULONG SaclLength
= 0;
882 SECURITY_INFORMATION SecurityInformation
;
884 ObjectSd
= *ObjectsSecurityDescriptor
;
886 /* The object does not have a security descriptor. */
888 return STATUS_NO_SECURITY_ON_OBJECT
;
890 ASSERT(ObjectSd
->Control
& SE_SELF_RELATIVE
);
892 SecurityInformation
= *_SecurityInformation
;
894 /* Get owner and owner size */
895 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
897 if (SecurityDescriptor
->Owner
!= NULL
)
899 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
900 Owner
= (PSID
)((ULONG_PTR
)RelSD
->Owner
+
901 (ULONG_PTR
)SecurityDescriptor
);
903 Owner
= (PSID
)SecurityDescriptor
->Owner
;
904 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
907 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
913 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
914 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
917 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
920 /* Get group and group size */
921 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
923 if (SecurityDescriptor
->Group
!= NULL
)
925 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
926 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
927 (ULONG_PTR
)SecurityDescriptor
);
929 Group
= (PSID
)SecurityDescriptor
->Group
;
930 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
933 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
939 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
940 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
943 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
946 /* Get DACL and DACL size */
947 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
949 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
950 (SecurityDescriptor
->Dacl
!= NULL
))
952 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
953 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+
954 (ULONG_PTR
)SecurityDescriptor
);
956 Dacl
= (PACL
)SecurityDescriptor
->Dacl
;
958 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
961 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
965 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) && (ObjectSd
->Dacl
))
967 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
968 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
971 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
974 /* Get SACL and SACL size */
975 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
977 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
978 (SecurityDescriptor
->Sacl
!= NULL
))
980 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
981 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+
982 (ULONG_PTR
)SecurityDescriptor
);
984 Sacl
= (PACL
)SecurityDescriptor
->Sacl
;
985 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
988 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
992 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) && (ObjectSd
->Sacl
))
994 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
995 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
998 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
1001 NewSd
= ExAllocatePool(NonPagedPool
,
1002 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) + OwnerLength
+ GroupLength
+
1003 DaclLength
+ SaclLength
);
1006 ObDereferenceObject(Object
);
1007 return STATUS_INSUFFICIENT_RESOURCES
;
1010 RtlCreateSecurityDescriptor(NewSd
,
1011 SECURITY_DESCRIPTOR_REVISION1
);
1013 /* We always build a self-relative descriptor */
1014 NewSd
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
1016 Current
= sizeof(SECURITY_DESCRIPTOR
);
1018 if (OwnerLength
!= 0)
1020 RtlCopyMemory((PUCHAR
)NewSd
+ Current
, Owner
, OwnerLength
);
1021 NewSd
->Owner
= Current
;
1022 Current
+= OwnerLength
;
1025 if (GroupLength
!= 0)
1027 RtlCopyMemory((PUCHAR
)NewSd
+ Current
, Group
, GroupLength
);
1028 NewSd
->Group
= Current
;
1029 Current
+= GroupLength
;
1032 if (DaclLength
!= 0)
1034 RtlCopyMemory((PUCHAR
)NewSd
+ Current
, Dacl
, DaclLength
);
1035 NewSd
->Dacl
= Current
;
1036 Current
+= DaclLength
;
1039 if (SaclLength
!= 0)
1041 RtlCopyMemory((PUCHAR
)NewSd
+ Current
, Sacl
, SaclLength
);
1042 NewSd
->Sacl
= Current
;
1043 Current
+= SaclLength
;
1046 *ObjectsSecurityDescriptor
= NewSd
;
1047 return STATUS_SUCCESS
;
1055 SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL
,
1056 IN PSECURITY_INFORMATION SecurityInformation
,
1057 IN PSECURITY_DESCRIPTOR ModificationDescriptor
,
1058 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
1059 IN ULONG AutoInheritFlags
,
1060 IN POOL_TYPE PoolType
,
1061 IN PGENERIC_MAPPING GenericMapping
)
1063 PISECURITY_DESCRIPTOR ObjectSd
= *ObjectsSecurityDescriptor
;
1065 /* The object does not have a security descriptor. */
1067 return STATUS_NO_SECURITY_ON_OBJECT
;
1070 return STATUS_NOT_IMPLEMENTED
;
1078 SeValidSecurityDescriptor(IN ULONG Length
,
1079 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
)
1084 PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor
= _SecurityDescriptor
;
1086 if (Length
< SECURITY_DESCRIPTOR_MIN_LENGTH
)
1088 DPRINT1("Invalid Security Descriptor revision\n");
1092 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
1094 DPRINT1("Invalid Security Descriptor revision\n");
1098 if (!(SecurityDescriptor
->Control
& SE_SELF_RELATIVE
))
1100 DPRINT1("No self-relative Security Descriptor\n");
1104 SdLength
= sizeof(SECURITY_DESCRIPTOR
);
1106 /* Check Owner SID */
1107 if (SecurityDescriptor
->Owner
)
1109 DPRINT1("No Owner SID\n");
1113 if (SecurityDescriptor
->Owner
% sizeof(ULONG
))
1115 DPRINT1("Invalid Owner SID alignment\n");
1119 Sid
= (PISID
)((ULONG_PTR
)SecurityDescriptor
+ SecurityDescriptor
->Owner
);
1120 if (Sid
->Revision
!= SID_REVISION
)
1122 DPRINT1("Invalid Owner SID revision\n");
1126 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
1127 if (Length
< SdLength
)
1129 DPRINT1("Invalid Owner SID size\n");
1133 /* Check Group SID */
1134 if (SecurityDescriptor
->Group
)
1136 if (SecurityDescriptor
->Group
% sizeof(ULONG
))
1138 DPRINT1("Invalid Group SID alignment\n");
1142 Sid
= (PSID
)((ULONG_PTR
)SecurityDescriptor
+ SecurityDescriptor
->Group
);
1143 if (Sid
->Revision
!= SID_REVISION
)
1145 DPRINT1("Invalid Group SID revision\n");
1149 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
1150 if (Length
< SdLength
)
1152 DPRINT1("Invalid Group SID size\n");
1158 if (SecurityDescriptor
->Dacl
)
1160 if (SecurityDescriptor
->Dacl
% sizeof(ULONG
))
1162 DPRINT1("Invalid DACL alignment\n");
1166 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ SecurityDescriptor
->Dacl
);
1167 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) &&
1168 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1170 DPRINT1("Invalid DACL revision\n");
1174 SdLength
+= Acl
->AclSize
;
1175 if (Length
< SdLength
)
1177 DPRINT1("Invalid DACL size\n");
1183 if (SecurityDescriptor
->Sacl
)
1185 if (SecurityDescriptor
->Sacl
% sizeof(ULONG
))
1187 DPRINT1("Invalid SACL alignment\n");
1191 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ SecurityDescriptor
->Sacl
);
1192 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
1193 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1195 DPRINT1("Invalid SACL revision\n");
1199 SdLength
+= Acl
->AclSize
;
1200 if (Length
< SdLength
)
1202 DPRINT1("Invalid SACL size\n");
1214 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
1218 if (*SecurityDescriptor
!= NULL
)
1220 ExFreePoolWithTag(*SecurityDescriptor
, TAG_SD
);
1221 *SecurityDescriptor
= NULL
;
1224 return STATUS_SUCCESS
;
1233 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
1234 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
1235 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
1236 IN GUID
*ObjectType OPTIONAL
,
1237 IN BOOLEAN IsDirectoryObject
,
1238 IN ULONG AutoInheritFlags
,
1239 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
1240 IN PGENERIC_MAPPING GenericMapping
,
1241 IN POOL_TYPE PoolType
)
1244 return STATUS_NOT_IMPLEMENTED
;
1251 SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL
,
1252 PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL
,
1253 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1254 BOOLEAN IsDirectoryObject
,
1255 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
1256 PGENERIC_MAPPING GenericMapping
,
1259 PISECURITY_DESCRIPTOR ParentDescriptor
= _ParentDescriptor
;
1260 PISECURITY_DESCRIPTOR ExplicitDescriptor
= _ExplicitDescriptor
;
1261 PISECURITY_DESCRIPTOR_RELATIVE Descriptor
;
1263 ULONG OwnerLength
= 0;
1264 ULONG GroupLength
= 0;
1265 ULONG DaclLength
= 0;
1266 ULONG SaclLength
= 0;
1277 /* Lock subject context */
1278 SeLockSubjectContext(SubjectContext
);
1280 if (SubjectContext
->ClientToken
!= NULL
)
1282 Token
= SubjectContext
->ClientToken
;
1286 Token
= SubjectContext
->PrimaryToken
;
1289 /* Inherit the Owner SID */
1290 if (ExplicitDescriptor
!= NULL
)
1292 DPRINT("Use explicit owner sid!\n");
1293 Owner
= SepGetOwnerFromDescriptor(ExplicitDescriptor
);
1300 DPRINT("Use token owner sid!\n");
1301 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
1305 DPRINT("Use default owner sid!\n");
1306 Owner
= SeLocalSystemSid
;
1309 Control
|= SE_OWNER_DEFAULTED
;
1312 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
1314 /* Inherit the Group SID */
1315 if (ExplicitDescriptor
!= NULL
)
1317 Group
= SepGetGroupFromDescriptor(ExplicitDescriptor
);
1324 DPRINT("Use token group sid!\n");
1325 Group
= Token
->PrimaryGroup
;
1329 DPRINT("Use default group sid!\n");
1330 Group
= SeLocalSystemSid
;
1333 Control
|= SE_GROUP_DEFAULTED
;
1336 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
1338 /* Inherit the DACL */
1339 if (ExplicitDescriptor
!= NULL
&&
1340 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
1341 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
1343 DPRINT("Use explicit DACL!\n");
1344 Dacl
= SepGetDaclFromDescriptor(ExplicitDescriptor
);
1345 Control
|= SE_DACL_PRESENT
;
1347 else if (ParentDescriptor
!= NULL
&&
1348 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
1350 DPRINT("Use parent DACL!\n");
1351 /* FIXME: Inherit */
1352 Dacl
= SepGetDaclFromDescriptor(ParentDescriptor
);
1353 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1355 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
1357 DPRINT("Use token default DACL!\n");
1358 /* FIXME: Inherit */
1359 Dacl
= Token
->DefaultDacl
;
1360 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1364 DPRINT("Use NULL DACL!\n");
1366 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1369 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
1371 /* Inherit the SACL */
1372 if (ExplicitDescriptor
!= NULL
&&
1373 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
1374 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
1376 DPRINT("Use explicit SACL!\n");
1377 Sacl
= SepGetSaclFromDescriptor(ExplicitDescriptor
);
1378 Control
|= SE_SACL_PRESENT
;
1380 else if (ParentDescriptor
!= NULL
&&
1381 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
1383 DPRINT("Use parent SACL!\n");
1384 /* FIXME: Inherit */
1385 Sacl
= SepGetSaclFromDescriptor(ParentDescriptor
);
1386 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
1389 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
1391 /* Allocate and initialize the new security descriptor */
1392 Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
) +
1393 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
1395 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
1396 sizeof(SECURITY_DESCRIPTOR
),
1402 Descriptor
= ExAllocatePoolWithTag(PagedPool
, Length
, TAG_SD
);
1403 if (Descriptor
== NULL
)
1405 DPRINT1("ExAlloctePool() failed\n");
1406 /* FIXME: Unlock subject context */
1407 return STATUS_INSUFFICIENT_RESOURCES
;
1410 RtlZeroMemory(Descriptor
, Length
);
1411 RtlCreateSecurityDescriptor(Descriptor
, SECURITY_DESCRIPTOR_REVISION
);
1413 Descriptor
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
1415 Current
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
1417 if (SaclLength
!= 0)
1419 RtlCopyMemory((PUCHAR
)Descriptor
+ Current
, Sacl
, SaclLength
);
1420 Descriptor
->Sacl
= Current
;
1421 Current
+= SaclLength
;
1424 if (DaclLength
!= 0)
1426 RtlCopyMemory((PUCHAR
)Descriptor
+ Current
, Dacl
, DaclLength
);
1427 Descriptor
->Dacl
= Current
;
1428 Current
+= DaclLength
;
1431 if (OwnerLength
!= 0)
1433 RtlCopyMemory((PUCHAR
)Descriptor
+ Current
, Owner
, OwnerLength
);
1434 Descriptor
->Owner
= Current
;
1435 Current
+= OwnerLength
;
1436 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
1440 DPRINT("Owner of %x is zero length\n", Descriptor
);
1443 if (GroupLength
!= 0)
1445 RtlCopyMemory((PUCHAR
)Descriptor
+ Current
, Group
, GroupLength
);
1446 Descriptor
->Group
= Current
;
1449 /* Unlock subject context */
1450 SeUnlockSubjectContext(SubjectContext
);
1452 *NewDescriptor
= Descriptor
;
1454 DPRINT("Descrptor %x\n", Descriptor
);
1455 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
1457 return STATUS_SUCCESS
;