LDIF Basics

You are here:
< Back


If you have never used an LDIF file before to manage a directory then you are in for a treat. If you are looking for techy information on how to build out an LDIF, including examples, then just look a little lower here.

So what is an LDIF file? An LDIF is a text file that you can feed into a directory to add, delete, move, or modify objects in the directory. You can adjust users, groups, and containers in the directory. If you are doing a single user then it might be easier to use any GUI tool you have available to do that request. But if you are doing a number of users, or need to do the exact same change on a number of trees, then an LDIF will make your life much easier. This is also a really great way to level set the information in different trees or on different objects in the same tree that should all have the same attribute settings.

When you do a command line LDAP search on a directory the results that the command gives is in LDIF format. If you redirect that output to a file then you can use that as a base or template for building out your LDIF file. I will give some examples of this at the bottom of the page. Keep in mind though that the ldapsearch command output is limited to a max of 80 characters across (and a lot of implementations go only 78 characters). So if you output a listing where some attributes give more than 80 characters of information then you will have line wraps that you need to deal with on creating an LDIF for input.


Several things to keep in mind with LDIF files. First, just like ldapsearch LDIF commands are case insensitive. You can use upper case, lower case, or mixed case. As far as the attributes themselves though, however you type them into the LDIF is how they will show up in the directory, and how they will display on output of a search. So if there is a particular need for case in the attribute you need to be mindful of that in creating your LDIF. Sometimes certain programs are written expecting a certain case for the attribute, and you need to put it in using the same case. Some people will use mixed case in a way to make names easier to read. If you want that then put it in that way in the LDIF. But the ldapmodify program will not care what the case is that you use.

Any line that starts with the pound or hash sign is considered a comment and will be ignored when the file is processed.

# This is the comment line and can be used to section things or note info

Trailing Spaces and Line-folding
You will want to make sure that there are no trailing spaces on any lines. The only time that trailing spaces are allowed is when you are line-folding an entry. If you have information that is going to be on two lines for a single attribute entry then you need to have a trailing space on that line and a single space at the beginning of the next line. The LDIF parser will then remove the spaces and concatenate the two lines.

End of record and multiple modify option separators
One other big gotcha that a lot of people get hit with is lacking a blank line at the end of each record. Every entry in an LDIF file needs to have a line with no spaces to end it. It is just a blank line with a carriage return. The file needs to end with a final clean carriage return too. You also need to be careful if you create the file in an editor on a Windows computer and then copy the file to a Linux or Unix server to run. It is possible you will not have the proper carriage return codes in the file for the *nix system since Windows uses different codes for carriage returns than *nix by default. A lot of text editors on Windows have a setting for using *nix returns.

If you are doing a modify on one or more records and are doing multiple operations on each object you need to separate the different operations with a hyphen. Look below to the modify section for examples of this.

The Big DN
Every item or object in the directory that you are going to modify is known by their DN. This is the fully qualified name of the object in the tree. This will be the first line for any record in the LDIF file that you are updating. The DN will be in LDAP format. The line will start with dn: and then have the full DN of the object. This is NOT case sensitive. If you are dealing with containers then the beginning of the DN will not start with cn= but will start with the type of container like ou= instead. Of course, make sure there is no trailing spaces in the line, just like all other lines or you will get an error.


dn: cn=bobsmith,ou=operations,ou=people,o=MyBusiness

dn: cn=sallyjones,ou=homeoffice,o=mycorp,dc=supercorp,dc=com

dn: ou=groups,ou=shopfloor,o=business1

Pushing the LDIF into the system
There are several ways to push an LDIF file into a system. Probably the most generic is to use the ldapmodify command. This is available on all *nix and Mac systems. You can find it for Windows too. If you are going against AD then you can download Microsoft’s LDIFDE program to push the file in too. Some other environments have additional tools they make available to push the file into the system. The most basic ldapmodify line to accomplish this is:

ldapmodify -h hostname -D FQDNAdmin -w password -f filename.ldif

If you use this and there is a record that has an issue and throws an error then the processor will stop pushing entries and throw an error on the screen. If you want the program to keep processing records beyond the one that has the error then you can use a -c in the command line too. I will show an example later where this is very handy on a modify.

Note on system differences (and disclaimer)
LDAP and LDIF are supposed to be standards. But not everyone implements everything exactly the same way. You will find some slight differences between implementations. I will try to make note of the ones that I know of here. But it is always good to test your LDIF files in a test directory before jumping in and going all gung ho in your production system. It is expected that you will use all due diligence in making sure you have a good LDIF file and will be updating your particular system the way that you are expecting to update it. If you find interesting differences you can help others by sending me a note and I will add it to the site.

Adding new objects

If you want to add new users, groups, organizational units etc. then you need to perform an add operation. You designate the change type of an LDIF record with the changetype: line that goes right below the DN of the object you are adding or modifying.

With an add you need to make sure that you include the objectclass of the object you are creating. For most systems you should only need to specify the base class of the object and the system should fill in any additional entries. But I don’t like leaving that to chance. So my recommendation is to do an ldapsearch for an object like the type you want to add and then copy the objectclass section right out of the export. That way you get all the objectclass lines for the new object.

Second, you MUST put in all required attributes of the object. You don’t have to list any optional attributes unless you want to populate them. But you need to have the required attributes specified. This is something that will be different on various systems and platforms. Go into the definition of your class in the schema to determine what is required for any particular object class.

So let’s make a couple users now. Let’s make Clara Oswald and Bob Cratchit.

dn: cn=claraoswald,ou=people,ou=scifi,ou=fiction,o=myworld
changetype: add
sn: Oswald
givenname: Clara
fullname: Clara Oswald
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: Person
objectClass: ndsLoginProperties
objectClass: Top
mail: coswald@myscifi.com
uid: coswald
cn: claraoswald
userpassword: MyTardisRocks
telephonenumber: 555-1212
telephonenumber: 555-1234

dn: cn=bobcratchit,ou=people,ou=classics,ou=fiction,o=myworld
changetype: add
sn: Cratchit
givenname: Bob
fullname: Bob Cratchit
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: Person
objectClass: ndsLoginProperties
objectClass: Top
mail: bcratchit@dickens.com
uid: bobcratchit
cn: bobcratchit
userpassword: NotAHumbug
telephonenumber: 555-1213
telephonenumber: 555-5678

Each attribute gets a line that starts with the name of the attribute ending in a colon followed by a space then the value you want in the attribute. If the attribute is a multivalued attribute and you want to put in multiple entries then simply use the attribute name several times and it will add each entry to the array in the attribute. If you have a binary entry then you will need to encode it in Base64.

Two things to note here too. First, the uid and the cn are different attributes and can be set to different values. Often they are set the same, but nothing prevents you from setting them to different values. And since they are different attributes they both need to be set.

Second, and this is a little known bit of information, the cn attribute is actually a multivalued attribute (at least on the systems I have tested it on). Typically you will only ever see a single value in it. But it is possible to stuff more than one in there. Most programs will only ever read the first value in the array (multivalued attributes present to programming languages as arrays). So if the one you really want is the second or third in the array you could find some really odd behavior in your program. This becomes more important in the modify change type that we will talk about below.

You can add a container in basically the same way. Let’s do an OU.

dn: ou=monitoring,o=myorg
changetype: add
ou: monitoring
objectClass: organizationalUnit
objectClass: ndsLoginProperties
objectClass: ndsContainerLoginProperties
objectClass: Top

Pretty simple eh? List out the attributes and the values for each one below the first two lines of the record, make sure there are no trailing spaces, and that you have a clean blank carriage free line at the end of each record in the file. If you are setting up a test tree and want a large number of records to test with then you can use a bash script, VBScript, or PowerShell program (or language of your choice) to generate the file using some sort of cool algorithm to generate all the names and passwords, then simply push the file in.

Deleting Objects

Deletes are the easiest change type to create. There is basically only two parts to a delete. You specify the DN of the object to delete, and the change type as delete. Containers need to be empty before they can be deleted. Here are a few examples.

dn: cn=tyrashores,ou=users,ou=grandrapids,o=supergeek
changetype: delete

dn: cn=admins,ou=groups,ou=chicago,o=supergeek
changetype: delete

dn: ou=miami,o=supergeek
changetype: delete

Modifying Objects

The modify change type is the most complicated of the different operations in an LDIF. The reason for that is you can either add information to an attribute, delete an attribute, or replace an attribute. After changetype line you will specify the operation and the attribute it is happening on. Then if it needs a value you will add another line that is the attribute value pair to describe the change. Let’s look at each one of these operations.

Add a value
If you use the add operation then the value specified will be added to the object. If the object had no value at all it gets this value. If the attribute is multivalued then this value will be added to the end of the list of values.

dn: cn=jsmith,ou=users,ou=grandrapids,o=supergeek
changetype: modify
add: mail
mail: jsmith@atomicsupergeek.com

This will obviously add the new email address to the user jsmith. You can adjust multiple items by separating them with a hyphen like this.

dn: cn=rtyler,ou=users,ou=london,o=supergeek
changetype: modify
add: mail
mail: rtyler@atomicsupergeek.com

add: telephonenumber
telephonenumber: 555-1212

Delete values from an attribute
Deleting or clearing an attribute is really easy. This operation will remove all values from an attribute if it is multivalued. You simply name the attribute to be cleared.

dn: cn=apond,ou=users,ou=london,o=supergeek
changetype: modify
delete: mail

Replacing values in an attribute
The replace operation will replace all values in an attribute with the new value(s) listed in the LDIF. If nothing exists in the attribute the replace is basically the same as an add.

dn: cn=cjarvis,ou=users,ou=LA,o=supergeek
changetype: modify
replace: title
title: Creative Director

Mixing operations
You can mix these operations in the same record if you want. Keep in mind that if any of the operations in the record fails then the entire record will not be adjusted. So if you think something might error out then you might want to do each operation as a separate record on the same object.

dn: cn=zarrias,ou=users,ou=NY,o=supergeek
changetype: modify
add: title
title: photographer

delete: description

replace: mail
mail: zarrias@atomicsupergeek.com

Moving and Renaming Objects

You can move or rename an object with an ldif also. The change type you use is Moddn. There are two keywords for a rename and three for a move. The biggest thing to remember with how this operation happens is that it is doing a copy of the object to a new name, new location, or both, and then either deleting or leaving the original object in the directory after the copy. So it is either a copy of the object or a copy and delete.

  • newrdn – This is the new name of the object itself. Note that even on a move you need to specify this keyword even if you are not renaming the object. On a move without a rename you simply use the same name as before.
  • deleteoldrdn – This will indicate if the original object is to be deleted or not. A 0 (zero) means to save the original object and a 1 means to delete the original object.
  • newsuperior – This keyword gives the new location for the object. It is the entire path of the object without the actual object name. This is only needed if the object will end up in a new location in the tree.

Renaming an object

On a rename you simply give the full dn of the original object and then give the new name of the object with the newrdn keyword. You then specify to delete the old object with a 1.

dn: cn=clara_oswald,ou=users,ou=NY,o=supergeek
changetype: moddn
newrdn: cn=donna_nobel
deleteoldrdn: 1

Copying an object

Sometimes you will want to make a copy of an object in the tree because most all of the attributes are the same for the new object. The only difference between simply renaming an object and copying an object is if you delete the original object or not.

dn: cn=clara_oswin,ou=users,ou=NY,o=supergeek
changetype: moddn
newrdn: cn=clara_oswald
deleteoldrdn: 0

Moving an object

You can move an object without renaming it. However, you still need to specify a newrdn keyword. You will use the newsuperior to specify the new location.

dn: cn=rose_tyler,ou=users,ou=tardis,o=supergeek
changetype: moddn
newrdn: cn=rose_tyler
deleteoldrdn: 1
newsuperior: ou=users,ou=parallelearth,o=supergeek

Moving and renaming an object

If you want to move and rename an object at the same time you simply give a new name in the newrdn keyword.

dn: cn=doctor_donna,ou=companions,ou=tardis.o=supergeek
changetype: moddn
newrdn: cn=donna_nobel
deleteoldrdn: 1
newsuperior: ou=companions,ou=earth,o=supergeek

Obviously you can also copy an object to a new object in a new location in the directory and simply set the deleteoldrdn to a 0 (zero) to not delete the original object.