X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=servers%2Fslapd%2Fmodify.c;h=77b0d5013a2a630dd7fc6559227788b7b3ae77dd;hb=021443bd5d355b8171dcbe4650c67507b9e1b83b;hp=ea961ef57f7d3823746d468195d278009aad5cec;hpb=521fa9168d55a02f46b20fa8b9e09ee641812047;p=openldap diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index ea961ef57f..77b0d5013a 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -187,7 +187,7 @@ do_modify( } rs->sr_err = slap_mods_check( modlist, &rs->sr_text, - textbuf, textlen, NULL ); + textbuf, textlen, NULL ); if ( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); @@ -206,7 +206,7 @@ cleanup: op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); - if ( modlist != NULL ) slap_mods_free( modlist ); + if ( op->orm_modlist != NULL ) slap_mods_free( op->orm_modlist ); return rs->sr_err; } @@ -225,6 +225,9 @@ fe_op_modify( Operation *op, SlapReply *rs ) #endif int increment = op->orm_increment; int rc = 0; + BackendDB *op_be; + char textbuf[ SLAP_TEXT_BUFLEN ]; + size_t textlen = sizeof( textbuf ); if( op->o_req_ndn.bv_len == 0 ) { Debug( LDAP_DEBUG_ANY, "do_modify: root dse!\n", 0, 0, 0 ); @@ -330,6 +333,12 @@ fe_op_modify( Operation *op, SlapReply *rs ) goto cleanup; } + /* If we've got a glued backend, check the real backend */ + op_be = op->o_bd; + if ( SLAP_GLUE_INSTANCE( op->o_bd )) { + op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 0 ); + } + /* check restrictions */ if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); @@ -341,6 +350,15 @@ fe_op_modify( Operation *op, SlapReply *rs ) goto cleanup; } + { + rs->sr_err = slap_mods_obsolete_check( op, modlist, + &rs->sr_text, textbuf, textlen ); + if ( rs->sr_err != LDAP_SUCCESS ) { + send_ldap_result( op, rs ); + goto cleanup; + } + } + /* check for modify/increment support */ if( increment && !SLAP_INCREMENT( op->o_bd ) ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, @@ -420,22 +438,19 @@ fe_op_modify( Operation *op, SlapReply *rs ) #endif { int update = !BER_BVISEMPTY( &op->o_bd->be_update_ndn ); - char textbuf[ SLAP_TEXT_BUFLEN ]; - size_t textlen = sizeof( textbuf ); slap_callback cb = { NULL, slap_replog_cb, NULL, NULL }; + op->o_bd = op_be; if ( !update ) { - rs->sr_err = slap_mods_no_update_check( modlist, - &rs->sr_text, textbuf, textlen ); + rs->sr_err = slap_mods_no_user_mod_check( op, modlist, + &rs->sr_text, textbuf, textlen ); if ( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } } - - if ( !repl_user ) { for( modtail = &modlist; *modtail != NULL; @@ -513,20 +528,30 @@ cleanup:; } /* - * Do non-update constraint checking. + * Obsolete constraint checking. */ int -slap_mods_no_update_check( +slap_mods_obsolete_check( + Operation *op, Modifications *ml, const char **text, char *textbuf, size_t textlen ) { + if( get_manageDIT( op ) ) return LDAP_SUCCESS; + for ( ; ml != NULL; ml = ml->sml_next ) { - if ( is_at_no_user_mod( ml->sml_desc->ad_type ) ) { - /* user modification disallowed */ + if ( is_at_obsolete( ml->sml_desc->ad_type ) && + (( ml->sml_op != LDAP_MOD_REPLACE && + ml->sml_op != LDAP_MOD_DELETE ) || + ml->sml_values != NULL )) + { + /* + * attribute is obsolete, + * only allow replace/delete with no values + */ snprintf( textbuf, textlen, - "%s: no user modification allowed", + "%s: attribute is obsolete", ml->sml_type.bv_val ); *text = textbuf; return LDAP_CONSTRAINT_VIOLATION; @@ -536,6 +561,44 @@ slap_mods_no_update_check( return LDAP_SUCCESS; } +/* + * No-user-modification constraint checking. + */ +int +slap_mods_no_user_mod_check( + Operation *op, + Modifications *ml, + const char **text, + char *textbuf, + size_t textlen ) +{ + for ( ; ml != NULL; ml = ml->sml_next ) { + if ( !is_at_no_user_mod( ml->sml_desc->ad_type ) ) continue; + + if( get_manageDIT( op )) { + if ( ml->sml_desc->ad_type->sat_flags & SLAP_AT_MANAGEABLE ) { + continue; + } + + /* attribute not manageable */ + snprintf( textbuf, textlen, + "%s: no-user-modification attribute not manageable", + ml->sml_type.bv_val ); + + } else { + /* user modification disallowed */ + snprintf( textbuf, textlen, + "%s: no user modification allowed", + ml->sml_type.bv_val ); + } + + *text = textbuf; + return LDAP_CONSTRAINT_VIOLATION; + } + + return LDAP_SUCCESS; +} + /* * Do basic attribute type checking and syntax validation. */ @@ -595,17 +658,6 @@ int slap_mods_check( } #if 0 - /* moved to slap_mods_no_update_check() */ - if (!update && is_at_no_user_mod( ad->ad_type )) { - /* user modification disallowed */ - snprintf( textbuf, textlen, - "%s: no user modification allowed", - ml->sml_type.bv_val ); - *text = textbuf; - return LDAP_CONSTRAINT_VIOLATION; - } -#endif - if ( is_at_obsolete( ad->ad_type ) && (( ml->sml_op != LDAP_MOD_REPLACE && ml->sml_op != LDAP_MOD_DELETE ) || @@ -621,6 +673,7 @@ int slap_mods_check( *text = textbuf; return LDAP_CONSTRAINT_VIOLATION; } +#endif if ( ml->sml_op == LDAP_MOD_INCREMENT && #ifdef SLAPD_REAL_SYNTAX @@ -736,59 +789,37 @@ int slap_mods_check( ml->sml_nvalues[nvals].bv_len = 0; } - if( nvals ) { - /* check for duplicates */ - int i, j; + /* check for duplicates, but ignore Deletes. + */ + if( nvals > 1 && ml->sml_op != LDAP_MOD_DELETE ) { + int i, j, rc, match; 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; - 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; - - } else if ( rc != LDAP_SUCCESS ) { - return rc; - } + for ( i = 1; i < nvals ; i++ ) { + /* test asserted values against themselves */ + for( j = 0; j < i; j++ ) { + rc = ordered_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; + + } else if ( rc != LDAP_SUCCESS ) { + return rc; } } } @@ -856,7 +887,7 @@ int slap_mods_opattrs( if( op->o_tag == LDAP_REQ_ADD ) { struct berval tmpval; - if( global_schemacheck ) { + { int rc = mods_structural_class( mods, &tmpval, text, textbuf, textlen ); if( rc != LDAP_SUCCESS ) return rc;