]> git.sur5r.net Git - openldap/commitdiff
ITS#3066: properly detect duplicates
authorKurt Zeilenga <kurt@openldap.org>
Thu, 8 Apr 2004 06:44:50 +0000 (06:44 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Thu, 8 Apr 2004 06:44:50 +0000 (06:44 +0000)
servers/slapd/modify.c
servers/slapd/mods.c
servers/slapd/proto-slap.h

index 9e866be5815aac1caaf298d553f61104dec18cc8..b9e38eb17cbf962c23954affb69b0ac83616a6ca 100644 (file)
@@ -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;
+                               }
+                       }
+
                }
        }
 
index c2d74ba4d62e6c68ab5c012660078dd5804c6ca1..e6790c258f66297b9dce1d493fe752e9a10fcfb6 100644 (file)
 
 #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 ) {
index a24df9d9a7b46a1aa80b8a69e727e17510ebc9fb..655d26cbcf167922d8490bc1c60fdda3f6a40754 100644 (file)
@@ -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,