#! /bin/sh
-# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.560.2.15 2005/09/28 00:30:27 kurt Exp .
+# From configure.in OpenLDAP: pkg/ldap/configure.in,v 1.560.2.16 2005/11/03 18:02:53 kurt Exp .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59.
#
# 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
withval="$with_tls"
ol_arg=invalid
- for ol_val in auto ssleay openssl yes no ; do
+ for ol_val in auto openssl yes no ; do
if test "$withval" = "$ol_val" ; then
ol_arg="$ol_val"
fi
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'*)
if test "${lt_cv_prog_gnu_ld+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
case `$LD -v 2>&1 </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
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
- case "`/usr/bin/file conftest.o`" in
+ case `/usr/bin/file conftest.o` in
*32-bit*)
case $host in
x86_64-*linux*)
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`
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"
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 -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
LDFLAGS="$LDFLAGS $lt_prog_compiler_static"
printf "$lt_simple_link_test_code" > conftest.$ac_ext
if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The compiler can only warn and ignore the option if not recognized
+ # The linker can only warn and ignore the option if not recognized
# So say no if there are warnings
if test -s conftest.err; then
# Append any errors to the config.log.
# with a dollar sign (not a hyphen), so the echo should work correctly.
# The option is referenced via a variable to avoid confusing sed.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7669: $lt_compile\"" >&5)
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_prog_compiler_wl='-Wl,'
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
lt_prog_compiler_pic='-KPIC'
lt_prog_compiler_static='-static'
;;
- pgcc* | pgf77* | pgf90*)
+ pgcc* | pgf77* | pgf90* | pgf95*)
# Portland Group compilers (*not* the Pentium gcc compiler,
# which looks to be a dead project)
lt_prog_compiler_wl='-Wl,'
lt_prog_compiler_pic='-fpic'
- lt_prog_compiler_static='-static'
+ lt_prog_compiler_static='-Bstatic'
;;
ccc*)
lt_prog_compiler_wl='-Wl,'
# with a dollar sign (not a hyphen), so the echo should work correctly.
# The option is referenced via a variable to avoid confusing sed.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7931: $lt_compile\"" >&5)
fi
fi
-case "$host_os" in
+case $host_os in
# For platforms which do not support PIC, -DPIC is meaningless:
*djgpp*)
lt_prog_compiler_pic=
# Note that $ac_compile itself does not contain backslashes and begins
# with a dollar sign (not a hyphen), so the echo should work correctly.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7993: $lt_compile\"" >&5)
lt_cv_prog_compiler_c_o=yes
fi
fi
- chmod u+w .
+ chmod u+w . 2>&5
$rm conftest*
# SGI C++ compiler will create directory out/ii_files/ for
# template instantiation
tmp_addflag=
case $cc_basename,$host_cpu in
pgcc*) # Portland Group C compiler
- whole_archive_flag_spec='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag'
;;
- pgf77* | pgf90* ) # Portland Group f77 and f90 compilers
- whole_archive_flag_spec='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
tmp_addflag=' $pic_flag -Mnomain' ;;
ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
tmp_addflag=' -i_dynamic' ;;
# Exported symbols can be pulled into shared objects from archives
whole_archive_flag_spec=' '
archive_cmds_need_lc=yes
- # This is similar to how AIX traditionally builds it's shared libraries.
+ # This is similar to how AIX traditionally builds its shared libraries.
archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
;;
darwin* | rhapsody*)
- case "$host_os" in
+ case $host_os in
rhapsody* | darwin1.[012])
allow_undefined_flag='${wl}-undefined ${wl}suppress'
;;
output_verbose_link_cmd='echo'
archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
else
output_verbose_link_cmd='echo'
archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
;;
hpux10* | hpux11*)
if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
;;
esac
else
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
;;
esac
fi
if test "$with_gnu_ld" = no; then
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*)
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_flag_spec_ld='+b $libdir'
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
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10233 "configure"
+#line 10241 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) 2>/dev/null
+ (./conftest; exit; ) >&5 2>/dev/null
lt_status=$?
case x$lt_status in
x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10331 "configure"
+#line 10339 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) 2>/dev/null
+ (./conftest; exit; ) >&5 2>/dev/null
lt_status=$?
case x$lt_status in
x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
# 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
ol_link_tls=no
if test $ol_with_tls != no ; then
-
-for ac_header in openssl/ssl.h ssl.h
+for ac_header in openssl/ssl.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
done
- if test $ac_cv_header_openssl_ssl_h = yes ||
- test $ac_cv_header_ssl_h = yes ; then
- echo "$as_me:$LINENO: checking for SSLeay_add_ssl_algorithms in -lssl" >&5
-echo $ECHO_N "checking for SSLeay_add_ssl_algorithms in -lssl... $ECHO_C" >&6
-if test "${ac_cv_lib_ssl_SSLeay_add_ssl_algorithms+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lssl -lcrypto $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char SSLeay_add_ssl_algorithms ();
-int
-main ()
-{
-SSLeay_add_ssl_algorithms ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_ssl_SSLeay_add_ssl_algorithms=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_ssl_SSLeay_add_ssl_algorithms=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSLeay_add_ssl_algorithms" >&5
-echo "${ECHO_T}$ac_cv_lib_ssl_SSLeay_add_ssl_algorithms" >&6
-if test $ac_cv_lib_ssl_SSLeay_add_ssl_algorithms = yes; then
- have_ssleay=yes
- need_rsaref=no
-else
- have_ssleay=no
-fi
-
-
- if test $have_ssleay = no ; then
- echo "$as_me:$LINENO: checking for SSL_library_init in -lssl" >&5
+ if test $ac_cv_header_openssl_ssl_h = yes ; then
+ echo "$as_me:$LINENO: checking for SSL_library_init in -lssl" >&5
echo $ECHO_N "checking for SSL_library_init in -lssl... $ECHO_C" >&6
if test "${ac_cv_lib_ssl_SSL_library_init+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_library_init" >&5
echo "${ECHO_T}$ac_cv_lib_ssl_SSL_library_init" >&6
if test $ac_cv_lib_ssl_SSL_library_init = yes; then
- have_ssleay=yes
- need_rsaref=no
+ have_openssl=yes
+ need_rsaref=no
else
- have_ssleay=no
+ have_openssl=no
fi
- fi
- if test $have_ssleay = no ; then
+ if test $have_openssl = no ; then
echo "$as_me:$LINENO: checking for ssl3_accept in -lssl" >&5
echo $ECHO_N "checking for ssl3_accept in -lssl... $ECHO_C" >&6
if test "${ac_cv_lib_ssl_ssl3_accept+set}" = set; then
echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_ssl3_accept" >&5
echo "${ECHO_T}$ac_cv_lib_ssl_ssl3_accept" >&6
if test $ac_cv_lib_ssl_ssl3_accept = yes; then
- have_ssleay=yes
+ have_openssl=yes
need_rsaref=yes
else
- have_ssleay=no
+ have_openssl=no
fi
fi
- if test $have_ssleay = yes ; then
+ if test $have_openssl = yes ; then
ol_with_tls=found
ol_link_tls=yes
cat >>confdefs.h <<\_ACEOF
-#define HAVE_SSLEAY 1
+#define HAVE_OPENSSL 1
_ACEOF
+
+
getspnam \
gettimeofday \
initgroups \
+ inet_ntoa_b \
lockf \
memcpy \
memmove \
+ memrchr \
mkstemp \
mktemp \
pipe \
lockf \
memcpy \
memmove \
+ memrchr \
mkstemp \
mktemp \
pipe \
to your slapd configuration file. (You should obtain the necessary schema
files from the Heimdal and/or Samba distributions. At this time, there
are several known errors in these schema files that you will have to
-correct before they will load in slapd.)
+correct before they will load in slapd. As of Samba 3.0 the schema looks
+fine as shipped.)
+
+All modules compiled in (i.e. krb5 and samba) are enabled; the statement
+
+ smbk5pwd-enable <module>
+
+can be used to enable only the desired one(s); legal values for <module>
+are "krb5" and "samba", if they are respectively enabled by defining
+DO_KRB5 and DO_SAMBA.
+
+The samba module also supports the
+
+ smbk5pwd-must-change <seconds>
+
+which sets the "sambaPwdMustChange" attribute accordingly to force passwd
+expiry. A value of 0 disables this feature.
+
+The overlay now supports table-driven configuration, and thus can be run-time
+loaded and configured via back-config. The layout of the entry is
+
+ # {0}smbk5pwd, {1}bdb, config
+ dn: olcOverlay={0}smbk5pwd,olcDatabase={1}bdb,cn=config
+ objectClass: olcOverlayConfig
+ objectClass: olcSmbK5PwdConfig
+ olcOverlay: {0}smbk5pwd
+ olcSmbK5PwdEnable: krb5
+ olcSmbK5PwdEnable: samba
+ olcSmbK5PwdMustChange: 2592000
+
+which enables both krb5 and samba modules with a password expiry time
+of 30 days.
The provided Makefile builds both Kerberos and Samba support by default.
You must edit the Makefile to insure that the correct include and library
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
+/*
+ * Support for sambaPwdMustChange added by Marco D'Ettorre.
+ * Support for table-driven configuration added by Pierangelo Masarati.
+ *
+ * The conditions of the OpenLDAP Public License apply.
+ */
#include <portable.h>
#include <ac/errno.h>
#include <ac/string.h>
+#include "config.h"
+
#ifdef DO_KRB5
#include <lber.h>
#include <lber_pvt.h>
static AttributeDescription *ad_sambaLMPassword;
static AttributeDescription *ad_sambaNTPassword;
static AttributeDescription *ad_sambaPwdLastSet;
+static AttributeDescription *ad_sambaPwdMustChange;
static ObjectClass *oc_sambaSamAccount;
#endif
-#if 0
-static void smbk5pwd_destroy() {
- kadm5_destroy(kadm_context);
- krb5_free_context(context);
-}
+/* Per-instance configuration information */
+typedef struct smbk5pwd_t {
+ unsigned mode;
+#define SMBK5PWD_F_KRB5 (0x1U)
+#define SMBK5PWD_F_SAMBA (0x2U)
+
+#define SMBK5PWD_DO_KRB5(pi) ((pi)->mode & SMBK5PWD_F_KRB5)
+#define SMBK5PWD_DO_SAMBA(pi) ((pi)->mode & SMBK5PWD_F_SAMBA)
+
+#ifdef DO_KRB5
+ /* nothing yet */
#endif
+#ifdef DO_SAMBA
+ /* How many seconds before forcing a password change? */
+ time_t smb_must_change;
+#endif
+} smbk5pwd_t;
+
+static const unsigned SMBK5PWD_F_ALL =
+ 0
+#ifdef DO_KRB5
+ | SMBK5PWD_F_KRB5
+#endif
+#ifdef DO_SAMBA
+ | SMBK5PWD_F_SAMBA
+#endif
+;
+
+static int smbk5pwd_modules_init( smbk5pwd_t *pi );
+
#ifdef DO_SAMBA
static const char hex[] = "0123456789abcdef";
Entry *e;
Modifications *ml;
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+ smbk5pwd_t *pi = on->on_bi.bi_private;
/* Not the operation we expected, pass it on... */
if ( ber_bvcmp( &slap_EXOP_MODIFY_PASSWD, &op->ore_reqoid ) ) {
int kvno, i;
Attribute *a;
+ if ( !SMBK5PWD_DO_KRB5( pi ) ) break;
+
if ( !is_entry_objectclass(e, oc_krb5KDCEntry, 0 ) ) break;
a = attr_find( e->e_attrs, ad_krb5PrincipalName );
"%d", kvno+1 );
BER_BVZERO( &ml->sml_values[1] );
ml->sml_nvalues = NULL;
- } while(0);
+ } while ( 0 );
#endif /* DO_KRB5 */
#ifdef DO_SAMBA
/* Samba stuff */
- if ( is_entry_objectclass(e, oc_sambaSamAccount, 0 ) ) {
+ if ( SMBK5PWD_DO_SAMBA( pi ) && is_entry_objectclass(e, oc_sambaSamAccount, 0 ) ) {
struct berval *keys;
ber_len_t j,l;
wchar_t *wcs, wc;
#endif
ml->sml_values = keys;
ml->sml_nvalues = NULL;
+
+ if (pi->smb_must_change)
+ {
+ ml = ch_malloc(sizeof(Modifications));
+ ml->sml_next = qpw->rs_mods;
+ qpw->rs_mods = ml;
+
+ keys = ch_malloc( 2 * sizeof(struct berval) );
+ keys[0].bv_val = ch_malloc( STRLENOF( "9223372036854775807L" ) + 1 );
+ keys[0].bv_len = snprintf(keys[0].bv_val,
+ STRLENOF( "9223372036854775807L" ) + 1,
+ "%ld", slap_get_time() + pi->smb_must_change);
+ BER_BVZERO( &keys[1] );
+
+ ml->sml_desc = ad_sambaPwdMustChange;
+ ml->sml_op = LDAP_MOD_REPLACE;
+#ifdef SLAP_MOD_INTERNAL
+ ml->sml_flags = SLAP_MOD_INTERNAL;
+#endif
+ ml->sml_values = keys;
+ ml->sml_nvalues = NULL;
+ }
}
#endif /* DO_SAMBA */
be_entry_release_r( op, e );
static slap_overinst smbk5pwd;
-int smbk5pwd_init() {
- int rc;
- const char *text;
+/* back-config stuff */
+enum {
+ PC_SMB_MUST_CHANGE = 1,
+ PC_SMB_ENABLE
+};
-#ifdef DO_KRB5
- krb5_error_code ret;
- extern HDB * _kadm5_s_get_db(void *);
-
- /* Make sure all of our necessary schema items are loaded */
- oc_krb5KDCEntry = oc_find("krb5KDCEntry");
- if ( !oc_krb5KDCEntry ) return -1;
-
- rc = slap_str2ad( "krb5Key", &ad_krb5Key, &text );
- if ( rc ) return rc;
- rc = slap_str2ad( "krb5KeyVersionNumber", &ad_krb5KeyVersionNumber, &text );
- if ( rc ) return rc;
- rc = slap_str2ad( "krb5PrincipalName", &ad_krb5PrincipalName, &text );
- if ( rc ) return rc;
-
- /* Initialize Kerberos context */
- ret = krb5_init_context(&context);
- if (ret) {
- return -1;
+static ConfigDriver smbk5pwd_cf_func;
+
+/*
+ * NOTE: uses OID arcs OLcfgOvAt:6 and OLcfgOvOc:6
+ */
+
+static ConfigTable smbk5pwd_cfats[] = {
+ { "smbk5pwd-enable", "arg",
+ 2, 0, 0, ARG_MAGIC|PC_SMB_ENABLE, smbk5pwd_cf_func,
+ "( OLcfgOvAt:6.1 NAME 'olcSmbK5PwdEnable' "
+ "DESC 'Modules to be enabled' "
+ "SYNTAX OMsDirectoryString )", NULL, NULL },
+ { "smbk5pwd-must-change", "time",
+ 2, 2, 0, ARG_MAGIC|ARG_INT|PC_SMB_MUST_CHANGE, smbk5pwd_cf_func,
+ "( OLcfgOvAt:6.2 NAME 'olcSmbK5PwdMustChange' "
+ "DESC 'Credentials validity interval' "
+ "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
+
+ { NULL, NULL, 0, 0, 0, ARG_IGNORED }
+};
+
+static ConfigOCs smbk5pwd_cfocs[] = {
+ { "( OLcfgOvOc:6.1 "
+ "NAME 'olcSmbK5PwdConfig' "
+ "DESC 'smbk5pwd overlay configuration' "
+ "SUP olcOverlayConfig "
+ "MAY ( "
+ "olcSmbK5PwdEnable "
+ "$ olcSmbK5PwdMustChange "
+ ") )", Cft_Overlay, smbk5pwd_cfats },
+
+ { NULL, 0, NULL }
+};
+
+/*
+ * add here other functionalities; handle their initialization
+ * as appropriate in smbk5pwd_modules_init().
+ */
+static slap_verbmasks smbk5pwd_modules[] = {
+ { BER_BVC( "krb5" ), SMBK5PWD_F_KRB5 },
+ { BER_BVC( "samba" ), SMBK5PWD_F_SAMBA },
+ { BER_BVNULL, -1 }
+};
+
+static int
+smbk5pwd_cf_func( ConfigArgs *c )
+{
+ slap_overinst *on = (slap_overinst *)c->bi;
+
+ int rc = 0;
+ smbk5pwd_t *pi = on->on_bi.bi_private;
+
+ if ( c->op == SLAP_CONFIG_EMIT ) {
+ switch( c->type ) {
+ case PC_SMB_MUST_CHANGE:
+#ifdef DO_SAMBA
+ c->value_int = pi->smb_must_change;
+#else /* ! DO_SAMBA */
+ c->value_int = 0;
+#endif /* ! DO_SAMBA */
+ break;
+
+ case PC_SMB_ENABLE:
+ c->rvalue_vals = NULL;
+ if ( pi->mode ) {
+ mask_to_verbs( smbk5pwd_modules, pi->mode, &c->rvalue_vals );
+ if ( c->rvalue_vals == NULL ) {
+ rc = 1;
+ }
+ }
+ break;
+
+ default:
+ assert( 0 );
+ rc = 1;
+ }
+ return rc;
+
+ } else if ( c->op == LDAP_MOD_DELETE ) {
+ switch( c->type ) {
+ case PC_SMB_MUST_CHANGE:
+ break;
+
+ case PC_SMB_ENABLE:
+ if ( !c->line ) {
+ pi->mode = 0;
+
+ } else {
+ slap_mask_t m;
+
+ m = verb_to_mask( c->line, smbk5pwd_modules );
+ pi->mode &= ~m;
+ }
+ break;
+
+ default:
+ assert( 0 );
+ rc = 1;
+ }
+ return rc;
+ }
+
+ switch( c->type ) {
+ case PC_SMB_MUST_CHANGE:
+#ifdef DO_SAMBA
+ if ( c->value_int < 0 ) {
+ Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: "
+ "<%s> invalid negative value \"%d\".",
+ c->log, c->argv[ 0 ], 0 );
+ return 1;
+ }
+ pi->smb_must_change = c->value_int;
+#else /* ! DO_SAMBA */
+ Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: "
+ "<%s> only meaningful "
+ "when compiled with -DDO_SAMBA.\n",
+ c->log, c->argv[ 0 ], 0 );
+ return 1;
+#endif /* ! DO_SAMBA */
+ break;
+
+ case PC_SMB_ENABLE: {
+ slap_mask_t mode = pi->mode, m;
+
+ rc = verbs_to_mask( c->argc, c->argv, smbk5pwd_modules, &m );
+ if ( rc > 0 ) {
+ Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: "
+ "<%s> unknown module \"%s\".\n",
+ c->log, c->argv[ 0 ], c->argv[ rc ] );
+ return 1;
+ }
+
+ /* we can hijack the smbk5pwd_t structure because
+ * from within the configuration, this is the only
+ * active thread. */
+ pi->mode |= m;
+
+#ifndef DO_KRB5
+ if ( SMBK5PWD_DO_KRB5( pi ) ) {
+ Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: "
+ "<%s> module \"%s\" only allowed when compiled with -DDO_KRB5.\n",
+ c->log, c->argv[ 0 ], c->argv[ rc ] );
+ pi->mode = mode;
+ return 1;
+ }
+#endif /* ! DO_KRB5 */
+
+#ifndef DO_SAMBA
+ if ( SMBK5PWD_DO_SAMBA( pi ) ) {
+ Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: "
+ "<%s> module \"%s\" only allowed when compiled with -DDO_SAMBA.\n",
+ c->log, c->argv[ 0 ], c->argv[ rc ] );
+ pi->mode = mode;
+ return 1;
+ }
+#endif /* ! DO_SAMBA */
+
+ {
+ BackendDB db = *c->be;
+
+ /* Re-initialize the module, because
+ * the configuration might have changed */
+ db.bd_info = (BackendInfo *)on;
+ rc = smbk5pwd_modules_init( pi );
+ if ( rc ) {
+ pi->mode = mode;
+ return 1;
+ }
+ }
+
+ } break;
+
+ default:
+ assert( 0 );
+ return 1;
+ }
+ return rc;
+}
+
+static int
+smbk5pwd_modules_init( smbk5pwd_t *pi )
+{
+ static struct {
+ const char *name;
+ AttributeDescription **adp;
}
+#ifdef DO_KRB5
+ krb5_ad[] = {
+ { "krb5Key", &ad_krb5Key },
+ { "krb5KeyVersionNumber", &ad_krb5KeyVersionNumber },
+ { "krb5PrincipalName", &ad_krb5PrincipalName },
+ { NULL }
+ },
+#endif /* DO_KRB5 */
+#ifdef DO_SAMBA
+ samba_ad[] = {
+ { "sambaLMPassword", &ad_sambaLMPassword },
+ { "sambaNTPassword", &ad_sambaNTPassword },
+ { "sambaPwdLastSet", &ad_sambaPwdLastSet },
+ { "sambaPwdMustChange", &ad_sambaPwdMustChange },
+ { NULL }
+ },
+#endif /* DO_SAMBA */
+ dummy_ad;
+
+ /* this is to silence the unused var warning */
+ dummy_ad.name = NULL;
+
+#ifdef DO_KRB5
+ if ( SMBK5PWD_DO_KRB5( pi ) && oc_krb5KDCEntry == NULL ) {
+ krb5_error_code ret;
+ extern HDB *_kadm5_s_get_db(void *);
+
+ int i, rc;
+
+ /* Make sure all of our necessary schema items are loaded */
+ oc_krb5KDCEntry = oc_find( "krb5KDCEntry" );
+ if ( !oc_krb5KDCEntry ) {
+ Debug( LDAP_DEBUG_ANY, "smbk5pwd: "
+ "unable to find \"krb5KDCEntry\" objectClass.\n",
+ 0, 0, 0 );
+ return -1;
+ }
+
+ for ( i = 0; krb5_ad[ i ].name != NULL; i++ ) {
+ const char *text;
+
+ *(krb5_ad[ i ].adp) = NULL;
+
+ rc = slap_str2ad( krb5_ad[ i ].name, krb5_ad[ i ].adp, &text );
+ if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_ANY, "smbk5pwd: "
+ "unable to find \"%s\" attributeType: %s (%d).\n",
+ krb5_ad[ i ].name, text, rc );
+ oc_krb5KDCEntry = NULL;
+ return rc;
+ }
+ }
- ret = kadm5_s_init_with_password_ctx( context,
- KADM5_ADMIN_SERVICE,
- NULL,
- KADM5_ADMIN_SERVICE,
- &conf, 0, 0, &kadm_context );
-
- db = _kadm5_s_get_db(kadm_context);
+ /* Initialize Kerberos context */
+ ret = krb5_init_context(&context);
+ if (ret) {
+ Debug( LDAP_DEBUG_ANY, "smbk5pwd: "
+ "unable to initialize krb5 context.\n",
+ 0, 0, 0 );
+ oc_krb5KDCEntry = NULL;
+ return -1;
+ }
+
+ /* FIXME: check return code? */
+ ret = kadm5_s_init_with_password_ctx( context,
+ KADM5_ADMIN_SERVICE,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0, &kadm_context );
+
+ /* FIXME: check return code? */
+ db = _kadm5_s_get_db( kadm_context );
+ }
#endif /* DO_KRB5 */
#ifdef DO_SAMBA
- oc_sambaSamAccount = oc_find("sambaSamAccount");
- if ( !oc_sambaSamAccount ) return -1;
-
- rc = slap_str2ad( "sambaLMPassword", &ad_sambaLMPassword, &text );
- if ( rc ) return rc;
- rc = slap_str2ad( "sambaNTPassword", &ad_sambaNTPassword, &text );
- if ( rc ) return rc;
- rc = slap_str2ad( "sambaPwdLastSet", &ad_sambaPwdLastSet, &text );
- if ( rc ) return rc;
+ if ( SMBK5PWD_DO_SAMBA( pi ) && oc_sambaSamAccount == NULL ) {
+ int i, rc;
+
+ oc_sambaSamAccount = oc_find( "sambaSamAccount" );
+ if ( !oc_sambaSamAccount ) {
+ Debug( LDAP_DEBUG_ANY, "smbk5pwd: "
+ "unable to find \"sambaSamAccount\" objectClass.\n",
+ 0, 0, 0 );
+ return -1;
+ }
+
+ for ( i = 0; samba_ad[ i ].name != NULL; i++ ) {
+ const char *text;
+
+ *(samba_ad[ i ].adp) = NULL;
+
+ rc = slap_str2ad( samba_ad[ i ].name, samba_ad[ i ].adp, &text );
+ if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_ANY, "smbk5pwd: "
+ "unable to find \"%s\" attributeType: %s (%d).\n",
+ samba_ad[ i ].name, text, rc );
+ oc_sambaSamAccount = NULL;
+ return rc;
+ }
+ }
+ }
#endif /* DO_SAMBA */
+ return 0;
+}
+
+static int
+smbk5pwd_db_init(BackendDB *be)
+{
+ slap_overinst *on = (slap_overinst *)be->bd_info;
+ smbk5pwd_t *pi;
+
+ pi = ch_calloc( 1, sizeof( smbk5pwd_t ) );
+ if ( pi == NULL ) {
+ return 1;
+ }
+ on->on_bi.bi_private = (void *)pi;
+
+ return 0;
+}
+
+static int
+smbk5pwd_db_open(BackendDB *be)
+{
+ slap_overinst *on = (slap_overinst *)be->bd_info;
+ smbk5pwd_t *pi = (smbk5pwd_t *)on->on_bi.bi_private;
+
+ int rc;
+
+ if ( pi->mode == 0 ) {
+ pi->mode = SMBK5PWD_F_ALL;
+ }
+
+ rc = smbk5pwd_modules_init( pi );
+ if ( rc ) {
+ return rc;
+ }
+
+ return 0;
+}
+
+static int
+smbk5pwd_db_destroy(BackendDB *be)
+{
+ slap_overinst *on = (slap_overinst *)be->bd_info;
+ smbk5pwd_t *pi = (smbk5pwd_t *)on->on_bi.bi_private;
+
+ if ( pi ) {
+ ch_free( pi );
+ }
+
+ return 0;
+}
+
+int
+smbk5pwd_initialize(void)
+{
+ int rc;
+
smbk5pwd.on_bi.bi_type = "smbk5pwd";
- smbk5pwd.on_bi.bi_extended = smbk5pwd_exop_passwd;
+ smbk5pwd.on_bi.bi_db_init = smbk5pwd_db_init;
+ smbk5pwd.on_bi.bi_db_open = smbk5pwd_db_open;
+ smbk5pwd.on_bi.bi_db_destroy = smbk5pwd_db_destroy;
+
+ smbk5pwd.on_bi.bi_extended = smbk5pwd_exop_passwd;
+
#ifdef DO_KRB5
smbk5pwd.on_bi.bi_op_bind = smbk5pwd_op_bind;
lutil_passwd_add( (struct berval *)&k5key_scheme, k5key_chk, k5key_hash );
#endif
+ smbk5pwd.on_bi.bi_cf_ocs = smbk5pwd_cfocs;
+
+ rc = config_register_schema( smbk5pwd_cfats, smbk5pwd_cfocs );
+ if ( rc ) {
+ return rc;
+ }
+
return overlay_register( &smbk5pwd );
}
#if SLAPD_OVER_SMBK5PWD == SLAPD_MOD_DYNAMIC
int init_module(int argc, char *argv[]) {
- return smbk5pwd_init();
+ return smbk5pwd_initialize();
}
#endif
.BR discover ,
support is detected by reading the remote server's root DSE.
+.TP
+.B timeout [{add|delete|modify|modrdn}=]<val> [...]
+This directive allows to set per-operation timeouts.
+If no operation is specified, it affects all.
+Currently, only write operations are addressed, because searches
+can already be limited by means of the
+.B limits
+directive (see
+.BR slapd.conf (5)
+for details), and other operations are not supposed to incur into the
+need for timeouts.
+Note: if the timelimit is exceeded, the operation is abandoned;
+the protocol does not provide any means to rollback the operation,
+so the client will not know if the operation eventually succeeded or not.
+
.SH BACKWARD COMPATIBILITY
The LDAP backend has been heavily reworked between releases 2.2 and 2.3;
as a side-effect, some of the traditional directives have been
.B defaultsearchbase <dn>
Specify a default search base to use when client submits a
non-base search request with an empty base DN.
+Base scoped search requests with an empty base DN are not affected.
.TP
.B disallow <features>
Specify a set of features (separated by white space) to
In the first case, all operations targeted at a specific configurable
subtree cause the object related to the request DN to be looked up
and checked for return code data: a response code, plus an optional
-textual message, an optional configurable delay, and, when the response code
-is referral, a (list of) referral(s).
+textual message, an optional configurable delay, an optional matched DN
+field, and, when the response code is "referral", a (list of) referral(s).
.LP
Well-known response codes from standard track documents are provided
in \fBretcode.conf\fP, which can be included after instantiating
.HP
.hy 0
.B retcode\-item <RDN> <errCode> [op=<oplist>] [text=<message>]
-.B [ref=<referral>] [sleeptime=<sec>]
+.B [ref=<referral>] [sleeptime=<sec>] [matched=<DN>]
.RS
A dynamically generated entry, located below \fBretcode\-parent\fP.
The \fB<errCode>\fP is the number of the response code;
it can be in any format supported by strtol.
The optional \fB<oplist>\fP is a list of operations that cause
response code generation; if absent, all operations are affected.
+The \fBmatched\fP field is the matched DN that is returned
+along with the error.
The \fBref\fP field is only allowed for the \fBreferral\fP
response code.
.RE
SINGLE-VALUE )
.RE
.LP
+The matched DN returned to the client:
+.RS 4
+( 1.3.6.1.4.1.4203.666.11.4.1.5
+ NAME ( 'errMatchedDN' )
+ DESC 'Value to be returned as matched DN'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ SINGLE-VALUE )
+.RE
+.LP
The abstract class that triggers the overlay:
.RS 4
( 1.3.6.1.4.1.4203.666.11.4.3.0
NAME ( 'errAbsObject' )
SUP top ABSTRACT
MUST ( errCode )
- MAY ( cn $ description $ errOp $ errText $ errSleepTime ) )
+ MAY ( cn $ description $ errOp $ errText $ errSleepTime
+ $ errMatchedDN ) )
.RE
.LP
The standalone structural objectclass for specifically created data:
are specified, the config file will be read and converted to
config directory format and written to the specified directory.
If neither option is specified, an attempt to read the
-default config directory wll be made before trying to use the default
+default config directory will be made before trying to use the default
config file. If a valid config directory exists then the
default config file is ignored.
.TP
are specified, the config file will be read and converted to
config directory format and written to the specified directory.
If neither option is specified, an attempt to read the
-default config directory wll be made before trying to use the default
+default config directory will be made before trying to use the default
config file. If a valid config directory exists then the
default config file is ignored. If dryrun mode is also specified,
no conversion will occur.
are specified, the config file will be read and converted to
config directory format and written to the specified directory.
If neither option is specified, an attempt to read the
-default config directory wll be made before trying to use the default
+default config directory will be made before trying to use the default
config file. If a valid config directory exists then the
default config file is ignored.
.TP
are specified, the config file will be read and converted to
config directory format and written to the specified directory.
If neither option is specified, an attempt to read the
-default config directory wll be made before trying to use the default
+default config directory will be made before trying to use the default
config file. If a valid config directory exists then the
default config file is ignored.
.TP
are specified, the config file will be read and converted to
config directory format and written to the specified directory.
If neither option is specified, an attempt to read the
-default config directory wll be made before trying to use the default
+default config directory will be made before trying to use the default
config file. If a valid config directory exists then the
default config file is ignored.
.TP
are specified, the config file will be read and converted to
config directory format and written to the specified directory.
If neither option is specified, an attempt to read the
-default config directory wll be made before trying to use the default
+default config directory will be made before trying to use the default
config file. If a valid config directory exists then the
default config file is ignored.
.SH LIMITATIONS
#define memcmp lutil_memcmp
#endif
+/* GNU extension (glibc >= 2.1.91), only declared when defined(_GNU_SOURCE) */
+#ifndef HAVE_MEMRCHR
+#undef memrchr
+#define memrchr lutil_memrchr
+#endif /* ! HAVE_MEMRCHR */
+void * memrchr(const void *b, int c, size_t len);
+
#define STRLENOF(s) (sizeof(s)-1)
#if defined( HAVE_NONPOSIX_STRERROR_R )
#define LBER_ERROR_PARAM 0x1
#define LBER_ERROR_MEMORY 0x2
+#ifdef LDAP_DEVEL
+#define LDAP_NULL_IS_NULL
+#endif
+
LDAP_END_DECL
#endif /* _LBER_H */
( (s)[0] == (c) && (s)[1] == '\0' )
#define ber_bvchr(bv,c) \
- memchr( (bv)->bv_val, (c), (bv)->bv_len )
+ ((char *) memchr( (bv)->bv_val, (c), (bv)->bv_len ))
+
+#define ber_bvrchr(bv,c) \
+ ((char *) memrchr( (bv)->bv_val, (c), (bv)->bv_len ))
+
+#define ber_bvchr_right(dst,bv,c) \
+ do { \
+ (dst)->bv_val = memchr( (bv)->bv_val, (c), (bv)->bv_len ); \
+ (dst)->bv_len = (dst)->bv_val ? (bv)->bv_len - ((dst)->bv_val - (bv)->bv_val) : 0; \
+ } while (0)
+
+#define ber_bvchr_left(dst,bv,c) \
+ do { \
+ (dst)->bv_val = memchr( (bv)->bv_val, (c), (bv)->bv_len ); \
+ (dst)->bv_len = (dst)->bv_val ? ((dst)->bv_val - (bv)->bv_val) : (bv)->bv_len; \
+ (dst)->bv_val = (bv)->bv_val; \
+ } while (0)
+
+#define ber_bvrchr_right(dst,bv,c) \
+ do { \
+ (dst)->bv_val = memrchr( (bv)->bv_val, (c), (bv)->bv_len ); \
+ (dst)->bv_len = (dst)->bv_val ? (bv)->bv_len - ((dst)->bv_val - (bv)->bv_val) : 0; \
+ } while (0)
+
+#define ber_bvrchr_left(dst,bv,c) \
+ do { \
+ (dst)->bv_val = memrchr( (bv)->bv_val, (c), (bv)->bv_len ); \
+ (dst)->bv_len = (dst)->bv_val ? ((dst)->bv_val - (bv)->bv_val) : (bv)->bv_len; \
+ (dst)->bv_val = (bv)->bv_val; \
+ } while (0)
#define BER_BVC(s) { STRLENOF(s), (s) }
#define BER_BVNULL { 0L, NULL }
LDAP_F (void) ldap_pvt_tls_destroy LDAP_P(( void ));
LDAP_F (int) ldap_pvt_tls_init LDAP_P(( void ));
-LDAP_F (int) ldap_pvt_tls_init_def_ctx LDAP_P(( void ));
+LDAP_F (int) ldap_pvt_tls_init_def_ctx LDAP_P(( int is_server ));
LDAP_F (int) ldap_pvt_tls_accept LDAP_P(( Sockbuf *sb, void *ctx_arg ));
LDAP_F (int) ldap_pvt_tls_inplace LDAP_P(( Sockbuf *sb ));
LDAP_F (void *) ldap_pvt_tls_sb_ctx LDAP_P(( Sockbuf *sb ));
#endif /* HAVE_OPENSSL_BN_H || HAVE_BN_H */
typedef BIGNUM* ldap_pvt_mp_t;
+#define LDAP_PVT_MP_INIT (NULL)
#define ldap_pvt_mp_init(mp) \
(mp) = BN_new()
#endif
typedef mpz_t ldap_pvt_mp_t;
+#define LDAP_PVT_MP_INIT { 0 }
+
#define ldap_pvt_mp_init(mp) \
mpz_init((mp))
#ifdef HAVE_LONG_LONG
typedef unsigned long long ldap_pvt_mp_t;
+#define LDAP_PVT_MP_INIT (0LL)
#else /* !HAVE_LONG_LONG */
typedef unsigned long ldap_pvt_mp_t;
+#define LDAP_PVT_MP_INIT (0L)
#endif /* !HAVE_LONG_LONG */
#define ldap_pvt_mp_init(mp) \
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
+/* Define to 1 if you have the `memrchr' function. */
+#undef HAVE_MEMRCHR
+
/* Define to 1 if you have the `mkstemp' function. */
#undef HAVE_MKSTEMP
return tag;
}
+#ifdef LDAP_NULL_IS_NULL
+ber_tag_t
+ber_get_stringbv_null( BerElement *ber, struct berval *bv, int alloc )
+{
+ ber_tag_t tag;
+
+ assert( ber != NULL );
+ assert( bv != NULL );
+
+ assert( LBER_VALID( ber ) );
+
+ if ( (tag = ber_skip_tag( ber, &bv->bv_len )) == LBER_DEFAULT ) {
+ bv->bv_val = NULL;
+ return LBER_DEFAULT;
+ }
+
+ if ( (ber_len_t) ber_pvt_ber_remaining( ber ) < bv->bv_len ) {
+ return LBER_DEFAULT;
+ }
+
+ if ( bv->bv_len == 0 ) {
+ bv->bv_val = NULL;
+ ber->ber_tag = *(unsigned char *)ber->ber_ptr;
+ return tag;
+ }
+
+ if ( alloc ) {
+ bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1,
+ ber->ber_memctx );
+ if ( bv->bv_val == NULL ) {
+ return LBER_DEFAULT;
+ }
+
+ if ( bv->bv_len > 0 && (ber_len_t) ber_read( ber, bv->bv_val,
+ bv->bv_len ) != bv->bv_len )
+ {
+ LBER_FREE( bv->bv_val );
+ bv->bv_val = NULL;
+ return LBER_DEFAULT;
+ }
+ } else {
+ bv->bv_val = ber->ber_ptr;
+ ber->ber_ptr += bv->bv_len;
+ }
+ ber->ber_tag = *(unsigned char *)ber->ber_ptr;
+ bv->bv_val[bv->bv_len] = '\0';
+
+ return tag;
+}
+#endif /* LDAP_NULL_IS_NULL */
+
ber_tag_t
ber_get_stringa( BerElement *ber, char **buf )
{
return tag;
}
+#ifdef LDAP_NULL_IS_NULL
+ber_tag_t
+ber_get_stringa_null( BerElement *ber, char **buf )
+{
+ BerValue bv;
+ ber_tag_t tag;
+
+ assert( buf != NULL );
+
+ tag = ber_get_stringbv_null( ber, &bv, 1 );
+ *buf = bv.bv_val;
+
+ return tag;
+}
+#endif /* LDAP_NULL_IS_NULL */
+
ber_tag_t
ber_get_stringal( BerElement *ber, struct berval **bv )
{
rc = ber_get_stringa( ber, ss );
break;
+#ifdef LDAP_NULL_IS_NULL
+ case 'A': /* octet string - allocate storage as needed,
+ * but return NULL if len == 0 */
+ ss = va_arg( ap, char ** );
+ rc = ber_get_stringa_null( ber, ss );
+ break;
+#endif /* LDAP_NULL_IS_NULL */
+
case 'b': /* boolean */
i = va_arg( ap, ber_int_t * );
rc = ber_get_boolean( ber, i );
break;
+ case 'B': /* bit string - allocate storage as needed */
+ ss = va_arg( ap, char ** );
+ l = va_arg( ap, ber_len_t * ); /* for length, in bits */
+ rc = ber_get_bitstringa( ber, ss, l );
+ break;
+
case 'e': /* enumerated */
case 'i': /* int */
i = va_arg( ap, ber_int_t * );
rc = ber_peek_tag( ber, l );
break;
- case 'n': /* null */
- rc = ber_get_null( ber );
+ case 'm': /* octet string in berval, in-place */
+ bval = va_arg( ap, struct berval * );
+ rc = ber_get_stringbv( ber, bval, 0 );
break;
- case 's': /* octet string - in a buffer */
- s = va_arg( ap, char * );
+ case 'M': /* bvoffarray - must include address of
+ * a record len, and record offset.
+ * number of records will be returned thru
+ * len ptr on finish. parsed in-place.
+ */
+ {
+ bgbvr cookie = { BvOff };
+ cookie.ber = ber;
+ cookie.res.ba = va_arg( ap, struct berval ** );
+ cookie.alloc = 0;
l = va_arg( ap, ber_len_t * );
- rc = ber_get_stringb( ber, s, l );
+ cookie.siz = *l;
+ cookie.off = va_arg( ap, ber_len_t );
+ rc = ber_get_stringbvl( &cookie, l );
break;
+ }
- case 'm': /* octet string in berval, in-place */
- bval = va_arg( ap, struct berval * );
- rc = ber_get_stringbv( ber, bval, 0 );
+ case 'n': /* null */
+ rc = ber_get_null( ber );
break;
case 'o': /* octet string in a supplied berval */
rc = ber_get_stringal( ber, bvp );
break;
- case 'B': /* bit string - allocate storage as needed */
- ss = va_arg( ap, char ** );
- l = va_arg( ap, ber_len_t * ); /* for length, in bits */
- rc = ber_get_bitstringa( ber, ss, l );
+ case 's': /* octet string - in a buffer */
+ s = va_arg( ap, char * );
+ l = va_arg( ap, ber_len_t * );
+ rc = ber_get_stringb( ber, s, l );
break;
case 't': /* tag of next item */
break;
}
- case 'M': /* bvoffarray - must include address of
- * a record len, and record offset.
- * number of records will be returned thru
- * len ptr on finish. parsed in-place.
- */
- {
- bgbvr cookie = { BvOff };
- cookie.ber = ber;
- cookie.res.ba = va_arg( ap, struct berval ** );
- cookie.alloc = 0;
- l = va_arg( ap, ber_len_t * );
- cookie.siz = *l;
- cookie.off = va_arg( ap, ber_len_t );
- rc = ber_get_stringbvl( &cookie, l );
- break;
- }
-
case 'x': /* skip the next element - whatever it is */
if ( (rc = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
break;
} break;
case 'a': /* octet string - allocate storage as needed */
+#ifdef LDAP_NULL_IS_NULL
+ case 'A':
+#endif /* LDAP_NULL_IS_NULL */
ss = va_arg( ap, char ** );
if ( *ss ) {
LBER_FREE( *ss );
(void) va_arg( ap, int * );
break;
- case 's': /* octet string - in a buffer */
- (void) va_arg( ap, char * );
- (void) va_arg( ap, ber_len_t * );
- break;
-
case 'l': /* length of next item */
(void) va_arg( ap, ber_len_t * );
break;
- case 't': /* tag of next item */
- case 'T': /* skip tag of next item */
- (void) va_arg( ap, ber_tag_t * );
- break;
-
case 'o': /* octet string in a supplied berval */
bval = va_arg( ap, struct berval * );
if ( bval->bv_val != NULL ) {
}
break;
+ case 's': /* octet string - in a buffer */
+ (void) va_arg( ap, char * );
+ (void) va_arg( ap, ber_len_t * );
+ break;
+
+ case 't': /* tag of next item */
+ case 'T': /* skip tag of next item */
+ (void) va_arg( ap, ber_tag_t * );
+ break;
+
case 'B': /* bit string - allocate storage as needed */
ss = va_arg( ap, char ** );
if ( *ss ) {
*(va_arg( ap, ber_len_t * )) = 0; /* for length, in bits */
break;
- case 'v': /* sequence of strings */
- case 'V': /* sequence of strings + lengths */
- case 'W': /* BerVarray */
case 'm': /* berval in-place */
case 'M': /* BVoff array in-place */
case 'n': /* null */
+ case 'v': /* sequence of strings */
+ case 'V': /* sequence of strings + lengths */
+ case 'W': /* BerVarray */
case 'x': /* skip the next element - whatever it is */
case '{': /* begin sequence */
case '[': /* begin set */
{
BerElement *ber;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
ber = (BerElement *) LBER_CALLOC( 1, sizeof(BerElement) );
if ( ber == NULL ) {
{
assert( ber != NULL );
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
(void) memset( (char *)ber, '\0', sizeof( BerElement ));
ber->ber_valid = LBER_VALID_BERELEMENT;
ber->ber_tag = LBER_DEFAULT;
assert( bv != NULL );
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if ( bv == NULL ) {
return NULL;
}
{
assert( bv != NULL );
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if ( bv == NULL ) {
return -1;
}
assert( bvPtr != NULL );
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if(bvPtr == NULL) {
return -1;
}
LBER_V (BER_ERRNO_FN) ber_int_errno_fn;
+#ifdef LDAP_MEMORY_TRACE
+# ifndef LDAP_MEMORY_DEBUG
+# define LDAP_MEMORY_DEBUG 1
+# endif
+#endif
+
+#ifdef LDAP_MEMORY_DEBUG
+LBER_V (long) ber_int_meminuse;
+#endif
+
struct lber_options {
short lbo_valid;
unsigned short lbo_options;
int lbo_debug;
- long lbo_meminuse;
};
LBER_F( int ) ber_pvt_log_output(
#include "lber-int.h"
#ifdef LDAP_MEMORY_TRACE
-# ifndef LDAP_MEMORY_DEBUG
-# define LDAP_MEMORY_DEBUG 1
-# endif
#include <stdio.h>
#endif
static const struct ber_mem_hdr ber_int_mem_hdr = { LBER_MEM_JUNK, 0, 0 };
-/* Note sequence and ber_int_options.lbu_meminuse are counters, but are not
+/* Note sequence and ber_int_meminuse are counters, but are not
* thread safe. If you want to use these values for multithreaded applications,
* you must put mutexes around them, otherwise they will have incorrect values.
* When debugging, if you sort the debug output, the sequence number will
void
ber_memfree_x( void *p, void *ctx )
{
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if( p == NULL ) {
return;
}
assert( mh->bm_top == LBER_MEM_JUNK);
assert( testdatatop( mh));
assert( testend( (char *)&mh[1] + mh->bm_length) );
- ber_int_options.lbo_meminuse -= mh->bm_length;
+ ber_int_meminuse -= mh->bm_length;
#ifdef LDAP_MEMORY_TRACE
fprintf(stderr, "0x%08lx 0x%08lx -f- %ld ber_memfree %ld\n",
(long)mh->bm_sequence, (long)mh, (long)mh->bm_length,
- ber_int_options.lbo_meminuse);
+ ber_int_meminuse);
#endif
/* Fill the free space with poison */
memset( mh, 0xff, mh->bm_length + sizeof(struct ber_mem_hdr) + sizeof(ber_int_t));
{
int i;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if( vec == NULL ) {
return;
}
ber_memalloc_x( ber_len_t s, void *ctx )
{
void *new;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
#ifdef LDAP_MEMORY_DEBUG
assert( s != 0 );
setdatatop( mh);
setend( (char *)&mh[1] + mh->bm_length );
- ber_int_options.lbo_meminuse += mh->bm_length; /* Count mem inuse */
+ ber_int_meminuse += mh->bm_length; /* Count mem inuse */
#ifdef LDAP_MEMORY_TRACE
mh->bm_sequence = sequence++;
fprintf(stderr, "0x%08lx 0x%08lx -a- %ld ber_memalloc %ld\n",
(long)mh->bm_sequence, (long)mh, (long)mh->bm_length,
- ber_int_options.lbo_meminuse);
+ ber_int_meminuse);
#endif
/* poison new memory */
memset( (char *)&mh[1], 0xff, s);
ber_memcalloc_x( ber_len_t n, ber_len_t s, void *ctx )
{
void *new;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
#ifdef LDAP_MEMORY_DEBUG
assert( n != 0 && s != 0);
setdatatop( mh);
setend( (char *)&mh[1] + mh->bm_length );
- ber_int_options.lbo_meminuse += mh->bm_length;
+ ber_int_meminuse += mh->bm_length;
#ifdef LDAP_MEMORY_TRACE
mh->bm_sequence = sequence++;
fprintf(stderr, "0x%08lx 0x%08lx -a- %ld ber_memcalloc %ld\n",
(long)mh->bm_sequence, (long)mh, (long)mh->bm_length,
- ber_int_options.lbo_meminuse);
+ ber_int_meminuse);
#endif
BER_MEM_VALID( &mh[1] );
new = &mh[1];
ber_memrealloc_x( void* p, ber_len_t s, void *ctx )
{
void *new = NULL;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
/* realloc(NULL,s) -> malloc(s) */
if( p == NULL ) {
assert( mh->bm_top == LBER_MEM_JUNK);
assert( testdatatop( mh));
- ber_int_options.lbo_meminuse += s - oldlen;
+ ber_int_meminuse += s - oldlen;
#ifdef LDAP_MEMORY_TRACE
fprintf(stderr, "0x%08lx 0x%08lx -a- %ld ber_memrealloc %ld\n",
(long)mh->bm_sequence, (long)mh, (long)mh->bm_length,
- ber_int_options.lbo_meminuse);
+ ber_int_meminuse);
#endif
BER_MEM_VALID( &mh[1] );
return &mh[1];
void
ber_bvfree_x( struct berval *bv, void *ctx )
{
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if( bv == NULL ) {
return;
}
{
int i;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if( bv == NULL ) {
return;
}
ber_len_t i;
struct berval **new;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if( *bvec == NULL ) {
if( bv == NULL ) {
/* nothing to add */
{
struct berval *new;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if( src == NULL ) {
ber_errno = LBER_ERROR_PARAM;
return NULL;
{
struct berval *new;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if( s == NULL ) {
ber_errno = LBER_ERROR_PARAM;
return NULL;
{
struct berval *new;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if( s == NULL ) {
ber_errno = LBER_ERROR_PARAM;
return NULL;
char *p;
size_t len;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
#ifdef LDAP_MEMORY_DEBUG
assert(s != NULL); /* bv damn better point to something */
#endif
char *p;
size_t len;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
#ifdef LDAP_MEMORY_DEBUG
assert(s != NULL); /* bv damn better point to something */
#endif
{
int i;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if (a) {
BER_MEM_VALID( a );
{
int n;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if ( *a == NULL ) {
if (bv == NULL) {
return 0;
char ber_pvt_opt_on; /* used to get a non-NULL address for *_OPT_ON */
struct lber_options ber_int_options = {
- LBER_UNINITIALIZED, 0, 0, 0 };
+ LBER_UNINITIALIZED, 0, 0 };
static BerMemoryFunctions ber_int_memory_fns_datum;
const BerElement *ber;
const Sockbuf *sb;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if(outvalue == NULL) {
/* no place to get to */
ber_errno = LBER_ERROR_PARAM;
* The counter is not accurate for multithreaded ldap applications.
*/
#ifdef LDAP_MEMORY_DEBUG
- * (int *) outvalue = ber_int_options.lbo_meminuse;
+ * (int *) outvalue = ber_int_meminuse;
return LBER_OPT_SUCCESS;
#else
return LBER_OPT_ERROR;
BerElement *ber;
Sockbuf *sb;
- if( (ber_int_options.lbo_valid == LBER_UNINITIALIZED)
- && ( ber_int_memory_fns == NULL )
- && ( option == LBER_OPT_MEMORY_FNS )
- && ( invalue != NULL ) )
- {
- const BerMemoryFunctions *f =
- (const BerMemoryFunctions *) invalue;
- /* make sure all functions are provided */
- if(!( f->bmf_malloc && f->bmf_calloc
- && f->bmf_realloc && f->bmf_free ))
- {
- ber_errno = LBER_ERROR_PARAM;
- return LBER_OPT_ERROR;
- }
-
- ber_int_memory_fns = &ber_int_memory_fns_datum;
-
- AC_MEMCPY(ber_int_memory_fns, f, sizeof(BerMemoryFunctions));
-
- ber_int_options.lbo_valid = LBER_INITIALIZED;
- return LBER_OPT_SUCCESS;
- }
-
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
if(invalue == NULL) {
/* no place to set from */
ber_errno = LBER_ERROR_PARAM;
* The counter is not accurate for multithreaded applications.
*/
#ifdef LDAP_MEMORY_DEBUG
- ber_int_options.lbo_meminuse = * (int *) invalue;
+ ber_int_meminuse = * (int *) invalue;
return LBER_OPT_SUCCESS;
#else
return LBER_OPT_ERROR;
#endif
+ case LBER_OPT_MEMORY_FNS:
+ if ( ber_int_memory_fns == NULL )
+ {
+ const BerMemoryFunctions *f =
+ (const BerMemoryFunctions *) invalue;
+ /* make sure all functions are provided */
+ if(!( f->bmf_malloc && f->bmf_calloc
+ && f->bmf_realloc && f->bmf_free ))
+ {
+ ber_errno = LBER_ERROR_PARAM;
+ return LBER_OPT_ERROR;
+ }
+
+ ber_int_memory_fns = &ber_int_memory_fns_datum;
+
+ AC_MEMCPY(ber_int_memory_fns, f,
+ sizeof(BerMemoryFunctions));
+
+ return LBER_OPT_SUCCESS;
+ }
+ break;
+
case LBER_OPT_LOG_PROC:
ber_int_log_proc = (BER_LOG_FN)invalue;
return LBER_OPT_SUCCESS;
{
Sockbuf *sb;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
sb = LBER_CALLOC( 1, sizeof( Sockbuf ) );
if( sb == NULL ) return NULL;
{
int rc;
+ /* map SASL errors to LDAP API errors returned by:
+ * sasl_client_new()
+ * SASL_OK, SASL_NOMECH, SASL_NOMEM
+ * sasl_client_start()
+ * SASL_OK, SASL_NOMECH, SASL_NOMEM, SASL_INTERACT
+ * sasl_client_step()
+ * SASL_OK, SASL_INTERACT, SASL_BADPROT, SASL_BADSERV
+ */
+
switch (saslerr) {
case SASL_CONTINUE:
rc = LDAP_MORE_RESULTS_TO_RETURN;
case SASL_OK:
rc = LDAP_SUCCESS;
break;
- case SASL_FAIL:
- rc = LDAP_LOCAL_ERROR;
- break;
case SASL_NOMEM:
rc = LDAP_NO_MEMORY;
break;
case SASL_NOMECH:
rc = LDAP_AUTH_UNKNOWN;
break;
+ case SASL_BADPROT:
+ rc = LDAP_DECODING_ERROR;
+ break;
+ case SASL_BADSERV:
+ rc = LDAP_AUTH_UNKNOWN;
+ break;
+
+ /* other codes */
case SASL_BADAUTH:
rc = LDAP_AUTH_UNKNOWN;
break;
case SASL_NOAUTHZ:
rc = LDAP_PARAM_ERROR;
break;
+ case SASL_FAIL:
+ rc = LDAP_LOCAL_ERROR;
+ break;
case SASL_TOOWEAK:
case SASL_ENCRYPT:
rc = LDAP_AUTH_UNKNOWN;
{LDAP_X_NO_OPERATION, N_("No Operation (X)")},
+ {LDAP_CUP_RESOURCES_EXHAUSTED, N_("LCUP Resources Exhausted")},
+ {LDAP_CUP_SECURITY_VIOLATION, N_("LCUP Security Violation")},
+ {LDAP_CUP_INVALID_DATA, N_("LCUP Invalid Data")},
+ {LDAP_CUP_UNSUPPORTED_SCHEME, N_("LCUP Unsupported Scheme")},
+ {LDAP_CUP_RELOAD_REQUIRED, N_("LCUP Reload Required")},
+
+
/* API ResultCodes */
{LDAP_SERVER_DOWN, N_("Can't contact LDAP server")},
{LDAP_LOCAL_ERROR, N_("Local error")},
{LDAP_CLIENT_LOOP, N_("Client Loop")},
{LDAP_REFERRAL_LIMIT_EXCEEDED, N_("Referral Limit Exceeded")},
- {LDAP_CUP_RESOURCES_EXHAUSTED, N_("LCUP Resources Exhausted")},
- {LDAP_CUP_SECURITY_VIOLATION, N_("LCUP Security Violation")},
- {LDAP_CUP_INVALID_DATA, N_("LCUP Invalid Data")},
- {LDAP_CUP_UNSUPPORTED_SCHEME, N_("LCUP Unsupported Scheme")},
- {LDAP_CUP_RELOAD_REQUIRED, N_("LCUP Reload Required")},
-
{0, NULL}
};
ber = ber_dup( lm->lm_ber );
if ( ld->ld_version < LDAP_VERSION2 ) {
+#ifdef LDAP_NULL_IS_NULL
+ tag = ber_scanf( ber, "{iA}",
+ &ld->ld_errno, &ld->ld_error );
+#else /* ! LDAP_NULL_IS_NULL */
tag = ber_scanf( ber, "{ia}",
&ld->ld_errno, &ld->ld_error );
+#endif /* ! LDAP_NULL_IS_NULL */
+
} else {
ber_len_t len;
+
+#ifdef LDAP_NULL_IS_NULL
+ tag = ber_scanf( ber, "{iAA" /*}*/,
+ &ld->ld_errno, &ld->ld_matched, &ld->ld_error );
+#else /* ! LDAP_NULL_IS_NULL */
tag = ber_scanf( ber, "{iaa" /*}*/,
&ld->ld_errno, &ld->ld_matched, &ld->ld_error );
+#endif /* ! LDAP_NULL_IS_NULL */
if( tag != LBER_ERROR ) {
/* peek for referrals */
}
if ( errcode == LDAP_SUCCESS ) {
if( matcheddnp != NULL ) {
- *matcheddnp = LDAP_STRDUP( ld->ld_matched );
+#ifdef LDAP_NULL_IS_NULL
+ if ( ld->ld_matched )
+#endif /* LDAP_NULL_IS_NULL */
+ {
+ *matcheddnp = LDAP_STRDUP( ld->ld_matched );
+ }
}
if( errmsgp != NULL ) {
- *errmsgp = LDAP_STRDUP( ld->ld_error );
+#ifdef LDAP_NULL_IS_NULL
+ if ( ld->ld_error )
+#endif /* LDAP_NULL_IS_NULL */
+ {
+ *errmsgp = LDAP_STRDUP( ld->ld_error );
+ }
}
if( referralsp != NULL) {
return ld->ld_errno;
}
+#ifdef LDAP_NULL_IS_NULL
+ rc = ber_scanf( ber, "{eAA" /*}*/, &errcode,
+ &ld->ld_matched, &ld->ld_error );
+#else /* ! LDAP_NULL_IS_NULL */
rc = ber_scanf( ber, "{eaa" /*}*/, &errcode,
&ld->ld_matched, &ld->ld_error );
+#endif /* ! LDAP_NULL_IS_NULL */
if( rc == LBER_ERROR ) {
ld->ld_errno = LDAP_DECODING_ERROR;
return ld->ld_errno;
}
+#ifdef LDAP_NULL_IS_NULL
+ assert( resoid[ 0 ] != '\0' );
+#endif /* LDAP_NULL_IS_NULL */
+
tag = ber_peek_tag( ber, &len );
}
return ld->ld_errno;
}
+#ifdef LDAP_NULL_IS_NULL
+ assert( resoid[ 0 ] != '\0' );
+#endif /* LDAP_NULL_IS_NULL */
+
tag = ber_peek_tag( ber, &len );
}
ber_int_t ldo_sizelimit;
#ifdef HAVE_TLS
+ /* tls context */
+ void *ldo_tls_ctx;
int ldo_tls_mode;
LDAP_TLS_CONNECT_CB *ldo_tls_connect_cb;
void* ldo_tls_connect_arg;
*/
typedef struct ldap_conn {
Sockbuf *lconn_sb;
-#ifdef HAVE_TLS
- /* tls context */
- void *lconn_tls_ctx;
-#endif
#ifdef HAVE_CYRUS_SASL
void *lconn_sasl_authctx; /* context for bind */
void *lconn_sasl_sockctx; /* for security layer */
if( ld->ld_matched == NULL ) {
* (char **) outvalue = NULL;
} else {
- * (char **) outvalue = LDAP_STRDUP(ld->ld_matched);
+ * (char **) outvalue = LDAP_STRDUP( ld->ld_matched );
}
return LDAP_OPT_SUCCESS;
if( ld->ld_error ) {
LDAP_FREE(ld->ld_error);
+ ld->ld_error = NULL;
}
- ld->ld_error = LDAP_STRDUP(err);
+ if ( err ) {
+ ld->ld_error = LDAP_STRDUP(err);
+ }
} return LDAP_OPT_SUCCESS;
case LDAP_OPT_MATCHED_DN: {
- const char *err = (const char *) invalue;
+ const char *matched = (const char *) invalue;
- if(ld == NULL) {
+ if (ld == NULL) {
/* need a struct ldap */
break;
}
if( ld->ld_matched ) {
LDAP_FREE(ld->ld_matched);
+ ld->ld_matched = NULL;
}
- ld->ld_matched = LDAP_STRDUP(err);
+ if ( matched ) {
+ ld->ld_matched = LDAP_STRDUP( matched );
+ }
} return LDAP_OPT_SUCCESS;
case LDAP_OPT_REFERRAL_URLS: {
ber_len_t len;
char *lr_res_error = NULL;
+#ifdef LDAP_NULL_IS_NULL
+ if ( ber_scanf( &tmpber, "{eAA",/*}*/ &lderr,
+ &lr->lr_res_matched, &lr_res_error )
+ != LBER_ERROR )
+#else /* ! LDAP_NULL_IS_NULL */
if ( ber_scanf( &tmpber, "{eaa",/*}*/ &lderr,
&lr->lr_res_matched, &lr_res_error )
!= LBER_ERROR )
+#endif /* ! LDAP_NULL_IS_NULL */
{
if ( lr_res_error != NULL ) {
- if ( lr->lr_res_error != NULL ) {
- (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
- LDAP_FREE( (char *)lr_res_error );
+#ifndef LDAP_NULL_IS_NULL
+ if ( lr_res_error[ 0 ] == '\0' ) {
+ LDAP_FREE( lr_res_error );
+ lr_res_error = NULL;
+ } else
+#endif /* ! LDAP_NULL_IS_NULL */
+ {
+ if ( lr->lr_res_error != NULL ) {
+ (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
+ LDAP_FREE( (char *)lr_res_error );
- } else {
- lr->lr_res_error = lr_res_error;
+ } else {
+ lr->lr_res_error = lr_res_error;
+ }
}
+ lr_res_error = NULL;
}
/* Check if V3 referral */
*/
if ( tag == LDAP_RES_SEARCH_RESULT )
refer_cnt = 0;
+#ifdef LDAP_NULL_IS_NULL
+ } else if ( ber_scanf( &tmpber, "{eAA}", &lderr,
+ &lr->lr_res_matched, &lr_res_error )
+ != LBER_ERROR )
+#else /* ! LDAP_NULL_IS_NULL */
} else if ( ber_scanf( &tmpber, "{eaa}", &lderr,
&lr->lr_res_matched, &lr_res_error )
!= LBER_ERROR )
+#endif /* ! LDAP_NULL_IS_NULL */
{
if ( lr_res_error != NULL ) {
- if ( lr->lr_res_error != NULL ) {
- (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
- LDAP_FREE( (char *)lr_res_error );
- } else {
- lr->lr_res_error = lr_res_error;
+#ifndef LDAP_NULL_IS_NULL
+ if ( lr_res_error[ 0 ] == '\0' ) {
+ LDAP_FREE( lr_res_error );
+ } else
+#endif /* ! LDAP_NULL_IS_NULL */
+ {
+ if ( lr->lr_res_error != NULL ) {
+ (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
+ LDAP_FREE( (char *)lr_res_error );
+ } else {
+ lr->lr_res_error = lr_res_error;
+ }
}
lr_res_error = NULL;
}
} else {
lr->lr_res_errno = LDAP_PARTIAL_RESULTS;
}
-Debug( LDAP_DEBUG_TRACE,
- "new result: res_errno: %d, res_error: <%s>, res_matched: <%s>\n",
- lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "",
- lr->lr_res_matched ? lr->lr_res_matched : "" );
+
+ Debug( LDAP_DEBUG_TRACE, "new result: "
+ "res_errno: %d, "
+ "res_error: <%s>, "
+ "res_matched: <%s>\n",
+ lr->lr_res_errno,
+ lr->lr_res_error ? lr->lr_res_error : "",
+ lr->lr_res_matched ? lr->lr_res_matched : "" );
+ }
+
+ /* in any case, don't leave any lr_res_error 'round */
+ if ( lr_res_error ) {
+ LDAP_FREE( lr_res_error );
}
}
}
if ( ld->ld_version < LDAP_VERSION2 ) {
+#ifdef LDAP_NULL_IS_NULL
+ tag = ber_scanf( ber, "{iA}",
+ &errcode, &ld->ld_error );
+#else /* ! LDAP_NULL_IS_NULL */
tag = ber_scanf( ber, "{ia}",
&errcode, &ld->ld_error );
+#endif /* ! LDAP_NULL_IS_NULL */
if( tag == LBER_ERROR ) {
ber_free( ber, 0 );
} else {
ber_len_t len;
+#ifdef LDAP_NULL_IS_NULL
+ tag = ber_scanf( ber, "{eAA" /*}*/,
+ &errcode, &ld->ld_matched, &ld->ld_error );
+#else /* ! LDAP_NULL_IS_NULL */
tag = ber_scanf( ber, "{eaa" /*}*/,
&errcode, &ld->ld_matched, &ld->ld_error );
+#endif /* ! LDAP_NULL_IS_NULL */
if( tag == LBER_ERROR ) {
ber_free( ber, 0 );
**sp != ')' &&
**sp != '$' &&
**sp != '\'' &&
+ /* for suggested minimum upper bound on the number
+ * of characters <draft-ietf-ldapbis-syntaxes> */
+ **sp != '{' &&
**sp != '\0' )
(*sp)++;
q = *sp;
if ( !at->at_oid ) {
if ( ( flags & ( LDAP_SCHEMA_ALLOW_NO_OID
| LDAP_SCHEMA_ALLOW_OID_MACRO ) )
- && (ss == savepos) ) {
+ && (ss == savepos) )
+ {
/* Backtracking */
ss = savepos;
kind = get_token(&ss,&sval);
!strcasecmp(sval, "COLLECTIVE") ||
!strcasecmp(sval, "NO-USER-MODIFICATION") ||
!strcasecmp(sval, "USAGE") ||
- !strncasecmp(sval, "X-", 2) ) {
+ !strncasecmp(sval, "X-", 2) )
+ {
/* Missing OID, backtrack */
ss = savepos;
} else if ( flags
- & LDAP_SCHEMA_ALLOW_OID_MACRO) {
+ & LDAP_SCHEMA_ALLOW_OID_MACRO)
+ {
/* Non-numerical OID ... */
int len = ss-savepos;
at->at_oid = LDAP_MALLOC(len+1);
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,
if( out->bv_val == NULL ) return -1;
for( i=0; i<in->bv_len; i++ ) {
- if (c & 0x80 || escape[in->bv_val[i]]) {
+ char c = in->bv_val[ i ];
+ if (c & 0x80 || escape[ c ]) {
out->bv_val[out->bv_len++] = '\\';
out->bv_val[out->bv_len++] = "0123456789ABCDEF"[0x0f & (c>>4)];
out->bv_val[out->bv_len++] = "0123456789ABCDEF"[0x0f & c];
* initialize the default context
*/
int
-ldap_pvt_tls_init_def_ctx( void )
+ldap_pvt_tls_init_def_ctx( int is_server )
{
STACK_OF(X509_NAME) *calist;
int rc = 0;
ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
#endif
- if ( !certfile && !keyfile && !cacertfile && !cacertdir ) {
+ if ( is_server && !certfile && !keyfile && !cacertfile && !cacertdir ) {
/* minimum configuration not provided */
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
}
static SSL *
-alloc_handle( void *ctx_arg )
+alloc_handle( void *ctx_arg, int is_server )
{
SSL_CTX *ctx;
SSL *ssl;
if ( ctx_arg ) {
ctx = (SSL_CTX *) ctx_arg;
} else {
- if ( ldap_pvt_tls_init_def_ctx() < 0 ) return NULL;
+ if ( ldap_pvt_tls_init_def_ctx( is_server ) < 0 ) return NULL;
ctx = tls_def_ctx;
}
} else {
struct ldapoptions *lo;
- void *ctx = ld->ld_defconn
- ? ld->ld_defconn->lconn_tls_ctx : NULL;
+ void *ctx;
- ssl = alloc_handle( ctx );
+ lo = &ld->ld_options;
+ ctx = lo->ldo_tls_ctx;
+
+ ssl = alloc_handle( ctx, 0 );
if ( ssl == NULL ) return -1;
if( ctx == NULL ) {
ctx = tls_def_ctx;
- conn->lconn_tls_ctx = tls_def_ctx;
+ lo->ldo_tls_ctx = ctx;
}
- lo = &ld->ld_options;
if ( lo->ldo_tls_connect_cb )
lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg );
lo = LDAP_INT_GLOBAL_OPT();
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
} else {
- ssl = alloc_handle( ctx_arg );
+ ssl = alloc_handle( ctx_arg, 1 );
if ( ssl == NULL ) return -1;
#ifdef LDAP_DEBUG
if ( ld == NULL ) {
*(void **)arg = (void *) tls_def_ctx;
} else {
- *(void **)arg = ld->ld_defconn->lconn_tls_ctx;
+ *(void **)arg = lo->ldo_tls_ctx;
}
break;
case LDAP_OPT_X_TLS_CACERTFILE:
tls_def_ctx = (SSL_CTX *) arg;
} else {
- ld->ld_defconn->lconn_tls_ctx = arg;
+ lo->ldo_tls_ctx = arg;
}
return 0;
case LDAP_OPT_X_TLS_CONNECT_CB:
dhparams = p;
}
}
-done:
+
#ifdef LDAP_R_COMPILE
ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
#endif
tavl_delete( Avlnode **root, void* data, AVL_CMP fcmp )
{
Avlnode *p, *q, *r, *top;
- int side, side_bf, shorter, nside;
+ int side, side_bf, shorter, nside = -1;
/* parent stack */
Avlnode *pptr[sizeof(void *)*8];
#endif
}
#endif
+
+/*
+ * Memory Reverse Search
+ */
+void *
+lutil_memrchr(const void *b, int c, size_t n)
+{
+ if (n != 0) {
+ const unsigned char *s, *bb = b, cc = c;
+
+ for ( s = bb + n; s > bb; ) {
+ if ( *--s == cc ) {
+ return (void *) s;
+ }
+ }
+ }
+
+ return NULL;
+}
#define ACI_BUF_SIZE 1024 /* use most appropriate size */
+enum {
+ ACI_BV_ENTRY,
+ ACI_BV_CHILDREN,
+ ACI_BV_ONELEVEL,
+ ACI_BV_SUBTREE,
+
+ ACI_BV_BR_ENTRY,
+ ACI_BV_BR_ALL,
+
+ ACI_BV_ACCESS_ID,
+ ACI_BV_PUBLIC,
+ ACI_BV_USERS,
+ ACI_BV_SELF,
+ ACI_BV_DNATTR,
+ ACI_BV_GROUP,
+ ACI_BV_ROLE,
+ ACI_BV_SET,
+ ACI_BV_SET_REF,
+
+ ACI_BV_GRANT,
+ ACI_BV_DENY,
+
+ ACI_BV_GROUP_CLASS,
+ ACI_BV_GROUP_ATTR,
+ ACI_BV_ROLE_CLASS,
+ ACI_BV_ROLE_ATTR,
+
+ ACI_BV_SET_ATTR,
+
+ ACI_BV_LAST
+};
+
+static const struct berval aci_bv[] = {
+ /* scope */
+ BER_BVC("entry"),
+ BER_BVC("children"),
+ BER_BVC("onelevel"),
+ BER_BVC("subtree"),
+
+ /* */
+ BER_BVC("[entry]"),
+ BER_BVC("[all]"),
+
+ /* type */
+ BER_BVC("access-id"),
+ BER_BVC("public"),
+ BER_BVC("users"),
+ BER_BVC("self"),
+ BER_BVC("dnattr"),
+ BER_BVC("group"),
+ BER_BVC("role"),
+ BER_BVC("set"),
+ BER_BVC("set-ref"),
+
+ /* actions */
+ BER_BVC("grant"),
+ BER_BVC("deny"),
+
+ /* schema */
+ BER_BVC(SLAPD_GROUP_CLASS),
+ BER_BVC(SLAPD_GROUP_ATTR),
+ BER_BVC(SLAPD_ROLE_CLASS),
+ BER_BVC(SLAPD_ROLE_ATTR),
+
+ BER_BVC(SLAPD_ACI_SET_ATTR),
+
+ BER_BVNULL
+};
+
#ifdef SLAP_DYNACL
static
#endif /* SLAP_DYNACL */
}
} else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET ], &type ) == 0 ) {
- if ( acl_match_set( &sdn, op, e, 0 ) ) {
+ if ( acl_match_set( &sdn, op, e, NULL ) ) {
return 1;
}
} else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET_REF ], &type ) == 0 ) {
- if ( acl_match_set( &sdn, op, e, 1 ) ) {
+ if ( acl_match_set( &sdn, op, e, (struct berval *)&aci_bv[ ACI_BV_SET_ATTR ] ) ) {
return 1;
}
int
aci_init( void )
{
- /* OpenLDAP Experimental Syntax */
+ /* OpenLDAP eXperimental Syntax */
static slap_syntax_defs_rec aci_syntax_def = {
"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
SLAP_SYNTAX_HIDE,
}
#ifdef SLAP_DYNACL
-/*
- * FIXME: there is a silly dependence that makes it difficult
- * to move ACIs in a run-time loadable module under the "dynacl"
- * umbrella, because sets share some helpers with ACIs.
- */
static int
dynacl_aci_parse(
const char *fname,
char accessmaskbuf1[ACCESSMASK_MAXLEN];
#endif /* LDAP_DEBUG */
+ if ( BER_BVISEMPTY( &e->e_nname ) ) {
+ /* no ACIs in the root DSE */
+ return -1;
+ }
+
/* start out with nothing granted, nothing denied */
ACL_INIT(tgrant);
ACL_INIT(tdeny);
}
}
- Debug( LDAP_DEBUG_ACL, "<= aci_mask grant %s deny %s\n",
+ Debug( LDAP_DEBUG_ACL, " <= aci_mask grant %s deny %s\n",
accessmask2str( tgrant, accessmaskbuf, 1 ),
accessmask2str( tdeny, accessmaskbuf1, 1 ), 0 );
}
if ( tgrant == ACL_PRIV_NONE && tdeny == ACL_PRIV_NONE ) {
struct berval parent_ndn;
-#if 1
- /* to solve the chicken'n'egg problem of accessing
- * the OpenLDAPaci attribute, the direct access
- * to the entry's attribute is unchecked; however,
- * further accesses to OpenLDAPaci values in the
- * ancestors occur through backend_attribute(), i.e.
- * with the identity of the operation, requiring
- * further access checking. For uniformity, this
- * makes further requests occur as the rootdn, if
- * any, i.e. searching for the OpenLDAPaci attribute
- * is considered an internal search. If this is not
- * acceptable, then the same check needs be performed
- * when accessing the entry's attribute. */
- Operation op2 = *op;
-
- if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) {
- op2.o_dn = op->o_bd->be_rootdn;
- op2.o_ndn = op->o_bd->be_rootndn;
- }
-#endif
-
dnParent( &e->e_nname, &parent_ndn );
while ( !BER_BVISEMPTY( &parent_ndn ) ){
int i;
BerVarray bvals = NULL;
int ret, stop;
- Debug( LDAP_DEBUG_ACL, "checking ACI of \"%s\"\n", parent_ndn.bv_val, 0, 0 );
- ret = backend_attribute( &op2, NULL, &parent_ndn, ad, &bvals, ACL_AUTH );
+ /* to solve the chicken'n'egg problem of accessing
+ * the OpenLDAPaci attribute, the direct access
+ * to the entry's attribute is unchecked; however,
+ * further accesses to OpenLDAPaci values in the
+ * ancestors occur through backend_attribute(), i.e.
+ * with the identity of the operation, requiring
+ * further access checking. For uniformity, this
+ * makes further requests occur as the rootdn, if
+ * any, i.e. searching for the OpenLDAPaci attribute
+ * is considered an internal search. If this is not
+ * acceptable, then the same check needs be performed
+ * when accessing the entry's attribute. */
+ struct berval save_o_dn, save_o_ndn;
+
+ if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) {
+ save_o_dn = op->o_dn;
+ save_o_ndn = op->o_ndn;
+
+ op->o_dn = op->o_bd->be_rootdn;
+ op->o_ndn = op->o_bd->be_rootndn;
+ }
+
+ Debug( LDAP_DEBUG_ACL, " checking ACI of \"%s\"\n", parent_ndn.bv_val, 0, 0 );
+ ret = backend_attribute( op, NULL, &parent_ndn, ad, &bvals, ACL_AUTH );
+
+ if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) {
+ op->o_dn = save_o_dn;
+ op->o_ndn = save_o_ndn;
+ }
switch ( ret ) {
case LDAP_SUCCESS :
struct berval ocbv = BER_BVNULL,
atbv = BER_BVNULL;
- ocbv.bv_val = strchr( type.bv_val, '/' );
- if ( ocbv.bv_val != NULL
- && ( ocbv.bv_val - type.bv_val ) < type.bv_len )
- {
+ ocbv.bv_val = ber_bvchr( &type, '/' );
+ if ( ocbv.bv_val != NULL ) {
ocbv.bv_val++;
+ ocbv.bv_len = type.bv_len
+ - ( ocbv.bv_val - type.bv_val );
- atbv.bv_val = strchr( ocbv.bv_val, '/' );
- if ( atbv.bv_val != NULL
- && ( atbv.bv_val - ocbv.bv_val ) < ocbv.bv_len )
- {
+ atbv.bv_val = ber_bvchr( &ocbv, '/' );
+ if ( atbv.bv_val != NULL ) {
AttributeDescription *ad = NULL;
const char *text = NULL;
int rc;
if ( rc != LDAP_SUCCESS ) {
return LDAP_INVALID_SYNTAX;
}
-
- } else {
- ocbv.bv_len = type.bv_len
- - ( ocbv.bv_val - type.bv_val );
}
if ( oc_bvfind( &ocbv ) == NULL ) {
struct berval ocbv = BER_BVNULL,
atbv = BER_BVNULL;
- ocbv.bv_val = strchr( type.bv_val, '/' );
- if ( ocbv.bv_val != NULL
- && ( ocbv.bv_val - type.bv_val ) < type.bv_len )
- {
+ ocbv.bv_val = ber_bvchr( &type, '/' );
+ if ( ocbv.bv_val != NULL ) {
ObjectClass *oc = NULL;
AttributeDescription *ad = NULL;
const char *text = NULL;
bv.bv_len = ntype.bv_len;
ocbv.bv_val++;
+ ocbv.bv_len = type.bv_len - ( ocbv.bv_val - type.bv_val );
- atbv.bv_val = strchr( ocbv.bv_val, '/' );
- if ( atbv.bv_val != NULL
- && ( atbv.bv_val - ocbv.bv_val ) < ocbv.bv_len )
- {
+ atbv.bv_val = ber_bvchr( &ocbv, '/' );
+ if ( atbv.bv_val != NULL ) {
atbv.bv_val++;
atbv.bv_len = type.bv_len
- ( atbv.bv_val - type.bv_val );
}
bv.bv_len += STRLENOF( "/" ) + ad->ad_cname.bv_len;
-
- } else {
- ocbv.bv_len = type.bv_len
- - ( ocbv.bv_val - type.bv_val );
}
oc = oc_bvfind( &ocbv );
#define ACL_BUF_SIZE 1024 /* use most appropriate size */
-/*
- * speed up compares
- */
-const struct berval aci_bv[] = {
- BER_BVC("entry"),
- BER_BVC("children"),
- BER_BVC("onelevel"),
- BER_BVC("subtree"),
- BER_BVC("[entry]"),
- BER_BVC("[all]"),
- BER_BVC("access-id"),
-#if 0
- BER_BVC("anonymous"),
-#endif
- BER_BVC("public"),
- BER_BVC("users"),
- BER_BVC("self"),
- BER_BVC("dnattr"),
- BER_BVC("group"),
- BER_BVC("role"),
- BER_BVC("set"),
- BER_BVC("set-ref"),
- BER_BVC("grant"),
- BER_BVC("deny"),
-
- BER_BVC("IP="),
+static const struct berval acl_bv_ip_eq = BER_BVC( "IP=" );
#ifdef LDAP_PF_LOCAL
- BER_BVC("PATH="),
-#if 0
- BER_BVC(LDAP_DIRSEP),
-#endif
+static const struct berval acl_bv_path_eq = BER_BVC("PATH=");
#endif /* LDAP_PF_LOCAL */
-
- BER_BVC(SLAPD_GROUP_CLASS),
- BER_BVC(SLAPD_GROUP_ATTR),
- BER_BVC(SLAPD_ROLE_CLASS),
- BER_BVC(SLAPD_ROLE_ATTR),
-
- BER_BVC(SLAPD_ACI_SET_ATTR)
-};
static AccessControl * slap_acl_get(
AccessControl *ac, int *count,
Access *b;
#ifdef LDAP_DEBUG
char accessmaskbuf[ACCESSMASK_MAXLEN];
-#if !defined( SLAP_DYNACL ) && defined( SLAPD_ACI_ENABLED )
- char accessmaskbuf1[ACCESSMASK_MAXLEN];
-#endif /* !SLAP_DYNACL && SLAPD_ACI_ENABLED */
#endif /* DEBUG */
const char *attr;
slap_mask_t a2pmask = ACL_ACCESS2PRIV( *mask );
int port_number = -1;
if ( strncasecmp( op->o_conn->c_peer_name.bv_val,
- aci_bv[ ACI_BV_IP_EQ ].bv_val,
- aci_bv[ ACI_BV_IP_EQ ].bv_len ) != 0 )
+ acl_bv_ip_eq.bv_val,
+ acl_bv_ip_eq.bv_len ) != 0 )
continue;
- ip.bv_val = op->o_conn->c_peer_name.bv_val + aci_bv[ ACI_BV_IP_EQ ].bv_len;
- ip.bv_len = op->o_conn->c_peer_name.bv_len - aci_bv[ ACI_BV_IP_EQ ].bv_len;
+ ip.bv_val = op->o_conn->c_peer_name.bv_val + acl_bv_ip_eq.bv_len;
+ ip.bv_len = op->o_conn->c_peer_name.bv_len - acl_bv_ip_eq.bv_len;
port = strrchr( ip.bv_val, ':' );
if ( port ) {
struct berval path;
if ( strncmp( op->o_conn->c_peer_name.bv_val,
- aci_bv[ ACI_BV_PATH_EQ ].bv_val,
- aci_bv[ ACI_BV_PATH_EQ ].bv_len ) != 0 )
+ acl_bv_path_eq.bv_val,
+ acl_bv_path_eq.bv_len ) != 0 )
continue;
path.bv_val = op->o_conn->c_peer_name.bv_val
- + aci_bv[ ACI_BV_PATH_EQ ].bv_len;
+ + acl_bv_path_eq.bv_len;
path.bv_len = op->o_conn->c_peer_name.bv_len
- - aci_bv[ ACI_BV_PATH_EQ ].bv_len;
+ - acl_bv_path_eq.bv_len;
if ( ber_bvcmp( &b->a_peername_pat, &path ) != 0 )
continue;
bv = b->a_set_pat;
}
- if ( acl_match_set( &bv, op, e, 0 ) == 0 ) {
+ if ( acl_match_set( &bv, op, e, NULL ) == 0 ) {
continue;
}
}
0, 0, 0 );
/* this case works different from the others above.
- * since aci's themselves give permissions, we need
+ * since dynamic ACL's themselves give permissions, we need
* to first check b->a_access_mask, the ACL's access level.
*/
- if ( BER_BVISEMPTY( &e->e_nname ) ) {
- /* no ACIs in the root DSE */
- continue;
- }
-
/* first check if the right being requested
* is allowed by the ACL clause.
*/
} else
#else /* !SLAP_DYNACL */
+ /* NOTE: this entire block can be eliminated when SLAP_DYNACL
+ * moves outside of LDAP_DEVEL */
#ifdef SLAPD_ACI_ENABLED
if ( b->a_aci_at != NULL ) {
Attribute *at;
struct berval parent_ndn;
BerVarray bvals = NULL;
int ret, stop;
+#ifdef LDAP_DEBUG
+ char accessmaskbuf1[ACCESSMASK_MAXLEN];
+#endif /* DEBUG */
Debug( LDAP_DEBUG_ACL, " <= check a_aci_at: %s\n",
b->a_aci_at->ad_cname.bv_val, 0, 0 );
struct berval *subj,
Operation *op,
Entry *e,
- int setref )
+ struct berval *default_set_attribute )
{
struct berval set = BER_BVNULL;
int rc = 0;
AclSetCookie cookie;
- if ( setref == 0 ) {
+ if ( default_set_attribute == NULL ) {
ber_dupbv_x( &set, subj, op->o_tmpmemctx );
} else {
}
if ( acl_get_part( subj, 1, '/', &setat ) < 0 ) {
- setat = aci_bv[ ACI_BV_SET_ATTR ];
+ setat = *default_set_attribute;
}
/*
}
#endif /* SLAP_DYNACL */
-int
-acl_init( void )
-{
- int rc = 0;
-
+/*
+ * statically built-in dynamic ACL initialization
+ */
+static int (*acl_init_func[])( void ) = {
#ifdef SLAPD_ACI_ENABLED
#ifdef SLAP_DYNACL
- rc = dynacl_aci_init();
+ dynacl_aci_init,
#else /* !SLAP_DYNACL */
- rc = aci_init();
+ aci_init,
#endif /* !SLAP_DYNACL */
- if ( rc != 0 ) {
- return rc;
- }
#endif /* SLAPD_ACI_ENABLED */
- return rc;
+ NULL
+};
+
+int
+acl_init( void )
+{
+ int i, rc;
+
+ for ( i = 0; acl_init_func[ i ] != NULL; i++ ) {
+ rc = (*(acl_init_func[ i ]))();
+ if ( rc != 0 ) {
+ return rc;
+ }
+ }
+
+ return 0;
}
int
memset( &desc, 0, sizeof( desc ) );
desc.ad_cname = *bv;
name = bv->bv_val;
- options = strchr( name, ';' );
+ options = ber_bvchr( bv, ';' );
if ( options != NULL && (unsigned) ( options - name ) < bv->bv_len ) {
/* don't go past the end of the berval! */
desc.ad_cname.bv_len = options - name;
} else {
csn = op->o_csn;
}
- ptr = strchr( csn.bv_val, '#' );
+ ptr = ber_bvchr( &csn, '#' );
if ( ptr ) {
timestamp.bv_len = ptr - csn.bv_val;
if ( timestamp.bv_len >= sizeof(timebuf) )
#ifdef BDB_HIER
if ( nrdn->bv_len != e->e_nname.bv_len ) {
- char *ptr = strchr( rdn.bv_val, ',' );
+ char *ptr = ber_bvchr( &rdn, ',' );
+ assert( ptr != NULL );
rdn.bv_len = ptr - rdn.bv_val;
}
ber_dupbv( &ei.bei_rdn, &rdn );
rdn = e->e_name;
if ( nrdn->bv_len != e->e_nname.bv_len ) {
- char *ptr = strchr(rdn.bv_val, ',');
+ char *ptr = ber_bvchr(&rdn, ',');
+ assert( ptr != NULL );
rdn.bv_len = ptr - rdn.bv_val;
}
ber_dupbv( &ei->bei_rdn, &rdn );
}
}
- e = ei->bei_e;
+ if ( !fakeroot ) {
+ e = ei->bei_e;
+ }
/* acquire and lock entry */
/* FIXME: dn2entry() should return non-glue entry */
if ( fakeroot ) {
e->e_private = NULL;
entry_free( e );
+ e = NULL;
+
} else {
rc = bdb_cache_modify( e, dummy.e_attrs, bdb->bi_dbenv, locker, &lock );
switch( rc ) {
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(
int bdb_tool_entry_close(
BackendDB *be )
{
- struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-
if ( bdb_tool_info ) {
slapd_shutdown = 1;
ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
Operation *op,
SlapReply *rs )
{
+ struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+
struct ldapconn *lc;
int i = 0,
j = 0;
retry:
rs->sr_err = ldap_add_ext( lc->lc_ld, op->o_req_dn.bv_val, attrs,
ctrls, NULL, &msgid );
- rs->sr_err = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
+ rs->sr_err = ldap_back_op_result( lc, op, rs, msgid,
+ li->timeout[ LDAP_BACK_OP_ADD ], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
LDAP_BACK_IDASSERT_OTHERID
};
+/*
+ * operation enumeration for timeouts
+ */
+enum {
+ LDAP_BACK_OP_ADD = 0,
+ LDAP_BACK_OP_DELETE,
+ LDAP_BACK_OP_MODIFY,
+ LDAP_BACK_OP_MODRDN,
+ LDAP_BACK_OP_LAST
+};
+
struct ldapinfo {
char *url;
LDAPURLDesc *lud;
/* FIXME: automatic rwm instantiation removed */
int rwm_started;
#endif
+
+ time_t timeout[ LDAP_BACK_OP_LAST ];
};
typedef enum ldap_back_send_t {
rs->sr_err = ldap_sasl_bind( lc->lc_ld, op->o_req_dn.bv_val,
LDAP_SASL_SIMPLE,
&op->orb_cred, op->o_ctrls, NULL, &msgid );
- rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDERR );
+ rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_SENDERR );
if ( rc == LDAP_SUCCESS ) {
/* If defined, proxyAuthz will be used also when
rc = ldap_parse_extended_result( ld, res,
NULL, &data, 0 );
if ( rc == LDAP_SUCCESS ) {
- rc = ldap_result2error( ld, res, 1 );
+ int err;
+ rc = ldap_parse_result( ld, res, &err,
+ NULL, NULL, NULL, NULL, 1 );
+ if ( rc == LDAP_SUCCESS ) {
+ rc = err;
+ }
res = NULL;
/* FIXME: in case a referral
return 0;
}
- rc = ldap_back_op_result( lc, op, rs, msgid, sendok );
+ rc = ldap_back_op_result( lc, op, rs, msgid, 0, sendok );
if ( rc == LDAP_SUCCESS ) {
LDAP_BACK_CONN_ISBOUND_SET( lc );
Operation *op,
SlapReply *rs,
ber_int_t msgid,
+ time_t timeout,
ldap_back_send_t sendok )
{
char *match = NULL;
int rc;
struct timeval tv;
- LDAP_BACK_TV_SET( &tv );
+ if ( timeout ) {
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+
+ } else {
+ LDAP_BACK_TV_SET( &tv );
+ }
retry:;
/* if result parsing fails, note the failure reason */
- switch ( ldap_result( lc->lc_ld, msgid, 1, &tv, &res ) ) {
+ rc = ldap_result( lc->lc_ld, msgid, 1, &tv, &res );
+ switch ( rc ) {
case 0:
+ if ( timeout ) {
+ (void)ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL );
+ rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
+ LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR;
+ rs->sr_text = "Operation timed out";
+ break;
+ }
+
LDAP_BACK_TV_SET( &tv );
ldap_pvt_thread_yield();
goto retry;
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
if ( lc->lc_refcnt == 1 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s ldap_back_retry: retrying URI=\"%s\" DN=\"%s\"\n",
+ op->o_log_prefix, li->url,
+ BER_BVISNULL( &lc->lc_bound_ndn ) ?
+ "" : lc->lc_bound_ndn.bv_val );
+
ldap_unbind_ext( lc->lc_ld, NULL, NULL );
lc->lc_ld = NULL;
LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
goto done;
}
- rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDERR );
+ rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_SENDERR );
if ( rc == LDAP_SUCCESS ) {
LDAP_BACK_CONN_ISBOUND_SET( lc );
}
rs->sr_text = "proxyAuthz not allowed within namingContext";
}
- if ( op->o_do_not_cache && op->o_is_auth_check ) {
+ if ( op->o_is_auth_check ) {
mode = LDAP_BACK_IDASSERT_NOASSERT;
} else {
op->orc_ava->aa_desc->ad_cname.bv_val,
&op->orc_ava->aa_value,
ctrls, NULL, &msgid );
- rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
+ rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_SENDRESULT );
if ( rc == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
LDAP_BACK_CFG_CHASE,
LDAP_BACK_CFG_T_F,
LDAP_BACK_CFG_WHOAMI,
+ LDAP_BACK_CFG_TIMEOUT,
LDAP_BACK_CFG_REWRITE
};
"SYNTAX OMsDirectoryString "
"SINGLE-VALUE )",
NULL, NULL },
+ { "timeout", "timeout", 0, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_TIMEOUT,
+ ldap_back_cf_gen, "( OLcfgDbAt:3.14 "
+ "NAME 'olcDbTimeout' "
+ "DESC 'Per-operation timeouts' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
{ "suffixmassage", "[virtual]> <real", 2, 3, 0,
ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
ldap_back_cf_gen, NULL, NULL, NULL },
"$ olcDbChaseReferrals "
"$ olcDbTFSupport "
"$ olcDbProxyWhoAmI "
+ "$ olcDbTimeout "
") )",
Cft_Database, ldapcfg},
{ NULL, 0, NULL }
{ BER_BVNULL, 0 }
};
+static slap_cf_aux_table timeout_table[] = {
+ { BER_BVC("add="), 0 * sizeof( time_t ), 'u', 0, NULL },
+ { BER_BVC("delete="), 1 * sizeof( time_t ), 'u', 0, NULL },
+ { BER_BVC("modify="), 2 * sizeof( time_t ), 'u', 0, NULL },
+ { BER_BVC("modrdn="), 3 * sizeof( time_t ), 'u', 0, NULL },
+ { BER_BVNULL, 0, 0, 0, NULL }
+};
+
static int
ldap_back_cf_gen( ConfigArgs *c )
{
}
break;
+ case LDAP_BACK_CFG_TIMEOUT:
+ BER_BVZERO( &bv );
+
+ slap_cf_aux_table_unparse( li->timeout, &bv, timeout_table );
+
+ if ( !BER_BVISNULL( &bv ) ) {
+ for ( i = 0; isspace( bv.bv_val[ i ] ); i++ )
+ /* count spaces */ ;
+
+ if ( i ) {
+ bv.bv_len -= i;
+ AC_MEMCPY( bv.bv_val, &bv.bv_val[ i ],
+ bv.bv_len + 1 );
+ }
+
+ ber_bvarray_add( &c->rvalue_vals, &bv );
+ }
+ break;
+
default:
/* FIXME: we need to handle all... */
assert( 0 );
rc = 1;
break;
+ case LDAP_BACK_CFG_TIMEOUT:
+ for ( i = 0; i < LDAP_BACK_OP_LAST; i++ ) {
+ li->timeout[ i ] = 0;
+ }
+ break;
+
default:
/* FIXME: we need to handle all... */
assert( 0 );
} else {
li->flags &= ~LDAP_BACK_F_SAVECRED;
}
- break;
- }
+ } break;
case LDAP_BACK_CFG_CHASE: {
int dochase = 0;
} else {
li->flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
}
- break;
- }
+ } break;
case LDAP_BACK_CFG_T_F:
i = verb_to_mask( c->argv[1], t_f_mode );
} else {
li->flags &= ~LDAP_BACK_F_PROXY_WHOAMI;
}
+ } break;
+
+ case LDAP_BACK_CFG_TIMEOUT:
+ if ( c->argc < 2 ) {
+ return 1;
+ }
+
+ for ( i = 1; i < c->argc; i++ ) {
+ if ( isdigit( c->argv[ i ][ 0 ] ) ) {
+ char *next;
+ int j;
+ unsigned u;
+
+ u = strtoul( c->argv[ i ], &next, 0 );
+ if ( next == c->argv[ i ] || next[ 0 ] != '\0' ) {
+ return 1;
+ }
+
+ for ( j = 0; j < LDAP_BACK_OP_LAST; j++ ) {
+ li->timeout[ j ] = u;
+ }
+
+ continue;
+ }
+
+ if ( slap_cf_aux_table_parse( c->argv[ i ], li->timeout, timeout_table, "slapd-ldap timeout" ) ) {
+ return 1;
+ }
+ }
break;
- }
case LDAP_BACK_CFG_REWRITE:
fprintf( stderr, "%s: line %d: "
Operation *op,
SlapReply *rs )
{
+ struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+
struct ldapconn *lc;
ber_int_t msgid;
LDAPControl **ctrls = NULL;
retry:
rs->sr_err = ldap_delete_ext( lc->lc_ld, op->o_req_ndn.bv_val,
ctrls, NULL, &msgid );
- rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
+ rc = ldap_back_op_result( lc, op, rs, msgid,
+ li->timeout[ LDAP_BACK_OP_DELETE], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
Operation *op,
SlapReply *rs )
{
+ struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+
struct ldapconn *lc;
LDAPMod **modv = NULL,
*mods = NULL;
retry:
rs->sr_err = ldap_modify_ext( lc->lc_ld, op->o_req_ndn.bv_val, modv,
ctrls, NULL, &msgid );
- rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
+ rc = ldap_back_op_result( lc, op, rs, msgid,
+ li->timeout[ LDAP_BACK_OP_MODIFY], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
Operation *op,
SlapReply *rs )
{
+ struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+
struct ldapconn *lc;
ber_int_t msgid;
LDAPControl **ctrls = NULL;
rs->sr_err = ldap_rename( lc->lc_ld, op->o_req_ndn.bv_val,
op->orr_newrdn.bv_val, newSup,
op->orr_deleteoldrdn, ctrls, NULL, &msgid );
- rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
+ rc = ldap_back_op_result( lc, op, rs, msgid,
+ li->timeout[ LDAP_BACK_OP_MODRDN ], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
int ldap_back_retry(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok);
int ldap_back_map_result(SlapReply *rs);
int ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
- ber_int_t msgid, ldap_back_send_t sendok);
+ ber_int_t msgid, time_t timeout, ldap_back_send_t sendok);
int back_ldap_LTX_init_module(int argc, char *argv[]);
int ldap_back_init_cf( BackendInfo *bi );
{
struct ldapconn *lc;
struct timeval tv;
- time_t stoptime;
+ time_t stoptime = (time_t)-1;
LDAPMessage *res,
*e;
int rc = 0,
goto retry;
}
}
- rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_DONTSEND );
+ rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND );
ldap_back_freeconn( op, lc );
lc = NULL;
goto finish;
/* cleanup */
if ( references ) {
- ldap_value_free( references );
+ ber_memvfree( (void **)references );
ch_free( rs->sr_ref );
rs->sr_ref = NULL;
}
/* cleanup */
if ( references ) {
- ldap_value_free( references );
+ ber_memvfree( (void **)references );
}
rc = 0;
LDAPMessage *res = NULL;
int rc;
- if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_ADD ] != 0 ) {
- tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_ADD ];
+ if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_ADD ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_ADD ];
tv.tv_usec = 0;
tvp = &tv;
}
struct slap_conn *mc_conn;
ldap_pvt_thread_mutex_t mc_mutex;
unsigned mc_refcnt;
+ int mc_tainted;
struct berval mc_local_ndn;
/* NOTE: msc_mscflags is used to recycle the #define
* in one block with the metaconn_t structure */
} metaconn_t;
-enum {
- META_OP_ADD = 0,
- META_OP_DELETE,
- META_OP_MODIFY,
- META_OP_MODRDN,
- META_OP_LAST
-};
-
typedef struct metatarget_t {
char *mt_uri;
int mt_scope;
unsigned mt_flags;
int mt_version;
- time_t mt_timeout[ META_OP_LAST ];
+ time_t mt_timeout[ LDAP_BACK_OP_LAST ];
} metatarget_t;
typedef struct metadncache_t {
#define META_BACK_DEFER_ROOTDN_BIND(mi) ( (mi)->flags & META_BACK_F_DEFER_ROOTDN_BIND )
int mi_version;
- time_t mi_timeout[ META_OP_LAST ];
+ time_t mi_timeout[ LDAP_BACK_OP_LAST ];
} metainfo_t;
typedef enum meta_op_type {
Operation *op,
SlapReply *rs,
metaconn_t *mc,
- int candidate );
+ int candidate,
+ int massage );
int
meta_back_bind( Operation *op, SlapReply *rs )
for ( i = 0; i < mi->mi_ntargets; i++ ) {
int lerr;
Operation op2 = *op;
+ int massage = 1;
/*
* Skip non-candidates
op2.o_req_ndn = mi->mi_targets[ i ].mt_pseudorootdn;
op2.orb_cred = mi->mi_targets[ i ].mt_pseudorootpw;
op2.orb_method = LDAP_AUTH_SIMPLE;
+
+ massage = 0;
}
- lerr = meta_back_single_bind( &op2, rs, mc, i );
+ lerr = meta_back_single_bind( &op2, rs, mc, i, massage );
+
if ( lerr != LDAP_SUCCESS ) {
rs->sr_err = lerr;
candidates[ i ].sr_tag = META_NOT_CANDIDATE;
Operation *op,
SlapReply *rs,
metaconn_t *mc,
- int candidate )
+ int candidate,
+ int massage )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metatarget_t *mt = &mi->mi_targets[ candidate ];
struct berval mdn = BER_BVNULL;
- dncookie dc;
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
int msgid,
rebinding = 0;
/*
* Rewrite the bind dn if needed
*/
- dc.target = mt;
- dc.conn = op->o_conn;
- dc.rs = rs;
- dc.ctx = "bindDN";
+ if ( massage ) {
+ dncookie dc;
- if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
- send_ldap_result( op, rs );
- return -1;
+ dc.target = mt;
+ dc.conn = op->o_conn;
+ dc.rs = rs;
+ dc.ctx = "bindDN";
+
+ if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
+ send_ldap_result( op, rs );
+ return -1;
+ }
+
+ } else {
+ mdn = op->o_req_dn;
}
/* FIXME: this fixes the bind problem right now; we need
rc = slap_map_api2result( rs );
if ( rs->sr_err == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) {
- ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
- if ( mc->mc_refcnt == 1 ) {
- meta_clear_one_candidate( msc );
- LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
-
- ( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
-
- /* mc here must be the regular mc,
- * reset and ready for init */
- rc = meta_back_init_one_conn( op, rs,
- mt, mc, msc, LDAP_BACK_CONN_ISPRIV( mc ),
- candidate == mc->mc_authz_target,
- LDAP_BACK_DONTSEND );
-
- } else {
- /* can't do anything about it */
- rc = 0;
- }
-
- ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
-
+ rc = meta_back_retry( op, rs, mc, candidate, LDAP_BACK_DONTSEND );
if ( rc ) {
if ( nretries > 0 ) {
nretries--;
rc = slap_map_api2result( rs );
if ( rc == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) {
+ /* NOTE: we do not use meta_back_retry() here
+ * to avoid circular loops; mc_mutex is set
+ * by the caller */
if ( dolock ) {
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
}
LDAP_BACK_CONN_ISPRIV( mc ),
candidate == mc->mc_authz_target,
LDAP_BACK_DONTSEND );
-
} else {
/* can't do anything about it */
rootdn = mi->mi_targets[ i ].mt_pseudorootdn.bv_val;
- rc = meta_back_single_bind( &op2, rs, mc, i );
+ rc = meta_back_single_bind( &op2, rs, mc, i, 0 );
} else {
rc = meta_back_single_dobind( op, rs, mc, i,
mi->mi_targets[ i ].mt_flags = mi->flags;
mi->mi_targets[ i ].mt_version = mi->mi_version;
- for ( c = 0; c < META_OP_LAST; c++ ) {
+ for ( c = 0; c < LDAP_BACK_OP_LAST; c++ ) {
mi->mi_targets[ i ].mt_timeout[ c ] = mi->mi_timeout[ c ];
}
size_t len = sep - argv[ c ];
if ( strncasecmp( argv[ c ], "add", len ) == 0 ) {
- t = &tv[ META_OP_ADD ];
+ t = &tv[ LDAP_BACK_OP_ADD ];
} else if ( strncasecmp( argv[ c ], "delete", len ) == 0 ) {
- t = &tv[ META_OP_DELETE ];
+ t = &tv[ LDAP_BACK_OP_DELETE ];
} else if ( strncasecmp( argv[ c ], "modify", len ) == 0 ) {
- t = &tv[ META_OP_MODIFY ];
+ t = &tv[ LDAP_BACK_OP_MODIFY ];
} else if ( strncasecmp( argv[ c ], "modrdn", len ) == 0 ) {
- t = &tv[ META_OP_MODRDN ];
+ t = &tv[ LDAP_BACK_OP_MODRDN ];
} else {
fprintf( stderr,
"%s: line %d: unknown operation \"%s\" for timeout #%d.\n",
} else {
int i;
- for ( i = 0; i < META_OP_LAST; i++ ) {
+ for ( i = 0; i < LDAP_BACK_OP_LAST; i++ ) {
tv[ i ] = val;
}
}
mc->mc_authz_target = META_BOUND_NONE;
ldap_pvt_thread_mutex_init( &mc->mc_mutex );
mc->mc_refcnt = 1;
+ mc->mc_tainted = 0;
return mc;
}
goto retry_lock;
}
+ Debug( LDAP_DEBUG_ANY,
+ "%s meta_back_retry: retrying URI=\"%s\" DN=\"%s\"\n",
+ op->o_log_prefix, mt->mt_uri,
+ BER_BVISNULL( &msc->msc_bound_ndn ) ?
+ "" : msc->msc_bound_ndn.bv_val );
+
meta_clear_one_candidate( msc );
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
ldap_pvt_thread_mutex_unlock( &mc->mc_mutex );
}
+ if ( rc != LDAP_SUCCESS ) {
+ mc->mc_tainted = 1;
+ }
+
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
return rc == LDAP_SUCCESS ? 1 : 0;
mc = (metaconn_t *)avl_find( mi->mi_conntree,
(caddr_t)&mc_curr, meta_back_conn_cmp );
if ( mc ) {
+ if ( mc->mc_tainted ) {
+ rs->sr_err = LDAP_UNAVAILABLE;
+ rs->sr_text = "remote server unavailable";
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+ return NULL;
+ }
+
mc->mc_refcnt++;
}
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
assert( mc->mc_refcnt > 0 );
mc->mc_refcnt--;
+ if ( mc->mc_refcnt == 0 && mc->mc_tainted ) {
+ (void)avl_delete( &mi->mi_conntree, ( caddr_t )mc,
+ meta_back_conn_cmp );
+ meta_back_conn_free( mc );
+ }
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
}
LDAPMessage *res = NULL;
int rc;
- if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_DELETE ] != 0 ) {
- tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_DELETE ];
+ if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_DELETE ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_DELETE ];
tv.tv_usec = 0;
tvp = &tv;
}
struct timeval tv, *tvp = NULL;
LDAPMessage *res = NULL;
- if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODIFY ] != 0 ) {
- tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODIFY ];
+ if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODIFY ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODIFY ];
tv.tv_usec = 0;
tvp = &tv;
}
LDAPMessage *res = NULL;
int rc;
- if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODRDN ] != 0 ) {
- tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODRDN ];
+ if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODRDN ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_MODRDN ];
tv.tv_usec = 0;
tvp = &tv;
}
int i,
LDAPMessage *e );
-static int
+typedef enum meta_search_candidate_t {
+ META_SEARCH_ERR = -1,
+ META_SEARCH_NOT_CANDIDATE,
+ META_SEARCH_CANDIDATE
+} meta_search_candidate_t;
+
+static meta_search_candidate_t
meta_back_search_start(
Operation *op,
SlapReply *rs,
struct berval mfilter = BER_BVNULL;
char **mapped_attrs = NULL;
int rc;
+ meta_search_candidate_t retcode;
struct timeval tv, *tvp = NULL;
/* should we check return values? */
/*
* this target is no longer candidate
*/
- return 0;
+ return META_SEARCH_NOT_CANDIDATE;
}
break;
/*
* this target is no longer candidate
*/
- return 0;
+ return META_SEARCH_NOT_CANDIDATE;
}
}
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
rs->sr_text = "Operation not allowed";
send_ldap_result( op, rs );
- return -1;
+ return META_SEARCH_ERR;
case REWRITE_REGEXEC_ERR:
/*
* this target is no longer candidate
*/
- return 0;
+ return META_SEARCH_NOT_CANDIDATE;
}
/*
/*
* this target is no longer candidate
*/
- rc = 0;
+ retcode = META_SEARCH_NOT_CANDIDATE;
goto done;
}
/*
* this target is no longer candidate
*/
- rc = 0;
+ retcode = META_SEARCH_NOT_CANDIDATE;
goto done;
}
op->o_ctrls, NULL, tvp, op->ors_slimit,
&candidates[ candidate ].sr_msgid );
if ( rc == LDAP_SUCCESS ) {
- rc = 1;
+ retcode = META_SEARCH_CANDIDATE;
} else {
candidates[ candidate ].sr_msgid = -1;
- rc = 0;
+ retcode = META_SEARCH_NOT_CANDIDATE;
}
done:;
free( mbase.bv_val );
}
- return rc;
+ return retcode;
}
int
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metaconn_t *mc;
struct timeval tv = { 0, 0 };
- time_t stoptime;
+ time_t stoptime = (time_t)-1;
LDAPMessage *res = NULL, *e;
int rc = 0, sres = LDAP_SUCCESS;
char *matched = NULL;
switch ( meta_back_search_start( op, rs, &dc, msc, i, candidates ) )
{
- case 0:
+ case META_SEARCH_NOT_CANDIDATE:
break;
- case 1:
+ case META_SEARCH_CANDIDATE:
+ candidates[ i ].sr_type = REP_INTERMEDIATE;
++ncandidates;
break;
- case -1:
+ case META_SEARCH_ERR:
rc = -1;
goto finish;
}
* get a LDAP_TIMELIMIT_EXCEEDED from
* one of them ...
*/
+get_result:;
rc = ldap_result( msc->msc_ld, candidates[ i ].sr_msgid,
0, &tv, &res );
} else if ( rc == -1 ) {
really_bad:;
/* something REALLY bad happened! */
- ( void )meta_clear_unused_candidates( op, -1 );
- rs->sr_err = LDAP_OTHER;
- savepriv = op->o_private;
- op->o_private = (void *)i;
- send_ldap_result( op, rs );
- op->o_private = savepriv;
-
- /* anything else needs be done? */
-
- /* FIXME: res should not need to be freed */
- assert( res == NULL );
+ if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
+ candidates[ i ].sr_type = REP_RESULT;
+
+ if ( meta_back_retry( op, rs, mc, i, LDAP_BACK_DONTSEND ) ) {
+ switch ( meta_back_search_start( op, rs, &dc, msc, i, candidates ) )
+ {
+ case META_SEARCH_CANDIDATE:
+ goto get_result;
+
+ default:
+ rc = rs->sr_err = LDAP_OTHER;
+ goto finish;
+ }
+ }
+ }
- goto finish;
+ /*
+ * When no candidates are left,
+ * the outer cycle finishes
+ */
+ candidates[ i ].sr_msgid = -1;
+ --ncandidates;
+ rs->sr_err = candidates[ i ].sr_err = LDAP_OTHER;
+ rs->sr_text = "remote server unavailable";
} else if ( rc == LDAP_RES_SEARCH_ENTRY ) {
+ if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
+ /* don't retry any more... */
+ candidates[ i ].sr_type = REP_RESULT;
+ }
+
if ( --op->ors_slimit == -1 ) {
ldap_msgfree( res );
res = NULL;
char **references = NULL;
int cnt;
+ if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
+ /* don't retry any more... */
+ candidates[ i ].sr_type = REP_RESULT;
+ }
+
is_ok++;
rc = ldap_parse_reference( msc->msc_ld, res,
/* cleanup */
if ( references ) {
- ldap_value_free( references );
+ ber_memvfree( (void **)references );
}
if ( rs->sr_ctrls ) {
char buf[ SLAP_TEXT_BUFLEN ];
char **references = NULL;
+ if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
+ /* don't retry any more... */
+ candidates[ i ].sr_type = REP_RESULT;
+ }
+
if ( ldap_parse_result( msc->msc_ld,
res,
&candidates[ i ].sr_err,
LDAP_OPT_ERROR_NUMBER,
&rs->sr_err );
sres = slap_map_api2result( rs );
+ candidates[ i ].sr_type = REP_RESULT;
goto really_bad;
}
( void )ldap_back_referral_result_rewrite( &dc, sr_ref );
/* cleanup */
- ldap_value_free( references );
+ ber_memvfree( (void **)references );
if ( rs->sr_v2ref == NULL ) {
rs->sr_v2ref = sr_ref;
{
monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private;
- ldap_pvt_mp_t nInitiated,
- nCompleted;
+ ldap_pvt_mp_t nInitiated = LDAP_PVT_MP_INIT,
+ nCompleted = LDAP_PVT_MP_INIT;
struct berval rdn;
int i;
Attribute *a;
SlapReply *rs )
{
struct passwd *pw;
- time_t stoptime;
+ time_t stoptime = (time_t)-1;
LDAPRDN rdn = NULL;
struct berval parent = BER_BVNULL;
ber_str2bv( pw->pw_gecos, 0, 0, &val );
attr_merge_normalize_one( e, ad_desc, &val, NULL );
- s = strchr( val.bv_val, ',' );
+ s = ber_bvchr( &val, ',' );
if ( s ) *s = '\0';
- s = strchr( val.bv_val, '&' );
+ s = ber_bvchr( &val, '&' );
if ( s ) {
char buf[1024];
int colnum;
slap_mask_t mask;
+ char textbuf[ SLAP_TEXT_BUFLEN ];
+ size_t textlen = sizeof( textbuf );
+
#ifdef BACKSQL_SYNCPROV
/*
* NOTE: fake successful result to force contextCSN to be bumped up
Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n",
op->ora_e->e_name.bv_val, 0, 0 );
+ slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
+
/* check schema */
if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' };
goto done;
}
+ /* check write access */
+ if ( !access_allowed_mask( op, op->ora_e,
+ slap_schema.si_ad_entry,
+ NULL, ACL_WADD, NULL, &mask ) )
+ {
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+ e = op->ora_e;
+ goto done;
+ }
+
rs->sr_err = backsql_get_db_conn( op, &dbh );
if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
/*
* Check if entry exists
- *
+ *
* NOTE: backsql_api_dn2odbc() is called explicitly because
* we need the mucked DN to pass it to the create procedure.
*/
} else {
dnParent( &op->ora_e->e_nname, &pdn );
- }
- /*
- * Get the parent
- */
- bsi.bsi_e = &p;
- rs->sr_err = backsql_init_search( &bsi, &pdn,
- LDAP_SCOPE_BASE,
- (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs,
- ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
- if ( rs->sr_err != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
- "could not retrieve addDN parent "
- "\"%s\" ID - %s matched=\"%s\"\n",
- pdn.bv_val,
- rs->sr_err == LDAP_REFERRAL ? "referral" : "no such entry",
- rs->sr_matched ? rs->sr_matched : "(null)" );
- e = &p;
- goto done;
- }
+ /*
+ * Get the parent
+ */
+ bsi.bsi_e = &p;
+ rs->sr_err = backsql_init_search( &bsi, &pdn,
+ LDAP_SCOPE_BASE,
+ (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs,
+ ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
+ if ( rs->sr_err != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
+ "could not retrieve addDN parent "
+ "\"%s\" ID - %s matched=\"%s\"\n",
+ pdn.bv_val,
+ rs->sr_err == LDAP_REFERRAL ? "referral" : "no such entry",
+ rs->sr_matched ? rs->sr_matched : "(null)" );
+ e = &p;
+ goto done;
+ }
- /* check "children" pseudo-attribute access to parent */
- if ( !access_allowed( op, &p, slap_schema.si_ad_children,
- NULL, ACL_WADD, NULL ) )
- {
- rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
- e = &p;
- goto done;
+ /* check "children" pseudo-attribute access to parent */
+ if ( !access_allowed( op, &p, slap_schema.si_ad_children,
+ NULL, ACL_WADD, NULL ) )
+ {
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+ e = &p;
+ goto done;
+ }
}
if ( get_assert( op ) &&
goto done;
}
- if ( !access_allowed_mask( op, op->ora_e,
- slap_schema.si_ad_entry,
- NULL, ACL_WADD, NULL, &mask ) )
- {
- rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
- e = op->ora_e;
- goto done;
- }
-
/*
* create_proc is executed; if expect_return is set, then
* an output parameter is bound, which should contain
/*
* Get the parent
*/
- dnParent( &op->o_req_ndn, &pdn );
- bsi.bsi_e = &p;
e_id = bsi.bsi_base_id;
- rs->sr_err = backsql_init_search( &bsi, &pdn,
- LDAP_SCOPE_BASE,
- (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs,
- BACKSQL_ISF_GET_ENTRY );
- if ( rs->sr_err != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
- "could not retrieve deleteDN ID - no such entry\n",
- 0, 0, 0 );
- e = &p;
- goto done;
- }
+ if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
+ dnParent( &op->o_req_ndn, &pdn );
+ bsi.bsi_e = &p;
+ rs->sr_err = backsql_init_search( &bsi, &pdn,
+ LDAP_SCOPE_BASE,
+ (time_t)(-1), NULL, dbh, op, rs,
+ slap_anlist_no_attrs,
+ BACKSQL_ISF_GET_ENTRY );
+ if ( rs->sr_err != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
+ "could not retrieve deleteDN ID "
+ "- no such entry\n",
+ 0, 0, 0 );
+ e = &p;
+ goto done;
+ }
- (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
+ (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 );
- /* check parent for "children" acl */
- if ( !access_allowed( op, &p, slap_schema.si_ad_children,
- NULL, ACL_WDEL, NULL ) )
- {
- Debug( LDAP_DEBUG_TRACE, " backsql_delete(): "
- "no write access to parent\n",
- 0, 0, 0 );
- rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
- e = &p;
- goto done;
+ /* check parent for "children" acl */
+ if ( !access_allowed( op, &p, slap_schema.si_ad_children,
+ NULL, ACL_WDEL, NULL ) )
+ {
+ Debug( LDAP_DEBUG_TRACE, " backsql_delete(): "
+ "no write access to parent\n",
+ 0, 0, 0 );
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
+ e = &p;
+ goto done;
+ }
}
/* avl_apply ... */
oldcount = 0,
res = 0;
#ifdef BACKSQL_COUNTQUERY
- unsigned long count,
- countsize = sizeof( count ),
+ unsigned count,
j,
append = 0;
+ SQLLEN countsize = sizeof( count );
Attribute *attr = NULL;
slap_mr_normalize_func *normfunc = NULL;
* UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%',?))
*/
- backsql_strfcat( &bb, "blbbb",
+ backsql_strfcat_x( &bb, NULL, "blbbb",
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE " ),
"(ldap_entries.dn) LIKE ",
* ldap_entries.dn LIKE CONCAT('%',?)
*/
- backsql_strfcat( &bb, "lb",
+ backsql_strfcat_x( &bb, NULL, "lb",
(ber_len_t)STRLENOF( "ldap_entries.dn LIKE " ),
"ldap_entries.dn LIKE ",
&concat );
* UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%,',?))
*/
- backsql_strfcat( &bb, "blbl",
+ backsql_strfcat_x( &bb, NULL, "blbl",
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(ldap_entries.dn)=" ),
"(ldap_entries.dn)=",
* ldap_entries.dn LIKE CONCAT('%,',?)
*/
- backsql_strfcat( &bb, "l",
+ backsql_strfcat_x( &bb, NULL, "l",
(ber_len_t)STRLENOF( "ldap_entries.dn=?" ),
"ldap_entries.dn=?");
}
if ( bi->sql_id_query == NULL ) {
/* no custom id_query provided */
if ( bi->sql_upper_func.bv_val == NULL ) {
- backsql_strcat( &bb, backsql_id_query, "dn=?", NULL );
+ backsql_strcat_x( &bb, NULL, backsql_id_query, "dn=?", NULL );
} else {
if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
- backsql_strcat( &bb, backsql_id_query,
+ backsql_strcat_x( &bb, NULL, backsql_id_query,
"dn_ru=?", NULL );
} else {
if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
- backsql_strfcat( &bb, "sbl",
+ backsql_strfcat_x( &bb, NULL, "sbl",
backsql_id_query,
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(dn)=?" ), "(dn)=?" );
} else {
- backsql_strfcat( &bb, "sblbcb",
+ backsql_strfcat_x( &bb, NULL, "sblbcb",
backsql_id_query,
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(dn)=" ), "(dn)=",
*/
BER_BVZERO( &bb.bb_val );
bb.bb_len = 0;
- backsql_strfcat( &bb, "sbsb",
+ backsql_strfcat_x( &bb, NULL, "sbsb",
"SELECT COUNT(distinct subordinates.id) "
"FROM ldap_entries,ldap_entries ",
&bi->sql_aliasing, "subordinates "
*/
BER_BVZERO( &bb.bb_val );
bb.bb_len = 0;
- backsql_strfcat( &bb, "sbbsbsbbsb",
+ backsql_strfcat_x( &bb, NULL, "sbbsbsbbsb",
" ", &bi->sql_aliasing, &bi->sql_aliasing_quote,
"objectClass", &bi->sql_aliasing_quote,
",ldap_entries.dn ", &bi->sql_aliasing,
goto done;
}
+ slap_mods_opattrs( op, op->orm_modlist, 1 );
+
oc = backsql_id2oc( bi, bsi.bsi_base_id.eid_oc_id );
assert( oc != NULL );
BER_BVZERO( &a->a_vals[ 1 ] );
#ifdef BACKSQL_SYNCPROV
- if ( op->o_sync && op->o_tag == LDAP_REQ_SEARCH ) {
+ if ( op->o_sync && op->o_tag == LDAP_REQ_SEARCH && op->o_private != NULL ) {
assert( op->o_private != NULL );
entryCSN = *((struct berval *)op->o_private);
extern char
backsql_check_dn_ru_query[];
-struct berbuf * backsql_strcat( struct berbuf *dest, ... );
-struct berbuf * backsql_strfcat( struct berbuf *dest, const char *fmt, ... );
+struct berbuf * backsql_strcat_x( struct berbuf *dest, void *memctx, ... );
+struct berbuf * backsql_strfcat_x( struct berbuf *dest, void *memctx, const char *fmt, ... );
int backsql_entry_addattr( Entry *e, AttributeDescription *ad,
struct berval *at_val, void *memctx );
{
struct berbuf bb = BB_NULL;
- backsql_strfcat( &bb, "lblbbbblblbcbl",
+ backsql_strfcat_x( &bb, NULL, "lblbbbblblbcbl",
(ber_len_t)STRLENOF( "SELECT " ), "SELECT ",
&at_map->bam_sel_expr,
(ber_len_t)STRLENOF( " " ), " ",
(ber_len_t)STRLENOF( "=?" ), "=?" );
if ( !BER_BVISNULL( &at_map->bam_join_where ) ) {
- backsql_strfcat( &bb, "lb",
+ backsql_strfcat_x( &bb, NULL, "lb",
(ber_len_t)STRLENOF( " AND " ), " AND ",
&at_map->bam_join_where );
}
- backsql_strfcat( &bb, "lbbb",
+ backsql_strfcat_x( &bb, NULL, "lbbb",
(ber_len_t)STRLENOF( " ORDER BY " ), " ORDER BY ",
&bi->sql_aliasing_quote,
&at_map->bam_ad->ad_cname,
/* Query to count how many rows will be returned. */
BER_BVZERO( &bb.bb_val );
bb.bb_len = 0;
- backsql_strfcat( &bb, "lblbcbl",
+ backsql_strfcat_x( &bb, NULL, "lblbcbl",
(ber_len_t)STRLENOF( "SELECT COUNT(*) FROM " ),
"SELECT COUNT(*) FROM ",
&at_map->bam_from_tbls,
(ber_len_t)STRLENOF( "=?" ), "=?" );
if ( !BER_BVISNULL( &at_map->bam_join_where ) ) {
- backsql_strfcat( &bb, "lb",
+ backsql_strfcat_x( &bb, NULL, "lb",
(ber_len_t)STRLENOF( " AND " ), " AND ",
&at_map->bam_join_where );
}
BER_BVZERO( &bb.bb_val );
bb.bb_len = 0;
- backsql_strfcat( &bb, "lbcblb",
+ backsql_strfcat_x( &bb, NULL, "lbcblb",
(ber_len_t)STRLENOF( "ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entries.keyval=" ),
"ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entries.keyval=",
&oc_map->bom_keytbl,
ch_free( at_map->bam_join_where.bv_val );
BER_BVZERO( &bb.bb_val );
bb.bb_len = 0;
- backsql_strfcat( &bb, "lbcblb",
+ backsql_strfcat_x( &bb, NULL, "lbcblb",
(ber_len_t)STRLENOF( /* "ldap_entries.id=ldap_entry_objclasses.entry_id AND " */ "ldap_entries.keyval=" ),
/* "ldap_entries.id=ldap_entry_objclasses.entry_id AND " */ "ldap_entries.keyval=",
&oc_map->bom_keytbl,
{
struct berbuf bb = BB_NULL;
- backsql_strfcat( &bb, "bcbc",
+ backsql_strfcat_x( &bb, NULL, "bcbc",
&bas->bas_bi->sql_upper_func,
'(' /* ) */ ,
&at_map->bam_sel_expr,
return 0;
}
- backsql_strfcat( &bsi->bsi_flt_where, "c", '(' /* ) */ );
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx, "c", '(' /* ) */ );
while ( 1 ) {
res = backsql_process_filter( bsi, f );
switch ( op ) {
case LDAP_FILTER_AND:
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx, "l",
(ber_len_t)STRLENOF( " AND " ),
" AND " );
break;
case LDAP_FILTER_OR:
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx, "l",
(ber_len_t)STRLENOF( " OR " ),
" OR " );
break;
}
}
- backsql_strfcat( &bsi->bsi_flt_where, "c", /* ( */ ')' );
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx, "c", /* ( */ ')' );
return 1;
}
* SQL filters are more liberal.
*/
- backsql_strfcat( &bsi->bsi_flt_where, "c", '(' /* ) */ );
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx, "c", '(' /* ) */ );
/* TimesTen */
Debug( LDAP_DEBUG_TRACE, "backsql_process_sub_filter(%s):\n",
* If a pre-upper-cased version of the column
* or a precompiled upper function exists, use it
*/
- backsql_strfcat( &bsi->bsi_flt_where,
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
"bl",
&at->bam_sel_expr_u,
(ber_len_t)STRLENOF( " LIKE '" ),
" LIKE '" );
} else {
- backsql_strfcat( &bsi->bsi_flt_where, "bl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "bl",
&at->bam_sel_expr,
(ber_len_t)STRLENOF( " LIKE '" ), " LIKE '" );
}
#endif /* BACKSQL_TRACE */
start = bsi->bsi_flt_where.bb_val.bv_len;
- backsql_strfcat( &bsi->bsi_flt_where, "b",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "b",
&f->f_sub_initial );
if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) {
ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] );
}
}
- backsql_strfcat( &bsi->bsi_flt_where, "c", '%' );
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "c", '%' );
if ( f->f_sub_any != NULL ) {
for ( i = 0; !BER_BVISNULL( &f->f_sub_any[ i ] ); i++ ) {
#endif /* BACKSQL_TRACE */
start = bsi->bsi_flt_where.bb_val.bv_len;
- backsql_strfcat( &bsi->bsi_flt_where,
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
"bc",
&f->f_sub_any[ i ],
'%' );
#endif /* BACKSQL_TRACE */
start = bsi->bsi_flt_where.bb_val.bv_len;
- backsql_strfcat( &bsi->bsi_flt_where, "b",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "b",
&f->f_sub_final );
if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) {
ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] );
}
}
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" );
return 1;
}
if ( !BER_BVISNULL( &bsi->bsi_from.bb_val ) ) {
- char *start, *end, *tmp;
+ char *start, *end;
+ struct berval tmp;
- tmp = ch_strdup( from_tbls->bv_val );
+ ber_dupbv_x( &tmp, from_tbls, bsi->bsi_op->o_tmpmemctx );
- for ( start = tmp, end = strchr( start, ',' ); start; ) {
+ for ( start = tmp.bv_val, end = strchr( start, ',' ); start; ) {
if ( end ) {
end[0] = '\0';
}
if ( strstr( bsi->bsi_from.bb_val.bv_val, start) == NULL )
{
- backsql_strfcat( &bsi->bsi_from, "cs", ',', start );
+ backsql_strfcat_x( &bsi->bsi_from,
+ bsi->bsi_op->o_tmpmemctx,
+ "cs", ',', start );
}
if ( end ) {
}
}
- ch_free( tmp );
+ bsi->bsi_op->o_tmpfree( tmp.bv_val, bsi->bsi_op->o_tmpmemctx );
} else {
- backsql_strfcat( &bsi->bsi_from, "b", from_tbls );
+ backsql_strfcat_x( &bsi->bsi_from,
+ bsi->bsi_op->o_tmpmemctx,
+ "b", from_tbls );
}
return LDAP_SUCCESS;
break;
case LDAP_FILTER_NOT:
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "NOT (" /* ) */ ),
"NOT (" /* ) */ );
rc = backsql_process_filter( bsi, f->f_not );
- backsql_strfcat( &bsi->bsi_flt_where, "c", /* ( */ ')' );
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "c", /* ( */ ')' );
done = 1;
break;
* ldap_entries AS attributeName WHERE attributeName.dn
* like '%attributeName=value%'"
*/
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "1=1" ), "1=1" );
bsi->bsi_status = LDAP_SUCCESS;
rc = 1;
backsql_merge_from_tbls( bsi, &ldap_entry_objclasses );
- backsql_strfcat( &bsi->bsi_flt_where, "lbl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "lbl",
(ber_len_t)STRLENOF( "(2=2 OR (ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ')) */ ),
"(2=2 OR (ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ')) */,
&bsi->bsi_oc->bom_oc->soc_cname,
}
case LDAP_FILTER_PRESENT:
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "3=3" ), "3=3" );
bsi->bsi_status = LDAP_SUCCESS;
rc = 1;
}
#ifdef BACKSQL_ARBITRARY_KEY
- backsql_strfcat( &bsi->bsi_flt_where, "bcblbc",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "bcblbc",
&bsi->bsi_oc->bom_keytbl, '.',
&bsi->bsi_oc->bom_keycol,
STRLENOF( " LIKE '" ), " LIKE '",
&keyval, '\'' );
#else /* ! BACKSQL_ARBITRARY_KEY */
snprintf( keyvalbuf, sizeof( keyvalbuf ), "%lu", keyval );
- backsql_strfcat( &bsi->bsi_flt_where, "bcbcs",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "bcbcs",
&bsi->bsi_oc->bom_keytbl, '.',
&bsi->bsi_oc->bom_keycol, '=', keyvalbuf );
#endif /* ! BACKSQL_ARBITRARY_KEY */
break;
case LDAP_FILTER_PRESENT:
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "4=4" ), "4=4" );
break;
/*
* support for syncrepl as producer...
*/
+#if 0
if ( !bsi->bsi_op->o_sync ) {
/* unsupported at present... */
bsi->bsi_status = LDAP_OTHER;
rc = -1;
goto done;
}
+#endif
bsi->bsi_flags |= ( BSQL_SF_FILTER_ENTRYCSN | BSQL_SF_RETURN_ENTRYUUID);
/* if doing a syncrepl, try to return as much as possible,
* and always match the filter */
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "5=5" ), "5=5" );
/* save for later use in operational attributes */
* selecting if there are descendants of the
* candidate.
*/
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "6=6" ), "6=6" );
if ( ad == slap_schema.si_ad_hasSubordinates ) {
/*
if ( vat == NULL ) {
/* search anyway; other parts of the filter
* may succeeed */
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "7=7" ), "7=7" );
bsi->bsi_status = LDAP_SUCCESS;
rc = 1;
/* if required, open extra level of parens */
done = 0;
if ( vat[0]->bam_next || vat[1] ) {
- backsql_strfcat( &bsi->bsi_flt_where, "c", '(' );
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "c", '(' );
done = 1;
}
/* if more definitions of the same attr, apply */
if ( vat[i]->bam_next ) {
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
STRLENOF( " OR " ), " OR " );
vat[i] = vat[i]->bam_next;
goto next;
/* if more descendants of the same attr, apply */
i++;
if ( vat[i] ) {
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
STRLENOF( " OR " ), " OR " );
goto next;
}
/* if needed, close extra level of parens */
if ( done ) {
- backsql_strfcat( &bsi->bsi_flt_where, "c", ')' );
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "c", ')' );
}
rc = 1;
if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) {
ber_len_t start;
- backsql_strfcat( &bsi->bsi_flt_where, "cbl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "cbl",
'(', /* ) */
&at->bam_sel_expr_u,
(ber_len_t)STRLENOF( "='" ),
start = bsi->bsi_flt_where.bb_val.bv_len;
- backsql_strfcat( &bsi->bsi_flt_where, "bl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "bl",
filter_value,
(ber_len_t)STRLENOF( /* (' */ "')" ),
/* (' */ "')" );
ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] );
} else {
- backsql_strfcat( &bsi->bsi_flt_where, "cblbl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "cblbl",
'(', /* ) */
&at->bam_sel_expr,
(ber_len_t)STRLENOF( "='" ), "='",
if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) {
ber_len_t start;
- backsql_strfcat( &bsi->bsi_flt_where, "cbl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "cbl",
'(', /* ) */
&at->bam_sel_expr_u,
(ber_len_t)STRLENOF( " LIKE '%" ),
start = bsi->bsi_flt_where.bb_val.bv_len;
- backsql_strfcat( &bsi->bsi_flt_where, "bl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "bl",
filter_value,
(ber_len_t)STRLENOF( /* (' */ "%')" ),
/* (' */ "%')" );
ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] );
} else {
- backsql_strfcat( &bsi->bsi_flt_where, "cblbl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "cblbl",
'(', /* ) */
&at->bam_sel_expr,
(ber_len_t)STRLENOF( " LIKE '%" ),
&& strstr( bsi->bsi_join_where.bb_val.bv_val,
at->bam_join_where.bv_val ) == NULL )
{
- backsql_strfcat( &bsi->bsi_join_where, "lb",
+ backsql_strfcat_x( &bsi->bsi_join_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "lb",
(ber_len_t)STRLENOF( " AND " ), " AND ",
&at->bam_join_where );
}
if ( at->bam_ad == slap_schema.si_ad_objectClass
|| at->bam_ad == slap_schema.si_ad_structuralObjectClass )
{
- backsql_strfcat( &bsi->bsi_flt_where, "lbl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "lbl",
(ber_len_t)STRLENOF( "(ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ') */ ),
"(ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ') */,
filter_value,
if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) {
ber_len_t start;
- backsql_strfcat( &bsi->bsi_flt_where, "cbbc",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "cbbc",
'(', /* ) */
&at->bam_sel_expr_u,
&ordering,
start = bsi->bsi_flt_where.bb_val.bv_len;
- backsql_strfcat( &bsi->bsi_flt_where, "bl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "bl",
filter_value,
(ber_len_t)STRLENOF( /* (' */ "')" ),
/* (' */ "')" );
ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] );
} else {
- backsql_strfcat( &bsi->bsi_flt_where, "cbbcbl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "cbbcbl",
'(' /* ) */ ,
&at->bam_sel_expr,
&ordering,
break;
case LDAP_FILTER_PRESENT:
- backsql_strfcat( &bsi->bsi_flt_where, "lbl",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "lbl",
(ber_len_t)STRLENOF( "NOT (" /* ) */),
"NOT (", /* ) */
&at->bam_sel_expr,
default:
/* unhandled filter type; should not happen */
assert( 0 );
- backsql_strfcat( &bsi->bsi_flt_where, "l",
+ backsql_strfcat_x( &bsi->bsi_flt_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "8=8" ), "8=8" );
break;
BER_BVZERO( &bsi->bsi_flt_where.bb_val );
bsi->bsi_flt_where.bb_len = 0;
- backsql_strfcat( &bsi->bsi_sel, "lbcbc",
+ backsql_strfcat_x( &bsi->bsi_sel,
+ bsi->bsi_op->o_tmpmemctx,
+ "lbcbc",
(ber_len_t)STRLENOF( "SELECT DISTINCT ldap_entries.id," ),
"SELECT DISTINCT ldap_entries.id,",
&bsi->bsi_oc->bom_keytbl,
',' );
if ( !BER_BVISNULL( &bi->sql_strcast_func ) ) {
- backsql_strfcat( &bsi->bsi_sel, "blbl",
+ backsql_strfcat_x( &bsi->bsi_sel,
+ bsi->bsi_op->o_tmpmemctx,
+ "blbl",
&bi->sql_strcast_func,
(ber_len_t)STRLENOF( "('" /* ') */ ),
"('" /* ') */ ,
(ber_len_t)STRLENOF( /* (' */ "')" ),
/* (' */ "')" );
} else {
- backsql_strfcat( &bsi->bsi_sel, "cbc",
+ backsql_strfcat_x( &bsi->bsi_sel,
+ bsi->bsi_op->o_tmpmemctx,
+ "cbc",
'\'',
&bsi->bsi_oc->bom_oc->soc_cname,
'\'' );
}
- backsql_strfcat( &bsi->bsi_sel, "b", &bi->sql_dn_oc_aliasing );
- backsql_strfcat( &bsi->bsi_from, "lb",
+ backsql_strfcat_x( &bsi->bsi_sel,
+ bsi->bsi_op->o_tmpmemctx,
+ "b",
+ &bi->sql_dn_oc_aliasing );
+ backsql_strfcat_x( &bsi->bsi_from,
+ bsi->bsi_op->o_tmpmemctx,
+ "lb",
(ber_len_t)STRLENOF( " FROM ldap_entries," ),
" FROM ldap_entries,",
&bsi->bsi_oc->bom_keytbl );
- backsql_strfcat( &bsi->bsi_join_where, "lbcbl",
+ backsql_strfcat_x( &bsi->bsi_join_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "lbcbl",
(ber_len_t)STRLENOF( " WHERE " ), " WHERE ",
&bsi->bsi_oc->bom_keytbl,
'.',
switch ( bsi->bsi_scope ) {
case LDAP_SCOPE_BASE:
if ( BACKSQL_CANUPPERCASE( bi ) ) {
- backsql_strfcat( &bsi->bsi_join_where, "bl",
+ backsql_strfcat_x( &bsi->bsi_join_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "bl",
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(ldap_entries.dn)=?" ),
"(ldap_entries.dn)=?" );
} else {
- backsql_strfcat( &bsi->bsi_join_where, "l",
+ backsql_strfcat_x( &bsi->bsi_join_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "ldap_entries.dn=?" ),
"ldap_entries.dn=?" );
}
case BACKSQL_SCOPE_BASE_LIKE:
if ( BACKSQL_CANUPPERCASE( bi ) ) {
- backsql_strfcat( &bsi->bsi_join_where, "bl",
+ backsql_strfcat_x( &bsi->bsi_join_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "bl",
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE ?" ),
"(ldap_entries.dn) LIKE ?" );
} else {
- backsql_strfcat( &bsi->bsi_join_where, "l",
+ backsql_strfcat_x( &bsi->bsi_join_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "ldap_entries.dn LIKE ?" ),
"ldap_entries.dn LIKE ?" );
}
break;
case LDAP_SCOPE_ONELEVEL:
- backsql_strfcat( &bsi->bsi_join_where, "l",
+ backsql_strfcat_x( &bsi->bsi_join_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "ldap_entries.parent=?" ),
"ldap_entries.parent=?" );
break;
if ( bsi->bsi_use_subtree_shortcut ) {
/* Skip the base DN filter, as every entry will match it */
- backsql_strfcat( &bsi->bsi_join_where, "l",
+ backsql_strfcat_x( &bsi->bsi_join_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "9=9"), "9=9");
} else if ( !BER_BVISNULL( &bi->sql_subtree_cond ) ) {
- backsql_strfcat( &bsi->bsi_join_where, "b", &bi->sql_subtree_cond );
+ backsql_strfcat_x( &bsi->bsi_join_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "b",
+ &bi->sql_subtree_cond );
} else if ( BACKSQL_CANUPPERCASE( bi ) ) {
- backsql_strfcat( &bsi->bsi_join_where, "bl",
+ backsql_strfcat_x( &bsi->bsi_join_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "bl",
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE ?" ),
"(ldap_entries.dn) LIKE ?" );
} else {
- backsql_strfcat( &bsi->bsi_join_where, "l",
+ backsql_strfcat_x( &bsi->bsi_join_where,
+ bsi->bsi_op->o_tmpmemctx,
+ "l",
(ber_len_t)STRLENOF( "ldap_entries.dn LIKE ?" ),
"ldap_entries.dn LIKE ?" );
}
if ( rc > 0 ) {
struct berbuf bb = BB_NULL;
- backsql_strfcat( &bb, "bbblb",
+ backsql_strfcat_x( &bb,
+ bsi->bsi_op->o_tmpmemctx,
+ "bbblb",
&bsi->bsi_sel.bb_val,
&bsi->bsi_from.bb_val,
&bsi->bsi_join_where.bb_val,
backsql_close_db_conn( void *v_conn )
{
backsql_db_conn *conn = (backsql_db_conn *)v_conn;
+ unsigned long cid = conn->ldap_cid;
Debug( LDAP_DEBUG_TRACE, "==>backsql_close_db_conn(%lu)\n",
- conn->ldap_cid, 0, 0 );
+ cid, 0, 0 );
/*
* Default transact is SQL_ROLLBACK; commit is required only
ch_free( conn );
Debug( LDAP_DEBUG_TRACE, "<==backsql_close_db_conn(%lu)\n",
- conn->ldap_cid, 0, 0 );
+ cid, 0, 0 );
}
int
char backsql_check_dn_ru_query[] = "SELECT dn_ru FROM ldap_entries";
struct berbuf *
-backsql_strcat( struct berbuf *dest, ... )
+backsql_strcat_x( struct berbuf *dest, void *memctx, ... )
{
va_list strs;
ber_len_t cdlen, cslen, grow;
Debug( LDAP_DEBUG_TRACE, "==>backsql_strcat()\n", 0, 0, 0 );
#endif /* BACKSQL_TRACE */
- va_start( strs, dest );
+ va_start( strs, memctx );
if ( dest->bb_val.bv_val == NULL || dest->bb_len == 0 ) {
- dest->bb_val.bv_val = (char *)ch_calloc( BACKSQL_STR_GROW,
- sizeof( char ) );
+ dest->bb_val.bv_val = (char *)ber_memalloc_x( BACKSQL_STR_GROW * sizeof( char ), memctx );
dest->bb_val.bv_len = 0;
dest->bb_len = BACKSQL_STR_GROW;
}
dest->bb_len, cdlen + 1, cslen );
#endif /* BACKSQL_TRACE */
- tmp_dest = (char *)ch_realloc( dest->bb_val.bv_val,
- ( dest->bb_len ) + grow * sizeof( char ) );
+ tmp_dest = (char *)ber_memrealloc_x( dest->bb_val.bv_val,
+ dest->bb_len + grow * sizeof( char ), memctx );
if ( tmp_dest == NULL ) {
Debug( LDAP_DEBUG_ANY, "backsql_strcat(): "
"could not reallocate string buffer.\n",
}
struct berbuf *
-backsql_strfcat( struct berbuf *dest, const char *fmt, ... )
+backsql_strfcat_x( struct berbuf *dest, void *memctx, const char *fmt, ... )
{
va_list strs;
ber_len_t cdlen;
va_start( strs, fmt );
if ( dest->bb_val.bv_val == NULL || dest->bb_len == 0 ) {
- dest->bb_val.bv_val = (char *)ch_calloc( BACKSQL_STR_GROW,
- sizeof( char ) );
+ dest->bb_val.bv_val = (char *)ber_memalloc_x( BACKSQL_STR_GROW * sizeof( char ), memctx );
dest->bb_val.bv_len = 0;
dest->bb_len = BACKSQL_STR_GROW;
}
dest->bb_len, cdlen + 1, cslen );
#endif /* BACKSQL_TRACE */
- tmp_dest = (char *)ch_realloc( dest->bb_val.bv_val,
- ( dest->bb_len ) + grow * sizeof( char ) );
+ tmp_dest = (char *)ber_memrealloc_x( dest->bb_val.bv_val,
+ ( dest->bb_len ) + grow * sizeof( char ), memctx );
if ( tmp_dest == NULL ) {
Debug( LDAP_DEBUG_ANY, "backsql_strfcat(): "
"could not reallocate string buffer.\n",
BACKSQL_NEXT_WORD;
/* table name */
- backsql_strcat( &res, s, NULL );
+ backsql_strcat_x( &res, NULL, s, NULL );
s = q;
BACKSQL_NEXT_WORD;
}
/* oracle doesn't understand "AS" :( and other RDBMSes don't need it */
- backsql_strfcat( &res, "lbbsb",
+ backsql_strfcat_x( &res, NULL, "lbbsb",
STRLENOF( " " ), " ",
&bi->sql_aliasing,
&bi->sql_aliasing_quote,
"p=\"%s\" s=\"%s\"\n", p, s, 0 );
#endif /* BACKSQL_TRACE */
- if ( res.bb_val.bv_val == NULL ) {
- backsql_strcat( &res, s, NULL );
+ if ( BER_BVISNULL( &res.bb_val ) ) {
+ backsql_strcat_x( &res, NULL, s, NULL );
} else {
pos = strstr( res.bb_val.bv_val, s );
if ( pos == NULL || ( ( e = pos[ strlen( s ) ] ) != '\0' && e != ',' ) ) {
- backsql_strfcat( &res, "cs", ',', s );
+ backsql_strfcat_x( &res, NULL, "cs", ',', s );
}
}
ch_free( bb.bb_val.bv_val );
return -1;
}
- backsql_strfcat( &bb, "b", &split_pattern[ i ] );
- backsql_strfcat( &bb, "b", &values[ i ] );
+ backsql_strfcat_x( &bb, NULL, "b", &split_pattern[ i ] );
+ backsql_strfcat_x( &bb, NULL, "b", &values[ i ] );
}
if ( split_pattern[ i ].bv_val == NULL ) {
return -1;
}
- backsql_strfcat( &bb, "b", &split_pattern[ i ] );
+ backsql_strfcat_x( &bb, NULL, "b", &split_pattern[ i ] );
*res = bb.bb_val;
BackendDB *b0 = op->o_bd;
BackendInfo *bi0 = op->o_bd->bd_info;
BI_op_modify **func;
- slap_operation_t which;
+ slap_operation_t which = op_bind;
int rc;
op->o_bd = glue_back_select (b0, &op->o_req_ndn);
case LDAP_REQ_DELETE: which = op_delete; break;
case LDAP_REQ_MODIFY: which = op_modify; break;
case LDAP_REQ_MODRDN: which = op_modrdn; break;
+ default: assert( 0 ); break;
}
func = &op->o_bd->bd_info->bi_op_bind;
};
/*
+ * Backend/Database registry
+ *
* OLcfg{Bk|Db}{Oc|At}:0 -> common
* OLcfg{Bk|Db}{Oc|At}:1 -> bdb
* OLcfg{Bk|Db}{Oc|At}:2 -> ldif
* OLcfg{Bk|Db}{Oc|At}:3 -> ldap?
*/
+/*
+ * Overlay registry
+ *
+ * OLcfgOv{Oc|At}:1 -> syncprov
+ * OLcfgOv{Oc|At}:2 -> pcache
+ * OLcfgOv{Oc|At}:3 -> chain
+ * OLcfgOv{Oc|At}:4 -> accesslog
+ * OLcfgOv{Oc|At}:5 -> valsort
+ * OLcfgOv{Oc|At}:6 -> smbk5pwd (use a separate arc for contrib?)
+ */
+
/* alphabetical ordering */
static ConfigTable config_back_cf_table[] = {
/* quote all args but the first */
line = ldap_charray2str( c->argv, "\" \"" );
ber_str2bv( line, 0, 0, &bv );
- s = strchr( bv.bv_val, '"' );
+ s = ber_bvchr( &bv, '"' );
assert( s != NULL );
/* move the trailing quote of argv[0] to the end */
AC_MEMCPY( s, s + 1, bv.bv_len - ( s - bv.bv_val ) );
static int
config_replica(ConfigArgs *c) {
int i, nr = -1;
- char *replicahost, *replicauri;
+ char *replicahost = NULL, *replicauri = NULL;
LDAPURLDesc *ludp;
if (c->op == SLAP_CONFIG_EMIT) {
if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) {
ber_len_t len;
+ if ( replicauri ) {
+ snprintf( c->msg, sizeof( c->msg ), "<%s> replica host/URI already specified", c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
+ return(1);
+ }
+
replicahost = c->argv[i] + STRLENOF("host=");
len = strlen( replicahost ) + STRLENOF("ldap://");
replicauri = ch_malloc( len + 1 );
nr = add_replica_info(c->be, replicauri, replicahost);
break;
} else if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
+ if ( replicauri ) {
+ snprintf( c->msg, sizeof( c->msg ), "<%s> replica host/URI already specified", c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
+ return(1);
+ }
+
if(ldap_url_parse(c->argv[i] + STRLENOF("uri="), &ludp) != LDAP_SUCCESS) {
snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
return(1);
} else if(nr == -1) {
snprintf( c->msg, sizeof( c->msg ), "<%s> unable to add replica", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
+ Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg,
+ replicauri ? replicauri : "" );
return(1);
} else {
for(i = 1; i < c->argc; i++) {
default: Debug(LDAP_DEBUG_ANY, "%s: "
"unknown tls_option <0x%x>\n",
c->log, c->type, 0);
+ return 1;
}
if (c->op == SLAP_CONFIG_EMIT) {
return ldap_pvt_tls_get_option( NULL, flag, &c->value_string );
Debug(LDAP_DEBUG_ANY, "%s: "
"unknown tls_option <0x%x>\n",
c->log, c->type, 0);
+ return 1;
}
if (c->op == SLAP_CONFIG_EMIT) {
ldap_pvt_tls_get_option( NULL, flag, &c->value_int );
CfEntryInfo *ce;
int index = -1, gotindex = 0, nsibs;
int renumber = 0, tailindex = 0;
- char *ptr1, *ptr2;
+ char *ptr1, *ptr2 = NULL;
struct berval rdn;
if ( renum ) *renum = 0;
/* See if the rdn has an index already */
dnRdn( &e->e_name, &rdn );
- ptr1 = strchr( e->e_name.bv_val, '{' );
+ ptr1 = ber_bvchr( &e->e_name, '{' );
if ( ptr1 && ptr1 - e->e_name.bv_val < rdn.bv_len ) {
ptr2 = strchr( ptr1, '}' );
if (!ptr2 || ptr2 - e->e_name.bv_val > rdn.bv_len)
switch (ml->sml_op) {
case LDAP_MOD_DELETE:
case LDAP_MOD_REPLACE: {
- BerVarray vals = NULL, nvals;
+ BerVarray vals = NULL, nvals = NULL;
int *idx = NULL;
if ( ct && ( ct->arg_type & ARG_NO_DELETE )) {
rc = LDAP_OTHER;
switch (ml->sml_op) {
case LDAP_MOD_DELETE:
case LDAP_MOD_REPLACE: {
- BerVarray vals = NULL, nvals;
+ BerVarray vals = NULL, nvals = NULL;
Attribute *a;
- delrec *d;
+ delrec *d = NULL;
a = attr_find( e->e_attrs, ml->sml_desc );
op->o_conn->c_authtype = op->orb_method;
}
- op->o_conn->c_sasl_bindop = NULL;
-
if( !BER_BVISNULL( &op->o_req_dn ) ) {
slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx );
BER_BVZERO( &op->o_req_dn );
rs->sr_err = slap_sasl_bind( op, rs );
- ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
- if( rs->sr_err == LDAP_SUCCESS ) {
- ber_dupbv(&op->o_conn->c_dn, &op->orb_edn);
- if( !BER_BVISEMPTY( &op->orb_edn ) ) {
- /* edn is always normalized already */
- ber_dupbv( &op->o_conn->c_ndn, &op->o_conn->c_dn );
- }
- op->o_tmpfree( op->orb_edn.bv_val, op->o_tmpmemctx );
- BER_BVZERO( &op->orb_edn );
- op->o_conn->c_authmech = op->o_conn->c_sasl_bind_mech;
- BER_BVZERO( &op->o_conn->c_sasl_bind_mech );
- op->o_conn->c_sasl_bind_in_progress = 0;
-
- op->o_conn->c_sasl_ssf = op->orb_ssf;
- if( op->orb_ssf > op->o_conn->c_ssf ) {
- op->o_conn->c_ssf = op->orb_ssf;
- }
-
- if( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
- ber_len_t max = sockbuf_max_incoming_auth;
- ber_sockbuf_ctrl( op->o_conn->c_sb,
- LBER_SB_OPT_SET_MAX_INCOMING, &max );
- }
-
- /* log authorization identity */
- Statslog( LDAP_DEBUG_STATS,
- "%s BIND dn=\"%s\" mech=%s ssf=%d\n",
- op->o_log_prefix,
- BER_BVISNULL( &op->o_conn->c_dn ) ? "<empty>" : op->o_conn->c_dn.bv_val,
- op->o_conn->c_authmech.bv_val, op->orb_ssf, 0 );
-
- Debug( LDAP_DEBUG_TRACE,
- "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
- op->o_conn->c_authmech.bv_val,
- BER_BVISNULL( &op->o_conn->c_dn ) ? "<empty>" : op->o_conn->c_dn.bv_val,
- op->orb_ssf );
-
- } else if ( rs->sr_err == LDAP_SASL_BIND_IN_PROGRESS ) {
- op->o_conn->c_sasl_bind_in_progress = 1;
-
- } else {
- if ( !BER_BVISNULL( &op->o_conn->c_sasl_bind_mech ) ) {
- free( op->o_conn->c_sasl_bind_mech.bv_val );
- BER_BVZERO( &op->o_conn->c_sasl_bind_mech );
- }
- op->o_conn->c_sasl_bind_in_progress = 0;
- }
-
- ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
-
goto cleanup;
} else {
int i, j;
for(i = 1; i < argc; i++) {
j = verb_to_mask(argv[i], v);
- if(BER_BVISNULL(&v[j].word)) return(1);
+ if(BER_BVISNULL(&v[j].word)) return i;
while (!v[j].mask) j--;
*m |= v[j].mask;
}
{ BER_BVNULL, 0 }
};
-typedef struct cf_aux_table {
- struct berval key;
- int off;
- char type;
- char quote;
- slap_verbmasks *aux;
-} cf_aux_table;
-
-static cf_aux_table bindkey[] = {
+static slap_cf_aux_table bindkey[] = {
{ BER_BVC("starttls="), offsetof(slap_bindconf, sb_tls), 'd', 0, tlskey },
{ BER_BVC("bindmethod="), offsetof(slap_bindconf, sb_method), 'd', 0, methkey },
{ BER_BVC("binddn="), offsetof(slap_bindconf, sb_binddn), 'b', 1, NULL },
{ BER_BVNULL, 0, 0, 0, NULL }
};
-int bindconf_parse( const char *word, slap_bindconf *bc ) {
+int
+slap_cf_aux_table_parse( const char *word, void *dst, slap_cf_aux_table *tab0, LDAP_CONST char *tabmsg )
+{
int rc = 0;
- cf_aux_table *tab;
+ slap_cf_aux_table *tab;
- for (tab = bindkey; !BER_BVISNULL(&tab->key); tab++) {
+ for (tab = tab0; !BER_BVISNULL(&tab->key); tab++ ) {
if ( !strncasecmp( word, tab->key.bv_val, tab->key.bv_len )) {
- char **cptr;
+ char **cptr, *next;
int *iptr, j;
+ unsigned *uptr;
struct berval *bptr;
const char *val = word + tab->key.bv_len;
switch ( tab->type ) {
case 's':
- cptr = (char **)((char *)bc + tab->off);
+ cptr = (char **)((char *)dst + tab->off);
*cptr = ch_strdup( val );
break;
case 'b':
- bptr = (struct berval *)((char *)bc + tab->off);
+ bptr = (struct berval *)((char *)dst + tab->off);
ber_str2bv( val, 0, 1, bptr );
break;
case 'd':
assert( tab->aux != NULL );
- iptr = (int *)((char *)bc + tab->off);
+ iptr = (int *)((char *)dst + tab->off);
rc = 1;
for ( j = 0; !BER_BVISNULL( &tab->aux[j].word ); j++ ) {
}
}
break;
+
+ case 'i':
+ iptr = (int *)((char *)dst + tab->off);
+
+ *iptr = strtol( val, &next, 0 );
+ if ( next == val || next[ 0 ] != '\0' ) {
+ rc = 1;
+ }
+ break;
+
+ case 'u':
+ uptr = (unsigned *)((char *)dst + tab->off);
+
+ *uptr = strtoul( val, &next, 0 );
+ if ( next == val || next[ 0 ] != '\0' ) {
+ rc = 1;
+ }
+ break;
}
if ( rc ) {
- Debug( LDAP_DEBUG_ANY, "invalid bind config value %s\n",
- word, 0, 0 );
+ Debug( LDAP_DEBUG_ANY, "invalid %s value %s\n",
+ tabmsg, word, 0 );
}
return rc;
return rc;
}
-int bindconf_unparse( slap_bindconf *bc, struct berval *bv ) {
+int
+slap_cf_aux_table_unparse( void *src, struct berval *bv, slap_cf_aux_table *tab0 )
+{
char buf[BUFSIZ], *ptr;
- cf_aux_table *tab;
+ slap_cf_aux_table *tab;
struct berval tmp;
ptr = buf;
- for (tab = bindkey; !BER_BVISNULL(&tab->key); tab++) {
+ for (tab = tab0; !BER_BVISNULL(&tab->key); tab++ ) {
char **cptr;
int *iptr, i;
+ unsigned *uptr;
struct berval *bptr;
- cptr = (char **)((char *)bc + tab->off);
+ cptr = (char **)((char *)src + tab->off);
switch ( tab->type ) {
case 'b':
- bptr = (struct berval *)((char *)bc + tab->off);
+ bptr = (struct berval *)((char *)src + tab->off);
cptr = &bptr->bv_val;
case 's':
if ( *cptr ) {
case 'd':
assert( tab->aux != NULL );
- iptr = (int *)((char *)bc + tab->off);
+ iptr = (int *)((char *)src + tab->off);
for ( i = 0; !BER_BVISNULL( &tab->aux[i].word ); i++ ) {
if ( *iptr == tab->aux[i].mask ) {
}
}
break;
+
+ case 'i':
+ iptr = (int *)((char *)src + tab->off);
+ *ptr++ = ' ';
+ ptr = lutil_strcopy( ptr, tab->key.bv_val );
+ ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%d", *iptr );
+ break;
+
+ case 'u':
+ uptr = (unsigned *)((char *)src + tab->off);
+ *ptr++ = ' ';
+ ptr = lutil_strcopy( ptr, tab->key.bv_val );
+ ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%u", *uptr );
+ break;
}
}
tmp.bv_val = buf;
return 0;
}
+int
+bindconf_parse( const char *word, slap_bindconf *bc )
+{
+ return slap_cf_aux_table_parse( word, bc, bindkey, "bind config" );
+}
+
+int
+bindconf_unparse( slap_bindconf *bc, struct berval *bv )
+{
+ return slap_cf_aux_table_unparse( bc, bv, bindkey );
+}
+
void bindconf_free( slap_bindconf *bc ) {
if ( !BER_BVISNULL( &bc->sb_binddn ) ) {
ch_free( bc->sb_binddn.bv_val );
NUM_CONNECTION_ARRAY, sizeof(ldap_pvt_thread_mutex_t) );
if( connections_mutex == NULL ) {
Debug( LDAP_DEBUG_ANY, "connections_init: "
- "allocation of connection mutex[%d] failed\n", i, 0, 0 );
+ "allocation of connection mutexes failed\n", 0, 0, 0 );
return -1;
}
ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
op->o_conn->c_conn_state = SLAP_C_ACTIVE;
+ op->o_conn->c_sasl_bind_in_progress =
+ ( rs->sr_err == LDAP_SASL_BIND_IN_PROGRESS );
+
+ /* Moved here from bind.c due to ITS#4158 */
+ op->o_conn->c_sasl_bindop = NULL;
+ if ( op->orb_method == LDAP_AUTH_SASL ) {
+ if( rs->sr_err == LDAP_SUCCESS ) {
+ ber_dupbv(&op->o_conn->c_dn, &op->orb_edn);
+ if( !BER_BVISEMPTY( &op->orb_edn ) ) {
+ /* edn is always normalized already */
+ ber_dupbv( &op->o_conn->c_ndn, &op->o_conn->c_dn );
+ }
+ op->o_tmpfree( op->orb_edn.bv_val, op->o_tmpmemctx );
+ BER_BVZERO( &op->orb_edn );
+ op->o_conn->c_authmech = op->o_conn->c_sasl_bind_mech;
+ BER_BVZERO( &op->o_conn->c_sasl_bind_mech );
+
+ op->o_conn->c_sasl_ssf = op->orb_ssf;
+ if( op->orb_ssf > op->o_conn->c_ssf ) {
+ op->o_conn->c_ssf = op->orb_ssf;
+ }
+
+ if( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
+ ber_len_t max = sockbuf_max_incoming_auth;
+ ber_sockbuf_ctrl( op->o_conn->c_sb,
+ LBER_SB_OPT_SET_MAX_INCOMING, &max );
+ }
+
+ /* log authorization identity */
+ Statslog( LDAP_DEBUG_STATS,
+ "%s BIND dn=\"%s\" mech=%s ssf=%d\n",
+ op->o_log_prefix,
+ BER_BVISNULL( &op->o_conn->c_dn ) ? "<empty>" : op->o_conn->c_dn.bv_val,
+ op->o_conn->c_authmech.bv_val, op->orb_ssf, 0 );
+
+ Debug( LDAP_DEBUG_TRACE,
+ "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
+ op->o_conn->c_authmech.bv_val,
+ BER_BVISNULL( &op->o_conn->c_dn ) ? "<empty>" : op->o_conn->c_dn.bv_val,
+ op->orb_ssf );
+
+ } else if ( rs->sr_err != LDAP_SASL_BIND_IN_PROGRESS ) {
+ if ( !BER_BVISNULL( &op->o_conn->c_sasl_bind_mech ) ) {
+ free( op->o_conn->c_sasl_bind_mech.bv_val );
+ BER_BVZERO( &op->o_conn->c_sasl_bind_mech );
+ }
+ }
+ }
ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
ch_free( cb );
static ber_socket_t wake_sds[2];
static int emfile;
-static int waking;
+static volatile int waking;
#define WAKE_LISTENER(w) do { \
- if ((w) && waking < 5) { \
- waking++; \
+ if ((w) && ++waking < 5) { \
tcp_write( wake_sds[1], "0", 1 ); \
} \
} while(0)
if (!SLAP_SOCK_IS_WRITE(fd)) { FD_SET((fd), &slap_daemon.sd_writers); } \
} while(0)
-# define SLAP_ADDTEST(s) do { } while 0
+# define SLAP_ADDTEST(s)
# define SLAP_EVENT_MAX dtblsize
# else
# define SLAP_SOCK_SET_READ(fd) FD_SET((fd), &slap_daemon.sd_readers)
}
#ifdef HAVE_NT_SERVICE_MANAGER
- if ( started_event != NULL ) }
+ if ( started_event != NULL ) {
ldap_pvt_thread_cond_signal( &started_event );
}
#endif
#if SLAP_EVENTS_ARE_INDEXED
if ( SLAP_EVENT_IS_READ( wake_sds[0] )) {
+ char c[BUFSIZ];
SLAP_EVENT_CLR_READ( wake_sds[0] );
- ns--;
- {
- char c[BUFSIZ];
- tcp_read( wake_sds[0], c, sizeof(c) );
- }
- Debug( LDAP_DEBUG_CONNS, "daemon: waked\n", 0, 0, 0 );
waking = 0;
+ tcp_read( wake_sds[0], c, sizeof(c) );
+ Debug( LDAP_DEBUG_CONNS, "daemon: waked\n", 0, 0, 0 );
continue;
}
/* Handle wake events */
if ( fd == wake_sds[0] ) {
char c[BUFSIZ];
- tcp_read( wake_sds[0], c, sizeof(c) );
waking = 0;
+ tcp_read( wake_sds[0], c, sizeof(c) );
break;
}
{
char *p;
- p = strchr( dn->bv_val, ',' );
+ p = ber_bvchr( dn, ',' );
/* one-level dn */
if ( p == NULL ) {
char *p;
*rdn = *dn;
- p = strchr( dn->bv_val, ',' );
+ p = ber_bvchr( dn, ',' );
/* one-level dn */
if ( p == NULL ) {
return 0;
}
- p = strchr( dn_in->bv_val, ',' );
+ p = ber_bvchr( dn_in, ',' );
return p ? p - dn_in->bv_val : dn_in->bv_len;
}
{
return LDAP_INVALID_SYNTAX;
}
- return strchr( rdn->bv_val, ',' ) == NULL
+ return ber_bvchr( rdn, ',' ) == NULL
? LDAP_SUCCESS : LDAP_INVALID_SYNTAX;
#else
reqdata = *op->ore_reqdata;
}
- if( !(ext = find_extop(supp_ext_list, &op->ore_reqoid )))
- {
+ ext = find_extop(supp_ext_list, &op->ore_reqoid );
+ if ( ext == NULL ) {
Statslog( LDAP_DEBUG_STATS, "%s EXT oid=%s\n",
op->o_log_prefix, op->ore_reqoid.bv_val, 0, 0, 0 );
Debug( LDAP_DEBUG_ANY, "do_extended: unsupported operation \"%s\"\n",
op->ore_reqoid.bv_val, 0 ,0 );
{ /* start of OpenLDAP extended operation */
+ BackendDB *bd = op->o_bd;
+
rs->sr_err = (ext->ext_main)( op, rs );
if( rs->sr_err != SLAPD_ABANDON ) {
}
if ( op->o_bd == NULL )
- op->o_bd = frontendDB;
+ op->o_bd = bd;
send_ldap_extended( op, rs );
if ( rs->sr_ref != default_referral ) {
void *memctx;
BER_MEMFREE_FN *memfree;
#ifdef LDAP_COMP_MATCH
- int i, num_attr_vals;
+ int i, num_attr_vals = 0;
#endif
if ( op == NULL ) {
int valid = 0;
char *rid_ptr;
char *cval;
+ char *next;
if ( cookie == NULL )
return -1;
+ if ( cookie->octet_str.bv_len <= STRLENOF( "rid=" ) )
+ return -1;
+
cookie->rid = -1;
- if (( rid_ptr = strstr( cookie->octet_str.bv_val, "rid=" )) != NULL ) {
- if ( (cval = strchr( rid_ptr, ',' )) != NULL ) {
- *cval = '\0';
- }
- cookie->rid = atoi( rid_ptr + sizeof("rid=") - 1 );
- if ( cval != NULL ) {
- *cval = ',';
- }
- } else {
+ /* FIXME: may read past end of cookie->octet_str.bv_val */
+ rid_ptr = strstr( cookie->octet_str.bv_val, "rid=" );
+ if ( rid_ptr == NULL
+ || rid_ptr > &cookie->octet_str.bv_val[ cookie->octet_str.bv_len - STRLENOF( "rid=" ) ] )
+ {
+ return -1;
+
+ }
+
+ cookie->rid = strtoul( &rid_ptr[ STRLENOF( "rid=" ) ], &next, 10 );
+ if ( next == &rid_ptr[ STRLENOF( "rid=" ) ] || ( next[ 0 ] != ',' && next[ 0 ] != '\0' ) ) {
return -1;
}
if ( ad == NULL )
break;
+ if ( csn_ptr >= &cookie->octet_str.bv_val[ cookie->octet_str.bv_len - STRLENOF( "csn=" ) ] ) {
+ return -1;
+ }
+
csn_str = csn_ptr + STRLENOF("csn=");
cval = strchr( csn_str, ',' );
- if ( cval )
+ if ( cval && cval < &cookie->octet_str.bv_val[ cookie->octet_str.bv_len ] )
csn_str_len = cval - csn_str;
else
csn_str_len = 0;
/* FIXME use csnValidate when it gets implemented */
csn_ptr = strchr( csn_str, '#' );
- if ( !csn_ptr ) break;
+ if ( !csn_ptr || csn_str >= &cookie->octet_str.bv_val[ cookie->octet_str.bv_len ] ) break;
stamp.bv_val = csn_str;
stamp.bv_len = csn_ptr - csn_str;
/* Force new ctx to be created */
ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_CTX, NULL );
- rc = ldap_pvt_tls_init_def_ctx();
+ rc = ldap_pvt_tls_init_def_ctx( 1 );
if( rc == 0 ) {
ldap_pvt_tls_get_option( NULL, LDAP_OPT_X_TLS_CTX, &slap_tls_ctx );
/* Restore previous ctx */
char textbuf[ SLAP_TEXT_BUFLEN ];
size_t textlen = sizeof( textbuf );
- if( op->o_req_ndn.bv_len == 0 ) {
+ if( BER_BVISEMPTY( &op->o_req_ndn ) ) {
Debug( LDAP_DEBUG_ANY, "do_modify: root dse!\n", 0, 0, 0 );
send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
* check that each value is valid per syntax
* and pretty if appropriate
*/
- for ( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) {
+ for ( nvals = 0; !BER_BVISNULL( &ml->sml_values[nvals] ); nvals++ ) {
struct berval pval;
if ( pretty ) {
ml->sml_nvalues = ber_memalloc_x(
(nvals+1)*sizeof(struct berval), ctx );
- for ( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) {
+ for ( nvals = 0; !BER_BVISNULL( &ml->sml_values[nvals] ); nvals++ ) {
#ifdef SLAP_ORDERED_PRETTYNORM
rc = ordered_value_normalize(
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
} else {
csn = op->o_csn;
}
- ptr = strchr( csn.bv_val, '#' );
- if ( ptr ) {
+ ptr = ber_bvchr( &csn, '#' );
+ if ( ptr && ptr < &csn.bv_val[csn.bv_len] ) {
timestamp.bv_len = ptr - csn.bv_val;
if ( timestamp.bv_len >= sizeof( timebuf ))
timestamp.bv_len = sizeof( timebuf ) - 1;
{
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
pp_info *pi = on->on_bi.bi_private;
- int i, rc, mod_pw_only, pwmod, pwmop, deladd,
+ int i, rc, mod_pw_only, pwmod, pwmop = -1, deladd,
hsize = 0;
PassPolicy pp;
- Modifications *mods = NULL, *modtail, *ml, *delmod, *addmod;
+ Modifications *mods = NULL, *modtail = NULL,
+ *ml, *delmod, *addmod;
Attribute *pa, *ha, at;
const char *txt;
pw_hist *tl = NULL, *p;
a_lock = attr_find( e->e_attrs, ad_pwdAccountLockedTime );
a_fail = attr_find( e->e_attrs, ad_pwdFailureTime );
- for( prev = &op->oq_modify.rs_modlist, ml = *prev; ml;
- prev = &ml->sml_next, ml = *prev ) {
+ for( prev = &op->oq_modify.rs_modlist, ml = *prev; ml; ml = *prev ) {
if ( ml->sml_desc == slap_schema.si_ad_userPassword )
got_pw = 1;
*prev = ml->sml_next;
ml->sml_next = NULL;
slap_mods_free( ml, 1 );
+ continue;
}
}
+ prev = &ml->sml_next;
}
/* If we're resetting the password, make sure grace, accountlock,
ppolicy_get( op, e, &pp );
- for(ml = op->oq_modify.rs_modlist,
+ for ( ml = op->oq_modify.rs_modlist,
pwmod = 0, mod_pw_only = 1,
deladd = 0, delmod = NULL,
addmod = NULL,
zapReset = 1;
- ml != NULL; modtail = ml, ml = ml->sml_next ) {
+ ml != NULL; modtail = ml, ml = ml->sml_next )
+ {
if ( ml->sml_desc == pp.ad ) {
pwmod = 1;
pwmop = ml->sml_op;
static AttributeDescription *ad_errText;
static AttributeDescription *ad_errOp;
static AttributeDescription *ad_errSleepTime;
+static AttributeDescription *ad_errMatchedDN;
static ObjectClass *oc_errAbsObject;
static ObjectClass *oc_errObject;
static ObjectClass *oc_errAuxObject;
struct berval rdi_dn;
struct berval rdi_ndn;
struct berval rdi_text;
+ struct berval rdi_matched;
int rdi_err;
BerVarray rdi_ref;
int rdi_sleeptime;
} retcode_t;
static int
-retcode_entry_response( Operation *op, SlapReply *rs, Entry *e );
+retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e );
static int
retcode_cleanup_cb( Operation *op, SlapReply *rs )
static int
retcode_op_add( Operation *op, SlapReply *rs )
{
- return retcode_entry_response( op, rs, op->ora_e );
+ return retcode_entry_response( op, rs, NULL, op->ora_e );
}
typedef struct retcode_cb_t {
+ BackendInfo *rdc_info;
unsigned rdc_flags;
ber_tag_t rdc_tag;
AttributeName *rdc_attrs;
if ( op->o_tag == LDAP_REQ_SEARCH ) {
rs->sr_attrs = rdc->rdc_attrs;
}
- rc = retcode_entry_response( op, rs, rs->sr_entry );
+ rc = retcode_entry_response( op, rs, rdc->rdc_info, rs->sr_entry );
op->o_tag = o_tag;
return rc;
}
if ( rs->sr_err == LDAP_SUCCESS ) {
- rdc->rdc_flags = SLAP_CB_CONTINUE;
+ if ( !op->o_abandon ) {
+ rdc->rdc_flags = SLAP_CB_CONTINUE;
+ }
return 0;
}
db.bd_info = on->on_info->oi_orig;
op2.o_bd = &db;
+ rdc.rdc_info = on->on_info->oi_orig;
rdc.rdc_flags = RETCODE_FINDIR;
if ( op->o_tag == LDAP_REQ_SEARCH ) {
rdc.rdc_attrs = op->ors_attrs;
return retcode_op_add( op, rs );
case LDAP_REQ_BIND:
+ /* skip if rootdn */
if ( be_isroot_pw( op ) ) {
return SLAP_CB_CONTINUE;
}
- /* fallthru */
+ return retcode_op_internal( op, rs );
+
+ case LDAP_REQ_SEARCH:
+ if ( op->ors_scope == LDAP_SCOPE_BASE ) {
+ rs->sr_err = retcode_op_internal( op, rs );
+ if ( rs->sr_err == SLAP_CB_CONTINUE ) {
+ rs->sr_err = LDAP_SUCCESS;
+ }
+ send_ldap_result( op, rs );
+ return rs->sr_err;
+ }
+ break;
case LDAP_REQ_MODIFY:
case LDAP_REQ_DELETE:
case LDAP_REQ_MODRDN:
case LDAP_REQ_COMPARE:
- case LDAP_REQ_SEARCH:
return retcode_op_internal( op, rs );
}
}
} else {
rs->sr_err = rdi->rdi_err;
rs->sr_text = rdi->rdi_text.bv_val;
+ rs->sr_matched = rdi->rdi_matched.bv_val;
/* FIXME: we only honor the rdi_ref field in case rdi_err
* is LDAP_REFERRAL otherwise send_ldap_result() bails out */
}
static int
-retcode_entry_response( Operation *op, SlapReply *rs, Entry *e )
+retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e )
{
- slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
-
Attribute *a;
int err;
char *next;
}
if ( rs->sr_err != LDAP_SUCCESS ) {
- BackendDB db = *op->o_bd;
+ BackendDB db = *op->o_bd,
+ *o_bd = op->o_bd;
void *o_callback = op->o_callback;
/* message text */
rs->sr_text = a->a_vals[ 0 ].bv_val;
}
- db.bd_info = on->on_info->oi_orig;
+ /* matched DN */
+ a = attr_find( e->e_attrs, ad_errMatchedDN );
+ if ( a != NULL ) {
+ rs->sr_matched = a->a_vals[ 0 ].bv_val;
+ }
+
+ if ( bi == NULL ) {
+ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+
+ bi = on->on_info->oi_orig;
+ }
+
+ db.bd_info = bi;
op->o_bd = &db;
op->o_callback = NULL;
}
rs->sr_text = NULL;
+ rs->sr_matched = NULL;
+ op->o_bd = o_bd;
op->o_callback = o_callback;
}
return SLAP_CB_CONTINUE;
}
- return retcode_entry_response( op, rs, rs->sr_entry );
+ return retcode_entry_response( op, rs, NULL, rs->sr_entry );
}
static int
} else if ( strcasecmp( ops[ j ], "compare" ) == 0 ) {
rdi.rdi_mask |= SN_DG_OP_COMPARE;
- } else if ( strcasecmp( ops[ j ], "add" ) == 0 ) {
+ } else if ( strcasecmp( ops[ j ], "delete" ) == 0 ) {
rdi.rdi_mask |= SN_DG_OP_DELETE;
} else if ( strcasecmp( ops[ j ], "modify" ) == 0 ) {
rdi.rdi_mask |= SN_DG_OP_MODIFY;
- } else if ( strcasecmp( ops[ j ], "rename" ) == 0 ) {
+ } else if ( strcasecmp( ops[ j ], "rename" ) == 0
+ || strcasecmp( ops[ j ], "modrdn" ) == 0 )
+ {
rdi.rdi_mask |= SN_DG_OP_RENAME;
} else if ( strcasecmp( ops[ j ], "search" ) == 0 ) {
}
ber_str2bv( &argv[ i ][ STRLENOF( "text=" ) ], 0, 1, &rdi.rdi_text );
+ } else if ( strncasecmp( argv[ i ], "matched=", STRLENOF( "matched=" ) ) == 0 )
+ {
+ struct berval dn;
+
+ if ( !BER_BVISNULL( &rdi.rdi_matched ) ) {
+ fprintf( stderr, "%s: line %d: retcode: "
+ "\"matched\" already provided.\n",
+ fname, lineno );
+ return 1;
+ }
+ ber_str2bv( &argv[ i ][ STRLENOF( "matched=" ) ], 0, 0, &dn );
+ if ( dnPretty( NULL, &dn, &rdi.rdi_matched, NULL ) != LDAP_SUCCESS ) {
+ fprintf( stderr, "%s: line %d: retcode: "
+ "unable to prettify matched DN \"%s\".\n",
+ fname, lineno, &argv[ i ][ STRLENOF( "matched=" ) ] );
+ return 1;
+ }
+
} else if ( strncasecmp( argv[ i ], "ref=", STRLENOF( "ref=" ) ) == 0 )
{
char **refs;
attr_merge_normalize_one( &rdi->rdi_e, ad_errText, &val[ 0 ], NULL );
}
+ /* matched */
+ if ( !BER_BVISNULL( &rdi->rdi_matched ) ) {
+ val[ 0 ] = rdi->rdi_matched;
+
+ attr_merge_normalize_one( &rdi->rdi_e, ad_errMatchedDN, &val[ 0 ], NULL );
+ }
+
/* sleep time */
if ( rdi->rdi_sleeptime > 0 ) {
snprintf( buf, sizeof( buf ), "%d", rdi->rdi_sleeptime );
ber_memfree( rdi->rdi_text.bv_val );
}
+ if ( !BER_BVISNULL( &rdi->rdi_matched ) ) {
+ ber_memfree( rdi->rdi_matched.bv_val );
+ }
+
+ if ( rdi->rdi_ref ) {
+ ber_bvarray_free( rdi->rdi_ref );
+ }
+
BER_BVZERO( &rdi->rdi_e.e_name );
BER_BVZERO( &rdi->rdi_e.e_nname );
ch_free( rdi );
}
+ if ( !BER_BVISNULL( &rd->rd_pdn ) ) {
+ ber_memfree( rd->rd_pdn.bv_val );
+ }
+
+ if ( !BER_BVISNULL( &rd->rd_npdn ) ) {
+ ber_memfree( rd->rd_npdn.bv_val );
+ }
+
ber_memfree( rd );
}
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 "
"SINGLE-VALUE )",
&ad_errSleepTime },
+ { "errMatchedDN", "( 1.3.6.1.4.1.4203.666.11.4.1.5 "
+ "NAME ( 'errMatchedDN' ) "
+ "DESC 'Value to be returned as matched DN' "
+ "EQUALITY distinguishedNameMatch "
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
+ "SINGLE-VALUE )",
+ &ad_errMatchedDN },
{ NULL }
};
"$ errOp "
"$ errText "
"$ errSleepTime "
+ "$ errMatchedDN "
") )",
&oc_errAbsObject },
{ "errObject", "( 1.3.6.1.4.1.4203.666.11.4.3.1 "
* CSN, and generate Present records for them. We always collect this result
* in SyncID sets, even if there's only one match.
*/
-#define FIND_MAXCSN 1
-#define FIND_CSN 2
-#define FIND_PRESENT 3
+typedef enum find_csn_t {
+ FIND_MAXCSN = 1,
+ FIND_CSN = 2,
+ FIND_PRESENT = 3
+} find_csn_t;
static int
findmax_cb( Operation *op, SlapReply *rs )
}
static int
-syncprov_findcsn( Operation *op, int mode )
+syncprov_findcsn( Operation *op, find_csn_t mode )
{
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
syncprov_info_t *si = on->on_bi.bi_private;
Operation nop = *op;
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
struct berval dn = { 0, NULL };
- char *odn = op->o_req_ndn.bv_val;
Attribute *a;
Entry *e;
- int idn, ldn;
-
- /* tis more work to use strchr() for a berval... */
- for(idn = 0; odn[idn] && odn[idn] != ','; idn++);
- if(!idn || !odn[idn]) return; /* because you never know */
- idn++;
- ldn = dn.bv_len = op->o_req_ndn.bv_len - idn;
- dn.bv_val = ch_malloc(ldn + 1);
- strcpy(dn.bv_val, odn + idn);
+ struct berval pdn;
+
+ dnParent( &op->o_req_ndn, &pdn );
+ ber_dupbv( &dn, &pdn );
Debug(LDAP_DEBUG_TRACE, "=> glue_parent: fabricating glue for <%s>\n", dn.bv_val, 0, 0);
do_sort( Operation *op, Attribute *a, int beg, int num, slap_mask_t sort )
{
int i, j, gotnvals;
- struct berval tmp, ntmp, *vals, *nvals;
+ struct berval tmp, ntmp, *vals = NULL, *nvals;
gotnvals = (a->a_vals != a->a_nvals );
gotnvals = (a->a_vals != a->a_nvals );
for (i=0; i<n; i++) {
- char *ptr = strchr( a->a_nvals[i].bv_val, '{' );
+ char *ptr = ber_bvchr( &a->a_nvals[i], '{' );
char *end = NULL;
if ( !ptr ) {
Debug(LDAP_DEBUG_TRACE, "weights missing from attr %s "
if ( a->a_vals != a->a_nvals ) {
ptr = a->a_vals[i].bv_val;
- end = strchr( ptr, '}' ) + 1;
+ end = ber_bvchr( &a->a_vals[i], '}' );
+ assert( end != NULL );
+ end++;
for (;*end;)
*ptr++ = *end++;
*ptr = '\0';
if ( !a )
continue;
for (i=0; !BER_BVISNULL( &a->a_vals[i] ); i++) {
- ptr = strchr(a->a_vals[i].bv_val, '{' );
+ ptr = ber_bvchr(&a->a_vals[i], '{' );
if ( !ptr ) {
Debug(LDAP_DEBUG_TRACE, "weight missing from attribute %s\n",
vi->vi_ad->ad_cname.bv_val, 0, 0);
if ( !ml )
continue;
for (i=0; !BER_BVISNULL( &ml->sml_values[i] ); i++) {
- ptr = strchr(ml->sml_values[i].bv_val, '{' );
+ ptr = ber_bvchr(&ml->sml_values[i], '{' );
if ( !ptr ) {
Debug(LDAP_DEBUG_TRACE, "weight missing from attribute %s\n",
vi->vi_ad->ad_cname.bv_val, 0, 0);
qpw->rs_old.bv_val ? " old" : "",
qpw->rs_new.bv_val ? " new" : "", 0 );
} else {
- Statslog( LDAP_DEBUG_STATS, "%s PASSMOD %s%s\n",
+ Statslog( LDAP_DEBUG_STATS, "%s PASSMOD%s%s\n",
op->o_log_prefix,
qpw->rs_old.bv_val ? " old" : "",
qpw->rs_new.bv_val ? " new" : "", 0, 0 );
error_return:;
if ( !BER_BVISNULL( &op->o_req_dn ) ) {
op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+ BER_BVZERO( &op->o_req_dn );
}
if ( !BER_BVISNULL( &op->o_req_ndn ) ) {
op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+ BER_BVZERO( &op->o_req_ndn );
}
return rc;
#endif /* SLAP_DYNACL */
LDAP_SLAPD_F (int) acl_init LDAP_P(( void ));
-LDAP_SLAPD_V (const struct berval) aci_bv[];
-
LDAP_SLAPD_F (int) acl_get_part LDAP_P((
struct berval *list,
int ix,
struct berval *subj,
Operation *op,
Entry *e,
- int setref ));
+ struct berval *default_set_attribute ));
LDAP_SLAPD_F (int) acl_string_expand LDAP_P((
struct berval *newbuf, struct berval *pattern,
char *match, int nmatch, regmatch_t *matches ));
LDAP_SLAPD_F (int) loglevel2bvarray LDAP_P(( int l, BerVarray *bva ));
LDAP_SLAPD_F (const char *) loglevel2str LDAP_P(( int l ));
LDAP_SLAPD_F (int) loglevel2bv LDAP_P(( int l, struct berval *bv ));
+LDAP_SLAPD_F (int) slap_cf_aux_table_parse LDAP_P(( const char *word, void *bc, slap_cf_aux_table *tab0, LDAP_CONST char *tabmsg ));
+LDAP_SLAPD_F (int) slap_cf_aux_table_unparse LDAP_P(( void *bc, struct berval *bv, slap_cf_aux_table *tab0 ));
/*
* ch_malloc.c
{
int rc;
+ /* map SASL errors to LDAP resultCode returned by:
+ * sasl_server_new()
+ * SASL_OK, SASL_NOMEM
+ * sasl_server_step()
+ * SASL_OK, SASL_CONTINUE, SASL_TRANS, SASL_BADPARAM, SASL_BADPROT,
+ * ...
+ * sasl_server_start()
+ * + SASL_NOMECH
+ * sasl_setprop()
+ * SASL_OK, SASL_BADPARAM
+ */
+
switch (saslerr) {
case SASL_OK:
rc = LDAP_SUCCESS;
rc = LDAP_SASL_BIND_IN_PROGRESS;
break;
case SASL_FAIL:
- rc = LDAP_OTHER;
- break;
case SASL_NOMEM:
rc = LDAP_OTHER;
break;
rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
break;
case SASL_BADAUTH:
+ case SASL_NOUSER:
+ case SASL_TRANS:
+ case SASL_EXPIRED:
rc = LDAP_INVALID_CREDENTIALS;
break;
case SASL_NOAUTHZ:
case SASL_ENCRYPT:
rc = LDAP_INAPPROPRIATE_AUTH;
break;
+ case SASL_UNAVAIL:
+ case SASL_TRYAGAIN:
+ rc = LDAP_UNAVAILABLE;
+ break;
+ case SASL_DISABLED:
+ rc = LDAP_UNWILLING_TO_PERFORM;
+ break;
default:
rc = LDAP_OTHER;
break;
* u[.mech[/realm]]:user
*/
- user->bv_val = strchr( id->bv_val, ':' );
+ user->bv_val = ber_bvchr( id, ':' );
if ( BER_BVISNULL( user ) ) {
return LDAP_PROTOCOL_ERROR;
}
user->bv_val++;
user->bv_len = id->bv_len - ( user->bv_val - id->bv_val );
- mech->bv_val = strchr( id->bv_val, '.' );
+ mech->bv_val = ber_bvchr( id, '.' );
if ( !BER_BVISNULL( mech ) ) {
mech->bv_val[ 0 ] = '\0';
mech->bv_val++;
+ mech->bv_len = user->bv_val - mech->bv_val - 1;
- realm->bv_val = strchr( mech->bv_val, '/' );
+ realm->bv_val = ber_bvchr( mech, '/' );
if ( !BER_BVISNULL( realm ) ) {
realm->bv_val[ 0 ] = '\0';
realm->bv_val++;
mech->bv_len = realm->bv_val - mech->bv_val - 1;
realm->bv_len = user->bv_val - realm->bv_val - 1;
- } else {
- mech->bv_len = user->bv_val - mech->bv_val - 1;
}
} else {
member_at = BER_BVNULL;
bv.bv_val = in->bv_val + STRLENOF( "group" );
- group_dn.bv_val = strchr( bv.bv_val, ':' );
+ bv.bv_len = in->bv_len - STRLENOF( "group" );
+ group_dn.bv_val = ber_bvchr( &bv, ':' );
if ( group_dn.bv_val == NULL ) {
/* last chance: assume it's a(n exact) DN ... */
bv.bv_val = in->bv_val;
*/
if ( bv.bv_val[ 0 ] == '/' ) {
group_oc.bv_val = &bv.bv_val[ 1 ];
+ group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
- member_at.bv_val = strchr( group_oc.bv_val, '/' );
+ member_at.bv_val = ber_bvchr( &group_oc, '/' );
if ( member_at.bv_val ) {
AttributeDescription *ad = NULL;
const char *text = NULL;
if ( rc != LDAP_SUCCESS ) {
return rc;
}
+ }
- } else {
- group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
-
- if ( oc_bvfind( &group_oc ) == NULL ) {
- return LDAP_INVALID_SYNTAX;
- }
+ if ( oc_bvfind( &group_oc ) == NULL ) {
+ return LDAP_INVALID_SYNTAX;
}
}
char *ptr;
bv.bv_val = val->bv_val + STRLENOF( "group" );
- group_dn.bv_val = strchr( bv.bv_val, ':' );
+ bv.bv_len = val->bv_len - STRLENOF( "group" );
+ group_dn.bv_val = ber_bvchr( &bv, ':' );
if ( group_dn.bv_val == NULL ) {
/* last chance: assume it's a(n exact) DN ... */
bv.bv_val = val->bv_val;
* are present in schema...
*/
if ( bv.bv_val[ 0 ] == '/' ) {
+ ObjectClass *oc = NULL;
+
group_oc.bv_val = &bv.bv_val[ 1 ];
+ group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
- member_at.bv_val = strchr( group_oc.bv_val, '/' );
+ member_at.bv_val = ber_bvchr( &group_oc, '/' );
if ( member_at.bv_val ) {
AttributeDescription *ad = NULL;
const char *text = NULL;
member_at = ad->ad_cname;
- } else {
- ObjectClass *oc = NULL;
-
- group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
-
- oc = oc_bvfind( &group_oc );
- if ( oc == NULL ) {
- return LDAP_INVALID_SYNTAX;
- }
+ }
- group_oc = oc->soc_cname;
+ oc = oc_bvfind( &group_oc );
+ if ( oc == NULL ) {
+ return LDAP_INVALID_SYNTAX;
}
+
+ group_oc = oc->soc_cname;
}
group_dn.bv_val++;
if ( idx.bv_val[ 0 ] == '{' ) {
char *ptr;
- ptr = strchr( idx.bv_val, '}' ) + 1;
+ ptr = ber_bvchr( &idx, '}' ) + 1;
assert( ptr != (void *)1 );
char *tmp;
bv.bv_val = uri->bv_val + STRLENOF( "group" );
- group_dn.bv_val = strchr( bv.bv_val, ':' );
+ bv.bv_len = uri->bv_len - STRLENOF( "group" );
+ group_dn.bv_val = ber_bvchr( &bv, ':' );
if ( group_dn.bv_val == NULL ) {
/* last chance: assume it's a(n exact) DN ... */
bv.bv_val = uri->bv_val;
if ( bv.bv_val[ 0 ] == '/' ) {
group_oc.bv_val = &bv.bv_val[ 1 ];
+ group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
- member_at.bv_val = strchr( group_oc.bv_val, '/' );
+ member_at.bv_val = ber_bvchr( &group_oc, '/' );
if ( member_at.bv_val ) {
group_oc.bv_len = member_at.bv_val - group_oc.bv_val;
member_at.bv_val++;
member_at.bv_len = group_dn.bv_val - member_at.bv_val;
} else {
- group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
BER_BVSTR( &member_at, SLAPD_GROUP_ATTR );
}
int rc;
AttributeDescription *desc = NULL;
struct berval rdn = frontendDB->be_schemadn;
- vals[0].bv_val = strchr( rdn.bv_val, '=' );
+ vals[0].bv_val = ber_bvchr( &rdn, '=' );
if( vals[0].bv_val == NULL ) {
*text = "improperly configured subschema subentry";
return LDAP_OTHER;
}
- nvals[0].bv_val = strchr( frontendDB->be_schemandn.bv_val, '=' );
+ nvals[0].bv_val = ber_bvchr( &frontendDB->be_schemandn, '=' );
assert( nvals[0].bv_val != NULL );
nvals[0].bv_val++;
nvals[0].bv_len = frontendDB->be_schemandn.bv_len -
struct berval sn, i;
if( in->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
- i.bv_val = strchr( in->bv_val, '$' );
+ i.bv_val = ber_bvchr( in, '$' );
if( BER_BVISNULL( &i ) ) return LDAP_INVALID_SYNTAX;
sn.bv_val = in->bv_val;
if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
- i.bv_val = strchr( val->bv_val, '$' );
+ i.bv_val = ber_bvchr( val, '$' );
if( BER_BVISNULL( &i ) ) return LDAP_INVALID_SYNTAX;
sn.bv_val = val->bv_val;
if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
- i.bv_val = strchr( val->bv_val, '$' );
+ i.bv_val = ber_bvchr( val, '$' );
if( BER_BVISNULL( &i ) ) return LDAP_INVALID_SYNTAX;
sn.bv_val = val->bv_val;
} slap_aci_scope_t;
#endif /* SLAPD_ACI_ENABLED */
-enum {
- ACI_BV_ENTRY,
- ACI_BV_CHILDREN,
- ACI_BV_ONELEVEL,
- ACI_BV_SUBTREE,
- ACI_BV_BR_ENTRY,
- ACI_BV_BR_ALL,
- ACI_BV_ACCESS_ID,
-#if 0
- ACI_BV_ANONYMOUS = BER_BVC("anonymous"),
-#endif
- ACI_BV_PUBLIC,
- ACI_BV_USERS,
- ACI_BV_SELF,
- ACI_BV_DNATTR,
- ACI_BV_GROUP,
- ACI_BV_ROLE,
- ACI_BV_SET,
- ACI_BV_SET_REF,
- ACI_BV_GRANT,
- ACI_BV_DENY,
-
- ACI_BV_IP_EQ,
-#ifdef LDAP_PF_LOCAL
- ACI_BV_PATH_EQ,
-#if 0
- ACI_BV_DIRSEP,
-#endif
-#endif /* LDAP_PF_LOCAL */
-
- ACI_BV_GROUP_CLASS,
- ACI_BV_GROUP_ATTR,
- ACI_BV_ROLE_CLASS,
- ACI_BV_ROLE_ATTR,
- ACI_BV_SET_ATTR,
-
- ACI_BV_LAST
-};
-
/*
* Backend-info
* represents a backend
const slap_mask_t mask;
} slap_verbmasks;
+typedef struct slap_cf_aux_table {
+ struct berval key;
+ int off;
+ char type;
+ char quote;
+ slap_verbmasks *aux;
+} slap_cf_aux_table;
+
#define SLAP_LIMIT_TIME 1
#define SLAP_LIMIT_SIZE 2
int truncatemode = 0;
int use_glue = 1;
+#ifdef LDAP_DEBUG
+ /* tools default to "none", so that at least LDAP_DEBUG_ANY
+ * messages show up; use -d 0 to reset */
+ ldap_debug = LDAP_DEBUG_NONE;
+#endif
+
#ifdef CSRIMALLOC
leakfilename = malloc( strlen( progname ) + STRLENOF( ".leak" ) + 1 );
sprintf( leakfilename, "%s.leak", progname );
break;
case 'd': /* turn on debugging */
+ {
#ifdef LDAP_DEBUG
+ int level;
+
if ( optarg != NULL && optarg[ 0 ] != '-' && !isdigit( optarg[ 0 ] ) )
{
- int level;
-
if ( str2loglevel( optarg, &level ) ) {
fprintf( stderr,
"unrecognized log level "
exit( EXIT_FAILURE );
}
- ldap_debug |= level;
-
} else {
- int level;
char *next = NULL;
level = strtol( optarg, &next, 0 );
"\"%s\"\n", optarg );
exit( EXIT_FAILURE );
}
+ }
+
+ if ( level ) {
ldap_debug |= level;
+ } else {
+ /* allow to reset log level */
+ ldap_debug = 0;
}
#else
if ( atoi( optarg ) != 0 )
fputs( "must compile with LDAP_DEBUG for debugging\n",
stderr );
#endif
- break;
+ } break;
case 'D':
ber_str2bv( optarg, 0, 1, &authcDN );
case SLAPI_X_CONN_SSF:
PBLOCK_ASSERT_CONN( pb );
PBLOCK_LOCK_CONN( pb );
- pb->pb_conn->c_ssf = (slap_ssf_t)value;
+ pb->pb_conn->c_ssf = (slap_ssf_t)(long)value;
PBLOCK_UNLOCK_CONN( pb );
break;
case SLAPI_X_CONN_SASL_CONTEXT:
save_errno, strerror( save_errno ) );
return -1;
}
+
+ return 0;
}
int
rctrlp = *rctrls;
ber_init2( ber, &rctrlp->ldctl_value, LBER_USE_DER );
ber_scanf( ber, "{em" /*"}"*/, &syncstate, &syncUUID );
- /* FIXME: what if syncUUID is NULL or empty? */
+ /* FIXME: what if syncUUID is NULL or empty?
+ * (happens with back-sql...) */
+ if ( BER_BVISEMPTY( &syncUUID ) ) {
+ Debug( LDAP_DEBUG_ANY, "do_syncrep2: "
+ "got empty syncUUID\n", 0, 0, 0 );
+ rc = -1;
+ goto done;
+ }
if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
ber_scanf( ber, /*"{"*/ "m}", &cookie );
if ( !BER_BVISNULL( &cookie ) ) {
ad = NULL;
bv = vals[i];
- colon = strchr( bv.bv_val, ':' );
+ colon = ber_bvchr( &bv, ':' );
if ( !colon )
continue; /* invalid */
bv.bv_len = colon - bv.bv_val;
int rc;
int suffrdns;
int i;
- struct berval dn = {0, NULL};
- struct berval ndn = {0, NULL};
+ struct berval dn = BER_BVNULL;
+ struct berval ndn = BER_BVNULL;
Entry *glue;
SlapReply rs_add = {REP_RESULT};
- char *ptr, *comma;
+ struct berval ptr, nptr;
+ char *comma;
op->o_tag = LDAP_REQ_ADD;
op->o_callback = &cb;
/* count RDNs in suffix */
if ( !BER_BVISEMPTY( &be->be_nsuffix[0] ) ) {
- for ( i = 0, ptr = be->be_nsuffix[0].bv_val; ptr; ptr = strchr( ptr, ',' ) ) {
- ptr++;
+ for ( i = 0, ptr = be->be_nsuffix[0], comma = ptr.bv_val; comma != NULL; comma = ber_bvchr( &ptr, ',' ) ) {
+ comma++;
+ ptr.bv_len -= comma - ptr.bv_val;
+ ptr.bv_val = comma;
i++;
}
suffrdns = i;
}
/* Start with BE suffix */
- for ( i = 0, ptr = NULL; i < suffrdns; i++ ) {
- comma = strrchr( dn.bv_val, ',' );
- if ( ptr ) *ptr = ',';
- if ( comma ) *comma = '\0';
- ptr = comma;
+ ptr = dn;
+ for ( i = 0; i < suffrdns; i++ ) {
+ comma = ber_bvrchr( &ptr, ',' );
+ if ( comma != NULL ) {
+ ptr.bv_len = comma - ptr.bv_val;
+ } else {
+ ptr.bv_len = 0;
+ break;
+ }
}
- if ( ptr ) {
- *ptr++ = ',';
- dn.bv_len -= ptr - dn.bv_val;
- dn.bv_val = ptr;
+
+ if ( !BER_BVISEMPTY( &ptr ) ) {
+ dn.bv_len -= ptr.bv_len + 1;
+ dn.bv_val += ptr.bv_len + 1;
}
+
/* the normalizedDNs are always the same length, no counting
* required.
*/
+ nptr = ndn;
if ( ndn.bv_len > be->be_nsuffix[0].bv_len ) {
ndn.bv_val += ndn.bv_len - be->be_nsuffix[0].bv_len;
ndn.bv_len = be->be_nsuffix[0].bv_len;
+
+ nptr.bv_len = ndn.bv_val - nptr.bv_val - 1;
+
+ } else {
+ nptr.bv_len = 0;
}
while ( ndn.bv_val > e->e_nname.bv_val ) {
}
/* Move to next child */
- for (ptr = dn.bv_val-2; ptr > e->e_name.bv_val && *ptr != ','; ptr--) {
- /* empty */
- }
- if ( ptr == e->e_name.bv_val ) break;
- dn.bv_val = ++ptr;
- dn.bv_len = e->e_name.bv_len - (ptr-e->e_name.bv_val);
- for( ptr = ndn.bv_val-2;
- ptr > e->e_nname.bv_val && *ptr != ',';
- ptr--)
- {
- /* empty */
+ comma = ber_bvrchr( &ptr, ',' );
+ if ( comma == NULL ) {
+ break;
}
- ndn.bv_val = ++ptr;
- ndn.bv_len = e->e_nname.bv_len - (ptr-e->e_nname.bv_val);
+ ptr.bv_len = comma - ptr.bv_val;
+
+ dn.bv_val = ++comma;
+ dn.bv_len = e->e_name.bv_len - (dn.bv_val - e->e_name.bv_val);
+
+ comma = ber_bvrchr( &nptr, ',' );
+ assert( comma != NULL );
+ nptr.bv_len = comma - nptr.bv_val;
+
+ ndn.bv_val = ++comma;
+ ndn.bv_len = e->e_nname.bv_len - (ndn.bv_val - e->e_nname.bv_val);
}
op->o_req_dn = e->e_name;
ibv.bv_len = sprintf(ibv.bv_val, "{%d}", i);
vtmp = a->a_vals[i];
if ( vtmp.bv_val[0] == '{' ) {
- ptr = strchr(vtmp.bv_val, '}') + 1;
+ ptr = ber_bvchr(&vtmp, '}');
+ assert( ptr != NULL );
+ ++ptr;
vtmp.bv_len -= ptr - vtmp.bv_val;
vtmp.bv_val = ptr;
}
if ( a->a_nvals && a->a_nvals != a->a_vals ) {
vtmp = a->a_nvals[i];
if ( vtmp.bv_val[0] == '{' ) {
- ptr = strchr(vtmp.bv_val, '}') + 1;
+ ptr = ber_bvchr(&vtmp, '}');
+ assert( ptr != NULL );
+ ++ptr;
vtmp.bv_len -= ptr - vtmp.bv_val;
vtmp.bv_val = ptr;
}
if ( a->a_vals[i].bv_val[0] == '{' ) {
char *ptr;
index = 1;
- ptr = strchr( a->a_vals[i].bv_val, '}' );
+ ptr = ber_bvchr( &a->a_vals[i], '}' );
if ( !ptr )
return LDAP_INVALID_SYNTAX;
if ( noindex )
a->a_nvals = ch_malloc( (vals+1)*sizeof(struct berval));
BER_BVZERO(a->a_nvals+vals);
for ( i=0; i<vals; i++ ) {
- ptr = strchr(a->a_vals[i].bv_val, '}') + 1;
+ char *ptr = ber_bvchr(&a->a_vals[i], '}') + 1;
a->a_nvals[i].bv_len = a->a_vals[i].bv_len -
(ptr - a->a_vals[i].bv_val);
a->a_nvals[i].bv_val = ch_malloc( a->a_nvals[i].bv_len + 1);
}
} else {
for ( i=0; i<vals; i++ ) {
- ptr = strchr(a->a_nvals[i].bv_val, '}') + 1;
+ char *ptr = ber_bvchr(&a->a_nvals[i], '}') + 1;
a->a_nvals[i].bv_len -= ptr - a->a_nvals[i].bv_val;
strcpy(a->a_nvals[i].bv_val, ptr);
}
if ( bv.bv_val[0] == '{' ) {
char *ptr;
- ptr = strchr( bv.bv_val, '}' );
+ ptr = ber_bvchr( &bv, '}' );
if ( ptr == NULL ) {
return LDAP_INVALID_SYNTAX;
}
if ( bv.bv_val[0] == '{' ) {
char *ptr;
- ptr = strchr( bv.bv_val, '}' );
+ ptr = ber_bvchr( &bv, '}' );
if ( ptr == NULL ) {
return LDAP_INVALID_SYNTAX;
}
if ( ad->ad_type->sat_flags & SLAP_AT_ORDERED ) {
/* Skip past the assertion index */
- if ( bv.bv_val[0] == '{' ) {
+ if ( bv.bv_val[ 0 ] == '{' ) {
char *ptr;
- ptr = strchr( bv.bv_val, '}' );
+ ptr = ber_bvchr( &bv, '}' );
if ( ptr == NULL ) {
return LDAP_INVALID_SYNTAX;
}
/* Skip past the assertion index */
if ( bv2.bv_val[0] == '{' ) {
- ptr = strchr( bv2.bv_val, '}' ) + 1;
+ ptr = ber_bvchr( &bv2, '}' );
+ if ( ptr == NULL ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+ ptr++;
bv2.bv_len -= ptr - bv2.bv_val;
bv2.bv_val = ptr;
v2 = &bv2;
}
/* Skip past the attribute index */
if ( bv1.bv_val[0] == '{' ) {
- ptr = strchr( bv1.bv_val, '}' ) + 1;
+ ptr = ber_bvchr( &bv1, '}' );
+ if ( ptr == NULL ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+ ptr++;
bv1.bv_len -= ptr - bv1.bv_val;
bv1.bv_val = ptr;
v1 = &bv1;
}
for (i=0; i<vnum; i++) {
+ char *next;
+
k = -1;
if ( vals[i].bv_val[0] == '{' ) {
- k = strtol( vals[i].bv_val+1, NULL, 0 );
+ k = strtol( vals[i].bv_val+1, &next, 0 );
+ if ( next == vals[i].bv_val + 1 ||
+ next[ 0 ] != '}' ||
+ next - vals[i].bv_val > vals[i].bv_len )
+ {
+ return -1;
+ }
if ( k > anum ) k = -1;
}
/* No index, or index is greater than current number of
static void add_replica LDAP_P(( char **, int ));
static int parse_replica_line LDAP_P(( char **, int, Ri *));
static void parse_line LDAP_P(( char * ));
-static char *getline LDAP_P(( FILE * ));
+static char *slurpd_getline LDAP_P(( FILE * ));
static char *strtok_quote LDAP_P(( char *, char * ));
int cargc = 0, cargv_size = 0;
}
lineno = 0;
- while ( (line = getline( fp )) != NULL ) {
+ while ( (line = slurpd_getline( fp )) != NULL ) {
/* skip comments and blank lines */
if ( line[0] == '#' || line[0] == '\0' ) {
continue;
* Get a line of input.
*/
static char *
-getline(
+slurpd_getline(
FILE *fp
)
{
}
#ifdef HAVE_TLS
- if( ldap_pvt_tls_init() || ldap_pvt_tls_init_def_ctx() ) {
+ if( ldap_pvt_tls_init() || ldap_pvt_tls_init_def_ctx( 0 ) ) {
rc = 0;
/* See if we actually need TLS */
for ( i=0; i < sglob->num_replicas; i++ ) {
}
#endif
- if ( slurpd_pid_file != NULL ) {
- FILE *fp = fopen( slurpd_pid_file, "w" );
+ /*
+ * don't open pid/args file in one-shot mode (ITS#4152)
+ *
+ * bail out if files were specified but cannot be opened (ITS#4074)
+ */
+ if ( !sglob->one_shot_mode) {
+ if ( slurpd_pid_file != NULL ) {
+ FILE *fp = fopen( slurpd_pid_file, "w" );
+
+ if ( fp == NULL ) {
+ int save_errno = errno;
+
+ fprintf( stderr, "unable to open pid file "
+ "\"%s\": %d (%s)\n",
+ slurpd_pid_file,
+ save_errno, strerror( save_errno ) );
+
+ free( slurpd_pid_file );
+ slurpd_pid_file = NULL;
+
+ rc = 1;
+ goto stop;
+ }
- if( fp != NULL ) {
fprintf( fp, "%d\n", (int) getpid() );
fclose( fp );
-
- } else {
- free(slurpd_pid_file);
- slurpd_pid_file = NULL;
}
- }
- if ( slurpd_args_file != NULL ) {
- FILE *fp = fopen( slurpd_args_file, "w" );
+ if ( slurpd_args_file != NULL ) {
+ FILE *fp = fopen( slurpd_args_file, "w" );
+
+ if ( fp == NULL ) {
+ int save_errno = errno;
+
+ fprintf( stderr, "unable to open args file "
+ "\"%s\": %d (%s)\n",
+ slurpd_args_file,
+ save_errno, strerror( save_errno ) );
+
+ free( slurpd_args_file );
+ slurpd_pid_file = NULL;
+
+ rc = 1;
+ goto stop;
+ }
- if( fp != NULL ) {
for ( i = 0; i < argc; i++ ) {
fprintf( fp, "%s ", argv[i] );
}
fprintf( fp, "\n" );
fclose( fp );
- } else {
- free(slurpd_args_file);
- slurpd_args_file = NULL;
}
}
# refldap://localhost:9016/cn=Somewhere,ou=Meta,dc=example,dc=com??sub
+# searching filter="(member=cn=Another Added Group,ou=Groups,o=Example,c=US)"
+# attrs="member"
+# base="o=Example,c=US"
+# with a timed out connection...
+dn: cn=Another Added Group,ou=Groups,o=Example,c=US
+member: cn=Added Group,ou=Groups,o=Example,c=US
+member: cn=Another Added Group,ou=Groups,o=Example,c=US
+
+# refldap://localhost:9016/cn=Somewhere,ou=Meta,dc=example,dc=com??sub
+
retcode-item "cn=strongAuthNotSupported" 0x07 text="same as authMethodNotSupported"
retcode-item "cn=strongAuthRequired" 0x08
retcode-item "cn=strongerAuthRequired" 0x08 text="same as strongAuthRequired"
-#retcode-item "cn=partialResults" 0x09 "LDAPv2+ (not LDAPv3)"
+#retcode-item "cn=partialResults" 0x09 text="LDAPv2+ (not LDAPv3)"
retcode-item "cn=referral" 0x0a text="LDAPv3" ref="ldap://:9019"
retcode-item "cn=adminLimitExceeded" 0x0b text="LDAPv3"
# cn=monitor, cn=schema, and cn=config
#
-access to attr=userpassword
+access to attrs=userpassword
by self =wx
by anonymous =x
#ldbm#index cn,sn,uid pres,eq,sub
access to dn.exact="cn=Proxy,ou=Admin,dc=example,dc=com"
- attr=authzTo
+ attrs=authzTo
by dn.exact="cn=Proxy,ou=Admin,dc=example,dc=com" =wx
by * =x
#rwmmod#modulepath ../servers/slapd/overlays/
#rwmmod#moduleload rwm.la
+idletimeout 5
+
#######################################################################
# database definitions
#######################################################################
# cn=monitor, cn=schema, and cn=config
#
-access to attr=userpassword
- by self =wx
+access to attrs=userpassword
+ by self =w
by anonymous =x
access to *
# cn=monitor, cn=schema, and cn=config
#
-access to attr=userpassword
- by self =wx
+access to attrs=userpassword
+ by self =w
by anonymous =x
access to *
"-f <addfile> "
"[-l <loops>] "
"[-r <maxretries>] "
- "[-t <delay>]\n",
+ "[-t <delay>] "
+ "[-F]\n",
name );
exit( EXIT_FAILURE );
}
#include <stdio.h>
#include <ac/stdlib.h>
+#include <ac/time.h>
#include <ac/ctype.h>
#include <ac/param.h>
#include <ac/string.h>
#include <ac/unistd.h>
#include <ac/wait.h>
+#include <ac/time.h>
#define LDAP_DEPRECATED 1
#include <ldap.h>
#define LOOPS 100
static int
-do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop );
+do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop,
+ int force );
static int
-do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop );
+do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop,
+ int force );
/* This program can be invoked two ways: if -D is used to specify a Bind DN,
* that DN will be used repeatedly for all of the Binds. If instead -b is used
static void
usage( char *name )
{
- fprintf( stderr, "usage: %s [-h <host>] -p port (-D <dn>|-b <baseDN>) -w <passwd> [-l <loops>]\n",
+ fprintf( stderr, "usage: %s [-h <host>] -p port (-D <dn>|-b <baseDN> [-f <searchfilter>]) -w <passwd> [-l <loops>] [-F]\n",
name );
exit( EXIT_FAILURE );
}
{
int i;
char *uri = NULL;
- char *host = "localhost";
+ char *host = "localhost";
char *dn = NULL;
char *base = NULL;
char *pass = NULL;
- int port = -1;
- int loops = LOOPS;
+ int port = -1;
+ int loops = LOOPS;
+ int force = 0;
- while ( (i = getopt( argc, argv, "b:H:h:p:D:w:l:" )) != EOF ) {
+ while ( (i = getopt( argc, argv, "b:H:h:p:D:w:l:f:F" )) != EOF ) {
switch( i ) {
case 'b': /* base DN of a tree of user DNs */
base = strdup( optarg );
loops = atoi( optarg );
break;
+ case 'f':
+ filter = optarg;
+ break;
+
+ case 'F':
+ force = 1;
+ break;
+
default:
usage( argv[0] );
break;
usage( argv[0] );
if ( base )
- do_base( uri, host, port, base, pass, ( 20 * loops ));
+ do_base( uri, host, port, base, pass, ( 20 * loops ), force );
else
- do_bind( uri, host, port, dn, pass, ( 20 * loops ));
+ do_bind( uri, host, port, dn, pass, ( 20 * loops ), force );
exit( EXIT_SUCCESS );
}
static int
-do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop )
+do_bind( char *uri, char *host, int port, char *dn, char *pass, int maxloop,
+ int force )
{
LDAP *ld = NULL;
- int i, rc;
- char *attrs[] = { "1.1", NULL };
+ int i, rc = -1;
pid_t pid = getpid();
if ( maxloop > 1 )
(long) pid, maxloop, dn );
for ( i = 0; i < maxloop; i++ ) {
- LDAPMessage *res;
-
if ( uri ) {
ldap_initialize( &ld, uri );
} else {
ldap_perror( ld, "ldap_bind" );
}
ldap_unbind( ld );
- if ( rc != LDAP_SUCCESS ) {
+ if ( rc != LDAP_SUCCESS && !force ) {
break;
}
}
static int
-do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop )
+do_base( char *uri, char *host, int port, char *base, char *pass, int maxloop,
+ int force )
{
LDAP *ld = NULL;
int i = 0;
char **rdns = NULL;
char *attrs[] = { "dn", NULL };
int nrdns = 0;
- time_t beg, end;
+#ifdef _WIN32
+ DWORD beg, end;
+#else
+ struct timeval beg, end;
+#endif
srand(pid);
}
ldap_unbind( ld );
- beg = time(0L);
+#ifdef _WIN32
+ beg = GetTickCount();
+#else
+ gettimeofday( &beg, NULL );
+#endif
+
+ if ( nrdns == 0 ) {
+ fprintf( stderr, "No RDNs.\n" );
+ return 1;
+ }
+
/* Ok, got list of RDNs, now start binding to each */
for (i=0; i<maxloop; i++) {
char dn[BUFSIZ], *ptr;
ptr = lutil_strcopy(dn, rdns[j]);
*ptr++ = ',';
strcpy(ptr, base);
- if ( do_bind( uri, host, port, dn, pass, 1 ))
+ if ( do_bind( uri, host, port, dn, pass, 1, force ) && !force )
break;
}
- end = time(0L);
- fprintf( stderr, "Done %d Binds in %d seconds.\n", i, end - beg );
+#ifdef _WIN32
+ end = GetTickCount();
+ end -= beg;
+
+ fprintf( stderr, "Done %d Binds in %d.%03d seconds.\n", i,
+ end / 1000, end % 1000 );
+#else
+ gettimeofday( &end, NULL );
+ end.tv_usec -= beg.tv_usec;
+ if (end.tv_usec < 0 ) {
+ end.tv_usec += 1000000;
+ end.tv_sec -= 1;
+ }
+ end.tv_sec -= beg.tv_sec;
+
+ fprintf( stderr, "Done %d Binds in %ld.%06ld seconds.\n", i,
+ (long) end.tv_sec, (long) end.tv_usec );
+#endif
return 0;
}
"-e <entry> "
"[-l <loops>] "
"[-r <maxretries>] "
- "[-t <delay>]\n",
+ "[-t <delay>] "
+ "[-F]\n",
name );
exit( EXIT_FAILURE );
}
"-e <entry> "
"[-l <loops>] "
"[-r <maxretries>] "
- "[-t <delay>]\n",
+ "[-t <delay>] "
+ "[-F]\n",
name );
exit( EXIT_FAILURE );
}
LDIFFILTER=$SRCDIR/scripts/acfilter.sh
CONFFILTER=$SRCDIR/scripts/conf.sh
-SLAPADD="../servers/slapd/slapd -Ta $LDAP_VERBOSE"
-SLAPCAT="../servers/slapd/slapd -Tc $LDAP_VERBOSE"
-SLAPINDEX="../servers/slapd/slapd -Ti $LDAP_VERBOSE"
+SLAPADD="../servers/slapd/slapd -Ta -d 0 $LDAP_VERBOSE"
+SLAPCAT="../servers/slapd/slapd -Tc -d 0 $LDAP_VERBOSE"
+SLAPINDEX="../servers/slapd/slapd -Ti -d 0 $LDAP_VERBOSE"
unset DIFF_OPTIONS
# NOTE: -u/-c is not that portable...
;;
esac
+echo "Waiting 10 seconds for cached connections to timeout..."
+sleep 10
+
+echo "Searching with a timed out connection..."
+echo "# searching filter=\"$FILTER\"" >> $SEARCHOUT
+echo "# attrs=\"member\"" >> $SEARCHOUT
+echo "# base=\"$BASEDN\"" >> $SEARCHOUT
+echo "# with a timed out connection..." >> $SEARCHOUT
+$LDAPSEARCH -S "" -h $LOCALHOST -p $PORT3 -D "cn=Manager,$BASEDN" -w $PASSWD \
+ -b "$BASEDN" "$FILTER" member \
+ >> $SEARCHOUT 2>&1
+RC=$?
+#if test $RC != 0 ; then
+# echo "Search failed ($RC)!"
+# test $KILLSERVERS != no && kill -HUP $KILLPIDS
+# exit $RC
+#fi
+case $RC in
+ 0)
+ ;;
+ 51)
+ echo "### Hit LDAP_BUSY problem; you may want to re-run the test"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 0
+ ;;
+ *)
+ echo "Search failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ ;;
+esac
+
echo "Filtering ldapsearch results..."
. $LDIFFILTER < $SEARCHOUT > $SEARCHFLT
echo "Filtering original ldif used to create database..."
#if test $RC != 6 ; then
# echo "Compare failed ($RC)!"
# test $KILLSERVERS != no && kill -HUP $KILLPIDS
-# exit $RC
+# exit -1
#fi
case $RC in
6)
$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
if test $? != 0 ; then
- echo "comparison failed - meta search/modification didn't succeed"
+ echo "comparison failed - slapd-meta search/modification didn't succeed"
exit 1
fi