From 2bffe6fe7dd34b654ff2dc45685bf6148347b8ff Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Mon, 14 Nov 2005 19:05:50 +0000 Subject: [PATCH] Sync with HEAD --- configure | 192 +++------ configure.in | 1 + contrib/slapd-modules/smbk5pwd/README | 33 +- contrib/slapd-modules/smbk5pwd/smbk5pwd.c | 470 +++++++++++++++++++--- doc/man/man5/slapd-ldap.5 | 15 + doc/man/man5/slapd.conf.5 | 1 + doc/man/man5/slapo-retcode.5 | 21 +- doc/man/man8/slapacl.8 | 2 +- doc/man/man8/slapadd.8 | 2 +- doc/man/man8/slapauth.8 | 2 +- doc/man/man8/slapcat.8 | 2 +- doc/man/man8/slapdn.8 | 2 +- doc/man/man8/slapindex.8 | 2 +- include/ac/string.h | 7 + include/lber.h | 4 + include/lber_pvt.h | 31 +- include/ldap_pvt.h | 7 +- include/portable.hin | 3 + libraries/liblber/decode.c | 162 ++++++-- libraries/liblber/io.c | 10 - libraries/liblber/lber-int.h | 11 +- libraries/liblber/memory.c | 48 +-- libraries/liblber/options.c | 55 ++- libraries/liblber/sockbuf.c | 2 - libraries/libldap/cyrus.c | 23 +- libraries/libldap/error.c | 39 +- libraries/libldap/extended.c | 13 + libraries/libldap/ldap-int.h | 6 +- libraries/libldap/options.c | 16 +- libraries/libldap/result.c | 65 ++- libraries/libldap/sasl.c | 10 + libraries/libldap/schema.c | 12 +- libraries/libldap/search.c | 4 +- libraries/libldap/tls.c | 27 +- libraries/liblutil/tavl.c | 2 +- libraries/liblutil/utils.c | 19 + servers/slapd/aci.c | 174 +++++--- servers/slapd/acl.c | 112 ++---- servers/slapd/ad.c | 2 +- servers/slapd/add.c | 2 +- servers/slapd/back-bdb/cache.c | 6 +- servers/slapd/back-bdb/modify.c | 6 +- servers/slapd/back-bdb/tools.c | 3 - servers/slapd/back-ldap/add.c | 5 +- servers/slapd/back-ldap/back-ldap.h | 13 + servers/slapd/back-ldap/bind.c | 41 +- servers/slapd/back-ldap/compare.c | 2 +- servers/slapd/back-ldap/config.c | 79 +++- servers/slapd/back-ldap/delete.c | 5 +- servers/slapd/back-ldap/modify.c | 5 +- servers/slapd/back-ldap/modrdn.c | 5 +- servers/slapd/back-ldap/proto-ldap.h | 2 +- servers/slapd/back-ldap/search.c | 8 +- servers/slapd/back-meta/add.c | 4 +- servers/slapd/back-meta/back-meta.h | 13 +- servers/slapd/back-meta/bind.c | 62 ++- servers/slapd/back-meta/config.c | 12 +- servers/slapd/back-meta/conn.c | 23 ++ servers/slapd/back-meta/delete.c | 4 +- servers/slapd/back-meta/modify.c | 4 +- servers/slapd/back-meta/modrdn.c | 4 +- servers/slapd/back-meta/search.c | 92 +++-- servers/slapd/back-monitor/operation.c | 4 +- servers/slapd/back-passwd/search.c | 6 +- servers/slapd/back-sql/add.c | 78 ++-- servers/slapd/back-sql/delete.c | 52 +-- servers/slapd/back-sql/entry-id.c | 4 +- servers/slapd/back-sql/init.c | 20 +- servers/slapd/back-sql/modify.c | 2 + servers/slapd/back-sql/operational.c | 2 +- servers/slapd/back-sql/proto-sql.h | 4 +- servers/slapd/back-sql/schema-map.c | 16 +- servers/slapd/back-sql/search.c | 238 ++++++++--- servers/slapd/back-sql/sql-wrap.c | 5 +- servers/slapd/back-sql/util.c | 36 +- servers/slapd/backglue.c | 3 +- servers/slapd/bconfig.c | 44 +- servers/slapd/bind.c | 52 --- servers/slapd/config.c | 92 +++-- servers/slapd/connection.c | 50 ++- servers/slapd/daemon.c | 20 +- servers/slapd/dn.c | 8 +- servers/slapd/extended.c | 8 +- servers/slapd/filterentry.c | 2 +- servers/slapd/ldapsync.c | 32 +- servers/slapd/main.c | 2 +- servers/slapd/modify.c | 10 +- servers/slapd/overlays/ppolicy.c | 15 +- servers/slapd/overlays/retcode.c | 110 ++++- servers/slapd/overlays/syncprov.c | 10 +- servers/slapd/overlays/translucent.c | 14 +- servers/slapd/overlays/valsort.c | 12 +- servers/slapd/passwd.c | 4 +- servers/slapd/proto-slap.h | 6 +- servers/slapd/sasl.c | 24 +- servers/slapd/saslauthz.c | 57 ++- servers/slapd/schema.c | 4 +- servers/slapd/schema_init.c | 6 +- servers/slapd/slap.h | 47 +-- servers/slapd/slapcommon.c | 22 +- servers/slapd/slapi/slapi_pblock.c | 2 +- servers/slapd/slaptest.c | 2 + servers/slapd/syncrepl.c | 80 ++-- servers/slapd/value.c | 44 +- servers/slurpd/config.c | 6 +- servers/slurpd/main.c | 56 ++- tests/data/meta.out | 10 + tests/data/retcode.conf | 2 +- tests/data/slapd-idassert.conf | 4 +- tests/data/slapd-meta2.conf | 2 + tests/data/slapd-sql-syncrepl-master.conf | 4 +- tests/data/slapd-sql.conf | 4 +- tests/progs/slapd-addel.c | 3 +- tests/progs/slapd-bind.c | 84 +++- tests/progs/slapd-modify.c | 3 +- tests/progs/slapd-modrdn.c | 3 +- tests/scripts/defines.sh | 6 +- tests/scripts/test035-meta | 34 +- tests/scripts/test036-meta-concurrency | 2 +- 119 files changed, 2359 insertions(+), 1122 deletions(-) diff --git a/configure b/configure index 199dd64de0..46d44a87c9 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.560.2.15 2005/09/28 00:30:27 kurt Exp . +# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.560.2.16 2005/11/03 18:02:53 kurt Exp . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59. # @@ -289,8 +289,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 @@ -2386,7 +2386,7 @@ if test "${with_tls+set}" = set; then withval="$with_tls" ol_arg=invalid - for ol_val in auto ssleay openssl yes no ; do + for ol_val in auto openssl yes no ; do if test "$withval" = "$ol_val" ; then ol_arg="$ol_val" fi @@ -5336,7 +5336,7 @@ else 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 &6 if test "${lt_cv_prog_gnu_ld+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - # 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 &5 (exit $ac_status); }; then - case "`/usr/bin/file conftest.o`" in + case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*linux*) @@ -6765,7 +6765,7 @@ else 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` @@ -7080,7 +7080,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" @@ -7401,7 +7401,7 @@ else 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 @@ -7463,7 +7463,7 @@ else 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 @@ -7612,7 +7612,7 @@ else LDFLAGS="$LDFLAGS $lt_prog_compiler_static" 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. @@ -7663,7 +7663,7 @@ else # 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:7669: $lt_compile\"" >&5) @@ -7753,7 +7753,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 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 ;; @@ -7800,7 +7800,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_wl='-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 ;; @@ -7830,12 +7830,12 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; - pgcc* | pgf77* | pgf90*) + pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-static' + lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' @@ -7925,7 +7925,7 @@ else # 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:7931: $lt_compile\"" >&5) @@ -7959,7 +7959,7 @@ else fi fi -case "$host_os" in +case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= @@ -7987,7 +7987,7 @@ else # 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:7993: $lt_compile\"" >&5) @@ -8005,7 +8005,7 @@ else lt_cv_prog_compiler_c_o=yes fi fi - chmod u+w . + chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation @@ -8205,11 +8205,11 @@ EOF tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='${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 - whole_archive_flag_spec='${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 + whole_archive_flag_spec='${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' ;; @@ -8517,7 +8517,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec=' ' archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds it's shared libraries. + # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$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 @@ -8557,7 +8557,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; darwin* | rhapsody*) - case "$host_os" in + case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag='${wl}-undefined ${wl}suppress' ;; @@ -8586,7 +8586,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi output_verbose_link_cmd='echo' archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' module_cmds='$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 archive_expsym_cmds='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}' module_expsym_cmds='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 @@ -8595,7 +8595,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi output_verbose_link_cmd='echo' archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' module_cmds='$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 archive_expsym_cmds='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}' module_expsym_cmds='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}' ;; @@ -8661,7 +8661,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hpux10* | hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; @@ -8670,7 +8670,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; esac else - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' ;; @@ -8680,7 +8680,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac fi if test "$with_gnu_ld" = no; then - case "$host_cpu" in + case $host_cpu in hppa*64*) hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_flag_spec_ld='+b $libdir' @@ -9139,7 +9139,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' @@ -9192,7 +9193,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"` @@ -9230,7 +9231,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*) @@ -9275,7 +9283,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 @@ -10230,7 +10238,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null + (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; @@ -10328,7 +10336,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null + (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; @@ -10444,7 +10452,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 @@ -19164,8 +19172,7 @@ fi ol_link_tls=no if test $ol_with_tls != no ; then - -for ac_header in openssl/ssl.h ssl.h +for ac_header in openssl/ssl.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then @@ -19315,82 +19322,8 @@ fi done - if test $ac_cv_header_openssl_ssl_h = yes || - test $ac_cv_header_ssl_h = yes ; then - echo "$as_me:$LINENO: checking for SSLeay_add_ssl_algorithms in -lssl" >&5 -echo $ECHO_N "checking for SSLeay_add_ssl_algorithms in -lssl... $ECHO_C" >&6 -if test "${ac_cv_lib_ssl_SSLeay_add_ssl_algorithms+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lssl -lcrypto $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char SSLeay_add_ssl_algorithms (); -int -main () -{ -SSLeay_add_ssl_algorithms (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_ssl_SSLeay_add_ssl_algorithms=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_ssl_SSLeay_add_ssl_algorithms=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSLeay_add_ssl_algorithms" >&5 -echo "${ECHO_T}$ac_cv_lib_ssl_SSLeay_add_ssl_algorithms" >&6 -if test $ac_cv_lib_ssl_SSLeay_add_ssl_algorithms = yes; then - have_ssleay=yes - need_rsaref=no -else - have_ssleay=no -fi - - - if test $have_ssleay = no ; then - echo "$as_me:$LINENO: checking for SSL_library_init in -lssl" >&5 + if test $ac_cv_header_openssl_ssl_h = yes ; then + echo "$as_me:$LINENO: checking for SSL_library_init in -lssl" >&5 echo $ECHO_N "checking for SSL_library_init in -lssl... $ECHO_C" >&6 if test "${ac_cv_lib_ssl_SSL_library_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 @@ -19455,15 +19388,14 @@ fi echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_library_init" >&5 echo "${ECHO_T}$ac_cv_lib_ssl_SSL_library_init" >&6 if test $ac_cv_lib_ssl_SSL_library_init = yes; then - have_ssleay=yes - need_rsaref=no + have_openssl=yes + need_rsaref=no else - have_ssleay=no + have_openssl=no fi - fi - if test $have_ssleay = no ; then + if test $have_openssl = no ; then echo "$as_me:$LINENO: checking for ssl3_accept in -lssl" >&5 echo $ECHO_N "checking for ssl3_accept in -lssl... $ECHO_C" >&6 if test "${ac_cv_lib_ssl_ssl3_accept+set}" = set; then @@ -19529,21 +19461,21 @@ fi echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_ssl3_accept" >&5 echo "${ECHO_T}$ac_cv_lib_ssl_ssl3_accept" >&6 if test $ac_cv_lib_ssl_ssl3_accept = yes; then - have_ssleay=yes + have_openssl=yes need_rsaref=yes else - have_ssleay=no + have_openssl=no fi fi - if test $have_ssleay = yes ; then + if test $have_openssl = yes ; then ol_with_tls=found ol_link_tls=yes cat >>confdefs.h <<\_ACEOF -#define HAVE_SSLEAY 1 +#define HAVE_OPENSSL 1 _ACEOF @@ -41324,6 +41256,8 @@ fi + + @@ -41346,9 +41280,11 @@ for ac_func in \ getspnam \ gettimeofday \ initgroups \ + inet_ntoa_b \ lockf \ memcpy \ memmove \ + memrchr \ mkstemp \ mktemp \ pipe \ diff --git a/configure.in b/configure.in index ec8f749343..be9a104c02 100644 --- a/configure.in +++ b/configure.in @@ -2535,6 +2535,7 @@ AC_CHECK_FUNCS( \ lockf \ memcpy \ memmove \ + memrchr \ mkstemp \ mktemp \ pipe \ diff --git a/contrib/slapd-modules/smbk5pwd/README b/contrib/slapd-modules/smbk5pwd/README index 8ccad2f05a..8031f534cf 100644 --- a/contrib/slapd-modules/smbk5pwd/README +++ b/contrib/slapd-modules/smbk5pwd/README @@ -42,7 +42,38 @@ To use the overlay, add: to your slapd configuration file. (You should obtain the necessary schema files from the Heimdal and/or Samba distributions. At this time, there are several known errors in these schema files that you will have to -correct before they will load in slapd.) +correct before they will load in slapd. As of Samba 3.0 the schema looks +fine as shipped.) + +All modules compiled in (i.e. krb5 and samba) are enabled; the statement + + smbk5pwd-enable + +can be used to enable only the desired one(s); legal values for +are "krb5" and "samba", if they are respectively enabled by defining +DO_KRB5 and DO_SAMBA. + +The samba module also supports the + + smbk5pwd-must-change + +which sets the "sambaPwdMustChange" attribute accordingly to force passwd +expiry. A value of 0 disables this feature. + +The overlay now supports table-driven configuration, and thus can be run-time +loaded and configured via back-config. The layout of the entry is + + # {0}smbk5pwd, {1}bdb, config + dn: olcOverlay={0}smbk5pwd,olcDatabase={1}bdb,cn=config + objectClass: olcOverlayConfig + objectClass: olcSmbK5PwdConfig + olcOverlay: {0}smbk5pwd + olcSmbK5PwdEnable: krb5 + olcSmbK5PwdEnable: samba + olcSmbK5PwdMustChange: 2592000 + +which enables both krb5 and samba modules with a password expiry time +of 30 days. The provided Makefile builds both Kerberos and Samba support by default. You must edit the Makefile to insure that the correct include and library diff --git a/contrib/slapd-modules/smbk5pwd/smbk5pwd.c b/contrib/slapd-modules/smbk5pwd/smbk5pwd.c index 9e8f27c7df..88448f1f33 100644 --- a/contrib/slapd-modules/smbk5pwd/smbk5pwd.c +++ b/contrib/slapd-modules/smbk5pwd/smbk5pwd.c @@ -12,6 +12,12 @@ * top-level directory of the distribution or, alternatively, at * . */ +/* + * Support for sambaPwdMustChange added by Marco D'Ettorre. + * Support for table-driven configuration added by Pierangelo Masarati. + * + * The conditions of the OpenLDAP Public License apply. + */ #include @@ -25,6 +31,8 @@ #include #include +#include "config.h" + #ifdef DO_KRB5 #include #include @@ -62,16 +70,41 @@ static ObjectClass *oc_krb5KDCEntry; static AttributeDescription *ad_sambaLMPassword; static AttributeDescription *ad_sambaNTPassword; static AttributeDescription *ad_sambaPwdLastSet; +static AttributeDescription *ad_sambaPwdMustChange; static ObjectClass *oc_sambaSamAccount; #endif -#if 0 -static void smbk5pwd_destroy() { - kadm5_destroy(kadm_context); - krb5_free_context(context); -} +/* Per-instance configuration information */ +typedef struct smbk5pwd_t { + unsigned mode; +#define SMBK5PWD_F_KRB5 (0x1U) +#define SMBK5PWD_F_SAMBA (0x2U) + +#define SMBK5PWD_DO_KRB5(pi) ((pi)->mode & SMBK5PWD_F_KRB5) +#define SMBK5PWD_DO_SAMBA(pi) ((pi)->mode & SMBK5PWD_F_SAMBA) + +#ifdef DO_KRB5 + /* nothing yet */ #endif +#ifdef DO_SAMBA + /* How many seconds before forcing a password change? */ + time_t smb_must_change; +#endif +} smbk5pwd_t; + +static const unsigned SMBK5PWD_F_ALL = + 0 +#ifdef DO_KRB5 + | SMBK5PWD_F_KRB5 +#endif +#ifdef DO_SAMBA + | SMBK5PWD_F_SAMBA +#endif +; + +static int smbk5pwd_modules_init( smbk5pwd_t *pi ); + #ifdef DO_SAMBA static const char hex[] = "0123456789abcdef"; @@ -312,6 +345,7 @@ static int smbk5pwd_exop_passwd( Entry *e; Modifications *ml; slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + smbk5pwd_t *pi = on->on_bi.bi_private; /* Not the operation we expected, pass it on... */ if ( ber_bvcmp( &slap_EXOP_MODIFY_PASSWD, &op->ore_reqoid ) ) { @@ -331,6 +365,8 @@ static int smbk5pwd_exop_passwd( int kvno, i; Attribute *a; + if ( !SMBK5PWD_DO_KRB5( pi ) ) break; + if ( !is_entry_objectclass(e, oc_krb5KDCEntry, 0 ) ) break; a = attr_find( e->e_attrs, ad_krb5PrincipalName ); @@ -402,12 +438,12 @@ static int smbk5pwd_exop_passwd( "%d", kvno+1 ); BER_BVZERO( &ml->sml_values[1] ); ml->sml_nvalues = NULL; - } while(0); + } while ( 0 ); #endif /* DO_KRB5 */ #ifdef DO_SAMBA /* Samba stuff */ - if ( is_entry_objectclass(e, oc_sambaSamAccount, 0 ) ) { + if ( SMBK5PWD_DO_SAMBA( pi ) && is_entry_objectclass(e, oc_sambaSamAccount, 0 ) ) { struct berval *keys; ber_len_t j,l; wchar_t *wcs, wc; @@ -494,6 +530,28 @@ static int smbk5pwd_exop_passwd( #endif ml->sml_values = keys; ml->sml_nvalues = NULL; + + if (pi->smb_must_change) + { + ml = ch_malloc(sizeof(Modifications)); + ml->sml_next = qpw->rs_mods; + qpw->rs_mods = ml; + + keys = ch_malloc( 2 * sizeof(struct berval) ); + 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() + pi->smb_must_change); + BER_BVZERO( &keys[1] ); + + ml->sml_desc = ad_sambaPwdMustChange; + ml->sml_op = LDAP_MOD_REPLACE; +#ifdef SLAP_MOD_INTERNAL + ml->sml_flags = SLAP_MOD_INTERNAL; +#endif + ml->sml_values = keys; + ml->sml_nvalues = NULL; + } } #endif /* DO_SAMBA */ be_entry_release_r( op, e ); @@ -503,67 +561,385 @@ static int smbk5pwd_exop_passwd( static slap_overinst smbk5pwd; -int smbk5pwd_init() { - int rc; - const char *text; +/* back-config stuff */ +enum { + PC_SMB_MUST_CHANGE = 1, + PC_SMB_ENABLE +}; -#ifdef DO_KRB5 - krb5_error_code ret; - extern HDB * _kadm5_s_get_db(void *); - - /* Make sure all of our necessary schema items are loaded */ - oc_krb5KDCEntry = oc_find("krb5KDCEntry"); - if ( !oc_krb5KDCEntry ) return -1; - - rc = slap_str2ad( "krb5Key", &ad_krb5Key, &text ); - if ( rc ) return rc; - rc = slap_str2ad( "krb5KeyVersionNumber", &ad_krb5KeyVersionNumber, &text ); - if ( rc ) return rc; - rc = slap_str2ad( "krb5PrincipalName", &ad_krb5PrincipalName, &text ); - if ( rc ) return rc; - - /* Initialize Kerberos context */ - ret = krb5_init_context(&context); - if (ret) { - return -1; +static ConfigDriver smbk5pwd_cf_func; + +/* + * NOTE: uses OID arcs OLcfgOvAt:6 and OLcfgOvOc:6 + */ + +static ConfigTable smbk5pwd_cfats[] = { + { "smbk5pwd-enable", "arg", + 2, 0, 0, ARG_MAGIC|PC_SMB_ENABLE, smbk5pwd_cf_func, + "( OLcfgOvAt:6.1 NAME 'olcSmbK5PwdEnable' " + "DESC 'Modules to be enabled' " + "SYNTAX OMsDirectoryString )", NULL, NULL }, + { "smbk5pwd-must-change", "time", + 2, 2, 0, ARG_MAGIC|ARG_INT|PC_SMB_MUST_CHANGE, smbk5pwd_cf_func, + "( OLcfgOvAt:6.2 NAME 'olcSmbK5PwdMustChange' " + "DESC 'Credentials validity interval' " + "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, + + { NULL, NULL, 0, 0, 0, ARG_IGNORED } +}; + +static ConfigOCs smbk5pwd_cfocs[] = { + { "( OLcfgOvOc:6.1 " + "NAME 'olcSmbK5PwdConfig' " + "DESC 'smbk5pwd overlay configuration' " + "SUP olcOverlayConfig " + "MAY ( " + "olcSmbK5PwdEnable " + "$ olcSmbK5PwdMustChange " + ") )", Cft_Overlay, smbk5pwd_cfats }, + + { NULL, 0, NULL } +}; + +/* + * add here other functionalities; handle their initialization + * as appropriate in smbk5pwd_modules_init(). + */ +static slap_verbmasks smbk5pwd_modules[] = { + { BER_BVC( "krb5" ), SMBK5PWD_F_KRB5 }, + { BER_BVC( "samba" ), SMBK5PWD_F_SAMBA }, + { BER_BVNULL, -1 } +}; + +static int +smbk5pwd_cf_func( ConfigArgs *c ) +{ + slap_overinst *on = (slap_overinst *)c->bi; + + int rc = 0; + smbk5pwd_t *pi = on->on_bi.bi_private; + + if ( c->op == SLAP_CONFIG_EMIT ) { + switch( c->type ) { + case PC_SMB_MUST_CHANGE: +#ifdef DO_SAMBA + c->value_int = pi->smb_must_change; +#else /* ! DO_SAMBA */ + c->value_int = 0; +#endif /* ! DO_SAMBA */ + break; + + case PC_SMB_ENABLE: + c->rvalue_vals = NULL; + if ( pi->mode ) { + mask_to_verbs( smbk5pwd_modules, pi->mode, &c->rvalue_vals ); + if ( c->rvalue_vals == NULL ) { + rc = 1; + } + } + break; + + default: + assert( 0 ); + rc = 1; + } + return rc; + + } else if ( c->op == LDAP_MOD_DELETE ) { + switch( c->type ) { + case PC_SMB_MUST_CHANGE: + break; + + case PC_SMB_ENABLE: + if ( !c->line ) { + pi->mode = 0; + + } else { + slap_mask_t m; + + m = verb_to_mask( c->line, smbk5pwd_modules ); + pi->mode &= ~m; + } + break; + + default: + assert( 0 ); + rc = 1; + } + return rc; + } + + switch( c->type ) { + case PC_SMB_MUST_CHANGE: +#ifdef DO_SAMBA + if ( c->value_int < 0 ) { + Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: " + "<%s> invalid negative value \"%d\".", + c->log, c->argv[ 0 ], 0 ); + return 1; + } + pi->smb_must_change = c->value_int; +#else /* ! DO_SAMBA */ + Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: " + "<%s> only meaningful " + "when compiled with -DDO_SAMBA.\n", + c->log, c->argv[ 0 ], 0 ); + return 1; +#endif /* ! DO_SAMBA */ + break; + + case PC_SMB_ENABLE: { + slap_mask_t mode = pi->mode, m; + + rc = verbs_to_mask( c->argc, c->argv, smbk5pwd_modules, &m ); + if ( rc > 0 ) { + Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: " + "<%s> unknown module \"%s\".\n", + c->log, c->argv[ 0 ], c->argv[ rc ] ); + return 1; + } + + /* we can hijack the smbk5pwd_t structure because + * from within the configuration, this is the only + * active thread. */ + pi->mode |= m; + +#ifndef DO_KRB5 + if ( SMBK5PWD_DO_KRB5( pi ) ) { + Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: " + "<%s> module \"%s\" only allowed when compiled with -DDO_KRB5.\n", + c->log, c->argv[ 0 ], c->argv[ rc ] ); + pi->mode = mode; + return 1; + } +#endif /* ! DO_KRB5 */ + +#ifndef DO_SAMBA + if ( SMBK5PWD_DO_SAMBA( pi ) ) { + Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: " + "<%s> module \"%s\" only allowed when compiled with -DDO_SAMBA.\n", + c->log, c->argv[ 0 ], c->argv[ rc ] ); + pi->mode = mode; + return 1; + } +#endif /* ! DO_SAMBA */ + + { + BackendDB db = *c->be; + + /* Re-initialize the module, because + * the configuration might have changed */ + db.bd_info = (BackendInfo *)on; + rc = smbk5pwd_modules_init( pi ); + if ( rc ) { + pi->mode = mode; + return 1; + } + } + + } break; + + default: + assert( 0 ); + return 1; + } + return rc; +} + +static int +smbk5pwd_modules_init( smbk5pwd_t *pi ) +{ + static struct { + const char *name; + AttributeDescription **adp; } +#ifdef DO_KRB5 + krb5_ad[] = { + { "krb5Key", &ad_krb5Key }, + { "krb5KeyVersionNumber", &ad_krb5KeyVersionNumber }, + { "krb5PrincipalName", &ad_krb5PrincipalName }, + { NULL } + }, +#endif /* DO_KRB5 */ +#ifdef DO_SAMBA + samba_ad[] = { + { "sambaLMPassword", &ad_sambaLMPassword }, + { "sambaNTPassword", &ad_sambaNTPassword }, + { "sambaPwdLastSet", &ad_sambaPwdLastSet }, + { "sambaPwdMustChange", &ad_sambaPwdMustChange }, + { NULL } + }, +#endif /* DO_SAMBA */ + dummy_ad; + + /* this is to silence the unused var warning */ + dummy_ad.name = NULL; + +#ifdef DO_KRB5 + if ( SMBK5PWD_DO_KRB5( pi ) && oc_krb5KDCEntry == NULL ) { + krb5_error_code ret; + extern HDB *_kadm5_s_get_db(void *); + + int i, rc; + + /* Make sure all of our necessary schema items are loaded */ + oc_krb5KDCEntry = oc_find( "krb5KDCEntry" ); + if ( !oc_krb5KDCEntry ) { + Debug( LDAP_DEBUG_ANY, "smbk5pwd: " + "unable to find \"krb5KDCEntry\" objectClass.\n", + 0, 0, 0 ); + return -1; + } + + for ( i = 0; krb5_ad[ i ].name != NULL; i++ ) { + const char *text; + + *(krb5_ad[ i ].adp) = NULL; + + rc = slap_str2ad( krb5_ad[ i ].name, krb5_ad[ i ].adp, &text ); + if ( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, "smbk5pwd: " + "unable to find \"%s\" attributeType: %s (%d).\n", + krb5_ad[ i ].name, text, rc ); + oc_krb5KDCEntry = NULL; + return rc; + } + } - ret = kadm5_s_init_with_password_ctx( context, - KADM5_ADMIN_SERVICE, - NULL, - KADM5_ADMIN_SERVICE, - &conf, 0, 0, &kadm_context ); - - db = _kadm5_s_get_db(kadm_context); + /* Initialize Kerberos context */ + ret = krb5_init_context(&context); + if (ret) { + Debug( LDAP_DEBUG_ANY, "smbk5pwd: " + "unable to initialize krb5 context.\n", + 0, 0, 0 ); + oc_krb5KDCEntry = NULL; + return -1; + } + + /* FIXME: check return code? */ + ret = kadm5_s_init_with_password_ctx( context, + KADM5_ADMIN_SERVICE, + NULL, + KADM5_ADMIN_SERVICE, + &conf, 0, 0, &kadm_context ); + + /* FIXME: check return code? */ + db = _kadm5_s_get_db( kadm_context ); + } #endif /* DO_KRB5 */ #ifdef DO_SAMBA - oc_sambaSamAccount = oc_find("sambaSamAccount"); - if ( !oc_sambaSamAccount ) return -1; - - rc = slap_str2ad( "sambaLMPassword", &ad_sambaLMPassword, &text ); - if ( rc ) return rc; - rc = slap_str2ad( "sambaNTPassword", &ad_sambaNTPassword, &text ); - if ( rc ) return rc; - rc = slap_str2ad( "sambaPwdLastSet", &ad_sambaPwdLastSet, &text ); - if ( rc ) return rc; + if ( SMBK5PWD_DO_SAMBA( pi ) && oc_sambaSamAccount == NULL ) { + int i, rc; + + oc_sambaSamAccount = oc_find( "sambaSamAccount" ); + if ( !oc_sambaSamAccount ) { + Debug( LDAP_DEBUG_ANY, "smbk5pwd: " + "unable to find \"sambaSamAccount\" objectClass.\n", + 0, 0, 0 ); + return -1; + } + + for ( i = 0; samba_ad[ i ].name != NULL; i++ ) { + const char *text; + + *(samba_ad[ i ].adp) = NULL; + + rc = slap_str2ad( samba_ad[ i ].name, samba_ad[ i ].adp, &text ); + if ( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, "smbk5pwd: " + "unable to find \"%s\" attributeType: %s (%d).\n", + samba_ad[ i ].name, text, rc ); + oc_sambaSamAccount = NULL; + return rc; + } + } + } #endif /* DO_SAMBA */ + return 0; +} + +static int +smbk5pwd_db_init(BackendDB *be) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + smbk5pwd_t *pi; + + pi = ch_calloc( 1, sizeof( smbk5pwd_t ) ); + if ( pi == NULL ) { + return 1; + } + on->on_bi.bi_private = (void *)pi; + + return 0; +} + +static int +smbk5pwd_db_open(BackendDB *be) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + smbk5pwd_t *pi = (smbk5pwd_t *)on->on_bi.bi_private; + + int rc; + + if ( pi->mode == 0 ) { + pi->mode = SMBK5PWD_F_ALL; + } + + rc = smbk5pwd_modules_init( pi ); + if ( rc ) { + return rc; + } + + return 0; +} + +static int +smbk5pwd_db_destroy(BackendDB *be) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + smbk5pwd_t *pi = (smbk5pwd_t *)on->on_bi.bi_private; + + if ( pi ) { + ch_free( pi ); + } + + return 0; +} + +int +smbk5pwd_initialize(void) +{ + int rc; + smbk5pwd.on_bi.bi_type = "smbk5pwd"; - smbk5pwd.on_bi.bi_extended = smbk5pwd_exop_passwd; + smbk5pwd.on_bi.bi_db_init = smbk5pwd_db_init; + smbk5pwd.on_bi.bi_db_open = smbk5pwd_db_open; + smbk5pwd.on_bi.bi_db_destroy = smbk5pwd_db_destroy; + + smbk5pwd.on_bi.bi_extended = smbk5pwd_exop_passwd; + #ifdef DO_KRB5 smbk5pwd.on_bi.bi_op_bind = smbk5pwd_op_bind; lutil_passwd_add( (struct berval *)&k5key_scheme, k5key_chk, k5key_hash ); #endif + smbk5pwd.on_bi.bi_cf_ocs = smbk5pwd_cfocs; + + rc = config_register_schema( smbk5pwd_cfats, smbk5pwd_cfocs ); + if ( rc ) { + return rc; + } + return overlay_register( &smbk5pwd ); } #if SLAPD_OVER_SMBK5PWD == SLAPD_MOD_DYNAMIC int init_module(int argc, char *argv[]) { - return smbk5pwd_init(); + return smbk5pwd_initialize(); } #endif diff --git a/doc/man/man5/slapd-ldap.5 b/doc/man/man5/slapd-ldap.5 index 80e408ffb6..b683085b0b 100644 --- a/doc/man/man5/slapd-ldap.5 +++ b/doc/man/man5/slapd-ldap.5 @@ -319,6 +319,21 @@ If set to .BR discover , support is detected by reading the remote server's root DSE. +.TP +.B timeout [{add|delete|modify|modrdn}=] [...] +This directive allows to set per-operation timeouts. +If no operation is specified, it affects all. +Currently, only write operations are addressed, because searches +can already be limited by means of the +.B limits +directive (see +.BR slapd.conf (5) +for details), and other operations are not supposed to incur into the +need for timeouts. +Note: if the timelimit is exceeded, the operation is abandoned; +the protocol does not provide any means to rollback the operation, +so the client will not know if the operation eventually succeeded or not. + .SH BACKWARD COMPATIBILITY The LDAP backend has been heavily reworked between releases 2.2 and 2.3; as a side-effect, some of the traditional directives have been diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index 33d1f406a2..580a084765 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -401,6 +401,7 @@ The default is 1000. .B defaultsearchbase Specify a default search base to use when client submits a non-base search request with an empty base DN. +Base scoped search requests with an empty base DN are not affected. .TP .B disallow Specify a set of features (separated by white space) to diff --git a/doc/man/man5/slapo-retcode.5 b/doc/man/man5/slapo-retcode.5 index 78cef21866..031094829c 100644 --- a/doc/man/man5/slapo-retcode.5 +++ b/doc/man/man5/slapo-retcode.5 @@ -21,8 +21,8 @@ The error responses are generated according to different strategies. In the first case, all operations targeted at a specific configurable subtree cause the object related to the request DN to be looked up and checked for return code data: a response code, plus an optional -textual message, an optional configurable delay, and, when the response code -is referral, a (list of) referral(s). +textual message, an optional configurable delay, an optional matched DN +field, and, when the response code is "referral", a (list of) referral(s). .LP Well-known response codes from standard track documents are provided in \fBretcode.conf\fP, which can be included after instantiating @@ -57,13 +57,15 @@ If not defined, the suffix of the database is used. .HP .hy 0 .B retcode\-item [op=] [text=] -.B [ref=] [sleeptime=] +.B [ref=] [sleeptime=] [matched=] .RS A dynamically generated entry, located below \fBretcode\-parent\fP. The \fB\fP is the number of the response code; it can be in any format supported by strtol. The optional \fB\fP is a list of operations that cause response code generation; if absent, all operations are affected. +The \fBmatched\fP field is the matched DN that is returned +along with the error. The \fBref\fP field is only allowed for the \fBreferral\fP response code. .RE @@ -130,13 +132,24 @@ The sleep time before the response is actually returned to the client: SINGLE-VALUE ) .RE .LP +The matched DN returned to the client: +.RS 4 +( 1.3.6.1.4.1.4203.666.11.4.1.5 + NAME ( 'errMatchedDN' ) + DESC 'Value to be returned as matched DN' + EQUALITY distinguishedNameMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 + SINGLE-VALUE ) +.RE +.LP The abstract class that triggers the overlay: .RS 4 ( 1.3.6.1.4.1.4203.666.11.4.3.0 NAME ( 'errAbsObject' ) SUP top ABSTRACT MUST ( errCode ) - MAY ( cn $ description $ errOp $ errText $ errSleepTime ) ) + MAY ( cn $ description $ errOp $ errText $ errSleepTime + $ errMatchedDN ) ) .RE .LP The standalone structural objectclass for specifically created data: diff --git a/doc/man/man8/slapacl.8 b/doc/man/man8/slapacl.8 index 4c392391e6..915b8320ca 100644 --- a/doc/man/man8/slapacl.8 +++ b/doc/man/man8/slapacl.8 @@ -56,7 +56,7 @@ and 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 +default config directory will be made before trying to use the default config file. If a valid config directory exists then the default config file is ignored. .TP diff --git a/doc/man/man8/slapadd.8 b/doc/man/man8/slapadd.8 index d6ba8c7174..c4d36228e2 100644 --- a/doc/man/man8/slapadd.8 +++ b/doc/man/man8/slapadd.8 @@ -100,7 +100,7 @@ and 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 +default config directory will be made before trying to use the default config file. If a valid config directory exists then the default config file is ignored. If dryrun mode is also specified, no conversion will occur. diff --git a/doc/man/man8/slapauth.8 b/doc/man/man8/slapauth.8 index eb91acf850..52ad6de8cc 100644 --- a/doc/man/man8/slapauth.8 +++ b/doc/man/man8/slapauth.8 @@ -54,7 +54,7 @@ and 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 +default config directory will be made before trying to use the default config file. If a valid config directory exists then the default config file is ignored. .TP diff --git a/doc/man/man8/slapcat.8 b/doc/man/man8/slapcat.8 index 62092b4b9c..6cb729c520 100644 --- a/doc/man/man8/slapcat.8 +++ b/doc/man/man8/slapcat.8 @@ -102,7 +102,7 @@ and 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 +default config directory will be made before trying to use the default config file. If a valid config directory exists then the default config file is ignored. .TP diff --git a/doc/man/man8/slapdn.8 b/doc/man/man8/slapdn.8 index 9099256db9..a1611914d3 100644 --- a/doc/man/man8/slapdn.8 +++ b/doc/man/man8/slapdn.8 @@ -50,7 +50,7 @@ and 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 +default config directory will be made before trying to use the default config file. If a valid config directory exists then the default config file is ignored. .TP diff --git a/doc/man/man8/slapindex.8 b/doc/man/man8/slapindex.8 index 2295301de8..c0e71435fb 100644 --- a/doc/man/man8/slapindex.8 +++ b/doc/man/man8/slapindex.8 @@ -79,7 +79,7 @@ and 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 +default config directory will be made before trying to use the default config file. If a valid config directory exists then the default config file is ignored. .SH LIMITATIONS diff --git a/include/ac/string.h b/include/ac/string.h index c35605ae08..7a5931e37e 100644 --- a/include/ac/string.h +++ b/include/ac/string.h @@ -94,6 +94,13 @@ int (strncasecmp)(); #define memcmp lutil_memcmp #endif +/* GNU extension (glibc >= 2.1.91), only declared when defined(_GNU_SOURCE) */ +#ifndef HAVE_MEMRCHR +#undef memrchr +#define memrchr lutil_memrchr +#endif /* ! HAVE_MEMRCHR */ +void * memrchr(const void *b, int c, size_t len); + #define STRLENOF(s) (sizeof(s)-1) #if defined( HAVE_NONPOSIX_STRERROR_R ) diff --git a/include/lber.h b/include/lber.h index 93eebc3e48..fb29a8cb41 100644 --- a/include/lber.h +++ b/include/lber.h @@ -622,6 +622,10 @@ LBER_F( int * ) ber_errno_addr LDAP_P((void)); #define LBER_ERROR_PARAM 0x1 #define LBER_ERROR_MEMORY 0x2 +#ifdef LDAP_DEVEL +#define LDAP_NULL_IS_NULL +#endif + LDAP_END_DECL #endif /* _LBER_H */ diff --git a/include/lber_pvt.h b/include/lber_pvt.h index 6fd557d230..346e2faecb 100644 --- a/include/lber_pvt.h +++ b/include/lber_pvt.h @@ -167,7 +167,36 @@ ber_bvarray_add_x LDAP_P(( BerVarray *p, BerValue *bv, void *ctx )); ( (s)[0] == (c) && (s)[1] == '\0' ) #define ber_bvchr(bv,c) \ - memchr( (bv)->bv_val, (c), (bv)->bv_len ) + ((char *) memchr( (bv)->bv_val, (c), (bv)->bv_len )) + +#define ber_bvrchr(bv,c) \ + ((char *) memrchr( (bv)->bv_val, (c), (bv)->bv_len )) + +#define ber_bvchr_right(dst,bv,c) \ + do { \ + (dst)->bv_val = memchr( (bv)->bv_val, (c), (bv)->bv_len ); \ + (dst)->bv_len = (dst)->bv_val ? (bv)->bv_len - ((dst)->bv_val - (bv)->bv_val) : 0; \ + } while (0) + +#define ber_bvchr_left(dst,bv,c) \ + do { \ + (dst)->bv_val = memchr( (bv)->bv_val, (c), (bv)->bv_len ); \ + (dst)->bv_len = (dst)->bv_val ? ((dst)->bv_val - (bv)->bv_val) : (bv)->bv_len; \ + (dst)->bv_val = (bv)->bv_val; \ + } while (0) + +#define ber_bvrchr_right(dst,bv,c) \ + do { \ + (dst)->bv_val = memrchr( (bv)->bv_val, (c), (bv)->bv_len ); \ + (dst)->bv_len = (dst)->bv_val ? (bv)->bv_len - ((dst)->bv_val - (bv)->bv_val) : 0; \ + } while (0) + +#define ber_bvrchr_left(dst,bv,c) \ + do { \ + (dst)->bv_val = memrchr( (bv)->bv_val, (c), (bv)->bv_len ); \ + (dst)->bv_len = (dst)->bv_val ? ((dst)->bv_val - (bv)->bv_val) : (bv)->bv_len; \ + (dst)->bv_val = (bv)->bv_val; \ + } while (0) #define BER_BVC(s) { STRLENOF(s), (s) } #define BER_BVNULL { 0L, NULL } diff --git a/include/ldap_pvt.h b/include/ldap_pvt.h index 2d810b04e0..54246b402f 100644 --- a/include/ldap_pvt.h +++ b/include/ldap_pvt.h @@ -235,7 +235,7 @@ LDAP_F (int) ldap_pvt_tls_set_option LDAP_P(( struct ldap *ld, LDAP_F (void) ldap_pvt_tls_destroy LDAP_P(( void )); LDAP_F (int) ldap_pvt_tls_init LDAP_P(( void )); -LDAP_F (int) ldap_pvt_tls_init_def_ctx LDAP_P(( void )); +LDAP_F (int) ldap_pvt_tls_init_def_ctx LDAP_P(( int is_server )); LDAP_F (int) ldap_pvt_tls_accept LDAP_P(( Sockbuf *sb, void *ctx_arg )); LDAP_F (int) ldap_pvt_tls_inplace LDAP_P(( Sockbuf *sb )); LDAP_F (void *) ldap_pvt_tls_sb_ctx LDAP_P(( Sockbuf *sb )); @@ -279,6 +279,7 @@ LDAP_END_DECL #endif /* HAVE_OPENSSL_BN_H || HAVE_BN_H */ typedef BIGNUM* ldap_pvt_mp_t; +#define LDAP_PVT_MP_INIT (NULL) #define ldap_pvt_mp_init(mp) \ (mp) = BN_new() @@ -305,6 +306,8 @@ typedef BIGNUM* ldap_pvt_mp_t; #endif typedef mpz_t ldap_pvt_mp_t; +#define LDAP_PVT_MP_INIT { 0 } + #define ldap_pvt_mp_init(mp) \ mpz_init((mp)) @@ -327,8 +330,10 @@ typedef mpz_t ldap_pvt_mp_t; #ifdef HAVE_LONG_LONG typedef unsigned long long ldap_pvt_mp_t; +#define LDAP_PVT_MP_INIT (0LL) #else /* !HAVE_LONG_LONG */ typedef unsigned long ldap_pvt_mp_t; +#define LDAP_PVT_MP_INIT (0L) #endif /* !HAVE_LONG_LONG */ #define ldap_pvt_mp_init(mp) \ diff --git a/include/portable.hin b/include/portable.hin index 10425199a3..b35359d1f6 100644 --- a/include/portable.hin +++ b/include/portable.hin @@ -397,6 +397,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `memrchr' function. */ +#undef HAVE_MEMRCHR + /* Define to 1 if you have the `mkstemp' function. */ #undef HAVE_MKSTEMP diff --git a/libraries/liblber/decode.c b/libraries/liblber/decode.c index 04ba7cabc6..f84ed86111 100644 --- a/libraries/liblber/decode.c +++ b/libraries/liblber/decode.c @@ -479,6 +479,57 @@ ber_get_stringbv( BerElement *ber, struct berval *bv, int alloc ) return tag; } +#ifdef LDAP_NULL_IS_NULL +ber_tag_t +ber_get_stringbv_null( BerElement *ber, struct berval *bv, int alloc ) +{ + ber_tag_t tag; + + assert( ber != NULL ); + assert( bv != NULL ); + + assert( LBER_VALID( ber ) ); + + if ( (tag = ber_skip_tag( ber, &bv->bv_len )) == LBER_DEFAULT ) { + bv->bv_val = NULL; + return LBER_DEFAULT; + } + + if ( (ber_len_t) ber_pvt_ber_remaining( ber ) < bv->bv_len ) { + return LBER_DEFAULT; + } + + if ( bv->bv_len == 0 ) { + bv->bv_val = NULL; + ber->ber_tag = *(unsigned char *)ber->ber_ptr; + return tag; + } + + if ( alloc ) { + bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1, + ber->ber_memctx ); + if ( bv->bv_val == NULL ) { + return LBER_DEFAULT; + } + + if ( bv->bv_len > 0 && (ber_len_t) ber_read( ber, bv->bv_val, + bv->bv_len ) != bv->bv_len ) + { + LBER_FREE( bv->bv_val ); + bv->bv_val = NULL; + return LBER_DEFAULT; + } + } else { + bv->bv_val = ber->ber_ptr; + ber->ber_ptr += bv->bv_len; + } + ber->ber_tag = *(unsigned char *)ber->ber_ptr; + bv->bv_val[bv->bv_len] = '\0'; + + return tag; +} +#endif /* LDAP_NULL_IS_NULL */ + ber_tag_t ber_get_stringa( BerElement *ber, char **buf ) { @@ -493,6 +544,22 @@ ber_get_stringa( BerElement *ber, char **buf ) return tag; } +#ifdef LDAP_NULL_IS_NULL +ber_tag_t +ber_get_stringa_null( BerElement *ber, char **buf ) +{ + BerValue bv; + ber_tag_t tag; + + assert( buf != NULL ); + + tag = ber_get_stringbv_null( ber, &bv, 1 ); + *buf = bv.bv_val; + + return tag; +} +#endif /* LDAP_NULL_IS_NULL */ + ber_tag_t ber_get_stringal( BerElement *ber, struct berval **bv ) { @@ -692,11 +759,25 @@ ber_scanf ( BerElement *ber, rc = ber_get_stringa( ber, ss ); break; +#ifdef LDAP_NULL_IS_NULL + case 'A': /* octet string - allocate storage as needed, + * but return NULL if len == 0 */ + ss = va_arg( ap, char ** ); + rc = ber_get_stringa_null( ber, ss ); + break; +#endif /* LDAP_NULL_IS_NULL */ + case 'b': /* boolean */ i = va_arg( ap, ber_int_t * ); rc = ber_get_boolean( ber, i ); break; + case 'B': /* bit string - allocate storage as needed */ + ss = va_arg( ap, char ** ); + l = va_arg( ap, ber_len_t * ); /* for length, in bits */ + rc = ber_get_bitstringa( ber, ss, l ); + break; + case 'e': /* enumerated */ case 'i': /* int */ i = va_arg( ap, ber_int_t * ); @@ -708,19 +789,30 @@ ber_scanf ( BerElement *ber, rc = ber_peek_tag( ber, l ); break; - case 'n': /* null */ - rc = ber_get_null( ber ); + case 'm': /* octet string in berval, in-place */ + bval = va_arg( ap, struct berval * ); + rc = ber_get_stringbv( ber, bval, 0 ); break; - case 's': /* octet string - in a buffer */ - s = va_arg( ap, char * ); + case 'M': /* bvoffarray - must include address of + * a record len, and record offset. + * number of records will be returned thru + * len ptr on finish. parsed in-place. + */ + { + bgbvr cookie = { BvOff }; + cookie.ber = ber; + cookie.res.ba = va_arg( ap, struct berval ** ); + cookie.alloc = 0; l = va_arg( ap, ber_len_t * ); - rc = ber_get_stringb( ber, s, l ); + cookie.siz = *l; + cookie.off = va_arg( ap, ber_len_t ); + rc = ber_get_stringbvl( &cookie, l ); break; + } - case 'm': /* octet string in berval, in-place */ - bval = va_arg( ap, struct berval * ); - rc = ber_get_stringbv( ber, bval, 0 ); + case 'n': /* null */ + rc = ber_get_null( ber ); break; case 'o': /* octet string in a supplied berval */ @@ -733,10 +825,10 @@ ber_scanf ( BerElement *ber, rc = ber_get_stringal( ber, bvp ); break; - case 'B': /* bit string - allocate storage as needed */ - ss = va_arg( ap, char ** ); - l = va_arg( ap, ber_len_t * ); /* for length, in bits */ - rc = ber_get_bitstringa( ber, ss, l ); + case 's': /* octet string - in a buffer */ + s = va_arg( ap, char * ); + l = va_arg( ap, ber_len_t * ); + rc = ber_get_stringb( ber, s, l ); break; case 't': /* tag of next item */ @@ -779,23 +871,6 @@ ber_scanf ( BerElement *ber, break; } - case 'M': /* bvoffarray - must include address of - * a record len, and record offset. - * number of records will be returned thru - * len ptr on finish. parsed in-place. - */ - { - bgbvr cookie = { BvOff }; - cookie.ber = ber; - cookie.res.ba = va_arg( ap, struct berval ** ); - cookie.alloc = 0; - l = va_arg( ap, ber_len_t * ); - cookie.siz = *l; - cookie.off = va_arg( ap, ber_len_t ); - rc = ber_get_stringbvl( &cookie, l ); - break; - } - case 'x': /* skip the next element - whatever it is */ if ( (rc = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) break; @@ -845,6 +920,9 @@ ber_scanf ( BerElement *ber, } break; case 'a': /* octet string - allocate storage as needed */ +#ifdef LDAP_NULL_IS_NULL + case 'A': +#endif /* LDAP_NULL_IS_NULL */ ss = va_arg( ap, char ** ); if ( *ss ) { LBER_FREE( *ss ); @@ -858,20 +936,10 @@ ber_scanf ( BerElement *ber, (void) va_arg( ap, int * ); break; - case 's': /* octet string - in a buffer */ - (void) va_arg( ap, char * ); - (void) va_arg( ap, ber_len_t * ); - break; - case 'l': /* length of next item */ (void) va_arg( ap, ber_len_t * ); break; - case 't': /* tag of next item */ - case 'T': /* skip tag of next item */ - (void) va_arg( ap, ber_tag_t * ); - break; - case 'o': /* octet string in a supplied berval */ bval = va_arg( ap, struct berval * ); if ( bval->bv_val != NULL ) { @@ -889,6 +957,16 @@ ber_scanf ( BerElement *ber, } break; + case 's': /* octet string - in a buffer */ + (void) va_arg( ap, char * ); + (void) va_arg( ap, ber_len_t * ); + break; + + case 't': /* tag of next item */ + case 'T': /* skip tag of next item */ + (void) va_arg( ap, ber_tag_t * ); + break; + case 'B': /* bit string - allocate storage as needed */ ss = va_arg( ap, char ** ); if ( *ss ) { @@ -898,12 +976,12 @@ ber_scanf ( BerElement *ber, *(va_arg( ap, ber_len_t * )) = 0; /* for length, in bits */ break; - case 'v': /* sequence of strings */ - case 'V': /* sequence of strings + lengths */ - case 'W': /* BerVarray */ case 'm': /* berval in-place */ case 'M': /* BVoff array in-place */ case 'n': /* null */ + case 'v': /* sequence of strings */ + case 'V': /* sequence of strings + lengths */ + case 'W': /* BerVarray */ case 'x': /* skip the next element - whatever it is */ case '{': /* begin sequence */ case '[': /* begin set */ diff --git a/libraries/liblber/io.c b/libraries/liblber/io.c index fc37f8dfb2..19757b7826 100644 --- a/libraries/liblber/io.c +++ b/libraries/liblber/io.c @@ -248,8 +248,6 @@ ber_alloc_t( int options ) { BerElement *ber; - ber_int_options.lbo_valid = LBER_INITIALIZED; - ber = (BerElement *) LBER_CALLOC( 1, sizeof(BerElement) ); if ( ber == NULL ) { @@ -301,8 +299,6 @@ ber_init2( BerElement *ber, struct berval *bv, int options ) { assert( ber != NULL ); - ber_int_options.lbo_valid = LBER_INITIALIZED; - (void) memset( (char *)ber, '\0', sizeof( BerElement )); ber->ber_valid = LBER_VALID_BERELEMENT; ber->ber_tag = LBER_DEFAULT; @@ -336,8 +332,6 @@ ber_init( struct berval *bv ) assert( bv != NULL ); - ber_int_options.lbo_valid = LBER_INITIALIZED; - if ( bv == NULL ) { return NULL; } @@ -377,8 +371,6 @@ int ber_flatten2( { assert( bv != NULL ); - ber_int_options.lbo_valid = LBER_INITIALIZED; - if ( bv == NULL ) { return -1; } @@ -416,8 +408,6 @@ int ber_flatten( assert( bvPtr != NULL ); - ber_int_options.lbo_valid = LBER_INITIALIZED; - if(bvPtr == NULL) { return -1; } diff --git a/libraries/liblber/lber-int.h b/libraries/liblber/lber-int.h index 3133540405..16cabd995c 100644 --- a/libraries/liblber/lber-int.h +++ b/libraries/liblber/lber-int.h @@ -38,11 +38,20 @@ typedef void (*BER_LOG_FN)(FILE *file, LBER_V (BER_ERRNO_FN) ber_int_errno_fn; +#ifdef LDAP_MEMORY_TRACE +# ifndef LDAP_MEMORY_DEBUG +# define LDAP_MEMORY_DEBUG 1 +# endif +#endif + +#ifdef LDAP_MEMORY_DEBUG +LBER_V (long) ber_int_meminuse; +#endif + struct lber_options { short lbo_valid; unsigned short lbo_options; int lbo_debug; - long lbo_meminuse; }; LBER_F( int ) ber_pvt_log_output( diff --git a/libraries/liblber/memory.c b/libraries/liblber/memory.c index a9dc92b915..899babb87c 100644 --- a/libraries/liblber/memory.c +++ b/libraries/liblber/memory.c @@ -21,9 +21,6 @@ #include "lber-int.h" #ifdef LDAP_MEMORY_TRACE -# ifndef LDAP_MEMORY_DEBUG -# define LDAP_MEMORY_DEBUG 1 -# endif #include #endif @@ -67,7 +64,7 @@ struct ber_mem_hdr { static const struct ber_mem_hdr ber_int_mem_hdr = { LBER_MEM_JUNK, 0, 0 }; -/* Note sequence and ber_int_options.lbu_meminuse are counters, but are not +/* Note sequence and ber_int_meminuse are counters, but are not * thread safe. If you want to use these values for multithreaded applications, * you must put mutexes around them, otherwise they will have incorrect values. * When debugging, if you sort the debug output, the sequence number will @@ -125,8 +122,6 @@ BerMemoryFunctions *ber_int_memory_fns = NULL; void ber_memfree_x( void *p, void *ctx ) { - ber_int_options.lbo_valid = LBER_INITIALIZED; - if( p == NULL ) { return; } @@ -140,12 +135,12 @@ ber_memfree_x( void *p, void *ctx ) assert( mh->bm_top == LBER_MEM_JUNK); assert( testdatatop( mh)); assert( testend( (char *)&mh[1] + mh->bm_length) ); - ber_int_options.lbo_meminuse -= mh->bm_length; + ber_int_meminuse -= mh->bm_length; #ifdef LDAP_MEMORY_TRACE fprintf(stderr, "0x%08lx 0x%08lx -f- %ld ber_memfree %ld\n", (long)mh->bm_sequence, (long)mh, (long)mh->bm_length, - ber_int_options.lbo_meminuse); + ber_int_meminuse); #endif /* Fill the free space with poison */ memset( mh, 0xff, mh->bm_length + sizeof(struct ber_mem_hdr) + sizeof(ber_int_t)); @@ -172,8 +167,6 @@ ber_memvfree_x( void **vec, void *ctx ) { int i; - ber_int_options.lbo_valid = LBER_INITIALIZED; - if( vec == NULL ) { return; } @@ -197,7 +190,6 @@ void * ber_memalloc_x( ber_len_t s, void *ctx ) { void *new; - ber_int_options.lbo_valid = LBER_INITIALIZED; #ifdef LDAP_MEMORY_DEBUG assert( s != 0 ); @@ -217,13 +209,13 @@ ber_memalloc_x( ber_len_t s, void *ctx ) setdatatop( mh); setend( (char *)&mh[1] + mh->bm_length ); - ber_int_options.lbo_meminuse += mh->bm_length; /* Count mem inuse */ + ber_int_meminuse += mh->bm_length; /* Count mem inuse */ #ifdef LDAP_MEMORY_TRACE mh->bm_sequence = sequence++; fprintf(stderr, "0x%08lx 0x%08lx -a- %ld ber_memalloc %ld\n", (long)mh->bm_sequence, (long)mh, (long)mh->bm_length, - ber_int_options.lbo_meminuse); + ber_int_meminuse); #endif /* poison new memory */ memset( (char *)&mh[1], 0xff, s); @@ -254,7 +246,6 @@ void * ber_memcalloc_x( ber_len_t n, ber_len_t s, void *ctx ) { void *new; - ber_int_options.lbo_valid = LBER_INITIALIZED; #ifdef LDAP_MEMORY_DEBUG assert( n != 0 && s != 0); @@ -275,13 +266,13 @@ ber_memcalloc_x( ber_len_t n, ber_len_t s, void *ctx ) setdatatop( mh); setend( (char *)&mh[1] + mh->bm_length ); - ber_int_options.lbo_meminuse += mh->bm_length; + ber_int_meminuse += mh->bm_length; #ifdef LDAP_MEMORY_TRACE mh->bm_sequence = sequence++; fprintf(stderr, "0x%08lx 0x%08lx -a- %ld ber_memcalloc %ld\n", (long)mh->bm_sequence, (long)mh, (long)mh->bm_length, - ber_int_options.lbo_meminuse); + ber_int_meminuse); #endif BER_MEM_VALID( &mh[1] ); new = &mh[1]; @@ -310,7 +301,6 @@ void * ber_memrealloc_x( void* p, ber_len_t s, void *ctx ) { void *new = NULL; - ber_int_options.lbo_valid = LBER_INITIALIZED; /* realloc(NULL,s) -> malloc(s) */ if( p == NULL ) { @@ -352,11 +342,11 @@ ber_memrealloc_x( void* p, ber_len_t s, void *ctx ) assert( mh->bm_top == LBER_MEM_JUNK); assert( testdatatop( mh)); - ber_int_options.lbo_meminuse += s - oldlen; + ber_int_meminuse += s - oldlen; #ifdef LDAP_MEMORY_TRACE fprintf(stderr, "0x%08lx 0x%08lx -a- %ld ber_memrealloc %ld\n", (long)mh->bm_sequence, (long)mh, (long)mh->bm_length, - ber_int_options.lbo_meminuse); + ber_int_meminuse); #endif BER_MEM_VALID( &mh[1] ); return &mh[1]; @@ -383,8 +373,6 @@ ber_memrealloc( void* p, ber_len_t s ) void ber_bvfree_x( struct berval *bv, void *ctx ) { - ber_int_options.lbo_valid = LBER_INITIALIZED; - if( bv == NULL ) { return; } @@ -409,8 +397,6 @@ ber_bvecfree_x( struct berval **bv, void *ctx ) { int i; - ber_int_options.lbo_valid = LBER_INITIALIZED; - if( bv == NULL ) { return; } @@ -440,8 +426,6 @@ ber_bvecadd_x( struct berval ***bvec, struct berval *bv, void *ctx ) ber_len_t i; struct berval **new; - ber_int_options.lbo_valid = LBER_INITIALIZED; - if( *bvec == NULL ) { if( bv == NULL ) { /* nothing to add */ @@ -497,8 +481,6 @@ ber_dupbv_x( { struct berval *new; - ber_int_options.lbo_valid = LBER_INITIALIZED; - if( src == NULL ) { ber_errno = LBER_ERROR_PARAM; return NULL; @@ -554,8 +536,6 @@ ber_str2bv_x( { struct berval *new; - ber_int_options.lbo_valid = LBER_INITIALIZED; - if( s == NULL ) { ber_errno = LBER_ERROR_PARAM; return NULL; @@ -602,8 +582,6 @@ ber_mem2bv_x( { struct berval *new; - ber_int_options.lbo_valid = LBER_INITIALIZED; - if( s == NULL ) { ber_errno = LBER_ERROR_PARAM; return NULL; @@ -650,8 +628,6 @@ ber_strdup_x( LDAP_CONST char *s, void *ctx ) char *p; size_t len; - ber_int_options.lbo_valid = LBER_INITIALIZED; - #ifdef LDAP_MEMORY_DEBUG assert(s != NULL); /* bv damn better point to something */ #endif @@ -684,8 +660,6 @@ ber_strndup_x( LDAP_CONST char *s, ber_len_t l, void *ctx ) char *p; size_t len; - ber_int_options.lbo_valid = LBER_INITIALIZED; - #ifdef LDAP_MEMORY_DEBUG assert(s != NULL); /* bv damn better point to something */ #endif @@ -748,8 +722,6 @@ ber_bvarray_free_x( BerVarray a, void *ctx ) { int i; - ber_int_options.lbo_valid = LBER_INITIALIZED; - if (a) { BER_MEM_VALID( a ); @@ -776,8 +748,6 @@ ber_bvarray_add_x( BerVarray *a, BerValue *bv, void *ctx ) { int n; - ber_int_options.lbo_valid = LBER_INITIALIZED; - if ( *a == NULL ) { if (bv == NULL) { return 0; diff --git a/libraries/liblber/options.c b/libraries/liblber/options.c index 39f58a6bef..6982ab79f4 100644 --- a/libraries/liblber/options.c +++ b/libraries/liblber/options.c @@ -23,7 +23,7 @@ char ber_pvt_opt_on; /* used to get a non-NULL address for *_OPT_ON */ struct lber_options ber_int_options = { - LBER_UNINITIALIZED, 0, 0, 0 }; + LBER_UNINITIALIZED, 0, 0 }; static BerMemoryFunctions ber_int_memory_fns_datum; @@ -36,8 +36,6 @@ ber_get_option( const BerElement *ber; const Sockbuf *sb; - ber_int_options.lbo_valid = LBER_INITIALIZED; - if(outvalue == NULL) { /* no place to get to */ ber_errno = LBER_ERROR_PARAM; @@ -59,7 +57,7 @@ ber_get_option( * The counter is not accurate for multithreaded ldap applications. */ #ifdef LDAP_MEMORY_DEBUG - * (int *) outvalue = ber_int_options.lbo_meminuse; + * (int *) outvalue = ber_int_meminuse; return LBER_OPT_SUCCESS; #else return LBER_OPT_ERROR; @@ -126,31 +124,6 @@ ber_set_option( BerElement *ber; Sockbuf *sb; - if( (ber_int_options.lbo_valid == LBER_UNINITIALIZED) - && ( ber_int_memory_fns == NULL ) - && ( option == LBER_OPT_MEMORY_FNS ) - && ( invalue != NULL ) ) - { - const BerMemoryFunctions *f = - (const BerMemoryFunctions *) invalue; - /* make sure all functions are provided */ - if(!( f->bmf_malloc && f->bmf_calloc - && f->bmf_realloc && f->bmf_free )) - { - ber_errno = LBER_ERROR_PARAM; - return LBER_OPT_ERROR; - } - - ber_int_memory_fns = &ber_int_memory_fns_datum; - - AC_MEMCPY(ber_int_memory_fns, f, sizeof(BerMemoryFunctions)); - - ber_int_options.lbo_valid = LBER_INITIALIZED; - return LBER_OPT_SUCCESS; - } - - ber_int_options.lbo_valid = LBER_INITIALIZED; - if(invalue == NULL) { /* no place to set from */ ber_errno = LBER_ERROR_PARAM; @@ -180,11 +153,33 @@ ber_set_option( * The counter is not accurate for multithreaded applications. */ #ifdef LDAP_MEMORY_DEBUG - ber_int_options.lbo_meminuse = * (int *) invalue; + ber_int_meminuse = * (int *) invalue; return LBER_OPT_SUCCESS; #else return LBER_OPT_ERROR; #endif + case LBER_OPT_MEMORY_FNS: + if ( ber_int_memory_fns == NULL ) + { + const BerMemoryFunctions *f = + (const BerMemoryFunctions *) invalue; + /* make sure all functions are provided */ + if(!( f->bmf_malloc && f->bmf_calloc + && f->bmf_realloc && f->bmf_free )) + { + ber_errno = LBER_ERROR_PARAM; + return LBER_OPT_ERROR; + } + + ber_int_memory_fns = &ber_int_memory_fns_datum; + + AC_MEMCPY(ber_int_memory_fns, f, + sizeof(BerMemoryFunctions)); + + return LBER_OPT_SUCCESS; + } + break; + case LBER_OPT_LOG_PROC: ber_int_log_proc = (BER_LOG_FN)invalue; return LBER_OPT_SUCCESS; diff --git a/libraries/liblber/sockbuf.c b/libraries/liblber/sockbuf.c index c30469cdec..21cf9eacb4 100644 --- a/libraries/liblber/sockbuf.c +++ b/libraries/liblber/sockbuf.c @@ -57,8 +57,6 @@ ber_sockbuf_alloc( void ) { Sockbuf *sb; - ber_int_options.lbo_valid = LBER_INITIALIZED; - sb = LBER_CALLOC( 1, sizeof( Sockbuf ) ); if( sb == NULL ) return NULL; diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c index ebaa7a3391..548f365952 100644 --- a/libraries/libldap/cyrus.c +++ b/libraries/libldap/cyrus.c @@ -455,6 +455,15 @@ sasl_err2ldap( int saslerr ) { int rc; + /* map SASL errors to LDAP API errors returned by: + * sasl_client_new() + * SASL_OK, SASL_NOMECH, SASL_NOMEM + * sasl_client_start() + * SASL_OK, SASL_NOMECH, SASL_NOMEM, SASL_INTERACT + * sasl_client_step() + * SASL_OK, SASL_INTERACT, SASL_BADPROT, SASL_BADSERV + */ + switch (saslerr) { case SASL_CONTINUE: rc = LDAP_MORE_RESULTS_TO_RETURN; @@ -465,21 +474,29 @@ sasl_err2ldap( int saslerr ) case SASL_OK: rc = LDAP_SUCCESS; break; - case SASL_FAIL: - rc = LDAP_LOCAL_ERROR; - break; case SASL_NOMEM: rc = LDAP_NO_MEMORY; break; case SASL_NOMECH: rc = LDAP_AUTH_UNKNOWN; break; + case SASL_BADPROT: + rc = LDAP_DECODING_ERROR; + break; + case SASL_BADSERV: + rc = LDAP_AUTH_UNKNOWN; + break; + + /* other codes */ case SASL_BADAUTH: rc = LDAP_AUTH_UNKNOWN; break; case SASL_NOAUTHZ: rc = LDAP_PARAM_ERROR; break; + case SASL_FAIL: + rc = LDAP_LOCAL_ERROR; + break; case SASL_TOOWEAK: case SASL_ENCRYPT: rc = LDAP_AUTH_UNKNOWN; diff --git a/libraries/libldap/error.c b/libraries/libldap/error.c index 529a3e2eea..bf782d7675 100644 --- a/libraries/libldap/error.c +++ b/libraries/libldap/error.c @@ -98,6 +98,13 @@ static struct ldaperror ldap_builtin_errlist[] = { {LDAP_X_NO_OPERATION, N_("No Operation (X)")}, + {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")}, + + /* API ResultCodes */ {LDAP_SERVER_DOWN, N_("Can't contact LDAP server")}, {LDAP_LOCAL_ERROR, N_("Local error")}, @@ -118,12 +125,6 @@ static struct ldaperror ldap_builtin_errlist[] = { {LDAP_CLIENT_LOOP, N_("Client Loop")}, {LDAP_REFERRAL_LIMIT_EXCEEDED, N_("Referral Limit Exceeded")}, - {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")}, - {0, NULL} }; @@ -310,12 +311,24 @@ ldap_parse_result( ber = ber_dup( lm->lm_ber ); if ( ld->ld_version < LDAP_VERSION2 ) { +#ifdef LDAP_NULL_IS_NULL + tag = ber_scanf( ber, "{iA}", + &ld->ld_errno, &ld->ld_error ); +#else /* ! LDAP_NULL_IS_NULL */ tag = ber_scanf( ber, "{ia}", &ld->ld_errno, &ld->ld_error ); +#endif /* ! LDAP_NULL_IS_NULL */ + } else { ber_len_t len; + +#ifdef LDAP_NULL_IS_NULL + tag = ber_scanf( ber, "{iAA" /*}*/, + &ld->ld_errno, &ld->ld_matched, &ld->ld_error ); +#else /* ! LDAP_NULL_IS_NULL */ tag = ber_scanf( ber, "{iaa" /*}*/, &ld->ld_errno, &ld->ld_matched, &ld->ld_error ); +#endif /* ! LDAP_NULL_IS_NULL */ if( tag != LBER_ERROR ) { /* peek for referrals */ @@ -376,10 +389,20 @@ ldap_parse_result( } if ( errcode == LDAP_SUCCESS ) { if( matcheddnp != NULL ) { - *matcheddnp = LDAP_STRDUP( ld->ld_matched ); +#ifdef LDAP_NULL_IS_NULL + if ( ld->ld_matched ) +#endif /* LDAP_NULL_IS_NULL */ + { + *matcheddnp = LDAP_STRDUP( ld->ld_matched ); + } } if( errmsgp != NULL ) { - *errmsgp = LDAP_STRDUP( ld->ld_error ); +#ifdef LDAP_NULL_IS_NULL + if ( ld->ld_error ) +#endif /* LDAP_NULL_IS_NULL */ + { + *errmsgp = LDAP_STRDUP( ld->ld_error ); + } } if( referralsp != NULL) { diff --git a/libraries/libldap/extended.c b/libraries/libldap/extended.c index 99d29d8f62..137dc69f04 100644 --- a/libraries/libldap/extended.c +++ b/libraries/libldap/extended.c @@ -210,8 +210,13 @@ ldap_parse_extended_result ( return ld->ld_errno; } +#ifdef LDAP_NULL_IS_NULL + rc = ber_scanf( ber, "{eAA" /*}*/, &errcode, + &ld->ld_matched, &ld->ld_error ); +#else /* ! LDAP_NULL_IS_NULL */ rc = ber_scanf( ber, "{eaa" /*}*/, &errcode, &ld->ld_matched, &ld->ld_error ); +#endif /* ! LDAP_NULL_IS_NULL */ if( rc == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; @@ -243,6 +248,10 @@ ldap_parse_extended_result ( return ld->ld_errno; } +#ifdef LDAP_NULL_IS_NULL + assert( resoid[ 0 ] != '\0' ); +#endif /* LDAP_NULL_IS_NULL */ + tag = ber_peek_tag( ber, &len ); } @@ -350,6 +359,10 @@ ldap_parse_intermediate ( return ld->ld_errno; } +#ifdef LDAP_NULL_IS_NULL + assert( resoid[ 0 ] != '\0' ); +#endif /* LDAP_NULL_IS_NULL */ + tag = ber_peek_tag( ber, &len ); } diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index ba6e98a6dc..533ef35296 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -169,6 +169,8 @@ struct ldapoptions { ber_int_t ldo_sizelimit; #ifdef HAVE_TLS + /* tls context */ + void *ldo_tls_ctx; int ldo_tls_mode; LDAP_TLS_CONNECT_CB *ldo_tls_connect_cb; void* ldo_tls_connect_arg; @@ -210,10 +212,6 @@ struct ldapoptions { */ typedef struct ldap_conn { Sockbuf *lconn_sb; -#ifdef HAVE_TLS - /* tls context */ - void *lconn_tls_ctx; -#endif #ifdef HAVE_CYRUS_SASL void *lconn_sasl_authctx; /* context for bind */ void *lconn_sasl_sockctx; /* for security layer */ diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c index e8106c5e7d..29760e3321 100644 --- a/libraries/libldap/options.c +++ b/libraries/libldap/options.c @@ -261,7 +261,7 @@ ldap_get_option( if( ld->ld_matched == NULL ) { * (char **) outvalue = NULL; } else { - * (char **) outvalue = LDAP_STRDUP(ld->ld_matched); + * (char **) outvalue = LDAP_STRDUP( ld->ld_matched ); } return LDAP_OPT_SUCCESS; @@ -615,24 +615,30 @@ ldap_set_option( if( ld->ld_error ) { LDAP_FREE(ld->ld_error); + ld->ld_error = NULL; } - ld->ld_error = LDAP_STRDUP(err); + if ( err ) { + ld->ld_error = LDAP_STRDUP(err); + } } return LDAP_OPT_SUCCESS; case LDAP_OPT_MATCHED_DN: { - const char *err = (const char *) invalue; + const char *matched = (const char *) invalue; - if(ld == NULL) { + if (ld == NULL) { /* need a struct ldap */ break; } if( ld->ld_matched ) { LDAP_FREE(ld->ld_matched); + ld->ld_matched = NULL; } - ld->ld_matched = LDAP_STRDUP(err); + if ( matched ) { + ld->ld_matched = LDAP_STRDUP( matched ); + } } return LDAP_OPT_SUCCESS; case LDAP_OPT_REFERRAL_URLS: { diff --git a/libraries/libldap/result.c b/libraries/libldap/result.c index 172ab6311e..f080c04ff9 100644 --- a/libraries/libldap/result.c +++ b/libraries/libldap/result.c @@ -565,18 +565,33 @@ nextresp2: ber_len_t len; char *lr_res_error = NULL; +#ifdef LDAP_NULL_IS_NULL + if ( ber_scanf( &tmpber, "{eAA",/*}*/ &lderr, + &lr->lr_res_matched, &lr_res_error ) + != LBER_ERROR ) +#else /* ! LDAP_NULL_IS_NULL */ if ( ber_scanf( &tmpber, "{eaa",/*}*/ &lderr, &lr->lr_res_matched, &lr_res_error ) != LBER_ERROR ) +#endif /* ! LDAP_NULL_IS_NULL */ { if ( lr_res_error != NULL ) { - if ( lr->lr_res_error != NULL ) { - (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error ); - LDAP_FREE( (char *)lr_res_error ); +#ifndef LDAP_NULL_IS_NULL + if ( lr_res_error[ 0 ] == '\0' ) { + LDAP_FREE( lr_res_error ); + lr_res_error = NULL; + } else +#endif /* ! LDAP_NULL_IS_NULL */ + { + if ( lr->lr_res_error != NULL ) { + (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error ); + LDAP_FREE( (char *)lr_res_error ); - } else { - lr->lr_res_error = lr_res_error; + } else { + lr->lr_res_error = lr_res_error; + } } + lr_res_error = NULL; } /* Check if V3 referral */ @@ -649,16 +664,29 @@ nextresp2: */ if ( tag == LDAP_RES_SEARCH_RESULT ) refer_cnt = 0; +#ifdef LDAP_NULL_IS_NULL + } else if ( ber_scanf( &tmpber, "{eAA}", &lderr, + &lr->lr_res_matched, &lr_res_error ) + != LBER_ERROR ) +#else /* ! LDAP_NULL_IS_NULL */ } else if ( ber_scanf( &tmpber, "{eaa}", &lderr, &lr->lr_res_matched, &lr_res_error ) != LBER_ERROR ) +#endif /* ! LDAP_NULL_IS_NULL */ { if ( lr_res_error != NULL ) { - if ( lr->lr_res_error != NULL ) { - (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error ); - LDAP_FREE( (char *)lr_res_error ); - } else { - lr->lr_res_error = lr_res_error; +#ifndef LDAP_NULL_IS_NULL + if ( lr_res_error[ 0 ] == '\0' ) { + LDAP_FREE( lr_res_error ); + } else +#endif /* ! LDAP_NULL_IS_NULL */ + { + if ( lr->lr_res_error != NULL ) { + (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error ); + LDAP_FREE( (char *)lr_res_error ); + } else { + lr->lr_res_error = lr_res_error; + } } lr_res_error = NULL; } @@ -697,10 +725,19 @@ nextresp2: } else { lr->lr_res_errno = LDAP_PARTIAL_RESULTS; } -Debug( LDAP_DEBUG_TRACE, - "new result: res_errno: %d, res_error: <%s>, res_matched: <%s>\n", - lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "", - lr->lr_res_matched ? lr->lr_res_matched : "" ); + + Debug( LDAP_DEBUG_TRACE, "new result: " + "res_errno: %d, " + "res_error: <%s>, " + "res_matched: <%s>\n", + lr->lr_res_errno, + lr->lr_res_error ? lr->lr_res_error : "", + lr->lr_res_matched ? lr->lr_res_matched : "" ); + } + + /* in any case, don't leave any lr_res_error 'round */ + if ( lr_res_error ) { + LDAP_FREE( lr_res_error ); } } diff --git a/libraries/libldap/sasl.c b/libraries/libldap/sasl.c index 849a9fa380..e47302f33b 100644 --- a/libraries/libldap/sasl.c +++ b/libraries/libldap/sasl.c @@ -294,8 +294,13 @@ ldap_parse_sasl_bind_result( } if ( ld->ld_version < LDAP_VERSION2 ) { +#ifdef LDAP_NULL_IS_NULL + tag = ber_scanf( ber, "{iA}", + &errcode, &ld->ld_error ); +#else /* ! LDAP_NULL_IS_NULL */ tag = ber_scanf( ber, "{ia}", &errcode, &ld->ld_error ); +#endif /* ! LDAP_NULL_IS_NULL */ if( tag == LBER_ERROR ) { ber_free( ber, 0 ); @@ -306,8 +311,13 @@ ldap_parse_sasl_bind_result( } else { ber_len_t len; +#ifdef LDAP_NULL_IS_NULL + tag = ber_scanf( ber, "{eAA" /*}*/, + &errcode, &ld->ld_matched, &ld->ld_error ); +#else /* ! LDAP_NULL_IS_NULL */ tag = ber_scanf( ber, "{eaa" /*}*/, &errcode, &ld->ld_matched, &ld->ld_error ); +#endif /* ! LDAP_NULL_IS_NULL */ if( tag == LBER_ERROR ) { ber_free( ber, 0 ); diff --git a/libraries/libldap/schema.c b/libraries/libldap/schema.c index bff6c5bdbe..f478e00324 100644 --- a/libraries/libldap/schema.c +++ b/libraries/libldap/schema.c @@ -1027,6 +1027,9 @@ get_token( const char ** sp, char ** token_val ) **sp != ')' && **sp != '$' && **sp != '\'' && + /* for suggested minimum upper bound on the number + * of characters */ + **sp != '{' && **sp != '\0' ) (*sp)++; q = *sp; @@ -2053,7 +2056,8 @@ ldap_str2attributetype( LDAP_CONST char * s, if ( !at->at_oid ) { if ( ( flags & ( LDAP_SCHEMA_ALLOW_NO_OID | LDAP_SCHEMA_ALLOW_OID_MACRO ) ) - && (ss == savepos) ) { + && (ss == savepos) ) + { /* Backtracking */ ss = savepos; kind = get_token(&ss,&sval); @@ -2070,11 +2074,13 @@ ldap_str2attributetype( LDAP_CONST char * s, !strcasecmp(sval, "COLLECTIVE") || !strcasecmp(sval, "NO-USER-MODIFICATION") || !strcasecmp(sval, "USAGE") || - !strncasecmp(sval, "X-", 2) ) { + !strncasecmp(sval, "X-", 2) ) + { /* Missing OID, backtrack */ ss = savepos; } else if ( flags - & LDAP_SCHEMA_ALLOW_OID_MACRO) { + & LDAP_SCHEMA_ALLOW_OID_MACRO) + { /* Non-numerical OID ... */ int len = ss-savepos; at->at_oid = LDAP_MALLOC(len+1); diff --git a/libraries/libldap/search.c b/libraries/libldap/search.c index d78eeb84ad..9a637ef7dc 100644 --- a/libraries/libldap/search.c +++ b/libraries/libldap/search.c @@ -368,7 +368,6 @@ ldap_search_s( 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, @@ -402,7 +401,8 @@ ldap_bv2escaped_filter_value( struct berval *in, struct berval *out ) if( out->bv_val == NULL ) return -1; for( i=0; ibv_len; i++ ) { - if (c & 0x80 || escape[in->bv_val[i]]) { + char c = in->bv_val[ i ]; + if (c & 0x80 || escape[ c ]) { 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]; diff --git a/libraries/libldap/tls.c b/libraries/libldap/tls.c index c03c8446a8..442db48655 100644 --- a/libraries/libldap/tls.c +++ b/libraries/libldap/tls.c @@ -200,7 +200,7 @@ ldap_pvt_tls_init( void ) * initialize the default context */ int -ldap_pvt_tls_init_def_ctx( void ) +ldap_pvt_tls_init_def_ctx( int is_server ) { STACK_OF(X509_NAME) *calist; int rc = 0; @@ -215,7 +215,7 @@ ldap_pvt_tls_init_def_ctx( void ) ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex ); #endif - if ( !certfile && !keyfile && !cacertfile && !cacertdir ) { + if ( is_server && !certfile && !keyfile && !cacertfile && !cacertdir ) { /* minimum configuration not provided */ #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex ); @@ -441,7 +441,7 @@ get_ca_list( char * bundle, char * dir ) } static SSL * -alloc_handle( void *ctx_arg ) +alloc_handle( void *ctx_arg, int is_server ) { SSL_CTX *ctx; SSL *ssl; @@ -449,7 +449,7 @@ alloc_handle( void *ctx_arg ) if ( ctx_arg ) { ctx = (SSL_CTX *) ctx_arg; } else { - if ( ldap_pvt_tls_init_def_ctx() < 0 ) return NULL; + if ( ldap_pvt_tls_init_def_ctx( is_server ) < 0 ) return NULL; ctx = tls_def_ctx; } @@ -764,10 +764,12 @@ ldap_int_tls_connect( LDAP *ld, LDAPConn *conn ) } else { struct ldapoptions *lo; - void *ctx = ld->ld_defconn - ? ld->ld_defconn->lconn_tls_ctx : NULL; + void *ctx; - ssl = alloc_handle( ctx ); + lo = &ld->ld_options; + ctx = lo->ldo_tls_ctx; + + ssl = alloc_handle( ctx, 0 ); if ( ssl == NULL ) return -1; @@ -780,9 +782,8 @@ ldap_int_tls_connect( LDAP *ld, LDAPConn *conn ) if( ctx == NULL ) { ctx = tls_def_ctx; - conn->lconn_tls_ctx = tls_def_ctx; + lo->ldo_tls_ctx = ctx; } - lo = &ld->ld_options; if ( lo->ldo_tls_connect_cb ) lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg ); lo = LDAP_INT_GLOBAL_OPT(); @@ -841,7 +842,7 @@ ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg ) ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl ); } else { - ssl = alloc_handle( ctx_arg ); + ssl = alloc_handle( ctx_arg, 1 ); if ( ssl == NULL ) return -1; #ifdef LDAP_DEBUG @@ -1245,7 +1246,7 @@ ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg ) if ( ld == NULL ) { *(void **)arg = (void *) tls_def_ctx; } else { - *(void **)arg = ld->ld_defconn->lconn_tls_ctx; + *(void **)arg = lo->ldo_tls_ctx; } break; case LDAP_OPT_X_TLS_CACERTFILE: @@ -1347,7 +1348,7 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg ) tls_def_ctx = (SSL_CTX *) arg; } else { - ld->ld_defconn->lconn_tls_ctx = arg; + lo->ldo_tls_ctx = arg; } return 0; case LDAP_OPT_X_TLS_CONNECT_CB: @@ -1782,7 +1783,7 @@ tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length ) dhparams = p; } } -done: + #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex ); #endif diff --git a/libraries/liblutil/tavl.c b/libraries/liblutil/tavl.c index f588c71d88..41e8d63018 100644 --- a/libraries/liblutil/tavl.c +++ b/libraries/liblutil/tavl.c @@ -186,7 +186,7 @@ void* tavl_delete( Avlnode **root, void* data, AVL_CMP fcmp ) { Avlnode *p, *q, *r, *top; - int side, side_bf, shorter, nside; + int side, side_bf, shorter, nside = -1; /* parent stack */ Avlnode *pptr[sizeof(void *)*8]; diff --git a/libraries/liblutil/utils.c b/libraries/liblutil/utils.c index 4d179f7543..d227f32828 100644 --- a/libraries/liblutil/utils.c +++ b/libraries/liblutil/utils.c @@ -310,3 +310,22 @@ int mkstemp( char * template ) #endif } #endif + +/* + * Memory Reverse Search + */ +void * +lutil_memrchr(const void *b, int c, size_t n) +{ + if (n != 0) { + const unsigned char *s, *bb = b, cc = c; + + for ( s = bb + n; s > bb; ) { + if ( *--s == cc ) { + return (void *) s; + } + } + } + + return NULL; +} diff --git a/servers/slapd/aci.c b/servers/slapd/aci.c index a77a9fb3ce..50bef60b75 100644 --- a/servers/slapd/aci.c +++ b/servers/slapd/aci.c @@ -42,6 +42,75 @@ #define ACI_BUF_SIZE 1024 /* use most appropriate size */ +enum { + ACI_BV_ENTRY, + ACI_BV_CHILDREN, + ACI_BV_ONELEVEL, + ACI_BV_SUBTREE, + + ACI_BV_BR_ENTRY, + ACI_BV_BR_ALL, + + ACI_BV_ACCESS_ID, + ACI_BV_PUBLIC, + ACI_BV_USERS, + ACI_BV_SELF, + ACI_BV_DNATTR, + ACI_BV_GROUP, + ACI_BV_ROLE, + ACI_BV_SET, + ACI_BV_SET_REF, + + ACI_BV_GRANT, + ACI_BV_DENY, + + ACI_BV_GROUP_CLASS, + ACI_BV_GROUP_ATTR, + ACI_BV_ROLE_CLASS, + ACI_BV_ROLE_ATTR, + + ACI_BV_SET_ATTR, + + ACI_BV_LAST +}; + +static const struct berval aci_bv[] = { + /* scope */ + BER_BVC("entry"), + BER_BVC("children"), + BER_BVC("onelevel"), + BER_BVC("subtree"), + + /* */ + BER_BVC("[entry]"), + BER_BVC("[all]"), + + /* type */ + BER_BVC("access-id"), + BER_BVC("public"), + BER_BVC("users"), + BER_BVC("self"), + BER_BVC("dnattr"), + BER_BVC("group"), + BER_BVC("role"), + BER_BVC("set"), + BER_BVC("set-ref"), + + /* actions */ + BER_BVC("grant"), + BER_BVC("deny"), + + /* schema */ + BER_BVC(SLAPD_GROUP_CLASS), + BER_BVC(SLAPD_GROUP_ATTR), + BER_BVC(SLAPD_ROLE_CLASS), + BER_BVC(SLAPD_ROLE_ATTR), + + BER_BVC(SLAPD_ACI_SET_ATTR), + + BER_BVNULL +}; + #ifdef SLAP_DYNACL static #endif /* SLAP_DYNACL */ @@ -554,12 +623,12 @@ aci_mask( } } else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET ], &type ) == 0 ) { - if ( acl_match_set( &sdn, op, e, 0 ) ) { + if ( acl_match_set( &sdn, op, e, NULL ) ) { return 1; } } else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET_REF ], &type ) == 0 ) { - if ( acl_match_set( &sdn, op, e, 1 ) ) { + if ( acl_match_set( &sdn, op, e, (struct berval *)&aci_bv[ ACI_BV_SET_ATTR ] ) ) { return 1; } @@ -574,7 +643,7 @@ aci_mask( int aci_init( void ) { - /* OpenLDAP Experimental Syntax */ + /* OpenLDAP eXperimental Syntax */ static slap_syntax_defs_rec aci_syntax_def = { "( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )", SLAP_SYNTAX_HIDE, @@ -659,11 +728,6 @@ aci_init( void ) } #ifdef SLAP_DYNACL -/* - * FIXME: there is a silly dependence that makes it difficult - * to move ACIs in a run-time loadable module under the "dynacl" - * umbrella, because sets share some helpers with ACIs. - */ static int dynacl_aci_parse( const char *fname, @@ -744,6 +808,11 @@ dynacl_aci_mask( char accessmaskbuf1[ACCESSMASK_MAXLEN]; #endif /* LDAP_DEBUG */ + if ( BER_BVISEMPTY( &e->e_nname ) ) { + /* no ACIs in the root DSE */ + return -1; + } + /* start out with nothing granted, nothing denied */ ACL_INIT(tgrant); ACL_INIT(tdeny); @@ -767,7 +836,7 @@ dynacl_aci_mask( } } - Debug( LDAP_DEBUG_ACL, "<= aci_mask grant %s deny %s\n", + Debug( LDAP_DEBUG_ACL, " <= aci_mask grant %s deny %s\n", accessmask2str( tgrant, accessmaskbuf, 1 ), accessmask2str( tdeny, accessmaskbuf1, 1 ), 0 ); } @@ -779,35 +848,41 @@ dynacl_aci_mask( if ( tgrant == ACL_PRIV_NONE && tdeny == ACL_PRIV_NONE ) { struct berval parent_ndn; -#if 1 - /* to solve the chicken'n'egg problem of accessing - * the OpenLDAPaci attribute, the direct access - * to the entry's attribute is unchecked; however, - * further accesses to OpenLDAPaci values in the - * ancestors occur through backend_attribute(), i.e. - * with the identity of the operation, requiring - * further access checking. For uniformity, this - * makes further requests occur as the rootdn, if - * any, i.e. searching for the OpenLDAPaci attribute - * is considered an internal search. If this is not - * acceptable, then the same check needs be performed - * when accessing the entry's attribute. */ - Operation op2 = *op; - - if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) { - op2.o_dn = op->o_bd->be_rootdn; - op2.o_ndn = op->o_bd->be_rootndn; - } -#endif - dnParent( &e->e_nname, &parent_ndn ); while ( !BER_BVISEMPTY( &parent_ndn ) ){ int i; BerVarray bvals = NULL; int ret, stop; - Debug( LDAP_DEBUG_ACL, "checking ACI of \"%s\"\n", parent_ndn.bv_val, 0, 0 ); - ret = backend_attribute( &op2, NULL, &parent_ndn, ad, &bvals, ACL_AUTH ); + /* to solve the chicken'n'egg problem of accessing + * the OpenLDAPaci attribute, the direct access + * to the entry's attribute is unchecked; however, + * further accesses to OpenLDAPaci values in the + * ancestors occur through backend_attribute(), i.e. + * with the identity of the operation, requiring + * further access checking. For uniformity, this + * makes further requests occur as the rootdn, if + * any, i.e. searching for the OpenLDAPaci attribute + * is considered an internal search. If this is not + * acceptable, then the same check needs be performed + * when accessing the entry's attribute. */ + struct berval save_o_dn, save_o_ndn; + + if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) { + save_o_dn = op->o_dn; + save_o_ndn = op->o_ndn; + + op->o_dn = op->o_bd->be_rootdn; + op->o_ndn = op->o_bd->be_rootndn; + } + + Debug( LDAP_DEBUG_ACL, " checking ACI of \"%s\"\n", parent_ndn.bv_val, 0, 0 ); + ret = backend_attribute( op, NULL, &parent_ndn, ad, &bvals, ACL_AUTH ); + + if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) { + op->o_dn = save_o_dn; + op->o_ndn = save_o_ndn; + } switch ( ret ) { case LDAP_SUCCESS : @@ -1319,16 +1394,14 @@ OpenLDAPaciValidate( struct berval ocbv = BER_BVNULL, atbv = BER_BVNULL; - ocbv.bv_val = strchr( type.bv_val, '/' ); - if ( ocbv.bv_val != NULL - && ( ocbv.bv_val - type.bv_val ) < type.bv_len ) - { + ocbv.bv_val = ber_bvchr( &type, '/' ); + if ( ocbv.bv_val != NULL ) { ocbv.bv_val++; + ocbv.bv_len = type.bv_len + - ( ocbv.bv_val - type.bv_val ); - atbv.bv_val = strchr( ocbv.bv_val, '/' ); - if ( atbv.bv_val != NULL - && ( atbv.bv_val - ocbv.bv_val ) < ocbv.bv_len ) - { + atbv.bv_val = ber_bvchr( &ocbv, '/' ); + if ( atbv.bv_val != NULL ) { AttributeDescription *ad = NULL; const char *text = NULL; int rc; @@ -1342,10 +1415,6 @@ OpenLDAPaciValidate( if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } - - } else { - ocbv.bv_len = type.bv_len - - ( ocbv.bv_val - type.bv_val ); } if ( oc_bvfind( &ocbv ) == NULL ) { @@ -1474,10 +1543,8 @@ OpenLDAPaciPrettyNormal( struct berval ocbv = BER_BVNULL, atbv = BER_BVNULL; - ocbv.bv_val = strchr( type.bv_val, '/' ); - if ( ocbv.bv_val != NULL - && ( ocbv.bv_val - type.bv_val ) < type.bv_len ) - { + ocbv.bv_val = ber_bvchr( &type, '/' ); + if ( ocbv.bv_val != NULL ) { ObjectClass *oc = NULL; AttributeDescription *ad = NULL; const char *text = NULL; @@ -1487,11 +1554,10 @@ OpenLDAPaciPrettyNormal( bv.bv_len = ntype.bv_len; ocbv.bv_val++; + ocbv.bv_len = type.bv_len - ( ocbv.bv_val - type.bv_val ); - atbv.bv_val = strchr( ocbv.bv_val, '/' ); - if ( atbv.bv_val != NULL - && ( atbv.bv_val - ocbv.bv_val ) < ocbv.bv_len ) - { + atbv.bv_val = ber_bvchr( &ocbv, '/' ); + if ( atbv.bv_val != NULL ) { atbv.bv_val++; atbv.bv_len = type.bv_len - ( atbv.bv_val - type.bv_val ); @@ -1504,10 +1570,6 @@ OpenLDAPaciPrettyNormal( } bv.bv_len += STRLENOF( "/" ) + ad->ad_cname.bv_len; - - } else { - ocbv.bv_len = type.bv_len - - ( ocbv.bv_val - type.bv_val ); } oc = oc_bvfind( &ocbv ); diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index 8bff33752d..5b84f9e304 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -39,46 +39,10 @@ #define ACL_BUF_SIZE 1024 /* use most appropriate size */ -/* - * speed up compares - */ -const struct berval aci_bv[] = { - BER_BVC("entry"), - BER_BVC("children"), - BER_BVC("onelevel"), - BER_BVC("subtree"), - BER_BVC("[entry]"), - BER_BVC("[all]"), - BER_BVC("access-id"), -#if 0 - BER_BVC("anonymous"), -#endif - BER_BVC("public"), - BER_BVC("users"), - BER_BVC("self"), - BER_BVC("dnattr"), - BER_BVC("group"), - BER_BVC("role"), - BER_BVC("set"), - BER_BVC("set-ref"), - BER_BVC("grant"), - BER_BVC("deny"), - - BER_BVC("IP="), +static const struct berval acl_bv_ip_eq = BER_BVC( "IP=" ); #ifdef LDAP_PF_LOCAL - BER_BVC("PATH="), -#if 0 - BER_BVC(LDAP_DIRSEP), -#endif +static const struct berval acl_bv_path_eq = BER_BVC("PATH="); #endif /* LDAP_PF_LOCAL */ - - BER_BVC(SLAPD_GROUP_CLASS), - BER_BVC(SLAPD_GROUP_ATTR), - BER_BVC(SLAPD_ROLE_CLASS), - BER_BVC(SLAPD_ROLE_ATTR), - - BER_BVC(SLAPD_ACI_SET_ATTR) -}; static AccessControl * slap_acl_get( AccessControl *ac, int *count, @@ -1395,9 +1359,6 @@ slap_acl_mask( Access *b; #ifdef LDAP_DEBUG char accessmaskbuf[ACCESSMASK_MAXLEN]; -#if !defined( SLAP_DYNACL ) && defined( SLAPD_ACI_ENABLED ) - char accessmaskbuf1[ACCESSMASK_MAXLEN]; -#endif /* !SLAP_DYNACL && SLAPD_ACI_ENABLED */ #endif /* DEBUG */ const char *attr; slap_mask_t a2pmask = ACL_ACCESS2PRIV( *mask ); @@ -1633,12 +1594,12 @@ slap_acl_mask( int port_number = -1; if ( strncasecmp( op->o_conn->c_peer_name.bv_val, - aci_bv[ ACI_BV_IP_EQ ].bv_val, - aci_bv[ ACI_BV_IP_EQ ].bv_len ) != 0 ) + acl_bv_ip_eq.bv_val, + acl_bv_ip_eq.bv_len ) != 0 ) continue; - ip.bv_val = op->o_conn->c_peer_name.bv_val + aci_bv[ ACI_BV_IP_EQ ].bv_len; - ip.bv_len = op->o_conn->c_peer_name.bv_len - aci_bv[ ACI_BV_IP_EQ ].bv_len; + ip.bv_val = op->o_conn->c_peer_name.bv_val + acl_bv_ip_eq.bv_len; + ip.bv_len = op->o_conn->c_peer_name.bv_len - acl_bv_ip_eq.bv_len; port = strrchr( ip.bv_val, ':' ); if ( port ) { @@ -1677,14 +1638,14 @@ slap_acl_mask( struct berval path; if ( strncmp( op->o_conn->c_peer_name.bv_val, - aci_bv[ ACI_BV_PATH_EQ ].bv_val, - aci_bv[ ACI_BV_PATH_EQ ].bv_len ) != 0 ) + acl_bv_path_eq.bv_val, + acl_bv_path_eq.bv_len ) != 0 ) continue; path.bv_val = op->o_conn->c_peer_name.bv_val - + aci_bv[ ACI_BV_PATH_EQ ].bv_len; + + acl_bv_path_eq.bv_len; path.bv_len = op->o_conn->c_peer_name.bv_len - - aci_bv[ ACI_BV_PATH_EQ ].bv_len; + - acl_bv_path_eq.bv_len; if ( ber_bvcmp( &b->a_peername_pat, &path ) != 0 ) continue; @@ -1923,7 +1884,7 @@ slap_acl_mask( bv = b->a_set_pat; } - if ( acl_match_set( &bv, op, e, 0 ) == 0 ) { + if ( acl_match_set( &bv, op, e, NULL ) == 0 ) { continue; } } @@ -1972,14 +1933,9 @@ slap_acl_mask( 0, 0, 0 ); /* this case works different from the others above. - * since aci's themselves give permissions, we need + * since dynamic ACL's themselves give permissions, we need * to first check b->a_access_mask, the ACL's access level. */ - if ( BER_BVISEMPTY( &e->e_nname ) ) { - /* no ACIs in the root DSE */ - continue; - } - /* first check if the right being requested * is allowed by the ACL clause. */ @@ -2037,6 +1993,8 @@ slap_acl_mask( } else #else /* !SLAP_DYNACL */ + /* NOTE: this entire block can be eliminated when SLAP_DYNACL + * moves outside of LDAP_DEVEL */ #ifdef SLAPD_ACI_ENABLED if ( b->a_aci_at != NULL ) { Attribute *at; @@ -2044,6 +2002,9 @@ slap_acl_mask( struct berval parent_ndn; BerVarray bvals = NULL; int ret, stop; +#ifdef LDAP_DEBUG + char accessmaskbuf1[ACCESSMASK_MAXLEN]; +#endif /* DEBUG */ Debug( LDAP_DEBUG_ACL, " <= check a_aci_at: %s\n", b->a_aci_at->ad_cname.bv_val, 0, 0 ); @@ -2679,13 +2640,13 @@ acl_match_set ( struct berval *subj, Operation *op, Entry *e, - int setref ) + struct berval *default_set_attribute ) { struct berval set = BER_BVNULL; int rc = 0; AclSetCookie cookie; - if ( setref == 0 ) { + if ( default_set_attribute == NULL ) { ber_dupbv_x( &set, subj, op->o_tmpmemctx ); } else { @@ -2701,7 +2662,7 @@ acl_match_set ( } if ( acl_get_part( subj, 1, '/', &setat ) < 0 ) { - setat = aci_bv[ ACI_BV_SET_ATTR ]; + setat = *default_set_attribute; } /* @@ -2798,23 +2759,34 @@ slap_dynacl_get( const char *name ) } #endif /* SLAP_DYNACL */ -int -acl_init( void ) -{ - int rc = 0; - +/* + * statically built-in dynamic ACL initialization + */ +static int (*acl_init_func[])( void ) = { #ifdef SLAPD_ACI_ENABLED #ifdef SLAP_DYNACL - rc = dynacl_aci_init(); + dynacl_aci_init, #else /* !SLAP_DYNACL */ - rc = aci_init(); + aci_init, #endif /* !SLAP_DYNACL */ - if ( rc != 0 ) { - return rc; - } #endif /* SLAPD_ACI_ENABLED */ - return rc; + NULL +}; + +int +acl_init( void ) +{ + int i, rc; + + for ( i = 0; acl_init_func[ i ] != NULL; i++ ) { + rc = (*(acl_init_func[ i ]))(); + if ( rc != 0 ) { + return rc; + } + } + + return 0; } int diff --git a/servers/slapd/ad.c b/servers/slapd/ad.c index d351c5c49d..b6dcbcf295 100644 --- a/servers/slapd/ad.c +++ b/servers/slapd/ad.c @@ -177,7 +177,7 @@ int slap_bv2ad( memset( &desc, 0, sizeof( desc ) ); desc.ad_cname = *bv; name = bv->bv_val; - options = strchr( name, ';' ); + options = ber_bvchr( bv, ';' ); if ( options != NULL && (unsigned) ( options - name ) < bv->bv_len ) { /* don't go past the end of the berval! */ desc.ad_cname.bv_len = options - name; diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 552a0e6245..896eae65ea 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -664,7 +664,7 @@ int slap_add_opattrs( } else { csn = op->o_csn; } - ptr = strchr( csn.bv_val, '#' ); + ptr = ber_bvchr( &csn, '#' ); if ( ptr ) { timestamp.bv_len = ptr - csn.bv_val; if ( timestamp.bv_len >= sizeof(timebuf) ) diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c index b236ac2dab..d7f41d5dac 100644 --- a/servers/slapd/back-bdb/cache.c +++ b/servers/slapd/back-bdb/cache.c @@ -899,7 +899,8 @@ bdb_cache_add( #ifdef BDB_HIER if ( nrdn->bv_len != e->e_nname.bv_len ) { - char *ptr = strchr( rdn.bv_val, ',' ); + char *ptr = ber_bvchr( &rdn, ',' ); + assert( ptr != NULL ); rdn.bv_len = ptr - rdn.bv_val; } ber_dupbv( &ei.bei_rdn, &rdn ); @@ -1012,7 +1013,8 @@ bdb_cache_modrdn( rdn = e->e_name; if ( nrdn->bv_len != e->e_nname.bv_len ) { - char *ptr = strchr(rdn.bv_val, ','); + char *ptr = ber_bvchr(&rdn, ','); + assert( ptr != NULL ); rdn.bv_len = ptr - rdn.bv_val; } ber_dupbv( &ei->bei_rdn, &rdn ); diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index 08d0a5d8c7..311e16cc4e 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -381,7 +381,9 @@ retry: /* transaction retry */ } } - e = ei->bei_e; + if ( !fakeroot ) { + e = ei->bei_e; + } /* acquire and lock entry */ /* FIXME: dn2entry() should return non-glue entry */ @@ -537,6 +539,8 @@ retry: /* transaction retry */ if ( fakeroot ) { e->e_private = NULL; entry_free( e ); + e = NULL; + } else { rc = bdb_cache_modify( e, dummy.e_attrs, bdb->bi_dbenv, locker, &lock ); switch( rc ) { diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c index 9dbb549afc..39ff2d728a 100644 --- a/servers/slapd/back-bdb/tools.c +++ b/servers/slapd/back-bdb/tools.c @@ -70,7 +70,6 @@ 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( @@ -118,8 +117,6 @@ int bdb_tool_entry_open( int bdb_tool_entry_close( BackendDB *be ) { - 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 ); diff --git a/servers/slapd/back-ldap/add.c b/servers/slapd/back-ldap/add.c index 96a9c3b94d..0c394c3645 100644 --- a/servers/slapd/back-ldap/add.c +++ b/servers/slapd/back-ldap/add.c @@ -36,6 +36,8 @@ ldap_back_add( Operation *op, SlapReply *rs ) { + struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + struct ldapconn *lc; int i = 0, j = 0; @@ -100,7 +102,8 @@ ldap_back_add( retry: rs->sr_err = ldap_add_ext( lc->lc_ld, op->o_req_dn.bv_val, attrs, ctrls, NULL, &msgid ); - rs->sr_err = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT ); + rs->sr_err = ldap_back_op_result( lc, op, rs, msgid, + li->timeout[ LDAP_BACK_OP_ADD ], LDAP_BACK_SENDRESULT ); if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { do_retry = 0; if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index e9a74db2f8..f0a4330ac4 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -93,6 +93,17 @@ enum { LDAP_BACK_IDASSERT_OTHERID }; +/* + * operation enumeration for timeouts + */ +enum { + LDAP_BACK_OP_ADD = 0, + LDAP_BACK_OP_DELETE, + LDAP_BACK_OP_MODIFY, + LDAP_BACK_OP_MODRDN, + LDAP_BACK_OP_LAST +}; + struct ldapinfo { char *url; LDAPURLDesc *lud; @@ -166,6 +177,8 @@ struct ldapinfo { /* FIXME: automatic rwm instantiation removed */ int rwm_started; #endif + + time_t timeout[ LDAP_BACK_OP_LAST ]; }; typedef enum ldap_back_send_t { diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index a34dc44e0f..a77af50c9f 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -71,7 +71,7 @@ ldap_back_bind( Operation *op, SlapReply *rs ) rs->sr_err = ldap_sasl_bind( lc->lc_ld, op->o_req_dn.bv_val, LDAP_SASL_SIMPLE, &op->orb_cred, op->o_ctrls, NULL, &msgid ); - rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDERR ); + rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_SENDERR ); if ( rc == LDAP_SUCCESS ) { /* If defined, proxyAuthz will be used also when @@ -316,7 +316,12 @@ retry:; rc = ldap_parse_extended_result( ld, res, NULL, &data, 0 ); if ( rc == LDAP_SUCCESS ) { - rc = ldap_result2error( ld, res, 1 ); + int err; + rc = ldap_parse_result( ld, res, &err, + NULL, NULL, NULL, NULL, 1 ); + if ( rc == LDAP_SUCCESS ) { + rc = err; + } res = NULL; /* FIXME: in case a referral @@ -737,7 +742,7 @@ retry:; return 0; } - rc = ldap_back_op_result( lc, op, rs, msgid, sendok ); + rc = ldap_back_op_result( lc, op, rs, msgid, 0, sendok ); if ( rc == LDAP_SUCCESS ) { LDAP_BACK_CONN_ISBOUND_SET( lc ); @@ -800,6 +805,7 @@ ldap_back_op_result( Operation *op, SlapReply *rs, ber_int_t msgid, + time_t timeout, ldap_back_send_t sendok ) { char *match = NULL; @@ -818,12 +824,27 @@ ldap_back_op_result( int rc; struct timeval tv; - LDAP_BACK_TV_SET( &tv ); + if ( timeout ) { + tv.tv_sec = timeout; + tv.tv_usec = 0; + + } else { + LDAP_BACK_TV_SET( &tv ); + } retry:; /* if result parsing fails, note the failure reason */ - switch ( ldap_result( lc->lc_ld, msgid, 1, &tv, &res ) ) { + rc = ldap_result( lc->lc_ld, msgid, 1, &tv, &res ); + switch ( rc ) { case 0: + if ( timeout ) { + (void)ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL ); + rs->sr_err = op->o_protocol >= LDAP_VERSION3 ? + LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR; + rs->sr_text = "Operation timed out"; + break; + } + LDAP_BACK_TV_SET( &tv ); ldap_pvt_thread_yield(); goto retry; @@ -893,6 +914,12 @@ ldap_back_retry( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_se ldap_pvt_thread_mutex_lock( &li->conn_mutex ); if ( lc->lc_refcnt == 1 ) { + Debug( LDAP_DEBUG_ANY, + "%s ldap_back_retry: retrying URI=\"%s\" DN=\"%s\"\n", + op->o_log_prefix, li->url, + BER_BVISNULL( &lc->lc_bound_ndn ) ? + "" : lc->lc_bound_ndn.bv_val ); + ldap_unbind_ext( lc->lc_ld, NULL, NULL ); lc->lc_ld = NULL; LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); @@ -1089,7 +1116,7 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ) goto done; } - rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDERR ); + rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_SENDERR ); if ( rc == LDAP_SUCCESS ) { LDAP_BACK_CONN_ISBOUND_SET( lc ); } @@ -1240,7 +1267,7 @@ ldap_back_proxy_authz_ctrl( rs->sr_text = "proxyAuthz not allowed within namingContext"; } - if ( op->o_do_not_cache && op->o_is_auth_check ) { + if ( op->o_is_auth_check ) { mode = LDAP_BACK_IDASSERT_NOASSERT; } else { diff --git a/servers/slapd/back-ldap/compare.c b/servers/slapd/back-ldap/compare.c index 44628d98b4..64caac368a 100644 --- a/servers/slapd/back-ldap/compare.c +++ b/servers/slapd/back-ldap/compare.c @@ -60,7 +60,7 @@ retry: op->orc_ava->aa_desc->ad_cname.bv_val, &op->orc_ava->aa_value, ctrls, NULL, &msgid ); - rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT ); + rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_SENDRESULT ); if ( rc == LDAP_UNAVAILABLE && do_retry ) { do_retry = 0; if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 7968dc5331..3e5573f7bb 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -59,6 +59,7 @@ enum { LDAP_BACK_CFG_CHASE, LDAP_BACK_CFG_T_F, LDAP_BACK_CFG_WHOAMI, + LDAP_BACK_CFG_TIMEOUT, LDAP_BACK_CFG_REWRITE }; @@ -203,6 +204,14 @@ static ConfigTable ldapcfg[] = { "SYNTAX OMsDirectoryString " "SINGLE-VALUE )", NULL, NULL }, + { "timeout", "timeout", 0, 2, 0, + ARG_MAGIC|LDAP_BACK_CFG_TIMEOUT, + ldap_back_cf_gen, "( OLcfgDbAt:3.14 " + "NAME 'olcDbTimeout' " + "DESC 'Per-operation timeouts' " + "SYNTAX OMsDirectoryString " + "SINGLE-VALUE )", + NULL, NULL }, { "suffixmassage", "[virtual]> o_bd->be_private; + struct ldapconn *lc; ber_int_t msgid; LDAPControl **ctrls = NULL; @@ -59,7 +61,8 @@ ldap_back_delete( retry: rs->sr_err = ldap_delete_ext( lc->lc_ld, op->o_req_ndn.bv_val, ctrls, NULL, &msgid ); - rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT ); + rc = ldap_back_op_result( lc, op, rs, msgid, + li->timeout[ LDAP_BACK_OP_DELETE], LDAP_BACK_SENDRESULT ); if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) { do_retry = 0; if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { diff --git a/servers/slapd/back-ldap/modify.c b/servers/slapd/back-ldap/modify.c index 7725986bf7..ae0820ff53 100644 --- a/servers/slapd/back-ldap/modify.c +++ b/servers/slapd/back-ldap/modify.c @@ -36,6 +36,8 @@ ldap_back_modify( Operation *op, SlapReply *rs ) { + struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + struct ldapconn *lc; LDAPMod **modv = NULL, *mods = NULL; @@ -107,7 +109,8 @@ ldap_back_modify( retry: rs->sr_err = ldap_modify_ext( lc->lc_ld, op->o_req_ndn.bv_val, modv, ctrls, NULL, &msgid ); - rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT ); + rc = ldap_back_op_result( lc, op, rs, msgid, + li->timeout[ LDAP_BACK_OP_MODIFY], LDAP_BACK_SENDRESULT ); if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { do_retry = 0; if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { diff --git a/servers/slapd/back-ldap/modrdn.c b/servers/slapd/back-ldap/modrdn.c index 0890b26d19..254038570e 100644 --- a/servers/slapd/back-ldap/modrdn.c +++ b/servers/slapd/back-ldap/modrdn.c @@ -36,6 +36,8 @@ ldap_back_modrdn( Operation *op, SlapReply *rs ) { + struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + struct ldapconn *lc; ber_int_t msgid; LDAPControl **ctrls = NULL; @@ -67,7 +69,8 @@ retry: rs->sr_err = ldap_rename( lc->lc_ld, op->o_req_ndn.bv_val, op->orr_newrdn.bv_val, newSup, op->orr_deleteoldrdn, ctrls, NULL, &msgid ); - rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT ); + rc = ldap_back_op_result( lc, op, rs, msgid, + li->timeout[ LDAP_BACK_OP_MODRDN ], LDAP_BACK_SENDRESULT ); if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) { do_retry = 0; if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { diff --git a/servers/slapd/back-ldap/proto-ldap.h b/servers/slapd/back-ldap/proto-ldap.h index 80600e391c..f705bf521c 100644 --- a/servers/slapd/back-ldap/proto-ldap.h +++ b/servers/slapd/back-ldap/proto-ldap.h @@ -55,7 +55,7 @@ int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_bac int ldap_back_retry(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok); int ldap_back_map_result(SlapReply *rs); int ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs, - ber_int_t msgid, ldap_back_send_t sendok); + ber_int_t msgid, time_t timeout, ldap_back_send_t sendok); int back_ldap_LTX_init_module(int argc, char *argv[]); int ldap_back_init_cf( BackendInfo *bi ); diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 8f33ae38f5..9c880bc552 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -143,7 +143,7 @@ ldap_back_search( { struct ldapconn *lc; struct timeval tv; - time_t stoptime; + time_t stoptime = (time_t)-1; LDAPMessage *res, *e; int rc = 0, @@ -223,7 +223,7 @@ fail:; goto retry; } } - rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); + rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND ); ldap_back_freeconn( op, lc ); lc = NULL; goto finish; @@ -346,7 +346,7 @@ fail:; /* cleanup */ if ( references ) { - ldap_value_free( references ); + ber_memvfree( (void **)references ); ch_free( rs->sr_ref ); rs->sr_ref = NULL; } @@ -404,7 +404,7 @@ fail:; /* cleanup */ if ( references ) { - ldap_value_free( references ); + ber_memvfree( (void **)references ); } rc = 0; diff --git a/servers/slapd/back-meta/add.c b/servers/slapd/back-meta/add.c index fe383f230c..84dc2b7f1c 100644 --- a/servers/slapd/back-meta/add.c +++ b/servers/slapd/back-meta/add.c @@ -178,8 +178,8 @@ retry:; LDAPMessage *res = NULL; int rc; - if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_ADD ] != 0 ) { - tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_ADD ]; + if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_ADD ] != 0 ) { + tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_ADD ]; tv.tv_usec = 0; tvp = &tv; } diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 5d1911d3ed..87ba1badf0 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -184,6 +184,7 @@ typedef struct metaconn_t { struct slap_conn *mc_conn; ldap_pvt_thread_mutex_t mc_mutex; unsigned mc_refcnt; + int mc_tainted; struct berval mc_local_ndn; /* NOTE: msc_mscflags is used to recycle the #define @@ -204,14 +205,6 @@ typedef struct metaconn_t { * in one block with the metaconn_t structure */ } metaconn_t; -enum { - META_OP_ADD = 0, - META_OP_DELETE, - META_OP_MODIFY, - META_OP_MODRDN, - META_OP_LAST -}; - typedef struct metatarget_t { char *mt_uri; int mt_scope; @@ -235,7 +228,7 @@ typedef struct metatarget_t { unsigned mt_flags; int mt_version; - time_t mt_timeout[ META_OP_LAST ]; + time_t mt_timeout[ LDAP_BACK_OP_LAST ]; } metatarget_t; typedef struct metadncache_t { @@ -278,7 +271,7 @@ typedef struct metainfo_t { #define META_BACK_DEFER_ROOTDN_BIND(mi) ( (mi)->flags & META_BACK_F_DEFER_ROOTDN_BIND ) int mi_version; - time_t mi_timeout[ META_OP_LAST ]; + time_t mi_timeout[ LDAP_BACK_OP_LAST ]; } metainfo_t; typedef enum meta_op_type { diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 3d59cf27d4..3d68674336 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -46,7 +46,8 @@ meta_back_single_bind( Operation *op, SlapReply *rs, metaconn_t *mc, - int candidate ); + int candidate, + int massage ); int meta_back_bind( Operation *op, SlapReply *rs ) @@ -124,6 +125,7 @@ meta_back_bind( Operation *op, SlapReply *rs ) for ( i = 0; i < mi->mi_ntargets; i++ ) { int lerr; Operation op2 = *op; + int massage = 1; /* * Skip non-candidates @@ -177,9 +179,12 @@ meta_back_bind( Operation *op, SlapReply *rs ) op2.o_req_ndn = mi->mi_targets[ i ].mt_pseudorootdn; op2.orb_cred = mi->mi_targets[ i ].mt_pseudorootpw; op2.orb_method = LDAP_AUTH_SIMPLE; + + massage = 0; } - lerr = meta_back_single_bind( &op2, rs, mc, i ); + lerr = meta_back_single_bind( &op2, rs, mc, i, massage ); + if ( lerr != LDAP_SUCCESS ) { rs->sr_err = lerr; candidates[ i ].sr_tag = META_NOT_CANDIDATE; @@ -274,12 +279,12 @@ meta_back_single_bind( Operation *op, SlapReply *rs, metaconn_t *mc, - int candidate ) + int candidate, + int massage ) { metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; metatarget_t *mt = &mi->mi_targets[ candidate ]; struct berval mdn = BER_BVNULL; - dncookie dc; metasingleconn_t *msc = &mc->mc_conns[ candidate ]; int msgid, rebinding = 0; @@ -300,14 +305,21 @@ meta_back_single_bind( /* * Rewrite the bind dn if needed */ - dc.target = mt; - dc.conn = op->o_conn; - dc.rs = rs; - dc.ctx = "bindDN"; + if ( massage ) { + dncookie dc; - if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) { - send_ldap_result( op, rs ); - return -1; + dc.target = mt; + dc.conn = op->o_conn; + dc.rs = rs; + dc.ctx = "bindDN"; + + if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) { + send_ldap_result( op, rs ); + return -1; + } + + } else { + mdn = op->o_req_dn; } /* FIXME: this fixes the bind problem right now; we need @@ -378,27 +390,7 @@ retry:; rc = slap_map_api2result( rs ); if ( rs->sr_err == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) { - ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); - if ( mc->mc_refcnt == 1 ) { - meta_clear_one_candidate( msc ); - LDAP_BACK_CONN_ISBOUND_CLEAR( msc ); - - ( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn ); - - /* mc here must be the regular mc, - * reset and ready for init */ - rc = meta_back_init_one_conn( op, rs, - mt, mc, msc, LDAP_BACK_CONN_ISPRIV( mc ), - candidate == mc->mc_authz_target, - LDAP_BACK_DONTSEND ); - - } else { - /* can't do anything about it */ - rc = 0; - } - - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); - + rc = meta_back_retry( op, rs, mc, candidate, LDAP_BACK_DONTSEND ); if ( rc ) { if ( nretries > 0 ) { nretries--; @@ -552,6 +544,9 @@ retry:; rc = slap_map_api2result( rs ); if ( rc == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) { + /* NOTE: we do not use meta_back_retry() here + * to avoid circular loops; mc_mutex is set + * by the caller */ if ( dolock ) { ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); } @@ -569,7 +564,6 @@ retry:; LDAP_BACK_CONN_ISPRIV( mc ), candidate == mc->mc_authz_target, LDAP_BACK_DONTSEND ); - } else { /* can't do anything about it */ @@ -685,7 +679,7 @@ meta_back_dobind( rootdn = mi->mi_targets[ i ].mt_pseudorootdn.bv_val; - rc = meta_back_single_bind( &op2, rs, mc, i ); + rc = meta_back_single_bind( &op2, rs, mc, i, 0 ); } else { rc = meta_back_single_dobind( op, rs, mc, i, diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 078d2ee0c6..58cba85096 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -163,7 +163,7 @@ meta_back_db_config( mi->mi_targets[ i ].mt_flags = mi->flags; mi->mi_targets[ i ].mt_version = mi->mi_version; - for ( c = 0; c < META_OP_LAST; c++ ) { + for ( c = 0; c < LDAP_BACK_OP_LAST; c++ ) { mi->mi_targets[ i ].mt_timeout[ c ] = mi->mi_timeout[ c ]; } @@ -619,13 +619,13 @@ meta_back_db_config( size_t len = sep - argv[ c ]; if ( strncasecmp( argv[ c ], "add", len ) == 0 ) { - t = &tv[ META_OP_ADD ]; + t = &tv[ LDAP_BACK_OP_ADD ]; } else if ( strncasecmp( argv[ c ], "delete", len ) == 0 ) { - t = &tv[ META_OP_DELETE ]; + t = &tv[ LDAP_BACK_OP_DELETE ]; } else if ( strncasecmp( argv[ c ], "modify", len ) == 0 ) { - t = &tv[ META_OP_MODIFY ]; + t = &tv[ LDAP_BACK_OP_MODIFY ]; } else if ( strncasecmp( argv[ c ], "modrdn", len ) == 0 ) { - t = &tv[ META_OP_MODRDN ]; + t = &tv[ LDAP_BACK_OP_MODRDN ]; } else { fprintf( stderr, "%s: line %d: unknown operation \"%s\" for timeout #%d.\n", @@ -652,7 +652,7 @@ meta_back_db_config( } else { int i; - for ( i = 0; i < META_OP_LAST; i++ ) { + for ( i = 0; i < LDAP_BACK_OP_LAST; i++ ) { tv[ i ] = val; } } diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index 8c341899d7..384e07b6f1 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -172,6 +172,7 @@ metaconn_alloc( mc->mc_authz_target = META_BOUND_NONE; ldap_pvt_thread_mutex_init( &mc->mc_mutex ); mc->mc_refcnt = 1; + mc->mc_tainted = 0; return mc; } @@ -447,6 +448,12 @@ retry_lock:; goto retry_lock; } + Debug( LDAP_DEBUG_ANY, + "%s meta_back_retry: retrying URI=\"%s\" DN=\"%s\"\n", + op->o_log_prefix, mt->mt_uri, + BER_BVISNULL( &msc->msc_bound_ndn ) ? + "" : msc->msc_bound_ndn.bv_val ); + meta_clear_one_candidate( msc ); LDAP_BACK_CONN_ISBOUND_CLEAR( msc ); @@ -465,6 +472,10 @@ retry_lock:; ldap_pvt_thread_mutex_unlock( &mc->mc_mutex ); } + if ( rc != LDAP_SUCCESS ) { + mc->mc_tainted = 1; + } + ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); return rc == LDAP_SUCCESS ? 1 : 0; @@ -720,6 +731,13 @@ meta_back_getconn( mc = (metaconn_t *)avl_find( mi->mi_conntree, (caddr_t)&mc_curr, meta_back_conn_cmp ); if ( mc ) { + if ( mc->mc_tainted ) { + rs->sr_err = LDAP_UNAVAILABLE; + rs->sr_text = "remote server unavailable"; + ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + return NULL; + } + mc->mc_refcnt++; } ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); @@ -1122,5 +1140,10 @@ meta_back_release_conn( ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); assert( mc->mc_refcnt > 0 ); mc->mc_refcnt--; + if ( mc->mc_refcnt == 0 && mc->mc_tainted ) { + (void)avl_delete( &mi->mi_conntree, ( caddr_t )mc, + meta_back_conn_cmp ); + meta_back_conn_free( mc ); + } ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); } diff --git a/servers/slapd/back-meta/delete.c b/servers/slapd/back-meta/delete.c index 7c1463d60f..42f77bf966 100644 --- a/servers/slapd/back-meta/delete.c +++ b/servers/slapd/back-meta/delete.c @@ -76,8 +76,8 @@ retry:; LDAPMessage *res = NULL; int rc; - if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_DELETE ] != 0 ) { - tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_DELETE ]; + if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_DELETE ] != 0 ) { + tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_DELETE ]; tv.tv_usec = 0; tvp = &tv; } diff --git a/servers/slapd/back-meta/modify.c b/servers/slapd/back-meta/modify.c index f6d2e9f428..9701257022 100644 --- a/servers/slapd/back-meta/modify.c +++ b/servers/slapd/back-meta/modify.c @@ -186,8 +186,8 @@ retry:; struct timeval tv, *tvp = NULL; LDAPMessage *res = NULL; - if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODIFY ] != 0 ) { - tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODIFY ]; + if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODIFY ] != 0 ) { + tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODIFY ]; tv.tv_usec = 0; tvp = &tv; } diff --git a/servers/slapd/back-meta/modrdn.c b/servers/slapd/back-meta/modrdn.c index 741571c32d..1c943b95d3 100644 --- a/servers/slapd/back-meta/modrdn.c +++ b/servers/slapd/back-meta/modrdn.c @@ -117,8 +117,8 @@ retry:; LDAPMessage *res = NULL; int rc; - if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODRDN ] != 0 ) { - tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODRDN ]; + if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODRDN ] != 0 ) { + tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODRDN ]; tv.tv_usec = 0; tvp = &tv; } diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index d621b43307..dbcab08c8b 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -43,7 +43,13 @@ meta_send_entry( int i, LDAPMessage *e ); -static int +typedef enum meta_search_candidate_t { + META_SEARCH_ERR = -1, + META_SEARCH_NOT_CANDIDATE, + META_SEARCH_CANDIDATE +} meta_search_candidate_t; + +static meta_search_candidate_t meta_back_search_start( Operation *op, SlapReply *rs, @@ -61,6 +67,7 @@ meta_back_search_start( struct berval mfilter = BER_BVNULL; char **mapped_attrs = NULL; int rc; + meta_search_candidate_t retcode; struct timeval tv, *tvp = NULL; /* should we check return values? */ @@ -105,7 +112,7 @@ meta_back_search_start( /* * this target is no longer candidate */ - return 0; + return META_SEARCH_NOT_CANDIDATE; } break; @@ -145,7 +152,7 @@ meta_back_search_start( /* * this target is no longer candidate */ - return 0; + return META_SEARCH_NOT_CANDIDATE; } } @@ -161,14 +168,14 @@ meta_back_search_start( rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "Operation not allowed"; send_ldap_result( op, rs ); - return -1; + return META_SEARCH_ERR; case REWRITE_REGEXEC_ERR: /* * this target is no longer candidate */ - return 0; + return META_SEARCH_NOT_CANDIDATE; } /* @@ -185,7 +192,7 @@ meta_back_search_start( /* * this target is no longer candidate */ - rc = 0; + retcode = META_SEARCH_NOT_CANDIDATE; goto done; } @@ -198,7 +205,7 @@ meta_back_search_start( /* * this target is no longer candidate */ - rc = 0; + retcode = META_SEARCH_NOT_CANDIDATE; goto done; } @@ -211,11 +218,11 @@ meta_back_search_start( op->o_ctrls, NULL, tvp, op->ors_slimit, &candidates[ candidate ].sr_msgid ); if ( rc == LDAP_SUCCESS ) { - rc = 1; + retcode = META_SEARCH_CANDIDATE; } else { candidates[ candidate ].sr_msgid = -1; - rc = 0; + retcode = META_SEARCH_NOT_CANDIDATE; } done:; @@ -229,7 +236,7 @@ done:; free( mbase.bv_val ); } - return rc; + return retcode; } int @@ -238,7 +245,7 @@ meta_back_search( Operation *op, SlapReply *rs ) metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; metaconn_t *mc; struct timeval tv = { 0, 0 }; - time_t stoptime; + time_t stoptime = (time_t)-1; LDAPMessage *res = NULL, *e; int rc = 0, sres = LDAP_SUCCESS; char *matched = NULL; @@ -284,14 +291,15 @@ meta_back_search( Operation *op, SlapReply *rs ) switch ( meta_back_search_start( op, rs, &dc, msc, i, candidates ) ) { - case 0: + case META_SEARCH_NOT_CANDIDATE: break; - case 1: + case META_SEARCH_CANDIDATE: + candidates[ i ].sr_type = REP_INTERMEDIATE; ++ncandidates; break; - case -1: + case META_SEARCH_ERR: rc = -1; goto finish; } @@ -386,6 +394,7 @@ meta_back_search( Operation *op, SlapReply *rs ) * get a LDAP_TIMELIMIT_EXCEEDED from * one of them ... */ +get_result:; rc = ldap_result( msc->msc_ld, candidates[ i ].sr_msgid, 0, &tv, &res ); @@ -411,21 +420,37 @@ meta_back_search( Operation *op, SlapReply *rs ) } else if ( rc == -1 ) { really_bad:; /* something REALLY bad happened! */ - ( void )meta_clear_unused_candidates( op, -1 ); - rs->sr_err = LDAP_OTHER; - savepriv = op->o_private; - op->o_private = (void *)i; - send_ldap_result( op, rs ); - op->o_private = savepriv; - - /* anything else needs be done? */ - - /* FIXME: res should not need to be freed */ - assert( res == NULL ); + if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { + candidates[ i ].sr_type = REP_RESULT; + + if ( meta_back_retry( op, rs, mc, i, LDAP_BACK_DONTSEND ) ) { + switch ( meta_back_search_start( op, rs, &dc, msc, i, candidates ) ) + { + case META_SEARCH_CANDIDATE: + goto get_result; + + default: + rc = rs->sr_err = LDAP_OTHER; + goto finish; + } + } + } - goto finish; + /* + * When no candidates are left, + * the outer cycle finishes + */ + candidates[ i ].sr_msgid = -1; + --ncandidates; + rs->sr_err = candidates[ i ].sr_err = LDAP_OTHER; + rs->sr_text = "remote server unavailable"; } else if ( rc == LDAP_RES_SEARCH_ENTRY ) { + if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { + /* don't retry any more... */ + candidates[ i ].sr_type = REP_RESULT; + } + if ( --op->ors_slimit == -1 ) { ldap_msgfree( res ); res = NULL; @@ -477,6 +502,11 @@ really_bad:; char **references = NULL; int cnt; + if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { + /* don't retry any more... */ + candidates[ i ].sr_type = REP_RESULT; + } + is_ok++; rc = ldap_parse_reference( msc->msc_ld, res, @@ -525,7 +555,7 @@ really_bad:; /* cleanup */ if ( references ) { - ldap_value_free( references ); + ber_memvfree( (void **)references ); } if ( rs->sr_ctrls ) { @@ -537,6 +567,11 @@ really_bad:; char buf[ SLAP_TEXT_BUFLEN ]; char **references = NULL; + if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { + /* don't retry any more... */ + candidates[ i ].sr_type = REP_RESULT; + } + if ( ldap_parse_result( msc->msc_ld, res, &candidates[ i ].sr_err, @@ -550,6 +585,7 @@ really_bad:; LDAP_OPT_ERROR_NUMBER, &rs->sr_err ); sres = slap_map_api2result( rs ); + candidates[ i ].sr_type = REP_RESULT; goto really_bad; } @@ -611,7 +647,7 @@ really_bad:; ( void )ldap_back_referral_result_rewrite( &dc, sr_ref ); /* cleanup */ - ldap_value_free( references ); + ber_memvfree( (void **)references ); if ( rs->sr_v2ref == NULL ) { rs->sr_v2ref = sr_ref; diff --git a/servers/slapd/back-monitor/operation.c b/servers/slapd/back-monitor/operation.c index f7aa7c6483..68a006362c 100644 --- a/servers/slapd/back-monitor/operation.c +++ b/servers/slapd/back-monitor/operation.c @@ -189,8 +189,8 @@ monitor_subsys_ops_update( { monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private; - ldap_pvt_mp_t nInitiated, - nCompleted; + ldap_pvt_mp_t nInitiated = LDAP_PVT_MP_INIT, + nCompleted = LDAP_PVT_MP_INIT; struct berval rdn; int i; Attribute *a; diff --git a/servers/slapd/back-passwd/search.c b/servers/slapd/back-passwd/search.c index 76386d756b..e12bdec44f 100644 --- a/servers/slapd/back-passwd/search.c +++ b/servers/slapd/back-passwd/search.c @@ -59,7 +59,7 @@ passwd_back_search( SlapReply *rs ) { struct passwd *pw; - time_t stoptime; + time_t stoptime = (time_t)-1; LDAPRDN rdn = NULL; struct berval parent = BER_BVNULL; @@ -324,10 +324,10 @@ pw2entry( Backend *be, struct passwd *pw, Entry *e ) ber_str2bv( pw->pw_gecos, 0, 0, &val ); attr_merge_normalize_one( e, ad_desc, &val, NULL ); - s = strchr( val.bv_val, ',' ); + s = ber_bvchr( &val, ',' ); if ( s ) *s = '\0'; - s = strchr( val.bv_val, '&' ); + s = ber_bvchr( &val, '&' ); if ( s ) { char buf[1024]; diff --git a/servers/slapd/back-sql/add.c b/servers/slapd/back-sql/add.c index 6656b774f3..15c3b9742a 100644 --- a/servers/slapd/back-sql/add.c +++ b/servers/slapd/back-sql/add.c @@ -930,6 +930,9 @@ backsql_add( Operation *op, SlapReply *rs ) int colnum; slap_mask_t mask; + char textbuf[ SLAP_TEXT_BUFLEN ]; + size_t textlen = sizeof( textbuf ); + #ifdef BACKSQL_SYNCPROV /* * NOTE: fake successful result to force contextCSN to be bumped up @@ -954,6 +957,8 @@ backsql_add( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n", op->ora_e->e_name.bv_val, 0, 0 ); + slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 ); + /* check schema */ if ( BACKSQL_CHECK_SCHEMA( bi ) ) { char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' }; @@ -1050,6 +1055,16 @@ backsql_add( Operation *op, SlapReply *rs ) goto done; } + /* check write access */ + if ( !access_allowed_mask( op, op->ora_e, + slap_schema.si_ad_entry, + NULL, ACL_WADD, NULL, &mask ) ) + { + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + e = op->ora_e; + goto done; + } + rs->sr_err = backsql_get_db_conn( op, &dbh ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " @@ -1063,7 +1078,7 @@ backsql_add( Operation *op, SlapReply *rs ) /* * Check if entry exists - * + * * NOTE: backsql_api_dn2odbc() is called explicitly because * we need the mucked DN to pass it to the create procedure. */ @@ -1096,34 +1111,34 @@ backsql_add( Operation *op, SlapReply *rs ) } else { dnParent( &op->ora_e->e_nname, &pdn ); - } - /* - * Get the parent - */ - bsi.bsi_e = &p; - rs->sr_err = backsql_init_search( &bsi, &pdn, - LDAP_SCOPE_BASE, - (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs, - ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) ); - if ( rs->sr_err != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, "backsql_add(): " - "could not retrieve addDN parent " - "\"%s\" ID - %s matched=\"%s\"\n", - pdn.bv_val, - rs->sr_err == LDAP_REFERRAL ? "referral" : "no such entry", - rs->sr_matched ? rs->sr_matched : "(null)" ); - e = &p; - goto done; - } + /* + * Get the parent + */ + bsi.bsi_e = &p; + rs->sr_err = backsql_init_search( &bsi, &pdn, + LDAP_SCOPE_BASE, + (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs, + ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) ); + if ( rs->sr_err != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, "backsql_add(): " + "could not retrieve addDN parent " + "\"%s\" ID - %s matched=\"%s\"\n", + pdn.bv_val, + rs->sr_err == LDAP_REFERRAL ? "referral" : "no such entry", + rs->sr_matched ? rs->sr_matched : "(null)" ); + e = &p; + goto done; + } - /* check "children" pseudo-attribute access to parent */ - if ( !access_allowed( op, &p, slap_schema.si_ad_children, - NULL, ACL_WADD, NULL ) ) - { - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - e = &p; - goto done; + /* check "children" pseudo-attribute access to parent */ + if ( !access_allowed( op, &p, slap_schema.si_ad_children, + NULL, ACL_WADD, NULL ) ) + { + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + e = &p; + goto done; + } } if ( get_assert( op ) && @@ -1135,15 +1150,6 @@ backsql_add( Operation *op, SlapReply *rs ) goto done; } - if ( !access_allowed_mask( op, op->ora_e, - slap_schema.si_ad_entry, - NULL, ACL_WADD, NULL, &mask ) ) - { - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - e = op->ora_e; - goto done; - } - /* * create_proc is executed; if expect_return is set, then * an output parameter is bound, which should contain diff --git a/servers/slapd/back-sql/delete.c b/servers/slapd/back-sql/delete.c index 1f059c2895..0ee1ec2ecd 100644 --- a/servers/slapd/back-sql/delete.c +++ b/servers/slapd/back-sql/delete.c @@ -217,34 +217,38 @@ backsql_delete( Operation *op, SlapReply *rs ) /* * Get the parent */ - dnParent( &op->o_req_ndn, &pdn ); - bsi.bsi_e = &p; e_id = bsi.bsi_base_id; - rs->sr_err = backsql_init_search( &bsi, &pdn, - LDAP_SCOPE_BASE, - (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs, - BACKSQL_ISF_GET_ENTRY ); - if ( rs->sr_err != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, "backsql_delete(): " - "could not retrieve deleteDN ID - no such entry\n", - 0, 0, 0 ); - e = &p; - goto done; - } + if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) { + dnParent( &op->o_req_ndn, &pdn ); + bsi.bsi_e = &p; + rs->sr_err = backsql_init_search( &bsi, &pdn, + LDAP_SCOPE_BASE, + (time_t)(-1), NULL, dbh, op, rs, + slap_anlist_no_attrs, + BACKSQL_ISF_GET_ENTRY ); + if ( rs->sr_err != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, "backsql_delete(): " + "could not retrieve deleteDN ID " + "- no such entry\n", + 0, 0, 0 ); + e = &p; + goto done; + } - (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); + (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); - /* check parent for "children" acl */ - if ( !access_allowed( op, &p, slap_schema.si_ad_children, - NULL, ACL_WDEL, NULL ) ) - { - Debug( LDAP_DEBUG_TRACE, " backsql_delete(): " - "no write access to parent\n", - 0, 0, 0 ); - rs->sr_err = LDAP_INSUFFICIENT_ACCESS; - e = &p; - goto done; + /* check parent for "children" acl */ + if ( !access_allowed( op, &p, slap_schema.si_ad_children, + NULL, ACL_WDEL, NULL ) ) + { + Debug( LDAP_DEBUG_TRACE, " backsql_delete(): " + "no write access to parent\n", + 0, 0, 0 ); + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + e = &p; + goto done; + } } /* avl_apply ... */ diff --git a/servers/slapd/back-sql/entry-id.c b/servers/slapd/back-sql/entry-id.c index 74035025d0..d0aafa1645 100644 --- a/servers/slapd/back-sql/entry-id.c +++ b/servers/slapd/back-sql/entry-id.c @@ -460,10 +460,10 @@ backsql_get_attr_vals( void *v_at, void *v_bsi ) oldcount = 0, res = 0; #ifdef BACKSQL_COUNTQUERY - unsigned long count, - countsize = sizeof( count ), + unsigned count, j, append = 0; + SQLLEN countsize = sizeof( count ); Attribute *attr = NULL; slap_mr_normalize_func *normfunc = NULL; diff --git a/servers/slapd/back-sql/init.c b/servers/slapd/back-sql/init.c index 40a4478c1f..48396c9753 100644 --- a/servers/slapd/back-sql/init.c +++ b/servers/slapd/back-sql/init.c @@ -335,7 +335,7 @@ backsql_db_open( * UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%',?)) */ - backsql_strfcat( &bb, "blbbb", + backsql_strfcat_x( &bb, NULL, "blbbb", &bi->sql_upper_func, (ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE " ), "(ldap_entries.dn) LIKE ", @@ -349,7 +349,7 @@ backsql_db_open( * ldap_entries.dn LIKE CONCAT('%',?) */ - backsql_strfcat( &bb, "lb", + backsql_strfcat_x( &bb, NULL, "lb", (ber_len_t)STRLENOF( "ldap_entries.dn LIKE " ), "ldap_entries.dn LIKE ", &concat ); @@ -373,7 +373,7 @@ backsql_db_open( * UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%,',?)) */ - backsql_strfcat( &bb, "blbl", + backsql_strfcat_x( &bb, NULL, "blbl", &bi->sql_upper_func, (ber_len_t)STRLENOF( "(ldap_entries.dn)=" ), "(ldap_entries.dn)=", @@ -386,7 +386,7 @@ backsql_db_open( * ldap_entries.dn LIKE CONCAT('%,',?) */ - backsql_strfcat( &bb, "l", + backsql_strfcat_x( &bb, NULL, "l", (ber_len_t)STRLENOF( "ldap_entries.dn=?" ), "ldap_entries.dn=?"); } @@ -497,20 +497,20 @@ backsql_db_open( if ( bi->sql_id_query == NULL ) { /* no custom id_query provided */ if ( bi->sql_upper_func.bv_val == NULL ) { - backsql_strcat( &bb, backsql_id_query, "dn=?", NULL ); + backsql_strcat_x( &bb, NULL, backsql_id_query, "dn=?", NULL ); } else { if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) { - backsql_strcat( &bb, backsql_id_query, + backsql_strcat_x( &bb, NULL, backsql_id_query, "dn_ru=?", NULL ); } else { if ( BACKSQL_USE_REVERSE_DN( bi ) ) { - backsql_strfcat( &bb, "sbl", + backsql_strfcat_x( &bb, NULL, "sbl", backsql_id_query, &bi->sql_upper_func, (ber_len_t)STRLENOF( "(dn)=?" ), "(dn)=?" ); } else { - backsql_strfcat( &bb, "sblbcb", + backsql_strfcat_x( &bb, NULL, "sblbcb", backsql_id_query, &bi->sql_upper_func, (ber_len_t)STRLENOF( "(dn)=" ), "(dn)=", @@ -528,7 +528,7 @@ backsql_db_open( */ BER_BVZERO( &bb.bb_val ); bb.bb_len = 0; - backsql_strfcat( &bb, "sbsb", + backsql_strfcat_x( &bb, NULL, "sbsb", "SELECT COUNT(distinct subordinates.id) " "FROM ldap_entries,ldap_entries ", &bi->sql_aliasing, "subordinates " @@ -541,7 +541,7 @@ backsql_db_open( */ BER_BVZERO( &bb.bb_val ); bb.bb_len = 0; - backsql_strfcat( &bb, "sbbsbsbbsb", + backsql_strfcat_x( &bb, NULL, "sbbsbsbbsb", " ", &bi->sql_aliasing, &bi->sql_aliasing_quote, "objectClass", &bi->sql_aliasing_quote, ",ldap_entries.dn ", &bi->sql_aliasing, diff --git a/servers/slapd/back-sql/modify.c b/servers/slapd/back-sql/modify.c index c9060f98eb..2977b3c8d6 100644 --- a/servers/slapd/back-sql/modify.c +++ b/servers/slapd/back-sql/modify.c @@ -122,6 +122,8 @@ backsql_modify( Operation *op, SlapReply *rs ) goto done; } + slap_mods_opattrs( op, op->orm_modlist, 1 ); + oc = backsql_id2oc( bi, bsi.bsi_base_id.eid_oc_id ); assert( oc != NULL ); diff --git a/servers/slapd/back-sql/operational.c b/servers/slapd/back-sql/operational.c index 1423e2156a..e99741a6d9 100644 --- a/servers/slapd/back-sql/operational.c +++ b/servers/slapd/back-sql/operational.c @@ -83,7 +83,7 @@ backsql_operational_entryCSN( Operation *op ) BER_BVZERO( &a->a_vals[ 1 ] ); #ifdef BACKSQL_SYNCPROV - if ( op->o_sync && op->o_tag == LDAP_REQ_SEARCH ) { + if ( op->o_sync && op->o_tag == LDAP_REQ_SEARCH && op->o_private != NULL ) { assert( op->o_private != NULL ); entryCSN = *((struct berval *)op->o_private); diff --git a/servers/slapd/back-sql/proto-sql.h b/servers/slapd/back-sql/proto-sql.h index 16a7ec6683..a427f205e4 100644 --- a/servers/slapd/back-sql/proto-sql.h +++ b/servers/slapd/back-sql/proto-sql.h @@ -242,8 +242,8 @@ extern char extern char backsql_check_dn_ru_query[]; -struct berbuf * backsql_strcat( struct berbuf *dest, ... ); -struct berbuf * backsql_strfcat( struct berbuf *dest, const char *fmt, ... ); +struct berbuf * backsql_strcat_x( struct berbuf *dest, void *memctx, ... ); +struct berbuf * backsql_strfcat_x( struct berbuf *dest, void *memctx, const char *fmt, ... ); int backsql_entry_addattr( Entry *e, AttributeDescription *ad, struct berval *at_val, void *memctx ); diff --git a/servers/slapd/back-sql/schema-map.c b/servers/slapd/back-sql/schema-map.c index ae97d27cf0..11056f039e 100644 --- a/servers/slapd/back-sql/schema-map.c +++ b/servers/slapd/back-sql/schema-map.c @@ -106,7 +106,7 @@ backsql_make_attr_query( { struct berbuf bb = BB_NULL; - backsql_strfcat( &bb, "lblbbbblblbcbl", + backsql_strfcat_x( &bb, NULL, "lblbbbblblbcbl", (ber_len_t)STRLENOF( "SELECT " ), "SELECT ", &at_map->bam_sel_expr, (ber_len_t)STRLENOF( " " ), " ", @@ -123,12 +123,12 @@ backsql_make_attr_query( (ber_len_t)STRLENOF( "=?" ), "=?" ); if ( !BER_BVISNULL( &at_map->bam_join_where ) ) { - backsql_strfcat( &bb, "lb", + backsql_strfcat_x( &bb, NULL, "lb", (ber_len_t)STRLENOF( " AND " ), " AND ", &at_map->bam_join_where ); } - backsql_strfcat( &bb, "lbbb", + backsql_strfcat_x( &bb, NULL, "lbbb", (ber_len_t)STRLENOF( " ORDER BY " ), " ORDER BY ", &bi->sql_aliasing_quote, &at_map->bam_ad->ad_cname, @@ -140,7 +140,7 @@ backsql_make_attr_query( /* Query to count how many rows will be returned. */ BER_BVZERO( &bb.bb_val ); bb.bb_len = 0; - backsql_strfcat( &bb, "lblbcbl", + backsql_strfcat_x( &bb, NULL, "lblbcbl", (ber_len_t)STRLENOF( "SELECT COUNT(*) FROM " ), "SELECT COUNT(*) FROM ", &at_map->bam_from_tbls, @@ -151,7 +151,7 @@ backsql_make_attr_query( (ber_len_t)STRLENOF( "=?" ), "=?" ); if ( !BER_BVISNULL( &at_map->bam_join_where ) ) { - backsql_strfcat( &bb, "lb", + backsql_strfcat_x( &bb, NULL, "lb", (ber_len_t)STRLENOF( " AND " ), " AND ", &at_map->bam_join_where ); } @@ -189,7 +189,7 @@ backsql_add_sysmaps( backsql_info *bi, backsql_oc_map_rec *oc_map ) BER_BVZERO( &bb.bb_val ); bb.bb_len = 0; - backsql_strfcat( &bb, "lbcblb", + backsql_strfcat_x( &bb, NULL, "lbcblb", (ber_len_t)STRLENOF( "ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entries.keyval=" ), "ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entries.keyval=", &oc_map->bom_keytbl, @@ -254,7 +254,7 @@ backsql_add_sysmaps( backsql_info *bi, backsql_oc_map_rec *oc_map ) ch_free( at_map->bam_join_where.bv_val ); BER_BVZERO( &bb.bb_val ); bb.bb_len = 0; - backsql_strfcat( &bb, "lbcblb", + backsql_strfcat_x( &bb, NULL, "lbcblb", (ber_len_t)STRLENOF( /* "ldap_entries.id=ldap_entry_objclasses.entry_id AND " */ "ldap_entries.keyval=" ), /* "ldap_entries.id=ldap_entry_objclasses.entry_id AND " */ "ldap_entries.keyval=", &oc_map->bom_keytbl, @@ -405,7 +405,7 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas ) { struct berbuf bb = BB_NULL; - backsql_strfcat( &bb, "bcbc", + backsql_strfcat_x( &bb, NULL, "bcbc", &bas->bas_bi->sql_upper_func, '(' /* ) */ , &at_map->bam_sel_expr, diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index 44b0617772..dcd349ffa7 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -345,7 +345,8 @@ backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op ) return 0; } - backsql_strfcat( &bsi->bsi_flt_where, "c", '(' /* ) */ ); + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, "c", '(' /* ) */ ); while ( 1 ) { res = backsql_process_filter( bsi, f ); @@ -364,20 +365,23 @@ backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op ) switch ( op ) { case LDAP_FILTER_AND: - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, "l", (ber_len_t)STRLENOF( " AND " ), " AND " ); break; case LDAP_FILTER_OR: - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, "l", (ber_len_t)STRLENOF( " OR " ), " OR " ); break; } } - backsql_strfcat( &bsi->bsi_flt_where, "c", /* ( */ ')' ); + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, "c", /* ( */ ')' ); return 1; } @@ -482,7 +486,8 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, * SQL filters are more liberal. */ - backsql_strfcat( &bsi->bsi_flt_where, "c", '(' /* ) */ ); + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, "c", '(' /* ) */ ); /* TimesTen */ Debug( LDAP_DEBUG_TRACE, "backsql_process_sub_filter(%s):\n", @@ -495,14 +500,17 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, * If a pre-upper-cased version of the column * or a precompiled upper function exists, use it */ - backsql_strfcat( &bsi->bsi_flt_where, + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, "bl", &at->bam_sel_expr_u, (ber_len_t)STRLENOF( " LIKE '" ), " LIKE '" ); } else { - backsql_strfcat( &bsi->bsi_flt_where, "bl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "bl", &at->bam_sel_expr, (ber_len_t)STRLENOF( " LIKE '" ), " LIKE '" ); } @@ -518,14 +526,18 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, #endif /* BACKSQL_TRACE */ start = bsi->bsi_flt_where.bb_val.bv_len; - backsql_strfcat( &bsi->bsi_flt_where, "b", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "b", &f->f_sub_initial ); if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } } - backsql_strfcat( &bsi->bsi_flt_where, "c", '%' ); + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "c", '%' ); if ( f->f_sub_any != NULL ) { for ( i = 0; !BER_BVISNULL( &f->f_sub_any[ i ] ); i++ ) { @@ -539,7 +551,8 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, #endif /* BACKSQL_TRACE */ start = bsi->bsi_flt_where.bb_val.bv_len; - backsql_strfcat( &bsi->bsi_flt_where, + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, "bc", &f->f_sub_any[ i ], '%' ); @@ -563,14 +576,18 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f, #endif /* BACKSQL_TRACE */ start = bsi->bsi_flt_where.bb_val.bv_len; - backsql_strfcat( &bsi->bsi_flt_where, "b", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "b", &f->f_sub_final ); if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } } - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); return 1; @@ -584,18 +601,21 @@ backsql_merge_from_tbls( backsql_srch_info *bsi, struct berval *from_tbls ) } if ( !BER_BVISNULL( &bsi->bsi_from.bb_val ) ) { - char *start, *end, *tmp; + char *start, *end; + struct berval tmp; - tmp = ch_strdup( from_tbls->bv_val ); + ber_dupbv_x( &tmp, from_tbls, bsi->bsi_op->o_tmpmemctx ); - for ( start = tmp, end = strchr( start, ',' ); start; ) { + for ( start = tmp.bv_val, end = strchr( start, ',' ); start; ) { if ( end ) { end[0] = '\0'; } if ( strstr( bsi->bsi_from.bb_val.bv_val, start) == NULL ) { - backsql_strfcat( &bsi->bsi_from, "cs", ',', start ); + backsql_strfcat_x( &bsi->bsi_from, + bsi->bsi_op->o_tmpmemctx, + "cs", ',', start ); } if ( end ) { @@ -611,10 +631,12 @@ backsql_merge_from_tbls( backsql_srch_info *bsi, struct berval *from_tbls ) } } - ch_free( tmp ); + bsi->bsi_op->o_tmpfree( tmp.bv_val, bsi->bsi_op->o_tmpmemctx ); } else { - backsql_strfcat( &bsi->bsi_from, "b", from_tbls ); + backsql_strfcat_x( &bsi->bsi_from, + bsi->bsi_op->o_tmpmemctx, + "b", from_tbls ); } return LDAP_SUCCESS; @@ -651,11 +673,15 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) break; case LDAP_FILTER_NOT: - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "NOT (" /* ) */ ), "NOT (" /* ) */ ); rc = backsql_process_filter( bsi, f->f_not ); - backsql_strfcat( &bsi->bsi_flt_where, "c", /* ( */ ')' ); + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "c", /* ( */ ')' ); done = 1; break; @@ -674,7 +700,9 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) * ldap_entries AS attributeName WHERE attributeName.dn * like '%attributeName=value%'" */ - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "1=1" ), "1=1" ); bsi->bsi_status = LDAP_SUCCESS; rc = 1; @@ -734,7 +762,9 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) backsql_merge_from_tbls( bsi, &ldap_entry_objclasses ); - backsql_strfcat( &bsi->bsi_flt_where, "lbl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "lbl", (ber_len_t)STRLENOF( "(2=2 OR (ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ')) */ ), "(2=2 OR (ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ')) */, &bsi->bsi_oc->bom_oc->soc_cname, @@ -749,7 +779,9 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) } case LDAP_FILTER_PRESENT: - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "3=3" ), "3=3" ); bsi->bsi_status = LDAP_SUCCESS; rc = 1; @@ -788,21 +820,27 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) } #ifdef BACKSQL_ARBITRARY_KEY - backsql_strfcat( &bsi->bsi_flt_where, "bcblbc", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "bcblbc", &bsi->bsi_oc->bom_keytbl, '.', &bsi->bsi_oc->bom_keycol, STRLENOF( " LIKE '" ), " LIKE '", &keyval, '\'' ); #else /* ! BACKSQL_ARBITRARY_KEY */ snprintf( keyvalbuf, sizeof( keyvalbuf ), "%lu", keyval ); - backsql_strfcat( &bsi->bsi_flt_where, "bcbcs", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "bcbcs", &bsi->bsi_oc->bom_keytbl, '.', &bsi->bsi_oc->bom_keycol, '=', keyvalbuf ); #endif /* ! BACKSQL_ARBITRARY_KEY */ break; case LDAP_FILTER_PRESENT: - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "4=4" ), "4=4" ); break; @@ -820,18 +858,22 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) /* * support for syncrepl as producer... */ +#if 0 if ( !bsi->bsi_op->o_sync ) { /* unsupported at present... */ bsi->bsi_status = LDAP_OTHER; rc = -1; goto done; } +#endif bsi->bsi_flags |= ( BSQL_SF_FILTER_ENTRYCSN | BSQL_SF_RETURN_ENTRYUUID); /* if doing a syncrepl, try to return as much as possible, * and always match the filter */ - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "5=5" ), "5=5" ); /* save for later use in operational attributes */ @@ -865,7 +907,9 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) * selecting if there are descendants of the * candidate. */ - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "6=6" ), "6=6" ); if ( ad == slap_schema.si_ad_hasSubordinates ) { /* @@ -898,7 +942,9 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) if ( vat == NULL ) { /* search anyway; other parts of the filter * may succeeed */ - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "7=7" ), "7=7" ); bsi->bsi_status = LDAP_SUCCESS; rc = 1; @@ -908,7 +954,9 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f ) /* if required, open extra level of parens */ done = 0; if ( vat[0]->bam_next || vat[1] ) { - backsql_strfcat( &bsi->bsi_flt_where, "c", '(' ); + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "c", '(' ); done = 1; } @@ -921,7 +969,9 @@ next:; /* if more definitions of the same attr, apply */ if ( vat[i]->bam_next ) { - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "l", STRLENOF( " OR " ), " OR " ); vat[i] = vat[i]->bam_next; goto next; @@ -930,14 +980,18 @@ next:; /* if more descendants of the same attr, apply */ i++; if ( vat[i] ) { - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "l", STRLENOF( " OR " ), " OR " ); goto next; } /* if needed, close extra level of parens */ if ( done ) { - backsql_strfcat( &bsi->bsi_flt_where, "c", ')' ); + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "c", ')' ); } rc = 1; @@ -967,7 +1021,9 @@ backsql_process_filter_eq( backsql_srch_info *bsi, backsql_at_map_rec *at, if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { ber_len_t start; - backsql_strfcat( &bsi->bsi_flt_where, "cbl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "cbl", '(', /* ) */ &at->bam_sel_expr_u, (ber_len_t)STRLENOF( "='" ), @@ -975,7 +1031,9 @@ backsql_process_filter_eq( backsql_srch_info *bsi, backsql_at_map_rec *at, start = bsi->bsi_flt_where.bb_val.bv_len; - backsql_strfcat( &bsi->bsi_flt_where, "bl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "bl", filter_value, (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); @@ -983,7 +1041,9 @@ backsql_process_filter_eq( backsql_srch_info *bsi, backsql_at_map_rec *at, ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } else { - backsql_strfcat( &bsi->bsi_flt_where, "cblbl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "cblbl", '(', /* ) */ &at->bam_sel_expr, (ber_len_t)STRLENOF( "='" ), "='", @@ -1008,7 +1068,9 @@ backsql_process_filter_like( backsql_srch_info *bsi, backsql_at_map_rec *at, if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { ber_len_t start; - backsql_strfcat( &bsi->bsi_flt_where, "cbl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "cbl", '(', /* ) */ &at->bam_sel_expr_u, (ber_len_t)STRLENOF( " LIKE '%" ), @@ -1016,7 +1078,9 @@ backsql_process_filter_like( backsql_srch_info *bsi, backsql_at_map_rec *at, start = bsi->bsi_flt_where.bb_val.bv_len; - backsql_strfcat( &bsi->bsi_flt_where, "bl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "bl", filter_value, (ber_len_t)STRLENOF( /* (' */ "%')" ), /* (' */ "%')" ); @@ -1024,7 +1088,9 @@ backsql_process_filter_like( backsql_srch_info *bsi, backsql_at_map_rec *at, ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } else { - backsql_strfcat( &bsi->bsi_flt_where, "cblbl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "cblbl", '(', /* ) */ &at->bam_sel_expr, (ber_len_t)STRLENOF( " LIKE '%" ), @@ -1061,7 +1127,9 @@ backsql_process_filter_attr( backsql_srch_info *bsi, Filter *f, backsql_at_map_r && strstr( bsi->bsi_join_where.bb_val.bv_val, at->bam_join_where.bv_val ) == NULL ) { - backsql_strfcat( &bsi->bsi_join_where, "lb", + backsql_strfcat_x( &bsi->bsi_join_where, + bsi->bsi_op->o_tmpmemctx, + "lb", (ber_len_t)STRLENOF( " AND " ), " AND ", &at->bam_join_where ); } @@ -1131,7 +1199,9 @@ equality_match:; if ( at->bam_ad == slap_schema.si_ad_objectClass || at->bam_ad == slap_schema.si_ad_structuralObjectClass ) { - backsql_strfcat( &bsi->bsi_flt_where, "lbl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "lbl", (ber_len_t)STRLENOF( "(ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ') */ ), "(ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ') */, filter_value, @@ -1173,7 +1243,9 @@ equality_match:; if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { ber_len_t start; - backsql_strfcat( &bsi->bsi_flt_where, "cbbc", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "cbbc", '(', /* ) */ &at->bam_sel_expr_u, &ordering, @@ -1181,7 +1253,9 @@ equality_match:; start = bsi->bsi_flt_where.bb_val.bv_len; - backsql_strfcat( &bsi->bsi_flt_where, "bl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "bl", filter_value, (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); @@ -1189,7 +1263,9 @@ equality_match:; ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } else { - backsql_strfcat( &bsi->bsi_flt_where, "cbbcbl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "cbbcbl", '(' /* ) */ , &at->bam_sel_expr, &ordering, @@ -1201,7 +1277,9 @@ equality_match:; break; case LDAP_FILTER_PRESENT: - backsql_strfcat( &bsi->bsi_flt_where, "lbl", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "lbl", (ber_len_t)STRLENOF( "NOT (" /* ) */), "NOT (", /* ) */ &at->bam_sel_expr, @@ -1228,7 +1306,9 @@ equality_match:; default: /* unhandled filter type; should not happen */ assert( 0 ); - backsql_strfcat( &bsi->bsi_flt_where, "l", + backsql_strfcat_x( &bsi->bsi_flt_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "8=8" ), "8=8" ); break; @@ -1262,7 +1342,9 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query ) BER_BVZERO( &bsi->bsi_flt_where.bb_val ); bsi->bsi_flt_where.bb_len = 0; - backsql_strfcat( &bsi->bsi_sel, "lbcbc", + backsql_strfcat_x( &bsi->bsi_sel, + bsi->bsi_op->o_tmpmemctx, + "lbcbc", (ber_len_t)STRLENOF( "SELECT DISTINCT ldap_entries.id," ), "SELECT DISTINCT ldap_entries.id,", &bsi->bsi_oc->bom_keytbl, @@ -1271,7 +1353,9 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query ) ',' ); if ( !BER_BVISNULL( &bi->sql_strcast_func ) ) { - backsql_strfcat( &bsi->bsi_sel, "blbl", + backsql_strfcat_x( &bsi->bsi_sel, + bsi->bsi_op->o_tmpmemctx, + "blbl", &bi->sql_strcast_func, (ber_len_t)STRLENOF( "('" /* ') */ ), "('" /* ') */ , @@ -1279,19 +1363,28 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query ) (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); } else { - backsql_strfcat( &bsi->bsi_sel, "cbc", + backsql_strfcat_x( &bsi->bsi_sel, + bsi->bsi_op->o_tmpmemctx, + "cbc", '\'', &bsi->bsi_oc->bom_oc->soc_cname, '\'' ); } - backsql_strfcat( &bsi->bsi_sel, "b", &bi->sql_dn_oc_aliasing ); - backsql_strfcat( &bsi->bsi_from, "lb", + backsql_strfcat_x( &bsi->bsi_sel, + bsi->bsi_op->o_tmpmemctx, + "b", + &bi->sql_dn_oc_aliasing ); + backsql_strfcat_x( &bsi->bsi_from, + bsi->bsi_op->o_tmpmemctx, + "lb", (ber_len_t)STRLENOF( " FROM ldap_entries," ), " FROM ldap_entries,", &bsi->bsi_oc->bom_keytbl ); - backsql_strfcat( &bsi->bsi_join_where, "lbcbl", + backsql_strfcat_x( &bsi->bsi_join_where, + bsi->bsi_op->o_tmpmemctx, + "lbcbl", (ber_len_t)STRLENOF( " WHERE " ), " WHERE ", &bsi->bsi_oc->bom_keytbl, '.', @@ -1302,12 +1395,16 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query ) switch ( bsi->bsi_scope ) { case LDAP_SCOPE_BASE: if ( BACKSQL_CANUPPERCASE( bi ) ) { - backsql_strfcat( &bsi->bsi_join_where, "bl", + backsql_strfcat_x( &bsi->bsi_join_where, + bsi->bsi_op->o_tmpmemctx, + "bl", &bi->sql_upper_func, (ber_len_t)STRLENOF( "(ldap_entries.dn)=?" ), "(ldap_entries.dn)=?" ); } else { - backsql_strfcat( &bsi->bsi_join_where, "l", + backsql_strfcat_x( &bsi->bsi_join_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "ldap_entries.dn=?" ), "ldap_entries.dn=?" ); } @@ -1315,19 +1412,25 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query ) case BACKSQL_SCOPE_BASE_LIKE: if ( BACKSQL_CANUPPERCASE( bi ) ) { - backsql_strfcat( &bsi->bsi_join_where, "bl", + backsql_strfcat_x( &bsi->bsi_join_where, + bsi->bsi_op->o_tmpmemctx, + "bl", &bi->sql_upper_func, (ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE ?" ), "(ldap_entries.dn) LIKE ?" ); } else { - backsql_strfcat( &bsi->bsi_join_where, "l", + backsql_strfcat_x( &bsi->bsi_join_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "ldap_entries.dn LIKE ?" ), "ldap_entries.dn LIKE ?" ); } break; case LDAP_SCOPE_ONELEVEL: - backsql_strfcat( &bsi->bsi_join_where, "l", + backsql_strfcat_x( &bsi->bsi_join_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "ldap_entries.parent=?" ), "ldap_entries.parent=?" ); break; @@ -1358,20 +1461,29 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query ) if ( bsi->bsi_use_subtree_shortcut ) { /* Skip the base DN filter, as every entry will match it */ - backsql_strfcat( &bsi->bsi_join_where, "l", + backsql_strfcat_x( &bsi->bsi_join_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "9=9"), "9=9"); } else if ( !BER_BVISNULL( &bi->sql_subtree_cond ) ) { - backsql_strfcat( &bsi->bsi_join_where, "b", &bi->sql_subtree_cond ); + backsql_strfcat_x( &bsi->bsi_join_where, + bsi->bsi_op->o_tmpmemctx, + "b", + &bi->sql_subtree_cond ); } else if ( BACKSQL_CANUPPERCASE( bi ) ) { - backsql_strfcat( &bsi->bsi_join_where, "bl", + backsql_strfcat_x( &bsi->bsi_join_where, + bsi->bsi_op->o_tmpmemctx, + "bl", &bi->sql_upper_func, (ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE ?" ), "(ldap_entries.dn) LIKE ?" ); } else { - backsql_strfcat( &bsi->bsi_join_where, "l", + backsql_strfcat_x( &bsi->bsi_join_where, + bsi->bsi_op->o_tmpmemctx, + "l", (ber_len_t)STRLENOF( "ldap_entries.dn LIKE ?" ), "ldap_entries.dn LIKE ?" ); } @@ -1386,7 +1498,9 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query ) if ( rc > 0 ) { struct berbuf bb = BB_NULL; - backsql_strfcat( &bb, "bbblb", + backsql_strfcat_x( &bb, + bsi->bsi_op->o_tmpmemctx, + "bbblb", &bsi->bsi_sel.bb_val, &bsi->bsi_from.bb_val, &bsi->bsi_join_where.bb_val, diff --git a/servers/slapd/back-sql/sql-wrap.c b/servers/slapd/back-sql/sql-wrap.c index aaa0a1ac64..e942a17d65 100644 --- a/servers/slapd/back-sql/sql-wrap.c +++ b/servers/slapd/back-sql/sql-wrap.c @@ -257,9 +257,10 @@ static void backsql_close_db_conn( void *v_conn ) { backsql_db_conn *conn = (backsql_db_conn *)v_conn; + unsigned long cid = conn->ldap_cid; Debug( LDAP_DEBUG_TRACE, "==>backsql_close_db_conn(%lu)\n", - conn->ldap_cid, 0, 0 ); + cid, 0, 0 ); /* * Default transact is SQL_ROLLBACK; commit is required only @@ -274,7 +275,7 @@ backsql_close_db_conn( void *v_conn ) ch_free( conn ); Debug( LDAP_DEBUG_TRACE, "<==backsql_close_db_conn(%lu)\n", - conn->ldap_cid, 0, 0 ); + cid, 0, 0 ); } int diff --git a/servers/slapd/back-sql/util.c b/servers/slapd/back-sql/util.c index eee55942e5..316f2bc5ee 100644 --- a/servers/slapd/back-sql/util.c +++ b/servers/slapd/back-sql/util.c @@ -65,7 +65,7 @@ char backsql_def_concat_func[] = "CONCAT(?,?)"; char backsql_check_dn_ru_query[] = "SELECT dn_ru FROM ldap_entries"; struct berbuf * -backsql_strcat( struct berbuf *dest, ... ) +backsql_strcat_x( struct berbuf *dest, void *memctx, ... ) { va_list strs; ber_len_t cdlen, cslen, grow; @@ -79,10 +79,9 @@ backsql_strcat( struct berbuf *dest, ... ) Debug( LDAP_DEBUG_TRACE, "==>backsql_strcat()\n", 0, 0, 0 ); #endif /* BACKSQL_TRACE */ - va_start( strs, dest ); + va_start( strs, memctx ); if ( dest->bb_val.bv_val == NULL || dest->bb_len == 0 ) { - dest->bb_val.bv_val = (char *)ch_calloc( BACKSQL_STR_GROW, - sizeof( char ) ); + dest->bb_val.bv_val = (char *)ber_memalloc_x( BACKSQL_STR_GROW * sizeof( char ), memctx ); dest->bb_val.bv_len = 0; dest->bb_len = BACKSQL_STR_GROW; } @@ -100,8 +99,8 @@ backsql_strcat( struct berbuf *dest, ... ) dest->bb_len, cdlen + 1, cslen ); #endif /* BACKSQL_TRACE */ - tmp_dest = (char *)ch_realloc( dest->bb_val.bv_val, - ( dest->bb_len ) + grow * sizeof( char ) ); + tmp_dest = (char *)ber_memrealloc_x( dest->bb_val.bv_val, + dest->bb_len + grow * sizeof( char ), memctx ); if ( tmp_dest == NULL ) { Debug( LDAP_DEBUG_ANY, "backsql_strcat(): " "could not reallocate string buffer.\n", @@ -133,7 +132,7 @@ backsql_strcat( struct berbuf *dest, ... ) } struct berbuf * -backsql_strfcat( struct berbuf *dest, const char *fmt, ... ) +backsql_strfcat_x( struct berbuf *dest, void *memctx, const char *fmt, ... ) { va_list strs; ber_len_t cdlen; @@ -150,8 +149,7 @@ backsql_strfcat( struct berbuf *dest, const char *fmt, ... ) va_start( strs, fmt ); if ( dest->bb_val.bv_val == NULL || dest->bb_len == 0 ) { - dest->bb_val.bv_val = (char *)ch_calloc( BACKSQL_STR_GROW, - sizeof( char ) ); + dest->bb_val.bv_val = (char *)ber_memalloc_x( BACKSQL_STR_GROW * sizeof( char ), memctx ); dest->bb_val.bv_len = 0; dest->bb_len = BACKSQL_STR_GROW; } @@ -208,8 +206,8 @@ backsql_strfcat( struct berbuf *dest, const char *fmt, ... ) dest->bb_len, cdlen + 1, cslen ); #endif /* BACKSQL_TRACE */ - tmp_dest = (char *)ch_realloc( dest->bb_val.bv_val, - ( dest->bb_len ) + grow * sizeof( char ) ); + tmp_dest = (char *)ber_memrealloc_x( dest->bb_val.bv_val, + ( dest->bb_len ) + grow * sizeof( char ), memctx ); if ( tmp_dest == NULL ) { Debug( LDAP_DEBUG_ANY, "backsql_strfcat(): " "could not reallocate string buffer.\n", @@ -302,7 +300,7 @@ backsql_get_table_spec( backsql_info *bi, char **p ) BACKSQL_NEXT_WORD; /* table name */ - backsql_strcat( &res, s, NULL ); + backsql_strcat_x( &res, NULL, s, NULL ); s = q; BACKSQL_NEXT_WORD; @@ -312,7 +310,7 @@ backsql_get_table_spec( backsql_info *bi, char **p ) } /* oracle doesn't understand "AS" :( and other RDBMSes don't need it */ - backsql_strfcat( &res, "lbbsb", + backsql_strfcat_x( &res, NULL, "lbbsb", STRLENOF( " " ), " ", &bi->sql_aliasing, &bi->sql_aliasing_quote, @@ -353,13 +351,13 @@ backsql_merge_from_clause( "p=\"%s\" s=\"%s\"\n", p, s, 0 ); #endif /* BACKSQL_TRACE */ - if ( res.bb_val.bv_val == NULL ) { - backsql_strcat( &res, s, NULL ); + if ( BER_BVISNULL( &res.bb_val ) ) { + backsql_strcat_x( &res, NULL, s, NULL ); } else { pos = strstr( res.bb_val.bv_val, s ); if ( pos == NULL || ( ( e = pos[ strlen( s ) ] ) != '\0' && e != ',' ) ) { - backsql_strfcat( &res, "cs", ',', s ); + backsql_strfcat_x( &res, NULL, "cs", ',', s ); } } @@ -464,8 +462,8 @@ backsql_prepare_pattern( ch_free( bb.bb_val.bv_val ); return -1; } - backsql_strfcat( &bb, "b", &split_pattern[ i ] ); - backsql_strfcat( &bb, "b", &values[ i ] ); + backsql_strfcat_x( &bb, NULL, "b", &split_pattern[ i ] ); + backsql_strfcat_x( &bb, NULL, "b", &values[ i ] ); } if ( split_pattern[ i ].bv_val == NULL ) { @@ -473,7 +471,7 @@ backsql_prepare_pattern( return -1; } - backsql_strfcat( &bb, "b", &split_pattern[ i ] ); + backsql_strfcat_x( &bb, NULL, "b", &split_pattern[ i ] ); *res = bb.bb_val; diff --git a/servers/slapd/backglue.c b/servers/slapd/backglue.c index 777a7272c5..99d88b0816 100644 --- a/servers/slapd/backglue.c +++ b/servers/slapd/backglue.c @@ -157,7 +157,7 @@ glue_op_func ( Operation *op, SlapReply *rs ) BackendDB *b0 = op->o_bd; BackendInfo *bi0 = op->o_bd->bd_info; BI_op_modify **func; - slap_operation_t which; + slap_operation_t which = op_bind; int rc; op->o_bd = glue_back_select (b0, &op->o_req_ndn); @@ -168,6 +168,7 @@ glue_op_func ( Operation *op, SlapReply *rs ) case LDAP_REQ_DELETE: which = op_delete; break; case LDAP_REQ_MODIFY: which = op_modify; break; case LDAP_REQ_MODRDN: which = op_modrdn; break; + default: assert( 0 ); break; } func = &op->o_bd->bd_info->bi_op_bind; diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 3544112261..a1545a1cb6 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -195,12 +195,25 @@ static OidRec OidMacros[] = { }; /* + * Backend/Database registry + * * OLcfg{Bk|Db}{Oc|At}:0 -> common * OLcfg{Bk|Db}{Oc|At}:1 -> bdb * OLcfg{Bk|Db}{Oc|At}:2 -> ldif * OLcfg{Bk|Db}{Oc|At}:3 -> ldap? */ +/* + * Overlay registry + * + * OLcfgOv{Oc|At}:1 -> syncprov + * OLcfgOv{Oc|At}:2 -> pcache + * OLcfgOv{Oc|At}:3 -> chain + * OLcfgOv{Oc|At}:4 -> accesslog + * OLcfgOv{Oc|At}:5 -> valsort + * OLcfgOv{Oc|At}:6 -> smbk5pwd (use a separate arc for contrib?) + */ + /* alphabetical ordering */ static ConfigTable config_back_cf_table[] = { @@ -1311,7 +1324,7 @@ config_generic(ConfigArgs *c) { /* quote all args but the first */ line = ldap_charray2str( c->argv, "\" \"" ); ber_str2bv( line, 0, 0, &bv ); - s = strchr( bv.bv_val, '"' ); + s = ber_bvchr( &bv, '"' ); assert( s != NULL ); /* move the trailing quote of argv[0] to the end */ AC_MEMCPY( s, s + 1, bv.bv_len - ( s - bv.bv_val ) ); @@ -2377,7 +2390,7 @@ replica_unparse( struct slap_replica_info *ri, int i, struct berval *bv ) static int config_replica(ConfigArgs *c) { int i, nr = -1; - char *replicahost, *replicauri; + char *replicahost = NULL, *replicauri = NULL; LDAPURLDesc *ludp; if (c->op == SLAP_CONFIG_EMIT) { @@ -2407,6 +2420,12 @@ config_replica(ConfigArgs *c) { if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) { ber_len_t len; + if ( replicauri ) { + snprintf( c->msg, sizeof( c->msg ), "<%s> replica host/URI already specified", c->argv[0] ); + Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri ); + return(1); + } + replicahost = c->argv[i] + STRLENOF("host="); len = strlen( replicahost ) + STRLENOF("ldap://"); replicauri = ch_malloc( len + 1 ); @@ -2415,6 +2434,12 @@ config_replica(ConfigArgs *c) { nr = add_replica_info(c->be, replicauri, replicahost); break; } else if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) { + if ( replicauri ) { + snprintf( c->msg, sizeof( c->msg ), "<%s> replica host/URI already specified", c->argv[0] ); + Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri ); + return(1); + } + if(ldap_url_parse(c->argv[i] + STRLENOF("uri="), &ludp) != LDAP_SUCCESS) { snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri", c->argv[0] ); Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 ); @@ -2442,7 +2467,8 @@ config_replica(ConfigArgs *c) { return(1); } else if(nr == -1) { 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 ); + Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, + replicauri ? replicauri : "" ); return(1); } else { for(i = 1; i < c->argc; i++) { @@ -2622,6 +2648,7 @@ config_tls_option(ConfigArgs *c) { default: Debug(LDAP_DEBUG_ANY, "%s: " "unknown tls_option <0x%x>\n", c->log, c->type, 0); + return 1; } if (c->op == SLAP_CONFIG_EMIT) { return ldap_pvt_tls_get_option( NULL, flag, &c->value_string ); @@ -2656,6 +2683,7 @@ config_tls_config(ConfigArgs *c) { Debug(LDAP_DEBUG_ANY, "%s: " "unknown tls_option <0x%x>\n", c->log, c->type, 0); + return 1; } if (c->op == SLAP_CONFIG_EMIT) { ldap_pvt_tls_get_option( NULL, flag, &c->value_int ); @@ -3120,7 +3148,7 @@ check_name_index( CfEntryInfo *parent, ConfigType ce_type, Entry *e, CfEntryInfo *ce; int index = -1, gotindex = 0, nsibs; int renumber = 0, tailindex = 0; - char *ptr1, *ptr2; + char *ptr1, *ptr2 = NULL; struct berval rdn; if ( renum ) *renum = 0; @@ -3134,7 +3162,7 @@ check_name_index( CfEntryInfo *parent, ConfigType ce_type, Entry *e, /* See if the rdn has an index already */ dnRdn( &e->e_name, &rdn ); - ptr1 = strchr( e->e_name.bv_val, '{' ); + ptr1 = ber_bvchr( &e->e_name, '{' ); if ( ptr1 && ptr1 - e->e_name.bv_val < rdn.bv_len ) { ptr2 = strchr( ptr1, '}' ); if (!ptr2 || ptr2 - e->e_name.bv_val > rdn.bv_len) @@ -3626,7 +3654,7 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs, switch (ml->sml_op) { case LDAP_MOD_DELETE: case LDAP_MOD_REPLACE: { - BerVarray vals = NULL, nvals; + BerVarray vals = NULL, nvals = NULL; int *idx = NULL; if ( ct && ( ct->arg_type & ARG_NO_DELETE )) { rc = LDAP_OTHER; @@ -3737,9 +3765,9 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs, switch (ml->sml_op) { case LDAP_MOD_DELETE: case LDAP_MOD_REPLACE: { - BerVarray vals = NULL, nvals; + BerVarray vals = NULL, nvals = NULL; Attribute *a; - delrec *d; + delrec *d = NULL; a = attr_find( e->e_attrs, ml->sml_desc ); diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c index aa5c58af0a..1c1d4db1f1 100644 --- a/servers/slapd/bind.c +++ b/servers/slapd/bind.c @@ -207,8 +207,6 @@ cleanup: op->o_conn->c_authtype = op->orb_method; } - op->o_conn->c_sasl_bindop = NULL; - if( !BER_BVISNULL( &op->o_req_dn ) ) { slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &op->o_req_dn ); @@ -275,56 +273,6 @@ fe_op_bind( Operation *op, SlapReply *rs ) rs->sr_err = slap_sasl_bind( op, rs ); - ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); - if( rs->sr_err == LDAP_SUCCESS ) { - ber_dupbv(&op->o_conn->c_dn, &op->orb_edn); - if( !BER_BVISEMPTY( &op->orb_edn ) ) { - /* edn is always normalized already */ - ber_dupbv( &op->o_conn->c_ndn, &op->o_conn->c_dn ); - } - op->o_tmpfree( op->orb_edn.bv_val, op->o_tmpmemctx ); - BER_BVZERO( &op->orb_edn ); - op->o_conn->c_authmech = op->o_conn->c_sasl_bind_mech; - BER_BVZERO( &op->o_conn->c_sasl_bind_mech ); - op->o_conn->c_sasl_bind_in_progress = 0; - - op->o_conn->c_sasl_ssf = op->orb_ssf; - if( op->orb_ssf > op->o_conn->c_ssf ) { - op->o_conn->c_ssf = op->orb_ssf; - } - - if( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) { - ber_len_t max = sockbuf_max_incoming_auth; - ber_sockbuf_ctrl( op->o_conn->c_sb, - LBER_SB_OPT_SET_MAX_INCOMING, &max ); - } - - /* log authorization identity */ - Statslog( LDAP_DEBUG_STATS, - "%s BIND dn=\"%s\" mech=%s ssf=%d\n", - op->o_log_prefix, - BER_BVISNULL( &op->o_conn->c_dn ) ? "" : op->o_conn->c_dn.bv_val, - op->o_conn->c_authmech.bv_val, op->orb_ssf, 0 ); - - Debug( LDAP_DEBUG_TRACE, - "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n", - op->o_conn->c_authmech.bv_val, - BER_BVISNULL( &op->o_conn->c_dn ) ? "" : op->o_conn->c_dn.bv_val, - op->orb_ssf ); - - } else if ( rs->sr_err == LDAP_SASL_BIND_IN_PROGRESS ) { - op->o_conn->c_sasl_bind_in_progress = 1; - - } else { - if ( !BER_BVISNULL( &op->o_conn->c_sasl_bind_mech ) ) { - free( op->o_conn->c_sasl_bind_mech.bv_val ); - BER_BVZERO( &op->o_conn->c_sasl_bind_mech ); - } - op->o_conn->c_sasl_bind_in_progress = 0; - } - - ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); - goto cleanup; } else { diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 26d20f5ee0..da85ee01ab 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -844,7 +844,7 @@ verbs_to_mask(int argc, char *argv[], slap_verbmasks *v, slap_mask_t *m) { int i, j; for(i = 1; i < argc; i++) { j = verb_to_mask(argv[i], v); - if(BER_BVISNULL(&v[j].word)) return(1); + if(BER_BVISNULL(&v[j].word)) return i; while (!v[j].mask) j--; *m |= v[j].mask; } @@ -991,15 +991,7 @@ static slap_verbmasks methkey[] = { { BER_BVNULL, 0 } }; -typedef struct cf_aux_table { - struct berval key; - int off; - char type; - char quote; - slap_verbmasks *aux; -} cf_aux_table; - -static cf_aux_table bindkey[] = { +static slap_cf_aux_table bindkey[] = { { BER_BVC("starttls="), offsetof(slap_bindconf, sb_tls), 'd', 0, tlskey }, { BER_BVC("bindmethod="), offsetof(slap_bindconf, sb_method), 'd', 0, methkey }, { BER_BVC("binddn="), offsetof(slap_bindconf, sb_binddn), 'b', 1, NULL }, @@ -1012,31 +1004,34 @@ static cf_aux_table bindkey[] = { { BER_BVNULL, 0, 0, 0, NULL } }; -int bindconf_parse( const char *word, slap_bindconf *bc ) { +int +slap_cf_aux_table_parse( const char *word, void *dst, slap_cf_aux_table *tab0, LDAP_CONST char *tabmsg ) +{ int rc = 0; - cf_aux_table *tab; + slap_cf_aux_table *tab; - for (tab = bindkey; !BER_BVISNULL(&tab->key); tab++) { + for (tab = tab0; !BER_BVISNULL(&tab->key); tab++ ) { if ( !strncasecmp( word, tab->key.bv_val, tab->key.bv_len )) { - char **cptr; + char **cptr, *next; int *iptr, j; + unsigned *uptr; struct berval *bptr; const char *val = word + tab->key.bv_len; switch ( tab->type ) { case 's': - cptr = (char **)((char *)bc + tab->off); + cptr = (char **)((char *)dst + tab->off); *cptr = ch_strdup( val ); break; case 'b': - bptr = (struct berval *)((char *)bc + tab->off); + bptr = (struct berval *)((char *)dst + tab->off); ber_str2bv( val, 0, 1, bptr ); break; case 'd': assert( tab->aux != NULL ); - iptr = (int *)((char *)bc + tab->off); + iptr = (int *)((char *)dst + tab->off); rc = 1; for ( j = 0; !BER_BVISNULL( &tab->aux[j].word ); j++ ) { @@ -1046,11 +1041,29 @@ int bindconf_parse( const char *word, slap_bindconf *bc ) { } } break; + + case 'i': + iptr = (int *)((char *)dst + tab->off); + + *iptr = strtol( val, &next, 0 ); + if ( next == val || next[ 0 ] != '\0' ) { + rc = 1; + } + break; + + case 'u': + uptr = (unsigned *)((char *)dst + tab->off); + + *uptr = strtoul( val, &next, 0 ); + if ( next == val || next[ 0 ] != '\0' ) { + rc = 1; + } + break; } if ( rc ) { - Debug( LDAP_DEBUG_ANY, "invalid bind config value %s\n", - word, 0, 0 ); + Debug( LDAP_DEBUG_ANY, "invalid %s value %s\n", + tabmsg, word, 0 ); } return rc; @@ -1060,22 +1073,25 @@ int bindconf_parse( const char *word, slap_bindconf *bc ) { return rc; } -int bindconf_unparse( slap_bindconf *bc, struct berval *bv ) { +int +slap_cf_aux_table_unparse( void *src, struct berval *bv, slap_cf_aux_table *tab0 ) +{ char buf[BUFSIZ], *ptr; - cf_aux_table *tab; + slap_cf_aux_table *tab; struct berval tmp; ptr = buf; - for (tab = bindkey; !BER_BVISNULL(&tab->key); tab++) { + for (tab = tab0; !BER_BVISNULL(&tab->key); tab++ ) { char **cptr; int *iptr, i; + unsigned *uptr; struct berval *bptr; - cptr = (char **)((char *)bc + tab->off); + cptr = (char **)((char *)src + tab->off); switch ( tab->type ) { case 'b': - bptr = (struct berval *)((char *)bc + tab->off); + bptr = (struct berval *)((char *)src + tab->off); cptr = &bptr->bv_val; case 's': if ( *cptr ) { @@ -1089,7 +1105,7 @@ int bindconf_unparse( slap_bindconf *bc, struct berval *bv ) { case 'd': assert( tab->aux != NULL ); - iptr = (int *)((char *)bc + tab->off); + iptr = (int *)((char *)src + tab->off); for ( i = 0; !BER_BVISNULL( &tab->aux[i].word ); i++ ) { if ( *iptr == tab->aux[i].mask ) { @@ -1100,6 +1116,20 @@ int bindconf_unparse( slap_bindconf *bc, struct berval *bv ) { } } break; + + case 'i': + iptr = (int *)((char *)src + tab->off); + *ptr++ = ' '; + ptr = lutil_strcopy( ptr, tab->key.bv_val ); + ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%d", *iptr ); + break; + + case 'u': + uptr = (unsigned *)((char *)src + tab->off); + *ptr++ = ' '; + ptr = lutil_strcopy( ptr, tab->key.bv_val ); + ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%u", *uptr ); + break; } } tmp.bv_val = buf; @@ -1108,6 +1138,18 @@ int bindconf_unparse( slap_bindconf *bc, struct berval *bv ) { return 0; } +int +bindconf_parse( const char *word, slap_bindconf *bc ) +{ + return slap_cf_aux_table_parse( word, bc, bindkey, "bind config" ); +} + +int +bindconf_unparse( slap_bindconf *bc, struct berval *bv ) +{ + return slap_cf_aux_table_unparse( bc, bv, bindkey ); +} + void bindconf_free( slap_bindconf *bc ) { if ( !BER_BVISNULL( &bc->sb_binddn ) ) { ch_free( bc->sb_binddn.bv_val ); diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index e3bd2f5d41..54bd488a9f 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -151,7 +151,7 @@ int connections_init(void) 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 ); + "allocation of connection mutexes failed\n", 0, 0, 0 ); return -1; } @@ -2004,6 +2004,54 @@ static int connection_bind_cb( Operation *op, SlapReply *rs ) ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); op->o_conn->c_conn_state = SLAP_C_ACTIVE; + op->o_conn->c_sasl_bind_in_progress = + ( rs->sr_err == LDAP_SASL_BIND_IN_PROGRESS ); + + /* Moved here from bind.c due to ITS#4158 */ + op->o_conn->c_sasl_bindop = NULL; + if ( op->orb_method == LDAP_AUTH_SASL ) { + if( rs->sr_err == LDAP_SUCCESS ) { + ber_dupbv(&op->o_conn->c_dn, &op->orb_edn); + if( !BER_BVISEMPTY( &op->orb_edn ) ) { + /* edn is always normalized already */ + ber_dupbv( &op->o_conn->c_ndn, &op->o_conn->c_dn ); + } + op->o_tmpfree( op->orb_edn.bv_val, op->o_tmpmemctx ); + BER_BVZERO( &op->orb_edn ); + op->o_conn->c_authmech = op->o_conn->c_sasl_bind_mech; + BER_BVZERO( &op->o_conn->c_sasl_bind_mech ); + + op->o_conn->c_sasl_ssf = op->orb_ssf; + if( op->orb_ssf > op->o_conn->c_ssf ) { + op->o_conn->c_ssf = op->orb_ssf; + } + + if( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) { + ber_len_t max = sockbuf_max_incoming_auth; + ber_sockbuf_ctrl( op->o_conn->c_sb, + LBER_SB_OPT_SET_MAX_INCOMING, &max ); + } + + /* log authorization identity */ + Statslog( LDAP_DEBUG_STATS, + "%s BIND dn=\"%s\" mech=%s ssf=%d\n", + op->o_log_prefix, + BER_BVISNULL( &op->o_conn->c_dn ) ? "" : op->o_conn->c_dn.bv_val, + op->o_conn->c_authmech.bv_val, op->orb_ssf, 0 ); + + Debug( LDAP_DEBUG_TRACE, + "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n", + op->o_conn->c_authmech.bv_val, + BER_BVISNULL( &op->o_conn->c_dn ) ? "" : op->o_conn->c_dn.bv_val, + op->orb_ssf ); + + } else if ( rs->sr_err != LDAP_SASL_BIND_IN_PROGRESS ) { + if ( !BER_BVISNULL( &op->o_conn->c_sasl_bind_mech ) ) { + free( op->o_conn->c_sasl_bind_mech.bv_val ); + BER_BVZERO( &op->o_conn->c_sasl_bind_mech ); + } + } + } ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); ch_free( cb ); diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 49007b612d..9d1df57a12 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -81,10 +81,9 @@ Listener **slap_listeners = NULL; static ber_socket_t wake_sds[2]; static int emfile; -static int waking; +static volatile int waking; #define WAKE_LISTENER(w) do { \ - if ((w) && waking < 5) { \ - waking++; \ + if ((w) && ++waking < 5) { \ tcp_write( wake_sds[1], "0", 1 ); \ } \ } while(0) @@ -283,7 +282,7 @@ static struct slap_daemon { if (!SLAP_SOCK_IS_WRITE(fd)) { FD_SET((fd), &slap_daemon.sd_writers); } \ } while(0) -# define SLAP_ADDTEST(s) do { } 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) @@ -1679,7 +1678,7 @@ slapd_daemon_task( } #ifdef HAVE_NT_SERVICE_MANAGER - if ( started_event != NULL ) } + if ( started_event != NULL ) { ldap_pvt_thread_cond_signal( &started_event ); } #endif @@ -1887,14 +1886,11 @@ slapd_daemon_task( #if SLAP_EVENTS_ARE_INDEXED if ( SLAP_EVENT_IS_READ( wake_sds[0] )) { + char c[BUFSIZ]; 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; + tcp_read( wake_sds[0], c, sizeof(c) ); + Debug( LDAP_DEBUG_CONNS, "daemon: waked\n", 0, 0, 0 ); continue; } @@ -2103,8 +2099,8 @@ slapd_daemon_task( /* Handle wake events */ if ( fd == wake_sds[0] ) { char c[BUFSIZ]; - tcp_read( wake_sds[0], c, sizeof(c) ); waking = 0; + tcp_read( wake_sds[0], c, sizeof(c) ); break; } diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c index 05832ecd97..0f4c1e9396 100644 --- a/servers/slapd/dn.c +++ b/servers/slapd/dn.c @@ -1129,7 +1129,7 @@ dnParent( { char *p; - p = strchr( dn->bv_val, ',' ); + p = ber_bvchr( dn, ',' ); /* one-level dn */ if ( p == NULL ) { @@ -1161,7 +1161,7 @@ dnRdn( char *p; *rdn = *dn; - p = strchr( dn->bv_val, ',' ); + p = ber_bvchr( dn, ',' ); /* one-level dn */ if ( p == NULL ) { @@ -1228,7 +1228,7 @@ dn_rdnlen( return 0; } - p = strchr( dn_in->bv_val, ',' ); + p = ber_bvchr( dn_in, ',' ); return p ? p - dn_in->bv_val : dn_in->bv_len; } @@ -1252,7 +1252,7 @@ rdn_validate( struct berval *rdn ) { return LDAP_INVALID_SYNTAX; } - return strchr( rdn->bv_val, ',' ) == NULL + return ber_bvchr( rdn, ',' ) == NULL ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX; #else diff --git a/servers/slapd/extended.c b/servers/slapd/extended.c index 894de43f52..443ea4eaaa 100644 --- a/servers/slapd/extended.c +++ b/servers/slapd/extended.c @@ -193,8 +193,8 @@ fe_extended( Operation *op, SlapReply *rs ) reqdata = *op->ore_reqdata; } - if( !(ext = find_extop(supp_ext_list, &op->ore_reqoid ))) - { + ext = find_extop(supp_ext_list, &op->ore_reqoid ); + if ( ext == NULL ) { Statslog( LDAP_DEBUG_STATS, "%s EXT oid=%s\n", op->o_log_prefix, op->ore_reqoid.bv_val, 0, 0, 0 ); Debug( LDAP_DEBUG_ANY, "do_extended: unsupported operation \"%s\"\n", @@ -210,6 +210,8 @@ fe_extended( Operation *op, SlapReply *rs ) op->ore_reqoid.bv_val, 0 ,0 ); { /* start of OpenLDAP extended operation */ + BackendDB *bd = op->o_bd; + rs->sr_err = (ext->ext_main)( op, rs ); if( rs->sr_err != SLAPD_ABANDON ) { @@ -224,7 +226,7 @@ fe_extended( Operation *op, SlapReply *rs ) } if ( op->o_bd == NULL ) - op->o_bd = frontendDB; + op->o_bd = bd; send_ldap_extended( op, rs ); if ( rs->sr_ref != default_referral ) { diff --git a/servers/slapd/filterentry.c b/servers/slapd/filterentry.c index 34b8bc784f..b0e5a595d7 100644 --- a/servers/slapd/filterentry.c +++ b/servers/slapd/filterentry.c @@ -158,7 +158,7 @@ static int test_mra_filter( void *memctx; BER_MEMFREE_FN *memfree; #ifdef LDAP_COMP_MATCH - int i, num_attr_vals; + int i, num_attr_vals = 0; #endif if ( op == NULL ) { diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c index 72022c24fa..e203781191 100644 --- a/servers/slapd/ldapsync.c +++ b/servers/slapd/ldapsync.c @@ -97,20 +97,26 @@ slap_parse_sync_cookie( int valid = 0; char *rid_ptr; char *cval; + char *next; if ( cookie == NULL ) return -1; + if ( cookie->octet_str.bv_len <= STRLENOF( "rid=" ) ) + return -1; + cookie->rid = -1; - if (( rid_ptr = strstr( cookie->octet_str.bv_val, "rid=" )) != NULL ) { - if ( (cval = strchr( rid_ptr, ',' )) != NULL ) { - *cval = '\0'; - } - cookie->rid = atoi( rid_ptr + sizeof("rid=") - 1 ); - if ( cval != NULL ) { - *cval = ','; - } - } else { + /* FIXME: may read past end of cookie->octet_str.bv_val */ + rid_ptr = strstr( cookie->octet_str.bv_val, "rid=" ); + if ( rid_ptr == NULL + || rid_ptr > &cookie->octet_str.bv_val[ cookie->octet_str.bv_len - STRLENOF( "rid=" ) ] ) + { + return -1; + + } + + cookie->rid = strtoul( &rid_ptr[ STRLENOF( "rid=" ) ], &next, 10 ); + if ( next == &rid_ptr[ STRLENOF( "rid=" ) ] || ( next[ 0 ] != ',' && next[ 0 ] != '\0' ) ) { return -1; } @@ -123,16 +129,20 @@ slap_parse_sync_cookie( if ( ad == NULL ) break; + if ( csn_ptr >= &cookie->octet_str.bv_val[ cookie->octet_str.bv_len - STRLENOF( "csn=" ) ] ) { + return -1; + } + csn_str = csn_ptr + STRLENOF("csn="); cval = strchr( csn_str, ',' ); - if ( cval ) + if ( cval && cval < &cookie->octet_str.bv_val[ cookie->octet_str.bv_len ] ) csn_str_len = cval - csn_str; else csn_str_len = 0; /* FIXME use csnValidate when it gets implemented */ csn_ptr = strchr( csn_str, '#' ); - if ( !csn_ptr ) break; + if ( !csn_ptr || csn_str >= &cookie->octet_str.bv_val[ cookie->octet_str.bv_len ] ) break; stamp.bv_val = csn_str; stamp.bv_len = csn_ptr - csn_str; diff --git a/servers/slapd/main.c b/servers/slapd/main.c index b32e60e4d2..f74bc4f231 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -668,7 +668,7 @@ unhandled_option:; /* Force new ctx to be created */ ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_CTX, NULL ); - rc = ldap_pvt_tls_init_def_ctx(); + rc = ldap_pvt_tls_init_def_ctx( 1 ); if( rc == 0 ) { ldap_pvt_tls_get_option( NULL, LDAP_OPT_X_TLS_CTX, &slap_tls_ctx ); /* Restore previous ctx */ diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 4f90671ec3..c9c594474f 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -220,7 +220,7 @@ fe_op_modify( Operation *op, SlapReply *rs ) char textbuf[ SLAP_TEXT_BUFLEN ]; size_t textlen = sizeof( textbuf ); - if( op->o_req_ndn.bv_len == 0 ) { + if( BER_BVISEMPTY( &op->o_req_ndn ) ) { Debug( LDAP_DEBUG_ANY, "do_modify: root dse!\n", 0, 0, 0 ); send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, @@ -650,7 +650,7 @@ int slap_mods_check( * check that each value is valid per syntax * and pretty if appropriate */ - for ( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) { + for ( nvals = 0; !BER_BVISNULL( &ml->sml_values[nvals] ); nvals++ ) { struct berval pval; if ( pretty ) { @@ -713,7 +713,7 @@ int slap_mods_check( ml->sml_nvalues = ber_memalloc_x( (nvals+1)*sizeof(struct berval), ctx ); - for ( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) { + for ( nvals = 0; !BER_BVISNULL( &ml->sml_values[nvals] ); nvals++ ) { #ifdef SLAP_ORDERED_PRETTYNORM rc = ordered_value_normalize( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, @@ -829,8 +829,8 @@ void slap_mods_opattrs( } else { csn = op->o_csn; } - ptr = strchr( csn.bv_val, '#' ); - if ( ptr ) { + ptr = ber_bvchr( &csn, '#' ); + if ( ptr && ptr < &csn.bv_val[csn.bv_len] ) { timestamp.bv_len = ptr - csn.bv_val; if ( timestamp.bv_len >= sizeof( timebuf )) timestamp.bv_len = sizeof( timebuf ) - 1; diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c index e543a48575..93d93c4c58 100644 --- a/servers/slapd/overlays/ppolicy.c +++ b/servers/slapd/overlays/ppolicy.c @@ -1155,10 +1155,11 @@ ppolicy_modify( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; pp_info *pi = on->on_bi.bi_private; - int i, rc, mod_pw_only, pwmod, pwmop, deladd, + int i, rc, mod_pw_only, pwmod, pwmop = -1, deladd, hsize = 0; PassPolicy pp; - Modifications *mods = NULL, *modtail, *ml, *delmod, *addmod; + Modifications *mods = NULL, *modtail = NULL, + *ml, *delmod, *addmod; Attribute *pa, *ha, at; const char *txt; pw_hist *tl = NULL, *p; @@ -1186,8 +1187,7 @@ ppolicy_modify( Operation *op, SlapReply *rs ) 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 ) { + for( prev = &op->oq_modify.rs_modlist, ml = *prev; ml; ml = *prev ) { if ( ml->sml_desc == slap_schema.si_ad_userPassword ) got_pw = 1; @@ -1217,8 +1217,10 @@ ppolicy_modify( Operation *op, SlapReply *rs ) *prev = ml->sml_next; ml->sml_next = NULL; slap_mods_free( ml, 1 ); + continue; } } + prev = &ml->sml_next; } /* If we're resetting the password, make sure grace, accountlock, @@ -1289,12 +1291,13 @@ ppolicy_modify( Operation *op, SlapReply *rs ) ppolicy_get( op, e, &pp ); - for(ml = op->oq_modify.rs_modlist, + for ( ml = op->oq_modify.rs_modlist, pwmod = 0, mod_pw_only = 1, deladd = 0, delmod = NULL, addmod = NULL, zapReset = 1; - ml != NULL; modtail = ml, ml = ml->sml_next ) { + ml != NULL; modtail = ml, ml = ml->sml_next ) + { if ( ml->sml_desc == pp.ad ) { pwmod = 1; pwmop = ml->sml_op; diff --git a/servers/slapd/overlays/retcode.c b/servers/slapd/overlays/retcode.c index 25e12d366f..845370a812 100644 --- a/servers/slapd/overlays/retcode.c +++ b/servers/slapd/overlays/retcode.c @@ -39,6 +39,7 @@ static AttributeDescription *ad_errCode; static AttributeDescription *ad_errText; static AttributeDescription *ad_errOp; static AttributeDescription *ad_errSleepTime; +static AttributeDescription *ad_errMatchedDN; static ObjectClass *oc_errAbsObject; static ObjectClass *oc_errObject; static ObjectClass *oc_errAuxObject; @@ -63,6 +64,7 @@ typedef struct retcode_item_t { struct berval rdi_dn; struct berval rdi_ndn; struct berval rdi_text; + struct berval rdi_matched; int rdi_err; BerVarray rdi_ref; int rdi_sleeptime; @@ -84,7 +86,7 @@ typedef struct retcode_t { } retcode_t; static int -retcode_entry_response( Operation *op, SlapReply *rs, Entry *e ); +retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e ); static int retcode_cleanup_cb( Operation *op, SlapReply *rs ) @@ -159,10 +161,11 @@ done:; static int retcode_op_add( Operation *op, SlapReply *rs ) { - return retcode_entry_response( op, rs, op->ora_e ); + return retcode_entry_response( op, rs, NULL, op->ora_e ); } typedef struct retcode_cb_t { + BackendInfo *rdc_info; unsigned rdc_flags; ber_tag_t rdc_tag; AttributeName *rdc_attrs; @@ -181,14 +184,16 @@ retcode_cb_response( Operation *op, SlapReply *rs ) if ( op->o_tag == LDAP_REQ_SEARCH ) { rs->sr_attrs = rdc->rdc_attrs; } - rc = retcode_entry_response( op, rs, rs->sr_entry ); + rc = retcode_entry_response( op, rs, rdc->rdc_info, rs->sr_entry ); op->o_tag = o_tag; return rc; } if ( rs->sr_err == LDAP_SUCCESS ) { - rdc->rdc_flags = SLAP_CB_CONTINUE; + if ( !op->o_abandon ) { + rdc->rdc_flags = SLAP_CB_CONTINUE; + } return 0; } @@ -225,6 +230,7 @@ retcode_op_internal( Operation *op, SlapReply *rs ) db.bd_info = on->on_info->oi_orig; op2.o_bd = &db; + rdc.rdc_info = on->on_info->oi_orig; rdc.rdc_flags = RETCODE_FINDIR; if ( op->o_tag == LDAP_REQ_SEARCH ) { rdc.rdc_attrs = op->ors_attrs; @@ -264,16 +270,27 @@ retcode_op_func( Operation *op, SlapReply *rs ) return retcode_op_add( op, rs ); case LDAP_REQ_BIND: + /* skip if rootdn */ if ( be_isroot_pw( op ) ) { return SLAP_CB_CONTINUE; } - /* fallthru */ + return retcode_op_internal( op, rs ); + + case LDAP_REQ_SEARCH: + if ( op->ors_scope == LDAP_SCOPE_BASE ) { + rs->sr_err = retcode_op_internal( op, rs ); + if ( rs->sr_err == SLAP_CB_CONTINUE ) { + rs->sr_err = LDAP_SUCCESS; + } + send_ldap_result( op, rs ); + return rs->sr_err; + } + break; case LDAP_REQ_MODIFY: case LDAP_REQ_DELETE: case LDAP_REQ_MODRDN: case LDAP_REQ_COMPARE: - case LDAP_REQ_SEARCH: return retcode_op_internal( op, rs ); } } @@ -362,6 +379,7 @@ retcode_op_func( Operation *op, SlapReply *rs ) } else { rs->sr_err = rdi->rdi_err; rs->sr_text = rdi->rdi_text.bv_val; + rs->sr_matched = rdi->rdi_matched.bv_val; /* FIXME: we only honor the rdi_ref field in case rdi_err * is LDAP_REFERRAL otherwise send_ldap_result() bails out */ @@ -447,10 +465,8 @@ retcode_op2str( ber_tag_t op, struct berval *bv ) } static int -retcode_entry_response( Operation *op, SlapReply *rs, Entry *e ) +retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e ) { - slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; - Attribute *a; int err; char *next; @@ -511,7 +527,8 @@ retcode_entry_response( Operation *op, SlapReply *rs, Entry *e ) } if ( rs->sr_err != LDAP_SUCCESS ) { - BackendDB db = *op->o_bd; + BackendDB db = *op->o_bd, + *o_bd = op->o_bd; void *o_callback = op->o_callback; /* message text */ @@ -520,7 +537,19 @@ retcode_entry_response( Operation *op, SlapReply *rs, Entry *e ) rs->sr_text = a->a_vals[ 0 ].bv_val; } - db.bd_info = on->on_info->oi_orig; + /* matched DN */ + a = attr_find( e->e_attrs, ad_errMatchedDN ); + if ( a != NULL ) { + rs->sr_matched = a->a_vals[ 0 ].bv_val; + } + + if ( bi == NULL ) { + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + + bi = on->on_info->oi_orig; + } + + db.bd_info = bi; op->o_bd = &db; op->o_callback = NULL; @@ -544,6 +573,8 @@ retcode_entry_response( Operation *op, SlapReply *rs, Entry *e ) } rs->sr_text = NULL; + rs->sr_matched = NULL; + op->o_bd = o_bd; op->o_callback = o_callback; } @@ -565,7 +596,7 @@ retcode_response( Operation *op, SlapReply *rs ) return SLAP_CB_CONTINUE; } - return retcode_entry_response( op, rs, rs->sr_entry ); + return retcode_entry_response( op, rs, NULL, rs->sr_entry ); } static int @@ -711,13 +742,15 @@ retcode_db_config( } else if ( strcasecmp( ops[ j ], "compare" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_COMPARE; - } else if ( strcasecmp( ops[ j ], "add" ) == 0 ) { + } else if ( strcasecmp( ops[ j ], "delete" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_DELETE; } else if ( strcasecmp( ops[ j ], "modify" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_MODIFY; - } else if ( strcasecmp( ops[ j ], "rename" ) == 0 ) { + } else if ( strcasecmp( ops[ j ], "rename" ) == 0 + || strcasecmp( ops[ j ], "modrdn" ) == 0 ) + { rdi.rdi_mask |= SN_DG_OP_RENAME; } else if ( strcasecmp( ops[ j ], "search" ) == 0 ) { @@ -757,6 +790,24 @@ retcode_db_config( } ber_str2bv( &argv[ i ][ STRLENOF( "text=" ) ], 0, 1, &rdi.rdi_text ); + } else if ( strncasecmp( argv[ i ], "matched=", STRLENOF( "matched=" ) ) == 0 ) + { + struct berval dn; + + if ( !BER_BVISNULL( &rdi.rdi_matched ) ) { + fprintf( stderr, "%s: line %d: retcode: " + "\"matched\" already provided.\n", + fname, lineno ); + return 1; + } + ber_str2bv( &argv[ i ][ STRLENOF( "matched=" ) ], 0, 0, &dn ); + if ( dnPretty( NULL, &dn, &rdi.rdi_matched, NULL ) != LDAP_SUCCESS ) { + fprintf( stderr, "%s: line %d: retcode: " + "unable to prettify matched DN \"%s\".\n", + fname, lineno, &argv[ i ][ STRLENOF( "matched=" ) ] ); + return 1; + } + } else if ( strncasecmp( argv[ i ], "ref=", STRLENOF( "ref=" ) ) == 0 ) { char **refs; @@ -898,6 +949,13 @@ retcode_db_open( BackendDB *be ) attr_merge_normalize_one( &rdi->rdi_e, ad_errText, &val[ 0 ], NULL ); } + /* matched */ + if ( !BER_BVISNULL( &rdi->rdi_matched ) ) { + val[ 0 ] = rdi->rdi_matched; + + attr_merge_normalize_one( &rdi->rdi_e, ad_errMatchedDN, &val[ 0 ], NULL ); + } + /* sleep time */ if ( rdi->rdi_sleeptime > 0 ) { snprintf( buf, sizeof( buf ), "%d", rdi->rdi_sleeptime ); @@ -968,6 +1026,14 @@ retcode_db_destroy( BackendDB *be ) ber_memfree( rdi->rdi_text.bv_val ); } + if ( !BER_BVISNULL( &rdi->rdi_matched ) ) { + ber_memfree( rdi->rdi_matched.bv_val ); + } + + if ( rdi->rdi_ref ) { + ber_bvarray_free( rdi->rdi_ref ); + } + BER_BVZERO( &rdi->rdi_e.e_name ); BER_BVZERO( &rdi->rdi_e.e_nname ); @@ -978,6 +1044,14 @@ retcode_db_destroy( BackendDB *be ) ch_free( rdi ); } + if ( !BER_BVISNULL( &rd->rd_pdn ) ) { + ber_memfree( rd->rd_pdn.bv_val ); + } + + if ( !BER_BVISNULL( &rd->rd_npdn ) ) { + ber_memfree( rd->rd_npdn.bv_val ); + } + ber_memfree( rd ); } @@ -1028,6 +1102,13 @@ retcode_init( void ) "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 " "SINGLE-VALUE )", &ad_errSleepTime }, + { "errMatchedDN", "( 1.3.6.1.4.1.4203.666.11.4.1.5 " + "NAME ( 'errMatchedDN' ) " + "DESC 'Value to be returned as matched DN' " + "EQUALITY distinguishedNameMatch " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 " + "SINGLE-VALUE )", + &ad_errMatchedDN }, { NULL } }; @@ -1046,6 +1127,7 @@ retcode_init( void ) "$ errOp " "$ errText " "$ errSleepTime " + "$ errMatchedDN " ") )", &oc_errAbsObject }, { "errObject", "( 1.3.6.1.4.1.4203.666.11.4.3.1 " diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 10ce96d7c5..afe894f795 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -483,9 +483,11 @@ syncprov_findbase( Operation *op, fbase_cookie *fc ) * CSN, and generate Present records for them. We always collect this result * in SyncID sets, even if there's only one match. */ -#define FIND_MAXCSN 1 -#define FIND_CSN 2 -#define FIND_PRESENT 3 +typedef enum find_csn_t { + FIND_MAXCSN = 1, + FIND_CSN = 2, + FIND_PRESENT = 3 +} find_csn_t; static int findmax_cb( Operation *op, SlapReply *rs ) @@ -564,7 +566,7 @@ findpres_cb( Operation *op, SlapReply *rs ) } static int -syncprov_findcsn( Operation *op, int mode ) +syncprov_findcsn( Operation *op, find_csn_t mode ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; syncprov_info_t *si = on->on_bi.bi_private; diff --git a/servers/slapd/overlays/translucent.c b/servers/slapd/overlays/translucent.c index 85724d5f50..49f1ff0e67 100644 --- a/servers/slapd/overlays/translucent.c +++ b/servers/slapd/overlays/translucent.c @@ -63,18 +63,12 @@ void glue_parent(Operation *op) { Operation nop = *op; slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; struct berval dn = { 0, NULL }; - char *odn = op->o_req_ndn.bv_val; Attribute *a; Entry *e; - int idn, ldn; - - /* tis more work to use strchr() for a berval... */ - for(idn = 0; odn[idn] && odn[idn] != ','; idn++); - if(!idn || !odn[idn]) return; /* because you never know */ - idn++; - ldn = dn.bv_len = op->o_req_ndn.bv_len - idn; - dn.bv_val = ch_malloc(ldn + 1); - strcpy(dn.bv_val, odn + idn); + struct berval pdn; + + dnParent( &op->o_req_ndn, &pdn ); + ber_dupbv( &dn, &pdn ); Debug(LDAP_DEBUG_TRACE, "=> glue_parent: fabricating glue for <%s>\n", dn.bv_val, 0, 0); diff --git a/servers/slapd/overlays/valsort.c b/servers/slapd/overlays/valsort.c index c273eb361c..1fe209b3c7 100644 --- a/servers/slapd/overlays/valsort.c +++ b/servers/slapd/overlays/valsort.c @@ -212,7 +212,7 @@ static void do_sort( Operation *op, Attribute *a, int beg, int num, slap_mask_t sort ) { int i, j, gotnvals; - struct berval tmp, ntmp, *vals, *nvals; + struct berval tmp, ntmp, *vals = NULL, *nvals; gotnvals = (a->a_vals != a->a_nvals ); @@ -314,7 +314,7 @@ valsort_response( Operation *op, SlapReply *rs ) gotnvals = (a->a_vals != a->a_nvals ); for (i=0; ia_nvals[i].bv_val, '{' ); + char *ptr = ber_bvchr( &a->a_nvals[i], '{' ); char *end = NULL; if ( !ptr ) { Debug(LDAP_DEBUG_TRACE, "weights missing from attr %s " @@ -339,7 +339,9 @@ valsort_response( Operation *op, SlapReply *rs ) if ( a->a_vals != a->a_nvals ) { ptr = a->a_vals[i].bv_val; - end = strchr( ptr, '}' ) + 1; + end = ber_bvchr( &a->a_vals[i], '}' ); + assert( end != NULL ); + end++; for (;*end;) *ptr++ = *end++; *ptr = '\0'; @@ -407,7 +409,7 @@ valsort_add( Operation *op, SlapReply *rs ) if ( !a ) continue; for (i=0; !BER_BVISNULL( &a->a_vals[i] ); i++) { - ptr = strchr(a->a_vals[i].bv_val, '{' ); + ptr = ber_bvchr(&a->a_vals[i], '{' ); if ( !ptr ) { Debug(LDAP_DEBUG_TRACE, "weight missing from attribute %s\n", vi->vi_ad->ad_cname.bv_val, 0, 0); @@ -451,7 +453,7 @@ valsort_modify( Operation *op, SlapReply *rs ) if ( !ml ) continue; for (i=0; !BER_BVISNULL( &ml->sml_values[i] ); i++) { - ptr = strchr(ml->sml_values[i].bv_val, '{' ); + ptr = ber_bvchr(&ml->sml_values[i], '{' ); if ( !ptr ) { Debug(LDAP_DEBUG_TRACE, "weight missing from attribute %s\n", vi->vi_ad->ad_cname.bv_val, 0, 0); diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index fee10439dd..cbb69bf9db 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -84,7 +84,7 @@ int passwd_extop( qpw->rs_old.bv_val ? " old" : "", qpw->rs_new.bv_val ? " new" : "", 0 ); } else { - Statslog( LDAP_DEBUG_STATS, "%s PASSMOD %s%s\n", + Statslog( LDAP_DEBUG_STATS, "%s PASSMOD%s%s\n", op->o_log_prefix, qpw->rs_old.bv_val ? " old" : "", qpw->rs_new.bv_val ? " new" : "", 0, 0 ); @@ -293,9 +293,11 @@ old_good: error_return:; if ( !BER_BVISNULL( &op->o_req_dn ) ) { op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); + BER_BVZERO( &op->o_req_dn ); } if ( !BER_BVISNULL( &op->o_req_ndn ) ) { op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); + BER_BVZERO( &op->o_req_ndn ); } return rc; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 62cfceaa0a..e8259a0959 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -93,8 +93,6 @@ LDAP_SLAPD_F (slap_dynacl_t *) slap_dynacl_get LDAP_P(( const char *name )); #endif /* SLAP_DYNACL */ LDAP_SLAPD_F (int) acl_init LDAP_P(( void )); -LDAP_SLAPD_V (const struct berval) aci_bv[]; - LDAP_SLAPD_F (int) acl_get_part LDAP_P(( struct berval *list, int ix, @@ -104,7 +102,7 @@ LDAP_SLAPD_F (int) acl_match_set LDAP_P(( struct berval *subj, Operation *op, Entry *e, - int setref )); + struct berval *default_set_attribute )); LDAP_SLAPD_F (int) acl_string_expand LDAP_P(( struct berval *newbuf, struct berval *pattern, char *match, int nmatch, regmatch_t *matches )); @@ -436,6 +434,8 @@ 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 )); +LDAP_SLAPD_F (int) slap_cf_aux_table_parse LDAP_P(( const char *word, void *bc, slap_cf_aux_table *tab0, LDAP_CONST char *tabmsg )); +LDAP_SLAPD_F (int) slap_cf_aux_table_unparse LDAP_P(( void *bc, struct berval *bv, slap_cf_aux_table *tab0 )); /* * ch_malloc.c diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index 394c0a0871..58f8a96342 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -833,6 +833,18 @@ slap_sasl_err2ldap( int saslerr ) { int rc; + /* map SASL errors to LDAP resultCode returned by: + * sasl_server_new() + * SASL_OK, SASL_NOMEM + * sasl_server_step() + * SASL_OK, SASL_CONTINUE, SASL_TRANS, SASL_BADPARAM, SASL_BADPROT, + * ... + * sasl_server_start() + * + SASL_NOMECH + * sasl_setprop() + * SASL_OK, SASL_BADPARAM + */ + switch (saslerr) { case SASL_OK: rc = LDAP_SUCCESS; @@ -841,8 +853,6 @@ slap_sasl_err2ldap( int saslerr ) rc = LDAP_SASL_BIND_IN_PROGRESS; break; case SASL_FAIL: - rc = LDAP_OTHER; - break; case SASL_NOMEM: rc = LDAP_OTHER; break; @@ -850,6 +860,9 @@ slap_sasl_err2ldap( int saslerr ) rc = LDAP_AUTH_METHOD_NOT_SUPPORTED; break; case SASL_BADAUTH: + case SASL_NOUSER: + case SASL_TRANS: + case SASL_EXPIRED: rc = LDAP_INVALID_CREDENTIALS; break; case SASL_NOAUTHZ: @@ -859,6 +872,13 @@ slap_sasl_err2ldap( int saslerr ) case SASL_ENCRYPT: rc = LDAP_INAPPROPRIATE_AUTH; break; + case SASL_UNAVAIL: + case SASL_TRYAGAIN: + rc = LDAP_UNAVAILABLE; + break; + case SASL_DISABLED: + rc = LDAP_UNWILLING_TO_PERFORM; + break; default: rc = LDAP_OTHER; break; diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index a7ef89783d..106dca9112 100644 --- a/servers/slapd/saslauthz.c +++ b/servers/slapd/saslauthz.c @@ -148,7 +148,7 @@ int slap_parse_user( struct berval *id, struct berval *user, * u[.mech[/realm]]:user */ - user->bv_val = strchr( id->bv_val, ':' ); + user->bv_val = ber_bvchr( id, ':' ); if ( BER_BVISNULL( user ) ) { return LDAP_PROTOCOL_ERROR; } @@ -156,20 +156,19 @@ int slap_parse_user( struct berval *id, struct berval *user, user->bv_val++; user->bv_len = id->bv_len - ( user->bv_val - id->bv_val ); - mech->bv_val = strchr( id->bv_val, '.' ); + mech->bv_val = ber_bvchr( id, '.' ); if ( !BER_BVISNULL( mech ) ) { mech->bv_val[ 0 ] = '\0'; mech->bv_val++; + mech->bv_len = user->bv_val - mech->bv_val - 1; - realm->bv_val = strchr( mech->bv_val, '/' ); + realm->bv_val = ber_bvchr( mech, '/' ); if ( !BER_BVISNULL( realm ) ) { realm->bv_val[ 0 ] = '\0'; realm->bv_val++; mech->bv_len = realm->bv_val - mech->bv_val - 1; realm->bv_len = user->bv_val - realm->bv_val - 1; - } else { - mech->bv_len = user->bv_val - mech->bv_val - 1; } } else { @@ -341,7 +340,8 @@ is_dn: bv.bv_len = in->bv_len - ( bv.bv_val - in->bv_val ); member_at = BER_BVNULL; bv.bv_val = in->bv_val + STRLENOF( "group" ); - group_dn.bv_val = strchr( bv.bv_val, ':' ); + bv.bv_len = in->bv_len - STRLENOF( "group" ); + group_dn.bv_val = ber_bvchr( &bv, ':' ); if ( group_dn.bv_val == NULL ) { /* last chance: assume it's a(n exact) DN ... */ bv.bv_val = in->bv_val; @@ -355,8 +355,9 @@ is_dn: bv.bv_len = in->bv_len - ( bv.bv_val - in->bv_val ); */ if ( bv.bv_val[ 0 ] == '/' ) { group_oc.bv_val = &bv.bv_val[ 1 ]; + group_oc.bv_len = group_dn.bv_val - group_oc.bv_val; - member_at.bv_val = strchr( group_oc.bv_val, '/' ); + member_at.bv_val = ber_bvchr( &group_oc, '/' ); if ( member_at.bv_val ) { AttributeDescription *ad = NULL; const char *text = NULL; @@ -368,13 +369,10 @@ is_dn: bv.bv_len = in->bv_len - ( bv.bv_val - in->bv_val ); if ( rc != LDAP_SUCCESS ) { return rc; } + } - } else { - group_oc.bv_len = group_dn.bv_val - group_oc.bv_val; - - if ( oc_bvfind( &group_oc ) == NULL ) { - return LDAP_INVALID_SYNTAX; - } + if ( oc_bvfind( &group_oc ) == NULL ) { + return LDAP_INVALID_SYNTAX; } } @@ -668,7 +666,8 @@ is_dn: bv.bv_len = val->bv_len - ( bv.bv_val - val->bv_val ); char *ptr; bv.bv_val = val->bv_val + STRLENOF( "group" ); - group_dn.bv_val = strchr( bv.bv_val, ':' ); + bv.bv_len = val->bv_len - STRLENOF( "group" ); + group_dn.bv_val = ber_bvchr( &bv, ':' ); if ( group_dn.bv_val == NULL ) { /* last chance: assume it's a(n exact) DN ... */ bv.bv_val = val->bv_val; @@ -681,9 +680,12 @@ is_dn: bv.bv_len = val->bv_len - ( bv.bv_val - val->bv_val ); * are present in schema... */ if ( bv.bv_val[ 0 ] == '/' ) { + ObjectClass *oc = NULL; + group_oc.bv_val = &bv.bv_val[ 1 ]; + group_oc.bv_len = group_dn.bv_val - group_oc.bv_val; - member_at.bv_val = strchr( group_oc.bv_val, '/' ); + member_at.bv_val = ber_bvchr( &group_oc, '/' ); if ( member_at.bv_val ) { AttributeDescription *ad = NULL; const char *text = NULL; @@ -698,18 +700,14 @@ is_dn: bv.bv_len = val->bv_len - ( bv.bv_val - val->bv_val ); member_at = ad->ad_cname; - } else { - ObjectClass *oc = NULL; - - group_oc.bv_len = group_dn.bv_val - group_oc.bv_val; - - oc = oc_bvfind( &group_oc ); - if ( oc == NULL ) { - return LDAP_INVALID_SYNTAX; - } + } - group_oc = oc->soc_cname; + oc = oc_bvfind( &group_oc ); + if ( oc == NULL ) { + return LDAP_INVALID_SYNTAX; } + + group_oc = oc->soc_cname; } group_dn.bv_val++; @@ -959,7 +957,7 @@ slap_parseURI( if ( idx.bv_val[ 0 ] == '{' ) { char *ptr; - ptr = strchr( idx.bv_val, '}' ) + 1; + ptr = ber_bvchr( &idx, '}' ) + 1; assert( ptr != (void *)1 ); @@ -1113,7 +1111,8 @@ is_dn: bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val); char *tmp; bv.bv_val = uri->bv_val + STRLENOF( "group" ); - group_dn.bv_val = strchr( bv.bv_val, ':' ); + bv.bv_len = uri->bv_len - STRLENOF( "group" ); + group_dn.bv_val = ber_bvchr( &bv, ':' ); if ( group_dn.bv_val == NULL ) { /* last chance: assume it's a(n exact) DN ... */ bv.bv_val = uri->bv_val; @@ -1123,15 +1122,15 @@ is_dn: bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val); if ( bv.bv_val[ 0 ] == '/' ) { group_oc.bv_val = &bv.bv_val[ 1 ]; + group_oc.bv_len = group_dn.bv_val - group_oc.bv_val; - member_at.bv_val = strchr( group_oc.bv_val, '/' ); + member_at.bv_val = ber_bvchr( &group_oc, '/' ); if ( member_at.bv_val ) { group_oc.bv_len = member_at.bv_val - group_oc.bv_val; member_at.bv_val++; member_at.bv_len = group_dn.bv_val - member_at.bv_val; } else { - group_oc.bv_len = group_dn.bv_val - group_oc.bv_val; BER_BVSTR( &member_at, SLAPD_GROUP_ATTR ); } diff --git a/servers/slapd/schema.c b/servers/slapd/schema.c index 7dd42ddf07..ca62d7784e 100644 --- a/servers/slapd/schema.c +++ b/servers/slapd/schema.c @@ -83,7 +83,7 @@ schema_info( Entry **entry, const char **text ) int rc; AttributeDescription *desc = NULL; struct berval rdn = frontendDB->be_schemadn; - vals[0].bv_val = strchr( rdn.bv_val, '=' ); + vals[0].bv_val = ber_bvchr( &rdn, '=' ); if( vals[0].bv_val == NULL ) { *text = "improperly configured subschema subentry"; @@ -102,7 +102,7 @@ schema_info( Entry **entry, const char **text ) return LDAP_OTHER; } - nvals[0].bv_val = strchr( frontendDB->be_schemandn.bv_val, '=' ); + nvals[0].bv_val = ber_bvchr( &frontendDB->be_schemandn, '=' ); assert( nvals[0].bv_val != NULL ); nvals[0].bv_val++; nvals[0].bv_len = frontendDB->be_schemandn.bv_len - diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index b4649932bf..505a375c51 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -2389,7 +2389,7 @@ serialNumberAndIssuerValidate( struct berval sn, i; if( in->bv_len < 3 ) return LDAP_INVALID_SYNTAX; - i.bv_val = strchr( in->bv_val, '$' ); + i.bv_val = ber_bvchr( in, '$' ); if( BER_BVISNULL( &i ) ) return LDAP_INVALID_SYNTAX; sn.bv_val = in->bv_val; @@ -2429,7 +2429,7 @@ serialNumberAndIssuerPretty( if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX; - i.bv_val = strchr( val->bv_val, '$' ); + i.bv_val = ber_bvchr( val, '$' ); if( BER_BVISNULL( &i ) ) return LDAP_INVALID_SYNTAX; sn.bv_val = val->bv_val; @@ -2504,7 +2504,7 @@ serialNumberAndIssuerNormalize( if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX; - i.bv_val = strchr( val->bv_val, '$' ); + i.bv_val = ber_bvchr( val, '$' ); if( BER_BVISNULL( &i ) ) return LDAP_INVALID_SYNTAX; sn.bv_val = val->bv_val; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 4514a45d18..1d81e8abaa 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1510,45 +1510,6 @@ typedef enum slap_aci_scope_t { } slap_aci_scope_t; #endif /* SLAPD_ACI_ENABLED */ -enum { - ACI_BV_ENTRY, - ACI_BV_CHILDREN, - ACI_BV_ONELEVEL, - ACI_BV_SUBTREE, - ACI_BV_BR_ENTRY, - ACI_BV_BR_ALL, - ACI_BV_ACCESS_ID, -#if 0 - ACI_BV_ANONYMOUS = BER_BVC("anonymous"), -#endif - ACI_BV_PUBLIC, - ACI_BV_USERS, - ACI_BV_SELF, - ACI_BV_DNATTR, - ACI_BV_GROUP, - ACI_BV_ROLE, - ACI_BV_SET, - ACI_BV_SET_REF, - ACI_BV_GRANT, - ACI_BV_DENY, - - ACI_BV_IP_EQ, -#ifdef LDAP_PF_LOCAL - ACI_BV_PATH_EQ, -#if 0 - ACI_BV_DIRSEP, -#endif -#endif /* LDAP_PF_LOCAL */ - - ACI_BV_GROUP_CLASS, - ACI_BV_GROUP_ATTR, - ACI_BV_ROLE_CLASS, - ACI_BV_ROLE_ATTR, - ACI_BV_SET_ATTR, - - ACI_BV_LAST -}; - /* * Backend-info * represents a backend @@ -1607,6 +1568,14 @@ typedef struct slap_verbmasks { const slap_mask_t mask; } slap_verbmasks; +typedef struct slap_cf_aux_table { + struct berval key; + int off; + char type; + char quote; + slap_verbmasks *aux; +} slap_cf_aux_table; + #define SLAP_LIMIT_TIME 1 #define SLAP_LIMIT_SIZE 2 diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c index f0fe956ad7..906d7a6046 100644 --- a/servers/slapd/slapcommon.c +++ b/servers/slapd/slapcommon.c @@ -180,6 +180,12 @@ slap_tool_init( int truncatemode = 0; int use_glue = 1; +#ifdef LDAP_DEBUG + /* tools default to "none", so that at least LDAP_DEBUG_ANY + * messages show up; use -d 0 to reset */ + ldap_debug = LDAP_DEBUG_NONE; +#endif + #ifdef CSRIMALLOC leakfilename = malloc( strlen( progname ) + STRLENOF( ".leak" ) + 1 ); sprintf( leakfilename, "%s.leak", progname ); @@ -245,11 +251,12 @@ slap_tool_init( break; case 'd': /* turn on debugging */ + { #ifdef LDAP_DEBUG + int level; + if ( optarg != NULL && optarg[ 0 ] != '-' && !isdigit( optarg[ 0 ] ) ) { - int level; - if ( str2loglevel( optarg, &level ) ) { fprintf( stderr, "unrecognized log level " @@ -257,10 +264,7 @@ slap_tool_init( exit( EXIT_FAILURE ); } - ldap_debug |= level; - } else { - int level; char *next = NULL; level = strtol( optarg, &next, 0 ); @@ -270,14 +274,20 @@ slap_tool_init( "\"%s\"\n", optarg ); exit( EXIT_FAILURE ); } + } + + if ( level ) { ldap_debug |= level; + } else { + /* allow to reset log level */ + ldap_debug = 0; } #else if ( atoi( optarg ) != 0 ) fputs( "must compile with LDAP_DEBUG for debugging\n", stderr ); #endif - break; + } break; case 'D': ber_str2bv( optarg, 0, 1, &authcDN ); diff --git a/servers/slapd/slapi/slapi_pblock.c b/servers/slapd/slapi/slapi_pblock.c index fa99303b0a..ef51920fb8 100644 --- a/servers/slapd/slapi/slapi_pblock.c +++ b/servers/slapd/slapi/slapi_pblock.c @@ -891,7 +891,7 @@ pblock_set( Slapi_PBlock *pb, int param, void *value ) case SLAPI_X_CONN_SSF: PBLOCK_ASSERT_CONN( pb ); PBLOCK_LOCK_CONN( pb ); - pb->pb_conn->c_ssf = (slap_ssf_t)value; + pb->pb_conn->c_ssf = (slap_ssf_t)(long)value; PBLOCK_UNLOCK_CONN( pb ); break; case SLAPI_X_CONN_SASL_CONTEXT: diff --git a/servers/slapd/slaptest.c b/servers/slapd/slaptest.c index 2453892230..85f08edc07 100644 --- a/servers/slapd/slaptest.c +++ b/servers/slapd/slaptest.c @@ -79,6 +79,8 @@ test_file( const char *fname, const char *ftype ) save_errno, strerror( save_errno ) ); return -1; } + + return 0; } int diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 4c1cbf49f0..b694ee2091 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -691,7 +691,14 @@ do_syncrep2( rctrlp = *rctrls; ber_init2( ber, &rctrlp->ldctl_value, LBER_USE_DER ); ber_scanf( ber, "{em" /*"}"*/, &syncstate, &syncUUID ); - /* FIXME: what if syncUUID is NULL or empty? */ + /* FIXME: what if syncUUID is NULL or empty? + * (happens with back-sql...) */ + if ( BER_BVISEMPTY( &syncUUID ) ) { + Debug( LDAP_DEBUG_ANY, "do_syncrep2: " + "got empty syncUUID\n", 0, 0, 0 ); + rc = -1; + goto done; + } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { ber_scanf( ber, /*"{"*/ "m}", &cookie ); if ( !BER_BVISNULL( &cookie ) ) { @@ -1175,7 +1182,7 @@ syncrepl_accesslog_mods( ad = NULL; bv = vals[i]; - colon = strchr( bv.bv_val, ':' ); + colon = ber_bvchr( &bv, ':' ); if ( !colon ) continue; /* invalid */ bv.bv_len = colon - bv.bv_val; @@ -2123,11 +2130,12 @@ syncrepl_add_glue( int rc; int suffrdns; int i; - struct berval dn = {0, NULL}; - struct berval ndn = {0, NULL}; + struct berval dn = BER_BVNULL; + struct berval ndn = BER_BVNULL; Entry *glue; SlapReply rs_add = {REP_RESULT}; - char *ptr, *comma; + struct berval ptr, nptr; + char *comma; op->o_tag = LDAP_REQ_ADD; op->o_callback = &cb; @@ -2139,8 +2147,10 @@ syncrepl_add_glue( /* count RDNs in suffix */ if ( !BER_BVISEMPTY( &be->be_nsuffix[0] ) ) { - for ( i = 0, ptr = be->be_nsuffix[0].bv_val; ptr; ptr = strchr( ptr, ',' ) ) { - ptr++; + for ( i = 0, ptr = be->be_nsuffix[0], comma = ptr.bv_val; comma != NULL; comma = ber_bvchr( &ptr, ',' ) ) { + comma++; + ptr.bv_len -= comma - ptr.bv_val; + ptr.bv_val = comma; i++; } suffrdns = i; @@ -2150,23 +2160,34 @@ syncrepl_add_glue( } /* Start with BE suffix */ - for ( i = 0, ptr = NULL; i < suffrdns; i++ ) { - comma = strrchr( dn.bv_val, ',' ); - if ( ptr ) *ptr = ','; - if ( comma ) *comma = '\0'; - ptr = comma; + ptr = dn; + for ( i = 0; i < suffrdns; i++ ) { + comma = ber_bvrchr( &ptr, ',' ); + if ( comma != NULL ) { + ptr.bv_len = comma - ptr.bv_val; + } else { + ptr.bv_len = 0; + break; + } } - if ( ptr ) { - *ptr++ = ','; - dn.bv_len -= ptr - dn.bv_val; - dn.bv_val = ptr; + + if ( !BER_BVISEMPTY( &ptr ) ) { + dn.bv_len -= ptr.bv_len + 1; + dn.bv_val += ptr.bv_len + 1; } + /* the normalizedDNs are always the same length, no counting * required. */ + nptr = ndn; if ( ndn.bv_len > be->be_nsuffix[0].bv_len ) { ndn.bv_val += ndn.bv_len - be->be_nsuffix[0].bv_len; ndn.bv_len = be->be_nsuffix[0].bv_len; + + nptr.bv_len = ndn.bv_val - nptr.bv_val - 1; + + } else { + nptr.bv_len = 0; } while ( ndn.bv_val > e->e_nname.bv_val ) { @@ -2211,20 +2232,21 @@ syncrepl_add_glue( } /* Move to next child */ - for (ptr = dn.bv_val-2; ptr > e->e_name.bv_val && *ptr != ','; ptr--) { - /* empty */ - } - if ( ptr == e->e_name.bv_val ) break; - dn.bv_val = ++ptr; - dn.bv_len = e->e_name.bv_len - (ptr-e->e_name.bv_val); - for( ptr = ndn.bv_val-2; - ptr > e->e_nname.bv_val && *ptr != ','; - ptr--) - { - /* empty */ + comma = ber_bvrchr( &ptr, ',' ); + if ( comma == NULL ) { + break; } - ndn.bv_val = ++ptr; - ndn.bv_len = e->e_nname.bv_len - (ptr-e->e_nname.bv_val); + ptr.bv_len = comma - ptr.bv_val; + + dn.bv_val = ++comma; + dn.bv_len = e->e_name.bv_len - (dn.bv_val - e->e_name.bv_val); + + comma = ber_bvrchr( &nptr, ',' ); + assert( comma != NULL ); + nptr.bv_len = comma - nptr.bv_val; + + ndn.bv_val = ++comma; + ndn.bv_len = e->e_nname.bv_len - (ndn.bv_val - e->e_nname.bv_val); } op->o_req_dn = e->e_name; diff --git a/servers/slapd/value.c b/servers/slapd/value.c index 280ab4af57..cf2d73075e 100644 --- a/servers/slapd/value.c +++ b/servers/slapd/value.c @@ -271,7 +271,9 @@ ordered_value_renumber( Attribute *a, int vals ) ibv.bv_len = sprintf(ibv.bv_val, "{%d}", i); vtmp = a->a_vals[i]; if ( vtmp.bv_val[0] == '{' ) { - ptr = strchr(vtmp.bv_val, '}') + 1; + ptr = ber_bvchr(&vtmp, '}'); + assert( ptr != NULL ); + ++ptr; vtmp.bv_len -= ptr - vtmp.bv_val; vtmp.bv_val = ptr; } @@ -286,7 +288,9 @@ ordered_value_renumber( Attribute *a, int vals ) if ( a->a_nvals && a->a_nvals != a->a_vals ) { vtmp = a->a_nvals[i]; if ( vtmp.bv_val[0] == '{' ) { - ptr = strchr(vtmp.bv_val, '}') + 1; + ptr = ber_bvchr(&vtmp, '}'); + assert( ptr != NULL ); + ++ptr; vtmp.bv_len -= ptr - vtmp.bv_val; vtmp.bv_val = ptr; } @@ -321,7 +325,7 @@ ordered_value_sort( Attribute *a, int do_renumber ) if ( a->a_vals[i].bv_val[0] == '{' ) { char *ptr; index = 1; - ptr = strchr( a->a_vals[i].bv_val, '}' ); + ptr = ber_bvchr( &a->a_vals[i], '}' ); if ( !ptr ) return LDAP_INVALID_SYNTAX; if ( noindex ) @@ -345,7 +349,7 @@ ordered_value_sort( Attribute *a, int do_renumber ) a->a_nvals = ch_malloc( (vals+1)*sizeof(struct berval)); BER_BVZERO(a->a_nvals+vals); for ( i=0; ia_vals[i].bv_val, '}') + 1; + char *ptr = ber_bvchr(&a->a_vals[i], '}') + 1; a->a_nvals[i].bv_len = a->a_vals[i].bv_len - (ptr - a->a_vals[i].bv_val); a->a_nvals[i].bv_val = ch_malloc( a->a_nvals[i].bv_len + 1); @@ -353,7 +357,7 @@ ordered_value_sort( Attribute *a, int do_renumber ) } } else { for ( i=0; ia_nvals[i].bv_val, '}') + 1; + char *ptr = ber_bvchr(&a->a_nvals[i], '}') + 1; a->a_nvals[i].bv_len -= ptr - a->a_nvals[i].bv_val; strcpy(a->a_nvals[i].bv_val, ptr); } @@ -423,7 +427,7 @@ ordered_value_validate( if ( bv.bv_val[0] == '{' ) { char *ptr; - ptr = strchr( bv.bv_val, '}' ); + ptr = ber_bvchr( &bv, '}' ); if ( ptr == NULL ) { return LDAP_INVALID_SYNTAX; } @@ -465,7 +469,7 @@ ordered_value_pretty( if ( bv.bv_val[0] == '{' ) { char *ptr; - ptr = strchr( bv.bv_val, '}' ); + ptr = ber_bvchr( &bv, '}' ); if ( ptr == NULL ) { return LDAP_INVALID_SYNTAX; } @@ -525,10 +529,10 @@ ordered_value_normalize( if ( ad->ad_type->sat_flags & SLAP_AT_ORDERED ) { /* Skip past the assertion index */ - if ( bv.bv_val[0] == '{' ) { + if ( bv.bv_val[ 0 ] == '{' ) { char *ptr; - ptr = strchr( bv.bv_val, '}' ); + ptr = ber_bvchr( &bv, '}' ); if ( ptr == NULL ) { return LDAP_INVALID_SYNTAX; } @@ -600,7 +604,11 @@ ordered_value_match( /* Skip past the assertion index */ if ( bv2.bv_val[0] == '{' ) { - ptr = strchr( bv2.bv_val, '}' ) + 1; + ptr = ber_bvchr( &bv2, '}' ); + if ( ptr == NULL ) { + return LDAP_INVALID_SYNTAX; + } + ptr++; bv2.bv_len -= ptr - bv2.bv_val; bv2.bv_val = ptr; v2 = &bv2; @@ -627,7 +635,11 @@ ordered_value_match( } /* Skip past the attribute index */ if ( bv1.bv_val[0] == '{' ) { - ptr = strchr( bv1.bv_val, '}' ) + 1; + ptr = ber_bvchr( &bv1, '}' ); + if ( ptr == NULL ) { + return LDAP_INVALID_SYNTAX; + } + ptr++; bv1.bv_len -= ptr - bv1.bv_val; bv1.bv_val = ptr; v1 = &bv1; @@ -684,9 +696,17 @@ ordered_value_add( } for (i=0; i vals[i].bv_len ) + { + return -1; + } if ( k > anum ) k = -1; } /* No index, or index is greater than current number of diff --git a/servers/slurpd/config.c b/servers/slurpd/config.c index 6fe2e4035e..be39480cf5 100644 --- a/servers/slurpd/config.c +++ b/servers/slurpd/config.c @@ -58,7 +58,7 @@ static void add_replica LDAP_P(( char **, int )); static int parse_replica_line LDAP_P(( char **, int, Ri *)); static void parse_line LDAP_P(( char * )); -static char *getline LDAP_P(( FILE * )); +static char *slurpd_getline LDAP_P(( FILE * )); static char *strtok_quote LDAP_P(( char *, char * )); int cargc = 0, cargv_size = 0; @@ -96,7 +96,7 @@ slurpd_read_config( } lineno = 0; - while ( (line = getline( fp )) != NULL ) { + while ( (line = slurpd_getline( fp )) != NULL ) { /* skip comments and blank lines */ if ( line[0] == '#' || line[0] == '\0' ) { continue; @@ -321,7 +321,7 @@ strtok_quote( * Get a line of input. */ static char * -getline( +slurpd_getline( FILE *fp ) { diff --git a/servers/slurpd/main.c b/servers/slurpd/main.c index ccd75e7ed0..a502ea0265 100644 --- a/servers/slurpd/main.c +++ b/servers/slurpd/main.c @@ -155,7 +155,7 @@ int main( int argc, char **argv ) } #ifdef HAVE_TLS - if( ldap_pvt_tls_init() || ldap_pvt_tls_init_def_ctx() ) { + if( ldap_pvt_tls_init() || ldap_pvt_tls_init_def_ctx( 0 ) ) { rc = 0; /* See if we actually need TLS */ for ( i=0; i < sglob->num_replicas; i++ ) { @@ -215,31 +215,57 @@ int main( int argc, char **argv ) } #endif - if ( slurpd_pid_file != NULL ) { - FILE *fp = fopen( slurpd_pid_file, "w" ); + /* + * don't open pid/args file in one-shot mode (ITS#4152) + * + * bail out if files were specified but cannot be opened (ITS#4074) + */ + if ( !sglob->one_shot_mode) { + if ( slurpd_pid_file != NULL ) { + FILE *fp = fopen( slurpd_pid_file, "w" ); + + if ( fp == NULL ) { + int save_errno = errno; + + fprintf( stderr, "unable to open pid file " + "\"%s\": %d (%s)\n", + slurpd_pid_file, + save_errno, strerror( save_errno ) ); + + free( slurpd_pid_file ); + slurpd_pid_file = NULL; + + rc = 1; + goto stop; + } - if( fp != NULL ) { fprintf( fp, "%d\n", (int) getpid() ); fclose( fp ); - - } else { - free(slurpd_pid_file); - slurpd_pid_file = NULL; } - } - if ( slurpd_args_file != NULL ) { - FILE *fp = fopen( slurpd_args_file, "w" ); + if ( slurpd_args_file != NULL ) { + FILE *fp = fopen( slurpd_args_file, "w" ); + + if ( fp == NULL ) { + int save_errno = errno; + + fprintf( stderr, "unable to open args file " + "\"%s\": %d (%s)\n", + slurpd_args_file, + save_errno, strerror( save_errno ) ); + + free( slurpd_args_file ); + slurpd_pid_file = NULL; + + rc = 1; + goto stop; + } - if( fp != NULL ) { for ( i = 0; i < argc; i++ ) { fprintf( fp, "%s ", argv[i] ); } fprintf( fp, "\n" ); fclose( fp ); - } else { - free(slurpd_args_file); - slurpd_args_file = NULL; } } diff --git a/tests/data/meta.out b/tests/data/meta.out index 817440d020..97b9ed4f06 100644 --- a/tests/data/meta.out +++ b/tests/data/meta.out @@ -1411,3 +1411,13 @@ member: cn=Another Added Group,ou=Groups,o=Example,c=US # refldap://localhost:9016/cn=Somewhere,ou=Meta,dc=example,dc=com??sub +# searching filter="(member=cn=Another Added Group,ou=Groups,o=Example,c=US)" +# attrs="member" +# base="o=Example,c=US" +# with a timed out connection... +dn: cn=Another Added Group,ou=Groups,o=Example,c=US +member: cn=Added Group,ou=Groups,o=Example,c=US +member: cn=Another Added Group,ou=Groups,o=Example,c=US + +# refldap://localhost:9016/cn=Somewhere,ou=Meta,dc=example,dc=com??sub + diff --git a/tests/data/retcode.conf b/tests/data/retcode.conf index e498b0a0cb..18e9dcd06d 100644 --- a/tests/data/retcode.conf +++ b/tests/data/retcode.conf @@ -29,7 +29,7 @@ retcode-item "cn=authMethodNotSupported" 0x07 retcode-item "cn=strongAuthNotSupported" 0x07 text="same as authMethodNotSupported" retcode-item "cn=strongAuthRequired" 0x08 retcode-item "cn=strongerAuthRequired" 0x08 text="same as strongAuthRequired" -#retcode-item "cn=partialResults" 0x09 "LDAPv2+ (not LDAPv3)" +#retcode-item "cn=partialResults" 0x09 text="LDAPv2+ (not LDAPv3)" retcode-item "cn=referral" 0x0a text="LDAPv3" ref="ldap://:9019" retcode-item "cn=adminLimitExceeded" 0x0b text="LDAPv3" diff --git a/tests/data/slapd-idassert.conf b/tests/data/slapd-idassert.conf index f3cd6ae015..6f97a0216f 100644 --- a/tests/data/slapd-idassert.conf +++ b/tests/data/slapd-idassert.conf @@ -46,7 +46,7 @@ authz-regexp "^uid=(us/)?([^,]+),.+" "ldap:///ou=People,dc=example,dc=com??sub?( # cn=monitor, cn=schema, and cn=config # -access to attr=userpassword +access to attrs=userpassword by self =wx by anonymous =x @@ -71,7 +71,7 @@ rootpw secret #ldbm#index cn,sn,uid pres,eq,sub access to dn.exact="cn=Proxy,ou=Admin,dc=example,dc=com" - attr=authzTo + attrs=authzTo by dn.exact="cn=Proxy,ou=Admin,dc=example,dc=com" =wx by * =x diff --git a/tests/data/slapd-meta2.conf b/tests/data/slapd-meta2.conf index 2af5277231..5c018073aa 100644 --- a/tests/data/slapd-meta2.conf +++ b/tests/data/slapd-meta2.conf @@ -35,6 +35,8 @@ argsfile @TESTDIR@/slapd.2.args #rwmmod#modulepath ../servers/slapd/overlays/ #rwmmod#moduleload rwm.la +idletimeout 5 + ####################################################################### # database definitions ####################################################################### diff --git a/tests/data/slapd-sql-syncrepl-master.conf b/tests/data/slapd-sql-syncrepl-master.conf index 984d158f8e..f7029eddd4 100644 --- a/tests/data/slapd-sql-syncrepl-master.conf +++ b/tests/data/slapd-sql-syncrepl-master.conf @@ -34,8 +34,8 @@ argsfile @TESTDIR@/slapd.1.args # cn=monitor, cn=schema, and cn=config # -access to attr=userpassword - by self =wx +access to attrs=userpassword + by self =w by anonymous =x access to * diff --git a/tests/data/slapd-sql.conf b/tests/data/slapd-sql.conf index 8b7ae7dc40..a93b00ede9 100644 --- a/tests/data/slapd-sql.conf +++ b/tests/data/slapd-sql.conf @@ -32,8 +32,8 @@ argsfile @TESTDIR@/slapd.1.args # cn=monitor, cn=schema, and cn=config # -access to attr=userpassword - by self =wx +access to attrs=userpassword + by self =w by anonymous =x access to * diff --git a/tests/progs/slapd-addel.c b/tests/progs/slapd-addel.c index 456bb78475..8acd88a810 100644 --- a/tests/progs/slapd-addel.c +++ b/tests/progs/slapd-addel.c @@ -55,7 +55,8 @@ usage( char *name ) "-f " "[-l ] " "[-r ] " - "[-t ]\n", + "[-t ] " + "[-F]\n", name ); exit( EXIT_FAILURE ); } diff --git a/tests/progs/slapd-bind.c b/tests/progs/slapd-bind.c index e471c350eb..25175590f8 100644 --- a/tests/progs/slapd-bind.c +++ b/tests/progs/slapd-bind.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #define LDAP_DEPRECATED 1 #include @@ -37,10 +39,12 @@ #define LOOPS 100 static int -do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop ); +do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop, + int force ); static int -do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop ); +do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop, + int force ); /* 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 @@ -52,7 +56,7 @@ do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop ); static void usage( char *name ) { - fprintf( stderr, "usage: %s [-h ] -p port (-D |-b ) -w [-l ]\n", + fprintf( stderr, "usage: %s [-h ] -p port (-D |-b [-f ]) -w [-l ] [-F]\n", name ); exit( EXIT_FAILURE ); } @@ -64,14 +68,15 @@ main( int argc, char **argv ) { int i; char *uri = NULL; - char *host = "localhost"; + char *host = "localhost"; char *dn = NULL; char *base = NULL; char *pass = NULL; - int port = -1; - int loops = LOOPS; + int port = -1; + int loops = LOOPS; + int force = 0; - while ( (i = getopt( argc, argv, "b:H:h:p:D:w:l:" )) != EOF ) { + while ( (i = getopt( argc, argv, "b:H:h:p:D:w:l:f:F" )) != EOF ) { switch( i ) { case 'b': /* base DN of a tree of user DNs */ base = strdup( optarg ); @@ -100,6 +105,14 @@ main( int argc, char **argv ) loops = atoi( optarg ); break; + case 'f': + filter = optarg; + break; + + case 'F': + force = 1; + break; + default: usage( argv[0] ); break; @@ -110,19 +123,19 @@ main( int argc, char **argv ) usage( argv[0] ); if ( base ) - do_base( uri, host, port, base, pass, ( 20 * loops )); + do_base( uri, host, port, base, pass, ( 20 * loops ), force ); else - do_bind( uri, host, port, dn, pass, ( 20 * loops )); + do_bind( uri, host, port, dn, pass, ( 20 * loops ), force ); exit( EXIT_SUCCESS ); } static int -do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop ) +do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop, + int force ) { LDAP *ld = NULL; - int i, rc; - char *attrs[] = { "1.1", NULL }; + int i, rc = -1; pid_t pid = getpid(); if ( maxloop > 1 ) @@ -130,8 +143,6 @@ do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop ) (long) pid, maxloop, dn ); for ( i = 0; i < maxloop; i++ ) { - LDAPMessage *res; - if ( uri ) { ldap_initialize( &ld, uri ); } else { @@ -154,7 +165,7 @@ do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop ) ldap_perror( ld, "ldap_bind" ); } ldap_unbind( ld ); - if ( rc != LDAP_SUCCESS ) { + if ( rc != LDAP_SUCCESS && !force ) { break; } } @@ -167,7 +178,8 @@ 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 ) +do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop, + int force ) { LDAP *ld = NULL; int i = 0; @@ -178,7 +190,11 @@ do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop ) char **rdns = NULL; char *attrs[] = { "dn", NULL }; int nrdns = 0; - time_t beg, end; +#ifdef _WIN32 + DWORD beg, end; +#else + struct timeval beg, end; +#endif srand(pid); @@ -244,7 +260,17 @@ do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop ) } ldap_unbind( ld ); - beg = time(0L); +#ifdef _WIN32 + beg = GetTickCount(); +#else + gettimeofday( &beg, NULL ); +#endif + + if ( nrdns == 0 ) { + fprintf( stderr, "No RDNs.\n" ); + return 1; + } + /* Ok, got list of RDNs, now start binding to each */ for (i=0; i " "[-l ] " "[-r ] " - "[-t ]\n", + "[-t ] " + "[-F]\n", name ); exit( EXIT_FAILURE ); } diff --git a/tests/progs/slapd-modrdn.c b/tests/progs/slapd-modrdn.c index 1522b864f3..d6c5f9257f 100644 --- a/tests/progs/slapd-modrdn.c +++ b/tests/progs/slapd-modrdn.c @@ -52,7 +52,8 @@ usage( char *name ) "-e " "[-l ] " "[-r ] " - "[-t ]\n", + "[-t ] " + "[-F]\n", name ); exit( EXIT_FAILURE ); } diff --git a/tests/scripts/defines.sh b/tests/scripts/defines.sh index 1beba89e3e..6d896d7972 100755 --- a/tests/scripts/defines.sh +++ b/tests/scripts/defines.sh @@ -122,9 +122,9 @@ CLIENTDIR=../clients/tools LDIFFILTER=$SRCDIR/scripts/acfilter.sh CONFFILTER=$SRCDIR/scripts/conf.sh -SLAPADD="../servers/slapd/slapd -Ta $LDAP_VERBOSE" -SLAPCAT="../servers/slapd/slapd -Tc $LDAP_VERBOSE" -SLAPINDEX="../servers/slapd/slapd -Ti $LDAP_VERBOSE" +SLAPADD="../servers/slapd/slapd -Ta -d 0 $LDAP_VERBOSE" +SLAPCAT="../servers/slapd/slapd -Tc -d 0 $LDAP_VERBOSE" +SLAPINDEX="../servers/slapd/slapd -Ti -d 0 $LDAP_VERBOSE" unset DIFF_OPTIONS # NOTE: -u/-c is not that portable... diff --git a/tests/scripts/test035-meta b/tests/scripts/test035-meta index 895644f873..6a2c2d2b2a 100755 --- a/tests/scripts/test035-meta +++ b/tests/scripts/test035-meta @@ -412,6 +412,38 @@ case $RC in ;; esac +echo "Waiting 10 seconds for cached connections to timeout..." +sleep 10 + +echo "Searching with a timed out connection..." +echo "# searching filter=\"$FILTER\"" >> $SEARCHOUT +echo "# attrs=\"member\"" >> $SEARCHOUT +echo "# base=\"$BASEDN\"" >> $SEARCHOUT +echo "# with a timed out connection..." >> $SEARCHOUT +$LDAPSEARCH -S "" -h $LOCALHOST -p $PORT3 -D "cn=Manager,$BASEDN" -w $PASSWD \ + -b "$BASEDN" "$FILTER" member \ + >> $SEARCHOUT 2>&1 +RC=$? +#if test $RC != 0 ; then +# echo "Search failed ($RC)!" +# test $KILLSERVERS != no && kill -HUP $KILLPIDS +# exit $RC +#fi +case $RC in + 0) + ;; + 51) + echo "### Hit LDAP_BUSY problem; you may want to re-run the test" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit 0 + ;; + *) + echo "Search failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC + ;; +esac + echo "Filtering ldapsearch results..." . $LDIFFILTER < $SEARCHOUT > $SEARCHFLT echo "Filtering original ldif used to create database..." @@ -576,7 +608,7 @@ RC=$? #if test $RC != 6 ; then # echo "Compare failed ($RC)!" # test $KILLSERVERS != no && kill -HUP $KILLPIDS -# exit $RC +# exit -1 #fi case $RC in 6) diff --git a/tests/scripts/test036-meta-concurrency b/tests/scripts/test036-meta-concurrency index a75253a514..e29b8e0972 100755 --- a/tests/scripts/test036-meta-concurrency +++ b/tests/scripts/test036-meta-concurrency @@ -215,7 +215,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-meta search/modification didn't succeed" exit 1 fi -- 2.39.5