]> git.sur5r.net Git - openldap/commitdiff
Sync with HEAD
authorKurt Zeilenga <kurt@openldap.org>
Thu, 3 Nov 2005 19:02:53 +0000 (19:02 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Thu, 3 Nov 2005 19:02:53 +0000 (19:02 +0000)
117 files changed:
CHANGES
aclocal.m4
build/BerkeleyDB42.patch [deleted file]
build/ltmain.sh
clients/tools/ldapmodrdn.c
clients/tools/ldappasswd.c
configure.in
contrib/slapd-modules/smbk5pwd/smbk5pwd.c
doc/devel/todo
doc/guide/admin/tls.sdf
doc/man/man3/ldap.3
doc/man/man5/slapd.conf.5
doc/man/man5/slapo-accesslog.5
doc/man/man5/slapo-retcode.5
doc/man/man5/slapo-syncprov.5
doc/man/man8/slapadd.8
doc/man/man8/slapauth.8
doc/man/man8/slapcat.8
doc/man/man8/slapdn.8
doc/man/man8/slapindex.8
include/ldap.h
include/portable.hin
libraries/libldap/cyrus.c
libraries/libldap/error.c
libraries/libldap/init.c
libraries/libldap/os-ip.c
libraries/libldap/search.c
libraries/libldap/tls.c
libraries/libldap/utf-8-conv.c
libraries/libldap/util-int.c
libraries/libldap_r/tpool.c
libraries/librewrite/info.c
libraries/librewrite/session.c
servers/slapd/aci.c
servers/slapd/acl.c
servers/slapd/aclparse.c
servers/slapd/add.c
servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/attr.c
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/cache.c
servers/slapd/back-bdb/delete.c
servers/slapd/back-bdb/dn2id.c
servers/slapd/back-bdb/id2entry.c
servers/slapd/back-bdb/index.c
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/key.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/tools.c
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/chain.c
servers/slapd/back-ldap/extended.c
servers/slapd/back-ldap/search.c
servers/slapd/back-ldbm/add.c
servers/slapd/back-ldbm/delete.c
servers/slapd/back-ldbm/modify.c
servers/slapd/back-ldif/ldif.c
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/candidates.c
servers/slapd/back-meta/config.c
servers/slapd/back-meta/conn.c
servers/slapd/back-meta/init.c
servers/slapd/back-meta/map.c
servers/slapd/back-meta/search.c
servers/slapd/back-meta/unbind.c
servers/slapd/back-monitor/init.c
servers/slapd/back-monitor/log.c
servers/slapd/back-monitor/modify.c
servers/slapd/back-monitor/rww.c
servers/slapd/back-sql/add.c
servers/slapd/back-sql/modrdn.c
servers/slapd/back-sql/operational.c
servers/slapd/backglue.c
servers/slapd/bconfig.c
servers/slapd/config.c
servers/slapd/connection.c
servers/slapd/ctxcsn.c
servers/slapd/daemon.c
servers/slapd/delete.c
servers/slapd/extended.c
servers/slapd/init.c
servers/slapd/main.c
servers/slapd/modify.c
servers/slapd/modrdn.c
servers/slapd/mods.c
servers/slapd/operation.c
servers/slapd/overlays/accesslog.c
servers/slapd/overlays/lastmod.c
servers/slapd/overlays/ppolicy.c
servers/slapd/overlays/refint.c
servers/slapd/overlays/rwm.c
servers/slapd/overlays/rwm.h
servers/slapd/overlays/rwmconf.c
servers/slapd/overlays/rwmmap.c
servers/slapd/overlays/syncprov.c
servers/slapd/passwd.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/sasl.c
servers/slapd/saslauthz.c
servers/slapd/schema/core.schema
servers/slapd/schema_init.c
servers/slapd/slap.h
servers/slapd/slapcommon.c
servers/slapd/slapi/slapi_ops.c
servers/slapd/slaptest.c
servers/slapd/syncrepl.c
tests/progs/Makefile.in
tests/progs/slapd-bind.c [new file with mode: 0644]
tests/run.in
tests/scripts/conf.sh
tests/scripts/defines.sh
tests/scripts/test031-component-filter
tests/scripts/test035-meta
tests/scripts/test039-glue-ldap-concurrency

diff --git a/CHANGES b/CHANGES
index 9d73a2561d685ee6b242751661c7f4025cf336bc..649b3115fcb79b8bbb43380cb98cf85694049b45 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,13 @@
 OpenLDAP 2.3 Change Log
 
 OpenLDAP 2.3.12 Engineering
+       Fixed libldap ldapi:// authdn construction
+       Added libldap ldap_bv2escaped_filter_value
+       Updated contrib smbk5pwd module
+       Build environment
+               Added slapd-bind test program
+               Added inet_ntoa_b support for VxWorks
+               Dropped SSLeay support
 
 OpenLDAP 2.3.11 Release
        Fixed libldap reentrancy issue (ITS#3988)
index 22cdcb9365bd519ced000ed78035146f3bff8d59..d5ecbecab1f1346790959f6b8765ea785c853cfd 100644 (file)
@@ -621,7 +621,7 @@ rm="rm -f"
 default_ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a `.a' archive for static linking (except M$VC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 ltmain="$ac_aux_dir/ltmain.sh"
@@ -837,8 +837,8 @@ if test "X${echo_test_string+set}" != Xset; then
 # find a string as large as possible, as long as the shell can cope with it
   for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
     # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
-    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
-       echo_test_string="`eval $cmd`" &&
+    if (echo_test_string=`eval $cmd`) 2>/dev/null &&
+       echo_test_string=`eval $cmd` &&
        (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
     then
       break
@@ -1007,7 +1007,7 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
   # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
-    case "`/usr/bin/file conftest.o`" in
+    case `/usr/bin/file conftest.o` in
     *32-bit*)
       case $host in
         x86_64-*linux*)
@@ -1089,7 +1089,7 @@ AC_CACHE_CHECK([$1], [$2],
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    # The option is referenced via a variable to avoid confusing sed.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
@@ -1128,7 +1128,7 @@ AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
    LDFLAGS="$LDFLAGS $3"
    printf "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
-     # The compiler can only warn and ignore the option if not recognized
+     # The linker can only warn and ignore the option if not recognized
      # So say no if there are warnings
      if test -s conftest.err; then
        # Append any errors to the config.log.
@@ -1203,7 +1203,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     elif test -x /usr/sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
     else
-      lt_cv_sys_max_cmd_len=65536 # usable default for *BSD
+      lt_cv_sys_max_cmd_len=65536      # usable default for all BSDs
     fi
     # And add a safety zone
     lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
@@ -1215,7 +1215,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     # nice to cause kernel panics so lets avoid the loop below.
     # First set a reasonable default.
     lt_cv_sys_max_cmd_len=16384
-    # 
+    #
     if test -x /sbin/sysconfig; then
       case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
         *1*) lt_cv_sys_max_cmd_len=-1 ;;
@@ -1332,7 +1332,7 @@ int main ()
 }]
 EOF
   if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
-    (./conftest; exit; ) 2>/dev/null
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
     lt_status=$?
     case x$lt_status in
       x$lt_dlno_uscore) $1 ;;
@@ -1481,7 +1481,7 @@ AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
    # Note that $ac_compile itself does not contain backslashes and begins
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
@@ -1499,7 +1499,7 @@ AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
        _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
      fi
    fi
-   chmod u+w .
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
    $rm conftest*
    # SGI C++ compiler will create directory out/ii_files/ for
    # template instantiation
@@ -1759,7 +1759,8 @@ cygwin* | mingw* | pw32*)
       dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
-      $install_prog $dir/$dlname \$dldir/$dlname'
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
     postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
       dlpath=$dir/\$dldll~
        $rm \$dlpath'
@@ -1812,7 +1813,7 @@ darwin* | rhapsody*)
   soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
-  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
   # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
   if test "$GCC" = yes; then
     sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
@@ -1850,7 +1851,14 @@ kfreebsd*-gnu)
 freebsd* | dragonfly*)
   # DragonFly does not have aout.  When/if they implement a new
   # versioning mechanism, adjust this.
-  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[123]]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
@@ -1895,7 +1903,7 @@ hpux9* | hpux10* | hpux11*)
   version_type=sunos
   need_lib_prefix=no
   need_version=no
-  case "$host_cpu" in
+  case $host_cpu in
   ia64*)
     shrext_cmds='.so'
     hardcode_into_libs=yes
@@ -2291,7 +2299,7 @@ AC_DEFUN([AC_LIBTOOL_DLOPEN],
 
 # AC_LIBTOOL_WIN32_DLL
 # --------------------
-# declare package support for building win32 dll's
+# declare package support for building win32 DLLs
 AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
 [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
 ])# AC_LIBTOOL_WIN32_DLL
@@ -2465,7 +2473,7 @@ dnl not every word.  This closes a longstanding sh security hole.
       if test -n "$file_magic_test_file"; then
        case $deplibs_check_method in
        "file_magic "*)
-         file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+         file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
          MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
          if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
            $EGREP "$file_magic_regex" > /dev/null; then
@@ -2575,7 +2583,7 @@ AC_CACHE_VAL(lt_cv_path_LD,
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
       lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some GNU ld's only accept -v.
+      # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
@@ -2607,7 +2615,7 @@ AC_PROG_LD_GNU
 AC_DEFUN([AC_PROG_LD_GNU],
 [AC_REQUIRE([AC_PROG_EGREP])dnl
 AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
-[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
 case `$LD -v 2>&1 </dev/null` in
 *GNU* | *'with BFD'*)
   lt_cv_prog_gnu_ld=yes
@@ -2721,7 +2729,7 @@ gnu*)
 
 hpux10.20* | hpux11*)
   lt_cv_file_magic_cmd=/usr/bin/file
-  case "$host_cpu" in
+  case $host_cpu in
   ia64*)
     lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
     lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
@@ -2895,13 +2903,13 @@ esac
 # -----------------------------------
 # sets LIBLTDL to the link flags for the libltdl convenience library and
 # LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-convenience to the configure arguments.  Note that LIBLTDL
-# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If
-# DIRECTORY is not provided, it is assumed to be `libltdl'.  LIBLTDL will
-# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with
-# '${top_srcdir}/' (note the single quotes!).  If your package is not
-# flat and you're not using automake, define top_builddir and
-# top_srcdir appropriately in the Makefiles.
+# --enable-ltdl-convenience to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
+# it is assumed to be `libltdl'.  LIBLTDL will be prefixed with
+# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/'
+# (note the single quotes!).  If your package is not flat and you're not
+# using automake, define top_builddir and top_srcdir appropriately in
+# the Makefiles.
 AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
 [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
   case $enable_ltdl_convenience in
@@ -2920,13 +2928,13 @@ AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
 # -----------------------------------
 # sets LIBLTDL to the link flags for the libltdl installable library and
 # LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-install to the configure arguments.  Note that LIBLTDL
-# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If
-# DIRECTORY is not provided and an installed libltdl is not found, it is
-# assumed to be `libltdl'.  LIBLTDL will be prefixed with '${top_builddir}/'
-# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single
-# quotes!).  If your package is not flat and you're not using automake,
-# define top_builddir and top_srcdir appropriately in the Makefiles.
+# --enable-ltdl-install to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
+# and an installed libltdl is not found, it is assumed to be `libltdl'.
+# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and top_srcdir
+# appropriately in the Makefiles.
 # In the future, this macro may have to be called after AC_PROG_LIBTOOL.
 AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
 [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
@@ -3105,7 +3113,7 @@ test "$can_build_shared" = "no" && enable_shared=no
 
 # On AIX, shared libraries and static libraries use the same namespace, and
 # are all built from PIC.
-case "$host_os" in
+case $host_os in
 aix3*)
   test "$enable_shared" = yes && enable_static=no
   if test -n "$RANLIB"; then
@@ -3172,7 +3180,7 @@ _LT_AC_TAGVAR(postdeps, $1)=
 _LT_AC_TAGVAR(compiler_lib_search_path, $1)=
 
 # Source file extension for C++ test sources.
-ac_ext=cc
+ac_ext=cpp
 
 # Object file extension for compiled C++ test sources.
 objext=o
@@ -3388,7 +3396,7 @@ case $host_os in
        # Exported symbols can be pulled into shared objects from archives
        _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
        _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
-       # This is similar to how AIX traditionally builds it's shared libraries.
+       # This is similar to how AIX traditionally builds its shared libraries.
        _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
       fi
     fi
@@ -3427,7 +3435,7 @@ case $host_os in
     fi
   ;;
       darwin* | rhapsody*)
-        case "$host_os" in
+        case $host_os in
         rhapsody* | darwin1.[[012]])
          _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
          ;;
@@ -3465,7 +3473,7 @@ case $host_os in
           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
         fi
         _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-        # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
           if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
             _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           else
@@ -3478,7 +3486,7 @@ case $host_os in
          output_verbose_link_cmd='echo'
           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
           _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
           _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           ;;
@@ -3558,7 +3566,7 @@ case $host_os in
     ;;
   hpux10*|hpux11*)
     if test $with_gnu_ld = no; then
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*)
        _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
        _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
@@ -3574,7 +3582,7 @@ case $host_os in
         ;;
       esac
     fi
-    case "$host_cpu" in
+    case $host_cpu in
     hppa*64*)
       _LT_AC_TAGVAR(hardcode_direct, $1)=no
       _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -3600,7 +3608,7 @@ case $host_os in
        _LT_AC_TAGVAR(ld_shlibs, $1)=no
        ;;
       aCC*)
-       case "$host_cpu" in
+       case $host_cpu in
        hppa*64*|ia64*)
          _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
          ;;
@@ -3621,7 +3629,7 @@ case $host_os in
       *)
        if test "$GXX" = yes; then
          if test $with_gnu_ld = no; then
-           case "$host_cpu" in
+           case $host_cpu in
            ia64*|hppa*64*)
              _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
              ;;
@@ -3722,7 +3730,7 @@ case $host_os in
 
        _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
        _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
         ;;
       cxx*)
        # Compaq C++
@@ -3954,10 +3962,11 @@ case $host_os in
     case $cc_basename in
       CC*)
        # Sun C++ 4.2, 5.x and Centerline C++
+        _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes
        _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
        _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-       $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+       $CC -G${allow_undefined_flag}  ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
 
        _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
        _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -3977,15 +3986,7 @@ case $host_os in
        esac
        _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
 
-       # Commands to make compiler produce verbose output that lists
-       # what "hidden" libraries, object files and flags are used when
-       # linking a shared library.
-       #
-       # There doesn't appear to be a way to prevent this compiler from
-       # explicitly linking system object files so we need to strip them
-       # from the output so that they don't get included in the library
-       # dependencies.
-       output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       output_verbose_link_cmd='echo'
 
        # Archives containing C++ object files must be created using
        # "CC -xar", where "CC" is the Sun C++ compiler.  This is
@@ -4142,7 +4143,7 @@ if AC_TRY_EVAL(ac_compile); then
   # The `*' in the case matches for architectures that use `case' in
   # $output_verbose_cmd can trigger glob expansion during the loop
   # eval without this substitution.
-  output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+  output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
 
   for p in `eval $output_verbose_link_cmd`; do
     case $p in
@@ -4218,6 +4219,21 @@ fi
 
 $rm -f confest.$objext
 
+# PORTME: override above test on systems where it is broken
+ifelse([$1],[CXX],
+[case $host_os in
+solaris*)
+  case $cc_basename in
+  CC*)
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun'
+    ;;
+  esac
+esac
+])
+
 case " $_LT_AC_TAGVAR(postdeps, $1) " in
 *" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
 esac
@@ -4287,7 +4303,7 @@ test "$can_build_shared" = "no" && enable_shared=no
 
 # On AIX, shared libraries and static libraries use the same namespace, and
 # are all built from PIC.
-case "$host_os" in
+case $host_os in
 aix3*)
   test "$enable_shared" = yes && enable_static=no
   if test -n "$RANLIB"; then
@@ -5186,7 +5202,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
     hpux*)
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
        ;;
       *)
@@ -5255,7 +5271,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
          aCC*)
            _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
            _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
-           case "$host_cpu" in
+           case $host_cpu in
            hppa*64*|ia64*)
              # +Z the default
              ;;
@@ -5296,7 +5312,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
            # Portland Group C++ compiler.
            _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
            _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
-           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
            ;;
          cxx*)
            # Compaq C++
@@ -5460,7 +5476,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
     hpux*)
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
        # +Z the default
        ;;
@@ -5507,7 +5523,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
       _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
       # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
       # not for PA HP-UX.
-      case "$host_cpu" in
+      case $host_cpu in
       hppa*64*|ia64*)
        # +Z the default
        ;;
@@ -5537,12 +5553,12 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
        _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
        _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
         ;;
-      pgcc* | pgf77* | pgf90*)
+      pgcc* | pgf77* | pgf90* | pgf95*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
        # which looks to be a dead project)
        _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
        _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
-       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
         ;;
       ccc*)
         _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
@@ -5625,7 +5641,7 @@ if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then
     [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
 fi
-case "$host_os" in
+case $host_os in
   # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
@@ -5721,7 +5737,7 @@ ifelse([$1],[CXX],[
   if test "$with_gnu_ld" = yes; then
     # If archive_cmds runs LD, not CC, wlarc should be empty
     wlarc='${wl}'
-    
+
     # Set some defaults for GNU ld with shared library support. These
     # are reset later if shared libraries are not supported. Putting them
     # here allows them to be overridden if necessary.
@@ -5742,7 +5758,7 @@ ifelse([$1],[CXX],[
       *\ 2.11.*) ;; # other 2.11 versions
       *) supports_anon_versioning=yes ;;
     esac
-    
+
     # See if GNU ld supports shared libraries.
     case $host_os in
     aix3* | aix4* | aix5*)
@@ -5816,11 +5832,11 @@ EOF
        tmp_addflag=
        case $cc_basename,$host_cpu in
        pgcc*)                          # Portland Group C compiler
-         _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+         _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
          tmp_addflag=' $pic_flag'
          ;;
-       pgf77* | pgf90* )                       # Portland Group f77 and f90 compilers
-         _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+       pgf77* | pgf90* | pgf95*)       # Portland Group f77 and f90 compilers
+         _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
          tmp_addflag=' $pic_flag -Mnomain' ;;
        ecc*,ia64* | icc*,ia64*)                # Intel C compiler on ia64
          tmp_addflag=' -i_dynamic' ;;
@@ -6026,7 +6042,7 @@ EOF
          # Exported symbols can be pulled into shared objects from archives
          _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
          _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
-         # This is similar to how AIX traditionally builds it's shared libraries.
+         # This is similar to how AIX traditionally builds its shared libraries.
          _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
        fi
       fi
@@ -6066,7 +6082,7 @@ EOF
       ;;
 
     darwin* | rhapsody*)
-      case "$host_os" in
+      case $host_os in
         rhapsody* | darwin1.[[012]])
          _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
          ;;
@@ -6095,7 +6111,7 @@ EOF
        output_verbose_link_cmd='echo'
         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
       _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
       _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
     else
@@ -6104,7 +6120,7 @@ EOF
          output_verbose_link_cmd='echo'
          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
          _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
           ;;
@@ -6170,7 +6186,7 @@ EOF
 
     hpux10* | hpux11*)
       if test "$GCC" = yes -a "$with_gnu_ld" = no; then
-       case "$host_cpu" in
+       case $host_cpu in
        hppa*64*|ia64*)
          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
          ;;
@@ -6179,7 +6195,7 @@ EOF
          ;;
        esac
       else
-       case "$host_cpu" in
+       case $host_cpu in
        hppa*64*|ia64*)
          _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
          ;;
@@ -6189,7 +6205,7 @@ EOF
        esac
       fi
       if test "$with_gnu_ld" = no; then
-       case "$host_cpu" in
+       case $host_cpu in
        hppa*64*)
          _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
          _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
diff --git a/build/BerkeleyDB42.patch b/build/BerkeleyDB42.patch
deleted file mode 100644 (file)
index 7ff8874..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-This patch is intended to be applied to Berkeley DB 4.2.52 and,
-if applied, will automatically be used by slapd(8) back-bdb/hdb.
-Without this patch the BDB DB_LOG_AUTOREMOVE option will not work,
-nor will db_archive allow any transaction log files to be removed
-while slapd is running.
-
-The patch can be applied to the BDB source using patch(1) as follows
-       cd db-4.2.52
-       patch -p0 < openldap-src/build/BerkeleyDB42.patch
-
-(modify directory paths as necessary), then recompile and reinstall
-the BerkeleyDB 4.2 library, and then build and install OpenLDAP
-Software.
-
-The patch should not be applied to Berkeley DB 4.3.
-
-
-Index: dbinc/db.in
-===================================================================
-RCS file: /var/CVSROOT/bdb42/dbinc/db.in,v
-retrieving revision 1.1.1.1
-retrieving revision 1.2
-diff -u -r1.1.1.1 -r1.2
---- dbinc/db.in        25 Nov 2003 21:58:02 -0000      1.1.1.1
-+++ dbinc/db.in        17 Jul 2004 16:07:23 -0000      1.2
-@@ -839,6 +839,7 @@
- #define       TXN_NOWAIT      0x040           /* Do not wait on locks. */
- #define       TXN_RESTORED    0x080           /* Transaction has been restored. */
- #define       TXN_SYNC        0x100           /* Sync on prepare and commit. */
-+#define       TXN_NOLOG       0x200           /* Do not log this transaction. */
-       u_int32_t       flags;
- };
-Index: txn/txn.c
-===================================================================
-RCS file: /var/CVSROOT/bdb42/txn/txn.c,v
-retrieving revision 1.1.1.2
-retrieving revision 1.2
-diff -u -r1.1.1.2 -r1.2
---- txn/txn.c  17 Dec 2003 21:43:53 -0000      1.1.1.2
-+++ txn/txn.c  17 Jul 2004 16:07:27 -0000      1.2
-@@ -127,7 +127,7 @@
-       if ((ret = __db_fchk(dbenv,
-           "txn_begin", flags,
-           DB_DIRTY_READ | DB_TXN_NOWAIT |
--          DB_TXN_NOSYNC | DB_TXN_SYNC)) != 0)
-+          DB_TXN_NOSYNC | DB_TXN_SYNC | DB_TXN_NOT_DURABLE)) != 0)
-               return (ret);
-       if ((ret = __db_fcchk(dbenv,
-           "txn_begin", flags, DB_TXN_NOSYNC, DB_TXN_SYNC)) != 0)
-@@ -193,6 +193,8 @@
-               F_SET(txn, TXN_SYNC);
-       if (LF_ISSET(DB_TXN_NOWAIT))
-               F_SET(txn, TXN_NOWAIT);
-+      if (LF_ISSET(DB_TXN_NOT_DURABLE))
-+              F_SET(txn, TXN_NOLOG);
-       if ((ret = __txn_begin_int(txn, 0)) != 0)
-               goto err;
-@@ -328,7 +330,7 @@
-        * We should set this value when we write the first log record, not
-        * here.
-        */
--      if (DBENV_LOGGING(dbenv))
-+      if (DBENV_LOGGING(dbenv) && !F_ISSET(txn, TXN_NOLOG))
-               __log_txn_lsn(dbenv, &begin_lsn, NULL, NULL);
-       else
-               ZERO_LSN(begin_lsn);
index a47be7185434c0c9d99c79412a15a4faae6e50f0..83e369c029b4b1e80091e38e7ec86c5df425b9ff 100755 (executable)
@@ -58,8 +58,8 @@ EXIT_FAILURE=1
 
 PROGRAM=ltmain.sh
 PACKAGE=libtool
-VERSION=1.5.18-OpenLDAP
-TIMESTAMP=" (1.1220.2.245 2005/05/16 08:55:27)"
+VERSION=1.5.20-OpenLDAP
+TIMESTAMP=" (1.1220.2.287 2005/08/31 18:54:15)"
 
 # See if we are running on zsh, and set the options which allow our
 # commands through without removal of \ escapes.
@@ -103,14 +103,15 @@ rm="rm -f"
 Xsed="${SED}"' -e 1s/^X//'
 sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
 # test EBCDIC or ASCII
-case `echo A|tr A '\301'` in
- A) # EBCDIC based system
-  SP2NL="tr '\100' '\n'"
-  NL2SP="tr '\r\n' '\100\100'"
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  SP2NL='tr \040 \012'
+  NL2SP='tr \015\012 \040\040'
   ;;
- *) # Assume ASCII based system
-  SP2NL="tr '\040' '\012'"
-  NL2SP="tr '\015\012' '\040\040'"
+ *) # EBCDIC based system
+  SP2NL='tr \100 \n'
+  NL2SP='tr \r\n \100\100'
   ;;
 esac
 
@@ -148,7 +149,6 @@ show_help=
 execute_dlfiles=
 lo2o="s/\\.lo\$/.${objext}/"
 o2lo="s/\\.${objext}\$/.lo/"
-quote_scanset='[[~#^*{};<>?'"'"'       ]'
 
 #####################################
 # Shell function definitions:
@@ -207,7 +207,7 @@ func_infer_tag ()
       CC_quoted=
       for arg in $CC; do
        case $arg in
-         *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+         *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
          arg="\"$arg\""
          ;;
        esac
@@ -228,7 +228,7 @@ func_infer_tag ()
            for arg in $CC; do
            # Double-quote args containing other shell metacharacters.
            case $arg in
-             *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+             *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \     ]*|*]*|"")
              arg="\"$arg\""
              ;;
            esac
@@ -352,7 +352,7 @@ func_extract_archives ()
            func_extract_an_archive "$my_xdir" "$my_xabs"
          fi # $darwin_arches
        fi # $run
-      ;;
+       ;;
       *)
         func_extract_an_archive "$my_xdir" "$my_xabs"
         ;;
@@ -591,7 +591,7 @@ if test -z "$show_help"; then
 
     for arg
     do
-      case "$arg_mode" in
+      case $arg_mode in
       arg  )
        # do not "continue".  Instead, add this to base_compile
        lastarg="$arg"
@@ -642,7 +642,7 @@ if test -z "$show_help"; then
            # Many Bourne shells cannot handle close brackets correctly
            # in scan sets, so we specify it separately.
            case $arg in
-             *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+             *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \     ]*|*]*|"")
              arg="\"$arg\""
              ;;
            esac
@@ -677,7 +677,7 @@ if test -z "$show_help"; then
       # in scan sets (worked around with variable expansion),
       # and furthermore cannot handle '|' '&' '(' ')' in scan sets 
       # at all, so we specify them separately.
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
        lastarg="\"$lastarg\""
        ;;
       esac
@@ -752,13 +752,12 @@ if test -z "$show_help"; then
 
     qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
     case $qlibobj in
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
        qlibobj="\"$qlibobj\"" ;;
     esac
-    if test "X$libobj" != "X$qlibobj"; then
-       $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
-       exit $EXIT_FAILURE
-    fi
+    test "X$libobj" != "X$qlibobj" \
+       && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"'  &()|`$[]' \
+       && $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
     objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
     xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
     if test "X$xdir" = "X$obj"; then
@@ -839,7 +838,7 @@ compiler."
     fi
     qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
     case $qsrcfile in
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
       qsrcfile="\"$qsrcfile\"" ;;
     esac
 
@@ -1105,15 +1104,14 @@ EOF
          if test -n "$link_static_flag"; then
            dlopen_self=$dlopen_self_static
          fi
-         prefer_static_libs=yes
        else
          if test -z "$pic_flag" && test -n "$link_static_flag"; then
            dlopen_self=$dlopen_self_static
          fi
-         prefer_static_libs=built
        fi
        build_libtool_libs=no
        build_old_libs=yes
+       prefer_static_libs=yes
        break
        ;;
       esac
@@ -1127,7 +1125,7 @@ EOF
       arg="$1"
       shift
       case $arg in
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
        qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
        ;;
       *) qarg=$arg ;;
@@ -1436,7 +1434,7 @@ EOF
        continue
        ;;
 
-      -framework)
+      -framework|-arch)
         prev=darwin_framework
         compiler_flags="$compiler_flags $arg"
        compile_command="$compile_command $arg"
@@ -1566,7 +1564,7 @@ EOF
        # to be aesthetically quoted because they are evaled later.
        arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
        case $arg in
-       *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
          arg="\"$arg\""
          ;;
        esac
@@ -1682,7 +1680,7 @@ EOF
        for flag in $args; do
          IFS="$save_ifs"
          case $flag in
-           *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+           *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \       ]*|*]*|"")
            flag="\"$flag\""
            ;;
          esac
@@ -1700,7 +1698,7 @@ EOF
        for flag in $args; do
          IFS="$save_ifs"
          case $flag in
-           *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+           *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \       ]*|*]*|"")
            flag="\"$flag\""
            ;;
          esac
@@ -1733,7 +1731,7 @@ EOF
        # to be aesthetically quoted because they are evaled later.
        arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
        case $arg in
-       *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
          arg="\"$arg\""
          ;;
        esac
@@ -1867,7 +1865,7 @@ EOF
        # to be aesthetically quoted because they are evaled later.
        arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
        case $arg in
-       *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
          arg="\"$arg\""
          ;;
        esac
@@ -2455,7 +2453,7 @@ EOF
              case "$temp_rpath " in
              *" $dir "*) ;;
              *" $absdir "*) ;;
-             *) temp_rpath="$temp_rpath $dir" ;;
+             *) temp_rpath="$temp_rpath $absdir" ;;
              esac
            fi
 
@@ -2492,12 +2490,8 @@ EOF
        fi
 
        link_static=no # Whether the deplib will be linked statically
-       use_static_libs="$prefer_static_libs"
-       if test "$use_static_libs" = built && test "$installed" = yes ; then
-         use_static_libs=no
-       fi
        if test -n "$library_names" &&
-          { test "$use_static_libs" = no || test -z "$old_library"; }; then
+          { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
          if test "$installed" = no; then
            notinst_deplibs="$notinst_deplibs $lib"
            need_relink=yes
@@ -2645,7 +2639,7 @@ EOF
                add_dir="-L$dir"
                # Try looking first in the location we're being installed to.
                if test -n "$inst_prefix_dir"; then
-                 case "$libdir" in
+                 case $libdir in
                    [\\/]*)
                      add_dir="$add_dir -L$inst_prefix_dir$libdir"
                      ;;
@@ -2718,7 +2712,7 @@ EOF
              add_dir="-L$libdir"
              # Try looking first in the location we're being installed to.
              if test -n "$inst_prefix_dir"; then
-               case "$libdir" in
+               case $libdir in
                  [\\/]*)
                    add_dir="$add_dir -L$inst_prefix_dir$libdir"
                    ;;
@@ -2779,8 +2773,6 @@ EOF
              fi
            fi
          else
-           convenience="$convenience $dir/$old_library"
-           old_convenience="$old_convenience $dir/$old_library"
            deplibs="$dir/$old_library $deplibs"
            link_static=yes
          fi
@@ -3470,7 +3462,7 @@ EOF
          if test "$?" -eq 0 ; then
            ldd_output=`ldd conftest`
            for i in $deplibs; do
-             name="`expr $i : '-l\(.*\)'`"
+             name=`expr $i : '-l\(.*\)'`
              # If $name is empty we are operating on a -L argument.
               if test "$name" != "" && test "$name" -ne "0"; then
                if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
@@ -3507,7 +3499,7 @@ EOF
            # Error occurred in the first compile.  Let's try to salvage
            # the situation: Compile a separate program for each library.
            for i in $deplibs; do
-             name="`expr $i : '-l\(.*\)'`"
+             name=`expr $i : '-l\(.*\)'`
              # If $name is empty we are operating on a -L argument.
               if test "$name" != "" && test "$name" != "0"; then
                $rm conftest
@@ -3559,7 +3551,7 @@ EOF
          set dummy $deplibs_check_method
          file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
          for a_deplib in $deplibs; do
-           name="`expr $a_deplib : '-l\(.*\)'`"
+           name=`expr $a_deplib : '-l\(.*\)'`
            # If $name is empty we are operating on a -L argument.
             if test "$name" != "" && test  "$name" != "0"; then
              if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
@@ -3628,7 +3620,7 @@ EOF
          set dummy $deplibs_check_method
          match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
          for a_deplib in $deplibs; do
-           name="`expr $a_deplib : '-l\(.*\)'`"
+           name=`expr $a_deplib : '-l\(.*\)'`
            # If $name is empty we are operating on a -L argument.
            if test -n "$name" && test "$name" != "0"; then
              if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
@@ -3869,6 +3861,9 @@ EOF
                # The command line is too long to execute in one step.
                $show "using reloadable object file for export list..."
                skipped_export=:
+               # Break out early, otherwise skipped_export may be
+               # set to false by a later but shorter cmd.
+               break
              fi
            done
            IFS="$save_ifs"
@@ -3938,7 +3933,8 @@ EOF
          fi
        fi
 
-       if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*"` &&
+       if test "X$skipped_export" != "X:" &&
+          len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
           test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
          :
        else
@@ -3973,7 +3969,7 @@ EOF
          do
            eval test_cmds=\"$reload_cmds $objlist $last_robj\"
            if test "X$objlist" = X ||
-              { len=`expr "X$test_cmds" : ".*"` &&
+              { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
                 test "$len" -le "$max_cmd_len"; }; then
              objlist="$objlist $obj"
            else
@@ -4063,13 +4059,30 @@ EOF
          IFS="$save_ifs"
          eval cmd=\"$cmd\"
          $show "$cmd"
-         $run eval "$cmd" || exit $?
+         $run eval "$cmd" || {
+           lt_exit=$?
+
+           # Restore the uninstalled library and exit
+           if test "$mode" = relink; then
+             $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+           fi
+
+           exit $lt_exit
+         }
        done
        IFS="$save_ifs"
 
        # Restore the uninstalled library and exit
        if test "$mode" = relink; then
          $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+
+         if test -n "$convenience"; then
+           if test -z "$whole_archive_flag_spec"; then
+             $show "${rm}r $gentop"
+             $run ${rm}r "$gentop"
+           fi
+         fi
+
          exit $EXIT_SUCCESS
        fi
 
@@ -4414,7 +4427,7 @@ extern \"C\" {
            if test -z "$export_symbols"; then
              export_symbols="$output_objdir/$outputname.exp"
              $run $rm $export_symbols
-             $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+             $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
            else
              $run eval "${SED} -e 's/\([ ][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
              $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
@@ -4819,6 +4832,7 @@ EOF
 EOF
 
            cat >> $cwrappersource <<"EOF"
+  return 127;
 }
 
 void *
@@ -5082,13 +5096,13 @@ else
        # Backslashes separate directories on plain windows
        *-*-mingw | *-*-os2*)
          $echo >> $output "\
-      exec \$progdir\\\\\$program \${1+\"\$@\"}
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
 "
          ;;
 
        *)
          $echo >> $output "\
-      exec \$progdir/\$program \${1+\"\$@\"}
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
 "
          ;;
        esac
@@ -5098,7 +5112,7 @@ else
     fi
   else
     # The program doesn't exist.
-    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
     \$echo \"This script is just a wrapper for \$program.\" 1>&2
     $echo \"See the $PACKAGE documentation for more information.\" 1>&2
     exit $EXIT_FAILURE
@@ -5221,7 +5235,7 @@ fi\
            oldobjs="$objlist $obj"
            objlist="$objlist $obj"
            eval test_cmds=\"$old_archive_cmds\"
-           if len=`expr "X$test_cmds" : ".*"` &&
+           if len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
               test "$len" -le "$max_cmd_len"; then
              :
            else
@@ -5418,11 +5432,11 @@ relink_command=\"$relink_command\""
     # install_prog (especially on Windows NT).
     if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
        # Allow the use of GNU shtool's install command.
-       $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then
+       $echo "X$nonopt" | grep shtool > /dev/null; then
       # Aesthetically quote it.
       arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
       case $arg in
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
        arg="\"$arg\""
        ;;
       esac
@@ -5431,14 +5445,14 @@ relink_command=\"$relink_command\""
       shift
     else
       install_prog=
-      arg="$nonopt"
+      arg=$nonopt
     fi
 
     # The real first argument should be the name of the installation program.
     # Aesthetically quote it.
     arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
     case $arg in
-    *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \      ]*|*]*|"")
       arg="\"$arg\""
       ;;
     esac
@@ -5456,28 +5470,31 @@ relink_command=\"$relink_command\""
     do
       if test -n "$dest"; then
        files="$files $dest"
-       dest="$arg"
+       dest=$arg
        continue
       fi
 
       case $arg in
       -d) isdir=yes ;;
-      -f) prev="-f" ;;
-      -g) prev="-g" ;;
-      -m) prev="-m" ;;
-      -o) prev="-o" ;;
+      -f) 
+       case " $install_prog " in
+       *[\\\ /]cp\ *) ;;
+       *) prev=$arg ;;
+       esac
+       ;;
+      -g | -m | -o) prev=$arg ;;
       -s)
        stripme=" -s"
        continue
        ;;
-      -*) ;;
-
+      -*)
+       ;;
       *)
        # If the previous option needed an argument, then skip it.
        if test -n "$prev"; then
          prev=
        else
-         dest="$arg"
+         dest=$arg
          continue
        fi
        ;;
@@ -5486,7 +5503,7 @@ relink_command=\"$relink_command\""
       # Aesthetically quote the argument.
       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
       case $arg in
-      *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
        arg="\"$arg\""
        ;;
       esac
@@ -5655,11 +5672,14 @@ relink_command=\"$relink_command\""
 
          if test "$#" -gt 0; then
            # Delete the old symlinks, and create new ones.
+           # Try `ln -sf' first, because the `ln' binary might depend on
+           # the symlink we replace!  Solaris /bin/ln does not understand -f,
+           # so we also need to try rm && ln -s.
            for linkname
            do
              if test "$linkname" != "$realname"; then
-               $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
-               $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+                $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+                $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
              fi
            done
          fi
@@ -5672,7 +5692,16 @@ relink_command=\"$relink_command\""
            IFS="$save_ifs"
            eval cmd=\"$cmd\"
            $show "$cmd"
-           $run eval "$cmd" || exit $?
+           $run eval "$cmd" || {
+             lt_exit=$?
+
+             # Restore the uninstalled library and exit
+             if test "$mode" = relink; then
+               $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+             fi
+
+             exit $lt_exit
+           }
          done
          IFS="$save_ifs"
        fi
@@ -5773,17 +5802,15 @@ relink_command=\"$relink_command\""
          notinst_deplibs=
          relink_command=
 
-         # To insure that "foo" is sourced, and not "foo.exe",
-         # finese the cygwin/MSYS system by explicitly sourcing "foo."
-         # which disallows the automatic-append-.exe behavior.
-         case $build in
-         *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
-         *) wrapperdot=${wrapper} ;;
-         esac
+         # Note that it is not necessary on cygwin/mingw to append a dot to
+         # foo even if both foo and FILE.exe exist: automatic-append-.exe
+         # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+         # `FILE.' does not work on cygwin managed mounts.
+         #
          # If there is no directory component, then add one.
-         case $file in
-         */* | *\\*) . ${wrapperdot} ;;
-         *) . ./${wrapperdot} ;;
+         case $wrapper in
+         */* | *\\*) . ${wrapper} ;;
+         *) . ./${wrapper} ;;
          esac
 
          # Check the variables that should have been set.
@@ -5811,17 +5838,15 @@ relink_command=\"$relink_command\""
          done
 
          relink_command=
-         # To insure that "foo" is sourced, and not "foo.exe",
-         # finese the cygwin/MSYS system by explicitly sourcing "foo."
-         # which disallows the automatic-append-.exe behavior.
-         case $build in
-         *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
-         *) wrapperdot=${wrapper} ;;
-         esac
+         # Note that it is not necessary on cygwin/mingw to append a dot to
+         # foo even if both foo and FILE.exe exist: automatic-append-.exe
+         # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+         # `FILE.' does not work on cygwin managed mounts.
+         #
          # If there is no directory component, then add one.
-         case $file in
-         */* | *\\*) . ${wrapperdot} ;;
-         *) . ./${wrapperdot} ;;
+         case $wrapper in
+         */* | *\\*) . ${wrapper} ;;
+         *) . ./${wrapper} ;;
          esac
 
          outputname=
@@ -5862,7 +5887,7 @@ relink_command=\"$relink_command\""
        fi
 
        # remove .exe since cygwin /usr/bin/install will append another
-       # one anyways
+       # one anyway 
        case $install_prog,$host in
        */usr/bin/install*,*cygwin*)
          case $file:$destfile in
index e87e13d7d7705f3a0c40bad15e813b0bc3d80754..d921fe736d8c95b0daca7d70f17e3d997f24ed2b 100644 (file)
@@ -206,7 +206,7 @@ main(int argc, char **argv)
     if (havedn)
        retval = domodrdn( ld, entrydn, rdn, newSuperior, remove_old_RDN );
     else while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) {
-       if ( *buf != '\0' ) {   /* blank lines optional, skip */
+       if ( *buf != '\n' ) {   /* blank lines optional, skip */
            buf[ strlen( buf ) - 1 ] = '\0';    /* remove nl */
 
            if ( havedn ) {     /* have DN, get RDN */
index 31556695c0f310e4bbeeb7a6566bfc41ff59d7ec..0acd9cdc13122a2f5e47cb83563755a54e920132 100644 (file)
@@ -345,7 +345,6 @@ main( int argc, char *argv[] )
 
        rc = ldap_parse_result( ld, res,
                &code, &matcheddn, &text, &refs, NULL, 0 );
-
        if( rc != LDAP_SUCCESS ) {
                ldap_perror( ld, "ldap_parse_result" );
                rc = EXIT_FAILURE;
@@ -353,9 +352,8 @@ main( int argc, char *argv[] )
        }
 
        rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
-
        if( rc != LDAP_SUCCESS ) {
-               ldap_perror( ld, "ldap_parse_result" );
+               ldap_perror( ld, "ldap_parse_extended_result" );
                rc = EXIT_FAILURE;
                goto done;
        }
index 44b15b56d7316b2281f57cd6ec425dc1b7df4199..ec8f749343e1c78ddfc4ed6211bc73e2031861dd 100644 (file)
@@ -245,7 +245,7 @@ ol_with_kerberos=${ol_with_kerberos-auto}
 OL_ARG_WITH(threads,[  --with-threads    with threads],
        auto, [auto nt posix mach pth lwp yes no manual] )
 OL_ARG_WITH(tls,[  --with-tls            with TLS/SSL support],
-       auto, [auto ssleay openssl yes no] )
+       auto, [auto openssl yes no] )
 OL_ARG_WITH(yielding_select,[  --with-yielding-select  with implicitly yielding select],
        auto, [auto yes no manual] )
 OL_ARG_WITH(multiple_precision,[  --with-multiple-precision
@@ -1312,40 +1312,31 @@ dnl TLS/SSL
        
 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 ||
-          test $ac_cv_header_ssl_h = yes ; then
-               AC_CHECK_LIB(ssl, SSLeay_add_ssl_algorithms, 
-                       [have_ssleay=yes
-                       need_rsaref=no],
-                       [have_ssleay=no],
+       AC_CHECK_HEADERS(openssl/ssl.h)
+
+       if test $ac_cv_header_openssl_ssl_h = yes ; then
+               AC_CHECK_LIB(ssl, SSL_library_init,
+                       [have_openssl=yes
+                       need_rsaref=no], [have_openssl=no],
                        [-lcrypto])
-                       
-               if test $have_ssleay = no ; then
-                       AC_CHECK_LIB(ssl, SSL_library_init,
-                               [have_ssleay=yes
-                               need_rsaref=no], [have_ssleay=no],
-                               [-lcrypto])
-               fi
 
-               if test $have_ssleay = no ; then
+               if test $have_openssl = no ; then
                        AC_CHECK_LIB(ssl, ssl3_accept, 
-                               [have_ssleay=yes
-                               need_rsaref=yes], [have_ssleay=no],
+                               [have_openssl=yes
+                               need_rsaref=yes], [have_openssl=no],
                                [-lcrypto -lRSAglue -lrsaref])
                fi
 
-               if test $have_ssleay = yes ; then
+               if test $have_openssl = yes ; then
                        ol_with_tls=found
                        ol_link_tls=yes
 
-                       AC_DEFINE(HAVE_SSLEAY, 1, 
-                               [define if you have SSLeay or OpenSSL])
+                       AC_DEFINE(HAVE_OPENSSL, 1, 
+                               [define if you have OpenSSL])
 
                        if test $need_rsaref = yes; then
                                AC_DEFINE(HAVE_RSAREF, 1, 
-                                       [define if you have RSAref])
+                                       [define if OpenSSL needs RSAref])
 
                                TLS_LIBS="-lssl -lcrypto -lRSAglue -lrsaref"
                        else
@@ -2408,7 +2399,7 @@ if test "$ol_with_multiple_precision" != "no" ; then
        case "$ol_mp_support" in
        bignum)
                AC_DEFINE(HAVE_BIGNUM, 1,
-                       [define if you have SSLeay or OpenSSL's BIGNUM])
+                       [define if you have OpenSSL's BIGNUM])
                ;;
        gmp)
                AC_DEFINE(HAVE_GMP, 1, [define if you have -lgmp])
@@ -2540,6 +2531,7 @@ AC_CHECK_FUNCS(           \
        getspnam                \
        gettimeofday    \
        initgroups              \
+       inet_ntoa_b             \
        lockf                   \
        memcpy                  \
        memmove                 \
index 3bac38736dbb34a8b19e066e16de21665f8db72e..9e8f27c7df8da5b6080688d76bb9f8a40d01d6cf 100644 (file)
@@ -23,9 +23,9 @@
 
 #include <slap.h>
 #include <ac/errno.h>
+#include <ac/string.h>
 
 #ifdef DO_KRB5
-#include <ac/string.h>
 #include <lber.h>
 #include <lber_pvt.h>
 #include <lutil.h>
@@ -57,6 +57,7 @@ static ObjectClass *oc_krb5KDCEntry;
 #ifdef DO_SAMBA
 #include <openssl/des.h>
 #include <openssl/md4.h>
+#include "ldap_utf8.h"
 
 static AttributeDescription *ad_sambaLMPassword;
 static AttributeDescription *ad_sambaNTPassword;
@@ -155,7 +156,6 @@ static void nthash(
         * 256 UCS2 characters, not 256 bytes...
         */
        char hbuf[HASHLEN];
-       int i;
        MD4_CTX ctx;
 
        if (passwd->bv_len > MAX_PWLEN*2)
@@ -307,10 +307,9 @@ static int smbk5pwd_exop_passwd(
        Operation *op,
        SlapReply *rs )
 {
-       int i, rc;
+       int rc;
        req_pwdexop_s *qpw = &op->oq_pwdexop;
        Entry *e;
-       Attribute *a;
        Modifications *ml;
        slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
 
@@ -329,7 +328,8 @@ static int smbk5pwd_exop_passwd(
                krb5_error_code ret;
                hdb_entry ent;
                struct berval *keys;
-               int kvno;
+               int kvno, i;
+               Attribute *a;
 
                if ( !is_entry_objectclass(e, oc_krb5KDCEntry, 0 ) ) break;
 
@@ -365,8 +365,7 @@ static int smbk5pwd_exop_passwd(
                        keys[i].bv_val = (char *)buf;
                        keys[i].bv_len = len;
                }
-               keys[i].bv_val = NULL;
-               keys[i].bv_len = 0;
+               BER_BVZERO( &keys[i] );
 
                _kadm5_free_keys(kadm_context, ent.keys.len, ent.keys.val);
 
@@ -401,8 +400,7 @@ static int smbk5pwd_exop_passwd(
                ml->sml_values[0].bv_val = ch_malloc( 64 );
                ml->sml_values[0].bv_len = sprintf(ml->sml_values[0].bv_val,
                        "%d", kvno+1 );
-               ml->sml_values[1].bv_val = NULL;
-               ml->sml_values[1].bv_len = 0;
+               BER_BVZERO( &ml->sml_values[1] );
                ml->sml_nvalues = NULL;
        } while(0);
 #endif /* DO_KRB5 */
@@ -439,8 +437,7 @@ static int smbk5pwd_exop_passwd(
                qpw->rs_mods = ml;
 
                keys = ch_malloc( 2 * sizeof(struct berval) );
-               keys[1].bv_val = NULL;
-               keys[1].bv_len = 0;
+               BER_BVZERO( &keys[1] );
                nthash( &pwd, keys );
                
                ml->sml_desc = ad_sambaNTPassword;
@@ -466,8 +463,7 @@ static int smbk5pwd_exop_passwd(
                qpw->rs_mods = ml;
 
                keys = ch_malloc( 2 * sizeof(struct berval) );
-               keys[1].bv_val = NULL;
-               keys[1].bv_len = 0;
+               BER_BVZERO( &keys[1] );
                lmhash( &pwd, keys );
                
                ml->sml_desc = ad_sambaLMPassword;
@@ -485,11 +481,11 @@ static int smbk5pwd_exop_passwd(
                qpw->rs_mods = ml;
 
                keys = ch_malloc( 2 * sizeof(struct berval) );
-               keys[1].bv_val = NULL;
-               keys[1].bv_len = 0;
-               keys[0].bv_val = ch_malloc(16);
-               keys[0].bv_len = sprintf(keys[0].bv_val, "%d",
-                       slap_get_time());
+               keys[0].bv_val = ch_malloc( STRLENOF( "9223372036854775807L" ) + 1 );
+               keys[0].bv_len = snprintf(keys[0].bv_val,
+                       STRLENOF( "9223372036854775807L" ) + 1,
+                       "%ld", slap_get_time());
+               BER_BVZERO( &keys[1] );
                
                ml->sml_desc = ad_sambaPwdLastSet;
                ml->sml_op = LDAP_MOD_REPLACE;
index b7e6bca01821d63480fac37512bbe3114ff1d98e..a1bba31b4af8ff3a6cd2242cbe3d8865c28eeba0 100644 (file)
@@ -48,6 +48,7 @@ Localize tools
 
 Small projects
 --------------
+Add BSD kqueue(2) support to slapd(8)
 Add DSML capabilities to command line tools
 Add LDIFv2 (XML) support to command line tools
 Implement authPassword (RFC 3112)
index 182aa1dd8d2b1ba08deb1cc6777cb2821503cb26..fcbdd68a85343aca45d730c7e208300a06b062ad 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 1999-2003, The OpenLDAP Foundation, All Rights Reserved.
+# Copyright 1999-2005, The OpenLDAP Foundation, All Rights Reserved.
 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
 
 H1: Using TLS
@@ -132,6 +132,16 @@ bytes of arbitrary data into the file. The file is only used to
 provide a seed for the pseudo-random number generator, and it doesn't
 need very much data to work.
 
+H4: TLSEphemeralDHParamFile <filename>
+
+This directive specifies the file that contains parameters for Diffie-Hellman
+ephemeral key exchange.  This is required in order to use a DSA certificate on
+the server side (i.e. {{EX:TLSCertificateKeyFile}} points to a DSA key).
+Multiple sets of parameters can be included in the file; all of them will
+be processed.  Parameters can be generated using the following command
+
+>      openssl dhparam [-dsaparam] -out <filename> <numbits>
+
 H4: TLSVerifyClient { never | allow | try | demand }
 
 This directive specifies what checks to perform on client certificates
index c9cd6f8b9a271167cef1e42ba08ce6b4ada4d445..9e85767a009c54b4cf3fa951f65ba14ac389a9f8 100644 (file)
@@ -76,16 +76,15 @@ All character string input/output is expected to be/is UTF\-8
 encoded Unicode (version 3.2). 
 .LP
 Distinguished names (DN) (and relative distinguished names (RDN) to
-be passed to the LDAP routines should conform to RFC 2253.  The
-.BR ldap_explode_dn (3)
-routines can be used to work with DNs.
+be passed to the LDAP routines should conform to RFC 2253 UTF\-8
+string representation. 
 .LP
 Search filters to be passed to the search routines are to be
-constructed by hand and should conform to RFC 2254.
+constructed by hand and should conform to RFC 2254 UTF\-8
+string representation.
 .LP
 LDAP URL are to be passed to routines are expected to conform
-to RFC 2255.
-The
+to RFC 2255 syntax.  The
 .BR ldap_url (3)
 routines can be used to work with LDAP URLs.
 .SH DISPLAYING RESULTS
@@ -194,12 +193,6 @@ return number of entries in a search result
 .SM ldap_get_dn(3)
 extract the DN from an entry
 .TP
-.SM ldap_explode_dn(3)
-convert a DN into its component parts (deprecated)
-.TP
-.SM ldap_explode_rdn(3)
-convert an RDN into its component parts (deprecated)
-.TP
 .SM ldap_get_values_len(3)
 return an attribute's values with lengths
 .TP
index 924b00a43167a93bff1b16c0d197485219593204..2ff81bbcbc0c3804c3550586a1e7e2b44ee6946b 100644 (file)
@@ -859,9 +859,15 @@ See
 .BR limits
 for an explanation of the different flags.
 .TP
-.B ucdata-path <path>
-Specify the path to the directory containing the Unicode character
-tables. The default path is DATADIR/ucdata.
+.B tool-threads <integer>
+Specify the maximum number of threads to use in tool mode.
+This should not be greater than the number of CPUs in the system.
+The default is 1.
+.\"ucdata-path is obsolete / ignored...
+.\".TP
+.\".B ucdata-path <path>
+.\"Specify the path to the directory containing the Unicode character
+.\"tables. The default path is DATADIR/ucdata.
 .SH TLS OPTIONS
 If
 .B slapd
@@ -902,6 +908,12 @@ server private key that matches the certificate stored in the
 file.  Currently, the private key must not be protected with a password, so
 it is of critical importance that it is protected carefully. 
 .TP
+.B TLSDHParamFile <filename>
+This directive specifies the file that contains parameters for Diffie-Hellman
+ephemeral key exchange.  This is required in order to use a DSA certificate on
+the server. If multiple sets of parameters are present in the file, all of
+them will be processed.
+.TP
 .B TLSRandFile <filename>
 Specifies the file to obtain random bits from when /dev/[u]random
 is not available.  Generally set to the name of the EGD/PRNGD socket.
@@ -1464,6 +1476,9 @@ in order to work over all of the glued databases. E.g.
 .B [credentials=<passwd>]
 .B [realm=<realm>]
 .B [secprops=<properties>]
+.B [logbase=<base DN>]
+.B [logfilter=<filter str>]
+.B [syncdata=default|accesslog|changelog]
 .RS
 Specify the current database as a replica which is kept up-to-date with the 
 master content by establishing the current
@@ -1568,6 +1583,22 @@ keyword above) for a SASL bind can be set with the
 option. A non default SASL realm can be set with the
 .B realm 
 option.
+
+Rather than replicating whole entries, the consumer can query logs of
+data modifications. This mode of operation is referred to as \fIdelta
+syncrepl\fP. In addition to the above parameters, the
+.B logbase
+and
+.B logfilter
+parameters must be set appropriately for the log that will be used. The
+.B syncdata
+parameter must be set to either "accesslog" if the log conforms to the
+.BR slapo-accesslog (5)
+log format, or "changelog" if the log conforms
+to the obsolete \fIchangelog\fP format. If the
+.B syncdata
+parameter is omitted or set to "default" then the log parameters are
+ignored.
 .RE
 .TP
 .B updatedn <dn>
@@ -1629,14 +1660,12 @@ It uses Berkeley DB or GDBM to store data.
 .B ldif
 This database uses the filesystem to build the tree structure
 of the database, using plain ascii files to store data.
-Its usage should be limited to very simple databases, where performances
-are not a requirement.
+Its usage should be limited to very simple databases, where performance
+is not a requirement.
 .TP
 .B meta
 This backend performs basic LDAP proxying with respect to a set of
-remote LDAP servers. It is an enhancement of the ldap backend. The
-proxy cache extension of meta backend provides answering of search
-requests from the proxy using results of previously cached requests.
+remote LDAP servers. It is an enhancement of the ldap backend.
 .TP
 .B monitor
 This backend provides information about the running status of the slapd
@@ -1722,6 +1751,7 @@ operation performed on that database.
 .B pcache
 Proxycache.
 This overlay allows caching of LDAP search requests in a local database.
+It is most often used with the ldap or meta backends.
 .TP
 .B ppolicy
 Password Policy.
index 0b1cf78c284b0c9ddac86b718dc9562145590d48..9e869a2cc52bd716ff221a273d49329f4e0ab9ad 100644 (file)
@@ -12,9 +12,9 @@ backend database on another database. This allows all of the activity on
 a given database to be reviewed using arbitrary LDAP queries, instead of
 just logging to local flat text files. Configuration options are available
 for selecting a subset of operation types to log, and to automatically
-prune older log records from the logging database. Log records are stored
-with a custom schema to assure their readability whether viewed as LDIF
-or in raw form.
+prune older log records from the logging database.  Log records are stored
+with audit schema (see below) to assure their readability whether viewed
+as LDIF or in raw form.
 .SH CONFIGURATION
 These
 .B slapd.conf
@@ -58,14 +58,14 @@ and how often to scan the database for old entries. Both the
 and
 .B interval
 are specified as a time span in days, hours, minutes, and seconds. The
-time format is [dd+]hh:mm[:ss] i.e., the days and seconds components are
-optional but hours and minutes are required. Each numeric field must be
-exactly two digits. For example
+time format is [ddd+]hh:mm[:ss] i.e., the days and seconds components are
+optional but hours and minutes are required. Except for days, which can
+be up to 5 digits, each numeric field must be exactly two digits. For example
 .RS
 .RS
 .PD 0
 .TP
-logpurge 02+00:00 01+00:00
+logpurge 2+00:00 1+00:00
 .RE
 .PD
 would specify that the log database should be scanned every day for old
@@ -74,6 +74,13 @@ log database that supports ordered indexing on generalizedTime attributes,
 specifying an eq index on the
 .B reqStart
 attribute will greatly benefit the performance of the purge operation.
+.RE
+.TP
+.B logsuccess TRUE | FALSE
+If set to TRUE then log records will only be generated for successful
+requests, i.e., requests that produce a result code of 0 (LDAP_SUCCESS).
+If FALSE, log records are generated for all requests whether they
+succeed or not. The default is FALSE.
 
 .SH EXAMPLES
 .LP
@@ -91,10 +98,23 @@ attribute will greatly benefit the performance of the purge operation.
        logops writes reads
 .fi
 
-.SH OBJECT CLASSES
+.SH SCHEMA
 The
 .B accesslog
-overlay defines a number of object classes for use in the logs. There is
+overlay utilizes the "audit" schema described herein.
+This schema is specifically designed for
+.B accesslog
+auditing and is not intended to be used otherwise.  It is also
+noted that the schema describe here is
+.I a work in
+.IR progress ,
+and hence subject to change without notice.
+The schema is loaded automatically by the overlay.
+
+The schema includes a number of object classes and associated
+attribute types as described below.
+
+There is
 a basic
 .B auditObject
 class from which two additional classes,
@@ -116,7 +136,7 @@ class is as follows:
     SUP top STRUCTURAL
     MUST ( reqStart $ reqType $ reqSession )
     MAY ( reqDN $ reqAuthzID $ reqControls $ reqRespControls $
-        reqEnd $ reqResult $ reqMessage ) )
+        reqEnd $ reqResult $ reqMessage $ reqReferral ) )
 .RE
 .P
 Note that all of the OIDs used in the logging schema currently reside
@@ -141,7 +161,7 @@ being logged, e.g.
 .BR search ,
 etc. For extended operations, the type also includes the OID of the
 extended operation, e.g.
-.B extended(1.2.3.4.1)
+.B extended(1.1.1.1)
 
 The
 .B reqSession
@@ -179,6 +199,11 @@ accompanied by a text error message which will be recorded in the
 .B reqMessage
 attribute.
 
+The
+.B reqReferral
+attribute carries any referrals that were returned with the result of the
+request.
+
 Operation-specific classes are defined with additional attributes to carry
 all of the relevant parameters associated with the operation:
 
@@ -210,36 +235,37 @@ The
 .B Add
 class inherits from the
 .B auditWriteObject
-class. The Add and Modify classes are essentially the same. The
+class. The Add and Modify classes are very similar. The
 .B reqMod
 attribute carries all of the attributes of the original entry being added.
 (Or in the case of a Modify operation, all of the modifications being
 performed.) The values are formatted as
 .RS
-.RS
 .PD 0
 .TP
 attribute:<+|-|=|#> [ value]
 .RE
+.RE
 .PD
 Where '+' indicates an Add of a value, '-' for Delete, '=' for Replace,
 and '#' for Increment. In an Add operation, all of the reqMod values will
 have the '+' designator.
-.RE
 .P
-
 .LP
 .RS 4
 (  1.3.6.1.4.1.4203.666.11.5.2.6
     NAME 'auditBind'
     DESC 'Bind operation'
     SUP auditObject STRUCTURAL
-    MUST reqMethod )
+    MUST ( reqVersion $ reqMethod ) )
 .RE
 .P
 The
 .B Bind
-class just adds the
+class includes the
+.B reqVersion
+attribute which contains the LDAP protocol version specified in the Bind
+as well as the
 .B reqMethod
 attribute which contains the Bind Method used in the Bind. This will be
 the string
@@ -268,19 +294,48 @@ attribute carries the Attribute Value Assertion used in the compare request.
 .LP
 .RS 4
 (  1.3.6.1.4.1.4203.666.11.5.2.8
+    NAME 'auditDelete'
+    DESC 'Delete operation'
+    SUP auditWriteObject STRUCTURAL
+    MAY reqOld )
+.RE
+.P
+The
+.B Delete
+operation needs no further parameters. However, the
+.B reqOld
+attribute may optionally be used to record the contents of the entry prior
+to its deletion. The values are formatted as
+.RS
+.PD 0
+.TP
+attribute: value
+.RE
+.PD
+This option is not yet implemented.
+
+.LP
+.RS 4
+(  1.3.6.1.4.1.4203.666.11.5.2.9
     NAME 'auditModify'
     DESC 'Modify operation'
     SUP auditWriteObject STRUCTURAL
-    MUST reqMod )
+    MAY reqOld MUST reqMod )
 .RE
 .P
 The
 .B Modify
-operation has already been described.
+operation contains a description of modifications in the
+.B reqMod
+attribute, which was already described above in the Add operation. It may
+optionally contain the previous contents of any modified attributes in the
+.B reqOld
+attribute, using the same format as described above for the Delete operation.
+This option is not yet implemented.
 
 .LP
 .RS 4
-(  1.3.6.1.4.1.4203.666.11.5.2.9
+(  1.3.6.1.4.1.4203.666.11.5.2.10
     NAME 'auditModRDN'
     DESC 'ModRDN operation'
     SUP auditWriteObject STRUCTURAL
@@ -307,11 +362,11 @@ the new parent.
 
 .LP
 .RS 4
-(  1.3.6.1.4.1.4203.666.11.5.2.10
+(  1.3.6.1.4.1.4203.666.11.5.2.11
     NAME 'auditSearch'
     DESC 'Search operation'
     SUP auditReadObject STRUCTURAL
-    MUST ( reqScope $ reqAttrsOnly )
+    MUST ( reqScope $ reqDerefAliases $ reqAttrsOnly )
     MAY ( reqFilter $ reqAttr $ reqEntries $ reqSizeLimit $
           reqTimeLimit ) )
 .RE
@@ -320,12 +375,22 @@ For the
 .B Search
 class the
 .B reqScope
-attribute contains the scope of the original search request, i.e.
+attribute contains the scope of the original search request, using the
+values specified for the LDAP URL format. I.e.
 .BR base ,
-.BR onelevel ,
-.BR subtree ,
+.BR one ,
+.BR sub ,
+or
+.BR subord .
+The
+.B reqDerefAliases
+attribute is one of
+.BR never ,
+.BR finding ,
+.BR searching ,
 or
-.BR subordinate .
+.BR always ,
+denoting how aliases will be processed during the search.
 The
 .B reqAttrsOnly
 attribute is a Boolean value showing
@@ -352,7 +417,7 @@ attributes indicate what limits were requested on the search operation.
 
 .LP
 .RS 4
-(  1.3.6.1.4.1.4203.666.11.5.2.11
+(  1.3.6.1.4.1.4203.666.11.5.2.12
     NAME 'auditExtended'
     DESC 'Extended operation'
     SUP auditObject STRUCTURAL
index be612cd306737447c5749d143cabaac79dedb06f..78cef21866a532243e05bad8769f08bfe56282aa 100644 (file)
@@ -73,7 +73,20 @@ Enables exploitation of in-directory stored errAbsObject.
 May result in a lot of unnecessary overhead.
 
 .SH SCHEMA
-The following schema items are created and used by the overlay:
+The
+.B retcode
+overlay utilizes the "return code" schema described herein. 
+This schema is specifically designed for use with this
+overlay and is not intended to be used otherwise.
+It is also noted that the schema describe here is
+.I a work in
+.IR progress ,
+and hence subject to change without notice.
+The schema is loaded automatically by the overlay.
+
+The schema includes a number of object classes and associated
+attribute types as described below.
+
 .LP
 The error code:
 .RS 4
index 02cf2337401561edf7256bccbac8a744b5bc6ee6..884ceeff530da2f665c79fc6b1c4f9c2668aa0d1 100644 (file)
@@ -52,10 +52,25 @@ specifies the number of operations that are recorded in the log. All write
 operations (except Adds) are recorded in the log.
 When using the session log, it is helpful to set an eq index on the
 entryUUID attribute in the underlying database.
+.TP
+.B syncprov-nopresent TRUE | FALSE
+Specify that the Present phase of refreshing should be skipped. This value
+should only be set TRUE for a syncprov instance on top of a log database
+(such as one managed by the accesslog overlay).
+The default is FALSE.
+.TP
+.B syncprov-reloadhint TRUE | FALSE
+Specify that the overlay should honor the reloadHint flag in the Syncrepl
+Control. In OpenLDAP releases 2.3.11 and earlier the Syncrepl consumer did
+not properly set this flag, so the overlay must ignore it. This option
+should be set TRUE when working with newer releases that properly support
+this flag. It must be set TRUE when using the accesslog overlay for
+delta-based Syncrepl support.  The default is FALSE.
 .SH FILES
 .TP
 ETCDIR/slapd.conf
 default slapd configuration file
 .SH SEE ALSO
-.BR slapd.conf (5).
+.BR slapd.conf (5),
+.BR slapo-accesslog (5).
 OpenLDAP Administrator's Guide.
index 62352889050d364367f2ae713d7b1e8d404df159..d6ba8c71740d0d4142370f4a23031b864a5867b1 100644 (file)
@@ -8,6 +8,7 @@ slapadd \- Add entries to a SLAPD database
 .B SBINDIR/slapadd
 .B [\-v]
 .B [\-c]
+.B [\-g]
 .B [\-u]
 .B [\-q]
 .B [\-w]
@@ -29,7 +30,7 @@ suffix and adds entries corresponding to the provided LDIF to
 the database.
 Databases configured as
 .B subordinate
-of this one are also updated.
+of this one are also updated, unless \fB-g\fP is specified.
 The LDIF input is read from standard input or the specified file.
 .LP
 As
@@ -48,6 +49,10 @@ enable verbose mode.
 .B \-c
 enable continue (ignore errors) mode.
 .TP
+.B \-g
+disable subordinate gluing.  Only the specified database will be
+processed, and not its glued subordinates (if any).
+.TP
 .B \-u
 enable dry-run (don't write to backend) mode.
 .TP
index 6b8242c610274f32b92d1c0828ec9887c2927904..eb91acf85059e43426a92aaa7c836c95ceef529d 100644 (file)
@@ -8,6 +8,7 @@ slapauth \- Check a list of string-represented IDs for authc/authz.
 .B [\-v]
 .B [\-d level]
 .B [\-f slapd.conf]
+.B [\-F confdir]
 .B [\-M mech]
 .B [\-R realm]
 .B [\-U authcID]
@@ -44,6 +45,19 @@ specify an alternative
 .BR slapd.conf (5)
 file.
 .TP
+.BI \-F " confdir"
+specify a config directory.
+If both
+.B -f
+and
+.B -F
+are specified, the config file will be read and converted to
+config directory format and written to the specified directory.
+If neither option is specified, an attempt to read the
+default config directory wll be made before trying to use the default
+config file. If a valid config directory exists then the
+default config file is ignored.
+.TP
 .BI \-M " mech"
 specify a mechanism.
 .TP
index 03a0aa5d4a5e92e87e6f30fcdab0ebadd6ec0a2c..62092b4b9c3ad6857a9d96f785cede3e2d305ff5 100644 (file)
@@ -8,12 +8,14 @@ slapcat \- SLAPD database to LDIF utility
 .B SBINDIR/slapcat
 .B [\-v]
 .B [\-c]
+.B [\-g]
 .B [\-d level]
 .B [\-b suffix]
 .B [\-n dbnum]
 .B [\-a filter]
 .B [\-s subtree-dn]
 .B [\-f slapd.conf]
+.B [\-F confdir]
 .B [\-l ldif-file]
 .B 
 .LP
@@ -29,7 +31,7 @@ suffix and writes the corresponding LDIF to standard output or
 the specified file.
 Databases configured as
 .B subordinate
-of this one are also output.
+of this one are also output, unless \fB-g\fP is specified.
 .LP
 The LDIF generated by this tool is suitable for use with
 .BR slapadd (8).
@@ -45,6 +47,10 @@ Enable verbose mode.
 .B \-c
 Enable continue (ignore errors) mode.
 .TP
+.B \-g
+disable subordinate gluing.  Only the specified database will be
+processed, and not its glued subordinates (if any).
+.TP
 .BI \-d " level"
 Enable debugging messages as defined by the specified
 .IR level .
@@ -87,6 +93,19 @@ Specify an alternative
 .BR slapd.conf (5)
 file.
 .TP
+.BI \-F " confdir"
+specify a config directory.
+If both
+.B -f
+and
+.B -F
+are specified, the config file will be read and converted to
+config directory format and written to the specified directory.
+If neither option is specified, an attempt to read the
+default config directory wll be made before trying to use the default
+config file. If a valid config directory exists then the
+default config file is ignored.
+.TP
 .BI \-l " ldif-file"
 Write LDIF to specified file instead of standard output.
 .SH LIMITATIONS
index c2a54649caa560164450e6be793799870c42dcef..9099256db926ec67f2d24ccdbf4b3c2d81b1ae2f 100644 (file)
@@ -41,6 +41,19 @@ specify an alternative
 .BR slapd.conf (5)
 file.
 .TP
+.BI \-F " confdir"
+specify a config directory.
+If both
+.B -f
+and
+.B -F
+are specified, the config file will be read and converted to
+config directory format and written to the specified directory.
+If neither option is specified, an attempt to read the
+default config directory wll be made before trying to use the default
+config file. If a valid config directory exists then the
+default config file is ignored.
+.TP
 .BI \-N
 only output a normalized form of the DN, suitable to be used
 in a normalization tool; incompatible with
index 57a0391efa585f00c8226be59087262ec047ba73..2295301de836ca58d1d5267745e3d1ee062ca7b8 100644 (file)
@@ -8,6 +8,7 @@ slapindex \- SLAPD index to LDIF utility
 .B SBINDIR/slapindex
 .B [\-v]
 .B [\-c]
+.B [\-g]
 .B [\-q]
 .B [\-d level]
 .B [\-b suffix]
@@ -27,7 +28,7 @@ suffix and updates the indices for all values of all attributes
 of all entries.
 Databases configured as
 .B subordinate
-of this one are also re-indexed.
+of this one are also re-indexed, unless \fB-g\fP is specified.
 .SH OPTIONS
 .TP
 .B \-v
@@ -36,6 +37,10 @@ enable verbose mode.
 .B \-c
 enable continue (ignore errors) mode.
 .TP
+.B \-g
+disable subordinate gluing.  Only the specified database will be
+processed, and not its glued subordinates (if any).
+.TP
 .B \-q
 enable quick (fewer integrity checks) mode. Performs no consistency checks
 when writing the database. Improves indexing time, but if any errors or
index 201db1e836802070a05608662a469d1b90d92705..7cfba13cf083369f5022aa108731458b08126b8f 100644 (file)
@@ -136,6 +136,7 @@ LDAP_BEGIN_DECL
 #define LDAP_OPT_X_TLS_CRLCHECK                0x600b
 #define LDAP_OPT_X_TLS_CONNECT_CB      0x600c
 #define LDAP_OPT_X_TLS_CONNECT_ARG     0x600d
+#define LDAP_OPT_X_TLS_DHFILE          0x600e
 
 #define LDAP_OPT_X_TLS_NEVER   0
 #define LDAP_OPT_X_TLS_HARD            1
@@ -203,20 +204,26 @@ typedef struct ldapcontrol {
 
 /* LDAP Controls */
 /*     standard track controls */
-#define LDAP_CONTROL_MANAGEDSAIT               "2.16.840.1.113730.3.4.2" /* RFC 3296 */
-#define LDAP_CONTROL_SUBENTRIES                        "1.3.6.1.4.1.4203.1.10.1" /* RFC 3672 */
-#define LDAP_CONTROL_PAGEDRESULTS              "1.2.840.113556.1.4.319"  /* RFC 2696 */
-#define LDAP_CONTROL_VALUESRETURNFILTER        "1.2.826.0.1.334810.2.3"  /* RFC 3876 */
-#define LDAP_CONTROL_ASSERT                            "1.3.6.1.1.12"
-#define LDAP_CONTROL_PRE_READ                  "1.3.6.1.1.13.1"
-#define LDAP_CONTROL_POST_READ                 "1.3.6.1.1.13.2"
+#define LDAP_CONTROL_MANAGEDSAIT       "2.16.840.1.113730.3.4.2"  /* RFC 3296 */
+#define LDAP_CONTROL_PROXY_AUTHZ       "2.16.840.1.113730.3.4.18" /* RFC TBD  */
+#define LDAP_CONTROL_SUBENTRIES                "1.3.6.1.4.1.4203.1.10.1"  /* RFC 3672 */
+
+#define LDAP_CONTROL_VALUESRETURNFILTER        "1.2.826.0.1.334810.2.3"/* RFC 3876 */
+#define LDAP_CONTROL_ASSERT                            "1.3.6.1.1.12"                  /* RFC TBD */
+#define LDAP_CONTROL_PRE_READ                  "1.3.6.1.1.13.1"                /* RFC TBD */
+#define LDAP_CONTROL_POST_READ                 "1.3.6.1.1.13.2"                /* RFC TBD */
 
 /*  standard track - not implemented in slapd(8) */
 #define LDAP_CONTROL_SORTREQUEST    "1.2.840.113556.1.4.473" /* RFC 2891 */
 #define LDAP_CONTROL_SORTRESPONSE      "1.2.840.113556.1.4.474" /* RFC 2891 */
 
-/* but not yet formalized controls */
-#define LDAP_CONTROL_PROXY_AUTHZ               "2.16.840.1.113730.3.4.18"
+/*     non-standard track controls */
+#define LDAP_CONTROL_PAGEDRESULTS      "1.2.840.113556.1.4.319"   /* RFC 2696 */
+
+/* Password policy Controls *//* work in progress */
+/* ITS#3458: released; disabled by default */
+#define LDAP_CONTROL_PASSWORDPOLICYREQUEST     "1.3.6.1.4.1.42.2.27.8.5.1"
+#define LDAP_CONTROL_PASSWORDPOLICYRESPONSE    "1.3.6.1.4.1.42.2.27.8.5.1"
 
 /* various works in progress */
 #define LDAP_CONTROL_NOOP                              "1.3.6.1.4.1.4203.666.5.2"
@@ -225,30 +232,6 @@ typedef struct ldapcontrol {
 #define LDAP_CONTROL_SLURP                             "1.3.6.1.4.1.4203.666.5.13"
 #define LDAP_CONTROL_VALSORT                   "1.3.6.1.4.1.4203.666.5.14"
 
-/* LDAP Duplicated Entry Control Extension *//* not implemented in slapd(8) */
-#define LDAP_CONTROL_DUPENT_REQUEST            "2.16.840.1.113719.1.27.101.1"
-#define LDAP_CONTROL_DUPENT_RESPONSE   "2.16.840.1.113719.1.27.101.2"
-#define LDAP_CONTROL_DUPENT_ENTRY              "2.16.840.1.113719.1.27.101.3"
-#define LDAP_CONTROL_DUPENT    LDAP_CONTROL_DUPENT_REQUEST
-
-/* LDAP Persistent Search Control *//* not implemented in slapd(8) */
-/* draft-ietf-ldapext-psearch-03.txt (expired) */
-#define LDAP_CONTROL_PERSIST_REQUEST                           "2.16.840.1.113730.3.4.3"
-#define LDAP_CONTROL_PERSIST_ENTRY_CHANGE_NOTICE       "2.16.840.1.113730.3.4.7"
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_ADD          0x1
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_DELETE       0x2
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_MODIFY       0x4
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_RENAME       0x8
-
-/* LDAP VLV *//* not implemented in slapd(8) */
-#define LDAP_CONTROL_VLVREQUEST        "2.16.840.1.113730.3.4.9"
-#define LDAP_CONTROL_VLVRESPONSE    "2.16.840.1.113730.3.4.10"
-
-/* Password policy Controls *//* work in progress */
-/* ITS#3458: released; disabled by default */
-#define LDAP_CONTROL_PASSWORDPOLICYREQUEST     "1.3.6.1.4.1.42.2.27.8.5.1"
-#define LDAP_CONTROL_PASSWORDPOLICYRESPONSE    "1.3.6.1.4.1.42.2.27.8.5.1"
-
 /* LDAP Sync -- draft-zeilenga-ldup-sync *//* submitted for publication */
 #define LDAP_SYNC_OID                  "1.3.6.1.4.1.4203.1.9.1"
 #define LDAP_CONTROL_SYNC              LDAP_SYNC_OID ".1"
@@ -291,16 +274,38 @@ typedef struct ldapcontrol {
 #define LDAP_REFERRALS_REQUIRED                                3
 #endif
 
-/* MS ActiveDirectory controls (for compatibility) */
-#define LDAP_CONTROL_X_DOMAIN_SCOPE            "1.2.840.113556.1.4.1339"
-#define LDAP_CONTROL_X_PERMISSIVE_MODIFY       "1.2.840.113556.1.4.1413"
+/* MS Active Directory controls (for compatibility) */
 #define LDAP_CONTROL_X_INCREMENTAL_VALUES      "1.2.840.113556.1.4.802"
-#define LDAP_CONTROL_X_TREE_DELETE             "1.2.840.113556.1.4.805"
+#define LDAP_CONTROL_X_DOMAIN_SCOPE                    "1.2.840.113556.1.4.1339"
+#define LDAP_CONTROL_X_PERMISSIVE_MODIFY       "1.2.840.113556.1.4.1413"
 #define LDAP_CONTROL_X_SEARCH_OPTIONS          "1.2.840.113556.1.4.1340"
-#define LDAP_SEARCH_FLAG_DOMAIN_SCOPE          1 /* do not generate referrals */
-#define LDAP_SEARCH_FLAG_PHANTOM_ROOT          2 /* search all NCs subordinate to base */
+#define LDAP_SEARCH_FLAG_DOMAIN_SCOPE 1 /* do not generate referrals */
+#define LDAP_SEARCH_FLAG_PHANTOM_ROOT 2 /* search all subordinate NCs */
+
+/* MS Active Directory controls - not implemented in slapd(8) */
+#define LDAP_CONTROL_X_TREE_DELETE             "1.2.840.113556.1.4.805"
 #define LDAP_CONTROL_X_EXTENDED_DN             "1.2.840.113556.1.4.529"
 
+/* various expired works */
+/* LDAP Duplicated Entry Control Extension *//* not implemented in slapd(8) */
+#define LDAP_CONTROL_DUPENT_REQUEST            "2.16.840.1.113719.1.27.101.1"
+#define LDAP_CONTROL_DUPENT_RESPONSE   "2.16.840.1.113719.1.27.101.2"
+#define LDAP_CONTROL_DUPENT_ENTRY              "2.16.840.1.113719.1.27.101.3"
+#define LDAP_CONTROL_DUPENT    LDAP_CONTROL_DUPENT_REQUEST
+
+/* LDAP Persistent Search Control *//* not implemented in slapd(8) */
+#define LDAP_CONTROL_PERSIST_REQUEST                           "2.16.840.1.113730.3.4.3"
+#define LDAP_CONTROL_PERSIST_ENTRY_CHANGE_NOTICE       "2.16.840.1.113730.3.4.7"
+#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_ADD          0x1
+#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_DELETE       0x2
+#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_MODIFY       0x4
+#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_RENAME       0x8
+
+/* LDAP VLV *//* not implemented in slapd(8) */
+#define LDAP_CONTROL_VLVREQUEST        "2.16.840.1.113730.3.4.9"
+#define LDAP_CONTROL_VLVRESPONSE    "2.16.840.1.113730.3.4.10"
+
+
 /* LDAP Unsolicited Notifications */
 #define        LDAP_NOTICE_OF_DISCONNECTION    "1.3.6.1.4.1.1466.20036" /* RFC 2251 */
 #define LDAP_NOTICE_DISCONNECT LDAP_NOTICE_OF_DISCONNECTION
@@ -318,7 +323,6 @@ typedef struct ldapcontrol {
 #define LDAP_EXOP_X_CANCEL             LDAP_EXOP_CANCEL
 
 /* various works in progress */
-
 #define LDAP_EXOP_WHO_AM_I             "1.3.6.1.4.1.4203.1.11.3"
 #define LDAP_EXOP_X_WHO_AM_I   LDAP_EXOP_WHO_AM_I
 
@@ -470,7 +474,6 @@ typedef struct ldapcontrol {
 #define LDAP_SUBSTRING_FINAL   ((ber_tag_t) 0x82U)     /* context specific */
 
 /* search scopes */
-#define LDAP_SCOPE_DEFAULT             ((ber_int_t) -1)         /* OpenLDAP extension */
 #define LDAP_SCOPE_BASE                        ((ber_int_t) 0x0000)
 #define LDAP_SCOPE_BASEOBJECT  LDAP_SCOPE_BASE
 #define LDAP_SCOPE_ONELEVEL            ((ber_int_t) 0x0001)
@@ -479,6 +482,7 @@ typedef struct ldapcontrol {
 #define LDAP_SCOPE_SUB                 LDAP_SCOPE_SUBTREE
 #define LDAP_SCOPE_SUBORDINATE ((ber_int_t) 0x0003) /* OpenLDAP extension */
 #define LDAP_SCOPE_CHILDREN            LDAP_SCOPE_SUBORDINATE
+#define LDAP_SCOPE_DEFAULT             ((ber_int_t) -1)         /* OpenLDAP extension */
 
 /* substring filter component types */
 #define LDAP_SUBSTRING_INITIAL ((ber_tag_t) 0x80U)     /* context specific */
@@ -550,7 +554,7 @@ typedef struct ldapcontrol {
 #define LDAP_ALREADY_EXISTS                    0x44
 #define LDAP_NO_OBJECT_CLASS_MODS      0x45
 #define LDAP_RESULTS_TOO_LARGE         0x46 /* CLDAP */
-#define LDAP_AFFECTS_MULTIPLE_DSAS     0x47 /* LDAPv3 */
+#define LDAP_AFFECTS_MULTIPLE_DSAS     0x47
 
 #define LDAP_OTHER                                     0x50
 
@@ -567,27 +571,34 @@ typedef struct ldapcontrol {
 #define LDAP_TOO_LATE                          0x78
 #define LDAP_CANNOT_CANCEL                     0x79
 
+/* Assertion control (122) */ 
+#define LDAP_ASSERTION_FAILED          0x7A
+
 
 /* Experimental result codes */
-#define LDAP_E_ERROR(n)        LDAP_RANGE((n),0x1000,0x3FFF) /* experimental */
-#define LDAP_X_ERROR(n)        LDAP_RANGE((n),0x4000,0xFFFF) /* private use */
+#define LDAP_E_ERROR(n)        LDAP_RANGE((n),0x1000,0x3FFF)
 
-/* for the LDAP Sync operation */
-#define LDAP_SYNC_REFRESH_REQUIRED             0x4100
+/* LDAP Sync (4096) */
+#define LDAP_SYNC_REFRESH_REQUIRED             0x1000
 
-/* for the LDAP No-Op control */
-#define LDAP_NO_OPERATION                              0x410e
 
-/* for the Assertion control */
-#define LDAP_ASSERTION_FAILED                  0x410f
+/* Private Use result codes */
+#define LDAP_X_ERROR(n)        LDAP_RANGE((n),0x4000,0xFFFF)
+
+#define LDAP_X_SYNC_REFRESH_REQUIRED   0x4100 /* defunct */
+#define LDAP_X_ASSERTION_FAILED                        0x410f /* defunct */
+
+/* for the LDAP No-Op control */
+#define LDAP_X_NO_OPERATION                            0x410e
 
 /* for the Chaining Behavior control (consecutive result codes requested;
  * see <draft-sermersheim-ldap-chaining> ) */
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-#define        LDAP_NO_REFERRALS_FOUND                 0x4110
-#define LDAP_CANNOT_CHAIN                      0x4111
+#define        LDAP_X_NO_REFERRALS_FOUND               0x4110
+#define LDAP_X_CANNOT_CHAIN                            0x4111
 #endif
 
+
 /* API Error Codes
  *
  * Based on draft-ietf-ldap-c-api-xx
@@ -1664,6 +1675,11 @@ ldap_msgdelete LDAP_P((
  * in search.c:
  */
 LDAP_F( int )
+ldap_bv2escaped_filter_value LDAP_P(( 
+       struct berval *in, 
+       struct berval *out ));
+
+LDAP_F( int )
 ldap_search_ext LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *base,
index e339b15d12a4b1390375ba60f6cbd1140d23028e..10425199a36fc30ca0570c2ec7da7395a6c85030 100644 (file)
 /* define if Berkeley DB has DB_THREAD support */
 #undef HAVE_BERKELEY_DB_THREAD
 
-/* define if you have SSLeay or OpenSSL's BIGNUM */
+/* define if you have OpenSSL's BIGNUM */
 #undef HAVE_BIGNUM
 
 /* Define to 1 if you have the <bits/types.h> header file. */
 /* define to you inet_aton(3) is available */
 #undef HAVE_INET_ATON
 
+/* Define to 1 if you have the `inet_ntoa_b' function. */
+#undef HAVE_INET_NTOA_B
+
 /* Define to 1 if you have the `inet_ntop' function. */
 #undef HAVE_INET_NTOP
 
 /* if you have NT Threads */
 #undef HAVE_NT_THREADS
 
+/* define if you have OpenSSL */
+#undef HAVE_OPENSSL
+
 /* Define to 1 if you have the <openssl/bn.h> header file. */
 #undef HAVE_OPENSSL_BN_H
 
 /* define if you have res_query() */
 #undef HAVE_RES_QUERY
 
-/* define if you have RSAref */
+/* define if OpenSSL needs RSAref */
 #undef HAVE_RSAREF
 
 /* Define to 1 if you have the <sasl.h> header file. */
 /* Define to 1 if you have the <sql.h> header file. */
 #undef HAVE_SQL_H
 
-/* define if you have SSLeay or OpenSSL */
-#undef HAVE_SSLEAY
-
-/* Define to 1 if you have the <ssl.h> header file. */
-#undef HAVE_SSL_H
-
 /* Define to 1 if you have the <stddef.h> header file. */
 #undef HAVE_STDDEF_H
 
index 99893b285d87ccbd01bcae215868ffc8b23d57ce..ebaa7a3391c6f31758160c80a58815dccf4397fc 100644 (file)
@@ -594,7 +594,8 @@ ldap_int_sasl_bind(
                rc = ldap_open_defconn( ld );
                if( rc < 0 ) return ld->ld_errno;
 
-               ber_sockbuf_ctrl( ld->ld_defconn->lconn_sb, LBER_SB_OPT_GET_FD, &sd );
+               ber_sockbuf_ctrl( ld->ld_defconn->lconn_sb,
+                       LBER_SB_OPT_GET_FD, &sd );
 
                if( sd == AC_SOCKET_INVALID ) {
                        ld->ld_errno = LDAP_LOCAL_ERROR;
@@ -612,9 +613,11 @@ ldap_int_sasl_bind(
                ld->ld_defconn->lconn_sasl_authctx = NULL;
        }
 
-       { char *saslhost = ldap_host_connected_to( ld->ld_defconn->lconn_sb, "localhost" );
-       rc = ldap_int_sasl_open( ld, ld->ld_defconn, saslhost );
-       LDAP_FREE( saslhost );
+       {
+               char *saslhost = ldap_host_connected_to( ld->ld_defconn->lconn_sb,
+                       "localhost" );
+               rc = ldap_int_sasl_open( ld, ld->ld_defconn, saslhost );
+               LDAP_FREE( saslhost );
        }
 
        if ( rc != LDAP_SUCCESS ) return rc;
@@ -637,13 +640,16 @@ ldap_int_sasl_bind(
 
 #if !defined(_WIN32)
        /* Check for local */
-       if ( ldap_pvt_url_scheme2proto( ld->ld_defconn->lconn_server->lud_scheme ) == LDAP_PROTO_IPC ) {
-               char authid[sizeof("uidNumber=4294967295+gidNumber=4294967295,"
+       if ( ldap_pvt_url_scheme2proto(
+               ld->ld_defconn->lconn_server->lud_scheme ) == LDAP_PROTO_IPC )
+       {
+               char authid[sizeof("gidNumber=4294967295+uidNumber=4294967295,"
                        "cn=peercred,cn=external,cn=auth")];
-               sprintf( authid, "uidNumber=%d+gidNumber=%d,"
+               sprintf( authid, "gidNumber=%d+uidNumber=%d,"
                        "cn=peercred,cn=external,cn=auth",
-                       (int) geteuid(), (int) getegid() );
-               (void) ldap_int_sasl_external( ld, ld->ld_defconn, authid, LDAP_PVT_SASL_LOCAL_SSF );
+                       (int) getegid(), (int) geteuid() );
+               (void) ldap_int_sasl_external( ld, ld->ld_defconn, authid,
+                       LDAP_PVT_SASL_LOCAL_SSF );
        }
 #endif
 
@@ -703,7 +709,8 @@ ldap_int_sasl_bind(
 
                scred = NULL;
 
-               rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls, &scred );
+               rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls,
+                       &scred );
 
                if ( ccred.bv_val != NULL ) {
 #if SASL_VERSION_MAJOR < 2
@@ -714,13 +721,12 @@ ldap_int_sasl_bind(
 
                if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
                        if( scred ) {
-                               if ( scred->bv_len ) {
-                                       /* and server provided us with data? */
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
-                                               rc, saslrc, scred->bv_len );
-                               }
+                               /* and server provided us with data? */
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
+                                       rc, saslrc, scred ? scred->bv_len : -1 );
                                ber_bvfree( scred );
+                               scred = NULL;
                        }
                        rc = ld->ld_errno;
                        goto done;
@@ -729,12 +735,11 @@ ldap_int_sasl_bind(
                if( rc == LDAP_SUCCESS && saslrc == SASL_OK ) {
                        /* we're done, no need to step */
                        if( scred ) {
-                               if ( scred->bv_len ) {
-                                       /* but server provided us with data! */
-                                       Debug( LDAP_DEBUG_TRACE,
-                                               "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
-                                               rc, saslrc, scred->bv_len );
-                               }
+                               /* but we got additional data? */
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
+                                       rc, saslrc, scred ? scred->bv_len : -1 );
+
                                ber_bvfree( scred );
                                rc = ld->ld_errno = LDAP_LOCAL_ERROR;
                                goto done;
@@ -743,6 +748,13 @@ ldap_int_sasl_bind(
                }
 
                do {
+                       if( ! scred ) {
+                               /* no data! */
+                               Debug( LDAP_DEBUG_TRACE,
+                                       "ldap_int_sasl_bind: no data in step!\n",
+                                       0, 0, 0 );
+                       }
+
                        saslrc = sasl_client_step( ctx,
                                (scred == NULL) ? NULL : scred->bv_val,
                                (scred == NULL) ? 0 : scred->bv_len,
@@ -791,13 +803,15 @@ ldap_int_sasl_bind(
        }
 
        if( flags != LDAP_SASL_QUIET ) {
-               saslrc = sasl_getprop( ctx, SASL_USERNAME, (SASL_CONST void **) &data );
+               saslrc = sasl_getprop( ctx, SASL_USERNAME,
+                       (SASL_CONST void **) &data );
                if( saslrc == SASL_OK && data && *data ) {
                        fprintf( stderr, "SASL username: %s\n", data );
                }
 
 #if SASL_VERSION_MAJOR < 2
-               saslrc = sasl_getprop( ctx, SASL_REALM, (SASL_CONST void **) &data );
+               saslrc = sasl_getprop( ctx, SASL_REALM,
+                       (SASL_CONST void **) &data );
                if( saslrc == SASL_OK && data && *data ) {
                        fprintf( stderr, "SASL realm: %s\n", data );
                }
index db26ae97ce7d0f0c8e7b4ba6f4d7c9552d5994e8..529a3e2eeabd23a75ee02ec9f4fa241471678af8 100644 (file)
@@ -85,6 +85,19 @@ static struct ldaperror ldap_builtin_errlist[] = {
 
        {LDAP_OTHER,                                    N_("Internal (implementation specific) error")},
 
+       {LDAP_CANCELLED,                                N_("Cancelled")},
+       {LDAP_NO_SUCH_OPERATION,                N_("No Operation to Cancel")},
+       {LDAP_TOO_LATE,                                 N_("Too Late to Cancel")},
+       {LDAP_CANNOT_CANCEL,                    N_("Cannot Cancel")},
+
+       {LDAP_ASSERTION_FAILED,                 N_("Assertion Failed")},
+       {LDAP_X_ASSERTION_FAILED,               N_("Assertion Failed (X)")},
+
+       {LDAP_SYNC_REFRESH_REQUIRED,    N_("Content Sync Refresh Required")},
+       {LDAP_X_SYNC_REFRESH_REQUIRED,  N_("Content Sync Refresh Required (X)")},
+
+       {LDAP_X_NO_OPERATION,                   N_("No Operation (X)")},
+
        /* API ResultCodes */
        {LDAP_SERVER_DOWN,                              N_("Can't contact LDAP server")},
        {LDAP_LOCAL_ERROR,                              N_("Local error")},
@@ -105,22 +118,12 @@ static struct ldaperror ldap_builtin_errlist[] = {
        {LDAP_CLIENT_LOOP,                              N_("Client Loop")},
        {LDAP_REFERRAL_LIMIT_EXCEEDED,  N_("Referral Limit Exceeded")},
 
-       {LDAP_SYNC_REFRESH_REQUIRED,    N_("Content Sync Refresh Required")},
-
-       {LDAP_NO_OPERATION,                             N_("No Operation")},
-       {LDAP_ASSERTION_FAILED,                 N_("Assertion Failed")},
-
        {LDAP_CUP_RESOURCES_EXHAUSTED,  N_("LCUP Resources Exhausted")},
        {LDAP_CUP_SECURITY_VIOLATION,   N_("LCUP Security Violation")},
        {LDAP_CUP_INVALID_DATA,                 N_("LCUP Invalid Data")},
        {LDAP_CUP_UNSUPPORTED_SCHEME,   N_("LCUP Unsupported Scheme")},
        {LDAP_CUP_RELOAD_REQUIRED,              N_("LCUP Reload Required")},
 
-       {LDAP_CANCELLED,                                N_("Cancelled")},
-       {LDAP_NO_SUCH_OPERATION,                N_("No Operation to Cancel")},
-       {LDAP_TOO_LATE,                                 N_("Too Late to Cancel")},
-       {LDAP_CANNOT_CANCEL,                    N_("Cannot Cancel")},
-
        {0, NULL}
 };
 
index fe47f8dc392c23755443e68e63a06f9b8033207d..cb0fc14e9a0db0a433282efd3deb62a3b33ad363 100644 (file)
@@ -110,7 +110,7 @@ static const struct ol_attribute {
        {0, ATTR_NONE,          NULL,           NULL,   0}
 };
 
-#define MAX_LDAP_ATTR_LEN  sizeof("TLS_CACERTDIR")
+#define MAX_LDAP_ATTR_LEN  sizeof("TLS_CIPHER_SUITE")
 #define MAX_LDAP_ENV_PREFIX_LEN 8
 
 static void openldap_ldap_init_w_conf(
@@ -409,6 +409,11 @@ ldap_int_destroy_global_options(void)
 #if defined(HAVE_WINSOCK) || defined(HAVE_WINSOCK2)
        WSACleanup( );
 #endif
+
+       if ( ldap_int_hostname ) {
+               LDAP_FREE( ldap_int_hostname );
+               ldap_int_hostname = NULL;
+       }
 }
 
 /* 
@@ -529,7 +534,15 @@ void ldap_int_initialize( struct ldapoptions *gopts, int *dbglvl )
 
 #if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) \
        || defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
-       ldap_int_hostname = ldap_pvt_get_fqdn( ldap_int_hostname );
+       {
+               char    *name = ldap_int_hostname;
+
+               ldap_int_hostname = ldap_pvt_get_fqdn( name );
+
+               if ( name != NULL && name != ldap_int_hostname ) {
+                       LDAP_FREE( name );
+               }
+       }
 #endif
 
 #ifndef HAVE_POLL
index 65341b5e846d3f82d0c943bc94dbfb33b14be771..0c5fb36b8bfbcf548f590dfa940a2cb2ccf3f969 100644 (file)
@@ -529,8 +529,18 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
                                sizeof(sin.sin_addr) );
                }
 
+#ifdef HAVE_INET_NTOA_B
+               {
+                       /* for VxWorks */
+                       char address[INET_ADDR_LEN];
+                       inet_ntoa_b(sin.sin_address, address);
+                       osip_debug(ld, "ldap_connect_to_host: Trying %s:%d\n", 
+                               address, port, 0);
+               }
+#else
                osip_debug(ld, "ldap_connect_to_host: Trying %s:%d\n", 
                        inet_ntoa(sin.sin_addr), port, 0);
+#endif
 
                rc = ldap_pvt_connect(ld, s,
                        (struct sockaddr *)&sin, sizeof(sin),
index a2d97a3e01755b8ee780b5929c7ad56de38a15a9..d78eeb84ad712f2cacbd234189f64fdffb1cb56f 100644 (file)
@@ -365,3 +365,53 @@ ldap_search_s(
        return( ldap_result2error( ld, *res, 0 ) );
 }
 
+int
+ldap_bv2escaped_filter_value( struct berval *in, struct berval *out )
+{
+       char c;
+       ber_len_t i;
+       static char escape[128] = {
+               1, 1, 1, 1, 1, 1, 1, 1,
+               1, 1, 1, 1, 1, 1, 1, 1,
+               1, 1, 1, 1, 1, 1, 1, 1,
+               1, 1, 1, 1, 1, 1, 1, 1,
+
+               1, 1, 1, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 1, 0, 0, 0,
+
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 0,
+               0, 0, 0, 0, 0, 0, 0, 1
+       };
+
+       out->bv_len = 0;
+       out->bv_val = NULL;
+
+       if( in->bv_len == 0 ) return 0;
+
+       /* assume we'll escape everything */
+       out->bv_val = LDAP_MALLOC( 3 * in->bv_len + 1 );
+       if( out->bv_val == NULL ) return -1;
+
+       for( i=0; i<in->bv_len; i++ ) {
+               if (c & 0x80 || escape[in->bv_val[i]]) {
+                       out->bv_val[out->bv_len++] = '\\';
+                       out->bv_val[out->bv_len++] = "0123456789ABCDEF"[0x0f & (c>>4)];
+                       out->bv_val[out->bv_len++] = "0123456789ABCDEF"[0x0f & c];
+               } else {
+                       out->bv_val[out->bv_len++] = c;
+               }
+       }
+
+       out->bv_val[out->bv_len] = '\0';
+       return 0;
+}
+
index 2b8cafb52a045209ff38d2fbc31bb16d6ba7a251..c03c8446a8d69be9c5e502030a177847a885f27d 100644 (file)
@@ -50,6 +50,7 @@
 static int  tls_opt_trace = 1;
 static char *tls_opt_certfile = NULL;
 static char *tls_opt_keyfile = NULL;
+static char *tls_opt_dhfile = NULL;
 static char *tls_opt_cacertfile = NULL;
 static char *tls_opt_cacertdir = NULL;
 static int  tls_opt_require_cert = LDAP_OPT_X_TLS_DEMAND;
@@ -70,12 +71,18 @@ static int tls_verify_ok( int ok, X509_STORE_CTX *ctx );
 static RSA * tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length );
 static STACK_OF(X509_NAME) * get_ca_list( char * bundle, char * dir );
 
-#if 0  /* Currently this is not used by anyone */
 static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length );
-#endif
 
 static SSL_CTX *tls_def_ctx = NULL;
 
+typedef struct dhplist {
+       struct dhplist *next;
+       int keylength;
+       DH *param;
+} dhplist;
+
+static dhplist *dhparams;
+
 static int tls_seed_PRNG( const char *randfile );
 
 #ifdef LDAP_R_COMPILE
@@ -134,6 +141,10 @@ ldap_pvt_tls_destroy( void )
                LDAP_FREE( tls_opt_keyfile );
                tls_opt_keyfile = NULL;
        }
+       if ( tls_opt_dhfile ) {
+               LDAP_FREE( tls_opt_dhfile );
+               tls_opt_dhfile = NULL;
+       }
        if ( tls_opt_cacertfile ) {
                LDAP_FREE( tls_opt_cacertfile );
                tls_opt_cacertfile = NULL;
@@ -198,6 +209,7 @@ ldap_pvt_tls_init_def_ctx( void )
        char *cacertdir = tls_opt_cacertdir;
        char *certfile = tls_opt_certfile;
        char *keyfile = tls_opt_keyfile;
+       char *dhfile = tls_opt_dhfile;
 
 #ifdef LDAP_R_COMPILE
        ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
@@ -205,6 +217,9 @@ ldap_pvt_tls_init_def_ctx( void )
 
        if ( !certfile && !keyfile && !cacertfile && !cacertdir ) {
                /* minimum configuration not provided */
+#ifdef LDAP_R_COMPILE
+               ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
+#endif
                return LDAP_NOT_SUPPORTED;
        }
 
@@ -230,6 +245,10 @@ ldap_pvt_tls_init_def_ctx( void )
                keyfile = LDAP_STRDUP( keyfile );
                __atoe( keyfile );
        }
+       if ( dhfile ) {
+               dhfile = LDAP_STRDUP( dhfile );
+               __atoe( dhfile );
+       }
 #endif
        if ( tls_def_ctx == NULL ) {
                int i;
@@ -321,6 +340,31 @@ ldap_pvt_tls_init_def_ctx( void )
                        goto error_exit;
                }
 
+               if ( tls_opt_dhfile ) {
+                       DH *dh = NULL;
+                       BIO *bio;
+                       dhplist *p;
+
+                       if (( bio=BIO_new_file( dhfile,"r" )) == NULL ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "TLS: could not use DH parameters file `%s'.\n",
+                                       tls_opt_dhfile,0,0);
+                               tls_report_error();
+                               rc = -1;
+                               goto error_exit;
+                       }
+                       while (( dh=PEM_read_bio_DHparams( bio, NULL, NULL, NULL ))) {
+                               p = LDAP_MALLOC( sizeof(dhplist) );
+                               if ( p != NULL ) {
+                                       p->keylength = DH_size( dh ) * 8;
+                                       p->param = dh;
+                                       p->next = dhparams;
+                                       dhparams = p;
+                               }
+                       }
+                       BIO_free( bio );
+               }
+
                if ( tls_opt_trace ) {
                        SSL_CTX_set_info_callback( tls_def_ctx, tls_info_cb );
                }
@@ -338,7 +382,7 @@ ldap_pvt_tls_init_def_ctx( void )
                        tls_opt_require_cert == LDAP_OPT_X_TLS_ALLOW ?
                        tls_verify_ok : tls_verify_cb );
                SSL_CTX_set_tmp_rsa_callback( tls_def_ctx, tls_tmp_rsa_cb );
-               /* SSL_CTX_set_tmp_dh_callback( tls_def_ctx, tls_tmp_dh_cb ); */
+               SSL_CTX_set_tmp_dh_callback( tls_def_ctx, tls_tmp_dh_cb );
 #ifdef HAVE_OPENSSL_CRL
                if ( tls_opt_crlcheck ) {
                        X509_STORE *x509_s = SSL_CTX_get_cert_store( tls_def_ctx );
@@ -362,6 +406,7 @@ error_exit:
        LDAP_FREE( cacertdir );
        LDAP_FREE( certfile );
        LDAP_FREE( keyfile );
+       LDAP_FREE( dhfile );
 #endif
 #ifdef LDAP_R_COMPILE
        ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
@@ -1121,6 +1166,7 @@ ldap_int_tls_config( LDAP *ld, int option, const char *arg )
        case LDAP_OPT_X_TLS_KEYFILE:
        case LDAP_OPT_X_TLS_RANDOM_FILE:
        case LDAP_OPT_X_TLS_CIPHER_SUITE:
+       case LDAP_OPT_X_TLS_DHFILE:
                return ldap_pvt_tls_set_option( ld, option, (void *) arg );
 
        case LDAP_OPT_X_TLS_REQUIRE_CERT:
@@ -1218,6 +1264,10 @@ ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
                *(char **)arg = tls_opt_keyfile ?
                        LDAP_STRDUP( tls_opt_keyfile ) : NULL;
                break;
+       case LDAP_OPT_X_TLS_DHFILE:
+               *(char **)arg = tls_opt_dhfile ?
+                       LDAP_STRDUP( tls_opt_dhfile ) : NULL;
+               break;
        case LDAP_OPT_X_TLS_REQUIRE_CERT:
                *(int *)arg = tls_opt_require_cert;
                break;
@@ -1329,6 +1379,10 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
                if ( tls_opt_keyfile ) LDAP_FREE( tls_opt_keyfile );
                tls_opt_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
                break;
+       case LDAP_OPT_X_TLS_DHFILE:
+               if ( tls_opt_dhfile ) LDAP_FREE( tls_opt_dhfile );
+               tls_opt_dhfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+               break;
        case LDAP_OPT_X_TLS_REQUIRE_CERT:
                switch( *(int *) arg ) {
                case LDAP_OPT_X_TLS_NEVER:
@@ -1626,13 +1680,114 @@ tls_seed_PRNG( const char *randfile )
        return 0;
 }
 
-#if 0
+struct dhinfo {
+       int keylength;
+       const char *pem;
+       size_t size;
+};
+
+
+/* From the OpenSSL 0.9.7 distro */
+static const char dhpem512[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn\n\
+a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC\n\
+-----END DH PARAMETERS-----\n";
+
+static const char dhpem1024[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq\n\
+/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx\n\
+/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC\n\
+-----END DH PARAMETERS-----\n";
+
+static const char dhpem2048[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o\n\
+AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh\n\
+z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo\n\
+pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW\n\
+aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA\n\
+Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg==\n\
+-----END DH PARAMETERS-----\n";
+
+static const char dhpem4096[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7\n\
+vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H\n\
+TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF\n\
+bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1\n\
+rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE\n\
+EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9\n\
+bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3\n\
+W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH\n\
+ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb\n\
+NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR\n\
+jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI=\n\
+-----END DH PARAMETERS-----\n";
+
+static const struct dhinfo dhpem[] = {
+       { 512, dhpem512, sizeof(dhpem512) },
+       { 1024, dhpem1024, sizeof(dhpem1024) },
+       { 2048, dhpem2048, sizeof(dhpem2048) },
+       { 4096, dhpem4096, sizeof(dhpem4096) },
+       { 0, NULL, 0 }
+};
+
 static DH *
 tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
 {
-       return NULL;
-}
+       struct dhplist *p = NULL;
+       BIO *b = NULL;
+       DH *dh = NULL;
+       int i;
+
+       /* Do we have params of this length already? */
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
+#endif
+       for ( p = dhparams; p; p=p->next ) {
+               if ( p->keylength == key_length ) {
+#ifdef LDAP_R_COMPILE
+                       ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
 #endif
+                       return p->param;
+               }
+       }
+
+       /* No - check for hardcoded params */
+
+       for (i=0; dhpem[i].keylength; i++) {
+               if ( dhpem[i].keylength == key_length ) {
+                       b = BIO_new_mem_buf( (char *)dhpem[i].pem, dhpem[i].size );
+                       break;
+               }
+       }
+
+       if ( b ) {
+               dh = PEM_read_bio_DHparams( b, NULL, NULL, NULL );
+               BIO_free( b );
+       }
+
+       /* Generating on the fly is expensive/slow... */
+       if ( !dh ) {
+               dh = DH_generate_parameters( key_length, DH_GENERATOR_2, NULL, NULL );
+       }
+       if ( dh ) {
+               p = LDAP_MALLOC( sizeof(struct dhplist) );
+               if ( p != NULL ) {
+                       p->keylength = key_length;
+                       p->param = dh;
+                       p->next = dhparams;
+                       dhparams = p;
+               }
+       }
+done:
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
+#endif
+       return dh;
+}
 #endif
 
 void *
index df477822f7f3dc1a361f3cb4fa17b6a8e933c48e..b35941db3ae8e9d330a72ba2eb3ca741ed8650b7 100644 (file)
@@ -79,8 +79,8 @@ ASCII chars                                           7 bits
 Unicode address space   (0 - 0x10FFFF)    21 bits
 ISO-10646 address space (0 - 0x7FFFFFFF)  31 bits
 
-Note:  This code does not prevent UTF-8 sequences which are longer than
-          necessary from being decoded.
+Note: This code does not prevent UTF-8 sequences which are longer than
+      necessary from being decoded.
 */
 
 /*----------------------------------------------------------------------------- 
@@ -93,31 +93,25 @@ ldap_x_utf8_to_wc ( wchar_t *wchar, const char *utf8char )
        int utflen, i;
        wchar_t ch;
 
-       /* If input ptr is NULL, treat it as empty string. */
-       if (utf8char == NULL)
-               utf8char = "";
+       if (utf8char == NULL) return -1;
 
        /* Get UTF-8 sequence length from 1st byte */
        utflen = LDAP_UTF8_CHARLEN2(utf8char, utflen);
        
-       if( utflen==0 || utflen > (int)LDAP_MAX_UTF8_LEN )
-               return -1;                                                                      /* Invalid input */
+       if( utflen==0 || utflen > (int)LDAP_MAX_UTF8_LEN ) return -1;
 
        /* First byte minus length tag */
        ch = (wchar_t)(utf8char[0] & mask[utflen]);
        
-       for(i=1; i < utflen; i++)
-       {
+       for(i=1; i < utflen; i++) {
                /* Subsequent bytes must start with 10 */
-               if ((utf8char[i] & 0xc0) != 0x80)
-                       return -1;
+               if ((utf8char[i] & 0xc0) != 0x80) return -1;
        
                ch <<= 6;                       /* 6 bits of data in each subsequent byte */
                ch |= (wchar_t)(utf8char[i] & 0x3f);
        }
        
-       if (wchar)
-               *wchar = ch;
+       if (wchar) *wchar = ch;
 
        return utflen;
 }
@@ -136,41 +130,34 @@ ldap_x_utf8s_to_wcs ( wchar_t *wcstr, const char *utf8str, size_t count )
 
 
        /* If input ptr is NULL, treat it as empty string. */
-       if (utf8str == NULL)
-               utf8str = "";
+       if (utf8str == NULL) utf8str = "";
 
        /* Examine next UTF-8 character.  If output buffer is NULL, ignore count */
-       while ( *utf8str && (wcstr==NULL || wclen<count) )
-       {
+       while ( *utf8str && (wcstr==NULL || wclen<count) ) {
                /* Get UTF-8 sequence length from 1st byte */
                utflen = LDAP_UTF8_CHARLEN2(utf8str, utflen);
                
-               if( utflen==0 || utflen > (int)LDAP_MAX_UTF8_LEN )
-                       return -1;                                                                      /* Invalid input */
+               if( utflen==0 || utflen > (int)LDAP_MAX_UTF8_LEN ) return -1;
 
                /* First byte minus length tag */
                ch = (wchar_t)(utf8str[0] & mask[utflen]);
                
-               for(i=1; i < utflen; i++)
-               {
+               for(i=1; i < utflen; i++) {
                        /* Subsequent bytes must start with 10 */
-                       if ((utf8str[i] & 0xc0) != 0x80)
-                               return -1;
+                       if ((utf8str[i] & 0xc0) != 0x80) return -1;
                
                        ch <<= 6;                       /* 6 bits of data in each subsequent byte */
                        ch |= (wchar_t)(utf8str[i] & 0x3f);
                }
                
-               if (wcstr)
-                       wcstr[wclen] = ch;
+               if (wcstr) wcstr[wclen] = ch;
                
-               utf8str += utflen;              /* Move to next UTF-8 character */
-               wclen++;                                /* Count number of wide chars stored/required */
+               utf8str += utflen;      /* Move to next UTF-8 character */
+               wclen++;                        /* Count number of wide chars stored/required */
        }
 
        /* Add null terminator if there's room in the buffer. */
-       if (wcstr && wclen < count)
-               wcstr[wclen] = 0;
+       if (wcstr && wclen < count) wcstr[wclen] = 0;
 
        return wclen;
 }
index 089a17cafd1ffd23c243d64041bdc66cfa3fcd6f..c913b1833c0da996f987dd0551a685af4da7b7aa 100644 (file)
@@ -303,7 +303,7 @@ int ldap_pvt_get_hname(
                rc = 0;
        } else {
                rc = h_errno;
-               *err = (char *)hp_strerror( h_errno );
+               *err = (char *)HSTRERROR( h_errno );
        }
 #if defined( LDAP_R_COMPILE )
        ldap_pvt_thread_mutex_unlock( &ldap_int_resolv_mutex );
index ba87eaa989175049c9d5c7e465577e32085e20e1..41a3fc556dff2b251aade0adfd9479de229c0bee 100644 (file)
@@ -243,13 +243,9 @@ ldap_pvt_thread_pool_submit (
                return(0);
        }
        ldap_pvt_thread_cond_signal(&pool->ltp_cond);
-       if ((pool->ltp_open_count <= 0
-#if 0
-                       || pool->ltp_pending_count > 1
-#endif
-                       || pool->ltp_open_count == pool->ltp_active_count)
-               && (pool->ltp_max_count <= 0
-                       || pool->ltp_open_count < pool->ltp_max_count))
+       if (pool->ltp_open_count < pool->ltp_active_count + pool->ltp_pending_count
+               && (pool->ltp_open_count < pool->ltp_max_count ||
+                       pool->ltp_max_count <= 0 ))
        {
                pool->ltp_open_count++;
                pool->ltp_starting++;
index 53f759975dfa4bb51d1f5261f24047f4027f4dc7..32b5544ebf08dbc21068374863126f4702e5acc0 100644 (file)
@@ -81,10 +81,13 @@ rewrite_info_init(
 
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
        if ( ldap_pvt_thread_rdwr_init( &info->li_cookies_mutex ) ) {
+               avl_free( info->li_context, rewrite_context_free );
                free( info );
                return NULL;
        }
        if ( ldap_pvt_thread_rdwr_init( &info->li_params_mutex ) ) {
+               ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex );
+               avl_free( info->li_context, rewrite_context_free );
                free( info );
                return NULL;
        }
@@ -116,7 +119,7 @@ rewrite_info_delete(
        if ( info->li_maps ) {
                avl_free( info->li_maps, rewrite_builtin_map_free );
        }
-       info->li_context = NULL;
+       info->li_maps = NULL;
 
        rewrite_session_destroy( info );
 
index bd0685167c926dab95868cd30e893df163a7e7d3..4fa58f876c5664e0f04af10563b938e7d30f8963 100644 (file)
@@ -302,6 +302,32 @@ rewrite_session_var_get(
        return REWRITE_SUCCESS;
 }
 
+static void
+rewrite_session_clean( void *v_session )
+{
+       struct rewrite_session  *session = (struct rewrite_session *)v_session;
+
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+       ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex );
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+
+       rewrite_var_delete( session->ls_vars );
+
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+       ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
+       ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex );
+       ldap_pvt_thread_mutex_unlock( &session->ls_mutex );
+       ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+}
+
+static void
+rewrite_session_free( void *v_session )
+{
+       rewrite_session_clean( v_session );
+       free( v_session );
+}
+
 /*
  * Deletes a session
  */
@@ -311,13 +337,11 @@ rewrite_session_delete(
                const void *cookie
 )
 {
-       struct rewrite_session *session, tmp;
+       struct rewrite_session *session, tmp = { 0 };
 
        assert( info != NULL );
        assert( cookie != NULL );
 
-       tmp.ls_cookie = ( void * )cookie;
-       
        session = rewrite_session_find( info, cookie );
 
        if ( session == NULL ) {
@@ -329,18 +353,7 @@ rewrite_session_delete(
                return REWRITE_SUCCESS;
        }
 
-#ifdef USE_REWRITE_LDAP_PVT_THREADS
-       ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex );
-#endif /* USE_REWRITE_LDAP_PVT_THREADS */
-
-       rewrite_var_delete( session->ls_vars );
-
-#ifdef USE_REWRITE_LDAP_PVT_THREADS
-       ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
-       ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex );
-       ldap_pvt_thread_mutex_unlock( &session->ls_mutex );
-       ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
-#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+       rewrite_session_clean( session );
 
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
        ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
@@ -352,7 +365,9 @@ rewrite_session_delete(
        /*
         * There is nothing to delete in the return value
         */
+       tmp.ls_cookie = ( void * )cookie;
        avl_delete( &info->li_cookies, ( caddr_t )&tmp, rewrite_cookie_cmp );
+
        free( session );
 
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
@@ -382,7 +397,7 @@ rewrite_session_destroy(
         * Should call per-session destruction routine ...
         */
        
-       count = avl_free( info->li_cookies, NULL );
+       count = avl_free( info->li_cookies, rewrite_session_free );
        info->li_cookies = NULL;
 
 #if 0
index 6b44e802446eacd9a5e52bc8efa765c00a4dee21..a77a9fb3ceefedb1667701975ef8556f5f6ac143 100644 (file)
@@ -1320,11 +1320,15 @@ OpenLDAPaciValidate(
                                atbv = BER_BVNULL;
 
                ocbv.bv_val = strchr( type.bv_val, '/' );
-               if ( ocbv.bv_val != NULL ) {
+               if ( ocbv.bv_val != NULL
+                       && ( ocbv.bv_val - type.bv_val ) < type.bv_len )
+               {
                        ocbv.bv_val++;
 
                        atbv.bv_val = strchr( ocbv.bv_val, '/' );
-                       if ( atbv.bv_val != NULL ) {
+                       if ( atbv.bv_val != NULL
+                               && ( atbv.bv_val - ocbv.bv_val ) < ocbv.bv_len )
+                       {
                                AttributeDescription    *ad = NULL;
                                const char              *text = NULL;
                                int                     rc;
@@ -1471,7 +1475,9 @@ OpenLDAPaciPrettyNormal(
                                        atbv = BER_BVNULL;
 
                        ocbv.bv_val = strchr( type.bv_val, '/' );
-                       if ( ocbv.bv_val != NULL ) {
+                       if ( ocbv.bv_val != NULL
+                               && ( ocbv.bv_val - type.bv_val ) < type.bv_len )
+                       {
                                ObjectClass             *oc = NULL;
                                AttributeDescription    *ad = NULL;
                                const char              *text = NULL;
@@ -1483,7 +1489,9 @@ OpenLDAPaciPrettyNormal(
                                ocbv.bv_val++;
 
                                atbv.bv_val = strchr( ocbv.bv_val, '/' );
-                               if ( atbv.bv_val != NULL ) {
+                               if ( atbv.bv_val != NULL
+                                       && ( atbv.bv_val - ocbv.bv_val ) < ocbv.bv_len )
+                               {
                                        atbv.bv_val++;
                                        atbv.bv_len = type.bv_len
                                                - ( atbv.bv_val - type.bv_val );
@@ -1616,5 +1624,17 @@ OpenLDAPaciNormalize(
        return OpenLDAPaciPrettyNormal( val, out, ctx, 1 );
 }
 
+#if SLAPD_ACI_ENABLED == SLAPD_MOD_DYNAMIC
+/*
+ * FIXME: need config and Makefile.am code to ease building
+ * as dynamic module
+ */
+int
+init_module( int argc, char *argv[] )
+{
+       return slap_dynacl_register();
+}
+#endif /* SLAPD_ACI_ENABLED == SLAPD_MOD_DYNAMIC */
+
 #endif /* SLAPD_ACI_ENABLED */
 
index f224e68e8a1b823178c7284c00ba9432fa80c11a..8bff33752d108dea7ca3b293c0c40c5034bb33e9 100644 (file)
@@ -2603,7 +2603,7 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de
        op2.o_tag = LDAP_REQ_SEARCH;
        op2.o_ndn = op2.o_bd->be_rootndn;
        op2.o_callback = &cb;
-       op2.o_time = slap_get_time();
+       slap_op_time( &op2.o_time, &op2.o_tincr );
        op2.o_do_not_cache = 1;
        op2.o_is_auth_check = 0;
        ber_dupbv_x( &op2.o_req_dn, &op2.o_req_ndn, cp->asc_op->o_tmpmemctx );
index 9b0e8e7acb507e733e7b45a378e3745fe82fd3b9..3c52759f7033aa55afc9b13438d3c3ac99913ec7 100644 (file)
@@ -58,7 +58,7 @@ char *style_strings[] = {
 
 static void            split(char *line, int splitchar, char **left, char **right);
 static void            access_append(Access **l, Access *a);
-static void            acl_usage(void) LDAP_GCCATTR((noreturn));
+static int             acl_usage(void);
 
 static void            acl_regex_normalized_dn(const char *src, struct berval *pat);
 
@@ -87,7 +87,7 @@ slap_dynacl_config(
                        Debug( LDAP_DEBUG_ANY,
                                "%s: line %d: dynacl \"%s\" already specified.\n",
                                fname, lineno, name );
-                       acl_usage();
+                       return acl_usage();
                }
        }
 
@@ -154,7 +154,8 @@ regtest(const char *fname, int lineno, char *pat) {
                Debug( LDAP_DEBUG_ANY,
                        "%s: line %d: regular expression \"%s\" too large\n",
                        fname, lineno, pat );
-               acl_usage();
+               (void)acl_usage();
+               exit( EXIT_FAILURE );
        }
 
        if ((e = regcomp(&re, buf, REG_EXTENDED|REG_ICASE))) {
@@ -169,6 +170,7 @@ regtest(const char *fname, int lineno, char *pat) {
                        "%s: line %d: %s\n",
                        fname, lineno, buf );
                acl_usage();
+               exit( EXIT_FAILURE );
        }
        regfree(&re);
 }
@@ -313,13 +315,13 @@ regex_done:;
        return ACL_SCOPE_UNKNOWN;
 }
 
-void
+int
 parse_acl(
-    Backend    *be,
-    const char *fname,
-    int                lineno,
-    int                argc,
-    char       **argv,
+       Backend *be,
+       const char      *fname,
+       int             lineno,
+       int             argc,
+       char            **argv,
        int             pos )
 {
        int             i;
@@ -338,7 +340,7 @@ parse_acl(
                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                        "only one to clause allowed in access line\n",
                                    fname, lineno, 0 );
-                               acl_usage();
+                               return acl_usage();
                        }
                        a = (AccessControl *) ch_calloc( 1, sizeof(AccessControl) );
                        for ( ++i; i < argc; i++ ) {
@@ -355,7 +357,7 @@ parse_acl(
                                                        "%s: line %d: dn pattern"
                                                        " already specified in to clause.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        ber_str2bv( "*", STRLENOF( "*" ), 1, &a->acl_dn_pat );
@@ -369,7 +371,7 @@ parse_acl(
                                        Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                "missing \"=\" in \"%s\" in to clause\n",
                                            fname, lineno, left );
-                                       acl_usage();
+                                       return acl_usage();
                                }
 
                                if ( strcasecmp( left, "dn" ) == 0 ) {
@@ -380,7 +382,7 @@ parse_acl(
                                                        "%s: line %d: dn pattern"
                                                        " already specified in to clause.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( style == NULL || *style == '\0' ||
@@ -438,7 +440,7 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "unknown dn style \"%s\" in to clause\n",
                                                    fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        continue;
@@ -449,7 +451,7 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY,
                                "%s: line %d: bad filter \"%s\" in to clause\n",
                                                    fname, lineno, right );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                } else if ( strcasecmp( left, "attr" ) == 0             /* TOLERATED */
@@ -469,7 +471,7 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY,
                                "%s: line %d: unknown attr \"%s\" in to clause\n",
                                                    fname, lineno, right );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                } else if ( strncasecmp( left, "val", 3 ) == 0 ) {
@@ -479,14 +481,14 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY,
                                "%s: line %d: attr val already specified in to clause.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
                                        if ( a->acl_attrs == NULL || !BER_BVISEMPTY( &a->acl_attrs[1].an_name ) )
                                        {
                                                Debug( LDAP_DEBUG_ANY,
                                "%s: line %d: attr val requires a single attribute.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        ber_str2bv( right, 0, 1, &a->acl_attrval );
@@ -502,7 +504,7 @@ parse_acl(
                                                        Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                                "invalid matching rule \"%s\".\n",
                                                                fname, lineno, mr );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                }
 
                                                if( !mr_usable_with_at( a->acl_attrval_mr, a->acl_attrs[ 0 ].an_desc->ad_type ) )
@@ -517,7 +519,7 @@ parse_acl(
 
                                                        Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
                                                                fname, lineno, buf );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                }
                                        }
                                        
@@ -537,7 +539,7 @@ parse_acl(
 
                                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
                                                                        fname, lineno, buf );
-                                                               acl_usage();
+                                                               return acl_usage();
                                                        }
                                                        a->acl_attrval_style = ACL_STYLE_REGEX;
 
@@ -584,7 +586,7 @@ parse_acl(
                                                                                "%s: line %d: %s\n",
                                                                                fname, lineno, buf );
 #ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-                                                                       acl_usage();
+                                                                       return acl_usage();
 #endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
                                                                        a->acl_attrval_style = ACL_STYLE_BASE;
                                                                }
@@ -603,7 +605,7 @@ parse_acl(
                                                                        Debug( LDAP_DEBUG_ANY, 
                                                                                "%s: line %d: %s\n",
                                                                                fname, lineno, buf );
-                                                                       acl_usage();
+                                                                       return acl_usage();
                                                                }
                                                                ber_memfree( bv.bv_val );
 
@@ -621,7 +623,7 @@ parse_acl(
                                                                        "%s: line %d: %s\n",
                                                                        fname, lineno, buf );
 #ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-                                                               acl_usage();
+                                                               return acl_usage();
 #endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
                                                                a->acl_attrval_style = ACL_STYLE_BASE;
                                                        }
@@ -638,7 +640,7 @@ parse_acl(
                                                        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();
+                                                       return acl_usage();
                                                }
                                        }
 
@@ -646,7 +648,7 @@ parse_acl(
                                        Debug( LDAP_DEBUG_ANY,
                                                "%s: line %d: expecting <what> got \"%s\"\n",
                                            fname, lineno, left );
-                                       acl_usage();
+                                       return acl_usage();
                                }
                        }
 
@@ -668,7 +670,7 @@ parse_acl(
                                                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();
+                                               return acl_usage();
                                        }
                                        free( a->acl_dn_pat.bv_val );
                                        a->acl_dn_pat = bv;
@@ -686,7 +688,7 @@ parse_acl(
                                                        right, err );
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
                                                        fname, lineno, buf );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
                                }
                        }
@@ -697,7 +699,7 @@ parse_acl(
                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                        "to clause required before by clause in access line\n",
                                        fname, lineno, 0 );
-                               acl_usage();
+                               return acl_usage();
                        }
 
                        /*
@@ -712,7 +714,7 @@ parse_acl(
                                Debug( LDAP_DEBUG_ANY,
                                        "%s: line %d: premature EOL: expecting <who>\n",
                                        fname, lineno, 0 );
-                               acl_usage();
+                               return acl_usage();
                        }
 
                        /* get <who> */
@@ -739,13 +741,13 @@ parse_acl(
                                                                        "%s: line %d: premature eol: "
                                                                        "expecting closing '}' in \"level{n}\"\n",
                                                                        fname, lineno, 0 );
-                                                               acl_usage();
+                                                               return acl_usage();
                                                        } else if ( p == style_level ) {
                                                                Debug( LDAP_DEBUG_ANY,
                                                                        "%s: line %d: empty level "
                                                                        "in \"level{n}\"\n",
                                                                        fname, lineno, 0 );
-                                                               acl_usage();
+                                                               return acl_usage();
                                                        }
                                                        p[0] = '\0';
                                                }
@@ -782,7 +784,7 @@ parse_acl(
                                                        "%s: line %d: unable to parse level "
                                                        "in \"level{n}\"\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        sty = ACL_STYLE_LEVEL;
@@ -805,7 +807,7 @@ parse_acl(
                                                SLAPD_CONF_UNKNOWN_IGNORED ".\n",
                                                fname, lineno, 0 );
 #ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-                                       acl_usage();
+                                       return acl_usage();
 #endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
 #endif /* LDAP_PF_LOCAL */
 
@@ -813,7 +815,7 @@ parse_acl(
                                        Debug( LDAP_DEBUG_ANY,
                                                "%s: line %d: unknown style \"%s\" in by clause\n",
                                                fname, lineno, style );
-                                       acl_usage();
+                                       return acl_usage();
                                }
 
                                if ( style_modifier &&
@@ -827,7 +829,7 @@ parse_acl(
                                                        SLAPD_CONF_UNKNOWN_IGNORED ".\n",
                                                        fname, lineno, 0 );
 #ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-                                               acl_usage();
+                                               return acl_usage();
 #endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
                                                break;
 
@@ -852,7 +854,7 @@ parse_acl(
                                                SLAPD_CONF_UNKNOWN_IGNORED ".\n",
                                                fname, lineno, 0 );
 #ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-                                               acl_usage();
+                                               return acl_usage();
 #endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
                                }
 
@@ -864,7 +866,7 @@ parse_acl(
 
                                if ( strcasecmp( left, "*" ) == 0 ) {
                                        if ( is_realdn ) {
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        ber_str2bv( "*", STRLENOF( "*" ), 1, &bv );
@@ -942,7 +944,7 @@ parse_acl(
                                                        "missing \"=\" in (or value after) \"%s\" "
                                                        "in by clause\n",
                                                        fname, lineno, left );
-                                               acl_usage();
+                                               return acl_usage();
 
                                        } else {
                                                ber_str2bv( right, 0, 1, &bv );
@@ -957,7 +959,7 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: dn pattern already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( sty != ACL_STYLE_REGEX &&
@@ -972,7 +974,7 @@ parse_acl(
                                                        Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: bad DN \"%s\" in by DN clause\n",
                                                                fname, lineno, bv.bv_val );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                }
                                                free( bv.bv_val );
                                                if ( sty == ACL_STYLE_BASE
@@ -1015,7 +1017,7 @@ parse_acl(
                                                                SLAPD_CONF_UNKNOWN_IGNORED ".\n",
                                                                fname, lineno, 0 );
 #ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-                                                       acl_usage();
+                                                       return acl_usage();
 #endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
                                                } 
                                        }
@@ -1028,7 +1030,7 @@ parse_acl(
                                                                "%s: line %d: bad negative level \"%d\" "
                                                                "in by DN clause\n",
                                                                fname, lineno, level );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                } else if ( level == 1 ) {
                                                        Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: \"onelevel\" should be used "
@@ -1052,14 +1054,14 @@ parse_acl(
                                                        "missing \"=\" in (or value after) \"%s\" "
                                                        "in by clause\n",
                                                        fname, lineno, left );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if( bdn->a_at != NULL ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: dnattr already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        rc = slap_str2ad( right, &bdn->a_at, &text );
@@ -1073,7 +1075,7 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: %s\n",
                                                        fname, lineno, buf );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
 
@@ -1092,7 +1094,7 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: %s\n",
                                                        fname, lineno, buf );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if( bdn->a_at->ad_type->sat_equality == NULL ) {
@@ -1100,7 +1102,7 @@ parse_acl(
                                                        "%s: line %d: dnattr \"%s\": "
                                                        "inappropriate matching (no EQUALITY)\n",
                                                        fname, lineno, right );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        continue;
@@ -1133,7 +1135,7 @@ parse_acl(
                                                        "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause.\n",
                                                        fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( right == NULL || right[0] == '\0' ) {
@@ -1142,14 +1144,14 @@ parse_acl(
                                                        "missing \"=\" in (or value after) \"%s\" "
                                                        "in by clause.\n",
                                                        fname, lineno, left );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( !BER_BVISEMPTY( &b->a_group_pat ) ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: group pattern already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        /* format of string is
@@ -1177,7 +1179,7 @@ parse_acl(
                                                        Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: bad DN \"%s\".\n",
                                                                fname, lineno, right );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                }
                                        }
 
@@ -1190,7 +1192,7 @@ parse_acl(
                                                                "%s: line %d: group objectclass "
                                                                "\"%s\" unknown.\n",
                                                                fname, lineno, value );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                }
 
                                        } else {
@@ -1201,7 +1203,7 @@ parse_acl(
                                                                "%s: line %d: group default objectclass "
                                                                "\"%s\" unknown.\n",
                                                                fname, lineno, SLAPD_GROUP_CLASS );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                }
                                        }
 
@@ -1212,7 +1214,7 @@ parse_acl(
                                                        "%s: line %d: group objectclass \"%s\" "
                                                        "is subclass of referral.\n",
                                                        fname, lineno, value );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( is_object_subclass( slap_schema.si_oc_alias,
@@ -1222,7 +1224,7 @@ parse_acl(
                                                        "%s: line %d: group objectclass \"%s\" "
                                                        "is subclass of alias.\n",
                                                        fname, lineno, value );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( name && *name ) {
@@ -1237,7 +1239,7 @@ parse_acl(
                                                        Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: %s\n",
                                                                fname, lineno, buf );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                }
                                                *--name = '/';
 
@@ -1253,7 +1255,7 @@ parse_acl(
                                                        Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: %s\n",
                                                                fname, lineno, buf );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                }
                                        }
 
@@ -1272,7 +1274,7 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: %s\n",
                                                        fname, lineno, buf );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
 
@@ -1295,7 +1297,7 @@ parse_acl(
                                                                b->a_group_oc->soc_oid );
                                                        Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
                                                                fname, lineno, buf );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                }
                                        }
                                        continue;
@@ -1317,7 +1319,7 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause.\n",
                                                    fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( right == NULL || right[0] == '\0' ) {
@@ -1325,14 +1327,14 @@ parse_acl(
                                                        "missing \"=\" in (or value after) \"%s\" "
                                                        "in by clause.\n",
                                                        fname, lineno, left );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( !BER_BVISEMPTY( &b->a_peername_pat ) ) {
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "peername pattern already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        b->a_peername_style = sty;
@@ -1360,7 +1362,7 @@ parse_acl(
                                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                                        "illegal peername address \"%s\".\n",
                                                                        fname, lineno, addr );
-                                                               acl_usage();
+                                                               return acl_usage();
                                                        }
 
                                                        b->a_peername_mask = (unsigned long)(-1);
@@ -1374,7 +1376,7 @@ parse_acl(
                                                                                "illegal peername address mask "
                                                                                "\"%s\".\n",
                                                                                fname, lineno, mask );
-                                                                       acl_usage();
+                                                                       return acl_usage();
                                                                }
                                                        } 
 
@@ -1389,7 +1391,7 @@ parse_acl(
                                                                                "illegal peername port specification "
                                                                                "\"{%s}\".\n",
                                                                                fname, lineno, port );
-                                                                       acl_usage();
+                                                                       return acl_usage();
                                                                }
                                                        }
                                                }
@@ -1411,7 +1413,7 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause\n",
                                                    fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( right == NULL || right[0] == '\0' ) {
@@ -1419,14 +1421,14 @@ parse_acl(
                                                        "missing \"=\" in (or value after) \"%s\" "
                                                        "in by clause\n",
                                                        fname, lineno, left );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( !BER_BVISNULL( &b->a_sockname_pat ) ) {
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "sockname pattern already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        b->a_sockname_style = sty;
@@ -1469,7 +1471,7 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause.\n",
                                                    fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( right == NULL || right[0] == '\0' ) {
@@ -1477,14 +1479,14 @@ parse_acl(
                                                        "missing \"=\" in (or value after) \"%s\" "
                                                        "in by clause.\n",
                                                        fname, lineno, left );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( !BER_BVISEMPTY( &b->a_domain_pat ) ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: domain pattern already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        b->a_domain_style = sty;
@@ -1516,7 +1518,7 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause.\n",
                                                    fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( right == NULL || right[0] == '\0' ) {
@@ -1524,14 +1526,14 @@ parse_acl(
                                                        "missing \"=\" in (or value after) \"%s\" "
                                                        "in by clause.\n",
                                                        fname, lineno, left );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( !BER_BVISEMPTY( &b->a_sockurl_pat ) ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: sockurl pattern already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        b->a_sockurl_style = sty;
@@ -1569,21 +1571,21 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause.\n",
                                                        fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( !BER_BVISEMPTY( &b->a_set_pat ) ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: set attribute already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( right == NULL || *right == '\0' ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: no set is defined.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        b->a_set_style = sty;
@@ -1614,7 +1616,7 @@ parse_acl(
                                                        Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                                "unable to configure dynacl \"%s\".\n",
                                                                fname, lineno, name );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                }
 
                                                continue;
@@ -1628,14 +1630,14 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause.\n",
                                                    fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if( b->a_aci_at != NULL ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: ACI attribute already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( right != NULL && *right != '\0' ) {
@@ -1650,7 +1652,7 @@ parse_acl(
                                                        Debug( LDAP_DEBUG_ANY,
                                                                "%s: line %d: %s\n",
                                                                fname, lineno, buf );
-                                                       acl_usage();
+                                                       return acl_usage();
                                                }
 
                                        } else {
@@ -1668,7 +1670,7 @@ parse_acl(
                                                        b->a_aci_at->ad_type->sat_syntax_oid );
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
                                                        fname, lineno, buf );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        continue;
@@ -1681,21 +1683,21 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause.\n",
                                                    fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( b->a_authz.sai_ssf ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: ssf attribute already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( right == NULL || *right == '\0' ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: no ssf is defined.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        b->a_authz.sai_ssf = strtol( right, &next, 10 );
@@ -1703,14 +1705,14 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: unable to parse ssf value (%s).\n",
                                                        fname, lineno, right );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( !b->a_authz.sai_ssf ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: invalid ssf value (%s).\n",
                                                        fname, lineno, right );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
                                        continue;
                                }
@@ -1720,21 +1722,21 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause.\n",
                                                        fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( b->a_authz.sai_transport_ssf ) {
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "transport_ssf attribute already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( right == NULL || *right == '\0' ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: no transport_ssf is defined.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        b->a_authz.sai_transport_ssf = strtol( right, &next, 10 );
@@ -1742,14 +1744,14 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "unable to parse transport_ssf value (%s).\n",
                                                        fname, lineno, right );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( !b->a_authz.sai_transport_ssf ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: invalid transport_ssf value (%s).\n",
                                                        fname, lineno, right );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
                                        continue;
                                }
@@ -1759,21 +1761,21 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause.\n",
                                                        fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( b->a_authz.sai_tls_ssf ) {
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "tls_ssf attribute already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( right == NULL || *right == '\0' ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: no tls_ssf is defined\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        b->a_authz.sai_tls_ssf = strtol( right, &next, 10 );
@@ -1781,14 +1783,14 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "unable to parse tls_ssf value (%s).\n",
                                                        fname, lineno, right );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( !b->a_authz.sai_tls_ssf ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: invalid tls_ssf value (%s).\n",
                                                        fname, lineno, right );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
                                        continue;
                                }
@@ -1798,21 +1800,21 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "inappropriate style \"%s\" in by clause.\n",
                                                        fname, lineno, style );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( b->a_authz.sai_sasl_ssf ) {
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "sasl_ssf attribute already specified.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( right == NULL || *right == '\0' ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: no sasl_ssf is defined.\n",
                                                        fname, lineno, 0 );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        b->a_authz.sai_sasl_ssf = strtol( right, &next, 10 );
@@ -1820,14 +1822,14 @@ parse_acl(
                                                Debug( LDAP_DEBUG_ANY, "%s: line %d: "
                                                        "unable to parse sasl_ssf value (%s).\n",
                                                        fname, lineno, right );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
 
                                        if ( !b->a_authz.sai_sasl_ssf ) {
                                                Debug( LDAP_DEBUG_ANY,
                                                        "%s: line %d: invalid sasl_ssf value (%s).\n",
                                                        fname, lineno, right );
-                                               acl_usage();
+                                               return acl_usage();
                                        }
                                        continue;
                                }
@@ -1896,7 +1898,7 @@ parse_acl(
                                Debug( LDAP_DEBUG_ANY,
                                        "%s: line %d: expecting <access> got \"%s\".\n",
                                        fname, lineno, left );
-                               acl_usage();
+                               return acl_usage();
                        }
 
                        b->a_type = ACL_STOP;
@@ -1927,7 +1929,7 @@ parse_acl(
                                "%s: line %d: expecting \"to\" "
                                "or \"by\" got \"%s\"\n",
                                fname, lineno, argv[i] );
-                       acl_usage();
+                       return acl_usage();
                }
        }
 
@@ -1939,7 +1941,7 @@ parse_acl(
                        SLAPD_CONF_UNKNOWN_IGNORED ".\n",
                        fname, lineno, 0 );
 #ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-               acl_usage();
+               return acl_usage();
 #endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
 
        } else {
@@ -1956,7 +1958,7 @@ parse_acl(
                                SLAPD_CONF_UNKNOWN_IGNORED ".\n",
                                fname, lineno, 0 );
 #ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-                       acl_usage();
+                       return acl_usage();
 #endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
                }
 
@@ -2006,6 +2008,8 @@ parse_acl(
                        acl_append( &frontendDB->be_acl, a, pos );
                }
        }
+
+       return 0;
 }
 
 char *
@@ -2231,17 +2235,17 @@ str2accessmask( const char *str )
        return mask;
 }
 
-static void
+static int
 acl_usage( void )
 {
        char *access =
                "<access clause> ::= access to <what> "
                                "[ 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";
+               "<what> ::= * | [dn[.<dnstyle>]=<DN>] [filter=<filter>] [attrs=<attrspec>]\n"
+               "<attrspec> ::= <attrname> [val[/<matchingRule>][.<attrstyle>]=<value>] | <attrlist>\n"
+               "<attrlist> ::= <attr> [ , <attrlist> ]\n"
+               "<attr> ::= <attrname> | @<objectClass> | !<objectClass> | entry | children\n";
 
        char *who =
                "<who> ::= [ * | anonymous | users | self | dn[.<dnstyle>]=<DN> ]\n"
@@ -2278,8 +2282,9 @@ acl_usage( void )
 #endif /* ! SLAP_DYNACL */
                "";
 
-       Debug( LDAP_DEBUG_ANY, "%s%s%s\n", access, who, what );
-       exit( EXIT_FAILURE );
+       Debug( LDAP_DEBUG_ANY, "%s%s%s\n", access, what, who );
+
+       return 1;
 }
 
 /*
index 7df87348aa1c7b1b5b8740e63044c4b5e5b24230..250da6093a9fa81555c0a336a6ddb54d49f7b499 100644 (file)
@@ -30,6 +30,7 @@
 #include <ac/time.h>
 #include <ac/socket.h>
 
+#include "lutil.h"
 #include "slap.h"
 
 int
@@ -192,8 +193,6 @@ do_add( Operation *op, SlapReply *rs )
        }
 
 done:;
-       slap_graduate_commit_csn( op );
-
        if ( modlist != NULL ) {
                slap_mods_free( modlist, 0 );
        }
@@ -312,14 +311,6 @@ fe_op_add( Operation *op, SlapReply *rs )
                                }
 
 
-                               rs->sr_err = slap_mods_opattrs( op, modlist,
-                                               modtail, &rs->sr_text,
-                                               textbuf, textlen, 1 );
-                               if ( rs->sr_err != LDAP_SUCCESS ) {
-                                       send_ldap_result( op, rs );
-                                       goto done;
-                               }
-
                                /* check for duplicate values */
                                rs->sr_err = slap_mods_no_repl_user_mod_check( op,
                                        modlist, &rs->sr_text, textbuf, textlen );
@@ -626,3 +617,119 @@ slap_entry2mods(
        return LDAP_SUCCESS;
 }
 
+int slap_add_opattrs(
+       Operation *op,
+       const char **text,
+       char *textbuf,
+       size_t textlen,
+       int manage_ctxcsn )
+{
+       struct berval name, timestamp, csn = BER_BVNULL;
+       struct berval nname, tmp;
+       char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
+       char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
+       Attribute *a;
+
+       a = attr_find( op->ora_e->e_attrs,
+               slap_schema.si_ad_structuralObjectClass );
+
+       if ( !a ) {
+               Attribute *oc;
+               int rc;
+
+               oc = attr_find( op->ora_e->e_attrs, slap_schema.si_ad_objectClass );
+               if ( oc ) {
+                       rc = structural_class( oc->a_vals, &tmp, NULL, text,
+                               textbuf, textlen );
+                       if( rc != LDAP_SUCCESS ) return rc;
+
+                       attr_merge_one( op->ora_e, slap_schema.si_ad_structuralObjectClass,
+                               &tmp, NULL );
+               }
+       }
+
+       if ( SLAP_LASTMOD( op->o_bd ) ) {
+               char *ptr;
+               timestamp.bv_val = timebuf;
+               if ( BER_BVISEMPTY( &op->o_csn )) {
+                       if ( SLAP_SHADOW( op->o_bd ))
+                               manage_ctxcsn = 0;
+                       csn.bv_val = csnbuf;
+                       csn.bv_len = sizeof(csnbuf);
+                       slap_get_csn( op, &csn, manage_ctxcsn );
+               } else {
+                       csn = op->o_csn;
+               }
+               ptr = strchr( csn.bv_val, '#' );
+               if ( ptr ) {
+                       timestamp.bv_len = ptr - csn.bv_val;
+                       if ( timestamp.bv_len >= sizeof(timebuf) )
+                               timestamp.bv_len = sizeof(timebuf) - 1;
+                       strncpy( timebuf, csn.bv_val, timestamp.bv_len );
+                       timebuf[timestamp.bv_len] = '\0';
+               } else {
+                       time_t now = slap_get_time();
+
+                       timestamp.bv_len = sizeof(timebuf);
+
+                       slap_timestamp( &now, &timestamp );
+               }
+
+               if ( BER_BVISEMPTY( &op->o_dn ) ) {
+                       BER_BVSTR( &name, SLAPD_ANONYMOUS );
+                       nname = name;
+               } else {
+                       name = op->o_dn;
+                       nname = op->o_ndn;
+               }
+
+               a = attr_find( op->ora_e->e_attrs,
+                       slap_schema.si_ad_entryUUID );
+               if ( !a ) {
+                       char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
+
+                       tmp.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
+                       tmp.bv_val = uuidbuf;
+                       
+                       attr_merge_normalize_one( op->ora_e,
+                               slap_schema.si_ad_entryUUID, &tmp, op->o_tmpmemctx );
+               }
+
+               a = attr_find( op->ora_e->e_attrs,
+                       slap_schema.si_ad_creatorsName );
+               if ( !a ) {
+                       attr_merge_one( op->ora_e,
+                               slap_schema.si_ad_creatorsName, &name, &nname );
+               }
+
+               a = attr_find( op->ora_e->e_attrs,
+                       slap_schema.si_ad_createTimestamp );
+               if ( !a ) {
+                       attr_merge_one( op->ora_e,
+                               slap_schema.si_ad_createTimestamp, &timestamp, NULL );
+               }
+
+               a = attr_find( op->ora_e->e_attrs,
+                       slap_schema.si_ad_entryCSN );
+               if ( !a ) {
+                       attr_merge_one( op->ora_e,
+                               slap_schema.si_ad_entryCSN, &csn, NULL );
+               }
+
+               a = attr_find( op->ora_e->e_attrs,
+                       slap_schema.si_ad_modifiersName );
+               if ( !a ) {
+                       attr_merge_one( op->ora_e,
+                               slap_schema.si_ad_modifiersName, &name, &nname );
+               }
+
+               a = attr_find( op->ora_e->e_attrs,
+                       slap_schema.si_ad_modifyTimestamp );
+               if ( !a ) {
+                       attr_merge_one( op->ora_e,
+                               slap_schema.si_ad_modifyTimestamp, &timestamp, NULL );
+               }
+
+       }
+       return LDAP_SUCCESS;
+}
index 227652077e1258978d857763b6d58426693c4226..6cf4e58f1d2f3a855f17071f3c0cccf9456888c2 100644 (file)
@@ -51,6 +51,8 @@ bdb_add(Operation *op, SlapReply *rs )
 
        ctrls[num_ctrls] = 0;
 
+       slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
+
        /* check entry's schema */
        rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
                get_manageDIT(op), &rs->sr_text, textbuf, textlen );
@@ -170,14 +172,8 @@ retry:     /* transaction retry */
                                "does not exist\n", 0, 0, 0 );
 
                        rs->sr_err = LDAP_REFERRAL;
-                       send_ldap_result( op, rs );
-
-                       ber_bvarray_free( rs->sr_ref );
-                       op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx );
-                       rs->sr_ref = NULL;
-                       rs->sr_matched = NULL;
-
-                       goto done;
+                       rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+                       goto return_results;
                }
 
                rs->sr_err = access_allowed( op, p,
@@ -221,22 +217,18 @@ retry:    /* transaction retry */
 
                if ( is_entry_referral( p ) ) {
                        /* parent is a referral, don't allow add */
-                       rs->sr_matched = p->e_name.bv_val;
+                       rs->sr_matched = ber_strdup_x( p->e_name.bv_val,
+                               op->o_tmpmemctx );
                        rs->sr_ref = get_entry_referrals( op, p );
-
+                       bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
+                       p = NULL;
                        Debug( LDAP_DEBUG_TRACE,
                                LDAP_XSTRING(bdb_add) ": parent is referral\n",
                                0, 0, 0 );
 
                        rs->sr_err = LDAP_REFERRAL;
-                       send_ldap_result( op, rs );
-
-                       ber_bvarray_free( rs->sr_ref );
-                       bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
-                       rs->sr_ref = NULL;
-                       rs->sr_matched = NULL;
-                       p = NULL;
-                       goto done;
+                       rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+                       goto return_results;
                }
 
 #ifdef BDB_SUBENTRIES
@@ -385,7 +377,8 @@ retry:      /* transaction retry */
                if (( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
                        rs->sr_text = "txn_abort (no-op) failed";
                } else {
-                       rs->sr_err = LDAP_NO_OPERATION;
+                       rs->sr_err = LDAP_X_NO_OPERATION;
+                       ltid = NULL;
                        goto return_results;
                }
 
@@ -430,22 +423,23 @@ retry:    /* transaction retry */
 
 return_results:
        send_ldap_result( op, rs );
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_graduate_commit_csn( op );
 
-       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
-               ldap_pvt_thread_yield();
-               TXN_CHECKPOINT( bdb->bi_dbenv,
-                       bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
-       }
-
-done:
        if( ltid != NULL ) {
                TXN_ABORT( ltid );
-               op->o_private = NULL;
        }
+       op->o_private = NULL;
 
        if( postread_ctrl != NULL ) {
                slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
                slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
        }
+
+       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
+               ldap_pvt_thread_yield();
+               TXN_CHECKPOINT( bdb->bi_dbenv,
+                       bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
+       }
        return rs->sr_err;
 }
index f058c1f59672ddcda65b19638977d5d8ee64b923..6667249bd6209238f4597c5fca090648117d7430 100644 (file)
 #include "back-bdb.h"
 #include "lutil.h"
 
-
-static int
-ainfo_type_cmp(
-       const void *v_desc,
-       const void *v_a
-)
+/* Find the ad, return -1 if not found,
+ * set point for insertion if ins is non-NULL
+ */
+int
+bdb_attr_slot( struct bdb_info *bdb, AttributeDescription *ad, unsigned *ins )
 {
-       const AttributeDescription *desc = v_desc;
-       const AttrInfo  *a = v_a;
-       return SLAP_PTRCMP(desc, a->ai_desc);
+       unsigned base = 0, cursor = 0;
+       unsigned n = bdb->bi_nattrs;
+       int val = 0;
+       
+       while ( 0 < n ) {
+               int pivot = n >> 1;
+               cursor = base + pivot;
+
+               val = SLAP_PTRCMP( ad, bdb->bi_attrs[cursor]->ai_desc );
+               if ( val < 0 ) {
+                       n = pivot;
+               } else if ( val > 0 ) {
+                       base = cursor + 1;
+                       n -= pivot + 1;
+               } else {
+                       return cursor;
+               }
+       }
+       if ( ins ) {
+               if ( val > 0 )
+                       ++cursor;
+               *ins = cursor;
+       }
+       return -1;
 }
 
 static int
-ainfo_cmp(
-       const void      *v_a,
-       const void      *v_b
-)
+ainfo_insert( struct bdb_info *bdb, AttrInfo *a )
 {
-       const AttrInfo *a = v_a, *b = v_b;
-       return SLAP_PTRCMP(a->ai_desc, b->ai_desc);
+       unsigned x;
+       int i = bdb_attr_slot( bdb, a->ai_desc, &x );
+
+       /* Is it a dup? */
+       if ( i >= 0 )
+               return -1;
+
+       bdb->bi_attrs = ch_realloc( bdb->bi_attrs, ( bdb->bi_nattrs+1 ) * 
+               sizeof( AttrInfo * ));
+       if ( x < bdb->bi_nattrs )
+               AC_MEMCPY( &bdb->bi_attrs[x+1], &bdb->bi_attrs[x],
+                       ( bdb->bi_nattrs - x ) * sizeof( AttrInfo *));
+       bdb->bi_attrs[x] = a;
+       bdb->bi_nattrs++;
+       return 0;
 }
 
 AttrInfo *
@@ -52,8 +82,8 @@ bdb_attr_mask(
        struct bdb_info *bdb,
        AttributeDescription *desc )
 {
-
-       return avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
+       int i = bdb_attr_slot( bdb, desc, NULL );
+       return i < 0 ? NULL : bdb->bi_attrs[i];
 }
 
 int
@@ -220,7 +250,7 @@ bdb_attr_index_config(
 
 #ifdef LDAP_COMP_MATCH
                if ( cr ) {
-                       a_cr = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
+                       a_cr = bdb_attr_mask( bdb, ad );
                        if ( a_cr ) {
                                /*
                                 * AttrInfo is already in AVL
@@ -242,12 +272,10 @@ bdb_attr_index_config(
                        }
                }
 #endif
-               rc = avl_insert( &bdb->bi_attrs, (caddr_t) a,
-                                ainfo_cmp, avl_dup_error );
-
+               rc = ainfo_insert( bdb, a );
                if( rc ) {
                        if ( bdb->bi_flags & BDB_IS_OPEN ) {
-                               AttrInfo *b = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
+                               AttrInfo *b = bdb_attr_mask( bdb, ad );
                                /* If we were editing this attr, reset it */
                                b->ai_indexmask &= ~BDB_INDEX_DELETING;
                                /* If this is leftover from a previous add, commit it */
@@ -298,17 +326,19 @@ static AttrInfo aidef = { &addef };
 void
 bdb_attr_index_unparse( struct bdb_info *bdb, BerVarray *bva )
 {
+       int i;
+
        if ( bdb->bi_defaultmask ) {
                aidef.ai_indexmask = bdb->bi_defaultmask;
                bdb_attr_index_unparser( &aidef, bva );
        }
-       avl_apply( bdb->bi_attrs, bdb_attr_index_unparser, bva, -1, AVL_INORDER );
+       for ( i=0; i<bdb->bi_nattrs; i++ )
+               bdb_attr_index_unparser( bdb->bi_attrs[i], bva );
 }
 
-static void
-bdb_attrinfo_free( void *v )
+void
+bdb_attr_info_free( AttrInfo *ai )
 {
-       AttrInfo *ai = v;
 #ifdef LDAP_COMP_MATCH
        free( ai->ai_cr );
 #endif
@@ -316,52 +346,41 @@ bdb_attrinfo_free( void *v )
 }
 
 void
-bdb_attr_index_destroy( Avlnode *tree )
+bdb_attr_index_destroy( struct bdb_info *bdb )
 {
-       avl_free( tree, bdb_attrinfo_free );
-}
+       int i;
 
-void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad )
-{
-       AttrInfo *ai;
+       for ( i=0; i<bdb->bi_nattrs; i++ ) 
+               bdb_attr_info_free( bdb->bi_attrs[i] );
 
-       ai = avl_delete( &bdb->bi_attrs, ad, ainfo_type_cmp );
-       if ( ai )
-               bdb_attrinfo_free( ai );
+       free( bdb->bi_attrs );
 }
 
-/* Get a list of AttrInfo's to delete */
-
-typedef struct Alist {
-       struct Alist *next;
-       AttrInfo *ptr;
-} Alist;
-
-static int
-bdb_attrinfo_flush( void *v1, void *arg )
+void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad )
 {
-       AttrInfo *ai = v1;
-
-       if ( ai->ai_indexmask & BDB_INDEX_DELETING ) {
-               Alist **al = arg;
-               Alist *a = ch_malloc( sizeof( Alist ));
-               a->ptr = ai;
-               a->next = *al;
-               *al = a;
+       int i;
+
+       i = bdb_attr_slot( bdb, ad, NULL );
+       if ( i >= 0 ) {
+               bdb_attr_info_free( bdb->bi_attrs[i] );
+               bdb->bi_nattrs--;
+               for (; i<bdb->bi_nattrs; i++)
+                       bdb->bi_attrs[i] = bdb->bi_attrs[i+1];
        }
-       return 0;
 }
 
 void bdb_attr_flush( struct bdb_info *bdb )
 {
-       Alist *al = NULL, *a2;
-
-       avl_apply( bdb->bi_attrs, bdb_attrinfo_flush, &al, -1, AVL_INORDER );
-
-       while (( a2 = al )) {
-               al = al->next;
-               avl_delete( &bdb->bi_attrs, a2->ptr, ainfo_cmp );
-               bdb_attrinfo_free( a2->ptr );
-               ch_free( a2 );
+       int i;
+
+       for ( i=0; i<bdb->bi_nattrs; i++ ) {
+               if ( bdb->bi_attrs[i]->ai_indexmask & BDB_INDEX_DELETING ) {
+                       int j;
+                       bdb_attr_info_free( bdb->bi_attrs[i] );
+                       bdb->bi_nattrs--;
+                       for (j=i; j<bdb->bi_nattrs; j++)
+                               bdb->bi_attrs[j] = bdb->bi_attrs[j+1];
+                       i--;
+               }
        }
 }
index 7091d343db863181cb43951e063aac023692c598..854a9b80ffa927f88ea4f00e201b62f10deaef6d 100644 (file)
@@ -166,7 +166,8 @@ struct bdb_info {
 
        slap_mask_t     bi_defaultmask;
        Cache           bi_cache;
-       Avlnode         *bi_attrs;
+       struct bdb_attrinfo             **bi_attrs;
+       int                     bi_nattrs;
        void            *bi_search_stack;
        int             bi_search_stack_depth;
        int             bi_linear_index;
@@ -299,6 +300,19 @@ typedef struct bdb_attrinfo {
 #define        BDB_INDEX_DELETING      0x8000U /* index is being modified */
 #define        BDB_INDEX_UPDATE_OP     0x03    /* performing an index update */
 
+/* For slapindex to record which attrs in an entry belong to which
+ * index database 
+ */
+typedef struct AttrList {
+       struct AttrList *next;
+       Attribute *attr;
+} AttrList;
+
+typedef struct IndexRec {
+       AttrInfo *ai;
+       AttrList *attrs;
+} IndexRec;
+
 #include "proto-bdb.h"
 
 #endif /* _BACK_BDB_H_ */
index d155ef7c2ea9cdca7c1eaeb7d8550ef11002cfcd..b236ac2dab2a8d50f3dce73be325fdeb3aadad48 100644 (file)
@@ -35,16 +35,6 @@ static int   bdb_cache_delete_internal(Cache *cache, EntryInfo *e, int decr);
 static void    bdb_lru_print(Cache *cache);
 #endif
 
-static int bdb_txn_get( Operation *op, DB_ENV *env, DB_TXN **txn, int reset );
-
-/* 4.2.52 */
-#if DB_VERSION_FULL == 0x04020034
-#define        READ_TXN_FLAG   ReadFlag
-static int ReadFlag = DB_TXN_NOT_DURABLE;
-#else
-#define READ_TXN_FLAG  0
-#endif
-
 static EntryInfo *
 bdb_cache_entryinfo_new( Cache *cache )
 {
@@ -384,10 +374,11 @@ bdb_cache_find_ndn(
 /* Walk up the tree from a child node, looking for an ID that's already
  * been linked into the cache.
  */
-static int
+int
 hdb_cache_find_parent(
        Operation *op,
        DB_TXN *txn,
+       u_int32_t       locker,
        ID id,
        EntryInfo **res )
 {
@@ -401,7 +392,7 @@ hdb_cache_find_parent(
        ei.bei_ckids = 0;
 
        for (;;) {
-               rc = hdb_dn2id_parent( op, txn, &ei, &eip.bei_id );
+               rc = hdb_dn2id_parent( op, txn, locker, &ei, &eip.bei_id );
                if ( rc ) break;
 
                /* Save the previous node, if any */
@@ -703,7 +694,7 @@ again:      ldap_pvt_thread_rdwr_rlock( &bdb->bi_cache.c_rwlock );
        /* See if the ID exists in the database; add it to the cache if so */
        if ( !*eip ) {
 #ifndef BDB_HIER
-               rc = bdb_id2entry( op->o_bd, tid, id, &ep );
+               rc = bdb_id2entry( op->o_bd, tid, locker, id, &ep );
                if ( rc == 0 ) {
                        rc = bdb_cache_find_ndn( op, tid,
                                &ep->e_nname, eip );
@@ -718,7 +709,7 @@ again:      ldap_pvt_thread_rdwr_rlock( &bdb->bi_cache.c_rwlock );
                        }
                }
 #else
-               rc = hdb_cache_find_parent(op, tid, id, eip );
+               rc = hdb_cache_find_parent(op, tid, locker, id, eip );
                if ( rc == 0 && *eip ) islocked = 1;
 #endif
        }
@@ -751,31 +742,14 @@ load1:
                                bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
                        } else if ( rc == 0 ) {
                                if ( load ) {
-                                       DB_TXN *ltid;
-                                       u_int32_t locker2 = locker;
-
-                                       /* We don't wrap entire read operations in txn's, but
-                                        * we need our cache entry lock and any DB page locks
-                                        * to be associated, in order for deadlock detection
-                                        * to work properly. So if we need to read from the DB,
-                                        * we use a long-lived per-thread txn for this step.
-                                        */
-                                       if ( !ep && !tid ) {
-                                               rc = bdb_txn_get( op, bdb->bi_dbenv, &ltid, 0 );
-                                               if ( ltid )
-                                                       locker2 = TXN_ID( ltid );
-                                       } else {
-                                               ltid = tid;
-                                       }
-                                       /* Give up original read lock, obtain write lock with
-                                        * (possibly) new locker ID.
+                                       /* Give up original read lock, obtain write lock
                                         */
                                    if ( rc == 0 ) {
-                                               rc = bdb_cache_entry_db_relock( bdb->bi_dbenv, locker2,
+                                               rc = bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
                                                        *eip, 1, 0, lock );
                                        }
                                        if ( rc == 0 && !ep) {
-                                               rc = bdb_id2entry( op->o_bd, ltid, id, &ep );
+                                               rc = bdb_id2entry( op->o_bd, tid, locker, id, &ep );
                                        }
                                        if ( rc == 0 ) {
                                                ep->e_private = *eip;
@@ -797,22 +771,6 @@ load1:
                                                /* Otherwise, release the lock. */
                                                bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
                                        }
-                                       if ( locker2 != locker ) {
-                                               /* If we're using the per-thread txn, release all
-                                                * of its page locks now.
-                                                */
-                                               DB_LOCKREQ list;
-                                               list.op = DB_LOCK_PUT_ALL;
-                                               list.obj = NULL;
-                                               bdb->bi_dbenv->lock_vec( bdb->bi_dbenv, locker2,
-                                                       0, &list, 1, NULL );
-                                               /* If this txn was deadlocked, we must abort it
-                                                * and invalidate this per-thread txn.
-                                                */
-                                               if ( rc == DB_LOCK_DEADLOCK ) {
-                                                       bdb_txn_get( op, bdb->bi_dbenv, &ltid, 1 );
-                                               }
-                                       }
                                } else if ( !(*eip)->bei_e ) {
                                        /* Some other thread is trying to load the entry,
                                         * give it a chance to finish.
@@ -1281,77 +1239,6 @@ bdb_lru_print( Cache *cache )
 }
 #endif
 
-static void
-bdb_txn_free( void *key, void *data )
-{
-       DB_TXN *txn = data;
-       TXN_ABORT( txn );
-}
-
-/* Obtain a long-lived transaction for the current thread.
- * If reset == 1, remove the current transaction. */
-static int
-bdb_txn_get( Operation *op, DB_ENV *env, DB_TXN **txn, int reset )
-{
-       int i, rc;
-       void *ctx, *data = NULL;
-
-       if ( slapMode & SLAP_TOOL_MODE ) {
-               *txn = NULL;
-               return 0;
-       }
-
-       /* If no op was provided, try to find the ctx anyway... */
-       if ( op ) {
-               ctx = op->o_threadctx;
-       } else {
-               ctx = ldap_pvt_thread_pool_context();
-       }
-
-       /* Shouldn't happen unless we're single-threaded */
-       if ( !ctx ) {
-               *txn = NULL;
-               return 0;
-       }
-
-       if ( reset ) {
-               TXN_ABORT( *txn );
-               return ldap_pvt_thread_pool_setkey( ctx, ((char *)env)+1, NULL, NULL );
-       }
-
-       if ( ldap_pvt_thread_pool_getkey( ctx, ((char *)env)+1, &data, NULL ) ||
-               data == NULL ) {
-               for ( i=0, rc=1; rc != 0 && i<4; i++ ) {
-                       rc = TXN_BEGIN( env, NULL, txn, READ_TXN_FLAG );
-#if DB_VERSION_FULL == 0x04020034
-                       if ( rc == EINVAL && READ_TXN_FLAG ) {
-                               READ_TXN_FLAG = 0;
-                               Debug( LDAP_DEBUG_ANY,
-                                       "bdb_txn_get: BerkeleyDB 4.2.52 library needs TXN patch!\n",
-                                       0, 0, 0 );
-                               i--;
-                               continue;
-                       }
-#endif
-                       if (rc) ldap_pvt_thread_yield();
-               }
-               if ( rc != 0) {
-                       return rc;
-               }
-               if ( ( rc = ldap_pvt_thread_pool_setkey( ctx, ((char *)env)+1,
-                       *txn, bdb_txn_free ) ) ) {
-                       TXN_ABORT( *txn );
-                       Debug( LDAP_DEBUG_ANY, "bdb_txn_get: err %s(%d)\n",
-                               db_strerror(rc), rc, 0 );
-
-                       return rc;
-               }
-       } else {
-               *txn = data;
-       }
-       return 0;
-}
-
 #ifdef BDB_REUSE_LOCKERS
 static void
 bdb_locker_id_free( void *key, void *data )
index a0dcce5669ff1af4971d92c4069f8dc56b4ca313..a1bef6cccd343e35ffd38373300bc24af5a6468d 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <ac/string.h>
 
+#include "lutil.h"
 #include "back-bdb.h"
 
 int
@@ -51,15 +52,20 @@ bdb_delete( Operation *op, SlapReply *rs )
        int     parent_is_glue = 0;
        int parent_is_leaf = 0;
 
-       struct berval ctxcsn_ndn = BER_BVNULL;
-
        ctrls[num_ctrls] = 0;
 
        Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_delete) ": %s\n",
                op->o_req_dn.bv_val, 0, 0 );
 
-       build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0],
-                               (struct berval *)&slap_ldapsync_cn_bv, op->o_tmpmemctx );
+       /* allocate CSN */
+       if ( !SLAP_SHADOW( op->o_bd )) {
+               struct berval csn;
+               char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
+
+               csn.bv_val = csnbuf;
+               csn.bv_len = sizeof(csnbuf);
+               slap_get_csn( op, &csn, 1 );
+       }
 
        if( 0 ) {
 retry: /* transaction retry */
@@ -166,17 +172,8 @@ retry:     /* transaction retry */
                }
 
                rs->sr_err = LDAP_REFERRAL;
-               send_ldap_result( op, rs );
-
-               if ( rs->sr_ref != default_referral ) {
-                       ber_bvarray_free( rs->sr_ref );
-               }
-               free( (char *)rs->sr_matched );
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-
-               rs->sr_err = -1;
-               goto done;
+               rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+               goto return_results;
        }
 
        rc = bdb_cache_find_id( op, ltid, eip->bei_id, &eip, 0, locker, &plock );
@@ -296,15 +293,9 @@ retry:     /* transaction retry */
                        0, 0, 0 );
 
                rs->sr_err = LDAP_REFERRAL;
-               rs->sr_matched = e->e_name.bv_val;
-               send_ldap_result( op, rs );
-
-               ber_bvarray_free( rs->sr_ref );
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-
-               rs->sr_err = 1;
-               goto done;
+               rs->sr_matched = ch_strdup( e->e_name.bv_val );
+               rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+               goto return_results;
        }
 
        /* pre-read */
@@ -455,7 +446,8 @@ retry:      /* transaction retry */
                if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) {
                        rs->sr_text = "txn_abort (no-op) failed";
                } else {
-                       rs->sr_err = LDAP_NO_OPERATION;
+                       rs->sr_err = LDAP_X_NO_OPERATION;
+                       ltid = NULL;
                        goto return_results;
                }
        } else {
@@ -492,19 +484,10 @@ retry:    /* transaction retry */
        if( num_ctrls ) rs->sr_ctrls = ctrls;
 
 return_results:
-       send_ldap_result( op, rs );
-
-       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
-               ldap_pvt_thread_yield();
-               TXN_CHECKPOINT( bdb->bi_dbenv,
-                       bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
-       }
-
        if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) {
                op->o_delete_glue_parent = 1;
        }
 
-done:
        if ( p )
                bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
 
@@ -520,14 +503,22 @@ done:
 
        if( ltid != NULL ) {
                TXN_ABORT( ltid );
-               op->o_private = NULL;
        }
+       op->o_private = NULL;
 
-       slap_sl_free( ctxcsn_ndn.bv_val, op->o_tmpmemctx );
+       send_ldap_result( op, rs );
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_graduate_commit_csn( op );
 
        if( preread_ctrl != NULL ) {
                slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
                slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
        }
+
+       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
+               ldap_pvt_thread_yield();
+               TXN_CHECKPOINT( bdb->bi_dbenv,
+                       bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
+       }
        return rs->sr_err;
 }
index d2ed137e979716e881c372e6c82f475a0cfe9307..51beedb2f4c4967b1f127eb2d99f55976a30fcc6 100644 (file)
@@ -709,6 +709,7 @@ int
 hdb_dn2id_parent(
        Operation *op,
        DB_TXN *txn,
+       u_int32_t       locker,
        EntryInfo *ei,
        ID *idp )
 {
@@ -733,6 +734,9 @@ hdb_dn2id_parent(
 
        rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
        if ( rc ) return rc;
+       if ( !txn && locker ) {
+               cursor->locker = locker;
+       }
 
        data.ulen = sizeof(diskNode) + (SLAP_LDAPDN_MAXLEN * 2);
        d = op->o_tmpalloc( data.ulen, op->o_tmpmemctx );
@@ -915,7 +919,8 @@ hdb_dn2idl_internal(
 
                cx->rc = cx->db->cursor( cx->db, NULL, &cx->dbc,
                        cx->bdb->bi_db_opflags );
-               if ( cx->rc ) return cx->rc;
+               if ( cx->rc )
+                       goto done_one;
 
                cx->data.data = &cx->dbuf;
                cx->data.ulen = sizeof(ID);
@@ -928,7 +933,7 @@ hdb_dn2idl_internal(
                cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data, DB_SET );
                if ( cx->rc ) {
                        cx->dbc->c_close( cx->dbc );
-                       return cx->rc;
+                       goto done_one;
                }
 
                /* If the on-disk count is zero we've never checked it.
@@ -973,6 +978,13 @@ hdb_dn2idl_internal(
                        }
                }
                cx->rc = cx->dbc->c_close( cx->dbc );
+done_one:
+               bdb_cache_entryinfo_lock( cx->ei );
+               cx->ei->bei_state ^= CACHE_ENTRY_ONELEVEL;
+               bdb_cache_entryinfo_unlock( cx->ei );
+               if ( cx->rc )
+                       return cx->rc;
+
        } else {
                /* The in-memory cache is in sync with the on-disk data.
                 * do we have any kids?
index 9a1e7d520c3ad626cdccc0222685cb5cbbc5a82d..dd427d2ba69a4f56a2c9afa78e9d451537cf9c4d 100644 (file)
@@ -92,12 +92,14 @@ int bdb_id2entry_update(
 int bdb_id2entry(
        BackendDB *be,
        DB_TXN *tid,
+       u_int32_t locker,
        ID id,
        Entry **e )
 {
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
        DB *db = bdb->bi_id2entry->bdi_db;
        DBT key, data;
+       DBC *cursor;
        struct berval bv;
        int rc = 0;
        ID nid;
@@ -113,7 +115,15 @@ int bdb_id2entry(
        data.flags = DB_DBT_MALLOC;
 
        /* fetch it */
-       rc = db->get( db, tid, &key, &data, bdb->bi_db_opflags );
+       rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
+       if ( rc ) return rc;
+
+       /* Use our own locker if needed */
+       if ( !tid && locker )
+               cursor->locker = locker;
+
+       rc = cursor->c_get( cursor, &key, &data, DB_SET );
+       cursor->c_close( cursor );
 
        if( rc != 0 ) {
                return rc;
@@ -212,14 +222,10 @@ int bdb_entry_return(
                e->e_nname.bv_val = NULL;
        }
 #ifndef SLAP_ZONE_ALLOC
-#ifndef BDB_HIER
        /* In tool mode the e_bv buffer is realloc'd, leave it alone */
        if( !(slapMode & SLAP_TOOL_MODE) ) {
                free( e->e_bv.bv_val );
        }
-#else
-       free( e->e_bv.bv_val );
-#endif /* BDB_HIER */
 #endif /* !SLAP_ZONE_ALLOC */
 
 #ifdef SLAP_ZONE_ALLOC
index 0e17da25b7661b48d9402e02a238e4299d331010..18c478db536ff13261b5523ac055949f62d1bf2b 100644 (file)
@@ -48,7 +48,7 @@ static AttrInfo *index_mask(
                /* has tagging option */
                ai = bdb_attr_mask( be->be_private, desc->ad_type->sat_ad );
 
-               if ( ai && ( ai->ai_indexmask ^ SLAP_INDEX_NOTAGS ) ) {
+               if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOTAGS ) ) {
                        *atname = desc->ad_type->sat_cname;
                        return ai;
                }
@@ -61,7 +61,7 @@ static AttrInfo *index_mask(
 
                ai = bdb_attr_mask( be->be_private, at->sat_ad );
 
-               if ( ai && ( ai->ai_indexmask ^ SLAP_INDEX_NOSUBTYPES ) ) {
+               if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOSUBTYPES ) ) {
                        *atname = at->sat_cname;
                        return ai;
                }
@@ -377,6 +377,80 @@ int bdb_index_values(
        return rc;
 }
 
+/* Get the list of which indices apply to this attr */
+int
+bdb_index_recset(
+       struct bdb_info *bdb,
+       Attribute *a,
+       AttributeType *type,
+       struct berval *tags,
+       IndexRec *ir )
+{
+       int rc, slot;
+       AttrList *al;
+
+       if( type->sat_sup ) {
+               /* recurse */
+               rc = bdb_index_recset( bdb, a, type->sat_sup, tags, ir );
+               if( rc ) return rc;
+       }
+       /* If this type has no AD, we've never used it before */
+       if( type->sat_ad ) {
+               slot = bdb_attr_slot( bdb, type->sat_ad, NULL );
+               if ( slot >= 0 ) {
+                       ir[slot].ai = bdb->bi_attrs[slot];
+                       al = ch_malloc( sizeof( AttrList ));
+                       al->attr = a;
+                       al->next = ir[slot].attrs;
+                       ir[slot].attrs = al;
+               }
+       }
+       if( tags->bv_len ) {
+               AttributeDescription *desc;
+
+               desc = ad_find_tags( type, tags );
+               if( desc ) {
+                       slot = bdb_attr_slot( bdb, desc, NULL );
+                       if ( slot >= 0 ) {
+                               ir[slot].ai = bdb->bi_attrs[slot];
+                               al = ch_malloc( sizeof( AttrList ));
+                               al->attr = a;
+                               al->next = ir[slot].attrs;
+                               ir[slot].attrs = al;
+                       }
+               }
+       }
+       return LDAP_SUCCESS;
+}
+
+/* Apply the indices for the recset */
+int bdb_index_recrun(
+       Operation *op,
+       struct bdb_info *bdb,
+       IndexRec *ir0,
+       ID id,
+       int base )
+{
+       IndexRec *ir;
+       AttrList *al;
+       int i, rc = 0;
+
+       for (i=base; i<bdb->bi_nattrs; i+=slap_tool_thread_max) {
+               ir = ir0 + i;
+               if ( !ir->ai ) continue;
+               while (( al = ir->attrs )) {
+                       ir->attrs = al->next;
+                       rc = indexer( op, NULL, ir->ai->ai_desc,
+                               &ir->ai->ai_desc->ad_type->sat_cname,
+                               al->attr->a_nvals, id, SLAP_INDEX_ADD_OP,
+                               ir->ai->ai_indexmask );
+                       free( al );
+                       if ( rc ) break;
+               }
+       }
+       return rc;
+}
+
 int
 bdb_index_entry(
        Operation *op,
index 36af08c8e5d03e6fe3e42ff3949172c949718b4b..3fbf91bf6d262b49bb3acb8f5b7377e86ed28132 100644 (file)
@@ -426,6 +426,10 @@ bdb_db_open( BackendDB *be )
                }
 
                if( i == BDB_ID2ENTRY ) {
+                       if ( slapMode & SLAP_TOOL_MODE )
+                               db->bdi_db->mpf->set_priority( db->bdi_db->mpf,
+                                       DB_PRIORITY_VERY_LOW );
+
                        rc = db->bdi_db->set_pagesize( db->bdi_db,
                                BDB_ID2ENTRY_PAGESIZE );
                        if ( slapMode & SLAP_TOOL_READMAIN ) {
@@ -482,13 +486,6 @@ bdb_db_open( BackendDB *be )
                        return rc;
                }
 
-#if 0
-               if( i == BDB_ID2ENTRY && ( slapMode & SLAP_TOOL_MODE )) {
-                       db->bdi_db->mpf->set_priority( db->bdi_db->mpf,
-                               DB_PRIORITY_VERY_LOW );
-               }
-#endif
-
                flags &= ~(DB_CREATE | DB_RDONLY);
                db->bdi_name = bdbi_databases[i].name;
                bdb->bi_databases[i] = db;
@@ -609,7 +606,7 @@ bdb_db_destroy( BackendDB *be )
        if( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home );
        if( bdb->bi_db_config_path ) ch_free( bdb->bi_db_config_path );
 
-       bdb_attr_index_destroy( bdb->bi_attrs );
+       bdb_attr_index_destroy( bdb );
 
        ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock );
        ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.lru_mutex );
index e64236693578b93efa160842596e3ec413bd1a8e..7b36624e08a5a3c4c2c9ee7fb9a8e15b9ea1bc42 100644 (file)
@@ -84,7 +84,13 @@ bdb_key_change(
 
        if (op == SLAP_INDEX_ADD_OP) {
                /* Add values */
-               rc = bdb_idl_insert_key( be, db, txn, &key, id );
+
+#ifdef BDB_TOOL_IDL_CACHING
+               if ( slapMode & SLAP_TOOL_QUICK )
+                       rc = bdb_tool_idl_add( be, db, txn, &key, id );
+               else
+#endif
+                       rc = bdb_idl_insert_key( be, db, txn, &key, id );
                if ( rc == DB_KEYEXIST ) rc = 0;
        } else {
                /* Delete values */
index e680de5ef2a176f9720f394f1272a1915c4bf565..08d0a5d8c7c114b798c751dbc4a9e56490f13f44 100644 (file)
@@ -289,6 +289,9 @@ bdb_modify( Operation *op, SlapReply *rs )
 
        ctrls[num_ctrls] = NULL;
 
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_mods_opattrs( op, op->orm_modlist, 1 );
+
        if( 0 ) {
 retry: /* transaction retry */
                if ( dummy.e_attrs ) {
@@ -524,7 +527,8 @@ retry:      /* transaction retry */
                if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) {
                        rs->sr_text = "txn_abort (no-op) failed";
                } else {
-                       rs->sr_err = LDAP_NO_OPERATION;
+                       rs->sr_err = LDAP_X_NO_OPERATION;
+                       ltid = NULL;
                        goto return_results;
                }
        } else {
@@ -573,6 +577,8 @@ return_results:
                attrs_free( dummy.e_attrs );
        }
        send_ldap_result( op, rs );
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_graduate_commit_csn( op );
 
        if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
                ldap_pvt_thread_yield();
@@ -583,8 +589,8 @@ return_results:
 done:
        if( ltid != NULL ) {
                TXN_ABORT( ltid );
-               op->o_private = NULL;
        }
+       op->o_private = NULL;
 
        if( e != NULL ) {
                bdb_unlocked_cache_return_entry_w (&bdb->bi_cache, e);
index 1bdebe513366690d75209887d1b6a82d77ec599f..422420dcafc84e0c2d582fe274b073b1fff3bf9b 100644 (file)
@@ -728,7 +728,8 @@ retry:      /* transaction retry */
                if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
                        rs->sr_text = "txn_abort (no-op) failed";
                } else {
-                       rs->sr_err = LDAP_SUCCESS;
+                       rs->sr_err = LDAP_X_NO_OPERATION;
+                       ltid = NULL;
                        goto return_results;
                }
 
@@ -831,8 +832,8 @@ done:
 
        if( ltid != NULL ) {
                TXN_ABORT( ltid );
-               op->o_private = NULL;
        }
+       op->o_private = NULL;
 
        if( preread_ctrl != NULL ) {
                slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
index a9a3b831560eac0568e5e8d3f563730389fbb27e..9991da08b3e1bfac2b2bd5487bcb1712c3d281d6 100644 (file)
@@ -32,25 +32,32 @@ LDAP_BEGIN_DECL
 
 #define bdb_attr_mask                          BDB_SYMBOL(attr_mask)
 #define bdb_attr_flush                         BDB_SYMBOL(attr_flush)
+#define bdb_attr_slot                          BDB_SYMBOL(attr_slot)
 #define bdb_attr_index_config          BDB_SYMBOL(attr_index_config)
 #define bdb_attr_index_destroy         BDB_SYMBOL(attr_index_destroy)
 #define bdb_attr_index_free                    BDB_SYMBOL(attr_index_free)
 #define bdb_attr_index_unparse         BDB_SYMBOL(attr_index_unparse)
+#define bdb_attr_info_free                     BDB_SYMBOL(attr_info_free)
 
 AttrInfo *bdb_attr_mask( struct bdb_info *bdb,
        AttributeDescription *desc );
 
 void bdb_attr_flush( struct bdb_info *bdb );
 
+int bdb_attr_slot( struct bdb_info *bdb,
+       AttributeDescription *desc, unsigned *insert );
+
 int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb,
        const char *fname, int lineno,
        int argc, char **argv ));
 
 void bdb_attr_index_unparse LDAP_P(( struct bdb_info *bdb, BerVarray *bva ));
-void bdb_attr_index_destroy LDAP_P(( Avlnode *tree ));
+void bdb_attr_index_destroy LDAP_P(( struct bdb_info *bdb ));
 void bdb_attr_index_free LDAP_P(( struct bdb_info *bdb,
        AttributeDescription *ad ));
 
+void bdb_attr_info_free( AttrInfo *ai );
+
 /*
  * config.c
  */
@@ -124,6 +131,7 @@ int bdb_dn2idl(
 int bdb_dn2id_parent(
        Operation *op,
        DB_TXN *txn,
+       u_int32_t locker,
        EntryInfo *ei,
        ID *idp );
 
@@ -191,6 +199,7 @@ int bdb_id2entry_delete(
 int bdb_id2entry(
        BackendDB *be,
        DB_TXN *tid,
+       u_int32_t locker,
        ID id,
        Entry **e);
 #endif
@@ -320,6 +329,8 @@ int bdb_idl_append_one( ID *ids, ID id );
 #define bdb_index_param                                BDB_SYMBOL(index_param)
 #define bdb_index_values                       BDB_SYMBOL(index_values)
 #define bdb_index_entry                                BDB_SYMBOL(index_entry)
+#define bdb_index_recset                       BDB_SYMBOL(index_recset)
+#define bdb_index_recrun                       BDB_SYMBOL(index_recrun)
 
 extern int
 bdb_index_is_indexed LDAP_P((
@@ -344,6 +355,22 @@ bdb_index_values LDAP_P((
        ID id,
        int opid ));
 
+extern int
+bdb_index_recset LDAP_P((
+       struct bdb_info *bdb,
+       Attribute *a,
+       AttributeType *type,
+       struct berval *tags,
+       IndexRec *ir ));
+
+extern int
+bdb_index_recrun LDAP_P((
+       Operation *op,
+       struct bdb_info *bdb,
+       IndexRec *ir,
+       ID id,
+       int base ));
+
 int bdb_index_entry LDAP_P(( Operation *op, DB_TXN *t, int r, Entry *e ));
 
 #define bdb_index_entry_add(op,t,e) \
@@ -443,6 +470,7 @@ void bdb_unlocked_cache_return_entry_rw( Cache *cache, Entry *e, int rw );
 #define bdb_cache_find_id                      BDB_SYMBOL(cache_find_id)
 #define bdb_cache_find_info                    BDB_SYMBOL(cache_find_info)
 #define bdb_cache_find_ndn                     BDB_SYMBOL(cache_find_ndn)
+#define bdb_cache_find_parent          BDB_SYMBOL(cache_find_parent)
 #define bdb_cache_modify                       BDB_SYMBOL(cache_modify)
 #define bdb_cache_modrdn                       BDB_SYMBOL(cache_modrdn)
 #define bdb_cache_release_all          BDB_SYMBOL(cache_release_all)
@@ -495,6 +523,14 @@ int bdb_cache_find_id(
        u_int32_t       locker,
        DB_LOCK         *lock
 );
+int
+bdb_cache_find_parent(
+       Operation *op,
+       DB_TXN *txn,
+       u_int32_t       locker,
+       ID id,
+       EntryInfo **res
+);
 int bdb_cache_delete(
        Cache   *cache,
        Entry   *e,
@@ -584,6 +620,7 @@ bdb_trans_backoff( int num_retries );
 #define bdb_tool_dn2id_get             BDB_SYMBOL(tool_dn2id_get)
 #define bdb_tool_id2entry_get          BDB_SYMBOL(tool_id2entry_get)
 #define bdb_tool_entry_modify          BDB_SYMBOL(tool_entry_modify)
+#define bdb_tool_idl_add               BDB_SYMBOL(tool_idl_add)
 
 extern BI_init                         bdb_back_initialize;
 
@@ -615,6 +652,8 @@ extern BI_tool_dn2id_get            bdb_tool_dn2id_get;
 extern BI_tool_id2entry_get            bdb_tool_id2entry_get;
 extern BI_tool_entry_modify            bdb_tool_entry_modify;
 
+int bdb_tool_idl_add( BackendDB *be, DB *db, DB_TXN *txn, DBT *key, ID id );
+
 LDAP_END_DECL
 
 #endif /* _PROTO_BDB_H */
index bafba3549e7a2ef597aba98f95496bcdc354d59f..d3701e15931dfdeb774c5c0a8c35e389ada5a73d 100644 (file)
@@ -21,6 +21,7 @@
 
 #define AVL_INTERNAL
 #include "back-bdb.h"
+#include "idl.h"
 
 static DBC *cursor = NULL;
 static DBT key, data;
@@ -35,24 +36,96 @@ static dn_id hbuf[HOLE_SIZE], *holes = hbuf;
 static unsigned nhmax = HOLE_SIZE;
 static unsigned nholes;
 
-static Avlnode *index_attrs, index_dummy;
+static int index_nattrs;
+
+#ifdef BDB_TOOL_IDL_CACHING
+#define bdb_tool_idl_cmp               BDB_SYMBOL(tool_idl_cmp)
+#define bdb_tool_idl_flush_one         BDB_SYMBOL(tool_idl_flush_one)
+#define bdb_tool_idl_flush             BDB_SYMBOL(tool_idl_flush)
+
+static int bdb_tool_idl_flush( BackendDB *be );
+
+#define        IDBLOCK 1024
+
+typedef struct bdb_tool_idl_cache_entry {
+       struct bdb_tool_idl_cache_entry *next;
+       ID ids[IDBLOCK];
+} bdb_tool_idl_cache_entry;
+typedef struct bdb_tool_idl_cache {
+       struct berval kstr;
+       bdb_tool_idl_cache_entry *head, *tail;
+       ID first, last;
+       int count;
+} bdb_tool_idl_cache;
+
+static bdb_tool_idl_cache_entry *bdb_tool_idl_free_list;
+#endif /* BDB_TOOL_IDL_CACHING */
+
+static ID bdb_tool_ix_id;
+static Operation *bdb_tool_ix_op;
+static volatile int *bdb_tool_index_threads;
+static void *bdb_tool_index_rec;
+static struct bdb_info *bdb_tool_info;
+static ldap_pvt_thread_mutex_t bdb_tool_index_mutex;
+static ldap_pvt_thread_cond_t bdb_tool_index_cond;
+
+static int bdb_tool_ix_rec( int base );
+static void * bdb_tool_index_task( void *ctx, void *ptr );
 
 int bdb_tool_entry_open(
        BackendDB *be, int mode )
 {
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
        /* initialize key and data thangs */
        DBTzero( &key );
        DBTzero( &data );
        key.flags = DB_DBT_REALLOC;
        data.flags = DB_DBT_REALLOC;
 
+       if (cursor == NULL) {
+               int rc = bdb->bi_id2entry->bdi_db->cursor(
+                       bdb->bi_id2entry->bdi_db, NULL, &cursor,
+                       bdb->bi_db_opflags );
+               if( rc != 0 ) {
+                       return -1;
+               }
+       }
+
+       /* Set up for slapindex */
+       if ( !(slapMode & SLAP_TOOL_READONLY )) {
+               int i;
+               if ( !bdb_tool_info && ( slapMode & SLAP_TOOL_QUICK )) {
+                       ldap_pvt_thread_mutex_init( &bdb_tool_index_mutex );
+                       ldap_pvt_thread_cond_init( &bdb_tool_index_cond );
+                       bdb_tool_index_threads = ch_malloc( slap_tool_thread_max * sizeof( int ));
+                       bdb_tool_index_rec = ch_malloc( bdb->bi_nattrs * sizeof( IndexRec ));
+                       for (i=1; i<slap_tool_thread_max; i++) {
+                               int *ptr = ch_malloc( sizeof( int ));
+                               *ptr = i;
+                               ldap_pvt_thread_pool_submit( &connection_pool,
+                                       bdb_tool_index_task, ptr );
+                               ldap_pvt_thread_yield();
+                       }
+               }
+               bdb_tool_info = bdb;
+       }
+
        return 0;
 }
 
 int bdb_tool_entry_close(
        BackendDB *be )
 {
-       assert( be != NULL );
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
+       if ( bdb_tool_info ) {
+               slapd_shutdown = 1;
+               ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
+               ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond );
+               ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
+       }
 
        if( key.data ) {
                ch_free( key.data );
@@ -68,6 +141,10 @@ int bdb_tool_entry_close(
                cursor = NULL;
        }
 
+#ifdef BDB_TOOL_IDL_CACHING
+       bdb_tool_idl_flush( be );
+#endif
+
        if( nholes ) {
                unsigned i;
                fprintf( stderr, "Error, entries missing!\n");
@@ -81,8 +158,6 @@ int bdb_tool_entry_close(
        return 0;
 }
 
-static int bdb_reindex_cmp(const void *a, const void *b) { return 0; }
-
 ID bdb_tool_entry_next(
        BackendDB *be )
 {
@@ -94,30 +169,19 @@ ID bdb_tool_entry_next(
        assert( slapMode & SLAP_TOOL_MODE );
        assert( bdb != NULL );
        
-       /* Initialization */
-       if (cursor == NULL) {
-               rc = bdb->bi_id2entry->bdi_db->cursor(
-                       bdb->bi_id2entry->bdi_db, NULL, &cursor,
-                       bdb->bi_db_opflags );
-               if( rc != 0 ) {
-                       return NOID;
-               }
-       }
-
        rc = cursor->c_get( cursor, &key, &data, DB_NEXT );
 
        if( rc != 0 ) {
                /* If we're doing linear indexing and there are more attrs to
                 * index, and we're at the end of the database, start over.
                 */
-               if ( bdb->bi_attrs == &index_dummy ) {
-                       if ( index_attrs && rc == DB_NOTFOUND ) {
-                               /* optional - do a checkpoint here? */
-                               index_dummy.avl_data = avl_delete(&index_attrs, NULL, bdb_reindex_cmp);
-                               rc = cursor->c_get( cursor, &key, &data, DB_FIRST );
-                       }
+               if ( index_nattrs && rc == DB_NOTFOUND ) {
+                       /* optional - do a checkpoint here? */
+                       bdb_attr_info_free( bdb->bi_attrs[0] );
+                       bdb->bi_attrs[0] = bdb->bi_attrs[index_nattrs];
+                       index_nattrs--;
+                       rc = cursor->c_get( cursor, &key, &data, DB_FIRST );
                        if ( rc ) {
-                               bdb->bi_attrs = NULL;
                                return NOID;
                        }
                } else {
@@ -165,7 +229,7 @@ int bdb_tool_id2entry_get(
        Entry **e
 )
 {
-       int rc = bdb_id2entry( be, NULL, id, e );
+       int rc = bdb_id2entry( be, NULL, 0, id, e );
 
        if ( rc == DB_NOTFOUND && id == 0 ) {
                Entry *dummy = ch_calloc( 1, sizeof(Entry) );
@@ -185,15 +249,12 @@ Entry* bdb_tool_entry_get( BackendDB *be, ID id )
 {
        int rc;
        Entry *e = NULL;
-#ifndef BDB_HIER
        struct berval bv;
-#endif
 
        assert( be != NULL );
        assert( slapMode & SLAP_TOOL_MODE );
        assert( data.data != NULL );
 
-#ifndef BDB_HIER
        DBT2bv( &data, &bv );
 
 #ifdef SLAP_ZONE_ALLOC
@@ -206,8 +267,8 @@ Entry* bdb_tool_entry_get( BackendDB *be, ID id )
        if( rc == LDAP_SUCCESS ) {
                e->e_id = id;
        }
-#else
-       {
+#ifdef BDB_HIER
+       if ( slapMode & SLAP_TOOL_READONLY ) {
                EntryInfo *ei = NULL;
                Operation op = {0};
                Opheader ohdr = {0};
@@ -217,9 +278,15 @@ Entry* bdb_tool_entry_get( BackendDB *be, ID id )
                op.o_tmpmemctx = NULL;
                op.o_tmpmfuncs = &ch_mfuncs;
 
-               rc = bdb_cache_find_id( &op, NULL, id, &ei, 0, 0, NULL );
-               if ( rc == LDAP_SUCCESS )
-                       e = ei->bei_e;
+               rc = bdb_cache_find_parent( &op, NULL, cursor->locker, id, &ei );
+               if ( rc == LDAP_SUCCESS ) {
+                       bdb_cache_entryinfo_unlock( ei );
+                       e->e_private = ei;
+                       ei->bei_e = e;
+                       bdb_fix_dn( e, 0 );
+                       ei->bei_e = NULL;
+                       e->e_private = NULL;
+               }
        }
 #endif
        return e;
@@ -317,6 +384,53 @@ static int bdb_tool_next_id(
        return rc;
 }
 
+static int
+bdb_tool_index_add(
+       Operation *op,
+       DB_TXN *txn,
+       Entry *e )
+{
+       struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
+
+       if ( slapMode & SLAP_TOOL_QUICK ) {
+               IndexRec *ir;
+               int i, rc;
+               Attribute *a;
+               
+               ir = bdb_tool_index_rec;
+               memset(ir, 0, bdb->bi_nattrs * sizeof( IndexRec ));
+
+               for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+                       rc = bdb_index_recset( bdb, a, a->a_desc->ad_type, 
+                               &a->a_desc->ad_tags, ir );
+                       if ( rc )
+                               return rc;
+               }
+               bdb_tool_ix_id = e->e_id;
+               bdb_tool_ix_op = op;
+               ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
+               for ( i=1; i<slap_tool_thread_max; i++ )
+                       bdb_tool_index_threads[i] = LDAP_BUSY;
+               ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond );
+               ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
+               rc = bdb_index_recrun( op, bdb, ir, e->e_id, 0 );
+               if ( rc )
+                       return rc;
+               for ( i=1; i<slap_tool_thread_max; i++ ) {
+                       if ( bdb_tool_index_threads[i] == LDAP_BUSY ) {
+                               ldap_pvt_thread_yield();
+                               i--;
+                               continue;
+                       }
+                       if ( bdb_tool_index_threads[i] )
+                               return bdb_tool_index_threads[i];
+               }
+               return 0;
+       } else {
+               return bdb_index_entry_add( op, txn, e );
+       }
+}
+
 ID bdb_tool_entry_put(
        BackendDB *be,
        Entry *e,
@@ -376,7 +490,7 @@ ID bdb_tool_entry_put(
        }
 
        if ( !bdb->bi_linear_index )
-               rc = bdb_index_entry_add( &op, tid, e );
+               rc = bdb_tool_index_add( &op, tid, e );
        if( rc != 0 ) {
                snprintf( text->bv_val, text->bv_len,
                                "index_entry_add failed: %s (%d)",
@@ -441,10 +555,9 @@ int bdb_tool_entry_reindex(
        }
 
        /* Get the first attribute to index */
-       if (bi->bi_linear_index && !index_attrs && bi->bi_attrs != &index_dummy) {
-               index_attrs = bi->bi_attrs;
-               bi->bi_attrs = &index_dummy;
-               index_dummy.avl_data = avl_delete(&index_attrs, NULL, bdb_reindex_cmp);
+       if (bi->bi_linear_index && !index_nattrs) {
+               index_nattrs = bi->bi_nattrs - 1;
+               bi->bi_nattrs = 1;
        }
 
        e = bdb_tool_entry_get( be, id );
@@ -484,7 +597,7 @@ int bdb_tool_entry_reindex(
        op.o_tmpmemctx = NULL;
        op.o_tmpmfuncs = &ch_mfuncs;
 
-       rc = bdb_index_entry_add( &op, tid, e );
+       rc = bdb_tool_index_add( &op, tid, e );
 
 done:
        if( rc == 0 ) {
@@ -626,3 +739,311 @@ done:
 
        return e->e_id;
 }
+
+#ifdef BDB_TOOL_IDL_CACHING
+static int
+bdb_tool_idl_cmp( const void *v1, const void *v2 )
+{
+       const bdb_tool_idl_cache *c1 = v1, *c2 = v2;
+       int rc;
+
+       if (( rc = c1->kstr.bv_len - c2->kstr.bv_len )) return rc;
+       return memcmp( c1->kstr.bv_val, c2->kstr.bv_val, c1->kstr.bv_len );
+}
+
+static int
+bdb_tool_idl_flush_one( void *v1, void *arg )
+{
+       bdb_tool_idl_cache *ic = v1;
+       DB *db = arg;
+       struct bdb_info *bdb = bdb_tool_info;
+       bdb_tool_idl_cache_entry *ice;
+       DBC *curs;
+       DBT key, data;
+       int i, rc;
+       ID id, nid;
+
+       /* Freshly allocated, ignore it */
+       if ( !ic->head && ic->count <= BDB_IDL_DB_SIZE ) {
+               return 0;
+       }
+
+       rc = db->cursor( db, NULL, &curs, 0 );
+       if ( rc )
+               return -1;
+
+       DBTzero( &key );
+       DBTzero( &data );
+
+       bv2DBT( &ic->kstr, &key );
+
+       data.size = data.ulen = sizeof( ID );
+       data.flags = DB_DBT_USERMEM;
+       data.data = &nid;
+
+       rc = curs->c_get( curs, &key, &data, DB_SET );
+       /* If key already exists and we're writing a range... */
+       if ( rc == 0 && ic->count > BDB_IDL_DB_SIZE ) {
+               /* If it's not currently a range, must delete old info */
+               if ( nid ) {
+                       /* Skip lo */
+                       while ( curs->c_get( curs, &key, &data, DB_NEXT_DUP ) == 0 )
+                               curs->c_del( curs, 0 );
+
+                       nid = 0;
+                       /* Store range marker */
+                       curs->c_put( curs, &key, &data, DB_KEYFIRST );
+               } else {
+                       
+                       /* Skip lo */
+                       rc = curs->c_get( curs, &key, &data, DB_NEXT_DUP );
+
+                       /* Get hi */
+                       rc = curs->c_get( curs, &key, &data, DB_NEXT_DUP );
+
+                       /* Delete hi */
+                       curs->c_del( curs, 0 );
+               }
+               BDB_ID2DISK( ic->last, &nid );
+               curs->c_put( curs, &key, &data, DB_KEYLAST );
+               rc = 0;
+       } else if ( rc && rc != DB_NOTFOUND ) {
+               rc = -1;
+       } else if ( ic->count > BDB_IDL_DB_SIZE ) {
+               /* range, didn't exist before */
+               nid = 0;
+               rc = curs->c_put( curs, &key, &data, DB_KEYLAST );
+               if ( rc == 0 ) {
+                       BDB_ID2DISK( ic->first, &nid );
+                       rc = curs->c_put( curs, &key, &data, DB_KEYLAST );
+                       if ( rc == 0 ) {
+                               BDB_ID2DISK( ic->last, &nid );
+                               rc = curs->c_put( curs, &key, &data, DB_KEYLAST );
+                       }
+               }
+               if ( rc ) {
+                       rc = -1;
+               }
+       } else {
+               int n;
+
+               /* Just a normal write */
+               rc = 0;
+               for ( ice = ic->head, n=0; ice; ice = ice->next, n++ ) {
+                       int end;
+                       if ( ice->next ) {
+                               end = IDBLOCK;
+                       } else {
+                               end = ic->count & (IDBLOCK-1);
+                               if ( !end )
+                                       end = IDBLOCK;
+                       }
+                       for ( i=0; i<end; i++ ) {
+                               if ( !ice->ids[i] ) continue;
+                               BDB_ID2DISK( ice->ids[i], &nid );
+                               rc = curs->c_put( curs, &key, &data, DB_NODUPDATA );
+                               if ( rc ) {
+                                       if ( rc == DB_KEYEXIST ) {
+                                               rc = 0;
+                                               continue;
+                                       }
+                                       rc = -1;
+                                       break;
+                               }
+                       }
+                       if ( rc ) {
+                               rc = -1;
+                               break;
+                       }
+               }
+               if ( ic->head ) {
+                       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+                       ic->tail->next = bdb_tool_idl_free_list;
+                       bdb_tool_idl_free_list = ic->head;
+                       bdb->bi_idl_cache_size -= n;
+                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+               }
+       }
+       if ( ic != db->app_private ) {
+               ch_free( ic );
+       } else {
+               ic->head = ic->tail = NULL;
+       }
+       curs->c_close( curs );
+       return rc;
+}
+
+static int
+bdb_tool_idl_flush_db( DB *db, bdb_tool_idl_cache *ic )
+{
+       Avlnode *root = db->app_private;
+       int rc;
+
+       db->app_private = ic;
+       rc = avl_apply( root, bdb_tool_idl_flush_one, db, -1, AVL_INORDER );
+       avl_free( root, NULL );
+       db->app_private = NULL;
+       if ( rc != -1 )
+               rc = 0;
+       return rc;
+}
+
+static int
+bdb_tool_idl_flush( BackendDB *be )
+{
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+       DB *db;
+       Avlnode *root;
+       int i, rc = 0;
+
+       for ( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) {
+               db = bdb->bi_databases[i]->bdi_db;
+               if ( !db->app_private ) continue;
+               rc = bdb_tool_idl_flush_db( db, NULL );
+               if ( rc )
+                       break;
+       }
+       if ( !rc ) {
+               bdb->bi_idl_cache_size = 0;
+       }
+       return rc;
+}
+
+int bdb_tool_idl_add(
+       BackendDB *be,
+       DB *db,
+       DB_TXN *txn,
+       DBT *key,
+       ID id )
+{
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+       bdb_tool_idl_cache *ic, itmp;
+       bdb_tool_idl_cache_entry *ice;
+       int rc;
+
+       if ( !bdb->bi_idl_cache_max_size )
+               return bdb_idl_insert_key( be, db, txn, key, id );
+
+       DBT2bv( key, &itmp.kstr );
+
+       ic = avl_find( (Avlnode *)db->app_private, &itmp, bdb_tool_idl_cmp );
+
+       /* No entry yet, create one */
+       if ( !ic ) {
+               DBC *curs;
+               DBT data;
+               ID nid;
+               int rc;
+
+               ic = ch_malloc( sizeof( bdb_tool_idl_cache ) + itmp.kstr.bv_len );
+               ic->kstr.bv_len = itmp.kstr.bv_len;
+               ic->kstr.bv_val = (char *)(ic+1);
+               AC_MEMCPY( ic->kstr.bv_val, itmp.kstr.bv_val, ic->kstr.bv_len );
+               ic->head = ic->tail = NULL;
+               ic->last = 0;
+               ic->count = 0;
+               avl_insert( (Avlnode **)&db->app_private, ic, bdb_tool_idl_cmp,
+                       avl_dup_error );
+
+               /* load existing key count here */
+               rc = db->cursor( db, NULL, &curs, 0 );
+               if ( rc ) return rc;
+
+               data.ulen = sizeof( ID );
+               data.flags = DB_DBT_USERMEM;
+               data.data = &nid;
+               rc = curs->c_get( curs, key, &data, DB_SET );
+               if ( rc == 0 ) {
+                       if ( nid == 0 ) {
+                               ic->count = BDB_IDL_DB_SIZE+1;
+                       } else {
+                               db_recno_t count;
+
+                               curs->c_count( curs, &count, 0 );
+                               ic->count = count;
+                               BDB_DISK2ID( &nid, &ic->first );
+                       }
+               }
+               curs->c_close( curs );
+       }
+       /* are we a range already? */
+       if ( ic->count > BDB_IDL_DB_SIZE ) {
+               ic->last = id;
+               return 0;
+       /* Are we at the limit, and converting to a range? */
+       } else if ( ic->count == BDB_IDL_DB_SIZE ) {
+               int n;
+               for ( ice = ic->head, n=0; ice; ice = ice->next, n++ )
+                       /* counting */ ;
+               if ( n ) {
+                       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+                       ic->tail->next = bdb_tool_idl_free_list;
+                       bdb_tool_idl_free_list = ic->head;
+                       bdb->bi_idl_cache_size -= n;
+                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+               }
+               ic->head = ic->tail = NULL;
+               ic->last = id;
+               ic->count++;
+               return 0;
+       }
+       /* No free block, create that too */
+       if ( !ic->tail || ( ic->count & (IDBLOCK-1)) == 0) {
+               ice = NULL;
+               ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+               if ( bdb->bi_idl_cache_size >= bdb->bi_idl_cache_max_size ) {
+                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+                       rc = bdb_tool_idl_flush_db( db, ic );
+                       if ( rc )
+                               return rc;
+                       avl_insert( (Avlnode **)&db->app_private, ic, bdb_tool_idl_cmp,
+                               avl_dup_error );
+                       ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+               }
+               bdb->bi_idl_cache_size++;
+               if ( bdb_tool_idl_free_list ) {
+                       ice = bdb_tool_idl_free_list;
+                       bdb_tool_idl_free_list = ice->next;
+               }
+               ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+               if ( !ice ) {
+                       ice = ch_malloc( sizeof( bdb_tool_idl_cache_entry ));
+               }
+               memset( ice, 0, sizeof( *ice ));
+               if ( !ic->head ) {
+                       ic->head = ice;
+               } else {
+                       ic->tail->next = ice;
+               }
+               ic->tail = ice;
+               if ( !ic->count )
+                       ic->first = id;
+       }
+       ice = ic->tail;
+       ice->ids[ ic->count & (IDBLOCK-1) ] = id;
+       ic->count++;
+
+       return 0;
+}
+#endif
+
+static void *
+bdb_tool_index_task( void *ctx, void *ptr )
+{
+       int base = *(int *)ptr;
+
+       free( ptr );
+       while ( 1 ) {
+               ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
+               ldap_pvt_thread_cond_wait( &bdb_tool_index_cond,
+                       &bdb_tool_index_mutex );
+               ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
+               if ( slapd_shutdown )
+                       break;
+
+               bdb_tool_index_threads[base] = bdb_index_recrun( bdb_tool_ix_op,
+                       bdb_tool_info, bdb_tool_index_rec, bdb_tool_ix_id, base );
+       }
+
+       return NULL;
+}
index 93f5cff445748f5130a6be828a4d81bb21e9f6da..a34dc44e0f9d89955815a804f5233062cf546ae4 100644 (file)
@@ -503,11 +503,15 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
                } else {
                        BER_BVZERO( &lc->lc_cred );
                        BER_BVZERO( &lc->lc_bound_ndn );
+#if 0
+                       /* FIXME: if we set lc_bound_ndn = o_ndn
+                        * we end up with a bind with DN but no password! */
                        if ( !BER_BVISEMPTY( &op->o_ndn )
                                && SLAP_IS_AUTHZ_BACKEND( op ) )
                        {
                                ber_dupbv( &lc->lc_bound_ndn, &op->o_ndn );
                        }
+#endif
                }
 
 #ifdef HAVE_TLS
index 2cba84c833adb8002556bd4ebf184bf32dcebb93..8f702c85b9d18882ef57ad434631d54e667d2f17 100644 (file)
@@ -576,7 +576,7 @@ ldap_chain_response( Operation *op, SlapReply *rs )
 
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
        if ( rc != LDAP_SUCCESS || sc2.sc_private == LDAP_CH_ERR ) {
-               if ( rs->sr_err == LDAP_CANNOT_CHAIN ) {
+               if ( rs->sr_err == LDAP_X_CANNOT_CHAIN ) {
                        goto cannot_chain;
                }
 
@@ -584,7 +584,8 @@ ldap_chain_response( Operation *op, SlapReply *rs )
                case LDAP_CHAINING_REQUIRED:
 cannot_chain:;
                        op->o_callback = NULL;
-                       send_ldap_error( op, rs, LDAP_CANNOT_CHAIN, "operation cannot be completed without chaining" );
+                       send_ldap_error( op, rs, LDAP_X_CANNOT_CHAIN,
+                               "operation cannot be completed without chaining" );
                        break;
 
                default:
index 92ebf50034bac7f35d26c424b4f159b70775cd5c..7218af2e84f322b3d14de82d4f66aff25a1afde3 100644 (file)
@@ -135,6 +135,12 @@ retry:
                                        (char **)&rs->sr_matched,
                                        (char **)&rs->sr_text,
                                        NULL, NULL, 0 );
+                       if ( rs->sr_matched && rs->sr_matched[ 0 ] == '\0' ) {
+                               free( (char *)rs->sr_matched );
+                       }
+                       if ( rs->sr_text && rs->sr_text[ 0 ] == '\0' ) {
+                               free( (char *)rs->sr_text );
+                       }
                        if ( rc == LDAP_SUCCESS ) {
                                if ( rs->sr_err == LDAP_SUCCESS ) {
                                        struct berval   newpw;
@@ -165,17 +171,19 @@ retry:
                        }
                }
                send_ldap_result( op, rs );
-               if ( rs->sr_matched ) {
-                       free( (char *)rs->sr_matched );
-               }
-               if ( rs->sr_text ) {
-                       free( (char *)rs->sr_text );
-               }
-               rs->sr_matched = NULL;
-               rs->sr_text = NULL;
                rc = -1;
        }
 
+       /* these have to be freed anyway... */
+       if ( rs->sr_matched ) {
+               free( (char *)rs->sr_matched );
+       }
+       if ( rs->sr_text ) {
+               free( (char *)rs->sr_text );
+       }
+       rs->sr_matched = NULL;
+       rs->sr_text = NULL;
+
        if ( lc != NULL ) {
                ldap_back_release_conn( op, rs, lc );
        }
index 45bc2e91528176b0d50b2b1efe8503bec151df06..8f33ae38f511d8363588aee81d5f87fba158e65e 100644 (file)
@@ -431,6 +431,7 @@ fail:;
 
                if ( dnPretty( NULL, &match, &pmatch, op->o_tmpmemctx ) == LDAP_SUCCESS ) {
                        rs->sr_matched = pmatch.bv_val;
+                       LDAP_FREE( match.bv_val );
 
                } else {
                        rs->sr_matched = match.bv_val;
index 413d292508e2145487552d3eba4d500217761a01..0f98eca3d0ffc46cbda6303507bee694cddb98ff 100644 (file)
 #include "back-ldbm.h"
 #include "proto-back-ldbm.h"
 
+static int
+ldbm_csn_cb(
+       Operation *op,
+       SlapReply *rs )
+{
+       op->o_callback = op->o_callback->sc_next;
+       slap_graduate_commit_csn( op );
+       return SLAP_CB_CONTINUE;
+}
+
 int
 ldbm_back_add(
     Operation  *op,
@@ -38,6 +48,7 @@ ldbm_back_add(
        AttributeDescription *entry = slap_schema.si_ad_entry;
        char textbuf[SLAP_TEXT_BUFLEN];
        size_t textlen = sizeof textbuf;
+       slap_callback cb = { NULL };
 #ifdef LDBM_SUBENTRIES
        int subentry;
 #endif
@@ -45,6 +56,12 @@ ldbm_back_add(
        Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n",
                op->o_req_dn.bv_val, 0, 0);
        
+       slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
+
+       cb.sc_cleanup = ldbm_csn_cb;
+       cb.sc_next = op->o_callback;
+       op->o_callback = &cb;
+
        rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
                get_manageDIT(op), &rs->sr_text, textbuf, textlen );
 
index 6db0d31dbf47be50e88496c1be6621d0850f28ff..f0274aa623a6b993b9dca3ff5992320a7a1bc9ef 100644 (file)
@@ -24,6 +24,7 @@
 #include "slap.h"
 #include "back-ldbm.h"
 #include "proto-back-ldbm.h"
+#include "lutil.h"
 
 int
 ldbm_back_delete(
@@ -44,6 +45,16 @@ ldbm_back_delete(
        /* grab giant lock for writing */
        ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
 
+       /* allocate CSN */
+       if ( !SLAP_SHADOW( op->o_bd )) {
+               struct berval csn;
+               char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
+
+               csn.bv_val = csnbuf;
+               csn.bv_len = sizeof(csnbuf);
+               slap_get_csn( op, &csn, 1 );
+       }
+
        /* get entry with writer lock */
        e = dn2entry_w( op->o_bd, &op->o_req_ndn, &matched );
 
@@ -64,16 +75,9 @@ ldbm_back_delete(
                                                        &op->o_req_dn, LDAP_SCOPE_DEFAULT );
                }
 
-               ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
-
                rs->sr_err = LDAP_REFERRAL;
-               send_ldap_result( op, rs );
-
-               if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
-               free( (char *)rs->sr_matched );
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-               return( -1 );
+               rs->sr_flags |= REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+               goto return_results;
        }
 
        /* check entry for "entry" acl */
@@ -83,10 +87,8 @@ ldbm_back_delete(
                        "<=- ldbm_back_delete: no write access to entry\n", 0,
                        0, 0 );
 
-               send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
-                       "no write access to entry" );
-
-               rc = LDAP_INSUFFICIENT_ACCESS;
+               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+               rs->sr_text = "no write access to entry";
                goto return_results;
        }
 
@@ -99,13 +101,8 @@ ldbm_back_delete(
                    0, 0 );
 
                rs->sr_err = LDAP_REFERRAL;
-               rs->sr_matched = e->e_name.bv_val;
-               send_ldap_result( op, rs );
-
-               if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-               rc = LDAP_REFERRAL;
+               rs->sr_matched = ch_strdup( e->e_name.bv_val );
+               rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
                goto return_results;
        }
 
@@ -113,8 +110,8 @@ ldbm_back_delete(
                Debug(LDAP_DEBUG_ARGS, "<=- ldbm_back_delete: non leaf %s\n",
                        op->o_req_dn.bv_val, 0, 0);
 
-               send_ldap_error( op, rs, LDAP_NOT_ALLOWED_ON_NONLEAF,
-                       "subordinate objects must be deleted first");
+               rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
+               rs->sr_text = "subordinate objects must be deleted first";
                goto return_results;
        }
 
@@ -126,8 +123,8 @@ ldbm_back_delete(
                                "<=- ldbm_back_delete: parent does not exist\n",
                                0, 0, 0);
 
-                       send_ldap_error( op, rs, LDAP_OTHER,
-                               "could not locate parent of entry" );
+                       rs->sr_err = LDAP_OTHER;
+                       rs->sr_text = "could not locate parent of entry";
                        goto return_results;
                }
 
@@ -139,8 +136,8 @@ ldbm_back_delete(
                                "<=- ldbm_back_delete: no access to parent\n", 0,
                                0, 0 );
 
-                       send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
-                               "no write access to parent" );
+                       rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+                       rs->sr_text = "no write access to parent";
                        goto return_results;
                }
 
@@ -161,8 +158,8 @@ ldbm_back_delete(
                                                "<=- ldbm_back_delete: no "
                                                "access to parent\n", 0, 0, 0 );
 
-                                       send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
-                                               "no write access to parent" );
+                                       rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+                                       rs->sr_text = "no write access to parent";
                                        goto return_results;
                                }
 
@@ -171,9 +168,7 @@ ldbm_back_delete(
                                        "<=- ldbm_back_delete: no parent & "
                                        "not root\n", 0, 0, 0);
 
-                               send_ldap_error( op, rs,
-                                       LDAP_INSUFFICIENT_ACCESS,
-                                       NULL );
+                               rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
                                goto return_results;
                        }
                }
@@ -185,8 +180,8 @@ ldbm_back_delete(
                        "<=- ldbm_back_delete: operations error %s\n",
                        op->o_req_dn.bv_val, 0, 0);
 
-               send_ldap_error( op, rs, LDAP_OTHER,
-                       "DN index delete failed" );
+               rs->sr_err = LDAP_OTHER;
+               rs->sr_text = "DN index delete failed";
                goto return_results;
        }
 
@@ -196,8 +191,8 @@ ldbm_back_delete(
                        "<=- ldbm_back_delete: operations error %s\n",
                        op->o_req_dn.bv_val, 0, 0);
 
-               send_ldap_error( op, rs, LDAP_OTHER,
-                       "entry delete failed" );
+               rs->sr_err = LDAP_OTHER;
+               rs->sr_text = "entry delete failed";
                goto return_results;
        }
 
@@ -205,19 +200,25 @@ ldbm_back_delete(
        (void) index_entry_del( op, e );
 
        rs->sr_err = LDAP_SUCCESS;
-       send_ldap_result( op, rs );
-       rc = LDAP_SUCCESS;
 
 return_results:;
+       rc = rs->sr_err;
+
        if( p != NULL ) {
                /* free parent and writer lock */
                cache_return_entry_w( &li->li_cache, p );
        }
 
-       /* free entry and writer lock */
-       cache_return_entry_w( &li->li_cache, e );
+       if ( e != NULL ) {
+               /* free entry and writer lock */
+               cache_return_entry_w( &li->li_cache, e );
+       }
 
        ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
 
+       send_ldap_result( op, rs );
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_graduate_commit_csn( op );
+
        return rc;
 }
index 2dd696919fbde91b3d885c344ca7d74151f6e7b6..1df17bd4f78bc72a4debe856fe395262c6577124 100644 (file)
@@ -241,6 +241,9 @@ ldbm_back_modify(
 
        Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0);
 
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_mods_opattrs( op, op->orm_modlist, 1 );
+
        /* grab giant lock for writing */
        ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
 
@@ -250,7 +253,7 @@ ldbm_back_modify(
        /* FIXME: dn2entry() should return non-glue entry */
        if (( e == NULL ) || ( !manageDSAit && e && is_entry_glue( e ))) {
                if ( matched != NULL ) {
-                       rs->sr_matched = ch_strdup( matched->e_dn );
+                       rs->sr_matched = ber_strdup_x( matched->e_dn, op->o_tmpmemctx );
                        rs->sr_ref = is_entry_referral( matched )
                                ? get_entry_referrals( op, matched )
                                : NULL;
@@ -260,16 +263,9 @@ ldbm_back_modify(
                                                &op->o_req_dn, LDAP_SCOPE_DEFAULT );
                }
 
-               ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
                rs->sr_err = LDAP_REFERRAL;
-               send_ldap_result( op, rs );
-
-               if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
-               free( (char *)rs->sr_matched );
-
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-               return rs->sr_err;
+               rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+               goto return_results;
        }
 
        if ( !manageDSAit && is_entry_referral( e ) )
@@ -282,47 +278,31 @@ ldbm_back_modify(
                    0, 0 );
 
                rs->sr_err = LDAP_REFERRAL;
-               rs->sr_matched = e->e_name.bv_val;
-               send_ldap_result( op, rs );
-
-               if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
-               rs->sr_ref = NULL;
-               rs->sr_matched = NULL;
-               goto error_return;
+               rs->sr_matched = ber_strdup_x( e->e_name.bv_val, op->o_tmpmemctx );
+               rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+               goto return_results;
        }
        
        /* Modify the entry */
        rs->sr_err = ldbm_modify_internal( op, op->oq_modify.rs_modlist, e,
                &rs->sr_text, textbuf, textlen );
 
-       if( rs->sr_err != LDAP_SUCCESS ) {
-               if( rs->sr_err != SLAPD_ABANDON ) {
-                       send_ldap_result( op, rs );
-               }
-
-               goto error_return;
-       }
-
        /* change the entry itself */
-       if ( id2entry_add( op->o_bd, e ) != 0 ) {
-               send_ldap_error( op, rs, LDAP_OTHER,
-                       "id2entry failure" );
-               rs->sr_err = LDAP_OTHER;
-               goto error_return;
+       if( rs->sr_err == LDAP_SUCCESS ) {
+               if ( id2entry_add( op->o_bd, e ) != 0 ) {
+                       rs->sr_err = LDAP_OTHER;
+                       rs->sr_text = "id2entry failure";
+               }
        }
 
-       rs->sr_text = NULL;
-       send_ldap_error( op, rs, LDAP_SUCCESS,
-               NULL );
-
+return_results:;
        cache_return_entry_w( &li->li_cache, e );
        ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
 
-       return LDAP_SUCCESS;
+       send_ldap_result( op, rs );
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_graduate_commit_csn( op );
 
-error_return:;
-       cache_return_entry_w( &li->li_cache, e );
-       ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
        rs->sr_text = NULL;
        return rs->sr_err;
 }
index e6dd8a78f90ee10ddf004983b9af2968269d0c02..10cf47802dcf7509db26e3bf0411ad09fad4801d 100644 (file)
@@ -767,6 +767,9 @@ static int ldif_back_add(Operation *op, SlapReply *rs) {
        int statres;
        char textbuf[SLAP_TEXT_BUFLEN];
 
+       slap_add_opattrs( op, &rs->sr_text, textbuf, sizeof( textbuf ),
+               op->o_bd->be_pcl_mutexp != NULL ? 1 : 0 );
+
        rs->sr_err = entry_schema_check(op, e, NULL, 0,
                &rs->sr_text, textbuf, sizeof( textbuf ) );
        if ( rs->sr_err != LDAP_SUCCESS ) goto send_res;
@@ -815,6 +818,8 @@ static int ldif_back_add(Operation *op, SlapReply *rs) {
 
 send_res:
        send_ldap_result(op, rs);
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_graduate_commit_csn( op );
        return 0;
 }
 
@@ -825,6 +830,10 @@ static int ldif_back_modify(Operation *op, SlapReply *rs) {
        Entry * entry = NULL;
        int spew_res;
 
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_mods_opattrs( op, op->orm_modlist,
+                       op->o_bd->be_pcl_mutexp != NULL ? 1 : 0 );
+
        ldap_pvt_thread_mutex_lock(&ni->li_mutex);
        dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path,
                &path);
@@ -853,6 +862,8 @@ static int ldif_back_modify(Operation *op, SlapReply *rs) {
        rs->sr_text = NULL;
        ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
        send_ldap_result(op, rs);
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_graduate_commit_csn( op );
        return 0;
 }
 
@@ -861,6 +872,15 @@ static int ldif_back_delete(Operation *op, SlapReply *rs) {
        struct berval path = BER_BVNULL;
        int res = 0;
 
+       if ( !SLAP_SHADOW( op->o_bd )) {
+               struct berval csn;
+               char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
+
+               csn.bv_val = csnbuf;
+               csn.bv_len = sizeof( csnbuf );
+               slap_get_csn( op, &csn, 1 );
+       }
+
        ldap_pvt_thread_mutex_lock(&ni->li_mutex);
        dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, &path);
 
@@ -885,6 +905,8 @@ static int ldif_back_delete(Operation *op, SlapReply *rs) {
        SLAP_FREE(path.bv_val);
        ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
        send_ldap_result(op, rs);
+       if ( !SLAP_SHADOW( op->o_bd ))
+               slap_graduate_commit_csn( op );
        return 0;
 }
 
index 2106a2d7e539964e82ac3aeed9a71f5c7f1930fb..3d59cf27d4965760eddca6d21e392c2f64fc3d4a 100644 (file)
@@ -80,7 +80,7 @@ meta_back_bind( Operation *op, SlapReply *rs )
                if ( META_BACK_DEFER_ROOTDN_BIND( mi ) ) {
                        rs->sr_err = LDAP_SUCCESS;
                        rs->sr_text = NULL;
-                       send_ldap_result( op, rs );
+                       /* frontend will return success */
                        return rs->sr_err;
                }
 
@@ -184,10 +184,8 @@ meta_back_bind( Operation *op, SlapReply *rs )
                        rs->sr_err = lerr;
                        candidates[ i ].sr_tag = META_NOT_CANDIDATE;
 
-                       if ( META_BACK_ONERR_STOP( mi ) ) {
-                               rc = rs->sr_err;
-                               break;
-                       }
+                       rc = rs->sr_err;
+                       break;
                }
        }
 
@@ -382,8 +380,7 @@ retry:;
                        if ( rs->sr_err == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) {
                                ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
                                if ( mc->mc_refcnt == 1 ) {
-                                       ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
-                                       msc->msc_ld = NULL;
+                                       meta_clear_one_candidate( msc );
                                        LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
 
                                        ( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
@@ -560,8 +557,7 @@ retry:;
                                }
 
                                if ( mc->mc_refcnt == 1 ) {
-                                       ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
-                                       msc->msc_ld = NULL;
+                                       meta_clear_one_candidate( msc );
                                        LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
 
                                        ( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
index 1254a26184ea52ec93a5dea7de2c2524309dc2d7..1cc8d83a87a38e46f49892ada7463ca6f6511ba1 100644 (file)
@@ -178,18 +178,18 @@ meta_clear_one_candidate(
        metasingleconn_t        *msc )
 {
        if ( msc->msc_ld ) {
-               ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
+               ldap_unbind_ext( msc->msc_ld, NULL, NULL );
                msc->msc_ld = NULL;
        }
 
        if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
-               ber_memfree( msc->msc_bound_ndn.bv_val );
+               ber_memfree_x( msc->msc_bound_ndn.bv_val, NULL );
                BER_BVZERO( &msc->msc_bound_ndn );
        }
 
        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_memfree_x( msc->msc_cred.bv_val, NULL );
                BER_BVZERO( &msc->msc_cred );
        }
 
index aeba81e1db57f6d06c14b486eb57b5dbba0c6259..078d2ee0c6f8669215d365a2b076e4be9a0a1215 100644 (file)
@@ -113,10 +113,21 @@ meta_back_db_config(
                int             rc;
                int             c;
                
-               if ( argc != 2 ) {
+               switch ( argc ) {
+               case 1:
                        fprintf( stderr,
-       "%s: line %d: missing address"
-       " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
+       "%s: line %d: missing URI "
+       "in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
+                               fname, lineno );
+                       return 1;
+
+               case 2:
+                       break;
+
+               default:
+                       fprintf( stderr,
+       "%s: line %d: too many args "
+       "in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
                                fname, lineno );
                        return 1;
                }
@@ -928,17 +939,17 @@ ldap_back_map_config(
                        fname, lineno );
                return 1;
        }
-       ber_str2bv( src, 0, 1, &mapping->src );
-       ber_str2bv( dst, 0, 1, &mapping->dst );
-       mapping[ 1 ].src = mapping->dst;
-       mapping[ 1 ].dst = mapping->src;
+       ber_str2bv( src, 0, 1, &mapping[ 0 ].src );
+       ber_str2bv( dst, 0, 1, &mapping[ 0 ].dst );
+       mapping[ 1 ].src = mapping[ 0 ].dst;
+       mapping[ 1 ].dst = mapping[ 0 ].src;
 
        /*
         * schema check
         */
        if ( is_oc ) {
                if ( src[ 0 ] != '\0' ) {
-                       if ( oc_bvfind( &mapping->src ) == NULL ) {
+                       if ( oc_bvfind( &mapping[ 0 ].src ) == NULL ) {
                                fprintf( stderr,
        "%s: line %d: warning, source objectClass '%s' "
        "should be defined in schema\n",
@@ -951,7 +962,7 @@ ldap_back_map_config(
                        }
                }
 
-               if ( oc_bvfind( &mapping->dst ) == NULL ) {
+               if ( oc_bvfind( &mapping[ 0 ].dst ) == NULL ) {
                        fprintf( stderr,
        "%s: line %d: warning, destination objectClass '%s' "
        "is not defined in schema\n",
@@ -963,7 +974,7 @@ ldap_back_map_config(
                AttributeDescription    *ad = NULL;
 
                if ( src[ 0 ] != '\0' ) {
-                       rc = slap_bv2ad( &mapping->src, &ad, &text );
+                       rc = slap_bv2ad( &mapping[ 0 ].src, &ad, &text );
                        if ( rc != LDAP_SUCCESS ) {
                                fprintf( stderr,
        "%s: line %d: warning, source attributeType '%s' "
@@ -978,7 +989,7 @@ ldap_back_map_config(
                                 * and add it here.
                                 */
 
-                               rc = slap_bv2undef_ad( &mapping->src,
+                               rc = slap_bv2undef_ad( &mapping[ 0 ].src,
                                                &ad, &text, SLAP_AD_PROXIED );
                                if ( rc != LDAP_SUCCESS ) {
                                        fprintf( stderr,
@@ -992,7 +1003,7 @@ ldap_back_map_config(
                        ad = NULL;
                }
 
-               rc = slap_bv2ad( &mapping->dst, &ad, &text );
+               rc = slap_bv2ad( &mapping[ 0 ].dst, &ad, &text );
                if ( rc != LDAP_SUCCESS ) {
                        fprintf( stderr,
        "%s: line %d: warning, destination attributeType '%s' "
@@ -1004,7 +1015,7 @@ ldap_back_map_config(
                         * and add it here.
                         */
 
-                       rc = slap_bv2undef_ad( &mapping->dst,
+                       rc = slap_bv2undef_ad( &mapping[ 0 ].dst,
                                        &ad, &text, SLAP_AD_PROXIED );
                        if ( rc != LDAP_SUCCESS ) {
                                fprintf( stderr,
@@ -1016,7 +1027,7 @@ ldap_back_map_config(
                }
        }
 
-       if ( (src[ 0 ] != '\0' && avl_find( map->map, (caddr_t)mapping, mapping_cmp ) != NULL)
+       if ( (src[ 0 ] != '\0' && avl_find( map->map, (caddr_t)&mapping[ 0 ], mapping_cmp ) != NULL)
                        || avl_find( map->remap, (caddr_t)&mapping[ 1 ], mapping_cmp ) != NULL)
        {
                fprintf( stderr,
@@ -1026,7 +1037,7 @@ ldap_back_map_config(
        }
 
        if ( src[ 0 ] != '\0' ) {
-               avl_insert( &map->map, (caddr_t)mapping,
+               avl_insert( &map->map, (caddr_t)&mapping[ 0 ],
                                        mapping_cmp, mapping_dup );
        }
        avl_insert( &map->remap, (caddr_t)&mapping[ 1 ],
@@ -1036,8 +1047,8 @@ ldap_back_map_config(
 
 error_return:;
        if ( mapping ) {
-               ch_free( mapping->src.bv_val );
-               ch_free( mapping->dst.bv_val );
+               ch_free( mapping[ 0 ].src.bv_val );
+               ch_free( mapping[ 0 ].dst.bv_val );
                ch_free( mapping );
        }
 
index 9254407e45f515370323ff6a1a3dc9683b57bf13..8c341899d7c416ef53aaa3d52e1784e6b5c8e817 100644 (file)
@@ -447,8 +447,7 @@ retry_lock:;
                        goto retry_lock;
                }
 
-               ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
-               msc->msc_ld = NULL;
+               meta_clear_one_candidate( msc );
                LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
 
                ( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
index 3f71a429f25882e9ca123a5474241d74e4404e5e..a978646f1f8c270f0c575220b177a2c09e1f2d95 100644 (file)
@@ -146,21 +146,7 @@ meta_back_conn_free(
        ntargets = mc->mc_conns[ 0 ].msc_info->mi_ntargets;
 
        for ( i = 0; i < ntargets; i++ ) {
-               metasingleconn_t        *msc = &mc->mc_conns[ i ];
-
-               if ( msc->msc_ld != NULL ) {
-                       ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
-               }
-
-               if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
-                       ber_memfree( msc->msc_bound_ndn.bv_val );
-               }
-
-               if ( !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 );
-               }
+               (void)meta_clear_one_candidate( &mc->mc_conns[ i ] );
        }
 
        ldap_pvt_thread_mutex_destroy( &mc->mc_mutex );
@@ -177,6 +163,17 @@ mapping_free(
        ch_free( mapping );
 }
 
+static void
+mapping_dst_free(
+       void            *v_mapping )
+{
+       struct ldapmapping *mapping = v_mapping;
+
+       if ( BER_BVISEMPTY( &mapping->dst ) ) {
+               mapping_free( &mapping[ -1 ] );
+       }
+}
+
 static void
 target_free(
        metatarget_t    *mt )
@@ -205,9 +202,9 @@ target_free(
        if ( mt->mt_rwmap.rwm_rw ) {
                rewrite_info_delete( &mt->mt_rwmap.rwm_rw );
        }
-       avl_free( mt->mt_rwmap.rwm_oc.remap, NULL );
+       avl_free( mt->mt_rwmap.rwm_oc.remap, mapping_dst_free );
        avl_free( mt->mt_rwmap.rwm_oc.map, mapping_free );
-       avl_free( mt->mt_rwmap.rwm_at.remap, NULL );
+       avl_free( mt->mt_rwmap.rwm_at.remap, mapping_dst_free );
        avl_free( mt->mt_rwmap.rwm_at.map, mapping_free );
 }
 
@@ -235,11 +232,13 @@ meta_back_db_destroy(
                 * Destroy the per-target stuff (assuming there's at
                 * least one ...)
                 */
-               for ( i = 0; i < mi->mi_ntargets; i++ ) {
-                       target_free( &mi->mi_targets[ i ] );
-               }
+               if ( mi->mi_targets != NULL ) {
+                       for ( i = 0; i < mi->mi_ntargets; i++ ) {
+                               target_free( &mi->mi_targets[ i ] );
+                       }
 
-               free( mi->mi_targets );
+                       free( mi->mi_targets );
+               }
 
                ldap_pvt_thread_mutex_lock( &mi->mi_cache.mutex );
                if ( mi->mi_cache.tree ) {
index 550c06ad134ec7f569df02b5dcd56ac525565c72..f655e9e3925af5454805e63788d47bbfc7a5ca25 100644 (file)
@@ -208,6 +208,7 @@ map_attr_value(
 
        ldap_back_map( &dc->target->mt_rwmap.rwm_at, &ad->ad_cname, mapped_attr, remap );
        if ( BER_BVISNULL( mapped_attr ) || BER_BVISEMPTY( mapped_attr ) ) {
+#if 0
                /*
                 * FIXME: are we sure we need to search oc_map if at_map fails?
                 */
@@ -215,6 +216,12 @@ map_attr_value(
                if ( BER_BVISNULL( mapped_attr ) || BER_BVISEMPTY( mapped_attr ) ) {
                        *mapped_attr = ad->ad_cname;
                }
+#endif
+               if ( dc->target->mt_rwmap.rwm_at.drop_missing ) {
+                       return -1;
+               }
+
+               *mapped_attr = ad->ad_cname;
        }
 
        if ( value == NULL ) {
@@ -271,13 +278,28 @@ ldap_back_int_filter_map_rewrite(
 {
        int             i;
        Filter          *p;
-       struct berval   atmp;
-       struct berval   vtmp;
+       struct berval   atmp,
+                       vtmp,
+                       *tmp;
+       static struct berval
+                       /* better than nothing... */
+                       ber_bvfalse = BER_BVC( "(!(objectClass=*))" ),
+                       ber_bvtf_false = BER_BVC( "(|)" ),
+                       /* better than nothing... */
+                       ber_bvtrue = BER_BVC( "(objectClass=*)" ),
+                       ber_bvtf_true = BER_BVC( "(&)" ),
+#if 0
+                       /* no longer needed; preserved for completeness */
+                       ber_bvundefined = BER_BVC( "(?=undefined)" ),
+#endif
+                       ber_bverror = BER_BVC( "(?=error)" ),
+                       ber_bvunknown = BER_BVC( "(?=unknown)" ),
+                       ber_bvnone = BER_BVC( "(?=none)" );
        ber_len_t       len;
 
        if ( f == NULL ) {
-               ber_str2bv( "No filter!", STRLENOF( "No filter!" ), 1, fstr );
-               return -1;
+               ber_dupbv( fstr, &ber_bvnone );
+               return LDAP_OTHER;
        }
 
        switch ( f->f_choice ) {
@@ -285,7 +307,7 @@ ldap_back_int_filter_map_rewrite(
                if ( map_attr_value( dc, f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, remap ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len
@@ -302,7 +324,7 @@ ldap_back_int_filter_map_rewrite(
                if ( map_attr_value( dc, f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, remap ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len
@@ -319,7 +341,7 @@ ldap_back_int_filter_map_rewrite(
                if ( map_attr_value( dc, f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, remap ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len
@@ -336,7 +358,7 @@ ldap_back_int_filter_map_rewrite(
                if ( map_attr_value( dc, f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, remap ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len
@@ -353,7 +375,7 @@ ldap_back_int_filter_map_rewrite(
                if ( map_attr_value( dc, f->f_sub_desc, &atmp,
                                        NULL, NULL, remap ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                /* cannot be a DN ... */
@@ -415,7 +437,7 @@ ldap_back_int_filter_map_rewrite(
                if ( map_attr_value( dc, f->f_desc, &atmp,
                                        NULL, NULL, remap ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                fstr->bv_len = atmp.bv_len + ( STRLENOF( "(=*)" ) );
@@ -436,11 +458,13 @@ ldap_back_int_filter_map_rewrite(
                        f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
 
                for ( p = f->f_list; p != NULL; p = p->f_next ) {
+                       int     rc;
+
                        len = fstr->bv_len;
 
-                       if ( ldap_back_int_filter_map_rewrite( dc, p, &vtmp, remap ) )
-                       {
-                               return -1;
+                       rc = ldap_back_int_filter_map_rewrite( dc, p, &vtmp, remap );
+                       if ( rc != LDAP_SUCCESS ) {
+                               return rc;
                        }
                        
                        fstr->bv_len += vtmp.bv_len;
@@ -459,7 +483,7 @@ ldap_back_int_filter_map_rewrite(
                        if ( map_attr_value( dc, f->f_mr_desc, &atmp,
                                                &f->f_mr_value, &vtmp, remap ) )
                        {
-                               return -1;
+                               goto computed;
                        }
 
                } else {
@@ -483,43 +507,38 @@ ldap_back_int_filter_map_rewrite(
                ber_memfree( vtmp.bv_val );
                break;
 
-       case SLAPD_FILTER_COMPUTED: {
-               struct berval   bv;
-
+       case SLAPD_FILTER_COMPUTED:
                switch ( f->f_result ) {
                case LDAP_COMPARE_FALSE:
+               /* FIXME: treat UNDEFINED as FALSE */
+               case SLAPD_COMPARE_UNDEFINED:
+computed:;
                        if ( dc->target->mt_flags & LDAP_BACK_F_SUPPORT_T_F ) {
-                               BER_BVSTR( &bv, "(|)" );
+                               tmp = &ber_bvtf_false;
                                break;
                        }
-                       /* fallthru */
-
-               /* FIXME: treat UNDEFINED as FALSE */
-               case SLAPD_COMPARE_UNDEFINED:
-                       /* better than nothing... */
-                       BER_BVSTR( &bv, "(!(objectClass=*))" );
+                       tmp = &ber_bvfalse;
                        break;
 
                case LDAP_COMPARE_TRUE:
                        if ( dc->target->mt_flags & LDAP_BACK_F_SUPPORT_T_F ) {
-                               BER_BVSTR( &bv, "(&)" );
+                               tmp = &ber_bvtf_true;
                                break;
                        }
 
-                       /* better than nothing... */
-                       BER_BVSTR( &bv, "(objectClass=*)" );
+                       tmp = &ber_bvtrue;
                        break;
 
                default:
-                       BER_BVSTR( &bv, "(?=error)" );
+                       tmp = &ber_bverror;
                        break;
                }
 
-               ber_dupbv( fstr, &bv );
-               break;
+               ber_dupbv( fstr, tmp );
+               break;
 
        default:
-               ber_str2bv( "(?=unknown)", STRLENOF( "(?=unknown)" ), 1, fstr );
+               ber_dupbv( fstr, &ber_bvunknown );
                break;
        }
 
@@ -655,6 +674,7 @@ ldap_back_referral_result_rewrite(
 
                                ludp->lud_dn = dn.bv_val;
                                newurl = ldap_url_desc2str( ludp );
+                               free( dn.bv_val );
                                if ( newurl == NULL ) {
                                        /* FIXME: leave attr untouched
                                         * even if ldap_url_desc2str failed...
index 544bf6e31f5f2c0a9ebe69d01b505cebadf15221..ccd058c2a407377ab97627005558249a652ce9f8 100644 (file)
@@ -926,15 +926,13 @@ meta_send_entry(
                ldap_back_map( &mi->mi_targets[ target ].mt_rwmap.rwm_at, 
                                &a, &mapped, BACKLDAP_REMAP );
                if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
+                       ( void )ber_scanf( &ber, "x" /* [W] */ );
                        continue;
                }
-               attr = ( Attribute * )ch_malloc( sizeof( Attribute ) );
+               attr = ( Attribute * )ch_calloc( 1, sizeof( Attribute ) );
                if ( attr == NULL ) {
                        continue;
                }
-               attr->a_flags = 0;
-               attr->a_next = 0;
-               attr->a_desc = NULL;
                if ( slap_bv2ad( &mapped, &attr->a_desc, &text )
                                != LDAP_SUCCESS) {
                        if ( slap_bv2undef_ad( &mapped, &attr->a_desc, &text,
@@ -990,7 +988,6 @@ meta_send_entry(
                pretty = attr->a_desc->ad_type->sat_syntax->ssyn_pretty;
 
                if ( !validate && !pretty ) {
-                       attr->a_nvals = NULL;
                        attr_free( attr );
                        goto next_attr;
                }
@@ -1029,16 +1026,18 @@ meta_send_entry(
                 * ACLs to the target directory server, and letting
                 * everything pass thru the ldap backend.
                 */
-               } else if ( attr->a_desc->ad_type->sat_syntax ==
+               } else {
+                       int     i;
+
+                       if ( attr->a_desc->ad_type->sat_syntax ==
                                slap_schema.si_syn_distinguishedName )
-               {
-                       ldap_dnattr_result_rewrite( &dc, attr->a_vals );
+                       {
+                               ldap_dnattr_result_rewrite( &dc, attr->a_vals );
 
-               } else if ( attr->a_desc == slap_schema.si_ad_ref ) {
-                       ldap_back_referral_result_rewrite( &dc, attr->a_vals );
+                       } else if ( attr->a_desc == slap_schema.si_ad_ref ) {
+                               ldap_back_referral_result_rewrite( &dc, attr->a_vals );
 
-               } else {
-                       int     i;
+                       }
 
                        for ( i = 0; i < last; i++ ) {
                                struct berval   pval;
index ed4bc96e30e82339f83857ef7ce7e01f22632b0c..a38bfa2b0729314d8209d6642b3894d2a8db9616 100644 (file)
@@ -48,6 +48,7 @@ meta_back_conn_destroy(
                conn->c_connid, 0, 0 );
        
        mc_curr.mc_conn = conn;
+       mc_curr.mc_local_ndn = conn->c_ndn;
        
        ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
        mc = avl_delete( &mi->mi_conntree, ( caddr_t )&mc_curr,
@@ -61,12 +62,6 @@ meta_back_conn_destroy(
                
                assert( mc->mc_refcnt == 0 );
 
-               for ( i = 0; i < mi->mi_ntargets; ++i ) {
-                       if ( mc->mc_conns[ i ].msc_ld != NULL ) {
-                               meta_clear_one_candidate( &mc->mc_conns[ i ] );
-                       }
-               }
-
                meta_back_conn_free( mc );
        }
 
index 50cb2b44c113d3468eaf4080204656f80aae87b2..a13056cdf682f0bf3569bc460d9b38eb18ad9995 100644 (file)
@@ -1855,6 +1855,14 @@ monitor_back_db_destroy(
                        if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_rdn ) ) {
                                ch_free( monitor_subsys[ i ]->mss_rdn.bv_val );
                        }
+
+                       if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_dn ) ) {
+                               ch_free( monitor_subsys[ i ]->mss_dn.bv_val );
+                       }
+
+                       if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_ndn ) ) {
+                               ch_free( monitor_subsys[ i ]->mss_ndn.bv_val );
+                       }
                }
 
                ch_free( monitor_subsys );
index 6a390891d463c49949a3e2c02537464bc85c34cf..ac9294906b2a4392ba9de5f2db480450535f5bed 100644 (file)
@@ -31,8 +31,8 @@
 #include "ldif.h"
 #include "back-monitor.h"
 
-static int
-monitor_subsys_log_destroy(
+static int 
+monitor_subsys_log_open( 
        BackendDB               *be,
        monitor_subsys_t        *ms );
 
@@ -47,34 +47,9 @@ monitor_subsys_log_modify(
  */
 ldap_pvt_thread_mutex_t                monitor_log_mutex;
 
-static struct {
-       int i;
-       struct berval s;
-       struct berval n;
-} int_2_level[] = {
-       { LDAP_DEBUG_TRACE,     BER_BVC("Trace"),       BER_BVNULL },
-       { LDAP_DEBUG_PACKETS,   BER_BVC("Packets"),     BER_BVNULL },
-       { LDAP_DEBUG_ARGS,      BER_BVC("Args"),        BER_BVNULL },
-       { LDAP_DEBUG_CONNS,     BER_BVC("Conns"),       BER_BVNULL },
-       { LDAP_DEBUG_BER,       BER_BVC("BER"), BER_BVNULL },
-       { LDAP_DEBUG_FILTER,    BER_BVC("Filter"),      BER_BVNULL },
-       { LDAP_DEBUG_CONFIG,    BER_BVC("Config"),      BER_BVNULL },   /* useless */
-       { LDAP_DEBUG_ACL,       BER_BVC("ACL"), BER_BVNULL },
-       { LDAP_DEBUG_STATS,     BER_BVC("Stats"),       BER_BVNULL },
-       { LDAP_DEBUG_STATS2,    BER_BVC("Stats2"),      BER_BVNULL },
-       { LDAP_DEBUG_SHELL,     BER_BVC("Shell"),       BER_BVNULL },
-       { LDAP_DEBUG_PARSE,     BER_BVC("Parse"),       BER_BVNULL },
-       { LDAP_DEBUG_CACHE,     BER_BVC("Cache"),       BER_BVNULL },
-       { LDAP_DEBUG_INDEX,     BER_BVC("Index"),       BER_BVNULL },
-       { 0,                    BER_BVNULL,     BER_BVNULL }
-};
-
-static int loglevel2int( struct berval *l );
-static int int2loglevel( int n );
-
-static int add_values( Entry *e, Modification *mod, int *newlevel );
-static int delete_values( Entry *e, Modification *mod, int *newlevel );
-static int replace_values( Entry *e, Modification *mod, int *newlevel );
+static int add_values( Operation *op, Entry *e, Modification *mod, int *newlevel );
+static int delete_values( Operation *op, Entry *e, Modification *mod, int *newlevel );
+static int replace_values( Operation *op, Entry *e, Modification *mod, int *newlevel );
 
 /*
  * initializes log subentry
@@ -84,68 +59,46 @@ monitor_subsys_log_init(
        BackendDB               *be,
        monitor_subsys_t        *ms )
 {
-       monitor_info_t  *mi;
-       Entry           *e;
-       int             i;
-
-       ms->mss_destroy = monitor_subsys_log_destroy;
+       ms->mss_open = monitor_subsys_log_open;
        ms->mss_modify = monitor_subsys_log_modify;
 
        ldap_pvt_thread_mutex_init( &monitor_log_mutex );
 
-       mi = ( monitor_info_t * )be->be_private;
-
-       if ( monitor_cache_get( mi, &ms->mss_ndn, 
-                               &e ) ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "monitor_subsys_log_init: "
-                       "unable to get entry \"%s\"\n",
-                       ms->mss_ndn.bv_val, 0, 0 );
-               return( -1 );
-       }
-
-       /* initialize the debug level(s) */
-       for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
-               if ( mi->mi_ad_managedInfo->ad_type->sat_equality->smr_normalize ) {
-                       int     rc;
-
-                       rc = (*mi->mi_ad_managedInfo->ad_type->sat_equality->smr_normalize)(
-                                       SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
-                                       mi->mi_ad_managedInfo->ad_type->sat_syntax,
-                                       mi->mi_ad_managedInfo->ad_type->sat_equality,
-                                       &int_2_level[ i ].s,
-                                       &int_2_level[ i ].n, NULL );
-                       if ( rc ) {
-                               return( -1 );
-                       }
-               }
-
-               if ( int_2_level[ i ].i & ldap_syslog ) {
-                       attr_merge_one( e, mi->mi_ad_managedInfo,
-                                       &int_2_level[ i ].s,
-                                       &int_2_level[ i ].n );
-               }
-       }
-
-       monitor_cache_release( mi, e );
-
        return( 0 );
 }
 
-static int
-monitor_subsys_log_destroy(
+/*
+ * opens log subentry
+ */
+int
+monitor_subsys_log_open(
        BackendDB               *be,
        monitor_subsys_t        *ms )
 {
-       int             i;
+       BerVarray       bva = NULL;
+
+       if ( loglevel2bvarray( ldap_syslog, &bva ) == 0 && bva != NULL ) {
+               monitor_info_t  *mi;
+               Entry           *e;
 
-       for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
-               if ( !BER_BVISNULL( &int_2_level[ i ].n ) ) {
-                       ch_free( int_2_level[ i ].n.bv_val );
+               mi = ( monitor_info_t * )be->be_private;
+
+               if ( monitor_cache_get( mi, &ms->mss_ndn, &e ) ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "monitor_subsys_log_init: "
+                               "unable to get entry \"%s\"\n",
+                               ms->mss_ndn.bv_val, 0, 0 );
+                       ber_bvarray_free( bva );
+                       return( -1 );
                }
+
+               attr_merge_normalize( e, mi->mi_ad_managedInfo, bva, NULL );
+               ber_bvarray_free( bva );
+
+               monitor_cache_release( mi, e );
        }
 
-       return 0;
+       return( 0 );
 }
 
 static int 
@@ -176,7 +129,8 @@ monitor_subsys_log_modify(
                 */
                if ( is_at_operational( mod->sm_desc->ad_type ) ) {
                        ( void ) attr_delete( &e->e_attrs, mod->sm_desc );
-                       rc = rs->sr_err = attr_merge( e, mod->sm_desc, mod->sm_values, mod->sm_nvalues );
+                       rc = rs->sr_err = attr_merge( e, mod->sm_desc,
+                                       mod->sm_values, mod->sm_nvalues );
                        if ( rc != LDAP_SUCCESS ) {
                                break;
                        }
@@ -192,15 +146,15 @@ monitor_subsys_log_modify(
 
                switch ( mod->sm_op ) {
                case LDAP_MOD_ADD:
-                       rc = add_values( e, mod, &newlevel );
+                       rc = add_values( op, e, mod, &newlevel );
                        break;
                        
                case LDAP_MOD_DELETE:
-                       rc = delete_values( e, mod, &newlevel );
+                       rc = delete_values( op, e, mod, &newlevel );
                        break;
 
                case LDAP_MOD_REPLACE:
-                       rc = replace_values( e, mod, &newlevel );
+                       rc = replace_values( op, e, mod, &newlevel );
                        break;
 
                default:
@@ -267,64 +221,31 @@ cleanup:;
 }
 
 static int
-loglevel2int( struct berval *l )
+check_constraints( Modification *mod, int *newlevel )
 {
        int             i;
-       
-       for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
-               if ( l->bv_len != int_2_level[ i ].s.bv_len ) {
-                       continue;
-               }
-
-               if ( strcasecmp( l->bv_val, int_2_level[ i ].s.bv_val ) == 0 ) {
-                       return int_2_level[ i ].i;
-               }
-       }
-
-       return 0;
-}
 
-static int
-int2loglevel( int n )
-{
-       int             i;
-       
-       for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
-               if ( int_2_level[ i ].i == n ) {
-                       return i;
-               }
+       if ( mod->sm_nvalues != NULL ) {
+               ber_bvarray_free( mod->sm_nvalues );
+               mod->sm_nvalues = NULL;
        }
 
-       return -1;
-}
-
-static int
-check_constraints( Modification *mod, int *newlevel )
-{
-       int             i;
-
-       for ( i = 0; mod->sm_values && !BER_BVISNULL( &mod->sm_values[ i ] ); i++ ) {
+       for ( i = 0; !BER_BVISNULL( &mod->sm_values[ i ] ); i++ ) {
                int             l;
-               
-               l = loglevel2int( &mod->sm_values[ i ] );
-               if ( !l ) {
+               struct berval   bv;
+
+               if ( str2loglevel( mod->sm_values[ i ].bv_val, &l ) ) {
                        return LDAP_CONSTRAINT_VIOLATION;
                }
 
-               if ( ( l = int2loglevel( l ) ) == -1 ) {
-                       return LDAP_OTHER;
+               if ( loglevel2bv( l, &bv ) ) {
+                       return LDAP_CONSTRAINT_VIOLATION;
                }
-
-               assert( int_2_level[ l ].s.bv_len
-                               == mod->sm_values[ i ].bv_len );
+               
+               assert( bv.bv_len == mod->sm_values[ i ].bv_len );
                
                AC_MEMCPY( mod->sm_values[ i ].bv_val,
-                               int_2_level[ l ].s.bv_val,
-                               int_2_level[ l ].s.bv_len );
-
-               AC_MEMCPY( mod->sm_nvalues[ i ].bv_val,
-                               int_2_level[ l ].n.bv_val,
-                               int_2_level[ l ].n.bv_len );
+                               bv.bv_val, bv.bv_len );
 
                *newlevel |= l;
        }
@@ -333,12 +254,14 @@ check_constraints( Modification *mod, int *newlevel )
 }      
 
 static int 
-add_values( Entry *e, Modification *mod, int *newlevel )
+add_values( Operation *op, Entry *e, Modification *mod, int *newlevel )
 {
        Attribute       *a;
        int             i, rc;
        MatchingRule    *mr = mod->sm_desc->ad_type->sat_equality;
 
+       assert( mod->sm_values != NULL );
+
        rc = check_constraints( mod, newlevel );
        if ( rc != LDAP_SUCCESS ) {
                return rc;
@@ -360,7 +283,8 @@ add_values( Entry *e, Modification *mod, int *newlevel )
 
                        rc = asserted_value_validate_normalize(
                                mod->sm_desc, mr, SLAP_MR_EQUALITY,
-                               &mod->sm_values[ i ], &asserted, &text, NULL );
+                               &mod->sm_values[ i ], &asserted, &text,
+                               op->o_tmpmemctx );
 
                        if ( rc != LDAP_SUCCESS ) {
                                return rc;
@@ -369,7 +293,7 @@ add_values( Entry *e, Modification *mod, int *newlevel )
                        for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) {
                                int match;
                                int rc = value_match( &match, mod->sm_desc, mr,
-                                       0, &a->a_vals[ j ], &asserted, &text );
+                                       0, &a->a_nvals[ j ], &asserted, &text );
 
                                if ( rc == LDAP_SUCCESS && match == 0 ) {
                                        free( asserted.bv_val );
@@ -382,9 +306,9 @@ add_values( Entry *e, Modification *mod, int *newlevel )
        }
 
        /* no - add them */
-       rc = attr_merge( e, mod->sm_desc, mod->sm_values, mod->sm_nvalues );
+       rc = attr_merge_normalize( e, mod->sm_desc, mod->sm_values,
+               op->o_tmpmemctx );
        if ( rc != LDAP_SUCCESS ) {
-               /* this should return result of attr_mergeit */
                return rc;
        }
 
@@ -392,25 +316,19 @@ add_values( Entry *e, Modification *mod, int *newlevel )
 }
 
 static int
-delete_values( Entry *e, Modification *mod, int *newlevel )
+delete_values( Operation *op, Entry *e, Modification *mod, int *newlevel )
 {
        int             i, j, k, found, rc, nl = 0;
        Attribute       *a;
        MatchingRule    *mr = mod->sm_desc->ad_type->sat_equality;
 
-       rc = check_constraints( mod, &nl );
-       if ( rc != LDAP_SUCCESS ) {
-               return rc;
-       }
-
-       *newlevel &= ~nl;
-
        /* delete the entire attribute */
        if ( mod->sm_values == NULL ) {
                int rc = attr_delete( &e->e_attrs, mod->sm_desc );
 
                if ( rc ) {
                        rc = LDAP_NO_SUCH_ATTRIBUTE;
+
                } else {
                        *newlevel = 0;
                        rc = LDAP_SUCCESS;
@@ -418,6 +336,13 @@ delete_values( Entry *e, Modification *mod, int *newlevel )
                return rc;
        }
 
+       rc = check_constraints( mod, &nl );
+       if ( rc != LDAP_SUCCESS ) {
+               return rc;
+       }
+
+       *newlevel &= ~nl;
+
        if ( mr == NULL || !mr->smr_match ) {
                /* disallow specific attributes from being deleted if
                 * no equality rule */
@@ -438,7 +363,8 @@ delete_values( Entry *e, Modification *mod, int *newlevel )
 
                rc = asserted_value_validate_normalize(
                                mod->sm_desc, mr, SLAP_MR_EQUALITY,
-                               &mod->sm_values[ i ], &asserted, &text, NULL );
+                               &mod->sm_values[ i ], &asserted, &text,
+                               op->o_tmpmemctx );
 
                if( rc != LDAP_SUCCESS ) return rc;
 
@@ -446,8 +372,7 @@ delete_values( Entry *e, Modification *mod, int *newlevel )
                for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) {
                        int match;
                        int rc = value_match( &match, mod->sm_desc, mr,
-                               0,
-                               &a->a_vals[ j ], &asserted, &text );
+                               0, &a->a_nvals[ j ], &asserted, &text );
 
                        if( rc == LDAP_SUCCESS && match != 0 ) {
                                continue;
@@ -457,6 +382,14 @@ delete_values( Entry *e, Modification *mod, int *newlevel )
                        found = 1;
 
                        /* delete it */
+                       if ( a->a_nvals != a->a_vals ) {
+                               free( a->a_nvals[ j ].bv_val );
+                               for ( k = j + 1; !BER_BVISNULL( &a->a_nvals[ k ] ); k++ ) {
+                                       a->a_nvals[ k - 1 ] = a->a_nvals[ k ];
+                               }
+                               BER_BVZERO( &a->a_nvals[ k - 1 ] );
+                       }
+
                        free( a->a_vals[ j ].bv_val );
                        for ( k = j + 1; !BER_BVISNULL( &a->a_vals[ k ] ); k++ ) {
                                a->a_vals[ k - 1 ] = a->a_vals[ k ];
@@ -488,14 +421,16 @@ delete_values( Entry *e, Modification *mod, int *newlevel )
 }
 
 static int
-replace_values( Entry *e, Modification *mod, int *newlevel )
+replace_values( Operation *op, Entry *e, Modification *mod, int *newlevel )
 {
        int rc;
 
-       *newlevel = 0;
-       rc = check_constraints( mod, newlevel );
-       if ( rc != LDAP_SUCCESS ) {
-               return rc;
+       if ( mod->sm_values != NULL ) {
+               *newlevel = 0;
+               rc = check_constraints( mod, newlevel );
+               if ( rc != LDAP_SUCCESS ) {
+                       return rc;
+               }
        }
 
        rc = attr_delete( &e->e_attrs, mod->sm_desc );
@@ -505,7 +440,8 @@ replace_values( Entry *e, Modification *mod, int *newlevel )
        }
 
        if ( mod->sm_values != NULL ) {
-               rc = attr_merge( e, mod->sm_desc, mod->sm_values, mod->sm_nvalues );
+               rc = attr_merge_normalize( e, mod->sm_desc, mod->sm_values,
+                               op->o_tmpmemctx );
                if ( rc != LDAP_SUCCESS ) {
                        return rc;
                }
index eafeb6e063f6611815e5f4053d3f0d90f144f540..728975360cf8de4e0f67bf04ba0601d8315b8f79 100644 (file)
@@ -69,6 +69,9 @@ monitor_back_modify( Operation *op, SlapReply *rs )
                rc = LDAP_INSUFFICIENT_ACCESS;
 
        } else {
+               assert( !SLAP_SHADOW( op->o_bd ) );
+               slap_mods_opattrs( op, op->orm_modlist, 0 );
+
                rc = monitor_entry_modify( op, rs, e );
        }
 
index 0edea5d0792aa5967a8535326d145f3be5dafe51..a0e53714256c89ec8acc51eaa2abf14d09eee1e9 100644 (file)
 #include "lutil.h"
 #include "back-monitor.h"
 
+static int
+monitor_subsys_rww_destroy(
+       BackendDB               *be,
+       monitor_subsys_t        *ms );
+
 static int
 monitor_subsys_rww_update(
        Operation               *op,
@@ -41,7 +46,7 @@ enum {
        MONITOR_RWW_LAST
 };
 
-struct monitor_rww_t {
+static struct monitor_rww_t {
        struct berval   rdn;
        struct berval   nrdn;
 } monitor_rww[] = {
@@ -53,8 +58,7 @@ struct monitor_rww_t {
 int
 monitor_subsys_rww_init(
        BackendDB               *be,
-       monitor_subsys_t        *ms
-)
+       monitor_subsys_t        *ms )
 {
        monitor_info_t  *mi;
        
@@ -64,6 +68,7 @@ monitor_subsys_rww_init(
 
        assert( be != NULL );
 
+       ms->mss_destroy = monitor_subsys_rww_destroy;
        ms->mss_update = monitor_subsys_rww_update;
 
        mi = ( monitor_info_t * )be->be_private;
@@ -147,6 +152,20 @@ monitor_subsys_rww_init(
        return( 0 );
 }
 
+static int
+monitor_subsys_rww_destroy(
+       BackendDB               *be,
+       monitor_subsys_t        *ms )
+{
+       int             i;
+
+       for ( i = 0; i < MONITOR_RWW_LAST; i++ ) {
+               ber_memfree_x( monitor_rww[ i ].nrdn.bv_val, NULL );
+       }
+
+       return 0;
+}
+
 static int
 monitor_subsys_rww_update(
        Operation               *op,
index 548bfd835eb809bf2618ca3b471f5b0864c332e5..6656b774f311965baa79305f2064152ba84eb2e9 100644 (file)
@@ -936,9 +936,11 @@ backsql_add( Operation *op, SlapReply *rs )
         */
        if ( op->o_sync ) {
                char            buf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
-               struct berval   csn = BER_BVNULL;
+               struct berval   csn;
 
-               slap_get_csn( op, buf, sizeof( buf ), &csn, 1 );
+               csn.bv_val = buf;
+               csn.bv_len = sizeof( buf );
+               slap_get_csn( op, &csn, 1 );
 
                rs->sr_err = LDAP_SUCCESS;
                send_ldap_result( op, rs );
index 306e557d02fd145492529e130d883861027c9f4f..a6aca06c96eee281873fb0f68bc3e6c1693b9dc3 100644 (file)
@@ -438,6 +438,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
 
        oc = backsql_id2oc( bi, e_id.eid_oc_id );
        rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id, mod );
+       slap_graduate_commit_csn( op );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                e = &r;
                goto done;
index 6edde629ca61613ace4f92c219973a02bc32759c..1423e2156a88cf1d331527d98a621fd7996a9c9f 100644 (file)
@@ -91,7 +91,9 @@ backsql_operational_entryCSN( Operation *op )
        } else
 #endif /* BACKSQL_SYNCPROV */
        {
-               slap_get_csn( op, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
+               entryCSN.bv_val = csnbuf;
+               entryCSN.bv_len = sizeof( csnbuf );
+               slap_get_csn( op, &entryCSN, 0 );
        }
 
        ber_dupbv( &a->a_vals[ 0 ], &entryCSN );
index bc17618b36bf29a0f08acab01865199ae424380a..777a7272c5c8435c4d69054657c3eac54bdedd23 100644 (file)
@@ -369,7 +369,7 @@ glue_op_search ( Operation *op, SlapReply *rs )
                        case LDAP_ADMINLIMIT_EXCEEDED:
                        case LDAP_NO_SUCH_OBJECT:
 #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-                       case LDAP_CANNOT_CHAIN:
+                       case LDAP_X_CANNOT_CHAIN:
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
                                goto end_of_loop;
                        
index 3dd6cfc0cc8fe9b6de4835f83443e9998658f8e9..634e3ff96219834dcf2c980dbbb6e619e7c8f937 100644 (file)
@@ -40,7 +40,7 @@
 static struct berval config_rdn = BER_BVC("cn=config");
 static struct berval schema_rdn = BER_BVC("cn=schema");
 
-#define        IFMT    "{%d}"
+#define        SLAP_X_ORDERED_FMT      "{%d}"
 
 #ifdef SLAPD_MODULES
 typedef struct modpath_s {
@@ -136,6 +136,7 @@ enum {
        CFG_TLS_CERT_KEY,
        CFG_TLS_CA_PATH,
        CFG_TLS_CA_FILE,
+       CFG_TLS_DH_FILE,
        CFG_TLS_VERIFY,
        CFG_TLS_CRLCHECK,
        CFG_CONCUR,
@@ -162,6 +163,7 @@ enum {
        CFG_SASLSECP,
        CFG_SSTR_IF_MAX,
        CFG_SSTR_IF_MIN,
+       CFG_TTHREADS,
 
        CFG_LAST
 };
@@ -561,6 +563,17 @@ static ConfigTable config_back_cf_table[] = {
 #endif
                "( OLcfgGlAt:75 NAME 'olcTLSVerifyClient' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+       { "TLSDHParamFile", NULL, 0, 0, 0,
+#ifdef HAVE_TLS
+               CFG_TLS_DH_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
+#else
+               ARG_IGNORED, NULL,
+#endif
+               "( OLcfgGlAt:77 NAME 'olcTLSDHParamFile' "
+                       "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+       { "tool-threads", "count", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_TTHREADS,
+               &config_generic, "( OLcfgGlAt:80 NAME 'olcToolThreads' "
+                       "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
        { "ucdata-path", "path", 2, 2, 0, ARG_IGNORED,
                NULL, NULL, NULL, NULL },
        { "updatedn", "dn", 2, 2, 0, ARG_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
@@ -618,7 +631,8 @@ static ConfigOCs cf_ocs[] = {
                 "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
                 "olcTLSCACertificatePath $ olcTLSCertificateFile $ "
                 "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
-                "olcTLSRandFile $ olcTLSVerifyClient $ "
+                "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ "
+                "olcToolThreads $ "
                 "olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
                 "olcDitContentRules ) )", Cft_Global },
        { "( OLcfgGlOc:2 "
@@ -691,6 +705,9 @@ config_generic(ConfigArgs *c) {
                case CFG_THREADS:
                        c->value_int = connection_pool_max;
                        break;
+               case CFG_TTHREADS:
+                       c->value_int = slap_tool_thread_max;
+                       break;
                case CFG_SALT:
                        if ( passwd_salt )
                                c->value_string = ch_strdup( passwd_salt );
@@ -704,8 +721,14 @@ config_generic(ConfigArgs *c) {
                                int i;
 
                                for ( i=0; c->be->be_limits[i]; i++ ) {
-                                       bv.bv_len = sprintf( buf, IFMT, i );
-                                       bv.bv_val = buf+bv.bv_len;
+                                       bv.bv_len = snprintf( buf, sizeof( buf ), SLAP_X_ORDERED_FMT, i );
+                                       if ( bv.bv_len >= sizeof( buf ) ) {
+                                               ber_bvarray_free_x( c->rvalue_vals, NULL );
+                                               c->rvalue_vals = NULL;
+                                               rc = 1;
+                                               break;
+                                       }
+                                       bv.bv_val = buf + bv.bv_len;
                                        limits_unparse( c->be->be_limits[i], &bv );
                                        bv.bv_len += bv.bv_val - buf;
                                        bv.bv_val = buf;
@@ -790,7 +813,13 @@ config_generic(ConfigArgs *c) {
                        char *src, *dst, ibuf[11];
                        struct berval bv, abv;
                        for (i=0, a=c->be->be_acl; a; i++,a=a->acl_next) {
-                               abv.bv_len = sprintf( ibuf, IFMT, i );
+                               abv.bv_len = snprintf( ibuf, sizeof( ibuf ), SLAP_X_ORDERED_FMT, i );
+                               if ( abv.bv_len >= sizeof( ibuf ) ) {
+                                       ber_bvarray_free_x( c->rvalue_vals, NULL );
+                                       c->rvalue_vals = NULL;
+                                       i = 0;
+                                       break;
+                               }
                                acl_unparse( a, &bv );
                                abv.bv_val = ch_malloc( abv.bv_len + bv.bv_len + 1 );
                                AC_MEMCPY( abv.bv_val, ibuf, abv.bv_len );
@@ -846,8 +875,14 @@ config_generic(ConfigArgs *c) {
                                for (i=0; !BER_BVISNULL(&mp->mp_loads[i]); i++) {
                                        struct berval bv;
                                        bv.bv_val = c->log;
-                                       bv.bv_len = sprintf( bv.bv_val, IFMT "%s", i,
+                                       bv.bv_len = snprintf( bv.bv_val, sizeof( c->log ),
+                                               SLAP_X_ORDERED_FMT "%s", i,
                                                mp->mp_loads[i].bv_val );
+                                       if ( bv.bv_len >= sizeof( c->log ) ) {
+                                               ber_bvarray_free_x( c->rvalue_vals, NULL );
+                                               c->rvalue_vals = NULL;
+                                               break;
+                                       }
                                        value_add_one( &c->rvalue_vals, &bv );
                                }
                        }
@@ -879,11 +914,18 @@ config_generic(ConfigArgs *c) {
 
                                idx.bv_val = ibuf;
                                for ( i=0; !BER_BVISNULL( &authz_rewrites[i] ); i++ ) {
-                                       idx.bv_len = sprintf( idx.bv_val, IFMT, i );
+                                       idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), SLAP_X_ORDERED_FMT, i );
+                                       if ( idx.bv_len >= sizeof( ibuf ) ) {
+                                               ber_bvarray_free_x( c->rvalue_vals, NULL );
+                                               c->rvalue_vals = NULL;
+                                               break;
+                                       }
                                        bv.bv_len = idx.bv_len + authz_rewrites[i].bv_len;
                                        bv.bv_val = ch_malloc( bv.bv_len + 1 );
-                                       strcpy( bv.bv_val, idx.bv_val );
-                                       strcpy( bv.bv_val+idx.bv_len, authz_rewrites[i].bv_val );
+                                       AC_MEMCPY( bv.bv_val, idx.bv_val, idx.bv_len );
+                                       AC_MEMCPY( &bv.bv_val[ idx.bv_len ],
+                                               authz_rewrites[i].bv_val,
+                                               authz_rewrites[i].bv_len + 1 );
                                        ber_bvarray_add( &c->rvalue_vals, &bv );
                                }
                        }
@@ -900,6 +942,7 @@ config_generic(ConfigArgs *c) {
                /* single-valued attrs, no-ops */
                case CFG_CONCUR:
                case CFG_THREADS:
+               case CFG_TTHREADS:
                case CFG_RO:
                case CFG_AZPOLICY:
                case CFG_DEPTH:
@@ -914,7 +957,7 @@ config_generic(ConfigArgs *c) {
                case CFG_MODLOAD:
                case CFG_AZREGEXP:
                case CFG_REWRITE:
-                       sprintf(c->log, "change requires slapd restart");
+                       snprintf(c->log, sizeof( c->log ), "change requires slapd restart");
                        break;
 
                case CFG_SALT:
@@ -940,6 +983,8 @@ config_generic(ConfigArgs *c) {
                                else
                                        end = frontendDB->be_acl;
                                acl_destroy( c->be->be_acl, end );
+                               c->be->be_acl = end;
+
                        } else {
                                AccessControl **prev, *a;
                                int i;
@@ -978,7 +1023,7 @@ config_generic(ConfigArgs *c) {
        switch(c->type) {
                case CFG_BACKEND:
                        if(!(c->bi = backend_info(c->argv[1]))) {
-                               sprintf( c->msg, "<%s> failed init", c->argv[0] );
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> failed init", c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
                                        c->log, c->msg, c->argv[1] );
                                return(1);
@@ -996,7 +1041,7 @@ config_generic(ConfigArgs *c) {
                        } else {
                                c->be = backend_db_init(c->argv[1]);
                                if ( !c->be ) {
-                                       sprintf( c->msg, "<%s> failed init", c->argv[0] );
+                                       snprintf( c->msg, sizeof( c->msg ), "<%s> failed init", c->argv[0] );
                                        Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
                                                c->log, c->msg, c->argv[1] );
                                        return(1);
@@ -1013,6 +1058,11 @@ config_generic(ConfigArgs *c) {
                        connection_pool_max = c->value_int;     /* save for reference */
                        break;
 
+               case CFG_TTHREADS:
+                       ldap_pvt_thread_pool_maxthreads(&connection_pool, c->value_int);
+                       slap_tool_thread_max = c->value_int;    /* save for reference */
+                       break;
+
                case CFG_SALT:
                        if ( passwd_salt ) ch_free( passwd_salt );
                        passwd_salt = c->value_string;
@@ -1034,7 +1084,7 @@ config_generic(ConfigArgs *c) {
                case CFG_AZPOLICY:
                        ch_free(c->value_string);
                        if (slap_sasl_setpolicy( c->argv[1] )) {
-                               sprintf( c->msg, "<%s> unable to parse value", c->argv[0] );
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
                                        c->log, c->msg, c->argv[1] );
                                return(1);
@@ -1109,7 +1159,9 @@ config_generic(ConfigArgs *c) {
                        break;
 
                case CFG_ACL:
-                       parse_acl(c->be, c->fname, c->lineno, c->argc, c->argv, c->valx);
+                       if ( parse_acl(c->be, c->fname, c->lineno, c->argc, c->argv, c->valx) ) {
+                               return 1;
+                       }
                        break;
 
                case CFG_REPLOG:
@@ -1126,7 +1178,7 @@ config_generic(ConfigArgs *c) {
 
                case CFG_ROOTDSE:
                        if(read_root_dse_file(c->argv[1])) {
-                               sprintf( c->msg, "<%s> could not read file", c->argv[0] );
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> could not read file", c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
                                        c->log, c->msg, c->argv[1] );
                                return(1);
@@ -1148,7 +1200,7 @@ config_generic(ConfigArgs *c) {
 
                case CFG_LASTMOD:
                        if(SLAP_NOLASTMODCMD(c->be)) {
-                               sprintf( c->msg, "<%s> not available for %s database",
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> not available for %s database",
                                        c->argv[0], c->be->bd_info->bi_type );
                                Debug(LDAP_DEBUG_ANY, "%s: %s\n",
                                        c->log, c->msg, 0 );
@@ -1162,7 +1214,7 @@ config_generic(ConfigArgs *c) {
 
                case CFG_SSTR_IF_MAX:
                        if (c->value_int < index_substr_if_minlen) {
-                               sprintf( c->msg, "<%s> invalid value", c->argv[0] );
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value", c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s (%d)\n",
                                        c->log, c->msg, c->value_int );
                                return(1);
@@ -1172,7 +1224,7 @@ config_generic(ConfigArgs *c) {
 
                case CFG_SSTR_IF_MIN:
                        if (c->value_int > index_substr_if_maxlen) {
-                               sprintf( c->msg, "<%s> invalid value", c->argv[0] );
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value", c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s (%d)\n",
                                        c->log, c->msg, c->value_int );
                                return(1);
@@ -1189,7 +1241,7 @@ config_generic(ConfigArgs *c) {
                                modcur = c->private;
                                /* This should never fail */
                                if ( module_path( modcur->mp_path.bv_val )) {
-                                       sprintf( c->msg, "<%s> module path no longer valid",
+                                       snprintf( c->msg, sizeof( c->msg ), "<%s> module path no longer valid",
                                                c->argv[0] );
                                        Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
                                                c->log, c->msg, modcur->mp_path.bv_val );
@@ -1379,14 +1431,14 @@ config_passwd_hash(ConfigArgs *c) {
        }
        for(i = 1; i < c->argc; i++) {
                if(!lutil_passwd_scheme(c->argv[i])) {
-                       sprintf( c->msg, "<%s> scheme not available", c->argv[0] );
+                       snprintf( c->msg, sizeof( c->msg ), "<%s> scheme not available", c->argv[0] );
                        Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
                                c->log, c->msg, c->argv[i]);
                } else {
                        ldap_charray_add(&default_passwd_hash, c->argv[i]);
                }
                if(!default_passwd_hash) {
-                       sprintf( c->msg, "<%s> no valid hashes found", c->argv[0] );
+                       snprintf( c->msg, sizeof( c->msg ), "<%s> no valid hashes found", c->argv[0] );
                        Debug(LDAP_DEBUG_ANY, "%s: %s\n",
                                c->log, c->msg, 0 );
                        return(1);
@@ -1449,7 +1501,7 @@ config_sizelimit(ConfigArgs *c) {
                if(!strncasecmp(c->argv[i], "size", 4)) {
                        rc = limits_parse_one(c->argv[i], lim);
                        if ( rc ) {
-                               sprintf( c->msg, "<%s> unable to parse value", c->argv[0] );
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
                                        c->log, c->msg, c->argv[i]);
                                return(1);
@@ -1460,7 +1512,7 @@ config_sizelimit(ConfigArgs *c) {
                        } else {
                                lim->lms_s_soft = strtol(c->argv[i], &next, 0);
                                if(next == c->argv[i]) {
-                                       sprintf( c->msg, "<%s> unable to parse limit", c->argv[0]);
+                                       snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
                                        Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
                                                c->log, c->msg, c->argv[i]);
                                        return(1);
@@ -1506,7 +1558,7 @@ config_timelimit(ConfigArgs *c) {
                if(!strncasecmp(c->argv[i], "time", 4)) {
                        rc = limits_parse_one(c->argv[i], lim);
                        if ( rc ) {
-                               sprintf( c->msg, "<%s> unable to parse value", c->argv[0] );
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
                                        c->log, c->msg, c->argv[i]);
                                return(1);
@@ -1517,7 +1569,7 @@ config_timelimit(ConfigArgs *c) {
                        } else {
                                lim->lms_t_soft = strtol(c->argv[i], &next, 0);
                                if(next == c->argv[i]) {
-                                       sprintf( c->msg, "<%s> unable to parse limit", c->argv[0]);
+                                       snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
                                        Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
                                                c->log, c->msg, c->argv[i]);
                                        return(1);
@@ -1681,7 +1733,7 @@ config_suffix(ConfigArgs *c)
 
 #ifdef SLAPD_MONITOR_DN
        if(!strcasecmp(c->argv[1], SLAPD_MONITOR_DN)) {
-               sprintf( c->msg, "<%s> DN is reserved for monitoring slapd",
+               snprintf( c->msg, sizeof( c->msg ), "<%s> DN is reserved for monitoring slapd",
                        c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
                        c->log, c->msg, SLAPD_MONITOR_DN);
@@ -1710,7 +1762,7 @@ config_suffix(ConfigArgs *c)
                        type = oi->oi_orig->bi_type;
                }
 
-               sprintf( c->msg, "<%s> namingContext \"%s\" already served by "
+               snprintf( c->msg, sizeof( c->msg ), "<%s> namingContext \"%s\" already served by "
                        "a preceding %s database serving namingContext",
                        c->argv[0], pdn.bv_val, type );
                Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
@@ -1774,7 +1826,7 @@ config_rootpw(ConfigArgs *c) {
 
        tbe = select_backend(&c->be->be_rootndn, 0, 0);
        if(tbe != c->be) {
-               sprintf( c->msg, "<%s> can only be set when rootdn is under suffix",
+               snprintf( c->msg, sizeof( c->msg ), "<%s> can only be set when rootdn is under suffix",
                        c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s\n",
                        c->log, c->msg, 0);
@@ -1823,7 +1875,7 @@ config_restrict(ConfigArgs *c) {
        }
        i = verbs_to_mask( c->argc, c->argv, restrictable_ops, &restrictops );
        if ( i ) {
-               sprintf( c->msg, "<%s> unknown operation", c->argv[0] );
+               snprintf( c->msg, sizeof( c->msg ), "<%s> unknown operation", c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
                        c->log, c->msg, c->argv[i]);
                return(1);
@@ -1858,7 +1910,7 @@ config_allows(ConfigArgs *c) {
        }
        i = verbs_to_mask(c->argc, c->argv, allowable_ops, &allows);
        if ( i ) {
-               sprintf( c->msg, "<%s> unknown feature", c->argv[0] );
+               snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature", c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
                        c->log, c->msg, c->argv[i]);
                return(1);
@@ -1892,7 +1944,7 @@ config_disallows(ConfigArgs *c) {
        }
        i = verbs_to_mask(c->argc, c->argv, disallowable_ops, &disallows);
        if ( i ) {
-               sprintf( c->msg, "<%s> unknown feature", c->argv[0] );
+               snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature", c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
                        c->log, c->msg, c->argv[i]);
                return(1);
@@ -1926,7 +1978,7 @@ config_requires(ConfigArgs *c) {
        }
        i = verbs_to_mask(c->argc, c->argv, requires_ops, &requires);
        if ( i ) {
-               sprintf( c->msg, "<%s> unknown feature", c->argv[0] );
+               snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature", c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
                        c->log, c->msg, c->argv[i]);
                return(1);
@@ -1957,7 +2009,8 @@ loglevel_init( void )
                { BER_BVC("Cache"),     LDAP_DEBUG_CACHE },
                { BER_BVC("Index"),     LDAP_DEBUG_INDEX },
                { BER_BVC("Sync"),      LDAP_DEBUG_SYNC },
-               { BER_BVNULL,   0 }
+               { BER_BVC("None"),      LDAP_DEBUG_NONE },
+               { BER_BVNULL,           0 }
        };
 
        return slap_verbmasks_init( &loglevel_ops, lo );
@@ -1993,6 +2046,43 @@ slap_loglevel_register( slap_mask_t m, struct berval *s )
        return rc;
 }
 
+int
+slap_loglevel_get( struct berval *s, int *l )
+{
+       int             rc;
+       unsigned long   i;
+       slap_mask_t     m;
+
+       if ( loglevel_ops == NULL ) {
+               loglevel_init();
+       }
+
+       for ( m = 0, i = 1; !BER_BVISNULL( &loglevel_ops[ i ].word ); i++ ) {
+               m |= loglevel_ops[ i ].mask;
+       }
+
+       m = ~m;
+
+       for ( i = 1; i <= ( 1 << ( sizeof( int ) * 8 - 1 ) ) && !( m & i ); i <<= 1 )
+               ;
+
+       if ( !( m & i ) ) {
+               return -1;
+       }
+
+       rc = slap_verbmasks_append( &loglevel_ops, i, s, loglevel_ignore );
+
+       if ( rc != 0 ) {
+               Debug( LDAP_DEBUG_ANY, "slap_loglevel_register(%lu, \"%s\") failed\n",
+                       i, s->bv_val, 0 );
+
+       } else {
+               *l = i;
+       }
+
+       return rc;
+}
+
 int
 str2loglevel( const char *s, int *l )
 {
@@ -2004,7 +2094,7 @@ str2loglevel( const char *s, int *l )
 
        i = verb_to_mask( s, loglevel_ops );
 
-       if ( BER_BVISNULL( &loglevel_ops[ i ].word) ) {
+       if ( BER_BVISNULL( &loglevel_ops[ i ].word ) ) {
                return -1;
        }
 
@@ -2013,6 +2103,38 @@ str2loglevel( const char *s, int *l )
        return 0;
 }
 
+const char *
+loglevel2str( int l )
+{
+       struct berval   bv = BER_BVNULL;
+
+       loglevel2bv( l, &bv );
+
+       return bv.bv_val;
+}
+
+int
+loglevel2bv( int l, struct berval *bv )
+{
+       if ( loglevel_ops == NULL ) {
+               loglevel_init();
+       }
+
+       BER_BVZERO( bv );
+
+       return enum_to_verb( loglevel_ops, l, bv ) == -1;
+}
+
+int
+loglevel2bvarray( int l, BerVarray *bva )
+{
+       if ( loglevel_ops == NULL ) {
+               loglevel_init();
+       }
+
+       return mask_to_verbs( loglevel_ops, l, bva );
+}
+
 static int config_syslog;
 
 static int
@@ -2028,7 +2150,8 @@ config_loglevel(ConfigArgs *c) {
                /* Get default or commandline slapd setting */
                if ( ldap_syslog && !config_syslog )
                        config_syslog = ldap_syslog;
-               return mask_to_verbs( loglevel_ops, config_syslog, &c->rvalue_vals );
+               return loglevel2bvarray( config_syslog, &c->rvalue_vals );
+
        } else if ( c->op == LDAP_MOD_DELETE ) {
                if ( !c->line ) {
                        config_syslog = 0;
@@ -2050,14 +2173,14 @@ config_loglevel(ConfigArgs *c) {
                if ( isdigit( c->argv[i][0] ) || c->argv[i][0] == '-' ) {
                        level = strtol( c->argv[i], &next, 10 );
                        if ( next == NULL || next[0] != '\0' ) {
-                               sprintf( c->msg, "<%s> unable to parse level", c->argv[0] );
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse level", c->argv[0] );
                                Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
                                        c->log, c->msg, c->argv[i]);
                                return( 1 );
                        }
                } else {
                        if ( str2loglevel( c->argv[i], &level ) ) {
-                               sprintf( c->msg, "<%s> unknown level", c->argv[0] );
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> unknown level", c->argv[0] );
                                Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
                                        c->log, c->msg, c->argv[i]);
                                return( 1 );
@@ -2094,7 +2217,7 @@ config_referral(ConfigArgs *c) {
                return 0;
        }
        if(validate_global_referral(c->argv[1])) {
-               sprintf( c->msg, "<%s> invalid URL", c->argv[0] );
+               snprintf( c->msg, sizeof( c->msg ), "<%s> invalid URL", c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
                        c->log, c->msg, c->argv[1]);
                return(1);
@@ -2136,7 +2259,13 @@ config_security(ConfigArgs *c) {
                        tgt = (slap_ssf_t *)((char *)set + sec_keys[i].off);
                        if ( *tgt ) {
                                rc = 0;
-                               bv.bv_len = sprintf( numbuf, "%u", *tgt );
+                               bv.bv_len = snprintf( numbuf, sizeof( numbuf ), "%u", *tgt );
+                               if ( bv.bv_len >= sizeof( numbuf ) ) {
+                                       ber_bvarray_free_x( c->rvalue_vals, NULL );
+                                       c->rvalue_vals = NULL;
+                                       rc = 1;
+                                       break;
+                               }
                                bv.bv_len += sec_keys[i].key.bv_len;
                                bv.bv_val = ch_malloc( bv.bv_len + 1);
                                next = lutil_strcopy( bv.bv_val, sec_keys[i].key.bv_val );
@@ -2158,7 +2287,7 @@ config_security(ConfigArgs *c) {
                        }
                }
                if ( !tgt ) {
-                       sprintf( c->msg, "<%s> unknown factor", c->argv[0] );
+                       snprintf( c->msg, sizeof( c->msg ), "<%s> unknown factor", c->argv[0] );
                        Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
                                c->log, c->msg, c->argv[i]);
                        return(1);
@@ -2166,7 +2295,7 @@ config_security(ConfigArgs *c) {
 
                *tgt = strtol(src, &next, 10);
                if(next == NULL || next[0] != '\0' ) {
-                       sprintf( c->msg, "<%s> unable to parse factor", c->argv[0] );
+                       snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse factor", c->argv[0] );
                        Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
                                c->log, c->msg, c->argv[i]);
                        return(1);
@@ -2195,7 +2324,13 @@ replica_unparse( struct slap_replica_info *ri, int i, struct berval *bv )
        struct berval bc = BER_BVNULL;
        char numbuf[32];
 
-       len = sprintf(numbuf, IFMT, i );
+       BER_BVZERO( bv );
+
+       len = snprintf(numbuf, sizeof( numbuf ), SLAP_X_ORDERED_FMT, i );
+       if ( len >= sizeof( numbuf ) ) {
+               /* FIXME: how can indicate error? */
+               return;
+       }
 
        len += strlen( ri->ri_uri ) + STRLENOF("uri=");
        if ( ri->ri_nsuffix ) {
@@ -2241,7 +2376,7 @@ replica_unparse( struct slap_replica_info *ri, int i, struct berval *bv )
 
 static int
 config_replica(ConfigArgs *c) {
-       int i, nr = -1, len;
+       int i, nr = -1;
        char *replicahost, *replicauri;
        LDAPURLDesc *ludp;
 
@@ -2270,22 +2405,24 @@ config_replica(ConfigArgs *c) {
 
        for(i = 1; i < c->argc; i++) {
                if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) {
+                       ber_len_t       len;
+
                        replicahost = c->argv[i] + STRLENOF("host=");
-                       len = strlen( replicahost );
-                       replicauri = ch_malloc( len + STRLENOF("ldap://") + 1 );
-                       sprintf( replicauri, "ldap://%s", replicahost );
+                       len = strlen( replicahost ) + STRLENOF("ldap://");
+                       replicauri = ch_malloc( len + 1 );
+                       snprintf( replicauri, len + 1, "ldap://%s", replicahost );
                        replicahost = replicauri + STRLENOF( "ldap://");
                        nr = add_replica_info(c->be, replicauri, replicahost);
                        break;
                } else if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
                        if(ldap_url_parse(c->argv[i] + STRLENOF("uri="), &ludp) != LDAP_SUCCESS) {
-                               sprintf( c->msg, "<%s> invalid uri", c->argv[0] );
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri", c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
                                return(1);
                        }
                        if(!ludp->lud_host) {
                                ldap_free_urldesc(ludp);
-                               sprintf( c->msg, "<%s> invalid uri - missing hostname",
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri - missing hostname",
                                        c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
                                return(1);
@@ -2300,11 +2437,11 @@ config_replica(ConfigArgs *c) {
                }
        }
        if(i == c->argc) {
-               sprintf( c->msg, "<%s> missing host or uri", c->argv[0] );
+               snprintf( c->msg, sizeof( c->msg ), "<%s> missing host or uri", c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
                return(1);
        } else if(nr == -1) {
-               sprintf( c->msg, "<%s> unable to add replica", c->argv[0] );
+               snprintf( c->msg, sizeof( c->msg ), "<%s> unable to add replica", c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
                return(1);
        } else {
@@ -2342,7 +2479,7 @@ config_replica(ConfigArgs *c) {
                                        continue;
                                }
                                if(add_replica_attrs(c->be, nr, arg + 1, exclude)) {
-                                       sprintf( c->msg, "<%s> unknown attribute", c->argv[0] );
+                                       snprintf( c->msg, sizeof( c->msg ), "<%s> unknown attribute", c->argv[0] );
                                        Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
                                                c->log, c->msg, arg + 1);
                                        return(1);
@@ -2372,7 +2509,7 @@ config_updatedn(ConfigArgs *c) {
                return 0;
        }
        if(SLAP_SHADOW(c->be)) {
-               sprintf( c->msg, "<%s> database already shadowed", c->argv[0] );
+               snprintf( c->msg, sizeof( c->msg ), "<%s> database already shadowed", c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s\n",
                        c->log, c->msg, 0);
                return(1);
@@ -2413,7 +2550,7 @@ config_updateref(ConfigArgs *c) {
                return 0;
        }
        if(!SLAP_SHADOW(c->be)) {
-               sprintf( c->msg, "<%s> must appear after syncrepl or updatedn",
+               snprintf( c->msg, sizeof( c->msg ), "<%s> must appear after syncrepl or updatedn",
                        c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s\n",
                        c->log, c->msg, 0);
@@ -2421,7 +2558,7 @@ config_updateref(ConfigArgs *c) {
        }
 
        if(validate_global_referral(c->argv[1])) {
-               sprintf( c->msg, "<%s> invalid URL", c->argv[0] );
+               snprintf( c->msg, sizeof( c->msg ), "<%s> invalid URL", c->argv[0] );
                Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
                        c->log, c->msg, c->argv[1]);
                return(1);
@@ -2481,6 +2618,7 @@ config_tls_option(ConfigArgs *c) {
        case CFG_TLS_CERT_KEY:  flag = LDAP_OPT_X_TLS_KEYFILE;          break;
        case CFG_TLS_CA_PATH:   flag = LDAP_OPT_X_TLS_CACERTDIR;        break;
        case CFG_TLS_CA_FILE:   flag = LDAP_OPT_X_TLS_CACERTFILE;       break;
+       case CFG_TLS_DH_FILE:   flag = LDAP_OPT_X_TLS_DHFILE;   break;
        default:                Debug(LDAP_DEBUG_ANY, "%s: "
                                        "unknown tls_option <0x%x>\n",
                                        c->log, c->type, 0);
@@ -2958,7 +3096,7 @@ check_vals( ConfigTable *ct, ConfigArgs *ca, void *ptr, int isAttr )
                sort = 1;
                rc = ordered_value_sort( a, 1 );
                if ( rc ) {
-                       sprintf(ca->msg, "ordered_value_sort failed on attr %s\n",
+                       snprintf(ca->msg, sizeof( ca->msg ), "ordered_value_sort failed on attr %s\n",
                                ad->ad_cname.bv_val );
                        return rc;
                }
@@ -3048,7 +3186,10 @@ check_name_index( CfEntryInfo *parent, ConfigType ce_type, Entry *e,
                        if (!a ) return LDAP_NAMING_VIOLATION;
 
                        ival.bv_val = ibuf;
-                       ival.bv_len = sprintf( ibuf, IFMT, nsibs );
+                       ival.bv_len = snprintf( ibuf, sizeof( ibuf ), SLAP_X_ORDERED_FMT, nsibs );
+                       if ( ival.bv_len >= sizeof( ibuf ) ) {
+                               return LDAP_NAMING_VIOLATION;
+                       }
                        
                        newrdn.bv_len = rdn.bv_len + ival.bv_len;
                        newrdn.bv_val = ch_malloc( newrdn.bv_len+1 );
@@ -3351,7 +3492,7 @@ ok:
                        }
                }
                if ( rc ) {
-                       sprintf( ca->msg, "<%s> failed startup", ca->argv[0] );
+                       snprintf( ca->msg, sizeof( ca->msg ), "<%s> failed startup", ca->argv[0] );
                        Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
                                ca->log, ca->msg, ca->argv[1] );
                        rc = LDAP_OTHER;
@@ -3984,7 +4125,11 @@ config_build_schema_inc( ConfigArgs *c, CfEntryInfo *ceparent,
                ptr = strchr( bv.bv_val, '.' );
                if ( ptr )
                        bv.bv_len = ptr - bv.bv_val;
-               c->value_dn.bv_len = sprintf(c->value_dn.bv_val, "cn=" IFMT, c->depth);
+               c->value_dn.bv_len = snprintf(c->value_dn.bv_val, sizeof( c->log ), "cn=" SLAP_X_ORDERED_FMT, c->depth);
+               if ( c->value_dn.bv_len >= sizeof( c->log ) ) {
+                       /* FIXME: how can indicate error? */
+                       return;
+               }
                strncpy( c->value_dn.bv_val + c->value_dn.bv_len, bv.bv_val,
                        bv.bv_len );
                c->value_dn.bv_len += bv.bv_len;
@@ -4010,7 +4155,11 @@ config_build_includes( ConfigArgs *c, CfEntryInfo *ceparent,
 
        for (i=0; cf; cf=cf->c_sibs, i++) {
                c->value_dn.bv_val = c->log;
-               c->value_dn.bv_len = sprintf(c->value_dn.bv_val, "cn=include" IFMT, i);
+               c->value_dn.bv_len = snprintf(c->value_dn.bv_val, sizeof( c->log ), "cn=include" SLAP_X_ORDERED_FMT, i);
+               if ( c->value_dn.bv_len >= sizeof( c->log ) ) {
+                       /* FIXME: how can indicate error? */
+                       return;
+               }
                c->private = cf;
                e = config_build_entry( op, rs, ceparent, c, &c->value_dn,
                        &CFOC_INCLUDE, NULL );
@@ -4034,7 +4183,11 @@ config_build_modules( ConfigArgs *c, CfEntryInfo *ceparent,
                if ( BER_BVISNULL( &mp->mp_path ) && !mp->mp_loads )
                        continue;
                c->value_dn.bv_val = c->log;
-               c->value_dn.bv_len = sprintf(c->value_dn.bv_val, "cn=module" IFMT, i);
+               c->value_dn.bv_len = snprintf(c->value_dn.bv_val, sizeof( c->log ), "cn=module" SLAP_X_ORDERED_FMT, i);
+               if ( c->value_dn.bv_len >= sizeof( c->log ) ) {
+                       /* FIXME: how can indicate error? */
+                       return;
+               }
                c->private = mp;
                config_build_entry( op, rs, ceparent, c, &c->value_dn,
                        &CFOC_MODULE, NULL );
@@ -4129,7 +4282,11 @@ config_back_db_open( BackendDB *be )
                if (!bi->bi_private) continue;
 
                rdn.bv_val = c.log;
-               rdn.bv_len = sprintf(rdn.bv_val, "%s=%s", cfAd_backend->ad_cname.bv_val, bi->bi_type);
+               rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ),
+                       "%s=%s", cfAd_backend->ad_cname.bv_val, bi->bi_type);
+               if ( rdn.bv_len >= sizeof( c.log ) ) {
+                       /* FIXME: holler ... */ ;
+               }
                c.bi = bi;
                e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_BACKEND,
                        bi->bi_cf_ocs );
@@ -4149,8 +4306,12 @@ config_back_db_open( BackendDB *be )
                        bi = be->bd_info;
                }
                rdn.bv_val = c.log;
-               rdn.bv_len = sprintf(rdn.bv_val, "%s=" IFMT "%s", cfAd_database->ad_cname.bv_val,
+               rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ),
+                       "%s=" SLAP_X_ORDERED_FMT "%s", cfAd_database->ad_cname.bv_val,
                        i, bi->bi_type);
+               if ( rdn.bv_len >= sizeof( c.log ) ) {
+                       /* FIXME: holler ... */ ;
+               }
                c.be = be;
                c.bi = bi;
                e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_DATABASE,
@@ -4166,8 +4327,12 @@ config_back_db_open( BackendDB *be )
 
                        for (j=0,on=oi->oi_list; on; j++,on=on->on_next) {
                                rdn.bv_val = c.log;
-                               rdn.bv_len = sprintf(rdn.bv_val, "%s=" IFMT "%s",
+                               rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ),
+                                       "%s=" SLAP_X_ORDERED_FMT "%s",
                                        cfAd_overlay->ad_cname.bv_val, j, on->on_bi.bi_type );
+                               if ( rdn.bv_len >= sizeof( c.log ) ) {
+                                       /* FIXME: holler ... */ ;
+                               }
                                c.be = be;
                                c.bi = &on->on_bi;
                                oe = config_build_entry( op, &rs, ce, &c, &rdn,
index 8d5544183def6690f1005d663978c4607d4d98b2..26d20f5ee0260a8ff43bca07aebcb7cfb6326aaf 100644 (file)
@@ -131,7 +131,7 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) {
                c->argv[1] = "";
        }
        if(Conf->min_args && (c->argc < Conf->min_args)) {
-               sprintf( c->msg, "<%s> missing <%s> argument",
+               snprintf( c->msg, sizeof( c->msg ), "<%s> missing <%s> argument",
                        c->argv[0], Conf->what );
                Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n", c->log, c->msg, 0 );
                return(ARG_BAD_CONF);
@@ -139,7 +139,7 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) {
        if(Conf->max_args && (c->argc > Conf->max_args)) {
                char    *ignored = " ignored";
 
-               sprintf( c->msg, "<%s> extra cruft after <%s>",
+               snprintf( c->msg, sizeof( c->msg ), "<%s> extra cruft after <%s>",
                        c->argv[0], Conf->what );
 
 #ifdef LDAP_DEVEL
@@ -152,34 +152,34 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) {
 #endif /* LDAP_DEVEL */
        }
        if((arg_type & ARG_DB) && !c->be) {
-               sprintf( c->msg, "<%s> only allowed within database declaration",
+               snprintf( c->msg, sizeof( c->msg ), "<%s> only allowed within database declaration",
                        c->argv[0] );
                Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n",
                        c->log, c->msg, 0);
                return(ARG_BAD_CONF);
        }
        if((arg_type & ARG_PRE_BI) && c->bi) {
-               sprintf( c->msg, "<%s> must occur before any backend %sdeclaration",
+               snprintf( c->msg, sizeof( c->msg ), "<%s> must occur before any backend %sdeclaration",
                        c->argv[0], (arg_type & ARG_PRE_DB) ? "or database " : "" );
                Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n",
                        c->log, c->msg, 0 );
                return(ARG_BAD_CONF);
        }
        if((arg_type & ARG_PRE_DB) && c->be && c->be != frontendDB) {
-               sprintf( c->msg, "<%s> must occur before any database declaration",
+               snprintf( c->msg, sizeof( c->msg ), "<%s> must occur before any database declaration",
                        c->argv[0] );
                Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n",
                        c->log, c->msg, 0);
                return(ARG_BAD_CONF);
        }
        if((arg_type & ARG_PAREN) && *c->argv[1] != '(' /*')'*/) {
-               sprintf( c->msg, "<%s> old format not supported", c->argv[0] );
+               snprintf( c->msg, sizeof( c->msg ), "<%s> old format not supported", c->argv[0] );
                Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
                        c->log, c->msg, 0);
                return(ARG_BAD_CONF);
        }
        if((arg_type & ARGS_POINTER) && !Conf->arg_item && !(arg_type & ARG_OFFSET)) {
-               sprintf( c->msg, "<%s> invalid config_table, arg_item is NULL",
+               snprintf( c->msg, sizeof( c->msg ), "<%s> invalid config_table, arg_item is NULL",
                        c->argv[0] );
                Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
                        c->log, c->msg, 0);
@@ -204,7 +204,7 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) {
                                        !strcasecmp(c->argv[1], "false")) {
                                        iarg = 0;
                                } else {
-                                       sprintf( c->msg, "<%s> invalid value, ignored",
+                                       snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value, ignored",
                                                c->argv[0] );
                                        Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
                                                c->log, c->msg, 0 );
@@ -215,7 +215,7 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) {
                j = (arg_type & ARG_NONZERO) ? 1 : 0;
                if(iarg < j && larg < j && barg < j ) {
                        larg = larg ? larg : (barg ? barg : iarg);
-                       sprintf( c->msg, "<%s> invalid value, ignored",
+                       snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value, ignored",
                                c->argv[0] );
                        Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
                                c->log, c->msg, 0 );
@@ -238,7 +238,7 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) {
                ber_str2bv( c->argv[1], 0, 0, &bv );
                rc = dnPrettyNormal( NULL, &bv, &c->value_dn, &c->value_ndn, NULL );
                if ( rc != LDAP_SUCCESS ) {
-                       sprintf( c->msg, "<%s> invalid DN %d (%s)",
+                       snprintf( c->msg, sizeof( c->msg ), "<%s> invalid DN %d (%s)",
                                c->argv[0], rc, ldap_err2string( rc ));
                        Debug(LDAP_DEBUG_CONFIG, "%s: %s\n" , c->log, c->msg, 0);
                        return(ARG_BAD_CONF);
@@ -265,7 +265,7 @@ int config_set_vals(ConfigTable *Conf, ConfigArgs *c) {
 #endif
                if(rc) {
                        if ( !c->msg[0] ) {
-                               sprintf( c->msg, "<%s> handler exited with %d",
+                               snprintf( c->msg, sizeof( c->msg ), "<%s> handler exited with %d",
                                        c->argv[0], rc );
                                Debug(LDAP_DEBUG_CONFIG, "%s: %s!\n",
                                        c->log, c->msg, 0 );
@@ -280,7 +280,7 @@ int config_set_vals(ConfigTable *Conf, ConfigArgs *c) {
                else if (c->bi)
                        ptr = c->bi->bi_private;
                else {
-                       sprintf( c->msg, "<%s> offset is missing base pointer",
+                       snprintf( c->msg, sizeof( c->msg ), "<%s> offset is missing base pointer",
                                c->argv[0] );
                        Debug(LDAP_DEBUG_CONFIG, "%s: %s!\n",
                                c->log, c->msg, 0);
@@ -393,10 +393,10 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c)
        if ( cf->arg_type & ARGS_POINTER) {
                bv.bv_val = c->log;
                switch(cf->arg_type & ARGS_POINTER) {
-               case ARG_INT: bv.bv_len = sprintf(bv.bv_val, "%d", c->value_int); break;
-               case ARG_LONG: bv.bv_len = sprintf(bv.bv_val, "%ld", c->value_long); break;
-               case ARG_BER_LEN_T: bv.bv_len = sprintf(bv.bv_val, "%ld", c->value_ber_t); break;
-               case ARG_ON_OFF: bv.bv_len = sprintf(bv.bv_val, "%s",
+               case ARG_INT: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%d", c->value_int); break;
+               case ARG_LONG: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%ld", c->value_long); break;
+               case ARG_BER_LEN_T: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%ld", c->value_ber_t); break;
+               case ARG_ON_OFF: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%s",
                        c->value_int ? "TRUE" : "FALSE"); break;
                case ARG_STRING:
                        if ( c->value_string && c->value_string[0]) {
@@ -413,6 +413,9 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c)
                        }
                        break;
                }
+               if (bv.bv_val == c->log && bv.bv_len >= sizeof( c->log ) ) {
+                       return 1;
+               }
                if (( cf->arg_type & ARGS_POINTER ) == ARG_STRING )
                        ber_bvarray_add(&c->rvalue_vals, &bv);
                else
@@ -853,18 +856,20 @@ verbs_to_mask(int argc, char *argv[], slap_verbmasks *v, slap_mask_t *m) {
  */
 int
 mask_to_verbs(slap_verbmasks *v, slap_mask_t m, BerVarray *bva) {
-       int i;
-
-       if (!m) return 1;
-       for (i=0; !BER_BVISNULL(&v[i].word); i++) {
-               if (!v[i].mask) continue;
-               if (( m & v[i].mask ) == v[i].mask ) {
-                       value_add_one( bva, &v[i].word );
-                       m ^= v[i].mask;
-                       if ( !m ) break;
+       int i, rc = 1;
+
+       if (m) {
+               for (i=0; !BER_BVISNULL(&v[i].word); i++) {
+                       if (!v[i].mask) continue;
+                       if (( m & v[i].mask ) == v[i].mask ) {
+                               value_add_one( bva, &v[i].word );
+                               rc = 0;
+                               m ^= v[i].mask;
+                               if ( !m ) break;
+                       }
                }
        }
-       return 0;
+       return rc;
 }
 
 int
@@ -1383,7 +1388,7 @@ int config_generic_wrapper( Backend *be, const char *fname, int lineno,
        c.argc = argc;
        c.argv = argv;
        c.valx = -1;
-       sprintf( c.log, "%s: line %d", fname, lineno );
+       snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno );
 
        rc = SLAP_CONF_UNKNOWN;
        ct = config_find_keyword( be->be_cf_ocs->co_table, &c );
index 06918c2a3d2a24bcc53264c0845c58144320eb8e..e3bd2f5d411915b288f6904a3be681581cb38549 100644 (file)
 #include "slapi/slapi.h"
 #endif
 
+#ifdef SLAP_MULTI_CONN_ARRAY
+/* for Multiple Connection Arrary (MCA) Support */
+static ldap_pvt_thread_mutex_t* connections_mutex;
+static Connection **connections = NULL;
+
+/* set to the number of processors (round up to a power of 2) */
+#      define NUM_CONNECTION_ARRAY 4
+
+/* partition the array in a modulo manner */
+#      define MCA_conn_array_id(fd)            ((int)(fd)%NUM_CONNECTION_ARRAY)
+#      define MCA_conn_array_element_id(fd)    ((int)(fd)/NUM_CONNECTION_ARRAY)
+#      define MCA_ARRAY_SIZE                   ((int)(MCA_conn_array_element_id(dtblsize) + (MCA_conn_array_id(dtblsize) ? 1 : 0)))
+#      define MCA_conn_check(fd)               (dtblsize > 0 && (fd) >= 0 && (fd) < (MCA_ARRAY_SIZE*NUM_CONNECTION_ARRAY))
+#      define MCA_GET_CONNECTION(fd) (&(connections[MCA_conn_array_id(fd)]) \
+               [MCA_conn_array_element_id(fd)])
+#      define MCA_GET_CONN_MUTEX(fd) (&connections_mutex[MCA_conn_array_id(fd)])
+
+#else
 /* protected by connections_mutex */
 static ldap_pvt_thread_mutex_t connections_mutex;
 static Connection *connections = NULL;
 
+#      define MCA_conn_check(fd)               (dtblsize > 0 && (fd) < dtblsize)
+#      define MCA_GET_CONNECTION(fd) (&connections[s])
+#      define MCA_GET_CONN_MUTEX(fd) (&connections_mutex)
+#endif
+
 static ldap_pvt_thread_mutex_t conn_nextid_mutex;
 static unsigned long conn_nextid = 0;
 
@@ -82,10 +105,25 @@ connection_state2str( int state )
 
 static Connection* connection_get( ber_socket_t s );
 
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+
+typedef struct conn_readinfo {
+       Operation *op;
+       ldap_pvt_thread_start_t *func;
+       void *arg;
+       int nullop;
+} conn_readinfo;
+
+static int connection_input( Connection *c, conn_readinfo *cri );
+#else
 static int connection_input( Connection *c );
+#endif
 static void connection_close( Connection *c );
 
 static int connection_op_activate( Operation *op );
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+static void connection_op_queue( Operation *op );
+#endif
 static int connection_resched( Connection *conn );
 static void connection_abandon( Connection *conn );
 static void connection_destroy( Connection *c );
@@ -96,6 +134,69 @@ static ldap_pvt_thread_start_t connection_operation;
  * Initialize connection management infrastructure.
  */
 int connections_init(void)
+#ifdef SLAP_MULTI_CONN_ARRAY
+{
+       int             i, j;
+       Connection*     conn;
+
+       assert( connections == NULL );
+
+       if( connections != NULL) {
+               Debug( LDAP_DEBUG_ANY, "connections_init: already initialized.\n",
+                       0, 0, 0 );
+               return -1;
+       }
+
+       connections_mutex = (ldap_pvt_thread_mutex_t*) ch_calloc(
+               NUM_CONNECTION_ARRAY, sizeof(ldap_pvt_thread_mutex_t) );
+       if( connections_mutex == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "connections_init: "
+                       "allocation of connection mutex[%d] failed\n", i, 0, 0 );
+               return -1;
+       }
+
+       connections = (Connection**) ch_calloc(
+               NUM_CONNECTION_ARRAY, sizeof(Connection*));
+       if( connections == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "connections_init: "
+                       "allocation of connection[%d] failed\n", 0, 0, 0 );
+               return -1;
+       }
+
+       for ( i = 0; i < NUM_CONNECTION_ARRAY; i++ ) {
+               ldap_pvt_thread_mutex_init( connections_mutex+i );
+               connections[i] = (Connection*) ch_calloc(
+                       MCA_ARRAY_SIZE, sizeof(Connection) );
+               if( connections[i] == NULL ) {
+                       Debug( LDAP_DEBUG_ANY, "connections_init: "
+                               "allocation (%d*%ld) of connection array[%d] failed\n",
+                               dtblsize, (long) sizeof(Connection), i );
+                       return -1;
+               }
+       }
+
+       /* should check return of every call */
+       ldap_pvt_thread_mutex_init( &conn_nextid_mutex );
+
+       assert( connections[0]->c_struct_state == SLAP_C_UNINITIALIZED );
+       assert( connections[NUM_CONNECTION_ARRAY-1]->c_struct_state ==
+               SLAP_C_UNINITIALIZED );
+
+       for ( i = 0; i < NUM_CONNECTION_ARRAY; i++ ) {
+               conn = connections[i];
+               for ( j = 0; j < MCA_ARRAY_SIZE; j++ ) {
+                       conn[j].c_conn_idx = j;
+               }
+       }
+
+       /*
+        * per entry initialization of the Connection array initialization
+        * will be done by connection_init()
+        */ 
+
+       return 0;
+}
+#else
 {
        int i;
 
@@ -114,8 +215,8 @@ int connections_init(void)
        connections = (Connection *) ch_calloc( dtblsize, sizeof(Connection) );
 
        if( connections == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "connections_init: allocation (%d*%ld) of connection array failed\n",
+               Debug( LDAP_DEBUG_ANY, "connections_init: "
+                       "allocation (%d*%ld) of connection array failed\n",
                        dtblsize, (long) sizeof(Connection), 0 );
                return -1;
        }
@@ -132,11 +233,58 @@ int connections_init(void)
 
        return 0;
 }
+#endif
 
 /*
  * Destroy connection management infrastructure.
  */
+
 int connections_destroy(void)
+#ifdef SLAP_MULTI_CONN_ARRAY
+{
+       int i;
+       ber_socket_t j;
+
+       if( connections == NULL) {
+               Debug( LDAP_DEBUG_ANY, "connections_destroy: nothing to destroy.\n",
+                       0, 0, 0 );
+               return -1;
+       }
+
+    for ( i = 0; i < NUM_CONNECTION_ARRAY; i++ ) {
+               Connection* conn = connections[i];
+               for ( j = 0; j < MCA_ARRAY_SIZE; j++ ) {
+                       if( conn[j].c_struct_state != SLAP_C_UNINITIALIZED ) {
+                               ber_sockbuf_free( conn[j].c_sb );
+                               ldap_pvt_thread_mutex_destroy( &conn[j].c_mutex );
+                               ldap_pvt_thread_mutex_destroy( &conn[j].c_write_mutex );
+                               ldap_pvt_thread_cond_destroy( &conn[j].c_write_cv );
+#ifdef LDAP_SLAPI
+                               /* FIX ME!! */
+                               if ( slapi_plugins_used ) {
+                                       slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION,
+                                               &connections[i] );
+                               }
+#endif
+                       }
+               }
+       }
+
+       for ( i = 0; i < NUM_CONNECTION_ARRAY; i++ ) {
+               free( connections[i] );
+               connections[i] = NULL;
+               ldap_pvt_thread_mutex_destroy( &connections_mutex[i] );
+       }
+
+       free( connections );
+       free( connections_mutex );
+
+       ldap_pvt_thread_mutex_destroy( &conn_nextid_mutex );
+
+       return 0;
+
+}
+#else
 {
        ber_socket_t i;
 
@@ -156,7 +304,8 @@ int connections_destroy(void)
                        ldap_pvt_thread_cond_destroy( &connections[i].c_write_cv );
 #ifdef LDAP_SLAPI
                        if ( slapi_plugins_used ) {
-                               slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, &connections[i] );
+                               slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION,
+                                       &connections[i] );
                        }
 #endif
                }
@@ -169,11 +318,45 @@ int connections_destroy(void)
        ldap_pvt_thread_mutex_destroy( &conn_nextid_mutex );
        return 0;
 }
+#endif
 
 /*
  * shutdown all connections
  */
 int connections_shutdown(void)
+#ifdef SLAP_MULTI_CONN_ARRAY
+{
+       int i;
+       ber_socket_t j;
+
+       for ( i = 0; i < NUM_CONNECTION_ARRAY; i++ ) {
+               Connection* conn = connections[i];
+               ldap_pvt_thread_mutex_lock( &connections_mutex[i] );
+               for ( j = 0; j < MCA_ARRAY_SIZE; j++ ) {
+                       if( conn[j].c_struct_state != SLAP_C_USED ) {
+                               continue;
+                       }
+                       /* give persistent clients a chance to cleanup */
+                       if( conn[j].c_conn_state == SLAP_C_CLIENT ) {
+                               ldap_pvt_thread_pool_submit( &connection_pool,
+                               conn[j].c_clientfunc, conn[j].c_clientarg );
+                               continue;
+                       }
+
+                       ldap_pvt_thread_mutex_lock( &conn[j].c_mutex );
+                       /* connections_mutex and c_mutex are locked */
+                       connection_closing( &conn[j], "connection shutdown" );
+                       connection_close( &conn[j] );
+                       ldap_pvt_thread_mutex_unlock( &conn[j].c_mutex );
+               }
+
+               ldap_pvt_thread_mutex_unlock( &connections_mutex[i] );
+       }
+
+       return 0;
+
+}
+#else
 {
        ber_socket_t i;
 
@@ -203,6 +386,7 @@ int connections_shutdown(void)
 
        return 0;
 }
+#endif
 
 /*
  * Timeout idle connections.
@@ -219,8 +403,9 @@ int connections_timeout_idle(time_t now)
        {
                /* Don't timeout a slow-running request or a persistent
                 * outbound connection */
-               if( c->c_n_ops_executing ||
-                       c->c_conn_state == SLAP_C_CLIENT ) continue;
+               if( c->c_n_ops_executing || c->c_conn_state == SLAP_C_CLIENT ) {
+                       continue;
+               }
 
                if( difftime( c->c_activitytime+global_idletimeout, now) < 0 ) {
                        /* close it */
@@ -246,12 +431,11 @@ static Connection* connection_get( ber_socket_t s )
 
        assert( connections != NULL );
 
-       if(s == AC_SOCKET_INVALID) {
-               return NULL;
-       }
+       if(s == AC_SOCKET_INVALID) return NULL;
 
 #ifndef HAVE_WINSOCK
-       c = &connections[s];
+       assert( MCA_conn_check( s ) );
+       c = MCA_GET_CONNECTION(s);
 
        assert( c->c_struct_state != SLAP_C_UNINITIALIZED );
 
@@ -367,11 +551,11 @@ long connection_init(
        assert( s < dtblsize );
 #endif
 
-       ldap_pvt_thread_mutex_lock( &connections_mutex );
+       ldap_pvt_thread_mutex_lock( MCA_GET_CONN_MUTEX(s) );
 
 #ifndef HAVE_WINSOCK
-       c = &connections[s];
-
+       assert( MCA_conn_check( s ) );
+       c = MCA_GET_CONNECTION(s);
 #else
        {
                ber_socket_t i;
@@ -398,9 +582,7 @@ long connection_init(
                                break;
                        }
 
-                       if( connections[i].c_conn_state == SLAP_C_CLIENT ) {
-                               continue;
-                       }
+                       if( connections[i].c_conn_state == SLAP_C_CLIENT ) continue;
 
                        assert( connections[i].c_struct_state == SLAP_C_USED );
                        assert( connections[i].c_conn_state != SLAP_C_INVALID );
@@ -497,7 +679,7 @@ long connection_init(
                c->c_close_reason = "?";                        /* should never be needed */
                ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_FD, &s );
                ldap_pvt_thread_mutex_unlock( &c->c_mutex );
-               ldap_pvt_thread_mutex_unlock( &connections_mutex );
+               ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
 
                return 0;
        }
@@ -584,8 +766,9 @@ long connection_init(
        slap_sasl_open( c, 0 );
        slap_sasl_external( c, ssf, authid );
 
+       slapd_add_internal( s, 1 );
        ldap_pvt_thread_mutex_unlock( &c->c_mutex );
-       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+       ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
 
        backend_connection_init(c);
 
@@ -611,10 +794,12 @@ void connection2anonymous( Connection *c )
                ch_free(c->c_dn.bv_val);
        }
        BER_BVZERO( &c->c_dn );
+
        if ( !BER_BVISNULL( &c->c_ndn ) ) {
                ch_free(c->c_ndn.bv_val);
        }
        BER_BVZERO( &c->c_ndn );
+
        if ( !BER_BVISNULL( &c->c_sasl_authz_dn ) ) {
                ber_memfree_x( c->c_sasl_authz_dn.bv_val, NULL );
        }
@@ -675,17 +860,19 @@ connection_destroy( Connection *c )
        }
 
        ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
+       slapd_sd_lock();
+       ber_sockbuf_free( c->c_sb );
        if ( sd != AC_SOCKET_INVALID ) {
-               slapd_remove( sd, 1, 0 );
+               slapd_remove( sd, 1, 0, 1 );
 
                Statslog( LDAP_DEBUG_STATS, (close_reason
                                                                         ? "conn=%lu fd=%ld closed (%s)\n"
                                                                         : "conn=%lu fd=%ld closed\n"),
                        connid, (long) sd, close_reason, 0, 0 );
+       } else {
+               slapd_sd_unlock();
        }
 
-       ber_sockbuf_free( c->c_sb );
-
        c->c_sb = ber_sockbuf_alloc( );
 
        {
@@ -817,21 +1004,34 @@ unsigned long connections_nextid(void)
        unsigned long id;
        assert( connections != NULL );
 
-       ldap_pvt_thread_mutex_lock( &connections_mutex );
+       ldap_pvt_thread_mutex_lock( &conn_nextid_mutex );
 
        id = conn_nextid;
 
-       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+       ldap_pvt_thread_mutex_unlock( &conn_nextid_mutex );
 
        return id;
 }
 
 Connection* connection_first( ber_socket_t *index )
 {
+#ifdef SLAP_MULTI_CONN_ARRAY
+       int conn_array_id;
+#endif
+
        assert( connections != NULL );
        assert( index != NULL );
 
+#ifdef SLAP_MULTI_CONN_ARRAY
+       for ( conn_array_id = 0;
+               conn_array_id < NUM_CONNECTION_ARRAY;
+               conn_array_id++ )
+       {
+               ldap_pvt_thread_mutex_lock( &connections_mutex[ conn_array_id ] );
+       }
+#else
        ldap_pvt_thread_mutex_lock( &connections_mutex );
+#endif
 
        *index = 0;
 
@@ -839,15 +1039,54 @@ Connection* connection_first( ber_socket_t *index )
 }
 
 Connection* connection_next( Connection *c, ber_socket_t *index )
+#ifdef SLAP_MULTI_CONN_ARRAY
 {
+       Connection* conn;
+
        assert( connections != NULL );
        assert( index != NULL );
-       assert( *index <= dtblsize );
+       assert( *index >= 0 && *index < MCA_ARRAY_SIZE );
 
-       if( c != NULL ) {
-               ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+       if( c != NULL ) ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+
+       c = NULL;
+
+       for(; *index < dtblsize; (*index)++) {
+               assert( MCA_conn_check( *index ) );
+               conn = MCA_GET_CONNECTION(*index);
+               if( conn->c_struct_state == SLAP_C_UNINITIALIZED ) {
+                       assert( conn->c_conn_state == SLAP_C_INVALID );
+#ifndef HAVE_WINSOCK
+                       continue;
+#else
+                       break;
+#endif
+               }
+
+               if( conn->c_struct_state == SLAP_C_USED ) {
+                       assert( conn->c_conn_state != SLAP_C_INVALID );
+                       c = conn;
+                       (*index)++;
+                       break;
+               }
+
+               assert( conn->c_struct_state == SLAP_C_UNUSED );
+               assert( conn->c_conn_state == SLAP_C_INVALID );
        }
 
+       if( c != NULL ) ldap_pvt_thread_mutex_lock( &c->c_mutex );
+
+       return c;
+
+}
+#else
+{
+       assert( connections != NULL );
+       assert( index != NULL );
+       assert( *index <= dtblsize );
+
+       if( c != NULL ) ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+
        c = NULL;
 
        for(; *index < dtblsize; (*index)++) {
@@ -870,22 +1109,31 @@ Connection* connection_next( Connection *c, ber_socket_t *index )
                assert( connections[*index].c_conn_state == SLAP_C_INVALID );
        }
 
-       if( c != NULL ) {
-               ldap_pvt_thread_mutex_lock( &c->c_mutex );
-       }
-
+       if( c != NULL ) ldap_pvt_thread_mutex_lock( &c->c_mutex );
        return c;
 }
+#endif
 
 void connection_done( Connection *c )
 {
+#ifdef SLAP_MULTI_CONN_ARRAY
+       int conn_array_id;
+#endif
+
        assert( connections != NULL );
 
-       if( c != NULL ) {
-               ldap_pvt_thread_mutex_unlock( &c->c_mutex );
-       }
+       if( c != NULL ) ldap_pvt_thread_mutex_unlock( &c->c_mutex );
 
+#ifdef SLAP_MULTI_CONN_ARRAY
+       for ( conn_array_id = 0;
+               conn_array_id < NUM_CONNECTION_ARRAY;
+               conn_array_id++ )
+       {
+               ldap_pvt_thread_mutex_unlock( &connections_mutex[ conn_array_id ] );
+       }
+#else
        ldap_pvt_thread_mutex_unlock( &connections_mutex );
+#endif
 }
 
 /*
@@ -910,7 +1158,7 @@ void connection_done( Connection *c )
                ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex ); \
        } while (0)
 #else /* !SLAPD_MONITOR */
-#define INCR_OP_INITIATED(index) 
+#define INCR_OP_INITIATED(index) do { } while (0)
 #define INCR_OP_COMPLETED(index) \
        do { \
                ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex ); \
@@ -1072,10 +1320,11 @@ operations_error:
        }
 
        if ( op->o_cancel == SLAP_CANCEL_REQ ) {
-               if ( rc == SLAPD_ABANDON )
+               if ( rc == SLAPD_ABANDON ) {
                        op->o_cancel = SLAP_CANCEL_ACK;
-               else
+               } else {
                        op->o_cancel = LDAP_TOO_LATE;
+               }
        }
        while ( op->o_cancel != SLAP_CANCEL_NONE &&
                op->o_cancel != SLAP_CANCEL_DONE )
@@ -1097,17 +1346,9 @@ operations_error:
        case LBER_ERROR:
        case LDAP_REQ_UNBIND:
                /* c_mutex is locked */
-               connection_closing(
-                       conn, tag == LDAP_REQ_UNBIND ? NULL : "operations error" );
+               connection_closing( conn,
+                       tag == LDAP_REQ_UNBIND ? NULL : "operations error" );
                break;
-
-       case LDAP_REQ_BIND:
-               conn->c_sasl_bind_in_progress =
-                       rc == LDAP_SASL_BIND_IN_PROGRESS ? 1 : 0;
-
-               if( conn->c_conn_state == SLAP_C_BINDING) {
-                       conn->c_conn_state = SLAP_C_ACTIVE;
-               }
        }
 
        connection_resched( conn );
@@ -1132,9 +1373,10 @@ int connection_client_setup(
        c = connection_get( s );
        c->c_clientfunc = func;
        c->c_clientarg = arg;
-       connection_return( c );
+
        slapd_add_internal( s, 0 );
        slapd_set_read( s, 1 );
+       connection_return( c );
        return 0;
 }
 
@@ -1158,7 +1400,9 @@ void connection_client_stop(
        c->c_conn_state = SLAP_C_INVALID;
        c->c_struct_state = SLAP_C_UNUSED;
        c->c_close_reason = "?";                        /* should never be needed */
+       slapd_sd_lock();
        ber_sockbuf_free( c->c_sb );
+       slapd_remove( s, 0, 1, 1 );
        c->c_sb = ber_sockbuf_alloc( );
        {
                ber_len_t max = sockbuf_max_incoming;
@@ -1166,17 +1410,76 @@ void connection_client_stop(
        }
 
        connection_return( c );
-       slapd_remove( s, 0, 1 );
 }
 
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+
+static int connection_read( ber_socket_t s, conn_readinfo *cri );
+
+static void* connection_read_thread( void* ctx, void* argv )
+{
+       int rc ;
+       conn_readinfo cri = { NULL, NULL, NULL, 0 };
+       ber_socket_t s = (long)argv;
+
+       /*
+        * read incoming LDAP requests. If there is more than one,
+        * the first one is returned with new_op
+        */
+       if( ( rc = connection_read( s, &cri ) ) < 0 ) {
+               Debug( LDAP_DEBUG_CONNS, "connection_read(%d) error\n", s, 0, 0 );
+               return (void*)(long)rc;
+       }
+
+       /* execute a single queued request in the same thread */
+       if( cri.op && !cri.nullop ) {
+               rc = (long)connection_operation( ctx, cri.op );
+       } else if ( cri.func ) {
+               rc = (long)cri.func( ctx, cri.arg );
+       }
+
+       return (void*)(long)rc;
+}
+
+int connection_read_activate( ber_socket_t s )
+{
+       int rc;
+
+       /*
+        * suspend reading on this file descriptor until a connection processing
+        * thread reads data on it. Otherwise the listener thread will repeatedly
+        * submit the same event on it to the pool.
+        */
+       rc = slapd_clr_read( s, 0 );
+       if ( rc )
+               return rc;
+
+       rc = ldap_pvt_thread_pool_submit( &connection_pool,
+               connection_read_thread, (void *)(long)s );
+
+       if( rc != 0 ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "connection_read_activate(%d): submit failed (%d)\n",
+                       s, rc, 0 );
+       }
+
+       return rc;
+}
+#endif
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+static int
+connection_read( ber_socket_t s, conn_readinfo *cri )
+#else
 int connection_read(ber_socket_t s)
+#endif
 {
        int rc = 0;
        Connection *c;
 
        assert( connections != NULL );
 
-       ldap_pvt_thread_mutex_lock( &connections_mutex );
+       ldap_pvt_thread_mutex_lock( MCA_GET_CONN_MUTEX(s) );
 
        /* get (locked) connection */
        c = connection_get( s );
@@ -1185,9 +1488,8 @@ int connection_read(ber_socket_t s)
                Debug( LDAP_DEBUG_ANY,
                        "connection_read(%ld): no connection!\n",
                        (long) s, 0, 0 );
-               slapd_remove(s, 1, 0);
 
-               ldap_pvt_thread_mutex_unlock( &connections_mutex );
+               ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
                return -1;
        }
 
@@ -1197,17 +1499,27 @@ int connection_read(ber_socket_t s)
                Debug( LDAP_DEBUG_TRACE,
                        "connection_read(%d): closing, ignoring input for id=%lu\n",
                        s, c->c_connid, 0 );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+               slapd_set_read( s, 1 );
+#endif
                connection_return( c );
-               ldap_pvt_thread_mutex_unlock( &connections_mutex );
+               ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
                return 0;
        }
 
        if ( c->c_conn_state == SLAP_C_CLIENT ) {
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+               cri->func = c->c_clientfunc;
+               cri->arg = c->c_clientarg;
+               /* read should already be cleared */
+#else
                slapd_clr_read( s, 0 );
                ldap_pvt_thread_pool_submit( &connection_pool,
                        c->c_clientfunc, c->c_clientarg );
+#endif
                connection_return( c );
-               ldap_pvt_thread_mutex_unlock( &connections_mutex );
+               ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
                return 0;
        }
 
@@ -1219,34 +1531,38 @@ int connection_read(ber_socket_t s)
        if ( c->c_is_tls && c->c_needs_tls_accept ) {
                rc = ldap_pvt_tls_accept( c->c_sb, slap_tls_ctx );
                if ( rc < 0 ) {
-#if 0 /* required by next #if 0 */
-                       struct timeval tv;
-                       fd_set rfd;
-#endif
-
                        Debug( LDAP_DEBUG_TRACE,
-                               "connection_read(%d): TLS accept error "
+                               "connection_read(%d): TLS accept failure "
                                "error=%d id=%lu, closing\n",
                                s, rc, c->c_connid );
+
                        c->c_needs_tls_accept = 0;
                        /* connections_mutex and c_mutex are locked */
                        connection_closing( c, "TLS negotiation failure" );
 
 #if 0
-                       /* Drain input before close, to allow SSL error codes
-                        * to propagate to client. */
-                       FD_ZERO(&rfd);
-                       FD_SET(s, &rfd);
-                       for (rc=1; rc>0;) {
-                               tv.tv_sec = 1;
-                               tv.tv_usec = 0;
-                               rc = select(s+1, &rfd, NULL, NULL, &tv);
-                               if (rc == 1) {
-                                       ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DRAIN, NULL);
+                       {
+                               struct timeval tv;
+                               fd_set rfd;
+                               /* Drain input before close, to allow SSL error codes
+                                * to propagate to client. */
+                               FD_ZERO(&rfd);
+                               FD_SET(s, &rfd);
+                               for (rc=1; rc>0;) {
+                                       tv.tv_sec = 1;
+                                       tv.tv_usec = 0;
+                                       rc = select(s+1, &rfd, NULL, NULL, &tv);
+                                       if (rc == 1) {
+                                               ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DRAIN, NULL);
+                                       }
                                }
                        }
 #endif
+
                        connection_close( c );
+                       connection_return( c );
+                       ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
+                       return 0;
 
                } else if ( rc == 0 ) {
                        void *ssl;
@@ -1279,8 +1595,12 @@ int connection_read(ber_socket_t s)
                if( rc != 0 ||
                        !ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL ) )
                {
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+                       slapd_set_read( s, 1 );
+#endif
+
                        connection_return( c );
-                       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+                       ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
                        return 0;
                }
        }
@@ -1290,25 +1610,29 @@ int connection_read(ber_socket_t s)
        if ( c->c_sasl_layers ) {
                /* If previous layer is not removed yet, give up for now */
                if ( !c->c_sasl_sockctx ) {
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+                       slapd_set_read( s, 1 );
+#endif
+
                        connection_return( c );
-                       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+                       ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
                        return 0;
                }
 
                c->c_sasl_layers = 0;
 
                rc = ldap_pvt_sasl_install( c->c_sb, c->c_sasl_sockctx );
-
                if( rc != LDAP_SUCCESS ) {
                        Debug( LDAP_DEBUG_TRACE,
                                "connection_read(%d): SASL install error "
                                "error=%d id=%lu, closing\n",
                                s, rc, c->c_connid );
+
                        /* connections_mutex and c_mutex are locked */
                        connection_closing( c, "SASL layer install failure" );
                        connection_close( c );
                        connection_return( c );
-                       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+                       ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
                        return 0;
                }
        }
@@ -1319,7 +1643,11 @@ int connection_read(ber_socket_t s)
 
        do {
                /* How do we do this without getting into a busy loop ? */
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+               rc = connection_input( c, cri );
+#else
                rc = connection_input( c );
+#endif
        }
 #ifdef DATA_READY_LOOP
        while( !rc && ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL ));
@@ -1333,14 +1661,22 @@ int connection_read(ber_socket_t s)
                Debug( LDAP_DEBUG_TRACE,
                        "connection_read(%d): input error=%d id=%lu, closing.\n",
                        s, rc, c->c_connid );
+
                /* connections_mutex and c_mutex are locked */
                connection_closing( c, conn_lost_str );
                connection_close( c );
                connection_return( c );
-               ldap_pvt_thread_mutex_unlock( &connections_mutex );
+               ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
                return 0;
        }
 
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+       if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
+               slapd_set_write( s, 0 );
+       }
+
+       slapd_set_read( s, 1 );
+#else
        if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_READ, NULL ) ) {
                slapd_set_read( s, 1 );
        }
@@ -1348,15 +1684,20 @@ int connection_read(ber_socket_t s)
        if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
                slapd_set_write( s, 1 );
        }
+#endif
 
        connection_return( c );
-       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+       ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
+
        return 0;
 }
 
 static int
-connection_input(
-       Connection *conn )
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+connection_input( Connection *conn , conn_readinfo *cri )
+#else
+connection_input( Connection *conn )
+#endif
 {
        Operation *op;
        ber_tag_t       tag;
@@ -1381,11 +1722,11 @@ connection_input(
 
 #ifdef LDAP_CONNECTIONLESS
        if ( conn->c_is_udp ) {
-               char    peername[sizeof("IP=255.255.255.255:65336")];
-               len = ber_int_sb_read(conn->c_sb, &peeraddr,
-                       sizeof(struct sockaddr));
-               if (len != sizeof(struct sockaddr))
-                       return 1;
+               char peername[sizeof("IP=255.255.255.255:65336")];
+
+               len = ber_int_sb_read(conn->c_sb, &peeraddr, sizeof(struct sockaddr));
+               if (len != sizeof(struct sockaddr)) return 1;
+
                sprintf( peername, "IP=%s:%d",
                        inet_ntoa( peeraddr.sa_in_addr.sin_addr ),
                        (unsigned) ntohs( peeraddr.sa_in_addr.sin_port ) );
@@ -1394,6 +1735,7 @@ connection_input(
                        conn->c_connid, peername, conn->c_sock_name.bv_val, 0, 0 );
        }
 #endif
+
        tag = ber_get_next( conn->c_sb, &len, conn->c_currentber );
        if ( tag != LDAP_TAG_MESSAGE ) {
                int err = errno;
@@ -1419,16 +1761,14 @@ connection_input(
 
        if ( (tag = ber_get_int( ber, &msgid )) != LDAP_TAG_MSGID ) {
                /* log, close and send error */
-               Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n",
-                       tag, 0, 0 );
+               Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n", tag, 0, 0 );
                ber_free( ber, 1 );
                return -1;
        }
 
        if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
                /* log, close and send error */
-               Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%lx\n",
-                       tag, 0, 0 );
+               Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%lx\n", tag, 0, 0 );
                ber_free( ber, 1 );
 
                return -1;
@@ -1447,6 +1787,7 @@ connection_input(
                }
        }
 #endif
+
        if(tag == LDAP_REQ_BIND) {
                /* immediately abandon all existing operations upon BIND */
                connection_abandon( conn );
@@ -1457,7 +1798,8 @@ connection_input(
        op->o_conn = conn;
        /* clear state if the connection is being reused from inactive */
        if ( conn->c_conn_state == SLAP_C_INACTIVE ) {
-               memset( &conn->c_pagedresults_state, 0, sizeof( conn->c_pagedresults_state ) );
+               memset( &conn->c_pagedresults_state, 0,
+                       sizeof( conn->c_pagedresults_state ) );
        }
 
        op->o_res_ber = NULL;
@@ -1536,14 +1878,33 @@ connection_input(
                        conn->c_connid, defer, 0 );
                conn->c_n_ops_pending++;
                LDAP_STAILQ_INSERT_TAIL( &conn->c_pending_ops, op, o_next );
-               if ( conn->c_n_ops_pending > max ) {
-                       rc = -1;
-               } else {
-                       rc = 1;
-               }
+               rc = ( conn->c_n_ops_pending > max ) ? -1 : 0;
+
        } else {
                conn->c_n_ops_executing++;
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+               /*
+                * The first op will be processed in the same thread context,
+                * as long as there is only one op total.
+                * Subsequent ops will be submitted to the pool by
+                * calling connection_op_activate()
+                */
+               if ( cri->op == NULL ) {
+                       /* the first incoming request */
+                       connection_op_queue( op );
+                       cri->op = op;
+               } else {
+                       if ( !cri->nullop ) {
+                               cri->nullop = 1;
+                               rc = ldap_pvt_thread_pool_submit( &connection_pool,
+                                       connection_operation, (void *) cri->op );
+                       }
+                       connection_op_activate( op );
+               }
+#else
                connection_op_activate( op );
+#endif
        }
 
 #ifdef NO_THREADS
@@ -1552,8 +1913,8 @@ connection_input(
                return 1;
        }
 #endif
-       assert( conn->c_struct_state == SLAP_C_USED );
 
+       assert( conn->c_struct_state == SLAP_C_USED );
        return rc;
 }
 
@@ -1568,7 +1929,7 @@ connection_resched( Connection *conn )
                ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
 
                /* use trylock to avoid possible deadlock */
-               rc = ldap_pvt_thread_mutex_trylock( &connections_mutex );
+               rc = ldap_pvt_thread_mutex_trylock( MCA_GET_CONN_MUTEX( sd ) );
 
                if( rc ) {
                        Debug( LDAP_DEBUG_TRACE,
@@ -1580,7 +1941,7 @@ connection_resched( Connection *conn )
                         * so recheck state below.
                         */
                        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
-                       ldap_pvt_thread_mutex_lock( &connections_mutex );
+                       ldap_pvt_thread_mutex_lock( MCA_GET_CONN_MUTEX ( sd ) );
                        ldap_pvt_thread_mutex_lock( &conn->c_mutex );
                }
 
@@ -1595,7 +1956,7 @@ connection_resched( Connection *conn )
                        connection_close( conn );
                }
 
-               ldap_pvt_thread_mutex_unlock( &connections_mutex );
+               ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX( sd ) );
                return 0;
        }
 
@@ -1605,11 +1966,11 @@ connection_resched( Connection *conn )
        }
 
        while ((op = LDAP_STAILQ_FIRST( &conn->c_pending_ops )) != NULL) {
-               if ( conn->c_n_ops_executing > connection_pool_max/2 ) {
-                       break;
-               }
+               if ( conn->c_n_ops_executing > connection_pool_max/2 ) break;
+
                LDAP_STAILQ_REMOVE_HEAD( &conn->c_pending_ops, o_next );
                LDAP_STAILQ_NEXT(op, o_next) = NULL;
+
                /* pending operations should not be marked for abandonment */
                assert(!op->o_abandon);
 
@@ -1618,9 +1979,7 @@ connection_resched( Connection *conn )
 
                connection_op_activate( op );
 
-               if ( conn->c_conn_state == SLAP_C_BINDING ) {
-                       break;
-               }
+               if ( conn->c_conn_state == SLAP_C_BINDING ) break;
        }
        return 0;
 }
@@ -1630,20 +1989,36 @@ connection_init_log_prefix( Operation *op )
 {
        if ( op->o_connid == (unsigned long)(-1) ) {
                snprintf( op->o_log_prefix, sizeof( op->o_log_prefix ),
-                               "conn=-1 op=%lu", op->o_opid );
+                       "conn=-1 op=%lu", op->o_opid );
 
        } else {
                snprintf( op->o_log_prefix, sizeof( op->o_log_prefix ),
-                               "conn=%lu op=%lu", op->o_connid, op->o_opid );
+                       "conn=%lu op=%lu", op->o_connid, op->o_opid );
        }
 }
 
-static int connection_op_activate( Operation *op )
+static int connection_bind_cb( Operation *op, SlapReply *rs )
+{
+       slap_callback *cb = op->o_callback;
+       op->o_callback = cb->sc_next;
+
+       ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
+       op->o_conn->c_conn_state = SLAP_C_ACTIVE;
+       ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
+
+       ch_free( cb );
+       return SLAP_CB_CONTINUE;
+}
+
+static void connection_op_queue( Operation *op )
 {
-       int status;
        ber_tag_t tag = op->o_tag;
 
-       if(tag == LDAP_REQ_BIND) {
+       if (tag == LDAP_REQ_BIND) {
+               slap_callback *sc = ch_calloc( 1, sizeof( slap_callback ));
+               sc->sc_response = connection_bind_cb;
+               sc->sc_next = op->o_callback;
+               op->o_callback = sc;
                op->o_conn->c_conn_state = SLAP_C_BINDING;
        }
 
@@ -1657,6 +2032,7 @@ static int connection_op_activate( Operation *op )
                        ber_dupbv( &op->o_ndn, &op->o_conn->c_sasl_authz_dn );
                }
        }
+
        op->o_authtype = op->o_conn->c_authtype;
        ber_dupbv( &op->o_authmech, &op->o_conn->c_authmech );
        
@@ -1664,8 +2040,9 @@ static int connection_op_activate( Operation *op )
                op->o_protocol = op->o_conn->c_protocol
                        ? op->o_conn->c_protocol : LDAP_VERSION3;
        }
-       if (op->o_conn->c_conn_state == SLAP_C_INACTIVE
-               && op->o_protocol > LDAP_VERSION2)
+
+       if (op->o_conn->c_conn_state == SLAP_C_INACTIVE &&
+               op->o_protocol > LDAP_VERSION2)
        {
                op->o_conn->c_conn_state = SLAP_C_ACTIVE;
        }
@@ -1674,20 +2051,58 @@ static int connection_op_activate( Operation *op )
        connection_init_log_prefix( op );
 
        LDAP_STAILQ_INSERT_TAIL( &op->o_conn->c_ops, op, o_next );
+}
+
+static int connection_op_activate( Operation *op )
+{
+       int rc;
+
+       connection_op_queue( op );
 
-       status = ldap_pvt_thread_pool_submit( &connection_pool,
+       rc = ldap_pvt_thread_pool_submit( &connection_pool,
                connection_operation, (void *) op );
 
-       if ( status != 0 ) {
+       if ( rc != 0 ) {
                Debug( LDAP_DEBUG_ANY,
-                       "ldap_pvt_thread_pool_submit: failed (%d) for conn=%lu\n",
-                       status, op->o_connid, 0 );
+                       "connection_op_activate: submit failed (%d) for conn=%lu\n",
+                       rc, op->o_connid, 0 );
                /* should move op to pending list */
        }
 
-       return status;
+       return rc;
 }
 
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+static int connection_write( ber_socket_t s );
+static void *connection_write_thread( void *ctx, void *arg )
+{
+       return (void *)(long)connection_write((long)arg);
+}
+
+int connection_write_activate( ber_socket_t s )
+{
+       int rc;
+
+       /*
+        * suspend reading on this file descriptor until a connection processing
+        * thread write data on it. Otherwise the listener thread will repeatedly
+        * submit the same event on it to the pool.
+        */
+       slapd_clr_write( s, 0);
+
+       rc = ldap_pvt_thread_pool_submit( &connection_pool,
+               connection_write_thread, (void *)(long)s );
+
+       if( rc != 0 ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "connection_write_activate(%d): submit failed (%d)\n",
+                       (int) s, rc, 0 );
+       }
+       return rc;
+}
+
+static
+#endif
 int connection_write(ber_socket_t s)
 {
        Connection *c;
@@ -1695,21 +2110,20 @@ int connection_write(ber_socket_t s)
 
        assert( connections != NULL );
 
-       ldap_pvt_thread_mutex_lock( &connections_mutex );
+       ldap_pvt_thread_mutex_lock( MCA_GET_CONN_MUTEX( s ) );
 
        c = connection_get( s );
-
        if( c == NULL ) {
                Debug( LDAP_DEBUG_ANY,
                        "connection_write(%ld): no connection!\n",
                        (long)s, 0, 0 );
-               slapd_remove(s, 1, 0);
-               ldap_pvt_thread_mutex_unlock( &connections_mutex );
+               ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX( s ) );
                return -1;
        }
 
+#ifndef SLAP_LIGHTWEIGHT_DISPATCHER
        slapd_clr_write( s, 0);
-
+#endif
        c->c_n_write++;
 
        Debug( LDAP_DEBUG_TRACE,
@@ -1723,16 +2137,17 @@ int connection_write(ber_socket_t s)
        if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
                slapd_set_write( s, 1 );
        }
-       /* If there are ops pending because of a writewaiter, start
-        * one up.
+
+       /* If there are ops pending because of a writewaiter,
+        * start one up.
         */
        while ((op = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) {
                if ( !c->c_writewaiter ) break;
-               if ( c->c_n_ops_executing > connection_pool_max/2 ) {
-                       break;
-               }
+               if ( c->c_n_ops_executing > connection_pool_max/2 ) break;
+
                LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next );
                LDAP_STAILQ_NEXT(op, o_next) = NULL;
+
                /* pending operations should not be marked for abandonment */
                assert(!op->o_abandon);
 
@@ -1743,8 +2158,9 @@ int connection_write(ber_socket_t s)
 
                break;
        }
+
        connection_return( c );
-       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+       ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
        return 0;
 }
 
@@ -1774,7 +2190,7 @@ connection_fake_init(
        op->o_connid = op->o_conn->c_connid;
        connection_init_log_prefix( op );
 
-       op->o_time = slap_get_time();
+       slap_op_time( &op->o_time, &op->o_tincr );
 }
 
 void
@@ -1784,4 +2200,3 @@ connection_assign_nextid( Connection *conn )
        conn->c_connid = conn_nextid++;
        ldap_pvt_thread_mutex_unlock( &conn_nextid_mutex );
 }
-
index 6d29007b58ef542dedff258f4a381626f4540633..87d8cbc3717464a32af500e8d61551df2216d694 100644 (file)
@@ -100,6 +100,9 @@ slap_graduate_commit_csn( Operation *op )
                if ( csne->ce_opid == op->o_opid && csne->ce_connid == op->o_connid ) {
                        LDAP_TAILQ_REMOVE( op->o_bd->be_pending_csn_list,
                                csne, ce_csn_link );
+                       if ( op->o_csn.bv_val == csne->ce_csn.bv_val ) {
+                               BER_BVZERO( &op->o_csn );
+                       }
                        ch_free( csne->ce_csn.bv_val );
                        ch_free( csne );
                        break;
@@ -163,6 +166,7 @@ slap_queue_csn(
        ldap_pvt_thread_mutex_lock( op->o_bd->be_pcl_mutexp );
 
        ber_dupbv( &pending->ce_csn, csn );
+       op->o_csn = pending->ce_csn;
        pending->ce_connid = op->o_connid;
        pending->ce_opid = op->o_opid;
        pending->ce_state = SLAP_CSN_PENDING;
@@ -174,8 +178,6 @@ slap_queue_csn(
 int
 slap_get_csn(
        Operation *op,
-       char *csnbuf,
-       int     len,
        struct berval *csn,
        int manage_ctxcsn )
 {
@@ -184,11 +186,10 @@ slap_get_csn(
 #ifndef HAVE_GMTIME_R
        ldap_pvt_thread_mutex_lock( &gmtime_mutex );
 #endif
-       csn->bv_len = lutil_csnstr( csnbuf, len, 0, 0 );
+       csn->bv_len = lutil_csnstr( csn->bv_val, csn->bv_len, 0, 0 );
 #ifndef HAVE_GMTIME_R
        ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
 #endif
-       csn->bv_val = csnbuf;
 
        if ( manage_ctxcsn )
                slap_queue_csn( op, csn );
index c50db15639744a17a123834ea1589232178fcf14..49007b612dd6b32dcd935aa46509cc751fa0f206 100644 (file)
 #include "ldap_rq.h"
 
 #if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL)
-#include <sys/epoll.h>
+# include <sys/epoll.h>
 #endif
 
 #ifdef HAVE_TCPD
-#include <tcpd.h>
-#define SLAP_STRING_UNKNOWN    STRING_UNKNOWN
-
+# include <tcpd.h>
 int allow_severity = LOG_INFO;
 int deny_severity = LOG_NOTICE;
+
+# define SLAP_STRING_UNKNOWN   STRING_UNKNOWN
 #else /* ! TCP Wrappers */
-#define SLAP_STRING_UNKNOWN    "unknown"
+# define SLAP_STRING_UNKNOWN   "unknown"
 #endif /* ! TCP Wrappers */
 
 #ifdef LDAP_PF_LOCAL
-#include <sys/stat.h>
+# include <sys/stat.h>
 /* this should go in <ldap.h> as soon as it is accepted */
-#define LDAPI_MOD_URLEXT               "x-mod"
+# define LDAPI_MOD_URLEXT              "x-mod"
 #endif /* LDAP_PF_LOCAL */
 
 #ifdef LDAP_PF_INET6
@@ -82,15 +82,22 @@ static ber_socket_t wake_sds[2];
 static int emfile;
 
 static int waking;
-#define WAKE_LISTENER(w) do { \
-       if ((w) && waking < 5) { waking++; tcp_write( wake_sds[1], "0", 1 ); } \
-       } while(0)
+#define WAKE_LISTENER(w)       do { \
+       if ((w) && waking < 5) { \
+               waking++; \
+               tcp_write( wake_sds[1], "0", 1 ); \
+       } \
+} while(0)
 
-volatile sig_atomic_t slapd_shutdown = 0, slapd_gentle_shutdown = 0;
+volatile sig_atomic_t slapd_shutdown = 0;
+volatile sig_atomic_t slapd_gentle_shutdown = 0;
 volatile sig_atomic_t slapd_abrupt_shutdown = 0;
 
 static struct slap_daemon {
        ldap_pvt_thread_mutex_t sd_mutex;
+#ifdef HAVE_TCPD
+       ldap_pvt_thread_mutex_t tcpd_mutex;
+#endif
 
        ber_socket_t sd_nactives;
        int sd_nwriters;
@@ -102,13 +109,11 @@ static struct slap_daemon {
        int     sd_epfd;
        int     sd_nfds;
 #else
-
 #ifndef HAVE_WINSOCK
        /* In winsock, accept() returns values higher than dtblsize
                so don't bother with this optimization */
        int sd_nfds;
 #endif
-
        fd_set sd_actives;
        fd_set sd_readers;
        fd_set sd_writers;
@@ -116,196 +121,206 @@ static struct slap_daemon {
 } slap_daemon;
 
 #ifdef HAVE_EPOLL
-#define        SLAP_EVENTS_ARE_INDEXED 0
-#define        SLAP_SOCK_IX(s) (slap_daemon.sd_index[s])
-#define SLAP_SOCK_EP(s)        (slap_daemon.sd_epolls[SLAP_SOCK_IX(s)])
-#define SLAP_SOCK_EV(s)        (SLAP_SOCK_EP(s).events)
-#define SLAP_SOCK_IS_ACTIVE(s) (SLAP_SOCK_IX(s) != -1)
-#define SLAP_SOCK_NOT_ACTIVE(s)        (SLAP_SOCK_IX(s) == -1)
-#define SLAP_SOCK_IS_SET(s, mode)      (SLAP_SOCK_EV(s) & mode)
-
-#define SLAP_SOCK_IS_READ(s)   SLAP_SOCK_IS_SET(s, EPOLLIN)
-#define SLAP_SOCK_IS_WRITE(s)  SLAP_SOCK_IS_SET(s, EPOLLOUT)
-
-#define        SLAP_SET_SOCK(s, mode) do { \
-       if ((SLAP_SOCK_EV(s) & mode) != mode) { \
-               SLAP_SOCK_EV(s) |= mode;        \
-               epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, s,        \
-                       &SLAP_SOCK_EP(s));      \
-       }       \
+# define SLAP_EVENTS_ARE_INDEXED       0
+# define SLAP_SOCK_IX(s)       (slap_daemon.sd_index[(s)])
+# define SLAP_SOCK_EP(s)       (slap_daemon.sd_epolls[SLAP_SOCK_IX(s)])
+# define SLAP_SOCK_EV(s)       (SLAP_SOCK_EP(s).events)
+# define SLAP_SOCK_IS_ACTIVE(s)        (SLAP_SOCK_IX(s) != -1)
+# define SLAP_SOCK_NOT_ACTIVE(s)       (SLAP_SOCK_IX(s) == -1)
+# define SLAP_SOCK_IS_SET(s, mode)     (SLAP_SOCK_EV(s) & (mode))
+
+# define SLAP_SOCK_IS_READ(s)  SLAP_SOCK_IS_SET((s), EPOLLIN)
+# define SLAP_SOCK_IS_WRITE(s) SLAP_SOCK_IS_SET((s), EPOLLOUT)
+
+# define SLAP_SET_SOCK(s, mode) do { \
+       if ((SLAP_SOCK_EV(s) & (mode)) != (mode)) {     \
+               SLAP_SOCK_EV(s) |= (mode); \
+               epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, (s), \
+                       &SLAP_SOCK_EP(s)); \
+       } \
 } while(0)
 
-#define SLAP_CLR_SOCK(s, mode) do { \
-       if ((SLAP_SOCK_EV(s) & mode)) { \
-               SLAP_SOCK_EV(s) &= ~mode;       \
-               epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, s,        \
-                       &SLAP_SOCK_EP(s));      \
-       }       \
+# define SLAP_CLR_SOCK(s, mode) do { \
+       if ((SLAP_SOCK_EV(s) & (mode))) { \
+               SLAP_SOCK_EV(s) &= ~(mode);     \
+               epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, s, \
+                       &SLAP_SOCK_EP(s)); \
+       } \
 } while(0)
 
-#define SLAP_SOCK_SET_READ(s)  SLAP_SET_SOCK(s, EPOLLIN)
-#define SLAP_SOCK_SET_WRITE(s) SLAP_SET_SOCK(s, EPOLLOUT)
+# define SLAP_SOCK_SET_READ(s) SLAP_SET_SOCK(s, EPOLLIN)
+# define SLAP_SOCK_SET_WRITE(s)        SLAP_SET_SOCK(s, EPOLLOUT)
 
-#define SLAP_SOCK_CLR_READ(s)  SLAP_CLR_SOCK(s, EPOLLIN)
-#define SLAP_SOCK_CLR_WRITE(s) SLAP_CLR_SOCK(s, EPOLLOUT)
+# ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+#  define SLAP_SOCK_SET_SUSPEND(s) \
+       ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] = 1 )
+#  define SLAP_SOCK_CLR_SUSPEND(s) \
+       ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] = 0 )
+#  define SLAP_SOCK_IS_SUSPEND(s) \
+       ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] == 1 )
+# endif
 
-#define SLAP_CLR_EVENT(i, mode)        (revents[i].events &= ~mode)
+# define SLAP_SOCK_CLR_READ(s) SLAP_CLR_SOCK((s), EPOLLIN)
+# define SLAP_SOCK_CLR_WRITE(s)        SLAP_CLR_SOCK((s), EPOLLOUT)
 
+# define SLAP_CLR_EVENT(i, mode)       (revents[(i)].events &= ~(mode))
 
-#define SLAP_EVENT_MAX slap_daemon.sd_nfds
+# define SLAP_EVENT_MAX        slap_daemon.sd_nfds
 
 /* If a Listener address is provided, store that as the epoll data.
  * Otherwise, store the address of this socket's slot in the
  * index array. If we can't do this add, the system is out of
  * resources and we need to shutdown.
  */
-#define SLAP_ADD_SOCK(s, l) do { \
-       int rc; \
-       SLAP_SOCK_IX(s) = slap_daemon.sd_nfds;  \
-       SLAP_SOCK_EP(s).data.ptr = (l) ? (l) : (void *)(&SLAP_SOCK_IX(s)); \
-       SLAP_SOCK_EV(s) = EPOLLIN;      \
-       rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_ADD, s,   \
-                       &SLAP_SOCK_EP(s));      \
-       if ( rc == 0 ) slap_daemon.sd_nfds++;   \
-       else {  \
-               Debug( LDAP_DEBUG_ANY, "daemon: epoll_ctl ADD failed, errno %d, shutting down\n",       \
-               errno, 0, 0 );  \
-               slapd_shutdown = 2;     \
-       }       \
-} while(0)
-
-#define        SLAP_EV_LISTENER(ptr) (((int *)(ptr) >= slap_daemon.sd_index && \
-        (int *)(ptr) <= (slap_daemon.sd_index+dtblsize)) ? 0 : 1)
-
-#define        SLAP_EV_PTRFD(ptr) (SLAP_EV_LISTENER(ptr) ? \
-        ((Listener *)ptr)->sl_sd : (int *)(ptr) - slap_daemon.sd_index)
-
-#define SLAP_DEL_SOCK(s) do { \
-       int fd, rc, index = SLAP_SOCK_IX(s); \
-       rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_DEL, s,   \
-                       &SLAP_SOCK_EP(s));      \
-       slap_daemon.sd_epolls[index] = slap_daemon.sd_epolls[slap_daemon.sd_nfds-1];    \
-       fd = SLAP_EV_PTRFD(slap_daemon.sd_epolls[index].data.ptr);      \
-       slap_daemon.sd_index[fd] = index;       \
-       slap_daemon.sd_index[s] = -1;   \
-       slap_daemon.sd_nfds--;  \
-} while(0)
-
-#define SLAP_EVENT_CLR_READ(i) SLAP_CLR_EVENT(i, EPOLLIN)
-#define SLAP_EVENT_CLR_WRITE(i)        SLAP_CLR_EVENT(i, EPOLLOUT)
-
-#define SLAP_CHK_EVENT(i, mode)        (revents[i].events & mode)
-
-#define SLAP_EVENT_IS_READ(i)  SLAP_CHK_EVENT(i, EPOLLIN)
-#define SLAP_EVENT_IS_WRITE(i) SLAP_CHK_EVENT(i, EPOLLOUT)
-#define SLAP_EVENT_IS_LISTENER(i)      SLAP_EV_LISTENER(revents[i].data.ptr)
-#define SLAP_EVENT_LISTENER(i) (revents[i].data.ptr)
-
-#define SLAP_EVENT_FD(i)       SLAP_EV_PTRFD(revents[i].data.ptr)
-#define        SLAP_SOCK_SET_MUTE(s)   SLAP_SOCK_CLR_READ(s)
-#define        SLAP_SOCK_CLR_MUTE(s)   SLAP_SOCK_SET_READ(s)
-#define        SLAP_SOCK_IS_MUTE(s)    (!SLAP_SOCK_IS_READ(s))
-
-#define SLAP_SOCK_SET_INIT     \
-       slap_daemon.sd_epolls = ch_calloc(1, sizeof(struct epoll_event) * dtblsize * 2);        \
-       slap_daemon.sd_index = ch_malloc(sizeof(int) * dtblsize);       \
-       slap_daemon.sd_epfd = epoll_create( dtblsize ); \
-       for (i=0; i<dtblsize; i++) slap_daemon.sd_index[i] = -1
-
-
-#define        SLAP_EVENT_DECL \
-       struct epoll_event *revents
-
-#define SLAP_EVENT_INIT        \
-       revents = slap_daemon.sd_epolls + dtblsize;     \
-
-#define SLAP_EVENT_WAIT(tvp)   \
-       epoll_wait( slap_daemon.sd_epfd, revents, dtblsize, tvp ? tvp->tv_sec * 1000 : -1 )
+# define SLAP_ADD_SOCK(s, l) do { \
+       int rc; \
+       SLAP_SOCK_IX((s)) = slap_daemon.sd_nfds; \
+       SLAP_SOCK_EP((s)).data.ptr = (l) ? (l) : (void *)(&SLAP_SOCK_IX(s)); \
+       SLAP_SOCK_EV((s)) = EPOLLIN; \
+       rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_ADD, \
+               (s), &SLAP_SOCK_EP((s))); \
+       if ( rc == 0 ) { \
+               slap_daemon.sd_nfds++; \
+       } else { \
+               Debug( LDAP_DEBUG_ANY, \
+                       "daemon: epoll_ctl(ADD,fd=%d) failed, errno=%d, shutting down\n", \
+                       s, errno, 0 ); \
+               slapd_shutdown = 2; \
+       } \
+} while (0)
+
+# define SLAP_EV_LISTENER(ptr) (((int *)(ptr) >= slap_daemon.sd_index && \
+       (int *)(ptr) <= (slap_daemon.sd_index+dtblsize)) ? 0 : 1 )
+
+# define SLAP_EV_PTRFD(ptr) (SLAP_EV_LISTENER(ptr) ? \
+       ((Listener *)ptr)->sl_sd : (int *)(ptr) - slap_daemon.sd_index)
+
+# define SLAP_DEL_SOCK(s) do { \
+       int fd, rc, index = SLAP_SOCK_IX((s)); \
+       if ( index < 0 ) break; \
+       rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_DEL, \
+               (s), &SLAP_SOCK_EP((s))); \
+       slap_daemon.sd_epolls[index] = \
+               slap_daemon.sd_epolls[slap_daemon.sd_nfds-1]; \
+       fd = SLAP_EV_PTRFD(slap_daemon.sd_epolls[index].data.ptr); \
+       slap_daemon.sd_index[fd] = index; \
+       slap_daemon.sd_index[(s)] = -1; \
+       slap_daemon.sd_nfds--; \
+} while (0)
+
+# define SLAP_EVENT_CLR_READ(i)        SLAP_CLR_EVENT((i), EPOLLIN)
+# define SLAP_EVENT_CLR_WRITE(i)       SLAP_CLR_EVENT((i), EPOLLOUT)
+
+# define SLAP_CHK_EVENT(i, mode)       (revents[(i)].events & mode)
+
+# define SLAP_EVENT_IS_READ(i) SLAP_CHK_EVENT((i), EPOLLIN)
+# define SLAP_EVENT_IS_WRITE(i)        SLAP_CHK_EVENT((i), EPOLLOUT)
+# define SLAP_EVENT_IS_LISTENER(i)     SLAP_EV_LISTENER(revents[(i)].data.ptr)
+# define SLAP_EVENT_LISTENER(i)        (revents[(i)].data.ptr)
+
+# define SLAP_EVENT_FD(i)      SLAP_EV_PTRFD(revents[(i)].data.ptr)
+
+# define SLAP_SOCK_SET_INIT do { \
+       slap_daemon.sd_epolls = ch_calloc(1, \
+               sizeof(struct epoll_event) * dtblsize * 2); \
+       slap_daemon.sd_index = ch_malloc(sizeof(int) * dtblsize); \
+       slap_daemon.sd_epfd = epoll_create( dtblsize ); \
+       for (i=0; i<dtblsize; i++) slap_daemon.sd_index[i] = -1; \
+} while (0)
+
+# define SLAP_EVENT_DECL struct epoll_event *revents
+
+# define SLAP_EVENT_INIT do { \
+       revents = slap_daemon.sd_epolls + dtblsize; \
+} while (0)
+
+# define SLAP_EVENT_WAIT(tvp) \
+       epoll_wait( slap_daemon.sd_epfd, revents, \
+               dtblsize, (tvp) ? (tvp)->tv_sec * 1000 : -1 )
 
 #else
-
 /* select */
-#define        SLAP_EVENTS_ARE_INDEXED 1
-#define SLAP_EVENT_DECL        \
+
+# define SLAP_EVENTS_ARE_INDEXED 1
+# define SLAP_EVENT_DECL       \
        fd_set readfds, writefds
 
-#define SLAP_EVENT_INIT \
+# define SLAP_EVENT_INIT do { \
        AC_MEMCPY( &readfds, &slap_daemon.sd_readers, sizeof(fd_set) ); \
-       if ( nwriters ) \
+       if ( nwriters ) \
                AC_MEMCPY( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) ); \
-       else \
-               FD_ZERO( &writefds )
-
-#ifdef FD_SETSIZE
-#define        CHK_SETSIZE     \
-       if (dtblsize > FD_SETSIZE) dtblsize = FD_SETSIZE
-#else
-#define        CHK_SETSIZE
-#endif
-
-#define        SLAP_SOCK_SET_INIT      \
-       CHK_SETSIZE;    \
-       FD_ZERO(&slap_daemon.sd_readers);       \
-       FD_ZERO(&slap_daemon.sd_writers)
-
-#define SLAP_SOCK_IS_ACTIVE(fd)        FD_ISSET(fd, &slap_daemon.sd_actives)
-
-#define SLAP_SOCK_IS_READ(fd)  FD_ISSET(fd, &slap_daemon.sd_readers)
-#define SLAP_SOCK_IS_WRITE(fd) FD_ISSET(fd, &slap_daemon.sd_writers)
-
-#define SLAP_SOCK_NOT_ACTIVE(fd)       (!SLAP_SOCK_IS_ACTIVE(fd) && \
+       } else { \
+               FD_ZERO( &writefds ); \
+       } \
+} while (0)
+
+# ifdef FD_SETSIZE
+#  define      CHK_SETSIZE do { \
+       if (dtblsize > FD_SETSIZE) dtblsize = FD_SETSIZE; \
+} while (0)
+# else
+#  define       CHK_SETSIZE do { ; } while (0)
+# endif
+
+# define       SLAP_SOCK_SET_INIT do { \
+       CHK_SETSIZE; \
+       FD_ZERO(&slap_daemon.sd_readers); \
+       FD_ZERO(&slap_daemon.sd_writers); \
+} while (0)
+
+# define SLAP_SOCK_IS_ACTIVE(fd)       FD_ISSET((fd), &slap_daemon.sd_actives)
+# define SLAP_SOCK_IS_READ(fd)         FD_ISSET((fd), &slap_daemon.sd_readers)
+# define SLAP_SOCK_IS_WRITE(fd)                FD_ISSET((fd), &slap_daemon.sd_writers)
+
+# define SLAP_SOCK_NOT_ACTIVE(fd)      (!SLAP_SOCK_IS_ACTIVE(fd) && \
         !SLAP_SOCK_IS_READ(fd) && !SLAP_SOCK_IS_WRITE(fd))
 
-#ifdef HAVE_WINSOCK
-#define SLAP_SOCK_SET_READ(fd) do { \
-       if (!SLAP_SOCK_IS_READ(fd)) {FD_SET(fd, &slap_daemon.sd_readers);}      \
+# ifdef HAVE_WINSOCK
+#  define SLAP_SOCK_SET_READ(fd)       do { \
+       if (!SLAP_SOCK_IS_READ(fd)) { FD_SET((fd), &slap_daemon.sd_readers); } \
 } while(0)
-#define SLAP_SOCK_SET_WRITE(fd)        do { \
-       if (!SLAP_SOCK_IS_WRITE(fd)) {FD_SET(fd, &slap_daemon.sd_writers);}     \
+#  define SLAP_SOCK_SET_WRITE(fd)      do { \
+       if (!SLAP_SOCK_IS_WRITE(fd)) { FD_SET((fd), &slap_daemon.sd_writers); } \
 } while(0)
 
-#define SLAP_ADDTEST(s)
-#define SLAP_EVENT_MAX dtblsize
-#else
-#define SLAP_SOCK_SET_READ(fd) FD_SET(fd, &slap_daemon.sd_readers)
-#define SLAP_SOCK_SET_WRITE(fd)        FD_SET(fd, &slap_daemon.sd_writers)
-
-#define SLAP_EVENT_MAX slap_daemon.sd_nfds
-#define        SLAP_ADDTEST(s) if (s >= slap_daemon.sd_nfds) slap_daemon.sd_nfds = s+1
-#endif
-
-#define SLAP_SOCK_CLR_READ(fd) FD_CLR(fd, &slap_daemon.sd_readers)
-#define SLAP_SOCK_CLR_WRITE(fd)        FD_CLR(fd, &slap_daemon.sd_writers)
-
-#define        SLAP_ADD_SOCK(s, l) do {        \
-       SLAP_ADDTEST(s);        \
-       FD_SET(s, &slap_daemon.sd_actives);     \
-       FD_SET(s, &slap_daemon.sd_readers);     \
+#  define SLAP_ADDTEST(s)      do { } while 0
+#  define SLAP_EVENT_MAX       dtblsize
+# else
+#  define SLAP_SOCK_SET_READ(fd)       FD_SET((fd), &slap_daemon.sd_readers)
+#  define SLAP_SOCK_SET_WRITE(fd)      FD_SET((fd), &slap_daemon.sd_writers)
+
+#  define SLAP_EVENT_MAX       slap_daemon.sd_nfds
+#  define SLAP_ADDTEST(s)      do { \
+       if ((s) >= slap_daemon.sd_nfds) slap_daemon.sd_nfds = (s)+1; \
+} while (0)
+# endif
+
+# define SLAP_SOCK_CLR_READ(fd)                FD_CLR((fd), &slap_daemon.sd_readers)
+# define SLAP_SOCK_CLR_WRITE(fd)       FD_CLR((fd), &slap_daemon.sd_writers)
+
+# define SLAP_ADD_SOCK(s, l) do { \
+       SLAP_ADDTEST((s)); \
+       FD_SET((s), &slap_daemon.sd_actives); \
+       FD_SET((s), &slap_daemon.sd_readers); \
 } while(0)
 
-#define SLAP_DEL_SOCK(s) do {  \
-       FD_CLR(s, &slap_daemon.sd_actives);     \
-       FD_CLR(s, &slap_daemon.sd_readers);     \
-       FD_CLR(s, &slap_daemon.sd_writers);     \
+# define SLAP_DEL_SOCK(s) do { \
+       FD_CLR((s), &slap_daemon.sd_actives); \
+       FD_CLR((s), &slap_daemon.sd_readers); \
+       FD_CLR((s), &slap_daemon.sd_writers); \
 } while(0)
 
-#define SLAP_EVENT_IS_READ(fd) FD_ISSET(fd, &readfds)
-#define SLAP_EVENT_IS_WRITE(fd)        FD_ISSET(fd, &writefds)
-
-#define SLAP_EVENT_CLR_READ(fd)        FD_CLR(fd, &readfds)
-#define SLAP_EVENT_CLR_WRITE(fd)       FD_CLR(fd, &writefds)
+# define SLAP_EVENT_IS_READ(fd)                FD_ISSET((fd), &readfds)
+# define SLAP_EVENT_IS_WRITE(fd)       FD_ISSET((fd), &writefds)
 
-#define SLAP_EVENT_WAIT(tvp)   \
-       select( SLAP_EVENT_MAX, &readfds,       \
-               nwriters > 0 ? &writefds : NULL, NULL, tvp )
-
-#define        SLAP_SOCK_SET_MUTE(s)   FD_CLR(s, &readfds)
-#define SLAP_SOCK_CLR_MUTE(s)  FD_SET(s, &readfds)
-#define        SLAP_SOCK_IS_MUTE(s)    (!FD_ISSET(s, &readfds))
+# define SLAP_EVENT_CLR_READ(fd)       FD_CLR((fd), &readfds)
+# define SLAP_EVENT_CLR_WRITE(fd)      FD_CLR((fd), &writefds)
 
+# define SLAP_EVENT_WAIT(tvp) \
+       select( SLAP_EVENT_MAX, &readfds, \
+               nwriters > 0 ? &writefds : NULL, NULL, (tvp) )
 #endif
 
-
 #ifdef HAVE_SLP
 /*
  * SLP related functions
@@ -426,32 +441,57 @@ static void slapd_add(ber_socket_t s, int isactive, Listener *sl) {
 
        assert( SLAP_SOCK_NOT_ACTIVE(s) );
 
-       if ( isactive ) {
-               slap_daemon.sd_nactives++;
-       }
+       if ( isactive ) slap_daemon.sd_nactives++;
 
        SLAP_ADD_SOCK(s, sl);
 
        Debug( LDAP_DEBUG_CONNS, "daemon: added %ldr\n",
                (long) s, 0, 0 );
+
+       ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+       WAKE_LISTENER(1);
+#endif
+}
+
+void slapd_sd_lock()
+{
+       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+}
+
+void slapd_sd_unlock()
+{
        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
 }
 
 /*
  * Remove the descriptor from daemon control
  */
-void slapd_remove(ber_socket_t s, int wasactive, int wake) {
+void slapd_remove(
+       ber_socket_t s,
+       int wasactive,
+       int wake,
+       int locked )
+{
        int waswriter;
-       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+       int wasreader;
+
+       if ( !locked )
+               ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+
+       assert( SLAP_SOCK_IS_ACTIVE( s ));
+
+       if ( wasactive ) slap_daemon.sd_nactives--;
 
-       if ( wasactive ) {
-               slap_daemon.sd_nactives--;
-       }
        waswriter = SLAP_SOCK_IS_WRITE(s);
+       wasreader = SLAP_SOCK_IS_READ(s);
 
        Debug( LDAP_DEBUG_CONNS, "daemon: removing %ld%s%s\n",
-               (long) s, SLAP_SOCK_IS_READ(s) ? "r" : "",
+               (long) s,
+               wasreader ? "r" : "",
                waswriter ? "w" : "" );
+
        if ( waswriter ) slap_daemon.sd_nwriters--;
 
        SLAP_DEL_SOCK(s);
@@ -463,20 +503,20 @@ void slapd_remove(ber_socket_t s, int wasactive, int wake) {
        if ( emfile ) {
                int i;
                for ( i = 0; slap_listeners[i] != NULL; i++ ) {
-                       if ( slap_listeners[i]->sl_sd != AC_SOCKET_INVALID ) {
-                               if ( slap_listeners[i]->sl_sd == s ) continue;
-                               if ( slap_listeners[i]->sl_is_mute ) {
-                                       slap_listeners[i]->sl_is_mute = 0;
-                                       emfile--;
-                                       break;
-                               }
+                       Listener *lr = slap_listeners[i];
+
+                       if ( lr->sl_sd == AC_SOCKET_INVALID ) continue;
+                       if ( lr->sl_sd == s ) continue;
+                       if ( lr->sl_mute ) {
+                               lr->sl_mute = 0;
+                               emfile--;
+                               break;
                        }
                }
                /* Walked the entire list without enabling anything; emfile
                 * counter is stale. Reset it.
                 */
-               if ( slap_listeners[i] == NULL )
-                       emfile = 0;
+               if ( slap_listeners[i] == NULL ) emfile = 0;
        }
        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
        WAKE_LISTENER(wake || slapd_gentle_shutdown == 2);
@@ -486,6 +526,7 @@ void slapd_clr_write(ber_socket_t s, int wake) {
        ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 
        assert( SLAP_SOCK_IS_ACTIVE( s ));
+
        if ( SLAP_SOCK_IS_WRITE( s )) {
                SLAP_SOCK_CLR_WRITE( s );
                slap_daemon.sd_nwriters--;
@@ -499,6 +540,7 @@ void slapd_set_write(ber_socket_t s, int wake) {
        ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 
        assert( SLAP_SOCK_IS_ACTIVE( s ));
+
        if ( !SLAP_SOCK_IS_WRITE( s )) {
                SLAP_SOCK_SET_WRITE( s );
                slap_daemon.sd_nwriters++;
@@ -508,22 +550,25 @@ void slapd_set_write(ber_socket_t s, int wake) {
        WAKE_LISTENER(wake);
 }
 
-void slapd_clr_read(ber_socket_t s, int wake) {
+int slapd_clr_read(ber_socket_t s, int wake) {
+       int rc = 1;
        ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 
-       assert( SLAP_SOCK_IS_ACTIVE( s ));
-       SLAP_SOCK_CLR_READ( s );
-
+       if ( SLAP_SOCK_IS_ACTIVE( s )) {
+               SLAP_SOCK_CLR_READ( s );
+               rc = 0;
+       }
        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
-       WAKE_LISTENER(wake);
+       if ( !rc )
+               WAKE_LISTENER(wake);
+       return rc;
 }
 
 void slapd_set_read(ber_socket_t s, int wake) {
        ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 
        assert( SLAP_SOCK_IS_ACTIVE( s ));
-       if (!SLAP_SOCK_IS_READ( s ))
-               SLAP_SOCK_SET_READ( s );
+       if (!SLAP_SOCK_IS_READ( s )) SLAP_SOCK_SET_READ( s );
 
        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
        WAKE_LISTENER(wake);
@@ -535,18 +580,10 @@ static void slapd_close(ber_socket_t s) {
        tcp_close(s);
 }
 
-static void slap_free_listener_addresses(struct sockaddr **sal)
-{
+static void slap_free_listener_addresses(struct sockaddr **sal) {
        struct sockaddr **sap;
-
-       if (sal == NULL) {
-               return;
-       }
-
-       for (sap = sal; *sap != NULL; sap++) {
-               ch_free(*sap);
-       }
-
+       if (sal == NULL) return;
+       for (sap = sal; *sap != NULL; sap++) ch_free(*sap);
        ch_free(sal);
 }
 
@@ -572,18 +609,17 @@ static int get_url_perms(
                        type++;
                }
 
-               if ( strncasecmp( type, LDAPI_MOD_URLEXT "=", sizeof(LDAPI_MOD_URLEXT "=") - 1 ) == 0 ) {
-                       char    *value = type
-                               + ( sizeof(LDAPI_MOD_URLEXT "=") - 1 );
-                       mode_t  p = 0;
-                       int     j;
+               if ( strncasecmp( type, LDAPI_MOD_URLEXT "=",
+                       sizeof(LDAPI_MOD_URLEXT "=") - 1 ) == 0 )
+               {
+                       char *value = type + ( sizeof(LDAPI_MOD_URLEXT "=") - 1 );
+                       mode_t p = 0;
+                       int j;
 
                        switch (strlen(value)) {
                        case 4:
                                /* skip leading '0' */
-                               if ( value[ 0 ] != '0' ) {
-                                       return LDAP_OTHER;
-                               }
+                               if ( value[ 0 ] != '0' ) return LDAP_OTHER;
                                value++;
 
                        case 3:
@@ -592,9 +628,7 @@ static int get_url_perms(
 
                                        v = value[ j ] - '0';
 
-                                       if ( v < 0 || v > 7 ) {
-                                               return LDAP_OTHER;
-                                       }
+                                       if ( v < 0 || v > 7 ) return LDAP_OTHER;
 
                                        p |= v << 3*(2-j);
                                }
@@ -644,21 +678,19 @@ static int slap_get_listener_addresses(
 #ifdef LDAP_PF_LOCAL
        if ( port == 0 ) {
                *sal = ch_malloc(2 * sizeof(void *));
-               if (*sal == NULL) {
-                       return -1;
-               }
+               if (*sal == NULL) return -1;
 
                sap = *sal;
                *sap = ch_malloc(sizeof(struct sockaddr_un));
-               if (*sap == NULL)
-                       goto errexit;
+               if (*sap == NULL) goto errexit;
                sap[1] = NULL;
 
                if ( strlen(host) >
-                    (sizeof(((struct sockaddr_un *)*sap)->sun_path) - 1) ) {
+                       (sizeof(((struct sockaddr_un *)*sap)->sun_path) - 1) )
+               {
                        Debug( LDAP_DEBUG_ANY,
-                              "daemon: domain socket path (%s) too long in URL",
-                              host, 0, 0);
+                               "daemon: domain socket path (%s) too long in URL",
+                               host, 0, 0);
                        goto errexit;
                }
 
@@ -680,7 +712,7 @@ static int slap_get_listener_addresses(
                snprintf(serv, sizeof serv, "%d", port);
 
                if ( (err = getaddrinfo(host, serv, &hints, &res)) ) {
-                       Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo failed: %s\n",
+                       Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo() failed: %s\n",
                                AC_GAI_STRERROR(err), 0, 0);
                        return -1;
                }
@@ -690,9 +722,7 @@ static int slap_get_listener_addresses(
                        /* EMPTY */ ;
                }
                *sal = ch_calloc(n, sizeof(void *));
-               if (*sal == NULL) {
-                       return -1;
-               }
+               if (*sal == NULL) return -1;
 
                sap = *sal;
                *sap = NULL;
@@ -739,6 +769,7 @@ static int slap_get_listener_addresses(
                }
 
                freeaddrinfo(res);
+
 #else
                int i, n = 1;
                struct in_addr in;
@@ -751,31 +782,25 @@ static int slap_get_listener_addresses(
                        he = gethostbyname( host );
                        if( he == NULL ) {
                                Debug( LDAP_DEBUG_ANY,
-                                      "daemon: invalid host %s", host, 0, 0);
+                                       "daemon: invalid host %s", host, 0, 0);
                                return -1;
                        }
-                       for (n = 0; he->h_addr_list[n]; n++) ;
+                       for (n = 0; he->h_addr_list[n]; n++) /* empty */;
                }
 
                *sal = ch_malloc((n+1) * sizeof(void *));
-               if (*sal == NULL) {
-                       return -1;
-               }
+               if (*sal == NULL) return -1;
 
                sap = *sal;
                for ( i = 0; i<n; i++ ) {
                        sap[i] = ch_malloc(sizeof(struct sockaddr_in));
-                       if (*sap == NULL) {
-                               goto errexit;
-                       }
+                       if (*sap == NULL) goto errexit;
+
                        (void)memset( (void *)sap[i], '\0', sizeof(struct sockaddr_in) );
                        sap[i]->sa_family = AF_INET;
                        ((struct sockaddr_in *)sap[i])->sin_port = htons(port);
-                       if (he) {
-                               AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr, he->h_addr_list[i], sizeof(struct in_addr) );
-                       } else {
-                               AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr, &in, sizeof(struct in_addr) );
-                       }
+                       AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr,
+                               he ? he->h_addr_list[i] : &in, sizeof(struct in_addr) );
                }
                sap[i] = NULL;
 #endif
@@ -820,20 +845,20 @@ static int slap_open_listener(
        }
 
        l.sl_url.bv_val = NULL;
-       l.sl_is_mute = 0;
+       l.sl_mute = 0;
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+       l.sl_busy = 0;
+#endif
 
 #ifndef HAVE_TLS
        if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "daemon: TLS not supported (%s)\n",
+               Debug( LDAP_DEBUG_ANY, "daemon: TLS not supported (%s)\n",
                        url, 0, 0 );
                ldap_free_urldesc( lud );
                return -1;
        }
 
-       if(! lud->lud_port ) {
-               lud->lud_port = LDAP_PORT;
-       }
+       if(! lud->lud_port ) lud->lud_port = LDAP_PORT;
 
 #else
        l.sl_is_tls = ldap_pvt_url_scheme2tls( lud->lud_scheme );
@@ -869,6 +894,7 @@ static int slap_open_listener(
                        err = slap_get_listener_addresses(lud->lud_host, port, &sal);
                }
        }
+
 #ifdef LDAP_CONNECTIONLESS
        l.sl_is_udp = ( tmp == LDAP_PROTO_UDP );
 #endif
@@ -882,17 +908,16 @@ static int slap_open_listener(
 #endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
 
        ldap_free_urldesc( lud );
-       if ( err ) {
-               return -1;
-       }
+       if ( err ) return -1;
 
        /* If we got more than one address returned, we need to make space
         * for it in the slap_listeners array.
         */
-       for ( num=0; sal[num]; num++ );
+       for ( num=0; sal[num]; num++ ) /* empty */;
        if ( num > 1 ) {
                *listeners += num-1;
-               slap_listeners = ch_realloc( slap_listeners, (*listeners + 1) * sizeof(Listener *) );
+               slap_listeners = ch_realloc( slap_listeners,
+                       (*listeners + 1) * sizeof(Listener *) );
        }
 
        psal = sal;
@@ -916,9 +941,11 @@ static int slap_open_listener(
                        sal++;
                        continue;
                }
+
 #ifdef LDAP_CONNECTIONLESS
                if( l.sl_is_udp ) socktype = SOCK_DGRAM;
 #endif
+
                l.sl_sd = socket( (*sal)->sa_family, socktype, 0);
                if ( l.sl_sd == AC_SOCKET_INVALID ) {
                        int err = sock_errno();
@@ -928,6 +955,7 @@ static int slap_open_listener(
                        sal++;
                        continue;
                }
+
 #ifndef HAVE_WINSOCK
                if ( l.sl_sd >= dtblsize ) {
                        Debug( LDAP_DEBUG_ANY,
@@ -938,9 +966,10 @@ static int slap_open_listener(
                        continue;
                }
 #endif
+
 #ifdef LDAP_PF_LOCAL
                if ( (*sal)->sa_family == AF_LOCAL ) {
-                       unlink ( ((struct sockaddr_un *)*sal)->sun_path );
+                       unlink( ((struct sockaddr_un *)*sal)->sun_path );
                } else
 #endif
                {
@@ -951,9 +980,9 @@ static int slap_open_listener(
                                (char *) &tmp, sizeof(tmp) );
                        if ( rc == AC_SOCKET_ERROR ) {
                                int err = sock_errno();
-                               Debug( LDAP_DEBUG_ANY,
-                                      "slapd(%ld): setsockopt(SO_REUSEADDR) failed errno=%d (%s)\n",
-                                      (long) l.sl_sd, err, sock_errstr(err) );
+                               Debug( LDAP_DEBUG_ANY, "slapd(%ld): "
+                                       "setsockopt(SO_REUSEADDR) failed errno=%d (%s)\n",
+                                       (long) l.sl_sd, err, sock_errstr(err) );
                        }
 #endif
                }
@@ -968,17 +997,18 @@ static int slap_open_listener(
                        /* Try to use IPv6 sockets for IPv6 only */
                        tmp = 1;
                        rc = setsockopt( l.sl_sd, IPPROTO_IPV6, IPV6_V6ONLY,
-                                        (char *) &tmp, sizeof(tmp) );
+                               (char *) &tmp, sizeof(tmp) );
                        if ( rc == AC_SOCKET_ERROR ) {
                                int err = sock_errno();
-                               Debug( LDAP_DEBUG_ANY,
-                                      "slapd(%ld): setsockopt(IPV6_V6ONLY) failed errno=%d (%s)\n",
-                                      (long) l.sl_sd, err, sock_errstr(err) );
+                               Debug( LDAP_DEBUG_ANY, "slapd(%ld): "
+                                       "setsockopt(IPV6_V6ONLY) failed errno=%d (%s)\n",
+                                       (long) l.sl_sd, err, sock_errstr(err) );
                        }
 #endif
                        addrlen = sizeof(struct sockaddr_in6);
                        break;
 #endif
+
 #ifdef LDAP_PF_LOCAL
                case AF_LOCAL:
 #ifdef LOCAL_CREDS
@@ -994,82 +1024,97 @@ static int slap_open_listener(
 
                if (bind(l.sl_sd, *sal, addrlen)) {
                        err = sock_errno();
-               Debug( LDAP_DEBUG_ANY, "daemon: bind(%ld) failed errno=%d (%s)\n",
-                      (long) l.sl_sd, err, sock_errstr(err) );
+                       Debug( LDAP_DEBUG_ANY,
+                               "daemon: bind(%ld) failed errno=%d (%s)\n",
+                               (long) l.sl_sd, err, sock_errstr(err) );
                        tcp_close( l.sl_sd );
                        sal++;
                        continue;
                }
 
-       switch ( (*sal)->sa_family ) {
+               switch ( (*sal)->sa_family ) {
 #ifdef LDAP_PF_LOCAL
-       case AF_LOCAL: {
-               char *addr = ((struct sockaddr_un *)*sal)->sun_path;
-               l.sl_name.bv_len = strlen(addr) + sizeof("PATH=") - 1;
-               l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len + 1 );
-               snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1, 
+               case AF_LOCAL: {
+                       char *addr = ((struct sockaddr_un *)*sal)->sun_path;
+                       l.sl_name.bv_len = strlen(addr) + sizeof("PATH=") - 1;
+                       l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len + 1 );
+                       snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1, 
                                "PATH=%s", addr );
-       } break;
+               } break;
 #endif /* LDAP_PF_LOCAL */
 
-       case AF_INET: {
-               char *s;
+               case AF_INET: {
+                       char *s;
 #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
-               char addr[INET_ADDRSTRLEN];
-               inet_ntop( AF_INET, &((struct sockaddr_in *)*sal)->sin_addr,
-                          addr, sizeof(addr) );
-               s = addr;
+                       char addr[INET_ADDRSTRLEN];
+                       inet_ntop( AF_INET, &((struct sockaddr_in *)*sal)->sin_addr,
+                               addr, sizeof(addr) );
+                       s = addr;
 #else
-               s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr );
+                       s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr );
 #endif
-               port = ntohs( ((struct sockaddr_in *)*sal) ->sin_port );
-               l.sl_name.bv_val = ber_memalloc( sizeof("IP=255.255.255.255:65535") );
-               snprintf( l.sl_name.bv_val, sizeof("IP=255.255.255.255:65535"),
-                       "IP=%s:%d",
-                        s != NULL ? s : SLAP_STRING_UNKNOWN, port );
-               l.sl_name.bv_len = strlen( l.sl_name.bv_val );
-       } break;
+                       port = ntohs( ((struct sockaddr_in *)*sal) ->sin_port );
+                       l.sl_name.bv_val =
+                               ber_memalloc( sizeof("IP=255.255.255.255:65535") );
+                       snprintf( l.sl_name.bv_val, sizeof("IP=255.255.255.255:65535"),
+                               "IP=%s:%d",
+                                s != NULL ? s : SLAP_STRING_UNKNOWN, port );
+                       l.sl_name.bv_len = strlen( l.sl_name.bv_val );
+               } break;
 
 #ifdef LDAP_PF_INET6
-       case AF_INET6: {
-               char addr[INET6_ADDRSTRLEN];
-               inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr,
-                          addr, sizeof addr);
-               port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
-               l.sl_name.bv_len = strlen(addr) + sizeof("IP= 65535");
-               l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len );
-               snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=%s %d", 
+               case AF_INET6: {
+                       char addr[INET6_ADDRSTRLEN];
+                       inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr,
+                               addr, sizeof addr);
+                       port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
+                       l.sl_name.bv_len = strlen(addr) + sizeof("IP= 65535");
+                       l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len );
+                       snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=%s %d", 
                                addr, port );
-               l.sl_name.bv_len = strlen( l.sl_name.bv_val );
-       } break;
+                       l.sl_name.bv_len = strlen( l.sl_name.bv_val );
+               } break;
 #endif /* LDAP_PF_INET6 */
 
-       default:
-               Debug( LDAP_DEBUG_ANY, "daemon: unsupported address family (%d)\n",
-                       (int) (*sal)->sa_family, 0, 0 );
-               break;
-       }
-
-       AC_MEMCPY(&l.sl_sa, *sal, addrlen);
-       ber_str2bv( url, 0, 1, &l.sl_url);
-       li = ch_malloc( sizeof( Listener ) );
-       *li = l;
-       slap_listeners[*cur] = li;
-       (*cur)++;
-       sal++;
+               default:
+                       Debug( LDAP_DEBUG_ANY, "daemon: unsupported address family (%d)\n",
+                               (int) (*sal)->sa_family, 0, 0 );
+                       break;
+               }
 
-       } /* while ( *sal != NULL ) */
+               AC_MEMCPY(&l.sl_sa, *sal, addrlen);
+               ber_str2bv( url, 0, 1, &l.sl_url);
+               li = ch_malloc( sizeof( Listener ) );
+               *li = l;
+               slap_listeners[*cur] = li;
+               (*cur)++;
+               sal++;
+       }
 
        slap_free_listener_addresses(psal);
 
-       if ( l.sl_url.bv_val == NULL )
-       {
+       if ( l.sl_url.bv_val == NULL ) {
                Debug( LDAP_DEBUG_TRACE,
                        "slap_open_listener: failed on %s\n", url, 0, 0 );
                return -1;
        }
 
-       Debug( LDAP_DEBUG_TRACE, "daemon: initialized %s\n",
+#ifdef LDAP_CONNECTIONLESS
+       if( l.sl_is_udp ) {
+               long id = connection_init( l.sl_sd, &l, "", "", CONN_IS_UDP,
+                       (slap_ssf_t) 0, NULL );
+
+               if( id < 0 ) {
+                       Debug( LDAP_DEBUG_TRACE,
+                               "slap_open_listener: connectionless init failed on %s (%d)\n",
+                               url, l.sl_sd, 0 );
+                       return -1;
+               }
+               l.sl_is_udp++;
+       }
+#endif
+
+       Debug( LDAP_DEBUG_TRACE, "daemon: listener initialized %s\n",
                l.sl_url.bv_val, 0, 0 );
        return 0;
 }
@@ -1084,9 +1129,7 @@ int slapd_daemon_init( const char *urls )
 
        Debug( LDAP_DEBUG_ARGS, "daemon_init: %s\n",
                urls ? urls : "<null>", 0, 0 );
-       if( (rc = sockinit()) != 0 ) {
-               return rc;
-       }
+       if( (rc = sockinit()) != 0 ) return rc;
 
 #ifdef HAVE_SYSCONF
        dtblsize = sysconf( _SC_OPEN_MAX );
@@ -1109,9 +1152,7 @@ int slapd_daemon_init( const char *urls )
 
        SLAP_SOCK_SET_INIT;
 
-       if( urls == NULL ) {
-               urls = "ldap:///";
-       }
+       if( urls == NULL ) urls = "ldap:///";
 
        u = ldap_str2charray( urls, " " );
 
@@ -1148,6 +1189,7 @@ int slapd_daemon_init( const char *urls )
        Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners opened\n",
                i, 0, 0 );
 
+
 #ifdef HAVE_SLP
        if( slapd_register_slp ) {
                slapd_slp_init( urls );
@@ -1157,6 +1199,11 @@ int slapd_daemon_init( const char *urls )
 
        ldap_charray_free( u );
        ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex );
+
+#ifdef HAVE_TCPD
+       ldap_pvt_thread_mutex_init( &slap_daemon.tcpd_mutex );
+#endif
+
        return !i;
 }
 
@@ -1176,41 +1223,52 @@ slapd_daemon_destroy(void)
        }
 #endif
 
+#ifdef HAVE_TCPD
+       ldap_pvt_thread_mutex_destroy( &slap_daemon.tcpd_mutex );
+#endif
+
+       ldap_pvt_thread_mutex_destroy( &slap_daemon.sd_mutex );
        return 0;
 }
 
 
 static void
 close_listeners(
-       int remove
-)
+       int remove )
 {
        int l;
 
        for ( l = 0; slap_listeners[l] != NULL; l++ ) {
-               if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) {
-                       if ( remove )
-                               slapd_remove( slap_listeners[l]->sl_sd, 0, 0 );
+               Listener *lr = slap_listeners[l];
+
+               if ( lr->sl_sd != AC_SOCKET_INVALID ) {
+                       if ( remove ) slapd_remove( lr->sl_sd, 0, 0, 0 );
+
 #ifdef LDAP_PF_LOCAL
-                       if ( slap_listeners[l]->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
-                               unlink( slap_listeners[l]->sl_sa.sa_un_addr.sun_path );
+                       if ( lr->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
+                               unlink( lr->sl_sa.sa_un_addr.sun_path );
                        }
 #endif /* LDAP_PF_LOCAL */
-                       slapd_close( slap_listeners[l]->sl_sd );
+
+                       slapd_close( lr->sl_sd );
                }
-               if ( slap_listeners[l]->sl_url.bv_val )
-                       ber_memfree( slap_listeners[l]->sl_url.bv_val );
-               if ( slap_listeners[l]->sl_name.bv_val )
-                       ber_memfree( slap_listeners[l]->sl_name.bv_val );
-               free ( slap_listeners[l] );
+
+               if ( lr->sl_url.bv_val ) {
+                       ber_memfree( lr->sl_url.bv_val );
+               }
+
+               if ( lr->sl_name.bv_val ) {
+                       ber_memfree( lr->sl_name.bv_val );
+               }
+
+               free( lr );
                slap_listeners[l] = NULL;
        }
 }
 
 static int
-slapd_handle_listener(
-       Listener *sl
-)
+slap_listener(
+       Listener *sl )
 {
        Sockaddr                from;
 
@@ -1236,18 +1294,7 @@ slapd_handle_listener(
        peername[0] = '\0';
 
 #ifdef LDAP_CONNECTIONLESS
-       if ( sl->sl_is_udp ) {
-               /* The first time we receive a query, we set this
-                * up as a "connection". It remains open for the life
-                * of the slapd.
-                */
-               if ( sl->sl_is_udp < 2 ) {
-                       id = connection_init( sl->sl_sd, sl, "", "",
-                               CONN_IS_UDP, ssf, NULL );
-                   sl->sl_is_udp++;
-               }
-               return 1;
-       }
+       if ( sl->sl_is_udp ) return 1;
 #endif
 
 #  ifdef LDAP_PF_LOCAL
@@ -1257,6 +1304,15 @@ slapd_handle_listener(
 #  endif /* LDAP_PF_LOCAL */
 
        s = accept( sl->sl_sd, (struct sockaddr *) &from, &len );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+       /* Resume the listener FD to allow concurrent-processing of
+        * additional incoming connections.
+        */
+       sl->sl_busy = 0;
+       WAKE_LISTENER(1);
+#endif
+
        if ( s == AC_SOCKET_INVALID ) {
                int err = sock_errno();
 
@@ -1272,14 +1328,13 @@ slapd_handle_listener(
                        ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
                        emfile++;
                        /* Stop listening until an existing session closes */
-                       sl->sl_is_mute = 1;
+                       sl->sl_mute = 1;
                        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
                }
 
                Debug( LDAP_DEBUG_ANY,
                        "daemon: accept(%ld) failed errno=%d (%s)\n",
-                       (long) sl->sl_sd, err,
-                       sock_errstr(err) );
+                       (long) sl->sl_sd, err, sock_errstr(err) );
                ldap_pvt_thread_yield();
                return 0;
        }
@@ -1299,10 +1354,8 @@ slapd_handle_listener(
 
 #ifdef LDAP_DEBUG
        ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
-
        /* newly accepted stream should not be in any of the FD SETS */
        assert( SLAP_SOCK_NOT_ACTIVE( s ));
-
        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
 #endif
 
@@ -1341,8 +1394,10 @@ slapd_handle_listener(
        }
 #endif
 
-       Debug( LDAP_DEBUG_CONNS, "daemon: new connection on %ld\n",
-               (long) s, 0, 0 );
+       Debug( LDAP_DEBUG_CONNS,
+               "daemon: listen=%ld, new connection on %ld\n",
+               (long) sl->sl_sd, (long) s, 0 );
+
        switch ( from.sa_addr.sa_family ) {
 #  ifdef LDAP_PF_LOCAL
        case AF_LOCAL:
@@ -1414,7 +1469,9 @@ slapd_handle_listener(
 #ifdef LDAP_PF_INET6
                || ( from.sa_addr.sa_family == AF_INET6 )
 #endif
-       ) {
+               )
+       {
+               dnsname = NULL;
 #ifdef SLAPD_RLOOKUPS
                if ( use_reverse_lookup ) {
                        char *herr;
@@ -1424,25 +1481,28 @@ slapd_handle_listener(
                                dnsname = hbuf;
                        }
                }
-#else
-               dnsname = NULL;
 #endif /* SLAPD_RLOOKUPS */
 
 #ifdef HAVE_TCPD
-               if ( !hosts_ctl("slapd",
-                               dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
-                               peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
-                               SLAP_STRING_UNKNOWN ))
                {
-                       /* DENY ACCESS */
-                       Statslog( LDAP_DEBUG_STATS,
-                               "fd=%ld DENIED from %s (%s)\n",
-                               (long) s,
+                       int rc;
+                       ldap_pvt_thread_mutex_lock( &slap_daemon.tcpd_mutex );
+                       rc = hosts_ctl("slapd",
                                dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
                                peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
-                               0, 0 );
-                       slapd_close(s);
-                       return 0;
+                               SLAP_STRING_UNKNOWN );
+                       ldap_pvt_thread_mutex_unlock( &slap_daemon.tcpd_mutex );
+                       if ( !rc ) {
+                               /* DENY ACCESS */
+                               Statslog( LDAP_DEBUG_STATS,
+                                       "fd=%ld DENIED from %s (%s)\n",
+                                       (long) s,
+                                       dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
+                                       peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
+                                       0, 0 );
+                               slapd_close(s);
+                               return 0;
+                       }
                }
 #endif /* HAVE_TCPD */
        }
@@ -1473,17 +1533,56 @@ slapd_handle_listener(
                id, (long) s, peername, sl->sl_name.bv_val,
                0 );
 
-       slapd_add( s, 1, NULL );
        return 0;
 }
 
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+static void*
+slap_listener_thread(
+       void* ctx,
+       void* ptr )
+{
+       int rc;
+
+       rc = slap_listener( (Listener*)ptr );
+
+       if( rc != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "listener_thread: failed %d", rc, 0, 0 );
+       }
+
+       return (void*)NULL;
+}
+
+static int
+slap_listener_activate(
+       Listener* sl )
+{
+       int rc;
+
+       Debug( LDAP_DEBUG_TRACE, "slap_listener_activate(%d): %s\n",
+               sl->sl_sd, sl->sl_busy ? "busy" : "", 0 );
+
+       sl->sl_busy++;
+
+       rc = ldap_pvt_thread_pool_submit( &connection_pool,
+               slap_listener_thread, (void *) sl );
+
+       if( rc != 0 ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "listener_activate(%d): submit failed (%d)\n",
+                       sl->sl_sd, rc, 0 );
+       }
+       return rc;
+}
+#endif
+
 static void *
 slapd_daemon_task(
-       void *ptr
-)
+       void *ptr )
 {
        int l;
-       time_t  last_idle_check = 0;
+       time_t last_idle_check = 0;
        struct timeval idle;
        int ebadf = 0;
 
@@ -1495,8 +1594,9 @@ slapd_daemon_task(
                 * Don't just truncate, preserve the fractions of
                 * seconds to prevent sleeping for zero time.
                 */
-               idle.tv_sec = global_idletimeout/SLAPD_IDLE_CHECK_LIMIT;
-               idle.tv_usec = global_idletimeout - idle.tv_sec * SLAPD_IDLE_CHECK_LIMIT;
+               idle.tv_sec = global_idletimeout / SLAPD_IDLE_CHECK_LIMIT;
+               idle.tv_usec = global_idletimeout - \
+                       ( idle.tv_sec * SLAPD_IDLE_CHECK_LIMIT );
                idle.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT;
        } else {
                idle.tv_sec = 0;
@@ -1506,8 +1606,8 @@ slapd_daemon_task(
        slapd_add( wake_sds[0], 0, NULL );
 
        for ( l = 0; slap_listeners[l] != NULL; l++ ) {
-               if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
-                       continue;
+               if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue;
+
 #ifdef LDAP_CONNECTIONLESS
                /* Since this is connectionless, the data port is the
                 * listening port. The listen() and accept() calls
@@ -1537,15 +1637,19 @@ slapd_daemon_task(
                                        for ( i = 0 ; i < l; i++ ) {
                                                sa6 = slap_listeners[i]->sl_sa.sa_in6_addr;
                                                if ( sa6.sin6_family == AF_INET6 &&
-                                                    !memcmp( &sa6.sin6_addr, &in6addr_any, sizeof(struct in6_addr) ) )
+                                                    !memcmp( &sa6.sin6_addr, &in6addr_any,
+                                                               sizeof(struct in6_addr) ) )
+                                               {
                                                        break;
+                                               }
                                        }
 
                                        if ( i < l ) {
                                                /* We are already listening to in6addr_any */
                                                Debug( LDAP_DEBUG_CONNS,
-                                                      "daemon: Attempt to listen to 0.0.0.0 failed, already listening on ::, assuming IPv4 included\n",
-                                                      0, 0, 0 );
+                                                       "daemon: Attempt to listen to 0.0.0.0 failed, "
+                                                       "already listening on ::, assuming IPv4 included\n",
+                                                       0, 0, 0 );
                                                slapd_close( slap_listeners[l]->sl_sd );
                                                slap_listeners[l]->sl_sd = AC_SOCKET_INVALID;
                                                continue;
@@ -1557,17 +1661,38 @@ slapd_daemon_task(
                                "daemon: listen(%s, 5) failed errno=%d (%s)\n",
                                        slap_listeners[l]->sl_url.bv_val, err,
                                        sock_errstr(err) );
-                       return( (void*)-1 );
+                       return (void*)-1;
                }
 
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+               /* make the listening socket non-blocking */
+               if ( ber_pvt_socket_set_nonblock( slap_listeners[l]->sl_sd, 1 ) < 0 ) {
+                       Debug( LDAP_DEBUG_ANY, "slapd_daemon_task: "
+                               "set nonblocking on a listening socket failed\n",
+                               0, 0, 0 );
+                       slapd_shutdown = 2;
+                       return (void*)-1;
+               }
+#endif
+
                slapd_add( slap_listeners[l]->sl_sd, 0, slap_listeners[l] );
        }
 
 #ifdef HAVE_NT_SERVICE_MANAGER
-       if ( started_event != NULL ) {
+       if ( started_event != NULL ) }
                ldap_pvt_thread_cond_signal( &started_event );
        }
 #endif
+
+#ifdef SLAP_SEM_LOAD_CONTROL
+       /*
+        * initialize count and lazyness of a semaphore
+        */
+       (void) ldap_lazy_sem_init(
+               SLAP_MAX_WORKER_THREADS + 4 /* max workers + margin */,
+               4 /* lazyness */ );
+#endif
+
        /* initialization complete. Here comes the loop. */
 
        while ( !slapd_shutdown ) {
@@ -1620,28 +1745,34 @@ slapd_daemon_task(
                        }
                }
 #endif
-
                at = 0;
 
                ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 
                nwriters = slap_daemon.sd_nwriters;
-               SLAP_EVENT_INIT;
 
                for ( l = 0; slap_listeners[l] != NULL; l++ ) {
-                       if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
-                               continue;
-                       if ( slap_listeners[l]->sl_is_mute )
-                               SLAP_SOCK_SET_MUTE( slap_listeners[l]->sl_sd );
-                       else
-                       if ( SLAP_SOCK_IS_MUTE( slap_listeners[l]->sl_sd ))
-                           SLAP_SOCK_CLR_MUTE( slap_listeners[l]->sl_sd );
+                       Listener *lr = slap_listeners[l];
+
+                       if ( lr->sl_sd == AC_SOCKET_INVALID ) continue;
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+                       if ( lr->sl_mute || lr->sl_busy )
+#else
+                       if ( lr->sl_mute )
+#endif
+                       {
+                           SLAP_SOCK_CLR_READ( lr->sl_sd );
+                       } else {
+                               SLAP_SOCK_SET_READ( lr->sl_sd );
+                       }
                }
 
+               SLAP_EVENT_INIT;
+
                nfds = SLAP_EVENT_MAX;
 
-               if ( global_idletimeout && slap_daemon.sd_nactives )
-                       at = 1;
+               if ( global_idletimeout && slap_daemon.sd_nactives ) at = 1;
 
                ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
 
@@ -1650,9 +1781,11 @@ slapd_daemon_task(
                        &&  ( tv.tv_sec || tv.tv_usec )
 #endif
                        )
+               {
                        tvp = &tv;
-               else
+               } else {
                        tvp = NULL;
+               }
 
                ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
                rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
@@ -1673,8 +1806,7 @@ slapd_daemon_task(
 
                if ( cat && cat->tv_sec ) {
                        time_t diff = difftime( cat->tv_sec, now );
-                       if ( diff == 0 )
-                               diff = tdelta;
+                       if ( diff == 0 ) diff = tdelta;
                        if ( tvp == NULL || diff < tv.tv_sec ) {
                                tv.tv_sec = diff;
                                tv.tv_usec = 0;
@@ -1683,18 +1815,34 @@ slapd_daemon_task(
                }
 
                for ( l = 0; slap_listeners[l] != NULL; l++ ) {
-                       if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ||
-                           slap_listeners[l]->sl_is_mute )
+                       Listener *lr = slap_listeners[l];
+
+                       if ( lr->sl_sd == AC_SOCKET_INVALID ) {
                                continue;
+                       }
+
+                       if ( lr->sl_mute ) {
+                               Debug( LDAP_DEBUG_CONNS,
+                                       "daemon: select: listen=%d muted\n",
+                                       lr->sl_sd, 0, 0 );
+                               continue;
+                       }
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+                       if ( lr->sl_busy ) {
+                               Debug( LDAP_DEBUG_CONNS,
+                                       "daemon: select: listen=%d busy\n",
+                                       lr->sl_sd, 0, 0 );
+                               continue;
+                       }
+#endif
 
                        Debug( LDAP_DEBUG_CONNS,
                                "daemon: select: listen=%d active_threads=%d tvp=%s\n",
-                                       slap_listeners[l]->sl_sd, at,
-                                       tvp == NULL ? "NULL" : "zero" );
+                               lr->sl_sd, at, tvp == NULL ? "NULL" : "zero" );
                }
 
-               switch(ns = SLAP_EVENT_WAIT(tvp))
-               {
+               switch(ns = SLAP_EVENT_WAIT(tvp)) {
                case -1: {      /* failure - try again */
                                int err = sock_errno();
 
@@ -1731,18 +1879,22 @@ slapd_daemon_task(
                        if( slapd_shutdown ) continue;
 
                        ebadf = 0;
-                       Debug( LDAP_DEBUG_CONNS, "daemon: activity on %d descriptors\n",
-                               ns, 0, 0 );
+                       Debug( LDAP_DEBUG_CONNS,
+                               "daemon: activity on %d descriptor%s\n",
+                               ns, ns != 1 ? "s" : "", 0 );
                        /* FALL THRU */
                }
 
 #if SLAP_EVENTS_ARE_INDEXED
                if ( SLAP_EVENT_IS_READ( wake_sds[0] )) {
-                       char c[BUFSIZ];
-                       tcp_read( wake_sds[0], c, sizeof(c) );
-                       waking = 0;
-                       ns--;
                        SLAP_EVENT_CLR_READ( wake_sds[0] );
+                       ns--;
+                       {
+                               char c[BUFSIZ];
+                               tcp_read( wake_sds[0], c, sizeof(c) );
+                       }
+                       Debug( LDAP_DEBUG_CONNS, "daemon: waked\n", 0, 0, 0 );
+                       waking = 0;
                        continue;
                }
 
@@ -1754,25 +1906,22 @@ slapd_daemon_task(
                        int rc;
 
                        if ( ns <= 0 ) break;
-
-                       if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
-                               continue;
-
-                       if ( !SLAP_EVENT_IS_READ( slap_listeners[l]->sl_sd ))
-                               continue;
-                       
-                       rc = slapd_handle_listener(slap_listeners[l]);
-
+                       if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue;
 #ifdef LDAP_CONNECTIONLESS
-                       /* This is a UDP session, let the data loop process it */
-                       if ( rc ) continue;
+                       if ( slap_listeners[l]->sl_is_udp ) continue;
 #endif
-
-                       ns--;
-
-                       /* Don't need to look at this in the data loops */
+                       if ( !SLAP_EVENT_IS_READ( slap_listeners[l]->sl_sd )) continue;
+                       
+                       /* clear events */
                        SLAP_EVENT_CLR_READ( slap_listeners[l]->sl_sd );
                        SLAP_EVENT_CLR_WRITE( slap_listeners[l]->sl_sd );
+                       ns--;
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+                       rc = slap_listener_activate(slap_listeners[l]);
+#else
+                       rc = slap_listener(slap_listeners[l]);
+#endif
                }
 
                /* bypass the following tests if no descriptors left */
@@ -1824,29 +1973,31 @@ slapd_daemon_task(
 
 
                /* loop through the writers */
-               for ( i = 0; nwfds > 0; i++ )
-               {
+               for ( i = 0; nwfds > 0; i++ ) {
                        ber_socket_t wd;
 #ifdef HAVE_WINSOCK
                        wd = writefds.fd_array[i];
 #else
-                       if( ! SLAP_EVENT_IS_WRITE( i ) ) {
-                               continue;
-                       }
+                       if( ! SLAP_EVENT_IS_WRITE( i ) ) continue;
                        wd = i;
 #endif
+
+                       SLAP_EVENT_CLR_WRITE( wd );
                        nwfds--;
 
                        Debug( LDAP_DEBUG_CONNS,
                                "daemon: write active on %d\n",
                                wd, 0, 0 );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+                       connection_write_activate( wd );
+#else
                        /*
                         * NOTE: it is possible that the connection was closed
                         * and that the stream is now inactive.
-                        * connection_write() must valid the stream is still
+                        * connection_write() must validate the stream is still
                         * active.
                         */
-
                        if ( connection_write( wd ) < 0 ) {
                                if ( SLAP_EVENT_IS_READ( wd )) {
                                        SLAP_EVENT_CLR_READ( (unsigned) wd );
@@ -1854,20 +2005,18 @@ slapd_daemon_task(
                                }
                                slapd_close( wd );
                        }
-                       SLAP_EVENT_CLR_WRITE( wd );
+#endif
                }
 
-               for ( i = 0; nrfds > 0; i++ )
-               {
+               for ( i = 0; nrfds > 0; i++ ) {
                        ber_socket_t rd;
 #ifdef HAVE_WINSOCK
                        rd = readfds.fd_array[i];
 #else
-                       if( ! SLAP_EVENT_IS_READ( i ) ) {
-                               continue;
-                       }
+                       if( ! SLAP_EVENT_IS_READ( i ) ) continue;
                        rd = i;
 #endif
+                       SLAP_EVENT_CLR_READ( rd );
                        nrfds--;
 
                        Debug ( LDAP_DEBUG_CONNS,
@@ -1879,9 +2028,13 @@ slapd_daemon_task(
                         * active.
                         */
 
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+                       connection_read_activate( rd );
+#else
                        if ( connection_read( rd ) < 0 ) {
                                slapd_close( rd );
                        }
+#endif
                }
 #else  /* !SLAP_EVENTS_ARE_INDEXED */
        /* FIXME */
@@ -1896,33 +2049,28 @@ slapd_daemon_task(
         * an event, so we could use pointers to the listener structure
         * instead of just the file descriptor. For /dev/poll we have to
         * search the listeners array for a matching descriptor.
+        *
+        * We now handle wake events when we see them; they are not given
+        * higher priority.
         */
-               /* if waking is set and we woke up, we'll read whatever
-                * we can.
-                */
-               if ( waking ) {
-                       char c[BUFSIZ];
-                       tcp_read( wake_sds[0], c, sizeof(c) );
-                       waking = 0;
-                       ns--;
-                       continue;
-               }
-
 #ifdef LDAP_DEBUG
                Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
 
                for (i=0; i<ns; i++) {
                        int     r, w;
 
+                       /* Don't log listener events */
                        if ( SLAP_EVENT_IS_LISTENER(i)
 #ifdef LDAP_CONNECTIONLESS
-                       && !((SLAP_EVENT_LISTENER(i))->sl_is_udp)
+                               && !((SLAP_EVENT_LISTENER(i))->sl_is_udp)
 #endif
-                        ) continue;
+                               )
+                       {
+                               continue;
+                       }
 
                        /* Don't log internal wake events */
-                       if ( SLAP_EVENT_FD( i ) == wake_sds[0] )
-                               continue;
+                       if ( SLAP_EVENT_FD( i ) == wake_sds[0] ) continue;
 
                        r = SLAP_EVENT_IS_READ( i );
                        w = SLAP_EVENT_IS_WRITE( i );
@@ -1931,13 +2079,20 @@ slapd_daemon_task(
                                    r ? "r" : "", w ? "w" : "" );
                        }
                }
+               Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
 #endif
+
                for (i=0; i<ns; i++) {
                        int rc = 1, fd;
 
                        if ( SLAP_EVENT_IS_LISTENER(i) ) {
-                               rc = slapd_handle_listener( SLAP_EVENT_LISTENER( i ));
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+                               rc = slap_listener_activate( SLAP_EVENT_LISTENER( i ));
+#else
+                               rc = slap_listener( SLAP_EVENT_LISTENER( i ));
+#endif
                        }
+
                        /* If we found a regular listener, rc is now zero, and we
                         * can skip the data portion. But if it was a UDP listener
                         * then rc is still 1, and we want to handle the data.
@@ -1945,40 +2100,50 @@ slapd_daemon_task(
                        if ( rc ) {
                                fd = SLAP_EVENT_FD( i );
 
-                               /* Ignore wake events, they were handled above */
-                               if ( fd == wake_sds[0] )
-                                       continue;
+                               /* Handle wake events */
+                               if ( fd == wake_sds[0] ) {
+                                       char c[BUFSIZ];
+                                       tcp_read( wake_sds[0], c, sizeof(c) );
+                                       waking = 0;
+                                       break;
+                               }
 
                                if( SLAP_EVENT_IS_WRITE( i ) ) {
                                        Debug( LDAP_DEBUG_CONNS,
                                                "daemon: write active on %d\n",
                                                fd, 0, 0 );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+                                       connection_write_activate( fd );
+#else
                                        /*
                                         * NOTE: it is possible that the connection was closed
                                         * and that the stream is now inactive.
                                         * connection_write() must valid the stream is still
                                         * active.
                                         */
-
                                        if ( connection_write( fd ) < 0 ) {
                                                slapd_close( fd );
                                                continue;
                                        }
+#endif
                                }
                                if( SLAP_EVENT_IS_READ( i ) ) {
                                        Debug( LDAP_DEBUG_CONNS,
                                                "daemon: read active on %d\n",
                                                fd, 0, 0 );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+                                       connection_read_activate( fd );
+#else
                                        /*
                                         * NOTE: it is possible that the connection was closed
                                         * and that the stream is now inactive.
                                         * connection_read() must valid the stream is still
                                         * active.
                                         */
-
-                                       if ( connection_read( fd ) < 0 ) {
-                                               slapd_close( fd );
-                                       }
+                                       if ( connection_read( fd ) < 0 ) slapd_close( fd );
+#endif
                                }
                        }
                }
@@ -2010,9 +2175,7 @@ slapd_daemon_task(
                       0, 0, 0 );
        }
 
-       if( slapd_gentle_shutdown != 2 ) {
-               close_listeners ( 0 );
-       }
+       if( slapd_gentle_shutdown != 2 ) close_listeners ( 0 );
 
        if( !slapd_gentle_shutdown ) {
                slapd_abrupt_shutdown = 1;
@@ -2098,10 +2261,9 @@ static int sockinit(void)
        /* The WinSock DLL is acceptable. Proceed. */
 #elif defined( HAVE_WINSOCK )
        WSADATA wsaData;
-       if ( WSAStartup( 0x0101, &wsaData ) != 0 ) {
-           return -1;
-       }
+       if ( WSAStartup( 0x0101, &wsaData ) != 0 ) return -1;
 #endif
+
        return 0;
 }
 
@@ -2127,16 +2289,19 @@ slap_sig_shutdown( int sig )
         */
 
 #if HAVE_NT_SERVICE_MANAGER && SIGBREAK
-       if (is_NT_Service && sig == SIGBREAK)
-               ;
-       else
+       if (is_NT_Service && sig == SIGBREAK) {
+               /* empty */;
+       else
 #endif
 #ifdef SIGHUP
-       if (sig == SIGHUP && global_gentlehup && slapd_gentle_shutdown == 0)
+       if (sig == SIGHUP && global_gentlehup && slapd_gentle_shutdown == 0) {
                slapd_gentle_shutdown = 1;
-       else
+       else
 #endif
-       slapd_shutdown = 1;
+       {
+               slapd_shutdown = 1;
+       }
+
        WAKE_LISTENER(1);
 
        /* reinstall self */
@@ -2161,7 +2326,6 @@ Listener ** slapd_get_listeners(void) {
        return slap_listeners;
 }
 
-void slap_wake_listener()
-{
+void slap_wake_listener() {
        WAKE_LISTENER(1);
 }
index 51bb8d7902d706a95343559cad1285413d9c143e..078505cd221eaf2affd0cff80b67fd9a364f7e62 100644 (file)
@@ -91,8 +91,6 @@ do_delete(
        rs->sr_err = frontendDB->be_delete( op, rs );
 
 cleanup:;
-       slap_graduate_commit_csn( op );
-
        op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
        op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
        return rs->sr_err;
@@ -174,12 +172,6 @@ fe_op_delete( Operation *op, SlapReply *rs )
 
                        op->o_bd = op_be;
 
-                       if ( !repl_user ) {
-                               struct berval csn = BER_BVNULL;
-                               char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
-                               slap_get_csn( op, csnbuf, sizeof(csnbuf), &csn, 1 );
-                       }
-
 #ifdef SLAPD_MULTIMASTER
                        if ( !op->o_bd->be_update_ndn.bv_len || !repl_user )
 #endif
index bef3b965604c05eb7a7da277da331cd659850258..894de43f5254487a57612ce135bf752c9eef7942 100644 (file)
@@ -248,7 +248,7 @@ done:;
 
 int
 load_extop(
-       struct berval *ext_oid,
+       const struct berval *ext_oid,
        slap_mask_t ext_flags,
        SLAP_EXTOP_MAIN_FN *ext_main )
 {
index ab5f17b7a72cdeca721a9ff64d37b98e92e571c4..6a68e498eec835b3128163c3f5bb387582ebcedc 100644 (file)
@@ -67,6 +67,7 @@ struct berval NoAttrs = BER_BVC( LDAP_NO_ATTRS );
  */
 ldap_pvt_thread_pool_t connection_pool;
 int                    connection_pool_max = SLAP_MAX_WORKER_THREADS;
+int            slap_tool_thread_max = 1;
 #ifndef HAVE_GMTIME_R
 ldap_pvt_thread_mutex_t        gmtime_mutex;
 #endif
@@ -124,8 +125,6 @@ slap_init( int mode, const char *name )
 
        switch ( slapMode & SLAP_MODE ) {
        case SLAP_SERVER_MODE:
-               ldap_pvt_thread_pool_init( &connection_pool,
-                               connection_pool_max, 0);
 
                /* FALLTHRU */
        case SLAP_TOOL_MODE:
@@ -136,6 +135,9 @@ slap_init( int mode, const char *name )
 
                slap_name = name;
 
+               ldap_pvt_thread_pool_init( &connection_pool,
+                               connection_pool_max, 0);
+
                ldap_pvt_thread_mutex_init( &entry2str_mutex );
                ldap_pvt_thread_mutex_init( &replog_mutex );
 
index 7de2855ba472ea9ee90ade3032709e1e3e9e36fd..b32e60e4d26383194db389118be898394d22d1ad 100644 (file)
@@ -332,7 +332,7 @@ int main( int argc, char **argv )
 #endif
 
        while ( (i = getopt( argc, argv,
-                            "c:d:f:F:h:n:o:s:StT:V"
+                            "c:d:f:F:h:n:o:s:tT:V"
 #if LDAP_PF_INET6
                                "46"
 #endif
@@ -669,7 +669,7 @@ unhandled_option:;
                ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_CTX, NULL );
 
                rc = ldap_pvt_tls_init_def_ctx();
-               if( rc == 0) {
+               if( rc == 0 ) {
                        ldap_pvt_tls_get_option( NULL, LDAP_OPT_X_TLS_CTX, &slap_tls_ctx );
                        /* Restore previous ctx */
                        ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_CTX, def_ctx );
@@ -721,7 +721,7 @@ unhandled_option:;
         */
        time( &starttime );
 
-       if ( slap_startup( NULL )  != 0 ) {
+       if ( slap_startup( NULL ) != 0 ) {
                rc = 1;
                SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 21 );
                goto shutdown;
@@ -729,33 +729,51 @@ unhandled_option:;
 
        Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 );
 
-
        if ( slapd_pid_file != NULL ) {
                FILE *fp = fopen( slapd_pid_file, "w" );
 
-               if( fp != NULL ) {
-                       fprintf( fp, "%d\n", (int) getpid() );
-                       fclose( fp );
+               if ( fp == NULL ) {
+                       int save_errno = errno;
+
+                       Debug( LDAP_DEBUG_ANY, "unable to open pid file "
+                               "\"%s\": %d (%s)\n",
+                               slapd_pid_file,
+                               save_errno, strerror( save_errno ) );
 
-               } else {
-                       free(slapd_pid_file);
+                       free( slapd_pid_file );
                        slapd_pid_file = NULL;
+
+                       rc = 1;
+                       goto shutdown;
                }
+
+               fprintf( fp, "%d\n", (int) getpid() );
+               fclose( fp );
        }
 
        if ( slapd_args_file != NULL ) {
                FILE *fp = fopen( slapd_args_file, "w" );
 
-               if( fp != NULL ) {
-                       for ( i = 0; i < g_argc; i++ ) {
-                               fprintf( fp, "%s ", g_argv[i] );
-                       }
-                       fprintf( fp, "\n" );
-                       fclose( fp );
-               } else {
-                       free(slapd_args_file);
+               if ( fp == NULL ) {
+                       int save_errno = errno;
+
+                       Debug( LDAP_DEBUG_ANY, "unable to open args file "
+                               "\"%s\": %d (%s)\n",
+                               slapd_args_file,
+                               save_errno, strerror( save_errno ) );
+
+                       free( slapd_args_file );
                        slapd_args_file = NULL;
+
+                       rc = 1;
+                       goto shutdown;
+               }
+
+               for ( i = 0; i < g_argc; i++ ) {
+                       fprintf( fp, "%s ", g_argv[i] );
                }
+               fprintf( fp, "\n" );
+               fclose( fp );
        }
 
 #ifdef HAVE_NT_EVENT_LOG
index ca628ef5ff424a93f86a8b243407d6e93f351fc7..4f90671ec32f5ca3ab160167284bfdb0fa176613 100644 (file)
@@ -200,8 +200,6 @@ do_modify(
        rs->sr_err = frontendDB->be_modify( op, rs );
 
 cleanup:
-       slap_graduate_commit_csn( op );
-
        op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
        op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
        if ( op->orm_modlist != NULL ) slap_mods_free( op->orm_modlist, 1 );
@@ -217,7 +215,6 @@ fe_op_modify( Operation *op, SlapReply *rs )
 #endif
        int             manageDSAit;
        Modifications   *modlist = op->orm_modlist;
-       Modifications   **modtail = &modlist;
        int             increment = op->orm_increment;
        BackendDB *op_be;
        char            textbuf[ SLAP_TEXT_BUFLEN ];
@@ -388,22 +385,6 @@ fe_op_modify( Operation *op, SlapReply *rs )
                                }
                        }
 
-                       if ( !repl_user ) {
-                               for( modtail = &modlist;
-                                       *modtail != NULL;
-                                       modtail = &(*modtail)->sml_next )
-                               {
-                                       /* empty */
-                               }
-
-                               rs->sr_err = slap_mods_opattrs( op, modlist, modtail,
-                                       &rs->sr_text, textbuf, textlen, 1 );
-                               if( rs->sr_err != LDAP_SUCCESS ) {
-                                       send_ldap_result( op, rs );
-                                       goto cleanup;
-                               }
-                       }
-
                        op->orm_modlist = modlist;
 #ifdef SLAPD_MULTIMASTER
                        if ( !repl_user )
@@ -825,35 +806,43 @@ void slap_timestamp( time_t *tm, struct berval *bv )
 #endif
 }
 
-int slap_mods_opattrs(
+/* modify only calls this for non-replicas. modrdn always calls.
+ */
+void slap_mods_opattrs(
        Operation *op,
        Modifications *mods,
-       Modifications **modtail,
-       const char **text,
-       char *textbuf, size_t textlen,
        int manage_ctxcsn )
 {
-       struct berval name, timestamp, csn;
+       struct berval name, timestamp, csn = BER_BVNULL;
        struct berval nname;
        char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
        char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
-       Modifications *mod;
-
-       int mop = op->o_tag == LDAP_REQ_ADD
-               ? LDAP_MOD_ADD : LDAP_MOD_REPLACE;
-
-       assert( modtail != NULL );
-       assert( *modtail == NULL );
+       Modifications *mod, **modtail, *modlast;
 
        if ( SLAP_LASTMOD( op->o_bd ) ) {
-               time_t now = slap_get_time();
-
-               slap_get_csn( op, csnbuf, sizeof(csnbuf), &csn, manage_ctxcsn );
-
+               char *ptr;
                timestamp.bv_val = timebuf;
-               timestamp.bv_len = sizeof(timebuf);
+               if ( BER_BVISEMPTY( &op->o_csn )) {
+                       csn.bv_val = csnbuf;
+                       csn.bv_len = sizeof( csnbuf );
+                       slap_get_csn( op, &csn, manage_ctxcsn );
+               } else {
+                       csn = op->o_csn;
+               }
+               ptr = strchr( csn.bv_val, '#' );
+               if ( ptr ) {
+                       timestamp.bv_len = ptr - csn.bv_val;
+                       if ( timestamp.bv_len >= sizeof( timebuf ))
+                               timestamp.bv_len = sizeof( timebuf ) - 1;
+                       strncpy( timebuf, csn.bv_val, timestamp.bv_len );
+                       timebuf[timestamp.bv_len] = '\0';
+               } else {
+                       time_t now = slap_get_time();
 
-               slap_timestamp( &now, &timestamp );
+                       timestamp.bv_len = sizeof(timebuf);
+
+                       slap_timestamp( &now, &timestamp );
+               }
 
                if ( BER_BVISEMPTY( &op->o_dn ) ) {
                        BER_BVSTR( &name, SLAPD_ANONYMOUS );
@@ -862,146 +851,13 @@ int slap_mods_opattrs(
                        name = op->o_dn;
                        nname = op->o_ndn;
                }
-       }
-
-       if ( op->o_tag == LDAP_REQ_ADD ) {
-               struct berval tmpval;
-
-               mod = *modtail;
-               if ( get_manageDIT( op ) ) {
-                       for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
-                               if ( mod->sml_desc == slap_schema.si_ad_structuralObjectClass ) {
-                                       break;
-                               }
-                       }
-
-               }
-
-               if ( mod == *modtail ) {
-                       int rc = mods_structural_class( mods, &tmpval,
-                               text, textbuf, textlen );
-                       if( rc != LDAP_SUCCESS ) return rc;
 
-                       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 =
-                               (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-                       ber_dupbv( &mod->sml_values[0], &tmpval );
-                       BER_BVZERO( &mod->sml_values[1] );
-                       assert( !BER_BVISNULL( &mod->sml_values[0] ) );
-                       mod->sml_nvalues =
-                               (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-                       ber_dupbv( &mod->sml_nvalues[0], &tmpval );
-                       BER_BVZERO( &mod->sml_nvalues[1] );
-                       assert( !BER_BVISNULL( &mod->sml_nvalues[0] ) );
-                       *modtail = mod;
-                       modtail = &mod->sml_next;
-               }
-
-               if ( SLAP_LASTMOD( op->o_bd ) ) {
-                       mod = *modtail;
-                       if ( get_manageDIT( op ) ) {
-                               for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
-                                       if ( mod->sml_desc == slap_schema.si_ad_entryUUID ) {
-                                               break;
-                                       }
-                               }
-                       }
-
-                       if ( mod == *modtail ) {
-                               char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
-
-                               tmpval.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
-                               tmpval.bv_val = uuidbuf;
-                       
-                               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 =
-                                       (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-                               ber_dupbv( &mod->sml_values[0], &tmpval );
-                               BER_BVZERO( &mod->sml_values[1] );
-                               assert( !BER_BVISNULL( &mod->sml_values[0] ) );
-                               mod->sml_nvalues =
-                                       (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-                               (*mod->sml_desc->ad_type->sat_equality->smr_normalize)(
-                                               SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
-                                               mod->sml_desc->ad_type->sat_syntax,
-                                               mod->sml_desc->ad_type->sat_equality,
-                                               mod->sml_values, mod->sml_nvalues, NULL );
-                               BER_BVZERO( &mod->sml_nvalues[1] );
-                               *modtail = mod;
-                               modtail = &mod->sml_next;
-                       }
-
-                       mod = *modtail;
-                       if ( get_manageDIT( op ) ) {
-                               for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
-                                       if ( mod->sml_desc == slap_schema.si_ad_creatorsName ) {
-                                               break;
-                                       }
-                               }
-                       }
-
-                       if ( mod == *modtail ) {
-                               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 =
-                                       (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-                               ber_dupbv( &mod->sml_values[0], &name );
-                               BER_BVZERO( &mod->sml_values[1] );
-                               assert( !BER_BVISNULL( &mod->sml_values[0] ) );
-                               mod->sml_nvalues =
-                                       (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-                               ber_dupbv( &mod->sml_nvalues[0], &nname );
-                               BER_BVZERO( &mod->sml_nvalues[1] );
-                               assert( !BER_BVISNULL( &mod->sml_nvalues[0] ) );
-                               *modtail = mod;
-                               modtail = &mod->sml_next;
-                       }
-       
-                       mod = *modtail;
-                       if ( get_manageDIT( op ) ) {
-                               for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
-                                       if ( mod->sml_desc == slap_schema.si_ad_createTimestamp ) {
-                                               break;
-                                       }
-                               }
-                       }
-
-                       if ( mod == *modtail ) {
-                               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 =
-                                       (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-                               ber_dupbv( &mod->sml_values[0], &timestamp );
-                               BER_BVZERO( &mod->sml_values[1] );
-                               assert( !BER_BVISNULL( &mod->sml_values[0] ) );
-                               mod->sml_nvalues = NULL;
-                               *modtail = mod;
-                               modtail = &mod->sml_next;
-                       }
-               }
-       }
+               for ( mod = mods; mod->sml_next; mod = mod->sml_next )
+                       ;
+               modtail = &mod->sml_next;
 
-       if ( SLAP_LASTMOD( op->o_bd ) ) {
                mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
-               mod->sml_op = mop;
+               mod->sml_op = LDAP_MOD_REPLACE;
                mod->sml_flags = SLAP_MOD_INTERNAL;
                mod->sml_next = NULL;
                BER_BVZERO( &mod->sml_type );
@@ -1012,20 +868,20 @@ int slap_mods_opattrs(
                assert( !BER_BVISNULL( &mod->sml_values[0] ) );
                mod->sml_nvalues = NULL;
                *modtail = mod;
+               modlast = mod;
                modtail = &mod->sml_next;
        
-               mod = *modtail;
                if ( get_manageDIT( op ) ) {
-                       for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
+                       for ( mod = mods; mod != modlast; mod = mod->sml_next ) {
                                if ( mod->sml_desc == slap_schema.si_ad_modifiersName ) {
                                        break;
                                }
                        }
                }
 
-               if ( mod == *modtail ) {
+               if ( mod->sml_desc != slap_schema.si_ad_modifiersName ) {
                        mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
-                       mod->sml_op = mop;
+                       mod->sml_op = LDAP_MOD_REPLACE;
                        mod->sml_flags = SLAP_MOD_INTERNAL;
                        mod->sml_next = NULL;
                        BER_BVZERO( &mod->sml_type );
@@ -1043,18 +899,17 @@ int slap_mods_opattrs(
                        modtail = &mod->sml_next;
                }
 
-               mod = *modtail;
                if ( get_manageDIT( op ) ) {
-                       for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
+                       for ( mod = mods; mod != modlast; mod = mod->sml_next ) {
                                if ( mod->sml_desc == slap_schema.si_ad_modifyTimestamp ) {
                                        break;
                                }
                        }
                }
 
-               if ( mod == *modtail ) {
+               if ( mod->sml_desc != slap_schema.si_ad_modifyTimestamp ) {
                        mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
-                       mod->sml_op = mop;
+                       mod->sml_op = LDAP_MOD_REPLACE;
                        mod->sml_flags = SLAP_MOD_INTERNAL;
                        mod->sml_next = NULL;
                        BER_BVZERO( &mod->sml_type );
@@ -1068,8 +923,5 @@ int slap_mods_opattrs(
                        modtail = &mod->sml_next;
                }
        }
-
-       *modtail = NULL;
-       return LDAP_SUCCESS;
 }
 
index f54f714103772eb95bcc8a3de356dd6e5668e478..496abe34d7a300599bbc6b0538c283d357cc0a3c 100644 (file)
@@ -178,8 +178,6 @@ do_modrdn(
        rs->sr_err = frontendDB->be_modrdn( op, rs );
 
 cleanup:
-       slap_graduate_commit_csn( op );
-
        op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
        op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
 
@@ -386,7 +384,6 @@ slap_modrdn2mods(
        Modifications   **pmod )
 {
        Modifications   *mod = NULL;
-       Modifications   **modtail = &mod;
        int             a_cnt, d_cnt;
        int repl_user;
 
@@ -506,18 +503,7 @@ slap_modrdn2mods(
 done:
 
        if ( rs->sr_err == LDAP_SUCCESS && !repl_user ) {
-               char textbuf[ SLAP_TEXT_BUFLEN ];
-               size_t textlen = sizeof textbuf;
-
-               for( modtail = &mod;
-                       *modtail != NULL;
-                       modtail = &(*modtail)->sml_next )
-               {
-                       /* empty */
-               }
-
-               rs->sr_err = slap_mods_opattrs( op, mod, modtail,
-                                               &rs->sr_text, textbuf, textlen, 1 );
+               slap_mods_opattrs( op, mod, 1 );
        }
 
        /* LDAP v2 supporting correct attribute handling. */
index a9a66074dae5a31c1480c36ef162c677913a0274..40945fd21fbc9c5ab5c39b752eba3c00cb243b18 100644 (file)
@@ -73,11 +73,15 @@ modify_add_values(
                }
 
                if ( permissive ) {
-                       for ( i = 0; !BER_BVISNULL( &mod->sm_values[i] ); i++ ) /* count 'em */;
-                       pmod.sm_values = (BerVarray)ch_malloc( (i + 1)*sizeof( struct berval ) );
+                       for ( i = 0; !BER_BVISNULL( &mod->sm_values[i] ); i++ ) {
+                               /* EMPTY -- just counting 'em */;
+                       }
+
+                       pmod.sm_values = (BerVarray)ch_malloc(
+                               (i + 1) * sizeof( struct berval ));
                        if ( pmod.sm_nvalues != NULL ) {
                                pmod.sm_nvalues = (BerVarray)ch_malloc(
-                                       (i + 1)*sizeof( struct berval ) );
+                                       (i + 1) * sizeof( struct berval ));
                        }
                }
 
index f8ecf3b920548920b5d3bbb7f85372ea9e09882d..68ee4d198a371cab500ca6b37082ab9c6bf0831c 100644 (file)
@@ -112,6 +112,21 @@ slap_op_free( Operation *op )
        ldap_pvt_thread_mutex_unlock( &slap_op_mutex );
 }
 
+void
+slap_op_time(time_t *t, int *nop)
+{
+       *t = slap_get_time();
+       ldap_pvt_thread_mutex_lock( &slap_op_mutex );
+       if ( *t == last_time ) {
+               *nop = ++last_incr;
+       } else {
+               last_time = *t;
+               last_incr = 0;
+               *nop = 0;
+       }
+       ldap_pvt_thread_mutex_unlock( &slap_op_mutex );
+}
+
 Operation *
 slap_op_alloc(
     BerElement         *ber,
@@ -139,13 +154,7 @@ slap_op_alloc(
        op->o_msgid = msgid;
        op->o_tag = tag;
 
-       op->o_time = slap_get_time();
-       if ( op->o_time == last_time ) {
-               op->o_tincr = ++last_incr;
-       } else {
-               last_time = op->o_time;
-               last_incr = 0;  /* o_tincr is alredy zero */
-       }
+       slap_op_time( &op->o_time, &op->o_tincr );
        op->o_opid = id;
        op->o_res_ber = NULL;
 
index 9da3a59b30dfbd7a1952a38cbdbd2dc8cfd381fa..4b37dce011a87e610d9489cefeff531d8e71895e 100644 (file)
@@ -58,6 +58,8 @@ typedef struct log_info {
        int li_cycle;
        struct re_s *li_task;
        int li_success;
+       ldap_pvt_thread_mutex_t li_op_mutex;
+       ldap_pvt_thread_mutex_t li_log_mutex;
 } log_info;
 
 static ConfigDriver log_cf_gen;
@@ -139,7 +141,7 @@ enum {
        LOG_EN__COUNT
 };
 
-static ObjectClass *log_ocs[LOG_EN__COUNT];
+static ObjectClass *log_ocs[LOG_EN__COUNT], *log_container;
 
 #define LOG_SCHEMA_ROOT        "1.3.6.1.4.1.4203.666.11.5"
 
@@ -152,10 +154,8 @@ static AttributeDescription *ad_reqDN, *ad_reqStart, *ad_reqEnd, *ad_reqType,
        *ad_reqNewSuperior, *ad_reqDeleteOldRDN, *ad_reqMod,
        *ad_reqScope, *ad_reqFilter, *ad_reqAttr, *ad_reqEntries,
        *ad_reqSizeLimit, *ad_reqTimeLimit, *ad_reqAttrsOnly, *ad_reqData,
-       *ad_reqId, *ad_reqMessage;
-#if 0
-static AttributeDescription *ad_oldest;
-#endif
+       *ad_reqId, *ad_reqMessage, *ad_reqVersion, *ad_reqDerefAliases,
+       *ad_reqReferral, *ad_reqOld;
 
 static struct {
        char *at;
@@ -188,97 +188,127 @@ static struct {
                "EQUALITY caseIgnoreMatch "
                "SYNTAX OMsDirectoryString "
                "SINGLE-VALUE )", &ad_reqSession },
-       { "( " LOG_SCHEMA_AT ".6 NAME 'reqResult' "
-               "DESC 'Result code of request' "
-               "EQUALITY integerMatch "
-               "SYNTAX OMsInteger "
-               "SINGLE-VALUE )", &ad_reqResult },
-       { "( " LOG_SCHEMA_AT ".7 NAME 'reqAuthzID' "
+       { "( " LOG_SCHEMA_AT ".6 NAME 'reqAuthzID' "
                "DESC 'Authorization ID of requestor' "
                "EQUALITY distinguishedNameMatch "
                "SYNTAX OMsDN "
                "SINGLE-VALUE )", &ad_reqAuthzID },
-       { "( " LOG_SCHEMA_AT ".8 NAME 'reqControls' "
+       { "( " LOG_SCHEMA_AT ".7 NAME 'reqResult' "
+               "DESC 'Result code of request' "
+               "EQUALITY integerMatch "
+               "ORDERING integerOrderingMatch "
+               "SYNTAX OMsInteger "
+               "SINGLE-VALUE )", &ad_reqResult },
+       { "( " LOG_SCHEMA_AT ".8 NAME 'reqMessage' "
+               "DESC 'Error text of request' "
+               "EQUALITY caseIgnoreMatch "
+               "SUBSTR caseIgnoreSubstringsMatch "
+               "SYNTAX OMsDirectoryString "
+               "SINGLE-VALUE )", &ad_reqMessage },
+       { "( " LOG_SCHEMA_AT ".9 NAME 'reqReferral' "
+               "DESC 'Referrals returned for request' "
+               "SUP labeledURI )", &ad_reqReferral },
+       { "( " LOG_SCHEMA_AT ".10 NAME 'reqControls' "
                "DESC 'Request controls' "
                "SYNTAX OMsOctetString )", &ad_reqControls },
-       { "( " LOG_SCHEMA_AT ".9 NAME 'reqRespControls' "
+       { "( " LOG_SCHEMA_AT ".11 NAME 'reqRespControls' "
                "DESC 'Response controls of request' "
                "SYNTAX OMsOctetString )", &ad_reqRespControls },
-       { "( " LOG_SCHEMA_AT ".10 NAME 'reqMethod' "
+       { "( " LOG_SCHEMA_AT ".12 NAME 'reqId' "
+               "DESC 'ID of Request to Abandon' "
+               "EQUALITY integerMatch "
+               "ORDERING integerOrderingMatch "
+               "SYNTAX OMsInteger "
+               "SINGLE-VALUE )", &ad_reqId },
+       { "( " LOG_SCHEMA_AT ".13 NAME 'reqVersion' "
+               "DESC 'Protocol version of Bind request' "
+               "EQUALITY integerMatch "
+               "ORDERING integerOrderingMatch "
+               "SYNTAX OMsInteger "
+               "SINGLE-VALUE )", &ad_reqVersion },
+       { "( " LOG_SCHEMA_AT ".14 NAME 'reqMethod' "
                "DESC 'Bind method of request' "
                "EQUALITY caseIgnoreMatch "
                "SYNTAX OMsDirectoryString "
                "SINGLE-VALUE )", &ad_reqMethod },
-       { "( " LOG_SCHEMA_AT ".11 NAME 'reqAssertion' "
+       { "( " LOG_SCHEMA_AT ".15 NAME 'reqAssertion' "
                "DESC 'Compare Assertion of request' "
                "SYNTAX OMsDirectoryString "
                "SINGLE-VALUE )", &ad_reqAssertion },
-       { "( " LOG_SCHEMA_AT ".12 NAME 'reqNewRDN' "
+       { "( " LOG_SCHEMA_AT ".16 NAME 'reqMod' "
+               "DESC 'Modifications of request' "
+               "EQUALITY octetStringMatch "
+               "SUBSTR octetStringSubstringsMatch "
+               "SYNTAX OMsOctetString )", &ad_reqMod },
+       { "( " LOG_SCHEMA_AT ".17 NAME 'reqOld' "
+               "DESC 'Old values of entry before request completed' "
+               "EQUALITY octetStringMatch "
+               "SUBSTR octetStringSubstringsMatch "
+               "SYNTAX OMsOctetString )", &ad_reqOld },
+       { "( " LOG_SCHEMA_AT ".18 NAME 'reqNewRDN' "
                "DESC 'New RDN of request' "
                "EQUALITY distinguishedNameMatch "
                "SYNTAX OMsDN "
                "SINGLE-VALUE )", &ad_reqNewRDN },
-       { "( " LOG_SCHEMA_AT ".13 NAME 'reqNewSuperior' "
+       { "( " LOG_SCHEMA_AT ".19 NAME 'reqDeleteOldRDN' "
+               "DESC 'Delete old RDN' "
+               "EQUALITY booleanMatch "
+               "SYNTAX OMsBoolean "
+               "SINGLE-VALUE )", &ad_reqDeleteOldRDN },
+       { "( " LOG_SCHEMA_AT ".20 NAME 'reqNewSuperior' "
                "DESC 'New superior DN of request' "
                "EQUALITY distinguishedNameMatch "
                "SYNTAX OMsDN "
                "SINGLE-VALUE )", &ad_reqNewSuperior },
-       { "( " LOG_SCHEMA_AT ".14 NAME 'reqDeleteOldRDN' "
-               "DESC 'Delete old RDN' "
-               "SYNTAX OMsBoolean "
-               "SINGLE-VALUE )", &ad_reqDeleteOldRDN },
-       { "( " LOG_SCHEMA_AT ".15 NAME 'reqMod' "
-               "DESC 'Modifications of request' "
-               "SYNTAX OMsDirectoryString "
-               "EQUALITY caseIgnoreMatch "
-               "SUBSTR caseIgnoreSubstringsMatch )", &ad_reqMod },
-       { "( " LOG_SCHEMA_AT ".16 NAME 'reqScope' "
+       { "( " LOG_SCHEMA_AT ".21 NAME 'reqScope' "
                "DESC 'Scope of request' "
+               "EQUALITY caseIgnoreMatch "
                "SYNTAX OMsDirectoryString "
                "SINGLE-VALUE )", &ad_reqScope },
-       { "( " LOG_SCHEMA_AT ".17 NAME 'reqFilter' "
+       { "( " LOG_SCHEMA_AT ".22 NAME 'reqDerefAliases' "
+               "DESC 'Disposition of Aliases in request' "
+               "EQUALITY caseIgnoreMatch "
+               "SYNTAX OMsDirectoryString "
+               "SINGLE-VALUE )", &ad_reqDerefAliases },
+       { "( " LOG_SCHEMA_AT ".23 NAME 'reqAttrsOnly' "
+               "DESC 'Attributes and values of request' "
+               "EQUALITY booleanMatch "
+               "SYNTAX OMsBoolean "
+               "SINGLE-VALUE )", &ad_reqAttrsOnly },
+       { "( " LOG_SCHEMA_AT ".24 NAME 'reqFilter' "
                "DESC 'Filter of request' "
+               "EQUALITY caseIgnoreMatch "
+               "SUBSTR caseIgnoreSubstringsMatch "
                "SYNTAX OMsDirectoryString "
                "SINGLE-VALUE )", &ad_reqFilter },
-       { "( " LOG_SCHEMA_AT ".18 NAME 'reqAttr' "
+       { "( " LOG_SCHEMA_AT ".25 NAME 'reqAttr' "
                "DESC 'Attributes of request' "
+               "EQUALITY caseIgnoreMatch "
                "SYNTAX OMsDirectoryString )", &ad_reqAttr },
-       { "( " LOG_SCHEMA_AT ".19 NAME 'reqEntries' "
-               "DESC 'Number of entries returned' "
-               "SYNTAX OMsInteger "
-               "SINGLE-VALUE )", &ad_reqEntries },
-       { "( " LOG_SCHEMA_AT ".20 NAME 'reqSizeLimit' "
+       { "( " LOG_SCHEMA_AT ".26 NAME 'reqSizeLimit' "
                "DESC 'Size limit of request' "
+               "EQUALITY integerMatch "
+               "ORDERING integerOrderingMatch "
                "SYNTAX OMsInteger "
                "SINGLE-VALUE )", &ad_reqSizeLimit },
-       { "( " LOG_SCHEMA_AT ".21 NAME 'reqTimeLimit' "
+       { "( " LOG_SCHEMA_AT ".27 NAME 'reqTimeLimit' "
                "DESC 'Time limit of request' "
+               "EQUALITY integerMatch "
+               "ORDERING integerOrderingMatch "
                "SYNTAX OMsInteger "
                "SINGLE-VALUE )", &ad_reqTimeLimit },
-       { "( " LOG_SCHEMA_AT ".22 NAME 'reqAttrsOnly' "
-               "DESC 'Attributes and values of request' "
-               "SYNTAX OMsBoolean "
-               "SINGLE-VALUE )", &ad_reqAttrsOnly },
-       { "( " LOG_SCHEMA_AT ".23 NAME 'reqData' "
+       { "( " LOG_SCHEMA_AT ".28 NAME 'reqEntries' "
+               "DESC 'Number of entries returned' "
+               "EQUALITY integerMatch "
+               "ORDERING integerOrderingMatch "
+               "SYNTAX OMsInteger "
+               "SINGLE-VALUE )", &ad_reqEntries },
+       { "( " LOG_SCHEMA_AT ".29 NAME 'reqData' "
                "DESC 'Data of extended request' "
+               "EQUALITY octetStringMatch "
+               "SUBSTR octetStringSubstringsMatch "
                "SYNTAX OMsOctetString "
                "SINGLE-VALUE )", &ad_reqData },
-       { "( " LOG_SCHEMA_AT ".24 NAME 'reqId' "
-               "DESC 'ID of Request to Abandon' "
-               "SYNTAX OMsInteger "
-               "SINGLE-VALUE )", &ad_reqId },
-       { "( " LOG_SCHEMA_AT ".25 NAME 'reqMessage' "
-               "DESC 'Error text of request' "
-               "SYNTAX OMsDirectoryString "
-               "SINGLE-VALUE )", &ad_reqMessage },
-#if 0
-       { "( " LOG_SCHEMA_AT ".26 NAME 'auditOldest' "
-               "DESC 'Oldest record in this branch' "
-               "EQUALITY generalizedTimeMatch "
-               "ORDERING generalizedTimeOrderingMatch "
-               "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
-               "SINGLE-VALUE )", &ad_oldest },
-#endif
        { NULL, NULL }
 };
 
@@ -286,24 +316,23 @@ static struct {
        char *ot;
        ObjectClass **oc;
 } locs[] = {
-#if 0
        { "( " LOG_SCHEMA_OC ".0 NAME 'auditContainer' "
+               "DESC 'AuditLog container' "
                "SUP top STRUCTURAL "
-               "MUST auditOldest "
-               "MAY cn )", &oc_container },
-#endif
+               "MAY ( cn $ reqStart $ reqEnd ) )", &log_container },
        { "( " LOG_SCHEMA_OC ".1 NAME 'auditObject' "
                "DESC 'OpenLDAP request auditing' "
                "SUP top STRUCTURAL "
                "MUST ( reqStart $ reqType $ reqSession ) "
                "MAY ( reqDN $ reqAuthzID $ reqControls $ reqRespControls $ reqEnd $ "
-                       "reqResult $ reqMessage ) )", &log_ocs[LOG_EN_UNBIND] },
+                       "reqResult $ reqMessage $ reqReferral ) )",
+                               &log_ocs[LOG_EN_UNBIND] },
        { "( " LOG_SCHEMA_OC ".2 NAME 'auditReadObject' "
                "DESC 'OpenLDAP read request record' "
                "SUP auditObject STRUCTURAL )", NULL },
        { "( " LOG_SCHEMA_OC ".3 NAME 'auditWriteObject' "
                "DESC 'OpenLDAP write request record' "
-               "SUP auditObject STRUCTURAL )", &log_ocs[LOG_EN_DELETE] },
+               "SUP auditObject STRUCTURAL )", NULL },
        { "( " LOG_SCHEMA_OC ".4 NAME 'auditAbandon' "
                "DESC 'Abandon operation' "
                "SUP auditObject STRUCTURAL "
@@ -315,27 +344,31 @@ static struct {
        { "( " LOG_SCHEMA_OC ".6 NAME 'auditBind' "
                "DESC 'Bind operation' "
                "SUP auditObject STRUCTURAL "
-               "MUST reqMethod )", &log_ocs[LOG_EN_BIND] },
+               "MUST ( reqVersion $ reqMethod ) )", &log_ocs[LOG_EN_BIND] },
        { "( " LOG_SCHEMA_OC ".7 NAME 'auditCompare' "
                "DESC 'Compare operation' "
                "SUP auditReadObject STRUCTURAL "
                "MUST reqAssertion )", &log_ocs[LOG_EN_COMPARE] },
-       { "( " LOG_SCHEMA_OC ".8 NAME 'auditModify' "
+       { "( " LOG_SCHEMA_OC ".8 NAME 'auditDelete' "
+               "DESC 'Delete operation' "
+               "SUP auditWriteObject STRUCTURAL "
+               "MAY reqOld )", &log_ocs[LOG_EN_DELETE] },
+       { "( " LOG_SCHEMA_OC ".9 NAME 'auditModify' "
                "DESC 'Modify operation' "
                "SUP auditWriteObject STRUCTURAL "
-               "MUST reqMod )", &log_ocs[LOG_EN_MODIFY] },
-       { "( " LOG_SCHEMA_OC ".9 NAME 'auditModRDN' "
+               "MAY reqOld MUST reqMod )", &log_ocs[LOG_EN_MODIFY] },
+       { "( " LOG_SCHEMA_OC ".10 NAME 'auditModRDN' "
                "DESC 'ModRDN operation' "
                "SUP auditWriteObject STRUCTURAL "
                "MUST ( reqNewRDN $ reqDeleteOldRDN ) "
                "MAY reqNewSuperior )", &log_ocs[LOG_EN_MODRDN] },
-       { "( " LOG_SCHEMA_OC ".10 NAME 'auditSearch' "
+       { "( " LOG_SCHEMA_OC ".11 NAME 'auditSearch' "
                "DESC 'Search operation' "
                "SUP auditReadObject STRUCTURAL "
-               "MUST ( reqScope $ reqAttrsonly ) "
+               "MUST ( reqScope $ reqDerefAliases $ reqAttrsonly ) "
                "MAY ( reqFilter $ reqAttr $ reqEntries $ reqSizeLimit $ "
                        "reqTimeLimit ) )", &log_ocs[LOG_EN_SEARCH] },
-       { "( " LOG_SCHEMA_OC ".11 NAME 'auditExtended' "
+       { "( " LOG_SCHEMA_OC ".12 NAME 'auditExtended' "
                "DESC 'Extended operation' "
                "SUP auditObject STRUCTURAL "
                "MAY reqData )", &log_ocs[LOG_EN_EXTENDED] },
@@ -344,22 +377,26 @@ static struct {
 
 #define        RDNEQ   "reqStart="
 
-/* Our time intervals are of the form [dd+]hh:mm[:ss]
- * If a field is present, it must be two digits. We assume no one
- * will want to keep log records for longer than 99 days.
+/* Our time intervals are of the form [ddd+]hh:mm[:ss]
+ * If a field is present, it must be two digits. (Except for
+ * days, which can be arbitrary width.)
  */
 static int
 log_age_parse(char *agestr)
 {
        int t1, t2;
        int gotdays = 0;
+       char *endptr;
 
-       t1 = atoi( agestr );
+       t1 = strtol( agestr, &endptr, 10 );
        /* Is there a days delimiter? */
-       if ( agestr[2] == '+' ) {
+       if ( *endptr == '+' ) {
+               /* 32 bit time only covers about 68 years */
+               if ( t1 < 0 || t1 > 25000 )
+                       return -1;
                t1 *= 24;
                gotdays = 1;
-       } else if ( agestr[2] != ':' ) {
+       } else if ( *endptr != ':' ) {
        /* No valid delimiter found, fail */
                return -1;
        }
@@ -419,7 +456,7 @@ log_age_unparse( int age, struct berval *agebv )
        ptr = agebv->bv_val;
 
        if ( dd ) 
-               ptr += sprintf( ptr, "%02d+", dd );
+               ptr += sprintf( ptr, "%d+", dd );
        ptr += sprintf( ptr, "%02d:%02d", hh, mm );
        if ( ss )
                ptr += sprintf( ptr, ":%02d", ss );
@@ -539,7 +576,7 @@ log_cf_gen(ConfigArgs *c)
        struct log_info *li = on->on_bi.bi_private;
        int rc = 0;
        slap_mask_t tmask = 0;
-       char agebuf[2*STRLENOF("dd+hh:mm:ss  ")];
+       char agebuf[2*STRLENOF("ddddd+hh:mm:ss  ")];
        struct berval agebv, cyclebv;
 
        switch( c->op ) {
@@ -649,7 +686,8 @@ log_cf_gen(ConfigArgs *c)
        return rc;
 }
 
-static Entry *accesslog_entry( Operation *op, int logop ) {
+static Entry *accesslog_entry( Operation *op, int logop,
+       Operation *op2 ) {
        slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
        log_info *li = on->on_bi.bi_private;
 
@@ -690,6 +728,15 @@ static Entry *accesslog_entry( Operation *op, int logop ) {
        attr_merge_one( e, ad_reqStart, &timestamp, &ntimestamp );
        op->o_tmpfree( ntimestamp.bv_val, op->o_tmpmemctx );
 
+       slap_op_time( &op2->o_time, &op2->o_tincr );
+
+       timestamp.bv_len = sizeof(rdnbuf) - STRLENOF(RDNEQ);
+       slap_timestamp( &op2->o_time, &timestamp );
+       sprintf( timestamp.bv_val + timestamp.bv_len-1, ".%06dZ", op2->o_tincr );
+       timestamp.bv_len += 7;
+
+       attr_merge_normalize_one( e, ad_reqEnd, &timestamp, op->o_tmpmemctx );
+
        /* Exops have OID appended */
        if ( logop == LOG_EN_EXTENDED ) {
                bv.bv_len = lo->word.bv_len + op->ore_reqoid.bv_len + 2;
@@ -721,9 +768,16 @@ static Entry *accesslog_entry( Operation *op, int logop ) {
 
 static struct berval scopes[] = {
        BER_BVC("base"),
-       BER_BVC("onelevel"),
-       BER_BVC("subtree"),
-       BER_BVC("subordinate")
+       BER_BVC("one"),
+       BER_BVC("sub"),
+       BER_BVC("subord")
+};
+
+static struct berval derefs[] = {
+       BER_BVC("never"),
+       BER_BVC("searching"),
+       BER_BVC("finding"),
+       BER_BVC("always")
 };
 
 static struct berval simple = BER_BVC("SIMPLE");
@@ -734,12 +788,11 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
        Attribute *a, *last_attr;
        Modifications *m;
        struct berval *b;
-       time_t endtime;
        int i;
        int logop;
        slap_verbmasks *lo;
        Entry *e;
-       char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE];
+       char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE+8];
        struct berval bv;
        char *ptr;
        BerVarray vals;
@@ -749,9 +802,6 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
        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;
@@ -769,15 +819,15 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
        if ( !( li->li_ops & lo->mask ))
                return SLAP_CB_CONTINUE;
 
-       endtime = slap_get_time();
-
-       e = accesslog_entry( op, logop );
+       if ( lo->mask & LOG_OP_WRITES ) {
+               ldap_pvt_thread_mutex_lock( &li->li_log_mutex );
+               ldap_pvt_thread_mutex_unlock( &li->li_op_mutex );
+       }
 
-       bv.bv_val = timebuf;
-       bv.bv_len = sizeof(timebuf);
-       slap_timestamp( &endtime, &bv );
+       if ( li->li_success && rs->sr_err != LDAP_SUCCESS )
+               goto done;
 
-       attr_merge_one( e, ad_reqEnd, &bv, NULL );
+       e = accesslog_entry( op, logop, &op2 );
 
        attr_merge_one( e, ad_reqDN, &op->o_req_dn, &op->o_req_ndn );
 
@@ -915,6 +965,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
 
        case LOG_EN_SEARCH:
                attr_merge_one( e, ad_reqScope, &scopes[op->ors_scope], NULL );
+               attr_merge_one( e, ad_reqDerefAliases, &derefs[op->ors_deref], NULL );
                attr_merge_one( e, ad_reqAttrsOnly, op->ors_attrsonly ?
                        (struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv,
                        NULL );
@@ -943,6 +994,9 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
                break;
 
        case LOG_EN_BIND:
+               bv.bv_val = timebuf;
+               bv.bv_len = sprintf( bv.bv_val, "%d", op->o_protocol );
+               attr_merge_one( e, ad_reqVersion, &bv, NULL );
                if ( op->orb_method == LDAP_AUTH_SIMPLE ) {
                        attr_merge_one( e, ad_reqMethod, &simple, NULL );
                } else {
@@ -955,6 +1009,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
                        attr_merge_one( e, ad_reqMethod, &bv, NULL );
                        op->o_tmpfree( bv.bv_val, op->o_tmpmemctx );
                }
+
                break;
 
        case LOG_EN_EXTENDED:
@@ -970,8 +1025,6 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
 
        op2.o_hdr = op->o_hdr;
        op2.o_tag = LDAP_REQ_ADD;
-       op2.o_time = endtime;
-       op2.o_tincr = 0;
        op2.o_bd = li->li_db;
        op2.o_dn = li->li_db->be_rootdn;
        op2.o_ndn = li->li_db->be_rootndn;
@@ -980,16 +1033,71 @@ 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 );
+       if (( lo->mask & LOG_OP_WRITES ) && !BER_BVISEMPTY( &op->o_csn )) {
+               slap_queue_csn( &op2, &op->o_csn );
        }
 
        op2.o_bd->be_add( &op2, &rs2 );
-       slap_graduate_commit_csn( &op2 );
        entry_free( e );
 
+done:
+       ldap_pvt_thread_mutex_unlock( &li->li_log_mutex );
+       return SLAP_CB_CONTINUE;
+}
+
+/* Since Bind success is sent by the frontend, it won't normally enter
+ * the overlay response callback. Add another callback to make sure it
+ * gets here.
+ */
+static int
+accesslog_bind_resp( Operation *op, SlapReply *rs )
+{
+       BackendDB *be, db;
+       int rc;
+       slap_callback *sc;
+
+       be = op->o_bd;
+       db = *be;
+       op->o_bd = &db;
+       db.bd_info = op->o_callback->sc_private;
+       rc = accesslog_response( op, rs );
+       op->o_bd = be;
+       sc = op->o_callback;
+       op->o_callback = sc->sc_next;
+       op->o_tmpfree( sc, op->o_tmpmemctx );
+       return rc;
+}
+
+static int
+accesslog_op_bind( Operation *op, SlapReply *rs )
+{
+       slap_callback *sc;
+
+       sc = op->o_tmpcalloc( 1, sizeof(slap_callback), op->o_tmpmemctx );
+       sc->sc_response = accesslog_bind_resp;
+       sc->sc_private = op->o_bd->bd_info;
+
+       if ( op->o_callback ) {
+               sc->sc_next = op->o_callback->sc_next;
+               op->o_callback->sc_next = sc;
+       } else {
+               op->o_callback = sc;
+       }
+       return SLAP_CB_CONTINUE;
+}
+
+static int
+accesslog_op_mod( Operation *op, SlapReply *rs )
+{
+       slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+       log_info *li = on->on_bi.bi_private;
+
+       if ( li->li_ops & LOG_OP_WRITES ) {
+               /* FIXME: this needs to be a recursive mutex to allow
+                * overlays like refint to keep working.
+                */
+               ldap_pvt_thread_mutex_lock( &li->li_op_mutex );
+       }
        return SLAP_CB_CONTINUE;
 }
 
@@ -999,21 +1107,20 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
 static int
 accesslog_unbind( Operation *op, SlapReply *rs )
 {
-       if ( op->o_conn->c_authz_backend == op->o_bd ) {
-               slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+       slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+       if ( op->o_conn->c_authz_backend == on->on_info->oi_origdb ) {
                log_info *li = on->on_bi.bi_private;
                Operation op2;
+               void *cids[SLAP_MAX_CIDS];
                SlapReply rs2 = {REP_RESULT};
                Entry *e;
 
                if ( !( li->li_ops & LOG_OP_UNBIND ))
                        return SLAP_CB_CONTINUE;
 
-               e = accesslog_entry( op, LOG_EN_UNBIND );
+               e = accesslog_entry( op, LOG_EN_UNBIND, &op2 );
                op2.o_hdr = op->o_hdr;
                op2.o_tag = LDAP_REQ_ADD;
-               op2.o_time = op->o_time;
-               op2.o_tincr = 0;
                op2.o_bd = li->li_db;
                op2.o_dn = li->li_db->be_rootdn;
                op2.o_ndn = li->li_db->be_rootndn;
@@ -1021,6 +1128,9 @@ accesslog_unbind( Operation *op, SlapReply *rs )
                op2.o_req_ndn = e->e_nname;
                op2.ora_e = e;
                op2.o_callback = &nullsc;
+               op2.o_controls = cids;
+               memset(cids, 0, sizeof( cids ));
+               memset(op2.o_ctrlflag, 0, sizeof( op2.o_ctrlflag ));
 
                op2.o_bd->be_add( &op2, &rs2 );
                entry_free( e );
@@ -1034,6 +1144,7 @@ accesslog_abandon( Operation *op, SlapReply *rs )
        slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
        log_info *li = on->on_bi.bi_private;
        Operation op2;
+       void *cids[SLAP_MAX_CIDS];
        SlapReply rs2 = {REP_RESULT};
        Entry *e;
        char buf[64];
@@ -1042,15 +1153,13 @@ accesslog_abandon( Operation *op, SlapReply *rs )
        if ( !op->o_time || !( li->li_ops & LOG_OP_ABANDON ))
                return SLAP_CB_CONTINUE;
 
-       e = accesslog_entry( op, LOG_EN_ABANDON );
+       e = accesslog_entry( op, LOG_EN_ABANDON, &op2 );
        bv.bv_val = buf;
        bv.bv_len = sprintf( buf, "%d", op->orn_msgid );
        attr_merge_one( e, ad_reqId, &bv, NULL );
 
        op2.o_hdr = op->o_hdr;
        op2.o_tag = LDAP_REQ_ADD;
-       op2.o_time = op->o_time;
-       op2.o_tincr = 0;
        op2.o_bd = li->li_db;
        op2.o_dn = li->li_db->be_rootdn;
        op2.o_ndn = li->li_db->be_rootndn;
@@ -1058,6 +1167,9 @@ accesslog_abandon( Operation *op, SlapReply *rs )
        op2.o_req_ndn = e->e_nname;
        op2.ora_e = e;
        op2.o_callback = &nullsc;
+       op2.o_controls = cids;
+       memset(cids, 0, sizeof( cids ));
+       memset(op2.o_ctrlflag, 0, sizeof( op2.o_ctrlflag ));
 
        op2.o_bd->be_add( &op2, &rs2 );
        entry_free( e );
@@ -1076,6 +1188,8 @@ accesslog_db_init(
        log_info *li = ch_calloc(1, sizeof(log_info));
 
        on->on_bi.bi_private = li;
+       ldap_pvt_thread_mutex_init( &li->li_op_mutex );
+       ldap_pvt_thread_mutex_init( &li->li_log_mutex );
        return 0;
 }
 
@@ -1087,6 +1201,8 @@ accesslog_db_destroy(
        slap_overinst *on = (slap_overinst *)be->bd_info;
        log_info *li = on->on_bi.bi_private;
        
+       ldap_pvt_thread_mutex_destroy( &li->li_log_mutex );
+       ldap_pvt_thread_mutex_destroy( &li->li_op_mutex );
        free( li );
        return LDAP_SUCCESS;
 }
@@ -1099,6 +1215,11 @@ int accesslog_init()
        accesslog.on_bi.bi_db_init = accesslog_db_init;
        accesslog.on_bi.bi_db_destroy = accesslog_db_destroy;
 
+       accesslog.on_bi.bi_op_add = accesslog_op_mod;
+       accesslog.on_bi.bi_op_bind = accesslog_op_bind;
+       accesslog.on_bi.bi_op_delete = accesslog_op_mod;
+       accesslog.on_bi.bi_op_modify = accesslog_op_mod;
+       accesslog.on_bi.bi_op_modrdn = accesslog_op_mod;
        accesslog.on_bi.bi_op_unbind = accesslog_unbind;
        accesslog.on_bi.bi_op_abandon = accesslog_abandon;
        accesslog.on_response = accesslog_response;
index 07e06eb0d21f605e32d7188c1da8688a98b23ed6..63a30e6301fece21a0e0276849db76fd3b6e579e 100644 (file)
@@ -370,7 +370,9 @@ best_guess( Operation *op,
                char            csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
                struct berval   entryCSN;
        
-               slap_get_csn( NULL, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
+               entryCSN.bv_val = csnbuf;
+               entryCSN.bv_len = sizeof( csnbuf );
+               slap_get_csn( NULL, &entryCSN, 0 );
 
                ber_dupbv( bv_entryCSN, &entryCSN );
                ber_dupbv( bv_nentryCSN, &entryCSN );
@@ -909,7 +911,9 @@ lastmod_db_open(
        timestamp.bv_len = sizeof(tmbuf);
        slap_timestamp( &starttime, &timestamp );
 
-       slap_get_csn( NULL, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
+       entryCSN.bv_val = csnbuf;
+       entryCSN.bv_len = sizeof( csnbuf );
+       slap_get_csn( NULL, &entryCSN, 0 );
 
        if ( BER_BVISNULL( &lmi->lmi_rdnvalue ) ) {
                ber_str2bv( "Lastmod", 0, 1, &lmi->lmi_rdnvalue );
index 0d87840a166290f1b081f1b0f791b3d658088c9b..e543a4857586ab287143db8353d74ab39296a804 100644 (file)
@@ -1179,11 +1179,12 @@ ppolicy_modify( Operation *op, SlapReply *rs )
         */
        if ( be_shadow_update( op )) {
                Modifications **prev;
-               int got_del_grace = 0, got_del_lock = 0, got_pw = 0;
-               Attribute *a_grace, *a_lock;
+               int got_del_grace = 0, got_del_lock = 0, got_pw = 0, got_del_fail = 0;
+               Attribute *a_grace, *a_lock, *a_fail;
 
                a_grace = attr_find( e->e_attrs, ad_pwdGraceUseTime );
                a_lock = attr_find( e->e_attrs, ad_pwdAccountLockedTime );
+               a_fail = attr_find( e->e_attrs, ad_pwdFailureTime );
 
                for( prev = &op->oq_modify.rs_modlist, ml = *prev; ml;
                        prev = &ml->sml_next, ml = *prev ) {
@@ -1206,6 +1207,11 @@ ppolicy_modify( Operation *op, SlapReply *rs )
                                        got_del_lock = 1;
                                        if ( !a_lock )
                                                drop = 1;
+                               } else
+                               if ( ml->sml_desc == ad_pwdFailureTime ) {
+                                       got_del_fail = 1;
+                                       if ( !a_fail )
+                                               drop = 1;
                                }
                                if ( drop ) {
                                        *prev = ml->sml_next;
@@ -1215,8 +1221,8 @@ ppolicy_modify( Operation *op, SlapReply *rs )
                        }
                }
 
-               /* If we're resetting the password, make sure grace and accountlock
-                * also get removed.
+               /* If we're resetting the password, make sure grace, accountlock,
+                * and failure also get removed.
                 */
                if ( got_pw ) {
                        if ( a_grace && !got_del_grace ) {
@@ -1242,6 +1248,17 @@ ppolicy_modify( Operation *op, SlapReply *rs )
                                ml->sml_next = NULL;
                                *prev = ml;
                        }
+                       if ( a_fail && !got_del_fail ) {
+                               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_pwdFailureTime;
+                               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 );
@@ -1577,6 +1594,19 @@ do_modify:
                        modtail = mods;
                }
 
+               if (attr_find(e->e_attrs, ad_pwdFailureTime )) {
+                       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_pwdFailureTime;
+                       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 ) );
index 41e1cbc9cf0739e4f49a38ceff0836545a565879..9004f902f971aff10053b3fb89a9c42d33535a12 100644 (file)
@@ -621,10 +621,6 @@ refint_response(
        */
 
        for(dp = dd.mods; dp; dp = dp->next) {
-               Modifications **tail, *m;
-
-               for(m = dp->mm; m && m->sml_next; m = m->sml_next);
-               tail = &m->sml_next;
                nop.o_req_dn    = dp->dn;
                nop.o_req_ndn   = dp->dn;
                nop.o_bd = select_backend(&dp->dn, 0, 1);
@@ -637,8 +633,6 @@ refint_response(
                nop.orm_modlist = dp->mm;       /* callback did all the work */
                nop.o_dn = refint_dn;
                nop.o_ndn = refint_dn;
-               rs->sr_err = slap_mods_opattrs( &nop, nop.orm_modlist,
-                       tail, &rs->sr_text, NULL, 0, 1 );
                nop.o_dn = nop.o_bd->be_rootdn;
                nop.o_ndn = nop.o_bd->be_rootndn;
                if(rs->sr_err != LDAP_SUCCESS) goto done;
index 430e214ec2eb65c90972decce27261144fc2a1fa..42bf3f8c1e2dc99d219edc1c67ddbcfd37d961af 100644 (file)
@@ -695,7 +695,7 @@ rwm_op_search( Operation *op, SlapReply *rs )
        dc.normalized = 0;
 #endif /* ! ENABLE_REWRITE */
 
-       rc = rwm_filter_map_rewrite( &dc, op->ors_filter, &fstr );
+       rc = rwm_filter_map_rewrite( op, &dc, op->ors_filter, &fstr );
        if ( rc != LDAP_SUCCESS ) {
                text = "searchFilter/searchFilterAttrDN massage error";
                goto error_return;
@@ -1043,6 +1043,7 @@ rwm_send_entry( Operation *op, SlapReply *rs )
                        goto fail;
                }
 
+               flags &= ~REP_ENTRY_MUSTRELEASE;
                flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
        }
 
@@ -1075,11 +1076,9 @@ rwm_send_entry( Operation *op, SlapReply *rs )
         * to return, and remap them accordingly */
        (void)rwm_attrs( op, rs, &e->e_attrs, 1 );
 
-#if 0
-       if ( rs->sr_operational_attrs ) {
-               (void)rwm_attrs( op, rs, &rs->sr_operational_attrs, 0 );
+       if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
+               be_entry_release_rw( op, rs->sr_entry, 0 );
        }
-#endif
 
        rs->sr_entry = e;
        rs->sr_flags = flags;
@@ -1395,9 +1394,14 @@ rwm_db_config(
                } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
                        rwmap->rwm_flags |= RWM_F_SUPPORT_T_F;
 
-#if 0
                /* TODO: not implemented yet */
                } else if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
+                       fprintf( stderr,
+               "%s: line %d: \"discover\" not supported yet "
+               "in \"t-f-support {no|yes|discover}\".\n",
+                                       fname, lineno );
+                       return( 1 );
+#if 0
                        rwmap->rwm_flags |= RWM_F_SUPPORT_T_F_DISCOVER;
 #endif
 
@@ -1477,7 +1481,7 @@ rwm_db_destroy(
                        (struct ldaprwmap *)on->on_bi.bi_private;
 
 #ifdef ENABLE_REWRITE
-               if (rwmap->rwm_rw) {
+               if ( rwmap->rwm_rw ) {
                        rewrite_info_delete( &rwmap->rwm_rw );
                }
 #else /* !ENABLE_REWRITE */
@@ -1486,9 +1490,9 @@ rwm_db_destroy(
                }
 #endif /* !ENABLE_REWRITE */
 
-               avl_free( rwmap->rwm_oc.remap, NULL );
+               avl_free( rwmap->rwm_oc.remap, rwm_mapping_dst_free );
                avl_free( rwmap->rwm_oc.map, rwm_mapping_free );
-               avl_free( rwmap->rwm_at.remap, NULL );
+               avl_free( rwmap->rwm_at.remap, rwm_mapping_dst_free );
                avl_free( rwmap->rwm_at.map, rwm_mapping_free );
 
                ch_free( rwmap );
index d27e6ac2a875fc84630fc91a6437afd0b11547e9..0c3c73e16c7af9a3ce34d207368e49dfc967fa48 100644 (file)
@@ -138,6 +138,8 @@ rwm_map_attrnames(
                AttributeName **anp,
                int remap );
 
+extern void rwm_mapping_dst_free ( void *mapping );
+
 extern void rwm_mapping_free ( void *mapping );
 
 extern int rwm_map_config(
@@ -150,6 +152,7 @@ extern int rwm_map_config(
 
 extern int
 rwm_filter_map_rewrite(
+               Operation               *op,
                dncookie                *dc,
                Filter                  *f,
                struct berval           *fstr );
index 7a87ccff0020665c92539e076407e02955e53029..71a77924c903cbc9a41d93583bbf87173feaaefe 100644 (file)
@@ -146,7 +146,7 @@ rwm_map_config(
                        if ( mapping[0].m_dst_oc == NULL ) {
                                fprintf( stderr, "%s: line %d: unable to mimic destination objectClass '%s'\n",
                                        fname, lineno, dst );
-                               return 1;
+                               goto error_return;
                        }
 
 #if 0
@@ -186,7 +186,7 @@ rwm_map_config(
                                        fprintf( stderr,
        "%s: line %d: source attributeType '%s': %d (%s)\n",
                                                fname, lineno, src, rc, text ? text : "null" );
-                                       return 1;
+                                       goto error_return;
                                }
 
                        }
@@ -207,7 +207,7 @@ rwm_map_config(
                                fprintf( stderr,
        "%s: line %d: destination attributeType '%s': %d (%s)\n",
                                        fname, lineno, dst, rc, text ? text : "null" );
-                               return 1;
+                               goto error_return;
                        }
                }
                mapping[1].m_src_ad = mapping[0].m_dst_ad;
index 4c573f3b423388f0ca1a2cc0d40149f2e496430b..1fa9c506d4631bb23a7256911447af6166f2c06f 100644 (file)
@@ -442,6 +442,7 @@ map_attr_value(
 
 static int
 rwm_int_filter_map_rewrite(
+               Operation               *op,
                dncookie                *dc,
                Filter                  *f,
                struct berval           *fstr )
@@ -450,7 +451,7 @@ rwm_int_filter_map_rewrite(
        Filter          *p;
        struct berval   atmp,
                        vtmp,
-                       tmp;
+                       *tmp;
        static struct berval
                        /* better than nothing... */
                        ber_bvfalse = BER_BVC( "(!(objectClass=*))" ),
@@ -469,7 +470,7 @@ rwm_int_filter_map_rewrite(
 
        if ( f == NULL ) {
                ber_dupbv( fstr, &ber_bvnone );
-               return -1;
+               return LDAP_OTHER;
        }
 
        switch ( f->f_choice ) {
@@ -477,7 +478,7 @@ rwm_int_filter_map_rewrite(
                if ( map_attr_value( dc, &f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(=)" );
@@ -493,7 +494,7 @@ rwm_int_filter_map_rewrite(
                if ( map_attr_value( dc, &f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(>=)" );
@@ -509,7 +510,7 @@ rwm_int_filter_map_rewrite(
                if ( map_attr_value( dc, &f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(<=)" );
@@ -525,7 +526,7 @@ rwm_int_filter_map_rewrite(
                if ( map_attr_value( dc, &f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(~=)" );
@@ -541,7 +542,7 @@ rwm_int_filter_map_rewrite(
                if ( map_attr_value( dc, &f->f_sub_desc, &atmp,
                                        NULL, NULL, RWM_MAP ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                /* cannot be a DN ... */
@@ -603,7 +604,7 @@ rwm_int_filter_map_rewrite(
                if ( map_attr_value( dc, &f->f_desc, &atmp,
                                        NULL, NULL, RWM_MAP ) )
                {
-                       return -1;
+                       goto computed;
                }
 
                fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
@@ -624,11 +625,13 @@ rwm_int_filter_map_rewrite(
                        f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
 
                for ( p = f->f_list; p != NULL; p = p->f_next ) {
+                       int     rc;
+
                        len = fstr->bv_len;
 
-                       if ( rwm_int_filter_map_rewrite( dc, p, &vtmp ) )
-                       {
-                               return -1;
+                       rc = rwm_int_filter_map_rewrite( op, dc, p, &vtmp );
+                       if ( rc != LDAP_SUCCESS ) {
+                               return rc;
                        }
                        
                        fstr->bv_len += vtmp.bv_len;
@@ -647,7 +650,7 @@ rwm_int_filter_map_rewrite(
                        if ( map_attr_value( dc, &f->f_mr_desc, &atmp,
                                                &f->f_mr_value, &vtmp, RWM_MAP ) )
                        {
-                               return -1;
+                               goto computed;
                        }
 
                } else {
@@ -672,33 +675,39 @@ rwm_int_filter_map_rewrite(
                break;
        }
 
+       case 0:
+computed:;
+               filter_free_x( op, f );
+               f->f_choice = SLAPD_FILTER_COMPUTED;
+               f->f_result = SLAPD_COMPARE_UNDEFINED;
+               /* fallthru */
+
        case SLAPD_FILTER_COMPUTED:
                switch ( f->f_result ) {
                case LDAP_COMPARE_FALSE:
+               /* FIXME: treat UNDEFINED as FALSE */
+               case SLAPD_COMPARE_UNDEFINED:
                        if ( dc->rwmap->rwm_flags & RWM_F_SUPPORT_T_F ) {
-                               tmp = ber_bvtf_false;
+                               tmp = &ber_bvtf_false;
                                break;
                        }
-                       /* fallthru */
-
-               case SLAPD_COMPARE_UNDEFINED:
-                       tmp = ber_bvfalse;
+                       tmp = &ber_bvfalse;
                        break;
 
                case LDAP_COMPARE_TRUE:
                        if ( dc->rwmap->rwm_flags & RWM_F_SUPPORT_T_F ) {
-                               tmp = ber_bvtf_true;
-                       } else {
-                               tmp = ber_bvtrue;
+                               tmp = &ber_bvtf_true;
+                               break;
                        }
+                       tmp = &ber_bvtrue;
                        break;
                        
                default:
-                       tmp = ber_bverror;
+                       tmp = &ber_bverror;
                        break;
                }
 
-               ber_dupbv( fstr, &tmp );
+               ber_dupbv( fstr, tmp );
                break;
                
        default:
@@ -706,11 +715,12 @@ rwm_int_filter_map_rewrite(
                break;
        }
 
-       return 0;
+       return LDAP_SUCCESS;
 }
 
 int
 rwm_filter_map_rewrite(
+               Operation               *op,
                dncookie                *dc,
                Filter                  *f,
                struct berval           *fstr )
@@ -719,10 +729,10 @@ rwm_filter_map_rewrite(
        dncookie        fdc;
        struct berval   ftmp;
 
-       rc = rwm_int_filter_map_rewrite( dc, f, fstr );
+       rc = rwm_int_filter_map_rewrite( op, dc, f, fstr );
 
 #ifdef ENABLE_REWRITE
-       if ( rc != LDAP_SUCCESS ) {
+       if ( rc != 0 ) {
                return rc;
        }
 
@@ -766,8 +776,8 @@ rwm_filter_map_rewrite(
                rc = LDAP_OTHER;
                break;
        }
-
 #endif /* ENABLE_REWRITE */
+
        return rc;
 }
 
@@ -1188,6 +1198,16 @@ rwm_dnattr_result_rewrite(
        return 0;
 }
 
+void
+rwm_mapping_dst_free( void *v_mapping )
+{
+       struct ldapmapping *mapping = v_mapping;
+
+       if ( BER_BVISEMPTY( &mapping[0].m_dst ) ) {
+               rwm_mapping_free( &mapping[ -1 ] );
+       }
+}
+
 void
 rwm_mapping_free( void *v_mapping )
 {
index 4070d5dd09626a2c412df00eecca9cdc95527b4d..561b5b2fd1cc21ab353d410d90f865cca9b500c1 100644 (file)
@@ -122,6 +122,7 @@ typedef struct syncprov_info_t {
        int             si_chktime;
        int             si_numops;      /* number of ops since last checkpoint */
        int             si_nopres;      /* Skip present phase */
+       int             si_usehint;     /* use reload hint */
        time_t  si_chklast;     /* time of last checkpoint */
        Avlnode *si_mods;       /* entries being modified */
        sessionlog      *si_logs;
@@ -382,6 +383,9 @@ findbase_cb( Operation *op, SlapReply *rs )
        return LDAP_SUCCESS;
 }
 
+static Filter generic_filter = { LDAP_FILTER_PRESENT, { 0 }, NULL };
+static struct berval generic_filterstr = BER_BVC("(objectclass=*)");
+
 static int
 syncprov_findbase( Operation *op, fbase_cookie *fc )
 {
@@ -421,6 +425,8 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
                fop.ors_tlimit = SLAP_NO_LIMIT;
                fop.ors_attrs = slap_anlist_no_attrs;
                fop.ors_attrsonly = 1;
+               fop.ors_filter = &generic_filter;
+               fop.ors_filterstr = generic_filterstr;
 
                fop.o_bd->bd_info = on->on_info->oi_orig;
                rc = fop.o_bd->be_search( &fop, &frs );
@@ -728,7 +734,8 @@ syncprov_free_syncop( syncops *so )
 
 /* Send a persistent search response */
 static int
-syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, Entry **e, int mode)
+syncprov_sendresp( Operation *op, opcookie *opc, syncops *so,
+       Entry **e, int mode )
 {
        slap_overinst *on = opc->son;
 
@@ -1943,12 +1950,11 @@ syncprov_op_search( Operation *op, SlapReply *rs )
                /* Is the CSN still present in the database? */
                if ( syncprov_findcsn( op, FIND_CSN ) != LDAP_SUCCESS ) {
                        /* No, so a reload is required */
-#if 0          /* the consumer doesn't seem to send this hint */
-                       if ( op->o_sync_rhint == 0 ) {
+                       /* the 2.2 consumer doesn't send this hint */
+                       if ( si->si_usehint && srs->sr_rhint == 0 ) {
                                send_ldap_error( op, rs, LDAP_SYNC_REFRESH_REQUIRED, "sync cookie is stale" );
                                return rs->sr_err;
                        }
-#endif
                } else {
                        gotstate = 1;
                        /* If changed and doing Present lookup, send Present UUIDs */
@@ -2069,7 +2075,8 @@ syncprov_operational(
 enum {
        SP_CHKPT = 1,
        SP_SESSL,
-       SP_NOPRES
+       SP_NOPRES,
+       SP_USEHINT
 };
 
 static ConfigDriver sp_cf_gen;
@@ -2087,6 +2094,10 @@ static ConfigTable spcfg[] = {
                sp_cf_gen, "( OLcfgOvAt:1.3 NAME 'olcSpNoPresent' "
                        "DESC 'Omit Present phase processing' "
                        "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+       { "syncprov-reloadhint", NULL, 2, 2, 0, ARG_ON_OFF|ARG_MAGIC|SP_USEHINT,
+               sp_cf_gen, "( OLcfgOvAt:1.4 NAME 'olcSpReloadHint' "
+                       "DESC 'Observe Reload Hint in Request control' "
+                       "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
        { NULL, NULL, 0, 0, 0, ARG_IGNORED }
 };
 
@@ -2134,6 +2145,13 @@ sp_cf_gen(ConfigArgs *c)
                                rc = 1;
                        }
                        break;
+               case SP_USEHINT:
+                       if ( si->si_usehint ) {
+                               c->value_int = 1;
+                       } else {
+                               rc = 1;
+                       }
+                       break;
                }
                return rc;
        } else if ( c->op == LDAP_MOD_DELETE ) {
@@ -2154,6 +2172,12 @@ sp_cf_gen(ConfigArgs *c)
                        else
                                rc = LDAP_NO_SUCH_ATTRIBUTE;
                        break;
+               case SP_USEHINT:
+                       if ( si->si_usehint )
+                               si->si_usehint = 0;
+                       else
+                               rc = LDAP_NO_SUCH_ATTRIBUTE;
+                       break;
                }
                return rc;
        }
@@ -2188,6 +2212,9 @@ sp_cf_gen(ConfigArgs *c)
        case SP_NOPRES:
                si->si_nopres = c->value_int;
                break;
+       case SP_USEHINT:
+               si->si_usehint = c->value_int;
+               break;
        }
        return rc;
 }
@@ -2275,8 +2302,8 @@ syncprov_db_open(
        }
 
        if ( BER_BVISEMPTY( &si->si_ctxcsn ) ) {
-               slap_get_csn( op, si->si_ctxcsnbuf, sizeof(si->si_ctxcsnbuf),
-                               &si->si_ctxcsn, 0 );
+               si->si_ctxcsn.bv_len = sizeof( si->si_ctxcsnbuf );
+               slap_get_csn( op, &si->si_ctxcsn, 0 );
        }
 
        /* If our ctxcsn is different from what was read from the root
@@ -2435,6 +2462,7 @@ static int syncprov_parseCtrl (
                        rs->sr_text = "Sync control : cookie decoding error";
                        return LDAP_PROTOCOL_ERROR;
                }
+               tag = ber_peek_tag( ber, &len );
        }
        if ( tag == LDAP_TAG_RELOAD_HINT ) {
                if (( ber_scanf( ber, /*{*/ "b", &rhint )) == LBER_ERROR ) {
@@ -2509,6 +2537,8 @@ syncprov_init()
 
        syncprov.on_bi.bi_cf_ocs = spocs;
 
+       generic_filter.f_desc = slap_schema.si_ad_objectClass;
+
        rc = config_register_schema( spcfg, spocs );
        if ( rc ) return rc;
 
index 4c69a2e6b5f4845ec72990bf3bec472b807573ab..fee10439dd2f1af387073e6fef9010b262c5f333 100644 (file)
@@ -273,12 +273,7 @@ old_good:
                cb2.sc_private = qpw;   /* let Modify know this was pwdMod,
                                         * if it cares... */
 
-               rs->sr_err = slap_mods_opattrs( op, ml, qpw->rs_modtail, &rs->sr_text,
-                       NULL, 0, 1 );
-               
-               if ( rs->sr_err == LDAP_SUCCESS ) {
-                       rs->sr_err = op->o_bd->be_modify( op, rs );
-               }
+               rs->sr_err = op->o_bd->be_modify( op, rs );
                if ( rs->sr_err == LDAP_SUCCESS ) {
                        rs->sr_rspdata = rsp;
                } else if ( rsp ) {
index e110c3865fe2f411224fce6931c7d9a5ce57cfed..e1aac002ae840f66d247abdbf5a998ac0c23d2af 100644 (file)
@@ -114,7 +114,7 @@ LDAP_SLAPD_F (int) acl_string_expand LDAP_P((
  */
 LDAP_SLAPD_V (char *) style_strings[];
 
-LDAP_SLAPD_F (void) parse_acl LDAP_P(( Backend *be,
+LDAP_SLAPD_F (int) parse_acl LDAP_P(( Backend *be,
        const char *fname, int lineno,
        int argc, char **argv, int pos ));
 
@@ -206,6 +206,12 @@ LDAP_SLAPD_F (int) slap_mods2entry LDAP_P(( Modifications *mods, Entry **e,
 LDAP_SLAPD_F (int) slap_entry2mods LDAP_P(( Entry *e,
                                                Modifications **mods, const char **text,
                                                char *textbuf, size_t textlen ));
+LDAP_SLAPD_F( int ) slap_add_opattrs(
+       Operation *op,
+       const char **text,
+       char *textbuf, size_t textlen,
+       int manage_ctxcsn );
+
 
 /*
  * at.c
@@ -426,6 +432,9 @@ LDAP_SLAPD_F (int) overlay_op_walk LDAP_P((
  */
 LDAP_SLAPD_F (int) slap_loglevel_register LDAP_P (( slap_mask_t m, struct berval *s ));
 LDAP_SLAPD_F (int) str2loglevel LDAP_P(( const char *s, int *l ));
+LDAP_SLAPD_F (int) loglevel2bvarray LDAP_P(( int l, BerVarray *bva ));
+LDAP_SLAPD_F (const char *) loglevel2str LDAP_P(( int l ));
+LDAP_SLAPD_F (int) loglevel2bv LDAP_P(( int l, struct berval *bv ));
 
 /*
  * ch_malloc.c
@@ -645,8 +654,13 @@ LDAP_SLAPD_F (int) connection_state_closing LDAP_P(( Connection *c ));
 LDAP_SLAPD_F (const char *) connection_state2str LDAP_P(( int state ))
        LDAP_GCCATTR((const));
 
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+LDAP_SLAPD_F (int) connection_write_activate LDAP_P((ber_socket_t s));
+LDAP_SLAPD_F (int) connection_read_activate LDAP_P((ber_socket_t s));
+#else
 LDAP_SLAPD_F (int) connection_write LDAP_P((ber_socket_t s));
 LDAP_SLAPD_F (int) connection_read LDAP_P((ber_socket_t s));
+#endif
 
 LDAP_SLAPD_F (unsigned long) connections_nextid(void);
 
@@ -693,7 +707,7 @@ LDAP_SLAPD_F (void) slap_get_commit_csn LDAP_P((
 LDAP_SLAPD_F (void) slap_rewind_commit_csn LDAP_P(( Operation * ));
 LDAP_SLAPD_F (void) slap_graduate_commit_csn LDAP_P(( Operation * ));
 LDAP_SLAPD_F (Entry *) slap_create_context_csn_entry LDAP_P(( Backend *, struct berval *));
-LDAP_SLAPD_F (int) slap_get_csn LDAP_P(( Operation *, char *, int, struct berval *, int ));
+LDAP_SLAPD_F (int) slap_get_csn LDAP_P(( Operation *, struct berval *, int ));
 LDAP_SLAPD_F (void) slap_queue_csn LDAP_P(( Operation *, struct berval * ));
 
 /*
@@ -704,7 +718,10 @@ LDAP_SLAPD_F (int) slapd_daemon_init( const char *urls );
 LDAP_SLAPD_F (int) slapd_daemon_destroy(void);
 LDAP_SLAPD_F (int) slapd_daemon(void);
 LDAP_SLAPD_F (Listener **)     slapd_get_listeners LDAP_P((void));
-LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wasactive, int wake));
+LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wasactive,
+       int wake, int locked ));
+LDAP_SLAPD_F (void) slapd_sd_lock();
+LDAP_SLAPD_F (void) slapd_sd_unlock();
 
 LDAP_SLAPD_F (RETSIGTYPE) slap_sig_shutdown LDAP_P((int sig));
 LDAP_SLAPD_F (RETSIGTYPE) slap_sig_wake LDAP_P((int sig));
@@ -713,7 +730,7 @@ LDAP_SLAPD_F (void) slap_wake_listener LDAP_P((void));
 LDAP_SLAPD_F (void) slapd_set_write LDAP_P((ber_socket_t s, int wake));
 LDAP_SLAPD_F (void) slapd_clr_write LDAP_P((ber_socket_t s, int wake));
 LDAP_SLAPD_F (void) slapd_set_read LDAP_P((ber_socket_t s, int wake));
-LDAP_SLAPD_F (void) slapd_clr_read LDAP_P((ber_socket_t s, int wake));
+LDAP_SLAPD_F (int) slapd_clr_read LDAP_P((ber_socket_t s, int wake));
 
 LDAP_SLAPD_V (volatile sig_atomic_t) slapd_abrupt_shutdown;
 LDAP_SLAPD_V (volatile sig_atomic_t) slapd_shutdown;
@@ -858,7 +875,7 @@ typedef int (SLAP_EXTOP_GETOID_FN) LDAP_P((
        int index, struct berval *oid, int blen ));
 
 LDAP_SLAPD_F (int) load_extop LDAP_P((
-       struct berval *ext_oid,
+       const struct berval *ext_oid,
        slap_mask_t flags,
        SLAP_EXTOP_MAIN_FN *ext_main ));
 
@@ -1037,12 +1054,9 @@ LDAP_SLAPD_F( void ) slap_timestamp(
        time_t *tm,
        struct berval *bv );
 
-LDAP_SLAPD_F( int ) slap_mods_opattrs(
+LDAP_SLAPD_F( void ) slap_mods_opattrs(
        Operation *op,
        Modifications *mods,
-       Modifications **modlist,
-       const char **text,
-       char *textbuf, size_t textlen,
        int manage_ctxcsn );
 
 /*
@@ -1206,6 +1220,7 @@ LDAP_SLAPD_F (int) parse_oidm LDAP_P((
 LDAP_SLAPD_F (void) slap_op_init LDAP_P(( void ));
 LDAP_SLAPD_F (void) slap_op_destroy LDAP_P(( void ));
 LDAP_SLAPD_F (void) slap_op_free LDAP_P(( Operation *op ));
+LDAP_SLAPD_F (void) slap_op_time LDAP_P(( time_t *t, int *n ));
 LDAP_SLAPD_F (Operation *) slap_op_alloc LDAP_P((
        BerElement *ber, ber_int_t msgid,
        ber_tag_t tag, ber_int_t id ));
@@ -1722,6 +1737,7 @@ LDAP_SLAPD_V (time_t)             starttime;
 
 LDAP_SLAPD_V (ldap_pvt_thread_pool_t)  connection_pool;
 LDAP_SLAPD_V (int)                     connection_pool_max;
+LDAP_SLAPD_V (int)                     slap_tool_thread_max;
 
 LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) entry2str_mutex;
 LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) replog_mutex;
index 6ee58c16a383e08d22a337ddaa91de0727a77059..a0feb62b87ca022bcf19cde26920acc67d5c9e25 100644 (file)
@@ -300,21 +300,19 @@ send_ldap_response(
        }
 
        if ( op->o_callback ) {
-               int             first = 1;
-               slap_callback   *sc = op->o_callback,
-                               *sc_next = op->o_callback;
+               slap_callback   *sc = op->o_callback, **sc_prev = &sc, *sc_next;
 
                rc = SLAP_CB_CONTINUE;
                for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
                        sc_next = op->o_callback->sc_next;
                        if ( op->o_callback->sc_response ) {
                                rc = op->o_callback->sc_response( op, rs );
-                               if ( first && op->o_callback == NULL ) {
-                                       sc = NULL;
+                               if ( op->o_callback != *sc_prev ) {
+                                       *sc_prev = op->o_callback;
                                }
-                               if ( rc != SLAP_CB_CONTINUE ) break;
+                               if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
                        }
-                       first = 0;
+                       sc_prev = &op->o_callback->sc_next;
                }
 
                op->o_callback = sc;
@@ -456,18 +454,18 @@ cleanup:;
 
 clean2:;
        if ( op->o_callback ) {
-               int             first = 1;
-               slap_callback   *sc = op->o_callback, *sc_next;
+               slap_callback   *sc = op->o_callback, **sc_prev = &sc, *sc_next;
 
                for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
                        sc_next = op->o_callback->sc_next;
                        if ( op->o_callback->sc_cleanup ) {
                                (void)op->o_callback->sc_cleanup( op, rs );
-                               if ( first && op->o_callback != sc ) {
-                                       sc = op->o_callback;
+                               if ( op->o_callback != *sc_prev ) {
+                                       *sc_prev = op->o_callback;
                                }
+                               if ( !op->o_callback ) break;
                        }
-                       first = 0;
+                       sc_prev = &op->o_callback->sc_next;
                }
                op->o_callback = sc;
        }
@@ -700,9 +698,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
        }
 
        if ( op->o_callback ) {
-               int             first = 1;
-               slap_callback   *sc = op->o_callback,
-                               *sc_next = op->o_callback;
+               slap_callback   *sc = op->o_callback, **sc_prev = &sc, *sc_next;
 
                rc = SLAP_CB_CONTINUE;
                for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next )
@@ -710,12 +706,12 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        sc_next = op->o_callback->sc_next;
                        if ( op->o_callback->sc_response ) {
                                rc = op->o_callback->sc_response( op, rs );
-                               if ( first && op->o_callback == NULL ) {
-                                       sc = NULL;
+                               if ( op->o_callback != *sc_prev ) {
+                                       *sc_prev = op->o_callback;
                                }
-                               if ( rc != SLAP_CB_CONTINUE ) break;
+                               if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
                        }
-                       first = 0;
+                       sc_prev = &op->o_callback->sc_next;
                }
 
                op->o_callback = sc;
@@ -1148,18 +1144,18 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
 error_return:;
        if ( op->o_callback ) {
-               int             first = 1;
-               slap_callback   *sc = op->o_callback, *sc_next;
+               slap_callback   *sc = op->o_callback, **sc_prev = &sc, *sc_next;
 
                for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
                        sc_next = op->o_callback->sc_next;
                        if ( op->o_callback->sc_cleanup ) {
                                (void)op->o_callback->sc_cleanup( op, rs );
-                               if ( first && op->o_callback != sc ) {
-                                       sc = op->o_callback;
+                               if ( op->o_callback != *sc_prev ) {
+                                       *sc_prev = op->o_callback;
                                }
+                               if ( !op->o_callback ) break;
                        }
-                       first = 0;
+                       sc_prev = &op->o_callback->sc_next;
                }
                op->o_callback = sc;
        }
@@ -1205,21 +1201,19 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 
        rs->sr_type = REP_SEARCHREF;
        if ( op->o_callback ) {
-               int             first = 1;
-               slap_callback   *sc = op->o_callback,
-                               *sc_next = op->o_callback;
+               slap_callback   *sc = op->o_callback, **sc_prev = &sc, *sc_next;
 
                rc = SLAP_CB_CONTINUE;
                for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
                        sc_next = op->o_callback->sc_next;
                        if ( op->o_callback->sc_response ) {
                                rc = op->o_callback->sc_response( op, rs );
-                               if ( first && op->o_callback == NULL ) {
-                                       sc = NULL;
+                               if ( op->o_callback != *sc_prev ) {
+                                       *sc_prev = op->o_callback;
                                }
-                               if ( rc != SLAP_CB_CONTINUE ) break;
+                               if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
                        }
-                       first = 0;
+                       sc_prev = &op->o_callback->sc_next;
                }
 
                op->o_callback = sc;
@@ -1351,18 +1345,18 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 
 rel:
        if ( op->o_callback ) {
-               int             first = 1;
-               slap_callback   *sc = op->o_callback, *sc_next;
+               slap_callback   *sc = op->o_callback, **sc_prev = &sc, *sc_next;
 
                for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
                        sc_next = op->o_callback->sc_next;
                        if ( op->o_callback->sc_cleanup ) {
                                (void)op->o_callback->sc_cleanup( op, rs );
-                               if ( first && op->o_callback != sc ) {
-                                       sc = op->o_callback;
+                               if ( op->o_callback != *sc_prev ) {
+                                       *sc_prev = op->o_callback;
                                }
+                               if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
                        }
-                       first = 0;
+                       sc_prev = &op->o_callback->sc_next;
                }
                op->o_callback = sc;
        }
index 66c591a956c5496648599ac266b835508f5a078a..394c0a087130104e7061f95d9e95aee1f71a6356 100644 (file)
@@ -374,7 +374,7 @@ slap_auxprop_lookup(
                                op.o_tag = LDAP_REQ_SEARCH;
                                op.o_ndn = conn->c_ndn;
                                op.o_callback = &cb;
-                               op.o_time = slap_get_time();
+                               slap_op_time( &op.o_time, &op.o_tincr );
                                op.o_do_not_cache = 1;
                                op.o_is_auth_check = 1;
                                op.o_req_dn = op.o_req_ndn;
@@ -472,22 +472,17 @@ slap_auxprop_store(
                        &text, textbuf, textlen );
 
                if ( rc == LDAP_SUCCESS ) {
-                       rc = slap_mods_opattrs( &op, modlist, modtail,
-                                       &text, textbuf, textlen, 1 );
-
-                       if ( rc == LDAP_SUCCESS ) {
-                               op.o_hdr = conn->c_sasl_bindop->o_hdr;
-                               op.o_tag = LDAP_REQ_MODIFY;
-                               op.o_ndn = op.o_req_ndn;
-                               op.o_callback = &cb;
-                               op.o_time = slap_get_time();
-                               op.o_do_not_cache = 1;
-                               op.o_is_auth_check = 1;
-                               op.o_req_dn = op.o_req_ndn;
-                               op.orm_modlist = modlist;
-
-                               rc = op.o_bd->be_modify( &op, &rs );
-                       }
+                       op.o_hdr = conn->c_sasl_bindop->o_hdr;
+                       op.o_tag = LDAP_REQ_MODIFY;
+                       op.o_ndn = op.o_req_ndn;
+                       op.o_callback = &cb;
+                       slap_op_time( &op.o_time, &op.o_tincr );
+                       op.o_do_not_cache = 1;
+                       op.o_is_auth_check = 1;
+                       op.o_req_dn = op.o_req_ndn;
+                       op.orm_modlist = modlist;
+
+                       rc = op.o_bd->be_modify( &op, &rs );
                }
        }
        slap_mods_free( modlist, 1 );
index d2d2facdad463f010490fff1a4da1d61ddec357a..a7ef89783d27b3b3c6503ed3050476fe324e3519 100644 (file)
@@ -1831,7 +1831,7 @@ exact_match:
        op.o_tag = LDAP_REQ_SEARCH;
        op.o_ndn = *authc;
        op.o_callback = &cb;
-       op.o_time = slap_get_time();
+       slap_op_time( &op.o_time, &op.o_tincr );
        op.o_do_not_cache = 1;
        op.o_is_auth_check = 1;
        /* use req_ndn as req_dn instead of non-pretty base of uri */
@@ -1999,7 +1999,7 @@ slap_sasl2dn(
        op.o_tag = LDAP_REQ_SEARCH;
        op.o_ndn = opx->o_conn->c_ndn;
        op.o_callback = &cb;
-       op.o_time = slap_get_time();
+       slap_op_time( &op.o_time, &op.o_tincr );
        op.o_do_not_cache = 1;
        op.o_is_auth_check = 1;
        op.ors_deref = LDAP_DEREF_NEVER;
index f8671b2d6f5b51ad354f6570fb4b2d601733ebba..1bb4cc9567f4fd1dc98a6cb8d78b8066cf252ae5 100644 (file)
@@ -347,6 +347,12 @@ attributetype ( 2.5.4.65 NAME 'pseudonym'
 
 # Standard object classes from RFC2256
 
+# system schema
+#objectclass ( 2.5.6.0 NAME 'top'
+#      DESC 'RFC2256: top of the superclass chain'
+#      ABSTRACT
+#      MUST objectClass )
+
 # system schema
 #objectclass ( 2.5.6.1 NAME 'alias'
 #      DESC 'RFC2256: an alias'
index 42f03d8f260a5d828e2939a3c4d0b52208d8aba6..b4649932bfe5dcab7488a47607b67f74dc065263 100644 (file)
@@ -169,16 +169,13 @@ octetStringOrderingMatch(
        return LDAP_SUCCESS;
 }
 
-void
-hashDigestify(
+static void
+hashPreset(
        HASH_CONTEXT *HASHcontext,
-       unsigned char *HASHdigest,
        struct berval *prefix,
        char pre,
        Syntax *syntax,
-       MatchingRule *mr,
-       unsigned char *value,
-       int value_len)
+       MatchingRule *mr)
 {
        HASH_Init(HASHcontext);
        if(prefix && prefix->bv_len > 0) {
@@ -188,11 +185,21 @@ hashDigestify(
        if(pre) HASH_Update(HASHcontext, (unsigned char*)&pre, sizeof(pre));
        HASH_Update(HASHcontext, (unsigned char*)syntax->ssyn_oid, syntax->ssyn_oidlen);
        HASH_Update(HASHcontext, (unsigned char*)mr->smr_oid, mr->smr_oidlen);
-       HASH_Update(HASHcontext, value, value_len);
-       HASH_Final(HASHdigest, HASHcontext);
        return;
 }
 
+static void
+hashIter(
+       HASH_CONTEXT *HASHcontext,
+       unsigned char *HASHdigest,
+       unsigned char *value,
+       int len)
+{
+       HASH_CONTEXT ctx = *HASHcontext;
+       HASH_Update( &ctx, value, len );
+       HASH_Final( HASHdigest, &ctx );
+}
+
 /* Index generation function */
 int octetStringIndexer(
        slap_mask_t use,
@@ -225,9 +232,10 @@ int octetStringIndexer(
        slen = syntax->ssyn_oidlen;
        mlen = mr->smr_oidlen;
 
+       hashPreset( &HASHcontext, prefix, 0, syntax, mr);
        for( i=0; !BER_BVISNULL( &values[i] ); i++ ) {
-               hashDigestify( &HASHcontext, HASHdigest, prefix, 0,
-                       syntax, mr, (unsigned char *)values[i].bv_val, values[i].bv_len );
+               hashIter( &HASHcontext, HASHdigest,
+                       (unsigned char *)values[i].bv_val, values[i].bv_len );
                ber_dupbv_x( &keys[i], &digest, ctx );
        }
 
@@ -263,8 +271,9 @@ int octetStringFilter(
 
        keys = slap_sl_malloc( sizeof( struct berval ) * 2, ctx );
 
-       hashDigestify( &HASHcontext, HASHdigest, prefix, 0,
-               syntax, mr, (unsigned char *)value->bv_val, value->bv_len );
+       hashPreset( &HASHcontext, prefix, 0, syntax, mr );
+       hashIter( &HASHcontext, HASHdigest,
+               (unsigned char *)value->bv_val, value->bv_len );
 
        ber_dupbv_x( keys, &digest, ctx );
        BER_BVZERO( &keys[1] );
@@ -414,7 +423,7 @@ octetStringSubstringsIndexer(
        size_t slen, mlen;
        BerVarray keys;
 
-       HASH_CONTEXT HASHcontext;
+       HASH_CONTEXT HCany, HCini, HCfin;
        unsigned char HASHdigest[HASH_BYTES];
        struct berval digest;
        digest.bv_val = (char *)HASHdigest;
@@ -460,6 +469,13 @@ octetStringSubstringsIndexer(
        slen = syntax->ssyn_oidlen;
        mlen = mr->smr_oidlen;
 
+       if ( flags & SLAP_INDEX_SUBSTR_ANY )
+               hashPreset( &HCany, prefix, SLAP_INDEX_SUBSTR_PREFIX, syntax, mr );
+       if( flags & SLAP_INDEX_SUBSTR_INITIAL )
+               hashPreset( &HCini, prefix, SLAP_INDEX_SUBSTR_INITIAL_PREFIX, syntax, mr );
+       if( flags & SLAP_INDEX_SUBSTR_FINAL )
+               hashPreset( &HCfin, prefix, SLAP_INDEX_SUBSTR_FINAL_PREFIX, syntax, mr );
+
        nkeys = 0;
        for ( i = 0; !BER_BVISNULL( &values[i] ); i++ ) {
                ber_len_t j,max;
@@ -467,12 +483,12 @@ octetStringSubstringsIndexer(
                if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
                        ( values[i].bv_len >= index_substr_any_len ) )
                {
-                       char pre = SLAP_INDEX_SUBSTR_PREFIX;
                        max = values[i].bv_len - (index_substr_any_len - 1);
 
                        for( j=0; j<max; j++ ) {
-                               hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
-                                       syntax, mr, (unsigned char *)&values[i].bv_val[j], index_substr_any_len);
+                               hashIter( &HCany, HASHdigest,
+                                       (unsigned char *)&values[i].bv_val[j],
+                                       index_substr_any_len );
                                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
                        }
                }
@@ -484,19 +500,16 @@ octetStringSubstringsIndexer(
                        ? index_substr_if_maxlen : values[i].bv_len;
 
                for( j=index_substr_if_minlen; j<=max; j++ ) {
-                       char pre;
 
                        if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
-                               pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
-                               hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
-                                       syntax, mr, (unsigned char *)values[i].bv_val, j );
+                               hashIter( &HCini, HASHdigest,
+                                       (unsigned char *)values[i].bv_val, j );
                                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
                        }
 
                        if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
-                               pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
-                               hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
-                                       syntax, mr, (unsigned char *)&values[i].bv_val[values[i].bv_len-j], j );
+                               hashIter( &HCfin, HASHdigest,
+                                       (unsigned char *)&values[i].bv_val[values[i].bv_len-j], j );
                                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
                        }
 
@@ -596,8 +609,9 @@ octetStringSubstringsFilter (
                klen = index_substr_if_maxlen < value->bv_len
                        ? index_substr_if_maxlen : value->bv_len;
 
-               hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
-                       syntax, mr, (unsigned char *)value->bv_val, klen );
+               hashPreset( &HASHcontext, prefix, pre, syntax, mr );
+               hashIter( &HASHcontext, HASHdigest,
+                       (unsigned char *)value->bv_val, klen );
                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
 
                /* If initial is too long and we have subany indexed, use it
@@ -607,10 +621,11 @@ octetStringSubstringsFilter (
                {
                        ber_len_t j;
                        pre = SLAP_INDEX_SUBSTR_PREFIX;
+                       hashPreset( &HASHcontext, prefix, pre, syntax, mr);
                        for ( j=index_substr_if_maxlen-1; j <= value->bv_len - index_substr_any_len; j+=index_substr_any_step )
                        {
-                               hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
-                                       syntax, mr, (unsigned char *)&value->bv_val[j], index_substr_any_len );
+                               hashIter( &HASHcontext, HASHdigest,
+                                       (unsigned char *)&value->bv_val[j], index_substr_any_len );
                                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
                        }
                }
@@ -628,12 +643,13 @@ octetStringSubstringsFilter (
 
                        value = &sa->sa_any[i];
 
+                       hashPreset( &HASHcontext, prefix, pre, syntax, mr);
                        for(j=0;
                                j <= value->bv_len - index_substr_any_len;
                                j += index_substr_any_step )
                        {
-                               hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
-                                       syntax, mr, (unsigned char *)&value->bv_val[j], klen ); 
+                               hashIter( &HASHcontext, HASHdigest,
+                                       (unsigned char *)&value->bv_val[j], klen ); 
                                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
                        }
                }
@@ -649,8 +665,9 @@ octetStringSubstringsFilter (
                klen = index_substr_if_maxlen < value->bv_len
                        ? index_substr_if_maxlen : value->bv_len;
 
-               hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
-                       syntax, mr, (unsigned char *)&value->bv_val[value->bv_len-klen], klen );
+               hashPreset( &HASHcontext, prefix, pre, syntax, mr );
+               hashIter( &HASHcontext, HASHdigest,
+                       (unsigned char *)&value->bv_val[value->bv_len-klen], klen );
                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
 
                /* If final is too long and we have subany indexed, use it
@@ -660,10 +677,11 @@ octetStringSubstringsFilter (
                {
                        ber_len_t j;
                        pre = SLAP_INDEX_SUBSTR_PREFIX;
+                       hashPreset( &HASHcontext, prefix, pre, syntax, mr);
                        for ( j=0; j <= value->bv_len - index_substr_if_maxlen; j+=index_substr_any_step )
                        {
-                               hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
-                                       syntax, mr, (unsigned char *)&value->bv_val[j], index_substr_any_len );
+                               hashIter( &HASHcontext, HASHdigest,
+                                       (unsigned char *)&value->bv_val[j], index_substr_any_len );
                                ber_dupbv_x( &keys[nkeys++], &digest, ctx );
                        }
                }
index 3faf4595df72b9e853ee7a8fab889699fb9f36ef..4514a45d181760b53179f041674dfc2915dc5cdd 100644 (file)
@@ -60,6 +60,12 @@ LDAP_BEGIN_DECL
 
 
 #ifdef LDAP_DEVEL
+#define SLAP_LIGHTWEIGHT_DISPATCHER /* experimental slapd architecture */
+#define SLAP_MULTI_CONN_ARRAY
+#ifdef LDAP_PVT_THREAD_POOL_SEM_LOAD_CONTROL
+#define SLAP_SEM_LOAD_CONTROL
+#endif /* LDAP_PVT_THREAD_POOL_SEM_LOAD_CONTROL */
+
 #define SLAP_ACL_HONOR_DISCLOSE        /* partially implemented */
 #define SLAP_ACL_HONOR_MANAGE  /* not yet implemented */
 #define SLAP_DYNACL
@@ -2549,6 +2555,7 @@ typedef struct slap_op {
        BerElement      *o_res_ber;     /* ber of the CLDAP reply or readback control */
        slap_callback *o_callback;      /* callback pointers */
        LDAPControl     **o_ctrls;       /* controls */
+       struct berval o_csn;
 
        void    *o_private;     /* anything the backend needs */
 
@@ -2735,7 +2742,10 @@ struct slap_listener {
 #ifdef LDAP_CONNECTIONLESS
        int     sl_is_udp;              /* UDP listener is also data port */
 #endif
-       int     sl_is_mute;     /* Listening is temporarily disabled */
+       int     sl_mute;        /* Listener is temporarily disabled due to emfile */
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+       int     sl_busy;        /* Listener is busy (accept thread activated) */
+#endif
        ber_socket_t sl_sd;
        Sockaddr sl_sa;
 #define sl_addr        sl_sa.sa_in_addr
index eb82e2da38502e6f50cbb0c4dbe139bc9e3582ed..f0fe956ad7d1e1ff6052a364cf60e559e4d9c025 100644 (file)
@@ -62,7 +62,7 @@ usage( int tool, const char *progname )
                break;
 
        case SLAPADD:
-               options = " [-c]\n\t[-n databasenumber | -b suffix]\n"
+               options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]\n"
                        "\t[-l ldiffile] [-q] [-u] [-w]\n";
                break;
 
@@ -71,7 +71,7 @@ usage( int tool, const char *progname )
                break;
 
        case SLAPCAT:
-               options = " [-c]\n\t[-n databasenumber | -b suffix]"
+               options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]"
                        " [-l ldiffile] [-a filter]\n";
                break;
 
@@ -80,7 +80,7 @@ usage( int tool, const char *progname )
                break;
 
        case SLAPINDEX:
-               options = " [-c]\n\t[-n databasenumber | -b suffix] [-q]\n";
+               options = " [-c]\n\t[-g] [-n databasenumber | -b suffix] [-q]\n";
                break;
 
        case SLAPTEST:
@@ -178,6 +178,7 @@ slap_tool_init(
        int rc, i, dbnum;
        int mode = SLAP_TOOL_MODE;
        int truncatemode = 0;
+       int use_glue = 1;
 
 #ifdef CSRIMALLOC
        leakfilename = malloc( strlen( progname ) + STRLENOF( ".leak" ) + 1 );
@@ -190,11 +191,11 @@ slap_tool_init(
 
        switch( tool ) {
        case SLAPADD:
-               options = "b:cd:f:F:l:n:qtuvw";
+               options = "b:cd:f:F:gl:n:qtuvw";
                break;
 
        case SLAPCAT:
-               options = "a:b:cd:f:F:l:n:s:v";
+               options = "a:b:cd:f:F:gl:n:s:v";
                mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
                break;
 
@@ -214,7 +215,7 @@ slap_tool_init(
                break;
 
        case SLAPINDEX:
-               options = "b:cd:f:F:n:qv";
+               options = "b:cd:f:F:gn:qv";
                mode |= SLAP_TOOL_READMAIN;
                break;
 
@@ -244,7 +245,38 @@ slap_tool_init(
                        break;
 
                case 'd':       /* turn on debugging */
-                       ldap_debug += atoi( optarg );
+#ifdef LDAP_DEBUG
+                       if ( optarg != NULL && optarg[ 0 ] != '-' && !isdigit( optarg[ 0 ] ) )
+                       {
+                               int     level;
+
+                               if ( str2loglevel( optarg, &level ) ) {
+                                       fprintf( stderr,
+                                               "unrecognized log level "
+                                               "\"%s\"\n", optarg );
+                                       exit( EXIT_FAILURE );
+                               }
+
+                               ldap_debug |= level;
+
+                       } else {
+                               int     level;
+                               char    *next = NULL;
+
+                               level = strtol( optarg, &next, 0 );
+                               if ( next == NULL || next[ 0 ] != '\0' ) {
+                                       fprintf( stderr,
+                                               "unrecognized log level "
+                                               "\"%s\"\n", optarg );
+                                       exit( EXIT_FAILURE );
+                               }
+                               ldap_debug |= level;
+                       }
+#else
+                       if ( atoi( optarg ) != 0 )
+                               fputs( "must compile with LDAP_DEBUG for debugging\n",
+                                      stderr );
+#endif
                        break;
 
                case 'D':
@@ -259,6 +291,10 @@ slap_tool_init(
                        confdir = strdup( optarg );
                        break;
 
+               case 'g':       /* disable subordinate glue */
+                       use_glue = 0;
+                       break;
+
                case 'l':       /* LDIF file */
                        ldiffile = strdup( optarg );
                        break;
@@ -424,11 +460,14 @@ slap_tool_init(
                break;
        }
 
-       rc = glue_sub_attach();
+       if ( use_glue ) {
+               rc = glue_sub_attach();
 
-       if ( rc != 0 ) {
-               fprintf( stderr, "%s: subordinate configuration error\n", progname );
-               exit( EXIT_FAILURE );
+               if ( rc != 0 ) {
+                       fprintf( stderr,
+                               "%s: subordinate configuration error\n", progname );
+                       exit( EXIT_FAILURE );
+               }
        }
 
        rc = slap_schema_check();
index 3820f57af23866593c0a9f62f3f6501400386a6b..376fd48abb9820be32a9b6135b7488588f2253a1 100644 (file)
@@ -409,7 +409,6 @@ slapi_delete_internal_pb( Slapi_PBlock *pb )
        PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_DELETE );
 
        slapi_int_func_internal_pb( pb, op_delete );
-       slap_graduate_commit_csn( pb->pb_op );
 
        return 0;
 }
@@ -492,7 +491,6 @@ slapi_add_internal_pb( Slapi_PBlock *pb )
        }
 
 cleanup:
-       slap_graduate_commit_csn( pb->pb_op );
 
        if ( pb->pb_op->ora_e != NULL ) {
                slapi_entry_free( pb->pb_op->ora_e );
@@ -524,7 +522,6 @@ slapi_modrdn_internal_pb( Slapi_PBlock *pb )
        slapi_int_func_internal_pb( pb, op_modrdn );
 
 cleanup:
-       slap_graduate_commit_csn( pb->pb_op );
 
        return 0;
 }
@@ -561,7 +558,6 @@ slapi_modify_internal_pb( Slapi_PBlock *pb )
        slapi_int_func_internal_pb( pb, op_modify );
 
 cleanup:
-       slap_graduate_commit_csn( pb->pb_op );
 
        return 0;
 }
index 2bd5d1b0f383b2b3aadcbbca57d4da7df2dfa487..245389223006170efbd49f1d80876b6e30ad5955 100644 (file)
 #include <ac/ctype.h>
 #include <ac/string.h>
 #include <ac/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <ac/unistd.h>
+#include <ac/errno.h>
 
 #include <lber.h>
 #include <ldif.h>
 
 #include "slapcommon.h"
 
+static int
+test_file( const char *fname, const char *ftype )
+{
+       struct stat     st;
+       int             save_errno;
+
+       switch ( stat( fname, &st ) ) {
+       case 0:
+               if ( !( st.st_mode & S_IWUSR ) ) {
+                       Debug( LDAP_DEBUG_ANY, "%s file "
+                               "\"%s\" exists, but user does not have access\n",
+                               ftype, fname, 0 );
+                       return -1;
+               }
+               break;
+
+       case -1:
+       default:
+               save_errno = errno;
+               if ( save_errno == ENOENT ) {
+                       FILE            *fp = fopen( fname, "w" );
+
+                       if ( fp == NULL ) {
+                               save_errno = errno;
+
+                               Debug( LDAP_DEBUG_ANY, "unable to open file "
+                                       "\"%s\": %d (%s)\n",
+                                       fname,
+                                       save_errno, strerror( save_errno ) );
+
+                               return -1;
+                       }
+                       unlink( fname );
+                       break;
+               }
+
+               Debug( LDAP_DEBUG_ANY, "unable to stat file "
+                       "\"%s\": %d (%s)\n",
+                       slapd_pid_file,
+                       save_errno, strerror( save_errno ) );
+               return -1;
+       }
+}
+
 int
 slaptest( int argc, char **argv )
 {
@@ -42,6 +89,18 @@ slaptest( int argc, char **argv )
 
        slap_tool_init( progname, SLAPTEST, argc, argv );
 
+       if ( slapd_pid_file != NULL ) {
+               if ( test_file( slapd_pid_file, "pid" ) ) {
+                       return EXIT_FAILURE;
+               }
+       }
+
+       if ( slapd_args_file != NULL ) {
+               if ( test_file( slapd_args_file, "args" ) ) {
+                       return EXIT_FAILURE;
+               }
+       }
+
        fprintf( stderr, "config file testing succeeded\n");
 
        slap_tool_destroy();
index deeacc5f4958fa5948145ea9c85103fceff92bca..4c1cbf49f0bd77468316b2e064f47edef336dc92 100644 (file)
@@ -41,14 +41,19 @@ struct nonpresent_entry {
 #define        SYNCDATA_ACCESSLOG      1       /* entries are accesslog format */
 #define        SYNCDATA_CHANGELOG      2       /* entries are changelog format */
 
+#define        SYNCLOG_LOGGING         0       /* doing a log-based update */
+#define        SYNCLOG_FALLBACK        1       /* doing a full refresh */
+
 typedef struct syncinfo_s {
        struct slap_backend_db *si_be;
        struct re_s                     *si_re;
        long                            si_rid;
        struct berval           si_provideruri;
        slap_bindconf           si_bindconf;
-       struct berval           si_filterstr;
        struct berval           si_base;
+       struct berval           si_logbase;
+       struct berval           si_filterstr;
+       struct berval           si_logfilterstr;
        int                                     si_scope;
        int                                     si_attrsonly;
        char                            *si_anfile;
@@ -59,7 +64,8 @@ typedef struct syncinfo_s {
        int                                     si_allattrs;
        int                                     si_allopattrs;
        int                                     si_schemachecking;
-       int                                     si_type;
+       int                                     si_type;        /* the active type */
+       int                                     si_ctype;       /* the configured type */
        time_t                          si_interval;
        time_t                          *si_retryinterval;
        int                                     *si_retrynum_init;
@@ -71,6 +77,8 @@ typedef struct syncinfo_s {
        int                                     si_refreshDelete;
        int                                     si_refreshPresent;
        int                                     si_syncdata;
+       int                                     si_logstate;
+       int                                     si_conn_setup;
        Avlnode                         *si_presentlist;
        LDAP                            *si_ld;
        LDAP_LIST_HEAD(np, nonpresent_entry) si_nonpresentlist;
@@ -266,6 +274,33 @@ init_syncrepl(syncinfo_t *si)
        si->si_exattrs = exattrs;       
 }
 
+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 int
 ldap_sync_search(
        syncinfo_t *si,
@@ -277,19 +312,66 @@ ldap_sync_search(
        struct timeval timeout;
        ber_int_t       msgid;
        int rc;
+       int rhint;
+       char *base;
+       char **attrs, *lattrs[8];
+       char *filter;
+       int attrsonly;
+       int scope;
 
        /* setup LDAP SYNC control */
        ber_init2( ber, NULL, LBER_USE_DER );
        ber_set_option( ber, LBER_OPT_BER_MEMCTX, &ctx );
 
+       /* If we're using a log but we have no state, then fallback to
+        * normal mode for a full refresh.
+        */
+       if ( si->si_syncdata && BER_BVISEMPTY( &si->si_syncCookie.ctxcsn ))
+               si->si_logstate = SYNCLOG_FALLBACK;
+
+       /* Use the log parameters if we're in log mode */
+       if ( si->si_syncdata && si->si_logstate == SYNCLOG_LOGGING ) {
+               logschema *ls;
+               if ( si->si_syncdata == SYNCDATA_ACCESSLOG )
+                       ls = &accesslog_sc;
+               else
+                       ls = &changelog_sc;
+               lattrs[0] = ls->ls_dn.bv_val;
+               lattrs[1] = ls->ls_req.bv_val;
+               lattrs[2] = ls->ls_mod.bv_val;
+               lattrs[3] = ls->ls_newRdn.bv_val;
+               lattrs[4] = ls->ls_delRdn.bv_val;
+               lattrs[5] = ls->ls_newSup.bv_val;
+               lattrs[6] = slap_schema.si_ad_entryCSN->ad_cname.bv_val;
+               lattrs[7] = NULL;
+
+               rhint = 0;
+               base = si->si_logbase.bv_val;
+               filter = si->si_logfilterstr.bv_val;
+               attrs = lattrs;
+               attrsonly = 0;
+               scope = LDAP_SCOPE_ONELEVEL;
+       } else {
+               rhint = 1;
+               base = si->si_base.bv_val;
+               filter = si->si_filterstr.bv_val;
+               attrs = si->si_attrs;
+               attrsonly = si->si_attrsonly;
+               scope = si->si_scope;
+       }
+       if ( si->si_syncdata && si->si_logstate == SYNCLOG_FALLBACK ) {
+               si->si_type = LDAP_SYNC_REFRESH_ONLY;
+       } else {
+               si->si_type = si->si_ctype;
+       }
+
        if ( !BER_BVISNULL( &si->si_syncCookie.octet_str ) )
        {
-               ber_printf( ber, "{eO}",
-                       abs(si->si_type),
-                       &si->si_syncCookie.octet_str );
+               ber_printf( ber, "{eOb}",
+                       abs(si->si_type), &si->si_syncCookie.octet_str, rhint );
        } else {
-               ber_printf( ber, "{e}",
-                       abs(si->si_type) );
+               ber_printf( ber, "{eb}",
+                       abs(si->si_type), rhint );
        }
 
        if ( (rc = ber_flatten2( ber, &c[0].ldctl_value, 0 )) == LBER_ERROR ) {
@@ -314,8 +396,7 @@ ldap_sync_search(
        timeout.tv_sec = si->si_tlimit;
        timeout.tv_usec = 0;
 
-       rc = ldap_search_ext( si->si_ld, si->si_base.bv_val, si->si_scope,
-               si->si_filterstr.bv_val, si->si_attrs, si->si_attrsonly,
+       rc = ldap_search_ext( si->si_ld, base, scope, filter, attrs, attrsonly,
                ctrls, NULL, si->si_tlimit > 0 ? &timeout : NULL,
                si->si_slimit, &msgid );
        ber_free_buf( ber );
@@ -622,7 +703,7 @@ do_syncrep2(
                                                slap_parse_sync_cookie( &syncCookie, NULL );
                                        }
                                }
-                               if ( si->si_syncdata ) {
+                               if ( si->si_syncdata && si->si_logstate == SYNCLOG_LOGGING ) {
                                        entry = NULL;
                                        modlist = NULL;
                                        if ( syncrepl_message_to_op( si, op, msg ) == LDAP_SUCCESS &&
@@ -658,6 +739,19 @@ do_syncrep2(
                                        "do_syncrep2: LDAP_RES_SEARCH_RESULT\n", 0, 0, 0 );
                                ldap_parse_result( si->si_ld, msg, &err, NULL, NULL, NULL,
                                        &rctrls, 0 );
+#ifdef LDAP_X_SYNC_REFRESH_REQUIRED
+                               if ( err == LDAP_X_SYNC_REFRESH_REQUIRED ) {
+                                       /* map old result code to registered code */
+                                       err = LDAP_SYNC_REFRESH_REQUIRED;
+                               }
+#endif
+                               if ( err == LDAP_SYNC_REFRESH_REQUIRED ) {
+                                       if ( si->si_logstate == SYNCLOG_LOGGING ) {
+                                               si->si_logstate = SYNCLOG_FALLBACK;
+                                       }
+                                       rc = err;
+                                       break;
+                               }
                                if ( rctrls ) {
                                        rctrlp = *rctrls;
                                        ber_init2( ber, &rctrlp->ldctl_value, LBER_USE_DER );
@@ -713,7 +807,13 @@ do_syncrep2(
                                                si->si_presentlist = NULL;
                                        }
                                }
-                               rc = -2;
+                               if ( err == LDAP_SUCCESS
+                                       && si->si_logstate == SYNCLOG_FALLBACK ) {
+                                       si->si_logstate = SYNCLOG_LOGGING;
+                                       rc = LDAP_SYNC_REFRESH_REQUIRED;
+                               } else {
+                                       rc = -2;
+                               }
                                goto done;
                                break;
 
@@ -886,7 +986,13 @@ done:
 
        if ( res ) ldap_msgfree( res );
 
-       if ( rc && si->si_ld ) {
+       if ( rc && rc != LDAP_SYNC_REFRESH_REQUIRED && si->si_ld ) {
+               if ( si->si_conn_setup ) {
+                       ber_socket_t s;
+                       ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
+                       connection_client_stop( s );
+                       si->si_conn_setup = 0;
+               }
                ldap_unbind_ext( si->si_ld, NULL, NULL );
                si->si_ld = NULL;
        }
@@ -905,7 +1011,6 @@ do_syncrepl(
        OperationBuffer opbuf;
        Operation *op;
        int rc = LDAP_SUCCESS;
-       int first = 0;
        int dostop = 0;
        ber_socket_t s;
        int i, defer = 1;
@@ -929,8 +1034,11 @@ do_syncrepl(
 
        if ( slapd_shutdown ) {
                if ( si->si_ld ) {
-                       ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
-                       connection_client_stop( s );
+                       if ( si->si_conn_setup ) {
+                               ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
+                               connection_client_stop( s );
+                               si->si_conn_setup = 0;
+                       }
                        ldap_unbind_ext( si->si_ld, NULL, NULL );
                        si->si_ld = NULL;
                }
@@ -952,29 +1060,35 @@ do_syncrepl(
 
        /* Establish session, do search */
        if ( !si->si_ld ) {
-               first = 1;
                si->si_refreshDelete = 0;
                si->si_refreshPresent = 0;
                rc = do_syncrep1( op, si );
        }
 
+reload:
        /* Process results */
        if ( rc == LDAP_SUCCESS ) {
                ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
 
                rc = do_syncrep2( op, si );
+               if ( rc == LDAP_SYNC_REFRESH_REQUIRED ) {
+                       rc = ldap_sync_search( si, op->o_tmpmemctx );
+                       goto reload;
+               }
 
                if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST ) {
                        /* If we succeeded, enable the connection for further listening.
                         * If we failed, tear down the connection and reschedule.
                         */
                        if ( rc == LDAP_SUCCESS ) {
-                               if ( first ) {
-                                       rc = connection_client_setup( s, do_syncrepl, arg );
-                               } else {
+                               if ( si->si_conn_setup ) {
                                        connection_client_enable( s );
+                               } else {
+                                       rc = connection_client_setup( s, do_syncrepl, arg );
+                                       if ( rc == 0 )
+                                               si->si_conn_setup = 1;
                                } 
-                       } else if ( !first ) {
+                       } else if ( si->si_conn_setup ) {
                                dostop = 1;
                        }
                } else {
@@ -1033,33 +1147,6 @@ 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 },
@@ -1125,10 +1212,12 @@ syncrepl_accesslog_mods(
                        *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 );
+               if ( colon[2] == ' ' ) {
+                       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;
 }
@@ -1223,6 +1312,9 @@ syncrepl_message_to_op(
                                deleteOldRdn = 1;
                } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_newSup )) {
                        sup = bvals[0];
+               } else if ( !ber_bvstrcasecmp( &bv,
+                       &slap_schema.si_ad_entryCSN->ad_cname )) {
+                       slap_queue_csn( op, bvals );
                }
                ch_free( bvals );
        }
@@ -1284,8 +1376,12 @@ syncrepl_message_to_op(
                op->orr_deleteoldrdn = deleteOldRdn;
                rc = op->o_bd->be_modrdn( op, &rs );
                break;
+       case LDAP_REQ_DELETE:
+               rc = op->o_bd->be_delete( op, &rs );
+               break;
        }
 done:
+       slap_graduate_commit_csn( op );
        if ( modlist )
                slap_mods_free( modlist, op->o_tag != LDAP_REQ_ADD );
        if ( !BER_BVISNULL( &rdn )) {
@@ -1633,6 +1729,11 @@ syncrepl_entry(
        switch ( syncstate ) {
        case LDAP_SYNC_ADD:
        case LDAP_SYNC_MODIFY:
+               {
+                       Attribute *a = attr_find( entry->e_attrs, slap_schema.si_ad_entryCSN );
+                       if ( a )
+                               op->o_csn = a->a_vals[0];
+               }
 retry_add:;
                if ( BER_BVISNULL( &dni.dn )) {
 
@@ -1852,6 +1953,7 @@ done :
        if ( !BER_BVISNULL( &dni.dn ) ) {
                op->o_tmpfree( dni.dn.bv_val, op->o_tmpmemctx );
        }
+       BER_BVZERO( &op->o_csn );
        return ret;
 }
 
@@ -2535,6 +2637,8 @@ syncinfo_free( syncinfo_t *sie )
 #define SYNCDATASTR            "syncdata"
 
 /* FIXME: undocumented */
+#define        LOGBASESTR      "logbase"
+#define LOGFILTERSTR   "logfilter"
 #define OLDAUTHCSTR            "bindprincipal"
 #define EXATTRSSTR             "exattrs"
 #define MANAGEDSAITSTR         "manageDSAit"
@@ -2627,6 +2731,13 @@ parse_syncrepl_line(
                        if ( si->si_filterstr.bv_val )
                                ch_free( si->si_filterstr.bv_val );
                        ber_str2bv( val, 0, 1, &si->si_filterstr );
+               } else if ( !strncasecmp( cargv[ i ], LOGFILTERSTR "=",
+                                       STRLENOF( LOGFILTERSTR "=" ) ) )
+               {
+                       val = cargv[ i ] + STRLENOF( LOGFILTERSTR "=" );
+                       if ( si->si_logfilterstr.bv_val )
+                               ch_free( si->si_logfilterstr.bv_val );
+                       ber_str2bv( val, 0, 1, &si->si_logfilterstr );
                } else if ( !strncasecmp( cargv[ i ], SEARCHBASESTR "=",
                                        STRLENOF( SEARCHBASESTR "=" ) ) )
                {
@@ -2644,6 +2755,23 @@ parse_syncrepl_line(
                                        val, rc, ldap_err2string( rc ) );
                                return -1;
                        }
+               } else if ( !strncasecmp( cargv[ i ], LOGBASESTR "=",
+                                       STRLENOF( LOGBASESTR "=" ) ) )
+               {
+                       struct berval   bv;
+                       int             rc;
+
+                       val = cargv[ i ] + STRLENOF( LOGBASESTR "=" );
+                       if ( si->si_logbase.bv_val ) {
+                               ch_free( si->si_logbase.bv_val );
+                       }
+                       ber_str2bv( val, 0, 0, &bv );
+                       rc = dnNormalize( 0, NULL, NULL, &bv, &si->si_logbase, NULL );
+                       if ( rc != LDAP_SUCCESS ) {
+                               fprintf( stderr, "Invalid logbase DN \"%s\": %d (%s)\n",
+                                       val, rc, ldap_err2string( rc ) );
+                               return -1;
+                       }
                } else if ( !strncasecmp( cargv[ i ], SCOPESTR "=",
                                        STRLENOF( SCOPESTR "=" ) ) )
                {
@@ -2727,11 +2855,11 @@ parse_syncrepl_line(
                        if ( !strncasecmp( val, "refreshOnly",
                                                STRLENOF("refreshOnly") ))
                        {
-                               si->si_type = LDAP_SYNC_REFRESH_ONLY;
+                               si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_ONLY;
                        } else if ( !strncasecmp( val, "refreshAndPersist",
                                                STRLENOF("refreshAndPersist") ))
                        {
-                               si->si_type = LDAP_SYNC_REFRESH_AND_PERSIST;
+                               si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_AND_PERSIST;
                                si->si_interval = 60;
                        } else {
                                fprintf( stderr, "Error: parse_syncrepl_line: "
@@ -2910,7 +3038,7 @@ add_syncrepl(
        si->si_allattrs = 0;
        si->si_allopattrs = 0;
        si->si_exattrs = NULL;
-       si->si_type = LDAP_SYNC_REFRESH_ONLY;
+       si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_ONLY;
        si->si_interval = 86400;
        si->si_retryinterval = NULL;
        si->si_retrynum_init = NULL;
@@ -2918,6 +3046,7 @@ add_syncrepl(
        si->si_manageDSAit = 0;
        si->si_tlimit = 0;
        si->si_slimit = 0;
+       si->si_conn_setup = 0;
 
        si->si_presentlist = NULL;
        LDAP_LIST_INIT( &si->si_nonpresentlist );
@@ -2975,6 +3104,16 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv )
                ptr = lutil_strcopy( ptr, si->si_base.bv_val );
                *ptr++ = '"';
        }
+       if ( !BER_BVISEMPTY( &si->si_logfilterstr )) {
+               ptr = lutil_strcopy( ptr, " " LOGFILTERSTR "=\"" );
+               ptr = lutil_strcopy( ptr, si->si_logfilterstr.bv_val );
+               *ptr++ = '"';
+       }
+       if ( !BER_BVISNULL( &si->si_logbase )) {
+               ptr = lutil_strcopy( ptr, " " LOGBASESTR "=\"" );
+               ptr = lutil_strcopy( ptr, si->si_logbase.bv_val );
+               *ptr++ = '"';
+       }
        for (i=0; !BER_BVISNULL(&scopes[i].key);i++) {
                if ( si->si_scope == scopes[i].val ) {
                        ptr = lutil_strcopy( ptr, " " SCOPESTR "=" );
index 39011cc1ece6ad5ddc05ff9a675bfe63e74f6d41..052b483cba4d52e9877432bd13d559b353ed8842 100644 (file)
 ## <http://www.OpenLDAP.org/license.html>.
 
 PROGRAMS = slapd-tester slapd-search slapd-read slapd-addel slapd-modrdn \
-               slapd-modify
+               slapd-modify slapd-bind
 
 SRCS     = slapd-tester.c slapd-search.c slapd-read.c slapd-addel.c \
-               slapd-modrdn.c slapd-modify.c
+               slapd-modrdn.c slapd-modify.c slapd-bind.c
 
 LDAP_INCDIR= ../../include
 LDAP_LIBDIR= ../../libraries
@@ -47,3 +47,6 @@ slapd-modrdn: slapd-modrdn.o $(XLIBS)
 
 slapd-modify: slapd-modify.o $(XLIBS)
        $(LTLINK) -o $@ slapd-modify.o $(LIBS)
+
+slapd-bind: slapd-bind.o $(XLIBS)
+       $(LTLINK) -o $@ slapd-bind.o $(LIBS)
diff --git a/tests/progs/slapd-bind.c b/tests/progs/slapd-bind.c
new file mode 100644 (file)
index 0000000..e471c35
--- /dev/null
@@ -0,0 +1,261 @@
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1999-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>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Howard Chu for inclusion
+ * in OpenLDAP Software.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+
+#include <ac/ctype.h>
+#include <ac/param.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+#include <ac/wait.h>
+
+#define LDAP_DEPRECATED 1
+#include <ldap.h>
+#include <lutil.h>
+
+#define LOOPS  100
+
+static int
+do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop );
+
+static int
+do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop );
+
+/* This program can be invoked two ways: if -D is used to specify a Bind DN,
+ * that DN will be used repeatedly for all of the Binds. If instead -b is used
+ * to specify a base DN, a search will be done for all "person" objects under
+ * that base DN. Then DNs from this list will be randomly selected for each
+ * Bind request. All of the users must have identical passwords. Also it is
+ * assumed that the users are all onelevel children of the base.
+ */
+static void
+usage( char *name )
+{
+       fprintf( stderr, "usage: %s [-h <host>] -p port (-D <dn>|-b <baseDN>) -w <passwd> [-l <loops>]\n",
+                       name );
+       exit( EXIT_FAILURE );
+}
+
+static char *filter = "(objectClass=person)";
+
+int
+main( int argc, char **argv )
+{
+       int             i;
+       char            *uri = NULL;
+       char        *host = "localhost";
+       char            *dn = NULL;
+       char            *base = NULL;
+       char            *pass = NULL;
+       int                     port = -1;
+       int                     loops = LOOPS;
+
+       while ( (i = getopt( argc, argv, "b:H:h:p:D:w:l:" )) != EOF ) {
+               switch( i ) {
+                       case 'b':               /* base DN of a tree of user DNs */
+                               base = strdup( optarg );
+                               break;
+
+                       case 'H':               /* the server uri */
+                               uri = strdup( optarg );
+                       break;
+                       case 'h':               /* the servers host */
+                               host = strdup( optarg );
+                       break;
+
+                       case 'p':               /* the servers port */
+                               port = atoi( optarg );
+                               break;
+
+                       case 'D':
+                               dn = strdup( optarg );
+                               break;
+
+                       case 'w':
+                               pass = strdup( optarg );
+                               break;
+
+                       case 'l':               /* the number of loops */
+                               loops = atoi( optarg );
+                               break;
+
+                       default:
+                               usage( argv[0] );
+                               break;
+               }
+       }
+
+       if ( port == -1 && uri == NULL )
+               usage( argv[0] );
+
+       if ( base )
+               do_base( uri, host, port, base, pass, ( 20 * loops ));
+       else
+               do_bind( uri, host, port, dn, pass, ( 20 * loops ));
+       exit( EXIT_SUCCESS );
+}
+
+
+static int
+do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop )
+{
+       LDAP    *ld = NULL;
+       int     i, rc;
+       char    *attrs[] = { "1.1", NULL };
+       pid_t   pid = getpid();
+
+       if ( maxloop > 1 )
+               fprintf( stderr, "PID=%ld - Bind(%d): dn=\"%s\".\n",
+                        (long) pid, maxloop, dn );
+
+       for ( i = 0; i < maxloop; i++ ) {
+               LDAPMessage *res;
+
+               if ( uri ) {
+                       ldap_initialize( &ld, uri );
+               } else {
+                       ld = ldap_init( host, port );
+               }
+               if ( ld == NULL ) {
+                       perror( "ldap_init" );
+                       rc = -1;
+                       break;
+               }
+
+               {
+                       int version = LDAP_VERSION3;
+                       (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
+                               &version ); 
+               }
+
+               rc = ldap_bind_s( ld, dn, pass, LDAP_AUTH_SIMPLE );
+               if ( rc != LDAP_SUCCESS ) {
+                       ldap_perror( ld, "ldap_bind" );
+               }
+               ldap_unbind( ld );
+               if ( rc != LDAP_SUCCESS ) {
+                       break;
+               }
+       }
+
+       if ( maxloop > 1 )
+               fprintf( stderr, " PID=%ld - Bind done.\n", (long) pid );
+
+       return rc;
+}
+
+
+static int
+do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop )
+{
+       LDAP    *ld = NULL;
+       int     i = 0;
+       pid_t   pid = getpid();
+       int     rc = LDAP_SUCCESS;
+       ber_int_t msgid;
+       LDAPMessage *res, *msg;
+       char **rdns = NULL;
+       char *attrs[] = { "dn", NULL };
+       int nrdns = 0;
+       time_t beg, end;
+
+       srand(pid);
+
+       if ( uri ) {
+               ldap_initialize( &ld, uri );
+       } else {
+               ld = ldap_init( host, port );
+       }
+       if ( ld == NULL ) {
+               perror( "ldap_init" );
+               exit( EXIT_FAILURE );
+       }
+
+       {
+               int version = LDAP_VERSION3;
+               (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
+                       &version ); 
+       }
+       (void) ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
+
+       rc = ldap_bind_s( ld, NULL, NULL, LDAP_AUTH_SIMPLE );
+       if ( rc != LDAP_SUCCESS ) {
+               ldap_perror( ld, "ldap_bind" );
+               exit( EXIT_FAILURE );
+       }
+
+       rc = ldap_search_ext( ld, base, LDAP_SCOPE_ONE,
+                       filter, attrs, 0, NULL, NULL, 0, 0, &msgid );
+       if ( rc != LDAP_SUCCESS ) {
+               ldap_perror( ld, "ldap_search_ex" );
+               exit( EXIT_FAILURE );
+       }
+
+       while (( rc=ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res )) >0){
+               BerElement *ber;
+               struct berval bv;
+               char *ptr;
+               int done = 0;
+
+               for (msg = ldap_first_message( ld, res ); msg;
+                       msg = ldap_next_message( ld, msg )) {
+                       switch ( ldap_msgtype( msg )) {
+                       case LDAP_RES_SEARCH_ENTRY:
+                               rc = ldap_get_dn_ber( ld, msg, &ber, &bv );
+                               ptr = strchr( bv.bv_val, ',');
+                               i = ptr-bv.bv_val;
+                               rdns = realloc( rdns, (nrdns+1)*sizeof(char *));
+                               rdns[nrdns] = malloc( i+1 );
+                               strncpy(rdns[nrdns], bv.bv_val, i );
+                               rdns[nrdns][i] = '\0';
+                               nrdns++;
+                               ber_free( ber, 0 );
+                               break;
+                       case LDAP_RES_SEARCH_RESULT:
+                               done = 1;
+                               break;
+                       }
+                       if ( done )
+                               break;
+               }
+               ldap_msgfree( res );
+               if ( done ) break;
+       }
+       ldap_unbind( ld );
+
+       beg = time(0L);
+       /* Ok, got list of RDNs, now start binding to each */
+       for (i=0; i<maxloop; i++) {
+               char dn[BUFSIZ], *ptr;
+               int j = rand() % nrdns;
+               ptr = lutil_strcopy(dn, rdns[j]);
+               *ptr++ = ',';
+               strcpy(ptr, base);
+               if ( do_bind( uri, host, port, dn, pass, 1 ))
+                       break;
+       }
+       end = time(0L);
+       fprintf( stderr, "Done %d Binds in %d seconds.\n", i, end - beg );
+       return 0;
+}
index 949cae538234ba9a7567a3101975375da4c67f64..f044bce5a2d82c2ad47d7639982326740a595b30 100644 (file)
@@ -34,6 +34,7 @@ AC_relay=relay@BUILD_RELAY@
 AC_sql=sql@BUILD_SQL@
 
 # overlays
+AC_accesslog=accesslog@BUILD_ACCESSLOG@
 AC_pcache=pcache@BUILD_PROXYCACHE@
 AC_ppolicy=ppolicy@BUILD_PPOLICY@
 AC_refint=refint@BUILD_REFINT@
@@ -53,7 +54,7 @@ AC_ACI_ENABLED=aci@WITH_ACI_ENABLED@
 export AC_bdb AC_hdb AC_ldap AC_ldbm AC_meta AC_monitor AC_relay AC_sql 
 export AC_pcache AC_ppolicy AC_refint AC_retcode AC_rwm AC_unique AC_syncprov
 export AC_translucent AC_WITH_SASL AC_WITH_TLS AC_WITH_MODULES_ENABLED AC_ACI_ENABLED
-export AC_valsort
+export AC_valsort AC_accesslog
 
 if test ! -x ../servers/slapd/slapd ; then
        echo "Could not locate slapd(8)"
index 0b43781c9dffe9639437306e4b8e2adc7ccae493..2491091f4da04b6ba066768f74cca8a28771e0f7 100755 (executable)
@@ -41,6 +41,7 @@ sed -e "s/@BACKEND@/${BACKEND}/"                      \
        -e "s/^#${AC_relay}#//"                         \
        -e "s/^#${AC_sql}#//"                           \
                -e "s/^#${RDBMS}#//"                    \
+       -e "s/^#${AC_accesslog}#//"                     \
        -e "s/^#${AC_pcache}#//"                        \
        -e "s/^#${AC_ppolicy}#//"                       \
        -e "s/^#${AC_refint}#//"                        \
index 0663ead213225fc3e3daa49413461ae5dacb423a..1beba89e3e06b050babf18e8d9288cb725f2cd64 100755 (executable)
@@ -14,6 +14,7 @@
 ## <http://www.OpenLDAP.org/license.html>.
 
 MONITORDB=${AC_monitor-no}
+ACCESSLOG=${AC_accesslog-accesslogno}
 BACKLDAP=${AC_ldap-ldapno}
 BACKMETA=${AC_meta-metano}
 BACKRELAY=${AC_relay-relayno}
@@ -63,6 +64,8 @@ ACLCONF=$DATADIR/slapd-acl.conf
 RCONF=$DATADIR/slapd-referrals.conf
 MASTERCONF=$DATADIR/slapd-repl-master.conf
 SRMASTERCONF=$DATADIR/slapd-syncrepl-master.conf
+DSRMASTERCONF=$DATADIR/slapd-deltasync-master.conf
+DSRSLAVECONF=$DATADIR/slapd-deltasync-slave.conf
 SLAVECONF=$DATADIR/slapd-repl-slave.conf
 PPOLICYCONF=$DATADIR/slapd-ppolicy.conf
 PROXYCACHECONF=$DATADIR/slapd-proxycache.conf
index 69466f2043d2751e0e776f8e2d0097c1a4d992f6..d0e12ce6c1f789578cd1dc6e45b210fdeaa03f26 100755 (executable)
@@ -18,7 +18,7 @@ echo "running defines.sh"
 
 ## If you use this script then
 ## Make sure that you turn on LDAP_COMP_MATCH in slapd source codes
-## and --enable-modules  is configured yes
+## and --enable-modules is configured yes
 if test "$AC_WITH_MODULES_ENABLED" != "yes" ; then
         echo "dynamic module disabled, test skipped"
         exit 0
@@ -163,7 +163,7 @@ if test $RC != 0 ; then
        exit $RC
 fi
 
-FILTER="(userCertificate:componentFilterMatch:=item:{component \"toBeSigned.extensions.\2a.extnID\",rule allComponentsMatch, value 2.5.29.14 })"
+FILTER="(userCertificate:componentFilterMatch:=item:{ component \"toBeSigned.extensions.\2a.extnID\", rule allComponentsMatch, value 2.5.29.14 })"
 echo "        f=$FILTER ..."
 echo "#         f=$FILTER ..." >> $SEARCHOUT
 $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
@@ -176,7 +176,7 @@ if test $RC != 0 ; then
        exit $RC
 fi
 
-FILTER="(userCertificate:componentFilterMatch:=not:item:{component \"toBeSigned.extensions.\2a\",rule allComponentsMatch, value { extnID 2.5.29.19 , extnValue '30030101FF'H })"
+FILTER="(userCertificate:componentFilterMatch:=not:item:{ component \"toBeSigned.extensions.\2a\", rule allComponentsMatch, value { extnID 2.5.29.19 , extnValue '30030101FF'H })"
 echo "        f=$FILTER ..."
 echo "#         f=$FILTER ..." >> $SEARCHOUT
 $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
@@ -255,6 +255,7 @@ if test $RC != 0 ; then
        exit $RC
 fi
 
+# extraction filter
 FILTER="(x509CertificateIssuer=c=US)"
 echo "        f=$FILTER ..."
 echo "#         f=$FILTER ..." >> $SEARCHOUT
@@ -268,6 +269,7 @@ if test $RC != 0 ; then
        exit $RC
 fi
 
+# extraction filter
 FILTER="(x509CertificateSerial=0)"
 echo "        f=$FILTER ..."
 echo "#         f=$FILTER ..." >> $SEARCHOUT
@@ -281,6 +283,7 @@ if test $RC != 0 ; then
        exit $RC
 fi
 
+# extraction filter
 FILTER="(x509CertificateSerialAndIssuer:certificateExactMatch:=0\$c=US)"
 echo "        f=$FILTER ..."
 echo "#         f=$FILTER ..." >> $SEARCHOUT
index c88b19de5b0a1ab4e6c5106ceecd1d21bc488d20..895644f8737847138abb339bb974f32134bf6d46 100755 (executable)
@@ -545,6 +545,29 @@ case $RC in
        ;;
 esac
 
+echo "Binding with incorrect password to database \"$BASEDN\"..."
+$LDAPWHOAMI -h $LOCALHOST -p $PORT3 \
+       -D "cn=Added User,ou=Same as above,ou=Meta,$BASEDN" \
+       -w bogus >> $TESTOUT 2>&1
+RC=$?
+#if test $RC != 0 ; then
+#      echo "WhoAmI failed ($RC)!"
+#      test $KILLSERVERS != no && kill -HUP $KILLPIDS
+#      exit $RC
+#fi
+case $RC in 
+       0)
+               echo "WhoAmI should have failed ($RC)!"
+               test $KILLSERVERS != no && kill -HUP $KILLPIDS
+               exit -1
+       ;;
+       51)
+               echo "### Hit LDAP_BUSY problem; you may want to re-run the test"
+       ;;
+       *)
+       ;;
+esac
+
 echo "Comparing to database \"$BASEDN\"..."
 $LDAPCOMPARE -h $LOCALHOST -p $PORT3 \
        "cn=Another Added Group,ou=Groups,$BASEDN" \
index 2617e780c9a24e3780934afe930dfdefca23fbb5..d395d6b59af51ce2efec1104ced07f8a79e4d257 100755 (executable)
@@ -191,7 +191,7 @@ echo "Comparing filter output..."
 $CMP $SEARCHFLT $LDIFFLT > $CMPOUT
 
 if test $? != 0 ; then
-       echo "comparison failed - meta search/modification didn't succeed"
+       echo "comparison failed - slapd-ldap search/modification didn't succeed"
        exit 1
 fi