1 /* COPYRIGHT: See COPYING in the top level directory
2 * PROJECT: ReactOS system libraries
3 * PURPOSE: Security manager
5 * PROGRAMER: David Welch <welch@cwcom.net>
8 /* INCLUDES *****************************************************************/
11 #include <../../ntoskrnl/include/internal/se.h>
15 /* PRIVATE FUNCTIONS **********************************************************/
19 RtlFirstFreeAce(IN PACL Acl
,
20 OUT PACE
* FirstFreeAce
)
30 /* Get the start and end pointers */
31 Current
= (PACE
)(Acl
+ 1);
32 AclEnd
= (ULONG_PTR
)Acl
+ Acl
->AclSize
;
34 /* Loop all the ACEs */
35 for (i
= 0; i
< Acl
->AceCount
; i
++)
37 /* If any is beyond the DACL, bail out, otherwise keep going */
38 if ((ULONG_PTR
)Current
>= AclEnd
) return FALSE
;
39 Current
= (PACE
)((ULONG_PTR
)Current
+ Current
->Header
.AceSize
);
42 /* If the last spot is empty and still valid, return it */
43 if ((ULONG_PTR
)Current
< AclEnd
) *FirstFreeAce
= Current
;
49 RtlpAddData(IN PVOID AceList
,
50 IN ULONG AceListLength
,
54 /* Shift the buffer down */
57 RtlCopyMemory((PVOID
)((ULONG_PTR
)Ace
+ AceListLength
),
62 /* Copy the new data in */
63 if (AceListLength
) RtlCopyMemory(Ace
, AceList
, AceListLength
);
68 RtlpDeleteData(IN PVOID Ace
,
72 /* Move the data up */
76 (PVOID
)((ULONG_PTR
)Ace
+ AceSize
),
81 if ((Offset
- AceSize
) < Offset
)
83 RtlZeroMemory((PVOID
)((ULONG_PTR
)Ace
+ Offset
- AceSize
), AceSize
);
89 RtlpAddKnownAce(IN PACL Acl
,
92 IN ACCESS_MASK AccessMask
,
97 ULONG AceSize
, InvalidFlags
;
100 /* Check the validity of the SID */
101 if (!RtlValidSid(Sid
)) return STATUS_INVALID_SID
;
103 /* Check the validity of the revision */
104 if ((Acl
->AclRevision
> ACL_REVISION4
) || (Revision
> ACL_REVISION4
))
106 return STATUS_REVISION_MISMATCH
;
109 /* Pick the smallest of the revisions */
110 if (Revision
< Acl
->AclRevision
) Revision
= Acl
->AclRevision
;
112 /* Validate the flags */
113 if (Type
== SYSTEM_AUDIT_ACE_TYPE
)
115 InvalidFlags
= Flags
& ~(VALID_INHERIT_FLAGS
|
116 SUCCESSFUL_ACCESS_ACE_FLAG
|
117 FAILED_ACCESS_ACE_FLAG
);
121 InvalidFlags
= Flags
& ~VALID_INHERIT_FLAGS
;
124 /* If flags are invalid, bail out */
125 if (InvalidFlags
!= 0) return STATUS_INVALID_PARAMETER
;
127 /* If ACL is invalid, bail out */
128 if (!RtlValidAcl(Acl
)) return STATUS_INVALID_ACL
;
130 /* If there's no free ACE, bail out */
131 if (!RtlFirstFreeAce(Acl
, (PACE
*)&Ace
)) return STATUS_INVALID_ACL
;
133 /* Calculate the size of the ACE and bail out if it's too small */
134 AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
135 if (!(Ace
) || ((ULONG_PTR
)Ace
+ AceSize
> (ULONG_PTR
)Acl
+ Acl
->AclSize
))
137 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
140 /* Initialize the header and common fields */
141 Ace
->Header
.AceFlags
= (BYTE
)Flags
;
142 Ace
->Header
.AceType
= Type
;
143 Ace
->Header
.AceSize
= (WORD
)AceSize
;
144 Ace
->Mask
= AccessMask
;
147 RtlCopySid(RtlLengthSid(Sid
), &Ace
->SidStart
, Sid
);
149 /* Fill out the ACL header and return */
151 Acl
->AclRevision
= (BYTE
)Revision
;
152 return STATUS_SUCCESS
;
157 RtlpAddKnownObjectAce(IN PACL Acl
,
160 IN ACCESS_MASK AccessMask
,
161 IN GUID
*ObjectTypeGuid OPTIONAL
,
162 IN GUID
*InheritedObjectTypeGuid OPTIONAL
,
166 PKNOWN_OBJECT_ACE Ace
;
168 ULONG AceSize
, InvalidFlags
, AceObjectFlags
= 0;
171 /* Check the validity of the SID */
172 if (!RtlValidSid(Sid
)) return STATUS_INVALID_SID
;
174 /* Check the validity of the revision */
175 if ((Acl
->AclRevision
> ACL_REVISION4
) || (Revision
> ACL_REVISION4
))
177 return STATUS_REVISION_MISMATCH
;
180 /* Pick the smallest of the revisions */
181 if (Revision
< Acl
->AclRevision
) Revision
= Acl
->AclRevision
;
183 /* Validate the flags */
184 if ((Type
== SYSTEM_AUDIT_OBJECT_ACE_TYPE
) ||
185 (Type
== SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
))
187 InvalidFlags
= Flags
& ~(VALID_INHERIT_FLAGS
|
188 SUCCESSFUL_ACCESS_ACE_FLAG
| FAILED_ACCESS_ACE_FLAG
);
192 InvalidFlags
= Flags
& ~VALID_INHERIT_FLAGS
;
195 /* If flags are invalid, bail out */
196 if (InvalidFlags
!= 0) return STATUS_INVALID_PARAMETER
;
198 /* If ACL is invalid, bail out */
199 if (!RtlValidAcl(Acl
)) return STATUS_INVALID_ACL
;
201 /* If there's no free ACE, bail out */
202 if (!RtlFirstFreeAce(Acl
, (PACE
*)&Ace
)) return STATUS_INVALID_ACL
;
204 /* Calculate the size of the ACE */
205 AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
) + sizeof(ULONG
);
207 /* Add-in the size of the GUIDs if any and update flags as needed */
210 AceObjectFlags
|= ACE_OBJECT_TYPE_PRESENT
;
211 AceSize
+= sizeof(GUID
);
213 if (InheritedObjectTypeGuid
)
215 AceObjectFlags
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
216 AceSize
+= sizeof(GUID
);
219 /* Bail out if there's not enough space in the ACL */
220 if (!(Ace
) || ((ULONG_PTR
)Ace
+ AceSize
> (ULONG_PTR
)Acl
+ Acl
->AclSize
))
222 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
225 /* Initialize the header and common fields */
226 Ace
->Header
.AceFlags
= (BYTE
)Flags
;
227 Ace
->Header
.AceType
= Type
;
228 Ace
->Header
.AceSize
= (WORD
)AceSize
;
229 Ace
->Mask
= AccessMask
;
230 Ace
->Flags
= AceObjectFlags
;
233 SidStart
= (ULONG_PTR
)&Ace
->SidStart
;
236 RtlCopyMemory((PVOID
)SidStart
, ObjectTypeGuid
, sizeof(GUID
));
237 SidStart
+= sizeof(GUID
);
239 if (InheritedObjectTypeGuid
)
241 RtlCopyMemory((PVOID
)SidStart
, InheritedObjectTypeGuid
, sizeof(GUID
));
242 SidStart
+= sizeof(GUID
);
246 RtlCopySid(RtlLengthSid(Sid
), (PSID
)SidStart
, Sid
);
248 /* Fill out the ACL header and return */
250 Acl
->AclRevision
= (BYTE
)Revision
;
251 return STATUS_SUCCESS
;
254 /* PUBLIC FUNCTIONS ***********************************************************/
261 RtlAddAccessAllowedAce(IN OUT PACL Acl
,
263 IN ACCESS_MASK AccessMask
,
268 /* Call the worker function */
269 return RtlpAddKnownAce(Acl
,
274 ACCESS_ALLOWED_ACE_TYPE
);
282 RtlAddAccessAllowedAceEx(IN OUT PACL Acl
,
285 IN ACCESS_MASK AccessMask
,
290 /* Call the worker function */
291 return RtlpAddKnownAce(Acl
,
296 ACCESS_ALLOWED_ACE_TYPE
);
304 RtlAddAccessAllowedObjectAce(IN OUT PACL Acl
,
307 IN ACCESS_MASK AccessMask
,
308 IN GUID
*ObjectTypeGuid OPTIONAL
,
309 IN GUID
*InheritedObjectTypeGuid OPTIONAL
,
314 /* Is there no object data? */
315 if (!(ObjectTypeGuid
) && !(InheritedObjectTypeGuid
))
317 /* Use the usual routine */
318 return RtlpAddKnownAce(Acl
,
323 ACCESS_ALLOWED_ACE_TYPE
);
326 /* Use the object routine */
327 return RtlpAddKnownObjectAce(Acl
,
332 InheritedObjectTypeGuid
,
334 ACCESS_ALLOWED_OBJECT_ACE_TYPE
);
342 RtlAddAccessDeniedAce(IN PACL Acl
,
344 IN ACCESS_MASK AccessMask
,
349 /* Call the worker function */
350 return RtlpAddKnownAce(Acl
,
355 ACCESS_DENIED_ACE_TYPE
);
363 RtlAddAccessDeniedAceEx(IN OUT PACL Acl
,
366 IN ACCESS_MASK AccessMask
,
371 /* Call the worker function */
372 return RtlpAddKnownAce(Acl
,
377 ACCESS_DENIED_ACE_TYPE
);
385 RtlAddAccessDeniedObjectAce(IN OUT PACL Acl
,
388 IN ACCESS_MASK AccessMask
,
389 IN GUID
*ObjectTypeGuid OPTIONAL
,
390 IN GUID
*InheritedObjectTypeGuid OPTIONAL
,
395 /* Is there no object data? */
396 if (!(ObjectTypeGuid
) && !(InheritedObjectTypeGuid
))
398 /* Use the usual routine */
399 return RtlpAddKnownAce(Acl
,
404 ACCESS_DENIED_ACE_TYPE
);
407 /* There's object data, use the object routine */
408 return RtlpAddKnownObjectAce(Acl
,
413 InheritedObjectTypeGuid
,
415 ACCESS_DENIED_OBJECT_ACE_TYPE
);
423 RtlAddAuditAccessAce(IN PACL Acl
,
425 IN ACCESS_MASK AccessMask
,
434 if (Success
) Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
435 if (Failure
) Flags
|= FAILED_ACCESS_ACE_FLAG
;
437 /* Call the worker routine */
438 return RtlpAddKnownAce(Acl
,
443 SYSTEM_AUDIT_ACE_TYPE
);
451 RtlAddAuditAccessAceEx(IN PACL Acl
,
454 IN ACCESS_MASK AccessMask
,
462 if (Success
) Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
463 if (Failure
) Flags
|= FAILED_ACCESS_ACE_FLAG
;
465 /* Call the worker routine */
466 return RtlpAddKnownAce(Acl
,
471 SYSTEM_AUDIT_ACE_TYPE
);
479 RtlAddAuditAccessObjectAce(IN PACL Acl
,
482 IN ACCESS_MASK AccessMask
,
483 IN GUID
*ObjectTypeGuid OPTIONAL
,
484 IN GUID
*InheritedObjectTypeGuid OPTIONAL
,
490 if (Success
) Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
491 if (Failure
) Flags
|= FAILED_ACCESS_ACE_FLAG
;
493 /* Is there no object data? */
494 if (!(ObjectTypeGuid
) && !(InheritedObjectTypeGuid
))
496 /* Call the normal routine */
497 return RtlpAddKnownAce(Acl
,
502 SYSTEM_AUDIT_ACE_TYPE
);
505 /* There's object data, use the object routine */
506 return RtlpAddKnownObjectAce(Acl
,
511 InheritedObjectTypeGuid
,
513 SYSTEM_AUDIT_OBJECT_ACE_TYPE
);
521 RtlGetAce(IN PACL Acl
,
528 /* Bail out if the revision or the index are invalid */
529 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
530 (Acl
->AclRevision
> MAX_ACL_REVISION
) ||
531 (AceIndex
>= Acl
->AceCount
))
533 return STATUS_INVALID_PARAMETER
;
536 /* Loop through the ACEs */
537 *Ace
= (PVOID
)((PACE
)(Acl
+ 1));
538 for (i
= 0; i
< AceIndex
; i
++)
540 /* Bail out if an invalid ACE is ever found */
541 if ((ULONG_PTR
)*Ace
>= (ULONG_PTR
)Acl
+ Acl
->AclSize
)
543 return STATUS_INVALID_PARAMETER
;
547 *Ace
= (PVOID
)((PACE
)((ULONG_PTR
)(*Ace
) + ((PACE
)(*Ace
))->Header
.AceSize
));
550 /* Check if the last ACE is still valid */
551 if ((ULONG_PTR
)*Ace
>= (ULONG_PTR
)Acl
+ Acl
->AclSize
)
553 return STATUS_INVALID_PARAMETER
;
556 /* All good, return */
557 return STATUS_SUCCESS
;
565 RtlAddAce(IN PACL Acl
,
566 IN ULONG AclRevision
,
567 IN ULONG StartingIndex
,
569 IN ULONG AceListLength
)
576 /* Bail out if the ACL is invalid */
577 if (!RtlValidAcl(Acl
)) return STATUS_INVALID_PARAMETER
;
579 /* Bail out if there's no space */
580 if (!RtlFirstFreeAce(Acl
, &FreeAce
)) return STATUS_INVALID_PARAMETER
;
582 /* Loop over all the ACEs, keeping track of new ACEs as we go along */
583 for (Ace
= AceList
, NewAceCount
= 0;
584 Ace
< (PACE
)((ULONG_PTR
)AceList
+ AceListLength
);
587 /* Make sure that the revision of this ACE is valid in this list.
588 The initial check looks strange, but it is what Windows does. */
589 if (Ace
->Header
.AceType
<= ACCESS_MAX_MS_ACE_TYPE
)
591 if (Ace
->Header
.AceType
> ACCESS_MAX_MS_V3_ACE_TYPE
)
593 if (AclRevision
< ACL_REVISION4
) return STATUS_INVALID_PARAMETER
;
595 else if (Ace
->Header
.AceType
> ACCESS_MAX_MS_V2_ACE_TYPE
)
597 if (AclRevision
< ACL_REVISION3
) return STATUS_INVALID_PARAMETER
;
601 /* Move to the next ACE */
602 Ace
= (PACE
)((ULONG_PTR
)Ace
+ Ace
->Header
.AceSize
);
605 /* Bail out if there's no more space for us */
606 if ((ULONG_PTR
)Ace
> ((ULONG_PTR
)AceList
+ AceListLength
))
608 return STATUS_INVALID_PARAMETER
;
611 /* Bail out if there's no free ACE spot, or if we would overflow it */
613 ((ULONG_PTR
)FreeAce
+ AceListLength
> (ULONG_PTR
)Acl
+ Acl
->AclSize
))
615 return STATUS_BUFFER_TOO_SMALL
;
618 /* Go down the list until we find our index */
619 Ace
= (PACE
)(Acl
+ 1);
620 for (Index
= 0; (Index
< StartingIndex
) && (Index
< Acl
->AceCount
); Index
++)
622 Ace
= (PACE
)((ULONG_PTR
)Ace
+ Ace
->Header
.AceSize
);
625 /* Found where we want to do, add us to the list */
629 (ULONG_PTR
)FreeAce
- (ULONG_PTR
)Ace
);
631 /* Update the header and return */
632 Acl
->AceCount
+= NewAceCount
;
633 Acl
->AclRevision
= (UCHAR
)min(Acl
->AclRevision
, AclRevision
);
634 return STATUS_SUCCESS
;
642 RtlDeleteAce(IN PACL Acl
,
648 /* Bail out if the ACL is invalid */
649 if (!RtlValidAcl(Acl
)) return STATUS_INVALID_PARAMETER
;
651 /* Bail out if there's no space or if we're full */
652 if ((Acl
->AceCount
<= AceIndex
) || !(RtlFirstFreeAce(Acl
, &FreeAce
)))
654 return STATUS_INVALID_PARAMETER
;
657 /* Enumerate until the indexed ACE is reached */
658 Ace
= (PACE
)(Acl
+ 1);
659 while (AceIndex
--) Ace
= (PACE
)((ULONG_PTR
)Ace
+ Ace
->Header
.AceSize
);
661 /* Delete this ACE */
664 (ULONG
)((ULONG_PTR
)FreeAce
- (ULONG_PTR
)Ace
));
666 /* Decrease an ACE and return success */
668 return STATUS_SUCCESS
;
676 RtlCreateAcl(IN PACL Acl
,
678 IN ULONG AclRevision
)
682 /* Bail out if too small */
683 if (AclSize
< sizeof(ACL
)) return STATUS_BUFFER_TOO_SMALL
;
685 /* Bail out if too large or invalid revision */
686 if ((AclRevision
< MIN_ACL_REVISION
) ||
687 (AclRevision
> MAX_ACL_REVISION
) ||
688 (AclSize
> MAXUSHORT
))
690 return STATUS_INVALID_PARAMETER
;
693 /* Setup the header */
694 Acl
->AclSize
= (USHORT
)ROUND_UP(AclSize
, 4);
695 Acl
->AclRevision
= (UCHAR
)AclRevision
;
699 return STATUS_SUCCESS
;
707 RtlQueryInformationAcl(IN PACL Acl
,
708 IN PVOID Information
,
709 IN ULONG InformationLength
,
710 IN ACL_INFORMATION_CLASS InformationClass
)
713 PACL_REVISION_INFORMATION RevisionInfo
;
714 PACL_SIZE_INFORMATION SizeInfo
;
717 /* Validate the ACL revision */
718 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
719 (Acl
->AclRevision
> MAX_ACL_REVISION
))
721 return STATUS_INVALID_PARAMETER
;
724 /* Check what the caller is querying */
725 switch (InformationClass
)
728 case AclRevisionInformation
:
730 /* Bail out if the buffer is too small */
731 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
733 return STATUS_BUFFER_TOO_SMALL
;
736 /* Return the current revision */
737 RevisionInfo
= (PACL_REVISION_INFORMATION
)Information
;
738 RevisionInfo
->AclRevision
= Acl
->AclRevision
;
742 case AclSizeInformation
:
744 /* Bail out if the buffer is too small */
745 if (InformationLength
< sizeof(ACL_SIZE_INFORMATION
))
747 return STATUS_BUFFER_TOO_SMALL
;
750 /* Bail out if there's no space in the ACL */
751 if (!RtlFirstFreeAce(Acl
, &Ace
)) return STATUS_INVALID_PARAMETER
;
753 /* Read the number of ACEs and check if there was a free ACE */
754 SizeInfo
= (PACL_SIZE_INFORMATION
)Information
;
755 SizeInfo
->AceCount
= Acl
->AceCount
;
758 /* Return how much space there is in the ACL */
759 SizeInfo
->AclBytesInUse
= (ULONG_PTR
)Ace
- (ULONG_PTR
)Acl
;
760 SizeInfo
->AclBytesFree
= Acl
->AclSize
- SizeInfo
->AclBytesInUse
;
764 /* No free ACE, means the whole ACL is full */
765 SizeInfo
->AclBytesInUse
= Acl
->AclSize
;
766 SizeInfo
->AclBytesFree
= 0;
771 /* Anything else is illegal */
772 return STATUS_INVALID_INFO_CLASS
;
776 return STATUS_SUCCESS
;
784 RtlSetInformationAcl(IN PACL Acl
,
785 IN PVOID Information
,
786 IN ULONG InformationLength
,
787 IN ACL_INFORMATION_CLASS InformationClass
)
789 PACL_REVISION_INFORMATION Info
;
792 /* Validate the ACL revision */
793 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
794 (Acl
->AclRevision
> MAX_ACL_REVISION
))
796 return STATUS_INVALID_PARAMETER
;
799 /* What is the caller trying to set? */
800 switch (InformationClass
)
802 /* This is the only info class */
803 case AclRevisionInformation
:
805 /* Make sure the buffer is large enough */
806 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
808 return STATUS_BUFFER_TOO_SMALL
;
811 /* Make sure the new revision is within the acceptable bounds*/
812 Info
= (PACL_REVISION_INFORMATION
)Information
;
813 if (Acl
->AclRevision
>= Info
->AclRevision
)
815 return STATUS_INVALID_PARAMETER
;
818 /* Set the new revision */
819 Acl
->AclRevision
= (BYTE
)Info
->AclRevision
;
823 /* Anything else is invalid */
824 return STATUS_INVALID_INFO_CLASS
;
828 return STATUS_SUCCESS
;
836 RtlValidAcl(IN PACL Acl
)
845 /* First, validate the revision */
846 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
847 (Acl
->AclRevision
> MAX_ACL_REVISION
))
849 DPRINT1("Invalid ACL revision\n");
850 _SEH2_YIELD(return FALSE
);
853 /* Next, validate that the ACL is USHORT-aligned */
854 if (ROUND_DOWN(Acl
->AclSize
, sizeof(USHORT
)) != Acl
->AclSize
)
856 DPRINT1("Invalid ACL size\n");
857 _SEH2_YIELD(return FALSE
);
860 /* And that it's big enough */
861 if (Acl
->AclSize
< sizeof(ACL
))
863 DPRINT1("Invalid ACL size\n");
864 _SEH2_YIELD(return FALSE
);
868 Ace
= (PACE_HEADER
)((ULONG_PTR
)Acl
+ sizeof(ACL
));
869 for (i
= 0; i
< Acl
->AceCount
; i
++)
871 /* Validate we have space for this ACE header */
872 if (((ULONG_PTR
)Ace
+ sizeof(ACE_HEADER
)) >= ((ULONG_PTR
)Acl
+ Acl
->AclSize
))
874 DPRINT1("Invalid ACE size\n");
875 _SEH2_YIELD(return FALSE
);
878 /* Validate the length of this ACE */
879 if (ROUND_DOWN(Ace
->AceSize
, sizeof(USHORT
)) != Ace
->AceSize
)
881 DPRINT1("Invalid ACE size: %lx\n", Ace
->AceSize
);
882 _SEH2_YIELD(return FALSE
);
885 /* Validate we have space for the entire ACE */
886 if (((ULONG_PTR
)Ace
+ Ace
->AceSize
) > ((ULONG_PTR
)Acl
+ Acl
->AclSize
))
888 DPRINT1("Invalid ACE size %lx %lx\n", Ace
->AceSize
, Acl
->AclSize
);
889 _SEH2_YIELD(return FALSE
);
892 /* Check what kind of ACE this is */
893 if (Ace
->AceType
<= ACCESS_MAX_MS_V2_ACE_TYPE
)
895 /* Validate the length of this ACE */
896 if (ROUND_DOWN(Ace
->AceSize
, sizeof(ULONG
)) != Ace
->AceSize
)
898 DPRINT1("Invalid ACE size\n");
899 _SEH2_YIELD(return FALSE
);
902 /* The ACE size should at least have enough for the header */
903 if (Ace
->AceSize
< sizeof(ACE_HEADER
))
905 DPRINT1("Invalid ACE size: %lx %lx\n", Ace
->AceSize
, sizeof(ACE_HEADER
));
906 _SEH2_YIELD(return FALSE
);
909 /* Check if the SID revision is valid */
910 Sid
= (PISID
)&((PKNOWN_ACE
)Ace
)->SidStart
;
911 if (Sid
->Revision
!= SID_REVISION
)
913 DPRINT1("Invalid SID\n");
914 _SEH2_YIELD(return FALSE
);
917 /* Check if the SID is out of bounds */
918 if (Sid
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
920 DPRINT1("Invalid SID\n");
921 _SEH2_YIELD(return FALSE
);
924 /* The ACE size should at least have enough for the header and SID */
925 if (Ace
->AceSize
< (sizeof(ACE_HEADER
) + RtlLengthSid(Sid
)))
927 DPRINT1("Invalid ACE size\n");
928 _SEH2_YIELD(return FALSE
);
931 else if (Ace
->AceType
== ACCESS_ALLOWED_COMPOUND_ACE_TYPE
)
933 DPRINT1("Unsupported ACE in ReactOS, assuming valid\n");
935 else if ((Ace
->AceType
>= ACCESS_MIN_MS_OBJECT_ACE_TYPE
) &&
936 (Ace
->AceType
<= ACCESS_MAX_MS_OBJECT_ACE_TYPE
))
938 DPRINT1("Unsupported ACE in ReactOS, assuming valid\n");
942 /* Unknown ACE, see if it's as big as a header at least */
943 if (Ace
->AceSize
< sizeof(ACE_HEADER
))
945 DPRINT1("Unknown ACE\n");
946 _SEH2_YIELD(return FALSE
);
950 /* Move to the next ace */
951 Ace
= (PACE_HEADER
)((ULONG_PTR
)Ace
+ Ace
->AceSize
);
954 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
956 /* Something was invalid, fail */
957 _SEH2_YIELD(return FALSE
);
961 /* The ACL looks ok */