From b2176590886812add2f17bfe49ed0e1acdc97886 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Thu, 8 Apr 2004 06:44:50 +0000 Subject: [PATCH] ITS#3066: properly detect duplicates --- servers/slapd/modify.c | 61 +++++++++++++++- servers/slapd/mods.c | 146 +++++++++++-------------------------- servers/slapd/proto-slap.h | 4 - 3 files changed, 101 insertions(+), 110 deletions(-) diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 9e866be581..b9e38eb17c 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -112,8 +112,7 @@ do_modify( tmp.sml_nvalues = NULL; if ( ber_scanf( op->o_ber, "{i{m[W]}}", &mop, - &tmp.sml_type, &tmp.sml_values ) - == LBER_ERROR ) + &tmp.sml_type, &tmp.sml_values ) == LBER_ERROR ) { send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding modlist error" ); @@ -766,6 +765,64 @@ int slap_mods_check( ml->sml_nvalues[nvals].bv_val = NULL; ml->sml_nvalues[nvals].bv_len = 0; } + + if( nvals ) { + /* check for duplicates */ + int i, j; + MatchingRule *mr = ad->ad_type->sat_equality; + + /* check if the values we're adding already exist */ + if( mr == NULL || !mr->smr_match ) { + for ( i = 1; ml->sml_values[i].bv_val != NULL; i++ ) { + /* test asserted values against themselves */ + for( j = 0; j < i; j++ ) { + if ( bvmatch( &ml->sml_values[i], + &ml->sml_values[j] ) ) + { + /* value exists already */ + snprintf( textbuf, textlen, + "%s: value #%d provided more than once", + ml->sml_desc->ad_cname.bv_val, j ); + *text = textbuf; + return LDAP_TYPE_OR_VALUE_EXISTS; + } + } + } + + } else { + int rc = LDAP_SUCCESS; + int match; + + for ( i = 1; ml->sml_values[i].bv_val != NULL; i++ ) { + /* test asserted values against themselves */ + for( j = 0; j < i; j++ ) { + rc = value_match( &match, ml->sml_desc, mr, + SLAP_MR_EQUALITY + | SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX + | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH + | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH, + ml->sml_nvalues + ? &ml->sml_nvalues[i] + : &ml->sml_values[i], + ml->sml_nvalues + ? &ml->sml_nvalues[j] + : &ml->sml_values[j], + text ); + if ( rc == LDAP_SUCCESS && match == 0 ) { + /* value exists already */ + snprintf( textbuf, textlen, + "%s: value #%d provided more than once", + ml->sml_desc->ad_cname.bv_val, j ); + *text = textbuf; + return LDAP_TYPE_OR_VALUE_EXISTS; + } + } + } + + if ( rc != LDAP_SUCCESS ) return rc; + } + } + } } diff --git a/servers/slapd/mods.c b/servers/slapd/mods.c index c2d74ba4d6..e6790c258f 100644 --- a/servers/slapd/mods.c +++ b/servers/slapd/mods.c @@ -29,22 +29,6 @@ #include "slap.h" -int -modify_check_duplicates( - AttributeDescription *ad, - MatchingRule *mr, - BerVarray vals, - BerVarray mods, - int permissive, - const char **text, - char *textbuf, size_t textlen ) -{ - int i, j, numvals = 0, nummods, - rc = LDAP_SUCCESS, matched; - /* this function is no longer used */ - return rc; -} - int modify_add_values( Entry *e, @@ -91,32 +75,14 @@ modify_add_values( return LDAP_INAPPROPRIATE_MATCHING; } - for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) { + for ( i = 0; mod->sm_values[i].bv_val != NULL; i++ ) { /* test asserted values against existing values */ - if( a ) { - for( matched = 0, j = 0; a->a_vals[j].bv_val != NULL; j++ ) { - if ( bvmatch( &mod->sm_bvalues[i], &a->a_vals[j] ) ) { - if ( permissive ) { - matched++; - continue; - } - /* value exists already */ - *text = textbuf; - snprintf( textbuf, textlen, - "modify/%s: %s: value #%i already exists", - op, mod->sm_desc->ad_cname.bv_val, j ); - return LDAP_TYPE_OR_VALUE_EXISTS; + for( matched = 0, j = 0; a->a_vals[j].bv_val != NULL; j++ ) { + if ( bvmatch( &mod->sm_values[i], &a->a_vals[j] ) ) { + if ( permissive ) { + matched++; + continue; } - } - if ( permissive && matched == j ) { - /* values already exist; do nothing */ - return LDAP_SUCCESS; - } - } - - /* test asserted values against themselves */ - for( j = 0; j < i; j++ ) { - if ( bvmatch( &mod->sm_bvalues[i], &mod->sm_bvalues[j] ) ) { /* value exists already */ *text = textbuf; snprintf( textbuf, textlen, @@ -125,78 +91,53 @@ modify_add_values( return LDAP_TYPE_OR_VALUE_EXISTS; } } + + if ( permissive && matched == j ) { + /* values already exist; do nothing */ + return LDAP_SUCCESS; + } } - } else { + } else if ( a != NULL ) { /* no normalization is done in this routine nor * in the matching routines called by this routine. * values are now normalized once on input to the * server (whether from LDAP or from the underlying * database). - * This should outperform the old code. No numbers - * are available yet. */ - int rc; - if ( mod->sm_bvalues[1].bv_val == 0 ) { - if ( a != NULL ) { - int i; - - for ( matched = 0, i = 0; a->a_vals[ i ].bv_val; i++ ) { - int match; - - if( mod->sm_nvalues ) { - rc = value_match( &match, mod->sm_desc, mr, - SLAP_MR_EQUALITY - | SLAP_MR_VALUE_OF_ASSERTION_SYNTAX - | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH - | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH, - &a->a_nvals[i], - &mod->sm_nvalues[0], - text ); - - } else { - rc = value_match( &match, mod->sm_desc, mr, - SLAP_MR_EQUALITY - | SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, - &a->a_vals[i], - &mod->sm_values[0], - text ); - } - - - if( rc == LDAP_SUCCESS && match == 0 ) { - if ( permissive ) { - matched++; - continue; - } - *text = textbuf; - snprintf( textbuf, textlen, - "modify/%s: %s: value #0 already exists", - op, mod->sm_desc->ad_cname.bv_val ); - return LDAP_TYPE_OR_VALUE_EXISTS; - } - } - if ( permissive && matched == i ) { - /* values already exist; do nothing */ - return LDAP_SUCCESS; - } - } - - } else { - rc = modify_check_duplicates( mod->sm_desc, mr, - a ? a->a_vals : NULL, mod->sm_bvalues, - permissive, text, textbuf, textlen ); + for ( matched = 0, i = 0; a->a_vals[ i ].bv_val; i++ ) { + int match; - if ( permissive && rc == LDAP_TYPE_OR_VALUE_EXISTS ) { - return LDAP_SUCCESS; + if( mod->sm_nvalues ) { + rc = value_match( &match, mod->sm_desc, mr, + SLAP_MR_EQUALITY | SLAP_MR_VALUE_OF_ASSERTION_SYNTAX + | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH + | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH, + &a->a_nvals[i], &mod->sm_nvalues[0], text ); + } else { + rc = value_match( &match, mod->sm_desc, mr, + SLAP_MR_EQUALITY | SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + &a->a_vals[i], &mod->sm_values[0], text ); } - if ( rc != LDAP_SUCCESS ) { - return rc; + if( rc == LDAP_SUCCESS && match == 0 ) { + if ( permissive ) { + matched++; + continue; + } + *text = textbuf; + snprintf( textbuf, textlen, + "modify/%s: %s: value #0 already exists", + op, mod->sm_desc->ad_cname.bv_val ); + return LDAP_TYPE_OR_VALUE_EXISTS; } } + if ( permissive && matched == i ) { + /* values already exist; do nothing */ + return LDAP_SUCCESS; + } } /* no - add them */ @@ -218,8 +159,7 @@ modify_delete_values( Modification *mod, int permissive, const char **text, - char *textbuf, size_t textlen -) + char *textbuf, size_t textlen ) { int i, j, k, rc = LDAP_SUCCESS; Attribute *a; @@ -233,7 +173,7 @@ modify_delete_values( */ /* delete the entire attribute */ - if ( mod->sm_bvalues == NULL ) { + if ( mod->sm_values == NULL ) { rc = attr_delete( &e->e_attrs, mod->sm_desc ); if( permissive ) { @@ -270,7 +210,6 @@ modify_delete_values( return LDAP_NO_SUCH_ATTRIBUTE; } - for ( i = 0; mod->sm_values[i].bv_val != NULL; i++ ) { int found = 0; for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) { @@ -380,7 +319,7 @@ modify_replace_values( { (void) attr_delete( &e->e_attrs, mod->sm_desc ); - if ( mod->sm_bvalues ) { + if ( mod->sm_values ) { return modify_add_values( e, mod, permissive, text, textbuf, textlen ); } @@ -406,11 +345,10 @@ modify_increment_values( return LDAP_NO_SUCH_ATTRIBUTE; } - if ( !strcmp( a->a_desc->ad_type->sat_syntax_oid, SLAPD_INTEGER_SYNTAX )) { int i; char str[sizeof(long)*3 + 2]; /* overly long */ - long incr = atol( mod->sm_bvalues[0].bv_val ); + long incr = atol( mod->sm_values[0].bv_val ); /* treat zero and errors as a no-op */ if( incr == 0 ) { diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index a24df9d9a7..655d26cbcf 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -688,10 +688,6 @@ LDAP_SLAPD_F( int ) slap_mods_opattrs( /* * mods.c */ -LDAP_SLAPD_F( int ) modify_check_duplicates( - AttributeDescription *ad, MatchingRule *mr, - BerVarray vals, BerVarray mods, int permissive, - const char **text, char *textbuf, size_t textlen ); LDAP_SLAPD_F( int ) modify_add_values( Entry *e, Modification *mod, int permissive, -- 2.39.5