How Windows 2000 Propagates Security Descriptors

This article explains how Microsoft Windows 2000 handles security descriptor propagation across directory trees in both the NTFS file system and Active Directory. It outlines the core architecture of Windows 2000 inheritance, detailing how Access Control Entries (ACEs) are inherited from parent containers, the function of inheritance flags, the role of background propagation mechanisms such as the Security Descriptor Propagator (SDPROP), and how the operating system maintains the canonical ordering of permissions.

The Dynamic Inheritance Model

Windows 2000 introduced a dynamic inheritance model to replace the static inheritance mechanism used in Windows NT 4.0. When an administrator modifies a security descriptor on a parent container, the system automatically cascades inheritable permissions down through child containers and leaf objects without requiring a manual recalculation of every explicit permission.

Security descriptors store access rights in Discretionary Access Control Lists (DACLs). Dynamic inheritance relies on distinct inheritance flags applied to individual ACEs:

  • CONTAINER_INHERIT_ACE (CI): Permits child containers (such as subfolders or Organizational Units) to inherit the ACE.
  • OBJECT_INHERIT_ACE (OI): Permits non-container child objects (such as files or leaf directory objects) to inherit the ACE.
  • NO_PROPAGATE_INHERIT_ACE (NP): Restricts inheritance strictly to the immediate children, preventing the ACE from propagating to grandchildren and deeper descendants.
  • INHERIT_ONLY_ACE (IO): Prevents the ACE from applying to the parent container itself, applying it only to downstream child objects.
  • INHERITED_ACE (ID): Indicates that an ACE was received from an ancestor rather than explicitly defined on the object itself.

Propagation in Active Directory (SDPROP)

In Active Directory, the propagation of security descriptors across the directory information tree (DIT) is managed asynchronously by an internal system task known as the Security Descriptor Propagator (SDPROP).

  1. Event Notification and Queuing: When a security descriptor on a container object changes, the Local Security Authority Subsystem Service (LSASS) marks the container as modified and places an event on the SDPROP queue within the directory service process (ntds.dit).
  2. Tree Traversal: SDPROP runs as a background thread, activating automatically on change notifications or during periodic consistency checks (by default, every eight hours). The thread traverses down the hierarchy starting from the modified container.
  3. ACE Synthesis: For each child object encountered, SDPROP evaluates the parent's inheritable ACEs alongside the child's existing explicit ACEs to compute a new effective DACL.
  4. Database Commit: The newly computed DACL is written directly to the child's nTSecurityDescriptor attribute, marking the newly derived entries with the INHERITED_ACE flag. If the child is itself a container, the process continues down the tree.

Propagation in the NTFS File System

In the NTFS file system, propagation functions through the local Security Reference Monitor (SRM) and Win32 application programming interfaces, such as SetNamedSecurityInfo and SetEntriesInAcl.

When an administrator applies permission changes to an NTFS folder via the Windows Explorer interface, the Explorer shell initiates a recursive tree-walk across the underlying file system. The system reads the updated parent DACL, filters for inheritable entries, and applies them to all subordinate files and folders. If the inheritance process is initiated programmatically via low-level kernel routines, child objects recalculate their descriptors upon direct access or through recursive API calls.

Blocking Inheritance

Propagation continues down the tree until it reaches a leaf node or encounters an object configured to block inheritance.

Windows 2000 implements an inheritance blocking flag within the control flags of the security descriptor called SE_DACL_PROTECTED. When this flag is set on a child object:

  • The child object ignores any inheritable ACEs from its parent.
  • The propagation engine skips modifying the protected object’s DACL.
  • Descendants of the protected object inherit permissions from the protected child, not from the ancestors higher up the tree.

When inheritance is blocked, administrators choose either to convert currently inherited ACEs into explicit ACEs (retaining access) or to strip all inherited ACEs entirely, leaving only previously explicit entries.

Canonical Ordering During Propagation

To maintain security consistency and prevent privilege escalation, the Windows 2000 propagation engine strictly enforces canonical ordering when it rebuilds an object's DACL. ACEs are ordered as follows:

  1. Explicit Deny
  2. Explicit Allow
  3. Inherited Deny
  4. Inherited Allow

When an updated ACE propagates down the tree, the engine extracts existing inherited entries, strips obsolete ones, appends the newly inherited entries, and reorders the entire DACL into canonical form. This guarantees that explicit denials always take precedence over explicit grants, and explicit permissions consistently override inherited permissions across all branches of the directory tree.