Windows 2000 NTDS.dit Database Structure
The ntds.dit file is the core database file responsible
for storing all Active Directory objects, attributes, and schema
information in Microsoft Windows 2000. Operating on the Extensible
Storage Engine (ESE), also known as JET Blue, this file organizes
hierarchical directory data into a structured, relational format using
database pages, B-trees, and specialized tables. Understanding its
internal architecture involves examining the underlying storage engine,
the primary tables that hold the directory information, and the indexing
mechanisms that enable rapid query resolution.
The Underlying Engine: ESE (JET Blue)
In Windows 2000, Active Directory relies on the Extensible Storage
Engine (ESE98 / JET Blue) to manage the physical reading and writing of
ntds.dit.
- Database Page Size: Windows 2000 uses a fixed page size of 4 KB (4,096 bytes). All data, records, and index nodes reside on these 4 KB pages.
- B-Tree Structure: ESE organizes tables and indices into balanced trees (B-trees). This layout allows the database engine to locate records efficiently with minimal disk I/O operations.
- Transaction Logging: Data modifications are written
to circular transaction logs (
edb.log) before being committed to the physicalntds.ditfile to ensure ACID (Atomicity, Consistency, Isolation, Durability) compliance.
Core Tables in the Windows 2000 NTDS.dit
Unlike later versions of Windows Server, which introduced additional
tables for security descriptor single-instancing, the Windows 2000
implementation of ntds.dit primarily consists of three key
tables:
1. The Data Table
The Data Table is the largest and most critical table in the database, containing virtually all directory objects (users, computers, organizational units, and schema definitions).
- Row Representation: Each row represents a single directory object or a phantom record (a reference to an object outside the local domain partition).
- Column Representation: Each column represents an attribute defined in the Active Directory schema. Because objects do not utilize every available attribute, the Data Table is heavily sparse. ESE handles this efficiently by only allocating storage space for columns that contain values.
- Distinguished Name Tag (DNT): Every record is assigned an internal unique 32-bit integer called the DNT. This acts as the primary key for the row.
- Parent Distinguished Name Tag (PDNT): To create the hierarchical tree structure of Active Directory within a flat relational table, each row includes a PDNT referencing the DNT of its parent container.
- Object Flag (Obj): A binary column indicating
whether the record represents a real Active Directory object
(
1) or an internal phantom record (0).
2. The Link Table
The Link Table manages linked attributes—specifically inter-object relationships and multi-valued attributes where one object references another (such as group memberships).
- Link DNT: Stores the DNT of the source object (e.g., the group).
- Backlink DNT: Stores the DNT of the target object (e.g., the user account).
- Link Base: Identifies the specific attribute type
that defines the relationship (e.g., the pair representing
memberandmemberOf). - This decoupled design prevents individual rows in the Data Table from becoming excessively large when an object has thousands of linked relationships.
3. The Hidden Table
The Hidden Table is an internal administrative table used exclusively by the ESE engine. It contains engine metadata, database creation details, schema version tracking, and synchronization markers necessary for database recovery and integrity verification.
Attribute and Security Storage
- Data Types: Fixed-length attributes (such as integers and GUIDs) are stored directly in predefined columns. Variable-length data (such as strings) and binary data are stored in variable columns or Long Value (LV) trees if the data exceeds the capacity of a single page.
- Security Descriptors: In Windows 2000, security
descriptors (
nTSecurityDescriptor) are stored directly as binary values within each individual object's row in the Data Table. (Single-instance security descriptor storage via a dedicated SD Table was not implemented until Windows Server 2003).
Indexing Mechanisms
To ensure fast search operations, ntds.dit generates
indices directly over the Data and Link Tables using secondary
B-trees:
- Ancestors Index: An index built on the
ancestorsattribute to accelerate sub-tree searches by tracking all parent containers up to the root. - Object Class and GUID Indices: Dedicated indices that allow the system to quickly resolve specific object types or look up objects via their globally unique identifier.
- Attribute Indices: Any schema attribute configured with the search flag enabled creates an automatic index within the ESE database structure to optimize LDAP query performance.