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
;
690 Status
= STATUS_INSUFFICIENT_RESOURCES
;
695 /* nothing to do... */
696 *CapturedSecurityDescriptor
= NULL
;
706 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation
,
707 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
708 IN OUT PULONG Length
,
709 IN PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor OPTIONAL
)
711 PISECURITY_DESCRIPTOR ObjectSd
;
712 PISECURITY_DESCRIPTOR_RELATIVE RelSD
;
717 ULONG OwnerLength
= 0;
718 ULONG GroupLength
= 0;
719 ULONG DaclLength
= 0;
720 ULONG SaclLength
= 0;
725 RelSD
= (PISECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
727 if (*ObjectsSecurityDescriptor
== NULL
)
729 if (*Length
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
))
731 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
732 return STATUS_BUFFER_TOO_SMALL
;
735 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
736 RtlCreateSecurityDescriptorRelative(RelSD
,
737 SECURITY_DESCRIPTOR_REVISION
);
738 return STATUS_SUCCESS
;
741 ObjectSd
= *ObjectsSecurityDescriptor
;
743 /* Calculate the required security descriptor length */
744 Control
= SE_SELF_RELATIVE
;
745 if ((*SecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
746 (ObjectSd
->Owner
!= NULL
))
748 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
749 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
750 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
753 if ((*SecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
754 (ObjectSd
->Group
!= NULL
))
756 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
757 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
758 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
761 if ((*SecurityInformation
& DACL_SECURITY_INFORMATION
) &&
762 (ObjectSd
->Control
& SE_DACL_PRESENT
))
764 if (ObjectSd
->Dacl
!= NULL
)
766 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
767 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
769 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
772 if ((*SecurityInformation
& SACL_SECURITY_INFORMATION
) &&
773 (ObjectSd
->Control
& SE_SACL_PRESENT
))
775 if (ObjectSd
->Sacl
!= NULL
)
777 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
778 SaclLength
= ROUND_UP(Sacl
->AclSize
, 4);
780 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
783 SdLength
= OwnerLength
+ GroupLength
+ DaclLength
+
784 SaclLength
+ sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
785 if (*Length
< SdLength
)
788 return STATUS_BUFFER_TOO_SMALL
;
791 /* Build the new security descrtiptor */
792 RtlCreateSecurityDescriptorRelative(RelSD
,
793 SECURITY_DESCRIPTOR_REVISION
);
794 RelSD
->Control
= (USHORT
)Control
;
796 Current
= (ULONG_PTR
)(RelSD
+ 1);
798 if (OwnerLength
!= 0)
800 RtlCopyMemory((PVOID
)Current
,
803 RelSD
->Owner
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
804 Current
+= OwnerLength
;
807 if (GroupLength
!= 0)
809 RtlCopyMemory((PVOID
)Current
,
812 RelSD
->Group
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
813 Current
+= GroupLength
;
818 RtlCopyMemory((PVOID
)Current
,
821 RelSD
->Dacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
822 Current
+= DaclLength
;
827 RtlCopyMemory((PVOID
)Current
,
830 RelSD
->Sacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
831 Current
+= SaclLength
;
836 return STATUS_SUCCESS
;
844 SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor
,
845 IN KPROCESSOR_MODE CurrentMode
,
846 IN BOOLEAN CaptureIfKernelMode
)
850 /* WARNING! You need to call this function with the same value for CurrentMode
851 and CaptureIfKernelMode that you previously passed to
852 SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
853 if(CapturedSecurityDescriptor
!= NULL
&&
854 (CurrentMode
!= KernelMode
||
855 (CurrentMode
== KernelMode
&& CaptureIfKernelMode
)))
857 /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
858 ExFreePoolWithTag(CapturedSecurityDescriptor
, TAG_SD
);
861 return STATUS_SUCCESS
;
868 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL
,
869 IN PSECURITY_INFORMATION _SecurityInformation
,
870 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
,
871 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
872 IN POOL_TYPE PoolType
,
873 IN PGENERIC_MAPPING GenericMapping
)
875 PISECURITY_DESCRIPTOR ObjectSd
;
876 PISECURITY_DESCRIPTOR NewSd
;
877 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
882 ULONG OwnerLength
= 0;
883 ULONG GroupLength
= 0;
884 ULONG DaclLength
= 0;
885 ULONG SaclLength
= 0;
888 SECURITY_INFORMATION SecurityInformation
;
890 ObjectSd
= *ObjectsSecurityDescriptor
;
893 return STATUS_NO_SECURITY_ON_OBJECT
; // The object does not have a security descriptor.
895 SecurityInformation
= *_SecurityInformation
;
897 /* Get owner and owner size */
898 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
900 if (SecurityDescriptor
->Owner
!= NULL
)
902 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
903 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+
904 (ULONG_PTR
)SecurityDescriptor
);
906 Owner
= (PSID
)SecurityDescriptor
->Owner
;
907 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);
918 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
921 /* Get group and group size */
922 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
924 if (SecurityDescriptor
->Group
!= NULL
)
926 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
927 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
928 (ULONG_PTR
)SecurityDescriptor
);
930 Group
= (PSID
)SecurityDescriptor
->Group
;
931 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
933 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
937 if (ObjectSd
->Group
!= NULL
)
939 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
940 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
942 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
945 /* Get DACL and DACL size */
946 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
948 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
949 (SecurityDescriptor
->Dacl
!= NULL
))
951 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
952 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+
953 (ULONG_PTR
)SecurityDescriptor
);
955 Dacl
= (PACL
)SecurityDescriptor
->Dacl
;
957 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
959 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
963 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
964 (ObjectSd
->Dacl
!= NULL
))
966 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
967 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
969 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
972 /* Get SACL and SACL size */
973 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
975 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
976 (SecurityDescriptor
->Sacl
!= NULL
))
978 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
979 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+
980 (ULONG_PTR
)SecurityDescriptor
);
982 Sacl
= (PACL
)SecurityDescriptor
->Sacl
;
983 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
985 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
989 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
990 (ObjectSd
->Sacl
!= NULL
))
992 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
993 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
995 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
998 NewSd
= ExAllocatePool(NonPagedPool
,
999 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
1000 DaclLength
+ SaclLength
);
1003 ObDereferenceObject(Object
);
1004 return STATUS_INSUFFICIENT_RESOURCES
;
1007 RtlCreateSecurityDescriptor(NewSd
,
1008 SECURITY_DESCRIPTOR_REVISION1
);
1009 /* We always build a self-relative descriptor */
1010 NewSd
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
1012 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
1014 if (OwnerLength
!= 0)
1016 RtlCopyMemory((PVOID
)Current
,
1019 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
1020 Current
+= OwnerLength
;
1023 if (GroupLength
!= 0)
1025 RtlCopyMemory((PVOID
)Current
,
1028 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
1029 Current
+= GroupLength
;
1032 if (DaclLength
!= 0)
1034 RtlCopyMemory((PVOID
)Current
,
1037 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
1038 Current
+= DaclLength
;
1041 if (SaclLength
!= 0)
1043 RtlCopyMemory((PVOID
)Current
,
1046 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
1047 Current
+= SaclLength
;
1050 *ObjectsSecurityDescriptor
= NewSd
;
1051 return STATUS_SUCCESS
;
1059 SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL
,
1060 IN PSECURITY_INFORMATION SecurityInformation
,
1061 IN PSECURITY_DESCRIPTOR ModificationDescriptor
,
1062 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
1063 IN ULONG AutoInheritFlags
,
1064 IN POOL_TYPE PoolType
,
1065 IN PGENERIC_MAPPING GenericMapping
)
1067 PISECURITY_DESCRIPTOR ObjectSd
= *ObjectsSecurityDescriptor
;
1070 return STATUS_NO_SECURITY_ON_OBJECT
; // The object does not have a security descriptor.
1073 return STATUS_NOT_IMPLEMENTED
;
1081 SeValidSecurityDescriptor(IN ULONG Length
,
1082 IN PSECURITY_DESCRIPTOR _SecurityDescriptor
)
1087 PISECURITY_DESCRIPTOR SecurityDescriptor
= _SecurityDescriptor
;
1089 if (Length
< SECURITY_DESCRIPTOR_MIN_LENGTH
)
1091 DPRINT1("Invalid Security Descriptor revision\n");
1095 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
1097 DPRINT1("Invalid Security Descriptor revision\n");
1101 if (!(SecurityDescriptor
->Control
& SE_SELF_RELATIVE
))
1103 DPRINT1("No self-relative Security Descriptor\n");
1107 SdLength
= sizeof(SECURITY_DESCRIPTOR
);
1109 /* Check Owner SID */
1110 if (SecurityDescriptor
->Owner
== NULL
)
1112 DPRINT1("No Owner SID\n");
1116 if ((ULONG_PTR
)SecurityDescriptor
->Owner
% sizeof(ULONG
))
1118 DPRINT1("Invalid Owner SID alignment\n");
1122 Sid
= (PISID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Owner
);
1123 if (Sid
->Revision
!= SID_REVISION
)
1125 DPRINT1("Invalid Owner SID revision\n");
1129 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
1130 if (Length
< SdLength
)
1132 DPRINT1("Invalid Owner SID size\n");
1136 /* Check Group SID */
1137 if (SecurityDescriptor
->Group
!= NULL
)
1139 if ((ULONG_PTR
)SecurityDescriptor
->Group
% sizeof(ULONG
))
1141 DPRINT1("Invalid Group SID alignment\n");
1145 Sid
= (PSID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Group
);
1146 if (Sid
->Revision
!= SID_REVISION
)
1148 DPRINT1("Invalid Group SID revision\n");
1152 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
1153 if (Length
< SdLength
)
1155 DPRINT1("Invalid Group SID size\n");
1161 if (SecurityDescriptor
->Dacl
!= NULL
)
1163 if ((ULONG_PTR
)SecurityDescriptor
->Dacl
% sizeof(ULONG
))
1165 DPRINT1("Invalid DACL alignment\n");
1169 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Dacl
);
1170 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) &&
1171 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1173 DPRINT1("Invalid DACL revision\n");
1177 SdLength
+= Acl
->AclSize
;
1178 if (Length
< SdLength
)
1180 DPRINT1("Invalid DACL size\n");
1186 if (SecurityDescriptor
->Sacl
!= NULL
)
1188 if ((ULONG_PTR
)SecurityDescriptor
->Sacl
% sizeof(ULONG
))
1190 DPRINT1("Invalid SACL alignment\n");
1194 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Sacl
);
1195 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
1196 (Acl
->AclRevision
> MAX_ACL_REVISION
))
1198 DPRINT1("Invalid SACL revision\n");
1202 SdLength
+= Acl
->AclSize
;
1203 if (Length
< SdLength
)
1205 DPRINT1("Invalid SACL size\n");
1217 SeDeassignSecurity(PSECURITY_DESCRIPTOR
*SecurityDescriptor
)
1221 if (*SecurityDescriptor
!= NULL
)
1223 ExFreePool(*SecurityDescriptor
);
1224 *SecurityDescriptor
= NULL
;
1227 return STATUS_SUCCESS
;
1235 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL
,
1236 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL
,
1237 OUT PSECURITY_DESCRIPTOR
*NewDescriptor
,
1238 IN GUID
*ObjectType OPTIONAL
,
1239 IN BOOLEAN IsDirectoryObject
,
1240 IN ULONG AutoInheritFlags
,
1241 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
1242 IN PGENERIC_MAPPING GenericMapping
,
1243 IN POOL_TYPE PoolType
)
1246 return STATUS_NOT_IMPLEMENTED
;
1253 SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL
,
1254 PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL
,
1255 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1256 BOOLEAN IsDirectoryObject
,
1257 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
1258 PGENERIC_MAPPING GenericMapping
,
1261 PISECURITY_DESCRIPTOR ParentDescriptor
= _ParentDescriptor
;
1262 PISECURITY_DESCRIPTOR ExplicitDescriptor
= _ExplicitDescriptor
;
1263 PISECURITY_DESCRIPTOR Descriptor
;
1265 ULONG OwnerLength
= 0;
1266 ULONG GroupLength
= 0;
1267 ULONG DaclLength
= 0;
1268 ULONG SaclLength
= 0;
1279 /* Lock subject context */
1280 SeLockSubjectContext(SubjectContext
);
1282 if (SubjectContext
->ClientToken
!= NULL
)
1284 Token
= SubjectContext
->ClientToken
;
1288 Token
= SubjectContext
->PrimaryToken
;
1292 /* Inherit the Owner SID */
1293 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Owner
!= NULL
)
1295 DPRINT("Use explicit owner sid!\n");
1296 Owner
= ExplicitDescriptor
->Owner
;
1298 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
1300 Owner
= (PSID
)(((ULONG_PTR
)Owner
) + (ULONG_PTR
)ExplicitDescriptor
);
1308 DPRINT("Use token owner sid!\n");
1309 Owner
= Token
->UserAndGroups
[Token
->DefaultOwnerIndex
].Sid
;
1313 DPRINT("Use default owner sid!\n");
1314 Owner
= SeLocalSystemSid
;
1317 Control
|= SE_OWNER_DEFAULTED
;
1320 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
1323 /* Inherit the Group SID */
1324 if (ExplicitDescriptor
!= NULL
&& ExplicitDescriptor
->Group
!= NULL
)
1326 DPRINT("Use explicit group sid!\n");
1327 Group
= ExplicitDescriptor
->Group
;
1328 if (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
)
1330 Group
= (PSID
)(((ULONG_PTR
)Group
) + (ULONG_PTR
)ExplicitDescriptor
);
1337 DPRINT("Use token group sid!\n");
1338 Group
= Token
->PrimaryGroup
;
1342 DPRINT("Use default group sid!\n");
1343 Group
= SeLocalSystemSid
;
1346 Control
|= SE_OWNER_DEFAULTED
;
1349 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
1352 /* Inherit the DACL */
1353 if (ExplicitDescriptor
!= NULL
&&
1354 (ExplicitDescriptor
->Control
& SE_DACL_PRESENT
) &&
1355 !(ExplicitDescriptor
->Control
& SE_DACL_DEFAULTED
))
1357 DPRINT("Use explicit DACL!\n");
1358 Dacl
= ExplicitDescriptor
->Dacl
;
1359 if (Dacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
1361 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ExplicitDescriptor
);
1364 Control
|= SE_DACL_PRESENT
;
1366 else if (ParentDescriptor
!= NULL
&&
1367 (ParentDescriptor
->Control
& SE_DACL_PRESENT
))
1369 DPRINT("Use parent DACL!\n");
1370 /* FIXME: Inherit */
1371 Dacl
= ParentDescriptor
->Dacl
;
1372 if (Dacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
1374 Dacl
= (PACL
)(((ULONG_PTR
)Dacl
) + (ULONG_PTR
)ParentDescriptor
);
1376 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1378 else if (Token
!= NULL
&& Token
->DefaultDacl
!= NULL
)
1380 DPRINT("Use token default DACL!\n");
1381 /* FIXME: Inherit */
1382 Dacl
= Token
->DefaultDacl
;
1383 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1387 DPRINT("Use NULL DACL!\n");
1389 Control
|= (SE_DACL_PRESENT
| SE_DACL_DEFAULTED
);
1392 DaclLength
= (Dacl
!= NULL
) ? ROUND_UP(Dacl
->AclSize
, 4) : 0;
1395 /* Inherit the SACL */
1396 if (ExplicitDescriptor
!= NULL
&&
1397 (ExplicitDescriptor
->Control
& SE_SACL_PRESENT
) &&
1398 !(ExplicitDescriptor
->Control
& SE_SACL_DEFAULTED
))
1400 DPRINT("Use explicit SACL!\n");
1401 Sacl
= ExplicitDescriptor
->Sacl
;
1402 if (Sacl
!= NULL
&& (ExplicitDescriptor
->Control
& SE_SELF_RELATIVE
))
1404 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ExplicitDescriptor
);
1407 Control
|= SE_SACL_PRESENT
;
1409 else if (ParentDescriptor
!= NULL
&&
1410 (ParentDescriptor
->Control
& SE_SACL_PRESENT
))
1412 DPRINT("Use parent SACL!\n");
1413 /* FIXME: Inherit */
1414 Sacl
= ParentDescriptor
->Sacl
;
1415 if (Sacl
!= NULL
&& (ParentDescriptor
->Control
& SE_SELF_RELATIVE
))
1417 Sacl
= (PACL
)(((ULONG_PTR
)Sacl
) + (ULONG_PTR
)ParentDescriptor
);
1419 Control
|= (SE_SACL_PRESENT
| SE_SACL_DEFAULTED
);
1422 SaclLength
= (Sacl
!= NULL
) ? ROUND_UP(Sacl
->AclSize
, 4) : 0;
1425 /* Allocate and initialize the new security descriptor */
1426 Length
= sizeof(SECURITY_DESCRIPTOR
) +
1427 OwnerLength
+ GroupLength
+ DaclLength
+ SaclLength
;
1429 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
1430 sizeof(SECURITY_DESCRIPTOR
),
1436 Descriptor
= ExAllocatePoolWithTag(PagedPool
,
1439 if (Descriptor
== NULL
)
1441 DPRINT1("ExAlloctePool() failed\n");
1442 /* FIXME: Unlock subject context */
1443 return STATUS_INSUFFICIENT_RESOURCES
;
1446 RtlZeroMemory( Descriptor
, Length
);
1447 RtlCreateSecurityDescriptor(Descriptor
,
1448 SECURITY_DESCRIPTOR_REVISION
);
1450 Descriptor
->Control
= (USHORT
)Control
| SE_SELF_RELATIVE
;
1452 Current
= (ULONG_PTR
)Descriptor
+ sizeof(SECURITY_DESCRIPTOR
);
1454 if (SaclLength
!= 0)
1456 RtlCopyMemory((PVOID
)Current
,
1459 Descriptor
->Sacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1460 Current
+= SaclLength
;
1463 if (DaclLength
!= 0)
1465 RtlCopyMemory((PVOID
)Current
,
1468 Descriptor
->Dacl
= (PACL
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1469 Current
+= DaclLength
;
1472 if (OwnerLength
!= 0)
1474 RtlCopyMemory((PVOID
)Current
,
1477 Descriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1478 Current
+= OwnerLength
;
1479 DPRINT("Owner of %x at %x\n", Descriptor
, Descriptor
->Owner
);
1482 DPRINT("Owner of %x is zero length\n", Descriptor
);
1484 if (GroupLength
!= 0)
1486 memmove((PVOID
)Current
,
1489 Descriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)Descriptor
);
1492 /* Unlock subject context */
1493 SeUnlockSubjectContext(SubjectContext
);
1495 *NewDescriptor
= Descriptor
;
1497 DPRINT("Descrptor %x\n", Descriptor
);
1498 ASSERT(RtlLengthSecurityDescriptor(Descriptor
));
1500 return STATUS_SUCCESS
;