The LDAP Data Interchange Format (LDIF) is a standard text-based file format designed for representing directory information in LDAP (Lightweight Directory Access Protocol) systems, as well as for describing modifications to directory entries such as additions, deletions, and updates.[1] Defined in RFC 2849, published by the Internet Engineering Task Force (IETF) in June 2000, LDIF provides a human-readable and machine-processable structure that facilitates the import and export of data between LDAP directory servers, enabling efficient bulk operations and data migration from legacy systems.[1] Originating from the University of Michigan's LDAP implementation in the 1990s, LDIF evolved to support both static directory entries and dynamic change records, with version 1 as the sole standardized version that mandates UTF-8 encoding and base64 for binary data to ensure portability across systems.[1]
LDIF files begin with a version specification (e.g., version: 1), followed by records separated by blank lines, each beginning with a distinguished name (dn:) that uniquely identifies an entry, and attribute-value pairs (attr: value) that define the directory object's properties, such as cn: [John Doe](/page/John_Doe) for a common name.[1] For modifications, LDIF uses change records that specify a changetype such as add, delete, modify, or modrdn (modify distinguished name), allowing precise control over updates without full entry recreation, which is essential for maintaining large-scale directories in enterprise environments.[1] The format supports line folding for long values (using a space prefix on continuation lines) and referencing external files via URLs, enhancing flexibility while adhering to LDAPv3 conventions outlined in related RFCs like 2251 (LDAPv3 protocol) and 2253 (distinguished names).[1] Widely adopted in tools from vendors like IBM, Microsoft, and Oracle, LDIF remains a foundational standard for LDAP administration, scripting, and interoperability, with no subsequent RFC superseding its core specification as of 2025.[2][3][4]
Overview and History
Definition and Purpose
The LDAP Data Interchange Format (LDIF) is a standard text-based file format designed for representing LDAP (Lightweight Directory Access Protocol) directory entries and updates in a human-readable and portable manner.[1] It enables the import and export of directory content between LDAP servers, as well as the description of modifications such as additions, deletions, attribute changes, and distinguished name (DN) renames.[1] This format uses simple attribute-value pairs to structure data, making it suitable for scripting, tool integration, and manual editing without requiring binary or proprietary encodings.[2]
The primary purposes of LDIF include building initial directory databases from scratch, performing bulk additions of entries, and applying targeted updates to existing directories without necessitating complete data exports.[5] It also supports interoperability by allowing data transfer between diverse LDAP implementations and legacy systems, facilitating migration, backups, and recovery processes in a vendor-neutral way.[2] For instance, tools like ldapadd and ldapmodify leverage LDIF files to populate or alter directories efficiently.[1]
In relation to LDAP, LDIF serves as an offline representation of LDAP objects—such as entries with their attributes—and corresponding operations, translating directly into protocol-level actions like add, delete, modify, and modrdn.[1] Its scope is limited to static directory information and change descriptions, excluding real-time interactive protocol exchanges, which are managed by the LDAP protocol itself.[5] This design ensures LDIF's role as a versatile intermediary for data management tasks in directory services.[2]
Historical Development
The LDAP Data Interchange Format (LDIF) was designed in the early 1990s by Tim Howes, Mark C. Smith, and Gordon Good at the University of Michigan as part of their LDAP reference implementation.[1] This effort was supported by the National Science Foundation under Grant No. NCR-9416667, aiming to provide a textual representation for directory data in LDAP systems.[1] The format first appeared in the University of Michigan's LDAP 3.3 release, where it was used primarily to describe static directory entries without support for change operations.[1]
In the late 1990s, as LDAP evolved toward version 3, LDIF was updated and extended to accommodate dynamic operations, including add, delete, modify, and modify DN changes, through the introduction of version 1.[1] This culminated in its formal standardization as a Proposed Standard in RFC 2849, authored by Gordon Good and published in June 2000 by the IETF LDAP Extensions Working Group.[1] The specification built on earlier internal drafts, such as draft-good-ldap-ldif from 1998, and emphasized LDIF's role in facilitating data interchange and replication across LDAPv3-compliant servers.[6]
Since its standardization in 2000, LDIF has maintained stability with no major revisions to its core format, though it has integrated with LDAP extensions for enhanced functionality.[1] A notable update came in RFC 4525 (June 2006), authored by Kurt D. Zeilenga, which extended LDIF to support the LDAP Modify-Increment operation for atomic integer increments in directory attributes.[7] This extension ensured LDIF's continued relevance in modern LDAPv3 implementations without altering the foundational structure.[7]
Key milestones in LDIF's adoption include its integration into OpenLDAP starting with the project's inception in 1998, derived directly from the University of Michigan LDAP codebase, where tools like ldapadd and ldapmodify rely on LDIF for entry management.[8] Microsoft incorporated LDIF support in [Active Directory](/page/Active Directory) with the release of Windows 2000 in 2000, providing the ldifde command-line tool for importing and exporting directory objects.[3] Similarly, Oracle Internet Directory adopted LDIF for schema and data operations around the same period, as documented in early administration guides, while the open-source 389 Directory Server and its commercial counterpart, Red Hat Directory Server, have utilized LDIF for configuration and migration since their initial releases in the early 2000s.[4] These adoptions solidified LDIF as a de facto standard for LDAP data handling across open-source and commercial directory services.
Record Structure
The LDAP Data Interchange Format (LDIF) organizes data into a sequence of records within a plain text file, where each record represents either a static directory entry or a dynamic change operation to the directory. Records are delimited by blank lines, consisting of two consecutive line separators (SEP, defined as CRLF or LF), ensuring clear separation between individual entries or modifications. This structure allows LDIF files to be human-readable and machine-parsable, facilitating the import, export, and bulk transfer of directory information across LDAP systems.[1]
The LDIF file must begin with the version header "version: 1" to indicate compliance with LDIF version 1. Following the version header, each record begins with a distinguished name specification ("dn:") followed by attribute-value pairs for content records or a changetype declaration for change records, and concludes with a blank line. Comments can be inserted anywhere in the file as lines starting with a "#" character, which are ignored by parsers to allow for annotations without affecting the data.[1]
To handle long lines, LDIF supports line folding, where a non-empty line may be continued by appending a line separator and a space; upon parsing, the leading space of the continuation line is discarded, and the lines are concatenated to form the complete value. Content records describe complete directory entries by listing the DN and one or more attribute-value specifications, representing the static state of an entry, whereas change records outline modifications such as additions or deletions, starting with the target DN, optional controls, and a "changetype:" line specifying the operation type. This distinction enables LDIF to serve both representational and operational purposes in directory management.[1]
Fields and Attributes
In LDIF records, fields represent the components of LDAP directory entries, consisting of attribute descriptions followed by their values, which map directly to LDAP directory elements. The mandatory first field is the distinguished name (dn), which serves as the unique identifier for the entry in the directory hierarchy. It follows the format "dn: ", where the distinguished name is a string compliant with LDAP naming conventions, such as "dn: cn=John Doe,ou=People,dc=example,dc=com". For distinguished names containing characters that are unsafe in LDIF (like line breaks or leading spaces), base64 encoding is used by prefixing the value with "::", ensuring safe representation without altering the original data.[1]
The objectClass field defines the type and structure of the entry by specifying the object classes to which it belongs, adhering to the LDAP schema. It is multi-valued, allowing multiple instances of the field, each on a separate line, such as "objectClass: inetOrgPerson" or "objectClass: organizationalPerson". This enables an entry to inherit attributes and behaviors from multiple classes, with the order of listing not implying any hierarchy or precedence.[1]
Standard attributes in LDIF capture common directory information, formatted as ": " for textual values or ":: " for binary or unsafe content. Examples include CommonName (cn) for a person's or object's name, such as "cn: John Doe"; Surname (sn) for the family name, like "sn: Doe"; OrganizationalUnit (ou) for departmental grouping, e.g., "ou: People"; DomainComponent (dc) for domain breakdown in the naming context, such as "dc: example"; and UserPassword (userPassword) for credential storage, often base64-encoded for security, as in "userPassword:: ". These attributes directly correspond to LDAP attribute types defined in relevant schemas.[1]
Multi-valued attributes are represented by repeating the attribute name on successive lines, each with a distinct value, such as multiple "cn: " entries for an entry with aliases; the order of these values is not preserved during processing. This mechanism supports LDAP's flexible data model without requiring special syntax.[1]
Optional fields include controls, which extend LDIF for LDAP-specific operations or server interactions, formatted as "control: [criticality] [value]". For instance, "control: 1.2.840.113556.1.4.805 true" specifies a control with an object identifier (OID), optional criticality flag, and value if needed. These are placed after standard attributes but before the record separator.[1]
Field rules in LDIF ensure consistency and portability: attribute names (descriptions) are case-insensitive, aligning with LDAP conventions, while values are UTF-8 encoded strings. Single-valued attributes should not have duplicate entries unless the underlying schema permits multi-valued semantics, though LDIF syntax allows repeats that may be validated by the directory server. No leading or trailing spaces are permitted in values unless explicitly part of the data, and empty values are indicated by a colon with no following content.[1]
Syntax and Encoding
Character Handling Rules
In the LDAP Data Interchange Format (LDIF), character handling ensures that attribute values and distinguished names (DNs) are represented in a portable, text-based manner while preserving binary integrity through selective encoding. The core rules define a set of "safe" characters that can appear unencoded in inline strings, with all other cases requiring base64 encoding to avoid parsing ambiguities or data corruption. These rules are specified in the Augmented Backus-Naur Form (ABNF) grammar and accompanying notes in RFC 2849.[1]
The SAFE-CHAR production allows unencoded characters limited to 7-bit values (≤ 127 decimal) excluding the null byte (NUL, 0x00), line feed (LF, 0x0A), and carriage return (CR, 0x0D); this includes printable US-ASCII characters from 0x20 (space) to 0x7E (~), as well as certain control characters (e.g., 0x01-0x09, 0x0B-0x0C, 0x0E-0x1F). However, the initial character of an unencoded value must adhere to the stricter SAFE-INIT-CHAR production, which excludes leading spaces (0x20), colons (:, 0x3A), and less-than signs (<, 0x3C) from the allowable set, in addition to the exclusions in SAFE-CHAR. Trailing spaces in values are not explicitly forbidden but should prompt base64 encoding to prevent misinterpretation during line unfolding. Any value containing characters outside SAFE-CHAR—such as non-ASCII bytes (>127) or prohibited controls—must be base64 encoded, as must DNs or relative DNs (RDNs) violating analogous SAFE-UTF8-CHAR or SAFE-INIT-UTF8-CHAR rules for multi-byte sequences.[1]
All LDIF values, including those for DirectoryString attributes, DNs, and RDNs, must be encoded in valid UTF-8; implementations generating LDIF content are prohibited from producing non-UTF-8 data, though parsers may tolerate other encodings if encountered. Special cases mandate base64 encoding for values starting with a space or colon, as these would conflict with syntax delimiters (e.g., the colon separating attribute descriptions from values). Null bytes (0x00) are forbidden in unencoded values and require base64 if present in binary data, while other control characters (e.g., CR) outside SAFE-CHAR similarly necessitate encoding to maintain structural integrity.[1]
Unencoded values in LDIF prohibit NUL characters and support folding of long lines by inserting a line separator followed by a single space, which indicates continuation; parsers must discard exactly one leading space from each folded line when reconstructing the original value, ensuring no alteration to the content. This mechanism preserves value integrity without introducing extraneous characters. Parsers are required to strictly adhere to the ABNF in RFC 2849 for attribute-value assertions, handling both unencoded SAFE-STRINGs and base64-encoded alternatives, including proper unfolding and UTF-8 validation.[1]
Unlike the LDAP wire format, which uses binary Abstract Syntax Notation One (ASN.1) Basic Encoding Rules (BER) for direct transmission of arbitrary octet strings without additional text constraints, LDIF introduces a textual encoding layer for file-based interchange, relying on base64 to embed unsafe or binary data portably across systems. This design prioritizes human readability and ASCII compatibility for safe subsets while enforcing encoding for broader character support.[1]
Base64 Encoding Mechanism
In the LDAP Data Interchange Format (LDIF), Base64 encoding serves to represent binary data or strings containing characters that are unsafe for direct inclusion in the text-based LDIF file, ensuring reliable parsing and transport without corruption.[1] This mechanism is particularly applied to attributes holding binary content, such as jpegPhoto, or to values violating safety rules, with the encoded form indicated by appending "::" to the attribute name followed by the Base64 data (e.g., jpegPhoto:: /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/).[1] For distinguished names (DNs), a similar notation uses dn:: to denote the Base64-encoded form when the DN includes unsafe characters or ends with a space.[1]
The encoding process begins by converting the input binary data or UTF-8 encoded string into groups of 6 bits, which are then mapped to a 64-character alphabet consisting of uppercase letters A-Z (values 0-25), lowercase letters a-z (26-51), digits 0-9 (52-61), the plus sign "+" (62), and the forward slash "/" (63).[9] If the input length is not a multiple of 3 bytes, padding is added using one or two "=" characters at the end to ensure the output length is a multiple of 4 characters, facilitating unambiguous decoding.[9] This aligns with the Base64 specification in RFC 2045, which LDIF adopts for compatibility with MIME standards, though LDIF imposes LDIF-specific rules: encoded values do not include internal line wrapping (unlike the optional 76-character limit in MIME Base64), and any line folding in long values follows LDIF's general continuation rules using a space followed by a separator line.[1][9]
Decoding reverses this process by mapping the Base64 characters back to 6-bit groups, reassembling them into 8-bit bytes, and discarding padding to recover the original binary or UTF-8 data; invalid inputs, such as non-alphabet characters or incorrect padding, result in parsing errors.[9] Encoding is triggered for binary attributes, non-UTF-8 content, or when values contain characters outside the SAFE-CHAR set (e.g., control characters like NUL or non-ASCII octets), as defined in the broader LDIF syntax rules.[1]
A key limitation of Base64 in LDIF is its expansion of data size by approximately 33%, as every 3 bytes of input produce 4 output characters, which reduces efficiency for large binary payloads and prioritizes machine parsing over human readability.[10]
Operations and Changes
Entry Records
Entry records in the LDAP Data Interchange Format (LDIF) provide a textual representation of static directory entries, capturing a complete snapshot of an LDAP entry's attributes and values. Each entry record begins with a mandatory "dn:" line that specifies the distinguished name (DN) of the entry, followed by one or more attribute-value pairs, including the required objectClass attribute(s). The structure adheres to the formal syntax defined as ldif-attrval-record = dn-spec SEP 1*attrval-spec, where SEP denotes a line separator (CR LF or LF), ensuring records are delimited clearly for parsing. This format allows entries to be exported from or imported into LDAP directories without specifying modification operations.[11]
Required elements in an entry record include the DN and at least one attribute-value specification, but compliance with LDAP schema rules is essential for validity. Every entry must include one or more objectClass attributes to define its type and allowable attributes, with structural object classes imposing mandatory attributes such as cn (common name) for person entries. While the LDIF specification itself does not enforce schema rules—leaving validation to the LDAP server or parser—non-compliant entries will fail during directory operations. For instance, an entry lacking a structural objectClass cannot be added successfully.[11][12][13]
In practice, entry records are primarily used for add operations when processed by LDAP tools. Tools like ldapadd interpret records without a changetype directive as implicit add requests, automatically generating the equivalent of a "changetype: add" operation to create new entries in the directory. This simplifies initial data loading or entry creation, as no explicit change type needs to be declared in the LDIF content.[14][15]
Bulk import is a common application of entry records, where multiple such records are included in a single LDIF file, each separated by a blank line, to populate directories or migrate data between servers. This approach supports efficient transfer of large datasets, such as during initial setup or synchronization, with the file starting with a "version: 1" directive for full compatibility. The version requirement ensures adherence to the LDIF standard, preventing parsing issues in tools expecting the defined syntax.[11]
Change Record Types
Change records in LDIF are designed to represent LDAP update operations, distinguishing them from static entry records by including a mandatory changetype field that specifies the type of modification: add, delete, modify, modrdn, or moddn. This field must appear after the dn: line in each change record and determines the structure and processing of the subsequent lines. Unlike entry records, which describe complete directory objects, change records focus on atomic updates to existing or new entries, with each record processed independently to ensure no partial application of changes.[1]
The add change type creates a new directory entry and follows a structure similar to an entry record, but prefixed with changetype: add. It requires the dn: followed by one or more attribute-value specifications (attrval-spec), listing all mandatory and optional attributes for the entry. If the entry already exists, the operation fails, preventing overwrites. For example:
dn: cn=Example User,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
cn: Example User
sn: User
dn: cn=Example User,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
cn: Example User
sn: User
This format ensures the new entry is fully defined before addition.[1]
A delete change record is the simplest form, consisting only of the dn: line and changetype: delete, with no additional attributes or values required. It removes the entire entry specified by the distinguished name, provided the entry has no subordinate entries (i.e., it is a leaf entry). If the entry has subordinates, the operation fails unless specific server extensions or controls enable recursive deletion of the subtree.[1][16] This minimal structure reflects the operation's intent to eliminate the entry completely. For instance:
dn: cn=Example User,dc=example,dc=com
changetype: delete
dn: cn=Example User,dc=example,dc=com
changetype: delete
The absence of further content emphasizes the irreversible nature of the deletion.[1]
The modify change type alters attributes of an existing entry and begins with dn: and changetype: [modify](/page/Change), followed by one or more modification specifications (mod-spec). Each mod-spec starts with an operation keyword—add:, delete:, or replace:—followed by the attribute type, optional values, and ends with a dash line (-) to terminate the modifications. The add operation appends values to an attribute; delete removes specified values or the entire attribute if no values are listed; replace deletes existing values and adds new ones. The sequence of mod-spec blocks must conclude with a standalone - line. An example might look like:
dn: cn=Example User,dc=example,dc=com
changetype: modify
replace: description
description: Updated description
-
add: mail
mail: [email protected]
-
dn: cn=Example User,dc=example,dc=com
changetype: modify
replace: description
description: Updated description
-
add: mail
mail: [email protected]
-
This allows precise, incremental updates without requiring a full entry rewrite.[1]
For renaming or moving an entry, the modrdn (or equivalently moddn) change type is used, starting with dn:, changetype: modrdn, newrdn: (the new relative distinguished name), and deleteoldrdn: 0 or 1 (indicating whether to remove the old RDN attributes from the entry). Optionally, newsuperior: specifies a new parent entry for moving the subtree. If deleteoldrdn: 1, the old RDN components are deleted; otherwise, they persist as non-distinguishing attributes. Without newsuperior:, the entry remains in the same parent. A sample record is:
dn: cn=Old Name,ou=people,dc=example,dc=com
changetype: modrdn
newrdn: cn=New Name
deleteoldrdn: 1
newsuperior: ou=users,dc=example,dc=com
dn: cn=Old Name,ou=people,dc=example,dc=com
changetype: modrdn
newrdn: cn=New Name
deleteoldrdn: 1
newsuperior: ou=users,dc=example,dc=com
This supports both simple renames and hierarchical moves.[1]
Optional LDAP controls can be included in any change record via control: lines immediately before the changetype, specifying an OID, criticality (true or false), and optional value in Base64 if needed. These extend operations, such as tree-wide deletes, but are ignored if unsupported by the server or in LDAPv2 contexts. Each change record maintains atomicity, meaning the entire record succeeds or fails as a unit, with no intermediate states applied.[1]
Common Use Cases
LDIF serves as a versatile text-based format for managing LDAP directory data, enabling efficient handling of entries and modifications in various operational contexts. Defined in RFC 2849, it supports both static directory content and dynamic change descriptions, making it suitable for administrative tasks that require portability and readability.[1]
Directory initialization represents a primary use case, where administrators bulk load LDIF files to populate empty LDAP servers with initial entries, such as user databases or organizational structures. This method efficiently constructs the Directory Information Tree (DIT) by defining root entries and adding large volumes of data in a single operation, often preferred over individual LDAP adds for scalability.[17][4][18]
Data migration frequently employs LDIF to transfer directory content between servers or implementations, preserving hierarchical structure and attributes. The process typically involves exporting data from the source server—generating an LDIF representation—and importing it into the target, which minimizes disruptions and ensures compatibility across different LDAP vendors.[18][4][19]
Update scripting leverages LDIF's change record capabilities for automated batch modifications, such as resetting passwords across multiple users or appending attributes like telephone numbers to existing entries. By specifying operations like changetype: modify in scripts, administrators can apply consistent updates to directories without repetitive manual interventions, enhancing efficiency in maintenance tasks.[18]
Backup and restore operations utilize LDIF to serialize the entire directory state into a compact, text-based archive, offering advantages over binary formats in terms of version control and cross-platform recovery. This approach allows for straightforward archival of data and configuration, with restoration achieved by re-importing the LDIF file to rebuild the directory.[17][19][18]
In testing and development, LDIF facilitates the rapid creation of sample directories or simulation of change scenarios in isolated environments, supporting prototyping and validation without affecting production systems. Developers often generate LDIF files to mimic real-world data sets, enabling iterative testing of LDAP applications or schema adjustments.[18][4]
LDIF also enables interoperability by serving as an intermediate format for exchanging data between LDAP and non-LDAP systems, such as converting CSV exports to LDIF for directory imports or vice versa. This text-oriented structure simplifies integration with tools and databases that lack native LDAP support, promoting data flow in heterogeneous environments.[1][18]
Several open-source and commercial directory servers provide built-in tools for generating, importing, and exporting data in LDIF format, facilitating interoperability across LDAP environments. These tools typically handle bulk operations efficiently, such as populating directories or migrating data between systems. Client applications and programming libraries further extend LDIF support for editing, parsing, and programmatic manipulation.
In the OpenLDAP suite, the ldapadd and ldapmodify utilities enable importing and updating directory entries from LDIF files, while ldapsearch with the -L option exports query results in LDIF format.[8] Additionally, slapadd supports high-performance bulk addition of LDIF data to offline databases, bypassing network overhead for large-scale imports.[20]
Microsoft Active Directory includes the LDIFDE.exe command-line tool for importing and exporting directory objects in LDIF format, available in Windows environments starting from Windows 2000.)
Oracle Directory Server, including legacy Sun Java System Directory Server and Oracle Unified Directory, uses the dsadm command for LDIF-based import and export operations on stopped instances, allowing administrators to initialize or back up suffixes efficiently.[21][22]
Red Hat Directory Server, built on the 389 Directory Server project, integrates LDIF support through utilities like db2ldif for exporting databases to LDIF files and ldif2db for importing them, enabling data manipulation and migration in enterprise Linux setups.
Graphical client tools such as JXplorer provide LDIF import capabilities within its LDAP browser interface, allowing users to insert LDIF content under selected directory entries.[23] Similarly, Apache Directory Studio features a dedicated LDIF Editor for syntax-highlighted editing and content assistance when working with LDIF files.[24]
For programmatic use, the Java Naming and Directory Interface (JNDI) combined with LDAP providers supports LDIF-related operations through extensions like those in Spring LDAP for parsing and deserializing LDIF into objects.[25] In Python, the ldap3 module includes built-in LDIF parsing and generation functions compliant with RFC 2849, enabling seamless integration in scripts for directory automation.[26]
Most modern LDAPv3-compliant servers implemented after 2000 fully support LDIF version 1 as specified in RFC 2849, ensuring broad compatibility for data interchange.[1][27]
Examples and Standards
Illustrative Examples
A simple LDIF entry record demonstrates the addition of a basic directory entry, such as a person object, by specifying the distinguished name (DN) followed by attributes like object classes and common attributes. For instance, the following snippet adds an entry for Barbara Jensen:
dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
objectclass: top
objectclass: [person](/page/Person)
objectclass: organizationalPerson
[cn](/page/.cn): Barbara Jensen
sn: Jensen
telephoneNumber: +1 555 987-6543
dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
objectclass: top
objectclass: [person](/page/Person)
objectclass: organizationalPerson
[cn](/page/.cn): Barbara Jensen
sn: Jensen
telephoneNumber: +1 555 987-6543
Here, the dn line defines the entry's unique identifier within the directory hierarchy; each objectclass line declares the schema classes the entry adheres to (e.g., person for basic personal details); [cn](/page/.cn) provides the common name; sn the surname; and telephoneNumber a contact detail.[28]
Binary attributes, such as images, require special handling to embed non-text data safely. An example incorporates a JPEG photo using base64 encoding, indicated by the double colon (::) suffix on the attribute name:
dn: cn=Jennifer J Jensen, dc=example, dc=com
objectclass: [person](/page/Person)
sn: Jensen
jpegPhoto:: /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAIAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAhEAACAQMDBQAAAAAAAAAAAAABAgMABAUGIWGRkqGx0f/EABUBAQEAAAAAAAAAAAAAAAAAAAMF/8QAGhEAAgIDAAAAAAAAAAAAAAAAAAECEgMRkf/aAAwDAQACEQMRAD8AuvSssC5X2j1o0tJ1ZfO4mU1uV6jG1p5b1P/Z
dn: cn=Jennifer J Jensen, dc=example, dc=com
objectclass: [person](/page/Person)
sn: Jensen
jpegPhoto:: /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAIAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAhEAACAQMDBQAAAAAAAAAAAAABAgMABAUGIWGRkqGx0f/EABUBAQEAAAAAAAAAAAAAAAAAAAMF/8QAGhEAAgIDAAAAAAAAAAAAAAAAAAECEgMRkf/aAAwDAQACEQMRAD8AuvSssC5X2j1o0tJ1ZfO4mU1uV6jG1p5b1P/Z
The jpegPhoto:: line embeds the base64-encoded binary image data directly, preventing parsing issues with special characters.[28]
Multi-valued attributes allow multiple instances of the same attribute type within an entry, each on a separate line without delimiters. Consider an extension to the person entry with repeated description attributes:
dn: cn=Barbara J Jensen, dc=example, dc=com
objectclass: person
sn: Jensen
description: Manager in Product Development
description: Oversees software testing team
dn: cn=Barbara J Jensen, dc=example, dc=com
objectclass: person
sn: Jensen
description: Manager in Product Development
description: Oversees software testing team
Each description line adds a distinct value to the multi-valued attribute, enabling rich, non-unique metadata like job roles or notes.[28]
At the file level, LDIF files often begin with a version header and may include comments for documentation, followed by one or more records. A multi-record file example might import two entries:
# LDIF file for example directory population
version: 1
# First entry: Organizational unit
dn: ou=People, dc=example, dc=com
objectclass: organizationalUnit
ou: People
# Second entry: Person within the OU
dn: cn=John Doe, ou=People, dc=example, dc=com
objectclass: inetOrgPerson
cn: John Doe
sn: Doe
mail: [email protected]
# LDIF file for example directory population
version: 1
# First entry: Organizational unit
dn: ou=People, dc=example, dc=com
objectclass: organizationalUnit
ou: People
# Second entry: Person within the OU
dn: cn=John Doe, ou=People, dc=example, dc=com
objectclass: inetOrgPerson
cn: John Doe
sn: Doe
mail: [email protected]
The # lines are comments ignored during processing; version: 1 specifies the LDIF format version; the first record creates an organizational unit; the second adds a person with email via the mail attribute.[28]
Key RFCs and Specifications
The LDAP Data Interchange Format (LDIF) is formally specified in RFC 2849, published in June 2000 as a Proposed Standard by the Internet Engineering Task Force (IETF). This document defines LDIF version 1 as a standard text-based file format suitable for representing directory entry content and modifications to directory entries in LDAP systems, enabling bulk import, export, and synchronization of data between directory servers. It encompasses both content records for full directory entries and change records for operations such as add, delete, modify, and modify DN, providing a structured way to describe directory information or sets of changes.[29]
RFC 2849 specifies the syntax using Augmented Backus-Naur Form (ABNF) as defined in RFC 2234, outlining rules for LDIF structure to ensure interoperability. The top-level production is ldif-file = ldif-content / ldif-changes, where ldif-content = version-spec 1*(1SEP ldif-attrval-record) specifies directory entry content (with ldif-attrval-record = dn-spec SEP 1attrval-spec [SEP]), and ldif-changes = version-spec 1*(1*SEP ldif-change-record) specifies modification operations; an LDIF file contains either content records or change records, but not both. SEP denotes a line separator (CRLF), version-spec indicates the LDIF version (typically "1"), attrval-spec handles attribute-value pairs, and ldif-change-record details the changetype. Optional blank lines (additional SEPs) separate records for readability. The format mandates UTF-8 encoding for all strings to support international characters, with Base64 encoding (detailed in RFC 4648) required for binary data, non-UTF-8 values, or characters unsafe for textual representation, such as those containing non-printable ASCII or line breaks. This specification formalizes and extends an earlier, implementation-specific LDIF format originating from the University of Michigan's LDAP software in the mid-1990s, which was limited to ASCII and content-only representations without standardized change support.[29][30]
Since its publication, RFC 2849 has seen no major updates, reflecting its maturity as a stable standard, though errata are available to address minor issues like clarifications in ABNF parsing and encoding edge cases. The document's Proposed Standard status indicates it is suitable for widespread deployment, and its lack of obsoletion underscores its ongoing relevance in LDAPv3 environments. Related extensions, such as RFC 4525 (published June 2006 as an Informational RFC), enhance LDIF compatibility by defining the Modify-Increment operation, which allows incremental updates to numeric attributes via a dedicated "increment:" changetype in modify change records, expanding modification capabilities without altering the core LDIF syntax.[1][31]