3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/se/sd.c
6 * PURPOSE: Security manager
8 * PROGRAMMERS: David Welch <welch@cwcom.net>
11 /* INCLUDES *****************************************************************/
14 #include <internal/debug.h>
16 #if defined (ALLOC_PRAGMA)
17 #pragma alloc_text(INIT, SepInitSDs)
21 /* GLOBALS ******************************************************************/
23 PSECURITY_DESCRIPTOR SePublicDefaultSd
= NULL
;
24 PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd
= NULL
;
25 PSECURITY_DESCRIPTOR SePublicOpenSd
= NULL
;
26 PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd
= NULL
;
27 PSECURITY_DESCRIPTOR SeSystemDefaultSd
= NULL
;
28 PSECURITY_DESCRIPTOR SeUnrestrictedSd
= NULL
;
30 /* FUNCTIONS ***************************************************************/
37 /* Create PublicDefaultSd */
38 SePublicDefaultSd
= ExAllocatePoolWithTag(PagedPool
,
39 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
40 if (SePublicDefaultSd
== NULL
)
43 RtlCreateSecurityDescriptor(SePublicDefaultSd
,
44 SECURITY_DESCRIPTOR_REVISION
);
45 RtlSetDaclSecurityDescriptor(SePublicDefaultSd
,
50 /* Create PublicDefaultUnrestrictedSd */
51 SePublicDefaultUnrestrictedSd
= ExAllocatePoolWithTag(PagedPool
,
52 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
53 if (SePublicDefaultUnrestrictedSd
== NULL
)
56 RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd
,
57 SECURITY_DESCRIPTOR_REVISION
);
58 RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd
,
60 SePublicDefaultUnrestrictedDacl
,
63 /* Create PublicOpenSd */
64 SePublicOpenSd
= ExAllocatePoolWithTag(PagedPool
,
65 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
66 if (SePublicOpenSd
== NULL
)
69 RtlCreateSecurityDescriptor(SePublicOpenSd
,
70 SECURITY_DESCRIPTOR_REVISION
);
71 RtlSetDaclSecurityDescriptor(SePublicOpenSd
,
76 /* Create PublicOpenUnrestrictedSd */
77 SePublicOpenUnrestrictedSd
= ExAllocatePoolWithTag(PagedPool
,
78 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
79 if (SePublicOpenUnrestrictedSd
== NULL
)
82 RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd
,
83 SECURITY_DESCRIPTOR_REVISION
);
84 RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd
,
86 SePublicOpenUnrestrictedDacl
,
89 /* Create SystemDefaultSd */
90 SeSystemDefaultSd
= ExAllocatePoolWithTag(PagedPool
,
91 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
92 if (SeSystemDefaultSd
== NULL
)
95 RtlCreateSecurityDescriptor(SeSystemDefaultSd
,
96 SECURITY_DESCRIPTOR_REVISION
);
97 RtlSetDaclSecurityDescriptor(SeSystemDefaultSd
,
102 /* Create UnrestrictedSd */
103 SeUnrestrictedSd
= ExAllocatePoolWithTag(PagedPool
,
104 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
105 if (SeUnrestrictedSd
== NULL
)
108 RtlCreateSecurityDescriptor(SeUnrestrictedSd
,
109 SECURITY_DESCRIPTOR_REVISION
);
110 RtlSetDaclSecurityDescriptor(SeUnrestrictedSd
,
120 SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation
,
121 PISECURITY_DESCRIPTOR SecurityDescriptor
,
129 DPRINT("SeSetWorldSecurityDescriptor() called\n");
131 if (SecurityInformation
== 0)
133 return STATUS_ACCESS_DENIED
;
136 SidSize
= RtlLengthSid(SeWorldSid
);
137 SdSize
= sizeof(SECURITY_DESCRIPTOR
) + (2 * SidSize
);
139 if (*BufferLength
< SdSize
)
141 *BufferLength
= SdSize
;
142 return STATUS_BUFFER_TOO_SMALL
;
145 *BufferLength
= SdSize
;
147 Status
= RtlCreateSecurityDescriptor(SecurityDescriptor
,
148 SECURITY_DESCRIPTOR_REVISION
);
149 if (!NT_SUCCESS(Status
))
154 SecurityDescriptor
->Control
|= SE_SELF_RELATIVE
;
155 Current
= (ULONG_PTR
)SecurityDescriptor
+ sizeof(SECURITY_DESCRIPTOR
);
157 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
159 RtlCopyMemory((PVOID
)Current
,
162 SecurityDescriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)SecurityDescriptor
);
166 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
168 RtlCopyMemory((PVOID
)Current
,
171 SecurityDescriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)SecurityDescriptor
);
175 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
177 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
;
180 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
182 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
;
185 return STATUS_SUCCESS
;
191 SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
192 IN KPROCESSOR_MODE AccessMode
,
193 IN POOL_TYPE PoolType
,
194 IN BOOLEAN CaptureIfKernel
,
195 OUT PSECURITY_QUALITY_OF_SERVICE
*CapturedSecurityQualityOfService
,
196 OUT PBOOLEAN Present
)
198 PSECURITY_QUALITY_OF_SERVICE CapturedQos
;
199 NTSTATUS Status
= STATUS_SUCCESS
;
203 ASSERT(CapturedSecurityQualityOfService
);
206 if(ObjectAttributes
!= NULL
)
208 if(AccessMode
!= KernelMode
)
210 SECURITY_QUALITY_OF_SERVICE SafeQos
;
214 ProbeForRead(ObjectAttributes
,
215 sizeof(ObjectAttributes
),
217 if(ObjectAttributes
->Length
== sizeof(OBJECT_ATTRIBUTES
))
219 if(ObjectAttributes
->SecurityQualityOfService
!= NULL
)
221 ProbeForRead(ObjectAttributes
->SecurityQualityOfService
,
222 sizeof(SECURITY_QUALITY_OF_SERVICE
),
225 if(((PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
)->Length
==
226 sizeof(SECURITY_QUALITY_OF_SERVICE
))
228 /* don't allocate memory here because ExAllocate should bugcheck
229 the system if it's buggy, SEH would catch that! So make a local
230 copy of the qos structure.*/
231 RtlCopyMemory(&SafeQos
,
232 ObjectAttributes
->SecurityQualityOfService
,
233 sizeof(SECURITY_QUALITY_OF_SERVICE
));
238 Status
= STATUS_INVALID_PARAMETER
;
243 *CapturedSecurityQualityOfService
= NULL
;
249 Status
= STATUS_INVALID_PARAMETER
;
254 Status
= _SEH_GetExceptionCode();
258 if(NT_SUCCESS(Status
))
262 CapturedQos
= ExAllocatePool(PoolType
,
263 sizeof(SECURITY_QUALITY_OF_SERVICE
));
264 if(CapturedQos
!= NULL
)
266 RtlCopyMemory(CapturedQos
,
268 sizeof(SECURITY_QUALITY_OF_SERVICE
));
269 *CapturedSecurityQualityOfService
= CapturedQos
;
273 Status
= STATUS_INSUFFICIENT_RESOURCES
;
278 *CapturedSecurityQualityOfService
= NULL
;
284 if(ObjectAttributes
->Length
== sizeof(OBJECT_ATTRIBUTES
))
288 if(ObjectAttributes
->SecurityQualityOfService
!= NULL
)
290 if(((PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
)->Length
==
291 sizeof(SECURITY_QUALITY_OF_SERVICE
))
293 CapturedQos
= ExAllocatePool(PoolType
,
294 sizeof(SECURITY_QUALITY_OF_SERVICE
));
295 if(CapturedQos
!= NULL
)
297 RtlCopyMemory(CapturedQos
,
298 ObjectAttributes
->SecurityQualityOfService
,
299 sizeof(SECURITY_QUALITY_OF_SERVICE
));
300 *CapturedSecurityQualityOfService
= CapturedQos
;
305 Status
= STATUS_INSUFFICIENT_RESOURCES
;
310 Status
= STATUS_INVALID_PARAMETER
;
315 *CapturedSecurityQualityOfService
= NULL
;
321 *CapturedSecurityQualityOfService
= (PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
;
322 *Present
= (ObjectAttributes
->SecurityQualityOfService
!= NULL
);
327 Status
= STATUS_INVALID_PARAMETER
;
333 *CapturedSecurityQualityOfService
= NULL
;
343 SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL
,
344 IN KPROCESSOR_MODE AccessMode
,
345 IN BOOLEAN CaptureIfKernel
)
349 if(CapturedSecurityQualityOfService
!= NULL
&&
350 (AccessMode
!= KernelMode
||
351 (AccessMode
== KernelMode
&& CaptureIfKernel
)))
353 ExFreePool(CapturedSecurityQualityOfService
);
363 SeCaptureSecurityDescriptor(
364 IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor
,
365 IN KPROCESSOR_MODE CurrentMode
,
366 IN POOL_TYPE PoolType
,
367 IN BOOLEAN CaptureIfKernel
,
368 OUT PSECURITY_DESCRIPTOR
*CapturedSecurityDescriptor
371 PISECURITY_DESCRIPTOR OriginalSecurityDescriptor
= _OriginalSecurityDescriptor
;
372 SECURITY_DESCRIPTOR DescriptorCopy
;
373 PISECURITY_DESCRIPTOR NewDescriptor
;
374 ULONG OwnerSAC
= 0, GroupSAC
= 0;
375 ULONG OwnerSize
= 0, GroupSize
= 0;
376 ULONG SaclSize
= 0, DaclSize
= 0;
377 ULONG DescriptorSize
= 0;
378 NTSTATUS Status
= STATUS_SUCCESS
;
380 if(OriginalSecurityDescriptor
!= NULL
)
382 if(CurrentMode
!= KernelMode
)
384 RtlZeroMemory(&DescriptorCopy
, sizeof(DescriptorCopy
));
388 /* first only probe and copy until the control field of the descriptor
389 to determine whether it's a self-relative descriptor */
390 DescriptorSize
= (ULONG
)((ULONG_PTR
)&OriginalSecurityDescriptor
->Control
-
391 (ULONG_PTR
)OriginalSecurityDescriptor
) +
392 sizeof(OriginalSecurityDescriptor
->Control
);
393 ProbeForRead(OriginalSecurityDescriptor
,
397 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
399 Status
= STATUS_UNKNOWN_REVISION
;
403 /* make a copy on the stack */
404 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
405 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
406 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
407 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
408 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
410 /* probe and copy the entire security descriptor structure. The SIDs
411 and ACLs will be probed and copied later though */
412 ProbeForRead(OriginalSecurityDescriptor
,
415 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
417 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
419 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
420 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
421 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
422 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
426 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
427 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
428 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
429 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
434 Status
= _SEH_GetExceptionCode();
438 if(!NT_SUCCESS(Status
))
443 else if(!CaptureIfKernel
)
445 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
447 return STATUS_UNKNOWN_REVISION
;
450 *CapturedSecurityDescriptor
= OriginalSecurityDescriptor
;
451 return STATUS_SUCCESS
;
455 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
457 return STATUS_UNKNOWN_REVISION
;
460 /* make a copy on the stack */
461 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
462 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
463 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
464 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
465 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
466 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
468 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
470 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
471 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
472 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
473 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
477 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
478 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
479 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
480 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
484 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
486 /* in case we're dealing with a self-relative descriptor, do a basic convert
487 to an absolute descriptor. We do this so we can simply access the data
488 using the pointers without calculating them again. */
489 DescriptorCopy
.Control
&= ~SE_SELF_RELATIVE
;
490 if(DescriptorCopy
.Owner
!= NULL
)
492 DescriptorCopy
.Owner
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Owner
);
494 if(DescriptorCopy
.Group
!= NULL
)
496 DescriptorCopy
.Group
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Group
);
498 if(DescriptorCopy
.Dacl
!= NULL
)
500 DescriptorCopy
.Dacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Dacl
);
502 if(DescriptorCopy
.Sacl
!= NULL
)
504 DescriptorCopy
.Sacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Sacl
);
508 /* determine the size of the SIDs */
509 #define DetermineSIDSize(SidType) \
511 if(DescriptorCopy.SidType != NULL) \
513 SID *SidType = (SID*)DescriptorCopy.SidType; \
515 if(CurrentMode != KernelMode) \
517 /* securely access the buffers! */ \
520 ProbeForRead(&SidType->SubAuthorityCount, \
521 sizeof(SidType->SubAuthorityCount), \
523 SidType##SAC = SidType->SubAuthorityCount; \
524 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
525 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
526 ProbeForRead(SidType, \
529 if(!RtlValidSid(SidType)) \
531 Status = STATUS_INVALID_SID; \
536 Status = _SEH_GetExceptionCode(); \
540 if(!NT_SUCCESS(Status)) \
547 SidType##SAC = SidType->SubAuthorityCount; \
548 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
549 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
554 DetermineSIDSize(Owner
);
555 DetermineSIDSize(Group
);
557 /* determine the size of the ACLs */
558 #define DetermineACLSize(AclType, AclFlag) \
560 if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \
561 DescriptorCopy.AclType != NULL) \
563 PACL AclType = (PACL)DescriptorCopy.AclType; \
565 if(CurrentMode != KernelMode) \
567 /* securely access the buffers! */ \
570 ProbeForRead(&AclType->AclSize, \
571 sizeof(AclType->AclSize), \
573 AclType##Size = AclType->AclSize; \
574 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
575 ProbeForRead(AclType, \
578 if(!RtlValidAcl(AclType)) \
580 Status = STATUS_INVALID_ACL; \
585 Status = _SEH_GetExceptionCode(); \
589 if(!NT_SUCCESS(Status)) \
596 AclType##Size = AclType->AclSize; \
597 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
602 DescriptorCopy.AclType = NULL; \
606 DetermineACLSize(Sacl
, SACL
);
607 DetermineACLSize(Dacl
, DACL
);
609 /* allocate enough memory to store a complete copy of a self-relative
610 security descriptor */
611 NewDescriptor
= ExAllocatePool(PoolType
,
613 if(NewDescriptor
!= NULL
)
615 ULONG_PTR Offset
= sizeof(SECURITY_DESCRIPTOR
);
617 RtlZeroMemory(NewDescriptor
, DescriptorSize
);
618 NewDescriptor
->Revision
= DescriptorCopy
.Revision
;
619 NewDescriptor
->Sbz1
= DescriptorCopy
.Sbz1
;
620 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 #define CopySIDOrACL(Type) \
629 if(DescriptorCopy.Type != NULL) \
631 NewDescriptor->Type = (PVOID)Offset; \
632 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
633 (ULONG_PTR)NewDescriptor->Type), \
634 DescriptorCopy.Type, \
636 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
647 Status
= _SEH_GetExceptionCode();
651 if(NT_SUCCESS(Status
))
653 /* we're finally done! copy the pointer to the captured descriptor to
655 *CapturedSecurityDescriptor
= NewDescriptor
;
656 return STATUS_SUCCESS
;
660 /* we failed to copy the data to the new descriptor */
661 ExFreePool(NewDescriptor
);
666 Status
= STATUS_INSUFFICIENT_RESOURCES
;
671 /* nothing to do... */
672 *CapturedSecurityDescriptor
= NULL
;
682 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation
,
683 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
684 IN OUT PULONG Length
,
685 IN PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor OPTIONAL
)
687 PISECURITY_DESCRIPTOR ObjectSd
;
688 PISECURITY_DESCRIPTOR_RELATIVE RelSD
;
693 ULONG OwnerLength
= 0;
694 ULONG GroupLength
= 0;
695 ULONG DaclLength
= 0;
696 ULONG SaclLength
= 0;
701 RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
703 if (*ObjectsSecurityDescriptor
== NULL
)
705 if (*Length
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
))
707 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
708 return STATUS_BUFFER_TOO_SMALL
;
711 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
712 RtlCreateSecurityDescriptorRelative(RelSD
,
713 SECURITY_DESCRIPTOR_REVISION
);
714 return STATUS_SUCCESS
;
717 ObjectSd
= *ObjectsSecurityDescriptor
;
719 /* Calculate the required security descriptor length */
720 Control
= SE_SELF_RELATIVE
;
721 if ((*SecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
722 (ObjectSd
->Owner
!= NULL
))
724 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
725 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
726 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
729 if ((*SecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
730 (ObjectSd
->Group
!= NULL
))
732 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
733 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
734 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
737 if ((*SecurityInformation
& DACL_SECURITY_INFORMATION
) &&
738 (ObjectSd
->Control
& SE_DACL_PRESENT
))
740 if (ObjectSd
->Dacl
!= NULL
)
742 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
743 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
745 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
748 if ((*SecurityInformation
& SACL_SECURITY_INFORMATION
) &&
749 (ObjectSd
->Control
& SE_SACL_PRESENT
))
751 if (ObjectSd
->Sacl
!= NULL
)
753 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
754 SaclLength
= ROUND_UP(Sacl
->AclSize
, 4);
756 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
759 SdLength
= OwnerLength
+ GroupLength
+ DaclLength
+
760 SaclLength
+ sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
761 if (*Length
< SdLength
)
764 return STATUS_BUFFER_TOO_SMALL
;
767 /* Build the new security descrtiptor */
768 RtlCreateSecurityDescriptorRelative(RelSD
,
769 SECURITY_DESCRIPTOR_REVISION
);
770 RelSD
->Control
= Control
;
772 Current
= (ULONG_PTR
)(RelSD
+ 1);
774 if (OwnerLength
!= 0)
776 RtlCopyMemory((PVOID
)Current
,
779 RelSD
->Owner
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
780 Current
+= OwnerLength
;
783 if (GroupLength
!= 0)
785 RtlCopyMemory((PVOID
)Current
,
788 RelSD
->Group
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
789 Current
+= GroupLength
;
794 RtlCopyMemory((PVOID
)Current
,
797 RelSD
->Dacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
798 Current
+= DaclLength
;
803 RtlCopyMemory((PVOID
)Current
,
806 RelSD
->Sacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
807 Current
+= SaclLength
;
812 return STATUS_SUCCESS
;
820 SeReleaseSecurityDescriptor(
821 IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor
,
822 IN KPROCESSOR_MODE CurrentMode
,
823 IN BOOLEAN CaptureIfKernelMode
828 /* WARNING! You need to call this function with the same value for CurrentMode
829 and CaptureIfKernelMode that you previously passed to
830 SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
831 if(CapturedSecurityDescriptor
!= NULL
&&
832 (CurrentMode
!= KernelMode
||
833 (CurrentMode
== KernelMode
&& CaptureIfKernelMode
)))
835 /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
836 ExFreePool(CapturedSecurityDescriptor
);
839 return STATUS_SUCCESS
;
846 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL
,
847 IN PSECURITY_INFORMATION SecurityInformation
,
848 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
849 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
850 IN POOL_TYPE PoolType
,
851 IN PGENERIC_MAPPING GenericMapping
)
854 return STATUS_NOT_IMPLEMENTED
;
862 SeSetSecurityDescriptorInfoEx(
863 IN PVOID Object OPTIONAL
,
864 IN PSECURITY_INFORMATION SecurityInformation
,
865 IN PSECURITY_DESCRIPTOR ModificationDescriptor
,
866 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
867 IN ULONG AutoInheritFlags
,
868 IN POOL_TYPE PoolType
,
869 IN PGENERIC_MAPPING GenericMapping
873 return STATUS_NOT_IMPLEMENTED
;
881 SeValidSecurityDescriptor(IN ULONG Length
,
882 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
)
887 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
889 if (Length
< SECURITY_DESCRIPTOR_MIN_LENGTH
)
891 DPRINT1("Invalid Security Descriptor revision\n");
895 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
897 DPRINT1("Invalid Security Descriptor revision\n");
901 if (!(SecurityDescriptor
->Control
& SE_SELF_RELATIVE
))
903 DPRINT1("No self-relative Security Descriptor\n");
907 SdLength
= sizeof(SECURITY_DESCRIPTOR
);
909 /* Check Owner SID */
910 if (SecurityDescriptor
->Owner
== NULL
)
912 DPRINT1("No Owner SID\n");
916 if ((ULONG_PTR
)SecurityDescriptor
->Owner
% sizeof(ULONG
))
918 DPRINT1("Invalid Owner SID alignment\n");
922 Sid
= (PISID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Owner
);
923 if (Sid
->Revision
!= SID_REVISION
)
925 DPRINT1("Invalid Owner SID revision\n");
929 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
930 if (Length
< SdLength
)
932 DPRINT1("Invalid Owner SID size\n");
936 /* Check Group SID */
937 if (SecurityDescriptor
->Group
!= NULL
)
939 if ((ULONG_PTR
)SecurityDescriptor
->Group
% sizeof(ULONG
))
941 DPRINT1("Invalid Group SID alignment\n");
945 Sid
= (PSID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Group
);
946 if (Sid
->Revision
!= SID_REVISION
)
948 DPRINT1("Invalid Group SID revision\n");
952 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
953 if (Length
< SdLength
)
955 DPRINT1("Invalid Group SID size\n");
961 if (SecurityDescriptor
->Dacl
!= NULL
)
963 if ((ULONG_PTR
)SecurityDescriptor
->Dacl
% sizeof(ULONG
))
965 DPRINT1("Invalid DACL alignment\n");
969 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Dacl
);
970 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) &&
971 (Acl
->AclRevision
> MAX_ACL_REVISION
))
973 DPRINT1("Invalid DACL revision\n");
977 SdLength
+= Acl
->AclSize
;
978 if (Length
< SdLength
)
980 DPRINT1("Invalid DACL size\n");
986 if (SecurityDescriptor
->Sacl
!= NULL
)
988 if ((ULONG_PTR
)SecurityDescriptor
->Sacl
% sizeof(ULONG
))
990 DPRINT1("Invalid SACL alignment\n");
994 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Sacl
);
995 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
996 (Acl
->AclRevision
> MAX_ACL_REVISION
))
998 DPRINT1("Invalid SACL revision\n");
1002 SdLength
+= Acl
->AclSize
;
1003 if (Length
< SdLength
)
1005 DPRINT1("Invalid SACL size\n");