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
,
128 PISECURITY_DESCRIPTOR_RELATIVE SdRel
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
130 DPRINT("SeSetWorldSecurityDescriptor() called\n");
132 if (SecurityInformation
== 0)
134 return STATUS_ACCESS_DENIED
;
137 /* calculate the minimum size of the buffer */
138 SidSize
= RtlLengthSid(SeWorldSid
);
139 SdSize
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
140 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
142 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
144 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
146 SdSize
+= sizeof(ACL
) + sizeof(ACE
) + SidSize
;
149 if (*BufferLength
< SdSize
)
151 *BufferLength
= SdSize
;
152 return STATUS_BUFFER_TOO_SMALL
;
155 *BufferLength
= SdSize
;
157 Status
= RtlCreateSecurityDescriptorRelative(SdRel
,
158 SECURITY_DESCRIPTOR_REVISION
);
159 if (!NT_SUCCESS(Status
))
164 Current
= (ULONG_PTR
)(SdRel
+ 1);
166 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
168 RtlCopyMemory((PVOID
)Current
,
171 SdRel
->Owner
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)SdRel
);
175 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
177 RtlCopyMemory((PVOID
)Current
,
180 SdRel
->Group
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)SdRel
);
184 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
186 PACL Dacl
= (PACL
)Current
;
187 SdRel
->Control
|= SE_DACL_PRESENT
;
189 Status
= RtlCreateAcl(Dacl
,
190 sizeof(ACL
) + sizeof(ACE
) + SidSize
,
192 if (!NT_SUCCESS(Status
))
195 Status
= RtlAddAccessAllowedAce(Dacl
,
199 if (!NT_SUCCESS(Status
))
202 SdRel
->Dacl
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)SdRel
);
205 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
207 /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */
210 return STATUS_SUCCESS
;
216 SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
217 IN KPROCESSOR_MODE AccessMode
,
218 IN POOL_TYPE PoolType
,
219 IN BOOLEAN CaptureIfKernel
,
220 OUT PSECURITY_QUALITY_OF_SERVICE
*CapturedSecurityQualityOfService
,
221 OUT PBOOLEAN Present
)
223 PSECURITY_QUALITY_OF_SERVICE CapturedQos
;
224 NTSTATUS Status
= STATUS_SUCCESS
;
228 ASSERT(CapturedSecurityQualityOfService
);
231 if(ObjectAttributes
!= NULL
)
233 if(AccessMode
!= KernelMode
)
235 SECURITY_QUALITY_OF_SERVICE SafeQos
;
239 ProbeForRead(ObjectAttributes
,
240 sizeof(ObjectAttributes
),
242 if(ObjectAttributes
->Length
== sizeof(OBJECT_ATTRIBUTES
))
244 if(ObjectAttributes
->SecurityQualityOfService
!= NULL
)
246 ProbeForRead(ObjectAttributes
->SecurityQualityOfService
,
247 sizeof(SECURITY_QUALITY_OF_SERVICE
),
250 if(((PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
)->Length
==
251 sizeof(SECURITY_QUALITY_OF_SERVICE
))
253 /* don't allocate memory here because ExAllocate should bugcheck
254 the system if it's buggy, SEH would catch that! So make a local
255 copy of the qos structure.*/
256 RtlCopyMemory(&SafeQos
,
257 ObjectAttributes
->SecurityQualityOfService
,
258 sizeof(SECURITY_QUALITY_OF_SERVICE
));
263 Status
= STATUS_INVALID_PARAMETER
;
268 *CapturedSecurityQualityOfService
= NULL
;
274 Status
= STATUS_INVALID_PARAMETER
;
279 Status
= _SEH_GetExceptionCode();
283 if(NT_SUCCESS(Status
))
287 CapturedQos
= ExAllocatePool(PoolType
,
288 sizeof(SECURITY_QUALITY_OF_SERVICE
));
289 if(CapturedQos
!= NULL
)
291 RtlCopyMemory(CapturedQos
,
293 sizeof(SECURITY_QUALITY_OF_SERVICE
));
294 *CapturedSecurityQualityOfService
= CapturedQos
;
298 Status
= STATUS_INSUFFICIENT_RESOURCES
;
303 *CapturedSecurityQualityOfService
= NULL
;
309 if(ObjectAttributes
->Length
== sizeof(OBJECT_ATTRIBUTES
))
313 if(ObjectAttributes
->SecurityQualityOfService
!= NULL
)
315 if(((PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
)->Length
==
316 sizeof(SECURITY_QUALITY_OF_SERVICE
))
318 CapturedQos
= ExAllocatePool(PoolType
,
319 sizeof(SECURITY_QUALITY_OF_SERVICE
));
320 if(CapturedQos
!= NULL
)
322 RtlCopyMemory(CapturedQos
,
323 ObjectAttributes
->SecurityQualityOfService
,
324 sizeof(SECURITY_QUALITY_OF_SERVICE
));
325 *CapturedSecurityQualityOfService
= CapturedQos
;
330 Status
= STATUS_INSUFFICIENT_RESOURCES
;
335 Status
= STATUS_INVALID_PARAMETER
;
340 *CapturedSecurityQualityOfService
= NULL
;
346 *CapturedSecurityQualityOfService
= (PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
;
347 *Present
= (ObjectAttributes
->SecurityQualityOfService
!= NULL
);
352 Status
= STATUS_INVALID_PARAMETER
;
358 *CapturedSecurityQualityOfService
= NULL
;
368 SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL
,
369 IN KPROCESSOR_MODE AccessMode
,
370 IN BOOLEAN CaptureIfKernel
)
374 if(CapturedSecurityQualityOfService
!= NULL
&&
375 (AccessMode
!= KernelMode
|| CaptureIfKernel
))
377 ExFreePool(CapturedSecurityQualityOfService
);
387 SeCaptureSecurityDescriptor(
388 IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor
,
389 IN KPROCESSOR_MODE CurrentMode
,
390 IN POOL_TYPE PoolType
,
391 IN BOOLEAN CaptureIfKernel
,
392 OUT PSECURITY_DESCRIPTOR
*CapturedSecurityDescriptor
395 PISECURITY_DESCRIPTOR OriginalSecurityDescriptor
= _OriginalSecurityDescriptor
;
396 SECURITY_DESCRIPTOR DescriptorCopy
;
397 PISECURITY_DESCRIPTOR NewDescriptor
;
398 ULONG OwnerSAC
= 0, GroupSAC
= 0;
399 ULONG OwnerSize
= 0, GroupSize
= 0;
400 ULONG SaclSize
= 0, DaclSize
= 0;
401 ULONG DescriptorSize
= 0;
402 NTSTATUS Status
= STATUS_SUCCESS
;
404 if(OriginalSecurityDescriptor
!= NULL
)
406 if(CurrentMode
!= KernelMode
)
408 RtlZeroMemory(&DescriptorCopy
, sizeof(DescriptorCopy
));
412 /* first only probe and copy until the control field of the descriptor
413 to determine whether it's a self-relative descriptor */
414 DescriptorSize
= FIELD_OFFSET(SECURITY_DESCRIPTOR
,
416 ProbeForRead(OriginalSecurityDescriptor
,
420 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
422 Status
= STATUS_UNKNOWN_REVISION
;
426 /* make a copy on the stack */
427 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
428 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
429 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
430 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
431 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
433 /* probe and copy the entire security descriptor structure. The SIDs
434 and ACLs will be probed and copied later though */
435 ProbeForRead(OriginalSecurityDescriptor
,
438 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
440 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
442 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
443 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
444 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
445 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
449 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
450 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
451 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
452 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
457 Status
= _SEH_GetExceptionCode();
461 if(!NT_SUCCESS(Status
))
466 else if(!CaptureIfKernel
)
468 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
470 return STATUS_UNKNOWN_REVISION
;
473 *CapturedSecurityDescriptor
= OriginalSecurityDescriptor
;
474 return STATUS_SUCCESS
;
478 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
480 return STATUS_UNKNOWN_REVISION
;
483 /* make a copy on the stack */
484 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
485 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
486 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
487 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
488 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
489 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
491 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
493 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
494 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
495 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
496 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
500 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
501 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
502 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
503 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
507 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
509 /* in case we're dealing with a self-relative descriptor, do a basic convert
510 to an absolute descriptor. We do this so we can simply access the data
511 using the pointers without calculating them again. */
512 DescriptorCopy
.Control
&= ~SE_SELF_RELATIVE
;
513 if(DescriptorCopy
.Owner
!= NULL
)
515 DescriptorCopy
.Owner
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Owner
);
517 if(DescriptorCopy
.Group
!= NULL
)
519 DescriptorCopy
.Group
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Group
);
521 if(DescriptorCopy
.Dacl
!= NULL
)
523 DescriptorCopy
.Dacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Dacl
);
525 if(DescriptorCopy
.Sacl
!= NULL
)
527 DescriptorCopy
.Sacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Sacl
);
531 /* determine the size of the SIDs */
532 #define DetermineSIDSize(SidType) \
534 if(DescriptorCopy.SidType != NULL) \
536 SID *SidType = (SID*)DescriptorCopy.SidType; \
538 if(CurrentMode != KernelMode) \
540 /* securely access the buffers! */ \
543 SidType##SAC = ProbeForReadUchar(&SidType->SubAuthorityCount); \
544 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
545 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
546 ProbeForRead(SidType, \
552 Status = _SEH_GetExceptionCode(); \
556 if(!NT_SUCCESS(Status)) \
563 SidType##SAC = SidType->SubAuthorityCount; \
564 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
565 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
570 DetermineSIDSize(Owner
);
571 DetermineSIDSize(Group
);
573 #undef DetermineSIDSize
575 /* determine the size of the ACLs */
576 #define DetermineACLSize(AclType, AclFlag) \
578 if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \
579 DescriptorCopy.AclType != NULL) \
581 PACL AclType = (PACL)DescriptorCopy.AclType; \
583 if(CurrentMode != KernelMode) \
585 /* securely access the buffers! */ \
588 AclType##Size = ProbeForReadUshort(&AclType->AclSize); \
589 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
590 ProbeForRead(AclType, \
596 Status = _SEH_GetExceptionCode(); \
600 if(!NT_SUCCESS(Status)) \
607 AclType##Size = AclType->AclSize; \
608 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
613 DescriptorCopy.AclType = NULL; \
617 DetermineACLSize(Sacl
, SACL
);
618 DetermineACLSize(Dacl
, DACL
);
620 #undef DetermineACLSize
622 /* allocate enough memory to store a complete copy of a self-relative
623 security descriptor */
624 NewDescriptor
= ExAllocatePool(PoolType
,
626 if(NewDescriptor
!= NULL
)
628 ULONG_PTR Offset
= sizeof(SECURITY_DESCRIPTOR
);
630 RtlZeroMemory(NewDescriptor
, DescriptorSize
);
631 NewDescriptor
->Revision
= DescriptorCopy
.Revision
;
632 NewDescriptor
->Sbz1
= DescriptorCopy
.Sbz1
;
633 NewDescriptor
->Control
= DescriptorCopy
.Control
| SE_SELF_RELATIVE
;
637 /* setup the offsets and copy the SIDs and ACLs to the new
638 self-relative security descriptor. Probing the pointers is not
639 neccessary anymore as we did that when collecting the sizes!
640 Make sure to validate the SIDs and ACLs *again* as they could have
641 been modified in the meanwhile! */
642 #define CopySID(Type) \
644 if(DescriptorCopy.Type != NULL) \
646 NewDescriptor->Type = (PVOID)Offset; \
647 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
648 (ULONG_PTR)NewDescriptor->Type), \
649 DescriptorCopy.Type, \
651 if (!RtlValidSid((PSID)((ULONG_PTR)NewDescriptor + \
652 (ULONG_PTR)NewDescriptor->Type))) \
654 RtlRaiseStatus(STATUS_INVALID_SID); \
656 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
665 #define CopyACL(Type) \
667 if(DescriptorCopy.Type != NULL) \
669 NewDescriptor->Type = (PVOID)Offset; \
670 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
671 (ULONG_PTR)NewDescriptor->Type), \
672 DescriptorCopy.Type, \
674 if (!RtlValidAcl((PACL)((ULONG_PTR)NewDescriptor + \
675 (ULONG_PTR)NewDescriptor->Type))) \
677 RtlRaiseStatus(STATUS_INVALID_ACL); \
679 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
690 Status
= _SEH_GetExceptionCode();
694 if(NT_SUCCESS(Status
))
696 /* we're finally done! copy the pointer to the captured descriptor to
698 *CapturedSecurityDescriptor
= NewDescriptor
;
699 return STATUS_SUCCESS
;
703 /* we failed to copy the data to the new descriptor */
704 ExFreePool(NewDescriptor
);
709 Status
= STATUS_INSUFFICIENT_RESOURCES
;
714 /* nothing to do... */
715 *CapturedSecurityDescriptor
= NULL
;
725 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation
,
726 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
727 IN OUT PULONG Length
,
728 IN PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor OPTIONAL
)
730 PISECURITY_DESCRIPTOR ObjectSd
;
731 PISECURITY_DESCRIPTOR_RELATIVE RelSD
;
736 ULONG OwnerLength
= 0;
737 ULONG GroupLength
= 0;
738 ULONG DaclLength
= 0;
739 ULONG SaclLength
= 0;
744 RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
746 if (*ObjectsSecurityDescriptor
== NULL
)
748 if (*Length
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
))
750 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
751 return STATUS_BUFFER_TOO_SMALL
;
754 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
755 RtlCreateSecurityDescriptorRelative(RelSD
,
756 SECURITY_DESCRIPTOR_REVISION
);
757 return STATUS_SUCCESS
;
760 ObjectSd
= *ObjectsSecurityDescriptor
;
762 /* Calculate the required security descriptor length */
763 Control
= SE_SELF_RELATIVE
;
764 if ((*SecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
765 (ObjectSd
->Owner
!= NULL
))
767 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
768 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
769 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
772 if ((*SecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
773 (ObjectSd
->Group
!= NULL
))
775 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
776 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
777 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
780 if ((*SecurityInformation
& DACL_SECURITY_INFORMATION
) &&
781 (ObjectSd
->Control
& SE_DACL_PRESENT
))
783 if (ObjectSd
->Dacl
!= NULL
)
785 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
786 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
788 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
791 if ((*SecurityInformation
& SACL_SECURITY_INFORMATION
) &&
792 (ObjectSd
->Control
& SE_SACL_PRESENT
))
794 if (ObjectSd
->Sacl
!= NULL
)
796 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
797 SaclLength
= ROUND_UP(Sacl
->AclSize
, 4);
799 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
802 SdLength
= OwnerLength
+ GroupLength
+ DaclLength
+
803 SaclLength
+ sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
804 if (*Length
< SdLength
)
807 return STATUS_BUFFER_TOO_SMALL
;
810 /* Build the new security descrtiptor */
811 RtlCreateSecurityDescriptorRelative(RelSD
,
812 SECURITY_DESCRIPTOR_REVISION
);
813 RelSD
->Control
= (USHORT
)Control
;
815 Current
= (ULONG_PTR
)(RelSD
+ 1);
817 if (OwnerLength
!= 0)
819 RtlCopyMemory((PVOID
)Current
,
822 RelSD
->Owner
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
823 Current
+= OwnerLength
;
826 if (GroupLength
!= 0)
828 RtlCopyMemory((PVOID
)Current
,
831 RelSD
->Group
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
832 Current
+= GroupLength
;
837 RtlCopyMemory((PVOID
)Current
,
840 RelSD
->Dacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
841 Current
+= DaclLength
;
846 RtlCopyMemory((PVOID
)Current
,
849 RelSD
->Sacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
850 Current
+= SaclLength
;
855 return STATUS_SUCCESS
;
863 SeReleaseSecurityDescriptor(
864 IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor
,
865 IN KPROCESSOR_MODE CurrentMode
,
866 IN BOOLEAN CaptureIfKernelMode
871 /* WARNING! You need to call this function with the same value for CurrentMode
872 and CaptureIfKernelMode that you previously passed to
873 SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
874 if(CapturedSecurityDescriptor
!= NULL
&&
875 (CurrentMode
!= KernelMode
||
876 (CurrentMode
== KernelMode
&& CaptureIfKernelMode
)))
878 /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
879 ExFreePool(CapturedSecurityDescriptor
);
882 return STATUS_SUCCESS
;
889 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL
,
890 IN PSECURITY_INFORMATION SecurityInformation
,
891 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
892 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
893 IN POOL_TYPE PoolType
,
894 IN PGENERIC_MAPPING GenericMapping
)
897 return STATUS_NOT_IMPLEMENTED
;
905 SeSetSecurityDescriptorInfoEx(
906 IN PVOID Object OPTIONAL
,
907 IN PSECURITY_INFORMATION SecurityInformation
,
908 IN PSECURITY_DESCRIPTOR ModificationDescriptor
,
909 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
910 IN ULONG AutoInheritFlags
,
911 IN POOL_TYPE PoolType
,
912 IN PGENERIC_MAPPING GenericMapping
916 return STATUS_NOT_IMPLEMENTED
;
924 SeValidSecurityDescriptor(IN ULONG Length
,
925 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
)
930 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
932 if (Length
< SECURITY_DESCRIPTOR_MIN_LENGTH
)
934 DPRINT1("Invalid Security Descriptor revision\n");
938 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
940 DPRINT1("Invalid Security Descriptor revision\n");
944 if (!(SecurityDescriptor
->Control
& SE_SELF_RELATIVE
))
946 DPRINT1("No self-relative Security Descriptor\n");
950 SdLength
= sizeof(SECURITY_DESCRIPTOR
);
952 /* Check Owner SID */
953 if (SecurityDescriptor
->Owner
== NULL
)
955 DPRINT1("No Owner SID\n");
959 if ((ULONG_PTR
)SecurityDescriptor
->Owner
% sizeof(ULONG
))
961 DPRINT1("Invalid Owner SID alignment\n");
965 Sid
= (PISID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Owner
);
966 if (Sid
->Revision
!= SID_REVISION
)
968 DPRINT1("Invalid Owner SID revision\n");
972 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
973 if (Length
< SdLength
)
975 DPRINT1("Invalid Owner SID size\n");
979 /* Check Group SID */
980 if (SecurityDescriptor
->Group
!= NULL
)
982 if ((ULONG_PTR
)SecurityDescriptor
->Group
% sizeof(ULONG
))
984 DPRINT1("Invalid Group SID alignment\n");
988 Sid
= (PSID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Group
);
989 if (Sid
->Revision
!= SID_REVISION
)
991 DPRINT1("Invalid Group SID revision\n");
995 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
996 if (Length
< SdLength
)
998 DPRINT1("Invalid Group SID size\n");
1004 if (SecurityDescriptor
->Dacl
!= NULL
)
1006 if ((ULONG_PTR
)SecurityDescriptor
->Dacl
% sizeof(ULONG
))
1008 DPRINT1("Invalid DACL alignment\n");
1012 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Dacl
);
1013 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) &&
1014 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1016 DPRINT1("Invalid DACL revision\n");
1020 SdLength
+= Acl
->AclSize
;
1021 if (Length
< SdLength
)
1023 DPRINT1("Invalid DACL size\n");
1029 if (SecurityDescriptor
->Sacl
!= NULL
)
1031 if ((ULONG_PTR
)SecurityDescriptor
->Sacl
% sizeof(ULONG
))
1033 DPRINT1("Invalid SACL alignment\n");
1037 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Sacl
);
1038 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
1039 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1041 DPRINT1("Invalid SACL revision\n");
1045 SdLength
+= Acl
->AclSize
;
1046 if (Length
< SdLength
)
1048 DPRINT1("Invalid SACL size\n");