2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * PURPOSE: Security manager
6 * PROGRAMER: David Welch <welch@cwcom.net>
9 /* INCLUDES *****************************************************************/
12 #include <../../ntoskrnl/include/internal/se.h>
16 /* PRIVATE FUNCTIONS **********************************************************/
20 RtlFirstFreeAce(IN PACL Acl
,
21 OUT PACE
* FirstFreeAce
)
31 /* Get the start and end pointers */
32 Current
= (PACE
)(Acl
+ 1);
33 AclEnd
= (ULONG_PTR
)Acl
+ Acl
->AclSize
;
35 /* Loop all the ACEs */
36 for (i
= 0; i
< Acl
->AceCount
; i
++)
38 /* If any is beyond the DACL, bail out, otherwise keep going */
39 if ((ULONG_PTR
)Current
>= AclEnd
) return FALSE
;
40 Current
= (PACE
)((ULONG_PTR
)Current
+ Current
->Header
.AceSize
);
43 /* If the last spot is empty and still valid, return it */
44 if ((ULONG_PTR
)Current
<= AclEnd
) *FirstFreeAce
= Current
;
50 RtlpAddData(IN PVOID AceList
,
51 IN ULONG AceListLength
,
55 /* Shift the buffer down */
58 RtlCopyMemory((PVOID
)((ULONG_PTR
)Ace
+ AceListLength
),
63 /* Copy the new data in */
64 if (AceListLength
) RtlCopyMemory(Ace
, AceList
, AceListLength
);
69 RtlpDeleteData(IN PVOID Ace
,
73 /* Move the data up */
77 (PVOID
)((ULONG_PTR
)Ace
+ AceSize
),
82 if ((Offset
- AceSize
) < Offset
)
84 RtlZeroMemory((PVOID
)((ULONG_PTR
)Ace
+ Offset
- AceSize
), AceSize
);
90 RtlpAddKnownAce(IN PACL Acl
,
93 IN ACCESS_MASK AccessMask
,
98 ULONG AceSize
, InvalidFlags
;
101 /* Check the validity of the SID */
102 if (!RtlValidSid(Sid
)) return STATUS_INVALID_SID
;
104 /* Check the validity of the revision */
105 if ((Acl
->AclRevision
> ACL_REVISION4
) || (Revision
> ACL_REVISION4
))
107 return STATUS_REVISION_MISMATCH
;
110 /* Pick the smallest of the revisions */
111 if (Revision
< Acl
->AclRevision
) Revision
= Acl
->AclRevision
;
113 /* Validate the flags */
114 if (Type
== SYSTEM_AUDIT_ACE_TYPE
)
116 InvalidFlags
= Flags
& ~(VALID_INHERIT_FLAGS
|
117 SUCCESSFUL_ACCESS_ACE_FLAG
|
118 FAILED_ACCESS_ACE_FLAG
);
122 InvalidFlags
= Flags
& ~VALID_INHERIT_FLAGS
;
125 /* If flags are invalid, bail out */
126 if (InvalidFlags
!= 0) return STATUS_INVALID_PARAMETER
;
128 /* If ACL is invalid, bail out */
129 if (!RtlValidAcl(Acl
)) return STATUS_INVALID_ACL
;
131 /* If there's no free ACE, bail out */
132 if (!RtlFirstFreeAce(Acl
, (PACE
*)&Ace
)) return STATUS_INVALID_ACL
;
134 /* Calculate the size of the ACE and bail out if it's too small */
135 AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
);
136 if (!(Ace
) || ((ULONG_PTR
)Ace
+ AceSize
> (ULONG_PTR
)Acl
+ Acl
->AclSize
))
138 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
141 /* Initialize the header and common fields */
142 Ace
->Header
.AceFlags
= (BYTE
)Flags
;
143 Ace
->Header
.AceType
= Type
;
144 Ace
->Header
.AceSize
= (WORD
)AceSize
;
145 Ace
->Mask
= AccessMask
;
148 RtlCopySid(RtlLengthSid(Sid
), &Ace
->SidStart
, Sid
);
150 /* Fill out the ACL header and return */
152 Acl
->AclRevision
= (BYTE
)Revision
;
153 return STATUS_SUCCESS
;
158 RtlpAddKnownObjectAce(IN PACL Acl
,
161 IN ACCESS_MASK AccessMask
,
162 IN GUID
*ObjectTypeGuid OPTIONAL
,
163 IN GUID
*InheritedObjectTypeGuid OPTIONAL
,
167 PKNOWN_OBJECT_ACE Ace
;
169 ULONG AceSize
, InvalidFlags
, AceObjectFlags
= 0;
172 /* Check the validity of the SID */
173 if (!RtlValidSid(Sid
)) return STATUS_INVALID_SID
;
175 /* Check the validity of the revision */
176 if ((Acl
->AclRevision
> ACL_REVISION4
) || (Revision
> ACL_REVISION4
))
178 return STATUS_REVISION_MISMATCH
;
181 /* Pick the smallest of the revisions */
182 if (Revision
< Acl
->AclRevision
) Revision
= Acl
->AclRevision
;
184 /* Validate the flags */
185 if ((Type
== SYSTEM_AUDIT_OBJECT_ACE_TYPE
) ||
186 (Type
== SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
))
188 InvalidFlags
= Flags
& ~(VALID_INHERIT_FLAGS
|
189 SUCCESSFUL_ACCESS_ACE_FLAG
| FAILED_ACCESS_ACE_FLAG
);
193 InvalidFlags
= Flags
& ~VALID_INHERIT_FLAGS
;
196 /* If flags are invalid, bail out */
197 if (InvalidFlags
!= 0) return STATUS_INVALID_PARAMETER
;
199 /* If ACL is invalid, bail out */
200 if (!RtlValidAcl(Acl
)) return STATUS_INVALID_ACL
;
202 /* If there's no free ACE, bail out */
203 if (!RtlFirstFreeAce(Acl
, (PACE
*)&Ace
)) return STATUS_INVALID_ACL
;
205 /* Calculate the size of the ACE */
206 AceSize
= RtlLengthSid(Sid
) + sizeof(ACE
) + sizeof(ULONG
);
208 /* Add-in the size of the GUIDs if any and update flags as needed */
211 AceObjectFlags
|= ACE_OBJECT_TYPE_PRESENT
;
212 AceSize
+= sizeof(GUID
);
214 if (InheritedObjectTypeGuid
)
216 AceObjectFlags
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
217 AceSize
+= sizeof(GUID
);
220 /* Bail out if there's not enough space in the ACL */
221 if (!(Ace
) || ((ULONG_PTR
)Ace
+ AceSize
> (ULONG_PTR
)Acl
+ Acl
->AclSize
))
223 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
226 /* Initialize the header and common fields */
227 Ace
->Header
.AceFlags
= (BYTE
)Flags
;
228 Ace
->Header
.AceType
= Type
;
229 Ace
->Header
.AceSize
= (WORD
)AceSize
;
230 Ace
->Mask
= AccessMask
;
231 Ace
->Flags
= AceObjectFlags
;
234 SidStart
= (ULONG_PTR
)&Ace
->SidStart
;
237 RtlCopyMemory((PVOID
)SidStart
, ObjectTypeGuid
, sizeof(GUID
));
238 SidStart
+= sizeof(GUID
);
240 if (InheritedObjectTypeGuid
)
242 RtlCopyMemory((PVOID
)SidStart
, InheritedObjectTypeGuid
, sizeof(GUID
));
243 SidStart
+= sizeof(GUID
);
247 RtlCopySid(RtlLengthSid(Sid
), (PSID
)SidStart
, Sid
);
249 /* Fill out the ACL header and return */
251 Acl
->AclRevision
= (BYTE
)Revision
;
252 return STATUS_SUCCESS
;
255 /* PUBLIC FUNCTIONS ***********************************************************/
262 RtlAddAccessAllowedAce(IN OUT PACL Acl
,
264 IN ACCESS_MASK AccessMask
,
269 /* Call the worker function */
270 return RtlpAddKnownAce(Acl
,
275 ACCESS_ALLOWED_ACE_TYPE
);
283 RtlAddAccessAllowedAceEx(IN OUT PACL Acl
,
286 IN ACCESS_MASK AccessMask
,
291 /* Call the worker function */
292 return RtlpAddKnownAce(Acl
,
297 ACCESS_ALLOWED_ACE_TYPE
);
305 RtlAddAccessAllowedObjectAce(IN OUT PACL Acl
,
308 IN ACCESS_MASK AccessMask
,
309 IN GUID
*ObjectTypeGuid OPTIONAL
,
310 IN GUID
*InheritedObjectTypeGuid OPTIONAL
,
315 /* Is there no object data? */
316 if (!(ObjectTypeGuid
) && !(InheritedObjectTypeGuid
))
318 /* Use the usual routine */
319 return RtlpAddKnownAce(Acl
,
324 ACCESS_ALLOWED_ACE_TYPE
);
327 /* Use the object routine */
328 return RtlpAddKnownObjectAce(Acl
,
333 InheritedObjectTypeGuid
,
335 ACCESS_ALLOWED_OBJECT_ACE_TYPE
);
343 RtlAddAccessDeniedAce(IN PACL Acl
,
345 IN ACCESS_MASK AccessMask
,
350 /* Call the worker function */
351 return RtlpAddKnownAce(Acl
,
356 ACCESS_DENIED_ACE_TYPE
);
364 RtlAddAccessDeniedAceEx(IN OUT PACL Acl
,
367 IN ACCESS_MASK AccessMask
,
372 /* Call the worker function */
373 return RtlpAddKnownAce(Acl
,
378 ACCESS_DENIED_ACE_TYPE
);
386 RtlAddAccessDeniedObjectAce(IN OUT PACL Acl
,
389 IN ACCESS_MASK AccessMask
,
390 IN GUID
*ObjectTypeGuid OPTIONAL
,
391 IN GUID
*InheritedObjectTypeGuid OPTIONAL
,
396 /* Is there no object data? */
397 if (!(ObjectTypeGuid
) && !(InheritedObjectTypeGuid
))
399 /* Use the usual routine */
400 return RtlpAddKnownAce(Acl
,
405 ACCESS_DENIED_ACE_TYPE
);
408 /* There's object data, use the object routine */
409 return RtlpAddKnownObjectAce(Acl
,
414 InheritedObjectTypeGuid
,
416 ACCESS_DENIED_OBJECT_ACE_TYPE
);
424 RtlAddAuditAccessAce(IN PACL Acl
,
426 IN ACCESS_MASK AccessMask
,
435 if (Success
) Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
436 if (Failure
) Flags
|= FAILED_ACCESS_ACE_FLAG
;
438 /* Call the worker routine */
439 return RtlpAddKnownAce(Acl
,
444 SYSTEM_AUDIT_ACE_TYPE
);
452 RtlAddAuditAccessAceEx(IN PACL Acl
,
455 IN ACCESS_MASK AccessMask
,
463 if (Success
) Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
464 if (Failure
) Flags
|= FAILED_ACCESS_ACE_FLAG
;
466 /* Call the worker routine */
467 return RtlpAddKnownAce(Acl
,
472 SYSTEM_AUDIT_ACE_TYPE
);
480 RtlAddAuditAccessObjectAce(IN PACL Acl
,
483 IN ACCESS_MASK AccessMask
,
484 IN GUID
*ObjectTypeGuid OPTIONAL
,
485 IN GUID
*InheritedObjectTypeGuid OPTIONAL
,
491 if (Success
) Flags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
492 if (Failure
) Flags
|= FAILED_ACCESS_ACE_FLAG
;
494 /* Is there no object data? */
495 if (!(ObjectTypeGuid
) && !(InheritedObjectTypeGuid
))
497 /* Call the normal routine */
498 return RtlpAddKnownAce(Acl
,
503 SYSTEM_AUDIT_ACE_TYPE
);
506 /* There's object data, use the object routine */
507 return RtlpAddKnownObjectAce(Acl
,
512 InheritedObjectTypeGuid
,
514 SYSTEM_AUDIT_OBJECT_ACE_TYPE
);
522 RtlGetAce(IN PACL Acl
,
529 /* Bail out if the revision or the index are invalid */
530 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
531 (Acl
->AclRevision
> MAX_ACL_REVISION
) ||
532 (AceIndex
>= Acl
->AceCount
))
534 return STATUS_INVALID_PARAMETER
;
537 /* Loop through the ACEs */
538 *Ace
= (PVOID
)((PACE
)(Acl
+ 1));
539 for (i
= 0; i
< AceIndex
; i
++)
541 /* Bail out if an invalid ACE is ever found */
542 if ((ULONG_PTR
)*Ace
>= (ULONG_PTR
)Acl
+ Acl
->AclSize
)
544 return STATUS_INVALID_PARAMETER
;
548 *Ace
= (PVOID
)((PACE
)((ULONG_PTR
)(*Ace
) + ((PACE
)(*Ace
))->Header
.AceSize
));
551 /* Check if the last ACE is still valid */
552 if ((ULONG_PTR
)*Ace
>= (ULONG_PTR
)Acl
+ Acl
->AclSize
)
554 return STATUS_INVALID_PARAMETER
;
557 /* All good, return */
558 return STATUS_SUCCESS
;
566 RtlAddAce(IN PACL Acl
,
567 IN ULONG AclRevision
,
568 IN ULONG StartingIndex
,
570 IN ULONG AceListLength
)
577 /* Bail out if the ACL is invalid */
578 if (!RtlValidAcl(Acl
)) return STATUS_INVALID_PARAMETER
;
580 /* Bail out if there's no space */
581 if (!RtlFirstFreeAce(Acl
, &FreeAce
)) return STATUS_INVALID_PARAMETER
;
583 /* Loop over all the ACEs, keeping track of new ACEs as we go along */
584 for (Ace
= AceList
, NewAceCount
= 0;
585 Ace
< (PACE
)((ULONG_PTR
)AceList
+ AceListLength
);
588 /* Make sure that the revision of this ACE is valid in this list.
589 The initial check looks strange, but it is what Windows does. */
590 if (Ace
->Header
.AceType
<= ACCESS_MAX_MS_ACE_TYPE
)
592 if (Ace
->Header
.AceType
> ACCESS_MAX_MS_V3_ACE_TYPE
)
594 if (AclRevision
< ACL_REVISION4
) return STATUS_INVALID_PARAMETER
;
596 else if (Ace
->Header
.AceType
> ACCESS_MAX_MS_V2_ACE_TYPE
)
598 if (AclRevision
< ACL_REVISION3
) return STATUS_INVALID_PARAMETER
;
602 /* Move to the next ACE */
603 Ace
= (PACE
)((ULONG_PTR
)Ace
+ Ace
->Header
.AceSize
);
606 /* Bail out if there's no more space for us */
607 if ((ULONG_PTR
)Ace
> ((ULONG_PTR
)AceList
+ AceListLength
))
609 return STATUS_INVALID_PARAMETER
;
612 /* Bail out if there's no free ACE spot, or if we would overflow it */
614 ((ULONG_PTR
)FreeAce
+ AceListLength
> (ULONG_PTR
)Acl
+ Acl
->AclSize
))
616 return STATUS_BUFFER_TOO_SMALL
;
619 /* Go down the list until we find our index */
620 Ace
= (PACE
)(Acl
+ 1);
621 for (Index
= 0; (Index
< StartingIndex
) && (Index
< Acl
->AceCount
); Index
++)
623 Ace
= (PACE
)((ULONG_PTR
)Ace
+ Ace
->Header
.AceSize
);
626 /* Found where we want to do, add us to the list */
630 (ULONG_PTR
)FreeAce
- (ULONG_PTR
)Ace
);
632 /* Update the header and return */
633 Acl
->AceCount
+= NewAceCount
;
634 Acl
->AclRevision
= (UCHAR
)min(Acl
->AclRevision
, AclRevision
);
635 return STATUS_SUCCESS
;
643 RtlDeleteAce(IN PACL Acl
,
649 /* Bail out if the ACL is invalid */
650 if (!RtlValidAcl(Acl
)) return STATUS_INVALID_PARAMETER
;
652 /* Bail out if there's no space or if we're full */
653 if ((Acl
->AceCount
<= AceIndex
) || !(RtlFirstFreeAce(Acl
, &FreeAce
)))
655 return STATUS_INVALID_PARAMETER
;
658 /* Enumerate until the indexed ACE is reached */
659 Ace
= (PACE
)(Acl
+ 1);
660 while (AceIndex
--) Ace
= (PACE
)((ULONG_PTR
)Ace
+ Ace
->Header
.AceSize
);
662 /* Delete this ACE */
665 (ULONG
)((ULONG_PTR
)FreeAce
- (ULONG_PTR
)Ace
));
667 /* Decrease an ACE and return success */
669 return STATUS_SUCCESS
;
677 RtlCreateAcl(IN PACL Acl
,
679 IN ULONG AclRevision
)
683 /* Bail out if too small */
684 if (AclSize
< sizeof(ACL
)) return STATUS_BUFFER_TOO_SMALL
;
686 /* Bail out if too large or invalid revision */
687 if ((AclRevision
< MIN_ACL_REVISION
) ||
688 (AclRevision
> MAX_ACL_REVISION
) ||
689 (AclSize
> MAXUSHORT
))
691 return STATUS_INVALID_PARAMETER
;
694 /* Setup the header */
695 Acl
->AclSize
= (USHORT
)ROUND_UP(AclSize
, 4);
696 Acl
->AclRevision
= (UCHAR
)AclRevision
;
700 return STATUS_SUCCESS
;
708 RtlQueryInformationAcl(IN PACL Acl
,
709 IN PVOID Information
,
710 IN ULONG InformationLength
,
711 IN ACL_INFORMATION_CLASS InformationClass
)
714 PACL_REVISION_INFORMATION RevisionInfo
;
715 PACL_SIZE_INFORMATION SizeInfo
;
718 /* Validate the ACL revision */
719 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
720 (Acl
->AclRevision
> MAX_ACL_REVISION
))
722 return STATUS_INVALID_PARAMETER
;
725 /* Check what the caller is querying */
726 switch (InformationClass
)
729 case AclRevisionInformation
:
731 /* Bail out if the buffer is too small */
732 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
734 return STATUS_BUFFER_TOO_SMALL
;
737 /* Return the current revision */
738 RevisionInfo
= (PACL_REVISION_INFORMATION
)Information
;
739 RevisionInfo
->AclRevision
= Acl
->AclRevision
;
743 case AclSizeInformation
:
745 /* Bail out if the buffer is too small */
746 if (InformationLength
< sizeof(ACL_SIZE_INFORMATION
))
748 return STATUS_BUFFER_TOO_SMALL
;
751 /* Bail out if there's no space in the ACL */
752 if (!RtlFirstFreeAce(Acl
, &Ace
)) return STATUS_INVALID_PARAMETER
;
754 /* Read the number of ACEs and check if there was a free ACE */
755 SizeInfo
= (PACL_SIZE_INFORMATION
)Information
;
756 SizeInfo
->AceCount
= Acl
->AceCount
;
759 /* Return how much space there is in the ACL */
760 SizeInfo
->AclBytesInUse
= (ULONG_PTR
)Ace
- (ULONG_PTR
)Acl
;
761 SizeInfo
->AclBytesFree
= Acl
->AclSize
- SizeInfo
->AclBytesInUse
;
765 /* No free ACE, means the whole ACL is full */
766 SizeInfo
->AclBytesInUse
= Acl
->AclSize
;
767 SizeInfo
->AclBytesFree
= 0;
772 /* Anything else is illegal */
773 return STATUS_INVALID_INFO_CLASS
;
777 return STATUS_SUCCESS
;
785 RtlSetInformationAcl(IN PACL Acl
,
786 IN PVOID Information
,
787 IN ULONG InformationLength
,
788 IN ACL_INFORMATION_CLASS InformationClass
)
790 PACL_REVISION_INFORMATION Info
;
793 /* Validate the ACL revision */
794 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
795 (Acl
->AclRevision
> MAX_ACL_REVISION
))
797 return STATUS_INVALID_PARAMETER
;
800 /* What is the caller trying to set? */
801 switch (InformationClass
)
803 /* This is the only info class */
804 case AclRevisionInformation
:
806 /* Make sure the buffer is large enough */
807 if (InformationLength
< sizeof(ACL_REVISION_INFORMATION
))
809 return STATUS_BUFFER_TOO_SMALL
;
812 /* Make sure the new revision is within the acceptable bounds*/
813 Info
= (PACL_REVISION_INFORMATION
)Information
;
814 if (Acl
->AclRevision
>= Info
->AclRevision
)
816 return STATUS_INVALID_PARAMETER
;
819 /* Set the new revision */
820 Acl
->AclRevision
= (BYTE
)Info
->AclRevision
;
824 /* Anything else is invalid */
825 return STATUS_INVALID_INFO_CLASS
;
829 return STATUS_SUCCESS
;
837 RtlValidAcl(IN PACL Acl
)
846 /* First, validate the revision */
847 if ((Acl
->AclRevision
< MIN_ACL_REVISION
) ||
848 (Acl
->AclRevision
> MAX_ACL_REVISION
))
850 DPRINT1("Invalid ACL revision\n");
851 _SEH2_YIELD(return FALSE
);
854 /* Next, validate that the ACL is USHORT-aligned */
855 if (ROUND_DOWN(Acl
->AclSize
, sizeof(USHORT
)) != Acl
->AclSize
)
857 DPRINT1("Invalid ACL size\n");
858 _SEH2_YIELD(return FALSE
);
861 /* And that it's big enough */
862 if (Acl
->AclSize
< sizeof(ACL
))
864 DPRINT1("Invalid ACL size\n");
865 _SEH2_YIELD(return FALSE
);
869 Ace
= (PACE_HEADER
)((ULONG_PTR
)Acl
+ sizeof(ACL
));
870 for (i
= 0; i
< Acl
->AceCount
; i
++)
872 /* Validate we have space for this ACE header */
873 if (((ULONG_PTR
)Ace
+ sizeof(ACE_HEADER
)) >= ((ULONG_PTR
)Acl
+ Acl
->AclSize
))
875 DPRINT1("Invalid ACE size\n");
876 _SEH2_YIELD(return FALSE
);
879 /* Validate the length of this ACE */
880 if (ROUND_DOWN(Ace
->AceSize
, sizeof(USHORT
)) != Ace
->AceSize
)
882 DPRINT1("Invalid ACE size: %lx\n", Ace
->AceSize
);
883 _SEH2_YIELD(return FALSE
);
886 /* Validate we have space for the entire ACE */
887 if (((ULONG_PTR
)Ace
+ Ace
->AceSize
) > ((ULONG_PTR
)Acl
+ Acl
->AclSize
))
889 DPRINT1("Invalid ACE size %lx %lx\n", Ace
->AceSize
, Acl
->AclSize
);
890 _SEH2_YIELD(return FALSE
);
893 /* Check what kind of ACE this is */
894 if (Ace
->AceType
<= ACCESS_MAX_MS_V2_ACE_TYPE
)
896 /* Validate the length of this ACE */
897 if (ROUND_DOWN(Ace
->AceSize
, sizeof(ULONG
)) != Ace
->AceSize
)
899 DPRINT1("Invalid ACE size\n");
900 _SEH2_YIELD(return FALSE
);
903 /* The ACE size should at least have enough for the header */
904 if (Ace
->AceSize
< sizeof(ACE_HEADER
))
906 DPRINT1("Invalid ACE size: %lx %lx\n", Ace
->AceSize
, sizeof(ACE_HEADER
));
907 _SEH2_YIELD(return FALSE
);
910 /* Check if the SID revision is valid */
911 Sid
= (PISID
)&((PKNOWN_ACE
)Ace
)->SidStart
;
912 if (Sid
->Revision
!= SID_REVISION
)
914 DPRINT1("Invalid SID\n");
915 _SEH2_YIELD(return FALSE
);
918 /* Check if the SID is out of bounds */
919 if (Sid
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
921 DPRINT1("Invalid SID\n");
922 _SEH2_YIELD(return FALSE
);
925 /* The ACE size should at least have enough for the header and SID */
926 if (Ace
->AceSize
< (sizeof(ACE_HEADER
) + RtlLengthSid(Sid
)))
928 DPRINT1("Invalid ACE size\n");
929 _SEH2_YIELD(return FALSE
);
932 else if (Ace
->AceType
== ACCESS_ALLOWED_COMPOUND_ACE_TYPE
)
934 DPRINT1("Unsupported ACE in ReactOS, assuming valid\n");
936 else if ((Ace
->AceType
>= ACCESS_MIN_MS_OBJECT_ACE_TYPE
) &&
937 (Ace
->AceType
<= ACCESS_MAX_MS_OBJECT_ACE_TYPE
))
939 DPRINT1("Unsupported ACE in ReactOS, assuming valid\n");
943 /* Unknown ACE, see if it's as big as a header at least */
944 if (Ace
->AceSize
< sizeof(ACE_HEADER
))
946 DPRINT1("Unknown ACE\n");
947 _SEH2_YIELD(return FALSE
);
951 /* Move to the next ace */
952 Ace
= (PACE_HEADER
)((ULONG_PTR
)Ace
+ Ace
->AceSize
);
955 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
957 /* Something was invalid, fail */
958 _SEH2_YIELD(return FALSE
);
962 /* The ACL looks ok */