diff --git a/configure b/configure
index 46d44a87c9d696443a272627c1fe3b135c40f71b..c08f2ae4926ba28ac88a9fde53341b3521e3b695 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.560.2.16 2005/11/03 18:02:53 kurt Exp .
+# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.560.2.18 2005/11/26 17:01:54 kurt Exp .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -1551,6 +1551,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
+
 
 
 ac_aux_dir=
@@ -5686,7 +5687,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 5689 "configure"' > conftest.$ac_ext
+  echo '#line 5690 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -7666,11 +7667,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7669: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7670: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7673: \$? = $ac_status" >&5
+   echo "$as_me:7674: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -7928,11 +7929,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7931: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7932: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7935: \$? = $ac_status" >&5
+   echo "$as_me:7936: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -7990,11 +7991,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7993: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7994: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:7997: \$? = $ac_status" >&5
+   echo "$as_me:7998: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -10238,7 +10239,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10241 "configure"
+#line 10242 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10336,7 +10337,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10339 "configure"
+#line 10340 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -27831,14 +27832,385 @@ echo "${ECHO_T}$ol_cv_header_db1" >&6
 
 	if test $ol_cv_header_db1 = yes ; then
 		ol_cv_lib_db=no
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (default)" >&5
-echo $ECHO_N "checking for Berkeley DB link (default)... $ECHO_C" >&6
-if test "${ol_cv_db_none+set}" = set; then
+
+echo "$as_me:$LINENO: checking for Berkeley DB major version" >&5
+echo $ECHO_N "checking for Berkeley DB major version... $ECHO_C" >&6
+if test "${ol_cv_bdb_major+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=
+	ol_cv_bdb_major=0
+	if test $ol_cv_bdb_major = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MAJOR
+#	define DB_VERSION_MAJOR 1
+#endif
+#if DB_VERSION_MAJOR == 4
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_major=4
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_major = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MAJOR
+#	define DB_VERSION_MAJOR 1
+#endif
+#if DB_VERSION_MAJOR == 3
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_major=3
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_major = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MAJOR
+#	define DB_VERSION_MAJOR 1
+#endif
+#if DB_VERSION_MAJOR == 2
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_major=2
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_major = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MAJOR
+#	define DB_VERSION_MAJOR 1
+#endif
+#if DB_VERSION_MAJOR == 1
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_major=1
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+
+	if test $ol_cv_bdb_major = 0 ; then
+		{ { echo "$as_me:$LINENO: error: Unknown Berkeley DB major version" >&5
+echo "$as_me: error: Unknown Berkeley DB major version" >&2;}
+   { (exit 1); exit 1; }; }
+	fi
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_bdb_major" >&5
+echo "${ECHO_T}$ol_cv_bdb_major" >&6
+
+echo "$as_me:$LINENO: checking for Berkeley DB minor version" >&5
+echo $ECHO_N "checking for Berkeley DB minor version... $ECHO_C" >&6
+if test "${ol_cv_bdb_minor+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_cv_bdb_minor=0
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 9
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=9
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 8
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=8
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 7
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=7
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 6
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=6
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 5
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=5
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 4
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=4
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 3
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=3
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 2
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=2
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 1
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=1
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_bdb_minor" >&5
+echo "${ECHO_T}$ol_cv_bdb_minor" >&6
+
+if test $ol_cv_bdb_major = 4 ; then
+	if test $ol_cv_bdb_minor = 4 ; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb44)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb44)... $ECHO_C" >&6
+if test "${ol_cv_db_db44+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_DB_LIB=-ldb44
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -27919,12 +28291,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_none=yes
+  ol_cv_db_db44=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_none=no
+ol_cv_db_db44=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -27932,22 +28304,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_none" >&5
-echo "${ECHO_T}$ol_cv_db_none" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db44" >&5
+echo "${ECHO_T}$ol_cv_db_db44" >&6
 
-	if test $ol_cv_db_none = yes ; then
-		ol_cv_lib_db=yes
+	if test $ol_cv_db_db44 = yes ; then
+		ol_cv_lib_db=-ldb44
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb43)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb43)... $ECHO_C" >&6
-if test "${ol_cv_db_db43+set}" = set; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-44)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-44)... $ECHO_C" >&6
+if test "${ol_cv_db_db_44+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb43
+	ol_DB_LIB=-ldb-44
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28028,12 +28400,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db43=yes
+  ol_cv_db_db_44=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db43=no
+ol_cv_db_db_44=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28041,22 +28413,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db43" >&5
-echo "${ECHO_T}$ol_cv_db_db43" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_44" >&5
+echo "${ECHO_T}$ol_cv_db_db_44" >&6
 
-	if test $ol_cv_db_db43 = yes ; then
-		ol_cv_lib_db=-ldb43
+	if test $ol_cv_db_db_44 = yes ; then
+		ol_cv_lib_db=-ldb-44
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-43)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-43)... $ECHO_C" >&6
-if test "${ol_cv_db_db_43+set}" = set; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.4)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4.4)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_dot_4+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-43
+	ol_DB_LIB=-ldb-4.4
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28137,12 +28509,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_43=yes
+  ol_cv_db_db_4_dot_4=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_43=no
+ol_cv_db_db_4_dot_4=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28150,22 +28522,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_43" >&5
-echo "${ECHO_T}$ol_cv_db_db_43" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_4" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_dot_4" >&6
 
-	if test $ol_cv_db_db_43 = yes ; then
-		ol_cv_lib_db=-ldb-43
+	if test $ol_cv_db_db_4_dot_4 = yes ; then
+		ol_cv_lib_db=-ldb-4.4
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.3)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_3+set}" = set; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-4)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4-4)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_4+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4.3
+	ol_DB_LIB=-ldb-4-4
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28246,12 +28618,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_3=yes
+  ol_cv_db_db_4_4=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_dot_3=no
+ol_cv_db_db_4_4=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28259,22 +28631,23 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_3" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_3" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_4" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_4" >&6
 
-	if test $ol_cv_db_db_4_dot_3 = yes ; then
-		ol_cv_lib_db=-ldb-4.3
+	if test $ol_cv_db_db_4_4 = yes ; then
+		ol_cv_lib_db=-ldb-4-4
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-3)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_3+set}" = set; then
+	elif test $ol_cv_bdb_minor = 3 ; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb43)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb43)... $ECHO_C" >&6
+if test "${ol_cv_db_db43+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4-3
+	ol_DB_LIB=-ldb43
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28355,12 +28728,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_3=yes
+  ol_cv_db_db43=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_3=no
+ol_cv_db_db43=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28368,22 +28741,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_3" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_3" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db43" >&5
+echo "${ECHO_T}$ol_cv_db_db43" >&6
 
-	if test $ol_cv_db_db_4_3 = yes ; then
-		ol_cv_lib_db=-ldb-4-3
+	if test $ol_cv_db_db43 = yes ; then
+		ol_cv_lib_db=-ldb43
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb42)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb42)... $ECHO_C" >&6
-if test "${ol_cv_db_db42+set}" = set; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-43)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-43)... $ECHO_C" >&6
+if test "${ol_cv_db_db_43+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb42
+	ol_DB_LIB=-ldb-43
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28464,12 +28837,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db42=yes
+  ol_cv_db_db_43=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db42=no
+ol_cv_db_db_43=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28477,22 +28850,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db42" >&5
-echo "${ECHO_T}$ol_cv_db_db42" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_43" >&5
+echo "${ECHO_T}$ol_cv_db_db_43" >&6
 
-	if test $ol_cv_db_db42 = yes ; then
-		ol_cv_lib_db=-ldb42
+	if test $ol_cv_db_db_43 = yes ; then
+		ol_cv_lib_db=-ldb-43
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-42)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-42)... $ECHO_C" >&6
-if test "${ol_cv_db_db_42+set}" = set; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.3)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4.3)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_dot_3+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-42
+	ol_DB_LIB=-ldb-4.3
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28573,12 +28946,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_42=yes
+  ol_cv_db_db_4_dot_3=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_42=no
+ol_cv_db_db_4_dot_3=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28586,22 +28959,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_42" >&5
-echo "${ECHO_T}$ol_cv_db_db_42" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_3" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_dot_3" >&6
 
-	if test $ol_cv_db_db_42 = yes ; then
-		ol_cv_lib_db=-ldb-42
+	if test $ol_cv_db_db_4_dot_3 = yes ; then
+		ol_cv_lib_db=-ldb-4.3
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.2)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.2)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_2+set}" = set; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-3)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4-3)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_3+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4.2
+	ol_DB_LIB=-ldb-4-3
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28682,12 +29055,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_2=yes
+  ol_cv_db_db_4_3=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_dot_2=no
+ol_cv_db_db_4_3=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28695,22 +29068,23 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_2" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_2" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_3" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_3" >&6
 
-	if test $ol_cv_db_db_4_dot_2 = yes ; then
-		ol_cv_lib_db=-ldb-4.2
+	if test $ol_cv_db_db_4_3 = yes ; then
+		ol_cv_lib_db=-ldb-4-3
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-2)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-2)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_2+set}" = set; then
+	elif test $ol_cv_bdb_minor = 2 ; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb42)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb42)... $ECHO_C" >&6
+if test "${ol_cv_db_db42+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4-2
+	ol_DB_LIB=-ldb42
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28791,12 +29165,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_2=yes
+  ol_cv_db_db42=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_2=no
+ol_cv_db_db42=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28804,22 +29178,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_2" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_2" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db42" >&5
+echo "${ECHO_T}$ol_cv_db_db42" >&6
 
-	if test $ol_cv_db_db_4_2 = yes ; then
-		ol_cv_lib_db=-ldb-4-2
+	if test $ol_cv_db_db42 = yes ; then
+		ol_cv_lib_db=-ldb42
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4+set}" = set; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-42)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-42)... $ECHO_C" >&6
+if test "${ol_cv_db_db_42+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4
+	ol_DB_LIB=-ldb-42
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -28900,12 +29274,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4=yes
+  ol_cv_db_db_42=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4=no
+ol_cv_db_db_42=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -28913,22 +29287,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4" >&5
-echo "${ECHO_T}$ol_cv_db_db_4" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_42" >&5
+echo "${ECHO_T}$ol_cv_db_db_42" >&6
 
-	if test $ol_cv_db_db_4 = yes ; then
-		ol_cv_lib_db=-ldb-4
+	if test $ol_cv_db_db_42 = yes ; then
+		ol_cv_lib_db=-ldb-42
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb4)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb4)... $ECHO_C" >&6
-if test "${ol_cv_db_db4+set}" = set; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.2)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4.2)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_dot_2+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb4
+	ol_DB_LIB=-ldb-4.2
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -29009,12 +29383,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db4=yes
+  ol_cv_db_db_4_dot_2=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db4=no
+ol_cv_db_db_4_dot_2=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -29022,22 +29396,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db4" >&5
-echo "${ECHO_T}$ol_cv_db_db4" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_2" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_dot_2" >&6
 
-	if test $ol_cv_db_db4 = yes ; then
-		ol_cv_lib_db=-ldb4
+	if test $ol_cv_db_db_4_dot_2 = yes ; then
+		ol_cv_lib_db=-ldb-4.2
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb)... $ECHO_C" >&6
-if test "${ol_cv_db_db+set}" = set; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-2)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4-2)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_2+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb
+	ol_DB_LIB=-ldb-4-2
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -29118,12 +29492,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db=yes
+  ol_cv_db_db_4_2=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db=no
+ol_cv_db_db_4_2=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -29131,15 +29505,16 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db" >&5
-echo "${ECHO_T}$ol_cv_db_db" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_2" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_2" >&6
 
-	if test $ol_cv_db_db = yes ; then
-		ol_cv_lib_db=-ldb
+	if test $ol_cv_db_db_4_2 = yes ; then
+		ol_cv_lib_db=-ldb-4-2
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
+	elif test $ol_cv_bdb_minor = 1 ; then
+		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb41)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb41)... $ECHO_C" >&6
 if test "${ol_cv_db_db41+set}" = set; then
@@ -29248,7 +29623,7 @@ echo "${ECHO_T}$ol_cv_db_db41" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
+		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-41)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb-41)... $ECHO_C" >&6
 if test "${ol_cv_db_db_41+set}" = set; then
@@ -29357,7 +29732,7 @@ echo "${ECHO_T}$ol_cv_db_db_41" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
+		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.1)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb-4.1)... $ECHO_C" >&6
 if test "${ol_cv_db_db_4_dot_1+set}" = set; then
@@ -29466,7 +29841,7 @@ echo "${ECHO_T}$ol_cv_db_db_4_dot_1" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
+		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-1)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb-4-1)... $ECHO_C" >&6
 if test "${ol_cv_db_db_4_1+set}" = set; then
@@ -29575,14 +29950,15 @@ echo "${ECHO_T}$ol_cv_db_db_4_1" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb3)... $ECHO_C" >&6
-if test "${ol_cv_db_db3+set}" = set; then
+	fi
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb3
+	ol_DB_LIB=-ldb-4
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -29663,12 +30039,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db3=yes
+  ol_cv_db_db_4=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db3=no
+ol_cv_db_db_4=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -29676,22 +30052,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db3" >&5
-echo "${ECHO_T}$ol_cv_db_db3" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4" >&5
+echo "${ECHO_T}$ol_cv_db_db_4" >&6
 
-	if test $ol_cv_db_db3 = yes ; then
-		ol_cv_lib_db=-ldb3
+	if test $ol_cv_db_db_4 = yes ; then
+		ol_cv_lib_db=-ldb-4
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-3)... $ECHO_C" >&6
-if test "${ol_cv_db_db_3+set}" = set; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb4)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb4)... $ECHO_C" >&6
+if test "${ol_cv_db_db4+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-3
+	ol_DB_LIB=-ldb4
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -29772,12 +30148,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_3=yes
+  ol_cv_db_db4=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_3=no
+ol_cv_db_db4=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -29785,22 +30161,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_3" >&5
-echo "${ECHO_T}$ol_cv_db_db_3" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db4" >&5
+echo "${ECHO_T}$ol_cv_db_db4" >&6
 
-	if test $ol_cv_db_db_3 = yes ; then
-		ol_cv_lib_db=-ldb-3
+	if test $ol_cv_db_db4 = yes ; then
+		ol_cv_lib_db=-ldb4
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb2)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb2)... $ECHO_C" >&6
-if test "${ol_cv_db_db2+set}" = set; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb)... $ECHO_C" >&6
+if test "${ol_cv_db_db+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb2
+	ol_DB_LIB=-ldb
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -29881,12 +30257,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db2=yes
+  ol_cv_db_db=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db2=no
+ol_cv_db_db=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -29894,22 +30270,24 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db2" >&5
-echo "${ECHO_T}$ol_cv_db_db2" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db" >&5
+echo "${ECHO_T}$ol_cv_db_db" >&6
 
-	if test $ol_cv_db_db2 = yes ; then
-		ol_cv_lib_db=-ldb2
+	if test $ol_cv_db_db = yes ; then
+		ol_cv_lib_db=-ldb
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-2)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-2)... $ECHO_C" >&6
-if test "${ol_cv_db_db_2+set}" = set; then
+
+elif test $ol_cv_bdb_major = 3 ; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb3)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb3)... $ECHO_C" >&6
+if test "${ol_cv_db_db3+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-2
+	ol_DB_LIB=-ldb3
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -29990,12 +30368,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_2=yes
+  ol_cv_db_db3=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_2=no
+ol_cv_db_db3=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -30003,22 +30381,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_2" >&5
-echo "${ECHO_T}$ol_cv_db_db_2" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db3" >&5
+echo "${ECHO_T}$ol_cv_db_db3" >&6
 
-	if test $ol_cv_db_db_2 = yes ; then
-		ol_cv_lib_db=-ldb-2
+	if test $ol_cv_db_db3 = yes ; then
+		ol_cv_lib_db=-ldb3
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb1)... $ECHO_C" >&6
-if test "${ol_cv_db_db1+set}" = set; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-3)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-3)... $ECHO_C" >&6
+if test "${ol_cv_db_db_3+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb1
+	ol_DB_LIB=-ldb-3
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -30099,12 +30477,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db1=yes
+  ol_cv_db_db_3=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db1=no
+ol_cv_db_db_3=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -30112,22 +30490,24 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db1" >&5
-echo "${ECHO_T}$ol_cv_db_db1" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_3" >&5
+echo "${ECHO_T}$ol_cv_db_db_3" >&6
 
-	if test $ol_cv_db_db1 = yes ; then
-		ol_cv_lib_db=-ldb1
+	if test $ol_cv_db_db_3 = yes ; then
+		ol_cv_lib_db=-ldb-3
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-1)... $ECHO_C" >&6
-if test "${ol_cv_db_db_1+set}" = set; then
+
+elif test $ol_cv_bdb_major = 2 ; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb2)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb2)... $ECHO_C" >&6
+if test "${ol_cv_db_db2+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-1
+	ol_DB_LIB=-ldb2
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -30208,12 +30588,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_1=yes
+  ol_cv_db_db2=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_1=no
+ol_cv_db_db2=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -30221,183 +30601,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_1" >&5
-echo "${ECHO_T}$ol_cv_db_db_1" >&6
-
-	if test $ol_cv_db_db_1 = yes ; then
-		ol_cv_lib_db=-ldb-1
-	fi
-fi
-
+echo "$as_me:$LINENO: result: $ol_cv_db_db2" >&5
+echo "${ECHO_T}$ol_cv_db_db2" >&6
 
-		if test "$ol_cv_lib_db" != no ; then
-			ol_cv_berkeley_db=yes
-		fi
+	if test $ol_cv_db_db2 = yes ; then
+		ol_cv_lib_db=-ldb2
 	fi
 fi
 
-	else
-		ol_cv_berkeley_db=no
-
-for ac_header in db.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------------ ##
-## Report this to the AC_PACKAGE_NAME lists.  ##
-## ------------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-if test $ac_cv_header_db_h = yes; then
-	ol_cv_lib_db=no
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (default)" >&5
-echo $ECHO_N "checking for Berkeley DB link (default)... $ECHO_C" >&6
-if test "${ol_cv_db_none+set}" = set; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-2)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-2)... $ECHO_C" >&6
+if test "${ol_cv_db_db_2+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=
+	ol_DB_LIB=-ldb-2
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -30478,12 +30697,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_none=yes
+  ol_cv_db_db_2=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_none=no
+ol_cv_db_db_2=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -30491,22 +30710,1321 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_none" >&5
-echo "${ECHO_T}$ol_cv_db_none" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_2" >&5
+echo "${ECHO_T}$ol_cv_db_db_2" >&6
 
-	if test $ol_cv_db_none = yes ; then
-		ol_cv_lib_db=yes
+	if test $ol_cv_db_db_2 = yes ; then
+		ol_cv_lib_db=-ldb-2
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb43)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb43)... $ECHO_C" >&6
-if test "${ol_cv_db_db43+set}" = set; then
+
+elif test $ol_cv_bdb_major = 1 ; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb1)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb1)... $ECHO_C" >&6
+if test "${ol_cv_db_db1+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb43
+	ol_DB_LIB=-ldb1
+	ol_LIBS=$LIBS
+	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#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
+
+int
+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 )
+		{
+			printf("Berkeley DB version mismatch\n"
+				"\theader: %s\n\tlibrary: %s\n",
+				DB_VERSION_STRING, version);
+			return 1;
+		}
+	}
+#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
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ol_cv_db_db1=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ol_cv_db_db1=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+	LIBS="$ol_LIBS"
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_db_db1" >&5
+echo "${ECHO_T}$ol_cv_db_db1" >&6
+
+	if test $ol_cv_db_db1 = yes ; then
+		ol_cv_lib_db=-ldb1
+	fi
+fi
+
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-1)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-1)... $ECHO_C" >&6
+if test "${ol_cv_db_db_1+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_DB_LIB=-ldb-1
+	ol_LIBS=$LIBS
+	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#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
+
+int
+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 )
+		{
+			printf("Berkeley DB version mismatch\n"
+				"\theader: %s\n\tlibrary: %s\n",
+				DB_VERSION_STRING, version);
+			return 1;
+		}
+	}
+#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
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ol_cv_db_db_1=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ol_cv_db_db_1=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+	LIBS="$ol_LIBS"
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_db_db_1" >&5
+echo "${ECHO_T}$ol_cv_db_db_1" >&6
+
+	if test $ol_cv_db_db_1 = yes ; then
+		ol_cv_lib_db=-ldb-1
+	fi
+fi
+
+fi
+if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (default)" >&5
+echo $ECHO_N "checking for Berkeley DB link (default)... $ECHO_C" >&6
+if test "${ol_cv_db_none+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_DB_LIB=
+	ol_LIBS=$LIBS
+	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#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
+
+int
+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 )
+		{
+			printf("Berkeley DB version mismatch\n"
+				"\theader: %s\n\tlibrary: %s\n",
+				DB_VERSION_STRING, version);
+			return 1;
+		}
+	}
+#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
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ol_cv_db_none=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ol_cv_db_none=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+	LIBS="$ol_LIBS"
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_db_none" >&5
+echo "${ECHO_T}$ol_cv_db_none" >&6
+
+	if test $ol_cv_db_none = yes ; then
+		ol_cv_lib_db=yes
+	fi
+fi
+
+
+		if test "$ol_cv_lib_db" != no ; then
+			ol_cv_berkeley_db=yes
+		fi
+	fi
+fi
+
+	else
+		ol_cv_berkeley_db=no
+
+for ac_header in db.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+if test $ac_cv_header_db_h = yes; then
+	ol_cv_lib_db=no
+
+echo "$as_me:$LINENO: checking for Berkeley DB major version" >&5
+echo $ECHO_N "checking for Berkeley DB major version... $ECHO_C" >&6
+if test "${ol_cv_bdb_major+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_cv_bdb_major=0
+	if test $ol_cv_bdb_major = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MAJOR
+#	define DB_VERSION_MAJOR 1
+#endif
+#if DB_VERSION_MAJOR == 4
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_major=4
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_major = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MAJOR
+#	define DB_VERSION_MAJOR 1
+#endif
+#if DB_VERSION_MAJOR == 3
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_major=3
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_major = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MAJOR
+#	define DB_VERSION_MAJOR 1
+#endif
+#if DB_VERSION_MAJOR == 2
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_major=2
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_major = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MAJOR
+#	define DB_VERSION_MAJOR 1
+#endif
+#if DB_VERSION_MAJOR == 1
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_major=1
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+
+	if test $ol_cv_bdb_major = 0 ; then
+		{ { echo "$as_me:$LINENO: error: Unknown Berkeley DB major version" >&5
+echo "$as_me: error: Unknown Berkeley DB major version" >&2;}
+   { (exit 1); exit 1; }; }
+	fi
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_bdb_major" >&5
+echo "${ECHO_T}$ol_cv_bdb_major" >&6
+
+echo "$as_me:$LINENO: checking for Berkeley DB minor version" >&5
+echo $ECHO_N "checking for Berkeley DB minor version... $ECHO_C" >&6
+if test "${ol_cv_bdb_minor+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_cv_bdb_minor=0
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 9
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=9
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 8
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=8
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 7
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=7
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 6
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=6
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 5
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=5
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 4
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=4
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 3
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=3
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 2
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=2
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+	if test $ol_cv_bdb_minor = 0 ; then
+		cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <db.h>
+#ifndef DB_VERSION_MINOR
+#	define DB_VERSION_MINOR 0
+#endif
+#if DB_VERSION_MINOR == 1
+__db_version
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__db_version" >/dev/null 2>&1; then
+  ol_cv_bdb_minor=1
+else
+  :
+fi
+rm -f conftest*
+
+	fi
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_bdb_minor" >&5
+echo "${ECHO_T}$ol_cv_bdb_minor" >&6
+
+if test $ol_cv_bdb_major = 4 ; then
+	if test $ol_cv_bdb_minor = 4 ; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb44)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb44)... $ECHO_C" >&6
+if test "${ol_cv_db_db44+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_DB_LIB=-ldb44
+	ol_LIBS=$LIBS
+	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#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
+
+int
+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 )
+		{
+			printf("Berkeley DB version mismatch\n"
+				"\theader: %s\n\tlibrary: %s\n",
+				DB_VERSION_STRING, version);
+			return 1;
+		}
+	}
+#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
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ol_cv_db_db44=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ol_cv_db_db44=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+	LIBS="$ol_LIBS"
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_db_db44" >&5
+echo "${ECHO_T}$ol_cv_db_db44" >&6
+
+	if test $ol_cv_db_db44 = yes ; then
+		ol_cv_lib_db=-ldb44
+	fi
+fi
+
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-44)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-44)... $ECHO_C" >&6
+if test "${ol_cv_db_db_44+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_DB_LIB=-ldb-44
+	ol_LIBS=$LIBS
+	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#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
+
+int
+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 )
+		{
+			printf("Berkeley DB version mismatch\n"
+				"\theader: %s\n\tlibrary: %s\n",
+				DB_VERSION_STRING, version);
+			return 1;
+		}
+	}
+#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
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ol_cv_db_db_44=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ol_cv_db_db_44=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+	LIBS="$ol_LIBS"
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_db_db_44" >&5
+echo "${ECHO_T}$ol_cv_db_db_44" >&6
+
+	if test $ol_cv_db_db_44 = yes ; then
+		ol_cv_lib_db=-ldb-44
+	fi
+fi
+
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.4)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4.4)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_dot_4+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_DB_LIB=-ldb-4.4
+	ol_LIBS=$LIBS
+	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#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
+
+int
+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 )
+		{
+			printf("Berkeley DB version mismatch\n"
+				"\theader: %s\n\tlibrary: %s\n",
+				DB_VERSION_STRING, version);
+			return 1;
+		}
+	}
+#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
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ol_cv_db_db_4_dot_4=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ol_cv_db_db_4_dot_4=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+	LIBS="$ol_LIBS"
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_4" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_dot_4" >&6
+
+	if test $ol_cv_db_db_4_dot_4 = yes ; then
+		ol_cv_lib_db=-ldb-4.4
+	fi
+fi
+
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-4)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4-4)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_4+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_DB_LIB=-ldb-4-4
+	ol_LIBS=$LIBS
+	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#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
+
+int
+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 )
+		{
+			printf("Berkeley DB version mismatch\n"
+				"\theader: %s\n\tlibrary: %s\n",
+				DB_VERSION_STRING, version);
+			return 1;
+		}
+	}
+#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
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ol_cv_db_db_4_4=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ol_cv_db_db_4_4=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+	LIBS="$ol_LIBS"
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_4" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_4" >&6
+
+	if test $ol_cv_db_db_4_4 = yes ; then
+		ol_cv_lib_db=-ldb-4-4
+	fi
+fi
+
+	elif test $ol_cv_bdb_minor = 3 ; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb43)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb43)... $ECHO_C" >&6
+if test "${ol_cv_db_db43+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_DB_LIB=-ldb43
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -30608,7 +32126,7 @@ echo "${ECHO_T}$ol_cv_db_db43" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
+		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-43)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb-43)... $ECHO_C" >&6
 if test "${ol_cv_db_db_43+set}" = set; then
@@ -30717,7 +32235,7 @@ echo "${ECHO_T}$ol_cv_db_db_43" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
+		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.3)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb-4.3)... $ECHO_C" >&6
 if test "${ol_cv_db_db_4_dot_3+set}" = set; then
@@ -30826,7 +32344,7 @@ echo "${ECHO_T}$ol_cv_db_db_4_dot_3" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
+		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-3)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb-4-3)... $ECHO_C" >&6
 if test "${ol_cv_db_db_4_3+set}" = set; then
@@ -30935,7 +32453,8 @@ echo "${ECHO_T}$ol_cv_db_db_4_3" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
+	elif test $ol_cv_bdb_minor = 2 ; then
+		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb42)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb42)... $ECHO_C" >&6
 if test "${ol_cv_db_db42+set}" = set; then
@@ -31044,7 +32563,7 @@ echo "${ECHO_T}$ol_cv_db_db42" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
+		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-42)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb-42)... $ECHO_C" >&6
 if test "${ol_cv_db_db_42+set}" = set; then
@@ -31153,7 +32672,7 @@ echo "${ECHO_T}$ol_cv_db_db_42" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
+		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.2)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb-4.2)... $ECHO_C" >&6
 if test "${ol_cv_db_db_4_dot_2+set}" = set; then
@@ -31262,7 +32781,7 @@ echo "${ECHO_T}$ol_cv_db_db_4_dot_2" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
+		if test $ol_cv_lib_db = no ; then
 	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-2)" >&5
 echo $ECHO_N "checking for Berkeley DB link (-ldb-4-2)... $ECHO_C" >&6
 if test "${ol_cv_db_db_4_2+set}" = set; then
@@ -31371,14 +32890,15 @@ echo "${ECHO_T}$ol_cv_db_db_4_2" >&6
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4+set}" = set; then
+	elif test $ol_cv_bdb_minor = 1 ; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb41)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb41)... $ECHO_C" >&6
+if test "${ol_cv_db_db41+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4
+	ol_DB_LIB=-ldb41
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -31459,12 +32979,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4=yes
+  ol_cv_db_db41=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4=no
+ol_cv_db_db41=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -31472,22 +32992,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4" >&5
-echo "${ECHO_T}$ol_cv_db_db_4" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db41" >&5
+echo "${ECHO_T}$ol_cv_db_db41" >&6
 
-	if test $ol_cv_db_db_4 = yes ; then
-		ol_cv_lib_db=-ldb-4
+	if test $ol_cv_db_db41 = yes ; then
+		ol_cv_lib_db=-ldb41
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb4)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb4)... $ECHO_C" >&6
-if test "${ol_cv_db_db4+set}" = set; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-41)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-41)... $ECHO_C" >&6
+if test "${ol_cv_db_db_41+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb4
+	ol_DB_LIB=-ldb-41
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -31568,12 +33088,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db4=yes
+  ol_cv_db_db_41=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db4=no
+ol_cv_db_db_41=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -31581,22 +33101,131 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db4" >&5
-echo "${ECHO_T}$ol_cv_db_db4" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_41" >&5
+echo "${ECHO_T}$ol_cv_db_db_41" >&6
 
-	if test $ol_cv_db_db4 = yes ; then
-		ol_cv_lib_db=-ldb4
+	if test $ol_cv_db_db_41 = yes ; then
+		ol_cv_lib_db=-ldb-41
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb)... $ECHO_C" >&6
-if test "${ol_cv_db_db+set}" = set; then
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.1)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4.1)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_dot_1+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb
+	ol_DB_LIB=-ldb-4.1
+	ol_LIBS=$LIBS
+	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#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
+
+int
+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 )
+		{
+			printf("Berkeley DB version mismatch\n"
+				"\theader: %s\n\tlibrary: %s\n",
+				DB_VERSION_STRING, version);
+			return 1;
+		}
+	}
+#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
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ol_cv_db_db_4_dot_1=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ol_cv_db_db_4_dot_1=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+	LIBS="$ol_LIBS"
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_1" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_dot_1" >&6
+
+	if test $ol_cv_db_db_4_dot_1 = yes ; then
+		ol_cv_lib_db=-ldb-4.1
+	fi
+fi
+
+		if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-1)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4-1)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4_1+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+	ol_DB_LIB=-ldb-4-1
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -31677,12 +33306,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db=yes
+  ol_cv_db_db_4_1=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db=no
+ol_cv_db_db_4_1=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -31690,22 +33319,23 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db" >&5
-echo "${ECHO_T}$ol_cv_db_db" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4_1" >&5
+echo "${ECHO_T}$ol_cv_db_db_4_1" >&6
 
-	if test $ol_cv_db_db = yes ; then
-		ol_cv_lib_db=-ldb
+	if test $ol_cv_db_db_4_1 = yes ; then
+		ol_cv_lib_db=-ldb-4-1
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb41)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb41)... $ECHO_C" >&6
-if test "${ol_cv_db_db41+set}" = set; then
+	fi
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-4)... $ECHO_C" >&6
+if test "${ol_cv_db_db_4+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb41
+	ol_DB_LIB=-ldb-4
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -31786,12 +33416,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db41=yes
+  ol_cv_db_db_4=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db41=no
+ol_cv_db_db_4=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -31799,22 +33429,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db41" >&5
-echo "${ECHO_T}$ol_cv_db_db41" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_4" >&5
+echo "${ECHO_T}$ol_cv_db_db_4" >&6
 
-	if test $ol_cv_db_db41 = yes ; then
-		ol_cv_lib_db=-ldb41
+	if test $ol_cv_db_db_4 = yes ; then
+		ol_cv_lib_db=-ldb-4
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-41)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-41)... $ECHO_C" >&6
-if test "${ol_cv_db_db_41+set}" = set; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb4)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb4)... $ECHO_C" >&6
+if test "${ol_cv_db_db4+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-41
+	ol_DB_LIB=-ldb4
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -31895,12 +33525,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_41=yes
+  ol_cv_db_db4=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_41=no
+ol_cv_db_db4=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -31908,22 +33538,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_41" >&5
-echo "${ECHO_T}$ol_cv_db_db_41" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db4" >&5
+echo "${ECHO_T}$ol_cv_db_db4" >&6
 
-	if test $ol_cv_db_db_41 = yes ; then
-		ol_cv_lib_db=-ldb-41
+	if test $ol_cv_db_db4 = yes ; then
+		ol_cv_lib_db=-ldb4
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4.1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4.1)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_dot_1+set}" = set; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb)... $ECHO_C" >&6
+if test "${ol_cv_db_db+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4.1
+	ol_DB_LIB=-ldb
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -32004,12 +33634,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_dot_1=yes
+  ol_cv_db_db=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_dot_1=no
+ol_cv_db_db=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -32017,22 +33647,24 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_dot_1" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_dot_1" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db" >&5
+echo "${ECHO_T}$ol_cv_db_db" >&6
 
-	if test $ol_cv_db_db_4_dot_1 = yes ; then
-		ol_cv_lib_db=-ldb-4.1
+	if test $ol_cv_db_db = yes ; then
+		ol_cv_lib_db=-ldb
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-4-1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-4-1)... $ECHO_C" >&6
-if test "${ol_cv_db_db_4_1+set}" = set; then
+
+elif test $ol_cv_bdb_major = 3 ; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb3)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb3)... $ECHO_C" >&6
+if test "${ol_cv_db_db3+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-4-1
+	ol_DB_LIB=-ldb3
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -32113,12 +33745,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_4_1=yes
+  ol_cv_db_db3=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_4_1=no
+ol_cv_db_db3=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -32126,22 +33758,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_4_1" >&5
-echo "${ECHO_T}$ol_cv_db_db_4_1" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db3" >&5
+echo "${ECHO_T}$ol_cv_db_db3" >&6
 
-	if test $ol_cv_db_db_4_1 = yes ; then
-		ol_cv_lib_db=-ldb-4-1
+	if test $ol_cv_db_db3 = yes ; then
+		ol_cv_lib_db=-ldb3
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb3)... $ECHO_C" >&6
-if test "${ol_cv_db_db3+set}" = set; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-3)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-3)... $ECHO_C" >&6
+if test "${ol_cv_db_db_3+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb3
+	ol_DB_LIB=-ldb-3
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -32222,12 +33854,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db3=yes
+  ol_cv_db_db_3=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db3=no
+ol_cv_db_db_3=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -32235,22 +33867,24 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db3" >&5
-echo "${ECHO_T}$ol_cv_db_db3" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_3" >&5
+echo "${ECHO_T}$ol_cv_db_db_3" >&6
 
-	if test $ol_cv_db_db3 = yes ; then
-		ol_cv_lib_db=-ldb3
+	if test $ol_cv_db_db_3 = yes ; then
+		ol_cv_lib_db=-ldb-3
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-3)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-3)... $ECHO_C" >&6
-if test "${ol_cv_db_db_3+set}" = set; then
+
+elif test $ol_cv_bdb_major = 2 ; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb2)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb2)... $ECHO_C" >&6
+if test "${ol_cv_db_db2+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-3
+	ol_DB_LIB=-ldb2
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -32331,12 +33965,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_3=yes
+  ol_cv_db_db2=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_3=no
+ol_cv_db_db2=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -32344,22 +33978,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_3" >&5
-echo "${ECHO_T}$ol_cv_db_db_3" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db2" >&5
+echo "${ECHO_T}$ol_cv_db_db2" >&6
 
-	if test $ol_cv_db_db_3 = yes ; then
-		ol_cv_lib_db=-ldb-3
+	if test $ol_cv_db_db2 = yes ; then
+		ol_cv_lib_db=-ldb2
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb2)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb2)... $ECHO_C" >&6
-if test "${ol_cv_db_db2+set}" = set; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-2)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-2)... $ECHO_C" >&6
+if test "${ol_cv_db_db_2+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb2
+	ol_DB_LIB=-ldb-2
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -32440,12 +34074,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db2=yes
+  ol_cv_db_db_2=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db2=no
+ol_cv_db_db_2=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -32453,22 +34087,24 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db2" >&5
-echo "${ECHO_T}$ol_cv_db_db2" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_2" >&5
+echo "${ECHO_T}$ol_cv_db_db_2" >&6
 
-	if test $ol_cv_db_db2 = yes ; then
-		ol_cv_lib_db=-ldb2
+	if test $ol_cv_db_db_2 = yes ; then
+		ol_cv_lib_db=-ldb-2
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-2)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-2)... $ECHO_C" >&6
-if test "${ol_cv_db_db_2+set}" = set; then
+
+elif test $ol_cv_bdb_major = 1 ; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb1)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb1)... $ECHO_C" >&6
+if test "${ol_cv_db_db1+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-2
+	ol_DB_LIB=-ldb1
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -32549,12 +34185,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_2=yes
+  ol_cv_db_db1=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_2=no
+ol_cv_db_db1=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -32562,22 +34198,22 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_2" >&5
-echo "${ECHO_T}$ol_cv_db_db_2" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db1" >&5
+echo "${ECHO_T}$ol_cv_db_db1" >&6
 
-	if test $ol_cv_db_db_2 = yes ; then
-		ol_cv_lib_db=-ldb-2
+	if test $ol_cv_db_db1 = yes ; then
+		ol_cv_lib_db=-ldb1
 	fi
 fi
 
-if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb1)... $ECHO_C" >&6
-if test "${ol_cv_db_db1+set}" = set; then
+	if test $ol_cv_lib_db = no ; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-1)" >&5
+echo $ECHO_N "checking for Berkeley DB link (-ldb-1)... $ECHO_C" >&6
+if test "${ol_cv_db_db_1+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb1
+	ol_DB_LIB=-ldb-1
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -32658,12 +34294,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db1=yes
+  ol_cv_db_db_1=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db1=no
+ol_cv_db_db_1=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -32671,22 +34307,23 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db1" >&5
-echo "${ECHO_T}$ol_cv_db_db1" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_db_1" >&5
+echo "${ECHO_T}$ol_cv_db_db_1" >&6
 
-	if test $ol_cv_db_db1 = yes ; then
-		ol_cv_lib_db=-ldb1
+	if test $ol_cv_db_db_1 = yes ; then
+		ol_cv_lib_db=-ldb-1
 	fi
 fi
 
+fi
 if test $ol_cv_lib_db = no ; then
-	echo "$as_me:$LINENO: checking for Berkeley DB link (-ldb-1)" >&5
-echo $ECHO_N "checking for Berkeley DB link (-ldb-1)... $ECHO_C" >&6
-if test "${ol_cv_db_db_1+set}" = set; then
+	echo "$as_me:$LINENO: checking for Berkeley DB link (default)" >&5
+echo $ECHO_N "checking for Berkeley DB link (default)... $ECHO_C" >&6
+if test "${ol_cv_db_none+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-	ol_DB_LIB=-ldb-1
+	ol_DB_LIB=
 	ol_LIBS=$LIBS
 	LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS"
 
@@ -32767,12 +34404,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
-  ol_cv_db_db_1=yes
+  ol_cv_db_none=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-ol_cv_db_db_1=no
+ol_cv_db_none=no
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
@@ -32780,11 +34417,11 @@ rm -f conftest.err conftest.$ac_objext \
 	LIBS="$ol_LIBS"
 
 fi
-echo "$as_me:$LINENO: result: $ol_cv_db_db_1" >&5
-echo "${ECHO_T}$ol_cv_db_db_1" >&6
+echo "$as_me:$LINENO: result: $ol_cv_db_none" >&5
+echo "${ECHO_T}$ol_cv_db_none" >&6
 
-	if test $ol_cv_db_db_1 = yes ; then
-		ol_cv_lib_db=-ldb-1
+	if test $ol_cv_db_none = yes ; then
+		ol_cv_lib_db=yes
 	fi
 fi
 
@@ -43227,7 +44864,10 @@ cat >>$CONFIG_STATUS <<_ACEOF
 #
 
 AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
 STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS"
+STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS"
+
 
 _ACEOF
 
@@ -44249,6 +45889,59 @@ ENDX
 /* end of generated file */
 ENDX
 fi
+OVERLAYSC="servers/slapd/overlays/statover.c"
+echo "Making $OVERLAYSC"
+rm -f $OVERLAYSC
+cat > $OVERLAYSC << ENDX
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2005 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>.
+ */
+/* This file is automatically generated by configure; please do not edit. */
+
+#include "portable.h"
+#include "slap.h"
+
+ENDX
+if test "${STATIC_OVERLAYS}"; then
+	for o in ${STATIC_OVERLAYS}; do
+		oo=`echo "${o}" | sed -e 's/.o$//' -e 's/_x$//'`
+		cat >> $OVERLAYSC << ENDX
+extern OV_init ${oo}_initialize;
+ENDX
+	done
+fi
+
+cat >> $OVERLAYSC << ENDX
+
+OverlayInit slap_oinfo[] = {
+ENDX
+
+if test "${STATIC_OVERLAYS}"; then
+	for o in ${STATIC_OVERLAYS}; do
+		oo=`echo "${o}" | sed -e 's/.o$//' -e 's/_x$//'`
+		echo "    Add ${oo} ..."
+		cat >> $OVERLAYSC << ENDX
+	{ "${oo}", ${oo}_initialize },
+ENDX
+	done
+fi
+
+	cat >> $OVERLAYSC << ENDX
+	{ NULL, NULL },
+};
+
+/* end of generated file */
+ENDX
 
 echo Please run \"make depend\" to build dependencies
  ;;
diff --git a/doc/man/man1/ldapsearch.1 b/doc/man/man1/ldapsearch.1
index 628712b01eee12a8db15d9bccd48d216fe4f092a..d7b82a03662553ea88693b54ddf4a093bd63d1ff 100644
--- a/doc/man/man1/ldapsearch.1
+++ b/doc/man/man1/ldapsearch.1
@@ -43,7 +43,7 @@ ldapsearch \- LDAP search tool
 [\c
 .BI \-b \ searchbase\fR]
 [\c
-.BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub\fR]
+.BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub\fR\||\|\fIchildren\fR]
 [\c
 .BI \-a \ never\fR\||\|\fIalways\fR\||\|\fIsearch\fR\||\|\fIfind\fR]
 [\c
@@ -183,15 +183,19 @@ Deprecated in favor of -H.
 Use \fIsearchbase\fP as the starting point for the search instead of
 the default.
 .TP
-.BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub
+.BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub\fR\||\|\fIchildren
 Specify the scope of the search to be one of
 .IR base ,
 .IR one ,
+.IR sub ,
 or
-.I sub
-to specify a base object, one-level, or subtree search.  The default
-is
+.I children
+to specify a base object, one-level, subtree, or children search.
+The default is
 .IR sub .
+Note:
+.I children
+scope requires LDAPv3 subordinate feature extension.
 .TP
 .BI \-a \ never\fR\||\|\fIalways\fR\||\|\fIsearch\fR\||\|\fIfind
 Specify how aliases dereferencing is done.  Should be one of
diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5
index 580a08476505f4b06c669fb1156f4093a6cebb1c..a552f4db8c02539b46e9d9105cf83f07a741338a 100644
--- a/doc/man/man5/slapd.conf.5
+++ b/doc/man/man5/slapd.conf.5
@@ -1758,7 +1758,8 @@ By default it is not built.
 .B chain
 Chaining.
 This overlay allows automatic referral chasing when a referral would
-have been returned.
+have been returned, either when configured by the server or when 
+requested by the client.
 .TP
 .B denyop
 Deny Operation.
diff --git a/doc/man/man5/slapo-accesslog.5 b/doc/man/man5/slapo-accesslog.5
index 9e869a2cc52bd716ff221a273d49329f4e0ab9ad..49d6bb3f38d811ee8f3b9924421105ef3bfcae9f 100644
--- a/doc/man/man5/slapo-accesslog.5
+++ b/doc/man/man5/slapo-accesslog.5
@@ -28,9 +28,9 @@ directive.
 .B logdb <suffix>
 Specify the suffix of a database to be used for storing the log records.
 The specified database must have already been configured in a prior section
-of the config file. The suffix entry of the database must also already
-exist. The log entries will be generated as the immediate children of the
-suffix entry.
+of the config file. The suffix entry of the log database will be created
+automatically by this overlay. The log entries will be generated as the
+immediate children of the suffix entry.
 .TP
 .B logops <operations>
 Specify which types of operations to log. The valid operation types are
diff --git a/doc/man/man5/slapo-chain.5 b/doc/man/man5/slapo-chain.5
index 27f9b5a2ba8f30d3ed431a2dedf899e09c1ca2a1..96cc0d4904697ab1c444a3f5caf85b4f80d1fc32 100644
--- a/doc/man/man5/slapo-chain.5
+++ b/doc/man/man5/slapo-chain.5
@@ -13,7 +13,7 @@ overlay to
 .BR slapd (8)
 allows automatic referral chasing.
 Any time a referral is returned (except for bind operations),
-it is chased by using an instance of the ldap backend.
+it chased by using an instance of the ldap backend.
 If operations are performed with an identity (i.e. after a bind),
 that identity can be asserted while chasing the referrals 
 by means of the \fIidentity assertion\fP feature of back-ldap
@@ -21,52 +21,104 @@ by means of the \fIidentity assertion\fP feature of back-ldap
 .BR slapd-ldap (5)
 for details), which is essentially based on the
 .B proxyAuthz
-control (see \fIdraft-weltman-ldapv3-proxy\fP for details).
+control (see \fIdraft-weltman-ldapv3-proxy\fP for details.)
+Referral chasing can be controlled by the client by issuing the 
+\fBchaining\fP control
+(see \fIdraft-sermersheim-ldap-chaining\fP for details.)
 
 .LP 
 The config directives that are specific to the
 .B chain
-overlay can be prefixed by
+overlay are prefixed by
 .BR chain\- ,
 to avoid potential conflicts with directives specific to the underlying 
 database or to other stacked overlays.
 
 .LP
-There are no chain overlay specific directives; however, directives 
-related to the \fIldap\fP database that is implicitly instantiated 
-by the overlay may assume a special meaning when used in conjunction
-with this overlay.  They are described in
-.BR slapd-ldap (5).
+There are very few chain overlay specific directives; however, directives 
+related to the instances of the \fIldap\fP backend that may be implicitly 
+instantiated by the overlay may assume a special meaning when used 
+in conjunction with this overlay.  They are described in
+.BR slapd-ldap (5),
+and they also need be prefixed by
+.BR chain\- .
 .TP
 .B overlay chain
 This directive adds the chain overlay to the current backend.
 The chain overlay may be used with any backend, but it is mainly 
 intended for use with local storage backends that may return referrals.
-It is useless in conjunction with the \fIldap\fP and \fImeta\fP backends
-because they already exploit the libldap specific referral chase feature.
+It is useless in conjunction with the \fIslapd-ldap\fP and \fIslapd-meta\fP
+backends because they already exploit the libldap specific referral chase 
+feature.
+[Note: this may change in the future, as the \fBldap\fP(5) and 
+\fBmeta\fP(5) backends might no longer chase referrals on their own.]
+.TP
+.B chain-chaining [resolve=<r>] [continuation=<c>] [critical]
+This directive enables the \fIchaining\fP control
+(see \fIdraft-sermersheim-ldap-chaining\fP for details)
+with the desired resolve and continuation behaviors and criticality.
+The \fBresolve\fP parameter refers to the behavior while discovering
+a resource, namely when accessing the object indicated by the request DN;
+the \fBcontinuation\fP parameter refers to the behavior while handling
+intermediate responses, which is mostly significant for the search 
+operation, but may affect extended operations that return intermediate
+responses.
+The values \fBr\fP and \fBc\fP can be any of
+.BR chainingPreferred ,
+.BR chainingRequired ,
+.BR referralsPreferred ,
+.BR referralsRequired .
+If the \fBcritical\fP flag affects the control criticality if provided.
+[This control is experimental and its support may change in the future.]
+.TP
+.B chain-cache-uris {FALSE|true}
+This directive instructs the \fIchain\fP overlay to cache
+connections to URIs parsed out of referrals that are not predefined,
+to be reused for later chaining.
 .TP
 .B chain-uri <ldapuri>
-This directive instructs the underlying ldap database about which
-URI to contact to chase referrals.
-If not present, the referral itself is parsed, and the protocol/host/port
-portions are used to establish a connection.
-
+This directive instantiates a new underlying \fIldap\fP database
+and instructs it about which URI to contact to chase referrals.
+As opposed to what stated in \fBslapd-ldap\fP(5), only one URI
+can appear after this directive; all subsequent \fBslapd-ldap\fP(5)
+directives prefixed by \fBchain-\fP refer to this specific instance
+of a remote server.
 .LP
+
 Directives for configuring the underlying ldap database may also 
-be required, as shown here:
+be required, as shown in this example:
 .LP
 .RS
 .nf
-chain-idassert-method	"simple"
-chain-idassert-authcDN	"cn=Auth,dc=example,dc=com"
-chain-idassert-passwd	"secret"
-chain-idassert-mode	"self"
+overlay                 chain
+chain-rebind-as-user    FALSE
+
+chain-uri               "ldap://ldap1.example.com"
+chain-rebind-as-user    TRUE
+chain-idassert-bind     bindmethod="simple"
+                        binddn="cn=Auth,dc=example,dc=com"
+                        credentials="secret"
+                        mode="self"
+
+chain-uri               "ldap://ldap2.example.com"
+chain-idassert-bind     bindmethod="simple"
+                        binddn="cn=Auth,dc=example,dc=com"
+                        credentials="secret"
+                        mode="none"
+
 .fi
 .RE
 .LP
 Any valid directives for the ldap database may be used; see
 .BR slapd-ldap (5)
 for details.
+Multiple occurrences of the \fBchain-uri\fP directive may appear,
+to define multiple "trusted" URIs where operations with 
+\fIidentity assertion\fP are chained.
+All URIs not listed in the configuration are chained anonymously.
+All \fBslapd-ldap\fP(5) directives appearing before the first 
+occurrence of \fBchain-uri\fP are inherited by all URIs,
+unless specifically overridden inside each URI configuration.
 .SH FILES
 .TP
 ETCDIR/slapd.conf
@@ -76,4 +128,4 @@ default slapd configuration file
 .BR slapd\-ldap (5),
 .BR slapd (8).
 .SH AUTHOR
-Originally implemented by Howard Chu.
+Originally implemented by Howard Chu; extended by Pierangelo Masarati.
diff --git a/doc/man/man5/slapo-pcache.5 b/doc/man/man5/slapo-pcache.5
index 0a7a733cb92b50ad93fd3977da24b0b96f61d304..a0e1bb6370a25353a158b83541da4cc6829d6edc 100644
--- a/doc/man/man5/slapo-pcache.5
+++ b/doc/man/man5/slapo-pcache.5
@@ -93,6 +93,23 @@ at response, it would cache entries that may be later "massaged"
 by other databases and thus returned \fIafter\fP massaging the first
 time, and \fIbefore\fP massaging when cached.
 
+.TP
+There are some constraints:
+
+all values must be positive;
+
+.B <entry_limit>
+must be less than or equal to
+.BR <max_entries> ;
+
+.B <numattrsets>
+attribute sets SHOULD be defined by using the directive
+.BR proxyattrset ;
+
+all attribute sets SHOULD be referenced by (at least) one
+.B proxytemplate
+directive; 
+
 .LP
 The following adds a template with filter string \fB((&sn=)(givenName=))\fP 
 and attributes mail, postaladdress, telephonenumber and a TTL of 1 hour. 
@@ -116,7 +133,52 @@ cachesize 100
 .RE
 .LP
 Any valid directives for the chosen database type may be used.
+.SH CAVEATS
+Caching data is prone to inconsistencies because updates on the remote server
+will not be reflected in the response of the cache at least (and at most)
+for the duration of the
+.B proxytemplate
+.BR TTL .
+
+Another potential (and subtle) inconsistency may occur when data is retrieved 
+with different identities and specific per-identity access control
+is enforced by the remote server.
+If data was retrieved with an identity that collected only partial results
+because of access rules enforcement on the remote server, other users
+with different access privileges on the remote server will get different
+results from the remote server and from the cache.
+If those users have higher access privileges on the remote server, they will 
+get from the cache only a subset of the results they would get directly 
+from the remote server; but if they have lower access privileges, they will 
+get from the cache a superset of the results they would get directly 
+from the remote server.
+Either occurrence may or may not be acceptable, based on the security policy
+of the cache and of the remote server.
+It is important to note that in this case the proxy is violating the security
+of the remote server by disclosing to an identity data that was collected 
+by another identity.
+For this reason, it is suggested that, when using
+.BR back-ldap ,
+proxy caching be used in conjunction with the 
+.I identity assertion
+feature of
+.BR slapd-ldap (5)
+(see the
+.B idassert-bind
+and the
+.B idassert-authz
+statements), so that remote server interrogation occurs with a vanilla identity 
+that has some relatively high
+.B search
+and
+.B read
+access privileges, and the "real" access control is delegated to the proxy's ACLs.
+Beware that since only the cached fraction of the real datum is available
+to the cache, it may not be possible to enforce the same access rules that
+are defined on the remote server.
+When security is a concern, cached proxy access must be carefully tailored.
 .SH FILES
+
 .TP
 ETCDIR/slapd.conf
 default slapd configuration file
diff --git a/libraries/librewrite/config.c b/libraries/librewrite/config.c
index b6c729406eb5aa0df8b99b5b8ce116ff36ca8a2c..a3956ec9233d61f6a891f5bdbb74509ba53330a1 100644
--- a/libraries/librewrite/config.c
+++ b/libraries/librewrite/config.c
@@ -104,19 +104,33 @@ rewrite_parse(
 			return -1;
 		}
 
-		info->li_max_passes = atoi( argv[ 1 ] );
+		if ( lutil_atoi( &info->li_max_passes, argv[ 1 ] ) != 0 ) {
+			Debug( LDAP_DEBUG_ANY,
+					"[%s:%d] unable to parse rewriteMaxPasses=\"%s\"\n",
+					fname, lineno, argv[ 1 ] );
+			return -1;
+		}
+
 		if ( info->li_max_passes <= 0 ) {
 			Debug( LDAP_DEBUG_ANY,
-					"[%s:%d] negative or null rewriteMaxPasses'\n",
+					"[%s:%d] negative or null rewriteMaxPasses\n",
 					fname, lineno, 0 );
+			return -1;
 		}
 
 		if ( argc > 2 ) {
-			info->li_max_passes_per_rule = atoi( argv[ 2 ] );
+			if ( lutil_atoi( &info->li_max_passes_per_rule, argv[ 2 ] ) != 0 ) {
+				Debug( LDAP_DEBUG_ANY,
+						"[%s:%d] unable to parse rewriteMaxPassesPerRule=\"%s\"\n",
+						fname, lineno, argv[ 2 ] );
+				return -1;
+			}
+
 			if ( info->li_max_passes_per_rule <= 0 ) {
 				Debug( LDAP_DEBUG_ANY,
-						"[%s:%d] negative or null rewriteMaxPassesPerRule'\n",
+						"[%s:%d] negative or null rewriteMaxPassesPerRule\n",
 						fname, lineno, 0 );
+				return -1;
 			}
 
 		} else {
diff --git a/servers/slapd/aci.c b/servers/slapd/aci.c
index 50bef60b754bf31c3d0458643b6c229601ca6794..70e749ef0a06b758d1b9fdbbf216593c632d138b 100644
--- a/servers/slapd/aci.c
+++ b/servers/slapd/aci.c
@@ -696,7 +696,7 @@ aci_init( void )
 		&rc, &text, LDAP_SCHEMA_ALLOW_ALL );
 	if ( !at ) {
 		Debug( LDAP_DEBUG_ANY,
-			"%s AttributeType load failed: %s %s\n",
+			"aci_init: AttributeType \"%s\" parse failed: %s %s\n",
 			aci_at.name, ldap_scherr2str( rc ), text );
 		return rc;
 	}
@@ -704,9 +704,9 @@ aci_init( void )
 	rc = at_add( at, 0, &sat, &text );
 	if ( rc != LDAP_SUCCESS ) {
 		ldap_attributetype_free( at );
-		fprintf( stderr, "iMUX_monitor_schema_init: "
-			"AttributeType load failed: %s %s\n",
-			scherr2str( rc ), text );
+		Debug( LDAP_DEBUG_ANY,
+			"aci_init: AttributeType \"%s\" load failed: %s %s\n",
+			aci_at.name, scherr2str( rc ), text );
 		return rc;
 	}
 	ldap_memfree( at );
@@ -715,7 +715,7 @@ aci_init( void )
 			aci_at.ad, &text );
 	if ( rc != LDAP_SUCCESS ) {
 		Debug( LDAP_DEBUG_ANY,
-			"unable to find AttributeDescription "
+			"aci_init: unable to find AttributeDescription "
 			"\"%s\": %d (%s)\n",
 			aci_at.name, rc, text );
 		return 1;
diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c
index 5b84f9e3045225dffff4faf4f8a8c9fa63fdf41d..48d5eb7f142b1bcecf431d563c3e3bba54be496a 100644
--- a/servers/slapd/acl.c
+++ b/servers/slapd/acl.c
@@ -310,9 +310,10 @@ fe_access_allowed(
 	 */
 	be_orig = op->o_bd;
 
-	op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
 	if ( op->o_bd == NULL ) {
-		op->o_bd = frontendDB;
+		op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
+		if ( op->o_bd == NULL )
+			op->o_bd = frontendDB;
 	}
 	rc = slap_access_allowed( op, e, desc, val, access, state, maskp );
 	op->o_bd = be_orig;
@@ -423,14 +424,10 @@ access_allowed_mask(
 				desc, val, access, state, &mask );
 
 	} else {
-		BackendDB	*be_orig = op->o_bd;
-
 		/* use default (but pass through frontend
 		 * for global ACL overlays) */
-		op->o_bd = frontendDB;
 		ret = frontendDB->bd_info->bi_access_allowed( op, e,
 				desc, val, access, state, &mask );
-		op->o_bd = be_orig;
 	}
 
 	if ( !ret ) {
@@ -1603,12 +1600,9 @@ slap_acl_mask(
 
 						port = strrchr( ip.bv_val, ':' );
 						if ( port ) {
-							char	*next;
-							
 							ip.bv_len = port - ip.bv_val;
 							++port;
-							port_number = strtol( port, &next, 10 );
-							if ( next[0] != '\0' )
+							if ( lutil_atoi( &port_number, port ) != 0 )
 								continue;
 						}
 						
diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c
index 3c52759f7033aa55afc9b13438d3c3ac99913ec7..5a666a4650eda5feed604bf3e49e88121cade0a3 100644
--- a/servers/slapd/aclparse.c
+++ b/servers/slapd/aclparse.c
@@ -325,7 +325,7 @@ parse_acl(
 	int		pos )
 {
 	int		i;
-	char		*left, *right, *style, *next;
+	char		*left, *right, *style;
 	struct berval	bv;
 	AccessControl	*a;
 	Access	*b;
@@ -776,10 +776,7 @@ parse_acl(
 
 				} else if ( strcasecmp( style, "level" ) == 0 )
 				{
-					char	*next;
-
-					level = strtol( style_level, &next, 10 );
-					if ( next[0] != '\0' ) {
+					if ( lutil_atoi( &level, style_level ) != 0 ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: unable to parse level "
 							"in \"level{n}\"\n",
@@ -1385,7 +1382,7 @@ parse_acl(
 								char	*end = NULL;
 
 								b->a_peername_port = strtol( port, &end, 10 );
-								if ( end[0] != '}' ) {
+								if ( end == port || end[0] != '}' ) {
 									/* illegal port */
 									Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 										"illegal peername port specification "
@@ -1700,8 +1697,7 @@ parse_acl(
 						return acl_usage();
 					}
 
-					b->a_authz.sai_ssf = strtol( right, &next, 10 );
-					if ( next == NULL || next[0] != '\0' ) {
+					if ( lutil_atou( &b->a_authz.sai_ssf, right ) != 0 ) {
 						Debug( LDAP_DEBUG_ANY,
 							"%s: line %d: unable to parse ssf value (%s).\n",
 							fname, lineno, right );
@@ -1739,8 +1735,7 @@ parse_acl(
 						return acl_usage();
 					}
 
-					b->a_authz.sai_transport_ssf = strtol( right, &next, 10 );
-					if ( next == NULL || next[0] != '\0' ) {
+					if ( lutil_atou( &b->a_authz.sai_transport_ssf, right ) != 0 ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"unable to parse transport_ssf value (%s).\n",
 							fname, lineno, right );
@@ -1778,8 +1773,7 @@ parse_acl(
 						return acl_usage();
 					}
 
-					b->a_authz.sai_tls_ssf = strtol( right, &next, 10 );
-					if ( next == NULL || next[0] != '\0' ) {
+					if ( lutil_atou( &b->a_authz.sai_tls_ssf, right ) != 0 ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"unable to parse tls_ssf value (%s).\n",
 							fname, lineno, right );
@@ -1817,8 +1811,7 @@ parse_acl(
 						return acl_usage();
 					}
 
-					b->a_authz.sai_sasl_ssf = strtol( right, &next, 10 );
-					if ( next == NULL || next[0] != '\0' ) {
+					if ( lutil_atou( &b->a_authz.sai_sasl_ssf, right ) != 0 ) {
 						Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 							"unable to parse sasl_ssf value (%s).\n",
 							fname, lineno, right );
diff --git a/servers/slapd/at.c b/servers/slapd/at.c
index 8829b5541f222012e44f679b0ac1b449b4620599..b9239013fd5872c59c1115e70b118b1e64514a7b 100644
--- a/servers/slapd/at.c
+++ b/servers/slapd/at.c
@@ -345,14 +345,13 @@ at_insert(
     const char		**err )
 {
 	struct aindexrec	*air;
-	char			**names;
+	char			**names = NULL;
 
 
 	if ( sat->sat_oid ) {
 		air = (struct aindexrec *)
 			ch_calloc( 1, sizeof(struct aindexrec) );
-		air->air_name.bv_val = sat->sat_oid;
-		air->air_name.bv_len = strlen(sat->sat_oid);
+		ber_str2bv( sat->sat_oid, 0, 0, &air->air_name );
 		air->air_at = sat;
 		if ( avl_insert( &attr_index, (caddr_t) air,
 		                 attr_index_cmp, avl_dup_error ) )
@@ -379,8 +378,7 @@ at_insert(
 		while ( *names ) {
 			air = (struct aindexrec *)
 				ch_calloc( 1, sizeof(struct aindexrec) );
-			air->air_name.bv_val = *names;
-			air->air_name.bv_len = strlen(*names);
+			ber_str2bv( *names, 0, 0, &air->air_name );
 			air->air_at = sat;
 			if ( avl_insert( &attr_index, (caddr_t) air,
 			                 attr_index_cmp, avl_dup_error ) )
@@ -396,6 +394,29 @@ at_insert(
 
 				ldap_memfree(air);
 
+				while ( names > sat->sat_names ) {
+					struct aindexrec	tmpair;
+
+					names--;
+					ber_str2bv( *names, 0, 0, &tmpair.air_name );
+					tmpair.air_at = sat;
+					air = (struct aindexrec *)avl_delete( &attr_index,
+						(caddr_t)&tmpair, attr_index_cmp );
+					assert( air != NULL );
+					ldap_memfree( air );
+				}
+
+				if ( sat->sat_oid ) {
+					struct aindexrec	tmpair;
+
+					ber_str2bv( sat->sat_oid, 0, 0, &tmpair.air_name );
+					tmpair.air_at = sat;
+					air = (struct aindexrec *)avl_delete( &attr_index,
+						(caddr_t)&tmpair, attr_index_cmp );
+					assert( air != NULL );
+					ldap_memfree( air );
+				}
+
 				return rc;
 			}
 			/* FIX: temporal consistency check */
@@ -428,16 +449,17 @@ at_add(
 	AttributeType		**rsat,
 	const char		**err )
 {
-	AttributeType	*sat;
-	MatchingRule	*mr;
-	Syntax		*syn;
+	AttributeType	*sat = NULL;
+	MatchingRule	*mr = NULL;
+	Syntax		*syn = NULL;
 	int		i;
-	int		code;
-	char	*cname;
-	char	*oid;
-	char	*oidm = NULL;
+	int		code = LDAP_SUCCESS;
+	char		*cname = NULL;
+	char		*oidm = NULL;
 
 	if ( !OID_LEADCHAR( at->at_oid[0] )) {
+		char	*oid;
+
 		/* Expand OID macros */
 		oid = oidm_find( at->at_oid );
 		if ( !oid ) {
@@ -451,11 +473,14 @@ at_add(
 	}
 
 	if ( at->at_syntax_oid && !OID_LEADCHAR( at->at_syntax_oid[0] )) {
+		char	*oid;
+
 		/* Expand OID macros */
 		oid = oidm_find( at->at_syntax_oid );
 		if ( !oid ) {
 			*err = at->at_syntax_oid;
-			return SLAP_SCHERR_OIDM;
+			code = SLAP_SCHERR_OIDM;
+			goto error_return;
 		}
 		if ( oid != at->at_syntax_oid ) {
 			ldap_memfree( at->at_syntax_oid );
@@ -469,7 +494,8 @@ at_add(
 		for( i=0; at->at_names[i]; i++ ) {
 			if( !slap_valid_descr( at->at_names[i] ) ) {
 				*err = at->at_names[i];
-				return SLAP_SCHERR_BAD_DESCR;
+				code = SLAP_SCHERR_BAD_DESCR;
+				goto error_return;
 			}
 		}
 
@@ -480,25 +506,29 @@ at_add(
 
 	} else {
 		*err = "";
-		return SLAP_SCHERR_ATTR_INCOMPLETE;
+		code = SLAP_SCHERR_ATTR_INCOMPLETE;
+		goto error_return;
 	}
 
 	*err = cname;
 
 	if ( !at->at_usage && at->at_no_user_mod ) {
 		/* user attribute must be modifable */
-		return SLAP_SCHERR_ATTR_BAD_USAGE;
+		code = SLAP_SCHERR_ATTR_BAD_USAGE;
+		goto error_return;
 	}
 
 	if ( at->at_collective ) {
 		if( at->at_usage ) {
 			/* collective attributes cannot be operational */
-			return SLAP_SCHERR_ATTR_BAD_USAGE;
+			code = SLAP_SCHERR_ATTR_BAD_USAGE;
+			goto error_return;
 		}
 
 		if( at->at_single_value ) {
 			/* collective attributes cannot be single-valued */
-			return SLAP_SCHERR_ATTR_BAD_USAGE;
+			code = SLAP_SCHERR_ATTR_BAD_USAGE;
+			goto error_return;
 		}
 	}
 
diff --git a/servers/slapd/back-bdb/config.c b/servers/slapd/back-bdb/config.c
index fa2bf98de5432a7c3f50e06bc12319a3a5a9da23..637bc027acc71a537b53d7b4c6d0f980d2a20200 100644
--- a/servers/slapd/back-bdb/config.c
+++ b/servers/slapd/back-bdb/config.c
@@ -484,10 +484,23 @@ bdb_cf_gen(ConfigArgs *c)
 	}
 
 	switch( c->type ) {
-	case BDB_CHKPT:
+	case BDB_CHKPT: {
+		long	l;
 		bdb->bi_txn_cp = 1;
-		bdb->bi_txn_cp_kbyte = strtol( c->argv[1], NULL, 0 );
-		bdb->bi_txn_cp_min = strtol( c->argv[2], NULL, 0 );
+		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.
 		 */
@@ -507,7 +520,7 @@ bdb_cf_gen(ConfigArgs *c)
 					LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val );
 			}
 		}
-		break;
+		} break;
 
 	case BDB_CONFIG: {
 		char *ptr = c->line;
diff --git a/servers/slapd/back-bdb/dn2id.c b/servers/slapd/back-bdb/dn2id.c
index 51beedb2f4c4967b1f127eb2d99f55976a30fcc6..311fb30f1934b80041f743b288d1b3ee03671695 100644
--- a/servers/slapd/back-bdb/dn2id.c
+++ b/servers/slapd/back-bdb/dn2id.c
@@ -948,35 +948,38 @@ hdb_dn2idl_internal(
 		cx->data.ulen = BDB_IDL_UM_SIZE * sizeof(ID);
 		cx->data.flags = DB_DBT_USERMEM;
 
-		/* 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 );
+		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 );
diff --git a/servers/slapd/back-bdb/filterindex.c b/servers/slapd/back-bdb/filterindex.c
index 21431fec2d01c30f60b661be9012198c9e0e42f9..a1e124d614cea1e5e08935b1815907d4efdce687 100644
--- a/servers/slapd/back-bdb/filterindex.c
+++ b/servers/slapd/back-bdb/filterindex.c
@@ -978,7 +978,6 @@ inequality_candidates(
 {
 	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};
@@ -1066,9 +1065,9 @@ inequality_candidates(
 
 		bdb_idl_union( ids, tmp );
 
-		if( BDB_IDL_IS_ZERO( ids ) )
+		if( op->ors_limit && op->ors_limit->lms_s_unchecked != -1 &&
+			BDB_IDL_N( ids ) >= (unsigned) op->ors_limit->lms_s_unchecked )
 			break;
-		i++;
 	}
 	ber_bvarray_free_x( keys, op->o_tmpmemctx );
 
diff --git a/servers/slapd/back-bdb/idl.c b/servers/slapd/back-bdb/idl.c
index d43d210e33b90239c6944c2c777c3e01d205d181..c29d9228ce1200c8c082c619125a8cf0a8353b31 100644
--- a/servers/slapd/back-bdb/idl.c
+++ b/servers/slapd/back-bdb/idl.c
@@ -1311,7 +1311,7 @@ int bdb_idl_append_one( ID *ids, ID id )
  */
 int bdb_idl_append( ID *a, ID *b )
 {
-	ID ida, idb, tmp;
+	ID ida, idb, tmp, swap = 0;
 
 	if ( BDB_IDL_IS_ZERO( b ) ) {
 		return 0;
@@ -1333,6 +1333,7 @@ int bdb_idl_append( ID *a, ID *b )
 	}
 
 	if ( b[0] > 1 && ida > idb ) {
+		swap = idb;
 		a[a[0]] = idb;
 		b[b[0]] = ida;
 	}
@@ -1351,6 +1352,9 @@ int bdb_idl_append( ID *a, ID *b )
 		AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID));
 		a[0] += i;
 	}
+	if ( swap ) {
+		b[b[0]] = swap;
+	}
 	return 0;
 }
 
diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c
index 3fbf91bf6d262b49bb3acb8f5b7377e86ed28132..991bbc033f264c15bf214067cbfb27c73571b380 100644
--- a/servers/slapd/back-bdb/init.c
+++ b/servers/slapd/back-bdb/init.c
@@ -81,6 +81,9 @@ bdb_db_init( BackendDB *be )
 	return 0;
 }
 
+static int
+bdb_db_close( BackendDB *be );
+
 static int
 bdb_db_open( BackendDB *be )
 {
@@ -180,7 +183,7 @@ bdb_db_open( BackendDB *be )
 		Debug( LDAP_DEBUG_ANY,
 			"bdb_db_open: db_env_create failed: %s (%d)\n",
 			db_strerror(rc), rc, 0 );
-		return rc;
+		goto fail;
 	}
 
 	bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val );
@@ -198,7 +201,7 @@ bdb_db_open( BackendDB *be )
 			Debug( LDAP_DEBUG_ANY,
 				"bdb_db_open: dbenv_set_flags failed: %s (%d)\n",
 				db_strerror(rc), rc, 0 );
-			return rc;
+			goto fail;
 		}
 	}
 
@@ -248,7 +251,8 @@ bdb_db_open( BackendDB *be )
 				Debug( LDAP_DEBUG_ANY,
 					"bdb_db_open: Database cannot be recovered. "
 					"Restore from backup!\n", 0, 0, 0);
-				return -1;
+				rc = -1;
+				goto fail;
 			}
 			/* We need to recover, and we had TXN support before:
 			 * Close this env, open a new one with recovery flags.
@@ -261,7 +265,7 @@ bdb_db_open( BackendDB *be )
 					Debug( LDAP_DEBUG_ANY,
 						"bdb_db_open: db_env_create failed: %s (%d)\n",
 						db_strerror(rc), rc, 0 );
-					return rc;
+					goto fail;
 				}
 				bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv,
 					be->be_suffix[0].bv_val );
@@ -272,7 +276,7 @@ bdb_db_open( BackendDB *be )
 					Debug( LDAP_DEBUG_ANY,
 						"bdb_db_open: recovery failed: %s (%d)\n",
 						db_strerror(rc), rc, 0 );
-					return rc;
+					goto fail;
 				}
 				do_recover = 0;
 			}
@@ -285,7 +289,7 @@ bdb_db_open( BackendDB *be )
 					Debug( LDAP_DEBUG_ANY,
 						"bdb_db_open: db_env_create failed: %s (%d)\n",
 						db_strerror(rc), rc, 0 );
-					return rc;
+					goto fail;
 				}
 				bdb->bi_dbenv->remove( bdb->bi_dbenv, dbhome, 0 );
 				bdb->bi_dbenv = NULL;
@@ -297,7 +301,8 @@ bdb_db_open( BackendDB *be )
 				Debug( LDAP_DEBUG_ANY,
 					"bdb_db_open: Database cannot be recovered. "
 					"Restore from backup!\n", 0, 0, 0);
-				return -1;
+				rc = -1;
+				goto fail;
 			}
 			/* Prev environment had no TXN support, close it */
 			if ( !flags_ok ) {
@@ -321,7 +326,7 @@ bdb_db_open( BackendDB *be )
 				Debug( LDAP_DEBUG_ANY,
 					"bdb_db_open: db_env_create failed: %s (%d)\n",
 					db_strerror(rc), rc, 0 );
-				return rc;
+				goto fail;
 			}
 
 			bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val );
@@ -338,7 +343,7 @@ bdb_db_open( BackendDB *be )
 					Debug( LDAP_DEBUG_ANY,
 						"bdb_db_open: dbenv_set_flags failed: %s (%d)\n",
 						db_strerror(rc), rc, 0 );
-					return rc;
+					goto fail;
 				}
 			}
 		}
@@ -375,7 +380,7 @@ bdb_db_open( BackendDB *be )
 			Debug( LDAP_DEBUG_ANY,
 				"bdb_db_open: dbenv_open failed: %s (%d)\n",
 				db_strerror(rc), rc, 0 );
-			return rc;
+			goto fail;
 		}
 	}
 
@@ -383,7 +388,8 @@ bdb_db_open( BackendDB *be )
 		Debug( LDAP_DEBUG_ANY,
 			"bdb_db_open: alock_recover failed\n",
 			0, 0, 0 );
-		return -1;
+		rc = -1;
+		goto fail;
 	}
 
 #ifdef SLAP_ZONE_ALLOC
@@ -422,7 +428,7 @@ bdb_db_open( BackendDB *be )
 			Debug( LDAP_DEBUG_ANY,
 				"bdb_db_open: db_create(%s) failed: %s (%d)\n",
 				bdb->bi_dbenv_home, db_strerror(rc), rc );
-			return rc;
+			goto fail;
 		}
 
 		if( i == BDB_ID2ENTRY ) {
@@ -483,7 +489,8 @@ bdb_db_open( BackendDB *be )
 			Debug( LDAP_DEBUG_ANY,
 				"bdb_db_open: db_open(%s) failed: %s (%d)\n",
 				buf, db_strerror(rc), rc );
-			return rc;
+			db->bdi_db->close( db->bdi_db, 0 );
+			goto fail;
 		}
 
 		flags &= ~(DB_CREATE | DB_RDONLY);
@@ -500,7 +507,7 @@ bdb_db_open( BackendDB *be )
 		Debug( LDAP_DEBUG_ANY,
 			"bdb_db_open: last_id(%s) failed: %s (%d)\n",
 			bdb->bi_dbenv_home, db_strerror(rc), rc );
-		return rc;
+		goto fail;
 	}
 
 	if ( !( slapMode & SLAP_TOOL_QUICK )) {
@@ -510,6 +517,10 @@ bdb_db_open( BackendDB *be )
 	bdb->bi_flags |= BDB_IS_OPEN;
 
 	return 0;
+
+fail:
+	bdb_db_close( be );
+	return rc;
 }
 
 static int
@@ -520,10 +531,6 @@ bdb_db_close( BackendDB *be )
 	struct bdb_db_info *db;
 	bdb_idl_cache_entry_t *entry, *next_entry;
 
-	/* backend_shutdown closes everything, even if not all were opened */
-	if ( !( bdb->bi_flags & BDB_IS_OPEN ))
-		return 0;
-
 	bdb->bi_flags &= ~BDB_IS_OPEN;
 
 	ber_bvarray_free( bdb->bi_db_config );
@@ -543,7 +550,6 @@ bdb_db_close( BackendDB *be )
 	bdb_cache_release_all (&bdb->bi_cache);
 
 	if ( bdb->bi_idl_cache_max_size ) {
-		ldap_pvt_thread_rdwr_wlock ( &bdb->bi_idl_tree_rwlock );
 		avl_free( bdb->bi_idl_tree, NULL );
 		bdb->bi_idl_tree = NULL;
 		entry = bdb->bi_idl_lru_head;
@@ -556,7 +562,6 @@ bdb_db_close( BackendDB *be )
 			entry = next_entry;
 		}
 		bdb->bi_idl_lru_head = bdb->bi_idl_lru_tail = NULL;
-		ldap_pvt_thread_rdwr_wunlock ( &bdb->bi_idl_tree_rwlock );
 	}
 
 	if ( !( slapMode & SLAP_TOOL_QUICK ) && bdb->bi_dbenv ) {
@@ -636,12 +641,8 @@ bdb_back_initialize(
 		LDAP_CONTROL_MANAGEDSAIT,
 		LDAP_CONTROL_NOOP,
 		LDAP_CONTROL_PAGEDRESULTS,
-#ifdef LDAP_CONTROL_SUBENTRIES
 		LDAP_CONTROL_SUBENTRIES,
-#endif
-#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
 		LDAP_CONTROL_X_PERMISSIVE_MODIFY,
-#endif
 		NULL
 	};
 
diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c
index 3151d3d6aa3f9e8d4e7198d25532dc1b9f392658..e39c23daf936a4b45e73340ca72e600f92e5fb5b 100644
--- a/servers/slapd/back-bdb/search.c
+++ b/servers/slapd/back-bdb/search.c
@@ -858,21 +858,6 @@ fetch_entry_retry:
 
 		if ( rs->sr_err == LDAP_COMPARE_TRUE ) {
 			/* check size limit */
-			if ( --op->ors_slimit == -1 ) {
-#ifdef SLAP_ZONE_ALLOC
-				slap_zn_runlock(bdb->bi_cache.c_zctx, e);
-#endif
-				bdb_cache_return_entry_r( bdb->bi_dbenv,
-						&bdb->bi_cache, e, &lock );
-				e = NULL;
-				rs->sr_entry = NULL;
-				rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
-				rs->sr_ref = rs->sr_v2ref;
-				send_ldap_result( op, rs );
-				rs->sr_err = LDAP_SUCCESS;
-				goto done;
-			}
-
 			if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
 				if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) {
 #ifdef SLAP_ZONE_ALLOC
@@ -889,20 +874,20 @@ fetch_entry_retry:
 
 			if (e) {
 				/* safe default */
-				int result = -1;
 				rs->sr_attrs = op->oq_search.rs_attrs;
 				rs->sr_operational_attrs = NULL;
 				rs->sr_ctrls = NULL;
 				rs->sr_flags = 0;
 				rs->sr_err = LDAP_SUCCESS;
-				result = send_search_entry( op, rs );
+				rs->sr_err = send_search_entry( op, rs );
 
-				switch (result) {
-				case 0:		/* entry sent ok */
+				switch ( rs->sr_err ) {
+				case LDAP_SUCCESS:	/* entry sent ok */
 					break;
-				case 1:		/* entry not sent */
+				default:		/* entry not sent */
 					break;
-				case -1:	/* connection closed */
+				case LDAP_UNAVAILABLE:
+				case LDAP_SIZELIMIT_EXCEEDED:
 #ifdef SLAP_ZONE_ALLOC
 					slap_zn_runlock(bdb->bi_cache.c_zctx, e);
 #endif
@@ -910,7 +895,14 @@ fetch_entry_retry:
 						&bdb->bi_cache, e, &lock);
 					e = NULL;
 					rs->sr_entry = NULL;
-					rs->sr_err = LDAP_OTHER;
+					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;
 				}
 			}
diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c
index 09d25571ae0812c668d661fa39a83299656c7d1f..9c970484852598698839d547f65f08041d0d7f96 100644
--- a/servers/slapd/back-bdb/tools.c
+++ b/servers/slapd/back-bdb/tools.c
@@ -93,7 +93,8 @@ int bdb_tool_entry_open(
 	}
 
 	/* Set up for threaded slapindex */
-	if (( slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY)) == SLAP_TOOL_QUICK) {
+	if (( slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY)) == SLAP_TOOL_QUICK
+		&& bdb->bi_nattrs ) {
 		if ( !bdb_tool_info ) {
 			int i;
 			ldap_pvt_thread_mutex_init( &bdb_tool_index_mutex );
diff --git a/servers/slapd/back-ldap/add.c b/servers/slapd/back-ldap/add.c
index 0c394c36453cedf3646715dbf64ded3c29b9aea4..c15fdd0e9f4bcf187774980bfb3a17c19c0b32af 100644
--- a/servers/slapd/back-ldap/add.c
+++ b/servers/slapd/back-ldap/add.c
@@ -36,9 +36,9 @@ ldap_back_add(
 	Operation	*op,
 	SlapReply	*rs )
 {
-	struct ldapinfo	*li = (struct ldapinfo *)op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
 
-	struct ldapconn	*lc;
+	ldapconn_t	*lc;
 	int		i = 0,
 			j = 0;
 	Attribute	*a;
@@ -103,10 +103,10 @@ retry:
 	rs->sr_err = ldap_add_ext( lc->lc_ld, op->o_req_dn.bv_val, attrs,
 			ctrls, NULL, &msgid );
 	rs->sr_err = ldap_back_op_result( lc, op, rs, msgid,
-		li->timeout[ LDAP_BACK_OP_ADD ], LDAP_BACK_SENDRESULT );
+		li->li_timeout[ LDAP_BACK_OP_ADD ], LDAP_BACK_SENDRESULT );
 	if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
 		do_retry = 0;
-		if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
+		if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 			goto retry;
 		}
 	}
diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h
index f0a4330ac4a1ce1ec9f6d46c7dfc13cccb767520..8ec1a372bc16a9e7e4e5065c4ca4819e57253a2c 100644
--- a/servers/slapd/back-ldap/back-ldap.h
+++ b/servers/slapd/back-ldap/back-ldap.h
@@ -26,7 +26,7 @@
 
 LDAP_BEGIN_DECL
 
-struct ldapconn {
+typedef struct ldapconn_t {
 	Connection		*lc_conn;
 #define	LDAP_BACK_PCONN		((void *)0x0)
 #define	LDAP_BACK_PCONN_TLS	((void *)0x1)
@@ -79,7 +79,7 @@ struct ldapconn {
 
 	unsigned		lc_refcnt;
 	unsigned		lc_flags;
-};
+} ldapconn_t;
 
 /*
  * identity assertion modes
@@ -104,50 +104,58 @@ enum {
 	LDAP_BACK_OP_LAST
 };
 
-struct ldapinfo {
-	char		*url;
-	LDAPURLDesc	*lud;
-
-	slap_bindconf	acl_sb;
-#define	acl_authcID	acl_sb.sb_authcId
-#define	acl_authcDN	acl_sb.sb_binddn
-#define	acl_passwd	acl_sb.sb_cred
-#define	acl_authzID	acl_sb.sb_authzId
-#define	acl_authmethod	acl_sb.sb_method
-#define	acl_sasl_mech	acl_sb.sb_saslmech
-#define	acl_sasl_realm	acl_sb.sb_realm
-#define	acl_secprops	acl_sb.sb_secprops
+typedef struct ldap_avl_info_t {
+	ldap_pvt_thread_mutex_t		lai_mutex;
+	Avlnode				*lai_tree;
+} ldap_avl_info_t;
+
+typedef struct ldapinfo_t {
+	/* li_uri: the string that goes into ldap_initialize()
+	 * TODO: use li_acl.sb_uri instead */
+	char		*li_uri;
+	/* li_bvuri: an array of each single URI that is equivalent;
+	 * to be checked for the presence of a certain item */
+	BerVarray	li_bvuri;
+
+	slap_bindconf	li_acl;
+#define	li_acl_authcID	li_acl.sb_authcId
+#define	li_acl_authcDN	li_acl.sb_binddn
+#define	li_acl_passwd	li_acl.sb_cred
+#define	li_acl_authzID	li_acl.sb_authzId
+#define	li_acl_authmethod	li_acl.sb_method
+#define	li_acl_sasl_mech	li_acl.sb_saslmech
+#define	li_acl_sasl_realm	li_acl.sb_realm
+#define	li_acl_secprops	li_acl.sb_secprops
 
 	/* ID assert stuff */
-	int		idassert_mode;
-
-	slap_bindconf	idassert_sb;
-#define	idassert_authcID	idassert_sb.sb_authcId
-#define	idassert_authcDN	idassert_sb.sb_binddn
-#define	idassert_passwd		idassert_sb.sb_cred
-#define	idassert_authzID	idassert_sb.sb_authzId
-#define	idassert_authmethod	idassert_sb.sb_method
-#define	idassert_sasl_mech	idassert_sb.sb_saslmech
-#define	idassert_sasl_realm	idassert_sb.sb_realm
-#define	idassert_secprops	idassert_sb.sb_secprops
-
-	unsigned 	idassert_flags;
+	int		li_idassert_mode;
+
+	slap_bindconf	li_idassert;
+#define	li_idassert_authcID	li_idassert.sb_authcId
+#define	li_idassert_authcDN	li_idassert.sb_binddn
+#define	li_idassert_passwd	li_idassert.sb_cred
+#define	li_idassert_authzID	li_idassert.sb_authzId
+#define	li_idassert_authmethod	li_idassert.sb_method
+#define	li_idassert_sasl_mech	li_idassert.sb_saslmech
+#define	li_idassert_sasl_realm	li_idassert.sb_realm
+#define	li_idassert_secprops	li_idassert.sb_secprops
+
+	unsigned 	li_idassert_flags;
 #define LDAP_BACK_AUTH_NONE		0x00U
 #define	LDAP_BACK_AUTH_NATIVE_AUTHZ	0x01U
 #define	LDAP_BACK_AUTH_OVERRIDE		0x02U
 #define	LDAP_BACK_AUTH_PRESCRIPTIVE	0x04U
 
-	BerVarray	idassert_authz;
+	BerVarray	li_idassert_authz;
 	/* end of ID assert stuff */
 
-	int		nretries;
+	int		li_nretries;
 #define LDAP_BACK_RETRY_UNDEFINED	(-2)
 #define LDAP_BACK_RETRY_FOREVER		(-1)
 #define LDAP_BACK_RETRY_NEVER		(0)
 #define LDAP_BACK_RETRY_DEFAULT		(3)
 
-	ldap_pvt_thread_mutex_t		conn_mutex;
-	unsigned	flags;
+	unsigned	li_flags;
 #define LDAP_BACK_F_NONE		0x00U
 #define LDAP_BACK_F_SAVECRED		0x01U
 #define LDAP_BACK_F_USE_TLS		0x02U
@@ -163,23 +171,20 @@ struct ldapinfo {
 #define	LDAP_BACK_F_SUPPORT_T_F_DISCOVER	0x40U
 #define	LDAP_BACK_F_SUPPORT_T_F_MASK		(LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER)
 
-#define LDAP_BACK_SAVECRED(li)		( (li)->flags & LDAP_BACK_F_SAVECRED )
-#define LDAP_BACK_USE_TLS(li)		( (li)->flags & LDAP_BACK_F_USE_TLS )
-#define LDAP_BACK_PROPAGATE_TLS(li)	( (li)->flags & LDAP_BACK_F_PROPAGATE_TLS )
-#define LDAP_BACK_TLS_CRITICAL(li)	( (li)->flags & LDAP_BACK_F_TLS_CRITICAL )
-#define LDAP_BACK_CHASE_REFERRALS(li)	( (li)->flags & LDAP_BACK_F_CHASE_REFERRALS )
+#define	LDAP_BACK_ISSET(li,f)		( ( (li)->li_flags & (f) ) == (f) )
+#define LDAP_BACK_SAVECRED(li)		LDAP_BACK_ISSET( (li), LDAP_BACK_F_SAVECRED )
+#define LDAP_BACK_USE_TLS(li)		LDAP_BACK_ISSET( (li), LDAP_BACK_F_USE_TLS )
+#define LDAP_BACK_PROPAGATE_TLS(li)	LDAP_BACK_ISSET( (li), LDAP_BACK_F_PROPAGATE_TLS )
+#define LDAP_BACK_TLS_CRITICAL(li)	LDAP_BACK_ISSET( (li), LDAP_BACK_F_TLS_CRITICAL )
+#define LDAP_BACK_CHASE_REFERRALS(li)	LDAP_BACK_ISSET( (li), LDAP_BACK_F_CHASE_REFERRALS )
+#define LDAP_BACK_PROXY_WHOAMI(li)	LDAP_BACK_ISSET( (li), LDAP_BACK_F_PROXY_WHOAMI )
 
-	int		version;
+	int		li_version;
 
-	Avlnode		*conntree;
+	ldap_avl_info_t	li_conninfo;
 
-#if 0
-	/* FIXME: automatic rwm instantiation removed */
-	int		rwm_started;
-#endif
-
-	time_t			timeout[ LDAP_BACK_OP_LAST ];
-};
+	time_t		li_timeout[ LDAP_BACK_OP_LAST ];
+} ldapinfo_t;
 
 typedef enum ldap_back_send_t {
 	LDAP_BACK_DONTSEND		= 0x00,
diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c
index a77af50c9f05e9250d77d93d56cc98e3663bbeb9..6d7899e44dde4efe40c57c67cd7012e1cecc03ac 100644
--- a/servers/slapd/back-ldap/bind.c
+++ b/servers/slapd/back-ldap/bind.c
@@ -42,16 +42,16 @@ static LDAP_REBIND_PROC	ldap_back_default_rebind;
 LDAP_REBIND_PROC	*ldap_back_rebind_f = ldap_back_default_rebind;
 
 static int
-ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs );
+ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs );
 
 static int
-ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok );
+ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok );
 
 int
 ldap_back_bind( Operation *op, SlapReply *rs )
 {
-	struct ldapinfo	*li = (struct ldapinfo *) op->o_bd->be_private;
-	struct ldapconn *lc;
+	ldapinfo_t	*li = (ldapinfo_t *) op->o_bd->be_private;
+	ldapconn_t	*lc;
 
 	int rc = 0;
 	ber_int_t msgid;
@@ -79,7 +79,7 @@ ldap_back_bind( Operation *op, SlapReply *rs )
 		 * purpose, a successful bind is followed by a
 		 * bind with the configured identity assertion */
 		/* NOTE: use with care */
-		if ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
+		if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
 			ldap_back_proxy_authz_bind( lc, op, rs );
 			if ( !LDAP_BACK_CONN_ISBOUND( lc ) ) {
 				rc = 1;
@@ -109,22 +109,22 @@ done:;
 
 		/* wait for all other ops to release the connection */
 retry_lock:;
-		ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+		ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
 		if ( lc->lc_refcnt > 1 ) {
-			ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+			ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
 			ldap_pvt_thread_yield();
 			goto retry_lock;
 		}
 
 		assert( lc->lc_refcnt == 1 );
-		lc = avl_delete( &li->conntree, (caddr_t)lc,
+		lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc,
 				ldap_back_conn_cmp );
 		assert( lc != NULL );
 
 		ber_bvreplace( &lc->lc_local_ndn, &op->o_req_ndn );
-		lerr = avl_insert( &li->conntree, (caddr_t)lc,
+		lerr = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc,
 			ldap_back_conn_cmp, ldap_back_conn_dup );
-		ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+		ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
 		if ( lerr == -1 ) {
 			/* we can do this because lc_refcnt == 1 */
 			ldap_back_conn_free( lc );
@@ -142,14 +142,14 @@ retry_lock:;
 /*
  * ldap_back_conn_cmp
  *
- * compares two struct ldapconn based on the value of the conn pointer;
+ * compares two ldapconn_t based on the value of the conn pointer;
  * used by avl stuff
  */
 int
 ldap_back_conn_cmp( const void *c1, const void *c2 )
 {
-	const struct ldapconn *lc1 = (const struct ldapconn *)c1;
-	const struct ldapconn *lc2 = (const struct ldapconn *)c2;
+	const ldapconn_t	*lc1 = (const ldapconn_t *)c1;
+	const ldapconn_t	*lc2 = (const ldapconn_t *)c2;
 	int rc;
 
 	/* If local DNs don't match, it is definitely not a match */
@@ -167,14 +167,14 @@ ldap_back_conn_cmp( const void *c1, const void *c2 )
 /*
  * ldap_back_conn_dup
  *
- * returns -1 in case a duplicate struct ldapconn has been inserted;
+ * returns -1 in case a duplicate ldapconn_t has been inserted;
  * used by avl stuff
  */
 int
 ldap_back_conn_dup( void *c1, void *c2 )
 {
-	struct ldapconn *lc1 = (struct ldapconn *)c1;
-	struct ldapconn *lc2 = (struct ldapconn *)c2;
+	ldapconn_t	*lc1 = (ldapconn_t *)c1;
+	ldapconn_t	*lc2 = (ldapconn_t *)c2;
 
 	/* Cannot have more than one shared session with same DN */
 	if ( dn_match( &lc1->lc_local_ndn, &lc2->lc_local_ndn ) &&
@@ -190,8 +190,8 @@ ldap_back_conn_dup( void *c1, void *c2 )
 static void
 ravl_print( Avlnode *root, int depth )
 {
-	int     i;
-	struct ldapconn *lc;
+	int		i;
+	ldapconn_t	*lc;
 	
 	if ( root == 0 ) {
 		return;
@@ -227,22 +227,26 @@ myprint( Avlnode *root )
 #endif /* PRINT_CONNTREE */
 
 int
-ldap_back_freeconn( Operation *op, struct ldapconn *lc )
+ldap_back_freeconn( Operation *op, ldapconn_t *lc, int dolock )
 {
-	struct ldapinfo	*li = (struct ldapinfo *) op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *) op->o_bd->be_private;
 
-	ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+	if ( dolock ) {
+		ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
+	}
 
 	assert( lc->lc_refcnt > 0 );
 	if ( --lc->lc_refcnt == 0 ) {
-		lc = avl_delete( &li->conntree, (caddr_t)lc,
+		lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc,
 				ldap_back_conn_cmp );
 		assert( lc != NULL );
 
 		ldap_back_conn_free( (void *)lc );
 	}
 
-	ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+	if ( dolock ) {
+		ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
+	}
 
 	return 0;
 }
@@ -259,10 +263,10 @@ ldap_back_start_tls(
 	const char	**text )
 {
 	int		rc = LDAP_SUCCESS;
-	struct ldapinfo	dummy;
+	ldapinfo_t	dummy;
 
 	/* this is ridiculous... */
-	dummy.flags = flags;
+	dummy.li_flags = flags;
 
 	/* start TLS ("tls-[try-]{start,propagate}" statements) */
 	if ( ( LDAP_BACK_USE_TLS( &dummy ) || ( *is_tls && LDAP_BACK_PROPAGATE_TLS( &dummy ) ) )
@@ -392,9 +396,9 @@ retry:;
 #endif /* HAVE_TLS */
 
 static int
-ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
+ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 {
-	struct ldapinfo	*li = (struct ldapinfo *)op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
 	int		vers = op->o_protocol;
 	LDAP		*ld = NULL;
 #ifdef HAVE_TLS
@@ -403,7 +407,7 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda
 
 	assert( lcp != NULL );
 
-	rs->sr_err = ldap_initialize( &ld, li->url );
+	rs->sr_err = ldap_initialize( &ld, li->li_uri );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		goto error_return;
 	}
@@ -420,7 +424,7 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda
 
 #ifdef HAVE_TLS
 	rs->sr_err = ldap_back_start_tls( ld, op->o_protocol, &is_tls,
-			li->url, li->flags, li->nretries, &rs->sr_text );
+			li->li_uri, li->li_flags, li->li_nretries, &rs->sr_text );
 	if ( rs->sr_err != LDAP_SUCCESS ) {
 		ldap_unbind_ext( ld, NULL, NULL );
 		goto error_return;
@@ -428,8 +432,8 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda
 #endif /* HAVE_TLS */
 
 	if ( *lcp == NULL ) {
-		*lcp = (struct ldapconn *)ch_calloc( 1, sizeof( struct ldapconn ) );
-		(*lcp)->lc_flags= li->flags;
+		*lcp = (ldapconn_t *)ch_calloc( 1, sizeof( ldapconn_t ) );
+		(*lcp)->lc_flags= li->li_flags;
 	}
 	(*lcp)->lc_ld = ld;
 	(*lcp)->lc_refcnt = 1;
@@ -456,11 +460,11 @@ error_return:;
 	return rs->sr_err;
 }
 
-struct ldapconn *
+ldapconn_t *
 ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 {
-	struct ldapinfo	*li = (struct ldapinfo *)op->o_bd->be_private;
-	struct ldapconn	*lc,
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
+	ldapconn_t	*lc,
 			lc_curr = { 0 };
 	int		refcnt = 1;
 
@@ -482,14 +486,14 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 	}
 
 	/* Searches for a ldapconn in the avl tree */
-	ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+	ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
 
-	lc = (struct ldapconn *)avl_find( li->conntree, 
+	lc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree, 
 			(caddr_t)&lc_curr, ldap_back_conn_cmp );
 	if ( lc != NULL ) {
 		refcnt = ++lc->lc_refcnt;
 	}
-	ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+	ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
 
 	/* Looks like we didn't get a bind. Open a new session... */
 	if ( lc == NULL ) {
@@ -501,8 +505,8 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 		ber_dupbv( &lc->lc_local_ndn, &lc_curr.lc_local_ndn );
 
 		if ( LDAP_BACK_CONN_ISPRIV( &lc_curr ) ) {
-			ber_dupbv( &lc->lc_cred, &li->acl_passwd );
-			ber_dupbv( &lc->lc_bound_ndn, &li->acl_authcDN );
+			ber_dupbv( &lc->lc_cred, &li->li_acl_passwd );
+			ber_dupbv( &lc->lc_bound_ndn, &li->li_acl_authcDN );
 			LDAP_BACK_CONN_ISPRIV_SET( lc );
 
 		} else {
@@ -527,18 +531,18 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 		if ( lc->lc_conn == LDAP_BACK_PCONN_TLS
 				&& !ldap_tls_inplace( lc->lc_ld ) )
 		{
-			struct ldapconn *tmplc;
+			ldapconn_t *tmplc;
 			
 			lc_curr.lc_conn = LDAP_BACK_PCONN;
-			ldap_pvt_thread_mutex_lock( &li->conn_mutex );
-			tmplc = (struct ldapconn *)avl_find( li->conntree, 
+			ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
+			tmplc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree, 
 					(caddr_t)&lc_curr, ldap_back_conn_cmp );
 			if ( tmplc != NULL ) {
 				refcnt = ++tmplc->lc_refcnt;
 				ldap_back_conn_free( lc );
 				lc = tmplc;
 			}
-			ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+			ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
 
 			if ( tmplc != NULL ) {
 				goto done;
@@ -549,17 +553,17 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 		LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
 
 		/* Inserts the newly created ldapconn in the avl tree */
-		ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+		ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
 
 		assert( lc->lc_refcnt == 1 );
-		rs->sr_err = avl_insert( &li->conntree, (caddr_t)lc,
+		rs->sr_err = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc,
 			ldap_back_conn_cmp, ldap_back_conn_dup );
 
 #if PRINT_CONNTREE > 0
-		myprint( li->conntree );
+		myprint( li->li_conninfo.lai_tree );
 #endif /* PRINT_CONNTREE */
 	
-		ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+		ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
 
 		Debug( LDAP_DEBUG_TRACE,
 			"=>ldap_back_getconn: conn %p inserted (refcnt=%u)\n",
@@ -590,14 +594,14 @@ void
 ldap_back_release_conn(
 	Operation		*op,
 	SlapReply		*rs,
-	struct ldapconn		*lc )
+	ldapconn_t		*lc )
 {
-	struct ldapinfo	*li = (struct ldapinfo *)op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
 
-	ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+	ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
 	assert( lc->lc_refcnt > 0 );
 	lc->lc_refcnt--;
-	ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+	ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
 }
 
 /*
@@ -607,18 +611,18 @@ ldap_back_release_conn(
  * it from all the callers, and I made the function return the flag, so
  * it can be used to simplify the check.
  *
- * Note: dolock indicates whether li->conn_mutex must be locked or not
+ * Note: dolock indicates whether li->li_conninfo.lai_mutex must be locked or not
  */
 static int
 ldap_back_dobind_int(
-	struct ldapconn		*lc,
+	ldapconn_t		*lc,
 	Operation		*op,
 	SlapReply		*rs,
 	ldap_back_send_t	sendok,
 	int			retries,
 	int			dolock )
 {	
-	struct ldapinfo	*li = (struct ldapinfo *)op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
 
 	int		rc = LDAP_BACK_CONN_ISBOUND( lc );
 	ber_int_t	msgid;
@@ -654,7 +658,7 @@ ldap_back_dobind_int(
 	if ( op->o_conn != NULL &&
 			!op->o_do_not_cache &&
 			( BER_BVISNULL( &lc->lc_bound_ndn ) ||
-			  ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
+			  ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
 	{
 		(void)ldap_back_proxy_authz_bind( lc, op, rs );
 		goto done;
@@ -662,32 +666,32 @@ ldap_back_dobind_int(
 
 #ifdef HAVE_CYRUS_SASL
 	if ( LDAP_BACK_CONN_ISPRIV( lc )
-		&& li->acl_authmethod == LDAP_AUTH_SASL )
+		&& li->li_acl_authmethod == LDAP_AUTH_SASL )
 	{
 		void		*defaults = NULL;
 
-		if ( li->acl_secprops != NULL ) {
+		if ( li->li_acl_secprops != NULL ) {
 			rc = ldap_set_option( lc->lc_ld,
-				LDAP_OPT_X_SASL_SECPROPS, li->acl_secprops);
+				LDAP_OPT_X_SASL_SECPROPS, li->li_acl_secprops);
 
 			if ( rc != LDAP_OPT_SUCCESS ) {
 				Debug( LDAP_DEBUG_ANY, "Error: ldap_set_option "
 					"(%s,SECPROPS,\"%s\") failed!\n",
-					li->url, li->acl_secprops, 0 );
+					li->li_uri, li->li_acl_secprops, 0 );
 				goto done;
 			}
 		}
 
 		defaults = lutil_sasl_defaults( lc->lc_ld,
-				li->acl_sasl_mech.bv_val,
-				li->acl_sasl_realm.bv_val,
-				li->acl_authcID.bv_val,
-				li->acl_passwd.bv_val,
+				li->li_acl_sasl_mech.bv_val,
+				li->li_acl_sasl_realm.bv_val,
+				li->li_acl_authcID.bv_val,
+				li->li_acl_passwd.bv_val,
 				NULL );
 
 		rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld,
-				li->acl_authcDN.bv_val,
-				li->acl_sasl_mech.bv_val, NULL, NULL,
+				li->li_acl_authcDN.bv_val,
+				li->li_acl_sasl_mech.bv_val, NULL, NULL,
 				LDAP_SASL_QUIET, lutil_sasl_interact,
 				defaults );
 
@@ -714,7 +718,7 @@ retry:;
 	if ( rs->sr_err == LDAP_SERVER_DOWN ) {
 		if ( retries != LDAP_BACK_RETRY_NEVER ) {
 			if ( dolock ) {
-				ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+				ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
 			}
 
 			assert( lc->lc_refcnt > 0 );
@@ -726,7 +730,7 @@ retry:;
 				rs->sr_err = ldap_back_prepare_conn( &lc, op, rs, sendok );
 			}
 			if ( dolock ) {
-				ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+				ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
 			}
 			if ( rs->sr_err == LDAP_SUCCESS ) {
 				if ( retries > 0 ) {
@@ -736,7 +740,7 @@ retry:;
 			}
 		}
 
-		ldap_back_freeconn( op, lc );
+		ldap_back_freeconn( op, lc, dolock );
 		rs->sr_err = slap_map_api2result( rs );
 
 		return 0;
@@ -757,11 +761,11 @@ done:;
 }
 
 int
-ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
+ldap_back_dobind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 {
-	struct ldapinfo	*li = (struct ldapinfo *)op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
 
-	return ldap_back_dobind_int( lc, op, rs, sendok, li->nretries, 1 );
+	return ldap_back_dobind_int( lc, op, rs, sendok, li->li_nretries, 1 );
 }
 
 /*
@@ -774,7 +778,7 @@ static int
 ldap_back_default_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
 	ber_int_t msgid, void *params )
 {
-	struct ldapconn *lc = (struct ldapconn *)params;
+	ldapconn_t	*lc = (ldapconn_t *)params;
 
 #ifdef HAVE_TLS
 	/* ... otherwise we couldn't get here */
@@ -801,7 +805,7 @@ ldap_back_default_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
 
 int
 ldap_back_op_result(
-		struct ldapconn		*lc,
+		ldapconn_t		*lc,
 		Operation		*op,
 		SlapReply		*rs,
 		ber_int_t		msgid,
@@ -862,6 +866,16 @@ retry:;
 		default:
 			rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
 					&match, &text, NULL, NULL, 1 );
+#ifndef LDAP_NULL_IS_NULL
+			if ( match != NULL && match[ 0 ] == '\0' ) {
+				ldap_memfree( match );
+				match = NULL;
+			}
+			if ( text != NULL && text[ 0 ] == '\0' ) {
+				ldap_memfree( text );
+				text = NULL;
+			}
+#endif /* LDAP_NULL_IS_NULL */
 			rs->sr_text = text;
 			if ( rc != LDAP_SUCCESS ) {
 				rs->sr_err = rc;
@@ -906,40 +920,43 @@ retry:;
 
 /* return true if bound, false if failed */
 int
-ldap_back_retry( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
+ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 {
 	int		rc = 0;
-	struct ldapinfo	*li = (struct ldapinfo *)op->o_bd->be_private;
-	
-	ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
+
+	ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
 
-	if ( lc->lc_refcnt == 1 ) {
+	if ( (*lcp)->lc_refcnt == 1 ) {
 		Debug( LDAP_DEBUG_ANY,
 			"%s ldap_back_retry: retrying URI=\"%s\" DN=\"%s\"\n",
-			op->o_log_prefix, li->url,
-			BER_BVISNULL( &lc->lc_bound_ndn ) ?
-				"" : lc->lc_bound_ndn.bv_val );
+			op->o_log_prefix, li->li_uri,
+			BER_BVISNULL( &(*lcp)->lc_bound_ndn ) ?
+				"" : (*lcp)->lc_bound_ndn.bv_val );
 
-		ldap_unbind_ext( lc->lc_ld, NULL, NULL );
-		lc->lc_ld = NULL;
-		LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
+		ldap_unbind_ext( (*lcp)->lc_ld, NULL, NULL );
+		(*lcp)->lc_ld = NULL;
+		LDAP_BACK_CONN_ISBOUND_CLEAR( (*lcp) );
 
 		/* lc here must be the regular lc, reset and ready for init */
-		rc = ldap_back_prepare_conn( &lc, op, rs, sendok );
+		rc = ldap_back_prepare_conn( lcp, op, rs, sendok );
 		if ( rc == LDAP_SUCCESS ) {
-			rc = ldap_back_dobind_int( lc, op, rs, sendok, 0, 0 );
+			rc = ldap_back_dobind_int( *lcp, op, rs, sendok, 0, 0 );
+			if ( rc == 0 ) {
+				*lcp = NULL;
+			}
 		}
 	}
 
-	ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+	ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
 
 	return rc;
 }
 
 static int
-ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
+ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs )
 {
-	struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
 	struct berval	binddn = slap_empty_bv;
 	struct berval	bindcred = slap_empty_bv;
 	int		dobind = 0;
@@ -969,13 +986,13 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
 	/* bind as proxyauthzdn only if no idassert mode
 	 * is requested, or if the client's identity
 	 * is authorized */
-	switch ( li->idassert_mode ) {
+	switch ( li->li_idassert_mode ) {
 	case LDAP_BACK_IDASSERT_LEGACY:
 		if ( !BER_BVISNULL( &op->o_conn->c_ndn ) && !BER_BVISEMPTY( &op->o_conn->c_ndn ) ) {
-			if ( !BER_BVISNULL( &li->idassert_authcDN ) && !BER_BVISEMPTY( &li->idassert_authcDN ) )
+			if ( !BER_BVISNULL( &li->li_idassert_authcDN ) && !BER_BVISEMPTY( &li->li_idassert_authcDN ) )
 			{
-				binddn = li->idassert_authcDN;
-				bindcred = li->idassert_passwd;
+				binddn = li->li_idassert_authcDN;
+				bindcred = li->li_idassert_passwd;
 				dobind = 1;
 			}
 		}
@@ -983,7 +1000,7 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
 
 	default:
 		/* NOTE: rootdn can always idassert */
-		if ( li->idassert_authz && !be_isroot( op ) ) {
+		if ( li->li_idassert_authz && !be_isroot( op ) ) {
 			struct berval authcDN;
 
 			if ( BER_BVISNULL( &op->o_conn->c_ndn ) ) {
@@ -992,10 +1009,10 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
 			} else {
 				authcDN = op->o_conn->c_ndn;
 			}	
-			rs->sr_err = slap_sasl_matches( op, li->idassert_authz,
+			rs->sr_err = slap_sasl_matches( op, li->li_idassert_authz,
 					&authcDN, &authcDN );
 			if ( rs->sr_err != LDAP_SUCCESS ) {
-				if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
+				if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
 					send_ldap_result( op, rs );
 					LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
 
@@ -1010,13 +1027,13 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
 			}
 		}
 
-		binddn = li->idassert_authcDN;
-		bindcred = li->idassert_passwd;
+		binddn = li->li_idassert_authcDN;
+		bindcred = li->li_idassert_passwd;
 		dobind = 1;
 		break;
 	}
 
-	if ( dobind && li->idassert_authmethod == LDAP_AUTH_SASL ) {
+	if ( dobind && li->li_idassert_authmethod == LDAP_AUTH_SASL ) {
 #ifdef HAVE_CYRUS_SASL
 		void		*defaults = NULL;
 		struct berval	authzID = BER_BVNULL;
@@ -1024,12 +1041,12 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
 
 		/* if SASL supports native authz, prepare for it */
 		if ( ( !op->o_do_not_cache || !op->o_is_auth_check ) &&
-				( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) )
+				( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) )
 		{
-			switch ( li->idassert_mode ) {
+			switch ( li->li_idassert_mode ) {
 			case LDAP_BACK_IDASSERT_OTHERID:
 			case LDAP_BACK_IDASSERT_OTHERDN:
-				authzID = li->idassert_authzID;
+				authzID = li->li_idassert_authzID;
 				break;
 
 			case LDAP_BACK_IDASSERT_ANONYMOUS:
@@ -1055,10 +1072,10 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
 			}
 		}
 
-		if ( li->idassert_secprops != NULL ) {
+		if ( li->li_idassert_secprops != NULL ) {
 			rs->sr_err = ldap_set_option( lc->lc_ld,
 				LDAP_OPT_X_SASL_SECPROPS,
-				(void *)li->idassert_secprops );
+				(void *)li->li_idassert_secprops );
 
 			if ( rs->sr_err != LDAP_OPT_SUCCESS ) {
 				send_ldap_result( op, rs );
@@ -1068,14 +1085,14 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
 		}
 
 		defaults = lutil_sasl_defaults( lc->lc_ld,
-				li->idassert_sasl_mech.bv_val,
-				li->idassert_sasl_realm.bv_val,
-				li->idassert_authcID.bv_val,
-				li->idassert_passwd.bv_val,
+				li->li_idassert_sasl_mech.bv_val,
+				li->li_idassert_sasl_realm.bv_val,
+				li->li_idassert_authcID.bv_val,
+				li->li_idassert_passwd.bv_val,
 				authzID.bv_val );
 
 		rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld, binddn.bv_val,
-				li->idassert_sasl_mech.bv_val, NULL, NULL,
+				li->li_idassert_sasl_mech.bv_val, NULL, NULL,
 				LDAP_SASL_QUIET, lutil_sasl_interact,
 				defaults );
 
@@ -1097,7 +1114,7 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
 #endif /* HAVE_CYRUS_SASL */
 	}
 
-	switch ( li->idassert_authmethod ) {
+	switch ( li->li_idassert_authmethod ) {
 	case LDAP_AUTH_NONE:
 		LDAP_BACK_CONN_ISBOUND_SET( lc );
 		goto done;
@@ -1152,12 +1169,12 @@ done:;
  */
 int
 ldap_back_proxy_authz_ctrl(
-		struct ldapconn	*lc,
+		ldapconn_t	*lc,
 		Operation	*op,
 		SlapReply	*rs,
 		LDAPControl	***pctrls )
 {
-	struct ldapinfo	*li = (struct ldapinfo *) op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *) op->o_bd->be_private;
 	LDAPControl	**ctrls = NULL;
 	int		i = 0,
 			mode;
@@ -1170,8 +1187,8 @@ ldap_back_proxy_authz_ctrl(
 	/* FIXME: SASL/EXTERNAL over ldapi:// doesn't honor the authcID,
 	 * but if it is not set this test fails.  We need a different
 	 * means to detect if idassert is enabled */
-	if ( ( BER_BVISNULL( &li->idassert_authcID ) || BER_BVISEMPTY( &li->idassert_authcID ) )
-			&& ( BER_BVISNULL( &li->idassert_authcDN ) || BER_BVISEMPTY( &li->idassert_authcDN ) ) )
+	if ( ( BER_BVISNULL( &li->li_idassert_authcID ) || BER_BVISEMPTY( &li->li_idassert_authcID ) )
+			&& ( BER_BVISNULL( &li->li_idassert_authcDN ) || BER_BVISEMPTY( &li->li_idassert_authcDN ) ) )
 	{
 		goto done;
 	}
@@ -1180,7 +1197,7 @@ ldap_back_proxy_authz_ctrl(
 		goto done;
 	}
 
-	if ( li->idassert_mode == LDAP_BACK_IDASSERT_LEGACY ) {
+	if ( li->li_idassert_mode == LDAP_BACK_IDASSERT_LEGACY ) {
 		if ( op->o_proxy_authz ) {
 			/*
 			 * FIXME: we do not want to perform proxyAuthz
@@ -1207,12 +1224,12 @@ ldap_back_proxy_authz_ctrl(
 			goto done;
 		}
 
-		if ( BER_BVISNULL( &li->idassert_authcDN ) ) {
+		if ( BER_BVISNULL( &li->li_idassert_authcDN ) ) {
 			goto done;
 		}
 
-	} else if ( li->idassert_authmethod == LDAP_AUTH_SASL ) {
-		if ( ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ )
+	} else if ( li->li_idassert_authmethod == LDAP_AUTH_SASL ) {
+		if ( ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ )
 				/* && ( !BER_BVISNULL( &op->o_conn->c_ndn )
 					|| LDAP_BACK_CONN_ISBOUND( lc ) ) */ )
 		{
@@ -1223,7 +1240,7 @@ ldap_back_proxy_authz_ctrl(
 			goto done;
 		}
 
-	} else if ( li->idassert_authz && !be_isroot( op ) ) {
+	} else if ( li->li_idassert_authz && !be_isroot( op ) ) {
 		int		rc;
 		struct berval authcDN;
 
@@ -1232,10 +1249,10 @@ ldap_back_proxy_authz_ctrl(
 		} else {
 			authcDN = op->o_conn->c_ndn;
 		}
-		rc = slap_sasl_matches( op, li->idassert_authz,
+		rc = slap_sasl_matches( op, li->li_idassert_authz,
 				&authcDN, & authcDN );
 		if ( rc != LDAP_SUCCESS ) {
-			if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE )
+			if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE )
 			{
 				/* op->o_conn->c_ndn is not authorized
 				 * to use idassert */
@@ -1271,7 +1288,7 @@ ldap_back_proxy_authz_ctrl(
 		mode = LDAP_BACK_IDASSERT_NOASSERT;
 
 	} else {
-		mode = li->idassert_mode;
+		mode = li->li_idassert_mode;
 	}
 
 	switch ( mode ) {
@@ -1298,7 +1315,7 @@ ldap_back_proxy_authz_ctrl(
 	case LDAP_BACK_IDASSERT_OTHERID:
 	case LDAP_BACK_IDASSERT_OTHERDN:
 		/* assert idassert DN */
-		assertedID = li->idassert_authzID;
+		assertedID = li->li_idassert_authzID;
 		break;
 
 	default:
@@ -1320,7 +1337,7 @@ ldap_back_proxy_authz_ctrl(
 	ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
 	ctrls[ 0 ]->ldctl_iscritical = 1;
 
-	switch ( li->idassert_mode ) {
+	switch ( li->li_idassert_mode ) {
 	/* already in u:ID or dn:DN form */
 	case LDAP_BACK_IDASSERT_OTHERID:
 	case LDAP_BACK_IDASSERT_OTHERDN:
diff --git a/servers/slapd/back-ldap/chain.c b/servers/slapd/back-ldap/chain.c
index 3a582883c3a135fb543c229fda116894f4387269..f42beab8d5dc7fa365ce9298047307491c2566eb 100644
--- a/servers/slapd/back-ldap/chain.c
+++ b/servers/slapd/back-ldap/chain.c
@@ -17,6 +17,7 @@
 /* ACKNOWLEDGEMENTS:
  * This work was initially developed by the Howard Chu for inclusion
  * in OpenLDAP Software.
+ * This work was subsequently modified by Pierangelo Masarati.
  */
 
 #include "portable.h"
@@ -64,12 +65,35 @@ static int		sc_chainingBehavior;
 static BackendInfo	*lback;
 
 typedef struct ldap_chain_t {
-	struct ldapinfo		*lc_li;
+	/*
+	 * A "template" ldapinfo_t gets all common configuration items;
+	 * then, for each configured URI, an entry is created in the tree;
+	 * all the specific configuration items get in the current URI 
+	 * structure.
+	 *
+ 	 * Then, for each referral, extract the URI and lookup the
+	 * related structure.  If configured to do so, allow URIs
+	 * not found in the structure to create a temporary one
+	 * that chains anonymously; maybe it can also be added to 
+	 * the tree?  Should be all configurable.
+	 */
+
+	/* "common" configuration info (all occurring before an "uri") */
+	ldapinfo_t		*lc_common_li;
+
+	/* current configuration info */
+	ldapinfo_t		*lc_cfg_li;
+
+	/* tree of configured[/generated?] "uri" info */
+	ldap_avl_info_t		lc_lai;
+
 	unsigned		lc_flags;
-#define LDAP_CHAIN_F_NONE		0x00U
-#define	LDAP_CHAIN_F_CHAINING		0x01U
+#define LDAP_CHAIN_F_NONE		(0x00U)
+#define	LDAP_CHAIN_F_CHAINING		(0x01U)
+#define	LDAP_CHAIN_F_CACHE_URI		(0x10U)
 
-	ldap_pvt_thread_mutex_t	lc_mutex;
+#define	LDAP_CHAIN_CHAINING( lc )	( ( (lc)->lc_flags & LDAP_CHAIN_F_CHAINING ) == LDAP_CHAIN_F_CHAINING )
+#define	LDAP_CHAIN_CACHE_URI( lc )	( ( (lc)->lc_flags & LDAP_CHAIN_F_CACHE_URI ) == LDAP_CHAIN_F_CACHE_URI )
 
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 	LDAPControl		lc_chaining_ctrl;
@@ -77,6 +101,12 @@ typedef struct ldap_chain_t {
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 } ldap_chain_t;
 
+static int ldap_chain_db_init_common( BackendDB	*be );
+static int ldap_chain_db_init_one( BackendDB *be );
+#define	ldap_chain_db_open_one(be)	(lback)->bi_db_open( (be) )
+#define	ldap_chain_db_close_one(be)	(0)
+#define	ldap_chain_db_destroy_one(be)	(lback)->bi_db_destroy( (be) )
+
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 static int
 chaining_control_add(
@@ -90,7 +120,7 @@ chaining_control_add(
 	*oldctrlsp = op->o_ctrls;
 
 	/* default chaining control not defined */
-	if ( !( lc->lc_flags & LDAP_CHAIN_F_CHAINING ) ) {
+	if ( !LDAP_CHAIN_CHAINING( lc ) ) {
 		return 0;
 	}
 
@@ -149,6 +179,46 @@ chaining_control_remove(
 }
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
+static int
+ldap_chain_uri_cmp( const void *c1, const void *c2 )
+{
+	const ldapinfo_t	*li1 = (const ldapinfo_t *)c1;
+	const ldapinfo_t	*li2 = (const ldapinfo_t *)c2;
+
+	assert( li1->li_bvuri != NULL );
+	assert( !BER_BVISNULL( &li1->li_bvuri[ 0 ] ) );
+	assert( BER_BVISNULL( &li1->li_bvuri[ 1 ] ) );
+
+	assert( li2->li_bvuri != NULL );
+	assert( !BER_BVISNULL( &li2->li_bvuri[ 0 ] ) );
+	assert( BER_BVISNULL( &li2->li_bvuri[ 1 ] ) );
+
+	/* If local DNs don't match, it is definitely not a match */
+	return ber_bvcmp( &li1->li_bvuri[ 0 ], &li2->li_bvuri[ 0 ] );
+}
+
+static int
+ldap_chain_uri_dup( void *c1, void *c2 )
+{
+	ldapinfo_t	*li1 = (ldapinfo_t *)c1;
+	ldapinfo_t	*li2 = (ldapinfo_t *)c2;
+
+	assert( li1->li_bvuri != NULL );
+	assert( !BER_BVISNULL( &li1->li_bvuri[ 0 ] ) );
+	assert( BER_BVISNULL( &li1->li_bvuri[ 1 ] ) );
+
+	assert( li2->li_bvuri != NULL );
+	assert( !BER_BVISNULL( &li2->li_bvuri[ 0 ] ) );
+	assert( BER_BVISNULL( &li2->li_bvuri[ 1 ] ) );
+
+	/* Cannot have more than one shared session with same DN */
+	if ( ber_bvcmp( &li1->li_bvuri[ 0 ], &li2->li_bvuri[ 0 ] ) == 0 ) {
+		return -1;
+	}
+		
+	return 0;
+}
+
 static int
 ldap_chain_operational( Operation *op, SlapReply *rs )
 {
@@ -211,7 +281,7 @@ ldap_chain_cb_search_response( Operation *op, SlapReply *rs )
 			switch ( get_continuationBehavior( op ) ) {
 			case SLAP_CH_RESOLVE_CHAINING_REQUIRED:
 				op->o_callback->sc_private = LDAP_CH_ERR;
-				return -1;
+				return rs->sr_err = LDAP_X_CANNOT_CHAIN;
 
 			default:
 				break;
@@ -241,7 +311,36 @@ ldap_chain_cb_response( Operation *op, SlapReply *rs )
 	}
 
 	if ( rs->sr_type == REP_RESULT ) {
-		op->o_callback->sc_private = LDAP_CH_RES;
+		switch ( rs->sr_err ) {
+		case LDAP_COMPARE_TRUE:
+		case LDAP_COMPARE_FALSE:
+			if ( op->o_tag != LDAP_REQ_COMPARE ) {
+				return rs->sr_err;
+			}
+			/* fallthru */
+
+		case LDAP_SUCCESS:
+			op->o_callback->sc_private = LDAP_CH_RES;
+			break;
+
+		case LDAP_REFERRAL:
+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
+			if ( get_chaining( op ) > SLAP_CONTROL_IGNORED ) {
+				switch ( get_continuationBehavior( op ) ) {
+				case SLAP_CH_RESOLVE_CHAINING_REQUIRED:
+					op->o_callback->sc_private = LDAP_CH_ERR;
+					return rs->sr_err = LDAP_X_CANNOT_CHAIN;
+
+				default:
+					break;
+				}
+			}
+#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
+			break;
+
+		default:
+			return rs->sr_err;
+		}
 
 	} else if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH )
 	{
@@ -261,10 +360,8 @@ ldap_chain_op(
 {
 	slap_overinst	*on = (slap_overinst *) op->o_bd->bd_info;
 	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
-
-	struct ldapinfo	*lip = lc->lc_li;
-	char		*save_url = NULL;
-	SlapReply	rs2 = { 0 };
+	ldapinfo_t	li = { 0 }, *lip = NULL;
+	struct berval	bvuri[ 2 ] = { { 0 } };
 
 	/* NOTE: returned if ref is empty... */
 	int		rc = LDAP_OTHER;
@@ -275,27 +372,11 @@ ldap_chain_op(
 	(void)chaining_control_add( lc, op, &ctrls );
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
-	if ( lip->url != NULL ) {
-		op->o_bd->be_private = lip;
-		rc = ( *op_f )( op, &rs2 );
-		rs->sr_err = rs2.sr_err;
-		goto done;
-	}
-
-	save_url = lip->url;
-	lip->url = NULL;
-	op->o_bd->be_private = lip;
-
-	/* if we parse the URI then by no means 
-	 * we can cache stuff or reuse connections, 
-	 * because in back-ldap there's no caching
-	 * based on the URI value, which is supposed
-	 * to be set once for all (correct?) */
-	op->o_do_not_cache = 1;
-
+	li.li_bvuri = bvuri;
 	for ( ; !BER_BVISNULL( ref ); ref++ ) {
 		LDAPURLDesc	*srv;
 		char		*save_dn;
+		int		temporary = 0;
 			
 		/* We're setting the URI of the first referral;
 		 * what if there are more?
@@ -328,30 +409,76 @@ Document: draft-ietf-ldapbis-protocol-27.txt
 		save_dn = srv->lud_dn;
 		srv->lud_dn = "";
 		srv->lud_scope = LDAP_SCOPE_DEFAULT;
-		lip->url = ldap_url_desc2str( srv );
+		li.li_uri = ldap_url_desc2str( srv );
 		srv->lud_dn = save_dn;
 		ldap_free_urldesc( srv );
 
-		if ( lip->url == NULL ) {
+		if ( li.li_uri == NULL ) {
 			/* try next */
 			rc = LDAP_OTHER;
 			continue;
 		}
 
-		rc = ( *op_f )( op, &rs2 );
-		rs->sr_err = rs2.sr_err;
+		ber_str2bv( li.li_uri, 0, 0, &li.li_bvuri[ 0 ] );
+
+		/* Searches for a ldapinfo in the avl tree */
+		ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex );
+		lip = (ldapinfo_t *)avl_find( lc->lc_lai.lai_tree, 
+			(caddr_t)&li, ldap_chain_uri_cmp );
+		ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex );
+
+		if ( lip != NULL ) {
+			op->o_bd->be_private = (void *)lip;
+
+		} else {
+			rc = ldap_chain_db_init_one( op->o_bd );
+			if ( rc != 0 ) {
+				goto cleanup;
+			}
+			lip = (ldapinfo_t *)op->o_bd->be_private;
+			lip->li_uri = li.li_uri;
+			lip->li_bvuri = bvuri;
+			rc = ldap_chain_db_open_one( op->o_bd );
+			if ( rc != 0 ) {
+				(void)ldap_chain_db_destroy_one( op->o_bd );
+				goto cleanup;
+			}
+
+			if ( LDAP_CHAIN_CACHE_URI( lc ) ) {
+				ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex );
+				if ( avl_insert( &lc->lc_lai.lai_tree,
+					(caddr_t)lip, ldap_chain_uri_cmp, ldap_chain_uri_dup ) )
+				{
+					/* someone just inserted another;
+					 * don't bother, use this and then
+					 * just free it */
+					temporary = 1;
+				}
+				ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex );
+
+			} else {
+				temporary = 1;
+			}
+		}
+
+		rc = ( *op_f )( op, rs );
+
+cleanup:;
+		ldap_memfree( li.li_uri );
+		li.li_uri = NULL;
 
-		ldap_memfree( lip->url );
-		lip->url = NULL;
+		if ( temporary ) {
+			lip->li_uri = NULL;
+			lip->li_bvuri = NULL;
+			(void)ldap_chain_db_close_one( op->o_bd );
+			(void)ldap_chain_db_destroy_one( op->o_bd );
+		}
 		
 		if ( rc == LDAP_SUCCESS && rs->sr_err == LDAP_SUCCESS ) {
 			break;
 		}
 	}
 
-	lip->url = save_url;
-
-done:;
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 	(void)chaining_control_remove( op, &ctrls );
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
@@ -367,17 +494,13 @@ ldap_chain_response( Operation *op, SlapReply *rs )
 	slap_callback	*sc = op->o_callback,
 			sc2 = { 0 };
 	int		rc = 0;
-	int		cache = op->o_do_not_cache;
-	char		*matched;
+	const char	*matched;
 	BerVarray	ref;
 	struct berval	ndn = op->o_ndn;
 
-	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
-	struct ldapinfo	*lip = lc->lc_li;
-
-#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 	int		sr_err = rs->sr_err;
 	slap_reply_t	sr_type = rs->sr_type;
+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 	slap_mask_t	chain_mask = 0;
 	ber_len_t	chain_shift = 0;
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
@@ -413,8 +536,6 @@ ldap_chain_response( Operation *op, SlapReply *rs )
 	}
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
-	ldap_pvt_thread_mutex_lock( &lc->lc_mutex );
-
 	/*
 	 * TODO: add checks on who/when chain operations; e.g.:
 	 *   a) what identities are authorized
@@ -455,28 +576,39 @@ ldap_chain_response( Operation *op, SlapReply *rs )
 		op->o_conn = conn;
 		}
 		break;
+
 	case LDAP_REQ_ADD:
 		rc = ldap_chain_op( op, rs, lback->bi_op_add, ref );
 		break;
+
 	case LDAP_REQ_DELETE:
 		rc = ldap_chain_op( op, rs, lback->bi_op_delete, ref );
 		break;
+
 	case LDAP_REQ_MODRDN:
 		rc = ldap_chain_op( op, rs, lback->bi_op_modrdn, ref );
 	    	break;
+
 	case LDAP_REQ_MODIFY:
 		rc = ldap_chain_op( op, rs, lback->bi_op_modify, ref );
 		break;
+
 	case LDAP_REQ_COMPARE:
 		rc = ldap_chain_op( op, rs, lback->bi_op_compare, ref );
+		if ( rs->sr_err == LDAP_COMPARE_TRUE || rs->sr_err == LDAP_COMPARE_FALSE ) {
+			rc = LDAP_SUCCESS;
+		}
 		break;
+
 	case LDAP_REQ_SEARCH:
 		if ( rs->sr_type == REP_SEARCHREF ) {
+			ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
+			ldapinfo_t	li = { 0 }, *lip = NULL;
+			struct berval	bvuri[ 2 ] = { { 0 } };
+
 			struct berval	*curr = ref,
 					odn = op->o_req_dn,
 					ondn = op->o_req_ndn;
-			char		*save_url = NULL;
-			SlapReply	rs2 = { 0 };
 
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 			LDAPControl	**ctrls = NULL;
@@ -488,21 +620,16 @@ ldap_chain_response( Operation *op, SlapReply *rs )
 
 			sc2.sc_response = ldap_chain_cb_search_response;
 
-			save_url = lip->url;
-			lip->url = NULL;
-			op->o_bd->be_private = lip;
-			
 			/* if we parse the URI then by no means 
 			 * we can cache stuff or reuse connections, 
 			 * because in back-ldap there's no caching
 			 * based on the URI value, which is supposed
 			 * to be set once for all (correct?) */
-			op->o_do_not_cache = 1;
-
-			/* copy the private info because we need to modify it */
+			li.li_bvuri = bvuri;
 			for ( ; !BER_BVISNULL( &curr[0] ); curr++ ) {
 				LDAPURLDesc	*srv;
 				char		*save_dn;
+				int		temporary = 0;
 
 				/* parse reference and use
 				 * proto://[host][:port]/ only */
@@ -519,8 +646,8 @@ ldap_chain_response( Operation *op, SlapReply *rs )
 				save_dn = srv->lud_dn;
 				srv->lud_dn = "";
 				srv->lud_scope = LDAP_SCOPE_DEFAULT;
-				lip->url = ldap_url_desc2str( srv );
-				if ( lip->url != NULL ) {
+				li.li_uri = ldap_url_desc2str( srv );
+				if ( li.li_uri != NULL ) {
 					ber_str2bv_x( save_dn, 0, 1, &op->o_req_dn,
 							op->o_tmpmemctx );
 					ber_dupbv_x( &op->o_req_ndn, &op->o_req_dn,
@@ -530,26 +657,75 @@ ldap_chain_response( Operation *op, SlapReply *rs )
 				srv->lud_dn = save_dn;
 				ldap_free_urldesc( srv );
 
-				if ( lip->url == NULL ) {
+				if ( li.li_uri == NULL ) {
 					/* try next */
 					rs->sr_err = LDAP_OTHER;
 					continue;
 				}
 
+				ber_str2bv( li.li_uri, 0, 0, &li.li_bvuri[ 0 ] );
+
+				/* Searches for a ldapinfo in the avl tree */
+				ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex );
+				lip = (ldapinfo_t *)avl_find( lc->lc_lai.lai_tree, 
+					(caddr_t)&li, ldap_chain_uri_cmp );
+				ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex );
+
+				if ( lip != NULL ) {
+					op->o_bd->be_private = (void *)lip;
+
+				} else {
+					/* if none is found, create a temporary... */
+					rc = ldap_chain_db_init_one( op->o_bd );
+					if ( rc != 0 ) {
+						goto cleanup;
+					}
+					lip = (ldapinfo_t *)op->o_bd->be_private;
+					lip->li_uri = li.li_uri;
+					lip->li_bvuri = bvuri;
+					rc = ldap_chain_db_open_one( op->o_bd );
+					if ( rc != 0 ) {
+						(void)ldap_chain_db_destroy_one( op->o_bd );
+						goto cleanup;
+					}
+
+					if ( LDAP_CHAIN_CACHE_URI( lc ) ) {
+						ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex );
+						if ( avl_insert( &lc->lc_lai.lai_tree,
+							(caddr_t)lip, ldap_chain_uri_cmp, ldap_chain_uri_dup ) )
+						{
+							/* someone just inserted another;
+							 * don't bother, use this and then
+							 * just free it */
+							temporary = 1;
+						}
+						ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex );
+		
+					} else {
+						temporary = 1;
+					}
+				}
 
 				/* FIXME: should we also copy filter and scope?
 				 * according to RFC3296, no */
-				rc = lback->bi_op_search( op, &rs2 );
-				rs->sr_err = rs2.sr_err;
+				rc = lback->bi_op_search( op, rs );
 
-				ldap_memfree( lip->url );
-				lip->url = NULL;
+cleanup:;
+				ldap_memfree( li.li_uri );
+				li.li_uri = NULL;
 
 				op->o_tmpfree( op->o_req_dn.bv_val,
 						op->o_tmpmemctx );
 				op->o_tmpfree( op->o_req_ndn.bv_val,
 						op->o_tmpmemctx );
 
+				if ( temporary ) {
+					lip->li_uri = NULL;
+					lip->li_bvuri = NULL;
+					(void)ldap_chain_db_close_one( op->o_bd );
+					(void)ldap_chain_db_destroy_one( op->o_bd );
+				}
+		
 				if ( rc == LDAP_SUCCESS && rs->sr_err == LDAP_SUCCESS ) {
 					break;
 				}
@@ -561,8 +737,6 @@ ldap_chain_response( Operation *op, SlapReply *rs )
 			(void)chaining_control_remove( op, &ctrls );
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
-			lip->url = save_url;
-
 			op->o_req_dn = odn;
 			op->o_req_ndn = ondn;
 			rs->sr_type = REP_SEARCHREF;
@@ -577,24 +751,38 @@ ldap_chain_response( Operation *op, SlapReply *rs )
 			rc = ldap_chain_op( op, rs, lback->bi_op_search, ref );
 		}
 	    	break;
+
 	case LDAP_REQ_EXTENDED:
 		rc = ldap_chain_op( op, rs, lback->bi_extended, ref );
 		/* FIXME: ldap_back_extended() by design 
 		 * doesn't send result; frontend is expected
 		 * to send it... */
+		/* FIXME: what aboit chaining? */
 		if ( rc != SLAPD_ABANDON ) {
 			send_ldap_extended( op, rs );
 			rc = LDAP_SUCCESS;
 		}
+		sc2.sc_private = LDAP_CH_RES;
 		break;
+
 	default:
 		rc = SLAP_CB_CONTINUE;
 		break;
 	}
 
+	switch ( rc ) {
+	case SLAPD_ABANDON:
+		goto dont_chain;
+
+	case LDAP_SUCCESS:
+	case LDAP_REFERRAL:
+		/* slapd-ldap sent response */
+		assert( sc2.sc_private == LDAP_CH_RES );
+		break;
+
+	default:
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-	if ( rc != LDAP_SUCCESS || sc2.sc_private == LDAP_CH_ERR ) {
-		if ( rs->sr_err == LDAP_X_CANNOT_CHAIN ) {
+		if ( sc2.sc_private == LDAP_CH_ERR && rs->sr_err == LDAP_X_CANNOT_CHAIN ) {
 			goto cannot_chain;
 		}
 
@@ -604,35 +792,35 @@ cannot_chain:;
 			op->o_callback = NULL;
 			send_ldap_error( op, rs, LDAP_X_CANNOT_CHAIN,
 				"operation cannot be completed without chaining" );
-			break;
+			goto dont_chain;
 
 		default:
+#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 			rc = SLAP_CB_CONTINUE;
 			rs->sr_err = sr_err;
 			rs->sr_type = sr_type;
+			rs->sr_matched = matched;
+			rs->sr_ref = ref;
+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 			break;
 		}
-		goto dont_chain;
-	}
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
+	}
 
-	if ( sc2.sc_private == LDAP_CH_NONE ) {
+	if ( sc2.sc_private == LDAP_CH_NONE && rc != SLAPD_ABANDON ) {
 		op->o_callback = NULL;
 		rc = rs->sr_err = slap_map_api2result( rs );
 		send_ldap_result( op, rs );
 	}
 
-#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 dont_chain:;
-#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
-	op->o_do_not_cache = cache;
+	rs->sr_err = sr_err;
+	rs->sr_type = sr_type;
+	rs->sr_matched = matched;
+	rs->sr_ref = ref;
 	op->o_bd->be_private = private;
 	op->o_callback = sc;
 	op->o_ndn = ndn;
-	rs->sr_matched = matched;
-	rs->sr_ref = ref;
-
-	ldap_pvt_thread_mutex_unlock( &lc->lc_mutex );
 
 	return rc;
 }
@@ -664,53 +852,179 @@ str2chain( const char *s )
 }
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
+/*
+ * configuration...
+ */
+
 enum {
-	PC_CHAINING = 1
+	CH_CHAINING = 1,
+	CH_CACHE_URI = 2,
+
+	CH_LAST
 };
 
-#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 static ConfigDriver chain_cf_gen;
 static ConfigCfAdd chain_cfadd;
-#endif
 static ConfigLDAPadd chain_ldadd;
 
 static ConfigTable chaincfg[] = {
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 	{ "chain-chaining", "args",
-		2, 4, 0, ARG_MAGIC|ARG_BERVAL|PC_CHAINING, chain_cf_gen,
+		2, 4, 0, ARG_MAGIC|ARG_BERVAL|CH_CHAINING, chain_cf_gen,
 		"( OLcfgOvAt:3.1 NAME 'olcChainingBehavior' "
 			"DESC 'Chaining behavior control parameters (draft-sermersheim-ldap-chaining)' "
 			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
+	{ "chain-cache-uris", "TRUE/FALSE",
+		2, 2, 0, ARG_MAGIC|ARG_ON_OFF|CH_CACHE_URI, chain_cf_gen,
+		"( OLcfgOvAt:3.2 NAME 'olcCacheURIs' "
+			"DESC 'Enables caching of URIs not present in configuration' "
+			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
 	{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
 };
 
 static ConfigOCs chainocs[] = {
-#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 	{ "( OLcfgOvOc:3.1 "
 		"NAME 'olcChainConfig' "
 		"DESC 'Chain configuration' "
 		"SUP olcOverlayConfig "
-		"MAY olcChainingBehavior )", Cft_Overlay, chaincfg, NULL, chain_cfadd },
-#endif
+		"MAY ( "
+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
+			"olcChainingBehavior $ "
+#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
+			"olcCacheURIs "
+			") )",
+		Cft_Overlay, chaincfg, NULL, chain_cfadd },
 	{ "( OLcfgOvOc:3.2 "
 		"NAME 'olcChainDatabase' "
 		"DESC 'Chain remote server configuration' "
-		"AUXILIARY )", Cft_Misc, chaincfg, chain_ldadd },
+		"AUXILIARY )",
+		Cft_Misc, chaincfg, chain_ldadd },
 	{ NULL, 0, NULL }
 };
 
 static int
 chain_ldadd( CfEntryInfo *p, Entry *e, ConfigArgs *ca )
 {
-	if ( p->ce_type != Cft_Overlay || !p->ce_bi ||
-		p->ce_bi->bi_cf_ocs != chainocs )
+	slap_overinst		*on;
+	ldap_chain_t		*lc;
+
+	ldapinfo_t		*li;
+
+	AttributeDescription	*ad = NULL;
+	Attribute		*at;
+	const char		*text;
+
+	int			rc;
+
+	if ( p->ce_type != Cft_Overlay
+		|| !p->ce_bi
+		|| p->ce_bi->bi_cf_ocs != chainocs )
+	{
 		return LDAP_CONSTRAINT_VIOLATION;
+	}
 
-	return LDAP_SUCCESS;
+	on = (slap_overinst *)p->ce_bi;
+	lc = (ldap_chain_t *)on->on_bi.bi_private;
+
+	assert( ca->be == NULL );
+	ca->be = (BackendDB *)ch_calloc( 1, sizeof( BackendDB ) );
+
+	ca->be->bd_info = (BackendInfo *)on;
+
+	rc = slap_str2ad( "olcDbURI", &ad, &text );
+	assert( rc == LDAP_SUCCESS );
+
+	at = attr_find( e->e_attrs, ad );
+	if ( lc->lc_common_li == NULL && at != NULL ) {
+		/* FIXME: we should generate an empty default entry
+		 * if none is supplied */
+		Debug( LDAP_DEBUG_ANY, "slapd-chain: "
+			"first underlying database \"%s\" "
+			"cannot contain attribute \"%s\".\n",
+			e->e_name.bv_val, ad->ad_cname.bv_val, 0 );
+		rc = LDAP_CONSTRAINT_VIOLATION;
+		goto done;
+
+	} else if ( lc->lc_common_li != NULL && at == NULL ) {
+		/* FIXME: we should generate an empty default entry
+		 * if none is supplied */
+		Debug( LDAP_DEBUG_ANY, "slapd-chain: "
+			"subsequent underlying database \"%s\" "
+			"must contain attribute \"%s\".\n",
+			e->e_name.bv_val, ad->ad_cname.bv_val, 0 );
+		rc = LDAP_CONSTRAINT_VIOLATION;
+		goto done;
+	}
+
+	if ( lc->lc_common_li == NULL ) {
+		rc = ldap_chain_db_init_common( ca->be );
+
+	} else {
+		rc = ldap_chain_db_init_one( ca->be );
+	}
+
+	if ( rc != 0 ) {
+		Debug( LDAP_DEBUG_ANY, "slapd-chain: "
+			"unable to init %sunderlying database \"%s\".\n",
+			lc->lc_common_li == NULL ? "common " : "", e->e_name.bv_val, 0 );
+		return LDAP_CONSTRAINT_VIOLATION;
+	}
+
+	li = ca->be->be_private;
+
+	if ( lc->lc_common_li == NULL ) {
+		lc->lc_common_li = li;
+
+	} else if ( avl_insert( &lc->lc_lai.lai_tree, (caddr_t)li,
+		ldap_chain_uri_cmp, ldap_chain_uri_dup ) )
+	{
+		Debug( LDAP_DEBUG_ANY, "slapd-chain: "
+			"database \"%s\" insert failed.\n",
+			e->e_name.bv_val, 0, 0 );
+		rc = LDAP_CONSTRAINT_VIOLATION;
+		goto done;
+	}
+
+done:;
+	if ( rc != LDAP_SUCCESS ) {
+		(void)ldap_chain_db_destroy_one( ca->be );
+		ch_free( ca->be );
+		ca->be = NULL;
+	}
+
+	return rc;
 }
 
-#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
+typedef struct ldap_chain_cfadd_apply_t {
+	Operation	*op;
+	SlapReply	*rs;
+	Entry		*p;
+	ConfigArgs	*ca;
+	int		count;
+} ldap_chain_cfadd_apply_t;
+
+static int
+ldap_chain_cfadd_apply( void *datum, void *arg )
+{
+	ldapinfo_t			*li = (ldapinfo_t *)datum;
+	ldap_chain_cfadd_apply_t	*lca = (ldap_chain_cfadd_apply_t *)arg;
+
+	struct berval			bv;
+
+	/* FIXME: should not hardcode "olcDatabase" here */
+	bv.bv_len = snprintf( lca->ca->msg, sizeof( lca->ca->msg ),
+		"olcDatabase={%d}%s", lca->count, lback->bi_type );
+	bv.bv_val = lca->ca->msg;
+
+	lca->ca->be->be_private = (void *)li;
+	config_build_entry( lca->op, lca->rs, lca->p->e_private, lca->ca,
+		&bv, lback->bi_cf_ocs, &chainocs[1] );
+
+	lca->count++;
+
+	return 0;
+}
 
 static int
 chain_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca )
@@ -719,22 +1033,28 @@ chain_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca )
 	slap_overinst	*on = (slap_overinst *)pe->ce_bi;
 	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
 	void		*priv = (void *)ca->be->be_private;
-	struct berval	bv;
-
-	/* FIXME: should not hardcode "olcDatabase" here */
-	bv.bv_len = sprintf( ca->msg, "olcDatabase=%s", lback->bi_type );
-	bv.bv_val = ca->msg;
 
-	/* We can only create this entry if the database is table-driven */
 	if ( lback->bi_cf_ocs ) {
-		ca->be->be_private = (void *)lc->lc_li;
-		config_build_entry( op, rs, pe, ca, &bv, lback->bi_cf_ocs, &chainocs[1] );
+		ldap_chain_cfadd_apply_t	lca = { 0 };
+
+		lca.op = op;
+		lca.rs = rs;
+		lca.p = p;
+		lca.ca = ca;
+		lca.count = 0;
+
+		(void)ldap_chain_cfadd_apply( (void *)lc->lc_common_li, (void *)&lca );
+
+		(void)avl_apply( lc->lc_lai.lai_tree, ldap_chain_cfadd_apply,
+			&lca, 1, AVL_INORDER );
+
 		ca->be->be_private = priv;
 	}
 
 	return 0;
 }
 
+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 static slap_verbmasks chaining_mode[] = {
 	{ BER_BVC("referralsRequired"),		LDAP_REFERRALS_REQUIRED },
 	{ BER_BVC("referralsPreferred"),	LDAP_REFERRALS_PREFERRED },
@@ -742,25 +1062,24 @@ static slap_verbmasks chaining_mode[] = {
 	{ BER_BVC("chainingPreferred"),		LDAP_CHAINING_PREFERRED },
 	{ BER_BVNULL,				0 }
 };
+#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
 static int
 chain_cf_gen( ConfigArgs *c )
 {
 	slap_overinst	*on = (slap_overinst *)c->bi;
-#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
-#endif
 
 	int		rc = 0;
 
 	if ( c->op == SLAP_CONFIG_EMIT ) {
 		switch( c->type ) {
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-		case PC_CHAINING: {
+		case CH_CHAINING: {
 			struct berval	resolve = BER_BVNULL,
 					continuation = BER_BVNULL;
 
-			if ( !( lc->lc_flags & LDAP_CHAIN_F_CHAINING ) ) {
+			if ( !LDAP_CHAIN_CHAINING( lc ) ) {
 				return 1;
 			}
 
@@ -787,6 +1106,10 @@ chain_cf_gen( ConfigArgs *c )
 		}
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
+		case CH_CACHE_URI:
+			c->value_int = LDAP_CHAIN_CACHE_URI( lc );
+			break;
+
 		default:
 			assert( 0 );
 			rc = 1;
@@ -794,19 +1117,23 @@ chain_cf_gen( ConfigArgs *c )
 		return rc;
 
 	} else if ( c->op == LDAP_MOD_DELETE ) {
-		return 1;	/* FIXME */
-#if 0
 		switch( c->type ) {
-		case PC_ATTR:
-		case PC_TEMP:
+		case CH_CHAINING:
+			return 1;
+
+		case CH_CACHE_URI:
+			lc->lc_flags &= ~LDAP_CHAIN_F_CACHE_URI;
+			break;
+
+		default:
+			return 1;
 		}
 		return rc;
-#endif
 	}
 
 	switch( c->type ) {
+	case CH_CHAINING: {
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-	case PC_CHAINING: {
 		char			**argv = c->argv;
 		int			argc = c->argc;
 		BerElementBuffer	berbuf;
@@ -823,20 +1150,20 @@ chain_cf_gen( ConfigArgs *c )
 			if ( strncasecmp( argv[ 0 ], "resolve=", STRLENOF( "resolve=" ) ) == 0 ) {
 				resolve = str2chain( argv[ 0 ] + STRLENOF( "resolve=" ) );
 				if ( resolve == -1 ) {
-					fprintf( stderr, "%s line %d: "
+					Debug( LDAP_DEBUG_ANY, "%s: "
 						"illegal <resolve> value %s "
-						"in \"chain-chaining>\"\n",
-						c->fname, c->lineno, argv[ 0 ] );
+						"in \"chain-chaining>\".\n",
+						c->log, argv[ 0 ], 0 );
 					return 1;
 				}
 
 			} else if ( strncasecmp( argv[ 0 ], "continuation=", STRLENOF( "continuation=" ) ) == 0 ) {
 				continuation = str2chain( argv[ 0 ] + STRLENOF( "continuation=" ) );
 				if ( continuation == -1 ) {
-					fprintf( stderr, "%s line %d: "
+					Debug( LDAP_DEBUG_ANY, "%s: "
 						"illegal <continuation> value %s "
-						"in \"chain-chaining\"\n",
-						c->fname, c->lineno, argv[ 0 ] );
+						"in \"chain-chaining\".\n",
+						c->log, argv[ 0 ], 0 );
 					return 1;
 				}
 
@@ -844,9 +1171,9 @@ chain_cf_gen( ConfigArgs *c )
 				iscritical = 1;
 
 			} else {
-				fprintf( stderr, "%s line %d: "
-					"unknown option in \"chain-chaining\"\n",
-					c->fname, c->lineno );
+				Debug( LDAP_DEBUG_ANY, "%s: "
+					"unknown option in \"chain-chaining\".\n",
+					c->log, 0, 0 );
 				return 1;
 			}
 		}
@@ -864,9 +1191,9 @@ chain_cf_gen( ConfigArgs *c )
 			err = ber_printf( ber, "{e" /* } */, resolve );
 	    		if ( err == -1 ) {
 				ber_free( ber, 1 );
-				fprintf( stderr, "%s line %d: "
+				Debug( LDAP_DEBUG_ANY, "%s: "
 					"chaining behavior control encoding error!\n",
-					c->fname, c->lineno );
+					c->log, 0, 0 );
 				return 1;
 			}
 
@@ -874,9 +1201,9 @@ chain_cf_gen( ConfigArgs *c )
 				err = ber_printf( ber, "e", continuation );
 	    			if ( err == -1 ) {
 					ber_free( ber, 1 );
-					fprintf( stderr, "%s line %d: "
+					Debug( LDAP_DEBUG_ANY, "%s: "
 						"chaining behavior control encoding error!\n",
-						c->fname, c->lineno );
+						c->log, 0, 0 );
 					return 1;
 				}
 			}
@@ -884,9 +1211,9 @@ chain_cf_gen( ConfigArgs *c )
 			err = ber_printf( ber, /* { */ "N}" );
 	    		if ( err == -1 ) {
 				ber_free( ber, 1 );
-				fprintf( stderr, "%s line %d: "
+				Debug( LDAP_DEBUG_ANY, "%s: "
 					"chaining behavior control encoding error!\n",
-					c->fname, c->lineno );
+					c->log, 0, 0 );
 				return 1;
 			}
 
@@ -903,10 +1230,9 @@ chain_cf_gen( ConfigArgs *c )
 
 		if ( ldap_chain_parse_ctrl( &op, &rs, &lc->lc_chaining_ctrl ) != LDAP_SUCCESS )
 		{
-			fprintf( stderr, "%s line %d: "
-				"unable to parse chaining control%s%s\n",
-				c->fname, c->lineno,
-				rs.sr_text ? ": " : "",
+			Debug( LDAP_DEBUG_ANY, "%s: "
+				"unable to parse chaining control%s%s.\n",
+				c->log, rs.sr_text ? ": " : "",
 				rs.sr_text ? rs.sr_text : "" );
 			return 1;
 		}
@@ -916,10 +1242,20 @@ chain_cf_gen( ConfigArgs *c )
 		lc->lc_flags |= LDAP_CHAIN_F_CHAINING;
 
 		rc = 0;
+#else /* ! LDAP_CONTROL_X_CHAINING_BEHAVIOR */
+		Debug( LDAP_DEBUG_ANY, "%s: "
+			"\"chaining\" control unsupported (ignored).\n",
+			c->log, 0, 0 );
+#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
+		} break;
 
+	case CH_CACHE_URI:
+		if ( c->value_int ) {
+			lc->lc_flags |= LDAP_CHAIN_F_CACHE_URI;
+		} else {
+			lc->lc_flags &= ~LDAP_CHAIN_F_CACHE_URI;
+		}
 		break;
-	}
-#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
 	default:
 		assert( 0 );
@@ -928,7 +1264,31 @@ chain_cf_gen( ConfigArgs *c )
 	return rc;
 }
 
-#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
+static int
+ldap_chain_db_init(
+	BackendDB *be )
+{
+	slap_overinst	*on = (slap_overinst *)be->bd_info;
+	ldap_chain_t	*lc = NULL;
+
+	if ( lback == NULL ) {
+		lback = backend_info( "ldap" );
+
+		if ( lback == NULL ) {
+			return 1;
+		}
+	}
+
+	lc = ch_malloc( sizeof( ldap_chain_t ) );
+	if ( lc == NULL ) {
+		return 1;
+	}
+	memset( lc, 0, sizeof( ldap_chain_t ) );
+
+	on->on_bi.bi_private = (void *)lc;
+
+	return 0;
+}
 
 static int
 ldap_chain_db_config(
@@ -938,219 +1298,302 @@ ldap_chain_db_config(
 	int		argc,
 	char		**argv )
 {
-	slap_overinst	*on = (slap_overinst *) be->bd_info;
+	slap_overinst	*on = (slap_overinst *)be->bd_info;
 	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
-	char		*argv0 = NULL;
-	int		rc;
-	BackendDB	db = *be;
 
-	if ( strncasecmp( argv[ 0 ], "chain-", STRLENOF( "chain-" ) ) == 0 ) {
-		argv0 = argv[ 0 ];
-		argv[ 0 ] = &argv[ 0 ][ STRLENOF( "chain-" ) ];
-
-#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-		if ( strcasecmp( argv[ 0 ], "chaining" ) == 0 ) {
-			char			**tmpargv = argv;
-			BerElementBuffer	berbuf;
-			BerElement		*ber = (BerElement *)&berbuf;
-			int			resolve = -1,
-						continuation = -1,
-						iscritical = 0;
-			Operation		op = { 0 };
-			SlapReply		rs = { 0 };
-
-			lc->lc_chaining_ctrlflag = 0;
-
-			for ( argc--, tmpargv++; argc > 0; argc--, tmpargv++ ) {
-				if ( strncasecmp( tmpargv[ 0 ], "resolve=", STRLENOF( "resolve=" ) ) == 0 ) {
-					resolve = str2chain( tmpargv[ 0 ] + STRLENOF( "resolve=" ) );
-					if ( resolve == -1 ) {
-						fprintf( stderr, "%s line %d: "
-							"illegal <resolve> value %s "
-							"in \"chain-chaining>\"\n",
-							fname, lineno, tmpargv[ 0 ] );
-						return 1;
-					}
-
-				} else if ( strncasecmp( tmpargv[ 0 ], "continuation=", STRLENOF( "continuation=" ) ) == 0 ) {
-					continuation = str2chain( tmpargv[ 0 ] + STRLENOF( "continuation=" ) );
-					if ( continuation == -1 ) {
-						fprintf( stderr, "%s line %d: "
-							"illegal <continuation> value %s "
-							"in \"chain-chaining\"\n",
-							fname, lineno, tmpargv[ 0 ] );
-						return 1;
-					}
-
-				} else if ( strcasecmp( tmpargv[ 0 ], "critical" ) == 0 ) {
-					iscritical = 1;
+	int		rc = SLAP_CONF_UNKNOWN;
+		
+	if ( lc->lc_common_li == NULL ) {
+		void	*be_private = be->be_private;
+		ldap_chain_db_init_common( be );
+		lc->lc_common_li = lc->lc_cfg_li = (ldapinfo_t *)be->be_private;
+		be->be_private = be_private;
+	}
 
-				} else {
-					fprintf( stderr, "%s line %d: "
-						"unknown option in \"chain-chaining\"\n",
-						fname, lineno );
-					return 1;
-				}
+	/* Something for the chain database? */
+	if ( strncasecmp( argv[ 0 ], "chain-", STRLENOF( "chain-" ) ) == 0 ) {
+		char		*save_argv0 = argv[ 0 ];
+		BackendInfo	*bd_info = be->bd_info;
+		void		*be_private = be->be_private;
+		ConfigOCs	*be_cf_ocs = be->be_cf_ocs;
+		int		is_uri = 0;
+
+		argv[ 0 ] += STRLENOF( "chain-" );
+
+		if ( strcasecmp( argv[ 0 ], "uri" ) == 0 ) {
+			rc = ldap_chain_db_init_one( be );
+			if ( rc != 0 ) {
+				Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+					"underlying slapd-ldap initialization failed.\n.",
+					fname, lineno, 0 );
+				return 1;
 			}
+			lc->lc_cfg_li = be->be_private;
+			is_uri = 1;
+		}
 
-			if ( resolve != -1 || continuation != -1 ) {
-				int	err;
+		/* TODO: add checks on what other slapd-ldap(5) args
+		 * should be put in the template; this is not quite
+		 * harmful, because attributes that shouldn't don't
+		 * get actually used, but the user should at least
+		 * be warned.
+		 */
 
-				if ( resolve == -1 ) {
-					/* default */
-					resolve = SLAP_CHAINING_DEFAULT;
-				}
+		be->bd_info = lback;
+		be->be_private = (void *)lc->lc_cfg_li;
+		be->be_cf_ocs = lback->bi_cf_ocs;
 
-				ber_init2( ber, NULL, LBER_USE_DER );
+		rc = config_generic_wrapper( be, fname, lineno, argc, argv );
 
-				err = ber_printf( ber, "{e" /* } */, resolve );
-		    		if ( err == -1 ) {
-					ber_free( ber, 1 );
-					fprintf( stderr, "%s line %d: "
-						"chaining behavior control encoding error!\n",
-						fname, lineno );
-					return 1;
-				}
+		argv[ 0 ] = save_argv0;
+		be->be_cf_ocs = be_cf_ocs;
+		be->be_private = be_private;
+		be->bd_info = bd_info;
 
-				if ( continuation > -1 ) {
-					err = ber_printf( ber, "e", continuation );
-		    			if ( err == -1 ) {
-						ber_free( ber, 1 );
-						fprintf( stderr, "%s line %d: "
-							"chaining behavior control encoding error!\n",
-							fname, lineno );
-						return 1;
-					}
-				}
+		if ( is_uri ) {
+private_destroy:;
+			if ( rc != 0 ) {
+				BackendDB		db = *be;
 
-				err = ber_printf( ber, /* { */ "N}" );
-		    		if ( err == -1 ) {
-					ber_free( ber, 1 );
-					fprintf( stderr, "%s line %d: "
-						"chaining behavior control encoding error!\n",
-						fname, lineno );
-					return 1;
-				}
-
-				if ( ber_flatten2( ber, &lc->lc_chaining_ctrl.ldctl_value, 0 ) == -1 ) {
-					exit( EXIT_FAILURE );
-				}
+				db.bd_info = lback;
+				db.be_private = (void *)lc->lc_cfg_li;
+				ldap_chain_db_destroy_one( &db );
+				lc->lc_cfg_li = NULL;
 
 			} else {
-				BER_BVZERO( &lc->lc_chaining_ctrl.ldctl_value );
-			}
-
-			lc->lc_chaining_ctrl.ldctl_oid = LDAP_CONTROL_X_CHAINING_BEHAVIOR;
-			lc->lc_chaining_ctrl.ldctl_iscritical = iscritical;
+				if ( lc->lc_cfg_li->li_bvuri == NULL
+					|| BER_BVISNULL( &lc->lc_cfg_li->li_bvuri[ 0 ] )
+					|| !BER_BVISNULL( &lc->lc_cfg_li->li_bvuri[ 1 ] ) )
+				{
+					Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+						"no URI list allowed in slapo-chain.\n",
+						fname, lineno, 0 );
+					rc = 1;
+					goto private_destroy;
+				}
 
-			if ( ldap_chain_parse_ctrl( &op, &rs, &lc->lc_chaining_ctrl ) != LDAP_SUCCESS )
-			{
-				fprintf( stderr, "%s line %d: "
-					"unable to parse chaining control%s%s\n",
-					fname, lineno,
-					rs.sr_text ? ": " : "",
-					rs.sr_text ? rs.sr_text : "" );
-				return 1;
+				if ( avl_insert( &lc->lc_lai.lai_tree,
+					(caddr_t)lc->lc_cfg_li,
+					ldap_chain_uri_cmp, ldap_chain_uri_dup ) )
+				{
+					Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+						"duplicate URI in slapo-chain.\n",
+						fname, lineno, 0 );
+					rc = 1;
+					goto private_destroy;
+				}
 			}
+		}
+	}
+	
+	return rc;
+}
 
-			lc->lc_chaining_ctrlflag = op.o_chaining;
+enum db_which {
+	db_open = 0,
+	db_close,
+	db_destroy,
 
-			lc->lc_flags |= LDAP_CHAIN_F_CHAINING;
+	db_last
+};
 
-			rc = 0;
-			goto done;
-		}
-#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
-	}
+typedef struct ldap_chain_db_apply_t {
+	BackendDB	*be;
+	BI_db_func	*func;
+} ldap_chain_db_apply_t;
 
-	db.be_cf_ocs = lback->bi_cf_ocs;
-	db.be_private = lc->lc_li;
-	rc = lback->bi_db_config( &db, fname, lineno, argc, argv );
+static int
+ldap_chain_db_apply( void *datum, void *arg )
+{
+	ldapinfo_t		*li = (ldapinfo_t *)datum;
+	ldap_chain_db_apply_t	*lca = (ldap_chain_db_apply_t *)arg;
 
-done:;
-	if ( argv0 ) {
-		argv[ 0 ] = argv0;
-	}
+	lca->be->be_private = (void *)li;
 
-	return rc;
+	return lca->func( lca->be );
 }
 
 static int
-ldap_chain_db_init(
-	BackendDB *be )
+ldap_chain_db_func(
+	BackendDB *be,
+	enum db_which which
+)
 {
 	slap_overinst	*on = (slap_overinst *)be->bd_info;
-	ldap_chain_t	*lc = NULL;
-	int		rc;
-	BackendDB	bd = *be;
+	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
 
-	if ( lback == NULL ) {
-		lback = backend_info( "ldap" );
+	int		rc = 0;
 
-		if ( lback == NULL ) {
-			return -1;
-		}
-	}
+	if ( lc ) {
+		BI_db_func	*func = (&lback->bi_db_open)[ which ];
 
-	lc = ch_malloc( sizeof( ldap_chain_t ) );
-	memset( lc, 0, sizeof( ldap_chain_t ) );
+		if ( func != NULL && lc->lc_common_li != NULL ) {
+			BackendDB		db = *be;
 
-	ldap_pvt_thread_mutex_init( &lc->lc_mutex );
+			db.bd_info = lback;
+			db.be_private = lc->lc_common_li;
 
-	bd.be_private = NULL;
-	rc = lback->bi_db_init( &bd );
-	lc->lc_li = (struct ldapinfo *)bd.be_private;
-	on->on_bi.bi_private = (void *)lc;
+			rc = func( &db );
+
+			if ( rc != 0 ) {
+				return rc;
+			}
+
+			if ( lc->lc_lai.lai_tree != NULL ) {
+				ldap_chain_db_apply_t	lca;
+
+				lca.be = &db;
+				lca.func = func;
+
+				rc = avl_apply( lc->lc_lai.lai_tree,
+					ldap_chain_db_apply, (void *)&lca,
+					1, AVL_INORDER ) != AVL_NOMORE;
+			}
+		}
+	}
 
 	return rc;
 }
 
 static int
 ldap_chain_db_open(
-	BackendDB *be
-)
+	BackendDB	*be )
 {
+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 	int	rc = 0;
 
-#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 	rc = overlay_register_control( be, LDAP_CONTROL_X_CHAINING_BEHAVIOR );
+	if ( rc != 0 ) {
+		return rc;
+	}
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
-	return rc;
+	return ldap_chain_db_func( be, db_open );
+}
+
+static int
+ldap_chain_db_close(
+	BackendDB	*be )
+{
+	return ldap_chain_db_func( be, db_close );
 }
 
 static int
 ldap_chain_db_destroy(
-	BackendDB *be
-)
+	BackendDB	*be )
 {
 	slap_overinst	*on = (slap_overinst *) be->bd_info;
 	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
-	void		*private = be->be_private;
+
 	int		rc;
 
-	be->be_private = (void *)lc->lc_li;
-	rc = lback->bi_db_destroy( be );
-	ldap_pvt_thread_mutex_destroy( &lc->lc_mutex );
-	ch_free( lc );
-	on->on_bi.bi_private = NULL;
-	be->be_private = private;
+	rc = ldap_chain_db_func( be, db_destroy );
+
+	if ( lc ) {
+		avl_free( lc->lc_lai.lai_tree, NULL );
+		ch_free( lc );
+	}
+
 	return rc;
 }
 
+/*
+ * inits one instance of the slapd-ldap backend, and stores
+ * the private info in be_private of the arg
+ */
+static int
+ldap_chain_db_init_common(
+	BackendDB	*be )
+{
+	BackendInfo	*bi = be->bd_info;
+	int		t;
+
+	be->bd_info = lback;
+	be->be_private = NULL;
+	t = lback->bi_db_init( be );
+	if ( t != 0 ) {
+		return t;
+	}
+	be->bd_info = bi;
+
+	return 0;
+}
+
+/*
+ * inits one instance of the slapd-ldap backend, stores
+ * the private info in be_private of the arg and fills
+ * selected fields with data from the template.
+ *
+ * NOTE: add checks about the other fields of the template,
+ * which are ignored and SHOULD NOT be configured by the user.
+ */
+static int
+ldap_chain_db_init_one(
+	BackendDB	*be )
+{
+	slap_overinst	*on = (slap_overinst *)be->bd_info;
+	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
+
+	BackendInfo	*bi = be->bd_info;
+	ldapinfo_t	*li;
+
+	int		t;
+
+	be->bd_info = lback;
+	be->be_private = NULL;
+	t = lback->bi_db_init( be );
+	if ( t != 0 ) {
+		return t;
+	}
+	li = (ldapinfo_t *)be->be_private;
+
+	/* copy common data */
+	li->li_nretries = lc->lc_common_li->li_nretries;
+	li->li_flags = lc->lc_common_li->li_flags;
+	li->li_version = lc->lc_common_li->li_version;
+	for ( t = 0; t < LDAP_BACK_OP_LAST; t++ ) {
+		li->li_timeout[ t ] = lc->lc_common_li->li_timeout[ t ];
+	}
+	be->bd_info = bi;
+
+	return 0;
+}
+
+typedef struct ldap_chain_conn_apply_t {
+	BackendDB	*be;
+	Connection	*conn;
+} ldap_chain_conn_apply_t;
+
+static int
+ldap_chain_conn_apply( void *datum, void *arg )
+{
+	ldapinfo_t		*li = (ldapinfo_t *)datum;
+	ldap_chain_conn_apply_t	*lca = (ldap_chain_conn_apply_t *)arg;
+
+	lca->be->be_private = (void *)li;
+
+	return lback->bi_connection_destroy( lca->be, lca->conn );
+}
+
 static int
 ldap_chain_connection_destroy(
 	BackendDB *be,
 	Connection *conn
 )
 {
-	slap_overinst	*on = (slap_overinst *) be->bd_info;
-	ldap_chain_t	*lc = (ldap_chain_t *)on->on_bi.bi_private;
-	void		*private = be->be_private;
-	int		rc;
-
-	be->be_private = (void *)lc->lc_li;
-	rc = lback->bi_connection_destroy( be, conn );
+	slap_overinst		*on = (slap_overinst *) be->bd_info;
+	ldap_chain_t		*lc = (ldap_chain_t *)on->on_bi.bi_private;
+	void			*private = be->be_private;
+	ldap_chain_conn_apply_t	lca;
+	int			rc;
+
+	be->be_private = NULL;
+	lca.be = be;
+	lca.conn = conn;
+	ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex );
+	rc = avl_apply( lc->lc_lai.lai_tree, ldap_chain_conn_apply,
+		(void *)&lca, 1, AVL_INORDER ) != AVL_NOMORE;
+	ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex );
 	be->be_private = private;
 
 	return rc;
@@ -1291,20 +1734,26 @@ chain_init( void )
 {
 	int	rc;
 
+	/* Make sure we don't exceed the bits reserved for userland */
+	config_check_userland( CH_LAST );
+
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
 	rc = register_supported_control( LDAP_CONTROL_X_CHAINING_BEHAVIOR,
 			/* SLAP_CTRL_GLOBAL| */ SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE, NULL,
 			ldap_chain_parse_ctrl, &sc_chainingBehavior );
 	if ( rc != LDAP_SUCCESS ) {
-		fprintf( stderr, "Failed to register chaining behavior control: %d\n", rc );
+		Debug( LDAP_DEBUG_ANY, "slapd-chain: "
+			"unable to register chaining behavior control: %d.\n",
+			rc, 0, 0 );
 		return rc;
 	}
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
 
 	ldapchain.on_bi.bi_type = "chain";
 	ldapchain.on_bi.bi_db_init = ldap_chain_db_init;
-	ldapchain.on_bi.bi_db_open = ldap_chain_db_open;
 	ldapchain.on_bi.bi_db_config = ldap_chain_db_config;
+	ldapchain.on_bi.bi_db_open = ldap_chain_db_open;
+	ldapchain.on_bi.bi_db_close = ldap_chain_db_close;
 	ldapchain.on_bi.bi_db_destroy = ldap_chain_db_destroy;
 
 	/* ... otherwise the underlying backend's function would be called,
diff --git a/servers/slapd/back-ldap/compare.c b/servers/slapd/back-ldap/compare.c
index 64caac368a98f9f4106fb37baea52c27d7ca4eb7..0d0a90ed49c41f5448d3408023e049fc2abfb8bd 100644
--- a/servers/slapd/back-ldap/compare.c
+++ b/servers/slapd/back-ldap/compare.c
@@ -36,7 +36,7 @@ ldap_back_compare(
 		Operation	*op,
 		SlapReply	*rs )
 {
-	struct ldapconn	*lc;
+	ldapconn_t	*lc;
 	ber_int_t	msgid;
 	int		do_retry = 1;
 	LDAPControl	**ctrls = NULL;
@@ -63,7 +63,7 @@ retry:
 	rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_SENDRESULT );
 	if ( rc == LDAP_UNAVAILABLE && do_retry ) {
 		do_retry = 0;
-		if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
+		if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 			goto retry;
 		}
 	}
diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c
index 3e5573f7bb48f59a8cfb85b7aa39a65c8e095d7f..b3ef34d0e8e8e7dcbfdb60af38a8f173c75a36fb 100644
--- a/servers/slapd/back-ldap/config.c
+++ b/servers/slapd/back-ldap/config.c
@@ -60,12 +60,14 @@ enum {
 	LDAP_BACK_CFG_T_F,
 	LDAP_BACK_CFG_WHOAMI,
 	LDAP_BACK_CFG_TIMEOUT,
-	LDAP_BACK_CFG_REWRITE
+	LDAP_BACK_CFG_REWRITE,
+
+	LDAP_BACK_CFG_LAST
 };
 
 static ConfigTable ldapcfg[] = {
 	{ "uri", "uri", 2, 2, 0,
-		ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_URI,
+		ARG_MAGIC|LDAP_BACK_CFG_URI,
 		ldap_back_cf_gen, "( OLcfgDbAt:0.14 "
 			"NAME 'olcDbURI' "
 			"DESC 'URI (list) for remote DSA' "
@@ -173,19 +175,19 @@ static ConfigTable ldapcfg[] = {
 			"X-ORDERED 'VALUES' )",
 		NULL, NULL },
 	{ "rebind-as-user", "NO|yes", 1, 2, 0,
-		ARG_MAGIC|LDAP_BACK_CFG_REBIND,
+		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_REBIND,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.10 "
 			"NAME 'olcDbRebindAsUser' "
 			"DESC 'Rebind as user' "
-			"SYNTAX OMsDirectoryString "
+			"SYNTAX OMsBoolean "
 			"SINGLE-VALUE )",
 		NULL, NULL },
 	{ "chase-referrals", "YES|no", 2, 2, 0,
-		ARG_MAGIC|LDAP_BACK_CFG_CHASE,
+		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_CHASE,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.11 "
 			"NAME 'olcDbChaseReferrals' "
 			"DESC 'Chase referrals' "
-			"SYNTAX OMsDirectoryString "
+			"SYNTAX OMsBoolean "
 			"SINGLE-VALUE )",
 		NULL, NULL },
 	{ "t-f-support", "NO|yes|discover", 2, 2, 0,
@@ -197,14 +199,14 @@ static ConfigTable ldapcfg[] = {
 			"SINGLE-VALUE )",
 		NULL, NULL },
 	{ "proxy-whoami", "NO|yes", 1, 2, 0,
-		ARG_MAGIC|LDAP_BACK_CFG_WHOAMI,
+		ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_WHOAMI,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.13 "
 			"NAME 'olcDbProxyWhoAmI' "
 			"DESC 'Proxy whoAmI exop' "
-			"SYNTAX OMsDirectoryString "
+			"SYNTAX OMsBoolean "
 			"SINGLE-VALUE )",
 		NULL, NULL },
-	{ "timeout", "timeout", 0, 2, 0,
+	{ "timeout", "timeout(list)", 2, 0, 0,
 		ARG_MAGIC|LDAP_BACK_CFG_TIMEOUT,
 		ldap_back_cf_gen, "( OLcfgDbAt:3.14 "
 			"NAME 'olcDbTimeout' "
@@ -250,14 +252,6 @@ static ConfigOCs ldapocs[] = {
 	{ NULL, 0, NULL }
 };
 
-#define	LDAP_BACK_C_NO			(0x0U)
-#define	LDAP_BACK_C_YES			(0x1U)
-static slap_verbmasks yn_mode[] = {
-	{ BER_BVC( "yes" ),		LDAP_BACK_C_YES},
-	{ BER_BVC( "no" ),		LDAP_BACK_C_NO },
-	{ BER_BVNULL,			0 }
-};
-
 static slap_verbmasks idassert_mode[] = {
 	{ BER_BVC("self"),		LDAP_BACK_IDASSERT_SELF },
 	{ BER_BVC("anonymous"),		LDAP_BACK_IDASSERT_ANONYMOUS },
@@ -271,14 +265,14 @@ static slap_verbmasks tls_mode[] = {
 	{ BER_BVC( "try-propagate" ),	LDAP_BACK_F_PROPAGATE_TLS },
 	{ BER_BVC( "start" ),		LDAP_BACK_F_TLS_USE_MASK },
 	{ BER_BVC( "try-start" ),	LDAP_BACK_F_USE_TLS },
-	{ BER_BVC( "none" ),		LDAP_BACK_C_NO },
+	{ BER_BVC( "none" ),		LDAP_BACK_F_NONE },
 	{ BER_BVNULL,			0 }
 };
 
 static slap_verbmasks t_f_mode[] = {
 	{ BER_BVC( "yes" ),		LDAP_BACK_F_SUPPORT_T_F },
 	{ BER_BVC( "discover" ),	LDAP_BACK_F_SUPPORT_T_F_DISCOVER },
-	{ BER_BVC( "no" ),		LDAP_BACK_C_NO },
+	{ BER_BVC( "no" ),		LDAP_BACK_F_NONE },
 	{ BER_BVNULL,			0 }
 };
 
@@ -293,7 +287,7 @@ static slap_cf_aux_table timeout_table[] = {
 static int
 ldap_back_cf_gen( ConfigArgs *c )
 {
-	struct ldapinfo	*li = ( struct ldapinfo * )c->be->be_private;
+	ldapinfo_t	*li = ( ldapinfo_t * )c->be->be_private;
 	int		rc;
 	int		i;
 
@@ -303,8 +297,11 @@ ldap_back_cf_gen( ConfigArgs *c )
 
 		switch( c->type ) {
 		case LDAP_BACK_CFG_URI:
-			if ( li->url != NULL ) {
-				c->value_string = ch_strdup( li->url );
+			if ( li->li_uri != NULL ) {
+				struct berval	bv;
+
+				ber_str2bv( li->li_uri, 0, 0, &bv );
+				value_add_one( &c->rvalue_vals, &bv );
 
 			} else {
 				rc = 1;
@@ -312,7 +309,7 @@ ldap_back_cf_gen( ConfigArgs *c )
 			break;
 
 		case LDAP_BACK_CFG_TLS:
-			enum_to_verb( tls_mode, ( li->flags & LDAP_BACK_F_TLS_MASK ), &bv );
+			enum_to_verb( tls_mode, ( li->li_flags & LDAP_BACK_F_TLS_MASK ), &bv );
 			if ( BER_BVISNULL( &bv ) ) {
 				/* there's something wrong... */
 				assert( 0 );
@@ -333,7 +330,7 @@ ldap_back_cf_gen( ConfigArgs *c )
 		case LDAP_BACK_CFG_ACL_BIND: {
 			int	i;
 
-			bindconf_unparse( &li->acl_sb, &bv );
+			bindconf_unparse( &li->li_acl, &bv );
 
 			for ( i = 0; isspace( bv.bv_val[ i ] ); i++ )
 				/* count spaces */ ;
@@ -359,14 +356,14 @@ ldap_back_cf_gen( ConfigArgs *c )
 		case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: {
 			int		i;
 
-			if ( li->idassert_authz == NULL ) {
+			if ( li->li_idassert_authz == NULL ) {
 				rc = 1;
 				break;
 			}
 
-			for ( i = 0; !BER_BVISNULL( &li->idassert_authz[ i ] ); i++ )
+			for ( i = 0; !BER_BVISNULL( &li->li_idassert_authz[ i ] ); i++ )
 			{
-				value_add_one( &c->rvalue_vals, &li->idassert_authz[ i ] );
+				value_add_one( &c->rvalue_vals, &li->li_idassert_authz[ i ] );
 			}
 			break;
 		}
@@ -376,10 +373,10 @@ ldap_back_cf_gen( ConfigArgs *c )
 			struct berval	bc = BER_BVNULL;
 			char		*ptr;
 
-			if ( li->idassert_authmethod != LDAP_AUTH_NONE ) {
+			if ( li->li_idassert_authmethod != LDAP_AUTH_NONE ) {
 				ber_len_t	len;
 
-				switch ( li->idassert_mode ) {
+				switch ( li->li_idassert_mode ) {
 				case LDAP_BACK_IDASSERT_OTHERID:
 				case LDAP_BACK_IDASSERT_OTHERDN:
 					break;
@@ -387,7 +384,7 @@ ldap_back_cf_gen( ConfigArgs *c )
 				default: {
 					struct berval	mode = BER_BVNULL;
 
-					enum_to_verb( idassert_mode, li->idassert_mode, &mode );
+					enum_to_verb( idassert_mode, li->li_idassert_mode, &mode );
 					if ( BER_BVISNULL( &mode ) ) {
 						/* there's something wrong... */
 						assert( 0 );
@@ -404,7 +401,7 @@ ldap_back_cf_gen( ConfigArgs *c )
 				}
 				}
 
-				if ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) {
+				if ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) {
 					len = bv.bv_len + STRLENOF( "authz=native" );
 
 					if ( !BER_BVISEMPTY( &bv ) ) {
@@ -438,13 +435,13 @@ ldap_back_cf_gen( ConfigArgs *c )
 
 				ptr = lutil_strcopy( ptr, "flags=" );
 
-				if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
+				if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
 					ptr = lutil_strcopy( ptr, "prescriptive" );
 				} else {
 					ptr = lutil_strcopy( ptr, "non-prescriptive" );
 				}
 
-				if ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
+				if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
 					ptr = lutil_strcopy( ptr, ",override" );
 				}
 
@@ -452,7 +449,7 @@ ldap_back_cf_gen( ConfigArgs *c )
 				/* end-of-flags */
 			}
 
-			bindconf_unparse( &li->idassert_sb, &bc );
+			bindconf_unparse( &li->li_idassert, &bc );
 
 			if ( !BER_BVISNULL( &bv ) ) {
 				ber_len_t	len = bv.bv_len + bc.bv_len;
@@ -483,31 +480,15 @@ ldap_back_cf_gen( ConfigArgs *c )
 		}
 
 		case LDAP_BACK_CFG_REBIND:
-			enum_to_verb( yn_mode, ( ( li->flags & LDAP_BACK_F_SAVECRED ) == LDAP_BACK_F_SAVECRED ), &bv );
-			if ( BER_BVISNULL( &bv ) ) {
-				/* there's something wrong... */
-				assert( 0 );
-				rc = 1;
-
-			} else {
-				value_add_one( &c->rvalue_vals, &bv );
-			}
+			c->value_int = LDAP_BACK_SAVECRED( li );
 			break;
 
 		case LDAP_BACK_CFG_CHASE:
-			enum_to_verb( yn_mode, ( ( li->flags & LDAP_BACK_F_CHASE_REFERRALS ) == LDAP_BACK_F_CHASE_REFERRALS ), &bv );
-			if ( BER_BVISNULL( &bv ) ) {
-				/* there's something wrong... */
-				assert( 0 );
-				rc = 1;
-
-			} else {
-				value_add_one( &c->rvalue_vals, &bv );
-			}
+			c->value_int = LDAP_BACK_CHASE_REFERRALS( li );
 			break;
 
 		case LDAP_BACK_CFG_T_F:
-			enum_to_verb( t_f_mode, ( ( li->flags & LDAP_BACK_F_SUPPORT_T_F_MASK ) == LDAP_BACK_F_SUPPORT_T_F_MASK ), &bv );
+			enum_to_verb( t_f_mode, (li->li_flags & LDAP_BACK_F_SUPPORT_T_F_MASK), &bv );
 			if ( BER_BVISNULL( &bv ) ) {
 				/* there's something wrong... */
 				assert( 0 );
@@ -519,21 +500,13 @@ ldap_back_cf_gen( ConfigArgs *c )
 			break;
 
 		case LDAP_BACK_CFG_WHOAMI:
-			enum_to_verb( yn_mode, ( ( li->flags & LDAP_BACK_F_PROXY_WHOAMI ) == LDAP_BACK_F_PROXY_WHOAMI ), &bv );
-			if ( BER_BVISNULL( &bv ) ) {
-				/* there's something wrong... */
-				assert( 0 );
-				rc = 1;
-
-			} else {
-				value_add_one( &c->rvalue_vals, &bv );
-			}
+			c->value_int = LDAP_BACK_PROXY_WHOAMI( li );
 			break;
 
 		case LDAP_BACK_CFG_TIMEOUT:
 			BER_BVZERO( &bv );
 
-			slap_cf_aux_table_unparse( li->timeout, &bv, timeout_table );
+			slap_cf_aux_table_unparse( li->li_timeout, &bv, timeout_table );
 
 			if ( !BER_BVISNULL( &bv ) ) {	
 				for ( i = 0; isspace( bv.bv_val[ i ] ); i++ )
@@ -560,21 +533,22 @@ ldap_back_cf_gen( ConfigArgs *c )
 		rc = 0;
 		switch( c->type ) {
 		case LDAP_BACK_CFG_URI:
-			if ( li->url != NULL ) {
-				ch_free( li->url );
-				li->url = NULL;
-			}
+			if ( li->li_uri != NULL ) {
+				ch_free( li->li_uri );
+				li->li_uri = NULL;
 
-			if ( li->lud != NULL ) {
-				ldap_free_urllist( li->lud );
-				li->lud = NULL;
+				assert( li->li_bvuri != NULL );
+				ber_bvarray_free( li->li_bvuri );
+				li->li_bvuri = NULL;
 			}
-			
+
 			/* better cleanup the cached connections... */
 			/* NOTE: don't worry about locking: if we got here,
 			 * other threads are suspended. */
-			avl_free( li->conntree, ldap_back_conn_free );
-			li->conntree = NULL;
+			if ( li->li_conninfo.lai_tree != NULL ) {
+				avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free );
+				li->li_conninfo.lai_tree = NULL;
+			}
 			
 			break;
 
@@ -590,7 +564,7 @@ ldap_back_cf_gen( ConfigArgs *c )
 			break;
 
 		case LDAP_BACK_CFG_ACL_BIND:
-			bindconf_free( &li->acl_sb );
+			bindconf_free( &li->li_acl );
 			break;
 
 		case LDAP_BACK_CFG_IDASSERT_MODE:
@@ -602,14 +576,14 @@ ldap_back_cf_gen( ConfigArgs *c )
 			break;
 
 		case LDAP_BACK_CFG_IDASSERT_AUTHZFROM:
-			if ( li->idassert_authz != NULL ) {
-				ber_bvarray_free( li->idassert_authz );
-				li->idassert_authz = NULL;
+			if ( li->li_idassert_authz != NULL ) {
+				ber_bvarray_free( li->li_idassert_authz );
+				li->li_idassert_authz = NULL;
 			}
 			break;
 
 		case LDAP_BACK_CFG_IDASSERT_BIND:
-			bindconf_free( &li->idassert_sb );
+			bindconf_free( &li->li_idassert );
 			break;
 
 		case LDAP_BACK_CFG_REBIND:
@@ -621,7 +595,7 @@ ldap_back_cf_gen( ConfigArgs *c )
 
 		case LDAP_BACK_CFG_TIMEOUT:
 			for ( i = 0; i < LDAP_BACK_OP_LAST; i++ ) {
-				li->timeout[ i ] = 0;
+				li->li_timeout[ i ] = 0;
 			}
 			break;
 
@@ -636,11 +610,9 @@ ldap_back_cf_gen( ConfigArgs *c )
 
 	switch( c->type ) {
 	case LDAP_BACK_CFG_URI: {
-		LDAPURLDesc	*tmpludp;
-#if 0
-		char		**urllist;
-#endif
-		int		urlrc, i;
+		LDAPURLDesc	*tmpludp, *lud;
+		char		**urllist = NULL;
+		int		urlrc = LDAP_URL_SUCCESS, i;
 
 		if ( c->argc != 2 ) {
 			fprintf( stderr, "%s: line %d: "
@@ -650,20 +622,17 @@ ldap_back_cf_gen( ConfigArgs *c )
 			return 1;
 		}
 
-		if ( li->url != NULL ) {
-			ch_free( li->url );
-		}
+		if ( li->li_uri != NULL ) {
+			ch_free( li->li_uri );
+			li->li_uri = NULL;
 
-		if ( li->lud != NULL ) {
-			ldap_free_urllist( li->lud );
+			assert( li->li_bvuri != NULL );
+			ber_bvarray_free( li->li_bvuri );
+			li->li_bvuri = NULL;
 		}
 
-#if 0
 		/* PARANOID: DN and more are not required nor allowed */
-		urlrc = ldap_url_parselist_ext( &li->lud, c->value_string, "\t" );
-#else
-		urlrc = ldap_url_parselist( &li->lud, c->value_string );
-#endif
+		urlrc = ldap_url_parselist_ext( &lud, c->argv[ 1 ], ", \t" );
 		if ( urlrc != LDAP_URL_SUCCESS ) {
 			char	*why;
 
@@ -682,6 +651,7 @@ ldap_back_cf_gen( ConfigArgs *c )
 				break;
 			case LDAP_URL_ERR_BADURL:
 				why = "URL is bad";
+				break;
 			case LDAP_URL_ERR_BADHOST:
 				why = "host/port is bad";
 				break;
@@ -705,10 +675,11 @@ ldap_back_cf_gen( ConfigArgs *c )
 					"unable to parse uri \"%s\" "
 					"in \"uri <uri>\" line: %s\n",
 					c->fname, c->lineno, c->value_string, why );
-			return 1;
+			urlrc = 1;
+			goto done_url;
 		}
 
-		for ( i = 0, tmpludp = li->lud;
+		for ( i = 0, tmpludp = lud;
 				tmpludp;
 				i++, tmpludp = tmpludp->lud_next )
 		{
@@ -728,20 +699,18 @@ ldap_back_cf_gen( ConfigArgs *c )
 			}
 		}
 
-#if 0
-		for ( i = 0, tmpludp = li->lud;
+		for ( i = 0, tmpludp = lud;
 				tmpludp;
 				i++, tmpludp = tmpludp->lud_next )
 			/* just count */
 			;
 		urllist = ch_calloc( sizeof( char * ), i + 1 );
 
-		for ( i = 0, tmpludp = li->lud;
+		for ( i = 0, tmpludp = lud;
 				tmpludp;
 				i++, tmpludp = tmpludp->lud_next )
 		{
 			LDAPURLDesc	tmplud;
-			ber_len_t	oldlen = 0, len;
 
 			tmplud = *tmpludp;
 			tmplud.lud_dn = "";
@@ -759,17 +728,33 @@ ldap_back_cf_gen( ConfigArgs *c )
 					"unable to rebuild uri "
 					"in \"uri <uri>\" statement "
 					"for \"%s\"\n",
-					c->fname, c->lineno, argv[ 1 ] );
-				return 1;
+					c->fname, c->lineno, c->argv[ 1 ] );
+				urlrc = 1;
+				goto done_url;
 			}
 		}
 
-		li->url = ldap_charray2str( urllist, " " );
-		ldap_charray_free( urllist );
-#else
-		li->url = c->value_string;
-		c->value_string = NULL;
-#endif
+		li->li_uri = ldap_charray2str( urllist, " " );
+		for ( i = 0; urllist[ i ] != NULL; i++ ) {
+			struct berval	bv;
+
+			ber_str2bv( urllist[ i ], 0, 0, &bv );
+			ber_bvarray_add( &li->li_bvuri, &bv );
+			urllist[ i ] = NULL;
+		}
+		ldap_memfree( urllist );
+		urllist = NULL;
+
+done_url:;
+		if ( urllist ) {
+			ldap_charray_free( urllist );
+		}
+		if ( lud ) {
+			ldap_free_urllist( lud );
+		}
+		if ( urlrc != LDAP_URL_SUCCESS ) {
+			return 1;
+		}
 		break;
 	}
 
@@ -778,14 +763,14 @@ ldap_back_cf_gen( ConfigArgs *c )
 		if ( BER_BVISNULL( &tls_mode[i].word ) ) {
 			return 1;
 		}
-		li->flags &= ~LDAP_BACK_F_TLS_MASK;
-		li->flags |= tls_mode[i].mask;
+		li->li_flags &= ~LDAP_BACK_F_TLS_MASK;
+		li->li_flags |= tls_mode[i].mask;
 		break;
 
 	case LDAP_BACK_CFG_ACL_AUTHCDN:
-		switch ( li->acl_authmethod ) {
+		switch ( li->li_acl_authmethod ) {
 		case LDAP_AUTH_NONE:
-			li->acl_authmethod = LDAP_AUTH_SIMPLE;
+			li->li_acl_authmethod = LDAP_AUTH_SIMPLE;
 			break;
 
 		case LDAP_AUTH_SIMPLE:
@@ -795,22 +780,22 @@ ldap_back_cf_gen( ConfigArgs *c )
 			fprintf( stderr, "%s: line %d: "
 				"\"acl-authcDN <DN>\" incompatible "
 				"with auth method %d.",
-				c->fname, c->lineno, li->acl_authmethod );
+				c->fname, c->lineno, li->li_acl_authmethod );
 			return 1;
 		}
-		if ( !BER_BVISNULL( &li->acl_authcDN ) ) {
-			free( li->acl_authcDN.bv_val );
+		if ( !BER_BVISNULL( &li->li_acl_authcDN ) ) {
+			free( li->li_acl_authcDN.bv_val );
 		}
 		ber_memfree_x( c->value_dn.bv_val, NULL );
-		li->acl_authcDN = c->value_ndn;
+		li->li_acl_authcDN = c->value_ndn;
 		BER_BVZERO( &c->value_dn );
 		BER_BVZERO( &c->value_ndn );
 		break;
 
 	case LDAP_BACK_CFG_ACL_PASSWD:
-		switch ( li->acl_authmethod ) {
+		switch ( li->li_acl_authmethod ) {
 		case LDAP_AUTH_NONE:
-			li->acl_authmethod = LDAP_AUTH_SIMPLE;
+			li->li_acl_authmethod = LDAP_AUTH_SIMPLE;
 			break;
 
 		case LDAP_AUTH_SIMPLE:
@@ -820,19 +805,19 @@ ldap_back_cf_gen( ConfigArgs *c )
 			fprintf( stderr, "%s: line %d: "
 				"\"acl-passwd <cred>\" incompatible "
 				"with auth method %d.",
-				c->fname, c->lineno, li->acl_authmethod );
+				c->fname, c->lineno, li->li_acl_authmethod );
 			return 1;
 		}
-		if ( !BER_BVISNULL( &li->acl_passwd ) ) {
-			free( li->acl_passwd.bv_val );
+		if ( !BER_BVISNULL( &li->li_acl_passwd ) ) {
+			free( li->li_acl_passwd.bv_val );
 		}
-		ber_str2bv( c->argv[ 1 ], 0, 1, &li->acl_passwd );
+		ber_str2bv( c->argv[ 1 ], 0, 1, &li->li_acl_passwd );
 		break;
 
 	case LDAP_BACK_CFG_ACL_METHOD:
 	case LDAP_BACK_CFG_ACL_BIND:
 		for ( i = 1; i < c->argc; i++ ) {
-			if ( bindconf_parse( c->argv[ i ], &li->acl_sb ) ) {
+			if ( bindconf_parse( c->argv[ i ], &li->li_acl ) ) {
 				return 1;
 			}
 		}
@@ -842,9 +827,9 @@ ldap_back_cf_gen( ConfigArgs *c )
 		i = verb_to_mask( c->argv[1], idassert_mode );
 		if ( BER_BVISNULL( &idassert_mode[i].word ) ) {
 			if ( strncasecmp( c->argv[1], "u:", STRLENOF( "u:" ) ) == 0 ) {
-				li->idassert_mode = LDAP_BACK_IDASSERT_OTHERID;
-				ber_str2bv( c->argv[1], 0, 1, &li->idassert_authzID );
-				li->idassert_authzID.bv_val[ 0 ] = 'u';
+				li->li_idassert_mode = LDAP_BACK_IDASSERT_OTHERID;
+				ber_str2bv( c->argv[1], 0, 1, &li->li_idassert_authzID );
+				li->li_idassert_authzID.bv_val[ 0 ] = 'u';
 				
 			} else {
 				struct berval	id, ndn;
@@ -864,17 +849,17 @@ ldap_back_cf_gen( ConfigArgs *c )
                                         return 1;
                                 }
 
-                                li->idassert_authzID.bv_len = STRLENOF( "dn:" ) + ndn.bv_len;
-                                li->idassert_authzID.bv_val = ch_malloc( li->idassert_authzID.bv_len + 1 );
-                                AC_MEMCPY( li->idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
-                                AC_MEMCPY( &li->idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], ndn.bv_val, ndn.bv_len + 1 );
+                                li->li_idassert_authzID.bv_len = STRLENOF( "dn:" ) + ndn.bv_len;
+                                li->li_idassert_authzID.bv_val = ch_malloc( li->li_idassert_authzID.bv_len + 1 );
+                                AC_MEMCPY( li->li_idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
+                                AC_MEMCPY( &li->li_idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], ndn.bv_val, ndn.bv_len + 1 );
                                 ch_free( ndn.bv_val );
 
-                                li->idassert_mode = LDAP_BACK_IDASSERT_OTHERDN;
+                                li->li_idassert_mode = LDAP_BACK_IDASSERT_OTHERDN;
 			}
 
 		} else {
-			li->idassert_mode = idassert_mode[i].mask;
+			li->li_idassert_mode = idassert_mode[i].mask;
 		}
 
 		if ( c->argc > 2 ) {
@@ -882,13 +867,13 @@ ldap_back_cf_gen( ConfigArgs *c )
 
 			for ( i = 2; i < c->argc; i++ ) {
 				if ( strcasecmp( c->argv[ i ], "override" ) == 0 ) {
-					li->idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
+					li->li_idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
 
 				} else if ( strcasecmp( c->argv[ i ], "prescriptive" ) == 0 ) {
-					li->idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
+					li->li_idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
 
 				} else if ( strcasecmp( c->argv[ i ], "non-prescriptive" ) == 0 ) {
-					li->idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
+					li->li_idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
 
 				} else {
 					Debug( LDAP_DEBUG_ANY,
@@ -903,9 +888,9 @@ ldap_back_cf_gen( ConfigArgs *c )
 		break;
 
 	case LDAP_BACK_CFG_IDASSERT_AUTHCDN:
-		switch ( li->idassert_authmethod ) {
+		switch ( li->li_idassert_authmethod ) {
 		case LDAP_AUTH_NONE:
-			li->idassert_authmethod = LDAP_AUTH_SIMPLE;
+			li->li_idassert_authmethod = LDAP_AUTH_SIMPLE;
 			break;
 
 		case LDAP_AUTH_SIMPLE:
@@ -915,22 +900,22 @@ ldap_back_cf_gen( ConfigArgs *c )
 			fprintf( stderr, "%s: line %d: "
 				"\"idassert-authcDN <DN>\" incompatible "
 				"with auth method %d.",
-				c->fname, c->lineno, li->idassert_authmethod );
+				c->fname, c->lineno, li->li_idassert_authmethod );
 			return 1;
 		}
-		if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
-			free( li->idassert_authcDN.bv_val );
+		if ( !BER_BVISNULL( &li->li_idassert_authcDN ) ) {
+			free( li->li_idassert_authcDN.bv_val );
 		}
 		ber_memfree_x( c->value_dn.bv_val, NULL );
-		li->idassert_authcDN = c->value_ndn;
+		li->li_idassert_authcDN = c->value_ndn;
 		BER_BVZERO( &c->value_dn );
 		BER_BVZERO( &c->value_ndn );
 		break;
 
 	case LDAP_BACK_CFG_IDASSERT_PASSWD:
-		switch ( li->idassert_authmethod ) {
+		switch ( li->li_idassert_authmethod ) {
 		case LDAP_AUTH_NONE:
-			li->idassert_authmethod = LDAP_AUTH_SIMPLE;
+			li->li_idassert_authmethod = LDAP_AUTH_SIMPLE;
 			break;
 
 		case LDAP_AUTH_SIMPLE:
@@ -940,13 +925,13 @@ ldap_back_cf_gen( ConfigArgs *c )
 			fprintf( stderr, "%s: line %d: "
 				"\"idassert-passwd <cred>\" incompatible "
 				"with auth method %d.",
-				c->fname, c->lineno, li->idassert_authmethod );
+				c->fname, c->lineno, li->li_idassert_authmethod );
 			return 1;
 		}
-		if ( !BER_BVISNULL( &li->idassert_passwd ) ) {
-			free( li->idassert_passwd.bv_val );
+		if ( !BER_BVISNULL( &li->li_idassert_passwd ) ) {
+			free( li->li_idassert_passwd.bv_val );
 		}
-		ber_str2bv( c->argv[ 1 ], 0, 1, &li->idassert_passwd );
+		ber_str2bv( c->argv[ 1 ], 0, 1, &li->li_idassert_passwd );
 		break;
 
 	case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: {
@@ -967,7 +952,7 @@ ldap_back_cf_gen( ConfigArgs *c )
 #else /* !SLAP_AUTHZ_SYNTAX */
 		ber_str2bv( c->argv[ 1 ], 0, 1, &bv );
 #endif /* !SLAP_AUTHZ_SYNTAX */
-		ber_bvarray_add( &li->idassert_authz, &bv );
+		ber_bvarray_add( &li->li_idassert_authz, &bv );
 		} break;
 
 	case LDAP_BACK_CFG_IDASSERT_METHOD:
@@ -993,13 +978,13 @@ ldap_back_cf_gen( ConfigArgs *c )
 					return 1;
 				}
 
-				li->idassert_mode = idassert_mode[ j ].mask;
+				li->li_idassert_mode = idassert_mode[ j ].mask;
 
 			} else if ( strncasecmp( c->argv[ i ], "authz=", STRLENOF( "authz=" ) ) == 0 ) {
 				char	*argvi = c->argv[ i ] + STRLENOF( "authz=" );
 
 				if ( strcasecmp( argvi, "native" ) == 0 ) {
-					if ( li->idassert_authmethod != LDAP_AUTH_SASL ) {
+					if ( li->li_idassert_authmethod != LDAP_AUTH_SASL ) {
 						fprintf( stderr, "%s: %d: "
 							"\"idassert-bind <args>\": "
 							"authz=\"native\" incompatible "
@@ -1007,10 +992,10 @@ ldap_back_cf_gen( ConfigArgs *c )
 							c->fname, c->lineno );
 						return 1;
 					}
-					li->idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;
+					li->li_idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;
 
 				} else if ( strcasecmp( argvi, "proxyAuthz" ) == 0 ) {
-					li->idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
+					li->li_idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
 
 				} else {
 					fprintf( stderr, "%s: %d: "
@@ -1035,13 +1020,13 @@ ldap_back_cf_gen( ConfigArgs *c )
 
 				for ( j = 0; flags[ j ] != NULL; j++ ) {
 					if ( strcasecmp( flags[ j ], "override" ) == 0 ) {
-						li->idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
+						li->li_idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
 
 					} else if ( strcasecmp( flags[ j ], "prescriptive" ) == 0 ) {
-						li->idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
+						li->li_idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
 
 					} else if ( strcasecmp( flags[ j ], "non-prescriptive" ) == 0 ) {
-						li->idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
+						li->li_idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
 
 					} else {
 						fprintf( stderr, "%s: %d: "
@@ -1054,98 +1039,49 @@ ldap_back_cf_gen( ConfigArgs *c )
 
 				ldap_charray_free( flags );
 
-			} else if ( bindconf_parse( c->argv[ i ], &li->idassert_sb ) ) {
+			} else if ( bindconf_parse( c->argv[ i ], &li->li_idassert ) ) {
 				return 1;
 			}
 		}
 		break;
 
-	case LDAP_BACK_CFG_REBIND: {
-		int	dorebind = 0;
-
-		if ( c->argc == 1 ) {
-			/* legacy */
-			dorebind = 1;
-
-		} else {
-			i = verb_to_mask( c->argv[1], yn_mode );
-			if ( BER_BVISNULL( &yn_mode[i].word ) ) {
-				return 1;
-			}
-			if ( yn_mode[i].mask & LDAP_BACK_C_YES ) {
-				dorebind = 1;
-			}
-		}
-
-		if ( dorebind ) {
-			li->flags |= LDAP_BACK_F_SAVECRED;
-
-		} else {
-			li->flags &= ~LDAP_BACK_F_SAVECRED;
-		}
-		} break;
-
-	case LDAP_BACK_CFG_CHASE: {
-		int	dochase = 0;
-
-		if ( c->argc == 1 ) {
-			/* legacy */
-			dochase = 1;
+	case LDAP_BACK_CFG_REBIND:
+		if ( c->argc == 1 || c->value_int ) {
+			li->li_flags |= LDAP_BACK_F_SAVECRED;
 
 		} else {
-			i = verb_to_mask( c->argv[1], yn_mode );
-			if ( BER_BVISNULL( &yn_mode[i].word ) ) {
-				return 1;
-			}
-			if ( yn_mode[i].mask & LDAP_BACK_C_YES ) {
-				dochase = 1;
-			}
+			li->li_flags &= ~LDAP_BACK_F_SAVECRED;
 		}
+		break;
 
-		if ( dochase ) {
-			li->flags |= LDAP_BACK_F_CHASE_REFERRALS;
+	case LDAP_BACK_CFG_CHASE:
+		if ( c->argc == 1 || c->value_int ) {
+			li->li_flags |= LDAP_BACK_F_CHASE_REFERRALS;
 
 		} else {
-			li->flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
+			li->li_flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
 		}
-		} break;
+		break;
 
 	case LDAP_BACK_CFG_T_F:
 		i = verb_to_mask( c->argv[1], t_f_mode );
 		if ( BER_BVISNULL( &t_f_mode[i].word ) ) {
 			return 1;
 		}
-		li->flags &= ~LDAP_BACK_F_SUPPORT_T_F_MASK;
-		li->flags |= t_f_mode[i].mask;
+		li->li_flags &= ~LDAP_BACK_F_SUPPORT_T_F_MASK;
+		li->li_flags |= t_f_mode[i].mask;
 		break;
 
-	case LDAP_BACK_CFG_WHOAMI: {
-		int	dowhoami = 0;
-
-		if ( c->argc == 1 ) {
-			/* legacy */
-			dowhoami = 1;
-
-		} else {
-			i = verb_to_mask( c->argv[1], yn_mode );
-			if ( BER_BVISNULL( &yn_mode[i].word ) ) {
-				return 1;
-			}
-			if ( yn_mode[i].mask & LDAP_BACK_C_YES ) {
-				dowhoami = 1;
-			}
-		}
-
-		if ( dowhoami ) {
-			li->flags |= LDAP_BACK_F_PROXY_WHOAMI;
-
+	case LDAP_BACK_CFG_WHOAMI:
+		if ( c->argc == 1 || c->value_int ) {
+			li->li_flags |= LDAP_BACK_F_PROXY_WHOAMI;
 			load_extop( (struct berval *)&slap_EXOP_WHOAMI,
 					0, ldap_back_exop_whoami );
 
 		} else {
-			li->flags &= ~LDAP_BACK_F_PROXY_WHOAMI;
+			li->li_flags &= ~LDAP_BACK_F_PROXY_WHOAMI;
 		}
-		} break;
+		break;
 
 	case LDAP_BACK_CFG_TIMEOUT:
 		if ( c->argc < 2 ) {
@@ -1154,23 +1090,21 @@ ldap_back_cf_gen( ConfigArgs *c )
 
 		for ( i = 1; i < c->argc; i++ ) {
 			if ( isdigit( c->argv[ i ][ 0 ] ) ) {
-				char		*next;
 				int		j;
 				unsigned	u;
 
-				u = strtoul( c->argv[ i ], &next, 0 );
-				if ( next == c->argv[ i ] || next[ 0 ] != '\0' ) {
+				if ( lutil_atoux( &u, c->argv[ i ], 0 ) != 0 ) {
 					return 1;
 				}
 
 				for ( j = 0; j < LDAP_BACK_OP_LAST; j++ ) {
-					li->timeout[ j ] = u;
+					li->li_timeout[ j ] = u;
 				}
 
 				continue;
 			}
 
-			if ( slap_cf_aux_table_parse( c->argv[ i ], li->timeout, timeout_table, "slapd-ldap timeout" ) ) {
+			if ( slap_cf_aux_table_parse( c->argv[ i ], li->li_timeout, timeout_table, "slapd-ldap timeout" ) ) {
 				return 1;
 			}
 		}
@@ -1201,6 +1135,9 @@ ldap_back_init_cf( BackendInfo *bi )
 	AttributeDescription	*ad = NULL;
 	const char		*text;
 
+	/* Make sure we don't exceed the bits reserved for userland */
+	config_check_userland( LDAP_BACK_CFG_LAST );
+
 	bi->bi_cf_ocs = ldapocs;
 
 	rc = config_register_schema( ldapcfg, ldapocs );
@@ -1238,400 +1175,6 @@ ldap_back_init_cf( BackendInfo *bi )
 }
 
 
-static int
-parse_idassert( BackendDB *be, const char *fname, int lineno,
-		int argc, char **argv );
-
-static int
-parse_acl_auth( BackendDB *be, const char *fname, int lineno,
-		int argc, char **argv );
-
-int
-ldap_back_db_config(
-		BackendDB	*be,
-		const char	*fname,
-		int		lineno,
-		int		argc,
-		char		**argv )
-{
-	struct ldapinfo	*li = (struct ldapinfo *) be->be_private;
-
-	if ( li == NULL ) {
-		fprintf( stderr, "%s: line %d: ldap backend info is null!\n",
-				fname, lineno );
-		return 1;
-	}
-
-	/* server address to query (no longer supported, use "uri" directive) */
-	if ( strcasecmp( argv[0], "server" ) == 0 ) {
-		fprintf( stderr,
-	"%s: line %d: \"server <address>\" directive is no longer supported.\n",
-					fname, lineno );
-		return 1;
-
-	/* URI of server to query (obsoletes "server" directive) */
-	} else if ( strcasecmp( argv[0], "uri" ) == 0 ) {
-		LDAPURLDesc	*tmpludp;
-#if 0
-		char		**urllist;
-#endif
-		int		urlrc, i;
-
-		if ( argc != 2 ) {
-			fprintf( stderr, "%s: line %d: "
-					"missing uri "
-					"in \"uri <uri>\" line\n",
-					fname, lineno );
-			return 1;
-		}
-		if ( li->url != NULL ) {
-			ch_free( li->url );
-		}
-		if ( li->lud != NULL ) {
-			ldap_free_urllist( li->lud );
-		}
-
-#if 0
-		/* PARANOID: DN and more are not required nor allowed */
-		urlrc = ldap_url_parselist_ext( &li->lud, argv[ 1 ], "\t" );
-#else
-		urlrc = ldap_url_parselist( &li->lud, argv[ 1 ] );
-#endif
-		if ( urlrc != LDAP_URL_SUCCESS ) {
-			char	*why;
-
-			switch ( urlrc ) {
-			case LDAP_URL_ERR_MEM:
-				why = "no memory";
-				break;
-			case LDAP_URL_ERR_PARAM:
-		  		why = "parameter is bad";
-				break;
-			case LDAP_URL_ERR_BADSCHEME:
-				why = "URL doesn't begin with \"[c]ldap[si]://\"";
-				break;
-			case LDAP_URL_ERR_BADENCLOSURE:
-				why = "URL is missing trailing \">\"";
-				break;
-			case LDAP_URL_ERR_BADURL:
-				why = "URL is bad";
-			case LDAP_URL_ERR_BADHOST:
-				why = "host/port is bad";
-				break;
-			case LDAP_URL_ERR_BADATTRS:
-				why = "bad (or missing) attributes";
-				break;
-			case LDAP_URL_ERR_BADSCOPE:
-				why = "scope string is invalid (or missing)";
-				break;
-			case LDAP_URL_ERR_BADFILTER:
-				why = "bad or missing filter";
-				break;
-			case LDAP_URL_ERR_BADEXTS:
-				why = "bad or missing extensions";
-				break;
-			default:
-				why = "unknown reason";
-				break;
-			}
-			fprintf( stderr, "%s: line %d: "
-					"unable to parse uri \"%s\" "
-					"in \"uri <uri>\" line: %s\n",
-					fname, lineno, argv[ 1 ], why );
-			return 1;
-		}
-
-		for ( i = 0, tmpludp = li->lud;
-				tmpludp;
-				i++, tmpludp = tmpludp->lud_next )
-		{
-			if ( ( tmpludp->lud_dn != NULL
-						&& tmpludp->lud_dn[0] != '\0' )
-					|| tmpludp->lud_attrs != NULL
-					/* || tmpludp->lud_scope != LDAP_SCOPE_DEFAULT */
-					|| tmpludp->lud_filter != NULL
-					|| tmpludp->lud_exts != NULL )
-			{
-				fprintf( stderr, "%s: line %d: "
-						"warning, only protocol, "
-						"host and port allowed "
-						"in \"uri <uri>\" statement "
-						"for uri #%d of \"%s\"\n",
-						fname, lineno, i, argv[1] );
-			}
-		}
-
-#if 0
-		for ( i = 0, tmpludp = li->lud;
-				tmpludp;
-				i++, tmpludp = tmpludp->lud_next )
-			/* just count */
-			;
-		urllist = ch_calloc( sizeof( char * ), i + 1 );
-
-		for ( i = 0, tmpludp = li->lud;
-				tmpludp;
-				i++, tmpludp = tmpludp->lud_next )
-		{
-			LDAPURLDesc	tmplud;
-			ber_len_t	oldlen = 0, len;
-
-			tmplud = *tmpludp;
-			tmplud.lud_dn = "";
-			tmplud.lud_attrs = NULL;
-			tmplud.lud_filter = NULL;
-			if ( !ldap_is_ldapi_url( tmplud.lud_scheme ) ) {
-				tmplud.lud_exts = NULL;
-				tmplud.lud_crit_exts = 0;
-			}
-
-			urllist[ i ]  = ldap_url_desc2str( &tmplud );
-
-			if ( urllist[ i ] == NULL ) {
-				fprintf( stderr, "%s: line %d: "
-					"unable to rebuild uri "
-					"in \"uri <uri>\" statement "
-					"for \"%s\"\n",
-					fname, lineno, argv[ 1 ] );
-				return 1;
-			}
-		}
-
-		li->url = ldap_charray2str( urllist, " " );
-		ldap_charray_free( urllist );
-#else
-		li->url = ch_strdup( argv[ 1 ] );
-#endif
-
-	} else if ( strcasecmp( argv[0], "tls" ) == 0 ) {
-		if ( argc != 2 ) {
-			fprintf( stderr,
-		"%s: line %d: \"tls <what>\" needs 1 argument.\n",
-					fname, lineno );
-			return( 1 );
-		}
-
-		/* none */
-		if ( strcasecmp( argv[1], "none" ) == 0 ) {
-			li->flags &= ~LDAP_BACK_F_TLS_MASK;
-	
-		/* try start tls */
-		} else if ( strcasecmp( argv[1], "start" ) == 0 ) {
-			li->flags |= LDAP_BACK_F_TLS_USE_MASK;
-	
-		/* try start tls */
-		} else if ( strcasecmp( argv[1], "try-start" ) == 0 ) {
-			li->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
-			li->flags |= LDAP_BACK_F_USE_TLS;
-	
-		/* propagate start tls */
-		} else if ( strcasecmp( argv[1], "propagate" ) == 0 ) {
-			li->flags |= LDAP_BACK_F_TLS_PROPAGATE_MASK;
-		
-		/* try start tls */
-		} else if ( strcasecmp( argv[1], "try-propagate" ) == 0 ) {
-			li->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
-			li->flags |= LDAP_BACK_F_PROPAGATE_TLS;
-
-		} else {
-			fprintf( stderr,
-		"%s: line %d: \"tls <what>\": unknown argument \"%s\".\n",
-					fname, lineno, argv[1] );
-			return( 1 );
-		}
-	
-	/* remote ACL stuff... */
-	} else if ( strncasecmp( argv[0], "acl-", STRLENOF( "acl-" ) ) == 0
-			|| strncasecmp( argv[0], "bind", STRLENOF( "bind" ) ) == 0 )
-	{
-		/* NOTE: "bind{DN,pw}" was initially used; it's now
-		 * deprected and undocumented, it can be dropped at some
-		 * point, since nobody should be really using it */
-		return parse_acl_auth( be, fname, lineno, argc, argv );
-
-	/* identity assertion stuff... */
-	} else if ( strncasecmp( argv[0], "idassert-", STRLENOF( "idassert-" ) ) == 0
-			|| strncasecmp( argv[0], "proxyauthz", STRLENOF( "proxyauthz" ) ) == 0 )
-	{
-		/* NOTE: "proxyauthz{DN,pw}" was initially used; it's now
-		 * deprected and undocumented, it can be dropped at some
-		 * point, since nobody should be really using it */
-		return parse_idassert( be, fname, lineno, argc, argv );
-
-	/* save bind creds for referral rebinds? */
-	} else if ( strcasecmp( argv[0], "rebind-as-user" ) == 0 ) {
-		switch ( argc ) {
-		case 1:
-			fprintf( stderr,
-	"%s: line %d: \"rebind-as-user {NO|yes}\": use without args is deprecated.\n",
-				fname, lineno );
-	
-			li->flags |= LDAP_BACK_F_SAVECRED;
-			break;
-
-		case 2:
-			if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
-				li->flags |= LDAP_BACK_F_SAVECRED;
-
-			} else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
-				li->flags &= ~LDAP_BACK_F_SAVECRED;
-
-			} else {
-				fprintf( stderr,
-	"%s: line %d: \"rebind-as-user {NO|yes}\": unknown argument \"%s\".\n",
-					fname, lineno, argv[ 1 ] );
-				return( 1 );
-			}
-			break;
-
-		default:
-			fprintf( stderr,
-	"%s: line %d: \"rebind-as-user {NO|yes}\" needs 1 argument.\n",
-					fname, lineno );
-			return( 1 );
-		}
-
-	} else if ( strcasecmp( argv[0], "chase-referrals" ) == 0 ) {
-		if ( argc != 2 ) {
-			fprintf( stderr,
-	"%s: line %d: \"chase-referrals {YES|no}\" needs 1 argument.\n",
-					fname, lineno );
-			return( 1 );
-		}
-
-		/* this is the default; we add it because the default might change... */
-		if ( strcasecmp( argv[1], "yes" ) == 0 ) {
-			li->flags |= LDAP_BACK_F_CHASE_REFERRALS;
-
-		} else if ( strcasecmp( argv[1], "no" ) == 0 ) {
-			li->flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
-
-		} else {
-			fprintf( stderr,
-		"%s: line %d: \"chase-referrals {YES|no}\": unknown argument \"%s\".\n",
-					fname, lineno, argv[1] );
-			return( 1 );
-		}
-	
-	} else if ( strcasecmp( argv[ 0 ], "t-f-support" ) == 0 ) {
-		if ( argc != 2 ) {
-			fprintf( stderr,
-		"%s: line %d: \"t-f-support {NO|yes|discover}\" needs 1 argument.\n",
-					fname, lineno );
-			return( 1 );
-		}
-
-		if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
-			li->flags &= ~(LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER);
-
-		} else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
-			li->flags |= LDAP_BACK_F_SUPPORT_T_F;
-
-		} else if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
-			li->flags |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
-
-		} else {
-			fprintf( stderr,
-	"%s: line %d: \"t-f-support {NO|yes|discover}\": unknown argument \"%s\".\n",
-				fname, lineno, argv[ 1 ] );
-			return 1;
-		}
-
-	/* intercept exop_who_am_i? */
-	} else if ( strcasecmp( argv[0], "proxy-whoami" ) == 0 ) {
-		int	doload_extop = 0;
-
-		switch ( argc ) {
-		case 1:
-			fprintf( stderr,
-	"%s: line %d: \"proxy-whoami {NO|yes}\": use without args is deprecated.\n",
-				fname, lineno );
-	
-			doload_extop = 1;
-			break;
-
-		case 2:
-			if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
-				doload_extop = 1;
-
-			} else if ( strcasecmp( argv[ 1 ], "no" ) != 0 ) {
-				fprintf( stderr,
-	"%s: line %d: \"proxy-whoami {NO|yes}\": unknown argument \"%s\".\n",
-					fname, lineno, argv[ 1 ] );
-				return( 1 );
-			}
-			break;
-
-		default:
-			fprintf( stderr,
-	"%s: line %d: \"proxy-whoami {NO|yes}\" needs 1 argument.\n",
-					fname, lineno );
-			return( 1 );
-		}
-
-		if ( doload_extop ) {
-			li->flags |= LDAP_BACK_F_PROXY_WHOAMI;
-
-			load_extop( (struct berval *)&slap_EXOP_WHOAMI,
-					0, ldap_back_exop_whoami );
-		}
-
-	/* FIXME: legacy: intercept old rewrite/remap directives
-	 * and try to start the rwm overlay */
-	} else if ( strcasecmp( argv[0], "suffixmassage" ) == 0
-			|| strcasecmp( argv[0], "map" ) == 0
-			|| strncasecmp( argv[0], "rewrite", STRLENOF( "rewrite" ) ) == 0 )
-	{
-#if 0
-		fprintf( stderr, "%s: line %d: "
-			"rewrite/remap capabilities have been moved "
-			"to the \"rwm\" overlay; see slapo-rwm(5) "
-			"for details.  I'm trying to do my best "
-			"to preserve backwards compatibility...\n",
-			fname, lineno );
-
-		if ( li->rwm_started == 0 ) {
-			if ( overlay_config( be, "rwm" ) ) {
-				fprintf( stderr, "%s: line %d: "
-					"unable to configure the \"rwm\" "
-					"overlay, required by directive "
-					"\"%s\".\n",
-					fname, lineno, argv[0] );
-#if SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC
-				fprintf( stderr, "\thint: try loading the \"rwm.la\" dynamic module.\n" );
-#endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */
-				return( 1 );
-			}
-
-			fprintf( stderr, "%s: line %d: back-ldap: "
-				"automatically starting \"rwm\" overlay, "
-				"triggered by \"%s\" directive.\n",
-				fname, lineno, argv[ 0 ] );
-
-		/* this is the default; we add it because the default might change... */
-			li->rwm_started = 1;
-
-			return ( *be->bd_info->bi_db_config )( be, fname, lineno, argc, argv );
-		}
-#else
-		fprintf( stderr, "%s: line %d: "
-			"rewrite/remap capabilities have been moved "
-			"to the \"rwm\" overlay; see slapo-rwm(5) "
-			"for details (hint: add \"overlay rwm\" "
-			"and prefix all directives with \"rwm-\").\n",
-			fname, lineno );
-#endif
-
-		return 1;
-	
-	/* anything else */
-	} else {
-		return SLAP_CONF_UNKNOWN;
-	}
-
-	return 0;
-}
-
 static int
 ldap_back_exop_whoami(
 		Operation	*op,
@@ -1654,7 +1197,7 @@ ldap_back_exop_whoami(
 
 	/* if auth'd by back-ldap and request is proxied, forward it */
 	if ( op->o_conn->c_authz_backend && !strcmp(op->o_conn->c_authz_backend->be_type, "ldap" ) && !dn_match(&op->o_ndn, &op->o_conn->c_ndn)) {
-		struct ldapconn *lc;
+		ldapconn_t	*lc;
 
 		LDAPControl c, *ctrls[2] = {NULL, NULL};
 		LDAPMessage *res;
@@ -1683,10 +1226,10 @@ retry:
 					&rs->sr_err);
 				if ( rs->sr_err == LDAP_SERVER_DOWN && doretry ) {
 					doretry = 0;
-					if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) )
+					if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) )
 						goto retry;
 				}
-				ldap_back_freeconn( op, lc );
+				ldap_back_freeconn( op, lc, 1 );
 				lc = NULL;
 
 			} else {
@@ -1724,562 +1267,3 @@ retry:
 }
 
 
-static int
-parse_idassert(
-    BackendDB	*be,
-    const char	*fname,
-    int		lineno,
-    int		argc,
-    char	**argv
-)
-{
-	struct ldapinfo	*li = (struct ldapinfo *) be->be_private;
-
-	/* identity assertion mode */
-	if ( strcasecmp( argv[0], "idassert-mode" ) == 0 ) {
-		if ( argc < 2 ) {
-			Debug( LDAP_DEBUG_ANY,
-				"%s: line %d: illegal args number %d in \"idassert-mode <args> [<flag> [...]]\" line.\n",
-				fname, lineno, argc );
-			return 1;
-		}
-
-		if ( strcasecmp( argv[1], "legacy" ) == 0 ) {
-			/* will proxyAuthz as client's identity only if bound */
-			li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
-
-		} else if ( strcasecmp( argv[1], "self" ) == 0 ) {
-			/* will proxyAuthz as client's identity */
-			li->idassert_mode = LDAP_BACK_IDASSERT_SELF;
-
-		} else if ( strcasecmp( argv[1], "anonymous" ) == 0 ) {
-			/* will proxyAuthz as anonymous */
-			li->idassert_mode = LDAP_BACK_IDASSERT_ANONYMOUS;
-
-		} else if ( strcasecmp( argv[1], "none" ) == 0 ) {
-			/* will not proxyAuthz */
-			li->idassert_mode = LDAP_BACK_IDASSERT_NOASSERT;
-
-		} else {
-			struct berval	id;
-			int		rc;
-
-			/* will proxyAuthz as argv[1] */
-			ber_str2bv( argv[1], 0, 0, &id );
-
-			if ( strncasecmp( id.bv_val, "u:", STRLENOF( "u:" ) ) == 0 ) {
-				/* force lowercase... */
-				id.bv_val[0] = 'u';
-				li->idassert_mode = LDAP_BACK_IDASSERT_OTHERID;
-				ber_dupbv( &li->idassert_authzID, &id );
-
-			} else {
-				struct berval	dn;
-
-				/* default is DN? */
-				if ( strncasecmp( id.bv_val, "dn:", STRLENOF( "dn:" ) ) == 0 ) {
-					id.bv_val += STRLENOF( "dn:" );
-					id.bv_len -= STRLENOF( "dn:" );
-				}
-
-				rc = dnNormalize( 0, NULL, NULL, &id, &dn, NULL );
-				if ( rc != LDAP_SUCCESS ) {
-					Debug( LDAP_DEBUG_ANY,
-						"%s: line %d: idassert ID \"%s\" is not a valid DN\n",
-						fname, lineno, argv[1] );
-					return 1;
-				}
-
-				li->idassert_authzID.bv_len = STRLENOF( "dn:" ) + dn.bv_len;
-				li->idassert_authzID.bv_val = ch_malloc( li->idassert_authzID.bv_len + 1 );
-				AC_MEMCPY( li->idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
-				AC_MEMCPY( &li->idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], dn.bv_val, dn.bv_len + 1 );
-				ch_free( dn.bv_val );
-
-				li->idassert_mode = LDAP_BACK_IDASSERT_OTHERDN;
-			}
-		}
-
-		for ( argc -= 2, argv += 2; argc--; argv++ ) {
-			if ( strcasecmp( argv[0], "override" ) == 0 ) {
-				li->idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
-
-			} else {
-				Debug( LDAP_DEBUG_ANY,
-					"%s: line %d: unknown flag \"%s\" "
-					"in \"idassert-mode <args> "
-					"[<flags>]\" line.\n",
-					fname, lineno, argv[0] );
-				return 1;
-			}
-		}
-
-	/* name to use for proxyAuthz propagation */
-	} else if ( strcasecmp( argv[0], "idassert-authcdn" ) == 0
-			|| strcasecmp( argv[0], "proxyauthzdn" ) == 0 )
-	{
-		struct berval	dn;
-		int		rc;
-
-		/* FIXME: "proxyauthzdn" is no longer documented, and
-		 * temporarily supported for backwards compatibility */
-
-		if ( argc != 2 ) {
-			fprintf( stderr,
-	"%s: line %d: missing name in \"%s <name>\" line\n",
-			    fname, lineno, argv[0] );
-			return( 1 );
-		}
-
-		if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
-			fprintf( stderr, "%s: line %d: "
-					"authcDN already defined; replacing...\n",
-					fname, lineno );
-			ch_free( li->idassert_authcDN.bv_val );
-		}
-		
-		ber_str2bv( argv[1], 0, 0, &dn );
-		rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_authcDN, NULL );
-		if ( rc != LDAP_SUCCESS ) {
-			Debug( LDAP_DEBUG_ANY,
-				"%s: line %d: idassert ID \"%s\" is not a valid DN\n",
-				fname, lineno, argv[1] );
-			return 1;
-		}
-
-	/* password to use for proxyAuthz propagation */
-	} else if ( strcasecmp( argv[0], "idassert-passwd" ) == 0
-			|| strcasecmp( argv[0], "proxyauthzpw" ) == 0 )
-	{
-		/* FIXME: "proxyauthzpw" is no longer documented, and
-		 * temporarily supported for backwards compatibility */
-
-		if ( argc != 2 ) {
-			fprintf( stderr,
-	"%s: line %d: missing password in \"%s <password>\" line\n",
-			    fname, lineno, argv[0] );
-			return( 1 );
-		}
-
-		if ( !BER_BVISNULL( &li->idassert_passwd ) ) {
-			fprintf( stderr, "%s: line %d: "
-					"passwd already defined; replacing...\n",
-					fname, lineno );
-			ch_free( li->idassert_passwd.bv_val );
-		}
-		
-		ber_str2bv( argv[1], 0, 1, &li->idassert_passwd );
-
-	/* rules to accept identity assertion... */
-	} else if ( strcasecmp( argv[0], "idassert-authzFrom" ) == 0 ) {
-		struct berval	rule;
-
-		ber_str2bv( argv[1], 0, 1, &rule );
-
-		ber_bvarray_add( &li->idassert_authz, &rule );
-
-	} else if ( strcasecmp( argv[0], "idassert-method" ) == 0 ) {
-		char	*argv1;
-
-		if ( argc < 2 ) {
-			fprintf( stderr,
-	"%s: line %d: missing method in \"%s <method>\" line\n",
-			    fname, lineno, argv[0] );
-			return( 1 );
-		}
-
-		argv1 = argv[1];
-		if ( strncasecmp( argv1, "bindmethod=", STRLENOF( "bindmethod=" ) ) == 0 ) {
-			argv1 += STRLENOF( "bindmethod=" );
-		}
-
-		if ( strcasecmp( argv1, "none" ) == 0 ) {
-			/* FIXME: is this at all useful? */
-			li->idassert_authmethod = LDAP_AUTH_NONE;
-
-			if ( argc != 2 ) {
-				fprintf( stderr,
-	"%s: line %d: trailing args in \"%s %s ...\" line ignored\"\n",
-					fname, lineno, argv[0], argv[1] );
-			}
-
-		} else if ( strcasecmp( argv1, "simple" ) == 0 ) {
-			int	arg;
-
-			for ( arg = 2; arg < argc; arg++ ) {
-				if ( strncasecmp( argv[arg], "authcdn=", STRLENOF( "authcdn=" ) ) == 0 ) {
-					char		*val = argv[arg] + STRLENOF( "authcdn=" );
-					struct berval	dn;
-					int		rc;
-
-					if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL authcDN already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->idassert_authcDN.bv_val );
-					}
-					if ( strncasecmp( argv[arg], "dn:", STRLENOF( "dn:" ) ) == 0 ) {
-						val += STRLENOF( "dn:" );
-					}
-
-					ber_str2bv( val, 0, 0, &dn );
-					rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_authcDN, NULL );
-					if ( rc != LDAP_SUCCESS ) {
-						Debug( LDAP_DEBUG_ANY,
-							"%s: line %d: SASL authcdn \"%s\" is not a valid DN\n",
-							fname, lineno, val );
-						return 1;
-					}
-
-				} else if ( strncasecmp( argv[arg], "cred=", STRLENOF( "cred=" ) ) == 0 ) {
-					char	*val = argv[arg] + STRLENOF( "cred=" );
-
-					if ( !BER_BVISNULL( &li->idassert_passwd ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL cred already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->idassert_passwd.bv_val );
-					}
-					ber_str2bv( val, 0, 1, &li->idassert_passwd );
-
-				} else {
-					fprintf( stderr, "%s: line %d: "
-							"unknown parameter %s\n",
-		    					fname, lineno, argv[arg] );
-					return 1;
-				}
-			}
-
-			li->idassert_authmethod = LDAP_AUTH_SIMPLE;
-
-		} else if ( strcasecmp( argv1, "sasl" ) == 0 ) {
-#ifdef HAVE_CYRUS_SASL
-			int	arg;
-
-			for ( arg = 2; arg < argc; arg++ ) {
-				if ( strncasecmp( argv[arg], "mech=", STRLENOF( "mech=" ) ) == 0 ) {
-					char	*val = argv[arg] + STRLENOF( "mech=" );
-
-					if ( !BER_BVISNULL( &li->idassert_sasl_mech ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL mech already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->idassert_sasl_mech.bv_val );
-					}
-					ber_str2bv( val, 0, 1, &li->idassert_sasl_mech );
-
-				} else if ( strncasecmp( argv[arg], "realm=", STRLENOF( "realm=" ) ) == 0 ) {
-					char	*val = argv[arg] + STRLENOF( "realm=" );
-
-					if ( !BER_BVISNULL( &li->idassert_sasl_realm ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL realm already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->idassert_sasl_realm.bv_val );
-					}
-					ber_str2bv( val, 0, 1, &li->idassert_sasl_realm );
-
-				} else if ( strncasecmp( argv[arg], "authcdn=", STRLENOF( "authcdn=" ) ) == 0 ) {
-					char		*val = argv[arg] + STRLENOF( "authcdn=" );
-					struct berval	dn;
-					int		rc;
-
-					if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL authcDN already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->idassert_authcDN.bv_val );
-					}
-					if ( strncasecmp( argv[arg], "dn:", STRLENOF( "dn:" ) ) == 0 ) {
-						val += STRLENOF( "dn:" );
-					}
-
-					ber_str2bv( val, 0, 0, &dn );
-					rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_authcDN, NULL );
-					if ( rc != LDAP_SUCCESS ) {
-						Debug( LDAP_DEBUG_ANY,
-							"%s: line %d: SASL authcdn \"%s\" is not a valid DN\n",
-							fname, lineno, val );
-						return 1;
-					}
-
-				} else if ( strncasecmp( argv[arg], "authcid=", STRLENOF( "authcid=" ) ) == 0 ) {
-					char	*val = argv[arg] + STRLENOF( "authcid=" );
-
-					if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL authcID already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->idassert_authcID.bv_val );
-					}
-					if ( strncasecmp( argv[arg], "u:", STRLENOF( "u:" ) ) == 0 ) {
-						val += STRLENOF( "u:" );
-					}
-					ber_str2bv( val, 0, 1, &li->idassert_authcID );
-
-				} else if ( strncasecmp( argv[arg], "cred=", STRLENOF( "cred=" ) ) == 0 ) {
-					char	*val = argv[arg] + STRLENOF( "cred=" );
-
-					if ( !BER_BVISNULL( &li->idassert_passwd ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL cred already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->idassert_passwd.bv_val );
-					}
-					ber_str2bv( val, 0, 1, &li->idassert_passwd );
-
-				} else if ( strncasecmp( argv[arg], "authz=", STRLENOF( "authz=" ) ) == 0 ) {
-					char	*val = argv[arg] + STRLENOF( "authz=" );
-
-					if ( strcasecmp( val, "proxyauthz" ) == 0 ) {
-						li->idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
-
-					} else if ( strcasecmp( val, "native" ) == 0 ) {
-						li->idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;
-
-					} else {
-						fprintf( stderr, "%s: line %d: "
-							"unknown authz mode \"%s\"\n",
-							fname, lineno, val );
-						return 1;
-					}
-
-				} else {
-					fprintf( stderr, "%s: line %d: "
-							"unknown SASL parameter %s\n",
-		    					fname, lineno, argv[arg] );
-					return 1;
-				}
-			}
-
-			li->idassert_authmethod = LDAP_AUTH_SASL;
-
-#else /* !HAVE_CYRUS_SASL */
-			fprintf( stderr, "%s: line %d: "
-					"compile --with-cyrus-sasl to enable SASL auth\n",
-					fname, lineno );
-			return 1;
-#endif /* !HAVE_CYRUS_SASL */
-
-		} else {
-			fprintf( stderr, "%s: line %d: "
-					"unhandled idassert-method method %s\n",
-					fname, lineno, argv[1] );
-			return 1;
-		}
-
-	} else {
-		return SLAP_CONF_UNKNOWN;
-	}
-
-	return 0;
-}
-
-static int
-parse_acl_auth(
-    BackendDB	*be,
-    const char	*fname,
-    int		lineno,
-    int		argc,
-    char	**argv
-)
-{
-	struct ldapinfo	*li = (struct ldapinfo *) be->be_private;
-
-	/* name to use for remote ACL access */
-	if ( strcasecmp( argv[0], "acl-authcdn" ) == 0
-			|| strcasecmp( argv[0], "binddn" ) == 0 )
-	{
-		struct berval	dn;
-		int		rc;
-
-		/* FIXME: "binddn" is no longer documented, and
-		 * temporarily supported for backwards compatibility */
-
-		if ( argc != 2 ) {
-			fprintf( stderr,
-	"%s: line %d: missing name in \"%s <name>\" line\n",
-			    fname, lineno, argv[0] );
-			return( 1 );
-		}
-
-		if ( !BER_BVISNULL( &li->acl_authcDN ) ) {
-			fprintf( stderr, "%s: line %d: "
-					"authcDN already defined; replacing...\n",
-					fname, lineno );
-			ch_free( li->acl_authcDN.bv_val );
-		}
-		
-		ber_str2bv( argv[1], 0, 0, &dn );
-		rc = dnNormalize( 0, NULL, NULL, &dn, &li->acl_authcDN, NULL );
-		if ( rc != LDAP_SUCCESS ) {
-			Debug( LDAP_DEBUG_ANY,
-				"%s: line %d: acl ID \"%s\" is not a valid DN\n",
-				fname, lineno, argv[1] );
-			return 1;
-		}
-
-	/* password to use for remote ACL access */
-	} else if ( strcasecmp( argv[0], "acl-passwd" ) == 0
-			|| strcasecmp( argv[0], "bindpw" ) == 0 )
-	{
-		/* FIXME: "bindpw" is no longer documented, and
-		 * temporarily supported for backwards compatibility */
-
-		if ( argc != 2 ) {
-			fprintf( stderr,
-	"%s: line %d: missing password in \"%s <password>\" line\n",
-			    fname, lineno, argv[0] );
-			return( 1 );
-		}
-
-		if ( !BER_BVISNULL( &li->acl_passwd ) ) {
-			fprintf( stderr, "%s: line %d: "
-					"passwd already defined; replacing...\n",
-					fname, lineno );
-			ch_free( li->acl_passwd.bv_val );
-		}
-		
-		ber_str2bv( argv[1], 0, 1, &li->acl_passwd );
-
-	} else if ( strcasecmp( argv[0], "acl-method" ) == 0 ) {
-		char	*argv1;
-
-		if ( argc < 2 ) {
-			fprintf( stderr,
-	"%s: line %d: missing method in \"%s <method>\" line\n",
-			    fname, lineno, argv[0] );
-			return( 1 );
-		}
-
-		argv1 = argv[1];
-		if ( strncasecmp( argv1, "bindmethod=", STRLENOF( "bindmethod=" ) ) == 0 ) {
-			argv1 += STRLENOF( "bindmethod=" );
-		}
-
-		if ( strcasecmp( argv1, "none" ) == 0 ) {
-			/* FIXME: is this at all useful? */
-			li->acl_authmethod = LDAP_AUTH_NONE;
-
-			if ( argc != 2 ) {
-				fprintf( stderr,
-	"%s: line %d: trailing args in \"%s %s ...\" line ignored\"\n",
-					fname, lineno, argv[0], argv[1] );
-			}
-
-		} else if ( strcasecmp( argv1, "simple" ) == 0 ) {
-			li->acl_authmethod = LDAP_AUTH_SIMPLE;
-
-			if ( argc != 2 ) {
-				fprintf( stderr,
-	"%s: line %d: trailing args in \"%s %s ...\" line ignored\"\n",
-					fname, lineno, argv[0], argv[1] );
-			}
-
-		} else if ( strcasecmp( argv1, "sasl" ) == 0 ) {
-#ifdef HAVE_CYRUS_SASL
-			int	arg;
-
-			for ( arg = 2; arg < argc; arg++ ) {
-				if ( strncasecmp( argv[arg], "mech=", STRLENOF( "mech=" ) ) == 0 ) {
-					char	*val = argv[arg] + STRLENOF( "mech=" );
-
-					if ( !BER_BVISNULL( &li->acl_sasl_mech ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL mech already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->acl_sasl_mech.bv_val );
-					}
-					ber_str2bv( val, 0, 1, &li->acl_sasl_mech );
-
-				} else if ( strncasecmp( argv[arg], "realm=", STRLENOF( "realm=" ) ) == 0 ) {
-					char	*val = argv[arg] + STRLENOF( "realm=" );
-
-					if ( !BER_BVISNULL( &li->acl_sasl_realm ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL realm already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->acl_sasl_realm.bv_val );
-					}
-					ber_str2bv( val, 0, 1, &li->acl_sasl_realm );
-
-				} else if ( strncasecmp( argv[arg], "authcdn=", STRLENOF( "authcdn=" ) ) == 0 ) {
-					char		*val = argv[arg] + STRLENOF( "authcdn=" );
-					struct berval	dn;
-					int		rc;
-
-					if ( !BER_BVISNULL( &li->acl_authcDN ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL authcDN already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->acl_authcDN.bv_val );
-					}
-					if ( strncasecmp( argv[arg], "dn:", STRLENOF( "dn:" ) ) == 0 ) {
-						val += STRLENOF( "dn:" );
-					}
-
-					ber_str2bv( val, 0, 0, &dn );
-					rc = dnNormalize( 0, NULL, NULL, &dn, &li->acl_authcDN, NULL );
-					if ( rc != LDAP_SUCCESS ) {
-						Debug( LDAP_DEBUG_ANY,
-							"%s: line %d: SASL authcdn \"%s\" is not a valid DN\n",
-							fname, lineno, val );
-						return 1;
-					}
-
-				} else if ( strncasecmp( argv[arg], "authcid=", STRLENOF( "authcid=" ) ) == 0 ) {
-					char	*val = argv[arg] + STRLENOF( "authcid=" );
-
-					if ( !BER_BVISNULL( &li->acl_authcID ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL authcID already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->acl_authcID.bv_val );
-					}
-					if ( strncasecmp( argv[arg], "u:", STRLENOF( "u:" ) ) == 0 ) {
-						val += STRLENOF( "u:" );
-					}
-					ber_str2bv( val, 0, 1, &li->acl_authcID );
-
-				} else if ( strncasecmp( argv[arg], "cred=", STRLENOF( "cred=" ) ) == 0 ) {
-					char	*val = argv[arg] + STRLENOF( "cred=" );
-
-					if ( !BER_BVISNULL( &li->acl_passwd ) ) {
-						fprintf( stderr, "%s: line %d: "
-								"SASL cred already defined; replacing...\n",
-			    					fname, lineno );
-						ch_free( li->acl_passwd.bv_val );
-					}
-					ber_str2bv( val, 0, 1, &li->acl_passwd );
-
-				} else {
-					fprintf( stderr, "%s: line %d: "
-							"unknown SASL parameter %s\n",
-		    					fname, lineno, argv[arg] );
-					return 1;
-				}
-			}
-
-			li->acl_authmethod = LDAP_AUTH_SASL;
-
-#else /* !HAVE_CYRUS_SASL */
-			fprintf( stderr, "%s: line %d: "
-					"compile --with-cyrus-sasl to enable SASL auth\n",
-					fname, lineno );
-			return 1;
-#endif /* !HAVE_CYRUS_SASL */
-
-		} else {
-			fprintf( stderr, "%s: line %d: "
-					"unhandled acl-method method %s\n",
-					fname, lineno, argv[1] );
-			return 1;
-		}
-
-	} else {
-		return SLAP_CONF_UNKNOWN;
-	}
-
-	return 0;
-}
-
diff --git a/servers/slapd/back-ldap/delete.c b/servers/slapd/back-ldap/delete.c
index dcce01ae742f16d8541641e4953bea5af39e0e92..03afa19083375d692a1b16e5efba411d15c8b727 100644
--- a/servers/slapd/back-ldap/delete.c
+++ b/servers/slapd/back-ldap/delete.c
@@ -36,9 +36,9 @@ ldap_back_delete(
 		Operation	*op,
 		SlapReply	*rs )
 {
-	struct ldapinfo	*li = (struct ldapinfo *)op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
 
-	struct ldapconn	*lc;
+	ldapconn_t	*lc;
 	ber_int_t	msgid;
 	LDAPControl	**ctrls = NULL;
 	int		do_retry = 1;
@@ -62,10 +62,10 @@ retry:
 	rs->sr_err = ldap_delete_ext( lc->lc_ld, op->o_req_ndn.bv_val,
 			ctrls, NULL, &msgid );
 	rc = ldap_back_op_result( lc, op, rs, msgid,
-		li->timeout[ LDAP_BACK_OP_DELETE], LDAP_BACK_SENDRESULT );
+		li->li_timeout[ LDAP_BACK_OP_DELETE], LDAP_BACK_SENDRESULT );
 	if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
 		do_retry = 0;
-		if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
+		if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 			goto retry;
 		}
 	}
diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c
index fde2c489b013af76e0cd0ab009216fb2aa52f5e4..dae58547f0a4ecb339a406c3d759e66ece8f6215 100644
--- a/servers/slapd/back-ldap/extended.c
+++ b/servers/slapd/back-ldap/extended.c
@@ -48,7 +48,7 @@ ldap_back_extended(
 	for ( i = 0; exop_table[i].extended != NULL; i++ ) {
 		if ( bvmatch( &exop_table[i].oid, &op->oq_extended.rs_reqoid ) )
 		{
-			struct ldapconn	*lc;
+			ldapconn_t	*lc;
 			LDAPControl	**oldctrls = NULL;
 			int		rc;
 
@@ -98,7 +98,7 @@ ldap_back_exop_passwd(
 		Operation	*op,
 		SlapReply	*rs )
 {
-	struct ldapconn	*lc;
+	ldapconn_t	*lc;
 	req_pwdexop_s	*qpw = &op->oq_pwdexop;
 	LDAPMessage	*res;
 	ber_int_t	msgid;
@@ -124,7 +124,7 @@ retry:
 	if ( rc == LDAP_SUCCESS ) {
 		if ( ldap_result( lc->lc_ld, msgid, 1, NULL, &res ) == -1 ) {
 			ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc );
-			ldap_back_freeconn( op, lc );
+			ldap_back_freeconn( op, lc, 0 );
 			lc = NULL;
 
 		} else {
@@ -135,6 +135,7 @@ retry:
 					(char **)&rs->sr_matched,
 					(char **)&rs->sr_text,
 					NULL, NULL, 0 );
+#ifndef LDAP_NULL_IS_NULL
 			if ( rs->sr_matched && rs->sr_matched[ 0 ] == '\0' ) {
 				free( (char *)rs->sr_matched );
 				rs->sr_matched = NULL;
@@ -143,6 +144,7 @@ retry:
 				free( (char *)rs->sr_text );
 				rs->sr_text = NULL;
 			}
+#endif /* LDAP_NULL_IS_NULL */
 			if ( rc == LDAP_SUCCESS ) {
 				if ( rs->sr_err == LDAP_SUCCESS ) {
 					struct berval	newpw;
@@ -168,7 +170,7 @@ retry:
 		rs->sr_err = slap_map_api2result( rs );
 		if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
 			do_retry = 0;
-			if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
+			if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 				goto retry;
 			}
 		}
diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c
index f250f6d0d99a1d2cd42403eb7e7bd8abbeddabf2..013e62306eac081dff0c4805b4713fbacb3fd4dc 100644
--- a/servers/slapd/back-ldap/init.c
+++ b/servers/slapd/back-ldap/init.c
@@ -80,45 +80,45 @@ ldap_back_initialize( BackendInfo *bi )
 int
 ldap_back_db_init( Backend *be )
 {
-	struct ldapinfo	*li;
+	ldapinfo_t	*li;
 
-	li = (struct ldapinfo *)ch_calloc( 1, sizeof( struct ldapinfo ) );
+	li = (ldapinfo_t *)ch_calloc( 1, sizeof( ldapinfo_t ) );
 	if ( li == NULL ) {
  		return -1;
  	}
 
-	BER_BVZERO( &li->acl_authcID );
-	BER_BVZERO( &li->acl_authcDN );
-	BER_BVZERO( &li->acl_passwd );
+	BER_BVZERO( &li->li_acl_authcID );
+	BER_BVZERO( &li->li_acl_authcDN );
+	BER_BVZERO( &li->li_acl_passwd );
 
-	li->acl_authmethod = LDAP_AUTH_NONE;
-	BER_BVZERO( &li->acl_sasl_mech );
-	li->acl_sb.sb_tls = SB_TLS_DEFAULT;
+	li->li_acl_authmethod = LDAP_AUTH_NONE;
+	BER_BVZERO( &li->li_acl_sasl_mech );
+	li->li_acl.sb_tls = SB_TLS_DEFAULT;
 
-	li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
+	li->li_idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
 
-	BER_BVZERO( &li->idassert_authcID );
-	BER_BVZERO( &li->idassert_authcDN );
-	BER_BVZERO( &li->idassert_passwd );
+	BER_BVZERO( &li->li_idassert_authcID );
+	BER_BVZERO( &li->li_idassert_authcDN );
+	BER_BVZERO( &li->li_idassert_passwd );
 
-	BER_BVZERO( &li->idassert_authzID );
+	BER_BVZERO( &li->li_idassert_authzID );
 
-	li->idassert_authmethod = LDAP_AUTH_NONE;
-	BER_BVZERO( &li->idassert_sasl_mech );
-	li->idassert_sb.sb_tls = SB_TLS_DEFAULT;
+	li->li_idassert_authmethod = LDAP_AUTH_NONE;
+	BER_BVZERO( &li->li_idassert_sasl_mech );
+	li->li_idassert.sb_tls = SB_TLS_DEFAULT;
 
 	/* by default, use proxyAuthz control on each operation */
-	li->idassert_flags = LDAP_BACK_AUTH_PRESCRIPTIVE;
+	li->li_idassert_flags = LDAP_BACK_AUTH_PRESCRIPTIVE;
 
-	li->idassert_authz = NULL;
+	li->li_idassert_authz = NULL;
 
 	/* initialize flags */
-	li->flags = LDAP_BACK_F_CHASE_REFERRALS;
+	li->li_flags = LDAP_BACK_F_CHASE_REFERRALS;
 
 	/* initialize version */
-	li->version = LDAP_VERSION3;
+	li->li_version = LDAP_VERSION3;
 
-	ldap_pvt_thread_mutex_init( &li->conn_mutex );
+	ldap_pvt_thread_mutex_init( &li->li_conninfo.lai_mutex );
 
 	be->be_private = li;
 	SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_NOLASTMOD;
@@ -131,19 +131,19 @@ ldap_back_db_init( Backend *be )
 int
 ldap_back_db_open( BackendDB *be )
 {
-	struct ldapinfo	*li = (struct ldapinfo *)be->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *)be->be_private;
 
 	Debug( LDAP_DEBUG_TRACE,
 		"ldap_back_db_open: URI=%s\n",
-		li->url != NULL ? li->url : "", 0, 0 );
+		li->li_uri != NULL ? li->li_uri : "", 0, 0 );
 
 	/* by default, use proxyAuthz control on each operation */
-	switch ( li->idassert_mode ) {
+	switch ( li->li_idassert_mode ) {
 	case LDAP_BACK_IDASSERT_LEGACY:
 	case LDAP_BACK_IDASSERT_SELF:
 		/* however, since admin connections are pooled and shared,
 		 * only static authzIDs can be native */
-		li->idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
+		li->li_idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
 		break;
 
 	default:
@@ -159,7 +159,6 @@ ldap_back_db_open( BackendDB *be )
 		 * the normalized one.  See ITS#3406 */
 		struct berval	filter,
 				base = BER_BVC( "cn=Databases," SLAPD_MONITOR );
-		struct berval	vals[ 2 ];
 		Attribute	a = { 0 };
 
 		filter.bv_len = STRLENOF( "(&(namingContexts:distinguishedNameMatch:=)(monitoredInfo=ldap))" )
@@ -170,10 +169,8 @@ ldap_back_db_open( BackendDB *be )
 				be->be_nsuffix[ 0 ].bv_val );
 
 		a.a_desc = slap_schema.si_ad_labeledURI;
-		ber_str2bv( li->url, 0, 0, &vals[ 0 ] );
-		BER_BVZERO( &vals[ 1 ] );
-		a.a_vals = vals;
-		a.a_nvals = vals;
+		a.a_vals = li->li_bvuri;
+		a.a_nvals = li->li_bvuri;
 		if ( monitor_back_register_entry_attrs( NULL, &a, NULL, &base, LDAP_SCOPE_SUBTREE, &filter ) ) {
 			/* error */
 		}
@@ -182,16 +179,16 @@ ldap_back_db_open( BackendDB *be )
 	}
 #endif /* SLAPD_MONITOR */
 
-	if ( li->flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER ) {
+	if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER ) {
 		int		rc;
 
-		li->flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
+		li->li_flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
 
-		rc = slap_discover_feature( li->url, li->version,
+		rc = slap_discover_feature( li->li_uri, li->li_version,
 				slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
 				LDAP_FEATURE_ABSOLUTE_FILTERS );
 		if ( rc == LDAP_COMPARE_TRUE ) {
-			li->flags |= LDAP_BACK_F_SUPPORT_T_F;
+			li->li_flags |= LDAP_BACK_F_SUPPORT_T_F;
 		}
 	}
 
@@ -201,7 +198,7 @@ ldap_back_db_open( BackendDB *be )
 void
 ldap_back_conn_free( void *v_lc )
 {
-	struct ldapconn	*lc = v_lc;
+	ldapconn_t	*lc = v_lc;
 
 	if ( lc->lc_ld != NULL ) {	
 		ldap_unbind_ext( lc->lc_ld, NULL, NULL );
@@ -224,75 +221,73 @@ ldap_back_db_destroy(
     Backend	*be
 )
 {
-	struct ldapinfo	*li;
-
 	if ( be->be_private ) {
-		li = ( struct ldapinfo * )be->be_private;
+		ldapinfo_t	*li = ( ldapinfo_t * )be->be_private;
 
-		ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+		ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
 
-		if ( li->url != NULL ) {
-			ch_free( li->url );
-			li->url = NULL;
-		}
-		if ( li->lud ) {
-			ldap_free_urldesc( li->lud );
-			li->lud = NULL;
+		if ( li->li_uri != NULL ) {
+			ch_free( li->li_uri );
+			li->li_uri = NULL;
+
+			assert( li->li_bvuri != NULL );
+			ber_bvarray_free( li->li_bvuri );
+			li->li_bvuri = NULL;
 		}
-		if ( !BER_BVISNULL( &li->acl_authcID ) ) {
-			ch_free( li->acl_authcID.bv_val );
-			BER_BVZERO( &li->acl_authcID );
+		if ( !BER_BVISNULL( &li->li_acl_authcID ) ) {
+			ch_free( li->li_acl_authcID.bv_val );
+			BER_BVZERO( &li->li_acl_authcID );
 		}
-		if ( !BER_BVISNULL( &li->acl_authcDN ) ) {
-			ch_free( li->acl_authcDN.bv_val );
-			BER_BVZERO( &li->acl_authcDN );
+		if ( !BER_BVISNULL( &li->li_acl_authcDN ) ) {
+			ch_free( li->li_acl_authcDN.bv_val );
+			BER_BVZERO( &li->li_acl_authcDN );
 		}
-		if ( !BER_BVISNULL( &li->acl_passwd ) ) {
-			ch_free( li->acl_passwd.bv_val );
-			BER_BVZERO( &li->acl_passwd );
+		if ( !BER_BVISNULL( &li->li_acl_passwd ) ) {
+			ch_free( li->li_acl_passwd.bv_val );
+			BER_BVZERO( &li->li_acl_passwd );
 		}
-		if ( !BER_BVISNULL( &li->acl_sasl_mech ) ) {
-			ch_free( li->acl_sasl_mech.bv_val );
-			BER_BVZERO( &li->acl_sasl_mech );
+		if ( !BER_BVISNULL( &li->li_acl_sasl_mech ) ) {
+			ch_free( li->li_acl_sasl_mech.bv_val );
+			BER_BVZERO( &li->li_acl_sasl_mech );
 		}
-		if ( !BER_BVISNULL( &li->acl_sasl_realm ) ) {
-			ch_free( li->acl_sasl_realm.bv_val );
-			BER_BVZERO( &li->acl_sasl_realm );
+		if ( !BER_BVISNULL( &li->li_acl_sasl_realm ) ) {
+			ch_free( li->li_acl_sasl_realm.bv_val );
+			BER_BVZERO( &li->li_acl_sasl_realm );
 		}
-		if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
-			ch_free( li->idassert_authcID.bv_val );
-			BER_BVZERO( &li->idassert_authcID );
+		if ( !BER_BVISNULL( &li->li_idassert_authcID ) ) {
+			ch_free( li->li_idassert_authcID.bv_val );
+			BER_BVZERO( &li->li_idassert_authcID );
 		}
-		if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
-			ch_free( li->idassert_authcDN.bv_val );
-			BER_BVZERO( &li->idassert_authcDN );
+		if ( !BER_BVISNULL( &li->li_idassert_authcDN ) ) {
+			ch_free( li->li_idassert_authcDN.bv_val );
+			BER_BVZERO( &li->li_idassert_authcDN );
 		}
-		if ( !BER_BVISNULL( &li->idassert_passwd ) ) {
-			ch_free( li->idassert_passwd.bv_val );
-			BER_BVZERO( &li->idassert_passwd );
+		if ( !BER_BVISNULL( &li->li_idassert_passwd ) ) {
+			ch_free( li->li_idassert_passwd.bv_val );
+			BER_BVZERO( &li->li_idassert_passwd );
 		}
-		if ( !BER_BVISNULL( &li->idassert_authzID ) ) {
-			ch_free( li->idassert_authzID.bv_val );
-			BER_BVZERO( &li->idassert_authzID );
+		if ( !BER_BVISNULL( &li->li_idassert_authzID ) ) {
+			ch_free( li->li_idassert_authzID.bv_val );
+			BER_BVZERO( &li->li_idassert_authzID );
 		}
-		if ( !BER_BVISNULL( &li->idassert_sasl_mech ) ) {
-			ch_free( li->idassert_sasl_mech.bv_val );
-			BER_BVZERO( &li->idassert_sasl_mech );
+		if ( !BER_BVISNULL( &li->li_idassert_sasl_mech ) ) {
+			ch_free( li->li_idassert_sasl_mech.bv_val );
+			BER_BVZERO( &li->li_idassert_sasl_mech );
 		}
-		if ( !BER_BVISNULL( &li->idassert_sasl_realm ) ) {
-			ch_free( li->idassert_sasl_realm.bv_val );
-			BER_BVZERO( &li->idassert_sasl_realm );
+		if ( !BER_BVISNULL( &li->li_idassert_sasl_realm ) ) {
+			ch_free( li->li_idassert_sasl_realm.bv_val );
+			BER_BVZERO( &li->li_idassert_sasl_realm );
 		}
-		if ( li->idassert_authz != NULL ) {
-			ber_bvarray_free( li->idassert_authz );
-			li->idassert_authz = NULL;
+		if ( li->li_idassert_authz != NULL ) {
+			ber_bvarray_free( li->li_idassert_authz );
+			li->li_idassert_authz = NULL;
 		}
-                if ( li->conntree ) {
-			avl_free( li->conntree, ldap_back_conn_free );
+               	if ( li->li_conninfo.lai_tree ) {
+			avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free );
 		}
 
-		ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
-		ldap_pvt_thread_mutex_destroy( &li->conn_mutex );
+		ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
+		ldap_pvt_thread_mutex_destroy( &li->li_conninfo.lai_mutex );
 	}
 
 	ch_free( be->be_private );
diff --git a/servers/slapd/back-ldap/modify.c b/servers/slapd/back-ldap/modify.c
index ae0820ff53971259ec4c282f4bc08dd2b4697411..c5889fb4f5db388419e107ce64c39783284d8c6d 100644
--- a/servers/slapd/back-ldap/modify.c
+++ b/servers/slapd/back-ldap/modify.c
@@ -36,9 +36,9 @@ ldap_back_modify(
 		Operation	*op,
 		SlapReply	*rs )
 {
-	struct ldapinfo	*li = (struct ldapinfo *)op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
 
-	struct ldapconn	*lc;
+	ldapconn_t	*lc;
 	LDAPMod		**modv = NULL,
 			*mods = NULL;
 	Modifications	*ml;
@@ -110,10 +110,10 @@ retry:
 	rs->sr_err = ldap_modify_ext( lc->lc_ld, op->o_req_ndn.bv_val, modv,
 			ctrls, NULL, &msgid );
 	rc = ldap_back_op_result( lc, op, rs, msgid,
-		li->timeout[ LDAP_BACK_OP_MODIFY], LDAP_BACK_SENDRESULT );
+		li->li_timeout[ LDAP_BACK_OP_MODIFY], LDAP_BACK_SENDRESULT );
 	if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
 		do_retry = 0;
-		if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
+		if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 			goto retry;
 		}
 	}
diff --git a/servers/slapd/back-ldap/modrdn.c b/servers/slapd/back-ldap/modrdn.c
index 254038570e5317184841f28823b300fd841c5167..17836b4aa17b61c8376c6175996fa61b056447b7 100644
--- a/servers/slapd/back-ldap/modrdn.c
+++ b/servers/slapd/back-ldap/modrdn.c
@@ -36,9 +36,9 @@ ldap_back_modrdn(
 		Operation	*op,
  		SlapReply	*rs )
 {
-	struct ldapinfo	*li = (struct ldapinfo *)op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *)op->o_bd->be_private;
 
-	struct ldapconn *lc;
+	ldapconn_t	*lc;
 	ber_int_t	msgid;
 	LDAPControl	**ctrls = NULL;
 	int		do_retry = 1;
@@ -70,10 +70,10 @@ retry:
 			op->orr_newrdn.bv_val, newSup,
 			op->orr_deleteoldrdn, ctrls, NULL, &msgid );
 	rc = ldap_back_op_result( lc, op, rs, msgid,
-		li->timeout[ LDAP_BACK_OP_MODRDN ], LDAP_BACK_SENDRESULT );
+		li->li_timeout[ LDAP_BACK_OP_MODRDN ], LDAP_BACK_SENDRESULT );
 	if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
 		do_retry = 0;
-		if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
+		if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 			goto retry;
 		}
 	}
diff --git a/servers/slapd/back-ldap/proto-ldap.h b/servers/slapd/back-ldap/proto-ldap.h
index f705bf521c9c43bf62ad24a4e70abc7ef04b07c8..4c911da13d92ebd54cc4ee0dc1bca8c85fb1e959 100644
--- a/servers/slapd/back-ldap/proto-ldap.h
+++ b/servers/slapd/back-ldap/proto-ldap.h
@@ -32,7 +32,6 @@ extern BI_destroy		ldap_back_destroy;
 extern BI_db_init		ldap_back_db_init;
 extern BI_db_open		ldap_back_db_open;
 extern BI_db_destroy		ldap_back_db_destroy;
-extern BI_db_config		ldap_back_db_config;
 
 extern BI_op_bind		ldap_back_bind;
 extern BI_op_search		ldap_back_search;
@@ -48,15 +47,14 @@ extern BI_connection_destroy	ldap_back_conn_destroy;
 
 extern BI_entry_get_rw		ldap_back_entry_get;
 
-int ldap_back_freeconn( Operation *op, struct ldapconn *lc );
-struct ldapconn *ldap_back_getconn(struct slap_op *op, struct slap_rep *rs, ldap_back_send_t sendok);
-void ldap_back_release_conn( struct slap_op *op, struct slap_rep *rs, struct ldapconn *lc );
-int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok);
-int ldap_back_retry(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok);
-int ldap_back_map_result(SlapReply *rs);
-int ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
-	ber_int_t msgid, time_t timeout, ldap_back_send_t sendok);
-int	back_ldap_LTX_init_module(int argc, char *argv[]);
+int ldap_back_freeconn( Operation *op, ldapconn_t *lc, int dolock );
+ldapconn_t *ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok );
+void ldap_back_release_conn( Operation *op, SlapReply *rs, ldapconn_t *lc );
+int ldap_back_dobind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok );
+int ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok );
+int ldap_back_map_result( SlapReply *rs );
+int ldap_back_op_result( ldapconn_t *lc, Operation *op, SlapReply *rs,
+	ber_int_t msgid, time_t timeout, ldap_back_send_t sendok );
 
 int ldap_back_init_cf( BackendInfo *bi );
 
@@ -66,7 +64,7 @@ extern void ldap_back_conn_free( void *c );
 
 extern int
 ldap_back_proxy_authz_ctrl(
-		struct ldapconn	*lc,
+		ldapconn_t	*lc,
 		Operation	*op,
 		SlapReply	*rs,
 		LDAPControl	***pctrls );
diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c
index 625f3b05500b436bf3502f7a085ca973091ac80f..1a30eb6960e81ca78596bff6596a93c6c5385bff 100644
--- a/servers/slapd/back-ldap/search.c
+++ b/servers/slapd/back-ldap/search.c
@@ -49,7 +49,7 @@ ldap_back_munge_filter(
 	Operation	*op,
 	struct berval	*filter )
 {
-	struct ldapinfo	*li = (struct ldapinfo *) op->o_bd->be_private;
+	ldapinfo_t	*li = (ldapinfo_t *) op->o_bd->be_private;
 
 	char		*ptr;
 	int		gotit = 0;
@@ -75,7 +75,7 @@ ldap_back_munge_filter(
 
 		if ( strncmp( ptr, bv_true.bv_val, bv_true.bv_len ) == 0 ) {
 			oldbv = &bv_true;
-			if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) {
+			if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F ) {
 				newbv = &bv_t;
 
 			} else {
@@ -85,7 +85,7 @@ ldap_back_munge_filter(
 		} else if ( strncmp( ptr, bv_false.bv_val, bv_false.bv_len ) == 0 )
 		{
 			oldbv = &bv_false;
-			if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) {
+			if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F ) {
 				newbv = &bv_f;
 
 			} else {
@@ -141,7 +141,7 @@ ldap_back_search(
 		Operation	*op,
 		SlapReply	*rs )
 {
-	struct ldapconn *lc;
+	ldapconn_t	*lc;
 	struct timeval	tv;
 	time_t		stoptime = (time_t)-1;
 	LDAPMessage	*res,
@@ -216,18 +216,24 @@ retry:
 			op->ors_slimit, &msgid );
 
 	if ( rs->sr_err != LDAP_SUCCESS ) {
-fail:;
 		switch ( rs->sr_err ) {
 		case LDAP_SERVER_DOWN:
 			if ( do_retry ) {
 				do_retry = 0;
-				if ( ldap_back_retry( lc, op, rs, LDAP_BACK_DONTSEND ) ) {
+				if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) {
 					goto retry;
 				}
 			}
-			rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND );
-			ldap_back_freeconn( op, lc );
-			lc = NULL;
+			if ( lc == NULL ) {
+				/* reset by ldap_back_retry ... */
+				rs->sr_err = slap_map_api2result( rs );
+
+			} else {
+				rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND );
+				ldap_back_freeconn( op, lc, 0 );
+				lc = NULL;
+			}
+				
 			goto finish;
 
 		case LDAP_FILTER_ERROR:
@@ -280,7 +286,6 @@ fail:;
 		} else if ( rc == LDAP_RES_SEARCH_ENTRY ) {
 			Entry		ent = { 0 };
 			struct berval	bdn = BER_BVNULL;
-			int		abort = 0;
 
 			do_retry = 0;
 
@@ -291,7 +296,7 @@ fail:;
 				rs->sr_attrs = op->ors_attrs;
 				rs->sr_operational_attrs = NULL;
 				rs->sr_flags = 0;
-				abort = send_search_entry( op, rs );
+				rc = rs->sr_err = send_search_entry( op, rs );
 				if ( !BER_BVISNULL( &ent.e_name ) ) {
 					assert( ent.e_name.bv_val != bdn.bv_val );
 					free( ent.e_name.bv_val );
@@ -304,8 +309,12 @@ fail:;
 				entry_clean( &ent );
 			}
 			ldap_msgfree( res );
-			if ( abort ) {
-				ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL );
+			if ( rc != LDAP_SUCCESS ) {
+				if ( rc == LDAP_UNAVAILABLE ) {
+					rc = rs->sr_err = LDAP_OTHER;
+				} else {
+					ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL );
+				}
 				goto finish;
 			}
 
@@ -396,13 +405,22 @@ fail:;
 			}
 
 			if ( match.bv_val != NULL ) {
+#ifndef LDAP_NULL_IS_NULL
 				if ( match.bv_val[ 0 ] == '\0' ) {
 					LDAP_FREE( match.bv_val );
 					BER_BVZERO( &match );
-				} else {
+				} else
+#endif /* LDAP_NULL_IS_NULL */
+				{
 					match.bv_len = strlen( match.bv_val );
 				}
 			}
+#ifndef LDAP_NULL_IS_NULL
+			if ( rs->sr_text != NULL && rs->sr_text[ 0 ] == '\0' ) {
+				LDAP_FREE( (char *)rs->sr_text );
+				rs->sr_text = NULL;
+			}
+#endif /* LDAP_NULL_IS_NULL */
 
 			/* cleanup */
 			if ( references ) {
@@ -417,12 +435,13 @@ fail:;
 	if ( rc == -1 ) {
 		if ( do_retry ) {
 			do_retry = 0;
-			if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
+			if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
 				goto retry;
 			}
 		}
 		rs->sr_err = LDAP_SERVER_DOWN;
-		goto fail;
+		rs->sr_err = slap_map_api2result( rs );
+		goto finish;
 	}
 
 	/*
@@ -688,7 +707,7 @@ ldap_back_entry_get(
 		Entry			**ent
 )
 {
-	struct ldapconn *lc;
+	ldapconn_t	*lc;
 	int		rc = 1,
 			do_not_cache;
 	struct berval	bdn;
@@ -746,7 +765,7 @@ retry:
 	if ( rc != LDAP_SUCCESS ) {
 		if ( rc == LDAP_SERVER_DOWN && do_retry ) {
 			do_retry = 0;
-			if ( ldap_back_retry( lc, op, &rs, LDAP_BACK_DONTSEND ) ) {
+			if ( ldap_back_retry( &lc, op, &rs, LDAP_BACK_DONTSEND ) ) {
 				goto retry;
 			}
 		}
diff --git a/servers/slapd/back-ldap/unbind.c b/servers/slapd/back-ldap/unbind.c
index e097d0ae7a725f9338e4c85a94b10f1d0d4f4777..6cc2c797da04f483bbb2869c571858fa2ddcafcd 100644
--- a/servers/slapd/back-ldap/unbind.c
+++ b/servers/slapd/back-ldap/unbind.c
@@ -38,8 +38,8 @@ ldap_back_conn_destroy(
 		Connection	*conn
 )
 {
-	struct ldapinfo	*li = (struct ldapinfo *) be->be_private;
-	struct ldapconn *lc = NULL, lc_curr;
+	ldapinfo_t	*li = (ldapinfo_t *) be->be_private;
+	ldapconn_t	*lc = NULL, lc_curr;
 
 	Debug( LDAP_DEBUG_TRACE,
 		"=>ldap_back_conn_destroy: fetching conn %ld\n",
@@ -48,9 +48,9 @@ ldap_back_conn_destroy(
 	lc_curr.lc_conn = conn;
 	lc_curr.lc_local_ndn = conn->c_ndn;
 	
-	ldap_pvt_thread_mutex_lock( &li->conn_mutex );
-	lc = avl_delete( &li->conntree, (caddr_t)&lc_curr, ldap_back_conn_cmp );
-	ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+	ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
+	lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)&lc_curr, ldap_back_conn_cmp );
+	ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
 
 	if ( lc ) {
 		Debug( LDAP_DEBUG_TRACE,
diff --git a/servers/slapd/back-ldbm/config.c b/servers/slapd/back-ldbm/config.c
index 2a0a5759ee2ebf6ca9567dcd006b84f068613dbe..5309f2e0c39adf623fd1ef0e2b8eaf5c509dd739 100644
--- a/servers/slapd/back-ldbm/config.c
+++ b/servers/slapd/back-ldbm/config.c
@@ -23,6 +23,7 @@
 
 #include "slap.h"
 #include "back-ldbm.h"
+#include "lutil.h"
 
 int
 ldbm_back_db_config(
@@ -62,7 +63,12 @@ ldbm_back_db_config(
 			    fname, lineno );
 			return( 1 );
 		}
-		li->li_mode = strtol( argv[1], NULL, 0 );
+		if ( lutil_atoix( &li->li_mode, argv[1], 0 ) != 0 ) {
+			fprintf( stderr,
+			"%s: line %d: unable to parse mode=\"%s\" in \"mode <mode>\" line\n",
+			    fname, lineno, argv[1] );
+			return( 1 );
+		}
 
 	/* attribute to index */
 	} else if ( strcasecmp( argv[0], "index" ) == 0 ) {
@@ -91,7 +97,12 @@ ldbm_back_db_config(
 			    fname, lineno );
 			return( 1 );
 		}
-		li->li_cache.c_maxsize = atoi( argv[1] );
+		if ( lutil_atoi( &li->li_cache.c_maxsize, argv[1] ) != 0 ) {
+			fprintf( stderr,
+		"%s: line %d: unable to parse cachesize \"%s\"\n",
+			    fname, lineno, argv[1] );
+			return( 1 );
+		}
 
 	/* size of each dbcache in bytes */
 	} else if ( strcasecmp( argv[0], "dbcachesize" ) == 0 ) {
@@ -101,7 +112,12 @@ ldbm_back_db_config(
 			    fname, lineno );
 			return( 1 );
 		}
-		li->li_dbcachesize = atoi( argv[1] );
+		if ( lutil_atoi( &li->li_dbcachesize, argv[1] ) ) {
+			fprintf( stderr,
+		"%s: line %d: unable to parse dbcachesize \"%s\"\n",
+			    fname, lineno, argv[1] );
+			return( 1 );
+		}
 
 	/* no locking (not safe) */
 	} else if ( strcasecmp( argv[0], "dbnolocking" ) == 0 ) {
@@ -124,9 +140,7 @@ ldbm_back_db_config(
 			return 1;
 		}
 
-		i = atoi( argv[1] );
-
-		if( i < 0 ) {
+		if ( lutil_atoi( &i, argv[1] ) != 0 || i < 0 ) {
 			Debug( LDAP_DEBUG_ANY,
     "%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n",
 			    fname, lineno, i );
@@ -136,8 +150,7 @@ ldbm_back_db_config(
 		li->li_dbsyncfreq = i;
 
 		if ( argc > 2 ) {
-			i = atoi( argv[2] );
-			if ( i < 0 ) {
+			if ( lutil_atoi( &i, argv[2] ) != 0 || i < 0 ) {
 				Debug( LDAP_DEBUG_ANY,
 	    "%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n",
 				    fname, lineno, i );
@@ -147,8 +160,7 @@ ldbm_back_db_config(
 		}
 
 		if ( argc > 3 ) {
-			i = atoi( argv[3] );
-			if ( i <= 0 ) {
+			if ( lutil_atoi( &i, argv[3] ) != 0 || i <= 0 ) {
 				Debug( LDAP_DEBUG_ANY,
 	    "%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n",
 				    fname, lineno, i );
diff --git a/servers/slapd/back-ldbm/init.c b/servers/slapd/back-ldbm/init.c
index 1ceb19bc5cd1516b9610cf9bb30e55ed6860c553..0f82638dcaab9736e716b0ce88cc36169d190da8 100644
--- a/servers/slapd/back-ldbm/init.c
+++ b/servers/slapd/back-ldbm/init.c
@@ -32,9 +32,7 @@ ldbm_back_initialize(
 {
 	static char *controls[] = {
 		LDAP_CONTROL_MANAGEDSAIT,
-#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
 		LDAP_CONTROL_X_PERMISSIVE_MODIFY,
-#endif
 		NULL
 	};
 
diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c
index 47e7886ee1a945c131ec298c6c3fd7f866b90fb2..455e31ccd942bdcf5e081bd0591a2e907f5a473a 100644
--- a/servers/slapd/back-ldbm/search.c
+++ b/servers/slapd/back-ldbm/search.c
@@ -417,40 +417,31 @@ searchit:
 			{
 				scopeok = dnIsSuffix( &e->e_nname, &realbase );
 
-#ifdef LDAP_SCOPE_SUBORDINATE
 			} else if ( !scopeok &&
 				op->ors_scope == LDAP_SCOPE_SUBORDINATE )
 			{
 				scopeok = !dn_match( &e->e_nname, &realbase )
 					&& dnIsSuffix( &e->e_nname, &realbase );
-#endif
 
 			} else {
 				scopeok = 1;
 			}
 
 			if ( scopeok ) {
-				/* check size limit */
-				if ( --op->ors_slimit == -1 ) {
-					cache_return_entry_r( &li->li_cache, e );
-					rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
-					rs->sr_entry = NULL;
-					send_ldap_result( op, rs );
-					rc = LDAP_SUCCESS;
-					goto done;
-				}
-
 				if (e) {
 					rs->sr_flags = 0;
-					result = send_search_entry( op, rs );
-
-					switch (result) {
-					case 0:		/* entry sent ok */
-						break;
-					case 1:		/* entry not sent */
-						break;
-					case -1:	/* connection closed */
+					rs->sr_err = send_search_entry( op, rs );
+
+					switch ( rs->sr_err ) {
+					case LDAP_UNAVAILABLE:	/* connection closed */
+						cache_return_entry_r( &li->li_cache, e );
+						rc = LDAP_SUCCESS;
+						goto done;
+					case LDAP_SIZELIMIT_EXCEEDED:
 						cache_return_entry_r( &li->li_cache, e );
+						rc = rs->sr_err;
+						rs->sr_entry = NULL;
+						send_ldap_result( op, rs );
 						rc = LDAP_SUCCESS;
 						goto done;
 					}
diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h
index 87ba1badf0bbe48ccfaa7d6da5bcee593ba15aa6..8ac932bb9996585ff2ebf15b3f8bda0929675444 100644
--- a/servers/slapd/back-meta/back-meta.h
+++ b/servers/slapd/back-meta/back-meta.h
@@ -236,8 +236,8 @@ typedef struct metadncache_t {
 	Avlnode			*tree;
 
 #define META_DNCACHE_DISABLED   (0)
-#define META_DNCACHE_FOREVER    (-1)
-	long int		ttl;  /* seconds; 0: no cache, -1: no expiry */
+#define META_DNCACHE_FOREVER    ((time_t)(-1))
+	time_t			ttl;  /* seconds; 0: no cache, -1: no expiry */
 } metadncache_t;
 
 typedef struct metacandidates_t {
@@ -257,18 +257,18 @@ typedef struct metainfo_t {
 
 	metadncache_t		mi_cache;
 	
-	ldap_pvt_thread_mutex_t	mi_conn_mutex;
-	Avlnode			*mi_conntree;
+	ldap_avl_info_t		mi_conninfo;
 
-	unsigned		flags;
+	unsigned		mi_flags;
+#define	li_flags		mi_flags
 /* uses flags as defined in <back-ldap/back-ldap.h> */
 #define	META_BACK_F_ONERR_STOP		0x00010000U
 #define	META_BACK_F_DEFER_ROOTDN_BIND	0x00020000U
 
-#define	META_BACK_ONERR_STOP(mi)	( (mi)->flags & META_BACK_F_ONERR_STOP )
+#define	META_BACK_ONERR_STOP(mi)	( (mi)->mi_flags & META_BACK_F_ONERR_STOP )
 #define	META_BACK_ONERR_CONTINUE(mi)	( !META_BACK_ONERR_CONTINUE( (mi) ) )
 
-#define META_BACK_DEFER_ROOTDN_BIND(mi)	( (mi)->flags & META_BACK_F_DEFER_ROOTDN_BIND )
+#define META_BACK_DEFER_ROOTDN_BIND(mi)	( (mi)->mi_flags & META_BACK_F_DEFER_ROOTDN_BIND )
 
 	int			mi_version;
 	time_t			mi_timeout[ LDAP_BACK_OP_LAST ];
diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c
index 3d6867433629ca8c98c80199a9241cd0fac56f29..ccd2a6c27583bb1f16e32d113ef723aa2c9eb3e2 100644
--- a/servers/slapd/back-meta/bind.c
+++ b/servers/slapd/back-meta/bind.c
@@ -206,22 +206,22 @@ meta_back_bind( Operation *op, SlapReply *rs )
 
 			/* wait for all other ops to release the connection */
 retry_lock:;
-			ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+			ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
 			if ( mc->mc_refcnt > 1 ) {
-				ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+				ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 				ldap_pvt_thread_yield();
 				goto retry_lock;
 			}
 
 			assert( mc->mc_refcnt == 1 );
-			mc = avl_delete( &mi->mi_conntree, (caddr_t)mc,
+			mc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
 				meta_back_conn_cmp );
 			assert( mc != NULL );
 
 			ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn );
-			lerr = avl_insert( &mi->mi_conntree, (caddr_t)mc,
+			lerr = avl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
 				meta_back_conn_cmp, meta_back_conn_dup );
-			ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+			ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 			if ( lerr == -1 ) {
 				for ( i = 0; i < mi->mi_ntargets; ++i ) {
 					if ( mc->mc_conns[ i ].msc_ld != NULL ) {
@@ -548,7 +548,7 @@ retry:;
 				 * to avoid circular loops; mc_mutex is set
 				 * by the caller */
 				if ( dolock ) {
-					ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+					ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
 				}
 
 				if ( mc->mc_refcnt == 1 ) {
@@ -571,7 +571,7 @@ retry:;
 				}
 
 				if ( dolock ) {
-					ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+					ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 				}
 
 				if ( rc == LDAP_SUCCESS ) {
diff --git a/servers/slapd/back-meta/candidates.c b/servers/slapd/back-meta/candidates.c
index 1cc8d83a87a38e46f49892ada7463ca6f6511ba1..a73cc1516ebff04ed229b5aeb0b4480cf70fd437 100644
--- a/servers/slapd/back-meta/candidates.c
+++ b/servers/slapd/back-meta/candidates.c
@@ -70,13 +70,11 @@ meta_back_is_candidate(
 		default:
 			return META_CANDIDATE;
 
-#ifdef LDAP_SCOPE_SUBORDINATE
 		case LDAP_SCOPE_SUBORDINATE:
 			if ( ndn->bv_len > nsuffix->bv_len ) {
 				return META_CANDIDATE;
 			}
 			break;
-#endif /* LDAP_SCOPE_SUBORDINATE */
 
 		/* nearly useless; not allowed by config */
 		case LDAP_SCOPE_ONELEVEL:
diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c
index 58cba850961b9414c76d9d50d43508298b74ef26..3516b82e359492d4a75da45679ae28f29a316388 100644
--- a/servers/slapd/back-meta/config.c
+++ b/servers/slapd/back-meta/config.c
@@ -95,12 +95,7 @@ meta_back_db_config(
 {
 	metainfo_t	*mi = ( metainfo_t * )be->be_private;
 
-	if ( mi == NULL ) {
-		fprintf( stderr, 
-	"%s: line %d: meta backend info is null!\n",
-		    fname, lineno );
-		return 1;
-	}
+	assert( mi != NULL );
 
 	/* URI of server to query */
 	if ( strcasecmp( argv[ 0 ], "uri" ) == 0 ) {
@@ -115,27 +110,27 @@ meta_back_db_config(
 		
 		switch ( argc ) {
 		case 1:
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: missing URI "
 	"in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 
 		case 2:
 			break;
 
 		default:
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: too many args "
 	"in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 
 		if ( be->be_nsuffix == NULL ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: the suffix must be defined before any target.\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 		
@@ -144,23 +139,23 @@ meta_back_db_config(
 		mi->mi_targets = ( metatarget_t * )ch_realloc( mi->mi_targets, 
 			sizeof( metatarget_t ) * mi->mi_ntargets );
 		if ( mi->mi_targets == NULL ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: out of memory while storing server name"
 	" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 
 		if ( new_target( &mi->mi_targets[ i ] ) != 0 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: unable to init server"
 	" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 
 		mi->mi_targets[ i ].mt_nretries = mi->mi_nretries;
-		mi->mi_targets[ i ].mt_flags = mi->flags;
+		mi->mi_targets[ i ].mt_flags = mi->mi_flags;
 		mi->mi_targets[ i ].mt_version = mi->mi_version;
 
 		for ( c = 0; c < LDAP_BACK_OP_LAST; c++ ) {
@@ -171,10 +166,10 @@ meta_back_db_config(
 		 * uri MUST be legal!
 		 */
 		if ( ldap_url_parselist_ext( &ludp, argv[ 1 ], "\t" ) != LDAP_SUCCESS ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: unable to parse URI"
 	" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 
@@ -182,10 +177,10 @@ meta_back_db_config(
 		 * uri MUST have the <dn> part!
 		 */
 		if ( ludp->lud_dn == NULL ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: missing <naming context> "
 	" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 
 		} else if ( ludp->lud_dn[ 0 ] == '\0' ) {
@@ -198,10 +193,10 @@ meta_back_db_config(
 			}
 
 			if ( BER_BVISNULL( &be->be_nsuffix[ j ] ) ) {
-				fprintf( stderr,
+				Debug( LDAP_DEBUG_ANY,
 		"%s: line %d: missing <naming context> "
 		" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
-					fname, lineno );
+					fname, lineno, 0 );
 				return 1;
 			}
 		}
@@ -213,9 +208,9 @@ meta_back_db_config(
 		rc = dnPrettyNormal( NULL, &dn, &mi->mi_targets[ i ].mt_psuffix,
 			&mi->mi_targets[ i ].mt_nsuffix, NULL );
 		if( rc != LDAP_SUCCESS ) {
-			fprintf( stderr, "%s: line %d: "
-					"target '%s' DN is invalid\n",
-					fname, lineno, argv[ 1 ] );
+			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+				"target \"%s\" DN is invalid\n",
+				fname, lineno, argv[ 1 ] );
 			return( 1 );
 		}
 
@@ -227,26 +222,24 @@ meta_back_db_config(
 			break;
 
 		case LDAP_SCOPE_SUBTREE:
-#ifdef LDAP_SCOPE_SUBORDINATE
 		case LDAP_SCOPE_SUBORDINATE:
-#endif /* LDAP_SCOPE_SUBORDINATE */
 			mi->mi_targets[ i ].mt_scope = ludp->lud_scope;
 			break;
 
 		default:
-			fprintf( stderr, "%s: line %d: "
-					"invalid scope for target '%s'\n",
-					fname, lineno, argv[ 1 ] );
+			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+				"invalid scope for target \"%s\"\n",
+				fname, lineno, argv[ 1 ] );
 			return( 1 );
 		}
 
 		/* check all, to apply the scope check on the first one */
 		for ( tmpludp = ludp; tmpludp; tmpludp = tmpludp->lud_next ) {
 			if ( tmpludp->lud_dn != NULL && tmpludp->lud_dn[ 0 ] != '\0' ) {
-				fprintf( stderr, "%s: line %d: "
-						"multiple URIs must have "
-						"no DN part\n",
-					fname, lineno );
+				Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+					"multiple URIs must have "
+					"no DN part\n",
+					fname, lineno, 0 );
 				return( 1 );
 
 			}
@@ -255,8 +248,8 @@ meta_back_db_config(
 		mi->mi_targets[ i ].mt_uri = ldap_url_list2urls( ludp );
 		ldap_free_urllist( ludp );
 		if ( mi->mi_targets[ i ].mt_uri == NULL) {
-			fprintf( stderr, "%s: line %d: no memory?\n",
-					fname, lineno );
+			Debug( LDAP_DEBUG_ANY, "%s: line %d: no memory?\n",
+				fname, lineno, 0 );
 			return( 1 );
 		}
 		
@@ -265,10 +258,10 @@ meta_back_db_config(
 		 */
 #if 0 /* too strict a constraint */
 		if ( select_backend( &mi->mi_targets[ i ].suffix, 0, 0 ) != be ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: <naming context> of URI does not refer to current backend"
 	" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 #else
@@ -276,10 +269,10 @@ meta_back_db_config(
 		 * uri MUST be a branch of a suffix!
 		 */
 		if ( select_backend( &mi->mi_targets[ i ].mt_nsuffix, 0, 0 ) == NULL ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: <naming context> of URI does not resolve to a backend"
 	" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 #endif
@@ -290,62 +283,85 @@ meta_back_db_config(
 		
 		if ( argc == 1 ) {
  			if ( i < 0 ) {
-				fprintf( stderr,
+				Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: \"default-target\" alone need be"
        	" inside a \"uri\" directive\n",
-					fname, lineno );
+					fname, lineno, 0 );
 				return 1;
 			}
 			mi->mi_defaulttarget = i;
+
 		} else {
 			if ( strcasecmp( argv[ 1 ], "none" ) == 0 ) {
 				if ( i >= 0 ) {
-					fprintf( stderr,
+					Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: \"default-target none\""
        	" should go before uri definitions\n",
-						fname, lineno );
+						fname, lineno, 0 );
 				}
 				mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE;
 
 			} else {
-				char	*next;
-				int	n = strtol( argv[ 1 ], &next, 10 );
-				if ( n < 0 || n >= i - 1 ) {
-					fprintf( stderr,
+				
+				if ( lutil_atoi( &mi->mi_defaulttarget, argv[ 1 ] ) != 0
+					|| mi->mi_defaulttarget < 0
+					|| mi->mi_defaulttarget >= i - 1 )
+				{
+					Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: illegal target number %d\n",
-						fname, lineno, n );
+						fname, lineno, mi->mi_defaulttarget );
 					return 1;
 				}
-				mi->mi_defaulttarget = n;
 			}
 		}
 		
 	/* ttl of dn cache */
 	} else if ( strcasecmp( argv[ 0 ], "dncache-ttl" ) == 0 ) {
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: missing ttl in \"dncache-ttl <ttl>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 		
 		if ( strcasecmp( argv[ 1 ], "forever" ) == 0 ) {
 			mi->mi_cache.ttl = META_DNCACHE_FOREVER;
+
 		} else if ( strcasecmp( argv[ 1 ], "disabled" ) == 0 ) {
 			mi->mi_cache.ttl = META_DNCACHE_DISABLED;
+
 		} else {
-			mi->mi_cache.ttl = atol( argv[ 1 ] );
+			unsigned long	t;
+
+			if ( lutil_parse_time( argv[ 1 ], &t ) != 0 ) {
+				Debug( LDAP_DEBUG_ANY,
+	"%s: line %d: unable to parse ttl \"%s\" in \"dncache-ttl <ttl>\" line\n",
+					fname, lineno, argv[ 1 ] );
+				return 1;
+			}
+			mi->mi_cache.ttl = (time_t)t;
 		}
 
 	/* network timeout when connecting to ldap servers */
 	} else if ( strcasecmp( argv[ 0 ], "network-timeout" ) == 0 ) {
+		unsigned long	t;
+
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: missing network timeout in \"network-timeout <seconds>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
+			return 1;
+		}
+
+		if ( lutil_parse_time( argv[ 1 ], &t ) ) {
+			Debug( LDAP_DEBUG_ANY,
+	"%s: line %d: unable to parse timeout \"%s\" in \"network-timeout <seconds>\" line\n",
+				fname, lineno, argv[ 1 ] );
 			return 1;
+
 		}
-		mi->mi_network_timeout = atol(argv[ 1 ]);
+
+		mi->mi_network_timeout = (int)t;
 
 	/* name to use for meta_back_group */
 	} else if ( strcasecmp( argv[ 0 ], "acl-authcDN" ) == 0
@@ -355,24 +371,24 @@ meta_back_db_config(
 		struct berval	dn;
 
 		if ( i < 0 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: need \"uri\" directive first\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 		
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: missing name in \"binddn <name>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 
 		if ( strcasecmp( argv[ 0 ], "binddn" ) == 0 ) {
-			fprintf( stderr, "%s: line %d: "
+			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 				"\"binddn\" statement is deprecated; "
 				"use \"acl-authcDN\" instead\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			/* FIXME: some day we'll need to throw an error */
 		}
 
@@ -381,7 +397,7 @@ meta_back_db_config(
 		if ( dnNormalize( 0, NULL, NULL, &dn, &mi->mi_targets[ i ].mt_binddn,
 			NULL ) != LDAP_SUCCESS )
 		{
-			fprintf( stderr, "%s: line %d: "
+			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 					"bind DN '%s' is invalid\n",
 					fname, lineno, argv[ 1 ] );
 			return( 1 );
@@ -394,24 +410,24 @@ meta_back_db_config(
 		int 		i = mi->mi_ntargets - 1;
 
 		if ( i < 0 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: need \"uri\" directive first\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 		
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: missing password in \"bindpw <password>\" line\n",
-			    fname, lineno );
+			    fname, lineno, 0 );
 			return 1;
 		}
 
 		if ( strcasecmp( argv[ 0 ], "bindpw" ) == 0 ) {
-			fprintf( stderr, "%s: line %d: "
+			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 				"\"bindpw\" statement is deprecated; "
 				"use \"acl-passwd\" instead\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			/* FIXME: some day we'll need to throw an error */
 		}
 
@@ -420,30 +436,30 @@ meta_back_db_config(
 	/* save bind creds for referral rebinds? */
 	} else if ( strcasecmp( argv[ 0 ], "rebind-as-user" ) == 0 ) {
 		if ( argc > 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: \"rebind-as-user {NO|yes}\" takes 1 argument.\n",
-			    fname, lineno );
+			    fname, lineno, 0 );
 			return( 1 );
 		}
 
 		if ( argc == 1 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: deprecated use of \"rebind-as-user {FALSE|true}\" with no arguments.\n",
-			    fname, lineno );
-			mi->flags |= LDAP_BACK_F_SAVECRED;
+			    fname, lineno, 0 );
+			mi->mi_flags |= LDAP_BACK_F_SAVECRED;
 
 		} else {
 			switch ( check_true_false( argv[ 1 ] ) ) {
 			case 0:
-				mi->flags &= ~LDAP_BACK_F_SAVECRED;
+				mi->mi_flags &= ~LDAP_BACK_F_SAVECRED;
 				break;
 
 			case 1:
-				mi->flags |= LDAP_BACK_F_SAVECRED;
+				mi->mi_flags |= LDAP_BACK_F_SAVECRED;
 				break;
 
 			default:
-				fprintf( stderr,
+				Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: \"rebind-as-user {FALSE|true}\" unknown argument \"%s\".\n",
 				    fname, lineno, argv[ 1 ] );
 				return 1;
@@ -453,12 +469,12 @@ meta_back_db_config(
 	} else if ( strcasecmp( argv[ 0 ], "chase-referrals" ) == 0 ) {
 		unsigned	*flagsp = mi->mi_ntargets ?
 				&mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
-				: &mi->flags;
+				: &mi->mi_flags;
 
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: \"chase-referrals {TRUE|false}\" needs 1 argument.\n",
-					fname, lineno );
+				fname, lineno, 0 );
 			return( 1 );
 		}
 
@@ -473,21 +489,21 @@ meta_back_db_config(
 			break;
 
 		default:
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 		"%s: line %d: \"chase-referrals {TRUE|false}\": unknown argument \"%s\".\n",
-					fname, lineno, argv[ 1 ] );
+				fname, lineno, argv[ 1 ] );
 			return( 1 );
 		}
 	
 	} else if ( strcasecmp( argv[ 0 ], "tls" ) == 0 ) {
 		unsigned	*flagsp = mi->mi_ntargets ?
 				&mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
-				: &mi->flags;
+				: &mi->mi_flags;
 
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 		"%s: line %d: \"tls <what>\" needs 1 argument.\n",
-					fname, lineno );
+				fname, lineno, 0 );
 			return( 1 );
 		}
 
@@ -510,21 +526,21 @@ meta_back_db_config(
 			*flagsp |= LDAP_BACK_F_PROPAGATE_TLS;
 
 		} else {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 		"%s: line %d: \"tls <what>\": unknown argument \"%s\".\n",
-					fname, lineno, argv[ 1 ] );
+				fname, lineno, argv[ 1 ] );
 			return( 1 );
 		}
 
 	} else if ( strcasecmp( argv[ 0 ], "t-f-support" ) == 0 ) {
 		unsigned	*flagsp = mi->mi_ntargets ?
 				&mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
-				: &mi->flags;
+				: &mi->mi_flags;
 
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 		"%s: line %d: \"t-f-support {FALSE|true|discover}\" needs 1 argument.\n",
-					fname, lineno );
+				fname, lineno, 0 );
 			return( 1 );
 		}
 
@@ -542,7 +558,7 @@ meta_back_db_config(
 				*flagsp |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
 
 			} else {
-				fprintf( stderr,
+				Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: unknown value \"%s\" for \"t-f-support {no|yes|discover}\".\n",
 					fname, lineno, argv[ 1 ] );
 				return 1;
@@ -553,20 +569,20 @@ meta_back_db_config(
 	/* onerr? */
 	} else if ( strcasecmp( argv[ 0 ], "onerr" ) == 0 ) {
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: \"onerr {CONTINUE|stop}\" takes 1 argument\n",
-			    fname, lineno );
+				fname, lineno, 0 );
 			return( 1 );
 		}
 
 		if ( strcasecmp( argv[ 1 ], "continue" ) == 0 ) {
-			mi->flags &= ~META_BACK_F_ONERR_STOP;
+			mi->mi_flags &= ~META_BACK_F_ONERR_STOP;
 
 		} else if ( strcasecmp( argv[ 1 ], "stop" ) == 0 ) {
-			mi->flags |= META_BACK_F_ONERR_STOP;
+			mi->mi_flags |= META_BACK_F_ONERR_STOP;
 
 		} else {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: \"onerr {CONTINUE|stop}\": invalid arg \"%s\".\n",
 				fname, lineno, argv[ 1 ] );
 			return 1;
@@ -575,44 +591,45 @@ meta_back_db_config(
 	/* bind-defer? */
 	} else if ( strcasecmp( argv[ 0 ], "pseudoroot-bind-defer" ) == 0 ) {
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: \"pseudoroot-bind-defer {FALSE|true}\" takes 1 argument\n",
-			    fname, lineno );
+				fname, lineno, 0 );
 			return( 1 );
 		}
 
 		switch ( check_true_false( argv[ 1 ] ) ) {
 		case 0:
-			mi->flags &= ~META_BACK_F_DEFER_ROOTDN_BIND;
+			mi->mi_flags &= ~META_BACK_F_DEFER_ROOTDN_BIND;
 			break;
 
 		case 1:
-			mi->flags |= META_BACK_F_DEFER_ROOTDN_BIND;
+			mi->mi_flags |= META_BACK_F_DEFER_ROOTDN_BIND;
 			break;
 
 		default:
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: \"pseudoroot-bind-defer {FALSE|true}\": invalid arg \"%s\".\n",
 				fname, lineno, argv[ 1 ] );
 			return 1;
 		}
 
 	} else if ( strcasecmp( argv[ 0 ], "timeout" ) == 0 ) {
-		char	*sep, *next;
+		char	*sep;
 		time_t	*tv = mi->mi_ntargets ?
 				mi->mi_targets[ mi->mi_ntargets - 1 ].mt_timeout
 				: mi->mi_timeout;
 		int	c;
 
 		if ( argc < 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: \"timeout [{add|delete|modify|modrdn}=]<val> [...]\" takes at least 1 argument\n",
-			    fname, lineno );
+				fname, lineno, 0 );
 			return( 1 );
 		}
 
 		for ( c = 1; c < argc; c++ ) {
-			time_t	*t = NULL, val;
+			time_t		*t = NULL;
+			unsigned long	val;
 
 			sep = strchr( argv[ c ], '=' );
 			if ( sep != NULL ) {
@@ -627,9 +644,13 @@ meta_back_db_config(
 				} else if ( strncasecmp( argv[ c ], "modrdn", len ) == 0 ) {
 					t = &tv[ LDAP_BACK_OP_MODRDN ];
 				} else {
-					fprintf( stderr,
-		"%s: line %d: unknown operation \"%s\" for timeout #%d.\n",
-						fname, lineno, argv[ c ], c );
+					char	buf[ SLAP_TEXT_BUFLEN ];
+					snprintf( buf, sizeof( buf ),
+						"unknown operation \"%s\" for timeout #%d",
+						argv[ c ], c );
+					Debug( LDAP_DEBUG_ANY,
+						"%s: line %d: %s.\n",
+						fname, lineno, buf );
 					return 1;
 				}
 				sep++;
@@ -638,22 +659,21 @@ meta_back_db_config(
 				sep = argv[ c ];
 			}
 	
-			val = strtoul( sep, &next, 10 );
-			if ( next == sep || next[ 0 ] != '\0' ) {
-				fprintf( stderr,
+			if ( lutil_parse_time( sep, &val ) != 0 ) {
+				Debug( LDAP_DEBUG_ANY,
 		"%s: line %d: unable to parse value \"%s\" for timeout.\n",
 					fname, lineno, sep );
 				return 1;
 			}
 		
 			if ( t ) {
-				*t = val;
+				*t = (time_t)val;
 	
 			} else {
 				int	i;
 	
 				for ( i = 0; i < LDAP_BACK_OP_LAST; i++ ) {
-					tv[ i ] = val;
+					tv[ i ] = (time_t)val;
 				}
 			}
 		}
@@ -664,16 +684,16 @@ meta_back_db_config(
 		struct berval	dn;
 
 		if ( i < 0 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: need \"uri\" directive first\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 		
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: missing name in \"pseudorootdn <name>\" line\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 
@@ -682,7 +702,7 @@ meta_back_db_config(
 		if ( dnNormalize( 0, NULL, NULL, &dn,
 			&mi->mi_targets[ i ].mt_pseudorootdn, NULL ) != LDAP_SUCCESS )
 		{
-			fprintf( stderr, "%s: line %d: "
+			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 					"pseudoroot DN '%s' is invalid\n",
 					fname, lineno, argv[ 1 ] );
 			return( 1 );
@@ -693,16 +713,16 @@ meta_back_db_config(
 		int 		i = mi->mi_ntargets - 1;
 
 		if ( i < 0 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: need \"uri\" directive first\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 		
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: missing password in \"pseudorootpw <password>\" line\n",
-			    fname, lineno );
+			    fname, lineno, 0 );
 			return 1;
 		}
 		ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ].mt_pseudorootpw );
@@ -714,9 +734,9 @@ meta_back_db_config(
 		struct berval	dn, nvnc, pvnc, nrnc, prnc;
 
 		if ( i < 0 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: need \"uri\" directive first\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 		
@@ -732,15 +752,15 @@ meta_back_db_config(
 		 * current server
 		 */
 		if ( argc != 3 ) {
- 			fprintf( stderr,
+ 			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: syntax is \"suffixMassage <suffix> <massaged suffix>\"\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 
 		ber_str2bv( argv[ 1 ], 0, 0, &dn );
 		if ( dnPrettyNormal( NULL, &dn, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
-			fprintf( stderr, "%s: line %d: "
+			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
 					"suffix '%s' is invalid\n",
 					fname, lineno, argv[ 1 ] );
 			return 1;
@@ -748,10 +768,10 @@ meta_back_db_config(
 		
 		tmp_be = select_backend( &nvnc, 0, 0 );
 		if ( tmp_be != NULL && tmp_be != be ) {
-			fprintf( stderr, 
+			Debug( LDAP_DEBUG_ANY, 
 	"%s: line %d: suffix already in use by another backend in"
 	" \"suffixMassage <suffix> <massaged suffix>\"\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			free( pvnc.bv_val );
 			free( nvnc.bv_val );
 			return 1;						
@@ -759,9 +779,9 @@ meta_back_db_config(
 
 		ber_str2bv( argv[ 2 ], 0, 0, &dn );
 		if ( dnPrettyNormal( NULL, &dn, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
-			fprintf( stderr, "%s: line %d: "
-					"massaged suffix '%s' is invalid\n",
-					fname, lineno, argv[ 2 ] );
+			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+				"massaged suffix '%s' is invalid\n",
+				fname, lineno, argv[ 2 ] );
 			free( pvnc.bv_val );
 			free( nvnc.bv_val );
 			return 1;
@@ -770,10 +790,10 @@ meta_back_db_config(
 #if 0	
 		tmp_be = select_backend( &nrnc, 0, 0 );
 		if ( tmp_be != NULL ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: massaged suffix already in use by another backend in" 
 	" \"suffixMassage <suffix> <massaged suffix>\"\n",
-                                fname, lineno );
+                                fname, lineno, 0 );
 			free( pvnc.bv_val );
 			free( nvnc.bv_val );
 			free( prnc.bv_val );
@@ -803,9 +823,9 @@ meta_back_db_config(
 		int 		i = mi->mi_ntargets - 1;
 
 		if ( i < 0 ) {
-			fprintf( stderr, "%s: line %d: \"rewrite\" "
+			Debug( LDAP_DEBUG_ANY, "%s: line %d: \"rewrite\" "
 				"statement outside target definition.\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 		
@@ -817,9 +837,9 @@ meta_back_db_config(
 		int 		i = mi->mi_ntargets - 1;
 
 		if ( i < 0 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: need \"uri\" directive first\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 
@@ -832,9 +852,9 @@ meta_back_db_config(
 		int		nretries = META_RETRY_UNDEFINED;
 
 		if ( argc != 2 ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: need value in \"nretries <value>\"\n",
-				fname, lineno );
+				fname, lineno, 0 );
 			return 1;
 		}
 
@@ -845,11 +865,8 @@ meta_back_db_config(
 			nretries = META_RETRY_NEVER;
 
 		} else {
-			char	*next;
-
-			nretries = strtol( argv[ 1 ], &next, 10 );
-			if ( next == argv[ 1 ] || next[ 0 ] != '\0' ) {
-				fprintf( stderr,
+			if ( lutil_atoi( &nretries, argv[ 1 ] ) != 0 ) {
+				Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: unable to parse value \"%s\" in \"nretries <value>\"\n",
 					fname, lineno, argv[ 1 ] );
 				return 1;
@@ -885,9 +902,9 @@ ldap_back_map_config(
 	int			is_oc = 0;
 
 	if ( argc < 3 || argc > 4 ) {
-		fprintf( stderr,
+		Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
-			fname, lineno );
+			fname, lineno, 0 );
 		return 1;
 	}
 
@@ -899,10 +916,10 @@ ldap_back_map_config(
 		map = at_map;
 
 	} else {
-		fprintf( stderr, "%s: line %d: syntax is "
+		Debug( LDAP_DEBUG_ANY, "%s: line %d: syntax is "
 			"\"map {objectclass | attribute} [<local> | *] "
 			"{<foreign> | *}\"\n",
-			fname, lineno );
+			fname, lineno, 0 );
 		return 1;
 	}
 
@@ -926,17 +943,17 @@ ldap_back_map_config(
 			&& ( strcasecmp( src, "objectclass" ) == 0
 			|| strcasecmp( dst, "objectclass" ) == 0 ) )
 	{
-		fprintf( stderr,
+		Debug( LDAP_DEBUG_ANY,
 			"%s: line %d: objectclass attribute cannot be mapped\n",
-			fname, lineno );
+			fname, lineno, 0 );
 	}
 
 	mapping = (struct ldapmapping *)ch_calloc( 2,
 		sizeof(struct ldapmapping) );
 	if ( mapping == NULL ) {
-		fprintf( stderr,
+		Debug( LDAP_DEBUG_ANY,
 			"%s: line %d: out of memory\n",
-			fname, lineno );
+			fname, lineno, 0 );
 		return 1;
 	}
 	ber_str2bv( src, 0, 1, &mapping[ 0 ].src );
@@ -950,7 +967,7 @@ ldap_back_map_config(
 	if ( is_oc ) {
 		if ( src[ 0 ] != '\0' ) {
 			if ( oc_bvfind( &mapping[ 0 ].src ) == NULL ) {
-				fprintf( stderr,
+				Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: warning, source objectClass '%s' "
 	"should be defined in schema\n",
 					fname, lineno, src );
@@ -963,7 +980,7 @@ ldap_back_map_config(
 		}
 
 		if ( oc_bvfind( &mapping[ 0 ].dst ) == NULL ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: warning, destination objectClass '%s' "
 	"is not defined in schema\n",
 				fname, lineno, dst );
@@ -976,7 +993,7 @@ ldap_back_map_config(
 		if ( src[ 0 ] != '\0' ) {
 			rc = slap_bv2ad( &mapping[ 0 ].src, &ad, &text );
 			if ( rc != LDAP_SUCCESS ) {
-				fprintf( stderr,
+				Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: warning, source attributeType '%s' "
 	"should be defined in schema\n",
 					fname, lineno, src );
@@ -992,10 +1009,14 @@ ldap_back_map_config(
 				rc = slap_bv2undef_ad( &mapping[ 0 ].src,
 						&ad, &text, SLAP_AD_PROXIED );
 				if ( rc != LDAP_SUCCESS ) {
-					fprintf( stderr,
-	"%s: line %d: source attributeType '%s': %d (%s)\n",
-						fname, lineno, src,
-						rc, text ? text : "" );
+					char	buf[ SLAP_TEXT_BUFLEN ];
+
+					snprintf( buf, sizeof( buf ),
+						"source attributeType \"%s\": %d (%s)",
+						src, rc, text ? text : "" );
+					Debug( LDAP_DEBUG_ANY,
+						"%s: line %d: %s\n",
+						fname, lineno, buf );
 					goto error_return;
 				}
 			}
@@ -1005,7 +1026,7 @@ ldap_back_map_config(
 
 		rc = slap_bv2ad( &mapping[ 0 ].dst, &ad, &text );
 		if ( rc != LDAP_SUCCESS ) {
-			fprintf( stderr,
+			Debug( LDAP_DEBUG_ANY,
 	"%s: line %d: warning, destination attributeType '%s' "
 	"is not defined in schema\n",
 				fname, lineno, dst );
@@ -1018,10 +1039,14 @@ ldap_back_map_config(
 			rc = slap_bv2undef_ad( &mapping[ 0 ].dst,
 					&ad, &text, SLAP_AD_PROXIED );
 			if ( rc != LDAP_SUCCESS ) {
-				fprintf( stderr,
-	"%s: line %d: source attributeType '%s': %d (%s)\n",
-					fname, lineno, dst,
-					rc, text ? text : "" );
+				char	buf[ SLAP_TEXT_BUFLEN ];
+
+				snprintf( buf, sizeof( buf ),
+					"source attributeType \"%s\": %d (%s)\n",
+					dst, rc, text ? text : "" );
+				Debug( LDAP_DEBUG_ANY,
+					"%s: line %d: %s\n",
+					fname, lineno, buf );
 				return 1;
 			}
 		}
@@ -1030,9 +1055,9 @@ ldap_back_map_config(
 	if ( (src[ 0 ] != '\0' && avl_find( map->map, (caddr_t)&mapping[ 0 ], mapping_cmp ) != NULL)
 			|| avl_find( map->remap, (caddr_t)&mapping[ 1 ], mapping_cmp ) != NULL)
 	{
-		fprintf( stderr,
+		Debug( LDAP_DEBUG_ANY,
 			"%s: line %d: duplicate mapping found" SLAPD_CONF_UNKNOWN_IGNORED ".\n",
-			fname, lineno );
+			fname, lineno, 0 );
 		goto error_return;
 	}
 
diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c
index caaff03b5ab45f689466c090695c5093c82c7984..772771abf9ac85385d1a7a94215c748e3bc2dc0c 100644
--- a/servers/slapd/back-meta/conn.c
+++ b/servers/slapd/back-meta/conn.c
@@ -186,13 +186,13 @@ meta_back_freeconn(
 
 	assert( mc != NULL );
 
-	ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+	ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
 
 	if ( --mc->mc_refcnt == 0 ) {
 		meta_back_conn_free( mc );
 	}
 
-	ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+	ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 }
 
 /*
@@ -444,13 +444,13 @@ meta_back_retry(
 	metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
 
 retry_lock:;
-	ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+	ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
 
 	assert( mc->mc_refcnt > 0 );
 
 	if ( mc->mc_refcnt == 1 ) {
 		while ( ldap_pvt_thread_mutex_trylock( &mc->mc_mutex ) ) {
-			ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+			ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 			ldap_pvt_thread_yield();
 			goto retry_lock;
 		}
@@ -483,7 +483,7 @@ retry_lock:;
 		mc->mc_tainted = 1;
 	}
 
-	ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+	ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 
 	return rc == LDAP_SUCCESS ? 1 : 0;
 }
@@ -734,20 +734,20 @@ meta_back_getconn(
 	}
 
 	/* Searches for a metaconn in the avl tree */
-	ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
-	mc = (metaconn_t *)avl_find( mi->mi_conntree, 
+	ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
+	mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, 
 		(caddr_t)&mc_curr, meta_back_conn_cmp );
 	if ( mc ) {
 		if ( mc->mc_tainted ) {
 			rs->sr_err = LDAP_UNAVAILABLE;
 			rs->sr_text = "remote server unavailable";
-			ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+			ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 			return NULL;
 		}
 			
 		mc->mc_refcnt++;
 	}
-	ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+	ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 
 	switch ( op->o_tag ) {
 	case LDAP_REQ_ADD:
@@ -927,13 +927,13 @@ meta_back_getconn(
 			/* Retries searching for a metaconn in the avl tree
 			 * the reason is that the connection might have been
 			 * created by meta_back_get_candidate() */
-			ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
-			mc = (metaconn_t *)avl_find( mi->mi_conntree, 
+			ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
+			mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, 
 				(caddr_t)&mc_curr, meta_back_conn_cmp );
 			if ( mc != NULL ) {
 				mc->mc_refcnt++;
 			}
-			ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+			ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 
 			/* Looks like we didn't get a bind. Open a new session... */
 			if ( mc == NULL ) {
@@ -1088,15 +1088,15 @@ done:;
 		/*
 		 * Inserts the newly created metaconn in the avl tree
 		 */
-		ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
-		err = avl_insert( &mi->mi_conntree, ( caddr_t )mc,
+		ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
+		err = avl_insert( &mi->mi_conninfo.lai_tree, ( caddr_t )mc,
 			       	meta_back_conn_cmp, meta_back_conn_dup );
 
 #if PRINT_CONNTREE > 0
-		myprint( mi->mi_conntree );
+		myprint( mi->mi_conninfo.lai_tree );
 #endif /* PRINT_CONNTREE */
 		
-		ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+		ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 
 		/*
 		 * Err could be -1 in case a duplicate metaconn is inserted
@@ -1144,13 +1144,13 @@ meta_back_release_conn(
 
 	assert( mc != NULL );
 
-	ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+	ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
 	assert( mc->mc_refcnt > 0 );
 	mc->mc_refcnt--;
 	if ( mc->mc_refcnt == 0 && mc->mc_tainted ) {
-		(void)avl_delete( &mi->mi_conntree, ( caddr_t )mc,
+		(void)avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )mc,
 				meta_back_conn_cmp );
 		meta_back_conn_free( mc );
 	}
-	ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+	ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 }
diff --git a/servers/slapd/back-meta/dncache.c b/servers/slapd/back-meta/dncache.c
index ccaf446de6f8b098e86576a5b1fc080a1f0e0792..1257862ee8cb53ec6fe567c35e7b812290f50916 100644
--- a/servers/slapd/back-meta/dncache.c
+++ b/servers/slapd/back-meta/dncache.c
@@ -94,7 +94,6 @@ meta_dncache_get_target(
 {
 	metadncacheentry_t	tmp_entry,
 				*entry;
-	time_t			curr_time;
 	int			target = META_TARGET_NONE;
 
 	assert( cache != NULL );
@@ -116,13 +115,7 @@ meta_dncache_get_target(
 			target = entry->target;
 
 		} else {
-
-			/*
-			 * Need mutex?
-			 */	
-			curr_time = time( NULL );
-
-			if ( entry->lastupdated+cache->ttl > curr_time ) {
+			if ( entry->lastupdated+cache->ttl > slap_get_time() ) {
 				target = entry->target;
 			}
 		}
@@ -158,11 +151,7 @@ meta_dncache_update_entry(
 	 * else, cache is used with ttl
 	 */
 	if ( cache->ttl > 0 ) {
-
-		/*
-		 * Need mutex?
-		 */
-		curr_time = time( NULL );
+		curr_time = slap_get_time();
 	}
 
 	tmp_entry.dn = *ndn;
@@ -178,18 +167,23 @@ meta_dncache_update_entry(
 	} else {
 		entry = ch_malloc( sizeof( metadncacheentry_t ) + ndn->bv_len + 1 );
 		if ( entry == NULL ) {
-			ldap_pvt_thread_mutex_unlock( &cache->mutex );
-			return -1;
+			err = -1;
+			goto error_return;
 		}
 
+		entry->dn.bv_len = ndn->bv_len;
 		entry->dn.bv_val = (char *)&entry[ 1 ];
-		AC_MEMCPY( entry->dn.bv_val, ndn->bv_val, ndn->bv_len + 1 );
+		AC_MEMCPY( entry->dn.bv_val, ndn->bv_val, ndn->bv_len );
+		entry->dn.bv_val[ ndn->bv_len ] = '\0';
+
 		entry->target = target;
 		entry->lastupdated = curr_time;
 
 		err = avl_insert( &cache->tree, ( caddr_t )entry,
 				meta_dncache_cmp, meta_dncache_dup );
 	}
+
+error_return:;
 	ldap_pvt_thread_mutex_unlock( &cache->mutex );
 
 	return err;
diff --git a/servers/slapd/back-meta/init.c b/servers/slapd/back-meta/init.c
index a978646f1f8c270f0c575220b177a2c09e1f2d95..627a26c27bd13e3dabe42940415472ebd675711e 100644
--- a/servers/slapd/back-meta/init.c
+++ b/servers/slapd/back-meta/init.c
@@ -77,11 +77,10 @@ meta_back_db_init(
 {
 	metainfo_t	*mi;
 
-	mi = ch_malloc( sizeof( metainfo_t ) );
+	mi = ch_calloc( 1, sizeof( metainfo_t ) );
 	if ( mi == NULL ) {
  		return -1;
  	}
-	memset( mi, 0, sizeof( metainfo_t ) );
 
 	/*
 	 * At present the default is no default target;
@@ -89,7 +88,7 @@ meta_back_db_init(
 	 */
 	mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE;
 
-	ldap_pvt_thread_mutex_init( &mi->mi_conn_mutex );
+	ldap_pvt_thread_mutex_init( &mi->mi_conninfo.lai_mutex );
 	ldap_pvt_thread_mutex_init( &mi->mi_cache.mutex );
 
 	/* safe default */
@@ -222,10 +221,10 @@ meta_back_db_destroy(
 		/*
 		 * Destroy the connection tree
 		 */
-		ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+		ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
 
-		if ( mi->mi_conntree ) {
-			avl_free( mi->mi_conntree, meta_back_conn_free );
+		if ( mi->mi_conninfo.lai_tree ) {
+			avl_free( mi->mi_conninfo.lai_tree, meta_back_conn_free );
 		}
 
 		/*
@@ -248,8 +247,8 @@ meta_back_db_destroy(
 		ldap_pvt_thread_mutex_unlock( &mi->mi_cache.mutex );
 		ldap_pvt_thread_mutex_destroy( &mi->mi_cache.mutex );
 
-		ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
-		ldap_pvt_thread_mutex_destroy( &mi->mi_conn_mutex );
+		ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
+		ldap_pvt_thread_mutex_destroy( &mi->mi_conninfo.lai_mutex );
 
 		if ( mi->mi_candidates != NULL ) {
 			ber_memfree_x( mi->mi_candidates, NULL );
diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c
index dbcab08c8b7007f546f74fd7ce72ab70152f5cdf..08f61b904db42c98b706b82f4aeeeacbb6191225 100644
--- a/servers/slapd/back-meta/search.c
+++ b/servers/slapd/back-meta/search.c
@@ -102,11 +102,9 @@ meta_back_search_start(
 					&op->o_req_ndn ) )
 			{
 				realbase = mi->mi_targets[ candidate ].mt_nsuffix;
-#ifdef LDAP_SCOPE_SUBORDINATE
 				if ( mi->mi_targets[ candidate ].mt_scope == LDAP_SCOPE_SUBORDINATE ) {
 					realscope = LDAP_SCOPE_SUBORDINATE;
 				}
-#endif /* LDAP_SCOPE_SUBORDINATE */
 
 			} else {
 				/*
@@ -116,9 +114,7 @@ meta_back_search_start(
 			}
 			break;
 
-#ifdef LDAP_SCOPE_SUBORDINATE
 		case LDAP_SCOPE_SUBORDINATE:
-#endif /* LDAP_SCOPE_SUBORDINATE */
 		case LDAP_SCOPE_ONELEVEL:
 		{
 			struct berval	rdn = mi->mi_targets[ candidate ].mt_nsuffix;
@@ -132,16 +128,13 @@ meta_back_search_start(
 				 * base, and make scope "base"
 				 */
 				realbase = mi->mi_targets[ candidate ].mt_nsuffix;
-#ifdef LDAP_SCOPE_SUBORDINATE
 				if ( op->ors_scope == LDAP_SCOPE_SUBORDINATE ) {
 					if ( mi->mi_targets[ candidate ].mt_scope == LDAP_SCOPE_SUBORDINATE ) {
 						realscope = LDAP_SCOPE_SUBORDINATE;
 					} else {
 						realscope = LDAP_SCOPE_SUBTREE;
 					}
-				} else
-#endif /* LDAP_SCOPE_SUBORDINATE */
-				{
+				} else {
 					realscope = LDAP_SCOPE_BASE;
 				}
 				break;
@@ -451,29 +444,30 @@ really_bad:;
 					candidates[ i ].sr_type = REP_RESULT;
 				}
 
-				if ( --op->ors_slimit == -1 ) {
-					ldap_msgfree( res );
-					res = NULL;
+				is_ok++;
 
-					rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
+				e = ldap_first_entry( msc->msc_ld, res );
+				savepriv = op->o_private;
+				op->o_private = (void *)i;
+				rs->sr_err = meta_send_entry( op, rs, mc, i, e );
+				ldap_msgfree( res );
+				res = NULL;
+
+				switch ( rc ) {
+				case LDAP_SIZELIMIT_EXCEEDED:
 					savepriv = op->o_private;
 					op->o_private = (void *)i;
 					send_ldap_result( op, rs );
 					op->o_private = savepriv;
+					rs->sr_err = LDAP_SUCCESS;
 					goto finish;
-				}
-
-				is_ok++;
 
-				e = ldap_first_entry( msc->msc_ld, res );
-				savepriv = op->o_private;
-				op->o_private = (void *)i;
-				meta_send_entry( op, rs, mc, i, e );
+				case LDAP_UNAVAILABLE:
+					rs->sr_err = LDAP_OTHER;
+					goto finish;
+				}
 				op->o_private = savepriv;
 
-				ldap_msgfree( res );
-				res = NULL;
-
 				gotit = 1;
 
 #if 0
@@ -595,19 +589,22 @@ really_bad:;
 
 				/* massage matchedDN if need be */
 				if ( candidates[ i ].sr_matched != NULL ) {
+#ifndef LDAP_NULL_IS_NULL
 					if ( candidates[ i ].sr_matched[ 0 ] == '\0' ) {
 						ldap_memfree( (char *)candidates[ i ].sr_matched );
 						candidates[ i ].sr_matched = NULL;
 
-					} else {
+					} else
+#endif /* LDAP_NULL_IS_NULL */
+					{
 						struct berval	match, mmatch;
 
 						ber_str2bv( candidates[ i ].sr_matched,
 							0, 0, &match );
+						candidates[ i ].sr_matched = NULL;
 
 						dc.ctx = "matchedDN";
 						dc.target = &mi->mi_targets[ i ];
-
 						if ( !ldap_back_dn_massage( &dc, &match, &mmatch ) ) {
 							if ( mmatch.bv_val == match.bv_val ) {
 								candidates[ i ].sr_matched = ch_strdup( mmatch.bv_val );
@@ -622,12 +619,14 @@ really_bad:;
 					}
 				}
 
+#ifndef LDAP_NULL_IS_NULL
 				/* just get rid of the error message, if any */
 				if ( candidates[ i ].sr_text && candidates[ i ].sr_text[ 0 ] == '\0' )
 				{
 					ldap_memfree( (char *)candidates[ i ].sr_text );
 					candidates[ i ].sr_text = NULL;
 				}
+#endif /* LDAP_NULL_IS_NULL */
 
 				/* add references to array */
 				if ( references ) {
@@ -766,11 +765,24 @@ really_bad:;
 		/* we use the first one */
 		for ( i = 0; i < mi->mi_ntargets; i++ ) {
 			if ( candidates[ i ].sr_tag == META_CANDIDATE
-					&& candidates[ i ].sr_matched )
+					&& candidates[ i ].sr_matched != NULL )
 			{
 				struct berval	bv, pbv;
 				int		rc;
 
+				/* if we got success, and this target
+				 * returned noSuchObject, and its suffix
+				 * is a superior of the searchBase,
+				 * ignore the matchedDN */
+				if ( sres == LDAP_SUCCESS
+					&& candidates[ i ].sr_err == LDAP_NO_SUCH_OBJECT
+					&& op->o_req_ndn.bv_len > mi->mi_targets[ i ].mt_nsuffix.bv_len )
+				{
+					free( (char *)candidates[ i ].sr_matched );
+					candidates[ i ].sr_matched = NULL;
+					continue;
+				}
+
 				ber_str2bv( candidates[ i ].sr_matched, 0, 0, &bv );
 				rc = dnPretty( NULL, &bv, &pbv, op->o_tmpmemctx );
 
@@ -1137,7 +1149,12 @@ next_attr:;
 	rs->sr_entry = &ent;
 	rs->sr_attrs = op->ors_attrs;
 	rs->sr_flags = 0;
-	send_search_entry( op, rs );
+	rc = send_search_entry( op, rs );
+	switch ( rc ) {
+	case LDAP_UNAVAILABLE:
+		rc = LDAP_OTHER;
+		break;
+	}
 	rs->sr_entry = NULL;
 	rs->sr_attrs = NULL;
 	
@@ -1151,6 +1168,6 @@ next_attr:;
 	}
 	entry_clean( &ent );
 
-	return LDAP_SUCCESS;
+	return rc;
 }
 
diff --git a/servers/slapd/back-meta/unbind.c b/servers/slapd/back-meta/unbind.c
index a38bfa2b0729314d8209d6642b3894d2a8db9616..ed98015e57504b2de59b53892deb684600aef21d 100644
--- a/servers/slapd/back-meta/unbind.c
+++ b/servers/slapd/back-meta/unbind.c
@@ -50,10 +50,10 @@ meta_back_conn_destroy(
 	mc_curr.mc_conn = conn;
 	mc_curr.mc_local_ndn = conn->c_ndn;
 	
-	ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
-	mc = avl_delete( &mi->mi_conntree, ( caddr_t )&mc_curr,
+	ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
+	mc = avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )&mc_curr,
 			meta_back_conn_cmp );
-	ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+	ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 
 	if ( mc ) {
 		Debug( LDAP_DEBUG_TRACE,
diff --git a/servers/slapd/back-monitor/database.c b/servers/slapd/back-monitor/database.c
index ae234a143b702e1c83ff529d6d5f0e3b396ab62b..6672c611cfa3522247dcb412edb3402dff5daebf 100644
--- a/servers/slapd/back-monitor/database.c
+++ b/servers/slapd/back-monitor/database.c
@@ -45,6 +45,9 @@ static int monitor_back_add_plugin( monitor_info_t *mi, Backend *be, Entry *e );
 #if 0 && defined(SLAPD_LDBM) 
 #include "../back-ldbm/back-ldbm.h"
 #endif /* defined(SLAPD_LDBM) */
+#if defined(SLAPD_META) 
+#include "../back-meta/back-meta.h"
+#endif /* defined(SLAPD_META) */
 
 /* for PATH_MAX on some systems (e.g. Solaris) */
 #ifdef HAVE_LIMITS_H
@@ -300,34 +303,19 @@ monitor_subsys_database_init(
 			}
 		}
 
+
+		if ( 0 ) {
+			assert( 0 );
+
 #if defined(SLAPD_BDB) || defined(SLAPD_HDB) 
-		if ( strcmp( bi->bi_type, "bdb" ) == 0
+		} else if ( strcmp( bi->bi_type, "bdb" ) == 0
 				|| strcmp( bi->bi_type, "hdb" ) == 0 )
 		{
 			struct berval	bv;
 			ber_len_t	pathlen = 0, len = 0;
 			char		path[ PATH_MAX ] = { '\0' };
-			char		*fname = NULL;
-
-			if ( strcmp( bi->bi_type, "bdb" ) == 0
-					|| strcmp( bi->bi_type, "hdb" ) == 0 )
-			{
-				struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-
-				fname = bdb->bi_dbenv_home;
-#if 0
-			} else if ( strcmp( bi->bi_type, "ldbm" ) == 0 ) {
-				struct ldbminfo *ldbm = (struct ldbminfo *) be->be_private;
-
-				/* FIXME: there's a conflict
-				 * between back-bdb.h and back.ldbm.h;
-				 * anyway, this code will be moved
-				 * to the backends as soon as the
-				 * issue with filtering on namingContexts
-				 * is fixed */
-				fname = ldbm->li_directory;
-#endif
-			}
+			struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+			char		*fname = bdb->bi_dbenv_home;
 
 			len = strlen( fname );
 			if ( fname[ 0 ] != '/' ) {
@@ -363,22 +351,54 @@ monitor_subsys_database_init(
 					&bv, NULL );
 
 			ch_free( bv.bv_val );
-		}
-#endif /* defined(SLAPD_LDAP) || defined(SLAPD_HDB) */
 
+#endif /* defined(SLAPD_BDB) || defined(SLAPD_HDB) */
 #if defined(SLAPD_LDAP) 
-		if ( strcmp( bi->bi_type, "ldap" ) == 0 ) {
-			struct ldapinfo		*li =
-				(struct ldapinfo *)be->be_private;
-			struct berval		bv;
+		} else if ( strcmp( bi->bi_type, "ldap" ) == 0 ) {
+			ldapinfo_t	*li = (ldapinfo_t *)be->be_private;
+#if 0
+			attr_merge_normalize( e, slap_schema.si_ad_labeledURI,
+					li->li_bvuri, NULL );
+#else
+			char		**urls = ldap_str2charray( li->li_uri, " " );
+			int		u;
 
-			ber_str2bv( li->url, 0, 0, &bv );
+			for ( u = 0; urls[ u ] != NULL; u++ ) {
+				struct berval	bv;
+
+				ber_str2bv( urls[ u ], 0, 0, &bv );
+
+				attr_merge_normalize_one( e,
+						slap_schema.si_ad_labeledURI,
+						&bv, NULL );
+			}
+
+			ldap_charray_free( urls );
+#endif
 
-			attr_merge_normalize_one( e,
-					slap_schema.si_ad_labeledURI,
-					&bv, NULL );
-		}
 #endif /* defined(SLAPD_LDAP) */
+#if defined(SLAPD_META) 
+		} else if ( strcmp( bi->bi_type, "meta" ) == 0 ) {
+			metainfo_t	*mi = (metainfo_t *)be->be_private;
+			int		t;
+
+			for ( t = 0; t < mi->mi_ntargets; t++ ) {
+				char		**urls = ldap_str2charray( mi->mi_targets[ t ].mt_uri, " " );
+				int		u;
+
+				for ( u = 0; urls[ u ] != NULL; u++ ) {
+					struct berval	bv;
+
+					ber_str2bv( urls[ u ], 0, 0, &bv );
+
+					attr_merge_normalize_one( e,
+						slap_schema.si_ad_labeledURI,
+						&bv, NULL );
+				}
+				ldap_charray_free( urls );
+			}
+#endif /* defined(SLAPD_META) */
+		}
 
 		j = -1;
 		LDAP_STAILQ_FOREACH( bi2, &backendInfo, bi_next ) {
diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c
index e9332c79ed0f8d4c0654167ee243463b180b9c63..14b3a60b888687f28e40ef80d5b83713f550ba7c 100644
--- a/servers/slapd/back-monitor/init.c
+++ b/servers/slapd/back-monitor/init.c
@@ -1366,7 +1366,9 @@ monitor_back_initialize(
 	bi->bi_destroy = 0;
 
 	bi->bi_db_init = monitor_back_db_init;
+#if 0
 	bi->bi_db_config = monitor_back_db_config;
+#endif
 	bi->bi_db_open = monitor_back_db_open;
 	bi->bi_db_close = 0;
 	bi->bi_db_destroy = monitor_back_db_destroy;
@@ -1812,6 +1814,7 @@ monitor_back_config(
 	return SLAP_CONF_UNKNOWN;
 }
 
+#if 0
 int
 monitor_back_db_config(
 	Backend     *be,
@@ -1820,15 +1823,14 @@ monitor_back_db_config(
 	int         argc,
 	char        **argv )
 {
-#if 0
 	monitor_info_t	*mi = ( monitor_info_t * )be->be_private;
-#endif
 
 	/*
 	 * eventually, will hold database specific configuration parameters
 	 */
 	return SLAP_CONF_UNKNOWN;
 }
+#endif
 
 int
 monitor_back_db_destroy(
diff --git a/servers/slapd/back-monitor/search.c b/servers/slapd/back-monitor/search.c
index 591287d06cfc73777e2d4fe2c93b4bb44d903eb2..ab5c475c078404f5ca7be2e3c528d8c1aa708cdb 100644
--- a/servers/slapd/back-monitor/search.c
+++ b/servers/slapd/back-monitor/search.c
@@ -113,7 +113,7 @@ monitor_send_children(
 		if ( rc == LDAP_COMPARE_TRUE ) {
 			rs->sr_entry = e;
 			rs->sr_flags = 0;
-			send_search_entry( op, rs );
+			rc = send_search_entry( op, rs );
 			rs->sr_entry = NULL;
 		}
 
diff --git a/servers/slapd/back-perl/search.c b/servers/slapd/back-perl/search.c
index 33d48225538bfc1264cd6ba772b0315cdc97e6fd..3709ac18d263171a113c721f08d9964e631e54d7 100644
--- a/servers/slapd/back-perl/search.c
+++ b/servers/slapd/back-perl/search.c
@@ -84,10 +84,17 @@ perl_back_search(
 						send_entry = 1;
 
 					if (send_entry) {
+						int	rc;
+
 						rs->sr_entry = e;
 						rs->sr_attrs = op->ors_attrs;
 						rs->sr_flags = REP_ENTRY_MODIFIABLE;
-						send_search_entry( op, rs );
+						rs->sr_err = LDAP_SUCCESS;
+						rs->sr_err = send_search_entry( op, rs );
+						if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ) {
+							rs->sr_entry = NULL;
+							goto done;
+						}
 					}
 
 					entry_free( e );
@@ -106,8 +113,7 @@ perl_back_search(
 
 		rs->sr_err = POPi;
 
-
-
+done:;
 		PUTBACK; FREETMPS; LEAVE;
 	}
 
diff --git a/servers/slapd/back-sql/entry-id.c b/servers/slapd/back-sql/entry-id.c
index 213fd7096c06c407333458d1610d051d1254f94f..9d33b9df729ef27ff0800eeb7d25603e819ac5e5 100644
--- a/servers/slapd/back-sql/entry-id.c
+++ b/servers/slapd/back-sql/entry-id.c
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 #include "ac/string.h"
 
+#include "lutil.h"
 #include "slap.h"
 #include "proto-sql.h"
 
@@ -250,43 +251,52 @@ backsql_dn2id(
 		if ( id != NULL ) {
 			struct berval	dn;
 
+			id->eid_next = NULL;
+
 #ifdef BACKSQL_ARBITRARY_KEY
 			ber_str2bv_x( row.cols[ 0 ], 0, 1, &id->eid_id,
 					op->o_tmpmemctx );
 			ber_str2bv_x( row.cols[ 1 ], 0, 1, &id->eid_keyval,
 					op->o_tmpmemctx );
 #else /* ! BACKSQL_ARBITRARY_KEY */
-			id->eid_id = strtol( row.cols[ 0 ], NULL, 0 );
-			id->eid_keyval = strtol( row.cols[ 1 ], NULL, 0 );
+			if ( lutil_atoulx( &id->eid_id, row.cols[ 0 ], 0 ) != 0 ) {
+				res = LDAP_OTHER;
+				goto done;
+			}
+			if ( lutil_atoulx( &id->eid_keyval, row.cols[ 1 ], 0 ) != 0 ) {
+				res = LDAP_OTHER;
+				goto done;
+			}
 #endif /* ! BACKSQL_ARBITRARY_KEY */
-			id->eid_oc_id = strtol( row.cols[ 2 ], NULL, 0 );
+			if ( lutil_atoulx( &id->eid_oc_id, row.cols[ 2 ], 0 ) != 0 ) {
+				res = LDAP_OTHER;
+				goto done;
+			}
 
 			ber_str2bv( row.cols[ 3 ], 0, 0, &dn );
 
 			if ( backsql_api_odbc2dn( op, rs, &dn ) ) {
 				res = LDAP_OTHER;
-
-			} else {
-				res = dnPrettyNormal( NULL, &dn,
-						&id->eid_dn, &id->eid_ndn,
-						op->o_tmpmemctx );
-				if ( res != LDAP_SUCCESS ) {
-					Debug( LDAP_DEBUG_TRACE,
-						"   backsql_dn2id(\"%s\"): "
-						"dnPrettyNormal failed (%d: %s)\n",
-						realndn.bv_val, res,
-						ldap_err2string( res ) );
-
-					/* cleanup... */
-					(void)backsql_free_entryID( op, id, 0 );
-				}
-
-				if ( dn.bv_val != row.cols[ 3 ] ) {
-					free( dn.bv_val );
-				}
+				goto done;
+			}
+			
+			res = dnPrettyNormal( NULL, &dn,
+					&id->eid_dn, &id->eid_ndn,
+					op->o_tmpmemctx );
+			if ( res != LDAP_SUCCESS ) {
+				Debug( LDAP_DEBUG_TRACE,
+					"   backsql_dn2id(\"%s\"): "
+					"dnPrettyNormal failed (%d: %s)\n",
+					realndn.bv_val, res,
+					ldap_err2string( res ) );
+
+				/* cleanup... */
+				(void)backsql_free_entryID( op, id, 0 );
 			}
 
-			id->eid_next = NULL;
+			if ( dn.bv_val != row.cols[ 3 ] ) {
+				free( dn.bv_val );
+			}
 		}
 
 	} else {
@@ -408,11 +418,28 @@ backsql_count_children(
 		char *end;
 
 		*nchildren = strtol( row.cols[ 0 ], &end, 0 );
-		if ( end[ 0 ] != '\0' && end[0] != '.' ) {
-			/* FIXME: braindead RDBMSes return
-			 * a fractional number from COUNT!
-			 */
+		if ( end == row.cols[ 0 ] ) {
 			res = LDAP_OTHER;
+
+		} else {
+			switch ( end[ 0 ] ) {
+			case '\0':
+				break;
+
+			case '.': {
+				unsigned long	ul;
+
+				/* FIXME: braindead RDBMSes return
+				 * a fractional number from COUNT!
+				 */
+				if ( lutil_atoul( &ul, end + 1 ) != 0 || ul != 0 ) {
+					res = LDAP_OTHER;
+				}
+				} break;
+
+			default:
+				res = LDAP_OTHER;
+			}
 		}
 
 	} else {
diff --git a/servers/slapd/back-sql/schema-map.c b/servers/slapd/back-sql/schema-map.c
index 11056f039e7dc044ddf6cee04e9246f40ac24feb..24342fcc665d988023e4deb02e1c13b41c809ab1 100644
--- a/servers/slapd/back-sql/schema-map.c
+++ b/servers/slapd/back-sql/schema-map.c
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 #include "ac/string.h"
 
+#include "lutil.h"
 #include "slap.h"
 #include "proto-sql.h"
 
@@ -316,7 +317,6 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
 	backsql_BindRowAsStrings( bas->bas_sth, &at_row );
 	for ( ; rc = SQLFetch( bas->bas_sth ), BACKSQL_SUCCESS( rc ); ) {
 		const char	*text = NULL;
-		char		*next = NULL;
 		struct berval	bv;
 		struct berbuf	bb = BB_NULL;
 
@@ -377,14 +377,10 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
 		if ( at_row.value_len[ 5 ] > 0 ) {
 			at_map->bam_delete_proc = ch_strdup( at_row.cols[ 5 ] );
 		}
-		at_map->bam_param_order = strtol( at_row.cols[ 6 ], 
-				&next, 0 );
-		if ( next == at_row.cols[ 6 ] || next[0] != '\0' ) {
+		if ( lutil_atoix( &at_map->bam_param_order, at_row.cols[ 6 ], 0 ) != 0 ) {
 			/* error */
 		}
-		at_map->bam_expect_return = strtol( at_row.cols[ 7 ],
-				&next, 0 );
-		if ( next == at_row.cols[ 7 ] || next[0] != '\0' ) {
+		if ( lutil_atoix( &at_map->bam_expect_return, at_row.cols[ 7 ], 0 ) != 0 ) {
 			/* error */
 		}
 		backsql_make_attr_query( bas->bas_bi, oc_map, at_map );
@@ -485,7 +481,12 @@ backsql_load_schema_map( backsql_info *bi, SQLHDBC dbh )
 		oc_map = (backsql_oc_map_rec *)ch_calloc( 1,
 				sizeof( backsql_oc_map_rec ) );
 
-		oc_map->bom_id = strtol( oc_row.cols[ 0 ], NULL, 0 );
+		if ( lutil_atoulx( &oc_map->bom_id, oc_row.cols[ 0 ], 0 ) != 0 ) {
+			Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
+				"unable to parse id=\"%s\"\n", 
+				oc_row.cols[ 0 ], 0, 0 );
+			return LDAP_OTHER;
+		}
 
 		oc_map->bom_oc = oc_find( oc_row.cols[ 1 ] );
 		if ( oc_map->bom_oc == NULL ) {
@@ -508,8 +509,12 @@ backsql_load_schema_map( backsql_info *bi, SQLHDBC dbh )
 		}
 		oc_map->bom_delete_proc = ( oc_row.value_len[ colnum ] < 0 ) ? NULL 
 			: ch_strdup( oc_row.cols[ colnum ] );
-		oc_map->bom_expect_return = strtol( oc_row.cols[ colnum + 1 ], 
-				NULL, 0 );
+		if ( lutil_atoix( &oc_map->bom_expect_return, oc_row.cols[ colnum + 1 ], 0 ) != 0 ) {
+			Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
+				"unable to parse expect_return=\"%s\" for objectClass \"%s\"\n", 
+				oc_row.cols[ colnum + 1 ], oc_row.cols[ 1 ], 0 );
+			return LDAP_OTHER;
+		}
 
 		colnum += 2;
 		if ( ( oc_row.ncols > colnum ) &&
diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c
index 2fe00acb2c6ffbcedccde806ba178bdac33f725a..ba54bef33bd02628346ea6a177b7b38786e606b7 100644
--- a/servers/slapd/back-sql/search.c
+++ b/servers/slapd/back-sql/search.c
@@ -28,6 +28,7 @@
 #include "ac/string.h"
 #include "ac/ctype.h"
 
+#include "lutil.h"
 #include "slap.h"
 #include "proto-sql.h"
 
@@ -1435,9 +1436,7 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
 					"ldap_entries.parent=?" );
 		break;
 
-#ifdef LDAP_SCOPE_SUBORDINATE
 	case LDAP_SCOPE_SUBORDINATE:
-#endif /* LDAP_SCOPE_SUBORDINATE */
 	case LDAP_SCOPE_SUBTREE:
 		if ( BACKSQL_USE_SUBTREE_SHORTCUT( bi ) ) {
 			int		i;
@@ -1678,9 +1677,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
 		}
 		break;
 
-#ifdef LDAP_SCOPE_SUBORDINATE
 	case LDAP_SCOPE_SUBORDINATE:
-#endif /* LDAP_SCOPE_SUBORDINATE */
 	case LDAP_SCOPE_SUBTREE:
 	{
 		/* if short-cutting the search base,
@@ -1719,11 +1716,9 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
 				tmp_base_ndn[ i ] = bsi->bsi_base_ndn->bv_val[ j ];
 			}
 
-#ifdef LDAP_SCOPE_SUBORDINATE
 			if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
 				tmp_base_ndn[ i++ ] = ',';
 			}
-#endif /* LDAP_SCOPE_SUBORDINATE */
 
 			tmp_base_ndn[ i ] = '%';
 			tmp_base_ndn[ i + 1 ] = '\0';
@@ -1733,11 +1728,9 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
 
 			tmp_base_ndn[ i++ ] = '%';
 
-#ifdef LDAP_SCOPE_SUBORDINATE
 			if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
 				tmp_base_ndn[ i++ ] = ',';
 			}
-#endif /* LDAP_SCOPE_SUBORDINATE */
 
 			AC_MEMCPY( &tmp_base_ndn[ i ], bsi->bsi_base_ndn->bv_val,
 				bsi->bsi_base_ndn->bv_len + 1 );
@@ -1749,13 +1742,10 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
 			ldap_pvt_str2upper( tmp_base_ndn );
 		}
 
-#ifdef LDAP_SCOPE_SUBORDINATE
 		if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
 			Debug( LDAP_DEBUG_TRACE, "(children)dn: \"%s\"\n",
 				tmp_base_ndn, 0, 0 );
-		} else 
-#endif /* LDAP_SCOPE_SUBORDINATE */
-		{
+		} else {
 			Debug( LDAP_DEBUG_TRACE, "(sub)dn: \"%s\"\n",
 				tmp_base_ndn, 0, 0 );
 		}
@@ -1828,21 +1818,23 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
 		}
 
 		if ( bi->sql_baseObject && dn_match( &ndn, &bi->sql_baseObject->e_nname ) ) {
-			op->o_tmpfree( pdn.bv_val, op->o_tmpmemctx );
-			op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );
-			continue;
+			goto cleanup;
 		}
 
-		c_id = (backsql_entryID *)ch_calloc( 1, 
-				sizeof( backsql_entryID ) );
+		c_id = (backsql_entryID *)op->o_tmpcalloc( 1, 
+				sizeof( backsql_entryID ), op->o_tmpmemctx );
 #ifdef BACKSQL_ARBITRARY_KEY
 		ber_str2bv_x( row.cols[ 0 ], 0, 1, &c_id->eid_id,
 				op->o_tmpmemctx );
 		ber_str2bv_x( row.cols[ 1 ], 0, 1, &c_id->eid_keyval,
 				op->o_tmpmemctx );
 #else /* ! BACKSQL_ARBITRARY_KEY */
-		c_id->eid_id = strtol( row.cols[ 0 ], NULL, 0 );
-		c_id->eid_keyval = strtol( row.cols[ 1 ], NULL, 0 );
+		if ( lutil_atoulx( &c_id->eid_id, row.cols[ 0 ], 0 ) != 0 ) {
+			goto cleanup;
+		}
+		if ( lutil_atoulx( &c_id->eid_keyval, row.cols[ 1 ], 0 ) != 0 ) {
+			goto cleanup;
+		}
 #endif /* ! BACKSQL_ARBITRARY_KEY */
 		c_id->eid_oc_id = bsi->bsi_oc->bom_id;
 
@@ -1870,6 +1862,18 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
 		if ( bsi->bsi_n_candidates == -1 ) {
 			break;
 		}
+		continue;
+
+cleanup:;
+		if ( !BER_BVISNULL( &pdn ) ) {
+			op->o_tmpfree( pdn.bv_val, op->o_tmpmemctx );
+		}
+		if ( !BER_BVISNULL( &ndn ) ) {
+			op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );
+		}
+		if ( c_id != NULL ) {
+			ch_free( c_id );
+		}
 	}
 	backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx );
 	SQLFreeStmt( sth, SQL_DROP );
@@ -1897,7 +1901,7 @@ backsql_search( Operation *op, SlapReply *rs )
 	Debug( LDAP_DEBUG_TRACE, "==>backsql_search(): "
 		"base=\"%s\", filter=\"%s\", scope=%d,", 
 		op->o_req_ndn.bv_val,
-		op->ors_filterstr.bv_val ? op->ors_filterstr.bv_val : "(no filter)",
+		op->ors_filterstr.bv_val,
 		op->ors_scope );
 	Debug( LDAP_DEBUG_TRACE, " deref=%d, attrsonly=%d, "
 		"attributes to load: %s\n",
@@ -2142,15 +2146,12 @@ backsql_search( Operation *op, SlapReply *rs )
 			/* fall thru */
 		}
 
-#ifdef LDAP_SCOPE_SUBORDINATE
 		case LDAP_SCOPE_SUBORDINATE:
 			/* discard the baseObject entry */
 			if ( dn_match( &eid->eid_ndn, &op->o_req_ndn ) ) {
 				goto next_entry2;
 			}
-		/* FALLTHRU */
-#endif /* LDAP_SCOPE_SUBORDINATE */
-
+			/* FALLTHRU */
 		case LDAP_SCOPE_SUBTREE:
 			/* FIXME: this should never fail... */
 			if ( !dnIsSuffix( &eid->eid_ndn, &op->o_req_ndn ) ) {
@@ -2305,24 +2306,18 @@ backsql_search( Operation *op, SlapReply *rs )
 
 		if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE )
 		{
-			if ( --op->ors_slimit == -1 ) {
-				rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
-				goto send_results;
-			}
-
 			rs->sr_attrs = op->ors_attrs;
 			rs->sr_operational_attrs = NULL;
 			rs->sr_entry = e;
-			if ( e == &user_entry ) {
-				rs->sr_flags = REP_ENTRY_MODIFIABLE;
-			}
+			rs->sr_flags = ( e == &user_entry ) ? REP_ENTRY_MODIFIABLE : 0;
 			/* FIXME: need the whole entry (ITS#3480) */
-			sres = send_search_entry( op, rs );
+			rs->sr_err = send_search_entry( op, rs );
 			rs->sr_entry = NULL;
 			rs->sr_attrs = NULL;
 			rs->sr_operational_attrs = NULL;
 
-			if ( sres == -1 ) {
+			switch ( rs->sr_err ) {
+			case LDAP_UNAVAILABLE:
 				/*
 				 * FIXME: send_search_entry failed;
 				 * better stop
@@ -2330,6 +2325,9 @@ backsql_search( Operation *op, SlapReply *rs )
 				Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
 					"connection lost\n", 0, 0, 0 );
 				goto end_of_search;
+
+			case LDAP_SIZELIMIT_EXCEEDED:
+				goto send_results;
 			}
 		}
 
diff --git a/servers/slapd/back-sql/util.c b/servers/slapd/back-sql/util.c
index 316f2bc5ee68148c77216bf584a1dafcdca6ba4f..361a465ebeba6569888555d287b567c23e20dfa2 100644
--- a/servers/slapd/back-sql/util.c
+++ b/servers/slapd/back-sql/util.c
@@ -544,7 +544,9 @@ backsql_entryUUID_decode(
 #endif /* ! BACKSQL_ARBITRARY_KEY */
 	)
 {
+#if 0
 	fprintf( stderr, "==> backsql_entryUUID_decode()\n" );
+#endif
 
 	*oc_id = ( entryUUID->bv_val[0] << 030 /* 24 */ )
 		+ ( entryUUID->bv_val[1] << 020 /* 16 */ )
@@ -560,8 +562,10 @@ backsql_entryUUID_decode(
 		+ entryUUID->bv_val[7];
 #endif /* ! BACKSQL_ARBITRARY_KEY */
 
+#if 0
 	fprintf( stderr, "<== backsql_entryUUID_decode(): oc=%lu id=%lu\n",
 			*oc_id, *keyval );
+#endif
 
 	return LDAP_SUCCESS;
 }
diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c
index 97cd302a342428c7a6a8f51d2e40b81f7771b372..35f4f2336d8e3378365a5430bad08d8a7e65052b 100644
--- a/servers/slapd/backend.c
+++ b/servers/slapd/backend.c
@@ -1311,14 +1311,12 @@ fe_acl_group(
 								goto loopit;
 							}
 							break;
-#ifdef LDAP_SCOPE_SUBORDINATE
 						case LDAP_SCOPE_SUBORDINATE:
 							if ( dn_match( &nbase, op_ndn ) ||
 								!dnIsSuffix( op_ndn, &nbase ) )
 							{
 								goto loopit;
 							}
-#endif
 						}
 						filter = str2filter_x( op, ludp->lud_filter );
 						if ( filter ) {
diff --git a/servers/slapd/backglue.c b/servers/slapd/backglue.c
index 99d88b0816949b93c541b51a8de1711468d04ea9..ec2f78ac17d95fd5643cd55ad65b15cbefdbd69b 100644
--- a/servers/slapd/backglue.c
+++ b/servers/slapd/backglue.c
@@ -79,7 +79,6 @@ glue_back_select (
 
 typedef struct glue_state {
 	int err;
-	int slimit;
 	int matchlen;
 	char *matched;
 	int nrefs;
@@ -93,13 +92,6 @@ glue_op_response ( Operation *op, SlapReply *rs )
 
 	switch(rs->sr_type) {
 	case REP_SEARCH:
-		if ( gs->slimit != SLAP_NO_LIMIT
-				&& rs->sr_nentries >= gs->slimit )
-		{
-			rs->sr_err = gs->err = LDAP_SIZELIMIT_EXCEEDED;
-			return -1;
-		}
-		/* fallthru */
 	case REP_SEARCHREF:
 		return SLAP_CB_CONTINUE;
 
@@ -242,9 +234,9 @@ glue_op_search ( Operation *op, SlapReply *rs )
 	BackendInfo *bi0 = op->o_bd->bd_info;
 	int i;
 	long stoptime = 0;
-	glue_state gs = {0, 0, 0, NULL, 0, NULL};
+	glue_state gs = {0, 0, NULL, 0, NULL};
 	slap_callback cb = { NULL, glue_op_response, NULL, NULL };
-	int scope0, slimit0, tlimit0;
+	int scope0, tlimit0;
 	struct berval dn, ndn, *pdn;
 
 	cb.sc_private = &gs;
@@ -266,9 +258,7 @@ glue_op_search ( Operation *op, SlapReply *rs )
 
 	case LDAP_SCOPE_ONELEVEL:
 	case LDAP_SCOPE_SUBTREE:
-#ifdef LDAP_SCOPE_SUBORDINATE
 	case LDAP_SCOPE_SUBORDINATE: /* FIXME */
-#endif
 
 #if 0
 		if ( op->o_sync ) {
@@ -285,7 +275,6 @@ glue_op_search ( Operation *op, SlapReply *rs )
 		op->o_callback = &cb;
 		rs->sr_err = gs.err = LDAP_UNWILLING_TO_PERFORM;
 		scope0 = op->ors_scope;
-		slimit0 = gs.slimit = op->ors_slimit;
 		tlimit0 = op->ors_tlimit;
 		dn = op->o_req_dn;
 		ndn = op->o_req_ndn;
@@ -313,13 +302,6 @@ glue_op_search ( Operation *op, SlapReply *rs )
 					break;
 				}
 			}
-			if (slimit0 != SLAP_NO_LIMIT) {
-				op->ors_slimit = slimit0 - rs->sr_nentries;
-				if (op->ors_slimit < 0) {
-					rs->sr_err = gs.err = LDAP_SIZELIMIT_EXCEEDED;
-					break;
-				}
-			}
 			rs->sr_err = 0;
 			/*
 			 * check for abandon 
@@ -380,7 +362,6 @@ glue_op_search ( Operation *op, SlapReply *rs )
 		}
 end_of_loop:;
 		op->ors_scope = scope0;
-		op->ors_slimit = slimit0;
 		op->ors_tlimit = tlimit0;
 		op->o_req_dn = dn;
 		op->o_req_ndn = ndn;
diff --git a/servers/slapd/backover.c b/servers/slapd/backover.c
index 054edbe11ab1fbf3cdef36d4f3c903fd83e011e2..b87500ebc2fbb20c085409c11a6cdcc9bb3573e8 100644
--- a/servers/slapd/backover.c
+++ b/servers/slapd/backover.c
@@ -137,6 +137,9 @@ over_db_config(
 	ca.fname = fname;
 	ca.lineno = lineno;
 	ca.be = be;
+	snprintf( ca.log, sizeof( ca.log ), "%s: line %d",
+			ca.fname, ca.lineno );
+
 	for (; on; on=on->on_next) {
 		rc = SLAP_CONF_UNKNOWN;
 		if (on->on_bi.bi_cf_ocs) {
@@ -249,7 +252,7 @@ over_access_allowed(
 {
 	slap_overinfo *oi;
 	slap_overinst *on;
-	BackendInfo *bi = op->o_bd->bd_info;
+	BackendInfo *bi;
 	BackendDB *be = op->o_bd, db;
 	int rc = SLAP_CB_CONTINUE;
 
@@ -257,7 +260,13 @@ over_access_allowed(
 	 * when global overlays are used... */
 	assert( op->o_bd != NULL );
 
-	oi = op->o_bd->bd_info->bi_private;
+	bi = op->o_bd->bd_info;
+	/* Were we invoked on the frontend? */
+	if ( !bi->bi_access_allowed ) {
+		oi = frontendDB->bd_info->bi_private;
+	} else {
+		oi = op->o_bd->bd_info->bi_private;
+	}
 	on = oi->oi_list;
 
 	for ( ; on; on = on->on_next ) {
@@ -795,7 +804,6 @@ overlay_is_inst( BackendDB *be, const char *over_type )
 int
 overlay_register_control( BackendDB *be, const char *oid )
 {
-	int		rc = 0;
 	int		gotit = 0;
 	int		cid;
 
@@ -818,12 +826,12 @@ overlay_register_control( BackendDB *be, const char *oid )
 
 	}
 	
-	if ( rc == 0 && !gotit ) {
+	if ( !gotit ) {
 		be->be_ctrls[ cid ] = 1;
 		be->be_ctrls[ SLAP_MAX_CIDS ] = 1;
 	}
 
-	return rc;
+	return 0;
 }
 
 void
diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c
index 688d6e815bf3a65455e9c209c897f070fd0626d9..16bd6cfe6c026cf91bb1fe0da53443ac452ca13d 100644
--- a/servers/slapd/bconfig.c
+++ b/servers/slapd/bconfig.c
@@ -1489,7 +1489,6 @@ config_schema_dn(ConfigArgs *c) {
 static int
 config_sizelimit(ConfigArgs *c) {
 	int i, rc = 0;
-	char *next;
 	struct slap_limits_set *lim = &c->be->be_def_limit;
 	if (c->op == SLAP_CONFIG_EMIT) {
 		char buf[8192];
@@ -1525,20 +1524,11 @@ config_sizelimit(ConfigArgs *c) {
 			if(!strcasecmp(c->argv[i], "unlimited")) {
 				lim->lms_s_soft = -1;
 			} else {
-				lim->lms_s_soft = strtol(c->argv[i], &next, 0);
-				if(next == c->argv[i]) {
+				if ( lutil_atoix( &lim->lms_s_soft, c->argv[i], 0 ) != 0 ) {
 					snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
 					Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
 						c->log, c->msg, c->argv[i]);
 					return(1);
-				} else if(next[0] != '\0') {
-					Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
-						"trailing chars \"%s\" in \"sizelimit <limit>\" line"
-						SLAPD_CONF_UNKNOWN_IGNORED ".\n",
-						c->log, next, 0);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-					return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
 				}
 			}
 			lim->lms_s_hard = 0;
@@ -1550,7 +1540,6 @@ config_sizelimit(ConfigArgs *c) {
 static int
 config_timelimit(ConfigArgs *c) {
 	int i, rc = 0;
-	char *next;
 	struct slap_limits_set *lim = &c->be->be_def_limit;
 	if (c->op == SLAP_CONFIG_EMIT) {
 		char buf[8192];
@@ -1582,20 +1571,11 @@ config_timelimit(ConfigArgs *c) {
 			if(!strcasecmp(c->argv[i], "unlimited")) {
 				lim->lms_t_soft = -1;
 			} else {
-				lim->lms_t_soft = strtol(c->argv[i], &next, 0);
-				if(next == c->argv[i]) {
+				if ( lutil_atoix( &lim->lms_t_soft, c->argv[i], 0 ) != 0 ) {
 					snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
 					Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
 						c->log, c->msg, c->argv[i]);
 					return(1);
-				} else if(next[0] != '\0') {
-					Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
-						"trailing chars \"%s\" in \"timelimit <limit>\" line"
-						SLAPD_CONF_UNKNOWN_IGNORED ".\n",
-						c->log, next, 0);
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-					return 1;
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
 				}
 			}
 			lim->lms_t_hard = 0;
@@ -2155,7 +2135,6 @@ static int config_syslog;
 static int
 config_loglevel(ConfigArgs *c) {
 	int i;
-	char *next;
 
 	if ( loglevel_ops == NULL ) {
 		loglevel_init();
@@ -2186,8 +2165,7 @@ config_loglevel(ConfigArgs *c) {
 		int	level;
 
 		if ( isdigit( c->argv[i][0] ) || c->argv[i][0] == '-' ) {
-			level = strtol( c->argv[i], &next, 10 );
-			if ( next == NULL || next[0] != '\0' ) {
+			if( lutil_atoi( &level, c->argv[i] ) != 0 ) {
 				snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse level", c->argv[0] );
 				Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
 					c->log, c->msg, c->argv[i]);
@@ -2308,8 +2286,7 @@ config_security(ConfigArgs *c) {
 			return(1);
 		}
 
-		*tgt = strtol(src, &next, 10);
-		if(next == NULL || next[0] != '\0' ) {
+		if ( lutil_atou( tgt, src ) != 0 ) {
 			snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse factor", c->argv[0] );
 			Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
 				c->log, c->msg, c->argv[i]);
@@ -2568,8 +2545,32 @@ config_updatedn(ConfigArgs *c) {
 	BER_BVZERO( &c->value_dn );
 	BER_BVZERO( &c->value_ndn );
 
-	SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SLURP_SHADOW);
-	return(0);
+	return config_slurp_shadow( c );
+}
+
+int
+config_shadow( ConfigArgs *c, int flag )
+{
+	char	*notallowed = NULL;
+
+	if ( c->be == frontendDB ) {
+		notallowed = "frontend";
+
+	} else if ( SLAP_MONITOR(c->be) ) {
+		notallowed = "monitor";
+
+	} else if ( SLAP_CONFIG(c->be) ) {
+		notallowed = "config";
+	}
+
+	if ( notallowed != NULL ) {
+		Debug( LDAP_DEBUG_ANY, "%s: %s database cannot be shadow.\n", c->log, notallowed, 0 );
+		return 1;
+	}
+
+	SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | flag);
+
+	return 0;
 }
 
 static int
@@ -2718,8 +2719,13 @@ config_tls_config(ConfigArgs *c) {
 		return ldap_pvt_tls_set_option( NULL, flag, &i );
 	}
 	ch_free( c->value_string );
-	if(isdigit((unsigned char)c->argv[1][0])) {
-		i = atoi(c->argv[1]);
+	if ( isdigit( (unsigned char)c->argv[1][0] ) ) {
+		if ( lutil_atoi( &i, c->argv[1] ) != 0 ) {
+			Debug(LDAP_DEBUG_ANY, "%s: "
+				"unable to parse %s \"%s\"\n",
+				c->log, c->argv[0], c->argv[1] );
+			return 1;
+		}
 		return(ldap_pvt_tls_set_option(NULL, flag, &i));
 	} else {
 		return(ldap_int_tls_config(NULL, flag, c->argv[1]));
@@ -2822,8 +2828,12 @@ config_setup_ldif( BackendDB *be, const char *dir, int readit ) {
 
 	cfb->cb_db.be_suffix = be->be_suffix;
 	cfb->cb_db.be_nsuffix = be->be_nsuffix;
-	cfb->cb_db.be_rootdn = be->be_rootdn;
-	cfb->cb_db.be_rootndn = be->be_rootndn;
+
+	/* The suffix is always "cn=config". The underlying DB's rootdn
+	 * is always the same as the suffix.
+	 */
+	cfb->cb_db.be_rootdn = be->be_suffix[0];
+	cfb->cb_db.be_rootndn = be->be_nsuffix[0];
 
 	ber_str2bv( dir, 0, 1, &cfdir );
 
@@ -2859,8 +2869,8 @@ config_setup_ldif( BackendDB *be, const char *dir, int readit ) {
 		op->ors_filterstr = filterstr;
 		op->ors_scope = LDAP_SCOPE_SUBTREE;
 
-		op->o_dn = be->be_rootdn;
-		op->o_ndn = be->be_rootndn;
+		op->o_dn = c.be->be_rootdn;
+		op->o_ndn = c.be->be_rootndn;
 
 		op->o_req_dn = be->be_suffix[0];
 		op->o_req_ndn = be->be_nsuffix[0];
@@ -2882,7 +2892,9 @@ config_setup_ldif( BackendDB *be, const char *dir, int readit ) {
 		ldap_pvt_thread_pool_context_reset( thrctx );
 	}
 
-	cfb->cb_use_ldif = 1;
+	/* ITS#4194 - only use if it's present, or we're converting. */
+	if ( !readit || rc == LDAP_SUCCESS )
+		cfb->cb_use_ldif = 1;
 
 	return rc;
 }
@@ -2950,9 +2962,16 @@ read_config(const char *fname, const char *dir) {
 		/* if fname is defaulted, try reading .d */
 		rc = config_setup_ldif( be, cfdir, !fname );
 
-		/* It's OK if the base object doesn't exist yet */
-		if ( rc && rc != LDAP_NO_SUCH_OBJECT )
-			return 1;
+		if ( rc ) {
+			/* It may be OK if the base object doesn't exist yet. */
+			if ( rc != LDAP_NO_SUCH_OBJECT )
+				return 1;
+			/* ITS#4194: But if dir was specified and no fname,
+			 * then we were supposed to read the dir.
+			 */
+			if ( dir && !fname )
+				return 1;
+		}
 
 		/* If we read the config from back-ldif, nothing to do here */
 		if ( cfb->cb_got_ldif ) {
@@ -3030,6 +3049,7 @@ config_send( Operation *op, SlapReply *rs, CfEntryInfo *ce, int depth )
 	{
 		rs->sr_attrs = op->ors_attrs;
 		rs->sr_entry = ce->ce_entry;
+		rs->sr_flags = 0;
 		rc = send_search_entry( op, rs );
 	}
 	if ( op->ors_scope == LDAP_SCOPE_SUBTREE ) {
@@ -3183,13 +3203,17 @@ check_name_index( CfEntryInfo *parent, ConfigType ce_type, Entry *e,
 	dnRdn( &e->e_name, &rdn );
 	ptr1 = ber_bvchr( &e->e_name, '{' );
 	if ( ptr1 && ptr1 - e->e_name.bv_val < rdn.bv_len ) {
+		char	*next;
 		ptr2 = strchr( ptr1, '}' );
 		if (!ptr2 || ptr2 - e->e_name.bv_val > rdn.bv_len)
 			return LDAP_NAMING_VIOLATION;
 		if ( ptr2-ptr1 == 1)
 			return LDAP_NAMING_VIOLATION;
 		gotindex = 1;
-		index = atoi(ptr1+1);
+		index = strtol( ptr1 + 1, &next, 10 );
+		if ( next == ptr1 + 1 || next[ 0 ] != '}' ) {
+			return LDAP_NAMING_VIOLATION;
+		}
 		if ( index < 0 ) {
 			/* Special case, we allow -1 for the frontendDB */
 			if ( index != -1 || ce_type != Cft_Database ||
@@ -3612,17 +3636,23 @@ config_back_add( Operation *op, SlapReply *rs )
 	} else if ( cfb->cb_use_ldif ) {
 		BackendDB *be = op->o_bd;
 		slap_callback sc = { NULL, slap_null_cb, NULL, NULL };
+		struct berval dn, ndn;
+
 		op->o_bd = &cfb->cb_db;
-		/* FIXME: there must be a better way. */
-		if ( ber_bvcmp( &op->o_bd->be_rootndn, &be->be_rootndn )) {
-			op->o_bd->be_rootdn = be->be_rootdn;
-			op->o_bd->be_rootndn= be->be_rootndn;
-		}
+
+		/* Save current rootdn; use the underlying DB's rootdn */
+		dn = op->o_dn;
+		ndn = op->o_ndn;
+		op->o_dn = op->o_bd->be_rootdn;
+		op->o_ndn = op->o_bd->be_rootndn;
+
 		sc.sc_next = op->o_callback;
 		op->o_callback = &sc;
 		op->o_bd->be_add( op, rs );
 		op->o_bd = be;
 		op->o_callback = sc.sc_next;
+		op->o_dn = dn;
+		op->o_ndn = ndn;
 	}
 	if ( renumber ) {
 	}
@@ -3731,9 +3761,13 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
 				}
 				for ( i=0; !BER_BVISNULL( &ml->sml_values[i] ); i++ ) {
 					if ( ml->sml_values[i].bv_val[0] == '{' &&
-						navals >= 0 ) {
-						int j = strtol( ml->sml_values[i].bv_val+1, NULL, 0 );
-						if ( j < navals ) {
+						navals >= 0 )
+					{
+						char	*next, *val = ml->sml_values[i].bv_val + 1;
+						int	j;
+
+						j = strtol( val, &next, 0 );
+						if ( next == val || next[ 0 ] != '}' || j < navals ) {
 							rc = LDAP_OTHER;
 							snprintf(ca->msg, sizeof(ca->msg), "cannot insert %s",
 								ml->sml_desc->ad_cname.bv_val );
@@ -3851,10 +3885,17 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
 					ca->line = ml->sml_values[i].bv_val;
 					ca->valx = -1;
 					if ( ml->sml_desc->ad_type->sat_flags & SLAP_AT_ORDERED &&
-						ca->line[0] == '{' ) {
-						ptr = strchr( ca->line, '}' );
+						ca->line[0] == '{' )
+					{
+						ptr = strchr( ca->line + 1, '}' );
 						if ( ptr ) {
-							ca->valx = strtol( ca->line+1, NULL, 0 );
+							char	*next;
+
+							ca->valx = strtol( ca->line + 1, &next, 0 );
+							if ( next == ca->line + 1 || next[ 0 ] != '}' ) {
+								rc = LDAP_OTHER;
+								goto out;
+							}
 							ca->line = ptr+1;
 						}
 					}
@@ -3941,16 +3982,22 @@ config_back_modify( Operation *op, SlapReply *rs )
 	} else if ( cfb->cb_use_ldif ) {
 		BackendDB *be = op->o_bd;
 		slap_callback sc = { NULL, slap_null_cb, NULL, NULL };
+		struct berval dn, ndn;
+
 		op->o_bd = &cfb->cb_db;
-		if ( ber_bvcmp( &op->o_bd->be_rootndn, &be->be_rootndn )) {
-			op->o_bd->be_rootdn = be->be_rootdn;
-			op->o_bd->be_rootndn= be->be_rootndn;
-		}
+
+		dn = op->o_dn;
+		ndn = op->o_ndn;
+		op->o_dn = op->o_bd->be_rootdn;
+		op->o_ndn = op->o_bd->be_rootndn;
+
 		sc.sc_next = op->o_callback;
 		op->o_callback = &sc;
 		op->o_bd->be_modify( op, rs );
 		op->o_bd = be;
 		op->o_callback = sc.sc_next;
+		op->o_dn = dn;
+		op->o_ndn = ndn;
 	}
 
 	ldap_pvt_thread_pool_resume( &connection_pool );
@@ -4247,7 +4294,7 @@ config_back_db_open( BackendDB *be )
 	struct berval rdn;
 	Entry *e, *parent;
 	CfEntryInfo *ce, *ceparent;
-	int i;
+	int i, unsupp = 0;
 	BackendInfo *bi;
 	ConfigArgs c;
 	Connection conn = {0};
@@ -4266,12 +4313,11 @@ config_back_db_open( BackendDB *be )
 		op = (Operation *) &opbuf;
 		connection_fake_init( &conn, op, thrctx );
 
-		op->o_dn = be->be_rootdn;
-		op->o_ndn = be->be_rootndn;
-
 		op->o_tag = LDAP_REQ_ADD;
 		op->o_callback = &cb;
 		op->o_bd = &cfb->cb_db;
+		op->o_dn = op->o_bd->be_rootdn;
+		op->o_ndn = op->o_bd->be_rootndn;
 	} else {
 		op = NULL;
 	}
@@ -4323,7 +4369,16 @@ config_back_db_open( BackendDB *be )
 	
 	c.line = 0;
 	LDAP_STAILQ_FOREACH( bi, &backendInfo, bi_next) {
-		if (!bi->bi_cf_ocs) continue;
+		if (!bi->bi_cf_ocs) {
+			/* If it only supports the old config mech, complain. */
+			if ( bi->bi_config ) {
+				Debug( LDAP_DEBUG_ANY,
+					"WARNING: No dynamic config support for backend %s.\n",
+					bi->bi_type, 0, 0 );
+				unsupp++;
+			}
+			continue;
+		}
 		if (!bi->bi_private) continue;
 
 		rdn.bv_val = c.log;
@@ -4350,6 +4405,16 @@ config_back_db_open( BackendDB *be )
 		} else {
 			bi = be->bd_info;
 		}
+
+		/* If this backend supports the old config mechanism, but not
+		 * the new mech, complain.
+		 */
+		if ( !be->be_cf_ocs && bi->bi_db_config ) {
+			Debug( LDAP_DEBUG_ANY,
+				"WARNING: No dynamic config support for database %s.\n",
+				bi->bi_type, 0, 0 );
+			unsupp++;
+		}
 		rdn.bv_val = c.log;
 		rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ),
 			"%s=" SLAP_X_ORDERED_FMT "%s", cfAd_database->ad_cname.bv_val,
@@ -4371,6 +4436,12 @@ config_back_db_open( BackendDB *be )
 			int j;
 
 			for (j=0,on=oi->oi_list; on; j++,on=on->on_next) {
+				if ( on->on_bi.bi_db_config && !on->on_bi.bi_cf_ocs ) {
+					Debug( LDAP_DEBUG_ANY,
+						"WARNING: No dynamic config support for overlay %s.\n",
+						on->on_bi.bi_type, 0, 0 );
+					unsupp++;
+				}
 				rdn.bv_val = c.log;
 				rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ),
 					"%s=" SLAP_X_ORDERED_FMT "%s",
@@ -4390,6 +4461,11 @@ config_back_db_open( BackendDB *be )
 	if ( thrctx )
 		ldap_pvt_thread_pool_context_reset( thrctx );
 
+	if ( unsupp  && cfb->cb_use_ldif ) {
+		Debug( LDAP_DEBUG_ANY, "\nWARNING: The converted cn=config "
+			"directory is incomplete and may not work.\n\n", 0, 0, 0 );
+	}
+
 	return 0;
 }
 
diff --git a/servers/slapd/config.c b/servers/slapd/config.c
index cbc9f21ec6ea39b916b3cf453864f6e239a63903..5e57b2703c761b02cd543e5edc8da3b6549316e9 100644
--- a/servers/slapd/config.c
+++ b/servers/slapd/config.c
@@ -191,17 +191,50 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) {
 		int j;
 		iarg = 0; larg = 0; barg = 0;
 		switch(arg_type & ARGS_NUMERIC) {
-			case ARG_INT:		iarg = strtol(c->argv[1], NULL, 0); break;
-			case ARG_LONG:		larg = strtol(c->argv[1], NULL, 0);	break;
-			case ARG_BER_LEN_T:	barg = (ber_len_t)atol(c->argv[1]);	break;
+			case ARG_INT:
+				if ( lutil_atoi( &iarg, c->argv[1] ) != 0 ) {
+					snprintf( c->msg, sizeof( c->msg ),
+						"<%s> unable to parse \"%s\" as int",
+						c->argv[0], c->argv[1] );
+					Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
+						c->log, c->msg, 0);
+					return(ARG_BAD_CONF);
+				}
+				break;
+			case ARG_LONG:
+				if ( lutil_atol( &larg, c->argv[1] ) != 0 ) {
+					snprintf( c->msg, sizeof( c->msg ),
+						"<%s> unable to parse \"%s\" as long",
+						c->argv[0], c->argv[1] );
+					Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
+						c->log, c->msg, 0);
+					return(ARG_BAD_CONF);
+				}
+				break;
+			case ARG_BER_LEN_T: {
+				unsigned long	l;
+				if ( lutil_atoul( &l, c->argv[1] ) != 0 ) {
+					snprintf( c->msg, sizeof( c->msg ),
+						"<%s> unable to parse \"%s\" as ber_len_t",
+						c->argv[0], c->argv[1] );
+					Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
+						c->log, c->msg, 0);
+					return(ARG_BAD_CONF);
+				}
+				barg = (ber_len_t)l;
+				} break;
 			case ARG_ON_OFF:
-				if(c->argc == 1) {
+				if (c->argc == 1) {
 					iarg = 1;
-				} else if(!strcasecmp(c->argv[1], "on") ||
-					!strcasecmp(c->argv[1], "true")) {
+				} else if ( !strcasecmp(c->argv[1], "on") ||
+					!strcasecmp(c->argv[1], "true") ||
+					!strcasecmp(c->argv[1], "yes") )
+				{
 					iarg = 1;
-				} else if(!strcasecmp(c->argv[1], "off") ||
-					!strcasecmp(c->argv[1], "false")) {
+				} else if ( !strcasecmp(c->argv[1], "off") ||
+					!strcasecmp(c->argv[1], "false") ||
+					!strcasecmp(c->argv[1], "no") )
+				{
 					iarg = 0;
 				} else {
 					snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value, ignored",
@@ -448,6 +481,7 @@ init_config_attrs(ConfigTable *ct) {
 				freeit = 1;
 
 			} else {
+				ldap_attributetype_free( at );
 				fprintf( stderr, "init_config_attrs: AttributeType \"%s\": %s, %s\n",
 					ct[i].attribute, scherr2str(code), err );
 				return code;
@@ -1013,9 +1047,11 @@ slap_cf_aux_table_parse( const char *word, void *dst, slap_cf_aux_table *tab0, L
 
 	for (tab = tab0; !BER_BVISNULL(&tab->key); tab++ ) {
 		if ( !strncasecmp( word, tab->key.bv_val, tab->key.bv_len )) {
-			char **cptr, *next;
+			char **cptr;
 			int *iptr, j;
 			unsigned *uptr;
+			long *lptr;
+			unsigned long *ulptr;
 			struct berval *bptr;
 			const char *val = word + tab->key.bv_len;
 
@@ -1046,19 +1082,25 @@ slap_cf_aux_table_parse( const char *word, void *dst, slap_cf_aux_table *tab0, L
 			case 'i':
 				iptr = (int *)((char *)dst + tab->off);
 
-				*iptr = strtol( val, &next, 0 );
-				if ( next == val || next[ 0 ] != '\0' ) {
-					rc = 1;
-				}
+				rc = lutil_atoix( iptr, val, 0 );
 				break;
 
 			case 'u':
 				uptr = (unsigned *)((char *)dst + tab->off);
 
-				*uptr = strtoul( val, &next, 0 );
-				if ( next == val || next[ 0 ] != '\0' ) {
-					rc = 1;
-				}
+				rc = lutil_atoux( uptr, val, 0 );
+				break;
+
+			case 'I':
+				lptr = (long *)((char *)dst + tab->off);
+
+				rc = lutil_atolx( lptr, val, 0 );
+				break;
+
+			case 'U':
+				ulptr = (unsigned long *)((char *)dst + tab->off);
+
+				rc = lutil_atoulx( ulptr, val, 0 );
 				break;
 			}
 
@@ -1086,6 +1128,8 @@ slap_cf_aux_table_unparse( void *src, struct berval *bv, slap_cf_aux_table *tab0
 		char **cptr;
 		int *iptr, i;
 		unsigned *uptr;
+		long *lptr;
+		unsigned long *ulptr;
 		struct berval *bptr;
 
 		cptr = (char **)((char *)src + tab->off);
@@ -1131,6 +1175,23 @@ slap_cf_aux_table_unparse( void *src, struct berval *bv, slap_cf_aux_table *tab0
 			ptr = lutil_strcopy( ptr, tab->key.bv_val );
 			ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%u", *uptr );
 			break;
+
+		case 'I':
+			lptr = (long *)((char *)src + tab->off);
+			*ptr++ = ' ';
+			ptr = lutil_strcopy( ptr, tab->key.bv_val );
+			ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%ld", *lptr );
+			break;
+
+		case 'U':
+			ulptr = (unsigned long *)((char *)src + tab->off);
+			*ptr++ = ' ';
+			ptr = lutil_strcopy( ptr, tab->key.bv_val );
+			ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%lu", *ulptr );
+			break;
+
+		default:
+			assert( 0 );
 		}
 	}
 	tmp.bv_val = buf;
diff --git a/servers/slapd/config.h b/servers/slapd/config.h
index 3dc25928031df9e67f4e24142fecf50b8fcee7fb..b5085e2a15c4be974fcb2a0a040f8d0537560890 100644
--- a/servers/slapd/config.h
+++ b/servers/slapd/config.h
@@ -14,6 +14,9 @@
  * <http://www.OpenLDAP.org/license.html>.
  */
 
+#ifndef CONFIG_H
+#define CONFIG_H
+
 typedef struct ConfigTable {
 	char *name;
 	char *what;
@@ -169,3 +172,13 @@ int read_config_file(const char *fname, int depth, ConfigArgs *cf,
 ConfigTable * config_find_keyword(ConfigTable *ct, ConfigArgs *c);
 Entry * config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
 	ConfigArgs *c, struct berval *rdn, ConfigOCs *main, ConfigOCs *extra );
+
+int config_shadow( ConfigArgs *c, int flag );
+#define	config_slurp_shadow(c)	config_shadow((c), SLAP_DBFLAG_SLURP_SHADOW)
+#define	config_sync_shadow(c)	config_shadow((c), SLAP_DBFLAG_SYNC_SHADOW)
+
+	/* Make sure we don't exceed the bits reserved for userland */
+#define	config_check_userland(last) \
+	assert( ( ( (last) - 1 ) & ARGS_USERLAND ) == ( (last) - 1 ) );
+
+#endif /* CONFIG_H */
diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c
index c2be214f59f3e442408da0b329610b34e6253723..a83739966d68a597ca37aa11c35ca8bd77d73477 100644
--- a/servers/slapd/connection.c
+++ b/servers/slapd/connection.c
@@ -606,9 +606,7 @@ long connection_init(
 		c->c_send_search_entry = slap_send_search_entry;
 		c->c_send_search_reference = slap_send_search_reference;
 		c->c_send_ldap_extended = slap_send_ldap_extended;
-#ifdef LDAP_RES_INTERMEDIATE
 		c->c_send_ldap_intermediate = slap_send_ldap_intermediate;
-#endif
 
 		BER_BVZERO( &c->c_authmech );
 		BER_BVZERO( &c->c_dn );
diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c
index 942749519c3fe0ba71a0ac556186d0d872a029f1..63b6b31dc4b7afc2cb90a734653f21d72bf0974c 100644
--- a/servers/slapd/controls.c
+++ b/servers/slapd/controls.c
@@ -29,6 +29,7 @@ static SLAP_CTRL_PARSE_FN parsePreRead;
 static SLAP_CTRL_PARSE_FN parsePostRead;
 static SLAP_CTRL_PARSE_FN parseProxyAuthz;
 #ifdef LDAP_DEVEL
+static SLAP_CTRL_PARSE_FN parseDontUseCopy;
 static SLAP_CTRL_PARSE_FN parseManageDIT;
 #endif
 static SLAP_CTRL_PARSE_FN parseManageDSAit;
@@ -125,41 +126,37 @@ static struct slap_control control_defs[] = {
 		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL,
 		parseSortedResults, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
 	{ LDAP_CONTROL_X_DOMAIN_SCOPE,
  		(int)offsetof(struct slap_control_ids, sc_domainScope),
-		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL,
+		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL,
 		parseDomainScope, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#endif
-#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
 	{ LDAP_CONTROL_X_PERMISSIVE_MODIFY,
  		(int)offsetof(struct slap_control_ids, sc_permissiveModify),
-		SLAP_CTRL_MODIFY, NULL,
+		SLAP_CTRL_MODIFY|SLAP_CTRL_HIDE, NULL,
 		parsePermissiveModify, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#endif
 #ifdef SLAP_CONTROL_X_TREE_DELETE
 	{ LDAP_CONTROL_X_TREE_DELETE,
  		(int)offsetof(struct slap_control_ids, sc_treeDelete),
-		SLAP_CTRL_HIDE|SLAP_CTRL_DELETE, NULL,
+		SLAP_CTRL_DELETE|SLAP_CTRL_HIDE, NULL,
 		parseTreeDelete, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
-#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS
 	{ LDAP_CONTROL_X_SEARCH_OPTIONS,
  		(int)offsetof(struct slap_control_ids, sc_searchOptions),
-		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL,
+		SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL,
 		parseSearchOptions, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#endif
-#ifdef LDAP_CONTROL_SUBENTRIES
 	{ LDAP_CONTROL_SUBENTRIES,
  		(int)offsetof(struct slap_control_ids, sc_subentries),
 		SLAP_CTRL_SEARCH, NULL,
 		parseSubentries, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#endif
 	{ LDAP_CONTROL_NOOP,
  		(int)offsetof(struct slap_control_ids, sc_noOp),
-		SLAP_CTRL_HIDE|SLAP_CTRL_ACCESS, NULL,
+		SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE, NULL,
 		parseNoOp, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #ifdef LDAP_DEVEL
+	{ LDAP_CONTROL_DONTUSECOPY,
+ 		(int)offsetof(struct slap_control_ids, sc_dontUseCopy),
+		SLAP_CTRL_INTROGATE|SLAP_CTRL_HIDE, NULL,
+		parseDontUseCopy, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 	{ LDAP_CONTROL_MANAGEDIT,
  		(int)offsetof(struct slap_control_ids, sc_manageDIT),
 		SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE|SLAP_CTRL_HIDE, NULL,
@@ -706,7 +703,8 @@ slap_remove_control(
 	switch ( op->o_ctrlflag[ ctrl ] ) {
 	case SLAP_CONTROL_NONCRITICAL:
 		for ( i = 0, j = -1; op->o_ctrls[ i ] != NULL; i++ ) {
-			if ( strcmp( op->o_ctrls[ i ]->ldctl_oid, slap_known_controls[ ctrl - 1 ] ) == 0 )
+			if ( strcmp( op->o_ctrls[ i ]->ldctl_oid,
+				slap_known_controls[ ctrl - 1 ] ) == 0 )
 			{
 				j = i;
 			}
@@ -763,6 +761,30 @@ slap_remove_control(
 }
 
 #ifdef LDAP_DEVEL
+static int parseDontUseCopy (
+	Operation *op,
+	SlapReply *rs,
+	LDAPControl *ctrl )
+{
+	if ( op->o_dontUseCopy != SLAP_CONTROL_NONE ) {
+		rs->sr_text = "dontUseCopy control specified multiple times";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	if ( ctrl->ldctl_value.bv_len ) {
+		rs->sr_text = "dontUseCopy control value not empty";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	if ( ctrl->ldctl_iscritical != SLAP_CONTROL_CRITICAL ) {
+		rs->sr_text = "dontUseCopy criticality of FALSE not allowed";
+		return LDAP_PROTOCOL_ERROR;
+	}
+
+	op->o_dontUseCopy = SLAP_CONTROL_CRITICAL;
+	return LDAP_SUCCESS;
+}
+
 static int parseManageDIT (
 	Operation *op,
 	SlapReply *rs,
@@ -1042,8 +1064,8 @@ static int parseAssert (
 		return LDAP_OTHER;
 	}
 	
-	rs->sr_err = get_filter( op, ber, (Filter **)&(op->o_assertion), &rs->sr_text);
-
+	rs->sr_err = get_filter( op, ber, (Filter **)&(op->o_assertion),
+		&rs->sr_text);
 	if( rs->sr_err != LDAP_SUCCESS ) {
 		if( rs->sr_err == SLAPD_DISCONNECT ) {
 			rs->sr_err = LDAP_PROTOCOL_ERROR;
@@ -1214,7 +1236,8 @@ static int parseValuesReturnFilter (
 		return LDAP_OTHER;
 	}
 	
-	rs->sr_err = get_vrFilter( op, ber, (ValuesReturnFilter **)&(op->o_vrFilter), &rs->sr_text);
+	rs->sr_err = get_vrFilter( op, ber,
+		(ValuesReturnFilter **)&(op->o_vrFilter), &rs->sr_text);
 
 	if( rs->sr_err != LDAP_SUCCESS ) {
 		if( rs->sr_err == SLAPD_DISCONNECT ) {
@@ -1244,7 +1267,6 @@ static int parseValuesReturnFilter (
 	return LDAP_SUCCESS;
 }
 
-#ifdef LDAP_CONTROL_SUBENTRIES
 static int parseSubentries (
 	Operation *op,
 	SlapReply *rs,
@@ -1274,9 +1296,7 @@ static int parseSubentries (
 
 	return LDAP_SUCCESS;
 }
-#endif
 
-#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
 static int parsePermissiveModify (
 	Operation *op,
 	SlapReply *rs,
@@ -1298,9 +1318,7 @@ static int parsePermissiveModify (
 
 	return LDAP_SUCCESS;
 }
-#endif
 
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
 static int parseDomainScope (
 	Operation *op,
 	SlapReply *rs,
@@ -1322,7 +1340,6 @@ static int parseDomainScope (
 
 	return LDAP_SUCCESS;
 }
-#endif
 
 #ifdef SLAP_CONTROL_X_TREE_DELETE
 static int parseTreeDelete (
@@ -1348,7 +1365,6 @@ static int parseTreeDelete (
 }
 #endif
 
-#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS
 static int parseSearchOptions (
 	Operation *op,
 	SlapReply *rs,
@@ -1399,5 +1415,4 @@ static int parseSearchOptions (
 
 	return LDAP_SUCCESS;
 }
-#endif
 
diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c
index 9d1df57a1255a3f7bcaaa3d6b09ad311faf0ec46..99c2f7c579dfd669d4701ac71bc4edf678f8397b 100644
--- a/servers/slapd/daemon.c
+++ b/servers/slapd/daemon.c
@@ -1729,9 +1729,13 @@ slapd_daemon_task(
 			ber_socket_t active;
 
 			if( slapd_gentle_shutdown == 1 ) {
+				BackendDB *be;
 				Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n", 0, 0, 0 );
 				close_listeners( 1 );
 				frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
+				LDAP_STAILQ_FOREACH(be, &backendDB, be_next) {
+					be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
+				}
 				slapd_gentle_shutdown = 2;
 			}
 
@@ -1739,7 +1743,7 @@ slapd_daemon_task(
 			active = slap_daemon.sd_nactives;
 			ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
 			if( active == 0 ) {
-				slapd_shutdown = 2;
+				slapd_shutdown = 1;
 				break;
 			}
 		}
diff --git a/servers/slapd/filter.c b/servers/slapd/filter.c
index eea855a4ae80b696861bc3e6fd56dcb04f8d7691..4f7b1516646546c82dc7d34d2a0ad4897ff23d95 100644
--- a/servers/slapd/filter.c
+++ b/servers/slapd/filter.c
@@ -45,11 +45,6 @@ static int	get_ssa(
 	SubstringsAssertion **s,
 	const char **text );
 
-static int filter_escape_value_x(
-	struct berval *in,
-	struct berval *out,
-	void *ctx );
-
 static void simple_vrFilter2bv(
 	Operation *op,
 	ValuesReturnFilter *f,
@@ -782,42 +777,6 @@ filter2bv( Filter *f, struct berval *fstr )
 	filter2bv_x( &op, f, fstr );
 }
 
-static int
-filter_escape_value_x(
-	struct berval *in,
-	struct berval *out,
-	void *ctx )
-{
-	ber_len_t i;
-	assert( in != NULL );
-	assert( out != NULL );
-
-	i = in->bv_len * 3 + 1;
-	out->bv_val = ctx ? slap_sl_malloc( i, ctx ) : ch_malloc( i );
-	out->bv_len = 0;
-
-	for( i=0; i < in->bv_len ; i++ ) {
-		if( FILTER_ESCAPE(in->bv_val[i]) ) {
-			out->bv_val[out->bv_len++] = SLAP_ESCAPE_CHAR;
-			out->bv_val[out->bv_len++] = SLAP_ESCAPE_HI( in->bv_val[i] );
-			out->bv_val[out->bv_len++] = SLAP_ESCAPE_LO( in->bv_val[i] );
-		} else {
-			out->bv_val[out->bv_len++] = in->bv_val[i];
-		}
-	}
-
-	out->bv_val[out->bv_len] = '\0';
-	return LDAP_SUCCESS;
-}
-
-int
-filter_escape_value(
-	struct berval *in,
-	struct berval *out )
-{
-	return filter_escape_value_x( in, out, NULL );
-}
-
 static int
 get_simple_vrFilter(
 	Operation *op,
diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c
index e2037811910ce622db318fd55ae87e720fb0cb0c..f4e80ac873efdbcae87dd429bdb0e3210b4cb187 100644
--- a/servers/slapd/ldapsync.c
+++ b/servers/slapd/ldapsync.c
@@ -112,7 +112,6 @@ slap_parse_sync_cookie(
 		|| rid_ptr > &cookie->octet_str.bv_val[ cookie->octet_str.bv_len - STRLENOF( "rid=" ) ] )
 	{
 		return -1;
-
 	}
 
 	cookie->rid = strtoul( &rid_ptr[ STRLENOF( "rid=" ) ], &next, 10 );
diff --git a/servers/slapd/limits.c b/servers/slapd/limits.c
index 691a1163661659fb730db628a721666d26ea3c45..053efd90bd3116dd19bb942dd7896f7fe5277166 100644
--- a/servers/slapd/limits.c
+++ b/servers/slapd/limits.c
@@ -650,14 +650,9 @@ limits_parse_one(
 					limit->lms_t_soft = -1;
 
 				} else {
-					char	*next = NULL;
-					int	soft = strtol( arg, &next, 10 );
+					int	soft;
 
-					if ( next == arg || next[ 0 ] != '\0' ) {
-						return( 1 );
-					}
-
-					if ( soft < -1 ) {
+					if ( lutil_atoi( &soft, arg ) != 0 || soft < -1 ) {
 						return( 1 );
 					}
 
@@ -677,14 +672,9 @@ limits_parse_one(
 					limit->lms_t_hard = -1;
 
 				} else {
-					char	*next = NULL;
-					int	hard = strtol( arg, &next, 10 );
-
-					if ( next == arg || next[ 0 ] != '\0' ) {
-						return( 1 );
-					}
+					int	hard;
 
-					if ( hard < -1 ) {
+					if ( lutil_atoi( &hard, arg ) != 0 || hard < -1 ) {
 						return( 1 );
 					}
 
@@ -709,10 +699,9 @@ limits_parse_one(
 				limit->lms_t_soft = -1;
 
 			} else {
-				char	*next = NULL;
-
-				limit->lms_t_soft = strtol( arg, &next, 10 );
-				if ( next == arg || limit->lms_t_soft < -1 ) {
+				if ( lutil_atoi( &limit->lms_t_soft, arg ) != 0 
+					|| limit->lms_t_soft < -1 )
+				{
 					return( 1 );
 				}
 			}
@@ -733,14 +722,9 @@ limits_parse_one(
 					limit->lms_s_soft = -1;
 
 				} else {
-					char	*next = NULL;
-					int	soft = strtol( arg, &next, 10 );
-
-					if ( next == arg || next[ 0 ] != '\0' ) {
-						return( 1 );
-					}
+					int	soft;
 
-					if ( soft < -1 ) {
+					if ( lutil_atoi( &soft, arg ) != 0 || soft < -1 ) {
 						return( 1 );
 					}
 
@@ -760,14 +744,9 @@ limits_parse_one(
 					limit->lms_s_hard = -1;
 
 				} else {
-					char	*next = NULL;
-					int	hard = strtol( arg, &next, 10 );
+					int	hard;
 
-					if ( next == arg || next[ 0 ] != '\0' ) {
-						return( 1 );
-					}
-
-					if ( hard < -1 ) {
+					if ( lutil_atoi( &hard, arg ) != 0 || hard < -1 ) {
 						return( 1 );
 					}
 
@@ -791,14 +770,9 @@ limits_parse_one(
 					limit->lms_s_unchecked = 0;
 
 				} else {
-					char	*next = NULL;
-					int	unchecked = strtol( arg, &next, 10 );
-
-					if ( next == arg || next[ 0 ] != '\0' ) {
-						return( 1 );
-					}
+					int	unchecked;
 
-					if ( unchecked < -1 ) {
+					if ( lutil_atoi( &unchecked, arg ) != 0 || unchecked < -1 ) {
 						return( 1 );
 					}
 
@@ -818,14 +792,9 @@ limits_parse_one(
 					limit->lms_s_pr = -1;
 
 				} else {
-					char	*next = NULL;
-					int	pr = strtol( arg, &next, 10 );
+					int	pr;
 
-					if ( next == arg || next[ 0 ] != '\0' ) {
-						return( 1 );
-					}
-
-					if ( pr < -1 ) {
+					if ( lutil_atoi( &pr, arg ) != 0 || pr < -1 ) {
 						return( 1 );
 					}
 
@@ -849,15 +818,9 @@ limits_parse_one(
 					limit->lms_s_pr_total = 0;
 
 				} else {
-					char	*next = NULL;
 					int	total;
 
-					total = strtol( arg, &next, 10 );
-					if ( next == arg || next[ 0 ] != '\0' ) {
-						return( 1 );
-					}
-
-					if ( total < -1 ) {
+					if ( lutil_atoi( &total, arg ) != 0 || total < -1 ) {
 						return( 1 );
 					}
 
@@ -882,10 +845,9 @@ limits_parse_one(
 				limit->lms_s_soft = -1;
 
 			} else {
-				char	*next = NULL;
-
-				limit->lms_s_soft = strtol( arg, &next, 10 );
-				if ( next == arg || limit->lms_s_soft < -1 ) {
+				if ( lutil_atoi( &limit->lms_s_soft, arg ) != 0
+					|| limit->lms_s_soft < -1 )
+				{
 					return( 1 );
 				}
 			}
diff --git a/servers/slapd/main.c b/servers/slapd/main.c
index f74bc4f231ae9f799e5a2302ae015501a9eab040..c47f477893e0ed665ea504d4a6b2a2afd105ba05 100644
--- a/servers/slapd/main.c
+++ b/servers/slapd/main.c
@@ -406,10 +406,8 @@ int main( int argc, char **argv )
 				slap_debug |= level;
 			} else {
 				int	level;
-				char	*next = NULL;
 
-				level = strtol( optarg, &next, 0 );
-				if ( next == NULL || next[ 0 ] != '\0' ) {
+				if ( lutil_atoix( &level, optarg, 0 ) != 0 ) {
 					fprintf( stderr,
 						"unrecognized log level "
 						"\"%s\"\n", optarg );
@@ -418,7 +416,7 @@ int main( int argc, char **argv )
 				slap_debug |= level;
 			}
 #else
-			if ( atoi( optarg ) != 0 )
+			if ( lutil_atoi( &level, optarg ) != 0 || level != 0 )
 				fputs( "must compile with LDAP_DEBUG for debugging\n",
 				       stderr );
 #endif
@@ -467,7 +465,10 @@ int main( int argc, char **argv )
 		}
 
 		case 's':	/* set syslog level */
-			ldap_syslog = atoi( optarg );
+			if ( lutil_atoi( &ldap_syslog, optarg ) != 0 ) {
+				fprintf( stderr, "unable to parse syslog level \"%s\"", optarg );
+				goto destroy;
+			}
 			break;
 
 #ifdef LOG_LOCAL4
diff --git a/servers/slapd/mods.c b/servers/slapd/mods.c
index 40945fd21fbc9c5ab5c39b752eba3c00cb243b18..918a25a4ffb59c38200858c45e8b4ffbb2031c75 100644
--- a/servers/slapd/mods.c
+++ b/servers/slapd/mods.c
@@ -28,6 +28,7 @@
 #include <ac/string.h>
 
 #include "slap.h"
+#include "lutil.h"
 
 int
 modify_add_values(
@@ -386,7 +387,12 @@ modify_increment_values(
 	if ( !strcmp( a->a_desc->ad_type->sat_syntax_oid, SLAPD_INTEGER_SYNTAX )) {
 		int i;
 		char str[sizeof(long)*3 + 2]; /* overly long */
-		long incr = atol( mod->sm_values[0].bv_val );
+		long incr;
+
+		if ( lutil_atol( &incr, mod->sm_values[0].bv_val ) != 0 ) {
+			*text = "modify/increment: invalid syntax of increment";
+			return LDAP_INVALID_SYNTAX;
+		}
 
 		/* treat zero and errors as a no-op */
 		if( incr == 0 ) {
@@ -395,13 +401,18 @@ modify_increment_values(
 
 		for( i = 0; !BER_BVISNULL( &a->a_nvals[i] ); i++ ) {
 			char *tmp;
-			long value = atol( a->a_nvals[i].bv_val );
-			size_t strln = snprintf( str, sizeof(str), "%ld", value+incr );
+			long value;
+			size_t strln;
+			if ( lutil_atol( &value, a->a_nvals[i].bv_val ) != 0 ) {
+				*text = "modify/increment: invalid syntax of original value";
+				return LDAP_INVALID_SYNTAX;
+			}
+			strln = snprintf( str, sizeof(str), "%ld", value+incr );
 
 			tmp = SLAP_REALLOC( a->a_nvals[i].bv_val, strln+1 );
 			if( tmp == NULL ) {
 				*text = "modify/increment: reallocation error";
-				return LDAP_OTHER;;
+				return LDAP_OTHER;
 			}
 			a->a_nvals[i].bv_val = tmp;
 			a->a_nvals[i].bv_len = strln;
diff --git a/servers/slapd/oc.c b/servers/slapd/oc.c
index af3913b602fc935c4962e16eafc98ecc57b86d16..acf8a5ff8b8d8c5e6869b47f5cf47b99bacbec74 100644
--- a/servers/slapd/oc.c
+++ b/servers/slapd/oc.c
@@ -524,6 +524,30 @@ oc_insert(
 				rc = oc_check_dup( old_soc, soc );
 
 				ldap_memfree( oir );
+
+				while ( names > soc->soc_names ) {
+					struct oindexrec	tmpoir;
+
+					names--;
+					ber_str2bv( *names, 0, 0, &tmpoir.oir_name );
+					tmpoir.oir_oc = soc;
+					oir = (struct oindexrec *)avl_delete( &oc_index,
+						(caddr_t)&tmpoir, oc_index_cmp );
+					assert( oir != NULL );
+					ldap_memfree( oir );
+				}
+
+				if ( soc->soc_oid ) {
+					struct oindexrec	tmpoir;
+
+					ber_str2bv( soc->soc_oid, 0, 0, &tmpoir.oir_name );
+					tmpoir.oir_oc = soc;
+					oir = (struct oindexrec *)avl_delete( &oc_index,
+						(caddr_t)&tmpoir, oc_index_cmp );
+					assert( oir != NULL );
+					ldap_memfree( oir );
+				}
+
 				return rc;
 			}
 
diff --git a/servers/slapd/overlays/Makefile.in b/servers/slapd/overlays/Makefile.in
index 86c8f043ca38fcf3f5e5b12184006e82a37682e0..5468620ba2d2bee7c5cf7fd07df498e10c6eaf44 100644
--- a/servers/slapd/overlays/Makefile.in
+++ b/servers/slapd/overlays/Makefile.in
@@ -29,6 +29,7 @@ SRCS = overlays.c \
 	unique.c \
 	valsort.c
 OBJS = overlays.o \
+	statover.o \
 	@SLAPD_STATIC_OVERLAYS@
 
 # Add here the objs that are needed by overlays, but do not make it
@@ -113,6 +114,8 @@ MKDEPFLAG = -l
 .c.lo:
 	$(LTCOMPILE_MOD) $<
 
+statover.o: statover.c $(srcdir)/../slap.h
+
 $(LIBRARY): $(OBJS) version.lo
 	$(AR) rs $@ $(OBJS)
 
@@ -124,3 +127,6 @@ depend-local:
 	mv Makefile Makefile.bak; $(SED) $$SCR Makefile.bak > Makefile && \
 	$(RM) Makefile.bak; fi
 
+veryclean-local:
+	$(RM) statover.c
+
diff --git a/servers/slapd/overlays/accesslog.c b/servers/slapd/overlays/accesslog.c
index 4b37dce011a87e610d9489cefeff531d8e71895e..e802492e8f2c8204a0383fbfb3e4c44f68d09f9f 100644
--- a/servers/slapd/overlays/accesslog.c
+++ b/servers/slapd/overlays/accesslog.c
@@ -990,7 +990,9 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
 
 		bv.bv_len = sprintf( bv.bv_val, "%d", op->ors_tlimit );
 		attr_merge_one( e, ad_reqTimeLimit, &bv, NULL );
-		/* FIXME: slimit was zeroed by the backends */
+
+		bv.bv_len = sprintf( bv.bv_val, "%d", op->ors_slimit );
+		attr_merge_one( e, ad_reqSizeLimit, &bv, NULL );
 		break;
 
 	case LOG_EN_BIND:
@@ -1200,20 +1202,113 @@ accesslog_db_destroy(
 {
 	slap_overinst *on = (slap_overinst *)be->bd_info;
 	log_info *li = on->on_bi.bi_private;
-	
+
 	ldap_pvt_thread_mutex_destroy( &li->li_log_mutex );
 	ldap_pvt_thread_mutex_destroy( &li->li_op_mutex );
 	free( li );
 	return LDAP_SUCCESS;
 }
 
-int accesslog_init()
+static int
+accesslog_db_open(
+	BackendDB *be
+)
+{
+	slap_overinst *on = (slap_overinst *)be->bd_info;
+	log_info *li = on->on_bi.bi_private;
+
+	Connection conn;
+	OperationBuffer opbuf;
+	Operation *op = (Operation *) &opbuf;
+	Entry *e;
+	int rc;
+	void *thrctx;
+
+	if ( slapMode & SLAP_TOOL_MODE )
+		return 0;
+
+	thrctx = ldap_pvt_thread_pool_context();
+	connection_fake_init( &conn, op, thrctx );
+	op->o_bd = li->li_db;
+	op->o_dn = li->li_db->be_rootdn;
+	op->o_ndn = li->li_db->be_rootndn;
+
+	rc = be_entry_get_rw( op, li->li_db->be_nsuffix, NULL, NULL, 0, &e );
+
+	if ( e ) {
+		be_entry_release_rw( op, e, 0 );
+	} else {
+		SlapReply rs = {REP_RESULT};
+		struct berval rdn, nrdn, attr;
+		char *ptr;
+		AttributeDescription *ad = NULL;
+		const char *text = NULL;
+		Entry *e_ctx;
+
+		e = ch_calloc( 1, sizeof( Entry ));
+		e->e_name = *li->li_db->be_suffix;
+		e->e_nname = *li->li_db->be_nsuffix;
+
+		attr_merge_one( e, slap_schema.si_ad_objectClass,
+			&log_container->soc_cname, NULL );
+
+		dnRdn( &e->e_name, &rdn );
+		dnRdn( &e->e_nname, &nrdn );
+		ptr = ber_bvchr( &rdn, '=' );
+
+		assert( ptr != NULL );
+
+		attr.bv_val = rdn.bv_val;
+		attr.bv_len = ptr - rdn.bv_val;
+
+		slap_bv2ad( &attr, &ad, &text );
+
+		rdn.bv_val = ptr+1;
+		rdn.bv_len -= attr.bv_len + 1;
+		ptr = ber_bvchr( &nrdn, '=' );
+		nrdn.bv_len -= ptr - nrdn.bv_val + 1;
+		nrdn.bv_val = ptr+1;
+		attr_merge_one( e, ad, &rdn, &nrdn );
+
+		/* Get contextCSN from main DB */
+		op->o_bd = be;
+		op->o_bd->bd_info = on->on_info->oi_orig;
+		rc = be_entry_get_rw( op, be->be_nsuffix, NULL,
+			slap_schema.si_ad_contextCSN, 0, &e_ctx );
+
+		if ( e_ctx ) {
+			Attribute *a;
+
+			a = attr_find( e_ctx->e_attrs, slap_schema.si_ad_contextCSN );
+			if ( a )
+				attr_merge( e, a->a_desc, a->a_vals, NULL );
+			be_entry_release_rw( op, e_ctx, 0 );
+		}
+		op->o_bd->bd_info = (BackendInfo *)on;
+		op->o_bd = li->li_db;
+
+		op->ora_e = e;
+		op->o_req_dn = e->e_name;
+		op->o_req_ndn = e->e_nname;
+		op->o_callback = &nullsc;
+		SLAP_DBFLAGS( op->o_bd ) |= SLAP_DBFLAG_NOLASTMOD;
+		rc = op->o_bd->be_add( op, &rs );
+		SLAP_DBFLAGS( op->o_bd ) ^= SLAP_DBFLAG_NOLASTMOD;
+		attrs_free( e->e_attrs );
+		ch_free( e );
+	}
+	ldap_pvt_thread_pool_context_reset( thrctx );
+	return rc;
+}
+
+int accesslog_initialize()
 {
 	int i, rc;
 
 	accesslog.on_bi.bi_type = "accesslog";
 	accesslog.on_bi.bi_db_init = accesslog_db_init;
 	accesslog.on_bi.bi_db_destroy = accesslog_db_destroy;
+	accesslog.on_bi.bi_db_open = accesslog_db_open;
 
 	accesslog.on_bi.bi_op_add = accesslog_op_mod;
 	accesslog.on_bi.bi_op_bind = accesslog_op_bind;
@@ -1292,8 +1387,10 @@ int accesslog_init()
 }
 
 #if SLAPD_OVER_ACCESSLOG == SLAPD_MOD_DYNAMIC
-int init_module( int argc, char *argv[]) {
-	return accesslog_init();
+int
+init_module( int argc, char *argv[] )
+{
+	return accesslog_initialize();
 }
 #endif
 
diff --git a/servers/slapd/overlays/auditlog.c b/servers/slapd/overlays/auditlog.c
index 41da39cbc8510498efdc2c22a65cc02c15faaff4..ab245794192b6f5110047f25041653debca3c91c 100644
--- a/servers/slapd/overlays/auditlog.c
+++ b/servers/slapd/overlays/auditlog.c
@@ -215,7 +215,7 @@ auditlog_config(
 	return SLAP_CONF_UNKNOWN;
 }
 
-int auditlog_init() {
+int auditlog_initialize() {
 
 	auditlog.on_bi.bi_type = "auditlog";
 	auditlog.on_bi.bi_db_init = auditlog_db_init;
@@ -228,8 +228,10 @@ int auditlog_init() {
 }
 
 #if SLAPD_OVER_AUDITLOG == SLAPD_MOD_DYNAMIC && defined(PIC)
-int init_module( int argc, char *argv[]) {
-	return auditlog_init();
+int
+init_module( int argc, char *argv[] )
+{
+	return auditlog_initialize();
 }
 #endif
 
diff --git a/servers/slapd/overlays/collect.c b/servers/slapd/overlays/collect.c
index 84bb00947ca329b3cd1647c6ad0ac036e86d663f..f87fed856515ff9ee4829d5de75963b7cdf09f30 100644
--- a/servers/slapd/overlays/collect.c
+++ b/servers/slapd/overlays/collect.c
@@ -153,7 +153,7 @@ static int collect_config(
 
 static slap_overinst collect;
 
-int collect_init() {
+int collect_initialize() {
 	collect.on_bi.bi_type = "collect";
 	collect.on_bi.bi_db_config = collect_config;
 	collect.on_response = collect_response;
@@ -163,7 +163,7 @@ int collect_init() {
 
 #if SLAPD_OVER_COLLECT == SLAPD_MOD_DYNAMIC
 int init_module(int argc, char *argv[]) {
-	return collect_init();
+	return collect_initialize();
 }
 #endif
 
diff --git a/servers/slapd/overlays/denyop.c b/servers/slapd/overlays/denyop.c
index 759a831d8db262db76325d46881f0c2d0a9b8de7..b3db024a99c1342e2c8184067c9a88fce7cc39af 100644
--- a/servers/slapd/overlays/denyop.c
+++ b/servers/slapd/overlays/denyop.c
@@ -224,7 +224,7 @@ denyop_destroy(
 static slap_overinst denyop;
 
 int
-denyop_init( void )
+denyop_initialize( void )
 {
 	memset( &denyop, 0, sizeof( slap_overinst ) );
 	denyop.on_bi.bi_type = "denyop";
@@ -251,7 +251,7 @@ denyop_init( void )
 int
 init_module( int argc, char *argv[] )
 {
-	return denyop_init();
+	return denyop_initialize();
 }
 #endif /* SLAPD_OVER_DENYOP == SLAPD_MOD_DYNAMIC */
 
diff --git a/servers/slapd/overlays/dyngroup.c b/servers/slapd/overlays/dyngroup.c
index 1bdd95e14e075c114a8e8bbcf74797ec7b35d7e0..620224c14c3f8c14430b3332ca78813348de97df 100644
--- a/servers/slapd/overlays/dyngroup.c
+++ b/servers/slapd/overlays/dyngroup.c
@@ -146,7 +146,7 @@ static slap_overinst dyngroup;
  * initialized and registered by some other function inside slapd.
  */
 
-int dyngroup_init() {
+int dyngroup_initialize() {
 	dyngroup.on_bi.bi_type = "dyngroup";
 	dyngroup.on_bi.bi_db_config = dyngroup_config;
 	dyngroup.on_bi.bi_db_close = dyngroup_close;
@@ -156,8 +156,10 @@ int dyngroup_init() {
 }
 
 #if SLAPD_OVER_DYNGROUP == SLAPD_MOD_DYNAMIC
-int init_module(int argc, char *argv[]) {
-	return dyngroup_init();
+int
+init_module( int argc, char *argv[] )
+{
+	return dyngroup_initialize();
 }
 #endif
 
diff --git a/servers/slapd/overlays/dynlist.c b/servers/slapd/overlays/dynlist.c
index e28d7315bc48c7d3eb1f6fd6d37c7ff868498f63..5ccccaf3b965ab97227c47b042ecfe9296568c95 100644
--- a/servers/slapd/overlays/dynlist.c
+++ b/servers/slapd/overlays/dynlist.c
@@ -588,7 +588,17 @@ dynlist_response( Operation *op, SlapReply *rs )
 		break;
 
 	case LDAP_REQ_COMPARE:
-		if ( rs->sr_err == LDAP_NO_SUCH_ATTRIBUTE ) {
+		switch ( rs->sr_err ) {
+		/* NOTE: we waste a few cycles running the dynamic list
+		 * also when the result is FALSE, which occurs if the
+		 * dynamic entry itself contains the AVA attribute  */
+		/* FIXME: this approach is less than optimal; a dedicated
+		 * compare op should be implemented, that fetches the
+		 * entry, checks if it has the appropriate objectClass
+		 * and, in case, runs a compare thru all the URIs,
+		 * stopping at the first positive occurrence; see ITS#3756 */
+		case LDAP_COMPARE_FALSE:
+		case LDAP_NO_SUCH_ATTRIBUTE:
 			return dynlist_compare( op, rs );
 		}
 		break;
@@ -602,12 +612,11 @@ dynlist_response( Operation *op, SlapReply *rs )
 
 static int
 dynlist_db_config(
-    BackendDB	*be,
-    const char	*fname,
-    int		lineno,
-    int		argc,
-    char	**argv
-)
+	BackendDB	*be,
+	const char	*fname,
+	int		lineno,
+	int		argc,
+	char		**argv )
 {
 	slap_overinst	*on = (slap_overinst *)be->bd_info;
 	dynlist_info	*dli = (dynlist_info *)on->on_bi.bi_private;
@@ -668,8 +677,7 @@ dynlist_db_config(
 
 static int
 dynlist_db_init(
-	BackendDB *be
-)
+	BackendDB	*be )
 {
 	slap_overinst	*on = (slap_overinst *) be->bd_info;
 	dynlist_info	*dli;
@@ -684,8 +692,7 @@ dynlist_db_init(
 
 static int
 dynlist_db_open(
-	BackendDB *be
-)
+	BackendDB	*be )
 {
 	slap_overinst	*on = (slap_overinst *) be->bd_info;
 	dynlist_info	*dli = (dynlist_info *)on->on_bi.bi_private;
@@ -719,8 +726,7 @@ dynlist_db_open(
 
 static int
 dynlist_db_destroy(
-	BackendDB *be
-)
+	BackendDB	*be )
 {
 	slap_overinst	*on = (slap_overinst *) be->bd_info;
 	int		rc = 0;
@@ -739,8 +745,11 @@ dynlist_db_destroy(
 
 static slap_overinst dynlist = { { NULL } };
 
+#if SLAPD_OVER_DYNLIST == SLAPD_MOD_DYNAMIC
+static
+#endif /* SLAPD_OVER_DYNLIST == SLAPD_MOD_DYNAMIC */
 int
-dynlist_init(void)
+dynlist_initialize(void)
 {
 	dynlist.on_bi.bi_type = "dynlist";
 	dynlist.on_bi.bi_db_init = dynlist_db_init;
@@ -757,7 +766,7 @@ dynlist_init(void)
 int
 init_module( int argc, char *argv[] )
 {
-	return dynlist_init();
+	return dynlist_initialize();
 }
 #endif
 
diff --git a/servers/slapd/overlays/lastmod.c b/servers/slapd/overlays/lastmod.c
index 63a30e6301fece21a0e0276849db76fd3b6e579e..2e6170fb0f6d90b6596cd5ca205b7dd822f8dacb 100644
--- a/servers/slapd/overlays/lastmod.c
+++ b/servers/slapd/overlays/lastmod.c
@@ -995,7 +995,7 @@ lastmod_db_destroy(
 static slap_overinst 		lastmod;
 
 int
-lastmod_init()
+lastmod_initialize()
 {
 	lastmod.on_bi.bi_type = "lastmod";
 	lastmod.on_bi.bi_db_init = lastmod_db_init;
@@ -1020,7 +1020,7 @@ lastmod_init()
 int
 init_module( int argc, char *argv[] )
 {
-	return lastmod_init();
+	return lastmod_initialize();
 }
 #endif /* SLAPD_OVER_LASTMOD == SLAPD_MOD_DYNAMIC */
 
diff --git a/servers/slapd/overlays/overlays.c b/servers/slapd/overlays/overlays.c
index 0f46ae2cf2841b44c02a02ea610cfba2aa01f02d..edf4fb3ea690775edb49cd848aa6d98ea87dec48 100644
--- a/servers/slapd/overlays/overlays.c
+++ b/servers/slapd/overlays/overlays.c
@@ -23,116 +23,22 @@
 
 #include "slap.h"
 
-#if SLAPD_OVER_ACCESSLOG == SLAPD_MOD_STATIC
-extern int accesslog_init();
-#endif
-#if SLAPD_OVER_DENYOP == SLAPD_MOD_STATIC
-extern int denyop_init();
-#endif
-#if SLAPD_OVER_DYNGROUP == SLAPD_MOD_STATIC
-extern int dyngroup_init();
-#endif
-#if SLAPD_OVER_DYNLIST == SLAPD_MOD_STATIC
-extern int dynlist_init();
-#endif
-#if SLAPD_OVER_GLUE == SLAPD_MOD_STATIC
-extern int glue_init();
-#endif
-#if SLAPD_OVER_LASTMOD == SLAPD_MOD_STATIC
-extern int lastmod_init();
-#endif
-#if SLAPD_OVER_PPOLICY == SLAPD_MOD_STATIC
-extern int ppolicy_init();
-#endif
-#if SLAPD_OVER_PROXYCACHE == SLAPD_MOD_STATIC
-extern int pcache_init();
-#endif
-#if SLAPD_OVER_REFINT == SLAPD_MOD_STATIC
-extern int refint_init();
-#endif
-#if SLAPD_OVER_RETCODE == SLAPD_MOD_STATIC
-extern int retcode_init();
-#endif
-#if SLAPD_OVER_RWM == SLAPD_MOD_STATIC
-extern int rwm_init();
-#endif
-#if SLAPD_OVER_SYNCPROV == SLAPD_MOD_STATIC
-extern int syncprov_init();
-#endif
-#if SLAPD_OVER_TRANSLUCENT == SLAPD_MOD_STATIC
-extern int translucent_init();
-#endif
-#if SLAPD_OVER_UNIQUE == SLAPD_MOD_STATIC
-extern int unique_init();
-#endif
-#if SLAPD_OVER_VALSORT == SLAPD_MOD_STATIC
-extern int valsort_init();
-#endif
-
-static struct {
-	char *name;
-	int (*func)();
-} funcs[] = {
-#if SLAPD_OVER_ACCESSLOG == SLAPD_MOD_STATIC
-	{ "Access Log", accesslog_init },
-#endif
-#if SLAPD_OVER_DENYOP == SLAPD_MOD_STATIC
-	{ "Deny Operation", denyop_init },
-#endif
-#if SLAPD_OVER_DYNGROUP == SLAPD_MOD_STATIC
-	{ "Dynamic Group", dyngroup_init },
-#endif
-#if SLAPD_OVER_DYNLIST == SLAPD_MOD_STATIC
-	{ "Dynamic List", dynlist_init },
-#endif
-#if SLAPD_OVER_GLUE == SLAPD_MOD_STATIC
-	{ "Backend Glue", glue_init },
-#endif
-#if SLAPD_OVER_LASTMOD == SLAPD_MOD_STATIC
-	{ "Last Modification", lastmod_init },
-#endif
-#if SLAPD_OVER_PPOLICY == SLAPD_MOD_STATIC
-	{ "Password Policy", ppolicy_init },
-#endif
-#if SLAPD_OVER_PROXYCACHE == SLAPD_MOD_STATIC
-	{ "Proxy Cache", pcache_init },
-#endif
-#if SLAPD_OVER_REFINT == SLAPD_MOD_STATIC
-	{ "Referential Integrity", refint_init },
-#endif
-#if SLAPD_OVER_RETCODE == SLAPD_MOD_STATIC
-	{ "Return Code", retcode_init },
-#endif
-#if SLAPD_OVER_RWM == SLAPD_MOD_STATIC
-	{ "Rewrite/Remap", rwm_init },
-#endif
-#if SLAPD_OVER_SYNCPROV == SLAPD_MOD_STATIC
-	{ "Syncrepl Provider", syncprov_init },
-#endif
-#if SLAPD_OVER_TRANSLUCENT == SLAPD_MOD_STATIC
-	{ "Translucent Proxy", translucent_init },
-#endif
-#if SLAPD_OVER_UNIQUE == SLAPD_MOD_STATIC
-	{ "Attribute Uniqueness", unique_init },
-#endif
-#if SLAPD_OVER_VALSORT == SLAPD_MOD_STATIC
-	{ "Value Sorting", valsort_init },
-#endif
-	{ NULL, NULL }
-};
+extern OverlayInit	slap_oinfo[];
 
 int
 overlay_init(void)
 {
 	int i, rc = 0;
 
-	for ( i=0; funcs[i].name; i++ ) {
-		rc = funcs[i].func();
+	for ( i= 0 ; slap_oinfo[i].ov_type; i++ ) {
+		rc = slap_oinfo[i].ov_init();
 		if ( rc ) {
 			Debug( LDAP_DEBUG_ANY,
-		"%s overlay setup failed, err %d\n", funcs[i].name, rc, 0 );
+				"%s overlay setup failed, err %d\n",
+				slap_oinfo[i].ov_type, rc, 0 );
 			break;
 		}
 	}
+
 	return rc;
 }
diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c
index b34ab149ad97213a2a029a498dc1e5e592530452..61e80fe0229633d12bfe1a3fc0615e85ae0ba32a 100644
--- a/servers/slapd/overlays/pcache.c
+++ b/servers/slapd/overlays/pcache.c
@@ -68,7 +68,7 @@ typedef struct query_template_s {
 	CachedQuery* 	query_last;     /* oldest query cached for the template */
 
 	int 		no_of_queries;  /* Total number of queries in the template */
-	long 		ttl;		/* TTL for the queries of this template */
+	time_t		ttl;		/* TTL for the queries of this template */
         ldap_pvt_thread_rdwr_t t_rwlock; /* Rd/wr lock for accessing queries in the template */
 } QueryTemplate;
 
@@ -78,6 +78,9 @@ typedef struct query_template_s {
  */
 
 struct attr_set {
+	unsigned	flags;
+#define	PC_CONFIGURED	(0x1)
+#define	PC_REFERENCED	(0x2)
 	AttributeName*	attrs; 		/* specifies the set */
 	int 		count;		/* number of attributes */
 	int*		ID_array;	/* array of indices of supersets of 'attrs' */
@@ -124,7 +127,7 @@ typedef struct cache_manager_s {
 #define PCACHE_RESPONSE_CB_HEAD	0
 #define PCACHE_RESPONSE_CB_TAIL	1
 
-	int     cc_period;		/* interval between successive consistency checks (sec) */
+	time_t	cc_period;		/* interval between successive consistency checks (sec) */
 	int	cc_paused;
 	void	*cc_arg;
 
@@ -730,6 +733,7 @@ static void cache_replacement(query_manager* qm, struct berval *result)
 		Debug ( LDAP_DEBUG_ANY,
 			"Cache replacement invoked without "
 			"any query in LRU list\n", 0, 0, 0 );
+		ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);
 		return;
 	}
 
@@ -1082,7 +1086,7 @@ cache_entries(
 }
 
 static int
-proxy_cache_response(
+pcache_response(
 	Operation	*op,
 	SlapReply	*rs )
 {
@@ -1117,13 +1121,16 @@ proxy_cache_response(
 			}
 		}
 
-		if (rs->sr_attrs != op->ors_attrs ) {
+		if ( rs->sr_attrs != op->ors_attrs ) {
 			op->o_tmpfree( rs->sr_attrs, op->o_tmpmemctx );
 		}
-		rs->sr_attrs = si->query.save_attrs;
-		op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
-		op->ors_attrs = si->query.save_attrs;
-		si->query.save_attrs = NULL;
+
+		if ( si->query.save_attrs != NULL ) {
+			rs->sr_attrs = si->query.save_attrs;
+			op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
+			op->ors_attrs = si->query.save_attrs;
+			si->query.save_attrs = NULL;
+		}
 
 	} else if ( rs->sr_type == REP_RESULT ) {
 		if ( si->count && cache_entries( op, rs, &uuid ) == 0 ) {
@@ -1211,7 +1218,7 @@ add_filter_attrs(
  * performing the pagedResults search only within the client
  * and the proxy.  This requires pcache to understand pagedResults. */
 static int
-proxy_cache_chk_controls(
+pcache_chk_controls(
 	Operation	*op,
 	SlapReply	*rs )
 {
@@ -1242,7 +1249,7 @@ proxy_cache_chk_controls(
 }
 
 static int
-proxy_cache_search(
+pcache_op_search(
 	Operation	*op,
 	SlapReply	*rs )
 {
@@ -1370,7 +1377,7 @@ proxy_cache_search(
 		add_filter_attrs(op, &op->ors_attrs, query.attrs, filter_attrs);
 
 		cb = op->o_tmpalloc( sizeof(*cb) + sizeof(*si), op->o_tmpmemctx);
-		cb->sc_response = proxy_cache_response;
+		cb->sc_response = pcache_response;
 		cb->sc_cleanup = NULL;
 		cb->sc_private = (cb+1);
 		si = cb->sc_private;
@@ -1710,21 +1717,22 @@ pc_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca )
 static int
 pc_cf_gen( ConfigArgs *c )
 {
-	slap_overinst *on = (slap_overinst *)c->bi;
+	slap_overinst	*on = (slap_overinst *)c->bi;
 	cache_manager* 	cm = on->on_bi.bi_private;
 	query_manager*  qm = cm->qm;
 	QueryTemplate* 	temp;
 	AttributeName*  attr_name;
 	AttributeName* 	attrarray;
 	const char* 	text=NULL;
-	int i, num, rc = 0;
-	char *ptr;
+	int		i, num, rc = 0;
+	char		*ptr;
+	unsigned long	t;
 
 	if ( c->op == SLAP_CONFIG_EMIT ) {
 		struct berval bv;
 		switch( c->type ) {
 		case PC_MAIN:
-			bv.bv_len = sprintf( c->msg, "%s %d %d %d %d",
+			bv.bv_len = snprintf( c->msg, sizeof( c->msg ), "%s %d %d %d %ld",
 				cm->db.bd_info->bi_type, cm->max_entries, cm->numattrsets,
 				cm->num_entries_limit, cm->cc_period );
 			bv.bv_val = c->msg;
@@ -1734,7 +1742,7 @@ pc_cf_gen( ConfigArgs *c )
 			for (i=0; i<cm->numattrsets; i++) {
 				if ( !qm->attr_sets[i].count ) continue;
 
-				bv.bv_len = sprintf( c->msg, "%d", i );
+				bv.bv_len = snprintf( c->msg, sizeof( c->msg ), "%d", i );
 
 				/* count the attr length */
 				for ( attr_name = qm->attr_sets[i].attrs;
@@ -1755,7 +1763,7 @@ pc_cf_gen( ConfigArgs *c )
 			break;
 		case PC_TEMP:
 			for (i=0; i<cm->numtemplates; i++) {
-				bv.bv_len = sprintf( c->msg, " %d %ld",
+				bv.bv_len = snprintf( c->msg, sizeof( c->msg ), " %d %ld",
 					qm->templates[i].attr_set_index,
 					qm->templates[i].ttl );
 				bv.bv_len += qm->templates[i].querystr.bv_len + 2;
@@ -1793,38 +1801,98 @@ pc_cf_gen( ConfigArgs *c )
 
 	switch( c->type ) {
 	case PC_MAIN:
-		cm->numattrsets = atoi( c->argv[3] );
+		if ( cm->numattrsets > 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "\"proxycache\" directive already provided" );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+
+		if ( lutil_atoi( &cm->numattrsets, c->argv[3] ) != 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "unable to parse num attrsets=\"%s\" (arg #3)",
+				c->argv[3] );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+		if ( cm->numattrsets <= 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "numattrsets (arg #3) must be positive" );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
 		if ( cm->numattrsets > MAX_ATTR_SETS ) {
-			sprintf( c->msg, "numattrsets must be <= %d", MAX_ATTR_SETS );
-			Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
+			snprintf( c->msg, sizeof( c->msg ), "numattrsets (arg #3) must be <= %d", MAX_ATTR_SETS );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 			return( 1 );
 		}
+
 		if ( !backend_db_init( c->argv[1], &cm->db )) {
-			sprintf( c->msg, "unknown backend type" );
+			snprintf( c->msg, sizeof( c->msg ), "unknown backend type (arg #1)" );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+
+		if ( lutil_atoi( &cm->max_entries, c->argv[2] ) != 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "unable to parse max entries=\"%s\" (arg #2)",
+				c->argv[2] );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+		if ( cm->max_entries <= 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "max entries (arg #2) must be positive.\n" );
 			Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
 			return( 1 );
 		}
-		cm->max_entries = atoi( c->argv[2] );
 
-		cm->num_entries_limit = atoi( c->argv[4] );
-		cm->cc_period = atoi( c->argv[5] );
+		if ( lutil_atoi( &cm->num_entries_limit, c->argv[4] ) != 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "unable to parse entry limit=\"%s\" (arg #4)",
+				c->argv[4] );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+		if ( cm->num_entries_limit <= 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "entry limit (arg #4) must be positive" );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+		if ( cm->num_entries_limit > cm->max_entries ) {
+			snprintf( c->msg, sizeof( c->msg ), "entry limit (arg #4) must be less than max entries %d (arg #2)", cm->max_entries );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+
+		if ( lutil_parse_time( c->argv[5], &t ) != 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "unable to parse period=\"%s\" (arg #5)",
+				c->argv[5] );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+		cm->cc_period = (time_t)t;
 		Debug( LDAP_DEBUG_TRACE,
-				"Total # of attribute sets to be cached = %d\n",
+				"Total # of attribute sets to be cached = %d.\n",
 				cm->numattrsets, 0, 0 );
-		qm->attr_sets = ( struct attr_set * )ch_malloc( cm->numattrsets *
-			    			sizeof( struct attr_set ));
-		for ( i = 0; i < cm->numattrsets; i++ ) {
-			qm->attr_sets[i].attrs = NULL;
-		}
+		qm->attr_sets = ( struct attr_set * )ch_calloc( cm->numattrsets,
+			    			sizeof( struct attr_set ) );
 		break;
 	case PC_ATTR:
-		num = atoi( c->argv[1] );
-		if (num >= cm->numattrsets) {
-			sprintf( c->msg, "attrset index out of bounds" );
-			Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
+		if ( cm->numattrsets == 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "\"proxycache\" directive not provided yet" );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+		if ( lutil_atoi( &num, c->argv[1] ) != 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "unable to parse attrset #=\"%s\"",
+				c->argv[1] );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+
+		if ( num < 0 || num >= cm->numattrsets ) {
+			snprintf( c->msg, sizeof( c->msg ), "attrset index %d out of bounds (must be %s%d)",
+				num, cm->numattrsets > 1 ? "0->" : "", cm->numattrsets - 1 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 			return 1;
 		}
-		if ( c->argv[2] && strcmp( c->argv[2], "*" ) ) {
+		qm->attr_sets[num].flags |= PC_CONFIGURED;
+		if ( c->argc > 2 && strcmp( c->argv[2], "*" ) ) {
 			qm->attr_sets[num].count = c->argc - 2;
 			qm->attr_sets[num].attrs = (AttributeName*)ch_malloc(
 						(c->argc-1) * sizeof( AttributeName ));
@@ -1833,9 +1901,10 @@ pc_cf_gen( ConfigArgs *c )
 				ber_str2bv( c->argv[i], 0, 1, &attr_name->an_name);
 				attr_name->an_desc = NULL;
 				if ( slap_bv2ad( &attr_name->an_name,
-						&attr_name->an_desc, &text )) {
+						&attr_name->an_desc, &text ) )
+				{
 					strcpy( c->msg, text );
-					Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
+					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 					ch_free( qm->attr_sets[num].attrs );
 					qm->attr_sets[num].attrs = NULL;
 					qm->attr_sets[num].count = 0;
@@ -1849,9 +1918,22 @@ pc_cf_gen( ConfigArgs *c )
 		}
 		break;
 	case PC_TEMP:
-		if (( i = atoi( c->argv[2] )) >= cm->numattrsets ) {
-			sprintf( c->msg, "template index invalid" );
-			Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
+		if ( cm->numattrsets == 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "\"proxycache\" directive not provided yet" );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+		if ( lutil_atoi( &i, c->argv[2] ) != 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "unable to parse template #=\"%s\"",
+				c->argv[2] );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+
+		if ( i < 0 || i >= cm->numattrsets ) {
+			snprintf( c->msg, sizeof( c->msg ), "template index %d invalid (%s%d)",
+				i, cm->numattrsets > 1 ? "0->" : "", cm->numattrsets - 1 );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 			return 1;
 		}
 		num = cm->numtemplates;
@@ -1862,7 +1944,14 @@ pc_cf_gen( ConfigArgs *c )
 		temp = qm->templates + num;
 		ldap_pvt_thread_rdwr_init( &temp->t_rwlock );
 		temp->query = temp->query_last = NULL;
-		temp->ttl = atoi( c->argv[3] );
+		if ( lutil_parse_time( c->argv[3], &t ) != 0 ) {
+			snprintf( c->msg, sizeof( c->msg ), "unable to parse template ttl=\"%s\"",
+				c->argv[3] );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+			return( 1 );
+		}
+		temp->ttl = (time_t)t;
+
 		temp->no_of_queries = 0;
 
 		ber_str2bv( c->argv[1], 0, 1, &temp->querystr );
@@ -1870,6 +1959,7 @@ pc_cf_gen( ConfigArgs *c )
 		Debug( LDAP_DEBUG_TRACE, "  query template: %s\n",
 				temp->querystr.bv_val, 0, 0 );
 		temp->attr_set_index = i;
+		qm->attr_sets[i].flags |= PC_REFERENCED;
 		Debug( LDAP_DEBUG_TRACE, "  attributes: \n", 0, 0, 0 );
 		if ( ( attrarray = qm->attr_sets[i].attrs ) != NULL ) {
 			for ( i=0; attrarray[i].an_name.bv_val; i++ )
@@ -1888,8 +1978,8 @@ pc_cf_gen( ConfigArgs *c )
 			cm->response_cb = PCACHE_RESPONSE_CB_TAIL;
 
 		} else {
-			sprintf( c->msg, "unknown specifier" );
-			Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
+			snprintf( c->msg, sizeof( c->msg ), "unknown specifier" );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 			return 1;
 		}
 		break;
@@ -1898,7 +1988,7 @@ pc_cf_gen( ConfigArgs *c )
 }
 
 static int
-proxy_cache_config(
+pcache_db_config(
 	BackendDB	*be,
 	const char	*fname,
 	int		lineno,
@@ -1917,7 +2007,7 @@ proxy_cache_config(
 }
 
 static int
-proxy_cache_init(
+pcache_db_init(
 	BackendDB *be
 )
 {
@@ -1962,13 +2052,42 @@ proxy_cache_init(
 }
 
 static int
-proxy_cache_open(
+pcache_db_open(
 	BackendDB *be
 )
 {
 	slap_overinst	*on = (slap_overinst *)be->bd_info;
 	cache_manager	*cm = on->on_bi.bi_private;
-	int		rc = 0;
+	query_manager*  qm = cm->qm;
+	int		i, ncf = 0, rf = 0, nrf = 0, rc = 0;
+
+	/* check attr sets */
+	for ( i = 0; i < cm->numattrsets; i++) {
+		if ( !( qm->attr_sets[i].flags & PC_CONFIGURED ) ) {
+			if ( qm->attr_sets[i].flags & PC_REFERENCED ) {
+				Debug( LDAP_DEBUG_ANY, "pcache: attr set #%d not configured but referenced.\n", i, 0, 0 );
+				rf++;
+
+			} else {
+				Debug( LDAP_DEBUG_ANY, "pcache: warning, attr set #%d not configured.\n", i, 0, 0 );
+			}
+			ncf++;
+
+		} else if ( !( qm->attr_sets[i].flags & PC_REFERENCED ) ) {
+			Debug( LDAP_DEBUG_ANY, "pcache: attr set #%d configured but not referenced.\n", i, 0, 0 );
+			nrf++;
+		}
+	}
+
+	if ( ncf || rf || nrf ) {
+		Debug( LDAP_DEBUG_ANY, "pcache: warning, %d attr sets configured but not referenced.\n", nrf, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "pcache: warning, %d attr sets not configured.\n", ncf, 0, 0 );
+		Debug( LDAP_DEBUG_ANY, "pcache: %d attr sets not configured but referenced.\n", rf, 0, 0 );
+
+		if ( rf > 0 ) {
+			return 1;
+		}
+	}
 
 	/* need to inherit something from the original database... */
 	cm->db.be_def_limit = be->be_def_limit;
@@ -1990,7 +2109,7 @@ proxy_cache_open(
 		if ( BER_BVISNULL( &cm->db.be_rootndn )
 				|| BER_BVISEMPTY( &cm->db.be_rootndn ) )
 		{
-			Debug( LDAP_DEBUG_ANY, "proxy_cache_open(): "
+			Debug( LDAP_DEBUG_ANY, "pcache_db_open(): "
 				"underlying database of type \"%s\"\n"
 				"    serving naming context \"%s\"\n"
 				"    has no \"rootdn\", required by \"proxycache\".\n",
@@ -2004,7 +2123,7 @@ proxy_cache_open(
 }
 
 static int
-proxy_cache_close(
+pcache_db_close(
 	BackendDB *be
 )
 {
@@ -2046,7 +2165,7 @@ proxy_cache_close(
 }
 
 static int
-proxy_cache_destroy(
+pcache_db_destroy(
 	BackendDB *be
 )
 {
@@ -2062,7 +2181,9 @@ proxy_cache_destroy(
 	BER_BVZERO( &cm->db.be_rootpw );
 	/* FIXME: there might be more... */
 
-	backend_destroy_one( &cm->db, 0 );
+	if ( cm->db.be_private != NULL ) {
+		backend_destroy_one( &cm->db, 0 );
+	}
 
 	ldap_pvt_thread_mutex_destroy( &qm->lru_mutex );
 	ldap_pvt_thread_mutex_destroy( &cm->cache_mutex );
@@ -2073,9 +2194,9 @@ proxy_cache_destroy(
 	return 0;
 }
 
-static slap_overinst proxy_cache;
+static slap_overinst pcache;
 
-int pcache_init()
+int pcache_initialize()
 {
 	LDAPAttributeType *at;
 	int code;
@@ -2085,7 +2206,7 @@ int pcache_init()
 		LDAP_SCHEMA_ALLOW_ALL );
 	if ( !at ) {
 		Debug( LDAP_DEBUG_ANY,
-			"pcache_init: ldap_str2attributetype failed %s %s\n",
+			"pcache_initialize: ldap_str2attributetype failed %s %s\n",
 			ldap_scherr2str(code), err, 0 );
 		return code;
 	}
@@ -2096,32 +2217,33 @@ int pcache_init()
 	ldap_memfree( at );
 	if ( code ) {
 		Debug( LDAP_DEBUG_ANY,
-			"pcache_init: at_add failed %s %s\n",
+			"pcache_initialize: at_add failed %s %s\n",
 			scherr2str(code), err, 0 );
 		return code;
 	}
 
-	proxy_cache.on_bi.bi_type = "pcache";
-	proxy_cache.on_bi.bi_db_init = proxy_cache_init;
-	proxy_cache.on_bi.bi_db_config = proxy_cache_config;
-	proxy_cache.on_bi.bi_db_open = proxy_cache_open;
-	proxy_cache.on_bi.bi_db_close = proxy_cache_close;
-	proxy_cache.on_bi.bi_db_destroy = proxy_cache_destroy;
-	proxy_cache.on_bi.bi_op_search = proxy_cache_search;
+	pcache.on_bi.bi_type = "pcache";
+	pcache.on_bi.bi_db_init = pcache_db_init;
+	pcache.on_bi.bi_db_config = pcache_db_config;
+	pcache.on_bi.bi_db_open = pcache_db_open;
+	pcache.on_bi.bi_db_close = pcache_db_close;
+	pcache.on_bi.bi_db_destroy = pcache_db_destroy;
+
+	pcache.on_bi.bi_op_search = pcache_op_search;
 
-	proxy_cache.on_bi.bi_chk_controls = proxy_cache_chk_controls;
+	pcache.on_bi.bi_chk_controls = pcache_chk_controls;
 
-	proxy_cache.on_bi.bi_cf_ocs = pcocs;
+	pcache.on_bi.bi_cf_ocs = pcocs;
 
 	code = config_register_schema( pccfg, pcocs );
 	if ( code ) return code;
 
-	return overlay_register( &proxy_cache );
+	return overlay_register( &pcache );
 }
 
 #if SLAPD_OVER_PROXYCACHE == SLAPD_MOD_DYNAMIC
 int init_module(int argc, char *argv[]) {
-	return pcache_init();
+	return pcache_initialize();
 }
 #endif
 
diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c
index 2a5568add9ed8b9372b3cf2b66725c2d329e894d..88633d167c55687909242472e820e820ea298d13 100644
--- a/servers/slapd/overlays/ppolicy.c
+++ b/servers/slapd/overlays/ppolicy.c
@@ -357,30 +357,40 @@ ppolicy_get( Operation *op, Entry *e, PassPolicy *pp )
 	pp->ad = slap_schema.si_ad_userPassword;
 #endif
 
-	if ((a = attr_find( pe->e_attrs, ad_pwdMinAge )))
-		pp->pwdMinAge = atoi(a->a_vals[0].bv_val );
-	if ((a = attr_find( pe->e_attrs, ad_pwdMaxAge )))
-		pp->pwdMaxAge = atoi(a->a_vals[0].bv_val );
-	if ((a = attr_find( pe->e_attrs, ad_pwdInHistory )))
-		pp->pwdInHistory = atoi(a->a_vals[0].bv_val );
-	if ((a = attr_find( pe->e_attrs, ad_pwdCheckQuality )))
-		pp->pwdCheckQuality = atoi(a->a_vals[0].bv_val );
-	if ((a = attr_find( pe->e_attrs, ad_pwdMinLength )))
-		pp->pwdMinLength = atoi(a->a_vals[0].bv_val );
-	if ((a = attr_find( pe->e_attrs, ad_pwdMaxFailure )))
-		pp->pwdMaxFailure = atoi(a->a_vals[0].bv_val );
-	if ((a = attr_find( pe->e_attrs, ad_pwdGraceAuthNLimit )))
-		pp->pwdGraceAuthNLimit = atoi(a->a_vals[0].bv_val );
-	if ((a = attr_find( pe->e_attrs, ad_pwdExpireWarning )))
-		pp->pwdExpireWarning = atoi(a->a_vals[0].bv_val );
-	if ((a = attr_find( pe->e_attrs, ad_pwdFailureCountInterval )))
-		pp->pwdFailureCountInterval = atoi(a->a_vals[0].bv_val );
-	if ((a = attr_find( pe->e_attrs, ad_pwdLockoutDuration )))
-		pp->pwdLockoutDuration = atoi(a->a_vals[0].bv_val );
-
-	if ((a = attr_find( pe->e_attrs, ad_pwdCheckModule ))) {
-		strncpy(pp->pwdCheckModule, a->a_vals[0].bv_val,
-			sizeof(pp->pwdCheckModule));
+	if ( ( a = attr_find( pe->e_attrs, ad_pwdMinAge ) )
+			&& lutil_atoi( &pp->pwdMinAge, a->a_vals[0].bv_val ) != 0 )
+		goto defaultpol;
+	if ( ( a = attr_find( pe->e_attrs, ad_pwdMaxAge ) )
+			&& lutil_atoi( &pp->pwdMaxAge, a->a_vals[0].bv_val ) != 0 )
+		goto defaultpol;
+	if ( ( a = attr_find( pe->e_attrs, ad_pwdInHistory ) )
+			&& lutil_atoi( &pp->pwdInHistory, a->a_vals[0].bv_val ) != 0 )
+		goto defaultpol;
+	if ( ( a = attr_find( pe->e_attrs, ad_pwdCheckQuality ) )
+			&& lutil_atoi( &pp->pwdCheckQuality, a->a_vals[0].bv_val ) != 0 )
+		goto defaultpol;
+	if ( ( a = attr_find( pe->e_attrs, ad_pwdMinLength ) )
+			&& lutil_atoi( &pp->pwdMinLength, a->a_vals[0].bv_val ) != 0 )
+		goto defaultpol;
+	if ( ( a = attr_find( pe->e_attrs, ad_pwdMaxFailure ) )
+			&& lutil_atoi( &pp->pwdMaxFailure, a->a_vals[0].bv_val ) != 0 )
+		goto defaultpol;
+	if ( ( a = attr_find( pe->e_attrs, ad_pwdGraceAuthNLimit ) )
+			&& lutil_atoi( &pp->pwdGraceAuthNLimit, a->a_vals[0].bv_val ) != 0 )
+		goto defaultpol;
+	if ( ( a = attr_find( pe->e_attrs, ad_pwdExpireWarning ) )
+			&& lutil_atoi( &pp->pwdExpireWarning, a->a_vals[0].bv_val ) != 0 )
+		goto defaultpol;
+	if ( ( a = attr_find( pe->e_attrs, ad_pwdFailureCountInterval ) )
+			&& lutil_atoi( &pp->pwdFailureCountInterval, a->a_vals[0].bv_val ) != 0 )
+		goto defaultpol;
+	if ( ( a = attr_find( pe->e_attrs, ad_pwdLockoutDuration ) )
+			&& lutil_atoi( &pp->pwdLockoutDuration, a->a_vals[0].bv_val ) != 0 )
+		goto defaultpol;
+
+	if ( ( a = attr_find( pe->e_attrs, ad_pwdCheckModule ) ) ) {
+		strncpy( pp->pwdCheckModule, a->a_vals[0].bv_val,
+			sizeof(pp->pwdCheckModule) );
 		pp->pwdCheckModule[sizeof(pp->pwdCheckModule)-1] = '\0';
 	}
 
@@ -1932,7 +1942,7 @@ static char *extops[] = {
 
 static slap_overinst ppolicy;
 
-int ppolicy_init()
+int ppolicy_initialize()
 {
 	LDAPAttributeType *at;
 	const char *err;
@@ -1992,7 +2002,7 @@ int ppolicy_init()
 
 #if SLAPD_OVER_PPOLICY == SLAPD_MOD_DYNAMIC
 int init_module(int argc, char *argv[]) {
-	return ppolicy_init();
+	return ppolicy_initialize();
 }
 #endif
 
diff --git a/servers/slapd/overlays/refint.c b/servers/slapd/overlays/refint.c
index 9004f902f971aff10053b3fb89a9c42d33535a12..5333da6062dd99fc596263eaf057d86319a6d756 100644
--- a/servers/slapd/overlays/refint.c
+++ b/servers/slapd/overlays/refint.c
@@ -659,7 +659,7 @@ done:
 ** it expects to be called automagically during dynamic module initialization
 */
 
-int refint_init() {
+int refint_initialize() {
 
 	/* statically declared just after the #includes at top */
 	refint.on_bi.bi_type = "refint";
@@ -674,7 +674,7 @@ int refint_init() {
 
 #if SLAPD_OVER_REFINT == SLAPD_MOD_DYNAMIC && defined(PIC)
 int init_module(int argc, char *argv[]) {
-	return refint_init();
+	return refint_initialize();
 }
 #endif
 
diff --git a/servers/slapd/overlays/retcode.c b/servers/slapd/overlays/retcode.c
index 845370a8123df3ab4ad5bd3112d26f907bb3c551..79db976854cb297567b178ee415e86a93c578f58 100644
--- a/servers/slapd/overlays/retcode.c
+++ b/servers/slapd/overlays/retcode.c
@@ -114,8 +114,6 @@ retcode_send_onelevel( Operation *op, SlapReply *rs )
 	retcode_item_t	*rdi;
 	
 	for ( rdi = rd->rd_item; rdi != NULL; rdi = rdi->rdi_next ) {
-		int	rc;
-
 		if ( op->o_abandon ) {
 			return rs->sr_err = SLAPD_ABANDON;
 		}
@@ -135,16 +133,14 @@ retcode_send_onelevel( Operation *op, SlapReply *rs )
 			rs->sr_err = LDAP_SUCCESS;
 			rs->sr_entry = &rdi->rdi_e;
 
-			rc = send_search_entry( op, rs );
+			rs->sr_err = send_search_entry( op, rs );
+			rs->sr_entry = NULL;
 
-			switch ( rc ) {
-			case 0:		/* entry sent ok */
-				break;
-			case 1:		/* entry not sent */
-				break;
-			case -1:	/* connection closed */
-				rs->sr_entry = NULL;
+			switch ( rs->sr_err ) {
+			case LDAP_UNAVAILABLE:	/* connection closed */
 				rs->sr_err = LDAP_OTHER;
+				/* fallthru */
+			case LDAP_SIZELIMIT_EXCEEDED:
 				goto done;
 			}
 		}
@@ -1062,7 +1058,7 @@ retcode_db_destroy( BackendDB *be )
 static
 #endif /* SLAPD_OVER_RETCODE == SLAPD_MOD_DYNAMIC */
 int
-retcode_init( void )
+retcode_initialize( void )
 {
 	int		i, code;
 	const char	*err;
@@ -1239,7 +1235,7 @@ retcode_init( void )
 int
 init_module( int argc, char *argv[] )
 {
-	return retcode_init();
+	return retcode_initialize();
 }
 #endif /* SLAPD_OVER_RETCODE == SLAPD_MOD_DYNAMIC */
 
diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c
index 42bf3f8c1e2dc99d219edc1c67ddbcfd37d961af..d4c5f1b9ed4c07c9a7690d75e9378f2ab9f2cb80 100644
--- a/servers/slapd/overlays/rwm.c
+++ b/servers/slapd/overlays/rwm.c
@@ -1504,7 +1504,7 @@ rwm_db_destroy(
 static slap_overinst rwm = { { NULL } };
 
 int
-rwm_init(void)
+rwm_initialize(void)
 {
 	memset( &rwm, 0, sizeof( slap_overinst ) );
 
@@ -1541,7 +1541,7 @@ rwm_init(void)
 int
 init_module( int argc, char *argv[] )
 {
-	return rwm_init();
+	return rwm_initialize();
 }
 #endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */
 
diff --git a/servers/slapd/overlays/seqmod.c b/servers/slapd/overlays/seqmod.c
index 18f5ded5d76b7ff3b6b4132139065b76fc60ae61..5018700d8eedb9c973e1ef406434012f87303d06 100644
--- a/servers/slapd/overlays/seqmod.c
+++ b/servers/slapd/overlays/seqmod.c
@@ -178,7 +178,7 @@ seqmod_db_close(
 static slap_overinst 		seqmod;
 
 int
-seqmod_init()
+seqmod_initialize()
 {
 	seqmod.on_bi.bi_type = "seqmod";
 	seqmod.on_bi.bi_db_open = seqmod_db_open;
@@ -195,7 +195,7 @@ seqmod_init()
 int
 init_module( int argc, char *argv[] )
 {
-	return seqmod_init();
+	return seqmod_initialize();
 }
 #endif /* SLAPD_OVER_SEQMOD == SLAPD_MOD_DYNAMIC */
 
diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c
index 4e090b0fc98f93e51b0bd09d54deb97726698e87..a62d0a0d0d8829ca15a8d54f9adcb78d6aafc56a 100644
--- a/servers/slapd/overlays/syncprov.c
+++ b/servers/slapd/overlays/syncprov.c
@@ -450,12 +450,10 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
 		case LDAP_SCOPE_SUBTREE:
 			fc->fscope = dnIsSuffix( fc->fdn, &fc->fss->s_base );
 			break;
-#ifdef LDAP_SCOPE_SUBORDINATE
 		case LDAP_SCOPE_SUBORDINATE:
 			fc->fscope = dnIsSuffix( fc->fdn, &fc->fss->s_base ) &&
 				!dn_match( fc->fdn, &fc->fss->s_base );
 			break;
-#endif
 		}
 	}
 
@@ -510,7 +508,11 @@ findcsn_cb( Operation *op, SlapReply *rs )
 {
 	slap_callback *sc = op->o_callback;
 
-	if ( rs->sr_type == REP_SEARCH && rs->sr_err == LDAP_SUCCESS ) {
+	/* We just want to know that at least one exists, so it's OK if
+	 * we exceed the unchecked limit.
+	 */
+	if ( rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ||
+		(rs->sr_type == REP_SEARCH && rs->sr_err == LDAP_SUCCESS )) {
 		sc->sc_private = (void *)1;
 	}
 	return LDAP_SUCCESS;
@@ -583,10 +585,10 @@ syncprov_findcsn( Operation *op, find_csn_t mode )
 #else
 	AttributeAssertion eq = { NULL, BER_BVNULL };
 #endif
-	int i, rc = LDAP_SUCCESS;
 	fpres_cookie pcookie;
 	sync_control *srs = NULL;
-	int findcsn_retry = 1;
+	struct slap_limits_set fc_limits;
+	int i, rc = LDAP_SUCCESS, findcsn_retry = 1;
 
 	if ( mode != FIND_MAXCSN ) {
 		srs = op->o_controls[slap_cids.sc_LDAPsync];
@@ -637,6 +639,8 @@ again:
 		/* On retry, look for <= */
 		} else {
 			cf.f_choice = LDAP_FILTER_LE;
+			fop.ors_limit = &fc_limits;
+			fc_limits.lms_s_unchecked = 1;
 			fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN<=%s)",
 				cf.f_av_value.bv_val );
 		}
@@ -1244,7 +1248,9 @@ syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on )
 	opm.o_req_ndn = op->o_bd->be_nsuffix[0];
 	opm.o_bd->bd_info = on->on_info->oi_orig;
 	opm.o_managedsait = SLAP_CONTROL_NONCRITICAL;
+	SLAP_DBFLAGS( opm.o_bd ) |= SLAP_DBFLAG_NOLASTMOD;
 	opm.o_bd->be_modify( &opm, &rsm );
+	SLAP_DBFLAGS( opm.o_bd ) ^= SLAP_DBFLAG_NOLASTMOD;
 	if ( mod.sml_next != NULL ) {
 		slap_mods_free( mod.sml_next, 1 );
 	}
@@ -2187,8 +2193,31 @@ sp_cf_gen(ConfigArgs *c)
 	}
 	switch ( c->type ) {
 	case SP_CHKPT:
-		si->si_chkops = atoi( c->argv[1] );
-		si->si_chktime = atoi( c->argv[2] ) * 60;
+		if ( lutil_atoi( &si->si_chkops, c->argv[1] ) != 0 ) {
+			sprintf( c->msg, "%s unable to parse checkpoint ops # \"%s\"",
+				c->argv[0], c->argv[1] );
+			Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
+			return ARG_BAD_CONF;
+		}
+		if ( si->si_chkops <= 0 ) {
+			sprintf( c->msg, "%s invalid checkpoint ops # \"%d\"",
+				c->argv[0], si->si_chkops );
+			Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
+			return ARG_BAD_CONF;
+		}
+		if ( lutil_atoi( &si->si_chktime, c->argv[2] ) != 0 ) {
+			sprintf( c->msg, "%s unable to parse checkpoint time \"%s\"",
+				c->argv[0], c->argv[1] );
+			Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
+			return ARG_BAD_CONF;
+		}
+		if ( si->si_chktime <= 0 ) {
+			sprintf( c->msg, "%s invalid checkpoint time \"%d\"",
+				c->argv[0], si->si_chkops );
+			Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
+			return ARG_BAD_CONF;
+		}
+		si->si_chktime *= 60;
 		break;
 	case SP_SESSL: {
 		sessionlog *sl;
@@ -2508,7 +2537,7 @@ static int syncprov_parseCtrl (
 static slap_overinst 		syncprov;
 
 int
-syncprov_init()
+syncprov_initialize()
 {
 	int rc;
 
@@ -2553,7 +2582,7 @@ syncprov_init()
 int
 init_module( int argc, char *argv[] )
 {
-	return syncprov_init();
+	return syncprov_initialize();
 }
 #endif /* SLAPD_OVER_SYNCPROV == SLAPD_MOD_DYNAMIC */
 
diff --git a/servers/slapd/overlays/translucent.c b/servers/slapd/overlays/translucent.c
index 13e37ff9be714ff3a53e75b3f07bb5181f5640ad..8b1e8f369390af540295fe6c056f6e272d438c1d 100644
--- a/servers/slapd/overlays/translucent.c
+++ b/servers/slapd/overlays/translucent.c
@@ -29,6 +29,7 @@
 #include <ac/socket.h>
 
 #include "slap.h"
+#include "lutil.h"
 
 /* config block */
 
@@ -620,7 +621,11 @@ static int translucent_config(
 			ov->config->debug = 0xFFFF;
 			rc = 0;
 		} else if(argc == 2) {
-			ov->config->debug = atoi(argv[1]);
+			if ( lutil_atoi( &ov->config->debug, argv[1]) != 0 ) {
+				fprintf(stderr, "%s: line %d: unable to parse debug \"%s\"\n",
+					fname, lineno, argv[1]);
+				return 1;
+			}
 			rc = 0;
 		} else {
 			fprintf(stderr, "%s: line %d: too many arguments (%d) to debug\n",
@@ -730,7 +735,7 @@ static int translucent_close(BackendDB *be) {
 **
 */
 
-int translucent_init() {
+int translucent_initialize() {
 
 	translucent.on_bi.bi_type	= "translucent";
 	translucent.on_bi.bi_db_init	= translucent_db_init;
@@ -750,7 +755,7 @@ int translucent_init() {
 
 #if SLAPD_OVER_TRANSLUCENT == SLAPD_MOD_DYNAMIC && defined(PIC)
 int init_module(int argc, char *argv[]) {
-	return translucent_init();
+	return translucent_initialize();
 }
 #endif
 
diff --git a/servers/slapd/overlays/unique.c b/servers/slapd/overlays/unique.c
index d1df4dbb3ea234acc71bd6bafd7cf6b16cc9c827..5802b4a9d1e5aa96cf0cbb5d069835bef45d217b 100644
--- a/servers/slapd/overlays/unique.c
+++ b/servers/slapd/overlays/unique.c
@@ -263,21 +263,35 @@ static int count_filter_len(
 	unique_attrs *up;
 	int i;
 
-	while(!is_at_operational(ad->ad_type)) {
-		if(ud->ignore) {
-			for(up = ud->ignore; up; up = up->next)
-				if(ad == up->attr) break;
-			if(up) break;
+	while ( !is_at_operational( ad->ad_type ) ) {
+		if ( ud->ignore ) {
+			for ( up = ud->ignore; up; up = up->next ) {
+				if (ad == up->attr ) {
+					break;
+				}
+			}
+			if ( up ) {
+				break;
+			}
 		}
-		if(ud->attrs) {
-			for(up = ud->attrs; up; up = up->next)
-				if(ad == up->attr) break;
-			if(!up) break;
+		if ( ud->attrs ) {
+			for ( up = ud->attrs; up; up = up->next ) {
+				if ( ad == up->attr ) {
+					break;
+				}
+			}
+			if ( !up ) {
+				break;
+			}
 		}
-		if(b && b[0].bv_val) for(i = 0; b[i].bv_val; i++)
-			ks += b[i].bv_len + ad->ad_cname.bv_len + STRLENOF( "(=)" );
-		else if(ud->strict)
+		if ( b && b[0].bv_val ) {
+			for (i = 0; b[i].bv_val; i++ ) {
+				/* note: make room for filter escaping... */
+				ks += ( 3 * b[i].bv_len ) + ad->ad_cname.bv_len + STRLENOF( "(=)" );
+			}
+		} else if ( ud->strict ) {
 			ks += ad->ad_cname.bv_len + STRLENOF( "(=*)" );	/* (attr=*) */
+		}
 		break;
 	}
 	return ks;
@@ -287,27 +301,47 @@ static char *build_filter(
 	unique_data *ud,
 	AttributeDescription *ad,
 	BerVarray b,
-	char *kp
+	char *kp,
+	void *ctx
 )
 {
 	unique_attrs *up;
 	int i;
 
-	while(!is_at_operational(ad->ad_type)) {
-		if(ud->ignore) {
-			for(up = ud->ignore; up; up = up->next)
-				if(ad == up->attr) break;
-			if(up) break;
+	while ( !is_at_operational( ad->ad_type ) ) {
+		if ( ud->ignore ) {
+			for ( up = ud->ignore; up; up = up->next ) {
+				if ( ad == up->attr ) {
+					break;
+				}
+			}
+			if ( up ) {
+				break;
+			}
 		}
-		if(ud->attrs) {
-			for(up = ud->attrs; up; up = up->next)
-				if(ad == up->attr) break;
-			if(!up) break;
+		if ( ud->attrs ) {
+			for ( up = ud->attrs; up; up = up->next ) {
+				if ( ad == up->attr ) {
+					break;
+				}
+			}
+			if ( !up ) {
+				break;
+			}
+		}
+		if ( b && b[0].bv_val ) {
+			for ( i = 0; b[i].bv_val; i++ ) {
+				struct berval	bv;
+
+				ldap_bv2escaped_filter_value_x( &b[i], &bv, 1, ctx );
+				kp += sprintf( kp, "(%s=%s)", ad->ad_cname.bv_val, bv.bv_val );
+				if ( bv.bv_val != b[i].bv_val ) {
+					ber_memfree_x( bv.bv_val, ctx );
+				}
+			}
+		} else if ( ud->strict ) {
+			kp += sprintf( kp, "(%s=*)", ad->ad_cname.bv_val );
 		}
-		if(b && b[0].bv_val) for(i = 0; b[i].bv_val; i++)
-			kp += sprintf(kp, "(%s=%s)", ad->ad_cname.bv_val, b[i].bv_val);
-		else if(ud->strict)
-			kp += sprintf(kp, "(%s=*)", ad->ad_cname.bv_val);
 		break;
 	}
 	return kp;
@@ -409,7 +443,7 @@ static int unique_add(
 	kp = key + sprintf(key, "(|");
 
 	for(a = op->ora_e->e_attrs; a; a = a->a_next) {
-		kp = build_filter(ud, a->a_desc, a->a_vals, kp);
+		kp = build_filter(ud, a->a_desc, a->a_vals, kp, op->o_tmpmemctx);
 	}
 
 	sprintf(kp, ")");
@@ -461,7 +495,7 @@ static int unique_modify(
 
 	for(m = op->orm_modlist; m; m = m->sml_next) {
  		if ((m->sml_op & LDAP_MOD_OP) == LDAP_MOD_DELETE) continue;
- 		kp = build_filter(ud, m->sml_desc, m->sml_values, kp);
+ 		kp = build_filter(ud, m->sml_desc, m->sml_values, kp, op->o_tmpmemctx);
 	}
 
 	sprintf(kp, ")");
@@ -524,7 +558,7 @@ static int unique_modrdn(
 
 	for(i = 0; newrdn[i]; i++) {
 		bv[0] = newrdn[i]->la_value;
-		kp = build_filter(ud, newrdn[i]->la_private, bv, kp);
+		kp = build_filter(ud, newrdn[i]->la_private, bv, kp, op->o_tmpmemctx);
 	}
 
 	sprintf(kp, ")");
@@ -539,7 +573,7 @@ static int unique_modrdn(
 ** it expects to be called automagically during dynamic module initialization
 */
 
-int unique_init() {
+int unique_initialize() {
 
 	/* statically declared just after the #includes at top */
 	unique.on_bi.bi_type = "unique";
@@ -557,7 +591,7 @@ int unique_init() {
 
 #if SLAPD_OVER_UNIQUE == SLAPD_MOD_DYNAMIC && defined(PIC)
 int init_module(int argc, char *argv[]) {
-	return unique_init();
+	return unique_initialize();
 }
 #endif
 
diff --git a/servers/slapd/overlays/valsort.c b/servers/slapd/overlays/valsort.c
index 1fe209b3c7b4349ce987854a06133415f907692d..1f42a13b3af0c87abd24a273bd1330c2f7d69dcf 100644
--- a/servers/slapd/overlays/valsort.c
+++ b/servers/slapd/overlays/valsort.c
@@ -531,7 +531,7 @@ valsort_parseCtrl(
 
 static slap_overinst valsort;
 
-int valsort_init()
+int valsort_initialize( void )
 {
 	int rc;
 
@@ -564,7 +564,7 @@ int valsort_init()
 
 #if SLAPD_OVER_VALSORT == SLAPD_MOD_DYNAMIC
 int init_module( int argc, char *argv[]) {
-	return valsort_init();
+	return valsort_initialize();
 }
 #endif
 
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index 14a7b8ea7761fda1b5304e8c6ba12de7d7322584..6727669d9996d57f1d8b6a6fe29ec7b89f7eef61 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -913,8 +913,8 @@ LDAP_SLAPD_F (void) vrFilter_free LDAP_P(( Operation *op, ValuesReturnFilter *f
 LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( Operation *op, ValuesReturnFilter *f, struct berval *fstr ));
 
 LDAP_SLAPD_F (int) filter_has_subordinates LDAP_P(( Filter *filter ));
-LDAP_SLAPD_F (int) filter_escape_value LDAP_P(( struct berval *in, 
-	struct berval *out ));
+#define filter_escape_value( in, out )		ldap_bv2escaped_filter_value_x( (in), (out), 0, NULL )
+#define filter_escape_value_x( in, out, ctx )	ldap_bv2escaped_filter_value_x( (in), (out), 0, ctx )
 
 /*
  * filterentry.c
diff --git a/servers/slapd/result.c b/servers/slapd/result.c
index 52a67ea2f8cd9e59aeb7bc3beeeea10198b59fc5..29bdb2ff7e098d08624b5a96b9fbfa8a7a88d5ac 100644
--- a/servers/slapd/result.c
+++ b/servers/slapd/result.c
@@ -36,6 +36,7 @@
 #include <ac/unistd.h>
 
 #include "slap.h"
+#include "lutil.h"
 
 const struct berval slap_dummy_bv = BER_BVNULL;
 
@@ -556,11 +557,8 @@ slap_send_ldap_result( Operation *op, SlapReply *rs )
 	assert( rs->sr_err != LDAP_PARTIAL_RESULTS );
 
 	if ( rs->sr_err == LDAP_REFERRAL ) {
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
-		if( op->o_domain_scope ) {
-			rs->sr_ref = NULL;
-		}
-#endif
+		if( op->o_domain_scope ) rs->sr_ref = NULL;
+
 		if( rs->sr_ref == NULL ) {
 			rs->sr_err = LDAP_NO_SUCH_OBJECT;
 		} else if ( op->o_protocol < LDAP_VERSION3 ) {
@@ -661,13 +659,23 @@ slap_send_ldap_intermediate( Operation *op, SlapReply *rs )
 	}
 }
 
+/*
+ * returns:
+ *
+ * LDAP_SUCCESS			entry sent
+ * LDAP_OTHER			entry not sent (other)
+ * LDAP_INSUFFICIENT_ACCESS	entry not sent (ACL)
+ * LDAP_UNAVAILABLE		entry not sent (connection closed)
+ * LDAP_SIZELIMIT_EXCEEDED	entry not sent (caller must send sizelimitExceeded)
+ */
+
 int
 slap_send_search_entry( Operation *op, SlapReply *rs )
 {
 	BerElementBuffer berbuf;
 	BerElement	*ber = (BerElement *) &berbuf;
 	Attribute	*a;
-	int		i, j, rc=-1, bytes;
+	int		i, j, rc = LDAP_UNAVAILABLE, bytes;
 	char		*edn;
 	int		userattrs;
 	AccessControlState acl_state = ACL_STATE_INIT;
@@ -679,7 +687,11 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 	 * e_flags: array of a_flags
 	 */
 	char **e_flags = NULL;
-	
+
+	if ( op->ors_slimit >= 0 && rs->sr_nentries >= op->ors_slimit ) {
+		return LDAP_SIZELIMIT_EXCEEDED;
+	}
+
 	rs->sr_type = REP_SEARCH;
 
 	/* eventually will loop through generated operational attribute types
@@ -730,7 +742,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 			"send_search_entry: conn %lu access to entry (%s) not allowed\n", 
 			op->o_connid, rs->sr_entry->e_name.bv_val, 0 );
 
-		rc = 1;
+		rc = LDAP_INSUFFICIENT_ACCESS;
 		goto error_return;
 	}
 
@@ -776,6 +788,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
 		if ( op->o_res_ber == NULL ) ber_free_buf( ber );
 		send_ldap_error( op, rs, LDAP_OTHER, "encoding DN error" );
+		rc = rs->sr_err;
 		goto error_return;
 	}
 
@@ -823,6 +836,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 				if ( op->o_res_ber == NULL ) ber_free_buf( ber );
 				send_ldap_error( op, rs, LDAP_OTHER,
 					"matched values filtering error" );
+				rc = rs->sr_err;
 				goto error_return;
 			}
 		}
@@ -872,6 +886,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 				if ( op->o_res_ber == NULL ) ber_free_buf( ber );
 				send_ldap_error( op, rs, LDAP_OTHER,
 					"encoding description error");
+				rc = rs->sr_err;
 				goto error_return;
 			}
 			finish = 1;
@@ -905,6 +920,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 						if ( op->o_res_ber == NULL ) ber_free_buf( ber );
 						send_ldap_error( op, rs, LDAP_OTHER,
 							"encoding description error");
+						rc = rs->sr_err;
 						goto error_return;
 					}
 				}
@@ -916,6 +932,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 					if ( op->o_res_ber == NULL ) ber_free_buf( ber );
 					send_ldap_error( op, rs, LDAP_OTHER,
 						"encoding values error" );
+					rc = rs->sr_err;
 					goto error_return;
 				}
 			}
@@ -928,6 +945,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
 			if ( op->o_res_ber == NULL ) ber_free_buf( ber );
 			send_ldap_error( op, rs, LDAP_OTHER, "encode end error" );
+			rc = rs->sr_err;
 			goto error_return;
 		}
 	}
@@ -981,6 +999,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 				if ( op->o_res_ber == NULL ) ber_free_buf( ber );
 				send_ldap_error( op, rs, LDAP_OTHER,
 					"matched values filtering error" );
+				rc = rs->sr_err;
 				goto error_return;
 			}
 		}
@@ -1030,6 +1049,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 			if ( op->o_res_ber == NULL ) ber_free_buf( ber );
 			send_ldap_error( op, rs, LDAP_OTHER,
 				"encoding description error" );
+			rc = rs->sr_err;
 			goto error_return;
 		}
 
@@ -1058,6 +1078,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 					if ( op->o_res_ber == NULL ) ber_free_buf( ber );
 					send_ldap_error( op, rs, LDAP_OTHER,
 						"encoding values error" );
+					rc = rs->sr_err;
 					goto error_return;
 				}
 			}
@@ -1070,6 +1091,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
 			if ( op->o_res_ber == NULL ) ber_free_buf( ber );
 			send_ldap_error( op, rs, LDAP_OTHER, "encode end error" );
+			rc = rs->sr_err;
 			goto error_return;
 		}
 	}
@@ -1104,7 +1126,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
 		if ( op->o_res_ber == NULL ) ber_free_buf( ber );
 		send_ldap_error( op, rs, LDAP_OTHER, "encode entry end error" );
-		rc = 1;
+		rc = rs->sr_err;
 		goto error_return;
 	}
 
@@ -1123,7 +1145,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 				"send_search_entry: conn %lu  ber write failed.\n", 
 				op->o_connid, 0, 0 );
 
-			rc = -1;
+			rc = LDAP_UNAVAILABLE;
 			goto error_return;
 		}
 		rs->sr_nentries++;
@@ -1141,7 +1163,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 	Debug( LDAP_DEBUG_TRACE,
 		"<= send_search_entry: conn %lu exit.\n", op->o_connid, 0, 0 );
 
-	rc = 0;
+	rc = LDAP_SUCCESS;
 
 error_return:;
 	if ( op->o_callback ) {
@@ -1246,7 +1268,6 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 		goto rel;
 	}
 
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
 	if( op->o_domain_scope ) {
 		Debug( LDAP_DEBUG_ANY,
 			"send_search_reference: domainScope control in (%s)\n", 
@@ -1254,7 +1275,6 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 		rc = 0;
 		goto rel;
 	}
-#endif
 
 	if( rs->sr_ref == NULL ) {
 		Debug( LDAP_DEBUG_ANY,
@@ -1397,8 +1417,8 @@ str2result(
 		}
 
 		if ( strncasecmp( s, "code", STRLENOF( "code" ) ) == 0 ) {
-			if ( c != NULL ) {
-				*code = atoi( c );
+			if ( c != NULL && lutil_atoi( code, c ) != 0 ) {
+				goto bailout;
 			}
 		} else if ( strncasecmp( s, "matched", STRLENOF( "matched" ) ) == 0 ) {
 			if ( c != NULL ) {
@@ -1409,6 +1429,7 @@ str2result(
 				*info = c;
 			}
 		} else {
+bailout:;
 			Debug( LDAP_DEBUG_ANY, "str2result (%s) unknown\n",
 			    s, 0, 0 );
 
diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c
index 58f8a963426db241eaf6f7d571277b68e62c27d3..3867dfcef998ab94dd4b40b92a6ae4da43643525 100644
--- a/servers/slapd/sasl.c
+++ b/servers/slapd/sasl.c
@@ -150,10 +150,10 @@ static const char *slap_propnames[] = {
 static Filter generic_filter = { LDAP_FILTER_PRESENT, { 0 }, NULL };
 static struct berval generic_filterstr = BER_BVC("(objectclass=*)");
 
-#define	PROP_CONN	0
-#define	PROP_AUTHC	1
-#define	PROP_AUTHZ	2
-#define	PROP_COUNT	3	/* Number of properties we used */
+#define	SLAP_SASL_PROP_CONN	0
+#define	SLAP_SASL_PROP_AUTHC	1
+#define	SLAP_SASL_PROP_AUTHZ	2
+#define	SLAP_SASL_PROP_COUNT	3	/* Number of properties we used */
 
 typedef struct lookup_info {
 	int flags;
@@ -185,7 +185,7 @@ sasl_ap_lookup( Operation *op, SlapReply *rs )
 			if ( sl->flags & SASL_AUXPROP_AUTHZID ) continue;
 			/* Skip our private properties */
 			if ( !strcmp( name, slap_propnames[0] )) {
-				i += PROP_COUNT-1;
+				i += SLAP_SASL_PROP_COUNT - 1;
 				continue;
 			}
 			name++;
@@ -275,19 +275,19 @@ slap_auxprop_lookup(
 	/* Find our DN and conn first */
 	for( i = 0; sl.list[i].name; i++ ) {
 		if ( sl.list[i].name[0] == '*' ) {
-			if ( !strcmp( sl.list[i].name, slap_propnames[PROP_CONN] ) ) {
+			if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_CONN] ) ) {
 				if ( sl.list[i].values && sl.list[i].values[0] )
 					AC_MEMCPY( &conn, sl.list[i].values[0], sizeof( conn ) );
 				continue;
 			}
 			if ( (flags & SASL_AUXPROP_AUTHZID) &&
-				!strcmp( sl.list[i].name, slap_propnames[PROP_AUTHZ] ) ) {
+				!strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHZ] ) ) {
 
 				if ( sl.list[i].values && sl.list[i].values[0] )
 					AC_MEMCPY( &op.o_req_ndn, sl.list[i].values[0], sizeof( struct berval ) );
 				break;
 			}
-			if ( !strcmp( sl.list[i].name, slap_propnames[PROP_AUTHC] ) ) {
+			if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHC] ) ) {
 				if ( sl.list[i].values && sl.list[i].values[0] ) {
 					AC_MEMCPY( &op.o_req_ndn, sl.list[i].values[0], sizeof( struct berval ) );
 					if ( !(flags & SASL_AUXPROP_AUTHZID) )
@@ -305,7 +305,7 @@ slap_auxprop_lookup(
 			if ( flags & SASL_AUXPROP_AUTHZID ) continue;
 			/* Skip our private properties */
 			if ( !strcmp( name, slap_propnames[0] )) {
-				i += PROP_COUNT-1;
+				i += SLAP_SASL_PROP_COUNT - 1;
 				continue;
 			}
 			name++;
@@ -423,12 +423,12 @@ slap_auxprop_store(
 	/* Find our DN and conn first */
 	for( i = 0; pr[i].name; i++ ) {
 		if ( pr[i].name[0] == '*' ) {
-			if ( !strcmp( pr[i].name, slap_propnames[PROP_CONN] ) ) {
+			if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_CONN] ) ) {
 				if ( pr[i].values && pr[i].values[0] )
 					AC_MEMCPY( &conn, pr[i].values[0], sizeof( conn ) );
 				continue;
 			}
-			if ( !strcmp( pr[i].name, slap_propnames[PROP_AUTHC] ) ) {
+			if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_AUTHC] ) ) {
 				if ( pr[i].values && pr[i].values[0] ) {
 					AC_MEMCPY( &op.o_req_ndn, pr[i].values[0], sizeof( struct berval ) );
 				}
@@ -542,7 +542,7 @@ slap_sasl_canonicalize(
 {
 	Connection *conn = (Connection *)context;
 	struct propctx *props = sasl_auxprop_getctx( sconn );
-	struct propval auxvals[3];
+	struct propval auxvals[ SLAP_SASL_PROP_COUNT ] = { { 0 } };
 	struct berval dn;
 	int rc, which;
 	const char *names[2];
@@ -575,13 +575,13 @@ slap_sasl_canonicalize(
 		prop_request( props, slap_propnames );
 
 	if ( flags & SASL_CU_AUTHID )
-		which = PROP_AUTHC;
+		which = SLAP_SASL_PROP_AUTHC;
 	else
-		which = PROP_AUTHZ;
+		which = SLAP_SASL_PROP_AUTHZ;
 
 	/* Need to store the Connection for auxprop_lookup */
-	if ( !auxvals[PROP_CONN].values ) {
-		names[0] = slap_propnames[PROP_CONN];
+	if ( !auxvals[SLAP_SASL_PROP_CONN].values ) {
+		names[0] = slap_propnames[SLAP_SASL_PROP_CONN];
 		names[1] = NULL;
 		prop_set( props, names[0], (char *)&conn, sizeof( conn ) );
 	}
@@ -605,7 +605,7 @@ slap_sasl_canonicalize(
 	 * it does authzID before the authcID. If we see that authzID
 	 * has already been done, don't do anything special with authcID.
 	 */
-	if ( flags == SASL_CU_AUTHID && !auxvals[PROP_AUTHZ].values ) {
+	if ( flags == SASL_CU_AUTHID && !auxvals[SLAP_SASL_PROP_AUTHZ].values ) {
 		conn->c_sasl_dn.bv_val = (char *) in;
 	} else if ( flags == SASL_CU_AUTHZID && conn->c_sasl_dn.bv_val ) {
 		rc = strcmp( in, conn->c_sasl_dn.bv_val );
@@ -654,7 +654,11 @@ slap_sasl_authorize(
 	struct propctx *props)
 {
 	Connection *conn = (Connection *)context;
-	struct propval auxvals[3];
+	/* actually:
+	 *	(SLAP_SASL_PROP_COUNT - 1)	because we skip "conn",
+	 *	+ 1				for NULL termination?
+	 */
+	struct propval auxvals[ SLAP_SASL_PROP_COUNT ] = { { 0 } };
 	struct berval authcDN, authzDN = BER_BVNULL;
 	int rc;
 
@@ -670,7 +674,7 @@ slap_sasl_authorize(
 		BER_BVZERO( &conn->c_sasl_dn );
 	}
 
-	/* Skip PROP_CONN */
+	/* Skip SLAP_SASL_PROP_CONN */
 	prop_getnames( props, slap_propnames+1, auxvals );
 	
 	/* Should not happen */
diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c
index 106dca9112a9f736e770c5ca46e479bd30fff2e5..42bb8a136810b99e193f7fd7f0f886832b6fe215 100644
--- a/servers/slapd/saslauthz.c
+++ b/servers/slapd/saslauthz.c
@@ -1969,9 +1969,7 @@ slap_sasl2dn(
 	case LDAP_SCOPE_BASE:
 	case LDAP_SCOPE_ONELEVEL:
 	case LDAP_SCOPE_SUBTREE:
-#ifdef LDAP_SCOPE_SUBORDINATE
 	case LDAP_SCOPE_SUBORDINATE:
-#endif
 		/* do a search */
 		break;
 
diff --git a/servers/slapd/schema_prep.c b/servers/slapd/schema_prep.c
index 7349628240966aa320d006b4b1e63dae89822060..ca06f111002f23ec8b61bda7fb99276cd8d75dfa 100644
--- a/servers/slapd/schema_prep.c
+++ b/servers/slapd/schema_prep.c
@@ -1207,6 +1207,7 @@ slap_schema_load( void )
 
 			code = at_add( at, 0, NULL, &err );
 			if ( code ) {
+				ldap_attributetype_free( at );
 				fprintf( stderr, "slap_schema_load: AttributeType "
 					"\"%s\": %s: \"%s\"\n",
 					 ad_map[i].ssam_name, scherr2str(code), err );
diff --git a/servers/slapd/schemaparse.c b/servers/slapd/schemaparse.c
index 0834dc0ae8c08a6795bce87c7e65c7fec5f71910..7aa7d61ba36513b2446a0de2ca9a1a6d1ff30ec8 100644
--- a/servers/slapd/schemaparse.c
+++ b/servers/slapd/schemaparse.c
@@ -280,6 +280,7 @@ parse_at(
 
 	code = at_add(at,1,sat,&err);
 	if ( code ) {
+		ldap_attributetype_free( at );
 		fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
 			 fname, lineno, scherr2str(code), err);
 		return 1;
diff --git a/servers/slapd/search.c b/servers/slapd/search.c
index 11b5f0733da311c189b658a30568597561ca5117..97f3e923c1bb7e661ef15755390a6820699c65fe 100644
--- a/servers/slapd/search.c
+++ b/servers/slapd/search.c
@@ -92,9 +92,7 @@ do_search(
 	case LDAP_SCOPE_BASE:
 	case LDAP_SCOPE_ONELEVEL:
 	case LDAP_SCOPE_SUBTREE:
-#ifdef LDAP_SCOPE_SUBORDINATE
 	case LDAP_SCOPE_SUBORDINATE:
-#endif
 		break;
 	default:
 		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid scope" );
@@ -283,9 +281,17 @@ fe_op_search( Operation *op, SlapReply *rs )
 			rs->sr_err = test_filter( op, entry, op->ors_filter );
 
 			if( rs->sr_err == LDAP_COMPARE_TRUE ) {
+				/* note: we set no limits because either
+				 * no limit is specified, or at least 1
+				 * is specified, and we're going to return
+				 * at most one entry */			
+				op->ors_slimit = SLAP_NO_LIMIT;
+				op->ors_tlimit = SLAP_NO_LIMIT;
+
 				rs->sr_entry = entry;
 				rs->sr_attrs = op->ors_attrs;
 				rs->sr_operational_attrs = NULL;
+				rs->sr_flags = 0;
 				send_search_entry( op, rs );
 				rs->sr_entry = NULL;
 				rs->sr_operational_attrs = NULL;
diff --git a/servers/slapd/shell-backends/shellutil.c b/servers/slapd/shell-backends/shellutil.c
index 2731b52b8676a3b55814d68e8b5c4de10c6ed99a..b519cf4d5c60b82200228244f877d60e6f8963f3 100644
--- a/servers/slapd/shell-backends/shellutil.c
+++ b/servers/slapd/shell-backends/shellutil.c
@@ -185,21 +185,32 @@ parse_input( FILE *ifp, FILE *ofp, struct ldop *op )
 	    op->ldop_dn = estrdup( args );
 	    break;
 	case IP_TYPE_SCOPE:
-	    if (( op->ldop_srch.ldsp_scope = atoi( args )) != LDAP_SCOPE_BASE &&
+	    if ( lutil_atoi( &op->ldop_srch.ldsp_scope, args ) != 0 ||
+		( op->ldop_srch.ldsp_scope != LDAP_SCOPE_BASE &&
 		    op->ldop_srch.ldsp_scope != LDAP_SCOPE_ONELEVEL &&
-		    op->ldop_srch.ldsp_scope != LDAP_SCOPE_SUBTREE ) {
+		    op->ldop_srch.ldsp_scope != LDAP_SCOPE_SUBTREE ) )
+	    {
 		write_result( ofp, LDAP_OTHER, NULL, "Bad scope" );
 		return( -1 );
 	    }
 	    break;
 	case IP_TYPE_ALIASDEREF:
-	    op->ldop_srch.ldsp_aliasderef = atoi( args );
+	    if ( lutil_atoi( &op->ldop_srch.ldsp_aliasderef, args ) != 0 ) {
+		write_result( ofp, LDAP_OTHER, NULL, "Bad alias deref" );
+		return( -1 );
+	    }
 	    break;
 	case IP_TYPE_SIZELIMIT:
-	    op->ldop_srch.ldsp_sizelimit = atoi( args );
+	    if ( lutil_atoi( &op->ldop_srch.ldsp_sizelimit, args ) != 0 ) {
+		write_result( ofp, LDAP_OTHER, NULL, "Bad size limit" );
+		return( -1 );
+	    }
 	    break;
 	case IP_TYPE_TIMELIMIT:
-	    op->ldop_srch.ldsp_timelimit = atoi( args );
+	    if ( lutil_atoi( &op->ldop_srch.ldsp_timelimit, args ) != 0 ) {
+		write_result( ofp, LDAP_OTHER, NULL, "Bad time limit" );
+		return( -1 );
+	    }
 	    break;
 	case IP_TYPE_FILTER:
 	    op->ldop_srch.ldsp_filter = estrdup( args );
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index 5f280d36639f080038571ea3e55c0eaee3960029..4379a6dadc167870b1b707c26e2cb50da200ba4c 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -74,8 +74,8 @@ LDAP_BEGIN_DECL
 #define LDAP_DYNAMIC_OBJECTS
 #define LDAP_SYNC_TIMESTAMP
 #define LDAP_COLLECTIVE_ATTRIBUTES
-#define SLAP_CONTROL_X_TREE_DELETE LDAP_CONTROL_X_TREE_DELETE
 #define SLAPD_CONF_UNKNOWN_BAILOUT
+#define SLAP_CONTROL_X_TREE_DELETE LDAP_CONTROL_X_TREE_DELETE
 
 #define SLAP_ORDERED_PRETTYNORM
 #define SLAP_AUTHZ_SYNTAX
@@ -1005,9 +1005,7 @@ typedef struct slap_filter {
 #define SLAPD_FILTER_COMPUTED		((ber_tag_t) -1)
 #define SLAPD_FILTER_DN_ONE			((ber_tag_t) -2)
 #define SLAPD_FILTER_DN_SUBTREE		((ber_tag_t) -3)
-#ifdef LDAP_SCOPE_SUBORDINATE
 #define SLAPD_FILTER_DN_CHILDREN	((ber_tag_t) -4)
-#endif
 
 	union f_un_u {
 		/* precomputed result */
@@ -1846,21 +1844,23 @@ struct slap_conn;
 struct slap_op;
 
 /* Backend function typedefs */
-typedef int (BI_init) LDAP_P((BackendInfo *bi));
+typedef int (BI_bi_func) LDAP_P((BackendInfo *bi));
+typedef BI_bi_func BI_init;
+typedef BI_bi_func BI_open;
+typedef BI_bi_func BI_close;
+typedef BI_bi_func BI_destroy;
 typedef int (BI_config) LDAP_P((BackendInfo *bi,
 	const char *fname, int lineno,
 	int argc, char **argv));
-typedef int (BI_open) LDAP_P((BackendInfo *bi));
-typedef int (BI_close) LDAP_P((BackendInfo *bi));
-typedef int (BI_destroy) LDAP_P((BackendInfo *bi));
 
-typedef int (BI_db_init) LDAP_P((Backend *bd));
+typedef int (BI_db_func) LDAP_P((Backend *bd));
+typedef BI_db_func BI_db_init;
+typedef BI_db_func BI_db_open;
+typedef BI_db_func BI_db_close;
+typedef BI_db_func BI_db_destroy;
 typedef int (BI_db_config) LDAP_P((Backend *bd,
 	const char *fname, int lineno,
 	int argc, char **argv));
-typedef int (BI_db_open) LDAP_P((Backend *bd));
-typedef int (BI_db_close) LDAP_P((Backend *bd));
-typedef int (BI_db_destroy) LDAP_P((Backend *bd));
 
 typedef struct req_bind_s {
 	int rb_method;
@@ -2001,22 +2001,20 @@ typedef struct slap_rep {
 #define	sr_rspdata sr_un.sru_extended.r_rspdata
 #define	sr_sasldata sr_un.sru_sasl.r_sasldata
 
-typedef int (BI_op_bind) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_op_unbind) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_op_search) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_op_compare) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_op_modify) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_op_modrdn) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_op_add) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_op_delete) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_op_abandon) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_op_cancel) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_op_extended) LDAP_P((
-	struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_chk_referrals) LDAP_P((
-	struct slap_op *op, struct slap_rep *rs ));
-typedef int (BI_chk_controls) LDAP_P((
-	struct slap_op *op, struct slap_rep *rs ));
+typedef int (BI_op_func) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
+typedef BI_op_func BI_op_bind;
+typedef BI_op_func BI_op_unbind;
+typedef BI_op_func BI_op_search;
+typedef BI_op_func BI_op_compare;
+typedef BI_op_func BI_op_modify;
+typedef BI_op_func BI_op_modrdn;
+typedef BI_op_func BI_op_add;
+typedef BI_op_func BI_op_delete;
+typedef BI_op_func BI_op_abandon;
+typedef BI_op_func BI_op_cancel;
+typedef BI_op_func BI_op_extended;
+typedef BI_op_func BI_chk_referrals;
+typedef BI_op_func BI_chk_controls;
 typedef int (BI_entry_release_rw)
 	LDAP_P(( struct slap_op *op, Entry *e, int rw ));
 typedef int (BI_entry_get_rw) LDAP_P(( struct slap_op *op, struct berval *ndn,
@@ -2036,10 +2034,9 @@ typedef int (BI_acl_attribute) LDAP_P(( struct slap_op *op, Entry *target,
 	BerVarray *vals, slap_access_t access ));
 #endif /* SLAP_OVERLAY_ACCESS */
 
-typedef int (BI_connection_init) LDAP_P(( BackendDB *bd,
-	struct slap_conn *c ));
-typedef int (BI_connection_destroy) LDAP_P(( BackendDB *bd,
-	struct slap_conn *c ));
+typedef int (BI_conn_func) LDAP_P(( BackendDB *bd, struct slap_conn *c ));
+typedef BI_conn_func BI_connection_init;
+typedef BI_conn_func BI_connection_destroy;
 
 typedef int (BI_tool_entry_open) LDAP_P(( BackendDB *be, int mode ));
 typedef int (BI_tool_entry_close) LDAP_P(( BackendDB *be ));
@@ -2253,8 +2250,8 @@ typedef struct slap_overinfo {
 } slap_overinfo;
 
 /* Should successive callbacks in a chain be processed? */
-#define	SLAP_CB_FREEME		0x4000
-#define	SLAP_CB_CONTINUE	0x8000
+#define	SLAP_CB_FREEME		0x04000
+#define	SLAP_CB_CONTINUE	0x08000
 
 /*
  * Paged Results state
@@ -2291,25 +2288,26 @@ typedef struct slap_gacl {
 } GroupAssertion;
 
 struct slap_control_ids {
+	int sc_LDAPsync;
 	int sc_assert;
-	int sc_preRead;
-	int sc_postRead;
-	int sc_proxyAuthz;
+	int sc_domainScope;
+	int sc_dontUseCopy;
 	int sc_manageDIT;
 	int sc_manageDSAit;
 	int sc_modifyIncrement;
 	int sc_noOp;
 	int sc_pagedResults;
+	int sc_permissiveModify;
+	int sc_postRead;
+	int sc_preRead;
+	int sc_proxyAuthz;
+	int sc_searchOptions;
 #ifdef LDAP_DEVEL
 	int sc_sortedResults;
 #endif
-	int sc_valuesReturnFilter;
-	int sc_permissiveModify;
-	int sc_domainScope;
-	int sc_treeDelete;
-	int sc_searchOptions;
 	int sc_subentries;
-	int sc_LDAPsync;
+	int sc_treeDelete;
+	int sc_valuesReturnFilter;
 };
 
 /*
@@ -2457,6 +2455,9 @@ typedef struct slap_op {
 	char o_ctrlflag[SLAP_MAX_CIDS];	/* per-control flags */
 	void **o_controls;		/* per-control state */
 
+#define o_dontUseCopy			o_ctrlflag[slap_cids.sc_dontUseCopy]
+#define get_dontUseCopy(op)		_SCM((op)->o_dontUseCopy)
+
 #define o_managedit				o_ctrlflag[slap_cids.sc_manageDIT]
 #define get_manageDIT(op)		_SCM((op)->o_managedit)
 
@@ -2481,26 +2482,14 @@ typedef struct slap_op {
 #define	o_valuesreturnfilter	o_ctrlflag[slap_cids.sc_valuesReturnFilter]
 #define o_vrFilter	o_controls[slap_cids.sc_valuesReturnFilter]
 
-#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
 #define o_permissive_modify	o_ctrlflag[slap_cids.sc_permissiveModify]
 #define get_permissiveModify(op)		((int)(op)->o_permissive_modify)
-#else
-#define get_permissiveModify(op)		(0)
-#endif
 
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
 #define o_domain_scope	o_ctrlflag[slap_cids.sc_domainScope]
 #define get_domainScope(op)				((int)(op)->o_domain_scope)
-#else
-#define get_domainScope(op)				(0)
-#endif
 
-#ifdef SLAP_CONTROL_X_TREE_DELETE
 #define	o_tree_delete	o_ctrlflag[slap_cids.sc_treeDelete]
 #define get_treeDelete(op)				((int)(op)->o_tree_delete)
-#else
-#define get_treeDelete(op)				(0)
-#endif
 
 #define o_preread	o_ctrlflag[slap_cids.sc_preRead]
 #define o_postread	o_ctrlflag[slap_cids.sc_postRead]
@@ -2670,10 +2659,7 @@ typedef struct slap_conn {
 	SEND_SEARCH_ENTRY *c_send_search_entry;
 	SEND_SEARCH_REFERENCE *c_send_search_reference;
 	SEND_LDAP_EXTENDED *c_send_ldap_extended;
-#ifdef LDAP_RES_INTERMEDIATE
 	SEND_LDAP_INTERMEDIATE *c_send_ldap_intermediate;
-#endif
-
 } Connection;
 
 #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG)
@@ -3096,6 +3082,12 @@ struct zone_heap {
 		return 0; \
 	}
 
+typedef int (OV_init)(void);
+typedef struct slap_oinit_t {
+	const char	*ov_type;
+	OV_init		*ov_init;
+} OverlayInit;
+
 LDAP_END_DECL
 
 #include "proto-slap.h"
diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c
index 906d7a60464e216618e729987b168d54f47b8382..389998655a1a8fcf4627dab516789da61d4bab64 100644
--- a/servers/slapd/slapcommon.c
+++ b/servers/slapd/slapcommon.c
@@ -133,16 +133,28 @@ parse_slapacl( void )
 		ber_str2bv( p, 0, 1, &sock_name );
 
 	} else if ( strncasecmp( optarg, "ssf", len ) == 0 ) {
-		ssf = atoi( p );
+		if ( lutil_atou( &ssf, p ) ) {
+			Debug( LDAP_DEBUG_ANY, "unable to parse ssf=\"%s\".\n", p, 0, 0 );
+			return -1;
+		}
 
 	} else if ( strncasecmp( optarg, "transport_ssf", len ) == 0 ) {
-		transport_ssf = atoi( p );
+		if ( lutil_atou( &transport_ssf, p ) ) {
+			Debug( LDAP_DEBUG_ANY, "unable to parse transport_ssf=\"%s\".\n", p, 0, 0 );
+			return -1;
+		}
 
 	} else if ( strncasecmp( optarg, "tls_ssf", len ) == 0 ) {
-		tls_ssf = atoi( p );
+		if ( lutil_atou( &tls_ssf, p ) ) {
+			Debug( LDAP_DEBUG_ANY, "unable to parse tls_ssf=\"%s\".\n", p, 0, 0 );
+			return -1;
+		}
 
 	} else if ( strncasecmp( optarg, "sasl_ssf", len ) == 0 ) {
-		sasl_ssf = atoi( p );
+		if ( lutil_atou( &sasl_ssf, p ) ) {
+			Debug( LDAP_DEBUG_ANY, "unable to parse sasl_ssf=\"%s\".\n", p, 0, 0 );
+			return -1;
+		}
 
 	} else if ( strncasecmp( optarg, "authzDN", len ) == 0 ) {
 		ber_str2bv( p, 0, 1, &authzDN );
@@ -264,16 +276,11 @@ slap_tool_init(
 					exit( EXIT_FAILURE );
 				}
 
-			} else {
-				char	*next = NULL;
-
-				level = strtol( optarg, &next, 0 );
-				if ( next == NULL || next[ 0 ] != '\0' ) {
-					fprintf( stderr,
-						"unrecognized log level "
-						"\"%s\"\n", optarg );
-					exit( EXIT_FAILURE );
-				}
+			} else if ( lutil_atoix( &level, optarg, 0 ) != 0 ) {
+				fprintf( stderr,
+					"unrecognized log level "
+					"\"%s\"\n", optarg );
+				exit( EXIT_FAILURE );
 			}
 
 			if ( level ) {
@@ -283,7 +290,7 @@ slap_tool_init(
 				ldap_debug = 0;
 			}
 #else
-			if ( atoi( optarg ) != 0 )
+			if ( lutil_atoi( &level, optarg ) != 0 || level != 0 )
 				fputs( "must compile with LDAP_DEBUG for debugging\n",
 				       stderr );
 #endif
@@ -321,7 +328,9 @@ slap_tool_init(
 			break;
 
 		case 'n':	/* which config file db to index */
-			dbnum = atoi( optarg );
+			if ( lutil_atoi( &dbnum, optarg ) ) {
+				usage( tool, progname );
+			}
 			break;
 
 		case 'o':
diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c
index a801e54a7cce3e10a69f1ef8d8773f4885d207b7..abce34456cc44687cf55e7bae5d7294f85b078e6 100644
--- a/servers/slapd/syncrepl.c
+++ b/servers/slapd/syncrepl.c
@@ -188,7 +188,7 @@ init_syncrepl(syncinfo_t *si)
 		}
 
 		if ( attrs == NULL ) {
-			Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 );
+			Debug( LDAP_DEBUG_ANY, "out of memory\n", 0, 0, 0 );
 		}
 
 		/* Add Attributes */
@@ -500,7 +500,7 @@ do_syncrep1(
 #else /* HAVE_CYRUS_SASL */
 		/* Should never get here, we trapped this at config time */
 		assert(0);
-		fprintf( stderr, "not compiled with SASL support\n" );
+		Debug( LDAP_DEBUG_SYNC, "not compiled with SASL support\n", 0, 0, 0 );
 		rc = LDAP_OTHER;
 		goto done;
 #endif
@@ -756,7 +756,7 @@ do_syncrep2(
 						si->si_logstate = SYNCLOG_FALLBACK;
 					}
 					rc = err;
-					break;
+					goto done;
 				}
 				if ( rctrls ) {
 					rctrlp = *rctrls;
@@ -2683,10 +2683,8 @@ static struct {
 	{ BER_BVC("base"), LDAP_SCOPE_BASE },
 	{ BER_BVC("one"), LDAP_SCOPE_ONELEVEL },
 	{ BER_BVC("onelevel"), LDAP_SCOPE_ONELEVEL },	/* OpenLDAP extension */
-#ifdef LDAP_SCOPE_SUBORDINATE
 	{ BER_BVC("children"), LDAP_SCOPE_SUBORDINATE },
 	{ BER_BVC("subordinate"), LDAP_SCOPE_SUBORDINATE },
-#endif
 	{ BER_BVC("sub"), LDAP_SCOPE_SUBTREE },
 	{ BER_BVC("subtree"), LDAP_SCOPE_SUBTREE },	/* OpenLDAP extension */
 	{ BER_BVNULL, 0 }
@@ -2701,40 +2699,46 @@ static slap_verbmasks datamodes[] = {
 
 static int
 parse_syncrepl_line(
-	char		**cargv,
-	int		cargc,
-	syncinfo_t	*si
-)
+	ConfigArgs	*c,
+	syncinfo_t	*si )
 {
 	int	gots = 0;
 	int	i;
 	char	*val;
 
-	for ( i = 1; i < cargc; i++ ) {
-		if ( !strncasecmp( cargv[ i ], IDSTR "=",
+	for ( i = 1; i < c->argc; i++ ) {
+		if ( !strncasecmp( c->argv[ i ], IDSTR "=",
 					STRLENOF( IDSTR "=" ) ) )
 		{
 			int tmp;
 			/* '\0' string terminator accounts for '=' */
-			val = cargv[ i ] + STRLENOF( IDSTR "=" );
-			tmp= atoi( val );
+			val = c->argv[ i ] + STRLENOF( IDSTR "=" );
+			if ( lutil_atoi( &tmp, val ) != 0 ) {
+				snprintf( c->msg, sizeof( c->msg ),
+					"Error: parse_syncrepl_line: "
+					"unable to parse syncrepl id \"%s\"", val );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				return -1;
+			}
 			if ( tmp >= 1000 || tmp < 0 ) {
-				fprintf( stderr, "Error: parse_syncrepl_line: "
-					 "syncrepl id %d is out of range [0..999]\n", tmp );
+				snprintf( c->msg, sizeof( c->msg ),
+					"Error: parse_syncrepl_line: "
+					"syncrepl id %d is out of range [0..999]", tmp );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 				return -1;
 			}
 			si->si_rid = tmp;
 			gots |= GOT_ID;
-		} else if ( !strncasecmp( cargv[ i ], PROVIDERSTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], PROVIDERSTR "=",
 					STRLENOF( PROVIDERSTR "=" ) ) )
 		{
-			val = cargv[ i ] + STRLENOF( PROVIDERSTR "=" );
+			val = c->argv[ i ] + STRLENOF( PROVIDERSTR "=" );
 			ber_str2bv( val, 0, 1, &si->si_bindconf.sb_uri );
 			gots |= GOT_PROVIDER;
-		} else if ( !strncasecmp( cargv[ i ], SCHEMASTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], SCHEMASTR "=",
 					STRLENOF( SCHEMASTR "=" ) ) )
 		{
-			val = cargv[ i ] + STRLENOF( SCHEMASTR "=" );
+			val = c->argv[ i ] + STRLENOF( SCHEMASTR "=" );
 			if ( !strncasecmp( val, "on", STRLENOF( "on" ) )) {
 				si->si_schemachecking = 1;
 			} else if ( !strncasecmp( val, "off", STRLENOF( "off" ) ) ) {
@@ -2742,59 +2746,63 @@ parse_syncrepl_line(
 			} else {
 				si->si_schemachecking = 1;
 			}
-		} else if ( !strncasecmp( cargv[ i ], FILTERSTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], FILTERSTR "=",
 					STRLENOF( FILTERSTR "=" ) ) )
 		{
-			val = cargv[ i ] + STRLENOF( FILTERSTR "=" );
+			val = c->argv[ i ] + STRLENOF( FILTERSTR "=" );
 			if ( si->si_filterstr.bv_val )
 				ch_free( si->si_filterstr.bv_val );
 			ber_str2bv( val, 0, 1, &si->si_filterstr );
-		} else if ( !strncasecmp( cargv[ i ], LOGFILTERSTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], LOGFILTERSTR "=",
 					STRLENOF( LOGFILTERSTR "=" ) ) )
 		{
-			val = cargv[ i ] + STRLENOF( LOGFILTERSTR "=" );
+			val = c->argv[ i ] + STRLENOF( LOGFILTERSTR "=" );
 			if ( si->si_logfilterstr.bv_val )
 				ch_free( si->si_logfilterstr.bv_val );
 			ber_str2bv( val, 0, 1, &si->si_logfilterstr );
-		} else if ( !strncasecmp( cargv[ i ], SEARCHBASESTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], SEARCHBASESTR "=",
 					STRLENOF( SEARCHBASESTR "=" ) ) )
 		{
 			struct berval	bv;
 			int		rc;
 
-			val = cargv[ i ] + STRLENOF( SEARCHBASESTR "=" );
+			val = c->argv[ i ] + STRLENOF( SEARCHBASESTR "=" );
 			if ( si->si_base.bv_val ) {
 				ch_free( si->si_base.bv_val );
 			}
 			ber_str2bv( val, 0, 0, &bv );
 			rc = dnNormalize( 0, NULL, NULL, &bv, &si->si_base, NULL );
 			if ( rc != LDAP_SUCCESS ) {
-				fprintf( stderr, "Invalid base DN \"%s\": %d (%s)\n",
+				snprintf( c->msg, sizeof( c->msg ),
+					"Invalid base DN \"%s\": %d (%s)",
 					val, rc, ldap_err2string( rc ) );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 				return -1;
 			}
-		} else if ( !strncasecmp( cargv[ i ], LOGBASESTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], LOGBASESTR "=",
 					STRLENOF( LOGBASESTR "=" ) ) )
 		{
 			struct berval	bv;
 			int		rc;
 
-			val = cargv[ i ] + STRLENOF( LOGBASESTR "=" );
+			val = c->argv[ i ] + STRLENOF( LOGBASESTR "=" );
 			if ( si->si_logbase.bv_val ) {
 				ch_free( si->si_logbase.bv_val );
 			}
 			ber_str2bv( val, 0, 0, &bv );
 			rc = dnNormalize( 0, NULL, NULL, &bv, &si->si_logbase, NULL );
 			if ( rc != LDAP_SUCCESS ) {
-				fprintf( stderr, "Invalid logbase DN \"%s\": %d (%s)\n",
+				snprintf( c->msg, sizeof( c->msg ),
+					"Invalid logbase DN \"%s\": %d (%s)",
 					val, rc, ldap_err2string( rc ) );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 				return -1;
 			}
-		} else if ( !strncasecmp( cargv[ i ], SCOPESTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], SCOPESTR "=",
 					STRLENOF( SCOPESTR "=" ) ) )
 		{
 			int j;
-			val = cargv[ i ] + STRLENOF( SCOPESTR "=" );
+			val = c->argv[ i ] + STRLENOF( SCOPESTR "=" );
 			for ( j=0; !BER_BVISNULL(&scopes[j].key); j++ ) {
 				if (!strcasecmp( val, scopes[j].key.bv_val )) {
 					si->si_scope = scopes[j].val;
@@ -2802,18 +2810,20 @@ parse_syncrepl_line(
 				}
 			}
 			if ( BER_BVISNULL(&scopes[j].key) ) {
-				fprintf( stderr, "Error: parse_syncrepl_line: "
-					"unknown scope \"%s\"\n", val);
+				snprintf( c->msg, sizeof( c->msg ),
+					"Error: parse_syncrepl_line: "
+					"unknown scope \"%s\"", val);
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 				return -1;
 			}
-		} else if ( !strncasecmp( cargv[ i ], ATTRSONLYSTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], ATTRSONLYSTR "=",
 					STRLENOF( ATTRSONLYSTR "=" ) ) )
 		{
 			si->si_attrsonly = 1;
-		} else if ( !strncasecmp( cargv[ i ], ATTRSSTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], ATTRSSTR "=",
 					STRLENOF( ATTRSSTR "=" ) ) )
 		{
-			val = cargv[ i ] + STRLENOF( ATTRSSTR "=" );
+			val = c->argv[ i ] + STRLENOF( ATTRSSTR "=" );
 			if ( !strncasecmp( val, ":include:", STRLENOF(":include:") ) ) {
 				char *attr_fname;
 				attr_fname = ch_strdup( val + STRLENOF(":include:") );
@@ -2846,15 +2856,15 @@ parse_syncrepl_line(
 					return -1;
 				}
 			}
-		} else if ( !strncasecmp( cargv[ i ], EXATTRSSTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], EXATTRSSTR "=",
 					STRLENOF( EXATTRSSTR "=" ) ) )
 		{
-			val = cargv[ i ] + STRLENOF( EXATTRSSTR "=" );
+			val = c->argv[ i ] + STRLENOF( EXATTRSSTR "=" );
 			if ( !strncasecmp( val, ":include:", STRLENOF(":include:") )) {
 				char *attr_fname;
 				attr_fname = ch_strdup( val + STRLENOF(":include:") );
 				si->si_exanlist = file2anlist(
-									si->si_exanlist, attr_fname, " ,\t" );
+					si->si_exanlist, attr_fname, " ,\t" );
 				if ( si->si_exanlist == NULL ) {
 					ch_free( attr_fname );
 					return -1;
@@ -2866,85 +2876,98 @@ parse_syncrepl_line(
 					return -1;
 				}
 			}
-		} else if ( !strncasecmp( cargv[ i ], TYPESTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], TYPESTR "=",
 					STRLENOF( TYPESTR "=" ) ) )
 		{
-			val = cargv[ i ] + STRLENOF( TYPESTR "=" );
+			val = c->argv[ i ] + STRLENOF( TYPESTR "=" );
 			if ( !strncasecmp( val, "refreshOnly",
-						STRLENOF("refreshOnly") ))
+						STRLENOF("refreshOnly") ) )
 			{
 				si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_ONLY;
 			} else if ( !strncasecmp( val, "refreshAndPersist",
-						STRLENOF("refreshAndPersist") ))
+						STRLENOF("refreshAndPersist") ) )
 			{
 				si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_AND_PERSIST;
 				si->si_interval = 60;
 			} else {
-				fprintf( stderr, "Error: parse_syncrepl_line: "
-					"unknown sync type \"%s\"\n", val);
+				snprintf( c->msg, sizeof( c->msg ),
+					"Error: parse_syncrepl_line: "
+					"unknown sync type \"%s\"", val);
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 				return -1;
 			}
-		} else if ( !strncasecmp( cargv[ i ], INTERVALSTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], INTERVALSTR "=",
 					STRLENOF( INTERVALSTR "=" ) ) )
 		{
-			val = cargv[ i ] + STRLENOF( INTERVALSTR "=" );
+			val = c->argv[ i ] + STRLENOF( INTERVALSTR "=" );
 			if ( si->si_type == LDAP_SYNC_REFRESH_AND_PERSIST ) {
 				si->si_interval = 0;
-			} else {
-				char *hstr;
-				char *mstr;
-				char *dstr;
-				char *sstr;
-				int dd, hh, mm, ss;
-				dstr = val;
-				hstr = strchr( dstr, ':' );
-				if ( hstr == NULL ) {
-					fprintf( stderr, "Error: parse_syncrepl_line: "
-						"invalid interval \"%s\"\n", val );
+			} else if ( strchr( val, ':' ) != NULL ) {
+				char *next, *ptr = val;
+				unsigned dd, hh, mm, ss;
+				dd = strtoul( ptr, &next, 10 );
+				if ( next == ptr || next[0] != ':' ) {
+					snprintf( c->msg, sizeof( c->msg ),
+						"Error: parse_syncrepl_line: "
+						"invalid interval \"%s\", unable to parse days", val );
+					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 					return -1;
 				}
-				*hstr++ = '\0';
-				mstr = strchr( hstr, ':' );
-				if ( mstr == NULL ) {
-					fprintf( stderr, "Error: parse_syncrepl_line: "
-						"invalid interval \"%s\"\n", val );
+				ptr = next + 1;
+				hh = strtoul( ptr, &next, 10 );
+				if ( next == ptr || next[0] != ':' || hh > 24 ) {
+					snprintf( c->msg, sizeof( c->msg ),
+						"Error: parse_syncrepl_line: "
+						"invalid interval \"%s\", unable to parse hours", val );
+					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 					return -1;
 				}
-				*mstr++ = '\0';
-				sstr = strchr( mstr, ':' );
-				if ( sstr == NULL ) {
-					fprintf( stderr, "Error: parse_syncrepl_line: "
-						"invalid interval \"%s\"\n", val );
+				ptr = next + 1;
+				mm = strtoul( ptr, &next, 10 );
+				if ( next == ptr || next[0] != ':' || mm > 60 ) {
+					snprintf( c->msg, sizeof( c->msg ),
+						"Error: parse_syncrepl_line: "
+						"invalid interval \"%s\", unable to parse minutes", val );
+					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 					return -1;
 				}
-				*sstr++ = '\0';
-
-				dd = atoi( dstr );
-				hh = atoi( hstr );
-				mm = atoi( mstr );
-				ss = atoi( sstr );
-				if (( hh > 24 ) || ( hh < 0 ) ||
-					( mm > 60 ) || ( mm < 0 ) ||
-					( ss > 60 ) || ( ss < 0 ) || ( dd < 0 )) {
-					fprintf( stderr, "Error: parse_syncrepl_line: "
-						"invalid interval \"%s\"\n", val );
+				ptr = next + 1;
+				ss = strtoul( ptr, &next, 10 );
+				if ( next == ptr || next[0] != '\0' || ss > 60 ) {
+					snprintf( c->msg, sizeof( c->msg ),
+						"Error: parse_syncrepl_line: "
+						"invalid interval \"%s\", unable to parse seconds", val );
+					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 					return -1;
 				}
 				si->si_interval = (( dd * 24 + hh ) * 60 + mm ) * 60 + ss;
+			} else {
+				unsigned long	t;
+
+				if ( lutil_parse_time( val, &t ) != 0 ) {
+					snprintf( c->msg, sizeof( c->msg ),
+						"Error: parse_syncrepl_line: "
+						"invalid interval \"%s\"", val );
+					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+					return -1;
+				}
+				si->si_interval = (time_t)t;
 			}
 			if ( si->si_interval < 0 ) {
-				fprintf( stderr, "Error: parse_syncrepl_line: "
-					"invalid interval \"%ld\"\n",
+				snprintf( c->msg, sizeof( c->msg ),
+					"Error: parse_syncrepl_line: "
+					"invalid interval \"%ld\"",
 					(long) si->si_interval);
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 				return -1;
 			}
-		} else if ( !strncasecmp( cargv[ i ], RETRYSTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], RETRYSTR "=",
 					STRLENOF( RETRYSTR "=" ) ) )
 		{
 			char **retry_list;
 			int j, k, n;
 
-			val = cargv[ i ] + STRLENOF( RETRYSTR "=" );
+			val = c->argv[ i ] + STRLENOF( RETRYSTR "=" );
 			retry_list = (char **) ch_calloc( 1, sizeof( char * ));
 			retry_list[0] = NULL;
 
@@ -2953,27 +2976,51 @@ parse_syncrepl_line(
 			for ( k = 0; retry_list && retry_list[k]; k++ ) ;
 			n = k / 2;
 			if ( k % 2 ) {
-				fprintf( stderr,
-						"Error: incomplete syncrepl retry list\n" );
+				snprintf( c->msg, sizeof( c->msg ),
+					"Error: incomplete syncrepl retry list" );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 				for ( k = 0; retry_list && retry_list[k]; k++ ) {
 					ch_free( retry_list[k] );
 				}
 				ch_free( retry_list );
-				exit( EXIT_FAILURE );
+				return 1;
 			}
 			si->si_retryinterval = (time_t *) ch_calloc( n + 1, sizeof( time_t ));
 			si->si_retrynum = (int *) ch_calloc( n + 1, sizeof( int ));
 			si->si_retrynum_init = (int *) ch_calloc( n + 1, sizeof( int ));
 			for ( j = 0; j < n; j++ ) {
-				si->si_retryinterval[j] = atoi( retry_list[j*2] );
+				unsigned long	t;
+				if ( lutil_atoul( &t, retry_list[j*2] ) != 0 ) {
+					snprintf( c->msg, sizeof( c->msg ),
+						"Error: invalid retry interval \"%s\" (#%d)",
+						retry_list[j*2], j );
+					Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+					/* do some cleanup */
+					return 1;
+				}
+				si->si_retryinterval[j] = (time_t)t;
 				if ( *retry_list[j*2+1] == '+' ) {
 					si->si_retrynum_init[j] = -1;
 					si->si_retrynum[j] = -1;
 					j++;
 					break;
 				} else {
-					si->si_retrynum_init[j] = atoi( retry_list[j*2+1] );
-					si->si_retrynum[j] = atoi( retry_list[j*2+1] );
+					if ( lutil_atoi( &si->si_retrynum_init[j], retry_list[j*2+1] ) != 0 ) {
+						snprintf( c->msg, sizeof( c->msg ),
+							"Error: invalid initial retry number \"%s\" (#%d)",
+							retry_list[j*2+1], j );
+						Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+						/* do some cleanup */
+						return 1;
+					}
+					if ( lutil_atoi( &si->si_retrynum[j], retry_list[j*2+1] ) != 0 ) {
+						snprintf( c->msg, sizeof( c->msg ),
+							"Error: invalid retry number \"%s\" (#%d)",
+							retry_list[j*2+1], j );
+						Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+						/* do some cleanup */
+						return 1;
+					}
 				}
 			}
 			si->si_retrynum_init[j] = -2;
@@ -2984,36 +3031,59 @@ parse_syncrepl_line(
 				ch_free( retry_list[k] );
 			}
 			ch_free( retry_list );
-		} else if ( !strncasecmp( cargv[ i ], MANAGEDSAITSTR "=",
+		} else if ( !strncasecmp( c->argv[ i ], MANAGEDSAITSTR "=",
 					STRLENOF( MANAGEDSAITSTR "=" ) ) )
 		{
-			val = cargv[ i ] + STRLENOF( MANAGEDSAITSTR "=" );
-			si->si_manageDSAit = atoi( val );
-		} else if ( !strncasecmp( cargv[ i ], SLIMITSTR "=",
+			val = c->argv[ i ] + STRLENOF( MANAGEDSAITSTR "=" );
+			if ( lutil_atoi( &si->si_manageDSAit, val ) != 0
+				|| si->si_manageDSAit < 0 || si->si_manageDSAit > 1 )
+			{
+				snprintf( c->msg, sizeof( c->msg ),
+					"invalid manageDSAit value \"%s\".\n",
+					val );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				return 1;
+			}
+		} else if ( !strncasecmp( c->argv[ i ], SLIMITSTR "=",
 					STRLENOF( SLIMITSTR "=") ) )
 		{
-			val = cargv[ i ] + STRLENOF( SLIMITSTR "=" );
-			si->si_slimit = atoi( val );
-		} else if ( !strncasecmp( cargv[ i ], TLIMITSTR "=",
+			val = c->argv[ i ] + STRLENOF( SLIMITSTR "=" );
+			if ( lutil_atoi( &si->si_slimit, val ) != 0 ) {
+				snprintf( c->msg, sizeof( c->msg ),
+					"invalid size limit value \"%s\".\n",
+					val );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				return 1;
+			}
+		} else if ( !strncasecmp( c->argv[ i ], TLIMITSTR "=",
 					STRLENOF( TLIMITSTR "=" ) ) )
 		{
-			val = cargv[ i ] + STRLENOF( TLIMITSTR "=" );
-			si->si_tlimit = atoi( val );
-		} else if ( !strncasecmp( cargv[ i ], SYNCDATASTR "=",
+			val = c->argv[ i ] + STRLENOF( TLIMITSTR "=" );
+			if ( lutil_atoi( &si->si_tlimit, val ) != 0 ) {
+				snprintf( c->msg, sizeof( c->msg ),
+					"invalid time limit value \"%s\".\n",
+					val );
+				Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+				return 1;
+			}
+		} else if ( !strncasecmp( c->argv[ i ], SYNCDATASTR "=",
 					STRLENOF( SYNCDATASTR "=" ) ) )
 		{
-			val = cargv[ i ] + STRLENOF( SYNCDATASTR "=" );
+			val = c->argv[ i ] + STRLENOF( SYNCDATASTR "=" );
 			si->si_syncdata = verb_to_mask( val, datamodes );
-		} else if ( bindconf_parse( cargv[i], &si->si_bindconf )) {
-			fprintf( stderr, "Error: parse_syncrepl_line: "
-				"unknown keyword \"%s\"\n", cargv[ i ] );
+		} else if ( bindconf_parse( c->argv[i], &si->si_bindconf ) ) {
+			snprintf( c->msg, sizeof( c->msg ),
+				"Error: parse_syncrepl_line: "
+				"unknown keyword \"%s\"\n", c->argv[ i ] );
+			Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 			return -1;
 		}
 	}
 
 	if ( gots != GOT_ALL ) {
-		fprintf( stderr,
+		snprintf( c->msg, sizeof( c->msg ),
 			"Error: Malformed \"syncrepl\" line in slapd config file" );
+		Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
 		return -1;
 	}
 
@@ -3022,17 +3092,14 @@ parse_syncrepl_line(
 
 static int
 add_syncrepl(
-	Backend *be,
-	char    **cargv,
-	int     cargc
-)
+	ConfigArgs *c )
 {
 	syncinfo_t *si;
 	int	rc = 0;
 
-	if ( !( be->be_search && be->be_add && be->be_modify && be->be_delete )) {
-		Debug( LDAP_DEBUG_ANY, "database %s does not support operations "
-			"required for syncrepl\n", be->be_type, 0, 0 );
+	if ( !( c->be->be_search && c->be->be_add && c->be->be_modify && c->be->be_delete ) ) {
+		Debug( LDAP_DEBUG_ANY, "%s: database %s does not support operations "
+			"required for syncrepl\n", c->log, c->be->be_type, 0 );
 		return 1;
 	}
 	si = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) );
@@ -3070,13 +3137,13 @@ add_syncrepl(
 	LDAP_LIST_INIT( &si->si_nonpresentlist );
 	ldap_pvt_thread_mutex_init( &si->si_mutex );
 
-	rc = parse_syncrepl_line( cargv, cargc, si );
+	rc = parse_syncrepl_line( c, si );
 
 	if ( rc == 0 ) {
-		si->si_be = be;
+		si->si_be = c->be;
 		init_syncrepl( si );
 		si->si_re = ldap_pvt_runqueue_insert( &slapd_rq, si->si_interval,
-			do_syncrepl, si, "do_syncrepl", be->be_suffix[0].bv_val );
+			do_syncrepl, si, "do_syncrepl", c->be->be_suffix[0].bv_val );
 		if ( !si->si_re )
 			rc = -1;
 	}
@@ -3090,9 +3157,9 @@ add_syncrepl(
 			BER_BVISNULL( &si->si_bindconf.sb_uri ) ?
 			"(null)" : si->si_bindconf.sb_uri.bv_val, 0, 0 );
 		if ( !si->si_schemachecking ) {
-			SLAP_DBFLAGS(be) |= SLAP_DBFLAG_NO_SCHEMA_CHECK;
+			SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_NO_SCHEMA_CHECK;
 		}
-		be->be_syncinfo = si;
+		c->be->be_syncinfo = si;
 		return 0;
 	}
 }
@@ -3226,7 +3293,8 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv )
 }
 
 int
-syncrepl_config(ConfigArgs *c) {
+syncrepl_config( ConfigArgs *c )
+{
 	if (c->op == SLAP_CONFIG_EMIT) {
 		if ( c->be->be_syncinfo ) {
 			struct berval bv;
@@ -3241,24 +3309,23 @@ syncrepl_config(ConfigArgs *c) {
 		if ( c->be->be_syncinfo ) {
 			re = c->be->be_syncinfo->si_re;
 			if ( re ) {
-				if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ))
+				if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) )
 					ldap_pvt_runqueue_stoptask( &slapd_rq, re );
 				ldap_pvt_runqueue_remove( &slapd_rq, re );
 			}
 			syncinfo_free( c->be->be_syncinfo );
 			c->be->be_syncinfo = NULL;
 		}
-		SLAP_DBFLAGS(c->be) &= ~(SLAP_DBFLAG_SHADOW|SLAP_DBFLAG_SYNC_SHADOW);
+		SLAP_DBFLAGS( c->be ) &= ~(SLAP_DBFLAG_SHADOW|SLAP_DBFLAG_SYNC_SHADOW);
 		return 0;
 	}
-	if(SLAP_SHADOW(c->be)) {
+	if ( SLAP_SHADOW( c->be ) ) {
 		Debug(LDAP_DEBUG_ANY, "%s: "
 			"syncrepl: database already shadowed.\n",
 			c->log, 0, 0);
 		return(1);
-	} else if(add_syncrepl(c->be, c->argv, c->argc)) {
+	} else if ( add_syncrepl( c ) ) {
 		return(1);
 	}
-	SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SYNC_SHADOW);
-	return(0);
+	return config_sync_shadow( c );
 }
diff --git a/servers/slapd/user.c b/servers/slapd/user.c
index 29aa25b4298e9f2f5fd05610e4f390c3f00da87c..7143802f3172ce781914842bcef77fdda12f33eb 100644
--- a/servers/slapd/user.c
+++ b/servers/slapd/user.c
@@ -34,6 +34,7 @@
 #include <ac/unistd.h>
 
 #include "slap.h"
+#include "lutil.h"
 
 /*
  * Set real and effective user id and group id, and group access list
@@ -49,9 +50,17 @@ slap_init_user( char *user, char *group )
 
     if ( user ) {
 	struct passwd *pwd;
-	if ( isdigit( (unsigned char) *user )) {
+	if ( isdigit( (unsigned char) *user ) ) {
+	    unsigned u;
+
 	    got_uid = 1;
-	    uid = atoi( user );
+	    if ( lutil_atou( &u, user ) != 0 ) {
+		Debug( LDAP_DEBUG_ANY, "Unble to parse user %s\n",
+		       user, 0, 0 );
+
+		exit( EXIT_FAILURE );
+	    }
+	    uid = (uid_t)u;
 #ifdef HAVE_GETPWUID
 	    pwd = getpwuid( uid );
 	    goto did_getpw;
@@ -86,7 +95,15 @@ slap_init_user( char *user, char *group )
     if ( group ) {
 	struct group *grp;
 	if ( isdigit( (unsigned char) *group )) {
-	    gid = atoi( group );
+	    unsigned g;
+
+	    if ( lutil_atou( &g, group ) != 0 ) {
+		Debug( LDAP_DEBUG_ANY, "Unble to parse group %s\n",
+		       group, 0, 0 );
+
+		exit( EXIT_FAILURE );
+	    }
+	    gid = (uid_t)g;
 #ifdef HAVE_GETGRGID
 	    grp = getgrgid( gid );
 	    goto did_group;
diff --git a/servers/slapd/value.c b/servers/slapd/value.c
index cf2d73075e8b16c4cc4039f46a1252502d938d67..2a544c050c0bcaba7538c50e94973d0610ce8f93 100644
--- a/servers/slapd/value.c
+++ b/servers/slapd/value.c
@@ -700,7 +700,7 @@ ordered_value_add(
 
 		k = -1;
 		if ( vals[i].bv_val[0] == '{' ) {
-			k = strtol( vals[i].bv_val+1, &next, 0 );
+			k = strtol( vals[i].bv_val + 1, &next, 0 );
 			if ( next == vals[i].bv_val + 1 ||
 				next[ 0 ] != '}' ||
 				next - vals[i].bv_val > vals[i].bv_len )
diff --git a/tests/data/meta.out b/tests/data/meta.out
index 97b9ed4f067a68677e8619efb1ea05bd94166254..4826865aa71d075cdf188ce3e1c9de9b8e2809a1 100644
--- a/tests/data/meta.out
+++ b/tests/data/meta.out
@@ -429,6 +429,27 @@ telephoneNumber: +1 313 555 5331
 
 # refldap://localhost:9016/cn=Somewhere,ou=Meta,dc=example,dc=com??sub
 
+# searching base="ou=Meta,o=Example,c=US"...
+dn: cn=Dan Aykroyd,ou=Meta,o=Example,c=US
+objectClass: inetOrgPerson
+cn: Dan Aykroyd
+sn: Aykroyd
+userPassword:: ZWx3b29k
+description: Elwood Blues
+
+dn: cn=John Belushi,ou=Meta,o=Example,c=US
+objectClass: inetOrgPerson
+cn: John Belushi
+sn: Belushi
+userPassword:: amFjaw==
+description: Joliet Jack Blues
+
+dn: ou=Meta,o=Example,c=US
+objectClass: organizationalUnit
+ou: Meta
+
+# refldap://localhost:9016/cn=Somewhere,ou=Meta,dc=example,dc=com??sub
+
 # searching base="o=Example,c=US"...
 dn: cn=Added Group,ou=Groups,o=Example,c=US
 objectClass: groupOfNames
diff --git a/tests/data/proxycache.out b/tests/data/proxycache.out
index c2e2337e85c03e96b25bb68fd10391a9691e5fb9..b52e6e3c4dcb89cf2b2dd65df23b1ee872343c95 100644
--- a/tests/data/proxycache.out
+++ b/tests/data/proxycache.out
@@ -1,3 +1,5 @@
+# Query 1: filter:(sn=Jon) attrs: all
+# Query 2: filter:(|(cn=*Jon*)(sn=Jon*)) attrs:cn sn title uid
 dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
 cn: James A Jones 1
 cn: James Jones
@@ -8,7 +10,6 @@ title: Mad Cow Researcher, UM Alumni Association
 
 dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=example
  ,dc=com
-objectClass: OpenLDAPperson
 cn: James A Jones 2
 cn: James Jones
 cn: Jim Jones
@@ -17,13 +18,13 @@ uid: jjones
 title: Senior Manager, Information Technology Division
 
 dn: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc=com
-objectClass: OpenLDAPperson
 cn: John Doe
 cn: Jonathon Doe
 sn: Doe
 uid: johnd
 title: System Administrator, Information Technology Division
 
+# Query 3: filter:(sn=Smith*) attrs:cn sn title uid
 dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
 cn: Jennifer Smith
 cn: Jen Smith
@@ -31,6 +32,7 @@ sn: Smith
 uid: jen
 title: Telemarketer, UM Alumni Association
 
+# Query 4: filter:(sn=Doe*) attrs:cn sn title uid
 dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=example
  ,dc=com
 cn: James A Jones 2
@@ -41,7 +43,6 @@ uid: jjones
 title: Senior Manager, Information Technology Division
 
 dn: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
-objectClass: OpenLDAPperson
 cn: Jane Doe
 cn: Jane Alverson
 sn: Doe
@@ -49,13 +50,13 @@ uid: jdoe
 title: Programmer Analyst, UM Alumni Association
 
 dn: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc=com
-objectClass: OpenLDAPperson
 cn: John Doe
 cn: Jonathon Doe
 sn: Doe
 uid: johnd
 title: System Administrator, Information Technology Division
 
+# Query 5: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid
 dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc
  =com
 cn: Bjorn Jensen
@@ -65,6 +66,7 @@ postalAddress: Info Tech Division $ 535 W. William St. $ Anytown, MI 48103
 mail: bjorn@mailgw.example.com
 telephoneNumber: +1 313 555 0355
 
+# Query 6: filter:(mail=*@mail.alumni.example.com) cn sn title uid
 dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
 cn: Dorothy Stevens
 cn: Dot Stevens
@@ -73,41 +75,34 @@ uid: dots
 title: Secretary, UM Alumni Association
 
 dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
-objectClass: OpenLDAPperson
 cn: James A Jones 1
 cn: James Jones
 cn: Jim Jones
 sn: Jones
 uid: jaj
 title: Mad Cow Researcher, UM Alumni Association
-mail: jaj@mail.alumni.example.com
 
 dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
-objectClass: OpenLDAPperson
 cn: Jennifer Smith
 cn: Jen Smith
 sn: Smith
 uid: jen
 title: Telemarketer, UM Alumni Association
-mail: jen@mail.alumni.example.com
 
 dn: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
-objectClass: OpenLDAPperson
 cn: Mark Elliot
 cn: Mark A Elliot
 sn: Elliot
 uid: melliot
 title: Director, UM Alumni Association
-mail: melliot@mail.alumni.example.com
 
 dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
-objectClass: OpenLDAPperson
 cn: Ursula Hampster
 sn: Hampster
 uid: uham
 title: Secretary, UM Alumni Association
-mail: uham@mail.alumni.example.com
 
+# Query 7: filter:(mail=*) cn sn title uid
 dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
  dc=com
 cn: Barbara Jensen
@@ -182,6 +177,7 @@ sn: Hampster
 uid: uham
 title: Secretary, UM Alumni Association
 
+# Query 8: filter:(|(cn=*Jones)(sn=Jones)) attrs:cn sn title uid
 dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
 cn: James A Jones 1
 cn: James Jones
@@ -199,6 +195,7 @@ sn: Doe
 uid: jjones
 title: Senior Manager, Information Technology Division
 
+# Query 9: filter:(sn=Smith) attrs:cn sn title uid
 dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
 cn: Jennifer Smith
 cn: Jen Smith
@@ -206,6 +203,7 @@ sn: Smith
 uid: jen
 title: Telemarketer, UM Alumni Association
 
+# Query 10: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid
 dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc
  =com
 cn: Bjorn Jensen
@@ -215,6 +213,7 @@ postalAddress: Info Tech Division $ 535 W. William St. $ Anytown, MI 48103
 mail: bjorn@mailgw.example.com
 telephoneNumber: +1 313 555 0355
 
+# Query 11: filter:(mail=jaj@mail.alumni.example.com) cn sn title uid
 dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
 cn: James A Jones 1
 cn: James Jones
diff --git a/tests/data/slapd-chain1.conf b/tests/data/slapd-chain1.conf
index 8f3554718b1696259d2b506f9caf81604f47f981..0ca328c3113fe53d1fef7324e65aaa25c989f171 100644
--- a/tests/data/slapd-chain1.conf
+++ b/tests/data/slapd-chain1.conf
@@ -33,9 +33,11 @@ argsfile	@TESTDIR@/slapd.1.args
 # uses the chain overlay as global;
 # no chain-URI is configured, so the URI is parsed out of the referral
 overlay         chain
-chain-acl-bind	bindmethod=simple
-		binddn="cn=Manager,dc=example,dc=com"
-		credentials=secret
+chain-uri	@URI2@
+chain-idassert-bind	bindmethod=simple
+			binddn="cn=Manager,dc=example,dc=com"
+			credentials=secret
+			mode=self
 
 #######################################################################
 # database definitions
diff --git a/tests/data/slapd-chain2.conf b/tests/data/slapd-chain2.conf
index acc434ba55a6b5d8426073d582ae04b6a0e9f3ae..b7abea1da35437fd1bf2ac6c17c4255184eec1d3 100644
--- a/tests/data/slapd-chain2.conf
+++ b/tests/data/slapd-chain2.conf
@@ -56,8 +56,9 @@ rootpw		secret
 # the chain-URI is configured, so only that URI is chained
 overlay		chain
 chain-uri	@URI1@
-chain-acl-bind	bindmethod=simple
-		binddn="cn=Manager,dc=example,dc=com"
-		credentials=secret
+chain-idassert-bind	bindmethod=simple
+			binddn="cn=Manager,dc=example,dc=com"
+			credentials=secret
+			mode=self
 
 #monitor#database	monitor
diff --git a/tests/data/slapd-unique.conf b/tests/data/slapd-unique.conf
index 8e069516e47023946b35d1a7e1da7acf463cc221..f2898b3ac9263765bf7a85c98adf5a0fb959e2d2 100644
--- a/tests/data/slapd-unique.conf
+++ b/tests/data/slapd-unique.conf
@@ -48,6 +48,6 @@ rootpw		secret
 
 overlay			unique
 unique_ignore		o cn sn ou objectClass
-unique_attributes	employeeNumber
+unique_attributes	employeeNumber displayName
 
 #monitor#database	monitor
diff --git a/tests/progs/slapd-addel.c b/tests/progs/slapd-addel.c
index 8acd88a810cc3f43eda130e59b82125a139e0650..07c0d175f02bc251b2210bfbda2ba4cfe168698a 100644
--- a/tests/progs/slapd-addel.c
+++ b/tests/progs/slapd-addel.c
@@ -32,6 +32,7 @@
 
 #define LDAP_DEPRECATED 1
 #include <ldap.h>
+#include <lutil.h>
 
 #define LOOPS	100
 #define RETRIES	0
@@ -93,7 +94,9 @@ main( int argc, char **argv )
 			break;
 
 		case 'p':		/* the servers port */
-			port = atoi( optarg );
+			if ( lutil_atoi( &port, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 'D':		/* the servers manager */
@@ -109,15 +112,21 @@ main( int argc, char **argv )
 			break;
 
 		case 'l':		/* the number of loops */
-			loops = atoi( optarg );
+			if ( lutil_atoi( &loops, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 'r':		/* number of retries */
-			retries = atoi( optarg );
+			if ( lutil_atoi( &retries, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 't':		/* delay in seconds */
-			delay = atoi( optarg );
+			if ( lutil_atoi( &delay, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		default:
diff --git a/tests/progs/slapd-bind.c b/tests/progs/slapd-bind.c
index 25175590f8ab8841fb6f25d7d25eceff965158d0..be604834a2bab6284d8b9b0389c75e80108b1191 100644
--- a/tests/progs/slapd-bind.c
+++ b/tests/progs/slapd-bind.c
@@ -90,7 +90,9 @@ main( int argc, char **argv )
 			break;
 
 			case 'p':		/* the servers port */
-				port = atoi( optarg );
+				if ( lutil_atoi( &port, optarg ) != 0 ) {
+					usage( argv[0] );
+				}
 				break;
 
 			case 'D':
@@ -102,7 +104,9 @@ main( int argc, char **argv )
 				break;
 
 			case 'l':		/* the number of loops */
-				loops = atoi( optarg );
+				if ( lutil_atoi( &loops, optarg ) != 0 ) {
+					usage( argv[0] );
+				}
 				break;
 
 			case 'f':
diff --git a/tests/progs/slapd-modify.c b/tests/progs/slapd-modify.c
index 727f1c741e43a7d5eb7e9c35d1499f03856fbfe2..cfda8b67e37d02ab7fb0409233fa2fce3bd5e66a 100644
--- a/tests/progs/slapd-modify.c
+++ b/tests/progs/slapd-modify.c
@@ -28,6 +28,7 @@
 
 #define LDAP_DEPRECATED 1
 #include <ldap.h>
+#include <lutil.h>
 
 #define LOOPS	100
 #define RETRIES 0
@@ -87,7 +88,9 @@ main( int argc, char **argv )
 			break;
 
 		case 'p':		/* the servers port */
-			port = atoi( optarg );
+			if ( lutil_atoi( &port, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 'D':		/* the servers manager */
@@ -107,15 +110,21 @@ main( int argc, char **argv )
 			break;
 
 		case 'l':		/* the number of loops */
-			loops = atoi( optarg );
+			if ( lutil_atoi( &loops, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 'r':		/* number of retries */
-			retries = atoi( optarg );
+			if ( lutil_atoi( &retries, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 't':		/* delay in seconds */
-			delay = atoi( optarg );
+			if ( lutil_atoi( &delay, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		default:
diff --git a/tests/progs/slapd-modrdn.c b/tests/progs/slapd-modrdn.c
index d6c5f9257f01e4ba8a003a37f1d10f7584993858..908d1892517457cd32bb7b174629f51a7a8fa142 100644
--- a/tests/progs/slapd-modrdn.c
+++ b/tests/progs/slapd-modrdn.c
@@ -32,6 +32,7 @@
 
 #define LDAP_DEPRECATED 1
 #include <ldap.h>
+#include <lutil.h>
 
 #define LOOPS	100
 #define RETRIES	0
@@ -88,7 +89,9 @@ main( int argc, char **argv )
 			break;
 
 		case 'p':		/* the servers port */
-			port = atoi( optarg );
+			if ( lutil_atoi( &port, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 'D':		/* the servers manager */
@@ -104,15 +107,21 @@ main( int argc, char **argv )
 			break;
 
 		case 'l':		/* the number of loops */
-			loops = atoi( optarg );
+			if ( lutil_atoi( &loops, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 'r':		/* the number of retries */
-			retries = atoi( optarg );
+			if ( lutil_atoi( &retries, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 't':		/* delay in seconds */
-			delay = atoi( optarg );
+			if ( lutil_atoi( &delay, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		default:
diff --git a/tests/progs/slapd-read.c b/tests/progs/slapd-read.c
index c5cb56ce33bd87d9ece5e3acdaa198eeb4a141f2..b70ace580f0bcd578bca3ae28a2e935b1349fbc7 100644
--- a/tests/progs/slapd-read.c
+++ b/tests/progs/slapd-read.c
@@ -32,6 +32,7 @@
 
 #define LDAP_DEPRECATED 1
 #include <ldap.h>
+#include <lutil.h>
 
 #define LOOPS	100
 #define RETRIES	0
@@ -77,7 +78,9 @@ main( int argc, char **argv )
 			break;
 
 		case 'p':		/* the servers port */
-			port = atoi( optarg );
+			if ( lutil_atoi( &port, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 'e':		/* DN to search for */
@@ -85,15 +88,21 @@ main( int argc, char **argv )
 			break;
 
 		case 'l':		/* the number of loops */
-			loops = atoi( optarg );
+			if ( lutil_atoi( &loops, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 'r':		/* the number of retries */
-			retries = atoi( optarg );
+			if ( lutil_atoi( &retries, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 't':		/* delay in seconds */
-			delay = atoi( optarg );
+			if ( lutil_atoi( &delay, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		default:
diff --git a/tests/progs/slapd-search.c b/tests/progs/slapd-search.c
index 9d9afe1e4fd39b144c1484fd72eca9066edbc585..0f3c1e63a006a51172ae4031ac83742da8e6728d 100644
--- a/tests/progs/slapd-search.c
+++ b/tests/progs/slapd-search.c
@@ -32,6 +32,7 @@
 
 #define LDAP_DEPRECATED 1
 #include <ldap.h>
+#include <lutil.h>
 
 #define LOOPS	100
 #define RETRIES	0
@@ -83,7 +84,9 @@ main( int argc, char **argv )
 			break;
 
 		case 'p':		/* the servers port */
-			port = atoi( optarg );
+			if ( lutil_atoi( &port, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 'D':		/* the servers manager */
@@ -103,15 +106,21 @@ main( int argc, char **argv )
 			break;
 
 		case 'l':		/* number of loops */
-			loops = atoi( optarg );
+			if ( lutil_atoi( &loops, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 'r':		/* number of retries */
-			retries = atoi( optarg );
+			if ( lutil_atoi( &retries, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 't':		/* delay in seconds */
-			delay = atoi( optarg );
+			if ( lutil_atoi( &delay, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		default:
diff --git a/tests/progs/slapd-tester.c b/tests/progs/slapd-tester.c
index e49947198b51ad57de3bee0af1b31a5ee680cc95..8cf65ef9e732a6a7dde6f0ba9cf2b21356541262 100644
--- a/tests/progs/slapd-tester.c
+++ b/tests/progs/slapd-tester.c
@@ -33,6 +33,7 @@
 
 
 #include "ldap_defaults.h"
+#include "lutil.h"
 
 
 #define SEARCHCMD		"slapd-search"
@@ -159,7 +160,9 @@ main( int argc, char **argv )
 			break;
 
 		case 'j':		/* the number of parallel clients */
-			maxkids = atoi( optarg );
+			if ( lutil_atoi( &maxkids, optarg ) != 0 ) {
+				usage( argv[0] );
+			}
 			break;
 
 		case 'l':		/* the number of loops per client */
diff --git a/tests/run.in b/tests/run.in
index f044bce5a2d82c2ad47d7639982326740a595b30..1becdae104f74dfe89ddd7c9ac68e031e04c086a 100644
--- a/tests/run.in
+++ b/tests/run.in
@@ -35,6 +35,7 @@ AC_sql=sql@BUILD_SQL@
 
 # overlays
 AC_accesslog=accesslog@BUILD_ACCESSLOG@
+AC_dynlist=dynlist@BUILD_DYNLIST@
 AC_pcache=pcache@BUILD_PROXYCACHE@
 AC_ppolicy=ppolicy@BUILD_PPOLICY@
 AC_refint=refint@BUILD_REFINT@
@@ -52,9 +53,9 @@ AC_WITH_MODULES_ENABLED=@WITH_MODULES_ENABLED@
 AC_ACI_ENABLED=aci@WITH_ACI_ENABLED@
 
 export AC_bdb AC_hdb AC_ldap AC_ldbm AC_meta AC_monitor AC_relay AC_sql 
-export AC_pcache AC_ppolicy AC_refint AC_retcode AC_rwm AC_unique AC_syncprov
-export AC_translucent AC_WITH_SASL AC_WITH_TLS AC_WITH_MODULES_ENABLED AC_ACI_ENABLED
-export AC_valsort AC_accesslog
+export AC_accesslog AC_dynlist AC_pcache AC_ppolicy AC_refint AC_retcode
+export AC_rwm AC_unique AC_syncprov AC_translucent AC_valsort
+export AC_WITH_SASL AC_WITH_TLS AC_WITH_MODULES_ENABLED AC_ACI_ENABLED
 
 if test ! -x ../servers/slapd/slapd ; then
 	echo "Could not locate slapd(8)"
diff --git a/tests/scripts/conf.sh b/tests/scripts/conf.sh
index 2491091f4da04b6ba066768f74cca8a28771e0f7..4b2a675951b45a6b98006f1fa5fac2e76332096c 100755
--- a/tests/scripts/conf.sh
+++ b/tests/scripts/conf.sh
@@ -42,6 +42,7 @@ sed -e "s/@BACKEND@/${BACKEND}/"			\
 	-e "s/^#${AC_sql}#//"				\
 		-e "s/^#${RDBMS}#//"			\
 	-e "s/^#${AC_accesslog}#//"			\
+	-e "s/^#${AC_dynlist}#//"			\
 	-e "s/^#${AC_pcache}#//"			\
 	-e "s/^#${AC_ppolicy}#//"			\
 	-e "s/^#${AC_refint}#//"			\
diff --git a/tests/scripts/test004-modify b/tests/scripts/test004-modify
index 649fde2c5afd0f13bb9debacd8504baa85b006c8..de2952569c36e58b7660829807f70d3cec40c920 100755
--- a/tests/scripts/test004-modify
+++ b/tests/scripts/test004-modify
@@ -165,6 +165,10 @@ uidNumber: 1
 increment: gidNumber
 gidNumber: -1
 
+dn: dc=example,dc=com
+changetype: modify
+# EMPTY SEQUENCE OF CHANGE
+
 EOMODS
 
 RC=$?
@@ -174,6 +178,31 @@ if test $RC != 0 ; then
 	exit $RC
 fi
 
+echo "Using ldapmodify to add an empty entry (should fail with protocolError)..."
+$LDAPMODIFY -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
+	 >> $TESTOUT 2>&1 << EOMODS
+dn: cn=Foo Bar,dc=example,dc=com
+changetype: add
+# EMPTY SEQUENCE OF ATTRS
+EOMODS
+
+RC=$?
+case $RC in
+2)
+	echo "	ldapmodify failed ($RC)"
+	;;
+0)
+	echo "	ldapmodify should have failed ($RC)!"
+	test $KILLSERVERS != no && kill -HUP $KILLPIDS
+	exit -1
+	;;
+*)
+	echo "	ldapmodify failed ($RC)!"
+	test $KILLSERVERS != no && kill -HUP $KILLPIDS
+	exit $RC
+	;;
+esac
+
 echo "Using ldapsearch to retrieve all the entries..."
 $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
 	    'objectClass=*' > $SEARCHOUT 2>&1
diff --git a/tests/scripts/test020-proxycache b/tests/scripts/test020-proxycache
index 0fc9f8b719b8cdbabf5bedb2fbafe802b1853324..c6ec3db525b28933128a0edc797a9d6b8e3f7d70 100755
--- a/tests/scripts/test020-proxycache
+++ b/tests/scripts/test020-proxycache
@@ -13,7 +13,7 @@
 ## top-level directory of the distribution or, alternatively, at
 ## <http://www.OpenLDAP.org/license.html>.
 
-CACHETTL=60
+CACHETTL="1m"
 CACHE_ENTRY_LIMIT=10
 
 . $SRCDIR/scripts/defines.sh
@@ -114,10 +114,13 @@ if test $RC != 0 ; then
 	exit $RC
 fi
 
+cat /dev/null > $SLAVEOUT
+
 echo "Making queries on the proxy cache..." 
 echo "Query 1: filter:(sn=Jon) attrs: all" 
+echo "# Query 1: filter:(sn=Jon) attrs: all" >> $SLAVEOUT
 $LDAPSEARCH -x -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
-	'sn=Jon' > $SLAVEOUT 2>&1
+	'sn=Jon' >> $SLAVEOUT 2>&1
 RC=$?
 if test $RC != 0 ; then
 	echo "ldapsearch failed ($RC)!"
@@ -126,6 +129,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Query 2: filter:(|(cn=*Jon*)(sn=Jon*)) attrs:cn sn title uid"  
+echo "# Query 2: filter:(|(cn=*Jon*)(sn=Jon*)) attrs:cn sn title uid" >> $SLAVEOUT
 $LDAPSEARCH -x -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
 	'(|(cn=*Jon*)(sn=Jon*))' cn sn title uid >> $SLAVEOUT 2>&1
 RC=$?
@@ -136,6 +140,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Query 3: filter:(sn=Smith*) attrs:cn sn title uid"  
+echo "# Query 3: filter:(sn=Smith*) attrs:cn sn title uid" >> $SLAVEOUT
 $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
 	'sn=Smith*' cn sn title uid >> $SLAVEOUT 2>&1
 RC=$?
@@ -146,6 +151,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Query 4: filter:(sn=Doe*) attrs:cn sn title uid"  
+echo "# Query 4: filter:(sn=Doe*) attrs:cn sn title uid" >> $SLAVEOUT
 $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
 	'sn=Doe' cn sn title uid >> $SLAVEOUT 2>&1
 RC=$?
@@ -156,6 +162,7 @@ if test $RC != 0 ; then
 fi
  
 echo "Query 5: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid"  
+echo "# Query 5: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid" >> $SLAVEOUT
 $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
 	'uid=bjorn' mail postaladdress telephonenumber cn uid >> $SLAVEOUT 2>&1
 RC=$?
@@ -166,6 +173,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Query 6: filter:(mail=*@mail.alumni.example.com) cn sn title uid"  
+echo "# Query 6: filter:(mail=*@mail.alumni.example.com) cn sn title uid" >> $SLAVEOUT
 $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
 	'mail=*@mail.alumni.example.com' cn sn title uid >> $SLAVEOUT 2>&1
 RC=$?
@@ -176,6 +184,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Query 7: filter:(mail=*) cn sn title uid"  
+echo "# Query 7: filter:(mail=*) cn sn title uid" >> $SLAVEOUT
 $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
 	'mail=*' cn sn title uid >> $SLAVEOUT 2>&1
 RC=$?
@@ -209,6 +218,7 @@ else
 fi
 
 echo "Query 8: filter:(|(cn=*Jones)(sn=Jones)) attrs:cn sn title uid"  
+echo "# Query 8: filter:(|(cn=*Jones)(sn=Jones)) attrs:cn sn title uid" >> $SLAVEOUT
 $LDAPSEARCH -x -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
 	'(|(cn=*Jones)(sn=Jones))' cn sn title uid >> $SLAVEOUT 2>&1
 RC=$?
@@ -219,6 +229,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Query 9: filter:(sn=Smith) attrs:cn sn title uid"  
+echo "# Query 9: filter:(sn=Smith) attrs:cn sn title uid" >> $SLAVEOUT
 $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
 	'sn=Smith' cn sn title uid >> $SLAVEOUT 2>&1
 RC=$?
@@ -229,6 +240,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Query 10: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid"  
+echo "# Query 10: filter:(uid=bjorn) attrs:mail postaladdress telephonenumber cn uid" >> $SLAVEOUT
 $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
 	'uid=bjorn' mail postaladdress telephonenumber cn uid >> $SLAVEOUT 2>&1
 RC=$?
@@ -239,6 +251,7 @@ if test $RC != 0 ; then
 fi
 
 echo "Query 11: filter:(mail=jaj@mail.alumni.example.com) cn sn title uid"  
+echo "# Query 11: filter:(mail=jaj@mail.alumni.example.com) cn sn title uid" >> $SLAVEOUT
 $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT2 \
 	'mail=jaj@mail.alumni.example.com' cn sn title uid >> $SLAVEOUT 2>&1
 RC=$?
@@ -279,8 +292,10 @@ fi
 
 echo "Filtering ldapsearch results..."
 . $LDIFFILTER < $SLAVEOUT > $SEARCHFLT
+echo "Filtering original ldif..."
+. $LDIFFILTER < $PROXYCACHEOUT > $LDIFFLT
 echo "Comparing filter output..."
-$CMP $SEARCHFLT $PROXYCACHEOUT > $CMPOUT
+$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
 
 if test $? != 0 ; then
 	echo "Comparison failed"
diff --git a/tests/scripts/test024-unique b/tests/scripts/test024-unique
index d14d6222bb3408cb912b76e6fcfa9ff3f33db14b..72ff91a94c59c40babd9607894897060be10f653 100755
--- a/tests/scripts/test024-unique
+++ b/tests/scripts/test024-unique
@@ -75,7 +75,9 @@ cn: dave
 businessCategory: otest
 carLicense: TEST
 departmentNumber: 42
-displayName: Dave
+# NOTE: use special chars in attr value to be used
+# in internal searches ITS#4212
+displayName: Dave (ITS#4212)
 employeeNumber: 69
 employeeType: contractor
 givenName: Dave
diff --git a/tests/scripts/test035-meta b/tests/scripts/test035-meta
index 6a2c2d2b2a533ab092ef12c9acddd5d21f5f50a3..f66d5cc984c00651a86600fe9aa2e3a8bd5142bf 100755
--- a/tests/scripts/test035-meta
+++ b/tests/scripts/test035-meta
@@ -161,6 +161,33 @@ case $RC in
 	;;
 esac
 
+# ITS#4195: spurious matchedDN when the search scopes the main target,
+# and the searchBase is not present, so that target returns noSuchObject
+BASEDN="ou=Meta,o=Example,c=US"
+echo "Searching base=\"$BASEDN\"..."
+echo "# searching base=\"$BASEDN\"..." >> $SEARCHOUT
+$LDAPSEARCH -S "" -h $LOCALHOST -p $PORT3 -b "$BASEDN" >> $SEARCHOUT 2>&1
+RC=$?
+#if test $RC != 0 ; then
+#	echo "Search failed ($RC)!"
+#	test $KILLSERVERS != no && kill -HUP $KILLPIDS
+#	exit $RC
+#fi
+case $RC in 
+	0)
+	;;
+	51)
+		echo "### Hit LDAP_BUSY problem; you may want to re-run the test"
+		test $KILLSERVERS != no && kill -HUP $KILLPIDS
+		exit 0
+	;;
+	*)
+		echo "Search failed ($RC)!"
+		test $KILLSERVERS != no && kill -HUP $KILLPIDS
+		exit $RC
+	;;
+esac
+
 #
 # Do some modifications
 #
diff --git a/tests/scripts/test043-delta-syncrepl b/tests/scripts/test043-delta-syncrepl
index edff472b219653194d4ca97e2dcbda958c08fb63..ab71809d88ec3bc835db2b2a555f9b7bb9980917 100755
--- a/tests/scripts/test043-delta-syncrepl
+++ b/tests/scripts/test043-delta-syncrepl
@@ -73,19 +73,6 @@ if test $RC != 0 ; then
 fi
 
 echo "Using ldapadd to create the context prefix entries in the master..."
-$LDAPADD -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD <<EOF \
-	> /dev/null 2>&1
-dn: cn=log
-objectclass: applicationProcess
-cn: log
-
-EOF
-RC=$?
-if test $RC != 0 ; then
-	echo "ldapadd failed ($RC)!"
-	test $KILLSERVERS != no && kill -HUP $KILLPIDS
-	exit $RC
-fi
 $LDAPADD -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD < \
 	$LDIFORDEREDCP > /dev/null 2>&1
 RC=$?