summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam A. Rowe Jr <wrowe@apache.org>2011-05-31 19:10:11 +0200
committerWilliam A. Rowe Jr <wrowe@apache.org>2011-05-31 19:10:11 +0200
commit37770675d7c1e829a24101ec2aad65ee94b82b1a (patch)
treeb770e2e00e1230e610d9c3029acebd18d5a9ee57
parentmod_ext_filter: Remove DebugLevel option in favor of per-module loglevel (diff)
downloadapache2-37770675d7c1e829a24101ec2aad65ee94b82b1a.tar.xz
apache2-37770675d7c1e829a24101ec2aad65ee94b82b1a.zip
Incorporate the ap_ldap incomplete API, as there is no interest or effort
at APR to make this a complete abstraction, and it was voted 'off the island' with APR 2.0. This will allow httpd 2.3 to build against either apr-2.0 or apr+util 1.x. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1129808 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--README5
-rw-r--r--build/find_ldap.m4263
-rw-r--r--configure.in1
-rw-r--r--docs/doxygen.conf9
-rw-r--r--include/ap_ldap.h.in193
-rw-r--r--include/ap_ldap.hnw137
-rw-r--r--include/ap_ldap.hw176
-rw-r--r--include/ap_ldap_init.h165
-rw-r--r--include/ap_ldap_option.h254
-rw-r--r--include/ap_ldap_rebind.h98
-rw-r--r--include/ap_ldap_url.h120
-rw-r--r--include/util_ldap.h18
-rw-r--r--modules/aaa/config.m45
-rw-r--r--modules/aaa/mod_authnz_ldap.c22
-rw-r--r--modules/ldap/ap_ldap_init.c195
-rw-r--r--modules/ldap/ap_ldap_option.c667
-rw-r--r--modules/ldap/ap_ldap_rebind.c371
-rw-r--r--modules/ldap/ap_ldap_url.c695
-rw-r--r--modules/ldap/config.m416
-rw-r--r--modules/ldap/util_ldap.c170
-rw-r--r--modules/ldap/util_ldap_cache.c4
-rw-r--r--modules/ldap/util_ldap_cache.h10
-rw-r--r--modules/ldap/util_ldap_cache_mgr.c4
23 files changed, 3459 insertions, 139 deletions
diff --git a/README b/README
index 7f90fb1987..36832b3765 100644
--- a/README
+++ b/README
@@ -76,6 +76,11 @@
OpenSSL or the operating system's platform-specific SSL facilities.
Apache httpd currently does not use that apr-util interface.
+ modules/ldap/ provides an abstract interface for SSL encrypted LDAP
+ (ldaps and STARTTLS style) connections, implemented with OpenLDAP,
+ Netscape LDAP SDK, Mozilla LDAP SDK, or other platform specific ldap
+ interfaces.
+
Some object code distributions of Apache httpd, indicated with the
word "crypto" in the package name, may include object code for the
OpenSSL encryption library as distributed in open source form from
diff --git a/build/find_ldap.m4 b/build/find_ldap.m4
new file mode 100644
index 0000000000..a0e6a066a0
--- /dev/null
+++ b/build/find_ldap.m4
@@ -0,0 +1,263 @@
+dnl -------------------------------------------------------- -*- autoconf -*-
+dnl Licensed to the Apache Software Foundation (ASF) under one or more
+dnl contributor license agreements. See the NOTICE file distributed with
+dnl this work for additional information regarding copyright ownership.
+dnl The ASF licenses this file to You under the Apache License, Version 2.0
+dnl (the "License"); you may not use this file except in compliance with
+dnl the License. You may obtain a copy of the License at
+dnl
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
+
+
+dnl
+dnl Find a particular LDAP library
+dnl
+AC_DEFUN([AP_FIND_LDAPLIB], [
+ if test ${ap_has_ldap} != "1"; then
+ ldaplib=$1
+ extralib=$2
+ # Clear the cache entry for subsequent AP_FIND_LDAPLIB invocations.
+ changequote(,)
+ ldaplib_cache_id="`echo $ldaplib | sed -e 's/[^a-zA-Z0-9_]/_/g'`"
+ changequote([,])
+ unset ac_cv_lib_${ldaplib_cache_id}_ldap_init
+ unset ac_cv_lib_${ldaplib_cache_id}___ldap_init
+ AC_CHECK_LIB(${ldaplib}, ldap_init,
+ [
+ LDADD_ldap="-l${ldaplib} ${extralib}"
+ AC_CHECK_LIB(${ldaplib}, ldapssl_client_init, ap_has_ldapssl_client_init="1", , ${extralib})
+ AC_CHECK_LIB(${ldaplib}, ldapssl_client_deinit, ap_has_ldapssl_client_deinit="1", , ${extralib})
+ AC_CHECK_LIB(${ldaplib}, ldapssl_add_trusted_cert, ap_has_ldapssl_add_trusted_cert="1", , ${extralib})
+ AC_CHECK_LIB(${ldaplib}, ldap_start_tls_s, ap_has_ldap_start_tls_s="1", , ${extralib})
+ AC_CHECK_LIB(${ldaplib}, ldap_sslinit, ap_has_ldap_sslinit="1", , ${extralib})
+ AC_CHECK_LIB(${ldaplib}, ldapssl_init, ap_has_ldapssl_init="1", , ${extralib})
+ AC_CHECK_LIB(${ldaplib}, ldapssl_install_routines, ap_has_ldapssl_install_routines="1", , ${extralib})
+ ap_has_ldap="1";
+ ], , ${extralib})
+ fi
+])
+
+
+dnl
+dnl AP_FIND_LDAP: figure out where LDAP is located
+dnl
+AC_DEFUN([AP_FIND_LDAP], [
+
+echo $ac_n "${nl}checking for ldap support..."
+
+ap_has_ldap="0";
+ap_has_ldapssl_client_init="0"
+ap_has_ldapssl_client_deinit="0"
+ap_has_ldapssl_add_trusted_cert="0"
+ap_has_ldap_start_tls_s="0"
+ap_has_ldapssl_init="0"
+ap_has_ldap_sslinit="0"
+ap_has_ldapssl_install_routines="0"
+ap_has_ldap_openldap="0"
+ap_has_ldap_solaris="0"
+ap_has_ldap_novell="0"
+ap_has_ldap_microsoft="0"
+ap_has_ldap_netscape="0"
+ap_has_ldap_mozilla="0"
+ap_has_ldap_tivoli="0"
+ap_has_ldap_zos="0"
+ap_has_ldap_other="0"
+LDADD_ldap=""
+
+AC_ARG_WITH(lber,[ --with-lber=library lber library to use],
+ [
+ if test "$withval" = "yes"; then
+ ap_liblber_name="lber"
+ else
+ ap_liblber_name="$withval"
+ fi
+ ],
+ [
+ ap_liblber_name="lber"
+ ])
+
+AC_ARG_WITH(ldap-include,[ --with-ldap-include=path path to ldap include files with trailing slash])
+AC_ARG_WITH(ldap-lib,[ --with-ldap-lib=path path to ldap lib file])
+AC_ARG_WITH(ldap,[ --with-ldap=library ldap library to use],
+ [
+ if test "$with_ldap" != "no"; then
+ save_cppflags="$CPPFLAGS"
+ save_ldflags="$LDFLAGS"
+ save_libs="$LIBS"
+ if test -n "$with_ldap_include"; then
+ CPPFLAGS="$CPPFLAGS -I$with_ldap_include"
+ APR_ADDTO(INCLUDES, [-I$with_ldap_include])
+ fi
+ if test -n "$with_ldap_lib"; then
+ APR_ADDTO(LDFLAGS, [-L$with_ldap_lib])
+ fi
+
+ LIBLDAP="$withval"
+ if test "$LIBLDAP" = "yes"; then
+ dnl The iPlanet C SDK 5.0 is as yet untested...
+ AP_FIND_LDAPLIB("ldap50", "-lnspr4 -lplc4 -lplds4 -liutil50 -llber50 -lldif50 -lnss3 -lprldap50 -lssl3 -lssldap50")
+ AP_FIND_LDAPLIB("ldapssl41", "-lnspr3 -lplc3 -lplds3")
+ AP_FIND_LDAPLIB("ldapssl40")
+ AP_FIND_LDAPLIB("ldapssl30")
+ AP_FIND_LDAPLIB("ldapssl20")
+ AP_FIND_LDAPLIB("ldapsdk", "-lldapx -lldapssl -lldapgss -lgssapi_krb5")
+ AP_FIND_LDAPLIB("ldapsdk", "-lldapx -lldapssl -lldapgss -lgss -lresolv -lsocket")
+ AP_FIND_LDAPLIB("ldap", "-llber")
+ AP_FIND_LDAPLIB("ldap", "-llber -lresolv")
+ AP_FIND_LDAPLIB("ldap", "-llber -lresolv -lsocket -lnsl")
+ AP_FIND_LDAPLIB("ldap", "-ldl -lpthread")
+ else
+ AP_FIND_LDAPLIB($LIBLDAP)
+ AP_FIND_LDAPLIB($LIBLDAP, "-lresolv")
+ AP_FIND_LDAPLIB($LIBLDAP, "-lresolv -lsocket -lnsl")
+ AP_FIND_LDAPLIB($LIBLDAP, "-ldl -lpthread")
+ fi
+
+ test ${ap_has_ldap} != "1" && AC_MSG_ERROR(could not find an LDAP library)
+ AC_CHECK_LIB($ap_liblber_name, ber_init,
+ [LDADD_ldap="${LDADD_ldap} -l${ap_liblber_name}"])
+
+ AC_CHECK_HEADERS(lber.h, lber_h=["#include <lber.h>"])
+
+ # Solaris has a problem in <ldap.h> which prevents it from
+ # being included by itself. Check for <ldap.h> manually,
+ # including lber.h first.
+ AC_CACHE_CHECK([for ldap.h], [ap_cv_hdr_ldap_h],
+ [AC_TRY_CPP(
+ [#ifdef HAVE_LBER_H
+ #include <lber.h>
+ #endif
+ #include <ldap.h>
+ ], [ap_cv_hdr_ldap_h=yes], [ap_cv_hdr_ldap_h=no])])
+ if test "$ap_cv_hdr_ldap_h" = "yes"; then
+ ldap_h=["#include <ldap.h>"]
+ AC_DEFINE([HAVE_LDAP_H], 1, [Defined if ldap.h is present])
+ fi
+
+ AC_CHECK_HEADERS(ldap_ssl.h, ldap_ssl_h=["#include <ldap_ssl.h>"])
+
+ if test "$ap_cv_hdr_ldap_h" = "yes"; then
+ AC_CACHE_CHECK([for LDAP toolkit],
+ [ap_cv_ldap_toolkit], [
+ if test "x$ap_cv_ldap_toolkit" = "x"; then
+ AC_EGREP_CPP([OpenLDAP], [$lber_h
+ $ldap_h
+ LDAP_VENDOR_NAME], [ap_has_ldap_openldap="1"
+ ap_cv_ldap_toolkit="OpenLDAP"])
+ fi
+ if test "x$ap_cv_ldap_toolkit" = "x"; then
+ AC_EGREP_CPP([Sun Microsystems Inc.], [$lber_h
+ $ldap_h
+ LDAP_VENDOR_NAME], [ap_has_ldap_solaris="1"
+ ap_cv_ldap_toolkit="Solaris"])
+ fi
+ if test "x$ap_cv_ldap_toolkit" = "x"; then
+ AC_EGREP_CPP([Novell], [$lber_h
+ $ldap_h
+ LDAP_VENDOR_NAME], [ap_has_ldap_novell="1"
+ ap_cv_ldap_toolkit="Novell"])
+ fi
+ if test "x$ap_cv_ldap_toolkit" = "x"; then
+ AC_EGREP_CPP([Microsoft Corporation.], [$lber_h
+ $ldap_h
+ LDAP_VENDOR_NAME], [ap_has_ldap_microsoft="1"
+ ap_cv_ldap_toolkit="Microsoft"])
+ fi
+ if test "x$ap_cv_ldap_toolkit" = "x"; then
+ AC_EGREP_CPP([Netscape Communications Corp.], [$lber_h
+ $ldap_h
+ LDAP_VENDOR_NAME], [ap_has_ldap_netscape="1"
+ ap_cv_ldap_toolkit="Netscape"])
+ fi
+ if test "x$ap_cv_ldap_toolkit" = "x"; then
+ AC_EGREP_CPP([mozilla.org], [$lber_h
+ $ldap_h
+ LDAP_VENDOR_NAME], [ap_has_ldap_mozilla="1"
+ ap_cv_ldap_toolkit="Mozilla"])
+ fi
+ if test "x$ap_cv_ldap_toolkit" = "x"; then
+ AC_EGREP_CPP([International Business Machines], [$lber_h
+ $ldap_h
+ LDAP_VENDOR_NAME], [ap_has_ldap_tivoli="1"
+ ap_cv_ldap_toolkit="Tivoli"])
+ fi
+ if test "x$ap_cv_ldap_toolkit" = "x"; then
+ case "$host" in
+ *-ibm-os390)
+ AC_EGREP_CPP([IBM], [$lber_h
+ $ldap_h], [ap_has_ldap_zos="1"
+ ap_cv_ldap_toolkit="z/OS"])
+ ;;
+ esac
+ fi
+ if test "x$ap_cv_ldap_toolkit" = "x"; then
+ ap_has_ldap_other="1"
+ ap_cv_ldap_toolkit="unknown"
+ fi
+ ])
+ fi
+
+ CPPFLAGS=$save_cppflags
+ LDFLAGS=$save_ldflags
+ LIBS=$save_libs
+ fi
+ ])
+
+if test "$ap_has_ldap_openldap" = "1"; then
+ save_cppflags="$CPPFLAGS"
+ save_ldflags="$LDFLAGS"
+ save_libs="$LIBS"
+
+ CPPFLAGS="$CPPFLAGS $INCLUDES"
+ AC_CACHE_CHECK([style of ldap_set_rebind_proc routine], ac_cv_ldap_set_rebind_proc_style,
+ APR_TRY_COMPILE_NO_WARNING([
+ #ifdef HAVE_LBER_H
+ #include <lber.h>
+ #endif
+ #ifdef HAVE_LDAP_H
+ #include <ldap.h>
+ #endif
+ ], [
+ int tmp = ldap_set_rebind_proc((LDAP *)0, (LDAP_REBIND_PROC *)0, (void *)0);
+ /* use tmp to suppress the warning */
+ tmp=0;
+ ], ac_cv_ldap_set_rebind_proc_style=three, ac_cv_ldap_set_rebind_proc_style=two))
+
+ if test "$ac_cv_ldap_set_rebind_proc_style" = "three"; then
+ AC_DEFINE(LDAP_SET_REBIND_PROC_THREE, 1, [Define if ldap_set_rebind_proc takes three arguments])
+ fi
+
+ CPPFLAGS="$save_cppflags"
+ LDFLAGS="$save_ldflags"
+ LIBS="$save_libs"
+fi
+
+AC_SUBST(ldap_h)
+AC_SUBST(lber_h)
+AC_SUBST(ldap_ssl_h)
+AC_SUBST(ap_has_ldapssl_client_init)
+AC_SUBST(ap_has_ldapssl_client_deinit)
+AC_SUBST(ap_has_ldapssl_add_trusted_cert)
+AC_SUBST(ap_has_ldap_start_tls_s)
+AC_SUBST(ap_has_ldapssl_init)
+AC_SUBST(ap_has_ldap_sslinit)
+AC_SUBST(ap_has_ldapssl_install_routines)
+AC_SUBST(ap_has_ldap)
+AC_SUBST(ap_has_ldap_openldap)
+AC_SUBST(ap_has_ldap_solaris)
+AC_SUBST(ap_has_ldap_novell)
+AC_SUBST(ap_has_ldap_microsoft)
+AC_SUBST(ap_has_ldap_netscape)
+AC_SUBST(ap_has_ldap_mozilla)
+AC_SUBST(ap_has_ldap_tivoli)
+AC_SUBST(ap_has_ldap_zos)
+AC_SUBST(ap_has_ldap_other)
+AC_SUBST(LDADD_ldap)
+AC_CONFIG_FILES(include/ap_ldap.h)
+])
diff --git a/configure.in b/configure.in
index 03fb8a927d..0d9a19150a 100644
--- a/configure.in
+++ b/configure.in
@@ -16,6 +16,7 @@ dnl #
sinclude(build/apr_common.m4)
sinclude(build/find_apr.m4)
sinclude(build/find_apu.m4)
+sinclude(build/find_ldap.m4)
sinclude(acinclude.m4)
dnl Later versions of autoconf (>= 2.62) by default cause the produced
diff --git a/docs/doxygen.conf b/docs/doxygen.conf
index 95e11bc2ae..751f2e2bc9 100644
--- a/docs/doxygen.conf
+++ b/docs/doxygen.conf
@@ -51,12 +51,13 @@ PREDEFINED="APR_DECLARE(x)=x" \
APR_HAS_USER \
APR_HAS_LARGE_FILES \
APR_HAS_XTHREAD_FILES \
- DOXYGEN= \
- APU_DECLARE_DATA= \
- __pre_nw__= \
+ DOXYGEN \
+ APU_DECLARE_DATA \
+ __pre_nw__ \
"APU_DECLARE(x)=x" \
"CACHE_DECLARE(x)=x" \
- "PROXY_DECLARE(x)=x"
+ "PROXY_DECLARE(x)=x" \
+ "MODLDAP_DECLARE(x)=x"
OPTIMIZE_OUTPUT_FOR_C=YES
diff --git a/include/ap_ldap.h.in b/include/ap_ldap.h.in
new file mode 100644
index 0000000000..e6d69af644
--- /dev/null
+++ b/include/ap_ldap.h.in
@@ -0,0 +1,193 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * ap_ldap.h is generated from ap_ldap.h.in by configure -- do not edit ap_ldap.h
+ */
+/**
+ * @file ap_ldap.h
+ * @brief MODLDAP
+ */
+#ifndef AP_LDAP_H
+#define AP_LDAP_H
+
+/**
+ * @defgroup AP_Util_LDAP LDAP
+ * @ingroup APR_Util
+ * @{
+ */
+
+#if !defined(WIN32)
+#define MODLDAP_DECLARE(type) type
+#define MODLDAP_DECLARE_NONSTD(type) type
+#define MODLDAP_DECLARE_DATA
+#elif defined(MODLDAP_DECLARE_STATIC)
+#define MODLDAP_DECLARE(type) type __stdcall
+#define MODLDAP_DECLARE_NONSTD(type) type
+#define MODLDAP_DECLARE_DATA
+#elif defined(MODLDAP_DECLARE_EXPORT)
+#define MODLDAP_DECLARE(type) __declspec(dllexport) type __stdcall
+#define MODLDAP_DECLARE_NONSTD(type) __declspec(dllexport) type
+#define MODLDAP_DECLARE_DATA __declspec(dllexport)
+#else
+#define MODLDAP_DECLARE(type) __declspec(dllimport) type __stdcall
+#define MODLDAP_DECLARE_NONSTD(type) __declspec(dllimport) type
+#define MODLDAP_DECLARE_DATA __declspec(dllimport)
+#endif
+/* this will be defined if LDAP support was compiled into apr-util */
+#define AP_HAS_LDAP @ap_has_ldap@
+
+/* identify the LDAP toolkit used */
+#define AP_HAS_NETSCAPE_LDAPSDK @ap_has_ldap_netscape@
+#define AP_HAS_SOLARIS_LDAPSDK @ap_has_ldap_solaris@
+#define AP_HAS_NOVELL_LDAPSDK @ap_has_ldap_novell@
+#define AP_HAS_MOZILLA_LDAPSDK @ap_has_ldap_mozilla@
+#define AP_HAS_OPENLDAP_LDAPSDK @ap_has_ldap_openldap@
+#define AP_HAS_MICROSOFT_LDAPSDK @ap_has_ldap_microsoft@
+#define AP_HAS_TIVOLI_LDAPSDK @ap_has_ldap_tivoli@
+#define AP_HAS_ZOS_LDAPSDK @ap_has_ldap_zos@
+#define AP_HAS_OTHER_LDAPSDK @ap_has_ldap_other@
+
+
+/*
+ * Handle the case when LDAP is enabled
+ */
+#if AP_HAS_LDAP
+
+/*
+ * The following #defines are DEPRECATED and should not be used for
+ * anything. They remain to maintain binary compatibility.
+ * The original code defined the OPENLDAP SDK as present regardless
+ * of what really was there, which was way bogus. In addition, the
+ * ap_ldap_url_parse*() functions have been rewritten specifically for
+ * APR, so the AP_HAS_LDAP_URL_PARSE macro is forced to zero.
+ */
+#if AP_HAS_TIVOLI_LDAPSDK
+#define AP_HAS_LDAP_SSL 0
+#else
+#define AP_HAS_LDAP_SSL 1
+#endif
+#define AP_HAS_LDAP_URL_PARSE 0
+
+#if AP_HAS_OPENLDAP_LDAPSDK && !defined(LDAP_DEPRECATED)
+/* Ensure that the "deprecated" interfaces are still exposed
+ * with OpenLDAP >= 2.3; these were exposed by default in earlier
+ * releases. */
+#define LDAP_DEPRECATED 1
+#endif
+
+/*
+ * Include the standard LDAP header files.
+ */
+
+@lber_h@
+@ldap_h@
+@ldap_ssl_h@
+
+
+/*
+ * Detected standard functions
+ */
+#define AP_HAS_LDAPSSL_CLIENT_INIT @ap_has_ldapssl_client_init@
+#define AP_HAS_LDAPSSL_CLIENT_DEINIT @ap_has_ldapssl_client_deinit@
+#define AP_HAS_LDAPSSL_ADD_TRUSTED_CERT @ap_has_ldapssl_add_trusted_cert@
+#define AP_HAS_LDAP_START_TLS_S @ap_has_ldap_start_tls_s@
+#define AP_HAS_LDAP_SSLINIT @ap_has_ldap_sslinit@
+#define AP_HAS_LDAPSSL_INIT @ap_has_ldapssl_init@
+#define AP_HAS_LDAPSSL_INSTALL_ROUTINES @ap_has_ldapssl_install_routines@
+
+/*
+ * Make sure the secure LDAP port is defined
+ */
+#ifndef LDAPS_PORT
+#define LDAPS_PORT 636 /* ldaps:/// default LDAP over TLS port */
+#endif
+
+/*
+ * For ldap function calls that input a size limit on the number of returned elements
+ * Some SDKs do not have the define for LDAP_DEFAULT_LIMIT (-1) or LDAP_NO_LIMIT (0)
+ * LDAP_DEFAULT_LIMIT is preferred as it allows inheritance from whatever the SDK
+ * or process is configured for.
+ */
+#ifdef LDAP_DEFAULT_LIMIT
+#define AP_LDAP_SIZELIMIT LDAP_DEFAULT_LIMIT
+#else
+#ifdef LDAP_NO_LIMIT
+#define AP_LDAP_SIZELIMIT LDAP_NO_LIMIT
+#endif
+#endif
+
+#ifndef AP_LDAP_SIZELIMIT
+#define AP_LDAP_SIZELIMIT 0 /* equivalent to LDAP_NO_LIMIT, and what goes on the wire */
+#endif
+
+/*
+ * z/OS is missing some defines
+ */
+#ifndef LDAP_VERSION_MAX
+#define LDAP_VERSION_MAX LDAP_VERSION
+#endif
+#if AP_HAS_ZOS_LDAPSDK
+#define LDAP_VENDOR_NAME "IBM z/OS"
+#endif
+
+/* Note: Macros defining const casting has been removed in APR v1.0,
+ * pending real support for LDAP v2.0 toolkits.
+ *
+ * In the mean time, please use an LDAP v3.0 toolkit.
+ */
+#if LDAP_VERSION_MAX <= 2
+#error Support for LDAP v2.0 toolkits has been removed from apr-util. Please use an LDAP v3.0 toolkit.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * This structure allows the C LDAP API error codes to be returned
+ * along with plain text error messages that explain to us mere mortals
+ * what really happened.
+ */
+typedef struct ap_ldap_err_t {
+ const char *reason;
+ const char *msg;
+ int rc;
+} ap_ldap_err_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+/* The MS SDK returns LDAP_UNAVAILABLE when the backend has closed the connection
+ * between LDAP calls. Protect with AP_HAS_MICROSOFT_LDAPSDK in case someone
+ * manually chooses another SDK on Windows
+ */
+#if AP_HAS_MICROSOFT_LDAPSDK
+#define AP_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN \
+ || (s) == LDAP_UNAVAILABLE)
+#else
+#define AP_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN)
+#endif
+
+#include "ap_ldap_url.h"
+#include "ap_ldap_init.h"
+#include "ap_ldap_option.h"
+#include "ap_ldap_rebind.h"
+
+#endif /* AP_HAS_LDAP */
+/** @} */
+#endif /* AP_LDAP_H */
diff --git a/include/ap_ldap.hnw b/include/ap_ldap.hnw
new file mode 100644
index 0000000000..52aac34b45
--- /dev/null
+++ b/include/ap_ldap.hnw
@@ -0,0 +1,137 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * ap_ldap.h is generated from ap_ldap.h.in by configure -- do not edit ap_ldap.h
+ */
+/**
+ * @file ap_ldap.h
+ * @brief MODLDAP
+ */
+#ifndef AP_LDAP_H
+#define AP_LDAP_H
+
+/**
+ * @defgroup AP_Util_LDAP LDAP
+ * @ingroup AP_Util
+ * @{
+ */
+
+/* this will be defined if LDAP support was compiled into apr-util */
+#define AP_HAS_LDAP 1
+
+/* identify the LDAP toolkit used */
+#define AP_HAS_NETSCAPE_LDAPSDK 0
+#define AP_HAS_SOLARIS_LDAPSDK 0
+#define AP_HAS_NOVELL_LDAPSDK 1
+#define AP_HAS_MOZILLA_LDAPSDK 0
+#define AP_HAS_OPENLDAP_LDAPSDK 0
+#define AP_HAS_MICROSOFT_LDAPSDK 0
+#define AP_HAS_OTHER_LDAPSDK 0
+
+
+/*
+ * Handle the case when LDAP is enabled
+ */
+#if AP_HAS_LDAP
+
+/*
+ * The following #defines are DEPRECATED and should not be used for
+ * anything. They remain to maintain binary compatibility.
+ * The original code defined the OPENLDAP SDK as present regardless
+ * of what really was there, which was way bogus. In addition, the
+ * ap_ldap_url_parse*() functions have been rewritten specifically for
+ * APR, so the AP_HAS_LDAP_URL_PARSE macro is forced to zero.
+ */
+#define AP_HAS_LDAP_SSL 1
+#define AP_HAS_LDAP_URL_PARSE 0
+
+
+/*
+ * Include the standard LDAP header files.
+ */
+
+#ifdef GENEXPORTS
+#define LDAP_VERSION_MAX 3
+#define LDAP_INSUFFICIENT_ACCESS
+#else
+#include <lber.h>
+#include <ldap.h>
+#if AP_HAS_LDAP_SSL
+#include <ldap_ssl.h>
+#endif
+#endif
+
+
+/*
+ * Detected standard functions
+ */
+#define AP_HAS_LDAPSSL_CLIENT_INIT 1
+#define AP_HAS_LDAPSSL_CLIENT_DEINIT 1
+#define AP_HAS_LDAPSSL_ADD_TRUSTED_CERT 1
+#define AP_HAS_LDAP_START_TLS_S 0
+#define AP_HAS_LDAP_SSLINIT 0
+#define AP_HAS_LDAPSSL_INIT 1
+#define AP_HAS_LDAPSSL_INSTALL_ROUTINES 0
+
+
+/*
+ * Make sure the secure LDAP port is defined
+ */
+#ifndef LDAPS_PORT
+#define LDAPS_PORT 636 /* ldaps:/// default LDAP over TLS port */
+#endif
+
+
+/* Note: Macros defining const casting has been removed in APR v1.0,
+ * pending real support for LDAP v2.0 toolkits.
+ *
+ * In the mean time, please use an LDAP v3.0 toolkit.
+ */
+#if LDAP_VERSION_MAX <= 2
+#error Support for LDAP v2.0 toolkits has been removed from apr-util. Please use an LDAP v3.0 toolkit.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * This structure allows the C LDAP API error codes to be returned
+ * along with plain text error messages that explain to us mere mortals
+ * what really happened.
+ */
+typedef struct ap_ldap_err_t {
+ const char *reason;
+ const char *msg;
+ int rc;
+} ap_ldap_err_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#define AP_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN)
+
+#include "ap_ldap_url.h"
+#include "ap_ldap_init.h"
+#include "ap_ldap_option.h"
+#include "ap_ldap_rebind.h"
+
+/** @} */
+#endif /* AP_HAS_LDAP */
+#endif /* AP_LDAP_H */
+
diff --git a/include/ap_ldap.hw b/include/ap_ldap.hw
new file mode 100644
index 0000000000..097ba472a7
--- /dev/null
+++ b/include/ap_ldap.hw
@@ -0,0 +1,176 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * ap_ldap.h is generated from ap_ldap.h.in by configure -- do not edit ap_ldap.h
+ */
+/**
+ * @file ap_ldap.h
+ * @brief AP-UTIL LDAP
+ */
+#ifndef AP_LDAP_H
+#define AP_LDAP_H
+
+/**
+ * @defgroup AP_Util_LDAP LDAP
+ * @ingroup AP_Util
+ * @{
+ */
+
+/* this will be defined if LDAP support was compiled into apr-util */
+#define AP_HAS_LDAP 0
+
+/* identify the LDAP toolkit used */
+#define AP_HAS_NETSCAPE_LDAPSDK 0
+#define AP_HAS_SOLARIS_LDAPSDK 0
+#define AP_HAS_NOVELL_LDAPSDK 0
+#define AP_HAS_MOZILLA_LDAPSDK 0
+#define AP_HAS_OPENLDAP_LDAPSDK 0
+#define AP_HAS_MICROSOFT_LDAPSDK 1
+#define AP_HAS_TIVOLI_LDAPSDK 0
+#define AP_HAS_ZOS_LDAPSDK 0
+#define AP_HAS_OTHER_LDAPSDK 0
+
+
+/*
+ * Handle the case when LDAP is enabled
+ */
+#if AP_HAS_LDAP
+
+/*
+ * The following #defines are DEPRECATED and should not be used for
+ * anything. They remain to maintain binary compatibility.
+ * The original code defined the OPENLDAP SDK as present regardless
+ * of what really was there, which was way bogus. In addition, the
+ * ap_ldap_url_parse*() functions have been rewritten specifically for
+ * APR, so the AP_HAS_LDAP_URL_PARSE macro is forced to zero.
+ */
+#if AP_HAS_TIVOLI_LDAPSDK
+#define AP_HAS_LDAP_SSL 0
+#else
+#define AP_HAS_LDAP_SSL 1
+#endif
+#define AP_HAS_LDAP_URL_PARSE 0
+
+#if AP_HAS_OPENLDAP_LDAPSDK && !defined(LDAP_DEPRECATED)
+/* Ensure that the "deprecated" interfaces are still exposed
+ * with OpenLDAP >= 2.3; these were exposed by default in earlier
+ * releases. */
+#define LDAP_DEPRECATED 1
+#endif
+
+/*
+ * Include the standard LDAP header files.
+ */
+
+#include <winldap.h>
+
+
+/*
+ * Detected standard functions
+ */
+#define AP_HAS_LDAPSSL_CLIENT_INIT 0
+#define AP_HAS_LDAPSSL_CLIENT_DEINIT 0
+#define AP_HAS_LDAPSSL_ADD_TRUSTED_CERT 0
+#define AP_HAS_LDAP_START_TLS_S 0
+#define AP_HAS_LDAP_SSLINIT 1
+#define AP_HAS_LDAPSSL_INIT 0
+#define AP_HAS_LDAPSSL_INSTALL_ROUTINES 0
+
+
+/*
+ * Make sure the secure LDAP port is defined
+ */
+#ifndef LDAPS_PORT
+#define LDAPS_PORT 636 /* ldaps:/// default LDAP over TLS port */
+#endif
+
+
+/*
+ * For ldap function calls that input a size limit on the number of returned elements
+ * Some SDKs do not have the define for LDAP_DEFAULT_LIMIT (-1) or LDAP_NO_LIMIT (0)
+ * LDAP_DEFAULT_LIMIT is preferred as it allows inheritance from whatever the SDK
+ * or process is configured for.
+ */
+#ifdef LDAP_DEFAULT_LIMIT
+#define AP_LDAP_SIZELIMIT LDAP_DEFAULT_LIMIT
+#else
+#ifdef LDAP_NO_LIMIT
+#define AP_LDAP_SIZELIMIT LDAP_NO_LIMIT
+#endif
+#endif
+
+#ifndef AP_LDAP_SIZELIMIT
+#define AP_LDAP_SIZELIMIT 0 /* equivalent to LDAP_NO_LIMIT, and what goes on the wire */
+#endif
+
+/*
+ * z/OS is missing some defines
+ */
+#ifndef LDAP_VERSION_MAX
+#define LDAP_VERSION_MAX LDAP_VERSION
+#endif
+#if AP_HAS_ZOS_LDAPSDK
+#define LDAP_VENDOR_NAME "IBM z/OS"
+#endif
+
+/* Note: Macros defining const casting has been removed in APR v1.0,
+ * pending real support for LDAP v2.0 toolkits.
+ *
+ * In the mean time, please use an LDAP v3.0 toolkit.
+ */
+#if LDAP_VERSION_MAX <= 2
+#error Support for LDAP v2.0 toolkits has been removed from apr-util. Please use an LDAP v3.0 toolkit.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * This structure allows the C LDAP API error codes to be returned
+ * along with plain text error messages that explain to us mere mortals
+ * what really happened.
+ */
+typedef struct ap_ldap_err_t {
+ const char *reason;
+ const char *msg;
+ int rc;
+} ap_ldap_err_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+/* The MS SDK returns LDAP_UNAVAILABLE when the backend has closed the connection
+ * between LDAP calls. Protect with AP_HAS_MICROSOFT_LDAPSDK in case someone
+ * manually chooses another SDK on Windows
+ */
+#if AP_HAS_MICROSOFT_LDAPSDK
+#define AP_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN \
+ || (s) == LDAP_UNAVAILABLE)
+#else
+#define AP_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN)
+#endif
+
+#include "ap_ldap_url.h"
+#include "ap_ldap_init.h"
+#include "ap_ldap_option.h"
+#include "ap_ldap_rebind.h"
+
+/** @} */
+#endif /* AP_HAS_LDAP */
+#endif /* AP_LDAP_H */
diff --git a/include/ap_ldap_init.h b/include/ap_ldap_init.h
new file mode 100644
index 0000000000..799eedd977
--- /dev/null
+++ b/include/ap_ldap_init.h
@@ -0,0 +1,165 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_ldap_init.h
+ * @brief AP-UTIL LDAP ldap_init() functions
+ */
+#ifndef AP_LDAP_INIT_H
+#define AP_LDAP_INIT_H
+
+/**
+ * @addtogroup AP_Util_LDAP
+ * @{
+ */
+
+#include "ap_ldap.h"
+
+#if AP_HAS_LDAP
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/**
+ * Macro to detect security related return values.
+ */
+#if defined(LDAP_INSUFFICIENT_ACCESS)
+#define AP_LDAP_INSUFFICIENT_ACCESS LDAP_INSUFFICIENT_ACCESS
+#elif defined(LDAP_INSUFFICIENT_RIGHTS)
+#define AP_LDAP_INSUFFICIENT_ACCESS LDAP_INSUFFICIENT_RIGHTS
+#elif defined(AP_HAS_MICROSOFT_LDAPSDK)
+/* The macros above fail to contemplate that LDAP_RETCODE values
+ * may be represented by an enum. autoconf tests would be much
+ * more robust.
+ */
+#define AP_LDAP_INSUFFICIENT_ACCESS LDAP_INSUFFICIENT_RIGHTS
+#else
+#error The security return codes must be added to support this LDAP toolkit.
+#endif
+
+#if defined(LDAP_SECURITY_ERROR)
+#define AP_LDAP_SECURITY_ERROR LDAP_SECURITY_ERROR
+#else
+#define AP_LDAP_SECURITY_ERROR(n) \
+ (LDAP_INAPPROPRIATE_AUTH == n) ? 1 \
+ : (LDAP_INVALID_CREDENTIALS == n) ? 1 \
+ : (AP_LDAP_INSUFFICIENT_ACCESS == n) ? 1 \
+ : 0
+#endif
+
+
+/**
+ * MODLDAP SSL Initialise function
+ *
+ * This function initialises SSL on the underlying LDAP toolkit
+ * if this is necessary.
+ *
+ * @bug ??? If a CA certificate is provided, this is set, however the setting
+ * of certificates via this method has been deprecated and will be removed in
+ * APR v2.0 ???
+ *
+ * The ap_ldap_set_option() function with the AP_LDAP_OPT_TLS_CERT option
+ * should be used instead to set certificates.
+ *
+ * If SSL support is not available on this platform, or a problem
+ * was encountered while trying to set the certificate, the function
+ * will return APR_EGENERAL. Further LDAP specific error information
+ * can be found in result_err.
+ * @param pool The pool to use
+ * @param cert_auth_file The name of the certificate to use, can be NULL
+ * @param cert_file_type The type of certificate specified. See the
+ * ap_ldap_set_option() AP_LDAP_OPT_TLS_CERT option for details.
+ * @param result_err The returned result
+ */
+MODLDAP_DECLARE(int) ap_ldap_ssl_init(apr_pool_t *pool,
+ const char *cert_auth_file,
+ int cert_file_type,
+ ap_ldap_err_t **result_err);
+
+/**
+ * MODLDAP SSL De-Initialise function
+ *
+ * This function tears down any SSL certificate setup previously
+ * set using ap_ldap_ssl_init(). It should be called to clean
+ * up if a graceful restart of a service is attempted.
+ * @todo currently we do not check whether ap_ldap_ssl_init()
+ * has been called first - we probably should.
+ */
+MODLDAP_DECLARE(int) ap_ldap_ssl_deinit(void);
+
+/**
+ * MODLDAP initialise function
+ *
+ * This function is responsible for initialising an LDAP
+ * connection in a toolkit independant way. It does the
+ * job of ldap_init() from the C api.
+ *
+ * It handles both the SSL and non-SSL case, and attempts
+ * to hide the complexity setup from the user. This function
+ * assumes that any certificate setup necessary has already
+ * been done.
+ *
+ * If SSL or STARTTLS needs to be enabled, and the underlying
+ * toolkit supports it, the following values are accepted for
+ * secure:
+ *
+ * AP_LDAP_NONE: No encryption
+ * AP_LDAP_SSL: SSL encryption (ldaps://)
+ * AP_LDAP_STARTTLS: Force STARTTLS on ldap://
+ * @remark The Novell toolkit is only able to set the SSL mode via this
+ * function. To work around this limitation, set the SSL mode here if no
+ * per connection client certificates are present, otherwise set secure
+ * AP_LDAP_NONE here, then set the per connection client certificates,
+ * followed by setting the SSL mode via ap_ldap_set_option(). As Novell
+ * does not support per connection client certificates, this problem is
+ * worked around while still being compatible with other LDAP toolkits.
+ * @param pool The pool to use
+ * @param ldap The LDAP handle
+ * @param hostname The name of the host to connect to. This can be either a
+ * DNS name, or an IP address.
+ * @param portno The port to connect to
+ * @param secure The security mode to set
+ * @param result_err The returned result
+ */
+MODLDAP_DECLARE(int) ap_ldap_init(apr_pool_t *pool,
+ LDAP **ldap,
+ const char *hostname,
+ int portno,
+ int secure,
+ ap_ldap_err_t **result_err);
+
+/**
+ * MODLDAP info function
+ *
+ * This function returns a string describing the LDAP toolkit
+ * currently in use. The string is placed inside result_err->reason.
+ * @param pool The pool to use
+ * @param result_err The returned result
+ */
+MODLDAP_DECLARE(int) ap_ldap_info(apr_pool_t *pool,
+ ap_ldap_err_t **result_err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AP_HAS_LDAP */
+
+/** @} */
+
+#endif /* AP_LDAP_URL_H */
diff --git a/include/ap_ldap_option.h b/include/ap_ldap_option.h
new file mode 100644
index 0000000000..ba6d995892
--- /dev/null
+++ b/include/ap_ldap_option.h
@@ -0,0 +1,254 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_ldap_option.h
+ * @brief MODLDAP ldap_*_option() functions
+ */
+#ifndef AP_LDAP_OPTION_H
+#define AP_LDAP_OPTION_H
+
+/**
+ * @addtogroup AP_Util_LDAP
+ * @{
+ */
+
+#include "ap_ldap.h"
+
+#if AP_HAS_LDAP
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * The following defines handle the different TLS certificate
+ * options available. If these options are missing, this API
+ * emulate support for this using the deprecated ldap_start_tls_s()
+ * function.
+ */
+/**
+ * Set SSL mode to one of AP_LDAP_NONE, AP_LDAP_SSL, AP_LDAP_STARTTLS
+ * or AP_LDAP_STOPTLS.
+ */
+#define AP_LDAP_OPT_TLS 0x6fff
+/**
+ * Set zero or more CA certificates, client certificates or private
+ * keys globally, or per connection (where supported).
+ */
+#define AP_LDAP_OPT_TLS_CERT 0x6ffe
+/**
+ * Set the LDAP library to no verify the server certificate. This means
+ * all servers are considered trusted.
+ */
+#define AP_LDAP_OPT_VERIFY_CERT 0x6ffd
+/**
+ * Set the LDAP library to indicate if referrals should be chased during
+ * LDAP searches.
+ */
+#define AP_LDAP_OPT_REFERRALS 0x6ffc
+/**
+ * Set the LDAP library to indicate a maximum number of referral hops to
+ * chase before giving up on the search.
+ */
+#define AP_LDAP_OPT_REFHOPLIMIT 0x6ffb
+
+/**
+ * Structures for the apr_set_option() cases
+ */
+
+/**
+ * AP_LDAP_OPT_TLS_CERT
+ *
+ * This structure includes possible options to set certificates on
+ * system initialisation. Different SDKs have different certificate
+ * requirements, and to achieve this multiple certificates must be
+ * specified at once passed as an (apr_array_header_t *).
+ *
+ * Netscape:
+ * Needs the CA cert database (cert7.db), the client cert database (key3.db)
+ * and the security module file (secmod.db) set at the system initialisation
+ * time. Three types are supported: AP_LDAP_CERT7_DB, AP_LDAP_KEY3_DB and
+ * AP_LDAP_SECMOD.
+ *
+ * To specify a client cert connection, a certificate nickname needs to be
+ * provided with a type of AP_LDAP_CERT.
+ * int ldapssl_enable_clientauth( LDAP *ld, char *keynickname,
+ * char *keypasswd, char *certnickname );
+ * keynickname is currently not used, and should be set to ""
+ *
+ * Novell:
+ * Needs CA certificates and client certificates set at system initialisation
+ * time. Three types are supported: AP_LDAP_CA*, AP_LDAP_CERT* and
+ * AP_LDAP_KEY*.
+ *
+ * Certificates cannot be specified per connection.
+ *
+ * The functions used are:
+ * ldapssl_add_trusted_cert(serverTrustedRoot, serverTrustedRootEncoding);
+ * Clients certs and keys are set at system initialisation time with
+ * int ldapssl_set_client_cert (
+ * void *cert,
+ * int type
+ * void *password);
+ * type can be LDAPSSL_CERT_FILETYPE_B64 or LDAPSSL_CERT_FILETYPE_DER
+ * ldapssl_set_client_private_key(clientPrivateKey,
+ * clientPrivateKeyEncoding,
+ * clientPrivateKeyPassword);
+ *
+ * OpenSSL:
+ * Needs one or more CA certificates to be set at system initialisation time
+ * with a type of AP_LDAP_CA*.
+ *
+ * May have one or more client certificates set per connection with a type of
+ * AP_LDAP_CERT*, and keys with AP_LDAP_KEY*.
+ */
+/** CA certificate type unknown */
+#define AP_LDAP_CA_TYPE_UNKNOWN 0
+/** binary DER encoded CA certificate */
+#define AP_LDAP_CA_TYPE_DER 1
+/** PEM encoded CA certificate */
+#define AP_LDAP_CA_TYPE_BASE64 2
+/** Netscape/Mozilla cert7.db CA certificate database */
+#define AP_LDAP_CA_TYPE_CERT7_DB 3
+/** Netscape/Mozilla secmod file */
+#define AP_LDAP_CA_TYPE_SECMOD 4
+/** Client certificate type unknown */
+#define AP_LDAP_CERT_TYPE_UNKNOWN 5
+/** binary DER encoded client certificate */
+#define AP_LDAP_CERT_TYPE_DER 6
+/** PEM encoded client certificate */
+#define AP_LDAP_CERT_TYPE_BASE64 7
+/** Netscape/Mozilla key3.db client certificate database */
+#define AP_LDAP_CERT_TYPE_KEY3_DB 8
+/** Netscape/Mozilla client certificate nickname */
+#define AP_LDAP_CERT_TYPE_NICKNAME 9
+/** Private key type unknown */
+#define AP_LDAP_KEY_TYPE_UNKNOWN 10
+/** binary DER encoded private key */
+#define AP_LDAP_KEY_TYPE_DER 11
+/** PEM encoded private key */
+#define AP_LDAP_KEY_TYPE_BASE64 12
+/** PKCS#12 encoded client certificate */
+#define AP_LDAP_CERT_TYPE_PFX 13
+/** PKCS#12 encoded private key */
+#define AP_LDAP_KEY_TYPE_PFX 14
+/** Openldap directory full of base64-encoded cert
+ * authorities with hashes in corresponding .0 directory
+ */
+#define AP_LDAP_CA_TYPE_CACERTDIR_BASE64 15
+
+
+/**
+ * Certificate structure.
+ *
+ * This structure is used to store certificate details. An array of
+ * these structures is passed to ap_ldap_set_option() to set CA
+ * and client certificates.
+ * @param type Type of certificate AP_LDAP_*_TYPE_*
+ * @param path Path, file or nickname of the certificate
+ * @param password Optional password, can be NULL
+ */
+typedef struct ap_ldap_opt_tls_cert_t ap_ldap_opt_tls_cert_t;
+struct ap_ldap_opt_tls_cert_t {
+ int type;
+ const char *path;
+ const char *password;
+};
+
+/**
+ * AP_LDAP_OPT_TLS
+ *
+ * This sets the SSL level on the LDAP handle.
+ *
+ * Netscape/Mozilla:
+ * Supports SSL, but not STARTTLS
+ * SSL is enabled by calling ldapssl_install_routines().
+ *
+ * Novell:
+ * Supports SSL and STARTTLS.
+ * SSL is enabled by calling ldapssl_install_routines(). Note that calling
+ * other ldap functions before ldapssl_install_routines() may cause this
+ * function to fail.
+ * STARTTLS is enabled by calling ldapssl_start_tls_s() after calling
+ * ldapssl_install_routines() (check this).
+ *
+ * OpenLDAP:
+ * Supports SSL and supports STARTTLS, but none of this is documented:
+ * http://www.openldap.org/lists/openldap-software/200409/msg00618.html
+ * Documentation for both SSL support and STARTTLS has been deleted from
+ * the OpenLDAP documentation and website.
+ */
+
+/** No encryption */
+#define AP_LDAP_NONE 0
+/** SSL encryption (ldaps://) */
+#define AP_LDAP_SSL 1
+/** TLS encryption (STARTTLS) */
+#define AP_LDAP_STARTTLS 2
+/** end TLS encryption (STOPTLS) */
+#define AP_LDAP_STOPTLS 3
+
+/**
+ * MODLDAP get option function
+ *
+ * This function gets option values from a given LDAP session if
+ * one was specified. It maps to the native ldap_get_option() function.
+ * @param pool The pool to use
+ * @param ldap The LDAP handle
+ * @param option The LDAP_OPT_* option to return
+ * @param outvalue The value returned (if any)
+ * @param result_err The ap_ldap_err_t structure contained detailed results
+ * of the operation.
+ */
+MODLDAP_DECLARE(int) ap_ldap_get_option(apr_pool_t *pool,
+ LDAP *ldap,
+ int option,
+ void *outvalue,
+ ap_ldap_err_t **result_err);
+
+/**
+ * MODLDAP set option function
+ *
+ * This function sets option values to a given LDAP session if
+ * one was specified. It maps to the native ldap_set_option() function.
+ *
+ * Where an option is not supported by an LDAP toolkit, this function
+ * will try and apply legacy functions to achieve the same effect,
+ * depending on the platform.
+ * @param pool The pool to use
+ * @param ldap The LDAP handle
+ * @param option The LDAP_OPT_* option to set
+ * @param invalue The value to set
+ * @param result_err The ap_ldap_err_t structure contained detailed results
+ * of the operation.
+ */
+MODLDAP_DECLARE(int) ap_ldap_set_option(apr_pool_t *pool,
+ LDAP *ldap,
+ int option,
+ const void *invalue,
+ ap_ldap_err_t **result_err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AP_HAS_LDAP */
+
+/** @} */
+
+#endif /* AP_LDAP_OPTION_H */
+
diff --git a/include/ap_ldap_rebind.h b/include/ap_ldap_rebind.h
new file mode 100644
index 0000000000..91c30e380d
--- /dev/null
+++ b/include/ap_ldap_rebind.h
@@ -0,0 +1,98 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * The MODLDAP rebind functions provide an implementation of
+ * a rebind procedure that can be used to allow clients to chase referrals,
+ * using the same credentials used to log in originally.
+ *
+ * Use of this implementation is optional.
+ *
+ * @file ap_ldap_rebind.h
+ * @brief Apache LDAP library
+ */
+
+#ifndef APU_LDAP_REBIND_H
+#define APU_LDAP_REBIND_H
+
+/**
+ * @addtogroup AP_Util_LDAP
+ * @{
+ **/
+
+#if defined(DOXYGEN)
+#include "ap_ldap.h"
+#endif
+
+/*
+ * Handle the case when LDAP is enabled
+ */
+#if AP_HAS_LDAP
+
+/**
+ * MODLDAP initialize rebind lock
+ *
+ * This function creates the lock for controlling access to the xref list..
+ * @param pool Pool to use when creating the xref_lock.
+ */
+MODLDAP_DECLARE(apr_status_t) ap_ldap_rebind_init(apr_pool_t *pool);
+
+
+/**
+ * MODLDAP rebind_add function
+ *
+ * This function creates a cross reference entry for the specified ldap
+ * connection. The rebind callback function will look up this ldap
+ * connection so it can retrieve the bindDN and bindPW for use in any
+ * binds while referrals are being chased.
+ *
+ * This function will add the callback to the LDAP handle passed in.
+ *
+ * A cleanup is registered within the pool provided to remove this
+ * entry when the pool is removed. Alternatively ap_ldap_rebind_remove()
+ * can be called to explicitly remove the entry at will.
+ *
+ * @param pool The pool to use
+ * @param ld The LDAP connectionhandle
+ * @param bindDN The bind DN to be used for any binds while chasing
+ * referrals on this ldap connection.
+ * @param bindPW The bind Password to be used for any binds while
+ * chasing referrals on this ldap connection.
+ */
+MODLDAP_DECLARE(apr_status_t) ap_ldap_rebind_add(apr_pool_t *pool,
+ LDAP *ld,
+ const char *bindDN,
+ const char *bindPW);
+
+/**
+ * MODLDAP rebind_remove function
+ *
+ * This function removes the rebind cross reference entry for the
+ * specified ldap connection.
+ *
+ * If not explicitly removed, this function will be called automatically
+ * when the pool is cleaned up.
+ *
+ * @param ld The LDAP connectionhandle
+ */
+MODLDAP_DECLARE(apr_status_t) ap_ldap_rebind_remove(LDAP *ld);
+
+#endif /* AP_HAS_LDAP */
+
+/** @} */
+
+#endif /* APU_LDAP_REBIND_H */
+
diff --git a/include/ap_ldap_url.h b/include/ap_ldap_url.h
new file mode 100644
index 0000000000..9f2bca1d08
--- /dev/null
+++ b/include/ap_ldap_url.h
@@ -0,0 +1,120 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_ldap_url.h
+ * @brief MODLDAP ldap_init() functions
+ */
+#ifndef AP_LDAP_URL_H
+#define AP_LDAP_URL_H
+
+/**
+ * @addtogroup AP_Util_LDAP
+ * @{
+ */
+
+#if defined(DOXYGEN)
+#include "ap_ldap.h"
+#endif
+
+#if AP_HAS_LDAP
+
+#include "apu.h"
+#include "apr_pools.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** Structure to access an exploded LDAP URL */
+typedef struct ap_ldap_url_desc_t {
+ struct ap_ldap_url_desc_t *lud_next;
+ char *lud_scheme;
+ char *lud_host;
+ int lud_port;
+ char *lud_dn;
+ char **lud_attrs;
+ int lud_scope;
+ char *lud_filter;
+ char **lud_exts;
+ int lud_crit_exts;
+} ap_ldap_url_desc_t;
+
+#ifndef AP_LDAP_URL_SUCCESS
+#define AP_LDAP_URL_SUCCESS 0x00 /* Success */
+#define AP_LDAP_URL_ERR_MEM 0x01 /* can't allocate memory space */
+#define AP_LDAP_URL_ERR_PARAM 0x02 /* parameter is bad */
+#define AP_LDAP_URL_ERR_BADSCHEME 0x03 /* URL doesn't begin with "ldap[si]://" */
+#define AP_LDAP_URL_ERR_BADENCLOSURE 0x04 /* URL is missing trailing ">" */
+#define AP_LDAP_URL_ERR_BADURL 0x05 /* URL is bad */
+#define AP_LDAP_URL_ERR_BADHOST 0x06 /* host port is bad */
+#define AP_LDAP_URL_ERR_BADATTRS 0x07 /* bad (or missing) attributes */
+#define AP_LDAP_URL_ERR_BADSCOPE 0x08 /* scope string is invalid (or missing) */
+#define AP_LDAP_URL_ERR_BADFILTER 0x09 /* bad or missing filter */
+#define AP_LDAP_URL_ERR_BADEXTS 0x0a /* bad or missing extensions */
+#endif
+
+/**
+ * Is this URL an ldap url? ldap://
+ * @param url The url to test
+ */
+MODLDAP_DECLARE(int) ap_ldap_is_ldap_url(const char *url);
+
+/**
+ * Is this URL an SSL ldap url? ldaps://
+ * @param url The url to test
+ */
+MODLDAP_DECLARE(int) ap_ldap_is_ldaps_url(const char *url);
+
+/**
+ * Is this URL an ldap socket url? ldapi://
+ * @param url The url to test
+ */
+MODLDAP_DECLARE(int) ap_ldap_is_ldapi_url(const char *url);
+
+/**
+ * Parse an LDAP URL.
+ * @param pool The pool to use
+ * @param url_in The URL to parse
+ * @param ludpp The structure to return the exploded URL
+ * @param result_err The result structure of the operation
+ */
+MODLDAP_DECLARE(int) ap_ldap_url_parse_ext(apr_pool_t *pool,
+ const char *url_in,
+ ap_ldap_url_desc_t **ludpp,
+ ap_ldap_err_t **result_err);
+
+/**
+ * Parse an LDAP URL.
+ * @param pool The pool to use
+ * @param url_in The URL to parse
+ * @param ludpp The structure to return the exploded URL
+ * @param result_err The result structure of the operation
+ */
+MODLDAP_DECLARE(int) ap_ldap_url_parse(apr_pool_t *pool,
+ const char *url_in,
+ ap_ldap_url_desc_t **ludpp,
+ ap_ldap_err_t **result_err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AP_HAS_LDAP */
+
+/** @} */
+
+#endif /* AP_LDAP_URL_H */
diff --git a/include/util_ldap.h b/include/util_ldap.h
index 18c990dbf5..2ab4b7eb3f 100644
--- a/include/util_ldap.h
+++ b/include/util_ldap.h
@@ -28,10 +28,10 @@
#include "apr_thread_rwlock.h"
#include "apr_tables.h"
#include "apr_time.h"
-#include "apr_ldap.h"
-#include "apr_ldap_rebind.h"
+#include "ap_ldap.h"
+#include "ap_ldap_rebind.h"
-#if APR_HAS_MICROSOFT_LDAPSDK
+#if AP_HAS_MICROSOFT_LDAPSDK
#define AP_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN \
||(s) == LDAP_UNAVAILABLE)
#else
@@ -44,7 +44,7 @@
#endif
/* this whole thing disappears if LDAP is not enabled */
-#if APR_HAS_LDAP
+#if AP_HAS_LDAP
/* Apache header files */
#include "ap_config.h"
@@ -194,7 +194,7 @@ APR_DECLARE_OPTIONAL_FN(int,uldap_connection_open,(request_rec *r,
* that was connected.
* @tip This function unbinds from the LDAP server, and clears ldc->ldap.
* It is possible to rebind to this server again using the same ldc
- * structure, using apr_ldap_open_connection().
+ * structure, using ap_ldap_open_connection().
* @fn util_ldap_close_connection(util_ldap_connection_t *ldc)
*/
APR_DECLARE_OPTIONAL_FN(void,uldap_connection_close,(util_ldap_connection_t *ldc));
@@ -222,7 +222,7 @@ APR_DECLARE_OPTIONAL_FN(apr_status_t,uldap_connection_unbind,(void *param));
* @tip Once a connection is found and returned, a lock will be acquired to
* lock that particular connection, so that another thread does not try and
* use this connection while it is busy. Once you are finished with a connection,
- * apr_ldap_connection_close() must be called to release this connection.
+ * ap_ldap_connection_close() must be called to release this connection.
* @fn util_ldap_connection_t *util_ldap_connection_find(request_rec *r, const char *host, int port,
* const char *binddn, const char *bindpw, deref_options deref,
* int netscapessl, int starttls)
@@ -351,7 +351,7 @@ APR_DECLARE_OPTIONAL_FN(int,uldap_cache_getuserdn,(request_rec *r, util_ldap_con
*/
APR_DECLARE_OPTIONAL_FN(int,uldap_ssl_supported,(request_rec *r));
-/* from apr_ldap_cache.c */
+/* from ap_ldap_cache.c */
/**
* Init the LDAP cache
@@ -366,7 +366,7 @@ APR_DECLARE_OPTIONAL_FN(int,uldap_ssl_supported,(request_rec *r));
*/
apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st);
-/* from apr_ldap_cache_mgr.c */
+/* from ap_ldap_cache_mgr.c */
/**
* Display formatted stats for cache
@@ -379,5 +379,5 @@ char *util_ald_cache_display(request_rec *r, util_ldap_state_t *st);
#ifdef __cplusplus
}
#endif
-#endif /* APR_HAS_LDAP */
+#endif /* AP_HAS_LDAP */
#endif /* UTIL_LDAP_H */
diff --git a/modules/aaa/config.m4 b/modules/aaa/config.m4
index 2bd87b8191..d2041dd7b0 100644
--- a/modules/aaa/config.m4
+++ b/modules/aaa/config.m4
@@ -39,11 +39,12 @@ APACHE_MODULE(authz_core, core authorization provider vector module, , , yes)
dnl LDAP authentication module. This module has both the authn and authz
dnl modules in one, so as to share the LDAP server config directives.
+dnl XXX FIXME
APACHE_MODULE(authnz_ldap, LDAP based authentication, , , no, [
if test -z "$apu_config" ; then
- MOD_AUTHNZ_LDAP_LDADD="`$apr_config --ldap-libs`"
+ MOD_AUTHNZ_LDAP_LDADD="$LDADD_ldap"
else
- MOD_AUTHNZ_LDAP_LDADD="`$apu_config --ldap-libs`"
+ MOD_AUTHNZ_LDAP_LDADD="$LDADD_ldap"
fi
AC_SUBST(MOD_AUTHNZ_LDAP_LDADD)
])
diff --git a/modules/aaa/mod_authnz_ldap.c b/modules/aaa/mod_authnz_ldap.c
index 42501e5245..a3cd161d63 100644
--- a/modules/aaa/mod_authnz_ldap.c
+++ b/modules/aaa/mod_authnz_ldap.c
@@ -34,8 +34,8 @@
#include <ctype.h>
-#if !APR_HAS_LDAP
-#error mod_authnz_ldap requires APR-util to have LDAP support built in. To fix add --with-ldap to ./configure.
+#if !AP_HAS_LDAP
+#error mod_authnz_ldap requires LDAP support. To fix add --with-ldap to ./configure.
#endif
static char *default_attributes[3] = { "member", "uniqueMember", NULL };
@@ -256,7 +256,7 @@ static void authn_ldap_build_filter(char *filtbuf,
* LDAP filter metachars are escaped.
*/
filtbuf_end = filtbuf + FILTER_LENGTH - 1;
-#if APR_HAS_MICROSOFT_LDAPSDK
+#if AP_HAS_MICROSOFT_LDAPSDK
for (p = user, q=filtbuf + strlen(filtbuf);
*p && q < filtbuf_end; ) {
if (strchr("*()\\", *p) != NULL) {
@@ -1333,12 +1333,12 @@ static const char *mod_auth_ldap_parse_url(cmd_parms *cmd,
const char *mode)
{
int rc;
- apr_ldap_url_desc_t *urld;
- apr_ldap_err_t *result;
+ ap_ldap_url_desc_t *urld;
+ ap_ldap_err_t *result;
authn_ldap_config_t *sec = config;
- rc = apr_ldap_url_parse(cmd->pool, url, &(urld), &(result));
+ rc = ap_ldap_url_parse(cmd->pool, url, &(urld), &(result));
if (rc != APR_SUCCESS) {
return result->reason;
}
@@ -1391,13 +1391,13 @@ static const char *mod_auth_ldap_parse_url(cmd_parms *cmd,
if (mode) {
if (0 == strcasecmp("NONE", mode)) {
- sec->secure = APR_LDAP_NONE;
+ sec->secure = AP_LDAP_NONE;
}
else if (0 == strcasecmp("SSL", mode)) {
- sec->secure = APR_LDAP_SSL;
+ sec->secure = AP_LDAP_SSL;
}
else if (0 == strcasecmp("TLS", mode) || 0 == strcasecmp("STARTTLS", mode)) {
- sec->secure = APR_LDAP_STARTTLS;
+ sec->secure = AP_LDAP_STARTTLS;
}
else {
return "Invalid LDAP connection mode setting: must be one of NONE, "
@@ -1409,7 +1409,7 @@ static const char *mod_auth_ldap_parse_url(cmd_parms *cmd,
*/
if (strncasecmp(url, "ldaps", 5) == 0)
{
- sec->secure = APR_LDAP_SSL;
+ sec->secure = AP_LDAP_SSL;
sec->port = urld->lud_port? urld->lud_port : LDAPS_PORT;
}
else
@@ -1431,7 +1431,7 @@ static const char *mod_auth_ldap_parse_url(cmd_parms *cmd,
urld->lud_scope == LDAP_SCOPE_BASE? "base" :
urld->lud_scope == LDAP_SCOPE_ONELEVEL? "onelevel" : "unknown"),
urld->lud_filter,
- sec->secure == APR_LDAP_SSL ? "using SSL": "not using SSL"
+ sec->secure == AP_LDAP_SSL ? "using SSL": "not using SSL"
);
return NULL;
diff --git a/modules/ldap/ap_ldap_init.c b/modules/ldap/ap_ldap_init.c
new file mode 100644
index 0000000000..ec34904e46
--- /dev/null
+++ b/modules/ldap/ap_ldap_init.c
@@ -0,0 +1,195 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * ap_ldap_init.c: LDAP v2/v3 common initialise
+ *
+ * Original code from auth_ldap module for Apache v1.3:
+ * Copyright 1998, 1999 Enbridge Pipelines Inc.
+ * Copyright 1999-2001 Dave Carrigan
+ */
+
+#include "apr.h"
+#include "apu.h"
+
+#include "ap_config.h"
+#include "ap_ldap.h"
+#include "apr_errno.h"
+#include "apr_pools.h"
+#include "apr_strings.h"
+
+#if AP_HAS_LDAP
+
+/**
+ * APR LDAP SSL Initialise function
+ *
+ * This function initialises SSL on the underlying LDAP toolkit
+ * if this is necessary.
+ *
+ * If a CA certificate is provided, this is set, however the setting
+ * of certificates via this method has been deprecated and will be removed in
+ * APR v2.0.
+ *
+ * The ap_ldap_set_option() function with the AP_LDAP_OPT_TLS_CERT option
+ * should be used instead to set certificates.
+ *
+ * If SSL support is not available on this platform, or a problem
+ * was encountered while trying to set the certificate, the function
+ * will return APR_EGENERAL. Further LDAP specific error information
+ * can be found in result_err.
+ */
+MODLDAP_DECLARE(int) ap_ldap_ssl_init(apr_pool_t *pool,
+ const char *cert_auth_file,
+ int cert_file_type,
+ ap_ldap_err_t **result_err)
+{
+
+ ap_ldap_err_t *result = (ap_ldap_err_t *)apr_pcalloc(pool, sizeof(ap_ldap_err_t));
+ *result_err = result;
+
+#if AP_HAS_LDAP_SSL /* compiled with ssl support */
+
+ /* Novell */
+#if AP_HAS_NOVELL_LDAPSDK
+ ldapssl_client_init(NULL, NULL);
+#endif
+
+ /* if a certificate was specified, set it */
+ if (cert_auth_file) {
+ ap_ldap_opt_tls_cert_t *cert = (ap_ldap_opt_tls_cert_t *)apr_pcalloc(pool, sizeof(ap_ldap_opt_tls_cert_t));
+ cert->type = cert_file_type;
+ cert->path = cert_auth_file;
+ return ap_ldap_set_option(pool, NULL, AP_LDAP_OPT_TLS_CERT, (void *)cert, result_err);
+ }
+
+#else /* not compiled with SSL Support */
+ if (cert_auth_file) {
+ result->reason = "LDAP: Attempt to set certificate store failed. "
+ "Not built with SSL support";
+ result->rc = -1;
+ }
+#endif /* AP_HAS_LDAP_SSL */
+
+ if (result->rc != -1) {
+ result->msg = ldap_err2string(result->rc);
+ }
+
+ if (LDAP_SUCCESS != result->rc) {
+ return APR_EGENERAL;
+ }
+
+ return APR_SUCCESS;
+
+}
+
+
+/**
+ * APR LDAP SSL De-Initialise function
+ *
+ * This function tears down any SSL certificate setup previously
+ * set using ap_ldap_ssl_init(). It should be called to clean
+ * up if a graceful restart of a service is attempted.
+ *
+ * This function only does anything on Netware.
+ *
+ * @todo currently we do not check whether ap_ldap_ssl_init()
+ * has been called first - should we?
+ */
+MODLDAP_DECLARE(int) ap_ldap_ssl_deinit(void)
+{
+
+#if AP_HAS_LDAP_SSL && AP_HAS_LDAPSSL_CLIENT_DEINIT
+ ldapssl_client_deinit();
+#endif
+ return APR_SUCCESS;
+
+}
+
+
+/**
+ * APR LDAP initialise function
+ *
+ * This function is responsible for initialising an LDAP
+ * connection in a toolkit independant way. It does the
+ * job of ldap_init() from the C api.
+ *
+ * It handles both the SSL and non-SSL case, and attempts
+ * to hide the complexity setup from the user. This function
+ * assumes that any certificate setup necessary has already
+ * been done.
+ *
+ * If SSL or STARTTLS needs to be enabled, and the underlying
+ * toolkit supports it, the following values are accepted for
+ * secure:
+ *
+ * AP_LDAP_NONE: No encryption
+ * AP_LDAP_SSL: SSL encryption (ldaps://)
+ * AP_LDAP_STARTTLS: Force STARTTLS on ldap://
+ */
+MODLDAP_DECLARE(int) ap_ldap_init(apr_pool_t *pool,
+ LDAP **ldap,
+ const char *hostname,
+ int portno,
+ int secure,
+ ap_ldap_err_t **result_err)
+{
+
+ ap_ldap_err_t *result = (ap_ldap_err_t *)apr_pcalloc(pool, sizeof(ap_ldap_err_t));
+ *result_err = result;
+
+#if AP_HAS_LDAPSSL_INIT
+ *ldap = ldapssl_init(hostname, portno, 0);
+#elif AP_HAS_LDAP_SSLINIT
+ *ldap = ldap_sslinit((char *)hostname, portno, 0);
+#else
+ *ldap = ldap_init((char *)hostname, portno);
+#endif
+ if (*ldap != NULL) {
+ return ap_ldap_set_option(pool, *ldap, AP_LDAP_OPT_TLS, &secure, result_err);
+ }
+ else {
+ /* handle the error case */
+ ap_ldap_err_t *result = (ap_ldap_err_t *)apr_pcalloc(pool, sizeof(ap_ldap_err_t));
+ *result_err = result;
+
+ result->reason = "APR LDAP: Unable to initialize the LDAP connection";
+ result->rc = -1;
+ return APR_EGENERAL;
+ }
+
+}
+
+
+/**
+ * APR LDAP info function
+ *
+ * This function returns a string describing the LDAP toolkit
+ * currently in use. The string is placed inside result_err->reason.
+ */
+MODLDAP_DECLARE(int) ap_ldap_info(apr_pool_t *pool,
+ ap_ldap_err_t **result_err)
+{
+ ap_ldap_err_t *result = (ap_ldap_err_t *)apr_pcalloc(pool, sizeof(ap_ldap_err_t));
+ *result_err = result;
+
+ result->reason = "APR LDAP: Built with "
+ LDAP_VENDOR_NAME
+ " LDAP SDK";
+ return APR_SUCCESS;
+
+}
+
+#endif /* AP_HAS_LDAP */
diff --git a/modules/ldap/ap_ldap_option.c b/modules/ldap/ap_ldap_option.c
new file mode 100644
index 0000000000..84e770dc4b
--- /dev/null
+++ b/modules/ldap/ap_ldap_option.c
@@ -0,0 +1,667 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* ap_ldap_option.c -- LDAP options
+ *
+ * The LDAP SDK allows the getting and setting of options on an LDAP
+ * connection.
+ *
+ */
+
+#include "apr.h"
+#include "apu.h"
+#include "ap_config.h"
+#include "ap_ldap.h"
+#include "apr_errno.h"
+#include "apr_pools.h"
+#include "apr_strings.h"
+#include "apr_tables.h"
+
+#if AP_HAS_LDAP
+
+static void option_set_cert(apr_pool_t *pool, LDAP *ldap, const void *invalue,
+ ap_ldap_err_t *result);
+static void option_set_tls(apr_pool_t *pool, LDAP *ldap, const void *invalue,
+ ap_ldap_err_t *result);
+
+/**
+ * MODLDAP get option function
+ *
+ * This function gets option values from a given LDAP session if
+ * one was specified.
+ */
+MODLDAP_DECLARE(int) ap_ldap_get_option(apr_pool_t *pool,
+ LDAP *ldap,
+ int option,
+ void *outvalue,
+ ap_ldap_err_t **result_err)
+{
+ ap_ldap_err_t *result;
+
+ result = apr_pcalloc(pool, sizeof(ap_ldap_err_t));
+ *result_err = result;
+ if (!result) {
+ return APR_ENOMEM;
+ }
+
+ /* get the option specified using the native LDAP function */
+ result->rc = ldap_get_option(ldap, option, outvalue);
+
+ /* handle the error case */
+ if (result->rc != LDAP_SUCCESS) {
+ result->msg = ldap_err2string(result-> rc);
+ result->reason = apr_pstrdup(pool, "LDAP: Could not get an option");
+ return APR_EGENERAL;
+ }
+
+ return APR_SUCCESS;
+
+}
+
+/**
+ * MODLDAP set option function
+ *
+ * This function sets option values to a given LDAP session if
+ * one was specified.
+ *
+ * Where an option is not supported by an LDAP toolkit, this function
+ * will try and apply legacy functions to achieve the same effect,
+ * depending on the platform.
+ */
+MODLDAP_DECLARE(int) ap_ldap_set_option(apr_pool_t *pool,
+ LDAP *ldap,
+ int option,
+ const void *invalue,
+ ap_ldap_err_t **result_err)
+{
+ ap_ldap_err_t *result;
+
+ result = apr_pcalloc(pool, sizeof(ap_ldap_err_t));
+ *result_err = result;
+ if (!result) {
+ return APR_ENOMEM;
+ }
+
+ switch (option) {
+ case AP_LDAP_OPT_TLS_CERT:
+ option_set_cert(pool, ldap, invalue, result);
+ break;
+
+ case AP_LDAP_OPT_TLS:
+ option_set_tls(pool, ldap, invalue, result);
+ break;
+
+ case AP_LDAP_OPT_VERIFY_CERT:
+#if AP_HAS_NETSCAPE_LDAPSDK || AP_HAS_SOLARIS_LDAPSDK || AP_HAS_MOZILLA_LDAPSK
+ result->reason = "LDAP: Verify certificate not yet supported on the "
+ "Netscape, Solaris or Mozilla LDAP SDKs";
+ result->rc = -1;
+ return APR_EGENERAL;
+#endif
+#if AP_HAS_NOVELL_LDAPSDK
+ if (*((int*)invalue)) {
+ result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_SERVER);
+ }
+ else {
+ result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_NONE);
+ }
+#endif
+#if AP_HAS_OPENLDAP_LDAPSDK
+#ifdef LDAP_OPT_X_TLS
+ /* This is not a per-connection setting so just pass NULL for the
+ Ldap connection handle */
+ if (*((int*)invalue)) {
+ int i = LDAP_OPT_X_TLS_DEMAND;
+ result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
+ }
+ else {
+ int i = LDAP_OPT_X_TLS_NEVER;
+ result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
+ }
+#else
+ result->reason = "LDAP: SSL/TLS not yet supported on this "
+ "version of the OpenLDAP toolkit";
+ result->rc = -1;
+ return APR_EGENERAL;
+#endif
+#endif
+
+ /* handle the error case */
+ if (result->rc != LDAP_SUCCESS) {
+ result->msg = ldap_err2string(result->rc);
+ result->reason = "LDAP: Could not set verify mode";
+ }
+ break;
+
+ case AP_LDAP_OPT_REFERRALS:
+ /* Setting this option is supported on at least TIVOLI_SDK and OpenLDAP. Folks
+ * who know the NOVELL, NETSCAPE, MOZILLA, and SOLARIS SDKs should note here if
+ * the SDK at least tolerates this option being set, or add an elif to handle
+ * special cases (i.e. different LDAP_OPT_X value).
+ */
+ result->rc = ldap_set_option(ldap, LDAP_OPT_REFERRALS, (void *)invalue);
+
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "Unable to set LDAP_OPT_REFERRALS.";
+ return(result->rc);
+ }
+ break;
+
+ case AP_LDAP_OPT_REFHOPLIMIT:
+#if !defined(LDAP_OPT_REFHOPLIMIT) || AP_HAS_NOVELL_LDAPSDK
+ /* If the LDAP_OPT_REFHOPLIMIT symbol is missing, assume that the
+ * particular LDAP library has a reasonable default. So far certain
+ * versions of the OpenLDAP SDK miss this symbol (but default to 5),
+ * and the Microsoft SDK misses the symbol (the default is not known).
+ */
+ result->rc = LDAP_SUCCESS;
+#else
+ /* Setting this option is supported on at least TIVOLI_SDK. Folks who know
+ * the NOVELL, NETSCAPE, MOZILLA, and SOLARIS SDKs should note here if
+ * the SDK at least tolerates this option being set, or add an elif to handle
+ * special cases so an error isn't returned if there is a perfectly good
+ * default value that just can't be changed (like openLDAP).
+ */
+ result->rc = ldap_set_option(ldap, LDAP_OPT_REFHOPLIMIT, (void *)invalue);
+#endif
+
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "Unable to set LDAP_OPT_REFHOPLIMIT.";
+ return(result->rc);
+ }
+ break;
+
+ default:
+ /* set the option specified using the native LDAP function */
+ result->rc = ldap_set_option(ldap, option, (void *)invalue);
+
+ /* handle the error case */
+ if (result->rc != LDAP_SUCCESS) {
+ result->msg = ldap_err2string(result->rc);
+ result->reason = "LDAP: Could not set an option";
+ }
+ break;
+ }
+
+ /* handle the error case */
+ if (result->rc != LDAP_SUCCESS) {
+ return APR_EGENERAL;
+ }
+
+ return APR_SUCCESS;
+
+}
+
+/**
+ * Handle AP_LDAP_OPT_TLS
+ *
+ * This function sets the type of TLS to be applied to this connection.
+ * The options are:
+ * AP_LDAP_NONE: no encryption
+ * AP_LDAP_SSL: SSL encryption (ldaps://)
+ * AP_LDAP_STARTTLS: STARTTLS encryption
+ * AP_LDAP_STOPTLS: Stop existing TLS connecttion
+ */
+static void option_set_tls(apr_pool_t *pool, LDAP *ldap, const void *invalue,
+ ap_ldap_err_t *result)
+{
+#if AP_HAS_LDAP_SSL /* compiled with ssl support */
+
+ int tls = * (const int *)invalue;
+
+ /* Netscape/Mozilla/Solaris SDK */
+#if AP_HAS_NETSCAPE_LDAPSDK || AP_HAS_SOLARIS_LDAPSDK || AP_HAS_MOZILLA_LDAPSK
+#if AP_HAS_LDAPSSL_INSTALL_ROUTINES
+ if (tls == AP_LDAP_SSL) {
+ result->rc = ldapssl_install_routines(ldap);
+#ifdef LDAP_OPT_SSL
+ /* apparently Netscape and Mozilla need this too, Solaris doesn't */
+ if (result->rc == LDAP_SUCCESS) {
+ result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, LDAP_OPT_ON);
+ }
+#endif
+ if (result->rc != LDAP_SUCCESS) {
+ result->msg = ldap_err2string(result->rc);
+ result->reason = "LDAP: Could not switch SSL on for this "
+ "connection.";
+ }
+ }
+ else if (tls == AP_LDAP_STARTTLS) {
+ result->reason = "LDAP: STARTTLS is not supported by the "
+ "Netscape/Mozilla/Solaris SDK";
+ result->rc = -1;
+ }
+ else if (tls == AP_LDAP_STOPTLS) {
+ result->reason = "LDAP: STOPTLS is not supported by the "
+ "Netscape/Mozilla/Solaris SDK";
+ result->rc = -1;
+ }
+#else
+ if (tls != AP_LDAP_NONE) {
+ result->reason = "LDAP: SSL/TLS is not supported by this version "
+ "of the Netscape/Mozilla/Solaris SDK";
+ result->rc = -1;
+ }
+#endif
+#endif
+
+ /* Novell SDK */
+#if AP_HAS_NOVELL_LDAPSDK
+ /* ldapssl_install_routines(ldap)
+ * Behavior is unpredictable when other LDAP functions are called
+ * between the ldap_init function and the ldapssl_install_routines
+ * function.
+ *
+ * STARTTLS is supported by the ldap_start_tls_s() method
+ */
+ if (tls == AP_LDAP_SSL) {
+ result->rc = ldapssl_install_routines(ldap);
+ if (result->rc != LDAP_SUCCESS) {
+ result->msg = ldap_err2string(result->rc);
+ result->reason = "LDAP: Could not switch SSL on for this "
+ "connection.";
+ }
+ }
+ if (tls == AP_LDAP_STARTTLS) {
+ result->rc = ldapssl_start_tls(ldap);
+ if (result->rc != LDAP_SUCCESS) {
+ result->msg = ldap_err2string(result->rc);
+ result->reason = "LDAP: Could not start TLS on this connection";
+ }
+ }
+ else if (tls == AP_LDAP_STOPTLS) {
+ result->rc = ldapssl_stop_tls(ldap);
+ if (result->rc != LDAP_SUCCESS) {
+ result->msg = ldap_err2string(result->rc);
+ result->reason = "LDAP: Could not stop TLS on this connection";
+ }
+ }
+#endif
+
+ /* OpenLDAP SDK */
+#if AP_HAS_OPENLDAP_LDAPSDK
+#ifdef LDAP_OPT_X_TLS
+ if (tls == AP_LDAP_SSL) {
+ int SSLmode = LDAP_OPT_X_TLS_HARD;
+ result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS, &SSLmode);
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "LDAP: ldap_set_option failed. "
+ "Could not set LDAP_OPT_X_TLS to "
+ "LDAP_OPT_X_TLS_HARD";
+ result->msg = ldap_err2string(result->rc);
+ }
+ }
+ else if (tls == AP_LDAP_STARTTLS) {
+ result->rc = ldap_start_tls_s(ldap, NULL, NULL);
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "LDAP: ldap_start_tls_s() failed";
+ result->msg = ldap_err2string(result->rc);
+ }
+ }
+ else if (tls == AP_LDAP_STOPTLS) {
+ result->reason = "LDAP: STOPTLS is not supported by the "
+ "OpenLDAP SDK";
+ result->rc = -1;
+ }
+#else
+ if (tls != AP_LDAP_NONE) {
+ result->reason = "LDAP: SSL/TLS not yet supported on this "
+ "version of the OpenLDAP toolkit";
+ result->rc = -1;
+ }
+#endif
+#endif
+
+ /* Microsoft SDK */
+#if AP_HAS_MICROSOFT_LDAPSDK
+ if (tls == AP_LDAP_NONE) {
+ ULONG ul = (ULONG) LDAP_OPT_OFF;
+ result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, &ul);
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "LDAP: an attempt to set LDAP_OPT_SSL off "
+ "failed.";
+ result->msg = ldap_err2string(result->rc);
+ }
+ }
+ else if (tls == AP_LDAP_SSL) {
+ ULONG ul = (ULONG) LDAP_OPT_ON;
+ result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, &ul);
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "LDAP: an attempt to set LDAP_OPT_SSL on "
+ "failed.";
+ result->msg = ldap_err2string(result->rc);
+ }
+ }
+#if AP_HAS_LDAP_START_TLS_S
+ else if (tls == AP_LDAP_STARTTLS) {
+ result->rc = ldap_start_tls_s(ldap, NULL, NULL, NULL, NULL);
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "LDAP: ldap_start_tls_s() failed";
+ result->msg = ldap_err2string(result->rc);
+ }
+ }
+ else if (tls == AP_LDAP_STOPTLS) {
+ result->rc = ldap_stop_tls_s(ldap);
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "LDAP: ldap_stop_tls_s() failed";
+ result->msg = ldap_err2string(result->rc);
+ }
+ }
+#endif
+#endif
+
+#if AP_HAS_OTHER_LDAPSDK
+ if (tls != AP_LDAP_NONE) {
+ result->reason = "LDAP: SSL/TLS is currently not supported "
+ "on this LDAP SDK";
+ result->rc = -1;
+ }
+#endif
+
+#endif /* AP_HAS_LDAP_SSL */
+
+}
+
+/**
+ * Handle AP_LDAP_OPT_TLS_CACERTFILE
+ *
+ * This function sets the CA certificate for further SSL/TLS connections.
+ *
+ * The file provided are in different formats depending on the toolkit used:
+ *
+ * Netscape: cert7.db file
+ * Novell: PEM or DER
+ * OpenLDAP: PEM (others supported?)
+ * Microsoft: unknown
+ * Solaris: unknown
+ */
+static void option_set_cert(apr_pool_t *pool, LDAP *ldap,
+ const void *invalue, ap_ldap_err_t *result)
+{
+#if AP_HAS_LDAP_SSL
+#if AP_HAS_LDAPSSL_CLIENT_INIT || AP_HAS_OPENLDAP_LDAPSDK
+ apr_array_header_t *certs = (apr_array_header_t *)invalue;
+ struct ap_ldap_opt_tls_cert_t *ents = (struct ap_ldap_opt_tls_cert_t *)certs->elts;
+ int i = 0;
+#endif
+
+ /* Netscape/Mozilla/Solaris SDK */
+#if AP_HAS_NETSCAPE_LDAPSDK || AP_HAS_SOLARIS_LDAPSDK || AP_HAS_MOZILLA_LDAPSDK
+#if AP_HAS_LDAPSSL_CLIENT_INIT
+ const char *nickname = NULL;
+ const char *secmod = NULL;
+ const char *key3db = NULL;
+ const char *cert7db = NULL;
+ const char *password = NULL;
+
+ /* set up cert7.db, key3.db and secmod parameters */
+ for (i = 0; i < certs->nelts; i++) {
+ switch (ents[i].type) {
+ case AP_LDAP_CA_TYPE_CERT7_DB:
+ cert7db = ents[i].path;
+ break;
+ case AP_LDAP_CA_TYPE_SECMOD:
+ secmod = ents[i].path;
+ break;
+ case AP_LDAP_CERT_TYPE_KEY3_DB:
+ key3db = ents[i].path;
+ break;
+ case AP_LDAP_CERT_TYPE_NICKNAME:
+ nickname = ents[i].path;
+ password = ents[i].password;
+ break;
+ default:
+ result->rc = -1;
+ result->reason = "LDAP: The Netscape/Mozilla LDAP SDK only "
+ "understands the CERT7, KEY3 and SECMOD "
+ "file types.";
+ break;
+ }
+ if (result->rc != LDAP_SUCCESS) {
+ break;
+ }
+ }
+
+ /* actually set the certificate parameters */
+ if (result->rc == LDAP_SUCCESS) {
+ if (nickname) {
+ result->rc = ldapssl_enable_clientauth(ldap, "",
+ (char *)password,
+ (char *)nickname);
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "LDAP: could not set client certificate: "
+ "ldapssl_enable_clientauth() failed.";
+ result->msg = ldap_err2string(result->rc);
+ }
+ }
+ else if (secmod) {
+ result->rc = ldapssl_advclientauth_init(cert7db, NULL,
+ key3db ? 1 : 0, key3db, NULL,
+ 1, secmod, LDAPSSL_AUTH_CNCHECK);
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "LDAP: ldapssl_advclientauth_init() failed.";
+ result->msg = ldap_err2string(result->rc);
+ }
+ }
+ else if (key3db) {
+ result->rc = ldapssl_clientauth_init(cert7db, NULL,
+ 1, key3db, NULL);
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "LDAP: ldapssl_clientauth_init() failed.";
+ result->msg = ldap_err2string(result->rc);
+ }
+ }
+ else {
+ result->rc = ldapssl_client_init(cert7db, NULL);
+ if (result->rc != LDAP_SUCCESS) {
+ result->reason = "LDAP: ldapssl_client_init() failed.";
+ result->msg = ldap_err2string(result->rc);
+ }
+ }
+ }
+#else
+ result->reason = "LDAP: SSL/TLS ldapssl_client_init() function not "
+ "supported by this Netscape/Mozilla/Solaris SDK. "
+ "Certificate authority file not set";
+ result->rc = -1;
+#endif
+#endif
+
+ /* Novell SDK */
+#if AP_HAS_NOVELL_LDAPSDK
+#if AP_HAS_LDAPSSL_CLIENT_INIT && AP_HAS_LDAPSSL_ADD_TRUSTED_CERT && AP_HAS_LDAPSSL_CLIENT_DEINIT
+ /* The Novell library cannot support per connection certificates. Error
+ * out if the ldap handle is provided.
+ */
+ if (ldap) {
+ result->rc = -1;
+ result->reason = "LDAP: The Novell LDAP SDK cannot support the setting "
+ "of certificates or keys on a per connection basis.";
+ }
+ /* Novell's library needs to be initialised first */
+ else {
+ result->rc = ldapssl_client_init(NULL, NULL);
+ if (result->rc != LDAP_SUCCESS) {
+ result->msg = ldap_err2string(result-> rc);
+ result->reason = apr_pstrdup(pool, "LDAP: Could not "
+ "initialize SSL");
+ }
+ }
+ /* set one or more certificates */
+ for (i = 0; LDAP_SUCCESS == result->rc && i < certs->nelts; i++) {
+ /* Novell SDK supports DER or BASE64 files. */
+ switch (ents[i].type) {
+ case AP_LDAP_CA_TYPE_DER:
+ result->rc = ldapssl_add_trusted_cert((void *)ents[i].path,
+ LDAPSSL_CERT_FILETYPE_DER);
+ result->msg = ldap_err2string(result->rc);
+ break;
+ case AP_LDAP_CA_TYPE_BASE64:
+ result->rc = ldapssl_add_trusted_cert((void *)ents[i].path,
+ LDAPSSL_CERT_FILETYPE_B64);
+ result->msg = ldap_err2string(result->rc);
+ break;
+ case AP_LDAP_CERT_TYPE_DER:
+ result->rc = ldapssl_set_client_cert((void *)ents[i].path,
+ LDAPSSL_CERT_FILETYPE_DER,
+ (void*)ents[i].password);
+ result->msg = ldap_err2string(result->rc);
+ break;
+ case AP_LDAP_CERT_TYPE_BASE64:
+ result->rc = ldapssl_set_client_cert((void *)ents[i].path,
+ LDAPSSL_CERT_FILETYPE_B64,
+ (void*)ents[i].password);
+ result->msg = ldap_err2string(result->rc);
+ break;
+ case AP_LDAP_CERT_TYPE_PFX:
+ result->rc = ldapssl_set_client_cert((void *)ents[i].path,
+ LDAPSSL_FILETYPE_P12,
+ (void*)ents[i].password);
+ result->msg = ldap_err2string(result->rc);
+ break;
+ case AP_LDAP_KEY_TYPE_DER:
+ result->rc = ldapssl_set_client_private_key((void *)ents[i].path,
+ LDAPSSL_CERT_FILETYPE_DER,
+ (void*)ents[i].password);
+ result->msg = ldap_err2string(result->rc);
+ break;
+ case AP_LDAP_KEY_TYPE_BASE64:
+ result->rc = ldapssl_set_client_private_key((void *)ents[i].path,
+ LDAPSSL_CERT_FILETYPE_B64,
+ (void*)ents[i].password);
+ result->msg = ldap_err2string(result->rc);
+ break;
+ case AP_LDAP_KEY_TYPE_PFX:
+ result->rc = ldapssl_set_client_private_key((void *)ents[i].path,
+ LDAPSSL_FILETYPE_P12,
+ (void*)ents[i].password);
+ result->msg = ldap_err2string(result->rc);
+ break;
+ default:
+ result->rc = -1;
+ result->reason = "LDAP: The Novell LDAP SDK only understands the "
+ "DER and PEM (BASE64) file types.";
+ break;
+ }
+ if (result->rc != LDAP_SUCCESS) {
+ break;
+ }
+ }
+#else
+ result->reason = "LDAP: ldapssl_client_init(), "
+ "ldapssl_add_trusted_cert() or "
+ "ldapssl_client_deinit() functions not supported "
+ "by this Novell SDK. Certificate authority file "
+ "not set";
+ result->rc = -1;
+#endif
+#endif
+
+ /* OpenLDAP SDK */
+#if AP_HAS_OPENLDAP_LDAPSDK
+#ifdef LDAP_OPT_X_TLS_CACERTFILE
+#ifndef LDAP_OPT_X_TLS_NEWCTX
+ if (ldap) {
+ result->reason = "LDAP: The OpenLDAP SDK cannot support the setting "
+ "of certificates or keys on a per connection basis.";
+ result->rc = -1;
+ return;
+ }
+#endif
+
+ /* set one or more certificates */
+ /* FIXME: make it support setting directories as well as files */
+ for (i = 0; i < certs->nelts; i++) {
+ /* OpenLDAP SDK supports BASE64 files. */
+ switch (ents[i].type) {
+ case AP_LDAP_CA_TYPE_BASE64:
+ result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_CACERTFILE,
+ (void *)ents[i].path);
+ result->msg = ldap_err2string(result->rc);
+ break;
+ case AP_LDAP_CERT_TYPE_BASE64:
+ result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_CERTFILE,
+ (void *)ents[i].path);
+ result->msg = ldap_err2string(result->rc);
+ break;
+ case AP_LDAP_KEY_TYPE_BASE64:
+ result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_KEYFILE,
+ (void *)ents[i].path);
+ result->msg = ldap_err2string(result->rc);
+ break;
+#ifdef LDAP_OPT_X_TLS_CACERTDIR
+ case AP_LDAP_CA_TYPE_CACERTDIR_BASE64:
+ result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_CACERTDIR,
+ (void *)ents[i].path);
+ result->msg = ldap_err2string(result->rc);
+ break;
+#endif
+ default:
+ result->rc = -1;
+ result->reason = "LDAP: The OpenLDAP SDK only understands the "
+ "PEM (BASE64) file type.";
+ break;
+ }
+ if (result->rc != LDAP_SUCCESS) {
+ break;
+ }
+ }
+#ifdef LDAP_OPT_X_TLS_NEWCTX
+ /* Certificate settings are now configured, but we also need a new
+ * TLS context to be created. This applies to both gnuTLS and openssl
+ */
+ if (ldap && (result->rc == LDAP_SUCCESS)) {
+ int IS_SERVER = 0;
+ result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_NEWCTX, &IS_SERVER);
+ result->msg = ldap_err2string(result->rc);
+ }
+#endif
+
+#else
+ result->reason = "LDAP: LDAP_OPT_X_TLS_CACERTFILE not "
+ "defined by this OpenLDAP SDK. Certificate "
+ "authority file not set";
+ result->rc = -1;
+#endif
+#endif
+
+ /* Microsoft SDK */
+#if AP_HAS_MICROSOFT_LDAPSDK
+ /* Microsoft SDK use the registry certificate store - error out
+ * here with a message explaining this. */
+ result->reason = "LDAP: CA certificates cannot be set using this method, "
+ "as they are stored in the registry instead.";
+ result->rc = -1;
+#endif
+
+ /* SDK not recognised */
+#if AP_HAS_OTHER_LDAPSDK
+ result->reason = "LDAP: LDAP_OPT_X_TLS_CACERTFILE not "
+ "defined by this LDAP SDK. Certificate "
+ "authority file not set";
+ result->rc = -1;
+#endif
+
+#else /* not compiled with SSL Support */
+ result->reason = "LDAP: Attempt to set certificate(s) failed. "
+ "Not built with SSL support";
+ result->rc = -1;
+#endif /* AP_HAS_LDAP_SSL */
+
+}
+
+#endif /* AP_HAS_LDAP */
+
diff --git a/modules/ldap/ap_ldap_rebind.c b/modules/ldap/ap_ldap_rebind.c
new file mode 100644
index 0000000000..0b93abc9d9
--- /dev/null
+++ b/modules/ldap/ap_ldap_rebind.c
@@ -0,0 +1,371 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* ap_ldap_rebind.c -- LDAP rebind callbacks for referrals
+ *
+ * The LDAP SDK allows a callback to be set to enable rebinding
+ * for referral processing.
+ *
+ */
+
+#include "apr.h"
+#include "ap_config.h"
+#include "ap_ldap.h"
+
+#if AP_HAS_LDAP
+
+#include "apr_errno.h"
+#include "apr_strings.h"
+
+#include "stdio.h"
+
+/* Used to store information about connections for use in the referral rebind callback. */
+struct ap_ldap_rebind_entry {
+ apr_pool_t *pool;
+ LDAP *index;
+ const char *bindDN;
+ const char *bindPW;
+ struct ap_ldap_rebind_entry *next;
+};
+typedef struct ap_ldap_rebind_entry ap_ldap_rebind_entry_t;
+
+
+#ifdef NETWARE
+#define get_apd \
+ APP_DATA* apd = (APP_DATA*)get_app_data(gLibId); \
+ ap_ldap_xref_lock = (apr_thread_mutex_t *)apd->gs_ldap_xref_lock; \
+ xref_head = (ap_ldap_rebind_entry_t *)apd->gs_xref_head;
+#endif
+
+#if APR_HAS_THREADS
+static apr_thread_mutex_t *ap_ldap_xref_lock = NULL;
+#endif
+static ap_ldap_rebind_entry_t *xref_head = NULL;
+
+static int ap_ldap_rebind_set_callback(LDAP *ld);
+static apr_status_t ap_ldap_rebind_remove_helper(void *data);
+
+static apr_status_t ap_ldap_pool_cleanup_set_null(void *data_)
+{
+ void **ptr = (void **)data_;
+ *ptr = NULL;
+ return APR_SUCCESS;
+}
+
+
+/* AP utility routine used to create the xref_lock. */
+MODLDAP_DECLARE(apr_status_t) ap_ldap_rebind_init(apr_pool_t *pool)
+{
+ apr_status_t retcode = APR_SUCCESS;
+
+#ifdef NETWARE
+ get_apd
+#endif
+
+ /* run after apr_thread_mutex_create cleanup */
+ apr_pool_cleanup_register(pool, &ap_ldap_xref_lock, ap_ldap_pool_cleanup_set_null,
+ apr_pool_cleanup_null);
+
+#if APR_HAS_THREADS
+ if (ap_ldap_xref_lock == NULL) {
+ retcode = apr_thread_mutex_create(&ap_ldap_xref_lock, APR_THREAD_MUTEX_DEFAULT, pool);
+ }
+#endif
+
+ return(retcode);
+}
+
+
+MODLDAP_DECLARE(apr_status_t) ap_ldap_rebind_add(apr_pool_t *pool,
+ LDAP *ld,
+ const char *bindDN,
+ const char *bindPW)
+{
+ apr_status_t retcode = APR_SUCCESS;
+ ap_ldap_rebind_entry_t *new_xref;
+
+#ifdef NETWARE
+ get_apd
+#endif
+
+ new_xref = (ap_ldap_rebind_entry_t *)apr_pcalloc(pool, sizeof(ap_ldap_rebind_entry_t));
+ if (new_xref) {
+ new_xref->pool = pool;
+ new_xref->index = ld;
+ if (bindDN) {
+ new_xref->bindDN = apr_pstrdup(pool, bindDN);
+ }
+ if (bindPW) {
+ new_xref->bindPW = apr_pstrdup(pool, bindPW);
+ }
+
+#if APR_HAS_THREADS
+ retcode = apr_thread_mutex_lock(ap_ldap_xref_lock);
+ if (retcode != APR_SUCCESS) {
+ return retcode;
+ }
+#endif
+
+ new_xref->next = xref_head;
+ xref_head = new_xref;
+
+#if APR_HAS_THREADS
+ retcode = apr_thread_mutex_unlock(ap_ldap_xref_lock);
+ if (retcode != APR_SUCCESS) {
+ return retcode;
+ }
+#endif
+ }
+ else {
+ return(APR_ENOMEM);
+ }
+
+ retcode = ap_ldap_rebind_set_callback(ld);
+ if (APR_SUCCESS != retcode) {
+ ap_ldap_rebind_remove(ld);
+ return retcode;
+ }
+
+ apr_pool_cleanup_register(pool, ld,
+ ap_ldap_rebind_remove_helper,
+ apr_pool_cleanup_null);
+
+ return(APR_SUCCESS);
+}
+
+
+MODLDAP_DECLARE(apr_status_t) ap_ldap_rebind_remove(LDAP *ld)
+{
+ ap_ldap_rebind_entry_t *tmp_xref, *prev = NULL;
+ apr_status_t retcode = 0;
+
+#ifdef NETWARE
+ get_apd
+#endif
+
+#if APR_HAS_THREADS
+ retcode = apr_thread_mutex_lock(ap_ldap_xref_lock);
+ if (retcode != APR_SUCCESS) {
+ return retcode;
+ }
+#endif
+ tmp_xref = xref_head;
+
+ while ((tmp_xref) && (tmp_xref->index != ld)) {
+ prev = tmp_xref;
+ tmp_xref = tmp_xref->next;
+ }
+
+ if (tmp_xref) {
+ if (tmp_xref == xref_head) {
+ xref_head = xref_head->next;
+ }
+ else {
+ prev->next = tmp_xref->next;
+ }
+
+ /* tmp_xref and its contents were pool allocated so they don't need to be freed here. */
+
+ /* remove the cleanup, just in case this was done manually */
+ apr_pool_cleanup_kill(tmp_xref->pool, tmp_xref->index,
+ ap_ldap_rebind_remove_helper);
+ }
+
+#if APR_HAS_THREADS
+ retcode = apr_thread_mutex_unlock(ap_ldap_xref_lock);
+ if (retcode != APR_SUCCESS) {
+ return retcode;
+ }
+#endif
+ return APR_SUCCESS;
+}
+
+
+static apr_status_t ap_ldap_rebind_remove_helper(void *data)
+{
+ LDAP *ld = (LDAP *)data;
+ ap_ldap_rebind_remove(ld);
+ return APR_SUCCESS;
+}
+
+#if AP_HAS_TIVOLI_LDAPSDK || AP_HAS_OPENLDAP_LDAPSDK || AP_HAS_NOVELL_LDAPSDK
+static ap_ldap_rebind_entry_t *ap_ldap_rebind_lookup(LDAP *ld)
+{
+ ap_ldap_rebind_entry_t *tmp_xref, *match = NULL;
+
+#ifdef NETWARE
+ get_apd
+#endif
+
+#if APR_HAS_THREADS
+ apr_thread_mutex_lock(ap_ldap_xref_lock);
+#endif
+ tmp_xref = xref_head;
+
+ while (tmp_xref) {
+ if (tmp_xref->index == ld) {
+ match = tmp_xref;
+ tmp_xref = NULL;
+ }
+ else {
+ tmp_xref = tmp_xref->next;
+ }
+ }
+
+#if APR_HAS_THREADS
+ apr_thread_mutex_unlock(ap_ldap_xref_lock);
+#endif
+
+ return (match);
+}
+#endif
+
+#if AP_HAS_TIVOLI_LDAPSDK
+
+/* LDAP_rebindproc() Tivoli LDAP style
+ * Rebind callback function. Called when chasing referrals. See API docs.
+ * ON ENTRY:
+ * ld Pointer to an LDAP control structure. (input only)
+ * binddnp Pointer to an Application DName used for binding (in *or* out)
+ * passwdp Pointer to the password associated with the DName (in *or* out)
+ * methodp Pointer to the Auth method (output only)
+ * freeit Flag to indicate if this is a lookup or a free request (input only)
+ */
+static int LDAP_rebindproc(LDAP *ld, char **binddnp, char **passwdp, int *methodp, int freeit)
+{
+ if (!freeit) {
+ ap_ldap_rebind_entry_t *my_conn;
+
+ *methodp = LDAP_AUTH_SIMPLE;
+ my_conn = ap_ldap_rebind_lookup(ld);
+
+ if ((my_conn) && (my_conn->bindDN != NULL)) {
+ *binddnp = strdup(my_conn->bindDN);
+ *passwdp = strdup(my_conn->bindPW);
+ } else {
+ *binddnp = NULL;
+ *passwdp = NULL;
+ }
+ } else {
+ if (*binddnp) {
+ free(*binddnp);
+ }
+ if (*passwdp) {
+ free(*passwdp);
+ }
+ }
+
+ return LDAP_SUCCESS;
+}
+
+static int ap_ldap_rebind_set_callback(LDAP *ld)
+{
+ ldap_set_rebind_proc(ld, (LDAPRebindProc)LDAP_rebindproc);
+ return APR_SUCCESS;
+}
+
+#elif AP_HAS_OPENLDAP_LDAPSDK
+
+/* LDAP_rebindproc() openLDAP V3 style
+ * ON ENTRY:
+ * ld Pointer to an LDAP control structure. (input only)
+ * url Unused in this routine
+ * request Unused in this routine
+ * msgid Unused in this routine
+ * params Unused in this routine
+ *
+ * or
+ *
+ * ld Pointer to an LDAP control structure. (input only)
+ * url Unused in this routine
+ * request Unused in this routine
+ * msgid Unused in this routine
+ */
+#if defined(LDAP_SET_REBIND_PROC_THREE)
+static int LDAP_rebindproc(LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
+ ber_int_t msgid, void *params)
+#else
+static int LDAP_rebindproc(LDAP *ld, LDAP_CONST char *url, int request,
+ ber_int_t msgid)
+#endif
+{
+ ap_ldap_rebind_entry_t *my_conn;
+ const char *bindDN = NULL;
+ const char *bindPW = NULL;
+
+ my_conn = ap_ldap_rebind_lookup(ld);
+
+ if ((my_conn) && (my_conn->bindDN != NULL)) {
+ bindDN = my_conn->bindDN;
+ bindPW = my_conn->bindPW;
+ }
+
+ return (ldap_bind_s(ld, bindDN, bindPW, LDAP_AUTH_SIMPLE));
+}
+
+static int ap_ldap_rebind_set_callback(LDAP *ld)
+{
+#if defined(LDAP_SET_REBIND_PROC_THREE)
+ ldap_set_rebind_proc(ld, LDAP_rebindproc, NULL);
+#else
+ ldap_set_rebind_proc(ld, LDAP_rebindproc);
+#endif
+ return APR_SUCCESS;
+}
+
+#elif AP_HAS_NOVELL_LDAPSDK
+
+/* LDAP_rebindproc() openLDAP V3 style
+ * ON ENTRY:
+ * ld Pointer to an LDAP control structure. (input only)
+ * url Unused in this routine
+ * request Unused in this routine
+ * msgid Unused in this routine
+ */
+static int LDAP_rebindproc(LDAP *ld, LDAP_CONST char *url, int request, ber_int_t msgid)
+{
+
+ ap_ldap_rebind_entry_t *my_conn;
+ const char *bindDN = NULL;
+ const char *bindPW = NULL;
+
+ my_conn = ap_ldap_rebind_lookup(ld);
+
+ if ((my_conn) && (my_conn->bindDN != NULL)) {
+ bindDN = my_conn->bindDN;
+ bindPW = my_conn->bindPW;
+ }
+
+ return (ldap_bind_s(ld, bindDN, bindPW, LDAP_AUTH_SIMPLE));
+}
+
+static int ap_ldap_rebind_set_callback(LDAP *ld)
+{
+ ldap_set_rebind_proc(ld, LDAP_rebindproc);
+ return APR_SUCCESS;
+}
+
+#else /* Implementation not recognised */
+
+static int ap_ldap_rebind_set_callback(LDAP *ld)
+{
+ return APR_ENOTIMPL;
+}
+
+#endif
+
+
+#endif /* AP_HAS_LDAP */
diff --git a/modules/ldap/ap_ldap_url.c b/modules/ldap/ap_ldap_url.c
new file mode 100644
index 0000000000..f1fe2166ee
--- /dev/null
+++ b/modules/ldap/ap_ldap_url.c
@@ -0,0 +1,695 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Portions Copyright 1998-2002 The OpenLDAP Foundation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License. A copy of this license is available at
+ * http://www.OpenLDAP.org/license.html or in file LICENSE in the
+ * top-level directory of the distribution.
+ *
+ * OpenLDAP is a registered trademark of the OpenLDAP Foundation.
+ *
+ * Individual files and/or contributed packages may be copyright by
+ * other parties and subject to additional restrictions.
+ *
+ * This work is derived from the University of Michigan LDAP v3.3
+ * distribution. Information concerning this software is available
+ * at: http://www.umich.edu/~dirsvcs/ldap/
+ *
+ * This work also contains materials derived from public sources.
+ *
+ * Additional information about OpenLDAP can be obtained at:
+ * http://www.openldap.org/
+ */
+
+/*
+ * Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of Michigan at Ann Arbor. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+/* ap_ldap_url.c -- LDAP URL (RFC 2255) related routines
+ *
+ * Win32 and perhaps other non-OpenLDAP based ldap libraries may be
+ * missing ldap_url_* APIs. We focus here on the one significant
+ * aspect, which is parsing. We have [for the time being] omitted
+ * the ldap_url_search APIs.
+ *
+ * LDAP URLs look like this:
+ * ldap[is]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]
+ *
+ * where:
+ * attributes is a comma separated list
+ * scope is one of these three strings: base one sub (default=base)
+ * filter is an string-represented filter as in RFC 2254
+ *
+ * e.g., ldap://host:port/dc=com?o,cn?base?o=openldap?extension
+ *
+ * Tolerates URLs that look like: <ldapurl> and <URL:ldapurl>
+ */
+
+#include "apu.h"
+#include "apr_pools.h"
+#include "apr_general.h"
+#include "apr_strings.h"
+#include "ap_config.h"
+#include "ap_ldap.h"
+
+#if AP_HAS_LDAP
+
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifndef LDAPS_PORT
+#define LDAPS_PORT 636 /* ldaps:/// default LDAP over TLS port */
+#endif
+
+#define AP_LDAP_URL_PREFIX "ldap://"
+#define AP_LDAP_URL_PREFIX_LEN (sizeof(AP_LDAP_URL_PREFIX)-1)
+#define AP_LDAPS_URL_PREFIX "ldaps://"
+#define AP_LDAPS_URL_PREFIX_LEN (sizeof(AP_LDAPS_URL_PREFIX)-1)
+#define AP_LDAPI_URL_PREFIX "ldapi://"
+#define AP_LDAPI_URL_PREFIX_LEN (sizeof(AP_LDAPI_URL_PREFIX)-1)
+#define AP_LDAP_URL_URLCOLON "URL:"
+#define AP_LDAP_URL_URLCOLON_LEN (sizeof(AP_LDAP_URL_URLCOLON)-1)
+
+
+/* local functions */
+static const char* skip_url_prefix(const char *url,
+ int *enclosedp,
+ const char **scheme);
+
+static void ap_ldap_pvt_hex_unescape(char *s);
+
+static int ap_ldap_pvt_unhex(int c);
+
+static char **ap_ldap_str2charray(apr_pool_t *pool,
+ const char *str,
+ const char *brkstr);
+
+
+/**
+ * Is this URL an ldap url?
+ *
+ */
+MODLDAP_DECLARE(int) ap_ldap_is_ldap_url(const char *url)
+{
+ int enclosed;
+ const char * scheme;
+
+ if( url == NULL ) {
+ return 0;
+ }
+
+ if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * Is this URL a secure ldap url?
+ *
+ */
+MODLDAP_DECLARE(int) ap_ldap_is_ldaps_url(const char *url)
+{
+ int enclosed;
+ const char * scheme;
+
+ if( url == NULL ) {
+ return 0;
+ }
+
+ if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
+ return 0;
+ }
+
+ return strcmp(scheme, "ldaps") == 0;
+}
+
+/**
+ * Is this URL an ldap socket url?
+ *
+ */
+MODLDAP_DECLARE(int) ap_ldap_is_ldapi_url(const char *url)
+{
+ int enclosed;
+ const char * scheme;
+
+ if( url == NULL ) {
+ return 0;
+ }
+
+ if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
+ return 0;
+ }
+
+ return strcmp(scheme, "ldapi") == 0;
+}
+
+
+static const char *skip_url_prefix(const char *url, int *enclosedp,
+ const char **scheme)
+{
+ /*
+ * return non-zero if this looks like a LDAP URL; zero if not
+ * if non-zero returned, *urlp will be moved past "ldap://" part of URL
+ */
+ const char *p;
+
+ if ( url == NULL ) {
+ return( NULL );
+ }
+
+ p = url;
+
+ /* skip leading '<' (if any) */
+ if ( *p == '<' ) {
+ *enclosedp = 1;
+ ++p;
+ } else {
+ *enclosedp = 0;
+ }
+
+ /* skip leading "URL:" (if any) */
+ if ( strncasecmp( p, AP_LDAP_URL_URLCOLON, AP_LDAP_URL_URLCOLON_LEN ) == 0 ) {
+ p += AP_LDAP_URL_URLCOLON_LEN;
+ }
+
+ /* check for "ldap://" prefix */
+ if ( strncasecmp( p, AP_LDAP_URL_PREFIX, AP_LDAP_URL_PREFIX_LEN ) == 0 ) {
+ /* skip over "ldap://" prefix and return success */
+ p += AP_LDAP_URL_PREFIX_LEN;
+ *scheme = "ldap";
+ return( p );
+ }
+
+ /* check for "ldaps://" prefix */
+ if ( strncasecmp( p, AP_LDAPS_URL_PREFIX, AP_LDAPS_URL_PREFIX_LEN ) == 0 ) {
+ /* skip over "ldaps://" prefix and return success */
+ p += AP_LDAPS_URL_PREFIX_LEN;
+ *scheme = "ldaps";
+ return( p );
+ }
+
+ /* check for "ldapi://" prefix */
+ if ( strncasecmp( p, AP_LDAPI_URL_PREFIX, AP_LDAPI_URL_PREFIX_LEN ) == 0 ) {
+ /* skip over "ldapi://" prefix and return success */
+ p += AP_LDAPI_URL_PREFIX_LEN;
+ *scheme = "ldapi";
+ return( p );
+ }
+
+ return( NULL );
+}
+
+
+static int str2scope(const char *p)
+{
+ if ( strcasecmp( p, "one" ) == 0 ) {
+ return LDAP_SCOPE_ONELEVEL;
+
+ } else if ( strcasecmp( p, "onetree" ) == 0 ) {
+ return LDAP_SCOPE_ONELEVEL;
+
+ } else if ( strcasecmp( p, "base" ) == 0 ) {
+ return LDAP_SCOPE_BASE;
+
+ } else if ( strcasecmp( p, "sub" ) == 0 ) {
+ return LDAP_SCOPE_SUBTREE;
+
+ } else if ( strcasecmp( p, "subtree" ) == 0 ) {
+ return LDAP_SCOPE_SUBTREE;
+ }
+
+ return( -1 );
+}
+
+
+/**
+ * Parse the URL provided into an ap_ldap_url_desc_t object.
+ *
+ * APR_SUCCESS is returned on success, APR_EGENERAL on failure.
+ * The LDAP result code and reason string is returned in the
+ * ap_ldap_err_t structure.
+ */
+MODLDAP_DECLARE(int) ap_ldap_url_parse_ext(apr_pool_t *pool,
+ const char *url_in,
+ ap_ldap_url_desc_t **ludpp,
+ ap_ldap_err_t **result_err)
+{
+ ap_ldap_url_desc_t *ludp;
+ char *p, *q, *r;
+ int i, enclosed;
+ const char *scheme = NULL;
+ const char *url_tmp;
+ char *url;
+
+ ap_ldap_err_t *result = (ap_ldap_err_t *)apr_pcalloc(pool, sizeof(ap_ldap_err_t));
+ *result_err = result;
+
+ /* sanity check our parameters */
+ if( url_in == NULL || ludpp == NULL ) {
+ result->reason = "Either the LDAP URL, or the URL structure was NULL. Oops.";
+ result->rc = AP_LDAP_URL_ERR_PARAM;
+ return APR_EGENERAL;
+ }
+
+ *ludpp = NULL; /* pessimistic */
+
+ url_tmp = skip_url_prefix( url_in, &enclosed, &scheme );
+ if ( url_tmp == NULL ) {
+ result->reason = "The scheme was not recognised as a valid LDAP URL scheme.";
+ result->rc = AP_LDAP_URL_ERR_BADSCHEME;
+ return APR_EGENERAL;
+ }
+
+ /* make working copy of the remainder of the URL */
+ url = (char *)apr_pstrdup(pool, url_tmp);
+ if ( url == NULL ) {
+ result->reason = "Out of memory parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_MEM;
+ return APR_EGENERAL;
+ }
+
+ if ( enclosed ) {
+ p = &url[strlen(url)-1];
+
+ if( *p != '>' ) {
+ result->reason = "Bad enclosure error while parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_BADENCLOSURE;
+ return APR_EGENERAL;
+ }
+
+ *p = '\0';
+ }
+
+ /* allocate return struct */
+ ludp = (ap_ldap_url_desc_t *)apr_pcalloc(pool, sizeof(ap_ldap_url_desc_t));
+ if ( ludp == NULL ) {
+ result->reason = "Out of memory parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_MEM;
+ return APR_EGENERAL;
+ }
+
+ ludp->lud_next = NULL;
+ ludp->lud_host = NULL;
+ ludp->lud_port = LDAP_PORT;
+ ludp->lud_dn = NULL;
+ ludp->lud_attrs = NULL;
+ ludp->lud_filter = NULL;
+ ludp->lud_scope = -1;
+ ludp->lud_filter = NULL;
+ ludp->lud_exts = NULL;
+
+ ludp->lud_scheme = (char *)apr_pstrdup(pool, scheme);
+ if ( ludp->lud_scheme == NULL ) {
+ result->reason = "Out of memory parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_MEM;
+ return APR_EGENERAL;
+ }
+
+ if( strcasecmp( ludp->lud_scheme, "ldaps" ) == 0 ) {
+ ludp->lud_port = LDAPS_PORT;
+ }
+
+ /* scan forward for '/' that marks end of hostport and begin. of dn */
+ p = strchr( url, '/' );
+
+ if( p != NULL ) {
+ /* terminate hostport; point to start of dn */
+ *p++ = '\0';
+ }
+
+ /* IPv6 syntax with [ip address]:port */
+ if ( *url == '[' ) {
+ r = strchr( url, ']' );
+ if ( r == NULL ) {
+ result->reason = "Bad LDAP URL while parsing IPV6 syntax.";
+ result->rc = AP_LDAP_URL_ERR_BADURL;
+ return APR_EGENERAL;
+ }
+ *r++ = '\0';
+ q = strrchr( r, ':' );
+ } else {
+ q = strrchr( url, ':' );
+ }
+
+ if ( q != NULL ) {
+ ap_ldap_pvt_hex_unescape( ++q );
+
+ if( *q == '\0' ) {
+ result->reason = "Bad LDAP URL while parsing.";
+ result->rc = AP_LDAP_URL_ERR_BADURL;
+ return APR_EGENERAL;
+ }
+
+ ludp->lud_port = atoi( q );
+ }
+
+ ap_ldap_pvt_hex_unescape( url );
+
+ /* If [ip address]:port syntax, url is [ip and we skip the [ */
+ ludp->lud_host = (char *)apr_pstrdup(pool, url + ( *url == '[' ));
+ if( ludp->lud_host == NULL ) {
+ result->reason = "Out of memory parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_MEM;
+ return APR_EGENERAL;
+ }
+
+ /*
+ * Kludge. ldap://111.222.333.444:389??cn=abc,o=company
+ *
+ * On early Novell releases, search references/referrals were returned
+ * in this format, i.e., the dn was kind of in the scope position,
+ * but the required slash is missing. The whole thing is illegal syntax,
+ * but we need to account for it. Fortunately it can't be confused with
+ * anything real.
+ */
+ if( (p == NULL) && (q != NULL) && ((q = strchr( q, '?')) != NULL)) {
+ q++;
+ /* ? immediately followed by question */
+ if( *q == '?') {
+ q++;
+ if( *q != '\0' ) {
+ /* parse dn part */
+ ap_ldap_pvt_hex_unescape( q );
+ ludp->lud_dn = (char *)apr_pstrdup(pool, q);
+ } else {
+ ludp->lud_dn = (char *)apr_pstrdup(pool, "");
+ }
+
+ if( ludp->lud_dn == NULL ) {
+ result->reason = "Out of memory parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_MEM;
+ return APR_EGENERAL;
+ }
+ }
+ }
+
+ if( p == NULL ) {
+ *ludpp = ludp;
+ return APR_SUCCESS;
+ }
+
+ /* scan forward for '?' that may marks end of dn */
+ q = strchr( p, '?' );
+
+ if( q != NULL ) {
+ /* terminate dn part */
+ *q++ = '\0';
+ }
+
+ if( *p != '\0' ) {
+ /* parse dn part */
+ ap_ldap_pvt_hex_unescape( p );
+ ludp->lud_dn = (char *)apr_pstrdup(pool, p);
+ } else {
+ ludp->lud_dn = (char *)apr_pstrdup(pool, "");
+ }
+
+ if( ludp->lud_dn == NULL ) {
+ result->reason = "Out of memory parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_MEM;
+ return APR_EGENERAL;
+ }
+
+ if( q == NULL ) {
+ /* no more */
+ *ludpp = ludp;
+ return APR_SUCCESS;
+ }
+
+ /* scan forward for '?' that may marks end of attributes */
+ p = q;
+ q = strchr( p, '?' );
+
+ if( q != NULL ) {
+ /* terminate attributes part */
+ *q++ = '\0';
+ }
+
+ if( *p != '\0' ) {
+ /* parse attributes */
+ ap_ldap_pvt_hex_unescape( p );
+ ludp->lud_attrs = ap_ldap_str2charray(pool, p, ",");
+
+ if( ludp->lud_attrs == NULL ) {
+ result->reason = "Bad attributes encountered while parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_BADATTRS;
+ return APR_EGENERAL;
+ }
+ }
+
+ if ( q == NULL ) {
+ /* no more */
+ *ludpp = ludp;
+ return APR_SUCCESS;
+ }
+
+ /* scan forward for '?' that may marks end of scope */
+ p = q;
+ q = strchr( p, '?' );
+
+ if( q != NULL ) {
+ /* terminate the scope part */
+ *q++ = '\0';
+ }
+
+ if( *p != '\0' ) {
+ /* parse the scope */
+ ap_ldap_pvt_hex_unescape( p );
+ ludp->lud_scope = str2scope( p );
+
+ if( ludp->lud_scope == -1 ) {
+ result->reason = "Bad scope encountered while parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_BADSCOPE;
+ return APR_EGENERAL;
+ }
+ }
+
+ if ( q == NULL ) {
+ /* no more */
+ *ludpp = ludp;
+ return APR_SUCCESS;
+ }
+
+ /* scan forward for '?' that may marks end of filter */
+ p = q;
+ q = strchr( p, '?' );
+
+ if( q != NULL ) {
+ /* terminate the filter part */
+ *q++ = '\0';
+ }
+
+ if( *p != '\0' ) {
+ /* parse the filter */
+ ap_ldap_pvt_hex_unescape( p );
+
+ if( ! *p ) {
+ /* missing filter */
+ result->reason = "Bad filter encountered while parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_BADFILTER;
+ return APR_EGENERAL;
+ }
+
+ ludp->lud_filter = (char *)apr_pstrdup(pool, p);
+ if( ludp->lud_filter == NULL ) {
+ result->reason = "Out of memory parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_MEM;
+ return APR_EGENERAL;
+ }
+ }
+
+ if ( q == NULL ) {
+ /* no more */
+ *ludpp = ludp;
+ return APR_SUCCESS;
+ }
+
+ /* scan forward for '?' that may marks end of extensions */
+ p = q;
+ q = strchr( p, '?' );
+
+ if( q != NULL ) {
+ /* extra '?' */
+ result->reason = "Bad URL encountered while parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_BADURL;
+ return APR_EGENERAL;
+ }
+
+ /* parse the extensions */
+ ludp->lud_exts = ap_ldap_str2charray(pool, p, ",");
+ if( ludp->lud_exts == NULL ) {
+ result->reason = "Bad extensions encountered while parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_BADEXTS;
+ return APR_EGENERAL;
+ }
+
+ for( i=0; ludp->lud_exts[i] != NULL; i++ ) {
+ ap_ldap_pvt_hex_unescape( ludp->lud_exts[i] );
+
+ if( *ludp->lud_exts[i] == '!' ) {
+ /* count the number of critical extensions */
+ ludp->lud_crit_exts++;
+ }
+ }
+
+ if( i == 0 ) {
+ /* must have 1 or more */
+ result->reason = "Bad extensions encountered while parsing LDAP URL.";
+ result->rc = AP_LDAP_URL_ERR_BADEXTS;
+ return APR_EGENERAL;
+ }
+
+ /* no more */
+ *ludpp = ludp;
+ return APR_SUCCESS;
+}
+
+
+/**
+ * Parse the URL provided into an ap_ldap_url_desc_t object.
+ *
+ * APR_SUCCESS is returned on success, APR_EGENERAL on failure.
+ * The LDAP result code and reason string is returned in the
+ * ap_ldap_err_t structure.
+ */
+MODLDAP_DECLARE(int) ap_ldap_url_parse(apr_pool_t *pool,
+ const char *url_in,
+ ap_ldap_url_desc_t **ludpp,
+ ap_ldap_err_t **result_err)
+{
+
+ int rc = ap_ldap_url_parse_ext(pool, url_in, ludpp, result_err);
+ if( rc != APR_SUCCESS ) {
+ return rc;
+ }
+
+ if ((*ludpp)->lud_scope == -1) {
+ (*ludpp)->lud_scope = LDAP_SCOPE_BASE;
+ }
+
+ if ((*ludpp)->lud_host != NULL && *(*ludpp)->lud_host == '\0') {
+ (*ludpp)->lud_host = NULL;
+ }
+
+ return rc;
+
+}
+
+
+static void ap_ldap_pvt_hex_unescape(char *s)
+{
+ /*
+ * Remove URL hex escapes from s... done in place. The basic concept for
+ * this routine is borrowed from the WWW library HTUnEscape() routine.
+ */
+ char *p;
+
+ for ( p = s; *s != '\0'; ++s ) {
+ if ( *s == '%' ) {
+ if ( *++s == '\0' ) {
+ break;
+ }
+ *p = ap_ldap_pvt_unhex( *s ) << 4;
+ if ( *++s == '\0' ) {
+ break;
+ }
+ *p++ += ap_ldap_pvt_unhex( *s );
+ } else {
+ *p++ = *s;
+ }
+ }
+
+ *p = '\0';
+}
+
+
+static int ap_ldap_pvt_unhex(int c)
+{
+ return( c >= '0' && c <= '9' ? c - '0'
+ : c >= 'A' && c <= 'F' ? c - 'A' + 10
+ : c - 'a' + 10 );
+}
+
+
+/**
+ * Convert a string to a character array
+ */
+static char **ap_ldap_str2charray(apr_pool_t *pool,
+ const char *str_in,
+ const char *brkstr)
+{
+ char **res;
+ char *str, *s;
+ char *lasts;
+ int i;
+
+ /* protect the input string from strtok */
+ str = (char *)apr_pstrdup(pool, str_in);
+ if( str == NULL ) {
+ return NULL;
+ }
+
+ i = 1;
+ for ( s = str; *s; s++ ) {
+ /* Warning: this strchr was previously ldap_utf8_strchr(), check
+ * whether this particular code has any charset issues.
+ */
+ if ( strchr( brkstr, *s ) != NULL ) {
+ i++;
+ }
+ }
+
+ res = (char **) apr_pcalloc(pool, (i + 1) * sizeof(char *));
+ if( res == NULL ) {
+ return NULL;
+ }
+
+ i = 0;
+
+ for ( s = (char *)apr_strtok( str, brkstr, &lasts );
+ s != NULL;
+ s = (char *)apr_strtok( NULL, brkstr, &lasts ) ) {
+
+ res[i] = (char *)apr_pstrdup(pool, s);
+ if(res[i] == NULL) {
+ return NULL;
+ }
+
+ i++;
+ }
+
+ res[i] = NULL;
+
+ return( res );
+
+}
+
+#endif /* AP_HAS_LDAP */
diff --git a/modules/ldap/config.m4 b/modules/ldap/config.m4
index f962dda2d7..014560dbbd 100644
--- a/modules/ldap/config.m4
+++ b/modules/ldap/config.m4
@@ -3,12 +3,22 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
APACHE_MODPATH_INIT(ldap)
-ldap_objects="util_ldap.lo util_ldap_cache.lo util_ldap_cache_mgr.lo"
+ldap_objects="dnl
+util_ldap.lo dnl
+util_ldap_cache.lo dnl
+util_ldap_cache_mgr.lo dnl
+ap_ldap_init.lo dnl
+ap_ldap_option.lo dnl
+ap_ldap_rebind.lo dnl
+ap_ldap_url.lo dnl
+"
+
APACHE_MODULE(ldap, LDAP caching and connection pooling services, $ldap_objects, , no, [
+ AP_FIND_LDAP
if test -z "$apu_config" ; then
- MOD_LDAP_LDADD="`$apr_config --ldap-libs`"
+ MOD_LDAP_LDADD="$LDADD_ldap"
else
- MOD_LDAP_LDADD="`$apu_config --ldap-libs`"
+ MOD_LDAP_LDADD="$LDADD_ldap"
fi
AC_SUBST(MOD_LDAP_LDADD)
])
diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c
index d774f383cb..b81efd61d3 100644
--- a/modules/ldap/util_ldap.c
+++ b/modules/ldap/util_ldap.c
@@ -38,17 +38,8 @@
#include <unistd.h>
#endif
-#if !APR_HAS_LDAP
-#error mod_ldap requires APR-util to have LDAP support built in
-#endif
-
-/* Default define for ldap functions that need a SIZELIMIT but
- * do not have the define
- * XXX This should be removed once a supporting #define is
- * released through APR-Util.
- */
-#ifndef APR_LDAP_SIZELIMIT
-#define APR_LDAP_SIZELIMIT -1
+#if !AP_HAS_LDAP
+#error mod_ldap requires httpd to detect LDAP support
#endif
#ifdef LDAP_OPT_DEBUG_LEVEL
@@ -181,7 +172,7 @@ static apr_status_t uldap_connection_unbind(void *param)
/* forget the rebind info for this conn */
if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
- apr_ldap_rebind_remove(ldc->ldap);
+ ap_ldap_rebind_remove(ldc->ldap);
apr_pool_clear(ldc->rebind_pool);
}
}
@@ -251,7 +242,7 @@ static int uldap_connection_init(request_rec *r,
{
int rc = 0, ldap_option = 0;
int version = LDAP_VERSION3;
- apr_ldap_err_t *result = NULL;
+ ap_ldap_err_t *result = NULL;
#ifdef LDAP_OPT_NETWORK_TIMEOUT
struct timeval connectionTimeout = {10,0}; /* 10 second connection timeout */
#endif
@@ -265,10 +256,10 @@ static int uldap_connection_init(request_rec *r,
* some hosts with ports and some without. All hosts which do not
* specify a port will use the default port.
*/
- apr_ldap_init(r->pool, &(ldc->ldap),
+ ap_ldap_init(r->pool, &(ldc->ldap),
ldc->host,
- APR_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT,
- APR_LDAP_NONE,
+ AP_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT,
+ AP_LDAP_NONE,
&(result));
if (NULL == result) {
@@ -300,7 +291,7 @@ static int uldap_connection_init(request_rec *r,
if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
/* Now that we have an ldap struct, add it to the referral list for rebinds. */
- rc = apr_ldap_rebind_add(ldc->rebind_pool, ldc->ldap, ldc->binddn, ldc->bindpw);
+ rc = ap_ldap_rebind_add(ldc->rebind_pool, ldc->ldap, ldc->binddn, ldc->bindpw);
if (rc != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server,
"LDAP: Unable to add rebind cross reference entry. Out of memory?");
@@ -315,7 +306,7 @@ static int uldap_connection_init(request_rec *r,
/* set client certificates */
if (!apr_is_empty_array(ldc->client_certs)) {
- apr_ldap_set_option(r->pool, ldc->ldap, APR_LDAP_OPT_TLS_CERT,
+ ap_ldap_set_option(r->pool, ldc->ldap, AP_LDAP_OPT_TLS_CERT,
ldc->client_certs, &(result));
if (LDAP_SUCCESS != result->rc) {
uldap_connection_unbind( ldc );
@@ -325,9 +316,9 @@ static int uldap_connection_init(request_rec *r,
}
/* switch on SSL/TLS */
- if (APR_LDAP_NONE != ldc->secure) {
- apr_ldap_set_option(r->pool, ldc->ldap,
- APR_LDAP_OPT_TLS, &ldc->secure, &(result));
+ if (AP_LDAP_NONE != ldc->secure) {
+ ap_ldap_set_option(r->pool, ldc->ldap,
+ AP_LDAP_OPT_TLS, &ldc->secure, &(result));
if (LDAP_SUCCESS != result->rc) {
uldap_connection_unbind( ldc );
ldc->reason = result->reason;
@@ -344,8 +335,8 @@ static int uldap_connection_init(request_rec *r,
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"LDAP: Setting referrals to %s.",
((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ? "On" : "Off"));
- apr_ldap_set_option(r->pool, ldc->ldap,
- APR_LDAP_OPT_REFERRALS,
+ ap_ldap_set_option(r->pool, ldc->ldap,
+ AP_LDAP_OPT_REFERRALS,
(void *)((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ?
LDAP_OPT_ON : LDAP_OPT_OFF),
&(result));
@@ -365,8 +356,8 @@ static int uldap_connection_init(request_rec *r,
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"Setting referral hop limit to %d.",
ldc->ReferralHopLimit);
- apr_ldap_set_option(r->pool, ldc->ldap,
- APR_LDAP_OPT_REFHOPLIMIT,
+ ap_ldap_set_option(r->pool, ldc->ldap,
+ AP_LDAP_OPT_REFHOPLIMIT,
(void *)&ldc->ReferralHopLimit,
&(result));
if (result->rc != LDAP_SUCCESS) {
@@ -382,31 +373,8 @@ static int uldap_connection_init(request_rec *r,
}
}
-/*XXX All of the #ifdef's need to be removed once apr-util 1.2 is released */
-#ifdef APR_LDAP_OPT_VERIFY_CERT
- apr_ldap_set_option(r->pool, ldc->ldap, APR_LDAP_OPT_VERIFY_CERT,
+ ap_ldap_set_option(r->pool, ldc->ldap, AP_LDAP_OPT_VERIFY_CERT,
&(st->verify_svr_cert), &(result));
-#else
-#if defined(LDAPSSL_VERIFY_SERVER)
- if (st->verify_svr_cert) {
- result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_SERVER);
- }
- else {
- result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_NONE);
- }
-#elif defined(LDAP_OPT_X_TLS_REQUIRE_CERT)
- /* This is not a per-connection setting so just pass NULL for the
- Ldap connection handle */
- if (st->verify_svr_cert) {
- int i = LDAP_OPT_X_TLS_DEMAND;
- result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
- }
- else {
- int i = LDAP_OPT_X_TLS_NEVER;
- result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
- }
-#endif
-#endif
#ifdef LDAP_OPT_NETWORK_TIMEOUT
if (st->connectionTimeout > 0) {
@@ -414,7 +382,7 @@ static int uldap_connection_init(request_rec *r,
}
if (st->connectionTimeout >= 0) {
- rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_NETWORK_TIMEOUT,
+ rc = ap_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_NETWORK_TIMEOUT,
(void *)&connectionTimeout, &(result));
if (APR_SUCCESS != rc) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
@@ -433,7 +401,7 @@ static int uldap_connection_init(request_rec *r,
* XXX: ldap_result() with a timeout.
*/
if (st->opTimeout) {
- rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_TIMEOUT,
+ rc = ap_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_TIMEOUT,
st->opTimeout, &(result));
if (APR_SUCCESS != rc) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
@@ -588,7 +556,7 @@ static int compare_client_certs(apr_array_header_t *srcs,
apr_array_header_t *dests)
{
int i = 0;
- struct apr_ldap_opt_tls_cert_t *src, *dest;
+ struct ap_ldap_opt_tls_cert_t *src, *dest;
/* arrays both NULL? if so, then equal */
if (srcs == NULL && dests == NULL) {
@@ -601,8 +569,8 @@ static int compare_client_certs(apr_array_header_t *srcs,
}
/* run an actual comparison */
- src = (struct apr_ldap_opt_tls_cert_t *)srcs->elts;
- dest = (struct apr_ldap_opt_tls_cert_t *)dests->elts;
+ src = (struct ap_ldap_opt_tls_cert_t *)srcs->elts;
+ dest = (struct ap_ldap_opt_tls_cert_t *)dests->elts;
for (i = 0; i < srcs->nelts; i++) {
if ((strcmp(src[i].path, dest[i].path)) ||
(src[i].type != dest[i].type) ||
@@ -649,7 +617,7 @@ static util_ldap_connection_t *
apr_thread_mutex_lock(st->mutex);
#endif
- if (secure < APR_LDAP_NONE) {
+ if (secure < AP_LDAP_NONE) {
secureflag = st->secure;
}
@@ -763,7 +731,7 @@ static util_ldap_connection_t *
l->ReferralHopLimit = dc->ReferralHopLimit;
/* The security mode after parsing the URL will always be either
- * APR_LDAP_NONE (ldap://) or APR_LDAP_SSL (ldaps://).
+ * AP_LDAP_NONE (ldap://) or AP_LDAP_SSL (ldaps://).
* If the security setting is NONE, override it to the security
* setting optionally supplied by the admin using LDAPTrustedMode
*/
@@ -885,7 +853,7 @@ start_over:
/* search for reqdn */
result = ldap_search_ext_s(ldc->ldap, (char *)reqdn, LDAP_SCOPE_BASE,
"(objectclass=*)", NULL, 1,
- NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
+ NULL, NULL, st->opTimeout, AP_LDAP_SIZELIMIT, &res);
if (AP_LDAP_IS_SERVER_DOWN(result))
{
ldc->reason = "DN Comparison ldap_search_ext_s() "
@@ -1144,7 +1112,7 @@ start_over:
/* try to do the search */
result = ldap_search_ext_s(ldc->ldap, (char *)dn, LDAP_SCOPE_BASE,
(char *)"cn=*", subgroupAttrs, 0,
- NULL, NULL, NULL, APR_LDAP_SIZELIMIT, &sga_res);
+ NULL, NULL, NULL, AP_LDAP_SIZELIMIT, &sga_res);
if (AP_LDAP_IS_SERVER_DOWN(result)) {
ldc->reason = "ldap_search_ext_s() for subgroups failed with server"
" down";
@@ -1615,7 +1583,7 @@ start_over:
result = ldap_search_ext_s(ldc->ldap,
(char *)basedn, scope,
(char *)filter, attrs, 0,
- NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
+ NULL, NULL, st->opTimeout, AP_LDAP_SIZELIMIT, &res);
if (AP_LDAP_IS_SERVER_DOWN(result))
{
ldc->reason = "ldap_search_ext_s() for user failed with server down";
@@ -1866,7 +1834,7 @@ start_over:
result = ldap_search_ext_s(ldc->ldap,
(char *)basedn, scope,
(char *)filter, attrs, 0,
- NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
+ NULL, NULL, st->opTimeout, AP_LDAP_SIZELIMIT, &res);
if (AP_LDAP_IS_SERVER_DOWN(result))
{
ldc->reason = "ldap_search_ext_s() for user failed with server down";
@@ -2136,72 +2104,72 @@ static const char *util_ldap_set_opcache_entries(cmd_parms *cmd, void *dummy,
* CA_DER, CA_BASE64, CA_CERT7_DB, CA_SECMOD, CERT_DER, CERT_BASE64,
* CERT_KEY3_DB, CERT_NICKNAME, KEY_DER, KEY_BASE64
*
- * If no matches are found, APR_LDAP_CA_TYPE_UNKNOWN is returned.
+ * If no matches are found, AP_LDAP_CA_TYPE_UNKNOWN is returned.
*/
static int util_ldap_parse_cert_type(const char *type)
{
/* Authority file in binary DER format */
if (0 == strcasecmp("CA_DER", type)) {
- return APR_LDAP_CA_TYPE_DER;
+ return AP_LDAP_CA_TYPE_DER;
}
/* Authority file in Base64 format */
else if (0 == strcasecmp("CA_BASE64", type)) {
- return APR_LDAP_CA_TYPE_BASE64;
+ return AP_LDAP_CA_TYPE_BASE64;
}
/* Netscape certificate database file/directory */
else if (0 == strcasecmp("CA_CERT7_DB", type)) {
- return APR_LDAP_CA_TYPE_CERT7_DB;
+ return AP_LDAP_CA_TYPE_CERT7_DB;
}
/* Netscape secmod file/directory */
else if (0 == strcasecmp("CA_SECMOD", type)) {
- return APR_LDAP_CA_TYPE_SECMOD;
+ return AP_LDAP_CA_TYPE_SECMOD;
}
/* Client cert file in DER format */
else if (0 == strcasecmp("CERT_DER", type)) {
- return APR_LDAP_CERT_TYPE_DER;
+ return AP_LDAP_CERT_TYPE_DER;
}
/* Client cert file in Base64 format */
else if (0 == strcasecmp("CERT_BASE64", type)) {
- return APR_LDAP_CERT_TYPE_BASE64;
+ return AP_LDAP_CERT_TYPE_BASE64;
}
/* Client cert file in PKCS#12 format */
else if (0 == strcasecmp("CERT_PFX", type)) {
- return APR_LDAP_CERT_TYPE_PFX;
+ return AP_LDAP_CERT_TYPE_PFX;
}
/* Netscape client cert database file/directory */
else if (0 == strcasecmp("CERT_KEY3_DB", type)) {
- return APR_LDAP_CERT_TYPE_KEY3_DB;
+ return AP_LDAP_CERT_TYPE_KEY3_DB;
}
/* Netscape client cert nickname */
else if (0 == strcasecmp("CERT_NICKNAME", type)) {
- return APR_LDAP_CERT_TYPE_NICKNAME;
+ return AP_LDAP_CERT_TYPE_NICKNAME;
}
/* Client cert key file in DER format */
else if (0 == strcasecmp("KEY_DER", type)) {
- return APR_LDAP_KEY_TYPE_DER;
+ return AP_LDAP_KEY_TYPE_DER;
}
/* Client cert key file in Base64 format */
else if (0 == strcasecmp("KEY_BASE64", type)) {
- return APR_LDAP_KEY_TYPE_BASE64;
+ return AP_LDAP_KEY_TYPE_BASE64;
}
/* Client cert key file in PKCS#12 format */
else if (0 == strcasecmp("KEY_PFX", type)) {
- return APR_LDAP_KEY_TYPE_PFX;
+ return AP_LDAP_KEY_TYPE_PFX;
}
else {
- return APR_LDAP_CA_TYPE_UNKNOWN;
+ return AP_LDAP_CA_TYPE_UNKNOWN;
}
}
@@ -2230,7 +2198,7 @@ static const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd,
apr_finfo_t finfo;
apr_status_t rv;
int cert_type = 0;
- apr_ldap_opt_tls_cert_t *cert;
+ ap_ldap_opt_tls_cert_t *cert;
if (err != NULL) {
return err;
@@ -2239,7 +2207,7 @@ static const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd,
/* handle the certificate type */
if (type) {
cert_type = util_ldap_parse_cert_type(type);
- if (APR_LDAP_CA_TYPE_UNKNOWN == cert_type) {
+ if (AP_LDAP_CA_TYPE_UNKNOWN == cert_type) {
return apr_psprintf(cmd->pool, "The certificate type %s is "
"not recognised. It should be one "
"of CA_DER, CA_BASE64, CA_CERT7_DB, "
@@ -2257,14 +2225,14 @@ static const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd,
file, type);
/* add the certificate to the global array */
- cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(st->global_certs);
+ cert = (ap_ldap_opt_tls_cert_t *)apr_array_push(st->global_certs);
cert->type = cert_type;
cert->path = file;
cert->password = password;
/* if file is a file or path, fix the path */
- if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
- cert_type != APR_LDAP_CERT_TYPE_NICKNAME) {
+ if (cert_type != AP_LDAP_CA_TYPE_UNKNOWN &&
+ cert_type != AP_LDAP_CERT_TYPE_NICKNAME) {
cert->path = ap_server_root_relative(cmd->pool, file);
if (cert->path &&
@@ -2301,12 +2269,12 @@ static const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd,
apr_finfo_t finfo;
apr_status_t rv;
int cert_type = 0;
- apr_ldap_opt_tls_cert_t *cert;
+ ap_ldap_opt_tls_cert_t *cert;
/* handle the certificate type */
if (type) {
cert_type = util_ldap_parse_cert_type(type);
- if (APR_LDAP_CA_TYPE_UNKNOWN == cert_type) {
+ if (AP_LDAP_CA_TYPE_UNKNOWN == cert_type) {
return apr_psprintf(cmd->pool, "The certificate type \"%s\" is "
"not recognised. It should be one "
"of CA_DER, CA_BASE64, "
@@ -2315,10 +2283,10 @@ static const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd,
"KEY_DER, KEY_BASE64, KEY_PFX",
type);
}
- else if ( APR_LDAP_CA_TYPE_CERT7_DB == cert_type ||
- APR_LDAP_CA_TYPE_SECMOD == cert_type ||
- APR_LDAP_CERT_TYPE_PFX == cert_type ||
- APR_LDAP_CERT_TYPE_KEY3_DB == cert_type) {
+ else if ( AP_LDAP_CA_TYPE_CERT7_DB == cert_type ||
+ AP_LDAP_CA_TYPE_SECMOD == cert_type ||
+ AP_LDAP_CERT_TYPE_PFX == cert_type ||
+ AP_LDAP_CERT_TYPE_KEY3_DB == cert_type) {
return apr_psprintf(cmd->pool, "The certificate type \"%s\" is "
"only valid within a "
"LDAPTrustedGlobalCert directive. "
@@ -2337,14 +2305,14 @@ static const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd,
file, type);
/* add the certificate to the client array */
- cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(dc->client_certs);
+ cert = (ap_ldap_opt_tls_cert_t *)apr_array_push(dc->client_certs);
cert->type = cert_type;
cert->path = file;
cert->password = password;
/* if file is a file or path, fix the path */
- if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
- cert_type != APR_LDAP_CERT_TYPE_NICKNAME) {
+ if (cert_type != AP_LDAP_CA_TYPE_UNKNOWN &&
+ cert_type != AP_LDAP_CERT_TYPE_NICKNAME) {
cert->path = ap_server_root_relative(cmd->pool, file);
if (cert->path &&
@@ -2384,14 +2352,14 @@ static const char *util_ldap_set_trusted_mode(cmd_parms *cmd, void *dummy,
mode);
if (0 == strcasecmp("NONE", mode)) {
- st->secure = APR_LDAP_NONE;
+ st->secure = AP_LDAP_NONE;
}
else if (0 == strcasecmp("SSL", mode)) {
- st->secure = APR_LDAP_SSL;
+ st->secure = AP_LDAP_SSL;
}
else if ( (0 == strcasecmp("TLS", mode))
|| (0 == strcasecmp("STARTTLS", mode))) {
- st->secure = APR_LDAP_STARTTLS;
+ st->secure = AP_LDAP_STARTTLS;
}
else {
return "Invalid LDAPTrustedMode setting: must be one of NONE, "
@@ -2515,7 +2483,7 @@ static void *util_ldap_create_dir_config(apr_pool_t *p, char *d) {
(util_ldap_config_t *) apr_pcalloc(p,sizeof(util_ldap_config_t));
/* defaults are AP_LDAP_CHASEREFERRALS_ON and AP_LDAP_DEFAULT_HOPLIMIT */
- dc->client_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t));
+ dc->client_certs = apr_array_make(p, 10, sizeof(ap_ldap_opt_tls_cert_t));
dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_ON;
dc->ReferralHopLimit = AP_LDAP_HOPLIMIT_UNSET;
@@ -2614,8 +2582,8 @@ static void *util_ldap_create_config(apr_pool_t *p, server_rec *s)
st->compare_cache_size = 1024;
st->connections = NULL;
st->ssl_supported = 0;
- st->global_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t));
- st->secure = APR_LDAP_NONE;
+ st->global_certs = apr_array_make(p, 10, sizeof(ap_ldap_opt_tls_cert_t));
+ st->secure = AP_LDAP_NONE;
st->secure_set = 0;
st->connectionTimeout = 10;
st->opTimeout = apr_pcalloc(p, sizeof(struct timeval));
@@ -2687,7 +2655,7 @@ static apr_status_t util_ldap_cleanup_module(void *data)
s->module_config, &ldap_module);
if (st->ssl_supported) {
- apr_ldap_ssl_deinit();
+ ap_ldap_ssl_deinit();
}
return APR_SUCCESS;
@@ -2719,7 +2687,7 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
ap_get_module_config(s->module_config,
&ldap_module);
- apr_ldap_err_t *result_err = NULL;
+ ap_ldap_err_t *result_err = NULL;
int rc;
/* util_ldap_post_config() will be called twice. Don't bother
@@ -2792,8 +2760,8 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
/* log the LDAP SDK used
*/
{
- apr_ldap_err_t *result = NULL;
- apr_ldap_info(p, &(result));
+ ap_ldap_err_t *result = NULL;
+ ap_ldap_info(p, &(result));
if (result != NULL) {
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "%s", result->reason);
}
@@ -2808,12 +2776,12 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
* If SSL is not supported it is not necessarily an error, as the
* application may not want to use it.
*/
- rc = apr_ldap_ssl_init(p,
+ rc = ap_ldap_ssl_init(p,
NULL,
0,
&(result_err));
if (APR_SUCCESS == rc) {
- rc = apr_ldap_set_option(ptemp, NULL, APR_LDAP_OPT_TLS_CERT,
+ rc = ap_ldap_set_option(ptemp, NULL, AP_LDAP_OPT_TLS_CERT,
(void *)st->global_certs, &(result_err));
}
@@ -2831,7 +2799,7 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
}
/* Initialize the rebind callback's cross reference list. */
- apr_ldap_rebind_init (p);
+ ap_ldap_rebind_init (p);
#ifdef AP_LDAP_OPT_DEBUG
if (st->debug_level > 0) {
diff --git a/modules/ldap/util_ldap_cache.c b/modules/ldap/util_ldap_cache.c
index 87642e114a..19b62f2a68 100644
--- a/modules/ldap/util_ldap_cache.c
+++ b/modules/ldap/util_ldap_cache.c
@@ -27,7 +27,7 @@
#include "util_ldap_cache.h"
#include <apr_strings.h>
-#if APR_HAS_LDAP
+#if AP_HAS_LDAP
/* ------------------------------------------------------------------ */
@@ -461,4 +461,4 @@ apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st)
}
-#endif /* APR_HAS_LDAP */
+#endif /* AP_HAS_LDAP */
diff --git a/modules/ldap/util_ldap_cache.h b/modules/ldap/util_ldap_cache.h
index 4c63e6059a..5d6b216064 100644
--- a/modules/ldap/util_ldap_cache.h
+++ b/modules/ldap/util_ldap_cache.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef APU_LDAP_CACHE_H
-#define APU_LDAP_CACHE_H
+#ifndef AP_LDAP_CACHE_H
+#define AP_LDAP_CACHE_H
/**
* @file util_ldap_cache.h
@@ -23,7 +23,7 @@
*/
/* this whole thing disappears if LDAP is not enabled */
-#if APR_HAS_LDAP
+#if AP_HAS_LDAP
/*
@@ -200,5 +200,5 @@ void *util_ald_cache_insert(util_ald_cache_t *cache, void *payload);
void util_ald_cache_remove(util_ald_cache_t *cache, void *payload);
char *util_ald_cache_display_stats(request_rec *r, util_ald_cache_t *cache, char *name, char *id);
-#endif /* APR_HAS_LDAP */
-#endif /* APU_LDAP_CACHE_H */
+#endif /* AP_HAS_LDAP */
+#endif /* AP_LDAP_CACHE_H */
diff --git a/modules/ldap/util_ldap_cache_mgr.c b/modules/ldap/util_ldap_cache_mgr.c
index 1998c13e0b..948b86ce45 100644
--- a/modules/ldap/util_ldap_cache_mgr.c
+++ b/modules/ldap/util_ldap_cache_mgr.c
@@ -29,7 +29,7 @@
APLOG_USE_MODULE(ldap);
-#if APR_HAS_LDAP
+#if AP_HAS_LDAP
/* only here until strdup is gone */
#include <string.h>
@@ -877,4 +877,4 @@ char *util_ald_cache_display(request_rec *r, util_ldap_state_t *st)
return buf;
}
-#endif /* APR_HAS_LDAP */
+#endif /* AP_HAS_LDAP */