1. Overview

LDAP (Lightweight Directory Access Protocol) is a well-known protocol that provides directory services. LDAP servers that implement this protocol are widely used across organizations to facilitate user management and authentication. On the other hand, ldapsearch is a command-line LDAP client that can send queries to a server and display the results to the user.

In this tutorial, we’ll examine methods to reduce the verbosity of the output generated by the ldapsearch command.

2. Test Environment

For our testing, we need an LDAP server populated with data. If we don’t have an LDAP server, we can install one from the repositories of most major Linux distributions and populate it with the required data.

2.1. Install an OpenLdap Server

In Ubuntu, we can install the slapd and ldap-utils packages using apt:

$ sudo apt install slapd ldap-utils

Now that we’ve installed the LDAP server, we can use dpkg-reconfigure to perform some configuration, like setting the domain name of our organization and the administrator’s password:

$ sudo dpkg-reconfigure slapd

During the LDAP server configuration, we set the domain name to example.com. This will also be the search base that we’ll use throughout the examples that we’ll see.

2.2. Create ldif File With Records

At this point, we can add some content. Our objective is to create a new group and a user under this group.

To do so, we create a new file and add some LDAP entries according to the LDAP Interchange Format:

dn: cn=developers,dc=example,dc=com
objectClass: posixGroup
cn: developers
gidNumber: 1

dn: uid=A1000,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: A1000
sn: Surname
givenName: Name
cn: Name Surname
displayName: Name Surname
uidNumber: 1
gidNumber: 1
userPassword: {CRYPT}x
gecos: Name Surname
loginShell: /bin/bash
homeDirectory: /home/A1000

We save the above attributes to a file named add_usergroup.ldif.

In, first, we create a developers group under the example.com organization. Next, we create a new user with username A1000 under the developers group. A key point here is that the A1000 user is connected with the developers group through the gidNumber attribute. In addition, we define user data like name, surname, password, home directory, and others.

2.3. Apply Configuration

Now, we’re ready to add the two records using the ldapadd command:

$ ldapadd -x -D cn=admin,dc=example,dc=com -W -f add_usergroup.ldif
Enter LDAP Password:
adding new entry "cn=developers,dc=example,dc=com"

adding new entry "uid=A1000,dc=example,dc=com"

Indeed, the group and the user were added to the directory:

  • x uses simple authentication
  • D sets the distinguished name of the LDAP account for authentication
  • W prompts for the simple authentication password
  • f specifies the file with the content we want to add

As a result, we now have a working LDAP server with two records.

3. The ldapsearch Command

The ldapsearch command performs searches on an LDAP server. The command accepts a filter to select particular directory entries. Furthermore, we can define a list of attributes to display instead of displaying them all.

Our objective is to find user A1000 that we created in the previous section:

$ ldapsearch -x -b dc=example,dc=com uid=A1000 displayName
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope subtree
# filter: uid=A1000
# requesting: displayName
#

# A1000, example.com
dn: uid=A1000,dc=example,dc=com
displayName: Name Surname

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Here, we used the -b option to set the search base. In our case, the search base is dc=example,dc=com which is also the suffix of our directory’s tree structure. Moreover, we used the -x option to enable simple authentication instead of SASL authentication.

Besides these two options, we used a filter and an attribute list. The filter is the uid=A1000 value, which will get the entry of user A1000. As for the attributes, we chose to display only the displayName attribute.

It’s evident that the output of the command is too verbose. If we’re creating a shell script, we may also need some way to keep only the value of the displayName attribute.

4. The ldapsearch -L Option

The -L option makes the ldapsearch command output records using version 1 of the LDAP Data Interchange Format. Interestingly, we can set this option up to three times:

  • -LL disables remarks
  • -LLL removes the LDIF version information from the output

Let’s examine the effect of the last option:

$ ldapsearch -x -LLL -b dc=example,dc=com uid=A1000 displayName
dn: uid=A1000,dc=example,dc=com
displayName: Name Surname

Indeed, we can see that the output is reduced when compared to the command’s output without the -LLL option. As a matter of fact, only the distinguished name of the entry and the attribute’s name and value are printed.

5. Using awk

To further reduce the output of the ldapsearch command so that it prints only values, we can use a tool like awk. In our case, the objective is to eliminate the first line which displays the distinguished name of the matched entry and remove the attribute name.

We can achieve this with an awk script:

$ ldapsearch -x -LLL -b dc=example,dc=com uid=A1000 displayName |
  awk '{if(NR!=1){for(i=2;i<=NF;i++){printf "%s ", $i }}}END{print}'
Name Surname

Indeed, we can see that the first line was omitted, and only the attribute value was printed.

In particular, the above awk script utilizes the built-in NR and NF variables. The NR variable holds the current row number, while NF holds the total number of fields of the current row. As a result, the if condition skips the first line. Next, the for loop prints all the fields of the current row starting from the second field, thus omitting the attribute name which is the first field. Finally, we use the printf function to print fields, but we also add a print command to print a newline character before the program ends.

6. Using sed

Instead of awk, we can use the sed stream editor to strip out the unwanted information printed by the ldapsearch command. In a similar way to the previous section, we want to print only the attribute value and omit the distinguished name:

$ ldapsearch -x -LLL -b dc=example,dc=com uid=A1000 displayName |
  sed '1d;s/[a-zA-Z:]*//' | tr '\n' ' '
 Name Surname

As we can see, we printed the displayName attribute value only. To achieve this, we’ve used two semicolon-separated sed commands:

  1. 1d deletes the first line
  2. s/[a-zA-z:]*// matches the string until the first space or tab character and substitutes it with an empty character

Finally, we used the tr command to remove newline characters.

7. Using a Bash Shell Script

Another solution would be to write a Bash shell script that filters the undesired information and keeps only the value of the selected attribute:

output=$(ldapsearch -x -LLL -b dc=example,dc=com uid=A1000 displayName |
  tr '\n' ' ' )
IFS=':'
read -a sarray <<< "$output"
echo ${sarray[-1]} | xargs

In the above script, we begin by saving the output of the ldapsearch command to the output variable via command substitution. Then, we set the colon character as the internal field separator so that the subsequent read command splits its input with this character instead of with space. Furthermore, the read command stores the tokens in the sarray array. Finally, we echo the last element of sarray after we trim leading whitespaces with the xargs command.

Let’s save the above script in the ldaptest.sh file, grant the execute permission, and run it:

$ ./ldaptest.sh
Name Surname

Indeed, we printed only the value of the displayName attribute.

8. Conclusion

In this article, we learned three methods for keeping only the attribute value of a ldapsearch response. The first one used the awk tool while the second utilized the sed stream editor. In the third method, we created a small Bash shell script. Critically, all methods are based on the -LLL option of the ldapsearch command.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.