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 ) {
#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,
#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
#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,
*/
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;
}
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,
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
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,
*/
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;
}
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;
/*
}
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,
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",
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,
}
if ( match == 0 ) {
+ if ( permissive ) {
+ matched++;
+ continue;
+ }
*text = textbuf;
snprintf( textbuf, textlen,
"%s: value #%d provided more than once",
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;
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,
}
if ( match == 0 ) {
+ if ( permissive ) {
+ matched++;
+ continue;
+ }
*text = textbuf;
snprintf( textbuf, textlen,
"%s: value #%d provided more than once",
}
}
+ if ( permissive && matched == i ) {
+ rc = LDAP_TYPE_OR_VALUE_EXISTS;
+ goto return_results;
+ }
}
}
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;
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 ) {
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,
return LDAP_TYPE_OR_VALUE_EXISTS;
}
}
+ if ( permissive && matched == j ) {
+ /* values already exist; do nothing */
+ return LDAP_SUCCESS;
+ }
}
/* test asserted values against themselves */
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,
&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,
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;
}
modify_delete_values(
Entry *e,
Modification *mod,
+ int permissive,
const char **text,
char *textbuf, size_t textlen
)
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",
/* 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",
modify_replace_values(
Entry *e,
Modification *mod,
+ int permissive,
const char **text,
char *textbuf, size_t textlen
)
(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;
*/
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 );