From e96865c1a813a4dd227edd9d95c900d0128c0dde Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Wed, 1 Mar 2000 22:59:34 +0000 Subject: [PATCH] Reorder error detection based upon precedence --- servers/slapd/ava.c | 30 ++++----- servers/slapd/bind.c | 18 +++--- servers/slapd/compare.c | 18 +++--- servers/slapd/delete.c | 10 +-- servers/slapd/filter.c | 128 ++++++++++++++++++++++++------------- servers/slapd/modify.c | 18 +++--- servers/slapd/modrdn.c | 32 +++++----- servers/slapd/proto-slap.h | 8 ++- servers/slapd/search.c | 7 +- 9 files changed, 156 insertions(+), 113 deletions(-) diff --git a/servers/slapd/ava.c b/servers/slapd/ava.c index d948f35bbf..0200d035f6 100644 --- a/servers/slapd/ava.c +++ b/servers/slapd/ava.c @@ -31,6 +31,19 @@ ava_free( #else +void +ava_free( + Ava *ava, + int freeit +) +{ + ch_free( (char *) ava->ava_type ); + ch_free( (char *) ava->ava_value.bv_val ); + if ( freeit ) { + ch_free( (char *) ava ); + } +} + int get_ava( BerElement *ber, @@ -40,26 +53,13 @@ get_ava( if ( ber_scanf( ber, "{ao}", &ava->ava_type, &ava->ava_value ) == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, " get_ava ber_scanf\n", 0, 0, 0 ); - return -1; + return SLAPD_DISCONNECT; } attr_normalize( ava->ava_type ); value_normalize( ava->ava_value.bv_val, attr_syntax( ava->ava_type ) ); - return( LDAP_SUCCESS ); -} - -void -ava_free( - Ava *ava, - int freeit -) -{ - ch_free( (char *) ava->ava_type ); - ch_free( (char *) ava->ava_value.bv_val ); - if ( freeit ) { - ch_free( (char *) ava ); - } + return LDAP_SUCCESS; } #endif diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c index c825d0b8b1..7f725d6df2 100644 --- a/servers/slapd/bind.c +++ b/servers/slapd/bind.c @@ -112,15 +112,6 @@ do_bind( goto cleanup; } - ndn = ch_strdup( dn ); - - if ( dn_normalize( ndn ) == NULL ) { - Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n", dn, 0, 0 ); - send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL, - "invalid DN", NULL, NULL ); - goto cleanup; - } - op->o_protocol = version; if( method != LDAP_AUTH_SASL ) { @@ -156,6 +147,15 @@ do_bind( goto cleanup; } + ndn = ch_strdup( dn ); + + if ( dn_normalize( ndn ) == NULL ) { + Debug( LDAP_DEBUG_ANY, "bind: invalid dn (%s)\n", dn, 0, 0 ); + send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL, + "invalid DN", NULL, NULL ); + goto cleanup; + } + if( method == LDAP_AUTH_SASL ) { Debug( LDAP_DEBUG_TRACE, "do_sasl_bind: dn (%s) mech %s\n", dn, mech, NULL ); diff --git a/servers/slapd/compare.c b/servers/slapd/compare.c index c95d98952f..259698bc46 100644 --- a/servers/slapd/compare.c +++ b/servers/slapd/compare.c @@ -76,15 +76,6 @@ do_compare( return SLAPD_DISCONNECT; } - ndn = ch_strdup( dn ); - - if( dn_normalize( ndn ) == NULL ) { - Debug( LDAP_DEBUG_ANY, "do_compare: invalid dn (%s)\n", dn, 0, 0 ); - send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL, - "invalid DN", NULL, NULL ); - goto cleanup; - } - if ( ber_scanf( op->o_ber, "{oo}", &desc, &value ) == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, "do_compare: get ava failed\n", 0, 0, 0 ); send_ldap_disconnect( conn, op, @@ -106,6 +97,15 @@ do_compare( goto cleanup; } + ndn = ch_strdup( dn ); + + if( dn_normalize( ndn ) == NULL ) { + Debug( LDAP_DEBUG_ANY, "do_compare: invalid dn (%s)\n", dn, 0, 0 ); + send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL, + "invalid DN", NULL, NULL ); + goto cleanup; + } + #ifdef SLAPD_SCHEMA_NOT_COMPAT rc = slap_bv2ad( &desc, &ava.aa_desc, &text ); if( rc != LDAP_SUCCESS ) { diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c index fad869826f..01d03f82f9 100644 --- a/servers/slapd/delete.c +++ b/servers/slapd/delete.c @@ -58,6 +58,11 @@ do_delete( return SLAPD_DISCONNECT; } + if( ( rc = get_ctrls( conn, op, 1 ) ) != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, "do_add: get_ctrls failed\n", 0, 0, 0 ); + goto cleanup; + } + ndn = ch_strdup( dn ); if( dn_normalize( ndn ) == NULL ) { @@ -67,11 +72,6 @@ do_delete( goto cleanup; } - if( ( rc = get_ctrls( conn, op, 1 ) ) != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_ANY, "do_add: get_ctrls failed\n", 0, 0, 0 ); - goto cleanup; - } - Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d DEL dn=\"%s\"\n", op->o_connid, op->o_opid, dn, 0, 0 ); diff --git a/servers/slapd/filter.c b/servers/slapd/filter.c index 83d8336fe6..2a609eab34 100644 --- a/servers/slapd/filter.c +++ b/servers/slapd/filter.c @@ -14,11 +14,26 @@ #include "slap.h" -static int get_filter_list(Connection *conn, BerElement *ber, Filter **f, char **fstr); -static int get_substring_filter(Connection *conn, BerElement *ber, Filter *f, char **fstr); +static int get_filter_list( + Connection *conn, + BerElement *ber, + Filter **f, + char **fstr, + char **text ); +static int get_substring_filter( + Connection *conn, + BerElement *ber, + Filter *f, + char **fstr, + char **text ); int -get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr ) +get_filter( + Connection *conn, + BerElement *ber, + Filter **filt, + char **fstr, + char **text ) { ber_tag_t tag; ber_len_t len; @@ -64,6 +79,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr ) tag = ber_peek_tag( ber, &len ); if( tag == LBER_ERROR ) { + *text = "error decoding filter"; return SLAPD_DISCONNECT; } @@ -80,43 +96,50 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr ) #else case LDAP_FILTER_EQUALITY: Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 ); - if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) { - *fstr = ch_malloc(4 + strlen( f->f_avtype ) + - f->f_avvalue.bv_len); - sprintf( *fstr, "(%s=%s)", f->f_avtype, - f->f_avvalue.bv_val ); + if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) { + *text = "error decoding filter"; + break; } + *fstr = ch_malloc(4 + strlen( f->f_avtype ) + + f->f_avvalue.bv_len); + sprintf( *fstr, "(%s=%s)", f->f_avtype, + f->f_avvalue.bv_val ); break; case LDAP_FILTER_SUBSTRINGS: Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 ); - err = get_substring_filter( conn, ber, f, fstr ); + err = get_substring_filter( conn, ber, f, fstr, text ); break; case LDAP_FILTER_GE: Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 ); - if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) { - *fstr = ch_malloc(5 + strlen( f->f_avtype ) + - f->f_avvalue.bv_len); - sprintf( *fstr, "(%s>=%s)", f->f_avtype, - f->f_avvalue.bv_val ); + if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) { + *text = "decoding filter error"; + break; } + *fstr = ch_malloc(5 + strlen( f->f_avtype ) + + f->f_avvalue.bv_len); + sprintf( *fstr, "(%s>=%s)", f->f_avtype, + f->f_avvalue.bv_val ); break; case LDAP_FILTER_LE: Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 ); - if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) { - *fstr = ch_malloc(5 + strlen( f->f_avtype ) + - f->f_avvalue.bv_len); - sprintf( *fstr, "(%s<=%s)", f->f_avtype, - f->f_avvalue.bv_val ); + if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) { + *text = "error decoding filter"; + break; } + *fstr = ch_malloc(5 + strlen( f->f_avtype ) + + f->f_avvalue.bv_len); + sprintf( *fstr, "(%s<=%s)", f->f_avtype, + f->f_avvalue.bv_val ); break; case LDAP_FILTER_PRESENT: Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 ); if ( ber_scanf( ber, "a", &f->f_type ) == LBER_ERROR ) { err = SLAPD_DISCONNECT; + *text = "error decoding filter"; break; } @@ -128,46 +151,52 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr ) case LDAP_FILTER_APPROX: Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 ); - if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) { - *fstr = ch_malloc(5 + strlen( f->f_avtype ) + - f->f_avvalue.bv_len); - sprintf( *fstr, "(%s~=%s)", f->f_avtype, - f->f_avvalue.bv_val ); + if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) { + *text = "error decoding filter"; + break; } + *fstr = ch_malloc(5 + strlen( f->f_avtype ) + + f->f_avvalue.bv_len); + sprintf( *fstr, "(%s~=%s)", f->f_avtype, + f->f_avvalue.bv_val ); break; #endif case LDAP_FILTER_AND: Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 ); - if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp )) - == LDAP_SUCCESS ) { - if (ftmp == NULL) ftmp = ch_strdup(""); - *fstr = ch_malloc( 4 + strlen( ftmp ) ); - sprintf( *fstr, "(&%s)", ftmp ); - free( ftmp ); + err = get_filter_list( conn, ber, &f->f_and, &ftmp, text ); + if ( err != LDAP_SUCCESS ) { + break; } + if (ftmp == NULL) ftmp = ch_strdup(""); + *fstr = ch_malloc( 4 + strlen( ftmp ) ); + sprintf( *fstr, "(&%s)", ftmp ); + free( ftmp ); break; case LDAP_FILTER_OR: Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 ); - if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp )) - == LDAP_SUCCESS ) { - if (ftmp == NULL) ftmp = ch_strdup(""); - *fstr = ch_malloc( 4 + strlen( ftmp ) ); - sprintf( *fstr, "(|%s)", ftmp ); - free( ftmp ); + err = get_filter_list( conn, ber, &f->f_and, &ftmp, text ); + if ( err != LDAP_SUCCESS ) { + break; } + if (ftmp == NULL) ftmp = ch_strdup(""); + *fstr = ch_malloc( 4 + strlen( ftmp ) ); + sprintf( *fstr, "(|%s)", ftmp ); + free( ftmp ); break; case LDAP_FILTER_NOT: Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 ); (void) ber_skip_tag( ber, &len ); - if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == LDAP_SUCCESS ) { - if (ftmp == NULL) ftmp = ch_strdup(""); - *fstr = ch_malloc( 4 + strlen( ftmp ) ); - sprintf( *fstr, "(!%s)", ftmp ); - free( ftmp ); + err = get_filter( conn, ber, &f->f_not, &ftmp, text ); + if ( err != LDAP_SUCCESS ) { + break; } + if (ftmp == NULL) ftmp = ch_strdup(""); + *fstr = ch_malloc( 4 + strlen( ftmp ) ); + sprintf( *fstr, "(!%s)", ftmp ); + free( ftmp ); break; case LDAP_FILTER_EXT: @@ -175,12 +204,14 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr ) Debug( LDAP_DEBUG_ANY, "extensible match not yet implemented.\n", f->f_choice, 0, 0 ); err = LDAP_PROTOCOL_ERROR; + *text = "extensible match not yet implemented"; break; default: Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n", f->f_choice, 0, 0 ); err = LDAP_PROTOCOL_ERROR; + *text = "unknown filter type"; break; } @@ -198,7 +229,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr ) } static int -get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr ) +get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr, char **text ) { Filter **new; int err; @@ -213,8 +244,10 @@ get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr ) for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ) { - if ( (err = get_filter( conn, ber, new, &ftmp )) != LDAP_SUCCESS ) + err = get_filter( conn, ber, new, &ftmp, text ); + if ( err != LDAP_SUCCESS ) return( err ); + if ( *fstr == NULL ) { *fstr = ftmp; } else { @@ -238,7 +271,8 @@ get_substring_filter( Connection *conn, BerElement *ber, Filter *f, - char **fstr + char **fstr, + char **text ) { ber_tag_t tag; @@ -248,17 +282,19 @@ get_substring_filter( char *last; int syntax; + *text = "error decoding filter"; + Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 ); if ( ber_scanf( ber, "{a" /*}*/, &f->f_sub_type ) == LBER_ERROR ) { return SLAPD_DISCONNECT; } - attr_normalize( f->f_sub_type ); - #ifdef SLAPD_SCHEMA_NOT_COMPAT /* not yet implemented */ #else + attr_normalize( f->f_sub_type ); + /* should get real syntax and see if we have a substring matching rule */ syntax = attr_syntax( f->f_sub_type ); #endif diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 4c201af7fb..df833bf573 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -88,15 +88,6 @@ do_modify( Debug( LDAP_DEBUG_ARGS, "do_modify: dn (%s)\n", dn, 0, 0 ); - ndn = ch_strdup( dn ); - - if( dn_normalize( ndn ) == NULL ) { - Debug( LDAP_DEBUG_ANY, "do_modify: invalid dn (%s)\n", dn, 0, 0 ); - send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL, - "invalid DN", NULL, NULL ); - goto cleanup; - } - /* collect modifications & save for later */ for ( tag = ber_first_element( op->o_ber, &len, &last ); @@ -162,6 +153,15 @@ do_modify( goto cleanup; } + ndn = ch_strdup( dn ); + + if( dn_normalize( ndn ) == NULL ) { + Debug( LDAP_DEBUG_ANY, "do_modify: invalid dn (%s)\n", dn, 0, 0 ); + send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL, + "invalid DN", NULL, NULL ); + goto cleanup; + } + #ifdef LDAP_DEBUG Debug( LDAP_DEBUG_ARGS, "modifications:\n", 0, 0, 0 ); for ( tmp = modlist; tmp != NULL; tmp = tmp->ml_next ) { diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index 0530579ee0..78b56666d5 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -83,22 +83,6 @@ do_modrdn( return SLAPD_DISCONNECT; } - ndn = ch_strdup( dn ); - - if( dn_normalize( ndn ) == NULL ) { - Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid dn (%s)\n", dn, 0, 0 ); - send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL, - "invalid DN", NULL, NULL ); - goto cleanup; - } - - if( !rdn_validate( newrdn ) ) { - Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid rdn (%s)\n", newrdn, 0, 0 ); - send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL, - "invalid RDN", NULL, NULL ); - goto cleanup; - } - /* Check for newSuperior parameter, if present scan it */ if ( ber_peek_tag( op->o_ber, &length ) == LDAP_TAG_NEWSUPERIOR ) { @@ -157,6 +141,22 @@ do_modrdn( goto cleanup; } + ndn = ch_strdup( dn ); + + if( dn_normalize( ndn ) == NULL ) { + Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid dn (%s)\n", dn, 0, 0 ); + send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL, + "invalid DN", NULL, NULL ); + goto cleanup; + } + + if( !rdn_validate( newrdn ) ) { + Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid rdn (%s)\n", newrdn, 0, 0 ); + send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL, + "invalid RDN", NULL, NULL ); + goto cleanup; + } + Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d MODRDN dn=\"%s\"\n", op->o_connid, op->o_opid, dn, 0, 0 ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index a199abcf54..0ade752f5b 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -360,7 +360,13 @@ LIBSLAPD_F (char *) get_supported_extop LDAP_P((int index)); * filter.c */ -LIBSLAPD_F (int) get_filter LDAP_P(( Connection *conn, BerElement *ber, Filter **filt, char **fstr )); +LIBSLAPD_F (int) get_filter LDAP_P(( + Connection *conn, + BerElement *ber, + Filter **filt, + char **fstr, + char **text )); + LIBSLAPD_F (void) filter_free LDAP_P(( Filter *f )); LIBSLAPD_F (void) filter_print LDAP_P(( Filter *f )); diff --git a/servers/slapd/search.c b/servers/slapd/search.c index 24bf9c34b3..5ba446f899 100644 --- a/servers/slapd/search.c +++ b/servers/slapd/search.c @@ -40,6 +40,7 @@ do_search( char **attrs = NULL; Backend *be; int rc; + char *text; Debug( LDAP_DEBUG_TRACE, "do_search\n", 0, 0, 0 ); @@ -121,13 +122,13 @@ do_search( attrsonly); /* filter - returns a "normalized" version */ - if ( (rc = get_filter( conn, op->o_ber, &filter, &fstr )) != LDAP_SUCCESS ) { + if ( (rc = get_filter( conn, op->o_ber, &filter, &fstr, &text )) != LDAP_SUCCESS ) { if( rc == SLAPD_DISCONNECT ) { send_ldap_disconnect( conn, op, - LDAP_PROTOCOL_ERROR, "decode filter error" ); + LDAP_PROTOCOL_ERROR, text ); } else { send_ldap_result( conn, op, rc, - NULL, "bad search filter", NULL, NULL ); + NULL, text, NULL, NULL ); } goto return_results; } -- 2.39.5