OpenLDAP 2.3 libldap upgrade howto

Şuraya atla: kullan, ara

With OpenLDAP 2.3.X a number of deprecated functions are not available in the interface any more by default. This document outlines how you can still make use of the old functions and it gives some hints how applications can be updated to use the non-deprecated variants of the functions.

Using deprecated libldap functions with OpenLDAP 2.3

The deprecated functions are just hidden be the LDAP_DEPRECATED pre-compiler directive in ldap.h. To make them available again to a LDAP client application the LDAP_DEPRECATED macro has to be defined to '1'. The easiest way to achieve this is by adding -DLDAP_DEPRECATED to the CPP_FLAGS enviroment variable. It's also possible to put a line #define LDAP_DEPRECATED 1 into your source code before the #include <ldap.h> line.

In the future it might be possible that the deprecated function get removed completely from libldap. So it might be a good idea to update clients to use the non-deprecated versions of the libldap functions.

Updating to the non-deprecated functions

The "normal" synchronus LDAP operations

  • ldap_abandon
  • ldap_add_s
  • ldap_compare_s
  • ldap_delete_s
  • ldap_modify_s
  • ldap_unbind_s

These can be replaced relatively easy with the new '_ext_s' calls ('ldap_(abandon|add|compare|delete|modify|unbind)_ext_s()'). All the new functions take two extra arguments ('LDAPControl **serverctrls' and 'LDAPControl **clientctrls'), which can just be set to NULL when replacing the old calls. E.g.:

 ldap_add_s(ldap, dn, attrs);

becomes:

 ldap_add_ext_s(ldap, dn, attrs, NULL, NULL );

The synchronus search calls (ldap_search_s and ldap_search_st) can be replaced with ldap_search_ext_s e.g.:

 ldap_search_s(ldap, base, scope, filter, attrs, attrsonly, res);

becomes:

 ldap_search_ext_s(ldap, base, scope, filter, attrs, attrsonly, NULL, NULL, NULL, 0, res);

and:

 ldap_search_st(ldap, base, scope, filter, attrs, attrsonly, timeout, res);

becomes:

 ldap_search_ext_s(ldap, base, scope, filter, attrs, attrsonly, NULL, NULL, timeout, 0, res);

The asynchronus LDAP operations

The asynchronus calls are similar

  • ldap_add
  • ldap_compare
  • ldap_delete
  • ldap_modify
  • ldap_search
  • ldap_unbind

They are replaced with the corresponding ldap_*_ext() function. Addtionally to the two extra LDAPControl** arguments they take a int* Argument to return the resulting message id to the caller (the old calls return the message id via the return code). The return code of the new calls is an LDAP error code or LDAP_SUCCESS if everything went ok. Example:

     int msgid;
     int result;
     msgid = ldap_add(ldap, dn, attrs);
     if( msgid < 0 ) {
         result = ....
     }

becomes:

   int msgid;
   int result;
   result = ldap_add_ext(ldap, dn, attrs, NULL, NULL, &msgid)
   if( result != LDAP_SUCCESS ) {
      ...
   }

MODRDN operations

The calls for the MODRDN operation:

  • ldap_rename2
  • ldap_rename2_s
  • ldap_modrdn
  • ldap_modrdn_s
  • ldap_modrdn2
  • ldap_modrdn2_s

have been consolidated to the functions ldap_rename an ldap_rename_s. ldap_rename_s takes the following arguments:

   LDAP *ld,
   LDAP_CONST char *dn,
   LDAP_CONST char *newrdn,
   LDAP_CONST char *newSuperior,
   int deleteoldrdn,
   LDAPControl **sctrls,
   LDAPControl **cctrls

the sctrls and cctrls arguments can be set up NULL. When replacing ldap_modrdn* the newSuperior argument can also be set to NULL. The async ldap_rename function additionally needs an argument int *msgid see above (async calls) on how to handle this.

BIND Operations

These bind operations are no longer available:

  • ldap_bind
  • ldap_bind_s
  • ldap_simple_bind
  • ldap_simple_bind_s

They can be replace by ldap_sasl_bind_s. The interface looks like this:

   ldap_sasl_bind_s( 
       LDAP *ld,
       LDAP_CONST char *dn,
       LDAP_CONST char *mechanism,
       struct berval *cred,
       LDAPControl **serverctrls,
       LDAPControl **clientctrls,
       struct berval **servercredp
   );

The paramenter 'mechanism' should be set to LDAP_SASL_SIMPLE(NULL). Note: The credentials are not passed as a char* any longer you need to put them in a struct *berval which is defined as:

   struct berval{
         char* bv_val;
         ber_len_t bv_len;
   }

where bv_len indicates the length of the value. serverctrls, clientctrls and servercredp can be set to NULL.

Result parsing and error handling

The function ldap_result2error() should be replaced with ldap_parse_result(). It takes the following arguments:

     LDAP            *ld,
     LDAPMessage     *res,
     int             *errcodep,
     char            **matcheddnp,
     char            **errmsgp,
     char            ***referralsp,
     LDAPControl     ***serverctrlsp,
     int             freeit

Example:

   int result;
   result = ldap_result2err(ldap, res, freeit);
   

becomes:

     int ret;
     int result;
     char *errmsg;
     char *matcheddn;
     
     ret = ldap_parse_result(ldap, res, &result, &matcheddn, &errmsg,
                             NULL, NULL, freeit)
     if( ret != LDAP_SUCCESS ) {
        /* result parsing failed */
     }

matcheddn and errmsg have to be freed by calling ldap_memfree(). If you are not interested in matcheddn or errmsg you can use NULL for them as well.

   ldap_perror()

Replace it with:

   ldap_get_option( ld, LDAP_OPT_RESULT_CODE, &rc );
   fprintf( stderr, "%s: %s", msg, ldap_err2string( rc ));

ldap_init() and ldap_open()

These are replace by ldap_initialize. Note that ldap_initialize takes an URI instead of the hostname and port:

     LDAP *ldap = ldap_init( "ldap.suse.de", 389);

becomes:

     LDAP *ldap;
     ldap_initialize( &ldap, "ldap://ldap.suse.de" );

ldap_get_values() and friends

Replace ldap_get_values with ldap_get_values_len which returns the values as struct berval** instead of char**

Replace ldap_count_values with ldap_count_values_len. The argument of ldap_count_values_len in a struct berval** as returned by ldap_get_values_len.

Replace ldap_value_free with ldap_value_free_len. The argument of ldap_value_free_len in a struct berval** as returned by ldap_get_values_len.

Removed without replacement

The following calls have been removed from libldap completely with out any replacement:

  • ldap_sort_entries
  • ldap_sort_values
  • ldap_sort_strcasecmp

More information

More information on the LDAP C API can be found in the (expired) internet draft for the API. If you have the openldap2 package installed you can find it here: /usr/share/doc/packages/openldap2/drafts/draft-ietf-ldapext-ldap-c-api-xx.txt

Also you can take a look at the various man-pages that get installed with the openldap2-devel package.