]> git.sur5r.net Git - openldap/commitdiff
Honour PermitModify control when adding or deleting values. This code needs
authorLuke Howard <lukeh@openldap.org>
Fri, 24 Jan 2003 01:43:09 +0000 (01:43 +0000)
committerLuke Howard <lukeh@openldap.org>
Fri, 24 Jan 2003 01:43:09 +0000 (01:43 +0000)
review although, with the control disabled, it should not affect existing
code paths.

servers/slapd/add.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-ldbm/modify.c
servers/slapd/mods.c
servers/slapd/proto-slap.h

index bbeedc1176d49d73768a946430ba95e95a534b49..924d537f57007bd290f4fa303c5a5b4ec30bd1ff 100644 (file)
@@ -454,7 +454,7 @@ slap_mods2entry(
                                char            textbuf[ SLAP_TEXT_BUFLEN ]  = { '\0' };
                                
                                rc = modify_check_duplicates( mods->sml_desc, mr,
-                                               NULL, mods->sml_bvalues,
+                                               NULL, mods->sml_bvalues, 0,
                                                &text, textbuf, sizeof( textbuf ) );
 
                                if ( rc != LDAP_SUCCESS ) {
index 3bf41f6928257b8c018a1cf9f8e6d24f9c33e3d1..92f376fa17d1b2c09c17ed28bc8db41866724ba1 100644 (file)
@@ -56,7 +56,7 @@ int bdb_modify_internal(
 #else
                        Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: add\n", 0, 0, 0);
 #endif
-                       err = modify_add_values( e, mod, text, textbuf, textlen );
+                       err = modify_add_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        if( err != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG ( OPERATION, ERR, 
@@ -75,7 +75,7 @@ int bdb_modify_internal(
 #else
                        Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: delete\n", 0, 0, 0);
 #endif
-                       err = modify_delete_values( e, mod, text, textbuf, textlen );
+                       err = modify_delete_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        assert( err != LDAP_TYPE_OR_VALUE_EXISTS );
                        if( err != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
@@ -95,7 +95,7 @@ int bdb_modify_internal(
 #else
                        Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: replace\n", 0, 0, 0);
 #endif
-                       err = modify_replace_values( e, mod, text, textbuf, textlen );
+                       err = modify_replace_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        if( err != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG ( OPERATION, ERR, 
@@ -119,7 +119,7 @@ int bdb_modify_internal(
                         */
                        mod->sm_op = LDAP_MOD_ADD;
 
-                       err = modify_add_values( e, mod, text, textbuf, textlen );
+                       err = modify_add_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) {
                                err = LDAP_SUCCESS;
                        }
index d5db4e28fca627626c200240207cf8bde557d830..7daf460d787ec9f24dbbd713c426528b15ab2aee 100644 (file)
@@ -65,7 +65,7 @@ int ldbm_modify_internal(
                        Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: add\n", 0, 0, 0);
 #endif
 
-                       rc = modify_add_values( e, mod, text, textbuf, textlen );
+                       rc = modify_add_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( BACK_LDBM, INFO, 
@@ -84,7 +84,7 @@ int ldbm_modify_internal(
                        Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: delete\n", 0, 0, 0);
 #endif
 
-                       rc = modify_delete_values( e, mod, text, textbuf, textlen );
+                       rc = modify_delete_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        assert( rc != LDAP_TYPE_OR_VALUE_EXISTS );
                        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
@@ -104,7 +104,7 @@ int ldbm_modify_internal(
                        Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: replace\n", 0, 0, 0);
 #endif
 
-                       rc = modify_replace_values( e, mod, text, textbuf, textlen );
+                       rc = modify_replace_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( BACK_LDBM, INFO, 
@@ -129,7 +129,7 @@ int ldbm_modify_internal(
                         */
                        mod->sm_op = LDAP_MOD_ADD;
 
-                       rc = modify_add_values( e, mod, text, textbuf, textlen );
+                       rc = modify_add_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
                                rc = LDAP_SUCCESS;
                        }
index 20721784ce0b0a75537c936e45b2abd5c7be14f2..81b6930cbe6d3dba03a5bbe98ba57484511c61fa 100644 (file)
@@ -24,11 +24,12 @@ modify_check_duplicates(
        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;
+                       rc = LDAP_SUCCESS, matched;
        BerVarray       nvals = NULL, nmods = NULL;
 
        /*
@@ -130,7 +131,7 @@ modify_check_duplicates(
                }
 
                if ( numvals > 0 && numvals < nummods ) {
-                       for ( j = 0; nvals[ j ].bv_val; j++ ) {
+                       for ( matched = 0, j = 0; nvals[ j ].bv_val; j++ ) {
                                int match;
 
                                rc = (*mr->smr_match)( &match,
@@ -145,8 +146,12 @@ modify_check_duplicates(
                                                ad->ad_cname.bv_val );
                                        goto return_results;
                                }
-       
+
                                if ( match == 0 ) {
+                                       if ( permissive ) {
+                                               matched++;
+                                               continue;
+                                       }
                                        *text = textbuf;
                                        snprintf( textbuf, textlen,
                                                "%s: value #%d provided more than once",
@@ -156,9 +161,15 @@ modify_check_duplicates(
                                        goto return_results;
                                }
                        }
+
+                       if ( permissive && matched == j ) {
+                               nmods[ i + 1 ].bv_val = NULL;
+                               rc = LDAP_TYPE_OR_VALUE_EXISTS;
+                               goto return_results;
+                       }
                }
        
-               for ( j = 0; j < i; j++ ) {
+               for ( matched = 0, j = 0; j < i; j++ ) {
                        int match;
 
                        rc = (*mr->smr_match)( &match,
@@ -175,6 +186,10 @@ modify_check_duplicates(
                        }
 
                        if ( match == 0 ) {
+                               if ( permissive ) {
+                                       matched++;
+                                       continue;
+                               }
                                *text = textbuf;
                                snprintf( textbuf, textlen,
                                        "%s: value #%d provided more than once",
@@ -184,6 +199,12 @@ modify_check_duplicates(
                                goto return_results;
                        }
                }
+
+               if ( permissive && matched == j ) {
+                       nmods[ i + 1 ].bv_val = NULL;
+                       rc = LDAP_TYPE_OR_VALUE_EXISTS;
+                       goto return_results;
+               }
        }
        nmods[ i ].bv_val = NULL;
 
@@ -205,7 +226,7 @@ modify_check_duplicates(
                                goto return_results;
                        }
 
-                       for ( i = 0; nmods[ i ].bv_val; i++ ) {
+                       for ( matched = 0, i = 0; nmods[ i ].bv_val; i++ ) {
                                int match;
 
                                rc = (*mr->smr_match)( &match,
@@ -221,6 +242,10 @@ modify_check_duplicates(
                                }
 
                                if ( match == 0 ) {
+                                       if ( permissive ) {
+                                               matched++;
+                                               continue;
+                                       }
                                        *text = textbuf;
                                        snprintf( textbuf, textlen,
                                                "%s: value #%d provided more than once",
@@ -230,6 +255,10 @@ modify_check_duplicates(
                                }
                        }
 
+                       if ( permissive && matched == i ) {
+                               rc = LDAP_TYPE_OR_VALUE_EXISTS;
+                               goto return_results;
+                       }
                }
        }
 
@@ -248,11 +277,13 @@ int
 modify_add_values(
        Entry   *e,
        Modification    *mod,
+       int     permissive,
        const char      **text,
        char *textbuf, size_t textlen
 )
 {
        int             i, j;
+       int             matched;
        Attribute       *a;
        MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
        const char *op;
@@ -271,6 +302,12 @@ modify_add_values(
 
        a = attr_find( e->e_attrs, mod->sm_desc );
 
+       /*
+        * With permissive set, as long as the attribute being added
+        * has the same value(s?) as the existing attribute, then the
+        * modify will succeed.
+        */
+
        /* check if the values we're adding already exist */
        if( mr == NULL || !mr->smr_match ) {
                if ( a != NULL ) {
@@ -286,10 +323,13 @@ modify_add_values(
                for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) {
                        /* test asserted values against existing values */
                        if( a ) {
-                               for( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
+                               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,
@@ -298,6 +338,10 @@ modify_add_values(
                                                return LDAP_TYPE_OR_VALUE_EXISTS;
                                        }
                                }
+                               if ( permissive && matched == j ) {
+                                       /* values already exist; do nothing */
+                                       return LDAP_SUCCESS;
+                               }
                        }
 
                        /* test asserted values against themselves */
@@ -357,7 +401,7 @@ modify_add_values(
                                        return rc;
                                }
 
-                               for ( i = 0; a->a_vals[ i ].bv_val; i++ ) {
+                               for ( matched = 0, i = 0; a->a_vals[ i ].bv_val; i++ ) {
                                        int     match;
 
                                        rc = value_match( &match, mod->sm_desc, mr,
@@ -365,6 +409,10 @@ modify_add_values(
                                                &a->a_vals[ i ], &asserted, text );
 
                                        if( rc == LDAP_SUCCESS && match == 0 ) {
+                                               if ( permissive ) {
+                                                       matched++;
+                                                       continue;
+                                               }
                                                free( asserted.bv_val );
                                                *text = textbuf;
                                                snprintf( textbuf, textlen,
@@ -373,13 +421,22 @@ modify_add_values(
                                                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 );
-       
+
+                       if ( permissive && rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
+                               return LDAP_SUCCESS;
+                       }
+
                        if ( rc != LDAP_SUCCESS ) {
                                return rc;
                        }
@@ -403,6 +460,7 @@ int
 modify_delete_values(
        Entry   *e,
        Modification    *mod,
+       int     permissive,
        const char      **text,
        char *textbuf, size_t textlen
 )
@@ -413,11 +471,18 @@ modify_delete_values(
        BerVarray       nvals = NULL;
        char            dummy = '\0';
 
+       /*
+        * If permissive is set, then the non-existence of an 
+        * attribute is not treated as an error.
+        */
+
        /* delete the entire attribute */
        if ( mod->sm_bvalues == NULL ) {
                rc = attr_delete( &e->e_attrs, mod->sm_desc );
 
-               if( rc != LDAP_SUCCESS ) {
+               if( permissive ) {
+                       rc = LDAP_SUCCESS;
+               } else if( rc != LDAP_SUCCESS ) {
                        *text = textbuf;
                        snprintf( textbuf, textlen,
                                "modify/delete: %s: no such attribute",
@@ -439,6 +504,9 @@ modify_delete_values(
 
        /* delete specific values - find the attribute first */
        if ( (a = attr_find( e->e_attrs, mod->sm_desc )) == NULL ) {
+               if( permissive ) {
+                       return LDAP_SUCCESS;
+               }
                *text = textbuf;
                snprintf( textbuf, textlen,
                        "modify/delete: %s: no such attribute",
@@ -581,6 +649,7 @@ int
 modify_replace_values(
        Entry   *e,
        Modification    *mod,
+       int             permissive,
        const char      **text,
        char *textbuf, size_t textlen
 )
@@ -588,7 +657,7 @@ modify_replace_values(
        (void) attr_delete( &e->e_attrs, mod->sm_desc );
 
        if ( mod->sm_bvalues ) {
-               return modify_add_values( e, mod, text, textbuf, textlen );
+               return modify_add_values( e, mod, permissive, text, textbuf, textlen );
        }
 
        return LDAP_SUCCESS;
index d281fe4f329b533a88971c92f534318bbe36399e..cab27a8eb880069a0c10db5769fc97a6afcf5a5a 100644 (file)
@@ -590,16 +590,19 @@ LDAP_SLAPD_F( int ) slap_mods_opattrs(
  */
 LDAP_SLAPD_F( int ) modify_check_duplicates(
        AttributeDescription *ad, MatchingRule *mr, 
-       BerVarray vals, BerVarray mods,
+       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,
        const char **text, char *textbuf, size_t textlen );
 LDAP_SLAPD_F( int ) modify_delete_values( Entry *e,
        Modification *mod,
+       int permissive,
        const char **text, char *textbuf, size_t textlen );
 LDAP_SLAPD_F( int ) modify_replace_values( Entry *e,
        Modification *mod,
+       int permissive,
        const char **text, char *textbuf, size_t textlen );
 
 LDAP_SLAPD_F( void ) slap_mod_free( Modification *mod, int freeit );