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
))
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.
257 RtlCopyMemory(&SafeQos
,
258 ObjectAttributes
->SecurityQualityOfService
,
259 sizeof(SECURITY_QUALITY_OF_SERVICE
));
264 Status
= STATUS_INVALID_PARAMETER
;
269 *CapturedSecurityQualityOfService
= NULL
;
275 Status
= STATUS_INVALID_PARAMETER
;
278 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
280 Status
= _SEH2_GetExceptionCode();
284 if (NT_SUCCESS(Status
))
288 CapturedQos
= ExAllocatePool(PoolType
,
289 sizeof(SECURITY_QUALITY_OF_SERVICE
));
290 if (CapturedQos
!= NULL
)
292 RtlCopyMemory(CapturedQos
,
294 sizeof(SECURITY_QUALITY_OF_SERVICE
));
295 *CapturedSecurityQualityOfService
= CapturedQos
;
299 Status
= STATUS_INSUFFICIENT_RESOURCES
;
304 *CapturedSecurityQualityOfService
= NULL
;
310 if (ObjectAttributes
->Length
== sizeof(OBJECT_ATTRIBUTES
))
314 if (ObjectAttributes
->SecurityQualityOfService
!= NULL
)
316 if (((PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
)->Length
==
317 sizeof(SECURITY_QUALITY_OF_SERVICE
))
319 CapturedQos
= ExAllocatePool(PoolType
,
320 sizeof(SECURITY_QUALITY_OF_SERVICE
));
321 if (CapturedQos
!= NULL
)
323 RtlCopyMemory(CapturedQos
,
324 ObjectAttributes
->SecurityQualityOfService
,
325 sizeof(SECURITY_QUALITY_OF_SERVICE
));
326 *CapturedSecurityQualityOfService
= CapturedQos
;
331 Status
= STATUS_INSUFFICIENT_RESOURCES
;
336 Status
= STATUS_INVALID_PARAMETER
;
341 *CapturedSecurityQualityOfService
= NULL
;
347 *CapturedSecurityQualityOfService
= (PSECURITY_QUALITY_OF_SERVICE
)ObjectAttributes
->SecurityQualityOfService
;
348 *Present
= (ObjectAttributes
->SecurityQualityOfService
!= NULL
);
353 Status
= STATUS_INVALID_PARAMETER
;
359 *CapturedSecurityQualityOfService
= NULL
;
369 SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL
,
370 IN KPROCESSOR_MODE AccessMode
,
371 IN BOOLEAN CaptureIfKernel
)
375 if (CapturedSecurityQualityOfService
!= NULL
&&
376 (AccessMode
!= KernelMode
|| CaptureIfKernel
))
378 ExFreePool(CapturedSecurityQualityOfService
);
382 /* PUBLIC FUNCTIONS ***********************************************************/
389 SeCaptureSecurityDescriptor(IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor
,
390 IN KPROCESSOR_MODE CurrentMode
,
391 IN POOL_TYPE PoolType
,
392 IN BOOLEAN CaptureIfKernel
,
393 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;
404 if (OriginalSecurityDescriptor
!= NULL
)
406 if (CurrentMode
!= KernelMode
)
408 RtlZeroMemory(&DescriptorCopy
, sizeof(DescriptorCopy
));
413 * First only probe and copy until the control field of the descriptor
414 * to determine whether it's a self-relative descriptor
416 DescriptorSize
= FIELD_OFFSET(SECURITY_DESCRIPTOR
,
418 ProbeForRead(OriginalSecurityDescriptor
,
422 if (OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
424 _SEH2_YIELD(return 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
));
435 * Probe and copy the entire security descriptor structure. The SIDs
436 * and ACLs will be probed and copied later though
438 ProbeForRead(OriginalSecurityDescriptor
,
441 if (DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
443 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
445 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
446 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
447 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
448 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
452 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
453 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
454 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
455 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
458 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
460 /* Return the exception code */
461 _SEH2_YIELD(return _SEH2_GetExceptionCode());
465 else if (!CaptureIfKernel
)
467 if (OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
469 return STATUS_UNKNOWN_REVISION
;
472 *CapturedSecurityDescriptor
= OriginalSecurityDescriptor
;
473 return STATUS_SUCCESS
;
477 if (OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
479 return STATUS_UNKNOWN_REVISION
;
482 /* Make a copy on the stack */
483 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
484 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
485 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
486 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
487 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
488 if (DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
490 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
492 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
493 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
494 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
495 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
499 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
500 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
501 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
502 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
506 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.
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 SidType##SAC = ProbeForReadUchar(&SidType->SubAuthorityCount); \
545 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
546 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
547 ProbeForRead(SidType, \
551 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) \
553 _SEH2_YIELD(return _SEH2_GetExceptionCode()); \
560 SidType##SAC = SidType->SubAuthorityCount; \
561 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
562 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
567 DetermineSIDSize(Owner
);
568 DetermineSIDSize(Group
);
570 #undef DetermineSIDSize
572 /* Determine the size of the ACLs */
573 #define DetermineACLSize(AclType, AclFlag) \
575 if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \
576 DescriptorCopy.AclType != NULL) \
578 PACL AclType = (PACL)DescriptorCopy.AclType; \
580 if(CurrentMode != KernelMode) \
582 /* Securely access the buffers! */ \
585 AclType##Size = ProbeForReadUshort(&AclType->AclSize); \
586 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
587 ProbeForRead(AclType, \
591 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) \
593 _SEH2_YIELD(return _SEH2_GetExceptionCode()); \
600 AclType##Size = AclType->AclSize; \
601 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
606 DescriptorCopy.AclType = NULL; \
610 DetermineACLSize(Sacl
, SACL
);
611 DetermineACLSize(Dacl
, DACL
);
613 #undef DetermineACLSize
616 * Allocate enough memory to store a complete copy of a self-relative
617 * security descriptor
619 NewDescriptor
= ExAllocatePoolWithTag(PoolType
,
622 if (NewDescriptor
!= NULL
)
624 ULONG_PTR Offset
= sizeof(SECURITY_DESCRIPTOR
);
626 RtlZeroMemory(NewDescriptor
, DescriptorSize
);
627 NewDescriptor
->Revision
= DescriptorCopy
.Revision
;
628 NewDescriptor
->Sbz1
= DescriptorCopy
.Sbz1
;
629 NewDescriptor
->Control
= DescriptorCopy
.Control
| SE_SELF_RELATIVE
;
634 * Setup the offsets and copy the SIDs and ACLs to the new
635 * self-relative security descriptor. Probing the pointers is not
636 * neccessary anymore as we did that when collecting the sizes!
637 * Make sure to validate the SIDs and ACLs *again* as they could have
638 * been modified in the meanwhile!
640 #define CopySID(Type) \
642 if(DescriptorCopy.Type != NULL) \
644 NewDescriptor->Type = (PVOID)Offset; \
645 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
646 (ULONG_PTR)NewDescriptor->Type), \
647 DescriptorCopy.Type, \
649 if (!RtlValidSid((PSID)((ULONG_PTR)NewDescriptor + \
650 (ULONG_PTR)NewDescriptor->Type))) \
652 RtlRaiseStatus(STATUS_INVALID_SID); \
654 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
663 #define CopyACL(Type) \
665 if(DescriptorCopy.Type != NULL) \
667 NewDescriptor->Type = (PVOID)Offset; \
668 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
669 (ULONG_PTR)NewDescriptor->Type), \
670 DescriptorCopy.Type, \
672 if (!RtlValidAcl((PACL)((ULONG_PTR)NewDescriptor + \
673 (ULONG_PTR)NewDescriptor->Type))) \
675 RtlRaiseStatus(STATUS_INVALID_ACL); \
677 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
686 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
688 /* We failed to copy the data to the new descriptor */
689 ExFreePool(NewDescriptor
);
690 _SEH2_YIELD(return _SEH2_GetExceptionCode());
695 * We're finally done!
696 * Copy the pointer to the captured descriptor to to the caller.
698 *CapturedSecurityDescriptor
= NewDescriptor
;
699 return STATUS_SUCCESS
;
703 Status
= STATUS_INSUFFICIENT_RESOURCES
;
708 /* Nothing to do... */
709 *CapturedSecurityDescriptor
= NULL
;
719 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation
,
720 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
721 IN OUT PULONG Length
,
722 IN PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor OPTIONAL
)
724 PISECURITY_DESCRIPTOR ObjectSd
;
725 PISECURITY_DESCRIPTOR_RELATIVE RelSD
;
730 ULONG OwnerLength
= 0;
731 ULONG GroupLength
= 0;
732 ULONG DaclLength
= 0;
733 ULONG SaclLength
= 0;
738 RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
740 if (*ObjectsSecurityDescriptor
== NULL
)
742 if (*Length
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
))
744 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
745 return STATUS_BUFFER_TOO_SMALL
;
748 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
749 RtlCreateSecurityDescriptorRelative(RelSD
,
750 SECURITY_DESCRIPTOR_REVISION
);
751 return STATUS_SUCCESS
;
754 ObjectSd
= *ObjectsSecurityDescriptor
;
756 /* Calculate the required security descriptor length */
757 Control
= SE_SELF_RELATIVE
;
758 if ((*SecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
759 (ObjectSd
->Owner
!= NULL
))
761 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
762 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
763 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
766 if ((*SecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
767 (ObjectSd
->Group
!= NULL
))
769 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
770 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
771 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
774 if ((*SecurityInformation
& DACL_SECURITY_INFORMATION
) &&
775 (ObjectSd
->Control
& SE_DACL_PRESENT
))
777 if (ObjectSd
->Dacl
!= NULL
)
779 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
780 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
783 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
786 if ((*SecurityInformation
& SACL_SECURITY_INFORMATION
) &&
787 (ObjectSd
->Control
& SE_SACL_PRESENT
))
789 if (ObjectSd
->Sacl
!= NULL
)
791 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
792 SaclLength
= ROUND_UP(Sacl
->AclSize
, 4);
795 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
798 SdLength
= OwnerLength
+ GroupLength
+ DaclLength
+
799 SaclLength
+ sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
800 if (*Length
< SdLength
)
803 return STATUS_BUFFER_TOO_SMALL
;
806 /* Build the new security descrtiptor */
807 RtlCreateSecurityDescriptorRelative(RelSD
,
808 SECURITY_DESCRIPTOR_REVISION
);
809 RelSD
->Control
= (USHORT
)Control
;
811 Current
= (ULONG_PTR
)(RelSD
+ 1);
813 if (OwnerLength
!= 0)
815 RtlCopyMemory((PVOID
)Current
,
818 RelSD
->Owner
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
819 Current
+= OwnerLength
;
822 if (GroupLength
!= 0)
824 RtlCopyMemory((PVOID
)Current
,
827 RelSD
->Group
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
828 Current
+= GroupLength
;
833 RtlCopyMemory((PVOID
)Current
,
836 RelSD
->Dacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
837 Current
+= DaclLength
;
842 RtlCopyMemory((PVOID
)Current
,
845 RelSD
->Sacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
846 Current
+= SaclLength
;
851 return STATUS_SUCCESS
;
859 SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor
,
860 IN KPROCESSOR_MODE CurrentMode
,
861 IN BOOLEAN CaptureIfKernelMode
)
866 * WARNING! You need to call this function with the same value for CurrentMode
867 * and CaptureIfKernelMode that you previously passed to
868 * SeCaptureSecurityDescriptor() in order to avoid memory leaks!
870 if (CapturedSecurityDescriptor
!= NULL
&&
871 (CurrentMode
!= KernelMode
||
872 (CurrentMode
== KernelMode
&& CaptureIfKernelMode
)))
874 /* Only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
875 ExFreePoolWithTag(CapturedSecurityDescriptor
, TAG_SD
);
878 return STATUS_SUCCESS
;
885 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL
,
886 IN PSECURITY_INFORMATION _SecurityInformation
,
887 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
,
888 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
889 IN POOL_TYPE PoolType
,
890 IN PGENERIC_MAPPING GenericMapping
)
892 PISECURITY_DESCRIPTOR ObjectSd
;
893 PISECURITY_DESCRIPTOR NewSd
;
894 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
899 ULONG OwnerLength
= 0;
900 ULONG GroupLength
= 0;
901 ULONG DaclLength
= 0;
902 ULONG SaclLength
= 0;
905 SECURITY_INFORMATION SecurityInformation
;
907 ObjectSd
= *ObjectsSecurityDescriptor
;
909 /* The object does not have a security descriptor. */
911 return STATUS_NO_SECURITY_ON_OBJECT
;
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);
928 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
932 if (ObjectSd
->Owner
!= NULL
)
934 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
935 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
938 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
941 /* Get group and group size */
942 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
944 if (SecurityDescriptor
->Group
!= NULL
)
946 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
947 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
948 (ULONG_PTR
)SecurityDescriptor
);
950 Group
= (PSID
)SecurityDescriptor
->Group
;
951 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
954 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
958 if (ObjectSd
->Group
!= NULL
)
960 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
961 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
964 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
967 /* Get DACL and DACL size */
968 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
970 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
971 (SecurityDescriptor
->Dacl
!= NULL
))
973 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
974 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+
975 (ULONG_PTR
)SecurityDescriptor
);
977 Dacl
= (PACL
)SecurityDescriptor
->Dacl
;
979 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
982 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
986 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
987 (ObjectSd
->Dacl
!= NULL
))
989 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
990 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
993 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
996 /* Get SACL and SACL size */
997 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
999 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
1000 (SecurityDescriptor
->Sacl
!= NULL
))
1002 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
1003 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+
1004 (ULONG_PTR
)SecurityDescriptor
);
1006 Sacl
= (PACL
)SecurityDescriptor
->Sacl
;
1007 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
1010 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
1014 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
1015 (ObjectSd
->Sacl
!= NULL
))
1017 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
1018 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
1021 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
1024 NewSd
= ExAllocatePool(NonPagedPool
,
1025 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
1026 DaclLength
+ SaclLength
);
1029 ObDereferenceObject(Object
);
1030 return STATUS_INSUFFICIENT_RESOURCES
;
1033 RtlCreateSecurityDescriptor(NewSd
,
1034 SECURITY_DESCRIPTOR_REVISION1
);
1036 /* We always build a self-relative descriptor */
1037 NewSd
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
1039 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
1041 if (OwnerLength
!= 0)
1043 RtlCopyMemory((PVOID
)Current
,
1046 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
1047 Current
+= OwnerLength
;
1050 if (GroupLength
!= 0)
1052 RtlCopyMemory((PVOID
)Current
,
1055 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
1056 Current
+= GroupLength
;
1059 if (DaclLength
!= 0)
1061 RtlCopyMemory((PVOID
)Current
,
1064 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
1065 Current
+= DaclLength
;
1068 if (SaclLength
!= 0)
1070 RtlCopyMemory((PVOID
)Current
,
1073 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
1074 Current
+= SaclLength
;
1077 *ObjectsSecurityDescriptor
= NewSd
;
1078 return STATUS_SUCCESS
;
1086 SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL
,
1087 IN PSECURITY_INFORMATION SecurityInformation
,
1088 IN PSECURITY_DESCRIPTOR ModificationDescriptor
,
1089 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
1090 IN ULONG AutoInheritFlags
,
1091 IN POOL_TYPE PoolType
,
1092 IN PGENERIC_MAPPING GenericMapping
)
1094 PISECURITY_DESCRIPTOR ObjectSd
= *ObjectsSecurityDescriptor
;
1096 /* The object does not have a security descriptor. */
1098 return STATUS_NO_SECURITY_ON_OBJECT
;
1101 return STATUS_NOT_IMPLEMENTED
;
1109 SeValidSecurityDescriptor(IN ULONG Length
,
1110 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
)
1115 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
1117 if (Length
< SECURITY_DESCRIPTOR_MIN_LENGTH
)
1119 DPRINT1("Invalid Security Descriptor revision\n");
1123 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
1125 DPRINT1("Invalid Security Descriptor revision\n");
1129 if (!(SecurityDescriptor
->Control
& SE_SELF_RELATIVE
))
1131 DPRINT1("No self-relative Security Descriptor\n");
1135 SdLength
= sizeof(SECURITY_DESCRIPTOR
);
1137 /* Check Owner SID */
1138 if (SecurityDescriptor
->Owner
== NULL
)
1140 DPRINT1("No Owner SID\n");
1144 if ((ULONG_PTR
)SecurityDescriptor
->Owner
% sizeof(ULONG
))
1146 DPRINT1("Invalid Owner SID alignment\n");
1150 Sid
= (PISID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Owner
);
1151 if (Sid
->Revision
!= SID_REVISION
)
1153 DPRINT1("Invalid Owner SID revision\n");
1157 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
1158 if (Length
< SdLength
)
1160 DPRINT1("Invalid Owner SID size\n");
1164 /* Check Group SID */
1165 if (SecurityDescriptor
->Group
!= NULL
)
1167 if ((ULONG_PTR
)SecurityDescriptor
->Group
% sizeof(ULONG
))
1169 DPRINT1("Invalid Group SID alignment\n");
1173 Sid
= (PSID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Group
);
1174 if (Sid
->Revision
!= SID_REVISION
)
1176 DPRINT1("Invalid Group SID revision\n");
1180 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
1181 if (Length
< SdLength
)
1183 DPRINT1("Invalid Group SID size\n");
1189 if (SecurityDescriptor
->Dacl
!= NULL
)
1191 if ((ULONG_PTR
)SecurityDescriptor
->Dacl
% sizeof(ULONG
))
1193 DPRINT1("Invalid DACL alignment\n");
1197 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Dacl
);
1198 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) &&
1199 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1201 DPRINT1("Invalid DACL revision\n");
1205 SdLength
+= Acl
->AclSize
;
1206 if (Length
< SdLength
)
1208 DPRINT1("Invalid DACL size\n");
1214 if (SecurityDescriptor
->Sacl
!= NULL
)
1216 if ((ULONG_PTR
)SecurityDescriptor
->Sacl
% sizeof(ULONG
))
1218 DPRINT1("Invalid SACL alignment\n");
1222 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Sacl
);
1223 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
1224 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1226 DPRINT1("Invalid SACL revision\n");
1230 SdLength
+= Acl
->AclSize
;
1231 if (Length
< SdLength
)
1233 DPRINT1("Invalid SACL size\n");
1245 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
1249 if (*SecurityDescriptor
!= NULL
)
1251 ExFreePool(*SecurityDescriptor
);
1252 *SecurityDescriptor
= NULL
;
1255 return STATUS_SUCCESS
;
1263 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
1264 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
1265 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
1266 IN GUID
*ObjectType OPTIONAL
,
1267 IN BOOLEAN IsDirectoryObject
,
1268 IN ULONG AutoInheritFlags
,
1269 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
1270 IN PGENERIC_MAPPING GenericMapping
,
1271 IN POOL_TYPE PoolType
)
1274 return STATUS_NOT_IMPLEMENTED
;
1281 SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL
,
1282 PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL
,
1283 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1284 BOOLEAN IsDirectoryObject
,
1285 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
1286 PGENERIC_MAPPING GenericMapping
,
1289 PISECURITY_DESCRIPTOR ParentDescriptor
= _ParentDescriptor
;
1290 PISECURITY_DESCRIPTOR ExplicitDescriptor
= _ExplicitDescriptor
;
1291 PISECURITY_DESCRIPTOR Descriptor
;
1293 ULONG OwnerLength
= 0;
1294 ULONG GroupLength
= 0;
1295 ULONG DaclLength
= 0;
1296 ULONG SaclLength
= 0;
1307 /* Lock subject context */
1308 SeLockSubjectContext(SubjectContext
);
1310 if (SubjectContext
->ClientToken
!= NULL
)
1312 Token
= SubjectContext
->ClientToken
;
1316 Token
= SubjectContext
->PrimaryToken
;
1319 /* Inherit the Owner SID */
1320 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Owner
!= NULL
)
1322 DPRINT("Use explicit owner sid!\n");
1323 Owner
= ExplicitDescriptor
->Owner
;
1325 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
1327 Owner
= (PSID
)(((ULONG_PTR
)Owner
) + (ULONG_PTR
)ExplicitDescriptor
);
1334 DPRINT("Use token owner sid!\n");
1335 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
1339 DPRINT("Use default owner sid!\n");
1340 Owner
= SeLocalSystemSid
;
1343 Control
|= SE_OWNER_DEFAULTED
;
1346 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
1348 /* Inherit the Group SID */
1349 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Group
!= NULL
)
1351 DPRINT("Use explicit group sid!\n");
1352 Group
= ExplicitDescriptor
->Group
;
1353 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
1355 Group
= (PSID
)(((ULONG_PTR
)Group
) + (ULONG_PTR
)ExplicitDescriptor
);
1362 DPRINT("Use token group sid!\n");
1363 Group
= Token
->PrimaryGroup
;
1367 DPRINT("Use default group sid!\n");
1368 Group
= SeLocalSystemSid
;
1371 Control
|= SE_OWNER_DEFAULTED
;
1374 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
1376 /* Inherit the DACL */
1377 if (ExplicitDescriptor
!= NULL
&&
1378 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
1379 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
1381 DPRINT("Use explicit DACL!\n");
1382 Dacl
= ExplicitDescriptor
->Dacl
;
1383 if (Dacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
1385 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ExplicitDescriptor
);
1388 Control
|= SE_DACL_PRESENT
;
1390 else if (ParentDescriptor
!= NULL
&&
1391 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
1393 DPRINT("Use parent DACL!\n");
1394 /* FIXME: Inherit */
1395 Dacl
= ParentDescriptor
->Dacl
;
1396 if (Dacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
1398 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ParentDescriptor
);
1401 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1403 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
1405 DPRINT("Use token default DACL!\n");
1406 /* FIXME: Inherit */
1407 Dacl
= Token
->DefaultDacl
;
1408 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1412 DPRINT("Use NULL DACL!\n");
1414 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1417 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
1419 /* Inherit the SACL */
1420 if (ExplicitDescriptor
!= NULL
&&
1421 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
1422 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
1424 DPRINT("Use explicit SACL!\n");
1425 Sacl
= ExplicitDescriptor
->Sacl
;
1426 if (Sacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
1428 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ExplicitDescriptor
);
1431 Control
|= SE_SACL_PRESENT
;
1433 else if (ParentDescriptor
!= NULL
&&
1434 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
1436 DPRINT("Use parent SACL!\n");
1437 /* FIXME: Inherit */
1438 Sacl
= ParentDescriptor
->Sacl
;
1439 if (Sacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
1441 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ParentDescriptor
);
1444 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
1447 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
1449 /* Allocate and initialize the new security descriptor */
1450 Length
= sizeof(SECURITY_DESCRIPTOR
) +
1451 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
1453 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
1454 sizeof(SECURITY_DESCRIPTOR
),
1460 Descriptor
= ExAllocatePoolWithTag(PagedPool
,
1463 if (Descriptor
== NULL
)
1465 DPRINT1("ExAlloctePool() failed\n");
1466 /* FIXME: Unlock subject context */
1467 return STATUS_INSUFFICIENT_RESOURCES
;
1470 RtlZeroMemory( Descriptor
, Length
);
1471 RtlCreateSecurityDescriptor(Descriptor
,
1472 SECURITY_DESCRIPTOR_REVISION
);
1474 Descriptor
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
1476 Current
= (ULONG_PTR
)Descriptor
+ sizeof(SECURITY_DESCRIPTOR
);
1478 if (SaclLength
!= 0)
1480 RtlCopyMemory((PVOID
)Current
,
1483 Descriptor
->Sacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1484 Current
+= SaclLength
;
1487 if (DaclLength
!= 0)
1489 RtlCopyMemory((PVOID
)Current
,
1492 Descriptor
->Dacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1493 Current
+= DaclLength
;
1496 if (OwnerLength
!= 0)
1498 RtlCopyMemory((PVOID
)Current
,
1501 Descriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1502 Current
+= OwnerLength
;
1503 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
1507 DPRINT("Owner of %x is zero length\n", Descriptor
);
1510 if (GroupLength
!= 0)
1512 memmove((PVOID
)Current
,
1515 Descriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1518 /* Unlock subject context */
1519 SeUnlockSubjectContext(SubjectContext
);
1521 *NewDescriptor
= Descriptor
;
1523 DPRINT("Descrptor %x\n", Descriptor
);
1524 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
1526 return STATUS_SUCCESS
;