OpenLDAP 2.3 Change Log
OpenLDAP 2.3.12 Engineering
+ Fixed libldap ldapi:// authdn construction
+ Added libldap ldap_bv2escaped_filter_value
+ Updated contrib smbk5pwd module
+ Build environment
+ Added slapd-bind test program
+ Added inet_ntoa_b support for VxWorks
+ Dropped SSLeay support
OpenLDAP 2.3.11 Release
Fixed libldap reentrancy issue (ITS#3988)
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"
# 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
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
- case "`/usr/bin/file conftest.o`" in
+ case `/usr/bin/file conftest.o` in
*32-bit*)
case $host in
x86_64-*linux*)
# with a dollar sign (not a hyphen), so the echo should work correctly.
# The option is referenced via a variable to avoid confusing sed.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
LDFLAGS="$LDFLAGS $3"
printf "$lt_simple_link_test_code" > conftest.$ac_ext
if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The compiler can only warn and ignore the option if not recognized
+ # The linker can only warn and ignore the option if not recognized
# So say no if there are warnings
if test -s conftest.err; then
# Append any errors to the config.log.
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`
# nice to cause kernel panics so lets avoid the loop below.
# First set a reasonable default.
lt_cv_sys_max_cmd_len=16384
- #
+ #
if test -x /sbin/sysconfig; then
case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
*1*) lt_cv_sys_max_cmd_len=-1 ;;
}]
EOF
if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) 2>/dev/null
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
lt_status=$?
case x$lt_status in
x$lt_dlno_uscore) $1 ;;
# Note that $ac_compile itself does not contain backslashes and begins
# with a dollar sign (not a hyphen), so the echo should work correctly.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
fi
fi
- chmod u+w .
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
$rm conftest*
# SGI C++ compiler will create directory out/ii_files/ for
# template instantiation
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'
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"`
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*)
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
# AC_LIBTOOL_WIN32_DLL
# --------------------
-# declare package support for building win32 dll's
+# declare package support for building win32 DLLs
AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
])# AC_LIBTOOL_WIN32_DLL
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
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
lt_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some GNU ld's only accept -v.
+ # but apparently some variants of GNU ld only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
AC_DEFUN([AC_PROG_LD_GNU],
[AC_REQUIRE([AC_PROG_EGREP])dnl
AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
-[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
case `$LD -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
lt_cv_prog_gnu_ld=yes
hpux10.20* | hpux11*)
lt_cv_file_magic_cmd=/usr/bin/file
- case "$host_cpu" in
+ case $host_cpu in
ia64*)
lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
# -----------------------------------
# sets LIBLTDL to the link flags for the libltdl convenience library and
# LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL
-# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If
-# DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will
-# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with
-# '${top_srcdir}/' (note the single quotes!). If your package is not
-# flat and you're not using automake, define top_builddir and
-# top_srcdir appropriately in the Makefiles.
+# --enable-ltdl-convenience to the configure arguments. Note that
+# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided,
+# it is assumed to be `libltdl'. LIBLTDL will be prefixed with
+# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/'
+# (note the single quotes!). If your package is not flat and you're not
+# using automake, define top_builddir and top_srcdir appropriately in
+# the Makefiles.
AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
case $enable_ltdl_convenience in
# -----------------------------------
# sets LIBLTDL to the link flags for the libltdl installable library and
# LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-install to the configure arguments. Note that LIBLTDL
-# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If
-# DIRECTORY is not provided and an installed libltdl is not found, it is
-# assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/'
-# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single
-# quotes!). If your package is not flat and you're not using automake,
-# define top_builddir and top_srcdir appropriately in the Makefiles.
+# --enable-ltdl-install to the configure arguments. Note that
+# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided,
+# and an installed libltdl is not found, it is assumed to be `libltdl'.
+# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with
+# '${top_srcdir}/' (note the single quotes!). If your package is not
+# flat and you're not using automake, define top_builddir and top_srcdir
+# appropriately in the Makefiles.
# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
# 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
_LT_AC_TAGVAR(compiler_lib_search_path, $1)=
# Source file extension for C++ test sources.
-ac_ext=cc
+ac_ext=cpp
# Object file extension for compiled C++ test sources.
objext=o
# Exported symbols can be pulled into shared objects from archives
_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds it's shared libraries.
+ # This is similar to how AIX traditionally builds its shared libraries.
_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
fi
;;
darwin* | rhapsody*)
- case "$host_os" in
+ case $host_os in
rhapsody* | darwin1.[[012]])
_LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
;;
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
fi
_LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
else
output_verbose_link_cmd='echo'
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
_LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
_LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
;;
;;
hpux10*|hpux11*)
if test $with_gnu_ld = no; then
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*)
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
;;
esac
fi
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*)
_LT_AC_TAGVAR(hardcode_direct, $1)=no
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_AC_TAGVAR(ld_shlibs, $1)=no
;;
aCC*)
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
_LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
;;
*)
if test "$GXX" = yes; then
if test $with_gnu_ld = no; then
- case "$host_cpu" in
+ case $host_cpu in
ia64*|hppa*64*)
_LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
;;
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
;;
cxx*)
# Compaq C++
case $cc_basename in
CC*)
# Sun C++ 4.2, 5.x and Centerline C++
+ _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes
_LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
esac
_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ output_verbose_link_cmd='echo'
# Archives containing C++ object files must be created using
# "CC -xar", where "CC" is the Sun C++ compiler. This is
# The `*' in the case matches for architectures that use `case' in
# $output_verbose_cmd can trigger glob expansion during the loop
# eval without this substitution.
- output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+ output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
for p in `eval $output_verbose_link_cmd`; do
case $p in
$rm -f confest.$objext
+# PORTME: override above test on systems where it is broken
+ifelse([$1],[CXX],
+[case $host_os in
+solaris*)
+ case $cc_basename in
+ CC*)
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun'
+ ;;
+ esac
+esac
+])
+
case " $_LT_AC_TAGVAR(postdeps, $1) " in
*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
esac
# 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
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*)
;;
*)
aCC*)
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
# Portland Group C++ compiler.
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
cxx*)
# Compaq C++
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
;;
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
- pgcc* | pgf77* | pgf90*)
+ pgcc* | pgf77* | pgf90* | pgf95*)
# Portland Group compilers (*not* the Pentium gcc compiler,
# which looks to be a dead project)
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
ccc*)
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
[_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
_LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
fi
-case "$host_os" in
+case $host_os in
# For platforms which do not support PIC, -DPIC is meaningless:
*djgpp*)
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
if test "$with_gnu_ld" = yes; then
# If archive_cmds runs LD, not CC, wlarc should be empty
wlarc='${wl}'
-
+
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
*\ 2.11.*) ;; # other 2.11 versions
*) supports_anon_versioning=yes ;;
esac
-
+
# See if GNU ld supports shared libraries.
case $host_os in
aix3* | aix4* | aix5*)
tmp_addflag=
case $cc_basename,$host_cpu in
pgcc*) # Portland Group C compiler
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag'
;;
- pgf77* | pgf90* ) # Portland Group f77 and f90 compilers
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag -Mnomain' ;;
ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
tmp_addflag=' -i_dynamic' ;;
# Exported symbols can be pulled into shared objects from archives
_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds it's shared libraries.
+ # This is similar to how AIX traditionally builds its shared libraries.
_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
;;
darwin* | rhapsody*)
- case "$host_os" in
+ case $host_os in
rhapsody* | darwin1.[[012]])
_LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
;;
output_verbose_link_cmd='echo'
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
_LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
_LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
else
output_verbose_link_cmd='echo'
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
_LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
_LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
;;
hpux10* | hpux11*)
if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
;;
esac
else
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
_LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
;;
esac
fi
if test "$with_gnu_ld" = no; then
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*)
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+++ /dev/null
-This patch is intended to be applied to Berkeley DB 4.2.52 and,
-if applied, will automatically be used by slapd(8) back-bdb/hdb.
-Without this patch the BDB DB_LOG_AUTOREMOVE option will not work,
-nor will db_archive allow any transaction log files to be removed
-while slapd is running.
-
-The patch can be applied to the BDB source using patch(1) as follows
- cd db-4.2.52
- patch -p0 < openldap-src/build/BerkeleyDB42.patch
-
-(modify directory paths as necessary), then recompile and reinstall
-the BerkeleyDB 4.2 library, and then build and install OpenLDAP
-Software.
-
-The patch should not be applied to Berkeley DB 4.3.
-
-
-Index: dbinc/db.in
-===================================================================
-RCS file: /var/CVSROOT/bdb42/dbinc/db.in,v
-retrieving revision 1.1.1.1
-retrieving revision 1.2
-diff -u -r1.1.1.1 -r1.2
---- dbinc/db.in 25 Nov 2003 21:58:02 -0000 1.1.1.1
-+++ dbinc/db.in 17 Jul 2004 16:07:23 -0000 1.2
-@@ -839,6 +839,7 @@
- #define TXN_NOWAIT 0x040 /* Do not wait on locks. */
- #define TXN_RESTORED 0x080 /* Transaction has been restored. */
- #define TXN_SYNC 0x100 /* Sync on prepare and commit. */
-+#define TXN_NOLOG 0x200 /* Do not log this transaction. */
- u_int32_t flags;
- };
-
-Index: txn/txn.c
-===================================================================
-RCS file: /var/CVSROOT/bdb42/txn/txn.c,v
-retrieving revision 1.1.1.2
-retrieving revision 1.2
-diff -u -r1.1.1.2 -r1.2
---- txn/txn.c 17 Dec 2003 21:43:53 -0000 1.1.1.2
-+++ txn/txn.c 17 Jul 2004 16:07:27 -0000 1.2
-@@ -127,7 +127,7 @@
- if ((ret = __db_fchk(dbenv,
- "txn_begin", flags,
- DB_DIRTY_READ | DB_TXN_NOWAIT |
-- DB_TXN_NOSYNC | DB_TXN_SYNC)) != 0)
-+ DB_TXN_NOSYNC | DB_TXN_SYNC | DB_TXN_NOT_DURABLE)) != 0)
- return (ret);
- if ((ret = __db_fcchk(dbenv,
- "txn_begin", flags, DB_TXN_NOSYNC, DB_TXN_SYNC)) != 0)
-@@ -193,6 +193,8 @@
- F_SET(txn, TXN_SYNC);
- if (LF_ISSET(DB_TXN_NOWAIT))
- F_SET(txn, TXN_NOWAIT);
-+ if (LF_ISSET(DB_TXN_NOT_DURABLE))
-+ F_SET(txn, TXN_NOLOG);
-
- if ((ret = __txn_begin_int(txn, 0)) != 0)
- goto err;
-@@ -328,7 +330,7 @@
- * We should set this value when we write the first log record, not
- * here.
- */
-- if (DBENV_LOGGING(dbenv))
-+ if (DBENV_LOGGING(dbenv) && !F_ISSET(txn, TXN_NOLOG))
- __log_txn_lsn(dbenv, &begin_lsn, NULL, NULL);
- else
- ZERO_LSN(begin_lsn);
PROGRAM=ltmain.sh
PACKAGE=libtool
-VERSION=1.5.18-OpenLDAP
-TIMESTAMP=" (1.1220.2.245 2005/05/16 08:55:27)"
+VERSION=1.5.20-OpenLDAP
+TIMESTAMP=" (1.1220.2.287 2005/08/31 18:54:15)"
# See if we are running on zsh, and set the options which allow our
# commands through without removal of \ escapes.
Xsed="${SED}"' -e 1s/^X//'
sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
# test EBCDIC or ASCII
-case `echo A|tr A '\301'` in
- A) # EBCDIC based system
- SP2NL="tr '\100' '\n'"
- NL2SP="tr '\r\n' '\100\100'"
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ SP2NL='tr \040 \012'
+ NL2SP='tr \015\012 \040\040'
;;
- *) # Assume ASCII based system
- SP2NL="tr '\040' '\012'"
- NL2SP="tr '\015\012' '\040\040'"
+ *) # EBCDIC based system
+ SP2NL='tr \100 \n'
+ NL2SP='tr \r\n \100\100'
;;
esac
execute_dlfiles=
lo2o="s/\\.lo\$/.${objext}/"
o2lo="s/\\.${objext}\$/.lo/"
-quote_scanset='[[~#^*{};<>?'"'"' ]'
#####################################
# Shell function definitions:
CC_quoted=
for arg in $CC; do
case $arg in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
for arg in $CC; do
# Double-quote args containing other shell metacharacters.
case $arg in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
func_extract_an_archive "$my_xdir" "$my_xabs"
fi # $darwin_arches
fi # $run
- ;;
+ ;;
*)
func_extract_an_archive "$my_xdir" "$my_xabs"
;;
for arg
do
- case "$arg_mode" in
+ case $arg_mode in
arg )
# do not "continue". Instead, add this to base_compile
lastarg="$arg"
# Many Bourne shells cannot handle close brackets correctly
# in scan sets, so we specify it separately.
case $arg in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
# in scan sets (worked around with variable expansion),
# and furthermore cannot handle '|' '&' '(' ')' in scan sets
# at all, so we specify them separately.
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
lastarg="\"$lastarg\""
;;
esac
qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
case $qlibobj in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
qlibobj="\"$qlibobj\"" ;;
esac
- if test "X$libobj" != "X$qlibobj"; then
- $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
- exit $EXIT_FAILURE
- fi
+ test "X$libobj" != "X$qlibobj" \
+ && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
if test "X$xdir" = "X$obj"; then
fi
qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
case $qsrcfile in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
qsrcfile="\"$qsrcfile\"" ;;
esac
if test -n "$link_static_flag"; then
dlopen_self=$dlopen_self_static
fi
- prefer_static_libs=yes
else
if test -z "$pic_flag" && test -n "$link_static_flag"; then
dlopen_self=$dlopen_self_static
fi
- prefer_static_libs=built
fi
build_libtool_libs=no
build_old_libs=yes
+ prefer_static_libs=yes
break
;;
esac
arg="$1"
shift
case $arg in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
;;
*) qarg=$arg ;;
continue
;;
- -framework)
+ -framework|-arch)
prev=darwin_framework
compiler_flags="$compiler_flags $arg"
compile_command="$compile_command $arg"
# to be aesthetically quoted because they are evaled later.
arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
case $arg in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
for flag in $args; do
IFS="$save_ifs"
case $flag in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
flag="\"$flag\""
;;
esac
for flag in $args; do
IFS="$save_ifs"
case $flag in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
flag="\"$flag\""
;;
esac
# to be aesthetically quoted because they are evaled later.
arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
case $arg in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
# to be aesthetically quoted because they are evaled later.
arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
case $arg in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
case "$temp_rpath " in
*" $dir "*) ;;
*" $absdir "*) ;;
- *) temp_rpath="$temp_rpath $dir" ;;
+ *) temp_rpath="$temp_rpath $absdir" ;;
esac
fi
fi
link_static=no # Whether the deplib will be linked statically
- use_static_libs="$prefer_static_libs"
- if test "$use_static_libs" = built && test "$installed" = yes ; then
- use_static_libs=no
- fi
if test -n "$library_names" &&
- { test "$use_static_libs" = no || test -z "$old_library"; }; then
+ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
if test "$installed" = no; then
notinst_deplibs="$notinst_deplibs $lib"
need_relink=yes
add_dir="-L$dir"
# Try looking first in the location we're being installed to.
if test -n "$inst_prefix_dir"; then
- case "$libdir" in
+ case $libdir in
[\\/]*)
add_dir="$add_dir -L$inst_prefix_dir$libdir"
;;
add_dir="-L$libdir"
# Try looking first in the location we're being installed to.
if test -n "$inst_prefix_dir"; then
- case "$libdir" in
+ case $libdir in
[\\/]*)
add_dir="$add_dir -L$inst_prefix_dir$libdir"
;;
fi
fi
else
- convenience="$convenience $dir/$old_library"
- old_convenience="$old_convenience $dir/$old_library"
deplibs="$dir/$old_library $deplibs"
link_static=yes
fi
if test "$?" -eq 0 ; then
ldd_output=`ldd conftest`
for i in $deplibs; do
- name="`expr $i : '-l\(.*\)'`"
+ name=`expr $i : '-l\(.*\)'`
# If $name is empty we are operating on a -L argument.
if test "$name" != "" && test "$name" -ne "0"; then
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
# Error occurred in the first compile. Let's try to salvage
# the situation: Compile a separate program for each library.
for i in $deplibs; do
- name="`expr $i : '-l\(.*\)'`"
+ name=`expr $i : '-l\(.*\)'`
# If $name is empty we are operating on a -L argument.
if test "$name" != "" && test "$name" != "0"; then
$rm conftest
set dummy $deplibs_check_method
file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
for a_deplib in $deplibs; do
- name="`expr $a_deplib : '-l\(.*\)'`"
+ name=`expr $a_deplib : '-l\(.*\)'`
# If $name is empty we are operating on a -L argument.
if test "$name" != "" && test "$name" != "0"; then
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
set dummy $deplibs_check_method
match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
for a_deplib in $deplibs; do
- name="`expr $a_deplib : '-l\(.*\)'`"
+ name=`expr $a_deplib : '-l\(.*\)'`
# If $name is empty we are operating on a -L argument.
if test -n "$name" && test "$name" != "0"; then
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
# The command line is too long to execute in one step.
$show "using reloadable object file for export list..."
skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
fi
done
IFS="$save_ifs"
fi
fi
- if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*"` &&
+ if test "X$skipped_export" != "X:" &&
+ len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
:
else
do
eval test_cmds=\"$reload_cmds $objlist $last_robj\"
if test "X$objlist" = X ||
- { len=`expr "X$test_cmds" : ".*"` &&
+ { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
test "$len" -le "$max_cmd_len"; }; then
objlist="$objlist $obj"
else
IFS="$save_ifs"
eval cmd=\"$cmd\"
$show "$cmd"
- $run eval "$cmd" || exit $?
+ $run eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+ fi
+
+ exit $lt_exit
+ }
done
IFS="$save_ifs"
# Restore the uninstalled library and exit
if test "$mode" = relink; then
$run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ fi
+ fi
+
exit $EXIT_SUCCESS
fi
if test -z "$export_symbols"; then
export_symbols="$output_objdir/$outputname.exp"
$run $rm $export_symbols
- $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
else
$run eval "${SED} -e 's/\([ ][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
$run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
EOF
cat >> $cwrappersource <<"EOF"
+ return 127;
}
void *
# Backslashes separate directories on plain windows
*-*-mingw | *-*-os2*)
$echo >> $output "\
- exec \$progdir\\\\\$program \${1+\"\$@\"}
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
"
;;
*)
$echo >> $output "\
- exec \$progdir/\$program \${1+\"\$@\"}
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
"
;;
esac
fi
else
# The program doesn't exist.
- \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
\$echo \"This script is just a wrapper for \$program.\" 1>&2
$echo \"See the $PACKAGE documentation for more information.\" 1>&2
exit $EXIT_FAILURE
oldobjs="$objlist $obj"
objlist="$objlist $obj"
eval test_cmds=\"$old_archive_cmds\"
- if len=`expr "X$test_cmds" : ".*"` &&
+ if len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
test "$len" -le "$max_cmd_len"; then
:
else
# install_prog (especially on Windows NT).
if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
# Allow the use of GNU shtool's install command.
- $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then
+ $echo "X$nonopt" | grep shtool > /dev/null; then
# Aesthetically quote it.
arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
case $arg in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
shift
else
install_prog=
- arg="$nonopt"
+ arg=$nonopt
fi
# The real first argument should be the name of the installation program.
# Aesthetically quote it.
arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
case $arg in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
do
if test -n "$dest"; then
files="$files $dest"
- dest="$arg"
+ dest=$arg
continue
fi
case $arg in
-d) isdir=yes ;;
- -f) prev="-f" ;;
- -g) prev="-g" ;;
- -m) prev="-m" ;;
- -o) prev="-o" ;;
+ -f)
+ case " $install_prog " in
+ *[\\\ /]cp\ *) ;;
+ *) prev=$arg ;;
+ esac
+ ;;
+ -g | -m | -o) prev=$arg ;;
-s)
stripme=" -s"
continue
;;
- -*) ;;
-
+ -*)
+ ;;
*)
# If the previous option needed an argument, then skip it.
if test -n "$prev"; then
prev=
else
- dest="$arg"
+ dest=$arg
continue
fi
;;
# Aesthetically quote the argument.
arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
case $arg in
- *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "")
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
if test "$#" -gt 0; then
# Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
for linkname
do
if test "$linkname" != "$realname"; then
- $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
- $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+ $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
fi
done
fi
IFS="$save_ifs"
eval cmd=\"$cmd\"
$show "$cmd"
- $run eval "$cmd" || exit $?
+ $run eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+ fi
+
+ exit $lt_exit
+ }
done
IFS="$save_ifs"
fi
notinst_deplibs=
relink_command=
- # To insure that "foo" is sourced, and not "foo.exe",
- # finese the cygwin/MSYS system by explicitly sourcing "foo."
- # which disallows the automatic-append-.exe behavior.
- case $build in
- *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
- *) wrapperdot=${wrapper} ;;
- esac
+ # Note that it is not necessary on cygwin/mingw to append a dot to
+ # foo even if both foo and FILE.exe exist: automatic-append-.exe
+ # behavior happens only for exec(3), not for open(2)! Also, sourcing
+ # `FILE.' does not work on cygwin managed mounts.
+ #
# If there is no directory component, then add one.
- case $file in
- */* | *\\*) . ${wrapperdot} ;;
- *) . ./${wrapperdot} ;;
+ case $wrapper in
+ */* | *\\*) . ${wrapper} ;;
+ *) . ./${wrapper} ;;
esac
# Check the variables that should have been set.
done
relink_command=
- # To insure that "foo" is sourced, and not "foo.exe",
- # finese the cygwin/MSYS system by explicitly sourcing "foo."
- # which disallows the automatic-append-.exe behavior.
- case $build in
- *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
- *) wrapperdot=${wrapper} ;;
- esac
+ # Note that it is not necessary on cygwin/mingw to append a dot to
+ # foo even if both foo and FILE.exe exist: automatic-append-.exe
+ # behavior happens only for exec(3), not for open(2)! Also, sourcing
+ # `FILE.' does not work on cygwin managed mounts.
+ #
# If there is no directory component, then add one.
- case $file in
- */* | *\\*) . ${wrapperdot} ;;
- *) . ./${wrapperdot} ;;
+ case $wrapper in
+ */* | *\\*) . ${wrapper} ;;
+ *) . ./${wrapper} ;;
esac
outputname=
fi
# remove .exe since cygwin /usr/bin/install will append another
- # one anyways
+ # one anyway
case $install_prog,$host in
*/usr/bin/install*,*cygwin*)
case $file:$destfile in
if (havedn)
retval = domodrdn( ld, entrydn, rdn, newSuperior, remove_old_RDN );
else while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) {
- if ( *buf != '\0' ) { /* blank lines optional, skip */
+ if ( *buf != '\n' ) { /* blank lines optional, skip */
buf[ strlen( buf ) - 1 ] = '\0'; /* remove nl */
if ( havedn ) { /* have DN, get RDN */
rc = ldap_parse_result( ld, res,
&code, &matcheddn, &text, &refs, NULL, 0 );
-
if( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_parse_result" );
rc = EXIT_FAILURE;
}
rc = ldap_parse_extended_result( ld, res, &retoid, &retdata, 1 );
-
if( rc != LDAP_SUCCESS ) {
- ldap_perror( ld, "ldap_parse_result" );
+ ldap_perror( ld, "ldap_parse_extended_result" );
rc = EXIT_FAILURE;
goto done;
}
OL_ARG_WITH(threads,[ --with-threads with threads],
auto, [auto nt posix mach pth lwp yes no manual] )
OL_ARG_WITH(tls,[ --with-tls with TLS/SSL support],
- auto, [auto ssleay openssl yes no] )
+ auto, [auto openssl yes no] )
OL_ARG_WITH(yielding_select,[ --with-yielding-select with implicitly yielding select],
auto, [auto yes no manual] )
OL_ARG_WITH(multiple_precision,[ --with-multiple-precision
ol_link_tls=no
if test $ol_with_tls != no ; then
- AC_CHECK_HEADERS(openssl/ssl.h ssl.h)
-
- if test $ac_cv_header_openssl_ssl_h = yes ||
- test $ac_cv_header_ssl_h = yes ; then
- AC_CHECK_LIB(ssl, SSLeay_add_ssl_algorithms,
- [have_ssleay=yes
- need_rsaref=no],
- [have_ssleay=no],
+ AC_CHECK_HEADERS(openssl/ssl.h)
+
+ if test $ac_cv_header_openssl_ssl_h = yes ; then
+ AC_CHECK_LIB(ssl, SSL_library_init,
+ [have_openssl=yes
+ need_rsaref=no], [have_openssl=no],
[-lcrypto])
-
- if test $have_ssleay = no ; then
- AC_CHECK_LIB(ssl, SSL_library_init,
- [have_ssleay=yes
- need_rsaref=no], [have_ssleay=no],
- [-lcrypto])
- fi
- if test $have_ssleay = no ; then
+ if test $have_openssl = no ; then
AC_CHECK_LIB(ssl, ssl3_accept,
- [have_ssleay=yes
- need_rsaref=yes], [have_ssleay=no],
+ [have_openssl=yes
+ need_rsaref=yes], [have_openssl=no],
[-lcrypto -lRSAglue -lrsaref])
fi
- if test $have_ssleay = yes ; then
+ if test $have_openssl = yes ; then
ol_with_tls=found
ol_link_tls=yes
- AC_DEFINE(HAVE_SSLEAY, 1,
- [define if you have SSLeay or OpenSSL])
+ AC_DEFINE(HAVE_OPENSSL, 1,
+ [define if you have OpenSSL])
if test $need_rsaref = yes; then
AC_DEFINE(HAVE_RSAREF, 1,
- [define if you have RSAref])
+ [define if OpenSSL needs RSAref])
TLS_LIBS="-lssl -lcrypto -lRSAglue -lrsaref"
else
case "$ol_mp_support" in
bignum)
AC_DEFINE(HAVE_BIGNUM, 1,
- [define if you have SSLeay or OpenSSL's BIGNUM])
+ [define if you have OpenSSL's BIGNUM])
;;
gmp)
AC_DEFINE(HAVE_GMP, 1, [define if you have -lgmp])
getspnam \
gettimeofday \
initgroups \
+ inet_ntoa_b \
lockf \
memcpy \
memmove \
#include <slap.h>
#include <ac/errno.h>
+#include <ac/string.h>
#ifdef DO_KRB5
-#include <ac/string.h>
#include <lber.h>
#include <lber_pvt.h>
#include <lutil.h>
#ifdef DO_SAMBA
#include <openssl/des.h>
#include <openssl/md4.h>
+#include "ldap_utf8.h"
static AttributeDescription *ad_sambaLMPassword;
static AttributeDescription *ad_sambaNTPassword;
* 256 UCS2 characters, not 256 bytes...
*/
char hbuf[HASHLEN];
- int i;
MD4_CTX ctx;
if (passwd->bv_len > MAX_PWLEN*2)
Operation *op,
SlapReply *rs )
{
- int i, rc;
+ int rc;
req_pwdexop_s *qpw = &op->oq_pwdexop;
Entry *e;
- Attribute *a;
Modifications *ml;
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
krb5_error_code ret;
hdb_entry ent;
struct berval *keys;
- int kvno;
+ int kvno, i;
+ Attribute *a;
if ( !is_entry_objectclass(e, oc_krb5KDCEntry, 0 ) ) break;
keys[i].bv_val = (char *)buf;
keys[i].bv_len = len;
}
- keys[i].bv_val = NULL;
- keys[i].bv_len = 0;
+ BER_BVZERO( &keys[i] );
_kadm5_free_keys(kadm_context, ent.keys.len, ent.keys.val);
ml->sml_values[0].bv_val = ch_malloc( 64 );
ml->sml_values[0].bv_len = sprintf(ml->sml_values[0].bv_val,
"%d", kvno+1 );
- ml->sml_values[1].bv_val = NULL;
- ml->sml_values[1].bv_len = 0;
+ BER_BVZERO( &ml->sml_values[1] );
ml->sml_nvalues = NULL;
} while(0);
#endif /* DO_KRB5 */
qpw->rs_mods = ml;
keys = ch_malloc( 2 * sizeof(struct berval) );
- keys[1].bv_val = NULL;
- keys[1].bv_len = 0;
+ BER_BVZERO( &keys[1] );
nthash( &pwd, keys );
ml->sml_desc = ad_sambaNTPassword;
qpw->rs_mods = ml;
keys = ch_malloc( 2 * sizeof(struct berval) );
- keys[1].bv_val = NULL;
- keys[1].bv_len = 0;
+ BER_BVZERO( &keys[1] );
lmhash( &pwd, keys );
ml->sml_desc = ad_sambaLMPassword;
qpw->rs_mods = ml;
keys = ch_malloc( 2 * sizeof(struct berval) );
- keys[1].bv_val = NULL;
- keys[1].bv_len = 0;
- keys[0].bv_val = ch_malloc(16);
- keys[0].bv_len = sprintf(keys[0].bv_val, "%d",
- slap_get_time());
+ keys[0].bv_val = ch_malloc( STRLENOF( "9223372036854775807L" ) + 1 );
+ keys[0].bv_len = snprintf(keys[0].bv_val,
+ STRLENOF( "9223372036854775807L" ) + 1,
+ "%ld", slap_get_time());
+ BER_BVZERO( &keys[1] );
ml->sml_desc = ad_sambaPwdLastSet;
ml->sml_op = LDAP_MOD_REPLACE;
Small projects
--------------
+Add BSD kqueue(2) support to slapd(8)
Add DSML capabilities to command line tools
Add LDIFv2 (XML) support to command line tools
Implement authPassword (RFC 3112)
-# Copyright 1999-2003, The OpenLDAP Foundation, All Rights Reserved.
+# Copyright 1999-2005, The OpenLDAP Foundation, All Rights Reserved.
# COPYING RESTRICTIONS APPLY, see COPYRIGHT.
H1: Using TLS
provide a seed for the pseudo-random number generator, and it doesn't
need very much data to work.
+H4: TLSEphemeralDHParamFile <filename>
+
+This directive specifies the file that contains parameters for Diffie-Hellman
+ephemeral key exchange. This is required in order to use a DSA certificate on
+the server side (i.e. {{EX:TLSCertificateKeyFile}} points to a DSA key).
+Multiple sets of parameters can be included in the file; all of them will
+be processed. Parameters can be generated using the following command
+
+> openssl dhparam [-dsaparam] -out <filename> <numbits>
+
H4: TLSVerifyClient { never | allow | try | demand }
This directive specifies what checks to perform on client certificates
encoded Unicode (version 3.2).
.LP
Distinguished names (DN) (and relative distinguished names (RDN) to
-be passed to the LDAP routines should conform to RFC 2253. The
-.BR ldap_explode_dn (3)
-routines can be used to work with DNs.
+be passed to the LDAP routines should conform to RFC 2253 UTF\-8
+string representation.
.LP
Search filters to be passed to the search routines are to be
-constructed by hand and should conform to RFC 2254.
+constructed by hand and should conform to RFC 2254 UTF\-8
+string representation.
.LP
LDAP URL are to be passed to routines are expected to conform
-to RFC 2255.
-The
+to RFC 2255 syntax. The
.BR ldap_url (3)
routines can be used to work with LDAP URLs.
.SH DISPLAYING RESULTS
.SM ldap_get_dn(3)
extract the DN from an entry
.TP
-.SM ldap_explode_dn(3)
-convert a DN into its component parts (deprecated)
-.TP
-.SM ldap_explode_rdn(3)
-convert an RDN into its component parts (deprecated)
-.TP
.SM ldap_get_values_len(3)
return an attribute's values with lengths
.TP
.BR limits
for an explanation of the different flags.
.TP
-.B ucdata-path <path>
-Specify the path to the directory containing the Unicode character
-tables. The default path is DATADIR/ucdata.
+.B tool-threads <integer>
+Specify the maximum number of threads to use in tool mode.
+This should not be greater than the number of CPUs in the system.
+The default is 1.
+.\"ucdata-path is obsolete / ignored...
+.\".TP
+.\".B ucdata-path <path>
+.\"Specify the path to the directory containing the Unicode character
+.\"tables. The default path is DATADIR/ucdata.
.SH TLS OPTIONS
If
.B slapd
file. Currently, the private key must not be protected with a password, so
it is of critical importance that it is protected carefully.
.TP
+.B TLSDHParamFile <filename>
+This directive specifies the file that contains parameters for Diffie-Hellman
+ephemeral key exchange. This is required in order to use a DSA certificate on
+the server. If multiple sets of parameters are present in the file, all of
+them will be processed.
+.TP
.B TLSRandFile <filename>
Specifies the file to obtain random bits from when /dev/[u]random
is not available. Generally set to the name of the EGD/PRNGD socket.
.B [credentials=<passwd>]
.B [realm=<realm>]
.B [secprops=<properties>]
+.B [logbase=<base DN>]
+.B [logfilter=<filter str>]
+.B [syncdata=default|accesslog|changelog]
.RS
Specify the current database as a replica which is kept up-to-date with the
master content by establishing the current
option. A non default SASL realm can be set with the
.B realm
option.
+
+Rather than replicating whole entries, the consumer can query logs of
+data modifications. This mode of operation is referred to as \fIdelta
+syncrepl\fP. In addition to the above parameters, the
+.B logbase
+and
+.B logfilter
+parameters must be set appropriately for the log that will be used. The
+.B syncdata
+parameter must be set to either "accesslog" if the log conforms to the
+.BR slapo-accesslog (5)
+log format, or "changelog" if the log conforms
+to the obsolete \fIchangelog\fP format. If the
+.B syncdata
+parameter is omitted or set to "default" then the log parameters are
+ignored.
.RE
.TP
.B updatedn <dn>
.B ldif
This database uses the filesystem to build the tree structure
of the database, using plain ascii files to store data.
-Its usage should be limited to very simple databases, where performances
-are not a requirement.
+Its usage should be limited to very simple databases, where performance
+is not a requirement.
.TP
.B meta
This backend performs basic LDAP proxying with respect to a set of
-remote LDAP servers. It is an enhancement of the ldap backend. The
-proxy cache extension of meta backend provides answering of search
-requests from the proxy using results of previously cached requests.
+remote LDAP servers. It is an enhancement of the ldap backend.
.TP
.B monitor
This backend provides information about the running status of the slapd
.B pcache
Proxycache.
This overlay allows caching of LDAP search requests in a local database.
+It is most often used with the ldap or meta backends.
.TP
.B ppolicy
Password Policy.
a given database to be reviewed using arbitrary LDAP queries, instead of
just logging to local flat text files. Configuration options are available
for selecting a subset of operation types to log, and to automatically
-prune older log records from the logging database. Log records are stored
-with a custom schema to assure their readability whether viewed as LDIF
-or in raw form.
+prune older log records from the logging database. Log records are stored
+with audit schema (see below) to assure their readability whether viewed
+as LDIF or in raw form.
.SH CONFIGURATION
These
.B slapd.conf
and
.B interval
are specified as a time span in days, hours, minutes, and seconds. The
-time format is [dd+]hh:mm[:ss] i.e., the days and seconds components are
-optional but hours and minutes are required. Each numeric field must be
-exactly two digits. For example
+time format is [ddd+]hh:mm[:ss] i.e., the days and seconds components are
+optional but hours and minutes are required. Except for days, which can
+be up to 5 digits, each numeric field must be exactly two digits. For example
.RS
.RS
.PD 0
.TP
-logpurge 02+00:00 01+00:00
+logpurge 2+00:00 1+00:00
.RE
.PD
would specify that the log database should be scanned every day for old
specifying an eq index on the
.B reqStart
attribute will greatly benefit the performance of the purge operation.
+.RE
+.TP
+.B logsuccess TRUE | FALSE
+If set to TRUE then log records will only be generated for successful
+requests, i.e., requests that produce a result code of 0 (LDAP_SUCCESS).
+If FALSE, log records are generated for all requests whether they
+succeed or not. The default is FALSE.
.SH EXAMPLES
.LP
logops writes reads
.fi
-.SH OBJECT CLASSES
+.SH SCHEMA
The
.B accesslog
-overlay defines a number of object classes for use in the logs. There is
+overlay utilizes the "audit" schema described herein.
+This schema is specifically designed for
+.B accesslog
+auditing and is not intended to be used otherwise. It is also
+noted that the schema describe here is
+.I a work in
+.IR progress ,
+and hence subject to change without notice.
+The schema is loaded automatically by the overlay.
+
+The schema includes a number of object classes and associated
+attribute types as described below.
+
+There is
a basic
.B auditObject
class from which two additional classes,
SUP top STRUCTURAL
MUST ( reqStart $ reqType $ reqSession )
MAY ( reqDN $ reqAuthzID $ reqControls $ reqRespControls $
- reqEnd $ reqResult $ reqMessage ) )
+ reqEnd $ reqResult $ reqMessage $ reqReferral ) )
.RE
.P
Note that all of the OIDs used in the logging schema currently reside
.BR search ,
etc. For extended operations, the type also includes the OID of the
extended operation, e.g.
-.B extended(1.2.3.4.1)
+.B extended(1.1.1.1)
The
.B reqSession
.B reqMessage
attribute.
+The
+.B reqReferral
+attribute carries any referrals that were returned with the result of the
+request.
+
Operation-specific classes are defined with additional attributes to carry
all of the relevant parameters associated with the operation:
.B Add
class inherits from the
.B auditWriteObject
-class. The Add and Modify classes are essentially the same. The
+class. The Add and Modify classes are very similar. The
.B reqMod
attribute carries all of the attributes of the original entry being added.
(Or in the case of a Modify operation, all of the modifications being
performed.) The values are formatted as
.RS
-.RS
.PD 0
.TP
attribute:<+|-|=|#> [ value]
.RE
+.RE
.PD
Where '+' indicates an Add of a value, '-' for Delete, '=' for Replace,
and '#' for Increment. In an Add operation, all of the reqMod values will
have the '+' designator.
-.RE
.P
-
.LP
.RS 4
( 1.3.6.1.4.1.4203.666.11.5.2.6
NAME 'auditBind'
DESC 'Bind operation'
SUP auditObject STRUCTURAL
- MUST reqMethod )
+ MUST ( reqVersion $ reqMethod ) )
.RE
.P
The
.B Bind
-class just adds the
+class includes the
+.B reqVersion
+attribute which contains the LDAP protocol version specified in the Bind
+as well as the
.B reqMethod
attribute which contains the Bind Method used in the Bind. This will be
the string
.LP
.RS 4
( 1.3.6.1.4.1.4203.666.11.5.2.8
+ NAME 'auditDelete'
+ DESC 'Delete operation'
+ SUP auditWriteObject STRUCTURAL
+ MAY reqOld )
+.RE
+.P
+The
+.B Delete
+operation needs no further parameters. However, the
+.B reqOld
+attribute may optionally be used to record the contents of the entry prior
+to its deletion. The values are formatted as
+.RS
+.PD 0
+.TP
+attribute: value
+.RE
+.PD
+This option is not yet implemented.
+
+.LP
+.RS 4
+( 1.3.6.1.4.1.4203.666.11.5.2.9
NAME 'auditModify'
DESC 'Modify operation'
SUP auditWriteObject STRUCTURAL
- MUST reqMod )
+ MAY reqOld MUST reqMod )
.RE
.P
The
.B Modify
-operation has already been described.
+operation contains a description of modifications in the
+.B reqMod
+attribute, which was already described above in the Add operation. It may
+optionally contain the previous contents of any modified attributes in the
+.B reqOld
+attribute, using the same format as described above for the Delete operation.
+This option is not yet implemented.
.LP
.RS 4
-( 1.3.6.1.4.1.4203.666.11.5.2.9
+( 1.3.6.1.4.1.4203.666.11.5.2.10
NAME 'auditModRDN'
DESC 'ModRDN operation'
SUP auditWriteObject STRUCTURAL
.LP
.RS 4
-( 1.3.6.1.4.1.4203.666.11.5.2.10
+( 1.3.6.1.4.1.4203.666.11.5.2.11
NAME 'auditSearch'
DESC 'Search operation'
SUP auditReadObject STRUCTURAL
- MUST ( reqScope $ reqAttrsOnly )
+ MUST ( reqScope $ reqDerefAliases $ reqAttrsOnly )
MAY ( reqFilter $ reqAttr $ reqEntries $ reqSizeLimit $
reqTimeLimit ) )
.RE
.B Search
class the
.B reqScope
-attribute contains the scope of the original search request, i.e.
+attribute contains the scope of the original search request, using the
+values specified for the LDAP URL format. I.e.
.BR base ,
-.BR onelevel ,
-.BR subtree ,
+.BR one ,
+.BR sub ,
+or
+.BR subord .
+The
+.B reqDerefAliases
+attribute is one of
+.BR never ,
+.BR finding ,
+.BR searching ,
or
-.BR subordinate .
+.BR always ,
+denoting how aliases will be processed during the search.
The
.B reqAttrsOnly
attribute is a Boolean value showing
.LP
.RS 4
-( 1.3.6.1.4.1.4203.666.11.5.2.11
+( 1.3.6.1.4.1.4203.666.11.5.2.12
NAME 'auditExtended'
DESC 'Extended operation'
SUP auditObject STRUCTURAL
May result in a lot of unnecessary overhead.
.SH SCHEMA
-The following schema items are created and used by the overlay:
+The
+.B retcode
+overlay utilizes the "return code" schema described herein.
+This schema is specifically designed for use with this
+overlay and is not intended to be used otherwise.
+It is also noted that the schema describe here is
+.I a work in
+.IR progress ,
+and hence subject to change without notice.
+The schema is loaded automatically by the overlay.
+
+The schema includes a number of object classes and associated
+attribute types as described below.
+
.LP
The error code:
.RS 4
operations (except Adds) are recorded in the log.
When using the session log, it is helpful to set an eq index on the
entryUUID attribute in the underlying database.
+.TP
+.B syncprov-nopresent TRUE | FALSE
+Specify that the Present phase of refreshing should be skipped. This value
+should only be set TRUE for a syncprov instance on top of a log database
+(such as one managed by the accesslog overlay).
+The default is FALSE.
+.TP
+.B syncprov-reloadhint TRUE | FALSE
+Specify that the overlay should honor the reloadHint flag in the Syncrepl
+Control. In OpenLDAP releases 2.3.11 and earlier the Syncrepl consumer did
+not properly set this flag, so the overlay must ignore it. This option
+should be set TRUE when working with newer releases that properly support
+this flag. It must be set TRUE when using the accesslog overlay for
+delta-based Syncrepl support. The default is FALSE.
.SH FILES
.TP
ETCDIR/slapd.conf
default slapd configuration file
.SH SEE ALSO
-.BR slapd.conf (5).
+.BR slapd.conf (5),
+.BR slapo-accesslog (5).
OpenLDAP Administrator's Guide.
.B SBINDIR/slapadd
.B [\-v]
.B [\-c]
+.B [\-g]
.B [\-u]
.B [\-q]
.B [\-w]
the database.
Databases configured as
.B subordinate
-of this one are also updated.
+of this one are also updated, unless \fB-g\fP is specified.
The LDIF input is read from standard input or the specified file.
.LP
As
.B \-c
enable continue (ignore errors) mode.
.TP
+.B \-g
+disable subordinate gluing. Only the specified database will be
+processed, and not its glued subordinates (if any).
+.TP
.B \-u
enable dry-run (don't write to backend) mode.
.TP
.B [\-v]
.B [\-d level]
.B [\-f slapd.conf]
+.B [\-F confdir]
.B [\-M mech]
.B [\-R realm]
.B [\-U authcID]
.BR slapd.conf (5)
file.
.TP
+.BI \-F " confdir"
+specify a config directory.
+If both
+.B -f
+and
+.B -F
+are specified, the config file will be read and converted to
+config directory format and written to the specified directory.
+If neither option is specified, an attempt to read the
+default config directory wll be made before trying to use the default
+config file. If a valid config directory exists then the
+default config file is ignored.
+.TP
.BI \-M " mech"
specify a mechanism.
.TP
.B SBINDIR/slapcat
.B [\-v]
.B [\-c]
+.B [\-g]
.B [\-d level]
.B [\-b suffix]
.B [\-n dbnum]
.B [\-a filter]
.B [\-s subtree-dn]
.B [\-f slapd.conf]
+.B [\-F confdir]
.B [\-l ldif-file]
.B
.LP
the specified file.
Databases configured as
.B subordinate
-of this one are also output.
+of this one are also output, unless \fB-g\fP is specified.
.LP
The LDIF generated by this tool is suitable for use with
.BR slapadd (8).
.B \-c
Enable continue (ignore errors) mode.
.TP
+.B \-g
+disable subordinate gluing. Only the specified database will be
+processed, and not its glued subordinates (if any).
+.TP
.BI \-d " level"
Enable debugging messages as defined by the specified
.IR level .
.BR slapd.conf (5)
file.
.TP
+.BI \-F " confdir"
+specify a config directory.
+If both
+.B -f
+and
+.B -F
+are specified, the config file will be read and converted to
+config directory format and written to the specified directory.
+If neither option is specified, an attempt to read the
+default config directory wll be made before trying to use the default
+config file. If a valid config directory exists then the
+default config file is ignored.
+.TP
.BI \-l " ldif-file"
Write LDIF to specified file instead of standard output.
.SH LIMITATIONS
.BR slapd.conf (5)
file.
.TP
+.BI \-F " confdir"
+specify a config directory.
+If both
+.B -f
+and
+.B -F
+are specified, the config file will be read and converted to
+config directory format and written to the specified directory.
+If neither option is specified, an attempt to read the
+default config directory wll be made before trying to use the default
+config file. If a valid config directory exists then the
+default config file is ignored.
+.TP
.BI \-N
only output a normalized form of the DN, suitable to be used
in a normalization tool; incompatible with
.B SBINDIR/slapindex
.B [\-v]
.B [\-c]
+.B [\-g]
.B [\-q]
.B [\-d level]
.B [\-b suffix]
of all entries.
Databases configured as
.B subordinate
-of this one are also re-indexed.
+of this one are also re-indexed, unless \fB-g\fP is specified.
.SH OPTIONS
.TP
.B \-v
.B \-c
enable continue (ignore errors) mode.
.TP
+.B \-g
+disable subordinate gluing. Only the specified database will be
+processed, and not its glued subordinates (if any).
+.TP
.B \-q
enable quick (fewer integrity checks) mode. Performs no consistency checks
when writing the database. Improves indexing time, but if any errors or
#define LDAP_OPT_X_TLS_CRLCHECK 0x600b
#define LDAP_OPT_X_TLS_CONNECT_CB 0x600c
#define LDAP_OPT_X_TLS_CONNECT_ARG 0x600d
+#define LDAP_OPT_X_TLS_DHFILE 0x600e
#define LDAP_OPT_X_TLS_NEVER 0
#define LDAP_OPT_X_TLS_HARD 1
/* LDAP Controls */
/* standard track controls */
-#define LDAP_CONTROL_MANAGEDSAIT "2.16.840.1.113730.3.4.2" /* RFC 3296 */
-#define LDAP_CONTROL_SUBENTRIES "1.3.6.1.4.1.4203.1.10.1" /* RFC 3672 */
-#define LDAP_CONTROL_PAGEDRESULTS "1.2.840.113556.1.4.319" /* RFC 2696 */
-#define LDAP_CONTROL_VALUESRETURNFILTER "1.2.826.0.1.334810.2.3" /* RFC 3876 */
-#define LDAP_CONTROL_ASSERT "1.3.6.1.1.12"
-#define LDAP_CONTROL_PRE_READ "1.3.6.1.1.13.1"
-#define LDAP_CONTROL_POST_READ "1.3.6.1.1.13.2"
+#define LDAP_CONTROL_MANAGEDSAIT "2.16.840.1.113730.3.4.2" /* RFC 3296 */
+#define LDAP_CONTROL_PROXY_AUTHZ "2.16.840.1.113730.3.4.18" /* RFC TBD */
+#define LDAP_CONTROL_SUBENTRIES "1.3.6.1.4.1.4203.1.10.1" /* RFC 3672 */
+
+#define LDAP_CONTROL_VALUESRETURNFILTER "1.2.826.0.1.334810.2.3"/* RFC 3876 */
+#define LDAP_CONTROL_ASSERT "1.3.6.1.1.12" /* RFC TBD */
+#define LDAP_CONTROL_PRE_READ "1.3.6.1.1.13.1" /* RFC TBD */
+#define LDAP_CONTROL_POST_READ "1.3.6.1.1.13.2" /* RFC TBD */
/* standard track - not implemented in slapd(8) */
#define LDAP_CONTROL_SORTREQUEST "1.2.840.113556.1.4.473" /* RFC 2891 */
#define LDAP_CONTROL_SORTRESPONSE "1.2.840.113556.1.4.474" /* RFC 2891 */
-/* but not yet formalized controls */
-#define LDAP_CONTROL_PROXY_AUTHZ "2.16.840.1.113730.3.4.18"
+/* non-standard track controls */
+#define LDAP_CONTROL_PAGEDRESULTS "1.2.840.113556.1.4.319" /* RFC 2696 */
+
+/* Password policy Controls *//* work in progress */
+/* ITS#3458: released; disabled by default */
+#define LDAP_CONTROL_PASSWORDPOLICYREQUEST "1.3.6.1.4.1.42.2.27.8.5.1"
+#define LDAP_CONTROL_PASSWORDPOLICYRESPONSE "1.3.6.1.4.1.42.2.27.8.5.1"
/* various works in progress */
#define LDAP_CONTROL_NOOP "1.3.6.1.4.1.4203.666.5.2"
#define LDAP_CONTROL_SLURP "1.3.6.1.4.1.4203.666.5.13"
#define LDAP_CONTROL_VALSORT "1.3.6.1.4.1.4203.666.5.14"
-/* LDAP Duplicated Entry Control Extension *//* not implemented in slapd(8) */
-#define LDAP_CONTROL_DUPENT_REQUEST "2.16.840.1.113719.1.27.101.1"
-#define LDAP_CONTROL_DUPENT_RESPONSE "2.16.840.1.113719.1.27.101.2"
-#define LDAP_CONTROL_DUPENT_ENTRY "2.16.840.1.113719.1.27.101.3"
-#define LDAP_CONTROL_DUPENT LDAP_CONTROL_DUPENT_REQUEST
-
-/* LDAP Persistent Search Control *//* not implemented in slapd(8) */
-/* draft-ietf-ldapext-psearch-03.txt (expired) */
-#define LDAP_CONTROL_PERSIST_REQUEST "2.16.840.1.113730.3.4.3"
-#define LDAP_CONTROL_PERSIST_ENTRY_CHANGE_NOTICE "2.16.840.1.113730.3.4.7"
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_ADD 0x1
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_DELETE 0x2
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_MODIFY 0x4
-#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_RENAME 0x8
-
-/* LDAP VLV *//* not implemented in slapd(8) */
-#define LDAP_CONTROL_VLVREQUEST "2.16.840.1.113730.3.4.9"
-#define LDAP_CONTROL_VLVRESPONSE "2.16.840.1.113730.3.4.10"
-
-/* Password policy Controls *//* work in progress */
-/* ITS#3458: released; disabled by default */
-#define LDAP_CONTROL_PASSWORDPOLICYREQUEST "1.3.6.1.4.1.42.2.27.8.5.1"
-#define LDAP_CONTROL_PASSWORDPOLICYRESPONSE "1.3.6.1.4.1.42.2.27.8.5.1"
-
/* LDAP Sync -- draft-zeilenga-ldup-sync *//* submitted for publication */
#define LDAP_SYNC_OID "1.3.6.1.4.1.4203.1.9.1"
#define LDAP_CONTROL_SYNC LDAP_SYNC_OID ".1"
#define LDAP_REFERRALS_REQUIRED 3
#endif
-/* MS ActiveDirectory controls (for compatibility) */
-#define LDAP_CONTROL_X_DOMAIN_SCOPE "1.2.840.113556.1.4.1339"
-#define LDAP_CONTROL_X_PERMISSIVE_MODIFY "1.2.840.113556.1.4.1413"
+/* MS Active Directory controls (for compatibility) */
#define LDAP_CONTROL_X_INCREMENTAL_VALUES "1.2.840.113556.1.4.802"
-#define LDAP_CONTROL_X_TREE_DELETE "1.2.840.113556.1.4.805"
+#define LDAP_CONTROL_X_DOMAIN_SCOPE "1.2.840.113556.1.4.1339"
+#define LDAP_CONTROL_X_PERMISSIVE_MODIFY "1.2.840.113556.1.4.1413"
#define LDAP_CONTROL_X_SEARCH_OPTIONS "1.2.840.113556.1.4.1340"
-#define LDAP_SEARCH_FLAG_DOMAIN_SCOPE 1 /* do not generate referrals */
-#define LDAP_SEARCH_FLAG_PHANTOM_ROOT 2 /* search all NCs subordinate to base */
+#define LDAP_SEARCH_FLAG_DOMAIN_SCOPE 1 /* do not generate referrals */
+#define LDAP_SEARCH_FLAG_PHANTOM_ROOT 2 /* search all subordinate NCs */
+
+/* MS Active Directory controls - not implemented in slapd(8) */
+#define LDAP_CONTROL_X_TREE_DELETE "1.2.840.113556.1.4.805"
#define LDAP_CONTROL_X_EXTENDED_DN "1.2.840.113556.1.4.529"
+/* various expired works */
+/* LDAP Duplicated Entry Control Extension *//* not implemented in slapd(8) */
+#define LDAP_CONTROL_DUPENT_REQUEST "2.16.840.1.113719.1.27.101.1"
+#define LDAP_CONTROL_DUPENT_RESPONSE "2.16.840.1.113719.1.27.101.2"
+#define LDAP_CONTROL_DUPENT_ENTRY "2.16.840.1.113719.1.27.101.3"
+#define LDAP_CONTROL_DUPENT LDAP_CONTROL_DUPENT_REQUEST
+
+/* LDAP Persistent Search Control *//* not implemented in slapd(8) */
+#define LDAP_CONTROL_PERSIST_REQUEST "2.16.840.1.113730.3.4.3"
+#define LDAP_CONTROL_PERSIST_ENTRY_CHANGE_NOTICE "2.16.840.1.113730.3.4.7"
+#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_ADD 0x1
+#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_DELETE 0x2
+#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_MODIFY 0x4
+#define LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_RENAME 0x8
+
+/* LDAP VLV *//* not implemented in slapd(8) */
+#define LDAP_CONTROL_VLVREQUEST "2.16.840.1.113730.3.4.9"
+#define LDAP_CONTROL_VLVRESPONSE "2.16.840.1.113730.3.4.10"
+
+
/* LDAP Unsolicited Notifications */
#define LDAP_NOTICE_OF_DISCONNECTION "1.3.6.1.4.1.1466.20036" /* RFC 2251 */
#define LDAP_NOTICE_DISCONNECT LDAP_NOTICE_OF_DISCONNECTION
#define LDAP_EXOP_X_CANCEL LDAP_EXOP_CANCEL
/* various works in progress */
-
#define LDAP_EXOP_WHO_AM_I "1.3.6.1.4.1.4203.1.11.3"
#define LDAP_EXOP_X_WHO_AM_I LDAP_EXOP_WHO_AM_I
#define LDAP_SUBSTRING_FINAL ((ber_tag_t) 0x82U) /* context specific */
/* search scopes */
-#define LDAP_SCOPE_DEFAULT ((ber_int_t) -1) /* OpenLDAP extension */
#define LDAP_SCOPE_BASE ((ber_int_t) 0x0000)
#define LDAP_SCOPE_BASEOBJECT LDAP_SCOPE_BASE
#define LDAP_SCOPE_ONELEVEL ((ber_int_t) 0x0001)
#define LDAP_SCOPE_SUB LDAP_SCOPE_SUBTREE
#define LDAP_SCOPE_SUBORDINATE ((ber_int_t) 0x0003) /* OpenLDAP extension */
#define LDAP_SCOPE_CHILDREN LDAP_SCOPE_SUBORDINATE
+#define LDAP_SCOPE_DEFAULT ((ber_int_t) -1) /* OpenLDAP extension */
/* substring filter component types */
#define LDAP_SUBSTRING_INITIAL ((ber_tag_t) 0x80U) /* context specific */
#define LDAP_ALREADY_EXISTS 0x44
#define LDAP_NO_OBJECT_CLASS_MODS 0x45
#define LDAP_RESULTS_TOO_LARGE 0x46 /* CLDAP */
-#define LDAP_AFFECTS_MULTIPLE_DSAS 0x47 /* LDAPv3 */
+#define LDAP_AFFECTS_MULTIPLE_DSAS 0x47
#define LDAP_OTHER 0x50
#define LDAP_TOO_LATE 0x78
#define LDAP_CANNOT_CANCEL 0x79
+/* Assertion control (122) */
+#define LDAP_ASSERTION_FAILED 0x7A
+
/* Experimental result codes */
-#define LDAP_E_ERROR(n) LDAP_RANGE((n),0x1000,0x3FFF) /* experimental */
-#define LDAP_X_ERROR(n) LDAP_RANGE((n),0x4000,0xFFFF) /* private use */
+#define LDAP_E_ERROR(n) LDAP_RANGE((n),0x1000,0x3FFF)
-/* for the LDAP Sync operation */
-#define LDAP_SYNC_REFRESH_REQUIRED 0x4100
+/* LDAP Sync (4096) */
+#define LDAP_SYNC_REFRESH_REQUIRED 0x1000
-/* for the LDAP No-Op control */
-#define LDAP_NO_OPERATION 0x410e
-/* for the Assertion control */
-#define LDAP_ASSERTION_FAILED 0x410f
+/* Private Use result codes */
+#define LDAP_X_ERROR(n) LDAP_RANGE((n),0x4000,0xFFFF)
+
+#define LDAP_X_SYNC_REFRESH_REQUIRED 0x4100 /* defunct */
+#define LDAP_X_ASSERTION_FAILED 0x410f /* defunct */
+
+/* for the LDAP No-Op control */
+#define LDAP_X_NO_OPERATION 0x410e
/* for the Chaining Behavior control (consecutive result codes requested;
* see <draft-sermersheim-ldap-chaining> ) */
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
-#define LDAP_NO_REFERRALS_FOUND 0x4110
-#define LDAP_CANNOT_CHAIN 0x4111
+#define LDAP_X_NO_REFERRALS_FOUND 0x4110
+#define LDAP_X_CANNOT_CHAIN 0x4111
#endif
+
/* API Error Codes
*
* Based on draft-ietf-ldap-c-api-xx
* in search.c:
*/
LDAP_F( int )
+ldap_bv2escaped_filter_value LDAP_P((
+ struct berval *in,
+ struct berval *out ));
+
+LDAP_F( int )
ldap_search_ext LDAP_P((
LDAP *ld,
LDAP_CONST char *base,
/* define if Berkeley DB has DB_THREAD support */
#undef HAVE_BERKELEY_DB_THREAD
-/* define if you have SSLeay or OpenSSL's BIGNUM */
+/* define if you have OpenSSL's BIGNUM */
#undef HAVE_BIGNUM
/* Define to 1 if you have the <bits/types.h> header file. */
/* define to you inet_aton(3) is available */
#undef HAVE_INET_ATON
+/* Define to 1 if you have the `inet_ntoa_b' function. */
+#undef HAVE_INET_NTOA_B
+
/* Define to 1 if you have the `inet_ntop' function. */
#undef HAVE_INET_NTOP
/* if you have NT Threads */
#undef HAVE_NT_THREADS
+/* define if you have OpenSSL */
+#undef HAVE_OPENSSL
+
/* Define to 1 if you have the <openssl/bn.h> header file. */
#undef HAVE_OPENSSL_BN_H
/* define if you have res_query() */
#undef HAVE_RES_QUERY
-/* define if you have RSAref */
+/* define if OpenSSL needs RSAref */
#undef HAVE_RSAREF
/* Define to 1 if you have the <sasl.h> header file. */
/* Define to 1 if you have the <sql.h> header file. */
#undef HAVE_SQL_H
-/* define if you have SSLeay or OpenSSL */
-#undef HAVE_SSLEAY
-
-/* Define to 1 if you have the <ssl.h> header file. */
-#undef HAVE_SSL_H
-
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
rc = ldap_open_defconn( ld );
if( rc < 0 ) return ld->ld_errno;
- ber_sockbuf_ctrl( ld->ld_defconn->lconn_sb, LBER_SB_OPT_GET_FD, &sd );
+ ber_sockbuf_ctrl( ld->ld_defconn->lconn_sb,
+ LBER_SB_OPT_GET_FD, &sd );
if( sd == AC_SOCKET_INVALID ) {
ld->ld_errno = LDAP_LOCAL_ERROR;
ld->ld_defconn->lconn_sasl_authctx = NULL;
}
- { char *saslhost = ldap_host_connected_to( ld->ld_defconn->lconn_sb, "localhost" );
- rc = ldap_int_sasl_open( ld, ld->ld_defconn, saslhost );
- LDAP_FREE( saslhost );
+ {
+ char *saslhost = ldap_host_connected_to( ld->ld_defconn->lconn_sb,
+ "localhost" );
+ rc = ldap_int_sasl_open( ld, ld->ld_defconn, saslhost );
+ LDAP_FREE( saslhost );
}
if ( rc != LDAP_SUCCESS ) return rc;
#if !defined(_WIN32)
/* Check for local */
- if ( ldap_pvt_url_scheme2proto( ld->ld_defconn->lconn_server->lud_scheme ) == LDAP_PROTO_IPC ) {
- char authid[sizeof("uidNumber=4294967295+gidNumber=4294967295,"
+ if ( ldap_pvt_url_scheme2proto(
+ ld->ld_defconn->lconn_server->lud_scheme ) == LDAP_PROTO_IPC )
+ {
+ char authid[sizeof("gidNumber=4294967295+uidNumber=4294967295,"
"cn=peercred,cn=external,cn=auth")];
- sprintf( authid, "uidNumber=%d+gidNumber=%d,"
+ sprintf( authid, "gidNumber=%d+uidNumber=%d,"
"cn=peercred,cn=external,cn=auth",
- (int) geteuid(), (int) getegid() );
- (void) ldap_int_sasl_external( ld, ld->ld_defconn, authid, LDAP_PVT_SASL_LOCAL_SSF );
+ (int) getegid(), (int) geteuid() );
+ (void) ldap_int_sasl_external( ld, ld->ld_defconn, authid,
+ LDAP_PVT_SASL_LOCAL_SSF );
}
#endif
scred = NULL;
- rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls, &scred );
+ rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls,
+ &scred );
if ( ccred.bv_val != NULL ) {
#if SASL_VERSION_MAJOR < 2
if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
if( scred ) {
- if ( scred->bv_len ) {
- /* and server provided us with data? */
- Debug( LDAP_DEBUG_TRACE,
- "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
- rc, saslrc, scred->bv_len );
- }
+ /* and server provided us with data? */
+ Debug( LDAP_DEBUG_TRACE,
+ "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
+ rc, saslrc, scred ? scred->bv_len : -1 );
ber_bvfree( scred );
+ scred = NULL;
}
rc = ld->ld_errno;
goto done;
if( rc == LDAP_SUCCESS && saslrc == SASL_OK ) {
/* we're done, no need to step */
if( scred ) {
- if ( scred->bv_len ) {
- /* but server provided us with data! */
- Debug( LDAP_DEBUG_TRACE,
- "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
- rc, saslrc, scred->bv_len );
- }
+ /* but we got additional data? */
+ Debug( LDAP_DEBUG_TRACE,
+ "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
+ rc, saslrc, scred ? scred->bv_len : -1 );
+
ber_bvfree( scred );
rc = ld->ld_errno = LDAP_LOCAL_ERROR;
goto done;
}
do {
+ if( ! scred ) {
+ /* no data! */
+ Debug( LDAP_DEBUG_TRACE,
+ "ldap_int_sasl_bind: no data in step!\n",
+ 0, 0, 0 );
+ }
+
saslrc = sasl_client_step( ctx,
(scred == NULL) ? NULL : scred->bv_val,
(scred == NULL) ? 0 : scred->bv_len,
}
if( flags != LDAP_SASL_QUIET ) {
- saslrc = sasl_getprop( ctx, SASL_USERNAME, (SASL_CONST void **) &data );
+ saslrc = sasl_getprop( ctx, SASL_USERNAME,
+ (SASL_CONST void **) &data );
if( saslrc == SASL_OK && data && *data ) {
fprintf( stderr, "SASL username: %s\n", data );
}
#if SASL_VERSION_MAJOR < 2
- saslrc = sasl_getprop( ctx, SASL_REALM, (SASL_CONST void **) &data );
+ saslrc = sasl_getprop( ctx, SASL_REALM,
+ (SASL_CONST void **) &data );
if( saslrc == SASL_OK && data && *data ) {
fprintf( stderr, "SASL realm: %s\n", data );
}
{LDAP_OTHER, N_("Internal (implementation specific) error")},
+ {LDAP_CANCELLED, N_("Cancelled")},
+ {LDAP_NO_SUCH_OPERATION, N_("No Operation to Cancel")},
+ {LDAP_TOO_LATE, N_("Too Late to Cancel")},
+ {LDAP_CANNOT_CANCEL, N_("Cannot Cancel")},
+
+ {LDAP_ASSERTION_FAILED, N_("Assertion Failed")},
+ {LDAP_X_ASSERTION_FAILED, N_("Assertion Failed (X)")},
+
+ {LDAP_SYNC_REFRESH_REQUIRED, N_("Content Sync Refresh Required")},
+ {LDAP_X_SYNC_REFRESH_REQUIRED, N_("Content Sync Refresh Required (X)")},
+
+ {LDAP_X_NO_OPERATION, N_("No Operation (X)")},
+
/* API ResultCodes */
{LDAP_SERVER_DOWN, N_("Can't contact LDAP server")},
{LDAP_LOCAL_ERROR, N_("Local error")},
{LDAP_CLIENT_LOOP, N_("Client Loop")},
{LDAP_REFERRAL_LIMIT_EXCEEDED, N_("Referral Limit Exceeded")},
- {LDAP_SYNC_REFRESH_REQUIRED, N_("Content Sync Refresh Required")},
-
- {LDAP_NO_OPERATION, N_("No Operation")},
- {LDAP_ASSERTION_FAILED, N_("Assertion Failed")},
-
{LDAP_CUP_RESOURCES_EXHAUSTED, N_("LCUP Resources Exhausted")},
{LDAP_CUP_SECURITY_VIOLATION, N_("LCUP Security Violation")},
{LDAP_CUP_INVALID_DATA, N_("LCUP Invalid Data")},
{LDAP_CUP_UNSUPPORTED_SCHEME, N_("LCUP Unsupported Scheme")},
{LDAP_CUP_RELOAD_REQUIRED, N_("LCUP Reload Required")},
- {LDAP_CANCELLED, N_("Cancelled")},
- {LDAP_NO_SUCH_OPERATION, N_("No Operation to Cancel")},
- {LDAP_TOO_LATE, N_("Too Late to Cancel")},
- {LDAP_CANNOT_CANCEL, N_("Cannot Cancel")},
-
{0, NULL}
};
{0, ATTR_NONE, NULL, NULL, 0}
};
-#define MAX_LDAP_ATTR_LEN sizeof("TLS_CACERTDIR")
+#define MAX_LDAP_ATTR_LEN sizeof("TLS_CIPHER_SUITE")
#define MAX_LDAP_ENV_PREFIX_LEN 8
static void openldap_ldap_init_w_conf(
#if defined(HAVE_WINSOCK) || defined(HAVE_WINSOCK2)
WSACleanup( );
#endif
+
+ if ( ldap_int_hostname ) {
+ LDAP_FREE( ldap_int_hostname );
+ ldap_int_hostname = NULL;
+ }
}
/*
#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) \
|| defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
- ldap_int_hostname = ldap_pvt_get_fqdn( ldap_int_hostname );
+ {
+ char *name = ldap_int_hostname;
+
+ ldap_int_hostname = ldap_pvt_get_fqdn( name );
+
+ if ( name != NULL && name != ldap_int_hostname ) {
+ LDAP_FREE( name );
+ }
+ }
#endif
#ifndef HAVE_POLL
sizeof(sin.sin_addr) );
}
+#ifdef HAVE_INET_NTOA_B
+ {
+ /* for VxWorks */
+ char address[INET_ADDR_LEN];
+ inet_ntoa_b(sin.sin_address, address);
+ osip_debug(ld, "ldap_connect_to_host: Trying %s:%d\n",
+ address, port, 0);
+ }
+#else
osip_debug(ld, "ldap_connect_to_host: Trying %s:%d\n",
inet_ntoa(sin.sin_addr), port, 0);
+#endif
rc = ldap_pvt_connect(ld, s,
(struct sockaddr *)&sin, sizeof(sin),
return( ldap_result2error( ld, *res, 0 ) );
}
+int
+ldap_bv2escaped_filter_value( struct berval *in, struct berval *out )
+{
+ char c;
+ ber_len_t i;
+ static char escape[128] = {
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1
+ };
+
+ out->bv_len = 0;
+ out->bv_val = NULL;
+
+ if( in->bv_len == 0 ) return 0;
+
+ /* assume we'll escape everything */
+ out->bv_val = LDAP_MALLOC( 3 * in->bv_len + 1 );
+ if( out->bv_val == NULL ) return -1;
+
+ for( i=0; i<in->bv_len; i++ ) {
+ if (c & 0x80 || escape[in->bv_val[i]]) {
+ out->bv_val[out->bv_len++] = '\\';
+ out->bv_val[out->bv_len++] = "0123456789ABCDEF"[0x0f & (c>>4)];
+ out->bv_val[out->bv_len++] = "0123456789ABCDEF"[0x0f & c];
+ } else {
+ out->bv_val[out->bv_len++] = c;
+ }
+ }
+
+ out->bv_val[out->bv_len] = '\0';
+ return 0;
+}
+
static int tls_opt_trace = 1;
static char *tls_opt_certfile = NULL;
static char *tls_opt_keyfile = NULL;
+static char *tls_opt_dhfile = NULL;
static char *tls_opt_cacertfile = NULL;
static char *tls_opt_cacertdir = NULL;
static int tls_opt_require_cert = LDAP_OPT_X_TLS_DEMAND;
static RSA * tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length );
static STACK_OF(X509_NAME) * get_ca_list( char * bundle, char * dir );
-#if 0 /* Currently this is not used by anyone */
static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length );
-#endif
static SSL_CTX *tls_def_ctx = NULL;
+typedef struct dhplist {
+ struct dhplist *next;
+ int keylength;
+ DH *param;
+} dhplist;
+
+static dhplist *dhparams;
+
static int tls_seed_PRNG( const char *randfile );
#ifdef LDAP_R_COMPILE
LDAP_FREE( tls_opt_keyfile );
tls_opt_keyfile = NULL;
}
+ if ( tls_opt_dhfile ) {
+ LDAP_FREE( tls_opt_dhfile );
+ tls_opt_dhfile = NULL;
+ }
if ( tls_opt_cacertfile ) {
LDAP_FREE( tls_opt_cacertfile );
tls_opt_cacertfile = NULL;
char *cacertdir = tls_opt_cacertdir;
char *certfile = tls_opt_certfile;
char *keyfile = tls_opt_keyfile;
+ char *dhfile = tls_opt_dhfile;
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
if ( !certfile && !keyfile && !cacertfile && !cacertdir ) {
/* minimum configuration not provided */
+#ifdef LDAP_R_COMPILE
+ ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
+#endif
return LDAP_NOT_SUPPORTED;
}
keyfile = LDAP_STRDUP( keyfile );
__atoe( keyfile );
}
+ if ( dhfile ) {
+ dhfile = LDAP_STRDUP( dhfile );
+ __atoe( dhfile );
+ }
#endif
if ( tls_def_ctx == NULL ) {
int i;
goto error_exit;
}
+ if ( tls_opt_dhfile ) {
+ DH *dh = NULL;
+ BIO *bio;
+ dhplist *p;
+
+ if (( bio=BIO_new_file( dhfile,"r" )) == NULL ) {
+ Debug( LDAP_DEBUG_ANY,
+ "TLS: could not use DH parameters file `%s'.\n",
+ tls_opt_dhfile,0,0);
+ tls_report_error();
+ rc = -1;
+ goto error_exit;
+ }
+ while (( dh=PEM_read_bio_DHparams( bio, NULL, NULL, NULL ))) {
+ p = LDAP_MALLOC( sizeof(dhplist) );
+ if ( p != NULL ) {
+ p->keylength = DH_size( dh ) * 8;
+ p->param = dh;
+ p->next = dhparams;
+ dhparams = p;
+ }
+ }
+ BIO_free( bio );
+ }
+
if ( tls_opt_trace ) {
SSL_CTX_set_info_callback( tls_def_ctx, tls_info_cb );
}
tls_opt_require_cert == LDAP_OPT_X_TLS_ALLOW ?
tls_verify_ok : tls_verify_cb );
SSL_CTX_set_tmp_rsa_callback( tls_def_ctx, tls_tmp_rsa_cb );
- /* SSL_CTX_set_tmp_dh_callback( tls_def_ctx, tls_tmp_dh_cb ); */
+ SSL_CTX_set_tmp_dh_callback( tls_def_ctx, tls_tmp_dh_cb );
#ifdef HAVE_OPENSSL_CRL
if ( tls_opt_crlcheck ) {
X509_STORE *x509_s = SSL_CTX_get_cert_store( tls_def_ctx );
LDAP_FREE( cacertdir );
LDAP_FREE( certfile );
LDAP_FREE( keyfile );
+ LDAP_FREE( dhfile );
#endif
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
case LDAP_OPT_X_TLS_KEYFILE:
case LDAP_OPT_X_TLS_RANDOM_FILE:
case LDAP_OPT_X_TLS_CIPHER_SUITE:
+ case LDAP_OPT_X_TLS_DHFILE:
return ldap_pvt_tls_set_option( ld, option, (void *) arg );
case LDAP_OPT_X_TLS_REQUIRE_CERT:
*(char **)arg = tls_opt_keyfile ?
LDAP_STRDUP( tls_opt_keyfile ) : NULL;
break;
+ case LDAP_OPT_X_TLS_DHFILE:
+ *(char **)arg = tls_opt_dhfile ?
+ LDAP_STRDUP( tls_opt_dhfile ) : NULL;
+ break;
case LDAP_OPT_X_TLS_REQUIRE_CERT:
*(int *)arg = tls_opt_require_cert;
break;
if ( tls_opt_keyfile ) LDAP_FREE( tls_opt_keyfile );
tls_opt_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
break;
+ case LDAP_OPT_X_TLS_DHFILE:
+ if ( tls_opt_dhfile ) LDAP_FREE( tls_opt_dhfile );
+ tls_opt_dhfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+ break;
case LDAP_OPT_X_TLS_REQUIRE_CERT:
switch( *(int *) arg ) {
case LDAP_OPT_X_TLS_NEVER:
return 0;
}
-#if 0
+struct dhinfo {
+ int keylength;
+ const char *pem;
+ size_t size;
+};
+
+
+/* From the OpenSSL 0.9.7 distro */
+static const char dhpem512[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn\n\
+a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC\n\
+-----END DH PARAMETERS-----\n";
+
+static const char dhpem1024[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq\n\
+/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx\n\
+/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC\n\
+-----END DH PARAMETERS-----\n";
+
+static const char dhpem2048[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o\n\
+AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh\n\
+z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo\n\
+pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW\n\
+aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA\n\
+Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg==\n\
+-----END DH PARAMETERS-----\n";
+
+static const char dhpem4096[] =
+"-----BEGIN DH PARAMETERS-----\n\
+MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7\n\
+vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H\n\
+TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF\n\
+bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1\n\
+rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE\n\
+EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9\n\
+bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3\n\
+W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH\n\
+ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb\n\
+NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR\n\
+jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI=\n\
+-----END DH PARAMETERS-----\n";
+
+static const struct dhinfo dhpem[] = {
+ { 512, dhpem512, sizeof(dhpem512) },
+ { 1024, dhpem1024, sizeof(dhpem1024) },
+ { 2048, dhpem2048, sizeof(dhpem2048) },
+ { 4096, dhpem4096, sizeof(dhpem4096) },
+ { 0, NULL, 0 }
+};
+
static DH *
tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
{
- return NULL;
-}
+ struct dhplist *p = NULL;
+ BIO *b = NULL;
+ DH *dh = NULL;
+ int i;
+
+ /* Do we have params of this length already? */
+#ifdef LDAP_R_COMPILE
+ ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
+#endif
+ for ( p = dhparams; p; p=p->next ) {
+ if ( p->keylength == key_length ) {
+#ifdef LDAP_R_COMPILE
+ ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
#endif
+ return p->param;
+ }
+ }
+
+ /* No - check for hardcoded params */
+
+ for (i=0; dhpem[i].keylength; i++) {
+ if ( dhpem[i].keylength == key_length ) {
+ b = BIO_new_mem_buf( (char *)dhpem[i].pem, dhpem[i].size );
+ break;
+ }
+ }
+
+ if ( b ) {
+ dh = PEM_read_bio_DHparams( b, NULL, NULL, NULL );
+ BIO_free( b );
+ }
+
+ /* Generating on the fly is expensive/slow... */
+ if ( !dh ) {
+ dh = DH_generate_parameters( key_length, DH_GENERATOR_2, NULL, NULL );
+ }
+ if ( dh ) {
+ p = LDAP_MALLOC( sizeof(struct dhplist) );
+ if ( p != NULL ) {
+ p->keylength = key_length;
+ p->param = dh;
+ p->next = dhparams;
+ dhparams = p;
+ }
+ }
+done:
+#ifdef LDAP_R_COMPILE
+ ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
+#endif
+ return dh;
+}
#endif
void *
Unicode address space (0 - 0x10FFFF) 21 bits
ISO-10646 address space (0 - 0x7FFFFFFF) 31 bits
-Note: This code does not prevent UTF-8 sequences which are longer than
- necessary from being decoded.
+Note: This code does not prevent UTF-8 sequences which are longer than
+ necessary from being decoded.
*/
/*-----------------------------------------------------------------------------
int utflen, i;
wchar_t ch;
- /* If input ptr is NULL, treat it as empty string. */
- if (utf8char == NULL)
- utf8char = "";
+ if (utf8char == NULL) return -1;
/* Get UTF-8 sequence length from 1st byte */
utflen = LDAP_UTF8_CHARLEN2(utf8char, utflen);
- if( utflen==0 || utflen > (int)LDAP_MAX_UTF8_LEN )
- return -1; /* Invalid input */
+ if( utflen==0 || utflen > (int)LDAP_MAX_UTF8_LEN ) return -1;
/* First byte minus length tag */
ch = (wchar_t)(utf8char[0] & mask[utflen]);
- for(i=1; i < utflen; i++)
- {
+ for(i=1; i < utflen; i++) {
/* Subsequent bytes must start with 10 */
- if ((utf8char[i] & 0xc0) != 0x80)
- return -1;
+ if ((utf8char[i] & 0xc0) != 0x80) return -1;
ch <<= 6; /* 6 bits of data in each subsequent byte */
ch |= (wchar_t)(utf8char[i] & 0x3f);
}
- if (wchar)
- *wchar = ch;
+ if (wchar) *wchar = ch;
return utflen;
}
/* If input ptr is NULL, treat it as empty string. */
- if (utf8str == NULL)
- utf8str = "";
+ if (utf8str == NULL) utf8str = "";
/* Examine next UTF-8 character. If output buffer is NULL, ignore count */
- while ( *utf8str && (wcstr==NULL || wclen<count) )
- {
+ while ( *utf8str && (wcstr==NULL || wclen<count) ) {
/* Get UTF-8 sequence length from 1st byte */
utflen = LDAP_UTF8_CHARLEN2(utf8str, utflen);
- if( utflen==0 || utflen > (int)LDAP_MAX_UTF8_LEN )
- return -1; /* Invalid input */
+ if( utflen==0 || utflen > (int)LDAP_MAX_UTF8_LEN ) return -1;
/* First byte minus length tag */
ch = (wchar_t)(utf8str[0] & mask[utflen]);
- for(i=1; i < utflen; i++)
- {
+ for(i=1; i < utflen; i++) {
/* Subsequent bytes must start with 10 */
- if ((utf8str[i] & 0xc0) != 0x80)
- return -1;
+ if ((utf8str[i] & 0xc0) != 0x80) return -1;
ch <<= 6; /* 6 bits of data in each subsequent byte */
ch |= (wchar_t)(utf8str[i] & 0x3f);
}
- if (wcstr)
- wcstr[wclen] = ch;
+ if (wcstr) wcstr[wclen] = ch;
- utf8str += utflen; /* Move to next UTF-8 character */
- wclen++; /* Count number of wide chars stored/required */
+ utf8str += utflen; /* Move to next UTF-8 character */
+ wclen++; /* Count number of wide chars stored/required */
}
/* Add null terminator if there's room in the buffer. */
- if (wcstr && wclen < count)
- wcstr[wclen] = 0;
+ if (wcstr && wclen < count) wcstr[wclen] = 0;
return wclen;
}
rc = 0;
} else {
rc = h_errno;
- *err = (char *)hp_strerror( h_errno );
+ *err = (char *)HSTRERROR( h_errno );
}
#if defined( LDAP_R_COMPILE )
ldap_pvt_thread_mutex_unlock( &ldap_int_resolv_mutex );
return(0);
}
ldap_pvt_thread_cond_signal(&pool->ltp_cond);
- if ((pool->ltp_open_count <= 0
-#if 0
- || pool->ltp_pending_count > 1
-#endif
- || pool->ltp_open_count == pool->ltp_active_count)
- && (pool->ltp_max_count <= 0
- || pool->ltp_open_count < pool->ltp_max_count))
+ if (pool->ltp_open_count < pool->ltp_active_count + pool->ltp_pending_count
+ && (pool->ltp_open_count < pool->ltp_max_count ||
+ pool->ltp_max_count <= 0 ))
{
pool->ltp_open_count++;
pool->ltp_starting++;
#ifdef USE_REWRITE_LDAP_PVT_THREADS
if ( ldap_pvt_thread_rdwr_init( &info->li_cookies_mutex ) ) {
+ avl_free( info->li_context, rewrite_context_free );
free( info );
return NULL;
}
if ( ldap_pvt_thread_rdwr_init( &info->li_params_mutex ) ) {
+ ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex );
+ avl_free( info->li_context, rewrite_context_free );
free( info );
return NULL;
}
if ( info->li_maps ) {
avl_free( info->li_maps, rewrite_builtin_map_free );
}
- info->li_context = NULL;
+ info->li_maps = NULL;
rewrite_session_destroy( info );
return REWRITE_SUCCESS;
}
+static void
+rewrite_session_clean( void *v_session )
+{
+ struct rewrite_session *session = (struct rewrite_session *)v_session;
+
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+ ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex );
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+
+ rewrite_var_delete( session->ls_vars );
+
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+ ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
+ ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex );
+ ldap_pvt_thread_mutex_unlock( &session->ls_mutex );
+ ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+}
+
+static void
+rewrite_session_free( void *v_session )
+{
+ rewrite_session_clean( v_session );
+ free( v_session );
+}
+
/*
* Deletes a session
*/
const void *cookie
)
{
- struct rewrite_session *session, tmp;
+ struct rewrite_session *session, tmp = { 0 };
assert( info != NULL );
assert( cookie != NULL );
- tmp.ls_cookie = ( void * )cookie;
-
session = rewrite_session_find( info, cookie );
if ( session == NULL ) {
return REWRITE_SUCCESS;
}
-#ifdef USE_REWRITE_LDAP_PVT_THREADS
- ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex );
-#endif /* USE_REWRITE_LDAP_PVT_THREADS */
-
- rewrite_var_delete( session->ls_vars );
-
-#ifdef USE_REWRITE_LDAP_PVT_THREADS
- ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
- ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex );
- ldap_pvt_thread_mutex_unlock( &session->ls_mutex );
- ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
-#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+ rewrite_session_clean( session );
#ifdef USE_REWRITE_LDAP_PVT_THREADS
ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
/*
* There is nothing to delete in the return value
*/
+ tmp.ls_cookie = ( void * )cookie;
avl_delete( &info->li_cookies, ( caddr_t )&tmp, rewrite_cookie_cmp );
+
free( session );
#ifdef USE_REWRITE_LDAP_PVT_THREADS
* Should call per-session destruction routine ...
*/
- count = avl_free( info->li_cookies, NULL );
+ count = avl_free( info->li_cookies, rewrite_session_free );
info->li_cookies = NULL;
#if 0
atbv = BER_BVNULL;
ocbv.bv_val = strchr( type.bv_val, '/' );
- if ( ocbv.bv_val != NULL ) {
+ if ( ocbv.bv_val != NULL
+ && ( ocbv.bv_val - type.bv_val ) < type.bv_len )
+ {
ocbv.bv_val++;
atbv.bv_val = strchr( ocbv.bv_val, '/' );
- if ( atbv.bv_val != NULL ) {
+ if ( atbv.bv_val != NULL
+ && ( atbv.bv_val - ocbv.bv_val ) < ocbv.bv_len )
+ {
AttributeDescription *ad = NULL;
const char *text = NULL;
int rc;
atbv = BER_BVNULL;
ocbv.bv_val = strchr( type.bv_val, '/' );
- if ( ocbv.bv_val != NULL ) {
+ if ( ocbv.bv_val != NULL
+ && ( ocbv.bv_val - type.bv_val ) < type.bv_len )
+ {
ObjectClass *oc = NULL;
AttributeDescription *ad = NULL;
const char *text = NULL;
ocbv.bv_val++;
atbv.bv_val = strchr( ocbv.bv_val, '/' );
- if ( atbv.bv_val != NULL ) {
+ if ( atbv.bv_val != NULL
+ && ( atbv.bv_val - ocbv.bv_val ) < ocbv.bv_len )
+ {
atbv.bv_val++;
atbv.bv_len = type.bv_len
- ( atbv.bv_val - type.bv_val );
return OpenLDAPaciPrettyNormal( val, out, ctx, 1 );
}
+#if SLAPD_ACI_ENABLED == SLAPD_MOD_DYNAMIC
+/*
+ * FIXME: need config and Makefile.am code to ease building
+ * as dynamic module
+ */
+int
+init_module( int argc, char *argv[] )
+{
+ return slap_dynacl_register();
+}
+#endif /* SLAPD_ACI_ENABLED == SLAPD_MOD_DYNAMIC */
+
#endif /* SLAPD_ACI_ENABLED */
op2.o_tag = LDAP_REQ_SEARCH;
op2.o_ndn = op2.o_bd->be_rootndn;
op2.o_callback = &cb;
- op2.o_time = slap_get_time();
+ slap_op_time( &op2.o_time, &op2.o_tincr );
op2.o_do_not_cache = 1;
op2.o_is_auth_check = 0;
ber_dupbv_x( &op2.o_req_dn, &op2.o_req_ndn, cp->asc_op->o_tmpmemctx );
static void split(char *line, int splitchar, char **left, char **right);
static void access_append(Access **l, Access *a);
-static void acl_usage(void) LDAP_GCCATTR((noreturn));
+static int acl_usage(void);
static void acl_regex_normalized_dn(const char *src, struct berval *pat);
Debug( LDAP_DEBUG_ANY,
"%s: line %d: dynacl \"%s\" already specified.\n",
fname, lineno, name );
- acl_usage();
+ return acl_usage();
}
}
Debug( LDAP_DEBUG_ANY,
"%s: line %d: regular expression \"%s\" too large\n",
fname, lineno, pat );
- acl_usage();
+ (void)acl_usage();
+ exit( EXIT_FAILURE );
}
if ((e = regcomp(&re, buf, REG_EXTENDED|REG_ICASE))) {
"%s: line %d: %s\n",
fname, lineno, buf );
acl_usage();
+ exit( EXIT_FAILURE );
}
regfree(&re);
}
return ACL_SCOPE_UNKNOWN;
}
-void
+int
parse_acl(
- Backend *be,
- const char *fname,
- int lineno,
- int argc,
- char **argv,
+ Backend *be,
+ const char *fname,
+ int lineno,
+ int argc,
+ char **argv,
int pos )
{
int i;
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"only one to clause allowed in access line\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
a = (AccessControl *) ch_calloc( 1, sizeof(AccessControl) );
for ( ++i; i < argc; i++ ) {
"%s: line %d: dn pattern"
" already specified in to clause.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
ber_str2bv( "*", STRLENOF( "*" ), 1, &a->acl_dn_pat );
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"missing \"=\" in \"%s\" in to clause\n",
fname, lineno, left );
- acl_usage();
+ return acl_usage();
}
if ( strcasecmp( left, "dn" ) == 0 ) {
"%s: line %d: dn pattern"
" already specified in to clause.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
if ( style == NULL || *style == '\0' ||
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unknown dn style \"%s\" in to clause\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
continue;
Debug( LDAP_DEBUG_ANY,
"%s: line %d: bad filter \"%s\" in to clause\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
} else if ( strcasecmp( left, "attr" ) == 0 /* TOLERATED */
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unknown attr \"%s\" in to clause\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
} else if ( strncasecmp( left, "val", 3 ) == 0 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: attr val already specified in to clause.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
if ( a->acl_attrs == NULL || !BER_BVISEMPTY( &a->acl_attrs[1].an_name ) )
{
Debug( LDAP_DEBUG_ANY,
"%s: line %d: attr val requires a single attribute.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
ber_str2bv( right, 0, 1, &a->acl_attrval );
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"invalid matching rule \"%s\".\n",
fname, lineno, mr );
- acl_usage();
+ return acl_usage();
}
if( !mr_usable_with_at( a->acl_attrval_mr, a->acl_attrs[ 0 ].an_desc->ad_type ) )
Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
}
Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
a->acl_attrval_style = ACL_STYLE_REGEX;
"%s: line %d: %s\n",
fname, lineno, buf );
#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
- acl_usage();
+ return acl_usage();
#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
a->acl_attrval_style = ACL_STYLE_BASE;
}
Debug( LDAP_DEBUG_ANY,
"%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
ber_memfree( bv.bv_val );
"%s: line %d: %s\n",
fname, lineno, buf );
#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
- acl_usage();
+ return acl_usage();
#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
a->acl_attrval_style = ACL_STYLE_BASE;
}
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"attr \"%s\" must have an EQUALITY matching rule.\n",
fname, lineno, a->acl_attrs[ 0 ].an_name.bv_val );
- acl_usage();
+ return acl_usage();
}
}
Debug( LDAP_DEBUG_ANY,
"%s: line %d: expecting <what> got \"%s\"\n",
fname, lineno, left );
- acl_usage();
+ return acl_usage();
}
}
Debug( LDAP_DEBUG_ANY,
"%s: line %d: bad DN \"%s\" in to DN clause\n",
fname, lineno, a->acl_dn_pat.bv_val );
- acl_usage();
+ return acl_usage();
}
free( a->acl_dn_pat.bv_val );
a->acl_dn_pat = bv;
right, err );
Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
}
}
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"to clause required before by clause in access line\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
/*
Debug( LDAP_DEBUG_ANY,
"%s: line %d: premature EOL: expecting <who>\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
/* get <who> */
"%s: line %d: premature eol: "
"expecting closing '}' in \"level{n}\"\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
} else if ( p == style_level ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: empty level "
"in \"level{n}\"\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
p[0] = '\0';
}
"%s: line %d: unable to parse level "
"in \"level{n}\"\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
sty = ACL_STYLE_LEVEL;
SLAPD_CONF_UNKNOWN_IGNORED ".\n",
fname, lineno, 0 );
#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
- acl_usage();
+ return acl_usage();
#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
#endif /* LDAP_PF_LOCAL */
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unknown style \"%s\" in by clause\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if ( style_modifier &&
SLAPD_CONF_UNKNOWN_IGNORED ".\n",
fname, lineno, 0 );
#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
- acl_usage();
+ return acl_usage();
#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
break;
SLAPD_CONF_UNKNOWN_IGNORED ".\n",
fname, lineno, 0 );
#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
- acl_usage();
+ return acl_usage();
#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
}
if ( strcasecmp( left, "*" ) == 0 ) {
if ( is_realdn ) {
- acl_usage();
+ return acl_usage();
}
ber_str2bv( "*", STRLENOF( "*" ), 1, &bv );
"missing \"=\" in (or value after) \"%s\" "
"in by clause\n",
fname, lineno, left );
- acl_usage();
+ return acl_usage();
} else {
ber_str2bv( right, 0, 1, &bv );
Debug( LDAP_DEBUG_ANY,
"%s: line %d: dn pattern already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
if ( sty != ACL_STYLE_REGEX &&
Debug( LDAP_DEBUG_ANY,
"%s: line %d: bad DN \"%s\" in by DN clause\n",
fname, lineno, bv.bv_val );
- acl_usage();
+ return acl_usage();
}
free( bv.bv_val );
if ( sty == ACL_STYLE_BASE
SLAPD_CONF_UNKNOWN_IGNORED ".\n",
fname, lineno, 0 );
#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
- acl_usage();
+ return acl_usage();
#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
}
}
"%s: line %d: bad negative level \"%d\" "
"in by DN clause\n",
fname, lineno, level );
- acl_usage();
+ return acl_usage();
} else if ( level == 1 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"onelevel\" should be used "
"missing \"=\" in (or value after) \"%s\" "
"in by clause\n",
fname, lineno, left );
- acl_usage();
+ return acl_usage();
}
if( bdn->a_at != NULL ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: dnattr already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
rc = slap_str2ad( right, &bdn->a_at, &text );
Debug( LDAP_DEBUG_ANY,
"%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
Debug( LDAP_DEBUG_ANY,
"%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
if( bdn->a_at->ad_type->sat_equality == NULL ) {
"%s: line %d: dnattr \"%s\": "
"inappropriate matching (no EQUALITY)\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
continue;
"%s: line %d: "
"inappropriate style \"%s\" in by clause.\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if ( right == NULL || right[0] == '\0' ) {
"missing \"=\" in (or value after) \"%s\" "
"in by clause.\n",
fname, lineno, left );
- acl_usage();
+ return acl_usage();
}
if ( !BER_BVISEMPTY( &b->a_group_pat ) ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: group pattern already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
/* format of string is
Debug( LDAP_DEBUG_ANY,
"%s: line %d: bad DN \"%s\".\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
}
"%s: line %d: group objectclass "
"\"%s\" unknown.\n",
fname, lineno, value );
- acl_usage();
+ return acl_usage();
}
} else {
"%s: line %d: group default objectclass "
"\"%s\" unknown.\n",
fname, lineno, SLAPD_GROUP_CLASS );
- acl_usage();
+ return acl_usage();
}
}
"%s: line %d: group objectclass \"%s\" "
"is subclass of referral.\n",
fname, lineno, value );
- acl_usage();
+ return acl_usage();
}
if ( is_object_subclass( slap_schema.si_oc_alias,
"%s: line %d: group objectclass \"%s\" "
"is subclass of alias.\n",
fname, lineno, value );
- acl_usage();
+ return acl_usage();
}
if ( name && *name ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
*--name = '/';
Debug( LDAP_DEBUG_ANY,
"%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
}
Debug( LDAP_DEBUG_ANY,
"%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
b->a_group_oc->soc_oid );
Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
}
continue;
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"inappropriate style \"%s\" in by clause.\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if ( right == NULL || right[0] == '\0' ) {
"missing \"=\" in (or value after) \"%s\" "
"in by clause.\n",
fname, lineno, left );
- acl_usage();
+ return acl_usage();
}
if ( !BER_BVISEMPTY( &b->a_peername_pat ) ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"peername pattern already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
b->a_peername_style = sty;
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"illegal peername address \"%s\".\n",
fname, lineno, addr );
- acl_usage();
+ return acl_usage();
}
b->a_peername_mask = (unsigned long)(-1);
"illegal peername address mask "
"\"%s\".\n",
fname, lineno, mask );
- acl_usage();
+ return acl_usage();
}
}
"illegal peername port specification "
"\"{%s}\".\n",
fname, lineno, port );
- acl_usage();
+ return acl_usage();
}
}
}
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"inappropriate style \"%s\" in by clause\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if ( right == NULL || right[0] == '\0' ) {
"missing \"=\" in (or value after) \"%s\" "
"in by clause\n",
fname, lineno, left );
- acl_usage();
+ return acl_usage();
}
if ( !BER_BVISNULL( &b->a_sockname_pat ) ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"sockname pattern already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
b->a_sockname_style = sty;
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"inappropriate style \"%s\" in by clause.\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if ( right == NULL || right[0] == '\0' ) {
"missing \"=\" in (or value after) \"%s\" "
"in by clause.\n",
fname, lineno, left );
- acl_usage();
+ return acl_usage();
}
if ( !BER_BVISEMPTY( &b->a_domain_pat ) ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: domain pattern already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
b->a_domain_style = sty;
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"inappropriate style \"%s\" in by clause.\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if ( right == NULL || right[0] == '\0' ) {
"missing \"=\" in (or value after) \"%s\" "
"in by clause.\n",
fname, lineno, left );
- acl_usage();
+ return acl_usage();
}
if ( !BER_BVISEMPTY( &b->a_sockurl_pat ) ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: sockurl pattern already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
b->a_sockurl_style = sty;
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"inappropriate style \"%s\" in by clause.\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if ( !BER_BVISEMPTY( &b->a_set_pat ) ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: set attribute already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
if ( right == NULL || *right == '\0' ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: no set is defined.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
b->a_set_style = sty;
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unable to configure dynacl \"%s\".\n",
fname, lineno, name );
- acl_usage();
+ return acl_usage();
}
continue;
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"inappropriate style \"%s\" in by clause.\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if( b->a_aci_at != NULL ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: ACI attribute already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
if ( right != NULL && *right != '\0' ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
} else {
b->a_aci_at->ad_type->sat_syntax_oid );
Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n",
fname, lineno, buf );
- acl_usage();
+ return acl_usage();
}
continue;
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"inappropriate style \"%s\" in by clause.\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if ( b->a_authz.sai_ssf ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: ssf attribute already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
if ( right == NULL || *right == '\0' ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: no ssf is defined.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
b->a_authz.sai_ssf = strtol( right, &next, 10 );
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unable to parse ssf value (%s).\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
if ( !b->a_authz.sai_ssf ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: invalid ssf value (%s).\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
continue;
}
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"inappropriate style \"%s\" in by clause.\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if ( b->a_authz.sai_transport_ssf ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"transport_ssf attribute already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
if ( right == NULL || *right == '\0' ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: no transport_ssf is defined.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
b->a_authz.sai_transport_ssf = strtol( right, &next, 10 );
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unable to parse transport_ssf value (%s).\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
if ( !b->a_authz.sai_transport_ssf ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: invalid transport_ssf value (%s).\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
continue;
}
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"inappropriate style \"%s\" in by clause.\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if ( b->a_authz.sai_tls_ssf ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"tls_ssf attribute already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
if ( right == NULL || *right == '\0' ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: no tls_ssf is defined\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
b->a_authz.sai_tls_ssf = strtol( right, &next, 10 );
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unable to parse tls_ssf value (%s).\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
if ( !b->a_authz.sai_tls_ssf ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: invalid tls_ssf value (%s).\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
continue;
}
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"inappropriate style \"%s\" in by clause.\n",
fname, lineno, style );
- acl_usage();
+ return acl_usage();
}
if ( b->a_authz.sai_sasl_ssf ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"sasl_ssf attribute already specified.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
if ( right == NULL || *right == '\0' ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: no sasl_ssf is defined.\n",
fname, lineno, 0 );
- acl_usage();
+ return acl_usage();
}
b->a_authz.sai_sasl_ssf = strtol( right, &next, 10 );
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unable to parse sasl_ssf value (%s).\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
if ( !b->a_authz.sai_sasl_ssf ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: invalid sasl_ssf value (%s).\n",
fname, lineno, right );
- acl_usage();
+ return acl_usage();
}
continue;
}
Debug( LDAP_DEBUG_ANY,
"%s: line %d: expecting <access> got \"%s\".\n",
fname, lineno, left );
- acl_usage();
+ return acl_usage();
}
b->a_type = ACL_STOP;
"%s: line %d: expecting \"to\" "
"or \"by\" got \"%s\"\n",
fname, lineno, argv[i] );
- acl_usage();
+ return acl_usage();
}
}
SLAPD_CONF_UNKNOWN_IGNORED ".\n",
fname, lineno, 0 );
#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
- acl_usage();
+ return acl_usage();
#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
} else {
SLAPD_CONF_UNKNOWN_IGNORED ".\n",
fname, lineno, 0 );
#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
- acl_usage();
+ return acl_usage();
#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
}
acl_append( &frontendDB->be_acl, a, pos );
}
}
+
+ return 0;
}
char *
return mask;
}
-static void
+static int
acl_usage( void )
{
char *access =
"<access clause> ::= access to <what> "
"[ by <who> <access> [ <control> ] ]+ \n";
-
char *what =
- "<what> ::= * | [dn[.<dnstyle>]=<DN>] [filter=<filter>] [attrs=<attrlist>]\n"
- "<attrlist> ::= <attr> [val[/matchingRule][.<attrstyle>]=<value>] | <attr> , <attrlist>\n"
- "<attr> ::= <attrname> | entry | children\n";
+ "<what> ::= * | [dn[.<dnstyle>]=<DN>] [filter=<filter>] [attrs=<attrspec>]\n"
+ "<attrspec> ::= <attrname> [val[/<matchingRule>][.<attrstyle>]=<value>] | <attrlist>\n"
+ "<attrlist> ::= <attr> [ , <attrlist> ]\n"
+ "<attr> ::= <attrname> | @<objectClass> | !<objectClass> | entry | children\n";
char *who =
"<who> ::= [ * | anonymous | users | self | dn[.<dnstyle>]=<DN> ]\n"
#endif /* ! SLAP_DYNACL */
"";
- Debug( LDAP_DEBUG_ANY, "%s%s%s\n", access, who, what );
- exit( EXIT_FAILURE );
+ Debug( LDAP_DEBUG_ANY, "%s%s%s\n", access, what, who );
+
+ return 1;
}
/*
#include <ac/time.h>
#include <ac/socket.h>
+#include "lutil.h"
#include "slap.h"
int
}
done:;
- slap_graduate_commit_csn( op );
-
if ( modlist != NULL ) {
slap_mods_free( modlist, 0 );
}
}
- rs->sr_err = slap_mods_opattrs( op, modlist,
- modtail, &rs->sr_text,
- textbuf, textlen, 1 );
- if ( rs->sr_err != LDAP_SUCCESS ) {
- send_ldap_result( op, rs );
- goto done;
- }
-
/* check for duplicate values */
rs->sr_err = slap_mods_no_repl_user_mod_check( op,
modlist, &rs->sr_text, textbuf, textlen );
return LDAP_SUCCESS;
}
+int slap_add_opattrs(
+ Operation *op,
+ const char **text,
+ char *textbuf,
+ size_t textlen,
+ int manage_ctxcsn )
+{
+ struct berval name, timestamp, csn = BER_BVNULL;
+ struct berval nname, tmp;
+ char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
+ char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
+ Attribute *a;
+
+ a = attr_find( op->ora_e->e_attrs,
+ slap_schema.si_ad_structuralObjectClass );
+
+ if ( !a ) {
+ Attribute *oc;
+ int rc;
+
+ oc = attr_find( op->ora_e->e_attrs, slap_schema.si_ad_objectClass );
+ if ( oc ) {
+ rc = structural_class( oc->a_vals, &tmp, NULL, text,
+ textbuf, textlen );
+ if( rc != LDAP_SUCCESS ) return rc;
+
+ attr_merge_one( op->ora_e, slap_schema.si_ad_structuralObjectClass,
+ &tmp, NULL );
+ }
+ }
+
+ if ( SLAP_LASTMOD( op->o_bd ) ) {
+ char *ptr;
+ timestamp.bv_val = timebuf;
+ if ( BER_BVISEMPTY( &op->o_csn )) {
+ if ( SLAP_SHADOW( op->o_bd ))
+ manage_ctxcsn = 0;
+ csn.bv_val = csnbuf;
+ csn.bv_len = sizeof(csnbuf);
+ slap_get_csn( op, &csn, manage_ctxcsn );
+ } else {
+ csn = op->o_csn;
+ }
+ ptr = strchr( csn.bv_val, '#' );
+ if ( ptr ) {
+ timestamp.bv_len = ptr - csn.bv_val;
+ if ( timestamp.bv_len >= sizeof(timebuf) )
+ timestamp.bv_len = sizeof(timebuf) - 1;
+ strncpy( timebuf, csn.bv_val, timestamp.bv_len );
+ timebuf[timestamp.bv_len] = '\0';
+ } else {
+ time_t now = slap_get_time();
+
+ timestamp.bv_len = sizeof(timebuf);
+
+ slap_timestamp( &now, ×tamp );
+ }
+
+ if ( BER_BVISEMPTY( &op->o_dn ) ) {
+ BER_BVSTR( &name, SLAPD_ANONYMOUS );
+ nname = name;
+ } else {
+ name = op->o_dn;
+ nname = op->o_ndn;
+ }
+
+ a = attr_find( op->ora_e->e_attrs,
+ slap_schema.si_ad_entryUUID );
+ if ( !a ) {
+ char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
+
+ tmp.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
+ tmp.bv_val = uuidbuf;
+
+ attr_merge_normalize_one( op->ora_e,
+ slap_schema.si_ad_entryUUID, &tmp, op->o_tmpmemctx );
+ }
+
+ a = attr_find( op->ora_e->e_attrs,
+ slap_schema.si_ad_creatorsName );
+ if ( !a ) {
+ attr_merge_one( op->ora_e,
+ slap_schema.si_ad_creatorsName, &name, &nname );
+ }
+
+ a = attr_find( op->ora_e->e_attrs,
+ slap_schema.si_ad_createTimestamp );
+ if ( !a ) {
+ attr_merge_one( op->ora_e,
+ slap_schema.si_ad_createTimestamp, ×tamp, NULL );
+ }
+
+ a = attr_find( op->ora_e->e_attrs,
+ slap_schema.si_ad_entryCSN );
+ if ( !a ) {
+ attr_merge_one( op->ora_e,
+ slap_schema.si_ad_entryCSN, &csn, NULL );
+ }
+
+ a = attr_find( op->ora_e->e_attrs,
+ slap_schema.si_ad_modifiersName );
+ if ( !a ) {
+ attr_merge_one( op->ora_e,
+ slap_schema.si_ad_modifiersName, &name, &nname );
+ }
+
+ a = attr_find( op->ora_e->e_attrs,
+ slap_schema.si_ad_modifyTimestamp );
+ if ( !a ) {
+ attr_merge_one( op->ora_e,
+ slap_schema.si_ad_modifyTimestamp, ×tamp, NULL );
+ }
+
+ }
+ return LDAP_SUCCESS;
+}
ctrls[num_ctrls] = 0;
+ slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
+
/* check entry's schema */
rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
get_manageDIT(op), &rs->sr_text, textbuf, textlen );
"does not exist\n", 0, 0, 0 );
rs->sr_err = LDAP_REFERRAL;
- send_ldap_result( op, rs );
-
- ber_bvarray_free( rs->sr_ref );
- op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx );
- rs->sr_ref = NULL;
- rs->sr_matched = NULL;
-
- goto done;
+ rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+ goto return_results;
}
rs->sr_err = access_allowed( op, p,
if ( is_entry_referral( p ) ) {
/* parent is a referral, don't allow add */
- rs->sr_matched = p->e_name.bv_val;
+ rs->sr_matched = ber_strdup_x( p->e_name.bv_val,
+ op->o_tmpmemctx );
rs->sr_ref = get_entry_referrals( op, p );
-
+ bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
+ p = NULL;
Debug( LDAP_DEBUG_TRACE,
LDAP_XSTRING(bdb_add) ": parent is referral\n",
0, 0, 0 );
rs->sr_err = LDAP_REFERRAL;
- send_ldap_result( op, rs );
-
- ber_bvarray_free( rs->sr_ref );
- bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
- rs->sr_ref = NULL;
- rs->sr_matched = NULL;
- p = NULL;
- goto done;
+ rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+ goto return_results;
}
#ifdef BDB_SUBENTRIES
if (( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
rs->sr_text = "txn_abort (no-op) failed";
} else {
- rs->sr_err = LDAP_NO_OPERATION;
+ rs->sr_err = LDAP_X_NO_OPERATION;
+ ltid = NULL;
goto return_results;
}
return_results:
send_ldap_result( op, rs );
+ if ( !SLAP_SHADOW( op->o_bd ))
+ slap_graduate_commit_csn( op );
- if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
- ldap_pvt_thread_yield();
- TXN_CHECKPOINT( bdb->bi_dbenv,
- bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
- }
-
-done:
if( ltid != NULL ) {
TXN_ABORT( ltid );
- op->o_private = NULL;
}
+ op->o_private = NULL;
if( postread_ctrl != NULL ) {
slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
}
+
+ if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
+ ldap_pvt_thread_yield();
+ TXN_CHECKPOINT( bdb->bi_dbenv,
+ bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
+ }
return rs->sr_err;
}
#include "back-bdb.h"
#include "lutil.h"
-
-static int
-ainfo_type_cmp(
- const void *v_desc,
- const void *v_a
-)
+/* Find the ad, return -1 if not found,
+ * set point for insertion if ins is non-NULL
+ */
+int
+bdb_attr_slot( struct bdb_info *bdb, AttributeDescription *ad, unsigned *ins )
{
- const AttributeDescription *desc = v_desc;
- const AttrInfo *a = v_a;
- return SLAP_PTRCMP(desc, a->ai_desc);
+ unsigned base = 0, cursor = 0;
+ unsigned n = bdb->bi_nattrs;
+ int val = 0;
+
+ while ( 0 < n ) {
+ int pivot = n >> 1;
+ cursor = base + pivot;
+
+ val = SLAP_PTRCMP( ad, bdb->bi_attrs[cursor]->ai_desc );
+ if ( val < 0 ) {
+ n = pivot;
+ } else if ( val > 0 ) {
+ base = cursor + 1;
+ n -= pivot + 1;
+ } else {
+ return cursor;
+ }
+ }
+ if ( ins ) {
+ if ( val > 0 )
+ ++cursor;
+ *ins = cursor;
+ }
+ return -1;
}
static int
-ainfo_cmp(
- const void *v_a,
- const void *v_b
-)
+ainfo_insert( struct bdb_info *bdb, AttrInfo *a )
{
- const AttrInfo *a = v_a, *b = v_b;
- return SLAP_PTRCMP(a->ai_desc, b->ai_desc);
+ unsigned x;
+ int i = bdb_attr_slot( bdb, a->ai_desc, &x );
+
+ /* Is it a dup? */
+ if ( i >= 0 )
+ return -1;
+
+ bdb->bi_attrs = ch_realloc( bdb->bi_attrs, ( bdb->bi_nattrs+1 ) *
+ sizeof( AttrInfo * ));
+ if ( x < bdb->bi_nattrs )
+ AC_MEMCPY( &bdb->bi_attrs[x+1], &bdb->bi_attrs[x],
+ ( bdb->bi_nattrs - x ) * sizeof( AttrInfo *));
+ bdb->bi_attrs[x] = a;
+ bdb->bi_nattrs++;
+ return 0;
}
AttrInfo *
struct bdb_info *bdb,
AttributeDescription *desc )
{
-
- return avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
+ int i = bdb_attr_slot( bdb, desc, NULL );
+ return i < 0 ? NULL : bdb->bi_attrs[i];
}
int
#ifdef LDAP_COMP_MATCH
if ( cr ) {
- a_cr = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
+ a_cr = bdb_attr_mask( bdb, ad );
if ( a_cr ) {
/*
* AttrInfo is already in AVL
}
}
#endif
- rc = avl_insert( &bdb->bi_attrs, (caddr_t) a,
- ainfo_cmp, avl_dup_error );
-
+ rc = ainfo_insert( bdb, a );
if( rc ) {
if ( bdb->bi_flags & BDB_IS_OPEN ) {
- AttrInfo *b = avl_find( bdb->bi_attrs, ad, ainfo_type_cmp );
+ AttrInfo *b = bdb_attr_mask( bdb, ad );
/* If we were editing this attr, reset it */
b->ai_indexmask &= ~BDB_INDEX_DELETING;
/* If this is leftover from a previous add, commit it */
void
bdb_attr_index_unparse( struct bdb_info *bdb, BerVarray *bva )
{
+ int i;
+
if ( bdb->bi_defaultmask ) {
aidef.ai_indexmask = bdb->bi_defaultmask;
bdb_attr_index_unparser( &aidef, bva );
}
- avl_apply( bdb->bi_attrs, bdb_attr_index_unparser, bva, -1, AVL_INORDER );
+ for ( i=0; i<bdb->bi_nattrs; i++ )
+ bdb_attr_index_unparser( bdb->bi_attrs[i], bva );
}
-static void
-bdb_attrinfo_free( void *v )
+void
+bdb_attr_info_free( AttrInfo *ai )
{
- AttrInfo *ai = v;
#ifdef LDAP_COMP_MATCH
free( ai->ai_cr );
#endif
}
void
-bdb_attr_index_destroy( Avlnode *tree )
+bdb_attr_index_destroy( struct bdb_info *bdb )
{
- avl_free( tree, bdb_attrinfo_free );
-}
+ int i;
-void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad )
-{
- AttrInfo *ai;
+ for ( i=0; i<bdb->bi_nattrs; i++ )
+ bdb_attr_info_free( bdb->bi_attrs[i] );
- ai = avl_delete( &bdb->bi_attrs, ad, ainfo_type_cmp );
- if ( ai )
- bdb_attrinfo_free( ai );
+ free( bdb->bi_attrs );
}
-/* Get a list of AttrInfo's to delete */
-
-typedef struct Alist {
- struct Alist *next;
- AttrInfo *ptr;
-} Alist;
-
-static int
-bdb_attrinfo_flush( void *v1, void *arg )
+void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad )
{
- AttrInfo *ai = v1;
-
- if ( ai->ai_indexmask & BDB_INDEX_DELETING ) {
- Alist **al = arg;
- Alist *a = ch_malloc( sizeof( Alist ));
- a->ptr = ai;
- a->next = *al;
- *al = a;
+ int i;
+
+ i = bdb_attr_slot( bdb, ad, NULL );
+ if ( i >= 0 ) {
+ bdb_attr_info_free( bdb->bi_attrs[i] );
+ bdb->bi_nattrs--;
+ for (; i<bdb->bi_nattrs; i++)
+ bdb->bi_attrs[i] = bdb->bi_attrs[i+1];
}
- return 0;
}
void bdb_attr_flush( struct bdb_info *bdb )
{
- Alist *al = NULL, *a2;
-
- avl_apply( bdb->bi_attrs, bdb_attrinfo_flush, &al, -1, AVL_INORDER );
-
- while (( a2 = al )) {
- al = al->next;
- avl_delete( &bdb->bi_attrs, a2->ptr, ainfo_cmp );
- bdb_attrinfo_free( a2->ptr );
- ch_free( a2 );
+ int i;
+
+ for ( i=0; i<bdb->bi_nattrs; i++ ) {
+ if ( bdb->bi_attrs[i]->ai_indexmask & BDB_INDEX_DELETING ) {
+ int j;
+ bdb_attr_info_free( bdb->bi_attrs[i] );
+ bdb->bi_nattrs--;
+ for (j=i; j<bdb->bi_nattrs; j++)
+ bdb->bi_attrs[j] = bdb->bi_attrs[j+1];
+ i--;
+ }
}
}
slap_mask_t bi_defaultmask;
Cache bi_cache;
- Avlnode *bi_attrs;
+ struct bdb_attrinfo **bi_attrs;
+ int bi_nattrs;
void *bi_search_stack;
int bi_search_stack_depth;
int bi_linear_index;
#define BDB_INDEX_DELETING 0x8000U /* index is being modified */
#define BDB_INDEX_UPDATE_OP 0x03 /* performing an index update */
+/* For slapindex to record which attrs in an entry belong to which
+ * index database
+ */
+typedef struct AttrList {
+ struct AttrList *next;
+ Attribute *attr;
+} AttrList;
+
+typedef struct IndexRec {
+ AttrInfo *ai;
+ AttrList *attrs;
+} IndexRec;
+
#include "proto-bdb.h"
#endif /* _BACK_BDB_H_ */
static void bdb_lru_print(Cache *cache);
#endif
-static int bdb_txn_get( Operation *op, DB_ENV *env, DB_TXN **txn, int reset );
-
-/* 4.2.52 */
-#if DB_VERSION_FULL == 0x04020034
-#define READ_TXN_FLAG ReadFlag
-static int ReadFlag = DB_TXN_NOT_DURABLE;
-#else
-#define READ_TXN_FLAG 0
-#endif
-
static EntryInfo *
bdb_cache_entryinfo_new( Cache *cache )
{
/* Walk up the tree from a child node, looking for an ID that's already
* been linked into the cache.
*/
-static int
+int
hdb_cache_find_parent(
Operation *op,
DB_TXN *txn,
+ u_int32_t locker,
ID id,
EntryInfo **res )
{
ei.bei_ckids = 0;
for (;;) {
- rc = hdb_dn2id_parent( op, txn, &ei, &eip.bei_id );
+ rc = hdb_dn2id_parent( op, txn, locker, &ei, &eip.bei_id );
if ( rc ) break;
/* Save the previous node, if any */
/* See if the ID exists in the database; add it to the cache if so */
if ( !*eip ) {
#ifndef BDB_HIER
- rc = bdb_id2entry( op->o_bd, tid, id, &ep );
+ rc = bdb_id2entry( op->o_bd, tid, locker, id, &ep );
if ( rc == 0 ) {
rc = bdb_cache_find_ndn( op, tid,
&ep->e_nname, eip );
}
}
#else
- rc = hdb_cache_find_parent(op, tid, id, eip );
+ rc = hdb_cache_find_parent(op, tid, locker, id, eip );
if ( rc == 0 && *eip ) islocked = 1;
#endif
}
bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
} else if ( rc == 0 ) {
if ( load ) {
- DB_TXN *ltid;
- u_int32_t locker2 = locker;
-
- /* We don't wrap entire read operations in txn's, but
- * we need our cache entry lock and any DB page locks
- * to be associated, in order for deadlock detection
- * to work properly. So if we need to read from the DB,
- * we use a long-lived per-thread txn for this step.
- */
- if ( !ep && !tid ) {
- rc = bdb_txn_get( op, bdb->bi_dbenv, <id, 0 );
- if ( ltid )
- locker2 = TXN_ID( ltid );
- } else {
- ltid = tid;
- }
- /* Give up original read lock, obtain write lock with
- * (possibly) new locker ID.
+ /* Give up original read lock, obtain write lock
*/
if ( rc == 0 ) {
- rc = bdb_cache_entry_db_relock( bdb->bi_dbenv, locker2,
+ rc = bdb_cache_entry_db_relock( bdb->bi_dbenv, locker,
*eip, 1, 0, lock );
}
if ( rc == 0 && !ep) {
- rc = bdb_id2entry( op->o_bd, ltid, id, &ep );
+ rc = bdb_id2entry( op->o_bd, tid, locker, id, &ep );
}
if ( rc == 0 ) {
ep->e_private = *eip;
/* Otherwise, release the lock. */
bdb_cache_entry_db_unlock( bdb->bi_dbenv, lock );
}
- if ( locker2 != locker ) {
- /* If we're using the per-thread txn, release all
- * of its page locks now.
- */
- DB_LOCKREQ list;
- list.op = DB_LOCK_PUT_ALL;
- list.obj = NULL;
- bdb->bi_dbenv->lock_vec( bdb->bi_dbenv, locker2,
- 0, &list, 1, NULL );
- /* If this txn was deadlocked, we must abort it
- * and invalidate this per-thread txn.
- */
- if ( rc == DB_LOCK_DEADLOCK ) {
- bdb_txn_get( op, bdb->bi_dbenv, <id, 1 );
- }
- }
} else if ( !(*eip)->bei_e ) {
/* Some other thread is trying to load the entry,
* give it a chance to finish.
}
#endif
-static void
-bdb_txn_free( void *key, void *data )
-{
- DB_TXN *txn = data;
- TXN_ABORT( txn );
-}
-
-/* Obtain a long-lived transaction for the current thread.
- * If reset == 1, remove the current transaction. */
-static int
-bdb_txn_get( Operation *op, DB_ENV *env, DB_TXN **txn, int reset )
-{
- int i, rc;
- void *ctx, *data = NULL;
-
- if ( slapMode & SLAP_TOOL_MODE ) {
- *txn = NULL;
- return 0;
- }
-
- /* If no op was provided, try to find the ctx anyway... */
- if ( op ) {
- ctx = op->o_threadctx;
- } else {
- ctx = ldap_pvt_thread_pool_context();
- }
-
- /* Shouldn't happen unless we're single-threaded */
- if ( !ctx ) {
- *txn = NULL;
- return 0;
- }
-
- if ( reset ) {
- TXN_ABORT( *txn );
- return ldap_pvt_thread_pool_setkey( ctx, ((char *)env)+1, NULL, NULL );
- }
-
- if ( ldap_pvt_thread_pool_getkey( ctx, ((char *)env)+1, &data, NULL ) ||
- data == NULL ) {
- for ( i=0, rc=1; rc != 0 && i<4; i++ ) {
- rc = TXN_BEGIN( env, NULL, txn, READ_TXN_FLAG );
-#if DB_VERSION_FULL == 0x04020034
- if ( rc == EINVAL && READ_TXN_FLAG ) {
- READ_TXN_FLAG = 0;
- Debug( LDAP_DEBUG_ANY,
- "bdb_txn_get: BerkeleyDB 4.2.52 library needs TXN patch!\n",
- 0, 0, 0 );
- i--;
- continue;
- }
-#endif
- if (rc) ldap_pvt_thread_yield();
- }
- if ( rc != 0) {
- return rc;
- }
- if ( ( rc = ldap_pvt_thread_pool_setkey( ctx, ((char *)env)+1,
- *txn, bdb_txn_free ) ) ) {
- TXN_ABORT( *txn );
- Debug( LDAP_DEBUG_ANY, "bdb_txn_get: err %s(%d)\n",
- db_strerror(rc), rc, 0 );
-
- return rc;
- }
- } else {
- *txn = data;
- }
- return 0;
-}
-
#ifdef BDB_REUSE_LOCKERS
static void
bdb_locker_id_free( void *key, void *data )
#include <stdio.h>
#include <ac/string.h>
+#include "lutil.h"
#include "back-bdb.h"
int
int parent_is_glue = 0;
int parent_is_leaf = 0;
- struct berval ctxcsn_ndn = BER_BVNULL;
-
ctrls[num_ctrls] = 0;
Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_delete) ": %s\n",
op->o_req_dn.bv_val, 0, 0 );
- build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0],
- (struct berval *)&slap_ldapsync_cn_bv, op->o_tmpmemctx );
+ /* allocate CSN */
+ if ( !SLAP_SHADOW( op->o_bd )) {
+ struct berval csn;
+ char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
+
+ csn.bv_val = csnbuf;
+ csn.bv_len = sizeof(csnbuf);
+ slap_get_csn( op, &csn, 1 );
+ }
if( 0 ) {
retry: /* transaction retry */
}
rs->sr_err = LDAP_REFERRAL;
- send_ldap_result( op, rs );
-
- if ( rs->sr_ref != default_referral ) {
- ber_bvarray_free( rs->sr_ref );
- }
- free( (char *)rs->sr_matched );
- rs->sr_ref = NULL;
- rs->sr_matched = NULL;
-
- rs->sr_err = -1;
- goto done;
+ rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+ goto return_results;
}
rc = bdb_cache_find_id( op, ltid, eip->bei_id, &eip, 0, locker, &plock );
0, 0, 0 );
rs->sr_err = LDAP_REFERRAL;
- rs->sr_matched = e->e_name.bv_val;
- send_ldap_result( op, rs );
-
- ber_bvarray_free( rs->sr_ref );
- rs->sr_ref = NULL;
- rs->sr_matched = NULL;
-
- rs->sr_err = 1;
- goto done;
+ rs->sr_matched = ch_strdup( e->e_name.bv_val );
+ rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+ goto return_results;
}
/* pre-read */
if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) {
rs->sr_text = "txn_abort (no-op) failed";
} else {
- rs->sr_err = LDAP_NO_OPERATION;
+ rs->sr_err = LDAP_X_NO_OPERATION;
+ ltid = NULL;
goto return_results;
}
} else {
if( num_ctrls ) rs->sr_ctrls = ctrls;
return_results:
- send_ldap_result( op, rs );
-
- if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
- ldap_pvt_thread_yield();
- TXN_CHECKPOINT( bdb->bi_dbenv,
- bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
- }
-
if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) {
op->o_delete_glue_parent = 1;
}
-done:
if ( p )
bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
if( ltid != NULL ) {
TXN_ABORT( ltid );
- op->o_private = NULL;
}
+ op->o_private = NULL;
- slap_sl_free( ctxcsn_ndn.bv_val, op->o_tmpmemctx );
+ send_ldap_result( op, rs );
+ if ( !SLAP_SHADOW( op->o_bd ))
+ slap_graduate_commit_csn( op );
if( preread_ctrl != NULL ) {
slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
slap_sl_free( *preread_ctrl, op->o_tmpmemctx );
}
+
+ if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
+ ldap_pvt_thread_yield();
+ TXN_CHECKPOINT( bdb->bi_dbenv,
+ bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
+ }
return rs->sr_err;
}
hdb_dn2id_parent(
Operation *op,
DB_TXN *txn,
+ u_int32_t locker,
EntryInfo *ei,
ID *idp )
{
rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
if ( rc ) return rc;
+ if ( !txn && locker ) {
+ cursor->locker = locker;
+ }
data.ulen = sizeof(diskNode) + (SLAP_LDAPDN_MAXLEN * 2);
d = op->o_tmpalloc( data.ulen, op->o_tmpmemctx );
cx->rc = cx->db->cursor( cx->db, NULL, &cx->dbc,
cx->bdb->bi_db_opflags );
- if ( cx->rc ) return cx->rc;
+ if ( cx->rc )
+ goto done_one;
cx->data.data = &cx->dbuf;
cx->data.ulen = sizeof(ID);
cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data, DB_SET );
if ( cx->rc ) {
cx->dbc->c_close( cx->dbc );
- return cx->rc;
+ goto done_one;
}
/* If the on-disk count is zero we've never checked it.
}
}
cx->rc = cx->dbc->c_close( cx->dbc );
+done_one:
+ bdb_cache_entryinfo_lock( cx->ei );
+ cx->ei->bei_state ^= CACHE_ENTRY_ONELEVEL;
+ bdb_cache_entryinfo_unlock( cx->ei );
+ if ( cx->rc )
+ return cx->rc;
+
} else {
/* The in-memory cache is in sync with the on-disk data.
* do we have any kids?
int bdb_id2entry(
BackendDB *be,
DB_TXN *tid,
+ u_int32_t locker,
ID id,
Entry **e )
{
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
DB *db = bdb->bi_id2entry->bdi_db;
DBT key, data;
+ DBC *cursor;
struct berval bv;
int rc = 0;
ID nid;
data.flags = DB_DBT_MALLOC;
/* fetch it */
- rc = db->get( db, tid, &key, &data, bdb->bi_db_opflags );
+ rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
+ if ( rc ) return rc;
+
+ /* Use our own locker if needed */
+ if ( !tid && locker )
+ cursor->locker = locker;
+
+ rc = cursor->c_get( cursor, &key, &data, DB_SET );
+ cursor->c_close( cursor );
if( rc != 0 ) {
return rc;
e->e_nname.bv_val = NULL;
}
#ifndef SLAP_ZONE_ALLOC
-#ifndef BDB_HIER
/* In tool mode the e_bv buffer is realloc'd, leave it alone */
if( !(slapMode & SLAP_TOOL_MODE) ) {
free( e->e_bv.bv_val );
}
-#else
- free( e->e_bv.bv_val );
-#endif /* BDB_HIER */
#endif /* !SLAP_ZONE_ALLOC */
#ifdef SLAP_ZONE_ALLOC
/* has tagging option */
ai = bdb_attr_mask( be->be_private, desc->ad_type->sat_ad );
- if ( ai && ( ai->ai_indexmask ^ SLAP_INDEX_NOTAGS ) ) {
+ if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOTAGS ) ) {
*atname = desc->ad_type->sat_cname;
return ai;
}
ai = bdb_attr_mask( be->be_private, at->sat_ad );
- if ( ai && ( ai->ai_indexmask ^ SLAP_INDEX_NOSUBTYPES ) ) {
+ if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOSUBTYPES ) ) {
*atname = at->sat_cname;
return ai;
}
return rc;
}
+/* Get the list of which indices apply to this attr */
+int
+bdb_index_recset(
+ struct bdb_info *bdb,
+ Attribute *a,
+ AttributeType *type,
+ struct berval *tags,
+ IndexRec *ir )
+{
+ int rc, slot;
+ AttrList *al;
+
+ if( type->sat_sup ) {
+ /* recurse */
+ rc = bdb_index_recset( bdb, a, type->sat_sup, tags, ir );
+ if( rc ) return rc;
+ }
+ /* If this type has no AD, we've never used it before */
+ if( type->sat_ad ) {
+ slot = bdb_attr_slot( bdb, type->sat_ad, NULL );
+ if ( slot >= 0 ) {
+ ir[slot].ai = bdb->bi_attrs[slot];
+ al = ch_malloc( sizeof( AttrList ));
+ al->attr = a;
+ al->next = ir[slot].attrs;
+ ir[slot].attrs = al;
+ }
+ }
+ if( tags->bv_len ) {
+ AttributeDescription *desc;
+
+ desc = ad_find_tags( type, tags );
+ if( desc ) {
+ slot = bdb_attr_slot( bdb, desc, NULL );
+ if ( slot >= 0 ) {
+ ir[slot].ai = bdb->bi_attrs[slot];
+ al = ch_malloc( sizeof( AttrList ));
+ al->attr = a;
+ al->next = ir[slot].attrs;
+ ir[slot].attrs = al;
+ }
+ }
+ }
+ return LDAP_SUCCESS;
+}
+
+/* Apply the indices for the recset */
+int bdb_index_recrun(
+ Operation *op,
+ struct bdb_info *bdb,
+ IndexRec *ir0,
+ ID id,
+ int base )
+{
+ IndexRec *ir;
+ AttrList *al;
+ int i, rc = 0;
+
+ for (i=base; i<bdb->bi_nattrs; i+=slap_tool_thread_max) {
+ ir = ir0 + i;
+ if ( !ir->ai ) continue;
+ while (( al = ir->attrs )) {
+ ir->attrs = al->next;
+ rc = indexer( op, NULL, ir->ai->ai_desc,
+ &ir->ai->ai_desc->ad_type->sat_cname,
+ al->attr->a_nvals, id, SLAP_INDEX_ADD_OP,
+ ir->ai->ai_indexmask );
+ free( al );
+ if ( rc ) break;
+ }
+ }
+ return rc;
+}
+
int
bdb_index_entry(
Operation *op,
}
if( i == BDB_ID2ENTRY ) {
+ if ( slapMode & SLAP_TOOL_MODE )
+ db->bdi_db->mpf->set_priority( db->bdi_db->mpf,
+ DB_PRIORITY_VERY_LOW );
+
rc = db->bdi_db->set_pagesize( db->bdi_db,
BDB_ID2ENTRY_PAGESIZE );
if ( slapMode & SLAP_TOOL_READMAIN ) {
return rc;
}
-#if 0
- if( i == BDB_ID2ENTRY && ( slapMode & SLAP_TOOL_MODE )) {
- db->bdi_db->mpf->set_priority( db->bdi_db->mpf,
- DB_PRIORITY_VERY_LOW );
- }
-#endif
-
flags &= ~(DB_CREATE | DB_RDONLY);
db->bdi_name = bdbi_databases[i].name;
bdb->bi_databases[i] = db;
if( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home );
if( bdb->bi_db_config_path ) ch_free( bdb->bi_db_config_path );
- bdb_attr_index_destroy( bdb->bi_attrs );
+ bdb_attr_index_destroy( bdb );
ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock );
ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.lru_mutex );
if (op == SLAP_INDEX_ADD_OP) {
/* Add values */
- rc = bdb_idl_insert_key( be, db, txn, &key, id );
+
+#ifdef BDB_TOOL_IDL_CACHING
+ if ( slapMode & SLAP_TOOL_QUICK )
+ rc = bdb_tool_idl_add( be, db, txn, &key, id );
+ else
+#endif
+ rc = bdb_idl_insert_key( be, db, txn, &key, id );
if ( rc == DB_KEYEXIST ) rc = 0;
} else {
/* Delete values */
ctrls[num_ctrls] = NULL;
+ if ( !SLAP_SHADOW( op->o_bd ))
+ slap_mods_opattrs( op, op->orm_modlist, 1 );
+
if( 0 ) {
retry: /* transaction retry */
if ( dummy.e_attrs ) {
if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) {
rs->sr_text = "txn_abort (no-op) failed";
} else {
- rs->sr_err = LDAP_NO_OPERATION;
+ rs->sr_err = LDAP_X_NO_OPERATION;
+ ltid = NULL;
goto return_results;
}
} else {
attrs_free( dummy.e_attrs );
}
send_ldap_result( op, rs );
+ if ( !SLAP_SHADOW( op->o_bd ))
+ slap_graduate_commit_csn( op );
if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
ldap_pvt_thread_yield();
done:
if( ltid != NULL ) {
TXN_ABORT( ltid );
- op->o_private = NULL;
}
+ op->o_private = NULL;
if( e != NULL ) {
bdb_unlocked_cache_return_entry_w (&bdb->bi_cache, e);
if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
rs->sr_text = "txn_abort (no-op) failed";
} else {
- rs->sr_err = LDAP_SUCCESS;
+ rs->sr_err = LDAP_X_NO_OPERATION;
+ ltid = NULL;
goto return_results;
}
if( ltid != NULL ) {
TXN_ABORT( ltid );
- op->o_private = NULL;
}
+ op->o_private = NULL;
if( preread_ctrl != NULL ) {
slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
#define bdb_attr_mask BDB_SYMBOL(attr_mask)
#define bdb_attr_flush BDB_SYMBOL(attr_flush)
+#define bdb_attr_slot BDB_SYMBOL(attr_slot)
#define bdb_attr_index_config BDB_SYMBOL(attr_index_config)
#define bdb_attr_index_destroy BDB_SYMBOL(attr_index_destroy)
#define bdb_attr_index_free BDB_SYMBOL(attr_index_free)
#define bdb_attr_index_unparse BDB_SYMBOL(attr_index_unparse)
+#define bdb_attr_info_free BDB_SYMBOL(attr_info_free)
AttrInfo *bdb_attr_mask( struct bdb_info *bdb,
AttributeDescription *desc );
void bdb_attr_flush( struct bdb_info *bdb );
+int bdb_attr_slot( struct bdb_info *bdb,
+ AttributeDescription *desc, unsigned *insert );
+
int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb,
const char *fname, int lineno,
int argc, char **argv ));
void bdb_attr_index_unparse LDAP_P(( struct bdb_info *bdb, BerVarray *bva ));
-void bdb_attr_index_destroy LDAP_P(( Avlnode *tree ));
+void bdb_attr_index_destroy LDAP_P(( struct bdb_info *bdb ));
void bdb_attr_index_free LDAP_P(( struct bdb_info *bdb,
AttributeDescription *ad ));
+void bdb_attr_info_free( AttrInfo *ai );
+
/*
* config.c
*/
int bdb_dn2id_parent(
Operation *op,
DB_TXN *txn,
+ u_int32_t locker,
EntryInfo *ei,
ID *idp );
int bdb_id2entry(
BackendDB *be,
DB_TXN *tid,
+ u_int32_t locker,
ID id,
Entry **e);
#endif
#define bdb_index_param BDB_SYMBOL(index_param)
#define bdb_index_values BDB_SYMBOL(index_values)
#define bdb_index_entry BDB_SYMBOL(index_entry)
+#define bdb_index_recset BDB_SYMBOL(index_recset)
+#define bdb_index_recrun BDB_SYMBOL(index_recrun)
extern int
bdb_index_is_indexed LDAP_P((
ID id,
int opid ));
+extern int
+bdb_index_recset LDAP_P((
+ struct bdb_info *bdb,
+ Attribute *a,
+ AttributeType *type,
+ struct berval *tags,
+ IndexRec *ir ));
+
+extern int
+bdb_index_recrun LDAP_P((
+ Operation *op,
+ struct bdb_info *bdb,
+ IndexRec *ir,
+ ID id,
+ int base ));
+
int bdb_index_entry LDAP_P(( Operation *op, DB_TXN *t, int r, Entry *e ));
#define bdb_index_entry_add(op,t,e) \
#define bdb_cache_find_id BDB_SYMBOL(cache_find_id)
#define bdb_cache_find_info BDB_SYMBOL(cache_find_info)
#define bdb_cache_find_ndn BDB_SYMBOL(cache_find_ndn)
+#define bdb_cache_find_parent BDB_SYMBOL(cache_find_parent)
#define bdb_cache_modify BDB_SYMBOL(cache_modify)
#define bdb_cache_modrdn BDB_SYMBOL(cache_modrdn)
#define bdb_cache_release_all BDB_SYMBOL(cache_release_all)
u_int32_t locker,
DB_LOCK *lock
);
+int
+bdb_cache_find_parent(
+ Operation *op,
+ DB_TXN *txn,
+ u_int32_t locker,
+ ID id,
+ EntryInfo **res
+);
int bdb_cache_delete(
Cache *cache,
Entry *e,
#define bdb_tool_dn2id_get BDB_SYMBOL(tool_dn2id_get)
#define bdb_tool_id2entry_get BDB_SYMBOL(tool_id2entry_get)
#define bdb_tool_entry_modify BDB_SYMBOL(tool_entry_modify)
+#define bdb_tool_idl_add BDB_SYMBOL(tool_idl_add)
extern BI_init bdb_back_initialize;
extern BI_tool_id2entry_get bdb_tool_id2entry_get;
extern BI_tool_entry_modify bdb_tool_entry_modify;
+int bdb_tool_idl_add( BackendDB *be, DB *db, DB_TXN *txn, DBT *key, ID id );
+
LDAP_END_DECL
#endif /* _PROTO_BDB_H */
#define AVL_INTERNAL
#include "back-bdb.h"
+#include "idl.h"
static DBC *cursor = NULL;
static DBT key, data;
static unsigned nhmax = HOLE_SIZE;
static unsigned nholes;
-static Avlnode *index_attrs, index_dummy;
+static int index_nattrs;
+
+#ifdef BDB_TOOL_IDL_CACHING
+#define bdb_tool_idl_cmp BDB_SYMBOL(tool_idl_cmp)
+#define bdb_tool_idl_flush_one BDB_SYMBOL(tool_idl_flush_one)
+#define bdb_tool_idl_flush BDB_SYMBOL(tool_idl_flush)
+
+static int bdb_tool_idl_flush( BackendDB *be );
+
+#define IDBLOCK 1024
+
+typedef struct bdb_tool_idl_cache_entry {
+ struct bdb_tool_idl_cache_entry *next;
+ ID ids[IDBLOCK];
+} bdb_tool_idl_cache_entry;
+
+typedef struct bdb_tool_idl_cache {
+ struct berval kstr;
+ bdb_tool_idl_cache_entry *head, *tail;
+ ID first, last;
+ int count;
+} bdb_tool_idl_cache;
+
+static bdb_tool_idl_cache_entry *bdb_tool_idl_free_list;
+#endif /* BDB_TOOL_IDL_CACHING */
+
+static ID bdb_tool_ix_id;
+static Operation *bdb_tool_ix_op;
+static volatile int *bdb_tool_index_threads;
+static void *bdb_tool_index_rec;
+static struct bdb_info *bdb_tool_info;
+static ldap_pvt_thread_mutex_t bdb_tool_index_mutex;
+static ldap_pvt_thread_cond_t bdb_tool_index_cond;
+
+static int bdb_tool_ix_rec( int base );
+static void * bdb_tool_index_task( void *ctx, void *ptr );
int bdb_tool_entry_open(
BackendDB *be, int mode )
{
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
/* initialize key and data thangs */
DBTzero( &key );
DBTzero( &data );
key.flags = DB_DBT_REALLOC;
data.flags = DB_DBT_REALLOC;
+ if (cursor == NULL) {
+ int rc = bdb->bi_id2entry->bdi_db->cursor(
+ bdb->bi_id2entry->bdi_db, NULL, &cursor,
+ bdb->bi_db_opflags );
+ if( rc != 0 ) {
+ return -1;
+ }
+ }
+
+ /* Set up for slapindex */
+ if ( !(slapMode & SLAP_TOOL_READONLY )) {
+ int i;
+ if ( !bdb_tool_info && ( slapMode & SLAP_TOOL_QUICK )) {
+ ldap_pvt_thread_mutex_init( &bdb_tool_index_mutex );
+ ldap_pvt_thread_cond_init( &bdb_tool_index_cond );
+ bdb_tool_index_threads = ch_malloc( slap_tool_thread_max * sizeof( int ));
+ bdb_tool_index_rec = ch_malloc( bdb->bi_nattrs * sizeof( IndexRec ));
+ for (i=1; i<slap_tool_thread_max; i++) {
+ int *ptr = ch_malloc( sizeof( int ));
+ *ptr = i;
+ ldap_pvt_thread_pool_submit( &connection_pool,
+ bdb_tool_index_task, ptr );
+ ldap_pvt_thread_yield();
+ }
+ }
+ bdb_tool_info = bdb;
+ }
+
return 0;
}
int bdb_tool_entry_close(
BackendDB *be )
{
- assert( be != NULL );
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
+ if ( bdb_tool_info ) {
+ slapd_shutdown = 1;
+ ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
+ ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond );
+ ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
+ }
if( key.data ) {
ch_free( key.data );
cursor = NULL;
}
+#ifdef BDB_TOOL_IDL_CACHING
+ bdb_tool_idl_flush( be );
+#endif
+
if( nholes ) {
unsigned i;
fprintf( stderr, "Error, entries missing!\n");
return 0;
}
-static int bdb_reindex_cmp(const void *a, const void *b) { return 0; }
-
ID bdb_tool_entry_next(
BackendDB *be )
{
assert( slapMode & SLAP_TOOL_MODE );
assert( bdb != NULL );
- /* Initialization */
- if (cursor == NULL) {
- rc = bdb->bi_id2entry->bdi_db->cursor(
- bdb->bi_id2entry->bdi_db, NULL, &cursor,
- bdb->bi_db_opflags );
- if( rc != 0 ) {
- return NOID;
- }
- }
-
rc = cursor->c_get( cursor, &key, &data, DB_NEXT );
if( rc != 0 ) {
/* If we're doing linear indexing and there are more attrs to
* index, and we're at the end of the database, start over.
*/
- if ( bdb->bi_attrs == &index_dummy ) {
- if ( index_attrs && rc == DB_NOTFOUND ) {
- /* optional - do a checkpoint here? */
- index_dummy.avl_data = avl_delete(&index_attrs, NULL, bdb_reindex_cmp);
- rc = cursor->c_get( cursor, &key, &data, DB_FIRST );
- }
+ if ( index_nattrs && rc == DB_NOTFOUND ) {
+ /* optional - do a checkpoint here? */
+ bdb_attr_info_free( bdb->bi_attrs[0] );
+ bdb->bi_attrs[0] = bdb->bi_attrs[index_nattrs];
+ index_nattrs--;
+ rc = cursor->c_get( cursor, &key, &data, DB_FIRST );
if ( rc ) {
- bdb->bi_attrs = NULL;
return NOID;
}
} else {
Entry **e
)
{
- int rc = bdb_id2entry( be, NULL, id, e );
+ int rc = bdb_id2entry( be, NULL, 0, id, e );
if ( rc == DB_NOTFOUND && id == 0 ) {
Entry *dummy = ch_calloc( 1, sizeof(Entry) );
{
int rc;
Entry *e = NULL;
-#ifndef BDB_HIER
struct berval bv;
-#endif
assert( be != NULL );
assert( slapMode & SLAP_TOOL_MODE );
assert( data.data != NULL );
-#ifndef BDB_HIER
DBT2bv( &data, &bv );
#ifdef SLAP_ZONE_ALLOC
if( rc == LDAP_SUCCESS ) {
e->e_id = id;
}
-#else
- {
+#ifdef BDB_HIER
+ if ( slapMode & SLAP_TOOL_READONLY ) {
EntryInfo *ei = NULL;
Operation op = {0};
Opheader ohdr = {0};
op.o_tmpmemctx = NULL;
op.o_tmpmfuncs = &ch_mfuncs;
- rc = bdb_cache_find_id( &op, NULL, id, &ei, 0, 0, NULL );
- if ( rc == LDAP_SUCCESS )
- e = ei->bei_e;
+ rc = bdb_cache_find_parent( &op, NULL, cursor->locker, id, &ei );
+ if ( rc == LDAP_SUCCESS ) {
+ bdb_cache_entryinfo_unlock( ei );
+ e->e_private = ei;
+ ei->bei_e = e;
+ bdb_fix_dn( e, 0 );
+ ei->bei_e = NULL;
+ e->e_private = NULL;
+ }
}
#endif
return e;
return rc;
}
+static int
+bdb_tool_index_add(
+ Operation *op,
+ DB_TXN *txn,
+ Entry *e )
+{
+ struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
+
+ if ( slapMode & SLAP_TOOL_QUICK ) {
+ IndexRec *ir;
+ int i, rc;
+ Attribute *a;
+
+ ir = bdb_tool_index_rec;
+ memset(ir, 0, bdb->bi_nattrs * sizeof( IndexRec ));
+
+ for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+ rc = bdb_index_recset( bdb, a, a->a_desc->ad_type,
+ &a->a_desc->ad_tags, ir );
+ if ( rc )
+ return rc;
+ }
+ bdb_tool_ix_id = e->e_id;
+ bdb_tool_ix_op = op;
+ ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
+ for ( i=1; i<slap_tool_thread_max; i++ )
+ bdb_tool_index_threads[i] = LDAP_BUSY;
+ ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond );
+ ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
+ rc = bdb_index_recrun( op, bdb, ir, e->e_id, 0 );
+ if ( rc )
+ return rc;
+ for ( i=1; i<slap_tool_thread_max; i++ ) {
+ if ( bdb_tool_index_threads[i] == LDAP_BUSY ) {
+ ldap_pvt_thread_yield();
+ i--;
+ continue;
+ }
+ if ( bdb_tool_index_threads[i] )
+ return bdb_tool_index_threads[i];
+ }
+ return 0;
+ } else {
+ return bdb_index_entry_add( op, txn, e );
+ }
+}
+
ID bdb_tool_entry_put(
BackendDB *be,
Entry *e,
}
if ( !bdb->bi_linear_index )
- rc = bdb_index_entry_add( &op, tid, e );
+ rc = bdb_tool_index_add( &op, tid, e );
if( rc != 0 ) {
snprintf( text->bv_val, text->bv_len,
"index_entry_add failed: %s (%d)",
}
/* Get the first attribute to index */
- if (bi->bi_linear_index && !index_attrs && bi->bi_attrs != &index_dummy) {
- index_attrs = bi->bi_attrs;
- bi->bi_attrs = &index_dummy;
- index_dummy.avl_data = avl_delete(&index_attrs, NULL, bdb_reindex_cmp);
+ if (bi->bi_linear_index && !index_nattrs) {
+ index_nattrs = bi->bi_nattrs - 1;
+ bi->bi_nattrs = 1;
}
e = bdb_tool_entry_get( be, id );
op.o_tmpmemctx = NULL;
op.o_tmpmfuncs = &ch_mfuncs;
- rc = bdb_index_entry_add( &op, tid, e );
+ rc = bdb_tool_index_add( &op, tid, e );
done:
if( rc == 0 ) {
return e->e_id;
}
+
+#ifdef BDB_TOOL_IDL_CACHING
+static int
+bdb_tool_idl_cmp( const void *v1, const void *v2 )
+{
+ const bdb_tool_idl_cache *c1 = v1, *c2 = v2;
+ int rc;
+
+ if (( rc = c1->kstr.bv_len - c2->kstr.bv_len )) return rc;
+ return memcmp( c1->kstr.bv_val, c2->kstr.bv_val, c1->kstr.bv_len );
+}
+
+static int
+bdb_tool_idl_flush_one( void *v1, void *arg )
+{
+ bdb_tool_idl_cache *ic = v1;
+ DB *db = arg;
+ struct bdb_info *bdb = bdb_tool_info;
+ bdb_tool_idl_cache_entry *ice;
+ DBC *curs;
+ DBT key, data;
+ int i, rc;
+ ID id, nid;
+
+ /* Freshly allocated, ignore it */
+ if ( !ic->head && ic->count <= BDB_IDL_DB_SIZE ) {
+ return 0;
+ }
+
+ rc = db->cursor( db, NULL, &curs, 0 );
+ if ( rc )
+ return -1;
+
+ DBTzero( &key );
+ DBTzero( &data );
+
+ bv2DBT( &ic->kstr, &key );
+
+ data.size = data.ulen = sizeof( ID );
+ data.flags = DB_DBT_USERMEM;
+ data.data = &nid;
+
+ rc = curs->c_get( curs, &key, &data, DB_SET );
+ /* If key already exists and we're writing a range... */
+ if ( rc == 0 && ic->count > BDB_IDL_DB_SIZE ) {
+ /* If it's not currently a range, must delete old info */
+ if ( nid ) {
+ /* Skip lo */
+ while ( curs->c_get( curs, &key, &data, DB_NEXT_DUP ) == 0 )
+ curs->c_del( curs, 0 );
+
+ nid = 0;
+ /* Store range marker */
+ curs->c_put( curs, &key, &data, DB_KEYFIRST );
+ } else {
+
+ /* Skip lo */
+ rc = curs->c_get( curs, &key, &data, DB_NEXT_DUP );
+
+ /* Get hi */
+ rc = curs->c_get( curs, &key, &data, DB_NEXT_DUP );
+
+ /* Delete hi */
+ curs->c_del( curs, 0 );
+ }
+ BDB_ID2DISK( ic->last, &nid );
+ curs->c_put( curs, &key, &data, DB_KEYLAST );
+ rc = 0;
+ } else if ( rc && rc != DB_NOTFOUND ) {
+ rc = -1;
+ } else if ( ic->count > BDB_IDL_DB_SIZE ) {
+ /* range, didn't exist before */
+ nid = 0;
+ rc = curs->c_put( curs, &key, &data, DB_KEYLAST );
+ if ( rc == 0 ) {
+ BDB_ID2DISK( ic->first, &nid );
+ rc = curs->c_put( curs, &key, &data, DB_KEYLAST );
+ if ( rc == 0 ) {
+ BDB_ID2DISK( ic->last, &nid );
+ rc = curs->c_put( curs, &key, &data, DB_KEYLAST );
+ }
+ }
+ if ( rc ) {
+ rc = -1;
+ }
+ } else {
+ int n;
+
+ /* Just a normal write */
+ rc = 0;
+ for ( ice = ic->head, n=0; ice; ice = ice->next, n++ ) {
+ int end;
+ if ( ice->next ) {
+ end = IDBLOCK;
+ } else {
+ end = ic->count & (IDBLOCK-1);
+ if ( !end )
+ end = IDBLOCK;
+ }
+ for ( i=0; i<end; i++ ) {
+ if ( !ice->ids[i] ) continue;
+ BDB_ID2DISK( ice->ids[i], &nid );
+ rc = curs->c_put( curs, &key, &data, DB_NODUPDATA );
+ if ( rc ) {
+ if ( rc == DB_KEYEXIST ) {
+ rc = 0;
+ continue;
+ }
+ rc = -1;
+ break;
+ }
+ }
+ if ( rc ) {
+ rc = -1;
+ break;
+ }
+ }
+ if ( ic->head ) {
+ ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+ ic->tail->next = bdb_tool_idl_free_list;
+ bdb_tool_idl_free_list = ic->head;
+ bdb->bi_idl_cache_size -= n;
+ ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+ }
+ }
+ if ( ic != db->app_private ) {
+ ch_free( ic );
+ } else {
+ ic->head = ic->tail = NULL;
+ }
+ curs->c_close( curs );
+ return rc;
+}
+
+static int
+bdb_tool_idl_flush_db( DB *db, bdb_tool_idl_cache *ic )
+{
+ Avlnode *root = db->app_private;
+ int rc;
+
+ db->app_private = ic;
+ rc = avl_apply( root, bdb_tool_idl_flush_one, db, -1, AVL_INORDER );
+ avl_free( root, NULL );
+ db->app_private = NULL;
+ if ( rc != -1 )
+ rc = 0;
+ return rc;
+}
+
+static int
+bdb_tool_idl_flush( BackendDB *be )
+{
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+ DB *db;
+ Avlnode *root;
+ int i, rc = 0;
+
+ for ( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) {
+ db = bdb->bi_databases[i]->bdi_db;
+ if ( !db->app_private ) continue;
+ rc = bdb_tool_idl_flush_db( db, NULL );
+ if ( rc )
+ break;
+ }
+ if ( !rc ) {
+ bdb->bi_idl_cache_size = 0;
+ }
+ return rc;
+}
+
+int bdb_tool_idl_add(
+ BackendDB *be,
+ DB *db,
+ DB_TXN *txn,
+ DBT *key,
+ ID id )
+{
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+ bdb_tool_idl_cache *ic, itmp;
+ bdb_tool_idl_cache_entry *ice;
+ int rc;
+
+ if ( !bdb->bi_idl_cache_max_size )
+ return bdb_idl_insert_key( be, db, txn, key, id );
+
+ DBT2bv( key, &itmp.kstr );
+
+ ic = avl_find( (Avlnode *)db->app_private, &itmp, bdb_tool_idl_cmp );
+
+ /* No entry yet, create one */
+ if ( !ic ) {
+ DBC *curs;
+ DBT data;
+ ID nid;
+ int rc;
+
+ ic = ch_malloc( sizeof( bdb_tool_idl_cache ) + itmp.kstr.bv_len );
+ ic->kstr.bv_len = itmp.kstr.bv_len;
+ ic->kstr.bv_val = (char *)(ic+1);
+ AC_MEMCPY( ic->kstr.bv_val, itmp.kstr.bv_val, ic->kstr.bv_len );
+ ic->head = ic->tail = NULL;
+ ic->last = 0;
+ ic->count = 0;
+ avl_insert( (Avlnode **)&db->app_private, ic, bdb_tool_idl_cmp,
+ avl_dup_error );
+
+ /* load existing key count here */
+ rc = db->cursor( db, NULL, &curs, 0 );
+ if ( rc ) return rc;
+
+ data.ulen = sizeof( ID );
+ data.flags = DB_DBT_USERMEM;
+ data.data = &nid;
+ rc = curs->c_get( curs, key, &data, DB_SET );
+ if ( rc == 0 ) {
+ if ( nid == 0 ) {
+ ic->count = BDB_IDL_DB_SIZE+1;
+ } else {
+ db_recno_t count;
+
+ curs->c_count( curs, &count, 0 );
+ ic->count = count;
+ BDB_DISK2ID( &nid, &ic->first );
+ }
+ }
+ curs->c_close( curs );
+ }
+ /* are we a range already? */
+ if ( ic->count > BDB_IDL_DB_SIZE ) {
+ ic->last = id;
+ return 0;
+ /* Are we at the limit, and converting to a range? */
+ } else if ( ic->count == BDB_IDL_DB_SIZE ) {
+ int n;
+ for ( ice = ic->head, n=0; ice; ice = ice->next, n++ )
+ /* counting */ ;
+ if ( n ) {
+ ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+ ic->tail->next = bdb_tool_idl_free_list;
+ bdb_tool_idl_free_list = ic->head;
+ bdb->bi_idl_cache_size -= n;
+ ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+ }
+ ic->head = ic->tail = NULL;
+ ic->last = id;
+ ic->count++;
+ return 0;
+ }
+ /* No free block, create that too */
+ if ( !ic->tail || ( ic->count & (IDBLOCK-1)) == 0) {
+ ice = NULL;
+ ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+ if ( bdb->bi_idl_cache_size >= bdb->bi_idl_cache_max_size ) {
+ ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+ rc = bdb_tool_idl_flush_db( db, ic );
+ if ( rc )
+ return rc;
+ avl_insert( (Avlnode **)&db->app_private, ic, bdb_tool_idl_cmp,
+ avl_dup_error );
+ ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
+ }
+ bdb->bi_idl_cache_size++;
+ if ( bdb_tool_idl_free_list ) {
+ ice = bdb_tool_idl_free_list;
+ bdb_tool_idl_free_list = ice->next;
+ }
+ ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
+ if ( !ice ) {
+ ice = ch_malloc( sizeof( bdb_tool_idl_cache_entry ));
+ }
+ memset( ice, 0, sizeof( *ice ));
+ if ( !ic->head ) {
+ ic->head = ice;
+ } else {
+ ic->tail->next = ice;
+ }
+ ic->tail = ice;
+ if ( !ic->count )
+ ic->first = id;
+ }
+ ice = ic->tail;
+ ice->ids[ ic->count & (IDBLOCK-1) ] = id;
+ ic->count++;
+
+ return 0;
+}
+#endif
+
+static void *
+bdb_tool_index_task( void *ctx, void *ptr )
+{
+ int base = *(int *)ptr;
+
+ free( ptr );
+ while ( 1 ) {
+ ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
+ ldap_pvt_thread_cond_wait( &bdb_tool_index_cond,
+ &bdb_tool_index_mutex );
+ ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
+ if ( slapd_shutdown )
+ break;
+
+ bdb_tool_index_threads[base] = bdb_index_recrun( bdb_tool_ix_op,
+ bdb_tool_info, bdb_tool_index_rec, bdb_tool_ix_id, base );
+ }
+
+ return NULL;
+}
} else {
BER_BVZERO( &lc->lc_cred );
BER_BVZERO( &lc->lc_bound_ndn );
+#if 0
+ /* FIXME: if we set lc_bound_ndn = o_ndn
+ * we end up with a bind with DN but no password! */
if ( !BER_BVISEMPTY( &op->o_ndn )
&& SLAP_IS_AUTHZ_BACKEND( op ) )
{
ber_dupbv( &lc->lc_bound_ndn, &op->o_ndn );
}
+#endif
}
#ifdef HAVE_TLS
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
if ( rc != LDAP_SUCCESS || sc2.sc_private == LDAP_CH_ERR ) {
- if ( rs->sr_err == LDAP_CANNOT_CHAIN ) {
+ if ( rs->sr_err == LDAP_X_CANNOT_CHAIN ) {
goto cannot_chain;
}
case LDAP_CHAINING_REQUIRED:
cannot_chain:;
op->o_callback = NULL;
- send_ldap_error( op, rs, LDAP_CANNOT_CHAIN, "operation cannot be completed without chaining" );
+ send_ldap_error( op, rs, LDAP_X_CANNOT_CHAIN,
+ "operation cannot be completed without chaining" );
break;
default:
(char **)&rs->sr_matched,
(char **)&rs->sr_text,
NULL, NULL, 0 );
+ if ( rs->sr_matched && rs->sr_matched[ 0 ] == '\0' ) {
+ free( (char *)rs->sr_matched );
+ }
+ if ( rs->sr_text && rs->sr_text[ 0 ] == '\0' ) {
+ free( (char *)rs->sr_text );
+ }
if ( rc == LDAP_SUCCESS ) {
if ( rs->sr_err == LDAP_SUCCESS ) {
struct berval newpw;
}
}
send_ldap_result( op, rs );
- if ( rs->sr_matched ) {
- free( (char *)rs->sr_matched );
- }
- if ( rs->sr_text ) {
- free( (char *)rs->sr_text );
- }
- rs->sr_matched = NULL;
- rs->sr_text = NULL;
rc = -1;
}
+ /* these have to be freed anyway... */
+ if ( rs->sr_matched ) {
+ free( (char *)rs->sr_matched );
+ }
+ if ( rs->sr_text ) {
+ free( (char *)rs->sr_text );
+ }
+ rs->sr_matched = NULL;
+ rs->sr_text = NULL;
+
if ( lc != NULL ) {
ldap_back_release_conn( op, rs, lc );
}
if ( dnPretty( NULL, &match, &pmatch, op->o_tmpmemctx ) == LDAP_SUCCESS ) {
rs->sr_matched = pmatch.bv_val;
+ LDAP_FREE( match.bv_val );
} else {
rs->sr_matched = match.bv_val;
#include "back-ldbm.h"
#include "proto-back-ldbm.h"
+static int
+ldbm_csn_cb(
+ Operation *op,
+ SlapReply *rs )
+{
+ op->o_callback = op->o_callback->sc_next;
+ slap_graduate_commit_csn( op );
+ return SLAP_CB_CONTINUE;
+}
+
int
ldbm_back_add(
Operation *op,
AttributeDescription *entry = slap_schema.si_ad_entry;
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
+ slap_callback cb = { NULL };
#ifdef LDBM_SUBENTRIES
int subentry;
#endif
Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n",
op->o_req_dn.bv_val, 0, 0);
+ slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
+
+ cb.sc_cleanup = ldbm_csn_cb;
+ cb.sc_next = op->o_callback;
+ op->o_callback = &cb;
+
rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
get_manageDIT(op), &rs->sr_text, textbuf, textlen );
#include "slap.h"
#include "back-ldbm.h"
#include "proto-back-ldbm.h"
+#include "lutil.h"
int
ldbm_back_delete(
/* grab giant lock for writing */
ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
+ /* allocate CSN */
+ if ( !SLAP_SHADOW( op->o_bd )) {
+ struct berval csn;
+ char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
+
+ csn.bv_val = csnbuf;
+ csn.bv_len = sizeof(csnbuf);
+ slap_get_csn( op, &csn, 1 );
+ }
+
/* get entry with writer lock */
e = dn2entry_w( op->o_bd, &op->o_req_ndn, &matched );
&op->o_req_dn, LDAP_SCOPE_DEFAULT );
}
- ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
-
rs->sr_err = LDAP_REFERRAL;
- send_ldap_result( op, rs );
-
- if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
- free( (char *)rs->sr_matched );
- rs->sr_ref = NULL;
- rs->sr_matched = NULL;
- return( -1 );
+ rs->sr_flags |= REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+ goto return_results;
}
/* check entry for "entry" acl */
"<=- ldbm_back_delete: no write access to entry\n", 0,
0, 0 );
- send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
- "no write access to entry" );
-
- rc = LDAP_INSUFFICIENT_ACCESS;
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+ rs->sr_text = "no write access to entry";
goto return_results;
}
0, 0 );
rs->sr_err = LDAP_REFERRAL;
- rs->sr_matched = e->e_name.bv_val;
- send_ldap_result( op, rs );
-
- if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
- rs->sr_ref = NULL;
- rs->sr_matched = NULL;
- rc = LDAP_REFERRAL;
+ rs->sr_matched = ch_strdup( e->e_name.bv_val );
+ rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
goto return_results;
}
Debug(LDAP_DEBUG_ARGS, "<=- ldbm_back_delete: non leaf %s\n",
op->o_req_dn.bv_val, 0, 0);
- send_ldap_error( op, rs, LDAP_NOT_ALLOWED_ON_NONLEAF,
- "subordinate objects must be deleted first");
+ rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
+ rs->sr_text = "subordinate objects must be deleted first";
goto return_results;
}
"<=- ldbm_back_delete: parent does not exist\n",
0, 0, 0);
- send_ldap_error( op, rs, LDAP_OTHER,
- "could not locate parent of entry" );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "could not locate parent of entry";
goto return_results;
}
"<=- ldbm_back_delete: no access to parent\n", 0,
0, 0 );
- send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
- "no write access to parent" );
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+ rs->sr_text = "no write access to parent";
goto return_results;
}
"<=- ldbm_back_delete: no "
"access to parent\n", 0, 0, 0 );
- send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
- "no write access to parent" );
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+ rs->sr_text = "no write access to parent";
goto return_results;
}
"<=- ldbm_back_delete: no parent & "
"not root\n", 0, 0, 0);
- send_ldap_error( op, rs,
- LDAP_INSUFFICIENT_ACCESS,
- NULL );
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
goto return_results;
}
}
"<=- ldbm_back_delete: operations error %s\n",
op->o_req_dn.bv_val, 0, 0);
- send_ldap_error( op, rs, LDAP_OTHER,
- "DN index delete failed" );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "DN index delete failed";
goto return_results;
}
"<=- ldbm_back_delete: operations error %s\n",
op->o_req_dn.bv_val, 0, 0);
- send_ldap_error( op, rs, LDAP_OTHER,
- "entry delete failed" );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "entry delete failed";
goto return_results;
}
(void) index_entry_del( op, e );
rs->sr_err = LDAP_SUCCESS;
- send_ldap_result( op, rs );
- rc = LDAP_SUCCESS;
return_results:;
+ rc = rs->sr_err;
+
if( p != NULL ) {
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
}
- /* free entry and writer lock */
- cache_return_entry_w( &li->li_cache, e );
+ if ( e != NULL ) {
+ /* free entry and writer lock */
+ cache_return_entry_w( &li->li_cache, e );
+ }
ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
+ send_ldap_result( op, rs );
+ if ( !SLAP_SHADOW( op->o_bd ))
+ slap_graduate_commit_csn( op );
+
return rc;
}
Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0);
+ if ( !SLAP_SHADOW( op->o_bd ))
+ slap_mods_opattrs( op, op->orm_modlist, 1 );
+
/* grab giant lock for writing */
ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
/* FIXME: dn2entry() should return non-glue entry */
if (( e == NULL ) || ( !manageDSAit && e && is_entry_glue( e ))) {
if ( matched != NULL ) {
- rs->sr_matched = ch_strdup( matched->e_dn );
+ rs->sr_matched = ber_strdup_x( matched->e_dn, op->o_tmpmemctx );
rs->sr_ref = is_entry_referral( matched )
? get_entry_referrals( op, matched )
: NULL;
&op->o_req_dn, LDAP_SCOPE_DEFAULT );
}
- ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
rs->sr_err = LDAP_REFERRAL;
- send_ldap_result( op, rs );
-
- if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
- free( (char *)rs->sr_matched );
-
- rs->sr_ref = NULL;
- rs->sr_matched = NULL;
- return rs->sr_err;
+ rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+ goto return_results;
}
if ( !manageDSAit && is_entry_referral( e ) )
0, 0 );
rs->sr_err = LDAP_REFERRAL;
- rs->sr_matched = e->e_name.bv_val;
- send_ldap_result( op, rs );
-
- if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref );
- rs->sr_ref = NULL;
- rs->sr_matched = NULL;
- goto error_return;
+ rs->sr_matched = ber_strdup_x( e->e_name.bv_val, op->o_tmpmemctx );
+ rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+ goto return_results;
}
/* Modify the entry */
rs->sr_err = ldbm_modify_internal( op, op->oq_modify.rs_modlist, e,
&rs->sr_text, textbuf, textlen );
- if( rs->sr_err != LDAP_SUCCESS ) {
- if( rs->sr_err != SLAPD_ABANDON ) {
- send_ldap_result( op, rs );
- }
-
- goto error_return;
- }
-
/* change the entry itself */
- if ( id2entry_add( op->o_bd, e ) != 0 ) {
- send_ldap_error( op, rs, LDAP_OTHER,
- "id2entry failure" );
- rs->sr_err = LDAP_OTHER;
- goto error_return;
+ if( rs->sr_err == LDAP_SUCCESS ) {
+ if ( id2entry_add( op->o_bd, e ) != 0 ) {
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "id2entry failure";
+ }
}
- rs->sr_text = NULL;
- send_ldap_error( op, rs, LDAP_SUCCESS,
- NULL );
-
+return_results:;
cache_return_entry_w( &li->li_cache, e );
ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
- return LDAP_SUCCESS;
+ send_ldap_result( op, rs );
+ if ( !SLAP_SHADOW( op->o_bd ))
+ slap_graduate_commit_csn( op );
-error_return:;
- cache_return_entry_w( &li->li_cache, e );
- ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
rs->sr_text = NULL;
return rs->sr_err;
}
int statres;
char textbuf[SLAP_TEXT_BUFLEN];
+ slap_add_opattrs( op, &rs->sr_text, textbuf, sizeof( textbuf ),
+ op->o_bd->be_pcl_mutexp != NULL ? 1 : 0 );
+
rs->sr_err = entry_schema_check(op, e, NULL, 0,
&rs->sr_text, textbuf, sizeof( textbuf ) );
if ( rs->sr_err != LDAP_SUCCESS ) goto send_res;
send_res:
send_ldap_result(op, rs);
+ if ( !SLAP_SHADOW( op->o_bd ))
+ slap_graduate_commit_csn( op );
return 0;
}
Entry * entry = NULL;
int spew_res;
+ if ( !SLAP_SHADOW( op->o_bd ))
+ slap_mods_opattrs( op, op->orm_modlist,
+ op->o_bd->be_pcl_mutexp != NULL ? 1 : 0 );
+
ldap_pvt_thread_mutex_lock(&ni->li_mutex);
dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path,
&path);
rs->sr_text = NULL;
ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
send_ldap_result(op, rs);
+ if ( !SLAP_SHADOW( op->o_bd ))
+ slap_graduate_commit_csn( op );
return 0;
}
struct berval path = BER_BVNULL;
int res = 0;
+ if ( !SLAP_SHADOW( op->o_bd )) {
+ struct berval csn;
+ char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
+
+ csn.bv_val = csnbuf;
+ csn.bv_len = sizeof( csnbuf );
+ slap_get_csn( op, &csn, 1 );
+ }
+
ldap_pvt_thread_mutex_lock(&ni->li_mutex);
dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, &path);
SLAP_FREE(path.bv_val);
ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
send_ldap_result(op, rs);
+ if ( !SLAP_SHADOW( op->o_bd ))
+ slap_graduate_commit_csn( op );
return 0;
}
if ( META_BACK_DEFER_ROOTDN_BIND( mi ) ) {
rs->sr_err = LDAP_SUCCESS;
rs->sr_text = NULL;
- send_ldap_result( op, rs );
+ /* frontend will return success */
return rs->sr_err;
}
rs->sr_err = lerr;
candidates[ i ].sr_tag = META_NOT_CANDIDATE;
- if ( META_BACK_ONERR_STOP( mi ) ) {
- rc = rs->sr_err;
- break;
- }
+ rc = rs->sr_err;
+ break;
}
}
if ( rs->sr_err == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) {
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
if ( mc->mc_refcnt == 1 ) {
- ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
- msc->msc_ld = NULL;
+ meta_clear_one_candidate( msc );
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
}
if ( mc->mc_refcnt == 1 ) {
- ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
- msc->msc_ld = NULL;
+ meta_clear_one_candidate( msc );
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
metasingleconn_t *msc )
{
if ( msc->msc_ld ) {
- ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
+ ldap_unbind_ext( msc->msc_ld, NULL, NULL );
msc->msc_ld = NULL;
}
if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
- ber_memfree( msc->msc_bound_ndn.bv_val );
+ ber_memfree_x( msc->msc_bound_ndn.bv_val, NULL );
BER_BVZERO( &msc->msc_bound_ndn );
}
if ( !BER_BVISNULL( &msc->msc_cred ) ) {
memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
- ber_memfree( msc->msc_cred.bv_val );
+ ber_memfree_x( msc->msc_cred.bv_val, NULL );
BER_BVZERO( &msc->msc_cred );
}
int rc;
int c;
- if ( argc != 2 ) {
+ switch ( argc ) {
+ case 1:
fprintf( stderr,
- "%s: line %d: missing address"
- " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
+ "%s: line %d: missing URI "
+ "in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
+ fname, lineno );
+ return 1;
+
+ case 2:
+ break;
+
+ default:
+ fprintf( stderr,
+ "%s: line %d: too many args "
+ "in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
fname, lineno );
return 1;
}
fname, lineno );
return 1;
}
- ber_str2bv( src, 0, 1, &mapping->src );
- ber_str2bv( dst, 0, 1, &mapping->dst );
- mapping[ 1 ].src = mapping->dst;
- mapping[ 1 ].dst = mapping->src;
+ ber_str2bv( src, 0, 1, &mapping[ 0 ].src );
+ ber_str2bv( dst, 0, 1, &mapping[ 0 ].dst );
+ mapping[ 1 ].src = mapping[ 0 ].dst;
+ mapping[ 1 ].dst = mapping[ 0 ].src;
/*
* schema check
*/
if ( is_oc ) {
if ( src[ 0 ] != '\0' ) {
- if ( oc_bvfind( &mapping->src ) == NULL ) {
+ if ( oc_bvfind( &mapping[ 0 ].src ) == NULL ) {
fprintf( stderr,
"%s: line %d: warning, source objectClass '%s' "
"should be defined in schema\n",
}
}
- if ( oc_bvfind( &mapping->dst ) == NULL ) {
+ if ( oc_bvfind( &mapping[ 0 ].dst ) == NULL ) {
fprintf( stderr,
"%s: line %d: warning, destination objectClass '%s' "
"is not defined in schema\n",
AttributeDescription *ad = NULL;
if ( src[ 0 ] != '\0' ) {
- rc = slap_bv2ad( &mapping->src, &ad, &text );
+ rc = slap_bv2ad( &mapping[ 0 ].src, &ad, &text );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr,
"%s: line %d: warning, source attributeType '%s' "
* and add it here.
*/
- rc = slap_bv2undef_ad( &mapping->src,
+ rc = slap_bv2undef_ad( &mapping[ 0 ].src,
&ad, &text, SLAP_AD_PROXIED );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr,
ad = NULL;
}
- rc = slap_bv2ad( &mapping->dst, &ad, &text );
+ rc = slap_bv2ad( &mapping[ 0 ].dst, &ad, &text );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr,
"%s: line %d: warning, destination attributeType '%s' "
* and add it here.
*/
- rc = slap_bv2undef_ad( &mapping->dst,
+ rc = slap_bv2undef_ad( &mapping[ 0 ].dst,
&ad, &text, SLAP_AD_PROXIED );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr,
}
}
- if ( (src[ 0 ] != '\0' && avl_find( map->map, (caddr_t)mapping, mapping_cmp ) != NULL)
+ if ( (src[ 0 ] != '\0' && avl_find( map->map, (caddr_t)&mapping[ 0 ], mapping_cmp ) != NULL)
|| avl_find( map->remap, (caddr_t)&mapping[ 1 ], mapping_cmp ) != NULL)
{
fprintf( stderr,
}
if ( src[ 0 ] != '\0' ) {
- avl_insert( &map->map, (caddr_t)mapping,
+ avl_insert( &map->map, (caddr_t)&mapping[ 0 ],
mapping_cmp, mapping_dup );
}
avl_insert( &map->remap, (caddr_t)&mapping[ 1 ],
error_return:;
if ( mapping ) {
- ch_free( mapping->src.bv_val );
- ch_free( mapping->dst.bv_val );
+ ch_free( mapping[ 0 ].src.bv_val );
+ ch_free( mapping[ 0 ].dst.bv_val );
ch_free( mapping );
}
goto retry_lock;
}
- ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
- msc->msc_ld = NULL;
+ meta_clear_one_candidate( msc );
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
ntargets = mc->mc_conns[ 0 ].msc_info->mi_ntargets;
for ( i = 0; i < ntargets; i++ ) {
- metasingleconn_t *msc = &mc->mc_conns[ i ];
-
- if ( msc->msc_ld != NULL ) {
- ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
- }
-
- if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
- ber_memfree( msc->msc_bound_ndn.bv_val );
- }
-
- if ( !BER_BVISNULL( &msc->msc_cred ) ) {
- /* destroy sensitive data */
- memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
- ber_memfree( msc->msc_cred.bv_val );
- }
+ (void)meta_clear_one_candidate( &mc->mc_conns[ i ] );
}
ldap_pvt_thread_mutex_destroy( &mc->mc_mutex );
ch_free( mapping );
}
+static void
+mapping_dst_free(
+ void *v_mapping )
+{
+ struct ldapmapping *mapping = v_mapping;
+
+ if ( BER_BVISEMPTY( &mapping->dst ) ) {
+ mapping_free( &mapping[ -1 ] );
+ }
+}
+
static void
target_free(
metatarget_t *mt )
if ( mt->mt_rwmap.rwm_rw ) {
rewrite_info_delete( &mt->mt_rwmap.rwm_rw );
}
- avl_free( mt->mt_rwmap.rwm_oc.remap, NULL );
+ avl_free( mt->mt_rwmap.rwm_oc.remap, mapping_dst_free );
avl_free( mt->mt_rwmap.rwm_oc.map, mapping_free );
- avl_free( mt->mt_rwmap.rwm_at.remap, NULL );
+ avl_free( mt->mt_rwmap.rwm_at.remap, mapping_dst_free );
avl_free( mt->mt_rwmap.rwm_at.map, mapping_free );
}
* Destroy the per-target stuff (assuming there's at
* least one ...)
*/
- for ( i = 0; i < mi->mi_ntargets; i++ ) {
- target_free( &mi->mi_targets[ i ] );
- }
+ if ( mi->mi_targets != NULL ) {
+ for ( i = 0; i < mi->mi_ntargets; i++ ) {
+ target_free( &mi->mi_targets[ i ] );
+ }
- free( mi->mi_targets );
+ free( mi->mi_targets );
+ }
ldap_pvt_thread_mutex_lock( &mi->mi_cache.mutex );
if ( mi->mi_cache.tree ) {
ldap_back_map( &dc->target->mt_rwmap.rwm_at, &ad->ad_cname, mapped_attr, remap );
if ( BER_BVISNULL( mapped_attr ) || BER_BVISEMPTY( mapped_attr ) ) {
+#if 0
/*
* FIXME: are we sure we need to search oc_map if at_map fails?
*/
if ( BER_BVISNULL( mapped_attr ) || BER_BVISEMPTY( mapped_attr ) ) {
*mapped_attr = ad->ad_cname;
}
+#endif
+ if ( dc->target->mt_rwmap.rwm_at.drop_missing ) {
+ return -1;
+ }
+
+ *mapped_attr = ad->ad_cname;
}
if ( value == NULL ) {
{
int i;
Filter *p;
- struct berval atmp;
- struct berval vtmp;
+ struct berval atmp,
+ vtmp,
+ *tmp;
+ static struct berval
+ /* better than nothing... */
+ ber_bvfalse = BER_BVC( "(!(objectClass=*))" ),
+ ber_bvtf_false = BER_BVC( "(|)" ),
+ /* better than nothing... */
+ ber_bvtrue = BER_BVC( "(objectClass=*)" ),
+ ber_bvtf_true = BER_BVC( "(&)" ),
+#if 0
+ /* no longer needed; preserved for completeness */
+ ber_bvundefined = BER_BVC( "(?=undefined)" ),
+#endif
+ ber_bverror = BER_BVC( "(?=error)" ),
+ ber_bvunknown = BER_BVC( "(?=unknown)" ),
+ ber_bvnone = BER_BVC( "(?=none)" );
ber_len_t len;
if ( f == NULL ) {
- ber_str2bv( "No filter!", STRLENOF( "No filter!" ), 1, fstr );
- return -1;
+ ber_dupbv( fstr, &ber_bvnone );
+ return LDAP_OTHER;
}
switch ( f->f_choice ) {
if ( map_attr_value( dc, f->f_av_desc, &atmp,
&f->f_av_value, &vtmp, remap ) )
{
- return -1;
+ goto computed;
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len
if ( map_attr_value( dc, f->f_av_desc, &atmp,
&f->f_av_value, &vtmp, remap ) )
{
- return -1;
+ goto computed;
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len
if ( map_attr_value( dc, f->f_av_desc, &atmp,
&f->f_av_value, &vtmp, remap ) )
{
- return -1;
+ goto computed;
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len
if ( map_attr_value( dc, f->f_av_desc, &atmp,
&f->f_av_value, &vtmp, remap ) )
{
- return -1;
+ goto computed;
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len
if ( map_attr_value( dc, f->f_sub_desc, &atmp,
NULL, NULL, remap ) )
{
- return -1;
+ goto computed;
}
/* cannot be a DN ... */
if ( map_attr_value( dc, f->f_desc, &atmp,
NULL, NULL, remap ) )
{
- return -1;
+ goto computed;
}
fstr->bv_len = atmp.bv_len + ( STRLENOF( "(=*)" ) );
f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
for ( p = f->f_list; p != NULL; p = p->f_next ) {
+ int rc;
+
len = fstr->bv_len;
- if ( ldap_back_int_filter_map_rewrite( dc, p, &vtmp, remap ) )
- {
- return -1;
+ rc = ldap_back_int_filter_map_rewrite( dc, p, &vtmp, remap );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
}
fstr->bv_len += vtmp.bv_len;
if ( map_attr_value( dc, f->f_mr_desc, &atmp,
&f->f_mr_value, &vtmp, remap ) )
{
- return -1;
+ goto computed;
}
} else {
ber_memfree( vtmp.bv_val );
break;
- case SLAPD_FILTER_COMPUTED: {
- struct berval bv;
-
+ case SLAPD_FILTER_COMPUTED:
switch ( f->f_result ) {
case LDAP_COMPARE_FALSE:
+ /* FIXME: treat UNDEFINED as FALSE */
+ case SLAPD_COMPARE_UNDEFINED:
+computed:;
if ( dc->target->mt_flags & LDAP_BACK_F_SUPPORT_T_F ) {
- BER_BVSTR( &bv, "(|)" );
+ tmp = &ber_bvtf_false;
break;
}
- /* fallthru */
-
- /* FIXME: treat UNDEFINED as FALSE */
- case SLAPD_COMPARE_UNDEFINED:
- /* better than nothing... */
- BER_BVSTR( &bv, "(!(objectClass=*))" );
+ tmp = &ber_bvfalse;
break;
case LDAP_COMPARE_TRUE:
if ( dc->target->mt_flags & LDAP_BACK_F_SUPPORT_T_F ) {
- BER_BVSTR( &bv, "(&)" );
+ tmp = &ber_bvtf_true;
break;
}
- /* better than nothing... */
- BER_BVSTR( &bv, "(objectClass=*)" );
+ tmp = &ber_bvtrue;
break;
default:
- BER_BVSTR( &bv, "(?=error)" );
+ tmp = &ber_bverror;
break;
}
- ber_dupbv( fstr, &bv );
- } break;
+ ber_dupbv( fstr, tmp );
+ break;
default:
- ber_str2bv( "(?=unknown)", STRLENOF( "(?=unknown)" ), 1, fstr );
+ ber_dupbv( fstr, &ber_bvunknown );
break;
}
ludp->lud_dn = dn.bv_val;
newurl = ldap_url_desc2str( ludp );
+ free( dn.bv_val );
if ( newurl == NULL ) {
/* FIXME: leave attr untouched
* even if ldap_url_desc2str failed...
ldap_back_map( &mi->mi_targets[ target ].mt_rwmap.rwm_at,
&a, &mapped, BACKLDAP_REMAP );
if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
+ ( void )ber_scanf( &ber, "x" /* [W] */ );
continue;
}
- attr = ( Attribute * )ch_malloc( sizeof( Attribute ) );
+ attr = ( Attribute * )ch_calloc( 1, sizeof( Attribute ) );
if ( attr == NULL ) {
continue;
}
- attr->a_flags = 0;
- attr->a_next = 0;
- attr->a_desc = NULL;
if ( slap_bv2ad( &mapped, &attr->a_desc, &text )
!= LDAP_SUCCESS) {
if ( slap_bv2undef_ad( &mapped, &attr->a_desc, &text,
pretty = attr->a_desc->ad_type->sat_syntax->ssyn_pretty;
if ( !validate && !pretty ) {
- attr->a_nvals = NULL;
attr_free( attr );
goto next_attr;
}
* ACLs to the target directory server, and letting
* everything pass thru the ldap backend.
*/
- } else if ( attr->a_desc->ad_type->sat_syntax ==
+ } else {
+ int i;
+
+ if ( attr->a_desc->ad_type->sat_syntax ==
slap_schema.si_syn_distinguishedName )
- {
- ldap_dnattr_result_rewrite( &dc, attr->a_vals );
+ {
+ ldap_dnattr_result_rewrite( &dc, attr->a_vals );
- } else if ( attr->a_desc == slap_schema.si_ad_ref ) {
- ldap_back_referral_result_rewrite( &dc, attr->a_vals );
+ } else if ( attr->a_desc == slap_schema.si_ad_ref ) {
+ ldap_back_referral_result_rewrite( &dc, attr->a_vals );
- } else {
- int i;
+ }
for ( i = 0; i < last; i++ ) {
struct berval pval;
conn->c_connid, 0, 0 );
mc_curr.mc_conn = conn;
+ mc_curr.mc_local_ndn = conn->c_ndn;
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
mc = avl_delete( &mi->mi_conntree, ( caddr_t )&mc_curr,
assert( mc->mc_refcnt == 0 );
- for ( i = 0; i < mi->mi_ntargets; ++i ) {
- if ( mc->mc_conns[ i ].msc_ld != NULL ) {
- meta_clear_one_candidate( &mc->mc_conns[ i ] );
- }
- }
-
meta_back_conn_free( mc );
}
if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_rdn ) ) {
ch_free( monitor_subsys[ i ]->mss_rdn.bv_val );
}
+
+ if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_dn ) ) {
+ ch_free( monitor_subsys[ i ]->mss_dn.bv_val );
+ }
+
+ if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_ndn ) ) {
+ ch_free( monitor_subsys[ i ]->mss_ndn.bv_val );
+ }
}
ch_free( monitor_subsys );
#include "ldif.h"
#include "back-monitor.h"
-static int
-monitor_subsys_log_destroy(
+static int
+monitor_subsys_log_open(
BackendDB *be,
monitor_subsys_t *ms );
*/
ldap_pvt_thread_mutex_t monitor_log_mutex;
-static struct {
- int i;
- struct berval s;
- struct berval n;
-} int_2_level[] = {
- { LDAP_DEBUG_TRACE, BER_BVC("Trace"), BER_BVNULL },
- { LDAP_DEBUG_PACKETS, BER_BVC("Packets"), BER_BVNULL },
- { LDAP_DEBUG_ARGS, BER_BVC("Args"), BER_BVNULL },
- { LDAP_DEBUG_CONNS, BER_BVC("Conns"), BER_BVNULL },
- { LDAP_DEBUG_BER, BER_BVC("BER"), BER_BVNULL },
- { LDAP_DEBUG_FILTER, BER_BVC("Filter"), BER_BVNULL },
- { LDAP_DEBUG_CONFIG, BER_BVC("Config"), BER_BVNULL }, /* useless */
- { LDAP_DEBUG_ACL, BER_BVC("ACL"), BER_BVNULL },
- { LDAP_DEBUG_STATS, BER_BVC("Stats"), BER_BVNULL },
- { LDAP_DEBUG_STATS2, BER_BVC("Stats2"), BER_BVNULL },
- { LDAP_DEBUG_SHELL, BER_BVC("Shell"), BER_BVNULL },
- { LDAP_DEBUG_PARSE, BER_BVC("Parse"), BER_BVNULL },
- { LDAP_DEBUG_CACHE, BER_BVC("Cache"), BER_BVNULL },
- { LDAP_DEBUG_INDEX, BER_BVC("Index"), BER_BVNULL },
- { 0, BER_BVNULL, BER_BVNULL }
-};
-
-static int loglevel2int( struct berval *l );
-static int int2loglevel( int n );
-
-static int add_values( Entry *e, Modification *mod, int *newlevel );
-static int delete_values( Entry *e, Modification *mod, int *newlevel );
-static int replace_values( Entry *e, Modification *mod, int *newlevel );
+static int add_values( Operation *op, Entry *e, Modification *mod, int *newlevel );
+static int delete_values( Operation *op, Entry *e, Modification *mod, int *newlevel );
+static int replace_values( Operation *op, Entry *e, Modification *mod, int *newlevel );
/*
* initializes log subentry
BackendDB *be,
monitor_subsys_t *ms )
{
- monitor_info_t *mi;
- Entry *e;
- int i;
-
- ms->mss_destroy = monitor_subsys_log_destroy;
+ ms->mss_open = monitor_subsys_log_open;
ms->mss_modify = monitor_subsys_log_modify;
ldap_pvt_thread_mutex_init( &monitor_log_mutex );
- mi = ( monitor_info_t * )be->be_private;
-
- if ( monitor_cache_get( mi, &ms->mss_ndn,
- &e ) ) {
- Debug( LDAP_DEBUG_ANY,
- "monitor_subsys_log_init: "
- "unable to get entry \"%s\"\n",
- ms->mss_ndn.bv_val, 0, 0 );
- return( -1 );
- }
-
- /* initialize the debug level(s) */
- for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
- if ( mi->mi_ad_managedInfo->ad_type->sat_equality->smr_normalize ) {
- int rc;
-
- rc = (*mi->mi_ad_managedInfo->ad_type->sat_equality->smr_normalize)(
- SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
- mi->mi_ad_managedInfo->ad_type->sat_syntax,
- mi->mi_ad_managedInfo->ad_type->sat_equality,
- &int_2_level[ i ].s,
- &int_2_level[ i ].n, NULL );
- if ( rc ) {
- return( -1 );
- }
- }
-
- if ( int_2_level[ i ].i & ldap_syslog ) {
- attr_merge_one( e, mi->mi_ad_managedInfo,
- &int_2_level[ i ].s,
- &int_2_level[ i ].n );
- }
- }
-
- monitor_cache_release( mi, e );
-
return( 0 );
}
-static int
-monitor_subsys_log_destroy(
+/*
+ * opens log subentry
+ */
+int
+monitor_subsys_log_open(
BackendDB *be,
monitor_subsys_t *ms )
{
- int i;
+ BerVarray bva = NULL;
+
+ if ( loglevel2bvarray( ldap_syslog, &bva ) == 0 && bva != NULL ) {
+ monitor_info_t *mi;
+ Entry *e;
- for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
- if ( !BER_BVISNULL( &int_2_level[ i ].n ) ) {
- ch_free( int_2_level[ i ].n.bv_val );
+ mi = ( monitor_info_t * )be->be_private;
+
+ if ( monitor_cache_get( mi, &ms->mss_ndn, &e ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "monitor_subsys_log_init: "
+ "unable to get entry \"%s\"\n",
+ ms->mss_ndn.bv_val, 0, 0 );
+ ber_bvarray_free( bva );
+ return( -1 );
}
+
+ attr_merge_normalize( e, mi->mi_ad_managedInfo, bva, NULL );
+ ber_bvarray_free( bva );
+
+ monitor_cache_release( mi, e );
}
- return 0;
+ return( 0 );
}
static int
*/
if ( is_at_operational( mod->sm_desc->ad_type ) ) {
( void ) attr_delete( &e->e_attrs, mod->sm_desc );
- rc = rs->sr_err = attr_merge( e, mod->sm_desc, mod->sm_values, mod->sm_nvalues );
+ rc = rs->sr_err = attr_merge( e, mod->sm_desc,
+ mod->sm_values, mod->sm_nvalues );
if ( rc != LDAP_SUCCESS ) {
break;
}
switch ( mod->sm_op ) {
case LDAP_MOD_ADD:
- rc = add_values( e, mod, &newlevel );
+ rc = add_values( op, e, mod, &newlevel );
break;
case LDAP_MOD_DELETE:
- rc = delete_values( e, mod, &newlevel );
+ rc = delete_values( op, e, mod, &newlevel );
break;
case LDAP_MOD_REPLACE:
- rc = replace_values( e, mod, &newlevel );
+ rc = replace_values( op, e, mod, &newlevel );
break;
default:
}
static int
-loglevel2int( struct berval *l )
+check_constraints( Modification *mod, int *newlevel )
{
int i;
-
- for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
- if ( l->bv_len != int_2_level[ i ].s.bv_len ) {
- continue;
- }
-
- if ( strcasecmp( l->bv_val, int_2_level[ i ].s.bv_val ) == 0 ) {
- return int_2_level[ i ].i;
- }
- }
-
- return 0;
-}
-static int
-int2loglevel( int n )
-{
- int i;
-
- for ( i = 0; int_2_level[ i ].i != 0; i++ ) {
- if ( int_2_level[ i ].i == n ) {
- return i;
- }
+ if ( mod->sm_nvalues != NULL ) {
+ ber_bvarray_free( mod->sm_nvalues );
+ mod->sm_nvalues = NULL;
}
- return -1;
-}
-
-static int
-check_constraints( Modification *mod, int *newlevel )
-{
- int i;
-
- for ( i = 0; mod->sm_values && !BER_BVISNULL( &mod->sm_values[ i ] ); i++ ) {
+ for ( i = 0; !BER_BVISNULL( &mod->sm_values[ i ] ); i++ ) {
int l;
-
- l = loglevel2int( &mod->sm_values[ i ] );
- if ( !l ) {
+ struct berval bv;
+
+ if ( str2loglevel( mod->sm_values[ i ].bv_val, &l ) ) {
return LDAP_CONSTRAINT_VIOLATION;
}
- if ( ( l = int2loglevel( l ) ) == -1 ) {
- return LDAP_OTHER;
+ if ( loglevel2bv( l, &bv ) ) {
+ return LDAP_CONSTRAINT_VIOLATION;
}
-
- assert( int_2_level[ l ].s.bv_len
- == mod->sm_values[ i ].bv_len );
+
+ assert( bv.bv_len == mod->sm_values[ i ].bv_len );
AC_MEMCPY( mod->sm_values[ i ].bv_val,
- int_2_level[ l ].s.bv_val,
- int_2_level[ l ].s.bv_len );
-
- AC_MEMCPY( mod->sm_nvalues[ i ].bv_val,
- int_2_level[ l ].n.bv_val,
- int_2_level[ l ].n.bv_len );
+ bv.bv_val, bv.bv_len );
*newlevel |= l;
}
}
static int
-add_values( Entry *e, Modification *mod, int *newlevel )
+add_values( Operation *op, Entry *e, Modification *mod, int *newlevel )
{
Attribute *a;
int i, rc;
MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
+ assert( mod->sm_values != NULL );
+
rc = check_constraints( mod, newlevel );
if ( rc != LDAP_SUCCESS ) {
return rc;
rc = asserted_value_validate_normalize(
mod->sm_desc, mr, SLAP_MR_EQUALITY,
- &mod->sm_values[ i ], &asserted, &text, NULL );
+ &mod->sm_values[ i ], &asserted, &text,
+ op->o_tmpmemctx );
if ( rc != LDAP_SUCCESS ) {
return rc;
for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) {
int match;
int rc = value_match( &match, mod->sm_desc, mr,
- 0, &a->a_vals[ j ], &asserted, &text );
+ 0, &a->a_nvals[ j ], &asserted, &text );
if ( rc == LDAP_SUCCESS && match == 0 ) {
free( asserted.bv_val );
}
/* no - add them */
- rc = attr_merge( e, mod->sm_desc, mod->sm_values, mod->sm_nvalues );
+ rc = attr_merge_normalize( e, mod->sm_desc, mod->sm_values,
+ op->o_tmpmemctx );
if ( rc != LDAP_SUCCESS ) {
- /* this should return result of attr_mergeit */
return rc;
}
}
static int
-delete_values( Entry *e, Modification *mod, int *newlevel )
+delete_values( Operation *op, Entry *e, Modification *mod, int *newlevel )
{
int i, j, k, found, rc, nl = 0;
Attribute *a;
MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
- rc = check_constraints( mod, &nl );
- if ( rc != LDAP_SUCCESS ) {
- return rc;
- }
-
- *newlevel &= ~nl;
-
/* delete the entire attribute */
if ( mod->sm_values == NULL ) {
int rc = attr_delete( &e->e_attrs, mod->sm_desc );
if ( rc ) {
rc = LDAP_NO_SUCH_ATTRIBUTE;
+
} else {
*newlevel = 0;
rc = LDAP_SUCCESS;
return rc;
}
+ rc = check_constraints( mod, &nl );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ *newlevel &= ~nl;
+
if ( mr == NULL || !mr->smr_match ) {
/* disallow specific attributes from being deleted if
* no equality rule */
rc = asserted_value_validate_normalize(
mod->sm_desc, mr, SLAP_MR_EQUALITY,
- &mod->sm_values[ i ], &asserted, &text, NULL );
+ &mod->sm_values[ i ], &asserted, &text,
+ op->o_tmpmemctx );
if( rc != LDAP_SUCCESS ) return rc;
for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) {
int match;
int rc = value_match( &match, mod->sm_desc, mr,
- 0,
- &a->a_vals[ j ], &asserted, &text );
+ 0, &a->a_nvals[ j ], &asserted, &text );
if( rc == LDAP_SUCCESS && match != 0 ) {
continue;
found = 1;
/* delete it */
+ if ( a->a_nvals != a->a_vals ) {
+ free( a->a_nvals[ j ].bv_val );
+ for ( k = j + 1; !BER_BVISNULL( &a->a_nvals[ k ] ); k++ ) {
+ a->a_nvals[ k - 1 ] = a->a_nvals[ k ];
+ }
+ BER_BVZERO( &a->a_nvals[ k - 1 ] );
+ }
+
free( a->a_vals[ j ].bv_val );
for ( k = j + 1; !BER_BVISNULL( &a->a_vals[ k ] ); k++ ) {
a->a_vals[ k - 1 ] = a->a_vals[ k ];
}
static int
-replace_values( Entry *e, Modification *mod, int *newlevel )
+replace_values( Operation *op, Entry *e, Modification *mod, int *newlevel )
{
int rc;
- *newlevel = 0;
- rc = check_constraints( mod, newlevel );
- if ( rc != LDAP_SUCCESS ) {
- return rc;
+ if ( mod->sm_values != NULL ) {
+ *newlevel = 0;
+ rc = check_constraints( mod, newlevel );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
}
rc = attr_delete( &e->e_attrs, mod->sm_desc );
}
if ( mod->sm_values != NULL ) {
- rc = attr_merge( e, mod->sm_desc, mod->sm_values, mod->sm_nvalues );
+ rc = attr_merge_normalize( e, mod->sm_desc, mod->sm_values,
+ op->o_tmpmemctx );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
rc = LDAP_INSUFFICIENT_ACCESS;
} else {
+ assert( !SLAP_SHADOW( op->o_bd ) );
+ slap_mods_opattrs( op, op->orm_modlist, 0 );
+
rc = monitor_entry_modify( op, rs, e );
}
#include "lutil.h"
#include "back-monitor.h"
+static int
+monitor_subsys_rww_destroy(
+ BackendDB *be,
+ monitor_subsys_t *ms );
+
static int
monitor_subsys_rww_update(
Operation *op,
MONITOR_RWW_LAST
};
-struct monitor_rww_t {
+static struct monitor_rww_t {
struct berval rdn;
struct berval nrdn;
} monitor_rww[] = {
int
monitor_subsys_rww_init(
BackendDB *be,
- monitor_subsys_t *ms
-)
+ monitor_subsys_t *ms )
{
monitor_info_t *mi;
assert( be != NULL );
+ ms->mss_destroy = monitor_subsys_rww_destroy;
ms->mss_update = monitor_subsys_rww_update;
mi = ( monitor_info_t * )be->be_private;
return( 0 );
}
+static int
+monitor_subsys_rww_destroy(
+ BackendDB *be,
+ monitor_subsys_t *ms )
+{
+ int i;
+
+ for ( i = 0; i < MONITOR_RWW_LAST; i++ ) {
+ ber_memfree_x( monitor_rww[ i ].nrdn.bv_val, NULL );
+ }
+
+ return 0;
+}
+
static int
monitor_subsys_rww_update(
Operation *op,
*/
if ( op->o_sync ) {
char buf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
- struct berval csn = BER_BVNULL;
+ struct berval csn;
- slap_get_csn( op, buf, sizeof( buf ), &csn, 1 );
+ csn.bv_val = buf;
+ csn.bv_len = sizeof( buf );
+ slap_get_csn( op, &csn, 1 );
rs->sr_err = LDAP_SUCCESS;
send_ldap_result( op, rs );
oc = backsql_id2oc( bi, e_id.eid_oc_id );
rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id, mod );
+ slap_graduate_commit_csn( op );
if ( rs->sr_err != LDAP_SUCCESS ) {
e = &r;
goto done;
} else
#endif /* BACKSQL_SYNCPROV */
{
- slap_get_csn( op, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
+ entryCSN.bv_val = csnbuf;
+ entryCSN.bv_len = sizeof( csnbuf );
+ slap_get_csn( op, &entryCSN, 0 );
}
ber_dupbv( &a->a_vals[ 0 ], &entryCSN );
case LDAP_ADMINLIMIT_EXCEEDED:
case LDAP_NO_SUCH_OBJECT:
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
- case LDAP_CANNOT_CHAIN:
+ case LDAP_X_CANNOT_CHAIN:
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
goto end_of_loop;
static struct berval config_rdn = BER_BVC("cn=config");
static struct berval schema_rdn = BER_BVC("cn=schema");
-#define IFMT "{%d}"
+#define SLAP_X_ORDERED_FMT "{%d}"
#ifdef SLAPD_MODULES
typedef struct modpath_s {
CFG_TLS_CERT_KEY,
CFG_TLS_CA_PATH,
CFG_TLS_CA_FILE,
+ CFG_TLS_DH_FILE,
CFG_TLS_VERIFY,
CFG_TLS_CRLCHECK,
CFG_CONCUR,
CFG_SASLSECP,
CFG_SSTR_IF_MAX,
CFG_SSTR_IF_MIN,
+ CFG_TTHREADS,
CFG_LAST
};
#endif
"( OLcfgGlAt:75 NAME 'olcTLSVerifyClient' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "TLSDHParamFile", NULL, 0, 0, 0,
+#ifdef HAVE_TLS
+ CFG_TLS_DH_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
+#else
+ ARG_IGNORED, NULL,
+#endif
+ "( OLcfgGlAt:77 NAME 'olcTLSDHParamFile' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "tool-threads", "count", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_TTHREADS,
+ &config_generic, "( OLcfgGlAt:80 NAME 'olcToolThreads' "
+ "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "ucdata-path", "path", 2, 2, 0, ARG_IGNORED,
NULL, NULL, NULL, NULL },
{ "updatedn", "dn", 2, 2, 0, ARG_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
"olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
"olcTLSCACertificatePath $ olcTLSCertificateFile $ "
"olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
- "olcTLSRandFile $ olcTLSVerifyClient $ "
+ "olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ "
+ "olcToolThreads $ "
"olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
"olcDitContentRules ) )", Cft_Global },
{ "( OLcfgGlOc:2 "
case CFG_THREADS:
c->value_int = connection_pool_max;
break;
+ case CFG_TTHREADS:
+ c->value_int = slap_tool_thread_max;
+ break;
case CFG_SALT:
if ( passwd_salt )
c->value_string = ch_strdup( passwd_salt );
int i;
for ( i=0; c->be->be_limits[i]; i++ ) {
- bv.bv_len = sprintf( buf, IFMT, i );
- bv.bv_val = buf+bv.bv_len;
+ bv.bv_len = snprintf( buf, sizeof( buf ), SLAP_X_ORDERED_FMT, i );
+ if ( bv.bv_len >= sizeof( buf ) ) {
+ ber_bvarray_free_x( c->rvalue_vals, NULL );
+ c->rvalue_vals = NULL;
+ rc = 1;
+ break;
+ }
+ bv.bv_val = buf + bv.bv_len;
limits_unparse( c->be->be_limits[i], &bv );
bv.bv_len += bv.bv_val - buf;
bv.bv_val = buf;
char *src, *dst, ibuf[11];
struct berval bv, abv;
for (i=0, a=c->be->be_acl; a; i++,a=a->acl_next) {
- abv.bv_len = sprintf( ibuf, IFMT, i );
+ abv.bv_len = snprintf( ibuf, sizeof( ibuf ), SLAP_X_ORDERED_FMT, i );
+ if ( abv.bv_len >= sizeof( ibuf ) ) {
+ ber_bvarray_free_x( c->rvalue_vals, NULL );
+ c->rvalue_vals = NULL;
+ i = 0;
+ break;
+ }
acl_unparse( a, &bv );
abv.bv_val = ch_malloc( abv.bv_len + bv.bv_len + 1 );
AC_MEMCPY( abv.bv_val, ibuf, abv.bv_len );
for (i=0; !BER_BVISNULL(&mp->mp_loads[i]); i++) {
struct berval bv;
bv.bv_val = c->log;
- bv.bv_len = sprintf( bv.bv_val, IFMT "%s", i,
+ bv.bv_len = snprintf( bv.bv_val, sizeof( c->log ),
+ SLAP_X_ORDERED_FMT "%s", i,
mp->mp_loads[i].bv_val );
+ if ( bv.bv_len >= sizeof( c->log ) ) {
+ ber_bvarray_free_x( c->rvalue_vals, NULL );
+ c->rvalue_vals = NULL;
+ break;
+ }
value_add_one( &c->rvalue_vals, &bv );
}
}
idx.bv_val = ibuf;
for ( i=0; !BER_BVISNULL( &authz_rewrites[i] ); i++ ) {
- idx.bv_len = sprintf( idx.bv_val, IFMT, i );
+ idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), SLAP_X_ORDERED_FMT, i );
+ if ( idx.bv_len >= sizeof( ibuf ) ) {
+ ber_bvarray_free_x( c->rvalue_vals, NULL );
+ c->rvalue_vals = NULL;
+ break;
+ }
bv.bv_len = idx.bv_len + authz_rewrites[i].bv_len;
bv.bv_val = ch_malloc( bv.bv_len + 1 );
- strcpy( bv.bv_val, idx.bv_val );
- strcpy( bv.bv_val+idx.bv_len, authz_rewrites[i].bv_val );
+ AC_MEMCPY( bv.bv_val, idx.bv_val, idx.bv_len );
+ AC_MEMCPY( &bv.bv_val[ idx.bv_len ],
+ authz_rewrites[i].bv_val,
+ authz_rewrites[i].bv_len + 1 );
ber_bvarray_add( &c->rvalue_vals, &bv );
}
}
/* single-valued attrs, no-ops */
case CFG_CONCUR:
case CFG_THREADS:
+ case CFG_TTHREADS:
case CFG_RO:
case CFG_AZPOLICY:
case CFG_DEPTH:
case CFG_MODLOAD:
case CFG_AZREGEXP:
case CFG_REWRITE:
- sprintf(c->log, "change requires slapd restart");
+ snprintf(c->log, sizeof( c->log ), "change requires slapd restart");
break;
case CFG_SALT:
else
end = frontendDB->be_acl;
acl_destroy( c->be->be_acl, end );
+ c->be->be_acl = end;
+
} else {
AccessControl **prev, *a;
int i;
switch(c->type) {
case CFG_BACKEND:
if(!(c->bi = backend_info(c->argv[1]))) {
- sprintf( c->msg, "<%s> failed init", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> failed init", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
c->log, c->msg, c->argv[1] );
return(1);
} else {
c->be = backend_db_init(c->argv[1]);
if ( !c->be ) {
- sprintf( c->msg, "<%s> failed init", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> failed init", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
c->log, c->msg, c->argv[1] );
return(1);
connection_pool_max = c->value_int; /* save for reference */
break;
+ case CFG_TTHREADS:
+ ldap_pvt_thread_pool_maxthreads(&connection_pool, c->value_int);
+ slap_tool_thread_max = c->value_int; /* save for reference */
+ break;
+
case CFG_SALT:
if ( passwd_salt ) ch_free( passwd_salt );
passwd_salt = c->value_string;
case CFG_AZPOLICY:
ch_free(c->value_string);
if (slap_sasl_setpolicy( c->argv[1] )) {
- sprintf( c->msg, "<%s> unable to parse value", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[1] );
return(1);
break;
case CFG_ACL:
- parse_acl(c->be, c->fname, c->lineno, c->argc, c->argv, c->valx);
+ if ( parse_acl(c->be, c->fname, c->lineno, c->argc, c->argv, c->valx) ) {
+ return 1;
+ }
break;
case CFG_REPLOG:
case CFG_ROOTDSE:
if(read_root_dse_file(c->argv[1])) {
- sprintf( c->msg, "<%s> could not read file", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> could not read file", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
c->log, c->msg, c->argv[1] );
return(1);
case CFG_LASTMOD:
if(SLAP_NOLASTMODCMD(c->be)) {
- sprintf( c->msg, "<%s> not available for %s database",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> not available for %s database",
c->argv[0], c->be->bd_info->bi_type );
Debug(LDAP_DEBUG_ANY, "%s: %s\n",
c->log, c->msg, 0 );
case CFG_SSTR_IF_MAX:
if (c->value_int < index_substr_if_minlen) {
- sprintf( c->msg, "<%s> invalid value", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%d)\n",
c->log, c->msg, c->value_int );
return(1);
case CFG_SSTR_IF_MIN:
if (c->value_int > index_substr_if_maxlen) {
- sprintf( c->msg, "<%s> invalid value", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%d)\n",
c->log, c->msg, c->value_int );
return(1);
modcur = c->private;
/* This should never fail */
if ( module_path( modcur->mp_path.bv_val )) {
- sprintf( c->msg, "<%s> module path no longer valid",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> module path no longer valid",
c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
c->log, c->msg, modcur->mp_path.bv_val );
}
for(i = 1; i < c->argc; i++) {
if(!lutil_passwd_scheme(c->argv[i])) {
- sprintf( c->msg, "<%s> scheme not available", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> scheme not available", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
c->log, c->msg, c->argv[i]);
} else {
ldap_charray_add(&default_passwd_hash, c->argv[i]);
}
if(!default_passwd_hash) {
- sprintf( c->msg, "<%s> no valid hashes found", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> no valid hashes found", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n",
c->log, c->msg, 0 );
return(1);
if(!strncasecmp(c->argv[i], "size", 4)) {
rc = limits_parse_one(c->argv[i], lim);
if ( rc ) {
- sprintf( c->msg, "<%s> unable to parse value", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[i]);
return(1);
} else {
lim->lms_s_soft = strtol(c->argv[i], &next, 0);
if(next == c->argv[i]) {
- sprintf( c->msg, "<%s> unable to parse limit", c->argv[0]);
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[i]);
return(1);
if(!strncasecmp(c->argv[i], "time", 4)) {
rc = limits_parse_one(c->argv[i], lim);
if ( rc ) {
- sprintf( c->msg, "<%s> unable to parse value", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[i]);
return(1);
} else {
lim->lms_t_soft = strtol(c->argv[i], &next, 0);
if(next == c->argv[i]) {
- sprintf( c->msg, "<%s> unable to parse limit", c->argv[0]);
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[i]);
return(1);
#ifdef SLAPD_MONITOR_DN
if(!strcasecmp(c->argv[1], SLAPD_MONITOR_DN)) {
- sprintf( c->msg, "<%s> DN is reserved for monitoring slapd",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> DN is reserved for monitoring slapd",
c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
c->log, c->msg, SLAPD_MONITOR_DN);
type = oi->oi_orig->bi_type;
}
- sprintf( c->msg, "<%s> namingContext \"%s\" already served by "
+ snprintf( c->msg, sizeof( c->msg ), "<%s> namingContext \"%s\" already served by "
"a preceding %s database serving namingContext",
c->argv[0], pdn.bv_val, type );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
tbe = select_backend(&c->be->be_rootndn, 0, 0);
if(tbe != c->be) {
- sprintf( c->msg, "<%s> can only be set when rootdn is under suffix",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> can only be set when rootdn is under suffix",
c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n",
c->log, c->msg, 0);
}
i = verbs_to_mask( c->argc, c->argv, restrictable_ops, &restrictops );
if ( i ) {
- sprintf( c->msg, "<%s> unknown operation", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unknown operation", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
c->log, c->msg, c->argv[i]);
return(1);
}
i = verbs_to_mask(c->argc, c->argv, allowable_ops, &allows);
if ( i ) {
- sprintf( c->msg, "<%s> unknown feature", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
c->log, c->msg, c->argv[i]);
return(1);
}
i = verbs_to_mask(c->argc, c->argv, disallowable_ops, &disallows);
if ( i ) {
- sprintf( c->msg, "<%s> unknown feature", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
c->log, c->msg, c->argv[i]);
return(1);
}
i = verbs_to_mask(c->argc, c->argv, requires_ops, &requires);
if ( i ) {
- sprintf( c->msg, "<%s> unknown feature", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
c->log, c->msg, c->argv[i]);
return(1);
{ BER_BVC("Cache"), LDAP_DEBUG_CACHE },
{ BER_BVC("Index"), LDAP_DEBUG_INDEX },
{ BER_BVC("Sync"), LDAP_DEBUG_SYNC },
- { BER_BVNULL, 0 }
+ { BER_BVC("None"), LDAP_DEBUG_NONE },
+ { BER_BVNULL, 0 }
};
return slap_verbmasks_init( &loglevel_ops, lo );
return rc;
}
+int
+slap_loglevel_get( struct berval *s, int *l )
+{
+ int rc;
+ unsigned long i;
+ slap_mask_t m;
+
+ if ( loglevel_ops == NULL ) {
+ loglevel_init();
+ }
+
+ for ( m = 0, i = 1; !BER_BVISNULL( &loglevel_ops[ i ].word ); i++ ) {
+ m |= loglevel_ops[ i ].mask;
+ }
+
+ m = ~m;
+
+ for ( i = 1; i <= ( 1 << ( sizeof( int ) * 8 - 1 ) ) && !( m & i ); i <<= 1 )
+ ;
+
+ if ( !( m & i ) ) {
+ return -1;
+ }
+
+ rc = slap_verbmasks_append( &loglevel_ops, i, s, loglevel_ignore );
+
+ if ( rc != 0 ) {
+ Debug( LDAP_DEBUG_ANY, "slap_loglevel_register(%lu, \"%s\") failed\n",
+ i, s->bv_val, 0 );
+
+ } else {
+ *l = i;
+ }
+
+ return rc;
+}
+
int
str2loglevel( const char *s, int *l )
{
i = verb_to_mask( s, loglevel_ops );
- if ( BER_BVISNULL( &loglevel_ops[ i ].word) ) {
+ if ( BER_BVISNULL( &loglevel_ops[ i ].word ) ) {
return -1;
}
return 0;
}
+const char *
+loglevel2str( int l )
+{
+ struct berval bv = BER_BVNULL;
+
+ loglevel2bv( l, &bv );
+
+ return bv.bv_val;
+}
+
+int
+loglevel2bv( int l, struct berval *bv )
+{
+ if ( loglevel_ops == NULL ) {
+ loglevel_init();
+ }
+
+ BER_BVZERO( bv );
+
+ return enum_to_verb( loglevel_ops, l, bv ) == -1;
+}
+
+int
+loglevel2bvarray( int l, BerVarray *bva )
+{
+ if ( loglevel_ops == NULL ) {
+ loglevel_init();
+ }
+
+ return mask_to_verbs( loglevel_ops, l, bva );
+}
+
static int config_syslog;
static int
/* Get default or commandline slapd setting */
if ( ldap_syslog && !config_syslog )
config_syslog = ldap_syslog;
- return mask_to_verbs( loglevel_ops, config_syslog, &c->rvalue_vals );
+ return loglevel2bvarray( config_syslog, &c->rvalue_vals );
+
} else if ( c->op == LDAP_MOD_DELETE ) {
if ( !c->line ) {
config_syslog = 0;
if ( isdigit( c->argv[i][0] ) || c->argv[i][0] == '-' ) {
level = strtol( c->argv[i], &next, 10 );
if ( next == NULL || next[0] != '\0' ) {
- sprintf( c->msg, "<%s> unable to parse level", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse level", c->argv[0] );
Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[i]);
return( 1 );
}
} else {
if ( str2loglevel( c->argv[i], &level ) ) {
- sprintf( c->msg, "<%s> unknown level", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unknown level", c->argv[0] );
Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[i]);
return( 1 );
return 0;
}
if(validate_global_referral(c->argv[1])) {
- sprintf( c->msg, "<%s> invalid URL", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> invalid URL", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
c->log, c->msg, c->argv[1]);
return(1);
tgt = (slap_ssf_t *)((char *)set + sec_keys[i].off);
if ( *tgt ) {
rc = 0;
- bv.bv_len = sprintf( numbuf, "%u", *tgt );
+ bv.bv_len = snprintf( numbuf, sizeof( numbuf ), "%u", *tgt );
+ if ( bv.bv_len >= sizeof( numbuf ) ) {
+ ber_bvarray_free_x( c->rvalue_vals, NULL );
+ c->rvalue_vals = NULL;
+ rc = 1;
+ break;
+ }
bv.bv_len += sec_keys[i].key.bv_len;
bv.bv_val = ch_malloc( bv.bv_len + 1);
next = lutil_strcopy( bv.bv_val, sec_keys[i].key.bv_val );
}
}
if ( !tgt ) {
- sprintf( c->msg, "<%s> unknown factor", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unknown factor", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
c->log, c->msg, c->argv[i]);
return(1);
*tgt = strtol(src, &next, 10);
if(next == NULL || next[0] != '\0' ) {
- sprintf( c->msg, "<%s> unable to parse factor", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse factor", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[i]);
return(1);
struct berval bc = BER_BVNULL;
char numbuf[32];
- len = sprintf(numbuf, IFMT, i );
+ BER_BVZERO( bv );
+
+ len = snprintf(numbuf, sizeof( numbuf ), SLAP_X_ORDERED_FMT, i );
+ if ( len >= sizeof( numbuf ) ) {
+ /* FIXME: how can indicate error? */
+ return;
+ }
len += strlen( ri->ri_uri ) + STRLENOF("uri=");
if ( ri->ri_nsuffix ) {
static int
config_replica(ConfigArgs *c) {
- int i, nr = -1, len;
+ int i, nr = -1;
char *replicahost, *replicauri;
LDAPURLDesc *ludp;
for(i = 1; i < c->argc; i++) {
if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) {
+ ber_len_t len;
+
replicahost = c->argv[i] + STRLENOF("host=");
- len = strlen( replicahost );
- replicauri = ch_malloc( len + STRLENOF("ldap://") + 1 );
- sprintf( replicauri, "ldap://%s", replicahost );
+ len = strlen( replicahost ) + STRLENOF("ldap://");
+ replicauri = ch_malloc( len + 1 );
+ snprintf( replicauri, len + 1, "ldap://%s", replicahost );
replicahost = replicauri + STRLENOF( "ldap://");
nr = add_replica_info(c->be, replicauri, replicahost);
break;
} else if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
if(ldap_url_parse(c->argv[i] + STRLENOF("uri="), &ludp) != LDAP_SUCCESS) {
- sprintf( c->msg, "<%s> invalid uri", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
return(1);
}
if(!ludp->lud_host) {
ldap_free_urldesc(ludp);
- sprintf( c->msg, "<%s> invalid uri - missing hostname",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri - missing hostname",
c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
return(1);
}
}
if(i == c->argc) {
- sprintf( c->msg, "<%s> missing host or uri", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> missing host or uri", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
return(1);
} else if(nr == -1) {
- sprintf( c->msg, "<%s> unable to add replica", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unable to add replica", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
return(1);
} else {
continue;
}
if(add_replica_attrs(c->be, nr, arg + 1, exclude)) {
- sprintf( c->msg, "<%s> unknown attribute", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> unknown attribute", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, arg + 1);
return(1);
return 0;
}
if(SLAP_SHADOW(c->be)) {
- sprintf( c->msg, "<%s> database already shadowed", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> database already shadowed", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n",
c->log, c->msg, 0);
return(1);
return 0;
}
if(!SLAP_SHADOW(c->be)) {
- sprintf( c->msg, "<%s> must appear after syncrepl or updatedn",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> must appear after syncrepl or updatedn",
c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n",
c->log, c->msg, 0);
}
if(validate_global_referral(c->argv[1])) {
- sprintf( c->msg, "<%s> invalid URL", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> invalid URL", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
c->log, c->msg, c->argv[1]);
return(1);
case CFG_TLS_CERT_KEY: flag = LDAP_OPT_X_TLS_KEYFILE; break;
case CFG_TLS_CA_PATH: flag = LDAP_OPT_X_TLS_CACERTDIR; break;
case CFG_TLS_CA_FILE: flag = LDAP_OPT_X_TLS_CACERTFILE; break;
+ case CFG_TLS_DH_FILE: flag = LDAP_OPT_X_TLS_DHFILE; break;
default: Debug(LDAP_DEBUG_ANY, "%s: "
"unknown tls_option <0x%x>\n",
c->log, c->type, 0);
sort = 1;
rc = ordered_value_sort( a, 1 );
if ( rc ) {
- sprintf(ca->msg, "ordered_value_sort failed on attr %s\n",
+ snprintf(ca->msg, sizeof( ca->msg ), "ordered_value_sort failed on attr %s\n",
ad->ad_cname.bv_val );
return rc;
}
if (!a ) return LDAP_NAMING_VIOLATION;
ival.bv_val = ibuf;
- ival.bv_len = sprintf( ibuf, IFMT, nsibs );
+ ival.bv_len = snprintf( ibuf, sizeof( ibuf ), SLAP_X_ORDERED_FMT, nsibs );
+ if ( ival.bv_len >= sizeof( ibuf ) ) {
+ return LDAP_NAMING_VIOLATION;
+ }
newrdn.bv_len = rdn.bv_len + ival.bv_len;
newrdn.bv_val = ch_malloc( newrdn.bv_len+1 );
}
}
if ( rc ) {
- sprintf( ca->msg, "<%s> failed startup", ca->argv[0] );
+ snprintf( ca->msg, sizeof( ca->msg ), "<%s> failed startup", ca->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
ca->log, ca->msg, ca->argv[1] );
rc = LDAP_OTHER;
ptr = strchr( bv.bv_val, '.' );
if ( ptr )
bv.bv_len = ptr - bv.bv_val;
- c->value_dn.bv_len = sprintf(c->value_dn.bv_val, "cn=" IFMT, c->depth);
+ c->value_dn.bv_len = snprintf(c->value_dn.bv_val, sizeof( c->log ), "cn=" SLAP_X_ORDERED_FMT, c->depth);
+ if ( c->value_dn.bv_len >= sizeof( c->log ) ) {
+ /* FIXME: how can indicate error? */
+ return;
+ }
strncpy( c->value_dn.bv_val + c->value_dn.bv_len, bv.bv_val,
bv.bv_len );
c->value_dn.bv_len += bv.bv_len;
for (i=0; cf; cf=cf->c_sibs, i++) {
c->value_dn.bv_val = c->log;
- c->value_dn.bv_len = sprintf(c->value_dn.bv_val, "cn=include" IFMT, i);
+ c->value_dn.bv_len = snprintf(c->value_dn.bv_val, sizeof( c->log ), "cn=include" SLAP_X_ORDERED_FMT, i);
+ if ( c->value_dn.bv_len >= sizeof( c->log ) ) {
+ /* FIXME: how can indicate error? */
+ return;
+ }
c->private = cf;
e = config_build_entry( op, rs, ceparent, c, &c->value_dn,
&CFOC_INCLUDE, NULL );
if ( BER_BVISNULL( &mp->mp_path ) && !mp->mp_loads )
continue;
c->value_dn.bv_val = c->log;
- c->value_dn.bv_len = sprintf(c->value_dn.bv_val, "cn=module" IFMT, i);
+ c->value_dn.bv_len = snprintf(c->value_dn.bv_val, sizeof( c->log ), "cn=module" SLAP_X_ORDERED_FMT, i);
+ if ( c->value_dn.bv_len >= sizeof( c->log ) ) {
+ /* FIXME: how can indicate error? */
+ return;
+ }
c->private = mp;
config_build_entry( op, rs, ceparent, c, &c->value_dn,
&CFOC_MODULE, NULL );
if (!bi->bi_private) continue;
rdn.bv_val = c.log;
- rdn.bv_len = sprintf(rdn.bv_val, "%s=%s", cfAd_backend->ad_cname.bv_val, bi->bi_type);
+ rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ),
+ "%s=%s", cfAd_backend->ad_cname.bv_val, bi->bi_type);
+ if ( rdn.bv_len >= sizeof( c.log ) ) {
+ /* FIXME: holler ... */ ;
+ }
c.bi = bi;
e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_BACKEND,
bi->bi_cf_ocs );
bi = be->bd_info;
}
rdn.bv_val = c.log;
- rdn.bv_len = sprintf(rdn.bv_val, "%s=" IFMT "%s", cfAd_database->ad_cname.bv_val,
+ rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ),
+ "%s=" SLAP_X_ORDERED_FMT "%s", cfAd_database->ad_cname.bv_val,
i, bi->bi_type);
+ if ( rdn.bv_len >= sizeof( c.log ) ) {
+ /* FIXME: holler ... */ ;
+ }
c.be = be;
c.bi = bi;
e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_DATABASE,
for (j=0,on=oi->oi_list; on; j++,on=on->on_next) {
rdn.bv_val = c.log;
- rdn.bv_len = sprintf(rdn.bv_val, "%s=" IFMT "%s",
+ rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ),
+ "%s=" SLAP_X_ORDERED_FMT "%s",
cfAd_overlay->ad_cname.bv_val, j, on->on_bi.bi_type );
+ if ( rdn.bv_len >= sizeof( c.log ) ) {
+ /* FIXME: holler ... */ ;
+ }
c.be = be;
c.bi = &on->on_bi;
oe = config_build_entry( op, &rs, ce, &c, &rdn,
c->argv[1] = "";
}
if(Conf->min_args && (c->argc < Conf->min_args)) {
- sprintf( c->msg, "<%s> missing <%s> argument",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> missing <%s> argument",
c->argv[0], Conf->what );
Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n", c->log, c->msg, 0 );
return(ARG_BAD_CONF);
if(Conf->max_args && (c->argc > Conf->max_args)) {
char *ignored = " ignored";
- sprintf( c->msg, "<%s> extra cruft after <%s>",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> extra cruft after <%s>",
c->argv[0], Conf->what );
#ifdef LDAP_DEVEL
#endif /* LDAP_DEVEL */
}
if((arg_type & ARG_DB) && !c->be) {
- sprintf( c->msg, "<%s> only allowed within database declaration",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> only allowed within database declaration",
c->argv[0] );
Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n",
c->log, c->msg, 0);
return(ARG_BAD_CONF);
}
if((arg_type & ARG_PRE_BI) && c->bi) {
- sprintf( c->msg, "<%s> must occur before any backend %sdeclaration",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> must occur before any backend %sdeclaration",
c->argv[0], (arg_type & ARG_PRE_DB) ? "or database " : "" );
Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n",
c->log, c->msg, 0 );
return(ARG_BAD_CONF);
}
if((arg_type & ARG_PRE_DB) && c->be && c->be != frontendDB) {
- sprintf( c->msg, "<%s> must occur before any database declaration",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> must occur before any database declaration",
c->argv[0] );
Debug(LDAP_DEBUG_CONFIG, "%s: keyword %s\n",
c->log, c->msg, 0);
return(ARG_BAD_CONF);
}
if((arg_type & ARG_PAREN) && *c->argv[1] != '(' /*')'*/) {
- sprintf( c->msg, "<%s> old format not supported", c->argv[0] );
+ snprintf( c->msg, sizeof( c->msg ), "<%s> old format not supported", c->argv[0] );
Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
c->log, c->msg, 0);
return(ARG_BAD_CONF);
}
if((arg_type & ARGS_POINTER) && !Conf->arg_item && !(arg_type & ARG_OFFSET)) {
- sprintf( c->msg, "<%s> invalid config_table, arg_item is NULL",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> invalid config_table, arg_item is NULL",
c->argv[0] );
Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
c->log, c->msg, 0);
!strcasecmp(c->argv[1], "false")) {
iarg = 0;
} else {
- sprintf( c->msg, "<%s> invalid value, ignored",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value, ignored",
c->argv[0] );
Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
c->log, c->msg, 0 );
j = (arg_type & ARG_NONZERO) ? 1 : 0;
if(iarg < j && larg < j && barg < j ) {
larg = larg ? larg : (barg ? barg : iarg);
- sprintf( c->msg, "<%s> invalid value, ignored",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value, ignored",
c->argv[0] );
Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
c->log, c->msg, 0 );
ber_str2bv( c->argv[1], 0, 0, &bv );
rc = dnPrettyNormal( NULL, &bv, &c->value_dn, &c->value_ndn, NULL );
if ( rc != LDAP_SUCCESS ) {
- sprintf( c->msg, "<%s> invalid DN %d (%s)",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> invalid DN %d (%s)",
c->argv[0], rc, ldap_err2string( rc ));
Debug(LDAP_DEBUG_CONFIG, "%s: %s\n" , c->log, c->msg, 0);
return(ARG_BAD_CONF);
#endif
if(rc) {
if ( !c->msg[0] ) {
- sprintf( c->msg, "<%s> handler exited with %d",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> handler exited with %d",
c->argv[0], rc );
Debug(LDAP_DEBUG_CONFIG, "%s: %s!\n",
c->log, c->msg, 0 );
else if (c->bi)
ptr = c->bi->bi_private;
else {
- sprintf( c->msg, "<%s> offset is missing base pointer",
+ snprintf( c->msg, sizeof( c->msg ), "<%s> offset is missing base pointer",
c->argv[0] );
Debug(LDAP_DEBUG_CONFIG, "%s: %s!\n",
c->log, c->msg, 0);
if ( cf->arg_type & ARGS_POINTER) {
bv.bv_val = c->log;
switch(cf->arg_type & ARGS_POINTER) {
- case ARG_INT: bv.bv_len = sprintf(bv.bv_val, "%d", c->value_int); break;
- case ARG_LONG: bv.bv_len = sprintf(bv.bv_val, "%ld", c->value_long); break;
- case ARG_BER_LEN_T: bv.bv_len = sprintf(bv.bv_val, "%ld", c->value_ber_t); break;
- case ARG_ON_OFF: bv.bv_len = sprintf(bv.bv_val, "%s",
+ case ARG_INT: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%d", c->value_int); break;
+ case ARG_LONG: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%ld", c->value_long); break;
+ case ARG_BER_LEN_T: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%ld", c->value_ber_t); break;
+ case ARG_ON_OFF: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%s",
c->value_int ? "TRUE" : "FALSE"); break;
case ARG_STRING:
if ( c->value_string && c->value_string[0]) {
}
break;
}
+ if (bv.bv_val == c->log && bv.bv_len >= sizeof( c->log ) ) {
+ return 1;
+ }
if (( cf->arg_type & ARGS_POINTER ) == ARG_STRING )
ber_bvarray_add(&c->rvalue_vals, &bv);
else
*/
int
mask_to_verbs(slap_verbmasks *v, slap_mask_t m, BerVarray *bva) {
- int i;
-
- if (!m) return 1;
- for (i=0; !BER_BVISNULL(&v[i].word); i++) {
- if (!v[i].mask) continue;
- if (( m & v[i].mask ) == v[i].mask ) {
- value_add_one( bva, &v[i].word );
- m ^= v[i].mask;
- if ( !m ) break;
+ int i, rc = 1;
+
+ if (m) {
+ for (i=0; !BER_BVISNULL(&v[i].word); i++) {
+ if (!v[i].mask) continue;
+ if (( m & v[i].mask ) == v[i].mask ) {
+ value_add_one( bva, &v[i].word );
+ rc = 0;
+ m ^= v[i].mask;
+ if ( !m ) break;
+ }
}
}
- return 0;
+ return rc;
}
int
c.argc = argc;
c.argv = argv;
c.valx = -1;
- sprintf( c.log, "%s: line %d", fname, lineno );
+ snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno );
rc = SLAP_CONF_UNKNOWN;
ct = config_find_keyword( be->be_cf_ocs->co_table, &c );
#include "slapi/slapi.h"
#endif
+#ifdef SLAP_MULTI_CONN_ARRAY
+/* for Multiple Connection Arrary (MCA) Support */
+static ldap_pvt_thread_mutex_t* connections_mutex;
+static Connection **connections = NULL;
+
+/* set to the number of processors (round up to a power of 2) */
+# define NUM_CONNECTION_ARRAY 4
+
+/* partition the array in a modulo manner */
+# define MCA_conn_array_id(fd) ((int)(fd)%NUM_CONNECTION_ARRAY)
+# define MCA_conn_array_element_id(fd) ((int)(fd)/NUM_CONNECTION_ARRAY)
+# define MCA_ARRAY_SIZE ((int)(MCA_conn_array_element_id(dtblsize) + (MCA_conn_array_id(dtblsize) ? 1 : 0)))
+# define MCA_conn_check(fd) (dtblsize > 0 && (fd) >= 0 && (fd) < (MCA_ARRAY_SIZE*NUM_CONNECTION_ARRAY))
+# define MCA_GET_CONNECTION(fd) (&(connections[MCA_conn_array_id(fd)]) \
+ [MCA_conn_array_element_id(fd)])
+# define MCA_GET_CONN_MUTEX(fd) (&connections_mutex[MCA_conn_array_id(fd)])
+
+#else
/* protected by connections_mutex */
static ldap_pvt_thread_mutex_t connections_mutex;
static Connection *connections = NULL;
+# define MCA_conn_check(fd) (dtblsize > 0 && (fd) < dtblsize)
+# define MCA_GET_CONNECTION(fd) (&connections[s])
+# define MCA_GET_CONN_MUTEX(fd) (&connections_mutex)
+#endif
+
static ldap_pvt_thread_mutex_t conn_nextid_mutex;
static unsigned long conn_nextid = 0;
static Connection* connection_get( ber_socket_t s );
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+
+typedef struct conn_readinfo {
+ Operation *op;
+ ldap_pvt_thread_start_t *func;
+ void *arg;
+ int nullop;
+} conn_readinfo;
+
+static int connection_input( Connection *c, conn_readinfo *cri );
+#else
static int connection_input( Connection *c );
+#endif
static void connection_close( Connection *c );
static int connection_op_activate( Operation *op );
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+static void connection_op_queue( Operation *op );
+#endif
static int connection_resched( Connection *conn );
static void connection_abandon( Connection *conn );
static void connection_destroy( Connection *c );
* Initialize connection management infrastructure.
*/
int connections_init(void)
+#ifdef SLAP_MULTI_CONN_ARRAY
+{
+ int i, j;
+ Connection* conn;
+
+ assert( connections == NULL );
+
+ if( connections != NULL) {
+ Debug( LDAP_DEBUG_ANY, "connections_init: already initialized.\n",
+ 0, 0, 0 );
+ return -1;
+ }
+
+ connections_mutex = (ldap_pvt_thread_mutex_t*) ch_calloc(
+ NUM_CONNECTION_ARRAY, sizeof(ldap_pvt_thread_mutex_t) );
+ if( connections_mutex == NULL ) {
+ Debug( LDAP_DEBUG_ANY, "connections_init: "
+ "allocation of connection mutex[%d] failed\n", i, 0, 0 );
+ return -1;
+ }
+
+ connections = (Connection**) ch_calloc(
+ NUM_CONNECTION_ARRAY, sizeof(Connection*));
+ if( connections == NULL ) {
+ Debug( LDAP_DEBUG_ANY, "connections_init: "
+ "allocation of connection[%d] failed\n", 0, 0, 0 );
+ return -1;
+ }
+
+ for ( i = 0; i < NUM_CONNECTION_ARRAY; i++ ) {
+ ldap_pvt_thread_mutex_init( connections_mutex+i );
+ connections[i] = (Connection*) ch_calloc(
+ MCA_ARRAY_SIZE, sizeof(Connection) );
+ if( connections[i] == NULL ) {
+ Debug( LDAP_DEBUG_ANY, "connections_init: "
+ "allocation (%d*%ld) of connection array[%d] failed\n",
+ dtblsize, (long) sizeof(Connection), i );
+ return -1;
+ }
+ }
+
+ /* should check return of every call */
+ ldap_pvt_thread_mutex_init( &conn_nextid_mutex );
+
+ assert( connections[0]->c_struct_state == SLAP_C_UNINITIALIZED );
+ assert( connections[NUM_CONNECTION_ARRAY-1]->c_struct_state ==
+ SLAP_C_UNINITIALIZED );
+
+ for ( i = 0; i < NUM_CONNECTION_ARRAY; i++ ) {
+ conn = connections[i];
+ for ( j = 0; j < MCA_ARRAY_SIZE; j++ ) {
+ conn[j].c_conn_idx = j;
+ }
+ }
+
+ /*
+ * per entry initialization of the Connection array initialization
+ * will be done by connection_init()
+ */
+
+ return 0;
+}
+#else
{
int i;
connections = (Connection *) ch_calloc( dtblsize, sizeof(Connection) );
if( connections == NULL ) {
- Debug( LDAP_DEBUG_ANY,
- "connections_init: allocation (%d*%ld) of connection array failed\n",
+ Debug( LDAP_DEBUG_ANY, "connections_init: "
+ "allocation (%d*%ld) of connection array failed\n",
dtblsize, (long) sizeof(Connection), 0 );
return -1;
}
return 0;
}
+#endif
/*
* Destroy connection management infrastructure.
*/
+
int connections_destroy(void)
+#ifdef SLAP_MULTI_CONN_ARRAY
+{
+ int i;
+ ber_socket_t j;
+
+ if( connections == NULL) {
+ Debug( LDAP_DEBUG_ANY, "connections_destroy: nothing to destroy.\n",
+ 0, 0, 0 );
+ return -1;
+ }
+
+ for ( i = 0; i < NUM_CONNECTION_ARRAY; i++ ) {
+ Connection* conn = connections[i];
+ for ( j = 0; j < MCA_ARRAY_SIZE; j++ ) {
+ if( conn[j].c_struct_state != SLAP_C_UNINITIALIZED ) {
+ ber_sockbuf_free( conn[j].c_sb );
+ ldap_pvt_thread_mutex_destroy( &conn[j].c_mutex );
+ ldap_pvt_thread_mutex_destroy( &conn[j].c_write_mutex );
+ ldap_pvt_thread_cond_destroy( &conn[j].c_write_cv );
+#ifdef LDAP_SLAPI
+ /* FIX ME!! */
+ if ( slapi_plugins_used ) {
+ slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION,
+ &connections[i] );
+ }
+#endif
+ }
+ }
+ }
+
+ for ( i = 0; i < NUM_CONNECTION_ARRAY; i++ ) {
+ free( connections[i] );
+ connections[i] = NULL;
+ ldap_pvt_thread_mutex_destroy( &connections_mutex[i] );
+ }
+
+ free( connections );
+ free( connections_mutex );
+
+ ldap_pvt_thread_mutex_destroy( &conn_nextid_mutex );
+
+ return 0;
+
+}
+#else
{
ber_socket_t i;
ldap_pvt_thread_cond_destroy( &connections[i].c_write_cv );
#ifdef LDAP_SLAPI
if ( slapi_plugins_used ) {
- slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, &connections[i] );
+ slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION,
+ &connections[i] );
}
#endif
}
ldap_pvt_thread_mutex_destroy( &conn_nextid_mutex );
return 0;
}
+#endif
/*
* shutdown all connections
*/
int connections_shutdown(void)
+#ifdef SLAP_MULTI_CONN_ARRAY
+{
+ int i;
+ ber_socket_t j;
+
+ for ( i = 0; i < NUM_CONNECTION_ARRAY; i++ ) {
+ Connection* conn = connections[i];
+ ldap_pvt_thread_mutex_lock( &connections_mutex[i] );
+ for ( j = 0; j < MCA_ARRAY_SIZE; j++ ) {
+ if( conn[j].c_struct_state != SLAP_C_USED ) {
+ continue;
+ }
+ /* give persistent clients a chance to cleanup */
+ if( conn[j].c_conn_state == SLAP_C_CLIENT ) {
+ ldap_pvt_thread_pool_submit( &connection_pool,
+ conn[j].c_clientfunc, conn[j].c_clientarg );
+ continue;
+ }
+
+ ldap_pvt_thread_mutex_lock( &conn[j].c_mutex );
+ /* connections_mutex and c_mutex are locked */
+ connection_closing( &conn[j], "connection shutdown" );
+ connection_close( &conn[j] );
+ ldap_pvt_thread_mutex_unlock( &conn[j].c_mutex );
+ }
+
+ ldap_pvt_thread_mutex_unlock( &connections_mutex[i] );
+ }
+
+ return 0;
+
+}
+#else
{
ber_socket_t i;
return 0;
}
+#endif
/*
* Timeout idle connections.
{
/* Don't timeout a slow-running request or a persistent
* outbound connection */
- if( c->c_n_ops_executing ||
- c->c_conn_state == SLAP_C_CLIENT ) continue;
+ if( c->c_n_ops_executing || c->c_conn_state == SLAP_C_CLIENT ) {
+ continue;
+ }
if( difftime( c->c_activitytime+global_idletimeout, now) < 0 ) {
/* close it */
assert( connections != NULL );
- if(s == AC_SOCKET_INVALID) {
- return NULL;
- }
+ if(s == AC_SOCKET_INVALID) return NULL;
#ifndef HAVE_WINSOCK
- c = &connections[s];
+ assert( MCA_conn_check( s ) );
+ c = MCA_GET_CONNECTION(s);
assert( c->c_struct_state != SLAP_C_UNINITIALIZED );
assert( s < dtblsize );
#endif
- ldap_pvt_thread_mutex_lock( &connections_mutex );
+ ldap_pvt_thread_mutex_lock( MCA_GET_CONN_MUTEX(s) );
#ifndef HAVE_WINSOCK
- c = &connections[s];
-
+ assert( MCA_conn_check( s ) );
+ c = MCA_GET_CONNECTION(s);
#else
{
ber_socket_t i;
break;
}
- if( connections[i].c_conn_state == SLAP_C_CLIENT ) {
- continue;
- }
+ if( connections[i].c_conn_state == SLAP_C_CLIENT ) continue;
assert( connections[i].c_struct_state == SLAP_C_USED );
assert( connections[i].c_conn_state != SLAP_C_INVALID );
c->c_close_reason = "?"; /* should never be needed */
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_FD, &s );
ldap_pvt_thread_mutex_unlock( &c->c_mutex );
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
return 0;
}
slap_sasl_open( c, 0 );
slap_sasl_external( c, ssf, authid );
+ slapd_add_internal( s, 1 );
ldap_pvt_thread_mutex_unlock( &c->c_mutex );
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
backend_connection_init(c);
ch_free(c->c_dn.bv_val);
}
BER_BVZERO( &c->c_dn );
+
if ( !BER_BVISNULL( &c->c_ndn ) ) {
ch_free(c->c_ndn.bv_val);
}
BER_BVZERO( &c->c_ndn );
+
if ( !BER_BVISNULL( &c->c_sasl_authz_dn ) ) {
ber_memfree_x( c->c_sasl_authz_dn.bv_val, NULL );
}
}
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
+ slapd_sd_lock();
+ ber_sockbuf_free( c->c_sb );
if ( sd != AC_SOCKET_INVALID ) {
- slapd_remove( sd, 1, 0 );
+ slapd_remove( sd, 1, 0, 1 );
Statslog( LDAP_DEBUG_STATS, (close_reason
? "conn=%lu fd=%ld closed (%s)\n"
: "conn=%lu fd=%ld closed\n"),
connid, (long) sd, close_reason, 0, 0 );
+ } else {
+ slapd_sd_unlock();
}
- ber_sockbuf_free( c->c_sb );
-
c->c_sb = ber_sockbuf_alloc( );
{
unsigned long id;
assert( connections != NULL );
- ldap_pvt_thread_mutex_lock( &connections_mutex );
+ ldap_pvt_thread_mutex_lock( &conn_nextid_mutex );
id = conn_nextid;
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( &conn_nextid_mutex );
return id;
}
Connection* connection_first( ber_socket_t *index )
{
+#ifdef SLAP_MULTI_CONN_ARRAY
+ int conn_array_id;
+#endif
+
assert( connections != NULL );
assert( index != NULL );
+#ifdef SLAP_MULTI_CONN_ARRAY
+ for ( conn_array_id = 0;
+ conn_array_id < NUM_CONNECTION_ARRAY;
+ conn_array_id++ )
+ {
+ ldap_pvt_thread_mutex_lock( &connections_mutex[ conn_array_id ] );
+ }
+#else
ldap_pvt_thread_mutex_lock( &connections_mutex );
+#endif
*index = 0;
}
Connection* connection_next( Connection *c, ber_socket_t *index )
+#ifdef SLAP_MULTI_CONN_ARRAY
{
+ Connection* conn;
+
assert( connections != NULL );
assert( index != NULL );
- assert( *index <= dtblsize );
+ assert( *index >= 0 && *index < MCA_ARRAY_SIZE );
- if( c != NULL ) {
- ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+ if( c != NULL ) ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+
+ c = NULL;
+
+ for(; *index < dtblsize; (*index)++) {
+ assert( MCA_conn_check( *index ) );
+ conn = MCA_GET_CONNECTION(*index);
+ if( conn->c_struct_state == SLAP_C_UNINITIALIZED ) {
+ assert( conn->c_conn_state == SLAP_C_INVALID );
+#ifndef HAVE_WINSOCK
+ continue;
+#else
+ break;
+#endif
+ }
+
+ if( conn->c_struct_state == SLAP_C_USED ) {
+ assert( conn->c_conn_state != SLAP_C_INVALID );
+ c = conn;
+ (*index)++;
+ break;
+ }
+
+ assert( conn->c_struct_state == SLAP_C_UNUSED );
+ assert( conn->c_conn_state == SLAP_C_INVALID );
}
+ if( c != NULL ) ldap_pvt_thread_mutex_lock( &c->c_mutex );
+
+ return c;
+
+}
+#else
+{
+ assert( connections != NULL );
+ assert( index != NULL );
+ assert( *index <= dtblsize );
+
+ if( c != NULL ) ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+
c = NULL;
for(; *index < dtblsize; (*index)++) {
assert( connections[*index].c_conn_state == SLAP_C_INVALID );
}
- if( c != NULL ) {
- ldap_pvt_thread_mutex_lock( &c->c_mutex );
- }
-
+ if( c != NULL ) ldap_pvt_thread_mutex_lock( &c->c_mutex );
return c;
}
+#endif
void connection_done( Connection *c )
{
+#ifdef SLAP_MULTI_CONN_ARRAY
+ int conn_array_id;
+#endif
+
assert( connections != NULL );
- if( c != NULL ) {
- ldap_pvt_thread_mutex_unlock( &c->c_mutex );
- }
+ if( c != NULL ) ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+#ifdef SLAP_MULTI_CONN_ARRAY
+ for ( conn_array_id = 0;
+ conn_array_id < NUM_CONNECTION_ARRAY;
+ conn_array_id++ )
+ {
+ ldap_pvt_thread_mutex_unlock( &connections_mutex[ conn_array_id ] );
+ }
+#else
ldap_pvt_thread_mutex_unlock( &connections_mutex );
+#endif
}
/*
ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex ); \
} while (0)
#else /* !SLAPD_MONITOR */
-#define INCR_OP_INITIATED(index)
+#define INCR_OP_INITIATED(index) do { } while (0)
#define INCR_OP_COMPLETED(index) \
do { \
ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex ); \
}
if ( op->o_cancel == SLAP_CANCEL_REQ ) {
- if ( rc == SLAPD_ABANDON )
+ if ( rc == SLAPD_ABANDON ) {
op->o_cancel = SLAP_CANCEL_ACK;
- else
+ } else {
op->o_cancel = LDAP_TOO_LATE;
+ }
}
while ( op->o_cancel != SLAP_CANCEL_NONE &&
op->o_cancel != SLAP_CANCEL_DONE )
case LBER_ERROR:
case LDAP_REQ_UNBIND:
/* c_mutex is locked */
- connection_closing(
- conn, tag == LDAP_REQ_UNBIND ? NULL : "operations error" );
+ connection_closing( conn,
+ tag == LDAP_REQ_UNBIND ? NULL : "operations error" );
break;
-
- case LDAP_REQ_BIND:
- conn->c_sasl_bind_in_progress =
- rc == LDAP_SASL_BIND_IN_PROGRESS ? 1 : 0;
-
- if( conn->c_conn_state == SLAP_C_BINDING) {
- conn->c_conn_state = SLAP_C_ACTIVE;
- }
}
connection_resched( conn );
c = connection_get( s );
c->c_clientfunc = func;
c->c_clientarg = arg;
- connection_return( c );
+
slapd_add_internal( s, 0 );
slapd_set_read( s, 1 );
+ connection_return( c );
return 0;
}
c->c_conn_state = SLAP_C_INVALID;
c->c_struct_state = SLAP_C_UNUSED;
c->c_close_reason = "?"; /* should never be needed */
+ slapd_sd_lock();
ber_sockbuf_free( c->c_sb );
+ slapd_remove( s, 0, 1, 1 );
c->c_sb = ber_sockbuf_alloc( );
{
ber_len_t max = sockbuf_max_incoming;
}
connection_return( c );
- slapd_remove( s, 0, 1 );
}
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+
+static int connection_read( ber_socket_t s, conn_readinfo *cri );
+
+static void* connection_read_thread( void* ctx, void* argv )
+{
+ int rc ;
+ conn_readinfo cri = { NULL, NULL, NULL, 0 };
+ ber_socket_t s = (long)argv;
+
+ /*
+ * read incoming LDAP requests. If there is more than one,
+ * the first one is returned with new_op
+ */
+ if( ( rc = connection_read( s, &cri ) ) < 0 ) {
+ Debug( LDAP_DEBUG_CONNS, "connection_read(%d) error\n", s, 0, 0 );
+ return (void*)(long)rc;
+ }
+
+ /* execute a single queued request in the same thread */
+ if( cri.op && !cri.nullop ) {
+ rc = (long)connection_operation( ctx, cri.op );
+ } else if ( cri.func ) {
+ rc = (long)cri.func( ctx, cri.arg );
+ }
+
+ return (void*)(long)rc;
+}
+
+int connection_read_activate( ber_socket_t s )
+{
+ int rc;
+
+ /*
+ * suspend reading on this file descriptor until a connection processing
+ * thread reads data on it. Otherwise the listener thread will repeatedly
+ * submit the same event on it to the pool.
+ */
+ rc = slapd_clr_read( s, 0 );
+ if ( rc )
+ return rc;
+
+ rc = ldap_pvt_thread_pool_submit( &connection_pool,
+ connection_read_thread, (void *)(long)s );
+
+ if( rc != 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "connection_read_activate(%d): submit failed (%d)\n",
+ s, rc, 0 );
+ }
+
+ return rc;
+}
+#endif
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+static int
+connection_read( ber_socket_t s, conn_readinfo *cri )
+#else
int connection_read(ber_socket_t s)
+#endif
{
int rc = 0;
Connection *c;
assert( connections != NULL );
- ldap_pvt_thread_mutex_lock( &connections_mutex );
+ ldap_pvt_thread_mutex_lock( MCA_GET_CONN_MUTEX(s) );
/* get (locked) connection */
c = connection_get( s );
Debug( LDAP_DEBUG_ANY,
"connection_read(%ld): no connection!\n",
(long) s, 0, 0 );
- slapd_remove(s, 1, 0);
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
return -1;
}
Debug( LDAP_DEBUG_TRACE,
"connection_read(%d): closing, ignoring input for id=%lu\n",
s, c->c_connid, 0 );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ slapd_set_read( s, 1 );
+#endif
connection_return( c );
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
return 0;
}
if ( c->c_conn_state == SLAP_C_CLIENT ) {
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ cri->func = c->c_clientfunc;
+ cri->arg = c->c_clientarg;
+ /* read should already be cleared */
+#else
slapd_clr_read( s, 0 );
ldap_pvt_thread_pool_submit( &connection_pool,
c->c_clientfunc, c->c_clientarg );
+#endif
connection_return( c );
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
return 0;
}
if ( c->c_is_tls && c->c_needs_tls_accept ) {
rc = ldap_pvt_tls_accept( c->c_sb, slap_tls_ctx );
if ( rc < 0 ) {
-#if 0 /* required by next #if 0 */
- struct timeval tv;
- fd_set rfd;
-#endif
-
Debug( LDAP_DEBUG_TRACE,
- "connection_read(%d): TLS accept error "
+ "connection_read(%d): TLS accept failure "
"error=%d id=%lu, closing\n",
s, rc, c->c_connid );
+
c->c_needs_tls_accept = 0;
/* connections_mutex and c_mutex are locked */
connection_closing( c, "TLS negotiation failure" );
#if 0
- /* Drain input before close, to allow SSL error codes
- * to propagate to client. */
- FD_ZERO(&rfd);
- FD_SET(s, &rfd);
- for (rc=1; rc>0;) {
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- rc = select(s+1, &rfd, NULL, NULL, &tv);
- if (rc == 1) {
- ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DRAIN, NULL);
+ {
+ struct timeval tv;
+ fd_set rfd;
+ /* Drain input before close, to allow SSL error codes
+ * to propagate to client. */
+ FD_ZERO(&rfd);
+ FD_SET(s, &rfd);
+ for (rc=1; rc>0;) {
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ rc = select(s+1, &rfd, NULL, NULL, &tv);
+ if (rc == 1) {
+ ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DRAIN, NULL);
+ }
}
}
#endif
+
connection_close( c );
+ connection_return( c );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
+ return 0;
} else if ( rc == 0 ) {
void *ssl;
if( rc != 0 ||
!ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL ) )
{
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ slapd_set_read( s, 1 );
+#endif
+
connection_return( c );
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
return 0;
}
}
if ( c->c_sasl_layers ) {
/* If previous layer is not removed yet, give up for now */
if ( !c->c_sasl_sockctx ) {
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ slapd_set_read( s, 1 );
+#endif
+
connection_return( c );
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
return 0;
}
c->c_sasl_layers = 0;
rc = ldap_pvt_sasl_install( c->c_sb, c->c_sasl_sockctx );
-
if( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
"connection_read(%d): SASL install error "
"error=%d id=%lu, closing\n",
s, rc, c->c_connid );
+
/* connections_mutex and c_mutex are locked */
connection_closing( c, "SASL layer install failure" );
connection_close( c );
connection_return( c );
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
return 0;
}
}
do {
/* How do we do this without getting into a busy loop ? */
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ rc = connection_input( c, cri );
+#else
rc = connection_input( c );
+#endif
}
#ifdef DATA_READY_LOOP
while( !rc && ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL ));
Debug( LDAP_DEBUG_TRACE,
"connection_read(%d): input error=%d id=%lu, closing.\n",
s, rc, c->c_connid );
+
/* connections_mutex and c_mutex are locked */
connection_closing( c, conn_lost_str );
connection_close( c );
connection_return( c );
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
return 0;
}
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
+ slapd_set_write( s, 0 );
+ }
+
+ slapd_set_read( s, 1 );
+#else
if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_READ, NULL ) ) {
slapd_set_read( s, 1 );
}
if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
slapd_set_write( s, 1 );
}
+#endif
connection_return( c );
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
+
return 0;
}
static int
-connection_input(
- Connection *conn )
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+connection_input( Connection *conn , conn_readinfo *cri )
+#else
+connection_input( Connection *conn )
+#endif
{
Operation *op;
ber_tag_t tag;
#ifdef LDAP_CONNECTIONLESS
if ( conn->c_is_udp ) {
- char peername[sizeof("IP=255.255.255.255:65336")];
- len = ber_int_sb_read(conn->c_sb, &peeraddr,
- sizeof(struct sockaddr));
- if (len != sizeof(struct sockaddr))
- return 1;
+ char peername[sizeof("IP=255.255.255.255:65336")];
+
+ len = ber_int_sb_read(conn->c_sb, &peeraddr, sizeof(struct sockaddr));
+ if (len != sizeof(struct sockaddr)) return 1;
+
sprintf( peername, "IP=%s:%d",
inet_ntoa( peeraddr.sa_in_addr.sin_addr ),
(unsigned) ntohs( peeraddr.sa_in_addr.sin_port ) );
conn->c_connid, peername, conn->c_sock_name.bv_val, 0, 0 );
}
#endif
+
tag = ber_get_next( conn->c_sb, &len, conn->c_currentber );
if ( tag != LDAP_TAG_MESSAGE ) {
int err = errno;
if ( (tag = ber_get_int( ber, &msgid )) != LDAP_TAG_MSGID ) {
/* log, close and send error */
- Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n",
- tag, 0, 0 );
+ Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n", tag, 0, 0 );
ber_free( ber, 1 );
return -1;
}
if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
/* log, close and send error */
- Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%lx\n",
- tag, 0, 0 );
+ Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%lx\n", tag, 0, 0 );
ber_free( ber, 1 );
return -1;
}
}
#endif
+
if(tag == LDAP_REQ_BIND) {
/* immediately abandon all existing operations upon BIND */
connection_abandon( conn );
op->o_conn = conn;
/* clear state if the connection is being reused from inactive */
if ( conn->c_conn_state == SLAP_C_INACTIVE ) {
- memset( &conn->c_pagedresults_state, 0, sizeof( conn->c_pagedresults_state ) );
+ memset( &conn->c_pagedresults_state, 0,
+ sizeof( conn->c_pagedresults_state ) );
}
op->o_res_ber = NULL;
conn->c_connid, defer, 0 );
conn->c_n_ops_pending++;
LDAP_STAILQ_INSERT_TAIL( &conn->c_pending_ops, op, o_next );
- if ( conn->c_n_ops_pending > max ) {
- rc = -1;
- } else {
- rc = 1;
- }
+ rc = ( conn->c_n_ops_pending > max ) ? -1 : 0;
+
} else {
conn->c_n_ops_executing++;
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ /*
+ * The first op will be processed in the same thread context,
+ * as long as there is only one op total.
+ * Subsequent ops will be submitted to the pool by
+ * calling connection_op_activate()
+ */
+ if ( cri->op == NULL ) {
+ /* the first incoming request */
+ connection_op_queue( op );
+ cri->op = op;
+ } else {
+ if ( !cri->nullop ) {
+ cri->nullop = 1;
+ rc = ldap_pvt_thread_pool_submit( &connection_pool,
+ connection_operation, (void *) cri->op );
+ }
+ connection_op_activate( op );
+ }
+#else
connection_op_activate( op );
+#endif
}
#ifdef NO_THREADS
return 1;
}
#endif
- assert( conn->c_struct_state == SLAP_C_USED );
+ assert( conn->c_struct_state == SLAP_C_USED );
return rc;
}
ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
/* use trylock to avoid possible deadlock */
- rc = ldap_pvt_thread_mutex_trylock( &connections_mutex );
+ rc = ldap_pvt_thread_mutex_trylock( MCA_GET_CONN_MUTEX( sd ) );
if( rc ) {
Debug( LDAP_DEBUG_TRACE,
* so recheck state below.
*/
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
- ldap_pvt_thread_mutex_lock( &connections_mutex );
+ ldap_pvt_thread_mutex_lock( MCA_GET_CONN_MUTEX ( sd ) );
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
}
connection_close( conn );
}
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX( sd ) );
return 0;
}
}
while ((op = LDAP_STAILQ_FIRST( &conn->c_pending_ops )) != NULL) {
- if ( conn->c_n_ops_executing > connection_pool_max/2 ) {
- break;
- }
+ if ( conn->c_n_ops_executing > connection_pool_max/2 ) break;
+
LDAP_STAILQ_REMOVE_HEAD( &conn->c_pending_ops, o_next );
LDAP_STAILQ_NEXT(op, o_next) = NULL;
+
/* pending operations should not be marked for abandonment */
assert(!op->o_abandon);
connection_op_activate( op );
- if ( conn->c_conn_state == SLAP_C_BINDING ) {
- break;
- }
+ if ( conn->c_conn_state == SLAP_C_BINDING ) break;
}
return 0;
}
{
if ( op->o_connid == (unsigned long)(-1) ) {
snprintf( op->o_log_prefix, sizeof( op->o_log_prefix ),
- "conn=-1 op=%lu", op->o_opid );
+ "conn=-1 op=%lu", op->o_opid );
} else {
snprintf( op->o_log_prefix, sizeof( op->o_log_prefix ),
- "conn=%lu op=%lu", op->o_connid, op->o_opid );
+ "conn=%lu op=%lu", op->o_connid, op->o_opid );
}
}
-static int connection_op_activate( Operation *op )
+static int connection_bind_cb( Operation *op, SlapReply *rs )
+{
+ slap_callback *cb = op->o_callback;
+ op->o_callback = cb->sc_next;
+
+ ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
+ op->o_conn->c_conn_state = SLAP_C_ACTIVE;
+ ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
+
+ ch_free( cb );
+ return SLAP_CB_CONTINUE;
+}
+
+static void connection_op_queue( Operation *op )
{
- int status;
ber_tag_t tag = op->o_tag;
- if(tag == LDAP_REQ_BIND) {
+ if (tag == LDAP_REQ_BIND) {
+ slap_callback *sc = ch_calloc( 1, sizeof( slap_callback ));
+ sc->sc_response = connection_bind_cb;
+ sc->sc_next = op->o_callback;
+ op->o_callback = sc;
op->o_conn->c_conn_state = SLAP_C_BINDING;
}
ber_dupbv( &op->o_ndn, &op->o_conn->c_sasl_authz_dn );
}
}
+
op->o_authtype = op->o_conn->c_authtype;
ber_dupbv( &op->o_authmech, &op->o_conn->c_authmech );
op->o_protocol = op->o_conn->c_protocol
? op->o_conn->c_protocol : LDAP_VERSION3;
}
- if (op->o_conn->c_conn_state == SLAP_C_INACTIVE
- && op->o_protocol > LDAP_VERSION2)
+
+ if (op->o_conn->c_conn_state == SLAP_C_INACTIVE &&
+ op->o_protocol > LDAP_VERSION2)
{
op->o_conn->c_conn_state = SLAP_C_ACTIVE;
}
connection_init_log_prefix( op );
LDAP_STAILQ_INSERT_TAIL( &op->o_conn->c_ops, op, o_next );
+}
+
+static int connection_op_activate( Operation *op )
+{
+ int rc;
+
+ connection_op_queue( op );
- status = ldap_pvt_thread_pool_submit( &connection_pool,
+ rc = ldap_pvt_thread_pool_submit( &connection_pool,
connection_operation, (void *) op );
- if ( status != 0 ) {
+ if ( rc != 0 ) {
Debug( LDAP_DEBUG_ANY,
- "ldap_pvt_thread_pool_submit: failed (%d) for conn=%lu\n",
- status, op->o_connid, 0 );
+ "connection_op_activate: submit failed (%d) for conn=%lu\n",
+ rc, op->o_connid, 0 );
/* should move op to pending list */
}
- return status;
+ return rc;
}
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+static int connection_write( ber_socket_t s );
+static void *connection_write_thread( void *ctx, void *arg )
+{
+ return (void *)(long)connection_write((long)arg);
+}
+
+int connection_write_activate( ber_socket_t s )
+{
+ int rc;
+
+ /*
+ * suspend reading on this file descriptor until a connection processing
+ * thread write data on it. Otherwise the listener thread will repeatedly
+ * submit the same event on it to the pool.
+ */
+ slapd_clr_write( s, 0);
+
+ rc = ldap_pvt_thread_pool_submit( &connection_pool,
+ connection_write_thread, (void *)(long)s );
+
+ if( rc != 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "connection_write_activate(%d): submit failed (%d)\n",
+ (int) s, rc, 0 );
+ }
+ return rc;
+}
+
+static
+#endif
int connection_write(ber_socket_t s)
{
Connection *c;
assert( connections != NULL );
- ldap_pvt_thread_mutex_lock( &connections_mutex );
+ ldap_pvt_thread_mutex_lock( MCA_GET_CONN_MUTEX( s ) );
c = connection_get( s );
-
if( c == NULL ) {
Debug( LDAP_DEBUG_ANY,
"connection_write(%ld): no connection!\n",
(long)s, 0, 0 );
- slapd_remove(s, 1, 0);
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX( s ) );
return -1;
}
+#ifndef SLAP_LIGHTWEIGHT_DISPATCHER
slapd_clr_write( s, 0);
-
+#endif
c->c_n_write++;
Debug( LDAP_DEBUG_TRACE,
if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
slapd_set_write( s, 1 );
}
- /* If there are ops pending because of a writewaiter, start
- * one up.
+
+ /* If there are ops pending because of a writewaiter,
+ * start one up.
*/
while ((op = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) {
if ( !c->c_writewaiter ) break;
- if ( c->c_n_ops_executing > connection_pool_max/2 ) {
- break;
- }
+ if ( c->c_n_ops_executing > connection_pool_max/2 ) break;
+
LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next );
LDAP_STAILQ_NEXT(op, o_next) = NULL;
+
/* pending operations should not be marked for abandonment */
assert(!op->o_abandon);
break;
}
+
connection_return( c );
- ldap_pvt_thread_mutex_unlock( &connections_mutex );
+ ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
return 0;
}
op->o_connid = op->o_conn->c_connid;
connection_init_log_prefix( op );
- op->o_time = slap_get_time();
+ slap_op_time( &op->o_time, &op->o_tincr );
}
void
conn->c_connid = conn_nextid++;
ldap_pvt_thread_mutex_unlock( &conn_nextid_mutex );
}
-
if ( csne->ce_opid == op->o_opid && csne->ce_connid == op->o_connid ) {
LDAP_TAILQ_REMOVE( op->o_bd->be_pending_csn_list,
csne, ce_csn_link );
+ if ( op->o_csn.bv_val == csne->ce_csn.bv_val ) {
+ BER_BVZERO( &op->o_csn );
+ }
ch_free( csne->ce_csn.bv_val );
ch_free( csne );
break;
ldap_pvt_thread_mutex_lock( op->o_bd->be_pcl_mutexp );
ber_dupbv( &pending->ce_csn, csn );
+ op->o_csn = pending->ce_csn;
pending->ce_connid = op->o_connid;
pending->ce_opid = op->o_opid;
pending->ce_state = SLAP_CSN_PENDING;
int
slap_get_csn(
Operation *op,
- char *csnbuf,
- int len,
struct berval *csn,
int manage_ctxcsn )
{
#ifndef HAVE_GMTIME_R
ldap_pvt_thread_mutex_lock( &gmtime_mutex );
#endif
- csn->bv_len = lutil_csnstr( csnbuf, len, 0, 0 );
+ csn->bv_len = lutil_csnstr( csn->bv_val, csn->bv_len, 0, 0 );
#ifndef HAVE_GMTIME_R
ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
#endif
- csn->bv_val = csnbuf;
if ( manage_ctxcsn )
slap_queue_csn( op, csn );
#include "ldap_rq.h"
#if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL)
-#include <sys/epoll.h>
+# include <sys/epoll.h>
#endif
#ifdef HAVE_TCPD
-#include <tcpd.h>
-#define SLAP_STRING_UNKNOWN STRING_UNKNOWN
-
+# include <tcpd.h>
int allow_severity = LOG_INFO;
int deny_severity = LOG_NOTICE;
+
+# define SLAP_STRING_UNKNOWN STRING_UNKNOWN
#else /* ! TCP Wrappers */
-#define SLAP_STRING_UNKNOWN "unknown"
+# define SLAP_STRING_UNKNOWN "unknown"
#endif /* ! TCP Wrappers */
#ifdef LDAP_PF_LOCAL
-#include <sys/stat.h>
+# include <sys/stat.h>
/* this should go in <ldap.h> as soon as it is accepted */
-#define LDAPI_MOD_URLEXT "x-mod"
+# define LDAPI_MOD_URLEXT "x-mod"
#endif /* LDAP_PF_LOCAL */
#ifdef LDAP_PF_INET6
static int emfile;
static int waking;
-#define WAKE_LISTENER(w) do { \
- if ((w) && waking < 5) { waking++; tcp_write( wake_sds[1], "0", 1 ); } \
- } while(0)
+#define WAKE_LISTENER(w) do { \
+ if ((w) && waking < 5) { \
+ waking++; \
+ tcp_write( wake_sds[1], "0", 1 ); \
+ } \
+} while(0)
-volatile sig_atomic_t slapd_shutdown = 0, slapd_gentle_shutdown = 0;
+volatile sig_atomic_t slapd_shutdown = 0;
+volatile sig_atomic_t slapd_gentle_shutdown = 0;
volatile sig_atomic_t slapd_abrupt_shutdown = 0;
static struct slap_daemon {
ldap_pvt_thread_mutex_t sd_mutex;
+#ifdef HAVE_TCPD
+ ldap_pvt_thread_mutex_t tcpd_mutex;
+#endif
ber_socket_t sd_nactives;
int sd_nwriters;
int sd_epfd;
int sd_nfds;
#else
-
#ifndef HAVE_WINSOCK
/* In winsock, accept() returns values higher than dtblsize
so don't bother with this optimization */
int sd_nfds;
#endif
-
fd_set sd_actives;
fd_set sd_readers;
fd_set sd_writers;
} slap_daemon;
#ifdef HAVE_EPOLL
-#define SLAP_EVENTS_ARE_INDEXED 0
-#define SLAP_SOCK_IX(s) (slap_daemon.sd_index[s])
-#define SLAP_SOCK_EP(s) (slap_daemon.sd_epolls[SLAP_SOCK_IX(s)])
-#define SLAP_SOCK_EV(s) (SLAP_SOCK_EP(s).events)
-#define SLAP_SOCK_IS_ACTIVE(s) (SLAP_SOCK_IX(s) != -1)
-#define SLAP_SOCK_NOT_ACTIVE(s) (SLAP_SOCK_IX(s) == -1)
-#define SLAP_SOCK_IS_SET(s, mode) (SLAP_SOCK_EV(s) & mode)
-
-#define SLAP_SOCK_IS_READ(s) SLAP_SOCK_IS_SET(s, EPOLLIN)
-#define SLAP_SOCK_IS_WRITE(s) SLAP_SOCK_IS_SET(s, EPOLLOUT)
-
-#define SLAP_SET_SOCK(s, mode) do { \
- if ((SLAP_SOCK_EV(s) & mode) != mode) { \
- SLAP_SOCK_EV(s) |= mode; \
- epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, s, \
- &SLAP_SOCK_EP(s)); \
- } \
+# define SLAP_EVENTS_ARE_INDEXED 0
+# define SLAP_SOCK_IX(s) (slap_daemon.sd_index[(s)])
+# define SLAP_SOCK_EP(s) (slap_daemon.sd_epolls[SLAP_SOCK_IX(s)])
+# define SLAP_SOCK_EV(s) (SLAP_SOCK_EP(s).events)
+# define SLAP_SOCK_IS_ACTIVE(s) (SLAP_SOCK_IX(s) != -1)
+# define SLAP_SOCK_NOT_ACTIVE(s) (SLAP_SOCK_IX(s) == -1)
+# define SLAP_SOCK_IS_SET(s, mode) (SLAP_SOCK_EV(s) & (mode))
+
+# define SLAP_SOCK_IS_READ(s) SLAP_SOCK_IS_SET((s), EPOLLIN)
+# define SLAP_SOCK_IS_WRITE(s) SLAP_SOCK_IS_SET((s), EPOLLOUT)
+
+# define SLAP_SET_SOCK(s, mode) do { \
+ if ((SLAP_SOCK_EV(s) & (mode)) != (mode)) { \
+ SLAP_SOCK_EV(s) |= (mode); \
+ epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, (s), \
+ &SLAP_SOCK_EP(s)); \
+ } \
} while(0)
-#define SLAP_CLR_SOCK(s, mode) do { \
- if ((SLAP_SOCK_EV(s) & mode)) { \
- SLAP_SOCK_EV(s) &= ~mode; \
- epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, s, \
- &SLAP_SOCK_EP(s)); \
- } \
+# define SLAP_CLR_SOCK(s, mode) do { \
+ if ((SLAP_SOCK_EV(s) & (mode))) { \
+ SLAP_SOCK_EV(s) &= ~(mode); \
+ epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, s, \
+ &SLAP_SOCK_EP(s)); \
+ } \
} while(0)
-#define SLAP_SOCK_SET_READ(s) SLAP_SET_SOCK(s, EPOLLIN)
-#define SLAP_SOCK_SET_WRITE(s) SLAP_SET_SOCK(s, EPOLLOUT)
+# define SLAP_SOCK_SET_READ(s) SLAP_SET_SOCK(s, EPOLLIN)
+# define SLAP_SOCK_SET_WRITE(s) SLAP_SET_SOCK(s, EPOLLOUT)
-#define SLAP_SOCK_CLR_READ(s) SLAP_CLR_SOCK(s, EPOLLIN)
-#define SLAP_SOCK_CLR_WRITE(s) SLAP_CLR_SOCK(s, EPOLLOUT)
+# ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+# define SLAP_SOCK_SET_SUSPEND(s) \
+ ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] = 1 )
+# define SLAP_SOCK_CLR_SUSPEND(s) \
+ ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] = 0 )
+# define SLAP_SOCK_IS_SUSPEND(s) \
+ ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] == 1 )
+# endif
-#define SLAP_CLR_EVENT(i, mode) (revents[i].events &= ~mode)
+# define SLAP_SOCK_CLR_READ(s) SLAP_CLR_SOCK((s), EPOLLIN)
+# define SLAP_SOCK_CLR_WRITE(s) SLAP_CLR_SOCK((s), EPOLLOUT)
+# define SLAP_CLR_EVENT(i, mode) (revents[(i)].events &= ~(mode))
-#define SLAP_EVENT_MAX slap_daemon.sd_nfds
+# define SLAP_EVENT_MAX slap_daemon.sd_nfds
/* If a Listener address is provided, store that as the epoll data.
* Otherwise, store the address of this socket's slot in the
* index array. If we can't do this add, the system is out of
* resources and we need to shutdown.
*/
-#define SLAP_ADD_SOCK(s, l) do { \
- int rc; \
- SLAP_SOCK_IX(s) = slap_daemon.sd_nfds; \
- SLAP_SOCK_EP(s).data.ptr = (l) ? (l) : (void *)(&SLAP_SOCK_IX(s)); \
- SLAP_SOCK_EV(s) = EPOLLIN; \
- rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_ADD, s, \
- &SLAP_SOCK_EP(s)); \
- if ( rc == 0 ) slap_daemon.sd_nfds++; \
- else { \
- Debug( LDAP_DEBUG_ANY, "daemon: epoll_ctl ADD failed, errno %d, shutting down\n", \
- errno, 0, 0 ); \
- slapd_shutdown = 2; \
- } \
-} while(0)
-
-#define SLAP_EV_LISTENER(ptr) (((int *)(ptr) >= slap_daemon.sd_index && \
- (int *)(ptr) <= (slap_daemon.sd_index+dtblsize)) ? 0 : 1)
-
-#define SLAP_EV_PTRFD(ptr) (SLAP_EV_LISTENER(ptr) ? \
- ((Listener *)ptr)->sl_sd : (int *)(ptr) - slap_daemon.sd_index)
-
-#define SLAP_DEL_SOCK(s) do { \
- int fd, rc, index = SLAP_SOCK_IX(s); \
- rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_DEL, s, \
- &SLAP_SOCK_EP(s)); \
- slap_daemon.sd_epolls[index] = slap_daemon.sd_epolls[slap_daemon.sd_nfds-1]; \
- fd = SLAP_EV_PTRFD(slap_daemon.sd_epolls[index].data.ptr); \
- slap_daemon.sd_index[fd] = index; \
- slap_daemon.sd_index[s] = -1; \
- slap_daemon.sd_nfds--; \
-} while(0)
-
-#define SLAP_EVENT_CLR_READ(i) SLAP_CLR_EVENT(i, EPOLLIN)
-#define SLAP_EVENT_CLR_WRITE(i) SLAP_CLR_EVENT(i, EPOLLOUT)
-
-#define SLAP_CHK_EVENT(i, mode) (revents[i].events & mode)
-
-#define SLAP_EVENT_IS_READ(i) SLAP_CHK_EVENT(i, EPOLLIN)
-#define SLAP_EVENT_IS_WRITE(i) SLAP_CHK_EVENT(i, EPOLLOUT)
-#define SLAP_EVENT_IS_LISTENER(i) SLAP_EV_LISTENER(revents[i].data.ptr)
-#define SLAP_EVENT_LISTENER(i) (revents[i].data.ptr)
-
-#define SLAP_EVENT_FD(i) SLAP_EV_PTRFD(revents[i].data.ptr)
-#define SLAP_SOCK_SET_MUTE(s) SLAP_SOCK_CLR_READ(s)
-#define SLAP_SOCK_CLR_MUTE(s) SLAP_SOCK_SET_READ(s)
-#define SLAP_SOCK_IS_MUTE(s) (!SLAP_SOCK_IS_READ(s))
-
-#define SLAP_SOCK_SET_INIT \
- slap_daemon.sd_epolls = ch_calloc(1, sizeof(struct epoll_event) * dtblsize * 2); \
- slap_daemon.sd_index = ch_malloc(sizeof(int) * dtblsize); \
- slap_daemon.sd_epfd = epoll_create( dtblsize ); \
- for (i=0; i<dtblsize; i++) slap_daemon.sd_index[i] = -1
-
-
-#define SLAP_EVENT_DECL \
- struct epoll_event *revents
-
-#define SLAP_EVENT_INIT \
- revents = slap_daemon.sd_epolls + dtblsize; \
-
-#define SLAP_EVENT_WAIT(tvp) \
- epoll_wait( slap_daemon.sd_epfd, revents, dtblsize, tvp ? tvp->tv_sec * 1000 : -1 )
+# define SLAP_ADD_SOCK(s, l) do { \
+ int rc; \
+ SLAP_SOCK_IX((s)) = slap_daemon.sd_nfds; \
+ SLAP_SOCK_EP((s)).data.ptr = (l) ? (l) : (void *)(&SLAP_SOCK_IX(s)); \
+ SLAP_SOCK_EV((s)) = EPOLLIN; \
+ rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_ADD, \
+ (s), &SLAP_SOCK_EP((s))); \
+ if ( rc == 0 ) { \
+ slap_daemon.sd_nfds++; \
+ } else { \
+ Debug( LDAP_DEBUG_ANY, \
+ "daemon: epoll_ctl(ADD,fd=%d) failed, errno=%d, shutting down\n", \
+ s, errno, 0 ); \
+ slapd_shutdown = 2; \
+ } \
+} while (0)
+
+# define SLAP_EV_LISTENER(ptr) (((int *)(ptr) >= slap_daemon.sd_index && \
+ (int *)(ptr) <= (slap_daemon.sd_index+dtblsize)) ? 0 : 1 )
+
+# define SLAP_EV_PTRFD(ptr) (SLAP_EV_LISTENER(ptr) ? \
+ ((Listener *)ptr)->sl_sd : (int *)(ptr) - slap_daemon.sd_index)
+
+# define SLAP_DEL_SOCK(s) do { \
+ int fd, rc, index = SLAP_SOCK_IX((s)); \
+ if ( index < 0 ) break; \
+ rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_DEL, \
+ (s), &SLAP_SOCK_EP((s))); \
+ slap_daemon.sd_epolls[index] = \
+ slap_daemon.sd_epolls[slap_daemon.sd_nfds-1]; \
+ fd = SLAP_EV_PTRFD(slap_daemon.sd_epolls[index].data.ptr); \
+ slap_daemon.sd_index[fd] = index; \
+ slap_daemon.sd_index[(s)] = -1; \
+ slap_daemon.sd_nfds--; \
+} while (0)
+
+# define SLAP_EVENT_CLR_READ(i) SLAP_CLR_EVENT((i), EPOLLIN)
+# define SLAP_EVENT_CLR_WRITE(i) SLAP_CLR_EVENT((i), EPOLLOUT)
+
+# define SLAP_CHK_EVENT(i, mode) (revents[(i)].events & mode)
+
+# define SLAP_EVENT_IS_READ(i) SLAP_CHK_EVENT((i), EPOLLIN)
+# define SLAP_EVENT_IS_WRITE(i) SLAP_CHK_EVENT((i), EPOLLOUT)
+# define SLAP_EVENT_IS_LISTENER(i) SLAP_EV_LISTENER(revents[(i)].data.ptr)
+# define SLAP_EVENT_LISTENER(i) (revents[(i)].data.ptr)
+
+# define SLAP_EVENT_FD(i) SLAP_EV_PTRFD(revents[(i)].data.ptr)
+
+# define SLAP_SOCK_SET_INIT do { \
+ slap_daemon.sd_epolls = ch_calloc(1, \
+ sizeof(struct epoll_event) * dtblsize * 2); \
+ slap_daemon.sd_index = ch_malloc(sizeof(int) * dtblsize); \
+ slap_daemon.sd_epfd = epoll_create( dtblsize ); \
+ for (i=0; i<dtblsize; i++) slap_daemon.sd_index[i] = -1; \
+} while (0)
+
+# define SLAP_EVENT_DECL struct epoll_event *revents
+
+# define SLAP_EVENT_INIT do { \
+ revents = slap_daemon.sd_epolls + dtblsize; \
+} while (0)
+
+# define SLAP_EVENT_WAIT(tvp) \
+ epoll_wait( slap_daemon.sd_epfd, revents, \
+ dtblsize, (tvp) ? (tvp)->tv_sec * 1000 : -1 )
#else
-
/* select */
-#define SLAP_EVENTS_ARE_INDEXED 1
-#define SLAP_EVENT_DECL \
+
+# define SLAP_EVENTS_ARE_INDEXED 1
+# define SLAP_EVENT_DECL \
fd_set readfds, writefds
-#define SLAP_EVENT_INIT \
+# define SLAP_EVENT_INIT do { \
AC_MEMCPY( &readfds, &slap_daemon.sd_readers, sizeof(fd_set) ); \
- if ( nwriters ) \
+ if ( nwriters ) { \
AC_MEMCPY( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) ); \
- else \
- FD_ZERO( &writefds )
-
-#ifdef FD_SETSIZE
-#define CHK_SETSIZE \
- if (dtblsize > FD_SETSIZE) dtblsize = FD_SETSIZE
-#else
-#define CHK_SETSIZE
-#endif
-
-#define SLAP_SOCK_SET_INIT \
- CHK_SETSIZE; \
- FD_ZERO(&slap_daemon.sd_readers); \
- FD_ZERO(&slap_daemon.sd_writers)
-
-#define SLAP_SOCK_IS_ACTIVE(fd) FD_ISSET(fd, &slap_daemon.sd_actives)
-
-#define SLAP_SOCK_IS_READ(fd) FD_ISSET(fd, &slap_daemon.sd_readers)
-#define SLAP_SOCK_IS_WRITE(fd) FD_ISSET(fd, &slap_daemon.sd_writers)
-
-#define SLAP_SOCK_NOT_ACTIVE(fd) (!SLAP_SOCK_IS_ACTIVE(fd) && \
+ } else { \
+ FD_ZERO( &writefds ); \
+ } \
+} while (0)
+
+# ifdef FD_SETSIZE
+# define CHK_SETSIZE do { \
+ if (dtblsize > FD_SETSIZE) dtblsize = FD_SETSIZE; \
+} while (0)
+# else
+# define CHK_SETSIZE do { ; } while (0)
+# endif
+
+# define SLAP_SOCK_SET_INIT do { \
+ CHK_SETSIZE; \
+ FD_ZERO(&slap_daemon.sd_readers); \
+ FD_ZERO(&slap_daemon.sd_writers); \
+} while (0)
+
+# define SLAP_SOCK_IS_ACTIVE(fd) FD_ISSET((fd), &slap_daemon.sd_actives)
+# define SLAP_SOCK_IS_READ(fd) FD_ISSET((fd), &slap_daemon.sd_readers)
+# define SLAP_SOCK_IS_WRITE(fd) FD_ISSET((fd), &slap_daemon.sd_writers)
+
+# define SLAP_SOCK_NOT_ACTIVE(fd) (!SLAP_SOCK_IS_ACTIVE(fd) && \
!SLAP_SOCK_IS_READ(fd) && !SLAP_SOCK_IS_WRITE(fd))
-#ifdef HAVE_WINSOCK
-#define SLAP_SOCK_SET_READ(fd) do { \
- if (!SLAP_SOCK_IS_READ(fd)) {FD_SET(fd, &slap_daemon.sd_readers);} \
+# ifdef HAVE_WINSOCK
+# define SLAP_SOCK_SET_READ(fd) do { \
+ if (!SLAP_SOCK_IS_READ(fd)) { FD_SET((fd), &slap_daemon.sd_readers); } \
} while(0)
-#define SLAP_SOCK_SET_WRITE(fd) do { \
- if (!SLAP_SOCK_IS_WRITE(fd)) {FD_SET(fd, &slap_daemon.sd_writers);} \
+# define SLAP_SOCK_SET_WRITE(fd) do { \
+ if (!SLAP_SOCK_IS_WRITE(fd)) { FD_SET((fd), &slap_daemon.sd_writers); } \
} while(0)
-#define SLAP_ADDTEST(s)
-#define SLAP_EVENT_MAX dtblsize
-#else
-#define SLAP_SOCK_SET_READ(fd) FD_SET(fd, &slap_daemon.sd_readers)
-#define SLAP_SOCK_SET_WRITE(fd) FD_SET(fd, &slap_daemon.sd_writers)
-
-#define SLAP_EVENT_MAX slap_daemon.sd_nfds
-#define SLAP_ADDTEST(s) if (s >= slap_daemon.sd_nfds) slap_daemon.sd_nfds = s+1
-#endif
-
-#define SLAP_SOCK_CLR_READ(fd) FD_CLR(fd, &slap_daemon.sd_readers)
-#define SLAP_SOCK_CLR_WRITE(fd) FD_CLR(fd, &slap_daemon.sd_writers)
-
-#define SLAP_ADD_SOCK(s, l) do { \
- SLAP_ADDTEST(s); \
- FD_SET(s, &slap_daemon.sd_actives); \
- FD_SET(s, &slap_daemon.sd_readers); \
+# define SLAP_ADDTEST(s) do { } while 0
+# define SLAP_EVENT_MAX dtblsize
+# else
+# define SLAP_SOCK_SET_READ(fd) FD_SET((fd), &slap_daemon.sd_readers)
+# define SLAP_SOCK_SET_WRITE(fd) FD_SET((fd), &slap_daemon.sd_writers)
+
+# define SLAP_EVENT_MAX slap_daemon.sd_nfds
+# define SLAP_ADDTEST(s) do { \
+ if ((s) >= slap_daemon.sd_nfds) slap_daemon.sd_nfds = (s)+1; \
+} while (0)
+# endif
+
+# define SLAP_SOCK_CLR_READ(fd) FD_CLR((fd), &slap_daemon.sd_readers)
+# define SLAP_SOCK_CLR_WRITE(fd) FD_CLR((fd), &slap_daemon.sd_writers)
+
+# define SLAP_ADD_SOCK(s, l) do { \
+ SLAP_ADDTEST((s)); \
+ FD_SET((s), &slap_daemon.sd_actives); \
+ FD_SET((s), &slap_daemon.sd_readers); \
} while(0)
-#define SLAP_DEL_SOCK(s) do { \
- FD_CLR(s, &slap_daemon.sd_actives); \
- FD_CLR(s, &slap_daemon.sd_readers); \
- FD_CLR(s, &slap_daemon.sd_writers); \
+# define SLAP_DEL_SOCK(s) do { \
+ FD_CLR((s), &slap_daemon.sd_actives); \
+ FD_CLR((s), &slap_daemon.sd_readers); \
+ FD_CLR((s), &slap_daemon.sd_writers); \
} while(0)
-#define SLAP_EVENT_IS_READ(fd) FD_ISSET(fd, &readfds)
-#define SLAP_EVENT_IS_WRITE(fd) FD_ISSET(fd, &writefds)
-
-#define SLAP_EVENT_CLR_READ(fd) FD_CLR(fd, &readfds)
-#define SLAP_EVENT_CLR_WRITE(fd) FD_CLR(fd, &writefds)
+# define SLAP_EVENT_IS_READ(fd) FD_ISSET((fd), &readfds)
+# define SLAP_EVENT_IS_WRITE(fd) FD_ISSET((fd), &writefds)
-#define SLAP_EVENT_WAIT(tvp) \
- select( SLAP_EVENT_MAX, &readfds, \
- nwriters > 0 ? &writefds : NULL, NULL, tvp )
-
-#define SLAP_SOCK_SET_MUTE(s) FD_CLR(s, &readfds)
-#define SLAP_SOCK_CLR_MUTE(s) FD_SET(s, &readfds)
-#define SLAP_SOCK_IS_MUTE(s) (!FD_ISSET(s, &readfds))
+# define SLAP_EVENT_CLR_READ(fd) FD_CLR((fd), &readfds)
+# define SLAP_EVENT_CLR_WRITE(fd) FD_CLR((fd), &writefds)
+# define SLAP_EVENT_WAIT(tvp) \
+ select( SLAP_EVENT_MAX, &readfds, \
+ nwriters > 0 ? &writefds : NULL, NULL, (tvp) )
#endif
-
#ifdef HAVE_SLP
/*
* SLP related functions
assert( SLAP_SOCK_NOT_ACTIVE(s) );
- if ( isactive ) {
- slap_daemon.sd_nactives++;
- }
+ if ( isactive ) slap_daemon.sd_nactives++;
SLAP_ADD_SOCK(s, sl);
Debug( LDAP_DEBUG_CONNS, "daemon: added %ldr\n",
(long) s, 0, 0 );
+
+ ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ WAKE_LISTENER(1);
+#endif
+}
+
+void slapd_sd_lock()
+{
+ ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+}
+
+void slapd_sd_unlock()
+{
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
}
/*
* Remove the descriptor from daemon control
*/
-void slapd_remove(ber_socket_t s, int wasactive, int wake) {
+void slapd_remove(
+ ber_socket_t s,
+ int wasactive,
+ int wake,
+ int locked )
+{
int waswriter;
- ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+ int wasreader;
+
+ if ( !locked )
+ ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+
+ assert( SLAP_SOCK_IS_ACTIVE( s ));
+
+ if ( wasactive ) slap_daemon.sd_nactives--;
- if ( wasactive ) {
- slap_daemon.sd_nactives--;
- }
waswriter = SLAP_SOCK_IS_WRITE(s);
+ wasreader = SLAP_SOCK_IS_READ(s);
Debug( LDAP_DEBUG_CONNS, "daemon: removing %ld%s%s\n",
- (long) s, SLAP_SOCK_IS_READ(s) ? "r" : "",
+ (long) s,
+ wasreader ? "r" : "",
waswriter ? "w" : "" );
+
if ( waswriter ) slap_daemon.sd_nwriters--;
SLAP_DEL_SOCK(s);
if ( emfile ) {
int i;
for ( i = 0; slap_listeners[i] != NULL; i++ ) {
- if ( slap_listeners[i]->sl_sd != AC_SOCKET_INVALID ) {
- if ( slap_listeners[i]->sl_sd == s ) continue;
- if ( slap_listeners[i]->sl_is_mute ) {
- slap_listeners[i]->sl_is_mute = 0;
- emfile--;
- break;
- }
+ Listener *lr = slap_listeners[i];
+
+ if ( lr->sl_sd == AC_SOCKET_INVALID ) continue;
+ if ( lr->sl_sd == s ) continue;
+ if ( lr->sl_mute ) {
+ lr->sl_mute = 0;
+ emfile--;
+ break;
}
}
/* Walked the entire list without enabling anything; emfile
* counter is stale. Reset it.
*/
- if ( slap_listeners[i] == NULL )
- emfile = 0;
+ if ( slap_listeners[i] == NULL ) emfile = 0;
}
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
WAKE_LISTENER(wake || slapd_gentle_shutdown == 2);
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
assert( SLAP_SOCK_IS_ACTIVE( s ));
+
if ( SLAP_SOCK_IS_WRITE( s )) {
SLAP_SOCK_CLR_WRITE( s );
slap_daemon.sd_nwriters--;
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
assert( SLAP_SOCK_IS_ACTIVE( s ));
+
if ( !SLAP_SOCK_IS_WRITE( s )) {
SLAP_SOCK_SET_WRITE( s );
slap_daemon.sd_nwriters++;
WAKE_LISTENER(wake);
}
-void slapd_clr_read(ber_socket_t s, int wake) {
+int slapd_clr_read(ber_socket_t s, int wake) {
+ int rc = 1;
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
- assert( SLAP_SOCK_IS_ACTIVE( s ));
- SLAP_SOCK_CLR_READ( s );
-
+ if ( SLAP_SOCK_IS_ACTIVE( s )) {
+ SLAP_SOCK_CLR_READ( s );
+ rc = 0;
+ }
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
- WAKE_LISTENER(wake);
+ if ( !rc )
+ WAKE_LISTENER(wake);
+ return rc;
}
void slapd_set_read(ber_socket_t s, int wake) {
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
assert( SLAP_SOCK_IS_ACTIVE( s ));
- if (!SLAP_SOCK_IS_READ( s ))
- SLAP_SOCK_SET_READ( s );
+ if (!SLAP_SOCK_IS_READ( s )) SLAP_SOCK_SET_READ( s );
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
WAKE_LISTENER(wake);
tcp_close(s);
}
-static void slap_free_listener_addresses(struct sockaddr **sal)
-{
+static void slap_free_listener_addresses(struct sockaddr **sal) {
struct sockaddr **sap;
-
- if (sal == NULL) {
- return;
- }
-
- for (sap = sal; *sap != NULL; sap++) {
- ch_free(*sap);
- }
-
+ if (sal == NULL) return;
+ for (sap = sal; *sap != NULL; sap++) ch_free(*sap);
ch_free(sal);
}
type++;
}
- if ( strncasecmp( type, LDAPI_MOD_URLEXT "=", sizeof(LDAPI_MOD_URLEXT "=") - 1 ) == 0 ) {
- char *value = type
- + ( sizeof(LDAPI_MOD_URLEXT "=") - 1 );
- mode_t p = 0;
- int j;
+ if ( strncasecmp( type, LDAPI_MOD_URLEXT "=",
+ sizeof(LDAPI_MOD_URLEXT "=") - 1 ) == 0 )
+ {
+ char *value = type + ( sizeof(LDAPI_MOD_URLEXT "=") - 1 );
+ mode_t p = 0;
+ int j;
switch (strlen(value)) {
case 4:
/* skip leading '0' */
- if ( value[ 0 ] != '0' ) {
- return LDAP_OTHER;
- }
+ if ( value[ 0 ] != '0' ) return LDAP_OTHER;
value++;
case 3:
v = value[ j ] - '0';
- if ( v < 0 || v > 7 ) {
- return LDAP_OTHER;
- }
+ if ( v < 0 || v > 7 ) return LDAP_OTHER;
p |= v << 3*(2-j);
}
#ifdef LDAP_PF_LOCAL
if ( port == 0 ) {
*sal = ch_malloc(2 * sizeof(void *));
- if (*sal == NULL) {
- return -1;
- }
+ if (*sal == NULL) return -1;
sap = *sal;
*sap = ch_malloc(sizeof(struct sockaddr_un));
- if (*sap == NULL)
- goto errexit;
+ if (*sap == NULL) goto errexit;
sap[1] = NULL;
if ( strlen(host) >
- (sizeof(((struct sockaddr_un *)*sap)->sun_path) - 1) ) {
+ (sizeof(((struct sockaddr_un *)*sap)->sun_path) - 1) )
+ {
Debug( LDAP_DEBUG_ANY,
- "daemon: domain socket path (%s) too long in URL",
- host, 0, 0);
+ "daemon: domain socket path (%s) too long in URL",
+ host, 0, 0);
goto errexit;
}
snprintf(serv, sizeof serv, "%d", port);
if ( (err = getaddrinfo(host, serv, &hints, &res)) ) {
- Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo failed: %s\n",
+ Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo() failed: %s\n",
AC_GAI_STRERROR(err), 0, 0);
return -1;
}
/* EMPTY */ ;
}
*sal = ch_calloc(n, sizeof(void *));
- if (*sal == NULL) {
- return -1;
- }
+ if (*sal == NULL) return -1;
sap = *sal;
*sap = NULL;
}
freeaddrinfo(res);
+
#else
int i, n = 1;
struct in_addr in;
he = gethostbyname( host );
if( he == NULL ) {
Debug( LDAP_DEBUG_ANY,
- "daemon: invalid host %s", host, 0, 0);
+ "daemon: invalid host %s", host, 0, 0);
return -1;
}
- for (n = 0; he->h_addr_list[n]; n++) ;
+ for (n = 0; he->h_addr_list[n]; n++) /* empty */;
}
*sal = ch_malloc((n+1) * sizeof(void *));
- if (*sal == NULL) {
- return -1;
- }
+ if (*sal == NULL) return -1;
sap = *sal;
for ( i = 0; i<n; i++ ) {
sap[i] = ch_malloc(sizeof(struct sockaddr_in));
- if (*sap == NULL) {
- goto errexit;
- }
+ if (*sap == NULL) goto errexit;
+
(void)memset( (void *)sap[i], '\0', sizeof(struct sockaddr_in) );
sap[i]->sa_family = AF_INET;
((struct sockaddr_in *)sap[i])->sin_port = htons(port);
- if (he) {
- AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr, he->h_addr_list[i], sizeof(struct in_addr) );
- } else {
- AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr, &in, sizeof(struct in_addr) );
- }
+ AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr,
+ he ? he->h_addr_list[i] : &in, sizeof(struct in_addr) );
}
sap[i] = NULL;
#endif
}
l.sl_url.bv_val = NULL;
- l.sl_is_mute = 0;
+ l.sl_mute = 0;
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ l.sl_busy = 0;
+#endif
#ifndef HAVE_TLS
if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) {
- Debug( LDAP_DEBUG_ANY,
- "daemon: TLS not supported (%s)\n",
+ Debug( LDAP_DEBUG_ANY, "daemon: TLS not supported (%s)\n",
url, 0, 0 );
ldap_free_urldesc( lud );
return -1;
}
- if(! lud->lud_port ) {
- lud->lud_port = LDAP_PORT;
- }
+ if(! lud->lud_port ) lud->lud_port = LDAP_PORT;
#else
l.sl_is_tls = ldap_pvt_url_scheme2tls( lud->lud_scheme );
err = slap_get_listener_addresses(lud->lud_host, port, &sal);
}
}
+
#ifdef LDAP_CONNECTIONLESS
l.sl_is_udp = ( tmp == LDAP_PROTO_UDP );
#endif
#endif /* LDAP_PF_LOCAL || SLAP_X_LISTENER_MOD */
ldap_free_urldesc( lud );
- if ( err ) {
- return -1;
- }
+ if ( err ) return -1;
/* If we got more than one address returned, we need to make space
* for it in the slap_listeners array.
*/
- for ( num=0; sal[num]; num++ );
+ for ( num=0; sal[num]; num++ ) /* empty */;
if ( num > 1 ) {
*listeners += num-1;
- slap_listeners = ch_realloc( slap_listeners, (*listeners + 1) * sizeof(Listener *) );
+ slap_listeners = ch_realloc( slap_listeners,
+ (*listeners + 1) * sizeof(Listener *) );
}
psal = sal;
sal++;
continue;
}
+
#ifdef LDAP_CONNECTIONLESS
if( l.sl_is_udp ) socktype = SOCK_DGRAM;
#endif
+
l.sl_sd = socket( (*sal)->sa_family, socktype, 0);
if ( l.sl_sd == AC_SOCKET_INVALID ) {
int err = sock_errno();
sal++;
continue;
}
+
#ifndef HAVE_WINSOCK
if ( l.sl_sd >= dtblsize ) {
Debug( LDAP_DEBUG_ANY,
continue;
}
#endif
+
#ifdef LDAP_PF_LOCAL
if ( (*sal)->sa_family == AF_LOCAL ) {
- unlink ( ((struct sockaddr_un *)*sal)->sun_path );
+ unlink( ((struct sockaddr_un *)*sal)->sun_path );
} else
#endif
{
(char *) &tmp, sizeof(tmp) );
if ( rc == AC_SOCKET_ERROR ) {
int err = sock_errno();
- Debug( LDAP_DEBUG_ANY,
- "slapd(%ld): setsockopt(SO_REUSEADDR) failed errno=%d (%s)\n",
- (long) l.sl_sd, err, sock_errstr(err) );
+ Debug( LDAP_DEBUG_ANY, "slapd(%ld): "
+ "setsockopt(SO_REUSEADDR) failed errno=%d (%s)\n",
+ (long) l.sl_sd, err, sock_errstr(err) );
}
#endif
}
/* Try to use IPv6 sockets for IPv6 only */
tmp = 1;
rc = setsockopt( l.sl_sd, IPPROTO_IPV6, IPV6_V6ONLY,
- (char *) &tmp, sizeof(tmp) );
+ (char *) &tmp, sizeof(tmp) );
if ( rc == AC_SOCKET_ERROR ) {
int err = sock_errno();
- Debug( LDAP_DEBUG_ANY,
- "slapd(%ld): setsockopt(IPV6_V6ONLY) failed errno=%d (%s)\n",
- (long) l.sl_sd, err, sock_errstr(err) );
+ Debug( LDAP_DEBUG_ANY, "slapd(%ld): "
+ "setsockopt(IPV6_V6ONLY) failed errno=%d (%s)\n",
+ (long) l.sl_sd, err, sock_errstr(err) );
}
#endif
addrlen = sizeof(struct sockaddr_in6);
break;
#endif
+
#ifdef LDAP_PF_LOCAL
case AF_LOCAL:
#ifdef LOCAL_CREDS
if (bind(l.sl_sd, *sal, addrlen)) {
err = sock_errno();
- Debug( LDAP_DEBUG_ANY, "daemon: bind(%ld) failed errno=%d (%s)\n",
- (long) l.sl_sd, err, sock_errstr(err) );
+ Debug( LDAP_DEBUG_ANY,
+ "daemon: bind(%ld) failed errno=%d (%s)\n",
+ (long) l.sl_sd, err, sock_errstr(err) );
tcp_close( l.sl_sd );
sal++;
continue;
}
- switch ( (*sal)->sa_family ) {
+ switch ( (*sal)->sa_family ) {
#ifdef LDAP_PF_LOCAL
- case AF_LOCAL: {
- char *addr = ((struct sockaddr_un *)*sal)->sun_path;
- l.sl_name.bv_len = strlen(addr) + sizeof("PATH=") - 1;
- l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len + 1 );
- snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1,
+ case AF_LOCAL: {
+ char *addr = ((struct sockaddr_un *)*sal)->sun_path;
+ l.sl_name.bv_len = strlen(addr) + sizeof("PATH=") - 1;
+ l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len + 1 );
+ snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1,
"PATH=%s", addr );
- } break;
+ } break;
#endif /* LDAP_PF_LOCAL */
- case AF_INET: {
- char *s;
+ case AF_INET: {
+ char *s;
#if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
- char addr[INET_ADDRSTRLEN];
- inet_ntop( AF_INET, &((struct sockaddr_in *)*sal)->sin_addr,
- addr, sizeof(addr) );
- s = addr;
+ char addr[INET_ADDRSTRLEN];
+ inet_ntop( AF_INET, &((struct sockaddr_in *)*sal)->sin_addr,
+ addr, sizeof(addr) );
+ s = addr;
#else
- s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr );
+ s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr );
#endif
- port = ntohs( ((struct sockaddr_in *)*sal) ->sin_port );
- l.sl_name.bv_val = ber_memalloc( sizeof("IP=255.255.255.255:65535") );
- snprintf( l.sl_name.bv_val, sizeof("IP=255.255.255.255:65535"),
- "IP=%s:%d",
- s != NULL ? s : SLAP_STRING_UNKNOWN, port );
- l.sl_name.bv_len = strlen( l.sl_name.bv_val );
- } break;
+ port = ntohs( ((struct sockaddr_in *)*sal) ->sin_port );
+ l.sl_name.bv_val =
+ ber_memalloc( sizeof("IP=255.255.255.255:65535") );
+ snprintf( l.sl_name.bv_val, sizeof("IP=255.255.255.255:65535"),
+ "IP=%s:%d",
+ s != NULL ? s : SLAP_STRING_UNKNOWN, port );
+ l.sl_name.bv_len = strlen( l.sl_name.bv_val );
+ } break;
#ifdef LDAP_PF_INET6
- case AF_INET6: {
- char addr[INET6_ADDRSTRLEN];
- inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr,
- addr, sizeof addr);
- port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
- l.sl_name.bv_len = strlen(addr) + sizeof("IP= 65535");
- l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len );
- snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=%s %d",
+ case AF_INET6: {
+ char addr[INET6_ADDRSTRLEN];
+ inet_ntop( AF_INET6, &((struct sockaddr_in6 *)*sal)->sin6_addr,
+ addr, sizeof addr);
+ port = ntohs( ((struct sockaddr_in6 *)*sal)->sin6_port );
+ l.sl_name.bv_len = strlen(addr) + sizeof("IP= 65535");
+ l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len );
+ snprintf( l.sl_name.bv_val, l.sl_name.bv_len, "IP=%s %d",
addr, port );
- l.sl_name.bv_len = strlen( l.sl_name.bv_val );
- } break;
+ l.sl_name.bv_len = strlen( l.sl_name.bv_val );
+ } break;
#endif /* LDAP_PF_INET6 */
- default:
- Debug( LDAP_DEBUG_ANY, "daemon: unsupported address family (%d)\n",
- (int) (*sal)->sa_family, 0, 0 );
- break;
- }
-
- AC_MEMCPY(&l.sl_sa, *sal, addrlen);
- ber_str2bv( url, 0, 1, &l.sl_url);
- li = ch_malloc( sizeof( Listener ) );
- *li = l;
- slap_listeners[*cur] = li;
- (*cur)++;
- sal++;
+ default:
+ Debug( LDAP_DEBUG_ANY, "daemon: unsupported address family (%d)\n",
+ (int) (*sal)->sa_family, 0, 0 );
+ break;
+ }
- } /* while ( *sal != NULL ) */
+ AC_MEMCPY(&l.sl_sa, *sal, addrlen);
+ ber_str2bv( url, 0, 1, &l.sl_url);
+ li = ch_malloc( sizeof( Listener ) );
+ *li = l;
+ slap_listeners[*cur] = li;
+ (*cur)++;
+ sal++;
+ }
slap_free_listener_addresses(psal);
- if ( l.sl_url.bv_val == NULL )
- {
+ if ( l.sl_url.bv_val == NULL ) {
Debug( LDAP_DEBUG_TRACE,
"slap_open_listener: failed on %s\n", url, 0, 0 );
return -1;
}
- Debug( LDAP_DEBUG_TRACE, "daemon: initialized %s\n",
+#ifdef LDAP_CONNECTIONLESS
+ if( l.sl_is_udp ) {
+ long id = connection_init( l.sl_sd, &l, "", "", CONN_IS_UDP,
+ (slap_ssf_t) 0, NULL );
+
+ if( id < 0 ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "slap_open_listener: connectionless init failed on %s (%d)\n",
+ url, l.sl_sd, 0 );
+ return -1;
+ }
+ l.sl_is_udp++;
+ }
+#endif
+
+ Debug( LDAP_DEBUG_TRACE, "daemon: listener initialized %s\n",
l.sl_url.bv_val, 0, 0 );
return 0;
}
Debug( LDAP_DEBUG_ARGS, "daemon_init: %s\n",
urls ? urls : "<null>", 0, 0 );
- if( (rc = sockinit()) != 0 ) {
- return rc;
- }
+ if( (rc = sockinit()) != 0 ) return rc;
#ifdef HAVE_SYSCONF
dtblsize = sysconf( _SC_OPEN_MAX );
SLAP_SOCK_SET_INIT;
- if( urls == NULL ) {
- urls = "ldap:///";
- }
+ if( urls == NULL ) urls = "ldap:///";
u = ldap_str2charray( urls, " " );
Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners opened\n",
i, 0, 0 );
+
#ifdef HAVE_SLP
if( slapd_register_slp ) {
slapd_slp_init( urls );
ldap_charray_free( u );
ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex );
+
+#ifdef HAVE_TCPD
+ ldap_pvt_thread_mutex_init( &slap_daemon.tcpd_mutex );
+#endif
+
return !i;
}
}
#endif
+#ifdef HAVE_TCPD
+ ldap_pvt_thread_mutex_destroy( &slap_daemon.tcpd_mutex );
+#endif
+
+ ldap_pvt_thread_mutex_destroy( &slap_daemon.sd_mutex );
return 0;
}
static void
close_listeners(
- int remove
-)
+ int remove )
{
int l;
for ( l = 0; slap_listeners[l] != NULL; l++ ) {
- if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) {
- if ( remove )
- slapd_remove( slap_listeners[l]->sl_sd, 0, 0 );
+ Listener *lr = slap_listeners[l];
+
+ if ( lr->sl_sd != AC_SOCKET_INVALID ) {
+ if ( remove ) slapd_remove( lr->sl_sd, 0, 0, 0 );
+
#ifdef LDAP_PF_LOCAL
- if ( slap_listeners[l]->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
- unlink( slap_listeners[l]->sl_sa.sa_un_addr.sun_path );
+ if ( lr->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
+ unlink( lr->sl_sa.sa_un_addr.sun_path );
}
#endif /* LDAP_PF_LOCAL */
- slapd_close( slap_listeners[l]->sl_sd );
+
+ slapd_close( lr->sl_sd );
}
- if ( slap_listeners[l]->sl_url.bv_val )
- ber_memfree( slap_listeners[l]->sl_url.bv_val );
- if ( slap_listeners[l]->sl_name.bv_val )
- ber_memfree( slap_listeners[l]->sl_name.bv_val );
- free ( slap_listeners[l] );
+
+ if ( lr->sl_url.bv_val ) {
+ ber_memfree( lr->sl_url.bv_val );
+ }
+
+ if ( lr->sl_name.bv_val ) {
+ ber_memfree( lr->sl_name.bv_val );
+ }
+
+ free( lr );
slap_listeners[l] = NULL;
}
}
static int
-slapd_handle_listener(
- Listener *sl
-)
+slap_listener(
+ Listener *sl )
{
Sockaddr from;
peername[0] = '\0';
#ifdef LDAP_CONNECTIONLESS
- if ( sl->sl_is_udp ) {
- /* The first time we receive a query, we set this
- * up as a "connection". It remains open for the life
- * of the slapd.
- */
- if ( sl->sl_is_udp < 2 ) {
- id = connection_init( sl->sl_sd, sl, "", "",
- CONN_IS_UDP, ssf, NULL );
- sl->sl_is_udp++;
- }
- return 1;
- }
+ if ( sl->sl_is_udp ) return 1;
#endif
# ifdef LDAP_PF_LOCAL
# endif /* LDAP_PF_LOCAL */
s = accept( sl->sl_sd, (struct sockaddr *) &from, &len );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ /* Resume the listener FD to allow concurrent-processing of
+ * additional incoming connections.
+ */
+ sl->sl_busy = 0;
+ WAKE_LISTENER(1);
+#endif
+
if ( s == AC_SOCKET_INVALID ) {
int err = sock_errno();
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
emfile++;
/* Stop listening until an existing session closes */
- sl->sl_is_mute = 1;
+ sl->sl_mute = 1;
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
}
Debug( LDAP_DEBUG_ANY,
"daemon: accept(%ld) failed errno=%d (%s)\n",
- (long) sl->sl_sd, err,
- sock_errstr(err) );
+ (long) sl->sl_sd, err, sock_errstr(err) );
ldap_pvt_thread_yield();
return 0;
}
#ifdef LDAP_DEBUG
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
-
/* newly accepted stream should not be in any of the FD SETS */
assert( SLAP_SOCK_NOT_ACTIVE( s ));
-
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
#endif
}
#endif
- Debug( LDAP_DEBUG_CONNS, "daemon: new connection on %ld\n",
- (long) s, 0, 0 );
+ Debug( LDAP_DEBUG_CONNS,
+ "daemon: listen=%ld, new connection on %ld\n",
+ (long) sl->sl_sd, (long) s, 0 );
+
switch ( from.sa_addr.sa_family ) {
# ifdef LDAP_PF_LOCAL
case AF_LOCAL:
#ifdef LDAP_PF_INET6
|| ( from.sa_addr.sa_family == AF_INET6 )
#endif
- ) {
+ )
+ {
+ dnsname = NULL;
#ifdef SLAPD_RLOOKUPS
if ( use_reverse_lookup ) {
char *herr;
dnsname = hbuf;
}
}
-#else
- dnsname = NULL;
#endif /* SLAPD_RLOOKUPS */
#ifdef HAVE_TCPD
- if ( !hosts_ctl("slapd",
- dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
- peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
- SLAP_STRING_UNKNOWN ))
{
- /* DENY ACCESS */
- Statslog( LDAP_DEBUG_STATS,
- "fd=%ld DENIED from %s (%s)\n",
- (long) s,
+ int rc;
+ ldap_pvt_thread_mutex_lock( &slap_daemon.tcpd_mutex );
+ rc = hosts_ctl("slapd",
dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
- 0, 0 );
- slapd_close(s);
- return 0;
+ SLAP_STRING_UNKNOWN );
+ ldap_pvt_thread_mutex_unlock( &slap_daemon.tcpd_mutex );
+ if ( !rc ) {
+ /* DENY ACCESS */
+ Statslog( LDAP_DEBUG_STATS,
+ "fd=%ld DENIED from %s (%s)\n",
+ (long) s,
+ dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN,
+ peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN,
+ 0, 0 );
+ slapd_close(s);
+ return 0;
+ }
}
#endif /* HAVE_TCPD */
}
id, (long) s, peername, sl->sl_name.bv_val,
0 );
- slapd_add( s, 1, NULL );
return 0;
}
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+static void*
+slap_listener_thread(
+ void* ctx,
+ void* ptr )
+{
+ int rc;
+
+ rc = slap_listener( (Listener*)ptr );
+
+ if( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_ANY,
+ "listener_thread: failed %d", rc, 0, 0 );
+ }
+
+ return (void*)NULL;
+}
+
+static int
+slap_listener_activate(
+ Listener* sl )
+{
+ int rc;
+
+ Debug( LDAP_DEBUG_TRACE, "slap_listener_activate(%d): %s\n",
+ sl->sl_sd, sl->sl_busy ? "busy" : "", 0 );
+
+ sl->sl_busy++;
+
+ rc = ldap_pvt_thread_pool_submit( &connection_pool,
+ slap_listener_thread, (void *) sl );
+
+ if( rc != 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "listener_activate(%d): submit failed (%d)\n",
+ sl->sl_sd, rc, 0 );
+ }
+ return rc;
+}
+#endif
+
static void *
slapd_daemon_task(
- void *ptr
-)
+ void *ptr )
{
int l;
- time_t last_idle_check = 0;
+ time_t last_idle_check = 0;
struct timeval idle;
int ebadf = 0;
* Don't just truncate, preserve the fractions of
* seconds to prevent sleeping for zero time.
*/
- idle.tv_sec = global_idletimeout/SLAPD_IDLE_CHECK_LIMIT;
- idle.tv_usec = global_idletimeout - idle.tv_sec * SLAPD_IDLE_CHECK_LIMIT;
+ idle.tv_sec = global_idletimeout / SLAPD_IDLE_CHECK_LIMIT;
+ idle.tv_usec = global_idletimeout - \
+ ( idle.tv_sec * SLAPD_IDLE_CHECK_LIMIT );
idle.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT;
} else {
idle.tv_sec = 0;
slapd_add( wake_sds[0], 0, NULL );
for ( l = 0; slap_listeners[l] != NULL; l++ ) {
- if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
- continue;
+ if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue;
+
#ifdef LDAP_CONNECTIONLESS
/* Since this is connectionless, the data port is the
* listening port. The listen() and accept() calls
for ( i = 0 ; i < l; i++ ) {
sa6 = slap_listeners[i]->sl_sa.sa_in6_addr;
if ( sa6.sin6_family == AF_INET6 &&
- !memcmp( &sa6.sin6_addr, &in6addr_any, sizeof(struct in6_addr) ) )
+ !memcmp( &sa6.sin6_addr, &in6addr_any,
+ sizeof(struct in6_addr) ) )
+ {
break;
+ }
}
if ( i < l ) {
/* We are already listening to in6addr_any */
Debug( LDAP_DEBUG_CONNS,
- "daemon: Attempt to listen to 0.0.0.0 failed, already listening on ::, assuming IPv4 included\n",
- 0, 0, 0 );
+ "daemon: Attempt to listen to 0.0.0.0 failed, "
+ "already listening on ::, assuming IPv4 included\n",
+ 0, 0, 0 );
slapd_close( slap_listeners[l]->sl_sd );
slap_listeners[l]->sl_sd = AC_SOCKET_INVALID;
continue;
"daemon: listen(%s, 5) failed errno=%d (%s)\n",
slap_listeners[l]->sl_url.bv_val, err,
sock_errstr(err) );
- return( (void*)-1 );
+ return (void*)-1;
}
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ /* make the listening socket non-blocking */
+ if ( ber_pvt_socket_set_nonblock( slap_listeners[l]->sl_sd, 1 ) < 0 ) {
+ Debug( LDAP_DEBUG_ANY, "slapd_daemon_task: "
+ "set nonblocking on a listening socket failed\n",
+ 0, 0, 0 );
+ slapd_shutdown = 2;
+ return (void*)-1;
+ }
+#endif
+
slapd_add( slap_listeners[l]->sl_sd, 0, slap_listeners[l] );
}
#ifdef HAVE_NT_SERVICE_MANAGER
- if ( started_event != NULL ) {
+ if ( started_event != NULL ) }
ldap_pvt_thread_cond_signal( &started_event );
}
#endif
+
+#ifdef SLAP_SEM_LOAD_CONTROL
+ /*
+ * initialize count and lazyness of a semaphore
+ */
+ (void) ldap_lazy_sem_init(
+ SLAP_MAX_WORKER_THREADS + 4 /* max workers + margin */,
+ 4 /* lazyness */ );
+#endif
+
/* initialization complete. Here comes the loop. */
while ( !slapd_shutdown ) {
}
}
#endif
-
at = 0;
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
nwriters = slap_daemon.sd_nwriters;
- SLAP_EVENT_INIT;
for ( l = 0; slap_listeners[l] != NULL; l++ ) {
- if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
- continue;
- if ( slap_listeners[l]->sl_is_mute )
- SLAP_SOCK_SET_MUTE( slap_listeners[l]->sl_sd );
- else
- if ( SLAP_SOCK_IS_MUTE( slap_listeners[l]->sl_sd ))
- SLAP_SOCK_CLR_MUTE( slap_listeners[l]->sl_sd );
+ Listener *lr = slap_listeners[l];
+
+ if ( lr->sl_sd == AC_SOCKET_INVALID ) continue;
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ if ( lr->sl_mute || lr->sl_busy )
+#else
+ if ( lr->sl_mute )
+#endif
+ {
+ SLAP_SOCK_CLR_READ( lr->sl_sd );
+ } else {
+ SLAP_SOCK_SET_READ( lr->sl_sd );
+ }
}
+ SLAP_EVENT_INIT;
+
nfds = SLAP_EVENT_MAX;
- if ( global_idletimeout && slap_daemon.sd_nactives )
- at = 1;
+ if ( global_idletimeout && slap_daemon.sd_nactives ) at = 1;
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
&& ( tv.tv_sec || tv.tv_usec )
#endif
)
+ {
tvp = &tv;
- else
+ } else {
tvp = NULL;
+ }
ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
if ( cat && cat->tv_sec ) {
time_t diff = difftime( cat->tv_sec, now );
- if ( diff == 0 )
- diff = tdelta;
+ if ( diff == 0 ) diff = tdelta;
if ( tvp == NULL || diff < tv.tv_sec ) {
tv.tv_sec = diff;
tv.tv_usec = 0;
}
for ( l = 0; slap_listeners[l] != NULL; l++ ) {
- if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ||
- slap_listeners[l]->sl_is_mute )
+ Listener *lr = slap_listeners[l];
+
+ if ( lr->sl_sd == AC_SOCKET_INVALID ) {
continue;
+ }
+
+ if ( lr->sl_mute ) {
+ Debug( LDAP_DEBUG_CONNS,
+ "daemon: select: listen=%d muted\n",
+ lr->sl_sd, 0, 0 );
+ continue;
+ }
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ if ( lr->sl_busy ) {
+ Debug( LDAP_DEBUG_CONNS,
+ "daemon: select: listen=%d busy\n",
+ lr->sl_sd, 0, 0 );
+ continue;
+ }
+#endif
Debug( LDAP_DEBUG_CONNS,
"daemon: select: listen=%d active_threads=%d tvp=%s\n",
- slap_listeners[l]->sl_sd, at,
- tvp == NULL ? "NULL" : "zero" );
+ lr->sl_sd, at, tvp == NULL ? "NULL" : "zero" );
}
- switch(ns = SLAP_EVENT_WAIT(tvp))
- {
+ switch(ns = SLAP_EVENT_WAIT(tvp)) {
case -1: { /* failure - try again */
int err = sock_errno();
if( slapd_shutdown ) continue;
ebadf = 0;
- Debug( LDAP_DEBUG_CONNS, "daemon: activity on %d descriptors\n",
- ns, 0, 0 );
+ Debug( LDAP_DEBUG_CONNS,
+ "daemon: activity on %d descriptor%s\n",
+ ns, ns != 1 ? "s" : "", 0 );
/* FALL THRU */
}
#if SLAP_EVENTS_ARE_INDEXED
if ( SLAP_EVENT_IS_READ( wake_sds[0] )) {
- char c[BUFSIZ];
- tcp_read( wake_sds[0], c, sizeof(c) );
- waking = 0;
- ns--;
SLAP_EVENT_CLR_READ( wake_sds[0] );
+ ns--;
+ {
+ char c[BUFSIZ];
+ tcp_read( wake_sds[0], c, sizeof(c) );
+ }
+ Debug( LDAP_DEBUG_CONNS, "daemon: waked\n", 0, 0, 0 );
+ waking = 0;
continue;
}
int rc;
if ( ns <= 0 ) break;
-
- if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
- continue;
-
- if ( !SLAP_EVENT_IS_READ( slap_listeners[l]->sl_sd ))
- continue;
-
- rc = slapd_handle_listener(slap_listeners[l]);
-
+ if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue;
#ifdef LDAP_CONNECTIONLESS
- /* This is a UDP session, let the data loop process it */
- if ( rc ) continue;
+ if ( slap_listeners[l]->sl_is_udp ) continue;
#endif
-
- ns--;
-
- /* Don't need to look at this in the data loops */
+ if ( !SLAP_EVENT_IS_READ( slap_listeners[l]->sl_sd )) continue;
+
+ /* clear events */
SLAP_EVENT_CLR_READ( slap_listeners[l]->sl_sd );
SLAP_EVENT_CLR_WRITE( slap_listeners[l]->sl_sd );
+ ns--;
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ rc = slap_listener_activate(slap_listeners[l]);
+#else
+ rc = slap_listener(slap_listeners[l]);
+#endif
}
/* bypass the following tests if no descriptors left */
/* loop through the writers */
- for ( i = 0; nwfds > 0; i++ )
- {
+ for ( i = 0; nwfds > 0; i++ ) {
ber_socket_t wd;
#ifdef HAVE_WINSOCK
wd = writefds.fd_array[i];
#else
- if( ! SLAP_EVENT_IS_WRITE( i ) ) {
- continue;
- }
+ if( ! SLAP_EVENT_IS_WRITE( i ) ) continue;
wd = i;
#endif
+
+ SLAP_EVENT_CLR_WRITE( wd );
nwfds--;
Debug( LDAP_DEBUG_CONNS,
"daemon: write active on %d\n",
wd, 0, 0 );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ connection_write_activate( wd );
+#else
/*
* NOTE: it is possible that the connection was closed
* and that the stream is now inactive.
- * connection_write() must valid the stream is still
+ * connection_write() must validate the stream is still
* active.
*/
-
if ( connection_write( wd ) < 0 ) {
if ( SLAP_EVENT_IS_READ( wd )) {
SLAP_EVENT_CLR_READ( (unsigned) wd );
}
slapd_close( wd );
}
- SLAP_EVENT_CLR_WRITE( wd );
+#endif
}
- for ( i = 0; nrfds > 0; i++ )
- {
+ for ( i = 0; nrfds > 0; i++ ) {
ber_socket_t rd;
#ifdef HAVE_WINSOCK
rd = readfds.fd_array[i];
#else
- if( ! SLAP_EVENT_IS_READ( i ) ) {
- continue;
- }
+ if( ! SLAP_EVENT_IS_READ( i ) ) continue;
rd = i;
#endif
+ SLAP_EVENT_CLR_READ( rd );
nrfds--;
Debug ( LDAP_DEBUG_CONNS,
* active.
*/
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ connection_read_activate( rd );
+#else
if ( connection_read( rd ) < 0 ) {
slapd_close( rd );
}
+#endif
}
#else /* !SLAP_EVENTS_ARE_INDEXED */
/* FIXME */
* an event, so we could use pointers to the listener structure
* instead of just the file descriptor. For /dev/poll we have to
* search the listeners array for a matching descriptor.
+ *
+ * We now handle wake events when we see them; they are not given
+ * higher priority.
*/
- /* if waking is set and we woke up, we'll read whatever
- * we can.
- */
- if ( waking ) {
- char c[BUFSIZ];
- tcp_read( wake_sds[0], c, sizeof(c) );
- waking = 0;
- ns--;
- continue;
- }
-
#ifdef LDAP_DEBUG
Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
for (i=0; i<ns; i++) {
int r, w;
+ /* Don't log listener events */
if ( SLAP_EVENT_IS_LISTENER(i)
#ifdef LDAP_CONNECTIONLESS
- && !((SLAP_EVENT_LISTENER(i))->sl_is_udp)
+ && !((SLAP_EVENT_LISTENER(i))->sl_is_udp)
#endif
- ) continue;
+ )
+ {
+ continue;
+ }
/* Don't log internal wake events */
- if ( SLAP_EVENT_FD( i ) == wake_sds[0] )
- continue;
+ if ( SLAP_EVENT_FD( i ) == wake_sds[0] ) continue;
r = SLAP_EVENT_IS_READ( i );
w = SLAP_EVENT_IS_WRITE( i );
r ? "r" : "", w ? "w" : "" );
}
}
+ Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
#endif
+
for (i=0; i<ns; i++) {
int rc = 1, fd;
if ( SLAP_EVENT_IS_LISTENER(i) ) {
- rc = slapd_handle_listener( SLAP_EVENT_LISTENER( i ));
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ rc = slap_listener_activate( SLAP_EVENT_LISTENER( i ));
+#else
+ rc = slap_listener( SLAP_EVENT_LISTENER( i ));
+#endif
}
+
/* If we found a regular listener, rc is now zero, and we
* can skip the data portion. But if it was a UDP listener
* then rc is still 1, and we want to handle the data.
if ( rc ) {
fd = SLAP_EVENT_FD( i );
- /* Ignore wake events, they were handled above */
- if ( fd == wake_sds[0] )
- continue;
+ /* Handle wake events */
+ if ( fd == wake_sds[0] ) {
+ char c[BUFSIZ];
+ tcp_read( wake_sds[0], c, sizeof(c) );
+ waking = 0;
+ break;
+ }
if( SLAP_EVENT_IS_WRITE( i ) ) {
Debug( LDAP_DEBUG_CONNS,
"daemon: write active on %d\n",
fd, 0, 0 );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ connection_write_activate( fd );
+#else
/*
* NOTE: it is possible that the connection was closed
* and that the stream is now inactive.
* connection_write() must valid the stream is still
* active.
*/
-
if ( connection_write( fd ) < 0 ) {
slapd_close( fd );
continue;
}
+#endif
}
if( SLAP_EVENT_IS_READ( i ) ) {
Debug( LDAP_DEBUG_CONNS,
"daemon: read active on %d\n",
fd, 0, 0 );
+
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ connection_read_activate( fd );
+#else
/*
* NOTE: it is possible that the connection was closed
* and that the stream is now inactive.
* connection_read() must valid the stream is still
* active.
*/
-
- if ( connection_read( fd ) < 0 ) {
- slapd_close( fd );
- }
+ if ( connection_read( fd ) < 0 ) slapd_close( fd );
+#endif
}
}
}
0, 0, 0 );
}
- if( slapd_gentle_shutdown != 2 ) {
- close_listeners ( 0 );
- }
+ if( slapd_gentle_shutdown != 2 ) close_listeners ( 0 );
if( !slapd_gentle_shutdown ) {
slapd_abrupt_shutdown = 1;
/* The WinSock DLL is acceptable. Proceed. */
#elif defined( HAVE_WINSOCK )
WSADATA wsaData;
- if ( WSAStartup( 0x0101, &wsaData ) != 0 ) {
- return -1;
- }
+ if ( WSAStartup( 0x0101, &wsaData ) != 0 ) return -1;
#endif
+
return 0;
}
*/
#if HAVE_NT_SERVICE_MANAGER && SIGBREAK
- if (is_NT_Service && sig == SIGBREAK)
- ;
- else
+ if (is_NT_Service && sig == SIGBREAK) {
+ /* empty */;
+ } else
#endif
#ifdef SIGHUP
- if (sig == SIGHUP && global_gentlehup && slapd_gentle_shutdown == 0)
+ if (sig == SIGHUP && global_gentlehup && slapd_gentle_shutdown == 0) {
slapd_gentle_shutdown = 1;
- else
+ } else
#endif
- slapd_shutdown = 1;
+ {
+ slapd_shutdown = 1;
+ }
+
WAKE_LISTENER(1);
/* reinstall self */
return slap_listeners;
}
-void slap_wake_listener()
-{
+void slap_wake_listener() {
WAKE_LISTENER(1);
}
rs->sr_err = frontendDB->be_delete( op, rs );
cleanup:;
- slap_graduate_commit_csn( op );
-
op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
return rs->sr_err;
op->o_bd = op_be;
- if ( !repl_user ) {
- struct berval csn = BER_BVNULL;
- char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
- slap_get_csn( op, csnbuf, sizeof(csnbuf), &csn, 1 );
- }
-
#ifdef SLAPD_MULTIMASTER
if ( !op->o_bd->be_update_ndn.bv_len || !repl_user )
#endif
int
load_extop(
- struct berval *ext_oid,
+ const struct berval *ext_oid,
slap_mask_t ext_flags,
SLAP_EXTOP_MAIN_FN *ext_main )
{
*/
ldap_pvt_thread_pool_t connection_pool;
int connection_pool_max = SLAP_MAX_WORKER_THREADS;
+int slap_tool_thread_max = 1;
#ifndef HAVE_GMTIME_R
ldap_pvt_thread_mutex_t gmtime_mutex;
#endif
switch ( slapMode & SLAP_MODE ) {
case SLAP_SERVER_MODE:
- ldap_pvt_thread_pool_init( &connection_pool,
- connection_pool_max, 0);
/* FALLTHRU */
case SLAP_TOOL_MODE:
slap_name = name;
+ ldap_pvt_thread_pool_init( &connection_pool,
+ connection_pool_max, 0);
+
ldap_pvt_thread_mutex_init( &entry2str_mutex );
ldap_pvt_thread_mutex_init( &replog_mutex );
#endif
while ( (i = getopt( argc, argv,
- "c:d:f:F:h:n:o:s:StT:V"
+ "c:d:f:F:h:n:o:s:tT:V"
#if LDAP_PF_INET6
"46"
#endif
ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_CTX, NULL );
rc = ldap_pvt_tls_init_def_ctx();
- if( rc == 0) {
+ if( rc == 0 ) {
ldap_pvt_tls_get_option( NULL, LDAP_OPT_X_TLS_CTX, &slap_tls_ctx );
/* Restore previous ctx */
ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_CTX, def_ctx );
*/
time( &starttime );
- if ( slap_startup( NULL ) != 0 ) {
+ if ( slap_startup( NULL ) != 0 ) {
rc = 1;
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 21 );
goto shutdown;
Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 );
-
if ( slapd_pid_file != NULL ) {
FILE *fp = fopen( slapd_pid_file, "w" );
- if( fp != NULL ) {
- fprintf( fp, "%d\n", (int) getpid() );
- fclose( fp );
+ if ( fp == NULL ) {
+ int save_errno = errno;
+
+ Debug( LDAP_DEBUG_ANY, "unable to open pid file "
+ "\"%s\": %d (%s)\n",
+ slapd_pid_file,
+ save_errno, strerror( save_errno ) );
- } else {
- free(slapd_pid_file);
+ free( slapd_pid_file );
slapd_pid_file = NULL;
+
+ rc = 1;
+ goto shutdown;
}
+
+ fprintf( fp, "%d\n", (int) getpid() );
+ fclose( fp );
}
if ( slapd_args_file != NULL ) {
FILE *fp = fopen( slapd_args_file, "w" );
- if( fp != NULL ) {
- for ( i = 0; i < g_argc; i++ ) {
- fprintf( fp, "%s ", g_argv[i] );
- }
- fprintf( fp, "\n" );
- fclose( fp );
- } else {
- free(slapd_args_file);
+ if ( fp == NULL ) {
+ int save_errno = errno;
+
+ Debug( LDAP_DEBUG_ANY, "unable to open args file "
+ "\"%s\": %d (%s)\n",
+ slapd_args_file,
+ save_errno, strerror( save_errno ) );
+
+ free( slapd_args_file );
slapd_args_file = NULL;
+
+ rc = 1;
+ goto shutdown;
+ }
+
+ for ( i = 0; i < g_argc; i++ ) {
+ fprintf( fp, "%s ", g_argv[i] );
}
+ fprintf( fp, "\n" );
+ fclose( fp );
}
#ifdef HAVE_NT_EVENT_LOG
rs->sr_err = frontendDB->be_modify( op, rs );
cleanup:
- slap_graduate_commit_csn( op );
-
op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
if ( op->orm_modlist != NULL ) slap_mods_free( op->orm_modlist, 1 );
#endif
int manageDSAit;
Modifications *modlist = op->orm_modlist;
- Modifications **modtail = &modlist;
int increment = op->orm_increment;
BackendDB *op_be;
char textbuf[ SLAP_TEXT_BUFLEN ];
}
}
- if ( !repl_user ) {
- for( modtail = &modlist;
- *modtail != NULL;
- modtail = &(*modtail)->sml_next )
- {
- /* empty */
- }
-
- rs->sr_err = slap_mods_opattrs( op, modlist, modtail,
- &rs->sr_text, textbuf, textlen, 1 );
- if( rs->sr_err != LDAP_SUCCESS ) {
- send_ldap_result( op, rs );
- goto cleanup;
- }
- }
-
op->orm_modlist = modlist;
#ifdef SLAPD_MULTIMASTER
if ( !repl_user )
#endif
}
-int slap_mods_opattrs(
+/* modify only calls this for non-replicas. modrdn always calls.
+ */
+void slap_mods_opattrs(
Operation *op,
Modifications *mods,
- Modifications **modtail,
- const char **text,
- char *textbuf, size_t textlen,
int manage_ctxcsn )
{
- struct berval name, timestamp, csn;
+ struct berval name, timestamp, csn = BER_BVNULL;
struct berval nname;
char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
- Modifications *mod;
-
- int mop = op->o_tag == LDAP_REQ_ADD
- ? LDAP_MOD_ADD : LDAP_MOD_REPLACE;
-
- assert( modtail != NULL );
- assert( *modtail == NULL );
+ Modifications *mod, **modtail, *modlast;
if ( SLAP_LASTMOD( op->o_bd ) ) {
- time_t now = slap_get_time();
-
- slap_get_csn( op, csnbuf, sizeof(csnbuf), &csn, manage_ctxcsn );
-
+ char *ptr;
timestamp.bv_val = timebuf;
- timestamp.bv_len = sizeof(timebuf);
+ if ( BER_BVISEMPTY( &op->o_csn )) {
+ csn.bv_val = csnbuf;
+ csn.bv_len = sizeof( csnbuf );
+ slap_get_csn( op, &csn, manage_ctxcsn );
+ } else {
+ csn = op->o_csn;
+ }
+ ptr = strchr( csn.bv_val, '#' );
+ if ( ptr ) {
+ timestamp.bv_len = ptr - csn.bv_val;
+ if ( timestamp.bv_len >= sizeof( timebuf ))
+ timestamp.bv_len = sizeof( timebuf ) - 1;
+ strncpy( timebuf, csn.bv_val, timestamp.bv_len );
+ timebuf[timestamp.bv_len] = '\0';
+ } else {
+ time_t now = slap_get_time();
- slap_timestamp( &now, ×tamp );
+ timestamp.bv_len = sizeof(timebuf);
+
+ slap_timestamp( &now, ×tamp );
+ }
if ( BER_BVISEMPTY( &op->o_dn ) ) {
BER_BVSTR( &name, SLAPD_ANONYMOUS );
name = op->o_dn;
nname = op->o_ndn;
}
- }
-
- if ( op->o_tag == LDAP_REQ_ADD ) {
- struct berval tmpval;
-
- mod = *modtail;
- if ( get_manageDIT( op ) ) {
- for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
- if ( mod->sml_desc == slap_schema.si_ad_structuralObjectClass ) {
- break;
- }
- }
-
- }
-
- if ( mod == *modtail ) {
- int rc = mods_structural_class( mods, &tmpval,
- text, textbuf, textlen );
- if( rc != LDAP_SUCCESS ) return rc;
- mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
- mod->sml_op = mop;
- mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_next = NULL;
- BER_BVZERO( &mod->sml_type );
- mod->sml_desc = slap_schema.si_ad_structuralObjectClass;
- mod->sml_values =
- (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
- ber_dupbv( &mod->sml_values[0], &tmpval );
- BER_BVZERO( &mod->sml_values[1] );
- assert( !BER_BVISNULL( &mod->sml_values[0] ) );
- mod->sml_nvalues =
- (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
- ber_dupbv( &mod->sml_nvalues[0], &tmpval );
- BER_BVZERO( &mod->sml_nvalues[1] );
- assert( !BER_BVISNULL( &mod->sml_nvalues[0] ) );
- *modtail = mod;
- modtail = &mod->sml_next;
- }
-
- if ( SLAP_LASTMOD( op->o_bd ) ) {
- mod = *modtail;
- if ( get_manageDIT( op ) ) {
- for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
- if ( mod->sml_desc == slap_schema.si_ad_entryUUID ) {
- break;
- }
- }
- }
-
- if ( mod == *modtail ) {
- char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
-
- tmpval.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
- tmpval.bv_val = uuidbuf;
-
- mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
- mod->sml_op = mop;
- mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_next = NULL;
- BER_BVZERO( &mod->sml_type );
- mod->sml_desc = slap_schema.si_ad_entryUUID;
- mod->sml_values =
- (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
- ber_dupbv( &mod->sml_values[0], &tmpval );
- BER_BVZERO( &mod->sml_values[1] );
- assert( !BER_BVISNULL( &mod->sml_values[0] ) );
- mod->sml_nvalues =
- (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
- (*mod->sml_desc->ad_type->sat_equality->smr_normalize)(
- SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
- mod->sml_desc->ad_type->sat_syntax,
- mod->sml_desc->ad_type->sat_equality,
- mod->sml_values, mod->sml_nvalues, NULL );
- BER_BVZERO( &mod->sml_nvalues[1] );
- *modtail = mod;
- modtail = &mod->sml_next;
- }
-
- mod = *modtail;
- if ( get_manageDIT( op ) ) {
- for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
- if ( mod->sml_desc == slap_schema.si_ad_creatorsName ) {
- break;
- }
- }
- }
-
- if ( mod == *modtail ) {
- mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
- mod->sml_op = mop;
- mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_next = NULL;
- BER_BVZERO( &mod->sml_type );
- mod->sml_desc = slap_schema.si_ad_creatorsName;
- mod->sml_values =
- (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
- ber_dupbv( &mod->sml_values[0], &name );
- BER_BVZERO( &mod->sml_values[1] );
- assert( !BER_BVISNULL( &mod->sml_values[0] ) );
- mod->sml_nvalues =
- (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
- ber_dupbv( &mod->sml_nvalues[0], &nname );
- BER_BVZERO( &mod->sml_nvalues[1] );
- assert( !BER_BVISNULL( &mod->sml_nvalues[0] ) );
- *modtail = mod;
- modtail = &mod->sml_next;
- }
-
- mod = *modtail;
- if ( get_manageDIT( op ) ) {
- for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
- if ( mod->sml_desc == slap_schema.si_ad_createTimestamp ) {
- break;
- }
- }
- }
-
- if ( mod == *modtail ) {
- mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
- mod->sml_op = mop;
- mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_next = NULL;
- BER_BVZERO( &mod->sml_type );
- mod->sml_desc = slap_schema.si_ad_createTimestamp;
- mod->sml_values =
- (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
- ber_dupbv( &mod->sml_values[0], ×tamp );
- BER_BVZERO( &mod->sml_values[1] );
- assert( !BER_BVISNULL( &mod->sml_values[0] ) );
- mod->sml_nvalues = NULL;
- *modtail = mod;
- modtail = &mod->sml_next;
- }
- }
- }
+ for ( mod = mods; mod->sml_next; mod = mod->sml_next )
+ ;
+ modtail = &mod->sml_next;
- if ( SLAP_LASTMOD( op->o_bd ) ) {
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
- mod->sml_op = mop;
+ mod->sml_op = LDAP_MOD_REPLACE;
mod->sml_flags = SLAP_MOD_INTERNAL;
mod->sml_next = NULL;
BER_BVZERO( &mod->sml_type );
assert( !BER_BVISNULL( &mod->sml_values[0] ) );
mod->sml_nvalues = NULL;
*modtail = mod;
+ modlast = mod;
modtail = &mod->sml_next;
- mod = *modtail;
if ( get_manageDIT( op ) ) {
- for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
+ for ( mod = mods; mod != modlast; mod = mod->sml_next ) {
if ( mod->sml_desc == slap_schema.si_ad_modifiersName ) {
break;
}
}
}
- if ( mod == *modtail ) {
+ if ( mod->sml_desc != slap_schema.si_ad_modifiersName ) {
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
- mod->sml_op = mop;
+ mod->sml_op = LDAP_MOD_REPLACE;
mod->sml_flags = SLAP_MOD_INTERNAL;
mod->sml_next = NULL;
BER_BVZERO( &mod->sml_type );
modtail = &mod->sml_next;
}
- mod = *modtail;
if ( get_manageDIT( op ) ) {
- for ( mod = mods; mod != *modtail; mod = mod->sml_next ) {
+ for ( mod = mods; mod != modlast; mod = mod->sml_next ) {
if ( mod->sml_desc == slap_schema.si_ad_modifyTimestamp ) {
break;
}
}
}
- if ( mod == *modtail ) {
+ if ( mod->sml_desc != slap_schema.si_ad_modifyTimestamp ) {
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
- mod->sml_op = mop;
+ mod->sml_op = LDAP_MOD_REPLACE;
mod->sml_flags = SLAP_MOD_INTERNAL;
mod->sml_next = NULL;
BER_BVZERO( &mod->sml_type );
modtail = &mod->sml_next;
}
}
-
- *modtail = NULL;
- return LDAP_SUCCESS;
}
rs->sr_err = frontendDB->be_modrdn( op, rs );
cleanup:
- slap_graduate_commit_csn( op );
-
op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
Modifications **pmod )
{
Modifications *mod = NULL;
- Modifications **modtail = &mod;
int a_cnt, d_cnt;
int repl_user;
done:
if ( rs->sr_err == LDAP_SUCCESS && !repl_user ) {
- char textbuf[ SLAP_TEXT_BUFLEN ];
- size_t textlen = sizeof textbuf;
-
- for( modtail = &mod;
- *modtail != NULL;
- modtail = &(*modtail)->sml_next )
- {
- /* empty */
- }
-
- rs->sr_err = slap_mods_opattrs( op, mod, modtail,
- &rs->sr_text, textbuf, textlen, 1 );
+ slap_mods_opattrs( op, mod, 1 );
}
/* LDAP v2 supporting correct attribute handling. */
}
if ( permissive ) {
- for ( i = 0; !BER_BVISNULL( &mod->sm_values[i] ); i++ ) /* count 'em */;
- pmod.sm_values = (BerVarray)ch_malloc( (i + 1)*sizeof( struct berval ) );
+ for ( i = 0; !BER_BVISNULL( &mod->sm_values[i] ); i++ ) {
+ /* EMPTY -- just counting 'em */;
+ }
+
+ pmod.sm_values = (BerVarray)ch_malloc(
+ (i + 1) * sizeof( struct berval ));
if ( pmod.sm_nvalues != NULL ) {
pmod.sm_nvalues = (BerVarray)ch_malloc(
- (i + 1)*sizeof( struct berval ) );
+ (i + 1) * sizeof( struct berval ));
}
}
ldap_pvt_thread_mutex_unlock( &slap_op_mutex );
}
+void
+slap_op_time(time_t *t, int *nop)
+{
+ *t = slap_get_time();
+ ldap_pvt_thread_mutex_lock( &slap_op_mutex );
+ if ( *t == last_time ) {
+ *nop = ++last_incr;
+ } else {
+ last_time = *t;
+ last_incr = 0;
+ *nop = 0;
+ }
+ ldap_pvt_thread_mutex_unlock( &slap_op_mutex );
+}
+
Operation *
slap_op_alloc(
BerElement *ber,
op->o_msgid = msgid;
op->o_tag = tag;
- op->o_time = slap_get_time();
- if ( op->o_time == last_time ) {
- op->o_tincr = ++last_incr;
- } else {
- last_time = op->o_time;
- last_incr = 0; /* o_tincr is alredy zero */
- }
+ slap_op_time( &op->o_time, &op->o_tincr );
op->o_opid = id;
op->o_res_ber = NULL;
int li_cycle;
struct re_s *li_task;
int li_success;
+ ldap_pvt_thread_mutex_t li_op_mutex;
+ ldap_pvt_thread_mutex_t li_log_mutex;
} log_info;
static ConfigDriver log_cf_gen;
LOG_EN__COUNT
};
-static ObjectClass *log_ocs[LOG_EN__COUNT];
+static ObjectClass *log_ocs[LOG_EN__COUNT], *log_container;
#define LOG_SCHEMA_ROOT "1.3.6.1.4.1.4203.666.11.5"
*ad_reqNewSuperior, *ad_reqDeleteOldRDN, *ad_reqMod,
*ad_reqScope, *ad_reqFilter, *ad_reqAttr, *ad_reqEntries,
*ad_reqSizeLimit, *ad_reqTimeLimit, *ad_reqAttrsOnly, *ad_reqData,
- *ad_reqId, *ad_reqMessage;
-#if 0
-static AttributeDescription *ad_oldest;
-#endif
+ *ad_reqId, *ad_reqMessage, *ad_reqVersion, *ad_reqDerefAliases,
+ *ad_reqReferral, *ad_reqOld;
static struct {
char *at;
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString "
"SINGLE-VALUE )", &ad_reqSession },
- { "( " LOG_SCHEMA_AT ".6 NAME 'reqResult' "
- "DESC 'Result code of request' "
- "EQUALITY integerMatch "
- "SYNTAX OMsInteger "
- "SINGLE-VALUE )", &ad_reqResult },
- { "( " LOG_SCHEMA_AT ".7 NAME 'reqAuthzID' "
+ { "( " LOG_SCHEMA_AT ".6 NAME 'reqAuthzID' "
"DESC 'Authorization ID of requestor' "
"EQUALITY distinguishedNameMatch "
"SYNTAX OMsDN "
"SINGLE-VALUE )", &ad_reqAuthzID },
- { "( " LOG_SCHEMA_AT ".8 NAME 'reqControls' "
+ { "( " LOG_SCHEMA_AT ".7 NAME 'reqResult' "
+ "DESC 'Result code of request' "
+ "EQUALITY integerMatch "
+ "ORDERING integerOrderingMatch "
+ "SYNTAX OMsInteger "
+ "SINGLE-VALUE )", &ad_reqResult },
+ { "( " LOG_SCHEMA_AT ".8 NAME 'reqMessage' "
+ "DESC 'Error text of request' "
+ "EQUALITY caseIgnoreMatch "
+ "SUBSTR caseIgnoreSubstringsMatch "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )", &ad_reqMessage },
+ { "( " LOG_SCHEMA_AT ".9 NAME 'reqReferral' "
+ "DESC 'Referrals returned for request' "
+ "SUP labeledURI )", &ad_reqReferral },
+ { "( " LOG_SCHEMA_AT ".10 NAME 'reqControls' "
"DESC 'Request controls' "
"SYNTAX OMsOctetString )", &ad_reqControls },
- { "( " LOG_SCHEMA_AT ".9 NAME 'reqRespControls' "
+ { "( " LOG_SCHEMA_AT ".11 NAME 'reqRespControls' "
"DESC 'Response controls of request' "
"SYNTAX OMsOctetString )", &ad_reqRespControls },
- { "( " LOG_SCHEMA_AT ".10 NAME 'reqMethod' "
+ { "( " LOG_SCHEMA_AT ".12 NAME 'reqId' "
+ "DESC 'ID of Request to Abandon' "
+ "EQUALITY integerMatch "
+ "ORDERING integerOrderingMatch "
+ "SYNTAX OMsInteger "
+ "SINGLE-VALUE )", &ad_reqId },
+ { "( " LOG_SCHEMA_AT ".13 NAME 'reqVersion' "
+ "DESC 'Protocol version of Bind request' "
+ "EQUALITY integerMatch "
+ "ORDERING integerOrderingMatch "
+ "SYNTAX OMsInteger "
+ "SINGLE-VALUE )", &ad_reqVersion },
+ { "( " LOG_SCHEMA_AT ".14 NAME 'reqMethod' "
"DESC 'Bind method of request' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString "
"SINGLE-VALUE )", &ad_reqMethod },
- { "( " LOG_SCHEMA_AT ".11 NAME 'reqAssertion' "
+ { "( " LOG_SCHEMA_AT ".15 NAME 'reqAssertion' "
"DESC 'Compare Assertion of request' "
"SYNTAX OMsDirectoryString "
"SINGLE-VALUE )", &ad_reqAssertion },
- { "( " LOG_SCHEMA_AT ".12 NAME 'reqNewRDN' "
+ { "( " LOG_SCHEMA_AT ".16 NAME 'reqMod' "
+ "DESC 'Modifications of request' "
+ "EQUALITY octetStringMatch "
+ "SUBSTR octetStringSubstringsMatch "
+ "SYNTAX OMsOctetString )", &ad_reqMod },
+ { "( " LOG_SCHEMA_AT ".17 NAME 'reqOld' "
+ "DESC 'Old values of entry before request completed' "
+ "EQUALITY octetStringMatch "
+ "SUBSTR octetStringSubstringsMatch "
+ "SYNTAX OMsOctetString )", &ad_reqOld },
+ { "( " LOG_SCHEMA_AT ".18 NAME 'reqNewRDN' "
"DESC 'New RDN of request' "
"EQUALITY distinguishedNameMatch "
"SYNTAX OMsDN "
"SINGLE-VALUE )", &ad_reqNewRDN },
- { "( " LOG_SCHEMA_AT ".13 NAME 'reqNewSuperior' "
+ { "( " LOG_SCHEMA_AT ".19 NAME 'reqDeleteOldRDN' "
+ "DESC 'Delete old RDN' "
+ "EQUALITY booleanMatch "
+ "SYNTAX OMsBoolean "
+ "SINGLE-VALUE )", &ad_reqDeleteOldRDN },
+ { "( " LOG_SCHEMA_AT ".20 NAME 'reqNewSuperior' "
"DESC 'New superior DN of request' "
"EQUALITY distinguishedNameMatch "
"SYNTAX OMsDN "
"SINGLE-VALUE )", &ad_reqNewSuperior },
- { "( " LOG_SCHEMA_AT ".14 NAME 'reqDeleteOldRDN' "
- "DESC 'Delete old RDN' "
- "SYNTAX OMsBoolean "
- "SINGLE-VALUE )", &ad_reqDeleteOldRDN },
- { "( " LOG_SCHEMA_AT ".15 NAME 'reqMod' "
- "DESC 'Modifications of request' "
- "SYNTAX OMsDirectoryString "
- "EQUALITY caseIgnoreMatch "
- "SUBSTR caseIgnoreSubstringsMatch )", &ad_reqMod },
- { "( " LOG_SCHEMA_AT ".16 NAME 'reqScope' "
+ { "( " LOG_SCHEMA_AT ".21 NAME 'reqScope' "
"DESC 'Scope of request' "
+ "EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString "
"SINGLE-VALUE )", &ad_reqScope },
- { "( " LOG_SCHEMA_AT ".17 NAME 'reqFilter' "
+ { "( " LOG_SCHEMA_AT ".22 NAME 'reqDerefAliases' "
+ "DESC 'Disposition of Aliases in request' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )", &ad_reqDerefAliases },
+ { "( " LOG_SCHEMA_AT ".23 NAME 'reqAttrsOnly' "
+ "DESC 'Attributes and values of request' "
+ "EQUALITY booleanMatch "
+ "SYNTAX OMsBoolean "
+ "SINGLE-VALUE )", &ad_reqAttrsOnly },
+ { "( " LOG_SCHEMA_AT ".24 NAME 'reqFilter' "
"DESC 'Filter of request' "
+ "EQUALITY caseIgnoreMatch "
+ "SUBSTR caseIgnoreSubstringsMatch "
"SYNTAX OMsDirectoryString "
"SINGLE-VALUE )", &ad_reqFilter },
- { "( " LOG_SCHEMA_AT ".18 NAME 'reqAttr' "
+ { "( " LOG_SCHEMA_AT ".25 NAME 'reqAttr' "
"DESC 'Attributes of request' "
+ "EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString )", &ad_reqAttr },
- { "( " LOG_SCHEMA_AT ".19 NAME 'reqEntries' "
- "DESC 'Number of entries returned' "
- "SYNTAX OMsInteger "
- "SINGLE-VALUE )", &ad_reqEntries },
- { "( " LOG_SCHEMA_AT ".20 NAME 'reqSizeLimit' "
+ { "( " LOG_SCHEMA_AT ".26 NAME 'reqSizeLimit' "
"DESC 'Size limit of request' "
+ "EQUALITY integerMatch "
+ "ORDERING integerOrderingMatch "
"SYNTAX OMsInteger "
"SINGLE-VALUE )", &ad_reqSizeLimit },
- { "( " LOG_SCHEMA_AT ".21 NAME 'reqTimeLimit' "
+ { "( " LOG_SCHEMA_AT ".27 NAME 'reqTimeLimit' "
"DESC 'Time limit of request' "
+ "EQUALITY integerMatch "
+ "ORDERING integerOrderingMatch "
"SYNTAX OMsInteger "
"SINGLE-VALUE )", &ad_reqTimeLimit },
- { "( " LOG_SCHEMA_AT ".22 NAME 'reqAttrsOnly' "
- "DESC 'Attributes and values of request' "
- "SYNTAX OMsBoolean "
- "SINGLE-VALUE )", &ad_reqAttrsOnly },
- { "( " LOG_SCHEMA_AT ".23 NAME 'reqData' "
+ { "( " LOG_SCHEMA_AT ".28 NAME 'reqEntries' "
+ "DESC 'Number of entries returned' "
+ "EQUALITY integerMatch "
+ "ORDERING integerOrderingMatch "
+ "SYNTAX OMsInteger "
+ "SINGLE-VALUE )", &ad_reqEntries },
+ { "( " LOG_SCHEMA_AT ".29 NAME 'reqData' "
"DESC 'Data of extended request' "
+ "EQUALITY octetStringMatch "
+ "SUBSTR octetStringSubstringsMatch "
"SYNTAX OMsOctetString "
"SINGLE-VALUE )", &ad_reqData },
- { "( " LOG_SCHEMA_AT ".24 NAME 'reqId' "
- "DESC 'ID of Request to Abandon' "
- "SYNTAX OMsInteger "
- "SINGLE-VALUE )", &ad_reqId },
- { "( " LOG_SCHEMA_AT ".25 NAME 'reqMessage' "
- "DESC 'Error text of request' "
- "SYNTAX OMsDirectoryString "
- "SINGLE-VALUE )", &ad_reqMessage },
-#if 0
- { "( " LOG_SCHEMA_AT ".26 NAME 'auditOldest' "
- "DESC 'Oldest record in this branch' "
- "EQUALITY generalizedTimeMatch "
- "ORDERING generalizedTimeOrderingMatch "
- "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
- "SINGLE-VALUE )", &ad_oldest },
-#endif
{ NULL, NULL }
};
char *ot;
ObjectClass **oc;
} locs[] = {
-#if 0
{ "( " LOG_SCHEMA_OC ".0 NAME 'auditContainer' "
+ "DESC 'AuditLog container' "
"SUP top STRUCTURAL "
- "MUST auditOldest "
- "MAY cn )", &oc_container },
-#endif
+ "MAY ( cn $ reqStart $ reqEnd ) )", &log_container },
{ "( " LOG_SCHEMA_OC ".1 NAME 'auditObject' "
"DESC 'OpenLDAP request auditing' "
"SUP top STRUCTURAL "
"MUST ( reqStart $ reqType $ reqSession ) "
"MAY ( reqDN $ reqAuthzID $ reqControls $ reqRespControls $ reqEnd $ "
- "reqResult $ reqMessage ) )", &log_ocs[LOG_EN_UNBIND] },
+ "reqResult $ reqMessage $ reqReferral ) )",
+ &log_ocs[LOG_EN_UNBIND] },
{ "( " LOG_SCHEMA_OC ".2 NAME 'auditReadObject' "
"DESC 'OpenLDAP read request record' "
"SUP auditObject STRUCTURAL )", NULL },
{ "( " LOG_SCHEMA_OC ".3 NAME 'auditWriteObject' "
"DESC 'OpenLDAP write request record' "
- "SUP auditObject STRUCTURAL )", &log_ocs[LOG_EN_DELETE] },
+ "SUP auditObject STRUCTURAL )", NULL },
{ "( " LOG_SCHEMA_OC ".4 NAME 'auditAbandon' "
"DESC 'Abandon operation' "
"SUP auditObject STRUCTURAL "
{ "( " LOG_SCHEMA_OC ".6 NAME 'auditBind' "
"DESC 'Bind operation' "
"SUP auditObject STRUCTURAL "
- "MUST reqMethod )", &log_ocs[LOG_EN_BIND] },
+ "MUST ( reqVersion $ reqMethod ) )", &log_ocs[LOG_EN_BIND] },
{ "( " LOG_SCHEMA_OC ".7 NAME 'auditCompare' "
"DESC 'Compare operation' "
"SUP auditReadObject STRUCTURAL "
"MUST reqAssertion )", &log_ocs[LOG_EN_COMPARE] },
- { "( " LOG_SCHEMA_OC ".8 NAME 'auditModify' "
+ { "( " LOG_SCHEMA_OC ".8 NAME 'auditDelete' "
+ "DESC 'Delete operation' "
+ "SUP auditWriteObject STRUCTURAL "
+ "MAY reqOld )", &log_ocs[LOG_EN_DELETE] },
+ { "( " LOG_SCHEMA_OC ".9 NAME 'auditModify' "
"DESC 'Modify operation' "
"SUP auditWriteObject STRUCTURAL "
- "MUST reqMod )", &log_ocs[LOG_EN_MODIFY] },
- { "( " LOG_SCHEMA_OC ".9 NAME 'auditModRDN' "
+ "MAY reqOld MUST reqMod )", &log_ocs[LOG_EN_MODIFY] },
+ { "( " LOG_SCHEMA_OC ".10 NAME 'auditModRDN' "
"DESC 'ModRDN operation' "
"SUP auditWriteObject STRUCTURAL "
"MUST ( reqNewRDN $ reqDeleteOldRDN ) "
"MAY reqNewSuperior )", &log_ocs[LOG_EN_MODRDN] },
- { "( " LOG_SCHEMA_OC ".10 NAME 'auditSearch' "
+ { "( " LOG_SCHEMA_OC ".11 NAME 'auditSearch' "
"DESC 'Search operation' "
"SUP auditReadObject STRUCTURAL "
- "MUST ( reqScope $ reqAttrsonly ) "
+ "MUST ( reqScope $ reqDerefAliases $ reqAttrsonly ) "
"MAY ( reqFilter $ reqAttr $ reqEntries $ reqSizeLimit $ "
"reqTimeLimit ) )", &log_ocs[LOG_EN_SEARCH] },
- { "( " LOG_SCHEMA_OC ".11 NAME 'auditExtended' "
+ { "( " LOG_SCHEMA_OC ".12 NAME 'auditExtended' "
"DESC 'Extended operation' "
"SUP auditObject STRUCTURAL "
"MAY reqData )", &log_ocs[LOG_EN_EXTENDED] },
#define RDNEQ "reqStart="
-/* Our time intervals are of the form [dd+]hh:mm[:ss]
- * If a field is present, it must be two digits. We assume no one
- * will want to keep log records for longer than 99 days.
+/* Our time intervals are of the form [ddd+]hh:mm[:ss]
+ * If a field is present, it must be two digits. (Except for
+ * days, which can be arbitrary width.)
*/
static int
log_age_parse(char *agestr)
{
int t1, t2;
int gotdays = 0;
+ char *endptr;
- t1 = atoi( agestr );
+ t1 = strtol( agestr, &endptr, 10 );
/* Is there a days delimiter? */
- if ( agestr[2] == '+' ) {
+ if ( *endptr == '+' ) {
+ /* 32 bit time only covers about 68 years */
+ if ( t1 < 0 || t1 > 25000 )
+ return -1;
t1 *= 24;
gotdays = 1;
- } else if ( agestr[2] != ':' ) {
+ } else if ( *endptr != ':' ) {
/* No valid delimiter found, fail */
return -1;
}
ptr = agebv->bv_val;
if ( dd )
- ptr += sprintf( ptr, "%02d+", dd );
+ ptr += sprintf( ptr, "%d+", dd );
ptr += sprintf( ptr, "%02d:%02d", hh, mm );
if ( ss )
ptr += sprintf( ptr, ":%02d", ss );
struct log_info *li = on->on_bi.bi_private;
int rc = 0;
slap_mask_t tmask = 0;
- char agebuf[2*STRLENOF("dd+hh:mm:ss ")];
+ char agebuf[2*STRLENOF("ddddd+hh:mm:ss ")];
struct berval agebv, cyclebv;
switch( c->op ) {
return rc;
}
-static Entry *accesslog_entry( Operation *op, int logop ) {
+static Entry *accesslog_entry( Operation *op, int logop,
+ Operation *op2 ) {
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
log_info *li = on->on_bi.bi_private;
attr_merge_one( e, ad_reqStart, ×tamp, &ntimestamp );
op->o_tmpfree( ntimestamp.bv_val, op->o_tmpmemctx );
+ slap_op_time( &op2->o_time, &op2->o_tincr );
+
+ timestamp.bv_len = sizeof(rdnbuf) - STRLENOF(RDNEQ);
+ slap_timestamp( &op2->o_time, ×tamp );
+ sprintf( timestamp.bv_val + timestamp.bv_len-1, ".%06dZ", op2->o_tincr );
+ timestamp.bv_len += 7;
+
+ attr_merge_normalize_one( e, ad_reqEnd, ×tamp, op->o_tmpmemctx );
+
/* Exops have OID appended */
if ( logop == LOG_EN_EXTENDED ) {
bv.bv_len = lo->word.bv_len + op->ore_reqoid.bv_len + 2;
static struct berval scopes[] = {
BER_BVC("base"),
- BER_BVC("onelevel"),
- BER_BVC("subtree"),
- BER_BVC("subordinate")
+ BER_BVC("one"),
+ BER_BVC("sub"),
+ BER_BVC("subord")
+};
+
+static struct berval derefs[] = {
+ BER_BVC("never"),
+ BER_BVC("searching"),
+ BER_BVC("finding"),
+ BER_BVC("always")
};
static struct berval simple = BER_BVC("SIMPLE");
Attribute *a, *last_attr;
Modifications *m;
struct berval *b;
- time_t endtime;
int i;
int logop;
slap_verbmasks *lo;
Entry *e;
- char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE];
+ char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE+8];
struct berval bv;
char *ptr;
BerVarray vals;
if ( rs->sr_type != REP_RESULT && rs->sr_type != REP_EXTENDED )
return SLAP_CB_CONTINUE;
- if ( li->li_success && rs->sr_err != LDAP_SUCCESS )
- return SLAP_CB_CONTINUE;
-
switch ( op->o_tag ) {
case LDAP_REQ_ADD: logop = LOG_EN_ADD; break;
case LDAP_REQ_DELETE: logop = LOG_EN_DELETE; break;
if ( !( li->li_ops & lo->mask ))
return SLAP_CB_CONTINUE;
- endtime = slap_get_time();
-
- e = accesslog_entry( op, logop );
+ if ( lo->mask & LOG_OP_WRITES ) {
+ ldap_pvt_thread_mutex_lock( &li->li_log_mutex );
+ ldap_pvt_thread_mutex_unlock( &li->li_op_mutex );
+ }
- bv.bv_val = timebuf;
- bv.bv_len = sizeof(timebuf);
- slap_timestamp( &endtime, &bv );
+ if ( li->li_success && rs->sr_err != LDAP_SUCCESS )
+ goto done;
- attr_merge_one( e, ad_reqEnd, &bv, NULL );
+ e = accesslog_entry( op, logop, &op2 );
attr_merge_one( e, ad_reqDN, &op->o_req_dn, &op->o_req_ndn );
case LOG_EN_SEARCH:
attr_merge_one( e, ad_reqScope, &scopes[op->ors_scope], NULL );
+ attr_merge_one( e, ad_reqDerefAliases, &derefs[op->ors_deref], NULL );
attr_merge_one( e, ad_reqAttrsOnly, op->ors_attrsonly ?
(struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv,
NULL );
break;
case LOG_EN_BIND:
+ bv.bv_val = timebuf;
+ bv.bv_len = sprintf( bv.bv_val, "%d", op->o_protocol );
+ attr_merge_one( e, ad_reqVersion, &bv, NULL );
if ( op->orb_method == LDAP_AUTH_SIMPLE ) {
attr_merge_one( e, ad_reqMethod, &simple, NULL );
} else {
attr_merge_one( e, ad_reqMethod, &bv, NULL );
op->o_tmpfree( bv.bv_val, op->o_tmpmemctx );
}
+
break;
case LOG_EN_EXTENDED:
op2.o_hdr = op->o_hdr;
op2.o_tag = LDAP_REQ_ADD;
- op2.o_time = endtime;
- op2.o_tincr = 0;
op2.o_bd = li->li_db;
op2.o_dn = li->li_db->be_rootdn;
op2.o_ndn = li->li_db->be_rootndn;
op2.ora_e = e;
op2.o_callback = &nullsc;
- if ( lo->mask & LOG_OP_WRITES ) {
- slap_get_commit_csn( op, NULL, &bv );
- attr_merge_one( e, slap_schema.si_ad_entryCSN, &bv, NULL );
- slap_queue_csn( &op2, &bv );
+ if (( lo->mask & LOG_OP_WRITES ) && !BER_BVISEMPTY( &op->o_csn )) {
+ slap_queue_csn( &op2, &op->o_csn );
}
op2.o_bd->be_add( &op2, &rs2 );
- slap_graduate_commit_csn( &op2 );
entry_free( e );
+done:
+ ldap_pvt_thread_mutex_unlock( &li->li_log_mutex );
+ return SLAP_CB_CONTINUE;
+}
+
+/* Since Bind success is sent by the frontend, it won't normally enter
+ * the overlay response callback. Add another callback to make sure it
+ * gets here.
+ */
+static int
+accesslog_bind_resp( Operation *op, SlapReply *rs )
+{
+ BackendDB *be, db;
+ int rc;
+ slap_callback *sc;
+
+ be = op->o_bd;
+ db = *be;
+ op->o_bd = &db;
+ db.bd_info = op->o_callback->sc_private;
+ rc = accesslog_response( op, rs );
+ op->o_bd = be;
+ sc = op->o_callback;
+ op->o_callback = sc->sc_next;
+ op->o_tmpfree( sc, op->o_tmpmemctx );
+ return rc;
+}
+
+static int
+accesslog_op_bind( Operation *op, SlapReply *rs )
+{
+ slap_callback *sc;
+
+ sc = op->o_tmpcalloc( 1, sizeof(slap_callback), op->o_tmpmemctx );
+ sc->sc_response = accesslog_bind_resp;
+ sc->sc_private = op->o_bd->bd_info;
+
+ if ( op->o_callback ) {
+ sc->sc_next = op->o_callback->sc_next;
+ op->o_callback->sc_next = sc;
+ } else {
+ op->o_callback = sc;
+ }
+ return SLAP_CB_CONTINUE;
+}
+
+static int
+accesslog_op_mod( Operation *op, SlapReply *rs )
+{
+ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+ log_info *li = on->on_bi.bi_private;
+
+ if ( li->li_ops & LOG_OP_WRITES ) {
+ /* FIXME: this needs to be a recursive mutex to allow
+ * overlays like refint to keep working.
+ */
+ ldap_pvt_thread_mutex_lock( &li->li_op_mutex );
+ }
return SLAP_CB_CONTINUE;
}
static int
accesslog_unbind( Operation *op, SlapReply *rs )
{
- if ( op->o_conn->c_authz_backend == op->o_bd ) {
- slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+ if ( op->o_conn->c_authz_backend == on->on_info->oi_origdb ) {
log_info *li = on->on_bi.bi_private;
Operation op2;
+ void *cids[SLAP_MAX_CIDS];
SlapReply rs2 = {REP_RESULT};
Entry *e;
if ( !( li->li_ops & LOG_OP_UNBIND ))
return SLAP_CB_CONTINUE;
- e = accesslog_entry( op, LOG_EN_UNBIND );
+ e = accesslog_entry( op, LOG_EN_UNBIND, &op2 );
op2.o_hdr = op->o_hdr;
op2.o_tag = LDAP_REQ_ADD;
- op2.o_time = op->o_time;
- op2.o_tincr = 0;
op2.o_bd = li->li_db;
op2.o_dn = li->li_db->be_rootdn;
op2.o_ndn = li->li_db->be_rootndn;
op2.o_req_ndn = e->e_nname;
op2.ora_e = e;
op2.o_callback = &nullsc;
+ op2.o_controls = cids;
+ memset(cids, 0, sizeof( cids ));
+ memset(op2.o_ctrlflag, 0, sizeof( op2.o_ctrlflag ));
op2.o_bd->be_add( &op2, &rs2 );
entry_free( e );
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
log_info *li = on->on_bi.bi_private;
Operation op2;
+ void *cids[SLAP_MAX_CIDS];
SlapReply rs2 = {REP_RESULT};
Entry *e;
char buf[64];
if ( !op->o_time || !( li->li_ops & LOG_OP_ABANDON ))
return SLAP_CB_CONTINUE;
- e = accesslog_entry( op, LOG_EN_ABANDON );
+ e = accesslog_entry( op, LOG_EN_ABANDON, &op2 );
bv.bv_val = buf;
bv.bv_len = sprintf( buf, "%d", op->orn_msgid );
attr_merge_one( e, ad_reqId, &bv, NULL );
op2.o_hdr = op->o_hdr;
op2.o_tag = LDAP_REQ_ADD;
- op2.o_time = op->o_time;
- op2.o_tincr = 0;
op2.o_bd = li->li_db;
op2.o_dn = li->li_db->be_rootdn;
op2.o_ndn = li->li_db->be_rootndn;
op2.o_req_ndn = e->e_nname;
op2.ora_e = e;
op2.o_callback = &nullsc;
+ op2.o_controls = cids;
+ memset(cids, 0, sizeof( cids ));
+ memset(op2.o_ctrlflag, 0, sizeof( op2.o_ctrlflag ));
op2.o_bd->be_add( &op2, &rs2 );
entry_free( e );
log_info *li = ch_calloc(1, sizeof(log_info));
on->on_bi.bi_private = li;
+ ldap_pvt_thread_mutex_init( &li->li_op_mutex );
+ ldap_pvt_thread_mutex_init( &li->li_log_mutex );
return 0;
}
slap_overinst *on = (slap_overinst *)be->bd_info;
log_info *li = on->on_bi.bi_private;
+ ldap_pvt_thread_mutex_destroy( &li->li_log_mutex );
+ ldap_pvt_thread_mutex_destroy( &li->li_op_mutex );
free( li );
return LDAP_SUCCESS;
}
accesslog.on_bi.bi_db_init = accesslog_db_init;
accesslog.on_bi.bi_db_destroy = accesslog_db_destroy;
+ accesslog.on_bi.bi_op_add = accesslog_op_mod;
+ accesslog.on_bi.bi_op_bind = accesslog_op_bind;
+ accesslog.on_bi.bi_op_delete = accesslog_op_mod;
+ accesslog.on_bi.bi_op_modify = accesslog_op_mod;
+ accesslog.on_bi.bi_op_modrdn = accesslog_op_mod;
accesslog.on_bi.bi_op_unbind = accesslog_unbind;
accesslog.on_bi.bi_op_abandon = accesslog_abandon;
accesslog.on_response = accesslog_response;
char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
struct berval entryCSN;
- slap_get_csn( NULL, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
+ entryCSN.bv_val = csnbuf;
+ entryCSN.bv_len = sizeof( csnbuf );
+ slap_get_csn( NULL, &entryCSN, 0 );
ber_dupbv( bv_entryCSN, &entryCSN );
ber_dupbv( bv_nentryCSN, &entryCSN );
timestamp.bv_len = sizeof(tmbuf);
slap_timestamp( &starttime, ×tamp );
- slap_get_csn( NULL, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
+ entryCSN.bv_val = csnbuf;
+ entryCSN.bv_len = sizeof( csnbuf );
+ slap_get_csn( NULL, &entryCSN, 0 );
if ( BER_BVISNULL( &lmi->lmi_rdnvalue ) ) {
ber_str2bv( "Lastmod", 0, 1, &lmi->lmi_rdnvalue );
*/
if ( be_shadow_update( op )) {
Modifications **prev;
- int got_del_grace = 0, got_del_lock = 0, got_pw = 0;
- Attribute *a_grace, *a_lock;
+ int got_del_grace = 0, got_del_lock = 0, got_pw = 0, got_del_fail = 0;
+ Attribute *a_grace, *a_lock, *a_fail;
a_grace = attr_find( e->e_attrs, ad_pwdGraceUseTime );
a_lock = attr_find( e->e_attrs, ad_pwdAccountLockedTime );
+ a_fail = attr_find( e->e_attrs, ad_pwdFailureTime );
for( prev = &op->oq_modify.rs_modlist, ml = *prev; ml;
prev = &ml->sml_next, ml = *prev ) {
got_del_lock = 1;
if ( !a_lock )
drop = 1;
+ } else
+ if ( ml->sml_desc == ad_pwdFailureTime ) {
+ got_del_fail = 1;
+ if ( !a_fail )
+ drop = 1;
}
if ( drop ) {
*prev = ml->sml_next;
}
}
- /* If we're resetting the password, make sure grace and accountlock
- * also get removed.
+ /* If we're resetting the password, make sure grace, accountlock,
+ * and failure also get removed.
*/
if ( got_pw ) {
if ( a_grace && !got_del_grace ) {
ml->sml_next = NULL;
*prev = ml;
}
+ if ( a_fail && !got_del_fail ) {
+ ml = (Modifications *) ch_malloc( sizeof( Modifications ) );
+ ml->sml_op = LDAP_MOD_DELETE;
+ ml->sml_flags = SLAP_MOD_INTERNAL;
+ ml->sml_type.bv_val = NULL;
+ ml->sml_desc = ad_pwdFailureTime;
+ ml->sml_values = NULL;
+ ml->sml_nvalues = NULL;
+ ml->sml_next = NULL;
+ *prev = ml;
+ }
}
op->o_bd->bd_info = (BackendInfo *)on->on_info;
be_entry_release_r( op, e );
modtail = mods;
}
+ if (attr_find(e->e_attrs, ad_pwdFailureTime )) {
+ mods = (Modifications *) ch_malloc( sizeof( Modifications ) );
+ mods->sml_op = LDAP_MOD_DELETE;
+ mods->sml_flags = SLAP_MOD_INTERNAL;
+ mods->sml_type.bv_val = NULL;
+ mods->sml_desc = ad_pwdFailureTime;
+ mods->sml_values = NULL;
+ mods->sml_nvalues = NULL;
+ mods->sml_next = NULL;
+ modtail->sml_next = mods;
+ modtail = mods;
+ }
+
/* Delete the pwdReset attribute, since it's being reset */
if ((zapReset) && (attr_find(e->e_attrs, ad_pwdReset ))) {
mods = (Modifications *) ch_malloc( sizeof( Modifications ) );
*/
for(dp = dd.mods; dp; dp = dp->next) {
- Modifications **tail, *m;
-
- for(m = dp->mm; m && m->sml_next; m = m->sml_next);
- tail = &m->sml_next;
nop.o_req_dn = dp->dn;
nop.o_req_ndn = dp->dn;
nop.o_bd = select_backend(&dp->dn, 0, 1);
nop.orm_modlist = dp->mm; /* callback did all the work */
nop.o_dn = refint_dn;
nop.o_ndn = refint_dn;
- rs->sr_err = slap_mods_opattrs( &nop, nop.orm_modlist,
- tail, &rs->sr_text, NULL, 0, 1 );
nop.o_dn = nop.o_bd->be_rootdn;
nop.o_ndn = nop.o_bd->be_rootndn;
if(rs->sr_err != LDAP_SUCCESS) goto done;
dc.normalized = 0;
#endif /* ! ENABLE_REWRITE */
- rc = rwm_filter_map_rewrite( &dc, op->ors_filter, &fstr );
+ rc = rwm_filter_map_rewrite( op, &dc, op->ors_filter, &fstr );
if ( rc != LDAP_SUCCESS ) {
text = "searchFilter/searchFilterAttrDN massage error";
goto error_return;
goto fail;
}
+ flags &= ~REP_ENTRY_MUSTRELEASE;
flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
}
* to return, and remap them accordingly */
(void)rwm_attrs( op, rs, &e->e_attrs, 1 );
-#if 0
- if ( rs->sr_operational_attrs ) {
- (void)rwm_attrs( op, rs, &rs->sr_operational_attrs, 0 );
+ if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
+ be_entry_release_rw( op, rs->sr_entry, 0 );
}
-#endif
rs->sr_entry = e;
rs->sr_flags = flags;
} else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
rwmap->rwm_flags |= RWM_F_SUPPORT_T_F;
-#if 0
/* TODO: not implemented yet */
} else if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
+ fprintf( stderr,
+ "%s: line %d: \"discover\" not supported yet "
+ "in \"t-f-support {no|yes|discover}\".\n",
+ fname, lineno );
+ return( 1 );
+#if 0
rwmap->rwm_flags |= RWM_F_SUPPORT_T_F_DISCOVER;
#endif
(struct ldaprwmap *)on->on_bi.bi_private;
#ifdef ENABLE_REWRITE
- if (rwmap->rwm_rw) {
+ if ( rwmap->rwm_rw ) {
rewrite_info_delete( &rwmap->rwm_rw );
}
#else /* !ENABLE_REWRITE */
}
#endif /* !ENABLE_REWRITE */
- avl_free( rwmap->rwm_oc.remap, NULL );
+ avl_free( rwmap->rwm_oc.remap, rwm_mapping_dst_free );
avl_free( rwmap->rwm_oc.map, rwm_mapping_free );
- avl_free( rwmap->rwm_at.remap, NULL );
+ avl_free( rwmap->rwm_at.remap, rwm_mapping_dst_free );
avl_free( rwmap->rwm_at.map, rwm_mapping_free );
ch_free( rwmap );
AttributeName **anp,
int remap );
+extern void rwm_mapping_dst_free ( void *mapping );
+
extern void rwm_mapping_free ( void *mapping );
extern int rwm_map_config(
extern int
rwm_filter_map_rewrite(
+ Operation *op,
dncookie *dc,
Filter *f,
struct berval *fstr );
if ( mapping[0].m_dst_oc == NULL ) {
fprintf( stderr, "%s: line %d: unable to mimic destination objectClass '%s'\n",
fname, lineno, dst );
- return 1;
+ goto error_return;
}
#if 0
fprintf( stderr,
"%s: line %d: source attributeType '%s': %d (%s)\n",
fname, lineno, src, rc, text ? text : "null" );
- return 1;
+ goto error_return;
}
}
fprintf( stderr,
"%s: line %d: destination attributeType '%s': %d (%s)\n",
fname, lineno, dst, rc, text ? text : "null" );
- return 1;
+ goto error_return;
}
}
mapping[1].m_src_ad = mapping[0].m_dst_ad;
static int
rwm_int_filter_map_rewrite(
+ Operation *op,
dncookie *dc,
Filter *f,
struct berval *fstr )
Filter *p;
struct berval atmp,
vtmp,
- tmp;
+ *tmp;
static struct berval
/* better than nothing... */
ber_bvfalse = BER_BVC( "(!(objectClass=*))" ),
if ( f == NULL ) {
ber_dupbv( fstr, &ber_bvnone );
- return -1;
+ return LDAP_OTHER;
}
switch ( f->f_choice ) {
if ( map_attr_value( dc, &f->f_av_desc, &atmp,
&f->f_av_value, &vtmp, RWM_MAP ) )
{
- return -1;
+ goto computed;
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(=)" );
if ( map_attr_value( dc, &f->f_av_desc, &atmp,
&f->f_av_value, &vtmp, RWM_MAP ) )
{
- return -1;
+ goto computed;
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(>=)" );
if ( map_attr_value( dc, &f->f_av_desc, &atmp,
&f->f_av_value, &vtmp, RWM_MAP ) )
{
- return -1;
+ goto computed;
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(<=)" );
if ( map_attr_value( dc, &f->f_av_desc, &atmp,
&f->f_av_value, &vtmp, RWM_MAP ) )
{
- return -1;
+ goto computed;
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(~=)" );
if ( map_attr_value( dc, &f->f_sub_desc, &atmp,
NULL, NULL, RWM_MAP ) )
{
- return -1;
+ goto computed;
}
/* cannot be a DN ... */
if ( map_attr_value( dc, &f->f_desc, &atmp,
NULL, NULL, RWM_MAP ) )
{
- return -1;
+ goto computed;
}
fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
for ( p = f->f_list; p != NULL; p = p->f_next ) {
+ int rc;
+
len = fstr->bv_len;
- if ( rwm_int_filter_map_rewrite( dc, p, &vtmp ) )
- {
- return -1;
+ rc = rwm_int_filter_map_rewrite( op, dc, p, &vtmp );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
}
fstr->bv_len += vtmp.bv_len;
if ( map_attr_value( dc, &f->f_mr_desc, &atmp,
&f->f_mr_value, &vtmp, RWM_MAP ) )
{
- return -1;
+ goto computed;
}
} else {
break;
}
+ case 0:
+computed:;
+ filter_free_x( op, f );
+ f->f_choice = SLAPD_FILTER_COMPUTED;
+ f->f_result = SLAPD_COMPARE_UNDEFINED;
+ /* fallthru */
+
case SLAPD_FILTER_COMPUTED:
switch ( f->f_result ) {
case LDAP_COMPARE_FALSE:
+ /* FIXME: treat UNDEFINED as FALSE */
+ case SLAPD_COMPARE_UNDEFINED:
if ( dc->rwmap->rwm_flags & RWM_F_SUPPORT_T_F ) {
- tmp = ber_bvtf_false;
+ tmp = &ber_bvtf_false;
break;
}
- /* fallthru */
-
- case SLAPD_COMPARE_UNDEFINED:
- tmp = ber_bvfalse;
+ tmp = &ber_bvfalse;
break;
case LDAP_COMPARE_TRUE:
if ( dc->rwmap->rwm_flags & RWM_F_SUPPORT_T_F ) {
- tmp = ber_bvtf_true;
- } else {
- tmp = ber_bvtrue;
+ tmp = &ber_bvtf_true;
+ break;
}
+ tmp = &ber_bvtrue;
break;
default:
- tmp = ber_bverror;
+ tmp = &ber_bverror;
break;
}
- ber_dupbv( fstr, &tmp );
+ ber_dupbv( fstr, tmp );
break;
default:
break;
}
- return 0;
+ return LDAP_SUCCESS;
}
int
rwm_filter_map_rewrite(
+ Operation *op,
dncookie *dc,
Filter *f,
struct berval *fstr )
dncookie fdc;
struct berval ftmp;
- rc = rwm_int_filter_map_rewrite( dc, f, fstr );
+ rc = rwm_int_filter_map_rewrite( op, dc, f, fstr );
#ifdef ENABLE_REWRITE
- if ( rc != LDAP_SUCCESS ) {
+ if ( rc != 0 ) {
return rc;
}
rc = LDAP_OTHER;
break;
}
-
#endif /* ENABLE_REWRITE */
+
return rc;
}
return 0;
}
+void
+rwm_mapping_dst_free( void *v_mapping )
+{
+ struct ldapmapping *mapping = v_mapping;
+
+ if ( BER_BVISEMPTY( &mapping[0].m_dst ) ) {
+ rwm_mapping_free( &mapping[ -1 ] );
+ }
+}
+
void
rwm_mapping_free( void *v_mapping )
{
int si_chktime;
int si_numops; /* number of ops since last checkpoint */
int si_nopres; /* Skip present phase */
+ int si_usehint; /* use reload hint */
time_t si_chklast; /* time of last checkpoint */
Avlnode *si_mods; /* entries being modified */
sessionlog *si_logs;
return LDAP_SUCCESS;
}
+static Filter generic_filter = { LDAP_FILTER_PRESENT, { 0 }, NULL };
+static struct berval generic_filterstr = BER_BVC("(objectclass=*)");
+
static int
syncprov_findbase( Operation *op, fbase_cookie *fc )
{
fop.ors_tlimit = SLAP_NO_LIMIT;
fop.ors_attrs = slap_anlist_no_attrs;
fop.ors_attrsonly = 1;
+ fop.ors_filter = &generic_filter;
+ fop.ors_filterstr = generic_filterstr;
fop.o_bd->bd_info = on->on_info->oi_orig;
rc = fop.o_bd->be_search( &fop, &frs );
/* Send a persistent search response */
static int
-syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, Entry **e, int mode)
+syncprov_sendresp( Operation *op, opcookie *opc, syncops *so,
+ Entry **e, int mode )
{
slap_overinst *on = opc->son;
/* Is the CSN still present in the database? */
if ( syncprov_findcsn( op, FIND_CSN ) != LDAP_SUCCESS ) {
/* No, so a reload is required */
-#if 0 /* the consumer doesn't seem to send this hint */
- if ( op->o_sync_rhint == 0 ) {
+ /* the 2.2 consumer doesn't send this hint */
+ if ( si->si_usehint && srs->sr_rhint == 0 ) {
send_ldap_error( op, rs, LDAP_SYNC_REFRESH_REQUIRED, "sync cookie is stale" );
return rs->sr_err;
}
-#endif
} else {
gotstate = 1;
/* If changed and doing Present lookup, send Present UUIDs */
enum {
SP_CHKPT = 1,
SP_SESSL,
- SP_NOPRES
+ SP_NOPRES,
+ SP_USEHINT
};
static ConfigDriver sp_cf_gen;
sp_cf_gen, "( OLcfgOvAt:1.3 NAME 'olcSpNoPresent' "
"DESC 'Omit Present phase processing' "
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+ { "syncprov-reloadhint", NULL, 2, 2, 0, ARG_ON_OFF|ARG_MAGIC|SP_USEHINT,
+ sp_cf_gen, "( OLcfgOvAt:1.4 NAME 'olcSpReloadHint' "
+ "DESC 'Observe Reload Hint in Request control' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
};
rc = 1;
}
break;
+ case SP_USEHINT:
+ if ( si->si_usehint ) {
+ c->value_int = 1;
+ } else {
+ rc = 1;
+ }
+ break;
}
return rc;
} else if ( c->op == LDAP_MOD_DELETE ) {
else
rc = LDAP_NO_SUCH_ATTRIBUTE;
break;
+ case SP_USEHINT:
+ if ( si->si_usehint )
+ si->si_usehint = 0;
+ else
+ rc = LDAP_NO_SUCH_ATTRIBUTE;
+ break;
}
return rc;
}
case SP_NOPRES:
si->si_nopres = c->value_int;
break;
+ case SP_USEHINT:
+ si->si_usehint = c->value_int;
+ break;
}
return rc;
}
}
if ( BER_BVISEMPTY( &si->si_ctxcsn ) ) {
- slap_get_csn( op, si->si_ctxcsnbuf, sizeof(si->si_ctxcsnbuf),
- &si->si_ctxcsn, 0 );
+ si->si_ctxcsn.bv_len = sizeof( si->si_ctxcsnbuf );
+ slap_get_csn( op, &si->si_ctxcsn, 0 );
}
/* If our ctxcsn is different from what was read from the root
rs->sr_text = "Sync control : cookie decoding error";
return LDAP_PROTOCOL_ERROR;
}
+ tag = ber_peek_tag( ber, &len );
}
if ( tag == LDAP_TAG_RELOAD_HINT ) {
if (( ber_scanf( ber, /*{*/ "b", &rhint )) == LBER_ERROR ) {
syncprov.on_bi.bi_cf_ocs = spocs;
+ generic_filter.f_desc = slap_schema.si_ad_objectClass;
+
rc = config_register_schema( spcfg, spocs );
if ( rc ) return rc;
cb2.sc_private = qpw; /* let Modify know this was pwdMod,
* if it cares... */
- rs->sr_err = slap_mods_opattrs( op, ml, qpw->rs_modtail, &rs->sr_text,
- NULL, 0, 1 );
-
- if ( rs->sr_err == LDAP_SUCCESS ) {
- rs->sr_err = op->o_bd->be_modify( op, rs );
- }
+ rs->sr_err = op->o_bd->be_modify( op, rs );
if ( rs->sr_err == LDAP_SUCCESS ) {
rs->sr_rspdata = rsp;
} else if ( rsp ) {
*/
LDAP_SLAPD_V (char *) style_strings[];
-LDAP_SLAPD_F (void) parse_acl LDAP_P(( Backend *be,
+LDAP_SLAPD_F (int) parse_acl LDAP_P(( Backend *be,
const char *fname, int lineno,
int argc, char **argv, int pos ));
LDAP_SLAPD_F (int) slap_entry2mods LDAP_P(( Entry *e,
Modifications **mods, const char **text,
char *textbuf, size_t textlen ));
+LDAP_SLAPD_F( int ) slap_add_opattrs(
+ Operation *op,
+ const char **text,
+ char *textbuf, size_t textlen,
+ int manage_ctxcsn );
+
/*
* at.c
*/
LDAP_SLAPD_F (int) slap_loglevel_register LDAP_P (( slap_mask_t m, struct berval *s ));
LDAP_SLAPD_F (int) str2loglevel LDAP_P(( const char *s, int *l ));
+LDAP_SLAPD_F (int) loglevel2bvarray LDAP_P(( int l, BerVarray *bva ));
+LDAP_SLAPD_F (const char *) loglevel2str LDAP_P(( int l ));
+LDAP_SLAPD_F (int) loglevel2bv LDAP_P(( int l, struct berval *bv ));
/*
* ch_malloc.c
LDAP_SLAPD_F (const char *) connection_state2str LDAP_P(( int state ))
LDAP_GCCATTR((const));
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+LDAP_SLAPD_F (int) connection_write_activate LDAP_P((ber_socket_t s));
+LDAP_SLAPD_F (int) connection_read_activate LDAP_P((ber_socket_t s));
+#else
LDAP_SLAPD_F (int) connection_write LDAP_P((ber_socket_t s));
LDAP_SLAPD_F (int) connection_read LDAP_P((ber_socket_t s));
+#endif
LDAP_SLAPD_F (unsigned long) connections_nextid(void);
LDAP_SLAPD_F (void) slap_rewind_commit_csn LDAP_P(( Operation * ));
LDAP_SLAPD_F (void) slap_graduate_commit_csn LDAP_P(( Operation * ));
LDAP_SLAPD_F (Entry *) slap_create_context_csn_entry LDAP_P(( Backend *, struct berval *));
-LDAP_SLAPD_F (int) slap_get_csn LDAP_P(( Operation *, char *, int, struct berval *, int ));
+LDAP_SLAPD_F (int) slap_get_csn LDAP_P(( Operation *, struct berval *, int ));
LDAP_SLAPD_F (void) slap_queue_csn LDAP_P(( Operation *, struct berval * ));
/*
LDAP_SLAPD_F (int) slapd_daemon_destroy(void);
LDAP_SLAPD_F (int) slapd_daemon(void);
LDAP_SLAPD_F (Listener **) slapd_get_listeners LDAP_P((void));
-LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wasactive, int wake));
+LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wasactive,
+ int wake, int locked ));
+LDAP_SLAPD_F (void) slapd_sd_lock();
+LDAP_SLAPD_F (void) slapd_sd_unlock();
LDAP_SLAPD_F (RETSIGTYPE) slap_sig_shutdown LDAP_P((int sig));
LDAP_SLAPD_F (RETSIGTYPE) slap_sig_wake LDAP_P((int sig));
LDAP_SLAPD_F (void) slapd_set_write LDAP_P((ber_socket_t s, int wake));
LDAP_SLAPD_F (void) slapd_clr_write LDAP_P((ber_socket_t s, int wake));
LDAP_SLAPD_F (void) slapd_set_read LDAP_P((ber_socket_t s, int wake));
-LDAP_SLAPD_F (void) slapd_clr_read LDAP_P((ber_socket_t s, int wake));
+LDAP_SLAPD_F (int) slapd_clr_read LDAP_P((ber_socket_t s, int wake));
LDAP_SLAPD_V (volatile sig_atomic_t) slapd_abrupt_shutdown;
LDAP_SLAPD_V (volatile sig_atomic_t) slapd_shutdown;
int index, struct berval *oid, int blen ));
LDAP_SLAPD_F (int) load_extop LDAP_P((
- struct berval *ext_oid,
+ const struct berval *ext_oid,
slap_mask_t flags,
SLAP_EXTOP_MAIN_FN *ext_main ));
time_t *tm,
struct berval *bv );
-LDAP_SLAPD_F( int ) slap_mods_opattrs(
+LDAP_SLAPD_F( void ) slap_mods_opattrs(
Operation *op,
Modifications *mods,
- Modifications **modlist,
- const char **text,
- char *textbuf, size_t textlen,
int manage_ctxcsn );
/*
LDAP_SLAPD_F (void) slap_op_init LDAP_P(( void ));
LDAP_SLAPD_F (void) slap_op_destroy LDAP_P(( void ));
LDAP_SLAPD_F (void) slap_op_free LDAP_P(( Operation *op ));
+LDAP_SLAPD_F (void) slap_op_time LDAP_P(( time_t *t, int *n ));
LDAP_SLAPD_F (Operation *) slap_op_alloc LDAP_P((
BerElement *ber, ber_int_t msgid,
ber_tag_t tag, ber_int_t id ));
LDAP_SLAPD_V (ldap_pvt_thread_pool_t) connection_pool;
LDAP_SLAPD_V (int) connection_pool_max;
+LDAP_SLAPD_V (int) slap_tool_thread_max;
LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) entry2str_mutex;
LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) replog_mutex;
}
if ( op->o_callback ) {
- int first = 1;
- slap_callback *sc = op->o_callback,
- *sc_next = op->o_callback;
+ slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
rc = SLAP_CB_CONTINUE;
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
sc_next = op->o_callback->sc_next;
if ( op->o_callback->sc_response ) {
rc = op->o_callback->sc_response( op, rs );
- if ( first && op->o_callback == NULL ) {
- sc = NULL;
+ if ( op->o_callback != *sc_prev ) {
+ *sc_prev = op->o_callback;
}
- if ( rc != SLAP_CB_CONTINUE ) break;
+ if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
}
- first = 0;
+ sc_prev = &op->o_callback->sc_next;
}
op->o_callback = sc;
clean2:;
if ( op->o_callback ) {
- int first = 1;
- slap_callback *sc = op->o_callback, *sc_next;
+ slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
sc_next = op->o_callback->sc_next;
if ( op->o_callback->sc_cleanup ) {
(void)op->o_callback->sc_cleanup( op, rs );
- if ( first && op->o_callback != sc ) {
- sc = op->o_callback;
+ if ( op->o_callback != *sc_prev ) {
+ *sc_prev = op->o_callback;
}
+ if ( !op->o_callback ) break;
}
- first = 0;
+ sc_prev = &op->o_callback->sc_next;
}
op->o_callback = sc;
}
}
if ( op->o_callback ) {
- int first = 1;
- slap_callback *sc = op->o_callback,
- *sc_next = op->o_callback;
+ slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
rc = SLAP_CB_CONTINUE;
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next )
sc_next = op->o_callback->sc_next;
if ( op->o_callback->sc_response ) {
rc = op->o_callback->sc_response( op, rs );
- if ( first && op->o_callback == NULL ) {
- sc = NULL;
+ if ( op->o_callback != *sc_prev ) {
+ *sc_prev = op->o_callback;
}
- if ( rc != SLAP_CB_CONTINUE ) break;
+ if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
}
- first = 0;
+ sc_prev = &op->o_callback->sc_next;
}
op->o_callback = sc;
error_return:;
if ( op->o_callback ) {
- int first = 1;
- slap_callback *sc = op->o_callback, *sc_next;
+ slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
sc_next = op->o_callback->sc_next;
if ( op->o_callback->sc_cleanup ) {
(void)op->o_callback->sc_cleanup( op, rs );
- if ( first && op->o_callback != sc ) {
- sc = op->o_callback;
+ if ( op->o_callback != *sc_prev ) {
+ *sc_prev = op->o_callback;
}
+ if ( !op->o_callback ) break;
}
- first = 0;
+ sc_prev = &op->o_callback->sc_next;
}
op->o_callback = sc;
}
rs->sr_type = REP_SEARCHREF;
if ( op->o_callback ) {
- int first = 1;
- slap_callback *sc = op->o_callback,
- *sc_next = op->o_callback;
+ slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
rc = SLAP_CB_CONTINUE;
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
sc_next = op->o_callback->sc_next;
if ( op->o_callback->sc_response ) {
rc = op->o_callback->sc_response( op, rs );
- if ( first && op->o_callback == NULL ) {
- sc = NULL;
+ if ( op->o_callback != *sc_prev ) {
+ *sc_prev = op->o_callback;
}
- if ( rc != SLAP_CB_CONTINUE ) break;
+ if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
}
- first = 0;
+ sc_prev = &op->o_callback->sc_next;
}
op->o_callback = sc;
rel:
if ( op->o_callback ) {
- int first = 1;
- slap_callback *sc = op->o_callback, *sc_next;
+ slap_callback *sc = op->o_callback, **sc_prev = &sc, *sc_next;
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
sc_next = op->o_callback->sc_next;
if ( op->o_callback->sc_cleanup ) {
(void)op->o_callback->sc_cleanup( op, rs );
- if ( first && op->o_callback != sc ) {
- sc = op->o_callback;
+ if ( op->o_callback != *sc_prev ) {
+ *sc_prev = op->o_callback;
}
+ if ( rc != SLAP_CB_CONTINUE || !op->o_callback ) break;
}
- first = 0;
+ sc_prev = &op->o_callback->sc_next;
}
op->o_callback = sc;
}
op.o_tag = LDAP_REQ_SEARCH;
op.o_ndn = conn->c_ndn;
op.o_callback = &cb;
- op.o_time = slap_get_time();
+ slap_op_time( &op.o_time, &op.o_tincr );
op.o_do_not_cache = 1;
op.o_is_auth_check = 1;
op.o_req_dn = op.o_req_ndn;
&text, textbuf, textlen );
if ( rc == LDAP_SUCCESS ) {
- rc = slap_mods_opattrs( &op, modlist, modtail,
- &text, textbuf, textlen, 1 );
-
- if ( rc == LDAP_SUCCESS ) {
- op.o_hdr = conn->c_sasl_bindop->o_hdr;
- op.o_tag = LDAP_REQ_MODIFY;
- op.o_ndn = op.o_req_ndn;
- op.o_callback = &cb;
- op.o_time = slap_get_time();
- op.o_do_not_cache = 1;
- op.o_is_auth_check = 1;
- op.o_req_dn = op.o_req_ndn;
- op.orm_modlist = modlist;
-
- rc = op.o_bd->be_modify( &op, &rs );
- }
+ op.o_hdr = conn->c_sasl_bindop->o_hdr;
+ op.o_tag = LDAP_REQ_MODIFY;
+ op.o_ndn = op.o_req_ndn;
+ op.o_callback = &cb;
+ slap_op_time( &op.o_time, &op.o_tincr );
+ op.o_do_not_cache = 1;
+ op.o_is_auth_check = 1;
+ op.o_req_dn = op.o_req_ndn;
+ op.orm_modlist = modlist;
+
+ rc = op.o_bd->be_modify( &op, &rs );
}
}
slap_mods_free( modlist, 1 );
op.o_tag = LDAP_REQ_SEARCH;
op.o_ndn = *authc;
op.o_callback = &cb;
- op.o_time = slap_get_time();
+ slap_op_time( &op.o_time, &op.o_tincr );
op.o_do_not_cache = 1;
op.o_is_auth_check = 1;
/* use req_ndn as req_dn instead of non-pretty base of uri */
op.o_tag = LDAP_REQ_SEARCH;
op.o_ndn = opx->o_conn->c_ndn;
op.o_callback = &cb;
- op.o_time = slap_get_time();
+ slap_op_time( &op.o_time, &op.o_tincr );
op.o_do_not_cache = 1;
op.o_is_auth_check = 1;
op.ors_deref = LDAP_DEREF_NEVER;
# Standard object classes from RFC2256
+# system schema
+#objectclass ( 2.5.6.0 NAME 'top'
+# DESC 'RFC2256: top of the superclass chain'
+# ABSTRACT
+# MUST objectClass )
+
# system schema
#objectclass ( 2.5.6.1 NAME 'alias'
# DESC 'RFC2256: an alias'
return LDAP_SUCCESS;
}
-void
-hashDigestify(
+static void
+hashPreset(
HASH_CONTEXT *HASHcontext,
- unsigned char *HASHdigest,
struct berval *prefix,
char pre,
Syntax *syntax,
- MatchingRule *mr,
- unsigned char *value,
- int value_len)
+ MatchingRule *mr)
{
HASH_Init(HASHcontext);
if(prefix && prefix->bv_len > 0) {
if(pre) HASH_Update(HASHcontext, (unsigned char*)&pre, sizeof(pre));
HASH_Update(HASHcontext, (unsigned char*)syntax->ssyn_oid, syntax->ssyn_oidlen);
HASH_Update(HASHcontext, (unsigned char*)mr->smr_oid, mr->smr_oidlen);
- HASH_Update(HASHcontext, value, value_len);
- HASH_Final(HASHdigest, HASHcontext);
return;
}
+static void
+hashIter(
+ HASH_CONTEXT *HASHcontext,
+ unsigned char *HASHdigest,
+ unsigned char *value,
+ int len)
+{
+ HASH_CONTEXT ctx = *HASHcontext;
+ HASH_Update( &ctx, value, len );
+ HASH_Final( HASHdigest, &ctx );
+}
+
/* Index generation function */
int octetStringIndexer(
slap_mask_t use,
slen = syntax->ssyn_oidlen;
mlen = mr->smr_oidlen;
+ hashPreset( &HASHcontext, prefix, 0, syntax, mr);
for( i=0; !BER_BVISNULL( &values[i] ); i++ ) {
- hashDigestify( &HASHcontext, HASHdigest, prefix, 0,
- syntax, mr, (unsigned char *)values[i].bv_val, values[i].bv_len );
+ hashIter( &HASHcontext, HASHdigest,
+ (unsigned char *)values[i].bv_val, values[i].bv_len );
ber_dupbv_x( &keys[i], &digest, ctx );
}
keys = slap_sl_malloc( sizeof( struct berval ) * 2, ctx );
- hashDigestify( &HASHcontext, HASHdigest, prefix, 0,
- syntax, mr, (unsigned char *)value->bv_val, value->bv_len );
+ hashPreset( &HASHcontext, prefix, 0, syntax, mr );
+ hashIter( &HASHcontext, HASHdigest,
+ (unsigned char *)value->bv_val, value->bv_len );
ber_dupbv_x( keys, &digest, ctx );
BER_BVZERO( &keys[1] );
size_t slen, mlen;
BerVarray keys;
- HASH_CONTEXT HASHcontext;
+ HASH_CONTEXT HCany, HCini, HCfin;
unsigned char HASHdigest[HASH_BYTES];
struct berval digest;
digest.bv_val = (char *)HASHdigest;
slen = syntax->ssyn_oidlen;
mlen = mr->smr_oidlen;
+ if ( flags & SLAP_INDEX_SUBSTR_ANY )
+ hashPreset( &HCany, prefix, SLAP_INDEX_SUBSTR_PREFIX, syntax, mr );
+ if( flags & SLAP_INDEX_SUBSTR_INITIAL )
+ hashPreset( &HCini, prefix, SLAP_INDEX_SUBSTR_INITIAL_PREFIX, syntax, mr );
+ if( flags & SLAP_INDEX_SUBSTR_FINAL )
+ hashPreset( &HCfin, prefix, SLAP_INDEX_SUBSTR_FINAL_PREFIX, syntax, mr );
+
nkeys = 0;
for ( i = 0; !BER_BVISNULL( &values[i] ); i++ ) {
ber_len_t j,max;
if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
( values[i].bv_len >= index_substr_any_len ) )
{
- char pre = SLAP_INDEX_SUBSTR_PREFIX;
max = values[i].bv_len - (index_substr_any_len - 1);
for( j=0; j<max; j++ ) {
- hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
- syntax, mr, (unsigned char *)&values[i].bv_val[j], index_substr_any_len);
+ hashIter( &HCany, HASHdigest,
+ (unsigned char *)&values[i].bv_val[j],
+ index_substr_any_len );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
}
? index_substr_if_maxlen : values[i].bv_len;
for( j=index_substr_if_minlen; j<=max; j++ ) {
- char pre;
if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
- pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
- hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
- syntax, mr, (unsigned char *)values[i].bv_val, j );
+ hashIter( &HCini, HASHdigest,
+ (unsigned char *)values[i].bv_val, j );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
- pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
- hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
- syntax, mr, (unsigned char *)&values[i].bv_val[values[i].bv_len-j], j );
+ hashIter( &HCfin, HASHdigest,
+ (unsigned char *)&values[i].bv_val[values[i].bv_len-j], j );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
klen = index_substr_if_maxlen < value->bv_len
? index_substr_if_maxlen : value->bv_len;
- hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
- syntax, mr, (unsigned char *)value->bv_val, klen );
+ hashPreset( &HASHcontext, prefix, pre, syntax, mr );
+ hashIter( &HASHcontext, HASHdigest,
+ (unsigned char *)value->bv_val, klen );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
/* If initial is too long and we have subany indexed, use it
{
ber_len_t j;
pre = SLAP_INDEX_SUBSTR_PREFIX;
+ hashPreset( &HASHcontext, prefix, pre, syntax, mr);
for ( j=index_substr_if_maxlen-1; j <= value->bv_len - index_substr_any_len; j+=index_substr_any_step )
{
- hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
- syntax, mr, (unsigned char *)&value->bv_val[j], index_substr_any_len );
+ hashIter( &HASHcontext, HASHdigest,
+ (unsigned char *)&value->bv_val[j], index_substr_any_len );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
}
value = &sa->sa_any[i];
+ hashPreset( &HASHcontext, prefix, pre, syntax, mr);
for(j=0;
j <= value->bv_len - index_substr_any_len;
j += index_substr_any_step )
{
- hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
- syntax, mr, (unsigned char *)&value->bv_val[j], klen );
+ hashIter( &HASHcontext, HASHdigest,
+ (unsigned char *)&value->bv_val[j], klen );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
}
klen = index_substr_if_maxlen < value->bv_len
? index_substr_if_maxlen : value->bv_len;
- hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
- syntax, mr, (unsigned char *)&value->bv_val[value->bv_len-klen], klen );
+ hashPreset( &HASHcontext, prefix, pre, syntax, mr );
+ hashIter( &HASHcontext, HASHdigest,
+ (unsigned char *)&value->bv_val[value->bv_len-klen], klen );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
/* If final is too long and we have subany indexed, use it
{
ber_len_t j;
pre = SLAP_INDEX_SUBSTR_PREFIX;
+ hashPreset( &HASHcontext, prefix, pre, syntax, mr);
for ( j=0; j <= value->bv_len - index_substr_if_maxlen; j+=index_substr_any_step )
{
- hashDigestify( &HASHcontext, HASHdigest, prefix, pre,
- syntax, mr, (unsigned char *)&value->bv_val[j], index_substr_any_len );
+ hashIter( &HASHcontext, HASHdigest,
+ (unsigned char *)&value->bv_val[j], index_substr_any_len );
ber_dupbv_x( &keys[nkeys++], &digest, ctx );
}
}
#ifdef LDAP_DEVEL
+#define SLAP_LIGHTWEIGHT_DISPATCHER /* experimental slapd architecture */
+#define SLAP_MULTI_CONN_ARRAY
+#ifdef LDAP_PVT_THREAD_POOL_SEM_LOAD_CONTROL
+#define SLAP_SEM_LOAD_CONTROL
+#endif /* LDAP_PVT_THREAD_POOL_SEM_LOAD_CONTROL */
+
#define SLAP_ACL_HONOR_DISCLOSE /* partially implemented */
#define SLAP_ACL_HONOR_MANAGE /* not yet implemented */
#define SLAP_DYNACL
BerElement *o_res_ber; /* ber of the CLDAP reply or readback control */
slap_callback *o_callback; /* callback pointers */
LDAPControl **o_ctrls; /* controls */
+ struct berval o_csn;
void *o_private; /* anything the backend needs */
#ifdef LDAP_CONNECTIONLESS
int sl_is_udp; /* UDP listener is also data port */
#endif
- int sl_is_mute; /* Listening is temporarily disabled */
+ int sl_mute; /* Listener is temporarily disabled due to emfile */
+#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+ int sl_busy; /* Listener is busy (accept thread activated) */
+#endif
ber_socket_t sl_sd;
Sockaddr sl_sa;
#define sl_addr sl_sa.sa_in_addr
break;
case SLAPADD:
- options = " [-c]\n\t[-n databasenumber | -b suffix]\n"
+ options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]\n"
"\t[-l ldiffile] [-q] [-u] [-w]\n";
break;
break;
case SLAPCAT:
- options = " [-c]\n\t[-n databasenumber | -b suffix]"
+ options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]"
" [-l ldiffile] [-a filter]\n";
break;
break;
case SLAPINDEX:
- options = " [-c]\n\t[-n databasenumber | -b suffix] [-q]\n";
+ options = " [-c]\n\t[-g] [-n databasenumber | -b suffix] [-q]\n";
break;
case SLAPTEST:
int rc, i, dbnum;
int mode = SLAP_TOOL_MODE;
int truncatemode = 0;
+ int use_glue = 1;
#ifdef CSRIMALLOC
leakfilename = malloc( strlen( progname ) + STRLENOF( ".leak" ) + 1 );
switch( tool ) {
case SLAPADD:
- options = "b:cd:f:F:l:n:qtuvw";
+ options = "b:cd:f:F:gl:n:qtuvw";
break;
case SLAPCAT:
- options = "a:b:cd:f:F:l:n:s:v";
+ options = "a:b:cd:f:F:gl:n:s:v";
mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
break;
break;
case SLAPINDEX:
- options = "b:cd:f:F:n:qv";
+ options = "b:cd:f:F:gn:qv";
mode |= SLAP_TOOL_READMAIN;
break;
break;
case 'd': /* turn on debugging */
- ldap_debug += atoi( optarg );
+#ifdef LDAP_DEBUG
+ if ( optarg != NULL && optarg[ 0 ] != '-' && !isdigit( optarg[ 0 ] ) )
+ {
+ int level;
+
+ if ( str2loglevel( optarg, &level ) ) {
+ fprintf( stderr,
+ "unrecognized log level "
+ "\"%s\"\n", optarg );
+ exit( EXIT_FAILURE );
+ }
+
+ ldap_debug |= level;
+
+ } else {
+ int level;
+ char *next = NULL;
+
+ level = strtol( optarg, &next, 0 );
+ if ( next == NULL || next[ 0 ] != '\0' ) {
+ fprintf( stderr,
+ "unrecognized log level "
+ "\"%s\"\n", optarg );
+ exit( EXIT_FAILURE );
+ }
+ ldap_debug |= level;
+ }
+#else
+ if ( atoi( optarg ) != 0 )
+ fputs( "must compile with LDAP_DEBUG for debugging\n",
+ stderr );
+#endif
break;
case 'D':
confdir = strdup( optarg );
break;
+ case 'g': /* disable subordinate glue */
+ use_glue = 0;
+ break;
+
case 'l': /* LDIF file */
ldiffile = strdup( optarg );
break;
break;
}
- rc = glue_sub_attach();
+ if ( use_glue ) {
+ rc = glue_sub_attach();
- if ( rc != 0 ) {
- fprintf( stderr, "%s: subordinate configuration error\n", progname );
- exit( EXIT_FAILURE );
+ if ( rc != 0 ) {
+ fprintf( stderr,
+ "%s: subordinate configuration error\n", progname );
+ exit( EXIT_FAILURE );
+ }
}
rc = slap_schema_check();
PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_DELETE );
slapi_int_func_internal_pb( pb, op_delete );
- slap_graduate_commit_csn( pb->pb_op );
return 0;
}
}
cleanup:
- slap_graduate_commit_csn( pb->pb_op );
if ( pb->pb_op->ora_e != NULL ) {
slapi_entry_free( pb->pb_op->ora_e );
slapi_int_func_internal_pb( pb, op_modrdn );
cleanup:
- slap_graduate_commit_csn( pb->pb_op );
return 0;
}
slapi_int_func_internal_pb( pb, op_modify );
cleanup:
- slap_graduate_commit_csn( pb->pb_op );
return 0;
}
#include <ac/ctype.h>
#include <ac/string.h>
#include <ac/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <ac/unistd.h>
+#include <ac/errno.h>
#include <lber.h>
#include <ldif.h>
#include "slapcommon.h"
+static int
+test_file( const char *fname, const char *ftype )
+{
+ struct stat st;
+ int save_errno;
+
+ switch ( stat( fname, &st ) ) {
+ case 0:
+ if ( !( st.st_mode & S_IWUSR ) ) {
+ Debug( LDAP_DEBUG_ANY, "%s file "
+ "\"%s\" exists, but user does not have access\n",
+ ftype, fname, 0 );
+ return -1;
+ }
+ break;
+
+ case -1:
+ default:
+ save_errno = errno;
+ if ( save_errno == ENOENT ) {
+ FILE *fp = fopen( fname, "w" );
+
+ if ( fp == NULL ) {
+ save_errno = errno;
+
+ Debug( LDAP_DEBUG_ANY, "unable to open file "
+ "\"%s\": %d (%s)\n",
+ fname,
+ save_errno, strerror( save_errno ) );
+
+ return -1;
+ }
+ unlink( fname );
+ break;
+ }
+
+ Debug( LDAP_DEBUG_ANY, "unable to stat file "
+ "\"%s\": %d (%s)\n",
+ slapd_pid_file,
+ save_errno, strerror( save_errno ) );
+ return -1;
+ }
+}
+
int
slaptest( int argc, char **argv )
{
slap_tool_init( progname, SLAPTEST, argc, argv );
+ if ( slapd_pid_file != NULL ) {
+ if ( test_file( slapd_pid_file, "pid" ) ) {
+ return EXIT_FAILURE;
+ }
+ }
+
+ if ( slapd_args_file != NULL ) {
+ if ( test_file( slapd_args_file, "args" ) ) {
+ return EXIT_FAILURE;
+ }
+ }
+
fprintf( stderr, "config file testing succeeded\n");
slap_tool_destroy();
#define SYNCDATA_ACCESSLOG 1 /* entries are accesslog format */
#define SYNCDATA_CHANGELOG 2 /* entries are changelog format */
+#define SYNCLOG_LOGGING 0 /* doing a log-based update */
+#define SYNCLOG_FALLBACK 1 /* doing a full refresh */
+
typedef struct syncinfo_s {
struct slap_backend_db *si_be;
struct re_s *si_re;
long si_rid;
struct berval si_provideruri;
slap_bindconf si_bindconf;
- struct berval si_filterstr;
struct berval si_base;
+ struct berval si_logbase;
+ struct berval si_filterstr;
+ struct berval si_logfilterstr;
int si_scope;
int si_attrsonly;
char *si_anfile;
int si_allattrs;
int si_allopattrs;
int si_schemachecking;
- int si_type;
+ int si_type; /* the active type */
+ int si_ctype; /* the configured type */
time_t si_interval;
time_t *si_retryinterval;
int *si_retrynum_init;
int si_refreshDelete;
int si_refreshPresent;
int si_syncdata;
+ int si_logstate;
+ int si_conn_setup;
Avlnode *si_presentlist;
LDAP *si_ld;
LDAP_LIST_HEAD(np, nonpresent_entry) si_nonpresentlist;
si->si_exattrs = exattrs;
}
+typedef struct logschema {
+ struct berval ls_dn;
+ struct berval ls_req;
+ struct berval ls_mod;
+ struct berval ls_newRdn;
+ struct berval ls_delRdn;
+ struct berval ls_newSup;
+} logschema;
+
+static logschema changelog_sc = {
+ BER_BVC("targetDN"),
+ BER_BVC("changeType"),
+ BER_BVC("changes"),
+ BER_BVC("newRDN"),
+ BER_BVC("deleteOldRDN"),
+ BER_BVC("newSuperior")
+};
+
+static logschema accesslog_sc = {
+ BER_BVC("reqDN"),
+ BER_BVC("reqType"),
+ BER_BVC("reqMod"),
+ BER_BVC("reqNewRDN"),
+ BER_BVC("reqDeleteOldRDN"),
+ BER_BVC("reqNewSuperior")
+};
+
static int
ldap_sync_search(
syncinfo_t *si,
struct timeval timeout;
ber_int_t msgid;
int rc;
+ int rhint;
+ char *base;
+ char **attrs, *lattrs[8];
+ char *filter;
+ int attrsonly;
+ int scope;
/* setup LDAP SYNC control */
ber_init2( ber, NULL, LBER_USE_DER );
ber_set_option( ber, LBER_OPT_BER_MEMCTX, &ctx );
+ /* If we're using a log but we have no state, then fallback to
+ * normal mode for a full refresh.
+ */
+ if ( si->si_syncdata && BER_BVISEMPTY( &si->si_syncCookie.ctxcsn ))
+ si->si_logstate = SYNCLOG_FALLBACK;
+
+ /* Use the log parameters if we're in log mode */
+ if ( si->si_syncdata && si->si_logstate == SYNCLOG_LOGGING ) {
+ logschema *ls;
+ if ( si->si_syncdata == SYNCDATA_ACCESSLOG )
+ ls = &accesslog_sc;
+ else
+ ls = &changelog_sc;
+ lattrs[0] = ls->ls_dn.bv_val;
+ lattrs[1] = ls->ls_req.bv_val;
+ lattrs[2] = ls->ls_mod.bv_val;
+ lattrs[3] = ls->ls_newRdn.bv_val;
+ lattrs[4] = ls->ls_delRdn.bv_val;
+ lattrs[5] = ls->ls_newSup.bv_val;
+ lattrs[6] = slap_schema.si_ad_entryCSN->ad_cname.bv_val;
+ lattrs[7] = NULL;
+
+ rhint = 0;
+ base = si->si_logbase.bv_val;
+ filter = si->si_logfilterstr.bv_val;
+ attrs = lattrs;
+ attrsonly = 0;
+ scope = LDAP_SCOPE_ONELEVEL;
+ } else {
+ rhint = 1;
+ base = si->si_base.bv_val;
+ filter = si->si_filterstr.bv_val;
+ attrs = si->si_attrs;
+ attrsonly = si->si_attrsonly;
+ scope = si->si_scope;
+ }
+ if ( si->si_syncdata && si->si_logstate == SYNCLOG_FALLBACK ) {
+ si->si_type = LDAP_SYNC_REFRESH_ONLY;
+ } else {
+ si->si_type = si->si_ctype;
+ }
+
if ( !BER_BVISNULL( &si->si_syncCookie.octet_str ) )
{
- ber_printf( ber, "{eO}",
- abs(si->si_type),
- &si->si_syncCookie.octet_str );
+ ber_printf( ber, "{eOb}",
+ abs(si->si_type), &si->si_syncCookie.octet_str, rhint );
} else {
- ber_printf( ber, "{e}",
- abs(si->si_type) );
+ ber_printf( ber, "{eb}",
+ abs(si->si_type), rhint );
}
if ( (rc = ber_flatten2( ber, &c[0].ldctl_value, 0 )) == LBER_ERROR ) {
timeout.tv_sec = si->si_tlimit;
timeout.tv_usec = 0;
- rc = ldap_search_ext( si->si_ld, si->si_base.bv_val, si->si_scope,
- si->si_filterstr.bv_val, si->si_attrs, si->si_attrsonly,
+ rc = ldap_search_ext( si->si_ld, base, scope, filter, attrs, attrsonly,
ctrls, NULL, si->si_tlimit > 0 ? &timeout : NULL,
si->si_slimit, &msgid );
ber_free_buf( ber );
slap_parse_sync_cookie( &syncCookie, NULL );
}
}
- if ( si->si_syncdata ) {
+ if ( si->si_syncdata && si->si_logstate == SYNCLOG_LOGGING ) {
entry = NULL;
modlist = NULL;
if ( syncrepl_message_to_op( si, op, msg ) == LDAP_SUCCESS &&
"do_syncrep2: LDAP_RES_SEARCH_RESULT\n", 0, 0, 0 );
ldap_parse_result( si->si_ld, msg, &err, NULL, NULL, NULL,
&rctrls, 0 );
+#ifdef LDAP_X_SYNC_REFRESH_REQUIRED
+ if ( err == LDAP_X_SYNC_REFRESH_REQUIRED ) {
+ /* map old result code to registered code */
+ err = LDAP_SYNC_REFRESH_REQUIRED;
+ }
+#endif
+ if ( err == LDAP_SYNC_REFRESH_REQUIRED ) {
+ if ( si->si_logstate == SYNCLOG_LOGGING ) {
+ si->si_logstate = SYNCLOG_FALLBACK;
+ }
+ rc = err;
+ break;
+ }
if ( rctrls ) {
rctrlp = *rctrls;
ber_init2( ber, &rctrlp->ldctl_value, LBER_USE_DER );
si->si_presentlist = NULL;
}
}
- rc = -2;
+ if ( err == LDAP_SUCCESS
+ && si->si_logstate == SYNCLOG_FALLBACK ) {
+ si->si_logstate = SYNCLOG_LOGGING;
+ rc = LDAP_SYNC_REFRESH_REQUIRED;
+ } else {
+ rc = -2;
+ }
goto done;
break;
if ( res ) ldap_msgfree( res );
- if ( rc && si->si_ld ) {
+ if ( rc && rc != LDAP_SYNC_REFRESH_REQUIRED && si->si_ld ) {
+ if ( si->si_conn_setup ) {
+ ber_socket_t s;
+ ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
+ connection_client_stop( s );
+ si->si_conn_setup = 0;
+ }
ldap_unbind_ext( si->si_ld, NULL, NULL );
si->si_ld = NULL;
}
OperationBuffer opbuf;
Operation *op;
int rc = LDAP_SUCCESS;
- int first = 0;
int dostop = 0;
ber_socket_t s;
int i, defer = 1;
if ( slapd_shutdown ) {
if ( si->si_ld ) {
- ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
- connection_client_stop( s );
+ if ( si->si_conn_setup ) {
+ ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
+ connection_client_stop( s );
+ si->si_conn_setup = 0;
+ }
ldap_unbind_ext( si->si_ld, NULL, NULL );
si->si_ld = NULL;
}
/* Establish session, do search */
if ( !si->si_ld ) {
- first = 1;
si->si_refreshDelete = 0;
si->si_refreshPresent = 0;
rc = do_syncrep1( op, si );
}
+reload:
/* Process results */
if ( rc == LDAP_SUCCESS ) {
ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
rc = do_syncrep2( op, si );
+ if ( rc == LDAP_SYNC_REFRESH_REQUIRED ) {
+ rc = ldap_sync_search( si, op->o_tmpmemctx );
+ goto reload;
+ }
if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST ) {
/* If we succeeded, enable the connection for further listening.
* If we failed, tear down the connection and reschedule.
*/
if ( rc == LDAP_SUCCESS ) {
- if ( first ) {
- rc = connection_client_setup( s, do_syncrepl, arg );
- } else {
+ if ( si->si_conn_setup ) {
connection_client_enable( s );
+ } else {
+ rc = connection_client_setup( s, do_syncrepl, arg );
+ if ( rc == 0 )
+ si->si_conn_setup = 1;
}
- } else if ( !first ) {
+ } else if ( si->si_conn_setup ) {
dostop = 1;
}
} else {
return NULL;
}
-typedef struct logschema {
- struct berval ls_dn;
- struct berval ls_req;
- struct berval ls_mod;
- struct berval ls_newRdn;
- struct berval ls_delRdn;
- struct berval ls_newSup;
-} logschema;
-
-static logschema changelog_sc = {
- BER_BVC("targetDN"),
- BER_BVC("changeType"),
- BER_BVC("changes"),
- BER_BVC("newRDN"),
- BER_BVC("deleteOldRDN"),
- BER_BVC("newSuperior")
-};
-
-static logschema accesslog_sc = {
- BER_BVC("reqDN"),
- BER_BVC("reqType"),
- BER_BVC("reqMod"),
- BER_BVC("reqNewRDN"),
- BER_BVC("reqDeleteOldRDN"),
- BER_BVC("reqNewSuperior")
-};
-
static slap_verbmasks modops[] = {
{ BER_BVC("add"), LDAP_REQ_ADD },
{ BER_BVC("delete"), LDAP_REQ_DELETE },
*modtail = mod;
modtail = &mod->sml_next;
}
- bv.bv_val = colon + 3;
- bv.bv_len = vals[i].bv_len - ( bv.bv_val - vals[i].bv_val );
- ber_dupbv( &bv2, &bv );
- ber_bvarray_add( &mod->sml_values, &bv2 );
+ if ( colon[2] == ' ' ) {
+ bv.bv_val = colon + 3;
+ bv.bv_len = vals[i].bv_len - ( bv.bv_val - vals[i].bv_val );
+ ber_dupbv( &bv2, &bv );
+ ber_bvarray_add( &mod->sml_values, &bv2 );
+ }
}
return modlist;
}
deleteOldRdn = 1;
} else if ( !ber_bvstrcasecmp( &bv, &ls->ls_newSup )) {
sup = bvals[0];
+ } else if ( !ber_bvstrcasecmp( &bv,
+ &slap_schema.si_ad_entryCSN->ad_cname )) {
+ slap_queue_csn( op, bvals );
}
ch_free( bvals );
}
op->orr_deleteoldrdn = deleteOldRdn;
rc = op->o_bd->be_modrdn( op, &rs );
break;
+ case LDAP_REQ_DELETE:
+ rc = op->o_bd->be_delete( op, &rs );
+ break;
}
done:
+ slap_graduate_commit_csn( op );
if ( modlist )
slap_mods_free( modlist, op->o_tag != LDAP_REQ_ADD );
if ( !BER_BVISNULL( &rdn )) {
switch ( syncstate ) {
case LDAP_SYNC_ADD:
case LDAP_SYNC_MODIFY:
+ {
+ Attribute *a = attr_find( entry->e_attrs, slap_schema.si_ad_entryCSN );
+ if ( a )
+ op->o_csn = a->a_vals[0];
+ }
retry_add:;
if ( BER_BVISNULL( &dni.dn )) {
if ( !BER_BVISNULL( &dni.dn ) ) {
op->o_tmpfree( dni.dn.bv_val, op->o_tmpmemctx );
}
+ BER_BVZERO( &op->o_csn );
return ret;
}
#define SYNCDATASTR "syncdata"
/* FIXME: undocumented */
+#define LOGBASESTR "logbase"
+#define LOGFILTERSTR "logfilter"
#define OLDAUTHCSTR "bindprincipal"
#define EXATTRSSTR "exattrs"
#define MANAGEDSAITSTR "manageDSAit"
if ( si->si_filterstr.bv_val )
ch_free( si->si_filterstr.bv_val );
ber_str2bv( val, 0, 1, &si->si_filterstr );
+ } else if ( !strncasecmp( cargv[ i ], LOGFILTERSTR "=",
+ STRLENOF( LOGFILTERSTR "=" ) ) )
+ {
+ val = cargv[ i ] + STRLENOF( LOGFILTERSTR "=" );
+ if ( si->si_logfilterstr.bv_val )
+ ch_free( si->si_logfilterstr.bv_val );
+ ber_str2bv( val, 0, 1, &si->si_logfilterstr );
} else if ( !strncasecmp( cargv[ i ], SEARCHBASESTR "=",
STRLENOF( SEARCHBASESTR "=" ) ) )
{
val, rc, ldap_err2string( rc ) );
return -1;
}
+ } else if ( !strncasecmp( cargv[ i ], LOGBASESTR "=",
+ STRLENOF( LOGBASESTR "=" ) ) )
+ {
+ struct berval bv;
+ int rc;
+
+ val = cargv[ i ] + STRLENOF( LOGBASESTR "=" );
+ if ( si->si_logbase.bv_val ) {
+ ch_free( si->si_logbase.bv_val );
+ }
+ ber_str2bv( val, 0, 0, &bv );
+ rc = dnNormalize( 0, NULL, NULL, &bv, &si->si_logbase, NULL );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "Invalid logbase DN \"%s\": %d (%s)\n",
+ val, rc, ldap_err2string( rc ) );
+ return -1;
+ }
} else if ( !strncasecmp( cargv[ i ], SCOPESTR "=",
STRLENOF( SCOPESTR "=" ) ) )
{
if ( !strncasecmp( val, "refreshOnly",
STRLENOF("refreshOnly") ))
{
- si->si_type = LDAP_SYNC_REFRESH_ONLY;
+ si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_ONLY;
} else if ( !strncasecmp( val, "refreshAndPersist",
STRLENOF("refreshAndPersist") ))
{
- si->si_type = LDAP_SYNC_REFRESH_AND_PERSIST;
+ si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_AND_PERSIST;
si->si_interval = 60;
} else {
fprintf( stderr, "Error: parse_syncrepl_line: "
si->si_allattrs = 0;
si->si_allopattrs = 0;
si->si_exattrs = NULL;
- si->si_type = LDAP_SYNC_REFRESH_ONLY;
+ si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_ONLY;
si->si_interval = 86400;
si->si_retryinterval = NULL;
si->si_retrynum_init = NULL;
si->si_manageDSAit = 0;
si->si_tlimit = 0;
si->si_slimit = 0;
+ si->si_conn_setup = 0;
si->si_presentlist = NULL;
LDAP_LIST_INIT( &si->si_nonpresentlist );
ptr = lutil_strcopy( ptr, si->si_base.bv_val );
*ptr++ = '"';
}
+ if ( !BER_BVISEMPTY( &si->si_logfilterstr )) {
+ ptr = lutil_strcopy( ptr, " " LOGFILTERSTR "=\"" );
+ ptr = lutil_strcopy( ptr, si->si_logfilterstr.bv_val );
+ *ptr++ = '"';
+ }
+ if ( !BER_BVISNULL( &si->si_logbase )) {
+ ptr = lutil_strcopy( ptr, " " LOGBASESTR "=\"" );
+ ptr = lutil_strcopy( ptr, si->si_logbase.bv_val );
+ *ptr++ = '"';
+ }
for (i=0; !BER_BVISNULL(&scopes[i].key);i++) {
if ( si->si_scope == scopes[i].val ) {
ptr = lutil_strcopy( ptr, " " SCOPESTR "=" );
## <http://www.OpenLDAP.org/license.html>.
PROGRAMS = slapd-tester slapd-search slapd-read slapd-addel slapd-modrdn \
- slapd-modify
+ slapd-modify slapd-bind
SRCS = slapd-tester.c slapd-search.c slapd-read.c slapd-addel.c \
- slapd-modrdn.c slapd-modify.c
+ slapd-modrdn.c slapd-modify.c slapd-bind.c
LDAP_INCDIR= ../../include
LDAP_LIBDIR= ../../libraries
slapd-modify: slapd-modify.o $(XLIBS)
$(LTLINK) -o $@ slapd-modify.o $(LIBS)
+
+slapd-bind: slapd-bind.o $(XLIBS)
+ $(LTLINK) -o $@ slapd-bind.o $(LIBS)
--- /dev/null
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1999-2005 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Howard Chu for inclusion
+ * in OpenLDAP Software.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+
+#include <ac/ctype.h>
+#include <ac/param.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+#include <ac/wait.h>
+
+#define LDAP_DEPRECATED 1
+#include <ldap.h>
+#include <lutil.h>
+
+#define LOOPS 100
+
+static int
+do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop );
+
+static int
+do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop );
+
+/* This program can be invoked two ways: if -D is used to specify a Bind DN,
+ * that DN will be used repeatedly for all of the Binds. If instead -b is used
+ * to specify a base DN, a search will be done for all "person" objects under
+ * that base DN. Then DNs from this list will be randomly selected for each
+ * Bind request. All of the users must have identical passwords. Also it is
+ * assumed that the users are all onelevel children of the base.
+ */
+static void
+usage( char *name )
+{
+ fprintf( stderr, "usage: %s [-h <host>] -p port (-D <dn>|-b <baseDN>) -w <passwd> [-l <loops>]\n",
+ name );
+ exit( EXIT_FAILURE );
+}
+
+static char *filter = "(objectClass=person)";
+
+int
+main( int argc, char **argv )
+{
+ int i;
+ char *uri = NULL;
+ char *host = "localhost";
+ char *dn = NULL;
+ char *base = NULL;
+ char *pass = NULL;
+ int port = -1;
+ int loops = LOOPS;
+
+ while ( (i = getopt( argc, argv, "b:H:h:p:D:w:l:" )) != EOF ) {
+ switch( i ) {
+ case 'b': /* base DN of a tree of user DNs */
+ base = strdup( optarg );
+ break;
+
+ case 'H': /* the server uri */
+ uri = strdup( optarg );
+ break;
+ case 'h': /* the servers host */
+ host = strdup( optarg );
+ break;
+
+ case 'p': /* the servers port */
+ port = atoi( optarg );
+ break;
+
+ case 'D':
+ dn = strdup( optarg );
+ break;
+
+ case 'w':
+ pass = strdup( optarg );
+ break;
+
+ case 'l': /* the number of loops */
+ loops = atoi( optarg );
+ break;
+
+ default:
+ usage( argv[0] );
+ break;
+ }
+ }
+
+ if ( port == -1 && uri == NULL )
+ usage( argv[0] );
+
+ if ( base )
+ do_base( uri, host, port, base, pass, ( 20 * loops ));
+ else
+ do_bind( uri, host, port, dn, pass, ( 20 * loops ));
+ exit( EXIT_SUCCESS );
+}
+
+
+static int
+do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop )
+{
+ LDAP *ld = NULL;
+ int i, rc;
+ char *attrs[] = { "1.1", NULL };
+ pid_t pid = getpid();
+
+ if ( maxloop > 1 )
+ fprintf( stderr, "PID=%ld - Bind(%d): dn=\"%s\".\n",
+ (long) pid, maxloop, dn );
+
+ for ( i = 0; i < maxloop; i++ ) {
+ LDAPMessage *res;
+
+ if ( uri ) {
+ ldap_initialize( &ld, uri );
+ } else {
+ ld = ldap_init( host, port );
+ }
+ if ( ld == NULL ) {
+ perror( "ldap_init" );
+ rc = -1;
+ break;
+ }
+
+ {
+ int version = LDAP_VERSION3;
+ (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
+ &version );
+ }
+
+ rc = ldap_bind_s( ld, dn, pass, LDAP_AUTH_SIMPLE );
+ if ( rc != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_bind" );
+ }
+ ldap_unbind( ld );
+ if ( rc != LDAP_SUCCESS ) {
+ break;
+ }
+ }
+
+ if ( maxloop > 1 )
+ fprintf( stderr, " PID=%ld - Bind done.\n", (long) pid );
+
+ return rc;
+}
+
+
+static int
+do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop )
+{
+ LDAP *ld = NULL;
+ int i = 0;
+ pid_t pid = getpid();
+ int rc = LDAP_SUCCESS;
+ ber_int_t msgid;
+ LDAPMessage *res, *msg;
+ char **rdns = NULL;
+ char *attrs[] = { "dn", NULL };
+ int nrdns = 0;
+ time_t beg, end;
+
+ srand(pid);
+
+ if ( uri ) {
+ ldap_initialize( &ld, uri );
+ } else {
+ ld = ldap_init( host, port );
+ }
+ if ( ld == NULL ) {
+ perror( "ldap_init" );
+ exit( EXIT_FAILURE );
+ }
+
+ {
+ int version = LDAP_VERSION3;
+ (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
+ &version );
+ }
+ (void) ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
+
+ rc = ldap_bind_s( ld, NULL, NULL, LDAP_AUTH_SIMPLE );
+ if ( rc != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_bind" );
+ exit( EXIT_FAILURE );
+ }
+
+ rc = ldap_search_ext( ld, base, LDAP_SCOPE_ONE,
+ filter, attrs, 0, NULL, NULL, 0, 0, &msgid );
+ if ( rc != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_ex" );
+ exit( EXIT_FAILURE );
+ }
+
+ while (( rc=ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res )) >0){
+ BerElement *ber;
+ struct berval bv;
+ char *ptr;
+ int done = 0;
+
+ for (msg = ldap_first_message( ld, res ); msg;
+ msg = ldap_next_message( ld, msg )) {
+ switch ( ldap_msgtype( msg )) {
+ case LDAP_RES_SEARCH_ENTRY:
+ rc = ldap_get_dn_ber( ld, msg, &ber, &bv );
+ ptr = strchr( bv.bv_val, ',');
+ i = ptr-bv.bv_val;
+ rdns = realloc( rdns, (nrdns+1)*sizeof(char *));
+ rdns[nrdns] = malloc( i+1 );
+ strncpy(rdns[nrdns], bv.bv_val, i );
+ rdns[nrdns][i] = '\0';
+ nrdns++;
+ ber_free( ber, 0 );
+ break;
+ case LDAP_RES_SEARCH_RESULT:
+ done = 1;
+ break;
+ }
+ if ( done )
+ break;
+ }
+ ldap_msgfree( res );
+ if ( done ) break;
+ }
+ ldap_unbind( ld );
+
+ beg = time(0L);
+ /* Ok, got list of RDNs, now start binding to each */
+ for (i=0; i<maxloop; i++) {
+ char dn[BUFSIZ], *ptr;
+ int j = rand() % nrdns;
+ ptr = lutil_strcopy(dn, rdns[j]);
+ *ptr++ = ',';
+ strcpy(ptr, base);
+ if ( do_bind( uri, host, port, dn, pass, 1 ))
+ break;
+ }
+ end = time(0L);
+ fprintf( stderr, "Done %d Binds in %d seconds.\n", i, end - beg );
+ return 0;
+}
AC_sql=sql@BUILD_SQL@
# overlays
+AC_accesslog=accesslog@BUILD_ACCESSLOG@
AC_pcache=pcache@BUILD_PROXYCACHE@
AC_ppolicy=ppolicy@BUILD_PPOLICY@
AC_refint=refint@BUILD_REFINT@
export AC_bdb AC_hdb AC_ldap AC_ldbm AC_meta AC_monitor AC_relay AC_sql
export AC_pcache AC_ppolicy AC_refint AC_retcode AC_rwm AC_unique AC_syncprov
export AC_translucent AC_WITH_SASL AC_WITH_TLS AC_WITH_MODULES_ENABLED AC_ACI_ENABLED
-export AC_valsort
+export AC_valsort AC_accesslog
if test ! -x ../servers/slapd/slapd ; then
echo "Could not locate slapd(8)"
-e "s/^#${AC_relay}#//" \
-e "s/^#${AC_sql}#//" \
-e "s/^#${RDBMS}#//" \
+ -e "s/^#${AC_accesslog}#//" \
-e "s/^#${AC_pcache}#//" \
-e "s/^#${AC_ppolicy}#//" \
-e "s/^#${AC_refint}#//" \
## <http://www.OpenLDAP.org/license.html>.
MONITORDB=${AC_monitor-no}
+ACCESSLOG=${AC_accesslog-accesslogno}
BACKLDAP=${AC_ldap-ldapno}
BACKMETA=${AC_meta-metano}
BACKRELAY=${AC_relay-relayno}
RCONF=$DATADIR/slapd-referrals.conf
MASTERCONF=$DATADIR/slapd-repl-master.conf
SRMASTERCONF=$DATADIR/slapd-syncrepl-master.conf
+DSRMASTERCONF=$DATADIR/slapd-deltasync-master.conf
+DSRSLAVECONF=$DATADIR/slapd-deltasync-slave.conf
SLAVECONF=$DATADIR/slapd-repl-slave.conf
PPOLICYCONF=$DATADIR/slapd-ppolicy.conf
PROXYCACHECONF=$DATADIR/slapd-proxycache.conf
## If you use this script then
## Make sure that you turn on LDAP_COMP_MATCH in slapd source codes
-## and --enable-modules is configured yes
+## and --enable-modules is configured yes
if test "$AC_WITH_MODULES_ENABLED" != "yes" ; then
echo "dynamic module disabled, test skipped"
exit 0
exit $RC
fi
-FILTER="(userCertificate:componentFilterMatch:=item:{component \"toBeSigned.extensions.\2a.extnID\",rule allComponentsMatch, value 2.5.29.14 })"
+FILTER="(userCertificate:componentFilterMatch:=item:{ component \"toBeSigned.extensions.\2a.extnID\", rule allComponentsMatch, value 2.5.29.14 })"
echo " f=$FILTER ..."
echo "# f=$FILTER ..." >> $SEARCHOUT
$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
exit $RC
fi
-FILTER="(userCertificate:componentFilterMatch:=not:item:{component \"toBeSigned.extensions.\2a\",rule allComponentsMatch, value { extnID 2.5.29.19 , extnValue '30030101FF'H })"
+FILTER="(userCertificate:componentFilterMatch:=not:item:{ component \"toBeSigned.extensions.\2a\", rule allComponentsMatch, value { extnID 2.5.29.19 , extnValue '30030101FF'H })"
echo " f=$FILTER ..."
echo "# f=$FILTER ..." >> $SEARCHOUT
$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
exit $RC
fi
+# extraction filter
FILTER="(x509CertificateIssuer=c=US)"
echo " f=$FILTER ..."
echo "# f=$FILTER ..." >> $SEARCHOUT
exit $RC
fi
+# extraction filter
FILTER="(x509CertificateSerial=0)"
echo " f=$FILTER ..."
echo "# f=$FILTER ..." >> $SEARCHOUT
exit $RC
fi
+# extraction filter
FILTER="(x509CertificateSerialAndIssuer:certificateExactMatch:=0\$c=US)"
echo " f=$FILTER ..."
echo "# f=$FILTER ..." >> $SEARCHOUT
;;
esac
+echo "Binding with incorrect password to database \"$BASEDN\"..."
+$LDAPWHOAMI -h $LOCALHOST -p $PORT3 \
+ -D "cn=Added User,ou=Same as above,ou=Meta,$BASEDN" \
+ -w bogus >> $TESTOUT 2>&1
+RC=$?
+#if test $RC != 0 ; then
+# echo "WhoAmI failed ($RC)!"
+# test $KILLSERVERS != no && kill -HUP $KILLPIDS
+# exit $RC
+#fi
+case $RC in
+ 0)
+ echo "WhoAmI should have failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit -1
+ ;;
+ 51)
+ echo "### Hit LDAP_BUSY problem; you may want to re-run the test"
+ ;;
+ *)
+ ;;
+esac
+
echo "Comparing to database \"$BASEDN\"..."
$LDAPCOMPARE -h $LOCALHOST -p $PORT3 \
"cn=Another Added Group,ou=Groups,$BASEDN" \
$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
if test $? != 0 ; then
- echo "comparison failed - meta search/modification didn't succeed"
+ echo "comparison failed - slapd-ldap search/modification didn't succeed"
exit 1
fi