Recipe 18.8 Accessing an LDAP Server

18.8.1 Problem

You want to fetch or maintain information from a Lightweight Directory Access Protocol (LDAP) server. For example, you have a list of email addresses in your company, and you want correct names for those people.

18.8.2 Solution

Use the Net::LDAP module from CPAN. For example, to search, use:

use Net::LDAP;

$ldap = Net::LDAP->new("") or die $@;
$ldap->bind( );
$mesg = $ldap->search(base => $base_dn,
                      filter => $FILTER);

$mesg->code( ) && die $mesg->error;

foreach $result ($mesg->all_entries) {
    # do something with $result
$ldap->unbind( );

18.8.3 Discussion

The Net::LDAP module manages an LDAP session. It is a pure Perl module, so it doesn't require a C compiler to install. To use it effectively, though, you'll need to know a little about LDAP in general and the query syntax in particular. If you're new to LDAP, you might want to read the articles at

The four steps to working with an LDAP server are connecting, authenticating, interacting, and logging off. Interacting includes searching, adding, deleting, and altering records.

The connect method establishes a connection to the LDAP server and is immediately followed by a call to the bind method. If you give no argument to bind, you log into the LDAP server anonymously. You can give a fully qualified Distinguished Name (DN) and password to authenticate yourself:

$ldap->bind("cn=directory manager,ou=gurus,dc=oreilly,dc=com",
            password => "timtoady") or die $@;

This sends the username and password unencrypted over the wire. For encrypted access, pass a sasl parameter to bind to use an Authen::SASL object to authenticate with.

The search method returns an object containing a set of entries. You can fetch that entire set of entries with all_entries as shown in the Solution, or one by one thus:

$num_entries = $mesg->count( );
for ($i=0; $i < $num_entries; $i++) {
  my $entry = $mesg->entry($i);
  # ...

You can even pop entries off the results stack:

while (my $entry = $mesg->shift_entry) {
  # ...

Each entry is an object with methods for querying attributes:

foreach $attr ($entry->attributes) {
  @values = $entry->get($attr);
  print "$attr : @values\n";

For a complete list of valid entry methods, see the Net::LDAP::Entry documentation. The DN is not an attribute of an entry, so to obtain the DN for an entry, use the dn method:

$dn = $entry->dn;

The basic components of a search are the base and the filter. The base marks the top of the tree being searched, and filter indicates which records you're interested in:

$mesg = $ldap->search(base => "",
                      filter => "uid=gnat");

You can limit how much of the tree is searched with an additional scope parameter: setting it to "base" searches only the base node of the tree. A value of "one" searches only nodes directly beneath the named node. The default value is "sub", meaning every node under the one named.

You can also administrate as well as search. For example, the add method inserts a record into the LDAP database:

$res = $ldap->add("cn=Sherlock Holmes, o=Sleuths B Us, c=gb",
       attr => [ cn    => ["Sherlock Holmes", "S Holmes"],
                 sn    => "Holmes",
                 mail  => '',
                 objectclass => [qw(top person organizationalPerson
                                    inetOrgPerson)] ]);

$res->code && warn "Couldn't add record: " . $res->error;

Similarly, you can delete records:

$res = $ldap->delete($DN);
$res && warn "Couldn't delete: " . $res->error;

The powerful modify method lets you make substantial changes to the information on a particular DN. See the documentation for Net::LDAP for information beyond these examples:

$res = $ldap->modify("cn=Sherlock Holmes, o=Sleuths B Us, c=gb",
       add     => { phone => '555 1212' },
       replace => { mail  => '' },
       delete  => { cn => [ 'S Holmes' ] });

18.8.4 See Also

The documentation for the CPAN module Net::LDAP; the Net::LDAP home page at