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 **********************************************************/
36 /* Create PublicDefaultSd */
37 SePublicDefaultSd
= ExAllocatePoolWithTag(PagedPool
,
38 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
39 if (SePublicDefaultSd
== NULL
)
42 RtlCreateSecurityDescriptor(SePublicDefaultSd
,
43 SECURITY_DESCRIPTOR_REVISION
);
44 RtlSetDaclSecurityDescriptor(SePublicDefaultSd
,
49 /* Create PublicDefaultUnrestrictedSd */
50 SePublicDefaultUnrestrictedSd
= ExAllocatePoolWithTag(PagedPool
,
51 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
52 if (SePublicDefaultUnrestrictedSd
== NULL
)
55 RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd
,
56 SECURITY_DESCRIPTOR_REVISION
);
57 RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd
,
59 SePublicDefaultUnrestrictedDacl
,
62 /* Create PublicOpenSd */
63 SePublicOpenSd
= ExAllocatePoolWithTag(PagedPool
,
64 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
65 if (SePublicOpenSd
== NULL
)
68 RtlCreateSecurityDescriptor(SePublicOpenSd
,
69 SECURITY_DESCRIPTOR_REVISION
);
70 RtlSetDaclSecurityDescriptor(SePublicOpenSd
,
75 /* Create PublicOpenUnrestrictedSd */
76 SePublicOpenUnrestrictedSd
= ExAllocatePoolWithTag(PagedPool
,
77 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
78 if (SePublicOpenUnrestrictedSd
== NULL
)
81 RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd
,
82 SECURITY_DESCRIPTOR_REVISION
);
83 RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd
,
85 SePublicOpenUnrestrictedDacl
,
88 /* Create SystemDefaultSd */
89 SeSystemDefaultSd
= ExAllocatePoolWithTag(PagedPool
,
90 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
91 if (SeSystemDefaultSd
== NULL
)
94 RtlCreateSecurityDescriptor(SeSystemDefaultSd
,
95 SECURITY_DESCRIPTOR_REVISION
);
96 RtlSetDaclSecurityDescriptor(SeSystemDefaultSd
,
101 /* Create UnrestrictedSd */
102 SeUnrestrictedSd
= ExAllocatePoolWithTag(PagedPool
,
103 sizeof(SECURITY_DESCRIPTOR
), TAG_SD
);
104 if (SeUnrestrictedSd
== NULL
)
107 RtlCreateSecurityDescriptor(SeUnrestrictedSd
,
108 SECURITY_DESCRIPTOR_REVISION
);
109 RtlSetDaclSecurityDescriptor(SeUnrestrictedSd
,
119 SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation
,
120 PISECURITY_DESCRIPTOR SecurityDescriptor
,
127 PISECURITY_DESCRIPTOR_RELATIVE SdRel
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
129 DPRINT("SeSetWorldSecurityDescriptor() called\n");
131 if (SecurityInformation
== 0)
133 return STATUS_ACCESS_DENIED
;
136 /* calculate the minimum size of the buffer */
137 SidSize
= RtlLengthSid(SeWorldSid
);
138 SdSize
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
139 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
141 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
143 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
145 SdSize
+= sizeof(ACL
) + sizeof(ACE
) + SidSize
;
148 if (*BufferLength
< SdSize
)
150 *BufferLength
= SdSize
;
151 return STATUS_BUFFER_TOO_SMALL
;
154 *BufferLength
= SdSize
;
156 Status
= RtlCreateSecurityDescriptorRelative(SdRel
,
157 SECURITY_DESCRIPTOR_REVISION
);
158 if (!NT_SUCCESS(Status
))
163 Current
= (ULONG_PTR
)(SdRel
+ 1);
165 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
167 RtlCopyMemory((PVOID
)Current
,
170 SdRel
->Owner
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)SdRel
);
174 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
176 RtlCopyMemory((PVOID
)Current
,
179 SdRel
->Group
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)SdRel
);
183 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
185 PACL Dacl
= (PACL
)Current
;
186 SdRel
->Control
|= SE_DACL_PRESENT
;
188 Status
= RtlCreateAcl(Dacl
,
189 sizeof(ACL
) + sizeof(ACE
) + SidSize
,
191 if (!NT_SUCCESS(Status
))
194 Status
= RtlAddAccessAllowedAce(Dacl
,
198 if (!NT_SUCCESS(Status
))
201 SdRel
->Dacl
= (ULONG
)((ULONG_PTR
)Current
- (ULONG_PTR
)SdRel
);
204 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
206 /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */
209 return STATUS_SUCCESS
;
215 SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
216 IN KPROCESSOR_MODE AccessMode
,
217 IN POOL_TYPE PoolType
,
218 IN BOOLEAN CaptureIfKernel
,
219 OUT PSECURITY_QUALITY_OF_SERVICE
*CapturedSecurityQualityOfService
,
220 OUT PBOOLEAN Present
)
222 PSECURITY_QUALITY_OF_SERVICE CapturedQos
;
223 NTSTATUS Status
= STATUS_SUCCESS
;
227 ASSERT(CapturedSecurityQualityOfService
);
230 if(ObjectAttributes
!= NULL
)
232 if(AccessMode
!= KernelMode
)
234 SECURITY_QUALITY_OF_SERVICE SafeQos
;
238 ProbeForRead(ObjectAttributes
,
239 sizeof(OBJECT_ATTRIBUTES
),
241 if(ObjectAttributes
->Length
== sizeof(OBJECT_ATTRIBUTES
))
243 if(ObjectAttributes
->SecurityQualityOfService
!= NULL
)
245 ProbeForRead(ObjectAttributes
->SecurityQualityOfService
,
246 sizeof(SECURITY_QUALITY_OF_SERVICE
),
249 if(((PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
)->Length
==
250 sizeof(SECURITY_QUALITY_OF_SERVICE
))
252 /* don't allocate memory here because ExAllocate should bugcheck
253 the system if it's buggy, SEH would catch that! So make a local
254 copy of the qos structure.*/
255 RtlCopyMemory(&SafeQos
,
256 ObjectAttributes
->SecurityQualityOfService
,
257 sizeof(SECURITY_QUALITY_OF_SERVICE
));
262 Status
= STATUS_INVALID_PARAMETER
;
267 *CapturedSecurityQualityOfService
= NULL
;
273 Status
= STATUS_INVALID_PARAMETER
;
276 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
278 Status
= _SEH2_GetExceptionCode();
282 if(NT_SUCCESS(Status
))
286 CapturedQos
= ExAllocatePool(PoolType
,
287 sizeof(SECURITY_QUALITY_OF_SERVICE
));
288 if(CapturedQos
!= NULL
)
290 RtlCopyMemory(CapturedQos
,
292 sizeof(SECURITY_QUALITY_OF_SERVICE
));
293 *CapturedSecurityQualityOfService
= CapturedQos
;
297 Status
= STATUS_INSUFFICIENT_RESOURCES
;
302 *CapturedSecurityQualityOfService
= NULL
;
308 if(ObjectAttributes
->Length
== sizeof(OBJECT_ATTRIBUTES
))
312 if(ObjectAttributes
->SecurityQualityOfService
!= NULL
)
314 if(((PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
)->Length
==
315 sizeof(SECURITY_QUALITY_OF_SERVICE
))
317 CapturedQos
= ExAllocatePool(PoolType
,
318 sizeof(SECURITY_QUALITY_OF_SERVICE
));
319 if(CapturedQos
!= NULL
)
321 RtlCopyMemory(CapturedQos
,
322 ObjectAttributes
->SecurityQualityOfService
,
323 sizeof(SECURITY_QUALITY_OF_SERVICE
));
324 *CapturedSecurityQualityOfService
= CapturedQos
;
329 Status
= STATUS_INSUFFICIENT_RESOURCES
;
334 Status
= STATUS_INVALID_PARAMETER
;
339 *CapturedSecurityQualityOfService
= NULL
;
345 *CapturedSecurityQualityOfService
= (PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
;
346 *Present
= (ObjectAttributes
->SecurityQualityOfService
!= NULL
);
351 Status
= STATUS_INVALID_PARAMETER
;
357 *CapturedSecurityQualityOfService
= NULL
;
367 SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL
,
368 IN KPROCESSOR_MODE AccessMode
,
369 IN BOOLEAN CaptureIfKernel
)
373 if(CapturedSecurityQualityOfService
!= NULL
&&
374 (AccessMode
!= KernelMode
|| CaptureIfKernel
))
376 ExFreePool(CapturedSecurityQualityOfService
);
380 /* PUBLIC FUNCTIONS ***********************************************************/
387 SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor
,
388 IN KPROCESSOR_MODE CurrentMode
,
389 IN POOL_TYPE PoolType
,
390 IN BOOLEAN CaptureIfKernel
,
391 OUT PSECURITY_DESCRIPTOR
*CapturedSecurityDescriptor
)
393 PISECURITY_DESCRIPTOR OriginalSecurityDescriptor
= _OriginalSecurityDescriptor
;
394 SECURITY_DESCRIPTOR DescriptorCopy
;
395 PISECURITY_DESCRIPTOR NewDescriptor
;
396 ULONG OwnerSAC
= 0, GroupSAC
= 0;
397 ULONG OwnerSize
= 0, GroupSize
= 0;
398 ULONG SaclSize
= 0, DaclSize
= 0;
399 ULONG DescriptorSize
= 0;
400 NTSTATUS Status
= STATUS_SUCCESS
;
402 if(OriginalSecurityDescriptor
!= NULL
)
404 if(CurrentMode
!= KernelMode
)
406 RtlZeroMemory(&DescriptorCopy
, sizeof(DescriptorCopy
));
410 /* first only probe and copy until the control field of the descriptor
411 to determine whether it's a self-relative descriptor */
412 DescriptorSize
= FIELD_OFFSET(SECURITY_DESCRIPTOR
,
414 ProbeForRead(OriginalSecurityDescriptor
,
418 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
420 Status
= STATUS_UNKNOWN_REVISION
;
424 /* make a copy on the stack */
425 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
426 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
427 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
428 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
429 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
431 /* probe and copy the entire security descriptor structure. The SIDs
432 and ACLs will be probed and copied later though */
433 ProbeForRead(OriginalSecurityDescriptor
,
436 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
438 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
440 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
441 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
442 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
443 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
447 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
448 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
449 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
450 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
453 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
455 Status
= _SEH2_GetExceptionCode();
459 if(!NT_SUCCESS(Status
))
464 else if(!CaptureIfKernel
)
466 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
468 return STATUS_UNKNOWN_REVISION
;
471 *CapturedSecurityDescriptor
= OriginalSecurityDescriptor
;
472 return STATUS_SUCCESS
;
476 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
478 return STATUS_UNKNOWN_REVISION
;
481 /* make a copy on the stack */
482 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
483 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
484 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
485 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
486 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
487 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
489 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
491 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
492 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
493 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
494 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
498 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
499 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
500 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
501 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
505 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
507 /* in case we're dealing with a self-relative descriptor, do a basic convert
508 to an absolute descriptor. We do this so we can simply access the data
509 using the pointers without calculating them again. */
510 DescriptorCopy
.Control
&= ~SE_SELF_RELATIVE
;
511 if(DescriptorCopy
.Owner
!= NULL
)
513 DescriptorCopy
.Owner
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Owner
);
515 if(DescriptorCopy
.Group
!= NULL
)
517 DescriptorCopy
.Group
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Group
);
519 if(DescriptorCopy
.Dacl
!= NULL
)
521 DescriptorCopy
.Dacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Dacl
);
523 if(DescriptorCopy
.Sacl
!= NULL
)
525 DescriptorCopy
.Sacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Sacl
);
529 /* determine the size of the SIDs */
530 #define DetermineSIDSize(SidType) \
532 if(DescriptorCopy.SidType != NULL) \
534 SID *SidType = (SID*)DescriptorCopy.SidType; \
536 if(CurrentMode != KernelMode) \
538 /* securely access the buffers! */ \
541 SidType##SAC = ProbeForReadUchar(&SidType->SubAuthorityCount); \
542 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
543 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
544 ProbeForRead(SidType, \
548 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) \
550 Status = _SEH2_GetExceptionCode(); \
554 if(!NT_SUCCESS(Status)) \
561 SidType##SAC = SidType->SubAuthorityCount; \
562 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
563 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
568 DetermineSIDSize(Owner
);
569 DetermineSIDSize(Group
);
571 #undef DetermineSIDSize
573 /* determine the size of the ACLs */
574 #define DetermineACLSize(AclType, AclFlag) \
576 if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \
577 DescriptorCopy.AclType != NULL) \
579 PACL AclType = (PACL)DescriptorCopy.AclType; \
581 if(CurrentMode != KernelMode) \
583 /* securely access the buffers! */ \
586 AclType##Size = ProbeForReadUshort(&AclType->AclSize); \
587 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
588 ProbeForRead(AclType, \
592 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) \
594 Status = _SEH2_GetExceptionCode(); \
598 if(!NT_SUCCESS(Status)) \
605 AclType##Size = AclType->AclSize; \
606 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
611 DescriptorCopy.AclType = NULL; \
615 DetermineACLSize(Sacl
, SACL
);
616 DetermineACLSize(Dacl
, DACL
);
618 #undef DetermineACLSize
620 /* allocate enough memory to store a complete copy of a self-relative
621 security descriptor */
622 NewDescriptor
= ExAllocatePoolWithTag(PoolType
,
625 if(NewDescriptor
!= NULL
)
627 ULONG_PTR Offset
= sizeof(SECURITY_DESCRIPTOR
);
629 RtlZeroMemory(NewDescriptor
, DescriptorSize
);
630 NewDescriptor
->Revision
= DescriptorCopy
.Revision
;
631 NewDescriptor
->Sbz1
= DescriptorCopy
.Sbz1
;
632 NewDescriptor
->Control
= DescriptorCopy
.Control
| SE_SELF_RELATIVE
;
636 /* setup the offsets and copy the SIDs and ACLs to the new
637 self-relative security descriptor. Probing the pointers is not
638 neccessary anymore as we did that when collecting the sizes!
639 Make sure to validate the SIDs and ACLs *again* as they could have
640 been modified in the meanwhile! */
641 #define CopySID(Type) \
643 if(DescriptorCopy.Type != NULL) \
645 NewDescriptor->Type = (PVOID)Offset; \
646 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
647 (ULONG_PTR)NewDescriptor->Type), \
648 DescriptorCopy.Type, \
650 if (!RtlValidSid((PSID)((ULONG_PTR)NewDescriptor + \
651 (ULONG_PTR)NewDescriptor->Type))) \
653 RtlRaiseStatus(STATUS_INVALID_SID); \
655 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
664 #define CopyACL(Type) \
666 if(DescriptorCopy.Type != NULL) \
668 NewDescriptor->Type = (PVOID)Offset; \
669 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
670 (ULONG_PTR)NewDescriptor->Type), \
671 DescriptorCopy.Type, \
673 if (!RtlValidAcl((PACL)((ULONG_PTR)NewDescriptor + \
674 (ULONG_PTR)NewDescriptor->Type))) \
676 RtlRaiseStatus(STATUS_INVALID_ACL); \
678 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
687 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
689 Status
= _SEH2_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
= (USHORT
)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(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor
,
863 IN KPROCESSOR_MODE CurrentMode
,
864 IN BOOLEAN CaptureIfKernelMode
)
868 /* WARNING! You need to call this function with the same value for CurrentMode
869 and CaptureIfKernelMode that you previously passed to
870 SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
871 if(CapturedSecurityDescriptor
!= NULL
&&
872 (CurrentMode
!= KernelMode
||
873 (CurrentMode
== KernelMode
&& CaptureIfKernelMode
)))
875 /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
876 ExFreePoolWithTag(CapturedSecurityDescriptor
, TAG_SD
);
879 return STATUS_SUCCESS
;
886 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL
,
887 IN PSECURITY_INFORMATION _SecurityInformation
,
888 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
,
889 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
890 IN POOL_TYPE PoolType
,
891 IN PGENERIC_MAPPING GenericMapping
)
893 PISECURITY_DESCRIPTOR ObjectSd
;
894 PISECURITY_DESCRIPTOR NewSd
;
895 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
900 ULONG OwnerLength
= 0;
901 ULONG GroupLength
= 0;
902 ULONG DaclLength
= 0;
903 ULONG SaclLength
= 0;
906 SECURITY_INFORMATION SecurityInformation
;
908 ObjectSd
= *ObjectsSecurityDescriptor
;
911 return STATUS_NO_SECURITY_ON_OBJECT
; // The object does not have a security descriptor.
913 SecurityInformation
= *_SecurityInformation
;
915 /* Get owner and owner size */
916 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
918 if (SecurityDescriptor
->Owner
!= NULL
)
920 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
921 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+
922 (ULONG_PTR
)SecurityDescriptor
);
924 Owner
= (PSID
)SecurityDescriptor
->Owner
;
925 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
927 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
931 if (ObjectSd
->Owner
!= NULL
)
933 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
934 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
936 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
939 /* Get group and group size */
940 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
942 if (SecurityDescriptor
->Group
!= NULL
)
944 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
945 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
946 (ULONG_PTR
)SecurityDescriptor
);
948 Group
= (PSID
)SecurityDescriptor
->Group
;
949 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
951 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
955 if (ObjectSd
->Group
!= NULL
)
957 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
958 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
960 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
963 /* Get DACL and DACL size */
964 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
966 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
967 (SecurityDescriptor
->Dacl
!= NULL
))
969 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
970 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+
971 (ULONG_PTR
)SecurityDescriptor
);
973 Dacl
= (PACL
)SecurityDescriptor
->Dacl
;
975 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
977 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
981 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
982 (ObjectSd
->Dacl
!= NULL
))
984 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
985 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
987 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
990 /* Get SACL and SACL size */
991 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
993 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
994 (SecurityDescriptor
->Sacl
!= NULL
))
996 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
997 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+
998 (ULONG_PTR
)SecurityDescriptor
);
1000 Sacl
= (PACL
)SecurityDescriptor
->Sacl
;
1001 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
1003 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
1007 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
1008 (ObjectSd
->Sacl
!= NULL
))
1010 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
1011 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
1013 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
1016 NewSd
= ExAllocatePool(NonPagedPool
,
1017 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
1018 DaclLength
+ SaclLength
);
1021 ObDereferenceObject(Object
);
1022 return STATUS_INSUFFICIENT_RESOURCES
;
1025 RtlCreateSecurityDescriptor(NewSd
,
1026 SECURITY_DESCRIPTOR_REVISION1
);
1027 /* We always build a self-relative descriptor */
1028 NewSd
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
1030 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
1032 if (OwnerLength
!= 0)
1034 RtlCopyMemory((PVOID
)Current
,
1037 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
1038 Current
+= OwnerLength
;
1041 if (GroupLength
!= 0)
1043 RtlCopyMemory((PVOID
)Current
,
1046 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
1047 Current
+= GroupLength
;
1050 if (DaclLength
!= 0)
1052 RtlCopyMemory((PVOID
)Current
,
1055 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
1056 Current
+= DaclLength
;
1059 if (SaclLength
!= 0)
1061 RtlCopyMemory((PVOID
)Current
,
1064 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
1065 Current
+= SaclLength
;
1068 *ObjectsSecurityDescriptor
= NewSd
;
1069 return STATUS_SUCCESS
;
1077 SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL
,
1078 IN PSECURITY_INFORMATION SecurityInformation
,
1079 IN PSECURITY_DESCRIPTOR ModificationDescriptor
,
1080 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
1081 IN ULONG AutoInheritFlags
,
1082 IN POOL_TYPE PoolType
,
1083 IN PGENERIC_MAPPING GenericMapping
)
1085 PISECURITY_DESCRIPTOR ObjectSd
= *ObjectsSecurityDescriptor
;
1088 return STATUS_NO_SECURITY_ON_OBJECT
; // The object does not have a security descriptor.
1091 return STATUS_NOT_IMPLEMENTED
;
1099 SeValidSecurityDescriptor(IN ULONG Length
,
1100 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
)
1105 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
1107 if (Length
< SECURITY_DESCRIPTOR_MIN_LENGTH
)
1109 DPRINT1("Invalid Security Descriptor revision\n");
1113 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
1115 DPRINT1("Invalid Security Descriptor revision\n");
1119 if (!(SecurityDescriptor
->Control
& SE_SELF_RELATIVE
))
1121 DPRINT1("No self-relative Security Descriptor\n");
1125 SdLength
= sizeof(SECURITY_DESCRIPTOR
);
1127 /* Check Owner SID */
1128 if (SecurityDescriptor
->Owner
== NULL
)
1130 DPRINT1("No Owner SID\n");
1134 if ((ULONG_PTR
)SecurityDescriptor
->Owner
% sizeof(ULONG
))
1136 DPRINT1("Invalid Owner SID alignment\n");
1140 Sid
= (PISID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Owner
);
1141 if (Sid
->Revision
!= SID_REVISION
)
1143 DPRINT1("Invalid Owner SID revision\n");
1147 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
1148 if (Length
< SdLength
)
1150 DPRINT1("Invalid Owner SID size\n");
1154 /* Check Group SID */
1155 if (SecurityDescriptor
->Group
!= NULL
)
1157 if ((ULONG_PTR
)SecurityDescriptor
->Group
% sizeof(ULONG
))
1159 DPRINT1("Invalid Group SID alignment\n");
1163 Sid
= (PSID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Group
);
1164 if (Sid
->Revision
!= SID_REVISION
)
1166 DPRINT1("Invalid Group SID revision\n");
1170 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
1171 if (Length
< SdLength
)
1173 DPRINT1("Invalid Group SID size\n");
1179 if (SecurityDescriptor
->Dacl
!= NULL
)
1181 if ((ULONG_PTR
)SecurityDescriptor
->Dacl
% sizeof(ULONG
))
1183 DPRINT1("Invalid DACL alignment\n");
1187 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Dacl
);
1188 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) &&
1189 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1191 DPRINT1("Invalid DACL revision\n");
1195 SdLength
+= Acl
->AclSize
;
1196 if (Length
< SdLength
)
1198 DPRINT1("Invalid DACL size\n");
1204 if (SecurityDescriptor
->Sacl
!= NULL
)
1206 if ((ULONG_PTR
)SecurityDescriptor
->Sacl
% sizeof(ULONG
))
1208 DPRINT1("Invalid SACL alignment\n");
1212 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Sacl
);
1213 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
1214 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1216 DPRINT1("Invalid SACL revision\n");
1220 SdLength
+= Acl
->AclSize
;
1221 if (Length
< SdLength
)
1223 DPRINT1("Invalid SACL size\n");
1235 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
1239 if (*SecurityDescriptor
!= NULL
)
1241 ExFreePool(*SecurityDescriptor
);
1242 *SecurityDescriptor
= NULL
;
1245 return STATUS_SUCCESS
;
1253 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
1254 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
1255 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
1256 IN GUID
*ObjectType OPTIONAL
,
1257 IN BOOLEAN IsDirectoryObject
,
1258 IN ULONG AutoInheritFlags
,
1259 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
1260 IN PGENERIC_MAPPING GenericMapping
,
1261 IN POOL_TYPE PoolType
)
1264 return STATUS_NOT_IMPLEMENTED
;
1271 SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL
,
1272 PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL
,
1273 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1274 BOOLEAN IsDirectoryObject
,
1275 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
1276 PGENERIC_MAPPING GenericMapping
,
1279 PISECURITY_DESCRIPTOR ParentDescriptor
= _ParentDescriptor
;
1280 PISECURITY_DESCRIPTOR ExplicitDescriptor
= _ExplicitDescriptor
;
1281 PISECURITY_DESCRIPTOR Descriptor
;
1283 ULONG OwnerLength
= 0;
1284 ULONG GroupLength
= 0;
1285 ULONG DaclLength
= 0;
1286 ULONG SaclLength
= 0;
1297 /* Lock subject context */
1298 SeLockSubjectContext(SubjectContext
);
1300 if (SubjectContext
->ClientToken
!= NULL
)
1302 Token
= SubjectContext
->ClientToken
;
1306 Token
= SubjectContext
->PrimaryToken
;
1310 /* Inherit the Owner SID */
1311 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Owner
!= NULL
)
1313 DPRINT("Use explicit owner sid!\n");
1314 Owner
= ExplicitDescriptor
->Owner
;
1316 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
1318 Owner
= (PSID
)(((ULONG_PTR
)Owner
) + (ULONG_PTR
)ExplicitDescriptor
);
1326 DPRINT("Use token owner sid!\n");
1327 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
1331 DPRINT("Use default owner sid!\n");
1332 Owner
= SeLocalSystemSid
;
1335 Control
|= SE_OWNER_DEFAULTED
;
1338 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
1341 /* Inherit the Group SID */
1342 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Group
!= NULL
)
1344 DPRINT("Use explicit group sid!\n");
1345 Group
= ExplicitDescriptor
->Group
;
1346 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
1348 Group
= (PSID
)(((ULONG_PTR
)Group
) + (ULONG_PTR
)ExplicitDescriptor
);
1355 DPRINT("Use token group sid!\n");
1356 Group
= Token
->PrimaryGroup
;
1360 DPRINT("Use default group sid!\n");
1361 Group
= SeLocalSystemSid
;
1364 Control
|= SE_OWNER_DEFAULTED
;
1367 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
1370 /* Inherit the DACL */
1371 if (ExplicitDescriptor
!= NULL
&&
1372 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
1373 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
1375 DPRINT("Use explicit DACL!\n");
1376 Dacl
= ExplicitDescriptor
->Dacl
;
1377 if (Dacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
1379 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ExplicitDescriptor
);
1382 Control
|= SE_DACL_PRESENT
;
1384 else if (ParentDescriptor
!= NULL
&&
1385 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
1387 DPRINT("Use parent DACL!\n");
1388 /* FIXME: Inherit */
1389 Dacl
= ParentDescriptor
->Dacl
;
1390 if (Dacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
1392 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ParentDescriptor
);
1394 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1396 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
1398 DPRINT("Use token default DACL!\n");
1399 /* FIXME: Inherit */
1400 Dacl
= Token
->DefaultDacl
;
1401 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1405 DPRINT("Use NULL DACL!\n");
1407 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1410 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
1413 /* Inherit the SACL */
1414 if (ExplicitDescriptor
!= NULL
&&
1415 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
1416 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
1418 DPRINT("Use explicit SACL!\n");
1419 Sacl
= ExplicitDescriptor
->Sacl
;
1420 if (Sacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
1422 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ExplicitDescriptor
);
1425 Control
|= SE_SACL_PRESENT
;
1427 else if (ParentDescriptor
!= NULL
&&
1428 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
1430 DPRINT("Use parent SACL!\n");
1431 /* FIXME: Inherit */
1432 Sacl
= ParentDescriptor
->Sacl
;
1433 if (Sacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
1435 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ParentDescriptor
);
1437 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
1440 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
1443 /* Allocate and initialize the new security descriptor */
1444 Length
= sizeof(SECURITY_DESCRIPTOR
) +
1445 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
1447 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
1448 sizeof(SECURITY_DESCRIPTOR
),
1454 Descriptor
= ExAllocatePoolWithTag(PagedPool
,
1457 if (Descriptor
== NULL
)
1459 DPRINT1("ExAlloctePool() failed\n");
1460 /* FIXME: Unlock subject context */
1461 return STATUS_INSUFFICIENT_RESOURCES
;
1464 RtlZeroMemory( Descriptor
, Length
);
1465 RtlCreateSecurityDescriptor(Descriptor
,
1466 SECURITY_DESCRIPTOR_REVISION
);
1468 Descriptor
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
1470 Current
= (ULONG_PTR
)Descriptor
+ sizeof(SECURITY_DESCRIPTOR
);
1472 if (SaclLength
!= 0)
1474 RtlCopyMemory((PVOID
)Current
,
1477 Descriptor
->Sacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1478 Current
+= SaclLength
;
1481 if (DaclLength
!= 0)
1483 RtlCopyMemory((PVOID
)Current
,
1486 Descriptor
->Dacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1487 Current
+= DaclLength
;
1490 if (OwnerLength
!= 0)
1492 RtlCopyMemory((PVOID
)Current
,
1495 Descriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1496 Current
+= OwnerLength
;
1497 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
1500 DPRINT("Owner of %x is zero length\n", Descriptor
);
1502 if (GroupLength
!= 0)
1504 memmove((PVOID
)Current
,
1507 Descriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1510 /* Unlock subject context */
1511 SeUnlockSubjectContext(SubjectContext
);
1513 *NewDescriptor
= Descriptor
;
1515 DPRINT("Descrptor %x\n", Descriptor
);
1516 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
1518 return STATUS_SUCCESS
;