]> git.sur5r.net Git - openldap/commitdiff
Sync with HEAD
authorKurt Zeilenga <kurt@openldap.org>
Wed, 28 Sep 2005 02:30:11 +0000 (02:30 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 28 Sep 2005 02:30:11 +0000 (02:30 +0000)
Changes needs updating for release...

137 files changed:
CHANGES
build/mkdep
build/openldap.m4
configure
configure.in
doc/guide/admin/slapdconf2.sdf
include/avl.h
include/ldap_int_thread.h
include/ldap_pvt_thread.h
libraries/liblber/encode.c
libraries/liblber/io.c
libraries/libldap/os-ip.c
libraries/libldap/os-local.c
libraries/libldap/result.c
libraries/libldap_r/Makefile.in
libraries/libldap_r/ldap_thr_debug.h [new file with mode: 0644]
libraries/libldap_r/rdwr.c
libraries/libldap_r/thr_cthreads.c
libraries/libldap_r/thr_debug.c [new file with mode: 0644]
libraries/libldap_r/thr_lwp.c
libraries/libldap_r/thr_nt.c
libraries/libldap_r/thr_posix.c
libraries/libldap_r/thr_pth.c
libraries/libldap_r/thr_stub.c
libraries/libldap_r/thr_thr.c
libraries/libldap_r/threads.c
libraries/libldap_r/tpool.c
libraries/liblunicode/Makefile.in
libraries/liblunicode/ucdata/ucgendat.c
libraries/liblutil/Makefile.in
libraries/liblutil/avl.c
libraries/liblutil/passwd.c
libraries/liblutil/tavl.c [new file with mode: 0644]
libraries/liblutil/utils.c
libraries/liblutil/uuid.c
libraries/librewrite/session.c
servers/slapd/Makefile.in
servers/slapd/acl.c
servers/slapd/aclparse.c
servers/slapd/ad.c
servers/slapd/alock.c [new file with mode: 0644]
servers/slapd/alock.h [new file with mode: 0644]
servers/slapd/at.c
servers/slapd/back-bdb/Makefile.in
servers/slapd/back-bdb/alock.c [deleted file]
servers/slapd/back-bdb/alock.h [deleted file]
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/cache.c
servers/slapd/back-bdb/dn2id.c
servers/slapd/back-bdb/idl.c
servers/slapd/back-bdb/idl.h
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/search.c
servers/slapd/back-hdb/Makefile.in
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/modify.c
servers/slapd/back-ldap/proto-ldap.h
servers/slapd/back-ldap/search.c
servers/slapd/back-ldap/unbind.c
servers/slapd/back-ldbm/back-ldbm.h
servers/slapd/back-ldbm/close.c
servers/slapd/back-ldbm/init.c
servers/slapd/back-ldbm/modrdn.c
servers/slapd/back-meta/Makefile.in
servers/slapd/back-meta/TODO [deleted file]
servers/slapd/back-meta/attribute.c [deleted file]
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/candidates.c
servers/slapd/back-meta/compare.c
servers/slapd/back-meta/config.c
servers/slapd/back-meta/conn.c
servers/slapd/back-meta/group.c [deleted file]
servers/slapd/back-meta/init.c
servers/slapd/back-meta/search.c
servers/slapd/back-meta/unbind.c
servers/slapd/back-monitor/init.c
servers/slapd/back-monitor/proto-back-monitor.h
servers/slapd/back-perl/close.c
servers/slapd/back-perl/init.c
servers/slapd/back-perl/proto-perl.h
servers/slapd/back-sql/add.c
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/util.c
servers/slapd/backend.c
servers/slapd/backglue.c
servers/slapd/bconfig.c
servers/slapd/bind.c
servers/slapd/ch_malloc.c
servers/slapd/config.c
servers/slapd/controls.c
servers/slapd/daemon.c
servers/slapd/dn.c
servers/slapd/init.c
servers/slapd/main.c
servers/slapd/modify.c
servers/slapd/oc.c
servers/slapd/overlays/accesslog.c
servers/slapd/overlays/pcache.c
servers/slapd/overlays/ppolicy.c
servers/slapd/overlays/rwm.c
servers/slapd/overlays/syncprov.c
servers/slapd/proto-slap.h
servers/slapd/saslauthz.c
servers/slapd/schema/nis.schema
servers/slapd/schema_init.c
servers/slapd/schema_prep.c
servers/slapd/slap.h
servers/slapd/slapacl.c
servers/slapd/slapcommon.c
servers/slapd/syncrepl.c
servers/slurpd/config.c
servers/slurpd/re.c
servers/slurpd/replica.c
tests/data/ldapglue.out
tests/data/test-glued.ldif
tests/run.in
tests/scripts/acfilter.sh
tests/scripts/conf.sh
tests/scripts/passwd-search
tests/scripts/test000-rootdse
tests/scripts/test001-slapadd
tests/scripts/test005-modrdn
tests/scripts/test008-concurrency
tests/scripts/test011-glue-slapadd
tests/scripts/test014-whoami
tests/scripts/test018-syncreplication-persist
tests/scripts/test019-syncreplication-cascade
tests/scripts/test022-ppolicy
tests/scripts/test023-refint
tests/scripts/test027-emptydn
tests/scripts/test032-chain
tests/scripts/test035-meta
tests/scripts/test036-meta-concurrency

diff --git a/CHANGES b/CHANGES
index cbe7e0648f1262a1b5aa14bb7bda0a08942f1983..fd3ef961c9d26f4499c5319f65771ff1fba34758 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,8 @@ OpenLDAP 2.3 Change Log
 
 OpenLDAP 2.3.8 Engineering
        Fixed slapd undef HAVE_EPOLL issue
+       Documentation
+               Add slapo-valsort(5) man page
 
 OpenLDAP 2.3.7 Release
        Updated slapd ManageDIT support
index 0e8ce3d8574e05f4164140c842f672dfd7794ae8..eec2d20de3806974fbd9a289e3dd26638aa500f0 100755 (executable)
@@ -161,7 +161,7 @@ for i in $files; do
        esac
 done
 for i in $FILES; do
-       $MKDEP_CC $MKDEP_CFLAGS $FLAGS $i | egrep '^#.*"' > $TMP.sed
+       $MKDEP_CC $MKDEP_CFLAGS $FLAGS $i | grep '^#.*"' > $TMP.sed
 awk '
 BEGIN {
        file = "'$i'"
index ab2371b3d5b7d32b8c60c2857132091ac7b52c4e..05170db5a93a4fabf9c0fb314871704ea406dcd1 100644 (file)
@@ -80,7 +80,7 @@ if test -z "${MKDEP}"; then
  noCode;
 EOF
                                if AC_TRY_COMMAND($OL_MKDEP $flag conftest.c) \
-                                       | egrep '^conftest\.'"${ac_objext}" >/dev/null 2>&1
+                                       | grep '^conftest\.'"${ac_objext}" >/dev/null 2>&1
                                then
                                        if test ! -f conftest."${ac_object}" ; then
                                                ol_cv_mkdep=$flag
@@ -500,7 +500,7 @@ dnl --------------------------------------------------------------------
 dnl Find old Berkeley DB 1.85/1.86
 AC_DEFUN([OL_BERKELEY_COMPAT_DB],
 [AC_CHECK_HEADERS(db_185.h db.h)
-if test $ac_cv_header_db_185_h = yes -o $ac_cv_header_db_h = yes; then
+if test $ac_cv_header_db_185_h = yes || test $ac_cv_header_db_h = yes; then
        AC_CACHE_CHECK([if Berkeley DB header compatibility], [ol_cv_header_db1],[
                AC_EGREP_CPP(__db_version_1,[
 #if HAVE_DB_185_H
@@ -562,7 +562,7 @@ AC_DEFUN([OL_GDBM],
 [AC_REQUIRE([OL_LIB_GDBM])
  AC_CHECK_HEADERS(gdbm.h)
  AC_CACHE_CHECK(for db, [ol_cv_gdbm], [
-       if test $ol_cv_lib_gdbm = no -o $ac_cv_header_gdbm_h = no ; then
+       if test $ol_cv_lib_gdbm = no || test $ac_cv_header_gdbm_h = no ; then
                ol_cv_gdbm=no
        else
                ol_cv_gdbm=yes
@@ -607,7 +607,7 @@ AC_DEFUN([OL_MDBM],
 [AC_REQUIRE([OL_LIB_MDBM])
  AC_CHECK_HEADERS(mdbm.h)
  AC_CACHE_CHECK(for db, [ol_cv_mdbm], [
-       if test $ol_cv_lib_mdbm = no -o $ac_cv_header_mdbm_h = no ; then
+       if test $ol_cv_lib_mdbm = no || test $ac_cv_header_mdbm_h = no ; then
                ol_cv_mdbm=no
        else
                ol_cv_mdbm=yes
@@ -663,7 +663,7 @@ AC_DEFUN([OL_NDBM],
 [AC_REQUIRE([OL_LIB_NDBM])
  AC_CHECK_HEADERS(ndbm.h)
  AC_CACHE_CHECK(for db, [ol_cv_ndbm], [
-       if test $ol_cv_lib_ndbm = no -o $ac_cv_header_ndbm_h = no ; then
+       if test $ol_cv_lib_ndbm = no || test $ac_cv_header_ndbm_h = no ; then
                ol_cv_ndbm=no
        else
                ol_cv_ndbm=yes
@@ -894,11 +894,11 @@ AC_DEFUN([OL_LINUX_THREADS], [
        AC_REQUIRE([OL_HEADER_LINUX_THREADS])
        AC_REQUIRE([OL_SYS_LINUX_THREADS])
        AC_CACHE_CHECK([for LinuxThreads consistency], [ol_cv_linux_threads], [
-               if test $ol_cv_header_linux_threads = yes -a \
-                       $ol_cv_sys_linux_threads = yes; then
+               if test $ol_cv_header_linux_threads = yes &&
+                  test $ol_cv_sys_linux_threads = yes; then
                        ol_cv_linux_threads=yes
-               elif test $ol_cv_header_linux_threads = no -a \
-                       $ol_cv_sys_linux_threads = no; then
+               elif test $ol_cv_header_linux_threads = no &&
+                    test $ol_cv_sys_linux_threads = no; then
                        ol_cv_linux_threads=no
                else
                        ol_cv_linux_threads=error
@@ -1089,13 +1089,13 @@ AC_DEFUN([OL_FUNC_CTIME_R_NARGS],
 
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]], [[time_t ti; char *buffer; ctime_r(&ti,buffer);]])],[ol_cv_func_ctime_r_nargs2=yes],[ol_cv_func_ctime_r_nargs2=no])
 
-       if test $ol_cv_func_ctime_r_nargs3 = yes -a \
-               $ol_cv_func_ctime_r_nargs2 = no ; then
+       if test $ol_cv_func_ctime_r_nargs3 = yes &&
+          test $ol_cv_func_ctime_r_nargs2 = no ; then
 
                ol_cv_func_ctime_r_nargs=3
 
-       elif test $ol_cv_func_ctime_r_nargs3 = no -a \
-               $ol_cv_func_ctime_r_nargs2 = yes ; then
+       elif test $ol_cv_func_ctime_r_nargs3 = no &&
+            test $ol_cv_func_ctime_r_nargs2 = yes ; then
 
                ol_cv_func_ctime_r_nargs=2
 
@@ -1144,13 +1144,13 @@ AC_DEFUN([OL_FUNC_GETHOSTBYNAME_R_NARGS],
                (void)gethostbyname_r("localhost", &hent, buffer, bufsize,
                        &rhent, &h_errno);]])],[ol_cv_func_gethostbyname_r_nargs6=yes],[ol_cv_func_gethostbyname_r_nargs6=no])
 
-       if test $ol_cv_func_gethostbyname_r_nargs5 = yes -a \
-               $ol_cv_func_gethostbyname_r_nargs6 = no ; then
+       if test $ol_cv_func_gethostbyname_r_nargs5 = yes &&
+          test $ol_cv_func_gethostbyname_r_nargs6 = no ; then
 
                ol_cv_func_gethostbyname_r_nargs=5
 
-       elif test $ol_cv_func_gethostbyname_r_nargs5 = no -a \
-               $ol_cv_func_gethostbyname_r_nargs6 = yes ; then
+       elif test $ol_cv_func_gethostbyname_r_nargs5 = no &&
+            test $ol_cv_func_gethostbyname_r_nargs6 = yes ; then
 
                ol_cv_func_gethostbyname_r_nargs=6
 
@@ -1193,13 +1193,13 @@ AC_DEFUN([OL_FUNC_GETHOSTBYADDR_R_NARGS],
                        alen, AF_INET, &hent, buffer, bufsize, 
                        &rhent, &h_errno);]])],[ol_cv_func_gethostbyaddr_r_nargs8=yes],[ol_cv_func_gethostbyaddr_r_nargs8=no])
 
-       if test $ol_cv_func_gethostbyaddr_r_nargs7 = yes -a \
-               $ol_cv_func_gethostbyaddr_r_nargs8 = no ; then
+       if test $ol_cv_func_gethostbyaddr_r_nargs7 = yes &&
+          test $ol_cv_func_gethostbyaddr_r_nargs8 = no ; then
 
                ol_cv_func_gethostbyaddr_r_nargs=7
 
-       elif test $ol_cv_func_gethostbyaddr_r_nargs7 = no -a \
-               $ol_cv_func_gethostbyaddr_r_nargs8 = yes ; then
+       elif test $ol_cv_func_gethostbyaddr_r_nargs7 = no &&
+            test $ol_cv_func_gethostbyaddr_r_nargs8 = yes ; then
 
                ol_cv_func_gethostbyaddr_r_nargs=8
 
index 70442223409be6ca4bf11221c0456d4ae44fdbdc..37b98acae3c56d841eeb5d317884c87393ad1fb4 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.560.2.13 2005/08/29 18:46:16 kurt Exp .
+# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.560.2.14 2005/09/01 20:28:09 kurt Exp .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -1585,7 +1585,7 @@ echo "$as_me: error: could not determine version" >&2;}
    { (exit 1); exit 1; }; }
 fi
 
-if test -f "$ac_aux_dir/shtool" -a ! -d $ac_aux_dir/shtool; then
+if test -f "$ac_aux_dir/shtool" && test ! -d $ac_aux_dir/shtool; then
        ac_cv_shtool="$ac_aux_dir/shtool"
 else
        { { echo "$as_me:$LINENO: error: no shtool found in $ac_aux_dir" >&5
@@ -3701,19 +3701,19 @@ echo "$as_me: WARNING: LDBM disabled, ignoring --enable-ldbm-api argument" >&2;}
 echo "$as_me: WARNING: LDBM disabled, ignoring --enable-ldbm-type argument" >&2;}
        fi
 
-       if test $ol_enable_modules != yes -a \
-               $ol_enable_bdb = no -a \
-               $ol_enable_dnssrv = no -a \
-               $ol_enable_hdb = no -a \
-               $ol_enable_ldap = no -a \
-               $ol_enable_meta = no -a \
-               $ol_enable_monitor = no -a \
-               $ol_enable_null = no -a \
-               $ol_enable_passwd = no -a \
-               $ol_enable_perl = no -a \
-               $ol_enable_relay = no -a \
-               $ol_enable_shell = no -a \
-               $ol_enable_sql = no ; then
+       if test $ol_enable_modules != yes &&
+          test $ol_enable_bdb = no &&
+          test $ol_enable_dnssrv = no &&
+          test $ol_enable_hdb = no &&
+          test $ol_enable_ldap = no &&
+          test $ol_enable_meta = no &&
+          test $ol_enable_monitor = no &&
+          test $ol_enable_null = no &&
+          test $ol_enable_passwd = no &&
+          test $ol_enable_perl = no &&
+          test $ol_enable_relay = no &&
+          test $ol_enable_shell = no &&
+          test $ol_enable_sql = no ; then
 
                if test $ol_enable_slapd = yes ; then
                        { { echo "$as_me:$LINENO: error: slapd requires a backend" >&5
@@ -3729,31 +3729,31 @@ echo "$as_me: WARNING: skipping slapd, no backend specified" >&2;}
        ol_enable_ldbm_api=no
        ol_enable_ldbm_type=no
 
-       if test $ol_enable_bdb != no -o $ol_enable_hdb != no; then
+       if test $ol_enable_bdb/$ol_enable_hdb != no/no; then
                ol_enable_ldbm_api=berkeley
        fi
 
 else
-               if test $ol_enable_ldbm_api = gdbm -a \
-               $ol_enable_ldbm_type = btree ; then
+               if test $ol_enable_ldbm_api = gdbm &&
+          test $ol_enable_ldbm_type = btree ; then
                { { echo "$as_me:$LINENO: error: GDBM only supports LDBM type hash" >&5
 echo "$as_me: error: GDBM only supports LDBM type hash" >&2;}
    { (exit 1); exit 1; }; }
        fi
-       if test $ol_enable_ldbm_api = mdbm -a \
-               $ol_enable_ldbm_type = btree ; then
+       if test $ol_enable_ldbm_api = mdbm &&
+          test $ol_enable_ldbm_type = btree ; then
                { { echo "$as_me:$LINENO: error: MDBM only supports LDBM type hash" >&5
 echo "$as_me: error: MDBM only supports LDBM type hash" >&2;}
    { (exit 1); exit 1; }; }
        fi
-       if test $ol_enable_ldbm_api = ndbm -a \
-               $ol_enable_ldbm_type = btree ; then
+       if test $ol_enable_ldbm_api = ndbm &&
+          test $ol_enable_ldbm_type = btree ; then
                { { echo "$as_me:$LINENO: error: NDBM only supports LDBM type hash" >&5
 echo "$as_me: error: NDBM only supports LDBM type hash" >&2;}
    { (exit 1); exit 1; }; }
        fi
 
-       if test $ol_enable_bdb != no -o $ol_enable_hdb != no ; then
+       if test $ol_enable_bdb/$ol_enable_hdb != no/no ; then
                if test $ol_enable_ldbm_api = auto ; then
                        ol_enable_ldbm_api=berkeley
                elif test $ol_enable_ldbm_api != berkeley ; then
@@ -3764,7 +3764,7 @@ echo "$as_me: error: LDBM API not compatible with BDB/HDB" >&2;}
        fi
 fi
 
-if test $ol_enable_meta = yes -a $ol_enable_ldap = no ; then
+if test $ol_enable_meta/$ol_enable_ldap = yes/no ; then
        { { echo "$as_me:$LINENO: error: --enable-meta requires --enable-ldap" >&5
 echo "$as_me: error: --enable-meta requires --enable-ldap" >&2;}
    { (exit 1); exit 1; }; }
@@ -3967,10 +3967,11 @@ echo "$as_me: WARNING: disabling threads, no cc_r on AIX" >&2;}
                fi
        fi
 
-       if test "${CC}" = "cc_r" -o "${CC}" = "xlc_r" ; then
+       case ${CC} in cc_r | xlc_r)
                ol_with_threads=posix
                ol_cv_pthread_create=yes
-       fi
+               ;;
+       esac
 fi
 
 if test -z "${CC}"; then
@@ -5685,7 +5686,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 5688 "configure"' > conftest.$ac_ext
+  echo '#line 5689 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -7665,11 +7666,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7668: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7669: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7672: \$? = $ac_status" >&5
+   echo "$as_me:7673: \$? = $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.
@@ -7927,11 +7928,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7930: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7931: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7934: \$? = $ac_status" >&5
+   echo "$as_me:7935: \$? = $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.
@@ -7989,11 +7990,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7992: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7993: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:7996: \$? = $ac_status" >&5
+   echo "$as_me:7997: \$? = $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
@@ -10229,7 +10230,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10232 "configure"
+#line 10233 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10327,7 +10328,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10330 "configure"
+#line 10331 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12799,7 +12800,7 @@ EOF
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; } \
-                                       | egrep '^conftest\.'"${ac_objext}" >/dev/null 2>&1
+                                       | grep '^conftest\.'"${ac_objext}" >/dev/null 2>&1
                                then
                                        if test ! -f conftest."${ac_object}" ; then
                                                ol_cv_mkdep=$flag
@@ -17387,7 +17388,7 @@ _ACEOF
        fi
 fi
 
-if test "$ol_enable_dnssrv" = yes -o "$ol_enable_dnssrv" = mod ; then
+if test "$ol_enable_dnssrv" = yes || test "$ol_enable_dnssrv" = mod ; then
        if test "$ol_link_dnssrv" = no ; then
                { { echo "$as_me:$LINENO: error: DNSSRV requires res_query()" >&5
 echo "$as_me: error: DNSSRV requires res_query()" >&2;}
@@ -17607,7 +17608,7 @@ done
 
 
 ol_link_ipv6=no
-if test $ac_cv_func_getaddrinfo = no -o $ac_cv_func_inet_ntop = no ; then
+if test $ac_cv_func_getaddrinfo = no || test $ac_cv_func_inet_ntop = no ; then
        if test $ol_enable_ipv6 = yes ; then
                { { echo "$as_me:$LINENO: error: IPv6 support requires getaddrinfo() and inet_ntop()" >&5
 echo "$as_me: error: IPv6 support requires getaddrinfo() and inet_ntop()" >&2;}
 echo "$as_me:$LINENO: result: $ol_cv_struct_sockaddr_storage" >&5
 echo "${ECHO_T}$ol_cv_struct_sockaddr_storage" >&6
 
-       if test $ol_cv_inet6_addrstrlen = yes \
-               -a $ol_cv_struct_sockaddr_storage = yes ; then
+       if test $ol_cv_inet6_addrstrlen = yes &&
+          test $ol_cv_struct_sockaddr_storage = yes ; then
                ol_link_ipv6=yes
-       elif test $ol_enable_ipv6 = yes \
-                       -a $ol_cv_inet6_addrstrlen = no ; then
+       elif test $ol_enable_ipv6 = yes &&
+            test $ol_cv_inet6_addrstrlen = no ; then
                { { echo "$as_me:$LINENO: error: IPv6 support requires INET6_ADDRSTRLEN" >&5
 echo "$as_me: error: IPv6 support requires INET6_ADDRSTRLEN" >&2;}
    { (exit 1); exit 1; }; }
-       elif test $ol_enable_ipv6 = yes \
-                       -a $ol_cv_struct_sockaddr_storage = no ; then
+       elif test $ol_enable_ipv6 = yes &&
+            test $ol_cv_struct_sockaddr_storage = no ; then
                { { echo "$as_me:$LINENO: error: IPv6 support requires struct sockaddr_storage" >&5
 echo "$as_me: error: IPv6 support requires struct sockaddr_storage" >&2;}
    { (exit 1); exit 1; }; }
@@ -17887,9 +17888,7 @@ ol_link_kbind=no
 ol_link_krb5=no
 ol_link_krb4=no
 
-if test $ol_with_kerberos = yes -o $ol_with_kerberos = auto \
-       -o $ol_with_kerberos = k5 -o $ol_with_kerberos = k5only \
-       -o $ol_with_kerberos = k425 ; then
+case $ol_with_kerberos in yes | auto | k5 | k5only | k425)
 
 
 for ac_header in krb5.h
@@ -18495,10 +18494,13 @@ echo "$as_me: error: Required Kerberos 5 support not available" >&2;}
                fi
 
        fi
-fi
+       ;;
+esac
 
-if test $ol_link_krb5 = yes -a \( $ol_with_kerberos = yes -o \
-       $ol_with_kerberos = auto -o $ol_with_kerberos = k425 \) ; then
+if test $ol_link_krb5 = yes &&
+   { test $ol_with_kerberos = yes ||
+     test $ol_with_kerberos = auto ||
+     test $ol_with_kerberos = k425; }; then
 
 
 
@@ -18891,8 +18893,7 @@ if test $ol_link_krb5 = yes ; then
        ol_with_kerberos=found
 fi
 
-if test $ol_with_kerberos = yes -o $ol_with_kerberos = auto \
-       -o $ol_with_kerberos = k4 -o $ol_with_kerberos = kth ; then
+case $ol_with_kerberos in yes | auto | k4 | kth)
 
 
 
@@ -19134,9 +19135,10 @@ _ACEOF
                        fi
                fi
        fi
-fi
+       ;;
+esac
 
-if test $ol_link_krb4 = yes -a $ol_enable_kbind != no ; then
+if test $ol_link_krb4 = yes && test $ol_enable_kbind != no ; then
        ol_link_kbind=yes
 
 elif test $ol_enable_kbind = yes ; then
@@ -19145,14 +19147,14 @@ echo "$as_me: error: Kerberos IV detection failed" >&2;}
    { (exit 1); exit 1; }; }
 fi
 
-if test $ol_link_krb4 = yes -o $ol_link_krb5 = yes ; then
+if test $ol_link_krb4 = yes || test $ol_link_krb5 = yes ; then
 
 cat >>confdefs.h <<\_ACEOF
 #define HAVE_KERBEROS 1
 _ACEOF
 
 
-elif test $ol_with_kerberos != auto -a $ol_with_kerberos != no ; then
+elif test $ol_with_kerberos != auto && test $ol_with_kerberos != no ; then
        { { echo "$as_me:$LINENO: error: Kerberos detection failed" >&5
 echo "$as_me: error: Kerberos detection failed" >&2;}
    { (exit 1); exit 1; }; }
@@ -19313,8 +19315,8 @@ fi
 done
 
 
-       if test $ac_cv_header_openssl_ssl_h = yes \
-               -o $ac_cv_header_ssl_h = yes ; then
+       if test $ac_cv_header_openssl_ssl_h = yes ||
+          test $ac_cv_header_ssl_h = yes ; then
                echo "$as_me:$LINENO: checking for SSLeay_add_ssl_algorithms in -lssl" >&5
 echo $ECHO_N "checking for SSLeay_add_ssl_algorithms in -lssl... $ECHO_C" >&6
 if test "${ac_cv_lib_ssl_SSLeay_add_ssl_algorithms+set}" = set; then
@@ -19647,8 +19649,7 @@ fi
 
 ol_link_threads=no
 
-if test $ol_with_threads = auto -o $ol_with_threads = yes \
-       -o $ol_with_threads = nt ; then
+case $ol_with_threads in auto | yes | nt)
 
 
        echo "$as_me:$LINENO: checking for _beginthread" >&5
@@ -19775,10 +19776,10 @@ _ACEOF
 echo "$as_me: error: could not locate NT Threads" >&2;}
    { (exit 1); exit 1; }; }
        fi
-fi
+       ;;
+esac
 
-if test $ol_with_threads = auto -o $ol_with_threads = yes \
-       -o $ol_with_threads = posix ; then
+case $ol_with_threads in auto | yes | posix)
 
 
 for ac_header in pthread.h
@@ -24171,9 +24172,9 @@ fi
 done
 
 
-                       if test $ac_cv_func_sched_yield = no -a \
-                               $ac_cv_func_pthread_yield = no -a \
-                               $ac_cv_func_thr_yield = no ; then
+                       if test $ac_cv_func_sched_yield = no &&
+                          test $ac_cv_func_pthread_yield = no &&
+                          test $ac_cv_func_thr_yield = no ; then
                                                                echo "$as_me:$LINENO: checking for sched_yield in -lrt" >&5
 echo $ECHO_N "checking for sched_yield in -lrt... $ECHO_C" >&6
 if test "${ac_cv_lib_rt_sched_yield+set}" = set; then
@@ -24251,9 +24252,9 @@ else
 fi
 
                        fi
-                       if test $ac_cv_func_sched_yield = no -a \
-                               $ac_cv_func_pthread_yield = no -a \
-                               "$ac_cv_func_thr_yield" = no ; then
+                       if test $ac_cv_func_sched_yield = no &&
+                          test $ac_cv_func_pthread_yield = no &&
+                          test "$ac_cv_func_thr_yield" = no ; then
                                { echo "$as_me:$LINENO: WARNING: could not locate sched_yield() or pthread_yield()" >&5
 echo "$as_me: WARNING: could not locate sched_yield() or pthread_yield()" >&2;}
                        fi
@@ -24669,11 +24670,11 @@ if test "${ol_cv_linux_threads+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-               if test $ol_cv_header_linux_threads = yes -a \
-                       $ol_cv_sys_linux_threads = yes; then
+               if test $ol_cv_header_linux_threads = yes &&
+                  test $ol_cv_sys_linux_threads = yes; then
                        ol_cv_linux_threads=yes
-               elif test $ol_cv_header_linux_threads = no -a \
-                       $ol_cv_sys_linux_threads = no; then
+               elif test $ol_cv_header_linux_threads = no &&
+                    test $ol_cv_sys_linux_threads = no; then
                        ol_cv_linux_threads=no
                else
                        ol_cv_linux_threads=error
@@ -24950,10 +24951,10 @@ echo "$as_me: error: could not locate usable POSIX Threads" >&2;}
 echo "$as_me: error: could not locate POSIX Threads" >&2;}
    { (exit 1); exit 1; }; }
        fi
-fi
+       ;;
+esac
 
-if test $ol_with_threads = auto -o $ol_with_threads = yes \
-       -o $ol_with_threads = mach ; then
+case $ol_with_threads in auto | yes | mach)
 
 
 
@@ -25403,10 +25404,10 @@ _ACEOF
 echo "$as_me: error: could not link with Mach CThreads" >&2;}
    { (exit 1); exit 1; }; }
        fi
-fi
+       ;;
+esac
 
-if test $ol_with_threads = auto -o $ol_with_threads = yes \
-       -o $ol_with_threads = pth ; then
+case $ol_with_threads in auto | yes | pth)
 
 
 for ac_header in pth.h
@@ -25646,10 +25647,10 @@ _ACEOF
                        fi
                fi
        fi
-fi
+       ;;
+esac
 
-if test $ol_with_threads = auto -o $ol_with_threads = yes \
-       -o $ol_with_threads = lwp ; then
+case $ol_with_threads in auto | yes | lwp)
 
 
 
@@ -25802,7 +25803,8 @@ fi
 
 done
 
-       if test $ac_cv_header_thread_h = yes -a $ac_cv_header_synch_h = yes ; then
+       if test $ac_cv_header_thread_h = yes &&
+          test $ac_cv_header_synch_h = yes ; then
                echo "$as_me:$LINENO: checking for thr_create in -lthread" >&5
 echo $ECHO_N "checking for thr_create in -lthread... $ECHO_C" >&6
 if test "${ac_cv_lib_thread_thr_create+set}" = set; then
@@ -26232,7 +26234,8 @@ _ACEOF
                        fi
                fi
        fi
-fi
+       ;;
+esac
 
 if test $ol_with_yielding_select = yes ; then
 
@@ -26990,7 +26993,7 @@ done
 
 fi
 
-if test $ol_link_threads != no -a $ol_link_threads != nt ; then
+if test $ol_link_threads != no && test $ol_link_threads != nt ; then
                        cat >>confdefs.h <<\_ACEOF
 #define REENTRANT 1
 _ACEOF
@@ -27134,8 +27137,8 @@ fi
 echo "$as_me:$LINENO: result: $ol_cv_h_errno_thread_specific" >&5
 echo "${ECHO_T}$ol_cv_h_errno_thread_specific" >&6
 
-       if test $ol_cv_errno_thread_specific != yes \
-               -o $ol_cv_h_errno_thread_specific != yes ; then
+       if test $ol_cv_errno_thread_specific != yes ||
+          test $ol_cv_h_errno_thread_specific != yes ; then
                LIBS="$LTHREAD_LIBS $LIBS"
                LTHREAD_LIBS=""
        fi
@@ -27379,13 +27382,13 @@ ol_cv_func_ctime_r_nargs2=no
 fi
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 
-       if test $ol_cv_func_ctime_r_nargs3 = yes -a \
-               $ol_cv_func_ctime_r_nargs2 = no ; then
+       if test $ol_cv_func_ctime_r_nargs3 = yes &&
+          test $ol_cv_func_ctime_r_nargs2 = no ; then
 
                ol_cv_func_ctime_r_nargs=3
 
-       elif test $ol_cv_func_ctime_r_nargs3 = no -a \
-               $ol_cv_func_ctime_r_nargs2 = yes ; then
+       elif test $ol_cv_func_ctime_r_nargs3 = no &&
+            test $ol_cv_func_ctime_r_nargs2 = yes ; then
 
                ol_cv_func_ctime_r_nargs=2
 
@@ -27520,13 +27523,13 @@ ol_cv_func_gethostbyname_r_nargs6=no
 fi
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 
-       if test $ol_cv_func_gethostbyname_r_nargs5 = yes -a \
-               $ol_cv_func_gethostbyname_r_nargs6 = no ; then
+       if test $ol_cv_func_gethostbyname_r_nargs5 = yes &&
+          test $ol_cv_func_gethostbyname_r_nargs6 = no ; then
 
                ol_cv_func_gethostbyname_r_nargs=5
 
-       elif test $ol_cv_func_gethostbyname_r_nargs5 = no -a \
-               $ol_cv_func_gethostbyname_r_nargs6 = yes ; then
+       elif test $ol_cv_func_gethostbyname_r_nargs5 = no &&
+            test $ol_cv_func_gethostbyname_r_nargs6 = yes ; then
 
                ol_cv_func_gethostbyname_r_nargs=6
 
@@ -27667,13 +27670,13 @@ ol_cv_func_gethostbyaddr_r_nargs8=no
 fi
 rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 
-       if test $ol_cv_func_gethostbyaddr_r_nargs7 = yes -a \
-               $ol_cv_func_gethostbyaddr_r_nargs8 = no ; then
+       if test $ol_cv_func_gethostbyaddr_r_nargs7 = yes &&
+          test $ol_cv_func_gethostbyaddr_r_nargs8 = no ; then
 
                ol_cv_func_gethostbyaddr_r_nargs=7
 
-       elif test $ol_cv_func_gethostbyaddr_r_nargs7 = no -a \
-               $ol_cv_func_gethostbyaddr_r_nargs8 = yes ; then
+       elif test $ol_cv_func_gethostbyaddr_r_nargs7 = no &&
+            test $ol_cv_func_gethostbyaddr_r_nargs8 = yes ; then
 
                ol_cv_func_gethostbyaddr_r_nargs=8
 
@@ -27698,9 +27701,7 @@ fi
 
 ol_link_ldbm=no
 
-if test $ol_enable_ldbm_api = auto \
-       -o $ol_enable_ldbm_api = berkeley \
-       -o $ol_enable_ldbm_api = bcompat ; then
+case $ol_enable_ldbm_api in auto | berkeley | bcompat)
 
        if test $ol_enable_ldbm_api = bcompat; then \
 
@@ -27854,7 +27855,7 @@ fi
 
 done
 
-if test $ac_cv_header_db_185_h = yes -o $ac_cv_header_db_h = yes; then
+if test $ac_cv_header_db_185_h = yes || test $ac_cv_header_db_h = yes; then
        echo "$as_me:$LINENO: checking if Berkeley DB header compatibility" >&5
 echo $ECHO_N "checking if Berkeley DB header compatibility... $ECHO_C" >&6
 if test "${ol_cv_header_db1+set}" = set; then
@@ -33104,9 +33105,10 @@ _ACEOF
                        LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_db"
                fi
        fi
-fi
+       ;;
+esac
 
-if test $ol_enable_bdb != no -o $ol_enable_hdb != no; then
+if test $ol_enable_bdb/$ol_enable_hdb != no/no; then
        if test $ol_link_ldbm != berkeley ; then
                { { echo "$as_me:$LINENO: error: BDB/HDB: BerkeleyDB not available" >&5
 echo "$as_me: error: BDB/HDB: BerkeleyDB not available" >&2;}
@@ -33162,13 +33164,13 @@ echo "$as_me: error: BDB/HDB: BerkeleyDB version incompatible" >&2;}
        fi
 fi
 
-if test $ol_link_ldbm = no -a $ol_enable_ldbm_type = btree ; then
+if test $ol_link_ldbm = no && test $ol_enable_ldbm_type = btree ; then
        { echo "$as_me:$LINENO: WARNING: Could not find LDBM with BTREE support" >&5
 echo "$as_me: WARNING: Could not find LDBM with BTREE support" >&2;}
        ol_enable_ldbm_api=none
 fi
 
-if test $ol_enable_ldbm_api = auto -o $ol_enable_ldbm_api = mdbm ; then
+if test $ol_enable_ldbm_api = auto || test $ol_enable_ldbm_api = mdbm ; then
        echo "$as_me:$LINENO: checking for MDBM library" >&5
 echo $ECHO_N "checking for MDBM library... $ECHO_C" >&6
 if test "${ol_cv_lib_mdbm+set}" = set; then
@@ -33505,7 +33507,7 @@ if test "${ol_cv_mdbm+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-       if test $ol_cv_lib_mdbm = no -o $ac_cv_header_mdbm_h = no ; then
+       if test $ol_cv_lib_mdbm = no || test $ac_cv_header_mdbm_h = no ; then
                ol_cv_mdbm=no
        else
                ol_cv_mdbm=yes
@@ -33532,7 +33534,7 @@ _ACEOF
        fi
 fi
 
-if test $ol_enable_ldbm_api = auto -o $ol_enable_ldbm_api = gdbm ; then
+if test $ol_enable_ldbm_api = auto || test $ol_enable_ldbm_api = gdbm ; then
        echo "$as_me:$LINENO: checking for GDBM library" >&5
 echo $ECHO_N "checking for GDBM library... $ECHO_C" >&6
 if test "${ol_cv_lib_gdbm+set}" = set; then
@@ -33869,7 +33871,7 @@ if test "${ol_cv_gdbm+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-       if test $ol_cv_lib_gdbm = no -o $ac_cv_header_gdbm_h = no ; then
+       if test $ol_cv_lib_gdbm = no || test $ac_cv_header_gdbm_h = no ; then
                ol_cv_gdbm=no
        else
                ol_cv_gdbm=yes
@@ -34304,7 +34306,7 @@ if test "${ol_cv_ndbm+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
 
-       if test $ol_cv_lib_ndbm = no -o $ac_cv_header_ndbm_h = no ; then
+       if test $ol_cv_lib_ndbm = no || test $ac_cv_header_ndbm_h = no ; then
                ol_cv_ndbm=no
        else
                ol_cv_ndbm=yes
@@ -34332,20 +34334,20 @@ _ACEOF
        fi
 fi
 
-if test $ol_link_ldbm = no -a $ol_enable_ldbm != no ; then
+if test $ol_link_ldbm = no && test $ol_enable_ldbm != no ; then
        { { echo "$as_me:$LINENO: error: could not find suitable LDBM backend" >&5
 echo "$as_me: error: could not find suitable LDBM backend" >&2;}
    { (exit 1); exit 1; }; }
 fi
 
-if test $ol_enable_bdb = yes -o \
-       $ol_enable_hdb = yes -o \
-       $ol_enable_ldbm = yes ; then
+if test $ol_enable_bdb = yes ||
+   test $ol_enable_hdb = yes ||
+   test $ol_enable_ldbm = yes ; then
        SLAPD_LIBS="$SLAPD_LIBS \$(LDBM_LIBS)"
 fi
 
 
-if test $ol_enable_dynamic = yes -a $enable_shared = yes ; then
+if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then
        BUILD_LIBS_DYNAMIC=shared
 
 cat >>confdefs.h <<\_ACEOF
@@ -34745,7 +34747,7 @@ fi
 echo "$as_me:$LINENO: result: $ac_cv_func_openlog" >&5
 echo "${ECHO_T}$ac_cv_func_openlog" >&6
 
-       if test $ac_cv_func_openlog = no -a $ol_enable_syslog = yes; then
+       if test $ac_cv_func_openlog = no && test $ol_enable_syslog = yes; then
                { { echo "$as_me:$LINENO: error: could not find syslog" >&5
 echo "$as_me: error: could not find syslog" >&2;}
    { (exit select appropriate options or disable); exit select appropriate options or disable; }; }
@@ -35232,7 +35234,8 @@ fi
 done
 
 
-       if test $ac_cv_header_sasl_sasl_h = yes -o $ac_cv_header_sasl_h = yes; then
+       if test $ac_cv_header_sasl_sasl_h = yes ||
+          test $ac_cv_header_sasl_h = yes; then
                echo "$as_me:$LINENO: checking for sasl_client_init in -lsasl2" >&5
 echo $ECHO_N "checking for sasl_client_init in -lsasl2... $ECHO_C" >&6
 if test "${ac_cv_lib_sasl2_sasl_client_init+set}" = set; then
@@ -35559,7 +35562,7 @@ echo "$as_me: WARNING: Strong authentication not supported!" >&2;}
        fi
 fi
 
-if test $cross_compiling != yes -a "$ac_cv_mingw32" != yes ; then
+if test $cross_compiling != yes && test "$ac_cv_mingw32" != yes ; then
        dev=no
        if test -r /dev/urandom ; then
                dev="/dev/urandom";
@@ -36749,18 +36752,18 @@ done
                ol_have_bn_h=no
                ol_have_crypto_h=no
 
-               if test "$ac_cv_header_openssl_bn_h" = "yes" \
-                               -o "$ac_cv_header_bn_h" = "yes" ; then
+               if test "$ac_cv_header_openssl_bn_h" = "yes" ||
+                  test "$ac_cv_header_bn_h" = "yes" ; then
                        ol_have_bn_h=yes
                fi
 
-               if test "$ac_cv_header_openssl_crypto_h" = "yes" \
-                               -o "$ac_cv_header_crypto_h" = "yes" ; then
+               if test "$ac_cv_header_openssl_crypto_h" = "yes" ||
+                  test "$ac_cv_header_crypto_h" = "yes" ; then
                        ol_have_crypto_h=yes
                fi
 
-               if test "$ol_have_bn_h" = "yes" \
-                               -a "$ol_have_crypto_h" = "yes" ; then
+               if test "$ol_have_bn_h" = "yes" &&
+                  test "$ol_have_crypto_h" = "yes" ; then
                        ol_have_bignum=yes
                fi
        fi
@@ -41838,7 +41841,8 @@ fi
        fi
        LIBSRCS="$LIBSRCS getpeereid.c"
 fi
-if test "$ac_cv_func_snprintf" != yes -o "$ac_cv_func_vsnprintf" != yes; then
+if test "$ac_cv_func_snprintf" != yes ||
+   test "$ac_cv_func_vsnprintf" != yes; then
        if test "$ac_cv_func_snprintf" != yes; then
 
 cat >>confdefs.h <<\_ACEOF
@@ -42286,7 +42290,7 @@ _ACEOF
 
 fi
 
-if test "$ol_link_ldbm" != no -a $ol_enable_ldbm != no; then
+if test "$ol_link_ldbm" != no && test $ol_enable_ldbm != no; then
        BUILD_SLAPD=yes
        BUILD_LDBM=$ol_enable_ldbm
        if test "$ol_enable_ldbm" = mod ; then
@@ -42669,8 +42673,9 @@ _ACEOF
 
 fi
 
-if test "$ol_enable_slurpd" != no -a "$ol_link_threads" != no -a \
-       $BUILD_SLAPD = yes ; then
+if test "$ol_enable_slurpd" != no &&
+   test "$ol_link_threads" != no &&
+   test $BUILD_SLAPD = yes ; then
        BUILD_SLURPD=yes
 fi
 
index d1ef9c248cb96775133b726f15d54fd9960979b4..44b15b56d7316b2281f57cd6ec425dc1b7df4199 100644 (file)
@@ -40,7 +40,7 @@ if test -z "$OL_STRING"; then
        AC_MSG_ERROR([could not determine version])
 fi
 
-if test -f "$ac_aux_dir/shtool" -a ! -d $ac_aux_dir/shtool; then
+if test -f "$ac_aux_dir/shtool" && test ! -d $ac_aux_dir/shtool; then
        ac_cv_shtool="$ac_aux_dir/shtool"
 else
        AC_MSG_ERROR([no shtool found in $ac_aux_dir])
@@ -483,19 +483,19 @@ elif test $ol_enable_ldbm = no ; then
                AC_MSG_WARN([LDBM disabled, ignoring --enable-ldbm-type argument])
        fi
 
-       if test $ol_enable_modules != yes -a \
-               $ol_enable_bdb = no -a \
-               $ol_enable_dnssrv = no -a \
-               $ol_enable_hdb = no -a \
-               $ol_enable_ldap = no -a \
-               $ol_enable_meta = no -a \
-               $ol_enable_monitor = no -a \
-               $ol_enable_null = no -a \
-               $ol_enable_passwd = no -a \
-               $ol_enable_perl = no -a \
-               $ol_enable_relay = no -a \
-               $ol_enable_shell = no -a \
-               $ol_enable_sql = no ; then
+       if test $ol_enable_modules != yes &&
+          test $ol_enable_bdb = no &&
+          test $ol_enable_dnssrv = no &&
+          test $ol_enable_hdb = no &&
+          test $ol_enable_ldap = no &&
+          test $ol_enable_meta = no &&
+          test $ol_enable_monitor = no &&
+          test $ol_enable_null = no &&
+          test $ol_enable_passwd = no &&
+          test $ol_enable_perl = no &&
+          test $ol_enable_relay = no &&
+          test $ol_enable_shell = no &&
+          test $ol_enable_sql = no ; then
 
                if test $ol_enable_slapd = yes ; then
                        AC_MSG_ERROR([slapd requires a backend])
@@ -508,26 +508,26 @@ elif test $ol_enable_ldbm = no ; then
        ol_enable_ldbm_api=no
        ol_enable_ldbm_type=no
 
-       if test $ol_enable_bdb != no -o $ol_enable_hdb != no; then
+       if test $ol_enable_bdb/$ol_enable_hdb != no/no; then
                ol_enable_ldbm_api=berkeley
        fi
 
 else
        dnl SLAPD with LDBM
-       if test $ol_enable_ldbm_api = gdbm -a \
-               $ol_enable_ldbm_type = btree ; then
+       if test $ol_enable_ldbm_api = gdbm &&
+          test $ol_enable_ldbm_type = btree ; then
                AC_MSG_ERROR([GDBM only supports LDBM type hash])
        fi
-       if test $ol_enable_ldbm_api = mdbm -a \
-               $ol_enable_ldbm_type = btree ; then
+       if test $ol_enable_ldbm_api = mdbm &&
+          test $ol_enable_ldbm_type = btree ; then
                AC_MSG_ERROR([MDBM only supports LDBM type hash])
        fi
-       if test $ol_enable_ldbm_api = ndbm -a \
-               $ol_enable_ldbm_type = btree ; then
+       if test $ol_enable_ldbm_api = ndbm &&
+          test $ol_enable_ldbm_type = btree ; then
                AC_MSG_ERROR([NDBM only supports LDBM type hash])
        fi
 
-       if test $ol_enable_bdb != no -o $ol_enable_hdb != no ; then
+       if test $ol_enable_bdb/$ol_enable_hdb != no/no ; then
                if test $ol_enable_ldbm_api = auto ; then
                        ol_enable_ldbm_api=berkeley
                elif test $ol_enable_ldbm_api != berkeley ; then
@@ -536,7 +536,7 @@ else
        fi
 fi
 
-if test $ol_enable_meta = yes -a $ol_enable_ldap = no ; then
+if test $ol_enable_meta/$ol_enable_ldap = yes/no ; then
        AC_MSG_ERROR([--enable-meta requires --enable-ldap])
 fi
 
@@ -700,10 +700,11 @@ if test $ol_aix_threads = yes ; then
                fi
        fi
 
-       if test "${CC}" = "cc_r" -o "${CC}" = "xlc_r" ; then
+       case ${CC} in cc_r | xlc_r)
                ol_with_threads=posix
                ol_cv_pthread_create=yes
-       fi
+               ;;
+       esac
 fi
 
 if test -z "${CC}"; then
@@ -1078,7 +1079,7 @@ if test "$ol_cv_lib_resolver" != no ; then
        fi
 fi
 
-if test "$ol_enable_dnssrv" = yes -o "$ol_enable_dnssrv" = mod ; then
+if test "$ol_enable_dnssrv" = yes || test "$ol_enable_dnssrv" = mod ; then
        if test "$ol_link_dnssrv" = no ; then
                AC_MSG_ERROR([DNSSRV requires res_query()])
        fi
@@ -1094,7 +1095,7 @@ dnl PF_LOCAL may use getaddrinfo in available
 AC_CHECK_FUNCS( getaddrinfo getnameinfo gai_strerror inet_ntop )
 
 ol_link_ipv6=no
-if test $ac_cv_func_getaddrinfo = no -o $ac_cv_func_inet_ntop = no ; then
+if test $ac_cv_func_getaddrinfo = no || test $ac_cv_func_inet_ntop = no ; then
        if test $ol_enable_ipv6 = yes ; then
                AC_MSG_ERROR([IPv6 support requires getaddrinfo() and inet_ntop()])
        fi
@@ -1116,14 +1117,14 @@ elif test $ol_enable_ipv6 != no ; then
                        struct sockaddr_storage ss;
 ]])],[ol_cv_struct_sockaddr_storage=yes],[ol_cv_struct_sockaddr_storage=no])])
 
-       if test $ol_cv_inet6_addrstrlen = yes \
-               -a $ol_cv_struct_sockaddr_storage = yes ; then
+       if test $ol_cv_inet6_addrstrlen = yes &&
+          test $ol_cv_struct_sockaddr_storage = yes ; then
                ol_link_ipv6=yes
-       elif test $ol_enable_ipv6 = yes \
-                       -a $ol_cv_inet6_addrstrlen = no ; then
+       elif test $ol_enable_ipv6 = yes &&
+            test $ol_cv_inet6_addrstrlen = no ; then
                AC_MSG_ERROR([IPv6 support requires INET6_ADDRSTRLEN])
-       elif test $ol_enable_ipv6 = yes \
-                       -a $ol_cv_struct_sockaddr_storage = no ; then
+       elif test $ol_enable_ipv6 = yes &&
+            test $ol_cv_struct_sockaddr_storage = no ; then
                AC_MSG_ERROR([IPv6 support requires struct sockaddr_storage])
        fi
 fi
@@ -1144,9 +1145,7 @@ ol_link_kbind=no
 ol_link_krb5=no
 ol_link_krb4=no
 
-if test $ol_with_kerberos = yes -o $ol_with_kerberos = auto \
-       -o $ol_with_kerberos = k5 -o $ol_with_kerberos = k5only \
-       -o $ol_with_kerberos = k425 ; then
+case $ol_with_kerberos in yes | auto | k5 | k5only | k425)
 
        AC_CHECK_HEADERS(krb5.h)
 
@@ -1204,10 +1203,13 @@ if test $ol_with_kerberos = yes -o $ol_with_kerberos = auto \
                fi
 
        fi
-fi
+       ;;
+esac
 
-if test $ol_link_krb5 = yes -a \( $ol_with_kerberos = yes -o \
-       $ol_with_kerberos = auto -o $ol_with_kerberos = k425 \) ; then
+if test $ol_link_krb5 = yes &&
+   { test $ol_with_kerberos = yes ||
+     test $ol_with_kerberos = auto ||
+     test $ol_with_kerberos = k425; }; then
 
        AC_CHECK_HEADERS(kerberosIV/krb.h kerberosIV/des.h)
 
@@ -1266,8 +1268,7 @@ if test $ol_link_krb5 = yes ; then
        ol_with_kerberos=found
 fi
 
-if test $ol_with_kerberos = yes -o $ol_with_kerberos = auto \
-       -o $ol_with_kerberos = k4 -o $ol_with_kerberos = kth ; then
+case $ol_with_kerberos in yes | auto | k4 | kth)
 
        AC_CHECK_HEADERS(krb.h des.h krb-archaeology.h )
 
@@ -1289,19 +1290,20 @@ if test $ol_with_kerberos = yes -o $ol_with_kerberos = auto \
                        fi
                fi
        fi
-fi
+       ;;
+esac
 
-if test $ol_link_krb4 = yes -a $ol_enable_kbind != no ; then
+if test $ol_link_krb4 = yes && test $ol_enable_kbind != no ; then
        ol_link_kbind=yes
 
 elif test $ol_enable_kbind = yes ; then
        AC_MSG_ERROR([Kerberos IV detection failed])
 fi
 
-if test $ol_link_krb4 = yes -o $ol_link_krb5 = yes ; then
+if test $ol_link_krb4 = yes || test $ol_link_krb5 = yes ; then
        AC_DEFINE(HAVE_KERBEROS, 1, [define if you have Kerberos])
 
-elif test $ol_with_kerberos != auto -a $ol_with_kerberos != no ; then
+elif test $ol_with_kerberos != auto && test $ol_with_kerberos != no ; then
        AC_MSG_ERROR([Kerberos detection failed])
 fi
 
@@ -1312,8 +1314,8 @@ ol_link_tls=no
 if test $ol_with_tls != no ; then
        AC_CHECK_HEADERS(openssl/ssl.h ssl.h)
 
-       if test $ac_cv_header_openssl_ssl_h = yes \
-               -o $ac_cv_header_ssl_h = yes ; then
+       if test $ac_cv_header_openssl_ssl_h = yes ||
+          test $ac_cv_header_ssl_h = yes ; then
                AC_CHECK_LIB(ssl, SSLeay_add_ssl_algorithms, 
                        [have_ssleay=yes
                        need_rsaref=no],
@@ -1390,8 +1392,7 @@ dnl ----------------------------------------------------------------
 dnl Threads?
 ol_link_threads=no
 
-if test $ol_with_threads = auto -o $ol_with_threads = yes \
-       -o $ol_with_threads = nt ; then
+case $ol_with_threads in auto | yes | nt)
 
        OL_NT_THREADS
 
@@ -1407,10 +1408,10 @@ if test $ol_with_threads = auto -o $ol_with_threads = yes \
        if test $ol_with_threads = nt ; then
                AC_MSG_ERROR([could not locate NT Threads])
        fi
-fi
+       ;;
+esac
 
-if test $ol_with_threads = auto -o $ol_with_threads = yes \
-       -o $ol_with_threads = posix ; then
+case $ol_with_threads in auto | yes | posix)
 
        AC_CHECK_HEADERS(pthread.h)
 
@@ -1526,9 +1527,9 @@ dnl                       [ol_cv_pthread_lpthread_lexc])
                        dnl check for both, and thr_yield for Solaris
                        AC_CHECK_FUNCS(sched_yield pthread_yield thr_yield)
 
-                       if test $ac_cv_func_sched_yield = no -a \
-                               $ac_cv_func_pthread_yield = no -a \
-                               $ac_cv_func_thr_yield = no ; then
+                       if test $ac_cv_func_sched_yield = no &&
+                          test $ac_cv_func_pthread_yield = no &&
+                          test $ac_cv_func_thr_yield = no ; then
                                dnl Digital UNIX has sched_yield() in -lrt
                                AC_CHECK_LIB(rt, sched_yield,
                                        [LTHREAD_LIBS="$LTHREAD_LIBS -lrt"
@@ -1537,9 +1538,9 @@ dnl                       [ol_cv_pthread_lpthread_lexc])
                                        ac_cv_func_sched_yield=yes],
                                        [ac_cv_func_sched_yield=no])
                        fi
-                       if test $ac_cv_func_sched_yield = no -a \
-                               $ac_cv_func_pthread_yield = no -a \
-                               "$ac_cv_func_thr_yield" = no ; then
+                       if test $ac_cv_func_sched_yield = no &&
+                          test $ac_cv_func_pthread_yield = no &&
+                          test "$ac_cv_func_thr_yield" = no ; then
                                AC_MSG_WARN([could not locate sched_yield() or pthread_yield()])
                        fi
 
@@ -1692,10 +1693,10 @@ int main(argc, argv)
        if test $ol_with_threads = posix ; then
                AC_MSG_ERROR([could not locate POSIX Threads])
        fi
-fi
+       ;;
+esac
 
-if test $ol_with_threads = auto -o $ol_with_threads = yes \
-       -o $ol_with_threads = mach ; then
+case $ol_with_threads in auto | yes | mach)
 
        dnl check for Mach CThreads
        AC_CHECK_HEADERS(mach/cthreads.h cthreads.h)
@@ -1757,10 +1758,10 @@ if test $ol_with_threads = auto -o $ol_with_threads = yes \
        elif test $ol_with_threads = found ; then
                AC_MSG_ERROR([could not link with Mach CThreads])
        fi
-fi
+       ;;
+esac
 
-if test $ol_with_threads = auto -o $ol_with_threads = yes \
-       -o $ol_with_threads = pth ; then
+case $ol_with_threads in auto | yes | pth)
 
        AC_CHECK_HEADERS(pth.h)
 
@@ -1778,14 +1779,15 @@ if test $ol_with_threads = auto -o $ol_with_threads = yes \
                        fi
                fi
        fi
-fi
+       ;;
+esac
 
-if test $ol_with_threads = auto -o $ol_with_threads = yes \
-       -o $ol_with_threads = lwp ; then
+case $ol_with_threads in auto | yes | lwp)
 
        dnl check for SunOS5 LWP
        AC_CHECK_HEADERS(thread.h synch.h)
-       if test $ac_cv_header_thread_h = yes -a $ac_cv_header_synch_h = yes ; then
+       if test $ac_cv_header_thread_h = yes &&
+          test $ac_cv_header_synch_h = yes ; then
                AC_CHECK_LIB(thread, thr_create, [have_thr=yes], [have_thr=no])
 
                if test $have_thr = yes ; then
@@ -1822,7 +1824,8 @@ if test $ol_with_threads = auto -o $ol_with_threads = yes \
                        fi
                fi
        fi
-fi
+       ;;
+esac
 
 if test $ol_with_yielding_select = yes ; then
        AC_DEFINE(HAVE_YIELDING_SELECT,1,
@@ -1844,7 +1847,7 @@ if test $ol_with_threads = manual ; then
        AC_CHECK_HEADERS(thread.h synch.h)
 fi
 
-if test $ol_link_threads != no -a $ol_link_threads != nt ; then  
+if test $ol_link_threads != no && test $ol_link_threads != nt ; then
        dnl needed to get reentrant/threadsafe versions
        dnl
        AC_DEFINE(REENTRANT,1)
@@ -1869,8 +1872,8 @@ if test $ol_link_threads != no -a $ol_link_threads != nt ; then
                AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <netdb.h>]], [[h_errno = 0;]])],[ol_cv_h_errno_thread_specific=yes],[ol_cv_h_errno_thread_specific=no])
        ])
 
-       if test $ol_cv_errno_thread_specific != yes \
-               -o $ol_cv_h_errno_thread_specific != yes ; then
+       if test $ol_cv_errno_thread_specific != yes ||
+          test $ol_cv_h_errno_thread_specific != yes ; then
                LIBS="$LTHREAD_LIBS $LIBS"
                LTHREAD_LIBS=""
        fi
@@ -1975,9 +1978,7 @@ fi
 dnl ----------------------------------------------------------------
 ol_link_ldbm=no 
 
-if test $ol_enable_ldbm_api = auto \
-       -o $ol_enable_ldbm_api = berkeley \
-       -o $ol_enable_ldbm_api = bcompat ; then
+case $ol_enable_ldbm_api in auto | berkeley | bcompat)
 
        if test $ol_enable_ldbm_api = bcompat; then \
                OL_BERKELEY_COMPAT_DB
@@ -2006,9 +2007,10 @@ if test $ol_enable_ldbm_api = auto \
                        LDBM_LIBS="$LDBM_LIBS $ol_cv_lib_db"
                fi
        fi
-fi
+       ;;
+esac
 
-if test $ol_enable_bdb != no -o $ol_enable_hdb != no; then
+if test $ol_enable_bdb/$ol_enable_hdb != no/no; then
        if test $ol_link_ldbm != berkeley ; then
                AC_MSG_ERROR(BDB/HDB: BerkeleyDB not available)
        else
@@ -2020,12 +2022,12 @@ if test $ol_enable_bdb != no -o $ol_enable_hdb != no; then
        fi
 fi
 
-if test $ol_link_ldbm = no -a $ol_enable_ldbm_type = btree ; then
+if test $ol_link_ldbm = no && test $ol_enable_ldbm_type = btree ; then
        AC_MSG_WARN([Could not find LDBM with BTREE support])
        ol_enable_ldbm_api=none
 fi
 
-if test $ol_enable_ldbm_api = auto -o $ol_enable_ldbm_api = mdbm ; then
+if test $ol_enable_ldbm_api = auto || test $ol_enable_ldbm_api = mdbm ; then
        OL_MDBM
 
        if test $ol_cv_mdbm = yes ; then
@@ -2037,7 +2039,7 @@ if test $ol_enable_ldbm_api = auto -o $ol_enable_ldbm_api = mdbm ; then
        fi
 fi
 
-if test $ol_enable_ldbm_api = auto -o $ol_enable_ldbm_api = gdbm ; then
+if test $ol_enable_ldbm_api = auto || test $ol_enable_ldbm_api = gdbm ; then
        OL_GDBM
 
        if test $ol_cv_gdbm = yes ; then
@@ -2063,19 +2065,19 @@ if test $ol_enable_ldbm_api = ndbm ; then
        fi
 fi
 
-if test $ol_link_ldbm = no -a $ol_enable_ldbm != no ; then
+if test $ol_link_ldbm = no && test $ol_enable_ldbm != no ; then
        AC_MSG_ERROR([could not find suitable LDBM backend])
 fi
 
-if test $ol_enable_bdb = yes -o \
-       $ol_enable_hdb = yes -o \
-       $ol_enable_ldbm = yes ; then
+if test $ol_enable_bdb = yes ||
+   test $ol_enable_hdb = yes ||
+   test $ol_enable_ldbm = yes ; then
        SLAPD_LIBS="$SLAPD_LIBS \$(LDBM_LIBS)"
 fi
 
 dnl ----------------------------------------------------------------
 
-if test $ol_enable_dynamic = yes -a $enable_shared = yes ; then
+if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then
        BUILD_LIBS_DYNAMIC=shared
        AC_DEFINE(LDAP_LIBS_DYNAMIC, 1, [define if LDAP libs are dynamic])
        LTSTATIC=""
@@ -2133,7 +2135,7 @@ fi
 dnl ----------------------------------------------------------------
 if test $ol_enable_syslog != no ; then
        AC_CHECK_FUNC(openlog)
-       if test $ac_cv_func_openlog = no -a $ol_enable_syslog = yes; then
+       if test $ac_cv_func_openlog = no && test $ol_enable_syslog = yes; then
                AC_MSG_ERROR(could not find syslog, select appropriate options or disable)
        fi
        ol_enable_syslog=$ac_cv_func_openlog
@@ -2180,7 +2182,8 @@ ol_link_spasswd=no
 if test $ol_with_cyrus_sasl != no ; then
        AC_CHECK_HEADERS(sasl/sasl.h sasl.h)
 
-       if test $ac_cv_header_sasl_sasl_h = yes -o $ac_cv_header_sasl_h = yes; then
+       if test $ac_cv_header_sasl_sasl_h = yes ||
+          test $ac_cv_header_sasl_h = yes; then
                AC_CHECK_LIB(sasl2, sasl_client_init,
                        [ol_link_sasl="-lsasl2"],
                        [AC_CHECK_LIB(sasl, sasl_client_init,
@@ -2228,7 +2231,7 @@ fi
 
 dnl ----------------------------------------------------------------
 dnl Check for entropy sources
-if test $cross_compiling != yes -a "$ac_cv_mingw32" != yes ; then
+if test $cross_compiling != yes && test "$ac_cv_mingw32" != yes ; then
        dev=no
        if test -r /dev/urandom ; then
                dev="/dev/urandom";
@@ -2339,18 +2342,18 @@ if test "$ol_with_multiple_precision" != "no" ; then
                ol_have_bn_h=no
                ol_have_crypto_h=no
 
-               if test "$ac_cv_header_openssl_bn_h" = "yes" \
-                               -o "$ac_cv_header_bn_h" = "yes" ; then
+               if test "$ac_cv_header_openssl_bn_h" = "yes" ||
+                  test "$ac_cv_header_bn_h" = "yes" ; then
                        ol_have_bn_h=yes
                fi
 
-               if test "$ac_cv_header_openssl_crypto_h" = "yes" \
-                               -o "$ac_cv_header_crypto_h" = "yes" ; then
+               if test "$ac_cv_header_openssl_crypto_h" = "yes" ||
+                  test "$ac_cv_header_crypto_h" = "yes" ; then
                        ol_have_crypto_h=yes
                fi
 
-               if test "$ol_have_bn_h" = "yes" \
-                               -a "$ol_have_crypto_h" = "yes" ; then
+               if test "$ol_have_bn_h" = "yes" &&
+                  test "$ol_have_crypto_h" = "yes" ; then
                        ol_have_bignum=yes
                fi
        fi
@@ -2595,7 +2598,8 @@ if test "$ac_cv_func_getpeereid" != yes; then
        fi
        LIBSRCS="$LIBSRCS getpeereid.c"
 fi
-if test "$ac_cv_func_snprintf" != yes -o "$ac_cv_func_vsnprintf" != yes; then
+if test "$ac_cv_func_snprintf" != yes ||
+   test "$ac_cv_func_vsnprintf" != yes; then
        if test "$ac_cv_func_snprintf" != yes; then
                AC_DEFINE(snprintf, ber_pvt_snprintf, [define to snprintf routine])
        fi
@@ -2734,7 +2738,7 @@ if test "$ol_enable_ldap" != no ; then
        AC_DEFINE_UNQUOTED(SLAPD_LDAP,$MFLAG,[define to support LDAP backend])
 fi
 
-if test "$ol_link_ldbm" != no -a $ol_enable_ldbm != no; then
+if test "$ol_link_ldbm" != no && test $ol_enable_ldbm != no; then
        BUILD_SLAPD=yes
        BUILD_LDBM=$ol_enable_ldbm
        if test "$ol_enable_ldbm" = mod ; then
@@ -3024,8 +3028,9 @@ if test "$ol_enable_valsort" != no ; then
        AC_DEFINE_UNQUOTED(SLAPD_OVER_VALSORT,$MFLAG,[define for Value Sorting overlay])
 fi
 
-if test "$ol_enable_slurpd" != no -a "$ol_link_threads" != no -a \
-       $BUILD_SLAPD = yes ; then
+if test "$ol_enable_slurpd" != no &&
+   test "$ol_link_threads" != no &&
+   test $BUILD_SLAPD = yes ; then
        BUILD_SLURPD=yes
 fi
 
index 8f9d607fa21752d390cfedf4d07f556c9a8f1daa..4db17e6d77554d4e3793811f3fd48136cfbfd444 100644 (file)
@@ -71,9 +71,9 @@ loaded from config files or added at runtime.
 
 The usual rules for LDIF files apply to the configuration information:
 Comment lines beginning with a '{{EX:#}}' character
-are ignored.  If a line begins with white space, it is considered a
+are ignored.  If a line begins with a single space, it is considered a
 continuation of the previous line (even if the previous line is a
-comment). Entries are separated by blank lines.
+comment) and the single leading space is removed. Entries are separated by blank lines.
 
 The general layout of the config LDIF is as follows:
 
@@ -132,9 +132,7 @@ prefix attached.
 
 A configuration directive may take arguments.  If so, the arguments are
 separated by white space.  If an argument contains white space,
-the argument should be enclosed in double quotes {{EX:"like this"}}. If
-an argument contains a double quote or a backslash character `{{EX:\}}',
-the character should be preceded by a backslash character `{{EX:\}}'.
+the argument should be enclosed in double quotes {{EX:"like this"}}.
 In the descriptions that follow, arguments that should be replaced
 by actual text are shown in brackets {{EX:<>}}.
 
@@ -349,13 +347,13 @@ H4: Sample Entries
 >objectClass: olcSchemaConfig
 >cn: test
 >olcAttributeTypes: ( 1.1.1
-> NAME 'testAttr'
-> EQUALITY integerMatch
-> SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
+>  NAME 'testAttr'
+>  EQUALITY integerMatch
+>  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
 >olcAttributeTypes: ( 1.1.2 NAME 'testTwo' EQUALITY caseIgnoreMatch
-> SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )
+>  SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 )
 >olcObjectClasses: ( 1.1.3 NAME 'testObject'
-> MAY ( testAttr $ testTwo ) AUXILIARY )
+>  MAY ( testAttr $ testTwo ) AUXILIARY )
 
 
 H3: Backend-specific Directives
index 458f99fd483bcf5798a0c4019bb4504e9a9b54c5..70bdbcd6cbd963d316b843abc14fb3820acfb89b 100644 (file)
@@ -40,11 +40,16 @@ typedef struct avlnode Avlnode;
 
 struct avlnode {
        void*           avl_data;
-       signed int              avl_bf;
-       struct avlnode  *avl_left;
-       struct avlnode  *avl_right;
+       struct avlnode  *avl_link[2];
+       char            avl_bits[2];
+       signed char             avl_bf;
 };
 
+#define avl_left       avl_link[0]
+#define avl_right      avl_link[1]
+#define avl_lbit       avl_bits[0]
+#define avl_rbit       avl_bits[1]
+
 #ifdef AVL_INTERNAL
 
 #define NULLAVL        ((Avlnode *) NULL)
@@ -54,12 +59,21 @@ struct avlnode {
 #define EH     0
 #define RH     1
 
+/* thread bits */
+#define        AVL_THREAD      0
+#define        AVL_CHILD       1
+
 /* avl routines */
 #define avl_getone(x)  ((x) == 0 ? 0 : (x)->avl_data)
 #define avl_onenode(x) ((x) == 0 || ((x)->avl_left == 0 && (x)->avl_right == 0))
 
 #endif /* AVL_INTERNALS */
 
+#define        avl_child(x,dir)        ((x)->avl_bits[dir]) == AVL_CHILD ? \
+       (x)->avl_link[dir] : NULL
+#define        avl_lchild(x)   avl_child(x,0)
+#define        avl_rchild(x)   avl_child(x,1)
+
 typedef int            (*AVL_APPLY) LDAP_P((void *, void*));
 typedef int            (*AVL_CMP) LDAP_P((const void*, const void*));
 typedef int            (*AVL_DUP) LDAP_P((void*, void*));
@@ -103,6 +117,30 @@ avl_apply LDAP_P((Avlnode *, AVL_APPLY, void*, int, int));
 LDAP_AVL_F( int )
 avl_prefixapply LDAP_P((Avlnode *, void*, AVL_CMP, void*, AVL_CMP, void*, int));
 
+LDAP_AVL_F( int )
+tavl_free LDAP_P(( Avlnode *root, AVL_FREE dfree ));
+
+LDAP_AVL_F( int )
+tavl_insert LDAP_P((Avlnode **, void*, AVL_CMP, AVL_DUP));
+
+LDAP_AVL_F( void* )
+tavl_delete LDAP_P((Avlnode **, void*, AVL_CMP));
+
+LDAP_AVL_F( void* )
+tavl_find LDAP_P((Avlnode *, const void*, AVL_CMP));
+
+LDAP_AVL_F( Avlnode* )
+tavl_find2 LDAP_P((Avlnode *, const void*, AVL_CMP));
+
+#define        TAVL_DIR_LEFT   0
+#define        TAVL_DIR_RIGHT  1
+
+LDAP_AVL_F( Avlnode* )
+tavl_end LDAP_P((Avlnode *, int direction ));
+
+LDAP_AVL_F( Avlnode* )
+tavl_next LDAP_P((Avlnode *, int direction ));
+
 /* apply traversal types */
 #define AVL_PREORDER   1
 #define AVL_INORDER    2
index 385fef52f64dae40f1fce5d7c1a5874e73b9b48e..307d85c86ebfafaa42a2a33d099551b03736033a 100644 (file)
  * <http://www.OpenLDAP.org/license.html>.
  */
 
+
+LDAP_BEGIN_DECL
+
+/* Can be done twice in libldap_r.  See libldap_r/ldap_thr_debug.h. */
+LDAP_F(int) ldap_int_thread_initialize LDAP_P(( void ));
+LDAP_F(int) ldap_int_thread_destroy    LDAP_P(( void ));
+
+LDAP_END_DECL
+
+
 #ifndef _LDAP_INT_THREAD_H
 #define _LDAP_INT_THREAD_H
 
@@ -35,6 +45,8 @@ typedef pthread_t             ldap_int_thread_t;
 typedef pthread_mutex_t                ldap_int_thread_mutex_t;
 typedef pthread_cond_t         ldap_int_thread_cond_t;
 
+#define ldap_int_thread_equal(a, b)    pthread_equal((a), (b))
+
 #if defined( _POSIX_REENTRANT_FUNCTIONS ) || \
        defined( _POSIX_THREAD_SAFE_FUNCTIONS ) || \
        defined( _POSIX_THREADSAFE_FUNCTIONS )
@@ -53,7 +65,7 @@ typedef pthread_cond_t                ldap_int_thread_cond_t;
 
 #if 0 && defined( HAVE_PTHREAD_RWLOCK_DESTROY )
 #define LDAP_THREAD_HAVE_RDWR 1
-typedef pthread_rwlock_t ldap_pvt_thread_rdwr_t;
+typedef pthread_rwlock_t ldap_int_thread_rdwr_t;
 #endif
 
 LDAP_END_DECL
@@ -97,7 +109,7 @@ typedef pth_cond_t   ldap_int_thread_cond_t;
 
 #if 0
 #define LDAP_THREAD_HAVE_RDWR 1
-typedef pth_rwlock_t ldap_pvt_thread_rdwr_t;
+typedef pth_rwlock_t ldap_int_thread_rdwr_t;
 #endif
 
 LDAP_END_DECL
@@ -155,6 +167,11 @@ typedef struct ldap_int_thread_lwp_cv ldap_int_thread_cond_t;
 LDAP_END_DECL
 
 #elif defined(HAVE_NT_THREADS)
+/*************************************
+ *                                   *
+ * thread definitions for NT threads *
+ *                                   *
+ *************************************/
 
 #include <process.h>
 #include <windows.h>
@@ -168,7 +185,6 @@ typedef HANDLE      ldap_int_thread_cond_t;
 LDAP_END_DECL
 
 #else
-
 /***********************************
  *                                 *
  * thread definitions for no       *
@@ -193,10 +209,17 @@ LDAP_END_DECL
 
 #endif /* no threads support */
 
+
 LDAP_BEGIN_DECL
 
-LDAP_F(int) ldap_int_thread_initialize LDAP_P(( void ));
-LDAP_F(int) ldap_int_thread_destroy LDAP_P(( void ));
+#ifndef ldap_int_thread_equal
+#define ldap_int_thread_equal(a, b)    ((a) == (b))
+#endif
+
+#ifndef LDAP_THREAD_HAVE_RDWR
+typedef struct ldap_int_thread_rdwr_s * ldap_int_thread_rdwr_t;
+#endif
+
 LDAP_F(int) ldap_int_thread_pool_startup ( void );
 LDAP_F(int) ldap_int_thread_pool_shutdown ( void );
 
@@ -206,4 +229,46 @@ typedef struct ldap_int_thread_pool_s * ldap_int_thread_pool_t;
 
 LDAP_END_DECL
 
+
+#if defined(LDAP_THREAD_DEBUG) && !((LDAP_THREAD_DEBUG +0) & 2U)
+#define LDAP_THREAD_DEBUG_WRAP 1
+#endif
+
+#ifdef LDAP_THREAD_DEBUG_WRAP
+/**************************************
+ *                                    *
+ * definitions for type-wrapped debug *
+ *                                    *
+ **************************************/
+
+LDAP_BEGIN_DECL
+
+#ifndef LDAP_UINTPTR_T /* May be configured in CPPFLAGS */
+#define LDAP_UINTPTR_T unsigned long
+#endif
+
+typedef union {
+       unsigned char                   *ptr;
+       LDAP_UINTPTR_T                  num;
+} ldap_debug_usage_info_t;
+
+typedef struct {
+       ldap_int_thread_mutex_t wrapped;
+       ldap_debug_usage_info_t usage;
+} ldap_debug_thread_mutex_t;
+
+typedef struct {
+       ldap_int_thread_cond_t  wrapped;
+       ldap_debug_usage_info_t usage;
+} ldap_debug_thread_cond_t;
+
+typedef struct {
+       ldap_int_thread_rdwr_t  wrapped;
+       ldap_debug_usage_info_t usage;
+} ldap_debug_thread_rdwr_t;
+
+LDAP_END_DECL
+
+#endif /* LDAP_THREAD_DEBUG_WRAP */
+
 #endif /* _LDAP_INT_THREAD_H */
index 79c821dd659ddf48255392bf7272de4337d6338e..47bcf129bb5e8a6c9836ac2044f5627b55ba311f 100644 (file)
  */
 
 #ifndef _LDAP_PVT_THREAD_H
-#define _LDAP_PVT_THREAD_H
+#define _LDAP_PVT_THREAD_H /* libldap_r/ldap_thr_debug.h #undefines this */
 
 #include "ldap_cdefs.h"
 #include "ldap_int_thread.h"
 
 LDAP_BEGIN_DECL
 
-typedef ldap_int_thread_t ldap_pvt_thread_t;
-typedef ldap_int_thread_mutex_t ldap_pvt_thread_mutex_t;
-typedef ldap_int_thread_cond_t ldap_pvt_thread_cond_t;
+#ifndef LDAP_PVT_THREAD_H_DONE
+typedef ldap_int_thread_t                      ldap_pvt_thread_t;
+#ifdef LDAP_THREAD_DEBUG_WRAP
+typedef ldap_debug_thread_mutex_t      ldap_pvt_thread_mutex_t;
+typedef ldap_debug_thread_cond_t       ldap_pvt_thread_cond_t;
+typedef ldap_debug_thread_rdwr_t       ldap_pvt_thread_rdwr_t;
+#else
+typedef ldap_int_thread_mutex_t                ldap_pvt_thread_mutex_t;
+typedef ldap_int_thread_cond_t         ldap_pvt_thread_cond_t;
+typedef ldap_int_thread_rdwr_t         ldap_pvt_thread_rdwr_t;
+#endif
+#endif /* !LDAP_PVT_THREAD_H_DONE */
+
+#define ldap_pvt_thread_equal          ldap_int_thread_equal
 
 LDAP_F( int )
 ldap_pvt_thread_initialize LDAP_P(( void ));
@@ -44,6 +55,7 @@ ldap_pvt_thread_set_concurrency LDAP_P(( int ));
 #define LDAP_PVT_THREAD_CREATE_JOINABLE 0
 #define LDAP_PVT_THREAD_CREATE_DETACHED 1
 
+#ifndef LDAP_PVT_THREAD_H_DONE
 #define        LDAP_PVT_THREAD_SET_STACK_SIZE
 #ifndef LDAP_PVT_THREAD_STACK_SIZE
        /* LARGE stack. Will be twice as large on 64 bit machine. */
@@ -52,6 +64,7 @@ ldap_pvt_thread_set_concurrency LDAP_P(( int ));
 #elif LDAP_PVT_THREAD_STACK_SIZE == 0
 #undef LDAP_PVT_THREAD_SET_STACK_SIZE
 #endif
+#endif /* !LDAP_PVT_THREAD_H_DONE */
 
 LDAP_F( int )
 ldap_pvt_thread_create LDAP_P((
@@ -107,10 +120,6 @@ ldap_pvt_thread_mutex_unlock LDAP_P(( ldap_pvt_thread_mutex_t *mutex ));
 LDAP_F( ldap_pvt_thread_t )
 ldap_pvt_thread_self LDAP_P(( void ));
 
-#ifndef LDAP_THREAD_HAVE_RDWR
-typedef struct ldap_int_thread_rdwr_s * ldap_pvt_thread_rdwr_t;
-#endif
-
 LDAP_F( int )
 ldap_pvt_thread_rdwr_init LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
@@ -149,10 +158,12 @@ ldap_pvt_thread_rdwr_active LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 #define LDAP_PVT_THREAD_EINVAL EINVAL
 #define LDAP_PVT_THREAD_EBUSY EINVAL
 
+#ifndef LDAP_PVT_THREAD_H_DONE
 typedef ldap_int_thread_pool_t ldap_pvt_thread_pool_t;
 
 typedef void * (ldap_pvt_thread_start_t) LDAP_P((void *ctx, void *arg));
 typedef void (ldap_pvt_thread_pool_keyfree_t) LDAP_P((void *key, void *data));
+#endif /* !LDAP_PVT_THREAD_H_DONE */
 
 LDAP_F( int )
 ldap_pvt_thread_pool_init LDAP_P((
@@ -213,4 +224,5 @@ ldap_pvt_thread_pool_context_reset LDAP_P(( void *key ));
 
 LDAP_END_DECL
 
+#define LDAP_PVT_THREAD_H_DONE
 #endif /* _LDAP_THREAD_H */
index 30ffac3a1e1e1c1dbd9001a43bc5b4353091624b..f0ea2c8698c9420611e3ccf058a40dbb1d0303b1 100644 (file)
@@ -56,18 +56,20 @@ static int ber_put_int_or_enum LDAP_P((
        ber_int_t num,
        ber_tag_t tag ));
 
+#define        BER_TOP_BYTE(type)      (sizeof(type)-1)
+#define        BER_TOP_MASK(type)      ((type)0xffU << (BER_TOP_BYTE(type)*8))
 
 static int
 ber_calc_taglen( ber_tag_t tag )
 {
-       int     i;
-       ber_tag_t       mask;
+       int     i = BER_TOP_BYTE(ber_tag_t);
+       ber_tag_t       mask = BER_TOP_MASK(ber_tag_t);
 
        /* find the first non-all-zero byte in the tag */
-       for ( i = sizeof(ber_tag_t) - 1; i > 0; i-- ) {
-               mask = ((ber_tag_t)0xffU << (i * 8));
+       for ( ; i > 0; i-- ) {
                /* not all zero */
                if ( tag & mask ) break;
+               mask >>= 8;
        }
 
        return i + 1;
@@ -80,7 +82,7 @@ ber_put_tag(
        int nosos )
 {
        int rc;
-       int     taglen;
+       int taglen;
        int     i;
        unsigned char nettag[sizeof(ber_tag_t)];
 
@@ -89,14 +91,12 @@ ber_put_tag(
 
        taglen = ber_calc_taglen( tag );
 
-       for( i=0; i<taglen; i++ ) {
-               nettag[(sizeof(ber_tag_t)-1) - i] = (unsigned char)(tag & 0xffU);
+       for( i=taglen-1; i>=0; i-- ) {
+               nettag[i] = (unsigned char)(tag & 0xffU);
                tag >>= 8;
        }
 
-       rc = ber_write( ber,
-               (char *) &nettag[sizeof(ber_tag_t) - taglen],
-           taglen, nosos );
+       rc = ber_write( ber, (char *) nettag, taglen, nosos );
 
        return rc;
 }
@@ -151,10 +151,12 @@ ber_put_len( BerElement *ber, ber_len_t len, int nosos )
         */
 
        /* find the first non-all-zero byte */
-       for ( i = sizeof(ber_len_t) - 1; i > 0; i-- ) {
-               mask = ((ber_len_t)0xffU << (i * 8));
+       i = BER_TOP_BYTE(ber_len_t);
+       mask = BER_TOP_MASK(ber_len_t);
+       for ( ; i > 0; i-- ) {
                /* not all zero */
                if ( len & mask ) break;
+               mask >>= 8;
        }
        lenlen = (unsigned char) ++i;
        if ( lenlen > 4 ) return -1;
@@ -164,15 +166,13 @@ ber_put_len( BerElement *ber, ber_len_t len, int nosos )
        /* write the length of the length */
        if ( ber_write( ber, &lenlen, 1, nosos ) != 1 ) return -1;
 
-       for( j=0; j<i; j++) {
-               netlen[(sizeof(ber_len_t)-1) - j] = (unsigned char)(len & 0xffU);
+       for( j=i-1; j>=0; j-- ) {
+               netlen[j] = (unsigned char)(len & 0xffU);
                len >>= 8;
        }
 
        /* write the length itself */
-       rc = ber_write( ber,
-               (char *) &netlen[sizeof(ber_len_t)-i],
-               i, nosos );
+       rc = ber_write( ber, (char *) netlen, i, nosos );
 
        return rc == i ?  i+1 : -1;
 }
@@ -199,9 +199,9 @@ ber_put_int_or_enum(
         * high bit is set - look for first non-all-one byte
         * high bit is clear - look for first non-all-zero byte
         */
-       for ( i = sizeof(ber_int_t) - 1; i > 0; i-- ) {
-               mask = ((ber_uint_t)0xffU << (i * 8));
-
+       i = BER_TOP_BYTE(ber_int_t);
+       mask = BER_TOP_MASK(ber_uint_t);
+       for ( ; i > 0; i-- ) {
                if ( sign ) {
                        /* not all ones */
                        if ( (unum & mask) != mask ) break;
@@ -209,6 +209,7 @@ ber_put_int_or_enum(
                        /* not all zero */
                        if ( unum & mask ) break;
                }
+               mask >>= 8;
        }
 
        /*
@@ -231,14 +232,12 @@ ber_put_int_or_enum(
        }
        i++;
 
-       for( j=0; j<i; j++ ) {
-               netnum[(sizeof(ber_int_t)-1) - j] = (unsigned char)(unum & 0xffU);
+       for( j=i-1; j>=0; j-- ) {
+               netnum[j] = (unsigned char)(unum & 0xffU);
                unum >>= 8;
        }
 
-       rc = ber_write( ber,
-               (char *) &netnum[sizeof(ber_int_t) - i],
-               i, 0 );
+       rc = ber_write( ber, (char *) netnum, i, 0 );
 
        /* length of tag + length + contents */
        return rc == i ? taglen + lenlen + i : -1;
@@ -536,13 +535,14 @@ ber_put_seqorset( BerElement *ber )
        }
 
        if( lenlen > 1 ) {
-               ber_len_t i;
-               for( i=0; i < lenlen-1; i++ ) {
-                       netlen[(sizeof(ber_len_t)-1) - i] = 
-                               (unsigned char)((len >> i*8) & 0xffU);
+               int i;
+               ber_len_t j = len;
+               for( i=lenlen-2; i >= 0; i-- ) {
+                       netlen[i] = j & 0xffU;
+                       j >>= 8;
                }
        } else {
-               netlen[sizeof(ber_len_t)-1] = (unsigned char)(len & 0x7fU);
+               netlen[0] = (unsigned char)(len & 0x7fU);
        }
 
        if ( (next = (*sos)->sos_next) == NULL ) {
@@ -575,9 +575,7 @@ ber_put_seqorset( BerElement *ber )
                        }
 
                        /* the length itself */
-                       rc  = ber_write( ber,
-                               (char *) &netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN-1)],
-                               FOUR_BYTE_LEN-1, 1 );
+                       rc  = ber_write( ber, (char *) netlen, FOUR_BYTE_LEN-1, 1 );
 
                        if( rc != FOUR_BYTE_LEN - 1 ) {
                                return -1;
@@ -609,14 +607,12 @@ ber_put_seqorset( BerElement *ber )
                /* the tag */
                taglen = ber_calc_taglen( tmptag );
 
-               for( i = 0; i < taglen; i++ ) {
-                       nettag[(sizeof(ber_tag_t)-1) - i] = (unsigned char)(tmptag & 0xffU);
+               for( i = taglen-1; i >= 0; i-- ) {
+                       nettag[i] = (unsigned char)(tmptag & 0xffU);
                        tmptag >>= 8;
                }
 
-               AC_FMEMCPY( (*sos)->sos_first,
-                       &nettag[sizeof(ber_tag_t) - taglen],
-                       taglen );
+               AC_FMEMCPY( (*sos)->sos_first, nettag, taglen );
 
                if ( ber->ber_options & LBER_USE_DER ) {
                        ltag = (lenlen == 1)
@@ -630,9 +626,7 @@ ber_put_seqorset( BerElement *ber )
                if ( ber->ber_options & LBER_USE_DER ) {
                        if (lenlen > 1) {
                                /* Write the length itself */
-                               AC_FMEMCPY( (*sos)->sos_first + 2,
-                                   &netlen[sizeof(ber_len_t) - (lenlen - 1)],
-                                       lenlen - 1 );
+                               AC_FMEMCPY( (*sos)->sos_first + 2, netlen, lenlen - 1 );
                        }
                        if (lenlen != FOUR_BYTE_LEN) {
                                /*
@@ -647,8 +641,7 @@ ber_put_seqorset( BerElement *ber )
                } else {
                        /* the length itself */
                        AC_FMEMCPY( (*sos)->sos_first + taglen + 1,
-                           &netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN - 1)],
-                               FOUR_BYTE_LEN - 1 );
+                           netlen, FOUR_BYTE_LEN - 1 );
                }
 
                next->sos_clen += (taglen + lenlen + len);
index f5f7ce9b166a6078c236985a56e0d6772896348e..fc37f8dfb20873880d04a4b2fb4bc26e03357595 100644 (file)
@@ -559,7 +559,7 @@ ber_get_next(
 
                /* Now look for the length */
                if (*ber->ber_ptr & 0x80) {     /* multi-byte */
-                       ber_len_t i;
+                       int i;
                        unsigned char *p = (unsigned char *)ber->ber_ptr;
                        int llen = *p++ & 0x7f;
                        if (llen > (int)sizeof(ber_len_t)) {
index 7715044f14f3b87c618ca8d8658b32c9f94ded5a..02eb7828aa55cd73c98f109681fbe636a5268f37 100644 (file)
@@ -209,7 +209,8 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s,
        int async)
 {
        int rc;
-       struct timeval  tv, *opt_tv=NULL;
+       struct timeval  tv = { 0 },
+                       *opt_tv = NULL;
 
 #ifdef LDAP_CONNECTIONLESS
        /* We could do a connect() but that would interfere with
@@ -223,9 +224,9 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s,
                return ( 0 );
        }
 #endif
-       if ( (opt_tv = ld->ld_options.ldo_tm_net) != NULL ) {
-               tv.tv_usec = opt_tv->tv_usec;
-               tv.tv_sec = opt_tv->tv_sec;
+       opt_tv = ld->ld_options.ldo_tm_net;
+       if ( opt_tv != NULL ) {
+               tv = *opt_tv;
        }
 
        osip_debug(ld, "ldap_connect_timeout: fd: %d tm: %ld async: %d\n",
index 5c46e5c6124099710214405798466b4c13d7d811..1079c5071363bc55423acb732f0abf2a8b16067d 100644 (file)
@@ -167,11 +167,12 @@ static int
 ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sa, int async)
 {
        int rc;
-       struct timeval  tv, *opt_tv=NULL;
+       struct timeval  tv = { 0 },
+                       *opt_tv = NULL;
 
-       if ( (opt_tv = ld->ld_options.ldo_tm_net) != NULL ) {
-               tv.tv_usec = opt_tv->tv_usec;
-               tv.tv_sec = opt_tv->tv_sec;
+       opt_tv = ld->ld_options.ldo_tm_net;
+       if ( opt_tv != NULL ) {
+               tv = *opt_tv;
        }
 
        oslocal_debug(ld, "ldap_connect_timeout: fd: %d tm: %ld async: %d\n",
index a4f1093bbe37b2e253cf690582a84e5edee6fa42..6891e6f9158ec68a083f4a82d9319c52d7d0220f 100644 (file)
@@ -251,7 +251,9 @@ wait4msg(
        LDAPMessage **result )
 {
        int             rc;
-       struct timeval  tv, tv0, *tvp;
+       struct timeval  tv = { 0 },
+                       tv0 = { 0 },
+                       *tvp;
        time_t          start_time = 0;
        time_t          tmp_time;
        LDAPConn        *lc, *nextlc;
@@ -281,9 +283,9 @@ wait4msg(
        rc = -2;
        while ( rc == -2 ) {
 #ifdef LDAP_DEBUG
-               Debug( LDAP_DEBUG_TRACE, "wait4msg continue, msgid %d, all %d\n",
-                   msgid, all, 0 );
                if ( ldap_debug & LDAP_DEBUG_TRACE ) {
+                       Debug( LDAP_DEBUG_TRACE, "wait4msg continue, msgid %d, all %d\n",
+                               msgid, all, 0 );
                        ldap_dump_connection( ld, ld->ld_conns, 1 );
                        ldap_dump_requests_and_responses( ld );
                }
@@ -360,7 +362,8 @@ wait4msg(
 
                if ( rc == -2 && tvp != NULL ) {
                        tmp_time = time( NULL );
-                       if (( tv0.tv_sec -=  ( tmp_time - start_time )) <= 0 ) {
+                       tv0.tv_sec -= ( tmp_time - start_time );
+                       if ( tv0.tv_sec <= 0 ) {
                                rc = 0; /* timed out */
                                ld->ld_errno = LDAP_TIMEOUT;
                                break;
@@ -1070,7 +1073,7 @@ int
 ldap_msgtype( LDAPMessage *lm )
 {
        assert( lm != NULL );
-       return ( lm != NULL ) ? lm->lm_msgtype : -1;
+       return ( lm != NULL ) ? (int)lm->lm_msgtype : -1;
 }
 
 
index 09554ea9adec80640f45557b509dae4b56b295af..bc658b84f3e2d89877918cd512928124c6dc63f1 100644 (file)
@@ -31,10 +31,10 @@ XXSRCS    = apitest.c test.c \
        turn.c groupings.c txn.c ppolicy.c
 SRCS   = threads.c rdwr.c tpool.c rq.c \
        thr_posix.c thr_cthreads.c thr_thr.c thr_lwp.c thr_nt.c \
-       thr_pth.c thr_stub.c
+       thr_pth.c thr_stub.c thr_debug.c
 OBJS   = threads.lo rdwr.lo tpool.lo  rq.lo \
        thr_posix.lo thr_cthreads.lo thr_thr.lo thr_lwp.lo thr_nt.lo \
-       thr_pth.lo thr_stub.lo \
+       thr_pth.lo thr_stub.lo thr_debug.lo \
        bind.lo open.lo result.lo error.lo compare.lo search.lo \
        controls.lo messages.lo references.lo extended.lo cyrus.lo \
        modify.lo add.lo modrdn.lo delete.lo abandon.lo \
diff --git a/libraries/libldap_r/ldap_thr_debug.h b/libraries/libldap_r/ldap_thr_debug.h
new file mode 100644 (file)
index 0000000..9c15bb1
--- /dev/null
@@ -0,0 +1,175 @@
+/* ldap_thr_debug.h - preprocessor magic for LDAP_THREAD_DEBUG */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 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>.
+ */
+
+#ifdef LDAP_THREAD_DEBUG
+
+/*
+ * libldap_r .c files should include this file after ldap_pvt_thread.h,
+ * with the appropriate LDAP_THREAD*_IMPLEMENTATION macro defined.
+ */
+
+#ifndef _LDAP_PVT_THREAD_H
+#error "ldap_pvt_thread.h" must be included before "ldap_thr_debug.h"
+#endif
+
+/*
+ * Support for thr_debug.c:
+ *
+ * thr_debug.c defines the ldap_pvt_*() as wrappers around
+ * ldap_int_*(), and ldap_debug_*() around ldap_int_*().
+ *
+ * Renames ldap_pvt_thread_* names to ldap_int_thread_*, and a few
+ * ldap_int_*() names to ldap_debug_*().  Includes "ldap_pvt_thread.h"
+ * to declare these renamed functions, and undefines the macros
+ * afterwards when included from thr_debug.c.  So,
+ *
+ * libldap_r/<not thr_debug.c> define ldap_int_* instead of ldap_pvt_*.
+ * In thread.c, ldap_pvt_thread_<initialize/destroy>() will call
+ * ldap_debug_*() instead of ldap_int_*().
+ * In tpool.c, ldap_int_thread_pool_shutdown() has thr_debug support
+ * which treats ldap_pvt_thread_pool_destroy() the same way.
+ */
+
+#ifndef LDAP_THREAD_IMPLEMENTATION             /* for first part of threads.c */
+#define        ldap_int_thread_initialize              ldap_debug_thread_initialize
+#define        ldap_int_thread_destroy                 ldap_debug_thread_destroy
+#else /* LDAP_THREAD_IMPLEMENTATION    -- for thr_*.c and end of threads.c */
+#undef ldap_int_thread_initialize
+#undef ldap_int_thread_destroy
+#ifdef LDAP_THREAD_DEBUG_WRAP                  /* see ldap_pvt_thread.h */
+#define        ldap_pvt_thread_mutex_t                 ldap_int_thread_mutex_t
+#define        ldap_pvt_thread_cond_t                  ldap_int_thread_cond_t
+#endif
+#define        ldap_pvt_thread_sleep                   ldap_int_thread_sleep
+#define        ldap_pvt_thread_get_concurrency ldap_int_thread_get_concurrency
+#define        ldap_pvt_thread_set_concurrency ldap_int_thread_set_concurrency
+#define        ldap_pvt_thread_create                  ldap_int_thread_create
+#define        ldap_pvt_thread_exit                    ldap_int_thread_exit
+#define        ldap_pvt_thread_join                    ldap_int_thread_join
+#define        ldap_pvt_thread_kill                    ldap_int_thread_kill
+#define        ldap_pvt_thread_yield                   ldap_int_thread_yield
+#define        ldap_pvt_thread_cond_init               ldap_int_thread_cond_init
+#define        ldap_pvt_thread_cond_destroy    ldap_int_thread_cond_destroy
+#define        ldap_pvt_thread_cond_signal             ldap_int_thread_cond_signal
+#define        ldap_pvt_thread_cond_broadcast  ldap_int_thread_cond_broadcast
+#define        ldap_pvt_thread_cond_wait               ldap_int_thread_cond_wait
+#define        ldap_pvt_thread_mutex_init              ldap_int_thread_mutex_init
+#define        ldap_pvt_thread_mutex_destroy   ldap_int_thread_mutex_destroy
+#define        ldap_pvt_thread_mutex_lock              ldap_int_thread_mutex_lock
+#define        ldap_pvt_thread_mutex_trylock   ldap_int_thread_mutex_trylock
+#define        ldap_pvt_thread_mutex_unlock    ldap_int_thread_mutex_unlock
+#define        ldap_pvt_thread_self                    ldap_int_thread_self
+#endif /* LDAP_THREAD_IMPLEMENTATION */
+
+#ifdef LDAP_THREAD_RDWR_IMPLEMENTATION /* rdwr.c, thr_debug.c */
+#ifdef LDAP_THREAD_DEBUG_WRAP                  /* see ldap_pvt_thread.h */
+#define        ldap_pvt_thread_rdwr_t                  ldap_int_thread_rdwr_t
+#endif
+#define        ldap_pvt_thread_rdwr_init               ldap_int_thread_rdwr_init
+#define        ldap_pvt_thread_rdwr_destroy    ldap_int_thread_rdwr_destroy
+#define        ldap_pvt_thread_rdwr_rlock              ldap_int_thread_rdwr_rlock
+#define        ldap_pvt_thread_rdwr_rtrylock   ldap_int_thread_rdwr_rtrylock
+#define        ldap_pvt_thread_rdwr_runlock    ldap_int_thread_rdwr_runlock
+#define        ldap_pvt_thread_rdwr_wlock              ldap_int_thread_rdwr_wlock
+#define        ldap_pvt_thread_rdwr_wtrylock   ldap_int_thread_rdwr_wtrylock
+#define        ldap_pvt_thread_rdwr_wunlock    ldap_int_thread_rdwr_wunlock
+#define        ldap_pvt_thread_rdwr_readers    ldap_int_thread_rdwr_readers
+#define        ldap_pvt_thread_rdwr_writers    ldap_int_thread_rdwr_writers
+#define        ldap_pvt_thread_rdwr_active             ldap_int_thread_rdwr_active
+#endif /* LDAP_THREAD_RDWR_IMPLEMENTATION */
+
+#ifdef LDAP_THREAD_POOL_IMPLEMENTATION /* tpool.c, thr_stub.c, thr_debug.c */
+#ifdef LDAP_THREAD_DEBUG_WRAP                  /* see ldap_pvt_thread.h */
+#define        ldap_pvt_thread_pool_t                  ldap_int_thread_pool_t
+#endif
+#define        ldap_pvt_thread_pool_init               ldap_int_thread_pool_init
+#define        ldap_pvt_thread_pool_submit             ldap_int_thread_pool_submit
+#define        ldap_pvt_thread_pool_maxthreads ldap_int_thread_pool_maxthreads
+#define        ldap_pvt_thread_pool_backload   ldap_int_thread_pool_backload
+#define        ldap_pvt_thread_pool_pause              ldap_int_thread_pool_pause
+#define        ldap_pvt_thread_pool_resume             ldap_int_thread_pool_resume
+#define        ldap_pvt_thread_pool_destroy    ldap_int_thread_pool_destroy
+#define        ldap_pvt_thread_pool_getkey             ldap_int_thread_pool_getkey
+#define        ldap_pvt_thread_pool_setkey             ldap_int_thread_pool_setkey
+#define        ldap_pvt_thread_pool_purgekey   ldap_int_thread_pool_purgekey
+#define        ldap_pvt_thread_pool_context    ldap_int_thread_pool_context
+#define        ldap_pvt_thread_pool_context_reset ldap_int_thread_pool_context_reset
+#endif /* LDAP_THREAD_POOL_IMPLEMENTATION */
+
+#undef _LDAP_PVT_THREAD_H
+#include "ldap_pvt_thread.h"
+
+#ifdef LDAP_THREAD_POOL_IMPLEMENTATION /* tpool.c */
+/*
+ * tpool.c:ldap_int_thread_pool_shutdown() needs this.  Could not
+ * use it for ldap_pvt_thread.h above because of its use of LDAP_P().
+ */
+#undef ldap_pvt_thread_pool_destroy
+#define        ldap_pvt_thread_pool_destroy(p,r) ldap_int_thread_pool_destroy(p,r)
+#endif
+
+#ifdef LDAP_THREAD_DEBUG_IMPLEMENTATION        /* thr_debug.c */
+#undef ldap_pvt_thread_mutex_t
+#undef ldap_pvt_thread_cond_t
+#undef ldap_pvt_thread_sleep
+#undef ldap_pvt_thread_get_concurrency
+#undef ldap_pvt_thread_set_concurrency
+#undef ldap_pvt_thread_create
+#undef ldap_pvt_thread_exit
+#undef ldap_pvt_thread_join
+#undef ldap_pvt_thread_kill
+#undef ldap_pvt_thread_yield
+#undef ldap_pvt_thread_cond_init
+#undef ldap_pvt_thread_cond_destroy
+#undef ldap_pvt_thread_cond_signal
+#undef ldap_pvt_thread_cond_broadcast
+#undef ldap_pvt_thread_cond_wait
+#undef ldap_pvt_thread_mutex_init
+#undef ldap_pvt_thread_mutex_destroy
+#undef ldap_pvt_thread_mutex_lock
+#undef ldap_pvt_thread_mutex_trylock
+#undef ldap_pvt_thread_mutex_unlock
+#undef ldap_pvt_thread_self
+/* LDAP_THREAD_RDWR_IMPLEMENTATION: */
+#undef ldap_pvt_thread_rdwr_t
+#undef ldap_pvt_thread_rdwr_init
+#undef ldap_pvt_thread_rdwr_destroy
+#undef ldap_pvt_thread_rdwr_rlock
+#undef ldap_pvt_thread_rdwr_rtrylock
+#undef ldap_pvt_thread_rdwr_runlock
+#undef ldap_pvt_thread_rdwr_wlock
+#undef ldap_pvt_thread_rdwr_wtrylock
+#undef ldap_pvt_thread_rdwr_wunlock
+#undef ldap_pvt_thread_rdwr_readers
+#undef ldap_pvt_thread_rdwr_writers
+#undef ldap_pvt_thread_rdwr_active
+/* LDAP_THREAD_POOL_IMPLEMENTATION: */
+#undef ldap_pvt_thread_pool_t
+#undef ldap_pvt_thread_pool_init
+#undef ldap_pvt_thread_pool_submit
+#undef ldap_pvt_thread_pool_maxthreads
+#undef ldap_pvt_thread_pool_backload
+#undef ldap_pvt_thread_pool_pause
+#undef ldap_pvt_thread_pool_resume
+#undef ldap_pvt_thread_pool_destroy
+#undef ldap_pvt_thread_pool_getkey
+#undef ldap_pvt_thread_pool_setkey
+#undef ldap_pvt_thread_pool_purgekey
+#undef ldap_pvt_thread_pool_context
+#undef ldap_pvt_thread_pool_context_reset
+#endif /* LDAP_THREAD_DEBUG_IMPLEMENTATION */
+
+#endif /* LDAP_THREAD_DEBUG */
index 5acf713e115c0f2aeb147581a717189c4ea7600c..bbae423bc638a2aa8a0da8fc9fb7b08055cb4b2e 100644 (file)
@@ -40,7 +40,9 @@
 #include <ac/time.h>
 
 #include "ldap-int.h"
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_RDWR_IMPLEMENTATION
+#include "ldap_thr_debug.h"  /* May rename the symbols defined below */
 
 /*
  * implementations that provide their own compatible 
@@ -439,6 +441,6 @@ int ldap_pvt_thread_rdwr_active(ldap_pvt_thread_rdwr_t *rwlock)
               ldap_pvt_thread_rdwr_writers(rwlock));
 }
 
-#endif /* LDAP_DEBUG */
+#endif /* LDAP_RDWR_DEBUG */
 
 #endif /* LDAP_THREAD_HAVE_RDWR */
index d81e0101b54d4320ada9655566be442cf7211606..83ba5aeb504f1b98ddbb49b1bc6d27d836767079 100644 (file)
@@ -20,7 +20,9 @@
 #include "portable.h"
 
 #if defined( HAVE_MACH_CTHREADS )
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#include "ldap_thr_debug.h"  /* May rename the symbols defined below */
 
 int
 ldap_int_thread_initialize( void )
diff --git a/libraries/libldap_r/thr_debug.c b/libraries/libldap_r/thr_debug.c
new file mode 100644 (file)
index 0000000..cc69b06
--- /dev/null
@@ -0,0 +1,1029 @@
+/* thr_debug.c - wrapper around the chosen thread wrapper, for debugging. */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 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 file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+/*
+ * This package provides three types of thread operation debugging:
+ *
+ * - Print error messages and abort() when thread operations fail:
+ *   Operations on threads, mutexes, condition variables, rdwr locks.
+ *   Some thread pool operations are also checked, but not those for
+ *   which failure can happen in normal slapd operation.
+ *
+ * - Wrap those types except threads and pools in structs that
+ *   contain a state variable or a pointer to dummy allocated memory,
+ *   and check that on all operations.  The dummy memory variant lets
+ *   malloc debuggers see some incorrect use as memory leaks, access
+ *   to freed memory, etc.
+ *
+ * - Print a count of leaked thread resources after cleanup.
+ *
+ * Compile-time (./configure) setup:  Macros defined in CPPFLAGS.
+ *
+ *   LDAP_THREAD_DEBUG or LDAP_THREAD_DEBUG=2
+ *      Enables debugging, but value & 2 turns off type wrapping.
+ *
+ *   LDAP_UINTPTR_T=integer type to hold pointers, preferably unsigned.
+ *      Used by dummy memory option "scramble". Default = unsigned long.
+ *
+ *   In addition, you may need to set up an implementation-specific way
+ *      to enable whatever error checking your thread library provides.
+ *      Currently only implemented for Posix threads (pthreads), where
+ *      you may need to define LDAP_INT_THREAD_MUTEXATTR.  The default
+ *      is PTHREAD_MUTEX_ERRORCHECK, or PTHREAD_MUTEX_ERRORCHECK_NP for
+ *      Linux threads.  See pthread_mutexattr_settype(3).
+ *
+ * Run-time configuration:  Environment variable LDAP_THREAD_DEBUG.
+ *
+ *   The variable may contain a comma- or space-separated option list.
+ *   Options:
+ *      off      - Disable this package.
+ *   Error checking:
+ *      noabort  - Do not abort() on errors.
+ *      noerror  - Do not report errors.  Implies noabort.
+ *      nocount  - Do not report counts of unreleased resources.
+ *   State variable/dummy memory, unless type wrapping is disabled:
+ *      noalloc  - Default.  Use a state variable, not dummy memory.
+ *      dupinit  - Implies noalloc.  Check if resources that have
+ *                 not been destroyed are reinitialized.  Tools that
+ *                 report uninitialized memory access should disable
+ *                 such warnings about debug_already_initialized().
+ *      alloc    - Allocate dummy memory and store pointers as-is.
+ *                 Malloc debuggers might not notice unreleased
+ *                 resources in global variables as memory leaks.
+ *      scramble - Store bitwise complement of dummy memory pointer.
+ *                 That never escapes memory leak detectors -
+ *                 but detection while the program is running will
+ *                 report active resources as leaks.  Do not
+ *                 use this if a garbage collector is in use:-)
+ *      adjptr   - Point to end of dummy memory.
+ *                 Purify reports these as "potential leaks" (PLK).
+ *                 I have not checked other malloc debuggers.
+ *   Tracing:
+ *      tracethreads - Report create/join/exit/kill of threads.
+ */
+
+#include "portable.h"
+
+#if defined( LDAP_THREAD_DEBUG )
+
+#include <stdio.h>
+#include <ac/errno.h>
+#include <ac/stdlib.h>
+#include <ac/string.h>
+
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#define LDAP_THREAD_DEBUG_IMPLEMENTATION
+#define LDAP_THREAD_RDWR_IMPLEMENTATION
+#define LDAP_THREAD_POOL_IMPLEMENTATION
+#include "ldap_thr_debug.h"  /* Get the underlying implementation */
+
+
+/* Options from environment variable $LDAP_THREAD_DEBUG */
+enum { Count_no = 0, Count_yes, Count_reported, Count_reported_more };
+static int nodebug, noabort, noerror, count = Count_yes, options_done;
+#ifdef LDAP_THREAD_DEBUG_WRAP
+enum { Wrap_noalloc, Wrap_alloc, Wrap_scramble, Wrap_adjptr };
+static int dupinit, wraptype = Wrap_noalloc, wrap_offset, unwrap_offset;
+#endif
+static int tracethreads;
+
+static int threading_enabled;
+
+enum {
+       Idx_unexited_thread, Idx_unjoined_thread, Idx_locked_mutex,
+       Idx_mutex, Idx_cond, Idx_rdwr, Idx_tpool, Idx_max
+};
+static int resource_counts[Idx_max];
+static const char *const resource_names[] = {
+       "unexited threads", "unjoined threads", "locked mutexes",
+       "mutexes", "conds", "rdwrs", "thread pools"
+};
+static ldap_int_thread_mutex_t resource_mutexes[Idx_max];
+
+
+/*
+ * Making ldap_pvt_thread_t a wrapper around ldap_int_thread_t would
+ * slow down ldap_pvt_thread_self(), so keep a list of threads instead.
+ */
+typedef struct ldap_debug_thread_s {
+       ldap_pvt_thread_t                       wrapped;
+       ldap_debug_usage_info_t         usage;
+       int                                                     detached;
+       int                                                     freeme, idx;
+} ldap_debug_thread_t;
+
+static ldap_debug_thread_t             **thread_info;
+static unsigned int                            thread_info_size, thread_info_used;
+static ldap_int_thread_mutex_t thread_info_mutex;
+
+
+#define WARN(var, msg)   (warn (__FILE__, __LINE__, (msg), #var, (var)))
+#define ERROR(var,msg)   (error(__FILE__, __LINE__, (msg), #var, (var)))
+#define WARN_IF(rc, msg) {if (rc) warn (__FILE__, __LINE__, (msg), #rc, (rc));}
+#define ERROR_IF(rc,msg) {if (rc) error(__FILE__, __LINE__, (msg), #rc, (rc));}
+
+#if 0
+static void
+warn( const char *file, int line, const char *msg, const char *var, int val )
+{
+       fprintf( stderr, "%s:%d: %s warning: %s is %d\n",
+               file, line, msg, var, val );
+}
+#endif
+
+static void
+error( const char *file, int line, const char *msg, const char *var, int val )
+{
+       if( !noerror ) {
+               fprintf( stderr, "%s:%d: %s error: %s is %d\n",
+                       file, line, msg, var, val );
+               if( !noabort )
+                       abort();
+       }
+}
+
+static void
+count_resource_leaks( void )
+{
+       int i, j;
+       char errbuf[200], *delim = "Leaked";
+       if( count == Count_yes ) {
+               count = Count_reported;
+#if 0 /* Could break if there are still threads after atexit */
+               for( i = j = 0; i < Idx_max; i++ )
+                       j |= ldap_int_thread_mutex_destroy( &resource_mutexes[i] );
+               WARN_IF( j, "ldap_debug_thread_destroy:mutexes" );
+#endif
+               for( i = j = 0; i < Idx_max; i++ ) {
+                       if( resource_counts[i] ) {
+                               j += sprintf( errbuf + j, "%s %d %s",
+                                       delim, resource_counts[i], resource_names[i] );
+                               delim = ",";
+                       }
+               }
+               if( j )
+                       fprintf( stderr, "%s:%d: %s.\n", __FILE__, __LINE__, errbuf );
+       }
+}
+
+static void
+get_options( void )
+{
+       static const struct option_info_s {
+               const char      *name;
+               int             *var, val;
+       } option_info[] = {
+               { "off",        &nodebug,  1 },
+               { "noabort",    &noabort,  1 },
+               { "noerror",    &noerror,  1 },
+               { "nocount",    &count,    Count_no },
+#ifdef LDAP_THREAD_DEBUG_WRAP
+               { "noalloc",    &wraptype, Wrap_noalloc },
+               { "dupinit",    &dupinit,  1 },
+               { "alloc",      &wraptype, Wrap_alloc },
+               { "adjptr",     &wraptype, Wrap_adjptr },
+               { "scramble",   &wraptype, Wrap_scramble },
+#endif
+               { "tracethreads", &tracethreads, 1 },
+               { NULL, NULL, 0 }
+       };
+       const char *s = getenv( "LDAP_THREAD_DEBUG" );
+       if( s != NULL ) {
+               while( *(s += strspn( s, ", \t\r\n" )) != '\0' ) {
+                       size_t optlen = strcspn( s, ", \t\r\n" );
+                       const struct option_info_s *oi;
+                       for( oi = option_info; oi->name; oi++ ) {
+                               if( strncasecmp( oi->name, s, optlen ) == 0 ) {
+                                       if( oi->name && oi->name[optlen] == '\0' ) {
+                                               *oi->var = oi->val;
+                                       } else {
+                                               fprintf( stderr, "Unknown $%s option '%.*s'\n",
+                                                       "LDAP_THREAD_DEBUG", (int) optlen, s );
+                                       }
+                                       break;
+                               }
+                       }
+                       s += optlen;
+               }
+       }
+       if( nodebug ) {
+               noabort = noerror = 1;
+               tracethreads = dupinit = 0;
+               count = Count_no;
+       }
+#ifdef LDAP_THREAD_DEBUG_WRAP
+       if( nodebug || dupinit ) {
+               wraptype = Wrap_noalloc;
+       } else if( wraptype == Wrap_scramble ) {
+               const unsigned char *dummy = (const unsigned char *)&option_info;
+               if( sizeof(LDAP_UINTPTR_T) < sizeof(void *)
+                       || (unsigned char *)~~(LDAP_UINTPTR_T) dummy != dummy
+                       || (unsigned char *)~~(LDAP_UINTPTR_T) (unsigned char *)0 )
+               {
+                       fprintf( stderr, "Misconfigured for $%s %s.  Using %s.\n",
+                               "LDAP_THREAD_DEBUG", "scramble", "adjptr" );
+                       wraptype = Wrap_adjptr;
+               }
+       }
+       unwrap_offset = -(wrap_offset = (wraptype == Wrap_adjptr));
+#endif
+       options_done = 1;
+}
+
+
+static char *
+thread_name( char *buf, int bufsize, ldap_pvt_thread_t thread )
+{
+       int i;
+       --bufsize;
+       if( bufsize > 2*sizeof(thread) )
+               bufsize = 2*sizeof(thread);
+       for( i = 0; i < bufsize; i += 2 )
+               snprintf( buf+i, 3, "%02x", ((unsigned char *)&thread)[i/2] );
+       return buf;
+}
+
+static void
+exit_thread_message( const ldap_pvt_thread_t thread )
+{
+       if( tracethreads ) {
+               char buf[40];
+               fprintf( stderr, "== Exiting thread %s ==\n",
+                       thread_name( buf, sizeof(buf), thread ) );
+       }
+}
+
+
+#ifndef LDAP_THREAD_DEBUG_WRAP
+
+#define        WRAPPED(ptr)                    (ptr)
+#define alloc_usage(ptr, msg)  ((void) 0)
+#define check_usage(ptr, msg)  ((void) 0)
+#define free_usage(ptr, msg)   ((void) 0)
+
+#define with_threads_lock(statement)   { statement; }
+#define get_new_thread_info(msg)               NULL
+#define update_thread_info(ti, th, det)        {}
+#define remove_thread_info(ti, msg)            ((void)0)
+#define get_thread_info(thread, msg)   NULL
+#define exiting_thread(msg)    exit_thread_message(ldap_pvt_thread_self())
+
+#else /* LDAP_THREAD_DEBUG_WRAP */
+
+#define        WRAPPED(ptr)                    (&(ptr)->wrapped)
+
+#define INITED_VALUE           0x12345678UL
+#define INITED_BYTE_VALUE      0xd5
+
+static int
+debug_already_initialized( const LDAP_UINTPTR_T *num )
+{
+       /* Valid programs will access uninitialized memory if dupinit */
+       return dupinit && *num == INITED_VALUE;
+}
+
+static void
+alloc_usage( ldap_debug_usage_info_t *usage, const char *msg )
+{
+       if( !options_done )
+               get_options();
+       if( wraptype == Wrap_noalloc ) {
+               ERROR_IF( debug_already_initialized( &usage->num ), msg );
+               usage->num = INITED_VALUE;
+       } else {
+               unsigned char *dummy = malloc( 1 );
+               assert( dummy != NULL );
+               *dummy = INITED_BYTE_VALUE;
+               if( wraptype == Wrap_scramble ) {
+                       usage->num = ~(LDAP_UINTPTR_T) dummy;
+                       assert( (unsigned char *)~usage->num == dummy );
+               } else {
+                       usage->ptr = dummy + wrap_offset;
+               }
+       }
+}
+
+static void
+check_usage( ldap_debug_usage_info_t *usage, const char *msg )
+{
+       if( wraptype == Wrap_noalloc ) {
+               ERROR_IF( usage->num != INITED_VALUE, msg );
+       } else if( wraptype == Wrap_scramble ) {
+               ERROR_IF( !usage->num, msg );
+               ERROR_IF( *(unsigned char *)~usage->num != INITED_BYTE_VALUE, msg );
+       } else {
+               ERROR_IF( !usage->ptr, msg );
+               ERROR_IF( usage->ptr[unwrap_offset] != INITED_BYTE_VALUE, msg );
+       }
+}
+
+static void
+free_usage( ldap_debug_usage_info_t *usage, const char *msg )
+{
+       if( wraptype == Wrap_noalloc ) {
+               usage->num = ~(LDAP_UINTPTR_T)INITED_VALUE;
+       } else {
+               unsigned char *dummy = (wraptype == Wrap_scramble
+                                       ? (unsigned char *)~usage->num
+                                       : usage->ptr + unwrap_offset);
+               *(volatile unsigned char *)dummy = (unsigned char)-1;
+               free( dummy );
+       }
+}
+
+#define with_threads_lock(statement) { \
+       if( !nodebug ) { \
+               int rc_wtl_ = ldap_int_thread_mutex_lock( &thread_info_mutex ); \
+               assert( rc_wtl_ == 0 ); \
+       } \
+    statement; \
+       if( !nodebug ) { \
+               int rc_wtl_ = ldap_int_thread_mutex_unlock( &thread_info_mutex ); \
+               assert( rc_wtl_ == 0 ); \
+       } \
+}
+
+static ldap_debug_thread_t *
+get_new_thread_info( const char *msg )
+{
+       if( nodebug )
+               return NULL;
+       if( thread_info_used >= thread_info_size ) {
+               unsigned int more = thread_info_size + 1; /* debug value. increase. */
+               unsigned int new_size = thread_info_size + more;
+               ldap_debug_thread_t *t = calloc( more, sizeof(ldap_debug_thread_t) );
+               assert( t != NULL );
+               t->freeme = 1;
+               thread_info = realloc( thread_info, new_size * sizeof(*thread_info) );
+               assert( thread_info != NULL );
+               while( thread_info_size < new_size ) {
+                       t->idx = thread_info_size;
+                       thread_info[thread_info_size++] = t++;
+               }
+       }
+       alloc_usage( &thread_info[thread_info_used]->usage, msg );
+       return thread_info[thread_info_used++];
+}
+
+static void
+update_thread_info(
+       ldap_debug_thread_t *t,
+       const ldap_pvt_thread_t *thread,
+       int detached )
+{
+       if( !nodebug ) {
+               t->wrapped = *thread;
+               t->detached = detached;
+       }
+}
+
+static void
+remove_thread_info( ldap_debug_thread_t *t, const char *msg )
+{
+       if( !nodebug ) {
+               ldap_debug_thread_t *last;
+               int idx;
+               free_usage( &t->usage, msg );
+               idx = t->idx;
+               assert( thread_info[idx] == t );
+               last = thread_info[--thread_info_used];
+               assert( last->idx == thread_info_used );
+               (thread_info[idx]              = last)->idx = idx;
+               (thread_info[thread_info_used] = t   )->idx = thread_info_used;
+       }
+}
+
+ldap_debug_thread_t *
+get_thread_info( ldap_pvt_thread_t *thread, const char *msg )
+{
+       unsigned int i;
+       ldap_debug_thread_t *t;
+       if( nodebug )
+               return NULL;
+       for( i = 0; i < thread_info_used; i++ ) {
+               if( ldap_pvt_thread_equal( *thread, thread_info[i]->wrapped ) )
+                       break;
+       }
+       ERROR_IF( i == thread_info_used, msg );
+       t = thread_info[i];
+       check_usage( &t->usage, msg );
+       return t;
+}
+
+static void
+exiting_thread( const char *msg )
+{
+       if( !nodebug ) {
+               ldap_pvt_thread_t thread;
+               thread = ldap_pvt_thread_self();
+               exit_thread_message( thread );
+               with_threads_lock({
+                       ldap_debug_thread_t *t = get_thread_info( &thread, msg );
+                       if( t->detached )
+                               remove_thread_info( t, msg );
+               });
+       }
+}
+
+#endif /* LDAP_THREAD_DEBUG_WRAP */
+
+
+static void
+adjust_count( int which, int adjust )
+{
+       int rc;
+       switch( count ) {
+       case Count_no:
+               break;
+       case Count_yes:
+               rc = ldap_int_thread_mutex_lock( &resource_mutexes[which] );
+               assert( rc == 0 );
+               resource_counts[which] += adjust;
+               rc = ldap_int_thread_mutex_unlock( &resource_mutexes[which] );
+               assert( rc == 0 );
+       case Count_reported:
+               fputs( "...more ldap_debug_thread activity after exit...\n", stderr );
+               count = Count_reported_more;
+               /* FALL THROUGH */
+       case Count_reported_more:
+               /* Not used, but result might be inspected with debugger */
+               /* (Hopefully threading is disabled by now...) */
+               resource_counts[which] += adjust;
+               break;
+       }
+}
+
+
+/* Wrappers for LDAP_THREAD_IMPLEMENTATION: */
+
+/* Used instead of ldap_int_thread_initialize by ldap_pvt_thread_initialize */
+int
+ldap_debug_thread_initialize( void )
+{
+       int i, rc, rc2;
+       if( !options_done )
+               get_options();
+       ERROR_IF( threading_enabled, "ldap_debug_thread_initialize" );
+       threading_enabled = 1;
+       rc = ldap_int_thread_initialize();
+       if( rc ) {
+               ERROR( rc, "ldap_debug_thread_initialize:threads" );
+               threading_enabled = 0;
+       } else {
+               rc2 = ldap_int_thread_mutex_init( &thread_info_mutex );
+               assert( rc2 == 0 );
+               if( count != Count_no ) {
+                       for( i = rc2 = 0; i < Idx_max; i++ )
+                               rc2 |= ldap_int_thread_mutex_init( &resource_mutexes[i] );
+                       assert( rc2 == 0 );
+                       /* FIXME: Only for static libldap_r as in init.c? If so, why? */
+                       atexit( count_resource_leaks );
+               }
+       }
+       return rc;
+}
+
+/* Used instead of ldap_int_thread_destroy by ldap_pvt_thread_destroy */
+int
+ldap_debug_thread_destroy( void )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_debug_thread_destroy" );
+       /* sleep(1) -- need to wait for thread pool to finish? */
+       rc = ldap_int_thread_destroy();
+       if( rc ) {
+               ERROR( rc, "ldap_debug_thread_destroy:threads" );
+       } else {
+               threading_enabled = 0;
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_set_concurrency( int n )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_set_concurrency" );
+       rc = ldap_int_thread_set_concurrency( n );
+       ERROR_IF( rc, "ldap_pvt_thread_set_concurrency" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_get_concurrency( void )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_get_concurrency" );
+       rc = ldap_int_thread_get_concurrency();
+       ERROR_IF( rc, "ldap_pvt_thread_get_concurrency" );
+       return rc;
+}
+
+unsigned int
+ldap_pvt_thread_sleep( unsigned int interval )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_sleep" );
+       rc = ldap_int_thread_sleep( interval );
+       ERROR_IF( rc, "ldap_pvt_thread_sleep" );
+       return 0;
+}
+
+int
+ldap_pvt_thread_create(
+       ldap_pvt_thread_t *thread,
+       int detach,
+       void *(*start_routine)( void * ),
+       void *arg )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_create" );
+       if( !options_done )
+               get_options();
+       with_threads_lock({
+               ldap_debug_thread_t *t;
+               t = get_new_thread_info( "ldap_pvt_thread_create" );
+               rc = ldap_int_thread_create( thread, detach, start_routine, arg );
+               if( rc ) {
+                       ERROR( rc, "ldap_pvt_thread_create" );
+                       remove_thread_info( t, "ldap_pvt_thread_init" );
+               } else {
+                       update_thread_info( t, thread, detach );
+               }
+       });
+       if( rc == 0 ) {
+               if( tracethreads ) {
+                       char buf[40];
+                       fprintf( stderr, "== Created thread %s%s ==\n",
+                               thread_name( buf, sizeof(buf), *thread ),
+                               detach ? " (detached)" : "" );
+               }
+               adjust_count( Idx_unexited_thread, +1 );
+               if( !detach )
+                       adjust_count( Idx_unjoined_thread, +1 );
+       }
+       return rc;
+}
+
+void
+ldap_pvt_thread_exit( void *retval )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_exit" );
+       adjust_count( Idx_unexited_thread, -1 );
+       exiting_thread( "ldap_pvt_thread_exit" );
+       ldap_int_thread_exit( retval );
+}
+
+int
+ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
+{
+       int rc;
+       ldap_debug_thread_t *t;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_join" );
+       if( tracethreads ) {
+               char buf[40];
+               fprintf( stderr, "== Joining thread %s ==\n",
+                       thread_name( buf, sizeof(buf), thread ) );
+       }
+       with_threads_lock(
+               t = get_thread_info( &thread, "ldap_pvt_thread_join" ) );
+       rc = ldap_int_thread_join( thread, thread_return );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_join" );
+       } else {
+               with_threads_lock(
+                       remove_thread_info( t, "ldap_pvt_thread_join" ) );
+               adjust_count( Idx_unjoined_thread, -1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_kill" );
+       if( tracethreads ) {
+               char buf[40];
+               fprintf( stderr, "== Killing thread %s (sig %i) ==\n",
+                       thread_name( buf, sizeof(buf), thread ), signo );
+       }
+       rc = ldap_int_thread_kill( thread, signo );
+       ERROR_IF( rc, "ldap_pvt_thread_kill" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_yield( void )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_yield" );
+       rc = ldap_int_thread_yield();
+       ERROR_IF( rc, "ldap_pvt_thread_yield" );
+       return rc;
+}
+
+ldap_pvt_thread_t
+ldap_pvt_thread_self( void )
+{
+#if 0 /* Function is used by ch_free() via slap_sl_contxt() in slapd */
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_self" );
+#endif
+       return ldap_int_thread_self();
+}
+
+int
+ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
+{
+       int rc;
+       alloc_usage( &cond->usage, "ldap_pvt_thread_cond_init" );
+       rc = ldap_int_thread_cond_init( WRAPPED( cond ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_cond_init" );
+               free_usage( &cond->usage, "ldap_pvt_thread_cond_init" );
+       } else {
+               adjust_count( Idx_cond, +1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond )
+{
+       int rc;
+       check_usage( &cond->usage, "ldap_pvt_thread_cond_destroy" );
+       rc = ldap_int_thread_cond_destroy( WRAPPED( cond ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_cond_destroy" );
+       } else {
+               free_usage( &cond->usage, "ldap_pvt_thread_cond_destroy" );
+               adjust_count( Idx_cond, -1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
+{
+       int rc;
+       check_usage( &cond->usage, "ldap_pvt_thread_cond_signal" );
+       rc = ldap_int_thread_cond_signal( WRAPPED( cond ) );
+       ERROR_IF( rc, "ldap_pvt_thread_cond_signal" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
+{
+       int rc;
+       check_usage( &cond->usage, "ldap_pvt_thread_cond_broadcast" );
+       rc = ldap_int_thread_cond_broadcast( WRAPPED( cond ) );
+       ERROR_IF( rc, "ldap_pvt_thread_cond_broadcast" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_cond_wait(
+       ldap_pvt_thread_cond_t *cond,
+       ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       check_usage( &cond->usage, "ldap_pvt_thread_cond_wait:cond" );
+       check_usage( &mutex->usage, "ldap_pvt_thread_cond_wait:mutex" );
+       adjust_count( Idx_locked_mutex, -1 );
+       rc = ldap_int_thread_cond_wait( WRAPPED( cond ), WRAPPED( mutex ) );
+       adjust_count( Idx_locked_mutex, +1 );
+       ERROR_IF( rc, "ldap_pvt_thread_cond_wait" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       alloc_usage( &mutex->usage, "ldap_pvt_thread_mutex_init" );
+       rc = ldap_int_thread_mutex_init( WRAPPED( mutex ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_mutex_init" );
+               free_usage( &mutex->usage, "ldap_pvt_thread_mutex_init" );
+       } else {
+               adjust_count( Idx_mutex, +1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       check_usage( &mutex->usage, "ldap_pvt_thread_mutex_destroy" );
+       rc = ldap_int_thread_mutex_destroy( WRAPPED( mutex ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_mutex_destroy" );
+       } else {
+               free_usage( &mutex->usage, "ldap_pvt_thread_mutex_destroy" );
+               adjust_count( Idx_mutex, -1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       check_usage( &mutex->usage, "ldap_pvt_thread_mutex_lock" );
+       rc = ldap_int_thread_mutex_lock( WRAPPED( mutex ) );
+       if( rc ) {
+               ERROR_IF( rc, "ldap_pvt_thread_mutex_lock" );
+       } else {
+               adjust_count( Idx_locked_mutex, +1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       check_usage( &mutex->usage, "ldap_pvt_thread_mutex_trylock" );
+       rc = ldap_int_thread_mutex_trylock( WRAPPED( mutex ) );
+       if( rc == 0 )
+               adjust_count( Idx_locked_mutex, +1 );
+       return rc;
+}
+
+int
+ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       check_usage( &mutex->usage, "ldap_pvt_thread_mutex_unlock" );
+       rc = ldap_int_thread_mutex_unlock( WRAPPED( mutex ) );
+       if( rc ) {
+               ERROR_IF( rc, "ldap_pvt_thread_mutex_unlock" );
+       } else {
+               adjust_count( Idx_locked_mutex, -1 );
+       }
+       return rc;
+}
+
+
+/* Wrappers for LDAP_THREAD_RDWR_IMPLEMENTATION: */
+
+int
+ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       alloc_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_init" );
+       rc = ldap_int_thread_rdwr_init( WRAPPED( rwlock ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_rdwr_init" );
+               free_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_init" );
+       } else {
+               adjust_count( Idx_rdwr, +1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_destroy" );
+       rc = ldap_int_thread_rdwr_destroy( WRAPPED( rwlock ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_rdwr_destroy" );
+       } else {
+               free_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_destroy" );
+               adjust_count( Idx_rdwr, -1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_rlock" );
+       rc = ldap_int_thread_rdwr_rlock( WRAPPED( rwlock ) );
+       ERROR_IF( rc, "ldap_pvt_thread_rdwr_rlock" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_rtrylock" );
+       return ldap_int_thread_rdwr_rtrylock( WRAPPED( rwlock ) );
+}
+
+int
+ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_runlock" );
+       rc = ldap_int_thread_rdwr_runlock( WRAPPED( rwlock ) );
+       ERROR_IF( rc, "ldap_pvt_thread_rdwr_runlock" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_wlock" );
+       rc = ldap_int_thread_rdwr_wlock( WRAPPED( rwlock ) );
+       ERROR_IF( rc, "ldap_pvt_thread_rdwr_wlock" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_wtrylock" );
+       return ldap_int_thread_rdwr_wtrylock( WRAPPED( rwlock ) );
+}
+
+int
+ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_wunlock" );
+       rc = ldap_int_thread_rdwr_wunlock( WRAPPED( rwlock ) );
+       ERROR_IF( rc, "ldap_pvt_thread_rdwr_wunlock" );
+       return rc;
+}
+
+#ifdef LDAP_RDWR_DEBUG
+
+int
+ldap_pvt_thread_rdwr_readers( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_readers" );
+       return ldap_int_thread_rdwr_readers( WRAPPED( rwlock ) );
+}
+
+int
+ldap_pvt_thread_rdwr_writers( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_writers" );
+       return ldap_int_thread_rdwr_writers( WRAPPED( rwlock ) );
+}
+
+int
+ldap_pvt_thread_rdwr_active( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_active" );
+       return ldap_int_thread_rdwr_active( WRAPPED( rwlock ) );
+}
+
+#endif /* LDAP_RDWR_DEBUG */
+
+
+/* Some wrappers for LDAP_THREAD_POOL_IMPLEMENTATION: */
+#ifdef LDAP_THREAD_POOL_IMPLEMENTATION
+
+int
+ldap_pvt_thread_pool_init(
+       ldap_pvt_thread_pool_t *tpool,
+       int max_threads,
+       int max_pending )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_init" );
+       rc = ldap_int_thread_pool_init( tpool, max_threads, max_pending );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_pool_init" );
+       } else {
+               adjust_count( Idx_tpool, +1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_pool_submit(
+       ldap_pvt_thread_pool_t *tpool,
+       ldap_pvt_thread_start_t *start_routine, void *arg )
+{
+       int rc, has_pool;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_submit" );
+       has_pool = (tpool != NULL && *tpool != NULL);
+       rc = ldap_int_thread_pool_submit( tpool, start_routine, arg );
+       if( has_pool )
+               ERROR_IF( rc, "ldap_pvt_thread_pool_submit" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_pool_maxthreads(
+       ldap_pvt_thread_pool_t *tpool,
+       int max_threads )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_maxthreads" );
+       return ldap_int_thread_pool_maxthreads( tpool, max_threads );
+}
+
+int
+ldap_pvt_thread_pool_backload( ldap_pvt_thread_pool_t *tpool )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_backload" );
+       return ldap_int_thread_pool_backload( tpool );
+}
+
+int
+ldap_pvt_thread_pool_destroy( ldap_pvt_thread_pool_t *tpool, int run_pending )
+{
+       int rc, has_pool;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_destroy" );
+       has_pool = (tpool != NULL && *tpool != NULL);
+       rc = ldap_int_thread_pool_destroy( tpool, run_pending );
+       if( has_pool ) {
+               if( rc ) {
+                       ERROR( rc, "ldap_pvt_thread_pool_destroy" );
+               } else {
+                       adjust_count( Idx_tpool, -1 );
+               }
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_pool_pause( ldap_pvt_thread_pool_t *tpool )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_pause" );
+       return ldap_int_thread_pool_pause( tpool );
+}
+
+int
+ldap_pvt_thread_pool_resume( ldap_pvt_thread_pool_t *tpool )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_resume" );
+       return ldap_int_thread_pool_resume( tpool );
+}
+
+int
+ldap_pvt_thread_pool_getkey(
+       void *xctx,
+       void *key,
+       void **data,
+       ldap_pvt_thread_pool_keyfree_t **kfree )
+{
+#if 0 /* Function is used by ch_free() via slap_sl_contxt() in slapd */
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_getkey" );
+#endif
+       return ldap_int_thread_pool_getkey( xctx, key, data, kfree );
+}
+
+int
+ldap_pvt_thread_pool_setkey(
+       void *xctx,
+       void *key,
+       void *data,
+       ldap_pvt_thread_pool_keyfree_t *kfree )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_setkey" );
+       rc = ldap_int_thread_pool_setkey( xctx, key, data, kfree );
+       ERROR_IF( rc, "ldap_pvt_thread_pool_setkey" );
+       return rc;
+}
+
+void
+ldap_pvt_thread_pool_purgekey( void *key )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_purgekey" );
+       ldap_int_thread_pool_purgekey( key );
+}
+
+void *
+ldap_pvt_thread_pool_context( void )
+{
+#if 0 /* Function is used by ch_free() via slap_sl_contxt() in slapd */
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_context" );
+#endif
+       return ldap_int_thread_pool_context();
+}
+
+void
+ldap_pvt_thread_pool_context_reset( void *vctx )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_context_reset" );
+       ldap_int_thread_pool_context_reset( vctx );
+}
+
+#endif /* LDAP_THREAD_POOL_IMPLEMENTATION */
+
+#endif /* LDAP_THREAD_DEBUG */
index 6d66e391365605157287bec7befd0fa8aa12ff72..be72e98976e3b68f952033baea9e9f416302401f 100644 (file)
@@ -38,7 +38,9 @@
 
 #include "ldap-int.h"
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#include "ldap_thr_debug.h"     /* May rename the symbols defined below */
 
 #include <lwp/lwp.h>
 #include <lwp/stackdep.h>
@@ -67,7 +69,7 @@ ldap_int_thread_initialize( void )
 int
 ldap_int_thread_destroy( void )
 {
-       /* need to destory lwp_scheduler thread and clean up private
+       /* need to destroy lwp_scheduler thread and clean up private
                variables */
        return 0;
 }
@@ -311,7 +313,7 @@ ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
 
 int 
 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
-       ldap_int_thread_mutex_t *mutex )
+       ldap_pvt_thread_mutex_t *mutex )
 {
        if ( ! cond->lcv_created ) {
                cv_create( &cond->lcv_cv, *mutex );
index 24a7a8d4ae431b5dd029ccbdf37fb450acdb058f..8953f4bdafc49f54a8fc8ae03b56ad558caf31b9 100644 (file)
@@ -18,7 +18,9 @@
 
 #if defined( HAVE_NT_THREADS )
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#include "ldap_thr_debug.h"     /* May rename the symbols defined below */
 
 typedef struct ldap_int_thread_s {
        long tid;
index 0d353206fafca11a6cd67ebbad8ba16288c1d20a..cb964d982d4db72329132b0c1a36d4297608a8de 100644 (file)
 
 #include <ac/errno.h>
 
-#include "ldap_pvt_thread.h"
-
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#define LDAP_THREAD_RDWR_IMPLEMENTATION
+#include "ldap_thr_debug.h"     /* May rename the symbols defined below */
 
 #if HAVE_PTHREADS < 6
 #  define LDAP_INT_THREAD_ATTR_DEFAULT         pthread_attr_default
 #else
 #  define LDAP_INT_THREAD_ATTR_DEFAULT         NULL
 #  define LDAP_INT_THREAD_CONDATTR_DEFAULT     NULL
-#  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT    NULL
+#  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT NULL
 #endif
 
+#ifdef LDAP_THREAD_DEBUG
+#  if defined LDAP_INT_THREAD_MUTEXATTR        /* May be defined in CPPFLAGS */
+#  elif defined HAVE_PTHREAD_KILL_OTHER_THREADS_NP
+        /* LinuxThreads hack */
+#    define LDAP_INT_THREAD_MUTEXATTR  PTHREAD_MUTEX_ERRORCHECK_NP
+#  else
+#    define LDAP_INT_THREAD_MUTEXATTR  PTHREAD_MUTEX_ERRORCHECK
+#  endif
+static pthread_mutexattr_t mutex_attr;
+#  undef  LDAP_INT_THREAD_MUTEXATTR_DEFAULT
+#  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT &mutex_attr
+#endif
 
 int
 ldap_int_thread_initialize( void )
 {
+#ifdef LDAP_INT_THREAD_MUTEXATTR
+       pthread_mutexattr_init( &mutex_attr );
+       pthread_mutexattr_settype( &mutex_attr, LDAP_INT_THREAD_MUTEXATTR );
+#endif
        return 0;
 }
 
@@ -46,6 +64,9 @@ ldap_int_thread_destroy( void )
 #ifdef HAVE_PTHREAD_KILL_OTHER_THREADS_NP
        /* LinuxThreads: kill clones */
        pthread_kill_other_threads_np();
+#endif
+#ifdef LDAP_INT_THREAD_MUTEXATTR
+       pthread_mutexattr_destroy( &mutex_attr );
 #endif
        return 0;
 }
@@ -407,7 +428,7 @@ int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
 #endif
 }
 
-#endif /* HAVE_PTHREAD_RDLOCK_DESTROY */
+#endif /* HAVE_PTHREAD_RWLOCK_DESTROY */
 #endif /* LDAP_THREAD_HAVE_RDWR */
 #endif /* HAVE_PTHREADS */
 
index 9b413ebd1519353cb0ce914b99822517885d7b26..2d6012ba96361ba4b2340e29dcd6b30802894820 100644 (file)
 
 #if defined( HAVE_GNU_PTH )
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#define LDAP_THREAD_RDWR_IMPLEMENTATION
+#include "ldap_thr_debug.h"     /* May rename the symbols defined below */
+
 #include <errno.h>
 
 /*******************
index ee65e6779067a06714603ccad643b7ed3a5c65ea..c4db69659ad149d20ef8afd497818d66f04dd56a 100644 (file)
 
 #if defined( NO_THREADS )
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#define LDAP_THREAD_POOL_IMPLEMENTATION
+#include "ldap_thr_debug.h"  /* May rename the symbols defined below */
 
 /***********************************************************************
  *                                                                     *
@@ -216,6 +219,10 @@ void *ldap_pvt_thread_pool_context( )
        return(NULL);
 }
 
+void ldap_pvt_thread_pool_context_reset( void *vctx )
+{
+}
+
 ldap_pvt_thread_t
 ldap_pvt_thread_self( void )
 {
index e609365447c5c0f4f36cffc2bc868dcad893d967..edbd78a3499845d5c2f8cf606f72ef65b7e27b99 100644 (file)
@@ -18,7 +18,9 @@
 
 #if defined( HAVE_THR )
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#include "ldap_thr_debug.h"     /* May rename the symbols defined below */
 
 /*******************
  *                 *
index d19400b971abe62ab6bbc430b9640c0c0c884848..e2ae4e5211968c66c6b6a04bcd463c048c4f6e1f 100644 (file)
@@ -22,7 +22,8 @@
 #include <ac/string.h>
 #include <ac/unistd.h>
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#include "ldap_thr_debug.h"  /* May redirect thread initialize/destroy calls */
 
 
 /*
@@ -60,6 +61,15 @@ int ldap_pvt_thread_destroy( void )
        return ldap_int_thread_destroy();
 }
 
+
+/*
+ * Default implementations of some LDAP thread routines
+ */
+
+#define LDAP_THREAD_IMPLEMENTATION
+#include "ldap_thr_debug.h"    /* May rename the symbols defined below */
+
+
 #ifndef LDAP_THREAD_HAVE_GETCONCURRENCY
 int
 ldap_pvt_thread_get_concurrency ( void )
index d65d9c40b6d3f2cdf00043b96b492f9869a3b737..ba87eaa989175049c9d5c7e465577e32085e20e1 100644 (file)
 #include <ac/errno.h>
 
 #include "ldap-int.h"
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
 #include "ldap_queue.h"
+#define LDAP_THREAD_POOL_IMPLEMENTATION
+#include "ldap_thr_debug.h"  /* May rename symbols defined below */
 
 #ifndef LDAP_THREAD_HAVE_TPOOL
 
@@ -50,11 +52,6 @@ typedef struct ldap_int_thread_key_s {
 
 static ldap_pvt_thread_t tid_zero;
 
-#ifdef HAVE_PTHREADS
-#define        TID_EQ(a,b)     pthread_equal((a),(b))
-#else
-#define        TID_EQ(a,b)     ((a) == (b))
-#endif
 static struct {
        ldap_pvt_thread_t id;
        ldap_int_thread_key_t *ctx;
@@ -115,7 +112,7 @@ ldap_int_thread_pool_shutdown ( void )
 
        while ((pool = LDAP_STAILQ_FIRST(&ldap_int_thread_pool_list)) != NULL) {
                LDAP_STAILQ_REMOVE_HEAD(&ldap_int_thread_pool_list, ltp_next);
-               ldap_pvt_thread_pool_destroy( &pool, 0);
+               (ldap_pvt_thread_pool_destroy)(&pool, 0); /* ignore thr_debug macro */
        }
        ldap_pvt_thread_mutex_destroy(&ldap_pvt_thread_pool_mutex);
        return(0);
@@ -277,7 +274,7 @@ ldap_pvt_thread_pool_submit (
                         */
                        TID_HASH(thr, hash);
                        for (rc = hash & (LDAP_MAXTHR-1);
-                               !TID_EQ(thread_keys[rc].id, tid_zero);
+                               !ldap_pvt_thread_equal(thread_keys[rc].id, tid_zero);
                                rc = (rc+1) & (LDAP_MAXTHR-1));
                        thread_keys[rc].id = thr;
                } else {
@@ -437,7 +434,8 @@ ldap_int_thread_pool_wrapper (
 
        /* store pointer to our keys */
        TID_HASH(tid, hash);
-       for (i = hash & (LDAP_MAXTHR-1); !TID_EQ(thread_keys[i].id, tid);
+       for (i = hash & (LDAP_MAXTHR-1);
+                               !ldap_pvt_thread_equal(thread_keys[i].id, tid);
                                i = (i+1) & (LDAP_MAXTHR-1));
        thread_keys[i].ctx = ltc_key;
        keyslot = i;
@@ -661,12 +659,14 @@ void *ldap_pvt_thread_pool_context( )
        int i, hash;
 
        tid = ldap_pvt_thread_self();
-       if ( TID_EQ( tid, ldap_int_main_tid ))
+       if ( ldap_pvt_thread_equal( tid, ldap_int_main_tid ))
                return ldap_int_main_thrctx;
 
        TID_HASH( tid, hash );
-       for (i = hash & (LDAP_MAXTHR-1); !TID_EQ(thread_keys[i].id, tid_zero) &&
-               !TID_EQ(thread_keys[i].id, tid); i = (i+1) & (LDAP_MAXTHR-1));
+       for (i = hash & (LDAP_MAXTHR-1);
+               !ldap_pvt_thread_equal(thread_keys[i].id, tid_zero) &&
+               !ldap_pvt_thread_equal(thread_keys[i].id, tid);
+               i = (i+1) & (LDAP_MAXTHR-1));
 
        return thread_keys[i].ctx;
 }
index 48c95a54ced3f7d05fa8d74a1cb17aa7ef13f4e0..59b5cae7c5a1c03e17d6b69c1a5d5b102fea087e 100644 (file)
@@ -43,7 +43,7 @@ ucgendat: $(XLIBS) ucgendat.o
        done
        touch .links
 
-$(XXSRCS) : .links
+$(XXSRCS) $(XXHEADERS) : .links
 
 clean-local: FORCE
        @$(RM) *.dat .links $(XXHEADERS) ucgendat
index 91f5bc9186bca87ba3f6b78caac59d82736173d4..297d146ad61c79de21f6c9d529c3bf565e475bff 100644 (file)
@@ -38,6 +38,7 @@
 #include "ldap_config.h"
 
 #include <stdio.h>
+#include <ac/ctype.h>
 #include <ac/stdlib.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
@@ -1223,7 +1224,7 @@ read_compexdata(FILE *in)
          */
 
        for (s = line, i = code = 0; *s != '#' && i < 6; i++, s++) {
-           if (isspace(*s)) break;
+           if (isspace((unsigned char)*s)) break;
             code <<= 4;
             if (*s >= '0' && *s <= '9')
                code += *s - '0';
@@ -1268,8 +1269,9 @@ write_case(FILE *out, _case_t *tab, int num, int first)
     for (i=0; i<num; i++) {
        if (first) first = 0;
        else fprintf(out, ",");
-       fprintf(out, "\n\t0x%08x, 0x%08x, 0x%08x",
-               tab[i].key, tab[i].other1, tab[i].other2);
+       fprintf(out, "\n\t0x%08lx, 0x%08lx, 0x%08lx",
+               (unsigned long) tab[i].key, (unsigned long) tab[i].other1,
+               (unsigned long) tab[i].other2);
     }
 }
 
@@ -1283,7 +1285,9 @@ write_cdata(char *opath)
     FILE *out;
        ac_uint4 bytes;
     ac_uint4 i, idx, nprops;
+#if !(HARDCODE_DATA)
     ac_uint2 casecnt[2];
+#endif
     char path[BUFSIZ];
 #if HARDCODE_DATA
     int j, k;
@@ -1364,7 +1368,7 @@ write_cdata(char *opath)
            if (!(k&3)) fprintf(out,"\n\t");
            else fprintf(out, " ");
            k++;
-           fprintf(out, "0x%08x", proptbl[i].ranges[j]);
+           fprintf(out, "0x%08lx", (unsigned long) proptbl[i].ranges[j]);
          }
        }
     }
@@ -1404,11 +1408,11 @@ write_cdata(char *opath)
      *****************************************************************/
 
 #if HARDCODE_DATA
-    fprintf(out, PREF "ac_uint4 _uccase_size = %d;\n\n",
-       upper_used + lower_used + title_used);
+    fprintf(out, PREF "ac_uint4 _uccase_size = %ld;\n\n",
+        (long) (upper_used + lower_used + title_used));
 
-    fprintf(out, PREF "ac_uint2 _uccase_len[2] = {%d, %d};\n\n",
-       upper_used, lower_used);
+    fprintf(out, PREF "ac_uint2 _uccase_len[2] = {%ld, %ld};\n\n",
+        (long) upper_used, (long) lower_used);
     fprintf(out, PREF "ac_uint4 _uccase_map[] = {");
 
     if (upper_used > 0)
@@ -1491,8 +1495,8 @@ write_cdata(char *opath)
     create_comps();
     
 #if HARDCODE_DATA
-    fprintf(out, PREF "ac_uint4 _uccomp_size = %d;\n\n",
-       comps_used * 4);
+    fprintf(out, PREF "ac_uint4 _uccomp_size = %ld;\n\n",
+        comps_used * 4L);
 
     fprintf(out, PREF "ac_uint4 _uccomp_data[] = {");
 
@@ -1502,8 +1506,9 @@ write_cdata(char *opath)
     if (comps_used > 0) {
        for (i=0; i<comps_used; i++) {
            if (i) fprintf(out, ",");
-           fprintf(out, "\n\t0x%08x, 0x%08x, 0x%08x, 0x%08x",
-               comps[i].comp, comps[i].count, comps[i].code1, comps[i].code2);
+           fprintf(out, "\n\t0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx",
+               (unsigned long) comps[i].comp, (unsigned long) comps[i].count,
+               (unsigned long) comps[i].code1, (unsigned long) comps[i].code2);
        }
     } else {
        fprintf(out, "\t0");
@@ -1550,8 +1555,8 @@ write_cdata(char *opath)
     expand_decomp();
 
 #if HARDCODE_DATA
-    fprintf(out, PREF "ac_uint4 _ucdcmp_size = %d;\n\n",
-       decomps_used * 2);
+    fprintf(out, PREF "ac_uint4 _ucdcmp_size = %ld;\n\n",
+        decomps_used * 2L);
 
     fprintf(out, PREF "ac_uint4 _ucdcmp_nodes[] = {");
 
@@ -1560,14 +1565,15 @@ write_cdata(char *opath)
         * Write the list of decomp nodes.
         */
        for (i = idx = 0; i < decomps_used; i++) {
-           fprintf(out, "\n\t0x%08x, 0x%08x,", decomps[i].code, idx);
+           fprintf(out, "\n\t0x%08lx, 0x%08lx,",
+               (unsigned long) decomps[i].code, (unsigned long) idx);
            idx += decomps[i].used;
        }
 
        /*
         * Write the sentinel index as the last decomp node.
         */
-       fprintf(out, "\n\t0x%08x\n};\n\n", idx);
+       fprintf(out, "\n\t0x%08lx\n};\n\n", (unsigned long) idx);
 
        fprintf(out, PREF "ac_uint4 _ucdcmp_decomp[] = {");
        /*
@@ -1580,7 +1586,7 @@ write_cdata(char *opath)
            if (!(k&3)) fprintf(out,"\n\t");
            else fprintf(out, " ");
            k++;
-           fprintf(out, "0x%08x", decomps[i].decomp[j]);
+           fprintf(out, "0x%08lx", (unsigned long) decomps[i].decomp[j]);
          }
        fprintf(out, "\n};\n\n");
     }
@@ -1641,8 +1647,8 @@ write_cdata(char *opath)
 #endif
 
 #ifdef HARDCODE_DATA
-    fprintf(out, PREF "ac_uint4 _uckdcmp_size = %d;\n\n",
-       kdecomps_used * 2);
+    fprintf(out, PREF "ac_uint4 _uckdcmp_size = %ld;\n\n",
+        kdecomps_used * 2L);
 
     fprintf(out, PREF "ac_uint4 _uckdcmp_nodes[] = {");
 
@@ -1651,14 +1657,15 @@ write_cdata(char *opath)
         * Write the list of kdecomp nodes.
         */
        for (i = idx = 0; i < kdecomps_used; i++) {
-           fprintf(out, "\n\t0x%08x, 0x%08x,", kdecomps[i].code, idx);
+           fprintf(out, "\n\t0x%08lx, 0x%08lx,",
+               (unsigned long) kdecomps[i].code, (unsigned long) idx);
            idx += kdecomps[i].used;
        }
 
        /*
         * Write the sentinel index as the last decomp node.
         */
-       fprintf(out, "\n\t0x%08x\n};\n\n", idx);
+       fprintf(out, "\n\t0x%08lx\n};\n\n", (unsigned long) idx);
 
        fprintf(out, PREF "ac_uint4 _uckdcmp_decomp[] = {");
 
@@ -1672,7 +1679,7 @@ write_cdata(char *opath)
            if (!(k&3)) fprintf(out,"\n\t");
            else fprintf(out, " ");
            k++;
-           fprintf(out, "0x%08x", kdecomps[i].decomp[j]);
+           fprintf(out, "0x%08lx", (unsigned long) kdecomps[i].decomp[j]);
          }
        fprintf(out, "\n};\n\n");
     }
@@ -1738,7 +1745,7 @@ write_cdata(char *opath)
      *
      *****************************************************************/
 #ifdef HARDCODE_DATA
-    fprintf(out, PREF "ac_uint4 _uccmcl_size = %d;\n\n", ccl_used);
+    fprintf(out, PREF "ac_uint4 _uccmcl_size = %ld;\n\n", (long) ccl_used);
 
     fprintf(out, PREF "ac_uint4 _uccmcl_nodes[] = {");
 
@@ -1750,7 +1757,7 @@ write_cdata(char *opath)
            if (i) fprintf(out, ",");
            if (!(i&3)) fprintf(out, "\n\t");
            else fprintf(out, " ");
-           fprintf(out, "0x%08x", ccl[i]);
+           fprintf(out, "0x%08lx", (unsigned long) ccl[i]);
        }
     } else {
        fprintf(out, "\t0");
@@ -1797,7 +1804,8 @@ write_cdata(char *opath)
      *****************************************************************/
 
 #if HARDCODE_DATA
-    fprintf(out, PREF "ac_uint4 _ucnum_size = %d;\n\n", ncodes_used<<1);
+    fprintf(out, PREF "ac_uint4 _ucnum_size = %lu;\n\n",
+        (unsigned long)ncodes_used<<1);
 
     fprintf(out, PREF "ac_uint4 _ucnum_nodes[] = {");
 
@@ -1809,7 +1817,8 @@ write_cdata(char *opath)
            if (i) fprintf(out, ",");
            if (!(i&1)) fprintf(out, "\n\t");
            else fprintf(out, " ");
-           fprintf(out, "0x%08x, 0x%08x", ncodes[i].code, ncodes[i].idx);
+           fprintf(out, "0x%08lx, 0x%08lx",
+               (unsigned long) ncodes[i].code, (unsigned long) ncodes[i].idx);
        }
        fprintf(out, "\n};\n\n");
 
index d112de8f0ad72d043ad86b26dce27fc2f9561bb6..65fae592db4505849ecd64fb1ee0e08188a7837f 100644 (file)
@@ -29,18 +29,21 @@ XLIBS = $(LIBRARY) $(LDAP_LIBLBER_LA)
 
 SRCS   = base64.c csn.c entropy.c sasl.c signal.c hash.c passfile.c \
        md5.c passwd.c sha1.c getpass.c lockf.c utils.c uuid.c sockpair.c \
-       avl.c ldif.c fetch.c \
+       avl.c tavl.c ldif.c fetch.c \
        testavl.c \
        @LIBSRCS@ $(@PLAT@_SRCS)
 
 OBJS   = base64.o csn.o entropy.o sasl.o signal.o hash.o passfile.o \
        md5.o passwd.o sha1.o getpass.o lockf.o utils.o uuid.o sockpair.o \
-       avl.o ldif.o fetch.o \
+       avl.o tavl.o ldif.o fetch.o \
        @LIBOBJS@ $(@PLAT@_OBJS)
 
 testavl: $(XLIBS) testavl.o
        (LTLINK) -o $@ testavl.o $(LIBS)
 
+testtavl: $(XLIBS) testtavl.o
+       (LTLINK) -o $@ testtavl.o $(LIBS)
+
 # These rules are for a Mingw32 build, specifically.
 # It's ok for them to be here because the clean rule is harmless, and
 # slapdmsg.res won't get built unless it's declared in OBJS.
index 279ff7f3eb9d183a3d8c8ff48ae051af25ef0724..14b4c46fda702a0e3a02aa6b30c6ed66042d1716 100644 (file)
@@ -27,6 +27,7 @@
  * This work was originally developed by the University of Michigan
  * (as part of U-MICH LDAP).  Additional significant contributors
  * include:
+ *   Howard Y. Chu
  *   Hallvard B. Furuseth
  *   Kurt D. Zeilenga
  */
 #define AVL_INTERNAL
 #include "avl.h"
 
-#define ROTATERIGHT(x) { \
-       Avlnode *tmp;\
-       if ( *(x) == NULL || (*(x))->avl_left == NULL ) {\
-               (void) fputs("RR error\n", stderr); exit( EXIT_FAILURE ); \
-       }\
-       tmp = (*(x))->avl_left;\
-       (*(x))->avl_left = tmp->avl_right;\
-       tmp->avl_right = *(x);\
-       *(x) = tmp;\
-}
-#define ROTATELEFT(x)  { \
-       Avlnode *tmp;\
-       if ( *(x) == NULL || (*(x))->avl_right == NULL ) {\
-               (void) fputs("RL error\n", stderr); exit( EXIT_FAILURE ); \
-       }\
-       tmp = (*(x))->avl_right;\
-       (*(x))->avl_right = tmp->avl_left;\
-       tmp->avl_left = *(x);\
-       *(x) = tmp;\
-}
-
-/*
- * ravl_insert - called from avl_insert() to do a recursive insert into
- * and balance of an avl tree.
- */
-
-static int
-ravl_insert(
-    Avlnode    **iroot,
-    void*      data,
-    int                *taller,
-    AVL_CMP            fcmp,                   /* comparison function */
-    AVL_DUP            fdup,                   /* function to call for duplicates */
-    int                depth
-)
-{
-       int     rc, cmp, tallersub;
-       Avlnode *l, *r;
-
-       if ( *iroot == 0 ) {
-               if ( (*iroot = (Avlnode *) ber_memalloc( sizeof( Avlnode ) ))
-                   == NULL ) {
-                       return( -1 );
-               }
-               (*iroot)->avl_left = 0;
-               (*iroot)->avl_right = 0;
-               (*iroot)->avl_bf = 0;
-               (*iroot)->avl_data = data;
-               *taller = 1;
-               return( 0 );
-       }
-
-       cmp = (*fcmp)( data, (*iroot)->avl_data );
-
-       /* equal - duplicate name */
-       if ( cmp == 0 ) {
-               *taller = 0;
-               return( (*fdup)( (*iroot)->avl_data, data ) );
-       }
-
-       /* go right */
-       else if ( cmp > 0 ) {
-               rc = ravl_insert( &((*iroot)->avl_right), data, &tallersub,
-                  fcmp, fdup, depth );
-               if ( tallersub )
-                       switch ( (*iroot)->avl_bf ) {
-                       case LH : /* left high - balance is restored */
-                               (*iroot)->avl_bf = EH;
-                               *taller = 0;
-                               break;
-                       case EH : /* equal height - now right heavy */
-                               (*iroot)->avl_bf = RH;
-                               *taller = 1;
-                               break;
-                       case RH : /* right heavy to start - right balance */
-                               r = (*iroot)->avl_right;
-                               switch ( r->avl_bf ) {
-                               case LH : /* double rotation left */
-                                       l = r->avl_left;
-                                       switch ( l->avl_bf ) {
-                                       case LH : (*iroot)->avl_bf = EH;
-                                                 r->avl_bf = RH;
-                                                 break;
-                                       case EH : (*iroot)->avl_bf = EH;
-                                                 r->avl_bf = EH;
-                                                 break;
-                                       case RH : (*iroot)->avl_bf = LH;
-                                                 r->avl_bf = EH;
-                                                 break;
-                                       }
-                                       l->avl_bf = EH;
-                                       ROTATERIGHT( (&r) )
-                                       (*iroot)->avl_right = r;
-                                       ROTATELEFT( iroot )
-                                       *taller = 0;
-                                       break;
-                               case EH : /* This should never happen */
-                                       break;
-                               case RH : /* single rotation left */
-                                       (*iroot)->avl_bf = EH;
-                                       r->avl_bf = EH;
-                                       ROTATELEFT( iroot )
-                                       *taller = 0;
-                                       break;
-                               }
-                               break;
-                       }
-               else
-                       *taller = 0;
-       }
-
-       /* go left */
-       else {
-               rc = ravl_insert( &((*iroot)->avl_left), data, &tallersub,
-                  fcmp, fdup, depth );
-               if ( tallersub )
-                       switch ( (*iroot)->avl_bf ) {
-                       case LH : /* left high to start - left balance */
-                               l = (*iroot)->avl_left;
-                               switch ( l->avl_bf ) {
-                               case LH : /* single rotation right */
-                                       (*iroot)->avl_bf = EH;
-                                       l->avl_bf = EH;
-                                       ROTATERIGHT( iroot )
-                                       *taller = 0;
-                                       break;
-                               case EH : /* this should never happen */
-                                       break;
-                               case RH : /* double rotation right */
-                                       r = l->avl_right;
-                                       switch ( r->avl_bf ) {
-                                       case LH : (*iroot)->avl_bf = RH;
-                                                 l->avl_bf = EH;
-                                                 break;
-                                       case EH : (*iroot)->avl_bf = EH;
-                                                 l->avl_bf = EH;
-                                                 break;
-                                       case RH : (*iroot)->avl_bf = EH;
-                                                 l->avl_bf = LH;
-                                                 break;
-                                       }
-                                       r->avl_bf = EH;
-                                       ROTATELEFT( (&l) )
-                                       (*iroot)->avl_left = l;
-                                       ROTATERIGHT( iroot )
-                                       *taller = 0;
-                                       break;
-                               }
-                               break;
-                       case EH : /* equal height - now left heavy */
-                               (*iroot)->avl_bf = LH;
-                               *taller = 1;
-                               break;
-                       case RH : /* right high - balance is restored */
-                               (*iroot)->avl_bf = EH;
-                               *taller = 0;
-                               break;
-                       }
-               else
-                       *taller = 0;
-       }
-
-       return( rc );
-}
+static const int avl_bfs[] = {LH, RH};
 
 /*
  * avl_insert -- insert a node containing data data into the avl tree
@@ -227,245 +65,284 @@ ravl_insert(
  *
  * NOTE: this routine may malloc memory
  */
-
 int
-avl_insert( Avlnode **root, void* data, AVL_CMP fcmp, AVL_DUP fdup )
+avl_insert( Avlnode ** root, void *data, AVL_CMP fcmp, AVL_DUP fdup )
 {
-       int     taller;
+    Avlnode *t, *p, *s, *q, *r;
+    int a, cmp, ncmp;
 
-       return( ravl_insert( root, data, &taller, fcmp, fdup, 0 ) );
-}
+       if ( *root == NULL ) {
+               if (( r = (Avlnode *) ber_memalloc( sizeof( Avlnode ))) == NULL ) {
+                       return( -1 );
+               }
+               r->avl_link[0] = r->avl_link[1] = NULL;
+               r->avl_data = data;
+               r->avl_bf = EH;
+               *root = r;
 
-/* 
- * right_balance() - called from delete when root's right subtree has
- * been shortened because of a deletion.
- */
+               return( 0 );
+       }
 
-static int
-right_balance( Avlnode **root )
-{
-       int     shorter = -1;
-       Avlnode *r, *l;
-
-       switch( (*root)->avl_bf ) {
-       case RH:        /* was right high - equal now */
-               (*root)->avl_bf = EH;
-               shorter = 1;
-               break;
-       case EH:        /* was equal - left high now */
-               (*root)->avl_bf = LH;
-               shorter = 0;
-               break;
-       case LH:        /* was right high - balance */
-               l = (*root)->avl_left;
-               switch ( l->avl_bf ) {
-               case RH : /* double rotation left */
-                       r = l->avl_right;
-                       switch ( r->avl_bf ) {
-                       case RH :
-                               (*root)->avl_bf = EH;
-                               l->avl_bf = LH;
-                               break;
-                       case EH :
-                               (*root)->avl_bf = EH;
-                               l->avl_bf = EH;
-                               break;
-                       case LH :
-                               (*root)->avl_bf = RH;
-                               l->avl_bf = EH;
-                               break;
+    t = NULL;
+    s = p = *root;
+
+       /* find insertion point */
+    while (1) {
+               cmp = fcmp( data, p->avl_data );
+               if ( cmp == 0 )
+                       return (*fdup)( p->avl_data, data );
+
+               cmp = (cmp > 0);
+               q = p->avl_link[cmp];
+               if (q == NULL) {
+                       /* insert */
+                       if (( q = (Avlnode *) ber_memalloc( sizeof( Avlnode ))) == NULL ) {
+                               return( -1 );
                        }
-                       r->avl_bf = EH;
-                       ROTATELEFT( (&l) )
-                       (*root)->avl_left = l;
-                       ROTATERIGHT( root )
-                       shorter = 1;
-                       break;
-               case EH : /* right rotation */
-                       (*root)->avl_bf = LH;
-                       l->avl_bf = RH;
-                       ROTATERIGHT( root );
-                       shorter = 0;
-                       break;
-               case LH : /* single rotation right */
-                       (*root)->avl_bf = EH;
-                       l->avl_bf = EH;
-                       ROTATERIGHT( root )
-                       shorter = 1;
+                       q->avl_link[0] = q->avl_link[1] = NULL;
+                       q->avl_data = data;
+                       q->avl_bf = EH;
+
+                       p->avl_link[cmp] = q;
                        break;
+               } else if ( q->avl_bf ) {
+                       t = p;
+                       s = q;
                }
-               break;
+               p = q;
+    }
+
+    /* adjust balance factors */
+    cmp = fcmp( data, s->avl_data ) > 0;
+       r = p = s->avl_link[cmp];
+       a = avl_bfs[cmp];
+
+       while ( p != q ) {
+               cmp = fcmp( data, p->avl_data ) > 0;
+               p->avl_bf = avl_bfs[cmp];
+               p = p->avl_link[cmp];
        }
 
-       return( shorter );
-}
-
-/* 
- * left_balance() - called from delete when root's left subtree has
- * been shortened because of a deletion.
- */
-
-static int
-left_balance( Avlnode **root )
-{
-       int     shorter = -1;
-       Avlnode *r, *l;
-
-       switch( (*root)->avl_bf ) {
-       case LH:        /* was left high - equal now */
-               (*root)->avl_bf = EH;
-               shorter = 1;
-               break;
-       case EH:        /* was equal - right high now */
-               (*root)->avl_bf = RH;
-               shorter = 0;
-               break;
-       case RH:        /* was right high - balance */
-               r = (*root)->avl_right;
-               switch ( r->avl_bf ) {
-               case LH : /* double rotation left */
-                       l = r->avl_left;
-                       switch ( l->avl_bf ) {
-                       case LH :
-                               (*root)->avl_bf = EH;
-                               r->avl_bf = RH;
-                               break;
-                       case EH :
-                               (*root)->avl_bf = EH;
-                               r->avl_bf = EH;
-                               break;
-                       case RH :
-                               (*root)->avl_bf = LH;
-                               r->avl_bf = EH;
-                               break;
+       /* checks and balances */
+
+       if ( s->avl_bf == EH ) {
+               s->avl_bf = a;
+               return 0;
+       } else if ( s->avl_bf == -a ) {
+               s->avl_bf = EH;
+               return 0;
+    } else if ( s->avl_bf == a ) {
+               cmp = (a > 0);
+               ncmp = !cmp;
+               if ( r->avl_bf == a ) {
+                       /* single rotation */
+                       p = r;
+                       s->avl_link[cmp] = r->avl_link[ncmp];
+                       r->avl_link[ncmp] = s;
+                       s->avl_bf = 0;
+                       r->avl_bf = 0;
+               } else if ( r->avl_bf == -a ) {
+                       /* double rotation */
+                       p = r->avl_link[ncmp];
+                       r->avl_link[ncmp] = p->avl_link[cmp];
+                       p->avl_link[cmp] = r;
+                       s->avl_link[cmp] = p->avl_link[ncmp];
+                       p->avl_link[ncmp] = s;
+
+                       if ( p->avl_bf == a ) {
+                               s->avl_bf = -a;
+                               r->avl_bf = 0;
+                       } else if ( p->avl_bf == -a ) {
+                               s->avl_bf = 0;
+                               r->avl_bf = a;
+                       } else {
+                               s->avl_bf = 0;
+                               r->avl_bf = 0;
                        }
-                       l->avl_bf = EH;
-                       ROTATERIGHT( (&r) )
-                       (*root)->avl_right = r;
-                       ROTATELEFT( root )
-                       shorter = 1;
-                       break;
-               case EH : /* single rotation left */
-                       (*root)->avl_bf = RH;
-                       r->avl_bf = LH;
-                       ROTATELEFT( root );
-                       shorter = 0;
-                       break;
-               case RH : /* single rotation left */
-                       (*root)->avl_bf = EH;
-                       r->avl_bf = EH;
-                       ROTATELEFT( root )
-                       shorter = 1;
-                       break;
+                       p->avl_bf = 0;
                }
-               break;
-       }
+               /* Update parent */
+               if ( t == NULL )
+                       *root = p;
+               else if ( s == t->avl_right )
+                       t->avl_right = p;
+               else
+                       t->avl_left = p;
+    }
 
-       return( shorter );
+  return 0;
 }
 
-/*
- * ravl_delete() - called from avl_delete to do recursive deletion of a
- * node from an avl tree.  It finds the node recursively, deletes it,
- * and returns shorter if the tree is shorter after the deletion and
- * rebalancing.
- */
-
-static void*
-ravl_delete( Avlnode **root, void* data, AVL_CMP fcmp, int *shorter )
+void*
+avl_delete( Avlnode **root, void* data, AVL_CMP fcmp )
 {
-       int     shortersubtree = 0;
-       int     cmp;
-       void*   savedata;
-       Avlnode *minnode, *savenode;
-
-       if ( *root == NULLAVL )
-               return( 0 );
-
-       cmp = (*fcmp)( data, (*root)->avl_data );
+       Avlnode *p, *q, *r, *top;
+       int side, side_bf, shorter, nside;
 
-       /* found it! */
-       if ( cmp == 0 ) {
-               savenode = *root;
-               savedata = savenode->avl_data;
-
-               /* simple cases: no left child */
-               if ( (*root)->avl_left == 0 ) {
-                       *root = (*root)->avl_right;
-                       *shorter = 1;
-                       ber_memfree( (char *) savenode );
-                       return( savedata );
-               /* no right child */
-               } else if ( (*root)->avl_right == 0 ) {
-                       *root = (*root)->avl_left;
-                       *shorter = 1;
-                       ber_memfree( (char *) savenode );
-                       return( savedata );
-               }
-
-               /* 
-                * avl_getmin will return to us the smallest node greater
-                * than the one we are trying to delete.  deleting this node
-                * from the right subtree is guaranteed to end in one of the
-                * simple cases above.
-                */
+       /* parent stack */
+       Avlnode *pptr[sizeof(void *)*8];
+       unsigned char pdir[sizeof(void *)*8];
+       int depth = 0;
 
-               minnode = (*root)->avl_right;
-               while ( minnode->avl_left != NULLAVL )
-                       minnode = minnode->avl_left;
+       if ( *root == NULL )
+               return NULL;
 
-               /* swap the data */
-               (*root)->avl_data = minnode->avl_data;
-               minnode->avl_data = savedata;
+       p = *root;
 
-               savedata = ravl_delete( &(*root)->avl_right, data, fcmp,
-                   &shortersubtree );
+       while (1) {
+               side = fcmp( data, p->avl_data );
+               if ( !side )
+                       break;
+               side = ( side > 0 );
+               pdir[depth] = side;
+               pptr[depth++] = p;
 
-               if ( shortersubtree )
-                       *shorter = right_balance( root );
-               else
-                       *shorter = 0;
-       /* go left */
-       } else if ( cmp < 0 ) {
-               if ( (savedata = ravl_delete( &(*root)->avl_left, data, fcmp,
-                   &shortersubtree )) == 0 ) {
-                       *shorter = 0;
-                       return( 0 );
+               p = p->avl_link[side];
+               if ( p == NULL )
+                       return p;
+       }
+       data = p->avl_data;
+
+       /* If this node has two children, swap so we are deleting a node with
+        * at most one child.
+        */
+       if ( p->avl_link[0] && p->avl_link[1] ) {
+
+               /* find the immediate predecessor <q> */
+               q = p->avl_link[0];
+               side = depth;
+               pdir[depth++] = 0;
+               while (q->avl_link[1]) {
+                       pdir[depth] = 1;
+                       pptr[depth++] = q;
+                       q = q->avl_link[1];
                }
-
-               /* left subtree shorter? */
-               if ( shortersubtree )
-                       *shorter = left_balance( root );
-               else
-                       *shorter = 0;
-       /* go right */
-       } else {
-               if ( (savedata = ravl_delete( &(*root)->avl_right, data, fcmp,
-                   &shortersubtree )) == 0 ) {
-                       *shorter = 0;
-                       return( 0 );
+               /* swap links */
+               r = p->avl_link[0];
+               p->avl_link[0] = q->avl_link[0];
+               q->avl_link[0] = r;
+
+               q->avl_link[1] = p->avl_link[1];
+               p->avl_link[1] = NULL;
+
+               q->avl_bf = p->avl_bf;
+
+               /* fix stack positions: old parent of p points to q */
+               pptr[side] = q;
+               if ( side ) {
+                       r = pptr[side-1];
+                       r->avl_link[pdir[side-1]] = q;
+               } else {
+                       *root = q;
+               }
+               /* new parent of p points to p */
+               if ( depth-side > 1 ) {
+                       r = pptr[depth-1];
+                       r->avl_link[1] = p;
+               } else {
+                       q->avl_link[0] = p;
                }
-
-               if ( shortersubtree ) 
-                       *shorter = right_balance( root );
-               else
-                       *shorter = 0;
        }
 
-       return( savedata );
-}
+       /* now <p> has at most one child, get it */
+       q = p->avl_link[0] ? p->avl_link[0] : p->avl_link[1];
 
-/*
- * avl_delete() - deletes the node containing data (according to fcmp) from
- * the avl tree rooted at root.
- */
+       ber_memfree( p );
 
-void*
-avl_delete( Avlnode **root, void* data, AVL_CMP fcmp )
-{
-       int     shorter;
+       if ( !depth ) {
+               *root = q;
+               return data;
+       }
+
+       /* set the child into p's parent */
+       depth--;
+       p = pptr[depth];
+       side = pdir[depth];
+       p->avl_link[side] = q;
+
+       top = NULL;
+       shorter = 1;
+  
+       while ( shorter ) {
+               p = pptr[depth];
+               side = pdir[depth];
+               nside = !side;
+               side_bf = avl_bfs[side];
+
+               /* case 1: height unchanged */
+               if ( p->avl_bf == EH ) {
+                       /* Tree is now heavier on opposite side */
+                       p->avl_bf = avl_bfs[nside];
+                       shorter = 0;
+                 
+               } else if ( p->avl_bf == side_bf ) {
+               /* case 2: taller subtree shortened, height reduced */
+                       p->avl_bf = EH;
+               } else {
+               /* case 3: shorter subtree shortened */
+                       if ( depth )
+                               top = pptr[depth-1]; /* p->parent; */
+                       else
+                               top = NULL;
+                       /* set <q> to the taller of the two subtrees of <p> */
+                       q = p->avl_link[nside];
+                       if ( q->avl_bf == EH ) {
+                               /* case 3a: height unchanged, single rotate */
+                               p->avl_link[nside] = q->avl_link[side];
+                               q->avl_link[side] = p;
+                               shorter = 0;
+                               q->avl_bf = side_bf;
+                               p->avl_bf = (- side_bf);
+
+                       } else if ( q->avl_bf == p->avl_bf ) {
+                               /* case 3b: height reduced, single rotate */
+                               p->avl_link[nside] = q->avl_link[side];
+                               q->avl_link[side] = p;
+                               shorter = 1;
+                               q->avl_bf = EH;
+                               p->avl_bf = EH;
+
+                       } else {
+                               /* case 3c: height reduced, balance factors opposite */
+                               r = q->avl_link[side];
+                               q->avl_link[side] = r->avl_link[nside];
+                               r->avl_link[nside] = q;
+
+                               p->avl_link[nside] = r->avl_link[side];
+                               r->avl_link[side] = p;
+
+                               if ( r->avl_bf == side_bf ) {
+                                       q->avl_bf = (- side_bf);
+                                       p->avl_bf = EH;
+                               } else if ( r->avl_bf == (- side_bf)) {
+                                       q->avl_bf = EH;
+                                       p->avl_bf = side_bf;
+                               } else {
+                                       q->avl_bf = EH;
+                                       p->avl_bf = EH;
+                               }
+                               r->avl_bf = EH;
+                               q = r;
+                       }
+                       /* a rotation has caused <q> (or <r> in case 3c) to become
+                        * the root.  let <p>'s former parent know this.
+                        */
+                       if ( top == NULL ) {
+                               *root = q;
+                       } else if (top->avl_link[0] == p) {
+                               top->avl_link[0] = q;
+                       } else {
+                               top->avl_link[1] = q;
+                       }
+                       /* end case 3 */
+                       p = q;
+               }
+               if ( !depth )
+                       break;
+               depth--;
+       } /* end while(shorter) */
 
-       return( ravl_delete( root, data, fcmp, &shorter ) );
+       return data;
 }
 
 static int
@@ -650,10 +527,8 @@ avl_find2( Avlnode *root, const void *data, AVL_CMP fcmp )
        int     cmp;
 
        while ( root != 0 && (cmp = (*fcmp)( data, root->avl_data )) != 0 ) {
-               if ( cmp < 0 )
-                       root = root->avl_left;
-               else
-                       root = root->avl_right;
+               cmp = cmp > 0;
+               root = root->avl_link[cmp];
        }
        return root;
 }
@@ -664,10 +539,8 @@ avl_find( Avlnode *root, const void* data, AVL_CMP fcmp )
        int     cmp;
 
        while ( root != 0 && (cmp = (*fcmp)( data, root->avl_data )) != 0 ) {
-               if ( cmp < 0 )
-                       root = root->avl_left;
-               else
-                       root = root->avl_right;
+               cmp = cmp > 0;
+               root = root->avl_link[cmp];
        }
 
        return( root ? root->avl_data : 0 );
index 8f6fda6129ccbed43d772e5d594980255de2cfa3..23d001f7d5aa5d4843fc704a6a879bd4f27c4194 100644 (file)
@@ -209,9 +209,7 @@ static const struct pw_scheme *get_scheme(
        bv.bv_val = (char *) scheme;
 
        for( pws=pw_schemes; pws; pws=pws->next ) {
-               if( bv.bv_len != pws->s.name.bv_len )
-                       continue;
-               if( strncasecmp(bv.bv_val, pws->s.name.bv_val, bv.bv_len ) == 0 ) {
+               if ( ber_bvstrcasecmp(&bv, &pws->s.name ) == 0 ) {
                        return &(pws->s);
                }
        }
diff --git a/libraries/liblutil/tavl.c b/libraries/liblutil/tavl.c
new file mode 100644 (file)
index 0000000..f588c71
--- /dev/null
@@ -0,0 +1,497 @@
+/* avl.c - routines to implement an avl tree */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2005 The OpenLDAP Foundation.
+ * Portions Copyright (c) 2005 by Howard Chu, Symas Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Howard Chu for inclusion
+ * in OpenLDAP software.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/stdlib.h>
+
+#ifdef CSRIMALLOC
+#define ber_memalloc malloc
+#define ber_memrealloc realloc
+#define ber_memfree free
+#else
+#include "lber.h"
+#endif
+
+#define AVL_INTERNAL
+#include "avl.h"
+
+static const int avl_bfs[] = {LH, RH};
+
+/*
+ * Threaded AVL trees - for fast in-order traversal of nodes.
+ */
+/*
+ * tavl_insert -- insert a node containing data data into the avl tree
+ * with root root.  fcmp is a function to call to compare the data portion
+ * of two nodes.  it should take two arguments and return <, >, or == 0,
+ * depending on whether its first argument is <, >, or == its second
+ * argument (like strcmp, e.g.).  fdup is a function to call when a duplicate
+ * node is inserted.  it should return 0, or -1 and its return value
+ * will be the return value from avl_insert in the case of a duplicate node.
+ * the function will be called with the original node's data as its first
+ * argument and with the incoming duplicate node's data as its second
+ * argument.  this could be used, for example, to keep a count with each
+ * node.
+ *
+ * NOTE: this routine may malloc memory
+ */
+int
+tavl_insert( Avlnode ** root, void *data, AVL_CMP fcmp, AVL_DUP fdup )
+{
+    Avlnode *t, *p, *s, *q, *r;
+    int a, cmp, ncmp;
+
+       if ( *root == NULL ) {
+               if (( r = (Avlnode *) ber_memalloc( sizeof( Avlnode ))) == NULL ) {
+                       return( -1 );
+               }
+               r->avl_link[0] = r->avl_link[1] = NULL;
+               r->avl_data = data;
+               r->avl_bf = EH;
+               r->avl_bits[0] = r->avl_bits[1] = AVL_THREAD;
+               *root = r;
+
+               return( 0 );
+       }
+
+    t = NULL;
+    s = p = *root;
+
+       /* find insertion point */
+    while (1) {
+               cmp = fcmp( data, p->avl_data );
+               if ( cmp == 0 )
+                       return (*fdup)( p->avl_data, data );
+
+               cmp = (cmp > 0);
+               q = avl_child( p, cmp );
+               if (q == NULL) {
+                       /* insert */
+                       if (( q = (Avlnode *) ber_memalloc( sizeof( Avlnode ))) == NULL ) {
+                               return( -1 );
+                       }
+                       q->avl_link[cmp] = p->avl_link[cmp];
+                       q->avl_link[!cmp] = p;
+                       q->avl_data = data;
+                       q->avl_bf = EH;
+                       q->avl_bits[0] = q->avl_bits[1] = AVL_THREAD;
+
+                       p->avl_link[cmp] = q;
+                       p->avl_bits[cmp] = AVL_CHILD;
+                       break;
+               } else if ( q->avl_bf ) {
+                       t = p;
+                       s = q;
+               }
+               p = q;
+    }
+
+    /* adjust balance factors */
+    cmp = fcmp( data, s->avl_data ) > 0;
+       r = p = s->avl_link[cmp];
+       a = avl_bfs[cmp];
+
+       while ( p != q ) {
+               cmp = fcmp( data, p->avl_data ) > 0;
+               p->avl_bf = avl_bfs[cmp];
+               p = p->avl_link[cmp];
+       }
+
+       /* checks and balances */
+
+       if ( s->avl_bf == EH ) {
+               s->avl_bf = a;
+               return 0;
+       } else if ( s->avl_bf == -a ) {
+               s->avl_bf = EH;
+               return 0;
+    } else if ( s->avl_bf == a ) {
+               cmp = (a > 0);
+               ncmp = !cmp;
+               if ( r->avl_bf == a ) {
+                       /* single rotation */
+                       p = r;
+                       if ( r->avl_bits[ncmp] == AVL_THREAD ) {
+                               r->avl_bits[ncmp] = AVL_CHILD;
+                               s->avl_bits[cmp] = AVL_THREAD;
+                       } else {
+                               s->avl_link[cmp] = r->avl_link[ncmp];
+                               r->avl_link[ncmp] = s;
+                       }
+                       s->avl_bf = 0;
+                       r->avl_bf = 0;
+               } else if ( r->avl_bf == -a ) {
+                       /* double rotation */
+                       p = r->avl_link[ncmp];
+                       if ( p->avl_bits[cmp] == AVL_THREAD ) {
+                               p->avl_bits[cmp] = AVL_CHILD;
+                               r->avl_bits[ncmp] = AVL_THREAD;
+                       } else {
+                               r->avl_link[ncmp] = p->avl_link[cmp];
+                               p->avl_link[cmp] = r;
+                       }
+                       if ( p->avl_bits[ncmp] == AVL_THREAD ) {
+                               p->avl_bits[ncmp] = AVL_CHILD;
+                               s->avl_link[cmp] = p;
+                               s->avl_bits[cmp] = AVL_THREAD;
+                       } else {
+                               s->avl_link[cmp] = p->avl_link[ncmp];
+                               p->avl_link[ncmp] = s;
+                       }
+                       if ( p->avl_bf == a ) {
+                               s->avl_bf = -a;
+                               r->avl_bf = 0;
+                       } else if ( p->avl_bf == -a ) {
+                               s->avl_bf = 0;
+                               r->avl_bf = a;
+                       } else {
+                               s->avl_bf = 0;
+                               r->avl_bf = 0;
+                       }
+                       p->avl_bf = 0;
+               }
+               /* Update parent */
+               if ( t == NULL )
+                       *root = p;
+               else if ( s == t->avl_right )
+                       t->avl_right = p;
+               else
+                       t->avl_left = p;
+    }
+
+  return 0;
+}
+
+void*
+tavl_delete( Avlnode **root, void* data, AVL_CMP fcmp )
+{
+       Avlnode *p, *q, *r, *top;
+       int side, side_bf, shorter, nside;
+
+       /* parent stack */
+       Avlnode *pptr[sizeof(void *)*8];
+       unsigned char pdir[sizeof(void *)*8];
+       int depth = 0;
+
+       if ( *root == NULL )
+               return NULL;
+
+       p = *root;
+
+       while (1) {
+               side = fcmp( data, p->avl_data );
+               if ( !side )
+                       break;
+               side = ( side > 0 );
+               pdir[depth] = side;
+               pptr[depth++] = p;
+
+               if ( p->avl_bits[side] == AVL_THREAD )
+                       return NULL;
+               p = p->avl_link[side];
+       }
+       data = p->avl_data;
+
+       /* If this node has two children, swap so we are deleting a node with
+        * at most one child.
+        */
+       if ( p->avl_bits[0] == AVL_CHILD && p->avl_bits[1] == AVL_CHILD &&
+               p->avl_link[0] && p->avl_link[1] ) {
+
+               /* find the immediate predecessor <q> */
+               q = p->avl_link[0];
+               side = depth;
+               pdir[depth++] = 0;
+               while (q->avl_bits[1] == AVL_CHILD && q->avl_link[1]) {
+                       pdir[depth] = 1;
+                       pptr[depth++] = q;
+                       q = q->avl_link[1];
+               }
+               /* swap links */
+               r = p->avl_link[0];
+               p->avl_link[0] = q->avl_link[0];
+               q->avl_link[0] = r;
+
+               q->avl_link[1] = p->avl_link[1];
+               p->avl_link[1] = q;
+
+               p->avl_bits[0] = q->avl_bits[0];
+               p->avl_bits[1] = q->avl_bits[1];
+               q->avl_bits[0] = q->avl_bits[1] = AVL_CHILD;
+
+               q->avl_bf = p->avl_bf;
+
+               /* fix stack positions: old parent of p points to q */
+               pptr[side] = q;
+               if ( side ) {
+                       r = pptr[side-1];
+                       r->avl_link[pdir[side-1]] = q;
+               } else {
+                       *root = q;
+               }
+               /* new parent of p points to p */
+               if ( depth-side > 1 ) {
+                       r = pptr[depth-1];
+                       r->avl_link[1] = p;
+               } else {
+                       q->avl_link[0] = p;
+               }
+
+               /* fix right subtree: successor of p points to q */
+               r = q->avl_link[1];
+               while ( r->avl_bits[0] == AVL_CHILD && r->avl_link[0] )
+                       r = r->avl_link[0];
+               r->avl_link[0] = q;
+       }
+
+       /* now <p> has at most one child, get it */
+       if ( p->avl_link[0] && p->avl_bits[0] == AVL_CHILD ) {
+               q = p->avl_link[0];
+               /* Preserve thread continuity */
+               r = p->avl_link[1];
+               nside = 1;
+       } else if ( p->avl_link[1] && p->avl_bits[1] == AVL_CHILD ) {
+               q = p->avl_link[1];
+               r = p->avl_link[0];
+               nside = 0;
+       } else {
+               q = NULL;
+               if ( depth > 0 )
+                       r = p->avl_link[pdir[depth-1]];
+               else
+                       r = NULL;
+       }
+
+       ber_memfree( p );
+
+       if ( !depth ) {
+               *root = q;
+               return data;
+       }
+
+       /* set the child into p's parent */
+       depth--;
+       p = pptr[depth];
+       side = pdir[depth];
+       p->avl_link[side] = q;
+
+       /* Update child thread */
+       if ( q ) {
+               for ( ; q->avl_bits[nside] == AVL_CHILD && q->avl_link[nside];
+                       q = q->avl_link[nside] ) ;
+               q->avl_link[nside] = r;
+       } else {
+               p->avl_bits[side] = AVL_THREAD;
+               p->avl_link[side] = r;
+       }
+
+       top = NULL;
+       shorter = 1;
+  
+       while ( shorter ) {
+               p = pptr[depth];
+               side = pdir[depth];
+               nside = !side;
+               side_bf = avl_bfs[side];
+
+               /* case 1: height unchanged */
+               if ( p->avl_bf == EH ) {
+                       /* Tree is now heavier on opposite side */
+                       p->avl_bf = avl_bfs[nside];
+                       shorter = 0;
+                 
+               } else if ( p->avl_bf == side_bf ) {
+               /* case 2: taller subtree shortened, height reduced */
+                       p->avl_bf = EH;
+               } else {
+               /* case 3: shorter subtree shortened */
+                       if ( depth )
+                               top = pptr[depth-1]; /* p->parent; */
+                       else
+                               top = NULL;
+                       /* set <q> to the taller of the two subtrees of <p> */
+                       q = p->avl_link[nside];
+                       if ( q->avl_bf == EH ) {
+                               /* case 3a: height unchanged, single rotate */
+                               if ( q->avl_bits[side] == AVL_THREAD ) {
+                                       q->avl_bits[side] = AVL_CHILD;
+                                       p->avl_bits[nside] = AVL_THREAD;
+                               } else {
+                                       p->avl_link[nside] = q->avl_link[side];
+                                       q->avl_link[side] = p;
+                               }
+                               shorter = 0;
+                               q->avl_bf = side_bf;
+                               p->avl_bf = (- side_bf);
+
+                       } else if ( q->avl_bf == p->avl_bf ) {
+                               /* case 3b: height reduced, single rotate */
+                               if ( q->avl_bits[side] == AVL_THREAD ) {
+                                       q->avl_bits[side] = AVL_CHILD;
+                                       p->avl_bits[nside] = AVL_THREAD;
+                               } else {
+                                       p->avl_link[nside] = q->avl_link[side];
+                                       q->avl_link[side] = p;
+                               }
+                               shorter = 1;
+                               q->avl_bf = EH;
+                               p->avl_bf = EH;
+
+                       } else {
+                               /* case 3c: height reduced, balance factors opposite */
+                               r = q->avl_link[side];
+                               if ( r->avl_bits[nside] == AVL_THREAD ) {
+                                       r->avl_bits[nside] = AVL_CHILD;
+                                       q->avl_bits[side] = AVL_THREAD;
+                               } else {
+                                       q->avl_link[side] = r->avl_link[nside];
+                                       r->avl_link[nside] = q;
+                               }
+
+                               if ( r->avl_bits[side] == AVL_THREAD ) {
+                                       r->avl_bits[side] = AVL_CHILD;
+                                       p->avl_bits[nside] = AVL_THREAD;
+                                       p->avl_link[nside] = r;
+                               } else {
+                                       p->avl_link[nside] = r->avl_link[side];
+                                       r->avl_link[side] = p;
+                               }
+
+                               if ( r->avl_bf == side_bf ) {
+                                       q->avl_bf = (- side_bf);
+                                       p->avl_bf = EH;
+                               } else if ( r->avl_bf == (- side_bf)) {
+                                       q->avl_bf = EH;
+                                       p->avl_bf = side_bf;
+                               } else {
+                                       q->avl_bf = EH;
+                                       p->avl_bf = EH;
+                               }
+                               r->avl_bf = EH;
+                               q = r;
+                       }
+                       /* a rotation has caused <q> (or <r> in case 3c) to become
+                        * the root.  let <p>'s former parent know this.
+                        */
+                       if ( top == NULL ) {
+                               *root = q;
+                       } else if (top->avl_link[0] == p) {
+                               top->avl_link[0] = q;
+                       } else {
+                               top->avl_link[1] = q;
+                       }
+                       /* end case 3 */
+                       p = q;
+               }
+               if ( !depth )
+                       break;
+               depth--;
+       } /* end while(shorter) */
+
+       return data;
+}
+
+/*
+ * tavl_free -- traverse avltree root, freeing the memory it is using.
+ * the dfree() is called to free the data portion of each node.  The
+ * number of items actually freed is returned.
+ */
+
+int
+tavl_free( Avlnode *root, AVL_FREE dfree )
+{
+       int     nleft, nright;
+
+       if ( root == 0 )
+               return( 0 );
+
+       nleft = tavl_free( avl_lchild( root ), dfree );
+
+       nright = tavl_free( avl_rchild( root ), dfree );
+
+       if ( dfree )
+               (*dfree)( root->avl_data );
+       ber_memfree( root );
+
+       return( nleft + nright + 1 );
+}
+
+/*
+ * tavl_find -- search avltree root for a node with data data.  the function
+ * cmp is used to compare things.  it is called with data as its first arg 
+ * and the current node data as its second.  it should return 0 if they match,
+ * < 0 if arg1 is less than arg2 and > 0 if arg1 is greater than arg2.
+ */
+
+Avlnode *
+tavl_find2( Avlnode *root, const void *data, AVL_CMP fcmp )
+{
+       int     cmp;
+
+       while ( root != 0 && (cmp = (*fcmp)( data, root->avl_data )) != 0 ) {
+               cmp = cmp > 0;
+               root = avl_child( root, cmp );
+       }
+       return root;
+}
+
+void*
+tavl_find( Avlnode *root, const void* data, AVL_CMP fcmp )
+{
+       int     cmp;
+
+       while ( root != 0 && (cmp = (*fcmp)( data, root->avl_data )) != 0 ) {
+               cmp = cmp > 0;
+               root = avl_child( root, cmp );
+       }
+
+       return( root ? root->avl_data : 0 );
+}
+
+/* Return the leftmost or rightmost node in the tree */
+Avlnode *
+tavl_end( Avlnode *root, int dir )
+{
+       if ( root ) {
+               while ( root->avl_bits[dir] == AVL_CHILD )
+                       root = root->avl_link[dir];
+       }
+       return root;
+}
+
+/* Return the next node in the given direction */
+Avlnode *
+tavl_next( Avlnode *root, int dir )
+{
+       if ( root ) {
+               int c = root->avl_bits[dir];
+
+               root = root->avl_link[dir];
+               if ( c == AVL_CHILD ) {
+                       dir ^= 1;
+                       while ( root->avl_bits[dir] == AVL_CHILD )
+                               root = root->avl_link[dir];
+               }
+       }
+       return root;
+}
index 692d2bebe6c9b311435c7c6dc751a7d9b2e72a15..4d179f7543a84d236c4dfa9c4269acebc4f45ff2 100644 (file)
@@ -204,7 +204,7 @@ int lutil_parsetime( char *atm, struct lutil_tm *tm )
 {
        while (atm && tm) {
                char *ptr = atm;
-               int i, fracs;
+               unsigned i, fracs;
 
                /* Is the stamp reasonably long? */
                for (i=0; isdigit(atm[i]); i++);
index f300f425746627717ef3ad28bf24e620d478f10b..6857759fcfbc792cdc237b28ed62c541334befbf 100644 (file)
@@ -169,7 +169,7 @@ lutil_eaddr( void )
        if (memcmp(eaddr, zero, sizeof(eaddr)) == 0) {
                /* XXX - who knows? */
                lutil_entropy( eaddr, sizeof(eaddr) );
-               eaddr[0] |= 0x80; /* turn it into a multicast address */
+               eaddr[0] |= 0x01; /* turn it into a multicast address */
        }
 
        return eaddr;
index ac9196cec8ac40ceaedc88fbb2ad70bd3acf4797..bd0685167c926dab95868cd30e893df163a7e7d3 100644 (file)
@@ -204,6 +204,13 @@ rewrite_session_var_set_f(
        session = rewrite_session_find( info, cookie );
        if ( session == NULL ) {
                session = rewrite_session_init( info, cookie );
+               if ( session == NULL ) {
+                       return REWRITE_ERR;
+               }
+
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+               ldap_pvt_thread_mutex_lock( &session->ls_mutex );
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
        }
 
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
index 46ee8dac699793b90bffe8759556c950cb498046..408126e0105dd641caec6449b5f95e99fd508487 100644 (file)
@@ -38,7 +38,7 @@ SRCS  = main.c globals.c bconfig.c config.c daemon.c \
                backglue.c backover.c ctxcsn.c ldapsync.c frontend.c \
                slapadd.c slapcat.c slapcommon.c slapdn.c slapindex.c \
                slappasswd.c slaptest.c slapauth.c slapacl.c component.c \
-               aci.c \
+               aci.c alock.c \
                $(@PLAT@_SRCS)
 
 OBJS   = main.o globals.o bconfig.o config.o daemon.o \
@@ -56,7 +56,7 @@ OBJS  = main.o globals.o bconfig.o config.o daemon.o \
                backglue.o backover.o ctxcsn.o ldapsync.o frontend.o \
                slapadd.o slapcat.o slapcommon.o slapdn.o slapindex.o \
                slappasswd.o slaptest.o slapauth.o slapacl.o component.o \
-               aci.o \
+               aci.o alock.o \
                $(@PLAT@_OBJS)
 
 LDAP_INCDIR= ../../include -I$(srcdir) -I$(srcdir)/slapi -I.
@@ -168,7 +168,7 @@ slapd.def: libbackends.a liboverlays.a version.o
                    done="" ;\
                    base=`expr "$$i" : "-l\(.*\)"`; \
                    for p in $$paths ; do \
-                       for ext in la dll a ; do \
+                       for ext in la dll dll.a a ; do \
                            path=$$p/lib$$base.$$ext; \
                            test ! -f $$path && continue; \
                            if test $$ext = la ; then \
@@ -192,12 +192,14 @@ slapd.def: libbackends.a liboverlays.a version.o
                    test -z "$$obj" && continue; \
                    ;; \
                *.la) \
-                   if test -n "$LTSTATIC"; then \
+                   if test -n "$(LTSTATIC)"; then \
                            base=`expr "$$i" : ".*/\(.*\).la"`; \
                            path=`expr "$$i" : "\(.*/\).*"`; \
                            obj=$$path.libs/$$base.a; \
                    fi; \
                    ;; \
+               *.dll.a) \
+                   ;; \
                *.o | *.a) \
                    obj=$$i; \
            esac; \
@@ -335,7 +337,7 @@ backends.o: backends.c $(srcdir)/slap.h
 
 depend-local-srv: FORCE
        @for i in $(SUBDIRS); do \
-               if test -d $$i -a -f $$i/Makefile ; then \
+               if test -d $$i && test -f $$i/Makefile ; then \
                        echo; echo "  cd $$i; $(MAKE) $(MFLAGS) depend"; \
                        ( cd $$i; $(MAKE) $(MFLAGS) depend ); \
                        if test $$? != 0 ; then exit 1; fi ; \
@@ -351,7 +353,7 @@ veryclean-local:
 
 clean-local-srv: FORCE
        @for i in $(SUBDIRS); do \
-               if test -d $$i -a -f $$i/Makefile ; then \
+               if test -d $$i && test -f $$i/Makefile ; then \
                        echo; echo "  cd $$i; $(MAKE) $(MFLAGS) clean"; \
                        ( cd $$i; $(MAKE) $(MFLAGS) clean ); \
                        if test $$? != 0 ; then exit 1; fi ; \
@@ -361,7 +363,7 @@ clean-local-srv: FORCE
 
 veryclean-local-srv: FORCE
        @for i in $(SUBDIRS); do \
-               if test -d $$i -a -f $$i/Makefile ; then \
+               if test -d $$i && test -f $$i/Makefile ; then \
                        echo; echo "  cd $$i; $(MAKE) $(MFLAGS) clean"; \
                        ( cd $$i; $(MAKE) $(MFLAGS) veryclean ); \
                fi; \
@@ -376,7 +378,7 @@ install-slapd: FORCE
        $(LTINSTALL) $(INSTALLFLAGS) $(STRIP) -m 755 \
                slapd$(EXEEXT) $(DESTDIR)$(libexecdir)
        @for i in $(SUBDIRS); do \
-           if test -d $$i -a -f $$i/Makefile ; then \
+           if test -d $$i && test -f $$i/Makefile ; then \
                echo; echo "  cd $$i; $(MAKE) $(MFLAGS) install"; \
                ( cd $$i; $(MAKE) $(MFLAGS) install ); \
                if test $$? != 0 ; then exit 1; fi ; \
index 91c33e9c2377e9f482128264555a99da7820ff99..f224e68e8a1b823178c7284c00ba9432fa80c11a 100644 (file)
@@ -851,7 +851,8 @@ slap_acl_get(
                                                continue;
 
                                } else if ( a->acl_dn_style == ACL_STYLE_ONE ) {
-                                       int     rdnlen = -1, sep = 0;
+                                       ber_len_t       rdnlen = 0;
+                                       int             sep = 0;
 
                                        if ( dnlen <= patlen )
                                                continue;
@@ -942,7 +943,7 @@ slap_acl_get(
                                                        continue;
        
                                        } else if ( a->acl_attrval_style == ACL_STYLE_ONE ) {
-                                               int rdnlen = -1;
+                                               ber_len_t       rdnlen = 0;
        
                                                if ( !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) )
                                                        continue;
@@ -1186,7 +1187,7 @@ acl_mask_dn(
                        }
 
                } else if ( b->a_style == ACL_STYLE_ONE ) {
-                       int rdnlen = -1;
+                       ber_len_t       rdnlen = 0;
 
                        if ( odnlen <= patlen ) {
                                goto dn_match_cleanup;
index e307b550c58663d1ad983ac1879b7331c98888ea..9b0e8e7acb507e733e7b45a378e3745fe82fd3b9 100644 (file)
@@ -84,7 +84,7 @@ slap_dynacl_config(
 
        for ( da = b->a_dynacl; da; da = da->da_next ) {
                if ( strcasecmp( da->da_name, name ) == 0 ) {
-                       fprintf( stderr,
+                       Debug( LDAP_DEBUG_ANY,
                                "%s: line %d: dynacl \"%s\" already specified.\n",
                                fname, lineno, name );
                        acl_usage();
@@ -119,8 +119,8 @@ regtest(const char *fname, int lineno, char *pat) {
        int e;
        regex_t re;
 
-       char buf[512];
-       unsigned size;
+       char            buf[ SLAP_TEXT_BUFLEN ];
+       unsigned        size;
 
        char *sp;
        char *dp;
@@ -151,18 +151,23 @@ regtest(const char *fname, int lineno, char *pat) {
 
        *dp = '\0';
        if ( size >= (sizeof(buf) - 1) ) {
-               fprintf( stderr,
+               Debug( LDAP_DEBUG_ANY,
                        "%s: line %d: regular expression \"%s\" too large\n",
                        fname, lineno, pat );
                acl_usage();
        }
 
        if ((e = regcomp(&re, buf, REG_EXTENDED|REG_ICASE))) {
-               char error[512];
+               char error[ SLAP_TEXT_BUFLEN ];
+
                regerror(e, &re, error, sizeof(error));
-               fprintf( stderr,
-                       "%s: line %d: regular expression \"%s\" bad because of %s\n",
-                       fname, lineno, pat, error );
+
+               snprintf( buf, sizeof( buf ),
+                       "regular expression \"%s\" bad because of %s",
+                       pat, error );
+               Debug( LDAP_DEBUG_ANY,
+                       "%s: line %d: %s\n",
+                       fname, lineno, buf );
                acl_usage();
        }
        regfree(&re);
@@ -183,7 +188,7 @@ regtest(const char *fname, int lineno, char *pat) {
 static int
 check_scope( BackendDB *be, AccessControl *a )
 {
-       int             patlen;
+       ber_len_t       patlen;
        struct berval   dn;
 
        dn = be->be_nsuffix[0];
@@ -252,7 +257,8 @@ regex_done:;
                         * more than one level between the suffix
                         * and the pattern */
                        if ( style == ACL_STYLE_ONE ) {
-                               int     rdnlen = -1, sep = 0;
+                               ber_len_t       rdnlen = 0;
+                               int             sep = 0;
 
                                if ( patlen > 0 ) {
                                        if ( !DN_SEPARATOR( dn.bv_val[dn.bv_len - patlen - 1] )) {
@@ -329,9 +335,9 @@ parse_acl(
                /* to clause - select which entries are protected */
                if ( strcasecmp( argv[i], "to" ) == 0 ) {
                        if ( a != NULL ) {
-                               fprintf( stderr, "%s: line %d: "
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                        "only one to clause allowed in access line\n",
-                                   fname, lineno );
+                                   fname, lineno, 0 );
                                acl_usage();
                        }
                        a = (AccessControl *) ch_calloc( 1, sizeof(AccessControl) );
@@ -345,10 +351,10 @@ parse_acl(
                                        if ( !BER_BVISEMPTY( &a->acl_dn_pat ) ||
                                                a->acl_dn_style != ACL_STYLE_REGEX )
                                        {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: dn pattern"
                                                        " already specified in to clause.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -360,7 +366,7 @@ parse_acl(
                                split( left, '.', &left, &style );
 
                                if ( right == NULL ) {
-                                       fprintf( stderr, "%s: line %d: "
+                                       Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                "missing \"=\" in \"%s\" in to clause\n",
                                            fname, lineno, left );
                                        acl_usage();
@@ -370,10 +376,10 @@ parse_acl(
                                        if ( !BER_BVISEMPTY( &a->acl_dn_pat ) ||
                                                a->acl_dn_style != ACL_STYLE_REGEX )
                                        {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: dn pattern"
                                                        " already specified in to clause.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -429,7 +435,7 @@ parse_acl(
                                                }
 
                                        } else {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "unknown dn style \"%s\" in to clause\n",
                                                    fname, lineno, style );
                                                acl_usage();
@@ -440,7 +446,7 @@ parse_acl(
 
                                if ( strcasecmp( left, "filter" ) == 0 ) {
                                        if ( (a->acl_filter = str2filter( right )) == NULL ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                "%s: line %d: bad filter \"%s\" in to clause\n",
                                                    fname, lineno, right );
                                                acl_usage();
@@ -449,10 +455,18 @@ parse_acl(
                                } else if ( strcasecmp( left, "attr" ) == 0             /* TOLERATED */
                                                || strcasecmp( left, "attrs" ) == 0 )   /* DOCUMENTED */
                                {
+                                       if ( strcasecmp( left, "attr" ) == 0 ) {
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: \"attr\" "
+                                                       "is deprecated (and undocumented); "
+                                                       "use \"attrs\" instead.\n",
+                                                       fname, lineno, 0 );
+                                       }
+
                                        a->acl_attrs = str2anlist( a->acl_attrs,
                                                right, "," );
                                        if ( a->acl_attrs == NULL ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                "%s: line %d: unknown attr \"%s\" in to clause\n",
                                                    fname, lineno, right );
                                                acl_usage();
@@ -462,16 +476,16 @@ parse_acl(
                                        char    *mr;
                                        
                                        if ( !BER_BVISEMPTY( &a->acl_attrval ) ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                "%s: line %d: attr val already specified in to clause.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
                                        if ( a->acl_attrs == NULL || !BER_BVISEMPTY( &a->acl_attrs[1].an_name ) )
                                        {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                "%s: line %d: attr val requires a single attribute.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -485,7 +499,7 @@ parse_acl(
 
                                                a->acl_attrval_mr = mr_find( mr );
                                                if ( a->acl_attrval_mr == NULL ) {
-                                                       fprintf( stderr, "%s: line %d: "
+                                                       Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                                "invalid matching rule \"%s\".\n",
                                                                fname, lineno, mr );
                                                        acl_usage();
@@ -493,11 +507,16 @@ parse_acl(
 
                                                if( !mr_usable_with_at( a->acl_attrval_mr, a->acl_attrs[ 0 ].an_desc->ad_type ) )
                                                {
-                                                       fprintf( stderr, "%s: line %d: "
+                                                       char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                                       snprintf( buf, sizeof( buf ),
                                                                "matching rule \"%s\" use "
-                                                               "with attr \"%s\" not appropriate.\n",
-                                                               fname, lineno, mr,
-                                                               a->acl_attrs[ 0 ].an_name.bv_val );
+                                                               "with attr \"%s\" not appropriate.",
+                                                               mr, a->acl_attrs[ 0 ].an_name.bv_val );
+                                                               
+
+                                                       Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
+                                                               fname, lineno, buf );
                                                        acl_usage();
                                                }
                                        }
@@ -507,11 +526,17 @@ parse_acl(
                                                        int e = regcomp( &a->acl_attrval_re, a->acl_attrval.bv_val,
                                                                REG_EXTENDED | REG_ICASE | REG_NOSUB );
                                                        if ( e ) {
-                                                               char buf[512];
-                                                               regerror( e, &a->acl_attrval_re, buf, sizeof(buf) );
-                                                               fprintf( stderr, "%s: line %d: "
-                                                                       "regular expression \"%s\" bad because of %s\n",
-                                                                       fname, lineno, right, buf );
+                                                               char    err[SLAP_TEXT_BUFLEN],
+                                                                       buf[ SLAP_TEXT_BUFLEN ];
+
+                                                               regerror( e, &a->acl_attrval_re, err, sizeof( err ) );
+
+                                                               snprintf( buf, sizeof( buf ),
+                                                                       "regular expression \"%s\" bad because of %s",
+                                                                       right, err );
+
+                                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
+                                                                       fname, lineno, buf );
                                                                acl_usage();
                                                        }
                                                        a->acl_attrval_style = ACL_STYLE_REGEX;
@@ -543,33 +568,61 @@ parse_acl(
                                                                } else if ( !strcasecmp( style, "children" ) ) {
                                                                        a->acl_attrval_style = ACL_STYLE_CHILDREN;
                                                                } else {
-                                                                       fprintf( stderr, 
-                                                                               "%s: line %d: unknown val.<style> \"%s\" "
+                                                                       char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                                                       /* FIXME: should be an error */
+
+                                                                       snprintf( buf, sizeof( buf ),
+                                                                               "unknown val.<style> \"%s\" "
                                                                                "for attributeType \"%s\" with DN syntax; "
-                                                                               "using \"base\"\n",
-                                                                               fname, lineno, style,
+                                                                               "using \"base\""
+                                                                               SLAPD_CONF_UNKNOWN_IGNORED ".",
+                                                                               style,
                                                                                a->acl_attrs[0].an_desc->ad_cname.bv_val );
+
+                                                                       Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, 
+                                                                               "%s: line %d: %s\n",
+                                                                               fname, lineno, buf );
+#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
+                                                                       acl_usage();
+#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
                                                                        a->acl_attrval_style = ACL_STYLE_BASE;
                                                                }
 
                                                                bv = a->acl_attrval;
                                                                rc = dnNormalize( 0, NULL, NULL, &bv, &a->acl_attrval, NULL );
                                                                if ( rc != LDAP_SUCCESS ) {
-                                                                       fprintf( stderr, 
-                                                                               "%s: line %d: unable to normalize DN \"%s\" "
-                                                                               "for attributeType \"%s\" (%d).\n",
-                                                                               fname, lineno, bv.bv_val,
-                                                                               a->acl_attrs[0].an_desc->ad_cname.bv_val, rc );
+                                                                       char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                                                       snprintf( buf, sizeof( buf ),
+                                                                               "unable to normalize DN \"%s\" "
+                                                                               "for attributeType \"%s\" (%d).",
+                                                                               bv.bv_val,
+                                                                               a->acl_attrs[0].an_desc->ad_cname.bv_val,
+                                                                               rc );
+                                                                       Debug( LDAP_DEBUG_ANY, 
+                                                                               "%s: line %d: %s\n",
+                                                                               fname, lineno, buf );
                                                                        acl_usage();
                                                                }
                                                                ber_memfree( bv.bv_val );
 
                                                        } else {
-                                                               fprintf( stderr, 
-                                                                       "%s: line %d: unknown val.<style> \"%s\" "
-                                                                       "for attributeType \"%s\"; using \"exact\"\n",
-                                                                       fname, lineno, style,
-                                                                       a->acl_attrs[0].an_desc->ad_cname.bv_val );
+                                                               char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                                               /* FIXME: should be an error */
+
+                                                               snprintf( buf, sizeof( buf ),
+                                                                       "unknown val.<style> \"%s\" "
+                                                                       "for attributeType \"%s\"; using \"exact\""
+                                                                       SLAPD_CONF_UNKNOWN_IGNORED ".",
+                                                                       style, a->acl_attrs[0].an_desc->ad_cname.bv_val );
+                                                               Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, 
+                                                                       "%s: line %d: %s\n",
+                                                                       fname, lineno, buf );
+#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
+                                                               acl_usage();
+#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
                                                                a->acl_attrval_style = ACL_STYLE_BASE;
                                                        }
                                                }
@@ -582,7 +635,7 @@ parse_acl(
                                                }
 
                                                if ( a->acl_attrval_mr == NULL ) {
-                                                       fprintf( stderr, "%s: line %d: "
+                                                       Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                                "attr \"%s\" must have an EQUALITY matching rule.\n",
                                                                fname, lineno, a->acl_attrs[ 0 ].an_name.bv_val );
                                                        acl_usage();
@@ -590,7 +643,7 @@ parse_acl(
                                        }
 
                                } else {
-                                       fprintf( stderr,
+                                       Debug( LDAP_DEBUG_ANY,
                                                "%s: line %d: expecting <what> got \"%s\"\n",
                                            fname, lineno, left );
                                        acl_usage();
@@ -612,7 +665,7 @@ parse_acl(
                                        struct berval bv;
                                        rc = dnNormalize( 0, NULL, NULL, &a->acl_dn_pat, &bv, NULL);
                                        if ( rc != LDAP_SUCCESS ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: bad DN \"%s\" in to DN clause\n",
                                                        fname, lineno, a->acl_dn_pat.bv_val );
                                                acl_usage();
@@ -624,11 +677,15 @@ parse_acl(
                                        int e = regcomp( &a->acl_dn_re, a->acl_dn_pat.bv_val,
                                                REG_EXTENDED | REG_ICASE );
                                        if ( e ) {
-                                               char buf[512];
-                                               regerror( e, &a->acl_dn_re, buf, sizeof(buf) );
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "regular expression \"%s\" bad because of %s\n",
-                                                       fname, lineno, right, buf );
+                                               char    err[ SLAP_TEXT_BUFLEN ],
+                                                       buf[ SLAP_TEXT_BUFLEN ];
+
+                                               regerror( e, &a->acl_dn_re, err, sizeof( err ) );
+                                               snprintf( buf, sizeof( buf ),
+                                                       "regular expression \"%s\" bad because of %s",
+                                                       right, err );
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
+                                                       fname, lineno, buf );
                                                acl_usage();
                                        }
                                }
@@ -637,9 +694,9 @@ parse_acl(
                /* by clause - select who has what access to entries */
                } else if ( strcasecmp( argv[i], "by" ) == 0 ) {
                        if ( a == NULL ) {
-                               fprintf( stderr, "%s: line %d: "
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                        "to clause required before by clause in access line\n",
-                                   fname, lineno );
+                                       fname, lineno, 0 );
                                acl_usage();
                        }
 
@@ -652,9 +709,9 @@ parse_acl(
                        ACL_INVALIDATE( b->a_access_mask );
 
                        if ( ++i == argc ) {
-                               fprintf( stderr,
-                           "%s: line %d: premature eol: expecting <who>\n",
-                                   fname, lineno );
+                               Debug( LDAP_DEBUG_ANY,
+                                       "%s: line %d: premature EOL: expecting <who>\n",
+                                       fname, lineno, 0 );
                                acl_usage();
                        }
 
@@ -678,16 +735,16 @@ parse_acl(
                                                if ( style_level != NULL ) {
                                                        char *p = strchr( style_level, '}' );
                                                        if ( p == NULL ) {
-                                                               fprintf( stderr,
+                                                               Debug( LDAP_DEBUG_ANY,
                                                                        "%s: line %d: premature eol: "
                                                                        "expecting closing '}' in \"level{n}\"\n",
-                                                                       fname, lineno );
+                                                                       fname, lineno, 0 );
                                                                acl_usage();
                                                        } else if ( p == style_level ) {
-                                                               fprintf( stderr,
+                                                               Debug( LDAP_DEBUG_ANY,
                                                                        "%s: line %d: empty level "
                                                                        "in \"level{n}\"\n",
-                                                                       fname, lineno );
+                                                                       fname, lineno, 0 );
                                                                acl_usage();
                                                        }
                                                        p[0] = '\0';
@@ -721,10 +778,10 @@ parse_acl(
 
                                        level = strtol( style_level, &next, 10 );
                                        if ( next[0] != '\0' ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: unable to parse level "
                                                        "in \"level{n}\"\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -742,15 +799,20 @@ parse_acl(
                                } else if ( strcasecmp( style, "path" ) == 0 ) {
                                        sty = ACL_STYLE_PATH;
 #ifndef LDAP_PF_LOCAL
-                                       fprintf( stderr, "%s: line %d: "
-                                               "path style modifier is useless without local\n",
-                                               fname, lineno );
+                                       Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL,
+                                               "%s: line %d: "
+                                               "\"path\" style modifier is useless without local"
+                                               SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+                                               fname, lineno, 0 );
+#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
+                                       acl_usage();
+#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
 #endif /* LDAP_PF_LOCAL */
 
                                } else {
-                                       fprintf( stderr,
+                                       Debug( LDAP_DEBUG_ANY,
                                                "%s: line %d: unknown style \"%s\" in by clause\n",
-                                           fname, lineno, style );
+                                               fname, lineno, style );
                                        acl_usage();
                                }
 
@@ -759,29 +821,17 @@ parse_acl(
                                {
                                        switch ( sty ) {
                                        case ACL_STYLE_REGEX:
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "\"regex\" style implies "
                                                        "\"expand\" modifier" 
                                                        SLAPD_CONF_UNKNOWN_IGNORED ".\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
 #ifdef SLAPD_CONF_UNKNOWN_BAILOUT
                                                acl_usage();
 #endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
                                                break;
 
                                        case ACL_STYLE_EXPAND:
-#if 0
-                                               /* FIXME: now it's legal... */
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "\"expand\" style used "
-                                                       "in conjunction with "
-                                                       "\"expand\" modifier"
-                                                       SLAPD_CONF_UNKNOWN_IGNORED ".\n",
-                                                       fname, lineno );
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-                                               acl_usage();
-#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
-#endif
                                                break;
 
                                        default:
@@ -795,11 +845,15 @@ parse_acl(
                                if ( ( sty == ACL_STYLE_EXPAND || expand )
                                                && a->acl_dn_style != ACL_STYLE_REGEX )
                                {
-                                       fprintf( stderr, "%s: line %d: "
+                                       Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, "%s: line %d: "
                                                "\"expand\" style or modifier used "
                                                "in conjunction with "
-                                               "a non-regex <what> clause\n",
-                                               fname, lineno );
+                                               "a non-regex <what> clause"
+                                               SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+                                               fname, lineno, 0 );
+#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
+                                               acl_usage();
+#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
                                }
 
                                if ( strncasecmp( left, "real", STRLENOF( "real" ) ) == 0 ) {
@@ -884,10 +938,10 @@ parse_acl(
                                                }
 
                                        } else if ( right == NULL || *right == '\0' ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "missing \"=\" in (or value after) \"%s\" "
                                                        "in by clause\n",
-                                                   fname, lineno, left );
+                                                       fname, lineno, left );
                                                acl_usage();
 
                                        } else {
@@ -900,9 +954,9 @@ parse_acl(
 
                                if ( !BER_BVISNULL( &bv ) ) {
                                        if ( !BER_BVISEMPTY( &bdn->a_pat ) ) {
-                                               fprintf( stderr,
-                                                   "%s: line %d: dn pattern already specified.\n",
-                                                   fname, lineno );
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: dn pattern already specified.\n",
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -915,12 +969,22 @@ parse_acl(
                                                rc = dnNormalize(0, NULL, NULL,
                                                        &bv, &bdn->a_pat, NULL);
                                                if ( rc != LDAP_SUCCESS ) {
-                                                       fprintf( stderr,
+                                                       Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: bad DN \"%s\" in by DN clause\n",
                                                                fname, lineno, bv.bv_val );
                                                        acl_usage();
                                                }
                                                free( bv.bv_val );
+                                               if ( sty == ACL_STYLE_BASE
+                                                       && be != NULL
+                                                       && !BER_BVISNULL( &be->be_rootndn )
+                                                       && dn_match( &bdn->a_pat, &be->be_rootndn ) )
+                                               {
+                                                       Debug( LDAP_DEBUG_ANY,
+                                                               "%s: line %d: rootdn is always granted "
+                                                               "unlimited privileges.\n",
+                                                               fname, lineno, 0 );
+                                               }
 
                                        } else {
                                                bdn->a_pat = bv;
@@ -931,7 +995,8 @@ parse_acl(
                                                int     gotit = 0;
 
                                                for ( exp = strchr( bdn->a_pat.bv_val, '$' );
-                                                               exp && exp - bdn->a_pat.bv_val < bdn->a_pat.bv_len;
+                                                               exp && (ber_len_t)(exp - bdn->a_pat.bv_val)
+                                                                       < bdn->a_pat.bv_len;
                                                                exp = strchr( exp, '$' ) )
                                                {
                                                        if ( isdigit( exp[ 1 ] ) ) {
@@ -944,11 +1009,11 @@ parse_acl(
                                                        bdn->a_expand = expand;
 
                                                } else {
-                                                       fprintf( stderr,
+                                                       Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: \"expand\" used "
                                                                "with no expansions in \"pattern\""
                                                                SLAPD_CONF_UNKNOWN_IGNORED ".\n",
-                                                               fname, lineno );
+                                                               fname, lineno, 0 );
 #ifdef SLAPD_CONF_UNKNOWN_BAILOUT
                                                        acl_usage();
 #endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
@@ -959,21 +1024,21 @@ parse_acl(
 
                                        } else {
                                                if ( level < 0 ) {
-                                                       fprintf( stderr,
+                                                       Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: bad negative level \"%d\" "
                                                                "in by DN clause\n",
                                                                fname, lineno, level );
                                                        acl_usage();
                                                } else if ( level == 1 ) {
-                                                       fprintf( stderr,
+                                                       Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: \"onelevel\" should be used "
                                                                "instead of \"level{1}\" in by DN clause\n",
-                                                               fname, lineno );
+                                                               fname, lineno, 0 );
                                                } else if ( level == 0 && sty == ACL_STYLE_LEVEL ) {
-                                                       fprintf( stderr,
+                                                       Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: \"base\" should be used "
                                                                "instead of \"level{0}\" in by DN clause\n",
-                                                               fname, lineno );
+                                                               fname, lineno, 0 );
                                                }
 
                                                bdn->a_level = level;
@@ -983,7 +1048,7 @@ parse_acl(
 
                                if ( strcasecmp( left, "dnattr" ) == 0 ) {
                                        if ( right == NULL || right[0] == '\0' ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "missing \"=\" in (or value after) \"%s\" "
                                                        "in by clause\n",
                                                        fname, lineno, left );
@@ -991,18 +1056,23 @@ parse_acl(
                                        }
 
                                        if( bdn->a_at != NULL ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: dnattr already specified.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
                                        rc = slap_str2ad( right, &bdn->a_at, &text );
 
                                        if( rc != LDAP_SUCCESS ) {
-                                               fprintf( stderr,
-                                                       "%s: line %d: dnattr \"%s\": %s\n",
-                                                       fname, lineno, right, text );
+                                               char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                               snprintf( buf, sizeof( buf ),
+                                                       "dnattr \"%s\": %s",
+                                                       right, text );
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: %s\n",
+                                                       fname, lineno, buf );
                                                acl_usage();
                                        }
 
@@ -1012,16 +1082,21 @@ parse_acl(
                                                !is_at_syntax( bdn->a_at->ad_type,
                                                SLAPD_NAMEUID_SYNTAX ))
                                        {
-                                               fprintf( stderr,
-                                                       "%s: line %d: dnattr \"%s\": "
+                                               char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                               snprintf( buf, sizeof( buf ),
+                                                       "dnattr \"%s\": "
                                                        "inappropriate syntax: %s\n",
-                                                       fname, lineno, right,
+                                                       right,
                                                        bdn->a_at->ad_type->sat_syntax_oid );
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: %s\n",
+                                                       fname, lineno, buf );
                                                acl_usage();
                                        }
 
                                        if( bdn->a_at->ad_type->sat_equality == NULL ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: dnattr \"%s\": "
                                                        "inappropriate matching (no EQUALITY)\n",
                                                        fname, lineno, right );
@@ -1038,10 +1113,11 @@ parse_acl(
                                        switch ( sty ) {
                                        case ACL_STYLE_REGEX:
                                                /* legacy, tolerated */
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL,
+                                                       "%s: line %d: "
                                                        "deprecated group style \"regex\"; "
-                                                       "use \"expand\" instead\n",
-                                                       fname, lineno );
+                                                       "use \"expand\" instead.\n",
+                                                       fname, lineno, 0 );
                                                sty = ACL_STYLE_EXPAND;
                                                break;
 
@@ -1053,24 +1129,26 @@ parse_acl(
 
                                        default:
                                                /* unknown */
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "inappropriate style \"%s\" in by clause\n",
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: "
+                                                       "inappropriate style \"%s\" in by clause.\n",
                                                        fname, lineno, style );
                                                acl_usage();
                                        }
 
                                        if ( right == NULL || right[0] == '\0' ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: "
                                                        "missing \"=\" in (or value after) \"%s\" "
-                                                       "in by clause\n",
+                                                       "in by clause.\n",
                                                        fname, lineno, left );
                                                acl_usage();
                                        }
 
                                        if ( !BER_BVISEMPTY( &b->a_group_pat ) ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: group pattern already specified.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -1096,8 +1174,8 @@ parse_acl(
                                                rc = dnNormalize( 0, NULL, NULL, &bv,
                                                        &b->a_group_pat, NULL );
                                                if ( rc != LDAP_SUCCESS ) {
-                                                       fprintf( stderr,
-                                                               "%s: line %d: bad DN \"%s\"\n",
+                                                       Debug( LDAP_DEBUG_ANY,
+                                                               "%s: line %d: bad DN \"%s\".\n",
                                                                fname, lineno, right );
                                                        acl_usage();
                                                }
@@ -1108,9 +1186,9 @@ parse_acl(
                                                *--value = '/';
 
                                                if ( b->a_group_oc == NULL ) {
-                                                       fprintf( stderr,
+                                                       Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: group objectclass "
-                                                               "\"%s\" unknown\n",
+                                                               "\"%s\" unknown.\n",
                                                                fname, lineno, value );
                                                        acl_usage();
                                                }
@@ -1119,9 +1197,9 @@ parse_acl(
                                                b->a_group_oc = oc_find( SLAPD_GROUP_CLASS );
 
                                                if( b->a_group_oc == NULL ) {
-                                                       fprintf( stderr,
+                                                       Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: group default objectclass "
-                                                               "\"%s\" unknown\n",
+                                                               "\"%s\" unknown.\n",
                                                                fname, lineno, SLAPD_GROUP_CLASS );
                                                        acl_usage();
                                                }
@@ -1130,9 +1208,9 @@ parse_acl(
                                        if ( is_object_subclass( slap_schema.si_oc_referral,
                                                b->a_group_oc ) )
                                        {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: group objectclass \"%s\" "
-                                                       "is subclass of referral\n",
+                                                       "is subclass of referral.\n",
                                                        fname, lineno, value );
                                                acl_usage();
                                        }
@@ -1140,9 +1218,9 @@ parse_acl(
                                        if ( is_object_subclass( slap_schema.si_oc_alias,
                                                b->a_group_oc ) )
                                        {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: group objectclass \"%s\" "
-                                                       "is subclass of alias\n",
+                                                       "is subclass of alias.\n",
                                                        fname, lineno, value );
                                                acl_usage();
                                        }
@@ -1151,9 +1229,14 @@ parse_acl(
                                                rc = slap_str2ad( name, &b->a_group_at, &text );
 
                                                if( rc != LDAP_SUCCESS ) {
-                                                       fprintf( stderr,
-                                                               "%s: line %d: group \"%s\": %s\n",
-                                                               fname, lineno, right, text );
+                                                       char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                                       snprintf( buf, sizeof( buf ),
+                                                               "group \"%s\": %s.",
+                                                               right, text );
+                                                       Debug( LDAP_DEBUG_ANY,
+                                                               "%s: line %d: %s\n",
+                                                               fname, lineno, buf );
                                                        acl_usage();
                                                }
                                                *--name = '/';
@@ -1162,9 +1245,14 @@ parse_acl(
                                                rc = slap_str2ad( SLAPD_GROUP_ATTR, &b->a_group_at, &text );
 
                                                if ( rc != LDAP_SUCCESS ) {
-                                                       fprintf( stderr,
-                                                               "%s: line %d: group \"%s\": %s\n",
-                                                               fname, lineno, SLAPD_GROUP_ATTR, text );
+                                                       char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                                       snprintf( buf, sizeof( buf ),
+                                                               "group \"%s\": %s.",
+                                                               SLAPD_GROUP_ATTR, text );
+                                                       Debug( LDAP_DEBUG_ANY,
+                                                               "%s: line %d: %s\n",
+                                                               fname, lineno, buf );
                                                        acl_usage();
                                                }
                                        }
@@ -1175,10 +1263,15 @@ parse_acl(
                                                SLAPD_NAMEUID_SYNTAX ) &&
                                                !is_at_subtype( b->a_group_at->ad_type, slap_schema.si_ad_labeledURI->ad_type ) )
                                        {
-                                               fprintf( stderr,
-                                                       "%s: line %d: group \"%s\": inappropriate syntax: %s\n",
-                                                       fname, lineno, right,
+                                               char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                               snprintf( buf, sizeof( buf ),
+                                                       "group \"%s\": inappropriate syntax: %s.",
+                                                       right,
                                                        b->a_group_at->ad_type->sat_syntax_oid );
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: %s\n",
+                                                       fname, lineno, buf );
                                                acl_usage();
                                        }
 
@@ -1194,11 +1287,14 @@ parse_acl(
                                                        vals, NULL );
 
                                                if( rc != 0 ) {
-                                                       fprintf( stderr, "%s: line %d: "
-                                                               "group: \"%s\" not allowed by \"%s\"\n",
-                                                               fname, lineno,
+                                                       char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                                       snprintf( buf, sizeof( buf ),
+                                                               "group: \"%s\" not allowed by \"%s\".",
                                                                b->a_group_at->ad_cname.bv_val,
                                                                b->a_group_oc->soc_oid );
+                                                       Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
+                                                               fname, lineno, buf );
                                                        acl_usage();
                                                }
                                        }
@@ -1218,24 +1314,24 @@ parse_acl(
                                                break;
 
                                        default:
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "inappropriate style \"%s\" in by clause\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "inappropriate style \"%s\" in by clause.\n",
                                                    fname, lineno, style );
                                                acl_usage();
                                        }
 
                                        if ( right == NULL || right[0] == '\0' ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "missing \"=\" in (or value after) \"%s\" "
-                                                       "in by clause\n",
+                                                       "in by clause.\n",
                                                        fname, lineno, left );
                                                acl_usage();
                                        }
 
                                        if ( !BER_BVISEMPTY( &b->a_peername_pat ) ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "peername pattern already specified.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -1261,7 +1357,7 @@ parse_acl(
                                                        b->a_peername_addr = inet_addr( addr );
                                                        if ( b->a_peername_addr == (unsigned long)(-1) ) {
                                                                /* illegal address */
-                                                               fprintf( stderr, "%s: line %d: "
+                                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                                        "illegal peername address \"%s\".\n",
                                                                        fname, lineno, addr );
                                                                acl_usage();
@@ -1274,7 +1370,7 @@ parse_acl(
                                                                        (unsigned long)(-1) )
                                                                {
                                                                        /* illegal mask */
-                                                                       fprintf( stderr, "%s: line %d: "
+                                                                       Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                                                "illegal peername address mask "
                                                                                "\"%s\".\n",
                                                                                fname, lineno, mask );
@@ -1289,7 +1385,7 @@ parse_acl(
                                                                b->a_peername_port = strtol( port, &end, 10 );
                                                                if ( end[0] != '}' ) {
                                                                        /* illegal port */
-                                                                       fprintf( stderr, "%s: line %d: "
+                                                                       Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                                                "illegal peername port specification "
                                                                                "\"{%s}\".\n",
                                                                                fname, lineno, port );
@@ -1312,14 +1408,14 @@ parse_acl(
 
                                        default:
                                                /* unknown */
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause\n",
                                                    fname, lineno, style );
                                                acl_usage();
                                        }
 
                                        if ( right == NULL || right[0] == '\0' ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "missing \"=\" in (or value after) \"%s\" "
                                                        "in by clause\n",
                                                        fname, lineno, left );
@@ -1327,9 +1423,9 @@ parse_acl(
                                        }
 
                                        if ( !BER_BVISNULL( &b->a_sockname_pat ) ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "sockname pattern already specified.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -1358,11 +1454,11 @@ parse_acl(
                                        case ACL_STYLE_EXPAND:
                                                /* tolerated: means exact,expand */
                                                if ( expand ) {
-                                                       fprintf( stderr,
+                                                       Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: "
                                                                "\"expand\" modifier "
-                                                               "with \"expand\" style\n",
-                                                               fname, lineno );
+                                                               "with \"expand\" style.\n",
+                                                               fname, lineno, 0 );
                                                }
                                                sty = ACL_STYLE_BASE;
                                                expand = 1;
@@ -1370,24 +1466,24 @@ parse_acl(
 
                                        default:
                                                /* unknown */
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "inappropriate style \"%s\" in by clause\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "inappropriate style \"%s\" in by clause.\n",
                                                    fname, lineno, style );
                                                acl_usage();
                                        }
 
                                        if ( right == NULL || right[0] == '\0' ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "missing \"=\" in (or value after) \"%s\" "
-                                                       "in by clause\n",
+                                                       "in by clause.\n",
                                                        fname, lineno, left );
                                                acl_usage();
                                        }
 
                                        if ( !BER_BVISEMPTY( &b->a_domain_pat ) ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: domain pattern already specified.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -1417,24 +1513,24 @@ parse_acl(
 
                                        default:
                                                /* unknown */
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "inappropriate style \"%s\" in by clause\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "inappropriate style \"%s\" in by clause.\n",
                                                    fname, lineno, style );
                                                acl_usage();
                                        }
 
                                        if ( right == NULL || right[0] == '\0' ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "missing \"=\" in (or value after) \"%s\" "
-                                                       "in by clause\n",
+                                                       "in by clause.\n",
                                                        fname, lineno, left );
                                                acl_usage();
                                        }
 
                                        if ( !BER_BVISEMPTY( &b->a_sockurl_pat ) ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: sockurl pattern already specified.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -1456,11 +1552,12 @@ parse_acl(
                                        switch ( sty ) {
                                                /* deprecated */
                                        case ACL_STYLE_REGEX:
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL,
+                                                       "%s: line %d: "
                                                        "deprecated set style "
                                                        "\"regex\" in <by> clause; "
-                                                       "use \"expand\" instead\n",
-                                                       fname, lineno );
+                                                       "use \"expand\" instead.\n",
+                                                       fname, lineno, 0 );
                                                sty = ACL_STYLE_EXPAND;
                                                /* FALLTHRU */
                                                
@@ -1469,23 +1566,23 @@ parse_acl(
                                                break;
 
                                        default:
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "inappropriate style \"%s\" in by clause\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "inappropriate style \"%s\" in by clause.\n",
                                                        fname, lineno, style );
                                                acl_usage();
                                        }
 
                                        if ( !BER_BVISEMPTY( &b->a_set_pat ) ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: set attribute already specified.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
                                        if ( right == NULL || *right == '\0' ) {
-                                               fprintf( stderr,
-                                                       "%s: line %d: no set is defined\n",
-                                                       fname, lineno );
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: no set is defined.\n",
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -1514,8 +1611,8 @@ parse_acl(
 
                                        if ( name ) {
                                                if ( slap_dynacl_config( fname, lineno, b, name, opts, sty, right ) ) {
-                                                       fprintf( stderr, "%s: line %d: "
-                                                               "unable to configure dynacl \"%s\"\n",
+                                                       Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                               "unable to configure dynacl \"%s\".\n",
                                                                fname, lineno, name );
                                                        acl_usage();
                                                }
@@ -1528,16 +1625,16 @@ parse_acl(
 #ifdef SLAPD_ACI_ENABLED
                                if ( strcasecmp( left, "aci" ) == 0 ) {
                                        if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) {
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "inappropriate style \"%s\" in by clause\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "inappropriate style \"%s\" in by clause.\n",
                                                    fname, lineno, style );
                                                acl_usage();
                                        }
 
                                        if( b->a_aci_at != NULL ) {
-                                               fprintf( stderr,
-                                                       "%s: line %d: aci attribute already specified.\n",
-                                                       fname, lineno );
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: ACI attribute already specified.\n",
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
@@ -1545,9 +1642,14 @@ parse_acl(
                                                rc = slap_str2ad( right, &b->a_aci_at, &text );
 
                                                if( rc != LDAP_SUCCESS ) {
-                                                       fprintf( stderr,
-                                                               "%s: line %d: aci \"%s\": %s\n",
-                                                               fname, lineno, right, text );
+                                                       char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                                       snprintf( buf, sizeof( buf ),
+                                                               "aci \"%s\": %s.",
+                                                               right, text );
+                                                       Debug( LDAP_DEBUG_ANY,
+                                                               "%s: line %d: %s\n",
+                                                               fname, lineno, buf );
                                                        acl_usage();
                                                }
 
@@ -1558,10 +1660,14 @@ parse_acl(
                                        if( !is_at_syntax( b->a_aci_at->ad_type,
                                                SLAPD_ACI_SYNTAX) )
                                        {
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "aci \"%s\": inappropriate syntax: %s\n",
-                                                       fname, lineno, right,
+                                               char    buf[ SLAP_TEXT_BUFLEN ];
+
+                                               snprintf( buf, sizeof( buf ),
+                                                       "ACI \"%s\": inappropriate syntax: %s.",
+                                                       right,
                                                        b->a_aci_at->ad_type->sat_syntax_oid );
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
+                                                       fname, lineno, buf );
                                                acl_usage();
                                        }
 
@@ -1572,37 +1678,37 @@ parse_acl(
 
                                if ( strcasecmp( left, "ssf" ) == 0 ) {
                                        if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "inappropriate style \"%s\" in by clause\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "inappropriate style \"%s\" in by clause.\n",
                                                    fname, lineno, style );
                                                acl_usage();
                                        }
 
                                        if ( b->a_authz.sai_ssf ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: ssf attribute already specified.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
                                        if ( right == NULL || *right == '\0' ) {
-                                               fprintf( stderr,
-                                                       "%s: line %d: no ssf is defined\n",
-                                                       fname, lineno );
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: no ssf is defined.\n",
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
                                        b->a_authz.sai_ssf = strtol( right, &next, 10 );
                                        if ( next == NULL || next[0] != '\0' ) {
-                                               fprintf( stderr,
-                                                       "%s: line %d: unable to parse ssf value (%s)\n",
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: unable to parse ssf value (%s).\n",
                                                        fname, lineno, right );
                                                acl_usage();
                                        }
 
                                        if ( !b->a_authz.sai_ssf ) {
-                                               fprintf( stderr,
-                                                       "%s: line %d: invalid ssf value (%s)\n",
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: invalid ssf value (%s).\n",
                                                        fname, lineno, right );
                                                acl_usage();
                                        }
@@ -1611,37 +1717,37 @@ parse_acl(
 
                                if ( strcasecmp( left, "transport_ssf" ) == 0 ) {
                                        if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "inappropriate style \"%s\" in by clause\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "inappropriate style \"%s\" in by clause.\n",
                                                        fname, lineno, style );
                                                acl_usage();
                                        }
 
                                        if ( b->a_authz.sai_transport_ssf ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "transport_ssf attribute already specified.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
                                        if ( right == NULL || *right == '\0' ) {
-                                               fprintf( stderr,
-                                                       "%s: line %d: no transport_ssf is defined\n",
-                                                       fname, lineno );
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: no transport_ssf is defined.\n",
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
                                        b->a_authz.sai_transport_ssf = strtol( right, &next, 10 );
                                        if ( next == NULL || next[0] != '\0' ) {
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "unable to parse transport_ssf value (%s)\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "unable to parse transport_ssf value (%s).\n",
                                                        fname, lineno, right );
                                                acl_usage();
                                        }
 
                                        if ( !b->a_authz.sai_transport_ssf ) {
-                                               fprintf( stderr,
-                                                       "%s: line %d: invalid transport_ssf value (%s)\n",
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: invalid transport_ssf value (%s).\n",
                                                        fname, lineno, right );
                                                acl_usage();
                                        }
@@ -1650,37 +1756,37 @@ parse_acl(
 
                                if ( strcasecmp( left, "tls_ssf" ) == 0 ) {
                                        if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "inappropriate style \"%s\" in by clause\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "inappropriate style \"%s\" in by clause.\n",
                                                        fname, lineno, style );
                                                acl_usage();
                                        }
 
                                        if ( b->a_authz.sai_tls_ssf ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "tls_ssf attribute already specified.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
                                        if ( right == NULL || *right == '\0' ) {
-                                               fprintf( stderr,
+                                               Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: no tls_ssf is defined\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
                                        b->a_authz.sai_tls_ssf = strtol( right, &next, 10 );
                                        if ( next == NULL || next[0] != '\0' ) {
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "unable to parse tls_ssf value (%s)\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "unable to parse tls_ssf value (%s).\n",
                                                        fname, lineno, right );
                                                acl_usage();
                                        }
 
                                        if ( !b->a_authz.sai_tls_ssf ) {
-                                               fprintf( stderr,
-                                                       "%s: line %d: invalid tls_ssf value (%s)\n",
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: invalid tls_ssf value (%s).\n",
                                                        fname, lineno, right );
                                                acl_usage();
                                        }
@@ -1689,37 +1795,37 @@ parse_acl(
 
                                if ( strcasecmp( left, "sasl_ssf" ) == 0 ) {
                                        if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "inappropriate style \"%s\" in by clause\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "inappropriate style \"%s\" in by clause.\n",
                                                        fname, lineno, style );
                                                acl_usage();
                                        }
 
                                        if ( b->a_authz.sai_sasl_ssf ) {
-                                               fprintf( stderr, "%s: line %d: "
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "sasl_ssf attribute already specified.\n",
-                                                       fname, lineno );
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
                                        if ( right == NULL || *right == '\0' ) {
-                                               fprintf( stderr,
-                                                       "%s: line %d: no sasl_ssf is defined\n",
-                                                       fname, lineno );
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: no sasl_ssf is defined.\n",
+                                                       fname, lineno, 0 );
                                                acl_usage();
                                        }
 
                                        b->a_authz.sai_sasl_ssf = strtol( right, &next, 10 );
                                        if ( next == NULL || next[0] != '\0' ) {
-                                               fprintf( stderr, "%s: line %d: "
-                                                       "unable to parse sasl_ssf value (%s)\n",
+                                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                                       "unable to parse sasl_ssf value (%s).\n",
                                                        fname, lineno, right );
                                                acl_usage();
                                        }
 
                                        if ( !b->a_authz.sai_sasl_ssf ) {
-                                               fprintf( stderr,
-                                                       "%s: line %d: invalid sasl_ssf value (%s)\n",
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: invalid sasl_ssf value (%s).\n",
                                                        fname, lineno, right );
                                                acl_usage();
                                        }
@@ -1787,8 +1893,8 @@ parse_acl(
                        }
 
                        if ( ACL_IS_INVALID( b->a_access_mask ) ) {
-                               fprintf( stderr,
-                                       "%s: line %d: expecting <access> got \"%s\"\n",
+                               Debug( LDAP_DEBUG_ANY,
+                                       "%s: line %d: expecting <access> got \"%s\".\n",
                                        fname, lineno, left );
                                acl_usage();
                        }
@@ -1817,7 +1923,7 @@ parse_acl(
                        access_append( &a->acl_access, b );
 
                } else {
-                       fprintf( stderr,
+                       Debug( LDAP_DEBUG_ANY,
                                "%s: line %d: expecting \"to\" "
                                "or \"by\" got \"%s\"\n",
                                fname, lineno, argv[i] );
@@ -1827,9 +1933,14 @@ parse_acl(
 
        /* if we have no real access clause, complain and do nothing */
        if ( a == NULL ) {
-               fprintf( stderr, "%s: line %d: "
-                       "warning: no access clause(s) specified in access line\n",
-                       fname, lineno );
+               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                       "warning: no access clause(s) "
+                       "specified in access line"
+                       SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+                       fname, lineno, 0 );
+#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
+               acl_usage();
+#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
 
        } else {
 #ifdef LDAP_DEBUG
@@ -1839,46 +1950,51 @@ parse_acl(
 #endif
        
                if ( a->acl_access == NULL ) {
-                       fprintf( stderr, "%s: line %d: "
-                               "warning: no by clause(s) specified in access line\n",
-                               fname, lineno );
+                       Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                               "warning: no by clause(s) "
+                               "specified in access line"
+                               SLAPD_CONF_UNKNOWN_IGNORED ".\n",
+                               fname, lineno, 0 );
+#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
+                       acl_usage();
+#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
                }
 
                if ( be != NULL ) {
                        if ( !BER_BVISNULL( &be->be_nsuffix[ 1 ] ) ) {
-                               fprintf( stderr, "%s: line %d: warning: "
+                               Debug( LDAP_DEBUG_ACL, "%s: line %d: warning: "
                                        "scope checking only applies to single-valued "
                                        "suffix databases\n",
-                                       fname, lineno );
+                                       fname, lineno, 0 );
                                /* go ahead, since checking is not authoritative */
                        }
 
                        switch ( check_scope( be, a ) ) {
                        case ACL_SCOPE_UNKNOWN:
-                               fprintf( stderr, "%s: line %d: warning: "
+                               Debug( LDAP_DEBUG_ACL, "%s: line %d: warning: "
                                        "cannot assess the validity of the ACL scope within "
                                        "backend naming context\n",
-                                       fname, lineno );
+                                       fname, lineno, 0 );
                                break;
 
                        case ACL_SCOPE_WARN:
-                               fprintf( stderr, "%s: line %d: warning: "
+                               Debug( LDAP_DEBUG_ACL, "%s: line %d: warning: "
                                        "ACL could be out of scope within backend naming context\n",
-                                       fname, lineno );
+                                       fname, lineno, 0 );
                                break;
 
                        case ACL_SCOPE_PARTIAL:
-                               fprintf( stderr, "%s: line %d: warning: "
+                               Debug( LDAP_DEBUG_ACL, "%s: line %d: warning: "
                                        "ACL appears to be partially out of scope within "
                                        "backend naming context\n",
-                                       fname, lineno );
+                                       fname, lineno, 0 );
                                break;
 
                        case ACL_SCOPE_ERR:
-                               fprintf( stderr, "%s: line %d: warning: "
+                               Debug( LDAP_DEBUG_ACL, "%s: line %d: warning: "
                                        "ACL appears to be out of scope within "
                                        "backend naming context\n",
-                                       fname, lineno );
+                                       fname, lineno, 0 );
                                break;
 
                        default:
@@ -2118,12 +2234,16 @@ str2accessmask( const char *str )
 static void
 acl_usage( void )
 {
-       fprintf( stderr, "%s%s%s\n",
+       char *access =
                "<access clause> ::= access to <what> "
-                               "[ by <who> <access> [ <control> ] ]+ \n"
+                               "[ by <who> <access> [ <control> ] ]+ \n";
+
+       char *what =
                "<what> ::= * | [dn[.<dnstyle>]=<DN>] [filter=<filter>] [attrs=<attrlist>]\n"
                "<attrlist> ::= <attr> [val[/matchingRule][.<attrstyle>]=<value>] | <attr> , <attrlist>\n"
-               "<attr> ::= <attrname> | entry | children\n",
+               "<attr> ::= <attrname> | entry | children\n";
+
+       char *who =
                "<who> ::= [ * | anonymous | users | self | dn[.<dnstyle>]=<DN> ]\n"
                        "\t[ realanonymous | realusers | realself | realdn[.<dnstyle>]=<DN> ]\n"
                        "\t[dnattr=<attrname>]\n"
@@ -2131,13 +2251,14 @@ acl_usage( void )
                        "\t[group[/<objectclass>[/<attrname>]][.<style>]=<group>]\n"
                        "\t[peername[.<peernamestyle>]=<peer>] [sockname[.<style>]=<name>]\n"
                        "\t[domain[.<domainstyle>]=<domain>] [sockurl[.<style>]=<url>]\n"
-#ifdef SLAPD_ACI_ENABLED
-                       "\t[aci[=<attrname>]]\n"
-#endif
 #ifdef SLAP_DYNACL
                        "\t[dynacl/<name>[/<options>][.<dynstyle>][=<pattern>]]\n"
-#endif /* SLAP_DYNACL */
-                       "\t[ssf=<n>] [transport_ssf=<n>] [tls_ssf=<n>] [sasl_ssf=<n>]\n",
+#else /* ! SLAP_DYNACL */
+#ifdef SLAPD_ACI_ENABLED
+                       "\t[aci[=<attrname>]]\n"
+#endif /* SLAPD_ACI_ENABLED */
+#endif /* ! SLAP_DYNACL */
+                       "\t[ssf=<n>] [transport_ssf=<n>] [tls_ssf=<n>] [sasl_ssf=<n>]\n"
                "<style> ::= exact | regex | base(Object)\n"
                "<dnstyle> ::= base(Object) | one(level) | sub(tree) | children | "
                        "exact | regex\n"
@@ -2149,7 +2270,15 @@ acl_usage( void )
                "<level> ::= none|disclose|auth|compare|search|read|{write|add|delete}|manage\n"
                "<priv> ::= {=|+|-}{0|d|x|c|s|r|{w|a|z}|m}+\n"
                "<control> ::= [ stop | continue | break ]\n"
-       );
+#ifdef SLAP_DYNACL
+#ifdef SLAPD_ACI_ENABLED
+               "dynacl:\n"
+               "\t<name>=ACI\t<pattern>=<attrname>\n"
+#endif /* SLAPD_ACI_ENABLED */
+#endif /* ! SLAP_DYNACL */
+               "";
+
+       Debug( LDAP_DEBUG_ANY, "%s%s%s\n", access, who, what );
        exit( EXIT_FAILURE );
 }
 
@@ -2374,8 +2503,9 @@ str2access( const char *str )
 
        } else if ( strcasecmp( str, "disclose" ) == 0 ) {
 #ifndef SLAP_ACL_HONOR_DISCLOSE
-               fprintf( stderr, "str2access: warning, "
-                       "\"disclose\" privilege disabled.\n" );
+               Debug( LDAP_DEBUG_ACL, "str2access: warning, "
+                       "\"disclose\" privilege disabled.\n",
+               0, 0, 0 );
 #endif /* SLAP_ACL_HONOR_DISCLOSE */
                return ACL_DISCLOSE;
 
@@ -2701,7 +2831,6 @@ acl_unparse( AccessControl *a, struct berval *bv )
 }
 
 #ifdef LDAP_DEBUG
-
 static void
 print_acl( Backend *be, AccessControl *a )
 {
index 2b32e533c78812a9e425f7a2316a152c67852815..676cf8d86f39d2881600b2d4d7907132c5c8cbf2 100644 (file)
@@ -770,11 +770,15 @@ int slap_bv2undef_ad(
 }
 
 static int
-undef_remove(
+undef_promote(
        AttributeType   *at,
-       char            *name )
+       char            *name,
+       AttributeType   *nat )
 {
-       AttributeDescription    **u_ad;
+       AttributeDescription    **u_ad, **n_ad;
+
+       /* Get to last ad on the new type */
+       for ( n_ad = &nat->sat_ad; *n_ad; n_ad = &(*n_ad)->ad_next ) ;
 
        for ( u_ad = &at->sat_ad; *u_ad; ) {
                struct berval   bv;
@@ -791,8 +795,9 @@ undef_remove(
 
                        *u_ad = (*u_ad)->ad_next;
 
-                       ch_free( tmp );
-
+                       tmp->ad_next = NULL;
+                       *n_ad = tmp;
+                       n_ad = &tmp->ad_next;
                } else {
                        u_ad = &(*u_ad)->ad_next;
                }
@@ -802,16 +807,17 @@ undef_remove(
 }
 
 int
-slap_ad_undef_remove(
-       char *name )
+slap_ad_undef_promote(
+       char *name,
+       AttributeType *at )
 {
        int     rc;
 
        ldap_pvt_thread_mutex_lock( &ad_undef_mutex );
 
-       rc = undef_remove( slap_schema.si_at_undefined, name );
+       rc = undef_promote( slap_schema.si_at_undefined, name, at );
        if ( rc == 0 ) {
-               rc = undef_remove( slap_schema.si_at_proxied, name );
+               rc = undef_promote( slap_schema.si_at_proxied, name, at );
        }
 
        ldap_pvt_thread_mutex_unlock( &ad_undef_mutex );
diff --git a/servers/slapd/alock.c b/servers/slapd/alock.c
new file mode 100644 (file)
index 0000000..fc9e529
--- /dev/null
@@ -0,0 +1,629 @@
+/* alock.c - access lock library */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2005 The OpenLDAP Foundation.
+ * Portions Copyright 2004-2005 Symas Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Matthew Backes at Symas
+ * Corporation for inclusion in OpenLDAP Software.
+ */
+
+#include "portable.h"
+
+#if SLAPD_BDB || SLAPD_HDB || SLAPD_LDBM
+
+#include "alock.h"
+
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+#include <ac/errno.h>
+#include <ac/assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <fcntl.h>
+
+#ifdef _WIN32
+#include <stdio.h>
+#include <io.h>
+#include <sys/locking.h>
+#endif
+
+
+static int
+alock_grab_lock ( int fd, int slot )
+{
+       int res;
+       
+#if defined( HAVE_LOCKF )
+       res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET);
+       if (res == -1) return -1;
+       res = lockf (fd, F_LOCK, (off_t) ALOCK_SLOT_SIZE);
+#elif defined( HAVE_FCNTL )
+       struct flock lock_info;
+       (void) memset ((void *) &lock_info, 0, sizeof (struct flock));
+
+       lock_info.l_type = F_WRLCK;
+       lock_info.l_whence = SEEK_SET;
+       lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot);
+       lock_info.l_len = (off_t) ALOCK_SLOT_SIZE;
+
+       res = fcntl (fd, F_SETLKW, &lock_info);
+#elif defined( _WIN32 )
+       if( _lseek( fd, (ALOCK_SLOT_SIZE * slot), SEEK_SET ) < 0 )
+               return -1;
+       /*
+        * _lock will try for the lock once per second, returning EDEADLOCK
+        * after ten tries. We just loop until we either get the lock
+        * or some other error is returned.
+        */
+       while((res = _locking( fd, _LK_LOCK, ALOCK_SLOT_SIZE )) < 0 ) {
+               if( errno != EDEADLOCK )
+                       break;
+       }
+#else
+#   error alock needs lockf, fcntl, or _locking
+#endif
+       if (res == -1) {
+               assert (errno != EDEADLK);
+               return -1;
+       }
+       return 0;
+}
+
+static int
+alock_release_lock ( int fd, int slot )
+{
+       int res;
+       
+#if defined( HAVE_LOCKF )
+       res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET);
+       if (res == -1) return -1;
+       res = lockf (fd, F_ULOCK, (off_t) ALOCK_SLOT_SIZE);
+       if (res == -1) return -1;
+#elif defined ( HAVE_FCNTL )
+       struct flock lock_info;
+       (void) memset ((void *) &lock_info, 0, sizeof (struct flock));
+
+       lock_info.l_type = F_UNLCK;
+       lock_info.l_whence = SEEK_SET;
+       lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot);
+       lock_info.l_len = (off_t) ALOCK_SLOT_SIZE;
+
+       res = fcntl (fd, F_SETLKW, &lock_info);
+       if (res == -1) return -1;
+#elif defined( _WIN32 )
+       res = _lseek (fd, (ALOCK_SLOT_SIZE * slot), SEEK_SET);
+       if (res == -1) return -1;
+       res = _locking( fd, _LK_UNLCK, ALOCK_SLOT_SIZE );
+       if (res == -1) return -1;
+#else
+#   error alock needs lockf, fcntl, or _locking
+#endif
+
+       return 0;
+}
+
+static int
+alock_test_lock ( int fd, int slot )
+{
+       int res;
+
+#if defined( HAVE_LOCKF )
+       res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET);
+       if (res == -1) return -1;
+
+       res = lockf (fd, F_TEST, (off_t) ALOCK_SLOT_SIZE);
+       if (res == -1) {
+               if (errno == EACCES || errno == EAGAIN) { 
+                       return ALOCK_LOCKED;
+               } else {
+                       return -1;
+               }
+       }
+#elif defined( HAVE_FCNTL )
+       struct flock lock_info;
+       (void) memset ((void *) &lock_info, 0, sizeof (struct flock));
+
+       lock_info.l_type = F_WRLCK;
+       lock_info.l_whence = SEEK_SET;
+       lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot);
+       lock_info.l_len = (off_t) ALOCK_SLOT_SIZE;
+
+       res = fcntl (fd, F_GETLK, &lock_info);
+       if (res == -1) return -1;
+
+       if (lock_info.l_type != F_UNLCK) return ALOCK_LOCKED;
+#elif defined( _WIN32 )
+       res = _lseek (fd, (ALOCK_SLOT_SIZE * slot), SEEK_SET);
+       if (res == -1) return -1;
+       res = _locking( fd, _LK_NBLCK, ALOCK_SLOT_SIZE );
+       _locking( fd, _LK_UNLCK, ALOCK_SLOT_SIZE );
+       if (res == -1) {
+          if( errno == EACCES ) {
+                  return ALOCK_LOCKED;
+          } else {
+                  return -1;
+          }
+       }
+#else
+#   error alock needs lockf, fcntl, or _locking
+#endif
+       
+       return 0;
+}
+
+/* Read a 64bit LE value */
+static unsigned long int
+alock_read_iattr ( unsigned char * bufptr )
+{
+       unsigned long int val = 0;
+       int count;
+
+       assert (bufptr != NULL);
+
+       bufptr += sizeof (unsigned long int);
+       for (count=0; count <= sizeof (unsigned long int); ++count) {
+               val <<= 8;
+               val += (unsigned long int) *bufptr--;
+       }
+
+       return val;
+}
+
+/* Write a 64bit LE value */
+static void
+alock_write_iattr ( unsigned char * bufptr,
+                   unsigned long int val )
+{
+       int count;
+
+       assert (bufptr != NULL);
+
+       for (count=0; count < 8; ++count) {
+               *bufptr++ = (unsigned char) (val & 0xff);
+               val >>= 8;
+       }
+}
+
+static int
+alock_read_slot ( alock_info_t * info,
+                 alock_slot_t * slot_data )
+{
+       unsigned char slotbuf [ALOCK_SLOT_SIZE];
+       int res, size, size_total, err;
+
+       assert (info != NULL);
+       assert (slot_data != NULL);
+       assert (info->al_slot > 0);
+
+       res = lseek (info->al_fd, 
+                    (off_t) (ALOCK_SLOT_SIZE * info->al_slot), 
+                    SEEK_SET);
+       if (res == -1) return -1;
+
+       size_total = 0;
+       while (size_total < ALOCK_SLOT_SIZE) {
+               size = read (info->al_fd, 
+                            slotbuf + size_total, 
+                            ALOCK_SLOT_SIZE - size_total);
+               if (size == 0) return -1;
+               if (size < 0) {
+                       err = errno;
+                       if (err != EINTR && err != EAGAIN) return -1;
+               } else {
+                       size_total += size;
+               }
+       }
+       
+       if (alock_read_iattr (slotbuf) != ALOCK_MAGIC) {
+               return 1;
+       }
+       slot_data->al_lock  = alock_read_iattr (slotbuf+8);
+       slot_data->al_stamp = alock_read_iattr (slotbuf+16);
+       slot_data->al_pid   = alock_read_iattr (slotbuf+24);
+
+       if (slot_data->al_appname) free (slot_data->al_appname);
+       slot_data->al_appname = calloc (1, ALOCK_MAX_APPNAME);
+       strncpy (slot_data->al_appname, (char *)slotbuf+32, ALOCK_MAX_APPNAME-1);
+       (slot_data->al_appname) [ALOCK_MAX_APPNAME-1] = '\0';
+
+       return 0;
+}
+
+static int
+alock_write_slot ( alock_info_t * info,
+                  alock_slot_t * slot_data )
+{
+       unsigned char slotbuf [ALOCK_SLOT_SIZE];
+       int res, size, size_total, err;
+
+       assert (info != NULL);
+       assert (slot_data != NULL);
+       assert (info->al_slot > 0);
+
+       (void) memset ((void *) slotbuf, 0, ALOCK_SLOT_SIZE);
+       
+       alock_write_iattr (slotbuf,    ALOCK_MAGIC);
+       assert (alock_read_iattr (slotbuf) == ALOCK_MAGIC);
+       alock_write_iattr (slotbuf+8,  slot_data->al_lock);
+       alock_write_iattr (slotbuf+16, slot_data->al_stamp);
+       alock_write_iattr (slotbuf+24, slot_data->al_pid);
+
+       strncpy ((char *)slotbuf+32, slot_data->al_appname, ALOCK_MAX_APPNAME-1);
+       slotbuf[ALOCK_SLOT_SIZE-1] = '\0';
+
+       res = lseek (info->al_fd, 
+                    (off_t) (ALOCK_SLOT_SIZE * info->al_slot),
+                    SEEK_SET);
+       if (res == -1) return -1;
+
+       size_total = 0;
+       while (size_total < ALOCK_SLOT_SIZE) {
+               size = write (info->al_fd, 
+                             slotbuf + size_total, 
+                             ALOCK_SLOT_SIZE - size_total);
+               if (size == 0) return -1;
+               if (size < 0) {
+                       err = errno;
+                       if (err != EINTR && err != EAGAIN) return -1;
+               } else {
+                       size_total += size;
+               }
+       }
+       
+       return 0;
+}
+
+static int
+alock_query_slot ( alock_info_t * info )
+{
+       int res;
+       alock_slot_t slot_data;
+
+       assert (info != NULL);
+       assert (info->al_slot > 0);
+       
+       (void) memset ((void *) &slot_data, 0, sizeof (alock_slot_t));
+       alock_read_slot (info, &slot_data);
+
+       if (slot_data.al_appname != NULL) free (slot_data.al_appname);
+       slot_data.al_appname = NULL;
+
+       if (slot_data.al_lock == ALOCK_UNLOCKED) return ALOCK_UNLOCKED;
+
+       res = alock_test_lock (info->al_fd, info->al_slot);
+       if (res < 0) return -1;
+       if (res > 0) {
+               if (slot_data.al_lock == ALOCK_UNIQUE) {
+                       return ALOCK_UNIQUE;
+               } else {
+                       return ALOCK_LOCKED;
+               }
+       }
+       
+       return ALOCK_DIRTY;
+}
+
+int 
+alock_open ( alock_info_t * info,
+            const char * appname,
+            const char * envdir,
+            int locktype )
+{
+       struct stat statbuf;
+       alock_info_t scan_info;
+       alock_slot_t slot_data;
+       char * filename;
+       int res, max_slot;
+       int dirty_count, live_count;
+
+       assert (info != NULL);
+       assert (appname != NULL);
+       assert (envdir != NULL);
+       assert (locktype >= 1 && locktype <= 2);
+
+       slot_data.al_lock = locktype;
+       slot_data.al_stamp = time(NULL);
+       slot_data.al_pid = getpid();
+       slot_data.al_appname = calloc (1, ALOCK_MAX_APPNAME);
+       strncpy (slot_data.al_appname, appname, ALOCK_MAX_APPNAME-1);
+       slot_data.al_appname [ALOCK_MAX_APPNAME-1] = '\0';
+
+       filename = calloc (1, strlen (envdir) + strlen ("/alock") + 1);
+       strcpy (filename, envdir);
+       strcat (filename, "/alock");
+       info->al_fd = open (filename, O_CREAT|O_RDWR, 0666);
+       free (filename);
+       if (info->al_fd < 0) {
+               free (slot_data.al_appname);
+               return ALOCK_UNSTABLE;
+       }
+       info->al_slot = 0;
+
+       res = alock_grab_lock (info->al_fd, 0);
+       if (res == -1) { 
+               close (info->al_fd);
+               free (slot_data.al_appname);
+               return ALOCK_UNSTABLE;
+       }
+
+       res = fstat (info->al_fd, &statbuf);
+       if (res == -1) { 
+               close (info->al_fd);
+               free (slot_data.al_appname);
+               return ALOCK_UNSTABLE;
+       }
+
+       max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE;
+       dirty_count = 0;
+       live_count = 0;
+       scan_info.al_fd = info->al_fd;
+       for (scan_info.al_slot = 1; 
+            scan_info.al_slot < max_slot;
+            ++ scan_info.al_slot) {
+               if (scan_info.al_slot != info->al_slot) {
+                       res = alock_query_slot (&scan_info);
+
+                       if (res == ALOCK_UNLOCKED
+                           && info->al_slot == 0) {
+                               info->al_slot = scan_info.al_slot;
+
+                       } else if (res == ALOCK_LOCKED) {
+                               ++live_count;
+
+                       } else if (res == ALOCK_UNIQUE
+                               && locktype == ALOCK_UNIQUE) {
+                               close (info->al_fd);
+                               free (slot_data.al_appname);
+                               return ALOCK_BUSY;
+
+                       } else if (res == ALOCK_DIRTY) {
+                               ++dirty_count;
+
+                       } else if (res == -1) {
+                               close (info->al_fd);
+                               free (slot_data.al_appname);
+                               return ALOCK_UNSTABLE;
+
+                       }
+               }
+       }
+
+       if (dirty_count && live_count) {
+               close (info->al_fd);
+               free (slot_data.al_appname);
+               return ALOCK_UNSTABLE;
+       }
+       
+       if (info->al_slot == 0) info->al_slot = max_slot + 1;
+       res = alock_grab_lock (info->al_fd,
+                              info->al_slot);
+       if (res == -1) { 
+               close (info->al_fd);
+               free (slot_data.al_appname);
+               return ALOCK_UNSTABLE;
+       }
+       res = alock_write_slot (info, &slot_data);
+       free (slot_data.al_appname);
+       if (res == -1) { 
+               close (info->al_fd);
+               return ALOCK_UNSTABLE;
+       }
+
+       res = alock_release_lock (info->al_fd, 0);
+       if (res == -1) { 
+               close (info->al_fd);
+               return ALOCK_UNSTABLE;
+       }
+       
+       if (dirty_count) return ALOCK_RECOVER;
+       return ALOCK_CLEAN;
+}
+
+int 
+alock_scan ( alock_info_t * info )
+{
+       struct stat statbuf;
+       alock_info_t scan_info;
+       int res, max_slot;
+       int dirty_count, live_count;
+
+       assert (info != NULL);
+
+       scan_info.al_fd = info->al_fd;
+
+       res = alock_grab_lock (info->al_fd, 0);
+       if (res == -1) {
+               close (info->al_fd);
+               return ALOCK_UNSTABLE;
+       }
+
+       res = fstat (info->al_fd, &statbuf);
+       if (res == -1) {
+               close (info->al_fd);
+               return ALOCK_UNSTABLE;
+       }
+
+       max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE;
+       dirty_count = 0;
+       live_count = 0;
+       for (scan_info.al_slot = 1; 
+            scan_info.al_slot < max_slot;
+            ++ scan_info.al_slot) {
+               if (scan_info.al_slot != info->al_slot) {
+                       res = alock_query_slot (&scan_info);
+
+                       if (res == ALOCK_LOCKED) {
+                               ++live_count;
+                               
+                       } else if (res == ALOCK_DIRTY) {
+                               ++dirty_count;
+
+                       } else if (res == -1) {
+                               close (info->al_fd);
+                               return ALOCK_UNSTABLE;
+
+                       }
+               }
+       }
+
+       res = alock_release_lock (info->al_fd, 0);
+       if (res == -1) {
+               close (info->al_fd);
+               return ALOCK_UNSTABLE;
+       }
+
+       if (dirty_count) {
+               if (live_count) {
+                       close (info->al_fd);
+                       return ALOCK_UNSTABLE;
+               } else {
+                       return ALOCK_RECOVER;
+               }
+       }
+       
+       return ALOCK_CLEAN;
+}
+
+int
+alock_close ( alock_info_t * info )
+{
+       alock_slot_t slot_data;
+       int res;
+
+       (void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t));
+
+       res = alock_grab_lock (info->al_fd, 0);
+       if (res == -1) {
+               close (info->al_fd);
+               return ALOCK_UNSTABLE;
+       }
+
+       /* mark our slot as clean */
+       res = alock_read_slot (info, &slot_data);
+       if (res == -1) {
+               close (info->al_fd);
+               if (slot_data.al_appname != NULL) 
+                       free (slot_data.al_appname);
+               return ALOCK_UNSTABLE;
+       }
+       slot_data.al_lock = ALOCK_UNLOCKED;
+       res = alock_write_slot (info, &slot_data);
+       if (res == -1) {
+               close (info->al_fd);
+               if (slot_data.al_appname != NULL) 
+                       free (slot_data.al_appname);
+               return ALOCK_UNSTABLE;
+       }
+       if (slot_data.al_appname != NULL) {
+               free (slot_data.al_appname);
+               slot_data.al_appname = NULL;
+       }
+
+       res = alock_release_lock (info->al_fd, info->al_slot);
+       if (res == -1) {
+               close (info->al_fd);
+               return ALOCK_UNSTABLE;
+       }
+       res = alock_release_lock (info->al_fd, 0);
+       if (res == -1) {
+               close (info->al_fd);
+               return ALOCK_UNSTABLE;
+       }
+
+       res = close (info->al_fd);
+       if (res == -1) return ALOCK_UNSTABLE;
+       
+       return ALOCK_CLEAN;
+}
+
+int 
+alock_recover ( alock_info_t * info )
+{
+       struct stat statbuf;
+       alock_slot_t slot_data;
+       alock_info_t scan_info;
+       int res, max_slot;
+
+       assert (info != NULL);
+
+       scan_info.al_fd = info->al_fd;
+
+       (void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t));
+
+       res = alock_grab_lock (info->al_fd, 0);
+       if (res == -1) {
+               close (info->al_fd);
+               return ALOCK_UNSTABLE;
+       }
+
+       res = fstat (info->al_fd, &statbuf);
+       if (res == -1) {
+               close (info->al_fd);
+               return ALOCK_UNSTABLE;
+       }
+
+       max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE;
+       for (scan_info.al_slot = 1; 
+            scan_info.al_slot < max_slot;
+            ++ scan_info.al_slot) {
+               if (scan_info.al_slot != info->al_slot) {
+                       res = alock_query_slot (&scan_info);
+
+                       if (res == ALOCK_LOCKED
+                           || res == ALOCK_UNIQUE) {
+                               /* recovery attempt on an active db? */
+                               close (info->al_fd);
+                               return ALOCK_UNSTABLE;
+                               
+                       } else if (res == ALOCK_DIRTY) {
+                               /* mark it clean */
+                               res = alock_read_slot (&scan_info, &slot_data);
+                               if (res == -1) {
+                                       close (info->al_fd);
+                                       return ALOCK_UNSTABLE;
+                               }
+                               slot_data.al_lock = ALOCK_UNLOCKED;
+                               res = alock_write_slot (&scan_info, &slot_data);
+                               if (res == -1) {
+                                       close (info->al_fd);
+                                       if (slot_data.al_appname != NULL) 
+                                               free (slot_data.al_appname);
+                                       return ALOCK_UNSTABLE;
+                               }
+                               if (slot_data.al_appname != NULL) {
+                                       free (slot_data.al_appname);
+                                       slot_data.al_appname = NULL;
+                               }
+                               
+                       } else if (res == -1) {
+                               close (info->al_fd);
+                               return ALOCK_UNSTABLE;
+
+                       }
+               }
+       }
+
+       res = alock_release_lock (info->al_fd, 0);
+       if (res == -1) {
+               close (info->al_fd);
+               return ALOCK_UNSTABLE;
+       }
+
+       return ALOCK_CLEAN;
+}
+
+#endif /* SLAPD_BDB || SLAPD_HDB */
diff --git a/servers/slapd/alock.h b/servers/slapd/alock.h
new file mode 100644 (file)
index 0000000..2f3039b
--- /dev/null
@@ -0,0 +1,69 @@
+/* alock.h - access lock header */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2005 The OpenLDAP Foundation.
+ * Portions Copyright 2004-2005 Symas Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Matthew Backes at Symas
+ * Corporation for inclusion in OpenLDAP Software.
+ */
+
+#ifndef _ALOCK_H_
+#define _ALOCK_H_
+
+#include "portable.h"
+#include <ac/time.h>
+#include <ac/unistd.h>
+
+/* environment states (all the slots together) */
+#define ALOCK_CLEAN            (0)
+#define ALOCK_RECOVER  (1)
+#define ALOCK_BUSY             (2)
+#define ALOCK_UNSTABLE (3)
+
+/* lock user types and states */
+#define ALOCK_UNLOCKED (0)
+#define ALOCK_LOCKED   (1)
+#define ALOCK_UNIQUE   (2)
+#define ALOCK_DIRTY            (3)
+
+/* constants */
+#define ALOCK_SLOT_SIZE                (1024)
+#define ALOCK_SLOT_IATTRS      (4)
+#define ALOCK_MAX_APPNAME      (ALOCK_SLOT_SIZE - 8 * ALOCK_SLOT_IATTRS)
+#define ALOCK_MAGIC                    (0x12345678)
+
+LDAP_BEGIN_DECL
+
+typedef struct alock_info {
+       int al_fd;
+       int al_slot;
+} alock_info_t;
+
+typedef struct alock_slot {
+       unsigned int al_lock;
+       time_t al_stamp;
+       pid_t al_pid;
+       char * al_appname;
+} alock_slot_t;
+
+LDAP_SLAPD_F (int) alock_open LDAP_P(( alock_info_t * info, const char * appname,
+       const char * envdir, int locktype ));
+LDAP_SLAPD_F (int) alock_scan LDAP_P(( alock_info_t * info ));
+LDAP_SLAPD_F (int) alock_close LDAP_P(( alock_info_t * info ));
+LDAP_SLAPD_F (int) alock_recover LDAP_P(( alock_info_t * info ));
+
+LDAP_END_DECL
+
+#endif
index 1b3b7b59919bd92354e7e6da0167e709b5c2a591..59bdb98142a23cf8882be565ef94941c41e9198a 100644 (file)
@@ -405,13 +405,13 @@ at_insert(
        }
 
        if ( sat->sat_oid ) {
-               slap_ad_undef_remove( sat->sat_oid );
+               slap_ad_undef_promote( sat->sat_oid, sat );
        }
 
        names = sat->sat_names;
        if ( names ) {
                while ( *names ) {
-                       slap_ad_undef_remove( *names );
+                       slap_ad_undef_promote( *names, sat );
                        names++;
                }
        }
index 0eeb6a75cd56ceaba58e2bc303a7943c5ebc3f24..f439138a523a89bcc42706659835b1ac117fd1eb 100644 (file)
@@ -18,14 +18,14 @@ SRCS = init.c tools.c config.c \
        extended.c referral.c operational.c \
        attr.c index.c key.c dbcache.c filterindex.c \
        dn2entry.c dn2id.c error.c id2entry.c idl.c \
-       nextid.c cache.c trans.c alock.c
+       nextid.c cache.c trans.c
 
 OBJS = init.lo tools.lo config.lo \
        add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
        extended.lo referral.lo operational.lo \
        attr.lo index.lo key.lo dbcache.lo filterindex.lo \
        dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo \
-       nextid.lo cache.lo trans.lo alock.lo
+       nextid.lo cache.lo trans.lo
 
 LDAP_INCDIR= ../../../include       
 LDAP_LIBDIR= ../../../libraries
diff --git a/servers/slapd/back-bdb/alock.c b/servers/slapd/back-bdb/alock.c
deleted file mode 100644 (file)
index 92fc243..0000000
+++ /dev/null
@@ -1,624 +0,0 @@
-/* alock.c - access lock library */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2005 The OpenLDAP Foundation.
- * Portions Copyright 2004-2005 Symas Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was initially developed by Matthew Backes at Symas
- * Corporation for inclusion in OpenLDAP Software.
- */
-
-#include "portable.h"
-#include "alock.h"
-
-#include <ac/stdlib.h>
-#include <ac/string.h>
-#include <ac/unistd.h>
-#include <ac/errno.h>
-#include <ac/assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <fcntl.h>
-
-#ifdef _WIN32
-#include <stdio.h>
-#include <io.h>
-#include <sys/locking.h>
-#endif
-
-
-static int
-alock_grab_lock ( int fd, int slot )
-{
-       int res;
-       
-#if defined( HAVE_LOCKF )
-       res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET);
-       if (res == -1) return -1;
-       res = lockf (fd, F_LOCK, (off_t) ALOCK_SLOT_SIZE);
-#elif defined( HAVE_FCNTL )
-       struct flock lock_info;
-       (void) memset ((void *) &lock_info, 0, sizeof (struct flock));
-
-       lock_info.l_type = F_WRLCK;
-       lock_info.l_whence = SEEK_SET;
-       lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot);
-       lock_info.l_len = (off_t) ALOCK_SLOT_SIZE;
-
-       res = fcntl (fd, F_SETLKW, &lock_info);
-#elif defined( _WIN32 )
-       if( _lseek( fd, (ALOCK_SLOT_SIZE * slot), SEEK_SET ) < 0 )
-               return -1;
-       /*
-        * _lock will try for the lock once per second, returning EDEADLOCK
-        * after ten tries. We just loop until we either get the lock
-        * or some other error is returned.
-        */
-       while((res = _locking( fd, _LK_LOCK, ALOCK_SLOT_SIZE )) < 0 ) {
-               if( errno != EDEADLOCK )
-                       break;
-       }
-#else
-#   error alock needs lockf, fcntl, or _locking
-#endif
-       if (res == -1) {
-               assert (errno != EDEADLK);
-               return -1;
-       }
-       return 0;
-}
-
-static int
-alock_release_lock ( int fd, int slot )
-{
-       int res;
-       
-#if defined( HAVE_LOCKF )
-       res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET);
-       if (res == -1) return -1;
-       res = lockf (fd, F_ULOCK, (off_t) ALOCK_SLOT_SIZE);
-       if (res == -1) return -1;
-#elif defined ( HAVE_FCNTL )
-       struct flock lock_info;
-       (void) memset ((void *) &lock_info, 0, sizeof (struct flock));
-
-       lock_info.l_type = F_UNLCK;
-       lock_info.l_whence = SEEK_SET;
-       lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot);
-       lock_info.l_len = (off_t) ALOCK_SLOT_SIZE;
-
-       res = fcntl (fd, F_SETLKW, &lock_info);
-       if (res == -1) return -1;
-#elif defined( _WIN32 )
-       res = _lseek (fd, (ALOCK_SLOT_SIZE * slot), SEEK_SET);
-       if (res == -1) return -1;
-       res = _locking( fd, _LK_UNLCK, ALOCK_SLOT_SIZE );
-       if (res == -1) return -1;
-#else
-#   error alock needs lockf, fcntl, or _locking
-#endif
-
-       return 0;
-}
-
-static int
-alock_test_lock ( int fd, int slot )
-{
-       int res;
-
-#if defined( HAVE_LOCKF )
-       res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET);
-       if (res == -1) return -1;
-
-       res = lockf (fd, F_TEST, (off_t) ALOCK_SLOT_SIZE);
-       if (res == -1) {
-               if (errno == EACCES || errno == EAGAIN) { 
-                       return ALOCK_LOCKED;
-               } else {
-                       return -1;
-               }
-       }
-#elif defined( HAVE_FCNTL )
-       struct flock lock_info;
-       (void) memset ((void *) &lock_info, 0, sizeof (struct flock));
-
-       lock_info.l_type = F_WRLCK;
-       lock_info.l_whence = SEEK_SET;
-       lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot);
-       lock_info.l_len = (off_t) ALOCK_SLOT_SIZE;
-
-       res = fcntl (fd, F_GETLK, &lock_info);
-       if (res == -1) return -1;
-
-       if (lock_info.l_type != F_UNLCK) return ALOCK_LOCKED;
-#elif defined( _WIN32 )
-       res = _lseek (fd, (ALOCK_SLOT_SIZE * slot), SEEK_SET);
-       if (res == -1) return -1;
-       res = _locking( fd, _LK_NBLCK, ALOCK_SLOT_SIZE );
-       _locking( fd, _LK_UNLCK, ALOCK_SLOT_SIZE );
-       if (res == -1) {
-          if( errno == EACCES ) {
-                  return ALOCK_LOCKED;
-          } else {
-                  return -1;
-          }
-       }
-#else
-#   error alock needs lockf, fcntl, or _locking
-#endif
-       
-       return 0;
-}
-
-/* Read a 64bit LE value */
-static unsigned long int
-alock_read_iattr ( unsigned char * bufptr )
-{
-       unsigned long int val = 0;
-       int count;
-
-       assert (bufptr != NULL);
-
-       bufptr += sizeof (unsigned long int);
-       for (count=0; count <= sizeof (unsigned long int); ++count) {
-               val <<= 8;
-               val += (unsigned long int) *bufptr--;
-       }
-
-       return val;
-}
-
-/* Write a 64bit LE value */
-static void
-alock_write_iattr ( unsigned char * bufptr,
-                   unsigned long int val )
-{
-       int count;
-
-       assert (bufptr != NULL);
-
-       for (count=0; count < 8; ++count) {
-               *bufptr++ = (unsigned char) (val & 0xff);
-               val >>= 8;
-       }
-}
-
-static int
-alock_read_slot ( alock_info_t * info,
-                 alock_slot_t * slot_data )
-{
-       unsigned char slotbuf [ALOCK_SLOT_SIZE];
-       int res, size, size_total, err;
-
-       assert (info != NULL);
-       assert (slot_data != NULL);
-       assert (info->al_slot > 0);
-
-       res = lseek (info->al_fd, 
-                    (off_t) (ALOCK_SLOT_SIZE * info->al_slot), 
-                    SEEK_SET);
-       if (res == -1) return -1;
-
-       size_total = 0;
-       while (size_total < ALOCK_SLOT_SIZE) {
-               size = read (info->al_fd, 
-                            slotbuf + size_total, 
-                            ALOCK_SLOT_SIZE - size_total);
-               if (size == 0) return -1;
-               if (size < 0) {
-                       err = errno;
-                       if (err != EINTR && err != EAGAIN) return -1;
-               } else {
-                       size_total += size;
-               }
-       }
-       
-       if (alock_read_iattr (slotbuf) != ALOCK_MAGIC) {
-               return 1;
-       }
-       slot_data->al_lock  = alock_read_iattr (slotbuf+8);
-       slot_data->al_stamp = alock_read_iattr (slotbuf+16);
-       slot_data->al_pid   = alock_read_iattr (slotbuf+24);
-
-       if (slot_data->al_appname) free (slot_data->al_appname);
-       slot_data->al_appname = calloc (1, ALOCK_MAX_APPNAME);
-       strncpy (slot_data->al_appname, (char *)slotbuf+32, ALOCK_MAX_APPNAME-1);
-       (slot_data->al_appname) [ALOCK_MAX_APPNAME-1] = '\0';
-
-       return 0;
-}
-
-static int
-alock_write_slot ( alock_info_t * info,
-                  alock_slot_t * slot_data )
-{
-       unsigned char slotbuf [ALOCK_SLOT_SIZE];
-       int res, size, size_total, err;
-
-       assert (info != NULL);
-       assert (slot_data != NULL);
-       assert (info->al_slot > 0);
-
-       (void) memset ((void *) slotbuf, 0, ALOCK_SLOT_SIZE);
-       
-       alock_write_iattr (slotbuf,    ALOCK_MAGIC);
-       assert (alock_read_iattr (slotbuf) == ALOCK_MAGIC);
-       alock_write_iattr (slotbuf+8,  slot_data->al_lock);
-       alock_write_iattr (slotbuf+16, slot_data->al_stamp);
-       alock_write_iattr (slotbuf+24, slot_data->al_pid);
-
-       strncpy ((char *)slotbuf+32, slot_data->al_appname, ALOCK_MAX_APPNAME-1);
-       slotbuf[ALOCK_SLOT_SIZE-1] = '\0';
-
-       res = lseek (info->al_fd, 
-                    (off_t) (ALOCK_SLOT_SIZE * info->al_slot),
-                    SEEK_SET);
-       if (res == -1) return -1;
-
-       size_total = 0;
-       while (size_total < ALOCK_SLOT_SIZE) {
-               size = write (info->al_fd, 
-                             slotbuf + size_total, 
-                             ALOCK_SLOT_SIZE - size_total);
-               if (size == 0) return -1;
-               if (size < 0) {
-                       err = errno;
-                       if (err != EINTR && err != EAGAIN) return -1;
-               } else {
-                       size_total += size;
-               }
-       }
-       
-       return 0;
-}
-
-static int
-alock_query_slot ( alock_info_t * info )
-{
-       int res;
-       alock_slot_t slot_data;
-
-       assert (info != NULL);
-       assert (info->al_slot > 0);
-       
-       (void) memset ((void *) &slot_data, 0, sizeof (alock_slot_t));
-       alock_read_slot (info, &slot_data);
-
-       if (slot_data.al_appname != NULL) free (slot_data.al_appname);
-       slot_data.al_appname = NULL;
-
-       if (slot_data.al_lock == ALOCK_UNLOCKED) return ALOCK_UNLOCKED;
-
-       res = alock_test_lock (info->al_fd, info->al_slot);
-       if (res < 0) return -1;
-       if (res > 0) {
-               if (slot_data.al_lock == ALOCK_UNIQUE) {
-                       return ALOCK_UNIQUE;
-               } else {
-                       return ALOCK_LOCKED;
-               }
-       }
-       
-       return ALOCK_DIRTY;
-}
-
-int 
-alock_open ( alock_info_t * info,
-            const char * appname,
-            const char * envdir,
-            int locktype )
-{
-       struct stat statbuf;
-       alock_info_t scan_info;
-       alock_slot_t slot_data;
-       char * filename;
-       int res, max_slot;
-       int dirty_count, live_count;
-
-       assert (info != NULL);
-       assert (appname != NULL);
-       assert (envdir != NULL);
-       assert (locktype >= 1 && locktype <= 2);
-
-       slot_data.al_lock = locktype;
-       slot_data.al_stamp = time(NULL);
-       slot_data.al_pid = getpid();
-       slot_data.al_appname = calloc (1, ALOCK_MAX_APPNAME);
-       strncpy (slot_data.al_appname, appname, ALOCK_MAX_APPNAME-1);
-       slot_data.al_appname [ALOCK_MAX_APPNAME-1] = '\0';
-
-       filename = calloc (1, strlen (envdir) + strlen ("/alock") + 1);
-       strcpy (filename, envdir);
-       strcat (filename, "/alock");
-       info->al_fd = open (filename, O_CREAT|O_RDWR, 0666);
-       free (filename);
-       if (info->al_fd < 0) {
-               free (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-       info->al_slot = 0;
-
-       res = alock_grab_lock (info->al_fd, 0);
-       if (res == -1) { 
-               close (info->al_fd);
-               free (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-
-       res = fstat (info->al_fd, &statbuf);
-       if (res == -1) { 
-               close (info->al_fd);
-               free (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-
-       max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE;
-       dirty_count = 0;
-       live_count = 0;
-       scan_info.al_fd = info->al_fd;
-       for (scan_info.al_slot = 1; 
-            scan_info.al_slot < max_slot;
-            ++ scan_info.al_slot) {
-               if (scan_info.al_slot != info->al_slot) {
-                       res = alock_query_slot (&scan_info);
-
-                       if (res == ALOCK_UNLOCKED
-                           && info->al_slot == 0) {
-                               info->al_slot = scan_info.al_slot;
-
-                       } else if (res == ALOCK_LOCKED) {
-                               ++live_count;
-
-                       } else if (res == ALOCK_UNIQUE
-                               && locktype == ALOCK_UNIQUE) {
-                               close (info->al_fd);
-                               free (slot_data.al_appname);
-                               return ALOCK_BUSY;
-
-                       } else if (res == ALOCK_DIRTY) {
-                               ++dirty_count;
-
-                       } else if (res == -1) {
-                               close (info->al_fd);
-                               free (slot_data.al_appname);
-                               return ALOCK_UNSTABLE;
-
-                       }
-               }
-       }
-
-       if (dirty_count && live_count) {
-               close (info->al_fd);
-               free (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-       
-       if (info->al_slot == 0) info->al_slot = max_slot + 1;
-       res = alock_grab_lock (info->al_fd,
-                              info->al_slot);
-       if (res == -1) { 
-               close (info->al_fd);
-               free (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-       res = alock_write_slot (info, &slot_data);
-       free (slot_data.al_appname);
-       if (res == -1) { 
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       res = alock_release_lock (info->al_fd, 0);
-       if (res == -1) { 
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-       
-       if (dirty_count) return ALOCK_RECOVER;
-       return ALOCK_CLEAN;
-}
-
-int 
-alock_scan ( alock_info_t * info )
-{
-       struct stat statbuf;
-       alock_info_t scan_info;
-       int res, max_slot;
-       int dirty_count, live_count;
-
-       assert (info != NULL);
-
-       scan_info.al_fd = info->al_fd;
-
-       res = alock_grab_lock (info->al_fd, 0);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       res = fstat (info->al_fd, &statbuf);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE;
-       dirty_count = 0;
-       live_count = 0;
-       for (scan_info.al_slot = 1; 
-            scan_info.al_slot < max_slot;
-            ++ scan_info.al_slot) {
-               if (scan_info.al_slot != info->al_slot) {
-                       res = alock_query_slot (&scan_info);
-
-                       if (res == ALOCK_LOCKED) {
-                               ++live_count;
-                               
-                       } else if (res == ALOCK_DIRTY) {
-                               ++dirty_count;
-
-                       } else if (res == -1) {
-                               close (info->al_fd);
-                               return ALOCK_UNSTABLE;
-
-                       }
-               }
-       }
-
-       res = alock_release_lock (info->al_fd, 0);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       if (dirty_count) {
-               if (live_count) {
-                       close (info->al_fd);
-                       return ALOCK_UNSTABLE;
-               } else {
-                       return ALOCK_RECOVER;
-               }
-       }
-       
-       return ALOCK_CLEAN;
-}
-
-int
-alock_close ( alock_info_t * info )
-{
-       alock_slot_t slot_data;
-       int res;
-
-       (void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t));
-
-       res = alock_grab_lock (info->al_fd, 0);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       /* mark our slot as clean */
-       res = alock_read_slot (info, &slot_data);
-       if (res == -1) {
-               close (info->al_fd);
-               if (slot_data.al_appname != NULL) 
-                       free (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-       slot_data.al_lock = ALOCK_UNLOCKED;
-       res = alock_write_slot (info, &slot_data);
-       if (res == -1) {
-               close (info->al_fd);
-               if (slot_data.al_appname != NULL) 
-                       free (slot_data.al_appname);
-               return ALOCK_UNSTABLE;
-       }
-       if (slot_data.al_appname != NULL) {
-               free (slot_data.al_appname);
-               slot_data.al_appname = NULL;
-       }
-
-       res = alock_release_lock (info->al_fd, info->al_slot);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-       res = alock_release_lock (info->al_fd, 0);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       res = close (info->al_fd);
-       if (res == -1) return ALOCK_UNSTABLE;
-       
-       return ALOCK_CLEAN;
-}
-
-int 
-alock_recover ( alock_info_t * info )
-{
-       struct stat statbuf;
-       alock_slot_t slot_data;
-       alock_info_t scan_info;
-       int res, max_slot;
-
-       assert (info != NULL);
-
-       scan_info.al_fd = info->al_fd;
-
-       (void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t));
-
-       res = alock_grab_lock (info->al_fd, 0);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       res = fstat (info->al_fd, &statbuf);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE;
-       for (scan_info.al_slot = 1; 
-            scan_info.al_slot < max_slot;
-            ++ scan_info.al_slot) {
-               if (scan_info.al_slot != info->al_slot) {
-                       res = alock_query_slot (&scan_info);
-
-                       if (res == ALOCK_LOCKED
-                           || res == ALOCK_UNIQUE) {
-                               /* recovery attempt on an active db? */
-                               close (info->al_fd);
-                               return ALOCK_UNSTABLE;
-                               
-                       } else if (res == ALOCK_DIRTY) {
-                               /* mark it clean */
-                               res = alock_read_slot (&scan_info, &slot_data);
-                               if (res == -1) {
-                                       close (info->al_fd);
-                                       return ALOCK_UNSTABLE;
-                               }
-                               slot_data.al_lock = ALOCK_UNLOCKED;
-                               res = alock_write_slot (&scan_info, &slot_data);
-                               if (res == -1) {
-                                       close (info->al_fd);
-                                       if (slot_data.al_appname != NULL) 
-                                               free (slot_data.al_appname);
-                                       return ALOCK_UNSTABLE;
-                               }
-                               if (slot_data.al_appname != NULL) {
-                                       free (slot_data.al_appname);
-                                       slot_data.al_appname = NULL;
-                               }
-                               
-                       } else if (res == -1) {
-                               close (info->al_fd);
-                               return ALOCK_UNSTABLE;
-
-                       }
-               }
-       }
-
-       res = alock_release_lock (info->al_fd, 0);
-       if (res == -1) {
-               close (info->al_fd);
-               return ALOCK_UNSTABLE;
-       }
-
-       return ALOCK_CLEAN;
-}
diff --git a/servers/slapd/back-bdb/alock.h b/servers/slapd/back-bdb/alock.h
deleted file mode 100644 (file)
index 902077d..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* alock.h - access lock header */
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 2005 The OpenLDAP Foundation.
- * Portions Copyright 2004-2005 Symas Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was initially developed by Matthew Backes at Symas
- * Corporation for inclusion in OpenLDAP Software.
- */
-
-#ifndef _ALOCK_H_
-#define _ALOCK_H_
-
-#include "portable.h"
-#include <ac/time.h>
-#include <ac/unistd.h>
-
-/* environment states (all the slots together) */
-#define ALOCK_CLEAN            (0)
-#define ALOCK_RECOVER  (1)
-#define ALOCK_BUSY             (2)
-#define ALOCK_UNSTABLE (3)
-
-/* lock user types and states */
-#define ALOCK_UNLOCKED (0)
-#define ALOCK_LOCKED   (1)
-#define ALOCK_UNIQUE   (2)
-#define ALOCK_DIRTY            (3)
-
-/* constants */
-#define ALOCK_SLOT_SIZE                (1024)
-#define ALOCK_SLOT_IATTRS      (4)
-#define ALOCK_MAX_APPNAME      (ALOCK_SLOT_SIZE - 8 * ALOCK_SLOT_IATTRS)
-#define ALOCK_MAGIC                    (0x12345678)
-
-LDAP_BEGIN_DECL
-
-typedef struct alock_info {
-       int al_fd;
-       int al_slot;
-} alock_info_t;
-
-typedef struct alock_slot {
-       unsigned int al_lock;
-       time_t al_stamp;
-       pid_t al_pid;
-       char * al_appname;
-} alock_slot_t;
-
-extern int alock_open LDAP_P(( alock_info_t * info, const char * appname,
-       const char * envdir, int locktype ));
-extern int alock_scan LDAP_P(( alock_info_t * info ));
-extern int alock_close LDAP_P(( alock_info_t * info ));
-extern int alock_recover LDAP_P(( alock_info_t * info ));
-
-LDAP_END_DECL
-
-#endif
index e28d7c189ba99e4c2b20a1c776d2ed79de9f5e75..7091d343db863181cb43951e063aac023692c598 100644 (file)
@@ -87,13 +87,15 @@ typedef struct bdb_entry_info {
         * that is always zero.
         */
        char bei_lockpad;
-                                               
+
        short bei_state;
 #define        CACHE_ENTRY_DELETED     1
 #define        CACHE_ENTRY_NO_KIDS     2
 #define        CACHE_ENTRY_NOT_LINKED  4
 #define CACHE_ENTRY_NO_GRANDKIDS       8
 #define        CACHE_ENTRY_LOADING     0x10
+#define        CACHE_ENTRY_WALKING     0x20
+#define        CACHE_ENTRY_ONELEVEL    0x40
 
        /*
         * remaining fields require backend cache lock to access
@@ -124,6 +126,7 @@ typedef struct bdb_cache {
        int             c_maxsize;
        int             c_cursize;
        int             c_eiused;       /* EntryInfo's in use */
+       int             c_leaves;       /* EntryInfo leaf nodes */
        EntryInfo       c_dntree;
        EntryInfo       *c_eifree;      /* free list */
        Avlnode         *c_idtree;
index d98ed21ecc7ca5db7a00a0a60ca8552078baf934..d155ef7c2ea9cdca7c1eaeb7d8550ef11002cfcd 100644 (file)
@@ -257,6 +257,13 @@ bdb_entryinfo_add_internal(
        } else {
                bdb->bi_cache.c_eiused++;
                ber_dupbv( &ei2->bei_nrdn, &ei->bei_nrdn );
+
+               /* This is a new leaf node. But if parent had no kids, then it was
+                * a leaf and we would be decrementing that. So, only increment if
+                * the parent already has kids.
+                */
+               if ( ei->bei_parent->bei_kids || !ei->bei_parent->bei_id )
+                       bdb->bi_cache.c_leaves++;
                avl_insert( &ei->bei_parent->bei_kids, ei2, bdb_rdn_cmp,
                        avl_dup_error );
 #ifdef BDB_HIER
@@ -387,7 +394,7 @@ hdb_cache_find_parent(
        struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
        EntryInfo ei, eip, *ei2 = NULL, *ein = NULL, *eir = NULL;
        int rc;
-       int addlru = 1;
+       int addlru = 0;
 
        ei.bei_id = id;
        ei.bei_kids = NULL;
@@ -435,11 +442,15 @@ hdb_cache_find_parent(
                                ein->bei_ckids++;
                                bdb_cache_entryinfo_unlock( ein );
                        }
+                       addlru = 0;
 
-                       if ( !eir ) {
-                               addlru = 0;
-                       }
                }
+               if ( addlru ) {
+                       ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_mutex );
+                       LRU_ADD( &bdb->bi_cache, ein );
+                       ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.lru_mutex );
+               }
+               addlru = 1;
 
                /* If this is the first time, save this node
                 * to be returned later.
@@ -457,6 +468,8 @@ hdb_cache_find_parent(
                        ei2 = &bdb->bi_cache.c_dntree;
                }
                bdb->bi_cache.c_eiused++;
+               if ( ei2 && ( ei2->bei_kids || !ei2->bei_id ))
+                               bdb->bi_cache.c_leaves++;
                ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
 
                /* Got the parent, link in and we're done. */
@@ -555,31 +568,53 @@ bdb_cache_lru_add(
                         */
                        if ( bdb_cache_entry_db_lock( bdb->bi_dbenv,
                                        bdb->bi_cache.c_locker, elru, 1, 1, lockp ) == 0 ) {
-                               int stop = 0;
 
-                               /* If there's no entry, or this node is in
-                                * the process of linking into the cache,
+                               int stop = 0, decr = 0;
+
+                               /* If this node is in the process of linking into the cache,
                                 * or this node is being deleted, skip it.
                                 */
-                               if ( !elru->bei_e || (elru->bei_state &
-                                       ( CACHE_ENTRY_NOT_LINKED | CACHE_ENTRY_DELETED ))) {
+                               if ( elru->bei_state &
+                                       ( CACHE_ENTRY_NOT_LINKED | CACHE_ENTRY_DELETED )) {
                                        bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
                                        continue;
                                }
-                               LRU_DELETE( &bdb->bi_cache, elru );
-                               elru->bei_e->e_private = NULL;
+                               /* Free entry for this node if it's present */
+                               if ( elru->bei_e ) {
+                                       elru->bei_e->e_private = NULL;
 #ifdef SLAP_ZONE_ALLOC
-                               bdb_entry_return( bdb, elru->bei_e, elru->bei_zseq );
+                                       bdb_entry_return( bdb, elru->bei_e, elru->bei_zseq );
 #else
-                               bdb_entry_return( elru->bei_e );
+                                       bdb_entry_return( elru->bei_e );
 #endif
-                               elru->bei_e = NULL;
+                                       elru->bei_e = NULL;
+                                       decr = 1;
+                               }
+                               /* ITS#4010 if we're in slapcat, and this node is a leaf
+                                * node, free it.
+                                *
+                                * FIXME: we need to do this for slapd as well, (which is
+                                * why we compute bi_cache.c_leaves now) but at the moment
+                                * we can't because it causes unresolvable deadlocks. 
+                                */
+                               if ( slapMode & SLAP_TOOL_READONLY ) {
+                                       if ( !elru->bei_kids ) {
+                                               /* This does LRU_DELETE for us */
+                                               bdb_cache_delete_internal( &bdb->bi_cache, elru, 0 );
+                                               bdb_cache_delete_cleanup( &bdb->bi_cache, elru );
+                                       }
+                                       /* Leave node on LRU list for a future pass */
+                               } else {
+                                       LRU_DELETE( &bdb->bi_cache, elru );
+                               }
+                               bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
+
                                ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
-                               --bdb->bi_cache.c_cursize;
+                               if ( decr )
+                                       --bdb->bi_cache.c_cursize;
                                if (bdb->bi_cache.c_cursize <= bdb->bi_cache.c_maxsize)
                                        stop = 1;
                                ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
-                               bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
                                if (stop) break;
                        }
                }
@@ -1085,7 +1120,15 @@ bdb_cache_delete(
 
        /* set lru mutex */
        ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
+
+       /* set cache write lock */
+       ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
+
        rc = bdb_cache_delete_internal( cache, e->e_private, 1 );
+
+       /* free cache write lock */
+       ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
+
        /* free lru mutex */
        ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
 
@@ -1137,9 +1180,6 @@ bdb_cache_delete_internal(
 {
        int rc = 0;     /* return code */
 
-       /* set cache write lock */
-       ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
-
        /* Lock the parent's kids tree */
        bdb_cache_entryinfo_lock( e->bei_parent );
 
@@ -1153,27 +1193,25 @@ bdb_cache_delete_internal(
        {
                rc = -1;
        }
+       if ( e->bei_parent->bei_kids )
+               cache->c_leaves--;
 
        /* id tree */
        if ( avl_delete( &cache->c_idtree, (caddr_t) e, bdb_id_cmp ) == NULL ) {
                rc = -1;
        }
 
-       if (rc != 0) {
-               return rc;
-       }
-
-       cache->c_eiused--;
+       if ( rc == 0 ){
+               cache->c_eiused--;
 
-       /* lru */
-       LRU_DELETE( cache, e );
-       if ( e->bei_e ) cache->c_cursize--;
+               /* lru */
+               LRU_DELETE( cache, e );
+               if ( e->bei_e ) cache->c_cursize--;
+       }
 
-       /* free cache write lock */
-       ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
        bdb_cache_entryinfo_unlock( e->bei_parent );
 
-       return( 0 );
+       return( rc );
 }
 
 static void
@@ -1212,6 +1250,7 @@ bdb_cache_release_all( Cache *cache )
        }
        cache->c_cursize = 0;
        cache->c_eiused = 0;
+       cache->c_leaves = 0;
        cache->c_idtree = NULL;
        cache->c_lruhead = NULL;
        cache->c_lrutail = NULL;
@@ -1318,7 +1357,7 @@ static void
 bdb_locker_id_free( void *key, void *data )
 {
        DB_ENV *env = key;
-       u_int32_t lockid = (u_int32_t) data;
+       u_int32_t lockid = (long)data;
        int rc;
 
        rc = XLOCK_ID_FREE( env, lockid );
@@ -1366,7 +1405,7 @@ bdb_locker_id( Operation *op, DB_ENV *env, u_int32_t *locker )
                if ( rc != 0) {
                        return rc;
                }
-               data = (void *)lockid;
+               data = (void *)((long)lockid);
                if ( ( rc = ldap_pvt_thread_pool_setkey( ctx, env,
                        data, bdb_locker_id_free ) ) ) {
                        XLOCK_ID_FREE( env, lockid );
@@ -1376,7 +1415,7 @@ bdb_locker_id( Operation *op, DB_ENV *env, u_int32_t *locker )
                        return rc;
                }
        } else {
-               lockid = (u_int32_t) data;
+               lockid = (long)data;
        }
        *locker = lockid;
        return 0;
index 89d5704c6431f9b03d4c597b8ca8f3285ef9e1b8..d2ed137e979716e881c372e6c82f475a0cfe9307 100644 (file)
@@ -502,11 +502,6 @@ hdb_dn2id_add(
        key.flags = DB_DBT_USERMEM;
        BDB_ID2DISK( eip->bei_id, &nid );
 
-       /* Delete parent's IDL cache entry */
-       if ( bdb->bi_idl_cache_size ) {
-               key.data = &eip->bei_id;
-               bdb_idl_cache_del( bdb, db, &key );
-       }
        key.data = &nid;
 
        /* Need to make dummy root node once. Subsequent attempts
@@ -535,6 +530,21 @@ hdb_dn2id_add(
                rc = db->put( db, txn, &key, &data, DB_NODUPDATA );
        }
 
+       /* Update all parents' IDL cache entries */
+       if ( rc == 0 && bdb->bi_idl_cache_size ) {
+               ID tmp[2];
+               char *ptr = ((char *)&tmp[1])-1;
+               key.data = ptr;
+               key.size = sizeof(ID)+1;
+               tmp[1] = eip->bei_id;
+               *ptr = DN_ONE_PREFIX;
+               bdb_idl_cache_add_id( bdb, db, &key, e->e_id );
+               *ptr = DN_SUBTREE_PREFIX;
+               for (; eip && eip->bei_parent->bei_id; eip = eip->bei_parent) {
+                       tmp[1] = eip->bei_id;
+                       bdb_idl_cache_add_id( bdb, db, &key, e->e_id );
+               }
+       }
        op->o_tmpfree( d, op->o_tmpmemctx );
 
        return rc;
@@ -568,15 +578,6 @@ hdb_dn2id_delete(
        data.dlen = data.size;
        data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
 
-       /* Delete IDL cache entries */
-       if ( bdb->bi_idl_cache_size ) {
-               /* Ours */
-               key.data = &e->e_id;
-               bdb_idl_cache_del( bdb, db, &key );
-               /* Parent's */
-               key.data = &eip->bei_id;
-               bdb_idl_cache_del( bdb, db, &key );
-       }
        key.data = &nid;
        rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
        if ( rc ) return rc;
@@ -612,6 +613,21 @@ hdb_dn2id_delete(
        cursor->c_close( cursor );
        op->o_tmpfree( d, op->o_tmpmemctx );
 
+       /* Delete IDL cache entries */
+       if ( rc == 0 && bdb->bi_idl_cache_size ) {
+               ID tmp[2];
+               char *ptr = ((char *)&tmp[1])-1;
+               key.data = ptr;
+               key.size = sizeof(ID)+1;
+               tmp[1] = eip->bei_id;
+               *ptr = DN_ONE_PREFIX;
+               bdb_idl_cache_del_id( bdb, db, &key, e->e_id );
+               *ptr = DN_SUBTREE_PREFIX;
+               for (; eip && eip->bei_parent->bei_id; eip = eip->bei_parent) {
+                       tmp[1] = eip->bei_id;
+                       bdb_idl_cache_del_id( bdb, db, &key, e->e_id );
+               }
+       }
        return rc;
 }
 
@@ -809,21 +825,22 @@ hdb_dn2id_children(
 
 struct dn2id_cookie {
        struct bdb_info *bdb;
-       DB *db;
-       int prefix;
-       int rc;
+       Operation *op;
        EntryInfo *ei;
-       ID id;
-       ID nid;
-       ID dbuf;
        ID *ids;
-       void *ptr;
-       ID tmp[BDB_IDL_UM_SIZE];
+       ID *tmp;
        ID *buf;
+       DB *db;
+       DBC *dbc;
        DBT key;
        DBT data;
-       DBC *dbc;
-       Operation *op;
+       ID dbuf;
+       ID id;
+       ID nid;
+       int rc;
+       int depth;
+       char need_sort;
+       char prefix;
 };
 
 static int
@@ -845,23 +862,31 @@ hdb_dn2idl_internal(
 {
        BDB_IDL_ZERO( cx->tmp );
 
-       if ( !cx->ei ) {
-               cx->ei = bdb_cache_find_info( cx->bdb, cx->id );
-               if ( !cx->ei ) {
-                       cx->rc = DB_NOTFOUND;
-                       goto saveit;
-               }
-       }
-
        if ( cx->bdb->bi_idl_cache_size ) {
-               cx->key.data = &cx->id;
-               cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, cx->tmp);
-               if ( cx->rc == DB_NOTFOUND ) {
-                       return cx->rc;
+               char *ptr = ((char *)&cx->id)-1;
+
+               cx->key.data = ptr;
+               cx->key.size = sizeof(ID)+1;
+               if ( cx->prefix == DN_SUBTREE_PREFIX ) {
+                       ID *ids = cx->depth ? cx->tmp : cx->ids;
+                       *ptr = cx->prefix;
+                       cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, ids);
+                       if ( cx->rc == LDAP_SUCCESS ) {
+                               if ( cx->depth ) {
+                                       bdb_idl_append( cx->ids, cx->tmp );
+                                       cx->need_sort = 1;
+                               }
+                               return cx->rc;
+                       }
                }
+               *ptr = DN_ONE_PREFIX;
+               cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, cx->tmp);
                if ( cx->rc == LDAP_SUCCESS ) {
                        goto gotit;
                }
+               if ( cx->rc == DB_NOTFOUND ) {
+                       return cx->rc;
+               }
        }
 
        bdb_cache_entryinfo_lock( cx->ei );
@@ -874,6 +899,18 @@ hdb_dn2idl_internal(
                db_recno_t dkids = cx->ei->bei_dkids;
                ei.bei_parent = cx->ei;
 
+               /* Only one thread should load the cache */
+               while ( cx->ei->bei_state & CACHE_ENTRY_ONELEVEL ) {
+                       bdb_cache_entryinfo_unlock( cx->ei );
+                       ldap_pvt_thread_yield();
+                       bdb_cache_entryinfo_lock( cx->ei );
+                       if ( cx->ei->bei_ckids+1 == cx->ei->bei_dkids ) {
+                               goto synced;
+                       }
+               }
+
+               cx->ei->bei_state |= CACHE_ENTRY_ONELEVEL;
+
                bdb_cache_entryinfo_unlock( cx->ei );
 
                cx->rc = cx->db->cursor( cx->db, NULL, &cx->dbc,
@@ -887,10 +924,10 @@ hdb_dn2idl_internal(
 
                /* The first item holds the parent ID. Ignore it. */
                cx->key.data = &cx->nid;
+               cx->key.size = sizeof(ID);
                cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data, DB_SET );
                if ( cx->rc ) {
                        cx->dbc->c_close( cx->dbc );
-                       if ( cx->rc == DB_NOTFOUND ) goto saveit;
                        return cx->rc;
                }
 
@@ -911,9 +948,10 @@ hdb_dn2idl_internal(
                        DB_MULTIPLE | DB_NEXT_DUP )) == 0 ) {
                        u_int8_t *j;
                        size_t len;
-                       DB_MULTIPLE_INIT( cx->ptr, &cx->data );
-                       while (cx->ptr) {
-                               DB_MULTIPLE_NEXT( cx->ptr, &cx->data, j, 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;
@@ -939,10 +977,11 @@ hdb_dn2idl_internal(
                /* The in-memory cache is in sync with the on-disk data.
                 * do we have any kids?
                 */
+synced:
                cx->rc = 0;
                if ( cx->ei->bei_ckids > 0 ) {
-                       /* Walk the kids tree; order is irrelevant since bdb_idl_insert
-                        * will insert in sorted order.
+                       /* Walk the kids tree; order is irrelevant since bdb_idl_sort
+                        * will sort it later.
                         */
                        avl_apply( cx->ei->bei_kids, apply_func,
                                cx->tmp, -1, AVL_POSTORDER );
@@ -950,16 +989,21 @@ hdb_dn2idl_internal(
                bdb_cache_entryinfo_unlock( cx->ei );
        }
 
-saveit:
+       if ( !BDB_IDL_IS_RANGE( cx->tmp ) && cx->tmp[0] > 3 )
+               bdb_idl_sort( cx->tmp, cx->buf );
        if ( cx->bdb->bi_idl_cache_max_size ) {
-               cx->key.data = &cx->id;
+               char *ptr = ((char *)&cx->id)-1;
+               cx->key.data = ptr;
+               cx->key.size = sizeof(ID)+1;
+               *ptr = DN_ONE_PREFIX;
                bdb_idl_cache_put( cx->bdb, cx->db, &cx->key, cx->tmp, cx->rc );
        }
-       ;
+
 gotit:
        if ( !BDB_IDL_IS_ZERO( cx->tmp )) {
                if ( cx->prefix == DN_SUBTREE_PREFIX ) {
                        bdb_idl_append( cx->ids, cx->tmp );
+                       cx->need_sort = 1;
                        if ( !(cx->ei->bei_state & CACHE_ENTRY_NO_GRANDKIDS)) {
                                ID *save, idcurs;
                                EntryInfo *ei = cx->ei;
@@ -969,15 +1013,21 @@ gotit:
                                BDB_IDL_CPY( save, cx->tmp );
 
                                idcurs = 0;
+                               cx->depth++;
                                for ( cx->id = bdb_idl_first( save, &idcurs );
                                        cx->id != NOID;
                                        cx->id = bdb_idl_next( save, &idcurs )) {
+                                       cx->ei = bdb_cache_find_info( cx->bdb, cx->id );
+                                       if ( !cx->ei ||
+                                               ( cx->ei->bei_state & CACHE_ENTRY_NO_KIDS ))
+                                               continue;
+
                                        BDB_ID2DISK( cx->id, &cx->nid );
-                                       cx->ei = NULL;
                                        hdb_dn2idl_internal( cx );
                                        if ( !BDB_IDL_IS_ZERO( cx->tmp ))
                                                nokids = 0;
                                }
+                               cx->depth--;
                                cx->op->o_tmpfree( save, cx->op->o_tmpmemctx );
                                if ( nokids ) ei->bei_state |= CACHE_ENTRY_NO_GRANDKIDS;
                        }
@@ -1022,13 +1072,20 @@ hdb_dn2idl(
        cx.prefix = (op->ors_scope == LDAP_SCOPE_ONELEVEL) ?
                DN_ONE_PREFIX : DN_SUBTREE_PREFIX;
        cx.ids = ids;
-       cx.buf = stack;
+       cx.tmp = stack;
+       cx.buf = stack + BDB_IDL_UM_SIZE;
        cx.op = op;
+       cx.need_sort = 0;
+       cx.depth = 0;
 
-       BDB_IDL_ZERO( ids );
        if ( cx.prefix == DN_SUBTREE_PREFIX ) {
-               bdb_idl_insert( ids, cx.id );
+               ids[0] = 1;
+               ids[1] = cx.id;
+       } else {
+               BDB_IDL_ZERO( ids );
        }
+       if ( cx.ei->bei_state & CACHE_ENTRY_NO_KIDS )
+               return LDAP_SUCCESS;
 
        DBTzero(&cx.key);
        cx.key.ulen = sizeof(ID);
@@ -1038,8 +1095,19 @@ hdb_dn2idl(
        DBTzero(&cx.data);
 
        hdb_dn2idl_internal(&cx);
-       if ( !BDB_IDL_IS_ZERO( ids ) && !BDB_IDL_IS_RANGE( ids ))
-               bdb_idl_sort( ids );
+       if ( cx.need_sort ) {
+               char *ptr = ((char *)&cx.id)-1;
+               if ( !BDB_IDL_IS_RANGE( cx.ids ) && cx.ids[0] > 3 ) 
+                       bdb_idl_sort( cx.ids, cx.tmp );
+               cx.key.data = ptr;
+               cx.key.size = sizeof(ID)+1;
+               *ptr = cx.prefix;
+               cx.id = e->e_id;
+               bdb_idl_cache_put( cx.bdb, cx.db, &cx.key, cx.ids, cx.rc );
+       }
+
+       if ( cx.rc == DB_NOTFOUND )
+               cx.rc = LDAP_SUCCESS;
 
        return cx.rc;
 }
index 5c5e0ef304eb3524127699796d603ddf3883f2d5..d43d210e33b90239c6944c2c777c3e01d205d181 100644 (file)
@@ -224,8 +224,7 @@ int bdb_idl_insert( ID *ids, ID id )
        return 0;
 }
 
-#if 0  /* unused */
-static int idl_delete( ID *ids, ID id )
+static int bdb_idl_delete( ID *ids, ID id )
 {
        unsigned x = bdb_idl_search( ids, id );
 
@@ -264,7 +263,6 @@ static int idl_delete( ID *ids, ID id )
 
        return 0;
 }
-#endif /* unused */
 
 static char *
 bdb_show_key(
@@ -407,6 +405,65 @@ bdb_idl_cache_del(
        ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
 }
 
+void
+bdb_idl_cache_add_id(
+       struct bdb_info *bdb,
+       DB                      *db,
+       DBT                     *key,
+       ID                      id )
+{
+       bdb_idl_cache_entry_t *cache_entry, idl_tmp;
+       DBT2bv( key, &idl_tmp.kstr );
+       idl_tmp.db = db;
+       ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
+       cache_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
+                                     bdb_idl_entry_cmp );
+       if ( cache_entry != NULL ) {
+               if ( !BDB_IDL_IS_RANGE( cache_entry->idl ) &&
+                       cache_entry->idl[0] < BDB_IDL_DB_MAX ) {
+                       size_t s = BDB_IDL_SIZEOF( cache_entry->idl ) + sizeof(ID);
+                       cache_entry->idl = ch_realloc( cache_entry->idl, s );
+               }
+               bdb_idl_insert( cache_entry->idl, id );
+       }
+       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
+}
+
+void
+bdb_idl_cache_del_id(
+       struct bdb_info *bdb,
+       DB                      *db,
+       DBT                     *key,
+       ID                      id )
+{
+       bdb_idl_cache_entry_t *cache_entry, idl_tmp;
+       DBT2bv( key, &idl_tmp.kstr );
+       idl_tmp.db = db;
+       ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock );
+       cache_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
+                                     bdb_idl_entry_cmp );
+       if ( cache_entry != NULL ) {
+               bdb_idl_delete( cache_entry->idl, id );
+               if ( cache_entry->idl[0] == 0 ) {
+                       if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) cache_entry,
+                                               bdb_idl_entry_cmp ) == NULL ) {
+                               Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_del: "
+                                       "AVL delete failed\n",
+                                       0, 0, 0 );
+                       }
+                       --bdb->bi_idl_cache_size;
+                       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+                       IDL_LRU_DELETE( bdb, cache_entry );
+                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+                       free( cache_entry->kstr.bv_val );
+                       if ( cache_entry->idl )
+                               free( cache_entry->idl );
+                       free( cache_entry );
+               }
+       }
+       ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock );
+}
+
 int
 bdb_idl_fetch_key(
        BackendDB       *be,
@@ -1207,8 +1264,11 @@ ID bdb_idl_next( ID *ids, ID *cursor )
        return NOID;
 }
 
-/* Add one ID to an unsorted list. We still maintain a lo/hi reference
- * for fast range compaction.
+#ifdef BDB_HIER
+
+/* Add one ID to an unsorted list. We ensure that the first element is the
+ * minimum and the last element is the maximum, for fast range compaction.
+ *   this means IDLs up to length 3 are always sorted...
  */
 int bdb_idl_append_one( ID *ids, ID id )
 {
@@ -1229,27 +1289,29 @@ int bdb_idl_append_one( ID *ids, ID id )
                        tmp = ids[1];
                        ids[1] = id;
                        id = tmp;
-               } else if ( ids[0] > 1 && id > ids[2] ) {
-                       tmp = ids[2];
-                       ids[2] = id;
+               }
+               if ( ids[0] > 1 && id < ids[ids[0]] ) {
+                       tmp = ids[ids[0]];
+                       ids[ids[0]] = id;
                        id = tmp;
                }
        }
        ids[0]++;
        if ( ids[0] >= BDB_IDL_UM_MAX ) {
                ids[0] = NOID;
+               ids[2] = id;
        } else {
                ids[ids[0]] = id;
        }
        return 0;
 }
 
-/* Append unsorted list b to unsorted list a. Both lists must have their
- * lowest value in slot 1 and highest value in slot 2.
+/* Append sorted list b to sorted list a. The result is unsorted but
+ * a[1] is the min of the result and a[a[0]] is the max.
  */
 int bdb_idl_append( ID *a, ID *b )
 {
-       ID ida, idb;
+       ID ida, idb, tmp;
 
        if ( BDB_IDL_IS_ZERO( b ) ) {
                return 0;
@@ -1260,80 +1322,213 @@ int bdb_idl_append( ID *a, ID *b )
                return 0;
        }
 
+       ida = BDB_IDL_LAST( a );
+       idb = BDB_IDL_LAST( b );
        if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) ||
                a[0] + b[0] >= BDB_IDL_UM_MAX ) {
-               ida = IDL_MIN( a[1], b[1] );
-               idb = IDL_MAX( a[2], b[2] );
+               a[2] = IDL_MAX( ida, idb );
+               a[1] = IDL_MIN( a[1], b[1] );
                a[0] = NOID;
-               a[1] = ida;
-               a[2] = idb;
                return 0;
        }
 
-       if ( b[1] < a[1] ) {
-               ida = a[1];
-               a[1] = b[1];
-       } else {
-               ida = b[1];
+       if ( b[0] > 1 && ida > idb ) {
+               a[a[0]] = idb;
+               b[b[0]] = ida;
        }
-       a[0]++;
-       a[a[0]] = ida;
 
-       if ( b[0] > 1 && b[2] > a[2] ) {
-               ida = a[2];
-               a[2] = b[2];
+       if ( b[1] < a[1] ) {
+               tmp = a[1];
+               a[1] = b[1];
        } else {
-               ida = b[2];
+               tmp = b[1];
        }
        a[0]++;
-       a[a[0]] = ida;
+       a[a[0]] = tmp;
 
-       if ( b[0] > 2 ) {
-               int i = b[0] - 2;
-               AC_MEMCPY(a+a[0]+1, b+3, i * sizeof(ID));
+       if ( b[0] > 1 ) {
+               int i = b[0] - 1;
+               AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID));
                a[0] += i;
        }
        return 0;
-       
 }
 
-/* Sort an IDL using HeapSort */
-static void
-siftDown(ID *ids, int root, int bottom)
+#if 0
+
+/* Quicksort + Insertion sort for small arrays */
+
+#define SMALL  8
+#define        SWAP(a,b)       itmp=(a);(a)=(b);(b)=itmp
+
+void
+bdb_idl_sort( ID *ids, ID *tmp )
 {
-       int child;
-       ID temp;
+       int *istack = (int *)tmp;
+       int i,j,k,l,ir,jstack;
+       ID a, itmp;
 
-       temp = ids[root];
-       while ((child=root*2) <= bottom) {
-               if (child < bottom && ids[child] < ids[child + 1])
-                       child++;
+       if ( BDB_IDL_IS_RANGE( ids ))
+               return;
 
-               if (temp >= ids[child])
-                       break;
-               ids[root] = ids[child];
-               root = child;
+       ir = ids[0];
+       l = 1;
+       jstack = 0;
+       for(;;) {
+               if (ir - l < SMALL) {   /* Insertion sort */
+                       for (j=l+1;j<=ir;j++) {
+                               a = ids[j];
+                               for (i=j-1;i>=1;i--) {
+                                       if (ids[i] <= a) break;
+                                       ids[i+1] = ids[i];
+                               }
+                               ids[i+1] = a;
+                       }
+                       if (jstack == 0) break;
+                       ir = istack[jstack--];
+                       l = istack[jstack--];
+               } else {
+                       k = (l + ir) >> 1;      /* Choose median of left, center, right */
+                       SWAP(ids[k], ids[l+1]);
+                       if (ids[l] > ids[ir]) {
+                               SWAP(ids[l], ids[ir]);
+                       }
+                       if (ids[l+1] > ids[ir]) {
+                               SWAP(ids[l+1], ids[ir]);
+                       }
+                       if (ids[l] > ids[l+1]) {
+                               SWAP(ids[l], ids[l+1]);
+                       }
+                       i = l+1;
+                       j = ir;
+                       a = ids[l+1];
+                       for(;;) {
+                               do i++; while(ids[i] < a);
+                               do j--; while(ids[j] > a);
+                               if (j < i) break;
+                               SWAP(ids[i],ids[j]);
+                       }
+                       ids[l+1] = ids[j];
+                       ids[j] = a;
+                       jstack += 2;
+                       if (ir-i+1 >= j-1) {
+                               istack[jstack] = ir;
+                               istack[jstack-1] = i;
+                               ir = j-1;
+                       } else {
+                               istack[jstack] = j-1;
+                               istack[jstack-1] = l;
+                               l = i;
+                       }
+               }
        }
-       ids[root] = temp;
 }
 
+#else
+
+/* 8 bit Radix sort + insertion sort
+ * 
+ * based on code from http://www.cubic.org/docs/radix.htm
+ * with improvements by mbackes@symas.com and hyc@symas.com
+ *
+ * This code is O(n) but has a relatively high constant factor. For lists
+ * up to ~50 Quicksort is slightly faster; up to ~100 they are even.
+ * Much faster than quicksort for lists longer than ~100. Insertion
+ * sort is actually superior for lists <50.
+ */
+
+#define BUCKETS        (1<<8)
+#define SMALL  50
+
 void
-bdb_idl_sort( ID *ids )
+bdb_idl_sort( ID *ids, ID *tmp )
 {
-       int i;
-       ID temp;
-
-       if ( BDB_IDL_IS_RANGE( ids ))
+       int count, soft_limit, phase = 0, size = ids[0];
+       ID *idls[2];
+       unsigned char *maxv = (unsigned char *)&ids[size];
+
+       if ( BDB_IDL_IS_RANGE( ids ))
+               return;
+
+       /* Use insertion sort for small lists */
+       if ( size <= SMALL ) {
+               int i,j;
+               ID a;
+
+               for (j=1;j<=size;j++) {
+                       a = ids[j];
+                       for (i=j-1;i>=1;i--) {
+                               if (ids[i] <= a) break;
+                               ids[i+1] = ids[i];
+                       }
+                       ids[i+1] = a;
+               }
                return;
+       }
 
-       for (i = ids[0] / 2; i >= 1; i--)
-               siftDown(ids, i, ids[0]);
+       tmp[0] = size;
+       idls[0] = ids;
+       idls[1] = tmp;
 
-       for (i = ids[0]; i > 1; i--)
-       {
-               temp = ids[i];
-               ids[i] = ids[1];
-               ids[1] = temp;
-               siftDown(ids, 1, i-1);
+#if BYTE_ORDER == BIG_ENDIAN
+    for (soft_limit = 0; !maxv[soft_limit]; soft_limit++);
+#else
+    for (soft_limit = sizeof(ID)-1; !maxv[soft_limit]; soft_limit--);
+#endif
+
+       for (
+#if BYTE_ORDER == BIG_ENDIAN
+       count = sizeof(ID)-1; count >= soft_limit; --count
+#else
+       count = 0; count <= soft_limit; ++count
+#endif
+       ) {
+               unsigned int num[BUCKETS], * np, n, sum;
+               int i;
+        ID *sp, *source, *dest;
+        unsigned char *bp, *source_start;
+
+               source = idls[phase]+1;
+               dest = idls[phase^1]+1;
+               source_start =  ((unsigned char *) source) + count;
+
+        np = num;
+        for ( i = BUCKETS; i > 0; --i ) *np++ = 0;
+
+               /* count occurences of every byte value */
+               bp = source_start;
+        for ( i = size; i > 0; --i, bp += sizeof(ID) )
+                               num[*bp]++;
+
+               /* transform count into index by summing elements and storing
+                * into same array
+                */
+        sum = 0;
+        np = num;
+        for ( i = BUCKETS; i > 0; --i ) {
+                n = *np;
+                *np++ = sum;
+                sum += n;
+        }
+
+               /* fill dest with the right values in the right place */
+               bp = source_start;
+        sp = source;
+        for ( i = size; i > 0; --i, bp += sizeof(ID) ) {
+                np = num + *bp;
+                dest[*np] = *sp++;
+                ++(*np);
+        }
+               phase ^= 1;
+       }
+
+       /* copy back from temp if needed */
+       if ( phase ) {
+               ids++; tmp++;
+               for ( count = 0; count < size; ++count ) 
+                       *ids++ = *tmp++;
        }
 }
+#endif /* Quick vs Radix */
+
+#endif /* BDB_HIER */
index 357c6539bdf62ce9a5eff51f7623ea8653b6e98d..29fcc83b0bca4cc2ca0e78e79dfe84c21049c14c 100644 (file)
@@ -20,8 +20,9 @@
 /* IDL sizes - likely should be even bigger
  *   limiting factors: sizeof(ID), thread stack size
  */
-#define BDB_IDL_DB_SIZE                (1<<16) /* 64K IDL on disk */
-#define BDB_IDL_UM_SIZE                (1<<17) /* 128K IDL in memory */
+#define        BDB_IDL_LOGN    16      /* DB_SIZE is 2^16, UM_SIZE is 2^17 */
+#define BDB_IDL_DB_SIZE                (1<<BDB_IDL_LOGN)
+#define BDB_IDL_UM_SIZE                (1<<(BDB_IDL_LOGN+1))
 #define BDB_IDL_UM_SIZEOF      (BDB_IDL_UM_SIZE * sizeof(ID))
 
 #define BDB_IDL_DB_MAX         (BDB_IDL_DB_SIZE-1)
index d342febff2787200199ec3a5b7bae75198757f7c..e680de5ef2a176f9720f394f1272a1915c4bf565 100644 (file)
@@ -345,8 +345,6 @@ retry:      /* transaction retry */
        rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1,
                locker, &lock );
 
-       e = ei->bei_e;
-
        if ( rs->sr_err != 0 ) {
                Debug( LDAP_DEBUG_TRACE,
                        LDAP_XSTRING(bdb_modify) ": dn2entry failed (%d)\n",
@@ -380,6 +378,8 @@ retry:      /* transaction retry */
                }
        }
 
+       e = ei->bei_e;
+
        /* acquire and lock entry */
        /* FIXME: dn2entry() should return non-glue entry */
        if (( rs->sr_err == DB_NOTFOUND ) ||
index 0a6b8d7fd2c7281d2e2f6bb2638e21c631610fad..1bdebe513366690d75209887d1b6a82d77ec599f 100644 (file)
@@ -29,7 +29,6 @@ bdb_modrdn( Operation *op, SlapReply *rs )
        AttributeDescription *entry = slap_schema.si_ad_entry;
        struct berval   p_dn, p_ndn;
        struct berval   new_dn = {0, NULL}, new_ndn = {0, NULL};
-       int             isroot = -1;
        Entry           *e = NULL;
        Entry           *p = NULL;
        EntryInfo       *ei = NULL, *eip = NULL, *nei = NULL, *neip = NULL;
@@ -253,7 +252,15 @@ retry:     /* transaction retry */
        }
 
        if ( be_issuffix( op->o_bd, &e->e_nname ) ) {
+#ifdef BDB_MULTIPLE_SUFFIXES
+               /* Allow renaming one suffix entry to another */
                p_ndn = slap_empty_bv;
+#else
+               /* There can only be one suffix entry */
+               rs->sr_err = LDAP_NAMING_VIOLATION;
+               rs->sr_text = "cannot rename suffix entry";
+               goto return_results;
+#endif
        } else {
                dnParent( &e->e_nname, &p_ndn );
        }
@@ -290,101 +297,48 @@ retry:   /* transaction retry */
                        rs->sr_text = "old entry's parent does not exist";
                        goto return_results;
                }
+       } else {
+               p = (Entry *)&slap_entry_root;
+       }
 
-               /* check parent for "children" acl */
-               rs->sr_err = access_allowed( op, p,
-                       children, NULL,
-                       op->oq_modrdn.rs_newSup == NULL ?
-                               ACL_WRITE : ACL_WDEL,
-                       NULL );
+       /* check parent for "children" acl */
+       rs->sr_err = access_allowed( op, p,
+               children, NULL,
+               op->oq_modrdn.rs_newSup == NULL ?
+                       ACL_WRITE : ACL_WDEL,
+               NULL );
 
-               if ( ! rs->sr_err ) {
-                       switch( opinfo.boi_err ) {
-                       case DB_LOCK_DEADLOCK:
-                       case DB_LOCK_NOTGRANTED:
-                               goto retry;
-                       }
-
-                       rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-                       Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
-                               0, 0 );
-                       rs->sr_text = "no write access to old parent's children";
-                       goto return_results;
-               }
+       if ( !p_ndn.bv_len )
+               p = NULL;
 
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modrdn) ": wr to children "
-                       "of entry %s OK\n", p_ndn.bv_val, 0, 0 );
-               
-               if ( p_ndn.bv_val == slap_empty_bv.bv_val ) {
-                       p_dn = slap_empty_bv;
-               } else {
-                       dnParent( &e->e_name, &p_dn );
+       if ( ! rs->sr_err ) {
+               switch( opinfo.boi_err ) {
+               case DB_LOCK_DEADLOCK:
+               case DB_LOCK_NOTGRANTED:
+                       goto retry;
                }
 
-               Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_modrdn) ": parent dn=%s\n",
-                       p_dn.bv_val, 0, 0 );
+               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+               Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
+                       0, 0 );
+               rs->sr_text = "no write access to old parent's children";
+               goto return_results;
+       }
 
+       Debug( LDAP_DEBUG_TRACE,
+               LDAP_XSTRING(bdb_modrdn) ": wr to children "
+               "of entry %s OK\n", p_ndn.bv_val, 0, 0 );
+       
+       if ( p_ndn.bv_val == slap_empty_bv.bv_val ) {
+               p_dn = slap_empty_bv;
        } else {
-               /* no parent, modrdn entry directly under root */
-               isroot = be_isroot( op );
-               if ( ! isroot ) {
-                       if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
-                               || be_shadow_update( op ) ) {
-
-                               p = (Entry *)&slap_entry_root;
-
-                               /* check parent for "children" acl */
-                               rs->sr_err = access_allowed( op, p,
-                                       children, NULL,
-                                       op->oq_modrdn.rs_newSup == NULL ?
-                                               ACL_WRITE : ACL_WDEL,
-                                       NULL );
-
-                               p = NULL;
-
-                               if ( ! rs->sr_err ) {
-                                       switch( opinfo.boi_err ) {
-                                       case DB_LOCK_DEADLOCK:
-                                       case DB_LOCK_NOTGRANTED:
-                                               goto retry;
-                                       }
-
-                                       rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-                                       Debug( LDAP_DEBUG_TRACE, 
-                                               "no access to parent\n", 
-                                               0, 0, 0 );
-                                       rs->sr_text = "no write access to old parent";
-                                       goto return_results;
-                               }
-
-                               Debug( LDAP_DEBUG_TRACE,
-                                       LDAP_XSTRING(bdb_modrdn)
-                                       ": wr to children of entry \"\" OK\n",
-                                       0, 0, 0 );
-               
-                               p_dn.bv_val = "";
-                               p_dn.bv_len = 0;
-
-                               Debug( LDAP_DEBUG_TRACE,
-                                       LDAP_XSTRING(bdb_modrdn)
-                                       ": parent dn=\"\"\n",
-                                       0, 0, 0 );
-
-                       } else {
-                               Debug( LDAP_DEBUG_TRACE,
-                                       LDAP_XSTRING(bdb_modrdn)
-                                       ": no parent, not root "
-                                       "& \"\" is not suffix\n",
-                                       0, 0, 0);
-                               rs->sr_text = "no write access to old parent";
-                               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-                               goto return_results;
-                       }
-               }
+               dnParent( &e->e_name, &p_dn );
        }
 
+       Debug( LDAP_DEBUG_TRACE,
+               LDAP_XSTRING(bdb_modrdn) ": parent dn=%s\n",
+               p_dn.bv_val, 0, 0 );
+
        new_parent_dn = &p_dn;  /* New Parent unless newSuperior given */
 
        if ( op->oq_modrdn.rs_newSup != NULL ) {
@@ -402,6 +356,15 @@ retry:     /* transaction retry */
                }
        }
 
+       /* There's a BDB_MULTIPLE_SUFFIXES case here that this code doesn't
+        * support. E.g., two suffixes dc=foo,dc=com and dc=bar,dc=net.
+        * We do not allow modDN
+        *   dc=foo,dc=com
+        *    newrdn dc=bar
+        *    newsup dc=net
+        * and we probably should. But since MULTIPLE_SUFFIXES is deprecated
+        * I'm ignoring this problem for now.
+        */
        if ( op->oq_modrdn.rs_newSup != NULL ) {
                if ( op->oq_modrdn.rs_newSup->bv_len ) {
                        np_dn = op->oq_modrdn.rs_newSup;
@@ -410,8 +373,8 @@ retry:      /* transaction retry */
                        /* newSuperior == oldParent? - checked above */
                        /* newSuperior == entry being moved?, if so ==> ERROR */
                        if ( dnIsSuffix( np_ndn, &e->e_nname )) {
-                               rs->sr_err = LDAP_NAMING_VIOLATION;
-                               rs->sr_text = "new superior is invalid";
+                               rs->sr_err = LDAP_NO_SUCH_OBJECT;
+                               rs->sr_text = "new superior not found";
                                goto return_results;
                        }
                        /* Get Entry with dn=newSuperior. Does newSuperior exist? */
@@ -441,7 +404,7 @@ retry:      /* transaction retry */
                                        ": newSup(ndn=%s) not here!\n",
                                        np_ndn->bv_val, 0, 0);
                                rs->sr_text = "new superior not found";
-                               rs->sr_err = LDAP_OTHER;
+                               rs->sr_err = LDAP_NO_SUCH_OBJECT;
                                goto return_results;
                        }
 
@@ -493,62 +456,35 @@ retry:    /* transaction retry */
                        }
 
                } else {
-                       if ( isroot == -1 ) {
-                               isroot = be_isroot( op );
-                       }
-                       
                        np_dn = NULL;
 
                        /* no parent, modrdn entry directly under root */
-                       if ( ! isroot ) {
-                               if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
-                                       || be_isupdate( op ) ) {
-                                       np = (Entry *)&slap_entry_root;
-
-                                       /* check parent for "children" acl */
-                                       rs->sr_err = access_allowed( op, np,
-                                               children, NULL, ACL_WADD, NULL );
-
-                                       np = NULL;
-
-                                       if ( ! rs->sr_err ) {
-                                               switch( opinfo.boi_err ) {
-                                               case DB_LOCK_DEADLOCK:
-                                               case DB_LOCK_NOTGRANTED:
-                                                       goto retry;
-                                               }
-
-                                               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
-                                               Debug( LDAP_DEBUG_TRACE, 
-                                                       "no access to new superior\n", 
-                                                       0, 0, 0 );
-                                               rs->sr_text =
-                                                       "no write access to new superior's children";
-                                               goto return_results;
+                       if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
+                               || be_isupdate( op ) ) {
+                               np = (Entry *)&slap_entry_root;
+
+                               /* check parent for "children" acl */
+                               rs->sr_err = access_allowed( op, np,
+                                       children, NULL, ACL_WADD, NULL );
+
+                               np = NULL;
+
+                               if ( ! rs->sr_err ) {
+                                       switch( opinfo.boi_err ) {
+                                       case DB_LOCK_DEADLOCK:
+                                       case DB_LOCK_NOTGRANTED:
+                                               goto retry;
                                        }
 
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               LDAP_XSTRING(bdb_modrdn)
-                                               ": wr to children "
-                                               "of entry \"\" OK\n",
-                                               0, 0, 0 );
-               
-                               } else {
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               LDAP_XSTRING(bdb_modrdn)
-                                               ": new superior=\"\", not root "
-                                               "& \"\" is not suffix\n",
-                                               0, 0, 0 );
-                                       rs->sr_text = "no write access to new superior's children";
                                        rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+                                       Debug( LDAP_DEBUG_TRACE, 
+                                               "no access to new superior\n", 
+                                               0, 0, 0 );
+                                       rs->sr_text =
+                                               "no write access to new superior's children";
                                        goto return_results;
                                }
                        }
-
-                       Debug( LDAP_DEBUG_TRACE,
-                               LDAP_XSTRING(bdb_modrdn)
-                               ": new superior=\"\"\n",
-                               0, 0, 0 );
                }
 
                Debug( LDAP_DEBUG_TRACE,
index 5955721f4ea4956476d61a987ba0c0fc6b538fc4..a9a3b831560eac0568e5e8d3f563730389fbb27e 100644 (file)
@@ -217,6 +217,8 @@ BI_entry_get_rw bdb_entry_get;
 #define bdb_idl_cache_get                      BDB_SYMBOL(idl_cache_get)
 #define bdb_idl_cache_put                      BDB_SYMBOL(idl_cache_put)
 #define bdb_idl_cache_del                      BDB_SYMBOL(idl_cache_del)
+#define bdb_idl_cache_add_id           BDB_SYMBOL(idl_cache_add_id)
+#define bdb_idl_cache_del_id           BDB_SYMBOL(idl_cache_del_id)
 
 int bdb_idl_cache_get(
        struct bdb_info *bdb,
@@ -238,6 +240,20 @@ bdb_idl_cache_del(
        DB              *db,
        DBT             *key );
 
+void
+bdb_idl_cache_add_id(
+       struct bdb_info *bdb,
+       DB              *db,
+       DBT             *key,
+       ID              id );
+
+void
+bdb_idl_cache_del_id(
+       struct bdb_info *bdb,
+       DB              *db,
+       DBT             *key,
+       ID              id );
+
 #define bdb_idl_first                          BDB_SYMBOL(idl_first)
 #define bdb_idl_next                           BDB_SYMBOL(idl_next)
 #define bdb_idl_search                         BDB_SYMBOL(idl_search)
@@ -292,7 +308,7 @@ bdb_idl_union(
 ID bdb_idl_first( ID *ids, ID *cursor );
 ID bdb_idl_next( ID *ids, ID *cursor );
 
-void bdb_idl_sort( ID *ids );
+void bdb_idl_sort( ID *ids, ID *tmp );
 int bdb_idl_append( ID *a, ID *b );
 int bdb_idl_append_one( ID *ids, ID id );
 
index f05b725b2698ad04a5b389049e8a8f3bf58afadf..3151d3d6aa3f9e8d4e7198d25532dc1b9f392658 100644 (file)
@@ -64,12 +64,17 @@ static Entry * deref_base (
        rs->sr_err = LDAP_ALIAS_DEREF_PROBLEM;
        rs->sr_text = "maximum deref depth exceeded";
 
-       while (BDB_IDL_N(tmp) < op->o_bd->be_max_deref_depth) {
+       for (;;) {
                /* Remember the last entry we looked at, so we can
                 * report broken links
                 */
                *matched = e;
 
+               if (BDB_IDL_N(tmp) >= op->o_bd->be_max_deref_depth) {
+                       e = NULL;
+                       break;
+               }
+
                /* If this is part of a subtree or onelevel search,
                 * have we seen this ID before? If so, quit.
                 */
@@ -360,6 +365,9 @@ bdb_search( Operation *op, SlapReply *rs )
                ei = &ei_root;
                rs->sr_err = LDAP_SUCCESS;
        } else {
+               if ( op->ors_deref & LDAP_DEREF_FINDING ) {
+                       BDB_IDL_ZERO(candidates);
+               }
 dn2entry_retry:
                /* get entry with reader lock */
                rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei,
@@ -388,10 +396,26 @@ dn2entry_retry:
                return rs->sr_err;
        }
 
-       if ( e && (op->ors_deref & LDAP_DEREF_FINDING) && is_entry_alias(e) ) {
-               BDB_IDL_ZERO(candidates);
-               e = deref_base( op, rs, e, &matched, locker, &lock,
-                       candidates, NULL );
+       if ( op->ors_deref & LDAP_DEREF_FINDING ) {
+               if ( matched && is_entry_alias( matched )) {
+                       struct berval stub;
+
+                       stub.bv_val = op->o_req_ndn.bv_val;
+                       stub.bv_len = op->o_req_ndn.bv_len - matched->e_nname.bv_len - 1;
+                       e = deref_base( op, rs, matched, &matched, locker, &lock,
+                               candidates, NULL );
+                       if ( e ) {
+                               build_new_dn( &op->o_req_ndn, &e->e_nname, &stub,
+                                       op->o_tmpmemctx );
+                               bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache,
+                                       e, &lock);
+                               matched = NULL;
+                               goto dn2entry_retry;
+                       }
+               } else if ( e && is_entry_alias( e )) {
+                       e = deref_base( op, rs, e, &matched, locker, &lock,
+                               candidates, NULL );
+               }
        }
 
        if ( e == NULL ) {
@@ -417,7 +441,8 @@ dn2entry_retry:
                                erefs = is_entry_referral( matched )
                                        ? get_entry_referrals( op, matched )
                                        : NULL;
-                               rs->sr_err = LDAP_REFERRAL;
+                               if ( rs->sr_err == DB_NOTFOUND )
+                                       rs->sr_err = LDAP_REFERRAL;
                                rs->sr_matched = matched_dn.bv_val;
                        }
 
index 854e5c3b5411a3c8a9cdb5fdc39d3691a707fe08..e7fa1e7ec330d23aa30f663dc60f33d30bc6ae7e 100644 (file)
@@ -19,13 +19,13 @@ XXDIR = $(srcdir)/../back-bdb
 
 XXSRCS = init.c tools.c config.c \
        add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
-       extended.c referral.c operational.c alock.c \
+       extended.c referral.c operational.c \
        attr.c index.c key.c dbcache.c filterindex.c trans.c \
        dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c
 SRCS = $(XXSRCS)
 OBJS = init.lo tools.lo config.lo \
        add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
-       extended.lo referral.lo operational.lo alock.lo \
+       extended.lo referral.lo operational.lo \
        attr.lo index.lo key.lo dbcache.lo filterindex.lo trans.lo \
        dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo
 
index 828b55261eef1afa22773232406acc5242068fd4..e9a74db2f8aea81e4c07badb26119a585ff84da1 100644 (file)
@@ -28,15 +28,55 @@ LDAP_BEGIN_DECL
 
 struct ldapconn {
        Connection              *lc_conn;
-#define        LDAP_BACK_PRIV_CONN     ((void *)0x0)
-#define        LDAP_BACK_PRIV_CONN_TLS ((void *)0x1)
+#define        LDAP_BACK_PCONN         ((void *)0x0)
+#define        LDAP_BACK_PCONN_TLS     ((void *)0x1)
+#define        LDAP_BACK_PCONN_ID(c)   ((void *)(c) > LDAP_BACK_PCONN_TLS ? (c)->c_connid : -1)
+#ifdef HAVE_TLS
+#define        LDAP_BACK_PCONN_SET(op) ((op)->o_conn->c_is_tls ? LDAP_BACK_PCONN_TLS : LDAP_BACK_PCONN)
+#else /* ! HAVE_TLS */
+#define        LDAP_BACK_PCONN_SET(op) (LDAP_BACK_PCONN)
+#endif /* ! HAVE_TLS */
+
        LDAP                    *lc_ld;
        struct berval           lc_cred;
        struct berval           lc_bound_ndn;
        struct berval           lc_local_ndn;
-       int                     lc_bound;
-       int                     lc_ispriv;
-       int                     lc_is_tls;
+       unsigned                lc_lcflags;
+#define LDAP_BACK_CONN_ISSET(lc,f)     ((lc)->lc_lcflags & (f))
+#define        LDAP_BACK_CONN_SET(lc,f)        ((lc)->lc_lcflags |= (f))
+#define        LDAP_BACK_CONN_CLEAR(lc,f)      ((lc)->lc_lcflags &= ~(f))
+#define        LDAP_BACK_CONN_CPY(lc,f,mlc) \
+       do { \
+               if ( ((f) & (mlc)->lc_lcflags) == (f) ) { \
+                       (lc)->lc_lcflags |= (f); \
+               } else { \
+                       (lc)->lc_lcflags &= ~(f); \
+               } \
+       } while ( 0 )
+
+#define        LDAP_BACK_FCONN_ISBOUND (0x01)
+#define        LDAP_BACK_FCONN_ISANON  (0x02)
+#define        LDAP_BACK_FCONN_ISBMASK (LDAP_BACK_FCONN_ISBOUND|LDAP_BACK_FCONN_ISANON)
+#define        LDAP_BACK_FCONN_ISPRIV  (0x04)
+#define        LDAP_BACK_FCONN_ISTLS   (0x08)
+
+#define        LDAP_BACK_CONN_ISBOUND(lc)              LDAP_BACK_CONN_ISSET((lc), LDAP_BACK_FCONN_ISBOUND)
+#define        LDAP_BACK_CONN_ISBOUND_SET(lc)          LDAP_BACK_CONN_SET((lc), LDAP_BACK_FCONN_ISBOUND)
+#define        LDAP_BACK_CONN_ISBOUND_CLEAR(lc)        LDAP_BACK_CONN_CLEAR((lc), LDAP_BACK_FCONN_ISBMASK)
+#define        LDAP_BACK_CONN_ISBOUND_CPY(lc, mlc)     LDAP_BACK_CONN_CPY((lc), LDAP_BACK_FCONN_ISBOUND, (mlc))
+#define        LDAP_BACK_CONN_ISANON(lc)               LDAP_BACK_CONN_ISSET((lc), LDAP_BACK_FCONN_ISANON)
+#define        LDAP_BACK_CONN_ISANON_SET(lc)           LDAP_BACK_CONN_SET((lc), LDAP_BACK_FCONN_ISANON)
+#define        LDAP_BACK_CONN_ISANON_CLEAR(lc)         LDAP_BACK_CONN_ISBOUND_CLEAR((lc))
+#define        LDAP_BACK_CONN_ISANON_CPY(lc, mlc)      LDAP_BACK_CONN_CPY((lc), LDAP_BACK_FCONN_ISANON, (mlc))
+#define        LDAP_BACK_CONN_ISPRIV(lc)               LDAP_BACK_CONN_ISSET((lc), LDAP_BACK_FCONN_ISPRIV)
+#define        LDAP_BACK_CONN_ISPRIV_SET(lc)           LDAP_BACK_CONN_SET((lc), LDAP_BACK_FCONN_ISPRIV)
+#define        LDAP_BACK_CONN_ISPRIV_CLEAR(lc)         LDAP_BACK_CONN_CLEAR((lc), LDAP_BACK_FCONN_ISPRIV)
+#define        LDAP_BACK_CONN_ISPRIV_CPY(lc, mlc)      LDAP_BACK_CONN_CPY((lc), LDAP_BACK_FCONN_ISPRIV, (mlc))
+#define        LDAP_BACK_CONN_ISTLS(lc)                LDAP_BACK_CONN_ISSET((lc), LDAP_BACK_FCONN_ISTLS)
+#define        LDAP_BACK_CONN_ISTLS_SET(lc)            LDAP_BACK_CONN_SET((lc), LDAP_BACK_FCONN_ISTLS)
+#define        LDAP_BACK_CONN_ISTLS_CLEAR(lc)          LDAP_BACK_CONN_CLEAR((lc), LDAP_BACK_FCONN_ISTLS)
+#define        LDAP_BACK_CONN_ISTLS_CPY(lc, mlc)       LDAP_BACK_CONN_CPY((lc), LDAP_BACK_FCONN_ISTLS, (mlc))
+
        unsigned                lc_refcnt;
        unsigned                lc_flags;
 };
@@ -89,6 +129,12 @@ struct ldapinfo {
        BerVarray       idassert_authz;
        /* end of ID assert stuff */
 
+       int             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;
 #define LDAP_BACK_F_NONE               0x00U
@@ -116,7 +162,10 @@ struct ldapinfo {
 
        Avlnode         *conntree;
 
+#if 0
+       /* FIXME: automatic rwm instantiation removed */
        int             rwm_started;
+#endif
 };
 
 typedef enum ldap_back_send_t {
@@ -129,6 +178,15 @@ typedef enum ldap_back_send_t {
 /* define to use asynchronous StartTLS */
 #define SLAP_STARTTLS_ASYNCHRONOUS
 
+/* timeout to use when calling ldap_result() */
+#define        LDAP_BACK_RESULT_TIMEOUT        (0)
+#define        LDAP_BACK_RESULT_UTIMEOUT       (100000)
+#define        LDAP_BACK_TV_SET(tv) \
+       do { \
+               (tv)->tv_sec = LDAP_BACK_RESULT_TIMEOUT; \
+               (tv)->tv_usec = LDAP_BACK_RESULT_UTIMEOUT; \
+       } while ( 0 )
+
 LDAP_END_DECL
 
 #include "proto-ldap.h"
index 5f6960abed0ecc9f2af8f189ba1bb368a8acc67b..93f5cff445748f5130a6be828a4d81bb21e9f6da 100644 (file)
@@ -37,7 +37,9 @@
 
 #define PRINT_CONNTREE 0
 
-static LDAP_REBIND_PROC        ldap_back_rebind;
+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 );
@@ -63,7 +65,7 @@ ldap_back_bind( Operation *op, SlapReply *rs )
                ch_free( lc->lc_bound_ndn.bv_val );
                BER_BVZERO( &lc->lc_bound_ndn );
        }
-       lc->lc_bound = 0;
+       LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
 
        /* method is always LDAP_AUTH_SIMPLE if we got here */
        rs->sr_err = ldap_sasl_bind( lc->lc_ld, op->o_req_dn.bv_val,
@@ -79,13 +81,13 @@ ldap_back_bind( Operation *op, SlapReply *rs )
                /* NOTE: use with care */
                if ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
                        ldap_back_proxy_authz_bind( lc, op, rs );
-                       if ( lc->lc_bound == 0 ) {
+                       if ( !LDAP_BACK_CONN_ISBOUND( lc ) ) {
                                rc = 1;
                                goto done;
                        }
                }
 
-               lc->lc_bound = 1;
+               LDAP_BACK_CONN_ISBOUND_SET( lc );
                ber_dupbv( &lc->lc_bound_ndn, &op->o_req_ndn );
 
                if ( LDAP_BACK_SAVECRED( li ) ) {
@@ -94,13 +96,15 @@ ldap_back_bind( Operation *op, SlapReply *rs )
                                                lc->lc_cred.bv_len );
                        }
                        ber_bvreplace( &lc->lc_cred, &op->orb_cred );
-                       ldap_set_rebind_proc( lc->lc_ld, ldap_back_rebind, lc );
+                       ldap_set_rebind_proc( lc->lc_ld, ldap_back_rebind_f, lc );
                }
        }
 done:;
 
        /* must re-insert if local DN changed as result of bind */
-       if ( lc->lc_bound && !dn_match( &op->o_req_ndn, &lc->lc_local_ndn ) ) {
+       if ( LDAP_BACK_CONN_ISBOUND( lc )
+               && !dn_match( &op->o_req_ndn, &lc->lc_local_ndn ) )
+       {
                int             lerr;
 
                /* wait for all other ops to release the connection */
@@ -251,16 +255,17 @@ ldap_back_start_tls(
        int             *is_tls,
        const char      *url,
        unsigned        flags,
+       int             retries,
        const char      **text )
 {
        int             rc = LDAP_SUCCESS;
-       struct ldapinfo li;
+       struct ldapinfo dummy;
 
-       /* this is ridicolous... */
-       li.flags = flags;
+       /* this is ridiculous... */
+       dummy.flags = flags;
 
        /* start TLS ("tls-[try-]{start,propagate}" statements) */
-       if ( ( LDAP_BACK_USE_TLS( &li ) || ( *is_tls && LDAP_BACK_PROPAGATE_TLS( &li ) ) )
+       if ( ( LDAP_BACK_USE_TLS( &dummy ) || ( *is_tls && LDAP_BACK_PROPAGATE_TLS( &dummy ) ) )
                                && !ldap_is_ldaps_url( url ) )
        {
 #ifdef SLAP_STARTTLS_ASYNCHRONOUS
@@ -285,8 +290,9 @@ ldap_back_start_tls(
                rc = ldap_start_tls( ld, NULL, NULL, &msgid );
                if ( rc == LDAP_SUCCESS ) {
                        LDAPMessage     *res = NULL;
-                       int             retries = 1;
-                       struct timeval  tv = { 0, 100000 };
+                       struct timeval  tv;
+
+                       LDAP_BACK_TV_SET( &tv );
 
 retry:;
                        rc = ldap_result( ld, msgid, LDAP_MSG_ALL, &tv, &res );
@@ -294,10 +300,12 @@ retry:;
                                rc = LDAP_OTHER;
 
                        } else if ( rc == 0 ) {
-                               if ( retries ) {
-                                       retries--;
-                                       tv.tv_sec = 0;
-                                       tv.tv_usec = 100000;
+                               if ( retries != LDAP_BACK_RETRY_NEVER ) {
+                                       ldap_pvt_thread_yield();
+                                       if ( retries > 0 ) {
+                                               retries--;
+                                       }
+                                       LDAP_BACK_TV_SET( &tv );
                                        goto retry;
                                }
                                rc = LDAP_OTHER;
@@ -359,7 +367,7 @@ retry:;
                        break;
 
                default:
-                       if ( LDAP_BACK_TLS_CRITICAL( &li ) ) {
+                       if ( LDAP_BACK_TLS_CRITICAL( &dummy ) ) {
                                *text = "could not start TLS";
                                break;
                        }
@@ -406,9 +414,8 @@ 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, &rs->sr_text );
+       rs->sr_err = ldap_back_start_tls( ld, op->o_protocol, &is_tls,
+                       li->url, li->flags, li->nretries, &rs->sr_text );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                ldap_unbind_ext( ld, NULL, NULL );
                goto error_return;
@@ -422,7 +429,11 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda
        (*lcp)->lc_ld = ld;
        (*lcp)->lc_refcnt = 1;
 #ifdef HAVE_TLS
-       (*lcp)->lc_is_tls = is_tls;
+       if ( is_tls ) {
+               LDAP_BACK_CONN_ISTLS_SET( *lcp );
+       } else {
+               LDAP_BACK_CONN_ISTLS_CLEAR( *lcp );
+       }
 #endif /* HAVE_TLS */
 
 error_return:;
@@ -448,45 +459,24 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
                        lc_curr = { 0 };
        int             refcnt = 1;
 
-       /* Searches for a ldapconn in the avl tree */
-
-       /* Explicit binds must not be shared */
-       if ( op->o_tag == LDAP_REQ_BIND
-               || ( op->o_conn
-                       && op->o_conn->c_authz_backend
-                       && op->o_bd->be_private == op->o_conn->c_authz_backend->be_private ) )
-       {
-               lc_curr.lc_conn = op->o_conn;
-
-       } else {
-#ifdef HAVE_TLS
-               if ( op->o_conn->c_is_tls ) {
-                       lc_curr.lc_conn = LDAP_BACK_PRIV_CONN_TLS;
-               } else
-#endif /* HAVE_TLS */
-               {
-                       lc_curr.lc_conn = LDAP_BACK_PRIV_CONN;
-               }
-       }
-       
        /* Internal searches are privileged and shared. So is root. */
-       /* FIXME: there seem to be concurrency issues */
        if ( op->o_do_not_cache || be_isroot( op ) ) {
+               LDAP_BACK_CONN_ISPRIV_SET( &lc_curr );
                lc_curr.lc_local_ndn = op->o_bd->be_rootndn;
-#ifdef HAVE_TLS
-               if ( op->o_conn->c_is_tls ) {
-                       lc_curr.lc_conn = LDAP_BACK_PRIV_CONN_TLS;
-               } else
-#endif /* HAVE_TLS */
-               {
-                       lc_curr.lc_conn = LDAP_BACK_PRIV_CONN;
-               }
-               lc_curr.lc_ispriv = 1;
+               lc_curr.lc_conn = LDAP_BACK_PCONN_SET( op );
 
        } else {
                lc_curr.lc_local_ndn = op->o_ndn;
+               /* Explicit binds must not be shared */
+               if ( op->o_tag == LDAP_REQ_BIND || SLAP_IS_AUTHZ_BACKEND( op ) ) {
+                       lc_curr.lc_conn = op->o_conn;
+       
+               } else {
+                       lc_curr.lc_conn = LDAP_BACK_PCONN_SET( op );
+               }
        }
 
+       /* Searches for a ldapconn in the avl tree */
        ldap_pvt_thread_mutex_lock( &li->conn_mutex );
 
        lc = (struct ldapconn *)avl_find( li->conntree, 
@@ -505,16 +495,16 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
                lc->lc_conn = lc_curr.lc_conn;
                ber_dupbv( &lc->lc_local_ndn, &lc_curr.lc_local_ndn );
 
-               if ( lc_curr.lc_ispriv ) {
+               if ( LDAP_BACK_CONN_ISPRIV( &lc_curr ) ) {
                        ber_dupbv( &lc->lc_cred, &li->acl_passwd );
                        ber_dupbv( &lc->lc_bound_ndn, &li->acl_authcDN );
-                       lc->lc_ispriv = lc_curr.lc_ispriv;
+                       LDAP_BACK_CONN_ISPRIV_SET( lc );
 
                } else {
                        BER_BVZERO( &lc->lc_cred );
                        BER_BVZERO( &lc->lc_bound_ndn );
-                       if ( op->o_conn && !BER_BVISEMPTY( &op->o_ndn )
-                               && op->o_bd->be_private == op->o_conn->c_authz_backend->be_private )
+                       if ( !BER_BVISEMPTY( &op->o_ndn )
+                               && SLAP_IS_AUTHZ_BACKEND( op ) )
                        {
                                ber_dupbv( &lc->lc_bound_ndn, &op->o_ndn );
                        }
@@ -525,12 +515,12 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
                 * check if the non-TLS connection was already
                 * in cache; in case, destroy the newly created
                 * connection and use the existing one */
-               if ( lc->lc_conn == LDAP_BACK_PRIV_CONN_TLS
+               if ( lc->lc_conn == LDAP_BACK_PCONN_TLS
                                && !ldap_tls_inplace( lc->lc_ld ) )
                {
                        struct ldapconn *tmplc;
                        
-                       lc_curr.lc_conn = LDAP_BACK_PRIV_CONN;
+                       lc_curr.lc_conn = LDAP_BACK_PCONN;
                        ldap_pvt_thread_mutex_lock( &li->conn_mutex );
                        tmplc = (struct ldapconn *)avl_find( li->conntree, 
                                        (caddr_t)&lc_curr, ldap_back_conn_cmp );
@@ -547,7 +537,7 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
                }
 #endif /* HAVE_TLS */
 
-               lc->lc_bound = 0;
+               LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
 
                /* Inserts the newly created ldapconn in the avl tree */
                ldap_pvt_thread_mutex_lock( &li->conn_mutex );
@@ -619,150 +609,160 @@ ldap_back_dobind_int(
        int                     retries,
        int                     dolock )
 {      
-       int             rc;
+       struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+
+       int             rc = LDAP_BACK_CONN_ISBOUND( lc );
        ber_int_t       msgid;
 
        assert( retries >= 0 );
 
-       if ( !lc->lc_bound ) {
-               struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+       if ( rc ) {
+               return rc;
+       }
 
-               /*
-                * FIXME: we need to let clients use proxyAuthz
-                * otherwise we cannot do symmetric pools of servers;
-                * we have to live with the fact that a user can
-                * authorize itself as any ID that is allowed
-                * by the authzTo directive of the "proxyauthzdn".
-                */
-               /*
-                * NOTE: current Proxy Authorization specification
-                * and implementation do not allow proxy authorization
-                * control to be provided with Bind requests
-                */
-               /*
-                * if no bind took place yet, but the connection is bound
-                * and the "idassert-authcDN" (or other ID) is set, 
-                * then bind as the asserting identity and explicitly 
-                * add the proxyAuthz control to every operation with the
-                * dn bound to the connection as control value.
-                * This is done also if this is the authrizing backend,
-                * but the "override" flag is given to idassert.
-                * It allows to use SASL bind and yet proxyAuthz users
-                */
-               if ( op->o_conn != NULL &&
-                               !op->o_do_not_cache &&
-                               ( BER_BVISNULL( &lc->lc_bound_ndn ) ||
-                                 ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
-               {
-                       (void)ldap_back_proxy_authz_bind( lc, op, rs );
-                       goto done;
-               }
+       /*
+        * FIXME: we need to let clients use proxyAuthz
+        * otherwise we cannot do symmetric pools of servers;
+        * we have to live with the fact that a user can
+        * authorize itself as any ID that is allowed
+        * by the authzTo directive of the "proxyauthzdn".
+        */
+       /*
+        * NOTE: current Proxy Authorization specification
+        * and implementation do not allow proxy authorization
+        * control to be provided with Bind requests
+        */
+       /*
+        * if no bind took place yet, but the connection is bound
+        * and the "idassert-authcDN" (or other ID) is set, 
+        * then bind as the asserting identity and explicitly 
+        * add the proxyAuthz control to every operation with the
+        * dn bound to the connection as control value.
+        * This is done also if this is the authrizing backend,
+        * but the "override" flag is given to idassert.
+        * It allows to use SASL bind and yet proxyAuthz users
+        */
+       if ( op->o_conn != NULL &&
+                       !op->o_do_not_cache &&
+                       ( BER_BVISNULL( &lc->lc_bound_ndn ) ||
+                         ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
+       {
+               (void)ldap_back_proxy_authz_bind( lc, op, rs );
+               goto done;
+       }
 
 #ifdef HAVE_CYRUS_SASL
-               if ( lc->lc_ispriv && li->acl_authmethod == LDAP_AUTH_SASL ) {
-                       void            *defaults = NULL;
-
-#if 1  /* will deal with this later... */
-                       if ( li->acl_secprops != NULL ) {
-                               rc = ldap_set_option( lc->lc_ld,
-                                       LDAP_OPT_X_SASL_SECPROPS, 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 );
-                                       goto done;
-                               }
-                       }
-#endif
+       if ( LDAP_BACK_CONN_ISPRIV( lc )
+               && li->acl_authmethod == LDAP_AUTH_SASL )
+       {
+               void            *defaults = NULL;
 
-                       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,
-                                       NULL );
+               if ( li->acl_secprops != NULL ) {
+                       rc = ldap_set_option( lc->lc_ld,
+                               LDAP_OPT_X_SASL_SECPROPS, li->acl_secprops);
 
-                       rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld,
-                                       li->acl_authcDN.bv_val,
-                                       li->acl_sasl_mech.bv_val, NULL, NULL,
-                                       LDAP_SASL_QUIET, lutil_sasl_interact,
-                                       defaults );
+                       if ( rc != LDAP_OPT_SUCCESS ) {
+                               Debug( LDAP_DEBUG_ANY, "Error: ldap_set_option "
+                                       "(%s,SECPROPS,\"%s\") failed!\n",
+                                       li->url, li->acl_secprops, 0 );
+                               goto done;
+                       }
+               }
 
-                       lutil_sasl_freedefs( defaults );
+               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,
+                               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,
+                               LDAP_SASL_QUIET, lutil_sasl_interact,
+                               defaults );
 
-                       rs->sr_err = slap_map_api2result( rs );
-                       if ( rs->sr_err != LDAP_SUCCESS ) {
-                               lc->lc_bound = 0;
-                               send_ldap_result( op, rs );
+               lutil_sasl_freedefs( defaults );
 
-                       } else {
-                               lc->lc_bound = 1;
-                       }
-                       goto done;
+               rs->sr_err = slap_map_api2result( rs );
+               if ( rs->sr_err != LDAP_SUCCESS ) {
+                       LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
+                       send_ldap_result( op, rs );
+
+               } else {
+                       LDAP_BACK_CONN_ISBOUND_SET( lc );
                }
+               goto done;
+       }
 #endif /* HAVE_CYRUS_SASL */
 
 retry:;
-               rs->sr_err = ldap_sasl_bind( lc->lc_ld,
-                               lc->lc_bound_ndn.bv_val,
-                               LDAP_SASL_SIMPLE, &lc->lc_cred,
-                               NULL, NULL, &msgid );
-
-               if ( rs->sr_err == LDAP_SERVER_DOWN ) {
-                       if ( retries > 0 ) {
-                               if ( dolock ) {
-                                       ldap_pvt_thread_mutex_lock( &li->conn_mutex );
-                               }
+       rs->sr_err = ldap_sasl_bind( lc->lc_ld,
+                       lc->lc_bound_ndn.bv_val,
+                       LDAP_SASL_SIMPLE, &lc->lc_cred,
+                       NULL, NULL, &msgid );
+
+       if ( rs->sr_err == LDAP_SERVER_DOWN ) {
+               if ( retries != LDAP_BACK_RETRY_NEVER ) {
+                       if ( dolock ) {
+                               ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+                       }
 
-                               assert( lc->lc_refcnt > 0 );
-                               if ( lc->lc_refcnt == 1 ) {
-                                       ldap_unbind_ext( lc->lc_ld, NULL, NULL );
-                                       lc->lc_ld = NULL;
+                       assert( lc->lc_refcnt > 0 );
+                       if ( lc->lc_refcnt == 1 ) {
+                               ldap_unbind_ext( lc->lc_ld, NULL, NULL );
+                               lc->lc_ld = NULL;
 
-                                       /* lc here must be the regular lc, reset and ready for init */
-                                       rs->sr_err = ldap_back_prepare_conn( &lc, op, rs, sendok );
-                               }
-                               if ( dolock ) {
-                                       ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
-                               }
-                               if ( rs->sr_err == LDAP_SUCCESS ) {
+                               /* lc here must be the regular lc, reset and ready for init */
+                               rs->sr_err = ldap_back_prepare_conn( &lc, op, rs, sendok );
+                       }
+                       if ( dolock ) {
+                               ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+                       }
+                       if ( rs->sr_err == LDAP_SUCCESS ) {
+                               if ( retries > 0 ) {
                                        retries--;
-                                       goto retry;
                                }
+                               goto retry;
                        }
+               }
 
-                       ldap_back_freeconn( op, lc );
-                       rs->sr_err = slap_map_api2result( rs );
+               ldap_back_freeconn( op, lc );
+               rs->sr_err = slap_map_api2result( rs );
 
-                       return 0;
-               }
+               return 0;
+       }
 
-               rc = ldap_back_op_result( lc, op, rs, msgid, sendok );
-               if ( rc == LDAP_SUCCESS ) {
-                       lc->lc_bound = 1;
-               }
+       rc = ldap_back_op_result( lc, op, rs, msgid, sendok );
+       if ( rc == LDAP_SUCCESS ) {
+               LDAP_BACK_CONN_ISBOUND_SET( lc );
+
+       } else {
+               ldap_back_release_conn( op, rs, lc );
        }
 
 done:;
-       rc = lc->lc_bound;
+       rc = LDAP_BACK_CONN_ISBOUND( lc );
+
        return rc;
 }
 
 int
 ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 {
-       return ldap_back_dobind_int( lc, op, rs, sendok, 1, 1 );
+       struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+
+       return ldap_back_dobind_int( lc, op, rs, sendok, li->nretries, 1 );
 }
 
 /*
- * ldap_back_rebind
+ * ldap_back_default_rebind
  *
  * This is a callback used for chasing referrals using the same
  * credentials as the original user on this session.
  */
 static int 
-ldap_back_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
+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;
@@ -772,11 +772,12 @@ ldap_back_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
        assert( lc != NULL );
 
        if ( !ldap_tls_inplace( ld ) ) {
-               int             is_tls = lc->lc_is_tls,
+               int             is_tls = LDAP_BACK_CONN_ISTLS( lc ),
                                rc;
                const char      *text = NULL;
 
-               rc = ldap_back_start_tls( ld, 0, &is_tls, url, lc->lc_flags, &text );
+               rc = ldap_back_start_tls( ld, 0, &is_tls, url, lc->lc_flags,
+                       LDAP_BACK_RETRY_DEFAULT, &text );
                if ( rc != LDAP_SUCCESS ) {
                        return rc;
                }
@@ -811,14 +812,15 @@ ldap_back_op_result(
         * remote server response */
        if ( ERR_OK( rs->sr_err ) ) {
                int             rc;
-               struct timeval  tv = { 0, 100000 };
+               struct timeval  tv;
+
+               LDAP_BACK_TV_SET( &tv );
 
 retry:;
                /* if result parsing fails, note the failure reason */
                switch ( ldap_result( lc->lc_ld, msgid, 1, &tv, &res ) ) {
                case 0:
-                       tv.tv_sec = 0;
-                       tv.tv_usec = 100000;    /* 0.1 s */
+                       LDAP_BACK_TV_SET( &tv );
                        ldap_pvt_thread_yield();
                        goto retry;
 
@@ -889,7 +891,7 @@ ldap_back_retry( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_se
        if ( lc->lc_refcnt == 1 ) {
                ldap_unbind_ext( lc->lc_ld, NULL, NULL );
                lc->lc_ld = NULL;
-               lc->lc_bound = 0;
+               LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
 
                /* lc here must be the regular lc, reset and ready for init */
                rc = ldap_back_prepare_conn( &lc, op, rs, sendok );
@@ -964,7 +966,7 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                        if ( rs->sr_err != LDAP_SUCCESS ) {
                                if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
                                        send_ldap_result( op, rs );
-                                       lc->lc_bound = 0;
+                                       LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
 
                                } else {
                                        rs->sr_err = LDAP_SUCCESS;
@@ -1022,18 +1024,17 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                        }
                }
 
-#if 0  /* will deal with this later... */
-               if ( sasl_secprops != NULL ) {
-                       rs->sr_err = ldap_set_option( lc->lc_ld, LDAP_OPT_X_SASL_SECPROPS,
-                               (void *) sasl_secprops );
+               if ( li->idassert_secprops != NULL ) {
+                       rs->sr_err = ldap_set_option( lc->lc_ld,
+                               LDAP_OPT_X_SASL_SECPROPS,
+                               (void *)li->idassert_secprops );
 
                        if ( rs->sr_err != LDAP_OPT_SUCCESS ) {
                                send_ldap_result( op, rs );
-                               lc->lc_bound = 0;
+                               LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
                                goto done;
                        }
                }
-#endif
 
                defaults = lutil_sasl_defaults( lc->lc_ld,
                                li->idassert_sasl_mech.bv_val,
@@ -1047,37 +1048,38 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                                LDAP_SASL_QUIET, lutil_sasl_interact,
                                defaults );
 
-               lutil_sasl_freedefs( defaults );
-               if ( freeauthz ) {
-                       slap_sl_free( authzID.bv_val, op->o_tmpmemctx );
-               }
-
                rs->sr_err = slap_map_api2result( rs );
                if ( rs->sr_err != LDAP_SUCCESS ) {
-                       lc->lc_bound = 0;
+                       LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
                        send_ldap_result( op, rs );
 
                } else {
-                       lc->lc_bound = 1;
+                       LDAP_BACK_CONN_ISBOUND_SET( lc );
+               }
+
+               lutil_sasl_freedefs( defaults );
+               if ( freeauthz ) {
+                       slap_sl_free( authzID.bv_val, op->o_tmpmemctx );
                }
+
                goto done;
 #endif /* HAVE_CYRUS_SASL */
        }
 
        switch ( li->idassert_authmethod ) {
+       case LDAP_AUTH_NONE:
+               LDAP_BACK_CONN_ISBOUND_SET( lc );
+               goto done;
+
        case LDAP_AUTH_SIMPLE:
                rs->sr_err = ldap_sasl_bind( lc->lc_ld,
                                binddn.bv_val, LDAP_SASL_SIMPLE,
                                &bindcred, NULL, NULL, &msgid );
                break;
 
-       case LDAP_AUTH_NONE:
-               lc->lc_bound = 1;
-               goto done;
-
        default:
                /* unsupported! */
-               lc->lc_bound = 0;
+               LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
                rs->sr_err = LDAP_AUTH_METHOD_NOT_SUPPORTED;
                send_ldap_result( op, rs );
                goto done;
@@ -1085,10 +1087,10 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
 
        rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDERR );
        if ( rc == LDAP_SUCCESS ) {
-               lc->lc_bound = 1;
+               LDAP_BACK_CONN_ISBOUND_SET( lc );
        }
 done:;
-       return lc->lc_bound;
+       return LDAP_BACK_CONN_ISBOUND( lc );
 }
 
 /*
@@ -1180,7 +1182,8 @@ ldap_back_proxy_authz_ctrl(
 
        } else if ( li->idassert_authmethod == LDAP_AUTH_SASL ) {
                if ( ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ )
-                               /* && ( !BER_BVISNULL( &op->o_conn->c_ndn ) || lc->lc_bound ) */ )
+                               /* && ( !BER_BVISNULL( &op->o_conn->c_ndn )
+                                       || LDAP_BACK_CONN_ISBOUND( lc ) ) */ )
                {
                        /* already asserted in SASL via native authz */
                        /* NOTE: the test on lc->lc_bound is used to trap
index adc0b649ad67de3d04ad71f290b73b4cde0c04f7..7725986bf7d507985afff2f00c08527688d25ef1 100644 (file)
@@ -64,7 +64,7 @@ ldap_back_modify(
 
        isupdate = be_shadow_update( op );
        for ( i = 0, ml = op->oq_modify.rs_modlist; ml; ml = ml->sml_next ) {
-               if ( !isupdate && !!get_manageDIT( op ) && ml->sml_desc->ad_type->sat_no_user_mod  )
+               if ( !isupdate && !get_manageDIT( op ) && ml->sml_desc->ad_type->sat_no_user_mod  )
                {
                        continue;
                }
index 1a812f3d879bfcaad608d43c188d3487736452d1..80600e391c5dbf1d88142361aef226b918460a4f 100644 (file)
@@ -78,6 +78,8 @@ ldap_back_proxy_authz_ctrl_free(
 
 extern int chain_init( void );
 
+extern LDAP_REBIND_PROC                *ldap_back_rebind_f;
+
 LDAP_END_DECL
 
 #endif /* PROTO_LDAP_H */
index 213de648712559325c36dae08239d85ef45dd3db..45bc2e91528176b0d50b2b1efe8503bec151df06 100644 (file)
@@ -178,8 +178,7 @@ ldap_back_search(
                stoptime = op->o_time + op->ors_tlimit;
 
        } else {
-               tv.tv_sec = 0;
-               tv.tv_usec = 100000;
+               LDAP_BACK_TV_SET( &tv );
        }
 
        if ( op->ors_attrs ) {
@@ -264,8 +263,7 @@ fail:;
                }
 
                if ( rc == 0 ) {
-                       tv.tv_sec = 0;
-                       tv.tv_usec = 100000;
+                       LDAP_BACK_TV_SET( &tv );
                        ldap_pvt_thread_yield();
 
                        /* check time limit */
index 180441a44d0d9ea22847227dd65c80131e03c363..e097d0ae7a725f9338e4c85a94b10f1d0d4f4777 100644 (file)
@@ -48,14 +48,14 @@ ldap_back_conn_destroy(
        lc_curr.lc_conn = conn;
        lc_curr.lc_local_ndn = conn->c_ndn;
        
-       ldap_pvt_thread_mutex_trylock( &li->conn_mutex );
+       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 );
 
        if ( lc ) {
                Debug( LDAP_DEBUG_TRACE,
                        "=>ldap_back_conn_destroy: destroying conn %ld (refcnt=%u)\n",
-                       lc->lc_conn->c_connid, lc->lc_refcnt, 0 );
+                       LDAP_BACK_PCONN_ID( lc->lc_conn ), lc->lc_refcnt, 0 );
 
                assert( lc->lc_refcnt == 0 );
 
index 6119e0ad9c4999069c03bce205a5faf8c5eea9a4..ea1c96acc601ca038a13192cda749774e1bbae1b 100644 (file)
@@ -18,6 +18,7 @@
 #define _BACK_LDBM_H_
 
 #include "ldbm.h"
+#include "alock.h"
 
 LDAP_BEGIN_DECL
 
@@ -152,6 +153,7 @@ struct ldbminfo {
        int                     li_dbsyncwaitn;
        int                     li_dbsyncwaitinterval;
        int                     li_dbsyncwaitcount;
+       alock_info_t    li_alock_info;
 };
 
 LDAP_END_DECL
index 2e2090e28663f9c26acf83e0fd2613de9e7d07b3..9c26976697797e2953a99e213a14f50be2de00bd 100644 (file)
 int
 ldbm_back_db_close( Backend *be )
 {
+       struct ldbminfo *li = be->be_private;
+
        Debug( LDAP_DEBUG_TRACE, "ldbm backend syncing\n", 0, 0, 0 );
 
        ldbm_cache_flush_all( be );
        Debug( LDAP_DEBUG_TRACE, "ldbm backend done syncing\n", 0, 0, 0 );
 
-       cache_release_all( &((struct ldbminfo *) be->be_private)->li_cache );
+       cache_release_all( &li->li_cache );
+       if ( alock_close( &li->li_alock_info )) {
+               Debug( LDAP_DEBUG_ANY,
+                       "ldbm_back_db_close: alock_close failed\n", 0, 0, 0 );
+       }
 
        return 0;
 }
index b8a6831ce5d4609d521d475ee66cc5fd59e4893f..1ceb19bc5cd1516b9610cf9bb30e55ed6860c553 100644 (file)
@@ -195,6 +195,28 @@ ldbm_back_db_open(
 )
 {
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
+       int rc;
+
+       rc = alock_open( &li->li_alock_info, "slapd",
+               li->li_directory, ALOCK_UNIQUE );
+       if ( rc == ALOCK_BUSY ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "ldbm_back_db_open: database already in use\n",
+                       0, 0, 0 );
+               return -1;
+       } else if ( rc == ALOCK_RECOVER ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "ldbm_back_db_open: unclean shutdown detected;"
+                       " database may be inconsistent!\n",
+                       0, 0, 0 );
+               rc = alock_recover( &li->li_alock_info );
+       }
+       if ( rc != ALOCK_CLEAN ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "ldbm_back_db_open: alock package is unstable;"
+                       " database may be inconsistent!\n",
+                       0, 0, 0 );
+       }
        li->li_dbenv = ldbm_initialize_env( li->li_directory,
                li->li_dbcachesize, &li->li_envdirok );
 
index c8ef1e5446379e24ead8ebfcf2f54773354fcc16..5f4478d5daa8eb197d315f69fb1ea38343f0e1c3 100644 (file)
@@ -49,7 +49,6 @@ ldbm_back_modrdn(
        /* LDAP v2 supporting correct attribute handling. */
        LDAPRDN         new_rdn = NULL;
        LDAPRDN         old_rdn = NULL;
-       int             isroot = -1;
        int             rc_id = 0;
        ID              id = NOID;
        char            textbuf[SLAP_TEXT_BUFLEN];
@@ -159,79 +158,40 @@ ldbm_back_modrdn(
 
                        goto return_results;
                }
+       } else {
+               p = (Entry *)&slap_entry_root;
+       }
 
-               /* check parent for "children" acl */
-               if ( ! access_allowed( op, p, children, NULL,
-                               op->oq_modrdn.rs_newSup != NULL ?
-                                       ACL_WDEL : ACL_WRITE,
-                               NULL ) )
-               {
-                       Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
-                               0, 0 );
-
-                       send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
-                               NULL );
-                       goto return_results;
-               }
+       /* check parent for "children" acl */
+       if ( ! access_allowed( op, p, children, NULL,
+                       op->oq_modrdn.rs_newSup != NULL ?
+                               ACL_WDEL : ACL_WRITE,
+                       NULL ) )
+       {
+               Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
+                       0, 0 );
 
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: wr to children of entry %s OK\n",
-                      p_ndn.bv_val, 0, 0 );
+               send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
+                       NULL );
+               goto return_results;
+       }
 
-               if ( p_ndn.bv_val == slap_empty_bv.bv_val ) {
-                       p_dn = slap_empty_bv;
-               } else {
-                       dnParent( &e->e_name, &p_dn );
-               }
+       if ( BER_BVISEMPTY( &p_ndn ))
+               p = NULL;
 
-               Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: parent dn=%s\n",
-                      p_dn.bv_val, 0, 0 );
+       Debug( LDAP_DEBUG_TRACE,
+                  "ldbm_back_modrdn: wr to children of entry %s OK\n",
+                  p_ndn.bv_val, 0, 0 );
 
+       if ( p_ndn.bv_val == slap_empty_bv.bv_val ) {
+               p_dn = slap_empty_bv;
        } else {
-               /* no parent, must be root to modify rdn */
-               isroot = be_isroot( op );
-               if ( ! isroot ) {
-                       if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
-                               || be_shadow_update( op ) ) {
-                               int     can_access;
-                               p = (Entry *)&slap_entry_root;
-                               
-                               can_access = access_allowed( op, p,
-                                               children, NULL,
-                                               op->oq_modrdn.rs_newSup ?
-                                                       ACL_WDEL : ACL_WRITE,
-                                               NULL );
-                               p = NULL;
-                                                               
-                               /* check parent for "children" acl */
-                               if ( ! can_access ) {
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               "<=- ldbm_back_modrdn: no "
-                                               "access to parent\n", 0, 0, 0 );
-
-                                       send_ldap_error( op, rs,
-                                               LDAP_INSUFFICIENT_ACCESS,
-                                               NULL );
-                                       goto return_results;
-                               }
-
-                       } else {
-                               Debug( LDAP_DEBUG_TRACE,
-                                       "<=- ldbm_back_modrdn: no parent & "
-                                       "not root\n", 0, 0, 0);
-
-                               send_ldap_error( op, rs,
-                                       LDAP_INSUFFICIENT_ACCESS,
-                                       NULL );
-                               goto return_results;
-                       }
-               }
-
-               Debug( LDAP_DEBUG_TRACE,
-                      "ldbm_back_modrdn: no parent, locked root\n",
-                      0, 0, 0 );
+               dnParent( &e->e_name, &p_dn );
        }
 
+       Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: parent dn=%s\n",
+                  p_dn.bv_val, 0, 0 );
+
        new_parent_dn = &p_dn;  /* New Parent unless newSuperior given */
 
        if ( op->oq_modrdn.rs_newSup != NULL ) {
@@ -262,7 +222,7 @@ ldbm_back_modrdn(
                                    "ldbm_back_modrdn: newSup(ndn=%s) not here!\n",
                                    np_ndn->bv_val, 0, 0);
 
-                               send_ldap_error( op, rs, LDAP_OTHER,
+                               send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT,
                                        "newSuperior not found" );
                                goto return_results;
                        }
@@ -306,27 +266,20 @@ ldbm_back_modrdn(
                        }
 
                } else {
-
-                       /* no parent, must be root to modify newSuperior */
-                       if ( isroot == -1 ) {
-                               isroot = be_isroot( op );
-                       }
-
-                       if ( ! isroot ) {
-                               if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
-                                       || be_shadow_update( op ) ) {
-                                       int     can_access;
-                                       np = (Entry *)&slap_entry_root;
-                               
-                                       can_access = access_allowed( op, np,
-                                                       children, NULL, ACL_WADD, NULL );
-                                       np = NULL;
-                                                               
-                                       /* check parent for "children" acl */
-                                       if ( ! can_access ) {
-                                               Debug( LDAP_DEBUG_TRACE,
-                                                       "<=- ldbm_back_modrdn: no "
-                                                       "access to new superior\n", 0, 0, 0 );
+                       if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
+                               || be_shadow_update( op ) ) {
+                               int     can_access;
+                               np = (Entry *)&slap_entry_root;
+                       
+                               can_access = access_allowed( op, np,
+                                               children, NULL, ACL_WADD, NULL );
+                               np = NULL;
+                                                       
+                               /* check parent for "children" acl */
+                               if ( ! can_access ) {
+                                       Debug( LDAP_DEBUG_TRACE,
+                                               "<=- ldbm_back_modrdn: no "
+                                               "access to new superior\n", 0, 0, 0 );
 
                                                send_ldap_error( op, rs,
                                                        LDAP_INSUFFICIENT_ACCESS,
@@ -334,17 +287,16 @@ ldbm_back_modrdn(
                                                goto return_results;
                                        }
 
-                               } else {
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               "<=- ldbm_back_modrdn: \"\" "
-                                               "not allowed as new superior\n", 
-                                               0, 0, 0);
-
-                                       send_ldap_error( op, rs,
-                                               LDAP_INSUFFICIENT_ACCESS,
-                                               NULL );
-                                       goto return_results;
-                               }
+                       } else {
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "<=- ldbm_back_modrdn: \"\" "
+                                       "not allowed as new superior\n", 
+                                       0, 0, 0);
+
+                               send_ldap_error( op, rs,
+                                       LDAP_INSUFFICIENT_ACCESS,
+                                       NULL );
+                               goto return_results;
                        }
                }
 
index 46be0895a5b5fbe1c10fc8e08d985fbe4a4268c1..1292b4c858f6d802fb3169dfdeb77c1ca1b61a2a 100644 (file)
@@ -29,8 +29,7 @@ BUILD_MOD = @BUILD_META@
 mod_DEFS = -DSLAPD_IMPORT
 MOD_DEFS = $(@BUILD_META@_DEFS)
 
-shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA) \
-       $(LDAP_LIBLREWRITE_LA)
+shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA)
 NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS)
 UNIX_LINK_LIBS = $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS)
 
diff --git a/servers/slapd/back-meta/TODO b/servers/slapd/back-meta/TODO
deleted file mode 100644 (file)
index c362533..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-* Short term:
-
-- add missing functions (FIXED)
-
-- review per-target error handling
-
-- dn cache and cache exploitation to refine the candidate selection (?) (FIXED)
-
-- review the group stuff (also in back-ldap!) (FIXED)
-
-- review the attribute stuff (also in bacl-ldap)
-  note: this requires changing the acl stuff that checks "dnattr"
-  to call a backend specific function that determines what need 
-  be done to retrieve the "dnattr" attribute from an entry.
-
-- rework compare and bind to attempt to operate on all candidate entries
-  while checking at most one succeedes (FIXED, check bind)
-
-- clear previously bound targets when the bind is repeated (FIXED)
-
-- apply new logging to all the stuff (also in back-ldap)
-
-* Long term:
-
-- distributed entries
-
diff --git a/servers/slapd/back-meta/attribute.c b/servers/slapd/back-meta/attribute.c
deleted file mode 100644 (file)
index 7528e06..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1999-2005 The OpenLDAP Foundation.
- * Portions Copyright 2001-2003 Pierangelo Masarati.
- * Portions Copyright 1999-2003 Howard Chu.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was initially developed by the Howard Chu for inclusion
- * in OpenLDAP Software and subsequently enhanced by Pierangelo
- * Masarati.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "../back-ldap/back-ldap.h"
-#include "back-meta.h"
-
-
-/* return 0 IFF we can retrieve the attributes
- * of entry with e_ndn
- */
-
-/*
- * FIXME: I never testd this function; I know it compiles ... :)
- */
-int
-meta_back_attribute(
-               Backend                 *be,
-               Connection              *conn,
-               Operation               *op,
-               Entry                   *target,
-               struct berval           *ndn,
-               AttributeDescription    *entry_at,
-               BerVarray                       *vals
-)
-{
-       struct metainfo *li = ( struct metainfo * )be->be_private;    
-       int rc = 1, i, j, count, is_oc, candidate;
-       Attribute *attr;
-       BerVarray abv, v;
-       char **vs; 
-       struct berval   mapped;
-       LDAPMessage     *result, *e;
-       char *gattr[ 2 ];
-       LDAP *ld;
-
-       *vals = NULL;
-       if ( target != NULL && dn_match( &target->e_nname, ndn ) ) {
-               /* we already have a copy of the entry */
-               /* attribute and objectclass mapping has already been done */
-               attr = attr_find( target->e_attrs, entry_at );
-               if ( attr == NULL ) {
-                       return 1;
-               }
-
-               for ( count = 0; attr->a_vals[ count ].bv_val != NULL; count++ )
-                       ;
-               v = ( BerVarray )ch_calloc( ( count + 1 ), sizeof( struct berval ) );
-               if ( v == NULL ) {
-                       return 1;
-               }
-
-               for ( j = 0, abv = attr->a_vals; --count >= 0; abv++ ) {
-                       if ( abv->bv_len > 0 ) {
-                               ber_dupbv( &v[ j ], abv );
-                               if ( v[ j ].bv_val == NULL ) {
-                                       break;
-                               }
-                       }
-               }
-               v[ j ].bv_val = NULL;
-               *vals = v;
-
-               return 0;
-       } /* else */
-
-       candidate = meta_back_select_unique_candidate( li, ndn );
-       if ( candidate == META_TARGET_NONE ) {
-               return 1;
-       }
-
-       ldap_back_map( &li->targets[ candidate ]->at_map,
-                       &entry_at->ad_cname, &mapped, BACKLDAP_MAP );
-       if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' )
-               return 1;
-
-       rc =  ldap_initialize( &ld, li->targets[ candidate ]->uri );
-       if ( rc != LDAP_SUCCESS ) {
-               return 1;
-       }
-
-       rc = ldap_bind_s( ld, li->targets[ candidate ]->binddn.bv_val,
-                       li->targets[ candidate ]->bindpw.bv_val, LDAP_AUTH_SIMPLE );
-       if ( rc != LDAP_SUCCESS) {
-               return 1;
-       }
-
-       gattr[ 0 ] = mapped.bv_val;
-       gattr[ 1 ] = NULL;
-       if ( ldap_search_ext_s( ld, ndn->bv_val, LDAP_SCOPE_BASE, 
-                               "(objectClass=*)",
-                               gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
-                               LDAP_NO_LIMIT, &result) == LDAP_SUCCESS) {
-               if ( ( e = ldap_first_entry( ld, result ) ) != NULL ) {
-                       vs = ldap_get_values( ld, e, mapped.bv_val );
-                       if ( vs != NULL ) {
-                               for ( count = 0; vs[ count ] != NULL;
-                                               count++ ) { }
-                               v = ( BerVarray )ch_calloc( ( count + 1 ),
-                                               sizeof( struct berval ) );
-                               if ( v == NULL ) {
-                                       ldap_value_free( vs );
-                               } else {
-                                       is_oc = ( strcasecmp( "objectclass", mapped.bv_val ) == 0 );
-                                       for ( i = 0, j = 0; i < count; i++ ) {
-                                               ber_str2bv( vs[ i ], 0, 0, &v[ j ] );
-                                               if ( !is_oc ) {
-                                                       if ( v[ j ].bv_val == NULL ) {
-                                                               ch_free( vs[ i ] );
-                                                       } else {
-                                                               j++;
-                                                       }
-                                               } else {
-                                                       ldap_back_map( &li->targets[ candidate ]->oc_map, &v[ j ], &mapped, BACKLDAP_REMAP );
-                                                       if ( mapped.bv_val && mapped.bv_val[0] != '\0' ) {
-                                                               ber_dupbv( &v[ j ], &mapped );
-                                                               if ( v[ j ].bv_val ) {
-                                                                       j++;
-                                                               }
-                                                       }
-                                                       ch_free( vs[ i ] );
-                                               }
-                                       }
-                                       v[ j ].bv_val = NULL;
-                                       *vals = v;
-                                       rc = 0;
-                                       ch_free( vs );
-                               }
-                       }
-               }
-               ldap_msgfree( result );
-       }
-       ldap_unbind( ld );
-
-       return(rc);
-}
-
index df9bfdf0237bfbad3791b69c1b225bfb464d0e0f..5a7f92e1c2dca5046f9eb2ea5b250b960f2b8755 100644 (file)
@@ -166,10 +166,16 @@ typedef struct metasingleconn_t {
        LDAP                    *msc_ld;
        struct berval           msc_bound_ndn;
        struct berval           msc_cred;
+       unsigned                msc_mscflags;
+       /* NOTE: lc_lcflags is redefined to msc_mscflags to reuse the macros
+        * defined for back-ldap */
+#define        lc_lcflags              msc_mscflags
+#if 0
        int                     msc_bound;
 #define META_UNBOUND           0
 #define META_BOUND             1
 #define META_ANONYMOUS         2
+#endif
 
        struct metainfo_t       *msc_info;
 } metasingleconn_t;
@@ -179,11 +185,16 @@ typedef struct metaconn_t {
        ldap_pvt_thread_mutex_t mc_mutex;
        unsigned                mc_refcnt;
        
+       struct berval           mc_local_ndn;
+       /* NOTE: msc_mscflags is used to recycle the #define
+        * in metasingleconn_t */
+       unsigned                msc_mscflags;
+
        /*
         * means that the connection is bound; 
         * of course only one target actually is ...
         */
-       int                     mc_auth_target;
+       int                     mc_authz_target;
 #define META_BOUND_NONE                (-1)
 #define META_BOUND_ALL         (-2)
        /* supersedes the connection stuff */
@@ -258,10 +269,14 @@ typedef struct metainfo_t {
 
        unsigned                flags;
 /* uses flags as defined in <back-ldap/back-ldap.h> */
-#define        META_BACK_F_ONERR_STOP  0x00010000U
+#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_CONTINUE(mi)    ( !META_BACK_ONERR_CONTINUE( (mi) ) )
 
+#define META_BACK_DEFER_ROOTDN_BIND(mi)        ( (mi)->flags & META_BACK_F_DEFER_ROOTDN_BIND )
+
        int                     mi_version;
        time_t                  mi_timeout[ META_OP_LAST ];
 } metainfo_t;
@@ -404,6 +419,8 @@ meta_dncache_delete_entry(
 extern void
 meta_dncache_free( void *entry );
 
+extern LDAP_REBIND_PROC                *meta_back_rebind_f;
+
 LDAP_END_DECL
 
 #endif /* SLAPD_META_H */
index 424210da025ed2ea8c56730fe9bcfc880a977adc..17dab2f39712ceb34df2f693cf95ef7b93b62f0e 100644 (file)
 #include "../back-ldap/back-ldap.h"
 #include "back-meta.h"
 
-static LDAP_REBIND_PROC        meta_back_rebind;
+static LDAP_REBIND_PROC        meta_back_default_rebind;
+
+/*
+ * a module could register a replacement for this function
+ */
+LDAP_REBIND_PROC       *meta_back_rebind_f = meta_back_default_rebind;
 
 static int
 meta_back_single_bind(
@@ -50,18 +55,36 @@ meta_back_bind( Operation *op, SlapReply *rs )
        metaconn_t      *mc = NULL;
 
        int             rc = LDAP_OTHER,
-                       i, gotit = 0, isroot = 0;
+                       i,
+                       gotit = 0,
+                       isroot = 0;
 
        SlapReply       *candidates = meta_back_candidates_get( op );
 
        rs->sr_err = LDAP_SUCCESS;
 
-       Debug( LDAP_DEBUG_ARGS, "meta_back_bind: dn: %s.\n%s%s",
-                       op->o_req_dn.bv_val, "", "" );
+       Debug( LDAP_DEBUG_ARGS, "%s meta_back_bind: dn=\"%s\".\n",
+               op->o_log_prefix, op->o_req_dn.bv_val, 0 );
+
+       /* the test on the bind method should be superfluous */
+       if ( op->orb_method == LDAP_AUTH_SIMPLE
+               && be_isroot_dn( op->o_bd, &op->o_req_ndn ) )
+       {
+               if ( !be_isroot_pw( op ) ) {
+                       rs->sr_err = LDAP_INVALID_CREDENTIALS;
+                       rs->sr_text = NULL;
+                       send_ldap_result( op, rs );
+                       return rs->sr_err;
+               }
+
+               if ( META_BACK_DEFER_ROOTDN_BIND( mi ) ) {
+                       rs->sr_err = LDAP_SUCCESS;
+                       rs->sr_text = NULL;
+                       send_ldap_result( op, rs );
+                       return rs->sr_err;
+               }
 
-       if ( op->orb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op ) ) {
                isroot = 1;
-               ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ) );
        }
 
        /* we need meta_back_getconn() not send result even on error,
@@ -69,11 +92,18 @@ meta_back_bind( Operation *op, SlapReply *rs )
         * invalidCredentials */
        mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_DONTSEND );
        if ( !mc ) {
+               char    buf[ SLAP_TEXT_BUFLEN ];
+
+               snprintf( buf, sizeof( buf ),
+                       "meta_back_bind: no target "
+                       "for dn \"%s\" (%d%s%s).",
+                       op->o_req_dn.bv_val, rs->sr_err,
+                       rs->sr_text ? ". " : "",
+                       rs->sr_text ? rs->sr_text : "" );
                Debug( LDAP_DEBUG_ANY,
-                               "meta_back_bind: no target "
-                               "for dn \"%s\" (%d: %s).\n",
-                               op->o_req_dn.bv_val, rs->sr_err,
-                               rs->sr_text ? rs->sr_text : "" );
+                       "%s %s\n",
+                       op->o_log_prefix, buf, 0 );
+
                /* FIXME: there might be cases where we don't want
                 * to map the error onto invalidCredentials */
                switch ( rs->sr_err ) {
@@ -90,7 +120,7 @@ meta_back_bind( Operation *op, SlapReply *rs )
        /*
         * Each target is scanned ...
         */
-       mc->mc_auth_target = META_BOUND_NONE;
+       mc->mc_authz_target = META_BOUND_NONE;
        for ( i = 0; i < mi->mi_ntargets; i++ ) {
                int             lerr;
                Operation       op2 = *op;
@@ -103,6 +133,9 @@ meta_back_bind( Operation *op, SlapReply *rs )
                }
 
                if ( gotit == 0 ) {
+                       /* set rc to LDAP_SUCCESS only if at least
+                        * one candidate has been tried */
+                       rc = LDAP_SUCCESS;
                        gotit = 1;
 
                } else if ( isroot == 0 ) {
@@ -111,13 +144,35 @@ meta_back_bind( Operation *op, SlapReply *rs )
                         * ONE CANDIDATE ONLY!
                         */
                        Debug( LDAP_DEBUG_ANY,
-                                       "==>meta_back_bind: more than one"
-                                       " candidate is trying to bind...\n",
-                                       0, 0, 0 );
+                               "### %s meta_back_bind: more than one"
+                               " candidate is trying to bind...\n",
+                               op->o_log_prefix, 0, 0 );
                }
 
-               if ( isroot && !BER_BVISNULL( &mi->mi_targets[ i ].mt_pseudorootdn ) )
-               {
+               if ( isroot ) {
+                       if ( BER_BVISNULL( &mi->mi_targets[ i ].mt_pseudorootdn ) )
+                       {
+                               metasingleconn_t        *msc = &mc->mc_conns[ i ];
+
+                               /* skip the target if no pseudorootdn is provided */
+                               if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
+                                       ch_free( msc->msc_bound_ndn.bv_val );
+                                       BER_BVZERO( &msc->msc_bound_ndn );
+                               }
+
+                               if ( LDAP_BACK_SAVECRED( mi ) &&
+                                       !BER_BVISNULL( &msc->msc_cred ) )
+                               {
+                                       /* destroy sensitive data */
+                                       memset( msc->msc_cred.bv_val, 0,
+                                               msc->msc_cred.bv_len );
+                                       ch_free( msc->msc_cred.bv_val );
+                                       BER_BVZERO( &msc->msc_cred );
+                               }
+
+                               continue;
+                       }
+
                        op2.o_req_dn = mi->mi_targets[ i ].mt_pseudorootdn;
                        op2.o_req_ndn = mi->mi_targets[ i ].mt_pseudorootdn;
                        op2.orb_cred = mi->mi_targets[ i ].mt_pseudorootpw;
@@ -133,22 +188,60 @@ meta_back_bind( Operation *op, SlapReply *rs )
                                rc = rs->sr_err;
                                break;
                        }
-                               
-               } else {
-                       rc = LDAP_SUCCESS;
                }
        }
 
-       if ( isroot ) {
-               mc->mc_auth_target = META_BOUND_ALL;
+       /* must re-insert if local DN changed as result of bind */
+       if ( rc == LDAP_SUCCESS ) {
+               if ( isroot ) {
+                       mc->mc_authz_target = META_BOUND_ALL;
+                       ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ) );
+               }
+
+               if ( !dn_match( &op->o_req_ndn, &mc->mc_local_ndn ) ) {
+                       int             lerr;
+
+                       /* wait for all other ops to release the connection */
+retry_lock:;
+                       ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+                       if ( mc->mc_refcnt > 1 ) {
+                               ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+                               ldap_pvt_thread_yield();
+                               goto retry_lock;
+                       }
+
+                       assert( mc->mc_refcnt == 1 );
+                       mc = avl_delete( &mi->mi_conntree, (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,
+                               meta_back_conn_cmp, meta_back_conn_dup );
+                       ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+                       if ( lerr == -1 ) {
+                               for ( i = 0; i < mi->mi_ntargets; ++i ) {
+                                       if ( mc->mc_conns[ i ].msc_ld != NULL ) {
+                                               meta_clear_one_candidate( &mc->mc_conns[ i ] );
+                                       }
+                               }
+
+                               /* we can do this because mc_refcnt == 1 */
+                               mc->mc_refcnt = 0;
+                               meta_back_conn_free( mc );
+                               mc = NULL;
+                       }
+               }
        }
 
-       meta_back_release_conn( op, mc );
+       if ( mc != NULL ) {
+               meta_back_release_conn( op, mc );
+       }
 
        /*
         * rc is LDAP_SUCCESS if at least one bind succeeded,
         * err is the last error that occurred during a bind;
-        * if at least (and at most?) one bind succeedes, fine.
+        * if at least (and at most?) one bind succeeds, fine.
         */
        if ( rc != LDAP_SUCCESS ) {
                
@@ -162,11 +255,12 @@ meta_back_bind( Operation *op, SlapReply *rs )
                 */
                if ( rs->sr_err == LDAP_SUCCESS && gotit == 0 ) {
                        rs->sr_err = LDAP_INVALID_CREDENTIALS;
+               } else {
+                       rs->sr_err = slap_map_api2result( rs );
                }
-
-               rs->sr_err = slap_map_api2result( rs );
                send_ldap_result( op, rs );
                return rs->sr_err;
+
        }
 
        return LDAP_SUCCESS;
@@ -191,11 +285,24 @@ meta_back_single_bind(
        metasingleconn_t        *msc = &mc->mc_conns[ candidate ];
        int                     msgid,
                                rebinding = 0;
+
        
+       if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
+               ch_free( msc->msc_bound_ndn.bv_val );
+               BER_BVZERO( &msc->msc_bound_ndn );
+       }
+
+       if ( LDAP_BACK_SAVECRED( mi ) && !BER_BVISNULL( &msc->msc_cred ) ) {
+               /* destroy sensitive data */
+               memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
+               ch_free( msc->msc_cred.bv_val );
+               BER_BVZERO( &msc->msc_cred );
+       }
+
        /*
         * Rewrite the bind dn if needed
         */
-       dc.target = &mi->mi_targets[ candidate ];
+       dc.target = mt;
        dc.conn = op->o_conn;
        dc.rs = rs;
        dc.ctx = "bindDN";
@@ -208,7 +315,7 @@ meta_back_single_bind(
        /* FIXME: this fixes the bind problem right now; we need
         * to use the asynchronous version to get the "matched"
         * and more in case of failure ... */
-       /* FIXME: should be check if at least some of the op->o_ctrls
+       /* FIXME: should we check if at least some of the op->o_ctrls
         * can/should be passed? */
 rebind:;
        rs->sr_err = ldap_sasl_bind( msc->msc_ld, mdn.bv_val,
@@ -216,10 +323,12 @@ rebind:;
                        op->o_ctrls, NULL, &msgid );
        if ( rs->sr_err == LDAP_SUCCESS ) {
                LDAPMessage     *res;
-               struct timeval  tv = { 0, 100000 };
+               struct timeval  tv;
                int             rc;
                int             nretries = mt->mt_nretries;
 
+               LDAP_BACK_TV_SET( &tv );
+
                /*
                 * handle response!!!
                 */
@@ -239,8 +348,7 @@ retry:;
                                if ( nretries > 0 ) {
                                        nretries--;
                                }
-                               tv.tv_sec = 0;
-                               tv.tv_usec = 100000;
+                               LDAP_BACK_TV_SET( &tv );
                                goto retry;
                        }
                        rs->sr_err = LDAP_BUSY;
@@ -276,7 +384,7 @@ retry:;
                                if ( mc->mc_refcnt == 1 ) {
                                        ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
                                        msc->msc_ld = NULL;
-                                       msc->msc_bound = 0;
+                                       LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
 
                                        ( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
 
@@ -318,12 +426,12 @@ retry:;
        }
 
        ber_bvreplace( &msc->msc_bound_ndn, &op->o_req_dn );
-       msc->msc_bound = META_BOUND;
-       mc->mc_auth_target = candidate;
+       LDAP_BACK_CONN_ISBOUND_SET( msc );
+       mc->mc_authz_target = candidate;
 
        if ( LDAP_BACK_SAVECRED( mi ) ) {
                ber_bvreplace( &msc->msc_cred, &op->orb_cred );
-               ldap_set_rebind_proc( msc->msc_ld, meta_back_rebind, msc );
+               ldap_set_rebind_proc( msc->msc_ld, meta_back_rebind_f, msc );
        }
 
        if ( mi->mi_cache.ttl != META_DNCACHE_DISABLED
@@ -358,11 +466,13 @@ meta_back_single_dobind(
        metatarget_t            *mt = &mi->mi_targets[ candidate ];
        metasingleconn_t        *msc = &mc->mc_conns[ candidate ];
        int                     rc;
-       struct berval           cred = BER_BVC( "" );
+       static struct berval    cred = BER_BVC( "" );
        int                     msgid,
                                rebinding = 0,
                                save_nretries = nretries;
 
+       assert( !LDAP_BACK_CONN_ISBOUND( msc ) );
+
        /*
         * Otherwise an anonymous bind is performed
         * (note: if the target was already bound, the anonymous
@@ -373,7 +483,7 @@ meta_back_single_dobind(
                BER_BVZERO( &msc->msc_bound_ndn );
        }
                
-       if ( !BER_BVISNULL( &msc->msc_cred ) ) {
+       if ( LDAP_BACK_SAVECRED( mi ) && !BER_BVISNULL( &msc->msc_cred ) ) {
                /* destroy sensitive data */
                memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
                ber_memfree( msc->msc_cred.bv_val );
@@ -387,7 +497,9 @@ rebind:;
                        NULL, NULL, &msgid );
        if ( rc == LDAP_SUCCESS ) {
                LDAPMessage     *res;
-               struct timeval  tv = { 0, 100000 };
+               struct timeval  tv;
+
+               LDAP_BACK_TV_SET( &tv );
 
                /*
                 * handle response!!!
@@ -408,8 +520,7 @@ retry:;
                                if ( nretries > 0 ) {
                                        nretries--;
                                }
-                               tv.tv_sec = 0;
-                               tv.tv_usec = 100000;
+                               LDAP_BACK_TV_SET( &tv );
                                goto retry;
                        }
 
@@ -449,7 +560,7 @@ retry:;
                                if ( mc->mc_refcnt == 1 ) {
                                        ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
                                        msc->msc_ld = NULL;
-                                       msc->msc_bound = 0;
+                                       LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
 
                                        ( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
 
@@ -524,7 +635,8 @@ meta_back_dobind(
 
        Debug( LDAP_DEBUG_TRACE,
                "%s meta_back_dobind: conn=%ld%s\n",
-               op->o_log_prefix, mc->mc_conn->c_connid,
+               op->o_log_prefix,
+               LDAP_BACK_PCONN_ID( mc->mc_conn ),
                isroot ? " (isroot)" : "" );
 
        ldap_pvt_thread_mutex_lock( &mc->mc_mutex );
@@ -532,7 +644,7 @@ meta_back_dobind(
        /*
         * all the targets are bound as pseudoroot
         */
-       if ( mc->mc_auth_target == META_BOUND_ALL ) {
+       if ( mc->mc_authz_target == META_BOUND_ALL ) {
                bound = 1;
                goto done;
        }
@@ -541,6 +653,7 @@ meta_back_dobind(
                metatarget_t            *mt = &mi->mi_targets[ i ];
                metasingleconn_t        *msc = &mc->mc_conns[ i ];
                int                     rc;
+               char                    *rootdn = NULL;
 
                /*
                 * Not a candidate
@@ -554,12 +667,8 @@ meta_back_dobind(
                /*
                 * If the target is already bound it is skipped
                 */
-               if ( msc->msc_bound == META_BOUND && mc->mc_auth_target == i ) {
+               if ( LDAP_BACK_CONN_ISBOUND( msc ) || LDAP_BACK_CONN_ISANON( msc ) ) {
                        ++bound;
-
-                       Debug( LDAP_DEBUG_TRACE, "%s meta_back_dobind[%d]: "
-                                       "authcTarget\n",
-                                       op->o_log_prefix, i, 0 );
                        continue;
                }
 
@@ -573,6 +682,8 @@ meta_back_dobind(
                        op2.orb_cred = mi->mi_targets[ i ].mt_pseudorootpw;
                        op2.orb_method = LDAP_AUTH_SIMPLE;
 
+                       rootdn = mi->mi_targets[ i ].mt_pseudorootdn.bv_val;
+
                        rc = meta_back_single_bind( &op2, rs, mc, i );
 
                } else {
@@ -581,9 +692,14 @@ meta_back_dobind(
                }
 
                if ( rc != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_ANY, "%s meta_back_dobind[%d]: "
-                                       "(anonymous) err=%d\n",
-                                       op->o_log_prefix, i, rc );
+                       char            buf[ SLAP_TEXT_BUFLEN ];
+
+                       snprintf( buf, sizeof( buf ),
+                               "meta_back_dobind[%d]: (%s) err=%d.",
+                               i, rootdn ? rootdn : "anonymous", rc );
+                       Debug( LDAP_DEBUG_ANY,
+                               "%s %s\n",
+                               op->o_log_prefix, buf, 0 );
 
                        /*
                         * null cred bind should always succeed
@@ -601,11 +717,17 @@ meta_back_dobind(
                        continue;
                } /* else */
                
-               Debug( LDAP_DEBUG_TRACE, "%s meta_back_dobind[%d]: "
-                               "(anonymous)\n",
-                               op->o_log_prefix, i, 0 );
-
-               msc->msc_bound = META_ANONYMOUS;
+               Debug( LDAP_DEBUG_TRACE,
+                       "%s meta_back_dobind[%d]: "
+                       "(%s)\n",
+                       op->o_log_prefix, i,
+                       rootdn ? rootdn : "anonymous" );
+
+               if ( rootdn ) {
+                       LDAP_BACK_CONN_ISBOUND_SET( msc );
+               } else {
+                       LDAP_BACK_CONN_ISANON_SET( msc );
+               }
                ++bound;
        }
 
@@ -614,7 +736,7 @@ done:;
 
        Debug( LDAP_DEBUG_TRACE,
                "%s meta_back_dobind: conn=%ld bound=%d\n",
-               op->o_log_prefix, mc->mc_conn->c_connid, bound );
+               op->o_log_prefix, LDAP_BACK_PCONN_ID( mc->mc_conn ), bound );
 
        if ( bound == 0 ) {
                meta_back_release_conn( op, mc );
@@ -631,13 +753,13 @@ done:;
 }
 
 /*
- * meta_back_rebind
+ * meta_back_default_rebind
  *
  * This is a callback used for chasing referrals using the same
  * credentials as the original user on this session.
  */
 static int 
-meta_back_rebind(
+meta_back_default_rebind(
        LDAP                    *ld,
        LDAP_CONST char         *url,
        ber_tag_t               request,
index aa8c7628df6bdf65931d52121a10919903ff9406..1254a26184ea52ec93a5dea7de2c2524309dc2d7 100644 (file)
@@ -188,6 +188,7 @@ meta_clear_one_candidate(
        }
 
        if ( !BER_BVISNULL( &msc->msc_cred ) ) {
+               memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
                ber_memfree( msc->msc_cred.bv_val );
                BER_BVZERO( &msc->msc_cred );
        }
index 82d407fe734adb7ce4bd330bf5933831d69d0e66..65fdde05f01c50c9a084b29dacd6ba974f750884 100644 (file)
@@ -176,10 +176,9 @@ meta_back_compare( Operation *op, SlapReply *rs )
                        metasingleconn_t        *msc = &mc->mc_conns[ i ];
                        int                     lrc;
                        LDAPMessage             *res = NULL;
-                       struct timeval          tv = { 0 };
+                       struct timeval          tv;
 
-                       tv.tv_sec = 0;
-                       tv.tv_usec = 100000;    /* 0.1 s */
+                       LDAP_BACK_TV_SET( &tv );
 
                        if ( msgid[ i ] == -1 ) {
                                continue;
index 143bbe573a56a3df32efea628328639279d382b8..1c596de1339fd83ba0e2282506664b80300cfa1c 100644 (file)
@@ -69,6 +69,21 @@ new_target(
        return 0;
 }
 
+static int
+check_true_false( char *str )
+{
+       if ( strcasecmp( str, "true" ) == 0 || strcasecmp( str, "yes" ) == 0 ) {
+               return 1;
+       }
+
+       if ( strcasecmp( str, "false" ) == 0 || strcasecmp( str, "no" ) == 0 ) {
+               return 0;
+       }
+
+       return -1;
+}
+
+
 int
 meta_back_db_config(
                BackendDB       *be,
@@ -378,20 +393,23 @@ meta_back_db_config(
 
                if ( argc == 1 ) {
                        fprintf( stderr,
-       "%s: line %d: deprecated use of \"rebind-as-user {NO|yes}\" with no arguments.\n",
+       "%s: line %d: deprecated use of \"rebind-as-user {FALSE|true}\" with no arguments.\n",
                            fname, lineno );
                        mi->flags |= LDAP_BACK_F_SAVECRED;
 
                } else {
-                       if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
+                       switch ( check_true_false( argv[ 1 ] ) ) {
+                       case 0:
                                mi->flags &= ~LDAP_BACK_F_SAVECRED;
+                               break;
 
-                       } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
+                       case 1:
                                mi->flags |= LDAP_BACK_F_SAVECRED;
+                               break;
 
-                       } else {
+                       default:
                                fprintf( stderr,
-       "%s: line %d: \"rebind-as-user {NO|yes}\" unknown argument \"%s\".\n",
+       "%s: line %d: \"rebind-as-user {FALSE|true}\" unknown argument \"%s\".\n",
                                    fname, lineno, argv[ 1 ] );
                                return 1;
                        }
@@ -404,21 +422,24 @@ meta_back_db_config(
 
                if ( argc != 2 ) {
                        fprintf( stderr,
-       "%s: line %d: \"chase-referrals\" needs 1 argument.\n",
+       "%s: line %d: \"chase-referrals {TRUE|false}\" 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 ) {
+               switch ( check_true_false( argv[ 1 ] ) ) {
+               case 1:
                        *flagsp |= LDAP_BACK_F_CHASE_REFERRALS;
+                       break;
 
-               } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
+               case 0:
                        *flagsp &= ~LDAP_BACK_F_CHASE_REFERRALS;
+                       break;
 
-               } else {
+               default:
                        fprintf( stderr,
-               "%s: line %d: \"chase-referrals {YES|no}\": unknown argument \"%s\".\n",
+               "%s: line %d: \"chase-referrals {TRUE|false}\": unknown argument \"%s\".\n",
                                        fname, lineno, argv[ 1 ] );
                        return( 1 );
                }
@@ -467,25 +488,31 @@ meta_back_db_config(
 
                if ( argc != 2 ) {
                        fprintf( stderr,
-               "%s: line %d: \"t-f-support {NO|yes|discover}\" needs 1 argument.\n",
+               "%s: line %d: \"t-f-support {FALSE|true|discover}\" needs 1 argument.\n",
                                        fname, lineno );
                        return( 1 );
                }
 
-               if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
+               switch ( check_true_false( argv[ 1 ] ) ) {
+               case 0:
                        *flagsp &= ~(LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER);
+                       break;
 
-               } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
+               case 1:
                        *flagsp |= LDAP_BACK_F_SUPPORT_T_F;
+                       break;
 
-               } else if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
-                       *flagsp |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
+               default:
+                       if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
+                               *flagsp |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
 
-               } else {
-                       fprintf( stderr,
+                       } else {
+                               fprintf( stderr,
        "%s: line %d: unknown value \"%s\" for \"t-f-support {no|yes|discover}\".\n",
-                               fname, lineno, argv[ 1 ] );
-                       return 1;
+                                       fname, lineno, argv[ 1 ] );
+                               return 1;
+                       }
+                       break;
                }
 
        /* onerr? */
@@ -510,6 +537,31 @@ meta_back_db_config(
                        return 1;
                }
 
+       /* bind-defer? */
+       } else if ( strcasecmp( argv[ 0 ], "pseudoroot-bind-defer" ) == 0 ) {
+               if ( argc != 2 ) {
+                       fprintf( stderr,
+       "%s: line %d: \"pseudoroot-bind-defer {FALSE|true}\" takes 1 argument\n",
+                           fname, lineno );
+                       return( 1 );
+               }
+
+               switch ( check_true_false( argv[ 1 ] ) ) {
+               case 0:
+                       mi->flags &= ~META_BACK_F_DEFER_ROOTDN_BIND;
+                       break;
+
+               case 1:
+                       mi->flags |= META_BACK_F_DEFER_ROOTDN_BIND;
+                       break;
+
+               default:
+                       fprintf( stderr,
+       "%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;
                time_t  *tv = mi->mi_ntargets ?
index a0ae2801249fe69e0b607e747dff707e43900006..0c8d140166ad33eba1676524c58b451fff3a7607 100644 (file)
@@ -52,7 +52,17 @@ meta_back_conn_cmp(
 {
        metaconn_t      *mc1 = ( metaconn_t * )c1;
         metaconn_t     *mc2 = ( metaconn_t * )c2;
+       int             rc;
        
+       /* If local DNs don't match, it is definitely not a match */
+       rc = ber_bvcmp( &mc1->mc_local_ndn, &mc2->mc_local_ndn );
+       if ( rc ) {
+               return rc;
+       }
+
+       /* For shared sessions, conn is NULL. Only explicitly
+        * bound sessions will have non-NULL conn.
+        */
        return SLAP_PTRCMP( mc1->mc_conn, mc2->mc_conn );
 }
 
@@ -70,7 +80,14 @@ meta_back_conn_dup(
        metaconn_t      *mc1 = ( metaconn_t * )c1;
        metaconn_t      *mc2 = ( metaconn_t * )c2;
 
-       return( ( mc1->mc_conn == mc2->mc_conn ) ? -1 : 0 );
+       /* Cannot have more than one shared session with same DN */
+       if ( dn_match( &mc1->mc_local_ndn, &mc2->mc_local_ndn ) &&
+                               mc1->mc_conn == mc2->mc_conn )
+       {
+               return -1;
+       }
+               
+       return 0;
 }
 
 /*
@@ -80,7 +97,8 @@ meta_back_conn_dup(
 static void
 ravl_print( Avlnode *root, int depth )
 {
-       int     i;
+       int             i;
+       metaconn_t      *mc = (metaconn_t *)root->avl_data;
        
        if ( root == 0 ) {
                return;
@@ -92,7 +110,11 @@ ravl_print( Avlnode *root, int depth )
                printf( "    " );
        }
 
-       printf( "c(%d) %d\n", ( ( metaconn_t * )root->avl_data )->mc_conn->c_connid, root->avl_bf );
+       printf( "c(%d%s%s) %d\n",
+               LDAP_BACK_PCONN_ID( mc->mc_conn ),
+               BER_BVISNULL( &mc->mc_local_ndn ) ? "" : ": ",
+               BER_BVISNULL( &mc->mc_local_ndn ) ? "" : mc->mc_local_ndn.bv_val,
+               root->avl_bf );
        
        ravl_print( root->avl_left, depth + 1 );
 }
@@ -141,11 +163,13 @@ metaconn_alloc(
                mc->mc_conns[ i ].msc_ld = NULL;
                BER_BVZERO( &mc->mc_conns[ i ].msc_bound_ndn );
                BER_BVZERO( &mc->mc_conns[ i ].msc_cred );
-               mc->mc_conns[ i ].msc_bound = META_UNBOUND;
+               LDAP_BACK_CONN_ISBOUND_CLEAR( &mc->mc_conns[ i ] );
                mc->mc_conns[ i ].msc_info = mi;
        }
 
-       mc->mc_auth_target = META_BOUND_NONE;
+       BER_BVZERO( &mc->mc_local_ndn );
+       mc->msc_mscflags = 0;
+       mc->mc_authz_target = META_BOUND_NONE;
        ldap_pvt_thread_mutex_init( &mc->mc_mutex );
        mc->mc_refcnt = 1;
 
@@ -165,6 +189,10 @@ meta_back_conn_free(
        assert( mc != NULL );
        assert( mc->mc_refcnt == 0 );
 
+       if ( !BER_BVISNULL( &mc->mc_local_ndn ) ) {
+               free( mc->mc_local_ndn.bv_val );
+       }
+
        ldap_pvt_thread_mutex_destroy( &mc->mc_mutex );
        free( mc );
 }
@@ -247,7 +275,9 @@ meta_back_init_one_conn(
                if ( rs->sr_err == LDAP_SUCCESS ) {
                        LDAPMessage     *res = NULL;
                        int             rc, nretries = mt->mt_nretries;
-                       struct timeval  tv = { 0, 0 };
+                       struct timeval  tv;
+
+                       LDAP_BACK_TV_SET( &tv );
 
 retry:;
                        rc = ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res );
@@ -259,8 +289,7 @@ retry:;
                                        if ( nretries > 0 ) {
                                                nretries--;
                                        }
-                                       tv.tv_sec = 0;
-                                       tv.tv_usec = 100000;
+                                       LDAP_BACK_TV_SET( &tv );
                                        goto retry;
                                }
                                rs->sr_err = LDAP_OTHER;
@@ -364,7 +393,7 @@ retry:;
                ber_str2bv( "", 0, 1, &msc->msc_bound_ndn );
        }
 
-       msc->msc_bound = META_UNBOUND;
+       LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
 
 error_return:;
        if ( rs->sr_err == LDAP_SUCCESS ) {
@@ -416,7 +445,7 @@ retry_lock:;
 
                ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
                msc->msc_ld = NULL;
-               msc->msc_bound = 0;
+               LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
 
                ( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
 
@@ -446,7 +475,7 @@ meta_back_conn_cb( Operation *op, SlapReply *rs )
 
        switch ( rs->sr_type ) {
        case REP_SEARCH:
-               ((int *)op->o_callback->sc_private)[0] = (int)op->o_private;
+               ((long *)op->o_callback->sc_private)[0] = (long)op->o_private;
                break;
 
        case REP_SEARCHREF:
@@ -662,8 +691,26 @@ meta_back_getconn(
 
        SlapReply       *candidates = meta_back_candidates_get( op );
 
+       /* Internal searches are privileged and shared. So is root. */
+       /* FIXME: there seem to be concurrency issues */
+       if ( op->o_do_not_cache || be_isroot( op ) ) {
+               mc_curr.mc_local_ndn = op->o_bd->be_rootndn;
+               LDAP_BACK_CONN_ISPRIV_SET( &mc_curr );
+               mc_curr.mc_conn = LDAP_BACK_PCONN_SET( op );
+
+       } else {
+               mc_curr.mc_local_ndn = op->o_ndn;
+
+               /* Explicit binds must not be shared */
+               if ( op->o_tag == LDAP_REQ_BIND || SLAP_IS_AUTHZ_BACKEND( op ) ) {
+                       mc_curr.mc_conn = op->o_conn;
+       
+               } else {
+                       mc_curr.mc_conn = LDAP_BACK_PCONN_SET( op );
+               }
+       }
+
        /* Searches for a metaconn in the avl tree */
-       mc_curr.mc_conn = op->o_conn;
        ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
        mc = (metaconn_t *)avl_find( mi->mi_conntree, 
                (caddr_t)&mc_curr, meta_back_conn_cmp );
@@ -720,24 +767,41 @@ meta_back_getconn(
                /* Looks like we didn't get a bind. Open a new session... */
                if ( mc == NULL ) {
                        mc = metaconn_alloc( op );
-                       mc->mc_conn = op->o_conn;
+                       mc->mc_conn = mc_curr.mc_conn;
+                       ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
                        new_conn = 1;
                }
 
                for ( i = 0; i < mi->mi_ntargets; i++ ) {
+                       metatarget_t            *mt = &mi->mi_targets[ i ];
+                       metasingleconn_t        *msc = &mc->mc_conns[ i ];
 
                        /*
                         * The target is activated; if needed, it is
                         * also init'd
                         */
-                       candidates[ i ].sr_err =
-                               meta_back_init_one_conn( op, rs,
-                                               &mi->mi_targets[ i ],
-                                               &mc->mc_conns[ i ], sendok );
+                       candidates[ i ].sr_err = meta_back_init_one_conn( op,
+                               rs, mt, msc, sendok );
                        if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
                                candidates[ i ].sr_tag = META_CANDIDATE;
                                ncandidates++;
-                               
+       
+                               if ( LDAP_BACK_CONN_ISPRIV( &mc_curr ) ) {
+                                       ber_dupbv( &msc->msc_cred, &mt->mt_pseudorootpw );
+                                       ber_dupbv( &msc->msc_bound_ndn, &mt->mt_pseudorootdn );
+                                       LDAP_BACK_CONN_ISPRIV_SET( msc );
+
+                               } else {
+                                       BER_BVZERO( &msc->msc_cred );
+                                       BER_BVZERO( &msc->msc_bound_ndn );
+                                       if ( !BER_BVISEMPTY( &op->o_ndn )
+                                               && SLAP_IS_AUTHZ_BACKEND( op )
+                                               && i == mc->mc_authz_target )
+                                       {
+                                               ber_dupbv( &msc->msc_bound_ndn, &op->o_ndn );
+                                       }
+                               }
+                       
                        } else {
                                
                                /*
@@ -785,7 +849,10 @@ meta_back_getconn(
        }
 
        if ( op_type == META_OP_REQUIRE_SINGLE ) {
-               int     j;
+               metatarget_t            *mt = NULL;
+               metasingleconn_t        *msc = NULL;
+
+               int                     j;
 
                for ( j = 0; j < mi->mi_ntargets; j++ ) {
                        candidates[ j ].sr_tag = META_NOT_CANDIDATE;
@@ -844,7 +911,6 @@ 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() */
-                       mc_curr.mc_conn = op->o_conn;
                        ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
                        mc = (metaconn_t *)avl_find( mi->mi_conntree, 
                                (caddr_t)&mc_curr, meta_back_conn_cmp );
@@ -856,7 +922,8 @@ meta_back_getconn(
                        /* Looks like we didn't get a bind. Open a new session... */
                        if ( mc == NULL ) {
                                mc = metaconn_alloc( op );
-                               mc->mc_conn = op->o_conn;
+                               mc->mc_conn = mc_curr.mc_conn;
+                               ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
                                new_conn = 1;
                        }
                }
@@ -866,13 +933,15 @@ meta_back_getconn(
                 */
                ( void )meta_clear_unused_candidates( op, i );
 
+               mt = &mi->mi_targets[ i ];
+               msc = &mc->mc_conns[ i ];
+
                /*
                 * The target is activated; if needed, it is
                 * also init'd. In case of error, meta_back_init_one_conn
                 * sends the appropriate result.
                 */
-               err = meta_back_init_one_conn( op, rs, &mi->mi_targets[ i ],
-                               &mc->mc_conns[ i ], sendok );
+               err = meta_back_init_one_conn( op, rs, mt, msc, sendok );
                if ( err != LDAP_SUCCESS ) {
                        /*
                         * FIXME: in case one target cannot
@@ -881,7 +950,7 @@ meta_back_getconn(
                         */
                        candidates[ i ].sr_tag = META_NOT_CANDIDATE;
                        if ( new_conn ) {
-                               (void)meta_clear_one_candidate( &mc->mc_conns[ i ] );
+                               (void)meta_clear_one_candidate( msc );
                                meta_back_freeconn( op, mc );
 
                        } else {
@@ -898,6 +967,22 @@ meta_back_getconn(
                        *candidate = i;
                }
 
+               if ( LDAP_BACK_CONN_ISPRIV( &mc_curr ) ) {
+                       ber_dupbv( &msc->msc_cred, &mt->mt_pseudorootpw );
+                       ber_dupbv( &msc->msc_bound_ndn, &mt->mt_pseudorootdn );
+                       LDAP_BACK_CONN_ISPRIV_SET( msc );
+
+               } else {
+                       BER_BVZERO( &msc->msc_cred );
+                       BER_BVZERO( &msc->msc_bound_ndn );
+                       if ( !BER_BVISEMPTY( &op->o_ndn )
+                               && SLAP_IS_AUTHZ_BACKEND( op )
+                               && i == mc->mc_authz_target )
+                       {
+                               ber_dupbv( &msc->msc_bound_ndn, &op->o_ndn );
+                       }
+               }
+                       
        /*
         * if no unique candidate ...
         */
@@ -906,15 +991,20 @@ meta_back_getconn(
                /* Looks like we didn't get a bind. Open a new session... */
                if ( mc == NULL ) {
                        mc = metaconn_alloc( op );
-                       mc->mc_conn = op->o_conn;
+                       mc->mc_conn = mc_curr.mc_conn;
+                       ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
                        new_conn = 1;
                }
 
                for ( i = 0; i < mi->mi_ntargets; i++ ) {
+                       metatarget_t            *mt = &mi->mi_targets[ i ];
+                       metasingleconn_t        *msc = &mc->mc_conns[ i ];
+
                        if ( i == cached 
-                               || meta_back_is_candidate( &mi->mi_targets[ i ].mt_nsuffix,
-                                               mi->mi_targets[ i ].mt_scope,
-                                               &op->o_req_ndn, LDAP_SCOPE_SUBTREE ) )
+                               || meta_back_is_candidate( &mt->mt_nsuffix,
+                                               mt->mt_scope,
+                                               &op->o_req_ndn,
+                                               LDAP_SCOPE_SUBTREE ) )
                        {
 
                                /*
@@ -922,13 +1012,28 @@ meta_back_getconn(
                                 * also init'd
                                 */
                                int lerr = meta_back_init_one_conn( op, rs,
-                                               &mi->mi_targets[ i ],
-                                               &mc->mc_conns[ i ], sendok );
+                                               mt, msc, sendok );
                                if ( lerr == LDAP_SUCCESS ) {
                                        candidates[ i ].sr_tag = META_CANDIDATE;
                                        candidates[ i ].sr_err = LDAP_SUCCESS;
                                        ncandidates++;
 
+                                       if ( LDAP_BACK_CONN_ISPRIV( &mc_curr ) ) {
+                                               ber_dupbv( &msc->msc_cred, &mt->mt_pseudorootpw );
+                                               ber_dupbv( &msc->msc_bound_ndn, &mt->mt_pseudorootdn );
+                                               LDAP_BACK_CONN_ISPRIV_SET( msc );
+
+                                       } else {
+                                               BER_BVZERO( &msc->msc_cred );
+                                               BER_BVZERO( &msc->msc_bound_ndn );
+                                               if ( !BER_BVISEMPTY( &op->o_ndn )
+                                                       && SLAP_IS_AUTHZ_BACKEND( op )
+                                                       && i == mc->mc_authz_target )
+                                               {
+                                                       ber_dupbv( &msc->msc_bound_ndn, &op->o_ndn );
+                                               }
+                                       }
+                       
                                        Debug( LDAP_DEBUG_TRACE, "%s: meta_back_init_one_conn(%d)\n",
                                                op->o_log_prefix, i, 0 );
 
@@ -940,7 +1045,7 @@ meta_back_getconn(
                                         * be tried?
                                         */
                                        if ( new_conn ) {
-                                               ( void )meta_clear_one_candidate( &mc->mc_conns[ i ] );
+                                               ( void )meta_clear_one_candidate( msc );
                                        }
                                        /* leave the target candidate, but record the error for later use */
                                        candidates[ i ].sr_err = lerr;
@@ -954,7 +1059,7 @@ meta_back_getconn(
 
                        } else {
                                if ( new_conn ) {
-                                       ( void )meta_clear_one_candidate( &mc->mc_conns[ i ] );
+                                       ( void )meta_clear_one_candidate( msc );
                                }
                                candidates[ i ].sr_tag = META_NOT_CANDIDATE;
                        }
@@ -1013,7 +1118,8 @@ done:;
                if ( err != 0 ) {
                        Debug( LDAP_DEBUG_ANY,
                                "%s meta_back_getconn: candidates=%d conn=%ld insert failed\n",
-                               op->o_log_prefix, ncandidates, mc->mc_conn->c_connid );
+                               op->o_log_prefix, ncandidates,
+                               LDAP_BACK_PCONN_ID( mc->mc_conn ) );
                
                        rs->sr_err = LDAP_OTHER;
                        rs->sr_text = "Internal server error";
@@ -1027,12 +1133,14 @@ done:;
 
                Debug( LDAP_DEBUG_TRACE,
                        "%s meta_back_getconn: candidates=%d conn=%ld inserted\n",
-                       op->o_log_prefix, ncandidates, mc->mc_conn->c_connid );
+                       op->o_log_prefix, ncandidates,
+                       LDAP_BACK_PCONN_ID( mc->mc_conn ) );
 
        } else {
                Debug( LDAP_DEBUG_TRACE,
                        "%s meta_back_getconn: candidates=%d conn=%ld fetched\n",
-                       op->o_log_prefix, ncandidates, mc->mc_conn->c_connid );
+                       op->o_log_prefix, ncandidates,
+                       LDAP_BACK_PCONN_ID( mc->mc_conn ) );
        }
        
        return mc;
diff --git a/servers/slapd/back-meta/group.c b/servers/slapd/back-meta/group.c
deleted file mode 100644 (file)
index cf4bf52..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/* $OpenLDAP$ */
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1999-2005 The OpenLDAP Foundation.
- * Portions Copyright 2001-2003 Pierangelo Masarati.
- * Portions Copyright 1999-2003 Howard Chu.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-/* ACKNOWLEDGEMENTS:
- * This work was initially developed by the Howard Chu for inclusion
- * in OpenLDAP Software and subsequently enhanced by Pierangelo
- * Masarati.
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "../back-ldap/back-ldap.h"
-#include "back-meta.h"
-#include "lutil.h"
-
-/* return 0 IFF op_dn is a value in group_at (member) attribute
- * of entry with gr_dn AND that entry has an objectClass
- * value of group_oc (groupOfNames)
- */
-int
-meta_back_group(
-               Backend                 *be,
-               Connection              *conn,
-               Operation               *op,
-               Entry                   *target,
-               struct berval           *gr_ndn,
-               struct berval           *op_ndn,
-               ObjectClass             *group_oc,
-               AttributeDescription    *group_at
-)
-{
-       struct metainfo *li = ( struct metainfo * )be->be_private;    
-       int rc = 1, candidate;
-       Attribute   *attr;
-       AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
-       LDAPMessage     *result;
-       char *gattr[ 2 ];
-       char *filter = NULL, *ptr;
-       LDAP *ld = NULL;
-       struct berval mop_ndn = BER_BVNULL, mgr_ndn = BER_BVNULL;
-
-       struct berval group_oc_name = BER_BVNULL;
-       struct berval group_at_name = group_at->ad_cname;
-
-       if ( group_oc->soc_names && group_oc->soc_names[ 0 ] ) {
-               group_oc_name.bv_val = group_oc->soc_names[ 0 ];
-       } else {
-               group_oc_name.bv_val = group_oc->soc_oid;
-       }
-
-       if ( group_oc_name.bv_val ) {
-               group_oc_name.bv_len = strlen( group_oc_name.bv_val );
-       }
-
-       if ( target != NULL && dn_match( &target->e_nname, gr_ndn ) ) {
-               /* we already have a copy of the entry */
-               /* attribute and objectclass mapping has already been done */
-
-               /*
-                * first we need to check if the objectClass attribute
-                * has been retrieved; otherwise we need to repeat the search
-                */
-               attr = attr_find( target->e_attrs, ad_objectClass );
-               if ( attr != NULL ) {
-
-                       /*
-                        * Now we can check for the group objectClass value
-                        */
-                       if ( !is_entry_objectclass( target, group_oc, 0 ) ) {
-                               return 1;
-                       }
-
-                       /*
-                        * This part has been reworked: the group attr compare
-                        * fails only if the attribute is PRESENT but the value
-                        * is NOT PRESENT; if the attribute is NOT PRESENT, the
-                        * search must be repeated as well.
-                        * This may happen if a search for an entry has already
-                        * been performed (target is not null) but the group
-                        * attribute has not been required
-                        */
-                       attr = attr_find( target->e_attrs, group_at );
-                       if ( attr != NULL ) {
-                               rc = value_find_ex( group_at,
-                                       SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-                                       attr->a_vals, op_ndn );
-                               if ( rc != LDAP_SUCCESS ) {
-                                       return 1;
-                               }
-                               return 0;
-                       } /* else: repeat the search */
-               } /* else: repeat the search */
-       } /* else: do the search */
-
-       candidate = meta_back_select_unique_candidate( li, gr_ndn );
-       if ( candidate == META_TARGET_NONE ) {
-               goto cleanup;
-       }
-
-       /*
-        * Rewrite the op ndn if needed
-        */
-       switch ( rewrite_session( li->targets[ candidate ]->rwinfo, "bindDn",
-                               op_ndn->bv_val, conn, &mop_ndn.bv_val ) ) {
-       case REWRITE_REGEXEC_OK:
-               if ( mop_ndn.bv_val != NULL && mop_ndn.bv_val[ 0 ] != '\0' ) {
-                       mop_ndn.bv_len = strlen( mop_ndn.bv_val );
-               } else {
-                       mop_ndn = *op_ndn;
-               }
-               Debug( LDAP_DEBUG_ARGS,
-                               "rw> bindDn (op ndn in group):"
-                               " \"%s\" -> \"%s\"\n%s",
-                               op_ndn->bv_val, mop_ndn.bv_val, "" );
-               break;
-               
-       case REWRITE_REGEXEC_UNWILLING:
-               /* continues to next case */
-               
-       case REWRITE_REGEXEC_ERR:
-               return 1;
-       }
-
-       /*
-        * Rewrite the gr ndn if needed
-        */
-       switch ( rewrite_session( li->targets[ candidate ]->rwinfo,
-                               "searchBase",
-                               gr_ndn->bv_val, conn, &mgr_ndn.bv_val ) ) {
-       case REWRITE_REGEXEC_OK:
-               if ( mgr_ndn.bv_val != NULL && mgr_ndn.bv_val[ 0 ] != '\0' ) {
-                       mgr_ndn.bv_len = strlen( mgr_ndn.bv_val );
-               } else {
-                       mgr_ndn = *gr_ndn;
-               }
-               Debug( LDAP_DEBUG_ARGS,
-                               "rw> searchBase (gr ndn in group):"
-                               " \"%s\" -> \"%s\"\n%s",
-                               gr_ndn->bv_val, mgr_ndn.bv_val, "" );
-               break;
-               
-       case REWRITE_REGEXEC_UNWILLING:
-               /* continues to next case */
-               
-       case REWRITE_REGEXEC_ERR:
-               goto cleanup;
-       }
-       
-       ldap_back_map( &li->targets[ candidate ]->oc_map,
-                       &group_oc_name, &group_oc_name, BACKLDAP_MAP );
-       if ( group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0' ) {
-               goto cleanup;
-       }
-       ldap_back_map( &li->targets[ candidate ]->at_map,
-                       &group_at_name, &group_at_name, BACKLDAP_MAP );
-       if ( group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0' ) {
-               goto cleanup;
-       }
-
-       filter = ch_malloc( sizeof( "(&(objectclass=)(=))" )
-                       + group_oc_name.bv_len
-                       + group_at_name.bv_len
-                       + mop_ndn.bv_len + 1 );
-       if ( filter == NULL ) {
-               goto cleanup;
-       }
-
-       rc = ldap_initialize( &ld, li->targets[ candidate ]->uri );
-       if ( rc != LDAP_SUCCESS ) {
-               goto cleanup;
-       }
-
-       rc = ldap_bind_s( ld, li->targets[ candidate ]->binddn.bv_val,
-                       li->targets[ candidate ]->bindpw.bv_val, 
-                       LDAP_AUTH_SIMPLE );
-       if ( rc != LDAP_SUCCESS ) {
-               goto cleanup;
-       }
-
-       ptr = lutil_strcopy( filter, "(&(objectclass=" );
-       ptr = lutil_strcopy( ptr , group_oc_name.bv_val );
-       ptr = lutil_strcopy( ptr , ")(" );
-       ptr = lutil_strcopy( ptr , group_at_name.bv_val );
-       ptr = lutil_strcopy( ptr , "=" );
-       ptr = lutil_strcopy( ptr , mop_ndn.bv_val );
-       strcpy( ptr , "))" );
-
-       gattr[ 0 ] = "objectclass";
-       gattr[ 1 ] = NULL;
-       rc = 1;
-       if ( ldap_search_ext_s( ld, mgr_ndn.bv_val, LDAP_SCOPE_BASE, filter,
-                               gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
-                               LDAP_NO_LIMIT, &result ) == LDAP_SUCCESS ) {
-               if ( ldap_first_entry( ld, result ) != NULL ) {
-                       rc = 0;
-               }
-               ldap_msgfree( result );
-       }
-
-cleanup:;
-       if ( ld != NULL ) {
-               ldap_unbind( ld );
-       }
-       if ( filter != NULL ) {
-               ch_free( filter );
-       }
-       if ( mop_ndn.bv_val != op_ndn->bv_val ) {
-               free( mop_ndn.bv_val );
-       }
-       if ( mgr_ndn.bv_val != gr_ndn->bv_val ) {
-               free( mgr_ndn.bv_val );
-       }
-
-       return rc;
-}
-
index 3b50226603d2826e39df0dd19bd13fc7f8571ddf..fb2b0d50ceb888241511c95a434b30397b052c47 100644 (file)
@@ -30,7 +30,9 @@ int
 meta_back_open(
        BackendInfo     *bi )
 {
+       /* FIXME: need to remove the pagedResults, and likely more... */
        bi->bi_controls = slap_known_controls;
+
        return 0;
 }
 
index 55edc25767777b32ecacfee03d01f4637ee8e16f..544bf6e31f5f2c0a9ebe69d01b505cebadf15221 100644 (file)
@@ -244,8 +244,9 @@ meta_back_search( Operation *op, SlapReply *rs )
        LDAPMessage     *res = NULL, *e;
        int             rc = 0, sres = LDAP_SUCCESS;
        char            *matched = NULL;
-       int             i, last = 0, ncandidates = 0,
+       int             last = 0, ncandidates = 0,
                        initial_candidates = 0, candidate_match = 0;
+       long            i;
        dncookie        dc;
        int             is_ok = 0;
        void            *savepriv;
@@ -357,7 +358,6 @@ meta_back_search( Operation *op, SlapReply *rs )
 
        if ( op->ors_tlimit != SLAP_NO_LIMIT ) {
                stoptime = op->o_time + op->ors_tlimit;
-               tv.tv_sec = 0;
        }
 
        /*
@@ -630,11 +630,11 @@ really_bad:;
                                sres = slap_map_api2result( rs );
 
                                snprintf( buf, sizeof( buf ),
-                                       "%s meta_back_search[%d] "
-                                       "match=\"%s\" err=%d\n",
+                                       "%s meta_back_search[%ld] "
+                                       "match=\"%s\" err=%ld\n",
                                        op->o_log_prefix, i,
                                        candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
-                                       candidates[ i ].sr_err );
+                                       (long) candidates[ i ].sr_err );
                                Debug( LDAP_DEBUG_ANY, "%s", buf, 0, 0 );
 
                                switch ( sres ) {
@@ -702,8 +702,7 @@ really_bad:;
                }
 
                if ( gotit == 0 ) {
-                       tv.tv_sec = 0;
-                        tv.tv_usec = 100000;   /* 0.1 s */
+                       LDAP_BACK_TV_SET( &tv );
                         ldap_pvt_thread_yield();
 
                } else {
@@ -726,7 +725,7 @@ really_bad:;
         * FIXME: only the last one gets caught!
         */
        savepriv = op->o_private;
-       op->o_private = (void *)mi->mi_ntargets;
+       op->o_private = (void *)(long)mi->mi_ntargets;
        if ( candidate_match > 0 ) {
                struct berval   pmatched = BER_BVNULL;
 
@@ -867,9 +866,11 @@ meta_send_entry(
        Entry                   ent = { 0 };
        BerElement              ber = *e->lm_ber;
        Attribute               *attr, **attrp;
-       struct berval           *bv, bdn;
+       struct berval           bdn,
+                               dn = BER_BVNULL;
        const char              *text;
        dncookie                dc;
+       int                     rc;
 
        if ( ber_scanf( &ber, "{m{", &bdn ) == LBER_ERROR ) {
                return LDAP_DECODING_ERROR;
@@ -883,7 +884,7 @@ meta_send_entry(
        dc.rs = rs;
        dc.ctx = "searchResult";
 
-       rs->sr_err = ldap_back_dn_massage( &dc, &bdn, &ent.e_name );
+       rs->sr_err = ldap_back_dn_massage( &dc, &bdn, &dn );
        if ( rs->sr_err != LDAP_SUCCESS) {
                return rs->sr_err;
        }
@@ -895,9 +896,14 @@ meta_send_entry(
         * 
         * FIXME: should we log anything, or delegate to dnNormalize?
         */
-       if ( dnNormalize( 0, NULL, NULL, &ent.e_name, &ent.e_nname,
-               op->o_tmpmemctx ) != LDAP_SUCCESS )
-       {
+       rc = dnPrettyNormal( NULL, &dn, &ent.e_name, &ent.e_nname,
+               op->o_tmpmemctx );
+       if ( dn.bv_val != bdn.bv_val ) {
+               free( dn.bv_val );
+       }
+       BER_BVZERO( &dn );
+
+       if ( rc != LDAP_SUCCESS ) {
                return LDAP_INVALID_DN_SYNTAX;
        }
 
@@ -992,6 +998,8 @@ meta_send_entry(
                if ( attr->a_desc == slap_schema.si_ad_objectClass
                                || attr->a_desc == slap_schema.si_ad_structuralObjectClass )
                {
+                       struct berval   *bv;
+
                        for ( bv = attr->a_vals; !BER_BVISNULL( bv ); bv++ ) {
                                ldap_back_map( &mi->mi_targets[ target ].mt_rwmap.rwm_oc,
                                                bv, &mapped, BACKLDAP_REMAP );
@@ -1045,11 +1053,28 @@ meta_send_entry(
                                                &attr->a_vals[i] );
                                }
 
+                               if ( rc ) {
+                                       LBER_FREE( attr->a_vals[i].bv_val );
+                                       if ( --last == i ) {
+                                               BER_BVZERO( &attr->a_vals[ i ] );
+                                               break;
+                                       }
+                                       attr->a_vals[i] = attr->a_vals[last];
+                                       BER_BVZERO( &attr->a_vals[last] );
+                                       i--;
+                                       continue;
+                               }
+
                                if ( pretty ) {
                                        LBER_FREE( attr->a_vals[i].bv_val );
                                        attr->a_vals[i] = pval;
                                }
                        }
+
+                       if ( last == 0 && attr->a_vals != &slap_dummy_bv ) {
+                               attr_free( attr );
+                               goto next_attr;
+                       }
                }
 
                if ( last && attr->a_desc->ad_type->sat_equality &&
@@ -1084,9 +1109,7 @@ next_attr:;
        rs->sr_attrs = NULL;
        
        if ( !BER_BVISNULL( &ent.e_name ) ) {
-               if ( ent.e_name.bv_val != bdn.bv_val ) {
-                       free( ent.e_name.bv_val );
-               }
+               free( ent.e_name.bv_val );
                BER_BVZERO( &ent.e_name );
        }
        if ( !BER_BVISNULL( &ent.e_nname ) ) {
index 93a694b02bf9b6fa8ce73bbe7bfb243fc4dd10b0..ed4bc96e30e82339f83857ef7ce7e01f22632b0c 100644 (file)
@@ -57,13 +57,10 @@ meta_back_conn_destroy(
        if ( mc ) {
                Debug( LDAP_DEBUG_TRACE,
                        "=>meta_back_conn_destroy: destroying conn %ld\n",
-                       mc->mc_conn->c_connid, 0, 0 );
+                       LDAP_BACK_PCONN_ID( mc->mc_conn ), 0, 0 );
                
                assert( mc->mc_refcnt == 0 );
 
-               /*
-                * Cleanup rewrite session
-                */
                for ( i = 0; i < mi->mi_ntargets; ++i ) {
                        if ( mc->mc_conns[ i ].msc_ld != NULL ) {
                                meta_clear_one_candidate( &mc->mc_conns[ i ] );
index 293d543535a1f9672b6fe87f6e98ae438a25fec1..cccdec15316c6e9181f03b5840228fa25e2a3cfb 100644 (file)
@@ -261,12 +261,28 @@ typedef struct entry_limbo_t {
        struct entry_limbo_t    *el_next;
 } entry_limbo_t;
 
+int
+monitor_back_is_configured( void )
+{
+       return be_monitor != NULL;
+}
+
 int
 monitor_back_register_entry(
        Entry                   *e,
        monitor_callback_t      *cb )
 {
-       monitor_info_t  *mi = ( monitor_info_t * )be_monitor->be_private;
+       monitor_info_t  *mi;
+
+       if ( be_monitor == NULL ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "monitor_back_register_entry(\"%s\"): "
+                       "monitor database not configured.\n",
+                       e->e_name.bv_val, 0, 0 );
+               return -1;
+       }
+
+       mi = ( monitor_info_t * )be_monitor->be_private;
 
        assert( mi != NULL );
        assert( e != NULL );
@@ -413,9 +429,21 @@ monitor_back_register_entry_parent(
        int                     scope,
        struct berval           *filter )
 {
-       monitor_info_t  *mi = ( monitor_info_t * )be_monitor->be_private;
+       monitor_info_t  *mi;
        struct berval   ndn = BER_BVNULL;
 
+       if ( be_monitor == NULL ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "monitor_back_register_entry_parent(base=\"%s\" scope=%s filter=\"%s\"): "
+                       "monitor database not configured.\n",
+                       BER_BVISNULL( base ) ? "" : base->bv_val,
+                       scope == LDAP_SCOPE_BASE ? "base" : ( scope == LDAP_SCOPE_ONELEVEL ? "one" : "subtree" ),
+                       BER_BVISNULL( filter ) ? "" : filter->bv_val );
+               return -1;
+       }
+
+       mi = ( monitor_info_t * )be_monitor->be_private;
+
        assert( mi != NULL );
        assert( e != NULL );
        assert( e->e_private == NULL );
@@ -712,8 +740,26 @@ monitor_back_register_entry_attrs(
        int                     scope,
        struct berval           *filter )
 {
-       monitor_info_t  *mi = ( monitor_info_t * )be_monitor->be_private;
+       monitor_info_t  *mi;
        struct berval   ndn = BER_BVNULL;
+       char            *fname = ( a == NULL ? "callback" : "attrs" );
+
+       if ( be_monitor == NULL ) {
+               char            buf[ SLAP_TEXT_BUFLEN ];
+
+               snprintf( buf, sizeof( buf ),
+                       "monitor_back_register_entry_%s(base=\"%s\" scope=%s filter=\"%s\"): "
+                       "monitor database not configured.\n",
+                       fname,
+                       BER_BVISNULL( base ) ? "" : base->bv_val,
+                       scope == LDAP_SCOPE_BASE ? "base" : ( scope == LDAP_SCOPE_ONELEVEL ? "one" : "subtree" ),
+                       BER_BVISNULL( filter ) ? "" : filter->bv_val );
+               Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
+
+               return -1;
+       }
+
+       mi = ( monitor_info_t * )be_monitor->be_private;
 
        assert( mi != NULL );
 
@@ -731,9 +777,9 @@ monitor_back_register_entry_attrs(
        {
                /* need a filter */
                Debug( LDAP_DEBUG_ANY,
-                       "monitor_back_register_entry_*(\"\"): "
+                       "monitor_back_register_entry_%s(\"\"): "
                        "need a valid filter\n",
-                       0, 0, 0 );
+                       fname, 0, 0 );
                return -1;
        }
 
@@ -747,13 +793,18 @@ monitor_back_register_entry_attrs(
 
                if ( BER_BVISNULL( &ndn ) ) {
                        if ( monitor_filter2ndn( base, scope, filter, &ndn ) ) {
-                               /* entry does not exist */
-                               Debug( LDAP_DEBUG_ANY,
-                                       "monitor_back_register_entry_*(\"\"): "
+                               char            buf[ SLAP_TEXT_BUFLEN ];
+
+                               snprintf( buf, sizeof( buf ),
+                                       "monitor_back_register_entry_%s(\"\"): "
                                        "base=%s scope=%d filter=%s : "
                                        "unable to find entry\n",
+                                       fname,
                                        base->bv_val ? base->bv_val : "\"\"",
                                        scope, filter->bv_val );
+
+                               /* entry does not exist */
+                               Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
                                return -1;
                        }
 
@@ -763,9 +814,9 @@ monitor_back_register_entry_attrs(
                if ( monitor_cache_get( mi, &ndn, &e ) != 0 ) {
                        /* entry does not exist */
                        Debug( LDAP_DEBUG_ANY,
-                               "monitor_back_register_entry_*(\"%s\"): "
+                               "monitor_back_register_entry_%s(\"%s\"): "
                                "entry does not exist\n",
-                               ndn.bv_val, 0, 0 );
+                               fname, ndn.bv_val, 0 );
                        rc = -1;
                        goto done;
                }
@@ -776,9 +827,9 @@ monitor_back_register_entry_attrs(
                if ( mp->mp_flags & MONITOR_F_VOLATILE ) {
                        /* entry is volatile; cannot append callback */
                        Debug( LDAP_DEBUG_ANY,
-                               "monitor_back_register_entry_*(\"%s\"): "
+                               "monitor_back_register_entry_%s(\"%s\"): "
                                "entry is volatile\n",
-                               e->e_name.bv_val, 0, 0 );
+                               fname, e->e_name.bv_val, 0 );
                        rc = -1;
                        goto done;
                }
@@ -790,9 +841,9 @@ monitor_back_register_entry_attrs(
                        *atp = attrs_dup( a );
                        if ( *atp == NULL ) {
                                Debug( LDAP_DEBUG_ANY,
-                                       "monitor_back_register_entry_*(\"%s\"): "
+                                       "monitor_back_register_entry_%s(\"%s\"): "
                                        "attrs_dup() failed\n",
-                                       e->e_name.bv_val, 0, 0 );
+                                       fname, e->e_name.bv_val, 0 );
                                rc = -1;
                                goto done;
                        }
index 70007135bde55b51884259f3ba63081af0ffd7b5..a3bb542b70209e15bbc91753f5c6bc4060d046bf 100644 (file)
@@ -130,6 +130,8 @@ monitor_back_get_subsys_by_dn LDAP_P((
        struct berval           *ndn,
        int                     sub ));
 extern int
+monitor_back_is_configured LDAP_P(( void ));
+extern int
 monitor_back_register_entry LDAP_P((
        Entry                   *e,
        monitor_callback_t      *cb ));
index 9a462acfb4b5a2987f7082ed2848cbd01147e5f4..0ba4acfdff241419e93352b9cb5dccc93844a76e 100644 (file)
@@ -28,20 +28,7 @@ perl_back_close(
        BackendInfo *bd
 )
 {
-       ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );  
-
        perl_destruct(PERL_INTERPRETER);
-
-       ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );        
-
-       return 0;
-}
-
-int
-perl_back_destroy(
-       BackendInfo *bd
-)
-{
        perl_free(PERL_INTERPRETER);
        PERL_INTERPRETER = NULL;
 
index fef6b782a9bda0338a8d53e6504017a52812d2dc..fe79d9a08c9521ee4464d80345b110124f2ae751 100644 (file)
@@ -35,25 +35,10 @@ perl_back_initialize(
        BackendInfo     *bi
 )
 {
-       char *embedding[] = { "", "-e", "0" };
-
-       Debug( LDAP_DEBUG_TRACE, "perl backend open\n", 0, 0, 0 );
-
-       if( PERL_INTERPRETER != NULL ) {
-               Debug( LDAP_DEBUG_ANY, "perl backend open: already opened\n",
-                       0, 0, 0 );
-               return 1;
-       }
-       
-       PERL_INTERPRETER = perl_alloc();
-       perl_construct(PERL_INTERPRETER);
-       perl_parse(PERL_INTERPRETER, perl_back_xs_init, 3, embedding, (char **)NULL);
-       perl_run(PERL_INTERPRETER);
-
        bi->bi_open = perl_back_open;
        bi->bi_config = 0;
        bi->bi_close = perl_back_close;
-       bi->bi_destroy = perl_back_destroy;
+       bi->bi_destroy = 0;
 
        bi->bi_db_init = perl_back_db_init;
        bi->bi_db_config = perl_back_db_config;
@@ -86,7 +71,22 @@ perl_back_open(
        BackendInfo     *bi
 )
 {
+       char *embedding[] = { "", "-e", "0" };
+
+       Debug( LDAP_DEBUG_TRACE, "perl backend open\n", 0, 0, 0 );
+
+       if( PERL_INTERPRETER != NULL ) {
+               Debug( LDAP_DEBUG_ANY, "perl backend open: already opened\n",
+                       0, 0, 0 );
+               return 1;
+       }
+       
        ldap_pvt_thread_mutex_init( &perl_interpreter_mutex );
+
+       PERL_INTERPRETER = perl_alloc();
+       perl_construct(PERL_INTERPRETER);
+       perl_parse(PERL_INTERPRETER, perl_back_xs_init, 3, embedding, (char **)NULL);
+       perl_run(PERL_INTERPRETER);
        return 0;
 }
 
index 1d9b6b963324879c07ad5b341b50be832b4930f8..eb034112237173e1587c2516c22f2fdb412200e8 100644 (file)
@@ -24,7 +24,6 @@ extern BI_init                perl_back_initialize;
 
 extern BI_open         perl_back_open;
 extern BI_close                perl_back_close;
-extern BI_destroy      perl_back_destroy;
 
 extern BI_db_init      perl_back_db_init;
 extern BI_db_open      perl_back_db_open;
index d8f3842366997d43305fac8e9e5e31077781ba4e..548bfd835eb809bf2618ca3b471f5b0864c332e5 100644 (file)
@@ -819,7 +819,7 @@ backsql_add_attr(
                        if ( rc != SQL_SUCCESS ) {
                                Debug( LDAP_DEBUG_TRACE,
                                        "   backsql_add_attr(): "
-                                       "error binding output parameter for %s[%d]\n",
+                                       "error binding output parameter for %s[%lu]\n",
                                        at_rec->bam_ad->ad_cname.bv_val, i, 0 );
                                backsql_PrintErrors( bi->sql_db_env, dbh, 
                                        sth, rc );
@@ -840,7 +840,7 @@ backsql_add_attr(
                if ( rc != SQL_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE,
                                "   backsql_add_attr(): "
-                               "error binding keyval parameter for %s[%d]\n",
+                               "error binding keyval parameter for %s[%lu]\n",
                                at_rec->bam_ad->ad_cname.bv_val, i, 0 );
                        backsql_PrintErrors( bi->sql_db_env, dbh, 
                                sth, rc );
@@ -861,7 +861,7 @@ backsql_add_attr(
                if ( rc != SQL_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE,
                                "   backsql_add_attr(): "
-                               "error binding value parameter for %s[%d]\n",
+                               "error binding value parameter for %s[%lu]\n",
                                at_rec->bam_ad->ad_cname.bv_val, i, 0 );
                        backsql_PrintErrors( bi->sql_db_env, dbh, 
                                sth, rc );
index 9690774a0951edfad36187c4070e39165a0ed0ed..74035025d025a6b559fd8a491e7d09e60bd040f2 100644 (file)
@@ -550,7 +550,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
        }
 
        Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
-               "number of values in query: %d\n", count, 0, 0 );
+               "number of values in query: %lu\n", count, 0, 0 );
        SQLFreeStmt( sth, SQL_DROP );
        if ( count == 0 ) {
                return 1;
@@ -662,7 +662,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                        BACKSQL_SUCCESS( rc );
                        rc = SQLFetch( sth ), k++ )
        {
-               for ( i = 0; i < row.ncols; i++ ) {
+               for ( i = 0; i < (unsigned long)row.ncols; i++ ) {
 
                        if ( row.value_len[ i ] > 0 ) {
                                struct berval           bv;
@@ -722,11 +722,11 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                                         * but we're accepting the attributes;
                                         * should we fail at all? */
                                        snprintf( buf, sizeof( buf ),
-                                                       "unable to %s value #%d "
+                                                       "unable to %s value #%lu "
                                                        "of AttributeDescription %s",
                                                        pretty ? "prettify" : "validate",
-                                                       at->bam_ad->ad_cname.bv_val,
-                                                       k - oldcount );
+                                                       k - oldcount,
+                                                       at->bam_ad->ad_cname.bv_val );
                                        Debug( LDAP_DEBUG_TRACE,
                                                "==>backsql_get_attr_vals(\"%s\"): "
                                                "%s (%d)\n",
@@ -757,10 +757,10 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
                                                 * but we're accepting the attributes;
                                                 * should we fail at all? */
                                                snprintf( buf, sizeof( buf ),
-                                                       "unable to normalize value #%d "
+                                                       "unable to normalize value #%lu "
                                                        "of AttributeDescription %s",
-                                                       at->bam_ad->ad_cname.bv_val,
-                                                       k - oldcount );
+                                                       k - oldcount,
+                                                       at->bam_ad->ad_cname.bv_val );
                                                Debug( LDAP_DEBUG_TRACE,
                                                        "==>backsql_get_attr_vals(\"%s\"): "
                                                        "%s (%d)\n",
index 4bb276f0f2d620fb5ee8909bd6a3b9b52eab5db1..eee55942e54a265d3611c8ac3455db8715f61638 100644 (file)
@@ -522,9 +522,9 @@ backsql_entryUUID(
        /* note: works only with 32 bit architectures... */
        snprintf( uuidbuf, sizeof( uuidbuf ),
                        "%08x-%04x-%04x-0000-000000000000",
-                       ( id->eid_oc_id & 0xFFFFFFFF ),
-                       ( ( id->eid_keyval & 0xFFFF0000 ) >> 020 /* 16 */ ),
-                       ( id->eid_keyval & 0xFFFF ) );
+                       ( (unsigned)id->eid_oc_id & 0xFFFFFFFF ),
+                       ( ( (unsigned)id->eid_keyval & 0xFFFF0000 ) >> 020 /* 16 */ ),
+                       ( (unsigned)id->eid_keyval & 0xFFFF ) );
 #endif /* ! BACKSQL_ARBITRARY_KEY */
 
        uuid.bv_val = uuidbuf;
index 18feb7df24433419ff42dbc35ad5838084db8fbd..f6f868a30d52d0b061e65f49992eb8b010aba4c6 100644 (file)
@@ -477,7 +477,9 @@ int backend_destroy(void)
                }
                acl_destroy( bd->be_acl, frontendDB->be_acl );
 
-               assert( bd->be_replogfile == NULL );
+               if ( bd->be_replogfile != NULL ) {
+                       free( bd->be_replogfile );
+               }
                assert( bd->be_replica == NULL );
        }
 
@@ -1184,19 +1186,17 @@ be_entry_get_rw(
        int rw,
        Entry **e )
 {
-       int rc;
-
        *e = NULL;
 
-       if (op->o_bd == NULL) {
-               rc = LDAP_NO_SUCH_OBJECT;
-       } else if ( op->o_bd->be_fetch ) {
-               rc = ( op->o_bd->be_fetch )( op, ndn,
-                       oc, at, rw, e );
-       } else {
-               rc = LDAP_UNWILLING_TO_PERFORM;
+       if ( op->o_bd == NULL ) {
+               return LDAP_NO_SUCH_OBJECT;
        }
-       return rc;
+
+       if ( op->o_bd->be_fetch ) {
+               return op->o_bd->be_fetch( op, ndn, oc, at, rw, e );
+       }
+
+       return LDAP_UNWILLING_TO_PERFORM;
 }
 
 int 
index 936d617fdef43541c1bcc3b284e8e9f1a4c0a6cd..db732652a42da840f6b2d1ec7a2a3ee2f50b0382 100644 (file)
@@ -477,16 +477,17 @@ glue_open (
        if (slapMode & SLAP_TOOL_MODE) {
                for (i = 0; i<gi->gi_nodes; i++) {
                        same = 0;
-                       /* Same type as our main backend? */
-                       if ( gi->gi_n[i].gn_be->bd_info == on->on_info->oi_orig )
+                       /* Same bi_open as our main backend? */
+                       if ( gi->gi_n[i].gn_be->bd_info->bi_open ==
+                               on->on_info->oi_orig->bi_open )
                                bsame = 1;
 
                        /* Loop thru the bd_info's and make sure we only
                         * invoke their bi_open functions once each.
                         */
                        for ( j = 0; j<i; j++ ) {
-                               if ( gi->gi_n[i].gn_be->bd_info ==
-                                       gi->gi_n[j].gn_be->bd_info ) {
+                               if ( gi->gi_n[i].gn_be->bd_info->bi_open ==
+                                       gi->gi_n[j].gn_be->bd_info->bi_open ) {
                                        same = 1;
                                        break;
                                }
@@ -715,6 +716,7 @@ glue_db_init(
 {
        slap_overinst   *on = (slap_overinst *)be->bd_info;
        slap_overinfo   *oi = on->on_info;
+       BackendInfo     *bi = oi->oi_orig;
        glueinfo *gi;
 
        gi = ch_calloc( 1, sizeof(glueinfo));
@@ -729,14 +731,23 @@ glue_db_init(
 
        oi->oi_bi.bi_entry_release_rw = glue_entry_release_rw;
 
-       oi->oi_bi.bi_tool_entry_open = glue_tool_entry_open;
-       oi->oi_bi.bi_tool_entry_close = glue_tool_entry_close;
-       oi->oi_bi.bi_tool_entry_first = glue_tool_entry_first;
-       oi->oi_bi.bi_tool_entry_next = glue_tool_entry_next;
-       oi->oi_bi.bi_tool_entry_get = glue_tool_entry_get;
-       oi->oi_bi.bi_tool_entry_put = glue_tool_entry_put;
-       oi->oi_bi.bi_tool_entry_reindex = glue_tool_entry_reindex;
-       oi->oi_bi.bi_tool_sync = glue_tool_sync;
+       /* Only advertise these if the root DB supports them */
+       if ( bi->bi_tool_entry_open )
+               oi->oi_bi.bi_tool_entry_open = glue_tool_entry_open;
+       if ( bi->bi_tool_entry_close )
+               oi->oi_bi.bi_tool_entry_close = glue_tool_entry_close;
+       if ( bi->bi_tool_entry_first )
+               oi->oi_bi.bi_tool_entry_first = glue_tool_entry_first;
+       if ( bi->bi_tool_entry_next )
+               oi->oi_bi.bi_tool_entry_next = glue_tool_entry_next;
+       if ( bi->bi_tool_entry_get )
+               oi->oi_bi.bi_tool_entry_get = glue_tool_entry_get;
+       if ( bi->bi_tool_entry_put )
+               oi->oi_bi.bi_tool_entry_put = glue_tool_entry_put;
+       if ( bi->bi_tool_entry_reindex )
+               oi->oi_bi.bi_tool_entry_reindex = glue_tool_entry_reindex;
+       if ( bi->bi_tool_sync )
+               oi->oi_bi.bi_tool_sync = glue_tool_sync;
 
        /*FIXME : need to add support */
        oi->oi_bi.bi_tool_dn2id_get = 0;
@@ -779,7 +790,7 @@ glue_sub_del( BackendDB *b0 )
 
        /* Find the top backend for this subordinate */
        be = b0;
-       while ( be=LDAP_STAILQ_NEXT( be, be_next )) {
+       while ( (be=LDAP_STAILQ_NEXT( be, be_next )) != NULL ) {
                slap_overinfo *oi;
                slap_overinst *on;
                glueinfo *gi;
@@ -826,7 +837,7 @@ typedef struct glue_Addrec {
 static glue_Addrec *ga_list;
 
 /* Attach all the subordinate backends to their superior */
-static int
+int
 glue_sub_attach()
 {
        glue_Addrec *ga, *gnext = NULL;
@@ -840,7 +851,7 @@ glue_sub_attach()
 
                /* Find the top backend for this subordinate */
                be = ga->ga_be;
-               while ( be=LDAP_STAILQ_NEXT( be, be_next )) {
+               while ( (be=LDAP_STAILQ_NEXT( be, be_next )) != NULL ) {
                        slap_overinfo *oi;
                        slap_overinst *on;
                        glueinfo *gi;
@@ -898,16 +909,9 @@ glue_sub_add( BackendDB *be, int advert, int online )
                SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_GLUE_ADVERTISE;
 
        ga = ch_malloc( sizeof( glue_Addrec ));
-       ga->ga_next = NULL;
+       ga->ga_next = ga_list;
        ga->ga_be = be;
-       if ( ga_list ) {
-               glue_Addrec *g2 = ga_list;
-
-               for ( ; g2 && g2->ga_next; g2=g2->ga_next );
-               g2->ga_next = ga;
-       } else {
-               ga_list = ga;
-       }
+       ga_list = ga;
 
        if ( online )
                rc = glue_sub_attach();
@@ -935,8 +939,5 @@ glue_sub_init()
        glue.on_bi.bi_chk_referrals = glue_chk_referrals;
        glue.on_bi.bi_chk_controls = glue_chk_controls;
 
-       rc = overlay_register( &glue );
-       if ( rc ) return rc;
-
-       return glue_sub_attach();
+       return overlay_register( &glue );
 }
index 5718714c279cf0950d9881dcb17f32b55e3243d6..e2be24c8f8e771ed65433f7a64c576768d75848c 100644 (file)
@@ -393,7 +393,7 @@ static ConfigTable config_back_cf_table[] = {
                        "SUP labeledURI SINGLE-VALUE )", NULL, NULL },
        { "replica", "host or uri", 2, 0, 0, ARG_DB|ARG_MAGIC,
                &config_replica, "( OLcfgDbAt:0.7 NAME 'olcReplica' "
-                       "SUP labeledURI )", NULL, NULL },
+                       "SUP labeledURI X-ORDERED 'VALUES' )", NULL, NULL },
        { "replica-argsfile", NULL, 0, 0, 0, ARG_STRING,
                &replica_argsFile, "( OLcfgGlAt:43 NAME 'olcReplicaArgsFile' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
index 73699edf1d81b1bccef425ff171400e0f6e827ee..aa5c58af0a5d5a9d8e61d8cd3d3f8d19838418fe 100644 (file)
@@ -452,6 +452,8 @@ fe_op_bind( Operation *op, SlapReply *rs )
        }
 
        if( op->o_bd->be_bind ) {
+               op->o_conn->c_authz_cookie = NULL;
+
                rs->sr_err = (op->o_bd->be_bind)( op, rs );
 
                if ( rs->sr_err == 0 ) {
index 2b698fa1779ae7abb5067fee2cde715bdc742e1a..5ea673525445f0ad43abb2caa42f83cabcc2606f 100644 (file)
@@ -75,6 +75,7 @@ ch_realloc(
 
        if( size == 0 ) {
                ch_free( block );
+               return NULL;
        }
 
        ctx = slap_sl_context( block );
index b1e5b18dd6cac5a935ef4e2c9bdbb5adb46537b2..8d44c6c60e6295bffae06f8d941bd248f79b9104 100644 (file)
@@ -81,6 +81,7 @@ static void fp_getline_init(ConfigArgs *c);
 static int fp_parse_line(ConfigArgs *c);
 
 static char    *strtok_quote(char *line, char *sep, char **quote_ptr);
+static char *strtok_quote_ldif(char **line);
 
 ConfigArgs *
 new_config_args( BackendDB *be, const char *fname, int lineno, int argc, char **argv )
@@ -285,7 +286,7 @@ int config_set_vals(ConfigTable *Conf, ConfigArgs *c) {
                                c->log, c->msg, 0);
                        return(ARG_BAD_CONF);
                }
-               ptr = (void *)((char *)ptr + (int)Conf->arg_item);
+               ptr = (void *)((char *)ptr + (long)Conf->arg_item);
        } else if (arg_type & ARGS_POINTER) {
                ptr = Conf->arg_item;
        }
@@ -371,7 +372,7 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c)
                                ptr = c->bi->bi_private;
                        else
                                return 1;
-                       ptr = (void *)((char *)ptr + (int)cf->arg_item);
+                       ptr = (void *)((char *)ptr + (long)cf->arg_item);
                } else {
                        ptr = cf->arg_item;
                }
@@ -493,11 +494,87 @@ init_config_ocs( ConfigOCs *ocs ) {
        return 0;
 }
 
+/* Split an LDIF line into space-separated tokens. Words may be grouped
+ * by quotes. A quoted string may begin in the middle of a word, but must
+ * end at the end of the word (be followed by whitespace or EOS). Any other
+ * quotes are passed through unchanged. All other characters are passed
+ * through unchanged.
+ */
+static char *
+strtok_quote_ldif( char **line )
+{
+       char *beg, *ptr, *quote=NULL;
+       int inquote=0;
+
+       ptr = *line;
+
+       if ( !ptr || !*ptr )
+               return NULL;
+
+       while( isspace( *ptr )) ptr++;
+
+       if ( *ptr == '"' ) {
+               inquote = 1;
+               ptr++;
+       }
+
+       beg = ptr;
+
+       for (;*ptr;ptr++) {
+               if ( *ptr == '"' ) {
+                       if ( inquote && ( !ptr[1] || isspace(ptr[1]))) {
+                               *ptr++ = '\0';
+                               break;
+                       }
+                       inquote = 1;
+                       quote = ptr;
+                       continue;
+               }
+               if ( inquote )
+                       continue;
+               if ( isspace( *ptr )) {
+                       *ptr++ = '\0';
+                       break;
+               }
+       }
+       if ( quote ) {
+               while ( quote < ptr ) {
+                       *quote = quote[1];
+                       quote++;
+               }
+       }
+       if ( !*ptr ) {
+               *line = NULL;
+       } else {
+               while ( isspace( *ptr )) ptr++;
+               *line = ptr;
+       }
+       return beg;
+}
+
+static void
+config_parse_ldif( ConfigArgs *c )
+{
+       char *next;
+       c->tline = ch_strdup(c->line);
+       next = c->tline;
+
+       while ((c->argv[c->argc] = strtok_quote_ldif( &next )) != NULL) {
+               c->argc++;
+               if ( c->argc >= c->argv_size ) {
+                       char **tmp = ch_realloc( c->argv, (c->argv_size + ARGS_STEP) *
+                               sizeof( *c->argv ));
+                       c->argv = tmp;
+                       c->argv_size += ARGS_STEP;
+               }
+       }
+       c->argv[c->argc] = NULL;
+}
+
 int
 config_parse_vals(ConfigTable *ct, ConfigArgs *c, int valx)
 {
        int     rc = 0;
-       char    *saveline = NULL;
 
        snprintf( c->log, sizeof( c->log ), "%s: value #%d",
                ct->ad->ad_cname.bv_val, valx );
@@ -505,29 +582,19 @@ config_parse_vals(ConfigTable *ct, ConfigArgs *c, int valx)
        c->argv[0] = ct->ad->ad_cname.bv_val;
 
        if ( ( ct->arg_type & ARG_QUOTE ) && c->line[ 0 ] != '"' ) {
-               ber_len_t       len;
-
-               saveline = c->line;
-               len = strlen( c->line );
-               c->line = ch_malloc( len + STRLENOF( "\"\"" ) + 1 );
-               sprintf( c->line, "\"%s\"", saveline );
-       }
-
-       if ( fp_parse_line( c ) ) {
-               rc = 1;
+               c->argv[c->argc] = c->line;
+               c->argc++;
+               c->argv[c->argc] = NULL;
+               c->tline = NULL;
        } else {
-               rc = config_check_vals( ct, c, 1 );
-       }
-
-       if ( saveline ) {
-               ch_free( c->line );
-               c->line = saveline;
+               config_parse_ldif( c );
        }
+       rc = config_check_vals( ct, c, 1 );
+       ch_free( c->tline );
 
        if ( rc )
                rc = LDAP_CONSTRAINT_VIOLATION;
 
-       ch_free( c->tline );
        return rc;
 }
 
@@ -535,7 +602,6 @@ int
 config_parse_add(ConfigTable *ct, ConfigArgs *c)
 {
        int     rc = 0;
-       char    *saveline = NULL;
 
        snprintf( c->log, sizeof( c->log ), "%s: value #%d",
                ct->ad->ad_cname.bv_val, c->valx );
@@ -543,28 +609,17 @@ config_parse_add(ConfigTable *ct, ConfigArgs *c)
        c->argv[0] = ct->ad->ad_cname.bv_val;
 
        if ( ( ct->arg_type & ARG_QUOTE ) && c->line[ 0 ] != '"' ) {
-               ber_len_t       len;
-
-               saveline = c->line;
-               len = strlen( c->line );
-                       
-               c->line = ch_malloc( len + STRLENOF( "\"\"" ) + 1 );
-               sprintf( c->line, "\"%s\"", saveline );
-       }
-
-       if ( fp_parse_line( c ) ) {
-               rc = 1;
+               c->argv[c->argc] = c->line;
+               c->argc++;
+               c->argv[c->argc] = NULL;
+               c->tline = NULL;
        } else {
-               c->op = LDAP_MOD_ADD;
-               rc = config_add_vals( ct, c );
-       }
-
-       if ( saveline ) {
-               ch_free( c->line );
-               c->line = saveline;
+               config_parse_ldif( c );
        }
-
+       c->op = LDAP_MOD_ADD;
+       rc = config_add_vals( ct, c );
        ch_free( c->tline );
+
        return rc;
 }
 
index 5e249595602f463b53acb1853c6be5b16dc52480..4eddc8310b4bbbffdeb00b1ca033cf407177003f 100644 (file)
@@ -694,6 +694,74 @@ return_results:
        return rs->sr_err;
 }
 
+int
+slap_remove_control(
+       Operation       *op,
+       SlapReply       *rs,
+       int             ctrl,
+       BI_chk_controls fnc )
+{
+       int             i, j;
+
+       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 )
+                       {
+                               j = i;
+                       }
+               }
+
+               if ( j == -1 ) {
+                       rs->sr_err = LDAP_OTHER;
+                       break;
+               }
+
+               if ( fnc ) {
+                       (void)fnc( op, rs );
+               }
+
+               op->o_tmpfree( op->o_ctrls[ j ], op->o_tmpmemctx );
+
+               if ( i > 1 ) {
+                       AC_MEMCPY( &op->o_ctrls[ j ], &op->o_ctrls[ j + 1 ],
+                               ( i - j ) * sizeof( LDAPControl * ) );
+
+               } else {
+                       op->o_tmpfree( op->o_ctrls, op->o_tmpmemctx );
+                       op->o_ctrls = NULL;
+               }
+
+               op->o_ctrlflag[ ctrl ] = SLAP_CONTROL_IGNORED;
+
+               Debug( LDAP_DEBUG_ANY, "%s: "
+                       "non-critical control \"%s\" not supported; stripped.\n",
+                       op->o_log_prefix, slap_known_controls[ ctrl ], 0 );
+               /* fall thru */
+
+       case SLAP_CONTROL_IGNORED:
+       case SLAP_CONTROL_NONE:
+               rs->sr_err = SLAP_CB_CONTINUE;
+               break;
+
+       case SLAP_CONTROL_CRITICAL:
+               rs->sr_err = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
+               if ( fnc ) {
+                       (void)fnc( op, rs );
+               }
+               Debug( LDAP_DEBUG_ANY, "%s: "
+                       "critical control \"%s\" not supported.\n",
+                       op->o_log_prefix, slap_known_controls[ ctrl ], 0 );
+               break;
+
+       default:
+               /* handle all cases! */
+               assert( 0 );
+       }
+
+       return rs->sr_err;
+}
+
 #ifdef LDAP_DEVEL
 static int parseManageDIT (
        Operation *op,
@@ -892,48 +960,6 @@ static int parsePagedResults (
                goto done;
        }
 
-#if 0
-       /* defer cookie decoding/checks to backend... */
-       if ( cookie.bv_len ) {
-               PagedResultsCookie reqcookie;
-               if( cookie.bv_len != sizeof( reqcookie ) ) {
-                       /* bad cookie */
-                       rs->sr_text = "paged results cookie is invalid";
-                       rc = LDAP_PROTOCOL_ERROR;
-                       goto done;
-               }
-
-               AC_MEMCPY( &reqcookie, cookie.bv_val, sizeof( reqcookie ));
-
-               if ( reqcookie > op->o_pagedresults_state.ps_cookie ) {
-                       /* bad cookie */
-                       rs->sr_text = "paged results cookie is invalid";
-                       rc = LDAP_PROTOCOL_ERROR;
-                       goto done;
-
-               } else if ( reqcookie < op->o_pagedresults_state.ps_cookie ) {
-                       rs->sr_text = "paged results cookie is invalid or old";
-                       rc = LDAP_UNWILLING_TO_PERFORM;
-                       goto done;
-               }
-
-       } else {
-               /* Initial request.  Initialize state. */
-#if 0
-               if ( op->o_conn->c_pagedresults_state.ps_cookie != 0 ) {
-                       /* There's another pagedResults control on the
-                        * same connection; reject new pagedResults controls 
-                        * (allowed by RFC2696) */
-                       rs->sr_text = "paged results cookie unavailable; try later";
-                       rc = LDAP_UNWILLING_TO_PERFORM;
-                       goto done;
-               }
-#endif
-               op->o_pagedresults_state.ps_cookie = 0;
-               op->o_pagedresults_state.ps_count = 0;
-       }
-#endif
-
        ps = op->o_tmpalloc( sizeof(PagedResultsState), op->o_tmpmemctx );
        *ps = op->o_conn->c_pagedresults_state;
        ps->ps_size = size;
index 814024df74e49cb9f6ec1139ce498090e9c5fc9e..a0125a19fc1248ba7f919d56d4112b8515d75805 100644 (file)
@@ -1572,7 +1572,10 @@ slapd_daemon_task(
                ber_socket_t i;
                int ns, nwriters;
                int at;
-               ber_socket_t nfds, nrfds, nwfds;
+               ber_socket_t nfds;
+#if SLAP_EVENTS_ARE_INDEXED
+               ber_socket_t nrfds, nwfds;
+#endif
 #define SLAPD_EBADF_LIMIT 16
 
                time_t  now;
@@ -1915,6 +1918,10 @@ slapd_daemon_task(
 #endif
                         ) continue;
 
+                       /* Don't log internal wake events */
+                       if ( SLAP_EVENT_FD( i ) == wake_sds[0] )
+                               continue;
+
                        r = SLAP_EVENT_IS_READ( i );
                        w = SLAP_EVENT_IS_WRITE( i );
                        if ( r || w ) {
@@ -1936,6 +1943,10 @@ slapd_daemon_task(
                        if ( rc ) {
                                fd = SLAP_EVENT_FD( i );
 
+                               /* Ignore wake events, they were handled above */
+                               if ( fd == wake_sds[0] )
+                                       continue;
+
                                if( SLAP_EVENT_IS_WRITE( i ) ) {
                                        Debug( LDAP_DEBUG_CONNS,
                                                "daemon: write active on %d\n",
index a47d1c418f25e8432cd8a82d8f89913f1d5b29c1..05832ecd97f1d3d4c83f6b5a6d7176cd0e05054f 100644 (file)
@@ -73,7 +73,12 @@ LDAPRDN_validate( LDAPRDN rdn )
 
                        rc = slap_bv2ad( &ava->la_attr, &ad, &text );
                        if ( rc != LDAP_SUCCESS ) {
-                               return LDAP_INVALID_SYNTAX;
+                               rc = slap_bv2undef_ad( &ava->la_attr,
+                                       &ad, &text,
+                                       SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
+                               if ( rc != LDAP_SUCCESS ) {
+                                       return LDAP_INVALID_SYNTAX;
+                               }
                        }
 
                        ava->la_private = ( void * )ad;
@@ -132,7 +137,12 @@ LDAPDN_validate( LDAPDN dn )
 
                                rc = slap_bv2ad( &ava->la_attr, &ad, &text );
                                if ( rc != LDAP_SUCCESS ) {
-                                       return LDAP_INVALID_SYNTAX;
+                                       rc = slap_bv2undef_ad( &ava->la_attr,
+                                               &ad, &text,
+                                               SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
+                                       if ( rc != LDAP_SUCCESS ) {
+                                               return LDAP_INVALID_SYNTAX;
+                                       }
                                }
 
                                ava->la_private = ( void * )ad;
@@ -344,7 +354,12 @@ LDAPRDN_rewrite( LDAPRDN rdn, unsigned flags, void *ctx )
 
                        rc = slap_bv2ad( &ava->la_attr, &ad, &text );
                        if ( rc != LDAP_SUCCESS ) {
-                               return LDAP_INVALID_SYNTAX;
+                               rc = slap_bv2undef_ad( &ava->la_attr,
+                                       &ad, &text,
+                                       SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
+                               if ( rc != LDAP_SUCCESS ) {
+                                       return LDAP_INVALID_SYNTAX;
+                               }
                        }
                        
                        ava->la_private = ( void * )ad;
@@ -469,7 +484,12 @@ LDAPDN_rewrite( LDAPDN dn, unsigned flags, void *ctx )
 
                                rc = slap_bv2ad( &ava->la_attr, &ad, &text );
                                if ( rc != LDAP_SUCCESS ) {
-                                       return LDAP_INVALID_SYNTAX;
+                                       rc = slap_bv2undef_ad( &ava->la_attr,
+                                               &ad, &text,
+                                               SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
+                                       if ( rc != LDAP_SUCCESS ) {
+                                               return LDAP_INVALID_SYNTAX;
+                                       }
                                }
                                
                                ava->la_private = ( void * )ad;
@@ -1187,7 +1207,7 @@ dnExtractRdn(
 /*
  * We can assume the input is a prettied or normalized DN
  */
-int 
+ber_len_t
 dn_rdnlen(
        Backend         *be,
        struct berval   *dn_in )
index 6b4589730810492f39cd09979ae97816f7482bd6..ab5f17b7a72cdeca721a9ff64d37b98e92e571c4 100644 (file)
@@ -216,6 +216,15 @@ slap_init( int mode, const char *name )
                return 1;
        }
 
+       if ( glue_sub_init() ) {
+               ldap_debug |= 1;
+               Debug( LDAP_DEBUG_ANY,
+                   "%s: glue/subordinate init failed\n",
+                   name, 0, 0 );
+
+               return 1;
+       }
+
        if ( acl_init() ) {
                ldap_debug |= 1;
                Debug( LDAP_DEBUG_ANY,
index 81fbed49f46f3908b573d304eee901a0d1160e66..3f9b948f7762e7c82651037be4a27b88a7da8f72 100644 (file)
@@ -631,7 +631,7 @@ unhandled_option:;
                }
        }
 
-       if ( glue_sub_init( ) != 0 ) {
+       if ( glue_sub_attach( ) != 0 ) {
                Debug( LDAP_DEBUG_ANY,
                    "subordinate config error\n",
                    0, 0, 0 );
index ba5477b7f8f4845d6065d2822633212f59038c21..ca628ef5ff424a93f86a8b243407d6e93f351fc7 100644 (file)
@@ -885,6 +885,7 @@ int slap_mods_opattrs(
                        mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
                        mod->sml_op = mop;
                        mod->sml_flags = SLAP_MOD_INTERNAL;
+                       mod->sml_next = NULL;
                        BER_BVZERO( &mod->sml_type );
                        mod->sml_desc = slap_schema.si_ad_structuralObjectClass;
                        mod->sml_values =
@@ -920,6 +921,7 @@ int slap_mods_opattrs(
                                mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
                                mod->sml_op = mop;
                                mod->sml_flags = SLAP_MOD_INTERNAL;
+                               mod->sml_next = NULL;
                                BER_BVZERO( &mod->sml_type );
                                mod->sml_desc = slap_schema.si_ad_entryUUID;
                                mod->sml_values =
@@ -952,6 +954,7 @@ int slap_mods_opattrs(
                                mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
                                mod->sml_op = mop;
                                mod->sml_flags = SLAP_MOD_INTERNAL;
+                               mod->sml_next = NULL;
                                BER_BVZERO( &mod->sml_type );
                                mod->sml_desc = slap_schema.si_ad_creatorsName;
                                mod->sml_values =
@@ -981,6 +984,7 @@ int slap_mods_opattrs(
                                mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
                                mod->sml_op = mop;
                                mod->sml_flags = SLAP_MOD_INTERNAL;
+                               mod->sml_next = NULL;
                                BER_BVZERO( &mod->sml_type );
                                mod->sml_desc = slap_schema.si_ad_createTimestamp;
                                mod->sml_values =
@@ -999,6 +1003,7 @@ int slap_mods_opattrs(
                mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
                mod->sml_op = mop;
                mod->sml_flags = SLAP_MOD_INTERNAL;
+               mod->sml_next = NULL;
                BER_BVZERO( &mod->sml_type );
                mod->sml_desc = slap_schema.si_ad_entryCSN;
                mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
@@ -1022,6 +1027,7 @@ int slap_mods_opattrs(
                        mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
                        mod->sml_op = mop;
                        mod->sml_flags = SLAP_MOD_INTERNAL;
+                       mod->sml_next = NULL;
                        BER_BVZERO( &mod->sml_type );
                        mod->sml_desc = slap_schema.si_ad_modifiersName;
                        mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
@@ -1050,6 +1056,7 @@ int slap_mods_opattrs(
                        mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
                        mod->sml_op = mop;
                        mod->sml_flags = SLAP_MOD_INTERNAL;
+                       mod->sml_next = NULL;
                        BER_BVZERO( &mod->sml_type );
                        mod->sml_desc = slap_schema.si_ad_modifyTimestamp;
                        mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
index 2772d72711fb99387701221a70809497753c91c4..af3913b602fc935c4962e16eafc98ecc57b86d16 100644 (file)
@@ -236,10 +236,10 @@ oc_bvfind_undef( struct berval *ocname )
 
 static int
 oc_create_required(
-    ObjectClass                *soc,
-    char               **attrs,
+       ObjectClass             *soc,
+       char                    **attrs,
        int                     *op,
-    const char         **err )
+       const char              **err )
 {
        char            **attrs1;
        AttributeType   *sat;
@@ -267,7 +267,7 @@ oc_create_required(
                }
                /* Now delete duplicates from the allowed list */
                for ( satp = soc->soc_required; *satp; satp++ ) {
-                       i = at_find_in_list(*satp,soc->soc_allowed);
+                       i = at_find_in_list(*satp, soc->soc_allowed);
                        if ( i >= 0 ) {
                                at_delete_from_list(i, &soc->soc_allowed);
                        }
@@ -312,10 +312,10 @@ oc_create_allowed(
 
 static int
 oc_add_sups(
-    ObjectClass                *soc,
-    char                       **sups,
+       ObjectClass             *soc,
+       char                    **sups,
        int                     *op,
-    const char         **err )
+       const char              **err )
 {
        int             code;
        ObjectClass     *soc1;
@@ -594,22 +594,54 @@ oc_add(
                code = oc_add_sups( soc, soc->soc_sup_oids, &op, err );
        }
 
-       if ( code != 0 ) return code;
-       if( user && op ) return SLAP_SCHERR_CLASS_BAD_SUP;
+       if ( code != 0 ) {
+               goto done;
+       }
+
+       if ( user && op ) {
+               code = SLAP_SCHERR_CLASS_BAD_SUP;
+               goto done;
+       }
 
        code = oc_create_required( soc, soc->soc_at_oids_must, &op, err );
-       if ( code != 0 ) return code;
+       if ( code != 0 ) {
+               goto done;
+       }
 
        code = oc_create_allowed( soc, soc->soc_at_oids_may, &op, err );
-       if ( code != 0 ) return code;
+       if ( code != 0 ) {
+               goto done;
+       }
 
-       if( user && op ) return SLAP_SCHERR_CLASS_BAD_USAGE;
+       if ( user && op ) {
+               code = SLAP_SCHERR_CLASS_BAD_USAGE;
+               goto done;
+       }
 
-       if( !user ) soc->soc_flags |= SLAP_OC_HARDCODE;
+       if ( !user ) {
+               soc->soc_flags |= SLAP_OC_HARDCODE;
+       }
 
        code = oc_insert(soc,err);
-       if ( code == 0 && rsoc )
+done:;
+       if ( code != 0 ) {
+               if ( soc->soc_sups ) {
+                       ch_free( soc->soc_sups );
+               }
+
+               if ( soc->soc_required ) {
+                       ch_free( soc->soc_required );
+               }
+
+               if ( soc->soc_allowed ) {
+                       ch_free( soc->soc_allowed );
+               }
+
+               ch_free( soc );
+
+       } else if ( rsoc ) {
                *rsoc = soc;
+       }
        return code;
 }
 
index 0470d0d1bd228676f767d957052d1275599927b0..2cbda0046eaf84b1b94a1419d70f5a2da4406e66 100644 (file)
@@ -57,6 +57,7 @@ typedef struct log_info {
        int li_age;
        int li_cycle;
        struct re_s *li_task;
+       int li_success;
 } log_info;
 
 static ConfigDriver log_cf_gen;
@@ -64,7 +65,8 @@ static ConfigDriver log_cf_gen;
 enum {
        LOG_DB = 1,
        LOG_OPS,
-       LOG_PURGE
+       LOG_PURGE,
+       LOG_SUCCESS
 };
 
 static ConfigTable log_cfats[] = {
@@ -82,6 +84,10 @@ static ConfigTable log_cfats[] = {
                log_cf_gen, "( OLcfgOvAt:4.3 NAME 'olcAccessLogPurge' "
                        "DESC 'Log cleanup parameters' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+       { "logsuccess", NULL, 2, 2, 0, ARG_MAGIC|ARG_ON_OFF|LOG_SUCCESS,
+               log_cf_gen, "( OLcfgOvAt:4.4 NAME 'olcAccessLogSuccess' "
+                       "DESC 'Log successful ops only' "
+                       "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
        { NULL }
 };
 
@@ -91,7 +97,7 @@ static ConfigOCs log_cfocs[] = {
                "DESC 'Access log configuration' "
                "SUP olcOverlayConfig "
                "MUST olcAccessLogDB "
-               "MAY ( olcAccessLogOps $ olcAccessLogPurge ) )",
+               "MAY ( olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogSuccess ) )",
                        Cft_Overlay, log_cfats },
        { NULL }
 };
@@ -188,7 +194,7 @@ static struct {
                "SYNTAX OMsInteger "
                "SINGLE-VALUE )", &ad_reqResult },
        { "( " LOG_SCHEMA_AT ".7 NAME 'reqAuthzID' "
-               "DESC 'AUthorization ID of requestor' "
+               "DESC 'Authorization ID of requestor' "
                "EQUALITY distinguishedNameMatch "
                "SYNTAX OMsDN "
                "SINGLE-VALUE )", &ad_reqAuthzID },
@@ -556,6 +562,12 @@ log_cf_gen(ConfigArgs *c)
                        agebv.bv_len += cyclebv.bv_len;
                        value_add_one( &c->rvalue_vals, &agebv );
                        break;
+               case LOG_SUCCESS:
+                       if ( li->li_success )
+                               c->value_int = li->li_success;
+                       else
+                               rc = 1;
+                       break;
                }
                break;
        case LDAP_MOD_DELETE:
@@ -583,6 +595,9 @@ log_cf_gen(ConfigArgs *c)
                        li->li_age = 0;
                        li->li_cycle = 0;
                        break;
+               case LOG_SUCCESS:
+                       li->li_success = 0;
+                       break;
                }
                break;
        default:
@@ -625,6 +640,9 @@ log_cf_gen(ConfigArgs *c)
                                }
                        }
                        break;
+               case LOG_SUCCESS:
+                       li->li_success = c->value_int;
+                       break;
                }
                break;
        }
@@ -714,12 +732,15 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
        struct berval bv;
        char *ptr;
        BerVarray vals;
-       Operation op2;
+       Operation op2 = {0};
        SlapReply rs2 = {REP_RESULT};
 
        if ( rs->sr_type != REP_RESULT && rs->sr_type != REP_EXTENDED )
                return SLAP_CB_CONTINUE;
 
+       if ( li->li_success && rs->sr_err != LDAP_SUCCESS )
+               return SLAP_CB_CONTINUE;
+
        switch ( op->o_tag ) {
        case LDAP_REQ_ADD:              logop = LOG_EN_ADD; break;
        case LDAP_REQ_DELETE:   logop = LOG_EN_DELETE; break;
@@ -948,7 +969,14 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
        op2.ora_e = e;
        op2.o_callback = &nullsc;
 
+       if ( lo->mask & LOG_OP_WRITES ) {
+               slap_get_commit_csn( op, NULL, &bv );
+               attr_merge_one( e, slap_schema.si_ad_entryCSN, &bv, NULL );
+               slap_queue_csn( &op2, &bv );
+       }
+
        op2.o_bd->be_add( &op2, &rs2 );
+       slap_graduate_commit_csn( &op2 );
        entry_free( e );
 
        return SLAP_CB_CONTINUE;
@@ -967,6 +995,9 @@ accesslog_unbind( Operation *op, SlapReply *rs )
                SlapReply rs2 = {REP_RESULT};
                Entry *e;
 
+               if ( !( li->li_ops & LOG_OP_UNBIND ))
+                       return SLAP_CB_CONTINUE;
+
                e = accesslog_entry( op, LOG_EN_UNBIND );
                op2.o_hdr = op->o_hdr;
                op2.o_tag = LDAP_REQ_ADD;
@@ -997,7 +1028,7 @@ accesslog_abandon( Operation *op, SlapReply *rs )
        char buf[64];
        struct berval bv;
 
-       if ( !op->o_time )
+       if ( !op->o_time || !( li->li_ops & LOG_OP_ABANDON ))
                return SLAP_CB_CONTINUE;
 
        e = accesslog_entry( op, LOG_EN_ABANDON );
index 78549fbe26a80b00badb47ff69c219aeed8ea32d..73ae35a272b462ed67f5917d128e5b4e12f46899 100644 (file)
@@ -1205,6 +1205,42 @@ add_filter_attrs(
        }
 }
 
+/* NOTE: this is a quick workaround to let pcache minimally interact
+ * with pagedResults.  A more articulated solutions would be to
+ * perform the remote query without control and cache all results,
+ * performing the pagedResults search only within the client
+ * and the proxy.  This requires pcache to understand pagedResults. */
+static int
+proxy_cache_chk_controls(
+       Operation       *op,
+       SlapReply       *rs )
+{
+       const char      *non = "";
+       const char      *stripped = "";
+
+       switch( op->o_pagedresults ) {
+       case SLAP_CONTROL_NONCRITICAL:
+               non = "non-";
+               stripped = "; stripped";
+               /* fallthru */
+
+       case SLAP_CONTROL_CRITICAL:
+               Debug( LDAP_DEBUG_ANY, "%s: "
+                       "%scritical pagedResults control "
+                       "disabled with proxy cache%s.\n",
+                       op->o_log_prefix, non, stripped );
+               
+               slap_remove_control( op, rs, slap_cids.sc_pagedResults, NULL );
+               break;
+
+       default:
+               rs->sr_err = SLAP_CB_CONTINUE;
+               break;
+       }
+
+       return rs->sr_err;
+}
+
 static int
 proxy_cache_search(
        Operation       *op,
@@ -1241,6 +1277,9 @@ proxy_cache_search(
        Debug( LDAP_DEBUG_ANY, "query template of incoming query = %s\n",
                                        tempstr.bv_val, 0, 0 );
 
+       /* FIXME: cannot cache/answer requests with pagedResults control */
+       
+
        /* find attr set */
        attr_set = get_attr_set(op->ors_attrs, qm, cm->numattrsets);
 
@@ -2080,6 +2119,8 @@ int pcache_init()
        proxy_cache.on_bi.bi_db_destroy = proxy_cache_destroy;
        proxy_cache.on_bi.bi_op_search = proxy_cache_search;
 
+       proxy_cache.on_bi.bi_chk_controls = proxy_cache_chk_controls;
+
        proxy_cache.on_bi.bi_cf_ocs = pcocs;
 
        code = config_register_schema( pccfg, pcocs );
index 006631cb8a4dff972240fe430afca9df38653281..0d87840a166290f1b081f1b0f791b3d658088c9b 100644 (file)
@@ -119,7 +119,12 @@ static struct schema_info {
                "EQUALITY generalizedTimeMatch "
                "ORDERING generalizedTimeOrderingMatch "
                "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
-               "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
+               "SINGLE-VALUE "
+#if 0
+               /* Not until MANAGEDIT control is released */
+               "NO-USER-MODIFICATION "
+#endif
+               "USAGE directoryOperation )",
                &ad_pwdAccountLockedTime },
        {       "( 1.3.6.1.4.1.42.2.27.8.1.19 "
                "NAME ( 'pwdFailureTime' ) "
@@ -1060,6 +1065,10 @@ ppolicy_add(
        if ( ppolicy_restrict( op, rs ) != SLAP_CB_CONTINUE )
                return rs->sr_err;
 
+       /* If this is a replica, assume the master checked everything */
+       if ( be_shadow_update( op ))
+               return SLAP_CB_CONTINUE;
+
        /* Check for password in entry */
        if ((pa = attr_find( op->oq_add.rs_e->e_attrs,
                slap_schema.si_ad_userPassword )))
@@ -1126,7 +1135,7 @@ ppolicy_add(
                        }
                }
                /* If password aging is in effect, set the pwdChangedTime */
-               if (( pp.pwdMaxAge || pp.pwdMinAge ) && !be_shadow_update( op )) {
+               if ( pp.pwdMaxAge || pp.pwdMinAge ) {
                        struct berval timestamp;
                        char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
                        time_t now = slap_get_time();
@@ -1165,6 +1174,80 @@ ppolicy_modify( Operation *op, SlapReply *rs )
 
        if ( rc != LDAP_SUCCESS ) return SLAP_CB_CONTINUE;
 
+       /* If this is a replica, we may need to tweak some of the
+        * master's modifications. Otherwise, just pass it through.
+        */
+       if ( be_shadow_update( op )) {
+               Modifications **prev;
+               int got_del_grace = 0, got_del_lock = 0, got_pw = 0;
+               Attribute *a_grace, *a_lock;
+
+               a_grace = attr_find( e->e_attrs, ad_pwdGraceUseTime );
+               a_lock = attr_find( e->e_attrs, ad_pwdAccountLockedTime );
+
+               for( prev = &op->oq_modify.rs_modlist, ml = *prev; ml;
+                       prev = &ml->sml_next, ml = *prev ) {
+
+                       if ( ml->sml_desc == slap_schema.si_ad_userPassword )
+                               got_pw = 1;
+
+                       /* If we're deleting an attr that didn't exist,
+                        * drop this delete op
+                        */
+                       if ( ml->sml_op == LDAP_MOD_DELETE ) {
+                               int drop = 0;
+
+                               if ( ml->sml_desc == ad_pwdGraceUseTime ) {
+                                       got_del_grace = 1;
+                                       if ( !a_grace )
+                                               drop = 1;
+                               } else
+                               if ( ml->sml_desc == ad_pwdAccountLockedTime ) {
+                                       got_del_lock = 1;
+                                       if ( !a_lock )
+                                               drop = 1;
+                               }
+                               if ( drop ) {
+                                       *prev = ml->sml_next;
+                                       ml->sml_next = NULL;
+                                       slap_mods_free( ml, 1 );
+                               }
+                       }
+               }
+
+               /* If we're resetting the password, make sure grace and accountlock
+                * also get removed.
+                */
+               if ( got_pw ) {
+                       if ( a_grace && !got_del_grace ) {
+                               ml = (Modifications *) ch_malloc( sizeof( Modifications ) );
+                               ml->sml_op = LDAP_MOD_DELETE;
+                               ml->sml_flags = SLAP_MOD_INTERNAL;
+                               ml->sml_type.bv_val = NULL;
+                               ml->sml_desc = ad_pwdGraceUseTime;
+                               ml->sml_values = NULL;
+                               ml->sml_nvalues = NULL;
+                               ml->sml_next = NULL;
+                               *prev = ml;
+                               prev = &ml->sml_next;
+                       }
+                       if ( a_lock && !got_del_lock ) {
+                               ml = (Modifications *) ch_malloc( sizeof( Modifications ) );
+                               ml->sml_op = LDAP_MOD_DELETE;
+                               ml->sml_flags = SLAP_MOD_INTERNAL;
+                               ml->sml_type.bv_val = NULL;
+                               ml->sml_desc = ad_pwdAccountLockedTime;
+                               ml->sml_values = NULL;
+                               ml->sml_nvalues = NULL;
+                               ml->sml_next = NULL;
+                               *prev = ml;
+                       }
+               }
+               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+               be_entry_release_r( op, e );
+               return SLAP_CB_CONTINUE;
+       }
+
        /* Did we receive a password policy request control? */
        if ( op->o_ctrlflag[ppolicy_cid] ) {
                send_ctrl = 1;
@@ -1434,7 +1517,7 @@ ppolicy_modify( Operation *op, SlapReply *rs )
        }
 
 do_modify:
-       if ((pwmod) && (!be_shadow_update( op ))) {
+       if (pwmod) {
                struct berval timestamp;
                char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
                time_t now = slap_get_time();
@@ -1481,6 +1564,19 @@ do_modify:
                        modtail = mods;
                }
 
+               if (attr_find(e->e_attrs, ad_pwdAccountLockedTime )) {
+                       mods = (Modifications *) ch_malloc( sizeof( Modifications ) );
+                       mods->sml_op = LDAP_MOD_DELETE;
+                       mods->sml_flags = SLAP_MOD_INTERNAL;
+                       mods->sml_type.bv_val = NULL;
+                       mods->sml_desc = ad_pwdAccountLockedTime;
+                       mods->sml_values = NULL;
+                       mods->sml_nvalues = NULL;
+                       mods->sml_next = NULL;
+                       modtail->sml_next = mods;
+                       modtail = mods;
+               }
+
                /* Delete the pwdReset attribute, since it's being reset */
                if ((zapReset) && (attr_find(e->e_attrs, ad_pwdReset ))) {
                        mods = (Modifications *) ch_malloc( sizeof( Modifications ) );
@@ -1643,6 +1739,44 @@ ppolicy_parseCtrl(
        return LDAP_SUCCESS;
 }
 
+static int
+attrPretty(
+       Syntax *syntax,
+       struct berval *val,
+       struct berval *out,
+       void *ctx )
+{
+       AttributeDescription *ad = NULL;
+       const char *err;
+       int code;
+
+       code = slap_bv2ad( val, &ad, &err );
+       if ( !code ) {
+               ber_dupbv_x( out, &ad->ad_type->sat_cname, ctx );
+       }
+       return code;
+}
+
+static int
+attrNormalize(
+       slap_mask_t use,
+       Syntax *syntax,
+       MatchingRule *mr,
+       struct berval *val,
+       struct berval *out,
+       void *ctx )
+{
+       AttributeDescription *ad = NULL;
+       const char *err;
+       int code;
+
+       code = slap_bv2ad( val, &ad, &err );
+       if ( !code ) {
+               ber_str2bv_x( ad->ad_type->sat_oid, 0, 1, out, ctx );
+       }
+       return code;
+}
+
 static int
 ppolicy_db_init(
        BackendDB *be
@@ -1662,6 +1796,20 @@ ppolicy_db_init(
                                return code;
                        }
                }
+               {
+                       Syntax *syn;
+                       MatchingRule *mr;
+
+                       syn = ch_malloc( sizeof( Syntax ));
+                       *syn = *ad_pwdAttribute->ad_type->sat_syntax;
+                       syn->ssyn_pretty = attrPretty;
+                       ad_pwdAttribute->ad_type->sat_syntax = syn;
+
+                       mr = ch_malloc( sizeof( MatchingRule ));
+                       *mr = *ad_pwdAttribute->ad_type->sat_equality;
+                       mr->smr_normalize = attrNormalize;
+                       ad_pwdAttribute->ad_type->sat_equality = mr;
+               }
        }
 
        on->on_bi.bi_private = ch_calloc( sizeof(pp_info), 1 );
@@ -1738,6 +1886,7 @@ ppolicy_config(
                        return ( 1 );
                }
                pi->hash_passwords = 1;
+               return 0;
        }
        return SLAP_CONF_UNKNOWN;
 }
index de1f5a830c40a81d53407b99441ab30a7d5c5567..430e214ec2eb65c90972decce27261144fc2a1fa 100644 (file)
@@ -669,7 +669,10 @@ rwm_op_search( Operation *op, SlapReply *rs )
        char                    *text = NULL;
 
 #ifdef ENABLE_REWRITE
-       rc = rwm_op_dn_massage( op, rs, "searchDN" );
+       rc = rewrite_session_var_set( rwmap->rwm_rw, op->o_conn,
+               "searchFilter", op->ors_filterstr.bv_val );
+       if ( rc == LDAP_SUCCESS )
+               rc = rwm_op_dn_massage( op, rs, "searchDN" );
 #else /* ! ENABLE_REWRITE */
        rc = 1;
        rc = rwm_op_dn_massage( op, rs, &rc );
index 238cef6a5bfe441e061e76adf73131fcf045b4e4..05f56c447de41e0a5df8e2a814d1524c0ccdc816 100644 (file)
@@ -116,6 +116,7 @@ typedef struct syncprov_info_t {
        int             si_chkops;      /* checkpointing info */
        int             si_chktime;
        int             si_numops;      /* number of ops since last checkpoint */
+       int             si_nopres;      /* Skip present phase */
        time_t  si_chklast;     /* time of last checkpoint */
        Avlnode *si_mods;       /* entries being modified */
        sessionlog      *si_logs;
@@ -408,26 +409,29 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
        SlapReply frs = { REP_RESULT };
        int rc;
 
-       fop = *op;
+       /* Use basic parameters from syncrepl search, but use
+        * current op's threadctx / tmpmemctx
+        */
+       fop = *fc->fss->s_op;
+
+       fop.o_hdr = op->o_hdr;
+       fop.o_bd = op->o_bd;
+       fop.o_time = op->o_time;
+       fop.o_tincr = op->o_tincr;
 
        cb.sc_response = findbase_cb;
        cb.sc_private = fc;
 
-       fop.o_sync_mode &= SLAP_CONTROL_MASK;   /* turn off sync mode */
+       fop.o_sync_mode = 0;    /* turn off sync mode */
        fop.o_managedsait = SLAP_CONTROL_CRITICAL;
        fop.o_callback = &cb;
        fop.o_tag = LDAP_REQ_SEARCH;
        fop.ors_scope = LDAP_SCOPE_BASE;
-       fop.ors_deref = fc->fss->s_op->ors_deref;
        fop.ors_limit = NULL;
        fop.ors_slimit = 1;
        fop.ors_tlimit = SLAP_NO_LIMIT;
        fop.ors_attrs = slap_anlist_no_attrs;
        fop.ors_attrsonly = 1;
-       fop.ors_filter = fc->fss->s_op->ors_filter;
-       fop.ors_filterstr = fc->fss->s_op->ors_filterstr;
-
-       fop.o_req_ndn = fc->fss->s_op->o_req_ndn;
 
        fop.o_bd->bd_info = on->on_info->oi_orig;
        rc = fop.o_bd->be_search( &fop, &frs );
@@ -780,6 +784,7 @@ syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, Entry **e, int mod
        sop.o_bd = op->o_bd;
        sop.o_controls = op->o_controls;
        sop.o_private = op->o_private;
+       sop.o_callback = NULL;
 
        /* If queueing is allowed */
        if ( queue ) {
@@ -1046,6 +1051,7 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
                                "search base has changed" );
                        sprev->s_next = snext;
                        syncprov_drop_psearch( ss, 1 );
+                       ss = sprev;
                        continue;
                }
 
@@ -1693,6 +1699,8 @@ syncprov_detach_op( Operation *op, syncops *so )
                g2->ga_next = op2->o_groups;
                op2->o_groups = g2;
        }
+       /* Don't allow any further group caching */
+       op2->o_do_not_cache = 1;
 
        /* Add op2 to conn so abandon will find us */
        ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
@@ -1786,7 +1794,7 @@ syncprov_op_search( Operation *op, SlapReply *rs )
        slap_overinst           *on = (slap_overinst *)op->o_bd->bd_info;
        syncprov_info_t         *si = (syncprov_info_t *)on->on_bi.bi_private;
        slap_callback   *cb;
-       int gotstate = 0, nochange = 0, do_present = 1;
+       int gotstate = 0, nochange = 0, do_present;
        syncops *sop = NULL;
        searchstate *ss;
        sync_control *srs;
@@ -1800,6 +1808,8 @@ syncprov_op_search( Operation *op, SlapReply *rs )
                return rs->sr_err;
        }
 
+       do_present = si->si_nopres ? 0 : 1;
+
        srs = op->o_controls[slap_cids.sc_LDAPsync];
        op->o_managedsait = SLAP_CONTROL_NONCRITICAL;
 
@@ -2010,7 +2020,8 @@ syncprov_operational(
 
 enum {
        SP_CHKPT = 1,
-       SP_SESSL
+       SP_SESSL,
+       SP_NOPRES
 };
 
 static ConfigDriver sp_cf_gen;
@@ -2024,6 +2035,10 @@ static ConfigTable spcfg[] = {
                sp_cf_gen, "( OLcfgOvAt:1.2 NAME 'olcSpSessionlog' "
                        "DESC 'Session log size in ops' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
+       { "syncprov-nopresent", NULL, 2, 2, 0, ARG_ON_OFF|ARG_MAGIC|SP_NOPRES,
+               sp_cf_gen, "( OLcfgOvAt:1.3 NAME 'olcSpNoPresent' "
+                       "DESC 'Omit Present phase processing' "
+                       "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
        { NULL, NULL, 0, 0, 0, ARG_IGNORED }
 };
 
@@ -2032,7 +2047,7 @@ static ConfigOCs spocs[] = {
                "NAME 'olcSyncProvConfig' "
                "DESC 'SyncRepl Provider configuration' "
                "SUP olcOverlayConfig "
-               "MAY ( olcSpCheckpoint $ olcSpSessionlog ) )",
+               "MAY ( olcSpCheckpoint $ olcSpSessionlog $ olcSpNoPresent ) )",
                        Cft_Overlay, spcfg },
        { NULL, 0, NULL }
 };
@@ -2064,6 +2079,13 @@ sp_cf_gen(ConfigArgs *c)
                                rc = 1;
                        }
                        break;
+               case SP_NOPRES:
+                       if ( si->si_nopres ) {
+                               c->value_int = 1;
+                       } else {
+                               rc = 1;
+                       }
+                       break;
                }
                return rc;
        } else if ( c->op == LDAP_MOD_DELETE ) {
@@ -2078,6 +2100,12 @@ sp_cf_gen(ConfigArgs *c)
                        else
                                rc = LDAP_NO_SUCH_ATTRIBUTE;
                        break;
+               case SP_NOPRES:
+                       if ( si->si_nopres )
+                               si->si_nopres = 0;
+                       else
+                               rc = LDAP_NO_SUCH_ATTRIBUTE;
+                       break;
                }
                return rc;
        }
@@ -2109,6 +2137,9 @@ sp_cf_gen(ConfigArgs *c)
                sl->sl_size = size;
                }
                break;
+       case SP_NOPRES:
+               si->si_nopres = c->value_int;
+               break;
        }
        return rc;
 }
index d79433ca2090c97047d99287bbf69c1baa75f806..e110c3865fe2f411224fce6931c7d9a5ce57cfed 100644 (file)
@@ -168,8 +168,9 @@ LDAP_SLAPD_F (int) slap_bv2undef_ad LDAP_P((
        const char **text,
        unsigned proxied ));
 
-LDAP_SLAPD_F (int) slap_ad_undef_remove LDAP_P((
-       char *name ));
+LDAP_SLAPD_F (int) slap_ad_undef_promote LDAP_P((
+       char *name,
+       AttributeType *nat ));
 
 LDAP_SLAPD_F (AttributeDescription *) ad_find_tags LDAP_P((
        AttributeType *type,
@@ -394,6 +395,7 @@ LDAP_SLAPD_V(BackendInfo) slap_binfo[];
  */
 
 LDAP_SLAPD_F (int) glue_sub_init( void );
+LDAP_SLAPD_F (int) glue_sub_attach( void );
 LDAP_SLAPD_F (int) glue_sub_add( BackendDB *be, int advert, int online );
 LDAP_SLAPD_F (int) glue_sub_del( BackendDB *be );
 
@@ -574,6 +576,11 @@ LDAP_SLAPD_F (int) slap_find_control_id LDAP_P ((
        const char *oid, int *cid ));
 LDAP_SLAPD_F (int) slap_global_control LDAP_P ((
        Operation *op, const char *oid, int *cid ));
+LDAP_SLAPD_F (int) slap_remove_control LDAP_P((
+       Operation       *op,
+       SlapReply       *rs,
+       int             ctrl,
+       BI_chk_controls fnc ));
 
 /*
  * config.c
@@ -778,7 +785,7 @@ LDAP_SLAPD_F (int) dnExtractRdn LDAP_P((
 
 LDAP_SLAPD_F (int) rdn_validate LDAP_P(( struct berval * rdn ));
 
-LDAP_SLAPD_F (int) dn_rdnlen LDAP_P(( Backend *be, struct berval *dn ));
+LDAP_SLAPD_F (ber_len_t) dn_rdnlen LDAP_P(( Backend *be, struct berval *dn ));
 
 LDAP_SLAPD_F (void) build_new_dn LDAP_P((
        struct berval * new_dn,
index 335ae6384383890367ba754ff1d727da232f6dfe..d2d2facdad463f010490fff1a4da1d61ddec357a 100644 (file)
@@ -1397,6 +1397,12 @@ int slap_sasl_regexp_config( const char *match, const char *replace )
                "SASL match pattern %s could not be compiled by regexp engine\n",
                reg->sr_match, 0, 0 );
 
+#ifdef ENABLE_REWRITE
+       /* Dummy block to force symbol references in librewrite */
+       if ( slapMode == ( SLAP_SERVER_MODE|SLAP_TOOL_MODE )) {
+               rewrite_info_init( 0 );
+       }
+#endif
                return( LDAP_OTHER );
        }
 
index 1f1524ec13735e11bd16317d9bc31d9a147fe04c..c6b03a52915c5c80d7be942c97f1c4be7efa0f23 100644 (file)
 
 # Attribute Type Definitions
 
-attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber'
-       DESC 'An integer uniquely identifying a user in an administrative domain'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.1.1.1.1 NAME 'gidNumber'
-       DESC 'An integer uniquely identifying a group in an administrative domain'
-       EQUALITY integerMatch
-       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+# builtin
+#attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber'
+#      DESC 'An integer uniquely identifying a user in an administrative domain'
+#      EQUALITY integerMatch
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# builtin
+#attributetype ( 1.3.6.1.1.1.1.1 NAME 'gidNumber'
+#      DESC 'An integer uniquely identifying a group in an administrative domain'
+#      EQUALITY integerMatch
+#      SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
 attributetype ( 1.3.6.1.1.1.1.2 NAME 'gecos'
        DESC 'The GECOS field; the common name'
index 07fb1f0db647c3a16528b54156e8352f985e283d..42f03d8f260a5d828e2939a3c4d0b52208d8aba6 100644 (file)
@@ -1066,7 +1066,7 @@ uniqueMemberMatch(
        struct berval *asserted = (struct berval *) assertedValue;
        struct berval assertedDN = *asserted;
        struct berval assertedUID = BER_BVNULL;
-       struct berval valueDN = BER_BVNULL;
+       struct berval valueDN = *value;
        struct berval valueUID = BER_BVNULL;
        int approx = ((flags & SLAP_MR_EQUALITY_APPROX) == SLAP_MR_EQUALITY_APPROX);
 
@@ -1087,7 +1087,6 @@ uniqueMemberMatch(
        }
 
        if ( !BER_BVISEMPTY( value ) ) {
-               valueDN = *value;
 
                valueUID.bv_val = strrchr( valueDN.bv_val, '#' );
                if ( !BER_BVISNULL( &valueUID ) ) {
@@ -3430,8 +3429,8 @@ static slap_syntax_defs_rec syntax_defs[] = {
                SLAP_SYNTAX_HIDE, NULL, NULL},
 #endif
 
-       {"( 1.3.6.1.4.1.4203.666.2.6 DESC 'UUID' )",
-               SLAP_SYNTAX_HIDE, UUIDValidate, NULL},
+       {"( 1.3.6.1.1.16.1 DESC 'UUID' )",
+               0, UUIDValidate, NULL},
 
        {"( 1.3.6.1.4.1.4203.666.11.2.1 DESC 'CSN' )",
                SLAP_SYNTAX_HIDE, csnValidate, NULL},
@@ -3854,16 +3853,16 @@ static slap_mrule_defs_rec mrule_defs[] = {
                NULL, NULL,
                "integerMatch" },
 
-       {"( 1.3.6.1.4.1.4203.666.4.6 NAME 'UUIDMatch' "
-               "SYNTAX 1.3.6.1.4.1.4203.666.2.6 )",
-               SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL,
+       {"( 1.3.6.1.1.16.2 NAME 'UUIDMatch' "
+               "SYNTAX 1.3.6.1.1.16.1 )",
+               SLAP_MR_EQUALITY, NULL,
                NULL, UUIDNormalize, octetStringMatch,
                octetStringIndexer, octetStringFilter,
                NULL},
 
-       {"( 1.3.6.1.4.1.4203.666.4.7 NAME 'UUIDOrderingMatch' "
-               "SYNTAX 1.3.6.1.4.1.4203.666.2.6 )",
-               SLAP_MR_HIDE | SLAP_MR_ORDERING, NULL,
+       {"( 1.3.6.1.1.16.3 NAME 'UUIDOrderingMatch' "
+               "SYNTAX 1.3.6.1.1.16.1 )",
+               SLAP_MR_ORDERING, NULL,
                NULL, UUIDNormalize, octetStringOrderingMatch,
                octetStringIndexer, octetStringFilter,
                "UUIDMatch"},
index a9cfd1e05bdff7eb49988bbd198843245ccf6cae..7349628240966aa320d006b4b1e63dae89822060 100644 (file)
@@ -545,13 +545,13 @@ static struct slap_schema_ad_map {
                NULL, NULL,
                NULL, NULL, NULL, NULL, NULL,
                offsetof(struct slap_internal_schema, si_ad_entryDN) },
-       { "entryUUID", "( 1.3.6.1.4.1.4203.666.1.6 NAME 'entryUUID' "   
+       { "entryUUID", "( 1.3.6.1.1.16.4 NAME 'entryUUID' "   
                        "DESC 'UUID of the entry' "
                        "EQUALITY UUIDMatch "
                        "ORDERING UUIDOrderingMatch "
-                       "SYNTAX 1.3.6.1.4.1.4203.666.2.6 "
+                       "SYNTAX 1.3.6.1.1.16.1 "
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
-               NULL, SLAP_AT_HIDE|SLAP_AT_MANAGEABLE,
+               NULL, SLAP_AT_MANAGEABLE,
                NULL, NULL,
                NULL, NULL, NULL, NULL, NULL,
                offsetof(struct slap_internal_schema, si_ad_entryUUID) },
@@ -579,8 +579,9 @@ static struct slap_schema_ad_map {
 #ifdef LDAP_SUPERIOR_UUID
        { "superiorUUID", "( 1.3.6.1.4.1.4203.666.1.11 NAME 'superiorUUID' "   
                        "DESC 'UUID of the superior entry' "
-                       "EQUALITY octetStringMatch "
-                       "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64} "
+                       "EQUALITY UUIDMatch "
+                       "ORDERING UUIDOrderingMatch "
+                       "SYNTAX 1.3.6.1.1.16.1 "
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
                NULL, SLAP_AT_HIDE,
                NULL, NULL,
@@ -942,6 +943,26 @@ static struct slap_schema_ad_map {
                NULL, NULL,
                NULL, NULL, NULL, NULL, NULL,
                offsetof(struct slap_internal_schema, si_ad_uid) },
+       { "uidNumber", /* for ldapi:// */
+               "( 1.3.6.1.1.1.1.0 NAME 'uidNumber' "
+               "DESC 'An integer uniquely identifying a user "
+                               "in an administrative domain' "
+               "EQUALITY integerMatch "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
+               NULL, 0,
+               NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL,
+               offsetof(struct slap_internal_schema, si_ad_uidNumber) },
+       { "gidNumber", /* for ldapi:// */
+               "( 1.3.6.1.1.1.1.1 NAME 'gidNumber' "
+               "DESC 'An integer uniquely identifying a group "
+                               "in an administrative domain' "
+               "EQUALITY integerMatch "
+               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )",
+               NULL, 0,
+               NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL,
+               offsetof(struct slap_internal_schema, si_ad_gidNumber) },
        { "userPassword", "( 2.5.4.35 NAME 'userPassword' "
                        "DESC 'RFC2256/2307: password of user' "
                        "EQUALITY octetStringMatch "
index 43da09895764487fc5247648ba2ee75f15999d70..bf02fa366625a1aa6129bf8ab1d1273a57245e18 100644 (file)
@@ -911,6 +911,8 @@ struct slap_internal_schema {
        AttributeDescription *si_ad_name;
        AttributeDescription *si_ad_cn;
        AttributeDescription *si_ad_uid;
+       AttributeDescription *si_ad_uidNumber;
+       AttributeDescription *si_ad_gidNumber;
        AttributeDescription *si_ad_userPassword;
        AttributeDescription *si_ad_labeledURI;
 #ifdef SLAPD_AUTHPASSWD
@@ -2619,6 +2621,14 @@ typedef struct slap_conn {
 
        /* authorization backend */
        Backend *c_authz_backend;
+       void    *c_authz_cookie;
+#define SLAP_IS_AUTHZ_BACKEND( op )    \
+       ( (op)->o_bd != NULL \
+               && (op)->o_bd->be_private != NULL \
+               && (op)->o_conn != NULL \
+               && (op)->o_conn->c_authz_backend != NULL \
+               && ( (op)->o_bd->be_private == (op)->o_conn->c_authz_backend->be_private \
+                       || (op)->o_bd->be_private == (op)->o_conn->c_authz_cookie ) )
 
        AuthorizationInformation c_authz;
 
index 7e2b50e58d6608dd320a705fca687029e25b9e9c..13dfccc8825b317d9cb86178438d6395f526ab6a 100644 (file)
@@ -66,7 +66,7 @@ slapacl( int argc, char **argv )
        Connection              conn = { 0 };
        Listener                listener;
        char                    opbuf[OPERATION_BUFFER_SIZE];
-       Operation               *op;
+       Operation               *op = NULL;
        Entry                   e = { 0 }, *ep = &e;
        char                    *attr = NULL;
        int                     doclose = 0;
index bbdb5bb3e3556b8c5aa6f35df750c4682ef5177d..eb82e2da38502e6f50cbb0c4dbe139bc9e3582ed 100644 (file)
@@ -424,7 +424,7 @@ slap_tool_init(
                break;
        }
 
-       rc = glue_sub_init();
+       rc = glue_sub_attach();
 
        if ( rc != 0 ) {
                fprintf( stderr, "%s: subordinate configuration error\n", progname );
index 2fdf30b3b4cc8b815e0a7065beabe95c4499ee03..429638165d3516e79146d68f203d8dfaf832fe11 100644 (file)
@@ -41,6 +41,10 @@ struct nonpresent_entry {
        LDAP_LIST_ENTRY(nonpresent_entry) npe_link;
 };
 
+#define        SYNCDATA_DEFAULT        0       /* entries are plain LDAP entries */
+#define        SYNCDATA_ACCESSLOG      1       /* entries are accesslog format */
+#define        SYNCDATA_CHANGELOG      2       /* entries are changelog format */
+
 typedef struct syncinfo_s {
        struct slap_backend_db *si_be;
        struct re_s                     *si_re;
@@ -70,6 +74,7 @@ typedef struct syncinfo_s {
        int                                     si_tlimit;
        int                                     si_refreshDelete;
        int                                     si_refreshPresent;
+       int                                     si_syncdata;
        Avlnode                         *si_presentlist;
        LDAP                            *si_ld;
        LDAP_LIST_HEAD(np, nonpresent_entry) si_nonpresentlist;
@@ -79,6 +84,8 @@ typedef struct syncinfo_s {
 static int syncuuid_cmp( const void *, const void * );
 static void avl_ber_bvfree( void * );
 static void syncrepl_del_nonpresent( Operation *, syncinfo_t *, BerVarray );
+static int syncrepl_message_to_op(
+                                       syncinfo_t *, Operation *, LDAPMessage * );
 static int syncrepl_message_to_entry(
                                        syncinfo_t *, Operation *, LDAPMessage *,
                                        Modifications **, Entry **, int );
@@ -621,11 +628,18 @@ do_syncrep2(
                                                slap_parse_sync_cookie( &syncCookie, NULL );
                                        }
                                }
-                               if ( syncrepl_message_to_entry( si, op, msg,
+                               if ( si->si_syncdata ) {
+                                       entry = NULL;
+                                       modlist = NULL;
+                                       if ( syncrepl_message_to_op( si, op, msg ) == LDAP_SUCCESS &&
+                                               !BER_BVISNULL( &syncCookie.ctxcsn ) ) {
+                                               syncrepl_updateCookie( si, op, psub, &syncCookie );
+                                       }
+                               } else if ( syncrepl_message_to_entry( si, op, msg,
                                        &modlist, &entry, syncstate ) == LDAP_SUCCESS ) {
                                        rc_efree = syncrepl_entry( si, op, entry, &modlist,
                                                syncstate, &syncUUID, &syncCookie_req, &syncCookie.ctxcsn );
-                                       if ( !BER_BVISNULL( &syncCookie.octet_str ) )
+                                       if ( !BER_BVISNULL( &syncCookie.ctxcsn ) )
                                        {
                                                syncrepl_updateCookie( si, op, psub, &syncCookie );
                                        }
@@ -683,7 +697,7 @@ do_syncrep2(
                                                &syncCookie_req.ctxcsn, &syncCookie.ctxcsn,
                                                &text );
                                }
-                               if ( !BER_BVISNULL( &syncCookie.octet_str ) &&
+                               if ( !BER_BVISNULL( &syncCookie.ctxcsn ) &&
                                        match < 0 && err == LDAP_SUCCESS )
                                {
                                        syncrepl_updateCookie( si, op, psub, &syncCookie );
@@ -1025,6 +1039,275 @@ do_syncrepl(
        return NULL;
 }
 
+typedef struct logschema {
+       struct berval ls_dn;
+       struct berval ls_req;
+       struct berval ls_mod;
+       struct berval ls_newRdn;
+       struct berval ls_delRdn;
+       struct berval ls_newSup;
+} logschema;
+
+static logschema changelog_sc = {
+       BER_BVC("targetDN"),
+       BER_BVC("changeType"),
+       BER_BVC("changes"),
+       BER_BVC("newRDN"),
+       BER_BVC("deleteOldRDN"),
+       BER_BVC("newSuperior")
+};
+
+static logschema accesslog_sc = {
+       BER_BVC("reqDN"),
+       BER_BVC("reqType"),
+       BER_BVC("reqMod"),
+       BER_BVC("reqNewRDN"),
+       BER_BVC("reqDeleteOldRDN"),
+       BER_BVC("reqNewSuperior")
+};
+
+static slap_verbmasks modops[] = {
+       { BER_BVC("add"), LDAP_REQ_ADD },
+       { BER_BVC("delete"), LDAP_REQ_DELETE },
+       { BER_BVC("modify"), LDAP_REQ_MODIFY },
+       { BER_BVC("modrdn"), LDAP_REQ_MODRDN},
+       { BER_BVNULL, 0 }
+};
+
+static Modifications *
+syncrepl_accesslog_mods(
+       syncinfo_t *si,
+       struct berval *vals
+)
+{
+       char *colon;
+       const char *text;
+       AttributeDescription *ad;
+       struct berval bv, bv2;
+       short op;
+       Modifications *mod = NULL, *modlist = NULL, **modtail;
+       int i;
+
+       modtail = &modlist;
+
+       for (i=0; !BER_BVISNULL( &vals[i] ); i++) {
+               ad = NULL;
+               bv = vals[i];
+
+               colon = strchr( bv.bv_val, ':' );
+               if ( !colon )
+                       continue;       /* invalid */
+               bv.bv_len = colon - bv.bv_val;
+               if ( slap_bv2ad( &bv, &ad, &text )) {
+                       /* Invalid */
+                       continue;
+               }
+               /* Ignore dynamically generated attrs */
+               if ( ad->ad_type->sat_flags & SLAP_AT_DYNAMIC )
+                       continue;
+               /* Ignore excluded attrs */
+               if ( ldap_charray_inlist( si->si_exattrs,
+                       ad->ad_type->sat_cname.bv_val ))
+                       continue;
+
+               switch(colon[1]) {
+               case '+':       op = LDAP_MOD_ADD; break;
+               case '-':       op = LDAP_MOD_DELETE; break;
+               case '=':       op = LDAP_MOD_REPLACE; break;
+               case '#':       op = LDAP_MOD_INCREMENT; break;
+               default:        continue;
+               }
+
+               if ( !mod || ad != mod->sml_desc || op != mod->sml_op ) {
+                       mod = (Modifications *) ch_malloc( sizeof( Modifications ));
+                       mod->sml_flags = 0;
+                       mod->sml_op = op;
+                       mod->sml_next = NULL;
+                       mod->sml_desc = ad;
+                       mod->sml_type = ad->ad_cname;
+                       mod->sml_values = NULL;
+                       mod->sml_nvalues = NULL;
+
+                       *modtail = mod;
+                       modtail = &mod->sml_next;
+               }
+               bv.bv_val = colon + 3;
+               bv.bv_len = vals[i].bv_len - ( bv.bv_val - vals[i].bv_val );
+               ber_dupbv( &bv2, &bv );
+               ber_bvarray_add( &mod->sml_values, &bv2 );
+       }
+       return modlist;
+}
+
+static Modifications *
+syncrepl_changelog_mods(
+       syncinfo_t *si,
+       struct berval *vals
+)
+{
+       return NULL;    /* FIXME */
+}
+
+static int
+syncrepl_message_to_op(
+       syncinfo_t      *si,
+       Operation       *op,
+       LDAPMessage     *msg
+)
+{
+       BerElement      *ber = NULL;
+       Modifications   *modlist = NULL;
+       logschema *ls;
+       SlapReply rs = { REP_RESULT };
+       slap_callback cb = { NULL, null_callback, NULL, NULL };
+
+       const char      *text;
+       char txtbuf[SLAP_TEXT_BUFLEN];
+       size_t textlen = sizeof txtbuf;
+
+       struct berval   bdn, dn = BER_BVNULL, ndn;
+       struct berval   bv, *bvals = NULL;
+       struct berval   rdn = BER_BVNULL, sup = BER_BVNULL,
+               prdn = BER_BVNULL, nrdn = BER_BVNULL,
+               psup = BER_BVNULL, nsup = BER_BVNULL;
+       int             rc, deleteOldRdn = 0;
+
+       if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_ENTRY ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "Message type should be entry (%d)", ldap_msgtype( msg ), 0, 0 );
+               return -1;
+       }
+
+       if ( si->si_syncdata == SYNCDATA_ACCESSLOG )
+               ls = &accesslog_sc;
+       else
+               ls = &changelog_sc;
+
+       rc = ldap_get_dn_ber( si->si_ld, msg, &ber, &bdn );
+
+       if ( rc != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "syncrepl_message_to_op : dn get failed (%d)", rc, 0, 0 );
+               return rc;
+       }
+
+       op->o_tag = LBER_DEFAULT;
+
+       while (( rc = ldap_get_attribute_ber( si->si_ld, msg, ber, &bv, &bvals ))
+               == LDAP_SUCCESS ) {
+               if ( bv.bv_val == NULL )
+                       break;
+
+               if ( !ber_bvstrcasecmp( &bv, &ls->ls_dn )) {
+                       bdn = bvals[0];
+                       dnPrettyNormal( NULL, &bdn, &dn, &ndn, op->o_tmpmemctx );
+                       ber_dupbv( &op->o_req_dn, &dn );
+                       ber_dupbv( &op->o_req_ndn, &ndn );
+                       slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
+                       slap_sl_free( dn.bv_val, op->o_tmpmemctx );
+               } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_req )) {
+                       int i = verb_to_mask( bvals[0].bv_val, modops );
+                       if ( i < 0 ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "syncrepl_message_to_op : unknown op %s",
+                                       bvals[0].bv_val, 0, 0 );
+                               ch_free( bvals );
+                               rc = -1;
+                               goto done;
+                       }
+                       op->o_tag = modops[i].mask;
+               } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_mod )) {
+                       /* Parse attribute into modlist */
+                       if ( si->si_syncdata == SYNCDATA_ACCESSLOG )
+                               modlist = syncrepl_accesslog_mods( si, bvals );
+                       else
+                               modlist = syncrepl_changelog_mods( si, bvals );
+               } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_newRdn )) {
+                       rdn = bvals[0];
+               } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_delRdn )) {
+                       if ( !ber_bvstrcasecmp( &slap_true_bv, bvals ))
+                               deleteOldRdn = 1;
+               } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_newSup )) {
+                       sup = bvals[0];
+               }
+               ch_free( bvals );
+       }
+
+       /* If we didn't get a mod type or a target DN, bail out */
+       if ( op->o_tag == LBER_DEFAULT || BER_BVISNULL( &dn )) {
+               rc = -1;
+               goto done;
+       }
+
+       op->o_callback = &cb;
+
+       switch( op->o_tag ) {
+       case LDAP_REQ_ADD:
+       case LDAP_REQ_MODIFY:
+               /* If we didn't get required data, bail */
+               if ( !modlist ) goto done;
+
+               rc = slap_mods_check( modlist, &text, txtbuf, textlen, NULL );
+
+               if ( rc != LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_op: mods check (%s)\n",
+                               text, 0, 0 );
+                       goto done;
+               }
+
+               if ( op->o_tag == LDAP_REQ_ADD ) {
+                       op->ora_e = ( Entry * ) ch_calloc( 1, sizeof( Entry ) );
+                       op->ora_e->e_name = op->o_req_dn;
+                       op->ora_e->e_nname = op->o_req_ndn;
+                       rc = slap_mods2entry( modlist, &op->ora_e, 1, 0, &text, txtbuf, textlen);
+                       if( rc != LDAP_SUCCESS ) {
+                               Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_op: mods2entry (%s)\n",
+                                       text, 0, 0 );
+                       } else {
+                               rc = op->o_bd->be_add( op, &rs );
+                       }
+                       be_entry_release_w( op, op->ora_e );
+               } else {
+                       op->orm_modlist = modlist;
+                       rc = op->o_bd->be_modify( op, &rs );
+               }
+               break;
+       case LDAP_REQ_MODRDN:
+               if ( BER_BVISNULL( &rdn )) goto done;
+
+               if ( rdnPretty( NULL, &rdn, &prdn, NULL ))
+                       goto done;
+               if ( rdnNormalize( 0, NULL, NULL, &rdn, &nrdn, NULL ))
+                       goto done;
+               if ( !BER_BVISNULL( &sup )) {
+                       if ( dnPrettyNormal( NULL, &sup, &psup, &nsup, NULL ))
+                               goto done;
+                       op->orr_newSup = &psup;
+                       op->orr_nnewSup = &nsup;
+               }
+               op->orr_newrdn = prdn;
+               op->orr_nnewrdn = nrdn;
+               op->orr_deleteoldrdn = deleteOldRdn;
+               rc = op->o_bd->be_modrdn( op, &rs );
+               break;
+       }
+done:
+       if ( modlist )
+               slap_mods_free( modlist, op->o_tag != LDAP_REQ_ADD );
+       if ( !BER_BVISNULL( &rdn )) {
+               if ( !BER_BVISNULL( &nsup ))
+                       ch_free( nsup.bv_val );
+               if ( !BER_BVISNULL( &psup ))
+                       ch_free( psup.bv_val );
+               if ( !BER_BVISNULL( &nrdn ))
+                       ch_free( nrdn.bv_val );
+               if ( !BER_BVISNULL( &prdn ))
+                       ch_free( prdn.bv_val );
+       }
+       ber_free ( ber, 0 );
+       return rc;
+}
+
 static int
 syncrepl_message_to_entry(
        syncinfo_t      *si,
@@ -2254,6 +2537,7 @@ syncinfo_free( syncinfo_t *sie )
 #define RETRYSTR               "retry"
 #define SLIMITSTR              "sizelimit"
 #define TLIMITSTR              "timelimit"
+#define SYNCDATASTR            "syncdata"
 
 /* FIXME: undocumented */
 #define OLDAUTHCSTR            "bindprincipal"
@@ -2291,6 +2575,13 @@ static struct {
        { BER_BVNULL, 0 }
 };
 
+static slap_verbmasks datamodes[] = {
+       { BER_BVC("default"), SYNCDATA_DEFAULT },
+       { BER_BVC("accesslog"), SYNCDATA_ACCESSLOG },
+       { BER_BVC("changelog"), SYNCDATA_CHANGELOG },
+       { BER_BVNULL, 0 }
+};
+
 static int
 parse_syncrepl_line(
        char            **cargv,
@@ -2338,6 +2629,8 @@ parse_syncrepl_line(
                                        STRLENOF( FILTERSTR "=" ) ) )
                {
                        val = cargv[ 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 ], SEARCHBASESTR "=",
                                        STRLENOF( SEARCHBASESTR "=" ) ) )
@@ -2565,6 +2858,11 @@ parse_syncrepl_line(
                {
                        val = cargv[ i ] + STRLENOF( TLIMITSTR "=" );
                        si->si_tlimit = atoi( val );
+               } else if ( !strncasecmp( cargv[ i ], SYNCDATASTR "=",
+                                       STRLENOF( SYNCDATASTR "=" ) ) )
+               {
+                       val = cargv[ 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 ] );
@@ -2758,6 +3056,13 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv )
                ptr = lutil_strcopy( ptr, " " TLIMITSTR "=" );
                ptr += sprintf( ptr, "%d", si->si_tlimit );
        }
+
+       if ( si->si_syncdata ) {
+               if ( enum_to_verb( datamodes, si->si_syncdata, &bc ) >= 0 ) {
+                       ptr = lutil_strcopy( ptr, " " SYNCDATASTR "=" );
+                       ptr = lutil_strcopy( ptr, bc.bv_val );
+               }
+       }
        bc.bv_len = ptr - buf;
        bc.bv_val = buf;
        ber_dupbv( bv, &bc );
index 71934ce59efc95a1555eb6720e3063d7254a51c9..6fe2e4035e92b3a418d1a7f47551907202a6cfc5 100644 (file)
@@ -459,7 +459,7 @@ parse_replica_line(
                ri->ri_port = atoi( hp );
            }
            if ( ri->ri_port <= 0 ) {
-               ri->ri_port = 0;
+               ri->ri_port = LDAP_PORT;
            }
            ri->ri_hostname = strdup( val );
            gots |= GOT_HOST;
index 7a709487834f9d410c4c6b059079f59a42427a36..3633732e5f6cf8a4bc968bef09a7b81a598143c2 100644 (file)
@@ -321,7 +321,7 @@ get_repl_hosts(
        if ( ldif_parse_line( line, &type, &value, &len ) < 0 ) {
            return( NULL );
        }
-       port = 0;
+       port = LDAP_PORT;
        if (( p = strchr( value, ':' )) != NULL ) {
            *p = '\0';
            p++;
@@ -544,11 +544,18 @@ Re_write(
     }
 
     if ( ri != NULL ) {                /* write a single "replica:" line */
-       if ( fprintf( fp, "replica: %s:%d\n", ri->ri_hostname,
-               ri->ri_port ) < 0 ) {
+       if ( ri->ri_port != 0 ) {
+           rc = fprintf( fp, "replica: %s:%d\n", ri->ri_hostname,
+                   ri->ri_port );
+       } else {
+           rc = fprintf( fp, "replica: %s\n", ri->ri_hostname );
+       }
+       if ( rc < 0 ) {
            rc = -1;
            goto bad;
        }
+       rc = 0;
+
     } else {                   /* write multiple "replica:" lines */
        for ( i = 0; re->re_replicas && re->re_replicas[ i ].rh_hostname != NULL; i++ ) {
            if ( fprintf( fp, "replica: %s:%d\n",
index 8a1605e6169d7ae89098d03a556db3cfba84e8cc..a01e0516dce726f122aac918ef238fc2534c6b51 100644 (file)
@@ -52,7 +52,7 @@ replicate(
     Ri         *ri = (Ri *) ri_arg;
 
     Debug( LDAP_DEBUG_ARGS, "begin replication thread for %s:%d\n",
-           ((Ri *)ri)->ri_hostname, ((Ri *)ri)->ri_port, 0 );
+           ri->ri_hostname, ri->ri_port, 0 );
 
     ri->ri_process( ri );
 
index e53f1a357d63d8ae4618981a23298101a904e80e..e781c717d19b151d58af67d9b82ee490aebe6657 100644 (file)
@@ -4,6 +4,27 @@ objectClass: dcObject
 o: Example, Inc.
 dc: example
 
+dn: ou=Groups,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Groups
+
+dn: cn=All,ou=Groups,dc=example,dc=com
+objectClass: groupOfNames
+cn: All
+member: uid=bjorn,ou=People,dc=example,dc=com
+member: uid=bjensen,ou=People,dc=example,dc=com
+
+dn: cn=ITD,ou=Groups,dc=example,dc=com
+objectClass: groupOfNames
+cn: ITD
+member: uid=bjorn,ou=People,dc=example,dc=com
+
+dn: uid=proxy,ou=Groups,dc=example,dc=com
+objectClass: inetOrgPerson
+cn: Proxy
+sn: Proxy
+uid: proxy
+
 dn: ou=People,dc=example,dc=com
 objectClass: organizationalUnit
 ou: People
@@ -28,24 +49,3 @@ cn: Proxy
 sn: Proxy
 uid: proxy
 
-dn: ou=Groups,dc=example,dc=com
-objectClass: organizationalUnit
-ou: Groups
-
-dn: cn=All,ou=Groups,dc=example,dc=com
-objectClass: groupOfNames
-cn: All
-member: uid=bjorn,ou=People,dc=example,dc=com
-member: uid=bjensen,ou=People,dc=example,dc=com
-
-dn: cn=ITD,ou=Groups,dc=example,dc=com
-objectClass: groupOfNames
-cn: ITD
-member: uid=bjorn,ou=People,dc=example,dc=com
-
-dn: uid=proxy,ou=Groups,dc=example,dc=com
-objectClass: inetOrgPerson
-cn: Proxy
-sn: Proxy
-uid: proxy
-
index 7032b4db04679b88555b9963e330ca0a68b62945..eabb0c562e5e3436c98b921e06da1a0ab16c5307 100644 (file)
@@ -137,57 +137,6 @@ pager: +1 313 555 2844
 facsimileTelephoneNumber: +1 313 555 9700
 telephoneNumber: +1 313 555 5331
 
-dn: ou=Groups,dc=example,dc=com
-objectClass: organizationalUnit
-ou: Groups
-
-dn: cn=All Staff,ou=Groups,dc=example,dc=com
-member: cn=Manager,dc=example,dc=com
-member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=exam
- ple,dc=com
-member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
-member: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc
- =com
-member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
-member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
-member: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=exa
- mple,dc=com
-member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
-member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
-member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
-member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=exampl
- e,dc=com
-owner: cn=Manager,dc=example,dc=com
-cn: All Staff
-description: Everyone in the sample data
-objectClass: groupOfNames
-
-dn: cn=Alumni Assoc Staff,ou=Groups,dc=example,dc=com
-member: cn=Manager,dc=example,dc=com
-member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
-member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
-member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
-member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
-member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
-member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
-owner: cn=Manager,dc=example,dc=com
-description: All Alumni Assoc Staff
-cn: Alumni Assoc Staff
-objectClass: groupOfNames
-
-dn: cn=ITD Staff,ou=Groups,dc=example,dc=com
-owner: cn=Manager,dc=example,dc=com
-description: All ITD Staff
-cn: ITD Staff
-objectClass: groupOfUniqueNames
-uniqueMember: cn=Manager,dc=example,dc=com
-uniqueMember: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=
- example,dc=com
-uniqueMember: cn=James A Jones 2,ou=Information Technology Division,ou=People,
- dc=example,dc=com
-uniqueMember: cn=John Doe,ou=Information Technology Division,ou=People,dc=exam
- ple,dc=com
-
 dn: ou=Information Technology Division,ou=People,dc=example,dc=com
 objectClass: organizationalUnit
 ou: Information Technology Division
@@ -408,3 +357,54 @@ pager: +1 313 555 6573
 facsimileTelephoneNumber: +1 313 555 4544
 telephoneNumber: +1 313 555 9394
 
+dn: ou=Groups,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Groups
+
+dn: cn=All Staff,ou=Groups,dc=example,dc=com
+member: cn=Manager,dc=example,dc=com
+member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=exam
+ ple,dc=com
+member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc
+ =com
+member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=exa
+ mple,dc=com
+member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=exampl
+ e,dc=com
+owner: cn=Manager,dc=example,dc=com
+cn: All Staff
+description: Everyone in the sample data
+objectClass: groupOfNames
+
+dn: cn=Alumni Assoc Staff,ou=Groups,dc=example,dc=com
+member: cn=Manager,dc=example,dc=com
+member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
+owner: cn=Manager,dc=example,dc=com
+description: All Alumni Assoc Staff
+cn: Alumni Assoc Staff
+objectClass: groupOfNames
+
+dn: cn=ITD Staff,ou=Groups,dc=example,dc=com
+owner: cn=Manager,dc=example,dc=com
+description: All ITD Staff
+cn: ITD Staff
+objectClass: groupOfUniqueNames
+uniqueMember: cn=Manager,dc=example,dc=com
+uniqueMember: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=
+ example,dc=com
+uniqueMember: cn=James A Jones 2,ou=Information Technology Division,ou=People,
+ dc=example,dc=com
+uniqueMember: cn=John Doe,ou=Information Technology Division,ou=People,dc=exam
+ ple,dc=com
+
index 2043d8fd68212393a55a972f56e1c2941b707a2a..8b2642e2f950f7faaec79ba2cbd5f62f2196c568 100644 (file)
@@ -19,8 +19,9 @@ USAGE="$0 [-b <backend>] [-c] [-k] [-p] [-u] [-w] <script>"
 SRCDIR="@srcdir@"
 TOPSRCDIR="@top_srcdir@"
 LN_S="@LN_S@"
+EGREP_CMD="@EGREP@"
 
-export SRCDIR TOPSRCDIR LN_S
+export SRCDIR TOPSRCDIR LN_S EGREP_CMD
 
 # backends
 AC_bdb=@BUILD_BDB@
@@ -33,7 +34,6 @@ AC_relay=relay@BUILD_RELAY@
 AC_sql=sql@BUILD_SQL@
 
 # overlays
-AC_glue=glue@BUILD_GLUE@
 AC_pcache=pcache@BUILD_PROXYCACHE@
 AC_ppolicy=ppolicy@BUILD_PPOLICY@
 AC_refint=refint@BUILD_REFINT@
@@ -51,7 +51,7 @@ 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_glue AC_pcache AC_ppolicy AC_refint AC_retcode AC_rwm AC_unique AC_syncprov
+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
 
index 5d7558c300c14d2e2ec59adb0daf85f4dad7a4cf..2d6023842e9795bd02dd7eee64a826f099d8709a 100755 (executable)
@@ -15,4 +15,4 @@
 #
 # Strip comments
 #
-egrep -iv '^#'
+grep -v '^#'
index 1f78c01ba305b8e338c5bb3797542c4cfe6adb42..58ce5214f4cdc50765ef1bca53d31e997b0d9f40 100755 (executable)
@@ -41,7 +41,6 @@ sed -e "s/@BACKEND@/${BACKEND}/"                      \
        -e "s/^#${AC_relay}#//"                         \
        -e "s/^#${AC_sql}#//"                           \
                -e "s/^#${RDBMS}#//"                    \
-       -e "s/^#${AC_glue}#//"                          \
        -e "s/^#${AC_pcache}#//"                        \
        -e "s/^#${AC_ppolicy}#//"                       \
        -e "s/^#${AC_refint}#//"                        \
index 6439908d002a8b884f8dd2299243728bf4fd9868..8c7ca24abb7d4d9545ec0c1def74eaf24dd21cbf 100755 (executable)
@@ -14,7 +14,7 @@
 ## <http://www.OpenLDAP.org/license.html>.
 
 if test $# -eq 0 ; then
-       SRCDIR="."
+       test -z "$SRCDIR" && SRCDIR="."
 else
        SRCDIR=$1; shift
 fi
@@ -25,17 +25,24 @@ fi
 echo "running defines.sh $SRCDIR $BACKEND"
 . $SRCDIR/scripts/defines.sh
 
-echo "Cleaning up in $DBDIR..."
-
-rm -f $DBDIR/[!C]*
+if test -d "$TESTDIR"; then
+       echo "Cleaning up in $TESTDIR..."
+       /bin/rm -rf testrun/db.*
+fi
+mkdir -p $TESTDIR
 
-echo "Starting slapd on TCP/IP port $PORT..."
-$SLAPD -f $PASSWDCONF -h $MASTERURI -d $LVL $TIMING > $MASTERLOG 2>&1 &
+echo "Starting slapd on TCP/IP port $PORT1..."
+$SLAPD -f $PASSWDCONF -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 &
 PID=$!
+if test ${WAIT-0} != 0 ; then
+    echo PID $PID
+    read foo
+fi
+KILLPIDS="$PID"
 
 echo "Testing slapd searching..."
 for i in 0 1 2 3 4 5; do
-       $LDAPSEARCH -L -b "$BASEDN" -h $LOCALHOST -p $PORT \
+       $LDAPSEARCH -L -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
                'objectclass=*' > /dev/null 2>&1
        RC=$?
        if test $RC = 1 ; then
@@ -46,66 +53,71 @@ done
 
 if test $RC != 0 ; then
        echo "ldapsearch failed!"
-       kill -HUP $PID
+       test "$KILLSERVERS" != no && kill -HUP $KILLPIDS
        exit $RC
 fi
 
 cat /dev/null > $TESTOUT
 
 echo "Testing base suffix searching..."
-$LDAPSEARCH -L -S "" -b "$BASEDN" -s base -h $LOCALHOST -p $PORT \
+$LDAPSEARCH -L -S "" -b "$BASEDN" -s base -h $LOCALHOST -p $PORT1 \
        '(objectclass=*)' >> $TESTOUT 2>&1
+RC=$?
 if test $RC != 0 ; then
        echo "ldapsearch failed!"
-       kill -HUP $PID
+       test "$KILLSERVERS" != no && kill -HUP $KILLPIDS
        exit $RC
 fi
 
 echo " ------------ " >> $TESTOUT
 
 echo "Testing user searching..."
-$LDAPSEARCH -L -S "" -b "uid=root,$BASEDN" -s base -h $LOCALHOST -p $PORT \
+$LDAPSEARCH -L -S "" -b "uid=root,$BASEDN" -s base -h $LOCALHOST -p $PORT1 \
        '(objectclass=*)' >> $TESTOUT 2>&1
+RC=$?
 if test $RC != 0 ; then
        echo "ldapsearch failed!"
-       kill -HUP $PID
+       test "$KILLSERVERS" != no && kill -HUP $KILLPIDS
        exit $RC
 fi
 
 echo " ------------ " >> $TESTOUT
 
 echo "Testing exact searching..."
-$LDAPSEARCH -L -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT \
+$LDAPSEARCH -L -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
        '(uid=root)' >> $TESTOUT 2>&1
+RC=$?
 if test $RC != 0 ; then
        echo "ldapsearch failed!"
-       kill -HUP $PID
+       test "$KILLSERVERS" != no && kill -HUP $KILLPIDS
        exit $RC
 fi
 
 echo " ------------ " >> $TESTOUT
 
 echo "Testing OR searching..."
-$LDAPSEARCH -L -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT \
+$LDAPSEARCH -L -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
        '(|(objectclass=person)(cn=root))' >> $TESTOUT 2>&1
+RC=$?
 if test $RC != 0 ; then
        echo "ldapsearch failed!"
-       kill -HUP $PID
+       test "$KILLSERVERS" != no && kill -HUP $KILLPIDS
        exit $RC
 fi
 
 echo " ------------ " >> $TESTOUT
 
 echo "Testing AND searching..."
-$LDAPSEARCH -L -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT \
+$LDAPSEARCH -L -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
        '(&(objectclass=person)(cn=root))' >> $TESTOUT 2>&1
+RC=$?
 if test $RC != 0 ; then
        echo "ldapsearch failed!"
-       kill -HUP $PID
+       test "$KILLSERVERS" != no && kill -HUP $KILLPIDS
        exit $RC
 fi
 
-kill -HUP $PID
+test "$KILLSERVERS" != no && kill -HUP $KILLPIDS
 
 echo "Assuming everything is fine."
 #echo "Comparing results"
@@ -117,5 +129,4 @@ echo "Assuming everything is fine."
 
 echo ">>>>> Test succeeded"
 
-
 exit 0
index d6651a67249ee63e941babcfa21aa171aada9a8a..61c0f8cca2b7b80bc46ed2d4c29332d0f501432d 100755 (executable)
@@ -16,7 +16,7 @@
 echo "running defines.sh"
 . $SRCDIR/scripts/defines.sh
 
-mkdir -p $TESTRUN $DBDIR1
+mkdir -p $TESTDIR $DBDIR1
 
 echo "Starting slapd on TCP/IP port $PORT1..."
 . $CONFFILTER $BACKEND $MONITORDB < $SCHEMACONF > $CONF1
@@ -51,13 +51,14 @@ fi
 
 count=2
 if test $RC = 0 ; then
-       if test $MONITORDB = yes -o $MONITORDB = mod ; then
+       case $MONITORDB in yes | mod)
                count=3
                echo "Using ldapsearch to retrieve the cn=Monitor..."
                $LDAPSEARCH -b "cn=Monitor" -s base -h $LOCALHOST -p $PORT1 \
                        '+extensibleObject' >> $SEARCHOUT 2>&1
                RC=$?
-       fi
+               ;;
+       esac
 fi
 
 test $KILLSERVERS != no && kill -HUP $KILLPIDS
index df82d1fee85f070d649eeb98a08ac2506a765149..fb1fc469dc55f2cfa56788342c74d517a365a321 100755 (executable)
@@ -16,7 +16,7 @@
 echo "running defines.sh"
 . $SRCDIR/scripts/defines.sh
 
-mkdir -p $TESTRUN $DBDIR1
+mkdir -p $TESTDIR $DBDIR1
 
 echo "Running slapadd to build slapd database..."
 . $CONFFILTER $BACKEND $MONITORDB < $CONF > $ADDCONF
index 955391aefa06b860e26a435a9ea7b1520775e601..c8154149b05cd3ba2a0cbbae725e0870ec025612 100755 (executable)
@@ -52,7 +52,7 @@ done
 
 if test $RC != 0 ; then
        echo "ldapsearch failed ($RC)!"
-       kill -HUP $PID
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
        exit $RC
 fi
 
@@ -65,7 +65,7 @@ $LDAPMODRDN -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
 RC=$?
 if test $RC != 0 ; then
        echo "ldapmodrdn failed ($RC)!"
-       kill -HUP $PID
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
        exit $RC
 fi
 
@@ -76,7 +76,7 @@ $LDAPMODRDN -D "$MANAGERDN" -r -h $LOCALHOST -p $PORT1 -w $PASSWD >> \
 RC=$?
 if test $RC != 0 ; then
        echo "ldapmodrdn failed ($RC)!"
-       kill -HUP $PID
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
        exit $RC
 fi
 
@@ -200,6 +200,7 @@ RC=$?
 
 if test $RC != 0 ; then
        echo "ldapsearch failed ($RC)!"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
        exit $RC
 fi
 
@@ -214,12 +215,13 @@ $CMP $SEARCHFLT $LDIFFLT > $CMPOUT
 
 if test $? != 0 ; then
        echo "comparison failed - modrdn operations did not complete correctly"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
        exit 1
 fi
 
 echo "Testing modrdn with newSuperior as child of target "
 $LDAPMODRDN -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
-       /dev/null 2>&1  -s 'cn=Sub1, ou=FooBar, cn=James A Jones 1, ou=Alumni Association, ou=People, dc=example, dc=com' 'cn=James A Jones 1' \
+       $TESTOUT 2>&1  -s 'cn=Sub1, ou=FooBar, cn=James A Jones 1, ou=Alumni Association, ou=People, dc=example, dc=com' \
        'cn=James A Jones 1, ou=Alumni Association, ou=People, dc=example, dc=com' 'cn=James A Jones 1'
 
 RC=$?
index 9c5df795155476733745020e8273e5f6eaa42f8b..3841c3345e79d9755dd0e8a95f76d4ec41b95abc 100755 (executable)
@@ -27,9 +27,6 @@ if test $RC != 0 ; then
        exit $RC
 fi
 
-echo "Waiting 5 seconds for slapadd to build slapd database..."
-sleep 5
-
 echo "Starting slapd on TCP/IP port $PORT1..."
 $SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 &
 PID=$!
index f87fe6df770f469b50079c5e251a341976f2d4ce..f54e0b5098cde1b83a3221b3863651ece333f74b 100755 (executable)
@@ -49,6 +49,7 @@ done
 
 if test $RC != 0 ; then
        echo "ldapsearch failed ($RC)!"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
        exit $RC
 fi
 
index a612864b909207d02cbddd6d76a199a0bf0ba14c..62734714ac5a38f9610a3a7bcc6192cca3548604 100755 (executable)
@@ -422,6 +422,6 @@ echo ">>>>> Test succeeded"
 exit 0
 
 ## Note to developers: when SLAPD_DEBUG=-1 the command
-## awk '/^do_extended$/ {if (c) {print c} c=0} /<===slap_sasl_match:/ {c++} END {print c}' testrun/slapd.1.log
+## awk '/^do_extended$/ {if (c) {print c} c=0} /<===slap_sasl_match:/ {c++} END {print c}' $TESTDIR/slapd.1.log
 ## must return the sequence 1 2 3 4 5 6 7 8 9 9 1 2 3 4 5 6 7 8 9 9 9 1
 ## to indicate that the authzFrom and authzTo rules applied in the right order.
index b08c7facebc5de820a4115030f1b65d8cd2a6302..db2df02054b56cf13ce9ae1517f55a809840ca97 100755 (executable)
@@ -13,7 +13,7 @@
 ## top-level directory of the distribution or, alternatively, at
 ## <http://www.OpenLDAP.org/license.html>.
 
-if test "$BACKEND" != "bdb" -a "$BACKEND" != "hdb" ; then
+if test "$BACKEND" != "bdb" && test "$BACKEND" != "hdb" ; then
        echo "Test does not support $BACKEND"
        exit 0
 fi
index fce1baac19a172dc451ebcbb30ca6f407b5ad360..2aa89e47dccf57d8dcac64ac2171cb6d28d7acf7 100755 (executable)
@@ -13,7 +13,7 @@
 ## top-level directory of the distribution or, alternatively, at
 ## <http://www.OpenLDAP.org/license.html>.
 
-if test "$BACKEND" != "bdb" -a "$BACKEND" != "hdb" ; then
+if test "$BACKEND" != "bdb" && test "$BACKEND" != "hdb" ; then
        echo "Test does not support $BACKEND"
        exit 0
 fi
index e1aac0c336ca17da07ece1ce89296a63cae93419..04109034e369287886c7f6297922d0d731bb3d94 100755 (executable)
@@ -48,7 +48,7 @@ for i in 0 1 2 3 4 5; do
        sleep 5
 done
 if test $RC != 0 ; then
-       echo "ldapsearch failed $(RC)!"
+       echo "ldapsearch failed ($RC)!"
        test $KILLSERVERS != no && kill -HUP $KILLPIDS
        exit $RC
 fi
index b38993c61fa328323226ee0dbb935b0ff673f719..6b33344e68461a974b0bec16d376e09203a25f8a 100755 (executable)
@@ -13,7 +13,7 @@
 ## top-level directory of the distribution or, alternatively, at
 ## <http://www.OpenLDAP.org/license.html>.
 
-if test "$BACKEND" != "bdb" -a "$BACKEND" != "hdb" ; then
+if test "$BACKEND" != "bdb" && test "$BACKEND" != "hdb" ; then
        echo "Test does not support $BACKEND"
        exit 0
 fi
@@ -67,7 +67,7 @@ fi
 echo "Searching unmodified database..."
 
 $LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 | \
-       egrep "(manager|secretary):" | sed "s/george/foster/g" | \
+       $EGREP_CMD "(manager|secretary):" | sed "s/george/foster/g" | \
        sort > $SEARCHOUT 2>&1
 
 RC=$?
@@ -93,7 +93,7 @@ fi
 echo "Using ldapsearch to check dependents new rdn..."
 
 $LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 | \
-       egrep "(manager|secretary):" | sort > $SEARCHFLT 2>&1
+       $EGREP_CMD "(manager|secretary):" | sort > $SEARCHFLT 2>&1
 
 RC=$?
        if test $RC != 0 ; then
@@ -107,6 +107,7 @@ $CMP $SEARCHOUT $SEARCHOUT > $CMPOUT
 
 if test $? != 0 ; then
        echo "comparison failed - modify operations did not complete correctly"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
        exit 1
 fi
 
@@ -127,7 +128,7 @@ fi
 
 echo "Using ldapsearch to verify dependents have been deleted..."
 $LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 | \
-       egrep "(manager|secretary):" > $SEARCHFLT 2>&1
+       $EGREP_CMD "(manager|secretary):" > $SEARCHFLT 2>&1
 
 RC=$?
 if test $RC != 0 ; then
@@ -139,6 +140,7 @@ fi
 RC=`grep -c foster $SEARCHFLT`
 if test $RC != 0 ; then
        echo "dependent modify failed - dependents were not deleted"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
        exit 1
 fi
 
index 1553147e95edfacd26f4695845f1a6e09427152a..efb922ae50725a184599c9bfd0060ae58c00a6de 100755 (executable)
@@ -91,7 +91,7 @@ fi
 echo "Comparison of database generated via slapadd succeeded"
 
 echo "Cleaning up database directories..."
-/bin/rm -rf testrun/db.*
+/bin/rm -rf $TESTDIR/db.*
 
 mkdir -p $TESTDIR $DBDIR1 $DBDIR2
 
index 0d930ceef838fa3e10a5a7240c8f0c025acadccc..b0c6435d79297eaeea06add59d85edc75c424df8 100755 (executable)
@@ -137,11 +137,11 @@ for P in $PORT1 $PORT2 ; do
 
        DN="cn=Mark Elliot,ou=Alumni Association,ou=People,$BASEDN"
        echo "Comparing \"$DN\" on port $P..."
-       $LDAPCOMPARE -h $LOCALHOST -p $P "$DN" "cn:Mark Elliot"
+       $LDAPCOMPARE -h $LOCALHOST -p $P "$DN" "cn:Mark Elliot" \
                 > $TESTOUT 2>&1
 
        RC=$?
-       if test $RC != 0 ; then
+       if test $RC != 6 ; then
                echo "ldapcompare failed ($RC)!"
                test $KILLSERVERS != no && kill -HUP $KILLPIDS
                exit $RC
@@ -149,11 +149,11 @@ for P in $PORT1 $PORT2 ; do
 
        DN="ou=Other,$BASEDN"
        echo "Comparing \"$DN\" on port $P with manageDSAit control..."
-       $LDAPCOMPARE -h $LOCALHOST -p $P -M "$DN" "ou:Other"
+       $LDAPCOMPARE -h $LOCALHOST -p $P -M "$DN" "ou:Other" \
                 > $TESTOUT 2>&1
 
        RC=$?
-       if test $RC != 0 ; then
+       if test $RC != 6 ; then
                echo "ldapcompare failed ($RC)!"
                test $KILLSERVERS != no && kill -HUP $KILLPIDS
                exit $RC
index 450e25699ad9400f69c52caa4f984618541367cf..d9164f1279c40b328daf1cf6a272519ca957f00e 100755 (executable)
@@ -259,7 +259,7 @@ case $RC in
                exit 0
        ;;
        *)
-               echo "Compare failed ($RC)!"
+               echo "Modify failed ($RC)!"
                test $KILLSERVERS != no && kill -HUP $KILLPIDS
                exit $RC
        ;;
@@ -485,7 +485,7 @@ case $RC in
                echo "### Hit LDAP_BUSY problem; you may want to re-run the test"
        ;;
        *)
-               echo "Compare failed ($RC)!"
+               echo "WhoAmI failed ($RC)!"
                test $KILLSERVERS != no && kill -HUP $KILLPIDS
                exit $RC
        ;;
index 958f7842e36ec71384d6a8a0c0e2441d51aca604..b802c1372baf2ff293cd375416e26f21467d1808 100755 (executable)
@@ -40,7 +40,7 @@ rm -rf $TESTDIR
 mkdir -p $TESTDIR $DBDIR1 $DBDIR2
 
 # NOTE: this could be added to all tests...
-if test "$BACKEND" = "bdb" -o "$BACKEND" = "hdb" ; then
+if test "$BACKEND" = "bdb" || test "$BACKEND" = "hdb" ; then
        if test "x$DB_CONFIG" != "x" ; then \
                if test -f $DB_CONFIG ; then
                        echo "==> using DB_CONFIG \"$DB_CONFIG\""