X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-mdb%2Fmodify.c;h=35682cefe8845fc70feb065fac23c440b95be3c5;hb=10755b91dd4c21851e6e25078bd45114b0032e33;hp=1a81e820a084b0fd612737f9b852f7669de0e6a3;hpb=d534e1149505c44f6ff2c0631e56c1c11d687c5d;p=openldap diff --git a/servers/slapd/back-mdb/modify.c b/servers/slapd/back-mdb/modify.c index 1a81e820a0..35682cefe8 100644 --- a/servers/slapd/back-mdb/modify.c +++ b/servers/slapd/back-mdb/modify.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2000-2013 The OpenLDAP Foundation. + * Copyright 2000-2015 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -228,7 +228,9 @@ int mdb_modify_internal( mod->sm_op = SLAP_MOD_SOFTDEL; - if ( err == LDAP_NO_SUCH_ATTRIBUTE ) { + if ( err == LDAP_SUCCESS ) { + got_delete = 1; + } else if ( err == LDAP_NO_SUCH_ATTRIBUTE ) { err = LDAP_SUCCESS; } @@ -338,6 +340,9 @@ int mdb_modify_internal( if ( a2 ) { /* need to detect which values were deleted */ int i, j; + /* let add know there were deletes */ + if ( a2->a_flags & SLAP_ATTR_IXADD ) + a2->a_flags |= SLAP_ATTR_IXDEL; vals = op->o_tmpalloc( (ap->a_numvals + 1) * sizeof(struct berval), op->o_tmpmemctx ); j = 0; @@ -375,9 +380,53 @@ int mdb_modify_internal( for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) { if (ap->a_flags & SLAP_ATTR_IXADD) { ap->a_flags &= ~SLAP_ATTR_IXADD; - rc = mdb_index_values( op, tid, ap->a_desc, - ap->a_nvals, - e->e_id, SLAP_INDEX_ADD_OP ); + if ( ap->a_flags & SLAP_ATTR_IXDEL ) { + /* if any values were deleted, we must readd index + * for all remaining values. + */ + ap->a_flags &= ~SLAP_ATTR_IXDEL; + rc = mdb_index_values( op, tid, ap->a_desc, + ap->a_nvals, + e->e_id, SLAP_INDEX_ADD_OP ); + } else { + int found = 0; + /* if this was only an add, we only need to index + * the added values. + */ + for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { + struct berval *vals; + if ( ml->sml_desc != ap->a_desc || !ml->sml_numvals ) + continue; + found = 1; + switch( ml->sml_op ) { + case LDAP_MOD_ADD: + case LDAP_MOD_REPLACE: + case LDAP_MOD_INCREMENT: + case SLAP_MOD_SOFTADD: + case SLAP_MOD_ADD_IF_NOT_PRESENT: + if ( ml->sml_op == LDAP_MOD_INCREMENT ) + vals = ap->a_nvals; + else if ( ml->sml_nvalues ) + vals = ml->sml_nvalues; + else + vals = ml->sml_values; + rc = mdb_index_values( op, tid, ap->a_desc, + vals, e->e_id, SLAP_INDEX_ADD_OP ); + break; + } + if ( rc ) + break; + } + /* This attr was affected by a modify of a subtype, so + * there was no direct match in the modlist. Just readd + * all of its values. + */ + if ( !found ) { + rc = mdb_index_values( op, tid, ap->a_desc, + ap->a_nvals, + e->e_id, SLAP_INDEX_ADD_OP ); + } + } if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s: attribute \"%s\" index add failure\n", @@ -410,49 +459,12 @@ mdb_modify( Operation *op, SlapReply *rs ) LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; int num_ctrls = 0; -#ifdef LDAP_X_TXN - int settle = 0; -#endif - Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(mdb_modify) ": %s\n", op->o_req_dn.bv_val, 0, 0 ); #ifdef LDAP_X_TXN - if( op->o_txnSpec ) { - /* acquire connection lock */ - ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); - if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) { - rs->sr_text = "invalid transaction identifier"; - rs->sr_err = LDAP_X_TXN_ID_INVALID; - goto txnReturn; - } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) { - settle=1; - goto txnReturn; - } - - if( op->o_conn->c_txn_backend == NULL ) { - op->o_conn->c_txn_backend = op->o_bd; - - } else if( op->o_conn->c_txn_backend != op->o_bd ) { - rs->sr_text = "transaction cannot span multiple database contexts"; - rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; - goto txnReturn; - } - - /* insert operation into transaction */ - - rs->sr_text = "transaction specified"; - rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY; - -txnReturn: - /* release connection lock */ - ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); - - if( !settle ) { - send_ldap_result( op, rs ); - return rs->sr_err; - } - } + if( op->o_txnSpec && txn_preop( op, rs )) + return rs->sr_err; #endif ctrls[num_ctrls] = NULL; @@ -589,7 +601,12 @@ txnReturn: Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(mdb_modify) ": id2entry update failed " "(%d)\n", rs->sr_err, 0, 0 ); - rs->sr_text = "entry update failed"; + if ( rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ) { + rs->sr_text = "entry too big"; + } else { + rs->sr_err = LDAP_OTHER; + rs->sr_text = "entry update failed"; + } goto return_results; }