Network Working Group
T. Howes
Request for Comments: 1823
M. Smith
Category: Informational
University of Michigan
August 1995
The LDAP Application Program Interface
Status of this Memo
This memo provides information for the Internet community.
This memo
does not specify an Internet standard of any kind.
Distribution of
this memo is unlimited.
1. Introduction
This document defines a C language application program
interface to
the lightweight directory access protocol (LDAP). The
LDAP API is
designed to be powerful, yet simple to use. It defines
compatible
synchronous and asynchronous interfaces to LDAP to suit
a wide
variety of applications. This document gives a brief
overview of the
LDAP model, then an overview of how the API is used by
an application
program to obtain LDAP information. The API calls
are described in
detail, followed by an appendix that provides some example
code
demonstrating the use of the API.
2. Overview of the LDAP Model
LDAP is the lightweight directory access protocol, described
in [2]
and [7]. It can provide a lightweight frontend to the
X.500 directory
[1], or a stand-alone service. In either mode, LDAP is
based on a
client-server model in which a client makes a TCP connection
to an
LDAP server, over which it sends requests and receives
responses.
The LDAP information model is based on the entry, which
contains
information about some object (e.g., a person).
Entries are composed
of attributes, which have a type and one or more values.
Each
attribute has a syntax that determines what kinds of values
are
allowed in the attribute (e.g., ASCII characters, a jpeg
photograph,
etc.) and how those values behave during directory operations
(e.g.,
is case significant during comparisons).
Entries are organized in a tree structure, usually based
on
political, geographical, and organizational boundaries.
Each entry is
uniquely named relative to its sibling entries by its
relative
distinguished name (RDN) consisting of one or more distinguished
attribute values from the entry. At most one value
from each
attribute may be used in the RDN. For example, the
entry for the
Howes & Smith Informational [Page 1]
RFC 1823
LDAP API
August 1995
person Babs Jensen might be named with the "Barbara Jensen"
value
from the commonName attribute. A globally unique name
for an entry,
called a distinguished name or DN, is constructed by concatenating
the sequence of RDNs from the root of the tree down to
the entry. For
example, if Babs worked for the University of Michigan,
the DN of her
U-M entry might be "cn=Barbara Jensen, o=University of
Michigan,
c=US". The DN format used by LDAP is defined in [4].
Operations are provided to authenticate, search for and
retrieve
information, modify information, and add and delete entries
from the
tree. The next sections give an overview of how
the API is used and
detailed descriptions of the LDAP API calls that implement
all of
these functions.
3. Overview of LDAP API Use
An application generally uses the LDAP API in four simple steps.
o Open a connection to an LDAP server.
The ldap_open() call
returns a handle to the
connection, allowing multiple
connections to be open at
once.
o Authenticate to the LDAP server and/or
the X.500 DSA. The
ldap_bind() call and friends
support a variety of
authentication methods.
o Perform some LDAP operations and obtain
some results.
ldap_search() and friends
return results which can be parsed
by ldap_result2error(),
ldap_first_entry(), ldap_next_entry(),
etc.
o Close the connection. The ldap_unbind()
call closes the
connection.
Operations can be performed either synchronously or asynchronously.
Synchronous calls end in _s. For example, a synchronous
search can be
completed by calling ldap_search_s(). An asynchronous
search can be
initiated by calling ldap_search(). All synchronous routines
return
an indication of the outcome of the operation (e.g, the
constant
LDAP_SUCCESS or some other error code). The asynchronous
routines
return the message id of the operation initiated. This
id can be used
in subsequent calls to ldap_result() to obtain the result(s)
of the
operation. An asynchronous operation can be abandoned
by calling
ldap_abandon().
Howes & Smith Informational [Page 2]
RFC 1823
LDAP API
August 1995
Results and errors are returned in an opaque structure
called
LDAPMessage. Routines are provided to parse this
structure, step
through entries and attributes returned, etc. Routines
are also
provided to interpret errors. The next sections describe
these
routines in more detail.
4. Calls for performing LDAP operations
This section describes each LDAP operation API call in
detail. All
calls take a "connection handle", a pointer to an LDAP
structure
containing per-connection information. Many routines
return results
in an LDAPMessage structure. These structures and others
are
described as needed below.
4.1. Opening a connection
ldap_open() opens a connection to the LDAP server.
typedef struct ldap {
/* ... opaque parameters ... */
int ld_deref;
int ld_timelimit;
int ld_sizelimit;
int ld_errno;
char *ld_matched;
char *ld_error;
/* ... opaque parameters ... */
} LDAP;
LDAP *ldap_open( char *hostname, int portno );
Parameters are:
hostname Contains a space-separated list
of hostnames or dotted
strings representing the IP address of hosts running an
LDAP server to connect to. The hosts are tried in the
order listed, stopping with the first one to which a
successful connection is made;
portno contains the TCP port
number to which to connect. The
default LDAP port can be obtained by supplying the
constant LDAP_PORT.
ldap_open() returns a "connection handle", a pointer to
an LDAP
structure that should be passed to subsequent calls pertaining
to the
connection. It returns NULL if the connection cannot be
opened. One
of the ldap_bind calls described below must be completed
before other
operations can be performed on the connection.
Howes & Smith Informational [Page 3]
RFC 1823
LDAP API
August 1995
The calling program should assume nothing about the order
of the
fields in the LDAP structure. There may be other fields
in the
structure for internal library use. The fields shown above
are
described as needed in the description of other calls
below.
4.2. Authenticating to the directory
ldap_bind() and friends are used to authenticate to the directory.
int ldap_bind( LDAP *ld, char *dn, char *cred, int method );
int ldap_bind_s( LDAP *ld, char *dn, char *cred, int method );
int ldap_simple_bind( LDAP *ld, char *dn, char *passwd );
int ldap_simple_bind_s( LDAP *ld, char *dn, char *passwd );
int ldap_kerberos_bind( LDAP *ld, char *dn );
int ldap_kerberos_bind_s( LDAP *ld, char *dn );
Parameters are:
ld The connection handle;
dn The name of the entry to bind as;
cred The credentials with which to authenticate;
method One of LDAP_AUTH_SIMPLE, LDAP_AUTH_KRBV41, or
LDAP_AUTH_KRBV42,
indicating the authentication method to use;
passwd For ldap_simple_bind(), the password to compare
to the entry's
userPassword
attribute;
There are three types of bind calls, providing simple authentication,
kerberos authentication, and general routines to do either
one. In
the case of Kerberos version 4 authentication using the
general
ldap_bind() routines, the credentials are ignored, as
the routines
assume a valid ticket granting ticket already exists which
can be
used to retrieve the appropriate service tickets.
Synchronous versions of the routines have names that end
in _s.
These routines return the result of the bind operation,
either the
constant LDAP_SUCCESS if the operation was successful,
or another
LDAP error code if it was not. See the section below on
error
handling for more information about possible errors and
how to
interpret them.
Howes & Smith Informational [Page 4]
RFC 1823
LDAP API
August 1995
Asynchronous versions of these routines return the message
id of the
bind operation initiated. A subsequent call to ldap_result(),
described below, can be used to obtain the result of the
bind. In
case of error, these routines will return -1, setting
the ld_errno
field in the LDAP structure appropriately.
Note that no other operations over the connection should
be attempted
before a bind call has successfully completed. Subsequent
bind calls
can be used to re-authenticate over the same connection.
4.3. Closing the connection
ldap_unbind() is used to unbind from the directory and
close the
connection.
int ldap_unbind( LDAP *ld );
Parameters are:
ld The connection handle.
ldap_unbind() works synchronously, unbinding from the directory,
closing the connection, and freeing up the ld structure
before
returning. ldap_unbind() returns LDAP_SUCCESS (or another
LDAP error
code if the request cannot be sent to the LDAP server).
After a call
to ldap_unbind(), the ld connection handle is invalid.
4.4. Searching
ldap_search() and friends are used to search the LDAP directory,
returning a requested set of attributes for each entry
matched.
There are three variations.
struct
timeval {
long tv_sec;
long tv_usec;
};
int ldap_search(
LDAP *ld,
char *base,
int scope,
char *filter,
char *attrs[],
int attrsonly
);
int ldap_search_s(
LDAP
*ld,
char
*base,
Howes & Smith Informational [Page 5]
RFC 1823
LDAP API
August 1995
int
scope,
char
*filter,
char
*attrs[],
int
attrsonly,
LDAPMessage **res
);
int ldap_search_st(
LDAP
*ld,
char
*base,
int
scope,
char
*filter,
char
*attrs[],
int
attrsonly,
struct timeval *timeout,
LDAPMessage **res
);
Parameters are:
ld The connection handle;
base The dn of the entry at which to start the search;
scope One of LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL,
or
LDAP_SCOPE_SUBTREE, indicating the scope of the search;
filter A character string as described
in RFC 1558 [3],
representing the search filter;
attrs A NULL-terminated array of
strings indicating which
attributes to return for each matching entry. Passing
NULL for this parameter causes all available attributes
to be retrieved;
attrsonly A boolean value that should be zero if both attribute
types and values are to be returned, non-zero if only
types are wanted;
timeout For the ldap_search_st() call, this
specifies the local
search timeout value;
res For the synchronous
calls, this is a result parameter
which will contain the results of the search upon
completion of the call.
There are three fields in the ld connection handle which
control how
the search is performed. They are:
Howes & Smith Informational [Page 6]
RFC 1823
LDAP API
August 1995
ld_sizelimit A limit on the number of entries to return
from the
search. A value of zero means no limit;
ld_timelimit A limit on the number of seconds to spend
on the search.
A value of zero means no limit;
ld_deref One of LDAP_DEREF_NEVER,
LDAP_DEREF_SEARCHING,
LDAP_DEREF_FINDING, or LDAP_DEREF_ALWAYS, specifying
how aliases should be handled during the search. The
LDAP_DEREF_SEARCHING value means aliases should be
dereferenced during the search but not when locating
the base object of the search. The LDAP_DEREF_FINDING
value means aliases should be dereferenced when
locating the base object but not during the search.
An asynchronous search is initiated by calling ldap_search().
It
returns the message id of the initiated search. The results
of the
search can be obtained by a subsequent call to ldap_result().
The
results can be parsed by the result parsing routines described
in
detail later. In case of error, -1 is returned and
the ld_errno
field in the LDAP structure is set appropriately.
A synchronous search is performed by calling ldap_search_s()
or
ldap_search_st(). The routines are identical, except that
ldap_search_st() takes an additional parameter specifying
a timeout
for the search. Both routines return an indication
of the result of
the search, either LDAP_SUCCESS or some error indication
(see Error
Handling below). The entries returned from the search
(if any) are
contained in the res parameter. This parameter is opaque
to the
caller. Entries, attributes, values, etc., should
be extracted by
calling the parsing routines described below. The results
contained
in res should be freed when no longer in use by calling
ldap_msgfree(), described later.
4.5. Reading an entry
LDAP does not support a read operation directly. Instead,
this
operation is emulated by a search with base set to the
DN of the
entry to read, scope set to LDAP_SCOPE_BASE, and filter
set to
"(objectclass=*)". attrs contains the list of attributes
to return.
4.6. Listing the children of an entry
LDAP does not support a list operation directly. Instead,
this
operation is emulated by a search with base set to the
DN of the
entry to list, scope set to LDAP_SCOPE_ONELEVEL, and filter
set to
"(objectclass=*)". attrs contains the list of attributes
to return
for each child entry.
Howes & Smith Informational [Page 7]
RFC 1823
LDAP API
August 1995
4.7. Modifying an entry
The ldap_modify() and ldap_modify_s() routines are used
to modify an
existing LDAP entry.
typedef
struct ldapmod {
int
mod_op;
char
*mod_type;
union {
char
**modv_strvals;
struct berval **modv_bvals;
} mod_vals;
} LDAPMod;
#define
mod_values mod_vals.modv_strvals
#define
mod_bvalues mod_vals.modv_bvals
int ldap_modify( LDAP *ld, char *dn, LDAPMod *mods[] );
int ldap_modify_s( LDAP *ld, char *dn, LDAPMod *mods[] );
Parameters are:
ld The connection handle;
dn The name of the entry to modify;
mods A NULL-terminated array of
modifications to make to the
entry.
The fields in the LDAPMod structure have the following meanings:
mod_op The modification operation to perform.
It should be one of
LDAP_MOD_ADD, LDAP_MOD_DELETE, or LDAP_MOD_REPLACE. This
field also indicates the type of values included in the
mod_vals union. It is ORed with LDAP_MOD_BVALUES to select
the mod_bvalues form. Otherwise, the mod_values form is
used;
mod_type The type of the attribute to modify;
mod_vals The values (if any) to add, delete, or replace.
Only one of
the mod_values or mod_bvalues variants should be used,
selected by ORing the mod_op field with the constant
LDAP_MOD_BVALUES. mod_values is a NULL-terminated array of
zero-terminated strings and mod_bvalues is a NULL-terminated
array of berval structures that can be used to pass binary
values such as images.
Howes & Smith Informational [Page 8]
RFC 1823
LDAP API
August 1995
For LDAP_MOD_ADD modifications, the given values are added
to the
entry, creating the attribute if necessary. For
LDAP_MOD_DELETE
modifications, the given values are deleted from the entry,
removing
the attribute if no values remain. If the entire
attribute is to be
deleted, the mod_vals field should be set to NULL.
For
LDAP_MOD_REPLACE modifications, the attribute will have
the listed
values after the modification, having been created if
necessary. All
modifications are performed in the order in which they
are listed.
ldap_modify_s() returns the LDAP error code resulting
from the
modify operation. This code
can be interpreted by ldap_perror()
and friends.
ldap_modify() returns the message id of the request it
initiates, or
-1 on error. The result of the operation can be
obtained by calling
ldap_result().
4.8. Modifying the RDN of an entry
The ldap_modrdn() and ldap_modrdn_s() routines are used
to change the
name of an LDAP entry.
int ldap_modrdn(
LDAP *ld,
char *dn,
char *newrdn,
int deleteoldrdn
);
int ldap_modrdn_s(
LDAP *ld,
char *dn,
char *newrdn,
int deleteoldrdn
);
Parameters are:
ld The connection handle;
dn The name of the entry whose RDN is to be changed;
newrdn The new RDN to give the entry;
deleteoldrdn A boolean value, if non-zero indicating
that the old
RDN value(s) should be removed, if zero indicating that
the old RDN value(s) should be retained as non-
distinguished values of the entry.
Howes & Smith Informational [Page 9]
RFC 1823
LDAP API
August 1995
The ldap_modrdn_s() routine is synchronous, returning the
LDAP error
code indicating the outcome of the operation.
The ldap_modrdn() routine is asynchronous, returning the
message id
of the operation it initiates, or -1 in case of trouble.
The result
of the operation can be obtained by calling ldap_result().
4.9. Adding an entry
ldap_add() and ldap_add_s() are used to add entries to
the LDAP
directory.
int ldap_add( LDAP *ld, char *dn, LDAPMod *attrs[] );
int ldap_add_s( LDAP *ld, char *dn, LDAPMod *attrs[] );
Parameters are:
ld The connection handle;
dn The name of the entry to add;
attrs The entry's attributes, specified using the LDAPMod
structure
defined for ldap_modify().
The mod_type and mod_vals fields
should be filled in.
The mod_op field is ignored unless ORed
with the constant
LDAP_MOD_BVALUES, used to select the
mod_bvalues case of
the mod_vals union.
Note that the parent of the entry must already exist.
ldap_add_s() is synchronous, returning the LDAP error code
indicating
the outcome of the operation.
ldap_add() is asynchronous, returning the message id of
the operation
it initiates, or -1 in case of trouble. The result of
the operation
can be obtained by calling ldap_result().
4.10. Deleting an entry
ldap_delete() and ldap_delete_s() are used to delete entries
from the
LDAP directory.
int ldap_delete( LDAP *ld, char *dn );
int ldap_delete_s(
LDAP *ld, char *dn );
Howes & Smith Informational [Page 10]
RFC 1823
LDAP API
August 1995
Parameters are:
ld The connection handle;
dn The name of the entry to delete.
Note that the entry to delete must be a leaf entry (i.e.,
it must
have no children). Deletion of entire subtrees is not
supported by
LDAP.
ldap_delete_s() is synchronous, returning the LDAP error
code
indicating the outcome of the operation.
ldap_delete() is asynchronous, returning the message id
of the
operation it initiates, or -1 in case of trouble. The
result of the
operation can be obtained by calling ldap_result().
5. Calls for abandoning an operation
ldap_abandon() is used to abandon an operation in progress.
int ldap_abandon( LDAP *ld, int msgid );
ldap_abandon() abandons the operation with message id msgid.
It
returns zero if the abandon was successful, -1 otherwise.
After a
successful call to ldap_abandon(), results with the given
message id
are never returned from a call to ldap_result().
6. Calls for obtaining results
ldap_result() is used to obtain the result of a previous
asynchronously initiated operation. ldap_msgfree() frees
the results
obtained from a previous call to ldap_result(), or a synchronous
search routine.
int ldap_result(
LDAP
*ld,
int
msgid,
int
all,
struct timeval *timeout,
LDAPMessage **res
);
int ldap_msgfree(
LDAPMessage *res );
Howes & Smith Informational [Page 11]
RFC 1823
LDAP API
August 1995
Parameters are:
ld The connection handle;
msgid The message id of the operation
whose results are to be
returned, or the constant LDAP_RES_ANY if any result is
desired;
all A boolean parameter that
only has meaning for search
results. If non-zero it indicates that all results of a
search should be retrieved before any are returned. If zero,
search results (entries) will be returned one at a time as
they arrive;
timeout A timeout specifying how long to wait for
results to be
returned. A NULL value causes ldap_result() to block until
results are available. A timeout value of zero second
specifies a polling behavior;
res For ldap_result(), a
result parameter that will contain the
result(s) of the operation. For ldap_msgfree(), the result
chain to be freed, obtained from a previous call to
ldap_result() or ldap_search_s() or ldap_search_st().
Upon successful completion, ldap_result() returns the type
of the
result returned in the res parameter. This will be one
of the
following constants.
LDAP_RES_BIND
LDAP_RES_SEARCH_ENTRY
LDAP_RES_SEARCH_RESULT
LDAP_RES_MODIFY
LDAP_RES_ADD
LDAP_RES_DELETE
LDAP_RES_MODRDN
LDAP_RES_COMPARE
ldap_result() returns 0 if the timeout expired and -1 if
an error
occurs, in which case the ld_errno field of the ld structure
will be
set accordingly.
ldap_msgfree() frees the result structure pointed to be
res and
returns the type of the message it freed.
Howes & Smith Informational [Page 12]
RFC 1823
LDAP API
August 1995
7. Calls for error handling
The following calls are used to interpret errors returned
by other
LDAP API routines.
int ldap_result2error(
LDAP
*ld,
LDAPMessage *res,
int
freeit
);
char *ldap_err2string( int err );
void ldap_perror( LDAP *ld, char *msg );
Parameters are:
ld The connection handle;
res The result of an LDAP
operation as returned by ldap_result()
or one of the synchronous API operation calls;
freeit A boolean parameter indicating whether
the res parameter
should be freed (non-zero) or not (zero);
err An LDAP error code, as
returned by ldap_result2error() or
one of the synchronous API operation calls;
msg A message to be displayed before the LDAP error message.
ldap_result2error() is used to convert the LDAP result
message
obtained from ldap_result(), or the res parameter returned
by one of
the synchronous API operation calls, into a numeric LDAP
error code.
It also parses the ld_matched and ld_error portions of
the result
message and puts them into the connection handle information.
All the
synchronous operation routines call ldap_result2error()
before
returning, ensuring that these fields are set correctly.
The relevant
fields in the connection structue are:
ld_matched In the event of an LDAP_NO_SUCH_OBJECT error
return, this
parameter contains the extent of the DN matched;
ld_error This parameter contains the error
message sent in the
result by the LDAP server.
ld_errno The LDAP error code indicating the
outcome of the
operation. It is one of the following constants:
Howes & Smith Informational [Page 13]
RFC 1823
LDAP API
August 1995
LDAP_SUCCESS
LDAP_OPERATIONS_ERROR
LDAP_PROTOCOL_ERROR
LDAP_TIMELIMIT_EXCEEDED
LDAP_SIZELIMIT_EXCEEDED
LDAP_COMPARE_FALSE
LDAP_COMPARE_TRUE
LDAP_STRONG_AUTH_NOT_SUPPORTED
LDAP_STRONG_AUTH_REQUIRED
LDAP_NO_SUCH_ATTRIBUTE
LDAP_UNDEFINED_TYPE
LDAP_INAPPROPRIATE_MATCHING
LDAP_CONSTRAINT_VIOLATION
LDAP_TYPE_OR_VALUE_EXISTS
LDAP_INVALID_SYNTAX
LDAP_NO_SUCH_OBJECT
LDAP_ALIAS_PROBLEM
LDAP_INVALID_DN_SYNTAX
LDAP_IS_LEAF
LDAP_ALIAS_DEREF_PROBLEM
LDAP_INAPPROPRIATE_AUTH
LDAP_INVALID_CREDENTIALS
LDAP_INSUFFICIENT_ACCESS
LDAP_BUSY
LDAP_UNAVAILABLE
LDAP_UNWILLING_TO_PERFORM
LDAP_LOOP_DETECT
LDAP_NAMING_VIOLATION
LDAP_OBJECT_CLASS_VIOLATION
LDAP_NOT_ALLOWED_ON_NONLEAF
LDAP_NOT_ALLOWED_ON_RDN
LDAP_ALREADY_EXISTS
LDAP_NO_OBJECT_CLASS_MODS
LDAP_RESULTS_TOO_LARGE
LDAP_OTHER
LDAP_SERVER_DOWN
LDAP_LOCAL_ERROR
LDAP_ENCODING_ERROR
LDAP_DECODING_ERROR
LDAP_TIMEOUT
LDAP_AUTH_UNKNOWN
LDAP_FILTER_ERROR
LDAP_USER_CANCELLED
LDAP_PARAM_ERROR
LDAP_NO_MEMORY
Howes & Smith Informational [Page 14]
RFC 1823
LDAP API
August 1995
ldap_err2string() is used to convert a numeric LDAP error
code, as
returned by ldap_result2error() or one of the synchronous
API
operation calls, into an informative NULL-terminated character
string
message describing the error. It returns a pointer
to static data.
ldap_perror() is used to print the message supplied in
msg, followed
by an indication of the error contained in the ld_errno
field of the
ld connection handle, to standard error.
8. Calls for parsing search entries
The following calls are used to parse the entries returned
by
ldap_search() and friends. These entries are returned
in an opaque
structure that should only be accessed by calling the
routines
described below. Routines are provided to step through
the entries
returned, step through the attributes of an entry, retrieve
the name
of an entry, and retrieve the values associated with a
given
attribute in an entry.
8.1. Stepping through a set of entries
The ldap_first_entry() and ldap_next_entry() routines are
used to
step through a set of entries in a search result.
ldap_count_entries() is used to count the number of entries
returned.
LDAPMesage *ldap_first_entry( LDAP *ld, LDAPMessage *res );
LDAPMesage *ldap_next_entry( LDAP *ld, LDAPMessage *entry );
int ldap_count_entries( LDAP *ld, LDAPMessage *res );
Parameters are:
ld The connection handle;
res The search result, as obtained by
a call to one of the syn-
chronous search
routines or ldap_result();
entry The entry returned by a previous call to ldap_first_entry()
or
ldap_next_entry().
ldap_first_entry() and ldap_next_entry() will return NULL
when no
more entries exist to be returned. NULL is also returned
if an error
occurs while stepping through the entries, in which case
the ld_errno
field of the ld connection handle will be set to indicate
the error.
ldap_count_entries() returns the number of entries contained
in a
chain of entries. It can also be used to count the number
of entries
Howes & Smith Informational [Page 15]
RFC 1823
LDAP API
August 1995
that remain in a chain if called with an entry returned
by
ldap_first_entry() or ldap_next_entry().
8.2. Stepping through the attributes of an entry
The ldap_first_attribute() and ldap_next_attribute() calls
are used
to step through the list of attribute types returned with
an entry.
char *ldap_first_attribute(
LDAP
*ld,
LDAPMessage *entry,
void
**ptr
);
char *ldap_next_attribute(
LDAP
*ld,
LDAPMessage *entry,
void
*ptr
);
Parameters are:
ld The connection handle;
entry The entry whose attributes are to be stepped
through, as
returned by
ldap_first_entry() or ldap_next_entry();
ptr In ldap_first_attribute(), the address
of a pointer used
internally to
keep track of the current position in the entry.
In ldap_next_attribute(),
the pointer returned by a previous
call to ldap_first_attribute().
ldap_first_attribute() and ldap_next_attribute() will return
NULL
when the end of the attributes is reached, or if there
is an error,
in which case the ld_errno field in the ld connection
handle will be
set to indicate the error.
Both routines return a pointer to a per-connection buffer
containing
the current attribute name. This should be treated like
static data.
ldap_first_attribute() will allocate and return in ptr
a pointer to a
BerElement used to keep track of the current position.
This pointer
should be passed in subsequent calls to ldap_next_attribute()
to step
through the entry's attributes.
The attribute names returned are suitable for passing in
a call to
ldap_get_values() and friends to retrieve the associated
values.
Howes & Smith Informational [Page 16]
RFC 1823
LDAP API
August 1995
8.3. Retrieving the values of an attribute
ldap_get_values() and ldap_get_values_len() are used to
retrieve the
values of a given attribute from an entry. ldap_count_values()
and
ldap_count_values_len() are used to count the returned
values.
ldap_value_free() and ldap_value_free_len() are used to
free the
values.
typedef
struct berval {
unsigned long bv_len;
char
*bv_val;
};
char **ldap_get_values(
LDAP
*ld,
LDAPMessage *entry,
char
*attr
);
struct
berval **ldap_get_values_len(
LDAP
*ld,
LDAPMessage *entry,
char
*attr
);
int ldap_count_values( char **vals );
int ldap_count_values_len( struct berval **vals );
int ldap_value_free( char **vals );
int ldap_value_free_len( struct berval **vals );
Parameters are:
ld The connection handle;
entry The entry from which to retrieve values, as
returned by
ldap_first_entry()
or ldap_next_entry();
attr The attribute whose values are to be retrieved,
as returned by
ldap_first_attribute()
or ldap_next_attribute(), or a caller-
supplied string
(e.g., "mail");
vals The values returned by a previous call
to ldap_get_values() or
ldap_get_values_len().
Howes & Smith Informational [Page 17]
RFC 1823
LDAP API
August 1995
Two forms of the various calls are provided. The first
form is only
suitable for use with non-binary character string data
only. The
second _len form is used with any kind of data.
Note that the values returned are malloc'ed and should
be freed by
calling either ldap_value_free() or ldap_value_free_len()
when no
longer in use.
8.4. Retrieving the name of an entry
ldap_get_dn() is used to retrieve the name of an entry.
ldap_explode_dn() is used to break up the name into its
component
parts. ldap_dn2ufn() is used to convert the name into
a more "user
friendly" format.
char *ldap_get_dn( LDAP *ld, LDAPMessage *entry );
char **ldap_explode_dn( char *dn, int notypes );
char *ldap_dn2ufn( char *dn );
Parameters are:
ld The connection handle;
entry The entry whose name is to be retrieved,
as returned by
ldap_first_entry()
or ldap_next_entry();
dn The dn to explode, as returned by ldap_get_dn();
notypes A boolean parameter, if non-zero indicating that
the dn com-
ponents
should have their type information stripped off
(i.e.,
"cn=Babs" would become "Babs").
ldap_get_dn() will return NULL if there is some error parsing
the dn,
setting ld_errno in the ld connection handle to indicate
the error.
It returns a pointer to malloc'ed space that the caller
should free
by calling free() when it is no longer in use. Note
the format of
the DNs returned is given by [4].
ldap_explode_dn() returns a char * array containing the
RDN
components of the DN supplied, with or without types as
indicated by
the notypes parameter. The array returned should be freed
when it is
no longer in use by calling ldap_value_free().
ldap_dn2ufn() converts the DN into the user friendly format
described
in [5]. The UFN returned is malloc'ed space that should
be freed by a
call to free() when no longer in use.
Howes & Smith Informational [Page 18]
RFC 1823
LDAP API
August 1995
9. Security Considerations
LDAP supports minimal security during connection authentication.
10. Acknowledgements
This material is based upon work supported by the National
Science
Foundation under Grant No. NCR-9416667.
11. Bibliography
[1] The Directory: Selected Attribute Syntaxes. CCITT,
Recommendation X.520.
[2] Howes, T., Kille, S., Yeong, W., and C. Robbins, "The
String
Representation of Standard Attribute
Syntaxes", University of
Michigan, ISODE Consortium, Performance
Systems International,
NeXor Ltd., RFC 1778, March 1995.
[3] Howes, T., "A String Representation of LDAP Search
Filters", RFC
1558, University of Michigan,
December 1993.
[4] Kille, S., "A String Representation of Distinguished
Names", RFC
1779, ISODE Consortium, March
1995.
[5] Kille, S., "Using the OSI Directory to Achieve User
Friendly
Naming", RFC 1781, ISODE
Consortium, March 1995.
[6] S.P. Miller, B.C. Neuman, J.I. Schiller, J.H. Saltzer,
"Kerberos
Authentication and Authorization
System", MIT Project Athena
Documentation Section E.2.1,
December 1987
[7] Yeong, W., Howes, T., and S. Kille, "Lightweight Directory
Access
Protocol," RFC 1777, Performance
Systems International,
University of Michigan, ISODE
Consortium, March 1995.
Howes & Smith Informational [Page 19]
RFC 1823
LDAP API
August 1995
12. Authors' Addresses
Tim Howes
University of Michigan
ITD Research Systems
535 W William St.
Ann Arbor, MI 48103-4943
USA
Phone: +1 313 747-4454
EMail: tim@umich.edu
Mark Smith
University of Michigan
ITD Research Systems
535 W William St.
Ann Arbor, MI 48103-4943
USA
Phone: +1 313 764-2277
EMail: mcs@umich.edu
Howes & Smith Informational [Page 20]
RFC 1823
LDAP API
August 1995
13. Appendix A - Sample LDAP API Code
#include <ldap.h>
main()
{
LDAP
*ld;
LDAPMessage
*res, *e;
int
i;
char
*a, *dn;
void
*ptr;
char
**vals;
/* open
a connection */
if ( (ld
= ldap_open( "dotted.host.name", LDAP_PORT ))
== NULL )
exit( 1 );
/* authenticate
as nobody */
if ( ldap_simple_bind_s(
ld, NULL, NULL ) != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_simple_bind_s" );
exit( 1 );
}
/* search
for entries with cn of "Babs Jensen",
return all attrs */
if ( ldap_search_s(
ld, "o=University of Michigan, c=US",
LDAP_SCOPE_SUBTREE, "(cn=Babs Jensen)", NULL, 0, &res )
!= LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_search_s" );
exit( 1 );
}
/* step
through each entry returned */
for (
e = ldap_first_entry( ld, res ); e != NULL;
e = ldap_next_entry( ld, e ) ) {
/* print its name */
dn = ldap_get_dn( ld, e );
printf( "dn: %s0, dn );
free( dn );
/* print each attribute */
for ( a = ldap_first_attribute( ld, e, &ptr );
a != NULL;
a = ldap_next_attribute( ld, e, ptr ) ) {
printf( "attribute: %s0, a );
/* print each value */
Howes & Smith Informational [Page 21]
RFC 1823
LDAP API
August 1995
vals = ldap_get_values( ld, e, a );
for ( i = 0; vals[i] != NULL; i++ ) {
printf( "value: %s0, vals[i] );
}
ldap_value_free( vals );
}
}
/* free
the search results */
ldap_msgfree(
res );
/* close
and free connection resources */
ldap_unbind(
ld );
}
Howes & Smith
Informational
[Page 22]