5. Implementation

In setting out to implement LDAP we had three goals in mind:

- provide a freely available reference implementation of the protocol;

- enable the development of LDAP clients on a wide variety of platforms; and

- solve the problem of providing access to our campus X.500 directory.

In addition, we have found our implementation has been incorporated into a number of vendor offerings, increasing the availability of LDAP products.

Our LDAP implementation has three main components: a server, a client library, and various clients. Our LDAP server, ldapd, is based on the popular ISO Development Environment (ISODE) package. We use the ISODE OSI stack implementation and DAP client library to access X.500. The ldapd server supports connections to multiple X.500 servers, providing efficient handling of referrals.

The ldapd server can be run as a UNIX stand-alone daemon or from inetd, the UNIX Internet protocol daemon. It accepts connections from LDAP clients, forking off a copy of itself to handle each connection. It also supports connectionless LDAP (CLDAP) [10], a version of LDAP that runs over UDP or other connectionless transport. CLDAP is useful in applications where speed is paramount, the information desired is small, and the connection setup overhead of LDAP is too large.

Key to the success of our LDAP implementation has been libldap, the LDAP client library. The libldap library gives programmers a simple yet powerful C Language API for accessing the X.500 directory through LDAP. The library is self-contained, including the necessary ASN.1/BER routines for producing and reading LDAP protocol elements. It contains routines to begin and end sessions with the directory, perform searches and other operations, and parse and display the results obtained from the directory. Figure 4 is a C code fragment showing a simple use of libldap. It illustrates the synchronous interface provided by libldap. Asynchronous routines are also provided.

#include <ldap.h>
LDAP *ld;
LDAPMessage *e, *r;
char *a, *dn;
/* open a connection and authenticate */
if ((ld = ldap_open("hostname", LDAP_PORT))
== NULL)
fail();
if (ldap_simple_bind_s(ld, NULL, NULL) !=
LDAP_SUCCESS)
fail();
/* search for entries, return all attrs */
if (ldap_search_s(ld, "c=US", LDAP_SCOPE_ONELEVEL,
"o=*michigan*", NULL, 0, &r) != LDAP_SUCCESS)
fail();
/* step through each entry returned */
for (e = ldap_first_entry(ld, r); e != NULL;
e = ldap_next_entry(ld, e)) {
/* get and print the entry name */
dn = ldap_getdn(ld, e);
printf("entry: %s\n", dn);
free(dn);
/* step through each attribute */
for (a = ldap_first_attribute(ld, e);
a != NULL;
a = ldap_next_attribute(ld, e, a)) {
printf("attr: %s\n", a);
/* get and print vals */
v = ldap_get_values(ld, e, a);
for (i = 0; v[i] != NULL; i++) {
printf("val: %s\n", v[i]);
}
ldap_value_free(v);
}

Figure 4. Sample libldap code

This code fragment searches for and retrieves entries from the directory. The entries are then stepped through and each value of each attribute is printed. If the attribute names retrieved are known, ldap_get_values() can be called with the names directly.

In addition to the basic operations shown in Figure 4, libldap contains routines to assist LDAP application developers in a variety of ways. There are display template routines which provide a standardized way of displaying entries. The display format is governed by a configuration file that tells which attributes to display for entries of a particular object class and how to display them. By using these routines, no code changes are necessary for an application to change how entries are displayed, add a new attribute to the display, etc.

Also provided are routines to assist in the construction of search filters. Often, different filters need to be constructed based on user input. For example, in a simple look-up application if a user types in a number, one might want to perform a search for entries with a phone number (home, work, fax, or pager) matching all or part of the number. If an alphabetic string is input, a search by name is more appropriate. If an exact match search yields no results, a less restrictive approximate search might be tried. The get filter routines automate the process of creating these filters. The filters produced are specified in a configuration file via regular expressions that are matched against user input.

Many LDAP client applications have been developed by us and others on the Internet. Some of the more interesting applications include maX.500, waX.500 and xax500, GUI clients for the Macintosh, MS Windows, and X Windows, respectively; go500gw, a gopher to X.500 gateway; web500gw, a World Wide Web to X.500 gateway; and mail500 and fax500, RFC 822-based X.500-capable mailers. Work is ongoing on other applications as well.


[Contents] [Previous] [Next]