How To Use LDIF Files to Make Changes to an OpenLDAP System
LDAP is a protocol for managing and interacting with directory services. The OpenLDAP project provides an LDAP-compliant directory service that can be used to store and provide an interface to directory data.
In this guide, we will discuss the LDIF file format that is used to communicate with LDAP directories. We will discuss the tools that you can use to process these files and modify the LDAP Directory Information Tree based on the commands specified.
Before starting this guide, you should have access to an OpenLDAP server. You can learn how to set up an OpenLDAP server here. You should be familiar with the basic terminology used when working with an LDAP directory service. This guide can be used to get more familiar with these topics.
LDIF, or the LDAP Data Interchange Format, is a text format for representing LDAP data and commands. When using an LDAP system, you will likely use the LDIF format to specify your data and the changes you wish to make to the LDAP DIT.
LDIF is meant to be able to describe any entry within an LDAP system, as well as any modifications that must take place. Because of this, the syntax is very precise and can initially seem somewhat complex. Using LDIF, LDAP changes are simple written within files with an arbitrary name and then fed into the LDAP system using one of the available management commands.
LDIF works using a basic key-value system, with one statement per-line. The key is on the left-hand side of a line followed by a colon (:) and a space. The space is important for the line to be read correctly. The value is then assigned on the right side. This format works well for LDAP's attribute-heavy syntax, but can also be used to issue commands and provide instructions on how the content should be interpreted.
Multiple lines can be used to provide long values for attribute by beginning the extra lines with a single space. LDAP will join these when processing the entry.
Adding Entries to the DIT
There are two main ways of specifying a new entry within an LDIF file. The best method for your needs depends on the types of other changes you need to coordinate with. The method you choose will dictate the tools and arguments you must use to apply the changes to the LDAP DIT (directory information tree).
Listing Entries to Add to the DIT
The most basic method of defining new entries to add to LDAP is to simply list the entries in their entirety, exactly as they would typically displayed using LDAP tools. This starts with the DN (distinguished name) where the entry will be created, after the
In the line above, we reference a few key-value pairs in order to construct the DN for our new entry. When setting attribute values, you must use the colon and space. When referencing attributes/values, an equal sign should be used instead.
In the simplest LDIF format for adding entries to a DIT, the rest of the entry is simply written out using this format beneath the DN definition. The necessary objectClass declarations and attributes must be set to construct a valid entry. For example, to create an organizational unit to contain the entries for the employees of our organization, we could use this:
dn: ou=People,dc=example,dc=com objectClass: organizationalUnit ou: People
You can add multiple entries in a single file. Each entry must be separated by at least one completely blank line:
dn: ou=People,dc=example,dc=com objectClass: organizationalUnit ou: People dn: ou=othergroup,dc=example,dc=com objectClass: organizationalUnit ou: othergroup
As you can see, this LDIF format mirrors almost exactly the format you would see when querying an LDAP tree for entries with this information. You can pretty much just write what you'd like the entry to contain verbatim.
Using "Changetype: Add" to Create New Entries
The second format that we will be looking at works well if you are making other modifications within the same LDIF file. OpenLDAP provides tools that can handle both additions and modifications, so if we are modifying other entries within the same file, we can flag our new entries as additions so that they are processed correctly.
This looks much like the method above, but we add
changetype: add directly below the DN specification. For instance, we could add a John Smith entry to a DIT that already contains the
ou=People,dc=example,dc=com structure using an LDIF like this:
dn: uid=jsmith1,ou=People,dc=example,dc=com changetype: add objectClass: inetOrgPerson description: John Smith from Accounting. John is the project manager of the building project, so contact him with any que stions. cn: John Smith sn: Smith uid: jsmith1
This is basically the format we've been using to describe entries thus far, with the exception of an additional line after the DN specification. Here, we tell LDAP that the change we are making is an entry creation. Since we are using the
changetype option, this entry can be processed by the
ldapmodify tool without a problem, allowing us to place modifications of other types in the same LDIF file. The
changetype option must come immediately after the DN specification.
Another thing to note above is the use of a multi-line value for the
description attribute. Since the lines that follow begin with a space, they will be joined with the space removed. Our first continuation line in our example contains an additional space, but that is part of the sentence itself, separating the words "project" and "manager".
As with the last section, each additional entry within the same file is separated by a blank line. Comments can be used by starting the line with a
# character. Comments must exist on their own line. For instance, if we wanted to add Sally in this same LDIF file, we could separate the two entries like this:
# Add John Smith to the organization dn: uid=jsmith1,ou=People,dc=example,dc=com changetype: add objectClass: inetOrgPerson description: John Smith from Accounting. John is the project manager of the building project, so contact him with any qu estions. cn: John Smith sn: Smith uid: jsmith1 # Add Sally Brown to the organization dn: uid=sbrown20,ou=People,dc=example,dc=com changetype: add objectClass: inetOrgPerson description: Sally Brown from engineering. Sally is responsibl e for designing the blue prints and testing the structural int egrity of the design. cn: Sally Brown sn: Brown uid: sbrown20
Processing Entry Additions
Now that we know how to construct LDIF files to add new entries, we need to actually process these with LDAP tools to add them to the DIT. The tool and/or arguments you use will depend on the form you chose above.
If you are using the simple entry format (without the
changetype setting), you can use the
ldapadd command or the
ldapmodify command with the
-a flag, which specifies an entry addition. You will either need to use a SASL method to authenticate with the LDAP instance (this is outside of the scope of this guide), or bind to an administrative account in your DIT and provide the required password.
For instance, if we stored our entries from the simple entry section in a file called
newgroups.ldif, the command we would need to process the file and add the new entries would look something like this:
- ldapadd -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f newgroups.ldif
You could also use the
ldapmodify -a combination for the same result:
- ldapmodify -a -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f newgroups.ldif
If you are using the second format, with the
changetype declaration, you will want to use the
ldapmodify command without the
-a flag. Since this command and format works for most other modifications, it is probably easier to use for most changes. If we stored the two new user additions within a file called
newusers.ldif, we could add it to our existing DIT by typing something like this:
- ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f newusers.ldif
This will allow you to add entries to your DIT at will. You can easily store many entries in a single LDIF file and populate your DIT in a single command.
Deleting Entries from the DIT
We had our first glimpse of the
changetype option in the last section. This option provides the method for specifying the high-level type of modification we wish to make. For an entry deletion, the value of this option is "delete".
Entry deletion is actually the most straight-forward change that you can perform because the only piece of information needed is the DN.
For instance, if we wanted to remove the
ou=othergroup entry from our DIT, our LDIF file would only need to contain this:
dn: ou=othergroup,dc=example,dc=com changetype: delete
To process the change, you can use the exact format used with
ldapmodify above. If we call the file with the deletion request
rmothergroup.ldif, we would apply it like this:
- ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f rmothergroup.ldif
This will remove the
ou=othergroup entry from the system immediately.
Modifying an Entry's Attributes
Modifying an entry's attributes is a very common change to make and is made possible by specifying
changetype: modify after the DN of the entry. The types of modifications you can make to attributes mostly mirror the modifications you can make to an entry itself. Because of this, the details of the type of requested attribute change are specified afterwards using additional directives.
Adding an Attribute to an Entry
For instance, you can add an attribute by using the
add: command after
changetype: modify. This should specify the attribute you wish to add. You would then set the value of the attribute like normal. So the basic format would be:
dn: entry_to_add_attribute changetype: modify add: attribute_type attribute_type: value_to_set
For instance, to add some email addresses to our accounts, we could have an LDIF file that looks like this:
dn: uid=sbrown20,ou=People,dc=example,dc=com changetype: modify add: mail mail: firstname.lastname@example.org dn: uid=jsmith1,ou=People,dc=example,dc=com changetype: modify add: mail mail: email@example.com mail: firstname.lastname@example.org
As you can see from the second entry, you can specify multiple additions at the same time. The
You can process this with
ldapmodify as normal. If the change is in the file
sbrownaddmail.ldif, you could type:
- ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f sbrownaddmail.ldif
Replacing the Value of an Attribute in an Entry
Another common change is to modify the existing value for an attribute. We can do this using the
replace: option below
This operates in almost the same way as the
add: command, but by default, removes every existing occurrence of the attribute from the entry and replaces it with the values defined afterwards. For instance, if we notice that our last
add: command had an incorrect email, we could modify it with the
replace command like this:
dn: uid=sbrown20,ou=People,dc=example,dc=com changetype: modify replace: mail mail: email@example.com
Keep in mind that this will replace every instance of
delete: option (described below) in combination with the attribute
add: option (described above).
If this change was stored in a file called
sbrownchangemail.ldif, we can replace Sally's email by typing:
- ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f sbrownchangemail.ldif
Delete Attributes from an Entry
If you wish to remove an attribute from an entry, you can use the
delete: command. You will specify the attribute you wish to delete as the value of the option. If you want to delete a specific instance of the attribute, you can specify the specific key-value attribute occurrence on the following line. Otherwise, every occurrence of that attribute in the entry will be removed.
For instance, this would delete every description attribute in John Smith's entry:
dn: uid=jsmith1,ou=People,dc=example,dc=com changetype: modify delete: description
However, this would delete only the email specified:
dn: uid=jsmith1,ou=People,dc=example,dc=com changetype: modify delete: mail mail: firstname.lastname@example.org
Since we gave John two email addresses earlier, the other email address should be left unchanged by this request.
If these changes were in files called
jsmithrmextramail.ldif, we could apply them by typing:
- ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f jsmithrmdesc.ldif
- ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f jsmithrmextramail.ldif
Specifying Multiple Attribute Changes
This is a good time to talk about specifying multiple attribute changes at the same time. For a single entry within an LDIF file, you can specify multiple attribute changes by separating them with a line populated only with the
- character. Following the separator, the attribute change type must be specified and the required attributes must be given.
For example, we could delete John's remaining email attribute, change his name to "Johnny Smith" and add his location by creating a file with the following contents:
dn: uid=jsmith1,ou=People,dc=example,dc=com changetype: modify delete: mail - replace: cn cn: Johnny Smith - add: l l: New York
To apply all of these changes in one command, we'd use the same
ldapmodify format we've been using all along:
- ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f multichange.ldif
Renaming and Moving Entries
changetype: modrdn option makes it possible to rename or move existing entries. After specifying the
dn: you wish to target, set the
changetype: modrdn option.
Renaming an Entry
Let's say that we mistyped Sally's username when we initially entered it into the system. Since that is used in the entry's DN, it can't simply be replaced with the
changetype: modify and
replace: options because the entry's RDN would be invalid. If her real username is
sbrown200, we could change the entry's DN, creating any necessary attributes along the way, with an LDIF file like this:
dn: uid=sbrown20,ou=People,dc=example,dc=com changetype: modrdn newrdn: uid=sbrown200 deleteoldrdn: 0
We could apply this change with this command:
- ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f fixsallydn.ldif
This would make the complete entry look something like this:
dn: uid=sbrown200,ou=People,dc=example,dc=com objectClass: inetOrgPerson description: Sally Brown from engineering. Sally is responsibl e for designing the blue prints and testing the structural int egrity of the design. cn: Sally Brown sn: Brown uid: sbrown20 uid: sbrown200 mail: email@example.com
As you can see, our DN has been adjusted to use the new attribute/value pair. The attribute has been added to the entry to make this possible.
You may have noticed two things in the example above. First, we set an option called
deleteoldrdn to "0". Secondly, the resulting entry has both
uid: sbrown20 and
deleteoldrdn option must be set when changing the DN of an entry. Setting
deleteoldrdn to "0" causes LDAP to keep the old attribute used in the DN alongside the new attribute in the entry. Sometimes this is what you want, but often you will want to remove the old attribute from the entry completely after the DN has changed. You can do that by setting
deleteoldrdn to "1" instead.
Let's pretend we made a mistake again and that Sally's actual username is
sbrown2. We can set
deleteoldrdn to "1" to remove the
sbrown200 instance that is currently used in the DN from the entry after the rename. We'll go ahead and include an additional
changetype: modify and
delete: pair to get rid of the other stray username,
sbrown20, since we kept that around during the first rename:
dn: uid=sbrown200,ou=People,dc=example,dc=com changetype: modrdn newrdn: uid=sbrown2 deleteoldrdn: 1 dn: uid=sbrown2,ou=People,dc=example,dc=com changetype: modify delete: uid uid: sbrown20
Apply the file like this:
- ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f fix2sallydn.ldif
This combination will not add a new username with the change (
sbrown200 will be removed), and the second entry modification will remove the original value of the username (
Moving an Entry
If you need to move the entry to a new location, an additional setting for
changetype: modrdn is the
newsuperior: option. When using this option, you can specify a new location on the DIT to move the entry to. This will place the entry under the specified parent DN during the change.
For instance, if we wanted to move Sally under the
ou=superusers entry, we could add this entry and then move her to it by typing:
dn: ou=superusers,dc=example,dc=com changetype: add objectClass: organizationalUnit ou: superusers dn: uid=sbrown2,ou=People,dc=example,dc=com changetype: modrdn newrdn: uid=sbrown2 deleteoldrdn: 0 newsuperior: ou=superusers,dc=example,dc=com
Assuming that this is stored in a file called
mksuperuser.ldif, we could apply the changes like this:
- ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f mksuperuser.ldif
This results in a move and never a copy.
In this case, we did not wish to actually change the RDN of the entry, so we set the
newrdn: value to the same value that it currently has. We could easily rename during the move too though if we so desired. In this case, the
newsuperior: setting is the only line of the second change that actually impacts the state of the entry.
An Aside: Adding Binary Data to an Entry
This section is separate from the information above because it could fit within the sections on creating an entry or with defining additional attributes.
LDAP has the ability to store binary data for certain attributes. For instance, the
inetOrgPerson class allows an attribute called
jpegPhoto, which can be used to store a person's photograph or user icon. Another attribute of this objectClass that can use binary data is the
To add this type of data to an LDAP entry, you must use a special format. When specifying the attribute, immediately following the colon, use a less-than character (<) and a space. Afterwards, include the path to the file in question.
For instance, if you have a file called
john.jpg in the
/tmp directory, you can add the file to John's entry with an LDIF file that looks like this:
dn: uid=jsmith1,ou=People,dc=example,dc=com changetype: modify add: jpegPhoto jpegPhoto:< file:///tmp/john.jpg
Pay close attention to the placement of the colon, less than character, and space. If your file is located on disk, the
file:// prefix can be used. The path will add an additional slash to indicate the root directory if you are using an absolute path.
This would work the same way with an audio file:
dn: uid=jsmith1,ou=People,dc=example,dc=com changetype: modify add: audio audio:< file:///tmp/hellojohn.mp3
Once you have processed the LDIF file, the actual file will be encoded within your LDAP directory service. This is important to keep in mind, because adding significant number of files like this will have an impact on the size and performance of your service.
When you need to retrieve the encoded data using the
ldapsearch tool, you will need to add the
-t flag, which will allow the file to be written to the
/tmp directory. The generated filename will be indicated in the results.
For instance, we could use this command to write out the binary data to a temporary file:
- ldapsearch -LLL -x -H ldap:// -t -b "dc=example,dc=com" "uid=jsmith1"
The search result will look like this:
dn: uid=jsmith1,ou=People,dc=example,dc=com objectClass: inetOrgPerson sn: Smith uid: jsmith1 cn: Johnny Smith l: New York audio:< file:///tmp/ldapsearch-audio-n5GRF6
If we go to the
/tmp directory, we can find the file. It can be renamed as needed and should be in the exact state that it was in before entering it into the directory.
Be careful when doing this operation repeatedly, as a new file is written out each time the search is performed. You could easily fill a disk without realizing if you do not pay attention.
By now you should have a fairly good handle on how to manipulate the entries within an LDAP directory information tree using LDIF formatted files and a few tools. While certain LDAP clients may make LDIF files unnecessary for day-to-day operations, LDIF files can be the best way of performing batch operations on your DIT entries. It is also important to know how to modify your entries using these methods for administration purposes, when setting up the initial directory service, and when fixing issues that might prevent clients from correctly accessing your data.