]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/getdn.c
ITS#5300
[openldap] / libraries / libldap / getdn.c
index d44ddf19f7799b4e3e867a94770eb2a9cd28ca1f..d43287172576ff1174dffff2afaf20f26ebb5137 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2004 The OpenLDAP Foundation.
+ * Copyright 1998-2007 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,6 @@
 /* extension to UFN that turns trailing "dc=value" rdns in DNS style,
  * e.g. "ou=People,dc=openldap,dc=org" => "People, openldap.org" */
 #define DC_IN_UFN
-#if 0
-#define PRETTY_ESCAPE
-#endif
 
 /* parsing/printing routines */
 static int str2strval( const char *str, ber_len_t stoplen, struct berval *val, 
@@ -92,11 +89,7 @@ ldap_get_dn( LDAP *ld, LDAPMessage *entry )
        char            *dn;
        BerElement      tmp;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY, "ldap_get_dn\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_TRACE, "ldap_get_dn\n", 0, 0, 0 );
-#endif
 
        assert( ld != NULL );
        assert( LDAP_VALID(ld) );
@@ -119,11 +112,7 @@ ldap_get_dn_ber( LDAP *ld, LDAPMessage *entry, BerElement **berout,
        ber_len_t       len = 0;
        int rc = LDAP_SUCCESS;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY, "ldap_get_dn_ber\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_TRACE, "ldap_get_dn_ber\n", 0, 0, 0 );
-#endif
 
        assert( ld != NULL );
        assert( LDAP_VALID(ld) );
@@ -170,11 +159,7 @@ ldap_dn2ufn( LDAP_CONST char *dn )
 {
        char    *out = NULL;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY, "ldap_dn2ufn\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 );
-#endif
 
        ( void )ldap_dn_normalize( dn, LDAP_DN_FORMAT_LDAP, 
                &out, LDAP_DN_FORMAT_UFN );
@@ -193,11 +178,7 @@ ldap_explode_dn( LDAP_CONST char *dn, int notypes )
        int     iRDN;
        unsigned flag = notypes ? LDAP_DN_FORMAT_UFN : LDAP_DN_FORMAT_LDAPV3;
        
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY, "ldap_explode_dn\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 );
-#endif
 
        if ( ldap_str2dn( dn, &tmpDN, LDAP_DN_FORMAT_LDAP ) 
                        != LDAP_SUCCESS ) {
@@ -237,11 +218,7 @@ ldap_explode_rdn( LDAP_CONST char *rdn, int notypes )
        const char      *p;
        int             iAVA;
        
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY, "ldap_explode_rdn\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 );
-#endif
 
        /*
         * we only parse the first rdn
@@ -322,11 +299,7 @@ ldap_dn2dcedn( LDAP_CONST char *dn )
 {
        char    *out = NULL;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY, "ldap_dn2dcedn\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_TRACE, "ldap_dn2dcedn\n", 0, 0, 0 );
-#endif
 
        ( void )ldap_dn_normalize( dn, LDAP_DN_FORMAT_LDAP, 
                                   &out, LDAP_DN_FORMAT_DCE );
@@ -339,11 +312,7 @@ ldap_dcedn2dn( LDAP_CONST char *dce )
 {
        char    *out = NULL;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY, "ldap_dcedn2dn\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_TRACE, "ldap_dcedn2dn\n", 0, 0, 0 );
-#endif
 
        ( void )ldap_dn_normalize( dce, LDAP_DN_FORMAT_DCE, &out, LDAP_DN_FORMAT_LDAPV3 );
 
@@ -355,11 +324,7 @@ ldap_dn2ad_canonical( LDAP_CONST char *dn )
 {
        char    *out = NULL;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY, "ldap_dn2ad_canonical\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_TRACE, "ldap_dn2ad_canonical\n", 0, 0, 0 );
-#endif
 
        ( void )ldap_dn_normalize( dn, LDAP_DN_FORMAT_LDAP, 
                       &out, LDAP_DN_FORMAT_AD_CANONICAL );
@@ -372,16 +337,15 @@ ldap_dn2ad_canonical( LDAP_CONST char *dn )
  * from ( fin & LDAP_DN_FORMAT_MASK ) to ( fout & LDAP_DN_FORMAT_MASK )
  * 
  * fin can be one of:
- *     LDAP_DN_FORMAT_LDAP             (rfc 2253 and ldapbis liberal, 
- *                                     plus some rfc 1779)
- *     LDAP_DN_FORMAT_LDAPV3           (rfc 2253 and ldapbis)
- *     LDAP_DN_FORMAT_LDAPV2           (rfc 1779)
+ *     LDAP_DN_FORMAT_LDAP             (RFC 4514 liberal, plus some RFC 1779)
+ *     LDAP_DN_FORMAT_LDAPV3   (RFC 4514)
+ *     LDAP_DN_FORMAT_LDAPV2   (RFC 1779)
  *     LDAP_DN_FORMAT_DCE              (?)
  *
  * fout can be any of the above except
  *     LDAP_DN_FORMAT_LDAP
  * plus:
- *     LDAP_DN_FORMAT_UFN              (rfc 1781, partial and with extensions)
+ *     LDAP_DN_FORMAT_UFN              (RFC 1781, partial and with extensions)
  *     LDAP_DN_FORMAT_AD_CANONICAL     (?)
  */
 int
@@ -391,13 +355,9 @@ ldap_dn_normalize( LDAP_CONST char *dnin,
        int     rc;
        LDAPDN  tmpDN = NULL;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY, "ldap_dn_normalize\n", 0, 0, 0 );
-#else
        Debug( LDAP_DEBUG_TRACE, "ldap_dn_normalize\n", 0, 0, 0 );
-#endif
 
-       assert( dnout );
+       assert( dnout != NULL );
 
        *dnout = NULL;
 
@@ -471,13 +431,25 @@ ldap_dn_normalize( LDAP_CONST char *dnin,
 #define LDAP_DN_ESCAPE(c)              ( (c) == '\\' )
 #define LDAP_DN_VALUE_END(c) \
        ( LDAP_DN_RDN_SEP(c) || LDAP_DN_AVA_SEP(c) )
+
+/* NOTE: according to RFC 4514, '=' can be escaped and treated as special,
+ * i.e. escaped both as "\<hexpair>" and * as "\=", but it is treated as
+ * a regular char, i.e. it can also appear as '='.
+ *
+ * As such, in 2.2 we used to allow reading unescaped '=', but we always
+ * produced escaped '\3D'; this changes since 2.3, if compatibility issues
+ * do not arise
+ */
 #define LDAP_DN_NE(c) \
        ( LDAP_DN_RDN_SEP_V2(c) || LDAP_DN_AVA_SEP(c) \
-         || LDAP_DN_AVA_EQUALS(c) || LDAP_DN_QUOTES(c) \
+         || LDAP_DN_QUOTES(c) \
          || (c) == '<' || (c) == '>' )
 #define LDAP_DN_MAYESCAPE(c) \
        ( LDAP_DN_ESCAPE(c) || LDAP_DN_NE(c) \
+         || LDAP_DN_AVA_EQUALS(c) \
          || LDAP_DN_ASCII_SPACE(c) || LDAP_DN_OCTOTHORPE(c) )
+#define LDAP_DN_SHOULDESCAPE(c)                ( LDAP_DN_AVA_EQUALS(c) )
+
 #define LDAP_DN_NEEDESCAPE(c) \
        ( LDAP_DN_ESCAPE(c) || LDAP_DN_NE(c) )
 #define LDAP_DN_NEEDESCAPE_LEAD(c)     LDAP_DN_MAYESCAPE(c)
@@ -584,14 +556,14 @@ ldap_dn_normalize( LDAP_CONST char *dnin,
  * LDAPAVA helpers (will become part of the API for operations 
  * on structural representations of DNs).
  */
-LDAPAVA *
+static LDAPAVA *
 ldapava_new( const struct berval *attr, const struct berval *val, 
                unsigned flags, void *ctx )
 {
        LDAPAVA *ava;
 
-       assert( attr );
-       assert( val );
+       assert( attr != NULL );
+       assert( val != NULL );
 
        ava = LDAP_MALLOCX( sizeof( LDAPAVA ) + attr->bv_len + 1, ctx );
 
@@ -613,7 +585,7 @@ ldapava_new( const struct berval *attr, const struct berval *val,
 void
 ldapava_free( LDAPAVA *ava, void *ctx )
 {
-       assert( ava );
+       assert( ava != NULL );
 
 #if 0
        /* ava's private must be freed by caller
@@ -700,7 +672,7 @@ ldap_str2dn( LDAP_CONST char *str, LDAPDN *dn, unsigned flags )
 {
        struct berval   bv;
 
-       assert( str );
+       assert( str != NULL );
 
        bv.bv_len = strlen( str );
        bv.bv_val = (char *) str;
@@ -727,19 +699,15 @@ ldap_bv2dn_x( struct berval *bvin, LDAPDN *dn, unsigned flags, void *ctx )
        char            *str, *end;
        struct berval   bvtmp, *bv = &bvtmp;
        
-       assert( bvin );
-       assert( bvin->bv_val );
-       assert( dn );
+       assert( bvin != NULL );
+       assert( bvin->bv_val != NULL );
+       assert( dn != NULL );
 
        *bv = *bvin;
        str = bv->bv_val;
        end = str + bv->bv_len;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ARGS, "ldap_bv2dn(%s,%u)\n%s", str, flags, "" );
-#else
-       Debug( LDAP_DEBUG_TRACE, "=> ldap_bv2dn(%s,%u)\n%s", str, flags, "" );
-#endif
+       Debug( LDAP_DEBUG_ARGS, "=> ldap_bv2dn(%s,%u)\n", str, flags, 0 );
 
        *dn = NULL;
 
@@ -921,12 +889,8 @@ return_result:;
                LDAP_FREEX( tmpDN, ctx );
        }
 
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, RESULTS, "<= ldap_bv2dn(%s,%u)=%d\n", 
-               str, flags, rc );
-#else
-       Debug( LDAP_DEBUG_TRACE, "<= ldap_bv2dn(%s,%u)=%d\n", str, flags, rc );
-#endif
+       Debug( LDAP_DEBUG_ARGS, "<= ldap_bv2dn(%s)=%d %s\n", str, rc,
+                       rc ? ldap_err2string( rc ) : "" );
        *dn = newDN;
        
        return( rc );
@@ -946,7 +910,7 @@ ldap_str2rdn( LDAP_CONST char *str, LDAPRDN *rdn,
 {
        struct berval   bv;
 
-       assert( str );
+       assert( str != NULL );
        assert( str[ 0 ] != '\0' );     /* FIXME: is this required? */
 
        bv.bv_len = strlen( str );
@@ -984,11 +948,11 @@ ldap_bv2rdn_x( struct berval *bv, LDAPRDN *rdn,
        char            *str;
        ber_len_t       stoplen;
        
-       assert( bv );
-       assert( bv->bv_len );
-       assert( bv->bv_val );
+       assert( bv != NULL );
+       assert( bv->bv_len != 0 );
+       assert( bv->bv_val != NULL );
        assert( rdn || flags & LDAP_DN_SKIP );
-       assert( n );
+       assert( n != NULL );
 
        str = bv->bv_val;
        stoplen = bv->bv_len;
@@ -1038,15 +1002,8 @@ ldap_bv2rdn_x( struct berval *bv, LDAPRDN *rdn,
                 * an AttributeType can be encoded as:
                 * - its string representation; in detail, implementations
                 *   MUST recognize AttributeType string type names listed 
-                *   in section 2.3 of draft-ietf-ldapbis-dn-XX.txt, and
-                *   MAY recognize other names.
-                * - its numeric OID (a dotted decimal string); in detail
-                *   RFC 2253 asserts that ``Implementations MUST allow 
-                *   an oid in the attribute type to be prefixed by one 
-                *   of the character strings "oid." or "OID."''.  As soon
-                *   as draft-ietf-ldapbis-dn-XX.txt obsoletes RFC 2253 
-                *   I'm not sure whether this is required or not any 
-                *   longer; to be liberal, we still implement it.
+                *   in Section 3 of RFC 4514, and MAY recognize other names.
+                * - its numeric OID (a dotted decimal string)
                 */
                case B4AVA:
                        if ( LDAP_DN_ASCII_SPACE( p[ 0 ] ) ) {
@@ -1146,9 +1103,8 @@ ldap_bv2rdn_x( struct berval *bv, LDAPRDN *rdn,
                                if ( LDAP_DN_LANG_SEP( p[ 0 ] ) ) {
                                        
                                        /*
-                                        * RFC 2253 does not explicitly
-                                        * allow lang extensions to attribute 
-                                        * types in DNs ... 
+                                        * RFC 4514 explicitly does not allow attribute
+                                        * description options, such as language tags.
                                         */
                                        if ( flags & LDAP_DN_PEDANTIC ) {
                                                goto parsing_error;
@@ -1268,7 +1224,7 @@ ldap_bv2rdn_x( struct berval *bv, LDAPRDN *rdn,
                        }
 
                        /*
-                        * here STRING means RFC 2253 string
+                        * here STRING means RFC 4514 string
                         * FIXME: what about DCE strings? 
                         */
                        if ( !p[ 0 ] ) {
@@ -1470,9 +1426,9 @@ str2strval( const char *str, ber_len_t stoplen, struct berval *val, const char *
        const char      *p, *end, *startPos, *endPos = NULL;
        ber_len_t       len, escapes;
 
-       assert( str );
-       assert( val );
-       assert( next );
+       assert( str != NULL );
+       assert( val != NULL );
+       assert( next != NULL );
 
        *next = NULL;
        end = str + stoplen;
@@ -1516,7 +1472,7 @@ str2strval( const char *str, ber_len_t stoplen, struct berval *val, const char *
                         */
                        return( 1 );
 
-               } else if (!LDAP_DN_ASCII_PRINTABLE( p[ 0 ] ) ) {
+               } else if ( !LDAP_DN_ASCII_PRINTABLE( p[ 0 ] ) ) {
                        if ( p[ 0 ] == '\0' ) {
                                return( 1 );
                        }
@@ -1616,9 +1572,9 @@ DCE2strval( const char *str, struct berval *val, const char **next, unsigned fla
        const char      *p, *startPos, *endPos = NULL;
        ber_len_t       len, escapes;
 
-       assert( str );
-       assert( val );
-       assert( next );
+       assert( str != NULL );
+       assert( val != NULL );
+       assert( next != NULL );
 
        *next = NULL;
        
@@ -1701,9 +1657,9 @@ IA52strval( const char *str, struct berval *val, const char **next, unsigned fla
        const char      *p, *startPos, *endPos = NULL;
        ber_len_t       len, escapes;
 
-       assert( str );
-       assert( val );
-       assert( next );
+       assert( str != NULL );
+       assert( val != NULL );
+       assert( next != NULL );
 
        *next = NULL;
 
@@ -1777,9 +1733,9 @@ quotedIA52strval( const char *str, struct berval *val, const char **next, unsign
        ber_len_t       len;
        unsigned        escapes = 0;
 
-       assert( str );
-       assert( val );
-       assert( next );
+       assert( str != NULL );
+       assert( val != NULL );
+       assert( next != NULL );
 
        *next = NULL;
 
@@ -1867,8 +1823,8 @@ hexstr2bin( const char *str, char *c )
 {
        char    c1, c2;
 
-       assert( str );
-       assert( c );
+       assert( str != NULL );
+       assert( c != NULL );
 
        c1 = str[ 0 ];
        c2 = str[ 1 ];
@@ -1909,9 +1865,9 @@ hexstr2binval( const char *str, struct berval *val, const char **next, unsigned
        ber_len_t       len;
        ber_len_t       s, d;
 
-       assert( str );
-       assert( val );
-       assert( next );
+       assert( str != NULL );
+       assert( val != NULL );
+       assert( next != NULL );
 
        *next = NULL;
 
@@ -2011,8 +1967,8 @@ byte2hexpair( const char *val, char *pair )
 {
        static const char       hexdig[] = "0123456789ABCDEF";
 
-       assert( val );
-       assert( pair );
+       assert( val != NULL );
+       assert( pair != NULL );
 
        /* 
         * we assume the string has enough room for the hex encoding
@@ -2033,8 +1989,8 @@ binval2hexstr( struct berval *val, char *str )
 {
        ber_len_t       s, d;
 
-       assert( val );
-       assert( str );
+       assert( val != NULL );
+       assert( str != NULL );
 
        if ( val->bv_len == 0 ) {
                return( 0 );
@@ -2060,21 +2016,22 @@ static int
 strval2strlen( struct berval *val, unsigned flags, ber_len_t *len )
 {
        ber_len_t       l, cl = 1;
-       char            *p;
+       char            *p, *end;
        int             escaped_byte_len = LDAP_DN_IS_PRETTY( flags ) ? 1 : 3;
 #ifdef PRETTY_ESCAPE
        int             escaped_ascii_len = LDAP_DN_IS_PRETTY( flags ) ? 2 : 3;
 #endif /* PRETTY_ESCAPE */
        
-       assert( val );
-       assert( len );
+       assert( val != NULL );
+       assert( len != NULL );
 
        *len = 0;
        if ( val->bv_len == 0 ) {
                return( 0 );
        }
 
-       for ( l = 0, p = val->bv_val; p < val->bv_val + val->bv_len; p += cl ) {
+       end = val->bv_val + val->bv_len - 1;
+       for ( l = 0, p = val->bv_val; p <= end; p += cl ) {
 
                /* 
                 * escape '%x00' 
@@ -2101,8 +2058,9 @@ strval2strlen( struct berval *val, unsigned flags, ber_len_t *len )
                        l += escaped_byte_len * cl;
 
                } else if ( LDAP_DN_NEEDESCAPE( p[ 0 ] )
+                               || LDAP_DN_SHOULDESCAPE( p[ 0 ] )
                                || ( p == val->bv_val && LDAP_DN_NEEDESCAPE_LEAD( p[ 0 ] ) )
-                               || ( !p[ 1 ] && LDAP_DN_NEEDESCAPE_TRAIL( p[ 0 ] ) ) ) {
+                               || ( p == end && LDAP_DN_NEEDESCAPE_TRAIL( p[ 0 ] ) ) ) {
 #ifdef PRETTY_ESCAPE
 #if 0
                        if ( LDAP_DN_WILLESCAPE_HEX( flags, p[ 0 ] ) ) {
@@ -2143,9 +2101,9 @@ strval2str( struct berval *val, char *str, unsigned flags, ber_len_t *len )
 {
        ber_len_t       s, d, end;
 
-       assert( val );
-       assert( str );
-       assert( len );
+       assert( val != NULL );
+       assert( str != NULL );
+       assert( len != NULL );
 
        if ( val->bv_len == 0 ) {
                *len = 0;
@@ -2191,6 +2149,7 @@ strval2str( struct berval *val, char *str, unsigned flags, ber_len_t *len )
 #endif
 #else /* ! PRETTY_ESCAPE */
                                || LDAP_DN_NEEDESCAPE( val->bv_val[ s ] )
+                               || LDAP_DN_SHOULDESCAPE( val->bv_val[ s ] )
                                || ( d == 0 && LDAP_DN_NEEDESCAPE_LEAD( val->bv_val[ s ] ) )
                                || ( s == end && LDAP_DN_NEEDESCAPE_TRAIL( val->bv_val[ s ] ) )
 
@@ -2211,6 +2170,7 @@ strval2str( struct berval *val, char *str, unsigned flags, ber_len_t *len )
                } else {
 #ifdef PRETTY_ESCAPE
                        if ( LDAP_DN_NEEDESCAPE( val->bv_val[ s ] )
+                                       || LDAP_DN_SHOULDESCAPE( val->bv_val[ s ] )
                                        || ( d == 0 && LDAP_DN_NEEDESCAPE_LEAD( val->bv_val[ s ] ) )
                                        || ( s == end && LDAP_DN_NEEDESCAPE_TRAIL( val->bv_val[ s ] ) ) ) {
                                str[ d++ ] = '\\';
@@ -2240,8 +2200,8 @@ strval2IA5strlen( struct berval *val, unsigned flags, ber_len_t *len )
        ber_len_t       l;
        char            *p;
 
-       assert( val );
-       assert( len );
+       assert( val != NULL );
+       assert( len != NULL );
 
        *len = 0;
        if ( val->bv_len == 0 ) {
@@ -2257,6 +2217,7 @@ strval2IA5strlen( struct berval *val, unsigned flags, ber_len_t *len )
        } else {
                for ( l = 0, p = val->bv_val; p[ 0 ]; p++ ) {
                        if ( LDAP_DN_NEEDESCAPE( p[ 0 ] )
+                                       || LDAP_DN_SHOULDESCAPE( p[ 0 ] )
                                        || ( p == val->bv_val && LDAP_DN_NEEDESCAPE_LEAD( p[ 0 ] ) )
                                        || ( !p[ 1 ] && LDAP_DN_NEEDESCAPE_TRAIL( p[ 0 ] ) ) ) {
                                l += 2;
@@ -2281,9 +2242,9 @@ strval2IA5str( struct berval *val, char *str, unsigned flags, ber_len_t *len )
 {
        ber_len_t       s, d, end;
 
-       assert( val );
-       assert( str );
-       assert( len );
+       assert( val != NULL );
+       assert( str != NULL );
+       assert( len != NULL );
 
        if ( val->bv_len == 0 ) {
                *len = 0;
@@ -2305,6 +2266,7 @@ strval2IA5str( struct berval *val, char *str, unsigned flags, ber_len_t *len )
 
                for ( s = 0, d = 0, end = val->bv_len - 1; s < val->bv_len; ) {
                        if ( LDAP_DN_NEEDESCAPE( val->bv_val[ s ] )
+                                       || LDAP_DN_SHOULDESCAPE( val->bv_val[ s ] )
                                        || ( s == 0 && LDAP_DN_NEEDESCAPE_LEAD( val->bv_val[ s ] ) )
                                        || ( s == end && LDAP_DN_NEEDESCAPE_TRAIL( val->bv_val[ s ] ) ) ) {
                                str[ d++ ] = '\\';
@@ -2328,8 +2290,8 @@ strval2DCEstrlen( struct berval *val, unsigned flags, ber_len_t *len )
        ber_len_t       l;
        char            *p;
 
-       assert( val );
-       assert( len );
+       assert( val != NULL );
+       assert( len != NULL );
 
        *len = 0;
        if ( val->bv_len == 0 ) {
@@ -2368,9 +2330,9 @@ strval2DCEstr( struct berval *val, char *str, unsigned flags, ber_len_t *len )
 {
        ber_len_t       s, d;
 
-       assert( val );
-       assert( str );
-       assert( len );
+       assert( val != NULL );
+       assert( str != NULL );
+       assert( len != NULL );
 
        if ( val->bv_len == 0 ) {
                *len = 0;
@@ -2406,81 +2368,71 @@ strval2DCEstr( struct berval *val, char *str, unsigned flags, ber_len_t *len )
 
 /*
  * Length of the (supposedly) AD canonical string representation, 
- * accounting for escaped hex of UTF-8 chars
+ * accounting for chars that need to be escaped 
  */
 static int
 strval2ADstrlen( struct berval *val, unsigned flags, ber_len_t *len )
 {
-       ber_len_t       l;
+       ber_len_t       l, cl;
        char            *p;
 
-       assert( val );
-       assert( len );
+       assert( val != NULL );
+       assert( len != NULL );
 
        *len = 0;
        if ( val->bv_len == 0 ) {
                return( 0 );
        }
 
-       if ( flags & LDAP_AVA_NONPRINTABLE ) {
-               /* 
-                * FIXME: Turn the value into a binary encoded BER?
-                */
-               return( -1 );
-               
-       } else {
-               for ( l = 0, p = val->bv_val; p[ 0 ]; p++ ) {
-                       if ( LDAP_DN_NEEDESCAPE_AD( p[ 0 ] ) ) {
-                               l += 2;
-
-                       } else {
-                               l++;
-                       }
+       for ( l = 0, p = val->bv_val; p[ 0 ]; p += cl ) {
+               cl = LDAP_UTF8_CHARLEN2( p, cl );
+               if ( cl == 0 ) {
+                       /* illegal utf-8 char */
+                       return -1;
+               } else if ( (cl == 1) && LDAP_DN_NEEDESCAPE_AD( p[ 0 ] ) ) {
+                       l += 2;
+               } else {
+                       l += cl;
                }
        }
 
        *len = l;
-       
+
        return( 0 );
 }
 
 /*
- * convert to (supposedly) AD string representation, 
- * escaping with hex the UTF-8 stuff;
+ * convert to (supposedly) AD string representation,
  * assume the destination has enough room for escaping
  */
 static int
 strval2ADstr( struct berval *val, char *str, unsigned flags, ber_len_t *len )
 {
-       ber_len_t       s, d;
+       ber_len_t       s, d, cl;
 
-       assert( val );
-       assert( str );
-       assert( len );
+       assert( val != NULL );
+       assert( str != NULL );
+       assert( len != NULL );
 
        if ( val->bv_len == 0 ) {
                *len = 0;
                return( 0 );
        }
 
-       if ( flags & LDAP_AVA_NONPRINTABLE ) {
-               /*
-                * FIXME: Turn the value into a binary encoded BER?
-                */
-               *len = 0;
-               return( -1 );
-               
-       } else {
-
-               /* 
-                * we assume the string has enough room for the hex encoding
-                * of the value
-                */
+       /* 
+        * we assume the string has enough room for the escaping
+        * of the value
+        */
 
-               for ( s = 0, d = 0; s < val->bv_len; ) {
-                       if ( LDAP_DN_NEEDESCAPE_AD( val->bv_val[ s ] ) ) {
-                               str[ d++ ] = '\\';
-                       }
+       for ( s = 0, d = 0; s < val->bv_len; ) {
+               cl = LDAP_UTF8_CHARLEN2( val->bv_val+s, cl );
+               if ( cl == 0 ) {
+                       /* illegal utf-8 char */
+                       return -1;
+               } else if ( (cl == 1) && LDAP_DN_NEEDESCAPE_AD(val->bv_val[ s ]) ) {
+                       str[ d++ ] = '\\';
+               }
+               for (; cl--;) {
                        str[ d++ ] = val->bv_val[ s++ ];
                }
        }
@@ -2507,9 +2459,9 @@ dn2domain( LDAPDN dn, struct berval *bv, int pos, int *iRDN )
        /* we are guaranteed there's enough memory in str */
 
        /* sanity */
-       assert( dn );
-       assert( bv );
-       assert( iRDN );
+       assert( dn != NULL );
+       assert( bv != NULL );
+       assert( iRDN != NULL );
        assert( *iRDN >= 0 );
 
        str = bv->bv_val + pos;
@@ -2518,10 +2470,10 @@ dn2domain( LDAPDN dn, struct berval *bv, int pos, int *iRDN )
                LDAPRDN         rdn;
                LDAPAVA         *ava;
 
-               assert( dn[ i ] );
+               assert( dn[ i ] != NULL );
                rdn = dn[ i ];
 
-               assert( rdn[ 0 ] );
+               assert( rdn[ 0 ] != NULL );
                ava = rdn[ 0 ];
 
                if ( !LDAP_DN_IS_RDN_DC( rdn ) ) {
@@ -2708,8 +2660,8 @@ rdn2UFNstrlen( LDAPRDN rdn, unsigned flags, ber_len_t *len )
        int             iAVA;
        ber_len_t       l = 0;
 
-       assert( rdn );
-       assert( len );
+       assert( rdn != NULL );
+       assert( len != NULL );
 
        *len = 0;
 
@@ -2787,8 +2739,8 @@ rdn2ADstrlen( LDAPRDN rdn, unsigned flags, ber_len_t *len )
        int             iAVA;
        ber_len_t       l = 0;
 
-       assert( rdn );
-       assert( len );
+       assert( rdn != NULL );
+       assert( len != NULL );
 
        *len = 0;
 
@@ -2868,7 +2820,7 @@ ldap_rdn2str( LDAPRDN rdn, char **str, unsigned flags )
        struct berval bv;
        int rc;
 
-       assert( str );
+       assert( str != NULL );
 
        if((flags & LDAP_DN_FORMAT_MASK) == LDAP_DN_FORMAT_LBER) {
                return LDAP_PARAM_ERROR;
@@ -2891,7 +2843,7 @@ ldap_rdn2bv_x( LDAPRDN rdn, struct berval *bv, unsigned flags, void *ctx )
        int             rc, back;
        ber_len_t       l;
        
-       assert( bv );
+       assert( bv != NULL );
 
        bv->bv_len = 0;
        bv->bv_val = NULL;
@@ -3001,7 +2953,7 @@ int ldap_dn2str( LDAPDN dn, char **str, unsigned flags )
        struct berval bv;
        int rc;
 
-       assert( str );
+       assert( str != NULL );
 
        if((flags & LDAP_DN_FORMAT_MASK) == LDAP_DN_FORMAT_LBER) {
                return LDAP_PARAM_ERROR;
@@ -3027,16 +2979,11 @@ int ldap_dn2bv_x( LDAPDN dn, struct berval *bv, unsigned flags, void *ctx )
        int ( *sv2l ) ( struct berval *v, unsigned f, ber_len_t *l );
        int ( *sv2s ) ( struct berval *v, char *s, unsigned f, ber_len_t *l );
 
-       assert( bv );
+       assert( bv != NULL );
        bv->bv_len = 0;
        bv->bv_val = NULL;
 
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ARGS, "=> ldap_dn2bv(%u)\n%s%s", 
-               flags, "", "" );
-#else
-       Debug( LDAP_DEBUG_TRACE, "=> ldap_dn2bv(%u)\n%s%s", flags, "", "" );
-#endif
+       Debug( LDAP_DEBUG_ARGS, "=> ldap_dn2bv(%u)\n", flags, 0, 0 );
 
        /* 
         * a null dn means an empty dn string 
@@ -3345,214 +3292,10 @@ int ldap_dn2bv_x( LDAPDN dn, struct berval *bv, unsigned flags, void *ctx )
                return LDAP_PARAM_ERROR;
        }
 
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, RESULTS, "<= ldap_dn2bv(%s,%u)=%d\n", 
-               bv->bv_val, flags, rc );
-#else
-       Debug( LDAP_DEBUG_TRACE, "<= ldap_dn2bv(%s,%u)=%d\n",
-               bv->bv_val, flags, rc );
-#endif
+       Debug( LDAP_DEBUG_ARGS, "<= ldap_dn2bv(%s)=%d %s\n",
+               bv->bv_val, rc, rc ? ldap_err2string( rc ) : "" );
 
 return_results:;
        return( rc );
 }
 
-#ifdef HAVE_TLS
-#include <openssl/x509.h>
-#include <openssl/err.h>
-
-/* Convert a structured DN from an X.509 certificate into an LDAPV3 DN.
- * x509_name must be an (X509_NAME *). If func is non-NULL, the
- * constructed DN will use numeric OIDs to identify attributeTypes,
- * and the func() will be invoked to rewrite the DN with the given
- * flags.
- *
- * Otherwise the DN will use shortNames as defined in the OpenSSL
- * library.
- *
- * It's preferable to let slapd do the OID to attributeType mapping,
- * because the OpenSSL tables are known to have many typos in versions
- * up to (at least) 0.9.6c. However, the LDAP client has no schema tables,
- * so we're forced to use OpenSSL's mapping there.
- *  -- Howard Chu 2002-04-18
- */
-
-int
-ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func,
-       unsigned flags )
-{
-       LDAPDN  newDN;
-       LDAPRDN newRDN;
-       LDAPAVA *newAVA, *baseAVA;
-       X509_NAME_ENTRY *ne;
-       ASN1_OBJECT *obj;
-       ASN1_STRING *str;
-       char oids[8192], *oidptr = oids, *oidbuf = NULL;
-       void *ptrs[2048];
-       int i, j, k = 0, navas, nrdns, rc = LDAP_SUCCESS;
-       int set = -1;
-       size_t dnsize, oidrem = sizeof(oids), oidsize = 0;
-       int csize;
-
-       struct berval   Val;
-
-       assert( bv );
-       bv->bv_len = 0;
-       bv->bv_val = NULL;
-
-       /* Get the number of AVAs. This is not necessarily the same as
-        * the number of RDNs.
-        */
-       navas = X509_NAME_entry_count( x509_name );
-
-       /* Get the last element, to see how many RDNs there are */
-       ne = X509_NAME_get_entry( x509_name, navas - 1 );
-       nrdns = ne->set + 1;
-
-       /* Allocate the DN/RDN/AVA stuff as a single block */    
-       dnsize = sizeof(LDAPRDN) * (nrdns+1);
-       dnsize += sizeof(LDAPAVA *) * (navas+nrdns);
-       dnsize += sizeof(LDAPAVA) * navas;
-       if (dnsize > sizeof(ptrs)) {
-               newDN = (LDAPDN)LDAP_MALLOC( dnsize );
-               if ( newDN == NULL )
-                       return LDAP_NO_MEMORY;
-       } else {
-               newDN = (LDAPDN)ptrs;
-       }
-       
-       newDN[nrdns] = NULL;
-       newRDN = (LDAPRDN)(newDN + nrdns+1);
-       newAVA = (LDAPAVA *)(newRDN + navas + nrdns);
-       baseAVA = newAVA;
-
-       /* Retrieve RDNs in reverse order; LDAP is backwards from X.500. */
-       for ( i = nrdns - 1, j = 0; i >= 0; i-- ) {
-               ne = X509_NAME_get_entry( x509_name, i );
-               obj = X509_NAME_ENTRY_get_object( ne );
-               str = X509_NAME_ENTRY_get_data( ne );
-
-               /* If set changed, move to next RDN */
-               if ( set != ne->set ) {
-                       /* If this is not the first time, end the
-                        * previous RDN and advance.
-                        */
-                       if ( j > 0 ) {
-                               newRDN[k] = NULL;
-                               newRDN += k+1;
-                       }
-                       newDN[j++] = newRDN;
-
-                       k = 0;
-                       set = ne->set;
-               }
-               newAVA->la_private = NULL;
-               newAVA->la_flags = LDAP_AVA_STRING;
-
-               if ( !func ) {
-                       int n = OBJ_obj2nid( obj );
-
-                       if (n == NID_undef)
-                               goto get_oid;
-                       newAVA->la_attr.bv_val = (char *)OBJ_nid2sn( n );
-                       newAVA->la_attr.bv_len = strlen( newAVA->la_attr.bv_val );
-#ifdef HAVE_EBCDIC
-                       newAVA->la_attr.bv_val = LDAP_STRDUP( newAVA->la_attr.bv_val );
-                       __etoa( newAVA->la_attr.bv_val );
-                       newAVA->la_flags |= LDAP_AVA_FREE_ATTR;
-#endif
-               } else {
-get_oid:               newAVA->la_attr.bv_val = oidptr;
-                       newAVA->la_attr.bv_len = OBJ_obj2txt( oidptr, oidrem, obj, 1 );
-#ifdef HAVE_EBCDIC
-                       __etoa( newAVA->la_attr.bv_val );
-#endif
-                       oidptr += newAVA->la_attr.bv_len + 1;
-                       oidrem -= newAVA->la_attr.bv_len + 1;
-
-                       /* Running out of OID buffer space? */
-                       if (oidrem < 128) {
-                               if ( oidsize == 0 ) {
-                                       oidsize = sizeof(oids) * 2;
-                                       oidrem = oidsize;
-                                       oidbuf = LDAP_MALLOC( oidsize );
-                                       if ( oidbuf == NULL ) goto nomem;
-                                       oidptr = oidbuf;
-                               } else {
-                                       char *old = oidbuf;
-                                       oidbuf = LDAP_REALLOC( oidbuf, oidsize*2 );
-                                       if ( oidbuf == NULL ) goto nomem;
-                                       /* Buffer moved! Fix AVA pointers */
-                                       if ( old != oidbuf ) {
-                                               LDAPAVA *a;
-                                               long dif = oidbuf - old;
-
-                                               for (a=baseAVA; a<=newAVA; a++){
-                                                       if (a->la_attr.bv_val >= old &&
-                                                               a->la_attr.bv_val <= (old + oidsize))
-                                                               a->la_attr.bv_val += dif;
-                                               }
-                                       }
-                                       oidptr = oidbuf + oidsize - oidrem;
-                                       oidrem += oidsize;
-                                       oidsize *= 2;
-                               }
-                       }
-               }
-               Val.bv_val = (char *) str->data;
-               Val.bv_len = str->length;
-               switch( str->type ) {
-               case V_ASN1_UNIVERSALSTRING:
-                       /* This uses 32-bit ISO 10646-1 */
-                       csize = 4; goto to_utf8;
-               case V_ASN1_BMPSTRING:
-                       /* This uses 16-bit ISO 10646-1 */
-                       csize = 2; goto to_utf8;
-               case V_ASN1_T61STRING:
-                       /* This uses 8-bit, assume ISO 8859-1 */
-                       csize = 1;
-to_utf8:               rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value );
-                       newAVA->la_flags |= LDAP_AVA_FREE_VALUE;
-                       if (rc != LDAP_SUCCESS) goto nomem;
-                       newAVA->la_flags = LDAP_AVA_NONPRINTABLE;
-                       break;
-               case V_ASN1_UTF8STRING:
-                       newAVA->la_flags = LDAP_AVA_NONPRINTABLE;
-                       /* This is already in UTF-8 encoding */
-               case V_ASN1_IA5STRING:
-               case V_ASN1_PRINTABLESTRING:
-                       /* These are always 7-bit strings */
-                       newAVA->la_value = Val;
-               default:
-                       ;
-               }
-               newRDN[k] = newAVA;
-               newAVA++;
-               k++;
-       }
-       newRDN[k] = NULL;
-
-       if ( func ) {
-               rc = func( newDN, flags, NULL );
-               if ( rc != LDAP_SUCCESS )
-                       goto nomem;
-       }
-
-       rc = ldap_dn2bv_x( newDN, bv, LDAP_DN_FORMAT_LDAPV3, NULL );
-
-nomem:
-       for (;baseAVA < newAVA; baseAVA++) {
-               if (baseAVA->la_flags & LDAP_AVA_FREE_ATTR)
-                       LDAP_FREE( baseAVA->la_attr.bv_val );
-               if (baseAVA->la_flags & LDAP_AVA_FREE_VALUE)
-                       LDAP_FREE( baseAVA->la_value.bv_val );
-       }
-
-       if ( oidsize != 0 )
-               LDAP_FREE( oidbuf );
-       if ( newDN != (LDAPDN) ptrs )
-               LDAP_FREE( newDN );
-       return rc;
-}
-#endif /* HAVE_TLS */
-