Modifications *ml;
Attribute *save_attrs;
Attribute *ap;
+ int glue_attr_delete = 0;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "bdb_modify_internal: 0x%08lx: %s\n",
save_attrs = e->e_attrs;
e->e_attrs = attrs_dup( e->e_attrs );
+ for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
+ mod = &ml->sml_mod;
+ switch( mod->sm_op ) {
+ case LDAP_MOD_ADD:
+ case LDAP_MOD_REPLACE:
+ if ( mod->sm_desc == slap_schema.si_ad_structuralObjectClass ) {
+ /* sc modify is internally allowed only to make an entry a glue */
+ glue_attr_delete = 1;
+ }
+ }
+ if ( glue_attr_delete )
+ break;
+ }
+
+ if ( glue_attr_delete ) {
+ Attribute **app = &e->e_attrs;
+ while ( *app != NULL ) {
+ if ( !is_at_operational( (*app)->a_desc->ad_type )) {
+ Attribute *save = *app;
+ *app = (*app)->a_next;
+ attr_free( save );
+ continue;
+ }
+ app = &(*app)->a_next;
+ }
+ }
+
for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
mod = &ml->sml_mod;
break;
case LDAP_MOD_DELETE:
+ if ( glue_attr_delete )
+ break;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, DETAIL1,
"bdb_modify_internal: delete\n", 0, 0, 0 );
e->e_ocflags = 0;
}
+ if ( glue_attr_delete ) {
+ e->e_ocflags = 0;
+ }
+
/* check if modified attribute was indexed
* but not in case of NOOP... */
err = bdb_index_is_indexed( op->o_bd, mod->sm_desc );
int rc, err, i;
ber_len_t len;
- int rc_efree;
+ int rc_efree = 1;
struct berval *psub;
Modifications *modlist = NULL;
syncCookie.octet_str[0].bv_val )
slap_parse_sync_cookie( &syncCookie );
}
- entry = syncrepl_message_to_entry( si, op, msg,
- &modlist, syncstate );
- rc_efree = syncrepl_entry( si, op, entry, modlist, syncstate,
- &syncUUID, &syncCookie_req );
- if ( syncCookie.octet_str && syncCookie.octet_str[0].bv_val ) {
- syncrepl_updateCookie( si, op, psub, &syncCookie );
+ if ( syncrepl_message_to_entry( si, op, msg,
+ &modlist, &entry, syncstate ) == LDAP_SUCCESS ) {
+ rc_efree = syncrepl_entry( si, op, entry, modlist,
+ syncstate, &syncUUID, &syncCookie_req );
+ if ( syncCookie.octet_str &&
+ syncCookie.octet_str[0].bv_val ) {
+ syncrepl_updateCookie( si, op, psub, &syncCookie );
+ }
}
ldap_controls_free( rctrls );
if ( modlist ) {
&syncCookie_req.ctxcsn[0], &syncCookie.ctxcsn[0], &text );
}
if ( syncCookie.octet_str && syncCookie.octet_str->bv_val
- && match < 0 ) {
+ && match < 0 && err == LDAP_SUCCESS ) {
syncrepl_updateCookie( si, op, psub, &syncCookie );
}
if ( rctrls ) {
* 1) err code : LDAP_BUSY ...
* 2) on err policy : stop service, stop sync, retry
*/
- if ( refreshDeletes == 0 && match < 0 ) {
+ if ( refreshDeletes == 0 && match < 0 &&
+ err == LDAP_SUCCESS ) {
syncrepl_del_nonpresent( op, si );
} else {
avl_free( si->si_presentlist, avl_ber_bvfree );
return NULL;
}
-Entry*
+int
syncrepl_message_to_entry(
syncinfo_t *si,
Operation *op,
LDAPMessage *msg,
Modifications **modlist,
+ Entry **entry,
int syncstate
)
{
Debug( LDAP_DEBUG_ANY,
"Message type should be entry (%d)", ldap_msgtype( msg ), 0, 0 );
#endif
- return NULL;
+ return -1;
}
op->o_tag = LDAP_REQ_ADD;
Debug( LDAP_DEBUG_ANY,
"syncrepl_message_to_entry : dn get failed (%d)", rc, 0, 0 );
#endif
- return NULL;
+ return rc;
}
dnPrettyNormal( NULL, &bdn, &dn, &ndn, op->o_tmpmemctx );
if ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_DELETE )
{
- return NULL;
+ return LDAP_SUCCESS;
+ }
+
+ if ( entry == NULL ) {
+ return -1;
}
e = ( Entry * ) ch_calloc( 1, sizeof( Entry ) );
+ *entry = e;
e->e_name = op->o_req_dn;
e->e_nname = op->o_req_ndn;
e = NULL;
}
- return e;
+ return rc;
}
int
return ret;
}
+static struct berval gcbva[] = {
+ BER_BVC("top"),
+ BER_BVC("glue"),
+ BER_BVNULL
+};
+
static void
syncrepl_del_nonpresent(
Operation *op,
slap_callback cb = { NULL };
SlapReply rs = {REP_RESULT};
struct nonpresent_entry *np_list, *np_prev;
+ int rc;
+ Modifications *ml;
+ Modifications *mlnext;
+ Modifications *mod;
+ Modifications *modlist = NULL;
+ Modifications **modtail = &modlist;
+ Attribute *attr;
op->o_req_dn = si->si_base;
op->o_req_ndn = si->si_base;
op->ors_filterstr = si->si_filterstr;
op->o_nocaching = 1;
+ op->o_managedsait = 0;
be->be_search( op, &rs );
+ op->o_managedsait = 1;
op->o_nocaching = 0;
if ( op->ors_filter ) filter_free_x( op, op->ors_filter );
cb.sc_private = si;
op->o_req_dn = *np_prev->npe_name;
op->o_req_ndn = *np_prev->npe_nname;
- op->o_bd->be_delete( op, &rs );
+ rc = op->o_bd->be_delete( op, &rs );
+
+ if ( rc == LDAP_NOT_ALLOWED_ON_NONLEAF ) {
+ mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ));
+ mod->sml_op = LDAP_MOD_REPLACE;
+ mod->sml_desc = slap_schema.si_ad_objectClass;
+ mod->sml_type = mod->sml_desc->ad_cname;
+ mod->sml_bvalues = &gcbva[0];
+ *modtail = mod;
+ modtail = &mod->sml_next;
+
+ mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ));
+ mod->sml_op = LDAP_MOD_REPLACE;
+ mod->sml_desc = slap_schema.si_ad_structuralObjectClass;
+ mod->sml_type = mod->sml_desc->ad_cname;
+ mod->sml_bvalues = &gcbva[1];
+ *modtail = mod;
+ modtail = &mod->sml_next;
+
+ op->o_tag = LDAP_REQ_MODIFY;
+ op->orm_modlist = modlist;
+
+ rc = be->be_modify( op, &rs );
+
+ for ( ml = modlist; ml != NULL; ml = mlnext ) {
+ mlnext = ml->sml_next;
+ free( ml );
+ }
+ }
+
ber_bvfree( np_prev->npe_name );
ber_bvfree( np_prev->npe_nname );
op->o_req_dn.bv_val = NULL;
}
-static struct berval gcbva[] = {
- BER_BVC("top"),
- BER_BVC("glue")
-};
-
void
syncrepl_add_glue(
Operation* op,
a->a_vals = ch_calloc( 3, sizeof( struct berval ));
ber_dupbv( &a->a_vals[0], &gcbva[0] );
ber_dupbv( &a->a_vals[1], &gcbva[1] );
- a->a_vals[2].bv_len = 0;
- a->a_vals[2].bv_val = NULL;
+ ber_dupbv( &a->a_vals[2], &gcbva[2] );
a->a_nvals = a->a_vals;
a->a_vals = ch_calloc( 2, sizeof( struct berval ));
ber_dupbv( &a->a_vals[0], &gcbva[1] );
- a->a_vals[1].bv_len = 0;
- a->a_vals[1].bv_val = NULL;
+ ber_dupbv( &a->a_vals[1], &gcbva[2] );
a->a_nvals = a->a_vals;