]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/tools.c
Happy New Year
[openldap] / servers / slapd / back-bdb / tools.c
index e41782acf9a134e713572b7fd93f5e48e87fb421..75e6e47e2b0ca22fbe052014b67f021797ab72a7 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2000-2013 The OpenLDAP Foundation.
+ * Copyright 2000-2018 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -747,6 +747,15 @@ done:
                e->e_id = NOID;
        }
 
+       if ( cursor == NULL )
+       {
+               int rc = bdb->bi_id2entry->bdi_db->cursor(
+                       bdb->bi_id2entry->bdi_db, bdb->bi_cache.c_txn, &cursor,
+                       bdb->bi_db_opflags );
+               if ( rc != 0 )
+                       e->e_id = NOID;
+       }
+
        return e->e_id;
 }
 
@@ -832,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 ) {
@@ -856,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:
@@ -982,9 +991,183 @@ done:
                e->e_id = NOID;
        }
 
+       if ( cursor == NULL )
+       {
+               int rc = bdb->bi_id2entry->bdi_db->cursor(
+                       bdb->bi_id2entry->bdi_db, bdb->bi_cache.c_txn, &cursor,
+                       bdb->bi_db_opflags );
+               if ( rc != 0 )
+                       e->e_id = NOID;
+       }
+
        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 )