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;
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 _SEH2_YIELD(return STATUS_UNKNOWN_REVISION
);
423 /* make a copy on the stack */
424 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
425 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
426 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
427 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
428 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
430 /* probe and copy the entire security descriptor structure. The SIDs
431 and ACLs will be probed and copied later though */
432 ProbeForRead(OriginalSecurityDescriptor
,
435 if (DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
437 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
439 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
440 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
441 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
442 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
446 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
447 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
448 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
449 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
452 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
454 /* Return the exception code */
455 _SEH2_YIELD(return _SEH2_GetExceptionCode());
459 else if (!CaptureIfKernel
)
461 if (OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
463 return STATUS_UNKNOWN_REVISION
;
466 *CapturedSecurityDescriptor
= OriginalSecurityDescriptor
;
467 return STATUS_SUCCESS
;
471 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
473 return STATUS_UNKNOWN_REVISION
;
476 /* make a copy on the stack */
477 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
478 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
479 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
480 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
481 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
482 if (DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
484 PISECURITY_DESCRIPTOR_RELATIVE RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
486 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
487 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
488 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
489 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
493 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
494 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
495 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
496 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
500 if (DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
502 /* in case we're dealing with a self-relative descriptor, do a basic convert
503 to an absolute descriptor. We do this so we can simply access the data
504 using the pointers without calculating them again. */
505 DescriptorCopy
.Control
&= ~SE_SELF_RELATIVE
;
506 if (DescriptorCopy
.Owner
!= NULL
)
508 DescriptorCopy
.Owner
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Owner
);
510 if (DescriptorCopy
.Group
!= NULL
)
512 DescriptorCopy
.Group
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Group
);
514 if (DescriptorCopy
.Dacl
!= NULL
)
516 DescriptorCopy
.Dacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Dacl
);
518 if (DescriptorCopy
.Sacl
!= NULL
)
520 DescriptorCopy
.Sacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Sacl
);
524 /* determine the size of the SIDs */
525 #define DetermineSIDSize(SidType) \
527 if(DescriptorCopy.SidType != NULL) \
529 SID *SidType = (SID*)DescriptorCopy.SidType; \
531 if(CurrentMode != KernelMode) \
533 /* securely access the buffers! */ \
536 SidType##SAC = ProbeForReadUchar(&SidType->SubAuthorityCount); \
537 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
538 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
539 ProbeForRead(SidType, \
543 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) \
545 _SEH2_YIELD(return _SEH2_GetExceptionCode()); \
552 SidType##SAC = SidType->SubAuthorityCount; \
553 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
554 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
559 DetermineSIDSize(Owner
);
560 DetermineSIDSize(Group
);
562 #undef DetermineSIDSize
564 /* determine the size of the ACLs */
565 #define DetermineACLSize(AclType, AclFlag) \
567 if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \
568 DescriptorCopy.AclType != NULL) \
570 PACL AclType = (PACL)DescriptorCopy.AclType; \
572 if(CurrentMode != KernelMode) \
574 /* securely access the buffers! */ \
577 AclType##Size = ProbeForReadUshort(&AclType->AclSize); \
578 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
579 ProbeForRead(AclType, \
583 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) \
585 _SEH2_YIELD(return _SEH2_GetExceptionCode()); \
592 AclType##Size = AclType->AclSize; \
593 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
598 DescriptorCopy.AclType = NULL; \
602 DetermineACLSize(Sacl
, SACL
);
603 DetermineACLSize(Dacl
, DACL
);
605 #undef DetermineACLSize
607 /* allocate enough memory to store a complete copy of a self-relative
608 security descriptor */
609 NewDescriptor
= ExAllocatePoolWithTag(PoolType
,
612 if(NewDescriptor
!= NULL
)
614 ULONG_PTR Offset
= sizeof(SECURITY_DESCRIPTOR
);
616 RtlZeroMemory(NewDescriptor
, DescriptorSize
);
617 NewDescriptor
->Revision
= DescriptorCopy
.Revision
;
618 NewDescriptor
->Sbz1
= DescriptorCopy
.Sbz1
;
619 NewDescriptor
->Control
= DescriptorCopy
.Control
| SE_SELF_RELATIVE
;
623 /* setup the offsets and copy the SIDs and ACLs to the new
624 self-relative security descriptor. Probing the pointers is not
625 neccessary anymore as we did that when collecting the sizes!
626 Make sure to validate the SIDs and ACLs *again* as they could have
627 been modified in the meanwhile! */
628 #define CopySID(Type) \
630 if(DescriptorCopy.Type != NULL) \
632 NewDescriptor->Type = (PVOID)Offset; \
633 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
634 (ULONG_PTR)NewDescriptor->Type), \
635 DescriptorCopy.Type, \
637 if (!RtlValidSid((PSID)((ULONG_PTR)NewDescriptor + \
638 (ULONG_PTR)NewDescriptor->Type))) \
640 RtlRaiseStatus(STATUS_INVALID_SID); \
642 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
651 #define CopyACL(Type) \
653 if(DescriptorCopy.Type != NULL) \
655 NewDescriptor->Type = (PVOID)Offset; \
656 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
657 (ULONG_PTR)NewDescriptor->Type), \
658 DescriptorCopy.Type, \
660 if (!RtlValidAcl((PACL)((ULONG_PTR)NewDescriptor + \
661 (ULONG_PTR)NewDescriptor->Type))) \
663 RtlRaiseStatus(STATUS_INVALID_ACL); \
665 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
674 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
676 /* we failed to copy the data to the new descriptor */
677 ExFreePool(NewDescriptor
);
678 _SEH2_YIELD(return _SEH2_GetExceptionCode());
682 /* we're finally done! copy the pointer to the captured descriptor to
684 *CapturedSecurityDescriptor
= NewDescriptor
;
685 return STATUS_SUCCESS
;
689 Status
= STATUS_INSUFFICIENT_RESOURCES
;
694 /* nothing to do... */
695 *CapturedSecurityDescriptor
= NULL
;
705 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation
,
706 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
707 IN OUT PULONG Length
,
708 IN PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor OPTIONAL
)
710 PISECURITY_DESCRIPTOR ObjectSd
;
711 PISECURITY_DESCRIPTOR_RELATIVE RelSD
;
716 ULONG OwnerLength
= 0;
717 ULONG GroupLength
= 0;
718 ULONG DaclLength
= 0;
719 ULONG SaclLength
= 0;
724 RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
726 if (*ObjectsSecurityDescriptor
== NULL
)
728 if (*Length
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
))
730 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
731 return STATUS_BUFFER_TOO_SMALL
;
734 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
735 RtlCreateSecurityDescriptorRelative(RelSD
,
736 SECURITY_DESCRIPTOR_REVISION
);
737 return STATUS_SUCCESS
;
740 ObjectSd
= *ObjectsSecurityDescriptor
;
742 /* Calculate the required security descriptor length */
743 Control
= SE_SELF_RELATIVE
;
744 if ((*SecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
745 (ObjectSd
->Owner
!= NULL
))
747 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
748 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
749 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
752 if ((*SecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
753 (ObjectSd
->Group
!= NULL
))
755 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
756 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
757 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
760 if ((*SecurityInformation
& DACL_SECURITY_INFORMATION
) &&
761 (ObjectSd
->Control
& SE_DACL_PRESENT
))
763 if (ObjectSd
->Dacl
!= NULL
)
765 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
766 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
768 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
771 if ((*SecurityInformation
& SACL_SECURITY_INFORMATION
) &&
772 (ObjectSd
->Control
& SE_SACL_PRESENT
))
774 if (ObjectSd
->Sacl
!= NULL
)
776 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
777 SaclLength
= ROUND_UP(Sacl
->AclSize
, 4);
779 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
782 SdLength
= OwnerLength
+ GroupLength
+ DaclLength
+
783 SaclLength
+ sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
784 if (*Length
< SdLength
)
787 return STATUS_BUFFER_TOO_SMALL
;
790 /* Build the new security descrtiptor */
791 RtlCreateSecurityDescriptorRelative(RelSD
,
792 SECURITY_DESCRIPTOR_REVISION
);
793 RelSD
->Control
= (USHORT
)Control
;
795 Current
= (ULONG_PTR
)(RelSD
+ 1);
797 if (OwnerLength
!= 0)
799 RtlCopyMemory((PVOID
)Current
,
802 RelSD
->Owner
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
803 Current
+= OwnerLength
;
806 if (GroupLength
!= 0)
808 RtlCopyMemory((PVOID
)Current
,
811 RelSD
->Group
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
812 Current
+= GroupLength
;
817 RtlCopyMemory((PVOID
)Current
,
820 RelSD
->Dacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
821 Current
+= DaclLength
;
826 RtlCopyMemory((PVOID
)Current
,
829 RelSD
->Sacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
830 Current
+= SaclLength
;
835 return STATUS_SUCCESS
;
843 SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor
,
844 IN KPROCESSOR_MODE CurrentMode
,
845 IN BOOLEAN CaptureIfKernelMode
)
849 /* WARNING! You need to call this function with the same value for CurrentMode
850 and CaptureIfKernelMode that you previously passed to
851 SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
852 if(CapturedSecurityDescriptor
!= NULL
&&
853 (CurrentMode
!= KernelMode
||
854 (CurrentMode
== KernelMode
&& CaptureIfKernelMode
)))
856 /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
857 ExFreePoolWithTag(CapturedSecurityDescriptor
, TAG_SD
);
860 return STATUS_SUCCESS
;
867 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL
,
868 IN PSECURITY_INFORMATION _SecurityInformation
,
869 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
,
870 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
871 IN POOL_TYPE PoolType
,
872 IN PGENERIC_MAPPING GenericMapping
)
874 PISECURITY_DESCRIPTOR ObjectSd
;
875 PISECURITY_DESCRIPTOR NewSd
;
876 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
881 ULONG OwnerLength
= 0;
882 ULONG GroupLength
= 0;
883 ULONG DaclLength
= 0;
884 ULONG SaclLength
= 0;
887 SECURITY_INFORMATION SecurityInformation
;
889 ObjectSd
= *ObjectsSecurityDescriptor
;
892 return STATUS_NO_SECURITY_ON_OBJECT
; // The object does not have a security descriptor.
894 SecurityInformation
= *_SecurityInformation
;
896 /* Get owner and owner size */
897 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
899 if (SecurityDescriptor
->Owner
!= NULL
)
901 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
902 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+
903 (ULONG_PTR
)SecurityDescriptor
);
905 Owner
= (PSID
)SecurityDescriptor
->Owner
;
906 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
909 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
913 if (ObjectSd
->Owner
!= NULL
)
915 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
916 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
919 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
922 /* Get group and group size */
923 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
925 if (SecurityDescriptor
->Group
!= NULL
)
927 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
928 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
929 (ULONG_PTR
)SecurityDescriptor
);
931 Group
= (PSID
)SecurityDescriptor
->Group
;
932 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
935 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
939 if (ObjectSd
->Group
!= NULL
)
941 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
942 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
945 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
948 /* Get DACL and DACL size */
949 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
951 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
952 (SecurityDescriptor
->Dacl
!= NULL
))
954 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
955 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+
956 (ULONG_PTR
)SecurityDescriptor
);
958 Dacl
= (PACL
)SecurityDescriptor
->Dacl
;
960 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
963 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
967 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
968 (ObjectSd
->Dacl
!= NULL
))
970 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
971 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
974 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
977 /* Get SACL and SACL size */
978 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
980 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
981 (SecurityDescriptor
->Sacl
!= NULL
))
983 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
984 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+
985 (ULONG_PTR
)SecurityDescriptor
);
987 Sacl
= (PACL
)SecurityDescriptor
->Sacl
;
988 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
991 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
995 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
996 (ObjectSd
->Sacl
!= NULL
))
998 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
999 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
1002 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
1005 NewSd
= ExAllocatePool(NonPagedPool
,
1006 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
1007 DaclLength
+ SaclLength
);
1010 ObDereferenceObject(Object
);
1011 return STATUS_INSUFFICIENT_RESOURCES
;
1014 RtlCreateSecurityDescriptor(NewSd
,
1015 SECURITY_DESCRIPTOR_REVISION1
);
1017 /* We always build a self-relative descriptor */
1018 NewSd
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
1020 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
1022 if (OwnerLength
!= 0)
1024 RtlCopyMemory((PVOID
)Current
,
1027 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
1028 Current
+= OwnerLength
;
1031 if (GroupLength
!= 0)
1033 RtlCopyMemory((PVOID
)Current
,
1036 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
1037 Current
+= GroupLength
;
1040 if (DaclLength
!= 0)
1042 RtlCopyMemory((PVOID
)Current
,
1045 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
1046 Current
+= DaclLength
;
1049 if (SaclLength
!= 0)
1051 RtlCopyMemory((PVOID
)Current
,
1054 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
1055 Current
+= SaclLength
;
1058 *ObjectsSecurityDescriptor
= NewSd
;
1059 return STATUS_SUCCESS
;
1067 SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL
,
1068 IN PSECURITY_INFORMATION SecurityInformation
,
1069 IN PSECURITY_DESCRIPTOR ModificationDescriptor
,
1070 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
1071 IN ULONG AutoInheritFlags
,
1072 IN POOL_TYPE PoolType
,
1073 IN PGENERIC_MAPPING GenericMapping
)
1075 PISECURITY_DESCRIPTOR ObjectSd
= *ObjectsSecurityDescriptor
;
1078 return STATUS_NO_SECURITY_ON_OBJECT
; // The object does not have a security descriptor.
1081 return STATUS_NOT_IMPLEMENTED
;
1089 SeValidSecurityDescriptor(IN ULONG Length
,
1090 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
)
1095 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
1097 if (Length
< SECURITY_DESCRIPTOR_MIN_LENGTH
)
1099 DPRINT1("Invalid Security Descriptor revision\n");
1103 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
1105 DPRINT1("Invalid Security Descriptor revision\n");
1109 if (!(SecurityDescriptor
->Control
& SE_SELF_RELATIVE
))
1111 DPRINT1("No self-relative Security Descriptor\n");
1115 SdLength
= sizeof(SECURITY_DESCRIPTOR
);
1117 /* Check Owner SID */
1118 if (SecurityDescriptor
->Owner
== NULL
)
1120 DPRINT1("No Owner SID\n");
1124 if ((ULONG_PTR
)SecurityDescriptor
->Owner
% sizeof(ULONG
))
1126 DPRINT1("Invalid Owner SID alignment\n");
1130 Sid
= (PISID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Owner
);
1131 if (Sid
->Revision
!= SID_REVISION
)
1133 DPRINT1("Invalid Owner SID revision\n");
1137 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
1138 if (Length
< SdLength
)
1140 DPRINT1("Invalid Owner SID size\n");
1144 /* Check Group SID */
1145 if (SecurityDescriptor
->Group
!= NULL
)
1147 if ((ULONG_PTR
)SecurityDescriptor
->Group
% sizeof(ULONG
))
1149 DPRINT1("Invalid Group SID alignment\n");
1153 Sid
= (PSID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Group
);
1154 if (Sid
->Revision
!= SID_REVISION
)
1156 DPRINT1("Invalid Group SID revision\n");
1160 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
1161 if (Length
< SdLength
)
1163 DPRINT1("Invalid Group SID size\n");
1169 if (SecurityDescriptor
->Dacl
!= NULL
)
1171 if ((ULONG_PTR
)SecurityDescriptor
->Dacl
% sizeof(ULONG
))
1173 DPRINT1("Invalid DACL alignment\n");
1177 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Dacl
);
1178 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) &&
1179 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1181 DPRINT1("Invalid DACL revision\n");
1185 SdLength
+= Acl
->AclSize
;
1186 if (Length
< SdLength
)
1188 DPRINT1("Invalid DACL size\n");
1194 if (SecurityDescriptor
->Sacl
!= NULL
)
1196 if ((ULONG_PTR
)SecurityDescriptor
->Sacl
% sizeof(ULONG
))
1198 DPRINT1("Invalid SACL alignment\n");
1202 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Sacl
);
1203 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
1204 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1206 DPRINT1("Invalid SACL revision\n");
1210 SdLength
+= Acl
->AclSize
;
1211 if (Length
< SdLength
)
1213 DPRINT1("Invalid SACL size\n");
1225 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
1229 if (*SecurityDescriptor
!= NULL
)
1231 ExFreePool(*SecurityDescriptor
);
1232 *SecurityDescriptor
= NULL
;
1235 return STATUS_SUCCESS
;
1243 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
1244 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
1245 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
1246 IN GUID
*ObjectType OPTIONAL
,
1247 IN BOOLEAN IsDirectoryObject
,
1248 IN ULONG AutoInheritFlags
,
1249 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
1250 IN PGENERIC_MAPPING GenericMapping
,
1251 IN POOL_TYPE PoolType
)
1254 return STATUS_NOT_IMPLEMENTED
;
1261 SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL
,
1262 PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL
,
1263 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1264 BOOLEAN IsDirectoryObject
,
1265 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
1266 PGENERIC_MAPPING GenericMapping
,
1269 PISECURITY_DESCRIPTOR ParentDescriptor
= _ParentDescriptor
;
1270 PISECURITY_DESCRIPTOR ExplicitDescriptor
= _ExplicitDescriptor
;
1271 PISECURITY_DESCRIPTOR Descriptor
;
1273 ULONG OwnerLength
= 0;
1274 ULONG GroupLength
= 0;
1275 ULONG DaclLength
= 0;
1276 ULONG SaclLength
= 0;
1287 /* Lock subject context */
1288 SeLockSubjectContext(SubjectContext
);
1290 if (SubjectContext
->ClientToken
!= NULL
)
1292 Token
= SubjectContext
->ClientToken
;
1296 Token
= SubjectContext
->PrimaryToken
;
1299 /* Inherit the Owner SID */
1300 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Owner
!= NULL
)
1302 DPRINT("Use explicit owner sid!\n");
1303 Owner
= ExplicitDescriptor
->Owner
;
1305 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
1307 Owner
= (PSID
)(((ULONG_PTR
)Owner
) + (ULONG_PTR
)ExplicitDescriptor
);
1314 DPRINT("Use token owner sid!\n");
1315 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
1319 DPRINT("Use default owner sid!\n");
1320 Owner
= SeLocalSystemSid
;
1323 Control
|= SE_OWNER_DEFAULTED
;
1326 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
1328 /* Inherit the Group SID */
1329 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Group
!= NULL
)
1331 DPRINT("Use explicit group sid!\n");
1332 Group
= ExplicitDescriptor
->Group
;
1333 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
1335 Group
= (PSID
)(((ULONG_PTR
)Group
) + (ULONG_PTR
)ExplicitDescriptor
);
1342 DPRINT("Use token group sid!\n");
1343 Group
= Token
->PrimaryGroup
;
1347 DPRINT("Use default group sid!\n");
1348 Group
= SeLocalSystemSid
;
1351 Control
|= SE_OWNER_DEFAULTED
;
1354 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
1356 /* Inherit the DACL */
1357 if (ExplicitDescriptor
!= NULL
&&
1358 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
1359 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
1361 DPRINT("Use explicit DACL!\n");
1362 Dacl
= ExplicitDescriptor
->Dacl
;
1363 if (Dacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
1365 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ExplicitDescriptor
);
1368 Control
|= SE_DACL_PRESENT
;
1370 else if (ParentDescriptor
!= NULL
&&
1371 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
1373 DPRINT("Use parent DACL!\n");
1374 /* FIXME: Inherit */
1375 Dacl
= ParentDescriptor
->Dacl
;
1376 if (Dacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
1378 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ParentDescriptor
);
1381 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1383 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
1385 DPRINT("Use token default DACL!\n");
1386 /* FIXME: Inherit */
1387 Dacl
= Token
->DefaultDacl
;
1388 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1392 DPRINT("Use NULL DACL!\n");
1394 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1397 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
1399 /* Inherit the SACL */
1400 if (ExplicitDescriptor
!= NULL
&&
1401 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
1402 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
1404 DPRINT("Use explicit SACL!\n");
1405 Sacl
= ExplicitDescriptor
->Sacl
;
1406 if (Sacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
1408 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ExplicitDescriptor
);
1411 Control
|= SE_SACL_PRESENT
;
1413 else if (ParentDescriptor
!= NULL
&&
1414 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
1416 DPRINT("Use parent SACL!\n");
1417 /* FIXME: Inherit */
1418 Sacl
= ParentDescriptor
->Sacl
;
1419 if (Sacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
1421 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ParentDescriptor
);
1424 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
1427 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
1429 /* Allocate and initialize the new security descriptor */
1430 Length
= sizeof(SECURITY_DESCRIPTOR
) +
1431 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
1433 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
1434 sizeof(SECURITY_DESCRIPTOR
),
1440 Descriptor
= ExAllocatePoolWithTag(PagedPool
,
1443 if (Descriptor
== NULL
)
1445 DPRINT1("ExAlloctePool() failed\n");
1446 /* FIXME: Unlock subject context */
1447 return STATUS_INSUFFICIENT_RESOURCES
;
1450 RtlZeroMemory( Descriptor
, Length
);
1451 RtlCreateSecurityDescriptor(Descriptor
,
1452 SECURITY_DESCRIPTOR_REVISION
);
1454 Descriptor
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
1456 Current
= (ULONG_PTR
)Descriptor
+ sizeof(SECURITY_DESCRIPTOR
);
1458 if (SaclLength
!= 0)
1460 RtlCopyMemory((PVOID
)Current
,
1463 Descriptor
->Sacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1464 Current
+= SaclLength
;
1467 if (DaclLength
!= 0)
1469 RtlCopyMemory((PVOID
)Current
,
1472 Descriptor
->Dacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1473 Current
+= DaclLength
;
1476 if (OwnerLength
!= 0)
1478 RtlCopyMemory((PVOID
)Current
,
1481 Descriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1482 Current
+= OwnerLength
;
1483 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
1487 DPRINT("Owner of %x is zero length\n", Descriptor
);
1490 if (GroupLength
!= 0)
1492 memmove((PVOID
)Current
,
1495 Descriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1498 /* Unlock subject context */
1499 SeUnlockSubjectContext(SubjectContext
);
1501 *NewDescriptor
= Descriptor
;
1503 DPRINT("Descrptor %x\n", Descriptor
);
1504 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
1506 return STATUS_SUCCESS
;