For the latest copy of these release notes, please go here:
These release notes include:
This release of the LDAP C SDK is available on the following platforms:
The following were changed for this release of the LDAP C SDK:
http://home.netscape.com/eng/server/directory/4.1/technotes/proxyauth.html
http://www.ietf.org/internet-drafts/draft-ietf-ldapext-ldap-c-api-xx.txt
where xx is the draft version number. At the time of this writing, xx was 03 but this number is subject to change. The changes made to bring the LDAP C SDK in line with the new internet draft include:
typedef struct berval { unsigned long bv_len; char *bv_val; } BerValue;
Internal (Software) Token:secret12You can then point to this file using the -I option on the command line utility. For example:
-I /h/bjensen/.netscape/my_pin_fileThe use of either the PIN file or interactive prompting for your password means that your Cert DB password is not exposed through process examination (that is, by using the ps command on Unix).
The following bugs are fixed with this version of the SDK:
A new function has been added to the SDK to provide better SSL error messages. Its prototype is:
const char * LDAP_CALL ldapssl_err2string( const int prerrno );
This function should be called if an ldapssl_*() function returns an error code that is unknown to ldap_err2string() (returns "Unknown Error"). Call ldapssl_err2string() after you call any of the following functions:
The errors returned by these functions are usually related to certificate database corruption, missing certs in a certificate database, client authentication failures, and general ssl errors.
A new function has been added to the SDK to provide better SSL initialization. Its prototype is:
int LDAP_CALL ldapssl_pkcs_init(const struct ldapssl_pkcs_fns *pfns);
ldap_pkcs_init() sets up callbacks for the security library to obtain required runtime information. It can be used in place of ldapssl_client_init(), ldapssl_clientauth_init(), or ldapssl_advclientauth_init().
Because ldap_pkcs_init() is based on the ldapssl_pkcs_fns structure, you do not need to know all of the security parameters at initialization, unlike the ldapssl_*_init() functions which did require all security parameters to be known at initialization.
Over time the use of the ldapssl_*_int() functions will be depricated in favor of ldap_pcks_init(). ldap_pcks_init() is preferred because it is thread-safe, while the ldapssl_*_init() functions are not.
The ldapssl_pkcs_fns structure is defined as follows:
typedef int (LDAP_PKCS_GET_TOKEN_CALLBACK)(void *context, char **tokenname);
typedef int (LDAP_PKCS_GET_PIN_CALLBACK)(void *context, const char *tokenname, char **tokenpin);
typedef int (LDAP_PKCS_GET_CERTPATH_CALLBACK)(void *context, char **certpath);
typedef int (LDAP_PKCS_GET_KEYPATH_CALLBACK)(void *context,char **keypath);
typedef int (LDAP_PKCS_GET_MODPATH_CALLBACK)(void *context, char **modulepath);
typedef int (LDAP_PKCS_GET_CERTNAME_CALLBACK)(void *context, char **certname);
typedef int (LDAP_PKCS_GET_DONGLEFILENAME_CALLBACK)(void *context, char **filename);
#define PKCS_STRUCTURE_ID 1
struct ldapssl_pkcs_fns {
int local_structure_id;
void *local_data;
LDAP_PKCS_GET_CERTPATH_CALLBACK *pkcs_getcertpath;
LDAP_PKCS_GET_CERTNAME_CALLBACK *pkcs_getcertname;
LDAP_PKCS_GET_KEYPATH_CALLBACK *pkcs_getkeypath;
LDAP_PKCS_GET_MODPATH_CALLBACK *pkcs_getmodpath;
LDAP_PKCS_GET_PIN_CALLBACK *pkcs_getpin;
LDAP_PKCS_GET_TOKEN_CALLBACK *pkcs_gettokenname;
LDAP_PKCS_GET_DONGLEFILENAME_CALLBACK *pkcs_getdonglefilename;
};
You can find an example of how to set up this call back structure here:
http://home.netscape.com/eng/server/directory/4.1/technotes/ldap_pkcs_init.html
Various macros and structures have been added to the SDK to allow for compile-time and run-time discovery of the API version. Their intended use is to allow you to ensure that you are compiling and running with the correct version of the LDAP C SDK. These features are required by the latest C LDAP API Internet Draft.
As a result of these changes, the command line tools bundled with the SDK will now check to ensure that they are running with the correct verion of the library. If your library path variable (LD_LIBRARY_PATH on most Unix systems and the PATH variable on NT) is set so that an old version of the LDAP C library is in use, then the command line tools can return one of the following error messages:
ldapsearch: unable to retrieve LDAP library version information;
this program requires an LDAP library that implements revision
2003 or greater of the LDAP API.
ldapsearch: this program requires an LDAP library that implements revision
2003 or greater of the LDAP API; running with revision 2002.
ldapsearch: this program requires Netscape Communications Corp.'s LDAP
library version 3.20 or greater; running with version 3.00.
By default, the tools will exit if they see a mismatch. You can cause the tools to continue to try to operate when a mismatch is encountered by using the -0 option (that's a zero, not an 'o').
You can now hand ldap_url_parse() a string of the format:
ldap://host1:port1 host2:port2 host2:port3 ... hostn:portn/<basedn>
and it will return results that are acceptable to ldap_init(). For example:
LDAP *ld; LDAPURLDesc *ludpp; int res; char *url = "ldap://phonebook.airius.com:2389 directory.airius.com:389/o=airius.com"; res = ldap_url_parse(url, &ludpp); ld = ldap_init(ludpp->host, ludpp->port);
This causes ldap_init() to try to connect to each host and port in the URL string until it finds a host to which it can connect.
Note that ludpp->port is set to the port identified on the last host in the URL string. If ludpp->port is used as shown here, then the last port identified on the URL string becomes the default port for any hosts for which a port is not explicitly set. That is, in the above example if the URL string contained:
ldap://phonebook.airius.com phonebook2.airius.com phonebook3.airius.com:2389/o=airius.com
then ldap_init() would use port 2389 for all the hosts that it tries. If the last host in the string does not identify a port, then ludpp->port is set to zero (0). Setting the port to 0 tells ldap_init() to use the default port, which is 389 for ldap:// urls and 636 for ldaps:// urls.
The extra thread functions were provided in the 3.1 SDK as an experimental mechanism for improving SDK performance in multi-threaded applications. Subsequent bench mark testing along with locking bugs encountered on MP machines has resulted in the following changes to these functions:
LDAP_TF_MUTEX_TRYLOCK_CALLBACK *ltf_mutex_trylock;
LDAP_TF_SEMA_ALLOC_CALLBACK *ltf_sema_alloc;
LDAP_TF_SEMA_FREE_CALLBACK *ltf_sema_free;
LDAP_TF_SEMA_WAIT_CALLBACK *ltf_sema_wait;
LDAP_TF_SEMA_POST_CALLBACK *ltf_sema_post;
The use of these functions will not result in any improved performance. Additionally, their use can result in dead locks, especially on MP machines.
LDAP_TF_THREADID_CALLBACK *ltf_threadid_fn;
Internal data types for liblber have been upgraded so that the data types are 64-bit safe. This is done in the following section of code in lber.h:
/*
* Implementation-specific integer data types. If living in an LP64
* environment (where sizeof(long) is 64 bits), we use unsigned ints;
* otherwise we use unsigned longs. The goal is to always use 32-bit
* quantities and to also be backwards compatible with previous SDK
* versions which used unsigned longs.
*/
#if defined(_LP64)
typedef unsigned int ber_len_t;
typedef int ber_signed_len_t;
typedef unsigned int ber_tag_t;
typedef int ber_int_t;
#else
typedef unsigned long ber_len_t;
typedef long ber_signed_len_t;
typedef unsigned long ber_tag_t;
typedef long ber_int_t;
#endif
This change was made to make liblber consistent between environments where ints are 32 bits and ints are 64 bits. However, this change may cause some compilers, especially c++ compilers where strong type checking is enforced, to emit warnings or errors when you recompile your old code.
The following are issues and suggestions for previous users of the LDAP C SDK who are migrating to the 4.0 LDAP C SDK:
ldap_get_option(LDAP *ld, LDAP_OPT_API_INFO, void *optdata);