[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
LDAP API questions
I have some questions regarding the differences between OpenLDAP's
libraries and the Netscape LDAP C SDK 3.0. My goal is to develop
an LDAP client that can be linked against either library.
I've included pseudo code for my LDAP client, below. It is based
upon various example programs and the book _Programming
Directory-Enabled Applications with LDAP_ by Tim Howes and Mark Smith.
My LDAP client is a daemon which allows network clients to connect
and interactively issue one or more queries consisting of LDAP filter
strings. The base dn and attribute list are predefined by the
application and cannot be changed by the user.
I'm using a Red Hat Linux 6.1 i386 distribution, but I've replaced
their OpenLDAP packages with ones that I've built myself. I'm using
OpenLDAP 1.2.9 with BerkeleyDB 2.7.7. I've populated the database
and I can search it successfully with the ldapsearch program, with
some custom PerLDAP scripts, and also with my LDAP client.
My questions:
1. How do you distinguish between the various LDAP SDK's,
programmatically? Currently, if the LDAP_OPT_SIZELIMIT symbol
is defined, I assume that I'm using Netscape's SDK. I selected
that symbol somewhat arbitrarily.
Is there a better way to do this?
2. What differences exist in the LDAP API supplied by the various
LDAP SDK's? Some differences that I know of are:
a. Netscape wants to treat the LDAP session handle (eg. LDAP *ld)
as an opaque structure, and therefore supplies functions to get
at its internals. This affects how the programmer gets at
ld_errno, for example.
b. OpenLDAP returns a char pointer from ldap_first_attribute() and
ldap_next_attribute(), to a static buffer. Therefore, you must
not free() the returned pointer. The Netscape documentation
tells you to call ldap_memfree() on the pointer returned by
ldap_first_attribute() and ldap_next_attribute(). Note that
OpenLDAP has no ldap_memfree() function.
c. OpenLDAP documents the ber_free() function, while Netscape's
documentation talks about ldap_ber_free(). However, Netscape's
example programs use ber_free() and that function *is* in their
library. The book I cited above also uses ber_free().
d. The Netscape SDK requires you to link in a threads library (eg.
-lpthread). I have the Netscape SDK with SSL support. I have not
used the one without SSL, so I don't know if it is any different.
This caused a problem for my application, which is not threaded.
My application would become wedged in __sigsuspend() after having
several of its clients connect and/or disconnect simultaneously.
Not being familiar with debugging threaded programs, my solution
was to switch to the OpenLDAP SDK. This "solved" the problem.
e. When using the OpenLDAP SDK, you will not normally call ber_free()
following the classic for(...) loop to fetch an entry's attributes.
Doing so will eventually cause a SIGSEGV (ie. a segmentation
violation). This is because OpenLDAP's ldap_next_attribute() has
already freed the BerElement when it returns NULL, signaling the
end of the entry's attributes. With the Netscape SDK, you *do*
need to call ber_free() (or ldap_ber_free(); see above).
What other differences exist between LDAP SDK's?
I would appreciate hearing from anyone who has used more than one LDAP
SDK. Thanks in advance.
-- cut here for LDAP client pseudo code --
new_client() {
connect();
while ((filter = fgets(...)) != NULL) {
search();
}
disconnect();
}
connect() {
ld = ldap_init(host,port);
ldap_simple_bind_s(ld,NULL,NULL);
}
search() {
ldap_search_s(ld,base,scope,filter,attrs,attrsonly,&result);
n = ldap_count_entries(ld,result);
for (e = ldap_first_entry(ld,result); e != NULL;
e = ldap_next_entry(ld,e)) {
dn = ldap_get_dn(ld,e);
for (a = ldap_first_attribute(ld,e,&ber); a != NULL;
a = ldap_next_attribute(ld,e,ber)) {
vals = ldap_get_values(ld,e,a);
#if (LDAP_SDK == NETSCAPE)
ldap_memfree(a);
#endif
}
#if (LDAP_SDK == NETSCAPE)
if (ber != NULL)
ldap_ber_free(ber,0);
#endif
#if (LDAP_SDK == OPENLDAP)
if (a != NULL)
ber_free(ber,0);
#endif
}
ldap_msgfree(result);
/* memory for dn and vals gets freed before next search() */
}
disconnect() {
ldap_unbind(ld);
}
-- end pseudo code --
--
Thomas J. Pinkl 738 Louis Drive
Unix Systems Programmer Warminster, Pa 18974
Health Business Systems, Inc. (215) 442-9300 x9260