ReactOS 0.4.15-dev-7788-g1ad9096
acl.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * PURPOSE: Security manager
5 * FILE: lib/rtl/acl.c
6 * PROGRAMER: David Welch <welch@cwcom.net>
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include <rtl.h>
12#include <../../ntoskrnl/include/internal/se.h>
13#define NDEBUG
14#include <debug.h>
15
16/* PRIVATE FUNCTIONS **********************************************************/
17
21 OUT PACE* FirstFreeAce)
22{
23 PACE Current;
24 ULONG_PTR AclEnd;
25 ULONG i;
27
28 /* Assume failure */
29 *FirstFreeAce = NULL;
30
31 /* Get the start and end pointers */
32 Current = (PACE)(Acl + 1);
33 AclEnd = (ULONG_PTR)Acl + Acl->AclSize;
34
35 /* Loop all the ACEs */
36 for (i = 0; i < Acl->AceCount; i++)
37 {
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);
41 }
42
43 /* If the last spot is empty and still valid, return it */
44 if ((ULONG_PTR)Current <= AclEnd) *FirstFreeAce = Current;
45 return TRUE;
46}
47
48VOID
52 IN PVOID Ace,
54{
55 /* Shift the buffer down */
56 if (Offset > 0)
57 {
59 Ace,
60 Offset);
61 }
62
63 /* Copy the new data in */
65}
66
67VOID
70 IN ULONG AceSize,
72{
73 /* Move the data up */
74 if (AceSize < Offset)
75 {
77 (PVOID)((ULONG_PTR)Ace + AceSize),
78 Offset - AceSize);
79 }
80
81 /* Zero the rest */
82 if ((Offset - AceSize) < Offset)
83 {
84 RtlZeroMemory((PVOID)((ULONG_PTR)Ace + Offset - AceSize), AceSize);
85 }
86}
87
94 IN PSID Sid,
96{
98 ULONG AceSize, InvalidFlags;
100
101 /* Check the validity of the SID */
102 if (!RtlValidSid(Sid)) return STATUS_INVALID_SID;
103
104 /* Check the validity of the revision */
105 if ((Acl->AclRevision > ACL_REVISION4) || (Revision > ACL_REVISION4))
106 {
108 }
109
110 /* Pick the smallest of the revisions */
111 if (Revision < Acl->AclRevision) Revision = Acl->AclRevision;
112
113 /* Validate the flags */
115 {
116 InvalidFlags = Flags & ~(VALID_INHERIT_FLAGS |
119 }
120 else
121 {
122 InvalidFlags = Flags & ~VALID_INHERIT_FLAGS;
123 }
124
125 /* If flags are invalid, bail out */
126 if (InvalidFlags != 0) return STATUS_INVALID_PARAMETER;
127
128 /* If ACL is invalid, bail out */
129 if (!RtlValidAcl(Acl)) return STATUS_INVALID_ACL;
130
131 /* If there's no free ACE, bail out */
132 if (!RtlFirstFreeAce(Acl, (PACE*)&Ace)) return STATUS_INVALID_ACL;
133
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))
137 {
139 }
140
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;
146
147 /* Copy the SID */
148 RtlCopySid(RtlLengthSid(Sid), &Ace->SidStart, Sid);
149
150 /* Fill out the ACL header and return */
151 Acl->AceCount++;
152 Acl->AclRevision = (BYTE)Revision;
153 return STATUS_SUCCESS;
154}
155
157NTAPI
160 IN ULONG Flags,
162 IN GUID *ObjectTypeGuid OPTIONAL,
163 IN GUID *InheritedObjectTypeGuid OPTIONAL,
164 IN PSID Sid,
165 IN UCHAR Type)
166{
168 ULONG_PTR SidStart;
169 ULONG AceSize, InvalidFlags, AceObjectFlags = 0;
171
172 /* Check the validity of the SID */
173 if (!RtlValidSid(Sid)) return STATUS_INVALID_SID;
174
175 /* Check the validity of the revision */
176 if ((Acl->AclRevision > ACL_REVISION4) || (Revision != ACL_REVISION4))
177 {
179 }
180
181 /* Pick the smallest of the revisions */
182 if (Revision < Acl->AclRevision) Revision = Acl->AclRevision;
183
184 /* Validate the flags */
187 {
188 InvalidFlags = Flags & ~(VALID_INHERIT_FLAGS |
190 }
191 else
192 {
193 InvalidFlags = Flags & ~VALID_INHERIT_FLAGS;
194 }
195
196 /* If flags are invalid, bail out */
197 if (InvalidFlags != 0) return STATUS_INVALID_PARAMETER;
198
199 /* If ACL is invalid, bail out */
200 if (!RtlValidAcl(Acl)) return STATUS_INVALID_ACL;
201
202 /* If there's no free ACE, bail out */
203 if (!RtlFirstFreeAce(Acl, (PACE*)&Ace)) return STATUS_INVALID_ACL;
204
205 /* Calculate the size of the ACE */
206 AceSize = RtlLengthSid(Sid) + sizeof(ACE) + sizeof(ULONG);
207
208 /* Add-in the size of the GUIDs if any and update flags as needed */
209 if (ObjectTypeGuid)
210 {
211 AceObjectFlags |= ACE_OBJECT_TYPE_PRESENT;
212 AceSize += sizeof(GUID);
213 }
214 if (InheritedObjectTypeGuid)
215 {
216 AceObjectFlags |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
217 AceSize += sizeof(GUID);
218 }
219
220 /* Bail out if there's not enough space in the ACL */
221 if (!(Ace) || ((ULONG_PTR)Ace + AceSize > (ULONG_PTR)Acl + Acl->AclSize))
222 {
224 }
225
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;
232
233 /* Copy the GUIDs */
234 SidStart = (ULONG_PTR)&Ace->SidStart;
235 if (ObjectTypeGuid )
236 {
237 RtlCopyMemory((PVOID)SidStart, ObjectTypeGuid, sizeof(GUID));
238 SidStart += sizeof(GUID);
239 }
240 if (InheritedObjectTypeGuid)
241 {
242 RtlCopyMemory((PVOID)SidStart, InheritedObjectTypeGuid, sizeof(GUID));
243 SidStart += sizeof(GUID);
244 }
245
246 /* Copy the SID */
247 RtlCopySid(RtlLengthSid(Sid), (PSID)SidStart, Sid);
248
249 /* Fill out the ACL header and return */
250 Acl->AceCount++;
251 Acl->AclRevision = (BYTE)Revision;
252 return STATUS_SUCCESS;
253}
254
255/* PUBLIC FUNCTIONS ***********************************************************/
256
257/*
258 * @implemented
259 */
261NTAPI
265 IN PSID Sid)
266{
268
269 /* Call the worker function */
270 return RtlpAddKnownAce(Acl,
271 Revision,
272 0,
274 Sid,
276}
277
278/*
279 * @implemented
280 */
282NTAPI
285 IN ULONG Flags,
287 IN PSID Sid)
288{
290
291 /* Call the worker function */
292 return RtlpAddKnownAce(Acl,
293 Revision,
294 Flags,
296 Sid,
298}
299
300/*
301 * @implemented
302 */
304NTAPI
307 IN ULONG Flags,
309 IN GUID *ObjectTypeGuid OPTIONAL,
310 IN GUID *InheritedObjectTypeGuid OPTIONAL,
311 IN PSID Sid)
312{
314
315 /* Is there no object data? */
316 if (!(ObjectTypeGuid) && !(InheritedObjectTypeGuid))
317 {
318 /* Use the usual routine */
319 return RtlpAddKnownAce(Acl,
320 Revision,
321 Flags,
323 Sid,
325 }
326
327 /* Use the object routine */
328 return RtlpAddKnownObjectAce(Acl,
329 Revision,
330 Flags,
332 ObjectTypeGuid,
333 InheritedObjectTypeGuid,
334 Sid,
336}
337
338/*
339 * @implemented
340 */
342NTAPI
346 IN PSID Sid)
347{
349
350 /* Call the worker function */
351 return RtlpAddKnownAce(Acl,
352 Revision,
353 0,
355 Sid,
357}
358
359/*
360 * @implemented
361 */
363NTAPI
366 IN ULONG Flags,
368 IN PSID Sid)
369{
371
372 /* Call the worker function */
373 return RtlpAddKnownAce(Acl,
374 Revision,
375 Flags,
377 Sid,
379}
380
381/*
382 * @implemented
383 */
385NTAPI
388 IN ULONG Flags,
390 IN GUID *ObjectTypeGuid OPTIONAL,
391 IN GUID *InheritedObjectTypeGuid OPTIONAL,
392 IN PSID Sid)
393{
395
396 /* Is there no object data? */
397 if (!(ObjectTypeGuid) && !(InheritedObjectTypeGuid))
398 {
399 /* Use the usual routine */
400 return RtlpAddKnownAce(Acl,
401 Revision,
402 Flags,
404 Sid,
406 }
407
408 /* There's object data, use the object routine */
409 return RtlpAddKnownObjectAce(Acl,
410 Revision,
411 Flags,
413 ObjectTypeGuid,
414 InheritedObjectTypeGuid,
415 Sid,
417}
418
419/*
420 * @implemented
421 */
423NTAPI
427 IN PSID Sid,
429 IN BOOLEAN Failure)
430{
431 ULONG Flags = 0;
433
434 /* Add flags */
436 if (Failure) Flags |= FAILED_ACCESS_ACE_FLAG;
437
438 /* Call the worker routine */
439 return RtlpAddKnownAce(Acl,
440 Revision,
441 Flags,
443 Sid,
445}
446
447/*
448 * @implemented
449 */
451NTAPI
454 IN ULONG Flags,
456 IN PSID Sid,
458 IN BOOLEAN Failure)
459{
461
462 /* Add flags */
464 if (Failure) Flags |= FAILED_ACCESS_ACE_FLAG;
465
466 /* Call the worker routine */
467 return RtlpAddKnownAce(Acl,
468 Revision,
469 Flags,
471 Sid,
473}
474
475/*
476 * @implemented
477 */
479NTAPI
482 IN ULONG Flags,
484 IN GUID *ObjectTypeGuid OPTIONAL,
485 IN GUID *InheritedObjectTypeGuid OPTIONAL,
486 IN PSID Sid,
488 IN BOOLEAN Failure)
489{
490 /* Add flags */
492 if (Failure) Flags |= FAILED_ACCESS_ACE_FLAG;
493
494 /* Is there no object data? */
495 if (!(ObjectTypeGuid) && !(InheritedObjectTypeGuid))
496 {
497 /* Call the normal routine */
498 return RtlpAddKnownAce(Acl,
499 Revision,
500 Flags,
502 Sid,
504 }
505
506 /* There's object data, use the object routine */
507 return RtlpAddKnownObjectAce(Acl,
508 Revision,
509 Flags,
511 ObjectTypeGuid,
512 InheritedObjectTypeGuid,
513 Sid,
515}
516
517/*
518 * @implemented
519 */
521NTAPI
524 OUT PVOID *Ace)
525{
526 ULONG i;
528
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))
533 {
535 }
536
537 /* Loop through the ACEs */
538 *Ace = (PVOID)((PACE)(Acl + 1));
539 for (i = 0; i < AceIndex; i++)
540 {
541 /* Bail out if an invalid ACE is ever found */
542 if ((ULONG_PTR)*Ace >= (ULONG_PTR)Acl + Acl->AclSize)
543 {
545 }
546
547 /* Keep going */
548 *Ace = (PVOID)((PACE)((ULONG_PTR)(*Ace) + ((PACE)(*Ace))->Header.AceSize));
549 }
550
551 /* Check if the last ACE is still valid */
552 if ((ULONG_PTR)*Ace >= (ULONG_PTR)Acl + Acl->AclSize)
553 {
555 }
556
557 /* All good, return */
558 return STATUS_SUCCESS;
559}
560
561/*
562 * @implemented
563 */
565NTAPI
569 IN PVOID AceList,
571{
572 PACE Ace, FreeAce;
573 USHORT NewAceCount;
574 ULONG Index;
576
577 /* Bail out if the ACL is invalid */
578 if (!RtlValidAcl(Acl)) return STATUS_INVALID_PARAMETER;
579
580 /* Bail out if there's no space */
581 if (!RtlFirstFreeAce(Acl, &FreeAce)) return STATUS_INVALID_PARAMETER;
582
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);
586 NewAceCount++)
587 {
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)
591 {
592 if (Ace->Header.AceType > ACCESS_MAX_MS_V3_ACE_TYPE)
593 {
595 }
596 else if (Ace->Header.AceType > ACCESS_MAX_MS_V2_ACE_TYPE)
597 {
599 }
600 }
601
602 /* Move to the next ACE */
603 Ace = (PACE)((ULONG_PTR)Ace + Ace->Header.AceSize);
604 }
605
606 /* Bail out if there's no more space for us */
607 if ((ULONG_PTR)Ace > ((ULONG_PTR)AceList + AceListLength))
608 {
610 }
611
612 /* Bail out if there's no free ACE spot, or if we would overflow it */
613 if (!(FreeAce) ||
614 ((ULONG_PTR)FreeAce + AceListLength > (ULONG_PTR)Acl + Acl->AclSize))
615 {
617 }
618
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++)
622 {
623 Ace = (PACE)((ULONG_PTR)Ace + Ace->Header.AceSize);
624 }
625
626 /* Found where we want to do, add us to the list */
627 RtlpAddData(AceList,
629 Ace,
630 (ULONG_PTR)FreeAce - (ULONG_PTR)Ace);
631
632 /* Update the header and return */
633 Acl->AceCount += NewAceCount;
634 Acl->AclRevision = (UCHAR)min(Acl->AclRevision, AclRevision);
635 return STATUS_SUCCESS;
636}
637
638/*
639 * @implemented
640 */
642NTAPI
645{
646 PACE FreeAce, Ace;
648
649 /* Bail out if the ACL is invalid */
650 if (!RtlValidAcl(Acl)) return STATUS_INVALID_PARAMETER;
651
652 /* Bail out if there's no space or if we're full */
653 if ((Acl->AceCount <= AceIndex) || !(RtlFirstFreeAce(Acl, &FreeAce)))
654 {
656 }
657
658 /* Enumerate until the indexed ACE is reached */
659 Ace = (PACE)(Acl + 1);
660 while (AceIndex--) Ace = (PACE)((ULONG_PTR)Ace + Ace->Header.AceSize);
661
662 /* Delete this ACE */
664 Ace->Header.AceSize,
665 (ULONG)((ULONG_PTR)FreeAce - (ULONG_PTR)Ace));
666
667 /* Decrease an ACE and return success */
668 Acl->AceCount--;
669 return STATUS_SUCCESS;
670}
671
672/*
673 * @implemented
674 */
676NTAPI
678 IN ULONG AclSize,
680{
682
683 /* Bail out if too small */
684 if (AclSize < sizeof(ACL)) return STATUS_BUFFER_TOO_SMALL;
685
686 /* Bail out if too large or invalid revision */
689 (AclSize > MAXUSHORT))
690 {
692 }
693
694 /* Setup the header */
695 Acl->AclSize = (USHORT)ROUND_UP(AclSize, 4);
696 Acl->AclRevision = (UCHAR)AclRevision;
697 Acl->AceCount = 0;
698 Acl->Sbz1 = 0;
699 Acl->Sbz2 = 0;
700 return STATUS_SUCCESS;
701}
702
703/*
704 * @implemented
705 */
707NTAPI
710 IN ULONG InformationLength,
712{
713 PACE Ace;
714 PACL_REVISION_INFORMATION RevisionInfo;
715 PACL_SIZE_INFORMATION SizeInfo;
717
718 /* Validate the ACL revision */
719 if ((Acl->AclRevision < MIN_ACL_REVISION) ||
720 (Acl->AclRevision > MAX_ACL_REVISION))
721 {
723 }
724
725 /* Check what the caller is querying */
726 switch (InformationClass)
727 {
728 /* Revision data */
730
731 /* Bail out if the buffer is too small */
732 if (InformationLength < sizeof(ACL_REVISION_INFORMATION))
733 {
735 }
736
737 /* Return the current revision */
739 RevisionInfo->AclRevision = Acl->AclRevision;
740 break;
741
742 /* Size data */
744
745 /* Bail out if the buffer is too small */
746 if (InformationLength < sizeof(ACL_SIZE_INFORMATION))
747 {
749 }
750
751 /* Bail out if there's no space in the ACL */
752 if (!RtlFirstFreeAce(Acl, &Ace)) return STATUS_INVALID_PARAMETER;
753
754 /* Read the number of ACEs and check if there was a free ACE */
756 SizeInfo->AceCount = Acl->AceCount;
757 if (Ace)
758 {
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;
762 }
763 else
764 {
765 /* No free ACE, means the whole ACL is full */
766 SizeInfo->AclBytesInUse = Acl->AclSize;
767 SizeInfo->AclBytesFree = 0;
768 }
769 break;
770
771 default:
772 /* Anything else is illegal */
774 }
775
776 /* All done */
777 return STATUS_SUCCESS;
778}
779
780/*
781 * @implemented
782 */
784NTAPI
787 IN ULONG InformationLength,
789{
792
793 /* Validate the ACL revision */
794 if ((Acl->AclRevision < MIN_ACL_REVISION) ||
795 (Acl->AclRevision > MAX_ACL_REVISION))
796 {
798 }
799
800 /* What is the caller trying to set? */
801 switch (InformationClass)
802 {
803 /* This is the only info class */
805
806 /* Make sure the buffer is large enough */
807 if (InformationLength < sizeof(ACL_REVISION_INFORMATION))
808 {
810 }
811
812 /* Make sure the new revision is within the acceptable bounds*/
814 if (Acl->AclRevision >= Info->AclRevision)
815 {
817 }
818
819 /* Set the new revision */
820 Acl->AclRevision = (BYTE)Info->AclRevision;
821 break;
822
823 default:
824 /* Anything else is invalid */
826 }
827
828 /* All good */
829 return STATUS_SUCCESS;
830}
831
832/*
833 * @implemented
834 */
836NTAPI
838{
840 PISID Sid;
841 ULONG i;
842 USHORT RequiredObjectAceSize;
844 ULONG GuidSize;
846
848 {
849 /* First, validate the revision */
850 if ((Acl->AclRevision < MIN_ACL_REVISION) ||
851 (Acl->AclRevision > MAX_ACL_REVISION))
852 {
853 DPRINT1("Invalid ACL revision: %u\n", Acl->AclRevision);
854 _SEH2_YIELD(return FALSE);
855 }
856
857 /* Next, validate that the ACL is USHORT-aligned */
858 if (ROUND_DOWN(Acl->AclSize, sizeof(USHORT)) != Acl->AclSize)
859 {
860 DPRINT1("Misaligned ACL size: %u\n", Acl->AclSize);
861 _SEH2_YIELD(return FALSE);
862 }
863
864 /* And that it's big enough */
865 if (Acl->AclSize < sizeof(ACL))
866 {
867 DPRINT1("Too small ACL size: %u\n", Acl->AclSize);
868 _SEH2_YIELD(return FALSE);
869 }
870
871 /* Loop each ACE */
872 Ace = (PACE_HEADER)((ULONG_PTR)Acl + sizeof(ACL));
873 for (i = 0; i < Acl->AceCount; i++)
874 {
875 /* Validate we have space for this ACE header */
876 if (((ULONG_PTR)Ace + sizeof(ACE_HEADER)) >= ((ULONG_PTR)Acl + Acl->AclSize))
877 {
878 DPRINT1("Invalid ACE size\n");
879 _SEH2_YIELD(return FALSE);
880 }
881
882 /* Validate the length of this ACE */
883 if (ROUND_DOWN(Ace->AceSize, sizeof(USHORT)) != Ace->AceSize)
884 {
885 DPRINT1("Invalid ACE size: %lx\n", Ace->AceSize);
886 _SEH2_YIELD(return FALSE);
887 }
888
889 /* Validate we have space for the entire ACE */
890 if (((ULONG_PTR)Ace + Ace->AceSize) > ((ULONG_PTR)Acl + Acl->AclSize))
891 {
892 DPRINT1("Invalid ACE size %lx %lx\n", Ace->AceSize, Acl->AclSize);
893 _SEH2_YIELD(return FALSE);
894 }
895
896 /* Check what kind of ACE this is */
897 if (Ace->AceType <= ACCESS_MAX_MS_V2_ACE_TYPE)
898 {
899 /* Validate the length of this ACE */
900 if (ROUND_DOWN(Ace->AceSize, sizeof(ULONG)) != Ace->AceSize)
901 {
902 DPRINT1("Invalid ACE size\n");
903 _SEH2_YIELD(return FALSE);
904 }
905
906 /* The ACE size should at least have enough for the header */
907 if (Ace->AceSize < sizeof(ACE_HEADER))
908 {
909 DPRINT1("Invalid ACE size: %lx %lx\n", Ace->AceSize, sizeof(ACE_HEADER));
910 _SEH2_YIELD(return FALSE);
911 }
912
913 /* Check if the SID revision is valid */
914 Sid = (PISID)&((PKNOWN_ACE)Ace)->SidStart;
915 if (Sid->Revision != SID_REVISION)
916 {
917 DPRINT1("Invalid SID\n");
918 _SEH2_YIELD(return FALSE);
919 }
920
921 /* Check if the SID is out of bounds */
923 {
924 DPRINT1("Invalid SID\n");
925 _SEH2_YIELD(return FALSE);
926 }
927
928 /* The ACE size should at least have enough for the header and SID */
929 if (Ace->AceSize < (sizeof(ACE_HEADER) + RtlLengthSid(Sid)))
930 {
931 DPRINT1("Invalid ACE size\n");
932 _SEH2_YIELD(return FALSE);
933 }
934 }
935 else if (Ace->AceType == ACCESS_ALLOWED_OBJECT_ACE_TYPE ||
937 {
938 /* Object ACEs are supported starting with Revision 4 */
939 if (Acl->AclRevision < ACL_REVISION4)
940 {
941 DPRINT1("Invalid ACL revision for Object ACE: %u\n", Acl->AclRevision);
942 _SEH2_YIELD(return FALSE);
943 }
944
945 /* Validate the length of this ACE */
946 if (ROUND_DOWN(Ace->AceSize, sizeof(ULONG)) != Ace->AceSize)
947 {
948 DPRINT1("Misaligned Object ACE size: %lx\n", Ace->AceSize);
949 _SEH2_YIELD(return FALSE);
950 }
951
952 /* The ACE size should at least have enough space for the known object ACE header */
953 if (Ace->AceSize < sizeof(KNOWN_OBJECT_ACE))
954 {
955 DPRINT1("Too small Object ACE size to hold KNOWN_OBJECT_ACE header: %lx\n", Ace->AceSize);
956 _SEH2_YIELD(return FALSE);
957 }
958
959 /* This ACL may have multiple Object ACEs so reset the size counter */
960 GuidSize = 0;
961
962 /* If we have GUIDs include them */
965 {
966 GuidSize += sizeof(GUID);
967 }
968
970 {
971 GuidSize += sizeof(GUID);
972 }
973
974 /* Check if the SID revision is valid */
975 Sid = (PISID)((ULONG_PTR)&((PKNOWN_OBJECT_ACE)Ace)->SidStart + GuidSize);
976 if (Sid->Revision != SID_REVISION)
977 {
978 DPRINT1("Object ACE SID has invalid revision: %u\n", Sid->Revision);
979 _SEH2_YIELD(return FALSE);
980 }
981
982 /* Check if the SID is out of bounds */
984 {
985 DPRINT1("Object ACE SID's sub-authority count is out of bounds: %u\n", Sid->SubAuthorityCount);
986 _SEH2_YIELD(return FALSE);
987 }
988
989 /* The ACE size should at least have enough space for the known object ACE header, GUIDs and the SID */
990 RequiredObjectAceSize = (sizeof(KNOWN_OBJECT_ACE) - sizeof(ULONG)) + GuidSize + RtlLengthSid(Sid);
991 if (Ace->AceSize < RequiredObjectAceSize)
992 {
993 DPRINT1("Too small Object ACE size: AceSize %u RequiredSize %u\n", Ace->AceSize, RequiredObjectAceSize);
994 _SEH2_YIELD(return FALSE);
995 }
996 }
997 else if (Ace->AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE)
998 {
999 DPRINT1("Unsupported ACE in ReactOS, assuming valid\n");
1000 }
1001 else if ((Ace->AceType >= ACCESS_MIN_MS_OBJECT_ACE_TYPE) &&
1002 (Ace->AceType <= ACCESS_MAX_MS_OBJECT_ACE_TYPE))
1003 {
1004 DPRINT1("Unsupported ACE in ReactOS, assuming valid\n");
1005 }
1006 else
1007 {
1008 /* Unknown ACE, see if it's as big as a header at least */
1009 if (Ace->AceSize < sizeof(ACE_HEADER))
1010 {
1011 DPRINT1("Unknown ACE\n");
1012 _SEH2_YIELD(return FALSE);
1013 }
1014 }
1015
1016 /* Move to the next ace */
1017 Ace = (PACE_HEADER)((ULONG_PTR)Ace + Ace->AceSize);
1018 }
1019 }
1021 {
1022 /* Something was invalid, fail */
1023 _SEH2_YIELD(return FALSE);
1024 }
1025 _SEH2_END;
1026
1027 /* The ACL looks ok */
1028 return TRUE;
1029}
1030
1031/* EOF */
unsigned char BOOLEAN
Type
Definition: Type.h:7
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
@ Ace
Definition: card.h:12
Definition: Header.h:9
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ULONG_PTR
Definition: config.h:101
@ Success
Definition: eventcreate.c:712
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned short WORD
Definition: ntddk_ex.h:93
_In_ FILTER_INFORMATION_CLASS InformationClass
Definition: fltkernel.h:1713
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI BOOLEAN WINAPI RtlCopySid(DWORD, PSID, PSID)
if(dx< 0)
Definition: linetemp.h:194
#define for
Definition: utility.h:88
#define min(a, b)
Definition: monoChain.cc:55
struct _ACL ACL
struct _ACE_HEADER ACE_HEADER
struct _ACE_HEADER * PACE_HEADER
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
NTSYSAPI BOOLEAN NTAPI RtlValidAcl(PACL Acl)
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI BOOLEAN NTAPI RtlValidSid(IN PSID Sid)
Definition: sid.c:21
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1133
_In_ ULONG Revision
Definition: rtlfuncs.h:1130
struct _ACE * PACE
struct _ACE ACE
ULONG ACCESS_MASK
Definition: nt_native.h:40
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
struct _KNOWN_OBJECT_ACE KNOWN_OBJECT_ACE
struct _KNOWN_OBJECT_ACE * PKNOWN_OBJECT_ACE
#define STATUS_INVALID_ACL
Definition: ntstatus.h:355
#define STATUS_INVALID_SID
Definition: ntstatus.h:356
#define STATUS_ALLOTTED_SPACE_EXCEEDED
Definition: ntstatus.h:389
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:325
unsigned short USHORT
Definition: pedump.c:61
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define PAGED_CODE_RTL()
Definition: rtlp.h:16
NTSTATUS NTAPI RtlAddAuditAccessAceEx(IN PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN PSID Sid, IN BOOLEAN Success, IN BOOLEAN Failure)
Definition: acl.c:452
BOOLEAN NTAPI RtlFirstFreeAce(IN PACL Acl, OUT PACE *FirstFreeAce)
Definition: acl.c:20
NTSTATUS NTAPI RtlAddAccessDeniedObjectAce(IN OUT PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN GUID *ObjectTypeGuid OPTIONAL, IN GUID *InheritedObjectTypeGuid OPTIONAL, IN PSID Sid)
Definition: acl.c:386
NTSTATUS NTAPI RtlAddAccessAllowedAceEx(IN OUT PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN PSID Sid)
Definition: acl.c:283
NTSTATUS NTAPI RtlAddAccessAllowedObjectAce(IN OUT PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN GUID *ObjectTypeGuid OPTIONAL, IN GUID *InheritedObjectTypeGuid OPTIONAL, IN PSID Sid)
Definition: acl.c:305
NTSTATUS NTAPI RtlQueryInformationAcl(IN PACL Acl, IN PVOID Information, IN ULONG InformationLength, IN ACL_INFORMATION_CLASS InformationClass)
Definition: acl.c:708
NTSTATUS NTAPI RtlAddAce(IN PACL Acl, IN ULONG AclRevision, IN ULONG StartingIndex, IN PVOID AceList, IN ULONG AceListLength)
Definition: acl.c:566
NTSTATUS NTAPI RtlAddAccessDeniedAceEx(IN OUT PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN PSID Sid)
Definition: acl.c:364
VOID NTAPI RtlpAddData(IN PVOID AceList, IN ULONG AceListLength, IN PVOID Ace, IN ULONG Offset)
Definition: acl.c:50
NTSTATUS NTAPI RtlSetInformationAcl(IN PACL Acl, IN PVOID Information, IN ULONG InformationLength, IN ACL_INFORMATION_CLASS InformationClass)
Definition: acl.c:785
NTSTATUS NTAPI RtlpAddKnownObjectAce(IN PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN GUID *ObjectTypeGuid OPTIONAL, IN GUID *InheritedObjectTypeGuid OPTIONAL, IN PSID Sid, IN UCHAR Type)
Definition: acl.c:158
NTSTATUS NTAPI RtlDeleteAce(IN PACL Acl, IN ULONG AceIndex)
Definition: acl.c:643
VOID NTAPI RtlpDeleteData(IN PVOID Ace, IN ULONG AceSize, IN ULONG Offset)
Definition: acl.c:69
NTSTATUS NTAPI RtlGetAce(IN PACL Acl, IN ULONG AceIndex, OUT PVOID *Ace)
Definition: acl.c:522
NTSTATUS NTAPI RtlAddAuditAccessAce(IN PACL Acl, IN ULONG Revision, IN ACCESS_MASK AccessMask, IN PSID Sid, IN BOOLEAN Success, IN BOOLEAN Failure)
Definition: acl.c:424
NTSTATUS NTAPI RtlAddAccessDeniedAce(IN PACL Acl, IN ULONG Revision, IN ACCESS_MASK AccessMask, IN PSID Sid)
Definition: acl.c:343
NTSTATUS NTAPI RtlAddAuditAccessObjectAce(IN PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN GUID *ObjectTypeGuid OPTIONAL, IN GUID *InheritedObjectTypeGuid OPTIONAL, IN PSID Sid, IN BOOLEAN Success, IN BOOLEAN Failure)
Definition: acl.c:480
NTSTATUS NTAPI RtlpAddKnownAce(IN PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN PSID Sid, IN UCHAR Type)
Definition: acl.c:90
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
USHORT AceSize
Definition: ms-dtyp.idl:212
Definition: rtltypes.h:993
ACE_HEADER Header
Definition: rtltypes.h:994
Definition: se.h:15
BYTE Revision
Definition: ms-dtyp.idl:199
BYTE SubAuthorityCount
Definition: ms-dtyp.idl:200
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
struct _ACL_REVISION_INFORMATION * PACL_REVISION_INFORMATION
enum _ACL_INFORMATION_CLASS ACL_INFORMATION_CLASS
struct _ACL_SIZE_INFORMATION * PACL_SIZE_INFORMATION
@ AclSizeInformation
Definition: winnt_old.h:1117
@ AclRevisionInformation
Definition: winnt_old.h:1116
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ ULONG _In_ ULONG _In_ ULONG AceListLength
Definition: rtlfuncs.h:1854
_In_ ULONG StartingIndex
Definition: rtlfuncs.h:395
_In_ ULONG _In_ ULONG AclRevision
Definition: rtlfuncs.h:1843
_In_ ULONG AceIndex
Definition: rtlfuncs.h:1862
#define VALID_INHERIT_FLAGS
Definition: setypes.h:751
#define ACE_INHERITED_OBJECT_TYPE_PRESENT
Definition: setypes.h:806
#define ACCESS_MAX_MS_ACE_TYPE
Definition: setypes.h:731
#define ACL_REVISION4
Definition: setypes.h:45
#define ACCESS_DENIED_OBJECT_ACE_TYPE
Definition: setypes.h:726
#define SYSTEM_AUDIT_ACE_TYPE
Definition: setypes.h:719
#define ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:717
#define ACL_REVISION3
Definition: setypes.h:44
#define SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
Definition: setypes.h:738
#define ACCESS_DENIED_ACE_TYPE
Definition: setypes.h:718
#define ACCESS_MAX_MS_V2_ACE_TYPE
Definition: setypes.h:721
#define MIN_ACL_REVISION
Definition: setypes.h:46
#define ACCESS_MIN_MS_OBJECT_ACE_TYPE
Definition: setypes.h:724
#define ACE_OBJECT_TYPE_PRESENT
Definition: setypes.h:805
#define ACCESS_ALLOWED_OBJECT_ACE_TYPE
Definition: setypes.h:725
#define ACCESS_ALLOWED_COMPOUND_ACE_TYPE
Definition: setypes.h:722
#define SID_MAX_SUB_AUTHORITIES
Definition: setypes.h:482
struct _SID * PISID
#define MAX_ACL_REVISION
Definition: setypes.h:47
#define SYSTEM_AUDIT_OBJECT_ACE_TYPE
Definition: setypes.h:727
#define SID_REVISION
Definition: setypes.h:481
#define FAILED_ACCESS_ACE_FLAG
Definition: setypes.h:754
#define SUCCESSFUL_ACCESS_ACE_FLAG
Definition: setypes.h:753
#define ACCESS_MAX_MS_V3_ACE_TYPE
Definition: setypes.h:723
#define ACCESS_MAX_MS_OBJECT_ACE_TYPE
Definition: setypes.h:729
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char BYTE
Definition: xxhash.c:193