From 3a0037cc530d2883335498acd1a9a99c64d6d435 Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Thu, 12 Jun 2008 11:46:57 +0000 Subject: [PATCH] Experimental code for delete support in back-config. Only overlays supported currently. --- servers/slapd/backover.c | 37 +++++++++++++++++ servers/slapd/bconfig.c | 85 +++++++++++++++++++++++++++++++++++++- servers/slapd/proto-slap.h | 5 ++- 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/servers/slapd/backover.c b/servers/slapd/backover.c index b813b9b662..6855246ece 100644 --- a/servers/slapd/backover.c +++ b/servers/slapd/backover.c @@ -1081,6 +1081,43 @@ overlay_destroy_one( BackendDB *be, slap_overinst *on ) } } +#ifdef SLAP_CONFIG_DELETE +void +overlay_remove( BackendDB *be, slap_overinst *on ) +{ + slap_overinfo *oi = on->on_info; + slap_overinst **oidx, *on2; + + /* remove overlay from oi_list an call db_close and db_destroy + * handlers */ + for ( oidx = &oi->oi_list; *oidx; oidx = &(*oidx)->on_next ) { + if ( *oidx == on ) { + *oidx = on->on_next; + BackendInfo *bi_orig = be->bd_info; + be->bd_info = (BackendInfo *)on; + if ( on->on_bi.bi_db_close ) { + on->on_bi.bi_db_close( be, NULL ); + } + if ( on->on_bi.bi_db_destroy ) { + on->on_bi.bi_db_destroy( be, NULL ); + } + be->bd_info = bi_orig; + free( on ); + break; + } + } + + /* clean up after removing last overlay */ + if ( ! oi->oi_list ) + { + /* reset db flags and bd_info to orig */ + SLAP_DBFLAGS( be ) &= ~SLAP_DBFLAG_GLOBAL_OVERLAY; + be->bd_info = oi->oi_orig; + ch_free(oi); + } +} +#endif /* SLAP_CONFIG_DELETE */ + void overlay_insert( BackendDB *be, slap_overinst *on2, slap_overinst ***prev, int idx ) diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 882be198c8..0cc2707c1d 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -5225,7 +5225,90 @@ out: static int config_back_delete( Operation *op, SlapReply *rs ) { - send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, NULL ); +#ifdef SLAP_CONFIG_DELETE + CfBackInfo *cfb; + CfEntryInfo *ce, *last, *ce2; + + slap_mask_t mask; + + cfb = (CfBackInfo *)op->o_bd->be_private; + + ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last ); + if ( !ce ) { + if ( last ) + rs->sr_matched = last->ce_entry->e_name.bv_val; + rs->sr_err = LDAP_NO_SUCH_OBJECT; + } if ( ce->ce_kids ) { + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + } else if ( ce->ce_type == Cft_Overlay ){ + char *iptr; + int count, ixold, rc; + + ldap_pvt_thread_pool_pause( &connection_pool ); + + overlay_remove( ce->ce_be, (slap_overinst *)ce->ce_bi ); + + /* remove CfEntryInfo from the siblings list */ + if ( ce->ce_parent->ce_kids == ce ) { + ce->ce_parent->ce_kids = ce->ce_sibs; + } else { + for ( ce2 = ce->ce_parent->ce_kids ; ce2; ce2 = ce2->ce_sibs ) { + if ( ce2->ce_sibs == ce ) { + ce2->ce_sibs = ce->ce_sibs; + break; + } + } + } + + /* remove from underlying database */ + if ( cfb->cb_use_ldif ) { + BackendDB *be = op->o_bd; + slap_callback sc = { NULL, slap_null_cb, NULL, NULL }, *scp; + struct berval dn, ndn, req_dn, req_ndn; + + op->o_bd = &cfb->cb_db; + + dn = op->o_dn; + ndn = op->o_ndn; + req_dn = op->o_req_dn; + req_ndn = op->o_req_ndn; + + op->o_dn = op->o_bd->be_rootdn; + op->o_ndn = op->o_bd->be_rootndn; + op->o_req_dn = ce->ce_entry->e_name; + op->o_req_ndn = ce->ce_entry->e_nname; + + scp = op->o_callback; + op->o_callback = ≻ + op->o_bd->be_delete( op, rs ); + op->o_bd = be; + op->o_callback = scp; + op->o_dn = dn; + op->o_ndn = ndn; + op->o_req_dn = req_dn; + op->o_req_ndn = req_ndn; + } + + /* renumber siblings */ + iptr = ber_bvchr( &op->o_req_ndn, '{' ) + 1; + ixold = strtol( iptr, NULL, 0 ); + for (ce2 = ce->ce_sibs, count=0; ce2; ce2=ce2->ce_sibs) { + config_renumber_one( op, rs, ce2->ce_parent, ce2->ce_entry, + count+ixold, 0, cfb->cb_use_ldif ); + count++; + } + + ce->ce_entry->e_private=NULL; + entry_free(ce->ce_entry); + ch_free(ce); + ldap_pvt_thread_pool_resume( &connection_pool ); + } else { + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + } +#else + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; +#endif /* SLAP_CONFIG_DELETE */ + send_ldap_result( op, rs ); return rs->sr_err; } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 77cfac404b..db339ac0c0 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -469,7 +469,10 @@ LDAP_SLAPD_F (void) overlay_insert LDAP_P(( BackendDB *be, slap_overinst *on, slap_overinst ***prev, int idx )); LDAP_SLAPD_F (void) overlay_move LDAP_P(( BackendDB *be, slap_overinst *on, int idx )); - +#ifdef SLAP_CONFIG_DELETE +LDAP_SLAPD_F (void) overlay_remove LDAP_P(( + BackendDB *be, slap_overinst *on )); +#endif /* SLAP_CONFIG_DELETE */ /* * bconfig.c */ -- 2.39.5