diff --git a/configure b/configure index 3fe6e12345..1ae425ebfb 100755 --- a/configure +++ b/configure @@ -314,7 +314,7 @@ ac_includes_default="\ # include #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 configure_args build build_cpu build_vendor build_os host host_cpu host_vendor host_os PORTNAME docdir enable_nls WANTED_LANGUAGES default_port enable_shared enable_rpath enable_debug CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP GCC TAS autodepend INCLUDES enable_thread_safety with_tcl with_perl with_python with_krb5 krb_srvtab with_pam with_bonjour with_openssl with_zlib EGREP ELF_SYS LDFLAGS_SL AWK FLEX FLEXFLAGS LN_S LD with_gnu_ld ld_R_works RANLIB ac_ct_RANLIB LORDER TAR STRIP ac_ct_STRIP STRIP_STATIC_LIB STRIP_SHARED_LIB YACC YFLAGS PERL perl_archlibexp perl_privlibexp perl_useshrplib perl_embed_ldflags PYTHON python_version python_configdir python_includespec python_libdir python_libspec python_additional_libs HAVE_IPV6 LIBOBJS acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS HAVE_POSIX_SIGNALS MSGFMT MSGMERGE XGETTEXT localedir TCLSH TCL_CONFIG_SH TCL_INCLUDE_SPEC TCL_LIB_FILE TCL_LIBS TCL_LIB_SPEC TCL_SHARED_BUILD TCL_SHLIB_LD_LIBS NSGMLS JADE have_docbook DOCBOOKSTYLE COLLATEINDEX SGMLSPL vpath_build 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 configure_args build build_cpu build_vendor build_os host host_cpu host_vendor host_os PORTNAME docdir enable_nls WANTED_LANGUAGES default_port enable_shared enable_rpath enable_debug CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP GCC TAS autodepend INCLUDES enable_thread_safety with_tcl with_perl with_python with_krb5 krb_srvtab with_pam with_ldap with_bonjour with_openssl with_zlib EGREP ELF_SYS LDFLAGS_SL AWK FLEX FLEXFLAGS LN_S LD with_gnu_ld ld_R_works RANLIB ac_ct_RANLIB LORDER TAR STRIP ac_ct_STRIP STRIP_STATIC_LIB STRIP_SHARED_LIB YACC YFLAGS PERL perl_archlibexp perl_privlibexp perl_useshrplib perl_embed_ldflags PYTHON python_version python_configdir python_includespec python_libdir python_libspec python_additional_libs HAVE_IPV6 LIBOBJS acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS HAVE_POSIX_SIGNALS MSGFMT MSGMERGE XGETTEXT localedir TCLSH TCL_CONFIG_SH TCL_INCLUDE_SPEC TCL_LIB_FILE TCL_LIBS TCL_LIB_SPEC TCL_SHARED_BUILD TCL_SHLIB_LD_LIBS NSGMLS JADE have_docbook DOCBOOKSTYLE COLLATEINDEX SGMLSPL vpath_build LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -888,6 +888,7 @@ Optional Packages: --with-krb5 build with Kerberos 5 support --with-krb-srvnam=NAME name of the default service principal in Kerberos [postgres] --with-pam build with PAM support + --with-ldap build with LDAP support --with-bonjour build with Bonjour support --with-openssl build with OpenSSL support --with-libedit-preferred prefer BSD Libedit over GNU Readline @@ -3690,6 +3691,46 @@ echo "${ECHO_T}$with_pam" >&6 +# +# LDAP +# +echo "$as_me:$LINENO: checking whether to build with LDAP support" >&5 +echo $ECHO_N "checking whether to build with LDAP support... $ECHO_C" >&6 + + + +# Check whether --with-ldap or --without-ldap was given. +if test "${with_ldap+set}" = set; then + withval="$with_ldap" + + case $withval in + yes) + +cat >>confdefs.h <<\_ACEOF +#define USE_LDAP 1 +_ACEOF + + ;; + no) + : + ;; + *) + { { echo "$as_me:$LINENO: error: no argument expected for --with-ldap option" >&5 +echo "$as_me: error: no argument expected for --with-ldap option" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + +else + with_ldap=no + +fi; + +echo "$as_me:$LINENO: result: $with_ldap" >&5 +echo "${ECHO_T}$with_ldap" >&6 + + + # # Bonjour # @@ -7170,6 +7211,168 @@ fi fi +if test "$with_ldap" = yes ; then + if test "$PORTNAME" != "win32"; then + +echo "$as_me:$LINENO: checking for ldap_bind in -lldap" >&5 +echo $ECHO_N "checking for ldap_bind in -lldap... $ECHO_C" >&6 +if test "${ac_cv_lib_ldap_ldap_bind+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lldap $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 ldap_bind (); +int +main () +{ +ldap_bind (); + ; + 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_ldap_ldap_bind=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_ldap_ldap_bind=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_bind" >&5 +echo "${ECHO_T}$ac_cv_lib_ldap_ldap_bind" >&6 +if test $ac_cv_lib_ldap_ldap_bind = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBLDAP 1 +_ACEOF + + LIBS="-lldap $LIBS" + +else + { { echo "$as_me:$LINENO: error: library 'ldap' is required for LDAP" >&5 +echo "$as_me: error: library 'ldap' is required for LDAP" >&2;} + { (exit 1); exit 1; }; } +fi + + else + +echo "$as_me:$LINENO: checking for ldap_bind in -lwldap32" >&5 +echo $ECHO_N "checking for ldap_bind in -lwldap32... $ECHO_C" >&6 +if test "${ac_cv_lib_wldap32_ldap_bind+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lwldap32 $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 ldap_bind (); +int +main () +{ +ldap_bind (); + ; + 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_wldap32_ldap_bind=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_wldap32_ldap_bind=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_wldap32_ldap_bind" >&5 +echo "${ECHO_T}$ac_cv_lib_wldap32_ldap_bind" >&6 +if test $ac_cv_lib_wldap32_ldap_bind = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBWLDAP32 1 +_ACEOF + + LIBS="-lwldap32 $LIBS" + +else + { { echo "$as_me:$LINENO: error: library 'wldap32' is required for LDAP" >&5 +echo "$as_me: error: library 'wldap32' is required for LDAP" >&2;} + { (exit 1); exit 1; }; } +fi + + fi +fi + ## ## Header files ## @@ -10268,6 +10471,233 @@ done fi +if test "$with_ldap" = yes ; then + if test "$PORTNAME" != "win32"; then + +for ac_header in ldap.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 pgsql-bugs@postgresql.org ## +## ---------------------------------------- ## +_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 + +else + { { echo "$as_me:$LINENO: error: header file is required for LDAP" >&5 +echo "$as_me: error: header file is required for LDAP" >&2;} + { (exit 1); exit 1; }; } +fi + +done + + else + +for ac_header in winldap.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +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 + 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 + + +#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 + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + { { echo "$as_me:$LINENO: error: header file is required for LDAP" >&5 +echo "$as_me: error: header file is required for LDAP" >&2;} + { (exit 1); exit 1; }; } +fi + +done + + fi +fi + if test "$with_bonjour" = yes ; then if test "${ac_cv_header_DNSServiceDiscovery_DNSServiceDiscovery_h+set}" = set; then echo "$as_me:$LINENO: checking for DNSServiceDiscovery/DNSServiceDiscovery.h" >&5 @@ -22822,6 +23252,7 @@ s,@with_python@,$with_python,;t t s,@with_krb5@,$with_krb5,;t t s,@krb_srvtab@,$krb_srvtab,;t t s,@with_pam@,$with_pam,;t t +s,@with_ldap@,$with_ldap,;t t s,@with_bonjour@,$with_bonjour,;t t s,@with_openssl@,$with_openssl,;t t s,@with_zlib@,$with_zlib,;t t diff --git a/configure.in b/configure.in index 0eec99433d..d4a11f2ba0 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -dnl $PostgreSQL: pgsql/configure.in,v 1.454 2006/03/05 15:58:18 momjian Exp $ +dnl $PostgreSQL: pgsql/configure.in,v 1.455 2006/03/06 17:41:43 momjian Exp $ dnl dnl Developers, please strive to achieve this order: dnl @@ -444,6 +444,17 @@ AC_MSG_RESULT([$with_pam]) AC_SUBST(with_pam) +# +# LDAP +# +AC_MSG_CHECKING([whether to build with LDAP support]) +PGAC_ARG_BOOL(with, ldap, no, + [ --with-ldap build with LDAP support], + [AC_DEFINE([USE_LDAP], 1, [Define to 1 to build with LDAP support. (--with-ldap)])]) +AC_MSG_RESULT([$with_ldap]) +AC_SUBST(with_ldap) + + # # Bonjour # @@ -669,6 +680,14 @@ if test "$with_pam" = yes ; then fi +if test "$with_ldap" = yes ; then + if test "$PORTNAME" != "win32"; then + AC_CHECK_LIB(ldap, ldap_bind, [], [AC_MSG_ERROR([library 'ldap' is required for LDAP])]) + else + AC_CHECK_LIB(wldap32, ldap_bind, [], [AC_MSG_ERROR([library 'wldap32' is required for LDAP])]) + fi +fi + ## ## Header files ## @@ -744,6 +763,19 @@ if test "$with_pam" = yes ; then [AC_MSG_ERROR([header file or is required for PAM.])])]) fi +if test "$with_ldap" = yes ; then + if test "$PORTNAME" != "win32"; then + AC_CHECK_HEADERS(ldap.h, [], + [AC_MSG_ERROR([header file is required for LDAP])]) + else + AC_CHECK_HEADERS(winldap.h, [], + [AC_MSG_ERROR([header file is required for LDAP])], + [AC_INCLUDES_DEFAULT +#include + ]) + fi +fi + if test "$with_bonjour" = yes ; then AC_CHECK_HEADER(DNSServiceDiscovery/DNSServiceDiscovery.h, [], [AC_MSG_ERROR([header file is required for Bonjour])]) fi diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 4d4e93943e..60a5c85728 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.134 2006/03/05 15:58:27 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.135 2006/03/06 17:41:43 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -69,6 +69,32 @@ static Port *pam_port_cludge; /* Workaround for passing "Port *port" into * pam_passwd_conv_proc */ #endif /* USE_PAM */ +#ifdef USE_LDAP +#ifndef WIN32 +/* We use a deprecated function to keep the codepaths the same as the + * win32 one. */ +#define LDAP_DEPRECATED 1 +#include +#else +/* Header broken in MingW */ +#define ldap_start_tls_sA __BROKEN_LDAP_HEADER +#include +#undef ldap_start_tls_sA + +/* Correct header from the Platform SDK */ +WINLDAPAPI ULONG ldap_start_tls_sA ( + IN PLDAP ExternalHandle, + OUT PULONG ServerReturnValue, + OUT LDAPMessage **result, + IN PLDAPControlA *ServerControls, + IN PLDAPControlA *ClientControls +); +#endif + +static int CheckLDAPAuth(Port *port); +#endif + + #ifdef KRB5 /*---------------------------------------------------------------- * MIT Kerberos authentication system - protocol version 5 @@ -327,6 +353,11 @@ auth_failed(Port *port, int status) errstr = gettext_noop("PAM authentication failed for user \"%s\""); break; #endif /* USE_PAM */ +#ifdef USE_LDAP + case uaLDAP: + errstr = gettext_noop("LDAP authentication failed for user \"%s\""); + break; +#endif /* USE_LDAP */ default: errstr = gettext_noop("authentication failed for user \"%s\": invalid authentication method"); break; @@ -455,6 +486,12 @@ ClientAuthentication(Port *port) break; #endif /* USE_PAM */ +#ifdef USE_LDAP + case uaLDAP: + status = CheckLDAPAuth(port); + break; +#endif + case uaTrust: status = STATUS_OK; break; @@ -674,6 +711,132 @@ CheckPAMAuth(Port *port, char *user, char *password) #endif /* USE_PAM */ +#ifdef USE_LDAP +static int +CheckLDAPAuth(Port *port) +{ + char *passwd; + char server[128]; + char basedn[128]; + char prefix[128]; + char suffix[128]; + LDAP *ldap; + int ssl = 0; + int r; + int ldapversion = LDAP_VERSION3; + int ldapport = LDAP_PORT; + char fulluser[128]; + + if (!port->auth_arg || port->auth_arg[0] == '\0') + { + ereport(LOG, + (errmsg("LDAP configuration URL not specified"))); + return STATUS_ERROR; + } + + /* + * Crack the LDAP url. We do a very trivial parse.. + * ldap[s]://[:]/[;prefix[;suffix]] + */ + + server[0] = '\0'; + basedn[0] = '\0'; + prefix[0] = '\0'; + suffix[0] = '\0'; + + /* ldap, including port number */ + r = sscanf(port->auth_arg, + "ldap://%127[^:]:%i/%127[^;];%127[^;];%127s", + server, &ldapport, basedn, prefix, suffix); + if (r < 3) + { + /* ldaps, including port number */ + r = sscanf(port->auth_arg, + "ldaps://%127[^:]:%i/%127[^;];%127[^;];%127s", + server, &ldapport, basedn, prefix, suffix); + if (r >=3) ssl = 1; + } + if (r < 3) + { + /* ldap, no port number */ + r = sscanf(port->auth_arg, + "ldap://%127[^/]/%127[^;];%127[^;];%127s", + server, basedn, prefix, suffix); + } + if (r < 2) + { + /* ldaps, no port number */ + r = sscanf(port->auth_arg, + "ldaps://%127[^/]/%127[^;];%127[^;];%127s", + server, basedn, prefix, suffix); + if (r >= 2) ssl = 1; + } + if (r < 2) + { + ereport(LOG, + (errmsg("Invalid LDAP url: '%s'", port->auth_arg))); + return STATUS_ERROR; + } + + sendAuthRequest(port, AUTH_REQ_PASSWORD); + + passwd = recv_password_packet(port); + if (passwd == NULL) + return STATUS_EOF; /* client wouldn't send password */ + + + ldap = ldap_init(server, ldapport); + if (!ldap) + { + ereport(LOG, + (errmsg("Failed to initialize LDAP: %i", +#ifndef WIN32 + errno +#else + (int)LdapGetLastError() +#endif + ))); + return STATUS_ERROR; + } + + if ((r = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS) + { + ereport(LOG, + (errmsg("Failed to set LDAP version: %i", r))); + return STATUS_ERROR; + } + + if (ssl) + { +#ifndef WIN32 + if ((r = ldap_start_tls_s(ldap, NULL, NULL)) != LDAP_SUCCESS) +#else + if ((r = ldap_start_tls_sA(ldap, NULL, NULL, NULL, NULL)) != LDAP_SUCCESS) +#endif + { + ereport(LOG, + (errmsg("Failed to start LDAP TLS session: %i", r))); + return STATUS_ERROR; + } + } + + snprintf(fulluser, sizeof(fulluser)-1, "%s%s%s", prefix, port->user_name, suffix); + fulluser[sizeof(fulluser)-1] = '\0'; + + r = ldap_simple_bind_s(ldap, fulluser, passwd); + ldap_unbind(ldap); + + if (r != LDAP_SUCCESS) + { + ereport(LOG, + (errmsg("LDAP login failed for user '%s' on server '%s': %i",fulluser,server,r))); + return STATUS_ERROR; + } + + return STATUS_OK; +} +#endif /* USE_LDAP */ + /* * Collect password response packet from frontend. * diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 31be6ba33e..a31f968baa 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.150 2006/03/05 15:58:27 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.151 2006/03/06 17:41:43 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -612,6 +612,10 @@ parse_hba_auth(ListCell **line_item, UserAuth *userauth_p, #ifdef USE_PAM else if (strcmp(token, "pam") == 0) *userauth_p = uaPAM; +#endif +#ifdef USE_LDAP + else if (strcmp(token,"ldap") == 0) + *userauth_p = uaLDAP; #endif else { diff --git a/src/backend/libpq/pg_hba.conf.sample b/src/backend/libpq/pg_hba.conf.sample index 521ce4ef09..abf4e827f1 100644 --- a/src/backend/libpq/pg_hba.conf.sample +++ b/src/backend/libpq/pg_hba.conf.sample @@ -35,7 +35,7 @@ # an IP address and netmask in separate columns to specify the set of hosts. # # METHOD can be "trust", "reject", "md5", "crypt", "password", -# "krb5", "ident", or "pam". Note that "password" sends passwords +# "krb5", "ident", "pam" or "ldap". Note that "password" sends passwords # in clear text; "md5" is preferred since it sends encrypted passwords. # # OPTION is the ident map or the name of the PAM service, depending on METHOD. diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h index 5251db1c05..eaa3cf529c 100644 --- a/src/include/libpq/hba.h +++ b/src/include/libpq/hba.h @@ -4,7 +4,7 @@ * Interface to hba.c * * - * $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.41 2005/10/15 02:49:44 momjian Exp $ + * $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.42 2006/03/06 17:41:44 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -26,6 +26,9 @@ typedef enum UserAuth #ifdef USE_PAM ,uaPAM #endif /* USE_PAM */ +#ifdef USE_LDAP + ,uaLDAP +#endif } UserAuth; typedef struct Port hbaPort; diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index e948cb207a..16d38f71b8 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -204,12 +204,18 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LANGINFO_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LDAP_H + /* Define to 1 if you have the `crypto' library (-lcrypto). */ #undef HAVE_LIBCRYPTO /* Define to 1 if you have the `eay32' library (-leay32). */ #undef HAVE_LIBEAY32 +/* Define to 1 if you have the `ldap' library (-lldap). */ +#undef HAVE_LIBLDAP + /* Define to 1 if you have the `pam' library (-lpam). */ #undef HAVE_LIBPAM @@ -222,6 +228,9 @@ /* Define to 1 if you have the `ssleay32' library (-lssleay32). */ #undef HAVE_LIBSSLEAY32 +/* Define to 1 if you have the `wldap32' library (-lwldap32). */ +#undef HAVE_LIBWLDAP32 + /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ @@ -513,6 +522,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_WCTYPE_H +/* Define to 1 if you have the header file. */ +#undef HAVE_WINLDAP_H + /* Define to the appropriate snprintf format for 64-bit ints, if any. */ #undef INT64_FORMAT @@ -589,6 +601,9 @@ (--enable-integer-datetimes) */ #undef USE_INTEGER_DATETIMES +/* Define to 1 to build with LDAP support. (--with-ldap) */ +#undef USE_LDAP + /* Define to select named POSIX semaphores. */ #undef USE_NAMED_POSIX_SEMAPHORES