]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9010 - Delete back-bdb/back-hdb
authorQuanah Gibson-Mount <quanah@openldap.org>
Fri, 3 May 2019 22:52:59 +0000 (22:52 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Mon, 13 May 2019 17:20:28 +0000 (17:20 +0000)
This commits deletes all references and code for back-bdb and back-hdb.
There is some follow up work still necessary to flush out the admin
guide for back-mdb.

101 files changed:
.gitignore
INSTALL
build/openldap.m4
build/top.mk
configure.in
contrib/slapd-modules/allowed/allowed.c
contrib/slapd-modules/nssov/README
contrib/slapd-modules/nssov/slapo-nssov.5
doc/guide/admin/appendix-changes.sdf
doc/guide/admin/appendix-common-errors.sdf
doc/guide/admin/aspell.en.pws
doc/guide/admin/backends.sdf
doc/guide/admin/install.sdf
doc/guide/admin/intro.sdf
doc/guide/admin/maintenance.sdf
doc/guide/admin/monitoringslapd.sdf
doc/guide/admin/overlays.sdf
doc/guide/admin/replication.sdf
doc/guide/admin/slapdconf2.sdf
doc/guide/admin/slapdconfig.sdf
doc/guide/admin/tuning.sdf
doc/guide/preamble.sdf
doc/guide/release/install.sdf
doc/man/man5/slapd-bdb.5 [deleted file]
doc/man/man5/slapd-bdb.5.links [deleted file]
doc/man/man5/slapd-config.5
doc/man/man5/slapd-mdb.5
doc/man/man5/slapd-sql.5
doc/man/man5/slapd.access.5
doc/man/man5/slapd.backends.5
doc/man/man5/slapd.conf.5
doc/man/man5/slapd.overlays.5
doc/man/man5/slapo-refint.5
doc/man/man5/slapo-translucent.5
doc/man/man8/slapcat.8
doc/man/man8/slapschema.8
include/portable.hin
servers/slapd/DB_CONFIG [deleted file]
servers/slapd/Makefile.in
servers/slapd/alock.c [deleted file]
servers/slapd/alock.h [deleted file]
servers/slapd/back-bdb/Makefile.in [deleted file]
servers/slapd/back-bdb/add.c [deleted file]
servers/slapd/back-bdb/attr.c [deleted file]
servers/slapd/back-bdb/back-bdb.h [deleted file]
servers/slapd/back-bdb/bind.c [deleted file]
servers/slapd/back-bdb/cache.c [deleted file]
servers/slapd/back-bdb/compare.c [deleted file]
servers/slapd/back-bdb/config.c [deleted file]
servers/slapd/back-bdb/dbcache.c [deleted file]
servers/slapd/back-bdb/delete.c [deleted file]
servers/slapd/back-bdb/dn2entry.c [deleted file]
servers/slapd/back-bdb/dn2id.c [deleted file]
servers/slapd/back-bdb/error.c [deleted file]
servers/slapd/back-bdb/extended.c [deleted file]
servers/slapd/back-bdb/filterindex.c [deleted file]
servers/slapd/back-bdb/id2entry.c [deleted file]
servers/slapd/back-bdb/idl.c [deleted file]
servers/slapd/back-bdb/idl.h [deleted file]
servers/slapd/back-bdb/index.c [deleted file]
servers/slapd/back-bdb/init.c [deleted file]
servers/slapd/back-bdb/key.c [deleted file]
servers/slapd/back-bdb/modify.c [deleted file]
servers/slapd/back-bdb/modrdn.c [deleted file]
servers/slapd/back-bdb/monitor.c [deleted file]
servers/slapd/back-bdb/nextid.c [deleted file]
servers/slapd/back-bdb/operational.c [deleted file]
servers/slapd/back-bdb/proto-bdb.h [deleted file]
servers/slapd/back-bdb/referral.c [deleted file]
servers/slapd/back-bdb/search.c [deleted file]
servers/slapd/back-bdb/tools.c [deleted file]
servers/slapd/back-bdb/trans.c [deleted file]
servers/slapd/back-hdb/Makefile.in [deleted file]
servers/slapd/back-hdb/back-bdb.h [deleted file]
servers/slapd/back-ldif/ldif.c
servers/slapd/back-monitor/init.c
servers/slapd/bconfig.c
servers/slapd/dn.c
servers/slapd/overlays/pcache.c
servers/slapd/slap.h
servers/slapd/slapd.ldif
tests/Makefile.in
tests/README
tests/data/regressions/its4184/its4184
tests/data/regressions/its4448/its4448
tests/data/slapd-proxyauthz.conf
tests/data/slapd-proxycache.conf
tests/data/slapd-ref-slave.conf
tests/data/slapd.conf
tests/run.in
tests/scripts/test023-refint
tests/scripts/test025-limits
tests/scripts/test036-meta-concurrency
tests/scripts/test040-subtree-rename
tests/scripts/test043-delta-syncrepl
tests/scripts/test052-memberof
tests/scripts/test053-syncprov-glue
tests/scripts/test056-monitor
tests/scripts/test057-memberof-refint
tests/scripts/test061-syncreplication-initiation
tests/scripts/test074-asyncmeta-concurrency

index f8a0716104469207cdc9b78667134d28e996a89d..e60a6c51845f00c57f9be8c262dc0019d7603cd2 100644 (file)
@@ -152,33 +152,6 @@ libraries/librewrite/rewrite
 libraries/librewrite/version.c
 servers/slapd/.backend
 servers/slapd/all-cffiles
-servers/slapd/back-hdb/add.c
-servers/slapd/back-hdb/attr.c
-servers/slapd/back-hdb/bind.c
-servers/slapd/back-hdb/cache.c
-servers/slapd/back-hdb/compare.c
-servers/slapd/back-hdb/config.c
-servers/slapd/back-hdb/dbcache.c
-servers/slapd/back-hdb/delete.c
-servers/slapd/back-hdb/dn2entry.c
-servers/slapd/back-hdb/dn2id.c
-servers/slapd/back-hdb/error.c
-servers/slapd/back-hdb/extended.c
-servers/slapd/back-hdb/filterindex.c
-servers/slapd/back-hdb/id2entry.c
-servers/slapd/back-hdb/idl.c
-servers/slapd/back-hdb/index.c
-servers/slapd/back-hdb/init.c
-servers/slapd/back-hdb/key.c
-servers/slapd/back-hdb/modify.c
-servers/slapd/back-hdb/modrdn.c
-servers/slapd/back-hdb/monitor.c
-servers/slapd/back-hdb/nextid.c
-servers/slapd/back-hdb/operational.c
-servers/slapd/back-hdb/referral.c
-servers/slapd/back-hdb/search.c
-servers/slapd/back-hdb/tools.c
-servers/slapd/back-hdb/trans.c
 servers/slapd/backends.c
 servers/slapd/overlays/statover.c
 servers/slapd/slapacl
diff --git a/INSTALL b/INSTALL
index a2b57fd094e00bdd87ce42ac550754a132ea01b6..f4f21bb413df33c4de44975c8b860ac4abb7666c 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -73,9 +73,6 @@ Making and Installing the OpenLDAP Distribution
 
 6.   Test the standalone system:
 
-     This step requires the standalone LDAP server, slapd(8), with HDB
-     and/or BDB support.
-
         % make test
 
      If all goes well, the system has been built as configured.  If
index e8b763466d9d4481793b17130d3f38d661b8984e..276ba2a3e258d3852ac10b6187c180b3f323345e 100644 (file)
@@ -270,298 +270,6 @@ if test $ac_cv_header_unicode_utypes_h = yes ; then
        fi
 fi
 ])
-dnl
-dnl ====================================================================
-dnl Berkeley DB macros
-dnl
-dnl --------------------------------------------------------------------
-dnl Try to link
-AC_DEFUN([OL_BERKELEY_DB_TRY],
-[if test $ol_cv_lib_db = no ; then
-       AC_CACHE_CHECK([for Berkeley DB link (]ifelse($2,,default,$2)[)],[$1],
-[
-       ol_DB_LIB=ifelse($2,,,$2)
-       ol_LIBS=$LIBS
-       LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
-
-       AC_LINK_IFELSE([AC_LANG_PROGRAM([[
-#ifdef HAVE_DB_185_H
-# include <db_185.h>
-#else
-# include <db.h>
-#endif
-
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-]], [[
-#if DB_VERSION_MAJOR > 2
-       db_env_create( NULL, 0 );
-#elif DB_VERSION_MAJOR > 1
-       db_appexit( NULL );
-#else
-       (void) dbopen( NULL, 0, 0, 0, NULL);
-#endif
-]])],[$1=yes],[$1=no])
-
-       LIBS="$ol_LIBS"
-])
-
-       if test $$1 = yes ; then
-               ol_cv_lib_db=ifelse($2,,yes,$2)
-       fi
-fi
-])
-dnl
-dnl --------------------------------------------------------------------
-dnl Get major and minor version from <db.h>
-AC_DEFUN([OL_BDB_HEADER_VERSION],
-[AC_CACHE_CHECK([for Berkeley DB major version in db.h], [ol_cv_bdb_major],[
-       AC_LANG_CONFTEST([AC_LANG_SOURCE([
-#include <db.h>
-#ifndef DB_VERSION_MAJOR
-#      define DB_VERSION_MAJOR 1
-#endif
-__db_version DB_VERSION_MAJOR
-])])
-       set X `eval "$ac_cpp -P conftest.$ac_ext" | $EGREP __db_version` none none
-       ol_cv_bdb_major=${3}
-])
-case $ol_cv_bdb_major in [[1-9]]*) : ;; *)
-       AC_MSG_ERROR([Unknown Berkeley DB major version in db.h]) ;;
-esac
-
-dnl Determine minor version
-AC_CACHE_CHECK([for Berkeley DB minor version in db.h], [ol_cv_bdb_minor],[
-       AC_LANG_CONFTEST([AC_LANG_SOURCE([
-#include <db.h>
-#ifndef DB_VERSION_MINOR
-#      define DB_VERSION_MINOR 0
-#endif
-__db_version DB_VERSION_MINOR
-])])
-       set X `eval "$ac_cpp -P conftest.$ac_ext" | $EGREP __db_version` none none
-       ol_cv_bdb_minor=${3}
-])
-case $ol_cv_bdb_minor in [[0-9]]*) : ;; *)
-       AC_MSG_ERROR([Unknown Berkeley DB minor version in db.h]) ;;
-esac
-])
-dnl
-dnl --------------------------------------------------------------------
-dnl Try to locate appropriate library
-AC_DEFUN([OL_BERKELEY_DB_LINK],
-[ol_cv_lib_db=no
-
-if test $ol_cv_bdb_major = 5 ; then
-       OL_BERKELEY_DB_TRY(ol_cv_db_db_5_dot_m,[-ldb-5.$ol_cv_bdb_minor])
-       OL_BERKELEY_DB_TRY(ol_cv_db_db5m,[-ldb5$ol_cv_bdb_minor])
-       OL_BERKELEY_DB_TRY(ol_cv_db_db_5m,[-ldb-5$ol_cv_bdb_minor])
-       OL_BERKELEY_DB_TRY(ol_cv_db_db_5_m,[-ldb-5-$ol_cv_bdb_minor])
-       OL_BERKELEY_DB_TRY(ol_cv_db_db_5,[-ldb-5])
-       OL_BERKELEY_DB_TRY(ol_cv_db_db5,[-ldb5])
-elif test $ol_cv_bdb_major = 4 ; then
-       OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_m,[-ldb-4.$ol_cv_bdb_minor])
-       OL_BERKELEY_DB_TRY(ol_cv_db_db4m,[-ldb4$ol_cv_bdb_minor])
-       OL_BERKELEY_DB_TRY(ol_cv_db_db_4m,[-ldb-4$ol_cv_bdb_minor])
-       OL_BERKELEY_DB_TRY(ol_cv_db_db_4_m,[-ldb-4-$ol_cv_bdb_minor])
-       OL_BERKELEY_DB_TRY(ol_cv_db_db_4,[-ldb-4])
-       OL_BERKELEY_DB_TRY(ol_cv_db_db4,[-ldb4])
-fi
-OL_BERKELEY_DB_TRY(ol_cv_db_db,[-ldb])
-OL_BERKELEY_DB_TRY(ol_cv_db_none)
-])
-dnl
-dnl --------------------------------------------------------------------
-dnl Check if Berkeley DB version
-AC_DEFUN([OL_BERKELEY_DB_VERSION],
-[AC_CACHE_CHECK([for Berkeley DB library and header version match], [ol_cv_berkeley_db_version], [
-       ol_LIBS="$LIBS"
-       LIBS="$LTHREAD_LIBS $LIBS"
-       if test $ol_cv_lib_db != yes ; then
-               LIBS="$ol_cv_lib_db $LIBS"
-       fi
-
-       AC_RUN_IFELSE([AC_LANG_SOURCE([[
-#ifdef HAVE_DB_185_H
-       choke me;
-#else
-#include <db.h>
-#endif
-#ifndef DB_VERSION_MAJOR
-# define DB_VERSION_MAJOR 1
-#endif
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-main()
-{
-#if DB_VERSION_MAJOR > 1
-       char *version;
-       int major, minor, patch;
-
-       version = db_version( &major, &minor, &patch );
-
-       if( major != DB_VERSION_MAJOR ||
-               minor != DB_VERSION_MINOR ||
-               patch != DB_VERSION_PATCH )
-       {
-               printf("Berkeley DB version mismatch\n"
-                       "\theader: %s\n\tlibrary: %s\n",
-                       DB_VERSION_STRING, version);
-               return 1;
-       }
-#endif
-
-       return 0;
-}]])],[ol_cv_berkeley_db_version=yes],[ol_cv_berkeley_db_version=no],[ol_cv_berkeley_db_version=cross])
-
-       LIBS="$ol_LIBS"
-])
-
-       if test $ol_cv_berkeley_db_version = no ; then
-               AC_MSG_ERROR([Berkeley DB version mismatch])
-       fi
-])dnl
-dnl
-dnl --------------------------------------------------------------------
-dnl Check if Berkeley DB supports DB_THREAD
-AC_DEFUN([OL_BERKELEY_DB_THREAD],
-[AC_CACHE_CHECK([for Berkeley DB thread support], [ol_cv_berkeley_db_thread], [
-       ol_LIBS="$LIBS"
-       LIBS="$LTHREAD_LIBS $LIBS"
-       if test $ol_cv_lib_db != yes ; then
-               LIBS="$ol_cv_lib_db $LIBS"
-       fi
-
-       AC_RUN_IFELSE([AC_LANG_SOURCE([[
-#ifdef HAVE_DB_185_H
-       choke me;
-#else
-#include <db.h>
-#endif
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-main()
-{
-       int rc;
-       u_int32_t flags = DB_CREATE |
-#ifdef DB_PRIVATE
-               DB_PRIVATE |
-#endif
-               DB_THREAD;
-
-#if DB_VERSION_MAJOR > 2
-       DB_ENV *env = NULL;
-
-       rc = db_env_create( &env, 0 );
-
-       flags |= DB_INIT_MPOOL;
-#ifdef DB_MPOOL_PRIVATE
-       flags |= DB_MPOOL_PRIVATE;
-#endif
-
-       if( rc ) {
-               printf("BerkeleyDB: %s\n", db_strerror(rc) );
-               return rc;
-       }
-
-#if (DB_VERSION_MAJOR > 3) || (DB_VERSION_MINOR >= 1)
-       rc = (env->open)( env, NULL, flags, 0 );
-#else
-       rc = (env->open)( env, NULL, NULL, flags, 0 );
-#endif
-
-       if ( rc == 0 ) {
-               rc = env->close( env, 0 );
-       }
-
-       if( rc ) {
-               printf("BerkeleyDB: %s\n", db_strerror(rc) );
-               return rc;
-       }
-
-#else
-       DB_ENV env;
-       memset( &env, '\0', sizeof(env) );
-
-       rc = db_appinit( NULL, NULL, &env, flags );
-
-       if( rc == 0 ) {
-               db_appexit( &env );
-       }
-
-       unlink("__db_mpool.share");
-       unlink("__db_lock.share");
-#endif
-
-       return rc;
-}]])],[ol_cv_berkeley_db_thread=yes],[ol_cv_berkeley_db_thread=no],[ol_cv_berkeley_db_thread=cross])
-
-       LIBS="$ol_LIBS"
-])
-
-       if test $ol_cv_berkeley_db_thread != no ; then
-               AC_DEFINE(HAVE_BERKELEY_DB_THREAD, 1,
-                       [define if Berkeley DB has DB_THREAD support])
-       fi
-])dnl
-dnl
-dnl --------------------------------------------------------------------
-dnl Find any DB
-AC_DEFUN([OL_BERKELEY_DB],
-[ol_cv_berkeley_db=no
-AC_CHECK_HEADERS(db.h)
-if test $ac_cv_header_db_h = yes; then
-       OL_BDB_HEADER_VERSION
-       OL_BDB_COMPAT
-
-       if test $ol_cv_bdb_compat != yes ; then
-               AC_MSG_ERROR([BerkeleyDB version incompatible with BDB/HDB backends])
-       fi
-
-       OL_BERKELEY_DB_LINK
-       if test "$ol_cv_lib_db" != no ; then
-               ol_cv_berkeley_db=yes
-               OL_BERKELEY_DB_VERSION
-               OL_BERKELEY_DB_THREAD
-       fi
-fi
-])
-dnl --------------------------------------------------------------------
-dnl Check for version compatibility with back-bdb
-AC_DEFUN([OL_BDB_COMPAT],
-[AC_CACHE_CHECK([if Berkeley DB version supported by BDB/HDB backends], [ol_cv_bdb_compat],[
-       AC_EGREP_CPP(__db_version_compat,[
-#include <db.h>
-
- /* this check could be improved */
-#ifndef DB_VERSION_MAJOR
-#      define DB_VERSION_MAJOR 1
-#endif
-#ifndef DB_VERSION_MINOR
-#      define DB_VERSION_MINOR 0
-#endif
-#ifndef DB_VERSION_PATCH
-#      define DB_VERSION_PATCH 0
-#endif
-
-#define DB_VERSION_FULL        ((DB_VERSION_MAJOR<<16)|(DB_VERSION_MINOR<<8)|DB_VERSION_PATCH)
-
-/* require 4.4 or later, but less than 6.0.20 */
-#if DB_VERSION_FULL >= 0x040400 && DB_VERSION_FULL < 0x060014
-       __db_version_compat
-#endif
-#if DB_VERSION_FULL >= 0x060014
-#error "BerkeleyDB 6.0.20+ license is incompatible with LDAP"
-#endif
-       ], [ol_cv_bdb_compat=yes], [ol_cv_bdb_compat=no])])
-])
 
 dnl
 dnl ====================================================================
index ddfa48777dffb56436b1e3d5f761b9c2c0611e9f..cddaf16e0a506ce2a99f231881a7a12ca9495a83 100644 (file)
@@ -163,7 +163,6 @@ CLIENT_LIBS = @CLIENT_LIBS@
 LUTIL_LIBS = @LUTIL_LIBS@
 LTHREAD_LIBS = @LTHREAD_LIBS@
 
-BDB_LIBS = @BDB_LIBS@
 SLAPD_NDB_LIBS = @SLAPD_NDB_LIBS@
 WT_LIBS = @WT_LIBS@
 
index 97972cdedf7ffb5edac075839ff3aa6b4867309c..ece3056fb7e492e05f8960847fddeb714caffcc1 100644 (file)
@@ -300,9 +300,7 @@ OL_ARG_ENABLE(wrappers,[    --enable-wrappers         enable tcp wrapper support], no)
 
 dnl ----------------------------------------------------------------
 dnl SLAPD Backend Options
-Backends="bdb \
-       dnssrv \
-       hdb \
+Backends="dnssrv \
        ldap \
        mdb \
        meta \
@@ -323,12 +321,8 @@ SLAPD Backend Options:])
 
 OL_ARG_ENABLE(backends,[    --enable-backends    enable all available backends],
        --, [no yes mod])dnl
-OL_ARG_ENABLE(bdb,[    --enable-bdb      enable Berkeley DB backend],
-       no, [no yes mod], ol_enable_backends)dnl
 OL_ARG_ENABLE(dnssrv,[    --enable-dnssrv        enable dnssrv backend],
        no, [no yes mod], ol_enable_backends)dnl
-OL_ARG_ENABLE(hdb,[    --enable-hdb      enable Hierarchical DB backend],
-       no, [no yes mod], ol_enable_backends)dnl
 OL_ARG_ENABLE(ldap,[    --enable-ldap    enable ldap backend],
        no, [no yes mod], ol_enable_backends)dnl
 OL_ARG_ENABLE(mdb,[    --enable-mdb      enable mdb database backend],
@@ -498,9 +492,7 @@ if test $ol_enable_slapd = no ; then
        ol_enable_rewrite=no
 
 elif test $ol_enable_modules != yes &&
-       test $ol_enable_bdb = no &&
        test $ol_enable_dnssrv = no &&
-       test $ol_enable_hdb = no &&
        test $ol_enable_ldap = no &&
        test $ol_enable_mdb = no &&
        test $ol_enable_meta = no &&
@@ -566,7 +558,6 @@ dnl ----------------------------------------------------------------
 
 dnl Initialize vars
 LDAP_LIBS=
-BDB_LIBS=
 SLAPD_NDB_LIBS=
 SLAPD_NDB_INCS=
 LTHREAD_LIBS=
@@ -583,9 +574,7 @@ BUILD_THREAD=no
 BUILD_SLAPI=no
 SLAPD_SLAPI_DEPEND=
 
-BUILD_BDB=no
 BUILD_DNSSRV=no
-BUILD_HDB=no
 BUILD_LDAP=no
 BUILD_MDB=no
 BUILD_META=no
@@ -1883,36 +1872,6 @@ else
        ol_cv_func_gethostbyaddr_r_nargs=0
 fi
 
-dnl ----------------------------------------------------------------
-ol_link_bdb=no 
-
-if test $ol_enable_bdb/$ol_enable_hdb != no/no; then
-       OL_BERKELEY_DB
-
-       if test $ol_cv_berkeley_db = no ; then
-               AC_MSG_ERROR(BDB/HDB: BerkeleyDB not available)
-       fi
-
-       AC_DEFINE(HAVE_BERKELEY_DB,1,
-               [define this if Berkeley DB is available])
-
-       dnl $ol_cv_lib_db should be yes or -ldb
-       dnl (it could be no, but that would be an error
-       if test $ol_cv_lib_db != yes ; then
-               BDB_LIBS="$BDB_LIBS $ol_cv_lib_db"
-       fi
-
-       dnl link BDB library to slapd when there is a
-       dnl static BDB based backend in use
-       if test $ol_enable_bdb/$ol_enable_hdb != mod/mod ; then
-               if test $ol_enable_bdb = yes -o $ol_enable_hdb = yes ; then
-                       SLAPD_LIBS="$SLAPD_LIBS \$(BDB_LIBS)"
-               fi
-       fi
-
-       ol_link_bdb=yes 
-fi
-
 dnl ----------------------------------------------------------------
 
 if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then
@@ -2667,19 +2626,6 @@ if test "$ol_enable_monitor" != no ; then
        AC_DEFINE_UNQUOTED(SLAPD_MONITOR,$MFLAG,[define to support cn=Monitor backend])
 fi
 
-if test "$ol_enable_bdb" != no ; then
-       BUILD_SLAPD=yes
-       BUILD_BDB=$ol_enable_bdb
-       if test "$ol_enable_bdb" = mod ; then
-               SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-bdb"
-               MFLAG=SLAPD_MOD_DYNAMIC
-       else
-               SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-bdb"
-               MFLAG=SLAPD_MOD_STATIC
-       fi
-       AC_DEFINE_UNQUOTED(SLAPD_BDB,$MFLAG,[define to support BDB backend])
-fi
-
 if test "$ol_enable_dnssrv" != no ; then
        BUILD_SLAPD=yes
        BUILD_DNSSRV=$ol_enable_dnssrv
@@ -2693,19 +2639,6 @@ if test "$ol_enable_dnssrv" != no ; then
        AC_DEFINE_UNQUOTED(SLAPD_DNSSRV,$MFLAG,[define to support DNS SRV backend])
 fi
 
-if test "$ol_enable_hdb" != no ; then
-       BUILD_SLAPD=yes
-       BUILD_HDB=$ol_enable_hdb
-       if test "$ol_enable_hdb" = mod ; then
-               SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-hdb"
-               MFLAG=SLAPD_MOD_DYNAMIC
-       else
-               SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-hdb"
-               MFLAG=SLAPD_MOD_STATIC
-       fi
-       AC_DEFINE_UNQUOTED(SLAPD_HDB,$MFLAG,[define to support HDB backend])
-fi
-
 if test "$ol_enable_ldap" != no ; then
        BUILD_SLAPD=yes
        BUILD_LDAP=$ol_enable_ldap
@@ -3172,9 +3105,7 @@ dnl slapi
   AC_SUBST(BUILD_SLAPI)
   AC_SUBST(SLAPD_SLAPI_DEPEND)
 dnl backends
-  AC_SUBST(BUILD_BDB)
   AC_SUBST(BUILD_DNSSRV)
-  AC_SUBST(BUILD_HDB)
   AC_SUBST(BUILD_LDAP)
   AC_SUBST(BUILD_MDB)
   AC_SUBST(BUILD_META)
@@ -3217,7 +3148,6 @@ dnl overlays
 AC_SUBST(LDAP_LIBS)
 AC_SUBST(CLIENT_LIBS)
 AC_SUBST(SLAPD_LIBS)
-AC_SUBST(BDB_LIBS)
 AC_SUBST(SLAPD_NDB_LIBS)
 AC_SUBST(SLAPD_NDB_INCS)
 AC_SUBST(LTHREAD_LIBS)
@@ -3286,9 +3216,7 @@ AC_CONFIG_FILES([Makefile:build/top.mk:Makefile.in:build/dir.mk]
 [libraries/librewrite/Makefile:build/top.mk:libraries/librewrite/Makefile.in:build/lib.mk:build/lib-static.mk]
 [servers/Makefile:build/top.mk:servers/Makefile.in:build/dir.mk]
 [servers/slapd/Makefile:build/top.mk:servers/slapd/Makefile.in:build/srv.mk]
-[servers/slapd/back-bdb/Makefile:build/top.mk:servers/slapd/back-bdb/Makefile.in:build/mod.mk]
 [servers/slapd/back-dnssrv/Makefile:build/top.mk:servers/slapd/back-dnssrv/Makefile.in:build/mod.mk]
-[servers/slapd/back-hdb/Makefile:build/top.mk:servers/slapd/back-hdb/Makefile.in:build/mod.mk]
 [servers/slapd/back-ldap/Makefile:build/top.mk:servers/slapd/back-ldap/Makefile.in:build/mod.mk]
 [servers/slapd/back-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/Makefile.in:build/mod.mk]
 [servers/slapd/back-mdb/Makefile:build/top.mk:servers/slapd/back-mdb/Makefile.in:build/mod.mk]
index 8f15ccf314a606b7137f57406b4263aa29c852c2..7920272269010b01c749a6a85bbc71a7e8f03240 100644 (file)
@@ -27,7 +27,7 @@
  * Caveats:
  * - right now, the overlay assumes that all values of the objectClass
  *   attribute will be returned in rs->sr_entry; this may not be true
- *   in general, but it usually is for back-bdb/back-hdb.  To generalize,
+ *   in general, but it usually is for back-mdb.  To generalize,
  *   the search request should be analyzed, and if allowedAttributes or
  *   allowedAttributesEffective are requested, add objectClass to the
  *   requested attributes
index c101502bab6061fe2c4dd72df8151f2723f2fe02..8576177c05d1aa21210eb5c51726a18b4b9a12a2 100644 (file)
@@ -21,7 +21,7 @@ To use the overlay, add:
        moduleload <path to>nssov.so
        ...
 
-       database hdb
+       database mdb
        ...
        overlay nssov
 
@@ -65,7 +65,7 @@ See the nss-ldapd/README for the original attribute names used in this code.
 The overlay also supports dynamic configuration in cn=config. The layout
 of the config entry is
 
-       dn: olcOverlay={0}nssov,ocDatabase={1}hdb,cn=config
+       dn: olcOverlay={0}nssov,ocDatabase={1}mdb,cn=config
        objectClass: olcOverlayConfig
        objectClass: olcNssOvConfig
        olcOverlay: {0}nssov
index ef7bb9d2f72482d7ba636b91da611361bc5e1b67..b93c874d6c35e162fce7866669a3ce14441cc204 100644 (file)
@@ -278,7 +278,7 @@ of the config entry is
 .LP 
 .RS
 .nf
-    dn: olcOverlay={0}nssov,ocDatabase={1}hdb,cn=config
+    dn: olcOverlay={0}nssov,ocDatabase={1}mdb,cn=config
     objectClass: olcOverlayConfig
     objectClass: olcNssOvConfig
     olcOverlay: {0}nssov
index a9e5716638a1b41f13ad6d7ebd9d937393c508a4..84191d6f58b3441098b05cdccff76742e2bd45d6 100644 (file)
@@ -147,11 +147,6 @@ search over 500 thousand entries per second. The search was on an unindexed
 attribute using a filter that would not match any entry, forcing slapd to examine 
 every entry in the DB, testing the filter for a match.
 
-Essentially the slapd entry cache in back-bdb/back-hdb is so efficient the search 
-processing time is almost invisible; the runtime is limited only by the memory 
-bandwidth of the machine. (The search data rate corresponds to about 3.5GB/sec; 
-the memory bandwidth on the machine is only about 4GB/sec due to ECC and register latency.)
-
 H3: New overlays
 
 * slapo-constraint (Attribute value constraints)
@@ -199,21 +194,13 @@ H3: New build options
 * Support for building against GnuTLS
 
 
-H2: Obsolete Features Removed From 2.4
-
-These features were strongly deprecated in 2.3 and removed in 2.4.
-
-H3: Slurpd
+H2: Obsolete Features Removed From 2.5
 
-Please read the {{SECT:Replication}} section as to why this is no longer in
-OpenLDAP
+These features were strongly deprecated in 2.4 and removed in 2.5.
 
-H3: back-ldbm
+H3: back-bdb and back-hdb
 
-back-ldbm was both slow and unreliable. Its byzantine indexing code was
-prone to spontaneous corruption, as were the underlying database libraries
-that were commonly used (e.g. GDBM or NDBM). back-bdb and back-hdb are
-superior in every aspect, with simplified indexing to avoid index corruption,
-fine-grained locking for greater concurrency, hierarchical caching for
-greater performance, streamlined on-disk format for greater efficiency
-and portability, and full transaction support for greater reliability.
+back-bdb and back-hdb were signficantly slower than back-mdb and
+required significant tuning of multiple parameters to maximize
+performance. back-mdb requires no tuning and provides all the
+functionality previously provided via back-bdb and back-hdb.
index d0b9cd756ee5e846858ae81855f76124f850f2f1..16c295edaa172bbef9a3664cefe4f6f55e7b14d7 100644 (file)
@@ -636,7 +636,7 @@ values of <n>.
 
 H3: ldap_*: Internal (implementation specific) error (80) - additional info: entry index delete failed
 
-This seems to be related with wrong ownership of the BDB's dir (/var/lib/ldap) 
+This seems to be related with wrong ownership of the MDB's dir (/var/lib/ldap)
 and files. The files must be owned by the user that slapd runs as.
 
 >    chown -R ldap:ldap /var/lib/ldap 
@@ -652,11 +652,3 @@ immediately and client gets an error :
 >     SASL/GSSAPI authentication started ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1)
 
 Then check the slapd service, it stopped.
-
-This may come from incompatible of using different versions of BerkeleyDB for 
-installing of SASL and installing of OpenLDAP. The problem arises in case of 
-using multiple version of BerkeleyDB. Solution: - Check which version of 
-BerkeleyDB when install Cyrus SASL. 
-
-Reinstall OpenLDAP with the version of BerkeleyDB above.
-
index 33934ff5d438dae8a8276b4789a60bcdc329a7fd..71ba59d4b34e8d135ec98633ab3ba0b473e0f2be 100644 (file)
@@ -102,7 +102,6 @@ NOSYNC
 env
 pagedResultsControl
 dup
-hdb
 LDIFv
 syslog
 monitorTimestamp
@@ -886,7 +885,6 @@ proxyAttrSet
 proxyAttrset
 mary
 crlcheck
-olcBdbConfig
 kadmin
 mech
 slapcat
@@ -1189,7 +1187,6 @@ moddn
 calloc
 LDFLAGS
 attributeOrValueExists
-olcHdbConfig
 bsize
 auditObject
 dnssrv
@@ -1491,7 +1488,6 @@ ghenry
 odbcinst
 reqType
 slapover
-BerkeleyDB's
 attributename
 lwrap
 reqStart
@@ -1627,7 +1623,6 @@ DSAIT
 olcHidden
 mySNMP
 metainformation
-BerkeleyDB
 ldapuri
 auditAbandon
 RANDFILE
@@ -1661,7 +1656,6 @@ olcPasswordHash
 ldapc
 loopback
 ldapi
-BDB's
 GETREALM
 functionalities
 noplain
@@ -1669,7 +1663,6 @@ NOECHOPROMPT
 AES
 ldaps
 notoc
-bdb
 LDAPv
 IPsec
 olcServerID
index 759036c9e3e12cc900db12abd698578e5921c628..d03b2bb92d0eb927ca02f2a3807938e19df227e3 100644 (file)
@@ -14,38 +14,9 @@ name of the module for a backend is usually of the form:
 
 >      back_<backend name>.la
 
-So for example, if you need to load the {{hdb}} backend, you would configure
+So for example, if you need to load the {{mdb}} backend, you would configure
 
->      moduleload back_hdb.la
-
-H2: Berkeley DB Backends
-
-
-H3: Overview
-
-The {{hdb}} backend to {{slapd}}(8) is a backend for a 
-normal {{slapd}} database.  It uses the Oracle Berkeley DB ({{TERM:BDB}}) 
-package to store data. It makes extensive use of indexing and caching 
-(see the {{SECT:Tuning}} section) to speed data access.
-
-{{hdb}} is a variant of the original {{bdb}} backend which was first written for use with BDB.
-{{hdb}} uses a hierarchical database layout which supports subtree renames.
-It is otherwise identical to the {{bdb}}
-behavior, and all the same configuration options apply.
-
-Note: An {{hdb}} database needs a large {{idlcachesize}} for good search performance, 
-typically three times the {{cachesize}} (entry cache size) or larger.
-
-Note: The {{hdb}} backend has superseded the {{bdb}} backend, and both will
-are deprecated in favor of the new {{mdb}} backend. See below.
-
-H3: back-bdb/back-hdb Configuration
-
-MORE LATER
-
-H3: Further Information
-
-{{slapd-bdb}}(5)
+>      moduleload back_mdb.la
 
 H2: LDAP
 
@@ -199,16 +170,16 @@ H3: Overview
 The {{mdb}} backend to {{slapd}}(8) is the recommended primary backend for a
 normal {{slapd}} database.  It uses OpenLDAP's own
 Lightning Memory-Mapped Database ({{TERM:LMDB}})
-library to store data and is intended to replace the Berkeley DB backends.
+library to store data and replaces the BerkeleyDB backends used in older
+OpenLDAP releases.
 
-It supports indexing like the BDB backends, but it uses no caching and requires
-no tuning to deliver maximum search performance.  Like {{hdb}}, it is also
-fully hierarchical and supports subtree renames in constant time.
+It supports indexing, it uses no caching, and requires no tuning to deliver
+maximum search performance.  It is fully hierarchical and supports subtree
+renames in constant time.
 
 H3: back-mdb Configuration
 
-Unlike the BDB backends, the {{mdb}} backend can be instantiated with very few
-configuration lines:
+The {{mdb}} backend can be instantiated with very few configuration lines:
 
 >      include ./schema/core.schema
 >
@@ -490,7 +461,7 @@ distribute information between different sites/applications that use RDBMSes
 and/or LDAP. Or whatever else...
 
 It is {{B:NOT}} designed as a general-purpose backend that uses RDBMS instead of 
-BerkeleyDB (as the standard BDB backend does), though it can be used as such with 
+LMDB (as the standard back-mdb backend does), though it can be used as such with
 several limitations. Please see {{SECT: LDAP vs RDBMS}} for discussion.
 
 The idea is to use some meta-information to translate LDAP queries to SQL queries, 
index f16a474b93d55fa5dc25be0f5b609d9d5f46100b..1d8cc006ffc6cd61b1f0b8178c605e1d51112d47 100644 (file)
@@ -118,23 +118,6 @@ OpenLDAP's {{slapd}}(8) {{TERM:MDB}} primary database backend uses the {{TERM:LM
 software included with the OpenLDAP source.  There is no need to download any
 additional software to have {{MDB}} support.
 
-OpenLDAP's {{slapd}}(8) {{TERM:BDB}} and {{TERM:HDB}} deprecated database backends
-require {{ORG[expand]Oracle}}'s Berkeley DB.
-If not available at configure time, you will not be able to build
-{{slapd}}(8) with these deprecated database backends.
-
-Your operating system may provide a supported version of
-Berkeley DB in the base system or as an optional
-software component.  If not, you'll have to obtain and
-install it yourself.  Berkeley DB is available from
-{{ORG[expand]Oracle}}'s Berkeley DB download page if required.
-
-There are several versions available from {{ORG[expand]Oracle}}.
-Berkeley DB version 6.0.20 and later uses a software license that is
-incompatible with LDAP technology and should not be used with OpenLDAP.
-
-Note: Please see {{SECT:Recommended OpenLDAP Software Dependency Versions}} for
-more information.
 
 
 H3: Threads
index 76ae2b6ae0ebeb07872eb1a6c7586488a3b21661..c9a5b7b84fe710e8aa7b22dc07e5202acababc7d 100644 (file)
@@ -346,7 +346,7 @@ really have a "directory".
 
 Existing commercial LDAP server implementations that use a relational database 
 are either from the first kind or the third. I don't know of any implementation 
-that uses a relational database to do inefficiently what BDB does efficiently.
+that uses a relational database to do inefficiently what LMDB does efficiently.
 For those who are interested in "third way" (exposing EXISTING data from RDBMS 
 as LDAP tree, having some limitations compared to classic LDAP model, but making 
 it possible to interoperate between LDAP and SQL applications):
@@ -403,15 +403,9 @@ tags.
 {{B:Choice of database backends}}: {{slapd}} comes with a variety
 of different database backends you can choose from. They include
 {{TERM:MDB}}, a hierarchical high-performance transactional database backend;
-{{TERM:BDB}}, a high-performance transactional database backend (deprecated);
-{{TERM:HDB}}, a hierarchical high-performance transactional
-backend (deprecated); {{SHELL}}, a backend interface to arbitrary shell scripts;
+{{SHELL}}, a backend interface to arbitrary shell scripts;
 and PASSWD, a simple backend interface to the {{passwd}}(5) file.
-The MDB backend utilizes {{TERM:LMDB}}, a high performance replacement
-for {{ORG[expand]Oracle}}'s Berkeley DB.
-The BDB and HDB backends utilize {{ORG[expand]Oracle}} Berkeley DB. These
-backends have been deprecated as LMDB provides significantly higher read
-and write throughput and data reliability.
+The MDB backend utilizes {{TERM:LMDB}}.
 
 {{B:Multiple database instances}}: {{slapd}} can be configured to
 serve multiple databases at the same time. This means that a single
index 9d765f2e7f2e28e7e1cf84abe71ce811a41e02e8..6844668c953931c29bba9a73c41799609d806ad4 100644 (file)
@@ -20,23 +20,7 @@ The LMDB database can be copied live using the mdb_copy command.  If the databas
 is a sparse file via the use of the "writemap" environment flag, the resulting
 copy will be the actual size of the database rather than a sparse copy.
 
-2. Backup the Berkeley database itself and periodically back up the transaction 
-log files:
-
-Berkeley DB produces transaction logs that can be used to reconstruct
-changes from a given point in time. For example, if an administrator were willing to only
-lose one hour's worth of changes, they could take down the server in
-the middle of the night, copy the Berkeley database files offsite, and bring
-the server back online. Then, on an hourly basis, they could force a
-database checkpoint, capture the log files that have been generated in the
-past hour, and copy them offsite. The accumulated log files, in combination
-with the previous database backup, could be used with db_recover to
-reconstruct the database up to the time the last collection of log files was
-copied offsite. This method affords good protection, with minimal space
-overhead.
-
-
-3. Periodically run slapcat and back up the LDIF file:
+2. Periodically run slapcat and back up the LDIF file:
 
 Slapcat can be run while slapd is active. However, one runs the risk of an
 inconsistent database- not from the point of slapd, but from the point of
@@ -52,71 +36,11 @@ files can be rather large and the accumulation of the day's backups could
 add up to a substantial amount of space.
 
 You can use {{slapcat}}(8) to generate an LDIF file for each of your {{slapd}}(8) 
-back-mdb, back-bdb, or back-hdb databases.
+back-mdb databases.
 
 >    slapcat -f slapd.conf -b "dc=example,dc=com"
 
-For back-mdb, back-bdb, and back-hdb, this command may be ran while slapd(8) is running.
-
-H2: Berkeley DB Logs
-
-Berkeley DB log files grow, and the administrator has to deal with it. The 
-procedure is known as log file archival or log file rotation. 
-
-Note: The actual log file rotation is handled by the Berkeley DB engine.
-
-Logs of current transactions need to be stored into files so that the database 
-can be recovered in the event of an application crash. Administrators can change 
-the size limit of a single log file (by default 10MB), and have old log files 
-removed automatically, by setting up DB environment (see below). The reason 
-Berkeley DB never deletes any log files by default is that the administrator 
-may wish to backup the log files before removal to make database recovery 
-possible even after a catastrophic failure, such as file system corruption.
-
-Log file names are {{F:log.XXXXXXXXXX}} (X is a digit). By default the log files 
-are located in the BDB backend directory. The {{F:db_archive}} tool knows what 
-log files are used in current transactions, and what are not. Administrators can 
-move unused log files to a backup media, and delete them. To have them removed 
-automatically, place set_flags {{DB_LOG_AUTOREMOVE}} directive in {{F:DB_CONFIG}}. 
-
-Note: If the log files are removed automatically, recovery after a catastrophic 
-failure is likely to be impossible.
-
-The files with names {{F:__db.001}}, {{F:__db.002}}, etc are just shared memory 
-regions (or whatever). These ARE NOT 'logs', they must be left alone. Don't be 
-afraid of them, they do not grow like logs do.
-
-To understand the {{F:db_archive}} interface, the reader should refer to 
-chapter 9 of the Berkeley DB guide. In particular, the following chapters are 
-recommended:
-
-* Database and log file archival - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/archival.html}}
-* Log file removal - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/logfile.html}}
-* Recovery procedures - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/recovery.html}}
-* Hot failover - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/hotfail.html}}
-* Complete list of Berkeley DB flags - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/api_c/env_set_flags.html}}
-
-Advanced installations can use special environment settings to fine-tune some 
-Berkeley DB options (change the log file limit, etc). This can be done by using 
-the {{F:DB_CONFIG}} file. This magic file can be created in BDB backend directory 
-set up by {{slapd.conf}}(5). More information on this file can be found in File 
-naming chapter. Specific directives can be found in C Interface, look for 
-{{DB_ENV->set_XXXX}} calls.
-
-Note: options set in {{F:DB_CONFIG}} file override options set by OpenLDAP. 
-Use them with extreme caution. Do not use them unless You know what You are doing.
-
-The advantages of {{F:DB_CONFIG}} usage can be the following:
-
-* to keep data files and log files on different mediums (i.e. disks) to improve 
-  performance and/or reliability;
-* to fine-tune some specific options (such as shared memory region sizes);
-* to set the log file limit (please read Log file limits before doing this).
-
-To figure out the best-practice BDB backup scenario, the reader is highly 
-recommended to read the whole Chapter 9: Berkeley DB Transactional Data Store Applications. 
-This chapter is a set of small pages with examples in C language. Non-programming 
-people can skip these examples without loss of knowledge.
+For back-mdb this command may be ran while slapd(8) is running.
 
 
 H2: Checkpointing
@@ -152,7 +76,7 @@ type are:
 +{{B: slapcat the current data out}}
 
 .{{S: }}
-+{{B: Clear out the current data directory (/usr/local/var/openldap-data/) leaving DB_CONFIG in place}}
++{{B: Clear out the current data directory (/usr/local/var/openldap-data/)}}
 
 .{{S: }}
 +{{B: Perform the software upgrades}}
index e582ce27e856755e4675247a42338f4966a50888..4ada7441cba8518b3e492c037393b96a99e32084 100644 (file)
@@ -214,12 +214,10 @@ backends, as well as backends loaded by modules.  For example:
 >      monitoredInfo: config                 
 >      monitoredInfo: ldif     
 >      monitoredInfo: monitor
->      monitoredInfo: bdb        
->      monitoredInfo: hdb
 >      monitoredInfo: mdb
 
-This indicates the {{config}}, {{ldif}}, {{monitor}}, {{bdb}},
-and {{hdb}} backends are available.
+This indicates the {{config}}, {{ldif}}, {{monitor}},
+and {{mdb}} backends are available.
 
 The {{EX:cn=Backends,cn=Monitor}} object is also a container
 for available backend objects.  Each available backend object
@@ -243,33 +241,6 @@ contains information about a particular backend.  For example:
 >      seeAlso: cn=Database 2,cn=Databases,cn=Monitor
 >      
 >      dn: cn=Backend 3,cn=Backends,cn=Monitor
->      monitoredInfo: bdb
->      monitorRuntimeConfig: TRUE
->      supportedControl: 1.3.6.1.1.12
->      supportedControl: 2.16.840.1.113730.3.4.2
->      supportedControl: 1.3.6.1.4.1.4203.666.5.2
->      supportedControl: 1.2.840.113556.1.4.319
->      supportedControl: 1.3.6.1.1.13.1
->      supportedControl: 1.3.6.1.1.13.2
->      supportedControl: 1.3.6.1.4.1.4203.1.10.1
->      supportedControl: 1.2.840.113556.1.4.1413
->      supportedControl: 1.3.6.1.4.1.4203.666.11.7.2
->      seeAlso: cn=Database 1,cn=Databases,cn=Monitor
->      
->      dn: cn=Backend 4,cn=Backends,cn=Monitor
->      monitoredInfo: hdb
->      monitorRuntimeConfig: TRUE
->      supportedControl: 1.3.6.1.1.12
->      supportedControl: 2.16.840.1.113730.3.4.2
->      supportedControl: 1.3.6.1.4.1.4203.666.5.2
->      supportedControl: 1.2.840.113556.1.4.319
->      supportedControl: 1.3.6.1.1.13.1
->      supportedControl: 1.3.6.1.1.13.2
->      supportedControl: 1.3.6.1.4.1.4203.1.10.1
->      supportedControl: 1.2.840.113556.1.4.1413
->      supportedControl: 1.3.6.1.4.1.4203.666.11.7.2
->
->      dn: cn=Backend 5,cn=Backends,cn=Monitor
 >      monitoredInfo: mdb
 >      monitorRuntimeConfig: TRUE
 >      supportedControl: 1.3.6.1.1.12
index 2143ebdb1839d54e0a5613bb9202dc6e400eb008..6df98ee2d1589e90a3ccffbdded8740c77ae6055 100644 (file)
@@ -86,7 +86,7 @@ H3: Access Logging Configuration
 
 The following is a basic example that implements Access Logging:
 
->        database bdb
+>        database mdb
 >        suffix dc=example,dc=com
 >        ...
 >        overlay accesslog
@@ -94,7 +94,7 @@ The following is a basic example that implements Access Logging:
 >        logops writes reads
 >        logold (objectclass=person)
 >        
->        database bdb
+>        database mdb
 >        suffix cn=log
 >        ...
 >        index reqStart eq
@@ -103,7 +103,7 @@ The following is a basic example that implements Access Logging:
 
 The following is an example used for {{SECT:delta-syncrepl replication}}:
 
->        database hdb
+>        database mdb
 >        suffix cn=accesslog
 >        directory /usr/local/var/openldap-accesslog
 >        rootdn cn=accesslog
@@ -112,7 +112,7 @@ The following is an example used for {{SECT:delta-syncrepl replication}}:
 
 Accesslog overlay definitions for the primary db
 
->        database bdb
+>        database mdb
 >        suffix dc=example,dc=com
 >        ...
 >        overlay accesslog
@@ -619,7 +619,7 @@ specific database. For example, with the following minimal slapd.conf:
 >
 >        authz-regexp "gidNumber=0\\\+uidNumber=0,cn=peercred,cn=external,cn=auth"
 >                "cn=Manager,dc=example,dc=com"
->        database        bdb
+>        database        mdb
 >        suffix          "dc=example,dc=com"
 >        rootdn          "cn=Manager,dc=example,dc=com"
 >        rootpw          secret
@@ -738,7 +738,7 @@ H4: Setting cache parameters
 This directive enables proxy caching and sets general cache
 parameters.  The <DB> parameter specifies which underlying database
 is to be used to hold cached entries.  It should be set to
-{{EX:bdb}} or {{EX:hdb}}.  The <maxentries> parameter specifies the
+{{EX:mdb}}.  The <maxentries> parameter specifies the
 total number of entries which may be held in the cache.  The
 <nattrsets> parameter specifies the total number of attribute sets
 (as specified by the {{EX:pcacheAttrset}} directive) that may be
@@ -777,7 +777,7 @@ at server {{EX:ldap.example.com}}.
 >      rootdn          "dc=example,dc=com" 
 >      uri             ldap://ldap.example.com/
 >      overlay pcache
->      pcache         hdb 100000 1 1000 100
+>      pcache         mdb 100000 1 1000 100
 >      pcacheAttrset  0 mail postaladdress telephonenumber 
 >      pcacheTemplate (sn=) 0 3600
 >      pcacheTemplate (&(sn=)(givenName=)) 0 3600
@@ -806,7 +806,7 @@ at server {{EX:ldap.example.com}}.
 >   objectClass: olcOverlayConfig
 >   objectClass: olcPcacheConfig
 >   olcOverlay: {0}pcache
->   olcPcache: hdb 100000 1 1000 100
+>   olcPcache: mdb 100000 1 1000 100
 >   olcPcacheAttrset: 0 mail postalAddress telephoneNumber
 >   olcPcacheTemplate: "(sn=)" 0 3600 0 0 0
 >   olcPcacheTemplate: "(&(sn=)(givenName=))" 0 3600 0 0 0
@@ -889,7 +889,7 @@ the ppolicy module being added to the database that handles the naming
 context "dc=example,dc=com". In this example we are also specifying the DN of 
 a policy object to use if none other is specified in a user's object.
 
->       database bdb
+>       database mdb
 >       suffix "dc=example,dc=com"
 >       [...additional database configuration directives go here...]
 >       
@@ -978,7 +978,7 @@ H2: Referential Integrity
 
 H3: Overview
 
-This overlay can be used with a backend database such as slapd-bdb(5)
+This overlay can be used with a backend database such as slapd-mdb(5)
 to maintain the cohesiveness of a schema which utilizes reference
 attributes.
 
@@ -1173,7 +1173,7 @@ H2: Translucent Proxy
 
 H3: Overview
 
-This overlay can be used with a backend database such as {{:slapd-bdb}}(5)
+This overlay can be used with a backend database such as {{:slapd-mdb}}(5)
 to create a "translucent proxy".
 
 Entries retrieved from a remote LDAP server may have some or all attributes 
@@ -1212,7 +1212,7 @@ First we configure the overlay in the normal manner:
 >       pidfile     ./slapd.pid
 >       argsfile    ./slapd.args
 >       
->       database    bdb
+>       database    mdb
 >       suffix      "dc=suretecsystems,dc=com"
 >       rootdn      "cn=trans,dc=suretecsystems,dc=com"
 >       rootpw      secret
@@ -1305,7 +1305,7 @@ H2: Attribute Uniqueness
 
 H3: Overview
 
-This overlay can be used with a backend database such as {{slapd-bdb(5)}}
+This overlay can be used with a backend database such as {{slapd-mdb(5)}}
 to enforce the uniqueness of some or all attributes within a subtree.
 
 
@@ -1390,7 +1390,7 @@ Here are a few examples:
 
 >       loglevel    sync stats
 >       
->       database    hdb
+>       database    mdb
 >       suffix      "dc=suretecsystems,dc=com"
 >       directory   /usr/local/var/openldap-data
 >       
index 874ed4c2829da242d14c6995d3e8ba7d9741bf2a..db39add7489313b2532c1d38bb74c823609e0033 100644 (file)
@@ -225,8 +225,8 @@ in the replication context.
 
 The syncrepl engine, which is a consumer-side replication engine,
 can work with any backends. The LDAP Sync provider can be configured
-as an overlay on any backend, but works best with the {{back-bdb}},
-{{back-hdb}}, or {{back-mdb}} backends.
+as an overlay on any backend, but works best with the {{back-mdb}}
+backend.
 
 The LDAP Sync provider maintains a {{EX:contextCSN}} for each
 database as the current synchronization state indicator of the
@@ -423,9 +423,6 @@ writes have to go to just one of the mirror nodes at a time
 server (slapd in proxy mode) or device (hardware load balancer)
 is needed to manage which provider is currently active
 * Backups are managed slightly differently
-- If backing up the Berkeley database itself and periodically backing up the 
-transaction log files, then the same member of the mirror pair needs to be 
-used to collect logfiles until the next database backup is taken 
 
 For configuration, please see the {{SECT:MirrorMode}} section below
 
@@ -674,8 +671,8 @@ replica servers:
 >     # Set the module path location
 >     modulepath /opt/symas/lib/openldap
 >     
->     # Load the hdb backend
->     moduleload back_hdb.la
+>     # Load the mdb backend
+>     moduleload back_mdb.la
 >     
 >     # Load the accesslog overlay
 >     moduleload accesslog.la
@@ -684,7 +681,7 @@ replica servers:
 >     moduleload syncprov.la
 >     
 >     # Accesslog database definitions
->     database hdb
+>     database mdb
 >     suffix cn=accesslog
 >     directory /db/accesslog
 >     rootdn cn=accesslog
@@ -699,7 +696,7 @@ replica servers:
 >     limits dn.exact="cn=replicator,dc=symas,dc=com" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited
 >     
 >     # Primary database definitions
->     database hdb
+>     database mdb
 >     suffix "dc=symas,dc=com"
 >     rootdn "cn=manager,dc=symas,dc=com"
 >     
@@ -730,7 +727,7 @@ For more information, always consult the relevant man pages ({{slapo-accesslog}}
 H4: Delta-syncrepl Consumer configuration
 
 >     # Replica database configuration
->     database hdb
+>     database mdb
 >     suffix "dc=symas,dc=com"
 >     rootdn "cn=manager,dc=symas,dc=com"
 >     
@@ -759,10 +756,7 @@ H4: Delta-syncrepl Consumer configuration
 
 
 The above configuration assumes that you have a replicator identity defined 
-in your database that can be used to bind to the provider. In addition, 
-all of the databases (primary, replica, and the accesslog 
-storage database) should also have properly tuned {{DB_CONFIG}} files that meet 
-your needs.
+in your database that can be used to bind to the provider.
 
 Note: An accesslog database is unique to a given master. It should
 never be replicated.
@@ -978,7 +972,7 @@ The following example is for a self-contained push-based replication solution:
 >      include     /usr/local/etc/openldap/slapd.acl
 >      
 >      modulepath  /usr/local/libexec/openldap
->      moduleload  back_hdb.la
+>      moduleload  back_mdb.la
 >      moduleload  syncprov.la
 >      moduleload  back_monitor.la
 >      moduleload  back_ldap.la
@@ -988,7 +982,7 @@ The following example is for a self-contained push-based replication solution:
 >      
 >      loglevel    sync stats
 >      
->      database    hdb
+>      database    mdb
 >      suffix      "dc=suretecsystems,dc=com"
 >      directory   /usr/local/var/openldap-data
 >      
@@ -1064,7 +1058,7 @@ A replica configuration for this type of setup could be:
 >      include     /usr/local/etc/openldap/slapd.acl
 >      
 >      modulepath  /usr/local/libexec/openldap
->      moduleload  back_hdb.la
+>      moduleload  back_mdb.la
 >      moduleload  syncprov.la
 >      moduleload  back_monitor.la
 >      moduleload  back_ldap.la
@@ -1074,7 +1068,7 @@ A replica configuration for this type of setup could be:
 >      
 >      loglevel    sync stats
 >      
->      database    hdb
+>      database    mdb
 >      suffix      "dc=suretecsystems,dc=com"
 >      directory   /usr/local/var/openldap-slave/data
 >      
index 017a05fcf0f374fce3c21b5d500b4500f8836608..7e1c7de4c58b11272b4d36d5e2c2a06fef6d7813 100644 (file)
@@ -69,7 +69,7 @@ used to configure the software.
 the schema that is hard-coded in slapd).
 .. Child entries of {{EX:cn=schema,cn=config}} contain user schema as
 loaded from config files or added at runtime.
-* Backend-specific configuration 
+* Backend-specific configuration
 * Database-specific configuration
 .. Overlays are defined in children of the Database entry.
 .. Databases and Overlays may also have other miscellaneous children.
@@ -207,7 +207,7 @@ Level       Keyword         Description
 !endblock
 
 The desired log level can be input as a single integer that
-combines the (ORed) desired levels, both in decimal or in hexadecimal 
+combines the (ORed) desired levels, both in decimal or in hexadecimal
 notation, as a list of integers (that are ORed internally), or as a list of the names that are shown between brackets, such that
 
 >              olcLogLevel 129
@@ -364,10 +364,8 @@ supported backend types listed in Table 5.2.
 !block table; align=Center; coltags="EX,N"; \
        title="Table 5.2: Database Backends"
 Types  Description
-bdb    Berkeley DB transactional backend (deprecated)
 config Slapd configuration backend
 dnssrv DNS SRV backend
-hdb    Hierarchical variant of bdb backend (deprecated)
 ldap   Lightweight Directory Access Protocol (Proxy) backend
 ldif   Lightweight Data Interchange Format backend
 mdb    Memory-Mapped DB backend
@@ -381,7 +379,7 @@ sql SQL Programmable backend
 
 \Example:
 
->      olcBackend: bdb
+>      olcBackend: mdb
 
 There are no other directives defined for this entry.  Specific backend
 types may define additional attributes for their particular use but so
@@ -391,9 +389,9 @@ not appear in any actual configurations.
 
 H4: Sample Entry
 
-> dn: olcBackend=bdb,cn=config
+> dn: olcBackend=mdb,cn=config
 > objectClass: olcBackendConfig
-> olcBackend: bdb
+> olcBackend: mdb
 
 
 H3: Database-specific Directives
@@ -421,9 +419,9 @@ databases.
 
 \Example:
 
->      olcDatabase: bdb
+>      olcDatabase: mdb
 
-This marks the beginning of a new {{TERM:BDB}} database instance.
+This marks the beginning of a new {{TERM:MDB}} database instance.
 
 
 H4: olcAccess: to <what> [ by <who> [<accesslevel>] [<control>] ]+
@@ -642,7 +640,7 @@ schema conformance. The default is off.
 The {{EX:binddn}} parameter gives the DN to bind as for the
 syncrepl searches to the provider slapd. It should be a DN
 which has read access to the replication content in the
-master database. 
+master database.
 
 The {{EX:bindmethod}} is {{EX:simple}} or {{EX:sasl}},
 depending on whether simple password-based authentication or
@@ -683,8 +681,8 @@ conforms to the obsolete {{changelog}} format. If the {{EX:syncdata}}
 parameter is omitted or set to {{EX:"default"}} then the log
 parameters are ignored.
 
-The {{syncrepl}} replication mechanism is supported by the {{bdb}},
-{{hdb}}, and {{mdb}} backends.
+The {{syncrepl}} replication mechanism is supported by the {{mdb}}
+backend.
 
 See the {{SECT:LDAP Sync Replication}} chapter of this guide for
 more information on how to use this directive.
@@ -731,21 +729,20 @@ H4: Sample Entries
 >olcRootDN: cn=Manager,dc=example,dc=com
 
 
-H3: BDB and HDB Database Directives
+H3: MDB Database Directives
 
-Directives in this category apply to both the {{TERM:BDB}}
-and the {{TERM:HDB}} database.
+Directives in this category apply to the {{TERM:MDB}}
+database backend.
 They are used in an olcDatabase entry in addition to the generic
 database directives defined above.  For a complete reference
-of BDB/HDB configuration directives, see {{slapd-bdb}}(5). In
-addition to the {{EX:olcDatabaseConfig}} objectClass, BDB and HDB
-database entries must have the {{EX:olcBdbConfig}} and
-{{EX:olcHdbConfig}} objectClass, respectively.
+of MDB configuration directives, see {{slapd-mdb}}(5). In
+addition to the {{EX:olcDatabaseConfig}} objectClass, MDB
+database entries must have the {{EX:olcMdbConfig}} objectClass.
 
 
 H4: olcDbDirectory: <directory>
 
-This directive specifies the directory where the BDB files
+This directive specifies the directory where the MDB files
 containing the database and associated indices live.
 
 \Default:
@@ -753,98 +750,48 @@ containing the database and associated indices live.
 >      olcDbDirectory: /usr/local/var/openldap-data
 
 
-H4: olcDbCachesize: <integer>
-
-This directive specifies the size in entries of the in-memory
-cache maintained by the BDB backend database instance.
-
-\Default:
-
->      olcDbCachesize: 1000
-
-
 H4: olcDbCheckpoint: <kbyte> <min>
 
-This directive specifies how often to checkpoint the BDB transaction log.
-A checkpoint operation flushes the database buffers to disk and writes a
-checkpoint record in the log.
+This directive specifies the frequency for flushing the database disk
+buffers. This directive is only needed if the {{olcDbNoSync}} option is
+{{EX:TRUE}}.
 The checkpoint will occur if either <kbyte> data has been written or
 <min> minutes have passed since the last checkpoint. Both arguments default
 to zero, in which case they are ignored. When the <min> argument is
 non-zero, an internal task will run every <min> minutes to perform the
-checkpoint. See the Berkeley DB reference guide for more details.
+checkpoint. Note: currently the _kbyte_ setting is unimplemented.
 
 \Example:
 
 >      olcDbCheckpoint: 1024 10
 
 
-H4: olcDbConfig: <DB_CONFIG setting>
+H4: olcDbEnvFlags: {nosync,nometasync,writemap,mapasync,nordahead}
 
-This attribute specifies a configuration directive to be placed in the
-{{EX:DB_CONFIG}} file of the database directory. At server startup time, if
-no such file exists yet, the {{EX:DB_CONFIG}} file will be created and the
-settings in this attribute will be written to it. If the file exists,
-its contents will be read and displayed in this attribute. The attribute
-is multi-valued, to accommodate multiple configuration directives. No default
-is provided, but it is essential to use proper settings here to get the
-best server performance.
+This option specifies flags for finer-grained control of  the  LMDB  library's
+operation.
 
-Any changes made to this attribute will be written to the {{EX:DB_CONFIG}}
-file and will cause the database environment to be reset so the changes
-can take immediate effect. If the environment cache is large and has not
-been recently checkpointed, this reset operation may take a long time. It
-may be advisable to manually perform a single checkpoint using the Berkeley DB
-{{db_checkpoint}} utility before using LDAP Modify to change this
-attribute.
+* {{F:nosync}}: This is exactly the same as the dbnosync directive.
 
-\Example:
+* {{F:nometasync}}: Flush the data on a commit, but skip the sync of the meta
+page. This mode is slightly faster than doing a full sync, but can
+potentially lose the last committed transaction if the operating system
+crashes. If both nometasync and nosync are set, the nosync flag takes
+precedence.
 
->      olcDbConfig: set_cachesize 0 10485760 0
->      olcDbConfig: set_lg_bsize 2097512
->      olcDbConfig: set_lg_dir /var/tmp/bdb-log
->      olcDbConfig: set_flags DB_LOG_AUTOREMOVE
-
-In this example, the BDB cache is set to 10MB, the BDB transaction log
-buffer size is set to 2MB, and the transaction log files are to be stored
-in the /var/tmp/bdb-log directory. Also a flag is set to tell BDB to
-delete transaction log files as soon as their contents have been
-checkpointed and they are no longer needed. Without this setting the
-transaction log files will continue to accumulate until some other
-cleanup procedure removes them. See the Berkeley DB documentation for the
-{{EX:db_archive}} command for details. For a complete list of Berkeley DB 
-flags please see - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/api_c/env_set_flags.html}}
-
-Ideally the BDB cache must be
-at least as large as the working set of the database, the log buffer size
-should be large enough to accommodate most transactions without overflowing,
-and the log directory must be on a separate physical disk from the main
-database files. And both the database directory and the log directory
-should be separate from disks used for regular system activities such as
-the root, boot, or swap filesystems. See the FAQ-o-Matic and the Berkeley DB
-documentation for more details.
+* {{F:writemap}}: Use a writable memory map instead of just read-only. This
+speeds up write operations but makes the database vulnerable to corruption in
+case any bugs in slapd cause stray writes into the mmap region.
 
+* {{F:mapasync}}: When using a writable memory map and performing flushes on
+each commit, use an asynchronous flush instead of a synchronous flush (the
+default). This option has no effect if writemap has not been set. It also has
+no effect if nosync is set.
 
-H4: olcDbNosync: { TRUE | FALSE }
-
-This option causes on-disk database contents to not be immediately
-synchronized with in memory changes upon change.  Setting this option
-to {{EX:TRUE}} may improve performance at the expense of data integrity. This
-directive has the same effect as using
->      olcDbConfig: set_flags DB_TXN_NOSYNC
-
-
-H4: olcDbIDLcacheSize: <integer>
-
-Specify the size of the in-memory index cache, in index slots. The
-default is zero. A larger value will speed up frequent searches of
-indexed entries. The optimal size will depend on the data and search
-characteristics of the database, but using a number three times
-the entry cache size is a good starting point.
-
-\Example:
-
->      olcDbIDLcacheSize: 3000
+* {{F:nordahead}}: Turn off file readahead. Usually the OS performs readahead
+on every read request. This usually boosts read performance but can be
+harmful to random access read performance if the system's memory is full and
+the DB is larger than RAM. This option is not implemented on Windows.
 
 
 H4: olcDbIndex: {<attrlist> | default} [pres,eq,approx,sub,none]
@@ -874,7 +821,7 @@ matches do not use an index. However, some attributes do support
 indexing for inequality matches, based on the equality index.
 
 A substring index can be more explicitly specified as {{EX:subinitial}},
-{{EX:subany}}, or {{EX:subfinal}}, corresponding to the three 
+{{EX:subany}}, or {{EX:subfinal}}, corresponding to the three
 possible components
 of a substring match filter. A subinitial index only indexes
 substrings that appear at the beginning of an attribute value.
@@ -890,7 +837,7 @@ attribute that inherits from {{EX:name}} to be indexed.
 By default, no indices are maintained.  It is generally advised
 that minimally an equality index upon objectClass be maintained.
 
->      olcDbindex: objectClass eq
+>      olcDbIndex: objectClass eq
 
 Additional indices should be configured corresponding to the
 most common searches that are used on the database.
@@ -907,18 +854,24 @@ stopped before the index task completes, indexing will have to be
 manually completed using the slapindex tool.
 
 
-H4: olcDbLinearIndex: { TRUE | FALSE }
+H4: olcDbMaxReaders: <integer>
+
+This directive specifies the maximum number of threads that may have
+concurrent read access to the database. Tools such as slapcat count as a
+single thread, in addition to threads in any active slapd processes. The
+default is 126.
+
 
-If this setting is {{EX:TRUE}} slapindex will index one attribute
-at a time. The default settings is {{EX:FALSE}} in which case all
-indexed attributes of an entry are processed at the same time. When
-enabled, each indexed attribute is processed individually, using
-multiple passes through the entire database. This option improves
-slapindex performance when the database size exceeds the BDB cache
-size. When the BDB cache is large enough, this option is not needed
-and will decrease performance. Also by default, slapadd performs
-full indexing and so a separate slapindex run is not needed. With
-this option, slapadd does no indexing and slapindex must be used.
+H4: olcDbMaxSize: <bytes>
+
+This directive specifies the maximum size of the database in bytes. A memory
+map of this size is allocated at startup time and the database will not be
+allowed to grow beyond this size. The default is 10485760 bytes (10MB). This
+setting may be changed upward if the configured limit needs to be increased.
+
+Note: It is important to set this to as large a value as possible, (relative
+to anticipated growth of the actual data over time) since growing the size
+later may not be practical when the system is under heavy load.
 
 
 H4: olcDbMode: { <octal> | <symbolic> }
@@ -932,6 +885,18 @@ created database index files should have. This can be in the form
 >      olcDbMode: 0600
 
 
+H4: olcDbRtxnsize: <entries>
+
+This directive specifies the maximum number of entries to process in a single
+read transaction when executing a large search. Long-lived read transactions
+prevent old database pages from being reused in write transactions, and so
+can cause significant growth of the database file when there is heavy write
+traffic. This setting causes the read transaction in large searches to be
+released and reacquired after the given number of entries has been read, to
+give writers the opportunity to reclaim old database pages. The default is
+10000.
+
+
 H4: olcDbSearchStack: <integer>
 
 Specify the depth of the stack used for search filter evaluation.
@@ -955,33 +920,21 @@ to take effect.
 >      olcDbSearchStack: 16
 
 
-H4: olcDbShmKey: <integer>
-
-Specify a key for a shared memory BDB environment. By default the BDB
-environment uses memory mapped files. If a non-zero value is specified,
-it will be used as the key to identify a shared memory region that will
-house the environment.
-
-\Example:
+H4: olcDbNosync: { TRUE | FALSE }
 
->      olcDbShmKey: 42
+This directive causes on-disk database contents to not be immediately
+synchronized with in memory changes upon change.  Setting this option
+to {{EX:TRUE}} may improve performance at the expense of data integrity.
 
 
 H4: Sample Entry
 
->dn: olcDatabase=hdb,cn=config
+>dn: olcDatabase=mdb,cn=config
 >objectClass: olcDatabaseConfig
->objectClass: olcHdbConfig
->olcDatabase: hdb
+>objectClass: olcMdbConfig
+>olcDatabase: mdb
 >olcSuffix: "dc=example,dc=com"
 >olcDbDirectory: /usr/local/var/openldap-data
->olcDbCacheSize: 1000
->olcDbCheckpoint: 1024 10
->olcDbConfig: set_cachesize 0 10485760 0
->olcDbConfig: set_lg_bsize 2097152
->olcDbConfig: set_lg_dir /var/tmp/bdb-log
->olcDbConfig: set_flags DB_LOG_AUTOREMOVE
->olcDbIDLcacheSize: 3000
 >olcDbIndex: objectClass eq
 
 
@@ -989,7 +942,7 @@ H2: Configuration Example
 
 The following is an example configuration, interspersed
 with explanatory text. It defines two databases to handle
-different parts of the {{TERM:X.500}} tree; both are {{TERM:BDB}}
+different parts of the {{TERM:X.500}} tree; both are {{TERM:MDB}}
 database instances. The line numbers shown are provided for
 reference only and are not included in the actual file. First, the
 global configuration section:
@@ -999,7 +952,7 @@ E:  2.    dn: cn=config
 E:  3.    objectClass: olcGlobal
 E:  4.    cn: config
 E:  5.    olcReferral: ldap://root.openldap.org
-E:  6.    
+E:  6.
 
 Line 1 is a comment. Lines 2-4 identify this as the global
 configuration entry.
@@ -1013,7 +966,7 @@ E:  7.    # internal schema
 E:  8.    dn: cn=schema,cn=config
 E:  9.    objectClass: olcSchemaConfig
 E: 10.    cn: schema
-E: 11.    
+E: 11.
 
 Line 7 is a comment. Lines 8-10 identify this as the root of
 the schema subtree. The actual schema definitions in this entry
@@ -1022,7 +975,7 @@ Line 11 is a blank line, indicating the end of this entry.
 
 E: 12.    # include the core schema
 E: 13.    include: file:///usr/local/etc/openldap/schema/core.ldif
-E: 14.    
+E: 14.
 
 Line 12 is a comment. Line 13 is an LDIF include directive which
 accesses the {{core}} schema definitions in LDIF format. Line 14
@@ -1037,7 +990,7 @@ E: 16.    dn: olcDatabase=frontend,cn=config
 E: 17.    objectClass: olcDatabaseConfig
 E: 18.    olcDatabase: frontend
 E: 19.    olcAccess: to * by * read
-E: 20.    
+E: 20.
 
 Line 15 is a comment. Lines 16-18 identify this entry as the global
 database entry. Line 19 is a global access control. It applies to all
@@ -1066,16 +1019,16 @@ inaccessible.)
 
 Line 28 is a blank line.
 
-The next entry defines a BDB backend that will handle queries for things
+The next entry defines an MDB backend that will handle queries for things
 in the "dc=example,dc=com" portion of the tree. Indices are to be maintained
 for several attributes, and the {{EX:userPassword}} attribute is to be
 protected from unauthorized access.
 
-E: 29.    # BDB definition for example.com
-E: 30.    dn: olcDatabase=bdb,cn=config
+E: 29.    # MDB definition for example.com
+E: 30.    dn: olcDatabase=mdb,cn=config
 E: 31.    objectClass: olcDatabaseConfig
-E: 32.    objectClass: olcBdbConfig
-E: 33.    olcDatabase: bdb
+E: 32.    objectClass: olcMdbConfig
+E: 33.    olcDatabase: mdb
 E: 34.    olcSuffix: dc=example,dc=com
 E: 35.    olcDbDirectory: /usr/local/var/openldap-data
 E: 36.    olcRootDN: cn=Manager,dc=example,dc=com
@@ -1092,9 +1045,9 @@ E: 46.    olcAccess: to *
 E: 47.      by self write
 E: 48.      by dn.base="cn=Admin,dc=example,dc=com" write
 E: 49.      by * read
-E: 50.    
+E: 50.
 
-Line 29 is a comment. Lines 30-33 identify this entry as a BDB database
+Line 29 is a comment. Lines 30-33 identify this entry as a MDB database
 configuration entry.  Line 34 specifies the DN suffix
 for queries to pass to this database. Line 35 specifies the directory
 in which the database files will live.
@@ -1116,16 +1069,16 @@ entry, but may be read by all users (authenticated or not).
 Line 50 is a blank line, indicating the end of this entry.
 
 The next entry defines another
-BDB database. This one handles queries involving the
+MDB database. This one handles queries involving the
 {{EX:dc=example,dc=net}} subtree but is managed by the same entity
 as the first database.  Note that without line 60, the read access
 would be allowed due to the global access rule at line 19.
 
-E: 51.    # BDB definition for example.net
-E: 52.    dn: olcDatabase=bdb,cn=config
+E: 51.    # MDB definition for example.net
+E: 52.    dn: olcDatabase=mdb,cn=config
 E: 53.    objectClass: olcDatabaseConfig
-E: 54.    objectClass: olcBdbConfig
-E: 55.    olcDatabase: bdb
+E: 54.    objectClass: olcMdbConfig
+E: 55.    olcDatabase: mdb
 E: 56.    olcSuffix: "dc=example,dc=net"
 E: 57.    olcDbDirectory: /usr/local/var/openldap-data-net
 E: 58.    olcRootDN: "cn=Manager,dc=example,dc=com"
index ae74062f4274e2b28987b746a5124bc6feb62232..831d5ef36520df282fcbee6e66113a1e7c6ba494 100644 (file)
@@ -90,7 +90,7 @@ H4: access to <what> [ by <who> [<accesslevel>] [<control>] ]+
 
 This directive grants access (specified by <accesslevel>) to a set
 of entries and/or attributes (specified by <what>) by one or more
-requestors (specified by <who>).  See the {{SECT:Access Control}} section of 
+requestors (specified by <who>).  See the {{SECT:Access Control}} section of
 this guide for basic usage.
 
 !if 0
@@ -162,7 +162,7 @@ Level       Keyword         Description
 !endblock
 
 The desired log level can be input as a single integer that
-combines the (ORed) desired levels, both in decimal or in hexadecimal 
+combines the (ORed) desired levels, both in decimal or in hexadecimal
 notation, as a list of integers (that are ORed internally), or as a list of the names that are shown between brackets, such that
 
 >              loglevel 129
@@ -264,9 +264,7 @@ supported backend types listed in Table 6.2.
 !block table; align=Center; coltags="EX,N"; \
        title="Table 6.2: Database Backends"
 Types  Description
-bdb    Berkeley DB transactional backend (deprecated)
 dnssrv DNS SRV backend
-hdb    Hierarchical variant of bdb backend (deprecated)
 ldap   Lightweight Directory Access Protocol (Proxy) backend
 mdb    Memory-Mapped DB backend
 meta   Meta Directory backend
@@ -279,9 +277,9 @@ sql SQL Programmable backend
 
 \Example:
 
->      backend bdb
+>      backend mdb
 
-This marks the beginning of a new {{TERM:BDB}} backend
+This marks the beginning of a new {{TERM:MDB}} backend
 definition.
 
 
@@ -299,9 +297,9 @@ supported backend types listed in Table 6.2.
 
 \Example:
 
->      database bdb
+>      database mdb
 
-This marks the beginning of a new {{TERM:BDB}} database instance
+This marks the beginning of a new {{TERM:MDB}} database instance
 declaration.
 
 
@@ -507,7 +505,7 @@ defaults for these parameters come from {{ldap.conf}}(5).
 The {{EX:binddn}} parameter gives the DN to bind as for the
 syncrepl searches to the provider slapd. It should be a DN
 which has read access to the replication content in the
-master database. 
+master database.
 
 The {{EX:bindmethod}} is {{EX:simple}} or {{EX:sasl}},
 depending on whether simple password-based authentication or
@@ -564,8 +562,7 @@ conforms to the obsolete {{changelog}} format. If the {{EX:syncdata}}
 parameter is omitted or set to {{EX:"default"}} then the log
 parameters are ignored.
 
-The {{syncrepl}} replication mechanism is supported by the {{bdb}},
-{{hdb}}, and {{mdb}} backends.
+The {{syncrepl}} replication mechanism is supported by the {{mdb}} backend.
 
 See the {{SECT:LDAP Sync Replication}} chapter of this guide for
 more information on how to use this directive.
@@ -584,31 +581,207 @@ If specified multiple times, each {{TERM:URL}} is provided.
 >      updateref       ldap://master.example.net
 
 
-H3: BDB and HDB Database Directives
+H3: MDB Database Directives
 
-Directives in this category only apply to both the {{TERM:BDB}}
-and the {{TERM:HDB}} database.
-That is, they must follow a "database bdb" or "database hdb" line
-and come before any
-subsequent "backend" or "database" line.  For a complete reference
-of BDB/HDB configuration directives, see {{slapd-bdb}}(5).
+Directives in this category only apply to the {{TERM:MDB}}
+database backend.
+That is, they must follow a "database mdb" line
+and come before any subsequent "backend" or "database" lines.
+For a complete reference of MDB configuration directives, see {{slapd-mdb}}(5).
 
 
 H4: directory <directory>
 
-This directive specifies the directory where the BDB files
+This directive specifies the directory where the MDB files
 containing the database and associated indices live.
 
 \Default:
 
 >      directory /usr/local/var/openldap-data
 
+H4: checkpoint <kbyte> <min>
+
+This directive specifies the frequency for flushing the database disk
+buffers. This directive is only needed if the {{dbnosync}} option is
+{{EX:TRUE}}.
+The checkpoint will occur if either <kbyte> data has been written or
+<min> minutes have passed since the last checkpoint. Both arguments default
+to zero, in which case they are ignored. When the <min> argument is
+non-zero, an internal task will run every <min> minutes to perform the
+checkpoint. Note: currently the _kbyte_ setting is unimplemented.
+
+\Example:
+
+>   checkpoint: 1024 10
+
+H4: dbnosync: { TRUE | FALSE }
+
+This directive causes on-disk database contents to not be immediately
+synchronized with in memory changes upon change.  Setting this option
+to {{EX:TRUE}} may improve performance at the expense of data integrity.
+
+
+H4: envflags: {nosync,nometasync,writemap,mapasync,nordahead}
+
+This option specifies flags for finer-grained control of  the  LMDB  library's
+operation.
+
+* {{F:nosync}}: This is exactly the same as the dbnosync directive.
+
+* {{F:nometasync}}: Flush the data on a commit, but skip the sync of the meta
+page. This mode is slightly faster than doing a full sync, but can
+potentially lose the last committed transaction if the operating system
+crashes. If both nometasync and nosync are set, the nosync flag takes
+precedence.
+
+* {{F:writemap}}: Use a writable memory map instead of just read-only. This
+speeds up write operations but makes the database vulnerable to corruption in
+case any bugs in slapd cause stray writes into the mmap region.
+
+* {{F:mapasync}}: When using a writable memory map and performing flushes on
+each commit, use an asynchronous flush instead of a synchronous flush (the
+default). This option has no effect if writemap has not been set. It also has
+no effect if nosync is set.
+
+* {{F:nordahead}}: Turn off file readahead. Usually the OS performs readahead
+on every read request. This usually boosts read performance but can be
+harmful to random access read performance if the system's memory is full and
+the DB is larger than RAM. This option is not implemented on Windows.
+
+
+H4: index: {<attrlist> | default} [pres,eq,approx,sub,none]
+
+This directive specifies the indices to maintain for the given
+attribute. If only an {{EX:<attrlist>}} is given, the default
+indices are maintained. The index keywords correspond to the
+common types of matches that may be used in an LDAP search filter.
+
+\Example:
+
+>   index: default pres,eq
+>   index: uid
+>   index: cn,sn pres,eq,sub
+>   index: objectClass eq
+
+The first line sets the default set of indices to maintain to
+present and equality.  The second line causes the default (pres,eq)
+set of indices to be maintained for the {{EX:uid}} attribute type.
+The third line causes present, equality, and substring indices to
+be maintained for {{EX:cn}} and {{EX:sn}} attribute types.  The
+fourth line causes an equality index for the {{EX:objectClass}}
+attribute type.
+
+There is no index keyword for inequality matches. Generally these
+matches do not use an index. However, some attributes do support
+indexing for inequality matches, based on the equality index.
+
+A substring index can be more explicitly specified as {{EX:subinitial}},
+{{EX:subany}}, or {{EX:subfinal}}, corresponding to the three
+possible components
+of a substring match filter. A subinitial index only indexes
+substrings that appear at the beginning of an attribute value.
+A subfinal index only indexes substrings that appear at the end
+of an attribute value, while subany indexes substrings that occur
+anywhere in a value.
+
+Note that by default, setting an index for an attribute also
+affects every subtype of that attribute. E.g., setting an equality
+index on the {{EX:name}} attribute causes {{EX:cn}}, {{EX:sn}}, and every other
+attribute that inherits from {{EX:name}} to be indexed.
+
+By default, no indices are maintained.  It is generally advised
+that minimally an equality index upon objectClass be maintained.
+
+>   index: objectClass eq
+
+Additional indices should be configured corresponding to the
+most common searches that are used on the database.
+Presence indexing should not be configured for an attribute
+unless the attribute occurs very rarely in the database, and
+presence searches on the attribute occur very frequently during
+normal use of the directory. Most applications don't use presence
+searches, so usually presence indexing is not very useful.
+
+
+H4: maxreaders: <integer>
+
+This directive specifies the maximum number of threads that may have
+concurrent read access to the database. Tools such as slapcat count as a
+single thread, in addition to threads in any active slapd processes. The
+default is 126.
+
+
+H4: maxsize: <bytes>
+
+This directive specifies the maximum size of the database in bytes. A memory
+map of this size is allocated at startup time and the database will not be
+allowed to grow beyond this size. The default is 10485760 bytes (10MB). This
+setting may be changed upward if the configured limit needs to be increased.
+
+Note: It is important to set this to as large a value as possible, (relative
+to anticipated growth of the actual data over time) since growing the size
+later may not be practical when the system is under heavy load.
+
+
+H4: mode: { <octal> | <symbolic> }
+
+This directive specifies the file protection mode that newly
+created database index files should have. This can be in the form
+{{EX:0600}} or {{EX:-rw-------}}
+
+\Default:
+
+>   mode: 0600
+
+
+H4: rtxnsize: <entries>
+
+This directive specifies the maximum number of entries to process in a single
+read transaction when executing a large search. Long-lived read transactions
+prevent old database pages from being reused in write transactions, and so
+can cause significant growth of the database file when there is heavy write
+traffic. This setting causes the read transaction in large searches to be
+released and reacquired after the given number of entries has been read, to
+give writers the opportunity to reclaim old database pages. The default is
+10000.
+
+
+H4: searchstack: <integer>
+
+Specify the depth of the stack used for search filter evaluation.
+Search filters are evaluated on a stack to accommodate nested {{EX:AND}} /
+{{EX:OR}} clauses. An individual stack is allocated for each server thread.
+The depth of the stack determines how complex a filter can be evaluated
+without requiring any additional memory allocation. Filters that are
+nested deeper than the search stack depth will cause a separate stack to
+be allocated for that particular search operation. These separate allocations
+can have a major negative impact on server performance, but specifying
+too much stack will also consume a great deal of memory. Each search
+uses 512K bytes per level on a 32-bit machine, or 1024K bytes per level
+on a 64-bit machine. The default stack depth is 16, thus 8MB or 16MB
+per thread is used on 32 and 64 bit machines, respectively. Also the
+512KB size of a single stack slot is set by a compile-time constant which
+may be changed if needed; the code must be recompiled for the change
+to take effect.
+
+\Default:
+
+>   searchstack: 16
+
+
+H4: Sample Entry
+
+>database mdb
+>suffix: "dc=example,dc=com"
+>directory: /usr/local/var/openldap-data
+>index: objectClass eq
+
 
 H2: Configuration File Example
 
 The following is an example configuration file, interspersed
 with explanatory text. It defines two databases to handle
-different parts of the {{TERM:X.500}} tree; both are {{TERM:BDB}}
+different parts of the {{TERM:X.500}} tree; both are {{TERM:MDB}}
 database instances. The line numbers shown are provided for
 reference only and are not included in the actual file. First, the
 global configuration section:
@@ -617,7 +790,7 @@ E:  1.    # example config file - global configuration section
 E:  2.    include /usr/local/etc/schema/core.schema
 E:  3.    referral ldap://root.openldap.org
 E:  4.    access to * by * read
+
 Line 1 is a comment. Line 2 includes another config file
 which contains {{core}} schema definitions.
 The {{EX:referral}} directive on line 3
@@ -629,7 +802,7 @@ Line 4 is a global access control.  It applies to all
 entries (after any applicable database-specific access
 controls).
 
-The next section of the configuration file defines a BDB
+The next section of the configuration file defines a MDB
 backend that will handle queries for things in the
 "dc=example,dc=com" portion of the tree. The
 database is to be replicated to two slave slapds, one on
@@ -637,8 +810,8 @@ truelies, the other on judgmentday. Indices are to be
 maintained for several attributes, and the {{EX:userPassword}}
 attribute is to be protected from unauthorized access.
 
-E:  5.    # BDB definition for the example.com
-E:  6.    database bdb
+E:  5.    # MDB definition for the example.com
+E:  6.    database mdb
 E:  7.    suffix "dc=example,dc=com"
 E:  8.    directory /usr/local/var/openldap-data
 E:  9.    rootdn "cn=Manager,dc=example,dc=com"
@@ -678,13 +851,13 @@ All other attributes are writable by the entry and the "admin"
 entry, but may be read by all users (authenticated or not).
 
 The next section of the example configuration file defines another
-BDB database. This one handles queries involving the
+MDB database. This one handles queries involving the
 {{EX:dc=example,dc=net}} subtree but is managed by the same entity
 as the first database.  Note that without line 39, the read access
 would be allowed due to the global access rule at line 4.
 
-E: 33.    # BDB definition for example.net
-E: 34.    database bdb
+E: 33.    # MDB definition for example.net
+E: 34.    database mdb
 E: 35.    suffix "dc=example,dc=net"
 E: 36.    directory /usr/local/var/openldap-data-net
 E: 37.    rootdn "cn=Manager,dc=example,dc=com"
index 9f72480dec7aa64e7cd092713ef93a7c0f8e23db..376d46d349de6f44cec706ca3be2036b6e3e0e9b 100644 (file)
@@ -27,10 +27,6 @@ H3: Memory
 
 Scale your cache to use available memory and increase system memory if you can.
 
-See {{SECT:Caching}} for BDB cache tuning hints.
-Note that LMDB uses no cache of its own and has no tuning options, so the Caching
-section can be ignored when using LMDB.
-
 
 H3: Disks
 
@@ -39,15 +35,7 @@ types perform best with your workload. (On our own Linux testing, EXT2 and JFS
 tend to provide better write performance than everything else, including
 newer filesystems like EXT4, BTRFS, etc.)
 
-Use fast subsystems. Put each database and logs on separate disks
-(for BDB this is configurable via {{DB_CONFIG}}):
-
->       # Data Directory
->       set_data_dir /data/db
->       
->       # Transaction Log settings
->       set_lg_dir /logs
-
+Use fast subsystems. Put each database on separate disks.
 
 H3: Network Topology
 
@@ -131,7 +119,7 @@ H3: What to watch out for
 
 The most common message you'll see that you should pay attention to is:
 
->       "<= bdb_equality_candidates: (foo) index_param failed (18)"
+>       "<= mdb_equality_candidates: (foo) index_param failed (18)"
 
 That means that some application tried to use an equality filter ({{foo=<somevalue>}}) 
 and attribute {{foo}} does not have an equality index. If you see a lot of these
@@ -163,165 +151,6 @@ For syslog-ng, add or modify the following line in {{syslog-ng.conf}}:
 where n is the number of lines which will be buffered before a write.
 
 
-H2: Caching
-
-We all know what caching is, don't we? 
-
-In brief, "A cache is a block of memory for temporary storage of data likely 
-to be used again" - {{URL:http://en.wikipedia.org/wiki/Cache}}
-
-There are 3 types of caches, BerkeleyDB's own cache, {{slapd}}(8) 
-entry cache and {{TERM:IDL}} (IDL) cache.
-
-
-H3: Berkeley DB Cache
-
-There are two ways to tune for the BDB cachesize:
-
-(a) BDB cache size necessary to load the database via slapadd in optimal time
-
-(b) BDB cache size necessary to have a high performing running slapd once the data is loaded
-
-For (a), the optimal cachesize is the size of the entire database.  If you 
-already have the database loaded, this is simply a 
-
->       du -c -h *.bdb 
-
-in the directory containing the OpenLDAP ({{/usr/local/var/openldap-data}}) data.
-
-For (b), the optimal cachesize is just the size of the {{id2entry.bdb}} file, 
-plus about 10% for growth.
-
-The tuning of {{DB_CONFIG}} should be done for each BDB type database 
-instantiated (back-bdb, back-hdb).
-
-Note that while the {{TERM:BDB}} cache is just raw chunks of memory and 
-configured as a memory size, the {{slapd}}(8) entry cache holds parsed entries, 
-and the size of each entry is variable. 
-
-There is also an IDL cache which is used for Index Data Lookups. 
-If you can fit all of your database into slapd's entry cache, and all of your 
-index lookups fit in the IDL cache, that will provide the maximum throughput. 
-
-If not, but you can fit the entire database into the BDB cache, then you 
-should do that and shrink the slapd entry cache as appropriate. 
-
-Failing that, you should balance the BDB cache against the entry cache.
-
-It is worth noting that it is not absolutely necessary to configure a BerkeleyDB 
-cache equal in size to your entire database. All that you need is a cache 
-that's large enough for your "working set." 
-
-That means, large enough to hold all of the most frequently accessed data, 
-plus a few less-frequently accessed items.
-
-For more information, please see: {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_conf/cachesize.html}}
-
-H4: Calculating Cachesize
-
-The back-bdb database lives in two main files, {{F:dn2id.bdb}} and {{F:id2entry.bdb}}. 
-These are B-tree databases. We have never documented the back-bdb internal 
-layout before, because it didn't seem like something anyone should have to worry 
-about, nor was it necessarily cast in stone. But here's how it works today, 
-in OpenLDAP 2.4.
-
-A B-tree is a balanced tree; it stores data in its leaf nodes and bookkeeping 
-data in its interior nodes (If you don't know what tree data structures look
- like in general, Google for some references, because that's getting far too 
-elementary for the purposes of this discussion).
-
-For decent performance, you need enough cache memory to contain all the nodes 
-along the path from the root of the tree down to the particular data item 
-you're accessing. That's enough cache for a single search. For the general case, 
-you want enough cache to contain all the internal nodes in the database. 
-
->       db_stat -d
-
-will tell you how many internal pages are present in a database. You should 
-check this number for both dn2id and id2entry.
-
-Also note that {{id2entry}} always uses 16KB per "page", while {{dn2id}} uses whatever 
-the underlying filesystem uses, typically 4 or 8KB. To avoid thrashing,
-your cache must be at least as large as the number of internal pages in both 
-the {{dn2id}} and {{id2entry}} databases, plus some extra space to accommodate
-the actual leaf data pages.
-
-For example, in my OpenLDAP 2.4 test database, I have an input LDIF file that's 
-about 360MB. With the back-hdb backend this creates a {{dn2id.bdb}} that's 68MB, 
-and an {{id2entry}} that's 800MB. db_stat tells me that {{dn2id}} uses 4KB pages, has 
-433 internal pages, and 6378 leaf pages. The id2entry uses 16KB pages, has 52 
-internal pages, and 45912 leaf pages. In order to efficiently retrieve any 
-single entry in this database, the cache should be at least
-
->       (433+1) * 4KB + (52+1) * 16KB in size: 1736KB + 848KB =~ 2.5MB.
-
-This doesn't take into account other library overhead, so this is even lower 
-than the barest minimum. The default cache size, when nothing is configured, 
-is only 256KB. 
-
-This 2.5MB number also doesn't take indexing into account. Each indexed
-attribute results in another database file.  Earlier versions of OpenLDAP
-kept these index databases in Hash format, but from OpenLDAP 2.2 onward
-the index databases are in B-tree format so the same procedure can
-be used to calculate the necessary amount of cache for each index database.
-
-For example, if your only index is for the objectClass attribute and db_stat
-reveals that {{objectClass.bdb}} has 339 internal pages and uses 4096 byte
-pages, the additional cache needed for just this attribute index is
-
->       (339+1) * 4KB =~ 1.3MB.
-
-With only this index enabled, I'd figure at least a 4MB cache for this backend. 
-(Of course you're using a single cache shared among all of the database files, 
-so the cache pages will most likely get used for something other than what you 
-accounted for, but this gives you a fighting chance.)
-
-With this 4MB cache I can slapcat this entire database on my 1.3GHz PIII in 
-1 minute, 40 seconds. With the cache doubled to 8MB, it still takes the same 1:40s. 
-Once you've got enough cache to fit the B-tree internal pages, increasing it 
-further won't have any effect until the cache really is large enough to hold 
-100% of the data pages. I don't have enough free RAM to hold all the 800MB 
-id2entry data, so 4MB is good enough.
-
-With back-bdb and back-hdb you can use "db_stat -m" to check how well the 
-database cache is performing. 
-
-For more information on {{db_stat}}: {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/utility/db_stat.html}}
-
-H3: {{slapd}}(8) Entry Cache (cachesize)
-
-The {{slapd}}(8) entry cache operates on decoded entries. The rationale - entries 
-in the entry cache can be used directly, giving the fastest response. If an entry 
-isn't in the entry cache but can be extracted from the BDB page cache, that will 
-avoid an I/O but it will still require parsing, so this will be slower. 
-
-If the entry is in neither cache then BDB will have to flush some of its current 
-cached pages and bring in the needed pages, resulting in a couple of expensive 
-I/Os as well as parsing.
-
-The most optimal value is of course, the entire number of entries in the database.  
-However, most directory servers don't consistently serve out their entire database, so setting this to a lesser number that more closely matches the believed working set of data is 
-sufficient. This is the second most important parameter for the DB.
-
-As far as balancing the entry cache vs the BDB cache - parsed entries in memory 
-are generally about twice as large as they are on disk. 
-
-As we have already mentioned, not having a proper database cache size will 
-cause performance issues. These issues are not an indication of corruption 
-occurring in the database. It is merely the fact that the cache is thrashing 
-itself that causes performance/response time to slowdown. 
-
-
-H3: {{TERM:IDL}} Cache (idlcachesize)
-
-Each IDL holds the search results from a given query, so the IDL cache will 
-end up holding the most frequently requested search results.  For back-bdb, 
-it is generally recommended to match the "cachesize" setting.  For back-hdb, 
-it is generally recommended to be 3x"cachesize".
-
-{NOTE: The idlcachesize setting directly affects search performance}
-
-
 H2: {{slapd}}(8) Threads
 
 {{slapd}}(8) can process requests via a configurable number of threads, which
index dc60b1d9e7fbe5e33a5d20968c1b25a9172d96b9..ba39141687eefb5a0dfc7f56b1335e3186243644 100644 (file)
@@ -167,7 +167,6 @@ AuthcId|Authentication Identity
 AuthzDN|Authorization DN
 AuthzId|Authorization Identity
 BCP|Best Current Practice
-BDB|Berkeley DB (Backend)
 BER|Basic Encoding Rules
 BNF|Backus-Naur Form
 C|The C Programming Language
@@ -201,7 +200,6 @@ FYI|For Your Information
 GSER|Generic String Encoding Rules
 GSS-API|Generic Security Service Application Program Interface
 GSSAPI|SASL Kerberos V GSS-API Authentication Mechanism
-HDB|Hierarchical Database (Backend)
 I-D|Internet-Draft
 IA5|International Alphabet 5
 IDNA|Internationalized Domain Names in Applications
index ee1d3ce7b06959b501fdc6bdb3953a925d22034f..268d163766668496905af20b350b20e8a0c5a1f7 100644 (file)
@@ -84,7 +84,7 @@ if you have not done so already.
 + Test the standalone system:
 
 .This step requires the standalone LDAP server, {{slapd}}(8),
-with {{HDB}} and/or {{BDB}} support.
+with {{MDB}} support.
 
 E:     % make test
 
diff --git a/doc/man/man5/slapd-bdb.5 b/doc/man/man5/slapd-bdb.5
deleted file mode 100644 (file)
index d5e1a7e..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-.TH SLAPD-BDB 5 "RELEASEDATE" "OpenLDAP LDVERSION"
-.\" Copyright 1998-2019 The OpenLDAP Foundation All Rights Reserved.
-.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
-.\" $OpenLDAP$
-.SH NAME
-slapd\-bdb, slapd\-hdb \- Berkeley DB backends to slapd
-.SH SYNOPSIS
-.B ETCDIR/slapd.conf
-.SH DESCRIPTION
-The \fBbdb\fP backend to
-.BR slapd (8)
-uses the Oracle Berkeley DB (BDB) package to store data.
-It makes extensive use of indexing and caching to speed data access.
-.LP
-Note that BDB is deprecated and support will be dropped in future
-OpenLDAP releases. Installations should use the \fBmdb\fP
-backend instead.
-.LP
-\fBhdb\fP is a variant of
-the \fBbdb\fP backend that uses a hierarchical database layout which
-supports subtree renames. It is both more space-efficient and more
-execution-efficient than the \fBbdb\fP backend.  It is otherwise identical
-to the \fBbdb\fP behavior, and all the same configuration options apply.
-.LP
-It is noted that these options are intended to complement
-Berkeley DB configuration options set in the environment's
-.B DB_CONFIG
-file.  See Berkeley DB documentation for details on
-.B DB_CONFIG
-configuration options.
-Where there is overlap, settings in
-.B DB_CONFIG
-take precedence.
-.SH CONFIGURATION
-These
-.B slapd.conf
-options apply to the \fBbdb\fP and \fBhdb\fP backend database.
-That is, they must follow a "database bdb" or "database hdb" line and
-come before any subsequent "backend" or "database" lines.
-Other database options are described in the
-.BR slapd.conf (5)
-manual page.
-.TP
-.BI cachesize \ <integer>
-Specify the size in entries of the in-memory entry cache maintained 
-by the \fBbdb\fP or \fBhdb\fP backend database instance.
-The default is 1000 entries.
-.TP
-.BI cachefree \ <integer>
-Specify the number of entries to free from the entry cache when the
-cache reaches the \fBcachesize\fP limit.
-The default is 1 entry.
-.TP
-.BI checkpoint \ <kbyte>\ <min>
-Specify the frequency for checkpointing the database transaction log.
-A checkpoint operation flushes the database buffers to disk and writes
-a checkpoint record in the log.
-The checkpoint will occur if either \fI<kbyte>\fP data has been written or
-\fI<min>\fP minutes have passed since the last checkpoint.
-Both arguments default to zero, in which case they are ignored. When
-the \fI<min>\fP argument is non-zero, an internal task will run every 
-\fI<min>\fP minutes to perform the checkpoint.
-See the Berkeley DB reference guide for more details.
-.TP
-.B checksum
-Enable checksum validation of DB pages whenever they are read from disk.
-This setting can only be configured before any database files are created.
-.TP
-.BI cryptfile \ <file>
-Specify the pathname of a file containing an encryption key to use for
-encrypting the database. Encryption is performed using Berkeley DB's
-implementation of AES. Note that encryption can only be configured before
-any database files are created, and changing the key can only be done
-after destroying the current database and recreating it. Encryption is
-not enabled by default, and some distributions of Berkeley DB do not
-support encryption.
-.TP
-.BI cryptkey \ <key>
-Specify an encryption key to use for encrypting the database. This option
-may be used when a separate
-.I cryptfile
-is not desired. Only one of
-.B cryptkey
-or
-.B cryptfile
-may be configured.
-.TP
-.BI dbconfig \ <Berkeley-DB-setting>
-Specify a configuration directive to be placed in the
-.B DB_CONFIG
-file of the database directory. The
-.B dbconfig
-directive is just a convenience
-to allow all necessary configuration to be set in the
-.B slapd.conf
-file.
-The options set using this directive will only be written to the 
-.B DB_CONFIG
-file if no such file existed at server startup time, otherwise
-they are completely ignored. This allows one
-to set initial values without overwriting/destroying a 
-.B DB_CONFIG 
-file that was already customized through other means. 
-This directive may be specified multiple times, as needed. 
-For example:
-.RS
-.nf
-       dbconfig set_cachesize 0 1048576 0
-       dbconfig set_lg_bsize 2097152
-.fi
-.RE
-.TP
-.B dbnosync
-Specify that on-disk database contents should not be immediately
-synchronized with in memory changes.
-Enabling this option may improve performance at the expense of data
-security.
-See the Berkeley DB reference guide for more details.
-.TP
-\fBdbpagesize \fR \fI<dbfile> <size>\fR
-Specify the page size to use for a particular database file, in units
-of 1024 bytes. The default for the
-.B id2entry
-file is 16, the default for all other files depends on the size of the
-underlying filesystem's block size (typically 4 or 8).
-The maximum that BerkeleyDB supports is 64. This
-setting usually should not need to be changed, but if BerkeleyDB's
-"db_stat \-d" shows a large amount of overflow pages in use in a file,
-setting a larger size may increase performance at the expense of
-data integrity. This setting only takes effect when a database is
-being newly created. See the Berkeley DB reference guide for more details.
-.TP
-.BI directory \ <directory>
-Specify the directory where the BDB files containing this database and
-associated indexes live.
-A separate directory must be specified for each database.
-The default is
-.BR LOCALSTATEDIR/openldap\-data .
-.TP
-.B dirtyread
-Allow reads of modified but not yet committed data.
-Usually transactions are isolated to prevent other operations from
-accessing uncommitted data.
-This option may improve performance, but may also return inconsistent
-results if the data comes from a transaction that is later aborted.
-In this case, the modified data is discarded and a subsequent search
-will return a different result.
-.TP
-.BI dncachesize \ <integer>
-Specify the maximum number of DNs in the in-memory DN cache.
-Ideally this cache should be
-large enough to contain the DNs of every entry in the database. If
-set to a smaller value than the \fBcachesize\fP it will be silently
-increased to equal the \fBcachesize\fP. The default value is 0 which
-means unlimited, i.e. the DN cache will grow without bound.
-
-It should be noted that the \fBDN cache\fP is allowed to temporarily
-grow beyond the configured size. It does this if many entries are 
-locked when it tries to do a purge, because that means they're
-legitimately in use. Also, the \fBDN cache\fP never purges entries
-that have cached children, so depending on the shape of the DIT, it 
-could have lots of cached DNs over the defined limit.
-.TP
-.BI idlcachesize \ <integer>
-Specify the size of the in-memory index cache, in index slots. The
-default is zero. A larger value will speed up frequent searches of
-indexed entries. An \fBhdb\fP database needs a large \fBidlcachesize\fP
-for good search performance, typically three times the 
-.B cachesize
-(entry cache size)
-or larger.
-.TP
-\fBindex \fR{\fI<attrlist>\fR|\fBdefault\fR} [\fBpres\fR,\fBeq\fR,\fBapprox\fR,\fBsub\fR,\fI<special>\fR]
-Specify the indexes to maintain for the given attribute (or
-list of attributes).
-Some attributes only support a subset of indexes.
-If only an \fI<attr>\fP is given, the indices specified for \fBdefault\fR
-are maintained.
-Note that setting a default does not imply that all attributes will be
-indexed. Also, for best performance, an
-.B eq
-index should always be configured for the
-.B objectClass
-attribute.
-
-A number of special index parameters may be specified.
-The index type
-.B sub
-can be decomposed into
-.BR subinitial ,
-.BR subany ,\ and
-.B subfinal
-indices.
-The special type
-.B nolang
-may be specified to disallow use of this index by language subtypes.
-The special type
-.B nosubtypes
-may be specified to disallow use of this index by named subtypes.
-Note: changing \fBindex\fP settings in 
-.BR slapd.conf (5)
-requires rebuilding indices, see
-.BR slapindex (8);
-changing \fBindex\fP settings
-dynamically by LDAPModifying "cn=config" automatically causes rebuilding
-of the indices online in a background task.
-.TP
-.B linearindex
-Tell 
-.B slapindex 
-to index one attribute at a time. By default, all indexed
-attributes in an entry are processed at the same time. With this option,
-each indexed attribute is processed individually, using multiple passes
-through the entire database. This option improves 
-.B slapindex 
-performance
-when the database size exceeds the \fBdbcache\fP size. When the \fBdbcache\fP is
-large enough, this option is not needed and will decrease performance.
-Also by default, 
-.B slapadd 
-performs full indexing and so a separate 
-.B slapindex
-run is not needed. With this option, 
-.B slapadd 
-does no indexing and 
-.B slapindex
-must be used.
-.TP
-.BR lockdetect \ { oldest | youngest | fewest | random | default }
-Specify which transaction to abort when a deadlock is detected.
-The default is
-.BR random .
-.TP
-.BI mode \ <integer>
-Specify the file protection mode that newly created database 
-index files should have.
-The default is 0600.
-.TP
-.BI searchstack \ <depth>
-Specify the depth of the stack used for search filter evaluation.
-Search filters are evaluated on a stack to accommodate nested AND / OR
-clauses. An individual stack is assigned to each server thread.
-The depth of the stack determines how complex a filter can be
-evaluated without requiring any additional memory allocation. Filters that
-are nested deeper than the search stack depth will cause a separate
-stack to be allocated for that particular search operation. These
-allocations can have a major negative impact on server performance,
-but specifying too much stack will also consume a great deal of memory.
-Each search stack uses 512K bytes per level. The default stack depth
-is 16, thus 8MB per thread is used.
-.TP
-.BI shm_key \ <integer>
-Specify a key for a shared memory BDB environment. By default the
-BDB environment uses memory mapped files. If a non-zero value is
-specified, it will be used as the key to identify a shared memory
-region that will house the environment.
-.SH ACCESS CONTROL
-The 
-.B bdb
-and
-.B hdb
-backends honor access control semantics as indicated in
-.BR slapd.access (5).
-.SH FILES
-.TP
-.B ETCDIR/slapd.conf
-default 
-.B slapd 
-configuration file
-.TP
-.B DB_CONFIG
-Berkeley DB configuration file
-.SH SEE ALSO
-.BR slapd.conf (5),
-.BR slapd\-config (5),
-.BR slapd\-mdb (5),
-.BR slapd (8),
-.BR slapadd (8),
-.BR slapcat (8),
-.BR slapindex (8),
-Berkeley DB documentation.
-.SH ACKNOWLEDGEMENTS
-.so ../Project
-Originally begun by Kurt Zeilenga. Caching mechanisms originally designed
-by Jong-Hyuk Choi. Completion and subsequent work, as well as
-back-hdb, by Howard Chu.
diff --git a/doc/man/man5/slapd-bdb.5.links b/doc/man/man5/slapd-bdb.5.links
deleted file mode 100644 (file)
index 3bc8c40..0000000
+++ /dev/null
@@ -1 +0,0 @@
-slapd-hdb.5
index b7773793f43cf13b6c5fc5b6fc228b965e3dea7b..f080e7bb61c9a1e04dd0924b86677fb28fb04c73 100644 (file)
@@ -1149,10 +1149,8 @@ The entry must be named
 and must have the olcBackendConfig objectClass.
 <databasetype>
 should be one of
-.BR bdb ,
 .BR config ,
 .BR dnssrv ,
-.BR hdb ,
 .BR ldap ,
 .BR ldif ,
 .BR mdb ,
@@ -2091,10 +2089,10 @@ olcDatabase: config
 olcRootPW: {SSHA}XKYnrjvGT3wZFQrDD5040US592LxsdLy
 olcAccess: to * by * none
 
-dn: olcDatabase=bdb,cn=config
+dn: olcDatabase=mdb,cn=config
 objectClass: olcDatabaseConfig
-objectClass: olcBdbConfig
-olcDatabase: bdb
+objectClass: olcMdbConfig
+olcDatabase: mdb
 olcSuffix: "dc=our\-domain,dc=com"
 # The database directory MUST exist prior to
 # running slapd AND should only be accessible
index e609e4e9a8eb0fb25555cfb14fb0e2e669753ab4..85f7235b176cd075613dafc9da81eb3d29cb4117 100644 (file)
@@ -14,11 +14,8 @@ It relies completely on the underlying operating system for memory
 management and does no caching of its own. It is the recommended
 primary database backend.
 .LP
-The \fBmdb\fP backend is similar to the \fBhdb\fP backend in that
-it uses a hierarchical database layout which
-supports subtree renames. It is both more space-efficient and more
-execution-efficient than the \fBbdb\fP backend, while being overall
-much simpler to manage.
+The \fBmdb\fP backend uses a hierarchical database layout which
+supports subtree renames.
 .SH CONFIGURATION
 These
 .B slapd.conf
index 9bb13b9d8734078243b3453750fe67061199843e..8e1f40be79711a6e93bb72aa3be6d8ec15b814a9 100644 (file)
@@ -19,7 +19,7 @@ sites/applications that use RDBMSes and/or LDAP.
 Or whatever else...
 .LP
 It is NOT designed as a general-purpose backend that uses RDBMS instead
-of BerkeleyDB (as the standard BDB backend does), though it can be
+of LMDB (as the standard MDB backend does), though it can be
 used as such with several limitations.
 You can take a look at
 .B http://www.openldap.org/faq/index.cgi?file=378 
index c7ea94017061ed459c6119026a22287918b8cacd..d8dd649131256df1e2ca832516718f7688ec005d 100644 (file)
@@ -920,9 +920,8 @@ identity, control is passed straight to the subsequent rules.
 
 .SH OPERATION REQUIREMENTS
 Operations require different privileges on different portions of entries.
-The following summary applies to primary MDB database backend and the
-deprecated BDB and HDB backends.   Requirements for other backends may
-(and often do) differ.
+The following summary applies to primary MDB database backend. Requirements
+for other backends may (and often do) differ.
 
 .LP
 The
@@ -1085,9 +1084,7 @@ Access control to search entries is checked by the frontend,
 so it is fully honored by all backends; for all other operations
 and for the discovery phase of the search operation,
 full ACL semantics is only supported by the primary backends, i.e.
-.BR back\-bdb (5),
-and
-.BR back\-hdb (5).
+.BR back\-mdb (5).
 
 Some other backend, like
 .BR back\-sql (5),
index e01574411d737b91a923ccb4b872b3b9f5074e2e..363b97f559b76168036f80e79436646c06e7c311 100644 (file)
@@ -19,14 +19,6 @@ corresponding
 .BR slapd\-<backend> (5)
 manual pages.
 .TP
-.B bdb
-This was the recommended primary backend through OpenLDAP 2.3, but it has
-since been superseded by the
-.BR mdb
-backend.  It takes care to configure it properly.
-It uses the transactional database interface of the Oracle Berkeley
-DB (BDB) package to store data.
-.TP
 .B config
 This backend is used to manage the configuration of slapd at run-time.
 Unlike other backends, only a single instance of the
@@ -41,22 +33,6 @@ This backend is experimental.
 It serves up referrals based upon SRV resource records held in the
 Domain Name System.
 .TP
-.B hdb
-This was the recommended primary backend through OpenLDAP 2.4.40 but it has
-since been superseded by the
-.BR mdb
-backend.  It takes care to configure it properly.
-.B hdb
-is a variant of the
-.B bdb
-backend that uses a hierarchical database
-layout.
-This layout stores entry DNs more efficiently than the
-.B bdb
-backend,
-using less space and requiring less work to create, delete, and rename
-entries. It is also one of the few backends to support subtree renames.
-.TP
 .B ldap
 This backend acts as a proxy to forward incoming requests to another
 LDAP server.
@@ -68,14 +44,9 @@ Its usage should be limited to very simple databases, where performance
 is not a requirement. This backend also supports subtree renames.
 .TP
 .B mdb
-This is the recommended primary backend, superseding
-.BR hdb .
+This is the recommended primary backend.
 This backend uses OpenLDAP's own MDB transactional database
-library. It is extremely compact and extremely efficient, delivering
-much higher performance than the Berkeley DB backends while using
-significantly less memory.  Also, unlike Berkeley DB, MDB is crash proof,
-and requires no special tuning or maintenance.
-This backend also supports subtree renames.
+library.  This backend also supports subtree renames.
 .TP
 .B meta
 This backend performs basic LDAP proxying with respect to a set of
@@ -138,10 +109,8 @@ ETCDIR/slapd.d
 default slapd configuration directory
 .SH SEE ALSO
 .BR ldap (3),
-.BR slapd\-bdb (5),
 .BR slapd\-config (5),
 .BR slapd\-dnssrv (5),
-.BR slapd\-hdb (5),
 .BR slapd\-ldap (5),
 .BR slapd\-ldif (5),
 .BR slapd\-mdb (5),
index 74295a481b9255e8d63ddb4cbdfd10b2569ed325..c0451167a23852c68d7437c286b4dfaa71182d58 100644 (file)
@@ -1276,10 +1276,8 @@ type of backend.
 .B backend <databasetype>
 Mark the beginning of a backend definition. <databasetype>
 should be one of
-.BR bdb ,
 .BR config ,
 .BR dnssrv ,
-.BR hdb ,
 .BR ldap ,
 .BR ldif ,
 .BR mdb ,
@@ -1306,10 +1304,8 @@ option are mandatory for each database.
 .B database <databasetype>
 Mark the beginning of a new database instance definition. <databasetype>
 should be one of
-.BR bdb ,
 .BR config ,
 .BR dnssrv ,
-.BR hdb ,
 .BR ldap ,
 .BR ldif ,
 .BR mdb ,
@@ -1619,8 +1615,7 @@ By default, mirrormode is off.
 This option enables database-specific monitoring in the entry related
 to the current database in the "cn=Databases,cn=Monitor" subtree 
 of the monitor database, if the monitor database is enabled.
-Currently, only the BDB and the HDB databases provide database-specific
-monitoring.
+Currently, only the MDB database provides database-specific monitoring.
 The default depends on the backend type.
 .TP
 .B overlay <overlay-name>
index f49346e2453f8abd27e89fb6ff31b12b4457d7ca..c67ad391dd6ff78057439999d0b25d8aa55254b4 100644 (file)
@@ -91,7 +91,7 @@ password resets, etc.
 .B refint
 Referential Integrity.
 This overlay can be used with a backend database such as
-.BR slapd\-bdb (5)
+.BR slapd\-mdb (5)
 to maintain the cohesiveness of a schema which utilizes reference
 attributes.
 .TP
@@ -121,7 +121,7 @@ replication, including persistent search functionality.
 .B translucent
 Translucent Proxy.
 This overlay can be used with a backend database such as
-.BR slapd\-bdb (5)
+.BR slapd\-mdb (5)
 to create a "translucent proxy".
 Content of entries retrieved from a remote LDAP server can be partially
 overridden by the database.
@@ -129,7 +129,7 @@ overridden by the database.
 .B unique
 Attribute Uniqueness.
 This overlay can be used with a backend database such as
-.BR slapd\-bdb (5)
+.BR slapd\-mdb (5)
 to enforce the uniqueness of some or all attributes within a subtree.
 .TP
 .B valsort
index c2592438caa1554cb39dfff2ef086ad005a291ef..7292e79f3b3211312bc7e9d1258df8f68f4c42e1 100644 (file)
@@ -8,7 +8,7 @@ slapo\-refint \- Referential Integrity overlay to slapd
 ETCDIR/slapd.conf
 .SH DESCRIPTION
 The Referential Integrity overlay can be used with a backend database such as
-.BR slapd\-bdb (5)
+.BR slapd\-mdb (5)
 to maintain the cohesiveness of a schema which utilizes reference attributes.
 .LP
 Integrity is maintained by updating database records which contain the named
index 3e20006b99516f9e9857f61596125f83a55678b7..88350f2d17133e684cf659a83babe5fc5236ff72 100644 (file)
@@ -8,7 +8,7 @@ slapo\-translucent \- Translucent Proxy overlay to slapd
 ETCDIR/slapd.conf
 .SH DESCRIPTION
 The Translucent Proxy overlay can be used with a backend database such as
-.BR slapd\-bdb (5)
+.BR slapd\-mdb (5)
 to create a "translucent proxy".  Entries retrieved from a remote LDAP
 server may have some or all attributes overridden, or new attributes
 added, by entries in the local database before being presented to the
index 3b0af48737ee708488a2f69fa3d65ce8d508d5f8..0a94122ece2c8535f38b723ecf2b54b9bb652d1b 100644 (file)
@@ -177,8 +177,6 @@ mode) when you do this to ensure consistency of the database. It is
 always safe to run 
 .B slapcat
 with the
-.BR slapd\-bdb (5),
-.BR slapd\-hdb (5),
 .BR slapd\-mdb (5),
 and
 .BR slapd\-null (5)
index 8b4b4acf4b857c072f7be0d80a0a7f1245eb52d6..dae8dbd65f5a923d93777cb601e809a8fc5df4e6 100644 (file)
@@ -168,8 +168,7 @@ mode) when you do this to ensure consistency of the database. It is
 always safe to run 
 .B slapschema
 with the
-.BR slapd\-bdb (5),
-.BR slapd\-hdb (5),
+.BR slapd\-mdb (5),
 and
 .BR slapd\-null (5)
 backends.
index 9775c0589a86efaf0c8a57f5d03fd5764d19d29c..97929a16a85791972c3c04d2d09b5f7710a55492 100644 (file)
 /* Define to 1 if you have the `bcopy' function. */
 #undef HAVE_BCOPY
 
-/* define this if Berkeley DB is available */
-#undef HAVE_BERKELEY_DB
-
-/* define if Berkeley DB has DB_THREAD support */
-#undef HAVE_BERKELEY_DB_THREAD
-
 /* Define to 1 if you have the <bits/types.h> header file. */
 #undef HAVE_BITS_TYPES_H
 
 /* define to support LDAP Async Metadirectory backend */
 #undef SLAPD_ASYNCMETA
 
-/* define to support BDB backend */
-#undef SLAPD_BDB
-
 /* define to support cleartext passwords */
 #undef SLAPD_CLEARTEXT
 
 /* define to support DNS SRV backend */
 #undef SLAPD_DNSSRV
 
-/* define to support HDB backend */
-#undef SLAPD_HDB
-
 /* define to support LDAP backend */
 #undef SLAPD_LDAP
 
diff --git a/servers/slapd/DB_CONFIG b/servers/slapd/DB_CONFIG
deleted file mode 100644 (file)
index d0f2c68..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# $OpenLDAP$
-# Example DB_CONFIG file for use with slapd(8) BDB/HDB databases.
-#
-# See the Oracle Berkeley DB documentation
-#   <http://www.oracle.com/technology/documentation/berkeley-db/db/ref/env/db_config.html>
-# for detail description of DB_CONFIG syntax and semantics.
-#
-# Hints can also be found in the OpenLDAP Software FAQ
-#      <http://www.openldap.org/faq/index.cgi?file=2>
-# in particular:
-#   <http://www.openldap.org/faq/index.cgi?file=1075>
-
-# Note: most DB_CONFIG settings will take effect only upon rebuilding
-# the DB environment.
-
-# one 0.25 GB cache
-set_cachesize 0 268435456 1
-
-# Data Directory
-#set_data_dir db
-
-# Transaction Log settings
-set_lg_regionmax 262144
-set_lg_bsize 2097152
-#set_lg_dir logs
-
-# Note: special DB_CONFIG flags are no longer needed for "quick"
-# slapadd(8) or slapindex(8) access (see their -q option). 
index 7136fb2765f187caeb6dd74f71d7ab22ed71f230..3c42653d2c553f803ca1b21a28763ef753019c1e 100644 (file)
@@ -38,7 +38,7 @@ SRCS  = main.c globals.c bconfig.c config.c daemon.c \
                backglue.c backover.c ctxcsn.c ldapsync.c frontend.c \
                slapadd.c slapcat.c slapcommon.c slapdn.c slapindex.c \
                slappasswd.c slaptest.c slapauth.c slapacl.c component.c \
-               aci.c alock.c txn.c slapschema.c slapmodify.c \
+               aci.c txn.c slapschema.c slapmodify.c \
                $(@PLAT@_SRCS)
 
 OBJS   = main.o globals.o bconfig.o config.o daemon.o \
@@ -56,7 +56,7 @@ OBJS  = main.o globals.o bconfig.o config.o daemon.o \
                backglue.o backover.o ctxcsn.o ldapsync.o frontend.o \
                slapadd.o slapcat.o slapcommon.o slapdn.o slapindex.o \
                slappasswd.o slaptest.o slapauth.o slapacl.o component.o \
-               aci.o alock.o txn.o slapschema.o slapmodify.o \
+               aci.o txn.o slapschema.o slapmodify.o \
                $(@PLAT@_OBJS)
 
 LDAP_INCDIR= ../../include -I$(srcdir) -I$(srcdir)/slapi -I.
@@ -366,14 +366,8 @@ veryclean-local-srv: FORCE
                fi; \
        done
 
-install-dbc-maybe: install-dbc-@BUILD_BDB@ install-dbc-@BUILD_HDB@
-
-install-dbc-yes:       install-db-config
-install-dbc-mod:       install-db-config
-install-dbc-no:
-
 install-local-srv: install-slapd install-tools \
-       install-conf install-dbc-maybe install-schema install-tools
+       install-conf install-schema install-tools
 
 install-slapd: FORCE
        -$(MKDIR) $(DESTDIR)$(libexecdir)
diff --git a/servers/slapd/alock.c b/servers/slapd/alock.c
deleted file mode 100644 (file)
index 1e54684..0000000
+++ /dev/null
@@ -1,718 +0,0 @@
-/* alock.c - access lock library */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2005-2019 The OpenLDAP Foundation.
- * Portions Copyright 2004-2005 Symas Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was initially developed by Emily Backes at Symas
- * Corporation for inclusion in OpenLDAP Software.
- */
-
-#include "portable.h"
-
-#if SLAPD_BDB || SLAPD_HDB
-
-#include <lber.h>
-#include "alock.h"
-#include "lutil.h"
-
-#include <ac/stdlib.h>
-#include <ac/string.h>
-#include <ac/unistd.h>
-#include <ac/errno.h>
-#include <ac/assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_SYS_FILE_H
-#include <sys/file.h>
-#endif
-#include <fcntl.h>
-
-#ifdef _WIN32
-#include <windows.h>
-#include <stdio.h>
-#include <io.h>
-#endif
-
-
-static int
-alock_grab_lock ( int fd, int slot )
-{
-       int res;
-       
-#if defined( HAVE_LOCKF )
-       res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET);
-       if (res == -1) return -1;
-       res = lockf (fd, F_LOCK, (off_t) ALOCK_SLOT_SIZE);
-#elif defined( HAVE_FCNTL )
-       struct flock lock_info;
-       (void) memset ((void *) &lock_info, 0, sizeof (struct flock));
-
-       lock_info.l_type = F_WRLCK;
-       lock_info.l_whence = SEEK_SET;
-       lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot);
-       lock_info.l_len = (off_t) ALOCK_SLOT_SIZE;
-
-       res = fcntl (fd, F_SETLKW, &lock_info);
-#elif defined( _WIN32 )
-       OVERLAPPED ov;
-       HANDLE hh = _get_osfhandle ( fd );
-       ov.hEvent = 0;
-       ov.Offset = ALOCK_SLOT_SIZE*slot;
-       ov.OffsetHigh = 0;
-       res = LockFileEx( hh, LOCKFILE_EXCLUSIVE_LOCK, 0,
-               ALOCK_SLOT_SIZE, 0, &ov ) ? 0 : -1;
-#else
-#   error alock needs lockf, fcntl, or LockFile[Ex]
-#endif
-       if (res == -1) {
-               assert (errno != EDEADLK);
-               return -1;
-       }
-       return 0;
-}
-
-static int
-alock_release_lock ( int fd, int slot )
-{
-       int res;
-       
-#if defined( HAVE_LOCKF )
-       res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET);
-       if (res == -1) return -1;
-       res = lockf (fd, F_ULOCK, (off_t) ALOCK_SLOT_SIZE);
-       if (res == -1) return -1;
-#elif defined ( HAVE_FCNTL )
-       struct flock lock_info;
-       (void) memset ((void *) &lock_info, 0, sizeof (struct flock));
-
-       lock_info.l_type = F_UNLCK;
-       lock_info.l_whence = SEEK_SET;
-       lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot);
-       lock_info.l_len = (off_t) ALOCK_SLOT_SIZE;
-
-       res = fcntl (fd, F_SETLKW, &lock_info);
-       if (res == -1) return -1;
-#elif defined( _WIN32 )
-       HANDLE hh = _get_osfhandle ( fd );
-       if ( !UnlockFile ( hh, ALOCK_SLOT_SIZE*slot, 0,
-               ALOCK_SLOT_SIZE, 0 ))
-               return -1;
-#else
-#   error alock needs lockf, fcntl, or LockFile[Ex]
-#endif
-
-       return 0;
-}
-
-static int
-alock_share_lock ( int fd, int slot )
-{
-       int res;
-
-#if defined( HAVE_LOCKF )
-       res = 0;        /* lockf has no shared locks */
-#elif defined ( HAVE_FCNTL )
-       struct flock lock_info;
-       (void) memset ((void *) &lock_info, 0, sizeof (struct flock));
-
-       /* The shared lock replaces the existing lock */
-       lock_info.l_type = F_RDLCK;
-       lock_info.l_whence = SEEK_SET;
-       lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot);
-       lock_info.l_len = (off_t) ALOCK_SLOT_SIZE;
-
-       res = fcntl (fd, F_SETLK, &lock_info);
-       if (res == -1) return -1;
-#elif defined( _WIN32 )
-       OVERLAPPED ov;
-       HANDLE hh = _get_osfhandle ( fd );
-
-       /* Windows locks are mandatory, not advisory.
-        * We must downgrade the lock to allow future
-        * callers to read the slot data.
-        *
-        * First acquire a shared lock. Unlock will
-        * release the existing exclusive lock.
-        */
-       ov.hEvent = 0;
-       ov.Offset = ALOCK_SLOT_SIZE*slot;
-       ov.OffsetHigh = 0;
-       LockFileEx (hh, 0, 0, ALOCK_SLOT_SIZE, 0, &ov);
-       UnlockFile (hh, ALOCK_SLOT_SIZE*slot, 0, ALOCK_SLOT_SIZE, 0);
-#else
-#   error alock needs lockf, fcntl, or LockFile[Ex]
-#endif
-
-       return 0;
-}
-
-static int
-alock_test_lock ( int fd, int slot )
-{
-       int res;
-
-#if defined( HAVE_LOCKF )
-       res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET);
-       if (res == -1) return -1;
-
-       res = lockf (fd, F_TEST, (off_t) ALOCK_SLOT_SIZE);
-       if (res == -1) {
-               if (errno == EACCES || errno == EAGAIN) { 
-                       return ALOCK_LOCKED;
-               } else {
-                       return -1;
-               }
-       }
-#elif defined( HAVE_FCNTL )
-       struct flock lock_info;
-       (void) memset ((void *) &lock_info, 0, sizeof (struct flock));
-
-       lock_info.l_type = F_WRLCK;
-       lock_info.l_whence = SEEK_SET;
-       lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot);
-       lock_info.l_len = (off_t) ALOCK_SLOT_SIZE;
-
-       res = fcntl (fd, F_GETLK, &lock_info);
-       if (res == -1) return -1;
-
-       if (lock_info.l_type != F_UNLCK) return ALOCK_LOCKED;
-#elif defined( _WIN32 )
-       OVERLAPPED ov;
-       HANDLE hh = _get_osfhandle ( fd );
-       ov.hEvent = 0;
-       ov.Offset = ALOCK_SLOT_SIZE*slot;
-       ov.OffsetHigh = 0;
-       if( !LockFileEx( hh,
-               LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, 0,
-               ALOCK_SLOT_SIZE, 0, &ov )) {
-               int err = GetLastError();
-               if ( err == ERROR_LOCK_VIOLATION )
-                       return ALOCK_LOCKED;
-               else
-                       return -1;
-       }
-#else
-#   error alock needs lockf, fcntl, or LockFile
-#endif
-       
-       return 0;
-}
-
-/* Read a 64bit LE value */
-static unsigned long int
-alock_read_iattr ( unsigned char * bufptr )
-{
-       unsigned long int val = 0;
-       int count;
-
-       assert (bufptr != NULL);
-
-       bufptr += sizeof (unsigned long int);
-       for (count=0; count <= (int) sizeof (unsigned long int); ++count) {
-               val <<= 8;
-               val += (unsigned long int) *bufptr--;
-       }
-
-       return val;
-}
-
-/* Write a 64bit LE value */
-static void
-alock_write_iattr ( unsigned char * bufptr,
-                   unsigned long int val )
-{
-       int count;
-
-       assert (bufptr != NULL);
-
-       for (count=0; count < 8; ++count) {
-               *bufptr++ = (unsigned char) (val & 0xff);
-               val >>= 8;
-       }
-}
-
-static int
-alock_read_slot ( alock_info_t * info,
-                 alock_slot_t * slot_data )
-{
-       unsigned char slotbuf [ALOCK_SLOT_SIZE];
-       int res, size, size_total, err;
-
-       assert (info != NULL);
-       assert (slot_data != NULL);
-       assert (info->al_slot > 0);
-
-       res = lseek (info->al_fd, 
-                    (off_t) (ALOCK_SLOT_SIZE * info->al_slot), 
-                    SEEK_SET);
-       if (res == -1) return -1;
-
-       size_total = 0;
-       while (size_total < ALOCK_SLOT_SIZE) {
-               size = read (info->al_fd, 
-                            slotbuf + size_total, 
-                            ALOCK_SLOT_SIZE - size_total);
-               if (size == 0) return -1;
-               if (size < 0) {
-                       err = errno;
-                       if (err != EINTR && err != EAGAIN) return -1;
-               } else {
-                       size_total += size;
-               }
-       }
-       
-       if (alock_read_iattr (slotbuf) != ALOCK_MAGIC) {
-               return -1;
-       }
-       slot_data->al_lock  = alock_read_iattr (slotbuf+8);
-       slot_data->al_stamp = alock_read_iattr (slotbuf+16);
-       slot_data->al_pid   = alock_read_iattr (slotbuf+24);
-
-       if (slot_data->al_appname) ber_memfree (slot_data->al_appname);
-       slot_data->al_appname = ber_memcalloc (1, ALOCK_MAX_APPNAME);
-       if (slot_data->al_appname == NULL) {
-               return -1;
-       }
-       strncpy (slot_data->al_appname, (char *)slotbuf+32, ALOCK_MAX_APPNAME-1);
-       (slot_data->al_appname) [ALOCK_MAX_APPNAME-1] = '\0';
-
-       return 0;
-}
-
-static int
-alock_write_slot ( alock_info_t * info,
-                  alock_slot_t * slot_data )
-{
-       unsigned char slotbuf [ALOCK_SLOT_SIZE];
-       int res, size, size_total, err;
-
-       assert (info != NULL);
-       assert (slot_data != NULL);
-       assert (info->al_slot > 0);
-
-       (void) memset ((void *) slotbuf, 0, ALOCK_SLOT_SIZE);
-       
-       alock_write_iattr (slotbuf,    ALOCK_MAGIC);
-       assert (alock_read_iattr (slotbuf) == ALOCK_MAGIC);
-       alock_write_iattr (slotbuf+8,  slot_data->al_lock);
-       alock_write_iattr (slotbuf+16, slot_data->al_stamp);
-       alock_write_iattr (slotbuf+24, slot_data->al_pid);
-
-       if (slot_data->al_appname)
-               strncpy ((char *)slotbuf+32, slot_data->al_appname, ALOCK_MAX_APPNAME-1);
-       slotbuf[ALOCK_SLOT_SIZE-1] = '\0';
-
-       res = lseek (info->al_fd, 
-                    (off_t) (ALOCK_SLOT_SIZE * info->al_slot),
-                    SEEK_SET);
-       if (res == -1) return -1;
-
-       size_total = 0;
-       while (size_total < ALOCK_SLOT_SIZE) {
-               size = write (info->al_fd, 
-                             slotbuf + size_total, 
-                             ALOCK_SLOT_SIZE - size_total);
-               if (size == 0) return -1;
-               if (size < 0) {
-                       err = errno;
-                       if (err != EINTR && err != EAGAIN) return -1;
-               } else {
-                       size_total += size;
-               }
-       }
-       
-       return 0;
-}
-
-static int
-alock_query_slot ( alock_info_t * info )
-{
-       int res, nosave;
-       alock_slot_t slot_data;
-
-       assert (info != NULL);
-       assert (info->al_slot > 0);
-       
-       (void) memset ((void *) &slot_data, 0, sizeof (alock_slot_t));
-       alock_read_slot (info, &slot_data);
-
-       if (slot_data.al_appname != NULL) ber_memfree (slot_data.al_appname);
-       slot_data.al_appname = NULL;
-
-       nosave = slot_data.al_lock & ALOCK_NOSAVE;
-
-       if ((slot_data.al_lock & ALOCK_SMASK) == ALOCK_UNLOCKED)
-               return slot_data.al_lock;
-
-       res = alock_test_lock (info->al_fd, info->al_slot);
-       if (res < 0) return -1;
-       if (res > 0) {
-               if ((slot_data.al_lock & ALOCK_SMASK) == ALOCK_UNIQUE) {
-                       return slot_data.al_lock;
-               } else {
-                       return ALOCK_LOCKED | nosave;
-               }
-       }
-       
-       return ALOCK_DIRTY | nosave;
-}
-
-int 
-alock_open ( alock_info_t * info,
-            const char * appname,
-            const char * envdir,
-            int locktype )
-{
-       struct stat statbuf;
-       alock_info_t scan_info;
-       alock_slot_t slot_data;
-       char * filename;
-       int res, max_slot;
-       int dirty_count, live_count, nosave;
-       char *ptr;
-
-       assert (info != NULL);
-       assert (appname != NULL);
-       assert (envdir != NULL);
-       assert ((locktype & ALOCK_SMASK) >= 1 && (locktype & ALOCK_SMASK) <= 2);
-
-       slot_data.al_lock = locktype;
-       slot_data.al_stamp = time(NULL);
-       slot_data.al_pid = getpid();
-       slot_data.al_appname = ber_memcalloc (1, ALOCK_MAX_APPNAME);
-       if (slot_data.al_appname == NULL) {
-               return ALOCK_UNSTABLE;
-       }
-       strncpy (slot_data.al_appname, appname, ALOCK_MAX_APPNAME-1);
-       slot_data.al_appname [ALOCK_MAX_APPNAME-1] = '\0';
-
-       filename = ber_memcalloc (1, strlen (envdir) + strlen ("/alock") + 1);
-       if (filename == NULL ) {
-               ber_memfree (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-       ptr = lutil_strcopy(filename, envdir);
-       lutil_strcopy(ptr, "/alock");
-#ifdef _WIN32
-       { HANDLE handle = CreateFile (filename, GENERIC_READ|GENERIC_WRITE,
-               FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
-               FILE_ATTRIBUTE_NORMAL, NULL);
-               info->al_fd = _open_osfhandle (handle, 0);
-       }
-#else
-       info->al_fd = open (filename, O_CREAT|O_RDWR, 0666);
-#endif
-       ber_memfree (filename);
-       if (info->al_fd < 0) {
-               ber_memfree (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-       info->al_slot = 0;
-
-       res = alock_grab_lock (info->al_fd, 0);
-       if (res == -1) { 
-               close (info->al_fd);
-               ber_memfree (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-
-       res = fstat (info->al_fd, &statbuf);
-       if (res == -1) { 
-               close (info->al_fd);
-               ber_memfree (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-
-       max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE;
-       dirty_count = 0;
-       live_count = 0;
-       nosave = 0;
-       scan_info.al_fd = info->al_fd;
-       for (scan_info.al_slot = 1; 
-            scan_info.al_slot < max_slot;
-            ++ scan_info.al_slot) {
-               if (scan_info.al_slot != info->al_slot) {
-                       res = alock_query_slot (&scan_info);
-
-                       if (res & ALOCK_NOSAVE) {
-                               nosave = ALOCK_NOSAVE;
-                               res ^= ALOCK_NOSAVE;
-                       }
-                       if (res == ALOCK_UNLOCKED
-                           && info->al_slot == 0) {
-                               info->al_slot = scan_info.al_slot;
-
-                       } else if (res == ALOCK_LOCKED) {
-                               ++live_count;
-
-                       } else if (res == ALOCK_UNIQUE
-                               && (( locktype & ALOCK_SMASK ) == ALOCK_UNIQUE
-                               || nosave )) {
-                               close (info->al_fd);
-                               ber_memfree (slot_data.al_appname);
-                               return ALOCK_BUSY;
-
-                       } else if (res == ALOCK_DIRTY) {
-                               ++dirty_count;
-
-                       } else if (res == -1) {
-                               close (info->al_fd);
-                               ber_memfree (slot_data.al_appname);
-                               return ALOCK_UNSTABLE;
-
-                       }
-               }
-       }
-
-       if (dirty_count && live_count) {
-               close (info->al_fd);
-               ber_memfree (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-       
-       if (info->al_slot == 0) info->al_slot = max_slot + 1;
-       res = alock_grab_lock (info->al_fd,
-                              info->al_slot);
-       if (res == -1) { 
-               close (info->al_fd);
-               ber_memfree (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-       res = alock_write_slot (info, &slot_data);
-       ber_memfree (slot_data.al_appname);
-       if (res == -1) { 
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-       alock_share_lock (info->al_fd, info->al_slot);
-
-       res = alock_release_lock (info->al_fd, 0);
-       if (res == -1) { 
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-       
-       if (dirty_count) return ALOCK_RECOVER | nosave;
-       return ALOCK_CLEAN | nosave;
-}
-
-int 
-alock_scan ( alock_info_t * info )
-{
-       struct stat statbuf;
-       alock_info_t scan_info;
-       int res, max_slot;
-       int dirty_count, live_count, nosave;
-
-       assert (info != NULL);
-
-       scan_info.al_fd = info->al_fd;
-
-       res = alock_grab_lock (info->al_fd, 0);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       res = fstat (info->al_fd, &statbuf);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE;
-       dirty_count = 0;
-       live_count = 0;
-       nosave = 0;
-       for (scan_info.al_slot = 1; 
-            scan_info.al_slot < max_slot;
-            ++ scan_info.al_slot) {
-               if (scan_info.al_slot != info->al_slot) {
-                       res = alock_query_slot (&scan_info);
-
-                       if (res & ALOCK_NOSAVE) {
-                               nosave = ALOCK_NOSAVE;
-                               res ^= ALOCK_NOSAVE;
-                       }
-
-                       if (res == ALOCK_LOCKED) {
-                               ++live_count;
-                               
-                       } else if (res == ALOCK_DIRTY) {
-                               ++dirty_count;
-
-                       } else if (res == -1) {
-                               close (info->al_fd);
-                               return ALOCK_UNSTABLE;
-
-                       }
-               }
-       }
-
-       res = alock_release_lock (info->al_fd, 0);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       if (dirty_count) {
-               if (live_count) {
-                       close (info->al_fd);
-                       return ALOCK_UNSTABLE;
-               } else {
-                       return ALOCK_RECOVER | nosave;
-               }
-       }
-       
-       return ALOCK_CLEAN | nosave;
-}
-
-int
-alock_close ( alock_info_t * info, int nosave )
-{
-       alock_slot_t slot_data;
-       int res;
-
-       if ( !info->al_slot )
-               return ALOCK_CLEAN;
-
-       (void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t));
-
-       res = alock_grab_lock (info->al_fd, 0);
-       if (res == -1) {
-fail:
-               /* Windows doesn't clean up locks immediately when a process exits.
-                * Make sure we release our locks, to prevent stale locks from
-                * hanging around.
-                */
-               alock_release_lock (info->al_fd, 0);
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       /* mark our slot as clean */
-       res = alock_read_slot (info, &slot_data);
-       if (res == -1) {
-               if (slot_data.al_appname != NULL) 
-                       ber_memfree (slot_data.al_appname);
-               goto fail;
-       }
-       slot_data.al_lock = ALOCK_UNLOCKED;
-       if ( nosave )
-               slot_data.al_lock |= ALOCK_NOSAVE;
-       /* since we have slot 0 locked, we don't need our slot lock */
-       res = alock_release_lock (info->al_fd, info->al_slot);
-       if (res == -1) {
-               goto fail;
-       }
-       res = alock_write_slot (info, &slot_data);
-       if (res == -1) {
-               if (slot_data.al_appname != NULL) 
-                       ber_memfree (slot_data.al_appname);
-               goto fail;
-       }
-       if (slot_data.al_appname != NULL) {
-               ber_memfree (slot_data.al_appname);
-               slot_data.al_appname = NULL;
-       }
-
-       res = alock_release_lock (info->al_fd, 0);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       res = close (info->al_fd);
-       if (res == -1) return ALOCK_UNSTABLE;
-       
-       return ALOCK_CLEAN;
-}
-
-int 
-alock_recover ( alock_info_t * info )
-{
-       struct stat statbuf;
-       alock_slot_t slot_data;
-       alock_info_t scan_info;
-       int res, max_slot;
-
-       assert (info != NULL);
-
-       scan_info.al_fd = info->al_fd;
-
-       (void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t));
-
-       res = alock_grab_lock (info->al_fd, 0);
-       if (res == -1) {
-               goto fail;
-       }
-
-       res = fstat (info->al_fd, &statbuf);
-       if (res == -1) {
-               goto fail;
-       }
-
-       max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE;
-       for (scan_info.al_slot = 1; 
-            scan_info.al_slot < max_slot;
-            ++ scan_info.al_slot) {
-               if (scan_info.al_slot != info->al_slot) {
-                       res = alock_query_slot (&scan_info) & ~ALOCK_NOSAVE;
-
-                       if (res == ALOCK_LOCKED
-                           || res == ALOCK_UNIQUE) {
-                               /* recovery attempt on an active db? */
-                               goto fail;
-                               
-                       } else if (res == ALOCK_DIRTY) {
-                               /* mark it clean */
-                               res = alock_read_slot (&scan_info, &slot_data);
-                               if (res == -1) {
-                                       goto fail;
-                               }
-                               slot_data.al_lock = ALOCK_UNLOCKED;
-                               res = alock_write_slot (&scan_info, &slot_data);
-                               if (res == -1) {
-                                       if (slot_data.al_appname != NULL) 
-                                               ber_memfree (slot_data.al_appname);
-                                       goto fail;
-                               }
-                               if (slot_data.al_appname != NULL) {
-                                       ber_memfree (slot_data.al_appname);
-                                       slot_data.al_appname = NULL;
-                               }
-                               
-                       } else if (res == -1) {
-                               goto fail;
-
-                       }
-               }
-       }
-
-       res = alock_release_lock (info->al_fd, 0);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       return ALOCK_CLEAN;
-
-fail:
-       alock_release_lock (info->al_fd, 0);
-       close (info->al_fd);
-       return ALOCK_UNSTABLE;
-}
-
-#endif /* SLAPD_BDB || SLAPD_HDB */
diff --git a/servers/slapd/alock.h b/servers/slapd/alock.h
deleted file mode 100644 (file)
index 0a98b38..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/* alock.h - access lock header */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2005-2019 The OpenLDAP Foundation.
- * Portions Copyright 2004-2005 Symas Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was initially developed by Emily Backes at Symas
- * Corporation for inclusion in OpenLDAP Software.
- */
-
-#ifndef _ALOCK_H_
-#define _ALOCK_H_
-
-#include "portable.h"
-#include <ac/time.h>
-#include <ac/unistd.h>
-
-/* environment states (all the slots together) */
-#define ALOCK_CLEAN            (0)
-#define ALOCK_RECOVER  (1)
-#define ALOCK_BUSY             (2)
-#define ALOCK_UNSTABLE (3)
-
-/* lock user types and states */
-#define ALOCK_UNLOCKED (0)
-#define ALOCK_LOCKED   (1)
-#define ALOCK_UNIQUE   (2)
-#define ALOCK_DIRTY            (3)
-
-#define ALOCK_SMASK            3
-
-/* lock/state where recovery is not available */
-#define        ALOCK_NOSAVE    4
-
-/* constants */
-#define ALOCK_SLOT_SIZE                (1024)
-#define ALOCK_SLOT_IATTRS      (4)
-#define ALOCK_MAX_APPNAME      (ALOCK_SLOT_SIZE - 8 * ALOCK_SLOT_IATTRS)
-#define ALOCK_MAGIC                    (0x12345678)
-
-LDAP_BEGIN_DECL
-
-typedef struct alock_info {
-       int al_fd;
-       int al_slot;
-} alock_info_t;
-
-typedef struct alock_slot {
-       unsigned int al_lock;
-       time_t al_stamp;
-       pid_t al_pid;
-       char * al_appname;
-} alock_slot_t;
-
-LDAP_SLAPD_F (int) alock_open LDAP_P(( alock_info_t * info, const char * appname,
-       const char * envdir, int locktype ));
-LDAP_SLAPD_F (int) alock_scan LDAP_P(( alock_info_t * info ));
-LDAP_SLAPD_F (int) alock_close LDAP_P(( alock_info_t * info, int nosave ));
-LDAP_SLAPD_F (int) alock_recover LDAP_P(( alock_info_t * info ));
-
-LDAP_END_DECL
-
-#endif
diff --git a/servers/slapd/back-bdb/Makefile.in b/servers/slapd/back-bdb/Makefile.in
deleted file mode 100644 (file)
index fcbb309..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-# Makefile.in for back-bdb
-# $OpenLDAP$
-## This work is part of OpenLDAP Software <http://www.openldap.org/>.
-##
-## Copyright 1998-2019 The OpenLDAP Foundation.
-## All rights reserved.
-##
-## Redistribution and use in source and binary forms, with or without
-## modification, are permitted only as authorized by the OpenLDAP
-## Public License.
-##
-## A copy of this license is available in the file LICENSE in the
-## top-level directory of the distribution or, alternatively, at
-## <http://www.OpenLDAP.org/license.html>.
-
-SRCS = init.c tools.c config.c \
-       add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
-       extended.c referral.c operational.c \
-       attr.c index.c key.c dbcache.c filterindex.c \
-       dn2entry.c dn2id.c error.c id2entry.c idl.c \
-       nextid.c cache.c trans.c monitor.c
-
-OBJS = init.lo tools.lo config.lo \
-       add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
-       extended.lo referral.lo operational.lo \
-       attr.lo index.lo key.lo dbcache.lo filterindex.lo \
-       dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo \
-       nextid.lo cache.lo trans.lo monitor.lo
-
-LDAP_INCDIR= ../../../include       
-LDAP_LIBDIR= ../../../libraries
-
-BUILD_OPT = "--enable-bdb"
-BUILD_MOD = @BUILD_BDB@
-
-mod_DEFS = -DSLAPD_IMPORT
-MOD_DEFS = $(@BUILD_BDB@_DEFS)
-MOD_LIBS = $(BDB_LIBS)
-
-shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA)
-NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS)
-UNIX_LINK_LIBS = $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS)
-
-LIBBASE = back_bdb
-
-XINCPATH = -I.. -I$(srcdir)/..
-XDEFS = $(MODULES_CPPFLAGS)
-
-all-local-lib: ../.backend
-
-../.backend: lib$(LIBBASE).a
-       @touch $@
-
diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c
deleted file mode 100644 (file)
index 631dcd4..0000000
+++ /dev/null
@@ -1,506 +0,0 @@
-/* add.c - ldap BerkeleyDB back-end add routine */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-
-int
-bdb_add(Operation *op, SlapReply *rs )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       struct berval   pdn;
-       Entry           *p = NULL, *oe = op->ora_e;
-       EntryInfo       *ei;
-       char textbuf[SLAP_TEXT_BUFLEN];
-       size_t textlen = sizeof textbuf;
-       AttributeDescription *children = slap_schema.si_ad_children;
-       AttributeDescription *entry = slap_schema.si_ad_entry;
-       DB_TXN          *ltid = NULL, *lt2;
-       ID eid = NOID;
-       struct bdb_op_info opinfo = {{{ 0 }}};
-       int subentry;
-       DB_LOCK         lock;
-
-       int             num_retries = 0;
-       int             success;
-
-       LDAPControl **postread_ctrl = NULL;
-       LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
-       int num_ctrls = 0;
-
-       Debug(LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_add) ": %s\n",
-               op->ora_e->e_name.bv_val );
-
-#ifdef LDAP_X_TXN
-       if( op->o_txnSpec && txn_preop( op, rs ))
-               return rs->sr_err;
-#endif
-
-       ctrls[num_ctrls] = 0;
-
-       /* check entry's schema */
-       rs->sr_err = entry_schema_check( op, op->ora_e, NULL,
-               get_relax(op), 1, NULL, &rs->sr_text, textbuf, textlen );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": entry failed schema check: "
-                       "%s (%d)\n", rs->sr_text, rs->sr_err );
-               goto return_results;
-       }
-
-       /* add opattrs to shadow as well, only missing attrs will actually
-        * be added; helps compatibility with older OL versions */
-       rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": entry failed op attrs add: "
-                       "%s (%d)\n", rs->sr_text, rs->sr_err );
-               goto return_results;
-       }
-
-       if ( get_assert( op ) &&
-               ( test_filter( op, op->ora_e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
-       {
-               rs->sr_err = LDAP_ASSERTION_FAILED;
-               goto return_results;
-       }
-
-       subentry = is_entry_subentry( op->ora_e );
-
-       if( 0 ) {
-retry: /* transaction retry */
-               if( p ) {
-                       /* free parent and reader lock */
-                       if ( p != (Entry *)&slap_entry_root ) {
-                               bdb_unlocked_cache_return_entry_r( bdb, p );
-                       }
-                       p = NULL;
-               }
-               rs->sr_err = TXN_ABORT( ltid );
-               ltid = NULL;
-               LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-               opinfo.boi_oe.oe_key = NULL;
-               op->o_do_not_cache = opinfo.boi_acl_cache;
-               if( rs->sr_err != 0 ) {
-                       rs->sr_err = LDAP_OTHER;
-                       rs->sr_text = "internal error";
-                       goto return_results;
-               }
-               if ( op->o_abandon ) {
-                       rs->sr_err = SLAPD_ABANDON;
-                       goto return_results;
-               }
-               bdb_trans_backoff( ++num_retries );
-       }
-
-       /* begin transaction */
-       {
-               int tflags = bdb->bi_db_opflags;
-               if ( get_lazyCommit( op ))
-                       tflags |= DB_TXN_NOSYNC;
-               rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, &ltid, tflags );
-       }
-       rs->sr_text = NULL;
-       if( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": txn_begin failed: %s (%d)\n",
-                       db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": txn1 id: %x\n",
-               ltid->id(ltid) );
-
-       opinfo.boi_oe.oe_key = bdb;
-       opinfo.boi_txn = ltid;
-       opinfo.boi_err = 0;
-       opinfo.boi_acl_cache = op->o_do_not_cache;
-       LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next );
-
-       /*
-        * Get the parent dn and see if the corresponding entry exists.
-        */
-       if ( be_issuffix( op->o_bd, &op->ora_e->e_nname ) ) {
-               pdn = slap_empty_bv;
-       } else {
-               dnParent( &op->ora_e->e_nname, &pdn );
-       }
-
-       /* get entry or parent */
-       rs->sr_err = bdb_dn2entry( op, ltid, &op->ora_e->e_nname, &ei,
-               1, &lock );
-       switch( rs->sr_err ) {
-       case 0:
-               rs->sr_err = LDAP_ALREADY_EXISTS;
-               goto return_results;
-       case DB_NOTFOUND:
-               break;
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               goto retry;
-       case LDAP_BUSY:
-               rs->sr_text = "ldap server busy";
-               goto return_results;
-       default:
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-
-       p = ei->bei_e;
-       if ( !p )
-               p = (Entry *)&slap_entry_root;
-
-       if ( !bvmatch( &pdn, &p->e_nname ) ) {
-               rs->sr_matched = ber_strdup_x( p->e_name.bv_val,
-                       op->o_tmpmemctx );
-               rs->sr_ref = is_entry_referral( p )
-                       ? get_entry_referrals( op, p )
-                       : NULL;
-               if ( p != (Entry *)&slap_entry_root )
-                       bdb_unlocked_cache_return_entry_r( bdb, p );
-               p = NULL;
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": parent "
-                       "does not exist\n" );
-
-               rs->sr_err = LDAP_REFERRAL;
-               rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
-               goto return_results;
-       }
-
-       rs->sr_err = access_allowed( op, p,
-               children, NULL, ACL_WADD, NULL );
-
-       if ( ! rs->sr_err ) {
-               switch( opinfo.boi_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-
-               if ( p != (Entry *)&slap_entry_root )
-                       bdb_unlocked_cache_return_entry_r( bdb, p );
-               p = NULL;
-
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": no write access to parent\n" );
-               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-               rs->sr_text = "no write access to parent";
-               goto return_results;;
-       }
-
-       if ( p != (Entry *)&slap_entry_root ) {
-               if ( is_entry_subentry( p ) ) {
-                       bdb_unlocked_cache_return_entry_r( bdb, p );
-                       p = NULL;
-                       /* parent is a subentry, don't allow add */
-                       Debug( LDAP_DEBUG_TRACE,
-                               LDAP_XSTRING(bdb_add) ": parent is subentry\n" );
-                       rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION;
-                       rs->sr_text = "parent is a subentry";
-                       goto return_results;;
-               }
-
-               if ( is_entry_alias( p ) ) {
-                       bdb_unlocked_cache_return_entry_r( bdb, p );
-                       p = NULL;
-                       /* parent is an alias, don't allow add */
-                       Debug( LDAP_DEBUG_TRACE,
-                               LDAP_XSTRING(bdb_add) ": parent is alias\n" );
-                       rs->sr_err = LDAP_ALIAS_PROBLEM;
-                       rs->sr_text = "parent is an alias";
-                       goto return_results;;
-               }
-
-               if ( is_entry_referral( p ) ) {
-                       /* parent is a referral, don't allow add */
-                       rs->sr_matched = ber_strdup_x( p->e_name.bv_val,
-                               op->o_tmpmemctx );
-                       rs->sr_ref = get_entry_referrals( op, p );
-                       bdb_unlocked_cache_return_entry_r( bdb, p );
-                       p = NULL;
-                       Debug( LDAP_DEBUG_TRACE,
-                               LDAP_XSTRING(bdb_add) ": parent is referral\n" );
-
-                       rs->sr_err = LDAP_REFERRAL;
-                       rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
-                       goto return_results;
-               }
-
-       }
-
-       if ( subentry ) {
-               /* FIXME: */
-               /* parent must be an administrative point of the required kind */
-       }
-
-       /* free parent and reader lock */
-       if ( p != (Entry *)&slap_entry_root ) {
-               if ( p->e_nname.bv_len ) {
-                       struct berval ppdn;
-
-                       /* ITS#5326: use parent's DN if differs from provided one */
-                       dnParent( &op->ora_e->e_name, &ppdn );
-                       if ( !dn_match( &p->e_name, &ppdn ) ) {
-                               struct berval rdn;
-                               struct berval newdn;
-
-                               dnRdn( &op->ora_e->e_name, &rdn );
-
-                               build_new_dn( &newdn, &p->e_name, &rdn, NULL ); 
-                               if ( op->ora_e->e_name.bv_val != op->o_req_dn.bv_val )
-                                       ber_memfree( op->ora_e->e_name.bv_val );
-                               op->ora_e->e_name = newdn;
-
-                               /* FIXME: should check whether
-                                * dnNormalize(newdn) == e->e_nname ... */
-                       }
-               }
-
-               bdb_unlocked_cache_return_entry_r( bdb, p );
-       }
-       p = NULL;
-
-       rs->sr_err = access_allowed( op, op->ora_e,
-               entry, NULL, ACL_WADD, NULL );
-
-       if ( ! rs->sr_err ) {
-               switch( opinfo.boi_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": no write access to entry\n" );
-               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-               rs->sr_text = "no write access to entry";
-               goto return_results;;
-       }
-
-       /* 
-        * Check ACL for attribute write access
-        */
-       if (!acl_check_modlist(op, oe, op->ora_modlist)) {
-               switch( opinfo.boi_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": no write access to attribute\n" );
-               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-               rs->sr_text = "no write access to attribute";
-               goto return_results;;
-       }
-
-       if ( eid == NOID ) {
-               rs->sr_err = bdb_next_id( op->o_bd, &eid );
-               if( rs->sr_err != 0 ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               LDAP_XSTRING(bdb_add) ": next_id failed (%d)\n",
-                               rs->sr_err );
-                       rs->sr_err = LDAP_OTHER;
-                       rs->sr_text = "internal error";
-                       goto return_results;
-               }
-               op->ora_e->e_id = eid;
-       }
-
-       /* nested transaction */
-       rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, &lt2, 
-               bdb->bi_db_opflags );
-       rs->sr_text = NULL;
-       if( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": txn_begin(2) failed: "
-                       "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": txn2 id: %x\n",
-               lt2->id(lt2) );
-
-       /* dn2id index */
-       rs->sr_err = bdb_dn2id_add( op, lt2, ei, op->ora_e );
-       if ( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": dn2id_add failed: %s (%d)\n",
-                       db_strerror(rs->sr_err), rs->sr_err );
-
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               case DB_KEYEXIST:
-                       rs->sr_err = LDAP_ALREADY_EXISTS;
-                       break;
-               default:
-                       rs->sr_err = LDAP_OTHER;
-               }
-               goto return_results;
-       }
-
-       /* attribute indexes */
-       rs->sr_err = bdb_index_entry_add( op, lt2, op->ora_e );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": index_entry_add failed\n" );
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               default:
-                       rs->sr_err = LDAP_OTHER;
-               }
-               rs->sr_text = "index generation failed";
-               goto return_results;
-       }
-
-       /* id2entry index */
-       rs->sr_err = bdb_id2entry_add( op->o_bd, lt2, op->ora_e );
-       if ( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": id2entry_add failed\n" );
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               default:
-                       rs->sr_err = LDAP_OTHER;
-               }
-               rs->sr_text = "entry store failed";
-               goto return_results;
-       }
-
-       if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "txn_commit(2) failed";
-               goto return_results;
-       }
-
-       /* post-read */
-       if( op->o_postread ) {
-               if( postread_ctrl == NULL ) {
-                       postread_ctrl = &ctrls[num_ctrls++];
-                       ctrls[num_ctrls] = NULL;
-               }
-               if ( slap_read_controls( op, rs, op->ora_e,
-                       &slap_post_read_bv, postread_ctrl ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<=- " LDAP_XSTRING(bdb_add) ": post-read "
-                               "failed!\n" );
-                       if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
-                               /* FIXME: is it correct to abort
-                                * operation if control fails? */
-                               goto return_results;
-                       }
-               }
-       }
-
-       if ( op->o_noop ) {
-               if (( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
-                       rs->sr_text = "txn_abort (no-op) failed";
-               } else {
-                       rs->sr_err = LDAP_X_NO_OPERATION;
-                       ltid = NULL;
-                       goto return_results;
-               }
-
-       } else {
-               struct berval nrdn;
-
-               /* pick the RDN if not suffix; otherwise pick the entire DN */
-               if (pdn.bv_len) {
-                       nrdn.bv_val = op->ora_e->e_nname.bv_val;
-                       nrdn.bv_len = pdn.bv_val - op->ora_e->e_nname.bv_val - 1;
-               } else {
-                       nrdn = op->ora_e->e_nname;
-               }
-
-               bdb_cache_add( bdb, ei, op->ora_e, &nrdn, ltid, &lock );
-
-               if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
-                       rs->sr_text = "txn_commit failed";
-               } else {
-                       rs->sr_err = LDAP_SUCCESS;
-               }
-       }
-
-       ltid = NULL;
-       LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-       opinfo.boi_oe.oe_key = NULL;
-
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": %s : %s (%d)\n",
-                       rs->sr_text, db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-               goto return_results;
-       }
-
-       Debug(LDAP_DEBUG_TRACE,
-               LDAP_XSTRING(bdb_add) ": added%s id=%08lx dn=\"%s\"\n",
-               op->o_noop ? " (no-op)" : "",
-               op->ora_e->e_id, op->ora_e->e_dn );
-
-       rs->sr_text = NULL;
-       if( num_ctrls ) rs->sr_ctrls = ctrls;
-
-return_results:
-       success = rs->sr_err;
-       send_ldap_result( op, rs );
-
-       if( ltid != NULL ) {
-               TXN_ABORT( ltid );
-       }
-       if ( opinfo.boi_oe.oe_key ) {
-               LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-       }
-
-       if( success == LDAP_SUCCESS ) {
-               /* We own the entry now, and it can be purged at will
-                * Check to make sure it's the same entry we entered with.
-                * Possibly a callback may have mucked with it, although
-                * in general callbacks should treat the entry as read-only.
-                */
-               bdb_cache_deref( oe->e_private );
-               if ( op->ora_e == oe )
-                       op->ora_e = NULL;
-
-               if ( bdb->bi_txn_cp_kbyte ) {
-                       TXN_CHECKPOINT( bdb->bi_dbenv,
-                               bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
-               }
-       }
-
-       slap_graduate_commit_csn( op );
-
-       if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
-               slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
-               slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
-       }
-       return rs->sr_err;
-}
diff --git a/servers/slapd/back-bdb/attr.c b/servers/slapd/back-bdb/attr.c
deleted file mode 100644 (file)
index d678d4d..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
-/* attr.c - backend routines for dealing with attributes */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-bdb.h"
-#include "config.h"
-#include "lutil.h"
-
-/* Find the ad, return -1 if not found,
- * set point for insertion if ins is non-NULL
- */
-int
-bdb_attr_slot( struct bdb_info *bdb, AttributeDescription *ad, int *ins )
-{
-       unsigned base = 0, cursor = 0;
-       unsigned n = bdb->bi_nattrs;
-       int val = 0;
-       
-       while ( 0 < n ) {
-               unsigned pivot = n >> 1;
-               cursor = base + pivot;
-
-               val = SLAP_PTRCMP( ad, bdb->bi_attrs[cursor]->ai_desc );
-               if ( val < 0 ) {
-                       n = pivot;
-               } else if ( val > 0 ) {
-                       base = cursor + 1;
-                       n -= pivot + 1;
-               } else {
-                       return cursor;
-               }
-       }
-       if ( ins ) {
-               if ( val > 0 )
-                       ++cursor;
-               *ins = cursor;
-       }
-       return -1;
-}
-
-static int
-ainfo_insert( struct bdb_info *bdb, AttrInfo *a )
-{
-       int x;
-       int i = bdb_attr_slot( bdb, a->ai_desc, &x );
-
-       /* Is it a dup? */
-       if ( i >= 0 )
-               return -1;
-
-       bdb->bi_attrs = ch_realloc( bdb->bi_attrs, ( bdb->bi_nattrs+1 ) * 
-               sizeof( AttrInfo * ));
-       if ( x < bdb->bi_nattrs )
-               AC_MEMCPY( &bdb->bi_attrs[x+1], &bdb->bi_attrs[x],
-                       ( bdb->bi_nattrs - x ) * sizeof( AttrInfo *));
-       bdb->bi_attrs[x] = a;
-       bdb->bi_nattrs++;
-       return 0;
-}
-
-AttrInfo *
-bdb_attr_mask(
-       struct bdb_info *bdb,
-       AttributeDescription *desc )
-{
-       int i = bdb_attr_slot( bdb, desc, NULL );
-       return i < 0 ? NULL : bdb->bi_attrs[i];
-}
-
-int
-bdb_attr_index_config(
-       struct bdb_info *bdb,
-       const char              *fname,
-       int                     lineno,
-       int                     argc,
-       char            **argv,
-       struct          config_reply_s *c_reply)
-{
-       int rc = 0;
-       int     i;
-       slap_mask_t mask;
-       char **attrs;
-       char **indexes = NULL;
-
-       attrs = ldap_str2charray( argv[0], "," );
-
-       if( attrs == NULL ) {
-               fprintf( stderr, "%s: line %d: "
-                       "no attributes specified: %s\n",
-                       fname, lineno, argv[0] );
-               return LDAP_PARAM_ERROR;
-       }
-
-       if ( argc > 1 ) {
-               indexes = ldap_str2charray( argv[1], "," );
-
-               if( indexes == NULL ) {
-                       fprintf( stderr, "%s: line %d: "
-                               "no indexes specified: %s\n",
-                               fname, lineno, argv[1] );
-                       rc = LDAP_PARAM_ERROR;
-                       goto done;
-               }
-       }
-
-       if( indexes == NULL ) {
-               mask = bdb->bi_defaultmask;
-
-       } else {
-               mask = 0;
-
-               for ( i = 0; indexes[i] != NULL; i++ ) {
-                       slap_mask_t index;
-                       rc = slap_str2index( indexes[i], &index );
-
-                       if( rc != LDAP_SUCCESS ) {
-                               if ( c_reply )
-                               {
-                                       snprintf(c_reply->msg, sizeof(c_reply->msg),
-                                               "index type \"%s\" undefined", indexes[i] );
-
-                                       fprintf( stderr, "%s: line %d: %s\n",
-                                               fname, lineno, c_reply->msg );
-                               }
-                               rc = LDAP_PARAM_ERROR;
-                               goto done;
-                       }
-
-                       mask |= index;
-               }
-       }
-
-       if( !mask ) {
-               if ( c_reply )
-               {
-                       snprintf(c_reply->msg, sizeof(c_reply->msg),
-                               "no indexes selected" );
-                       fprintf( stderr, "%s: line %d: %s\n",
-                               fname, lineno, c_reply->msg );
-               }
-               rc = LDAP_PARAM_ERROR;
-               goto done;
-       }
-
-       for ( i = 0; attrs[i] != NULL; i++ ) {
-               AttrInfo        *a;
-               AttributeDescription *ad;
-               const char *text;
-#ifdef LDAP_COMP_MATCH
-               ComponentReference* cr = NULL;
-               AttrInfo *a_cr = NULL;
-#endif
-
-               if( strcasecmp( attrs[i], "default" ) == 0 ) {
-                       bdb->bi_defaultmask |= mask;
-                       continue;
-               }
-
-#ifdef LDAP_COMP_MATCH
-               if ( is_component_reference( attrs[i] ) ) {
-                       rc = extract_component_reference( attrs[i], &cr );
-                       if ( rc != LDAP_SUCCESS ) {
-                               if ( c_reply )
-                               {
-                                       snprintf(c_reply->msg, sizeof(c_reply->msg),
-                                               "index component reference\"%s\" undefined",
-                                               attrs[i] );
-                                       fprintf( stderr, "%s: line %d: %s\n",
-                                               fname, lineno, c_reply->msg );
-                               }
-                               goto done;
-                       }
-                       cr->cr_indexmask = mask;
-                       /*
-                        * After extracting a component reference
-                        * only the name of a attribute will be remaining
-                        */
-               } else {
-                       cr = NULL;
-               }
-#endif
-               ad = NULL;
-               rc = slap_str2ad( attrs[i], &ad, &text );
-
-               if( rc != LDAP_SUCCESS ) {
-                       if ( c_reply )
-                       {
-                               snprintf(c_reply->msg, sizeof(c_reply->msg),
-                                       "index attribute \"%s\" undefined",
-                                       attrs[i] );
-
-                               fprintf( stderr, "%s: line %d: %s\n",
-                                       fname, lineno, c_reply->msg );
-                       }
-fail:
-#ifdef LDAP_COMP_MATCH
-                       ch_free( cr );
-#endif
-                       goto done;
-               }
-
-               if( ad == slap_schema.si_ad_entryDN || slap_ad_is_binary( ad ) ) {
-                       if (c_reply) {
-                               snprintf(c_reply->msg, sizeof(c_reply->msg),
-                                       "index of attribute \"%s\" disallowed", attrs[i] );
-                               fprintf( stderr, "%s: line %d: %s\n",
-                                       fname, lineno, c_reply->msg );
-                       }
-                       rc = LDAP_UNWILLING_TO_PERFORM;
-                       goto fail;
-               }
-
-               if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !(
-                       ad->ad_type->sat_approx
-                               && ad->ad_type->sat_approx->smr_indexer
-                               && ad->ad_type->sat_approx->smr_filter ) )
-               {
-                       if (c_reply) {
-                               snprintf(c_reply->msg, sizeof(c_reply->msg),
-                                       "approx index of attribute \"%s\" disallowed", attrs[i] );
-                               fprintf( stderr, "%s: line %d: %s\n",
-                                       fname, lineno, c_reply->msg );
-                       }
-                       rc = LDAP_INAPPROPRIATE_MATCHING;
-                       goto fail;
-               }
-
-               if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !(
-                       ad->ad_type->sat_equality
-                               && ad->ad_type->sat_equality->smr_indexer
-                               && ad->ad_type->sat_equality->smr_filter ) )
-               {
-                       if (c_reply) {
-                               snprintf(c_reply->msg, sizeof(c_reply->msg),
-                                       "equality index of attribute \"%s\" disallowed", attrs[i] );
-                               fprintf( stderr, "%s: line %d: %s\n",
-                                       fname, lineno, c_reply->msg );
-                       }
-                       rc = LDAP_INAPPROPRIATE_MATCHING;
-                       goto fail;
-               }
-
-               if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !(
-                       ad->ad_type->sat_substr
-                               && ad->ad_type->sat_substr->smr_indexer
-                               && ad->ad_type->sat_substr->smr_filter ) )
-               {
-                       if (c_reply) {
-                               snprintf(c_reply->msg, sizeof(c_reply->msg),
-                                       "substr index of attribute \"%s\" disallowed", attrs[i] );
-                               fprintf( stderr, "%s: line %d: %s\n",
-                                       fname, lineno, c_reply->msg );
-                       }
-                       rc = LDAP_INAPPROPRIATE_MATCHING;
-                       goto fail;
-               }
-
-               Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n",
-                       ad->ad_cname.bv_val, mask );
-
-               a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) );
-
-#ifdef LDAP_COMP_MATCH
-               a->ai_cr = NULL;
-#endif
-               a->ai_desc = ad;
-
-               if ( bdb->bi_flags & BDB_IS_OPEN ) {
-                       a->ai_indexmask = 0;
-                       a->ai_newmask = mask;
-               } else {
-                       a->ai_indexmask = mask;
-                       a->ai_newmask = 0;
-               }
-
-#ifdef LDAP_COMP_MATCH
-               if ( cr ) {
-                       a_cr = bdb_attr_mask( bdb, ad );
-                       if ( a_cr ) {
-                               /*
-                                * AttrInfo is already in AVL
-                                * just add the extracted component reference
-                                * in the AttrInfo
-                                */
-                               ch_free( a );
-                               rc = insert_component_reference( cr, &a_cr->ai_cr );
-                               if ( rc != LDAP_SUCCESS) {
-                                       fprintf( stderr, " error during inserting component reference in %s ", attrs[i]);
-                                       rc = LDAP_PARAM_ERROR;
-                                       goto fail;
-                               }
-                               continue;
-                       } else {
-                               rc = insert_component_reference( cr, &a->ai_cr );
-                               if ( rc != LDAP_SUCCESS) {
-                                       fprintf( stderr, " error during inserting component reference in %s ", attrs[i]);
-                                       rc = LDAP_PARAM_ERROR;
-                                       ch_free( a );
-                                       goto fail;
-                               }
-                       }
-               }
-#endif
-               rc = ainfo_insert( bdb, a );
-               if( rc ) {
-                       if ( bdb->bi_flags & BDB_IS_OPEN ) {
-                               AttrInfo *b = bdb_attr_mask( bdb, ad );
-                               /* If there is already an index defined for this attribute
-                                * it must be replaced. Otherwise we end up with multiple 
-                                * olcIndex values for the same attribute */
-                               if ( b->ai_indexmask & BDB_INDEX_DELETING ) {
-                                       /* If we were editing this attr, reset it */
-                                       b->ai_indexmask &= ~BDB_INDEX_DELETING;
-                                       /* If this is leftover from a previous add, commit it */
-                                       if ( b->ai_newmask )
-                                               b->ai_indexmask = b->ai_newmask;
-                                       b->ai_newmask = a->ai_newmask;
-                                       ch_free( a );
-                                       rc = 0;
-                                       continue;
-                               }
-                       }
-                       if (c_reply) {
-                               snprintf(c_reply->msg, sizeof(c_reply->msg),
-                                       "duplicate index definition for attr \"%s\"",
-                                       attrs[i] );
-                               fprintf( stderr, "%s: line %d: %s\n",
-                                       fname, lineno, c_reply->msg );
-                       }
-
-                       rc = LDAP_PARAM_ERROR;
-                       goto done;
-               }
-       }
-
-done:
-       ldap_charray_free( attrs );
-       if ( indexes != NULL ) ldap_charray_free( indexes );
-
-       return rc;
-}
-
-static int
-bdb_attr_index_unparser( void *v1, void *v2 )
-{
-       AttrInfo *ai = v1;
-       BerVarray *bva = v2;
-       struct berval bv;
-       char *ptr;
-
-       slap_index2bvlen( ai->ai_indexmask, &bv );
-       if ( bv.bv_len ) {
-               bv.bv_len += ai->ai_desc->ad_cname.bv_len + 1;
-               ptr = ch_malloc( bv.bv_len+1 );
-               bv.bv_val = lutil_strcopy( ptr, ai->ai_desc->ad_cname.bv_val );
-               *bv.bv_val++ = ' ';
-               slap_index2bv( ai->ai_indexmask, &bv );
-               bv.bv_val = ptr;
-               ber_bvarray_add( bva, &bv );
-       }
-       return 0;
-}
-
-static AttributeDescription addef = { NULL, NULL, BER_BVC("default") };
-static AttrInfo aidef = { &addef };
-
-void
-bdb_attr_index_unparse( struct bdb_info *bdb, BerVarray *bva )
-{
-       int i;
-
-       if ( bdb->bi_defaultmask ) {
-               aidef.ai_indexmask = bdb->bi_defaultmask;
-               bdb_attr_index_unparser( &aidef, bva );
-       }
-       for ( i=0; i<bdb->bi_nattrs; i++ )
-               bdb_attr_index_unparser( bdb->bi_attrs[i], bva );
-}
-
-void
-bdb_attr_info_free( AttrInfo *ai )
-{
-#ifdef LDAP_COMP_MATCH
-       free( ai->ai_cr );
-#endif
-       free( ai );
-}
-
-void
-bdb_attr_index_destroy( struct bdb_info *bdb )
-{
-       int i;
-
-       for ( i=0; i<bdb->bi_nattrs; i++ ) 
-               bdb_attr_info_free( bdb->bi_attrs[i] );
-
-       free( bdb->bi_attrs );
-}
-
-void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad )
-{
-       int i;
-
-       i = bdb_attr_slot( bdb, ad, NULL );
-       if ( i >= 0 ) {
-               bdb_attr_info_free( bdb->bi_attrs[i] );
-               bdb->bi_nattrs--;
-               for (; i<bdb->bi_nattrs; i++)
-                       bdb->bi_attrs[i] = bdb->bi_attrs[i+1];
-       }
-}
-
-void bdb_attr_flush( struct bdb_info *bdb )
-{
-       int i;
-
-       for ( i=0; i<bdb->bi_nattrs; i++ ) {
-               if ( bdb->bi_attrs[i]->ai_indexmask & BDB_INDEX_DELETING ) {
-                       int j;
-                       bdb_attr_info_free( bdb->bi_attrs[i] );
-                       bdb->bi_nattrs--;
-                       for (j=i; j<bdb->bi_nattrs; j++)
-                               bdb->bi_attrs[j] = bdb->bi_attrs[j+1];
-                       i--;
-               }
-       }
-}
diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h
deleted file mode 100644 (file)
index f50296f..0000000
+++ /dev/null
@@ -1,377 +0,0 @@
-/* back-bdb.h - bdb back-end header file */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#ifndef _BACK_BDB_H_
-#define _BACK_BDB_H_
-
-#include <portable.h>
-#include "slap.h"
-#include <db.h>
-#include "alock.h"
-
-LDAP_BEGIN_DECL
-
-#define DB_VERSION_FULL ((DB_VERSION_MAJOR << 24) | (DB_VERSION_MINOR << 16) | DB_VERSION_PATCH)
-
-#define DN_BASE_PREFIX         SLAP_INDEX_EQUALITY_PREFIX
-#define DN_ONE_PREFIX          '%'
-#define DN_SUBTREE_PREFIX      '@'
-
-#define DBTzero(t)                     (memset((t), 0, sizeof(DBT)))
-#define DBT2bv(t,bv)           ((bv)->bv_val = (t)->data, \
-                                                               (bv)->bv_len = (t)->size)
-#define bv2DBT(bv,t)           ((t)->data = (bv)->bv_val, \
-                                                               (t)->size = (bv)->bv_len )
-
-#define BDB_TXN_RETRIES                16
-
-#define BDB_MAX_ADD_LOOP       30
-
-#define BDB_SUFFIX             ".bdb"
-#define BDB_ID2ENTRY   0
-#define BDB_DN2ID              1
-#define BDB_NDB                        2
-
-/* The bdb on-disk entry format is pretty space-inefficient. Average
- * sized user entries are 3-4K each. You need at least two entries to
- * fit into a single database page, more is better. 64K is BDB's
- * upper bound. Smaller pages are better for concurrency.
- */
-#ifndef BDB_ID2ENTRY_PAGESIZE
-#define        BDB_ID2ENTRY_PAGESIZE   16384
-#endif
-
-#define DEFAULT_CACHE_SIZE     1000
-
-/* The default search IDL stack cache depth */
-#define DEFAULT_SEARCH_STACK_DEPTH     16
-
-/* The minimum we can function with */
-#define MINIMUM_SEARCH_STACK_DEPTH     8
-
-typedef struct bdb_idl_cache_entry_s {
-       struct berval kstr;
-       ID      *idl;
-       DB      *db;
-       int             idl_flags;
-       struct bdb_idl_cache_entry_s* idl_lru_prev;
-       struct bdb_idl_cache_entry_s* idl_lru_next;
-} bdb_idl_cache_entry_t;
-
-/* BDB backend specific entry info */
-typedef struct bdb_entry_info {
-       struct bdb_entry_info *bei_parent;
-       ID bei_id;
-
-       /* we use the bei_id as a lockobj, but we need to make the size != 4
-        * to avoid conflicting with BDB's internal locks. So add a byte here
-        * that is always zero.
-        */
-       short bei_lockpad;
-
-       short bei_state;
-#define        CACHE_ENTRY_DELETED     1
-#define        CACHE_ENTRY_NO_KIDS     2
-#define        CACHE_ENTRY_NOT_LINKED  4
-#define CACHE_ENTRY_NO_GRANDKIDS       8
-#define        CACHE_ENTRY_LOADING     0x10
-#define        CACHE_ENTRY_WALKING     0x20
-#define        CACHE_ENTRY_ONELEVEL    0x40
-#define        CACHE_ENTRY_REFERENCED  0x80
-#define        CACHE_ENTRY_NOT_CACHED  0x100
-       int bei_finders;
-
-       /*
-        * remaining fields require backend cache lock to access
-        */
-       struct berval bei_nrdn;
-#ifdef BDB_HIER
-       struct berval bei_rdn;
-       int     bei_modrdns;    /* track renames */
-       int     bei_ckids;      /* number of kids cached */
-       int     bei_dkids;      /* number of kids on-disk, plus 1 */
-#endif
-       Entry   *bei_e;
-       Avlnode *bei_kids;
-#ifdef SLAP_ZONE_ALLOC
-       struct bdb_info *bei_bdb;
-       int bei_zseq;   
-#endif
-       ldap_pvt_thread_mutex_t bei_kids_mutex;
-       
-       struct bdb_entry_info   *bei_lrunext;   /* for cache lru list */
-       struct bdb_entry_info   *bei_lruprev;
-} EntryInfo;
-#undef BEI
-#define BEI(e) ((EntryInfo *) ((e)->e_private))
-
-/* for the in-core cache of entries */
-typedef struct bdb_cache {
-       EntryInfo       *c_eifree;      /* free list */
-       Avlnode         *c_idtree;
-       EntryInfo       *c_lruhead;     /* lru - add accessed entries here */
-       EntryInfo       *c_lrutail;     /* lru - rem lru entries from here */
-       EntryInfo       c_dntree;
-       ID              c_maxsize;
-       ID              c_cursize;
-       ID              c_minfree;
-       ID              c_eimax;
-       ID              c_eiused;       /* EntryInfo's in use */
-       ID              c_leaves;       /* EntryInfo leaf nodes */
-       int             c_purging;
-       DB_TXN  *c_txn; /* used by lru cleaner */
-       ldap_pvt_thread_rdwr_t c_rwlock;
-       ldap_pvt_thread_mutex_t c_lru_mutex;
-       ldap_pvt_thread_mutex_t c_count_mutex;
-       ldap_pvt_thread_mutex_t c_eifree_mutex;
-#ifdef SLAP_ZONE_ALLOC
-       void *c_zctx;
-#endif
-} Cache;
-#define CACHE_READ_LOCK                0
-#define CACHE_WRITE_LOCK       1
-#define BDB_INDICES            128
-
-struct bdb_db_info {
-       struct berval   bdi_name;
-       DB                      *bdi_db;
-};
-
-struct bdb_db_pgsize {
-       struct bdb_db_pgsize *bdp_next;
-       struct berval   bdp_name;
-       int     bdp_size;
-};
-
-#ifdef LDAP_DEVEL
-#define BDB_MONITOR_IDX
-#endif
-
-typedef struct bdb_monitor_t {
-       void            *bdm_cb;
-       struct berval   bdm_ndn;
-} bdb_monitor_t;
-
-/* From ldap_rq.h */
-struct re_s;
-
-struct bdb_info {
-       DB_ENV          *bi_dbenv;
-
-       /* DB_ENV parameters */
-       /* The DB_ENV can be tuned via DB_CONFIG */
-       char            *bi_dbenv_home;
-       u_int32_t       bi_dbenv_xflags; /* extra flags */
-       int                     bi_dbenv_mode;
-
-       int                     bi_ndatabases;
-       int             bi_db_opflags;  /* db-specific flags */
-       struct bdb_db_info **bi_databases;
-       ldap_pvt_thread_mutex_t bi_database_mutex;
-       struct bdb_db_pgsize *bi_pagesizes;
-
-       slap_mask_t     bi_defaultmask;
-       Cache           bi_cache;
-       struct bdb_attrinfo             **bi_attrs;
-       int                     bi_nattrs;
-       void            *bi_search_stack;
-       int             bi_search_stack_depth;
-       int             bi_linear_index;
-
-       int                     bi_txn_cp;
-       u_int32_t       bi_txn_cp_min;
-       u_int32_t       bi_txn_cp_kbyte;
-       struct re_s             *bi_txn_cp_task;
-       struct re_s             *bi_index_task;
-
-       u_int32_t               bi_lock_detect;
-       long            bi_shm_key;
-
-       ID                      bi_lastid;
-       ldap_pvt_thread_mutex_t bi_lastid_mutex;
-       ID      bi_idl_cache_max_size;
-       ID              bi_idl_cache_size;
-       Avlnode         *bi_idl_tree;
-       bdb_idl_cache_entry_t   *bi_idl_lru_head;
-       bdb_idl_cache_entry_t   *bi_idl_lru_tail;
-       ldap_pvt_thread_rdwr_t bi_idl_tree_rwlock;
-       ldap_pvt_thread_mutex_t bi_idl_tree_lrulock;
-       alock_info_t    bi_alock_info;
-       char            *bi_db_config_path;
-       BerVarray       bi_db_config;
-       char            *bi_db_crypt_file;
-       struct berval   bi_db_crypt_key;
-       bdb_monitor_t   bi_monitor;
-
-#ifdef BDB_MONITOR_IDX
-       ldap_pvt_thread_mutex_t bi_idx_mutex;
-       Avlnode         *bi_idx;
-#endif /* BDB_MONITOR_IDX */
-
-       int             bi_flags;
-#define        BDB_IS_OPEN             0x01
-#define        BDB_HAS_CONFIG  0x02
-#define        BDB_UPD_CONFIG  0x04
-#define        BDB_DEL_INDEX   0x08
-#define        BDB_RE_OPEN             0x10
-#define BDB_CHKSUM             0x20
-#ifdef BDB_HIER
-       int             bi_modrdns;             /* number of modrdns completed */
-       ldap_pvt_thread_mutex_t bi_modrdns_mutex;
-#endif
-};
-
-#define bi_id2entry    bi_databases[BDB_ID2ENTRY]
-#define bi_dn2id       bi_databases[BDB_DN2ID]
-
-
-struct bdb_lock_info {
-       struct bdb_lock_info *bli_next;
-       DB_LOCK bli_lock;
-       ID              bli_id;
-       int             bli_flag;
-};
-#define        BLI_DONTFREE    1
-
-struct bdb_op_info {
-       OpExtra boi_oe;
-       DB_TXN*         boi_txn;
-       struct bdb_lock_info *boi_locks;        /* used when no txn */
-       u_int32_t       boi_err;
-       char            boi_acl_cache;
-       char            boi_flag;
-};
-#define BOI_DONTFREE   1
-
-#define        DB_OPEN(db, file, name, type, flags, mode) \
-       ((db)->open)(db, file, name, type, flags, mode)
-
-#if DB_VERSION_MAJOR < 4
-#define LOCK_DETECT(env,f,t,a)         lock_detect(env, f, t, a)
-#define LOCK_GET(env,i,f,o,m,l)                lock_get(env, i, f, o, m, l)
-#define LOCK_PUT(env,l)                        lock_put(env, l)
-#define TXN_CHECKPOINT(env,k,m,f)      txn_checkpoint(env, k, m, f)
-#define TXN_BEGIN(env,p,t,f)           txn_begin((env), p, t, f)
-#define TXN_PREPARE(txn,gid)           txn_prepare((txn), (gid))
-#define TXN_COMMIT(txn,f)                      txn_commit((txn), (f))
-#define        TXN_ABORT(txn)                          txn_abort((txn))
-#define TXN_ID(txn)                                    txn_id(txn)
-#define XLOCK_ID(env, locker)          lock_id(env, locker)
-#define XLOCK_ID_FREE(env, locker)     lock_id_free(env, locker)
-#else
-#define LOCK_DETECT(env,f,t,a)         (env)->lock_detect(env, f, t, a)
-#define LOCK_GET(env,i,f,o,m,l)                (env)->lock_get(env, i, f, o, m, l)
-#define LOCK_PUT(env,l)                        (env)->lock_put(env, l)
-#define TXN_CHECKPOINT(env,k,m,f)      (env)->txn_checkpoint(env, k, m, f)
-#define TXN_BEGIN(env,p,t,f)           (env)->txn_begin((env), p, t, f)
-#define TXN_PREPARE(txn,g)                     (txn)->prepare((txn), (g))
-#define TXN_COMMIT(txn,f)                      (txn)->commit((txn), (f))
-#define TXN_ABORT(txn)                         (txn)->abort((txn))
-#define TXN_ID(txn)                                    (txn)->id(txn)
-#define XLOCK_ID(env, locker)          (env)->lock_id(env, locker)
-#define XLOCK_ID_FREE(env, locker)     (env)->lock_id_free(env, locker)
-
-/* BDB 4.1.17 adds txn arg to db->open */
-#if DB_VERSION_FULL >= 0x04010011
-#undef DB_OPEN
-#define        DB_OPEN(db, file, name, type, flags, mode) \
-       ((db)->open)(db, NULL, file, name, type, flags, mode)
-#endif
-
-/* #undef BDB_LOG_DEBUG */
-
-#ifdef BDB_LOG_DEBUG
-
-/* env->log_printf appeared in 4.4 */
-#if DB_VERSION_FULL >= 0x04040000
-#define        BDB_LOG_PRINTF(env,txn,fmt,...) (env)->log_printf((env),(txn),(fmt),__VA_ARGS__)
-#else
-extern int __db_logmsg(const DB_ENV *env, DB_TXN *txn, const char *op, u_int32_t flags,
-       const char *fmt,...);
-#define        BDB_LOG_PRINTF(env,txn,fmt,...) __db_logmsg((env),(txn),"DIAGNOSTIC",0,(fmt),__VA_ARGS__)
-#endif
-
-/* !BDB_LOG_DEBUG */
-#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
-       (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__STRICT_ANSI__))
-#define BDB_LOG_PRINTF(a,b,c,...)
-#else
-#define BDB_LOG_PRINTF (void)  /* will evaluate and discard the arguments */
-
-#endif /* BDB_LOG_DEBUG */
-
-#endif
-
-#ifndef DB_BUFFER_SMALL
-#define DB_BUFFER_SMALL                        ENOMEM
-#endif
-
-#define BDB_CSN_COMMIT 0
-#define BDB_CSN_ABORT  1
-#define BDB_CSN_RETRY  2
-
-/* Copy an ID "src" to pointer "dst" in big-endian byte order */
-#define BDB_ID2DISK( src, dst )        \
-       do { int i0; ID tmp; unsigned char *_p; \
-               tmp = (src); _p = (unsigned char *)(dst);       \
-               for ( i0=sizeof(ID)-1; i0>=0; i0-- ) {  \
-                       _p[i0] = tmp & 0xff; tmp >>= 8; \
-               } \
-       } while(0)
-
-/* Copy a pointer "src" to a pointer "dst" from big-endian to native order */
-#define BDB_DISK2ID( src, dst ) \
-       do { unsigned i0; ID tmp = 0; unsigned char *_p;        \
-               _p = (unsigned char *)(src);    \
-               for ( i0=0; i0<sizeof(ID); i0++ ) {     \
-                       tmp <<= 8; tmp |= *_p++;        \
-               } *(dst) = tmp; \
-       } while (0)
-
-LDAP_END_DECL
-
-/* for the cache of attribute information (which are indexed, etc.) */
-typedef struct bdb_attrinfo {
-       AttributeDescription *ai_desc; /* attribute description cn;lang-en */
-       slap_mask_t ai_indexmask;       /* how the attr is indexed      */
-       slap_mask_t ai_newmask; /* new settings to replace old mask */
-#ifdef LDAP_COMP_MATCH
-       ComponentReference* ai_cr; /*component indexing*/
-#endif
-} AttrInfo;
-
-/* These flags must not clash with SLAP_INDEX flags or ops in slap.h! */
-#define        BDB_INDEX_DELETING      0x8000U /* index is being modified */
-#define        BDB_INDEX_UPDATE_OP     0x03    /* performing an index update */
-
-/* For slapindex to record which attrs in an entry belong to which
- * index database 
- */
-typedef struct AttrList {
-       struct AttrList *next;
-       Attribute *attr;
-} AttrList;
-
-typedef struct IndexRec {
-       AttrInfo *ai;
-       AttrList *attrs;
-} IndexRec;
-
-#include "proto-bdb.h"
-
-#endif /* _BACK_BDB_H_ */
diff --git a/servers/slapd/back-bdb/bind.c b/servers/slapd/back-bdb/bind.c
deleted file mode 100644 (file)
index e01c455..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/* bind.c - bdb backend bind routine */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-#include <ac/unistd.h>
-
-#include "back-bdb.h"
-
-int
-bdb_bind( Operation *op, SlapReply *rs )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       Entry           *e;
-       Attribute       *a;
-       EntryInfo       *ei;
-
-       AttributeDescription *password = slap_schema.si_ad_userPassword;
-
-       DB_TXN          *rtxn;
-       DB_LOCK         lock;
-
-       Debug( LDAP_DEBUG_ARGS,
-               "==> " LDAP_XSTRING(bdb_bind) ": dn: %s\n",
-               op->o_req_dn.bv_val );
-
-       /* allow noauth binds */
-       switch ( be_rootdn_bind( op, NULL ) ) {
-       case LDAP_SUCCESS:
-               /* frontend will send result */
-               return rs->sr_err = LDAP_SUCCESS;
-
-       default:
-               /* give the database a chance */
-               /* NOTE: this behavior departs from that of other backends,
-                * since the others, in case of password checking failure
-                * do not give the database a chance.  If an entry with
-                * rootdn's name does not exist in the database the result
-                * will be the same.  See ITS#4962 for discussion. */
-               break;
-       }
-
-       rs->sr_err = bdb_reader_get(op, bdb->bi_dbenv, &rtxn);
-       switch(rs->sr_err) {
-       case 0:
-               break;
-       default:
-               rs->sr_text = "internal error";
-               send_ldap_result( op, rs );
-               return rs->sr_err;
-       }
-
-dn2entry_retry:
-       /* get entry with reader lock */
-       rs->sr_err = bdb_dn2entry( op, rtxn, &op->o_req_ndn, &ei, 1,
-               &lock );
-
-       switch(rs->sr_err) {
-       case DB_NOTFOUND:
-       case 0:
-               break;
-       case LDAP_BUSY:
-               send_ldap_error( op, rs, LDAP_BUSY, "ldap_server_busy" );
-               return LDAP_BUSY;
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               goto dn2entry_retry;
-       default:
-               send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-               return rs->sr_err;
-       }
-
-       e = ei->bei_e;
-       if ( rs->sr_err == DB_NOTFOUND ) {
-               if( e != NULL ) {
-                       bdb_cache_return_entry_r( bdb, e, &lock );
-                       e = NULL;
-               }
-
-               rs->sr_err = LDAP_INVALID_CREDENTIALS;
-               send_ldap_result( op, rs );
-
-               return rs->sr_err;
-       }
-
-       ber_dupbv( &op->oq_bind.rb_edn, &e->e_name );
-
-       /* check for deleted */
-       if ( is_entry_subentry( e ) ) {
-               /* entry is an subentry, don't allow bind */
-               Debug( LDAP_DEBUG_TRACE, "entry is subentry\n" );
-               rs->sr_err = LDAP_INVALID_CREDENTIALS;
-               goto done;
-       }
-
-       if ( is_entry_alias( e ) ) {
-               /* entry is an alias, don't allow bind */
-               Debug( LDAP_DEBUG_TRACE, "entry is alias\n" );
-               rs->sr_err = LDAP_INVALID_CREDENTIALS;
-               goto done;
-       }
-
-       if ( is_entry_referral( e ) ) {
-               Debug( LDAP_DEBUG_TRACE, "entry is referral\n" );
-               rs->sr_err = LDAP_INVALID_CREDENTIALS;
-               goto done;
-       }
-
-       switch ( op->oq_bind.rb_method ) {
-       case LDAP_AUTH_SIMPLE:
-               a = attr_find( e->e_attrs, password );
-               if ( a == NULL ) {
-                       rs->sr_err = LDAP_INVALID_CREDENTIALS;
-                       goto done;
-               }
-
-               if ( slap_passwd_check( op, e, a, &op->oq_bind.rb_cred,
-                                       &rs->sr_text ) != 0 )
-               {
-                       /* failure; stop front end from sending result */
-                       rs->sr_err = LDAP_INVALID_CREDENTIALS;
-                       goto done;
-               }
-                       
-               rs->sr_err = 0;
-               break;
-
-       default:
-               assert( 0 ); /* should not be reachable */
-               rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED;
-               rs->sr_text = "authentication method not supported";
-       }
-
-done:
-       /* free entry and reader lock */
-       if( e != NULL ) {
-               bdb_cache_return_entry_r( bdb, e, &lock );
-       }
-
-       if ( rs->sr_err ) {
-               send_ldap_result( op, rs );
-               if ( rs->sr_ref ) {
-                       ber_bvarray_free( rs->sr_ref );
-                       rs->sr_ref = NULL;
-               }
-       }
-       /* front end will send result on success (rs->sr_err==0) */
-       return rs->sr_err;
-}
diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c
deleted file mode 100644 (file)
index c136ea7..0000000
+++ /dev/null
@@ -1,1692 +0,0 @@
-/* cache.c - routines to maintain an in-core cache of entries */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/errno.h>
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-
-#include "back-bdb.h"
-
-#include "ldap_rq.h"
-
-#ifdef BDB_HIER
-#define bdb_cache_lru_purge    hdb_cache_lru_purge
-#endif
-static void bdb_cache_lru_purge( struct bdb_info *bdb );
-
-static int     bdb_cache_delete_internal(Cache *cache, EntryInfo *e, int decr);
-#ifdef LDAP_DEBUG
-#define SLAPD_UNUSED
-#ifdef SLAPD_UNUSED
-static void    bdb_lru_print(Cache *cache);
-static void    bdb_idtree_print(Cache *cache);
-#endif
-#endif
-
-/* For concurrency experiments only! */
-#if 0
-#define        ldap_pvt_thread_rdwr_wlock(a)   0
-#define        ldap_pvt_thread_rdwr_wunlock(a) 0
-#define        ldap_pvt_thread_rdwr_rlock(a)   0
-#define        ldap_pvt_thread_rdwr_runlock(a) 0
-#endif
-
-#if 0
-#define ldap_pvt_thread_mutex_trylock(a) 0
-#endif
-
-static EntryInfo *
-bdb_cache_entryinfo_new( Cache *cache )
-{
-       EntryInfo *ei = NULL;
-
-       if ( cache->c_eifree ) {
-               ldap_pvt_thread_mutex_lock( &cache->c_eifree_mutex );
-               if ( cache->c_eifree ) {
-                       ei = cache->c_eifree;
-                       cache->c_eifree = ei->bei_lrunext;
-                       ei->bei_finders = 0;
-                       ei->bei_lrunext = NULL;
-               }
-               ldap_pvt_thread_mutex_unlock( &cache->c_eifree_mutex );
-       }
-       if ( !ei ) {
-               ei = ch_calloc(1, sizeof(EntryInfo));
-               ldap_pvt_thread_mutex_init( &ei->bei_kids_mutex );
-       }
-
-       ei->bei_state = CACHE_ENTRY_REFERENCED;
-
-       return ei;
-}
-
-static void
-bdb_cache_entryinfo_free( Cache *cache, EntryInfo *ei )
-{
-       free( ei->bei_nrdn.bv_val );
-       BER_BVZERO( &ei->bei_nrdn );
-#ifdef BDB_HIER
-       free( ei->bei_rdn.bv_val );
-       BER_BVZERO( &ei->bei_rdn );
-       ei->bei_modrdns = 0;
-       ei->bei_ckids = 0;
-       ei->bei_dkids = 0;
-#endif
-       ei->bei_parent = NULL;
-       ei->bei_kids = NULL;
-       ei->bei_lruprev = NULL;
-
-#if 0
-       ldap_pvt_thread_mutex_lock( &cache->c_eifree_mutex );
-       ei->bei_lrunext = cache->c_eifree;
-       cache->c_eifree = ei;
-       ldap_pvt_thread_mutex_unlock( &cache->c_eifree_mutex );
-#else
-       ldap_pvt_thread_mutex_destroy( &ei->bei_kids_mutex );
-       ch_free( ei );
-#endif
-}
-
-#define LRU_DEL( c, e ) do { \
-       if ( e == e->bei_lruprev ) { \
-               (c)->c_lruhead = (c)->c_lrutail = NULL; \
-       } else { \
-               if ( e == (c)->c_lruhead ) (c)->c_lruhead = e->bei_lruprev; \
-               if ( e == (c)->c_lrutail ) (c)->c_lrutail = e->bei_lruprev; \
-               e->bei_lrunext->bei_lruprev = e->bei_lruprev; \
-               e->bei_lruprev->bei_lrunext = e->bei_lrunext; \
-       } \
-       e->bei_lruprev = NULL; \
-} while ( 0 )
-
-/* Note - we now use a Second-Chance / Clock algorithm instead of
- * Least-Recently-Used. This tremendously improves concurrency
- * because we no longer need to manipulate the lists every time an
- * entry is touched. We only need to lock the lists when adding
- * or deleting an entry. It's now a circular doubly-linked list.
- * We always append to the tail, but the head traverses the circle
- * during a purge operation.
- */
-static void
-bdb_cache_lru_link( struct bdb_info *bdb, EntryInfo *ei )
-{
-
-       /* Already linked, ignore */
-       if ( ei->bei_lruprev )
-               return;
-
-       /* Insert into circular LRU list */
-       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex );
-
-       ei->bei_lruprev = bdb->bi_cache.c_lrutail;
-       if ( bdb->bi_cache.c_lrutail ) {
-               ei->bei_lrunext = bdb->bi_cache.c_lrutail->bei_lrunext;
-               bdb->bi_cache.c_lrutail->bei_lrunext = ei;
-               if ( ei->bei_lrunext )
-                       ei->bei_lrunext->bei_lruprev = ei;
-       } else {
-               ei->bei_lrunext = ei->bei_lruprev = ei;
-               bdb->bi_cache.c_lruhead = ei;
-       }
-       bdb->bi_cache.c_lrutail = ei;
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex );
-}
-
-#ifdef NO_THREADS
-#define NO_DB_LOCK
-#endif
-
-/* #define NO_DB_LOCK 1 */
-/* Note: The BerkeleyDB locks are much slower than regular
- * mutexes or rdwr locks. But the BDB implementation has the
- * advantage of using a fixed size lock table, instead of
- * allocating a lock object per entry in the DB. That's a
- * key benefit for scaling. It also frees us from worrying
- * about undetectable deadlocks between BDB activity and our
- * own cache activity. It's still worth exploring faster
- * alternatives though.
- */
-
-/* Atomically release and reacquire a lock */
-int
-bdb_cache_entry_db_relock(
-       struct bdb_info *bdb,
-       DB_TXN *txn,
-       EntryInfo *ei,
-       int rw,
-       int tryOnly,
-       DB_LOCK *lock )
-{
-#ifdef NO_DB_LOCK
-       return 0;
-#else
-       int     rc;
-       DBT     lockobj;
-       DB_LOCKREQ list[2];
-
-       if ( !lock ) return 0;
-
-       DBTzero( &lockobj );
-       lockobj.data = &ei->bei_id;
-       lockobj.size = sizeof(ei->bei_id) + 1;
-
-       list[0].op = DB_LOCK_PUT;
-       list[0].lock = *lock;
-       list[1].op = DB_LOCK_GET;
-       list[1].lock = *lock;
-       list[1].mode = rw ? DB_LOCK_WRITE : DB_LOCK_READ;
-       list[1].obj = &lockobj;
-       rc = bdb->bi_dbenv->lock_vec(bdb->bi_dbenv, TXN_ID(txn), tryOnly ? DB_LOCK_NOWAIT : 0,
-               list, 2, NULL );
-
-       if (rc && !tryOnly) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "bdb_cache_entry_db_relock: entry %ld, rw %d, rc %d\n",
-                       ei->bei_id, rw, rc );
-       } else {
-               *lock = list[1].lock;
-       }
-       return rc;
-#endif
-}
-
-static int
-bdb_cache_entry_db_lock( struct bdb_info *bdb, DB_TXN *txn, EntryInfo *ei,
-       int rw, int tryOnly, DB_LOCK *lock )
-{
-#ifdef NO_DB_LOCK
-       return 0;
-#else
-       int       rc;
-       DBT       lockobj;
-       int       db_rw;
-
-       if ( !lock ) return 0;
-
-       if (rw)
-               db_rw = DB_LOCK_WRITE;
-       else
-               db_rw = DB_LOCK_READ;
-
-       DBTzero( &lockobj );
-       lockobj.data = &ei->bei_id;
-       lockobj.size = sizeof(ei->bei_id) + 1;
-
-       rc = LOCK_GET(bdb->bi_dbenv, TXN_ID(txn), tryOnly ? DB_LOCK_NOWAIT : 0,
-                                       &lockobj, db_rw, lock);
-       if (rc && !tryOnly) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "bdb_cache_entry_db_lock: entry %ld, rw %d, rc %d\n",
-                       ei->bei_id, rw, rc );
-       }
-       return rc;
-#endif /* NO_DB_LOCK */
-}
-
-int
-bdb_cache_entry_db_unlock ( struct bdb_info *bdb, DB_LOCK *lock )
-{
-#ifdef NO_DB_LOCK
-       return 0;
-#else
-       int rc;
-
-       if ( !lock || lock->mode == DB_LOCK_NG ) return 0;
-
-       rc = LOCK_PUT ( bdb->bi_dbenv, lock );
-       return rc;
-#endif
-}
-
-void
-bdb_cache_return_entry_rw( struct bdb_info *bdb, Entry *e,
-       int rw, DB_LOCK *lock )
-{
-       EntryInfo *ei;
-       int free = 0;
-
-       ei = e->e_private;
-       if ( ei && ( ei->bei_state & CACHE_ENTRY_NOT_CACHED )) {
-               bdb_cache_entryinfo_lock( ei );
-               if ( ei->bei_state & CACHE_ENTRY_NOT_CACHED ) {
-                       /* Releasing the entry can only be done when
-                        * we know that nobody else is using it, i.e we
-                        * should have an entry_db writelock.  But the
-                        * flag is only set by the thread that loads the
-                        * entry, and only if no other threads has found
-                        * it while it was working.  All other threads
-                        * clear the flag, which mean that we should be
-                        * the only thread using the entry if the flag
-                        * is set here.
-                        */
-                       ei->bei_e = NULL;
-                       ei->bei_state ^= CACHE_ENTRY_NOT_CACHED;
-                       free = 1;
-               }
-               bdb_cache_entryinfo_unlock( ei );
-       }
-       bdb_cache_entry_db_unlock( bdb, lock );
-       if ( free ) {
-               e->e_private = NULL;
-               bdb_entry_return( e );
-       }
-}
-
-static int
-bdb_cache_entryinfo_destroy( EntryInfo *e )
-{
-       ldap_pvt_thread_mutex_destroy( &e->bei_kids_mutex );
-       free( e->bei_nrdn.bv_val );
-#ifdef BDB_HIER
-       free( e->bei_rdn.bv_val );
-#endif
-       free( e );
-       return 0;
-}
-
-/* Do a length-ordered sort on normalized RDNs */
-static int
-bdb_rdn_cmp( const void *v_e1, const void *v_e2 )
-{
-       const EntryInfo *e1 = v_e1, *e2 = v_e2;
-       int rc = e1->bei_nrdn.bv_len - e2->bei_nrdn.bv_len;
-       if (rc == 0) {
-               rc = strncmp( e1->bei_nrdn.bv_val, e2->bei_nrdn.bv_val,
-                       e1->bei_nrdn.bv_len );
-       }
-       return rc;
-}
-
-static int
-bdb_id_cmp( const void *v_e1, const void *v_e2 )
-{
-       const EntryInfo *e1 = v_e1, *e2 = v_e2;
-       return e1->bei_id - e2->bei_id;
-}
-
-static int
-bdb_id_dup_err( void *v1, void *v2 )
-{
-       EntryInfo *e2 = v2;
-       e2->bei_lrunext = v1;
-       return -1;
-}
-
-/* Create an entryinfo in the cache. Caller must release the locks later.
- */
-static int
-bdb_entryinfo_add_internal(
-       struct bdb_info *bdb,
-       EntryInfo *ei,
-       EntryInfo **res )
-{
-       EntryInfo *ei2 = NULL;
-
-       *res = NULL;
-
-       ei2 = bdb_cache_entryinfo_new( &bdb->bi_cache );
-
-       bdb_cache_entryinfo_lock( ei->bei_parent );
-       ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
-
-       ei2->bei_id = ei->bei_id;
-       ei2->bei_parent = ei->bei_parent;
-#ifdef BDB_HIER
-       ei2->bei_rdn = ei->bei_rdn;
-#endif
-#ifdef SLAP_ZONE_ALLOC
-       ei2->bei_bdb = bdb;
-#endif
-
-       /* Add to cache ID tree */
-       if (avl_insert( &bdb->bi_cache.c_idtree, ei2, bdb_id_cmp,
-               bdb_id_dup_err )) {
-               EntryInfo *eix = ei2->bei_lrunext;
-               bdb_cache_entryinfo_free( &bdb->bi_cache, ei2 );
-               ei2 = eix;
-#ifdef BDB_HIER
-               /* It got freed above because its value was
-                * assigned to ei2.
-                */
-               ei->bei_rdn.bv_val = NULL;
-#endif
-       } else {
-               int rc;
-
-               bdb->bi_cache.c_eiused++;
-               ber_dupbv( &ei2->bei_nrdn, &ei->bei_nrdn );
-
-               /* This is a new leaf node. But if parent had no kids, then it was
-                * a leaf and we would be decrementing that. So, only increment if
-                * the parent already has kids.
-                */
-               if ( ei->bei_parent->bei_kids || !ei->bei_parent->bei_id )
-                       bdb->bi_cache.c_leaves++;
-               rc = avl_insert( &ei->bei_parent->bei_kids, ei2, bdb_rdn_cmp,
-                       avl_dup_error );
-#ifdef BDB_HIER
-               /* it's possible for hdb_cache_find_parent to beat us to it */
-               if ( !rc ) {
-                       ei->bei_parent->bei_ckids++;
-               }
-#endif
-       }
-
-       *res = ei2;
-       return 0;
-}
-
-/* Find the EntryInfo for the requested DN. If the DN cannot be found, return
- * the info for its closest ancestor. *res should be NULL to process a
- * complete DN starting from the tree root. Otherwise *res must be the
- * immediate parent of the requested DN, and only the RDN will be searched.
- * The EntryInfo is locked upon return and must be unlocked by the caller.
- */
-int
-bdb_cache_find_ndn(
-       Operation       *op,
-       DB_TXN          *txn,
-       struct berval   *ndn,
-       EntryInfo       **res )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       EntryInfo       ei, *eip, *ei2;
-       int rc = 0;
-       char *ptr;
-
-       /* this function is always called with normalized DN */
-       if ( *res ) {
-               /* we're doing a onelevel search for an RDN */
-               ei.bei_nrdn.bv_val = ndn->bv_val;
-               ei.bei_nrdn.bv_len = dn_rdnlen( op->o_bd, ndn );
-               eip = *res;
-       } else {
-               /* we're searching a full DN from the root */
-               ptr = ndn->bv_val + ndn->bv_len - op->o_bd->be_nsuffix[0].bv_len;
-               ei.bei_nrdn.bv_val = ptr;
-               ei.bei_nrdn.bv_len = op->o_bd->be_nsuffix[0].bv_len;
-               /* Skip to next rdn if suffix is empty */
-               if ( ei.bei_nrdn.bv_len == 0 ) {
-                       for (ptr = ei.bei_nrdn.bv_val - 2; ptr > ndn->bv_val
-                               && !DN_SEPARATOR(*ptr); ptr--) /* empty */;
-                       if ( ptr >= ndn->bv_val ) {
-                               if (DN_SEPARATOR(*ptr)) ptr++;
-                               ei.bei_nrdn.bv_len = ei.bei_nrdn.bv_val - ptr;
-                               ei.bei_nrdn.bv_val = ptr;
-                       }
-               }
-               eip = &bdb->bi_cache.c_dntree;
-       }
-       
-       for ( bdb_cache_entryinfo_lock( eip ); eip; ) {
-               eip->bei_state |= CACHE_ENTRY_REFERENCED;
-               ei.bei_parent = eip;
-               ei2 = (EntryInfo *)avl_find( eip->bei_kids, &ei, bdb_rdn_cmp );
-               if ( !ei2 ) {
-                       DBC *cursor;
-                       int len = ei.bei_nrdn.bv_len;
-                               
-                       if ( BER_BVISEMPTY( ndn )) {
-                               *res = eip;
-                               return LDAP_SUCCESS;
-                       }
-
-                       ei.bei_nrdn.bv_len = ndn->bv_len -
-                               (ei.bei_nrdn.bv_val - ndn->bv_val);
-                       eip->bei_finders++;
-                       bdb_cache_entryinfo_unlock( eip );
-
-                       BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Reading %s",
-                               ei.bei_nrdn.bv_val );
-
-                       cursor = NULL;
-                       rc = bdb_dn2id( op, &ei.bei_nrdn, &ei, txn, &cursor );
-                       if (rc) {
-                               bdb_cache_entryinfo_lock( eip );
-                               eip->bei_finders--;
-                               if ( cursor ) cursor->c_close( cursor );
-                               *res = eip;
-                               return rc;
-                       }
-
-                       BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Read got %s(%d)",
-                               ei.bei_nrdn.bv_val, ei.bei_id );
-
-                       /* DN exists but needs to be added to cache */
-                       ei.bei_nrdn.bv_len = len;
-                       rc = bdb_entryinfo_add_internal( bdb, &ei, &ei2 );
-                       /* add_internal left eip and c_rwlock locked */
-                       eip->bei_finders--;
-                       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-                       if ( cursor ) cursor->c_close( cursor );
-                       if ( rc ) {
-                               *res = eip;
-                               return rc;
-                       }
-               }
-               bdb_cache_entryinfo_lock( ei2 );
-               if ( ei2->bei_state & CACHE_ENTRY_DELETED ) {
-                       /* In the midst of deleting? Give it a chance to
-                        * complete.
-                        */
-                       bdb_cache_entryinfo_unlock( ei2 );
-                       bdb_cache_entryinfo_unlock( eip );
-                       ldap_pvt_thread_yield();
-                       bdb_cache_entryinfo_lock( eip );
-                       *res = eip;
-                       return DB_NOTFOUND;
-               }
-               bdb_cache_entryinfo_unlock( eip );
-
-               eip = ei2;
-
-               /* Advance to next lower RDN */
-               for (ptr = ei.bei_nrdn.bv_val - 2; ptr > ndn->bv_val
-                       && !DN_SEPARATOR(*ptr); ptr--) /* empty */;
-               if ( ptr >= ndn->bv_val ) {
-                       if (DN_SEPARATOR(*ptr)) ptr++;
-                       ei.bei_nrdn.bv_len = ei.bei_nrdn.bv_val - ptr - 1;
-                       ei.bei_nrdn.bv_val = ptr;
-               }
-               if ( ptr < ndn->bv_val ) {
-                       *res = eip;
-                       break;
-               }
-       }
-
-       return rc;
-}
-
-#ifdef BDB_HIER
-/* Walk up the tree from a child node, looking for an ID that's already
- * been linked into the cache.
- */
-int
-hdb_cache_find_parent(
-       Operation *op,
-       DB_TXN  *txn,
-       ID id,
-       EntryInfo **res )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       EntryInfo ei, eip, *ei2 = NULL, *ein = NULL, *eir = NULL;
-       int rc, add;
-
-       ei.bei_id = id;
-       ei.bei_kids = NULL;
-       ei.bei_ckids = 0;
-
-       for (;;) {
-               rc = hdb_dn2id_parent( op, txn, &ei, &eip.bei_id );
-               if ( rc ) break;
-
-               /* Save the previous node, if any */
-               ei2 = ein;
-
-               /* Create a new node for the current ID */
-               ein = bdb_cache_entryinfo_new( &bdb->bi_cache );
-               ein->bei_id = ei.bei_id;
-               ein->bei_kids = ei.bei_kids;
-               ein->bei_nrdn = ei.bei_nrdn;
-               ein->bei_rdn = ei.bei_rdn;
-               ein->bei_ckids = ei.bei_ckids;
-#ifdef SLAP_ZONE_ALLOC
-               ein->bei_bdb = bdb;
-#endif
-               ei.bei_ckids = 0;
-               add = 1;
-               
-               /* This node is not fully connected yet */
-               ein->bei_state |= CACHE_ENTRY_NOT_LINKED;
-
-               /* If this is the first time, save this node
-                * to be returned later.
-                */
-               if ( eir == NULL ) {
-                       eir = ein;
-                       ein->bei_finders++;
-               }
-
-again:
-               /* Insert this node into the ID tree */
-               ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
-               if ( avl_insert( &bdb->bi_cache.c_idtree, (caddr_t)ein,
-                       bdb_id_cmp, bdb_id_dup_err ) ) {
-                       EntryInfo *eix = ein->bei_lrunext;
-
-                       if ( bdb_cache_entryinfo_trylock( eix )) {
-                               ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-                               ldap_pvt_thread_yield();
-                               goto again;
-                       }
-                       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-
-                       /* Someone else created this node just before us.
-                        * Free our new copy and use the existing one.
-                        */
-                       bdb_cache_entryinfo_free( &bdb->bi_cache, ein );
-
-                       /* if it was the node we were looking for, just return it */
-                       if ( eir == ein ) {
-                               *res = eix;
-                               rc = 0;
-                               break;
-                       }
-
-                       ein = ei2;
-                       ei2 = eix;
-                       add = 0;
-
-                       /* otherwise, link up what we have and return */
-                       goto gotparent;
-               }
-
-               /* If there was a previous node, link it to this one */
-               if ( ei2 ) ei2->bei_parent = ein;
-
-               /* Look for this node's parent */
-par2:
-               if ( eip.bei_id ) {
-                       ei2 = (EntryInfo *) avl_find( bdb->bi_cache.c_idtree,
-                                       (caddr_t) &eip, bdb_id_cmp );
-               } else {
-                       ei2 = &bdb->bi_cache.c_dntree;
-               }
-               if ( ei2 && bdb_cache_entryinfo_trylock( ei2 )) {
-                       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-                       ldap_pvt_thread_yield();
-                       ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
-                       goto par2;
-               }
-               if ( add )
-                       bdb->bi_cache.c_eiused++;
-               if ( ei2 && ( ei2->bei_kids || !ei2->bei_id ))
-                       bdb->bi_cache.c_leaves++;
-               ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-
-gotparent:
-               /* Got the parent, link in and we're done. */
-               if ( ei2 ) {
-                       bdb_cache_entryinfo_lock( eir );
-                       ein->bei_parent = ei2;
-
-                       if ( avl_insert( &ei2->bei_kids, (caddr_t)ein, bdb_rdn_cmp,
-                               avl_dup_error) == 0 )
-                               ei2->bei_ckids++;
-
-                       /* Reset all the state info */
-                       for (ein = eir; ein != ei2; ein=ein->bei_parent)
-                               ein->bei_state &= ~CACHE_ENTRY_NOT_LINKED;
-
-                       bdb_cache_entryinfo_unlock( ei2 );
-                       eir->bei_finders--;
-
-                       *res = eir;
-                       break;
-               }
-               ei.bei_kids = NULL;
-               ei.bei_id = eip.bei_id;
-               ei.bei_ckids = 1;
-               avl_insert( &ei.bei_kids, (caddr_t)ein, bdb_rdn_cmp,
-                       avl_dup_error );
-       }
-       return rc;
-}
-
-/* Used by hdb_dn2idl when loading the EntryInfo for all the children
- * of a given node
- */
-int hdb_cache_load(
-       struct bdb_info *bdb,
-       EntryInfo *ei,
-       EntryInfo **res )
-{
-       EntryInfo *ei2;
-       int rc;
-
-       /* See if we already have this one */
-       bdb_cache_entryinfo_lock( ei->bei_parent );
-       ei2 = (EntryInfo *)avl_find( ei->bei_parent->bei_kids, ei, bdb_rdn_cmp );
-       bdb_cache_entryinfo_unlock( ei->bei_parent );
-
-       if ( !ei2 ) {
-               /* Not found, add it */
-               struct berval bv;
-
-               /* bei_rdn was not malloc'd before, do it now */
-               ber_dupbv( &bv, &ei->bei_rdn );
-               ei->bei_rdn = bv;
-
-               rc = bdb_entryinfo_add_internal( bdb, ei, res );
-               bdb_cache_entryinfo_unlock( ei->bei_parent );
-               ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-       } else {
-               /* Found, return it */
-               *res = ei2;
-               return 0;
-       }
-       return rc;
-}
-#endif
-
-/* This is best-effort only. If all entries in the cache are
- * busy, they will all be kept. This is unlikely to happen
- * unless the cache is very much smaller than the working set.
- */
-static void
-bdb_cache_lru_purge( struct bdb_info *bdb )
-{
-       DB_LOCK         lock, *lockp;
-       EntryInfo *elru, *elnext = NULL;
-       int islocked;
-       ID eicount, ecount;
-       ID count, efree, eifree = 0;
-#ifdef LDAP_DEBUG
-       int iter;
-#endif
-
-       /* Wait for the mutex; we're the only one trying to purge. */
-       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex );
-
-       if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) {
-               efree = bdb->bi_cache.c_cursize - bdb->bi_cache.c_maxsize;
-               efree += bdb->bi_cache.c_minfree;
-       } else {
-               efree = 0;
-       }
-
-       /* maximum number of EntryInfo leaves to cache. In slapcat
-        * we always free all leaf nodes.
-        */
-
-       if ( slapMode & SLAP_TOOL_READONLY ) {
-               eifree = bdb->bi_cache.c_leaves;
-       } else if ( bdb->bi_cache.c_eimax &&
-               bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) {
-               eifree = bdb->bi_cache.c_minfree * 10;
-               if ( eifree >= bdb->bi_cache.c_leaves )
-                       eifree /= 2;
-       }
-
-       if ( !efree && !eifree ) {
-               ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex );
-               bdb->bi_cache.c_purging = 0;
-               return;
-       }
-
-       if ( bdb->bi_cache.c_txn ) {
-               lockp = &lock;
-       } else {
-               lockp = NULL;
-       }
-
-       count = 0;
-       eicount = 0;
-       ecount = 0;
-#ifdef LDAP_DEBUG
-       iter = 0;
-#endif
-
-       /* Look for an unused entry to remove */
-       for ( elru = bdb->bi_cache.c_lruhead; elru; elru = elnext ) {
-               elnext = elru->bei_lrunext;
-
-               if ( bdb_cache_entryinfo_trylock( elru ))
-                       goto bottom;
-
-               /* This flag implements the clock replacement behavior */
-               if ( elru->bei_state & ( CACHE_ENTRY_REFERENCED )) {
-                       elru->bei_state &= ~CACHE_ENTRY_REFERENCED;
-                       bdb_cache_entryinfo_unlock( elru );
-                       goto bottom;
-               }
-
-               /* If this node is in the process of linking into the cache,
-                * or this node is being deleted, skip it.
-                */
-               if (( elru->bei_state & ( CACHE_ENTRY_NOT_LINKED |
-                       CACHE_ENTRY_DELETED | CACHE_ENTRY_LOADING |
-                       CACHE_ENTRY_ONELEVEL )) ||
-                       elru->bei_finders > 0 ) {
-                       bdb_cache_entryinfo_unlock( elru );
-                       goto bottom;
-               }
-
-               if ( bdb_cache_entryinfo_trylock( elru->bei_parent )) {
-                       bdb_cache_entryinfo_unlock( elru );
-                       goto bottom;
-               }
-
-               /* entryinfo is locked */
-               islocked = 1;
-
-               /* If we can successfully writelock it, then
-                * the object is idle.
-                */
-               if ( bdb_cache_entry_db_lock( bdb,
-                       bdb->bi_cache.c_txn, elru, 1, 1, lockp ) == 0 ) {
-
-                       /* Free entry for this node if it's present */
-                       if ( elru->bei_e ) {
-                               ecount++;
-
-                               /* the cache may have gone over the limit while we
-                                * weren't looking, so double check.
-                                */
-                               if ( !efree && ecount > bdb->bi_cache.c_maxsize )
-                                       efree = bdb->bi_cache.c_minfree;
-
-                               if ( count < efree ) {
-                                       elru->bei_e->e_private = NULL;
-#ifdef SLAP_ZONE_ALLOC
-                                       bdb_entry_return( bdb, elru->bei_e, elru->bei_zseq );
-#else
-                                       bdb_entry_return( elru->bei_e );
-#endif
-                                       elru->bei_e = NULL;
-                                       count++;
-                               } else {
-                                       /* Keep this node cached, skip to next */
-                                       bdb_cache_entry_db_unlock( bdb, lockp );
-                                       goto next;
-                               }
-                       }
-                       bdb_cache_entry_db_unlock( bdb, lockp );
-
-                       /* 
-                        * If it is a leaf node, and we're over the limit, free it.
-                        */
-                       if ( elru->bei_kids ) {
-                               /* Drop from list, we ignore it... */
-                               LRU_DEL( &bdb->bi_cache, elru );
-                       } else if ( eicount < eifree ) {
-                               /* Too many leaf nodes, free this one */
-                               bdb_cache_delete_internal( &bdb->bi_cache, elru, 0 );
-                               bdb_cache_delete_cleanup( &bdb->bi_cache, elru );
-                               islocked = 0;
-                               eicount++;
-                       }       /* Leave on list until we need to free it */
-               }
-
-next:
-               if ( islocked ) {
-                       bdb_cache_entryinfo_unlock( elru );
-                       bdb_cache_entryinfo_unlock( elru->bei_parent );
-               }
-
-               if ( count >= efree && eicount >= eifree )
-                       break;
-bottom:
-               if ( elnext == bdb->bi_cache.c_lruhead )
-                       break;
-#ifdef LDAP_DEBUG
-               iter++;
-#endif
-       }
-
-       if ( count || ecount > bdb->bi_cache.c_cursize ) {
-               ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
-               /* HACK: we seem to be losing track, fix up now */
-               if ( ecount > bdb->bi_cache.c_cursize )
-                       bdb->bi_cache.c_cursize = ecount;
-               bdb->bi_cache.c_cursize -= count;
-               ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
-       }
-       bdb->bi_cache.c_lruhead = elnext;
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex );
-       bdb->bi_cache.c_purging = 0;
-}
-
-/*
- * cache_find_id - find an entry in the cache, given id.
- * The entry is locked for Read upon return. Call with flag ID_LOCKED if
- * the supplied *eip was already locked.
- */
-
-int
-bdb_cache_find_id(
-       Operation *op,
-       DB_TXN  *tid,
-       ID                              id,
-       EntryInfo       **eip,
-       int             flag,
-       DB_LOCK         *lock )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       Entry   *ep = NULL;
-       int     rc = 0, load = 0;
-       EntryInfo ei = { 0 };
-
-       ei.bei_id = id;
-
-#ifdef SLAP_ZONE_ALLOC
-       slap_zh_rlock(bdb->bi_cache.c_zctx);
-#endif
-       /* If we weren't given any info, see if we have it already cached */
-       if ( !*eip ) {
-again: ldap_pvt_thread_rdwr_rlock( &bdb->bi_cache.c_rwlock );
-               *eip = (EntryInfo *) avl_find( bdb->bi_cache.c_idtree,
-                       (caddr_t) &ei, bdb_id_cmp );
-               if ( *eip ) {
-                       /* If the lock attempt fails, the info is in use */
-                       if ( bdb_cache_entryinfo_trylock( *eip )) {
-                               int del = (*eip)->bei_state & CACHE_ENTRY_DELETED;
-                               ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock );
-                               /* If this node is being deleted, treat
-                                * as if the delete has already finished
-                                */
-                               if ( del ) {
-                                       return DB_NOTFOUND;
-                               }
-                               /* otherwise, wait for the info to free up */
-                               ldap_pvt_thread_yield();
-                               goto again;
-                       }
-                       /* If this info isn't hooked up to its parent yet,
-                        * unlock and wait for it to be fully initialized
-                        */
-                       if ( (*eip)->bei_state & CACHE_ENTRY_NOT_LINKED ) {
-                               bdb_cache_entryinfo_unlock( *eip );
-                               ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock );
-                               ldap_pvt_thread_yield();
-                               goto again;
-                       }
-                       flag |= ID_LOCKED;
-               }
-               ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock );
-       }
-
-       /* See if the ID exists in the database; add it to the cache if so */
-       if ( !*eip ) {
-#ifndef BDB_HIER
-               rc = bdb_id2entry( op->o_bd, tid, id, &ep );
-               if ( rc == 0 ) {
-                       rc = bdb_cache_find_ndn( op, tid,
-                               &ep->e_nname, eip );
-                       if ( *eip ) flag |= ID_LOCKED;
-                       if ( rc ) {
-                               ep->e_private = NULL;
-#ifdef SLAP_ZONE_ALLOC
-                               bdb_entry_return( bdb, ep, (*eip)->bei_zseq );
-#else
-                               bdb_entry_return( ep );
-#endif
-                               ep = NULL;
-                       }
-               }
-#else
-               rc = hdb_cache_find_parent(op, tid, id, eip );
-               if ( rc == 0 ) flag |= ID_LOCKED;
-#endif
-       }
-
-       /* Ok, we found the info, do we have the entry? */
-       if ( rc == 0 ) {
-               if ( !( flag & ID_LOCKED )) {
-                       bdb_cache_entryinfo_lock( *eip );
-                       flag |= ID_LOCKED;
-               }
-
-               if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) {
-                       rc = DB_NOTFOUND;
-               } else {
-                       (*eip)->bei_finders++;
-                       (*eip)->bei_state |= CACHE_ENTRY_REFERENCED;
-                       if ( flag & ID_NOENTRY ) {
-                               bdb_cache_entryinfo_unlock( *eip );
-                               return 0;
-                       }
-                       /* Make sure only one thread tries to load the entry */
-load1:
-#ifdef SLAP_ZONE_ALLOC
-                       if ((*eip)->bei_e && !slap_zn_validate(
-                                       bdb->bi_cache.c_zctx, (*eip)->bei_e, (*eip)->bei_zseq)) {
-                               (*eip)->bei_e = NULL;
-                               (*eip)->bei_zseq = 0;
-                       }
-#endif
-                       if ( !(*eip)->bei_e && !((*eip)->bei_state & CACHE_ENTRY_LOADING)) {
-                               load = 1;
-                               (*eip)->bei_state |= CACHE_ENTRY_LOADING;
-                               flag |= ID_CHKPURGE;
-                       }
-
-                       if ( !load ) {
-                               /* Clear the uncached state if we are not
-                                * loading it, i.e it is already cached or
-                                * another thread is currently loading it.
-                                */
-                               if ( (*eip)->bei_state & CACHE_ENTRY_NOT_CACHED ) {
-                                       (*eip)->bei_state ^= CACHE_ENTRY_NOT_CACHED;
-                                       flag |= ID_CHKPURGE;
-                               }
-                       }
-
-                       if ( flag & ID_LOCKED ) {
-                               bdb_cache_entryinfo_unlock( *eip );
-                               flag ^= ID_LOCKED;
-                       }
-                       rc = bdb_cache_entry_db_lock( bdb, tid, *eip, load, 0, lock );
-                       if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) {
-                               rc = DB_NOTFOUND;
-                               bdb_cache_entry_db_unlock( bdb, lock );
-                               bdb_cache_entryinfo_lock( *eip );
-                               (*eip)->bei_finders--;
-                               bdb_cache_entryinfo_unlock( *eip );
-                       } else if ( rc == 0 ) {
-                               if ( load ) {
-                                       if ( !ep) {
-                                               rc = bdb_id2entry( op->o_bd, tid, id, &ep );
-                                       }
-                                       if ( rc == 0 ) {
-                                               ep->e_private = *eip;
-#ifdef BDB_HIER
-                                               while ( (*eip)->bei_state & CACHE_ENTRY_NOT_LINKED )
-                                                       ldap_pvt_thread_yield();
-                                               bdb_fix_dn( ep, 0 );
-#endif
-                                               bdb_cache_entryinfo_lock( *eip );
-
-                                               (*eip)->bei_e = ep;
-#ifdef SLAP_ZONE_ALLOC
-                                               (*eip)->bei_zseq = *((ber_len_t *)ep - 2);
-#endif
-                                               ep = NULL;
-                                               if ( flag & ID_NOCACHE ) {
-                                                       /* Set the cached state only if no other thread
-                                                        * found the info while we were loading the entry.
-                                                        */
-                                                       if ( (*eip)->bei_finders == 1 ) {
-                                                               (*eip)->bei_state |= CACHE_ENTRY_NOT_CACHED;
-                                                               flag ^= ID_CHKPURGE;
-                                                       }
-                                               }
-                                               bdb_cache_entryinfo_unlock( *eip );
-                                               bdb_cache_lru_link( bdb, *eip );
-                                       }
-                                       if ( rc == 0 ) {
-                                               /* If we succeeded, downgrade back to a readlock. */
-                                               rc = bdb_cache_entry_db_relock( bdb, tid,
-                                                       *eip, 0, 0, lock );
-                                       } else {
-                                               /* Otherwise, release the lock. */
-                                               bdb_cache_entry_db_unlock( bdb, lock );
-                                       }
-                               } else if ( !(*eip)->bei_e ) {
-                                       /* Some other thread is trying to load the entry,
-                                        * wait for it to finish.
-                                        */
-                                       bdb_cache_entry_db_unlock( bdb, lock );
-                                       bdb_cache_entryinfo_lock( *eip );
-                                       flag |= ID_LOCKED;
-                                       goto load1;
-#ifdef BDB_HIER
-                               } else {
-                                       /* Check for subtree renames
-                                        */
-                                       rc = bdb_fix_dn( (*eip)->bei_e, 1 );
-                                       if ( rc ) {
-                                               bdb_cache_entry_db_relock( bdb,
-                                                       tid, *eip, 1, 0, lock );
-                                               /* check again in case other modifier did it already */
-                                               if ( bdb_fix_dn( (*eip)->bei_e, 1 ) )
-                                                       rc = bdb_fix_dn( (*eip)->bei_e, 2 );
-                                               bdb_cache_entry_db_relock( bdb,
-                                                       tid, *eip, 0, 0, lock );
-                                       }
-#endif
-                               }
-                               bdb_cache_entryinfo_lock( *eip );
-                               (*eip)->bei_finders--;
-                               if ( load )
-                                       (*eip)->bei_state ^= CACHE_ENTRY_LOADING;
-                               bdb_cache_entryinfo_unlock( *eip );
-                       }
-               }
-       }
-       if ( flag & ID_LOCKED ) {
-               bdb_cache_entryinfo_unlock( *eip );
-       }
-       if ( ep ) {
-               ep->e_private = NULL;
-#ifdef SLAP_ZONE_ALLOC
-               bdb_entry_return( bdb, ep, (*eip)->bei_zseq );
-#else
-               bdb_entry_return( ep );
-#endif
-       }
-       if ( rc == 0 ) {
-               int purge = 0;
-
-               if (( flag & ID_CHKPURGE ) || bdb->bi_cache.c_eimax ) {
-                       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
-                       if ( flag & ID_CHKPURGE ) {
-                               bdb->bi_cache.c_cursize++;
-                               if ( !bdb->bi_cache.c_purging && bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) {
-                                       purge = 1;
-                                       bdb->bi_cache.c_purging = 1;
-                               }
-                       } else if ( !bdb->bi_cache.c_purging && bdb->bi_cache.c_eimax && bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) {
-                               purge = 1;
-                               bdb->bi_cache.c_purging = 1;
-                       }
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
-               }
-               if ( purge )
-                       bdb_cache_lru_purge( bdb );
-       }
-
-#ifdef SLAP_ZONE_ALLOC
-       if (rc == 0 && (*eip)->bei_e) {
-               slap_zn_rlock(bdb->bi_cache.c_zctx, (*eip)->bei_e);
-       }
-       slap_zh_runlock(bdb->bi_cache.c_zctx);
-#endif
-       return rc;
-}
-
-int
-bdb_cache_children(
-       Operation *op,
-       DB_TXN *txn,
-       Entry *e )
-{
-       int rc;
-
-       if ( BEI(e)->bei_kids ) {
-               return 0;
-       }
-       if ( BEI(e)->bei_state & CACHE_ENTRY_NO_KIDS ) {
-               return DB_NOTFOUND;
-       }
-       rc = bdb_dn2id_children( op, txn, e );
-       if ( rc == DB_NOTFOUND ) {
-               BEI(e)->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
-       }
-       return rc;
-}
-
-/* Update the cache after a successful database Add. */
-int
-bdb_cache_add(
-       struct bdb_info *bdb,
-       EntryInfo *eip,
-       Entry *e,
-       struct berval *nrdn,
-       DB_TXN *txn,
-       DB_LOCK *lock )
-{
-       EntryInfo *new, ei;
-       int rc, purge = 0;
-#ifdef BDB_HIER
-       struct berval rdn = e->e_name;
-#endif
-
-       ei.bei_id = e->e_id;
-       ei.bei_parent = eip;
-       ei.bei_nrdn = *nrdn;
-       ei.bei_lockpad = 0;
-
-#if 0
-       /* Lock this entry so that bdb_add can run to completion.
-        * It can only fail if BDB has run out of lock resources.
-        */
-       rc = bdb_cache_entry_db_lock( bdb, txn, &ei, 0, 0, lock );
-       if ( rc ) {
-               bdb_cache_entryinfo_unlock( eip );
-               return rc;
-       }
-#endif
-
-#ifdef BDB_HIER
-       if ( nrdn->bv_len != e->e_nname.bv_len ) {
-               char *ptr = ber_bvchr( &rdn, ',' );
-               assert( ptr != NULL );
-               rdn.bv_len = ptr - rdn.bv_val;
-       }
-       ber_dupbv( &ei.bei_rdn, &rdn );
-       if ( eip->bei_dkids ) eip->bei_dkids++;
-#endif
-
-       if (eip->bei_parent) {
-               bdb_cache_entryinfo_lock( eip->bei_parent );
-               eip->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS;
-               bdb_cache_entryinfo_unlock( eip->bei_parent );
-       }
-
-       rc = bdb_entryinfo_add_internal( bdb, &ei, &new );
-       /* bdb_csn_commit can cause this when adding the database root entry */
-       if ( new->bei_e ) {
-               new->bei_e->e_private = NULL;
-#ifdef SLAP_ZONE_ALLOC
-               bdb_entry_return( bdb, new->bei_e, new->bei_zseq );
-#else
-               bdb_entry_return( new->bei_e );
-#endif
-       }
-       new->bei_e = e;
-       e->e_private = new;
-       new->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
-       eip->bei_state &= ~CACHE_ENTRY_NO_KIDS;
-       bdb_cache_entryinfo_unlock( eip );
-
-       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
-       ++bdb->bi_cache.c_cursize;
-       if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize &&
-               !bdb->bi_cache.c_purging ) {
-               purge = 1;
-               bdb->bi_cache.c_purging = 1;
-       }
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
-
-       new->bei_finders = 1;
-       bdb_cache_lru_link( bdb, new );
-
-       if ( purge )
-               bdb_cache_lru_purge( bdb );
-
-       return rc;
-}
-
-void bdb_cache_deref(
-       EntryInfo *ei
-       )
-{
-       bdb_cache_entryinfo_lock( ei );
-       ei->bei_finders--;
-       bdb_cache_entryinfo_unlock( ei );
-}
-
-int
-bdb_cache_modify(
-       struct bdb_info *bdb,
-       Entry *e,
-       Attribute *newAttrs,
-       DB_TXN *txn,
-       DB_LOCK *lock )
-{
-       EntryInfo *ei = BEI(e);
-       int rc;
-       /* Get write lock on data */
-       rc = bdb_cache_entry_db_relock( bdb, txn, ei, 1, 0, lock );
-
-       /* If we've done repeated mods on a cached entry, then e_attrs
-        * is no longer contiguous with the entry, and must be freed.
-        */
-       if ( ! rc ) {
-               if ( (void *)e->e_attrs != (void *)(e+1) ) {
-                       attrs_free( e->e_attrs ); 
-               }
-               e->e_attrs = newAttrs;
-       }
-       return rc;
-}
-
-/*
- * Change the rdn in the entryinfo. Also move to a new parent if needed.
- */
-int
-bdb_cache_modrdn(
-       struct bdb_info *bdb,
-       Entry *e,
-       struct berval *nrdn,
-       Entry *new,
-       EntryInfo *ein,
-       DB_TXN *txn,
-       DB_LOCK *lock )
-{
-       EntryInfo *ei = BEI(e), *pei;
-       int rc;
-#ifdef BDB_HIER
-       struct berval rdn;
-#endif
-
-       /* Get write lock on data */
-       rc =  bdb_cache_entry_db_relock( bdb, txn, ei, 1, 0, lock );
-       if ( rc ) return rc;
-
-       /* If we've done repeated mods on a cached entry, then e_attrs
-        * is no longer contiguous with the entry, and must be freed.
-        */
-       if ( (void *)e->e_attrs != (void *)(e+1) && e->e_attrs != new->e_attrs ) {
-               attrs_free( e->e_attrs );
-       }
-       e->e_attrs = new->e_attrs;
-       if( e->e_nname.bv_val < e->e_bv.bv_val ||
-               e->e_nname.bv_val > e->e_bv.bv_val + e->e_bv.bv_len )
-       {
-               ch_free(e->e_name.bv_val);
-               ch_free(e->e_nname.bv_val);
-       }
-       e->e_name = new->e_name;
-       e->e_nname = new->e_nname;
-
-       /* Lock the parent's kids AVL tree */
-       pei = ei->bei_parent;
-       bdb_cache_entryinfo_lock( pei );
-       avl_delete( &pei->bei_kids, (caddr_t) ei, bdb_rdn_cmp );
-       free( ei->bei_nrdn.bv_val );
-       ber_dupbv( &ei->bei_nrdn, nrdn );
-
-#ifdef BDB_HIER
-       free( ei->bei_rdn.bv_val );
-
-       rdn = e->e_name;
-       if ( nrdn->bv_len != e->e_nname.bv_len ) {
-               char *ptr = ber_bvchr(&rdn, ',');
-               assert( ptr != NULL );
-               rdn.bv_len = ptr - rdn.bv_val;
-       }
-       ber_dupbv( &ei->bei_rdn, &rdn );
-
-       /* If new parent, decrement kid counts */
-       if ( ein ) {
-               pei->bei_ckids--;
-               if ( pei->bei_dkids ) {
-                       pei->bei_dkids--;
-                       if ( pei->bei_dkids < 2 )
-                               pei->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
-               }
-       }
-#endif
-
-       if (!ein) {
-               ein = ei->bei_parent;
-       } else {
-               ei->bei_parent = ein;
-               bdb_cache_entryinfo_unlock( pei );
-               bdb_cache_entryinfo_lock( ein );
-
-               /* new parent now has kids */
-               if ( ein->bei_state & CACHE_ENTRY_NO_KIDS )
-                       ein->bei_state ^= CACHE_ENTRY_NO_KIDS;
-               /* grandparent has grandkids */
-               if ( ein->bei_parent )
-                       ein->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS;
-#ifdef BDB_HIER
-               /* parent might now have grandkids */
-               if ( ein->bei_state & CACHE_ENTRY_NO_GRANDKIDS &&
-                       !(ei->bei_state & CACHE_ENTRY_NO_KIDS))
-                       ein->bei_state ^= CACHE_ENTRY_NO_GRANDKIDS;
-
-               ein->bei_ckids++;
-               if ( ein->bei_dkids ) ein->bei_dkids++;
-#endif
-       }
-
-#ifdef BDB_HIER
-       /* Record the generation number of this change */
-       ldap_pvt_thread_mutex_lock( &bdb->bi_modrdns_mutex );
-       bdb->bi_modrdns++;
-       ei->bei_modrdns = bdb->bi_modrdns;
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_modrdns_mutex );
-#endif
-
-       avl_insert( &ein->bei_kids, ei, bdb_rdn_cmp, avl_dup_error );
-       bdb_cache_entryinfo_unlock( ein );
-       return rc;
-}
-/*
- * cache_delete - delete the entry e from the cache. 
- *
- * returns:    0       e was deleted ok
- *             1       e was not in the cache
- *             -1      something bad happened
- */
-int
-bdb_cache_delete(
-       struct bdb_info *bdb,
-    Entry              *e,
-    DB_TXN *txn,
-    DB_LOCK    *lock )
-{
-       EntryInfo *ei = BEI(e);
-       int     rc, busy = 0, counter = 0;
-
-       assert( e->e_private != NULL );
-
-       /* Lock the entry's info */
-       bdb_cache_entryinfo_lock( ei );
-
-       /* Set this early, warn off any queriers */
-       ei->bei_state |= CACHE_ENTRY_DELETED;
-
-       if (( ei->bei_state & ( CACHE_ENTRY_NOT_LINKED |
-               CACHE_ENTRY_LOADING | CACHE_ENTRY_ONELEVEL )) ||
-               ei->bei_finders > 0 )
-               busy = 1;
-
-       bdb_cache_entryinfo_unlock( ei );
-
-       while ( busy && counter < 1000) {
-               ldap_pvt_thread_yield();
-               busy = 0;
-               bdb_cache_entryinfo_lock( ei );
-               if (( ei->bei_state & ( CACHE_ENTRY_NOT_LINKED |
-                       CACHE_ENTRY_LOADING | CACHE_ENTRY_ONELEVEL )) ||
-                       ei->bei_finders > 0 )
-                       busy = 1;
-               bdb_cache_entryinfo_unlock( ei );
-               counter ++;
-       }
-       if( busy ) {
-               bdb_cache_entryinfo_lock( ei );
-               ei->bei_state ^= CACHE_ENTRY_DELETED;
-               bdb_cache_entryinfo_unlock( ei );
-               return DB_LOCK_DEADLOCK;
-       }
-
-       /* Get write lock on the data */
-       rc = bdb_cache_entry_db_relock( bdb, txn, ei, 1, 0, lock );
-       if ( rc ) {
-               bdb_cache_entryinfo_lock( ei );
-               /* couldn't lock, undo and give up */
-               ei->bei_state ^= CACHE_ENTRY_DELETED;
-               bdb_cache_entryinfo_unlock( ei );
-               return rc;
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "====> bdb_cache_delete( %ld )\n",
-               e->e_id );
-
-       /* set lru mutex */
-       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex );
-
-       bdb_cache_entryinfo_lock( ei->bei_parent );
-       bdb_cache_entryinfo_lock( ei );
-       rc = bdb_cache_delete_internal( &bdb->bi_cache, e->e_private, 1 );
-       bdb_cache_entryinfo_unlock( ei );
-
-       /* free lru mutex */
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex );
-
-       return( rc );
-}
-
-void
-bdb_cache_delete_cleanup(
-       Cache *cache,
-       EntryInfo *ei )
-{
-       /* Enter with ei locked */
-
-       /* already freed? */
-       if ( !ei->bei_parent ) return;
-
-       if ( ei->bei_e ) {
-               ei->bei_e->e_private = NULL;
-#ifdef SLAP_ZONE_ALLOC
-               bdb_entry_return( ei->bei_bdb, ei->bei_e, ei->bei_zseq );
-#else
-               bdb_entry_return( ei->bei_e );
-#endif
-               ei->bei_e = NULL;
-       }
-
-       bdb_cache_entryinfo_unlock( ei );
-       bdb_cache_entryinfo_free( cache, ei );
-}
-
-static int
-bdb_cache_delete_internal(
-    Cache      *cache,
-    EntryInfo          *e,
-    int                decr )
-{
-       int rc = 0;     /* return code */
-       int decr_leaf = 0;
-
-       /* already freed? */
-       if ( !e->bei_parent ) {
-               assert(0);
-               return -1;
-       }
-
-#ifdef BDB_HIER
-       e->bei_parent->bei_ckids--;
-       if ( decr && e->bei_parent->bei_dkids ) e->bei_parent->bei_dkids--;
-#endif
-       /* dn tree */
-       if ( avl_delete( &e->bei_parent->bei_kids, (caddr_t) e, bdb_rdn_cmp )
-               == NULL )
-       {
-               rc = -1;
-               assert(0);
-       }
-       if ( e->bei_parent->bei_kids )
-               decr_leaf = 1;
-
-       ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
-       /* id tree */
-       if ( avl_delete( &cache->c_idtree, (caddr_t) e, bdb_id_cmp )) {
-               cache->c_eiused--;
-               if ( decr_leaf )
-                       cache->c_leaves--;
-       } else {
-               rc = -1;
-               assert(0);
-       }
-       ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
-       bdb_cache_entryinfo_unlock( e->bei_parent );
-
-       if ( rc == 0 ){
-               /* lru */
-               LRU_DEL( cache, e );
-
-               if ( e->bei_e ) {
-                       ldap_pvt_thread_mutex_lock( &cache->c_count_mutex );
-                       cache->c_cursize--;
-                       ldap_pvt_thread_mutex_unlock( &cache->c_count_mutex );
-               }
-       }
-
-       return( rc );
-}
-
-static void
-bdb_entryinfo_release( void *data )
-{
-       EntryInfo *ei = (EntryInfo *)data;
-       if ( ei->bei_kids ) {
-               avl_free( ei->bei_kids, NULL );
-       }
-       if ( ei->bei_e ) {
-               ei->bei_e->e_private = NULL;
-#ifdef SLAP_ZONE_ALLOC
-               bdb_entry_return( ei->bei_bdb, ei->bei_e, ei->bei_zseq );
-#else
-               bdb_entry_return( ei->bei_e );
-#endif
-       }
-       bdb_cache_entryinfo_destroy( ei );
-}
-
-void
-bdb_cache_release_all( Cache *cache )
-{
-       /* set cache write lock */
-       ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
-       /* set lru mutex */
-       ldap_pvt_thread_mutex_lock( &cache->c_lru_mutex );
-
-       Debug( LDAP_DEBUG_TRACE, "====> bdb_cache_release_all\n" );
-
-       avl_free( cache->c_dntree.bei_kids, NULL );
-       avl_free( cache->c_idtree, bdb_entryinfo_release );
-       for (;cache->c_eifree;cache->c_eifree = cache->c_lruhead) {
-               cache->c_lruhead = cache->c_eifree->bei_lrunext;
-               bdb_cache_entryinfo_destroy(cache->c_eifree);
-       }
-       cache->c_cursize = 0;
-       cache->c_eiused = 0;
-       cache->c_leaves = 0;
-       cache->c_idtree = NULL;
-       cache->c_lruhead = NULL;
-       cache->c_lrutail = NULL;
-       cache->c_dntree.bei_kids = NULL;
-
-       /* free lru mutex */
-       ldap_pvt_thread_mutex_unlock( &cache->c_lru_mutex );
-       /* free cache write lock */
-       ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
-}
-
-#ifdef LDAP_DEBUG
-static void
-bdb_lru_count( Cache *cache )
-{
-       EntryInfo       *e;
-       int ei = 0, ent = 0, nc = 0;
-
-       for ( e = cache->c_lrutail; ; ) {
-               ei++;
-               if ( e->bei_e ) {
-                       ent++;
-                       if ( e->bei_state & CACHE_ENTRY_NOT_CACHED )
-                               nc++;
-                       fprintf( stderr, "ei %d entry %p dn %s\n", ei, (void *) e->bei_e, e->bei_e->e_name.bv_val );
-               }
-               e = e->bei_lrunext;
-               if ( e == cache->c_lrutail )
-                       break;
-       }
-       fprintf( stderr, "counted %d entryInfos and %d entries, %d notcached\n",
-               ei, ent, nc );
-       ei = 0;
-       for ( e = cache->c_lrutail; ; ) {
-               ei++;
-               e = e->bei_lruprev;
-               if ( e == cache->c_lrutail )
-                       break;
-       }
-       fprintf( stderr, "counted %d entryInfos (on lruprev)\n", ei );
-}
-
-#ifdef SLAPD_UNUSED
-static void
-bdb_lru_print( Cache *cache )
-{
-       EntryInfo       *e;
-
-       fprintf( stderr, "LRU circle head: %p\n", (void *) cache->c_lruhead );
-       fprintf( stderr, "LRU circle (tail forward):\n" );
-       for ( e = cache->c_lrutail; ; ) {
-               fprintf( stderr, "\t%p, %p id %ld rdn \"%s\"\n",
-                       (void *) e, (void *) e->bei_e, e->bei_id, e->bei_nrdn.bv_val );
-               e = e->bei_lrunext;
-               if ( e == cache->c_lrutail )
-                       break;
-       }
-       fprintf( stderr, "LRU circle (tail backward):\n" );
-       for ( e = cache->c_lrutail; ; ) {
-               fprintf( stderr, "\t%p, %p id %ld rdn \"%s\"\n",
-                       (void *) e, (void *) e->bei_e, e->bei_id, e->bei_nrdn.bv_val );
-               e = e->bei_lruprev;
-               if ( e == cache->c_lrutail )
-                       break;
-       }
-}
-
-static int
-bdb_entryinfo_print(void *data, void *arg)
-{
-       EntryInfo *e = data;
-       fprintf( stderr, "\t%p, %p id %ld rdn \"%s\"\n",
-               (void *) e, (void *) e->bei_e, e->bei_id, e->bei_nrdn.bv_val );
-       return 0;
-}
-
-static void
-bdb_idtree_print(Cache *cache)
-{
-       avl_apply( cache->c_idtree, bdb_entryinfo_print, NULL, -1, AVL_INORDER );
-}
-#endif
-#endif
-
-static void
-bdb_reader_free( void *key, void *data )
-{
-       /* DB_ENV *env = key; */
-       DB_TXN *txn = data;
-
-       if ( txn ) TXN_ABORT( txn );
-}
-
-/* free up any keys used by the main thread */
-void
-bdb_reader_flush( DB_ENV *env )
-{
-       void *data;
-       void *ctx = ldap_pvt_thread_pool_context();
-
-       if ( !ldap_pvt_thread_pool_getkey( ctx, env, &data, NULL ) ) {
-               ldap_pvt_thread_pool_setkey( ctx, env, NULL, 0, NULL, NULL );
-               bdb_reader_free( env, data );
-       }
-}
-
-int
-bdb_reader_get( Operation *op, DB_ENV *env, DB_TXN **txn )
-{
-       int i, rc;
-       void *data;
-       void *ctx;
-
-       if ( !env || !txn ) return -1;
-
-       /* If no op was provided, try to find the ctx anyway... */
-       if ( op ) {
-               ctx = op->o_threadctx;
-       } else {
-               ctx = ldap_pvt_thread_pool_context();
-       }
-
-       /* Shouldn't happen unless we're single-threaded */
-       if ( !ctx ) {
-               *txn = NULL;
-               return 0;
-       }
-
-       if ( ldap_pvt_thread_pool_getkey( ctx, env, &data, NULL ) ) {
-               for ( i=0, rc=1; rc != 0 && i<4; i++ ) {
-                       rc = TXN_BEGIN( env, NULL, txn, DB_READ_COMMITTED );
-                       if (rc) ldap_pvt_thread_yield();
-               }
-               if ( rc != 0) {
-                       return rc;
-               }
-               data = *txn;
-               if ( ( rc = ldap_pvt_thread_pool_setkey( ctx, env,
-                       data, bdb_reader_free, NULL, NULL ) ) ) {
-                       TXN_ABORT( *txn );
-                       Debug( LDAP_DEBUG_ANY, "bdb_reader_get: err %s(%d)\n",
-                               db_strerror(rc), rc );
-
-                       return rc;
-               }
-       } else {
-               *txn = data;
-       }
-       return 0;
-}
diff --git a/servers/slapd/back-bdb/compare.c b/servers/slapd/back-bdb/compare.c
deleted file mode 100644 (file)
index 7e573ea..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/* compare.c - bdb backend compare routine */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-
-int
-bdb_compare( Operation *op, SlapReply *rs )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       Entry           *e = NULL;
-       EntryInfo       *ei;
-       int             manageDSAit = get_manageDSAit( op );
-
-       DB_TXN          *rtxn;
-       DB_LOCK         lock;
-
-       rs->sr_err = bdb_reader_get(op, bdb->bi_dbenv, &rtxn);
-       switch(rs->sr_err) {
-       case 0:
-               break;
-       default:
-               send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-               return rs->sr_err;
-       }
-
-dn2entry_retry:
-       /* get entry */
-       rs->sr_err = bdb_dn2entry( op, rtxn, &op->o_req_ndn, &ei, 1,
-               &lock );
-
-       switch( rs->sr_err ) {
-       case DB_NOTFOUND:
-       case 0:
-               break;
-       case LDAP_BUSY:
-               rs->sr_text = "ldap server busy";
-               goto return_results;
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               goto dn2entry_retry;
-       default:
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-
-       e = ei->bei_e;
-       if ( rs->sr_err == DB_NOTFOUND ) {
-               if ( e != NULL ) {
-                       /* return referral only if "disclose" is granted on the object */
-                       if ( ! access_allowed( op, e, slap_schema.si_ad_entry,
-                               NULL, ACL_DISCLOSE, NULL ) )
-                       {
-                               rs->sr_err = LDAP_NO_SUCH_OBJECT;
-
-                       } else {
-                               rs->sr_matched = ch_strdup( e->e_dn );
-                               rs->sr_ref = is_entry_referral( e )
-                                       ? get_entry_referrals( op, e )
-                                       : NULL;
-                               rs->sr_err = LDAP_REFERRAL;
-                       }
-
-                       bdb_cache_return_entry_r( bdb, e, &lock );
-                       e = NULL;
-
-               } else {
-                       rs->sr_ref = referral_rewrite( default_referral,
-                               NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
-                       rs->sr_err = rs->sr_ref ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT;
-               }
-
-               send_ldap_result( op, rs );
-
-               ber_bvarray_free( rs->sr_ref );
-               free( (char *)rs->sr_matched );
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-
-               goto done;
-       }
-
-       if (!manageDSAit && is_entry_referral( e ) ) {
-               /* return referral only if "disclose" is granted on the object */
-               if ( !access_allowed( op, e, slap_schema.si_ad_entry,
-                       NULL, ACL_DISCLOSE, NULL ) )
-               {
-                       rs->sr_err = LDAP_NO_SUCH_OBJECT;
-               } else {
-                       /* entry is a referral, don't allow compare */
-                       rs->sr_ref = get_entry_referrals( op, e );
-                       rs->sr_err = LDAP_REFERRAL;
-                       rs->sr_matched = e->e_name.bv_val;
-               }
-
-               Debug( LDAP_DEBUG_TRACE, "entry is referral\n" );
-
-               send_ldap_result( op, rs );
-
-               ber_bvarray_free( rs->sr_ref );
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-               goto done;
-       }
-
-       rs->sr_err = slap_compare_entry( op, e, op->orc_ava );
-
-return_results:
-       send_ldap_result( op, rs );
-
-       switch ( rs->sr_err ) {
-       case LDAP_COMPARE_FALSE:
-       case LDAP_COMPARE_TRUE:
-               rs->sr_err = LDAP_SUCCESS;
-               break;
-       }
-
-done:
-       /* free entry */
-       if ( e != NULL ) {
-               bdb_cache_return_entry_r( bdb, e, &lock );
-       }
-
-       return rs->sr_err;
-}
diff --git a/servers/slapd/back-bdb/config.c b/servers/slapd/back-bdb/config.c
deleted file mode 100644 (file)
index 30e0363..0000000
+++ /dev/null
@@ -1,967 +0,0 @@
-/* config.c - bdb backend configuration file routine */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/ctype.h>
-#include <ac/string.h>
-#include <ac/errno.h>
-
-#include "back-bdb.h"
-
-#include "config.h"
-
-#include "lutil.h"
-#include "ldap_rq.h"
-
-#ifdef DB_DIRTY_READ
-#      define  SLAP_BDB_ALLOW_DIRTY_READ
-#endif
-
-#define bdb_cf_gen             BDB_SYMBOL(cf_gen)
-#define        bdb_cf_cleanup          BDB_SYMBOL(cf_cleanup)
-#define bdb_checkpoint         BDB_SYMBOL(checkpoint)
-#define bdb_online_index       BDB_SYMBOL(online_index)
-
-static ConfigDriver bdb_cf_gen;
-
-enum {
-       BDB_CHKPT = 1,
-       BDB_CONFIG,
-       BDB_CRYPTFILE,
-       BDB_CRYPTKEY,
-       BDB_DIRECTORY,
-       BDB_NOSYNC,
-       BDB_DIRTYR,
-       BDB_INDEX,
-       BDB_LOCKD,
-       BDB_SSTACK,
-       BDB_MODE,
-       BDB_PGSIZE,
-       BDB_CHECKSUM
-};
-
-static ConfigTable bdbcfg[] = {
-       { "directory", "dir", 2, 2, 0, ARG_STRING|ARG_MAGIC|BDB_DIRECTORY,
-               bdb_cf_gen, "( OLcfgDbAt:0.1 NAME 'olcDbDirectory' "
-                       "DESC 'Directory for database content' "
-                       "EQUALITY caseIgnoreMatch "
-                       "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
-       { "cachefree", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET,
-               (void *)offsetof(struct bdb_info, bi_cache.c_minfree),
-               "( OLcfgDbAt:1.11 NAME 'olcDbCacheFree' "
-                       "DESC 'Number of extra entries to free when max is reached' "
-                       "EQUALITY integerMatch "
-                       "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { "cachesize", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET,
-               (void *)offsetof(struct bdb_info, bi_cache.c_maxsize),
-               "( OLcfgDbAt:1.1 NAME 'olcDbCacheSize' "
-                       "DESC 'Entry cache size in entries' "
-                       "EQUALITY integerMatch "
-                       "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { "checkpoint", "kbyte> <min", 3, 3, 0, ARG_MAGIC|BDB_CHKPT,
-               bdb_cf_gen, "( OLcfgDbAt:1.2 NAME 'olcDbCheckpoint' "
-                       "DESC 'Database checkpoint interval in kbytes and minutes' "
-                       "EQUALITY caseIgnoreMatch "
-                       "SYNTAX OMsDirectoryString SINGLE-VALUE )",NULL, NULL },
-       { "checksum", NULL, 1, 2, 0, ARG_ON_OFF|ARG_MAGIC|BDB_CHECKSUM,
-               bdb_cf_gen, "( OLcfgDbAt:1.16 NAME 'olcDbChecksum' "
-                       "DESC 'Enable database checksum validation' "
-                       "EQUALITY booleanMatch "
-                       "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
-       { "cryptfile", "file", 2, 2, 0, ARG_STRING|ARG_MAGIC|BDB_CRYPTFILE,
-               bdb_cf_gen, "( OLcfgDbAt:1.13 NAME 'olcDbCryptFile' "
-                       "DESC 'Pathname of file containing the DB encryption key' "
-                       "EQUALITY caseExactMatch "
-                       "SYNTAX OMsDirectoryString SINGLE-VALUE )",NULL, NULL },
-       { "cryptkey", "key", 2, 2, 0, ARG_BERVAL|ARG_MAGIC|BDB_CRYPTKEY,
-               bdb_cf_gen, "( OLcfgDbAt:1.14 NAME 'olcDbCryptKey' "
-                       "DESC 'DB encryption key' "
-                       "EQUALITY octetStringMatch "
-                       "SYNTAX OMsOctetString SINGLE-VALUE )",NULL, NULL },
-       { "dbconfig", "DB_CONFIG setting", 1, 0, 0, ARG_MAGIC|BDB_CONFIG,
-               bdb_cf_gen, "( OLcfgDbAt:1.3 NAME 'olcDbConfig' "
-                       "DESC 'BerkeleyDB DB_CONFIG configuration directives' "
-                       "EQUALITY caseIgnoreIA5Match "
-                       "SYNTAX OMsIA5String X-ORDERED 'VALUES' )", NULL, NULL },
-       { "dbnosync", NULL, 1, 2, 0, ARG_ON_OFF|ARG_MAGIC|BDB_NOSYNC,
-               bdb_cf_gen, "( OLcfgDbAt:1.4 NAME 'olcDbNoSync' "
-                       "DESC 'Disable synchronous database writes' "
-                       "EQUALITY booleanMatch "
-                       "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
-       { "dbpagesize", "db> <size", 3, 3, 0, ARG_MAGIC|BDB_PGSIZE,
-               bdb_cf_gen, "( OLcfgDbAt:1.15 NAME 'olcDbPageSize' "
-                       "DESC 'Page size of specified DB, in Kbytes' "
-                       "EQUALITY caseExactMatch "
-                       "SYNTAX OMsDirectoryString )", NULL, NULL },
-       { "dirtyread", NULL, 1, 2, 0,
-#ifdef SLAP_BDB_ALLOW_DIRTY_READ
-               ARG_ON_OFF|ARG_MAGIC|BDB_DIRTYR, bdb_cf_gen,
-#else
-               ARG_IGNORED, NULL,
-#endif
-               "( OLcfgDbAt:1.5 NAME 'olcDbDirtyRead' "
-               "DESC 'Allow reads of uncommitted data' "
-               "EQUALITY booleanMatch "
-               "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
-       { "dncachesize", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET,
-               (void *)offsetof(struct bdb_info, bi_cache.c_eimax),
-               "( OLcfgDbAt:1.12 NAME 'olcDbDNcacheSize' "
-                       "DESC 'DN cache size' "
-                       "EQUALITY integerMatch "
-                       "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { "idlcachesize", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET,
-               (void *)offsetof(struct bdb_info, bi_idl_cache_max_size),
-               "( OLcfgDbAt:1.6 NAME 'olcDbIDLcacheSize' "
-               "DESC 'IDL cache size in IDLs' "
-               "EQUALITY integerMatch "
-               "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { "index", "attr> <[pres,eq,approx,sub]", 2, 3, 0, ARG_MAGIC|BDB_INDEX,
-               bdb_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' "
-               "DESC 'Attribute index parameters' "
-               "EQUALITY caseIgnoreMatch "
-               "SYNTAX OMsDirectoryString )", NULL, NULL },
-       { "linearindex", NULL, 1, 2, 0, ARG_ON_OFF|ARG_OFFSET,
-               (void *)offsetof(struct bdb_info, bi_linear_index), 
-               "( OLcfgDbAt:1.7 NAME 'olcDbLinearIndex' "
-               "DESC 'Index attributes one at a time' "
-               "EQUALITY booleanMatch "
-               "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
-       { "lockdetect", "policy", 2, 2, 0, ARG_MAGIC|BDB_LOCKD,
-               bdb_cf_gen, "( OLcfgDbAt:1.8 NAME 'olcDbLockDetect' "
-               "DESC 'Deadlock detection algorithm' "
-               "EQUALITY caseIgnoreMatch "
-               "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
-       { "mode", "mode", 2, 2, 0, ARG_MAGIC|BDB_MODE,
-               bdb_cf_gen, "( OLcfgDbAt:0.3 NAME 'olcDbMode' "
-               "DESC 'Unix permissions of database files' "
-               "EQUALITY caseIgnoreMatch "
-               "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
-       { "searchstack", "depth", 2, 2, 0, ARG_INT|ARG_MAGIC|BDB_SSTACK,
-               bdb_cf_gen, "( OLcfgDbAt:1.9 NAME 'olcDbSearchStack' "
-               "DESC 'Depth of search stack in IDLs' "
-               "EQUALITY integerMatch "
-               "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { "shm_key", "key", 2, 2, 0, ARG_LONG|ARG_OFFSET,
-               (void *)offsetof(struct bdb_info, bi_shm_key), 
-               "( OLcfgDbAt:1.10 NAME 'olcDbShmKey' "
-               "DESC 'Key for shared memory region' "
-               "EQUALITY integerMatch "
-               "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { NULL, NULL, 0, 0, 0, ARG_IGNORED,
-               NULL, NULL, NULL, NULL }
-};
-
-static ConfigOCs bdbocs[] = {
-       {
-#ifdef BDB_HIER
-               "( OLcfgDbOc:1.2 "
-               "NAME 'olcHdbConfig' "
-               "DESC 'HDB backend configuration' "
-#else
-               "( OLcfgDbOc:1.1 "
-               "NAME 'olcBdbConfig' "
-               "DESC 'BDB backend configuration' "
-#endif
-               "SUP olcDatabaseConfig "
-               "MUST olcDbDirectory "
-               "MAY ( olcDbCacheSize $ olcDbCheckpoint $ olcDbChecksum $ "
-               "olcDbConfig $ olcDbCryptFile $ olcDbCryptKey $ "
-               "olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ "
-               "olcDbIndex $ olcDbLinearIndex $ olcDbLockDetect $ "
-               "olcDbMode $ olcDbSearchStack $ olcDbShmKey $ "
-               "olcDbCacheFree $ olcDbDNcacheSize $ olcDbPageSize ) )",
-                       Cft_Database, bdbcfg },
-       { NULL, 0, NULL }
-};
-
-static slap_verbmasks bdb_lockd[] = {
-       { BER_BVC("default"), DB_LOCK_DEFAULT },
-       { BER_BVC("oldest"), DB_LOCK_OLDEST },
-       { BER_BVC("random"), DB_LOCK_RANDOM },
-       { BER_BVC("youngest"), DB_LOCK_YOUNGEST },
-       { BER_BVC("fewest"), DB_LOCK_MINLOCKS },
-       { BER_BVNULL, 0 }
-};
-
-/* perform periodic checkpoints */
-static void *
-bdb_checkpoint( void *ctx, void *arg )
-{
-       struct re_s *rtask = arg;
-       struct bdb_info *bdb = rtask->arg;
-       
-       TXN_CHECKPOINT( bdb->bi_dbenv, bdb->bi_txn_cp_kbyte,
-               bdb->bi_txn_cp_min, 0 );
-       ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
-       ldap_pvt_runqueue_stoptask( &slapd_rq, rtask );
-       ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
-       return NULL;
-}
-
-/* reindex entries on the fly */
-static void *
-bdb_online_index( void *ctx, void *arg )
-{
-       struct re_s *rtask = arg;
-       BackendDB *be = rtask->arg;
-       struct bdb_info *bdb = be->be_private;
-
-       Connection conn = {0};
-       OperationBuffer opbuf;
-       Operation *op;
-
-       DBC *curs;
-       DBT key, data;
-       DB_TXN *txn;
-       DB_LOCK lock;
-       ID id, nid;
-       EntryInfo *ei;
-       int rc, getnext = 1;
-       int i;
-
-       connection_fake_init( &conn, &opbuf, ctx );
-       op = &opbuf.ob_op;
-
-       op->o_bd = be;
-
-       DBTzero( &key );
-       DBTzero( &data );
-       
-       id = 1;
-       key.data = &nid;
-       key.size = key.ulen = sizeof(ID);
-       key.flags = DB_DBT_USERMEM;
-
-       data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
-       data.dlen = data.ulen = 0;
-
-       while ( 1 ) {
-               if ( slapd_shutdown )
-                       break;
-
-               rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &txn, bdb->bi_db_opflags );
-               if ( rc ) 
-                       break;
-               Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_online_index) ": txn id: %x\n",
-                       txn->id(txn) );
-               if ( getnext ) {
-                       getnext = 0;
-                       BDB_ID2DISK( id, &nid );
-                       rc = bdb->bi_id2entry->bdi_db->cursor(
-                               bdb->bi_id2entry->bdi_db, txn, &curs, bdb->bi_db_opflags );
-                       if ( rc ) {
-                               TXN_ABORT( txn );
-                               break;
-                       }
-                       rc = curs->c_get( curs, &key, &data, DB_SET_RANGE );
-                       curs->c_close( curs );
-                       if ( rc ) {
-                               TXN_ABORT( txn );
-                               if ( rc == DB_NOTFOUND )
-                                       rc = 0;
-                               if ( rc == DB_LOCK_DEADLOCK ) {
-                                       ldap_pvt_thread_yield();
-                                       continue;
-                               }
-                               break;
-                       }
-                       BDB_DISK2ID( &nid, &id );
-               }
-
-               ei = NULL;
-               rc = bdb_cache_find_id( op, txn, id, &ei, 0, &lock );
-               if ( rc ) {
-                       TXN_ABORT( txn );
-                       if ( rc == DB_LOCK_DEADLOCK ) {
-                               ldap_pvt_thread_yield();
-                               continue;
-                       }
-                       if ( rc == DB_NOTFOUND ) {
-                               id++;
-                               getnext = 1;
-                               continue;
-                       }
-                       break;
-               }
-               if ( ei->bei_e ) {
-                       rc = bdb_index_entry( op, txn, BDB_INDEX_UPDATE_OP, ei->bei_e );
-                       if ( rc ) {
-                               TXN_ABORT( txn );
-                               if ( rc == DB_LOCK_DEADLOCK ) {
-                                       ldap_pvt_thread_yield();
-                                       continue;
-                               }
-                               break;
-                       }
-                       rc = TXN_COMMIT( txn, 0 );
-                       txn = NULL;
-               }
-               id++;
-               getnext = 1;
-       }
-
-       for ( i = 0; i < bdb->bi_nattrs; i++ ) {
-               if ( bdb->bi_attrs[ i ]->ai_indexmask & BDB_INDEX_DELETING
-                       || bdb->bi_attrs[ i ]->ai_newmask == 0 )
-               {
-                       continue;
-               }
-               bdb->bi_attrs[ i ]->ai_indexmask = bdb->bi_attrs[ i ]->ai_newmask;
-               bdb->bi_attrs[ i ]->ai_newmask = 0;
-       }
-
-       ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
-       ldap_pvt_runqueue_stoptask( &slapd_rq, rtask );
-       bdb->bi_index_task = NULL;
-       ldap_pvt_runqueue_remove( &slapd_rq, rtask );
-       ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
-
-       return NULL;
-}
-
-/* Cleanup loose ends after Modify completes */
-static int
-bdb_cf_cleanup( ConfigArgs *c )
-{
-       struct bdb_info *bdb = c->be->be_private;
-       int rc = 0;
-       BerVarray bva;
-
-       if ( bdb->bi_flags & BDB_DEL_INDEX ) {
-               bdb_attr_flush( bdb );
-               bdb->bi_flags ^= BDB_DEL_INDEX;
-       }
-
-       if ( bdb->bi_flags & BDB_RE_OPEN ) {
-               bdb->bi_flags ^= BDB_RE_OPEN;
-               bva = bdb->bi_db_config;
-               bdb->bi_db_config = NULL;
-               rc = c->be->bd_info->bi_db_close( c->be, &c->reply );
-               if ( rc == 0 ) {
-                       if ( bdb->bi_flags & BDB_UPD_CONFIG ) {
-                               if ( bva ) {
-                                       int i;
-                                       FILE *f = fopen( bdb->bi_db_config_path, "w" );
-                                       if ( f ) {
-                                               bdb->bi_db_config = bva;
-                                               bva = NULL;
-                                               for (i=0; bdb->bi_db_config[i].bv_val; i++)
-                                                       fprintf( f, "%s\n", bdb->bi_db_config[i].bv_val );
-                                               fclose( f );
-                                       } else {
-                                               ber_bvarray_free( bva );
-                                       }
-                               } else {
-                                       unlink( bdb->bi_db_config_path );
-                               }
-                               bdb->bi_flags ^= BDB_UPD_CONFIG;
-                       }
-                       rc = c->be->bd_info->bi_db_open( c->be, &c->reply );
-               }
-               /* If this fails, we need to restart */
-               if ( rc ) {
-                       slapd_shutdown = 2;
-                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
-                               "failed to reopen database, rc=%d", rc );
-                       Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_cf_cleanup)
-                               ": %s\n", c->cr_msg );
-                       rc = LDAP_OTHER;
-               }
-       }
-       return rc;
-}
-
-static int
-bdb_cf_gen( ConfigArgs *c )
-{
-       struct bdb_info *bdb = c->be->be_private;
-       int rc;
-
-       if ( c->op == SLAP_CONFIG_EMIT ) {
-               rc = 0;
-               switch( c->type ) {
-               case BDB_MODE: {
-                       char buf[64];
-                       struct berval bv;
-                       bv.bv_len = snprintf( buf, sizeof(buf), "0%o", bdb->bi_dbenv_mode );
-                       if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) {
-                               bv.bv_val = buf;
-                               value_add_one( &c->rvalue_vals, &bv );
-                       } else {
-                               rc = 1;
-                       }
-                       } break;
-
-               case BDB_CHKPT:
-                       if ( bdb->bi_txn_cp ) {
-                               char buf[64];
-                               struct berval bv;
-                               bv.bv_len = snprintf( buf, sizeof(buf), "%ld %ld",
-                                       (long) bdb->bi_txn_cp_kbyte, (long) bdb->bi_txn_cp_min );
-                               if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) {
-                                       bv.bv_val = buf;
-                                       value_add_one( &c->rvalue_vals, &bv );
-                               } else {
-                                       rc = 1;
-                               }
-                       } else {
-                               rc = 1;
-                       }
-                       break;
-
-               case BDB_CRYPTFILE:
-                       if ( bdb->bi_db_crypt_file ) {
-                               c->value_string = ch_strdup( bdb->bi_db_crypt_file );
-                       } else {
-                               rc = 1;
-                       }
-                       break;
-
-               /* If a crypt file has been set, its contents are copied here.
-                * But we don't want the key to be incorporated here.
-                */
-               case BDB_CRYPTKEY:
-                       if ( !bdb->bi_db_crypt_file && !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
-                               value_add_one( &c->rvalue_vals, &bdb->bi_db_crypt_key );
-                       } else {
-                               rc = 1;
-                       }
-                       break;
-
-               case BDB_DIRECTORY:
-                       if ( bdb->bi_dbenv_home ) {
-                               c->value_string = ch_strdup( bdb->bi_dbenv_home );
-                       } else {
-                               rc = 1;
-                       }
-                       break;
-
-               case BDB_CONFIG:
-                       if ( !( bdb->bi_flags & BDB_IS_OPEN )
-                               && !bdb->bi_db_config )
-                       {
-                               char    buf[SLAP_TEXT_BUFLEN];
-                               FILE *f = fopen( bdb->bi_db_config_path, "r" );
-                               struct berval bv;
-
-                               if ( f ) {
-                                       bdb->bi_flags |= BDB_HAS_CONFIG;
-                                       while ( fgets( buf, sizeof(buf), f )) {
-                                               ber_str2bv( buf, 0, 1, &bv );
-                                               if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\n' ) {
-                                                       bv.bv_len--;
-                                                       bv.bv_val[bv.bv_len] = '\0';
-                                               }
-                                               /* shouldn't need this, but ... */
-                                               if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\r' ) {
-                                                       bv.bv_len--;
-                                                       bv.bv_val[bv.bv_len] = '\0';
-                                               }
-                                               ber_bvarray_add( &bdb->bi_db_config, &bv );
-                                       }
-                                       fclose( f );
-                               }
-                       }
-                       if ( bdb->bi_db_config ) {
-                               int i;
-                               struct berval bv;
-
-                               bv.bv_val = c->log;
-                               for (i=0; !BER_BVISNULL(&bdb->bi_db_config[i]); i++) {
-                                       bv.bv_len = sprintf( bv.bv_val, "{%d}%s", i,
-                                               bdb->bi_db_config[i].bv_val );
-                                       value_add_one( &c->rvalue_vals, &bv );
-                               }
-                       }
-                       if ( !c->rvalue_vals ) rc = 1;
-                       break;
-
-               case BDB_NOSYNC:
-                       if ( bdb->bi_dbenv_xflags & DB_TXN_NOSYNC )
-                               c->value_int = 1;
-                       break;
-                       
-               case BDB_CHECKSUM:
-                       if ( bdb->bi_flags & BDB_CHKSUM )
-                               c->value_int = 1;
-                       break;
-
-               case BDB_INDEX:
-                       bdb_attr_index_unparse( bdb, &c->rvalue_vals );
-                       if ( !c->rvalue_vals ) rc = 1;
-                       break;
-
-               case BDB_LOCKD:
-                       rc = 1;
-                       if ( bdb->bi_lock_detect != DB_LOCK_DEFAULT ) {
-                               int i;
-                               for (i=0; !BER_BVISNULL(&bdb_lockd[i].word); i++) {
-                                       if ( bdb->bi_lock_detect == (u_int32_t)bdb_lockd[i].mask ) {
-                                               value_add_one( &c->rvalue_vals, &bdb_lockd[i].word );
-                                               rc = 0;
-                                               break;
-                                       }
-                               }
-                       }
-                       break;
-
-               case BDB_SSTACK:
-                       c->value_int = bdb->bi_search_stack_depth;
-                       break;
-
-               case BDB_PGSIZE: {
-                               struct bdb_db_pgsize *ps;
-                               char buf[SLAP_TEXT_BUFLEN];
-                               struct berval bv;
-                               int rc = 1;
-
-                               bv.bv_val = buf;
-                               for ( ps = bdb->bi_pagesizes; ps; ps = ps->bdp_next ) {
-                                       bv.bv_len = sprintf( buf, "%s %d", ps->bdp_name.bv_val,
-                                               ps->bdp_size / 1024 );
-                                       value_add_one( &c->rvalue_vals, &bv );
-                                       rc = 0;
-
-                               }
-                               break;
-                       }
-               }
-               return rc;
-       } else if ( c->op == LDAP_MOD_DELETE ) {
-               rc = 0;
-               switch( c->type ) {
-               case BDB_MODE:
-#if 0
-                       /* FIXME: does it make any sense to change the mode,
-                        * if we don't exec a chmod()? */
-                       bdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE;
-                       break;
-#endif
-
-               /* single-valued no-ops */
-               case BDB_LOCKD:
-               case BDB_SSTACK:
-                       break;
-
-               case BDB_CHKPT:
-                       if ( bdb->bi_txn_cp_task ) {
-                               struct re_s *re = bdb->bi_txn_cp_task;
-                               bdb->bi_txn_cp_task = NULL;
-                               ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
-                               if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) )
-                                       ldap_pvt_runqueue_stoptask( &slapd_rq, re );
-                               ldap_pvt_runqueue_remove( &slapd_rq, re );
-                               ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
-                       }
-                       bdb->bi_txn_cp = 0;
-                       break;
-               case BDB_CONFIG:
-                       if ( c->valx < 0 ) {
-                               ber_bvarray_free( bdb->bi_db_config );
-                               bdb->bi_db_config = NULL;
-                       } else {
-                               int i = c->valx;
-                               ch_free( bdb->bi_db_config[i].bv_val );
-                               for (; bdb->bi_db_config[i].bv_val; i++)
-                                       bdb->bi_db_config[i] = bdb->bi_db_config[i+1];
-                       }
-                       bdb->bi_flags |= BDB_UPD_CONFIG|BDB_RE_OPEN;
-                       c->cleanup = bdb_cf_cleanup;
-                       break;
-               /* Doesn't really make sense to change these on the fly;
-                * the entire DB must be dumped and reloaded
-                */
-               case BDB_CRYPTFILE:
-                       if ( bdb->bi_db_crypt_file ) {
-                               ch_free( bdb->bi_db_crypt_file );
-                               bdb->bi_db_crypt_file = NULL;
-                       }
-                       /* FALLTHRU */
-               case BDB_CRYPTKEY:
-                       if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
-                               ch_free( bdb->bi_db_crypt_key.bv_val );
-                               BER_BVZERO( &bdb->bi_db_crypt_key );
-                       }
-                       break;
-               case BDB_DIRECTORY:
-                       bdb->bi_flags |= BDB_RE_OPEN;
-                       bdb->bi_flags ^= BDB_HAS_CONFIG;
-                       ch_free( bdb->bi_dbenv_home );
-                       bdb->bi_dbenv_home = NULL;
-                       ch_free( bdb->bi_db_config_path );
-                       bdb->bi_db_config_path = NULL;
-                       c->cleanup = bdb_cf_cleanup;
-                       ldap_pvt_thread_pool_purgekey( bdb->bi_dbenv );
-                       break;
-               case BDB_NOSYNC:
-                       bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC, 0 );
-                       break;
-               case BDB_CHECKSUM:
-                       bdb->bi_flags &= ~BDB_CHKSUM;
-                       break;
-               case BDB_INDEX:
-                       if ( c->valx == -1 ) {
-                               int i;
-
-                               /* delete all */
-                               for ( i = 0; i < bdb->bi_nattrs; i++ ) {
-                                       bdb->bi_attrs[i]->ai_indexmask |= BDB_INDEX_DELETING;
-                               }
-                               bdb->bi_defaultmask = 0;
-                               bdb->bi_flags |= BDB_DEL_INDEX;
-                               c->cleanup = bdb_cf_cleanup;
-
-                       } else {
-                               struct berval bv, def = BER_BVC("default");
-                               char *ptr;
-
-                               for (ptr = c->line; !isspace( (unsigned char) *ptr ); ptr++);
-
-                               bv.bv_val = c->line;
-                               bv.bv_len = ptr - bv.bv_val;
-                               if ( bvmatch( &bv, &def )) {
-                                       bdb->bi_defaultmask = 0;
-
-                               } else {
-                                       int i;
-                                       char **attrs;
-                                       char sep;
-
-                                       sep = bv.bv_val[ bv.bv_len ];
-                                       bv.bv_val[ bv.bv_len ] = '\0';
-                                       attrs = ldap_str2charray( bv.bv_val, "," );
-
-                                       for ( i = 0; attrs[ i ]; i++ ) {
-                                               AttributeDescription *ad = NULL;
-                                               const char *text;
-                                               AttrInfo *ai;
-
-                                               slap_str2ad( attrs[ i ], &ad, &text );
-                                               /* if we got here... */
-                                               assert( ad != NULL );
-
-                                               ai = bdb_attr_mask( bdb, ad );
-                                               /* if we got here... */
-                                               assert( ai != NULL );
-
-                                               ai->ai_indexmask |= BDB_INDEX_DELETING;
-                                               bdb->bi_flags |= BDB_DEL_INDEX;
-                                               c->cleanup = bdb_cf_cleanup;
-                                       }
-
-                                       bv.bv_val[ bv.bv_len ] = sep;
-                                       ldap_charray_free( attrs );
-                               }
-                       }
-                       break;
-               /* doesn't make sense on the fly; the DB file must be
-                * recreated
-                */
-               case BDB_PGSIZE: {
-                               struct bdb_db_pgsize *ps, **prev;
-                               int i;
-
-                               for ( i = 0, prev = &bdb->bi_pagesizes, ps = *prev; ps;
-                                       prev = &ps->bdp_next, ps = ps->bdp_next, i++ ) {
-                                       if ( c->valx == -1 || i == c->valx ) {
-                                               *prev = ps->bdp_next;
-                                               ch_free( ps );
-                                               ps = *prev;
-                                               if ( i == c->valx ) break;
-                                       }
-                               }
-                       }
-                       break;
-               }
-               return rc;
-       }
-
-       switch( c->type ) {
-       case BDB_MODE:
-               if ( ASCII_DIGIT( c->argv[1][0] ) ) {
-                       long mode;
-                       char *next;
-                       errno = 0;
-                       mode = strtol( c->argv[1], &next, 0 );
-                       if ( errno != 0 || next == c->argv[1] || next[0] != '\0' ) {
-                               fprintf( stderr, "%s: "
-                                       "unable to parse mode=\"%s\".\n",
-                                       c->log, c->argv[1] );
-                               return 1;
-                       }
-                       bdb->bi_dbenv_mode = mode;
-
-               } else {
-                       char *m = c->argv[1];
-                       int who, what, mode = 0;
-
-                       if ( strlen( m ) != STRLENOF("-rwxrwxrwx") ) {
-                               return 1;
-                       }
-
-                       if ( m[0] != '-' ) {
-                               return 1;
-                       }
-
-                       m++;
-                       for ( who = 0; who < 3; who++ ) {
-                               for ( what = 0; what < 3; what++, m++ ) {
-                                       if ( m[0] == '-' ) {
-                                               continue;
-                                       } else if ( m[0] != "rwx"[what] ) {
-                                               return 1;
-                                       }
-                                       mode += ((1 << (2 - what)) << 3*(2 - who));
-                               }
-                       }
-                       bdb->bi_dbenv_mode = mode;
-               }
-               break;
-       case BDB_CHKPT: {
-               long    l;
-               bdb->bi_txn_cp = 1;
-               if ( lutil_atolx( &l, c->argv[1], 0 ) != 0 ) {
-                       fprintf( stderr, "%s: "
-                               "invalid kbyte \"%s\" in \"checkpoint\".\n",
-                               c->log, c->argv[1] );
-                       return 1;
-               }
-               bdb->bi_txn_cp_kbyte = l;
-               if ( lutil_atolx( &l, c->argv[2], 0 ) != 0 ) {
-                       fprintf( stderr, "%s: "
-                               "invalid minutes \"%s\" in \"checkpoint\".\n",
-                               c->log, c->argv[2] );
-                       return 1;
-               }
-               bdb->bi_txn_cp_min = l;
-               /* If we're in server mode and time-based checkpointing is enabled,
-                * submit a task to perform periodic checkpoints.
-                */
-               if ((slapMode & SLAP_SERVER_MODE) && bdb->bi_txn_cp_min ) {
-                       struct re_s *re = bdb->bi_txn_cp_task;
-                       if ( re ) {
-                               re->interval.tv_sec = bdb->bi_txn_cp_min * 60;
-                       } else {
-                               if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) {
-                                       fprintf( stderr, "%s: "
-                                               "\"checkpoint\" must occur after \"suffix\".\n",
-                                               c->log );
-                                       return 1;
-                               }
-                               ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
-                               bdb->bi_txn_cp_task = ldap_pvt_runqueue_insert( &slapd_rq,
-                                       bdb->bi_txn_cp_min * 60, bdb_checkpoint, bdb,
-                                       LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val );
-                               ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
-                       }
-               }
-               } break;
-
-       case BDB_CONFIG: {
-               char *ptr = c->line;
-               struct berval bv;
-
-               if ( c->op == SLAP_CONFIG_ADD ) {
-                       ptr += STRLENOF("dbconfig");
-                       while (!isspace((unsigned char)*ptr)) ptr++;
-                       while (isspace((unsigned char)*ptr)) ptr++;
-               }
-
-               if ( bdb->bi_flags & BDB_IS_OPEN ) {
-                       bdb->bi_flags |= BDB_UPD_CONFIG|BDB_RE_OPEN;
-                       c->cleanup = bdb_cf_cleanup;
-               } else {
-               /* If we're just starting up...
-                */
-                       FILE *f;
-                       /* If a DB_CONFIG file exists, or we don't know the path
-                        * to the DB_CONFIG file, ignore these directives
-                        */
-                       if (( bdb->bi_flags & BDB_HAS_CONFIG ) || !bdb->bi_db_config_path )
-                               break;
-                       f = fopen( bdb->bi_db_config_path, "a" );
-                       if ( f ) {
-                               /* FIXME: EBCDIC probably needs special handling */
-                               fprintf( f, "%s\n", ptr );
-                               fclose( f );
-                       }
-               }
-               ber_str2bv( ptr, 0, 1, &bv );
-               ber_bvarray_add( &bdb->bi_db_config, &bv );
-               }
-               break;
-
-       case BDB_CRYPTFILE:
-               rc = lutil_get_filed_password( c->value_string, &bdb->bi_db_crypt_key );
-               if ( rc == 0 ) {
-                       bdb->bi_db_crypt_file = c->value_string;
-               }
-               break;
-
-       /* Cannot set key if file was already set */
-       case BDB_CRYPTKEY:
-               if ( bdb->bi_db_crypt_file ) {
-                       rc = 1;
-               } else {
-                       bdb->bi_db_crypt_key = c->value_bv;
-               }
-               break;
-
-       case BDB_DIRECTORY: {
-               FILE *f;
-               char *ptr, *testpath;
-               int len;
-
-               len = strlen( c->value_string );
-               testpath = ch_malloc( len + STRLENOF(LDAP_DIRSEP) + STRLENOF("DUMMY") + 1 );
-               ptr = lutil_strcopy( testpath, c->value_string );
-               *ptr++ = LDAP_DIRSEP[0];
-               strcpy( ptr, "DUMMY" );
-               f = fopen( testpath, "w" );
-               if ( f ) {
-                       fclose( f );
-                       unlink( testpath );
-               }
-               ch_free( testpath );
-               if ( !f ) {
-                       snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid path: %s",
-                               c->log, strerror( errno ));
-                       Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg );
-                       return -1;
-               }
-
-               if ( bdb->bi_dbenv_home )
-                       ch_free( bdb->bi_dbenv_home );
-               bdb->bi_dbenv_home = c->value_string;
-
-               /* See if a DB_CONFIG file already exists here */
-               if ( bdb->bi_db_config_path )
-                       ch_free( bdb->bi_db_config_path );
-               bdb->bi_db_config_path = ch_malloc( len +
-                       STRLENOF(LDAP_DIRSEP) + STRLENOF("DB_CONFIG") + 1 );
-               ptr = lutil_strcopy( bdb->bi_db_config_path, bdb->bi_dbenv_home );
-               *ptr++ = LDAP_DIRSEP[0];
-               strcpy( ptr, "DB_CONFIG" );
-
-               f = fopen( bdb->bi_db_config_path, "r" );
-               if ( f ) {
-                       bdb->bi_flags |= BDB_HAS_CONFIG;
-                       fclose(f);
-               }
-               }
-               break;
-
-       case BDB_NOSYNC:
-               if ( c->value_int )
-                       bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC;
-               else
-                       bdb->bi_dbenv_xflags &= ~DB_TXN_NOSYNC;
-               if ( bdb->bi_flags & BDB_IS_OPEN ) {
-                       bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC,
-                               c->value_int );
-               }
-               break;
-
-       case BDB_CHECKSUM:
-               if ( c->value_int )
-                       bdb->bi_flags |= BDB_CHKSUM;
-               else
-                       bdb->bi_flags &= ~BDB_CHKSUM;
-               break;
-
-       case BDB_INDEX:
-               rc = bdb_attr_index_config( bdb, c->fname, c->lineno,
-                       c->argc - 1, &c->argv[1], &c->reply);
-
-               if( rc != LDAP_SUCCESS ) return 1;
-               if (( bdb->bi_flags & BDB_IS_OPEN ) && !bdb->bi_index_task ) {
-                       /* Start the task as soon as we finish here. Set a long
-                        * interval (10 hours) so that it only gets scheduled once.
-                        */
-                       if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) {
-                               fprintf( stderr, "%s: "
-                                       "\"index\" must occur after \"suffix\".\n",
-                                       c->log );
-                               return 1;
-                       }
-                       ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
-                       bdb->bi_index_task = ldap_pvt_runqueue_insert( &slapd_rq, 36000,
-                               bdb_online_index, c->be,
-                               LDAP_XSTRING(bdb_online_index), c->be->be_suffix[0].bv_val );
-                       ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
-               }
-               break;
-
-       case BDB_LOCKD:
-               rc = verb_to_mask( c->argv[1], bdb_lockd );
-               if ( BER_BVISNULL(&bdb_lockd[rc].word) ) {
-                       fprintf( stderr, "%s: "
-                               "bad policy (%s) in \"lockDetect <policy>\" line\n",
-                               c->log, c->argv[1] );
-                       return 1;
-               }
-               bdb->bi_lock_detect = (u_int32_t)rc;
-               break;
-
-       case BDB_SSTACK:
-               if ( c->value_int < MINIMUM_SEARCH_STACK_DEPTH ) {
-                       fprintf( stderr,
-               "%s: depth %d too small, using %d\n",
-                       c->log, c->value_int, MINIMUM_SEARCH_STACK_DEPTH );
-                       c->value_int = MINIMUM_SEARCH_STACK_DEPTH;
-               }
-               bdb->bi_search_stack_depth = c->value_int;
-               break;
-
-       case BDB_PGSIZE: {
-               struct bdb_db_pgsize *ps, **prev;
-               int i, s;
-               
-               s = atoi(c->argv[2]);
-               if ( s < 1 || s > 64 ) {
-                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
-                               "%s: size must be > 0 and <= 64: %d",
-                               c->log, s );
-                       Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg );
-                       return -1;
-               }
-               i = strlen(c->argv[1]);
-               ps = ch_malloc( sizeof(struct bdb_db_pgsize) + i + 1 );
-               ps->bdp_next = NULL;
-               ps->bdp_name.bv_len = i;
-               ps->bdp_name.bv_val = (char *)(ps+1);
-               strcpy( ps->bdp_name.bv_val, c->argv[1] );
-               ps->bdp_size = s * 1024;
-               for ( prev = &bdb->bi_pagesizes; *prev; prev = &(*prev)->bdp_next )
-                       ;
-               *prev = ps;
-               }
-               break;
-       }
-       return 0;
-}
-
-int bdb_back_init_cf( BackendInfo *bi )
-{
-       int rc;
-       bi->bi_cf_ocs = bdbocs;
-
-       rc = config_register_schema( bdbcfg, bdbocs );
-       if ( rc ) return rc;
-       return 0;
-}
diff --git a/servers/slapd/back-bdb/dbcache.c b/servers/slapd/back-bdb/dbcache.c
deleted file mode 100644 (file)
index ef9992f..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/* dbcache.c - manage cache of open databases */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/errno.h>
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/time.h>
-#include <sys/stat.h>
-
-#include "slap.h"
-#include "back-bdb.h"
-#include "lutil_hash.h"
-
-#ifdef BDB_INDEX_USE_HASH
-/* Pass-thru hash function. Since the indexer is already giving us hash
- * values as keys, we don't need BDB to re-hash them.
- */
-static u_int32_t
-bdb_db_hash(
-       DB *db,
-       const void *bytes,
-       u_int32_t length
-)
-{
-       u_int32_t ret = 0;
-       unsigned char *dst = (unsigned char *)&ret;
-       const unsigned char *src = (const unsigned char *)bytes;
-
-       if ( length > sizeof(u_int32_t) )
-               length = sizeof(u_int32_t);
-
-       while ( length ) {
-               *dst++ = *src++;
-               length--;
-       }
-       return ret;
-}
-#define        BDB_INDEXTYPE   DB_HASH
-#else
-#define        BDB_INDEXTYPE   DB_BTREE
-#endif
-
-/* If a configured size is found, return it, otherwise return 0 */
-int
-bdb_db_findsize(
-       struct bdb_info *bdb,
-       struct berval *name
-)
-{
-       struct bdb_db_pgsize *bp;
-       int rc;
-
-       for ( bp = bdb->bi_pagesizes; bp; bp=bp->bdp_next ) {
-               rc = strncmp( name->bv_val, bp->bdp_name.bv_val, name->bv_len );
-               if ( !rc ) {
-                       if ( name->bv_len == bp->bdp_name.bv_len )
-                               return bp->bdp_size;
-                       if ( name->bv_len < bp->bdp_name.bv_len &&
-                               bp->bdp_name.bv_val[name->bv_len] == '.' )
-                               return bp->bdp_size;
-               }
-       }
-       return 0;
-}
-
-int
-bdb_db_cache(
-       Backend *be,
-       struct berval *name,
-       DB **dbout )
-{
-       int i, flags;
-       int rc;
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       struct bdb_db_info *db;
-       char *file;
-
-       *dbout = NULL;
-
-       for( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) {
-               if( !ber_bvcmp( &bdb->bi_databases[i]->bdi_name, name) ) {
-                       *dbout = bdb->bi_databases[i]->bdi_db;
-                       return 0;
-               }
-       }
-
-       ldap_pvt_thread_mutex_lock( &bdb->bi_database_mutex );
-
-       /* check again! may have been added by another thread */
-       for( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) {
-               if( !ber_bvcmp( &bdb->bi_databases[i]->bdi_name, name) ) {
-                       *dbout = bdb->bi_databases[i]->bdi_db;
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex );
-                       return 0;
-               }
-       }
-
-       if( i >= BDB_INDICES ) {
-               ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex );
-               return -1;
-       }
-
-       db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info));
-
-       ber_dupbv( &db->bdi_name, name );
-
-       rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 );
-       if( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "bdb_db_cache: db_create(%s) failed: %s (%d)\n",
-                       bdb->bi_dbenv_home, db_strerror(rc), rc );
-               ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex );
-               ch_free( db );
-               return rc;
-       }
-
-       if( !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
-               rc = db->bdi_db->set_flags( db->bdi_db, DB_ENCRYPT );
-               if ( rc ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb_db_cache: db set_flags(DB_ENCRYPT)(%s) failed: %s (%d)\n",
-                               bdb->bi_dbenv_home, db_strerror(rc), rc );
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex );
-                       db->bdi_db->close( db->bdi_db, 0 );
-                       ch_free( db );
-                       return rc;
-               }
-       }
-
-       if( bdb->bi_flags & BDB_CHKSUM ) {
-               rc = db->bdi_db->set_flags( db->bdi_db, DB_CHKSUM );
-               if ( rc ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb_db_cache: db set_flags(DB_CHKSUM)(%s) failed: %s (%d)\n",
-                               bdb->bi_dbenv_home, db_strerror(rc), rc );
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex );
-                       db->bdi_db->close( db->bdi_db, 0 );
-                       ch_free( db );
-                       return rc;
-               }
-       }
-
-       /* If no explicit size set, use the FS default */
-       flags = bdb_db_findsize( bdb, name );
-       if ( flags )
-               rc = db->bdi_db->set_pagesize( db->bdi_db, flags );
-
-#ifdef BDB_INDEX_USE_HASH
-       rc = db->bdi_db->set_h_hash( db->bdi_db, bdb_db_hash );
-#endif
-       rc = db->bdi_db->set_flags( db->bdi_db, DB_DUP | DB_DUPSORT );
-
-       file = ch_malloc( db->bdi_name.bv_len + sizeof(BDB_SUFFIX) );
-       strcpy( file, db->bdi_name.bv_val );
-       strcpy( file+db->bdi_name.bv_len, BDB_SUFFIX );
-
-#ifdef HAVE_EBCDIC
-       __atoe( file );
-#endif
-       flags = DB_CREATE | DB_THREAD;
-#ifdef DB_AUTO_COMMIT
-       if ( !( slapMode & SLAP_TOOL_QUICK ))
-               flags |= DB_AUTO_COMMIT;
-#endif
-       /* Cannot Truncate when Transactions are in use */
-       if ( (slapMode & (SLAP_TOOL_QUICK|SLAP_TRUNCATE_MODE)) ==
-               (SLAP_TOOL_QUICK|SLAP_TRUNCATE_MODE))
-                       flags |= DB_TRUNCATE;
-
-       rc = DB_OPEN( db->bdi_db,
-               file, NULL /* name */,
-               BDB_INDEXTYPE, bdb->bi_db_opflags | flags, bdb->bi_dbenv_mode );
-
-       ch_free( file );
-
-       if( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "bdb_db_cache: db_open(%s) failed: %s (%d)\n",
-                       name->bv_val, db_strerror(rc), rc );
-               ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex );
-               db->bdi_db->close( db->bdi_db, 0 );
-               ch_free( db );
-               return rc;
-       }
-
-       bdb->bi_databases[i] = db;
-       bdb->bi_ndatabases = i+1;
-
-       *dbout = db->bdi_db;
-
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex );
-       return 0;
-}
diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c
deleted file mode 100644 (file)
index 915c568..0000000
+++ /dev/null
@@ -1,569 +0,0 @@
-/* delete.c - bdb backend delete routine */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "lutil.h"
-#include "back-bdb.h"
-
-int
-bdb_delete( Operation *op, SlapReply *rs )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       Entry   *matched = NULL;
-       struct berval   pdn = {0, NULL};
-       Entry   *e = NULL;
-       Entry   *p = NULL;
-       EntryInfo       *ei = NULL, *eip = NULL;
-       int             manageDSAit = get_manageDSAit( op );
-       AttributeDescription *children = slap_schema.si_ad_children;
-       AttributeDescription *entry = slap_schema.si_ad_entry;
-       DB_TXN          *ltid = NULL, *lt2;
-       struct bdb_op_info opinfo = {{{ 0 }}};
-       ID      eid;
-
-       DB_LOCK         lock, plock;
-
-       int             num_retries = 0;
-
-       int     rc;
-
-       LDAPControl **preread_ctrl = NULL;
-       LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
-       int num_ctrls = 0;
-
-       int     parent_is_glue = 0;
-       int parent_is_leaf = 0;
-
-       Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_delete) ": %s\n",
-               op->o_req_dn.bv_val );
-
-#ifdef LDAP_X_TXN
-       if( op->o_txnSpec && txn_preop( op, rs ))
-               return rs->sr_err;
-#endif
-
-       ctrls[num_ctrls] = 0;
-
-       /* allocate CSN */
-       if ( BER_BVISNULL( &op->o_csn ) ) {
-               struct berval csn;
-               char csnbuf[LDAP_PVT_CSNSTR_BUFSIZE];
-
-               csn.bv_val = csnbuf;
-               csn.bv_len = sizeof(csnbuf);
-               slap_get_csn( op, &csn, 1 );
-       }
-
-       if( 0 ) {
-retry: /* transaction retry */
-               if( e != NULL ) {
-                       bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
-                       e = NULL;
-               }
-               if( p != NULL ) {
-                       bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
-                       p = NULL;
-               }
-               Debug( LDAP_DEBUG_TRACE,
-                       "==> " LDAP_XSTRING(bdb_delete) ": retrying...\n" );
-               rs->sr_err = TXN_ABORT( ltid );
-               ltid = NULL;
-               LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-               opinfo.boi_oe.oe_key = NULL;
-               op->o_do_not_cache = opinfo.boi_acl_cache;
-               if( rs->sr_err != 0 ) {
-                       rs->sr_err = LDAP_OTHER;
-                       rs->sr_text = "internal error";
-                       goto return_results;
-               }
-               if ( op->o_abandon ) {
-                       rs->sr_err = SLAPD_ABANDON;
-                       goto return_results;
-               }
-               parent_is_glue = 0;
-               parent_is_leaf = 0;
-               bdb_trans_backoff( ++num_retries );
-       }
-
-       /* begin transaction */
-       {
-               int tflags = bdb->bi_db_opflags;
-               if ( get_lazyCommit( op ))
-                       tflags |= DB_TXN_NOSYNC;
-               rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, &ltid, tflags );
-       }
-       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_delete) ": txn1 id: %x\n",
-               ltid->id(ltid) );
-       rs->sr_text = NULL;
-       if( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_delete) ": txn_begin failed: "
-                       "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-
-       opinfo.boi_oe.oe_key = bdb;
-       opinfo.boi_txn = ltid;
-       opinfo.boi_err = 0;
-       opinfo.boi_acl_cache = op->o_do_not_cache;
-       LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next );
-
-       if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
-               dnParent( &op->o_req_ndn, &pdn );
-       }
-
-       /* get entry */
-       rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1,
-               &lock );
-
-       switch( rs->sr_err ) {
-       case 0:
-       case DB_NOTFOUND:
-               break;
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               goto retry;
-       case LDAP_BUSY:
-               rs->sr_text = "ldap server busy";
-               goto return_results;
-       default:
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-
-       if ( rs->sr_err == 0 ) {
-               e = ei->bei_e;
-               eip = ei->bei_parent;
-       } else {
-               matched = ei->bei_e;
-       }
-
-       /* FIXME : dn2entry() should return non-glue entry */
-       if ( e == NULL || ( !manageDSAit && is_entry_glue( e ))) {
-               Debug( LDAP_DEBUG_ARGS,
-                       "<=- " LDAP_XSTRING(bdb_delete) ": no such object %s\n",
-                       op->o_req_dn.bv_val );
-
-               if ( matched != NULL ) {
-                       rs->sr_matched = ch_strdup( matched->e_dn );
-                       rs->sr_ref = is_entry_referral( matched )
-                               ? get_entry_referrals( op, matched )
-                               : NULL;
-                       bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, matched);
-                       matched = NULL;
-
-               } else {
-                       rs->sr_ref = referral_rewrite( default_referral, NULL,
-                                       &op->o_req_dn, LDAP_SCOPE_DEFAULT );
-               }
-
-               rs->sr_err = LDAP_REFERRAL;
-               rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
-               goto return_results;
-       }
-
-       rc = bdb_cache_find_id( op, ltid, eip->bei_id, &eip, 0, &plock );
-       switch( rc ) {
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               goto retry;
-       case 0:
-       case DB_NOTFOUND:
-               break;
-       default:
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-       if ( eip ) p = eip->bei_e;
-
-       if ( pdn.bv_len != 0 ) {
-               if( p == NULL || !bvmatch( &pdn, &p->e_nname )) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<=- " LDAP_XSTRING(bdb_delete) ": parent "
-                               "does not exist\n" );
-                       rs->sr_err = LDAP_OTHER;
-                       rs->sr_text = "could not locate parent of entry";
-                       goto return_results;
-               }
-
-               /* check parent for "children" acl */
-               rs->sr_err = access_allowed( op, p,
-                       children, NULL, ACL_WDEL, NULL );
-
-               if ( !rs->sr_err  ) {
-                       switch( opinfo.boi_err ) {
-                       case DB_LOCK_DEADLOCK:
-                       case DB_LOCK_NOTGRANTED:
-                               goto retry;
-                       }
-
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<=- " LDAP_XSTRING(bdb_delete) ": no write "
-                               "access to parent\n" );
-                       rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-                       rs->sr_text = "no write access to parent";
-                       goto return_results;
-               }
-
-       } else {
-               /* no parent, must be root to delete */
-               if( ! be_isroot( op ) ) {
-                       if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
-                               || be_shadow_update( op ) ) {
-                               p = (Entry *)&slap_entry_root;
-
-                               /* check parent for "children" acl */
-                               rs->sr_err = access_allowed( op, p,
-                                       children, NULL, ACL_WDEL, NULL );
-
-                               p = NULL;
-
-                               if ( !rs->sr_err  ) {
-                                       switch( opinfo.boi_err ) {
-                                       case DB_LOCK_DEADLOCK:
-                                       case DB_LOCK_NOTGRANTED:
-                                               goto retry;
-                                       }
-
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               "<=- " LDAP_XSTRING(bdb_delete)
-                                               ": no access to parent\n" );
-                                       rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-                                       rs->sr_text = "no write access to parent";
-                                       goto return_results;
-                               }
-
-                       } else {
-                               Debug( LDAP_DEBUG_TRACE,
-                                       "<=- " LDAP_XSTRING(bdb_delete)
-                                       ": no parent and not root\n" );
-                               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-                               goto return_results;
-                       }
-               }
-       }
-
-       if ( get_assert( op ) &&
-               ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
-       {
-               rs->sr_err = LDAP_ASSERTION_FAILED;
-               goto return_results;
-       }
-
-       rs->sr_err = access_allowed( op, e,
-               entry, NULL, ACL_WDEL, NULL );
-
-       if ( !rs->sr_err  ) {
-               switch( opinfo.boi_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-
-               Debug( LDAP_DEBUG_TRACE,
-                       "<=- " LDAP_XSTRING(bdb_delete) ": no write access "
-                       "to entry\n" );
-               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-               rs->sr_text = "no write access to entry";
-               goto return_results;
-       }
-
-       if ( !manageDSAit && is_entry_referral( e ) ) {
-               /* entry is a referral, don't allow delete */
-               rs->sr_ref = get_entry_referrals( op, e );
-
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_delete) ": entry is referral\n" );
-
-               rs->sr_err = LDAP_REFERRAL;
-               rs->sr_matched = ch_strdup( e->e_name.bv_val );
-               rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
-               goto return_results;
-       }
-
-       /* pre-read */
-       if( op->o_preread ) {
-               if( preread_ctrl == NULL ) {
-                       preread_ctrl = &ctrls[num_ctrls++];
-                       ctrls[num_ctrls] = NULL;
-               }
-               if( slap_read_controls( op, rs, e,
-                       &slap_pre_read_bv, preread_ctrl ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<=- " LDAP_XSTRING(bdb_delete) ": pre-read "
-                               "failed!\n" );
-                       if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
-                               /* FIXME: is it correct to abort
-                                * operation if control fails? */
-                               goto return_results;
-                       }
-               }
-       }
-
-       /* nested transaction */
-       rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, &lt2, 
-               bdb->bi_db_opflags );
-       rs->sr_text = NULL;
-       if( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_delete) ": txn_begin(2) failed: "
-                       "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_delete) ": txn2 id: %x\n",
-               lt2->id(lt2) );
-
-       BDB_LOG_PRINTF( bdb->bi_dbenv, lt2, "slapd Starting delete %s(%d)",
-               e->e_nname.bv_val, e->e_id );
-
-       /* Can't do it if we have kids */
-       rs->sr_err = bdb_cache_children( op, lt2, e );
-       if( rs->sr_err != DB_NOTFOUND ) {
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               case 0:
-                       Debug(LDAP_DEBUG_ARGS,
-                               "<=- " LDAP_XSTRING(bdb_delete)
-                               ": non-leaf %s\n",
-                               op->o_req_dn.bv_val );
-                       rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
-                       rs->sr_text = "subordinate objects must be deleted first";
-                       break;
-               default:
-                       Debug(LDAP_DEBUG_ARGS,
-                               "<=- " LDAP_XSTRING(bdb_delete)
-                               ": has_children failed: %s (%d)\n",
-                               db_strerror(rs->sr_err), rs->sr_err );
-                       rs->sr_err = LDAP_OTHER;
-                       rs->sr_text = "internal error";
-               }
-               goto return_results;
-       }
-
-       /* delete from dn2id */
-       rs->sr_err = bdb_dn2id_delete( op, lt2, eip, e );
-       if ( rs->sr_err != 0 ) {
-               Debug(LDAP_DEBUG_TRACE,
-                       "<=- " LDAP_XSTRING(bdb_delete) ": dn2id failed: "
-                       "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err );
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-               rs->sr_text = "DN index delete failed";
-               rs->sr_err = LDAP_OTHER;
-               goto return_results;
-       }
-
-       /* delete indices for old attributes */
-       rs->sr_err = bdb_index_entry_del( op, lt2, e );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-               Debug(LDAP_DEBUG_TRACE,
-                       "<=- " LDAP_XSTRING(bdb_delete) ": index failed: "
-                       "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err );
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-               rs->sr_text = "entry index delete failed";
-               rs->sr_err = LDAP_OTHER;
-               goto return_results;
-       }
-
-       /* fixup delete CSN */
-       if ( !SLAP_SHADOW( op->o_bd )) {
-               struct berval vals[2];
-
-               assert( !BER_BVISNULL( &op->o_csn ) );
-               vals[0] = op->o_csn;
-               BER_BVZERO( &vals[1] );
-               rs->sr_err = bdb_index_values( op, lt2, slap_schema.si_ad_entryCSN,
-                       vals, 0, SLAP_INDEX_ADD_OP );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-                       switch( rs->sr_err ) {
-                       case DB_LOCK_DEADLOCK:
-                       case DB_LOCK_NOTGRANTED:
-                               goto retry;
-                       }
-                       rs->sr_text = "entryCSN index update failed";
-                       rs->sr_err = LDAP_OTHER;
-                       goto return_results;
-               }
-       }
-
-       /* delete from id2entry */
-       rs->sr_err = bdb_id2entry_delete( op->o_bd, lt2, e );
-       if ( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<=- " LDAP_XSTRING(bdb_delete) ": id2entry failed: "
-                       "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err );
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-               rs->sr_text = "entry delete failed";
-               rs->sr_err = LDAP_OTHER;
-               goto return_results;
-       }
-
-       if ( pdn.bv_len != 0 ) {
-               parent_is_glue = is_entry_glue(p);
-               rs->sr_err = bdb_cache_children( op, lt2, p );
-               if ( rs->sr_err != DB_NOTFOUND ) {
-                       switch( rs->sr_err ) {
-                       case DB_LOCK_DEADLOCK:
-                       case DB_LOCK_NOTGRANTED:
-                               goto retry;
-                       case 0:
-                               break;
-                       default:
-                               Debug(LDAP_DEBUG_ARGS,
-                                       "<=- " LDAP_XSTRING(bdb_delete)
-                                       ": has_children failed: %s (%d)\n",
-                                       db_strerror(rs->sr_err), rs->sr_err );
-                               rs->sr_err = LDAP_OTHER;
-                               rs->sr_text = "internal error";
-                               goto return_results;
-                       }
-                       parent_is_leaf = 1;
-               }
-               bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
-               p = NULL;
-       }
-
-       BDB_LOG_PRINTF( bdb->bi_dbenv, lt2, "slapd Commit1 delete %s(%d)",
-               e->e_nname.bv_val, e->e_id );
-
-       if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "txn_commit(2) failed";
-               goto return_results;
-       }
-
-       eid = e->e_id;
-
-#if 0  /* Do we want to reclaim deleted IDs? */
-       ldap_pvt_thread_mutex_lock( &bdb->bi_lastid_mutex );
-       if ( e->e_id == bdb->bi_lastid ) {
-               bdb_last_id( op->o_bd, ltid );
-       }
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_lastid_mutex );
-#endif
-
-       if( op->o_noop ) {
-               if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) {
-                       rs->sr_text = "txn_abort (no-op) failed";
-               } else {
-                       rs->sr_err = LDAP_X_NO_OPERATION;
-                       ltid = NULL;
-                       goto return_results;
-               }
-       } else {
-
-               BDB_LOG_PRINTF( bdb->bi_dbenv, ltid, "slapd Cache delete %s(%d)",
-                       e->e_nname.bv_val, e->e_id );
-
-               rc = bdb_cache_delete( bdb, e, ltid, &lock );
-               switch( rc ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-
-               rs->sr_err = TXN_COMMIT( ltid, 0 );
-       }
-       ltid = NULL;
-       LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-       opinfo.boi_oe.oe_key = NULL;
-
-       BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Committed delete %s(%d)",
-               e->e_nname.bv_val, e->e_id );
-
-       if( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_delete) ": txn_%s failed: %s (%d)\n",
-                       op->o_noop ? "abort (no-op)" : "commit",
-                       db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "commit failed";
-
-               goto return_results;
-       }
-
-       Debug( LDAP_DEBUG_TRACE,
-               LDAP_XSTRING(bdb_delete) ": deleted%s id=%08lx dn=\"%s\"\n",
-               op->o_noop ? " (no-op)" : "",
-               eid, op->o_req_dn.bv_val );
-       rs->sr_err = LDAP_SUCCESS;
-       rs->sr_text = NULL;
-       if( num_ctrls ) rs->sr_ctrls = ctrls;
-
-return_results:
-       if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) {
-               op->o_delete_glue_parent = 1;
-       }
-
-       if ( p )
-               bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
-
-       /* free entry */
-       if( e != NULL ) {
-               if ( rs->sr_err == LDAP_SUCCESS ) {
-                       /* Free the EntryInfo and the Entry */
-                       bdb_cache_entryinfo_lock( BEI(e) );
-                       bdb_cache_delete_cleanup( &bdb->bi_cache, BEI(e) );
-               } else {
-                       bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
-               }
-       }
-
-       if( ltid != NULL ) {
-               TXN_ABORT( ltid );
-       }
-       if ( opinfo.boi_oe.oe_key ) {
-               LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-       }
-
-       send_ldap_result( op, rs );
-       slap_graduate_commit_csn( op );
-
-       if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
-               slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
-               slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
-       }
-
-       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) {
-               TXN_CHECKPOINT( bdb->bi_dbenv,
-                       bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
-       }
-       return rs->sr_err;
-}
diff --git a/servers/slapd/back-bdb/dn2entry.c b/servers/slapd/back-bdb/dn2entry.c
deleted file mode 100644 (file)
index 37bc501..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* dn2entry.c - routines to deal with the dn2id / id2entry glue */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-
-/*
- * dn2entry - look up dn in the cache/indexes and return the corresponding
- * entry. If the requested DN is not found and matched is TRUE, return info
- * for the closest ancestor of the DN. Otherwise e is NULL.
- */
-
-int
-bdb_dn2entry(
-       Operation *op,
-       DB_TXN *tid,
-       struct berval *dn,
-       EntryInfo **e,
-       int matched,
-       DB_LOCK *lock )
-{
-       EntryInfo *ei = NULL;
-       int rc, rc2;
-
-       Debug(LDAP_DEBUG_TRACE, "bdb_dn2entry(\"%s\")\n",
-               dn->bv_val );
-
-       *e = NULL;
-
-       rc = bdb_cache_find_ndn( op, tid, dn, &ei );
-       if ( rc ) {
-               if ( matched && rc == DB_NOTFOUND ) {
-                       /* Set the return value, whether we have its entry
-                        * or not.
-                        */
-                       *e = ei;
-                       if ( ei && ei->bei_id ) {
-                               rc2 = bdb_cache_find_id( op, tid, ei->bei_id,
-                                       &ei, ID_LOCKED, lock );
-                               if ( rc2 ) rc = rc2;
-                       } else if ( ei ) {
-                               bdb_cache_entryinfo_unlock( ei );
-                               memset( lock, 0, sizeof( *lock ));
-                               lock->mode = DB_LOCK_NG;
-                       }
-               } else if ( ei ) {
-                       bdb_cache_entryinfo_unlock( ei );
-               }
-       } else {
-               rc = bdb_cache_find_id( op, tid, ei->bei_id, &ei, ID_LOCKED,
-                       lock );
-               if ( rc == 0 ) {
-                       *e = ei;
-               } else if ( matched && rc == DB_NOTFOUND ) {
-                       /* always return EntryInfo */
-                       if ( ei->bei_parent ) {
-                               ei = ei->bei_parent;
-                               rc2 = bdb_cache_find_id( op, tid, ei->bei_id, &ei, 0,
-                                       lock );
-                               if ( rc2 ) rc = rc2;
-                       }
-                       *e = ei;
-               }
-       }
-
-       return rc;
-}
diff --git a/servers/slapd/back-bdb/dn2id.c b/servers/slapd/back-bdb/dn2id.c
deleted file mode 100644 (file)
index aba74a6..0000000
+++ /dev/null
@@ -1,1214 +0,0 @@
-/* dn2id.c - routines to deal with the dn2id index */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-#include "idl.h"
-#include "lutil.h"
-
-#ifndef BDB_HIER
-int
-bdb_dn2id_add(
-       Operation *op,
-       DB_TXN *txn,
-       EntryInfo *eip,
-       Entry           *e )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB *db = bdb->bi_dn2id->bdi_db;
-       int             rc;
-       DBT             key, data;
-       ID              nid;
-       char            *buf;
-       struct berval   ptr, pdn;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_add 0x%lx: \"%s\"\n",
-               e->e_id, e->e_ndn );
-       assert( e->e_id != NOID );
-
-       DBTzero( &key );
-       key.size = e->e_nname.bv_len + 2;
-       key.ulen = key.size;
-       key.flags = DB_DBT_USERMEM;
-       buf = op->o_tmpalloc( key.size, op->o_tmpmemctx );
-       key.data = buf;
-       buf[0] = DN_BASE_PREFIX;
-       ptr.bv_val = buf + 1;
-       ptr.bv_len = e->e_nname.bv_len;
-       AC_MEMCPY( ptr.bv_val, e->e_nname.bv_val, e->e_nname.bv_len );
-       ptr.bv_val[ptr.bv_len] = '\0';
-
-       DBTzero( &data );
-       data.data = &nid;
-       data.size = sizeof( nid );
-       BDB_ID2DISK( e->e_id, &nid );
-
-       /* store it -- don't override */
-       rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );
-       if( rc != 0 ) {
-               Debug(LDAP_DEBUG_ANY,
-                     "%s => bdb_dn2id_add dn=\"%s\" ID=0x%lx: put failed: %s %d\n",
-                     op->o_log_prefix, e->e_name.bv_val, e->e_id,
-                     db_strerror(rc), rc );
-               goto done;
-       }
-
-#ifndef BDB_MULTIPLE_SUFFIXES
-       if( !be_issuffix( op->o_bd, &ptr ))
-#endif
-       {
-               buf[0] = DN_SUBTREE_PREFIX;
-               rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                       "=> bdb_dn2id_add 0x%lx: subtree (%s) put failed: %d\n",
-                       e->e_id, ptr.bv_val, rc );
-                       goto done;
-               }
-               
-#ifdef BDB_MULTIPLE_SUFFIXES
-       if( !be_issuffix( op->o_bd, &ptr ))
-#endif
-       {
-               dnParent( &ptr, &pdn );
-       
-               key.size = pdn.bv_len + 2;
-               key.ulen = key.size;
-               pdn.bv_val[-1] = DN_ONE_PREFIX;
-               key.data = pdn.bv_val-1;
-               ptr = pdn;
-
-               rc = bdb_idl_insert_key( op->o_bd, db, txn, &key, e->e_id );
-
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "=> bdb_dn2id_add 0x%lx: parent (%s) insert failed: %d\n",
-                                       e->e_id, ptr.bv_val, rc );
-                       goto done;
-               }
-       }
-
-#ifndef BDB_MULTIPLE_SUFFIXES
-       while( !be_issuffix( op->o_bd, &ptr ))
-#else
-       for (;;)
-#endif
-       {
-               ptr.bv_val[-1] = DN_SUBTREE_PREFIX;
-
-               rc = bdb_idl_insert_key( op->o_bd, db, txn, &key, e->e_id );
-
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "=> bdb_dn2id_add 0x%lx: subtree (%s) insert failed: %d\n",
-                                       e->e_id, ptr.bv_val, rc );
-                       break;
-               }
-#ifdef BDB_MULTIPLE_SUFFIXES
-               if( be_issuffix( op->o_bd, &ptr )) break;
-#endif
-               dnParent( &ptr, &pdn );
-
-               key.size = pdn.bv_len + 2;
-               key.ulen = key.size;
-               key.data = pdn.bv_val - 1;
-               ptr = pdn;
-       }
-       }
-
-done:
-       op->o_tmpfree( buf, op->o_tmpmemctx );
-       Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_add 0x%lx: %d\n", e->e_id, rc );
-       return rc;
-}
-
-int
-bdb_dn2id_delete(
-       Operation *op,
-       DB_TXN *txn,
-       EntryInfo       *eip,
-       Entry           *e )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB *db = bdb->bi_dn2id->bdi_db;
-       char            *buf;
-       DBT             key;
-       struct berval   pdn, ptr;
-       int             rc;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_delete 0x%lx: \"%s\"\n",
-               e->e_id, e->e_ndn );
-
-       DBTzero( &key );
-       key.size = e->e_nname.bv_len + 2;
-       buf = op->o_tmpalloc( key.size, op->o_tmpmemctx );
-       key.data = buf;
-       key.flags = DB_DBT_USERMEM;
-       buf[0] = DN_BASE_PREFIX;
-       ptr.bv_val = buf+1;
-       ptr.bv_len = e->e_nname.bv_len;
-       AC_MEMCPY( ptr.bv_val, e->e_nname.bv_val, e->e_nname.bv_len );
-       ptr.bv_val[ptr.bv_len] = '\0';
-
-       /* delete it */
-       rc = db->del( db, txn, &key, 0 );
-       if( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_delete 0x%lx: delete failed: %s %d\n",
-                       e->e_id, db_strerror(rc), rc );
-               goto done;
-       }
-
-#ifndef BDB_MULTIPLE_SUFFIXES
-       if( !be_issuffix( op->o_bd, &ptr ))
-#endif
-       {
-               buf[0] = DN_SUBTREE_PREFIX;
-               rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id );
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                       "=> bdb_dn2id_delete 0x%lx: subtree (%s) delete failed: %d\n",
-                       e->e_id, ptr.bv_val, rc );
-                       goto done;
-               }
-
-#ifdef BDB_MULTIPLE_SUFFIXES
-       if( !be_issuffix( op->o_bd, &ptr ))
-#endif
-       {
-               dnParent( &ptr, &pdn );
-
-               key.size = pdn.bv_len + 2;
-               key.ulen = key.size;
-               pdn.bv_val[-1] = DN_ONE_PREFIX;
-               key.data = pdn.bv_val - 1;
-               ptr = pdn;
-
-               rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id );
-
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "=> bdb_dn2id_delete 0x%lx: parent (%s) delete failed: %d\n",
-                               e->e_id, ptr.bv_val, rc );
-                       goto done;
-               }
-       }
-
-#ifndef BDB_MULTIPLE_SUFFIXES
-       while( !be_issuffix( op->o_bd, &ptr ))
-#else
-       for (;;)
-#endif
-       {
-               ptr.bv_val[-1] = DN_SUBTREE_PREFIX;
-
-               rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id );
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "=> bdb_dn2id_delete 0x%lx: subtree (%s) delete failed: %d\n",
-                               e->e_id, ptr.bv_val, rc );
-                       goto done;
-               }
-#ifdef BDB_MULTIPLE_SUFFIXES
-               if( be_issuffix( op->o_bd, &ptr )) break;
-#endif
-               dnParent( &ptr, &pdn );
-
-               key.size = pdn.bv_len + 2;
-               key.ulen = key.size;
-               key.data = pdn.bv_val - 1;
-               ptr = pdn;
-       }
-       }
-
-done:
-       op->o_tmpfree( buf, op->o_tmpmemctx );
-       Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc );
-       return rc;
-}
-
-int
-bdb_dn2id(
-       Operation *op,
-       struct berval   *dn,
-       EntryInfo *ei,
-       DB_TXN *txn,
-       DBC **cursor )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB *db = bdb->bi_dn2id->bdi_db;
-       int             rc;
-       DBT             key, data;
-       ID              nid;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id(\"%s\")\n", dn->bv_val );
-
-       DBTzero( &key );
-       key.size = dn->bv_len + 2;
-       key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx );
-       ((char *)key.data)[0] = DN_BASE_PREFIX;
-       AC_MEMCPY( &((char *)key.data)[1], dn->bv_val, key.size - 1 );
-
-       /* store the ID */
-       DBTzero( &data );
-       data.data = &nid;
-       data.ulen = sizeof(ID);
-       data.flags = DB_DBT_USERMEM;
-
-       rc = db->cursor( db, txn, cursor, bdb->bi_db_opflags );
-
-       /* fetch it */
-       if ( !rc )
-               rc = (*cursor)->c_get( *cursor, &key, &data, DB_SET );
-
-       if( rc != 0 ) {
-               Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: get failed: %s (%d)\n",
-                       db_strerror( rc ), rc );
-       } else {
-               BDB_DISK2ID( &nid, &ei->bei_id );
-               Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: got id=0x%lx\n",
-                       ei->bei_id );
-       }
-       op->o_tmpfree( key.data, op->o_tmpmemctx );
-       return rc;
-}
-
-int
-bdb_dn2id_children(
-       Operation *op,
-       DB_TXN *txn,
-       Entry *e )
-{
-       DBT             key, data;
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB *db = bdb->bi_dn2id->bdi_db;
-       ID              id;
-       int             rc;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_children(\"%s\")\n",
-               e->e_nname.bv_val );
-       DBTzero( &key );
-       key.size = e->e_nname.bv_len + 2;
-       key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx );
-       ((char *)key.data)[0] = DN_ONE_PREFIX;
-       AC_MEMCPY( &((char *)key.data)[1], e->e_nname.bv_val, key.size - 1 );
-
-       if ( bdb->bi_idl_cache_size ) {
-               rc = bdb_idl_cache_get( bdb, db, &key, NULL );
-               if ( rc != LDAP_NO_SUCH_OBJECT ) {
-                       op->o_tmpfree( key.data, op->o_tmpmemctx );
-                       return rc;
-               }
-       }
-       /* we actually could do a empty get... */
-       DBTzero( &data );
-       data.data = &id;
-       data.ulen = sizeof(id);
-       data.flags = DB_DBT_USERMEM;
-       data.doff = 0;
-       data.dlen = sizeof(id);
-
-       rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags );
-       op->o_tmpfree( key.data, op->o_tmpmemctx );
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children(\"%s\"): %s (%d)\n",
-               e->e_nname.bv_val,
-               rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " :
-                       db_strerror(rc) ), rc );
-
-       return rc;
-}
-
-int
-bdb_dn2idl(
-       Operation *op,
-       DB_TXN *txn,
-       struct berval *ndn,
-       EntryInfo *ei,
-       ID *ids,
-       ID *stack )
-{
-       int             rc;
-       DBT             key;
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB *db = bdb->bi_dn2id->bdi_db;
-       int prefix = ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
-               ? DN_ONE_PREFIX : DN_SUBTREE_PREFIX;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2idl(\"%s\")\n",
-               ndn->bv_val );
-
-#ifndef        BDB_MULTIPLE_SUFFIXES
-       if ( prefix == DN_SUBTREE_PREFIX
-               && ( ei->bei_id == 0 ||
-               ( ei->bei_parent->bei_id == 0 && op->o_bd->be_suffix[0].bv_len ))) {
-               BDB_IDL_ALL(bdb, ids);
-               return 0;
-       }
-#endif
-
-       DBTzero( &key );
-       key.size = ndn->bv_len + 2;
-       key.ulen = key.size;
-       key.flags = DB_DBT_USERMEM;
-       key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx );
-       ((char *)key.data)[0] = prefix;
-       AC_MEMCPY( &((char *)key.data)[1], ndn->bv_val, key.size - 1 );
-
-       BDB_IDL_ZERO( ids );
-       rc = bdb_idl_fetch_key( op->o_bd, db, txn, &key, ids, NULL, 0 );
-
-       if( rc != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_dn2idl: get failed: %s (%d)\n",
-                       db_strerror( rc ), rc );
-
-       } else {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_dn2idl: id=%ld first=%ld last=%ld\n",
-                       (long) ids[0],
-                       (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) );
-       }
-
-       op->o_tmpfree( key.data, op->o_tmpmemctx );
-       return rc;
-}
-
-#else  /* BDB_HIER */
-/* Management routines for a hierarchically structured database.
- *
- * Instead of a ldbm-style dn2id database, we use a hierarchical one. Each
- * entry in this database is a struct diskNode, keyed by entryID and with
- * the data containing the RDN and entryID of the node's children. We use
- * a B-Tree with sorted duplicates to store all the children of a node under
- * the same key. Also, the first item under the key contains the entry's own
- * rdn and the ID of the node's parent, to allow bottom-up tree traversal as
- * well as top-down. To keep this info first in the list, the high bit of all
- * subsequent nrdnlen's is always set. This means we can only accomodate
- * RDNs up to length 32767, but that's fine since full DNs are already
- * restricted to 8192.
- *
- * The diskNode is a variable length structure. This definition is not
- * directly usable for in-memory manipulation.
- */
-typedef struct diskNode {
-       unsigned char nrdnlen[2];
-       char nrdn[1];
-       char rdn[1];                        /* variable placement */
-       unsigned char entryID[sizeof(ID)];  /* variable placement */
-} diskNode;
-
-/* Sort function for the sorted duplicate data items of a dn2id key.
- * Sorts based on normalized RDN, in length order.
- */
-int
-hdb_dup_compare(
-       DB *db, 
-       const DBT *usrkey,
-       const DBT *curkey
-)
-{
-       diskNode *un, *cn;
-       int rc;
-
-       un = (diskNode *)usrkey->data;
-       cn = (diskNode *)curkey->data;
-
-       /* data is not aligned, cannot compare directly */
-       rc = un->nrdnlen[0] - cn->nrdnlen[0];
-       if ( rc ) return rc;
-       rc = un->nrdnlen[1] - cn->nrdnlen[1];
-       if ( rc ) return rc;
-
-       return strcmp( un->nrdn, cn->nrdn );
-}
-
-/* This function constructs a full DN for a given entry.
- */
-int hdb_fix_dn(
-       Entry *e,
-       int checkit )
-{
-       EntryInfo *ei;
-       int rlen = 0, nrlen = 0;
-       char *ptr, *nptr;
-       int max = 0;
-
-       if ( !e->e_id )
-               return 0;
-
-       /* count length of all DN components */
-       for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) {
-               rlen += ei->bei_rdn.bv_len + 1;
-               nrlen += ei->bei_nrdn.bv_len + 1;
-               if (ei->bei_modrdns > max) max = ei->bei_modrdns;
-       }
-
-       /* See if the entry DN was invalidated by a subtree rename */
-       if ( checkit ) {
-               if ( BEI(e)->bei_modrdns >= max ) {
-                       return 0;
-               }
-               /* We found a mismatch, tell the caller to lock it */
-               if ( checkit == 1 ) {
-                       return 1;
-               }
-               /* checkit == 2. do the fix. */
-               free( e->e_name.bv_val );
-               free( e->e_nname.bv_val );
-       }
-
-       e->e_name.bv_len = rlen - 1;
-       e->e_nname.bv_len = nrlen - 1;
-       e->e_name.bv_val = ch_malloc(rlen);
-       e->e_nname.bv_val = ch_malloc(nrlen);
-       ptr = e->e_name.bv_val;
-       nptr = e->e_nname.bv_val;
-       for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) {
-               ptr = lutil_strcopy(ptr, ei->bei_rdn.bv_val);
-               nptr = lutil_strcopy(nptr, ei->bei_nrdn.bv_val);
-               if ( ei->bei_parent ) {
-                       *ptr++ = ',';
-                       *nptr++ = ',';
-               }
-       }
-       BEI(e)->bei_modrdns = max;
-       if ( ptr > e->e_name.bv_val ) ptr[-1] = '\0';
-       if ( nptr > e->e_nname.bv_val ) nptr[-1] = '\0';
-
-       return 0;
-}
-
-/* We add two elements to the DN2ID database - a data item under the parent's
- * entryID containing the child's RDN and entryID, and an item under the
- * child's entryID containing the parent's entryID.
- */
-int
-hdb_dn2id_add(
-       Operation       *op,
-       DB_TXN *txn,
-       EntryInfo       *eip,
-       Entry           *e )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB *db = bdb->bi_dn2id->bdi_db;
-       DBT             key, data;
-       ID              nid;
-       int             rc, rlen, nrlen;
-       diskNode *d;
-       char *ptr;
-
-       Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id_add 0x%lx: \"%s\"\n",
-               e->e_id, e->e_ndn );
-
-       nrlen = dn_rdnlen( op->o_bd, &e->e_nname );
-       if (nrlen) {
-               rlen = dn_rdnlen( op->o_bd, &e->e_name );
-       } else {
-               nrlen = e->e_nname.bv_len;
-               rlen = e->e_name.bv_len;
-       }
-
-       d = op->o_tmpalloc(sizeof(diskNode) + rlen + nrlen, op->o_tmpmemctx);
-       d->nrdnlen[1] = nrlen & 0xff;
-       d->nrdnlen[0] = (nrlen >> 8) | 0x80;
-       ptr = lutil_strncopy( d->nrdn, e->e_nname.bv_val, nrlen );
-       *ptr++ = '\0';
-       ptr = lutil_strncopy( ptr, e->e_name.bv_val, rlen );
-       *ptr++ = '\0';
-       BDB_ID2DISK( e->e_id, ptr );
-
-       DBTzero(&key);
-       DBTzero(&data);
-       key.size = sizeof(ID);
-       key.flags = DB_DBT_USERMEM;
-       BDB_ID2DISK( eip->bei_id, &nid );
-
-       key.data = &nid;
-
-       /* Need to make dummy root node once. Subsequent attempts
-        * will fail harmlessly.
-        */
-       if ( eip->bei_id == 0 ) {
-               diskNode dummy = {{0, 0}, "", "", ""};
-               data.data = &dummy;
-               data.size = sizeof(diskNode);
-               data.flags = DB_DBT_USERMEM;
-
-               db->put( db, txn, &key, &data, DB_NODUPDATA );
-       }
-
-       data.data = d;
-       data.size = sizeof(diskNode) + rlen + nrlen;
-       data.flags = DB_DBT_USERMEM;
-
-       rc = db->put( db, txn, &key, &data, DB_NODUPDATA );
-
-       if (rc == 0) {
-               BDB_ID2DISK( e->e_id, &nid );
-               BDB_ID2DISK( eip->bei_id, ptr );
-               d->nrdnlen[0] ^= 0x80;
-
-               rc = db->put( db, txn, &key, &data, DB_NODUPDATA );
-       }
-
-       /* Update all parents' IDL cache entries */
-       if ( rc == 0 && bdb->bi_idl_cache_size ) {
-               ID tmp[2];
-               char *ptr = ((char *)&tmp[1])-1;
-               key.data = ptr;
-               key.size = sizeof(ID)+1;
-               tmp[1] = eip->bei_id;
-               *ptr = DN_ONE_PREFIX;
-               bdb_idl_cache_add_id( bdb, db, &key, e->e_id );
-               if ( eip->bei_parent ) {
-                       *ptr = DN_SUBTREE_PREFIX;
-                       for (; eip && eip->bei_parent->bei_id; eip = eip->bei_parent) {
-                               tmp[1] = eip->bei_id;
-                               bdb_idl_cache_add_id( bdb, db, &key, e->e_id );
-                       }
-                       /* Handle DB with empty suffix */
-                       if ( !op->o_bd->be_suffix[0].bv_len && eip ) {
-                               tmp[1] = eip->bei_id;
-                               bdb_idl_cache_add_id( bdb, db, &key, e->e_id );
-                       }
-               }
-       }
-
-       op->o_tmpfree( d, op->o_tmpmemctx );
-       Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id_add 0x%lx: %d\n", e->e_id, rc );
-
-       return rc;
-}
-
-int
-hdb_dn2id_delete(
-       Operation       *op,
-       DB_TXN *txn,
-       EntryInfo       *eip,
-       Entry   *e )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB *db = bdb->bi_dn2id->bdi_db;
-       DBT             key, data;
-       DBC     *cursor;
-       diskNode *d;
-       int rc;
-       ID      nid;
-       unsigned char dlen[2];
-
-       Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id_delete 0x%lx: \"%s\"\n",
-               e->e_id, e->e_ndn );
-
-       DBTzero(&key);
-       key.size = sizeof(ID);
-       key.ulen = key.size;
-       key.flags = DB_DBT_USERMEM;
-       BDB_ID2DISK( eip->bei_id, &nid );
-
-       DBTzero(&data);
-       data.size = sizeof(diskNode) + BEI(e)->bei_nrdn.bv_len - sizeof(ID) - 1;
-       data.ulen = data.size;
-       data.dlen = data.size;
-       data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
-
-       key.data = &nid;
-
-       d = op->o_tmpalloc( data.size, op->o_tmpmemctx );
-       d->nrdnlen[1] = BEI(e)->bei_nrdn.bv_len & 0xff;
-       d->nrdnlen[0] = (BEI(e)->bei_nrdn.bv_len >> 8) | 0x80;
-       dlen[0] = d->nrdnlen[0];
-       dlen[1] = d->nrdnlen[1];
-       memcpy( d->nrdn, BEI(e)->bei_nrdn.bv_val, BEI(e)->bei_nrdn.bv_len+1 );
-       data.data = d;
-
-       rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
-       if ( rc ) goto func_leave;
-
-       /* Delete our ID from the parent's list */
-       rc = cursor->c_get( cursor, &key, &data, DB_GET_BOTH_RANGE );
-       if ( rc == 0 ) {
-               if ( dlen[1] == d->nrdnlen[1] && dlen[0] == d->nrdnlen[0] &&
-                       !strcmp( d->nrdn, BEI(e)->bei_nrdn.bv_val ))
-                       rc = cursor->c_del( cursor, 0 );
-               else
-                       rc = DB_NOTFOUND;
-       }
-
-       /* Delete our ID from the tree. With sorted duplicates, this
-        * will leave any child nodes still hanging around. This is OK
-        * for modrdn, which will add our info back in later.
-        */
-       if ( rc == 0 ) {
-               BDB_ID2DISK( e->e_id, &nid );
-               rc = cursor->c_get( cursor, &key, &data, DB_SET );
-               if ( rc == 0 )
-                       rc = cursor->c_del( cursor, 0 );
-       }
-
-       cursor->c_close( cursor );
-func_leave:
-       op->o_tmpfree( d, op->o_tmpmemctx );
-
-       /* Delete IDL cache entries */
-       if ( rc == 0 && bdb->bi_idl_cache_size ) {
-               ID tmp[2];
-               char *ptr = ((char *)&tmp[1])-1;
-               key.data = ptr;
-               key.size = sizeof(ID)+1;
-               tmp[1] = eip->bei_id;
-               *ptr = DN_ONE_PREFIX;
-               bdb_idl_cache_del_id( bdb, db, &key, e->e_id );
-               if ( eip ->bei_parent ) {
-                       *ptr = DN_SUBTREE_PREFIX;
-                       for (; eip && eip->bei_parent->bei_id; eip = eip->bei_parent) {
-                               tmp[1] = eip->bei_id;
-                               bdb_idl_cache_del_id( bdb, db, &key, e->e_id );
-                       }
-                       /* Handle DB with empty suffix */
-                       if ( !op->o_bd->be_suffix[0].bv_len && eip ) {
-                               tmp[1] = eip->bei_id;
-                               bdb_idl_cache_del_id( bdb, db, &key, e->e_id );
-                       }
-               }
-       }
-       Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc );
-       return rc;
-}
-
-
-int
-hdb_dn2id(
-       Operation       *op,
-       struct berval   *in,
-       EntryInfo       *ei,
-       DB_TXN *txn,
-       DBC **cursor )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB *db = bdb->bi_dn2id->bdi_db;
-       DBT             key, data;
-       int             rc = 0, nrlen;
-       diskNode *d;
-       char    *ptr;
-       unsigned char dlen[2];
-       ID idp, parentID;
-
-       Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id(\"%s\")\n", in->bv_val );
-
-       nrlen = dn_rdnlen( op->o_bd, in );
-       if (!nrlen) nrlen = in->bv_len;
-
-       DBTzero(&key);
-       key.size = sizeof(ID);
-       key.data = &idp;
-       key.ulen = sizeof(ID);
-       key.flags = DB_DBT_USERMEM;
-       parentID = ( ei->bei_parent != NULL ) ? ei->bei_parent->bei_id : 0;
-       BDB_ID2DISK( parentID, &idp );
-
-       DBTzero(&data);
-       data.size = sizeof(diskNode) + nrlen - sizeof(ID) - 1;
-       data.ulen = data.size * 3;
-       data.dlen = data.ulen;
-       data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
-
-       rc = db->cursor( db, txn, cursor, bdb->bi_db_opflags );
-       if ( rc ) return rc;
-
-       d = op->o_tmpalloc( data.size * 3, op->o_tmpmemctx );
-       d->nrdnlen[1] = nrlen & 0xff;
-       d->nrdnlen[0] = (nrlen >> 8) | 0x80;
-       dlen[0] = d->nrdnlen[0];
-       dlen[1] = d->nrdnlen[1];
-       ptr = lutil_strncopy( d->nrdn, in->bv_val, nrlen );
-       *ptr = '\0';
-       data.data = d;
-
-       rc = (*cursor)->c_get( *cursor, &key, &data, DB_GET_BOTH_RANGE );
-       if ( rc == 0 && (dlen[1] != d->nrdnlen[1] || dlen[0] != d->nrdnlen[0] ||
-               strncmp( d->nrdn, in->bv_val, nrlen ))) {
-               rc = DB_NOTFOUND;
-       }
-       if ( rc == 0 ) {
-               ptr = (char *) data.data + data.size - sizeof(ID);
-               BDB_DISK2ID( ptr, &ei->bei_id );
-               ei->bei_rdn.bv_len = data.size - sizeof(diskNode) - nrlen;
-               ptr = d->nrdn + nrlen + 1;
-               ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn );
-               if ( ei->bei_parent != NULL && !ei->bei_parent->bei_dkids ) {
-                       db_recno_t dkids;
-                       /* How many children does the parent have? */
-                       /* FIXME: do we need to lock the parent
-                        * entryinfo? Seems safe...
-                        */
-                       (*cursor)->c_count( *cursor, &dkids, 0 );
-                       ei->bei_parent->bei_dkids = dkids;
-               }
-       }
-
-       op->o_tmpfree( d, op->o_tmpmemctx );
-       if( rc != 0 ) {
-               Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: get failed: %s (%d)\n",
-                       db_strerror( rc ), rc );
-       } else {
-               Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: got id=0x%lx\n",
-                       ei->bei_id );
-       }
-
-       return rc;
-}
-
-int
-hdb_dn2id_parent(
-       Operation *op,
-       DB_TXN *txn,
-       EntryInfo *ei,
-       ID *idp )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB *db = bdb->bi_dn2id->bdi_db;
-       DBT             key, data;
-       DBC     *cursor;
-       int             rc = 0;
-       diskNode *d;
-       char    *ptr;
-       ID      nid;
-
-       DBTzero(&key);
-       key.size = sizeof(ID);
-       key.data = &nid;
-       key.ulen = sizeof(ID);
-       key.flags = DB_DBT_USERMEM;
-       BDB_ID2DISK( ei->bei_id, &nid );
-
-       DBTzero(&data);
-       data.flags = DB_DBT_USERMEM;
-
-       rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
-       if ( rc ) return rc;
-
-       data.ulen = sizeof(diskNode) + (SLAP_LDAPDN_MAXLEN * 2);
-       d = op->o_tmpalloc( data.ulen, op->o_tmpmemctx );
-       data.data = d;
-
-       rc = cursor->c_get( cursor, &key, &data, DB_SET );
-       if ( rc == 0 ) {
-               if (d->nrdnlen[0] & 0x80) {
-                       rc = LDAP_OTHER;
-               } else {
-                       db_recno_t dkids;
-                       ptr = (char *) data.data + data.size - sizeof(ID);
-                       BDB_DISK2ID( ptr, idp );
-                       ei->bei_nrdn.bv_len = (d->nrdnlen[0] << 8) | d->nrdnlen[1];
-                       ber_str2bv( d->nrdn, ei->bei_nrdn.bv_len, 1, &ei->bei_nrdn );
-                       ei->bei_rdn.bv_len = data.size - sizeof(diskNode) -
-                               ei->bei_nrdn.bv_len;
-                       ptr = d->nrdn + ei->bei_nrdn.bv_len + 1;
-                       ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn );
-                       /* How many children does this node have? */
-                       cursor->c_count( cursor, &dkids, 0 );
-                       ei->bei_dkids = dkids;
-               }
-       }
-       cursor->c_close( cursor );
-       op->o_tmpfree( d, op->o_tmpmemctx );
-       return rc;
-}
-
-int
-hdb_dn2id_children(
-       Operation *op,
-       DB_TXN *txn,
-       Entry *e )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB *db = bdb->bi_dn2id->bdi_db;
-       DBT             key, data;
-       DBC             *cursor;
-       int             rc;
-       ID              id;
-       diskNode d;
-
-       DBTzero(&key);
-       key.size = sizeof(ID);
-       key.data = &e->e_id;
-       key.flags = DB_DBT_USERMEM;
-       BDB_ID2DISK( e->e_id, &id );
-
-       /* IDL cache is in host byte order */
-       if ( bdb->bi_idl_cache_size ) {
-               rc = bdb_idl_cache_get( bdb, db, &key, NULL );
-               if ( rc != LDAP_NO_SUCH_OBJECT ) {
-                       return rc;
-               }
-       }
-
-       key.data = &id;
-       DBTzero(&data);
-       data.data = &d;
-       data.ulen = sizeof(d);
-       data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
-       data.dlen = sizeof(d);
-
-       rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
-       if ( rc ) return rc;
-
-       rc = cursor->c_get( cursor, &key, &data, DB_SET );
-       if ( rc == 0 ) {
-               db_recno_t dkids;
-               rc = cursor->c_count( cursor, &dkids, 0 );
-               if ( rc == 0 ) {
-                       BEI(e)->bei_dkids = dkids;
-                       if ( dkids < 2 ) rc = DB_NOTFOUND;
-               }
-       }
-       cursor->c_close( cursor );
-       return rc;
-}
-
-/* bdb_dn2idl:
- * We can't just use bdb_idl_fetch_key because
- * 1 - our data items are longer than just an entry ID
- * 2 - our data items are sorted alphabetically by nrdn, not by ID.
- *
- * We descend the tree recursively, so we define this cookie
- * to hold our necessary state information. The bdb_dn2idl_internal
- * function uses this cookie when calling itself.
- */
-
-struct dn2id_cookie {
-       struct bdb_info *bdb;
-       Operation *op;
-       DB_TXN *txn;
-       EntryInfo *ei;
-       ID *ids;
-       ID *tmp;
-       ID *buf;
-       DB *db;
-       DBC *dbc;
-       DBT key;
-       DBT data;
-       ID dbuf;
-       ID id;
-       ID nid;
-       int rc;
-       int depth;
-       char need_sort;
-       char prefix;
-};
-
-static int
-apply_func(
-       void *data,
-       void *arg )
-{
-       EntryInfo *ei = data;
-       ID *idl = arg;
-
-       bdb_idl_append_one( idl, ei->bei_id );
-       return 0;
-}
-
-static int
-hdb_dn2idl_internal(
-       struct dn2id_cookie *cx
-)
-{
-       BDB_IDL_ZERO( cx->tmp );
-
-       if ( cx->bdb->bi_idl_cache_size ) {
-               char *ptr = ((char *)&cx->id)-1;
-
-               cx->key.data = ptr;
-               cx->key.size = sizeof(ID)+1;
-               if ( cx->prefix == DN_SUBTREE_PREFIX ) {
-                       ID *ids = cx->depth ? cx->tmp : cx->ids;
-                       *ptr = cx->prefix;
-                       cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, ids);
-                       if ( cx->rc == LDAP_SUCCESS ) {
-                               if ( cx->depth ) {
-                                       bdb_idl_delete( cx->tmp, cx->id );      /* ITS#6983, drop our own ID */
-                                       bdb_idl_append( cx->ids, cx->tmp );
-                                       cx->need_sort = 1;
-                               }
-                               return cx->rc;
-                       }
-               }
-               *ptr = DN_ONE_PREFIX;
-               cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, cx->tmp);
-               if ( cx->rc == LDAP_SUCCESS ) {
-                       goto gotit;
-               }
-               if ( cx->rc == DB_NOTFOUND ) {
-                       return cx->rc;
-               }
-       }
-
-       bdb_cache_entryinfo_lock( cx->ei );
-
-       /* If number of kids in the cache differs from on-disk, load
-        * up all the kids from the database
-        */
-       if ( cx->ei->bei_ckids+1 != cx->ei->bei_dkids ) {
-               EntryInfo ei;
-               db_recno_t dkids = cx->ei->bei_dkids;
-               ei.bei_parent = cx->ei;
-
-               /* Only one thread should load the cache */
-               while ( cx->ei->bei_state & CACHE_ENTRY_ONELEVEL ) {
-                       bdb_cache_entryinfo_unlock( cx->ei );
-                       ldap_pvt_thread_yield();
-                       bdb_cache_entryinfo_lock( cx->ei );
-                       if ( cx->ei->bei_ckids+1 == cx->ei->bei_dkids ) {
-                               goto synced;
-                       }
-               }
-
-               cx->ei->bei_state |= CACHE_ENTRY_ONELEVEL;
-
-               bdb_cache_entryinfo_unlock( cx->ei );
-
-               cx->rc = cx->db->cursor( cx->db, NULL, &cx->dbc,
-                       cx->bdb->bi_db_opflags );
-               if ( cx->rc )
-                       goto done_one;
-
-               cx->data.data = &cx->dbuf;
-               cx->data.ulen = sizeof(ID);
-               cx->data.dlen = sizeof(ID);
-               cx->data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
-
-               /* The first item holds the parent ID. Ignore it. */
-               cx->key.data = &cx->nid;
-               cx->key.size = sizeof(ID);
-               cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data, DB_SET );
-               if ( cx->rc ) {
-                       cx->dbc->c_close( cx->dbc );
-                       goto done_one;
-               }
-
-               /* If the on-disk count is zero we've never checked it.
-                * Count it now.
-                */
-               if ( !dkids ) {
-                       cx->dbc->c_count( cx->dbc, &dkids, 0 );
-                       cx->ei->bei_dkids = dkids;
-               }
-
-               cx->data.data = cx->buf;
-               cx->data.ulen = BDB_IDL_UM_SIZE * sizeof(ID);
-               cx->data.flags = DB_DBT_USERMEM;
-
-               if ( dkids > 1 ) {
-                       /* Fetch the rest of the IDs in a loop... */
-                       while ( (cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data,
-                               DB_MULTIPLE | DB_NEXT_DUP )) == 0 ) {
-                               u_int8_t *j;
-                               size_t len;
-                               void *ptr;
-                               DB_MULTIPLE_INIT( ptr, &cx->data );
-                               while (ptr) {
-                                       DB_MULTIPLE_NEXT( ptr, &cx->data, j, len );
-                                       if (j) {
-                                               EntryInfo *ei2;
-                                               diskNode *d = (diskNode *)j;
-                                               short nrlen;
-
-                                               BDB_DISK2ID( j + len - sizeof(ID), &ei.bei_id );
-                                               nrlen = ((d->nrdnlen[0] ^ 0x80) << 8) | d->nrdnlen[1];
-                                               ei.bei_nrdn.bv_len = nrlen;
-                                               /* nrdn/rdn are set in-place.
-                                                * hdb_cache_load will copy them as needed
-                                                */
-                                               ei.bei_nrdn.bv_val = d->nrdn;
-                                               ei.bei_rdn.bv_len = len - sizeof(diskNode)
-                                                       - ei.bei_nrdn.bv_len;
-                                               ei.bei_rdn.bv_val = d->nrdn + ei.bei_nrdn.bv_len + 1;
-                                               bdb_idl_append_one( cx->tmp, ei.bei_id );
-                                               hdb_cache_load( cx->bdb, &ei, &ei2 );
-                                       }
-                               }
-                       }
-               }
-
-               cx->rc = cx->dbc->c_close( cx->dbc );
-done_one:
-               bdb_cache_entryinfo_lock( cx->ei );
-               cx->ei->bei_state &= ~CACHE_ENTRY_ONELEVEL;
-               bdb_cache_entryinfo_unlock( cx->ei );
-               if ( cx->rc )
-                       return cx->rc;
-
-       } else {
-               /* The in-memory cache is in sync with the on-disk data.
-                * do we have any kids?
-                */
-synced:
-               cx->rc = 0;
-               if ( cx->ei->bei_ckids > 0 ) {
-                       /* Walk the kids tree; order is irrelevant since bdb_idl_sort
-                        * will sort it later.
-                        */
-                       avl_apply( cx->ei->bei_kids, apply_func,
-                               cx->tmp, -1, AVL_POSTORDER );
-               }
-               bdb_cache_entryinfo_unlock( cx->ei );
-       }
-
-       if ( !BDB_IDL_IS_RANGE( cx->tmp ) && cx->tmp[0] > 3 )
-               bdb_idl_sort( cx->tmp, cx->buf );
-       if ( cx->bdb->bi_idl_cache_max_size && !BDB_IDL_IS_ZERO( cx->tmp )) {
-               char *ptr = ((char *)&cx->id)-1;
-               cx->key.data = ptr;
-               cx->key.size = sizeof(ID)+1;
-               *ptr = DN_ONE_PREFIX;
-               bdb_idl_cache_put( cx->bdb, cx->db, &cx->key, cx->tmp, cx->rc );
-       }
-
-gotit:
-       if ( !BDB_IDL_IS_ZERO( cx->tmp )) {
-               if ( cx->prefix == DN_SUBTREE_PREFIX ) {
-                       bdb_idl_append( cx->ids, cx->tmp );
-                       cx->need_sort = 1;
-                       if ( !(cx->ei->bei_state & CACHE_ENTRY_NO_GRANDKIDS)) {
-                               ID *save, idcurs;
-                               EntryInfo *ei = cx->ei;
-                               int nokids = 1;
-                               save = cx->op->o_tmpalloc( BDB_IDL_SIZEOF( cx->tmp ),
-                                       cx->op->o_tmpmemctx );
-                               BDB_IDL_CPY( save, cx->tmp );
-
-                               idcurs = 0;
-                               cx->depth++;
-                               for ( cx->id = bdb_idl_first( save, &idcurs );
-                                       cx->id != NOID;
-                                       cx->id = bdb_idl_next( save, &idcurs )) {
-                                       EntryInfo *ei2;
-                                       cx->ei = NULL;
-                                       if ( bdb_cache_find_id( cx->op, cx->txn, cx->id, &cx->ei,
-                                               ID_NOENTRY, NULL ))
-                                               continue;
-                                       if ( cx->ei ) {
-                                               ei2 = cx->ei;
-                                               if ( !( ei2->bei_state & CACHE_ENTRY_NO_KIDS )) {
-                                                       BDB_ID2DISK( cx->id, &cx->nid );
-                                                       hdb_dn2idl_internal( cx );
-                                                       if ( !BDB_IDL_IS_ZERO( cx->tmp ))
-                                                               nokids = 0;
-                                               }
-                                               bdb_cache_entryinfo_lock( ei2 );
-                                               ei2->bei_finders--;
-                                               bdb_cache_entryinfo_unlock( ei2 );
-                                       }
-                               }
-                               cx->depth--;
-                               cx->op->o_tmpfree( save, cx->op->o_tmpmemctx );
-                               if ( nokids ) {
-                                       bdb_cache_entryinfo_lock( ei );
-                                       ei->bei_state |= CACHE_ENTRY_NO_GRANDKIDS;
-                                       bdb_cache_entryinfo_unlock( ei );
-                               }
-                       }
-                       /* Make sure caller knows it had kids! */
-                       cx->tmp[0]=1;
-
-                       cx->rc = 0;
-               } else {
-                       BDB_IDL_CPY( cx->ids, cx->tmp );
-               }
-       }
-       return cx->rc;
-}
-
-int
-hdb_dn2idl(
-       Operation       *op,
-       DB_TXN *txn,
-       struct berval *ndn,
-       EntryInfo       *ei,
-       ID *ids,
-       ID *stack )
-{
-       struct bdb_info *bdb = (struct bdb_info *)op->o_bd->be_private;
-       struct dn2id_cookie cx;
-
-       Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2idl(\"%s\")\n",
-               ndn->bv_val );
-
-#ifndef BDB_MULTIPLE_SUFFIXES
-       if ( op->ors_scope != LDAP_SCOPE_ONELEVEL && 
-               ( ei->bei_id == 0 ||
-               ( ei->bei_parent->bei_id == 0 && op->o_bd->be_suffix[0].bv_len )))
-       {
-               BDB_IDL_ALL( bdb, ids );
-               return 0;
-       }
-#endif
-
-       cx.id = ei->bei_id;
-       BDB_ID2DISK( cx.id, &cx.nid );
-       cx.ei = ei;
-       cx.bdb = bdb;
-       cx.db = cx.bdb->bi_dn2id->bdi_db;
-       cx.prefix = (op->ors_scope == LDAP_SCOPE_ONELEVEL) ?
-               DN_ONE_PREFIX : DN_SUBTREE_PREFIX;
-       cx.ids = ids;
-       cx.tmp = stack;
-       cx.buf = stack + BDB_IDL_UM_SIZE;
-       cx.op = op;
-       cx.txn = txn;
-       cx.need_sort = 0;
-       cx.depth = 0;
-
-       if ( cx.prefix == DN_SUBTREE_PREFIX ) {
-               ids[0] = 1;
-               ids[1] = cx.id;
-       } else {
-               BDB_IDL_ZERO( ids );
-       }
-       if ( cx.ei->bei_state & CACHE_ENTRY_NO_KIDS )
-               return LDAP_SUCCESS;
-
-       DBTzero(&cx.key);
-       cx.key.ulen = sizeof(ID);
-       cx.key.size = sizeof(ID);
-       cx.key.flags = DB_DBT_USERMEM;
-
-       DBTzero(&cx.data);
-
-       hdb_dn2idl_internal(&cx);
-       if ( cx.need_sort ) {
-               char *ptr = ((char *)&cx.id)-1;
-               if ( !BDB_IDL_IS_RANGE( cx.ids ) && cx.ids[0] > 3 ) 
-                       bdb_idl_sort( cx.ids, cx.tmp );
-               cx.key.data = ptr;
-               cx.key.size = sizeof(ID)+1;
-               *ptr = cx.prefix;
-               cx.id = ei->bei_id;
-               if ( cx.bdb->bi_idl_cache_max_size )
-                       bdb_idl_cache_put( cx.bdb, cx.db, &cx.key, cx.ids, cx.rc );
-       }
-
-       if ( cx.rc == DB_NOTFOUND )
-               cx.rc = LDAP_SUCCESS;
-
-       return cx.rc;
-}
-#endif /* BDB_HIER */
diff --git a/servers/slapd/back-bdb/error.c b/servers/slapd/back-bdb/error.c
deleted file mode 100644 (file)
index 738ba8b..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* error.c - BDB errcall routine */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-bdb.h"
-
-#if DB_VERSION_FULL < 0x04030000
-void bdb_errcall( const char *pfx, char * msg )
-#else
-void bdb_errcall( const DB_ENV *env, const char *pfx, const char * msg )
-#endif
-{
-#ifdef HAVE_EBCDIC
-       if ( msg[0] > 0x7f )
-               __etoa( msg );
-#endif
-       Debug( LDAP_DEBUG_ANY, "bdb(%s): %s\n", pfx, msg );
-}
-
-#if DB_VERSION_FULL >= 0x04030000
-void bdb_msgcall( const DB_ENV *env, const char *msg )
-{
-#ifdef HAVE_EBCDIC
-       if ( msg[0] > 0x7f )
-               __etoa( msg );
-#endif
-       Debug( LDAP_DEBUG_TRACE, "bdb: %s\n", msg );
-}
-#endif
-
-#ifdef HAVE_EBCDIC
-
-#undef db_strerror
-
-/* Not re-entrant! */
-char *ebcdic_dberror( int rc )
-{
-       static char msg[1024];
-
-       strcpy( msg, db_strerror( rc ) );
-       __etoa( msg );
-       return msg;
-}
-#endif
diff --git a/servers/slapd/back-bdb/extended.c b/servers/slapd/back-bdb/extended.c
deleted file mode 100644 (file)
index 2a3b87a..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* extended.c - bdb backend extended routines */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-#include "lber_pvt.h"
-
-static struct exop {
-       struct berval *oid;
-       BI_op_extended  *extended;
-} exop_table[] = {
-       { NULL, NULL }
-};
-
-int
-bdb_extended( Operation *op, SlapReply *rs )
-/*     struct berval           *reqoid,
-       struct berval   *reqdata,
-       char            **rspoid,
-       struct berval   **rspdata,
-       LDAPControl *** rspctrls,
-       const char**    text,
-       BerVarray       *refs 
-) */
-{
-       int i;
-
-       for( i=0; exop_table[i].extended != NULL; i++ ) {
-               if( ber_bvcmp( exop_table[i].oid, &op->oq_extended.rs_reqoid ) == 0 ) {
-                       return (exop_table[i].extended)( op, rs );
-               }
-       }
-
-       rs->sr_text = "not supported within naming context";
-       return rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
-}
-
diff --git a/servers/slapd/back-bdb/filterindex.c b/servers/slapd/back-bdb/filterindex.c
deleted file mode 100644 (file)
index 90b5858..0000000
+++ /dev/null
@@ -1,1183 +0,0 @@
-/* filterindex.c - generate the list of candidate entries from a filter */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-#include "idl.h"
-#ifdef LDAP_COMP_MATCH
-#include <component.h>
-#endif
-
-static int presence_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       AttributeDescription *desc,
-       ID *ids );
-
-static int equality_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       AttributeAssertion *ava,
-       ID *ids,
-       ID *tmp );
-static int inequality_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       AttributeAssertion *ava,
-       ID *ids,
-       ID *tmp,
-       int gtorlt );
-static int approx_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       AttributeAssertion *ava,
-       ID *ids,
-       ID *tmp );
-static int substring_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       SubstringsAssertion *sub,
-       ID *ids,
-       ID *tmp );
-
-static int list_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       Filter *flist,
-       int ftype,
-       ID *ids,
-       ID *tmp,
-       ID *stack );
-
-static int
-ext_candidates(
-        Operation *op,
-               DB_TXN *rtxn,
-        MatchingRuleAssertion *mra,
-        ID *ids,
-        ID *tmp,
-        ID *stack);
-
-#ifdef LDAP_COMP_MATCH
-static int
-comp_candidates (
-       Operation *op,
-       DB_TXN *rtxn,
-       MatchingRuleAssertion *mra,
-       ComponentFilter *f,
-       ID *ids,
-       ID *tmp,
-       ID *stack);
-
-static int
-ava_comp_candidates (
-               Operation *op,
-               DB_TXN *rtxn,
-               AttributeAssertion *ava,
-               AttributeAliasing *aa,
-               ID *ids,
-               ID *tmp,
-               ID *stack);
-#endif
-
-int
-bdb_filter_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       Filter  *f,
-       ID *ids,
-       ID *tmp,
-       ID *stack )
-{
-       int rc = 0;
-#ifdef LDAP_COMP_MATCH
-       AttributeAliasing *aa;
-#endif
-       Debug( LDAP_DEBUG_FILTER, "=> bdb_filter_candidates\n" );
-
-       if ( f->f_choice & SLAPD_FILTER_UNDEFINED ) {
-               BDB_IDL_ZERO( ids );
-               goto out;
-       }
-
-       switch ( f->f_choice ) {
-       case SLAPD_FILTER_COMPUTED:
-               switch( f->f_result ) {
-               case SLAPD_COMPARE_UNDEFINED:
-               /* This technically is not the same as FALSE, but it
-                * certainly will produce no matches.
-                */
-               /* FALL THRU */
-               case LDAP_COMPARE_FALSE:
-                       BDB_IDL_ZERO( ids );
-                       break;
-               case LDAP_COMPARE_TRUE: {
-                       struct bdb_info *bdb = (struct bdb_info *)op->o_bd->be_private;
-                       BDB_IDL_ALL( bdb, ids );
-                       } break;
-               case LDAP_SUCCESS:
-                       /* this is a pre-computed scope, leave it alone */
-                       break;
-               }
-               break;
-       case LDAP_FILTER_PRESENT:
-               Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n" );
-               rc = presence_candidates( op, rtxn, f->f_desc, ids );
-               break;
-
-       case LDAP_FILTER_EQUALITY:
-               Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n" );
-#ifdef LDAP_COMP_MATCH
-               if ( is_aliased_attribute && ( aa = is_aliased_attribute ( f->f_ava->aa_desc ) ) ) {
-                       rc = ava_comp_candidates ( op, rtxn, f->f_ava, aa, ids, tmp, stack );
-               }
-               else
-#endif
-               {
-                       rc = equality_candidates( op, rtxn, f->f_ava, ids, tmp );
-               }
-               break;
-
-       case LDAP_FILTER_APPROX:
-               Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n" );
-               rc = approx_candidates( op, rtxn, f->f_ava, ids, tmp );
-               break;
-
-       case LDAP_FILTER_SUBSTRINGS:
-               Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n" );
-               rc = substring_candidates( op, rtxn, f->f_sub, ids, tmp );
-               break;
-
-       case LDAP_FILTER_GE:
-               /* if no GE index, use pres */
-               Debug( LDAP_DEBUG_FILTER, "\tGE\n" );
-               if( f->f_ava->aa_desc->ad_type->sat_ordering &&
-                       ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) )
-                       rc = inequality_candidates( op, rtxn, f->f_ava, ids, tmp, LDAP_FILTER_GE );
-               else
-                       rc = presence_candidates( op, rtxn, f->f_ava->aa_desc, ids );
-               break;
-
-       case LDAP_FILTER_LE:
-               /* if no LE index, use pres */
-               Debug( LDAP_DEBUG_FILTER, "\tLE\n" );
-               if( f->f_ava->aa_desc->ad_type->sat_ordering &&
-                       ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) )
-                       rc = inequality_candidates( op, rtxn, f->f_ava, ids, tmp, LDAP_FILTER_LE );
-               else
-                       rc = presence_candidates( op, rtxn, f->f_ava->aa_desc, ids );
-               break;
-
-       case LDAP_FILTER_NOT:
-               /* no indexing to support NOT filters */
-               Debug( LDAP_DEBUG_FILTER, "\tNOT\n" );
-               { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-               BDB_IDL_ALL( bdb, ids );
-               }
-               break;
-
-       case LDAP_FILTER_AND:
-               Debug( LDAP_DEBUG_FILTER, "\tAND\n" );
-               rc = list_candidates( op, rtxn, 
-                       f->f_and, LDAP_FILTER_AND, ids, tmp, stack );
-               break;
-
-       case LDAP_FILTER_OR:
-               Debug( LDAP_DEBUG_FILTER, "\tOR\n" );
-               rc = list_candidates( op, rtxn,
-                       f->f_or, LDAP_FILTER_OR, ids, tmp, stack );
-               break;
-       case LDAP_FILTER_EXT:
-                Debug( LDAP_DEBUG_FILTER, "\tEXT\n" );
-                rc = ext_candidates( op, rtxn, f->f_mra, ids, tmp, stack );
-                break;
-       default:
-               Debug( LDAP_DEBUG_FILTER, "\tUNKNOWN %lu\n",
-                       (unsigned long) f->f_choice );
-               /* Must not return NULL, otherwise extended filters break */
-               { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-               BDB_IDL_ALL( bdb, ids );
-               }
-       }
-
-out:
-       Debug( LDAP_DEBUG_FILTER,
-               "<= bdb_filter_candidates: id=%ld first=%ld last=%ld\n",
-               (long) ids[0],
-               (long) BDB_IDL_FIRST( ids ),
-               (long) BDB_IDL_LAST( ids ) );
-
-       return rc;
-}
-
-#ifdef LDAP_COMP_MATCH
-static int
-comp_list_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       MatchingRuleAssertion* mra,
-       ComponentFilter *flist,
-       int     ftype,
-       ID *ids,
-       ID *tmp,
-       ID *save )
-{
-       int rc = 0;
-       ComponentFilter *f;
-
-       Debug( LDAP_DEBUG_FILTER, "=> comp_list_candidates 0x%x\n", ftype );
-       for ( f = flist; f != NULL; f = f->cf_next ) {
-               /* ignore precomputed scopes */
-               if ( f->cf_choice == SLAPD_FILTER_COMPUTED &&
-                    f->cf_result == LDAP_SUCCESS ) {
-                       continue;
-               }
-               BDB_IDL_ZERO( save );
-               rc = comp_candidates( op, rtxn, mra, f, save, tmp, save+BDB_IDL_UM_SIZE );
-
-               if ( rc != 0 ) {
-                       if ( ftype == LDAP_COMP_FILTER_AND ) {
-                               rc = 0;
-                               continue;
-                       }
-                       break;
-               }
-               
-               if ( ftype == LDAP_COMP_FILTER_AND ) {
-                       if ( f == flist ) {
-                               BDB_IDL_CPY( ids, save );
-                       } else {
-                               bdb_idl_intersection( ids, save );
-                       }
-                       if( BDB_IDL_IS_ZERO( ids ) )
-                               break;
-               } else {
-                       if ( f == flist ) {
-                               BDB_IDL_CPY( ids, save );
-                       } else {
-                               bdb_idl_union( ids, save );
-                       }
-               }
-       }
-
-       if( rc == LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_FILTER,
-                       "<= comp_list_candidates: id=%ld first=%ld last=%ld\n",
-                       (long) ids[0],
-                       (long) BDB_IDL_FIRST(ids),
-                       (long) BDB_IDL_LAST(ids) );
-
-       } else {
-               Debug( LDAP_DEBUG_FILTER,
-                       "<= comp_list_candidates: undefined rc=%d\n",
-                       rc );
-       }
-
-       return rc;
-}
-
-static int
-comp_equality_candidates (
-        Operation *op,
-       DB_TXN *rtxn,
-        MatchingRuleAssertion *mra,
-       ComponentAssertion *ca,
-        ID *ids,
-        ID *tmp,
-        ID *stack)
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-        DB      *db;
-        int i;
-        int rc;
-        slap_mask_t mask;
-        struct berval prefix = {0, NULL};
-        struct berval *keys = NULL;
-        MatchingRule *mr = mra->ma_rule;
-        Syntax *sat_syntax;
-       ComponentReference* cr_list, *cr;
-       AttrInfo *ai;
-
-        BDB_IDL_ALL( bdb, ids );
-
-       if ( !ca->ca_comp_ref )
-               return 0;
-
-       ai = bdb_attr_mask( op->o_bd->be_private, mra->ma_desc );
-       if( ai ) {
-               cr_list = ai->ai_cr;
-       }
-       else {
-               return 0;
-       }
-       /* find a component reference to be indexed */
-       sat_syntax = ca->ca_ma_rule->smr_syntax;
-       for ( cr = cr_list ; cr ; cr = cr->cr_next ) {
-               if ( cr->cr_string.bv_len == ca->ca_comp_ref->cr_string.bv_len &&
-                       strncmp( cr->cr_string.bv_val, ca->ca_comp_ref->cr_string.bv_val,cr->cr_string.bv_len ) == 0 )
-                       break;
-       }
-       
-       if ( !cr )
-               return 0;
-
-        rc = bdb_index_param( op->o_bd, mra->ma_desc, LDAP_FILTER_EQUALITY,
-                &db, &mask, &prefix );
-
-        if( rc != LDAP_SUCCESS ) {
-                return 0;
-        }
-
-        if( !mr ) {
-                return 0;
-        }
-
-        if( !mr->smr_filter ) {
-                return 0;
-        }
-
-       rc = (ca->ca_ma_rule->smr_filter)(
-                LDAP_FILTER_EQUALITY,
-                cr->cr_indexmask,
-                sat_syntax,
-                ca->ca_ma_rule,
-                &prefix,
-                &ca->ca_ma_value,
-                &keys, op->o_tmpmemctx );
-
-        if( rc != LDAP_SUCCESS ) {
-                return 0;
-        }
-
-        if( keys == NULL ) {
-                return 0;
-        }
-        for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-                rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 );
-
-                if( rc == DB_NOTFOUND ) {
-                        BDB_IDL_ZERO( ids );
-                        rc = 0;
-                        break;
-                } else if( rc != LDAP_SUCCESS ) {
-                        break;
-                }
-
-                if( BDB_IDL_IS_ZERO( tmp ) ) {
-                        BDB_IDL_ZERO( ids );
-                        break;
-                }
-
-                if ( i == 0 ) {
-                        BDB_IDL_CPY( ids, tmp );
-                } else {
-                        bdb_idl_intersection( ids, tmp );
-                }
-
-                if( BDB_IDL_IS_ZERO( ids ) )
-                        break;
-        }
-        ber_bvarray_free_x( keys, op->o_tmpmemctx );
-
-        Debug( LDAP_DEBUG_TRACE,
-                "<= comp_equality_candidates: id=%ld, first=%ld, last=%ld\n",
-                (long) ids[0],
-                (long) BDB_IDL_FIRST(ids),
-                (long) BDB_IDL_LAST(ids) );
-        return( rc );
-}
-
-static int
-ava_comp_candidates (
-       Operation *op,
-       DB_TXN *rtxn,
-       AttributeAssertion *ava,
-       AttributeAliasing *aa,
-       ID *ids,
-       ID *tmp,
-       ID *stack )
-{
-       MatchingRuleAssertion mra;
-       
-       mra.ma_rule = ava->aa_desc->ad_type->sat_equality;
-       if ( !mra.ma_rule ) {
-               struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-               BDB_IDL_ALL( bdb, ids );
-               return 0;
-       }
-       mra.ma_desc = aa->aa_aliased_ad;
-       mra.ma_rule = ava->aa_desc->ad_type->sat_equality;
-       
-       return comp_candidates ( op, rtxn, &mra, ava->aa_cf, ids, tmp, stack );
-}
-
-static int
-comp_candidates (
-       Operation *op,
-       DB_TXN *rtxn,
-       MatchingRuleAssertion *mra,
-       ComponentFilter *f,
-       ID *ids,
-       ID *tmp,
-       ID *stack)
-{
-       int     rc;
-
-       if ( !f ) return LDAP_PROTOCOL_ERROR;
-
-       Debug( LDAP_DEBUG_FILTER, "comp_candidates\n" );
-       switch ( f->cf_choice ) {
-       case SLAPD_FILTER_COMPUTED:
-               rc = f->cf_result;
-               break;
-       case LDAP_COMP_FILTER_AND:
-               rc = comp_list_candidates( op, rtxn, mra, f->cf_and, LDAP_COMP_FILTER_AND, ids, tmp, stack );
-               break;
-       case LDAP_COMP_FILTER_OR:
-               rc = comp_list_candidates( op, rtxn, mra, f->cf_or, LDAP_COMP_FILTER_OR, ids, tmp, stack );
-               break;
-       case LDAP_COMP_FILTER_NOT:
-               /* No component indexing supported for NOT filter */
-               Debug( LDAP_DEBUG_FILTER, "\tComponent NOT\n" );
-               {
-                       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-                       BDB_IDL_ALL( bdb, ids );
-               }
-               rc = LDAP_PROTOCOL_ERROR;
-               break;
-       case LDAP_COMP_FILTER_ITEM:
-               rc = comp_equality_candidates( op, rtxn, mra, f->cf_ca, ids, tmp, stack );
-               break;
-       default:
-               {
-                       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-                       BDB_IDL_ALL( bdb, ids );
-               }
-               rc = LDAP_PROTOCOL_ERROR;
-       }
-
-       return( rc );
-}
-#endif
-
-static int
-ext_candidates(
-        Operation *op,
-               DB_TXN *rtxn,
-        MatchingRuleAssertion *mra,
-        ID *ids,
-        ID *tmp,
-        ID *stack)
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-
-#ifdef LDAP_COMP_MATCH
-       /*
-        * Currently Only Component Indexing for componentFilterMatch is supported
-        * Indexing for an extensible filter is not supported yet
-        */
-       if ( mra->ma_cf ) {
-               return comp_candidates ( op, rtxn, mra, mra->ma_cf, ids, tmp, stack);
-       }
-#endif
-       if ( mra->ma_desc == slap_schema.si_ad_entryDN ) {
-               int rc;
-               EntryInfo *ei;
-
-               BDB_IDL_ZERO( ids );
-               if ( mra->ma_rule == slap_schema.si_mr_distinguishedNameMatch ) {
-                       ei = NULL;
-                       rc = bdb_cache_find_ndn( op, rtxn, &mra->ma_value, &ei );
-                       if ( rc == LDAP_SUCCESS )
-                               bdb_idl_insert( ids, ei->bei_id );
-                       if ( ei )
-                               bdb_cache_entryinfo_unlock( ei );
-                       return 0;
-               } else if ( mra->ma_rule && mra->ma_rule->smr_match ==
-                       dnRelativeMatch && dnIsSuffix( &mra->ma_value,
-                               op->o_bd->be_nsuffix )) {
-                       int scope;
-                       if ( mra->ma_rule == slap_schema.si_mr_dnSuperiorMatch ) {
-                               struct berval pdn;
-                               ei = NULL;
-                               dnParent( &mra->ma_value, &pdn );
-                               bdb_cache_find_ndn( op, rtxn, &pdn, &ei );
-                               if ( ei ) {
-                                       bdb_cache_entryinfo_unlock( ei );
-                                       while ( ei && ei->bei_id ) {
-                                               bdb_idl_insert( ids, ei->bei_id );
-                                               ei = ei->bei_parent;
-                                       }
-                               }
-                               return 0;
-                       }
-                       if ( mra->ma_rule == slap_schema.si_mr_dnSubtreeMatch )
-                               scope = LDAP_SCOPE_SUBTREE;
-                       else if ( mra->ma_rule == slap_schema.si_mr_dnOneLevelMatch )
-                               scope = LDAP_SCOPE_ONELEVEL;
-                       else if ( mra->ma_rule == slap_schema.si_mr_dnSubordinateMatch )
-                               scope = LDAP_SCOPE_SUBORDINATE;
-                       else
-                               scope = LDAP_SCOPE_BASE;
-                       if ( scope > LDAP_SCOPE_BASE ) {
-                               ei = NULL;
-                               rc = bdb_cache_find_ndn( op, rtxn, &mra->ma_value, &ei );
-                               if ( ei )
-                                       bdb_cache_entryinfo_unlock( ei );
-                               if ( rc == LDAP_SUCCESS ) {
-                                       int sc = op->ors_scope;
-                                       op->ors_scope = scope;
-                                       rc = bdb_dn2idl( op, rtxn, &mra->ma_value, ei, ids,
-                                               stack );
-                                       op->ors_scope = sc;
-                               }
-                               return 0;
-                       }
-               }
-       }
-
-       BDB_IDL_ALL( bdb, ids );
-       return 0;
-}
-
-static int
-list_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       Filter  *flist,
-       int             ftype,
-       ID *ids,
-       ID *tmp,
-       ID *save )
-{
-       int rc = 0;
-       Filter  *f;
-
-       Debug( LDAP_DEBUG_FILTER, "=> bdb_list_candidates 0x%x\n", ftype );
-       for ( f = flist; f != NULL; f = f->f_next ) {
-               /* ignore precomputed scopes */
-               if ( f->f_choice == SLAPD_FILTER_COMPUTED &&
-                    f->f_result == LDAP_SUCCESS ) {
-                       continue;
-               }
-               BDB_IDL_ZERO( save );
-               rc = bdb_filter_candidates( op, rtxn, f, save, tmp,
-                       save+BDB_IDL_UM_SIZE );
-
-               if ( rc != 0 ) {
-                       if ( rc == DB_LOCK_DEADLOCK )
-                               return rc;
-
-                       if ( ftype == LDAP_FILTER_AND ) {
-                               rc = 0;
-                               continue;
-                       }
-                       break;
-               }
-
-               
-               if ( ftype == LDAP_FILTER_AND ) {
-                       if ( f == flist ) {
-                               BDB_IDL_CPY( ids, save );
-                       } else {
-                               bdb_idl_intersection( ids, save );
-                       }
-                       if( BDB_IDL_IS_ZERO( ids ) )
-                               break;
-               } else {
-                       if ( f == flist ) {
-                               BDB_IDL_CPY( ids, save );
-                       } else {
-                               bdb_idl_union( ids, save );
-                       }
-               }
-       }
-
-       if( rc == LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_FILTER,
-                       "<= bdb_list_candidates: id=%ld first=%ld last=%ld\n",
-                       (long) ids[0],
-                       (long) BDB_IDL_FIRST(ids),
-                       (long) BDB_IDL_LAST(ids) );
-
-       } else {
-               Debug( LDAP_DEBUG_FILTER,
-                       "<= bdb_list_candidates: undefined rc=%d\n",
-                       rc );
-       }
-
-       return rc;
-}
-
-static int
-presence_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       AttributeDescription *desc,
-       ID *ids )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB *db;
-       int rc;
-       slap_mask_t mask;
-       struct berval prefix = {0, NULL};
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_presence_candidates (%s)\n",
-                       desc->ad_cname.bv_val );
-
-       BDB_IDL_ALL( bdb, ids );
-
-       if( desc == slap_schema.si_ad_objectClass ) {
-               return 0;
-       }
-
-       rc = bdb_index_param( op->o_bd, desc, LDAP_FILTER_PRESENT,
-               &db, &mask, &prefix );
-
-       if( rc == LDAP_INAPPROPRIATE_MATCHING ) {
-               /* not indexed */
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_presence_candidates: (%s) not indexed\n",
-                       desc->ad_cname.bv_val );
-               return 0;
-       }
-
-       if( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_presence_candidates: (%s) index_param "
-                       "returned=%d\n",
-                       desc->ad_cname.bv_val, rc );
-               return 0;
-       }
-
-       if( prefix.bv_val == NULL ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_presence_candidates: (%s) no prefix\n",
-                       desc->ad_cname.bv_val );
-               return -1;
-       }
-
-       rc = bdb_key_read( op->o_bd, db, rtxn, &prefix, ids, NULL, 0 );
-
-       if( rc == DB_NOTFOUND ) {
-               BDB_IDL_ZERO( ids );
-               rc = 0;
-       } else if( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_presense_candidates: (%s) "
-                       "key read failed (%d)\n",
-                       desc->ad_cname.bv_val, rc );
-               goto done;
-       }
-
-       Debug(LDAP_DEBUG_TRACE,
-               "<= bdb_presence_candidates: id=%ld first=%ld last=%ld\n",
-               (long) ids[0],
-               (long) BDB_IDL_FIRST(ids),
-               (long) BDB_IDL_LAST(ids) );
-
-done:
-       return rc;
-}
-
-static int
-equality_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       AttributeAssertion *ava,
-       ID *ids,
-       ID *tmp )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB      *db;
-       int i;
-       int rc;
-       slap_mask_t mask;
-       struct berval prefix = {0, NULL};
-       struct berval *keys = NULL;
-       MatchingRule *mr;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_equality_candidates (%s)\n",
-                       ava->aa_desc->ad_cname.bv_val );
-
-       if ( ava->aa_desc == slap_schema.si_ad_entryDN ) {
-               EntryInfo *ei = NULL;
-               rc = bdb_cache_find_ndn( op, rtxn, &ava->aa_value, &ei );
-               if ( rc == LDAP_SUCCESS ) {
-                       /* exactly one ID can match */
-                       ids[0] = 1;
-                       ids[1] = ei->bei_id;
-               }
-               if ( ei ) {
-                       bdb_cache_entryinfo_unlock( ei );
-               }
-               if ( rc == DB_NOTFOUND ) {
-                       BDB_IDL_ZERO( ids );
-                       rc = 0;
-               }
-               return rc;
-       }
-
-       BDB_IDL_ALL( bdb, ids );
-
-       rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_EQUALITY,
-               &db, &mask, &prefix );
-
-       if ( rc == LDAP_INAPPROPRIATE_MATCHING ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_equality_candidates: (%s) not indexed\n", 
-                       ava->aa_desc->ad_cname.bv_val );
-               return 0;
-       }
-
-       if( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_equality_candidates: (%s) "
-                       "index_param failed (%d)\n",
-                       ava->aa_desc->ad_cname.bv_val, rc );
-               return 0;
-       }
-
-       mr = ava->aa_desc->ad_type->sat_equality;
-       if( !mr ) {
-               return 0;
-       }
-
-       if( !mr->smr_filter ) {
-               return 0;
-       }
-
-       rc = (mr->smr_filter)(
-               LDAP_FILTER_EQUALITY,
-               mask,
-               ava->aa_desc->ad_type->sat_syntax,
-               mr,
-               &prefix,
-               &ava->aa_value,
-               &keys, op->o_tmpmemctx );
-
-       if( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_equality_candidates: (%s, %s) "
-                       "MR filter failed (%d)\n",
-                       prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
-               return 0;
-       }
-
-       if( keys == NULL ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_equality_candidates: (%s) no keys\n",
-                       ava->aa_desc->ad_cname.bv_val );
-               return 0;
-       }
-
-       for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-               rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 );
-
-               if( rc == DB_NOTFOUND ) {
-                       BDB_IDL_ZERO( ids );
-                       rc = 0;
-                       break;
-               } else if( rc != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<= bdb_equality_candidates: (%s) "
-                               "key read failed (%d)\n",
-                               ava->aa_desc->ad_cname.bv_val, rc );
-                       break;
-               }
-
-               if( BDB_IDL_IS_ZERO( tmp ) ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<= bdb_equality_candidates: (%s) NULL\n", 
-                               ava->aa_desc->ad_cname.bv_val );
-                       BDB_IDL_ZERO( ids );
-                       break;
-               }
-
-               if ( i == 0 ) {
-                       BDB_IDL_CPY( ids, tmp );
-               } else {
-                       bdb_idl_intersection( ids, tmp );
-               }
-
-               if( BDB_IDL_IS_ZERO( ids ) )
-                       break;
-       }
-
-       ber_bvarray_free_x( keys, op->o_tmpmemctx );
-
-       Debug( LDAP_DEBUG_TRACE,
-               "<= bdb_equality_candidates: id=%ld, first=%ld, last=%ld\n",
-               (long) ids[0],
-               (long) BDB_IDL_FIRST(ids),
-               (long) BDB_IDL_LAST(ids) );
-       return( rc );
-}
-
-
-static int
-approx_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       AttributeAssertion *ava,
-       ID *ids,
-       ID *tmp )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB      *db;
-       int i;
-       int rc;
-       slap_mask_t mask;
-       struct berval prefix = {0, NULL};
-       struct berval *keys = NULL;
-       MatchingRule *mr;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_approx_candidates (%s)\n",
-                       ava->aa_desc->ad_cname.bv_val );
-
-       BDB_IDL_ALL( bdb, ids );
-
-       rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_APPROX,
-               &db, &mask, &prefix );
-
-       if ( rc == LDAP_INAPPROPRIATE_MATCHING ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_approx_candidates: (%s) not indexed\n",
-                       ava->aa_desc->ad_cname.bv_val );
-               return 0;
-       }
-
-       if( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_approx_candidates: (%s) "
-                       "index_param failed (%d)\n",
-                       ava->aa_desc->ad_cname.bv_val, rc );
-               return 0;
-       }
-
-       mr = ava->aa_desc->ad_type->sat_approx;
-       if( !mr ) {
-               /* no approx matching rule, try equality matching rule */
-               mr = ava->aa_desc->ad_type->sat_equality;
-       }
-
-       if( !mr ) {
-               return 0;
-       }
-
-       if( !mr->smr_filter ) {
-               return 0;
-       }
-
-       rc = (mr->smr_filter)(
-               LDAP_FILTER_APPROX,
-               mask,
-               ava->aa_desc->ad_type->sat_syntax,
-               mr,
-               &prefix,
-               &ava->aa_value,
-               &keys, op->o_tmpmemctx );
-
-       if( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_approx_candidates: (%s, %s) "
-                       "MR filter failed (%d)\n",
-                       prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
-               return 0;
-       }
-
-       if( keys == NULL ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_approx_candidates: (%s) no keys (%s)\n",
-                       prefix.bv_val, ava->aa_desc->ad_cname.bv_val );
-               return 0;
-       }
-
-       for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-               rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 );
-
-               if( rc == DB_NOTFOUND ) {
-                       BDB_IDL_ZERO( ids );
-                       rc = 0;
-                       break;
-               } else if( rc != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<= bdb_approx_candidates: (%s) "
-                               "key read failed (%d)\n",
-                               ava->aa_desc->ad_cname.bv_val, rc );
-                       break;
-               }
-
-               if( BDB_IDL_IS_ZERO( tmp ) ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<= bdb_approx_candidates: (%s) NULL\n",
-                               ava->aa_desc->ad_cname.bv_val );
-                       BDB_IDL_ZERO( ids );
-                       break;
-               }
-
-               if ( i == 0 ) {
-                       BDB_IDL_CPY( ids, tmp );
-               } else {
-                       bdb_idl_intersection( ids, tmp );
-               }
-
-               if( BDB_IDL_IS_ZERO( ids ) )
-                       break;
-       }
-
-       ber_bvarray_free_x( keys, op->o_tmpmemctx );
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb_approx_candidates %ld, first=%ld, last=%ld\n",
-               (long) ids[0],
-               (long) BDB_IDL_FIRST(ids),
-               (long) BDB_IDL_LAST(ids) );
-       return( rc );
-}
-
-static int
-substring_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       SubstringsAssertion     *sub,
-       ID *ids,
-       ID *tmp )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB      *db;
-       int i;
-       int rc;
-       slap_mask_t mask;
-       struct berval prefix = {0, NULL};
-       struct berval *keys = NULL;
-       MatchingRule *mr;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_substring_candidates (%s)\n",
-                       sub->sa_desc->ad_cname.bv_val );
-
-       BDB_IDL_ALL( bdb, ids );
-
-       rc = bdb_index_param( op->o_bd, sub->sa_desc, LDAP_FILTER_SUBSTRINGS,
-               &db, &mask, &prefix );
-
-       if ( rc == LDAP_INAPPROPRIATE_MATCHING ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_substring_candidates: (%s) not indexed\n",
-                       sub->sa_desc->ad_cname.bv_val );
-               return 0;
-       }
-
-       if( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_substring_candidates: (%s) "
-                       "index_param failed (%d)\n",
-                       sub->sa_desc->ad_cname.bv_val, rc );
-               return 0;
-       }
-
-       mr = sub->sa_desc->ad_type->sat_substr;
-
-       if( !mr ) {
-               return 0;
-       }
-
-       if( !mr->smr_filter ) {
-               return 0;
-       }
-
-       rc = (mr->smr_filter)(
-               LDAP_FILTER_SUBSTRINGS,
-               mask,
-               sub->sa_desc->ad_type->sat_syntax,
-               mr,
-               &prefix,
-               sub,
-               &keys, op->o_tmpmemctx );
-
-       if( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_substring_candidates: (%s) "
-                       "MR filter failed (%d)\n",
-                       sub->sa_desc->ad_cname.bv_val, rc );
-               return 0;
-       }
-
-       if( keys == NULL ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_substring_candidates: (0x%04lx) no keys (%s)\n",
-                       mask, sub->sa_desc->ad_cname.bv_val );
-               return 0;
-       }
-
-       for ( i= 0; keys[i].bv_val != NULL; i++ ) {
-               rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 );
-
-               if( rc == DB_NOTFOUND ) {
-                       BDB_IDL_ZERO( ids );
-                       rc = 0;
-                       break;
-               } else if( rc != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<= bdb_substring_candidates: (%s) "
-                               "key read failed (%d)\n",
-                               sub->sa_desc->ad_cname.bv_val, rc );
-                       break;
-               }
-
-               if( BDB_IDL_IS_ZERO( tmp ) ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<= bdb_substring_candidates: (%s) NULL\n",
-                               sub->sa_desc->ad_cname.bv_val );
-                       BDB_IDL_ZERO( ids );
-                       break;
-               }
-
-               if ( i == 0 ) {
-                       BDB_IDL_CPY( ids, tmp );
-               } else {
-                       bdb_idl_intersection( ids, tmp );
-               }
-
-               if( BDB_IDL_IS_ZERO( ids ) )
-                       break;
-       }
-
-       ber_bvarray_free_x( keys, op->o_tmpmemctx );
-
-       Debug( LDAP_DEBUG_TRACE, "<= bdb_substring_candidates: %ld, first=%ld, last=%ld\n",
-               (long) ids[0],
-               (long) BDB_IDL_FIRST(ids),
-               (long) BDB_IDL_LAST(ids) );
-       return( rc );
-}
-
-static int
-inequality_candidates(
-       Operation *op,
-       DB_TXN *rtxn,
-       AttributeAssertion *ava,
-       ID *ids,
-       ID *tmp,
-       int gtorlt )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       DB      *db;
-       int rc;
-       slap_mask_t mask;
-       struct berval prefix = {0, NULL};
-       struct berval *keys = NULL;
-       MatchingRule *mr;
-       DBC * cursor = NULL;
-
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_inequality_candidates (%s)\n",
-                       ava->aa_desc->ad_cname.bv_val );
-
-       BDB_IDL_ALL( bdb, ids );
-
-       rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_EQUALITY,
-               &db, &mask, &prefix );
-
-       if ( rc == LDAP_INAPPROPRIATE_MATCHING ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_inequality_candidates: (%s) not indexed\n", 
-                       ava->aa_desc->ad_cname.bv_val );
-               return 0;
-       }
-
-       if( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_inequality_candidates: (%s) "
-                       "index_param failed (%d)\n",
-                       ava->aa_desc->ad_cname.bv_val, rc );
-               return 0;
-       }
-
-       mr = ava->aa_desc->ad_type->sat_equality;
-       if( !mr ) {
-               return 0;
-       }
-
-       if( !mr->smr_filter ) {
-               return 0;
-       }
-
-       rc = (mr->smr_filter)(
-               LDAP_FILTER_EQUALITY,
-               mask,
-               ava->aa_desc->ad_type->sat_syntax,
-               mr,
-               &prefix,
-               &ava->aa_value,
-               &keys, op->o_tmpmemctx );
-
-       if( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_inequality_candidates: (%s, %s) "
-                       "MR filter failed (%d)\n",
-                       prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
-               return 0;
-       }
-
-       if( keys == NULL ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_inequality_candidates: (%s) no keys\n",
-                       ava->aa_desc->ad_cname.bv_val );
-               return 0;
-       }
-
-       BDB_IDL_ZERO( ids );
-       while(1) {
-               rc = bdb_key_read( op->o_bd, db, rtxn, &keys[0], tmp, &cursor, gtorlt );
-
-               if( rc == DB_NOTFOUND ) {
-                       rc = 0;
-                       break;
-               } else if( rc != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                              "<= bdb_inequality_candidates: (%s) "
-                              "key read failed (%d)\n",
-                              ava->aa_desc->ad_cname.bv_val, rc );
-                       break;
-               }
-
-               if( BDB_IDL_IS_ZERO( tmp ) ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                              "<= bdb_inequality_candidates: (%s) NULL\n", 
-                              ava->aa_desc->ad_cname.bv_val );
-                       break;
-               }
-
-               bdb_idl_union( ids, tmp );
-
-               if( op->ors_limit && op->ors_limit->lms_s_unchecked != -1 &&
-                       BDB_IDL_N( ids ) >= (unsigned) op->ors_limit->lms_s_unchecked ) {
-                       cursor->c_close( cursor );
-                       break;
-               }
-       }
-       ber_bvarray_free_x( keys, op->o_tmpmemctx );
-
-       Debug( LDAP_DEBUG_TRACE,
-               "<= bdb_inequality_candidates: id=%ld, first=%ld, last=%ld\n",
-               (long) ids[0],
-               (long) BDB_IDL_FIRST(ids),
-               (long) BDB_IDL_LAST(ids) );
-       return( rc );
-}
diff --git a/servers/slapd/back-bdb/id2entry.c b/servers/slapd/back-bdb/id2entry.c
deleted file mode 100644 (file)
index 810f85f..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-/* id2entry.c - routines to deal with the id2entry database */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-#include <ac/errno.h>
-
-#include "back-bdb.h"
-
-static int bdb_id2entry_put(
-       BackendDB *be,
-       DB_TXN *tid,
-       Entry *e,
-       int flag )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       DB *db = bdb->bi_id2entry->bdi_db;
-       DBT key, data;
-       struct berval bv;
-       int rc;
-       ID nid;
-#ifdef BDB_HIER
-       struct berval odn, ondn;
-
-       /* We only store rdns, and they go in the dn2id database. */
-
-       odn = e->e_name; ondn = e->e_nname;
-
-       e->e_name = slap_empty_bv;
-       e->e_nname = slap_empty_bv;
-#endif
-       DBTzero( &key );
-
-       /* Store ID in BigEndian format */
-       key.data = &nid;
-       key.size = sizeof(ID);
-       BDB_ID2DISK( e->e_id, &nid );
-
-       rc = entry_encode( e, &bv );
-#ifdef BDB_HIER
-       e->e_name = odn; e->e_nname = ondn;
-#endif
-       if( rc != LDAP_SUCCESS ) {
-               return -1;
-       }
-
-       DBTzero( &data );
-       bv2DBT( &bv, &data );
-
-       rc = db->put( db, tid, &key, &data, flag );
-
-       free( bv.bv_val );
-       return rc;
-}
-
-/*
- * This routine adds (or updates) an entry on disk.
- * The cache should be already be updated.
- */
-
-
-int bdb_id2entry_add(
-       BackendDB *be,
-       DB_TXN *tid,
-       Entry *e )
-{
-       return bdb_id2entry_put(be, tid, e, DB_NOOVERWRITE);
-}
-
-int bdb_id2entry_update(
-       BackendDB *be,
-       DB_TXN *tid,
-       Entry *e )
-{
-       return bdb_id2entry_put(be, tid, e, 0);
-}
-
-int bdb_id2entry(
-       BackendDB *be,
-       DB_TXN *tid,
-       ID id,
-       Entry **e )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       DB *db = bdb->bi_id2entry->bdi_db;
-       DBT key, data;
-       DBC *cursor;
-       EntryHeader eh;
-       char buf[16];
-       int rc = 0, off;
-       ID nid;
-
-       *e = NULL;
-
-       DBTzero( &key );
-       key.data = &nid;
-       key.size = sizeof(ID);
-       BDB_ID2DISK( id, &nid );
-
-       DBTzero( &data );
-       data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
-
-       /* fetch it */
-       rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
-       if ( rc ) return rc;
-
-       /* Get the nattrs / nvals counts first */
-       data.ulen = data.dlen = sizeof(buf);
-       data.data = buf;
-       rc = cursor->c_get( cursor, &key, &data, DB_SET );
-       if ( rc ) goto finish;
-
-
-       eh.bv.bv_val = buf;
-       eh.bv.bv_len = data.size;
-       rc = entry_header( &eh );
-       if ( rc ) goto finish;
-
-       if ( eh.nvals ) {
-               /* Get the size */
-               data.flags ^= DB_DBT_PARTIAL;
-               data.ulen = 0;
-               rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
-               if ( rc != DB_BUFFER_SMALL ) goto finish;
-
-               /* Allocate a block and retrieve the data */
-               off = eh.data - eh.bv.bv_val;
-               eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size;
-               eh.bv.bv_val = ch_malloc( eh.bv.bv_len );
-               eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval );
-               data.data = eh.data;
-               data.ulen = data.size;
-
-               /* skip past already parsed nattr/nvals */
-               eh.data += off;
-
-               rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
-       }
-
-finish:
-       cursor->c_close( cursor );
-
-       if( rc != 0 ) {
-               return rc;
-       }
-
-       if ( eh.nvals ) {
-#ifdef SLAP_ZONE_ALLOC
-               rc = entry_decode(&eh, e, bdb->bi_cache.c_zctx);
-#else
-               rc = entry_decode(&eh, e);
-#endif
-       } else {
-               *e = entry_alloc();
-       }
-
-       if( rc == 0 ) {
-               (*e)->e_id = id;
-       } else {
-               /* only free on error. On success, the entry was
-                * decoded in place.
-                */
-#ifndef SLAP_ZONE_ALLOC
-               ch_free(eh.bv.bv_val);
-#endif
-       }
-#ifdef SLAP_ZONE_ALLOC
-       ch_free(eh.bv.bv_val);
-#endif
-
-       return rc;
-}
-
-int bdb_id2entry_delete(
-       BackendDB *be,
-       DB_TXN *tid,
-       Entry *e )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       DB *db = bdb->bi_id2entry->bdi_db;
-       DBT key;
-       int rc;
-       ID nid;
-
-       DBTzero( &key );
-       key.data = &nid;
-       key.size = sizeof(ID);
-       BDB_ID2DISK( e->e_id, &nid );
-
-       /* delete from database */
-       rc = db->del( db, tid, &key, 0 );
-
-       return rc;
-}
-
-int bdb_entry_return(
-       Entry *e
-)
-{
-       /* Our entries are allocated in two blocks; the data comes from
-        * the db itself and the Entry structure and associated pointers
-        * are allocated in entry_decode. The db data pointer is saved
-        * in e_bv.
-        */
-       if ( e->e_bv.bv_val ) {
-               /* See if the DNs were changed by modrdn */
-               if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val >
-                       e->e_bv.bv_val + e->e_bv.bv_len ) {
-                       ch_free(e->e_name.bv_val);
-                       ch_free(e->e_nname.bv_val);
-               }
-               e->e_name.bv_val = NULL;
-               e->e_nname.bv_val = NULL;
-               /* In tool mode the e_bv buffer is realloc'd, leave it alone */
-               if( !(slapMode & SLAP_TOOL_MODE) ) {
-                       free( e->e_bv.bv_val );
-               }
-               BER_BVZERO( &e->e_bv );
-       }
-       entry_free( e );
-       return 0;
-}
-
-int bdb_entry_release(
-       Operation *op,
-       Entry *e,
-       int rw )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       struct bdb_op_info *boi;
-       OpExtra *oex;
-       /* slapMode : SLAP_SERVER_MODE, SLAP_TOOL_MODE,
-                       SLAP_TRUNCATE_MODE, SLAP_UNDEFINED_MODE */
-       if ( slapMode & SLAP_SERVER_MODE ) {
-               /* If not in our cache, just free it */
-               if ( !e->e_private ) {
-#ifdef SLAP_ZONE_ALLOC
-                       return bdb_entry_return( bdb, e, -1 );
-#else
-                       return bdb_entry_return( e );
-#endif
-               }
-               /* free entry and reader or writer lock */
-               LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
-                       if ( oex->oe_key == bdb ) break;
-               }
-               boi = (struct bdb_op_info *)oex;
-
-               /* lock is freed with txn */
-               if ( !boi || boi->boi_txn ) {
-                       bdb_unlocked_cache_return_entry_rw( bdb, e, rw );
-               } else {
-                       struct bdb_lock_info *bli, *prev;
-                       for ( prev=(struct bdb_lock_info *)&boi->boi_locks,
-                               bli = boi->boi_locks; bli; prev=bli, bli=bli->bli_next ) {
-                               if ( bli->bli_id == e->e_id ) {
-                                       bdb_cache_return_entry_rw( bdb, e, rw, &bli->bli_lock );
-                                       prev->bli_next = bli->bli_next;
-                                       /* Cleanup, or let caller know we unlocked */
-                                       if ( bli->bli_flag & BLI_DONTFREE )
-                                               bli->bli_flag = 0;
-                                       else
-                                               op->o_tmpfree( bli, op->o_tmpmemctx );
-                                       break;
-                               }
-                       }
-                       if ( !boi->boi_locks ) {
-                               LDAP_SLIST_REMOVE( &op->o_extra, &boi->boi_oe, OpExtra, oe_next );
-                               if ( !(boi->boi_flag & BOI_DONTFREE))
-                                       op->o_tmpfree( boi, op->o_tmpmemctx );
-                       }
-               }
-       } else {
-#ifdef SLAP_ZONE_ALLOC
-               int zseq = -1;
-               if (e->e_private != NULL) {
-                       BEI(e)->bei_e = NULL;
-                       zseq = BEI(e)->bei_zseq;
-               }
-#else
-               if (e->e_private != NULL)
-                       BEI(e)->bei_e = NULL;
-#endif
-               e->e_private = NULL;
-#ifdef SLAP_ZONE_ALLOC
-               bdb_entry_return ( bdb, e, zseq );
-#else
-               bdb_entry_return ( e );
-#endif
-       }
-       return 0;
-}
-
-/* return LDAP_SUCCESS IFF we can retrieve the specified entry.
- */
-int bdb_entry_get(
-       Operation *op,
-       struct berval *ndn,
-       ObjectClass *oc,
-       AttributeDescription *at,
-       int rw,
-       Entry **ent )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       struct bdb_op_info *boi = NULL;
-       DB_TXN *txn = NULL;
-       Entry *e = NULL;
-       EntryInfo *ei;
-       int     rc;
-       const char *at_name = at ? at->ad_cname.bv_val : "(null)";
-
-       DB_LOCK         lock;
-
-       Debug( LDAP_DEBUG_ARGS,
-               "=> bdb_entry_get: ndn: \"%s\"\n", ndn->bv_val );
-       Debug( LDAP_DEBUG_ARGS,
-               "=> bdb_entry_get: oc: \"%s\", at: \"%s\"\n",
-               oc ? oc->soc_cname.bv_val : "(null)", at_name );
-
-       if( op ) {
-               OpExtra *oex;
-               LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
-                       if ( oex->oe_key == bdb ) break;
-               }
-               boi = (struct bdb_op_info *)oex;
-               if ( boi )
-                       txn = boi->boi_txn;
-       }
-
-       if ( !txn ) {
-               rc = bdb_reader_get( op, bdb->bi_dbenv, &txn );
-               switch(rc) {
-               case 0:
-                       break;
-               default:
-                       return LDAP_OTHER;
-               }
-       }
-
-dn2entry_retry:
-       /* can we find entry */
-       rc = bdb_dn2entry( op, txn, ndn, &ei, 0, &lock );
-       switch( rc ) {
-       case DB_NOTFOUND:
-       case 0:
-               break;
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               /* the txn must abort and retry */
-               if ( txn ) {
-                       if ( boi ) boi->boi_err = rc;
-                       return LDAP_BUSY;
-               }
-               ldap_pvt_thread_yield();
-               goto dn2entry_retry;
-       default:
-               if ( boi ) boi->boi_err = rc;
-               return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY;
-       }
-       if (ei) e = ei->bei_e;
-       if (e == NULL) {
-               Debug( LDAP_DEBUG_ACL,
-                       "=> bdb_entry_get: cannot find entry: \"%s\"\n",
-                               ndn->bv_val );
-               return LDAP_NO_SUCH_OBJECT; 
-       }
-       
-       Debug( LDAP_DEBUG_ACL,
-               "=> bdb_entry_get: found entry: \"%s\"\n",
-               ndn->bv_val );
-
-       if ( oc && !is_entry_objectclass( e, oc, 0 )) {
-               Debug( LDAP_DEBUG_ACL,
-                       "<= bdb_entry_get: failed to find objectClass %s\n",
-                       oc->soc_cname.bv_val );
-               rc = LDAP_NO_SUCH_ATTRIBUTE;
-               goto return_results;
-       }
-
-       /* NOTE: attr_find() or attrs_find()? */
-       if ( at && attr_find( e->e_attrs, at ) == NULL ) {
-               Debug( LDAP_DEBUG_ACL,
-                       "<= bdb_entry_get: failed to find attribute %s\n",
-                       at->ad_cname.bv_val );
-               rc = LDAP_NO_SUCH_ATTRIBUTE;
-               goto return_results;
-       }
-
-return_results:
-       if( rc != LDAP_SUCCESS ) {
-               /* free entry */
-               bdb_cache_return_entry_rw(bdb, e, rw, &lock);
-
-       } else {
-               if ( slapMode & SLAP_SERVER_MODE ) {
-                       *ent = e;
-                       /* big drag. we need a place to store a read lock so we can
-                        * release it later?? If we're in a txn, nothing is needed
-                        * here because the locks will go away with the txn.
-                        */
-                       if ( op ) {
-                               if ( !boi ) {
-                                       boi = op->o_tmpcalloc(1,sizeof(struct bdb_op_info),op->o_tmpmemctx);
-                                       boi->boi_oe.oe_key = bdb;
-                                       LDAP_SLIST_INSERT_HEAD( &op->o_extra, &boi->boi_oe, oe_next );
-                               }
-                               if ( !boi->boi_txn ) {
-                                       struct bdb_lock_info *bli;
-                                       bli = op->o_tmpalloc( sizeof(struct bdb_lock_info),
-                                               op->o_tmpmemctx );
-                                       bli->bli_next = boi->boi_locks;
-                                       bli->bli_id = e->e_id;
-                                       bli->bli_flag = 0;
-                                       bli->bli_lock = lock;
-                                       boi->boi_locks = bli;
-                               }
-                       }
-               } else {
-                       *ent = entry_dup( e );
-                       bdb_cache_return_entry_rw(bdb, e, rw, &lock);
-               }
-       }
-
-       Debug( LDAP_DEBUG_TRACE,
-               "bdb_entry_get: rc=%d\n",
-               rc );
-       return(rc);
-}
diff --git a/servers/slapd/back-bdb/idl.c b/servers/slapd/back-bdb/idl.c
deleted file mode 100644 (file)
index b818b66..0000000
+++ /dev/null
@@ -1,1567 +0,0 @@
-/* idl.c - ldap id list handling routines */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-#include "idl.h"
-
-#define IDL_MAX(x,y)   ( (x) > (y) ? (x) : (y) )
-#define IDL_MIN(x,y)   ( (x) < (y) ? (x) : (y) )
-#define IDL_CMP(x,y)   ( (x) < (y) ? -1 : (x) > (y) )
-
-#define IDL_LRU_DELETE( bdb, e ) do { \
-       if ( (e) == (bdb)->bi_idl_lru_head ) { \
-               if ( (e)->idl_lru_next == (bdb)->bi_idl_lru_head ) { \
-                       (bdb)->bi_idl_lru_head = NULL; \
-               } else { \
-                       (bdb)->bi_idl_lru_head = (e)->idl_lru_next; \
-               } \
-       } \
-       if ( (e) == (bdb)->bi_idl_lru_tail ) { \
-               if ( (e)->idl_lru_prev == (bdb)->bi_idl_lru_tail ) { \
-                       assert( (bdb)->bi_idl_lru_head == NULL ); \
-                       (bdb)->bi_idl_lru_tail = NULL; \
-               } else { \
-                       (bdb)->bi_idl_lru_tail = (e)->idl_lru_prev; \
-               } \
-       } \
-       (e)->idl_lru_next->idl_lru_prev = (e)->idl_lru_prev; \
-       (e)->idl_lru_prev->idl_lru_next = (e)->idl_lru_next; \
-} while ( 0 )
-
-static int
-bdb_idl_entry_cmp( const void *v_idl1, const void *v_idl2 )
-{
-       const bdb_idl_cache_entry_t *idl1 = v_idl1, *idl2 = v_idl2;
-       int rc;
-
-       if ((rc = SLAP_PTRCMP( idl1->db, idl2->db ))) return rc;
-       if ((rc = idl1->kstr.bv_len - idl2->kstr.bv_len )) return rc;
-       return ( memcmp ( idl1->kstr.bv_val, idl2->kstr.bv_val , idl1->kstr.bv_len ) );
-}
-
-#if IDL_DEBUG > 0
-static void idl_check( ID *ids )
-{
-       if( BDB_IDL_IS_RANGE( ids ) ) {
-               assert( BDB_IDL_RANGE_FIRST(ids) <= BDB_IDL_RANGE_LAST(ids) );
-       } else {
-               ID i;
-               for( i=1; i < ids[0]; i++ ) {
-                       assert( ids[i+1] > ids[i] );
-               }
-       }
-}
-
-#if IDL_DEBUG > 1
-static void idl_dump( ID *ids )
-{
-       if( BDB_IDL_IS_RANGE( ids ) ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "IDL: range ( %ld - %ld )\n",
-                       (long) BDB_IDL_RANGE_FIRST( ids ),
-                       (long) BDB_IDL_RANGE_LAST( ids ) );
-
-       } else {
-               ID i;
-               Debug( LDAP_DEBUG_ANY, "IDL: size %ld", (long) ids[0] );
-
-               for( i=1; i<=ids[0]; i++ ) {
-                       if( i % 16 == 1 ) {
-                               Debug( LDAP_DEBUG_ANY, "\n" );
-                       }
-                       Debug( LDAP_DEBUG_ANY, "  %02lx", (long) ids[i] );
-               }
-
-               Debug( LDAP_DEBUG_ANY, "\n" );
-       }
-
-       idl_check( ids );
-}
-#endif /* IDL_DEBUG > 1 */
-#endif /* IDL_DEBUG > 0 */
-
-unsigned bdb_idl_search( ID *ids, ID id )
-{
-#define IDL_BINARY_SEARCH 1
-#ifdef IDL_BINARY_SEARCH
-       /*
-        * binary search of id in ids
-        * if found, returns position of id
-        * if not found, returns first postion greater than id
-        */
-       unsigned base = 0;
-       unsigned cursor = 1;
-       int val = 0;
-       unsigned n = ids[0];
-
-#if IDL_DEBUG > 0
-       idl_check( ids );
-#endif
-
-       while( 0 < n ) {
-               unsigned pivot = n >> 1;
-               cursor = base + pivot + 1;
-               val = IDL_CMP( id, ids[cursor] );
-
-               if( val < 0 ) {
-                       n = pivot;
-
-               } else if ( val > 0 ) {
-                       base = cursor;
-                       n -= pivot + 1;
-
-               } else {
-                       return cursor;
-               }
-       }
-       
-       if( val > 0 ) {
-               ++cursor;
-       }
-       return cursor;
-
-#else
-       /* (reverse) linear search */
-       int i;
-
-#if IDL_DEBUG > 0
-       idl_check( ids );
-#endif
-
-       for( i=ids[0]; i; i-- ) {
-               if( id > ids[i] ) {
-                       break;
-               }
-       }
-
-       return i+1;
-#endif
-}
-
-int bdb_idl_insert( ID *ids, ID id )
-{
-       unsigned x;
-
-#if IDL_DEBUG > 1
-       Debug( LDAP_DEBUG_ANY, "insert: %04lx at %d\n", (long) id, x );
-       idl_dump( ids );
-#elif IDL_DEBUG > 0
-       idl_check( ids );
-#endif
-
-       if (BDB_IDL_IS_RANGE( ids )) {
-               /* if already in range, treat as a dup */
-               if (id >= BDB_IDL_RANGE_FIRST(ids) && id <= BDB_IDL_RANGE_LAST(ids))
-                       return -1;
-               if (id < BDB_IDL_RANGE_FIRST(ids))
-                       ids[1] = id;
-               else if (id > BDB_IDL_RANGE_LAST(ids))
-                       ids[2] = id;
-               return 0;
-       }
-
-       x = bdb_idl_search( ids, id );
-       assert( x > 0 );
-
-       if( x < 1 ) {
-               /* internal error */
-               return -2;
-       }
-
-       if ( x <= ids[0] && ids[x] == id ) {
-               /* duplicate */
-               return -1;
-       }
-
-       if ( ++ids[0] >= BDB_IDL_DB_MAX ) {
-               if( id < ids[1] ) {
-                       ids[1] = id;
-                       ids[2] = ids[ids[0]-1];
-               } else if ( ids[ids[0]-1] < id ) {
-                       ids[2] = id;
-               } else {
-                       ids[2] = ids[ids[0]-1];
-               }
-               ids[0] = NOID;
-       
-       } else {
-               /* insert id */
-               AC_MEMCPY( &ids[x+1], &ids[x], (ids[0]-x) * sizeof(ID) );
-               ids[x] = id;
-       }
-
-#if IDL_DEBUG > 1
-       idl_dump( ids );
-#elif IDL_DEBUG > 0
-       idl_check( ids );
-#endif
-
-       return 0;
-}
-
-int bdb_idl_delete( ID *ids, ID id )
-{
-       unsigned x;
-
-#if IDL_DEBUG > 1
-       Debug( LDAP_DEBUG_ANY, "delete: %04lx at %d\n", (long) id, x );
-       idl_dump( ids );
-#elif IDL_DEBUG > 0
-       idl_check( ids );
-#endif
-
-       if (BDB_IDL_IS_RANGE( ids )) {
-               /* If deleting a range boundary, adjust */
-               if ( ids[1] == id )
-                       ids[1]++;
-               else if ( ids[2] == id )
-                       ids[2]--;
-               /* deleting from inside a range is a no-op */
-
-               /* If the range has collapsed, re-adjust */
-               if ( ids[1] > ids[2] )
-                       ids[0] = 0;
-               else if ( ids[1] == ids[2] )
-                       ids[1] = 1;
-               return 0;
-       }
-
-       x = bdb_idl_search( ids, id );
-       assert( x > 0 );
-
-       if( x <= 0 ) {
-               /* internal error */
-               return -2;
-       }
-
-       if( x > ids[0] || ids[x] != id ) {
-               /* not found */
-               return -1;
-
-       } else if ( --ids[0] == 0 ) {
-               if( x != 1 ) {
-                       return -3;
-               }
-
-       } else {
-               AC_MEMCPY( &ids[x], &ids[x+1], (1+ids[0]-x) * sizeof(ID) );
-       }
-
-#if IDL_DEBUG > 1
-       idl_dump( ids );
-#elif IDL_DEBUG > 0
-       idl_check( ids );
-#endif
-
-       return 0;
-}
-
-static char *
-bdb_show_key(
-       DBT             *key,
-       char            *buf )
-{
-       if ( key->size == 4 /* LUTIL_HASH_BYTES */ ) {
-               unsigned char *c = key->data;
-               sprintf( buf, "[%02x%02x%02x%02x]", c[0], c[1], c[2], c[3] );
-               return buf;
-       } else {
-               return key->data;
-       }
-}
-
-/* Find a db/key pair in the IDL cache. If ids is non-NULL,
- * copy the cached IDL into it, otherwise just return the status.
- */
-int
-bdb_idl_cache_get(
-       struct bdb_info *bdb,
-       DB                      *db,
-       DBT                     *key,
-       ID                      *ids )
-{
-       bdb_idl_cache_entry_t idl_tmp;
-       bdb_idl_cache_entry_t *matched_idl_entry;
-       int rc = LDAP_NO_SUCH_OBJECT;
-
-       DBT2bv( key, &idl_tmp.kstr );
-       idl_tmp.db = db;
-       ldap_pvt_thread_rdwr_rlock( &bdb->bi_idl_tree_rwlock );
-       matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
-                                     bdb_idl_entry_cmp );
-       if ( matched_idl_entry != NULL ) {
-               if ( matched_idl_entry->idl && ids )
-                       BDB_IDL_CPY( ids, matched_idl_entry->idl );
-               matched_idl_entry->idl_flags |= CACHE_ENTRY_REFERENCED;
-               if ( matched_idl_entry->idl )
-                       rc = LDAP_SUCCESS;
-               else
-                       rc = DB_NOTFOUND;
-       }
-       ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
-
-       return rc;
-}
-
-void
-bdb_idl_cache_put(
-       struct bdb_info *bdb,
-       DB                      *db,
-       DBT                     *key,
-       ID                      *ids,
-       int                     rc )
-{
-       bdb_idl_cache_entry_t idl_tmp;
-       bdb_idl_cache_entry_t *ee, *eprev;
-
-       if ( rc == DB_NOTFOUND || BDB_IDL_IS_ZERO( ids ))
-               return;
-
-       DBT2bv( key, &idl_tmp.kstr );
-
-       ee = (bdb_idl_cache_entry_t *) ch_malloc(
-               sizeof( bdb_idl_cache_entry_t ) );
-       ee->db = db;
-       ee->idl = (ID*) ch_malloc( BDB_IDL_SIZEOF ( ids ) );
-       BDB_IDL_CPY( ee->idl, ids );
-
-       ee->idl_lru_prev = NULL;
-       ee->idl_lru_next = NULL;
-       ee->idl_flags = 0;
-       ber_dupbv( &ee->kstr, &idl_tmp.kstr );
-       ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
-       if ( avl_insert( &bdb->bi_idl_tree, (caddr_t) ee,
-               bdb_idl_entry_cmp, avl_dup_error ))
-       {
-               ch_free( ee->kstr.bv_val );
-               ch_free( ee->idl );
-               ch_free( ee );
-               ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
-               return;
-       }
-       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-       /* LRU_ADD */
-       if ( bdb->bi_idl_lru_head ) {
-               assert( bdb->bi_idl_lru_tail != NULL );
-               assert( bdb->bi_idl_lru_head->idl_lru_prev != NULL );
-               assert( bdb->bi_idl_lru_head->idl_lru_next != NULL );
-
-               ee->idl_lru_next = bdb->bi_idl_lru_head;
-               ee->idl_lru_prev = bdb->bi_idl_lru_head->idl_lru_prev;
-               bdb->bi_idl_lru_head->idl_lru_prev->idl_lru_next = ee;
-               bdb->bi_idl_lru_head->idl_lru_prev = ee;
-       } else {
-               ee->idl_lru_next = ee->idl_lru_prev = ee;
-               bdb->bi_idl_lru_tail = ee;
-       }
-       bdb->bi_idl_lru_head = ee;
-
-       if ( bdb->bi_idl_cache_size >= bdb->bi_idl_cache_max_size ) {
-               int i;
-               eprev = bdb->bi_idl_lru_tail;
-               for ( i = 0; (ee = eprev) != NULL && i < 10; i++ ) {
-                       eprev = ee->idl_lru_prev;
-                       if ( eprev == ee ) {
-                               eprev = NULL;
-                       }
-                       if ( ee->idl_flags & CACHE_ENTRY_REFERENCED ) {
-                               ee->idl_flags ^= CACHE_ENTRY_REFERENCED;
-                               continue;
-                       }
-                       if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) ee,
-                                   bdb_idl_entry_cmp ) == NULL ) {
-                               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_put: "
-                                       "AVL delete failed\n" );
-                       }
-                       IDL_LRU_DELETE( bdb, ee );
-                       i++;
-                       --bdb->bi_idl_cache_size;
-                       ch_free( ee->kstr.bv_val );
-                       ch_free( ee->idl );
-                       ch_free( ee );
-               }
-               bdb->bi_idl_lru_tail = eprev;
-               assert( bdb->bi_idl_lru_tail != NULL
-                       || bdb->bi_idl_lru_head == NULL );
-       }
-       bdb->bi_idl_cache_size++;
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
-       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
-}
-
-void
-bdb_idl_cache_del(
-       struct bdb_info *bdb,
-       DB                      *db,
-       DBT                     *key )
-{
-       bdb_idl_cache_entry_t *matched_idl_entry, idl_tmp;
-       DBT2bv( key, &idl_tmp.kstr );
-       idl_tmp.db = db;
-       ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
-       matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
-                                     bdb_idl_entry_cmp );
-       if ( matched_idl_entry != NULL ) {
-               if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry,
-                                   bdb_idl_entry_cmp ) == NULL ) {
-                       Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_del: "
-                               "AVL delete failed\n" );
-               }
-               --bdb->bi_idl_cache_size;
-               ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-               IDL_LRU_DELETE( bdb, matched_idl_entry );
-               ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
-               free( matched_idl_entry->kstr.bv_val );
-               if ( matched_idl_entry->idl )
-                       free( matched_idl_entry->idl );
-               free( matched_idl_entry );
-       }
-       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
-}
-
-void
-bdb_idl_cache_add_id(
-       struct bdb_info *bdb,
-       DB                      *db,
-       DBT                     *key,
-       ID                      id )
-{
-       bdb_idl_cache_entry_t *cache_entry, idl_tmp;
-       DBT2bv( key, &idl_tmp.kstr );
-       idl_tmp.db = db;
-       ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
-       cache_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
-                                     bdb_idl_entry_cmp );
-       if ( cache_entry != NULL ) {
-               if ( !BDB_IDL_IS_RANGE( cache_entry->idl ) &&
-                       cache_entry->idl[0] < BDB_IDL_DB_MAX ) {
-                       size_t s = BDB_IDL_SIZEOF( cache_entry->idl ) + sizeof(ID);
-                       cache_entry->idl = ch_realloc( cache_entry->idl, s );
-               }
-               bdb_idl_insert( cache_entry->idl, id );
-       }
-       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
-}
-
-void
-bdb_idl_cache_del_id(
-       struct bdb_info *bdb,
-       DB                      *db,
-       DBT                     *key,
-       ID                      id )
-{
-       bdb_idl_cache_entry_t *cache_entry, idl_tmp;
-       DBT2bv( key, &idl_tmp.kstr );
-       idl_tmp.db = db;
-       ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
-       cache_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
-                                     bdb_idl_entry_cmp );
-       if ( cache_entry != NULL ) {
-               bdb_idl_delete( cache_entry->idl, id );
-               if ( cache_entry->idl[0] == 0 ) {
-                       if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) cache_entry,
-                                               bdb_idl_entry_cmp ) == NULL ) {
-                               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_del: "
-                                       "AVL delete failed\n" );
-                       }
-                       --bdb->bi_idl_cache_size;
-                       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-                       IDL_LRU_DELETE( bdb, cache_entry );
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
-                       free( cache_entry->kstr.bv_val );
-                       free( cache_entry->idl );
-                       free( cache_entry );
-               }
-       }
-       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
-}
-
-int
-bdb_idl_fetch_key(
-       BackendDB       *be,
-       DB                      *db,
-       DB_TXN          *txn,
-       DBT                     *key,
-       ID                      *ids,
-       DBC                     **saved_cursor,
-       int                     get_flag )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       int rc;
-       DBT data, key2, *kptr;
-       DBC *cursor;
-       ID *i;
-       void *ptr;
-       size_t len;
-       int rc2;
-       int flags = bdb->bi_db_opflags | DB_MULTIPLE;
-       int opflag;
-
-       /* If using BerkeleyDB 4.0, the buf must be large enough to
-        * grab the entire IDL in one get(), otherwise BDB will leak
-        * resources on subsequent get's.  We can safely call get()
-        * twice - once for the data, and once to get the DB_NOTFOUND
-        * result meaning there's no more data. See ITS#2040 for details.
-        * This bug is fixed in BDB 4.1 so a smaller buffer will work if
-        * stack space is too limited.
-        *
-        * configure now requires Berkeley DB 4.1.
-        */
-#if DB_VERSION_FULL < 0x04010000
-#      define BDB_ENOUGH 5
-#else
-       /* We sometimes test with tiny IDLs, and BDB always wants buffers
-        * that are at least one page in size.
-        */
-# if BDB_IDL_DB_SIZE < 4096
-#   define BDB_ENOUGH 2048
-# else
-#      define BDB_ENOUGH 1
-# endif
-#endif
-       ID buf[BDB_IDL_DB_SIZE*BDB_ENOUGH];
-
-       char keybuf[16];
-
-       Debug( LDAP_DEBUG_ARGS,
-               "bdb_idl_fetch_key: %s\n", 
-               bdb_show_key( key, keybuf ) );
-
-       assert( ids != NULL );
-
-       if ( saved_cursor && *saved_cursor ) {
-               opflag = DB_NEXT;
-       } else if ( get_flag == LDAP_FILTER_GE ) {
-               opflag = DB_SET_RANGE;
-       } else if ( get_flag == LDAP_FILTER_LE ) {
-               opflag = DB_FIRST;
-       } else {
-               opflag = DB_SET;
-       }
-
-       /* only non-range lookups can use the IDL cache */
-       if ( bdb->bi_idl_cache_size && opflag == DB_SET ) {
-               rc = bdb_idl_cache_get( bdb, db, key, ids );
-               if ( rc != LDAP_NO_SUCH_OBJECT ) return rc;
-       }
-
-       DBTzero( &data );
-
-       data.data = buf;
-       data.ulen = sizeof(buf);
-       data.flags = DB_DBT_USERMEM;
-
-       /* If we're not reusing an existing cursor, get a new one */
-       if( opflag != DB_NEXT ) {
-               rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "
-                               "cursor failed: %s (%d)\n", db_strerror(rc), rc );
-                       return rc;
-               }
-       } else {
-               cursor = *saved_cursor;
-       }
-       
-       /* If this is a LE lookup, save original key so we can determine
-        * when to stop. If this is a GE lookup, save the key since it
-        * will be overwritten.
-        */
-       if ( get_flag == LDAP_FILTER_LE || get_flag == LDAP_FILTER_GE ) {
-               DBTzero( &key2 );
-               key2.flags = DB_DBT_USERMEM;
-               key2.ulen = sizeof(keybuf);
-               key2.data = keybuf;
-               key2.size = key->size;
-               AC_MEMCPY( keybuf, key->data, key->size );
-               kptr = &key2;
-       } else {
-               kptr = key;
-       }
-       len = key->size;
-       rc = cursor->c_get( cursor, kptr, &data, flags | opflag );
-
-       /* skip presence key on range inequality lookups */
-       while (rc == 0 && kptr->size != len) {
-               rc = cursor->c_get( cursor, kptr, &data, flags | DB_NEXT_NODUP );
-       }
-       /* If we're doing a LE compare and the new key is greater than
-        * our search key, we're done
-        */
-       if (rc == 0 && get_flag == LDAP_FILTER_LE && memcmp( kptr->data,
-               key->data, key->size ) > 0 ) {
-               rc = DB_NOTFOUND;
-       }
-       if (rc == 0) {
-               i = ids;
-               while (rc == 0) {
-                       u_int8_t *j;
-
-                       DB_MULTIPLE_INIT( ptr, &data );
-                       while (ptr) {
-                               DB_MULTIPLE_NEXT(ptr, &data, j, len);
-                               if (j) {
-                                       ++i;
-                                       BDB_DISK2ID( j, i );
-                               }
-                       }
-                       rc = cursor->c_get( cursor, key, &data, flags | DB_NEXT_DUP );
-               }
-               if ( rc == DB_NOTFOUND ) rc = 0;
-               ids[0] = i - ids;
-               /* On disk, a range is denoted by 0 in the first element */
-               if (ids[1] == 0) {
-                       if (ids[0] != BDB_IDL_RANGE_SIZE) {
-                               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "
-                                       "range size mismatch: expected %d, got %ld\n",
-                                       BDB_IDL_RANGE_SIZE, ids[0] );
-                               cursor->c_close( cursor );
-                               return -1;
-                       }
-                       BDB_IDL_RANGE( ids, ids[2], ids[3] );
-               }
-               data.size = BDB_IDL_SIZEOF(ids);
-       }
-
-       if ( saved_cursor && rc == 0 ) {
-               if ( !*saved_cursor )
-                       *saved_cursor = cursor;
-               rc2 = 0;
-       }
-       else
-               rc2 = cursor->c_close( cursor );
-       if (rc2) {
-               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "
-                       "close failed: %s (%d)\n", db_strerror(rc2), rc2 );
-               return rc2;
-       }
-
-       if( rc == DB_NOTFOUND ) {
-               return rc;
-
-       } else if( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "
-                       "get failed: %s (%d)\n",
-                       db_strerror(rc), rc );
-               return rc;
-
-       } else if ( data.size == 0 || data.size % sizeof( ID ) ) {
-               /* size not multiple of ID size */
-               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "
-                       "odd size: expected %ld multiple, got %ld\n",
-                       (long) sizeof( ID ), (long) data.size );
-               return -1;
-
-       } else if ( data.size != BDB_IDL_SIZEOF(ids) ) {
-               /* size mismatch */
-               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "
-                       "get size mismatch: expected %ld, got %ld\n",
-                       (long) ((1 + ids[0]) * sizeof( ID )), (long) data.size );
-               return -1;
-       }
-
-       if ( bdb->bi_idl_cache_max_size ) {
-               bdb_idl_cache_put( bdb, db, key, ids, rc );
-       }
-
-       return rc;
-}
-
-
-int
-bdb_idl_insert_key(
-       BackendDB       *be,
-       DB                      *db,
-       DB_TXN          *tid,
-       DBT                     *key,
-       ID                      id )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       int     rc;
-       DBT data;
-       DBC *cursor;
-       ID lo, hi, nlo, nhi, nid;
-       char *err;
-
-       {
-               char buf[16];
-               Debug( LDAP_DEBUG_ARGS,
-                       "bdb_idl_insert_key: %lx %s\n", 
-                       (long) id, bdb_show_key( key, buf ) );
-       }
-
-       assert( id != NOID );
-
-       DBTzero( &data );
-       data.size = sizeof( ID );
-       data.ulen = data.size;
-       data.flags = DB_DBT_USERMEM;
-
-       BDB_ID2DISK( id, &nid );
-
-       rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
-       if ( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: "
-                       "cursor failed: %s (%d)\n", db_strerror(rc), rc );
-               return rc;
-       }
-       data.data = &nlo;
-       /* Fetch the first data item for this key, to see if it
-        * exists and if it's a range.
-        */
-       rc = cursor->c_get( cursor, key, &data, DB_SET );
-       err = "c_get";
-       if ( rc == 0 ) {
-               if ( nlo != 0 ) {
-                       /* not a range, count the number of items */
-                       db_recno_t count;
-                       rc = cursor->c_count( cursor, &count, 0 );
-                       if ( rc != 0 ) {
-                               err = "c_count";
-                               goto fail;
-                       }
-                       if ( count >= BDB_IDL_DB_MAX ) {
-                       /* No room, convert to a range */
-                               DBT key2 = *key;
-                               db_recno_t i;
-
-                               key2.dlen = key2.ulen;
-                               key2.flags |= DB_DBT_PARTIAL;
-
-                               BDB_DISK2ID( &nlo, &lo );
-                               data.data = &nhi;
-
-                               rc = cursor->c_get( cursor, &key2, &data, DB_NEXT_NODUP );
-                               if ( rc != 0 && rc != DB_NOTFOUND ) {
-                                       err = "c_get next_nodup";
-                                       goto fail;
-                               }
-                               if ( rc == DB_NOTFOUND ) {
-                                       rc = cursor->c_get( cursor, key, &data, DB_LAST );
-                                       if ( rc != 0 ) {
-                                               err = "c_get last";
-                                               goto fail;
-                                       }
-                               } else {
-                                       rc = cursor->c_get( cursor, key, &data, DB_PREV );
-                                       if ( rc != 0 ) {
-                                               err = "c_get prev";
-                                               goto fail;
-                                       }
-                               }
-                               BDB_DISK2ID( &nhi, &hi );
-                               /* Update hi/lo if needed, then delete all the items
-                                * between lo and hi
-                                */
-                               if ( id < lo ) {
-                                       lo = id;
-                                       nlo = nid;
-                               } else if ( id > hi ) {
-                                       hi = id;
-                                       nhi = nid;
-                               }
-                               data.data = &nid;
-                               /* Don't fetch anything, just position cursor */
-                               data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
-                               data.dlen = data.ulen = 0;
-                               rc = cursor->c_get( cursor, key, &data, DB_SET );
-                               if ( rc != 0 ) {
-                                       err = "c_get 2";
-                                       goto fail;
-                               }
-                               rc = cursor->c_del( cursor, 0 );
-                               if ( rc != 0 ) {
-                                       err = "c_del range1";
-                                       goto fail;
-                               }
-                               /* Delete all the records */
-                               for ( i=1; i<count; i++ ) {
-                                       rc = cursor->c_get( cursor, &key2, &data, DB_NEXT_DUP );
-                                       if ( rc != 0 ) {
-                                               err = "c_get next_dup";
-                                               goto fail;
-                                       }
-                                       rc = cursor->c_del( cursor, 0 );
-                                       if ( rc != 0 ) {
-                                               err = "c_del range";
-                                               goto fail;
-                                       }
-                               }
-                               /* Store the range marker */
-                               data.size = data.ulen = sizeof(ID);
-                               data.flags = DB_DBT_USERMEM;
-                               nid = 0;
-                               rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );
-                               if ( rc != 0 ) {
-                                       err = "c_put range";
-                                       goto fail;
-                               }
-                               nid = nlo;
-                               rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );
-                               if ( rc != 0 ) {
-                                       err = "c_put lo";
-                                       goto fail;
-                               }
-                               nid = nhi;
-                               rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );
-                               if ( rc != 0 ) {
-                                       err = "c_put hi";
-                                       goto fail;
-                               }
-                       } else {
-                       /* There's room, just store it */
-                               goto put1;
-                       }
-               } else {
-                       /* It's a range, see if we need to rewrite
-                        * the boundaries
-                        */
-                       hi = id;
-                       data.data = &nlo;
-                       rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );
-                       if ( rc != 0 ) {
-                               err = "c_get lo";
-                               goto fail;
-                       }
-                       BDB_DISK2ID( &nlo, &lo );
-                       if ( id > lo ) {
-                               data.data = &nhi;
-                               rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );
-                               if ( rc != 0 ) {
-                                       err = "c_get hi";
-                                       goto fail;
-                               }
-                               BDB_DISK2ID( &nhi, &hi );
-                       }
-                       if ( id < lo || id > hi ) {
-                               /* Delete the current lo/hi */
-                               rc = cursor->c_del( cursor, 0 );
-                               if ( rc != 0 ) {
-                                       err = "c_del";
-                                       goto fail;
-                               }
-                               data.data = &nid;
-                               rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );
-                               if ( rc != 0 ) {
-                                       err = "c_put lo/hi";
-                                       goto fail;
-                               }
-                       }
-               }
-       } else if ( rc == DB_NOTFOUND ) {
-put1:          data.data = &nid;
-               rc = cursor->c_put( cursor, key, &data, DB_NODUPDATA );
-               /* Don't worry if it's already there */
-               if ( rc != 0 && rc != DB_KEYEXIST ) {
-                       err = "c_put id";
-                       goto fail;
-               }
-       } else {
-               /* initial c_get failed, nothing was done */
-fail:
-               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: "
-                       "%s failed: %s (%d)\n", err, db_strerror(rc), rc );
-               cursor->c_close( cursor );
-               return rc;
-       }
-       /* If key was added (didn't already exist) and using IDL cache,
-        * update key in IDL cache.
-        */
-       if ( !rc && bdb->bi_idl_cache_max_size ) {
-               bdb_idl_cache_add_id( bdb, db, key, id );
-       }
-       rc = cursor->c_close( cursor );
-       if( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: "
-                       "c_close failed: %s (%d)\n",
-                       db_strerror(rc), rc );
-       }
-       return rc;
-}
-
-int
-bdb_idl_delete_key(
-       BackendDB       *be,
-       DB                      *db,
-       DB_TXN          *tid,
-       DBT                     *key,
-       ID                      id )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       int     rc;
-       DBT data;
-       DBC *cursor;
-       ID lo, hi, tmp, nid, nlo, nhi;
-       char *err;
-
-       {
-               char buf[16];
-               Debug( LDAP_DEBUG_ARGS,
-                       "bdb_idl_delete_key: %lx %s\n", 
-                       (long) id, bdb_show_key( key, buf ) );
-       }
-       assert( id != NOID );
-
-       if ( bdb->bi_idl_cache_size ) {
-               bdb_idl_cache_del( bdb, db, key );
-       }
-
-       BDB_ID2DISK( id, &nid );
-
-       DBTzero( &data );
-       data.data = &tmp;
-       data.size = sizeof( id );
-       data.ulen = data.size;
-       data.flags = DB_DBT_USERMEM;
-
-       rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
-       if ( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_delete_key: "
-                       "cursor failed: %s (%d)\n", db_strerror(rc), rc );
-               return rc;
-       }
-       /* Fetch the first data item for this key, to see if it
-        * exists and if it's a range.
-        */
-       rc = cursor->c_get( cursor, key, &data, DB_SET );
-       err = "c_get";
-       if ( rc == 0 ) {
-               if ( tmp != 0 ) {
-                       /* Not a range, just delete it */
-                       if (tmp != nid) {
-                               /* position to correct item */
-                               tmp = nid;
-                               rc = cursor->c_get( cursor, key, &data, DB_GET_BOTH );
-                               if ( rc != 0 ) {
-                                       err = "c_get id";
-                                       goto fail;
-                               }
-                       }
-                       rc = cursor->c_del( cursor, 0 );
-                       if ( rc != 0 ) {
-                               err = "c_del id";
-                               goto fail;
-                       }
-               } else {
-                       /* It's a range, see if we need to rewrite
-                        * the boundaries
-                        */
-                       data.data = &nlo;
-                       rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );
-                       if ( rc != 0 ) {
-                               err = "c_get lo";
-                               goto fail;
-                       }
-                       BDB_DISK2ID( &nlo, &lo );
-                       data.data = &nhi;
-                       rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );
-                       if ( rc != 0 ) {
-                               err = "c_get hi";
-                               goto fail;
-                       }
-                       BDB_DISK2ID( &nhi, &hi );
-                       if ( id == lo || id == hi ) {
-                               if ( id == lo ) {
-                                       id++;
-                                       lo = id;
-                               } else if ( id == hi ) {
-                                       id--;
-                                       hi = id;
-                               }
-                               if ( lo >= hi ) {
-                               /* The range has collapsed... */
-                                       rc = db->del( db, tid, key, 0 );
-                                       if ( rc != 0 ) {
-                                               err = "del";
-                                               goto fail;
-                                       }
-                               } else {
-                                       if ( id == lo ) {
-                                               /* reposition on lo slot */
-                                               data.data = &nlo;
-                                               cursor->c_get( cursor, key, &data, DB_PREV );
-                                       }
-                                       rc = cursor->c_del( cursor, 0 );
-                                       if ( rc != 0 ) {
-                                               err = "c_del";
-                                               goto fail;
-                                       }
-                               }
-                               if ( lo <= hi ) {
-                                       BDB_ID2DISK( id, &nid );
-                                       data.data = &nid;
-                                       rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );
-                                       if ( rc != 0 ) {
-                                               err = "c_put lo/hi";
-                                               goto fail;
-                                       }
-                               }
-                       }
-               }
-       } else {
-               /* initial c_get failed, nothing was done */
-fail:
-               if ( rc != DB_NOTFOUND ) {
-               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_delete_key: "
-                       "%s failed: %s (%d)\n", err, db_strerror(rc), rc );
-               }
-               cursor->c_close( cursor );
-               return rc;
-       }
-       rc = cursor->c_close( cursor );
-       if( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "=> bdb_idl_delete_key: c_close failed: %s (%d)\n",
-                       db_strerror(rc), rc );
-       }
-
-       return rc;
-}
-
-
-/*
- * idl_intersection - return a = a intersection b
- */
-int
-bdb_idl_intersection(
-       ID *a,
-       ID *b )
-{
-       ID ida, idb;
-       ID idmax, idmin;
-       ID cursora = 0, cursorb = 0, cursorc;
-       int swap = 0;
-
-       if ( BDB_IDL_IS_ZERO( a ) || BDB_IDL_IS_ZERO( b ) ) {
-               a[0] = 0;
-               return 0;
-       }
-
-       idmin = IDL_MAX( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) );
-       idmax = IDL_MIN( BDB_IDL_LAST(a), BDB_IDL_LAST(b) );
-       if ( idmin > idmax ) {
-               a[0] = 0;
-               return 0;
-       } else if ( idmin == idmax ) {
-               a[0] = 1;
-               a[1] = idmin;
-               return 0;
-       }
-
-       if ( BDB_IDL_IS_RANGE( a ) ) {
-               if ( BDB_IDL_IS_RANGE(b) ) {
-               /* If both are ranges, just shrink the boundaries */
-                       a[1] = idmin;
-                       a[2] = idmax;
-                       return 0;
-               } else {
-               /* Else swap so that b is the range, a is a list */
-                       ID *tmp = a;
-                       a = b;
-                       b = tmp;
-                       swap = 1;
-               }
-       }
-
-       /* If a range completely covers the list, the result is
-        * just the list.
-        */
-       if ( BDB_IDL_IS_RANGE( b )
-               && BDB_IDL_RANGE_FIRST( b ) <= BDB_IDL_FIRST( a )
-               && BDB_IDL_RANGE_LAST( b ) >= BDB_IDL_LLAST( a ) ) {
-               goto done;
-       }
-
-       /* Fine, do the intersection one element at a time.
-        * First advance to idmin in both IDLs.
-        */
-       cursora = cursorb = idmin;
-       ida = bdb_idl_first( a, &cursora );
-       idb = bdb_idl_first( b, &cursorb );
-       cursorc = 0;
-
-       while( ida <= idmax || idb <= idmax ) {
-               if( ida == idb ) {
-                       a[++cursorc] = ida;
-                       ida = bdb_idl_next( a, &cursora );
-                       idb = bdb_idl_next( b, &cursorb );
-               } else if ( ida < idb ) {
-                       ida = bdb_idl_next( a, &cursora );
-               } else {
-                       idb = bdb_idl_next( b, &cursorb );
-               }
-       }
-       a[0] = cursorc;
-done:
-       if (swap)
-               BDB_IDL_CPY( b, a );
-
-       return 0;
-}
-
-
-/*
- * idl_union - return a = a union b
- */
-int
-bdb_idl_union(
-       ID      *a,
-       ID      *b )
-{
-       ID ida, idb;
-       ID cursora = 0, cursorb = 0, cursorc;
-
-       if ( BDB_IDL_IS_ZERO( b ) ) {
-               return 0;
-       }
-
-       if ( BDB_IDL_IS_ZERO( a ) ) {
-               BDB_IDL_CPY( a, b );
-               return 0;
-       }
-
-       if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) ) {
-over:          ida = IDL_MIN( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) );
-               idb = IDL_MAX( BDB_IDL_LAST(a), BDB_IDL_LAST(b) );
-               a[0] = NOID;
-               a[1] = ida;
-               a[2] = idb;
-               return 0;
-       }
-
-       ida = bdb_idl_first( a, &cursora );
-       idb = bdb_idl_first( b, &cursorb );
-
-       cursorc = b[0];
-
-       /* The distinct elements of a are cat'd to b */
-       while( ida != NOID || idb != NOID ) {
-               if ( ida < idb ) {
-                       if( ++cursorc > BDB_IDL_UM_MAX ) {
-                               goto over;
-                       }
-                       b[cursorc] = ida;
-                       ida = bdb_idl_next( a, &cursora );
-
-               } else {
-                       if ( ida == idb )
-                               ida = bdb_idl_next( a, &cursora );
-                       idb = bdb_idl_next( b, &cursorb );
-               }
-       }
-
-       /* b is copied back to a in sorted order */
-       a[0] = cursorc;
-       cursora = 1;
-       cursorb = 1;
-       cursorc = b[0]+1;
-       while (cursorb <= b[0] || cursorc <= a[0]) {
-               if (cursorc > a[0])
-                       idb = NOID;
-               else
-                       idb = b[cursorc];
-               if (cursorb <= b[0] && b[cursorb] < idb)
-                       a[cursora++] = b[cursorb++];
-               else {
-                       a[cursora++] = idb;
-                       cursorc++;
-               }
-       }
-
-       return 0;
-}
-
-
-#if 0
-/*
- * bdb_idl_notin - return a intersection ~b (or a minus b)
- */
-int
-bdb_idl_notin(
-       ID      *a,
-       ID      *b,
-       ID *ids )
-{
-       ID ida, idb;
-       ID cursora = 0, cursorb = 0;
-
-       if( BDB_IDL_IS_ZERO( a ) ||
-               BDB_IDL_IS_ZERO( b ) ||
-               BDB_IDL_IS_RANGE( b ) )
-       {
-               BDB_IDL_CPY( ids, a );
-               return 0;
-       }
-
-       if( BDB_IDL_IS_RANGE( a ) ) {
-               BDB_IDL_CPY( ids, a );
-               return 0;
-       }
-
-       ida = bdb_idl_first( a, &cursora ),
-       idb = bdb_idl_first( b, &cursorb );
-
-       ids[0] = 0;
-
-       while( ida != NOID ) {
-               if ( idb == NOID ) {
-                       /* we could shortcut this */
-                       ids[++ids[0]] = ida;
-                       ida = bdb_idl_next( a, &cursora );
-
-               } else if ( ida < idb ) {
-                       ids[++ids[0]] = ida;
-                       ida = bdb_idl_next( a, &cursora );
-
-               } else if ( ida > idb ) {
-                       idb = bdb_idl_next( b, &cursorb );
-
-               } else {
-                       ida = bdb_idl_next( a, &cursora );
-                       idb = bdb_idl_next( b, &cursorb );
-               }
-       }
-
-       return 0;
-}
-#endif
-
-ID bdb_idl_first( ID *ids, ID *cursor )
-{
-       ID pos;
-
-       if ( ids[0] == 0 ) {
-               *cursor = NOID;
-               return NOID;
-       }
-
-       if ( BDB_IDL_IS_RANGE( ids ) ) {
-               if( *cursor < ids[1] ) {
-                       *cursor = ids[1];
-               }
-               return *cursor;
-       }
-
-       if ( *cursor == 0 )
-               pos = 1;
-       else
-               pos = bdb_idl_search( ids, *cursor );
-
-       if( pos > ids[0] ) {
-               return NOID;
-       }
-
-       *cursor = pos;
-       return ids[pos];
-}
-
-ID bdb_idl_next( ID *ids, ID *cursor )
-{
-       if ( BDB_IDL_IS_RANGE( ids ) ) {
-               if( ids[2] < ++(*cursor) ) {
-                       return NOID;
-               }
-               return *cursor;
-       }
-
-       if ( ++(*cursor) <= ids[0] ) {
-               return ids[*cursor];
-       }
-
-       return NOID;
-}
-
-#ifdef BDB_HIER
-
-/* Add one ID to an unsorted list. We ensure that the first element is the
- * minimum and the last element is the maximum, for fast range compaction.
- *   this means IDLs up to length 3 are always sorted...
- */
-int bdb_idl_append_one( ID *ids, ID id )
-{
-       if (BDB_IDL_IS_RANGE( ids )) {
-               /* if already in range, treat as a dup */
-               if (id >= BDB_IDL_RANGE_FIRST(ids) && id <= BDB_IDL_RANGE_LAST(ids))
-                       return -1;
-               if (id < BDB_IDL_RANGE_FIRST(ids))
-                       ids[1] = id;
-               else if (id > BDB_IDL_RANGE_LAST(ids))
-                       ids[2] = id;
-               return 0;
-       }
-       if ( ids[0] ) {
-               ID tmp;
-
-               if (id < ids[1]) {
-                       tmp = ids[1];
-                       ids[1] = id;
-                       id = tmp;
-               }
-               if ( ids[0] > 1 && id < ids[ids[0]] ) {
-                       tmp = ids[ids[0]];
-                       ids[ids[0]] = id;
-                       id = tmp;
-               }
-       }
-       ids[0]++;
-       if ( ids[0] >= BDB_IDL_UM_MAX ) {
-               ids[0] = NOID;
-               ids[2] = id;
-       } else {
-               ids[ids[0]] = id;
-       }
-       return 0;
-}
-
-/* Append sorted list b to sorted list a. The result is unsorted but
- * a[1] is the min of the result and a[a[0]] is the max.
- */
-int bdb_idl_append( ID *a, ID *b )
-{
-       ID ida, idb, tmp, swap = 0;
-
-       if ( BDB_IDL_IS_ZERO( b ) ) {
-               return 0;
-       }
-
-       if ( BDB_IDL_IS_ZERO( a ) ) {
-               BDB_IDL_CPY( a, b );
-               return 0;
-       }
-
-       if ( b[0] == 1 ) {
-               return bdb_idl_append_one( a, BDB_IDL_FIRST( b ));
-       }
-
-       ida = BDB_IDL_LAST( a );
-       idb = BDB_IDL_LAST( b );
-       if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) ||
-               a[0] + b[0] >= BDB_IDL_UM_MAX ) {
-               a[2] = IDL_MAX( ida, idb );
-               a[1] = IDL_MIN( a[1], b[1] );
-               a[0] = NOID;
-               return 0;
-       }
-
-       if ( ida > idb ) {
-               swap = idb;
-               a[a[0]] = idb;
-               b[b[0]] = ida;
-       }
-
-       if ( b[1] < a[1] ) {
-               tmp = a[1];
-               a[1] = b[1];
-       } else {
-               tmp = b[1];
-       }
-       a[0]++;
-       a[a[0]] = tmp;
-
-       {
-               int i = b[0] - 1;
-               AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID));
-               a[0] += i;
-       }
-       if ( swap ) {
-               b[b[0]] = swap;
-       }
-       return 0;
-}
-
-#if 1
-
-/* Quicksort + Insertion sort for small arrays */
-
-#define SMALL  8
-#define        SWAP(a,b)       itmp=(a);(a)=(b);(b)=itmp
-
-void
-bdb_idl_sort( ID *ids, ID *tmp )
-{
-       int *istack = (int *)tmp;
-       int i,j,k,l,ir,jstack;
-       ID a, itmp;
-
-       if ( BDB_IDL_IS_RANGE( ids ))
-               return;
-
-       ir = ids[0];
-       l = 1;
-       jstack = 0;
-       for(;;) {
-               if (ir - l < SMALL) {   /* Insertion sort */
-                       for (j=l+1;j<=ir;j++) {
-                               a = ids[j];
-                               for (i=j-1;i>=1;i--) {
-                                       if (ids[i] <= a) break;
-                                       ids[i+1] = ids[i];
-                               }
-                               ids[i+1] = a;
-                       }
-                       if (jstack == 0) break;
-                       ir = istack[jstack--];
-                       l = istack[jstack--];
-               } else {
-                       k = (l + ir) >> 1;      /* Choose median of left, center, right */
-                       SWAP(ids[k], ids[l+1]);
-                       if (ids[l] > ids[ir]) {
-                               SWAP(ids[l], ids[ir]);
-                       }
-                       if (ids[l+1] > ids[ir]) {
-                               SWAP(ids[l+1], ids[ir]);
-                       }
-                       if (ids[l] > ids[l+1]) {
-                               SWAP(ids[l], ids[l+1]);
-                       }
-                       i = l+1;
-                       j = ir;
-                       a = ids[l+1];
-                       for(;;) {
-                               do i++; while(ids[i] < a);
-                               do j--; while(ids[j] > a);
-                               if (j < i) break;
-                               SWAP(ids[i],ids[j]);
-                       }
-                       ids[l+1] = ids[j];
-                       ids[j] = a;
-                       jstack += 2;
-                       if (ir-i+1 >= j-l) {
-                               istack[jstack] = ir;
-                               istack[jstack-1] = i;
-                               ir = j-1;
-                       } else {
-                               istack[jstack] = j-1;
-                               istack[jstack-1] = l;
-                               l = i;
-                       }
-               }
-       }
-}
-
-#else
-
-/* 8 bit Radix sort + insertion sort
- * 
- * based on code from http://www.cubic.org/docs/radix.htm
- * with improvements by ebackes@symas.com and hyc@symas.com
- *
- * This code is O(n) but has a relatively high constant factor. For lists
- * up to ~50 Quicksort is slightly faster; up to ~100 they are even.
- * Much faster than quicksort for lists longer than ~100. Insertion
- * sort is actually superior for lists <50.
- */
-
-#define BUCKETS        (1<<8)
-#define SMALL  50
-
-void
-bdb_idl_sort( ID *ids, ID *tmp )
-{
-       int count, soft_limit, phase = 0, size = ids[0];
-       ID *idls[2];
-       unsigned char *maxv = (unsigned char *)&ids[size];
-
-       if ( BDB_IDL_IS_RANGE( ids ))
-               return;
-
-       /* Use insertion sort for small lists */
-       if ( size <= SMALL ) {
-               int i,j;
-               ID a;
-
-               for (j=1;j<=size;j++) {
-                       a = ids[j];
-                       for (i=j-1;i>=1;i--) {
-                               if (ids[i] <= a) break;
-                               ids[i+1] = ids[i];
-                       }
-                       ids[i+1] = a;
-               }
-               return;
-       }
-
-       tmp[0] = size;
-       idls[0] = ids;
-       idls[1] = tmp;
-
-#if BYTE_ORDER == BIG_ENDIAN
-    for (soft_limit = 0; !maxv[soft_limit]; soft_limit++);
-#else
-    for (soft_limit = sizeof(ID)-1; !maxv[soft_limit]; soft_limit--);
-#endif
-
-       for (
-#if BYTE_ORDER == BIG_ENDIAN
-       count = sizeof(ID)-1; count >= soft_limit; --count
-#else
-       count = 0; count <= soft_limit; ++count
-#endif
-       ) {
-               unsigned int num[BUCKETS], * np, n, sum;
-               int i;
-        ID *sp, *source, *dest;
-        unsigned char *bp, *source_start;
-
-               source = idls[phase]+1;
-               dest = idls[phase^1]+1;
-               source_start =  ((unsigned char *) source) + count;
-
-        np = num;
-        for ( i = BUCKETS; i > 0; --i ) *np++ = 0;
-
-               /* count occurences of every byte value */
-               bp = source_start;
-        for ( i = size; i > 0; --i, bp += sizeof(ID) )
-                               num[*bp]++;
-
-               /* transform count into index by summing elements and storing
-                * into same array
-                */
-        sum = 0;
-        np = num;
-        for ( i = BUCKETS; i > 0; --i ) {
-                n = *np;
-                *np++ = sum;
-                sum += n;
-        }
-
-               /* fill dest with the right values in the right place */
-               bp = source_start;
-        sp = source;
-        for ( i = size; i > 0; --i, bp += sizeof(ID) ) {
-                np = num + *bp;
-                dest[*np] = *sp++;
-                ++(*np);
-        }
-               phase ^= 1;
-       }
-
-       /* copy back from temp if needed */
-       if ( phase ) {
-               ids++; tmp++;
-               for ( count = 0; count < size; ++count ) 
-                       *ids++ = *tmp++;
-       }
-}
-#endif /* Quick vs Radix */
-
-#endif /* BDB_HIER */
diff --git a/servers/slapd/back-bdb/idl.h b/servers/slapd/back-bdb/idl.h
deleted file mode 100644 (file)
index 6e06e34..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* idl.h - ldap bdb back-end ID list header file */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#ifndef _BDB_IDL_H_
-#define _BDB_IDL_H_
-
-/* IDL sizes - likely should be even bigger
- *   limiting factors: sizeof(ID), thread stack size
- */
-#define        BDB_IDL_LOGN    16      /* DB_SIZE is 2^16, UM_SIZE is 2^17 */
-#define BDB_IDL_DB_SIZE                (1<<BDB_IDL_LOGN)
-#define BDB_IDL_UM_SIZE                (1<<(BDB_IDL_LOGN+1))
-#define BDB_IDL_UM_SIZEOF      (BDB_IDL_UM_SIZE * sizeof(ID))
-
-#define BDB_IDL_DB_MAX         (BDB_IDL_DB_SIZE-1)
-
-#define BDB_IDL_UM_MAX         (BDB_IDL_UM_SIZE-1)
-
-#define BDB_IDL_IS_RANGE(ids)  ((ids)[0] == NOID)
-#define BDB_IDL_RANGE_SIZE             (3)
-#define BDB_IDL_RANGE_SIZEOF   (BDB_IDL_RANGE_SIZE * sizeof(ID))
-#define BDB_IDL_SIZEOF(ids)            ((BDB_IDL_IS_RANGE(ids) \
-       ? BDB_IDL_RANGE_SIZE : ((ids)[0]+1)) * sizeof(ID))
-
-#define BDB_IDL_RANGE_FIRST(ids)       ((ids)[1])
-#define BDB_IDL_RANGE_LAST(ids)                ((ids)[2])
-
-#define BDB_IDL_RANGE( ids, f, l ) \
-       do { \
-               (ids)[0] = NOID; \
-               (ids)[1] = (f);  \
-               (ids)[2] = (l);  \
-       } while(0)
-
-#define BDB_IDL_ZERO(ids) \
-       do { \
-               (ids)[0] = 0; \
-               (ids)[1] = 0; \
-               (ids)[2] = 0; \
-       } while(0)
-
-#define BDB_IDL_IS_ZERO(ids) ( (ids)[0] == 0 )
-#define BDB_IDL_IS_ALL( range, ids ) ( (ids)[0] == NOID \
-       && (ids)[1] <= (range)[1] && (range)[2] <= (ids)[2] )
-
-#define BDB_IDL_CPY( dst, src ) (AC_MEMCPY( dst, src, BDB_IDL_SIZEOF( src ) ))
-
-#define BDB_IDL_ID( bdb, ids, id ) BDB_IDL_RANGE( ids, id, ((bdb)->bi_lastid) )
-#define BDB_IDL_ALL( bdb, ids ) BDB_IDL_RANGE( ids, 1, ((bdb)->bi_lastid) )
-
-#define BDB_IDL_FIRST( ids )   ( (ids)[1] )
-#define BDB_IDL_LLAST( ids )   ( (ids)[(ids)[0]] )
-#define BDB_IDL_LAST( ids )            ( BDB_IDL_IS_RANGE(ids) \
-       ? (ids)[2] : (ids)[(ids)[0]] )
-
-#define BDB_IDL_N( ids )               ( BDB_IDL_IS_RANGE(ids) \
-       ? ((ids)[2]-(ids)[1])+1 : (ids)[0] )
-
-LDAP_BEGIN_DECL
-LDAP_END_DECL
-
-#endif
diff --git a/servers/slapd/back-bdb/index.c b/servers/slapd/back-bdb/index.c
deleted file mode 100644 (file)
index f9cd25e..0000000
+++ /dev/null
@@ -1,574 +0,0 @@
-/* index.c - routines for dealing with attribute indexes */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb.h"
-#include "lutil_hash.h"
-
-static char presence_keyval[] = {0,0};
-static struct berval presence_key = BER_BVC(presence_keyval);
-
-AttrInfo *bdb_index_mask(
-       Backend *be,
-       AttributeDescription *desc,
-       struct berval *atname )
-{
-       AttributeType *at;
-       AttrInfo *ai = bdb_attr_mask( be->be_private, desc );
-
-       if( ai ) {
-               *atname = desc->ad_cname;
-               return ai;
-       }
-
-       /* If there is a tagging option, did we ever index the base
-        * type? If so, check for mask, otherwise it's not there.
-        */
-       if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) {
-               /* has tagging option */
-               ai = bdb_attr_mask( be->be_private, desc->ad_type->sat_ad );
-
-               if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOTAGS ) ) {
-                       *atname = desc->ad_type->sat_cname;
-                       return ai;
-               }
-       }
-
-       /* see if supertype defined mask for its subtypes */
-       for( at = desc->ad_type; at != NULL ; at = at->sat_sup ) {
-               /* If no AD, we've never indexed this type */
-               if ( !at->sat_ad ) continue;
-
-               ai = bdb_attr_mask( be->be_private, at->sat_ad );
-
-               if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOSUBTYPES ) ) {
-                       *atname = at->sat_cname;
-                       return ai;
-               }
-       }
-
-       return 0;
-}
-
-/* This function is only called when evaluating search filters.
- */
-int bdb_index_param(
-       Backend *be,
-       AttributeDescription *desc,
-       int ftype,
-       DB **dbp,
-       slap_mask_t *maskp,
-       struct berval *prefixp )
-{
-       AttrInfo *ai;
-       int rc;
-       slap_mask_t mask, type = 0;
-       DB *db;
-
-       ai = bdb_index_mask( be, desc, prefixp );
-
-       if ( !ai ) {
-#ifdef BDB_MONITOR_IDX
-               switch ( ftype ) {
-               case LDAP_FILTER_PRESENT:
-                       type = SLAP_INDEX_PRESENT;
-                       break;
-               case LDAP_FILTER_APPROX:
-                       type = SLAP_INDEX_APPROX;
-                       break;
-               case LDAP_FILTER_EQUALITY:
-                       type = SLAP_INDEX_EQUALITY;
-                       break;
-               case LDAP_FILTER_SUBSTRINGS:
-                       type = SLAP_INDEX_SUBSTR;
-                       break;
-               default:
-                       return LDAP_INAPPROPRIATE_MATCHING;
-               }
-               bdb_monitor_idx_add( be->be_private, desc, type );
-#endif /* BDB_MONITOR_IDX */
-
-               return LDAP_INAPPROPRIATE_MATCHING;
-       }
-       mask = ai->ai_indexmask;
-
-       rc = bdb_db_cache( be, prefixp, &db );
-
-       if( rc != LDAP_SUCCESS ) {
-               return rc;
-       }
-
-       switch( ftype ) {
-       case LDAP_FILTER_PRESENT:
-               type = SLAP_INDEX_PRESENT;
-               if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
-                       *prefixp = presence_key;
-                       goto done;
-               }
-               break;
-
-       case LDAP_FILTER_APPROX:
-               type = SLAP_INDEX_APPROX;
-               if ( desc->ad_type->sat_approx ) {
-                       if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
-                               goto done;
-                       }
-                       break;
-               }
-
-               /* Use EQUALITY rule and index for approximate match */
-               /* fall thru */
-
-       case LDAP_FILTER_EQUALITY:
-               type = SLAP_INDEX_EQUALITY;
-               if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
-                       goto done;
-               }
-               break;
-
-       case LDAP_FILTER_SUBSTRINGS:
-               type = SLAP_INDEX_SUBSTR;
-               if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
-                       goto done;
-               }
-               break;
-
-       default:
-               return LDAP_OTHER;
-       }
-
-#ifdef BDB_MONITOR_IDX
-       bdb_monitor_idx_add( be->be_private, desc, type );
-#endif /* BDB_MONITOR_IDX */
-
-       return LDAP_INAPPROPRIATE_MATCHING;
-
-done:
-       *dbp = db;
-       *maskp = mask;
-       return LDAP_SUCCESS;
-}
-
-static int indexer(
-       Operation *op,
-       DB_TXN *txn,
-       AttributeDescription *ad,
-       struct berval *atname,
-       BerVarray vals,
-       ID id,
-       int opid,
-       slap_mask_t mask )
-{
-       int rc, i;
-       DB *db;
-       struct berval *keys;
-
-       assert( mask != 0 );
-
-       rc = bdb_db_cache( op->o_bd, atname, &db );
-       
-       if ( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "bdb_index_read: Could not open DB %s\n",
-                       atname->bv_val );
-               return LDAP_OTHER;
-       }
-
-       if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
-               rc = bdb_key_change( op->o_bd, db, txn, &presence_key, id, opid );
-               if( rc ) {
-                       goto done;
-               }
-       }
-
-       if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
-               rc = ad->ad_type->sat_equality->smr_indexer(
-                       LDAP_FILTER_EQUALITY,
-                       mask,
-                       ad->ad_type->sat_syntax,
-                       ad->ad_type->sat_equality,
-                       atname, vals, &keys, op->o_tmpmemctx );
-
-               if( rc == LDAP_SUCCESS && keys != NULL ) {
-                       for( i=0; keys[i].bv_val != NULL; i++ ) {
-                               rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid );
-                               if( rc ) {
-                                       ber_bvarray_free_x( keys, op->o_tmpmemctx );
-                                       goto done;
-                               }
-                       }
-                       ber_bvarray_free_x( keys, op->o_tmpmemctx );
-               }
-               rc = LDAP_SUCCESS;
-       }
-
-       if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
-               rc = ad->ad_type->sat_approx->smr_indexer(
-                       LDAP_FILTER_APPROX,
-                       mask,
-                       ad->ad_type->sat_syntax,
-                       ad->ad_type->sat_approx,
-                       atname, vals, &keys, op->o_tmpmemctx );
-
-               if( rc == LDAP_SUCCESS && keys != NULL ) {
-                       for( i=0; keys[i].bv_val != NULL; i++ ) {
-                               rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid );
-                               if( rc ) {
-                                       ber_bvarray_free_x( keys, op->o_tmpmemctx );
-                                       goto done;
-                               }
-                       }
-                       ber_bvarray_free_x( keys, op->o_tmpmemctx );
-               }
-
-               rc = LDAP_SUCCESS;
-       }
-
-       if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
-               rc = ad->ad_type->sat_substr->smr_indexer(
-                       LDAP_FILTER_SUBSTRINGS,
-                       mask,
-                       ad->ad_type->sat_syntax,
-                       ad->ad_type->sat_substr,
-                       atname, vals, &keys, op->o_tmpmemctx );
-
-               if( rc == LDAP_SUCCESS && keys != NULL ) {
-                       for( i=0; keys[i].bv_val != NULL; i++ ) {
-                               rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid );
-                               if( rc ) {
-                                       ber_bvarray_free_x( keys, op->o_tmpmemctx );
-                                       goto done;
-                               }
-                       }
-                       ber_bvarray_free_x( keys, op->o_tmpmemctx );
-               }
-
-               rc = LDAP_SUCCESS;
-       }
-
-done:
-       switch( rc ) {
-       /* The callers all know how to deal with these results */
-       case 0:
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               break;
-       /* Anything else is bad news */
-       default:
-               rc = LDAP_OTHER;
-       }
-       return rc;
-}
-
-static int index_at_values(
-       Operation *op,
-       DB_TXN *txn,
-       AttributeDescription *ad,
-       AttributeType *type,
-       struct berval *tags,
-       BerVarray vals,
-       ID id,
-       int opid )
-{
-       int rc;
-       slap_mask_t mask = 0;
-       int ixop = opid;
-       AttrInfo *ai = NULL;
-
-       if ( opid == BDB_INDEX_UPDATE_OP )
-               ixop = SLAP_INDEX_ADD_OP;
-
-       if( type->sat_sup ) {
-               /* recurse */
-               rc = index_at_values( op, txn, NULL,
-                       type->sat_sup, tags,
-                       vals, id, opid );
-
-               if( rc ) return rc;
-       }
-
-       /* If this type has no AD, we've never used it before */
-       if( type->sat_ad ) {
-               ai = bdb_attr_mask( op->o_bd->be_private, type->sat_ad );
-               if ( ai ) {
-#ifdef LDAP_COMP_MATCH
-                       /* component indexing */
-                       if ( ai->ai_cr ) {
-                               ComponentReference *cr;
-                               for( cr = ai->ai_cr ; cr ; cr = cr->cr_next ) {
-                                       rc = indexer( op, txn, cr->cr_ad, &type->sat_cname,
-                                               cr->cr_nvals, id, ixop,
-                                               cr->cr_indexmask );
-                               }
-                       }
-#endif
-                       ad = type->sat_ad;
-                       /* If we're updating the index, just set the new bits that aren't
-                        * already in the old mask.
-                        */
-                       if ( opid == BDB_INDEX_UPDATE_OP )
-                               mask = ai->ai_newmask & ~ai->ai_indexmask;
-                       else
-                       /* For regular updates, if there is a newmask use it. Otherwise
-                        * just use the old mask.
-                        */
-                               mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask;
-                       if( mask ) {
-                               rc = indexer( op, txn, ad, &type->sat_cname,
-                                       vals, id, ixop, mask );
-
-                               if( rc ) return rc;
-                       }
-               }
-       }
-
-       if( tags->bv_len ) {
-               AttributeDescription *desc;
-
-               desc = ad_find_tags( type, tags );
-               if( desc ) {
-                       ai = bdb_attr_mask( op->o_bd->be_private, desc );
-
-                       if( ai ) {
-                               if ( opid == BDB_INDEX_UPDATE_OP )
-                                       mask = ai->ai_newmask & ~ai->ai_indexmask;
-                               else
-                                       mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask;
-                               if ( mask ) {
-                                       rc = indexer( op, txn, desc, &desc->ad_cname,
-                                               vals, id, ixop, mask );
-
-                                       if( rc ) {
-                                               return rc;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       return LDAP_SUCCESS;
-}
-
-int bdb_index_values(
-       Operation *op,
-       DB_TXN *txn,
-       AttributeDescription *desc,
-       BerVarray vals,
-       ID id,
-       int opid )
-{
-       int rc;
-
-       /* Never index ID 0 */
-       if ( id == 0 )
-               return 0;
-
-       rc = index_at_values( op, txn, desc,
-               desc->ad_type, &desc->ad_tags,
-               vals, id, opid );
-
-       return rc;
-}
-
-/* Get the list of which indices apply to this attr */
-int
-bdb_index_recset(
-       struct bdb_info *bdb,
-       Attribute *a,
-       AttributeType *type,
-       struct berval *tags,
-       IndexRec *ir )
-{
-       int rc, slot;
-       AttrList *al;
-
-       if( type->sat_sup ) {
-               /* recurse */
-               rc = bdb_index_recset( bdb, a, type->sat_sup, tags, ir );
-               if( rc ) return rc;
-       }
-       /* If this type has no AD, we've never used it before */
-       if( type->sat_ad ) {
-               slot = bdb_attr_slot( bdb, type->sat_ad, NULL );
-               if ( slot >= 0 ) {
-                       ir[slot].ai = bdb->bi_attrs[slot];
-                       al = ch_malloc( sizeof( AttrList ));
-                       al->attr = a;
-                       al->next = ir[slot].attrs;
-                       ir[slot].attrs = al;
-               }
-       }
-       if( tags->bv_len ) {
-               AttributeDescription *desc;
-
-               desc = ad_find_tags( type, tags );
-               if( desc ) {
-                       slot = bdb_attr_slot( bdb, desc, NULL );
-                       if ( slot >= 0 ) {
-                               ir[slot].ai = bdb->bi_attrs[slot];
-                               al = ch_malloc( sizeof( AttrList ));
-                               al->attr = a;
-                               al->next = ir[slot].attrs;
-                               ir[slot].attrs = al;
-                       }
-               }
-       }
-       return LDAP_SUCCESS;
-}
-
-/* Apply the indices for the recset */
-int bdb_index_recrun(
-       Operation *op,
-       struct bdb_info *bdb,
-       IndexRec *ir0,
-       ID id,
-       int base )
-{
-       IndexRec *ir;
-       AttrList *al;
-       int i, rc = 0;
-
-       /* Never index ID 0 */
-       if ( id == 0 )
-               return 0;
-
-       for (i=base; i<bdb->bi_nattrs; i+=slap_tool_thread_max-1) {
-               ir = ir0 + i;
-               if ( !ir->ai ) continue;
-               while (( al = ir->attrs )) {
-                       ir->attrs = al->next;
-                       rc = indexer( op, NULL, ir->ai->ai_desc,
-                               &ir->ai->ai_desc->ad_type->sat_cname,
-                               al->attr->a_nvals, id, SLAP_INDEX_ADD_OP,
-                               ir->ai->ai_indexmask );
-                       free( al );
-                       if ( rc ) break;
-               }
-       }
-       return rc;
-}
-
-int
-bdb_index_entry(
-       Operation *op,
-       DB_TXN *txn,
-       int opid,
-       Entry   *e )
-{
-       int rc;
-       Attribute *ap = e->e_attrs;
-#if 0 /* ifdef LDAP_COMP_MATCH */
-       ComponentReference *cr_list = NULL;
-       ComponentReference *cr = NULL, *dupped_cr = NULL;
-       void* decoded_comp;
-       ComponentSyntaxInfo* csi_attr;
-       Syntax* syn;
-       AttributeType* at;
-       int i, num_attr;
-       void* mem_op;
-       struct berval value = {0};
-#endif
-
-       /* Never index ID 0 */
-       if ( e->e_id == 0 )
-               return 0;
-
-       Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n",
-               opid == SLAP_INDEX_DELETE_OP ? "del" : "add",
-               (long) e->e_id, e->e_dn );
-
-       /* add each attribute to the indexes */
-       for ( ; ap != NULL; ap = ap->a_next ) {
-#if 0 /* ifdef LDAP_COMP_MATCH */
-               AttrInfo *ai;
-               /* see if attribute has components to be indexed */
-               ai = bdb_attr_mask( op->o_bd->be_private, ap->a_desc->ad_type->sat_ad );
-               if ( !ai ) continue;
-               cr_list = ai->ai_cr;
-               if ( attr_converter && cr_list ) {
-                       syn = ap->a_desc->ad_type->sat_syntax;
-                       ap->a_comp_data = op->o_tmpalloc( sizeof( ComponentData ), op->o_tmpmemctx );
-                       /* Memory chunk(nibble) pre-allocation for decoders */
-                       mem_op = nibble_mem_allocator ( 1024*16, 1024*4 );
-                       ap->a_comp_data->cd_mem_op = mem_op;
-                       for( cr = cr_list ; cr ; cr = cr->cr_next ) {
-                               /* count how many values in an attribute */
-                               for( num_attr=0; ap->a_vals[num_attr].bv_val != NULL; num_attr++ );
-                               num_attr++;
-                               cr->cr_nvals = (BerVarray)op->o_tmpalloc( sizeof( struct berval )*num_attr, op->o_tmpmemctx );
-                               for( i=0; ap->a_vals[i].bv_val != NULL; i++ ) {
-                                       /* decoding attribute value */
-                                       decoded_comp = attr_converter ( ap, syn, &ap->a_vals[i] );
-                                       if ( !decoded_comp )
-                                               return LDAP_DECODING_ERROR;
-                                       /* extracting the referenced component */
-                                       dupped_cr = dup_comp_ref( op, cr );
-                                       csi_attr = ((ComponentSyntaxInfo*)decoded_comp)->csi_comp_desc->cd_extract_i( mem_op, dupped_cr, decoded_comp );
-                                       if ( !csi_attr )
-                                               return LDAP_DECODING_ERROR;
-                                       cr->cr_asn_type_id = csi_attr->csi_comp_desc->cd_type_id;
-                                       cr->cr_ad = (AttributeDescription*)get_component_description ( cr->cr_asn_type_id );
-                                       if ( !cr->cr_ad )
-                                               return LDAP_INVALID_SYNTAX;
-                                       at = cr->cr_ad->ad_type;
-                                       /* encoding the value of component in GSER */
-                                       rc = component_encoder( mem_op, csi_attr, &value );
-                                       if ( rc != LDAP_SUCCESS )
-                                               return LDAP_ENCODING_ERROR;
-                                       /* Normalize the encoded component values */
-                                       if ( at->sat_equality && at->sat_equality->smr_normalize ) {
-                                               rc = at->sat_equality->smr_normalize (
-                                                       SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
-                                                       at->sat_syntax, at->sat_equality,
-                                                       &value, &cr->cr_nvals[i], op->o_tmpmemctx );
-                                       } else {
-                                               cr->cr_nvals[i] = value;
-                                       }
-                               }
-                               /* The end of BerVarray */
-                               cr->cr_nvals[num_attr-1].bv_val = NULL;
-                               cr->cr_nvals[num_attr-1].bv_len = 0;
-                       }
-                       op->o_tmpfree( ap->a_comp_data, op->o_tmpmemctx );
-                       nibble_mem_free ( mem_op );
-                       ap->a_comp_data = NULL;
-               }
-#endif
-               rc = bdb_index_values( op, txn, ap->a_desc,
-                       ap->a_nvals, e->e_id, opid );
-
-               if( rc != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<= index_entry_%s( %ld, \"%s\" ) failure\n",
-                               opid == SLAP_INDEX_ADD_OP ? "add" : "del",
-                               (long) e->e_id, e->e_dn );
-                       return rc;
-               }
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n",
-               opid == SLAP_INDEX_DELETE_OP ? "del" : "add",
-               (long) e->e_id, e->e_dn );
-
-       return LDAP_SUCCESS;
-}
diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c
deleted file mode 100644 (file)
index 1b25dbc..0000000
+++ /dev/null
@@ -1,871 +0,0 @@
-/* init.c - initialize bdb backend */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-#include <ac/unistd.h>
-#include <ac/stdlib.h>
-#include <ac/errno.h>
-#include <sys/stat.h>
-#include "back-bdb.h"
-#include <lutil.h>
-#include <ldap_rq.h>
-#include "alock.h"
-#include "config.h"
-
-static const struct bdbi_database {
-       char *file;
-       struct berval name;
-       int type;
-       int flags;
-} bdbi_databases[] = {
-       { "id2entry" BDB_SUFFIX, BER_BVC("id2entry"), DB_BTREE, 0 },
-       { "dn2id" BDB_SUFFIX, BER_BVC("dn2id"), DB_BTREE, 0 },
-       { NULL, BER_BVNULL, 0, 0 }
-};
-
-typedef void * db_malloc(size_t);
-typedef void * db_realloc(void *, size_t);
-
-#define bdb_db_init    BDB_SYMBOL(db_init)
-#define bdb_db_open BDB_SYMBOL(db_open)
-#define bdb_db_close BDB_SYMBOL(db_close)
-
-static int
-bdb_db_init( BackendDB *be, ConfigReply *cr )
-{
-       struct bdb_info *bdb;
-       int rc;
-
-       Debug( LDAP_DEBUG_TRACE,
-               LDAP_XSTRING(bdb_db_init) ": Initializing " BDB_UCTYPE " database\n" );
-
-       /* allocate backend-database-specific stuff */
-       bdb = (struct bdb_info *) ch_calloc( 1, sizeof(struct bdb_info) );
-
-       /* DBEnv parameters */
-       bdb->bi_dbenv_home = ch_strdup( SLAPD_DEFAULT_DB_DIR );
-       bdb->bi_dbenv_xflags = DB_TIME_NOTGRANTED;
-       bdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE;
-
-       bdb->bi_cache.c_maxsize = DEFAULT_CACHE_SIZE;
-       bdb->bi_cache.c_minfree = 1;
-
-       bdb->bi_lock_detect = DB_LOCK_DEFAULT;
-       bdb->bi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH;
-       bdb->bi_search_stack = NULL;
-
-       ldap_pvt_thread_mutex_init( &bdb->bi_database_mutex );
-       ldap_pvt_thread_mutex_init( &bdb->bi_lastid_mutex );
-#ifdef BDB_HIER
-       ldap_pvt_thread_mutex_init( &bdb->bi_modrdns_mutex );
-#endif
-       ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_lru_mutex );
-       ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_count_mutex );
-       ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_eifree_mutex );
-       ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_dntree.bei_kids_mutex );
-       ldap_pvt_thread_rdwr_init ( &bdb->bi_cache.c_rwlock );
-       ldap_pvt_thread_rdwr_init( &bdb->bi_idl_tree_rwlock );
-       ldap_pvt_thread_mutex_init( &bdb->bi_idl_tree_lrulock );
-
-       be->be_private = bdb;
-       be->be_cf_ocs = be->bd_info->bi_cf_ocs;
-
-#ifndef BDB_MULTIPLE_SUFFIXES
-       SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_ONE_SUFFIX;
-#endif
-
-       rc = bdb_monitor_db_init( be );
-
-       return rc;
-}
-
-static int
-bdb_db_close( BackendDB *be, ConfigReply *cr );
-
-static int
-bdb_db_open( BackendDB *be, ConfigReply *cr )
-{
-       int rc, i;
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       struct stat stat1, stat2;
-       u_int32_t flags;
-       char path[MAXPATHLEN];
-       char *dbhome;
-       Entry *e = NULL;
-       int do_recover = 0, do_alock_recover = 0;
-       int alockt, quick = 0;
-       int do_retry = 1;
-
-       if ( be->be_suffix == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": need suffix.\n" );
-               return -1;
-       }
-
-       Debug( LDAP_DEBUG_ARGS,
-               LDAP_XSTRING(bdb_db_open) ": \"%s\"\n",
-               be->be_suffix[0].bv_val );
-
-       /* Check existence of dbenv_home. Any error means trouble */
-       rc = stat( bdb->bi_dbenv_home, &stat1 );
-       if( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-                       "cannot access database directory \"%s\" (%d).\n",
-                       be->be_suffix[0].bv_val, bdb->bi_dbenv_home, errno );
-               return -1;
-       }
-
-       /* Perform database use arbitration/recovery logic */
-       alockt = (slapMode & SLAP_TOOL_READONLY) ? ALOCK_LOCKED : ALOCK_UNIQUE;
-       if ( slapMode & SLAP_TOOL_QUICK ) {
-               alockt |= ALOCK_NOSAVE;
-               quick = 1;
-       }
-
-       rc = alock_open( &bdb->bi_alock_info, 
-                               "slapd", 
-                               bdb->bi_dbenv_home, alockt );
-
-       /* alockt is TRUE if the existing environment was created in Quick mode */
-       alockt = (rc & ALOCK_NOSAVE) ? 1 : 0;
-       rc &= ~ALOCK_NOSAVE;
-
-       if( rc == ALOCK_RECOVER ) {
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-                       "unclean shutdown detected; attempting recovery.\n", 
-                       be->be_suffix[0].bv_val );
-               do_alock_recover = 1;
-               do_recover = DB_RECOVER;
-       } else if( rc == ALOCK_BUSY ) {
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-                       "database already in use.\n", 
-                       be->be_suffix[0].bv_val );
-               return -1;
-       } else if( rc != ALOCK_CLEAN ) {
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-                       "alock package is unstable.\n", 
-                       be->be_suffix[0].bv_val );
-               return -1;
-       }
-       if ( rc == ALOCK_CLEAN )
-               be->be_flags |= SLAP_DBFLAG_CLEAN;
-
-       /*
-        * The DB_CONFIG file may have changed. If so, recover the
-        * database so that new settings are put into effect. Also
-        * note the possible absence of DB_CONFIG in the log.
-        */
-       if( stat( bdb->bi_db_config_path, &stat1 ) == 0 ) {
-               if ( !do_recover ) {
-                       char *ptr = lutil_strcopy(path, bdb->bi_dbenv_home);
-                       *ptr++ = LDAP_DIRSEP[0];
-                       strcpy( ptr, "__db.001" );
-                       if( stat( path, &stat2 ) == 0 ) {
-                               if( stat2.st_mtime < stat1.st_mtime ) {
-                                       Debug( LDAP_DEBUG_ANY,
-                                               LDAP_XSTRING(bdb_db_open) ": DB_CONFIG for suffix \"%s\" has changed.\n",
-                                                       be->be_suffix[0].bv_val );
-                                       if ( quick ) {
-                                               Debug( LDAP_DEBUG_ANY,
-                                                       "Cannot use Quick mode; perform manual recovery first.\n" );
-                                               slapMode ^= SLAP_TOOL_QUICK;
-                                               rc = -1;
-                                               goto fail;
-                                       } else {
-                                               Debug( LDAP_DEBUG_ANY,
-                                                       "Performing database recovery to activate new settings.\n" );
-                                       }
-                                       do_recover = DB_RECOVER;
-                               }
-                       }
-               }
-       }
-       else {
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": warning - no DB_CONFIG file found "
-                       "in directory %s: (%d).\n"
-                       "Expect poor performance for suffix \"%s\".\n",
-                       bdb->bi_dbenv_home, errno, be->be_suffix[0].bv_val );
-       }
-
-       /* Always let slapcat run, regardless of environment state.
-        * This can be used to cause a cache flush after an unclean
-        * shutdown.
-        */
-       if ( do_recover && ( slapMode & SLAP_TOOL_READONLY )) {
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-                       "recovery skipped in read-only mode. "
-                       "Run manual recovery if errors are encountered.\n",
-                       be->be_suffix[0].bv_val );
-               do_recover = 0;
-               do_alock_recover = 0;
-               quick = alockt;
-       }
-
-       /* An existing environment in Quick mode has nothing to recover. */
-       if ( alockt && do_recover ) {
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-                       "cannot recover, database must be reinitialized.\n", 
-                       be->be_suffix[0].bv_val );
-               rc = -1;
-               goto fail;
-       }
-
-       rc = db_env_create( &bdb->bi_dbenv, 0 );
-       if( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-                       "db_env_create failed: %s (%d).\n",
-                       be->be_suffix[0].bv_val, db_strerror(rc), rc );
-               goto fail;
-       }
-
-#ifdef HAVE_EBCDIC
-       strcpy( path, bdb->bi_dbenv_home );
-       __atoe( path );
-       dbhome = path;
-#else
-       dbhome = bdb->bi_dbenv_home;
-#endif
-
-       /* If existing environment is clean but doesn't support
-        * currently requested modes, remove it.
-        */
-       if ( !do_recover && ( alockt ^ quick )) {
-shm_retry:
-               rc = bdb->bi_dbenv->remove( bdb->bi_dbenv, dbhome, DB_FORCE );
-               if ( rc ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-                               "dbenv remove failed: %s (%d).\n",
-                               be->be_suffix[0].bv_val, db_strerror(rc), rc );
-                       bdb->bi_dbenv = NULL;
-                       goto fail;
-               }
-               rc = db_env_create( &bdb->bi_dbenv, 0 );
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-                               "db_env_create failed: %s (%d).\n",
-                               be->be_suffix[0].bv_val, db_strerror(rc), rc );
-                       goto fail;
-               }
-       }
-
-       bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val );
-       bdb->bi_dbenv->set_errcall( bdb->bi_dbenv, bdb_errcall );
-
-       bdb->bi_dbenv->set_lk_detect( bdb->bi_dbenv, bdb->bi_lock_detect );
-
-       if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
-               rc = bdb->bi_dbenv->set_encrypt( bdb->bi_dbenv, bdb->bi_db_crypt_key.bv_val,
-                       DB_ENCRYPT_AES );
-               if ( rc ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-                               "dbenv set_encrypt failed: %s (%d).\n",
-                               be->be_suffix[0].bv_val, db_strerror(rc), rc );
-                       goto fail;
-               }
-       }
-
-       /* One long-lived TXN per thread, two TXNs per write op */
-       bdb->bi_dbenv->set_tx_max( bdb->bi_dbenv, connection_pool_max * 3 );
-
-       if( bdb->bi_dbenv_xflags != 0 ) {
-               rc = bdb->bi_dbenv->set_flags( bdb->bi_dbenv,
-                       bdb->bi_dbenv_xflags, 1);
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-                               "dbenv_set_flags failed: %s (%d).\n",
-                               be->be_suffix[0].bv_val, db_strerror(rc), rc );
-                       goto fail;
-               }
-       }
-
-#define        BDB_TXN_FLAGS   (DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN)
-
-       Debug( LDAP_DEBUG_TRACE,
-               LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
-               "dbenv_open(%s).\n",
-               be->be_suffix[0].bv_val, bdb->bi_dbenv_home );
-
-       flags = DB_INIT_MPOOL | DB_CREATE | DB_THREAD;
-
-       if ( !quick )
-               flags |= BDB_TXN_FLAGS;
-
-       /* If a key was set, use shared memory for the BDB environment */
-       if ( bdb->bi_shm_key ) {
-               bdb->bi_dbenv->set_shm_key( bdb->bi_dbenv, bdb->bi_shm_key );
-               flags |= DB_SYSTEM_MEM;
-       }
-       rc = (bdb->bi_dbenv->open)( bdb->bi_dbenv, dbhome,
-                       flags | do_recover, bdb->bi_dbenv_mode );
-
-       if ( rc ) {
-               /* Regular open failed, probably a missing shm environment.
-                * Start over, do a recovery.
-                */
-               if ( !do_recover && bdb->bi_shm_key && do_retry ) {
-                       bdb->bi_dbenv->close( bdb->bi_dbenv, 0 );
-                       rc = db_env_create( &bdb->bi_dbenv, 0 );
-                       if( rc == 0 ) {
-                               Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_db_open)
-                                       ": database \"%s\": "
-                                       "shared memory env open failed, assuming stale env.\n",
-                                       be->be_suffix[0].bv_val );
-                               do_retry = 0;
-                               goto shm_retry;
-                       }
-               }
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": database \"%s\" cannot be %s, err %d. "
-                       "Restore from backup!\n",
-                       be->be_suffix[0].bv_val, do_recover ? "recovered" : "opened", rc );
-               goto fail;
-       }
-
-       if ( do_alock_recover && alock_recover (&bdb->bi_alock_info) != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": database \"%s\": alock_recover failed\n",
-                       be->be_suffix[0].bv_val );
-               rc = -1;
-               goto fail;
-       }
-
-#ifdef SLAP_ZONE_ALLOC
-       if ( bdb->bi_cache.c_maxsize ) {
-               bdb->bi_cache.c_zctx = slap_zn_mem_create(
-                       SLAP_ZONE_INITSIZE, SLAP_ZONE_MAXSIZE,
-                       SLAP_ZONE_DELTA, SLAP_ZONE_SIZE);
-       }
-#endif
-
-       /* dncache defaults to 0 == unlimited
-        * must be >= entrycache
-        */
-       if ( bdb->bi_cache.c_eimax && bdb->bi_cache.c_eimax < bdb->bi_cache.c_maxsize ) {
-               bdb->bi_cache.c_eimax = bdb->bi_cache.c_maxsize;
-       }
-
-       if ( bdb->bi_idl_cache_max_size ) {
-               bdb->bi_idl_tree = NULL;
-               bdb->bi_idl_cache_size = 0;
-       }
-
-       flags = DB_THREAD | bdb->bi_db_opflags;
-
-#ifdef DB_AUTO_COMMIT
-       if ( !quick )
-               flags |= DB_AUTO_COMMIT;
-#endif
-
-       bdb->bi_databases = (struct bdb_db_info **) ch_malloc(
-               BDB_INDICES * sizeof(struct bdb_db_info *) );
-
-       /* open (and create) main database */
-       for( i = 0; bdbi_databases[i].name.bv_val; i++ ) {
-               struct bdb_db_info *db;
-
-               db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info));
-
-               rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 );
-               if( rc != 0 ) {
-                       snprintf(cr->msg, sizeof(cr->msg),
-                               "database \"%s\": db_create(%s) failed: %s (%d).",
-                               be->be_suffix[0].bv_val, 
-                               bdb->bi_dbenv_home, db_strerror(rc), rc );
-                       Debug( LDAP_DEBUG_ANY,
-                               LDAP_XSTRING(bdb_db_open) ": %s\n",
-                               cr->msg );
-                       ch_free( db );
-                       goto fail;
-               }
-
-               if( !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
-                       rc = db->bdi_db->set_flags( db->bdi_db, DB_ENCRYPT );
-                       if ( rc ) {
-                               snprintf(cr->msg, sizeof(cr->msg),
-                                       "database \"%s\": db set_flags(DB_ENCRYPT)(%s) failed: %s (%d).",
-                                       be->be_suffix[0].bv_val, 
-                                       bdb->bi_dbenv_home, db_strerror(rc), rc );
-                               Debug( LDAP_DEBUG_ANY,
-                                       LDAP_XSTRING(bdb_db_open) ": %s\n",
-                                       cr->msg );
-                               db->bdi_db->close( db->bdi_db, 0 );
-                               ch_free( db );
-                               goto fail;
-                       }
-               }
-
-               if( bdb->bi_flags & BDB_CHKSUM ) {
-                       rc = db->bdi_db->set_flags( db->bdi_db, DB_CHKSUM );
-                       if ( rc ) {
-                               snprintf(cr->msg, sizeof(cr->msg),
-                                       "database \"%s\": db set_flags(DB_CHKSUM)(%s) failed: %s (%d).",
-                                       be->be_suffix[0].bv_val, 
-                                       bdb->bi_dbenv_home, db_strerror(rc), rc );
-                               Debug( LDAP_DEBUG_ANY,
-                                       LDAP_XSTRING(bdb_db_open) ": %s\n",
-                                       cr->msg );
-                               db->bdi_db->close( db->bdi_db, 0 );
-                               ch_free( db );
-                               goto fail;
-                       }
-               }
-
-               rc = bdb_db_findsize( bdb, (struct berval *)&bdbi_databases[i].name );
-
-               if( i == BDB_ID2ENTRY ) {
-                       if ( !rc ) rc = BDB_ID2ENTRY_PAGESIZE;
-                       rc = db->bdi_db->set_pagesize( db->bdi_db, rc );
-
-                       if ( slapMode & SLAP_TOOL_MODE )
-                               db->bdi_db->mpf->set_priority( db->bdi_db->mpf,
-                                       DB_PRIORITY_VERY_LOW );
-
-                       if ( slapMode & SLAP_TOOL_READMAIN ) {
-                               flags |= DB_RDONLY;
-                       } else {
-                               flags |= DB_CREATE;
-                       }
-               } else {
-                       /* Use FS default size if not configured */
-                       if ( rc )
-                               rc = db->bdi_db->set_pagesize( db->bdi_db, rc );
-
-                       rc = db->bdi_db->set_flags( db->bdi_db, 
-                               DB_DUP | DB_DUPSORT );
-#ifndef BDB_HIER
-                       if ( slapMode & SLAP_TOOL_READONLY ) {
-                               flags |= DB_RDONLY;
-                       } else {
-                               flags |= DB_CREATE;
-                       }
-#else
-                       rc = db->bdi_db->set_dup_compare( db->bdi_db,
-                               bdb_dup_compare );
-                       if ( slapMode & (SLAP_TOOL_READONLY|SLAP_TOOL_READMAIN) ) {
-                               flags |= DB_RDONLY;
-                       } else {
-                               flags |= DB_CREATE;
-                       }
-#endif
-               }
-
-#ifdef HAVE_EBCDIC
-               strcpy( path, bdbi_databases[i].file );
-               __atoe( path );
-               rc = DB_OPEN( db->bdi_db,
-                       path,
-               /*      bdbi_databases[i].name, */ NULL,
-                       bdbi_databases[i].type,
-                       bdbi_databases[i].flags | flags,
-                       bdb->bi_dbenv_mode );
-#else
-               rc = DB_OPEN( db->bdi_db,
-                       bdbi_databases[i].file,
-               /*      bdbi_databases[i].name, */ NULL,
-                       bdbi_databases[i].type,
-                       bdbi_databases[i].flags | flags,
-                       bdb->bi_dbenv_mode );
-#endif
-
-               if ( rc != 0 ) {
-                       snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": "
-                               "db_open(%s/%s) failed: %s (%d).", 
-                               be->be_suffix[0].bv_val, 
-                               bdb->bi_dbenv_home, bdbi_databases[i].file,
-                               db_strerror(rc), rc );
-                       Debug( LDAP_DEBUG_ANY,
-                               LDAP_XSTRING(bdb_db_open) ": %s\n",
-                               cr->msg );
-                       db->bdi_db->close( db->bdi_db, 0 );
-                       ch_free( db );
-                       goto fail;
-               }
-
-               flags &= ~(DB_CREATE | DB_RDONLY);
-               db->bdi_name = bdbi_databases[i].name;
-               bdb->bi_databases[i] = db;
-       }
-
-       bdb->bi_databases[i] = NULL;
-       bdb->bi_ndatabases = i;
-
-       /* get nextid */
-       rc = bdb_last_id( be, NULL );
-       if( rc != 0 ) {
-               snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": "
-                       "last_id(%s) failed: %s (%d).",
-                       be->be_suffix[0].bv_val, bdb->bi_dbenv_home,
-                       db_strerror(rc), rc );
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_db_open) ": %s\n",
-                       cr->msg );
-               goto fail;
-       }
-
-       if ( !quick ) {
-               int txflag = DB_READ_COMMITTED;
-               /* avoid deadlocks in server; tools should
-                * wait since they have no deadlock retry mechanism.
-                */
-               if ( slapMode & SLAP_SERVER_MODE )
-                       txflag |= DB_TXN_NOWAIT;
-               TXN_BEGIN(bdb->bi_dbenv, NULL, &bdb->bi_cache.c_txn, txflag);
-       }
-
-       entry_prealloc( bdb->bi_cache.c_maxsize );
-       attr_prealloc( bdb->bi_cache.c_maxsize * 20 );
-
-       /* setup for empty-DN contexts */
-       if ( BER_BVISEMPTY( &be->be_nsuffix[0] )) {
-               rc = bdb_id2entry( be, NULL, 0, &e );
-       }
-       if ( !e ) {
-               struct berval gluebv = BER_BVC("glue");
-               Operation op = {0};
-               Opheader ohdr = {0};
-               e = entry_alloc();
-               e->e_id = 0;
-               ber_dupbv( &e->e_name, (struct berval *)&slap_empty_bv );
-               ber_dupbv( &e->e_nname, (struct berval *)&slap_empty_bv );
-               attr_merge_one( e, slap_schema.si_ad_objectClass,
-                       &gluebv, NULL );
-               attr_merge_one( e, slap_schema.si_ad_structuralObjectClass,
-                       &gluebv, NULL );
-               op.o_hdr = &ohdr;
-               op.o_bd = be;
-               op.ora_e = e;
-               op.o_dn = be->be_rootdn;
-               op.o_ndn = be->be_rootndn;
-               slap_add_opattrs( &op, NULL, NULL, 0, 0 );
-       }
-       e->e_ocflags = SLAP_OC_GLUE|SLAP_OC__END;
-       e->e_private = &bdb->bi_cache.c_dntree;
-       bdb->bi_cache.c_dntree.bei_e = e;
-
-       /* monitor setup */
-       rc = bdb_monitor_db_open( be );
-       if ( rc != 0 ) {
-               goto fail;
-       }
-
-       bdb->bi_flags |= BDB_IS_OPEN;
-
-       return 0;
-
-fail:
-       bdb_db_close( be, NULL );
-       return rc;
-}
-
-static int
-bdb_db_close( BackendDB *be, ConfigReply *cr )
-{
-       int rc;
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       struct bdb_db_info *db;
-       bdb_idl_cache_entry_t *entry, *next_entry;
-
-       /* monitor handling */
-       (void)bdb_monitor_db_close( be );
-
-       {
-               Entry *e = bdb->bi_cache.c_dntree.bei_e;
-               if ( e ) {
-                       bdb->bi_cache.c_dntree.bei_e = NULL;
-                       e->e_private = NULL;
-                       bdb_entry_return( e );
-               }
-       }
-
-       bdb->bi_flags &= ~BDB_IS_OPEN;
-
-       ber_bvarray_free( bdb->bi_db_config );
-       bdb->bi_db_config = NULL;
-
-       if( bdb->bi_dbenv ) {
-               /* Free cache locker if we enabled locking.
-                * TXNs must all be closed before DBs...
-                */
-               if ( !( slapMode & SLAP_TOOL_QUICK ) && bdb->bi_cache.c_txn ) {
-                       TXN_ABORT( bdb->bi_cache.c_txn );
-                       bdb->bi_cache.c_txn = NULL;
-               }
-               bdb_reader_flush( bdb->bi_dbenv );
-       }
-
-       while( bdb->bi_databases && bdb->bi_ndatabases-- ) {
-               db = bdb->bi_databases[bdb->bi_ndatabases];
-               rc = db->bdi_db->close( db->bdi_db, 0 );
-               /* Lower numbered names are not strdup'd */
-               if( bdb->bi_ndatabases >= BDB_NDB )
-                       free( db->bdi_name.bv_val );
-               free( db );
-       }
-       free( bdb->bi_databases );
-       bdb->bi_databases = NULL;
-
-       bdb_cache_release_all (&bdb->bi_cache);
-
-       if ( bdb->bi_idl_cache_size ) {
-               avl_free( bdb->bi_idl_tree, NULL );
-               bdb->bi_idl_tree = NULL;
-               entry = bdb->bi_idl_lru_head;
-               do {
-                       next_entry = entry->idl_lru_next;
-                       if ( entry->idl )
-                               free( entry->idl );
-                       free( entry->kstr.bv_val );
-                       free( entry );
-                       entry = next_entry;
-               } while ( entry != bdb->bi_idl_lru_head );
-               bdb->bi_idl_lru_head = bdb->bi_idl_lru_tail = NULL;
-       }
-
-       /* close db environment */
-       if( bdb->bi_dbenv ) {
-               /* force a checkpoint, but not if we were ReadOnly,
-                * and not in Quick mode since there are no transactions there.
-                */
-               if ( !( slapMode & ( SLAP_TOOL_QUICK|SLAP_TOOL_READONLY ))) {
-                       rc = TXN_CHECKPOINT( bdb->bi_dbenv, 0, 0, DB_FORCE );
-                       if( rc != 0 ) {
-                               Debug( LDAP_DEBUG_ANY,
-                                       "bdb_db_close: database \"%s\": "
-                                       "txn_checkpoint failed: %s (%d).\n",
-                                       be->be_suffix[0].bv_val, db_strerror(rc), rc );
-                       }
-               }
-
-               rc = bdb->bi_dbenv->close( bdb->bi_dbenv, 0 );
-               bdb->bi_dbenv = NULL;
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb_db_close: database \"%s\": "
-                               "close failed: %s (%d)\n",
-                               be->be_suffix[0].bv_val, db_strerror(rc), rc );
-                       return rc;
-               }
-       }
-
-       rc = alock_close( &bdb->bi_alock_info, slapMode & SLAP_TOOL_QUICK );
-       if( rc != 0 ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "bdb_db_close: database \"%s\": alock_close failed\n",
-                       be->be_suffix[0].bv_val );
-               return -1;
-       }
-
-       return 0;
-}
-
-static int
-bdb_db_destroy( BackendDB *be, ConfigReply *cr )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-
-       /* stop and remove checkpoint task */
-       if ( bdb->bi_txn_cp_task ) {
-               struct re_s *re = bdb->bi_txn_cp_task;
-               bdb->bi_txn_cp_task = NULL;
-               ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
-               if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) )
-                       ldap_pvt_runqueue_stoptask( &slapd_rq, re );
-               ldap_pvt_runqueue_remove( &slapd_rq, re );
-               ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
-       }
-
-       /* monitor handling */
-       (void)bdb_monitor_db_destroy( be );
-
-       if( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home );
-       if( bdb->bi_db_config_path ) ch_free( bdb->bi_db_config_path );
-
-       bdb_attr_index_destroy( bdb );
-
-       ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock );
-       ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_lru_mutex );
-       ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_count_mutex );
-       ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_eifree_mutex );
-       ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_dntree.bei_kids_mutex );
-#ifdef BDB_HIER
-       ldap_pvt_thread_mutex_destroy( &bdb->bi_modrdns_mutex );
-#endif
-       ldap_pvt_thread_mutex_destroy( &bdb->bi_lastid_mutex );
-       ldap_pvt_thread_mutex_destroy( &bdb->bi_database_mutex );
-       ldap_pvt_thread_rdwr_destroy( &bdb->bi_idl_tree_rwlock );
-       ldap_pvt_thread_mutex_destroy( &bdb->bi_idl_tree_lrulock );
-
-       ch_free( bdb );
-       be->be_private = NULL;
-
-       return 0;
-}
-
-int
-bdb_back_initialize(
-       BackendInfo     *bi )
-{
-       int rc;
-
-       static char *controls[] = {
-               LDAP_CONTROL_ASSERT,
-               LDAP_CONTROL_MANAGEDSAIT,
-               LDAP_CONTROL_NOOP,
-               LDAP_CONTROL_PAGEDRESULTS,
-               LDAP_CONTROL_PRE_READ,
-               LDAP_CONTROL_POST_READ,
-               LDAP_CONTROL_SUBENTRIES,
-               LDAP_CONTROL_X_PERMISSIVE_MODIFY,
-#ifdef LDAP_X_TXN
-               LDAP_CONTROL_X_TXN_SPEC,
-#endif
-               NULL
-       };
-
-       /* initialize the underlying database system */
-       Debug( LDAP_DEBUG_TRACE,
-               LDAP_XSTRING(bdb_back_initialize) ": initialize " 
-               BDB_UCTYPE " backend\n" );
-
-       bi->bi_flags |=
-               SLAP_BFLAG_INCREMENT |
-               SLAP_BFLAG_SUBENTRIES |
-               SLAP_BFLAG_ALIASES |
-               SLAP_BFLAG_REFERRALS;
-
-       bi->bi_controls = controls;
-
-       {       /* version check */
-               int major, minor, patch, ver;
-               char *version = db_version( &major, &minor, &patch );
-#ifdef HAVE_EBCDIC
-               char v2[1024];
-
-               /* All our stdio does an ASCII to EBCDIC conversion on
-                * the output. Strings from the BDB library are already
-                * in EBCDIC; we have to go back and forth...
-                */
-               strcpy( v2, version );
-               __etoa( v2 );
-               version = v2;
-#endif
-
-               ver = (major << 24) | (minor << 16) | patch;
-               if( ver != DB_VERSION_FULL ) {
-                       /* fail if a versions don't match */
-                       Debug( LDAP_DEBUG_ANY,
-                               LDAP_XSTRING(bdb_back_initialize) ": "
-                               "BDB library version mismatch:"
-                               " expected " DB_VERSION_STRING ","
-                               " got %s\n", version );
-                       return -1;
-               }
-
-               Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_back_initialize)
-                       ": %s\n", version );
-       }
-
-       db_env_set_func_free( ber_memfree );
-       db_env_set_func_malloc( (db_malloc *)ber_memalloc );
-       db_env_set_func_realloc( (db_realloc *)ber_memrealloc );
-#if !defined(NO_THREAD) && DB_VERSION_FULL <= 0x04070000
-       /* This is a no-op on a NO_THREAD build. Leave the default
-        * alone so that BDB will sleep on interprocess conflicts.
-        * Don't bother on BDB 4.7...
-        */
-       db_env_set_func_yield( ldap_pvt_thread_yield );
-#endif
-
-       bi->bi_open = 0;
-       bi->bi_close = 0;
-       bi->bi_config = 0;
-       bi->bi_destroy = 0;
-
-       bi->bi_db_init = bdb_db_init;
-       bi->bi_db_config = config_generic_wrapper;
-       bi->bi_db_open = bdb_db_open;
-       bi->bi_db_close = bdb_db_close;
-       bi->bi_db_destroy = bdb_db_destroy;
-
-       bi->bi_op_add = bdb_add;
-       bi->bi_op_bind = bdb_bind;
-       bi->bi_op_compare = bdb_compare;
-       bi->bi_op_delete = bdb_delete;
-       bi->bi_op_modify = bdb_modify;
-       bi->bi_op_modrdn = bdb_modrdn;
-       bi->bi_op_search = bdb_search;
-
-       bi->bi_op_unbind = 0;
-
-       bi->bi_extended = bdb_extended;
-
-       bi->bi_chk_referrals = bdb_referrals;
-       bi->bi_operational = bdb_operational;
-       bi->bi_has_subordinates = bdb_hasSubordinates;
-       bi->bi_entry_release_rw = bdb_entry_release;
-       bi->bi_entry_get_rw = bdb_entry_get;
-
-       /*
-        * hooks for slap tools
-        */
-       bi->bi_tool_entry_open = bdb_tool_entry_open;
-       bi->bi_tool_entry_close = bdb_tool_entry_close;
-       bi->bi_tool_entry_first = backend_tool_entry_first;
-       bi->bi_tool_entry_first_x = bdb_tool_entry_first_x;
-       bi->bi_tool_entry_next = bdb_tool_entry_next;
-       bi->bi_tool_entry_get = bdb_tool_entry_get;
-       bi->bi_tool_entry_put = bdb_tool_entry_put;
-       bi->bi_tool_entry_reindex = bdb_tool_entry_reindex;
-       bi->bi_tool_sync = 0;
-       bi->bi_tool_dn2id_get = bdb_tool_dn2id_get;
-       bi->bi_tool_entry_modify = bdb_tool_entry_modify;
-       bi->bi_tool_entry_delete = bdb_tool_entry_delete;
-
-       bi->bi_connection_init = 0;
-       bi->bi_connection_destroy = 0;
-
-       rc = bdb_back_init_cf( bi );
-
-       return rc;
-}
-
-#if    (SLAPD_BDB == SLAPD_MOD_DYNAMIC && !defined(BDB_HIER)) || \
-       (SLAPD_HDB == SLAPD_MOD_DYNAMIC && defined(BDB_HIER))
-
-/* conditionally define the init_module() function */
-#ifdef BDB_HIER
-SLAP_BACKEND_INIT_MODULE( hdb )
-#else /* !BDB_HIER */
-SLAP_BACKEND_INIT_MODULE( bdb )
-#endif /* !BDB_HIER */
-
-#endif /* SLAPD_[BH]DB == SLAPD_MOD_DYNAMIC */
-
diff --git a/servers/slapd/back-bdb/key.c b/servers/slapd/back-bdb/key.c
deleted file mode 100644 (file)
index b0acd0d..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/* index.c - routines for dealing with attribute indexes */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb.h"
-#include "idl.h"
-
-/* read a key */
-int
-bdb_key_read(
-       Backend *be,
-       DB *db,
-       DB_TXN *txn,
-       struct berval *k,
-       ID *ids,
-       DBC **saved_cursor,
-       int get_flag
-)
-{
-       int rc;
-       DBT key;
-
-       Debug( LDAP_DEBUG_TRACE, "=> key_read\n" );
-
-       DBTzero( &key );
-       bv2DBT(k,&key);
-       key.ulen = key.size;
-       key.flags = DB_DBT_USERMEM;
-
-       rc = bdb_idl_fetch_key( be, db, txn, &key, ids, saved_cursor, get_flag );
-
-       if( rc != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE, "<= bdb_index_read: failed (%d)\n",
-                       rc );
-       } else {
-               Debug( LDAP_DEBUG_TRACE, "<= bdb_index_read %ld candidates\n",
-                       (long) BDB_IDL_N(ids) );
-       }
-
-       return rc;
-}
-
-/* Add or remove stuff from index files */
-int
-bdb_key_change(
-       Backend *be,
-       DB *db,
-       DB_TXN *txn,
-       struct berval *k,
-       ID id,
-       int op
-)
-{
-       int     rc;
-       DBT     key;
-
-       Debug( LDAP_DEBUG_TRACE, "=> key_change(%s,%lx)\n",
-               op == SLAP_INDEX_ADD_OP ? "ADD":"DELETE", (long) id );
-
-       DBTzero( &key );
-       bv2DBT(k,&key);
-       key.ulen = key.size;
-       key.flags = DB_DBT_USERMEM;
-
-       if (op == SLAP_INDEX_ADD_OP) {
-               /* Add values */
-
-#ifdef BDB_TOOL_IDL_CACHING
-               if ( slapMode & SLAP_TOOL_QUICK )
-                       rc = bdb_tool_idl_add( be, db, txn, &key, id );
-               else
-#endif
-                       rc = bdb_idl_insert_key( be, db, txn, &key, id );
-               if ( rc == DB_KEYEXIST ) rc = 0;
-       } else {
-               /* Delete values */
-               rc = bdb_idl_delete_key( be, db, txn, &key, id );
-               if ( rc == DB_NOTFOUND ) rc = 0;
-       }
-
-       Debug( LDAP_DEBUG_TRACE, "<= key_change %d\n", rc );
-
-       return rc;
-}
diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c
deleted file mode 100644 (file)
index 536aab3..0000000
+++ /dev/null
@@ -1,801 +0,0 @@
-/* modify.c - bdb backend modify routine */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-#include <ac/time.h>
-
-#include "back-bdb.h"
-
-static struct berval scbva[] = {
-       BER_BVC("glue"),
-       BER_BVNULL
-};
-
-static void
-bdb_modify_idxflags(
-       Operation *op,
-       AttributeDescription *desc,
-       int got_delete,
-       Attribute *newattrs,
-       Attribute *oldattrs )
-{
-       struct berval   ix_at;
-       AttrInfo        *ai;
-
-       /* check if modified attribute was indexed
-        * but not in case of NOOP... */
-       ai = bdb_index_mask( op->o_bd, desc, &ix_at );
-       if ( ai ) {
-               if ( got_delete ) {
-                       Attribute       *ap;
-                       struct berval   ix2;
-
-                       ap = attr_find( oldattrs, desc );
-                       if ( ap ) ap->a_flags |= SLAP_ATTR_IXDEL;
-
-                       /* Find all other attrs that index to same slot */
-                       for ( ap = newattrs; ap; ap = ap->a_next ) {
-                               ai = bdb_index_mask( op->o_bd, ap->a_desc, &ix2 );
-                               if ( ai && ix2.bv_val == ix_at.bv_val )
-                                       ap->a_flags |= SLAP_ATTR_IXADD;
-                       }
-
-               } else {
-                       Attribute       *ap;
-
-                       ap = attr_find( newattrs, desc );
-                       if ( ap ) ap->a_flags |= SLAP_ATTR_IXADD;
-               }
-       }
-}
-
-int bdb_modify_internal(
-       Operation *op,
-       DB_TXN *tid,
-       Modifications *modlist,
-       Entry *e,
-       const char **text,
-       char *textbuf,
-       size_t textlen )
-{
-       int rc, err;
-       Modification    *mod;
-       Modifications   *ml;
-       Attribute       *save_attrs;
-       Attribute       *ap;
-       int                     glue_attr_delete = 0;
-       int                     got_delete;
-
-       Debug( LDAP_DEBUG_TRACE, "bdb_modify_internal: 0x%08lx: %s\n",
-               e->e_id, e->e_dn );
-
-       if ( !acl_check_modlist( op, e, modlist )) {
-               return LDAP_INSUFFICIENT_ACCESS;
-       }
-
-       /* save_attrs will be disposed of by bdb_cache_modify */
-       save_attrs = e->e_attrs;
-       e->e_attrs = attrs_dup( e->e_attrs );
-
-       for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
-               int match;
-               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 ) {
-                               value_match( &match, slap_schema.si_ad_structuralObjectClass,
-                                       slap_schema.si_ad_structuralObjectClass->
-                                               ad_type->sat_equality,
-                                       SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
-                                       &mod->sm_values[0], &scbva[0], text );
-                               if ( !match ) 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;
-               got_delete = 0;
-
-               switch ( mod->sm_op ) {
-               case LDAP_MOD_ADD:
-                       Debug(LDAP_DEBUG_ARGS,
-                               "bdb_modify_internal: add %s\n",
-                               mod->sm_desc->ad_cname.bv_val );
-                       err = modify_add_values( e, mod, get_permissiveModify(op),
-                               text, textbuf, textlen );
-                       if( err != LDAP_SUCCESS ) {
-                               Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n",
-                                       err, *text );
-                       }
-                       break;
-
-               case LDAP_MOD_DELETE:
-                       if ( glue_attr_delete ) {
-                               err = LDAP_SUCCESS;
-                               break;
-                       }
-
-                       Debug(LDAP_DEBUG_ARGS,
-                               "bdb_modify_internal: delete %s\n",
-                               mod->sm_desc->ad_cname.bv_val );
-                       err = modify_delete_values( e, mod, get_permissiveModify(op),
-                               text, textbuf, textlen );
-                       if( err != LDAP_SUCCESS ) {
-                               Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n",
-                                       err, *text );
-                       } else {
-                               got_delete = 1;
-                       }
-                       break;
-
-               case LDAP_MOD_REPLACE:
-                       Debug(LDAP_DEBUG_ARGS,
-                               "bdb_modify_internal: replace %s\n",
-                               mod->sm_desc->ad_cname.bv_val );
-                       err = modify_replace_values( e, mod, get_permissiveModify(op),
-                               text, textbuf, textlen );
-                       if( err != LDAP_SUCCESS ) {
-                               Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n",
-                                       err, *text );
-                       } else {
-                               got_delete = 1;
-                       }
-                       break;
-
-               case LDAP_MOD_INCREMENT:
-                       Debug(LDAP_DEBUG_ARGS,
-                               "bdb_modify_internal: increment %s\n",
-                               mod->sm_desc->ad_cname.bv_val );
-                       err = modify_increment_values( e, mod, get_permissiveModify(op),
-                               text, textbuf, textlen );
-                       if( err != LDAP_SUCCESS ) {
-                               Debug(LDAP_DEBUG_ARGS,
-                                       "bdb_modify_internal: %d %s\n",
-                                       err, *text );
-                       } else {
-                               got_delete = 1;
-                       }
-                       break;
-
-               case SLAP_MOD_SOFTADD:
-                       Debug(LDAP_DEBUG_ARGS,
-                               "bdb_modify_internal: softadd %s\n",
-                               mod->sm_desc->ad_cname.bv_val );
-                       /* Avoid problems in index_add_mods()
-                        * We need to add index if necessary.
-                        */
-                       mod->sm_op = LDAP_MOD_ADD;
-
-                       err = modify_add_values( e, mod, get_permissiveModify(op),
-                               text, textbuf, textlen );
-
-                       mod->sm_op = SLAP_MOD_SOFTADD;
-
-                       if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) {
-                               err = LDAP_SUCCESS;
-                       }
-
-                       if( err != LDAP_SUCCESS ) {
-                               Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n",
-                                       err, *text );
-                       }
-                       break;
-
-               case SLAP_MOD_SOFTDEL:
-                       Debug(LDAP_DEBUG_ARGS,
-                               "bdb_modify_internal: softdel %s\n",
-                               mod->sm_desc->ad_cname.bv_val );
-                       /* Avoid problems in index_delete_mods()
-                        * We need to add index if necessary.
-                        */
-                       mod->sm_op = LDAP_MOD_DELETE;
-
-                       err = modify_delete_values( e, mod, get_permissiveModify(op),
-                               text, textbuf, textlen );
-
-                       mod->sm_op = SLAP_MOD_SOFTDEL;
-
-                       if ( err == LDAP_SUCCESS ) {
-                               got_delete = 1;
-                       } else if ( err == LDAP_NO_SUCH_ATTRIBUTE ) {
-                               err = LDAP_SUCCESS;
-                       }
-
-                       if( err != LDAP_SUCCESS ) {
-                               Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n",
-                                       err, *text );
-                       }
-                       break;
-
-               case SLAP_MOD_ADD_IF_NOT_PRESENT:
-                       if ( attr_find( e->e_attrs, mod->sm_desc ) != NULL ) {
-                               /* skip */
-                               err = LDAP_SUCCESS;
-                               break;
-                       }
-
-                       Debug(LDAP_DEBUG_ARGS,
-                               "bdb_modify_internal: add_if_not_present %s\n",
-                               mod->sm_desc->ad_cname.bv_val );
-                       /* Avoid problems in index_add_mods()
-                        * We need to add index if necessary.
-                        */
-                       mod->sm_op = LDAP_MOD_ADD;
-
-                       err = modify_add_values( e, mod, get_permissiveModify(op),
-                               text, textbuf, textlen );
-
-                       mod->sm_op = SLAP_MOD_ADD_IF_NOT_PRESENT;
-
-                       if( err != LDAP_SUCCESS ) {
-                               Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n",
-                                       err, *text );
-                       }
-                       break;
-
-               default:
-                       Debug(LDAP_DEBUG_ANY, "bdb_modify_internal: invalid op %d\n",
-                               mod->sm_op );
-                       *text = "Invalid modify operation";
-                       err = LDAP_OTHER;
-                       Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n",
-                               err, *text );
-               }
-
-               if ( err != LDAP_SUCCESS ) {
-                       attrs_free( e->e_attrs );
-                       e->e_attrs = save_attrs;
-                       /* unlock entry, delete from cache */
-                       return err; 
-               }
-
-               /* If objectClass was modified, reset the flags */
-               if ( mod->sm_desc == slap_schema.si_ad_objectClass ) {
-                       e->e_ocflags = 0;
-               }
-
-               if ( glue_attr_delete ) e->e_ocflags = 0;
-
-
-               /* check if modified attribute was indexed
-                * but not in case of NOOP... */
-               if ( !op->o_noop ) {
-                       bdb_modify_idxflags( op, mod->sm_desc, got_delete, e->e_attrs, save_attrs );
-               }
-       }
-
-       /* check that the entry still obeys the schema */
-       ap = NULL;
-       rc = entry_schema_check( op, e, save_attrs, get_relax(op), 0, &ap,
-               text, textbuf, textlen );
-       if ( rc != LDAP_SUCCESS || op->o_noop ) {
-               attrs_free( e->e_attrs );
-               /* clear the indexing flags */
-               for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) {
-                       ap->a_flags &= ~(SLAP_ATTR_IXADD|SLAP_ATTR_IXDEL);
-               }
-               e->e_attrs = save_attrs;
-
-               if ( rc != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "entry failed schema check: %s\n",
-                               *text );
-               }
-
-               /* if NOOP then silently revert to saved attrs */
-               return rc;
-       }
-
-       /* structuralObjectClass modified! */
-       if ( ap ) {
-               assert( ap->a_desc == slap_schema.si_ad_structuralObjectClass );
-               if ( !op->o_noop ) {
-                       bdb_modify_idxflags( op, slap_schema.si_ad_structuralObjectClass,
-                               1, e->e_attrs, save_attrs );
-               }
-       }
-
-       /* update the indices of the modified attributes */
-
-       /* start with deleting the old index entries */
-       for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) {
-               if ( ap->a_flags & SLAP_ATTR_IXDEL ) {
-                       struct berval *vals;
-                       Attribute *a2;
-                       ap->a_flags &= ~SLAP_ATTR_IXDEL;
-                       a2 = attr_find( e->e_attrs, ap->a_desc );
-                       if ( a2 ) {
-                               /* need to detect which values were deleted */
-                               int i, j;
-                               /* let add know there were deletes */
-                               if ( a2->a_flags & SLAP_ATTR_IXADD )
-                                       a2->a_flags |= SLAP_ATTR_IXDEL;
-                               vals = op->o_tmpalloc( (ap->a_numvals + 1) *
-                                       sizeof(struct berval), op->o_tmpmemctx );
-                               j = 0;
-                               for ( i=0; i < ap->a_numvals; i++ ) {
-                                       rc = attr_valfind( a2, SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-                                               &ap->a_nvals[i], NULL, op->o_tmpmemctx );
-                                       /* Save deleted values */
-                                       if ( rc == LDAP_NO_SUCH_ATTRIBUTE )
-                                               vals[j++] = ap->a_nvals[i];
-                               }
-                               BER_BVZERO(vals+j);
-                       } else {
-                               /* attribute was completely deleted */
-                               vals = ap->a_nvals;
-                       }
-                       rc = 0;
-                       if ( !BER_BVISNULL( vals )) {
-                               rc = bdb_index_values( op, tid, ap->a_desc,
-                                       vals, e->e_id, SLAP_INDEX_DELETE_OP );
-                               if ( rc != LDAP_SUCCESS ) {
-                                       Debug( LDAP_DEBUG_ANY,
-                                               "%s: attribute \"%s\" index delete failure\n",
-                                               op->o_log_prefix, ap->a_desc->ad_cname.bv_val );
-                                       attrs_free( e->e_attrs );
-                                       e->e_attrs = save_attrs;
-                               }
-                       }
-                       if ( vals != ap->a_nvals )
-                               op->o_tmpfree( vals, op->o_tmpmemctx );
-                       if ( rc ) return rc;
-               }
-       }
-
-       /* add the new index entries */
-       for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
-               if (ap->a_flags & SLAP_ATTR_IXADD) {
-                       ap->a_flags &= ~SLAP_ATTR_IXADD;
-                       if ( ap->a_flags & SLAP_ATTR_IXDEL ) {
-                               /* if any values were deleted, we must readd index
-                                * for all remaining values.
-                                */
-                               ap->a_flags &= ~SLAP_ATTR_IXDEL;
-                               rc = bdb_index_values( op, tid, ap->a_desc,
-                                       ap->a_nvals,
-                                       e->e_id, SLAP_INDEX_ADD_OP );
-                       } else {
-                               int found = 0;
-                               /* if this was only an add, we only need to index
-                                * the added values.
-                                */
-                               for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
-                                       struct berval *vals;
-                                       if ( ml->sml_desc != ap->a_desc || !ml->sml_numvals )
-                                               continue;
-                                       found = 1;
-                                       switch( ml->sml_op ) {
-                                       case LDAP_MOD_ADD:
-                                       case LDAP_MOD_REPLACE:
-                                       case LDAP_MOD_INCREMENT:
-                                       case SLAP_MOD_SOFTADD:
-                                       case SLAP_MOD_ADD_IF_NOT_PRESENT:
-                                               if ( ml->sml_op == LDAP_MOD_INCREMENT )
-                                                       vals = ap->a_nvals;
-                                               else if ( ml->sml_nvalues )
-                                                       vals = ml->sml_nvalues;
-                                               else
-                                                       vals = ml->sml_values;
-                                               rc = bdb_index_values( op, tid, ap->a_desc,
-                                                       vals, e->e_id, SLAP_INDEX_ADD_OP );
-                                               break;
-                                       }
-                                       if ( rc )
-                                               break;
-                               }
-                               /* This attr was affected by a modify of a subtype, so
-                                * there was no direct match in the modlist. Just readd
-                                * all of its values.
-                                */
-                               if ( !found ) {
-                                       rc = bdb_index_values( op, tid, ap->a_desc,
-                                               ap->a_nvals,
-                                               e->e_id, SLAP_INDEX_ADD_OP );
-                               }
-                       }
-                       if ( rc != LDAP_SUCCESS ) {
-                               Debug( LDAP_DEBUG_ANY,
-                                      "%s: attribute \"%s\" index add failure\n",
-                                       op->o_log_prefix, ap->a_desc->ad_cname.bv_val );
-                               attrs_free( e->e_attrs );
-                               e->e_attrs = save_attrs;
-                               return rc;
-                       }
-               }
-       }
-
-       return rc;
-}
-
-
-int
-bdb_modify( Operation *op, SlapReply *rs )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       Entry           *e = NULL;
-       EntryInfo       *ei = NULL;
-       int             manageDSAit = get_manageDSAit( op );
-       char textbuf[SLAP_TEXT_BUFLEN];
-       size_t textlen = sizeof textbuf;
-       DB_TXN  *ltid = NULL, *lt2;
-       struct bdb_op_info opinfo = {{{ 0 }}};
-       Entry           dummy = {0};
-
-       DB_LOCK         lock;
-
-       int             num_retries = 0;
-
-       LDAPControl **preread_ctrl = NULL;
-       LDAPControl **postread_ctrl = NULL;
-       LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
-       int num_ctrls = 0;
-
-       int rc;
-
-       Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(bdb_modify) ": %s\n",
-               op->o_req_dn.bv_val );
-
-#ifdef LDAP_X_TXN
-       if( op->o_txnSpec && txn_preop( op, rs ))
-               return rs->sr_err;
-#endif
-
-       ctrls[num_ctrls] = NULL;
-
-       /* Don't touch the opattrs, if this is a contextCSN update
-        * initiated from updatedn */
-       if ( !be_isupdate(op) || !op->orm_modlist || op->orm_modlist->sml_next ||
-                op->orm_modlist->sml_desc != slap_schema.si_ad_contextCSN ) {
-
-               slap_mods_opattrs( op, &op->orm_modlist, 1 );
-       }
-
-       if( 0 ) {
-retry: /* transaction retry */
-               if ( dummy.e_attrs ) {
-                       attrs_free( dummy.e_attrs );
-                       dummy.e_attrs = NULL;
-               }
-               if( e != NULL ) {
-                       bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
-                       e = NULL;
-               }
-               Debug(LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modify) ": retrying...\n" );
-
-               rs->sr_err = TXN_ABORT( ltid );
-               ltid = NULL;
-               LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-               opinfo.boi_oe.oe_key = NULL;
-               op->o_do_not_cache = opinfo.boi_acl_cache;
-               if( rs->sr_err != 0 ) {
-                       rs->sr_err = LDAP_OTHER;
-                       rs->sr_text = "internal error";
-                       goto return_results;
-               }
-               if ( op->o_abandon ) {
-                       rs->sr_err = SLAPD_ABANDON;
-                       goto return_results;
-               }
-               bdb_trans_backoff( ++num_retries );
-       }
-
-       /* begin transaction */
-       {
-               int tflags = bdb->bi_db_opflags;
-               if ( get_lazyCommit( op ))
-                       tflags |= DB_TXN_NOSYNC;
-               rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, &ltid, tflags );
-       }
-       rs->sr_text = NULL;
-       if( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modify) ": txn_begin failed: "
-                       "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modify) ": txn1 id: %x\n",
-               ltid->id(ltid) );
-
-       opinfo.boi_oe.oe_key = bdb;
-       opinfo.boi_txn = ltid;
-       opinfo.boi_err = 0;
-       opinfo.boi_acl_cache = op->o_do_not_cache;
-       LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next );
-
-       /* get entry or ancestor */
-       rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1,
-               &lock );
-
-       if ( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modify) ": dn2entry failed (%d)\n",
-                       rs->sr_err );
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               case DB_NOTFOUND:
-                       break;
-               case LDAP_BUSY:
-                       rs->sr_text = "ldap server busy";
-                       goto return_results;
-               default:
-                       rs->sr_err = LDAP_OTHER;
-                       rs->sr_text = "internal error";
-                       goto return_results;
-               }
-       }
-
-       e = ei->bei_e;
-
-       /* acquire and lock entry */
-       /* FIXME: dn2entry() should return non-glue entry */
-       if (( rs->sr_err == DB_NOTFOUND ) ||
-               ( !manageDSAit && e && is_entry_glue( e )))
-       {
-               if ( e != NULL ) {
-                       rs->sr_matched = ch_strdup( e->e_dn );
-                       rs->sr_ref = is_entry_referral( e )
-                               ? get_entry_referrals( op, e )
-                               : NULL;
-                       bdb_unlocked_cache_return_entry_r (&bdb->bi_cache, e);
-                       e = NULL;
-
-               } else {
-                       rs->sr_ref = referral_rewrite( default_referral, NULL,
-                               &op->o_req_dn, LDAP_SCOPE_DEFAULT );
-               }
-
-               rs->sr_err = LDAP_REFERRAL;
-               send_ldap_result( op, rs );
-
-               if ( rs->sr_ref != default_referral ) {
-                       ber_bvarray_free( rs->sr_ref );
-               }
-               free( (char *)rs->sr_matched );
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-
-               goto done;
-       }
-
-       if ( !manageDSAit && is_entry_referral( e ) ) {
-               /* entry is a referral, don't allow modify */
-               rs->sr_ref = get_entry_referrals( op, e );
-
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modify) ": entry is referral\n" );
-
-               rs->sr_err = LDAP_REFERRAL;
-               rs->sr_matched = e->e_name.bv_val;
-               send_ldap_result( op, rs );
-
-               ber_bvarray_free( rs->sr_ref );
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-               goto done;
-       }
-
-       if ( get_assert( op ) &&
-               ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
-       {
-               rs->sr_err = LDAP_ASSERTION_FAILED;
-               goto return_results;
-       }
-
-       if( op->o_preread ) {
-               if( preread_ctrl == NULL ) {
-                       preread_ctrl = &ctrls[num_ctrls++];
-                       ctrls[num_ctrls] = NULL;
-               }
-               if ( slap_read_controls( op, rs, e,
-                       &slap_pre_read_bv, preread_ctrl ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<=- " LDAP_XSTRING(bdb_modify) ": pre-read "
-                               "failed!\n" );
-                       if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
-                               /* FIXME: is it correct to abort
-                                * operation if control fails? */
-                               goto return_results;
-                       }
-               }
-       }
-
-       /* nested transaction */
-       rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, &lt2, bdb->bi_db_opflags );
-       rs->sr_text = NULL;
-       if( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modify) ": txn_begin(2) failed: " "%s (%d)\n",
-                       db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modify) ": txn2 id: %x\n",
-               lt2->id(lt2) );
-       /* Modify the entry */
-       dummy = *e;
-       rs->sr_err = bdb_modify_internal( op, lt2, op->orm_modlist,
-               &dummy, &rs->sr_text, textbuf, textlen );
-
-       if( rs->sr_err != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modify) ": modify failed (%d)\n",
-                       rs->sr_err );
-               if ( (rs->sr_err == LDAP_INSUFFICIENT_ACCESS) && opinfo.boi_err ) {
-                       rs->sr_err = opinfo.boi_err;
-               }
-               /* Only free attrs if they were dup'd.  */
-               if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-               goto return_results;
-       }
-
-       /* change the entry itself */
-       rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, &dummy );
-       if ( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modify) ": id2entry update failed " "(%d)\n",
-                       rs->sr_err );
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-               rs->sr_text = "entry update failed";
-               goto return_results;
-       }
-
-       if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "txn_commit(2) failed";
-               goto return_results;
-       }
-
-       if( op->o_postread ) {
-               if( postread_ctrl == NULL ) {
-                       postread_ctrl = &ctrls[num_ctrls++];
-                       ctrls[num_ctrls] = NULL;
-               }
-               if( slap_read_controls( op, rs, &dummy,
-                       &slap_post_read_bv, postread_ctrl ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE,
-                               "<=- " LDAP_XSTRING(bdb_modify)
-                               ": post-read failed!\n" );
-                       if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
-                               /* FIXME: is it correct to abort
-                                * operation if control fails? */
-                               goto return_results;
-                       }
-               }
-       }
-
-       if( op->o_noop ) {
-               if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) {
-                       rs->sr_text = "txn_abort (no-op) failed";
-               } else {
-                       rs->sr_err = LDAP_X_NO_OPERATION;
-                       ltid = NULL;
-                       /* Only free attrs if they were dup'd.  */
-                       if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
-                       goto return_results;
-               }
-       } else {
-               /* may have changed in bdb_modify_internal() */
-               e->e_ocflags = dummy.e_ocflags;
-               rc = bdb_cache_modify( bdb, e, dummy.e_attrs, ltid, &lock );
-               switch( rc ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-               dummy.e_attrs = NULL;
-
-               rs->sr_err = TXN_COMMIT( ltid, 0 );
-       }
-       ltid = NULL;
-       LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-       opinfo.boi_oe.oe_key = NULL;
-
-       if( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modify) ": txn_%s failed: %s (%d)\n",
-                       op->o_noop ? "abort (no-op)" : "commit",
-                       db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "commit failed";
-
-               goto return_results;
-       }
-
-       Debug( LDAP_DEBUG_TRACE,
-               LDAP_XSTRING(bdb_modify) ": updated%s id=%08lx dn=\"%s\"\n",
-               op->o_noop ? " (no-op)" : "",
-               dummy.e_id, op->o_req_dn.bv_val );
-
-       rs->sr_err = LDAP_SUCCESS;
-       rs->sr_text = NULL;
-       if( num_ctrls ) rs->sr_ctrls = ctrls;
-
-return_results:
-       if( dummy.e_attrs ) {
-               attrs_free( dummy.e_attrs );
-       }
-       send_ldap_result( op, rs );
-
-       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) {
-               TXN_CHECKPOINT( bdb->bi_dbenv,
-                       bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
-       }
-
-done:
-       slap_graduate_commit_csn( op );
-
-       if( ltid != NULL ) {
-               TXN_ABORT( ltid );
-       }
-       if ( opinfo.boi_oe.oe_key ) {
-               LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-       }
-
-       if( e != NULL ) {
-               bdb_unlocked_cache_return_entry_w (&bdb->bi_cache, e);
-       }
-
-       if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
-               slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
-               slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
-       }
-       if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
-               slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
-               slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
-       }
-
-       rs->sr_text = NULL;
-
-       return rs->sr_err;
-}
diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c
deleted file mode 100644 (file)
index 1308075..0000000
+++ /dev/null
@@ -1,800 +0,0 @@
-/* modrdn.c - bdb backend modrdn routine */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-
-int
-bdb_modrdn( Operation  *op, SlapReply *rs )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       AttributeDescription *children = slap_schema.si_ad_children;
-       AttributeDescription *entry = slap_schema.si_ad_entry;
-       struct berval   p_dn, p_ndn;
-       struct berval   new_dn = {0, NULL}, new_ndn = {0, NULL};
-       Entry           *e = NULL;
-       Entry           *p = NULL;
-       EntryInfo       *ei = NULL, *eip = NULL, *nei = NULL, *neip = NULL;
-       /* LDAP v2 supporting correct attribute handling. */
-       char textbuf[SLAP_TEXT_BUFLEN];
-       size_t textlen = sizeof textbuf;
-       DB_TXN          *ltid = NULL, *lt2;
-       struct bdb_op_info opinfo = {{{ 0 }}};
-       Entry dummy = {0};
-
-       Entry           *np = NULL;                     /* newSuperior Entry */
-       struct berval   *np_dn = NULL;                  /* newSuperior dn */
-       struct berval   *np_ndn = NULL;                 /* newSuperior ndn */
-       struct berval   *new_parent_dn = NULL;  /* np_dn, p_dn, or NULL */
-
-       int             manageDSAit = get_manageDSAit( op );
-
-       DB_LOCK         lock, plock, nplock;
-
-       int             num_retries = 0;
-
-       LDAPControl **preread_ctrl = NULL;
-       LDAPControl **postread_ctrl = NULL;
-       LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
-       int num_ctrls = 0;
-
-       int     rc;
-
-       int parent_is_glue = 0;
-       int parent_is_leaf = 0;
-
-       Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn) "(%s,%s,%s)\n",
-               op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val,
-               op->oq_modrdn.rs_newSup ? op->oq_modrdn.rs_newSup->bv_val : "NULL" );
-
-#ifdef LDAP_X_TXN
-       if( op->o_txnSpec && txn_preop( op, rs ))
-               return rs->sr_err;
-#endif
-
-       ctrls[num_ctrls] = NULL;
-
-       slap_mods_opattrs( op, &op->orr_modlist, 1 );
-
-       if( 0 ) {
-retry: /* transaction retry */
-               if ( dummy.e_attrs ) {
-                       if ( dummy.e_attrs != e->e_attrs )
-                               attrs_free( dummy.e_attrs );
-                       dummy.e_attrs = NULL;
-               }
-               if (e != NULL) {
-                       bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
-                       e = NULL;
-               }
-               if (p != NULL) {
-                       bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
-                       p = NULL;
-               }
-               if (np != NULL) {
-                       bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, np);
-                       np = NULL;
-               }
-               Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn)
-                               ": retrying...\n" );
-
-               rs->sr_err = TXN_ABORT( ltid );
-               ltid = NULL;
-               LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-               opinfo.boi_oe.oe_key = NULL;
-               op->o_do_not_cache = opinfo.boi_acl_cache;
-               if( rs->sr_err != 0 ) {
-                       rs->sr_err = LDAP_OTHER;
-                       rs->sr_text = "internal error";
-                       goto return_results;
-               }
-               if ( op->o_abandon ) {
-                       rs->sr_err = SLAPD_ABANDON;
-                       goto return_results;
-               }
-               parent_is_glue = 0;
-               parent_is_leaf = 0;
-               bdb_trans_backoff( ++num_retries );
-       }
-
-       /* begin transaction */
-       {
-               int tflags = bdb->bi_db_opflags;
-               if ( get_lazyCommit( op ))
-                       tflags |= DB_TXN_NOSYNC;
-               rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, &ltid, tflags );
-       }
-       rs->sr_text = NULL;
-       if( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modrdn) ": txn_begin failed: "
-                       "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": txn1 id: %x\n",
-               ltid->id(ltid) );
-
-       opinfo.boi_oe.oe_key = bdb;
-       opinfo.boi_txn = ltid;
-       opinfo.boi_err = 0;
-       opinfo.boi_acl_cache = op->o_do_not_cache;
-       LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next );
-
-       /* get entry */
-       rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1,
-               &lock );
-
-       switch( rs->sr_err ) {
-       case 0:
-       case DB_NOTFOUND:
-               break;
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               goto retry;
-       case LDAP_BUSY:
-               rs->sr_text = "ldap server busy";
-               goto return_results;
-       default:
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-
-       e = ei->bei_e;
-       /* FIXME: dn2entry() should return non-glue entry */
-       if (( rs->sr_err == DB_NOTFOUND ) ||
-               ( !manageDSAit && e && is_entry_glue( e )))
-       {
-               if( e != NULL ) {
-                       rs->sr_matched = ch_strdup( e->e_dn );
-                       rs->sr_ref = is_entry_referral( e )
-                               ? get_entry_referrals( op, e )
-                               : NULL;
-                       bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, e);
-                       e = NULL;
-
-               } else {
-                       rs->sr_ref = referral_rewrite( default_referral, NULL,
-                                       &op->o_req_dn, LDAP_SCOPE_DEFAULT );
-               }
-
-               rs->sr_err = LDAP_REFERRAL;
-               send_ldap_result( op, rs );
-
-               ber_bvarray_free( rs->sr_ref );
-               free( (char *)rs->sr_matched );
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-
-               goto done;
-       }
-
-       if ( get_assert( op ) &&
-               ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
-       {
-               rs->sr_err = LDAP_ASSERTION_FAILED;
-               goto return_results;
-       }
-
-       /* check write on old entry */
-       rs->sr_err = access_allowed( op, e, entry, NULL, ACL_WRITE, NULL );
-       if ( ! rs->sr_err ) {
-               switch( opinfo.boi_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-
-               Debug( LDAP_DEBUG_TRACE, "no access to entry\n" );
-               rs->sr_text = "no write access to old entry";
-               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-               goto return_results;
-       }
-
-#ifndef BDB_HIER
-       rs->sr_err = bdb_cache_children( op, ltid, e );
-       if ( rs->sr_err != DB_NOTFOUND ) {
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               case 0:
-                       Debug(LDAP_DEBUG_ARGS,
-                               "<=- " LDAP_XSTRING(bdb_modrdn)
-                               ": non-leaf %s\n",
-                               op->o_req_dn.bv_val );
-                       rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
-                       rs->sr_text = "subtree rename not supported";
-                       break;
-               default:
-                       Debug(LDAP_DEBUG_ARGS,
-                               "<=- " LDAP_XSTRING(bdb_modrdn)
-                               ": has_children failed: %s (%d)\n",
-                               db_strerror(rs->sr_err), rs->sr_err );
-                       rs->sr_err = LDAP_OTHER;
-                       rs->sr_text = "internal error";
-               }
-               goto return_results;
-       }
-       ei->bei_state |= CACHE_ENTRY_NO_KIDS;
-#endif
-
-       if (!manageDSAit && is_entry_referral( e ) ) {
-               /* parent is a referral, don't allow add */
-               rs->sr_ref = get_entry_referrals( op, e );
-
-               Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn)
-                       ": entry %s is referral\n", e->e_dn );
-
-               rs->sr_err = LDAP_REFERRAL,
-               rs->sr_matched = e->e_name.bv_val;
-               send_ldap_result( op, rs );
-
-               ber_bvarray_free( rs->sr_ref );
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-               goto done;
-       }
-
-       if ( be_issuffix( op->o_bd, &e->e_nname ) ) {
-#ifdef BDB_MULTIPLE_SUFFIXES
-               /* Allow renaming one suffix entry to another */
-               p_ndn = slap_empty_bv;
-#else
-               /* There can only be one suffix entry */
-               rs->sr_err = LDAP_NAMING_VIOLATION;
-               rs->sr_text = "cannot rename suffix entry";
-               goto return_results;
-#endif
-       } else {
-               dnParent( &e->e_nname, &p_ndn );
-       }
-       np_ndn = &p_ndn;
-       eip = ei->bei_parent;
-       if ( eip && eip->bei_id ) {
-               /* Make sure parent entry exist and we can write its 
-                * children.
-                */
-               rs->sr_err = bdb_cache_find_id( op, ltid,
-                       eip->bei_id, &eip, 0, &plock );
-
-               switch( rs->sr_err ) {
-               case 0:
-               case DB_NOTFOUND:
-                       break;
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               case LDAP_BUSY:
-                       rs->sr_text = "ldap server busy";
-                       goto return_results;
-               default:
-                       rs->sr_err = LDAP_OTHER;
-                       rs->sr_text = "internal error";
-                       goto return_results;
-               }
-
-               p = eip->bei_e;
-               if( p == NULL) {
-                       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn)
-                               ": parent does not exist\n" );
-                       rs->sr_err = LDAP_OTHER;
-                       rs->sr_text = "old entry's parent does not exist";
-                       goto return_results;
-               }
-       } else {
-               p = (Entry *)&slap_entry_root;
-       }
-
-       /* check parent for "children" acl */
-       rs->sr_err = access_allowed( op, p,
-               children, NULL,
-               op->oq_modrdn.rs_newSup == NULL ?
-                       ACL_WRITE : ACL_WDEL,
-               NULL );
-
-       if ( !p_ndn.bv_len )
-               p = NULL;
-
-       if ( ! rs->sr_err ) {
-               switch( opinfo.boi_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-
-               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-               Debug( LDAP_DEBUG_TRACE, "no access to parent\n" );
-               rs->sr_text = "no write access to old parent's children";
-               goto return_results;
-       }
-
-       Debug( LDAP_DEBUG_TRACE,
-               LDAP_XSTRING(bdb_modrdn) ": wr to children "
-               "of entry %s OK\n", p_ndn.bv_val );
-       
-       if ( p_ndn.bv_val == slap_empty_bv.bv_val ) {
-               p_dn = slap_empty_bv;
-       } else {
-               dnParent( &e->e_name, &p_dn );
-       }
-
-       Debug( LDAP_DEBUG_TRACE,
-               LDAP_XSTRING(bdb_modrdn) ": parent dn=%s\n",
-               p_dn.bv_val );
-
-       new_parent_dn = &p_dn;  /* New Parent unless newSuperior given */
-
-       if ( op->oq_modrdn.rs_newSup != NULL ) {
-               Debug( LDAP_DEBUG_TRACE, 
-                       LDAP_XSTRING(bdb_modrdn)
-                       ": new parent \"%s\" requested...\n",
-                       op->oq_modrdn.rs_newSup->bv_val );
-
-               /*  newSuperior == oldParent? */
-               if( dn_match( &p_ndn, op->oq_modrdn.rs_nnewSup ) ) {
-                       Debug( LDAP_DEBUG_TRACE, "bdb_back_modrdn: "
-                               "new parent \"%s\" same as the old parent \"%s\"\n",
-                               op->oq_modrdn.rs_newSup->bv_val, p_dn.bv_val );
-                       op->oq_modrdn.rs_newSup = NULL; /* ignore newSuperior */
-               }
-       }
-
-       /* There's a BDB_MULTIPLE_SUFFIXES case here that this code doesn't
-        * support. E.g., two suffixes dc=foo,dc=com and dc=bar,dc=net.
-        * We do not allow modDN
-        *   dc=foo,dc=com
-        *    newrdn dc=bar
-        *    newsup dc=net
-        * and we probably should. But since MULTIPLE_SUFFIXES is deprecated
-        * I'm ignoring this problem for now.
-        */
-       if ( op->oq_modrdn.rs_newSup != NULL ) {
-               if ( op->oq_modrdn.rs_newSup->bv_len ) {
-                       np_dn = op->oq_modrdn.rs_newSup;
-                       np_ndn = op->oq_modrdn.rs_nnewSup;
-
-                       /* newSuperior == oldParent? - checked above */
-                       /* newSuperior == entry being moved?, if so ==> ERROR */
-                       if ( dnIsSuffix( np_ndn, &e->e_nname )) {
-                               rs->sr_err = LDAP_NO_SUCH_OBJECT;
-                               rs->sr_text = "new superior not found";
-                               goto return_results;
-                       }
-                       /* Get Entry with dn=newSuperior. Does newSuperior exist? */
-
-                       rs->sr_err = bdb_dn2entry( op, ltid, np_ndn,
-                               &neip, 0, &nplock );
-
-                       switch( rs->sr_err ) {
-                       case 0: np = neip->bei_e;
-                       case DB_NOTFOUND:
-                               break;
-                       case DB_LOCK_DEADLOCK:
-                       case DB_LOCK_NOTGRANTED:
-                               goto retry;
-                       case LDAP_BUSY:
-                               rs->sr_text = "ldap server busy";
-                               goto return_results;
-                       default:
-                               rs->sr_err = LDAP_OTHER;
-                               rs->sr_text = "internal error";
-                               goto return_results;
-                       }
-
-                       if( np == NULL) {
-                               Debug( LDAP_DEBUG_TRACE,
-                                       LDAP_XSTRING(bdb_modrdn)
-                                       ": newSup(ndn=%s) not here!\n",
-                                       np_ndn->bv_val );
-                               rs->sr_text = "new superior not found";
-                               rs->sr_err = LDAP_NO_SUCH_OBJECT;
-                               goto return_results;
-                       }
-
-                       Debug( LDAP_DEBUG_TRACE,
-                               LDAP_XSTRING(bdb_modrdn)
-                               ": wr to new parent OK np=%p, id=%ld\n",
-                               (void *) np, (long) np->e_id );
-
-                       /* check newSuperior for "children" acl */
-                       rs->sr_err = access_allowed( op, np, children,
-                               NULL, ACL_WADD, NULL );
-
-                       if( ! rs->sr_err ) {
-                               switch( opinfo.boi_err ) {
-                               case DB_LOCK_DEADLOCK:
-                               case DB_LOCK_NOTGRANTED:
-                                       goto retry;
-                               }
-
-                               Debug( LDAP_DEBUG_TRACE,
-                                       LDAP_XSTRING(bdb_modrdn)
-                                       ": no wr to newSup children\n" );
-                               rs->sr_text = "no write access to new superior's children";
-                               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-                               goto return_results;
-                       }
-
-                       if ( is_entry_alias( np ) ) {
-                               /* parent is an alias, don't allow add */
-                               Debug( LDAP_DEBUG_TRACE,
-                                       LDAP_XSTRING(bdb_modrdn)
-                                       ": entry is alias\n" );
-                               rs->sr_text = "new superior is an alias";
-                               rs->sr_err = LDAP_ALIAS_PROBLEM;
-                               goto return_results;
-                       }
-
-                       if ( is_entry_referral( np ) ) {
-                               /* parent is a referral, don't allow add */
-                               Debug( LDAP_DEBUG_TRACE,
-                                       LDAP_XSTRING(bdb_modrdn)
-                                       ": entry is referral\n" );
-                               rs->sr_text = "new superior is a referral";
-                               rs->sr_err = LDAP_OTHER;
-                               goto return_results;
-                       }
-
-               } else {
-                       np_dn = NULL;
-
-                       /* no parent, modrdn entry directly under root */
-                       if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
-                               || be_isupdate( op ) ) {
-                               np = (Entry *)&slap_entry_root;
-
-                               /* check parent for "children" acl */
-                               rs->sr_err = access_allowed( op, np,
-                                       children, NULL, ACL_WADD, NULL );
-
-                               np = NULL;
-
-                               if ( ! rs->sr_err ) {
-                                       switch( opinfo.boi_err ) {
-                                       case DB_LOCK_DEADLOCK:
-                                       case DB_LOCK_NOTGRANTED:
-                                               goto retry;
-                                       }
-
-                                       rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-                                       Debug( LDAP_DEBUG_TRACE, 
-                                               "no access to new superior\n" );
-                                       rs->sr_text =
-                                               "no write access to new superior's children";
-                                       goto return_results;
-                               }
-                       }
-               }
-
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modrdn)
-                       ": wr to new parent's children OK\n" );
-
-               new_parent_dn = np_dn;
-       }
-
-       /* Build target dn and make sure target entry doesn't exist already. */
-       if (!new_dn.bv_val) {
-               build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn, NULL ); 
-       }
-
-       if (!new_ndn.bv_val) {
-               struct berval bv = {0, NULL};
-               dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx );
-               ber_dupbv( &new_ndn, &bv );
-               /* FIXME: why not call dnNormalize() w/o ctx? */
-               op->o_tmpfree( bv.bv_val, op->o_tmpmemctx );
-       }
-
-       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": new ndn=%s\n",
-               new_ndn.bv_val );
-
-       /* Shortcut the search */
-       nei = neip ? neip : eip;
-       rs->sr_err = bdb_cache_find_ndn ( op, ltid, &new_ndn, &nei );
-       if ( nei ) bdb_cache_entryinfo_unlock( nei );
-       switch( rs->sr_err ) {
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               goto retry;
-       case DB_NOTFOUND:
-               break;
-       case 0:
-               /* Allow rename to same DN */
-               if ( nei == ei )
-                       break;
-               rs->sr_err = LDAP_ALREADY_EXISTS;
-               goto return_results;
-       default:
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-
-       if( op->o_preread ) {
-               if( preread_ctrl == NULL ) {
-                       preread_ctrl = &ctrls[num_ctrls++];
-                       ctrls[num_ctrls] = NULL;
-               }
-               if( slap_read_controls( op, rs, e,
-                       &slap_pre_read_bv, preread_ctrl ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE,        
-                               "<=- " LDAP_XSTRING(bdb_modrdn)
-                               ": pre-read failed!\n" );
-                       if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
-                               /* FIXME: is it correct to abort
-                                * operation if control fails? */
-                               goto return_results;
-                       }
-               }                   
-       }
-
-       /* nested transaction */
-       rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, &lt2, bdb->bi_db_opflags );
-       rs->sr_text = NULL;
-       if( rs->sr_err != 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modrdn)
-                       ": txn_begin(2) failed: %s (%d)\n",
-                       db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "internal error";
-               goto return_results;
-       }
-       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": txn2 id: %x\n",
-               lt2->id(lt2) );
-
-       /* delete old DN */
-       rs->sr_err = bdb_dn2id_delete( op, lt2, eip, e );
-       if ( rs->sr_err != 0 ) {
-               Debug(LDAP_DEBUG_TRACE,
-                       "<=- " LDAP_XSTRING(bdb_modrdn)
-                       ": dn2id del failed: %s (%d)\n",
-                       db_strerror(rs->sr_err), rs->sr_err );
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "DN index delete fail";
-               goto return_results;
-       }
-
-       /* copy the entry, then override some fields */
-       dummy = *e;
-       dummy.e_name = new_dn;
-       dummy.e_nname = new_ndn;
-       dummy.e_attrs = NULL;
-
-       /* add new DN */
-       rs->sr_err = bdb_dn2id_add( op, lt2, neip ? neip : eip, &dummy );
-       if ( rs->sr_err != 0 ) {
-               Debug(LDAP_DEBUG_TRACE,
-                       "<=- " LDAP_XSTRING(bdb_modrdn)
-                       ": dn2id add failed: %s (%d)\n",
-                       db_strerror(rs->sr_err), rs->sr_err );
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "DN index add failed";
-               goto return_results;
-       }
-
-       dummy.e_attrs = e->e_attrs;
-
-       if( op->orr_modlist != NULL ) {
-               /* modify entry */
-               rs->sr_err = bdb_modify_internal( op, lt2, op->orr_modlist, &dummy,
-                       &rs->sr_text, textbuf, textlen );
-               if( rs->sr_err != LDAP_SUCCESS ) {
-                       Debug(LDAP_DEBUG_TRACE,
-                               "<=- " LDAP_XSTRING(bdb_modrdn)
-                               ": modify failed: %s (%d)\n",
-                               db_strerror(rs->sr_err), rs->sr_err );
-                       if ( ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) && opinfo.boi_err ) {
-                               rs->sr_err = opinfo.boi_err;
-                       }
-                       switch( rs->sr_err ) {
-                       case DB_LOCK_DEADLOCK:
-                       case DB_LOCK_NOTGRANTED:
-                               goto retry;
-                       }
-                       goto return_results;
-               }
-       }
-
-       /* id2entry index */
-       rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, &dummy );
-       if ( rs->sr_err != 0 ) {
-               Debug(LDAP_DEBUG_TRACE,
-                       "<=- " LDAP_XSTRING(bdb_modrdn)
-                       ": id2entry failed: %s (%d)\n",
-                       db_strerror(rs->sr_err), rs->sr_err );
-               switch( rs->sr_err ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "entry update failed";
-               goto return_results;
-       }
-
-       if ( p_ndn.bv_len != 0 ) {
-               parent_is_glue = is_entry_glue(p);
-               rs->sr_err = bdb_cache_children( op, lt2, p );
-               if ( rs->sr_err != DB_NOTFOUND ) {
-                       switch( rs->sr_err ) {
-                       case DB_LOCK_DEADLOCK:
-                       case DB_LOCK_NOTGRANTED:
-                               goto retry;
-                       case 0:
-                               break;
-                       default:
-                               Debug(LDAP_DEBUG_ARGS,
-                                       "<=- " LDAP_XSTRING(bdb_modrdn)
-                                       ": has_children failed: %s (%d)\n",
-                                       db_strerror(rs->sr_err), rs->sr_err );
-                               rs->sr_err = LDAP_OTHER;
-                               rs->sr_text = "internal error";
-                               goto return_results;
-                       }
-                       parent_is_leaf = 1;
-               }
-               bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
-               p = NULL;
-       }
-
-       if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
-               rs->sr_err = LDAP_OTHER;
-               rs->sr_text = "txn_commit(2) failed";
-               goto return_results;
-       }
-
-       if( op->o_postread ) {
-               if( postread_ctrl == NULL ) {
-                       postread_ctrl = &ctrls[num_ctrls++];
-                       ctrls[num_ctrls] = NULL;
-               }
-               if( slap_read_controls( op, rs, &dummy,
-                       &slap_post_read_bv, postread_ctrl ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE,        
-                               "<=- " LDAP_XSTRING(bdb_modrdn)
-                               ": post-read failed!\n" );
-                       if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
-                               /* FIXME: is it correct to abort
-                                * operation if control fails? */
-                               goto return_results;
-                       }
-               }                   
-       }
-
-       if( op->o_noop ) {
-               if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
-                       rs->sr_text = "txn_abort (no-op) failed";
-               } else {
-                       rs->sr_err = LDAP_X_NO_OPERATION;
-                       ltid = NULL;
-                       goto return_results;
-               }
-
-       } else {
-               rc = bdb_cache_modrdn( bdb, e, &op->orr_nnewrdn, &dummy, neip,
-                       ltid, &lock );
-               switch( rc ) {
-               case DB_LOCK_DEADLOCK:
-               case DB_LOCK_NOTGRANTED:
-                       goto retry;
-               }
-               dummy.e_attrs = NULL;
-               new_dn.bv_val = NULL;
-               new_ndn.bv_val = NULL;
-
-               if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
-                       rs->sr_text = "txn_commit failed";
-               } else {
-                       rs->sr_err = LDAP_SUCCESS;
-               }
-       }
-       ltid = NULL;
-       LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-       opinfo.boi_oe.oe_key = NULL;
-       if( rs->sr_err != LDAP_SUCCESS ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modrdn) ": %s : %s (%d)\n",
-                       rs->sr_text, db_strerror(rs->sr_err), rs->sr_err );
-               rs->sr_err = LDAP_OTHER;
-
-               goto return_results;
-       }
-
-       Debug(LDAP_DEBUG_TRACE,
-               LDAP_XSTRING(bdb_modrdn)
-               ": rdn modified%s id=%08lx dn=\"%s\"\n",
-               op->o_noop ? " (no-op)" : "",
-               dummy.e_id, op->o_req_dn.bv_val );
-       rs->sr_text = NULL;
-       if( num_ctrls ) rs->sr_ctrls = ctrls;
-
-return_results:
-       if ( dummy.e_attrs != e->e_attrs ) {
-               attrs_free( dummy.e_attrs );
-       }
-       send_ldap_result( op, rs );
-
-       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) {
-               TXN_CHECKPOINT( bdb->bi_dbenv,
-                       bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
-       }
-       
-       if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) {
-               op->o_delete_glue_parent = 1;
-       }
-
-done:
-       slap_graduate_commit_csn( op );
-
-       if( new_dn.bv_val != NULL ) free( new_dn.bv_val );
-       if( new_ndn.bv_val != NULL ) free( new_ndn.bv_val );
-
-       /* LDAP v3 Support */
-       if( np != NULL ) {
-               /* free new parent and reader lock */
-               bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, np);
-       }
-
-       if( p != NULL ) {
-               /* free parent and reader lock */
-               bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
-       }
-
-       /* free entry */
-       if( e != NULL ) {
-               bdb_unlocked_cache_return_entry_w( &bdb->bi_cache, e);
-       }
-
-       if( ltid != NULL ) {
-               TXN_ABORT( ltid );
-       }
-       if ( opinfo.boi_oe.oe_key ) {
-               LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
-       }
-
-       if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
-               slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
-               slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
-       }
-       if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
-               slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
-               slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
-       }
-       return rs->sr_err;
-}
diff --git a/servers/slapd/back-bdb/monitor.c b/servers/slapd/back-bdb/monitor.c
deleted file mode 100644 (file)
index 97cae08..0000000
+++ /dev/null
@@ -1,723 +0,0 @@
-/* monitor.c - monitor bdb backend */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-#include <ac/unistd.h>
-#include <ac/stdlib.h>
-#include <ac/errno.h>
-#include <sys/stat.h>
-#include "lutil.h"
-#include "back-bdb.h"
-
-#include "../back-monitor/back-monitor.h"
-
-#include "config.h"
-
-static ObjectClass             *oc_olmBDBDatabase;
-
-static AttributeDescription    *ad_olmBDBEntryCache,
-       *ad_olmBDBDNCache, *ad_olmBDBIDLCache,
-       *ad_olmDbDirectory;
-
-#ifdef BDB_MONITOR_IDX
-static int
-bdb_monitor_idx_entry_add(
-       struct bdb_info *bdb,
-       Entry           *e );
-
-static AttributeDescription    *ad_olmDbNotIndexed;
-#endif /* BDB_MONITOR_IDX */
-
-/*
- * NOTE: there's some confusion in monitor OID arc;
- * by now, let's consider:
- * 
- * Subsystems monitor attributes       1.3.6.1.4.1.4203.666.1.55.0
- * Databases monitor attributes                1.3.6.1.4.1.4203.666.1.55.0.1
- * BDB database monitor attributes     1.3.6.1.4.1.4203.666.1.55.0.1.1
- *
- * Subsystems monitor objectclasses    1.3.6.1.4.1.4203.666.3.16.0
- * Databases monitor objectclasses     1.3.6.1.4.1.4203.666.3.16.0.1
- * BDB database monitor objectclasses  1.3.6.1.4.1.4203.666.3.16.0.1.1
- */
-
-static struct {
-       char                    *name;
-       char                    *oid;
-}              s_oid[] = {
-       { "olmBDBAttributes",                   "olmDatabaseAttributes:1" },
-       { "olmBDBObjectClasses",                "olmDatabaseObjectClasses:1" },
-
-       { NULL }
-};
-
-static struct {
-       char                    *desc;
-       AttributeDescription    **ad;
-}              s_at[] = {
-       { "( olmBDBAttributes:1 "
-               "NAME ( 'olmBDBEntryCache' ) "
-               "DESC 'Number of items in Entry Cache' "
-               "SUP monitorCounter "
-               "NO-USER-MODIFICATION "
-               "USAGE dSAOperation )",
-               &ad_olmBDBEntryCache },
-
-       { "( olmBDBAttributes:2 "
-               "NAME ( 'olmBDBDNCache' ) "
-               "DESC 'Number of items in DN Cache' "
-               "SUP monitorCounter "
-               "NO-USER-MODIFICATION "
-               "USAGE dSAOperation )",
-               &ad_olmBDBDNCache },
-
-       { "( olmBDBAttributes:3 "
-               "NAME ( 'olmBDBIDLCache' ) "
-               "DESC 'Number of items in IDL Cache' "
-               "SUP monitorCounter "
-               "NO-USER-MODIFICATION "
-               "USAGE dSAOperation )",
-               &ad_olmBDBIDLCache },
-
-       { "( olmDatabaseAttributes:1 "
-               "NAME ( 'olmDbDirectory' ) "
-               "DESC 'Path name of the directory "
-                       "where the database environment resides' "
-               "SUP monitoredInfo "
-               "NO-USER-MODIFICATION "
-               "USAGE dSAOperation )",
-               &ad_olmDbDirectory },
-
-#ifdef BDB_MONITOR_IDX
-       { "( olmDatabaseAttributes:2 "
-               "NAME ( 'olmDbNotIndexed' ) "
-               "DESC 'Missing indexes resulting from candidate selection' "
-               "SUP monitoredInfo "
-               "NO-USER-MODIFICATION "
-               "USAGE dSAOperation )",
-               &ad_olmDbNotIndexed },
-#endif /* BDB_MONITOR_IDX */
-
-       { NULL }
-};
-
-static struct {
-       char            *desc;
-       ObjectClass     **oc;
-}              s_oc[] = {
-       /* augments an existing object, so it must be AUXILIARY
-        * FIXME: derive from some ABSTRACT "monitoredEntity"? */
-       { "( olmBDBObjectClasses:1 "
-               "NAME ( 'olmBDBDatabase' ) "
-               "SUP top AUXILIARY "
-               "MAY ( "
-                       "olmBDBEntryCache "
-                       "$ olmBDBDNCache "
-                       "$ olmBDBIDLCache "
-                       "$ olmDbDirectory "
-#ifdef BDB_MONITOR_IDX
-                       "$ olmDbNotIndexed "
-#endif /* BDB_MONITOR_IDX */
-                       ") )",
-               &oc_olmBDBDatabase },
-
-       { NULL }
-};
-
-static int
-bdb_monitor_update(
-       Operation       *op,
-       SlapReply       *rs,
-       Entry           *e,
-       void            *priv )
-{
-       struct bdb_info         *bdb = (struct bdb_info *) priv;
-       Attribute               *a;
-
-       char                    buf[ BUFSIZ ];
-       struct berval           bv;
-
-       assert( ad_olmBDBEntryCache != NULL );
-
-       a = attr_find( e->e_attrs, ad_olmBDBEntryCache );
-       assert( a != NULL );
-       bv.bv_val = buf;
-       bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_cache.c_cursize );
-       ber_bvreplace( &a->a_vals[ 0 ], &bv );
-
-       a = attr_find( e->e_attrs, ad_olmBDBDNCache );
-       assert( a != NULL );
-       bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_cache.c_eiused );
-       ber_bvreplace( &a->a_vals[ 0 ], &bv );
-
-       a = attr_find( e->e_attrs, ad_olmBDBIDLCache );
-       assert( a != NULL );
-       bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_idl_cache_size );
-       ber_bvreplace( &a->a_vals[ 0 ], &bv );
-       
-#ifdef BDB_MONITOR_IDX
-       bdb_monitor_idx_entry_add( bdb, e );
-#endif /* BDB_MONITOR_IDX */
-
-       return SLAP_CB_CONTINUE;
-}
-
-#if 0  /* uncomment if required */
-static int
-bdb_monitor_modify(
-       Operation       *op,
-       SlapReply       *rs,
-       Entry           *e,
-       void            *priv )
-{
-       return SLAP_CB_CONTINUE;
-}
-#endif
-
-static int
-bdb_monitor_free(
-       Entry           *e,
-       void            **priv )
-{
-       struct berval   values[ 2 ];
-       Modification    mod = { 0 };
-
-       const char      *text;
-       char            textbuf[ SLAP_TEXT_BUFLEN ];
-
-       int             i, rc;
-
-       /* NOTE: if slap_shutdown != 0, priv might have already been freed */
-       *priv = NULL;
-
-       /* Remove objectClass */
-       mod.sm_op = LDAP_MOD_DELETE;
-       mod.sm_desc = slap_schema.si_ad_objectClass;
-       mod.sm_values = values;
-       mod.sm_numvals = 1;
-       values[ 0 ] = oc_olmBDBDatabase->soc_cname;
-       BER_BVZERO( &values[ 1 ] );
-
-       rc = modify_delete_values( e, &mod, 1, &text,
-               textbuf, sizeof( textbuf ) );
-       /* don't care too much about return code... */
-
-       /* remove attrs */
-       mod.sm_values = NULL;
-       mod.sm_numvals = 0;
-       for ( i = 0; s_at[ i ].desc != NULL; i++ ) {
-               mod.sm_desc = *s_at[ i ].ad;
-               rc = modify_delete_values( e, &mod, 1, &text,
-                       textbuf, sizeof( textbuf ) );
-               /* don't care too much about return code... */
-       }
-       
-       return SLAP_CB_CONTINUE;
-}
-
-#define        bdb_monitor_initialize  BDB_SYMBOL(monitor_initialize)
-
-/*
- * call from within bdb_initialize()
- */
-static int
-bdb_monitor_initialize( void )
-{
-       int             i, code;
-       ConfigArgs c;
-       char    *argv[ 3 ];
-
-       static int      bdb_monitor_initialized = 0;
-
-       /* set to 0 when successfully initialized; otherwise, remember failure */
-       static int      bdb_monitor_initialized_failure = 1;
-
-       if ( bdb_monitor_initialized++ ) {
-               return bdb_monitor_initialized_failure;
-       }
-
-       if ( backend_info( "monitor" ) == NULL ) {
-               return -1;
-       }
-
-       /* register schema here */
-
-       argv[ 0 ] = "back-bdb/back-hdb monitor";
-       c.argv = argv;
-       c.argc = 3;
-       c.fname = argv[0];
-
-       for ( i = 0; s_oid[ i ].name; i++ ) {
-               c.lineno = i;
-               argv[ 1 ] = s_oid[ i ].name;
-               argv[ 2 ] = s_oid[ i ].oid;
-
-               if ( parse_oidm( &c, 0, NULL ) != 0 ) {
-                       Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize)
-                               ": unable to add "
-                               "objectIdentifier \"%s=%s\"\n",
-                               s_oid[ i ].name, s_oid[ i ].oid );
-                       return 2;
-               }
-       }
-
-       for ( i = 0; s_at[ i ].desc != NULL; i++ ) {
-               code = register_at( s_at[ i ].desc, s_at[ i ].ad, 1 );
-               if ( code != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize)
-                               ": register_at failed for attributeType (%s)\n",
-                               s_at[ i ].desc );
-                       return 3;
-
-               } else {
-                       (*s_at[ i ].ad)->ad_type->sat_flags |= SLAP_AT_HIDE;
-               }
-       }
-
-       for ( i = 0; s_oc[ i ].desc != NULL; i++ ) {
-               code = register_oc( s_oc[ i ].desc, s_oc[ i ].oc, 1 );
-               if ( code != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize)
-                               ": register_oc failed for objectClass (%s)\n",
-                               s_oc[ i ].desc );
-                       return 4;
-
-               } else {
-                       (*s_oc[ i ].oc)->soc_flags |= SLAP_OC_HIDE;
-               }
-       }
-
-       return ( bdb_monitor_initialized_failure = LDAP_SUCCESS );
-}
-
-/*
- * call from within bdb_db_init()
- */
-int
-bdb_monitor_db_init( BackendDB *be )
-{
-       struct bdb_info         *bdb = (struct bdb_info *) be->be_private;
-
-       if ( bdb_monitor_initialize() == LDAP_SUCCESS ) {
-               /* monitoring in back-bdb is on by default */
-               SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_MONITORING;
-       }
-
-#ifdef BDB_MONITOR_IDX
-       bdb->bi_idx = NULL;
-       ldap_pvt_thread_mutex_init( &bdb->bi_idx_mutex );
-#endif /* BDB_MONITOR_IDX */
-
-       return 0;
-}
-
-/*
- * call from within bdb_db_open()
- */
-int
-bdb_monitor_db_open( BackendDB *be )
-{
-       struct bdb_info         *bdb = (struct bdb_info *) be->be_private;
-       Attribute               *a, *next;
-       monitor_callback_t      *cb = NULL;
-       int                     rc = 0;
-       BackendInfo             *mi;
-       monitor_extra_t         *mbe;
-
-       if ( !SLAP_DBMONITORING( be ) ) {
-               return 0;
-       }
-
-       mi = backend_info( "monitor" );
-       if ( !mi || !mi->bi_extra ) {
-               SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING;
-               return 0;
-       }
-       mbe = mi->bi_extra;
-
-       /* don't bother if monitor is not configured */
-       if ( !mbe->is_configured() ) {
-               static int warning = 0;
-
-               if ( warning++ == 0 ) {
-                       Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_db_open)
-                               ": monitoring disabled; "
-                               "configure monitor database to enable\n" );
-               }
-
-               return 0;
-       }
-
-       /* alloc as many as required (plus 1 for objectClass) */
-       a = attrs_alloc( 1 + 4 );
-       if ( a == NULL ) {
-               rc = 1;
-               goto cleanup;
-       }
-
-       a->a_desc = slap_schema.si_ad_objectClass;
-       attr_valadd( a, &oc_olmBDBDatabase->soc_cname, NULL, 1 );
-       next = a->a_next;
-
-       {
-               struct berval   bv = BER_BVC( "0" );
-
-               next->a_desc = ad_olmBDBEntryCache;
-               attr_valadd( next, &bv, NULL, 1 );
-               next = next->a_next;
-
-               next->a_desc = ad_olmBDBDNCache;
-               attr_valadd( next, &bv, NULL, 1 );
-               next = next->a_next;
-
-               next->a_desc = ad_olmBDBIDLCache;
-               attr_valadd( next, &bv, NULL, 1 );
-               next = next->a_next;
-       }
-
-       {
-               struct berval   bv, nbv;
-               ber_len_t       pathlen = 0, len = 0;
-               char            path[ MAXPATHLEN ] = { '\0' };
-               char            *fname = bdb->bi_dbenv_home,
-                               *ptr;
-
-               len = strlen( fname );
-               if ( fname[ 0 ] != '/' ) {
-                       /* get full path name */
-                       getcwd( path, sizeof( path ) );
-                       pathlen = strlen( path );
-
-                       if ( fname[ 0 ] == '.' && fname[ 1 ] == '/' ) {
-                               fname += 2;
-                               len -= 2;
-                       }
-               }
-
-               bv.bv_len = pathlen + STRLENOF( "/" ) + len;
-               ptr = bv.bv_val = ch_malloc( bv.bv_len + STRLENOF( "/" ) + 1 );
-               if ( pathlen ) {
-                       ptr = lutil_strncopy( ptr, path, pathlen );
-                       ptr[ 0 ] = '/';
-                       ptr++;
-               }
-               ptr = lutil_strncopy( ptr, fname, len );
-               if ( ptr[ -1 ] != '/' ) {
-                       ptr[ 0 ] = '/';
-                       ptr++;
-               }
-               ptr[ 0 ] = '\0';
-               
-               attr_normalize_one( ad_olmDbDirectory, &bv, &nbv, NULL );
-
-               next->a_desc = ad_olmDbDirectory;
-               next->a_vals = ch_calloc( sizeof( struct berval ), 2 );
-               next->a_vals[ 0 ] = bv;
-               next->a_numvals = 1;
-
-               if ( BER_BVISNULL( &nbv ) ) {
-                       next->a_nvals = next->a_vals;
-
-               } else {
-                       next->a_nvals = ch_calloc( sizeof( struct berval ), 2 );
-                       next->a_nvals[ 0 ] = nbv;
-               }
-
-               next = next->a_next;
-       }
-
-       cb = ch_calloc( sizeof( monitor_callback_t ), 1 );
-       cb->mc_update = bdb_monitor_update;
-#if 0  /* uncomment if required */
-       cb->mc_modify = bdb_monitor_modify;
-#endif
-       cb->mc_free = bdb_monitor_free;
-       cb->mc_private = (void *)bdb;
-
-       /* make sure the database is registered; then add monitor attributes */
-       rc = mbe->register_database( be, &bdb->bi_monitor.bdm_ndn );
-       if ( rc == 0 ) {
-               rc = mbe->register_entry_attrs( &bdb->bi_monitor.bdm_ndn, a, cb,
-                       NULL, 0, NULL );
-       }
-
-cleanup:;
-       if ( rc != 0 ) {
-               if ( cb != NULL ) {
-                       ch_free( cb );
-                       cb = NULL;
-               }
-
-               if ( a != NULL ) {
-                       attrs_free( a );
-                       a = NULL;
-               }
-       }
-
-       /* store for cleanup */
-       bdb->bi_monitor.bdm_cb = (void *)cb;
-
-       /* we don't need to keep track of the attributes, because
-        * bdb_monitor_free() takes care of everything */
-       if ( a != NULL ) {
-               attrs_free( a );
-       }
-
-       return rc;
-}
-
-/*
- * call from within bdb_db_close()
- */
-int
-bdb_monitor_db_close( BackendDB *be )
-{
-       struct bdb_info         *bdb = (struct bdb_info *) be->be_private;
-
-       if ( !BER_BVISNULL( &bdb->bi_monitor.bdm_ndn ) ) {
-               BackendInfo             *mi = backend_info( "monitor" );
-               monitor_extra_t         *mbe;
-
-               if ( mi && mi->bi_extra ) {
-                       mbe = mi->bi_extra;
-                       mbe->unregister_entry_callback( &bdb->bi_monitor.bdm_ndn,
-                               (monitor_callback_t *)bdb->bi_monitor.bdm_cb,
-                               NULL, 0, NULL );
-               }
-
-               memset( &bdb->bi_monitor, 0, sizeof( bdb->bi_monitor ) );
-       }
-
-       return 0;
-}
-
-/*
- * call from within bdb_db_destroy()
- */
-int
-bdb_monitor_db_destroy( BackendDB *be )
-{
-#ifdef BDB_MONITOR_IDX
-       struct bdb_info         *bdb = (struct bdb_info *) be->be_private;
-
-       /* TODO: free tree */
-       ldap_pvt_thread_mutex_destroy( &bdb->bi_idx_mutex );
-       avl_free( bdb->bi_idx, ch_free );
-#endif /* BDB_MONITOR_IDX */
-
-       return 0;
-}
-
-#ifdef BDB_MONITOR_IDX
-
-#define BDB_MONITOR_IDX_TYPES  (4)
-
-typedef struct monitor_idx_t monitor_idx_t;
-
-struct monitor_idx_t {
-       AttributeDescription    *idx_ad;
-       unsigned long           idx_count[BDB_MONITOR_IDX_TYPES];
-};
-
-static int
-bdb_monitor_bitmask2key( slap_mask_t bitmask )
-{
-       int     key;
-
-       for ( key = 0; key < 8 * (int)sizeof(slap_mask_t) && !( bitmask & 0x1U );
-                       key++ )
-               bitmask >>= 1;
-
-       return key;
-}
-
-static struct berval idxbv[] = {
-       BER_BVC( "present=" ),
-       BER_BVC( "equality=" ),
-       BER_BVC( "approx=" ),
-       BER_BVC( "substr=" ),
-       BER_BVNULL
-};
-
-static ber_len_t
-bdb_monitor_idx2len( monitor_idx_t *idx )
-{
-       int             i;
-       ber_len_t       len = 0;
-
-       for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) {
-               if ( idx->idx_count[ i ] != 0 ) {
-                       len += idxbv[i].bv_len;
-               }
-       }
-
-       return len;
-}
-
-static int
-monitor_idx_cmp( const void *p1, const void *p2 )
-{
-       const monitor_idx_t     *idx1 = (const monitor_idx_t *)p1;
-       const monitor_idx_t     *idx2 = (const monitor_idx_t *)p2;
-
-       return SLAP_PTRCMP( idx1->idx_ad, idx2->idx_ad );
-}
-
-static int
-monitor_idx_dup( void *p1, void *p2 )
-{
-       monitor_idx_t   *idx1 = (monitor_idx_t *)p1;
-       monitor_idx_t   *idx2 = (monitor_idx_t *)p2;
-
-       return SLAP_PTRCMP( idx1->idx_ad, idx2->idx_ad ) == 0 ? -1 : 0;
-}
-
-int
-bdb_monitor_idx_add(
-       struct bdb_info         *bdb,
-       AttributeDescription    *desc,
-       slap_mask_t             type )
-{
-       monitor_idx_t           idx_dummy = { 0 },
-                               *idx;
-       int                     rc = 0, key;
-
-       idx_dummy.idx_ad = desc;
-       key = bdb_monitor_bitmask2key( type ) - 1;
-       if ( key >= BDB_MONITOR_IDX_TYPES ) {
-               /* invalid index type */
-               return -1;
-       }
-
-       ldap_pvt_thread_mutex_lock( &bdb->bi_idx_mutex );
-
-       idx = (monitor_idx_t *)avl_find( bdb->bi_idx,
-               (caddr_t)&idx_dummy, monitor_idx_cmp );
-       if ( idx == NULL ) {
-               idx = (monitor_idx_t *)ch_calloc( sizeof( monitor_idx_t ), 1 );
-               idx->idx_ad = desc;
-               idx->idx_count[ key ] = 1;
-
-               switch ( avl_insert( &bdb->bi_idx, (caddr_t)idx, 
-                       monitor_idx_cmp, monitor_idx_dup ) )
-               {
-               case 0:
-                       break;
-
-               default:
-                       ch_free( idx );
-                       rc = -1;
-               }
-
-       } else {
-               idx->idx_count[ key ]++;
-       }
-
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_idx_mutex );
-
-       return rc;
-}
-
-static int
-bdb_monitor_idx_apply( void *v_idx, void *v_valp )
-{
-       monitor_idx_t   *idx = (monitor_idx_t *)v_idx;
-       BerVarray       *valp = (BerVarray *)v_valp;
-
-       struct berval   bv;
-       char            *ptr;
-       char            count_buf[ BDB_MONITOR_IDX_TYPES ][ SLAP_TEXT_BUFLEN ];
-       ber_len_t       count_len[ BDB_MONITOR_IDX_TYPES ],
-                       idx_len;
-       int             i, num = 0;
-
-       idx_len = bdb_monitor_idx2len( idx );
-
-       bv.bv_len = 0;
-       for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) {
-               if ( idx->idx_count[ i ] == 0 ) {
-                       continue;
-               }
-
-               count_len[ i ] = snprintf( count_buf[ i ],
-                       sizeof( count_buf[ i ] ), "%lu", idx->idx_count[ i ] );
-               bv.bv_len += count_len[ i ];
-               num++;
-       }
-
-       bv.bv_len += idx->idx_ad->ad_cname.bv_len
-               + num
-               + idx_len;
-       ptr = bv.bv_val = ch_malloc( bv.bv_len + 1 );
-       ptr = lutil_strcopy( ptr, idx->idx_ad->ad_cname.bv_val );
-       for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) {
-               if ( idx->idx_count[ i ] == 0 ) {
-                       continue;
-               }
-
-               ptr[ 0 ] = '#';
-               ++ptr;
-               ptr = lutil_strcopy( ptr, idxbv[ i ].bv_val );
-               ptr = lutil_strcopy( ptr, count_buf[ i ] );
-       }
-
-       ber_bvarray_add( valp, &bv );
-
-       return 0;
-}
-
-static int
-bdb_monitor_idx_entry_add(
-       struct bdb_info *bdb,
-       Entry           *e )
-{
-       BerVarray       vals = NULL;
-       Attribute       *a;
-
-       a = attr_find( e->e_attrs, ad_olmDbNotIndexed );
-
-       ldap_pvt_thread_mutex_lock( &bdb->bi_idx_mutex );
-
-       avl_apply( bdb->bi_idx, bdb_monitor_idx_apply,
-               &vals, -1, AVL_INORDER );
-
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_idx_mutex );
-
-       if ( vals != NULL ) {
-               if ( a != NULL ) {
-                       assert( a->a_nvals == a->a_vals );
-
-                       ber_bvarray_free( a->a_vals );
-
-               } else {
-                       Attribute       **ap;
-
-                       for ( ap = &e->e_attrs; *ap != NULL; ap = &(*ap)->a_next )
-                               ;
-                       *ap = attr_alloc( ad_olmDbNotIndexed );
-                       a = *ap;
-               }
-               a->a_vals = vals;
-               a->a_nvals = a->a_vals;
-       }
-
-       return 0;
-}
-
-#endif /* BDB_MONITOR_IDX */
diff --git a/servers/slapd/back-bdb/nextid.c b/servers/slapd/back-bdb/nextid.c
deleted file mode 100644 (file)
index 6178595..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* init.c - initialize bdb backend */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-
-int bdb_next_id( BackendDB *be, ID *out )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-
-       ldap_pvt_thread_mutex_lock( &bdb->bi_lastid_mutex );
-       *out = ++bdb->bi_lastid;
-       ldap_pvt_thread_mutex_unlock( &bdb->bi_lastid_mutex );
-
-       return 0;
-}
-
-int bdb_last_id( BackendDB *be, DB_TXN *tid )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       int rc;
-       ID id = 0;
-       unsigned char idbuf[sizeof(ID)];
-       DBT key, data;
-       DBC *cursor;
-
-       DBTzero( &key );
-       key.flags = DB_DBT_USERMEM;
-       key.data = (char *) idbuf;
-       key.ulen = sizeof( idbuf );
-
-       DBTzero( &data );
-       data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
-
-       /* Get a read cursor */
-       rc = bdb->bi_id2entry->bdi_db->cursor( bdb->bi_id2entry->bdi_db,
-               tid, &cursor, 0 );
-
-       if (rc == 0) {
-               rc = cursor->c_get(cursor, &key, &data, DB_LAST);
-               cursor->c_close(cursor);
-       }
-
-       switch(rc) {
-       case DB_NOTFOUND:
-               rc = 0;
-               break;
-       case 0:
-               BDB_DISK2ID( idbuf, &id );
-               break;
-
-       default:
-               Debug( LDAP_DEBUG_ANY,
-                       "=> bdb_last_id: get failed: %s (%d)\n",
-                       db_strerror(rc), rc );
-               goto done;
-       }
-
-       bdb->bi_lastid = id;
-
-done:
-       return rc;
-}
diff --git a/servers/slapd/back-bdb/operational.c b/servers/slapd/back-bdb/operational.c
deleted file mode 100644 (file)
index 447048c..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/* operational.c - bdb backend operational attributes function */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-bdb.h"
-
-/*
- * sets *hasSubordinates to LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE
- * if the entry has children or not.
- */
-int
-bdb_hasSubordinates(
-       Operation       *op,
-       Entry           *e,
-       int             *hasSubordinates )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       struct bdb_op_info      *opinfo;
-       OpExtra *oex;
-       DB_TXN          *rtxn;
-       int             rc;
-       int             release = 0;
-       
-       assert( e != NULL );
-
-       /* NOTE: this should never happen, but it actually happens
-        * when using back-relay; until we find a better way to
-        * preserve entry's private information while rewriting it,
-        * let's disable the hasSubordinate feature for back-relay.
-        */
-       if ( BEI( e ) == NULL ) {
-               Entry *ee = NULL;
-               rc = be_entry_get_rw( op, &e->e_nname, NULL, NULL, 0, &ee );
-               if ( rc != LDAP_SUCCESS || ee == NULL ) {
-                       rc = LDAP_OTHER;
-                       goto done;
-               }
-               e = ee;
-               release = 1;
-               if ( BEI( ee ) == NULL ) {
-                       rc = LDAP_OTHER;
-                       goto done;
-               }
-       }
-
-       /* Check for a txn in a parent op, otherwise use reader txn */
-       LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
-               if ( oex->oe_key == bdb )
-                       break;
-       }
-       opinfo = (struct bdb_op_info *) oex;
-       if ( opinfo && opinfo->boi_txn ) {
-               rtxn = opinfo->boi_txn;
-       } else {
-               rc = bdb_reader_get(op, bdb->bi_dbenv, &rtxn);
-               if ( rc ) {
-                       rc = LDAP_OTHER;
-                       goto done;
-               }
-       }
-
-retry:
-       /* FIXME: we can no longer assume the entry's e_private
-        * field is correctly populated; so we need to reacquire
-        * it with reader lock */
-       rc = bdb_cache_children( op, rtxn, e );
-
-       switch( rc ) {
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               goto retry;
-
-       case 0:
-               *hasSubordinates = LDAP_COMPARE_TRUE;
-               break;
-
-       case DB_NOTFOUND:
-               *hasSubordinates = LDAP_COMPARE_FALSE;
-               rc = LDAP_SUCCESS;
-               break;
-
-       default:
-               Debug(LDAP_DEBUG_ARGS, 
-                       "<=- " LDAP_XSTRING(bdb_hasSubordinates)
-                       ": has_children failed: %s (%d)\n", 
-                       db_strerror(rc), rc );
-               rc = LDAP_OTHER;
-       }
-
-done:;
-       if ( release && e != NULL ) be_entry_release_r( op, e );
-       return rc;
-}
-
-/*
- * sets the supported operational attributes (if required)
- */
-int
-bdb_operational(
-       Operation       *op,
-       SlapReply       *rs )
-{
-       Attribute       **ap;
-
-       assert( rs->sr_entry != NULL );
-
-       for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) {
-               if ( (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) {
-                       break;
-               }
-       }
-
-       if ( *ap == NULL &&
-               attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL &&
-               ( SLAP_OPATTRS( rs->sr_attr_flags ) ||
-                       ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) )
-       {
-               int     hasSubordinates, rc;
-
-               rc = bdb_hasSubordinates( op, rs->sr_entry, &hasSubordinates );
-               if ( rc == LDAP_SUCCESS ) {
-                       *ap = slap_operational_hasSubordinate( hasSubordinates == LDAP_COMPARE_TRUE );
-                       assert( *ap != NULL );
-
-                       ap = &(*ap)->a_next;
-               }
-       }
-
-       return LDAP_SUCCESS;
-}
-
diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h
deleted file mode 100644 (file)
index ade9d89..0000000
+++ /dev/null
@@ -1,680 +0,0 @@
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#ifndef _PROTO_BDB_H
-#define _PROTO_BDB_H
-
-LDAP_BEGIN_DECL
-
-#ifdef BDB_HIER
-#define        BDB_SYMBOL(x)   LDAP_CONCAT(hdb_,x)
-#define BDB_UCTYPE     "HDB"
-#else
-#define BDB_SYMBOL(x)  LDAP_CONCAT(bdb_,x)
-#define BDB_UCTYPE     "BDB"
-#endif
-
-/*
- * attr.c
- */
-
-#define bdb_attr_mask                          BDB_SYMBOL(attr_mask)
-#define bdb_attr_flush                         BDB_SYMBOL(attr_flush)
-#define bdb_attr_slot                          BDB_SYMBOL(attr_slot)
-#define bdb_attr_index_config          BDB_SYMBOL(attr_index_config)
-#define bdb_attr_index_destroy         BDB_SYMBOL(attr_index_destroy)
-#define bdb_attr_index_free                    BDB_SYMBOL(attr_index_free)
-#define bdb_attr_index_unparse         BDB_SYMBOL(attr_index_unparse)
-#define bdb_attr_info_free                     BDB_SYMBOL(attr_info_free)
-
-AttrInfo *bdb_attr_mask( struct bdb_info *bdb,
-       AttributeDescription *desc );
-
-void bdb_attr_flush( struct bdb_info *bdb );
-
-int bdb_attr_slot( struct bdb_info *bdb,
-       AttributeDescription *desc, int *insert );
-
-int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb,
-       const char *fname, int lineno,
-       int argc, char **argv, struct config_reply_s *cr ));
-
-void bdb_attr_index_unparse LDAP_P(( struct bdb_info *bdb, BerVarray *bva ));
-void bdb_attr_index_destroy LDAP_P(( struct bdb_info *bdb ));
-void bdb_attr_index_free LDAP_P(( struct bdb_info *bdb,
-       AttributeDescription *ad ));
-
-void bdb_attr_info_free( AttrInfo *ai );
-
-/*
- * config.c
- */
-
-#define bdb_back_init_cf                               BDB_SYMBOL(back_init_cf)
-
-int bdb_back_init_cf( BackendInfo *bi );
-
-/*
- * dbcache.c
- */
-#define bdb_db_cache                           BDB_SYMBOL(db_cache)
-#define bdb_db_findsize                                BDB_SYMBOL(db_findsize)
-
-int
-bdb_db_cache(
-    Backend    *be,
-    struct berval *name,
-       DB **db );
-
-int
-bdb_db_findsize(
-       struct bdb_info *bdb,
-       struct berval *name );
-
-/*
- * dn2entry.c
- */
-#define bdb_dn2entry                           BDB_SYMBOL(dn2entry)
-
-int bdb_dn2entry LDAP_P(( Operation *op, DB_TXN *tid,
-       struct berval *dn, EntryInfo **e, int matched,
-       DB_LOCK *lock ));
-
-/*
- * dn2id.c
- */
-#define bdb_dn2id                                      BDB_SYMBOL(dn2id)
-#define bdb_dn2id_add                          BDB_SYMBOL(dn2id_add)
-#define bdb_dn2id_delete                       BDB_SYMBOL(dn2id_delete)
-#define bdb_dn2id_children                     BDB_SYMBOL(dn2id_children)
-#define bdb_dn2idl                                     BDB_SYMBOL(dn2idl)
-
-int bdb_dn2id(
-       Operation *op,
-       struct berval *dn,
-       EntryInfo *ei,
-       DB_TXN *txn,
-       DBC **cursor );
-
-int bdb_dn2id_add(
-       Operation *op,
-       DB_TXN *tid,
-       EntryInfo *eip,
-       Entry *e );
-
-int bdb_dn2id_delete(
-       Operation *op,
-       DB_TXN *tid,
-       EntryInfo *eip,
-       Entry *e );
-
-int bdb_dn2id_children(
-       Operation *op,
-       DB_TXN *tid,
-       Entry *e );
-
-int bdb_dn2idl(
-       Operation *op,
-       DB_TXN *txn,
-       struct berval *ndn,
-       EntryInfo *ei,
-       ID *ids,
-       ID *stack );
-
-#ifdef BDB_HIER
-#define bdb_dn2id_parent                       BDB_SYMBOL(dn2id_parent)
-#define bdb_dup_compare                                BDB_SYMBOL(dup_compare)
-#define bdb_fix_dn                                     BDB_SYMBOL(fix_dn)
-
-int bdb_dn2id_parent(
-       Operation *op,
-       DB_TXN *txn,
-       EntryInfo *ei,
-       ID *idp );
-
-int bdb_dup_compare(
-       DB *db,
-       const DBT *usrkey,
-       const DBT *curkey );
-
-int bdb_fix_dn( Entry *e, int checkit );
-#endif
-
-
-/*
- * error.c
- */
-#define bdb_errcall                                    BDB_SYMBOL(errcall)
-
-#if DB_VERSION_FULL < 0x04030000
-void bdb_errcall( const char *pfx, char * msg );
-#else
-#define bdb_msgcall                                    BDB_SYMBOL(msgcall)
-void bdb_errcall( const DB_ENV *env, const char *pfx, const char * msg );
-void bdb_msgcall( const DB_ENV *env, const char * msg );
-#endif
-
-#ifdef HAVE_EBCDIC
-#define ebcdic_dberror                         BDB_SYMBOL(ebcdic_dberror)
-
-char *ebcdic_dberror( int rc );
-#define db_strerror(x) ebcdic_dberror(x)
-#endif
-
-/*
- * filterentry.c
- */
-#define bdb_filter_candidates          BDB_SYMBOL(filter_candidates)
-
-int bdb_filter_candidates(
-       Operation *op,
-       DB_TXN *txn,
-       Filter  *f,
-       ID *ids,
-       ID *tmp,
-       ID *stack );
-
-/*
- * id2entry.c
- */
-#define bdb_id2entry                           BDB_SYMBOL(id2entry)
-#define bdb_id2entry_add                       BDB_SYMBOL(id2entry_add)
-#define bdb_id2entry_update                    BDB_SYMBOL(id2entry_update)
-#define bdb_id2entry_delete                    BDB_SYMBOL(id2entry_delete)
-
-int bdb_id2entry_add(
-       BackendDB *be,
-       DB_TXN *tid,
-       Entry *e );
-
-int bdb_id2entry_update(
-       BackendDB *be,
-       DB_TXN *tid,
-       Entry *e );
-
-int bdb_id2entry_delete(
-       BackendDB *be,
-       DB_TXN *tid,
-       Entry *e);
-
-#ifdef SLAP_ZONE_ALLOC
-#else
-int bdb_id2entry(
-       BackendDB *be,
-       DB_TXN *tid,
-       ID id,
-       Entry **e);
-#endif
-
-#define bdb_entry_free                         BDB_SYMBOL(entry_free)
-#define bdb_entry_return                       BDB_SYMBOL(entry_return)
-#define bdb_entry_release                      BDB_SYMBOL(entry_release)
-#define bdb_entry_get                          BDB_SYMBOL(entry_get)
-
-void bdb_entry_free ( Entry *e );
-#ifdef SLAP_ZONE_ALLOC
-int bdb_entry_return( struct bdb_info *bdb, Entry *e, int seqno );
-#else
-int bdb_entry_return( Entry *e );
-#endif
-BI_entry_release_rw bdb_entry_release;
-BI_entry_get_rw bdb_entry_get;
-
-
-/*
- * idl.c
- */
-
-#define bdb_idl_cache_get                      BDB_SYMBOL(idl_cache_get)
-#define bdb_idl_cache_put                      BDB_SYMBOL(idl_cache_put)
-#define bdb_idl_cache_del                      BDB_SYMBOL(idl_cache_del)
-#define bdb_idl_cache_add_id           BDB_SYMBOL(idl_cache_add_id)
-#define bdb_idl_cache_del_id           BDB_SYMBOL(idl_cache_del_id)
-
-int bdb_idl_cache_get(
-       struct bdb_info *bdb,
-       DB *db,
-       DBT *key,
-       ID *ids );
-
-void
-bdb_idl_cache_put(
-       struct bdb_info *bdb,
-       DB              *db,
-       DBT             *key,
-       ID              *ids,
-       int             rc );
-
-void
-bdb_idl_cache_del(
-       struct bdb_info *bdb,
-       DB              *db,
-       DBT             *key );
-
-void
-bdb_idl_cache_add_id(
-       struct bdb_info *bdb,
-       DB              *db,
-       DBT             *key,
-       ID              id );
-
-void
-bdb_idl_cache_del_id(
-       struct bdb_info *bdb,
-       DB              *db,
-       DBT             *key,
-       ID              id );
-
-#define bdb_idl_first                          BDB_SYMBOL(idl_first)
-#define bdb_idl_next                           BDB_SYMBOL(idl_next)
-#define bdb_idl_search                         BDB_SYMBOL(idl_search)
-#define bdb_idl_insert                         BDB_SYMBOL(idl_insert)
-#define bdb_idl_delete                         BDB_SYMBOL(idl_delete)
-#define bdb_idl_intersection           BDB_SYMBOL(idl_intersection)
-#define bdb_idl_union                          BDB_SYMBOL(idl_union)
-#define bdb_idl_sort                           BDB_SYMBOL(idl_sort)
-#define bdb_idl_append                         BDB_SYMBOL(idl_append)
-#define bdb_idl_append_one                     BDB_SYMBOL(idl_append_one)
-
-#define bdb_idl_fetch_key                      BDB_SYMBOL(idl_fetch_key)
-#define bdb_idl_insert_key                     BDB_SYMBOL(idl_insert_key)
-#define bdb_idl_delete_key                     BDB_SYMBOL(idl_delete_key)
-
-unsigned bdb_idl_search( ID *ids, ID id );
-
-int bdb_idl_fetch_key(
-       BackendDB       *be,
-       DB                      *db,
-       DB_TXN          *txn,
-       DBT                     *key,
-       ID                      *ids,
-       DBC                     **saved_cursor,
-       int                     get_flag );
-
-int bdb_idl_insert( ID *ids, ID id );
-int bdb_idl_delete( ID *ids, ID id );
-
-int bdb_idl_insert_key(
-       BackendDB *be,
-       DB *db,
-       DB_TXN *txn,
-       DBT *key,
-       ID id );
-
-int bdb_idl_delete_key(
-       BackendDB *be,
-       DB *db,
-       DB_TXN *txn,
-       DBT *key,
-       ID id );
-
-int
-bdb_idl_intersection(
-       ID *a,
-       ID *b );
-
-int
-bdb_idl_union(
-       ID *a,
-       ID *b );
-
-ID bdb_idl_first( ID *ids, ID *cursor );
-ID bdb_idl_next( ID *ids, ID *cursor );
-
-void bdb_idl_sort( ID *ids, ID *tmp );
-int bdb_idl_append( ID *a, ID *b );
-int bdb_idl_append_one( ID *ids, ID id );
-
-
-/*
- * index.c
- */
-#define bdb_index_mask                         BDB_SYMBOL(index_mask)
-#define bdb_index_param                                BDB_SYMBOL(index_param)
-#define bdb_index_values                       BDB_SYMBOL(index_values)
-#define bdb_index_entry                                BDB_SYMBOL(index_entry)
-#define bdb_index_recset                       BDB_SYMBOL(index_recset)
-#define bdb_index_recrun                       BDB_SYMBOL(index_recrun)
-
-extern AttrInfo *
-bdb_index_mask LDAP_P((
-       Backend *be,
-       AttributeDescription *desc,
-       struct berval *name ));
-
-extern int
-bdb_index_param LDAP_P((
-       Backend *be,
-       AttributeDescription *desc,
-       int ftype,
-       DB **db,
-       slap_mask_t *mask,
-       struct berval *prefix ));
-
-extern int
-bdb_index_values LDAP_P((
-       Operation *op,
-       DB_TXN *txn,
-       AttributeDescription *desc,
-       BerVarray vals,
-       ID id,
-       int opid ));
-
-extern int
-bdb_index_recset LDAP_P((
-       struct bdb_info *bdb,
-       Attribute *a,
-       AttributeType *type,
-       struct berval *tags,
-       IndexRec *ir ));
-
-extern int
-bdb_index_recrun LDAP_P((
-       Operation *op,
-       struct bdb_info *bdb,
-       IndexRec *ir,
-       ID id,
-       int base ));
-
-int bdb_index_entry LDAP_P(( Operation *op, DB_TXN *t, int r, Entry *e ));
-
-#define bdb_index_entry_add(op,t,e) \
-       bdb_index_entry((op),(t),SLAP_INDEX_ADD_OP,(e))
-#define bdb_index_entry_del(op,t,e) \
-       bdb_index_entry((op),(t),SLAP_INDEX_DELETE_OP,(e))
-
-/*
- * key.c
- */
-#define bdb_key_read                           BDB_SYMBOL(key_read)
-#define bdb_key_change                         BDB_SYMBOL(key_change)
-
-extern int
-bdb_key_read(
-    Backend    *be,
-       DB *db,
-       DB_TXN *txn,
-    struct berval *k,
-       ID *ids,
-    DBC **saved_cursor,
-        int get_flags );
-
-extern int
-bdb_key_change(
-    Backend     *be,
-    DB *db,
-       DB_TXN *txn,
-    struct berval *k,
-    ID id,
-    int        op );
-       
-/*
- * nextid.c
- */
-#define bdb_next_id                                    BDB_SYMBOL(next_id)
-#define bdb_last_id                                    BDB_SYMBOL(last_id)
-
-int bdb_next_id( BackendDB *be, ID *id );
-int bdb_last_id( BackendDB *be, DB_TXN *tid );
-
-/*
- * modify.c
- */
-#define bdb_modify_internal                    BDB_SYMBOL(modify_internal)
-
-int bdb_modify_internal(
-       Operation *op,
-       DB_TXN *tid,
-       Modifications *modlist,
-       Entry *e,
-       const char **text,
-       char *textbuf,
-       size_t textlen );
-
-/*
- * monitor.c
- */
-
-#define bdb_monitor_db_init    BDB_SYMBOL(monitor_db_init)
-#define bdb_monitor_db_open    BDB_SYMBOL(monitor_db_open)
-#define bdb_monitor_db_close   BDB_SYMBOL(monitor_db_close)
-#define bdb_monitor_db_destroy BDB_SYMBOL(monitor_db_destroy)
-
-int bdb_monitor_db_init( BackendDB *be );
-int bdb_monitor_db_open( BackendDB *be );
-int bdb_monitor_db_close( BackendDB *be );
-int bdb_monitor_db_destroy( BackendDB *be );
-
-#ifdef BDB_MONITOR_IDX
-#define bdb_monitor_idx_add    BDB_SYMBOL(monitor_idx_add)
-int
-bdb_monitor_idx_add(
-       struct bdb_info         *bdb,
-       AttributeDescription    *desc,
-       slap_mask_t             type );
-#endif /* BDB_MONITOR_IDX */
-
-/*
- * cache.c
- */
-#define bdb_cache_entry_db_unlock      BDB_SYMBOL(cache_entry_db_unlock)
-#define bdb_cache_return_entry_rw      BDB_SYMBOL(cache_return_entry_rw)
-
-#define        bdb_cache_entryinfo_lock(e) \
-       ldap_pvt_thread_mutex_lock( &(e)->bei_kids_mutex )
-#define        bdb_cache_entryinfo_unlock(e) \
-       ldap_pvt_thread_mutex_unlock( &(e)->bei_kids_mutex )
-#define        bdb_cache_entryinfo_trylock(e) \
-       ldap_pvt_thread_mutex_trylock( &(e)->bei_kids_mutex )
-
-/* What a mess. Hopefully the current cache scheme will stabilize
- * and we can trim out all of this stuff.
- */
-void bdb_cache_return_entry_rw( struct bdb_info *bdb, Entry *e,
-       int rw, DB_LOCK *lock );
-#define bdb_cache_return_entry_r(bdb, e, l) \
-       bdb_cache_return_entry_rw((bdb), (e), 0, (l))
-#define bdb_cache_return_entry_w(bdb, e, l) \
-       bdb_cache_return_entry_rw((bdb), (e), 1, (l))
-#if 0
-void bdb_unlocked_cache_return_entry_rw( struct bdb_info *bdb, Entry *e, int rw );
-#else
-#define        bdb_unlocked_cache_return_entry_rw( a, b, c )   ((void)0)
-#endif
-#define bdb_unlocked_cache_return_entry_r( c, e ) \
-       bdb_unlocked_cache_return_entry_rw((c), (e), 0)
-#define bdb_unlocked_cache_return_entry_w( c, e ) \
-       bdb_unlocked_cache_return_entry_rw((c), (e), 1)
-
-#define bdb_cache_add                          BDB_SYMBOL(cache_add)
-#define bdb_cache_children                     BDB_SYMBOL(cache_children)
-#define bdb_cache_delete                       BDB_SYMBOL(cache_delete)
-#define bdb_cache_delete_cleanup       BDB_SYMBOL(cache_delete_cleanup)
-#define bdb_cache_find_id                      BDB_SYMBOL(cache_find_id)
-#define bdb_cache_find_ndn                     BDB_SYMBOL(cache_find_ndn)
-#define bdb_cache_find_parent          BDB_SYMBOL(cache_find_parent)
-#define bdb_cache_modify                       BDB_SYMBOL(cache_modify)
-#define bdb_cache_modrdn                       BDB_SYMBOL(cache_modrdn)
-#define bdb_cache_release_all          BDB_SYMBOL(cache_release_all)
-#define bdb_cache_delete_entry         BDB_SYMBOL(cache_delete_entry)
-#define bdb_cache_deref                                BDB_SYMBOL(cache_deref)
-
-int bdb_cache_children(
-       Operation *op,
-       DB_TXN *txn,
-       Entry *e
-);
-int bdb_cache_add(
-       struct bdb_info *bdb,
-       EntryInfo *pei,
-       Entry   *e,
-       struct berval *nrdn,
-       DB_TXN *txn,
-       DB_LOCK *lock
-);
-int bdb_cache_modrdn(
-       struct bdb_info *bdb,
-       Entry   *e,
-       struct berval *nrdn,
-       Entry   *new,
-       EntryInfo *ein,
-       DB_TXN *txn,
-       DB_LOCK *lock
-);
-int bdb_cache_modify(
-       struct bdb_info *bdb,
-       Entry *e,
-       Attribute *newAttrs,
-       DB_TXN *txn,
-       DB_LOCK *lock
-);
-int bdb_cache_find_ndn(
-       Operation *op,
-       DB_TXN *txn,
-       struct berval   *ndn,
-       EntryInfo       **res
-);
-
-#define        ID_LOCKED       1
-#define        ID_NOCACHE      2
-#define        ID_NOENTRY      4
-#define        ID_CHKPURGE     8
-int bdb_cache_find_id(
-       Operation *op,
-       DB_TXN  *tid,
-       ID              id,
-       EntryInfo **eip,
-       int     flag,
-       DB_LOCK         *lock
-);
-int
-bdb_cache_find_parent(
-       Operation *op,
-       DB_TXN *txn,
-       ID id,
-       EntryInfo **res
-);
-int bdb_cache_delete(
-       struct bdb_info *bdb,
-       Entry   *e,
-       DB_TXN *txn,
-       DB_LOCK *lock
-);
-void bdb_cache_delete_cleanup(
-       Cache   *cache,
-       EntryInfo *ei
-);
-void bdb_cache_release_all( Cache *cache );
-void bdb_cache_deref( EntryInfo *ei );
-
-#ifdef BDB_HIER
-int hdb_cache_load(
-       struct bdb_info *bdb,
-       EntryInfo *ei,
-       EntryInfo **res
-);
-#endif
-
-#define bdb_cache_entry_db_relock              BDB_SYMBOL(cache_entry_db_relock)
-int bdb_cache_entry_db_relock(
-       struct bdb_info *bdb,
-       DB_TXN *txn,
-       EntryInfo *ei,
-       int rw,
-       int tryOnly,
-       DB_LOCK *lock );
-
-int bdb_cache_entry_db_unlock(
-       struct bdb_info *bdb,
-       DB_LOCK *lock );
-
-#define bdb_reader_get                         BDB_SYMBOL(reader_get)
-#define bdb_reader_flush                       BDB_SYMBOL(reader_flush)
-int bdb_reader_get( Operation *op, DB_ENV *env, DB_TXN **txn );
-void bdb_reader_flush( DB_ENV *env );
-
-/*
- * trans.c
- */
-#define bdb_trans_backoff                      BDB_SYMBOL(trans_backoff)
-
-void
-bdb_trans_backoff( int num_retries );
-
-/*
- * former external.h
- */
-
-#define bdb_back_initialize            BDB_SYMBOL(back_initialize)
-#define bdb_db_config                  BDB_SYMBOL(db_config)
-#define bdb_add                                BDB_SYMBOL(add)
-#define bdb_bind                       BDB_SYMBOL(bind)
-#define bdb_compare                    BDB_SYMBOL(compare)
-#define bdb_delete                     BDB_SYMBOL(delete)
-#define bdb_modify                     BDB_SYMBOL(modify)
-#define bdb_modrdn                     BDB_SYMBOL(modrdn)
-#define bdb_search                     BDB_SYMBOL(search)
-#define bdb_extended                   BDB_SYMBOL(extended)
-#define bdb_referrals                  BDB_SYMBOL(referrals)
-#define bdb_operational                        BDB_SYMBOL(operational)
-#define bdb_hasSubordinates            BDB_SYMBOL(hasSubordinates)
-#define bdb_tool_entry_open            BDB_SYMBOL(tool_entry_open)
-#define bdb_tool_entry_close           BDB_SYMBOL(tool_entry_close)
-#define bdb_tool_entry_first_x         BDB_SYMBOL(tool_entry_first_x)
-#define bdb_tool_entry_next            BDB_SYMBOL(tool_entry_next)
-#define bdb_tool_entry_get             BDB_SYMBOL(tool_entry_get)
-#define bdb_tool_entry_put             BDB_SYMBOL(tool_entry_put)
-#define bdb_tool_entry_reindex         BDB_SYMBOL(tool_entry_reindex)
-#define bdb_tool_dn2id_get             BDB_SYMBOL(tool_dn2id_get)
-#define bdb_tool_entry_modify          BDB_SYMBOL(tool_entry_modify)
-#define bdb_tool_idl_add               BDB_SYMBOL(tool_idl_add)
-#define bdb_tool_entry_delete          BDB_SYMBOL(tool_entry_delete)
-
-extern BI_init                         bdb_back_initialize;
-
-extern BI_db_config                    bdb_db_config;
-
-extern BI_op_add                       bdb_add;
-extern BI_op_bind                      bdb_bind;
-extern BI_op_compare                   bdb_compare;
-extern BI_op_delete                    bdb_delete;
-extern BI_op_modify                    bdb_modify;
-extern BI_op_modrdn                    bdb_modrdn;
-extern BI_op_search                    bdb_search;
-extern BI_op_extended                  bdb_extended;
-
-extern BI_chk_referrals                        bdb_referrals;
-
-extern BI_operational                  bdb_operational;
-
-extern BI_has_subordinates             bdb_hasSubordinates;
-
-/* tools.c */
-extern BI_tool_entry_open              bdb_tool_entry_open;
-extern BI_tool_entry_close             bdb_tool_entry_close;
-extern BI_tool_entry_first_x           bdb_tool_entry_first_x;
-extern BI_tool_entry_next              bdb_tool_entry_next;
-extern BI_tool_entry_get               bdb_tool_entry_get;
-extern BI_tool_entry_put               bdb_tool_entry_put;
-extern BI_tool_entry_reindex           bdb_tool_entry_reindex;
-extern BI_tool_dn2id_get               bdb_tool_dn2id_get;
-extern BI_tool_entry_modify            bdb_tool_entry_modify;
-extern BI_tool_entry_delete            bdb_tool_entry_delete;
-
-int bdb_tool_idl_add( BackendDB *be, DB *db, DB_TXN *txn, DBT *key, ID id );
-
-LDAP_END_DECL
-
-#endif /* _PROTO_BDB_H */
diff --git a/servers/slapd/back-bdb/referral.c b/servers/slapd/back-bdb/referral.c
deleted file mode 100644 (file)
index 4507df9..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/* referral.c - BDB backend referral handler */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-
-int
-bdb_referrals( Operation *op, SlapReply *rs )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       Entry *e = NULL;
-       EntryInfo *ei;
-       int rc = LDAP_SUCCESS;
-
-       DB_TXN          *rtxn;
-       DB_LOCK         lock;
-
-       if( op->o_tag == LDAP_REQ_SEARCH ) {
-               /* let search take care of itself */
-               return rc;
-       }
-
-       if( get_manageDSAit( op ) ) {
-               /* let op take care of DSA management */
-               return rc;
-       } 
-
-       rc = bdb_reader_get(op, bdb->bi_dbenv, &rtxn);
-       switch(rc) {
-       case 0:
-               break;
-       default:
-               return LDAP_OTHER;
-       }
-
-dn2entry_retry:
-       /* get entry */
-       rc = bdb_dn2entry( op, rtxn, &op->o_req_ndn, &ei, 1, &lock );
-
-       /* bdb_dn2entry() may legally leave ei == NULL
-        * if rc != 0 and rc != DB_NOTFOUND
-        */
-       if ( ei ) {
-               e = ei->bei_e;
-       }
-
-       switch(rc) {
-       case DB_NOTFOUND:
-       case 0:
-               break;
-       case LDAP_BUSY:
-               rs->sr_text = "ldap server busy";
-               return LDAP_BUSY;
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               goto dn2entry_retry;
-       default:
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_referrals)
-                       ": dn2entry failed: %s (%d)\n",
-                       db_strerror(rc), rc );
-               rs->sr_text = "internal error";
-               return LDAP_OTHER;
-       }
-
-       if ( rc == DB_NOTFOUND ) {
-               rc = LDAP_SUCCESS;
-               rs->sr_matched = NULL;
-               if ( e != NULL ) {
-                       Debug( LDAP_DEBUG_TRACE,
-                               LDAP_XSTRING(bdb_referrals)
-                               ": tag=%lu target=\"%s\" matched=\"%s\"\n",
-                               (unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val );
-
-                       if( is_entry_referral( e ) ) {
-                               BerVarray ref = get_entry_referrals( op, e );
-                               rc = LDAP_OTHER;
-                               rs->sr_ref = referral_rewrite( ref, &e->e_name,
-                                       &op->o_req_dn, LDAP_SCOPE_DEFAULT );
-                               ber_bvarray_free( ref );
-                               if ( rs->sr_ref ) {
-                                       rs->sr_matched = ber_strdup_x(
-                                       e->e_name.bv_val, op->o_tmpmemctx );
-                               }
-                       }
-
-                       bdb_cache_return_entry_r (bdb, e, &lock);
-                       e = NULL;
-               }
-
-               if( rs->sr_ref != NULL ) {
-                       /* send referrals */
-                       rc = rs->sr_err = LDAP_REFERRAL;
-                       send_ldap_result( op, rs );
-                       ber_bvarray_free( rs->sr_ref );
-                       rs->sr_ref = NULL;
-               } else if ( rc != LDAP_SUCCESS ) {
-                       rs->sr_text = rs->sr_matched ? "bad referral object" : NULL;
-               }
-
-               if (rs->sr_matched) {
-                       op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx );
-                       rs->sr_matched = NULL;
-               }
-               return rc;
-       }
-
-       if ( is_entry_referral( e ) ) {
-               /* entry is a referral */
-               BerVarray refs = get_entry_referrals( op, e );
-               rs->sr_ref = referral_rewrite(
-                       refs, &e->e_name, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
-
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_referrals)
-                       ": tag=%lu target=\"%s\" matched=\"%s\"\n",
-                       (unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val );
-
-               rs->sr_matched = e->e_name.bv_val;
-               if( rs->sr_ref != NULL ) {
-                       rc = rs->sr_err = LDAP_REFERRAL;
-                       send_ldap_result( op, rs );
-                       ber_bvarray_free( rs->sr_ref );
-                       rs->sr_ref = NULL;
-               } else {
-                       rc = LDAP_OTHER;
-                       rs->sr_text = "bad referral object";
-               }
-
-               rs->sr_matched = NULL;
-               ber_bvarray_free( refs );
-       }
-
-       bdb_cache_return_entry_r(bdb, e, &lock);
-       return rc;
-}
diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c
deleted file mode 100644 (file)
index 20988bd..0000000
+++ /dev/null
@@ -1,1385 +0,0 @@
-/* search.c - search operation */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-#include "idl.h"
-
-static int base_candidate(
-       BackendDB       *be,
-       Entry   *e,
-       ID              *ids );
-
-static int search_candidates(
-       Operation *op,
-       SlapReply *rs,
-       Entry *e,
-       DB_TXN *txn,
-       ID      *ids,
-       ID      *scopes );
-
-static int parse_paged_cookie( Operation *op, SlapReply *rs );
-
-static void send_paged_response( 
-       Operation *op,
-       SlapReply *rs,
-       ID  *lastid,
-       int tentries );
-
-/* Dereference aliases for a single alias entry. Return the final
- * dereferenced entry on success, NULL on any failure.
- */
-static Entry * deref_base (
-       Operation *op,
-       SlapReply *rs,
-       Entry *e,
-       Entry **matched,
-       DB_TXN *txn,
-       DB_LOCK *lock,
-       ID      *tmp,
-       ID      *visited )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       struct berval ndn;
-       EntryInfo *ei;
-       DB_LOCK lockr;
-
-       rs->sr_err = LDAP_ALIAS_DEREF_PROBLEM;
-       rs->sr_text = "maximum deref depth exceeded";
-
-       for (;;) {
-               /* Remember the last entry we looked at, so we can
-                * report broken links
-                */
-               *matched = e;
-
-               if (BDB_IDL_N(tmp) >= op->o_bd->be_max_deref_depth) {
-                       e = NULL;
-                       break;
-               }
-
-               /* If this is part of a subtree or onelevel search,
-                * have we seen this ID before? If so, quit.
-                */
-               if ( visited && bdb_idl_insert( visited, e->e_id ) ) {
-                       e = NULL;
-                       break;
-               }
-
-               /* If we've seen this ID during this deref iteration,
-                * we've hit a loop.
-                */
-               if ( bdb_idl_insert( tmp, e->e_id ) ) {
-                       rs->sr_err = LDAP_ALIAS_PROBLEM;
-                       rs->sr_text = "circular alias";
-                       e = NULL;
-                       break;
-               }
-
-               /* If there was a problem getting the aliasedObjectName,
-                * get_alias_dn will have set the error status.
-                */
-               if ( get_alias_dn(e, &ndn, &rs->sr_err, &rs->sr_text) ) {
-                       e = NULL;
-                       break;
-               }
-
-               rs->sr_err = bdb_dn2entry( op, txn, &ndn, &ei,
-                       0, &lockr );
-               if ( rs->sr_err == DB_LOCK_DEADLOCK )
-                       return NULL;
-
-               if ( ei ) {
-                       e = ei->bei_e;
-               } else {
-                       e = NULL;
-               }
-
-               if (!e) {
-                       rs->sr_err = LDAP_ALIAS_PROBLEM;
-                       rs->sr_text = "aliasedObject not found";
-                       break;
-               }
-
-               /* Free the previous entry, continue to work with the
-                * one we just retrieved.
-                */
-               bdb_cache_return_entry_r( bdb, *matched, lock);
-               *lock = lockr;
-
-               /* We found a regular entry. Return this to the caller. The
-                * entry is still locked for Read.
-                */
-               if (!is_entry_alias(e)) {
-                       rs->sr_err = LDAP_SUCCESS;
-                       rs->sr_text = NULL;
-                       break;
-               }
-       }
-       return e;
-}
-
-/* Look for and dereference all aliases within the search scope. Adds
- * the dereferenced entries to the "ids" list. Requires "stack" to be
- * able to hold 8 levels of DB_SIZE IDLs. Of course we're hardcoded to
- * require a minimum of 8 UM_SIZE IDLs so this is never a problem.
- */
-static int search_aliases(
-       Operation *op,
-       SlapReply *rs,
-       Entry *e,
-       DB_TXN *txn,
-       ID *ids,
-       ID *scopes,
-       ID *stack )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       ID *aliases, *curscop, *subscop, *visited, *newsubs, *oldsubs, *tmp;
-       ID cursora, ida, cursoro, ido, *subscop2;
-       Entry *matched, *a;
-       EntryInfo *ei;
-       struct berval bv_alias = BER_BVC( "alias" );
-       AttributeAssertion aa_alias = ATTRIBUTEASSERTION_INIT;
-       Filter  af;
-       DB_LOCK locka, lockr;
-       int first = 1;
-
-       aliases = stack;        /* IDL of all aliases in the database */
-       curscop = aliases + BDB_IDL_DB_SIZE;    /* Aliases in the current scope */
-       subscop = curscop + BDB_IDL_DB_SIZE;    /* The current scope */
-       visited = subscop + BDB_IDL_DB_SIZE;    /* IDs we've seen in this search */
-       newsubs = visited + BDB_IDL_DB_SIZE;    /* New subtrees we've added */
-       oldsubs = newsubs + BDB_IDL_DB_SIZE;    /* Subtrees added previously */
-       tmp = oldsubs + BDB_IDL_DB_SIZE;        /* Scratch space for deref_base() */
-
-       /* A copy of subscop, because subscop gets clobbered by
-        * the bdb_idl_union/intersection routines
-        */
-       subscop2 = tmp + BDB_IDL_DB_SIZE;
-
-       af.f_choice = LDAP_FILTER_EQUALITY;
-       af.f_ava = &aa_alias;
-       af.f_av_desc = slap_schema.si_ad_objectClass;
-       af.f_av_value = bv_alias;
-       af.f_next = NULL;
-
-       /* Find all aliases in database */
-       BDB_IDL_ZERO( aliases );
-       rs->sr_err = bdb_filter_candidates( op, txn, &af, aliases,
-               curscop, visited );
-       if (rs->sr_err != LDAP_SUCCESS || BDB_IDL_IS_ZERO( aliases )) {
-               return rs->sr_err;
-       }
-       oldsubs[0] = 1;
-       oldsubs[1] = e->e_id;
-
-       BDB_IDL_ZERO( ids );
-       BDB_IDL_ZERO( visited );
-       BDB_IDL_ZERO( newsubs );
-
-       cursoro = 0;
-       ido = bdb_idl_first( oldsubs, &cursoro );
-
-       for (;;) {
-               /* Set curscop to only the aliases in the current scope. Start with
-                * all the aliases, obtain the IDL for the current scope, and then
-                * get the intersection of these two IDLs. Add the current scope
-                * to the cumulative list of candidates.
-                */
-               BDB_IDL_CPY( curscop, aliases );
-               rs->sr_err = bdb_dn2idl( op, txn, &e->e_nname, BEI(e), subscop,
-                       subscop2+BDB_IDL_DB_SIZE );
-
-               if (first) {
-                       first = 0;
-               } else {
-                       bdb_cache_return_entry_r (bdb, e, &locka);
-               }
-               if ( rs->sr_err == DB_LOCK_DEADLOCK )
-                       return rs->sr_err;
-
-               BDB_IDL_CPY(subscop2, subscop);
-               rs->sr_err = bdb_idl_intersection(curscop, subscop);
-               bdb_idl_union( ids, subscop2 );
-
-               /* Dereference all of the aliases in the current scope. */
-               cursora = 0;
-               for (ida = bdb_idl_first(curscop, &cursora); ida != NOID;
-                       ida = bdb_idl_next(curscop, &cursora))
-               {
-                       ei = NULL;
-retry1:
-                       rs->sr_err = bdb_cache_find_id(op, txn,
-                               ida, &ei, 0, &lockr );
-                       if (rs->sr_err != LDAP_SUCCESS) {
-                               if ( rs->sr_err == DB_LOCK_DEADLOCK )
-                                       return rs->sr_err;
-                               if ( rs->sr_err == DB_LOCK_NOTGRANTED )
-                                       goto retry1;
-                               continue;
-                       }
-                       a = ei->bei_e;
-
-                       /* This should only happen if the curscop IDL has maxed out and
-                        * turned into a range that spans IDs indiscriminately
-                        */
-                       if (!is_entry_alias(a)) {
-                               bdb_cache_return_entry_r (bdb, a, &lockr);
-                               continue;
-                       }
-
-                       /* Actually dereference the alias */
-                       BDB_IDL_ZERO(tmp);
-                       a = deref_base( op, rs, a, &matched, txn, &lockr,
-                               tmp, visited );
-                       if (a) {
-                               /* If the target was not already in our current candidates,
-                                * make note of it in the newsubs list. Also
-                                * set it in the scopes list so that bdb_search
-                                * can check it.
-                                */
-                               if (bdb_idl_insert(ids, a->e_id) == 0) {
-                                       bdb_idl_insert(newsubs, a->e_id);
-                                       bdb_idl_insert(scopes, a->e_id);
-                               }
-                               bdb_cache_return_entry_r( bdb, a, &lockr);
-
-                       } else if ( rs->sr_err == DB_LOCK_DEADLOCK ) {
-                               return rs->sr_err;
-                       } else if (matched) {
-                               /* Alias could not be dereferenced, or it deref'd to
-                                * an ID we've already seen. Ignore it.
-                                */
-                               bdb_cache_return_entry_r( bdb, matched, &lockr );
-                               rs->sr_text = NULL;
-                       }
-               }
-               /* If this is a OneLevel search, we're done; oldsubs only had one
-                * ID in it. For a Subtree search, oldsubs may be a list of scope IDs.
-                */
-               if ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) break;
-nextido:
-               ido = bdb_idl_next( oldsubs, &cursoro );
-               
-               /* If we're done processing the old scopes, did we add any new
-                * scopes in this iteration? If so, go back and do those now.
-                */
-               if (ido == NOID) {
-                       if (BDB_IDL_IS_ZERO(newsubs)) break;
-                       BDB_IDL_CPY(oldsubs, newsubs);
-                       BDB_IDL_ZERO(newsubs);
-                       cursoro = 0;
-                       ido = bdb_idl_first( oldsubs, &cursoro );
-               }
-
-               /* Find the entry corresponding to the next scope. If it can't
-                * be found, ignore it and move on. This should never happen;
-                * we should never see the ID of an entry that doesn't exist.
-                * Set the name so that the scope's IDL can be retrieved.
-                */
-               ei = NULL;
-sameido:
-               rs->sr_err = bdb_cache_find_id(op, txn, ido, &ei,
-                       0, &locka );
-               if ( rs->sr_err != LDAP_SUCCESS ) {
-                       if ( rs->sr_err == DB_LOCK_DEADLOCK )
-                               return rs->sr_err;
-                       if ( rs->sr_err == DB_LOCK_NOTGRANTED )
-                               goto sameido;
-                       goto nextido;
-               }
-               e = ei->bei_e;
-       }
-       return rs->sr_err;
-}
-
-/* Get the next ID from the DB. Used if the candidate list is
- * a range and simple iteration hits missing entryIDs
- */
-static int
-bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor)
-{
-       DBC *curs;
-       DBT key, data;
-       ID id, nid;
-       int rc;
-
-       id = *cursor + 1;
-       BDB_ID2DISK( id, &nid );
-       rc = bdb->bi_id2entry->bdi_db->cursor(
-               bdb->bi_id2entry->bdi_db, ltid, &curs, bdb->bi_db_opflags );
-       if ( rc )
-               return rc;
-       key.data = &nid;
-       key.size = key.ulen = sizeof(ID);
-       key.flags = DB_DBT_USERMEM;
-       data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
-       data.dlen = data.ulen = 0;
-       rc = curs->c_get( curs, &key, &data, DB_SET_RANGE );
-       curs->c_close( curs );
-       if ( rc )
-               return rc;
-       BDB_DISK2ID( &nid, cursor );
-       return 0;
-}
-
-int
-bdb_search( Operation *op, SlapReply *rs )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       ID              id, cursor;
-       ID              lastid = NOID;
-       ID              candidates[BDB_IDL_UM_SIZE];
-       ID              scopes[BDB_IDL_DB_SIZE];
-       Entry           *e = NULL, base, *e_root;
-       Entry           *matched = NULL;
-       EntryInfo       *ei;
-       AttributeName   *attrs;
-       struct berval   realbase = BER_BVNULL;
-       slap_mask_t     mask;
-       time_t          stoptime;
-       int             manageDSAit;
-       int             tentries = 0;
-       unsigned        nentries = 0;
-       int             idflag = 0;
-
-       DB_LOCK         lock;
-       struct  bdb_op_info     *opinfo = NULL;
-       DB_TXN                  *ltid = NULL;
-       OpExtra *oex;
-
-       Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(bdb_search) "\n" );
-       attrs = op->oq_search.rs_attrs;
-
-       LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
-               if ( oex->oe_key == bdb )
-                       break;
-       }
-       opinfo = (struct bdb_op_info *) oex;
-
-       manageDSAit = get_manageDSAit( op );
-
-       if ( opinfo && opinfo->boi_txn ) {
-               ltid = opinfo->boi_txn;
-       } else {
-               rs->sr_err = bdb_reader_get( op, bdb->bi_dbenv, &ltid );
-
-               switch(rs->sr_err) {
-               case 0:
-                       break;
-               default:
-                       send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-                       return rs->sr_err;
-               }
-       }
-
-       e_root = bdb->bi_cache.c_dntree.bei_e;
-       if ( op->o_req_ndn.bv_len == 0 ) {
-               /* DIT root special case */
-               ei = e_root->e_private;
-               rs->sr_err = LDAP_SUCCESS;
-       } else {
-               if ( op->ors_deref & LDAP_DEREF_FINDING ) {
-                       BDB_IDL_ZERO(candidates);
-               }
-dn2entry_retry:
-               /* get entry with reader lock */
-               rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei,
-                       1, &lock );
-       }
-
-       switch(rs->sr_err) {
-       case DB_NOTFOUND:
-               matched = ei->bei_e;
-               break;
-       case 0:
-               e = ei->bei_e;
-               break;
-       case DB_LOCK_DEADLOCK:
-               if ( !opinfo ) {
-                       ltid->flags &= ~TXN_DEADLOCK;
-                       goto dn2entry_retry;
-               }
-               opinfo->boi_err = rs->sr_err;
-               /* FALLTHRU */
-       case LDAP_BUSY:
-               send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" );
-               return LDAP_BUSY;
-       case DB_LOCK_NOTGRANTED:
-               goto dn2entry_retry;
-       default:
-               send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-               return rs->sr_err;
-       }
-
-       if ( op->ors_deref & LDAP_DEREF_FINDING ) {
-               if ( matched && is_entry_alias( matched )) {
-                       struct berval stub;
-
-                       stub.bv_val = op->o_req_ndn.bv_val;
-                       stub.bv_len = op->o_req_ndn.bv_len - matched->e_nname.bv_len - 1;
-                       e = deref_base( op, rs, matched, &matched, ltid, &lock,
-                               candidates, NULL );
-                       if ( e ) {
-                               build_new_dn( &op->o_req_ndn, &e->e_nname, &stub,
-                                       op->o_tmpmemctx );
-                               bdb_cache_return_entry_r (bdb, e, &lock);
-                               matched = NULL;
-                               goto dn2entry_retry;
-                       }
-               } else if ( e && is_entry_alias( e )) {
-                       e = deref_base( op, rs, e, &matched, ltid, &lock,
-                               candidates, NULL );
-               }
-       }
-
-       if ( e == NULL ) {
-               struct berval matched_dn = BER_BVNULL;
-
-               if ( matched != NULL ) {
-                       BerVarray erefs = NULL;
-
-                       /* return referral only if "disclose"
-                        * is granted on the object */
-                       if ( ! access_allowed( op, matched,
-                                               slap_schema.si_ad_entry,
-                                               NULL, ACL_DISCLOSE, NULL ) )
-                       {
-                               rs->sr_err = LDAP_NO_SUCH_OBJECT;
-
-                       } else {
-                               ber_dupbv( &matched_dn, &matched->e_name );
-
-                               erefs = is_entry_referral( matched )
-                                       ? get_entry_referrals( op, matched )
-                                       : NULL;
-                               if ( rs->sr_err == DB_NOTFOUND )
-                                       rs->sr_err = LDAP_REFERRAL;
-                               rs->sr_matched = matched_dn.bv_val;
-                       }
-
-#ifdef SLAP_ZONE_ALLOC
-                       slap_zn_runlock(bdb->bi_cache.c_zctx, matched);
-#endif
-                       bdb_cache_return_entry_r (bdb, matched, &lock);
-                       matched = NULL;
-
-                       if ( erefs ) {
-                               rs->sr_ref = referral_rewrite( erefs, &matched_dn,
-                                       &op->o_req_dn, op->oq_search.rs_scope );
-                               ber_bvarray_free( erefs );
-                       }
-
-               } else {
-#ifdef SLAP_ZONE_ALLOC
-                       slap_zn_runlock(bdb->bi_cache.c_zctx, matched);
-#endif
-                       rs->sr_ref = referral_rewrite( default_referral,
-                               NULL, &op->o_req_dn, op->oq_search.rs_scope );
-                       rs->sr_err = rs->sr_ref != NULL ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT;
-               }
-
-               send_ldap_result( op, rs );
-
-               if ( rs->sr_ref ) {
-                       ber_bvarray_free( rs->sr_ref );
-                       rs->sr_ref = NULL;
-               }
-               if ( !BER_BVISNULL( &matched_dn ) ) {
-                       ber_memfree( matched_dn.bv_val );
-                       rs->sr_matched = NULL;
-               }
-               return rs->sr_err;
-       }
-
-       /* NOTE: __NEW__ "search" access is required
-        * on searchBase object */
-       if ( ! access_allowed_mask( op, e, slap_schema.si_ad_entry,
-                               NULL, ACL_SEARCH, NULL, &mask ) )
-       {
-               if ( !ACL_GRANT( mask, ACL_DISCLOSE ) ) {
-                       rs->sr_err = LDAP_NO_SUCH_OBJECT;
-               } else {
-                       rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-               }
-
-#ifdef SLAP_ZONE_ALLOC
-               slap_zn_runlock(bdb->bi_cache.c_zctx, e);
-#endif
-               if ( e != e_root ) {
-                       bdb_cache_return_entry_r(bdb, e, &lock);
-               }
-               send_ldap_result( op, rs );
-               return rs->sr_err;
-       }
-
-       if ( !manageDSAit && e != e_root && is_entry_referral( e ) ) {
-               /* entry is a referral, don't allow add */
-               struct berval matched_dn = BER_BVNULL;
-               BerVarray erefs = NULL;
-               
-               ber_dupbv( &matched_dn, &e->e_name );
-               erefs = get_entry_referrals( op, e );
-
-               rs->sr_err = LDAP_REFERRAL;
-
-#ifdef SLAP_ZONE_ALLOC
-               slap_zn_runlock(bdb->bi_cache.c_zctx, e);
-#endif
-               bdb_cache_return_entry_r( bdb, e, &lock );
-               e = NULL;
-
-               if ( erefs ) {
-                       rs->sr_ref = referral_rewrite( erefs, &matched_dn,
-                               &op->o_req_dn, op->oq_search.rs_scope );
-                       ber_bvarray_free( erefs );
-
-                       if ( !rs->sr_ref ) {
-                               rs->sr_text = "bad_referral object";
-                       }
-               }
-
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_search) ": entry is referral\n" );
-
-               rs->sr_matched = matched_dn.bv_val;
-               send_ldap_result( op, rs );
-
-               ber_bvarray_free( rs->sr_ref );
-               rs->sr_ref = NULL;
-               ber_memfree( matched_dn.bv_val );
-               rs->sr_matched = NULL;
-               return 1;
-       }
-
-       if ( get_assert( op ) &&
-               ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
-       {
-               rs->sr_err = LDAP_ASSERTION_FAILED;
-#ifdef SLAP_ZONE_ALLOC
-               slap_zn_runlock(bdb->bi_cache.c_zctx, e);
-#endif
-               if ( e != e_root ) {
-                       bdb_cache_return_entry_r(bdb, e, &lock);
-               }
-               send_ldap_result( op, rs );
-               return 1;
-       }
-
-       /* compute it anyway; root does not use it */
-       stoptime = op->o_time + op->ors_tlimit;
-
-       /* need normalized dn below */
-       ber_dupbv( &realbase, &e->e_nname );
-
-       /* Copy info to base, must free entry before accessing the database
-        * in search_candidates, to avoid deadlocks.
-        */
-       base.e_private = e->e_private;
-       base.e_nname = realbase;
-       base.e_id = e->e_id;
-
-#ifdef SLAP_ZONE_ALLOC
-       slap_zn_runlock(bdb->bi_cache.c_zctx, e);
-#endif
-       if ( e != e_root ) {
-               bdb_cache_return_entry_r(bdb, e, &lock);
-       }
-       e = NULL;
-
-       /* select candidates */
-       if ( op->oq_search.rs_scope == LDAP_SCOPE_BASE ) {
-               rs->sr_err = base_candidate( op->o_bd, &base, candidates );
-
-       } else {
-cand_retry:
-               BDB_IDL_ZERO( candidates );
-               BDB_IDL_ZERO( scopes );
-               rs->sr_err = search_candidates( op, rs, &base,
-                       ltid, candidates, scopes );
-               if ( rs->sr_err == DB_LOCK_DEADLOCK ) {
-                       if ( !opinfo ) {
-                               ltid->flags &= ~TXN_DEADLOCK;
-                               goto cand_retry;
-                       }
-                       opinfo->boi_err = rs->sr_err;
-                       send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" );
-                       return LDAP_BUSY;
-               }
-       }
-
-       /* start cursor at beginning of candidates.
-        */
-       cursor = 0;
-
-       if ( candidates[0] == 0 ) {
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_search) ": no candidates\n" );
-
-               goto nochange;
-       }
-
-       /* if not root and candidates exceed to-be-checked entries, abort */
-       if ( op->ors_limit      /* isroot == FALSE */ &&
-               op->ors_limit->lms_s_unchecked != -1 &&
-               BDB_IDL_N(candidates) > (unsigned) op->ors_limit->lms_s_unchecked )
-       {
-               rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;
-               send_ldap_result( op, rs );
-               rs->sr_err = LDAP_SUCCESS;
-               goto done;
-       }
-
-       if ( op->ors_limit == NULL      /* isroot == TRUE */ ||
-               !op->ors_limit->lms_s_pr_hide )
-       {
-               tentries = BDB_IDL_N(candidates);
-       }
-
-       if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ) {
-               PagedResultsState *ps = op->o_pagedresults_state;
-               /* deferred cookie parsing */
-               rs->sr_err = parse_paged_cookie( op, rs );
-               if ( rs->sr_err != LDAP_SUCCESS ) {
-                       send_ldap_result( op, rs );
-                       goto done;
-               }
-
-               cursor = (ID) ps->ps_cookie;
-               if ( cursor && ps->ps_size == 0 ) {
-                       rs->sr_err = LDAP_SUCCESS;
-                       rs->sr_text = "search abandoned by pagedResult size=0";
-                       send_ldap_result( op, rs );
-                       goto done;
-               }
-               id = bdb_idl_first( candidates, &cursor );
-               if ( id == NOID ) {
-                       Debug( LDAP_DEBUG_TRACE, 
-                               LDAP_XSTRING(bdb_search)
-                               ": no paged results candidates\n" );
-                       send_paged_response( op, rs, &lastid, 0 );
-
-                       rs->sr_err = LDAP_OTHER;
-                       goto done;
-               }
-               nentries = ps->ps_count;
-               if ( id == (ID)ps->ps_cookie )
-                       id = bdb_idl_next( candidates, &cursor );
-               goto loop_begin;
-       }
-
-       for ( id = bdb_idl_first( candidates, &cursor );
-                 id != NOID ; id = bdb_idl_next( candidates, &cursor ) )
-       {
-               int scopeok;
-
-loop_begin:
-
-               /* check for abandon */
-               if ( op->o_abandon ) {
-                       rs->sr_err = SLAPD_ABANDON;
-                       send_ldap_result( op, rs );
-                       goto done;
-               }
-
-               /* mostly needed by internal searches,
-                * e.g. related to syncrepl, for whom
-                * abandon does not get set... */
-               if ( slapd_shutdown ) {
-                       rs->sr_err = LDAP_UNAVAILABLE;
-                       send_ldap_disconnect( op, rs );
-                       goto done;
-               }
-
-               /* check time limit */
-               if ( op->ors_tlimit != SLAP_NO_LIMIT
-                               && slap_get_time() > stoptime )
-               {
-                       rs->sr_err = LDAP_TIMELIMIT_EXCEEDED;
-                       rs->sr_ref = rs->sr_v2ref;
-                       send_ldap_result( op, rs );
-                       rs->sr_err = LDAP_SUCCESS;
-                       goto done;
-               }
-
-               /* If we inspect more entries than will
-                * fit into the entry cache, stop caching
-                * any subsequent entries
-                */
-               nentries++;
-               if ( nentries > bdb->bi_cache.c_maxsize && !idflag ) {
-                       idflag = ID_NOCACHE;
-               }
-
-fetch_entry_retry:
-               /* get the entry with reader lock */
-               ei = NULL;
-               rs->sr_err = bdb_cache_find_id( op, ltid,
-                       id, &ei, idflag, &lock );
-
-               if (rs->sr_err == LDAP_BUSY) {
-                       rs->sr_text = "ldap server busy";
-                       send_ldap_result( op, rs );
-                       goto done;
-
-               } else if ( rs->sr_err == DB_LOCK_DEADLOCK ) {
-                       if ( !opinfo ) {
-                               ltid->flags &= ~TXN_DEADLOCK;
-                               goto fetch_entry_retry;
-                       }
-txnfail:
-                       opinfo->boi_err = rs->sr_err;
-                       send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" );
-                       goto done;
-
-               } else if ( rs->sr_err == DB_LOCK_NOTGRANTED )
-               {
-                       goto fetch_entry_retry;
-               } else if ( rs->sr_err == LDAP_OTHER ) {
-                       rs->sr_text = "internal error";
-                       send_ldap_result( op, rs );
-                       goto done;
-               }
-
-               if ( ei && rs->sr_err == LDAP_SUCCESS ) {
-                       e = ei->bei_e;
-               } else {
-                       e = NULL;
-               }
-
-               if ( e == NULL ) {
-                       if( !BDB_IDL_IS_RANGE(candidates) ) {
-                               /* only complain for non-range IDLs */
-                               Debug( LDAP_DEBUG_TRACE,
-                                       LDAP_XSTRING(bdb_search)
-                                       ": candidate %ld not found\n",
-                                       (long) id );
-                       } else {
-                               /* get the next ID from the DB */
-id_retry:
-                               rs->sr_err = bdb_get_nextid( bdb, ltid, &cursor );
-                               if ( rs->sr_err == DB_NOTFOUND ) {
-                                       break;
-                               } else if ( rs->sr_err == DB_LOCK_DEADLOCK ) {
-                                       if ( opinfo )
-                                               goto txnfail;
-                                       ltid->flags &= ~TXN_DEADLOCK;
-                                       goto id_retry;
-                               } else if ( rs->sr_err == DB_LOCK_NOTGRANTED ) {
-                                       goto id_retry;
-                               }
-                               if ( rs->sr_err ) {
-                                       rs->sr_err = LDAP_OTHER;
-                                       rs->sr_text = "internal error in get_nextid";
-                                       send_ldap_result( op, rs );
-                                       goto done;
-                               }
-                               cursor--;
-                       }
-
-                       goto loop_continue;
-               }
-
-               if ( is_entry_subentry( e ) ) {
-                       if( op->oq_search.rs_scope != LDAP_SCOPE_BASE ) {
-                               if(!get_subentries_visibility( op )) {
-                                       /* only subentries are visible */
-                                       goto loop_continue;
-                               }
-
-                       } else if ( get_subentries( op ) &&
-                               !get_subentries_visibility( op ))
-                       {
-                               /* only subentries are visible */
-                               goto loop_continue;
-                       }
-
-               } else if ( get_subentries_visibility( op )) {
-                       /* only subentries are visible */
-                       goto loop_continue;
-               }
-
-               /* Does this candidate actually satisfy the search scope?
-                *
-                * Note that we don't lock access to the bei_parent pointer.
-                * Since only leaf nodes can be deleted, the parent of any
-                * node will always be a valid node. Also since we have
-                * a Read lock on the data, it cannot be renamed out of the
-                * scope while we are looking at it, and unless we're using
-                * BDB_HIER, its parents cannot be moved either.
-                */
-               scopeok = 0;
-               switch( op->ors_scope ) {
-               case LDAP_SCOPE_BASE:
-                       /* This is always true, yes? */
-                       if ( id == base.e_id ) scopeok = 1;
-                       break;
-
-               case LDAP_SCOPE_ONELEVEL:
-                       if ( ei->bei_parent->bei_id == base.e_id ) scopeok = 1;
-                       break;
-
-#ifdef LDAP_SCOPE_CHILDREN
-               case LDAP_SCOPE_CHILDREN:
-                       if ( id == base.e_id ) break;
-                       /* Fall-thru */
-#endif
-               case LDAP_SCOPE_SUBTREE: {
-                       EntryInfo *tmp;
-                       for ( tmp = BEI(e); tmp; tmp = tmp->bei_parent ) {
-                               if ( tmp->bei_id == base.e_id ) {
-                                       scopeok = 1;
-                                       break;
-                               }
-                       }
-                       } break;
-               }
-
-               /* aliases were already dereferenced in candidate list */
-               if ( op->ors_deref & LDAP_DEREF_SEARCHING ) {
-                       /* but if the search base is an alias, and we didn't
-                        * deref it when finding, return it.
-                        */
-                       if ( is_entry_alias(e) &&
-                               ((op->ors_deref & LDAP_DEREF_FINDING) ||
-                                       !bvmatch(&e->e_nname, &op->o_req_ndn)))
-                       {
-                               goto loop_continue;
-                       }
-
-                       /* scopes is only non-empty for onelevel or subtree */
-                       if ( !scopeok && BDB_IDL_N(scopes) ) {
-                               unsigned x;
-                               if ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) {
-                                       x = bdb_idl_search( scopes, e->e_id );
-                                       if ( scopes[x] == e->e_id ) scopeok = 1;
-                               } else {
-                                       /* subtree, walk up the tree */
-                                       EntryInfo *tmp = BEI(e);
-                                       for (;tmp->bei_parent; tmp=tmp->bei_parent) {
-                                               x = bdb_idl_search( scopes, tmp->bei_id );
-                                               if ( scopes[x] == tmp->bei_id ) {
-                                                       scopeok = 1;
-                                                       break;
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               /* Not in scope, ignore it */
-               if ( !scopeok )
-               {
-                       Debug( LDAP_DEBUG_TRACE,
-                               LDAP_XSTRING(bdb_search)
-                               ": %ld scope not okay\n",
-                               (long) id );
-                       goto loop_continue;
-               }
-
-               /*
-                * if it's a referral, add it to the list of referrals. only do
-                * this for non-base searches, and don't check the filter
-                * explicitly here since it's only a candidate anyway.
-                */
-               if ( !manageDSAit && op->oq_search.rs_scope != LDAP_SCOPE_BASE
-                       && is_entry_referral( e ) )
-               {
-                       struct bdb_op_info bois;
-                       struct bdb_lock_info blis;
-                       BerVarray erefs = get_entry_referrals( op, e );
-                       rs->sr_ref = referral_rewrite( erefs, &e->e_name, NULL,
-                               op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL
-                                       ? LDAP_SCOPE_BASE : LDAP_SCOPE_SUBTREE );
-
-                       /* Must set lockinfo so that entry_release will work */
-                       if (!opinfo) {
-                               bois.boi_oe.oe_key = bdb;
-                               bois.boi_txn = NULL;
-                               bois.boi_err = 0;
-                               bois.boi_acl_cache = op->o_do_not_cache;
-                               bois.boi_flag = BOI_DONTFREE;
-                               bois.boi_locks = &blis;
-                               blis.bli_next = NULL;
-                               LDAP_SLIST_INSERT_HEAD( &op->o_extra, &bois.boi_oe,
-                                       oe_next );
-                       } else {
-                               blis.bli_next = opinfo->boi_locks;
-                               opinfo->boi_locks = &blis;
-                       }
-                       blis.bli_id = e->e_id;
-                       blis.bli_lock = lock;
-                       blis.bli_flag = BLI_DONTFREE;
-
-                       rs->sr_entry = e;
-                       rs->sr_flags = REP_ENTRY_MUSTRELEASE;
-
-                       send_search_reference( op, rs );
-
-                       if ( blis.bli_flag ) {
-#ifdef SLAP_ZONE_ALLOC
-                               slap_zn_runlock(bdb->bi_cache.c_zctx, e);
-#endif
-                               bdb_cache_return_entry_r(bdb, e, &lock);
-                               if ( opinfo ) {
-                                       opinfo->boi_locks = blis.bli_next;
-                               } else {
-                                       LDAP_SLIST_REMOVE( &op->o_extra, &bois.boi_oe,
-                                               OpExtra, oe_next );
-                               }
-                       }
-                       rs->sr_entry = NULL;
-                       e = NULL;
-
-                       ber_bvarray_free( rs->sr_ref );
-                       ber_bvarray_free( erefs );
-                       rs->sr_ref = NULL;
-
-                       goto loop_continue;
-               }
-
-               if ( !manageDSAit && is_entry_glue( e )) {
-                       goto loop_continue;
-               }
-
-               /* if it matches the filter and scope, send it */
-               rs->sr_err = test_filter( op, e, op->oq_search.rs_filter );
-
-               if ( rs->sr_err == LDAP_COMPARE_TRUE ) {
-                       /* check size limit */
-                       if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
-                               if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) {
-#ifdef SLAP_ZONE_ALLOC
-                                       slap_zn_runlock(bdb->bi_cache.c_zctx, e);
-#endif
-                                       bdb_cache_return_entry_r( bdb, e, &lock );
-                                       e = NULL;
-                                       send_paged_response( op, rs, &lastid, tentries );
-                                       goto done;
-                               }
-                               lastid = id;
-                       }
-
-                       if (e) {
-                               struct bdb_op_info bois;
-                               struct bdb_lock_info blis;
-
-                               /* Must set lockinfo so that entry_release will work */
-                               if (!opinfo) {
-                                       bois.boi_oe.oe_key = bdb;
-                                       bois.boi_txn = NULL;
-                                       bois.boi_err = 0;
-                                       bois.boi_acl_cache = op->o_do_not_cache;
-                                       bois.boi_flag = BOI_DONTFREE;
-                                       bois.boi_locks = &blis;
-                                       blis.bli_next = NULL;
-                                       LDAP_SLIST_INSERT_HEAD( &op->o_extra, &bois.boi_oe,
-                                               oe_next );
-                               } else {
-                                       blis.bli_next = opinfo->boi_locks;
-                                       opinfo->boi_locks = &blis;
-                               }
-                               blis.bli_id = e->e_id;
-                               blis.bli_lock = lock;
-                               blis.bli_flag = BLI_DONTFREE;
-
-                               /* safe default */
-                               rs->sr_attrs = op->oq_search.rs_attrs;
-                               rs->sr_operational_attrs = NULL;
-                               rs->sr_ctrls = NULL;
-                               rs->sr_entry = e;
-                               RS_ASSERT( e->e_private != NULL );
-                               rs->sr_flags = REP_ENTRY_MUSTRELEASE;
-                               rs->sr_err = LDAP_SUCCESS;
-                               rs->sr_err = send_search_entry( op, rs );
-                               rs->sr_attrs = NULL;
-                               rs->sr_entry = NULL;
-
-                               /* send_search_entry will usually free it.
-                                * an overlay might leave its own copy here;
-                                * bli_flag will be 0 if lock was already released.
-                                */
-                               if ( blis.bli_flag ) {
-#ifdef SLAP_ZONE_ALLOC
-                                       slap_zn_runlock(bdb->bi_cache.c_zctx, e);
-#endif
-                                       bdb_cache_return_entry_r(bdb, e, &lock);
-                                       if ( opinfo ) {
-                                               opinfo->boi_locks = blis.bli_next;
-                                       } else {
-                                               LDAP_SLIST_REMOVE( &op->o_extra, &bois.boi_oe,
-                                                       OpExtra, oe_next );
-                                       }
-                               }
-                               e = NULL;
-
-                               switch ( rs->sr_err ) {
-                               case LDAP_SUCCESS:      /* entry sent ok */
-                                       break;
-                               default:                /* entry not sent */
-                                       break;
-                               case LDAP_BUSY:
-                                       send_ldap_result( op, rs );
-                                       goto done;
-                               case LDAP_UNAVAILABLE:
-                               case LDAP_SIZELIMIT_EXCEEDED:
-                                       if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ) {
-                                               rs->sr_ref = rs->sr_v2ref;
-                                               send_ldap_result( op, rs );
-                                               rs->sr_err = LDAP_SUCCESS;
-
-                                       } else {
-                                               rs->sr_err = LDAP_OTHER;
-                                       }
-                                       goto done;
-                               }
-                       }
-
-               } else {
-                       Debug( LDAP_DEBUG_TRACE,
-                               LDAP_XSTRING(bdb_search)
-                               ": %ld does not match filter\n",
-                               (long) id );
-               }
-
-loop_continue:
-               if( e != NULL ) {
-                       /* free reader lock */
-#ifdef SLAP_ZONE_ALLOC
-                       slap_zn_runlock(bdb->bi_cache.c_zctx, e);
-#endif
-                       bdb_cache_return_entry_r( bdb, e , &lock );
-                       RS_ASSERT( rs->sr_entry == NULL );
-                       e = NULL;
-                       rs->sr_entry = NULL;
-               }
-       }
-
-nochange:
-       rs->sr_ctrls = NULL;
-       rs->sr_ref = rs->sr_v2ref;
-       rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL;
-       rs->sr_rspoid = NULL;
-       if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
-               send_paged_response( op, rs, NULL, 0 );
-       } else {
-               send_ldap_result( op, rs );
-       }
-
-       rs->sr_err = LDAP_SUCCESS;
-
-done:
-       if( rs->sr_v2ref ) {
-               ber_bvarray_free( rs->sr_v2ref );
-               rs->sr_v2ref = NULL;
-       }
-       if( realbase.bv_val ) ch_free( realbase.bv_val );
-
-       return rs->sr_err;
-}
-
-
-static int base_candidate(
-       BackendDB       *be,
-       Entry   *e,
-       ID              *ids )
-{
-       Debug(LDAP_DEBUG_ARGS, "base_candidates: base: \"%s\" (0x%08lx)\n",
-               e->e_nname.bv_val, (long) e->e_id );
-
-       ids[0] = 1;
-       ids[1] = e->e_id;
-       return 0;
-}
-
-/* Look for "objectClass Present" in this filter.
- * Also count depth of filter tree while we're at it.
- */
-static int oc_filter(
-       Filter *f,
-       int cur,
-       int *max )
-{
-       int rc = 0;
-
-       assert( f != NULL );
-
-       if( cur > *max ) *max = cur;
-
-       switch( f->f_choice ) {
-       case LDAP_FILTER_PRESENT:
-               if (f->f_desc == slap_schema.si_ad_objectClass) {
-                       rc = 1;
-               }
-               break;
-
-       case LDAP_FILTER_AND:
-       case LDAP_FILTER_OR:
-               cur++;
-               for ( f=f->f_and; f; f=f->f_next ) {
-                       (void) oc_filter(f, cur, max);
-               }
-               break;
-
-       default:
-               break;
-       }
-       return rc;
-}
-
-static void search_stack_free( void *key, void *data )
-{
-       ber_memfree_x(data, NULL);
-}
-
-static void *search_stack( Operation *op )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       void *ret = NULL;
-
-       if ( op->o_threadctx ) {
-               ldap_pvt_thread_pool_getkey( op->o_threadctx, (void *)search_stack,
-                       &ret, NULL );
-       } else {
-               ret = bdb->bi_search_stack;
-       }
-
-       if ( !ret ) {
-               ret = ch_malloc( bdb->bi_search_stack_depth * BDB_IDL_UM_SIZE
-                       * sizeof( ID ) );
-               if ( op->o_threadctx ) {
-                       ldap_pvt_thread_pool_setkey( op->o_threadctx, (void *)search_stack,
-                               ret, search_stack_free, NULL, NULL );
-               } else {
-                       bdb->bi_search_stack = ret;
-               }
-       }
-       return ret;
-}
-
-static int search_candidates(
-       Operation *op,
-       SlapReply *rs,
-       Entry *e,
-       DB_TXN *txn,
-       ID      *ids,
-       ID      *scopes )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-       int rc, depth = 1;
-       Filter          f, rf, xf, nf;
-       ID              *stack;
-       AttributeAssertion aa_ref = ATTRIBUTEASSERTION_INIT;
-       Filter  sf;
-       AttributeAssertion aa_subentry = ATTRIBUTEASSERTION_INIT;
-
-       /*
-        * This routine takes as input a filter (user-filter)
-        * and rewrites it as follows:
-        *      (&(scope=DN)[(objectClass=subentry)]
-        *              (|[(objectClass=referral)(objectClass=alias)](user-filter))
-        */
-
-       Debug(LDAP_DEBUG_TRACE,
-               "search_candidates: base=\"%s\" (0x%08lx) scope=%d\n",
-               e->e_nname.bv_val, (long) e->e_id, op->oq_search.rs_scope );
-
-       xf.f_or = op->oq_search.rs_filter;
-       xf.f_choice = LDAP_FILTER_OR;
-       xf.f_next = NULL;
-
-       /* If the user's filter uses objectClass=*,
-        * these clauses are redundant.
-        */
-       if (!oc_filter(op->oq_search.rs_filter, 1, &depth)
-               && !get_subentries_visibility(op)) {
-               if( !get_manageDSAit(op) && !get_domainScope(op) ) {
-                       /* match referral objects */
-                       struct berval bv_ref = BER_BVC( "referral" );
-                       rf.f_choice = LDAP_FILTER_EQUALITY;
-                       rf.f_ava = &aa_ref;
-                       rf.f_av_desc = slap_schema.si_ad_objectClass;
-                       rf.f_av_value = bv_ref;
-                       rf.f_next = xf.f_or;
-                       xf.f_or = &rf;
-                       depth++;
-               }
-       }
-
-       f.f_next = NULL;
-       f.f_choice = LDAP_FILTER_AND;
-       f.f_and = &nf;
-       /* Dummy; we compute scope separately now */
-       nf.f_choice = SLAPD_FILTER_COMPUTED;
-       nf.f_result = LDAP_SUCCESS;
-       nf.f_next = ( xf.f_or == op->oq_search.rs_filter )
-               ? op->oq_search.rs_filter : &xf ;
-       /* Filter depth increased again, adding dummy clause */
-       depth++;
-
-       if( get_subentries_visibility( op ) ) {
-               struct berval bv_subentry = BER_BVC( "subentry" );
-               sf.f_choice = LDAP_FILTER_EQUALITY;
-               sf.f_ava = &aa_subentry;
-               sf.f_av_desc = slap_schema.si_ad_objectClass;
-               sf.f_av_value = bv_subentry;
-               sf.f_next = nf.f_next;
-               nf.f_next = &sf;
-       }
-
-       /* Allocate IDL stack, plus 1 more for former tmp */
-       if ( depth+1 > bdb->bi_search_stack_depth ) {
-               stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
-       } else {
-               stack = search_stack( op );
-       }
-
-       if( op->ors_deref & LDAP_DEREF_SEARCHING ) {
-               rc = search_aliases( op, rs, e, txn, ids, scopes, stack );
-               if ( BDB_IDL_IS_ZERO( ids ) && rc == LDAP_SUCCESS )
-                       rc = bdb_dn2idl( op, txn, &e->e_nname, BEI(e), ids, stack );
-       } else {
-               rc = bdb_dn2idl( op, txn, &e->e_nname, BEI(e), ids, stack );
-       }
-
-       if ( rc == LDAP_SUCCESS ) {
-               rc = bdb_filter_candidates( op, txn, &f, ids,
-                       stack, stack+BDB_IDL_UM_SIZE );
-       }
-
-       if ( depth+1 > bdb->bi_search_stack_depth ) {
-               ch_free( stack );
-       }
-
-       if( rc ) {
-               Debug(LDAP_DEBUG_TRACE,
-                       "bdb_search_candidates: failed (rc=%d)\n",
-                       rc );
-
-       } else {
-               Debug(LDAP_DEBUG_TRACE,
-                       "bdb_search_candidates: id=%ld first=%ld last=%ld\n",
-                       (long) ids[0],
-                       (long) BDB_IDL_FIRST(ids),
-                       (long) BDB_IDL_LAST(ids) );
-       }
-
-       return rc;
-}
-
-static int
-parse_paged_cookie( Operation *op, SlapReply *rs )
-{
-       int             rc = LDAP_SUCCESS;
-       PagedResultsState *ps = op->o_pagedresults_state;
-
-       /* this function must be invoked only if the pagedResults
-        * control has been detected, parsed and partially checked
-        * by the frontend */
-       assert( get_pagedresults( op ) > SLAP_CONTROL_IGNORED );
-
-       /* cookie decoding/checks deferred to backend... */
-       if ( ps->ps_cookieval.bv_len ) {
-               PagedResultsCookie reqcookie;
-               if( ps->ps_cookieval.bv_len != sizeof( reqcookie ) ) {
-                       /* bad cookie */
-                       rs->sr_text = "paged results cookie is invalid";
-                       rc = LDAP_PROTOCOL_ERROR;
-                       goto done;
-               }
-
-               AC_MEMCPY( &reqcookie, ps->ps_cookieval.bv_val, sizeof( reqcookie ));
-
-               if ( reqcookie > ps->ps_cookie ) {
-                       /* bad cookie */
-                       rs->sr_text = "paged results cookie is invalid";
-                       rc = LDAP_PROTOCOL_ERROR;
-                       goto done;
-
-               } else if ( reqcookie < ps->ps_cookie ) {
-                       rs->sr_text = "paged results cookie is invalid or old";
-                       rc = LDAP_UNWILLING_TO_PERFORM;
-                       goto done;
-               }
-
-       } else {
-               /* we're going to use ps_cookie */
-               op->o_conn->c_pagedresults_state.ps_cookie = 0;
-       }
-
-done:;
-
-       return rc;
-}
-
-static void
-send_paged_response( 
-       Operation       *op,
-       SlapReply       *rs,
-       ID              *lastid,
-       int             tentries )
-{
-       LDAPControl     *ctrls[2];
-       BerElementBuffer berbuf;
-       BerElement      *ber = (BerElement *)&berbuf;
-       PagedResultsCookie respcookie;
-       struct berval cookie;
-
-       Debug(LDAP_DEBUG_ARGS,
-               "send_paged_response: lastid=0x%08lx nentries=%d\n", 
-               lastid ? *lastid : 0, rs->sr_nentries );
-
-       ctrls[1] = NULL;
-
-       ber_init2( ber, NULL, LBER_USE_DER );
-
-       if ( lastid ) {
-               respcookie = ( PagedResultsCookie )(*lastid);
-               cookie.bv_len = sizeof( respcookie );
-               cookie.bv_val = (char *)&respcookie;
-
-       } else {
-               respcookie = ( PagedResultsCookie )0;
-               BER_BVSTR( &cookie, "" );
-       }
-
-       op->o_conn->c_pagedresults_state.ps_cookie = respcookie;
-       op->o_conn->c_pagedresults_state.ps_count =
-               ((PagedResultsState *)op->o_pagedresults_state)->ps_count +
-               rs->sr_nentries;
-
-       /* return size of 0 -- no estimate */
-       ber_printf( ber, "{iO}", 0, &cookie ); 
-
-       ctrls[0] = op->o_tmpalloc( sizeof(LDAPControl), op->o_tmpmemctx );
-       if ( ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 ) == -1 ) {
-               goto done;
-       }
-
-       ctrls[0]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
-       ctrls[0]->ldctl_iscritical = 0;
-
-       slap_add_ctrls( op, rs, ctrls );
-       rs->sr_err = LDAP_SUCCESS;
-       send_ldap_result( op, rs );
-
-done:
-       (void) ber_free_buf( ber );
-}
diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c
deleted file mode 100644 (file)
index 8729b1a..0000000
+++ /dev/null
@@ -1,1510 +0,0 @@
-/* tools.c - tools for slap tools */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-#include <ac/errno.h>
-
-#define AVL_INTERNAL
-#include "back-bdb.h"
-#include "idl.h"
-
-static DBC *cursor = NULL;
-static DBT key, data;
-static EntryHeader eh;
-static ID nid, previd = NOID;
-static char ehbuf[16];
-
-typedef struct dn_id {
-       ID id;
-       struct berval dn;
-} dn_id;
-
-#define        HOLE_SIZE       4096
-static dn_id hbuf[HOLE_SIZE], *holes = hbuf;
-static unsigned nhmax = HOLE_SIZE;
-static unsigned nholes;
-
-static int index_nattrs;
-
-static struct berval   *tool_base;
-static int             tool_scope;
-static Filter          *tool_filter;
-static Entry           *tool_next_entry;
-
-#ifdef BDB_TOOL_IDL_CACHING
-#define bdb_tool_idl_cmp               BDB_SYMBOL(tool_idl_cmp)
-#define bdb_tool_idl_flush_one         BDB_SYMBOL(tool_idl_flush_one)
-#define bdb_tool_idl_flush             BDB_SYMBOL(tool_idl_flush)
-
-static int bdb_tool_idl_flush( BackendDB *be );
-
-#define        IDBLOCK 1024
-
-typedef struct bdb_tool_idl_cache_entry {
-       struct bdb_tool_idl_cache_entry *next;
-       ID ids[IDBLOCK];
-} bdb_tool_idl_cache_entry;
-typedef struct bdb_tool_idl_cache {
-       struct berval kstr;
-       bdb_tool_idl_cache_entry *head, *tail;
-       ID first, last;
-       int count;
-} bdb_tool_idl_cache;
-
-static bdb_tool_idl_cache_entry *bdb_tool_idl_free_list;
-#endif /* BDB_TOOL_IDL_CACHING */
-
-static ID bdb_tool_ix_id;
-static Operation *bdb_tool_ix_op;
-static int *bdb_tool_index_threads, bdb_tool_index_tcount;
-static void *bdb_tool_index_rec;
-static struct bdb_info *bdb_tool_info;
-static ldap_pvt_thread_mutex_t bdb_tool_index_mutex;
-static ldap_pvt_thread_cond_t bdb_tool_index_cond_main;
-static ldap_pvt_thread_cond_t bdb_tool_index_cond_work;
-
-#if DB_VERSION_FULL >= 0x04060000
-#define        USE_TRICKLE     1
-#else
-/* Seems to slow things down too much in BDB 4.5 */
-#undef USE_TRICKLE
-#endif
-
-#ifdef USE_TRICKLE
-static ldap_pvt_thread_mutex_t bdb_tool_trickle_mutex;
-static ldap_pvt_thread_cond_t bdb_tool_trickle_cond;
-static ldap_pvt_thread_cond_t bdb_tool_trickle_cond_end;
-
-static void * bdb_tool_trickle_task( void *ctx, void *ptr );
-static int bdb_tool_trickle_active;
-#endif
-
-static void * bdb_tool_index_task( void *ctx, void *ptr );
-
-static int
-bdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep );
-
-static int bdb_tool_threads;
-
-int bdb_tool_entry_open(
-       BackendDB *be, int mode )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-
-       /* initialize key and data thangs */
-       DBTzero( &key );
-       DBTzero( &data );
-       key.flags = DB_DBT_USERMEM;
-       key.data = &nid;
-       key.size = key.ulen = sizeof( nid );
-       data.flags = DB_DBT_USERMEM;
-
-       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 ) {
-                       return -1;
-               }
-       }
-
-       /* Set up for threaded slapindex */
-       if (( slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY)) == SLAP_TOOL_QUICK ) {
-               if ( !bdb_tool_info ) {
-#ifdef USE_TRICKLE
-                       ldap_pvt_thread_mutex_init( &bdb_tool_trickle_mutex );
-                       ldap_pvt_thread_cond_init( &bdb_tool_trickle_cond );
-                       ldap_pvt_thread_cond_init( &bdb_tool_trickle_cond_end );
-                       ldap_pvt_thread_pool_submit( &connection_pool, bdb_tool_trickle_task, bdb->bi_dbenv );
-#endif
-
-                       ldap_pvt_thread_mutex_init( &bdb_tool_index_mutex );
-                       ldap_pvt_thread_cond_init( &bdb_tool_index_cond_main );
-                       ldap_pvt_thread_cond_init( &bdb_tool_index_cond_work );
-                       if ( bdb->bi_nattrs ) {
-                               int i;
-                               bdb_tool_threads = slap_tool_thread_max - 1;
-                               if ( bdb_tool_threads > 1 ) {
-                                       bdb_tool_index_threads = ch_malloc( bdb_tool_threads * sizeof( int ));
-                                       bdb_tool_index_rec = ch_malloc( bdb->bi_nattrs * sizeof( IndexRec ));
-                                       bdb_tool_index_tcount = bdb_tool_threads - 1;
-                                       for (i=1; i<bdb_tool_threads; i++) {
-                                               int *ptr = ch_malloc( sizeof( int ));
-                                               *ptr = i;
-                                               ldap_pvt_thread_pool_submit( &connection_pool,
-                                                       bdb_tool_index_task, ptr );
-                                       }
-                               }
-                       }
-                       bdb_tool_info = bdb;
-               }
-       }
-
-       return 0;
-}
-
-int bdb_tool_entry_close(
-       BackendDB *be )
-{
-       if ( bdb_tool_info ) {
-               slapd_shutdown = 1;
-#ifdef USE_TRICKLE
-               ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex );
-
-               /* trickle thread may not have started yet */
-               while ( !bdb_tool_trickle_active )
-                       ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond_end,
-                                       &bdb_tool_trickle_mutex );
-
-               ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond );
-               while ( bdb_tool_trickle_active )
-                       ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond_end,
-                                       &bdb_tool_trickle_mutex );
-               ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex );
-#endif
-               if ( bdb_tool_threads > 1 ) {
-                       ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
-
-                       /* There might still be some threads starting */
-                       while ( bdb_tool_index_tcount > 0 ) {
-                               ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main,
-                                               &bdb_tool_index_mutex );
-                       }
-
-                       bdb_tool_index_tcount = bdb_tool_threads - 1;
-                       ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work );
-
-                       /* Make sure all threads are stopped */
-                       while ( bdb_tool_index_tcount > 0 ) {
-                               ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main,
-                                       &bdb_tool_index_mutex );
-                       }
-                       ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
-
-                       ch_free( bdb_tool_index_threads );
-                       ch_free( bdb_tool_index_rec );
-                       bdb_tool_index_tcount = bdb_tool_threads - 1;
-               }
-               bdb_tool_info = NULL;
-               slapd_shutdown = 0;
-       }
-
-       if( eh.bv.bv_val ) {
-               ch_free( eh.bv.bv_val );
-               eh.bv.bv_val = NULL;
-       }
-
-       if( cursor ) {
-               cursor->c_close( cursor );
-               cursor = NULL;
-       }
-
-#ifdef BDB_TOOL_IDL_CACHING
-       bdb_tool_idl_flush( be );
-#endif
-
-       if( nholes ) {
-               unsigned i;
-               fprintf( stderr, "Error, entries missing!\n");
-               for (i=0; i<nholes; i++) {
-                       fprintf(stderr, "  entry %ld: %s\n",
-                               holes[i].id, holes[i].dn.bv_val);
-               }
-               return -1;
-       }
-                       
-       return 0;
-}
-
-ID
-bdb_tool_entry_first_x(
-       BackendDB *be,
-       struct berval *base,
-       int scope,
-       Filter *f )
-{
-       tool_base = base;
-       tool_scope = scope;
-       tool_filter = f;
-       
-       return bdb_tool_entry_next( be );
-}
-
-ID bdb_tool_entry_next(
-       BackendDB *be )
-{
-       int rc;
-       ID id;
-       struct bdb_info *bdb;
-
-       assert( be != NULL );
-       assert( slapMode & SLAP_TOOL_MODE );
-
-       bdb = (struct bdb_info *) be->be_private;
-       assert( bdb != NULL );
-
-next:;
-       /* Get the header */
-       data.ulen = data.dlen = sizeof( ehbuf );
-       data.data = ehbuf;
-       data.flags |= DB_DBT_PARTIAL;
-       rc = cursor->c_get( cursor, &key, &data, DB_NEXT );
-
-       if( rc ) {
-               /* If we're doing linear indexing and there are more attrs to
-                * index, and we're at the end of the database, start over.
-                */
-               if ( index_nattrs && rc == DB_NOTFOUND ) {
-                       /* optional - do a checkpoint here? */
-                       bdb_attr_info_free( bdb->bi_attrs[0] );
-                       bdb->bi_attrs[0] = bdb->bi_attrs[index_nattrs];
-                       index_nattrs--;
-                       rc = cursor->c_get( cursor, &key, &data, DB_FIRST );
-                       if ( rc ) {
-                               return NOID;
-                       }
-               } else {
-                       return NOID;
-               }
-       }
-
-       BDB_DISK2ID( key.data, &id );
-       previd = id;
-
-       if ( tool_filter || tool_base ) {
-               static Operation op = {0};
-               static Opheader ohdr = {0};
-
-               op.o_hdr = &ohdr;
-               op.o_bd = be;
-               op.o_tmpmemctx = NULL;
-               op.o_tmpmfuncs = &ch_mfuncs;
-
-               if ( tool_next_entry ) {
-                       bdb_entry_release( &op, tool_next_entry, 0 );
-                       tool_next_entry = NULL;
-               }
-
-               rc = bdb_tool_entry_get_int( be, id, &tool_next_entry );
-               if ( rc == LDAP_NO_SUCH_OBJECT ) {
-                       goto next;
-               }
-
-               assert( tool_next_entry != NULL );
-
-#ifdef BDB_HIER
-               /* TODO: needed until BDB_HIER is handled accordingly
-                * in bdb_tool_entry_get_int() */
-               if ( tool_base && !dnIsSuffixScope( &tool_next_entry->e_nname, tool_base, tool_scope ) )
-               {
-                       bdb_entry_release( &op, tool_next_entry, 0 );
-                       tool_next_entry = NULL;
-                       goto next;
-               }
-#endif
-
-               if ( tool_filter && test_filter( NULL, tool_next_entry, tool_filter ) != LDAP_COMPARE_TRUE )
-               {
-                       bdb_entry_release( &op, tool_next_entry, 0 );
-                       tool_next_entry = NULL;
-                       goto next;
-               }
-       }
-
-       return id;
-}
-
-ID bdb_tool_dn2id_get(
-       Backend *be,
-       struct berval *dn
-)
-{
-       Operation op = {0};
-       Opheader ohdr = {0};
-       EntryInfo *ei = NULL;
-       int rc;
-
-       if ( BER_BVISEMPTY(dn) )
-               return 0;
-
-       op.o_hdr = &ohdr;
-       op.o_bd = be;
-       op.o_tmpmemctx = NULL;
-       op.o_tmpmfuncs = &ch_mfuncs;
-
-       rc = bdb_cache_find_ndn( &op, 0, dn, &ei );
-       if ( ei ) bdb_cache_entryinfo_unlock( ei );
-       if ( rc == DB_NOTFOUND )
-               return NOID;
-       
-       return ei->bei_id;
-}
-
-static int
-bdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep )
-{
-       Entry *e = NULL;
-       char *dptr;
-       int rc, eoff;
-
-       assert( be != NULL );
-       assert( slapMode & SLAP_TOOL_MODE );
-
-       if ( ( tool_filter || tool_base ) && id == previd && tool_next_entry != NULL ) {
-               *ep = tool_next_entry;
-               tool_next_entry = NULL;
-               return LDAP_SUCCESS;
-       }
-
-       if ( id != previd ) {
-               data.ulen = data.dlen = sizeof( ehbuf );
-               data.data = ehbuf;
-               data.flags |= DB_DBT_PARTIAL;
-
-               BDB_ID2DISK( id, &nid );
-               rc = cursor->c_get( cursor, &key, &data, DB_SET );
-               if ( rc ) {
-                       rc = LDAP_OTHER;
-                       goto done;
-               }
-       }
-
-       /* Get the header */
-       dptr = eh.bv.bv_val;
-       eh.bv.bv_val = ehbuf;
-       eh.bv.bv_len = data.size;
-       rc = entry_header( &eh );
-       eoff = eh.data - eh.bv.bv_val;
-       eh.bv.bv_val = dptr;
-       if ( rc ) {
-               rc = LDAP_OTHER;
-               goto done;
-       }
-
-       /* Get the size */
-       data.flags &= ~DB_DBT_PARTIAL;
-       data.ulen = 0;
-       rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
-       if ( rc != DB_BUFFER_SMALL ) {
-               rc = LDAP_OTHER;
-               goto done;
-       }
-
-       /* Allocate a block and retrieve the data */
-       eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size;
-       eh.bv.bv_val = ch_realloc( eh.bv.bv_val, eh.bv.bv_len );
-       eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval );
-       data.data = eh.data;
-       data.ulen = data.size;
-
-       /* Skip past already parsed nattr/nvals */
-       eh.data += eoff;
-
-       rc = cursor->c_get( cursor, &key, &data, DB_CURRENT );
-       if ( rc ) {
-               rc = LDAP_OTHER;
-               goto done;
-       }
-
-#ifndef BDB_HIER
-       /* TODO: handle BDB_HIER accordingly */
-       if ( tool_base != NULL ) {
-               struct berval ndn;
-               entry_decode_dn( &eh, NULL, &ndn );
-
-               if ( !dnIsSuffixScope( &ndn, tool_base, tool_scope ) ) {
-                       return LDAP_NO_SUCH_OBJECT;
-               }
-       }
-#endif
-
-#ifdef SLAP_ZONE_ALLOC
-       /* FIXME: will add ctx later */
-       rc = entry_decode( &eh, &e, NULL );
-#else
-       rc = entry_decode( &eh, &e );
-#endif
-
-       if( rc == LDAP_SUCCESS ) {
-               e->e_id = id;
-#ifdef BDB_HIER
-               if ( slapMode & SLAP_TOOL_READONLY ) {
-                       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-                       EntryInfo *ei = NULL;
-                       Operation op = {0};
-                       Opheader ohdr = {0};
-
-                       op.o_hdr = &ohdr;
-                       op.o_bd = be;
-                       op.o_tmpmemctx = NULL;
-                       op.o_tmpmfuncs = &ch_mfuncs;
-
-                       rc = bdb_cache_find_parent( &op, bdb->bi_cache.c_txn, id, &ei );
-                       if ( rc == LDAP_SUCCESS ) {
-                               bdb_cache_entryinfo_unlock( ei );
-                               e->e_private = ei;
-                               ei->bei_e = e;
-                               bdb_fix_dn( e, 0 );
-                               ei->bei_e = NULL;
-                               e->e_private = NULL;
-                       }
-               }
-#endif
-       }
-done:
-       if ( e != NULL ) {
-               *ep = e;
-       }
-
-       return rc;
-}
-
-Entry*
-bdb_tool_entry_get( BackendDB *be, ID id )
-{
-       Entry *e = NULL;
-
-       (void)bdb_tool_entry_get_int( be, id, &e );
-       return e;
-}
-
-static int bdb_tool_next_id(
-       Operation *op,
-       DB_TXN *tid,
-       Entry *e,
-       struct berval *text,
-       int hole )
-{
-       struct berval dn = e->e_name;
-       struct berval ndn = e->e_nname;
-       struct berval pdn, npdn;
-       EntryInfo *ei = NULL, eidummy;
-       int rc;
-
-       if (ndn.bv_len == 0) {
-               e->e_id = 0;
-               return 0;
-       }
-
-       rc = bdb_cache_find_ndn( op, tid, &ndn, &ei );
-       if ( ei ) bdb_cache_entryinfo_unlock( ei );
-       if ( rc == DB_NOTFOUND ) {
-               if ( !be_issuffix( op->o_bd, &ndn ) ) {
-                       ID eid = e->e_id;
-                       dnParent( &dn, &pdn );
-                       dnParent( &ndn, &npdn );
-                       e->e_name = pdn;
-                       e->e_nname = npdn;
-                       rc = bdb_tool_next_id( op, tid, e, text, 1 );
-                       e->e_name = dn;
-                       e->e_nname = ndn;
-                       if ( rc ) {
-                               return rc;
-                       }
-                       /* If parent didn't exist, it was created just now
-                        * and its ID is now in e->e_id. Make sure the current
-                        * entry gets added under the new parent ID.
-                        */
-                       if ( eid != e->e_id ) {
-                               eidummy.bei_id = e->e_id;
-                               ei = &eidummy;
-                       }
-               }
-               rc = bdb_next_id( op->o_bd, &e->e_id );
-               if ( rc ) {
-                       snprintf( text->bv_val, text->bv_len,
-                               "next_id failed: %s (%d)",
-                               db_strerror(rc), rc );
-               Debug( LDAP_DEBUG_ANY,
-                       "=> bdb_tool_next_id: %s\n", text->bv_val );
-                       return rc;
-               }
-               rc = bdb_dn2id_add( op, tid, ei, e );
-               if ( rc ) {
-                       snprintf( text->bv_val, text->bv_len, 
-                               "dn2id_add failed: %s (%d)",
-                               db_strerror(rc), rc );
-               Debug( LDAP_DEBUG_ANY,
-                       "=> bdb_tool_next_id: %s\n", text->bv_val );
-               } else if ( hole ) {
-                       if ( nholes == nhmax - 1 ) {
-                               if ( holes == hbuf ) {
-                                       holes = ch_malloc( nhmax * sizeof(dn_id) * 2 );
-                                       AC_MEMCPY( holes, hbuf, sizeof(hbuf) );
-                               } else {
-                                       holes = ch_realloc( holes, nhmax * sizeof(dn_id) * 2 );
-                               }
-                               nhmax *= 2;
-                       }
-                       ber_dupbv( &holes[nholes].dn, &ndn );
-                       holes[nholes++].id = e->e_id;
-               }
-       } else if ( !hole ) {
-               unsigned i, j;
-
-               e->e_id = ei->bei_id;
-
-               for ( i=0; i<nholes; i++) {
-                       if ( holes[i].id == e->e_id ) {
-                               free(holes[i].dn.bv_val);
-                               for (j=i;j<nholes;j++) holes[j] = holes[j+1];
-                               holes[j].id = 0;
-                               nholes--;
-                               break;
-                       } else if ( holes[i].id > e->e_id ) {
-                               break;
-                       }
-               }
-       }
-       return rc;
-}
-
-static int
-bdb_tool_index_add(
-       Operation *op,
-       DB_TXN *txn,
-       Entry *e )
-{
-       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
-
-       if ( !bdb->bi_nattrs )
-               return 0;
-
-       if ( bdb_tool_threads > 1 ) {
-               IndexRec *ir;
-               int i, rc;
-               Attribute *a;
-               
-               ir = bdb_tool_index_rec;
-               memset(ir, 0, bdb->bi_nattrs * sizeof( IndexRec ));
-
-               for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-                       rc = bdb_index_recset( bdb, a, a->a_desc->ad_type, 
-                               &a->a_desc->ad_tags, ir );
-                       if ( rc )
-                               return rc;
-               }
-               bdb_tool_ix_id = e->e_id;
-               bdb_tool_ix_op = op;
-               ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
-               /* Wait for all threads to be ready */
-               while ( bdb_tool_index_tcount > 0 ) {
-                       ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, 
-                               &bdb_tool_index_mutex );
-               }
-               for ( i=1; i<bdb_tool_threads; i++ )
-                       bdb_tool_index_threads[i] = LDAP_BUSY;
-               bdb_tool_index_tcount = bdb_tool_threads - 1;
-               ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work );
-               ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
-               rc = bdb_index_recrun( op, bdb, ir, e->e_id, 0 );
-               if ( rc )
-                       return rc;
-               ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
-               for ( i=1; i<bdb_tool_threads; i++ ) {
-                       if ( bdb_tool_index_threads[i] == LDAP_BUSY ) {
-                               ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, 
-                                       &bdb_tool_index_mutex );
-                               i--;
-                               continue;
-                       }
-                       if ( bdb_tool_index_threads[i] ) {
-                               rc = bdb_tool_index_threads[i];
-                               break;
-                       }
-               }
-               ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
-               return rc;
-       } else {
-               return bdb_index_entry_add( op, txn, e );
-       }
-}
-
-ID bdb_tool_entry_put(
-       BackendDB *be,
-       Entry *e,
-       struct berval *text )
-{
-       int rc;
-       struct bdb_info *bdb;
-       DB_TXN *tid = NULL;
-       Operation op = {0};
-       Opheader ohdr = {0};
-
-       assert( be != NULL );
-       assert( slapMode & SLAP_TOOL_MODE );
-
-       assert( text != NULL );
-       assert( text->bv_val != NULL );
-       assert( text->bv_val[0] == '\0' );      /* overconservative? */
-
-       Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(bdb_tool_entry_put)
-               "( %ld, \"%s\" )\n", (long) e->e_id, e->e_dn );
-
-       bdb = (struct bdb_info *) be->be_private;
-
-       if (! (slapMode & SLAP_TOOL_QUICK)) {
-       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_put) ": %s\n",
-                        text->bv_val );
-               return NOID;
-       }
-       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_tool_entry_put) ": txn id: %x\n",
-               tid->id(tid) );
-       }
-
-       op.o_hdr = &ohdr;
-       op.o_bd = be;
-       op.o_tmpmemctx = NULL;
-       op.o_tmpmfuncs = &ch_mfuncs;
-
-       /* add dn2id indices */
-       rc = bdb_tool_next_id( &op, tid, e, text, 0 );
-       if( rc != 0 ) {
-               goto done;
-       }
-
-#ifdef USE_TRICKLE
-       if (( slapMode & SLAP_TOOL_QUICK ) && (( e->e_id & 0xfff ) == 0xfff )) {
-               ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond );
-       }
-#endif
-
-       if ( !bdb->bi_linear_index )
-               rc = bdb_tool_index_add( &op, tid, e );
-       if( rc != 0 ) {
-               snprintf( text->bv_val, text->bv_len,
-                               "index_entry_add failed: %s (%d)",
-                               rc == LDAP_OTHER ? "Internal error" :
-                               db_strerror(rc), rc );
-               Debug( LDAP_DEBUG_ANY,
-                       "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
-                       text->bv_val );
-               goto done;
-       }
-
-       /* id2entry index */
-       rc = bdb_id2entry_add( be, tid, e );
-       if( rc != 0 ) {
-               snprintf( text->bv_val, text->bv_len,
-                               "id2entry_add failed: %s (%d)",
-                               db_strerror(rc), rc );
-               Debug( LDAP_DEBUG_ANY,
-                       "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
-                       text->bv_val );
-               goto done;
-       }
-
-done:
-       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_put) ": %s\n",
-                               text->bv_val );
-                       e->e_id = NOID;
-               }
-               }
-
-       } else {
-               if ( !( slapMode & SLAP_TOOL_QUICK )) {
-               TXN_ABORT( tid );
-               snprintf( text->bv_val, text->bv_len,
-                       "txn_aborted! %s (%d)",
-                       rc == LDAP_OTHER ? "Internal error" :
-                       db_strerror(rc), rc );
-               Debug( LDAP_DEBUG_ANY,
-                       "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
-                       text->bv_val );
-               }
-               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_reindex(
-       BackendDB *be,
-       ID id,
-       AttributeDescription **adv )
-{
-       struct bdb_info *bi = (struct bdb_info *) be->be_private;
-       int rc;
-       Entry *e;
-       DB_TXN *tid = NULL;
-       Operation op = {0};
-       Opheader ohdr = {0};
-
-       Debug( LDAP_DEBUG_ARGS,
-               "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld )\n",
-               (long) id );
-       assert( tool_base == NULL );
-       assert( tool_filter == NULL );
-
-       /* No indexes configured, nothing to do. Could return an
-        * error here to shortcut things.
-        */
-       if (!bi->bi_attrs) {
-               return 0;
-       }
-
-       /* Check for explicit list of attrs to index */
-       if ( adv ) {
-               int i, j, n;
-
-               if ( bi->bi_attrs[0]->ai_desc != adv[0] ) {
-                       /* count */
-                       for ( n = 0; adv[n]; n++ ) ;
-
-                       /* insertion sort */
-                       for ( i = 0; i < n; i++ ) {
-                               AttributeDescription *ad = adv[i];
-                               for ( j = i-1; j>=0; j--) {
-                                       if ( SLAP_PTRCMP( adv[j], ad ) <= 0 ) break;
-                                       adv[j+1] = adv[j];
-                               }
-                               adv[j+1] = ad;
-                       }
-               }
-
-               for ( i = 0; adv[i]; i++ ) {
-                       if ( bi->bi_attrs[i]->ai_desc != adv[i] ) {
-                               for ( j = i+1; j < bi->bi_nattrs; j++ ) {
-                                       if ( bi->bi_attrs[j]->ai_desc == adv[i] ) {
-                                               AttrInfo *ai = bi->bi_attrs[i];
-                                               bi->bi_attrs[i] = bi->bi_attrs[j];
-                                               bi->bi_attrs[j] = ai;
-                                               break;
-                                       }
-                               }
-                               if ( j == bi->bi_nattrs ) {
-                                       Debug( LDAP_DEBUG_ANY,
-                                               LDAP_XSTRING(bdb_tool_entry_reindex)
-                                               ": no index configured for %s\n",
-                                               adv[i]->ad_cname.bv_val );
-                                       return -1;
-                               }
-                       }
-               }
-               bi->bi_nattrs = i;
-       }
-
-       /* Get the first attribute to index */
-       if (bi->bi_linear_index && !index_nattrs) {
-               index_nattrs = bi->bi_nattrs - 1;
-               bi->bi_nattrs = 1;
-       }
-
-       e = bdb_tool_entry_get( be, id );
-
-       if( e == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                       LDAP_XSTRING(bdb_tool_entry_reindex)
-                       ": could not locate id=%ld\n",
-                       (long) id );
-               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 ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "=> " LDAP_XSTRING(bdb_tool_entry_reindex) ": "
-                       "txn_begin failed: %s (%d)\n",
-                       db_strerror(rc), rc );
-               goto done;
-       }
-       Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_tool_entry_reindex) ": txn id: %x\n",
-               tid->id(tid) );
-       }
-       
-       /*
-        * just (re)add them for now
-        * assume that some other routine (not yet implemented)
-        * will zap index databases
-        *
-        */
-
-       Debug( LDAP_DEBUG_TRACE,
-               "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld, \"%s\" )\n",
-               (long) id, e->e_dn );
-
-       rc = bdb_tool_index_add( &op, tid, e );
-
-done:
-       if( rc == 0 ) {
-               if (! (slapMode & SLAP_TOOL_QUICK)) {
-               rc = TXN_COMMIT( tid, 0 );
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
-                               ": txn_commit failed: %s (%d)\n",
-                               db_strerror(rc), rc );
-                       e->e_id = NOID;
-               }
-               }
-
-       } else {
-               if (! (slapMode & SLAP_TOOL_QUICK)) {
-               TXN_ABORT( tid );
-               Debug( LDAP_DEBUG_ANY,
-                       "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
-                       ": txn_aborted! %s (%d)\n",
-                       db_strerror(rc), rc );
-               }
-               e->e_id = NOID;
-       }
-       bdb_entry_release( &op, e, 0 );
-
-       return rc;
-}
-
-ID bdb_tool_entry_modify(
-       BackendDB *be,
-       Entry *e,
-       struct berval *text )
-{
-       int rc;
-       struct bdb_info *bdb;
-       DB_TXN *tid = NULL;
-       Operation op = {0};
-       Opheader ohdr = {0};
-
-       assert( be != NULL );
-       assert( slapMode & SLAP_TOOL_MODE );
-
-       assert( text != NULL );
-       assert( text->bv_val != NULL );
-       assert( text->bv_val[0] == '\0' );      /* overconservative? */
-
-       assert ( e->e_id != NOID );
-
-       Debug( LDAP_DEBUG_TRACE,
-               "=> " LDAP_XSTRING(bdb_tool_entry_modify) "( %ld, \"%s\" )\n",
-               (long) e->e_id, e->e_dn );
-
-       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_modify) ": %s\n",
-                                text->bv_val );
-                       return NOID;
-               }
-               Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_tool_entry_modify) ": txn id: %x\n",
-                       tid->id(tid) );
-       }
-
-       op.o_hdr = &ohdr;
-       op.o_bd = be;
-       op.o_tmpmemctx = NULL;
-       op.o_tmpmfuncs = &ch_mfuncs;
-
-       /* id2entry index */
-       rc = bdb_id2entry_update( be, tid, e );
-       if( rc != 0 ) {
-               snprintf( text->bv_val, text->bv_len,
-                               "id2entry_add failed: %s (%d)",
-                               db_strerror(rc), rc );
-               Debug( LDAP_DEBUG_ANY,
-                       "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
-                       text->bv_val );
-               goto done;
-       }
-
-done:
-       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_modify) ": "
-                               "%s\n", text->bv_val );
-                       e->e_id = NOID;
-               }
-               }
-
-       } 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_modify) ": %s\n",
-                       text->bv_val );
-               }
-               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 );
-
-       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 );
-                       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 );
-               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 );
-               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 );
-               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 );
-               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 );
-               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 );
-               }
-               }
-
-       } 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 );
-               }
-       }
-
-       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 )
-{
-       const bdb_tool_idl_cache *c1 = v1, *c2 = v2;
-       int rc;
-
-       if (( rc = c1->kstr.bv_len - c2->kstr.bv_len )) return rc;
-       return memcmp( c1->kstr.bv_val, c2->kstr.bv_val, c1->kstr.bv_len );
-}
-
-static int
-bdb_tool_idl_flush_one( void *v1, void *arg )
-{
-       bdb_tool_idl_cache *ic = v1;
-       DB *db = arg;
-       struct bdb_info *bdb = bdb_tool_info;
-       bdb_tool_idl_cache_entry *ice;
-       DBC *curs;
-       DBT key, data;
-       int i, rc;
-       ID id, nid;
-
-       /* Freshly allocated, ignore it */
-       if ( !ic->head && ic->count <= BDB_IDL_DB_SIZE ) {
-               return 0;
-       }
-
-       rc = db->cursor( db, NULL, &curs, 0 );
-       if ( rc )
-               return -1;
-
-       DBTzero( &key );
-       DBTzero( &data );
-
-       bv2DBT( &ic->kstr, &key );
-
-       data.size = data.ulen = sizeof( ID );
-       data.flags = DB_DBT_USERMEM;
-       data.data = &nid;
-
-       rc = curs->c_get( curs, &key, &data, DB_SET );
-       /* If key already exists and we're writing a range... */
-       if ( rc == 0 && ic->count > BDB_IDL_DB_SIZE ) {
-               /* If it's not currently a range, must delete old info */
-               if ( nid ) {
-                       /* Skip lo */
-                       while ( curs->c_get( curs, &key, &data, DB_NEXT_DUP ) == 0 )
-                               curs->c_del( curs, 0 );
-
-                       nid = 0;
-                       /* Store range marker */
-                       curs->c_put( curs, &key, &data, DB_KEYFIRST );
-               } else {
-                       
-                       /* Skip lo */
-                       rc = curs->c_get( curs, &key, &data, DB_NEXT_DUP );
-
-                       /* Get hi */
-                       rc = curs->c_get( curs, &key, &data, DB_NEXT_DUP );
-
-                       /* Delete hi */
-                       curs->c_del( curs, 0 );
-               }
-               BDB_ID2DISK( ic->last, &nid );
-               curs->c_put( curs, &key, &data, DB_KEYLAST );
-               rc = 0;
-       } else if ( rc && rc != DB_NOTFOUND ) {
-               rc = -1;
-       } else if ( ic->count > BDB_IDL_DB_SIZE ) {
-               /* range, didn't exist before */
-               nid = 0;
-               rc = curs->c_put( curs, &key, &data, DB_KEYLAST );
-               if ( rc == 0 ) {
-                       BDB_ID2DISK( ic->first, &nid );
-                       rc = curs->c_put( curs, &key, &data, DB_KEYLAST );
-                       if ( rc == 0 ) {
-                               BDB_ID2DISK( ic->last, &nid );
-                               rc = curs->c_put( curs, &key, &data, DB_KEYLAST );
-                       }
-               }
-               if ( rc ) {
-                       rc = -1;
-               }
-       } else {
-               int n;
-
-               /* Just a normal write */
-               rc = 0;
-               for ( ice = ic->head, n=0; ice; ice = ice->next, n++ ) {
-                       int end;
-                       if ( ice->next ) {
-                               end = IDBLOCK;
-                       } else {
-                               end = ic->count & (IDBLOCK-1);
-                               if ( !end )
-                                       end = IDBLOCK;
-                       }
-                       for ( i=0; i<end; i++ ) {
-                               if ( !ice->ids[i] ) continue;
-                               BDB_ID2DISK( ice->ids[i], &nid );
-                               rc = curs->c_put( curs, &key, &data, DB_NODUPDATA );
-                               if ( rc ) {
-                                       if ( rc == DB_KEYEXIST ) {
-                                               rc = 0;
-                                               continue;
-                                       }
-                                       rc = -1;
-                                       break;
-                               }
-                       }
-                       if ( rc ) {
-                               rc = -1;
-                               break;
-                       }
-               }
-               if ( ic->head ) {
-                       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-                       ic->tail->next = bdb_tool_idl_free_list;
-                       bdb_tool_idl_free_list = ic->head;
-                       bdb->bi_idl_cache_size -= n;
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
-               }
-       }
-       if ( ic != db->app_private ) {
-               ch_free( ic );
-       } else {
-               ic->head = ic->tail = NULL;
-       }
-       curs->c_close( curs );
-       return rc;
-}
-
-static int
-bdb_tool_idl_flush_db( DB *db, bdb_tool_idl_cache *ic )
-{
-       Avlnode *root = db->app_private;
-       int rc;
-
-       db->app_private = ic;
-       rc = avl_apply( root, bdb_tool_idl_flush_one, db, -1, AVL_INORDER );
-       avl_free( root, NULL );
-       db->app_private = NULL;
-       if ( rc != -1 )
-               rc = 0;
-       return rc;
-}
-
-static int
-bdb_tool_idl_flush( BackendDB *be )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       DB *db;
-       Avlnode *root;
-       int i, rc = 0;
-
-       for ( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) {
-               db = bdb->bi_databases[i]->bdi_db;
-               if ( !db->app_private ) continue;
-               rc = bdb_tool_idl_flush_db( db, NULL );
-               if ( rc )
-                       break;
-       }
-       if ( !rc ) {
-               bdb->bi_idl_cache_size = 0;
-       }
-       return rc;
-}
-
-int bdb_tool_idl_add(
-       BackendDB *be,
-       DB *db,
-       DB_TXN *txn,
-       DBT *key,
-       ID id )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       bdb_tool_idl_cache *ic, itmp;
-       bdb_tool_idl_cache_entry *ice;
-       int rc;
-
-       if ( !bdb->bi_idl_cache_max_size )
-               return bdb_idl_insert_key( be, db, txn, key, id );
-
-       DBT2bv( key, &itmp.kstr );
-
-       ic = avl_find( (Avlnode *)db->app_private, &itmp, bdb_tool_idl_cmp );
-
-       /* No entry yet, create one */
-       if ( !ic ) {
-               DBC *curs;
-               DBT data;
-               ID nid;
-               int rc;
-
-               ic = ch_malloc( sizeof( bdb_tool_idl_cache ) + itmp.kstr.bv_len );
-               ic->kstr.bv_len = itmp.kstr.bv_len;
-               ic->kstr.bv_val = (char *)(ic+1);
-               AC_MEMCPY( ic->kstr.bv_val, itmp.kstr.bv_val, ic->kstr.bv_len );
-               ic->head = ic->tail = NULL;
-               ic->last = 0;
-               ic->count = 0;
-               avl_insert( (Avlnode **)&db->app_private, ic, bdb_tool_idl_cmp,
-                       avl_dup_error );
-
-               /* load existing key count here */
-               rc = db->cursor( db, NULL, &curs, 0 );
-               if ( rc ) return rc;
-
-               data.ulen = sizeof( ID );
-               data.flags = DB_DBT_USERMEM;
-               data.data = &nid;
-               rc = curs->c_get( curs, key, &data, DB_SET );
-               if ( rc == 0 ) {
-                       if ( nid == 0 ) {
-                               ic->count = BDB_IDL_DB_SIZE+1;
-                       } else {
-                               db_recno_t count;
-
-                               curs->c_count( curs, &count, 0 );
-                               ic->count = count;
-                               BDB_DISK2ID( &nid, &ic->first );
-                       }
-               }
-               curs->c_close( curs );
-       }
-       /* are we a range already? */
-       if ( ic->count > BDB_IDL_DB_SIZE ) {
-               ic->last = id;
-               return 0;
-       /* Are we at the limit, and converting to a range? */
-       } else if ( ic->count == BDB_IDL_DB_SIZE ) {
-               int n;
-               for ( ice = ic->head, n=0; ice; ice = ice->next, n++ )
-                       /* counting */ ;
-               if ( n ) {
-                       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-                       ic->tail->next = bdb_tool_idl_free_list;
-                       bdb_tool_idl_free_list = ic->head;
-                       bdb->bi_idl_cache_size -= n;
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
-               }
-               ic->head = ic->tail = NULL;
-               ic->last = id;
-               ic->count++;
-               return 0;
-       }
-       /* No free block, create that too */
-       if ( !ic->tail || ( ic->count & (IDBLOCK-1)) == 0) {
-               ice = NULL;
-               ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-               if ( bdb->bi_idl_cache_size >= bdb->bi_idl_cache_max_size ) {
-                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
-                       rc = bdb_tool_idl_flush_db( db, ic );
-                       if ( rc )
-                               return rc;
-                       avl_insert( (Avlnode **)&db->app_private, ic, bdb_tool_idl_cmp,
-                               avl_dup_error );
-                       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
-               }
-               bdb->bi_idl_cache_size++;
-               if ( bdb_tool_idl_free_list ) {
-                       ice = bdb_tool_idl_free_list;
-                       bdb_tool_idl_free_list = ice->next;
-               }
-               ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
-               if ( !ice ) {
-                       ice = ch_malloc( sizeof( bdb_tool_idl_cache_entry ));
-               }
-               memset( ice, 0, sizeof( *ice ));
-               if ( !ic->head ) {
-                       ic->head = ice;
-               } else {
-                       ic->tail->next = ice;
-               }
-               ic->tail = ice;
-               if ( !ic->count )
-                       ic->first = id;
-       }
-       ice = ic->tail;
-       ice->ids[ ic->count & (IDBLOCK-1) ] = id;
-       ic->count++;
-
-       return 0;
-}
-#endif
-
-#ifdef USE_TRICKLE
-static void *
-bdb_tool_trickle_task( void *ctx, void *ptr )
-{
-       DB_ENV *env = ptr;
-       int wrote;
-
-       ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex );
-       bdb_tool_trickle_active = 1;
-       ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond_end );
-       while ( 1 ) {
-               ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond,
-                       &bdb_tool_trickle_mutex );
-               if ( slapd_shutdown )
-                       break;
-               env->memp_trickle( env, 30, &wrote );
-       }
-       bdb_tool_trickle_active = 0;
-       ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond_end );
-       ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex );
-
-       return NULL;
-}
-#endif
-
-static void *
-bdb_tool_index_task( void *ctx, void *ptr )
-{
-       int base = *(int *)ptr;
-
-       free( ptr );
-       while ( 1 ) {
-               ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
-               bdb_tool_index_tcount--;
-               if ( !bdb_tool_index_tcount )
-                       ldap_pvt_thread_cond_signal( &bdb_tool_index_cond_main );
-               ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_work,
-                       &bdb_tool_index_mutex );
-               if ( slapd_shutdown ) {
-                       bdb_tool_index_tcount--;
-                       if ( !bdb_tool_index_tcount )
-                               ldap_pvt_thread_cond_signal( &bdb_tool_index_cond_main );
-                       ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
-                       break;
-               }
-               ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
-
-               bdb_tool_index_threads[base] = bdb_index_recrun( bdb_tool_ix_op,
-                       bdb_tool_info, bdb_tool_index_rec, bdb_tool_ix_id, base );
-       }
-
-       return NULL;
-}
diff --git a/servers/slapd/back-bdb/trans.c b/servers/slapd/back-bdb/trans.c
deleted file mode 100644 (file)
index 4dc608f..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* trans.c - bdb backend transaction routines */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-#include <ac/string.h>
-
-#include "back-bdb.h"
-#include "lber_pvt.h"
-#include "lutil.h"
-
-
-/* Congestion avoidance code
- * for Deadlock Rollback
- */
-
-void
-bdb_trans_backoff( int num_retries )
-{
-       int i;
-       int delay = 0;
-       int pow_retries = 1;
-       unsigned long key = 0;
-       unsigned long max_key = -1;
-       struct timeval timeout;
-
-       lutil_entropy( (unsigned char *) &key, sizeof( unsigned long ));
-
-       for ( i = 0; i < num_retries; i++ ) {
-               if ( i >= 5 ) break;
-               pow_retries *= 4;
-       }
-
-       delay = 16384 * (key * (double) pow_retries / (double) max_key);
-       delay = delay ? delay : 1;
-
-       Debug( LDAP_DEBUG_TRACE,  "delay = %d, num_retries = %d\n", delay, num_retries );
-
-       timeout.tv_sec = delay / 1000000;
-       timeout.tv_usec = delay % 1000000;
-       select( 0, NULL, NULL, NULL, &timeout );
-}
diff --git a/servers/slapd/back-hdb/Makefile.in b/servers/slapd/back-hdb/Makefile.in
deleted file mode 100644 (file)
index e645799..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-# Makefile for back-hdb
-# $OpenLDAP$
-## This work is part of OpenLDAP Software <http://www.openldap.org/>.
-##
-## Copyright 1998-2019 The OpenLDAP Foundation.
-## All rights reserved.
-##
-## Redistribution and use in source and binary forms, with or without
-## modification, are permitted only as authorized by the OpenLDAP
-## Public License.
-##
-## A copy of this license is available in the file LICENSE in the
-## top-level directory of the distribution or, alternatively, at
-## <http://www.OpenLDAP.org/license.html>.
-#
-## Copyright 2003 Howard Chu @ Symas Corp. See master COPYRIGHT file for terms.
-
-XXDIR = $(srcdir)/../back-bdb
-
-XXSRCS = init.c tools.c config.c \
-       add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
-       extended.c referral.c operational.c \
-       attr.c index.c key.c dbcache.c filterindex.c trans.c \
-       dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c \
-       monitor.c
-SRCS = $(XXSRCS)
-OBJS = init.lo tools.lo config.lo \
-       add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
-       extended.lo referral.lo operational.lo \
-       attr.lo index.lo key.lo dbcache.lo filterindex.lo trans.lo \
-       dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo \
-       monitor.lo
-
-LDAP_INCDIR= ../../../include       
-LDAP_LIBDIR= ../../../libraries
-
-BUILD_OPT = "--enable-hdb"
-BUILD_MOD = @BUILD_HDB@
-
-mod_DEFS = -DSLAPD_IMPORT
-MOD_DEFS = $(@BUILD_HDB@_DEFS)
-MOD_LIBS = $(BDB_LIBS)
-
-shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA)
-NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS)
-UNIX_LINK_LIBS = $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS)
-
-.links : Makefile
-       @for i in $(XXSRCS); do \
-               $(RM) $$i; \
-               $(LN_S) $(XXDIR)/$$i . ; \
-       done
-       touch .links
-
-$(XXSRCS) : .links
-
-LIBBASE = back_hdb
-
-XINCPATH = -I.. -I$(srcdir)/.. -I$(srcdir) -I$(XXDIR)
-XDEFS = $(MODULES_CPPFLAGS)
-
-depend-local-lib: .links
-
-all-local-lib: ../.backend
-
-../.backend: lib$(LIBBASE).a
-       @touch $@
-
-veryclean-local: FORCE
-       $(RM) $(XXSRCS) .links
diff --git a/servers/slapd/back-hdb/back-bdb.h b/servers/slapd/back-hdb/back-bdb.h
deleted file mode 100644 (file)
index e25bf75..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* back-bdb.h - hdb back-end header file */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2000-2019 The OpenLDAP Foundation.
- * Portions Copyright 2003 Howard Chu @ Symas Corp.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was originally developed by Howard Chu for inclusion
- * in OpenLDAP Software.
- */
-
-#ifndef _BACK_HDB_H_
-#define _BACK_HDB_H_
-
-#ifndef BDB_HIER
-#define        BDB_HIER        1
-#endif
-
-#include "../back-bdb/back-bdb.h"
-
-#endif /* _BACK_HDB_H_ */
index bfd9df18de4b716e91af4094e914efe8d825206a..d5a748dc1edf080fa428bacc69dc696db03d7b1b 100644 (file)
@@ -113,7 +113,7 @@ static int write_data( int fd, const char *spew, int len, int *save_errno );
 #endif /* !_WIN32 */
 
 /*
- * Left and Right "{num}" prefix to ordered RDNs ("olcDatabase={1}bdb").
+ * Left and Right "{num}" prefix to ordered RDNs ("olcDatabase={1}mdb").
  * IX_DN* are for LDAP RDNs, IX_FS* for their .ldif filenames.
  */
 #define IX_DNL '{'
index 56f8a4d9532f9a6c356e870875fb9b6651c6da4c..886f8ec9aeba6c1f1da70ad3cb52a9220569d997 100644 (file)
@@ -1962,8 +1962,8 @@ monitor_back_initialize(
                { "olmGenericAttributes",               "olmSubSystemAttributes:0" },
                { "olmDatabaseAttributes",              "olmSubSystemAttributes:1" },
 
-               /* for example, back-bdb specific attrs
-                * are in "olmDatabaseAttributes:1"
+               /* for example, back-mdb specific attrs
+                * are in "olmDatabaseAttributes:12"
                 *
                 * NOTE: developers, please record here OID assignments
                 * for other modules */
@@ -1973,8 +1973,8 @@ monitor_back_initialize(
                { "olmGenericObjectClasses",            "olmSubSystemObjectClasses:0" },
                { "olmDatabaseObjectClasses",           "olmSubSystemObjectClasses:1" },
 
-               /* for example, back-bdb specific objectClasses
-                * are in "olmDatabaseObjectClasses:1"
+               /* for example, back-mdb specific objectClasses
+                * are in "olmDatabaseObjectClasses:12"
                 *
                 * NOTE: developers, please record here OID assignments
                 * for other modules */
index 805e5acbcee14bf85b6dab6f100398c4865940e4..62767931b91f17d8088152fd40c2868d864db172 100644 (file)
@@ -247,7 +247,7 @@ static OidRec OidMacros[] = {
  * Backend/Database registry
  *
  * OLcfg{Bk|Db}{Oc|At}:0               -> common
- * OLcfg{Bk|Db}{Oc|At}:1               -> back-bdb(/back-hdb)
+ * OLcfg{Bk|Db}{Oc|At}:1               -> back-bdb(/back-hdb) (removed)
  * OLcfg{Bk|Db}{Oc|At}:2               -> back-ldif
  * OLcfg{Bk|Db}{Oc|At}:3               -> back-ldap/meta
  * OLcfg{Bk|Db}{Oc|At}:4               -> back-monitor
index d9a65597885afca297f2361a9a4aeecc53ed2ae7..3e9bdeed7fed5e26a79edb3b1ce9a34ae0747de2 100644 (file)
@@ -1130,8 +1130,7 @@ rdn_validate( struct berval *rdn )
 
 /* build_new_dn:
  *
- * Used by back-bdb back_modrdn to create the new dn of entries being
- * renamed.
+ * Used to create the new dn of entries being renamed.
  *
  * new_dn = parent (p_dn) + separator + rdn (newrdn) + null.
  */
index 8eef463d32f2d7f4c3fa1d2d1784ac630c84248e..9779b7745fb31e5f0350a0ba8eb1ed77b11b950a 100644 (file)
@@ -5613,7 +5613,7 @@ cleanup:;
        cm->monitor_cb = (void *)cb;
 
        /* we don't need to keep track of the attributes, because
-        * bdb_monitor_free() takes care of everything */
+        * mdb_monitor_free() takes care of everything */
        if ( a != NULL ) {
                attrs_free( a );
        }
@@ -5697,7 +5697,7 @@ pcache_initialize()
        }
 #endif /* PCACHE_EXOP_QUERY_DELETE */
 
-       argv[ 0 ] = "back-bdb/back-hdb monitor";
+       argv[ 0 ] = "back-mdb monitor";
        c.argv = argv;
        c.argc = 3;
        c.fname = argv[0];
index 0b542bf8d83fee3d27814fe07a4faea3175889ca..8f7e71536aefbefe03b928c77338aee125b5b927 100644 (file)
@@ -1818,7 +1818,6 @@ struct BackendDB {
 
 /*
  * define to honor hasSubordinates operational attribute in search filters
- * (in previous use there was a flaw with back-bdb; now it is fixed).
  */
 #define                be_has_subordinates bd_info->bi_has_subordinates
 
index 18549d8206c93ba2b34d2608bb6aa5cce332add2..c320f43deb1940f7521a3a18a087241109d021c7 100644 (file)
@@ -30,8 +30,7 @@ olcPidFile: %LOCALSTATEDIR%/run/slapd.pid
 #objectClass: olcModuleList
 #cn: module
 #olcModulepath:        %MODULEDIR%
-#olcModuleload:        back_bdb.la
-#olcModuleload:        back_hdb.la
+#olcModuleload:        back_mdb.la
 #olcModuleload:        back_ldap.la
 #olcModuleload:        back_passwd.la
 #olcModuleload:        back_shell.la
index 5cdbd28ebe247a058b270928d6da2d344591f964..f0dd9736c3b81f6c458bb32d7b205806a8131b3a 100644 (file)
 RUN=./run
 SUBDIRS= progs
 
-BUILD_BDB=@BUILD_BDB@
-BUILD_HDB=@BUILD_HDB@
 BUILD_MDB=@BUILD_MDB@
 BUILD_SQL=@BUILD_SQL@
 
 # test primary backends (default)
 test tests:
-       @$(MAKE) bdb
-       @$(MAKE) hdb
        @$(MAKE) mdb
 
 # test all backends
@@ -32,22 +28,6 @@ alltests: tests
        @$(MAKE) sql
        @$(MAKE) ldif
 
-bdb test-bdb:  bdb-$(BUILD_BDB)
-bdb-no:
-       @echo "run configure with --enable-bdb to run BDB tests"
-
-bdb-yes bdb-mod: FORCE
-       @echo "Initiating LDAP tests for BDB..."
-       @$(RUN) -b bdb all
-
-hdb test-hdb:  hdb-$(BUILD_HDB)
-hdb-no:
-       @echo "run configure with --enable-hdb to run HDB tests"
-
-hdb-yes hdb-mod: FORCE
-       @echo "Initiating LDAP tests for HDB..."
-       @$(RUN) -b hdb all
-
 mdb test-mdb:  mdb-$(BUILD_MDB)
 mdb-no:
        @echo "run configure with --enable-mdb to run MDB tests"
@@ -70,26 +50,10 @@ ldif test-ldif: FORCE
 
 regressions:   FORCE
        @echo "Testing (available) ITS regressions"
-       @$(MAKE) bdb-its
-       @$(MAKE) hdb-its
        @$(MAKE) mdb-its
 
 its: regressions
 
-bdb-its: bdb-its-$(BUILD_BDB)
-bdb-its-no:
-       @echo "run configure with --enable-bdb to run BDB ITS regressions"
-
-bdb-its-yes bdb-its-mod: FORCE
-       @$(RUN) -b bdb its-all
-
-hdb-its: hdb-its-$(BUILD_HDB)
-hdb-its-no:
-       @echo "run configure with --enable-hdb to run HDB ITS regressions"
-
-hdb-its-yes hdb-its-mod: FORCE
-       @$(RUN) -b hdb its-all
-
 mdb-its: mdb-its-$(BUILD_MDB)
 mdb-its-no:
        @echo "run configure with --enable-mdb to run MDB ITS regressions"
index 1a25df80ae8d6185fa5cb2f534d42d26c3269e70..a3b5d2f304cabd405f655c55013cbd7468369986 100644 (file)
@@ -2,8 +2,6 @@ This directory contains a series of test scripts which are used to
 verify basic functionality of the LDAP libraries and slapd.
 
        To run all of the tests, type "make test".
-       To run BDB tests, type "make bdb".
-       To run HDB tests, type "make hdb".
        To run MDB tests, type "make mdb".
        To run SQL tests, define SLAPD_USE_SQL=<rdbms> and type
                "make sql"; define SLAPD_USE_SQLWRITE=yes
index 2d0e401f18cfe5eb4fccf6432b1157be3df795e4..c6acd788c7ab8d8c24e91e5b2bd8535168f4043c 100755 (executable)
 echo "running defines.sh"
 . $SRCDIR/scripts/defines.sh
 
-if test "$BACKEND" != "bdb" && test "$BACKEND" != "hdb" ; then
-       echo "Warning: this test is known to affect bdb and hdb, although it may impact other backends as well."
-fi
-
 mkdir -p $DBDIR1A $DBDIR2A
 
 ITS=4184
index f6eec0b7f6440e0c36dd7914f0211495bb825dcb..3bfb9ce7e447d110751acdc8b1539bd7d3b6177f 100755 (executable)
@@ -47,22 +47,6 @@ ITS=4448
 ITSDIR=$DATADIR/regressions/its$ITS
 ITSCONF=$ITSDIR/slapd-meta.conf
 
-# NOTE: this could be added to all tests...
-if test "$BACKEND" = "bdb" || test "$BACKEND" = "hdb" ; then
-       if test "x$DB_CONFIG" != "x" ; then \
-               if test -f $DB_CONFIG ; then
-                       echo "==> using DB_CONFIG \"$DB_CONFIG\""
-                       cp $DB_CONFIG $DBDIR1
-                       cp $DB_CONFIG $DBDIR2
-               else
-                       echo "==> DB_CONFIG must point to a valid file (ignored)"
-               fi
-       else
-               echo "==> set \"DB_CONFIG\" to the DB_CONFIG file you want to use for the test."
-       fi
-       echo ""
-fi
-
 echo "Starting slapd on TCP/IP port $PORT1..."
 . $CONFFILTER $BACKEND $MONITORDB < $CONF > $CONF1
 $SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 &
index e01c6edb1eca20d8259b606b7bd2568662398d70..40c26ee5c4ae1d87ec5983e543fc965fa5c75521 100644 (file)
@@ -64,10 +64,6 @@ pcachetemplate       (cn=) 0 86400 86400 86400 180
 
 pcachebind             (cn=) 0 3600 sub ou=people,dc=example,dc=com
 
-#bdb#cachesize 20
-#hdb#cachesize 20
-#bdb#dbnosync
-#hdb#dbnosync
 #mdb#dbnosync
 
 #~null~#directory      @TESTDIR@/db.2.a
index 724449d3821ec8d476012a621d9d521e52cada7a..4a45d41d8fee4a8854140374c6d6dfd35be04bf0 100644 (file)
@@ -54,10 +54,6 @@ pcachetemplate       (mail=) 0 @TTL@ @NTTL@ @STTL@
 pcachetemplate         (&(objectclass=)(uid=)) 1 @TTL@ @NTTL@ @STTL@ @TTR@
 pcachebind             (&(objectclass=person)(uid=)) 1 @BTTR@ sub "ou=Alumni Association,ou=people,dc=example,dc=com"
 
-#bdb#cachesize 20
-#hdb#cachesize 20
-#bdb#dbnosync
-#hdb#dbnosync
 #mdb#dbnosync
 
 #~null~#directory      @TESTDIR@/db.2.a
index aa75dfc1090a2e459d0ab7021e0e46784179666a..9e2ffe3f346dce29392e42ab8af06d30c665d538 100644 (file)
@@ -34,8 +34,6 @@ argsfile      @TESTDIR@/slapd.2.args
 referral       "@URI1@"
 
 database       @BACKEND@
-#bdb#cachesize 0
-#hdb#cachesize 0
 
 suffix         "o=University of Mich,c=US"
 rootdn         "cn=Manager,o=University of Mich,c=US"
index bd9fc4591e0a7fa7895898834679f6819878cd78..8b3c883ce047280c18cb5a24322059ab90d71772 100644 (file)
@@ -44,8 +44,6 @@ rootpw                secret
 #~null~#directory      @TESTDIR@/db.1.a
 #indexdb#index         objectClass     eq
 #indexdb#index         cn,sn,uid       pres,eq,sub
-#bdb#checkpoint                1024 5
-#hdb#checkpoint                1024 5
 #mdb#maxsize   33554432
 #ndb#dbname db_1
 #ndb#include @DATADIR@/ndb.conf
index 9d81b1d846ea15818b5b94c55f3bc77a00cf02ad..a90106251c036982bc054dca85758c6907ce36e1 100644 (file)
@@ -24,8 +24,6 @@ EGREP_CMD="@EGREP@"
 export SRCDIR TOPSRCDIR LN_S EGREP_CMD
 
 # backends known to ./run -b <backend> (used to deduce $BACKENDTYPE)
-AC_bdb=@BUILD_BDB@
-AC_hdb=@BUILD_HDB@
 AC_ldif=yes
 AC_mdb=@BUILD_MDB@
 AC_null=@BUILD_NULL@
@@ -74,7 +72,7 @@ fi
 if test "${AC_asyncmeta}" = "metamod" && test "${AC_LIBS_DYNAMIC}" = "static" ; then
        AC_meta="asyncmetano"
 fi
-export AC_bdb AC_hdb AC_ldap AC_mdb AC_meta AC_asyncmeta AC_monitor AC_null AC_relay AC_sql \
+export AC_ldap AC_mdb AC_meta AC_asyncmeta AC_monitor AC_null AC_relay AC_sql \
        AC_accesslog AC_autoca AC_constraint AC_dds AC_dynlist AC_memberof AC_pcache AC_ppolicy \
        AC_refint AC_retcode AC_rwm AC_unique AC_syncprov AC_translucent \
        AC_valsort \
@@ -158,7 +156,7 @@ while test $# -gt 0 ; do
 done
 
 if test -z "$BACKEND" ; then
-       for b in bdb hdb mdb ; do
+       for b in mdb ; do
                if eval "test \"\$AC_$b\" != no" ; then
                        BACKEND=$b
                        break
@@ -179,7 +177,7 @@ fi
 # maindb: main storage backend.  Currently index,limits,mode,paged results.
 INDEXDB=noindexdb MAINDB=nomaindb
 case $BACKEND in
-       bdb|hdb|mdb) INDEXDB=indexdb MAINDB=maindb ;;
+       mdb) INDEXDB=indexdb MAINDB=maindb ;;
        ndb) INDEXDB=indexdb ;;
 esac
 
index cd26aeab6bece5f35e8d9c5f1f347c06a414c79a..0709c18828f05d6ee1ae32ecbc077604d20f561a 100755 (executable)
@@ -189,9 +189,8 @@ if test $RC != 0 ; then
        exit $RC
 fi
 
-if test $BACKEND != "bdb" ; then
-       $LDAPMODIFY -v -D "$REFINTDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
-               $TESTOUT 2>&1 << EDEL
+$LDAPMODIFY -v -D "$REFINTDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
+       $TESTOUT 2>&1 << EDEL
 version: 1
 dn: cn=group,o=refint
 changetype: add
@@ -205,63 +204,62 @@ member: uid=theman,ou=users,o=refint
 member: uid=richard,ou=users,o=refint
 EDEL
 
-       RC=$?
-       if test $RC != 0 ; then
-               echo "ldapmodify failed ($RC)!"
-               test $KILLSERVERS != no && kill -HUP $KILLPIDS
-               exit $RC
-       fi
+RC=$?
+if test $RC != 0 ; then
+       echo "ldapmodify failed ($RC)!"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
+       exit $RC
+fi
 
-       sleep 1;
+sleep 1;
 
-       $LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \
-               manager member secretary > $SEARCHOUT 2>&1
-       RC=$?
-       if test $RC != 0 ; then
-               echo "ldapsearch failed ($RC)!"
-               test $KILLSERVERS != no && kill -HUP $KILLPIDS
-               exit $RC
-       fi
+$LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \
+       manager member secretary > $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+       echo "ldapsearch failed ($RC)!"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
+       exit $RC
+fi
 
-       $EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \
-               | sed "s/ou=users/ou=people/g" | \
-               sort > $TESTOUT 2>&1
+$EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \
+       | sed "s/ou=users/ou=people/g" | \
+       sort > $TESTOUT 2>&1
 
-       echo "testing subtree rename"
-       $LDAPMODRDN -D "$REFINTDN" -r -h $LOCALHOST -p $PORT1 -w $PASSWD > \
-               /dev/null 2>&1 'ou=users,o=refint' 'ou=people'
-       RC=$?
-       if test $RC != 0 ; then
-               echo "ldapmodrdn failed ($RC)!"
-               test $KILLSERVERS != no && kill -HUP $KILLPIDS
-               exit $RC
-       fi
+echo "testing subtree rename"
+$LDAPMODRDN -D "$REFINTDN" -r -h $LOCALHOST -p $PORT1 -w $PASSWD > \
+       /dev/null 2>&1 'ou=users,o=refint' 'ou=people'
+RC=$?
+if test $RC != 0 ; then
+       echo "ldapmodrdn failed ($RC)!"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
+       exit $RC
+fi
 
-       sleep 1;
+sleep 1;
 
-       echo "Using ldapsearch to check dependents new rdn..."
+echo "Using ldapsearch to check dependents new rdn..."
 
-       $LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \
-               manager member secretary > $SEARCHOUT 2>&1
+$LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \
+       manager member secretary > $SEARCHOUT 2>&1
 
-       RC=$?
-       if test $RC != 0 ; then
-               echo "ldapsearch failed ($RC)!"
-               test $KILLSERVERS != no && kill -HUP $KILLPIDS
-               exit $RC
-       fi
+RC=$?
+if test $RC != 0 ; then
+       echo "ldapsearch failed ($RC)!"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
+       exit $RC
+fi
 
-       $EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \
-               | sort > $SEARCHFLT 2>&1
+$EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \
+       | sort > $SEARCHFLT 2>&1
 
-       echo "Comparing ldapsearch results against original..."
-       $CMP $TESTOUT $SEARCHFLT > $CMPOUT
+echo "Comparing ldapsearch results against original..."
+$CMP $TESTOUT $SEARCHFLT > $CMPOUT
 
-       if test $? != 0 ; then
-               echo "comparison failed - subtree rename operations did not complete correctly"
-               test $KILLSERVERS != no && kill -HUP $KILLPIDS
-               exit 1
-       fi
+if test $? != 0 ; then
+       echo "comparison failed - subtree rename operations did not complete correctly"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
+       exit 1
 fi
 
 test $KILLSERVERS != no && kill -HUP $KILLPIDS
index 5223dceccbce6e16212178bfc61e273dc9c7a837..17c49f64024853acd31280c1ab6611a931dc2d18 100755 (executable)
@@ -750,7 +750,7 @@ case $RC in
 esac
 
 if test $MAINDB != maindb ; then
-               # only bdb|hdb|mdb currently supports pagedResults control
+               # only mdb currently supports pagedResults control
                test $KILLSERVERS != no && kill -HUP $KILLPIDS
 
                echo ">>>>> Test succeeded"
index fc0f2b6b7d9a2c8210789183aefb1dc37da2af30..2741a8454bf3091359d749bdcb55ae4727aea8e8 100755 (executable)
@@ -40,22 +40,6 @@ rm -rf $TESTDIR
 
 mkdir -p $TESTDIR $DBDIR1 $DBDIR2
 
-# NOTE: this could be added to all tests...
-if test "$BACKEND" = "bdb" || test "$BACKEND" = "hdb" ; then
-       if test "x$DB_CONFIG" != "x" ; then \
-               if test -f $DB_CONFIG ; then
-                       echo "==> using DB_CONFIG \"$DB_CONFIG\""
-                       cp $DB_CONFIG $DBDIR1
-                       cp $DB_CONFIG $DBDIR2
-               else
-                       echo "==> DB_CONFIG must point to a valid file (ignored)"
-               fi
-       else
-               echo "==> set \"DB_CONFIG\" to the DB_CONFIG file you want to use for the test."
-       fi
-       echo ""
-fi
-
 echo "Starting slapd on TCP/IP port $PORT1..."
 . $CONFFILTER $BACKEND $MONITORDB < $METACONF1 > $CONF1
 $SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 &
index 17798d792a8f199c30b4d6957eefe6dd9fc7057f..a6153e78cb1225b44bd8578355ee6c5cae1698ad 100755 (executable)
 echo "running defines.sh"
 . $SRCDIR/scripts/defines.sh
 
-if test $BACKEND = bdb ; then
-       echo "subtree rename not supported by back-$BACKEND"
-       exit 0
-fi
-
 mkdir -p $TESTDIR $DBDIR1
 
 echo "Starting slapd on TCP/IP port $PORT1..."
index 874b8a1a6adab3d7ed35de383d4cc697a81fe4cb..4a2ce1b1945033f214d5b1e59aa18d8cb985921c 100755 (executable)
@@ -32,7 +32,7 @@ fi
 
 mkdir -p $TESTDIR $DBDIR1A $DBDIR1B $DBDIR2
 
-SPEC="mdb=a,bdb=a,hdb=a"
+SPEC="mdb=a"
 
 #
 # Test replication:
index bb0e1270410318ad918b06bd22772675c0c1c88c..575097c0f6d5239e145a06144b925ff083953adf 100755 (executable)
@@ -72,11 +72,10 @@ EOF
        fi
 fi
 
-indexInclude="" mainInclude="" bdbInclude="# " nullExclude=""
+indexInclude="" mainInclude="" " nullExclude=""
 test $INDEXDB = indexdb        || indexInclude="# "
 test $MAINDB  = maindb || mainInclude="# "
 case $BACKEND in
-bdb | hdb) bdbInclude="" ;;
 null) nullExclude="# " ;;
 esac
 
@@ -114,7 +113,6 @@ olcRootDN: cn=Manager,$BASEDN
 olcRootPW:: c2VjcmV0
 olcMonitoring: TRUE
 ${nullExclude}olcDbDirectory: $TESTDIR/db.1.a/
-${bdbInclude}olcDbCacheSize: 1000
 ${indexInclude}olcDbIndex: objectClass eq
 ${indexInclude}olcDbIndex: cn pres,eq,sub
 ${indexInclude}olcDbIndex: uid pres,eq,sub
index cd3fda6bc871009dcd7e2f5bccc3420da1b59431..4d2e2266bdbf0c026bd03bc16eb0efbd9c314f2a 100755 (executable)
@@ -479,29 +479,6 @@ if test $RC != 0 ; then
        exit $RC
 fi
 
-case $BACKEND in bdb | hdb)
-db_stat=
-for path in `echo "$PATH" | sed -e 's/:/ /g'`; do
-       if test -f "$path/db_stat" && \
-               "$path/db_stat" -E -h $PRODDIR/db > /dev/null 2>&1
-       then
-               db_stat="$path/db_stat"
-               break
-       fi
-done
-
-if test -z "$db_stat" ; then
-       echo "Could not find a working db_stat in PATH!"
-       lock_bug=1
-elif "$db_stat" -E -h $PRODDIR/db | egrep -q 'HELD .* len:'; then
-       echo "WARNING: Glue lock bug hit, next modify could deadlock"
-       lock_bug=2
-else
-       echo "Glue lock bug not found :-)"
-       lock_bug=0
-fi
-esac
-
 echo "Using ldapmodify to modify glue suffix on provider..."
 $LDAPADD -D "$MANAGERDN" -H $URI1 -w $PASSWD <<EOF >> $TESTOUT 2>&1
 dn: dc=example,dc=com
index 38ad8441b4a8baf14f7d1a8a210c003466f0e6ad..b4cf60da70dd02ae176b49bd157ad673932a4006 100755 (executable)
@@ -85,8 +85,7 @@ echo "Using ldapsearch to read database monitor entries..."
 $LDAPSEARCH -S "" -b "$DATABASESMONITORDN" -h $LOCALHOST -p $PORT1 \
        'objectclass=*' \
        structuralObjectClass entryDN namingContexts readOnly \
-       monitorIsShadow monitorContext \
-       olmBDBEntryCache olmBDBDNCache olmBDBIDLCache \
+       monitorIsShadow monitorContext
        > $SEARCHOUT 2>&1
 RC=$?
 
@@ -101,11 +100,8 @@ $LDIFFILTER -b monitor < $SEARCHOUT > $SEARCHFLT
 
 TMPMONITOROUT2=$MONITOROUT2
 case $BACKEND in
-bdb|hdb)
-       ;;
 *)
        TMPMONITOROUT2=$TESTDIR/monitor2.out
-       grep -v "olmBDB" $MONITOROUT2 > $TMPMONITOROUT2
        ;;
 esac
 
index 385c66c1234bda8dca715813aad41490cb6ef676..6d3bca93485a9e64200b0d73d067b14dcde5a0a3 100755 (executable)
@@ -27,11 +27,6 @@ if test $REFINT = refintno; then
        exit 0
 fi 
 
-if test $BACKEND = bdb; then
-       echo "$BACKEND backend does not support subtree rename, test skipped"
-       exit 0
-fi
-
 mkdir -p $TESTDIR $DBDIR1 $TESTDIR/confdir
 
 $SLAPPASSWD -g -n >$CONFIGPWF
@@ -66,11 +61,10 @@ fi
 
 cat /dev/null > $TESTOUT
 
-indexInclude="" mainInclude="" bdbInclude="# " nullExclude=""
+indexInclude="" mainInclude="" nullExclude=""
 test $INDEXDB = indexdb        || indexInclude="# "
 test $MAINDB  = maindb || mainInclude="# "
 case $BACKEND in
-bdb | hdb) bdbInclude="" ;;
 null) nullExclude="# " ;;
 esac
 
@@ -104,7 +98,6 @@ olcRootDN: cn=Manager,$BASEDN
 olcRootPW:: c2VjcmV0
 olcMonitoring: TRUE
 ${nullExclude}olcDbDirectory: $TESTDIR/db.1.a/
-${bdbInclude}olcDbCacheSize: 1000
 ${indexInclude}olcDbIndex: objectClass eq
 ${indexInclude}olcDbIndex: cn pres,eq,sub
 ${indexInclude}olcDbIndex: uid pres,eq,sub
index 60945fb68108c700d5f4acd04b15cdeda7a9163c..e698e633b8a3938e9da11b5befcd49b45460473d 100755 (executable)
@@ -63,7 +63,6 @@ KILLPIDS=
 $SLAPPASSWD -g -n >$CONFIGPWF
 
 case "$BACKEND" in
-       bdb|hdb)        olcDbCheckpoint="olcDbCheckpoint";;
        *)              olcDbCheckpoint="# olcDbCheckpoint";;
 esac
 
index a9274afbf34d291a8da1328c2a9ccd1b8b0b14d2..f7472b22c4b2402ff08523f4f1c9065e43ad3fb5 100755 (executable)
@@ -40,22 +40,6 @@ rm -rf $TESTDIR
 
 mkdir -p $TESTDIR $DBDIR1 $DBDIR2
 
-# NOTE: this could be added to all tests...
-if test "$BACKEND" = "bdb" || test "$BACKEND" = "hdb" ; then
-       if test "x$DB_CONFIG" != "x" ; then \
-               if test -f $DB_CONFIG ; then
-                       echo "==> using DB_CONFIG \"$DB_CONFIG\""
-                       cp $DB_CONFIG $DBDIR1
-                       cp $DB_CONFIG $DBDIR2
-               else
-                       echo "==> DB_CONFIG must point to a valid file (ignored)"
-               fi
-       else
-               echo "==> set \"DB_CONFIG\" to the DB_CONFIG file you want to use for the test."
-       fi
-       echo ""
-fi
-
 echo "Starting slapd on TCP/IP port $PORT1..."
 . $CONFFILTER $BACKEND $MONITORDB < $METACONF1 > $CONF1
 $SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 &