X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-bdb%2Ftools.c;h=75e6e47e2b0ca22fbe052014b67f021797ab72a7;hb=59e9ff6243465640956b58ad1756a3ede53eca7c;hp=c0ce3a2cf80cb82f0947cff5826dd895cd880574;hpb=b814f859204cace4b19637f731fec984b68d1e1a;p=openldap diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c index c0ce3a2cf8..75e6e47e2b 100644 --- a/servers/slapd/back-bdb/tools.c +++ b/servers/slapd/back-bdb/tools.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2000-2014 The OpenLDAP Foundation. + * Copyright 2000-2018 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -841,6 +841,11 @@ int bdb_tool_entry_reindex( return -1; } + op.o_hdr = &ohdr; + op.o_bd = be; + op.o_tmpmemctx = NULL; + op.o_tmpmfuncs = &ch_mfuncs; + if (! (slapMode & SLAP_TOOL_QUICK)) { rc = TXN_BEGIN( bi->bi_dbenv, NULL, &tid, bi->bi_db_opflags ); if( rc != 0 ) { @@ -865,11 +870,6 @@ int bdb_tool_entry_reindex( "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld, \"%s\" )\n", (long) id, e->e_dn, 0 ); - op.o_hdr = &ohdr; - op.o_bd = be; - op.o_tmpmemctx = NULL; - op.o_tmpmfuncs = &ch_mfuncs; - rc = bdb_tool_index_add( &op, tid, e ); done: @@ -1003,6 +1003,171 @@ done: return e->e_id; } +int bdb_tool_entry_delete( + BackendDB *be, + struct berval *ndn, + struct berval *text ) +{ + int rc; + struct bdb_info *bdb; + DB_TXN *tid = NULL; + Operation op = {0}; + Opheader ohdr = {0}; + EntryInfo *ei, *eip; + Entry *e; + DB_LOCK lock; + + assert( be != NULL ); + assert( slapMode & SLAP_TOOL_MODE ); + + assert( text != NULL ); + assert( text->bv_val != NULL ); + assert( text->bv_val[0] == '\0' ); /* overconservative? */ + + assert ( ndn != NULL ); + assert ( ndn->bv_val != NULL ); + + Debug( LDAP_DEBUG_TRACE, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) "( %s )\n", + ndn->bv_val, 0, 0 ); + + bdb = (struct bdb_info *) be->be_private; + + if (! (slapMode & SLAP_TOOL_QUICK)) { + if( cursor ) { + cursor->c_close( cursor ); + cursor = NULL; + } + rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, + bdb->bi_db_opflags ); + if( rc != 0 ) { + snprintf( text->bv_val, text->bv_len, + "txn_begin failed: %s (%d)", + db_strerror(rc), rc ); + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) ": %s\n", + text->bv_val, 0, 0 ); + return LDAP_OTHER; + } + rc = bdb->bi_id2entry->bdi_db->cursor( + bdb->bi_id2entry->bdi_db, bdb->bi_cache.c_txn, &cursor, + bdb->bi_db_opflags ); + } + + op.o_hdr = &ohdr; + op.o_bd = be; + op.o_tmpmemctx = NULL; + op.o_tmpmfuncs = &ch_mfuncs; + + /* do the deletion */ + rc = bdb_dn2entry( &op, tid, ndn, &ei, 1, &lock ); + if( rc != 0 ) { + snprintf( text->bv_val, text->bv_len, + "dn2entry failed: %s (%d)", + db_strerror(rc), rc ); + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) ": %s\n", + text->bv_val, 0, 0 ); + goto done; + } + + e = ei->bei_e; + eip = ei->bei_parent; + + rc = bdb_cache_children( &op, tid, e ); + if( rc != DB_NOTFOUND ) { + switch( rc ) { + case 0: + snprintf( text->bv_val, text->bv_len, + "delete failed:" + " subordinate objects must be deleted first"); + break; + default: + snprintf( text->bv_val, text->bv_len, + "has_children failed: %s (%d)", + db_strerror(rc), rc ); + break; + } + rc = -1; + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(mdb_tool_entry_delete) ": %s\n", + text->bv_val, 0, 0 ); + goto done; + } + rc = bdb_dn2id_delete( &op, tid, eip, e ); + if( rc != 0 ) { + snprintf( text->bv_val, text->bv_len, + "dn2entry failed: %s (%d)", + db_strerror(rc), rc ); + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) ": %s\n", + text->bv_val, 0, 0 ); + goto done; + } + + rc = bdb_index_entry_del( &op, tid, e ); + if( rc != 0 ) { + snprintf( text->bv_val, text->bv_len, + "dn2entry failed: %s (%d)", + db_strerror(rc), rc ); + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) ": %s\n", + text->bv_val, 0, 0 ); + goto done; + } + + rc = bdb_id2entry_delete( be, tid, e ); + if( rc != 0 ) { + snprintf( text->bv_val, text->bv_len, + "dn2entry failed: %s (%d)", + db_strerror(rc), rc ); + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) ": %s\n", + text->bv_val, 0, 0 ); + goto done; + } + +done: + /* Free the EntryInfo and the Entry */ + if( e != NULL ) { + bdb_entry_release( &op, e, 0 ); + } + + if( rc == 0 ) { + if (! (slapMode & SLAP_TOOL_QUICK)) { + rc = TXN_COMMIT( tid, 0 ); + if( rc != 0 ) { + snprintf( text->bv_val, text->bv_len, + "txn_commit failed: %s (%d)", + db_strerror(rc), rc ); + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) ": " + "%s\n", text->bv_val, 0, 0 ); + } + } + + } else { + if (! (slapMode & SLAP_TOOL_QUICK)) { + TXN_ABORT( tid ); + snprintf( text->bv_val, text->bv_len, + "txn_aborted! %s (%d)", + db_strerror(rc), rc ); + Debug( LDAP_DEBUG_ANY, + "=> " LDAP_XSTRING(bdb_tool_entry_delete) ": %s\n", + text->bv_val, 0, 0 ); + } + } + + if ( cursor == NULL ) + { + rc = bdb->bi_id2entry->bdi_db->cursor( + bdb->bi_id2entry->bdi_db, bdb->bi_cache.c_txn, &cursor, + bdb->bi_db_opflags ); + } + + return rc; +} + #ifdef BDB_TOOL_IDL_CACHING static int bdb_tool_idl_cmp( const void *v1, const void *v2 )