Accessing an LDAP Server (Perl Cookbook, 2nd Edition)

## 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("ldap.example.com") 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 http://www.onlamp.com/topics/apache/ldap.

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 => "o=oreilly.com",
>                           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  => 'sherlock@221b.uk',
>                      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  => 'sholmes@braintrust.uk' },
>            delete  => { cn => [ 'S Holmes' ] });

### 18.8.4. See Also

The documentation for the CPAN module Net::LDAP; the Net::LDAP home page at http://perl-ldap.sourceforge.net/

Copyright © 2003 O'Reilly & Associates. All rights reserved.