3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/se/sd.c
6 * PURPOSE: Security manager
8 * PROGRAMMERS: David Welch <welch@cwcom.net>
11 /* INCLUDES *****************************************************************/
14 #include <internal/debug.h>
16 /* GLOBALS ******************************************************************/
18 PSECURITY_DESCRIPTOR SePublicDefaultSd
= NULL
;
19 PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd
= NULL
;
20 PSECURITY_DESCRIPTOR SePublicOpenSd
= NULL
;
21 PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd
= NULL
;
22 PSECURITY_DESCRIPTOR SeSystemDefaultSd
= NULL
;
23 PSECURITY_DESCRIPTOR SeUnrestrictedSd
= NULL
;
25 /* FUNCTIONS ***************************************************************/
30 /* Create PublicDefaultSd */
31 SePublicDefaultSd
= ExAllocatePool(NonPagedPool
,
32 sizeof(SECURITY_DESCRIPTOR
));
33 if (SePublicDefaultSd
== NULL
)
36 RtlCreateSecurityDescriptor(SePublicDefaultSd
,
37 SECURITY_DESCRIPTOR_REVISION
);
38 RtlSetDaclSecurityDescriptor(SePublicDefaultSd
,
43 /* Create PublicDefaultUnrestrictedSd */
44 SePublicDefaultUnrestrictedSd
= ExAllocatePool(NonPagedPool
,
45 sizeof(SECURITY_DESCRIPTOR
));
46 if (SePublicDefaultUnrestrictedSd
== NULL
)
49 RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd
,
50 SECURITY_DESCRIPTOR_REVISION
);
51 RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd
,
53 SePublicDefaultUnrestrictedDacl
,
56 /* Create PublicOpenSd */
57 SePublicOpenSd
= ExAllocatePool(NonPagedPool
,
58 sizeof(SECURITY_DESCRIPTOR
));
59 if (SePublicOpenSd
== NULL
)
62 RtlCreateSecurityDescriptor(SePublicOpenSd
,
63 SECURITY_DESCRIPTOR_REVISION
);
64 RtlSetDaclSecurityDescriptor(SePublicOpenSd
,
69 /* Create PublicOpenUnrestrictedSd */
70 SePublicOpenUnrestrictedSd
= ExAllocatePool(NonPagedPool
,
71 sizeof(SECURITY_DESCRIPTOR
));
72 if (SePublicOpenUnrestrictedSd
== NULL
)
75 RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd
,
76 SECURITY_DESCRIPTOR_REVISION
);
77 RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd
,
79 SePublicOpenUnrestrictedDacl
,
82 /* Create SystemDefaultSd */
83 SeSystemDefaultSd
= ExAllocatePool(NonPagedPool
,
84 sizeof(SECURITY_DESCRIPTOR
));
85 if (SeSystemDefaultSd
== NULL
)
88 RtlCreateSecurityDescriptor(SeSystemDefaultSd
,
89 SECURITY_DESCRIPTOR_REVISION
);
90 RtlSetDaclSecurityDescriptor(SeSystemDefaultSd
,
95 /* Create UnrestrictedSd */
96 SeUnrestrictedSd
= ExAllocatePool(NonPagedPool
,
97 sizeof(SECURITY_DESCRIPTOR
));
98 if (SeUnrestrictedSd
== NULL
)
101 RtlCreateSecurityDescriptor(SeUnrestrictedSd
,
102 SECURITY_DESCRIPTOR_REVISION
);
103 RtlSetDaclSecurityDescriptor(SeUnrestrictedSd
,
116 SeCaptureSecurityDescriptor(
117 IN PSECURITY_DESCRIPTOR OriginalSecurityDescriptor
,
118 IN KPROCESSOR_MODE CurrentMode
,
119 IN POOL_TYPE PoolType
,
120 IN BOOLEAN CaptureIfKernel
,
121 OUT PSECURITY_DESCRIPTOR
*CapturedSecurityDescriptor
124 SECURITY_DESCRIPTOR DescriptorCopy
;
125 PSECURITY_DESCRIPTOR NewDescriptor
;
126 ULONG OwnerSAC
= 0, GroupSAC
= 0;
127 ULONG OwnerSize
= 0, GroupSize
= 0;
128 ULONG SaclSize
= 0, DaclSize
= 0;
129 ULONG DescriptorSize
= 0;
130 NTSTATUS Status
= STATUS_SUCCESS
;
132 if(OriginalSecurityDescriptor
!= NULL
)
134 if(CurrentMode
!= KernelMode
)
138 /* first only probe and copy until the control field of the descriptor
139 to determine whether it's a self-relative descriptor */
140 DescriptorSize
= (ULONG
)((ULONG_PTR
)&OriginalSecurityDescriptor
->Control
-
141 (ULONG_PTR
)OriginalSecurityDescriptor
) +
142 sizeof(OriginalSecurityDescriptor
->Control
);
143 ProbeForRead(OriginalSecurityDescriptor
,
147 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
149 Status
= STATUS_UNKNOWN_REVISION
;
153 /* make a copy on the stack */
154 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
155 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
156 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
157 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
158 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
160 /* probe and copy the entire security descriptor structure. The SIDs
161 and ACLs will be probed and copied later though */
162 ProbeForRead(OriginalSecurityDescriptor
,
165 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
167 PSECURITY_DESCRIPTOR_RELATIVE RelSD
= (PSECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
169 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
170 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
171 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
172 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
176 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
177 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
178 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
179 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
184 Status
= _SEH_GetExceptionCode();
188 if(!NT_SUCCESS(Status
))
193 else if(!CaptureIfKernel
)
195 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
197 return STATUS_UNKNOWN_REVISION
;
200 *CapturedSecurityDescriptor
= OriginalSecurityDescriptor
;
201 return STATUS_SUCCESS
;
205 if(OriginalSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
207 return STATUS_UNKNOWN_REVISION
;
210 /* make a copy on the stack */
211 DescriptorCopy
.Revision
= OriginalSecurityDescriptor
->Revision
;
212 DescriptorCopy
.Sbz1
= OriginalSecurityDescriptor
->Sbz1
;
213 DescriptorCopy
.Control
= OriginalSecurityDescriptor
->Control
;
214 DescriptorSize
= ((DescriptorCopy
.Control
& SE_SELF_RELATIVE
) ?
215 sizeof(SECURITY_DESCRIPTOR_RELATIVE
) : sizeof(SECURITY_DESCRIPTOR
));
216 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
218 PSECURITY_DESCRIPTOR_RELATIVE RelSD
= (PSECURITY_DESCRIPTOR_RELATIVE
)OriginalSecurityDescriptor
;
220 DescriptorCopy
.Owner
= (PSID
)RelSD
->Owner
;
221 DescriptorCopy
.Group
= (PSID
)RelSD
->Group
;
222 DescriptorCopy
.Sacl
= (PACL
)RelSD
->Sacl
;
223 DescriptorCopy
.Dacl
= (PACL
)RelSD
->Dacl
;
227 DescriptorCopy
.Owner
= OriginalSecurityDescriptor
->Owner
;
228 DescriptorCopy
.Group
= OriginalSecurityDescriptor
->Group
;
229 DescriptorCopy
.Sacl
= OriginalSecurityDescriptor
->Sacl
;
230 DescriptorCopy
.Dacl
= OriginalSecurityDescriptor
->Dacl
;
234 if(DescriptorCopy
.Control
& SE_SELF_RELATIVE
)
236 /* in case we're dealing with a self-relative descriptor, do a basic convert
237 to an absolute descriptor. We do this so we can simply access the data
238 using the pointers without calculating them again. */
239 DescriptorCopy
.Control
&= ~SE_SELF_RELATIVE
;
240 if(DescriptorCopy
.Owner
!= NULL
)
242 DescriptorCopy
.Owner
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Owner
);
244 if(DescriptorCopy
.Group
!= NULL
)
246 DescriptorCopy
.Group
= (PSID
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Group
);
248 if(DescriptorCopy
.Dacl
!= NULL
)
250 DescriptorCopy
.Dacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Dacl
);
252 if(DescriptorCopy
.Sacl
!= NULL
)
254 DescriptorCopy
.Sacl
= (PACL
)((ULONG_PTR
)OriginalSecurityDescriptor
+ (ULONG_PTR
)DescriptorCopy
.Sacl
);
258 /* determine the size of the SIDs */
259 #define DetermineSIDSize(SidType) \
261 if(DescriptorCopy.SidType != NULL) \
263 SID *SidType = (SID*)DescriptorCopy.SidType; \
265 if(CurrentMode != KernelMode) \
267 /* securely access the buffers! */ \
270 ProbeForRead(&SidType->SubAuthorityCount, \
271 sizeof(SidType->SubAuthorityCount), \
273 SidType##SAC = SidType->SubAuthorityCount; \
274 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
275 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
276 ProbeForRead(SidType, \
279 if(!RtlValidSid(SidType)) \
281 Status = STATUS_INVALID_SID; \
286 Status = _SEH_GetExceptionCode(); \
290 if(!NT_SUCCESS(Status)) \
297 SidType##SAC = SidType->SubAuthorityCount; \
298 SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
299 DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
304 DetermineSIDSize(Owner
);
305 DetermineSIDSize(Group
);
307 /* determine the size of the ACLs */
308 #define DetermineACLSize(AclType, AclFlag) \
310 if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \
311 DescriptorCopy.AclType != NULL) \
313 PACL AclType = (PACL)DescriptorCopy.AclType; \
315 if(CurrentMode != KernelMode) \
317 /* securely access the buffers! */ \
320 ProbeForRead(&AclType->AclSize, \
321 sizeof(AclType->AclSize), \
323 AclType##Size = AclType->AclSize; \
324 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
325 ProbeForRead(AclType, \
328 if(!RtlValidAcl(AclType)) \
330 Status = STATUS_INVALID_ACL; \
335 Status = _SEH_GetExceptionCode(); \
339 if(!NT_SUCCESS(Status)) \
346 AclType##Size = AclType->AclSize; \
347 DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
352 DescriptorCopy.AclType = NULL; \
356 DetermineACLSize(Sacl
, SACL
);
357 DetermineACLSize(Dacl
, DACL
);
359 /* allocate enough memory to store a complete copy of a self-relative
360 security descriptor */
361 NewDescriptor
= ExAllocatePool(PoolType
,
363 if(NewDescriptor
!= NULL
)
365 ULONG_PTR Offset
= sizeof(SECURITY_DESCRIPTOR
);
367 NewDescriptor
->Revision
= DescriptorCopy
.Revision
;
368 NewDescriptor
->Sbz1
= DescriptorCopy
.Sbz1
;
369 NewDescriptor
->Control
= DescriptorCopy
.Control
| SE_SELF_RELATIVE
;
373 /* setup the offsets and copy the SIDs and ACLs to the new
374 self-relative security descriptor. Probing the pointers is not
375 neccessary anymore as we did that when collecting the sizes! */
376 #define CopySIDOrACL(Type) \
378 if(DescriptorCopy.Type != NULL) \
380 NewDescriptor->Type = (PVOID)Offset; \
381 RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
382 (ULONG_PTR)NewDescriptor->Type), \
383 DescriptorCopy.Type, \
385 Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
396 Status
= _SEH_GetExceptionCode();
400 if(NT_SUCCESS(Status
))
402 /* we're finally done! copy the pointer to the captured descriptor to
404 *CapturedSecurityDescriptor
= NewDescriptor
;
405 return STATUS_SUCCESS
;
409 /* we failed to copy the data to the new descriptor */
410 ExFreePool(NewDescriptor
);
415 Status
= STATUS_INSUFFICIENT_RESOURCES
;
420 /* nothing to do... */
421 *CapturedSecurityDescriptor
= NULL
;
431 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation
,
432 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
433 IN OUT PULONG Length
,
434 IN PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor OPTIONAL
)
436 PSECURITY_DESCRIPTOR ObjectSd
;
437 PSECURITY_DESCRIPTOR_RELATIVE RelSD
;
442 ULONG OwnerLength
= 0;
443 ULONG GroupLength
= 0;
444 ULONG DaclLength
= 0;
445 ULONG SaclLength
= 0;
450 RelSD
= (PSECURITY_DESCRIPTOR_RELATIVE
)SecurityDescriptor
;
452 if (*ObjectsSecurityDescriptor
== NULL
)
454 if (*Length
< sizeof(SECURITY_DESCRIPTOR_RELATIVE
))
456 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
457 return STATUS_BUFFER_TOO_SMALL
;
460 *Length
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
461 RtlCreateSecurityDescriptorRelative(RelSD
,
462 SECURITY_DESCRIPTOR_REVISION
);
463 return STATUS_SUCCESS
;
466 ObjectSd
= *ObjectsSecurityDescriptor
;
468 /* Calculate the required security descriptor length */
469 Control
= SE_SELF_RELATIVE
;
470 if ((*SecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
471 (ObjectSd
->Owner
!= NULL
))
473 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
474 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
475 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
478 if ((*SecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
479 (ObjectSd
->Group
!= NULL
))
481 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
482 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
483 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
486 if ((*SecurityInformation
& DACL_SECURITY_INFORMATION
) &&
487 (ObjectSd
->Control
& SE_DACL_PRESENT
))
489 if (ObjectSd
->Dacl
!= NULL
)
491 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
492 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
494 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
497 if ((*SecurityInformation
& SACL_SECURITY_INFORMATION
) &&
498 (ObjectSd
->Control
& SE_SACL_PRESENT
))
500 if (ObjectSd
->Sacl
!= NULL
)
502 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
503 SaclLength
= ROUND_UP(Sacl
->AclSize
, 4);
505 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
508 SdLength
= OwnerLength
+ GroupLength
+ DaclLength
+
509 SaclLength
+ sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
510 if (*Length
< SdLength
)
513 return STATUS_BUFFER_TOO_SMALL
;
516 /* Build the new security descrtiptor */
517 RtlCreateSecurityDescriptorRelative(RelSD
,
518 SECURITY_DESCRIPTOR_REVISION
);
519 RelSD
->Control
= Control
;
521 Current
= (ULONG_PTR
)(RelSD
+ 1);
523 if (OwnerLength
!= 0)
525 RtlCopyMemory((PVOID
)Current
,
528 RelSD
->Owner
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
529 Current
+= OwnerLength
;
532 if (GroupLength
!= 0)
534 RtlCopyMemory((PVOID
)Current
,
537 RelSD
->Group
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
538 Current
+= GroupLength
;
543 RtlCopyMemory((PVOID
)Current
,
546 RelSD
->Dacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
547 Current
+= DaclLength
;
552 RtlCopyMemory((PVOID
)Current
,
555 RelSD
->Sacl
= (ULONG
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
556 Current
+= SaclLength
;
561 return STATUS_SUCCESS
;
569 SeReleaseSecurityDescriptor(
570 IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor
,
571 IN KPROCESSOR_MODE CurrentMode
,
572 IN BOOLEAN CaptureIfKernelMode
575 /* WARNING! You need to call this function with the same value for CurrentMode
576 and CaptureIfKernelMode that you previously passed to
577 SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
578 if(CapturedSecurityDescriptor
!= NULL
&&
579 (CurrentMode
== UserMode
||
580 (CurrentMode
== KernelMode
&& CaptureIfKernelMode
)))
582 /* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
583 ExFreePool(CapturedSecurityDescriptor
);
586 return STATUS_SUCCESS
;
593 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL
,
594 IN PSECURITY_INFORMATION SecurityInformation
,
595 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
596 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
597 IN POOL_TYPE PoolType
,
598 IN PGENERIC_MAPPING GenericMapping
)
601 return STATUS_NOT_IMPLEMENTED
;
609 SeSetSecurityDescriptorInfoEx(
610 IN PVOID Object OPTIONAL
,
611 IN PSECURITY_INFORMATION SecurityInformation
,
612 IN PSECURITY_DESCRIPTOR ModificationDescriptor
,
613 IN OUT PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
614 IN ULONG AutoInheritFlags
,
615 IN POOL_TYPE PoolType
,
616 IN PGENERIC_MAPPING GenericMapping
620 return STATUS_NOT_IMPLEMENTED
;
628 SeValidSecurityDescriptor(IN ULONG Length
,
629 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
635 if (Length
< SECURITY_DESCRIPTOR_MIN_LENGTH
)
637 DPRINT1("Invalid Security Descriptor revision\n");
641 if (SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION1
)
643 DPRINT1("Invalid Security Descriptor revision\n");
647 if (!(SecurityDescriptor
->Control
& SE_SELF_RELATIVE
))
649 DPRINT1("No self-relative Security Descriptor\n");
653 SdLength
= sizeof(SECURITY_DESCRIPTOR
);
655 /* Check Owner SID */
656 if (SecurityDescriptor
->Owner
== NULL
)
658 DPRINT1("No Owner SID\n");
662 if ((ULONG_PTR
)SecurityDescriptor
->Owner
% sizeof(ULONG
))
664 DPRINT1("Invalid Owner SID alignment\n");
668 Sid
= (PISID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Owner
);
669 if (Sid
->Revision
!= SID_REVISION
)
671 DPRINT1("Invalid Owner SID revision\n");
675 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
676 if (Length
< SdLength
)
678 DPRINT1("Invalid Owner SID size\n");
682 /* Check Group SID */
683 if (SecurityDescriptor
->Group
!= NULL
)
685 if ((ULONG_PTR
)SecurityDescriptor
->Group
% sizeof(ULONG
))
687 DPRINT1("Invalid Group SID alignment\n");
691 Sid
= (PSID
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Group
);
692 if (Sid
->Revision
!= SID_REVISION
)
694 DPRINT1("Invalid Group SID revision\n");
698 SdLength
+= (sizeof(SID
) + (Sid
->SubAuthorityCount
- 1) * sizeof(ULONG
));
699 if (Length
< SdLength
)
701 DPRINT1("Invalid Group SID size\n");
707 if (SecurityDescriptor
->Dacl
!= NULL
)
709 if ((ULONG_PTR
)SecurityDescriptor
->Dacl
% sizeof(ULONG
))
711 DPRINT1("Invalid DACL alignment\n");
715 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Dacl
);
716 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) &&
717 (Acl
->AclRevision
> MAX_ACL_REVISION
))
719 DPRINT1("Invalid DACL revision\n");
723 SdLength
+= Acl
->AclSize
;
724 if (Length
< SdLength
)
726 DPRINT1("Invalid DACL size\n");
732 if (SecurityDescriptor
->Sacl
!= NULL
)
734 if ((ULONG_PTR
)SecurityDescriptor
->Sacl
% sizeof(ULONG
))
736 DPRINT1("Invalid SACL alignment\n");
740 Acl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
+ (ULONG_PTR
)SecurityDescriptor
->Sacl
);
741 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
742 (Acl
->AclRevision
> MAX_ACL_REVISION
))
744 DPRINT1("Invalid SACL revision\n");
748 SdLength
+= Acl
->AclSize
;
749 if (Length
< SdLength
)
751 DPRINT1("Invalid SACL size\n");