OpenLDAP 2.4.13 Engineering
Fixed liblutil hex conversion (ITS#5699)
Fixed slapd database open with real structure (ITS#5724)
+ Added slapd GSSAPI refactoring (ITS#5369)
Added slapd support for certificateListExactMatch from RFC4523 (ITS#5700)
Fixed slapd-bdb/hdb invalid db crash (ITS#5698)
Added slapo-constraint parameter to allow LDAP URI constraints (ITS#5704)
KRB5_LIBS = @KRB5_LIBS@
KRB_LIBS = @KRB4_LIBS@ @KRB5_LIBS@
SASL_LIBS = @SASL_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
TLS_LIBS = @TLS_LIBS@
AUTH_LIBS = @AUTH_LIBS@
-SECURITY_LIBS = $(SASL_LIBS) $(KRB_LIBS) $(TLS_LIBS) $(AUTH_LIBS)
+SECURITY_LIBS = $(SASL_LIBS) $(KRB_LIBS) $(GSSAPI_LIBS) $(TLS_LIBS) $(AUTH_LIBS)
ICU_LIBS = @ICU_LIBS@
MODULES_CPPFLAGS = @SLAPD_MODULES_CPPFLAGS@
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar OPENLDAP_LIBRELEASE OPENLDAP_LIBVERSION OPENLDAP_RELEASE_DATE top_builddir ldap_subdir CC AR CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE EGREP LN_S ECHO ac_ct_AR RANLIB ac_ct_RANLIB DLLTOOL ac_ct_DLLTOOL AS ac_ct_AS OBJDUMP ac_ct_OBJDUMP CPP LIBTOOL PERLBIN OL_MKDEP OL_MKDEP_FLAGS LTSTATIC MYSQL LIBOBJS LIBSRCS PLAT WITH_SASL WITH_TLS WITH_MODULES_ENABLED WITH_ACI_ENABLED BUILD_THREAD BUILD_LIBS_DYNAMIC BUILD_SLAPD BUILD_SLAPI SLAPD_SLAPI_DEPEND BUILD_BDB BUILD_DNSSRV BUILD_HDB BUILD_LDAP BUILD_META BUILD_MONITOR BUILD_NDB BUILD_NULL BUILD_PASSWD BUILD_RELAY BUILD_PERL BUILD_SHELL BUILD_SOCK BUILD_SQL BUILD_ACCESSLOG BUILD_AUDITLOG BUILD_COLLECT BUILD_CONSTRAINT BUILD_DDS BUILD_DENYOP BUILD_DYNGROUP BUILD_DYNLIST BUILD_LASTMOD BUILD_MEMBEROF BUILD_PPOLICY BUILD_PROXYCACHE BUILD_REFINT BUILD_RETCODE BUILD_RWM BUILD_SEQMOD BUILD_SYNCPROV BUILD_TRANSLUCENT BUILD_UNIQUE BUILD_VALSORT LDAP_LIBS SLAPD_LIBS BDB_LIBS SLAPD_NDB_LIBS SLAPD_NDB_INCS LTHREAD_LIBS LUTIL_LIBS WRAP_LIBS SLAPD_MODULES_CPPFLAGS SLAPD_MODULES_LDFLAGS SLAPD_NO_STATIC SLAPD_STATIC_BACKENDS SLAPD_DYNAMIC_BACKENDS SLAPD_STATIC_OVERLAYS SLAPD_DYNAMIC_OVERLAYS PERL_CPPFLAGS SLAPD_PERL_LDFLAGS MOD_PERL_LDFLAGS KRB4_LIBS KRB5_LIBS SASL_LIBS TLS_LIBS MODULES_LIBS SLAPI_LIBS LIBSLAPI LIBSLAPITOOLS AUTH_LIBS ICU_LIBS SLAPD_SLP_LIBS SLAPD_GMP_LIBS SLAPD_SQL_LDFLAGS SLAPD_SQL_LIBS SLAPD_SQL_INCLUDES LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar OPENLDAP_LIBRELEASE OPENLDAP_LIBVERSION OPENLDAP_RELEASE_DATE top_builddir ldap_subdir CC AR CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE EGREP LN_S ECHO ac_ct_AR RANLIB ac_ct_RANLIB DLLTOOL ac_ct_DLLTOOL AS ac_ct_AS OBJDUMP ac_ct_OBJDUMP CPP LIBTOOL PERLBIN OL_MKDEP OL_MKDEP_FLAGS LTSTATIC MYSQL LIBOBJS LIBSRCS PLAT WITH_SASL WITH_TLS WITH_MODULES_ENABLED WITH_ACI_ENABLED BUILD_THREAD BUILD_LIBS_DYNAMIC BUILD_SLAPD BUILD_SLAPI SLAPD_SLAPI_DEPEND BUILD_BDB BUILD_DNSSRV BUILD_HDB BUILD_LDAP BUILD_META BUILD_MONITOR BUILD_NDB BUILD_NULL BUILD_PASSWD BUILD_RELAY BUILD_PERL BUILD_SHELL BUILD_SOCK BUILD_SQL BUILD_ACCESSLOG BUILD_AUDITLOG BUILD_COLLECT BUILD_CONSTRAINT BUILD_DDS BUILD_DENYOP BUILD_DYNGROUP BUILD_DYNLIST BUILD_LASTMOD BUILD_MEMBEROF BUILD_PPOLICY BUILD_PROXYCACHE BUILD_REFINT BUILD_RETCODE BUILD_RWM BUILD_SEQMOD BUILD_SYNCPROV BUILD_TRANSLUCENT BUILD_UNIQUE BUILD_VALSORT LDAP_LIBS SLAPD_LIBS BDB_LIBS SLAPD_NDB_LIBS SLAPD_NDB_INCS LTHREAD_LIBS LUTIL_LIBS WRAP_LIBS SLAPD_MODULES_CPPFLAGS SLAPD_MODULES_LDFLAGS SLAPD_NO_STATIC SLAPD_STATIC_BACKENDS SLAPD_DYNAMIC_BACKENDS SLAPD_STATIC_OVERLAYS SLAPD_DYNAMIC_OVERLAYS PERL_CPPFLAGS SLAPD_PERL_LDFLAGS MOD_PERL_LDFLAGS KRB4_LIBS KRB5_LIBS SASL_LIBS GSSAPI_LIBS TLS_LIBS MODULES_LIBS SLAPI_LIBS LIBSLAPI LIBSLAPITOOLS AUTH_LIBS ICU_LIBS SLAPD_SLP_LIBS SLAPD_GMP_LIBS SLAPD_SQL_LDFLAGS SLAPD_SQL_LIBS SLAPD_SQL_INCLUDES LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
--with-subdir=DIR change default subdirectory used for installs
--with-cyrus-sasl with Cyrus SASL support [auto]
--with-fetch with fetch(3) URL support [auto]
+ --with-gssapi with GSSAPI support [auto]
--with-threads with threads [auto]
--with-tls with TLS/SSL support auto|openssl|gnutls [auto]
--with-yielding-select with implicitly yielding select [auto]
ol_with_fetch="auto"
fi; # end --with-fetch
+# OpenLDAP --with-gssapi
+
+# Check whether --with-gssapi or --without-gssapi was given.
+if test "${with_gssapi+set}" = set; then
+ withval="$with_gssapi"
+
+ ol_arg=invalid
+ for ol_val in auto yes no ; do
+ if test "$withval" = "$ol_val" ; then
+ ol_arg="$ol_val"
+ fi
+ done
+ if test "$ol_arg" = "invalid" ; then
+ { { echo "$as_me:$LINENO: error: bad value $withval for --with-gssapi" >&5
+echo "$as_me: error: bad value $withval for --with-gssapi" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ ol_with_gssapi="$ol_arg"
+
+else
+ ol_with_gssapi="auto"
+fi; # end --with-gssapi
+
# OpenLDAP --with-threads
# Check whether --with-threads or --without-threads was given.
KRB4_LIBS=
KRB5_LIBS=
SASL_LIBS=
+GSSAPI_LIBS=
TLS_LIBS=
MODULES_LIBS=
SLAPI_LIBS=
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 5679 "configure"' > conftest.$ac_ext
+ echo '#line 5704 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
-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:7659: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7684: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7663: \$? = $ac_status" >&5
+ echo "$as_me:7688: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-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:7921: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7946: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7925: \$? = $ac_status" >&5
+ echo "$as_me:7950: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-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:7983: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8008: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:7987: \$? = $ac_status" >&5
+ echo "$as_me:8012: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10231 "configure"
+#line 10256 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10329 "configure"
+#line 10354 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ol_link_ipv6=no
+if test $ac_cv_func_getaddrinfo = no || test $ac_cv_func_inet_ntop = no ; then
+ if test $ol_enable_ipv6 = yes ; then
+ { { echo "$as_me:$LINENO: error: IPv6 support requires getaddrinfo() and inet_ntop()" >&5
+echo "$as_me: error: IPv6 support requires getaddrinfo() and inet_ntop()" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+elif test $ol_enable_ipv6 != no ; then
+ echo "$as_me:$LINENO: checking INET6_ADDRSTRLEN" >&5
+echo $ECHO_N "checking INET6_ADDRSTRLEN... $ECHO_C" >&6
+if test "${ol_cv_inet6_addrstrlen+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+# include <netinet/in.h>
+# ifdef INET6_ADDRSTRLEN
+ __has_inet6_addrstrlen__;
+# endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "__has_inet6_addrstrlen__" >/dev/null 2>&1; then
+ ol_cv_inet6_addrstrlen=yes
+else
+ ol_cv_inet6_addrstrlen=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ol_cv_inet6_addrstrlen" >&5
+echo "${ECHO_T}$ol_cv_inet6_addrstrlen" >&6
+
+
+ echo "$as_me:$LINENO: checking struct sockaddr_storage" >&5
+echo $ECHO_N "checking struct sockaddr_storage... $ECHO_C" >&6
+if test "${ol_cv_struct_sockaddr_storage+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+
+ struct sockaddr_storage ss;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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_objext'
+ { (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
+ ol_cv_struct_sockaddr_storage=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ol_cv_struct_sockaddr_storage=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ol_cv_struct_sockaddr_storage" >&5
+echo "${ECHO_T}$ol_cv_struct_sockaddr_storage" >&6
+
+ if test $ol_cv_inet6_addrstrlen = yes &&
+ test $ol_cv_struct_sockaddr_storage = yes ; then
+ ol_link_ipv6=yes
+ elif test $ol_enable_ipv6 = yes &&
+ test $ol_cv_inet6_addrstrlen = no ; then
+ { { echo "$as_me:$LINENO: error: IPv6 support requires INET6_ADDRSTRLEN" >&5
+echo "$as_me: error: IPv6 support requires INET6_ADDRSTRLEN" >&2;}
+ { (exit 1); exit 1; }; }
+ elif test $ol_enable_ipv6 = yes &&
+ test $ol_cv_struct_sockaddr_storage = no ; then
+ { { echo "$as_me:$LINENO: error: IPv6 support requires struct sockaddr_storage" >&5
+echo "$as_me: error: IPv6 support requires struct sockaddr_storage" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
+if test $ol_enable_local != no ; then
+
+for ac_header in sys/un.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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_objext'
+ { (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_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## --------------------------------------------- ##
+## Report this to <http://www.openldap.org/its/> ##
+## --------------------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ if test $ol_enable_local = auto ; then
+ ol_enable_local=$ac_cv_header_sys_un_h
+ elif test $ac_cv_header_sys_un_h = no ; then
+ { { echo "$as_me:$LINENO: error: AF_LOCAL domain support requires sys/un.h" >&5
+echo "$as_me: error: AF_LOCAL domain support requires sys/un.h" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
+ol_link_gssapi=no
+
+case $ol_with_gssapi in yes | auto)
+
+ ol_header_gssapi=no
+
+for ac_header in gssapi/gssapi.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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_objext'
+ { (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_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## --------------------------------------------- ##
+## Report this to <http://www.openldap.org/its/> ##
+## --------------------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ if test $ac_cv_header_gssapi_gssapi_h = yes ; then
+ ol_header_gssapi=yes
+ else
+
+for ac_header in gssapi.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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_objext'
+ { (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_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## --------------------------------------------- ##
+## Report this to <http://www.openldap.org/its/> ##
+## --------------------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ if test $ac_cv_header_gssapi_h = yes ; then
+ ol_header_gssapi=yes
+ fi
+
+ saveLIBS="$LIBS"
+ LIBS="$LIBS $GSSAPI_LIBS"
+
+for ac_func in gss_oid_to_str
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* 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 $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ 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
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ LIBS="$saveLIBS"
+ fi
+
+ if test $ol_header_gssapi = yes ; then
+ echo "$as_me:$LINENO: checking for gss_wrap in -lgssapi" >&5
+echo $ECHO_N "checking for gss_wrap in -lgssapi... $ECHO_C" >&6
+if test "${ac_cv_lib_gssapi_gss_wrap+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi $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 gss_wrap ();
+int
+main ()
+{
+gss_wrap ();
+ ;
+ 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_gssapi_gss_wrap=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-eval "$as_ac_var=no"
+ac_cv_lib_gssapi_gss_wrap=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: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-
-ol_link_ipv6=no
-if test $ac_cv_func_getaddrinfo = no || test $ac_cv_func_inet_ntop = no ; then
- if test $ol_enable_ipv6 = yes ; then
- { { echo "$as_me:$LINENO: error: IPv6 support requires getaddrinfo() and inet_ntop()" >&5
-echo "$as_me: error: IPv6 support requires getaddrinfo() and inet_ntop()" >&2;}
- { (exit 1); exit 1; }; }
- fi
-elif test $ol_enable_ipv6 != no ; then
- echo "$as_me:$LINENO: checking INET6_ADDRSTRLEN" >&5
-echo $ECHO_N "checking INET6_ADDRSTRLEN... $ECHO_C" >&6
-if test "${ol_cv_inet6_addrstrlen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_gss_wrap" >&5
+echo "${ECHO_T}$ac_cv_lib_gssapi_gss_wrap" >&6
+if test $ac_cv_lib_gssapi_gss_wrap = yes; then
+ ol_link_gssapi=yes;GSSAPI_LIBS="-lgssapi"
else
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-# include <netinet/in.h>
-# ifdef INET6_ADDRSTRLEN
- __has_inet6_addrstrlen__;
-# endif
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "__has_inet6_addrstrlen__" >/dev/null 2>&1; then
- ol_cv_inet6_addrstrlen=yes
-else
- ol_cv_inet6_addrstrlen=no
+ ol_link_gssapi=no
fi
-rm -f conftest*
-
-fi
-echo "$as_me:$LINENO: result: $ol_cv_inet6_addrstrlen" >&5
-echo "${ECHO_T}$ol_cv_inet6_addrstrlen" >&6
-
- echo "$as_me:$LINENO: checking struct sockaddr_storage" >&5
-echo $ECHO_N "checking struct sockaddr_storage... $ECHO_C" >&6
-if test "${ol_cv_struct_sockaddr_storage+set}" = set; then
+ if test $ol_link_gssapi != yes ; then
+ echo "$as_me:$LINENO: checking for gss_wrap in -lgssapi_krb5" >&5
+echo $ECHO_N "checking for gss_wrap in -lgssapi_krb5... $ECHO_C" >&6
+if test "${ac_cv_lib_gssapi_krb5_gss_wrap+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
-
- cat >conftest.$ac_ext <<_ACEOF
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi_krb5 $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <sys/types.h>
-#include <sys/socket.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 gss_wrap ();
int
main ()
{
-
- struct sockaddr_storage ss;
-
+gss_wrap ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
+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
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
+ { 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
- ol_cv_struct_sockaddr_storage=yes
+ ac_cv_lib_gssapi_krb5_gss_wrap=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-ol_cv_struct_sockaddr_storage=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_lib_gssapi_krb5_gss_wrap=no
fi
-echo "$as_me:$LINENO: result: $ol_cv_struct_sockaddr_storage" >&5
-echo "${ECHO_T}$ol_cv_struct_sockaddr_storage" >&6
-
- if test $ol_cv_inet6_addrstrlen = yes &&
- test $ol_cv_struct_sockaddr_storage = yes ; then
- ol_link_ipv6=yes
- elif test $ol_enable_ipv6 = yes &&
- test $ol_cv_inet6_addrstrlen = no ; then
- { { echo "$as_me:$LINENO: error: IPv6 support requires INET6_ADDRSTRLEN" >&5
-echo "$as_me: error: IPv6 support requires INET6_ADDRSTRLEN" >&2;}
- { (exit 1); exit 1; }; }
- elif test $ol_enable_ipv6 = yes &&
- test $ol_cv_struct_sockaddr_storage = no ; then
- { { echo "$as_me:$LINENO: error: IPv6 support requires struct sockaddr_storage" >&5
-echo "$as_me: error: IPv6 support requires struct sockaddr_storage" >&2;}
- { (exit 1); exit 1; }; }
- fi
-fi
-
-if test $ol_enable_local != no ; then
-
-for ac_header in sys/un.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 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_objext'
- { (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_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_krb5_gss_wrap" >&5
+echo "${ECHO_T}$ac_cv_lib_gssapi_krb5_gss_wrap" >&6
+if test $ac_cv_lib_gssapi_krb5_gss_wrap = yes; then
+ ol_link_gssapi=yes;GSSAPI_LIBS="-lgssapi_krb5"
else
- ac_cpp_err=yes
+ ol_link_gssapi=no
fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
+ fi
+ fi
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## --------------------------------------------- ##
-## Report this to <http://www.openldap.org/its/> ##
-## --------------------------------------------- ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
+ ;;
esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
+WITH_GSSAPI=no
+if test $ol_link_gssapi = yes; then
- if test $ol_enable_local = auto ; then
- ol_enable_local=$ac_cv_header_sys_un_h
- elif test $ac_cv_header_sys_un_h = no ; then
- { { echo "$as_me:$LINENO: error: AF_LOCAL domain support requires sys/un.h" >&5
-echo "$as_me: error: AF_LOCAL domain support requires sys/un.h" >&2;}
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSSAPI 1
+_ACEOF
+
+ WITH_GSSAPI=yes
+elif test $ol_with_gssapi = auto ; then
+ { echo "$as_me:$LINENO: WARNING: Could not locate GSSAPI package" >&5
+echo "$as_me: WARNING: Could not locate GSSAPI package" >&2;}
+ { echo "$as_me:$LINENO: WARNING: GSSAPI authentication not supported!" >&5
+echo "$as_me: WARNING: GSSAPI authentication not supported!" >&2;}
+elif test $ol_with_gssapi = yes ; then
+ { { echo "$as_me:$LINENO: error: GSSAPI detection failed" >&5
+echo "$as_me: error: GSSAPI detection failed" >&2;}
{ (exit 1); exit 1; }; }
- fi
fi
+
# Check whether --with-xxinstall or --without-xxinstall was given.
s,@KRB4_LIBS@,$KRB4_LIBS,;t t
s,@KRB5_LIBS@,$KRB5_LIBS,;t t
s,@SASL_LIBS@,$SASL_LIBS,;t t
+s,@GSSAPI_LIBS@,$GSSAPI_LIBS,;t t
s,@TLS_LIBS@,$TLS_LIBS,;t t
s,@MODULES_LIBS@,$MODULES_LIBS,;t t
s,@SLAPI_LIBS@,$SLAPI_LIBS,;t t
auto, [auto yes no] )
OL_ARG_WITH(fetch,[ --with-fetch with fetch(3) URL support],
auto, [auto yes no] )
+OL_ARG_WITH(gssapi,[ --with-gssapi with GSSAPI support],
+ auto, [auto yes no] )
OL_ARG_WITH(threads,[ --with-threads with threads],
auto, [auto nt posix mach pth lwp yes no manual] )
OL_ARG_WITH(tls,[ --with-tls with TLS/SSL support auto|openssl|gnutls],
KRB4_LIBS=
KRB5_LIBS=
SASL_LIBS=
+GSSAPI_LIBS=
TLS_LIBS=
MODULES_LIBS=
SLAPI_LIBS=
fi
fi
+dnl ----------------------------------------------------------------
+dnl GSSAPI
+ol_link_gssapi=no
+
+case $ol_with_gssapi in yes | auto)
+
+ ol_header_gssapi=no
+ AC_CHECK_HEADERS(gssapi/gssapi.h)
+ if test $ac_cv_header_gssapi_gssapi_h = yes ; then
+ ol_header_gssapi=yes
+ else
+ AC_CHECK_HEADERS(gssapi.h)
+ if test $ac_cv_header_gssapi_h = yes ; then
+ ol_header_gssapi=yes
+ fi
+
+ dnl## not every gssapi has gss_oid_to_str()
+ dnl## as it's not defined in the GSSAPI V2 API
+ dnl## anymore
+ saveLIBS="$LIBS"
+ LIBS="$LIBS $GSSAPI_LIBS"
+ AC_CHECK_FUNCS(gss_oid_to_str)
+ LIBS="$saveLIBS"
+ fi
+
+ if test $ol_header_gssapi = yes ; then
+ dnl## we check for gss_wrap
+ dnl## as it's new to the GSSAPI V2 API
+ AC_CHECK_LIB(gssapi, gss_wrap,
+ [ol_link_gssapi=yes;GSSAPI_LIBS="-lgssapi"],
+ [ol_link_gssapi=no])
+ if test $ol_link_gssapi != yes ; then
+ AC_CHECK_LIB(gssapi_krb5, gss_wrap,
+ [ol_link_gssapi=yes;GSSAPI_LIBS="-lgssapi_krb5"],
+ [ol_link_gssapi=no])
+ fi
+ fi
+
+ ;;
+esac
+
+WITH_GSSAPI=no
+if test $ol_link_gssapi = yes; then
+ AC_DEFINE(HAVE_GSSAPI, 1, [define if you have GSSAPI])
+ WITH_GSSAPI=yes
+elif test $ol_with_gssapi = auto ; then
+ AC_MSG_WARN([Could not locate GSSAPI package])
+ AC_MSG_WARN([GSSAPI authentication not supported!])
+elif test $ol_with_gssapi = yes ; then
+ AC_MSG_ERROR([GSSAPI detection failed])
+fi
+
dnl ----------------------------------------------------------------
dnl TLS/SSL
AC_SUBST(KRB4_LIBS)
AC_SUBST(KRB5_LIBS)
AC_SUBST(SASL_LIBS)
+AC_SUBST(GSSAPI_LIBS)
AC_SUBST(TLS_LIBS)
AC_SUBST(MODULES_LIBS)
AC_SUBST(SLAPI_LIBS)
specifies the maximum security layer receive buffer
size allowed. 0 disables security layers. The default is 65536.
.RE
+.SH GSSAPI OPTIONS
+If OpenLDAP is built with Generic Security Services Application Programming Interface support,
+there are more options you can specify.
+.TP
+.B GSSAPI_SIGN <on/true/yes/off/false/no>
+Specifies if GSSAPI signing (GSS_C_INTEG_FLAG) should be used.
+The default is off.
+.TP
+.B GSSAPI_ENCRYPT <on/true/yes/off/false/no>
+Specifies if GSSAPI encryption (GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG)
+should be used. The default is off.
+.TP
+.B GSSAPI_ALLOW_REMOTE_PRINCIPAL <on/true/yes/off/false/no>
+Specifies if GSSAPI based authentification should try to form the
+target principal name out of the ldapServiceName or dnsHostName
+attribute of the targets RootDSE entry. The default is off.
.SH TLS OPTIONS
If OpenLDAP is built with Transport Layer Security support, there
are more options you can specify. These options are used when an
#define LDAP_OPT_ERROR_STRING LDAP_OPT_DIAGNOSTIC_MESSAGE
#define LDAP_OPT_MATCHED_DN 0x0033
/* 0x0034 - 0x3fff not defined */
+/* 0x0091 used by Microsoft for LDAP_OPT_AUTO_RECONNECT */
+#define LDAP_OPT_SSPI_FLAGS 0x0092
+/* 0x0093 used by Microsoft for LDAP_OPT_SSL_INFO */
+/* 0x0094 used by Microsoft for LDAP_OPT_REF_DEREF_CONN_PER_MSG */
+#define LDAP_OPT_SIGN 0x0095
+#define LDAP_OPT_ENCRYPT 0x0096
+#define LDAP_OPT_SASL_METHOD 0x0097
+/* 0x0098 used by Microsoft for LDAP_OPT_AREC_EXCLUSIVE */
+#define LDAP_OPT_SECURITY_CONTEXT 0x0099
+/* 0x009A used by Microsoft for LDAP_OPT_ROOTDSE_CACHE */
+/* 0x009B - 0x3fff not defined */
/* API Extensions */
#define LDAP_OPT_API_EXTENSION_BASE 0x4000 /* API extensions */
#define LDAP_OPT_X_SASL_SECPROPS 0x6106 /* write-only */
#define LDAP_OPT_X_SASL_SSF_MIN 0x6107
#define LDAP_OPT_X_SASL_SSF_MAX 0x6108
-#define LDAP_OPT_X_SASL_MAXBUFSIZE 0x6109
+#define LDAP_OPT_X_SASL_MAXBUFSIZE 0x6109
+#define LDAP_OPT_X_SASL_MECHLIST 0x610a /* read-only */
+
+/* OpenLDAP GSSAPI options */
+#define LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT 0x6200
+#define LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL 0x6201
+
/* Private API Extensions -- reserved for application use */
#define LDAP_OPT_PRIVATE_EXTENSION_BASE 0x7000 /* Private API inclusive */
#define LDAP_AUTH_KRBV41 ((ber_tag_t) 0x81U) /* context specific + primitive */
#define LDAP_AUTH_KRBV42 ((ber_tag_t) 0x82U) /* context specific + primitive */
+/* used by the Windows API but not used on the wire */
+#define LDAP_AUTH_NEGOTIATE ((ber_tag_t) 0x04FFU)
/* filter types */
#define LDAP_FILTER_AND ((ber_tag_t) 0xa0U) /* context specific + constructed */
#define _LDAP_PVT_H 1
#include <lber.h> /* get ber_slen_t */
+#include <lber_pvt.h> /* get Sockbuf_Buf */
LDAP_BEGIN_DECL
LDAP_F (int) ldap_pvt_sasl_mutex_lock LDAP_P((void *mutex));
LDAP_F (int) ldap_pvt_sasl_mutex_unlock LDAP_P((void *mutex));
LDAP_F (void) ldap_pvt_sasl_mutex_dispose LDAP_P((void *mutex));
+#endif /* HAVE_CYRUS_SASL */
struct sockbuf; /* avoid pulling in <lber.h> */
LDAP_F (int) ldap_pvt_sasl_install LDAP_P(( struct sockbuf *, void * ));
LDAP_F (void) ldap_pvt_sasl_remove LDAP_P(( struct sockbuf * ));
-#endif /* HAVE_CYRUS_SASL */
+/*
+ * SASL encryption support for LBER Sockbufs
+ */
+
+struct sb_sasl_generic_data;
+
+struct sb_sasl_generic_ops {
+ void (*init)(struct sb_sasl_generic_data *p,
+ ber_len_t *min_send,
+ ber_len_t *max_send,
+ ber_len_t *max_recv);
+ ber_int_t (*encode)(struct sb_sasl_generic_data *p,
+ unsigned char *buf,
+ ber_len_t len,
+ Sockbuf_Buf *dst);
+ ber_int_t (*decode)(struct sb_sasl_generic_data *p,
+ const Sockbuf_Buf *src,
+ Sockbuf_Buf *dst);
+ void (*reset_buf)(struct sb_sasl_generic_data *p,
+ Sockbuf_Buf *buf);
+ void (*fini)(struct sb_sasl_generic_data *p);
+};
+
+struct sb_sasl_generic_install {
+ const struct sb_sasl_generic_ops *ops;
+ void *ops_private;
+};
+
+struct sb_sasl_generic_data {
+ const struct sb_sasl_generic_ops *ops;
+ void *ops_private;
+ Sockbuf_IO_Desc *sbiod;
+ ber_len_t min_send;
+ ber_len_t max_send;
+ ber_len_t max_recv;
+ Sockbuf_Buf sec_buf_in;
+ Sockbuf_Buf buf_in;
+ Sockbuf_Buf buf_out;
+};
+
#ifndef LDAP_PVT_SASL_LOCAL_SSF
#define LDAP_PVT_SASL_LOCAL_SSF 71 /* SSF for Unix Domain Sockets */
#endif /* ! LDAP_PVT_SASL_LOCAL_SSF */
/* Define to 1 if you have the <grp.h> header file. */
#undef HAVE_GRP_H
+/* define if you have GSSAPI */
+#undef HAVE_GSSAPI
+
+/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
+#undef HAVE_GSSAPI_GSSAPI_H
+
+/* Define to 1 if you have the <gssapi.h> header file. */
+#undef HAVE_GSSAPI_H
+
+/* Define to 1 if you have the `gss_oid_to_str' function. */
+#undef HAVE_GSS_OID_TO_STR
+
/* Define to 1 if you have the `hstrerror' function. */
#undef HAVE_HSTRERROR
SRCS = bind.c open.c result.c error.c compare.c search.c \
controls.c messages.c references.c extended.c cyrus.c \
modify.c add.c modrdn.c delete.c abandon.c \
- sasl.c sbind.c unbind.c cancel.c \
+ sasl.c gssapi.c sbind.c unbind.c cancel.c \
filter.c free.c sort.c passwd.c whoami.c \
getdn.c getentry.c getattr.c getvalues.c addentry.c \
request.c os-ip.c url.c pagectrl.c sortctrl.c vlvctrl.c \
OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
controls.lo messages.lo references.lo extended.lo cyrus.lo \
modify.lo add.lo modrdn.lo delete.lo abandon.lo \
- sasl.lo sbind.lo unbind.lo cancel.lo \
+ sasl.lo gssapi.lo sbind.lo unbind.lo cancel.lo \
filter.lo free.lo sort.lo passwd.lo whoami.lo \
getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
request.lo os-ip.lo url.lo pagectrl.lo sortctrl.lo vlvctrl.lo \
case LDAP_AUTH_SIMPLE:
return( ldap_simple_bind( ld, dn, passwd ) );
+#ifdef HAVE_GSSAPI
+ case LDAP_AUTH_NEGOTIATE:
+ return( ldap_gssapi_bind_s( ld, dn, passwd) );
+#endif
+
case LDAP_AUTH_SASL:
/* user must use ldap_sasl_bind */
/* FALL-THRU */
case LDAP_AUTH_SIMPLE:
return( ldap_simple_bind_s( ld, dn, passwd ) );
+#ifdef HAVE_GSSAPI
+ case LDAP_AUTH_NEGOTIATE:
+ return( ldap_gssapi_bind_s( ld, dn, passwd) );
+#endif
+
case LDAP_AUTH_SASL:
/* user must use ldap_sasl_bind */
/* FALL-THRU */
return -1;
}
-/*
- * SASL encryption support for LBER Sockbufs
- */
-
-struct sb_sasl_data {
- sasl_conn_t *sasl_context;
- unsigned *sasl_maxbuf;
- Sockbuf_Buf sec_buf_in;
- Sockbuf_Buf buf_in;
- Sockbuf_Buf buf_out;
-};
-
-static int
-sb_sasl_setup( Sockbuf_IO_Desc *sbiod, void *arg )
+static void
+sb_sasl_cyrus_init(
+ struct sb_sasl_generic_data *p,
+ ber_len_t *min_send,
+ ber_len_t *max_send,
+ ber_len_t *max_recv)
{
- struct sb_sasl_data *p;
-
- assert( sbiod != NULL );
-
- p = LBER_MALLOC( sizeof( *p ) );
- if ( p == NULL )
- return -1;
- p->sasl_context = (sasl_conn_t *)arg;
- ber_pvt_sb_buf_init( &p->sec_buf_in );
- ber_pvt_sb_buf_init( &p->buf_in );
- ber_pvt_sb_buf_init( &p->buf_out );
- if ( ber_pvt_sb_grow_buffer( &p->sec_buf_in, SASL_MIN_BUFF_SIZE ) < 0 ) {
- LBER_FREE( p );
- sock_errset(ENOMEM);
- return -1;
- }
- sasl_getprop( p->sasl_context, SASL_MAXOUTBUF,
- (SASL_CONST void **)(char *) &p->sasl_maxbuf );
-
- sbiod->sbiod_pvt = p;
-
- return 0;
-}
+ sasl_conn_t *sasl_context = (sasl_conn_t *)p->ops_private;
+ ber_len_t maxbuf;
-static int
-sb_sasl_remove( Sockbuf_IO_Desc *sbiod )
-{
- struct sb_sasl_data *p;
+ sasl_getprop( sasl_context, SASL_MAXOUTBUF,
+ (SASL_CONST void **)(char *) &maxbuf );
- assert( sbiod != NULL );
-
- p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
-#if SASL_VERSION_MAJOR >= 2
- /*
- * SASLv2 encode/decode buffers are managed by
- * libsasl2. Ensure they are not freed by liblber.
- */
- p->buf_in.buf_base = NULL;
- p->buf_out.buf_base = NULL;
-#endif
- ber_pvt_sb_buf_destroy( &p->sec_buf_in );
- ber_pvt_sb_buf_destroy( &p->buf_in );
- ber_pvt_sb_buf_destroy( &p->buf_out );
- LBER_FREE( p );
- sbiod->sbiod_pvt = NULL;
- return 0;
+ *min_send = SASL_MIN_BUFF_SIZE;
+ *max_send = maxbuf;
+ *max_recv = SASL_MAX_BUFF_SIZE;
}
-static ber_len_t
-sb_sasl_pkt_length( const unsigned char *buf, int debuglevel )
+static ber_int_t
+sb_sasl_cyrus_encode(
+ struct sb_sasl_generic_data *p,
+ unsigned char *buf,
+ ber_len_t len,
+ Sockbuf_Buf *dst)
{
- ber_len_t size;
+ sasl_conn_t *sasl_context = (sasl_conn_t *)p->ops_private;
+ ber_int_t ret;
+ unsigned tmpsize = dst->buf_size;
- assert( buf != NULL );
+ ret = sasl_encode( sasl_context, buf, len,
+ (SASL_CONST char **)&dst->buf_base,
+ &tmpsize );
- size = buf[0] << 24
- | buf[1] << 16
- | buf[2] << 8
- | buf[3];
+ dst->buf_size = tmpsize;
+ dst->buf_end = dst->buf_size;
- if ( size > SASL_MAX_BUFF_SIZE ) {
- /* somebody is trying to mess me up. */
- ber_log_printf( LDAP_DEBUG_ANY, debuglevel,
- "sb_sasl_pkt_length: received illegal packet length "
- "of %lu bytes\n", (unsigned long)size );
- size = 16; /* this should lead to an error. */
+ if ( ret != SASL_OK ) {
+ ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_cyrus_encode: failed to encode packet: %s\n",
+ sasl_errstring( ret, NULL, NULL ) );
+ return -1;
}
- return size + 4; /* include the size !!! */
-}
-
-/* Drop a processed packet from the input buffer */
-static void
-sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, int debuglevel )
-{
- ber_slen_t len;
-
- len = sec_buf_in->buf_ptr - sec_buf_in->buf_end;
- if ( len > 0 )
- AC_MEMCPY( sec_buf_in->buf_base, sec_buf_in->buf_base +
- sec_buf_in->buf_end, len );
-
- if ( len >= 4 ) {
- sec_buf_in->buf_end = sb_sasl_pkt_length(
- (unsigned char *) sec_buf_in->buf_base, debuglevel);
- }
- else {
- sec_buf_in->buf_end = 0;
- }
- sec_buf_in->buf_ptr = len;
+ return 0;
}
-static ber_slen_t
-sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+static ber_int_t
+sb_sasl_cyrus_decode(
+ struct sb_sasl_generic_data *p,
+ const Sockbuf_Buf *src,
+ Sockbuf_Buf *dst)
{
- struct sb_sasl_data *p;
- ber_slen_t ret, bufptr;
-
- assert( sbiod != NULL );
- assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
-
- p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
+ sasl_conn_t *sasl_context = (sasl_conn_t *)p->ops_private;
+ ber_int_t ret;
+ unsigned tmpsize = dst->buf_size;
- /* Are there anything left in the buffer? */
- ret = ber_pvt_sb_copy_out( &p->buf_in, buf, len );
- bufptr = ret;
- len -= ret;
+ ret = sasl_decode( sasl_context,
+ src->buf_base, src->buf_end,
+ (SASL_CONST char **)&dst->buf_base,
+ (unsigned *)&tmpsize );
- if ( len == 0 )
- return bufptr;
-#if SASL_VERSION_MAJOR >= 2
- ber_pvt_sb_buf_init( &p->buf_in );
-#else
- ber_pvt_sb_buf_destroy( &p->buf_in );
-#endif
-
- /* Read the length of the packet */
- while ( p->sec_buf_in.buf_ptr < 4 ) {
- ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base +
- p->sec_buf_in.buf_ptr,
- 4 - p->sec_buf_in.buf_ptr );
-#ifdef EINTR
- if ( ( ret < 0 ) && ( errno == EINTR ) )
- continue;
-#endif
- if ( ret <= 0 )
- return bufptr ? bufptr : ret;
-
- p->sec_buf_in.buf_ptr += ret;
- }
-
- /* The new packet always starts at p->sec_buf_in.buf_base */
- ret = sb_sasl_pkt_length( (unsigned char *) p->sec_buf_in.buf_base,
- sbiod->sbiod_sb->sb_debug );
-
- /* Grow the packet buffer if neccessary */
- if ( ( p->sec_buf_in.buf_size < (ber_len_t) ret ) &&
- ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 )
- {
- sock_errset(ENOMEM);
- return -1;
- }
- p->sec_buf_in.buf_end = ret;
-
- /* Did we read the whole encrypted packet? */
- while ( p->sec_buf_in.buf_ptr < p->sec_buf_in.buf_end ) {
- /* No, we have got only a part of it */
- ret = p->sec_buf_in.buf_end - p->sec_buf_in.buf_ptr;
-
- ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base +
- p->sec_buf_in.buf_ptr, ret );
-#ifdef EINTR
- if ( ( ret < 0 ) && ( errno == EINTR ) )
- continue;
-#endif
- if ( ret <= 0 )
- return bufptr ? bufptr : ret;
-
- p->sec_buf_in.buf_ptr += ret;
- }
-
- /* Decode the packet */
- {
- unsigned tmpsize = p->buf_in.buf_end;
- ret = sasl_decode( p->sasl_context, p->sec_buf_in.buf_base,
- p->sec_buf_in.buf_end,
- (SASL_CONST char **)&p->buf_in.buf_base,
- (unsigned *)&tmpsize );
- p->buf_in.buf_end = tmpsize;
- }
-
- /* Drop the packet from the input buffer */
- sb_sasl_drop_packet( &p->sec_buf_in, sbiod->sbiod_sb->sb_debug );
+ dst->buf_size = tmpsize;
+ dst->buf_end = dst->buf_size;
if ( ret != SASL_OK ) {
- ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
- "sb_sasl_read: failed to decode packet: %s\n",
- sasl_errstring( ret, NULL, NULL ) );
- sock_errset(EIO);
+ ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_cyrus_decode: failed to decode packet: %s\n",
+ sasl_errstring( ret, NULL, NULL ) );
return -1;
}
-
- p->buf_in.buf_size = p->buf_in.buf_end;
-
- bufptr += ber_pvt_sb_copy_out( &p->buf_in, (char*) buf + bufptr, len );
- return bufptr;
+ return 0;
}
-static ber_slen_t
-sb_sasl_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+static void
+sb_sasl_cyrus_reset_buf(
+ struct sb_sasl_generic_data *p,
+ Sockbuf_Buf *buf)
{
- struct sb_sasl_data *p;
- int ret;
-
- assert( sbiod != NULL );
- assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
-
- p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
-
- /* Are there anything left in the buffer? */
- if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
- ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
- if ( ret < 0 ) return ret;
-
- /* Still have something left?? */
- if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
- sock_errset(EAGAIN);
- return -1;
- }
- }
-
- /* now encode the next packet. */
#if SASL_VERSION_MAJOR >= 2
- ber_pvt_sb_buf_init( &p->buf_out );
+ ber_pvt_sb_buf_init( buf );
#else
- ber_pvt_sb_buf_destroy( &p->buf_out );
+ ber_pvt_sb_buf_destroy( buf );
#endif
- if ( len > *p->sasl_maxbuf - 100 ) {
- len = *p->sasl_maxbuf - 100; /* For safety margin */
- }
-
- {
- unsigned tmpsize = p->buf_out.buf_size;
- ret = sasl_encode( p->sasl_context, buf, len,
- (SASL_CONST char **)&p->buf_out.buf_base,
- &tmpsize );
- p->buf_out.buf_size = tmpsize;
- }
-
- if ( ret != SASL_OK ) {
- ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
- "sb_sasl_write: failed to encode packet: %s\n",
- sasl_errstring( ret, NULL, NULL ) );
- sock_errset(EIO);
- return -1;
- }
- p->buf_out.buf_end = p->buf_out.buf_size;
-
- ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
-
- /* return number of bytes encoded, not written, to ensure
- * no byte is encoded twice (even if only sent once).
- */
- return len;
}
-static int
-sb_sasl_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
+static void
+sb_sasl_cyrus_fini(
+ struct sb_sasl_generic_data *p)
{
- struct sb_sasl_data *p;
-
- p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
-
- if ( opt == LBER_SB_OPT_DATA_READY ) {
- if ( p->buf_in.buf_ptr != p->buf_in.buf_end ) return 1;
- }
-
- return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
+#if SASL_VERSION_MAJOR >= 2
+ /*
+ * SASLv2 encode/decode buffers are managed by
+ * libsasl2. Ensure they are not freed by liblber.
+ */
+ p->buf_in.buf_base = NULL;
+ p->buf_out.buf_base = NULL;
+#endif
}
-Sockbuf_IO ldap_pvt_sockbuf_io_sasl = {
- sb_sasl_setup, /* sbi_setup */
- sb_sasl_remove, /* sbi_remove */
- sb_sasl_ctrl, /* sbi_ctrl */
- sb_sasl_read, /* sbi_read */
- sb_sasl_write, /* sbi_write */
- NULL /* sbi_close */
-};
+static const struct sb_sasl_generic_ops sb_sasl_cyrus_ops = {
+ sb_sasl_cyrus_init,
+ sb_sasl_cyrus_encode,
+ sb_sasl_cyrus_decode,
+ sb_sasl_cyrus_reset_buf,
+ sb_sasl_cyrus_fini
+ };
int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg )
{
- Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_install\n",
- 0, 0, 0 );
-
- /* don't install the stuff unless security has been negotiated */
+ struct sb_sasl_generic_install install_arg;
- if ( !ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO,
- &ldap_pvt_sockbuf_io_sasl ) )
- {
-#ifdef LDAP_DEBUG
- ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
- LBER_SBIOD_LEVEL_APPLICATION, (void *)"sasl_" );
-#endif
- ber_sockbuf_add_io( sb, &ldap_pvt_sockbuf_io_sasl,
- LBER_SBIOD_LEVEL_APPLICATION, ctx_arg );
- }
+ install_arg.ops = &sb_sasl_cyrus_ops;
+ install_arg.ops_private = ctx_arg;
- return LDAP_SUCCESS;
+ return ldap_pvt_sasl_generic_install( sb, &install_arg );
}
void ldap_pvt_sasl_remove( Sockbuf *sb )
{
- ber_sockbuf_remove_io( sb, &ldap_pvt_sockbuf_io_sasl,
- LBER_SBIOD_LEVEL_APPLICATION );
-#ifdef LDAP_DEBUG
- ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
- LBER_SBIOD_LEVEL_APPLICATION );
-#endif
+ ldap_pvt_sasl_generic_remove( sb );
}
static int
int
ldap_int_sasl_get_option( LDAP *ld, int option, void *arg )
{
+ if ( option == LDAP_OPT_X_SASL_MECHLIST ) {
+ if ( ldap_int_sasl_init() )
+ return -1;
+ *(char ***)arg = (char **)sasl_global_listmech();
+ return 0;
+ }
+
if ( ld == NULL )
return -1;
--- /dev/null
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2007 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Author: Stefan Metzmacher <metze@sernet.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/stdlib.h>
+#include <ac/string.h>
+#include <ac/time.h>
+#include <ac/errno.h>
+#include <ac/ctype.h>
+#include <ac/unistd.h>
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "ldap-int.h"
+
+#ifdef HAVE_GSSAPI
+
+#ifdef HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#else
+#include <gssapi.h>
+#endif
+
+static char *
+gsserrstr(
+ char *buf,
+ ber_len_t buf_len,
+ gss_OID mech,
+ int gss_rc,
+ OM_uint32 minor_status )
+{
+ OM_uint32 min2;
+ gss_buffer_desc mech_msg = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc gss_msg = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc minor_msg = GSS_C_EMPTY_BUFFER;
+ OM_uint32 msg_ctx = 0;
+
+ if (buf == NULL) {
+ return NULL;
+ }
+
+ if (buf_len == 0) {
+ return NULL;
+ }
+
+#ifdef HAVE_GSS_OID_TO_STR
+ gss_oid_to_str(&min2, mech, &mech_msg);
+#endif
+ gss_display_status(&min2, gss_rc, GSS_C_GSS_CODE,
+ mech, &msg_ctx, &gss_msg);
+ gss_display_status(&min2, minor_status, GSS_C_MECH_CODE,
+ mech, &msg_ctx, &minor_msg);
+
+ snprintf(buf, buf_len, "gss_rc[%d:%*s] mech[%*s] minor[%u:%*s]",
+ gss_rc, (int)gss_msg.length,
+ (const char *)(gss_msg.value?gss_msg.value:""),
+ (int)mech_msg.length,
+ (const char *)(mech_msg.value?mech_msg.value:""),
+ minor_status, (int)minor_msg.length,
+ (const char *)(minor_msg.value?minor_msg.value:""));
+
+ gss_release_buffer(&min2, &mech_msg);
+ gss_release_buffer(&min2, &gss_msg);
+ gss_release_buffer(&min2, &minor_msg);
+
+ buf[buf_len-1] = '\0';
+
+ return buf;
+}
+
+static void
+sb_sasl_gssapi_init(
+ struct sb_sasl_generic_data *p,
+ ber_len_t *min_send,
+ ber_len_t *max_send,
+ ber_len_t *max_recv )
+{
+ gss_ctx_id_t gss_ctx = (gss_ctx_id_t)p->ops_private;
+ int gss_rc;
+ OM_uint32 minor_status;
+ gss_OID ctx_mech = GSS_C_NO_OID;
+ OM_uint32 ctx_flags = 0;
+ int conf_req_flag = 0;
+ OM_uint32 max_input_size;
+
+ gss_inquire_context(&minor_status,
+ gss_ctx,
+ NULL,
+ NULL,
+ NULL,
+ &ctx_mech,
+ &ctx_flags,
+ NULL,
+ NULL);
+
+ if (ctx_flags & (GSS_C_CONF_FLAG)) {
+ conf_req_flag = 1;
+ }
+
+#if defined(HAVE_CYRUS_SASL)
+#define SEND_PREALLOC_SIZE SASL_MIN_BUFF_SIZE
+#else
+#define SEND_PREALLOC_SIZE 4096
+#endif
+#define SEND_MAX_WIRE_SIZE 0x00A00000
+#define RECV_MAX_WIRE_SIZE 0x0FFFFFFF
+#define FALLBACK_SEND_MAX_SIZE 0x009FFFB8 /* from MIT 1.5.x */
+
+ gss_rc = gss_wrap_size_limit(&minor_status, gss_ctx,
+ conf_req_flag, GSS_C_QOP_DEFAULT,
+ SEND_MAX_WIRE_SIZE, &max_input_size);
+ if ( gss_rc != GSS_S_COMPLETE ) {
+ char msg[256];
+ ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_gssapi_init: failed to wrap size limit: %s\n",
+ gsserrstr( msg, sizeof(msg), ctx_mech, gss_rc, minor_status ) );
+ ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_gssapi_init: fallback to default wrap size limit\n");
+ /*
+ * some libgssglue/libgssapi versions
+ * have a broken gss_wrap_size_limit()
+ * implementation
+ */
+ max_input_size = FALLBACK_SEND_MAX_SIZE;
+ }
+
+ *min_send = SEND_PREALLOC_SIZE;
+ *max_send = max_input_size;
+ *max_recv = RECV_MAX_WIRE_SIZE;
+}
+
+static ber_int_t
+sb_sasl_gssapi_encode(
+ struct sb_sasl_generic_data *p,
+ unsigned char *buf,
+ ber_len_t len,
+ Sockbuf_Buf *dst )
+{
+ gss_ctx_id_t gss_ctx = (gss_ctx_id_t)p->ops_private;
+ int gss_rc;
+ OM_uint32 minor_status;
+ gss_buffer_desc unwrapped, wrapped;
+ gss_OID ctx_mech = GSS_C_NO_OID;
+ OM_uint32 ctx_flags = 0;
+ int conf_req_flag = 0;
+ int conf_state;
+ unsigned char *b;
+ ber_len_t pkt_len;
+
+ unwrapped.value = buf;
+ unwrapped.length = len;
+
+ gss_inquire_context(&minor_status,
+ gss_ctx,
+ NULL,
+ NULL,
+ NULL,
+ &ctx_mech,
+ &ctx_flags,
+ NULL,
+ NULL);
+
+ if (ctx_flags & (GSS_C_CONF_FLAG)) {
+ conf_req_flag = 1;
+ }
+
+ gss_rc = gss_wrap(&minor_status, gss_ctx,
+ conf_req_flag, GSS_C_QOP_DEFAULT,
+ &unwrapped, &conf_state,
+ &wrapped);
+ if ( gss_rc != GSS_S_COMPLETE ) {
+ char msg[256];
+ ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_gssapi_encode: failed to encode packet: %s\n",
+ gsserrstr( msg, sizeof(msg), ctx_mech, gss_rc, minor_status ) );
+ return -1;
+ }
+
+ if ( conf_req_flag && conf_state == 0 ) {
+ ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_gssapi_encode: GSS_C_CONF_FLAG was ignored by our gss_wrap()\n" );
+ return -1;
+ }
+
+ pkt_len = 4 + wrapped.length;
+
+ /* Grow the packet buffer if neccessary */
+ if ( dst->buf_size < pkt_len &&
+ ber_pvt_sb_grow_buffer( dst, pkt_len ) < 0 )
+ {
+ ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_gssapi_encode: failed to grow the buffer to %lu bytes\n",
+ pkt_len );
+ return -1;
+ }
+
+ dst->buf_end = pkt_len;
+
+ b = (unsigned char *)dst->buf_base;
+
+ b[0] = (unsigned char)(wrapped.length >> 24);
+ b[1] = (unsigned char)(wrapped.length >> 16);
+ b[2] = (unsigned char)(wrapped.length >> 8);
+ b[3] = (unsigned char)(wrapped.length >> 0);
+
+ /* copy the wrapped blob to the right location */
+ memcpy(b + 4, wrapped.value, wrapped.length);
+
+ gss_release_buffer(&minor_status, &wrapped);
+
+ return 0;
+}
+
+static ber_int_t
+sb_sasl_gssapi_decode(
+ struct sb_sasl_generic_data *p,
+ const Sockbuf_Buf *src,
+ Sockbuf_Buf *dst )
+{
+ gss_ctx_id_t gss_ctx = (gss_ctx_id_t)p->ops_private;
+ int gss_rc;
+ OM_uint32 minor_status;
+ gss_buffer_desc unwrapped, wrapped;
+ gss_OID ctx_mech = GSS_C_NO_OID;
+ OM_uint32 ctx_flags = 0;
+ int conf_req_flag = 0;
+ int conf_state;
+ unsigned char *b;
+ ber_len_t pkt_len;
+
+ wrapped.value = src->buf_base + 4;
+ wrapped.length = src->buf_end - 4;
+
+ gss_inquire_context(&minor_status,
+ gss_ctx,
+ NULL,
+ NULL,
+ NULL,
+ &ctx_mech,
+ &ctx_flags,
+ NULL,
+ NULL);
+
+ if (ctx_flags & (GSS_C_CONF_FLAG)) {
+ conf_req_flag = 1;
+ }
+
+ gss_rc = gss_unwrap(&minor_status, gss_ctx,
+ &wrapped, &unwrapped,
+ &conf_state, GSS_C_QOP_DEFAULT);
+ if ( gss_rc != GSS_S_COMPLETE ) {
+ char msg[256];
+ ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_gssapi_decode: failed to decode packet: %s\n",
+ gsserrstr( msg, sizeof(msg), ctx_mech, gss_rc, minor_status ) );
+ return -1;
+ }
+
+ if ( conf_req_flag && conf_state == 0 ) {
+ ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_gssapi_encode: GSS_C_CONF_FLAG was ignored by our peer\n" );
+ return -1;
+ }
+
+ /* Grow the packet buffer if neccessary */
+ if ( dst->buf_size < unwrapped.length &&
+ ber_pvt_sb_grow_buffer( dst, unwrapped.length ) < 0 )
+ {
+ ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_gssapi_decode: failed to grow the buffer to %lu bytes\n",
+ pkt_len );
+ return -1;
+ }
+
+ dst->buf_end = unwrapped.length;
+
+ b = (unsigned char *)dst->buf_base;
+
+ /* copy the wrapped blob to the right location */
+ memcpy(b, unwrapped.value, unwrapped.length);
+
+ gss_release_buffer(&minor_status, &unwrapped);
+
+ return 0;
+}
+
+static void
+sb_sasl_gssapi_reset_buf(
+ struct sb_sasl_generic_data *p,
+ Sockbuf_Buf *buf )
+{
+ ber_pvt_sb_buf_destroy( buf );
+}
+
+static void
+sb_sasl_gssapi_fini( struct sb_sasl_generic_data *p )
+{
+}
+
+static const struct sb_sasl_generic_ops sb_sasl_gssapi_ops = {
+ sb_sasl_gssapi_init,
+ sb_sasl_gssapi_encode,
+ sb_sasl_gssapi_decode,
+ sb_sasl_gssapi_reset_buf,
+ sb_sasl_gssapi_fini
+};
+
+static int
+sb_sasl_gssapi_install(
+ Sockbuf *sb,
+ gss_ctx_id_t gss_ctx )
+{
+ struct sb_sasl_generic_install install_arg;
+
+ install_arg.ops = &sb_sasl_gssapi_ops;
+ install_arg.ops_private = gss_ctx;
+
+ return ldap_pvt_sasl_generic_install( sb, &install_arg );
+}
+
+static void
+sb_sasl_gssapi_remove( Sockbuf *sb )
+{
+ ldap_pvt_sasl_generic_remove( sb );
+}
+
+static int
+map_gsserr2ldap(
+ LDAP *ld,
+ gss_OID mech,
+ int gss_rc,
+ OM_uint32 minor_status )
+{
+ OM_uint32 min2;
+ OM_uint32 msg_ctx = 0;
+ char msg[256];
+
+ Debug( LDAP_DEBUG_ANY, "%s\n",
+ gsserrstr( msg, sizeof(msg), mech, gss_rc, minor_status ),
+ NULL, NULL );
+
+ if (gss_rc == GSS_S_COMPLETE) {
+ ld->ld_errno = LDAP_SUCCESS;
+ } else if (GSS_CALLING_ERROR(gss_rc)) {
+ ld->ld_errno = LDAP_LOCAL_ERROR;
+ } else if (GSS_ROUTINE_ERROR(gss_rc)) {
+ ld->ld_errno = LDAP_INAPPROPRIATE_AUTH;
+ } else if (gss_rc == GSS_S_CONTINUE_NEEDED) {
+ ld->ld_errno = LDAP_SASL_BIND_IN_PROGRESS;
+ } else if (GSS_SUPPLEMENTARY_INFO(gss_rc)) {
+ ld->ld_errno = LDAP_AUTH_UNKNOWN;
+ } else if (GSS_ERROR(gss_rc)) {
+ ld->ld_errno = LDAP_AUTH_UNKNOWN;
+ } else {
+ ld->ld_errno = LDAP_OTHER;
+ }
+
+ return ld->ld_errno;
+}
+
+
+static int
+ldap_gssapi_get_rootdse_infos (
+ LDAP *ld,
+ char **pmechlist,
+ char **pldapServiceName,
+ char **pdnsHostName )
+{
+ /* we need to query the server for supported mechs anyway */
+ LDAPMessage *res, *e;
+ char *attrs[] = {
+ "supportedSASLMechanisms",
+ "ldapServiceName",
+ "dnsHostName",
+ NULL
+ };
+ char **values, *mechlist;
+ char *ldapServiceName = NULL;
+ char *dnsHostName = NULL;
+ int rc;
+
+ Debug( LDAP_DEBUG_TRACE, "ldap_gssapi_get_rootdse_infos\n", 0, 0, 0 );
+
+ rc = ldap_search_s( ld, "", LDAP_SCOPE_BASE,
+ NULL, attrs, 0, &res );
+
+ if ( rc != LDAP_SUCCESS ) {
+ return ld->ld_errno;
+ }
+
+ e = ldap_first_entry( ld, res );
+ if ( e == NULL ) {
+ ldap_msgfree( res );
+ if ( ld->ld_errno == LDAP_SUCCESS ) {
+ ld->ld_errno = LDAP_NO_SUCH_OBJECT;
+ }
+ return ld->ld_errno;
+ }
+
+ values = ldap_get_values( ld, e, "supportedSASLMechanisms" );
+ if ( values == NULL ) {
+ ldap_msgfree( res );
+ ld->ld_errno = LDAP_NO_SUCH_ATTRIBUTE;
+ return ld->ld_errno;
+ }
+
+ mechlist = ldap_charray2str( values, " " );
+ if ( mechlist == NULL ) {
+ LDAP_VFREE( values );
+ ldap_msgfree( res );
+ ld->ld_errno = LDAP_NO_MEMORY;
+ return ld->ld_errno;
+ }
+
+ LDAP_VFREE( values );
+
+ values = ldap_get_values( ld, e, "ldapServiceName" );
+ if ( values == NULL ) {
+ goto get_dns_host_name;
+ }
+
+ ldapServiceName = ldap_charray2str( values, " " );
+ if ( ldapServiceName == NULL ) {
+ LDAP_FREE( mechlist );
+ LDAP_VFREE( values );
+ ldap_msgfree( res );
+ ld->ld_errno = LDAP_NO_MEMORY;
+ return ld->ld_errno;
+ }
+ LDAP_VFREE( values );
+
+get_dns_host_name:
+
+ values = ldap_get_values( ld, e, "dnsHostName" );
+ if ( values == NULL ) {
+ goto done;
+ }
+
+ dnsHostName = ldap_charray2str( values, " " );
+ if ( dnsHostName == NULL ) {
+ LDAP_FREE( mechlist );
+ LDAP_FREE( ldapServiceName );
+ LDAP_VFREE( values );
+ ldap_msgfree( res );
+ ld->ld_errno = LDAP_NO_MEMORY;
+ return ld->ld_errno;
+ }
+ LDAP_VFREE( values );
+
+done:
+ ldap_msgfree( res );
+
+ *pmechlist = mechlist;
+ *pldapServiceName = ldapServiceName;
+ *pdnsHostName = dnsHostName;
+
+ return LDAP_SUCCESS;
+}
+
+
+static int check_for_gss_spnego_support( LDAP *ld, const char *mechs_str )
+{
+ int rc;
+ char **mechs_list = NULL;
+
+ mechs_list = ldap_str2charray( mechs_str, " " );
+ if ( mechs_list == NULL ) {
+ ld->ld_errno = LDAP_NO_MEMORY;
+ return ld->ld_errno;
+ }
+
+ rc = ldap_charray_inlist( mechs_list, "GSS-SPNEGO" );
+ ldap_charray_free( mechs_list );
+ if ( rc != 1) {
+ ld->ld_errno = LDAP_STRONG_AUTH_NOT_SUPPORTED;
+ return ld->ld_errno;
+ }
+
+ return LDAP_SUCCESS;
+}
+
+static int
+guess_service_principal(
+ LDAP *ld,
+ const char *ldapServiceName,
+ const char *dnsHostName,
+ gss_name_t *principal )
+{
+ gss_buffer_desc input_name;
+ /* GSS_KRB5_NT_PRINCIPAL_NAME */
+ gss_OID_desc nt_principal =
+ {10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01"};
+ const char *host = ld->ld_defconn->lconn_server->lud_host;
+ OM_uint32 minor_status;
+ int gss_rc;
+ int ret;
+ size_t svc_principal_size;
+ char *svc_principal = NULL;
+ const char *principal_fmt = NULL;
+ const char *str = NULL;
+ const char *givenstr = NULL;
+ const char *ignore = "not_defined_in_RFC4178@please_ignore";
+ int allow_remote = 0;
+
+ if (ldapServiceName) {
+ givenstr = strchr(ldapServiceName, ':');
+ if (givenstr && givenstr[1]) {
+ givenstr++;
+ if (strcmp(givenstr, ignore) == 0) {
+ givenstr = NULL;
+ }
+ } else {
+ givenstr = NULL;
+ }
+ }
+
+ if ( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL ) {
+ allow_remote = 1;
+ }
+
+ if (allow_remote && givenstr) {
+ principal_fmt = "%s";
+ svc_principal_size = strlen(givenstr) + 1;
+ str = givenstr;
+
+ } else if (allow_remote && dnsHostName) {
+ principal_fmt = "ldap/%s";
+ svc_principal_size = strlen(dnsHostName) + strlen(principal_fmt);
+ str = dnsHostName;
+
+ } else {
+ principal_fmt = "ldap/%s";
+ svc_principal_size = strlen(host) + strlen(principal_fmt);
+ str = host;
+ }
+
+ svc_principal = (char*) ldap_memalloc(svc_principal_size * sizeof(char));
+ if ( ret < 0 ) {
+ ld->ld_errno = LDAP_NO_MEMORY;
+ return ld->ld_errno;
+ }
+
+ ret = snprintf( svc_principal, svc_principal_size - 1, principal_fmt, str);
+ if (ret < 0 || ret >= svc_principal_size - 1) {
+ ld->ld_errno = LDAP_LOCAL_ERROR;
+ return ld->ld_errno;
+ }
+
+ Debug( LDAP_DEBUG_TRACE, "principal for host[%s]: '%s'\n",
+ host, svc_principal, 0 );
+
+ input_name.value = svc_principal;
+ input_name.length = strlen( svc_principal );
+
+ gss_rc = gss_import_name( &minor_status, &input_name, &nt_principal, principal );
+ ldap_memfree( svc_principal );
+ if ( gss_rc != GSS_S_COMPLETE ) {
+ return map_gsserr2ldap( ld, GSS_C_NO_OID, gss_rc, minor_status );
+ }
+
+ return LDAP_SUCCESS;
+}
+
+void ldap_int_gssapi_close( LDAP *ld, LDAPConn *lc )
+{
+ if ( lc && lc->lconn_gss_ctx ) {
+ OM_uint32 minor_status;
+ OM_uint32 ctx_flags = 0;
+ gss_ctx_id_t old_gss_ctx = GSS_C_NO_CONTEXT;
+ old_gss_ctx = (gss_ctx_id_t)lc->lconn_gss_ctx;
+
+ gss_inquire_context(&minor_status,
+ old_gss_ctx,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &ctx_flags,
+ NULL,
+ NULL);
+
+ if (!( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT )) {
+ gss_delete_sec_context( &minor_status, &old_gss_ctx, GSS_C_NO_BUFFER );
+ }
+ lc->lconn_gss_ctx = GSS_C_NO_CONTEXT;
+
+ if (ctx_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG)) {
+ /* remove wrapping layer */
+ sb_sasl_gssapi_remove( lc->lconn_sb );
+ }
+ }
+}
+
+static void
+ldap_int_gssapi_setup(
+ LDAP *ld,
+ LDAPConn *lc,
+ gss_ctx_id_t gss_ctx)
+{
+ OM_uint32 minor_status;
+ OM_uint32 ctx_flags = 0;
+
+ ldap_int_gssapi_close( ld, lc );
+
+ gss_inquire_context(&minor_status,
+ gss_ctx,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &ctx_flags,
+ NULL,
+ NULL);
+
+ lc->lconn_gss_ctx = gss_ctx;
+
+ if (ctx_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG)) {
+ /* setup wrapping layer */
+ sb_sasl_gssapi_install( lc->lconn_sb, gss_ctx );
+ }
+}
+
+#ifdef LDAP_R_COMPILE
+ldap_pvt_thread_mutex_t ldap_int_gssapi_mutex;
+#endif
+
+static int
+ldap_int_gss_spnego_bind_s( LDAP *ld )
+{
+ int rc;
+ int gss_rc;
+ OM_uint32 minor_status;
+ char *mechlist = NULL;
+ char *ldapServiceName = NULL;
+ char *dnsHostName = NULL;
+ gss_OID_set supported_mechs = GSS_C_NO_OID_SET;
+ int spnego_support = 0;
+#define __SPNEGO_OID_LENGTH 6
+#define __SPNEGO_OID "\053\006\001\005\005\002"
+ gss_OID_desc spnego_oid = {__SPNEGO_OID_LENGTH, __SPNEGO_OID};
+ gss_OID req_mech = GSS_C_NO_OID;
+ gss_OID ret_mech = GSS_C_NO_OID;
+ gss_ctx_id_t gss_ctx = GSS_C_NO_CONTEXT;
+ gss_name_t principal = GSS_C_NO_NAME;
+ OM_uint32 req_flags;
+ OM_uint32 ret_flags;
+ gss_buffer_desc input_token, output_token = GSS_C_EMPTY_BUFFER;
+ struct berval cred, *scred = NULL;
+
+#ifdef LDAP_R_COMPILE
+ ldap_pvt_thread_mutex_lock( &ldap_int_gssapi_mutex );
+#endif
+
+ /* get information from RootDSE entry */
+ rc = ldap_gssapi_get_rootdse_infos ( ld, &mechlist,
+ &ldapServiceName, &dnsHostName);
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ /* check that the server supports GSS-SPNEGO */
+ rc = check_for_gss_spnego_support( ld, mechlist );
+ if ( rc != LDAP_SUCCESS ) {
+ goto rc_error;
+ }
+
+ /* prepare new gss_ctx_id_t */
+ rc = guess_service_principal( ld, ldapServiceName, dnsHostName, &principal );
+ if ( rc != LDAP_SUCCESS ) {
+ goto rc_error;
+ }
+
+ /* see if our gssapi library supports spnego */
+ gss_rc = gss_indicate_mechs( &minor_status, &supported_mechs );
+ if ( gss_rc != GSS_S_COMPLETE ) {
+ goto gss_error;
+ }
+ gss_rc = gss_test_oid_set_member( &minor_status,
+ &spnego_oid, supported_mechs, &spnego_support);
+ gss_release_oid_set( &minor_status, &supported_mechs);
+ if ( gss_rc != GSS_S_COMPLETE ) {
+ goto gss_error;
+ }
+ if ( spnego_support != 0 ) {
+ req_mech = &spnego_oid;
+ }
+
+ req_flags = ld->ld_options.gssapi_flags;
+ req_flags |= GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
+
+ /*
+ * loop around gss_init_sec_context() and ldap_sasl_bind_s()
+ */
+ input_token.value = NULL;
+ input_token.length = 0;
+ gss_rc = gss_init_sec_context(&minor_status,
+ GSS_C_NO_CREDENTIAL,
+ &gss_ctx,
+ principal,
+ req_mech,
+ req_flags,
+ 0,
+ NULL,
+ &input_token,
+ &ret_mech,
+ &output_token,
+ &ret_flags,
+ NULL);
+ if ( gss_rc == GSS_S_COMPLETE ) {
+ rc = LDAP_INAPPROPRIATE_AUTH;
+ goto rc_error;
+ }
+ if ( gss_rc != GSS_S_CONTINUE_NEEDED ) {
+ goto gss_error;
+ }
+ while (1) {
+ cred.bv_val = (char *)output_token.value;
+ cred.bv_len = output_token.length;
+ rc = ldap_sasl_bind_s( ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred );
+ gss_release_buffer( &minor_status, &output_token );
+ if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
+ goto rc_error;
+ }
+
+ if ( scred ) {
+ input_token.value = scred->bv_val;
+ input_token.length = scred->bv_len;
+ } else {
+ input_token.value = NULL;
+ input_token.length = 0;
+ }
+
+ gss_rc = gss_init_sec_context(&minor_status,
+ GSS_C_NO_CREDENTIAL,
+ &gss_ctx,
+ principal,
+ req_mech,
+ req_flags,
+ 0,
+ NULL,
+ &input_token,
+ &ret_mech,
+ &output_token,
+ &ret_flags,
+ NULL);
+ if ( scred ) {
+ ber_bvfree( scred );
+ }
+ if ( gss_rc == GSS_S_COMPLETE ) {
+ gss_release_buffer( &minor_status, &output_token );
+ break;
+ }
+
+ if ( gss_rc != GSS_S_CONTINUE_NEEDED ) {
+ goto gss_error;
+ }
+ }
+
+ ldap_int_gssapi_setup( ld, ld->ld_defconn, gss_ctx);
+ gss_ctx = GSS_C_NO_CONTEXT;
+
+ rc = LDAP_SUCCESS;
+ goto rc_error;
+
+gss_error:
+ rc = map_gsserr2ldap( ld,
+ (ret_mech != GSS_C_NO_OID ? ret_mech : req_mech ),
+ gss_rc, minor_status );
+rc_error:
+#ifdef LDAP_R_COMPILE
+ ldap_pvt_thread_mutex_unlock( &ldap_int_gssapi_mutex );
+#endif
+ LDAP_FREE( mechlist );
+ LDAP_FREE( ldapServiceName );
+ LDAP_FREE( dnsHostName );
+ gss_release_buffer( &minor_status, &output_token );
+ if ( gss_ctx != GSS_C_NO_CONTEXT ) {
+ gss_delete_sec_context( &minor_status, &gss_ctx, GSS_C_NO_BUFFER );
+ }
+ if ( principal != GSS_C_NO_NAME ) {
+ gss_release_name( &minor_status, &principal );
+ }
+ return rc;
+}
+
+int
+ldap_int_gssapi_config( struct ldapoptions *lo, int option, const char *arg )
+{
+ int ok = 0;
+
+ switch( option ) {
+ case LDAP_OPT_SIGN:
+
+ if (!arg) {
+ } else if (strcasecmp(arg, "on") == 0) {
+ ok = 1;
+ } else if (strcasecmp(arg, "yes") == 0) {
+ ok = 1;
+ } else if (strcasecmp(arg, "true") == 0) {
+ ok = 1;
+
+ }
+ if (ok) {
+ lo->ldo_gssapi_flags |= GSS_C_INTEG_FLAG;
+ }
+
+ return 0;
+
+ case LDAP_OPT_ENCRYPT:
+
+ if (!arg) {
+ } else if (strcasecmp(arg, "on") == 0) {
+ ok = 1;
+ } else if (strcasecmp(arg, "yes") == 0) {
+ ok = 1;
+ } else if (strcasecmp(arg, "true") == 0) {
+ ok = 1;
+ }
+
+ if (ok) {
+ lo->ldo_gssapi_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;
+ }
+
+ return 0;
+
+ case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
+
+ if (!arg) {
+ } else if (strcasecmp(arg, "on") == 0) {
+ ok = 1;
+ } else if (strcasecmp(arg, "yes") == 0) {
+ ok = 1;
+ } else if (strcasecmp(arg, "true") == 0) {
+ ok = 1;
+ }
+
+ if (ok) {
+ lo->ldo_gssapi_options |= LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL;
+ }
+
+ return 0;
+ }
+
+ return -1;
+}
+
+int
+ldap_int_gssapi_get_option( LDAP *ld, int option, void *arg )
+{
+ if ( ld == NULL )
+ return -1;
+
+ switch ( option ) {
+ case LDAP_OPT_SSPI_FLAGS:
+ * (unsigned *) arg = (unsigned) ld->ld_options.gssapi_flags;
+ break;
+
+ case LDAP_OPT_SIGN:
+ if ( ld->ld_options.gssapi_flags & GSS_C_INTEG_FLAG ) {
+ * (int *) arg = (int)-1;
+ } else {
+ * (int *) arg = (int)0;
+ }
+ break;
+
+ case LDAP_OPT_ENCRYPT:
+ if ( ld->ld_options.gssapi_flags & GSS_C_CONF_FLAG ) {
+ * (int *) arg = (int)-1;
+ } else {
+ * (int *) arg = (int)0;
+ }
+ break;
+
+ case LDAP_OPT_SASL_METHOD:
+ * (char **) arg = LDAP_STRDUP("GSS-SPNEGO");
+ break;
+
+ case LDAP_OPT_SECURITY_CONTEXT:
+ if ( ld->ld_defconn && ld->ld_defconn->lconn_gss_ctx ) {
+ * (gss_ctx_id_t *) arg = (gss_ctx_id_t)ld->ld_defconn->lconn_gss_ctx;
+ } else {
+ * (gss_ctx_id_t *) arg = GSS_C_NO_CONTEXT;
+ }
+ break;
+
+ case LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT:
+ if ( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT ) {
+ * (int *) arg = (int)-1;
+ } else {
+ * (int *) arg = (int)0;
+ }
+ break;
+
+ case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
+ if ( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL ) {
+ * (int *) arg = (int)-1;
+ } else {
+ * (int *) arg = (int)0;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+ldap_int_gssapi_set_option( LDAP *ld, int option, void *arg )
+{
+ if ( ld == NULL )
+ return -1;
+
+ switch ( option ) {
+ case LDAP_OPT_SSPI_FLAGS:
+ if ( arg != LDAP_OPT_OFF ) {
+ ld->ld_options.gssapi_flags = * (unsigned *)arg;
+ }
+ break;
+
+ case LDAP_OPT_SIGN:
+ if ( arg != LDAP_OPT_OFF ) {
+ ld->ld_options.gssapi_flags |= GSS_C_INTEG_FLAG;
+ }
+ break;
+
+ case LDAP_OPT_ENCRYPT:
+ if ( arg != LDAP_OPT_OFF ) {
+ ld->ld_options.gssapi_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;
+ }
+ break;
+
+ case LDAP_OPT_SASL_METHOD:
+ if ( arg != LDAP_OPT_OFF ) {
+ const char *m = (const char *)arg;
+ if ( strcmp( "GSS-SPNEGO", m ) != 0 ) {
+ /* we currently only support GSS-SPNEGO */
+ return -1;
+ }
+ }
+ break;
+
+ case LDAP_OPT_SECURITY_CONTEXT:
+ if ( arg != LDAP_OPT_OFF && ld->ld_defconn) {
+ ldap_int_gssapi_setup( ld, ld->ld_defconn,
+ (gss_ctx_id_t) arg);
+ }
+ break;
+
+ case LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT:
+ if ( arg != LDAP_OPT_OFF ) {
+ ld->ld_options.ldo_gssapi_options |= LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT;
+ }
+ break;
+
+ case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
+ if ( arg != LDAP_OPT_OFF ) {
+ ld->ld_options.ldo_gssapi_options |= LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+#else /* HAVE_GSSAPI */
+#define ldap_int_gss_spnego_bind_s(ld) LDAP_NOT_SUPPORTED
+#endif /* HAVE_GSSAPI */
+
+int
+ldap_gssapi_bind(
+ LDAP *ld,
+ LDAP_CONST char *dn,
+ LDAP_CONST char *creds )
+{ return LDAP_NOT_SUPPORTED; }
+
+int
+ldap_gssapi_bind_s(
+ LDAP *ld,
+ LDAP_CONST char *dn,
+ LDAP_CONST char *creds )
+{
+ if ( dn != NULL ) {
+ return LDAP_NOT_SUPPORTED;
+ }
+
+ if ( creds != NULL ) {
+ return LDAP_NOT_SUPPORTED;
+ }
+
+ return ldap_int_gss_spnego_bind_s(ld);
+}
#define ATTR_OPT_TV 8
#define ATTR_OPT_INT 9
+#define ATTR_GSSAPI 10
+
struct ol_keyvalue {
const char * key;
int value;
{0, ATTR_SASL, "SASL_SECPROPS", NULL, LDAP_OPT_X_SASL_SECPROPS},
#endif
+#ifdef HAVE_GSSAPI
+ {0, ATTR_GSSAPI,"GSSAPI_SIGN", NULL, LDAP_OPT_SIGN},
+ {0, ATTR_GSSAPI,"GSSAPI_ENCRYPT", NULL, LDAP_OPT_ENCRYPT},
+ {0, ATTR_GSSAPI,"GSSAPI_ALLOW_REMOTE_PRINCIPAL",NULL, LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL},
+#endif
+
#ifdef HAVE_TLS
{1, ATTR_TLS, "TLS_CERT", NULL, LDAP_OPT_X_TLS_CERTFILE},
{1, ATTR_TLS, "TLS_KEY", NULL, LDAP_OPT_X_TLS_KEYFILE},
{0, ATTR_NONE, NULL, NULL, 0}
};
-#define MAX_LDAP_ATTR_LEN sizeof("TLS_CIPHER_SUITE")
+#define MAX_LDAP_ATTR_LEN sizeof("GSSAPI_ALLOW_REMOTE_PRINCIPAL")
#define MAX_LDAP_ENV_PREFIX_LEN 8
static void openldap_ldap_init_w_conf(
case ATTR_SASL:
#ifdef HAVE_CYRUS_SASL
ldap_int_sasl_config( gopts, attrs[i].offset, opt );
+#endif
+ break;
+ case ATTR_GSSAPI:
+#ifdef HAVE_GSSAPI
+ ldap_int_gssapi_config( gopts, attrs[i].offset, opt );
#endif
break;
case ATTR_TLS:
struct sasl_security_properties ldo_sasl_secprops;
#endif
+#ifdef HAVE_GSSAPI
+ unsigned gssapi_flags;
+
+ unsigned ldo_gssapi_flags;
+#define LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT 0x0001
+#define LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL 0x0002
+ unsigned ldo_gssapi_options;
+#endif
+
int ldo_refhoplimit; /* limit on referral nesting */
/* LDAPv3 server and client controls */
#ifdef HAVE_CYRUS_SASL
void *lconn_sasl_authctx; /* context for bind */
void *lconn_sasl_sockctx; /* for security layer */
+#endif
+#ifdef HAVE_GSSAPI
+ void *lconn_gss_ctx; /* gss_ctx_id_t */
#endif
int lconn_refcnt;
time_t lconn_created; /* time */
#ifdef HAVE_CYRUS_SASL
LDAP_V( ldap_pvt_thread_mutex_t ) ldap_int_sasl_mutex;
#endif
+#ifdef HAVE_GSSAPI
+LDAP_V( ldap_pvt_thread_mutex_t ) ldap_int_gssapi_mutex;
+#endif
#endif
#ifdef LDAP_R_COMPILE
if ( ldap_int_sasl_get_option( ld, option, outvalue ) == 0 ) {
return LDAP_OPT_SUCCESS;
}
+#endif
+#ifdef HAVE_GSSAPI
+ if ( ldap_int_gssapi_get_option( ld, option, outvalue ) == 0 ) {
+ return LDAP_OPT_SUCCESS;
+ }
#endif
/* bad param */
break;
#ifdef HAVE_CYRUS_SASL
if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 )
return LDAP_OPT_SUCCESS;
+#endif
+#ifdef HAVE_GSSAPI
+ if ( ldap_int_gssapi_set_option( ld, option, (void *)invalue ) == 0 )
+ return LDAP_OPT_SUCCESS;
#endif
/* bad param */
return LDAP_OPT_ERROR;
== AC_SOCKET_ERROR )
{
/* XXX: needs to be replace with ber_stream_read() */
- read(s, &ch, 1);
+ int rc = read(s, &ch, 1);
TRACE;
return -1;
}
== AC_SOCKET_ERROR )
{
/* XXX: needs to be replace with ber_stream_read() */
- read(s, &ch, 1);
+ int rc = read(s, &ch, 1);
TRACE;
return -1;
}
}
ldap_int_sasl_close( ld, lc );
+#ifdef HAVE_GSSAPI
+ ldap_int_gssapi_close( ld, lc );
+#endif
ldap_free_urllist( lc->lconn_server );
return rc;
}
+
+#ifdef HAVE_CYRUS_SASL
+
+#ifdef HAVE_SASL_SASL_H
+#include <sasl/sasl.h>
+#else
+#include <sasl.h>
+#endif
+
+#endif /* HAVE_CYRUS_SASL */
+
+static int
+sb_sasl_generic_remove( Sockbuf_IO_Desc *sbiod );
+
+static int
+sb_sasl_generic_setup( Sockbuf_IO_Desc *sbiod, void *arg )
+{
+ struct sb_sasl_generic_data *p;
+ struct sb_sasl_generic_install *i;
+
+ assert( sbiod != NULL );
+
+ i = (struct sb_sasl_generic_install *)arg;
+
+ p = LBER_MALLOC( sizeof( *p ) );
+ if ( p == NULL )
+ return -1;
+ p->ops = i->ops;
+ p->ops_private = i->ops_private;
+ p->sbiod = sbiod;
+ ber_pvt_sb_buf_init( &p->sec_buf_in );
+ ber_pvt_sb_buf_init( &p->buf_in );
+ ber_pvt_sb_buf_init( &p->buf_out );
+
+ sbiod->sbiod_pvt = p;
+
+ p->ops->init( p, &p->min_send, &p->max_send, &p->max_recv );
+
+ if ( ber_pvt_sb_grow_buffer( &p->sec_buf_in, p->min_send ) < 0 ) {
+ sb_sasl_generic_remove( sbiod );
+ sock_errset(ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+sb_sasl_generic_remove( Sockbuf_IO_Desc *sbiod )
+{
+ struct sb_sasl_generic_data *p;
+
+ assert( sbiod != NULL );
+
+ p = (struct sb_sasl_generic_data *)sbiod->sbiod_pvt;
+
+ p->ops->fini(p);
+
+ ber_pvt_sb_buf_destroy( &p->sec_buf_in );
+ ber_pvt_sb_buf_destroy( &p->buf_in );
+ ber_pvt_sb_buf_destroy( &p->buf_out );
+ LBER_FREE( p );
+ sbiod->sbiod_pvt = NULL;
+ return 0;
+}
+
+static ber_len_t
+sb_sasl_generic_pkt_length(
+ struct sb_sasl_generic_data *p,
+ const unsigned char *buf,
+ int debuglevel )
+{
+ ber_len_t size;
+
+ assert( buf != NULL );
+
+ size = buf[0] << 24
+ | buf[1] << 16
+ | buf[2] << 8
+ | buf[3];
+
+ if ( size > p->max_recv ) {
+ /* somebody is trying to mess me up. */
+ ber_log_printf( LDAP_DEBUG_ANY, debuglevel,
+ "sb_sasl_generic_pkt_length: "
+ "received illegal packet length of %lu bytes\n",
+ (unsigned long)size );
+ size = 16; /* this should lead to an error. */
+ }
+
+ return size + 4; /* include the size !!! */
+}
+
+/* Drop a processed packet from the input buffer */
+static void
+sb_sasl_generic_drop_packet (
+ struct sb_sasl_generic_data *p,
+ int debuglevel )
+{
+ ber_slen_t len;
+
+ len = p->sec_buf_in.buf_ptr - p->sec_buf_in.buf_end;
+ if ( len > 0 )
+ AC_MEMCPY( p->sec_buf_in.buf_base, p->sec_buf_in.buf_base +
+ p->sec_buf_in.buf_end, len );
+
+ if ( len >= 4 ) {
+ p->sec_buf_in.buf_end = sb_sasl_generic_pkt_length(p,
+ (unsigned char *) p->sec_buf_in.buf_base, debuglevel);
+ }
+ else {
+ p->sec_buf_in.buf_end = 0;
+ }
+ p->sec_buf_in.buf_ptr = len;
+}
+
+static ber_slen_t
+sb_sasl_generic_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+ struct sb_sasl_generic_data *p;
+ ber_slen_t ret, bufptr;
+
+ assert( sbiod != NULL );
+ assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+
+ p = (struct sb_sasl_generic_data *)sbiod->sbiod_pvt;
+
+ /* Are there anything left in the buffer? */
+ ret = ber_pvt_sb_copy_out( &p->buf_in, buf, len );
+ bufptr = ret;
+ len -= ret;
+
+ if ( len == 0 )
+ return bufptr;
+
+ p->ops->reset_buf( p, &p->buf_in );
+
+ /* Read the length of the packet */
+ while ( p->sec_buf_in.buf_ptr < 4 ) {
+ ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base +
+ p->sec_buf_in.buf_ptr,
+ 4 - p->sec_buf_in.buf_ptr );
+#ifdef EINTR
+ if ( ( ret < 0 ) && ( errno == EINTR ) )
+ continue;
+#endif
+ if ( ret <= 0 )
+ return bufptr ? bufptr : ret;
+
+ p->sec_buf_in.buf_ptr += ret;
+ }
+
+ /* The new packet always starts at p->sec_buf_in.buf_base */
+ ret = sb_sasl_generic_pkt_length(p, (unsigned char *) p->sec_buf_in.buf_base,
+ sbiod->sbiod_sb->sb_debug );
+
+ /* Grow the packet buffer if neccessary */
+ if ( ( p->sec_buf_in.buf_size < (ber_len_t) ret ) &&
+ ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 )
+ {
+ sock_errset(ENOMEM);
+ return -1;
+ }
+ p->sec_buf_in.buf_end = ret;
+
+ /* Did we read the whole encrypted packet? */
+ while ( p->sec_buf_in.buf_ptr < p->sec_buf_in.buf_end ) {
+ /* No, we have got only a part of it */
+ ret = p->sec_buf_in.buf_end - p->sec_buf_in.buf_ptr;
+
+ ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base +
+ p->sec_buf_in.buf_ptr, ret );
+#ifdef EINTR
+ if ( ( ret < 0 ) && ( errno == EINTR ) )
+ continue;
+#endif
+ if ( ret <= 0 )
+ return bufptr ? bufptr : ret;
+
+ p->sec_buf_in.buf_ptr += ret;
+ }
+
+ /* Decode the packet */
+ ret = p->ops->decode( p, &p->sec_buf_in, &p->buf_in );
+
+ /* Drop the packet from the input buffer */
+ sb_sasl_generic_drop_packet( p, sbiod->sbiod_sb->sb_debug );
+
+ if ( ret != 0 ) {
+ ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_generic_read: failed to decode packet\n" );
+ sock_errset(EIO);
+ return -1;
+ }
+
+ bufptr += ber_pvt_sb_copy_out( &p->buf_in, (char*) buf + bufptr, len );
+
+ return bufptr;
+}
+
+static ber_slen_t
+sb_sasl_generic_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+ struct sb_sasl_generic_data *p;
+ int ret;
+
+ assert( sbiod != NULL );
+ assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+
+ p = (struct sb_sasl_generic_data *)sbiod->sbiod_pvt;
+
+ /* Are there anything left in the buffer? */
+ if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
+ ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
+ if ( ret < 0 ) return ret;
+
+ /* Still have something left?? */
+ if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
+ sock_errset(EAGAIN);
+ return -1;
+ }
+ }
+
+ /* now encode the next packet. */
+ p->ops->reset_buf( p, &p->buf_out );
+
+ if ( len > p->max_send - 100 ) {
+ len = p->max_send - 100; /* For safety margin */
+ }
+
+ ret = p->ops->encode( p, buf, len, &p->buf_out );
+
+ if ( ret != 0 ) {
+ ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
+ "sb_sasl_generic_write: failed to encode packet\n" );
+ sock_errset(EIO);
+ return -1;
+ }
+
+ ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
+
+ /* return number of bytes encoded, not written, to ensure
+ * no byte is encoded twice (even if only sent once).
+ */
+ return len;
+}
+
+static int
+sb_sasl_generic_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
+{
+ struct sb_sasl_generic_data *p;
+
+ p = (struct sb_sasl_generic_data *)sbiod->sbiod_pvt;
+
+ if ( opt == LBER_SB_OPT_DATA_READY ) {
+ if ( p->buf_in.buf_ptr != p->buf_in.buf_end ) return 1;
+ }
+
+ return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
+}
+
+Sockbuf_IO ldap_pvt_sockbuf_io_sasl_generic = {
+ sb_sasl_generic_setup, /* sbi_setup */
+ sb_sasl_generic_remove, /* sbi_remove */
+ sb_sasl_generic_ctrl, /* sbi_ctrl */
+ sb_sasl_generic_read, /* sbi_read */
+ sb_sasl_generic_write, /* sbi_write */
+ NULL /* sbi_close */
+};
+
+int ldap_pvt_sasl_generic_install(
+ Sockbuf *sb,
+ struct sb_sasl_generic_install *install_arg )
+{
+ Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_generic_install\n",
+ 0, 0, 0 );
+
+ /* don't install the stuff unless security has been negotiated */
+
+ if ( !ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO,
+ &ldap_pvt_sockbuf_io_sasl_generic ) )
+ {
+#ifdef LDAP_DEBUG
+ ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
+ LBER_SBIOD_LEVEL_APPLICATION, (void *)"sasl_generic_" );
+#endif
+ ber_sockbuf_add_io( sb, &ldap_pvt_sockbuf_io_sasl_generic,
+ LBER_SBIOD_LEVEL_APPLICATION, install_arg );
+ }
+
+ return LDAP_SUCCESS;
+}
+
+void ldap_pvt_sasl_generic_remove( Sockbuf *sb )
+{
+ ber_sockbuf_remove_io( sb, &ldap_pvt_sockbuf_io_sasl_generic,
+ LBER_SBIOD_LEVEL_APPLICATION );
+#ifdef LDAP_DEBUG
+ ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
+ LBER_SBIOD_LEVEL_APPLICATION );
+#endif
+}
#ifdef HAVE_CYRUS_SASL
ldap_pvt_thread_mutex_init( &ldap_int_sasl_mutex );
#endif
+#ifdef HAVE_GSSAPI
+ ldap_pvt_thread_mutex_init( &ldap_int_gssapi_mutex );
+#endif
#endif
/* call other module init functions here... */
bind.c open.c result.c error.c compare.c search.c \
controls.c messages.c references.c extended.c cyrus.c \
modify.c add.c modrdn.c delete.c abandon.c \
- sasl.c sbind.c unbind.c cancel.c \
+ sasl.c gssapi.c sbind.c unbind.c cancel.c \
filter.c free.c sort.c passwd.c whoami.c \
getdn.c getentry.c getattr.c getvalues.c addentry.c \
request.c os-ip.c url.c pagectrl.c sortctrl.c vlvctrl.c \
bind.lo open.lo result.lo error.lo compare.lo search.lo \
controls.lo messages.lo references.lo extended.lo cyrus.lo \
modify.lo add.lo modrdn.lo delete.lo abandon.lo \
- sasl.lo sbind.lo unbind.lo cancel.lo \
+ sasl.lo gssapi.lo sbind.lo unbind.lo cancel.lo \
filter.lo free.lo sort.lo passwd.lo whoami.lo \
getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
request.lo os-ip.lo url.lo pagectrl.lo sortctrl.lo vlvctrl.lo \