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
= (DWORD
)((ULONG_PTR
)Current
- (ULONG_PTR
)SdRel
);
175 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
177 RtlCopyMemory((PVOID
)Current
,
180 SdRel
->Group
= (DWORD
)((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
= (DWORD
)((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
= (ULONG
)((ULONG_PTR
)&OriginalSecurityDescriptor
->Control
-
415 (ULONG_PTR
)OriginalSecurityDescriptor
) +
416 sizeof(OriginalSecurityDescriptor
->Control
);
417 ProbeForRead(OriginalSecurityDescriptor
,
421 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
423 Status
= STATUS_UNKNOWN_REVISION
;
427 /* make a copy on the stack */
428 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
429 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
430 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
431 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
432 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
434 /* probe and copy the entire security descriptor structure. The SIDs
435 and ACLs will be probed and copied later though */
436 ProbeForRead(OriginalSecurityDescriptor
,
439 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
441 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
443 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
444 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
445 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
446 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
450 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
451 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
452 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
453 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
458 Status
= _SEH_GetExceptionCode();
462 if(!NT_SUCCESS(Status
))
467 else if(!CaptureIfKernel
)
469 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
471 return STATUS_UNKNOWN_REVISION
;
474 *CapturedSecurityDescriptor
= OriginalSecurityDescriptor
;
475 return STATUS_SUCCESS
;
479 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
481 return STATUS_UNKNOWN_REVISION
;
484 /* make a copy on the stack */
485 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
486 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
487 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
488 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
489 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
490 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
492 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
494 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
495 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
496 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
497 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
501 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
502 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
503 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
504 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
508 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
510 /* in case we're dealing with a self-relative descriptor, do a basic convert
511 to an absolute descriptor. We do this so we can simply access the data
512 using the pointers without calculating them again. */
513 DescriptorCopy
.Control
&= ~SE_SELF_RELATIVE
;
514 if(DescriptorCopy
.Owner
!= NULL
)
516 DescriptorCopy
.Owner
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Owner
);
518 if(DescriptorCopy
.Group
!= NULL
)
520 DescriptorCopy
.Group
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Group
);
522 if(DescriptorCopy
.Dacl
!= NULL
)
524 DescriptorCopy
.Dacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Dacl
);
526 if(DescriptorCopy
.Sacl
!= NULL
)
528 DescriptorCopy
.Sacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Sacl
);
532 /* determine the size of the SIDs */
533 #define DetermineSIDSize(SidType) \
535 if(DescriptorCopy.SidType != NULL) \
537 SID *SidType = (SID*)DescriptorCopy.SidType; \
539 if(CurrentMode != KernelMode) \
541 /* securely access the buffers! */ \
544 ProbeForRead(&SidType->SubAuthorityCount, \
545 sizeof(SidType->SubAuthorityCount), \
547 SidType##SAC = SidType->SubAuthorityCount; \
548 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
549 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
550 ProbeForRead(SidType, \
556 Status = _SEH_GetExceptionCode(); \
560 if(!NT_SUCCESS(Status)) \
567 SidType##SAC = SidType->SubAuthorityCount; \
568 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
569 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
574 DetermineSIDSize(Owner
);
575 DetermineSIDSize(Group
);
577 /* determine the size of the ACLs */
578 #define DetermineACLSize(AclType, AclFlag) \
580 if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \
581 DescriptorCopy.AclType != NULL) \
583 PACL AclType = (PACL)DescriptorCopy.AclType; \
585 if(CurrentMode != KernelMode) \
587 /* securely access the buffers! */ \
590 ProbeForRead(&AclType->AclSize, \
591 sizeof(AclType->AclSize), \
593 AclType##Size = AclType->AclSize; \
594 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
595 ProbeForRead(AclType, \
601 Status = _SEH_GetExceptionCode(); \
605 if(!NT_SUCCESS(Status)) \
612 AclType##Size = AclType->AclSize; \
613 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
618 DescriptorCopy.AclType = NULL; \
622 DetermineACLSize(Sacl
, SACL
);
623 DetermineACLSize(Dacl
, DACL
);
625 /* allocate enough memory to store a complete copy of a self-relative
626 security descriptor */
627 NewDescriptor
= ExAllocatePool(PoolType
,
629 if(NewDescriptor
!= NULL
)
631 ULONG_PTR Offset
= sizeof(SECURITY_DESCRIPTOR
);
633 RtlZeroMemory(NewDescriptor
, DescriptorSize
);
634 NewDescriptor
->Revision
= DescriptorCopy
.Revision
;
635 NewDescriptor
->Sbz1
= DescriptorCopy
.Sbz1
;
636 NewDescriptor
->Control
= DescriptorCopy
.Control
| SE_SELF_RELATIVE
;
640 /* setup the offsets and copy the SIDs and ACLs to the new
641 self-relative security descriptor. Probing the pointers is not
642 neccessary anymore as we did that when collecting the sizes!
643 Make sure to validate the SIDs and ACLs *again* as they could have
644 been modified in the meanwhile! */
645 #define CopySID(Type) \
647 if(DescriptorCopy.Type != NULL) \
649 NewDescriptor->Type = (PVOID)Offset; \
650 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
651 (ULONG_PTR)NewDescriptor->Type), \
652 DescriptorCopy.Type, \
654 if (!RtlValidSid((PSID)((ULONG_PTR)NewDescriptor + \
655 (ULONG_PTR)NewDescriptor->Type))) \
657 RtlRaiseStatus(STATUS_INVALID_SID); \
659 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
666 #define CopyACL(Type) \
668 if(DescriptorCopy.Type != NULL) \
670 NewDescriptor->Type = (PVOID)Offset; \
671 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
672 (ULONG_PTR)NewDescriptor->Type), \
673 DescriptorCopy.Type, \
675 if (!RtlValidAcl((PACL)((ULONG_PTR)NewDescriptor + \
676 (ULONG_PTR)NewDescriptor->Type))) \
678 RtlRaiseStatus(STATUS_INVALID_ACL); \
680 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
689 Status
= _SEH_GetExceptionCode();
693 if(NT_SUCCESS(Status
))
695 /* we're finally done! copy the pointer to the captured descriptor to
697 *CapturedSecurityDescriptor
= NewDescriptor
;
698 return STATUS_SUCCESS
;
702 /* we failed to copy the data to the new descriptor */
703 ExFreePool(NewDescriptor
);
708 Status
= STATUS_INSUFFICIENT_RESOURCES
;
713 /* nothing to do... */
714 *CapturedSecurityDescriptor
= NULL
;
724 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation
,
725 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
726 IN OUT PULONG Length
,
727 IN PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor OPTIONAL
)
729 PISECURITY_DESCRIPTOR ObjectSd
;
730 PISECURITY_DESCRIPTOR_RELATIVE RelSD
;
735 ULONG OwnerLength
= 0;
736 ULONG GroupLength
= 0;
737 ULONG DaclLength
= 0;
738 ULONG SaclLength
= 0;
743 RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
745 if (*ObjectsSecurityDescriptor
== NULL
)
747 if (*Length
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
))
749 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
750 return STATUS_BUFFER_TOO_SMALL
;
753 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
754 RtlCreateSecurityDescriptorRelative(RelSD
,
755 SECURITY_DESCRIPTOR_REVISION
);
756 return STATUS_SUCCESS
;
759 ObjectSd
= *ObjectsSecurityDescriptor
;
761 /* Calculate the required security descriptor length */
762 Control
= SE_SELF_RELATIVE
;
763 if ((*SecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
764 (ObjectSd
->Owner
!= NULL
))
766 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
767 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
768 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
771 if ((*SecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
772 (ObjectSd
->Group
!= NULL
))
774 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
775 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
776 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
779 if ((*SecurityInformation
& DACL_SECURITY_INFORMATION
) &&
780 (ObjectSd
->Control
& SE_DACL_PRESENT
))
782 if (ObjectSd
->Dacl
!= NULL
)
784 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
785 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
787 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
790 if ((*SecurityInformation
& SACL_SECURITY_INFORMATION
) &&
791 (ObjectSd
->Control
& SE_SACL_PRESENT
))
793 if (ObjectSd
->Sacl
!= NULL
)
795 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
796 SaclLength
= ROUND_UP(Sacl
->AclSize
, 4);
798 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
801 SdLength
= OwnerLength
+ GroupLength
+ DaclLength
+
802 SaclLength
+ sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
803 if (*Length
< SdLength
)
806 return STATUS_BUFFER_TOO_SMALL
;
809 /* Build the new security descrtiptor */
810 RtlCreateSecurityDescriptorRelative(RelSD
,
811 SECURITY_DESCRIPTOR_REVISION
);
812 RelSD
->Control
= Control
;
814 Current
= (ULONG_PTR
)(RelSD
+ 1);
816 if (OwnerLength
!= 0)
818 RtlCopyMemory((PVOID
)Current
,
821 RelSD
->Owner
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
822 Current
+= OwnerLength
;
825 if (GroupLength
!= 0)
827 RtlCopyMemory((PVOID
)Current
,
830 RelSD
->Group
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
831 Current
+= GroupLength
;
836 RtlCopyMemory((PVOID
)Current
,
839 RelSD
->Dacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
840 Current
+= DaclLength
;
845 RtlCopyMemory((PVOID
)Current
,
848 RelSD
->Sacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
849 Current
+= SaclLength
;
854 return STATUS_SUCCESS
;
862 SeReleaseSecurityDescriptor(
863 IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor
,
864 IN KPROCESSOR_MODE CurrentMode
,
865 IN BOOLEAN CaptureIfKernelMode
870 /* WARNING! You need to call this function with the same value for CurrentMode
871 and CaptureIfKernelMode that you previously passed to
872 SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
873 if(CapturedSecurityDescriptor
!= NULL
&&
874 (CurrentMode
!= KernelMode
||
875 (CurrentMode
== KernelMode
&& CaptureIfKernelMode
)))
877 /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
878 ExFreePool(CapturedSecurityDescriptor
);
881 return STATUS_SUCCESS
;
888 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL
,
889 IN PSECURITY_INFORMATION SecurityInformation
,
890 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
891 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
892 IN POOL_TYPE PoolType
,
893 IN PGENERIC_MAPPING GenericMapping
)
896 return STATUS_NOT_IMPLEMENTED
;
904 SeSetSecurityDescriptorInfoEx(
905 IN PVOID Object OPTIONAL
,
906 IN PSECURITY_INFORMATION SecurityInformation
,
907 IN PSECURITY_DESCRIPTOR ModificationDescriptor
,
908 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
909 IN ULONG AutoInheritFlags
,
910 IN POOL_TYPE PoolType
,
911 IN PGENERIC_MAPPING GenericMapping
915 return STATUS_NOT_IMPLEMENTED
;
923 SeValidSecurityDescriptor(IN ULONG Length
,
924 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
)
929 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
931 if (Length
< SECURITY_DESCRIPTOR_MIN_LENGTH
)
933 DPRINT1("Invalid Security Descriptor revision\n");
937 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
939 DPRINT1("Invalid Security Descriptor revision\n");
943 if (!(SecurityDescriptor
->Control
& SE_SELF_RELATIVE
))
945 DPRINT1("No self-relative Security Descriptor\n");
949 SdLength
= sizeof(SECURITY_DESCRIPTOR
);
951 /* Check Owner SID */
952 if (SecurityDescriptor
->Owner
== NULL
)
954 DPRINT1("No Owner SID\n");
958 if ((ULONG_PTR
)SecurityDescriptor
->Owner
% sizeof(ULONG
))
960 DPRINT1("Invalid Owner SID alignment\n");
964 Sid
= (PISID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Owner
);
965 if (Sid
->Revision
!= SID_REVISION
)
967 DPRINT1("Invalid Owner SID revision\n");
971 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
972 if (Length
< SdLength
)
974 DPRINT1("Invalid Owner SID size\n");
978 /* Check Group SID */
979 if (SecurityDescriptor
->Group
!= NULL
)
981 if ((ULONG_PTR
)SecurityDescriptor
->Group
% sizeof(ULONG
))
983 DPRINT1("Invalid Group SID alignment\n");
987 Sid
= (PSID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Group
);
988 if (Sid
->Revision
!= SID_REVISION
)
990 DPRINT1("Invalid Group SID revision\n");
994 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
995 if (Length
< SdLength
)
997 DPRINT1("Invalid Group SID size\n");
1003 if (SecurityDescriptor
->Dacl
!= NULL
)
1005 if ((ULONG_PTR
)SecurityDescriptor
->Dacl
% sizeof(ULONG
))
1007 DPRINT1("Invalid DACL alignment\n");
1011 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Dacl
);
1012 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) &&
1013 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1015 DPRINT1("Invalid DACL revision\n");
1019 SdLength
+= Acl
->AclSize
;
1020 if (Length
< SdLength
)
1022 DPRINT1("Invalid DACL size\n");
1028 if (SecurityDescriptor
->Sacl
!= NULL
)
1030 if ((ULONG_PTR
)SecurityDescriptor
->Sacl
% sizeof(ULONG
))
1032 DPRINT1("Invalid SACL alignment\n");
1036 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Sacl
);
1037 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
1038 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1040 DPRINT1("Invalid SACL revision\n");
1044 SdLength
+= Acl
->AclSize
;
1045 if (Length
< SdLength
)
1047 DPRINT1("Invalid SACL size\n");