You exported users from Active Directory with ldifde, dumped an OpenLDAP tree with
ldapsearch, or inherited a directory-export.ldif from whoever ran the servers before you.
Open it in a text editor and it's readable-ish: lines like cn: Jane Doe and
mail: jane@example.com, grouped into blocks. But keep scrolling and you'll hit values that are
suddenly gibberish after a double colon, lines that wrap strangely, and blocks that say
changetype: modify instead of holding any actual data. This article explains what an LDIF file
actually is, what's inside one, and why parts of it look nothing like the rest.
What an LDIF file is
LDIF stands for LDAP Data Interchange Format, standardized by the IETF as RFC 2849. It's the
universal export/import format for directory servers — the systems that hold an organization's
users, groups, and computers. OpenLDAP, 389 Directory Server, Apache Directory, and Active
Directory (via Microsoft's ldifde command-line tool) all read and write it, which is why almost
any directory migration, backup, or audit eventually produces a .ldif (or .ldf, the extension
ldifde prefers) file.
An LDIF file is plain text. Each entry — one user, group, or other directory object — is one block, and blank lines separate the blocks:
version: 1
dn: uid=jdoe,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
uid: jdoe
cn: Jane Doe
sn: Doe
mail: jane.doe@example.com
telephoneNumber: +1 555 111 2222
memberOf: cn=engineering,ou=Groups,dc=example,dc=com
memberOf: cn=vpn-users,ou=Groups,dc=example,dc=com
Two things to notice. The optional version: 1 line opens the file (RFC 2849 only ever defined
version 1). And every entry starts with a dn: line — the distinguished name, the entry's
unique path in the directory tree, read right-to-left from the domain (dc=example,dc=com) down
through organizational units (ou=People) to the object itself (uid=jdoe).
Attributes, and why some repeat
Every other line is one attribute value: name: value. Common ones for a person entry are cn
(common name), sn (surname), givenName, mail, telephoneNumber, and objectClass (which
schema the entry follows). Unlike a spreadsheet column, an LDAP attribute can hold several
values — a user in five groups has five separate memberOf lines. That's normal, not a bug in
your export; any tool turning LDIF into a table has to decide how to combine them.
Attribute names can also carry options after a semicolon, like displayName;lang-en: for a
language-tagged variant. They're the same underlying attribute — just a flavored copy.
The three value shapes
A value can appear three ways, and the separator tells you which:
attr: value— a plain value, as-is.attr:: SGVsbG8=— a base64-encoded value. LDIF only allows plain printable ASCII after a single colon, so anything with accented characters (José García), non-Latin scripts, leading spaces, or raw binary gets base64-encoded and flagged with the double colon. The bytes underneath are almost always UTF-8 text — decode them and the name reads normally again.attr:< file:///path/photo.jpg— a URL reference: the value lives in an external file rather than inline. Common forjpegPhotoor certificates.
One more formatting rule: LDIF wraps long lines. A physical line starting with a single space
is a continuation of the previous line — a parser has to strip that space and rejoin the pieces
before the value (or the base64 blob) means anything. Lines starting with # are comments.
Content entries vs. change records
Here's the part that surprises people: an LDIF file can hold two fundamentally different things.
A content entry is a snapshot of an object, like the example above. A change record is an
instruction — it has a changetype: line (add, modify, delete, or modrdn) and
describes an edit to apply to the directory:
dn: uid=jdoe,ou=People,dc=example,dc=com
changetype: modify
replace: telephoneNumber
telephoneNumber: +1 555 999 8888
-
A changetype: add record carries the full object, so it's equivalent to a content entry. But a
modify record only names the attributes being patched, a delete record has no data at all,
and modrdn just renames the entry. None of those are rows of data — which is why a converter
turning LDIF into a table keeps add records and skips the rest (ideally telling you how many
it skipped).
Getting the data out of an LDIF file
None of this is something you want to untangle by hand — base64-decoding names one at a time and
rejoining folded lines gets old fast, and renaming .ldif to .csv just dumps raw syntax into
one Excel column. What you actually want is a flat table: one row per entry, dn first, one
column per attribute, multi-valued attributes joined into a readable cell. That's exactly what
the free LDIF to CSV converter here does — it unfolds lines, decodes
base64 as UTF-8, skips the change records with a count, and exports a clean CSV, XLSX, or JSON,
entirely in your browser. See
How to convert LDIF to CSV for the step-by-step version.