]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/dn2id.c
Fix slapadd crash when only a subset of databases have been initialized.
[openldap] / servers / slapd / back-bdb / dn2id.c
index 007c18866fbc7c4a9e5fbaee816d9b0dc32d9214..71ff928a9ad4d7ea61e0b7e3a910ab4eec88ee2f 100644 (file)
 #include <ac/string.h>
 
 #include "back-bdb.h"
+#include "idl.h"
 
 int
 bdb_dn2id_add(
-    Backend    *be,
+       BackendDB       *be,
        DB_TXN *txn,
-    const char *dn,
-    ID         id
-)
+       const char      *dn,
+       ID              id )
 {
        int             rc;
        DBT             key, data;
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
        DB *db = bdb->bi_dn2id->bdi_db;
 
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
+       Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_add( \"%s\", 0x%08lx )\n",
+               dn, id, 0 );
        assert( id != NOID );
 
        DBTzero( &key );
@@ -41,6 +42,8 @@ bdb_dn2id_add(
        /* store it -- don't override */
        rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );
        if( rc != 0 ) {
+               Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_add: put failed: %s %d\n",
+                       db_strerror(rc), rc, 0 );
                goto done;
        }
 
@@ -54,11 +57,15 @@ bdb_dn2id_add(
                                pdn, key.size - 1 );
 
                        rc = bdb_idl_insert_key( be, db, txn, &key, id );
-                       free( pdn );
 
                        if( rc != 0 ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "=> bdb_dn2id_add: parent (%s) insert failed: %d\n",
+                                       pdn, rc, 0 );
+                               free( pdn );
                                goto done;
                        }
+                       free( pdn );
                }
        }
 
@@ -76,7 +83,10 @@ bdb_dn2id_add(
                                rc = bdb_idl_insert_key( be, db, txn, &key, id );
 
                                if( rc != 0 ) {
-                                       goto done;
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "=> bdb_dn2id_add: subtree (%s) insert failed: %d\n",
+                                               subtree[i], rc, 0 );
+                                       break;
                                }
                        }
 
@@ -86,23 +96,24 @@ bdb_dn2id_add(
 
 done:
        ch_free( key.data );
-       Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_add %d\n", rc, 0, 0 );
+       Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_add: %d\n", rc, 0, 0 );
        return rc;
 }
 
 int
 bdb_dn2id_delete(
-    Backend    *be,
+       BackendDB       *be,
        DB_TXN *txn,
-    const char *dn,
-    ID         id )
+       const char      *dn,
+       ID              id )
 {
        int             rc;
        DBT             key;
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
        DB *db = bdb->bi_dn2id->bdi_db;
 
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_delete( \"%s\", %ld )\n", dn, id, 0 );
+       Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_delete( \"%s\", 0x%08lx )\n",
+               dn, id, 0 );
 
        DBTzero( &key );
        key.size = strlen( dn ) + 2;
@@ -113,6 +124,8 @@ bdb_dn2id_delete(
        /* store it -- don't override */
        rc = db->del( db, txn, &key, 0 );
        if( rc != 0 ) {
+               Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_delete: delete failed: %s %d\n",
+                       db_strerror(rc), rc, 0 );
                goto done;
        }
 
@@ -126,11 +139,15 @@ bdb_dn2id_delete(
                                pdn, key.size - 1 );
 
                        rc = bdb_idl_delete_key( be, db, txn, &key, id );
-                       free( pdn );
 
                        if( rc != 0 ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "=> bdb_dn2id_delete: parent (%s) delete failed: %d\n",
+                                       pdn, rc, 0 );
+                               free( pdn );
                                goto done;
                        }
+                       free( pdn );
                }
        }
 
@@ -148,6 +165,10 @@ bdb_dn2id_delete(
                                rc = bdb_idl_delete_key( be, db, txn, &key, id );
 
                                if( rc != 0 ) {
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "=> bdb_dn2id_delete: subtree (%s) delete failed: %d\n",
+                                               subtree[i], rc, 0 );
+                                       charray_free( subtree );
                                        goto done;
                                }
                        }
@@ -164,9 +185,9 @@ done:
 
 int
 bdb_dn2id(
-    Backend    *be,
+       BackendDB       *be,
        DB_TXN *txn,
-    const char *dn,
+       const char      *dn,
        ID *id )
 {
        int             rc;
@@ -191,8 +212,13 @@ bdb_dn2id(
        /* fetch it */
        rc = db->get( db, txn, &key, &data, 0 );
 
-       Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: id=%ld: %s (%d)\n",
-               id, db_strerror( rc ), rc );
+       if( rc != 0 ) {
+               Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: get failed: %s (%d)\n",
+                       db_strerror( rc ), rc, 0 );
+       } else {
+               Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: got id=0x%08lx\n",
+                       *id, 0, 0 );
+       }
 
        ch_free( key.data );
        return rc;
@@ -200,9 +226,9 @@ bdb_dn2id(
 
 int
 bdb_dn2id_matched(
-    Backend    *be,
+       BackendDB       *be,
        DB_TXN *txn,
-    const char *in,
+       const char      *in,
        ID *id,
        char **matchedDN )
 {
@@ -231,6 +257,8 @@ bdb_dn2id_matched(
        while(1) {
                AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
 
+               *id = NOID;
+
                /* fetch it */
                rc = db->get( db, txn, &key, &data, 0 );
 
@@ -240,6 +268,9 @@ bdb_dn2id_matched(
                        tmp = NULL;
 
                        if( pdn == NULL || *pdn == '\0' ) {
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "<= bdb_dn2id_matched: no match\n",
+                                       0, 0, 0 );
                                ch_free( pdn );
                                break;
                        }
@@ -249,15 +280,27 @@ bdb_dn2id_matched(
                        key.size = strlen( dn ) + 2;
 
                } else if ( rc == 0 ) {
+                       if( data.size != sizeof( ID ) ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "<= bdb_dn2id_matched: get size mismatch: "
+                                       "expected %ld, got %ld\n",
+                                       (long) sizeof(ID), (long) data.size, 0 );
+                               ch_free( tmp );
+                       }
+
                        if( in != dn ) {
                                *matchedDN = (char *) dn;
                        }
+
                        Debug( LDAP_DEBUG_TRACE,
-                               "<= bdb_dn2id_matched: id=%ld: %s\n",
-                               id, dn, 0 );
+                               "<= bdb_dn2id_matched: id=0x%08lx: %s %s\n",
+                               *id, *matchedDN == NULL ? "entry" : "matched", dn );
                        break;
 
                } else {
+                       Debug( LDAP_DEBUG_ANY,
+                               "<= bdb_dn2id_matched: get failed: %s (%d)\n",
+                               db_strerror(rc), rc, 0 );
                        ch_free( tmp );
                        break;
                }
@@ -269,9 +312,9 @@ bdb_dn2id_matched(
 
 int
 bdb_dn2id_children(
-    Backend    *be,
+       BackendDB       *be,
        DB_TXN *txn,
-    const char *dn )
+       const char *dn )
 {
        int             rc;
        DBT             key, data;
@@ -298,10 +341,54 @@ bdb_dn2id_children(
 
        rc = db->get( db, txn, &key, &data, 0 );
 
-       Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children( %s ): %s (%d)\n",
+       Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children( %s ): %schildren (%d)\n",
                dn,
-               rc == 0 ? "yes" : ( rc == DB_NOTFOUND ? "no" :
+               rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " :
                        db_strerror(rc) ), rc );
 
        return rc;
 }
+
+int
+bdb_dn2idl(
+       BackendDB       *be,
+       const char      *dn,
+       int prefix,
+       ID *ids )
+{
+       int             rc;
+       DBT             key, data;
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+       DB *db = bdb->bi_dn2id->bdi_db;
+
+       Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2idl( \"%s\" )\n", dn, 0, 0 );
+
+       DBTzero( &key );
+       key.size = strlen( dn ) + 2;
+       key.data = ch_malloc( key.size );
+       ((char *)key.data)[0] = prefix;
+       AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
+
+       /* store the ID */
+       DBTzero( &data );
+       data.data = ids;
+       data.ulen = sizeof(ID);
+       data.flags = DB_DBT_USERMEM;
+
+       /* fetch it */
+       rc = db->get( db, NULL, &key, &data, 0 );
+
+       if( rc != 0 ) {
+               Debug( LDAP_DEBUG_TRACE,
+                       "<= bdb_dn2idl: get failed: %s (%d)\n",
+                       db_strerror( rc ), rc, 0 );
+       } else {
+               Debug( LDAP_DEBUG_TRACE,
+                       "<= bdb_dn2idl: id=%ld first=%ld last=%ld\n",
+                       ids[0], BDB_IDL_FIRST( ids ), BDB_IDL_LAST( ids ) );
+       }
+
+       ch_free( key.data );
+       return rc;
+}
+