Order of ACEs in a DACL

When a process tries to access a securable object, the system steps through the ACEs in the object's DACL until it finds ACEs that allow or deny the requested access. The access rights that a DACL allows a user could vary depending on the order of ACEs in the DACL. Consequently, Microsoft defines a preferred order for ACEs in the DACL of a securable object. The preferred order provides a simple framework that makes it easy to be assured that an access-denied ACE actually denies access. For more information about the system's algorithm for checking access, see Checking a Thread's Access to an Object.

For Windows NT versions 4.0 and earlier, the preferred order of ACEs is simple: In a DACL, all access-denied ACEs should precede any access-allowed ACEs. The SetEntriesInAcl function creates a DACL with ACEs in this order. However, the low-level functions for adding ACEs to a DACL do not enforce the preferred order. The AddAce function adds ACEs at a specified location in an ACL. Functions such as AddAccessAllowedAce add an ACE to the end of an ACL. It is the caller's responsibility to ensure that the ACEs are added in the preferred order.

The following diagram illustrates how the same ACEs can allow different access rights, depending on their order in the DACL. The system denies access to object A when it reads the access-denied ACE; but the out-of-order DACL for Object B causes the system to grant access without reading the access-denied ACE.

For Windows NT version 5.0 and later, the proper order of ACEs is more complicated because of the introduction of object-specific ACEs and automatic inheritance. When called for objects on Windows NT, the SetSecurityInfoEx and SetNamedSecurityInfoEx functions build an object's DACL using the preferred order. For objects on other systems, the ordering of access-control information depends on the provider.

The following describes the preferred order for Windows NT version 5.0 and later.

Of course, not all ACE types are required in an ACL.

Functions such as AddAccessAllowedAceEx and AddAccessAllowedObjectAce add an ACE to the end of an ACL. It is the caller's responsibility to ensure that the ACEs are added in the proper order.