ReactOS 0.4.15-dev-7934-g1dc8d80
acl.c File Reference
#include <rtl.h>
#include <../../ntoskrnl/include/internal/se.h>
#include <debug.h>
Include dependency graph for acl.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN NTAPI RtlFirstFreeAce (IN PACL Acl, OUT PACE *FirstFreeAce)
 
VOID NTAPI RtlpAddData (IN PVOID AceList, IN ULONG AceListLength, IN PVOID Ace, IN ULONG Offset)
 
VOID NTAPI RtlpDeleteData (IN PVOID Ace, IN ULONG AceSize, IN ULONG Offset)
 
NTSTATUS NTAPI RtlpAddKnownAce (IN PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN PSID Sid, IN UCHAR Type)
 
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)
 
NTSTATUS NTAPI RtlAddAccessAllowedAce (IN OUT PACL Acl, IN ULONG Revision, IN ACCESS_MASK AccessMask, IN PSID Sid)
 
NTSTATUS NTAPI RtlAddAccessAllowedAceEx (IN OUT PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN PSID Sid)
 
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)
 
NTSTATUS NTAPI RtlAddAccessDeniedAce (IN PACL Acl, IN ULONG Revision, IN ACCESS_MASK AccessMask, IN PSID Sid)
 
NTSTATUS NTAPI RtlAddAccessDeniedAceEx (IN OUT PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN PSID Sid)
 
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)
 
NTSTATUS NTAPI RtlAddAuditAccessAce (IN PACL Acl, IN ULONG Revision, IN ACCESS_MASK AccessMask, IN PSID Sid, IN BOOLEAN Success, IN BOOLEAN Failure)
 
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)
 
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)
 
NTSTATUS NTAPI RtlGetAce (IN PACL Acl, IN ULONG AceIndex, OUT PVOID *Ace)
 
NTSTATUS NTAPI RtlAddAce (IN PACL Acl, IN ULONG AclRevision, IN ULONG StartingIndex, IN PVOID AceList, IN ULONG AceListLength)
 
NTSTATUS NTAPI RtlDeleteAce (IN PACL Acl, IN ULONG AceIndex)
 
NTSTATUS NTAPI RtlCreateAcl (IN PACL Acl, IN ULONG AclSize, IN ULONG AclRevision)
 
NTSTATUS NTAPI RtlQueryInformationAcl (IN PACL Acl, IN PVOID Information, IN ULONG InformationLength, IN ACL_INFORMATION_CLASS InformationClass)
 
NTSTATUS NTAPI RtlSetInformationAcl (IN PACL Acl, IN PVOID Information, IN ULONG InformationLength, IN ACL_INFORMATION_CLASS InformationClass)
 
BOOLEAN NTAPI RtlValidAcl (IN PACL Acl)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file acl.c.

Function Documentation

◆ RtlAddAccessAllowedAce()

NTSTATUS NTAPI RtlAddAccessAllowedAce ( IN OUT PACL  Acl,
IN ULONG  Revision,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid 
)

Definition at line 262 of file acl.c.

266{
268
269 /* Call the worker function */
270 return RtlpAddKnownAce(Acl,
271 Revision,
272 0,
274 Sid,
276}
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1133
_In_ ULONG Revision
Definition: rtlfuncs.h:1130
#define PAGED_CODE_RTL()
Definition: rtlp.h:16
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 ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:717

◆ RtlAddAccessAllowedAceEx()

NTSTATUS NTAPI RtlAddAccessAllowedAceEx ( IN OUT PACL  Acl,
IN ULONG  Revision,
IN ULONG  Flags,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid 
)

Definition at line 283 of file acl.c.

288{
290
291 /* Call the worker function */
292 return RtlpAddKnownAce(Acl,
293 Revision,
294 Flags,
296 Sid,
298}
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

◆ RtlAddAccessAllowedObjectAce()

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 at line 305 of file acl.c.

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}
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 ACCESS_ALLOWED_OBJECT_ACE_TYPE
Definition: setypes.h:725

◆ RtlAddAccessDeniedAce()

NTSTATUS NTAPI RtlAddAccessDeniedAce ( IN PACL  Acl,
IN ULONG  Revision,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid 
)

Definition at line 343 of file acl.c.

347{
349
350 /* Call the worker function */
351 return RtlpAddKnownAce(Acl,
352 Revision,
353 0,
355 Sid,
357}
#define ACCESS_DENIED_ACE_TYPE
Definition: setypes.h:718

◆ RtlAddAccessDeniedAceEx()

NTSTATUS NTAPI RtlAddAccessDeniedAceEx ( IN OUT PACL  Acl,
IN ULONG  Revision,
IN ULONG  Flags,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid 
)

Definition at line 364 of file acl.c.

369{
371
372 /* Call the worker function */
373 return RtlpAddKnownAce(Acl,
374 Revision,
375 Flags,
377 Sid,
379}

◆ RtlAddAccessDeniedObjectAce()

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 at line 386 of file acl.c.

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}
#define ACCESS_DENIED_OBJECT_ACE_TYPE
Definition: setypes.h:726

◆ RtlAddAce()

NTSTATUS NTAPI RtlAddAce ( IN PACL  Acl,
IN ULONG  AclRevision,
IN ULONG  StartingIndex,
IN PVOID  AceList,
IN ULONG  AceListLength 
)

Definition at line 566 of file acl.c.

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}
@ Ace
Definition: card.h:12
#define ULONG_PTR
Definition: config.h:101
#define min(a, b)
Definition: monoChain.cc:55
NTSYSAPI BOOLEAN NTAPI RtlValidAcl(PACL Acl)
struct _ACE * PACE
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN NTAPI RtlFirstFreeAce(IN PACL Acl, OUT PACE *FirstFreeAce)
Definition: acl.c:20
VOID NTAPI RtlpAddData(IN PVOID AceList, IN ULONG AceListLength, IN PVOID Ace, IN ULONG Offset)
Definition: acl.c:50
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
Definition: rtltypes.h:993
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ WDFCOLLECTION _In_ ULONG Index
_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
#define ACCESS_MAX_MS_ACE_TYPE
Definition: setypes.h:731
#define ACL_REVISION4
Definition: setypes.h:45
#define ACL_REVISION3
Definition: setypes.h:44
#define ACCESS_MAX_MS_V2_ACE_TYPE
Definition: setypes.h:721
#define ACCESS_MAX_MS_V3_ACE_TYPE
Definition: setypes.h:723
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ RtlAddAuditAccessAce()

NTSTATUS NTAPI RtlAddAuditAccessAce ( IN PACL  Acl,
IN ULONG  Revision,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid,
IN BOOLEAN  Success,
IN BOOLEAN  Failure 
)

Definition at line 424 of file acl.c.

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}
@ Success
Definition: eventcreate.c:712
#define SYSTEM_AUDIT_ACE_TYPE
Definition: setypes.h:719
#define FAILED_ACCESS_ACE_FLAG
Definition: setypes.h:754
#define SUCCESSFUL_ACCESS_ACE_FLAG
Definition: setypes.h:753

◆ RtlAddAuditAccessAceEx()

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 at line 452 of file acl.c.

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}

◆ RtlAddAuditAccessObjectAce()

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 at line 480 of file acl.c.

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}
#define SYSTEM_AUDIT_OBJECT_ACE_TYPE
Definition: setypes.h:727

◆ RtlCreateAcl()

NTSTATUS NTAPI RtlCreateAcl ( IN PACL  Acl,
IN ULONG  AclSize,
IN ULONG  AclRevision 
)

Definition at line 677 of file acl.c.

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}
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define MAXUSHORT
Definition: typedefs.h:83
#define MIN_ACL_REVISION
Definition: setypes.h:46
#define MAX_ACL_REVISION
Definition: setypes.h:47

◆ RtlDeleteAce()

NTSTATUS NTAPI RtlDeleteAce ( IN PACL  Acl,
IN ULONG  AceIndex 
)

Definition at line 643 of file acl.c.

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}
VOID NTAPI RtlpDeleteData(IN PVOID Ace, IN ULONG AceSize, IN ULONG Offset)
Definition: acl.c:69
_In_ ULONG AceIndex
Definition: rtlfuncs.h:1862

◆ RtlFirstFreeAce()

BOOLEAN NTAPI RtlFirstFreeAce ( IN PACL  Acl,
OUT PACE FirstFreeAce 
)

Definition at line 20 of file acl.c.

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}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
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 for
Definition: utility.h:88
USHORT AceSize
Definition: ms-dtyp.idl:212
ACE_HEADER Header
Definition: rtltypes.h:994

Referenced by RtlAddAce(), RtlDeleteAce(), RtlpAddKnownAce(), RtlpAddKnownObjectAce(), and RtlQueryInformationAcl().

◆ RtlGetAce()

NTSTATUS NTAPI RtlGetAce ( IN PACL  Acl,
IN ULONG  AceIndex,
OUT PVOID Ace 
)

Definition at line 522 of file acl.c.

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}
Definition: Header.h:9
void * PVOID
Definition: typedefs.h:50

◆ RtlpAddData()

VOID NTAPI RtlpAddData ( IN PVOID  AceList,
IN ULONG  AceListLength,
IN PVOID  Ace,
IN ULONG  Offset 
)

Definition at line 50 of file acl.c.

54{
55 /* Shift the buffer down */
56 if (Offset > 0)
57 {
59 Ace,
60 Offset);
61 }
62
63 /* Copy the new data in */
65}
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by RtlAddAce().

◆ RtlpAddKnownAce()

NTSTATUS NTAPI RtlpAddKnownAce ( IN PACL  Acl,
IN ULONG  Revision,
IN ULONG  Flags,
IN ACCESS_MASK  AccessMask,
IN PSID  Sid,
IN UCHAR  Type 
)

Definition at line 90 of file acl.c.

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}
Type
Definition: Type.h:7
unsigned short WORD
Definition: ntddk_ex.h:93
NTSYSAPI BOOLEAN WINAPI RtlCopySid(DWORD, PSID, PSID)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI BOOLEAN NTAPI RtlValidSid(IN PSID Sid)
Definition: sid.c:21
struct _ACE 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_REVISION_MISMATCH
Definition: ntstatus.h:325
Definition: se.h:15
#define VALID_INHERIT_FLAGS
Definition: setypes.h:751
unsigned char BYTE
Definition: xxhash.c:193

Referenced by RtlAddAccessAllowedAce(), RtlAddAccessAllowedAceEx(), RtlAddAccessAllowedObjectAce(), RtlAddAccessDeniedAce(), RtlAddAccessDeniedAceEx(), RtlAddAccessDeniedObjectAce(), RtlAddAuditAccessAce(), RtlAddAuditAccessAceEx(), and RtlAddAuditAccessObjectAce().

◆ RtlpAddKnownObjectAce()

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 at line 158 of file acl.c.

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}
if(dx< 0)
Definition: linetemp.h:194
#define ACE_INHERITED_OBJECT_TYPE_PRESENT
Definition: setypes.h:806
#define SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
Definition: setypes.h:738
#define ACE_OBJECT_TYPE_PRESENT
Definition: setypes.h:805

Referenced by RtlAddAccessAllowedObjectAce(), RtlAddAccessDeniedObjectAce(), and RtlAddAuditAccessObjectAce().

◆ RtlpDeleteData()

VOID NTAPI RtlpDeleteData ( IN PVOID  Ace,
IN ULONG  AceSize,
IN ULONG  Offset 
)

Definition at line 69 of file acl.c.

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}
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Referenced by RtlDeleteAce().

◆ RtlQueryInformationAcl()

NTSTATUS NTAPI RtlQueryInformationAcl ( IN PACL  Acl,
IN PVOID  Information,
IN ULONG  InformationLength,
IN ACL_INFORMATION_CLASS  InformationClass 
)

Definition at line 708 of file acl.c.

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}
_In_ FILTER_INFORMATION_CLASS InformationClass
Definition: fltkernel.h:1713
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
struct _ACL_REVISION_INFORMATION * PACL_REVISION_INFORMATION
struct _ACL_SIZE_INFORMATION * PACL_SIZE_INFORMATION
@ AclSizeInformation
Definition: winnt_old.h:1117
@ AclRevisionInformation
Definition: winnt_old.h:1116

◆ RtlSetInformationAcl()

NTSTATUS NTAPI RtlSetInformationAcl ( IN PACL  Acl,
IN PVOID  Information,
IN ULONG  InformationLength,
IN ACL_INFORMATION_CLASS  InformationClass 
)

Definition at line 785 of file acl.c.

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}
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690

Referenced by SetAclInformation().

◆ RtlValidAcl()

BOOLEAN NTAPI RtlValidAcl ( IN PACL  Acl)

Definition at line 837 of file acl.c.

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}
#define DPRINT1
Definition: precomp.h:8
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
struct _ACL ACL
struct _ACE_HEADER ACE_HEADER
struct _ACE_HEADER * PACE_HEADER
struct _KNOWN_OBJECT_ACE KNOWN_OBJECT_ACE
struct _KNOWN_OBJECT_ACE * PKNOWN_OBJECT_ACE
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
BYTE Revision
Definition: ms-dtyp.idl:199
BYTE SubAuthorityCount
Definition: ms-dtyp.idl:200
uint32_t * PULONG
Definition: typedefs.h:59
#define ACCESS_MIN_MS_OBJECT_ACE_TYPE
Definition: setypes.h:724
#define ACCESS_ALLOWED_COMPOUND_ACE_TYPE
Definition: setypes.h:722
#define SID_MAX_SUB_AUTHORITIES
Definition: setypes.h:482
struct _SID * PISID
#define SID_REVISION
Definition: setypes.h:481
#define ACCESS_MAX_MS_OBJECT_ACE_TYPE
Definition: setypes.h:729