ReactOS  0.4.15-dev-1201-gb2cf5a4
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 
18 BOOLEAN
19 NTAPI
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 
48 VOID
49 NTAPI
52  IN PVOID Ace,
53  IN ULONG Offset)
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 
67 VOID
68 NTAPI
70  IN ULONG AceSize,
71  IN ULONG Offset)
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 
89 NTAPI
92  IN ULONG Flags,
94  IN PSID Sid,
95  IN UCHAR Type)
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 
156 NTSTATUS
157 NTAPI
159  IN ULONG Revision,
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;
170  PAGED_CODE_RTL();
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  */
260 NTSTATUS
261 NTAPI
263  IN ULONG Revision,
265  IN PSID Sid)
266 {
267  PAGED_CODE_RTL();
268 
269  /* Call the worker function */
270  return RtlpAddKnownAce(Acl,
271  Revision,
272  0,
273  AccessMask,
274  Sid,
276 }
277 
278 /*
279  * @implemented
280  */
281 NTSTATUS
282 NTAPI
284  IN ULONG Revision,
285  IN ULONG Flags,
287  IN PSID Sid)
288 {
289  PAGED_CODE_RTL();
290 
291  /* Call the worker function */
292  return RtlpAddKnownAce(Acl,
293  Revision,
294  Flags,
295  AccessMask,
296  Sid,
298 }
299 
300 /*
301  * @implemented
302  */
303 NTSTATUS
304 NTAPI
306  IN ULONG Revision,
307  IN ULONG Flags,
309  IN GUID *ObjectTypeGuid OPTIONAL,
310  IN GUID *InheritedObjectTypeGuid OPTIONAL,
311  IN PSID Sid)
312 {
313  PAGED_CODE_RTL();
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,
322  AccessMask,
323  Sid,
325  }
326 
327  /* Use the object routine */
328  return RtlpAddKnownObjectAce(Acl,
329  Revision,
330  Flags,
331  AccessMask,
332  ObjectTypeGuid,
333  InheritedObjectTypeGuid,
334  Sid,
336 }
337 
338 /*
339  * @implemented
340  */
341 NTSTATUS
342 NTAPI
344  IN ULONG Revision,
346  IN PSID Sid)
347 {
348  PAGED_CODE_RTL();
349 
350  /* Call the worker function */
351  return RtlpAddKnownAce(Acl,
352  Revision,
353  0,
354  AccessMask,
355  Sid,
357 }
358 
359 /*
360  * @implemented
361  */
362 NTSTATUS
363 NTAPI
365  IN ULONG Revision,
366  IN ULONG Flags,
368  IN PSID Sid)
369 {
370  PAGED_CODE_RTL();
371 
372  /* Call the worker function */
373  return RtlpAddKnownAce(Acl,
374  Revision,
375  Flags,
376  AccessMask,
377  Sid,
379 }
380 
381 /*
382  * @implemented
383  */
384 NTSTATUS
385 NTAPI
387  IN ULONG Revision,
388  IN ULONG Flags,
390  IN GUID *ObjectTypeGuid OPTIONAL,
391  IN GUID *InheritedObjectTypeGuid OPTIONAL,
392  IN PSID Sid)
393 {
394  PAGED_CODE_RTL();
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,
403  AccessMask,
404  Sid,
406  }
407 
408  /* There's object data, use the object routine */
409  return RtlpAddKnownObjectAce(Acl,
410  Revision,
411  Flags,
412  AccessMask,
413  ObjectTypeGuid,
414  InheritedObjectTypeGuid,
415  Sid,
417 }
418 
419 /*
420  * @implemented
421  */
422 NTSTATUS
423 NTAPI
425  IN ULONG Revision,
427  IN PSID Sid,
429  IN BOOLEAN Failure)
430 {
431  ULONG Flags = 0;
432  PAGED_CODE_RTL();
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,
442  AccessMask,
443  Sid,
445 }
446 
447 /*
448  * @implemented
449  */
450 NTSTATUS
451 NTAPI
453  IN ULONG Revision,
454  IN ULONG Flags,
456  IN PSID Sid,
458  IN BOOLEAN Failure)
459 {
460  PAGED_CODE_RTL();
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,
470  AccessMask,
471  Sid,
473 }
474 
475 /*
476  * @implemented
477  */
478 NTSTATUS
479 NTAPI
481  IN ULONG Revision,
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,
501  AccessMask,
502  Sid,
504  }
505 
506  /* There's object data, use the object routine */
507  return RtlpAddKnownObjectAce(Acl,
508  Revision,
509  Flags,
510  AccessMask,
511  ObjectTypeGuid,
512  InheritedObjectTypeGuid,
513  Sid,
515 }
516 
517 /*
518  * @implemented
519  */
520 NTSTATUS
521 NTAPI
523  IN ULONG AceIndex,
524  OUT PVOID *Ace)
525 {
526  ULONG i;
527  PAGED_CODE_RTL();
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  */
564 NTSTATUS
565 NTAPI
569  IN PVOID AceList,
571 {
572  PACE Ace, FreeAce;
573  USHORT NewAceCount;
574  ULONG Index;
575  PAGED_CODE_RTL();
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  */
641 NTSTATUS
642 NTAPI
644  IN ULONG AceIndex)
645 {
646  PACE FreeAce, Ace;
647  PAGED_CODE_RTL();
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  */
675 NTSTATUS
676 NTAPI
678  IN ULONG AclSize,
680 {
681  PAGED_CODE_RTL();
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 */
687  if ((AclRevision < MIN_ACL_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  */
706 NTSTATUS
707 NTAPI
710  IN ULONG InformationLength,
712 {
713  PACE Ace;
714  PACL_REVISION_INFORMATION RevisionInfo;
715  PACL_SIZE_INFORMATION SizeInfo;
716  PAGED_CODE_RTL();
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 */
738  RevisionInfo = (PACL_REVISION_INFORMATION)Information;
739  RevisionInfo->AclRevision = Acl->AclRevision;
740  break;
741 
742  /* Size data */
743  case AclSizeInformation:
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  */
783 NTSTATUS
784 NTAPI
787  IN ULONG InformationLength,
789 {
791  PAGED_CODE_RTL();
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  */
835 BOOLEAN
836 NTAPI
838 {
840  PISID Sid;
841  ULONG i;
842  PAGED_CODE_RTL();
843 
844  _SEH2_TRY
845  {
846  /* First, validate the revision */
847  if ((Acl->AclRevision < MIN_ACL_REVISION) ||
848  (Acl->AclRevision > MAX_ACL_REVISION))
849  {
850  DPRINT1("Invalid ACL revision: %u\n", Acl->AclRevision);
851  _SEH2_YIELD(return FALSE);
852  }
853 
854  /* Next, validate that the ACL is USHORT-aligned */
855  if (ROUND_DOWN(Acl->AclSize, sizeof(USHORT)) != Acl->AclSize)
856  {
857  DPRINT1("Misaligned ACL size: %u\n", Acl->AclSize);
858  _SEH2_YIELD(return FALSE);
859  }
860 
861  /* And that it's big enough */
862  if (Acl->AclSize < sizeof(ACL))
863  {
864  DPRINT1("Too small ACL size: %u\n", Acl->AclSize);
865  _SEH2_YIELD(return FALSE);
866  }
867 
868  /* Loop each ACE */
869  Ace = (PACE_HEADER)((ULONG_PTR)Acl + sizeof(ACL));
870  for (i = 0; i < Acl->AceCount; i++)
871  {
872  /* Validate we have space for this ACE header */
873  if (((ULONG_PTR)Ace + sizeof(ACE_HEADER)) >= ((ULONG_PTR)Acl + Acl->AclSize))
874  {
875  DPRINT1("Invalid ACE size\n");
876  _SEH2_YIELD(return FALSE);
877  }
878 
879  /* Validate the length of this ACE */
880  if (ROUND_DOWN(Ace->AceSize, sizeof(USHORT)) != Ace->AceSize)
881  {
882  DPRINT1("Invalid ACE size: %lx\n", Ace->AceSize);
883  _SEH2_YIELD(return FALSE);
884  }
885 
886  /* Validate we have space for the entire ACE */
887  if (((ULONG_PTR)Ace + Ace->AceSize) > ((ULONG_PTR)Acl + Acl->AclSize))
888  {
889  DPRINT1("Invalid ACE size %lx %lx\n", Ace->AceSize, Acl->AclSize);
890  _SEH2_YIELD(return FALSE);
891  }
892 
893  /* Check what kind of ACE this is */
894  if (Ace->AceType <= ACCESS_MAX_MS_V2_ACE_TYPE)
895  {
896  /* Validate the length of this ACE */
897  if (ROUND_DOWN(Ace->AceSize, sizeof(ULONG)) != Ace->AceSize)
898  {
899  DPRINT1("Invalid ACE size\n");
900  _SEH2_YIELD(return FALSE);
901  }
902 
903  /* The ACE size should at least have enough for the header */
904  if (Ace->AceSize < sizeof(ACE_HEADER))
905  {
906  DPRINT1("Invalid ACE size: %lx %lx\n", Ace->AceSize, sizeof(ACE_HEADER));
907  _SEH2_YIELD(return FALSE);
908  }
909 
910  /* Check if the SID revision is valid */
911  Sid = (PISID)&((PKNOWN_ACE)Ace)->SidStart;
912  if (Sid->Revision != SID_REVISION)
913  {
914  DPRINT1("Invalid SID\n");
915  _SEH2_YIELD(return FALSE);
916  }
917 
918  /* Check if the SID is out of bounds */
920  {
921  DPRINT1("Invalid SID\n");
922  _SEH2_YIELD(return FALSE);
923  }
924 
925  /* The ACE size should at least have enough for the header and SID */
926  if (Ace->AceSize < (sizeof(ACE_HEADER) + RtlLengthSid(Sid)))
927  {
928  DPRINT1("Invalid ACE size\n");
929  _SEH2_YIELD(return FALSE);
930  }
931  }
932  else if (Ace->AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE)
933  {
934  DPRINT1("Unsupported ACE in ReactOS, assuming valid\n");
935  }
936  else if ((Ace->AceType >= ACCESS_MIN_MS_OBJECT_ACE_TYPE) &&
937  (Ace->AceType <= ACCESS_MAX_MS_OBJECT_ACE_TYPE))
938  {
939  DPRINT1("Unsupported ACE in ReactOS, assuming valid\n");
940  }
941  else
942  {
943  /* Unknown ACE, see if it's as big as a header at least */
944  if (Ace->AceSize < sizeof(ACE_HEADER))
945  {
946  DPRINT1("Unknown ACE\n");
947  _SEH2_YIELD(return FALSE);
948  }
949  }
950 
951  /* Move to the next ace */
952  Ace = (PACE_HEADER)((ULONG_PTR)Ace + Ace->AceSize);
953  }
954  }
956  {
957  /* Something was invalid, fail */
958  _SEH2_YIELD(return FALSE);
959  }
960  _SEH2_END;
961 
962  /* The ACL looks ok */
963  return TRUE;
964 }
965 
966 /* EOF */
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_REVISION_MISMATCH
Definition: ntstatus.h:325
VOID NTAPI RtlpDeleteData(IN PVOID Ace, IN ULONG AceSize, IN ULONG Offset)
Definition: acl.c:69
#define IN
Definition: typedefs.h:39
BOOLEAN NTAPI RtlFirstFreeAce(IN PACL Acl, OUT PACE *FirstFreeAce)
Definition: acl.c:20
NTSTATUS NTAPI RtlQueryInformationAcl(IN PACL Acl, IN PVOID Information, IN ULONG InformationLength, IN ACL_INFORMATION_CLASS InformationClass)
Definition: acl.c:708
#define ACE_OBJECT_TYPE_PRESENT
Definition: winnt_old.h:106
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define ACCESS_MAX_MS_V2_ACE_TYPE
Definition: setypes.h:689
NTSTATUS NTAPI RtlGetAce(IN PACL Acl, IN ULONG AceIndex, OUT PVOID *Ace)
Definition: acl.c:522
struct _ACE_HEADER * PACE_HEADER
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
Type
Definition: Type.h:6
enum _ACL_INFORMATION_CLASS ACL_INFORMATION_CLASS
struct _ACE_HEADER ACE_HEADER
#define VALID_INHERIT_FLAGS
Definition: setypes.h:719
#define SYSTEM_AUDIT_OBJECT_ACE_TYPE
Definition: setypes.h:695
Definition: se.h:3
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
#define MAX_ACL_REVISION
Definition: setypes.h:47
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
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _ACE ACE
#define SID_REVISION
Definition: setypes.h:453
struct _ACE * PACE
LONG NTSTATUS
Definition: precomp.h:26
#define PAGED_CODE_RTL()
Definition: rtlp.h:16
NTSTATUS NTAPI RtlAddAccessAllowedAceEx(IN OUT PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN PSID Sid)
Definition: acl.c:283
_In_ ULONG Revision
Definition: rtlfuncs.h:1103
struct TraceInfo Info
Iosb Information
Definition: create.c:4353
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
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SUCCESSFUL_ACCESS_ACE_FLAG
Definition: setypes.h:721
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
USHORT AceSize
Definition: ms-dtyp.idl:212
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 ACL_REVISION4
Definition: setypes.h:45
#define FAILED_ACCESS_ACE_FLAG
Definition: setypes.h:722
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FALSE
Definition: types.h:117
Definition: Header.h:8
#define ACCESS_DENIED_OBJECT_ACE_TYPE
Definition: setypes.h:694
struct _SID * PISID
#define ACCESS_ALLOWED_COMPOUND_ACE_TYPE
Definition: setypes.h:690
Definition: card.h:12
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ACE_INHERITED_OBJECT_TYPE_PRESENT
Definition: winnt_old.h:107
unsigned char BOOLEAN
#define SID_MAX_SUB_AUTHORITIES
Definition: setypes.h:454
struct _ACL ACL
smooth NULL
Definition: ftsmooth.c:416
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1103
#define ACCESS_MIN_MS_OBJECT_ACE_TYPE
Definition: setypes.h:692
#define ACL_REVISION3
Definition: setypes.h:44
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
#define STATUS_INVALID_SID
Definition: ntstatus.h:356
void * PVOID
Definition: retypes.h:9
NTSYSAPI BOOLEAN NTAPI RtlValidSid(IN PSID Sid)
Definition: sid.c:21
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
#define SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
Definition: setypes.h:706
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define STATUS_ALLOTTED_SPACE_EXCEEDED
Definition: ntstatus.h:389
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define ACCESS_MAX_MS_V3_ACE_TYPE
Definition: setypes.h:691
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
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
static const UCHAR Index[8]
Definition: usbohci.c:18
BOOLEAN NTAPI RtlValidAcl(IN PACL Acl)
Definition: acl.c:837
#define MIN_ACL_REVISION
Definition: setypes.h:46
unsigned short WORD
Definition: ntddk_ex.h:93
#define for
Definition: utility.h:88
#define ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:685
#define ACCESS_ALLOWED_OBJECT_ACE_TYPE
Definition: setypes.h:693
#define ACCESS_DENIED_ACE_TYPE
Definition: setypes.h:686
unsigned char UCHAR
Definition: xmlstorage.h:181
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
_In_ ULONG _In_ ULONG AclRevision
Definition: rtlfuncs.h:1844
NTSTATUS NTAPI RtlDeleteAce(IN PACL Acl, IN ULONG AceIndex)
Definition: acl.c:643
NTSYSAPI BOOLEAN WINAPI RtlCopySid(DWORD, PSID, PSID)
_In_ ULONG StartingIndex
Definition: rtlfuncs.h:395
_In_ ULONG AceIndex
Definition: rtlfuncs.h:1864
_In_ ULONG _In_ ULONG _In_ ULONG AceListLength
Definition: rtlfuncs.h:1856
unsigned char BYTE
Definition: xxhash.c:193
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:30
struct _GUID GUID
_SEH2_END
Definition: create.c:4400
NTSTATUS NTAPI RtlSetInformationAcl(IN PACL Acl, IN PVOID Information, IN ULONG InformationLength, IN ACL_INFORMATION_CLASS InformationClass)
Definition: acl.c:785
NTSTATUS NTAPI RtlAddAccessDeniedAce(IN PACL Acl, IN ULONG Revision, IN ACCESS_MASK AccessMask, IN PSID Sid)
Definition: acl.c:343
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_INVALID_ACL
Definition: ntstatus.h:355
NTSTATUS NTAPI RtlAddAccessAllowedAce(IN OUT PACL Acl, IN ULONG Revision, IN ACCESS_MASK AccessMask, IN PSID Sid)
Definition: acl.c:262
#define ACCESS_MAX_MS_ACE_TYPE
Definition: setypes.h:699
BYTE SubAuthorityCount
Definition: ms-dtyp.idl:200
NTSTATUS NTAPI RtlCreateAcl(IN PACL Acl, IN ULONG AclSize, IN ULONG AclRevision)
Definition: acl.c:677
#define min(a, b)
Definition: monoChain.cc:55
#define MAXUSHORT
Definition: typedefs.h:83
#define DPRINT1
Definition: precomp.h:8
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
NTSTATUS NTAPI RtlAddAce(IN PACL Acl, IN ULONG AclRevision, IN ULONG StartingIndex, IN PVOID AceList, IN ULONG AceListLength)
Definition: acl.c:566
#define ULONG_PTR
Definition: config.h:101
#define SYSTEM_AUDIT_ACE_TYPE
Definition: setypes.h:687
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
BYTE Revision
Definition: ms-dtyp.idl:199
#define ACCESS_MAX_MS_OBJECT_ACE_TYPE
Definition: setypes.h:697
_In_ FILTER_INFORMATION_CLASS InformationClass
Definition: fltkernel.h:1714
return STATUS_SUCCESS
Definition: btrfs.c:3014
VOID NTAPI RtlpAddData(IN PVOID AceList, IN ULONG AceListLength, IN PVOID Ace, IN ULONG Offset)
Definition: acl.c:50
struct _ACL_REVISION_INFORMATION * PACL_REVISION_INFORMATION
Definition: rtltypes.h:990
ACE_HEADER Header
Definition: rtltypes.h:992
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSTATUS NTAPI RtlAddAccessDeniedAceEx(IN OUT PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN PSID Sid)
Definition: acl.c:364
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
struct _ACL_SIZE_INFORMATION * PACL_SIZE_INFORMATION
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68