X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fgetdn.c;h=d43287172576ff1174dffff2afaf20f26ebb5137;hb=3d39ff68a94e4455074707d763138f01aaa1c5b1;hp=d44ddf19f7799b4e3e867a94770eb2a9cd28ca1f;hpb=f195b20a1f3cc6da31d8a4e9f9d807cbf12f414c;p=openldap diff --git a/libraries/libldap/getdn.c b/libraries/libldap/getdn.c index d44ddf19f7..d432871725 100644 --- a/libraries/libldap/getdn.c +++ b/libraries/libldap/getdn.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * 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 "\" 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 -#include - -/* 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 */ -