mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-20 22:59:34 -05:00
ITS#9751 Do not drop out of order deletes completely
This commit is contained in:
parent
74ed5163ed
commit
70e6bd6777
1 changed files with 57 additions and 8 deletions
|
|
@ -2580,6 +2580,7 @@ static Modifications *mods_dup( Operation *op, Modifications *modlist, int match
|
|||
|
||||
typedef struct resolve_ctxt {
|
||||
syncinfo_t *rx_si;
|
||||
Entry *rx_entry;
|
||||
Modifications *rx_mods;
|
||||
} resolve_ctxt;
|
||||
|
||||
|
|
@ -2624,6 +2625,7 @@ syncrepl_resolve_cb( Operation *op, SlapReply *rs )
|
|||
Attribute *a = attr_find( rs->sr_entry->e_attrs, ad_reqMod );
|
||||
if ( a ) {
|
||||
Modifications *oldmods, *newmods, *m1, *m2, **prev;
|
||||
Entry *e = rx->rx_entry;
|
||||
oldmods = rx->rx_mods;
|
||||
syncrepl_accesslog_mods( rx->rx_si, a->a_vals, &newmods );
|
||||
for ( m2 = newmods; m2; m2=m2->sml_next ) {
|
||||
|
|
@ -2664,14 +2666,51 @@ drop:
|
|||
|
||||
if ( m2->sml_op == LDAP_MOD_ADD ||
|
||||
m2->sml_op == LDAP_MOD_REPLACE ) {
|
||||
if ( m1->sml_op == LDAP_MOD_DELETE ) {
|
||||
if ( !m1->sml_numvals ) goto drop;
|
||||
compare_vals( m1, m2 );
|
||||
if ( !m1->sml_numvals )
|
||||
goto drop;
|
||||
}
|
||||
if ( m2->sml_desc->ad_type->sat_atype.at_single_value )
|
||||
goto drop;
|
||||
if ( m1->sml_op == LDAP_MOD_DELETE ) {
|
||||
if ( m2->sml_op == LDAP_MOD_REPLACE ) {
|
||||
goto drop;
|
||||
}
|
||||
if ( !m1->sml_numvals ) {
|
||||
Modifications *m;
|
||||
unsigned int size, i;
|
||||
/*
|
||||
* ITS#9751 An ADD might supersede parts of
|
||||
* this delete, but we still need to honour the
|
||||
* rest. Keep resolving as if it was deleting
|
||||
* specific values
|
||||
*/
|
||||
a = attr_find( e->e_attrs, m1->sml_desc );
|
||||
if ( !a ) {
|
||||
goto drop;
|
||||
}
|
||||
|
||||
size = (a->a_numvals+1) * sizeof(struct berval);
|
||||
if ( a->a_nvals ) size *= 2;
|
||||
size += sizeof(Modifications);
|
||||
m = op->o_tmpalloc( size, op->o_tmpmemctx );
|
||||
*m = *m1;
|
||||
|
||||
m->sml_numvals = a->a_numvals;
|
||||
m->sml_values = (BerVarray)(m+1);
|
||||
|
||||
for ( i=0; i < a->a_numvals; i++ )
|
||||
m->sml_values[i] = a->a_vals[i];
|
||||
BER_BVZERO( &m->sml_values[i] );
|
||||
|
||||
if ( a->a_nvals ) {
|
||||
m->sml_nvalues = m->sml_values + m->sml_numvals + 1;
|
||||
for ( i=0; i < a->a_numvals; i++ )
|
||||
m->sml_nvalues[i] = a->a_nvals[i];
|
||||
BER_BVZERO( &m->sml_nvalues[i] );
|
||||
} else {
|
||||
m->sml_nvalues = NULL;
|
||||
}
|
||||
op->o_tmpfree( m1, op->o_tmpmemctx );
|
||||
*prev = m1 = m;
|
||||
}
|
||||
}
|
||||
compare_vals( m1, m2 );
|
||||
if ( !m1->sml_numvals )
|
||||
goto drop;
|
||||
|
|
@ -2689,6 +2728,7 @@ drop:
|
|||
typedef struct modify_ctxt {
|
||||
Modifications *mx_orig;
|
||||
Modifications *mx_free;
|
||||
Entry *mx_entry;
|
||||
} modify_ctxt;
|
||||
|
||||
static int
|
||||
|
|
@ -2704,6 +2744,9 @@ syncrepl_modify_cb( Operation *op, SlapReply *rs )
|
|||
mx->mx_free = ml->sml_next;
|
||||
op->o_tmpfree( ml, op->o_tmpmemctx );
|
||||
}
|
||||
if ( mx->mx_entry ) {
|
||||
entry_free( mx->mx_entry );
|
||||
}
|
||||
op->o_callback = sc->sc_next;
|
||||
op->o_tmpfree( sc, op->o_tmpmemctx );
|
||||
return SLAP_CB_CONTINUE;
|
||||
|
|
@ -2715,7 +2758,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
|||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
OpExtra *oex;
|
||||
syncinfo_t *si;
|
||||
Entry *e;
|
||||
Entry *e, *e_dup;
|
||||
int rc, match = 0;
|
||||
Modifications *mod, *newlist;
|
||||
|
||||
|
|
@ -2769,6 +2812,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
|||
/* no entryCSN? shouldn't happen. assume mod is newer. */
|
||||
match = 1;
|
||||
}
|
||||
e_dup = entry_dup( e );
|
||||
overlay_entry_release_ov( op, e, 0, on );
|
||||
} else {
|
||||
return SLAP_CB_CONTINUE;
|
||||
|
|
@ -2779,6 +2823,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
|||
slap_graduate_commit_csn( op );
|
||||
/* tell accesslog this was a failure */
|
||||
rs->sr_err = LDAP_TYPE_OR_VALUE_EXISTS;
|
||||
entry_free( e_dup );
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -2793,7 +2838,8 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
|||
* delete X delete all drop
|
||||
* delete X delete X drop
|
||||
* delete X delete Y OK
|
||||
* delete all add X drop
|
||||
* delete all add X convert to delete current values,
|
||||
* drop delete X from it
|
||||
* delete X add X drop
|
||||
* delete X add Y OK
|
||||
* add X delete all drop
|
||||
|
|
@ -2826,6 +2872,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
|||
AttributeAssertion aa[2] = {0};
|
||||
|
||||
rx.rx_si = si;
|
||||
rx.rx_entry = e_dup;
|
||||
rx.rx_mods = newlist;
|
||||
cb.sc_private = ℞
|
||||
|
||||
|
|
@ -2888,6 +2935,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
|||
op->orm_no_opattrs = 1;
|
||||
mx->mx_orig = op->orm_modlist;
|
||||
mx->mx_free = newlist;
|
||||
mx->mx_entry = e_dup;
|
||||
for ( ml = newlist; ml; ml=ml->sml_next ) {
|
||||
if ( ml->sml_flags == SLAP_MOD_INTERNAL ) {
|
||||
ml->sml_flags = 0;
|
||||
|
|
@ -2902,6 +2950,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
|
|||
op->orm_modlist = newlist;
|
||||
op->o_csn = mod->sml_nvalues[0];
|
||||
}
|
||||
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue