diff --git a/include/ldap.h b/include/ldap.h index 5872bf3b3c..1a801a3a32 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -1188,6 +1188,7 @@ typedef LDAPRDN** LDAPDN; /* DN flags */ #define LDAP_DN_PRETTY 0x0100U +#define LDAP_DN_SKIP 0x0200U #define LDAP_DN_P_NOLEADTRAILSPACES 0x1000U #define LDAP_DN_P_NOSPACEAFTERRDN 0x2000U #define LDAP_DN_PEDANTIC 0xF000U diff --git a/libraries/libldap/getdn.c b/libraries/libldap/getdn.c index 7a143bd589..75ea756b2b 100644 --- a/libraries/libldap/getdn.c +++ b/libraries/libldap/getdn.c @@ -873,12 +873,14 @@ ldap_str2rdn( const char *str, LDAPRDN **rdn, const char **n, unsigned flags ) LDAPRDN *newRDN = NULL; assert( str ); - assert( rdn ); + assert( rdn || flags & LDAP_DN_SKIP ); assert( n ); Debug( LDAP_DEBUG_TRACE, "=> ldap_str2rdn(%s,%u)\n%s", str, flags, "" ); - *rdn = NULL; + if ( rdn ) { + *rdn = NULL; + } *n = NULL; switch ( LDAP_DN_FORMAT( flags ) ) { @@ -995,13 +997,22 @@ ldap_str2rdn( const char *str, LDAPRDN **rdn, const char **n, unsigned flags ) if ( type == NULL ) { goto parsing_error; } - attrType = LDAP_MALLOC( sizeof( struct berval ) ); - if ( attrType== NULL ) { - rc = LDAP_NO_MEMORY; - goto parsing_error; + + if ( flags & LDAP_DN_SKIP ) { + /* + * FIXME: hack for skipping a rdn; + * need a cleaner solution + */ + LDAP_FREE( type ); + + } else { + attrType = ber_bvstr( type ); + if ( attrType == NULL ) { + rc = LDAP_NO_MEMORY; + goto parsing_error; + } } - attrType->bv_val = type; - attrType->bv_len = strlen( type ); + attrTypeEncoding = LDAP_AVA_BINARY; state = B4AVAEQUALS; @@ -1053,6 +1064,20 @@ ldap_str2rdn( const char *str, LDAPRDN **rdn, const char **n, unsigned flags ) goto parsing_error; } + attrTypeEncoding = LDAP_AVA_STRING; + + /* + * here we need to decide whether to use it as is + * or turn it in OID form; as a consequence, we + * need to decide whether to binary encode the value + */ + + state = B4AVAEQUALS; + + if ( flags & LDAP_DN_SKIP ) { + break; + } + assert( attrType == NULL ); attrType = LDAP_MALLOC( sizeof( struct berval ) ); if ( attrType == NULL ) { @@ -1065,15 +1090,7 @@ ldap_str2rdn( const char *str, LDAPRDN **rdn, const char **n, unsigned flags ) goto parsing_error; } attrType->bv_len = len; - attrTypeEncoding = LDAP_AVA_STRING; - /* - * here we need to decide whether to use it as is - * or turn it in OID form; as a consequence, we - * need to decide whether to binary encode the value - */ - - state = B4AVAEQUALS; break; } @@ -1209,26 +1226,29 @@ ldap_str2rdn( const char *str, LDAPRDN **rdn, const char **n, unsigned flags ) break; case GOTAVA: { - LDAPAVA *ava; - LDAPRDN *rdn; int rdnsep = 0; - /* - * we accept empty values - */ - ava = ldapava_new( attrType, attrValue, - attrValueEncoding ); - if ( ava == NULL ) { - rc = LDAP_NO_MEMORY; - goto parsing_error; - } + if ( !( flags & LDAP_DN_SKIP ) ) { + LDAPAVA *ava; + LDAPRDN *rdn; - rdn = ldapava_append_to_rdn( newRDN, ava ); - if ( rdn == NULL ) { - rc = LDAP_NO_MEMORY; - goto parsing_error; + /* + * we accept empty values + */ + ava = ldapava_new( attrType, attrValue, + attrValueEncoding ); + if ( ava == NULL ) { + rc = LDAP_NO_MEMORY; + goto parsing_error; + } + + rdn = ldapava_append_to_rdn( newRDN, ava ); + if ( rdn == NULL ) { + rc = LDAP_NO_MEMORY; + goto parsing_error; + } + newRDN = rdn; } - newRDN = rdn; /* * if we got an AVA separator ('+', or ',' for DCE ) @@ -1294,7 +1314,9 @@ return_result:; Debug( LDAP_DEBUG_TRACE, "<= ldap_str2rdn(%*s)=%d\n", *n - p, str, rc ); - *rdn = newRDN; + if ( rdn ) { + *rdn = newRDN; + } return( rc ); } @@ -1394,6 +1416,11 @@ str2strval( const char *str, struct berval **val, const char **next, unsigned fl } } + *next = p; + if ( flags & LDAP_DN_SKIP ) { + return( 0 ); + } + /* * FIXME: test memory? */ @@ -1442,9 +1469,6 @@ str2strval( const char *str, struct berval **val, const char **next, unsigned fl assert( strlen( ( *val )->bv_val ) == len ); } - - *next = p; - return( 0 ); } @@ -1501,7 +1525,11 @@ DCE2strval( const char *str, struct berval **val, const char **next, unsigned fl } } - + *next = p; + if ( flags & LDAP_DN_SKIP ) { + return( 0 ); + } + len = ( endPos ? endPos : p ) - startPos - escapes; *val = LDAP_MALLOC( sizeof( struct berval ) ); ( *val )->bv_len = len; @@ -1528,8 +1556,6 @@ DCE2strval( const char *str, struct berval **val, const char **next, unsigned fl assert( strlen( ( *val )->bv_val ) == len ); } - *next = p; - return( 0 ); } @@ -1582,6 +1608,11 @@ IA52strval( const char *str, struct berval **val, const char **next, unsigned fl /* no op */ } + *next = p; + if ( flags & LDAP_DN_SKIP ) { + return( 0 ); + } + *val = LDAP_MALLOC( sizeof( struct berval ) ); len = ( endPos ? endPos : p ) - startPos - escapes; ( *val )->bv_len = len; @@ -1601,7 +1632,6 @@ IA52strval( const char *str, struct berval **val, const char **next, unsigned fl ( *val )->bv_val[ d ] = '\0'; assert( strlen( ( *val )->bv_val ) == len ); } - *next = p; return( 0 ); } @@ -1669,6 +1699,11 @@ quotedIA52strval( const char *str, struct berval **val, const char **next, unsig /* no op */ } + *next = p; + if ( flags & LDAP_DN_SKIP ) { + return( 0 ); + } + len = endPos - startPos - escapes; assert( len >= 0 ); *val = LDAP_MALLOC( sizeof( struct berval ) ); @@ -1692,8 +1727,6 @@ quotedIA52strval( const char *str, struct berval **val, const char **next, unsig assert( strlen( ( *val )->bv_val ) == len ); } - *next = p; - return( 0 ); } @@ -1811,6 +1844,11 @@ hexstr2binval( const char *str, struct berval **val, const char **next, unsigned end_of_value:; + *next = p; + if ( flags & LDAP_DN_SKIP ) { + return( 0 ); + } + len = ( ( endPos ? endPos : p ) - startPos ) / 2; /* must be even! */ assert( 2 * len == (ber_len_t) (( endPos ? endPos : p ) - startPos )); @@ -1836,7 +1874,6 @@ end_of_value:; } ( *val )->bv_val[ d ] = '\0'; - *next = p; return( 0 ); } diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c index e6e4c90a85..eed563e950 100644 --- a/servers/slapd/dn.c +++ b/servers/slapd/dn.c @@ -714,7 +714,8 @@ dn_rdnlen( Backend *be, struct berval *dn_in ) { - struct berval rdn; + int rc; + char *p; assert( dn_in ); @@ -730,13 +731,13 @@ dn_rdnlen( return 0; } - if ( dnExtractRdn( dn_in, &rdn ) != LDAP_SUCCESS ) { + rc = ldap_str2rdn( dn_in->bv_val, NULL, &p, + LDAP_DN_FORMAT_LDAP | LDAP_DN_SKIP ); + if ( rc != LDAP_SUCCESS ) { return 0; } - free( rdn.bv_val ); - - return rdn.bv_len; + return p - dn_in->bv_val; } /*