objectClass: organizationalUnit
Assuming that these entries are stored in a file named /tmp/top.ldif, you can add them to the directory by executing:
root# slapadd -v -l /tmp/top.ldif
added: "dc=plainjoe,dc=org" (00000001)
added: "ou=people,dc=plainjoe,dc=org" (00000002)
The output indicates that the entries were added successfully.
Verifying the Directory's Contents
Next, you will bring the directory online so that you can use it in conjunction with ldapsearch, ldapmodify, and the other tools for working on a live directory:
root# /usr/local/libexec/slapd
After the directory server has started, you can use ldapsearch to query the server. ldapsearch allows you to dig through your directory, test for the existence of data, and test whether access control has been set up correctly.
OpenLDAP's ldapsearch began life as a simple wrapper for the LDAP search operation. The list of search possibilities is lengthy; I won't cover it until Chapter 5. For now, I will focus on very simple searches that assure you the directory is up and running correctly. In its simplest form, a query requires the following information:
The LDAP server's hostname or IP address
The credentials (i.e., user DN and password) to use to bind to the host
The search base in the form of a DN
The scope of the directory to search
A search filter
A list of attributes to return
We'll start with a "Show me everything" search. Here, you ask the directory to return all entries that have a value for the objectClass attribute (which is all entries).
$ ldapsearch -x -b "dc=plainjoe,dc=org" "(objectclass=*)"
version: 2
#
# filter: (objectclass=*)
# requesting: ALL
#
# plainjoe,dc=org
dn: dc=plainjoe,dc=org
dc: plainjoe.org
objectClass: dcObject
objectClass: organizationalUnit
ou: PlainJoe Dot Org
# people,dc=plainjoe,dc=org
dn: ou=people,dc=plainjoe,dc=org
ou: people
objectClass: organizationalUnit
# Search result
search: 2
result: 0 Success
# numResponses: 3
# numEntries: 2
The ldapsearch options used here are:
-x
Instructs ldapsearch to perform a simple bind (i.e., do not use SASL for authentication).
-b dc=plainjoe,dc=org
Defines the DN dc=plainjoe,dc=org as the search's base suffix. This DN specifies the point at which the search begins. Therefore, it must be a DN that is held by the LDAP server. All entries located higher in the tree will be ignored.
(objectclass=*)
The search filter. If you are familiar with filename globbing, or just general wildcard patterns, this filter should be familiar. RFC 2254 defines ways to represent an LDAP search filter as a string. The syntax of filters is covered in Chapter 5. For now, it's sufficient to know that this filter matches any value of the objectClass attribute.
The surprising thing about this command is that it doesn't explicitly contain most of the items that I said were necessary for any search. In fact, the only two items that we can clearly see are the search base and the search filter. What's going on? Let's look at the missing items one at a time:
The LDAP server's hostname (or IP address)
ldapsearch queries the local host if the server isn't specified explicitly. The -h hostname option specifies the hostname or IP address. In this case, though, you're running the server locally, so you don't need it.
Credentials used to bind to the directory
The ACL defined in slapd.conf gave read permission to all users. Therefore, you don't need to authenticate to perform this search. When authentication is required, the -D DN and -w password options specify the login DN and password to be used.
The search scope
By default, ldapsearch queries the server for all entries contained in the subtree of the root node defined by the -b option. Other possibilities include searching only the immediate children of the base suffix entry or searching this entry alone. The search scope (-s) option can be used to specify either sub, base, or one.
A list of attributes to return
By default, slapd returns all nonoperational attributes. On a complex directory, you might get an extremely long list of attributes for every entry in the directory. To limit the result to a few specific attributes, list the attributes you want on the command line, separated by commas. Operational attributes such as modifyTimestamp and modifiersName are not returned unless specifically asked for by name or by using the plus character (+) as the attribute list in the search.
The default values for many LDAP client parameters can be controlled via the system-wide ldap.conf configuration file (located in the same directory as slapd.conf) or the user-specific version in $HOME/.ldaprc. For more details, refer to the ldap.conf(5) manpage. Our examples explicitly list all parameters required by the command-line tools unless the compile-time defaults can be used, which was the case in the previous ldapsearch listing.
Table 4-3 and Table 4-4 list all the options and arguments for ldapsearch. Don't worry about understanding them all now.
Table 4-3. Command-line options common to ldapsearch, ldapadd, ldapdelete, ldapmodify, and ldapmodrdn
Option
Description
-d integer
Specifies what debugging information to log. See the loglevel slapd.conf parameter for a listing of log levels.
-D binddn
Specifies the DN to use for binding to the LDAP server.
-e [!]ctrl[=ctrlparam]
Defines an LDAP control to be used on the current operation. See also the -M option for the manageDSAit control.
-f filename
Specifies the file containing the LDIF entries to be used in the operations.
-H URI
Defines the LDAP URI to be used in the connection request.
-I
Enables the SASL "interactive" mode. By default, the client prompts for information only when necessary.
-k
Enables Kerberos 4 authentication.
-K
Enables only the first step of the Kerberos 4 bind for authentication.
-M-MM
Enable the Manager DSA IT control. This option is necessary when modifying an entry that is a referral or an alias. -MM requires that the Manager DSA IT control be supported by the server.
-n
Does not perform the search; just displays what would be done.
-O security_properties
Defines the SASL security properties for authentication. See previous information on the sasl-secprops parameter in slapd.conf.
-P [2|3]
Defines which protocol version to use in the connection (Version 2 or 3). The default is LDAPv3.
-Q
Suppresses SASL-related messages such as the authentication mechanism use, username, and realm.
-R sasl_realm
Defines the realm to be used by the SASL authentication mechanism.
-U username
Defines the username to be used by the SASL authentication mechanism.
-v
Enables verbose mode.
-w password
Specifies the password to be used for authentication.
-W
Instructs the client to prompt for the password.
-x
Enables simple authentication. The default is to use SASL authentication.
-X id
Defines the SASL authorization identity. The identity has the form dn:dn or u:user. The default is to use the same authorization identity as the authenticated user.
-y passwdfile
Instructs the ldap tool to read the password for a simple bind from the given filenam
e.
-Y sasl_mechanism
Instructs the client as to which SASL mechanism should be used. The bind request will fail if the server does not support the chosen mechanism.
-Z-ZZ
Issue a StartTLS request. Use of -ZZ makes the support of this request mandatory for a successful connection.
Table 4-4. Command-line options specific to ldapsearch
Option
Description
-a [never|always|search|find]
Specifies how to handle aliases when located during a search. Possible values include never (the default), always, search, or find.
-A
For any entries found, returns the attribute names but not their values.
-b basedn
Defines the base DN for the directory search.
-F prefix
Defines the URL prefix for filenames. The default is to use the value stored in $LDAP_FILE_URI_PREFIX.
-l limit
Defines a time limit (in seconds) for the server in the search.
-L-LL-LLL
Print the resulting output in LDIFv1 format. -LL causes the result to be printed in LDIF format without comments. -LLL prints the resulting output in LDIF format without comments or version information.
-s [sub|base|one]
Defines the scope of the search to be base, one, or sub (the default).
-S attribute
Causes the ldapsearch client to sort the results by the value of attribute .
-t-tt
Write binary values to files in a temporary directory defined by the -T option. -tt specifies that all values should be written to files in a temporary directory defined by the -T option.
-T directory
Defines the directory used to store the resulting output files. The default is the directory specified by $LDAP_TMPDIR.
-u
Includes user-friendly entry names in the output.
-z limit
Specifies the maximum number of entries to return
Updating What Is Already There
Eventually, the information stored in a directory will need to be updated or deleted. While a directory isn't designed to be updated as frequently as a database, there are very few applications in which the data never changes. This section covers how to update the data in the directory using ldapmodify. The name ldapmodify is a little misleading; this utility can add new entries and delete or update existing entries using some of the advanced features of LDIF for its input language.
The following LDIF listing defines two entries that we will add to our directory:
## filename: /tmp/users.ldif
## LDIF entry for "Gerald W. Carter"
dn: cn=Gerald W. Carter,ou=people,dc=plainjoe,dc=org
cn: Gerald W. Carter
sn: Carter
mail: [email protected]
mail: [email protected]
labeledURI: http://www.plainjoe.org/
roomNumber: 1234 Dudley Hall
departmentNumber: Engineering
telephoneNumber: 222-555-2345
pager: 222-555-6789
mobile: 222-555-1011
objectclass: inetOrgPerson
## LDIF entry for "Jerry Carter"
dn: cn=Jerry Carter,ou=people,dc=plainjoe,dc=org
cn: Jerry Carter
sn: Carter
mail: [email protected]
telephoneNumber: 555-123-1234
objectclass: inetOrgPerson
The following command shows how to add these entries to the directory while it is running. Because write privileges are required to add new entries, ldapmodify binds to the directory using the credentials from the rootdn and rootpw slapd.conf parameters.
$ ldapmodify -D "cn=Manager,dc=plainjoe,dc=org" -w secret
> -x -a -f /tmp/users.ldif
adding new entry "cn=Gerald W. Carter,ou=people,dc=plainjoe,dc=org"
adding new entry "cn=Jerry Carter,ou=people,dc=plainjoe,dc=org"
The output indicates that both entries were added successfully. The -D, -w, and -x options to ldapmodify should be familiar; they specify the DN to use for the modification, specify the password for the modification, and request simple authentication, respectively. This leaves only two new options to discuss:
-a
Entries are to be added to the directory. The default for ldapmodify is to update existing information.
-f filename
Reads the new entries from the given filename. By default, ldapmodify reads from standard input.
If ldapmodify returns an error message such as the following, try enabling verbose messages via the -v command-line switch:
ldap_add: Invalid syntax
additional info: value contains invalid data
There are two common causes of this error message. You may have forgotten to include all the necessary schema files in slapd.conf, or you may have extra whitespace at the end of line in the LDIF file. The set list command in vi can help you track down extra whitespace.
Refer again to Table 4-3 for a list of the common options for all of these ldap client tools. Table 4-5 lists those options specific to ldapmodify and ldapadd. Note that ldapadd and ldapmodify are the same executable; ldapadd is only a hard link to ldapmodify. The commands differ only in their default behavior, which depends on the name by which the program was invoked.
Table 4-5. Command-line options specific to ldapadd and ldapmodify
Option
Description
-a
Adds entries. This option is the default for ldapadd.
-r
Replaces (or modifies) entries and values. This is the default for ldapmodify.
-F
Forces all change records to be used from the input.
Now let's see how a modification works. Suppose you want to add a URL to the entry for cn=Jerry Carter,ou=people,dc=plainjoe,dc=org. To add a URL, use the labeledURI attribute:
labeledURI: http://www.plainjoe.org/~jerry/
In addition, you should delete the [email protected] email address for "Gerald W. Carter" because it has become invalid. You can place both changes in a single LDIF file:
## /tmp/update.ldif
## Add a web page location to Jerry Carter.
dn: cn=Jerry Carter,ou=people,dc=plainjoe,dc=org
changetype: modify
add: labeledURI
labeledURI: http://www.plainjoe.org/~jerry/
## Remove an email address from Gerald W. Carter.
dn: cn=Gerald W. Carter,ou=people,dc=plainjoe,dc=org
changetype: modify
delete: mail
mail: [email protected]
The changetype keyword in the LDIF file is the key to modifying existing entries. This keyword can accept the following values:
add
Adds the entry to the directory.
delete
Deletes the entry from the directory.
modify
Modifies the attributes of an entry. With this keyword, you can both add and delete attribute values.
modrdn
Changes the RDN of an entry.
moddn
Changes the DN of an entry.
This LDIF file tells ldapmodify what changes to make. We'll invoke ldapmodify with the verbose (-v) option so you can follow the update operations more closely. The -a option isn't needed because you're not adding new entries.
$ ldapmodify -D "cn=Manager,dc=plainjoe,dc=org" -w secret
> -x -v -f /tmp/update.ldif
ldap_initialize(
add labeledURI:
http://www.plainjoe.org/~jerry/
modifying entry "cn=Jerry Carter,ou=people,dc=plainjoe,dc=org"
modify complete
delete mail:
[email protected]
modifying entry "cn=Gerald W. Carter,ou=people,dc=plainjoe,dc=org"
modify complete
Notice that the LDIF file is parsed sequentially from the top. Therefore, later LD
IF entries can modify entries created previously in the file. You can also create an LDIF file with entries having different changetype values. For example, the following LDIF file adds an entry for user Peabody Soup, adds a new telephoneNumber to Jerry Carter's entry, and finally deletes the previously created entry for Peabody Soup.
## /tmp/changetypes.ldif
## Add entry for Peabody Soup.
dn: cn=Peabody Soup,ou=people,dc=plainjoe,dc=org
changetype: add
cn: Peabody Soup
sn: Soup
objectclass: inetOrgPerson
## Add new telephoneNumber for Jerry Carter.
dn: cn=Jerry Carter,ou=people,dc=plainjoe,dc=org
changetype: modify
delete: telephoneNumber
telephoneNumber: 555-123-1234
-
add: telephoneNumber
telephoneNumber: 234-555-6789
## Remove the entry for Peabody Soup.
dn: cn=Peabody Soup,ou=people,dc=plainjoe,dc=org
changetype: delete
A couple of facts about this LDIF file are worth mentioning:
Entries are separated by a blank line, as noted earlier.
Multiple changes to a single entry using the modify changetype are separated by a single dash (-) on a line by itself. These should be handled as a single change by the server. Either all the changes for this DN take effect or none are applied.
The modify changetype supports add and delete keywords for adding and deleting attribute values. In order to delete the value of an attribute, the delete: must immediately be followed by an attributetype:value pair. It's necessary to specify the value you're deleting because some attributes can hold multiple values. Specifying which value to remove eliminates any ambiguity about what you want to do. When the last value of an attribute is removed from an entry, that attribute is no longer present in the entry.
LDAP System Administration Page 10