Symas OpenLDAP Knowledge Base

OpenLDAP Client Command Reference

Quicklinks: ldapadd, ldapmodify, ldapdelete, ldappasswd, ldapwhoami, ldapcompare, ldapmodrdn, Using STDIN with ldap* commands,

This reference covers the all OpenLDAP client command utilities and the most common options used with them.

For comprehensive command details, refer to the man page for the command.

Common ldap* command options

The following are the most commonly used options with client commands. Nearly every common option is used for connecting to an LDAP server and presenting a user’s identity and credentials.

Option Description
-H URI The host to connect to in URI format “ldap://xyz/”
-Z[Z] Use StartTLS control if using LDAP over TLS
-x Use simple (dn + password) bind
-D BINDDN The user DN to bind with
-w PASSWORD | -W The password to bind with | Prompt for password
-v Verbose output
-Y MECHANISM SASL Binds: The SASL mechanism to use
-Q SASL Binds: Quiet the SASL messages
-d DEBUG-LEVEL Show client-side debug output
-p & -h DEPRECATED: OpenLDAP v2.5+ does not honor these options

Combining Options

OpenLDAP client command utilities allow combination of options for easier typing. Any number of options that don’t require a parameter may be strung together with other options. For example:

# Long form command:
ldapsearch -x -LLL -v -W -H ldap:/// -D dc=example,dc=com -b dc=example,dc=com "(objectClass=person)"

# Same command, but condensed:
ldapsearch -xLLLvWD dc=example,dc=com -H ldap:/// -b dc=example,dc=com "(objectClass=Company)"

ldapsearch

ldapsearch Man Page

Syntax: ldapsearch <opts> [search filter] [return attributes]

The ldapsearch command allows a user to query an LDAP directory. Entries matching the search are returned in LDIF format. In addition to the common options, ldapsearch requires (in bold) or uses the following:

Option Description
-b searchbase The searchbase tells where in the DIT to begin the search
-s (base|one|sub) The scope of the search:
- base scope returns only the entry identified in the searchbase
- one scope returns all entries that are one level below the searchbase
- sub (default) searches the entire subtree starting at the searchbase
-L[L[L]] Decreases the amount of information returned with an entry
-L : Removes search result stats
-LL : Removes LDAP version/search header, search result stats and number of responses
-LLL : Removes all extraneous information
-n Performs a dry run of the search. Useful for testing the syntax of the search filter
-f filename Search using a file containing one attribute value per line to search with.
Uses “%s” string substitution in the search filter
-c Continuous mode. Ignores errors and continues on to the next search.
This mode is only useful with the “-f filename” option
-A Only returns attribute names, no values. Useful for checking if an attribute is present in an entry
-S attribute Sorts the output of entries based on attribute
-z sizelimit Limits the number of entries returned by sizelimit
“err=4 (size limit exceeded)” is also returned, This is informational, not an error
-o ldif-wrap=no Disables word-wrapping of long attribute values

Search Scope

A very important part of efficient searches is to set the scope of the search The search scope tells the server how deep to perform a search (-s base|one|sub):

Scope Result
base Limits the search to the base object only; does not search for entries at any other level of the DIT
one (level) Limits the search to entries that are one level below the search base
sub (tree) Searches the entire subtree starting at the search base

The default search scope is sub (tree). While it’s useful when you want a full, unrestricted search, it also increases search times/overhead since it checks for subentries on every entry.

  • If you’re searching for one entry only and you know the full DN or at least know the search base and an attribute of the entry, use -s base for your search scope. Anything more is just wasting CPU cycles
  • If you want to limit your scope to one level, for example getting all of the OU entries (but not their children) in the example database, use -s one (-b dc=example,dc=com -s one )
  • If you want all entries below the search base, use -s sub (or exclude -s since sub is the default). Take note of any non-useful entries returned in the search result and adjust future searches to exclude those entries

Search Filters

Search filters are used to refine searches by attribute values so only necessary entries are returned

  • Filters use one or more attribute/value pairs contained within parentheses “( )” to match items in the directory
  • Search filters also use parentheses for grouping criteria together in conjunction with search operators
  • Search filters work more efficiently when attributes that are commonly searched are indexed in the database. Indexes will be covered in a later part of the class

Filter Operators

Operator Description
& (and) The and operator requires all criteria within a group to match
| (or) The or operator requires any criteria within a group to match
! (not) The not operator required the criteria to match none of the criteria
= (equals) Tests if the attribute value is equal
~= (approximate match) Makes an approximate match of the attribute value (english only)
>= (greater or equal) Attribute value is greater than or equal to criteria
<= (lesser or equal) Attribute value is less than or equal to criteria
=* (presence) A value is present in the attribute
=string**string* Substring match

Note 1: Greater/lesser than without equality operators (>, <) are not used in LDAP. Negation of the “greater/less or equal” operator is necessary to implement this operation. See examples below.

Note 2: Search results and performance depend on how the attributes are indexed. Unindexed attributes will cause excessive search time and improperly indexed attributes or improperly used operators may cause incomplete search results.

Example Search Filters

# Simple filter looking for entries that use the "person" objectClass:
(objectClass=person)

# Filter that looks for entries that don't have the last name (sn) "Smith":
(!(sn=Smith))

# Search for entries in the "Accounting" organizational unit with the last name "Smith":
(&(ou=Accounting)(sn=Smith))

# Search for entries in the "Accounting" organizational unit without the last name "Smith":
(&(ou=Accounting)(!(sn=Smith))

# Search for entries with UIDNumber greater or equal to 50:
(UIDNumber>=50)

# Search for entries with UIDNumber greater than 50 (add negation and reverse GT/LT operator):
(!(UID<=50))

Search Tips

  • If you know the exact DN of an entry, you can use the DN as the searchbase in the “-b searchbase” and allows you to forego the search filter
  • Search filters are evaluated by the server from left to right. Efficient search filters work from general to specific.
  • Use the search filter builder in Apache Directory Studio for building complicated search filters.

Return Attributes

At the end of the ldapsearch command, you may provide a list of attributes you want returned with the entry. Here are your options:

Attributes Returns
<none> or “*” Returns the DN and all user attributes of the entry
attr1 attr2 attr3 Returns only the DN and the three requested attributes
opAttr1 opAttr2 opAttr3 Returns the DN and the three requested operational attributes
“+” Returns the DN and all operational attributes
“*” “+” Returns the DN and all user and operational attributes
1.1 Returns only the DN and no attributes

ldapadd

ldapadd Man Page

Syntax: ldapadd <opts> -f <file.ldif>

The ldapadd command is used to add new entries to a directory using plain LDIF data (not a change-type LDIF). One or more entries may be added in the LDIF file being used. For example, let’s create an LDIF file that will add two new OU entries to the example database (be sure to have an empty line at the end of the file):

File: add-OUs.ldif:

dn: ou=assets,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: assets
description: Organizational Unit for storing asset data

dn: ou=policies,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: policies
description: Organizational Unit for storing password policies

ldapadd Examples

For this example, we’ll use SASL bind to authenticate to the server and verbose output when running the ldapadd command:

ldapadd -Q -Y EXTERNAL -f add-OUs.ldif -v

If the add is successful, you’ll see the following verbose output:

add objectClass:
    top
    organizationalUnit
add ou:
    assets
add description:
    Organizational Unit for storing asset data
adding new entry "ou=assets,dc=example,dc=com"
modify complete
...

See the later section covering how to do ldapadd, ldapmodify and ldapdelete without using ldif files.

ldapmodify

ldapmodify Man Page

Syntax: ldapmodify <opts> -f <file.ldif>

The ldapmodify command may be used to add, modify and delete entries. This section will focus on entry modifications.

Modification LDIFs

ldapmodify uses “changetype” LDIF input. All entry modifications will have a changetype of “modify” and action specifiers for the attribute being changed.

Multiple attributes may be modified in one modify operation. Simply put a single line with the “-” character between each action.

Modifications are atomic, so if any part of a modification fails, the entire modification is discarded unless there are multiple entries being modified and the continue (-c) option is used.

Adding Attributes

Example adding two attributes, one with multiple values to an entry:

dn: cn=may gaul,ou=accounting,dc=example,dc=com
changetype: modify
add: telephoneNumber
telephoneNumber: +1 213 867 5309
-
add: description
description: This is a description
description: This is another description

Replacing Attributes

Note: When replacing multivalued attributes and a specific value is to be replaced, the specific value must be deleted and then the new value must be added. If replace is used on an attribute with more than one value, all values will be deleted and the new value will be saved. Examples:

# Replace an attribute with a single value:
dn: cn=may gaul,ou=accounting,dc=example,dc=com
changetype: modify
replace: telephoneNumber
telephoneNumber: +65 223 867 5309

# Replace a specific value in an attribute with multiple values:
dn: cn=may gaul,ou=accounting,dc=example,dc=com
changetype: modify
delete: description
description: This is the a description
-
add: description
description: This is the replaced description

Deleting attributes

Note: When deleting multivalued attributes and a specific value is to be deleted, the value must be specified in the delete action. If delete is used on an attribute with more than one value and a value isn’t specified, all values will be deleted. Examples:

# Delete all description attributes in an entry:
dn: cn=may gaul,ou=accounting,dc=example,dc=com
changetype: modify
delete: description

# Delete a specific value in an attribute with multiple values:
dn: cn=may gaul,ou=accounting,dc=example,dc=com
changetype: modify
delete: description
description: This is the replaced description

Incrementing Attributes

Integer-type attributes may be incremented with the incremente action. This is a useful feature for keeping track of sequential ID numbers. Example:

# Increment an attribute by one
dn: cn=uidNumber,dc=example,dc=com
changetype: modify
increment: uidNumber
uidNumber: 1

# Increment an attribute by five
dn: cn=uidNumber,dc=example,dc=com
changetype: modify
increment: uidNumber
uidNumber: 5

Renaming or Moving Entries

Entries may be renamed and/or moved with the “modrdn” changetype:

# Let's create a ou=terminated so we have a place to put terminated users:
ldapadd -Qv <<<'
dn: ou=terminated,dc=example,dc=com
objectClass: organizationalUnit
ou: Terminated
description: Terminated employees go here'

# Rename the RDN of an entry and move it to the "terminated" OU and delete the old RDN 
dn: cn=Ann Tully,ou=Accounting,dc=example,dc=com
changetype: modrdn
newrdn: cn=T-Ann Tully
deleteoldrdn: 1
newsuperior: ou=terminated,dc=example,dc=com

See the later section covering how to do ldapadd, ldapmodify and ldapdelete without using ldif files.

ldapdelete

ldapdelete Man Page

Syntax: ldapdelete <opts> [-f <file.ldif>] [DN]

The ldapdelete command removes an entry from a DIT. If the entry being deleted has child entries, the ldap server will refuse to delete the entry unless the recursive delete option (-r).

Use caution with the -r option, as it does not prompt for confirmation!

ldapdelete Examples

# Delete a single entry
ldapdelete <opts> cn=Par Chong,ou=Accounting,dc=example,dc=com

# Recursively delete an entry and its children
ldapdelete <opts> -r ou=Planning,dc=example,dc=com

# Delete multiple entries by reading from a file named dn-list.txt
#   containing the following DNs (without the "dn:"" prefix seen 
#   in normal LDIF files):
#     cn=Muriel Oka,ou=Accounting,dc=example,dc=com
#     cn=Zyg Chawla,ou=Accounting,dc=example,dc=com
#     cn=Biddie Auld,ou=Accounting,dc=example,dc=com
#     cn=Byron Evers,ou=Accounting,dc=example,dc=com
ldapdelete <opts> -f dn-list.txt

See the later section covering how to do ldapadd, ldapmodify and ldapdelete without using ldif files.

ldappasswd

ldappasswd Man Page

Syntax ldappasswd \<opts> [-a|-A] (-s|-S) userDN

The ldappasswd command is used for updating the userPassword on person-type entries. ldappassword sends a Password Modify control so that the password is hashed before storing and also triggers password policy checks if policies are in place and enforced. Because ldappasswod forces password hashing, it is safer than simply updating a password using the ldapmodify command.

ldappasswd Examples

# Update a user's password using simple bind as admin and prompting for the old and new password
ldappasswd -xH ldap:/// -D dc=example,dc=com -WAS "cn=May Gaul,ou=Accounting,dc=example,dc=com"

# Update a user's password using simple bind as self and prompting for the old and new password
ldappasswd -xH ldap:/// -D "cn=May Gaul,ou=Accounting,dc=example,dc=com" \
  -WAS "cn=May Gaul,ou=Accounting,dc=example,dc=com"

ldapwhoami

ldapwhoami Man Page

Syntax: ldapwhoami <opts> [-D bindDN (-w|-W)]

The ldapwhoami command serves two purposes:

  1. It is used to test authentication
  2. It is used to confirm the identity of the user that binds

It is recommended that when using simple binds (-x), that the -W (prompt for password) Option is used. The -w Option will retain the password used is stored in the shell’s history.

ldapwhoami Examples

# Test if a password a user binding with is correct (successful result)
ldapwhoami -x -H ldap:/// -D "cn=May Gaul,ou=Accounting,dc=example,dc=com" -w secret
dn: cn=May Gaul,ou=Accounting,dc=example,dc=com

# Test if a password a user is binding with is correct (unsuccessful result)
ldapwhoami -x -H ldap:/// -D "cn=May Gaul,ou=Accounting,dc=example,dc=com" -w secrot
ldap_bind: Invalid credentials (49)

# See what identity the linux root user maps to with a SASL bind
ldapwhoami -Q -Y EXTERNAL
dn: dc=example,dc=com

ldapcompare

ldapcompare Man Page LDAP Result Codes RFC

Syntax: ldapcompare <opts> DN <attribute>:<value>

The ldapcompare command is used for testing the value of an attribute without using a search operation. You provide the DN of the entry to test, the attribute name and the expected value. If the given value matches, the command returns TRUE (6), if the value does not match, the command returns FALSE (5).

Testing values with spaces requires the attribute and value to be encapsulated in quotes. Examples:

# Compare matches true:
ldapcompare -Qv "cn=Pas Panger,ou=Payroll,dc=example,dc=com" "sn:Panger"
TRUE

# Then check the result code:
echo $?
6

# Compare matches true, using verbose output:
ldapcompare -Qv "cn=Pas Panger,ou=Payroll,dc=example,dc=com" "sn:Panger"
ldap_initialize( <DEFAULT> )
DN:cn=Pas Panger,ou=Payroll,dc=example,dc=com, attr:sn, value:Panger
Compare Result: Compare True (6)
TRUE

# Compare matches true, using verbose output:
ldapcompare -Qv "cn=Pas Panger,ou=Payroll,dc=example,dc=com" "sn:Danger"
FALSE

# Then check the result code:
echo $?
5

ldapmodrdn

ldaprdn Man Page

Syntax: ldapmodrdn <opts> [-r] [-s <new-superior>] <current DN> <newRDN>

The ldapmodrdn command is used to change the RDN of and/or move an entry.

# Change the RDN of an entry (and deletes the old RDN)
ldapmodrdn -Q -r "cn=Joly Tham,ou=Payroll,dc=example,dc=com" "cn=Joly Smith" 

# Move an entry to another OU
ldapmodrdn -Q -r -s ou=terminated,dc=example,dc=com "cn=Joly Smith"

# Rename an entry and move it to a new OU
ldapmodrdn -Q -r -s ou=terminated,dc=example,dc=com \
  "cn=Elsa Lytle,ou=Payroll,dc=example,dc=com" "cn=Elsa Biggles"

ldapurl

ldapurl Man Page

Syntax: ldapurl [-a attrs] [-b searchbase] [-f filter] [-H URI] [-s scope]

The ldapurl command is a tool that creates LDAP search URIs from a set of parameters. Search URIs are used in some LDAP client APIs. At this time, search URIs cannot be used with the ldapsearch command.

# Build a search URI
ldapurl -a cn,sn -s one -b ou=people,dc=example,dc=com -S ldap -h appserv01.example.com
ldap://appserv01.example.com:389/ou=people,dc=example,dc=com?cn,sn?one

Using STDIN with ldap* commands

The ldapadd, ldapmodify and ldapdelete commands can accept input from STDIN instead of reading from a file. This is handy for instances where a quick ADD/MOD/DELETE is needed.

With the ldapadd, ldapmodify or ldapdelete commands do not use the ‘-f filename’ Option is not used and LDIF data isn’t read from STDIN, thes commands go into ‘command mode’, where you may manually enter LDIF data and will perform the write when enter is pressed twice. If the ‘-c’ Option is used, additional LDIFs may be entered until you exit with CTRL-D. Using ‘-c’ also allows you to continue if the previous LDF failed.

Examples:

Add an entry using the ‘cat’ command:

cat << EOF | ldapadd -Qv
dn: ou=security,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: Security

EOF

Add an entry using ‘here strings’:

ldapadd -Qv <<< '
dn: ou=security,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: Security'

Modify an entry using the ‘cat’ command:

cat << EOF | ldapmodify -Qv
dn: dc=example,dc=com
changetype: modify
add: description
description: The Example Database'

Modify an entry using ‘here strings’:

ldapmodify -Qv <<< '
dn: dc=example,dc=com
changetype: modify
add: description
description: The Example Database

Delete multiple entries using the ‘cat’ command:

cat << EOF | ldapdelete -Qv
cn=May Gaul,ou=Accounting,dc=example,dc=com
cn=Ann Tully,ou=Accounting,dc=example,dc=com
cn=Par Chong,ou=Accounting,dc=example,dc=com
cn=Muriel Oka,ou=Accounting,dc=example,dc=com
cn=Zyg Chawla,ou=Accounting,dc=example,dc=com
EOF

Delete multiple entries using ‘here strings’:

ldapdelete -Qv <<< '
cn=May Gaul,ou=Accounting,dc=example,dc=com
cn=Ann Tully,ou=Accounting,dc=example,dc=com
cn=Par Chong,ou=Accounting,dc=example,dc=com
cn=Muriel Oka,ou=Accounting,dc=example,dc=com
cn=Zyg Chawla,ou=Accounting,dc=example,dc=com'