Performing LDAP Operations OpenDJ comes with a Control Panel browser for managing entries and also command-line tools for performing LDAP operations. This chapter demonstrates how to use the command line tools to script LDAP operations.
Searching the Directory Searching data Searching the directory resembles searching for a phone number in a paper phone book. You can look up a phone number because you know the last name of a subscriber's entry. In other words, you use the value of one attribute of the entry to find entries that have another attribute you want. Yet whereas a paper phone book has only one index (alphabetical order by name), the directory has many indexes. For a search you therefore always specify which index to use, by specifying which attribute(s) you are using to lookup entries. Your paper phone book might be divided into white pages for residential subscribers, and yellow pages for businesses. If you are looking up an individual's phone number, you limit your search to the white pages. Directory services divide entries in various ways, often to separate organizations, and to separate groups from user entries from printers for example, but potentially in other ways. When searching you therefore also specify where in the directory to search. The ldapsearch command thus takes at minimum a search base DN option and an LDAP filter. The search base DN identifies where in the directory to search for entries that match the filter. For example, if you are looking for printers, you might specify the base DN as ou=Printers,dc=example,dc=com. Perhaps you are visiting the GNB00 office and are looking for a printer. $ ldapsearch -b ou=Printers,dc=example,dc=com "(printerLocation=GNB00)" In the example, the LDAP filter indicates to the directory that you want to lookup printer entries where the printerLocation attribute is equal to GNB00. You also specify the host and port to access directory services, what protocol to use (for example, LDAP/SSL, or StartTLS to protect communication). If the directory service does not allow anonymous access to the data you want to search, you also identify who is performing the search and provide their credentials, such as a password or certificate. Finally, you can specify a list of attributes to return. If you do not specify attributes, then the search returns all user attributes for the entry. Search: Simple Filter The following example searches for entries with UID containing jensen, returning only DNs and uid values. $ ldapsearch -p 1389 -b dc=example,dc=com "(uid=*jensen*)" uid dn: uid=ajensen,ou=People,dc=example,dc=com uid: ajensen dn: uid=bjensen,ou=People,dc=example,dc=com uid: bjensen dn: uid=gjensen,ou=People,dc=example,dc=com uid: gjensen dn: uid=jjensen,ou=People,dc=example,dc=com uid: jjensen dn: uid=kjensen,ou=People,dc=example,dc=com uid: kjensen dn: uid=rjensen,ou=People,dc=example,dc=com uid: rjensen dn: uid=tjensen,ou=People,dc=example,dc=com uid: tjensen Result Code: 0 (Success) Search: Complex Filter The following example returns entries with uid containing jensen for users located in Santa Clara. The command returns the attributes associated with the person object class. $ ldapsearch -p 1389 -b ou=people,dc=example,dc=com "(&(uid=*jensen*)(l=Santa Clara))" @person dn: uid=ajensen,ou=People,dc=example,dc=com objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: posixAccount objectClass: top cn: Allison Jensen telephoneNumber: +1 408 555 7892 sn: Jensen dn: uid=gjensen,ou=People,dc=example,dc=com objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: posixAccount objectClass: top cn: Gern Jensen telephoneNumber: +1 408 555 3299 sn: Jensen dn: uid=kjensen,ou=People,dc=example,dc=com objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: posixAccount objectClass: top cn: Kurt Jensen telephoneNumber: +1 408 555 6127 sn: Jensen dn: uid=tjensen,ou=People,dc=example,dc=com objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: posixAccount objectClass: top cn: Ted Jensen telephoneNumber: +1 408 555 8622 sn: Jensen Search: Return Operational Attributes Use + in the attribute list after the filter to return all operational attributes. Alternatively, specify operational attributes by name. $ ldapsearch -p 1389 -b dc=example,dc=com uid=bjensen + dn: uid=bjensen,ou=People,dc=example,dc=com numSubordinates: 0 structuralObjectClass: inetOrgPerson pwdPolicySubentry: cn=Default Password Policy,cn=Password Policies,cn=config subschemaSubentry: cn=schema hasSubordinates: false entryDN: uid=bjensen,ou=people,dc=example,dc=com entryUUID: fc252fd9-b982-3ed6-b42a-c76d2546312c Search: Return Attributes for an Object Class Use @objectClass in the attribute list after the filter to return the attributes associated with a particular object class. $ ldapsearch -p 1389 -b dc=example,dc=com uid=bjensen @person dn: uid=bjensen,ou=People,dc=example,dc=com objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: posixAccount objectClass: top cn: Barbara Jensen cn: Babs Jensen telephoneNumber: +1 408 555 1862 sn: Jensen
Comparing Attribute Values Comparing attribute values The compare operation checks whether an attribute value you specify matches the attribute value stored on one or more directory entries. Compare: Checking <literal>authPassword</literal> In this example, Kirsten Vaughan checks whether the hashed password value matches the stored value on authPassword. $ ldapcompare -p 1389 -D "uid=kvaughan,ou=people,dc=example,dc=com" -w bribery 'authPassword:MD5$dFHgpDxXUT8=$qlC4xMXvmVlusJLz9/WJ5Q==' uid=kvaughan,ou=people,dc=example,dc=com Comparing type authPassword with value MD5$dFHgpDxXUT8=$qlC4xMXvmVlusJLz9/WJ5Q== in entry uid=kvaughan,ou=people,dc=example,dc=com Compare operation returned true for entry uid=kvaughan,ou=people,dc=example,dc=com
Updating the Directory Updating data LDIFExamples Authorized users can change directory data using the LDAP add, modify, modify DN, and delete operations.
Adding Entries With the ldapmodify -a command, authorized users can add entire entries from the same sort of LDIF file used to import and export data. Add: Two New Users $ cat new-users.ldif dn: cn=Arsene Lupin,ou=Special Users,dc=example,dc=com objectClass: person objectClass: top cn: Arsene Lupin telephoneNumber: +33 1 23 45 67 89 sn: Lupin dn: cn=Horace Velmont,ou=Special Users,dc=example,dc=com objectClass: person objectClass: top cn: Horace Velmont telephoneNumber: +33 1 12 23 34 45 sn: Velmont $ ldapmodify -a -p 1389 -D "uid=kvaughan,ou=people,dc=example,dc=com" -w bribery -f new-users.ldif Processing ADD request for cn=Arsene Lupin,ou=Special Users,dc=example,dc=com ADD operation successful for DN cn=Arsene Lupin,ou=Special Users,dc=example,dc=com Processing ADD request for cn=Horace Velmont,ou=Special Users,dc=example,dc=com ADD operation successful for DN cn=Horace Velmont,ou=Special Users,dc=example,dc=com
Modifying Entry Attributes With the ldapmodify command, authorized users can change the values of attributes in the directory using LDIF as specified in RFC 2849. Modify: Adding Attributes The following example adds a description and JPEG photo to Sam Carter's entry. $ cat scarter-mods.ldif dn: uid=scarter,ou=people,dc=example,dc=com changetype: modify add: description description: Accounting Manager - add: jpegphoto jpegphoto: /tmp/Samantha-Carter.jpg $ ldapmodify -p 1389 -D "uid=kvaughan,ou=people,dc=example,dc=com" -w bribery -f scarter-mods.ldif Processing MODIFY request for uid=scarter,ou=people,dc=example,dc=com MODIFY operation successful for DN uid=scarter,ou=people,dc=example,dc=com Modify: Changing an Attribute Value The following example replaces the description on Sam Carter's entry. $ cat scarter-newdesc.ldif dn: uid=scarter,ou=people,dc=example,dc=com changetype: modify replace: description description: Accounting Director $ ldapmodify -p 1389 -D "uid=kvaughan,ou=people,dc=example,dc=com" -w bribery -f scarter-newdesc.ldif Processing MODIFY request for uid=scarter,ou=people,dc=example,dc=com MODIFY operation successful for DN uid=scarter,ou=people,dc=example,dc=com Modify: Deleting an Attribute Value The following example deletes the JPEG photo on Sam Carter's entry. $ cat /path/to/scarter-deljpeg.ldif dn: uid=scarter,ou=people,dc=example,dc=com changetype: modify delete: jpegphoto $ ldapmodify -p 1389 -D "uid=kvaughan,ou=people,dc=example,dc=com" -w bribery -f scarter-deljpeg.ldif Processing MODIFY request for uid=scarter,ou=people,dc=example,dc=com MODIFY operation successful for DN uid=scarter,ou=people,dc=example,dc=com
Filtering Add & Modify Operations Updating data Filtering Some client applications send updates including attributes with names that differ from the attribute names defined in OpenDJ. Other client applications might try to update attributes they should not update, such as the operational attributes creatorsName, createTimestamp, modifiersName, and modifyTimestamp. Ideally you would fix the client application behavior, but that is not always feasible. You can configure the attribute cleanup plugin to filter add and modify requests, renaming attributes in requests using incorrect names, and removing attributes that applications should not change. Renaming Incoming Attributes The following example renames incoming email attributes to mail attributes. First, configure the attribute cleanup plugin to rename the inbound attribute. $ dsconfig -p 4444 -h `hostname` -D "cn=Directory Manager" -w password create-plugin --type attribute-cleanup --plugin-name "Rename email to mail" --set enabled:true --set rename-inbound-attributes:email:mail -X -n Next, see that it works as expected. $ cat email.ldif dn: uid=newuser,ou=People,dc=example,dc=com uid: newuser objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: top cn: New User sn: User ou: People email: newuser@example.com userPassword: changeme $ ldapmodify -p 1389 -D "cn=Directory Manager" -w password -a -f email.ldif Processing ADD request for uid=newuser,ou=People,dc=example,dc=com ADD operation successful for DN uid=newuser,ou=People,dc=example,dc=com $ ldapsearch -p 1389 -b dc=example,dc=com uid=newuser mail dn: uid=newuser,ou=People,dc=example,dc=com mail: newuser@example.com Removing Incoming Attributes The following example prevents client applications from adding or modifying creatorsName, createTimestamp, modifiersName, and modifyTimestamp attributes. First, set up the attribute cleanup plugin. $ dsconfig -p 4444 -h `hostname` -D "cn=Directory Manager" -w password create-plugin --type attribute-cleanup --plugin-name "Remove attrs" --set enabled:true --set remove-inbound-attributes:creatorsName --set remove-inbound-attributes:createTimestamp --set remove-inbound-attributes:modifiersName --set remove-inbound-attributes:modifyTimestamp -X -n Next, see that it works as expected. $ cat badattrs.ldif dn: uid=badattr,ou=People,dc=example,dc=com uid: newuser objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: top cn: Bad Attr sn: Attr ou: People mail: badattr@example.com userPassword: changeme creatorsName: cn=Bad Attr createTimestamp: Never in a million years. modifiersName: cn=Directory Manager,cn=Root DNs,cn=config modifyTimestamp: 20110930164937Z $ ldapmodify -p 1389 -D "cn=Directory Manager" -w password -a -f badattrs.ldif Processing ADD request for uid=badattr,ou=People,dc=example,dc=com ADD operation successful for DN uid=badattr,ou=People,dc=example,dc=com $ ldapsearch -p 1389 -b dc=example,dc=com uid=badattr + dn: uid=badattr,ou=People,dc=example,dc=com numSubordinates: 0 structuralObjectClass: inetOrgPerson pwdPolicySubentry: cn=Default Password Policy,cn=Password Policies,cn=config subschemaSubentry: cn=schema hasSubordinates: false entryDN: uid=badattr,ou=people,dc=example,dc=com entryUUID: 35e5cb0e-e929-49d8-a50f-2df036d60db9 pwdChangedTime: 20110930165959.135Z creatorsName: cn=Directory Manager,cn=Root DNs,cn=config createTimestamp: 20110930165959Z
Renaming Entries The Relative Distinguished Name (RDN) refers to the part of an entry's DN that distinguishes it from all other DNs at the same level in the directory tree. For example uid=bjensen is the RDN of the entry having DN uid=bjensen,ou=People,dc=example,dc=com. With the ldapmodify command, authorized users can rename entries in the directory. When you change the RDN of the entry, you are renaming the entry, modifying the value of the naming attribute, but also modifying the entry's DN. Rename: Modifying the DN Sam Carter is changing her last name to Jensen, and changing her login from scarter to sjensen. The following example renames and changes Sam Carter's entry accordingly. $ cat /path/to/scarter-sjensen.ldif dn: uid=scarter,ou=people,dc=example,dc=com changetype: modrdn newrdn: uid=sjensen deleteoldrdn: 1 dn: uid=sjensen,ou=people,dc=example,dc=com changetype: modify replace: cn cn: Sam Jensen - replace: sn sn: Jensen - replace: homeDirectory homeDirectory: /home/sjensen - replace: mail mail: sjensen@example.com $ ldapmodify -p 1389 -D "uid=kvaughan,ou=people,dc=example,dc=com" -w bribery -f /path/to/scarter-sjensen.ldif Processing MODIFY DN request for uid=scarter,ou=people,dc=example,dc=com MODIFY DN operation successful for DN uid=scarter,ou=people,dc=example,dc=com Processing MODIFY request for uid=sjensen,ou=people,dc=example,dc=com MODIFY operation successful for DN uid=sjensen,ou=people,dc=example,dc=com
Moving Entries When you rename an entry with child entries, the directory has to move all the entries underneath. The modify DN operation only works when moving entries in the same backend, under the same suffix. Also, depending on the number of entries you move, this can be a resource-intensive operation. With the ldapmodify command, authorized users can move entries in the directory. Move: Merging Customer and Employees Under <literal>ou=People</literal> The following example moves ou=Customers,dc=example,dc=com to ou=People,dc=example,dc=com, and then moves each employee under ou=Employees,dc=example,dc=com under ou=People,dc=example,dc=com as well, finally removing the empty ou=Employees,dc=example,dc=com container. $ cat move-customers.ldif dn: ou=Customers,dc=example,dc=com changetype: modrdn newrdn: ou=People deleteoldrdn: 1 newsuperior: dc=example,dc=com $ ldapmodify -p 1389 -D "cn=Directory Manager" -w password -f move-customers.ldif Processing MODIFY DN request for ou=Customers,dc=example,dc=com MODIFY DN operation successful for DN ou=Customers,dc=example,dc=com $ cat move-employees.pl #!/usr/bin/perl -w # For each employee, construct a spec to move under ou=People. while (<>) { # Next line folded for readability only. Should not be split. $_ =~ s/dn: (.*?)(,.*)/dn: $1$2\nchangetype: moddn\nnewrdn: $1\n deleteoldrdn: 0\nnewsuperior: ou=People,dc=example,dc=com/; print; } $ ldapsearch -p 1389 -b ou=Employees,dc=example,dc=com uid=* - | move-employees.pl > /tmp/move-employees.ldif $ head -n 6 /tmp/move-employees.ldif dn: uid=abarnes,ou=Employees,dc=example,dc=com changetype: moddn newrdn: uid=abarnes deleteoldrdn: 0 newsuperior: ou=People,dc=example,dc=com $ ldapmodify -p 1389 -D "cn=Directory Manager" -w password -f /tmp/move-employees.ldif Processing MODIFY DN request for uid=abarnes,ou=Employees,dc=example,dc=com MODIFY DN operation successful for DN uid=abarnes,ou=Employees,dc=example,dc=com Processing MODIFY DN request for uid=abergin,ou=Employees,dc=example,dc=com MODIFY DN operation successful for DN uid=abergin,ou=Employees,dc=example,dc=com ... Processing MODIFY DN request for uid=wlutz,ou=Employees,dc=example,dc=com MODIFY DN operation successful for DN uid=wlutz,ou=Employees,dc=example,dc=com $ ldapdelete -p 1389 -D "cn=Directory Manager" -w password ou=Employees,dc=example,dc=com Processing DELETE request for ou=Employees,dc=example,dc=com DELETE operation successful for DN ou=Employees,dc=example,dc=com
Deleting Entries With the ldapmodify command, authorized users can delete entries from the directory. Delete: Removing a Subtree The following example uses the subtree delete option to remove all Special Users from the directory. $ ldapdelete -p 1389 -D "cn=Directory Manager" -w password -x "ou=Special Users,dc=example,dc=com" Processing DELETE request for ou=Special Users,dc=example,dc=com DELETE operation successful for DN ou=Special Users,dc=example,dc=com
Changing Passwords PasswordsChanging With the ldappasswordmodify command, authorized users can change and reset user passwords. Password Reset The following example shows Kirsten Vaughan resetting Sam Carter's password. Kirsten has the appropriate privilege to reset Sam's password. The option means the same thing as . $ ldappasswordmodify -q -p 1389 -D "uid=kvaughan,ou=people,dc=example,dc=com" -w bribery -a "dn:uid=scarter,ou=people,dc=example,dc=com" -n ChangeMe The LDAP password modify operation was successful You could also accomplish password reset with the following command, but set-password-is-reset is a hidden option, supported only for testing. $ manage-account -D "cn=Directory Manager" -w password set-password-is-reset -b uid=scarter,ou=people,dc=example,dc=com -O true Password Is Reset: true Change Own Password You can use the ldappasswordmodify command to change your password, as long as you know your current password. $ ldappasswordmodify -p 1389 -a "dn:uid=bjensen,ou=people,dc=example,dc=com" --currentPassword hifalutin --newPassword secret12 The LDAP password modify operation was successful The same operation works for cn=Directory Manager. $ ldappasswordmodify -p 1389 -a "dn:cn=Directory Manager" --currentPassword password --newPassword secret12 The LDAP password modify operation was successful If you forget the password for cn=Directory Manager, then one remedy uses the following steps. Generate an encoded password value using the encode-password command. By default, the password for Directory Manager uses the SSHA512 password storage scheme. In the following example, the encoded password is wrapped to fit on a printed page. $ encode-password -s SSHA512 -i Please enter the password : Please renter the password: Encoded Password: "{SSHA512}U7Kx5oYcLxdsqSrpSkBk425LwL0Z61loNfS0dBVCcEKVhMyTT oe3oWikDJ/AJjKEkYBg+q3VUQ5hWgrGVf7MjfDrm5mum6yI" Stop OpenDJ. Edit config/config.ldif, replacing the userPassword value on the entry for cn=Directory Manager,cn=Root DNs,cn=config with the encoded password, taking care not to leave any whitespace at the end of the line. Start OpenDJ.
Configuring Default Settings PortsSettings for tools You can use ~/.opendj/tools.properties to set the defaults for bind DN, host name, and port number as in the following example. hostname=directory.example.com port=1389 bindDN=uid=kvaughan,ou=People,dc=example,dc=com ldapcompare.port=1389 ldapdelete.port=1389 ldapmodify.port=1389 ldappasswordmodify.port=1389 ldapsearch.port=1389 The location on Windows is %UserProfile%/.opendj/tools.properties.
Configuring Proxied Authorization Proxied authorization Proxied authorization provides a standard control as defined in RFC 4370 (and an earlier Internet-Draft) for binding with the user credentials of a proxy, who carries out LDAP operations on behalf of other users. You might use proxied authorization, for example, to have your application bind with its credentials, and then carry out operations as the users who login to the application. Suppose you have an administrative directory client application that has an entry in the directory with DN cn=My App,ou=Apps,dc=example,dc=com. You can give that application the access rights and privileges to use proxied authorization. The default access control for OpenDJ permits authenticated users to use the proxied authorization control. Suppose also that when directory administrator, Kirsten Vaughan, logs in to your application to change Babs Jensen's entry, your application looks up Kirsten's entry, and finds that she has DN uid=kvaughan,ou=People,dc=example,dc=com. For the example commands in the following procedure. My App uses proxied authorization to make a change to Babs's entry as Kirsten. To Set Up Proxied Authorization Grant access to applications that can use proxied authorization. $ ldapmodify -p 1389 -D "cn=Directory Manager" -w password dn: dc=example,dc=com changetype: modify add: aci aci: (target="ldap:///dc=example,dc=com") (targetattr ="* ")(version 3.0; acl "Allow apps proxied auth"; allow(all, proxy )(userdn = "ldap:///cn=*,ou=Apps,dc=example,dc=com");) Processing MODIFY request for dc=example,dc=com MODIFY operation successful for DN dc=example,dc=com Grant the privilege to use proxied authorization to My App. $ ldapmodify -p 1389 -D "cn=Directory Manager" -w password dn: cn=My App,ou=Apps,dc=example,dc=com changetype: modify add: ds-privilege-name ds-privilege-name: proxied-auth Processing MODIFY request for cn=My App,ou=Apps,dc=example,dc=com MODIFY operation successful for DN cn=My App,ou=Apps,dc=example,dc=com Test that My App can use proxied authorization. $ ldapmodify -p 1389 -D "cn=My App,ou=Apps,dc=example,dc=com" -w password -Y "dn:uid=kvaughan,ou=People,dc=example,dc=com" dn: uid=bjensen,ou=People,dc=example,dc=com changetype: modify replace: description description: Changed through proxied auth Processing MODIFY request for uid=bjensen,ou=People,dc=example,dc=com MODIFY operation successful for DN uid=bjensen,ou=People,dc=example,dc=com