Hi all,
This is a patch for httpd that adds support for ldapi:// URLs to mod_ldap and friends.
It depends on a patch for apr-util posted to the dev@apr list.
Regards,
Graham
—
Index: include/util_ldap.h
===================================================================
--- include/util_ldap.h (revision 1909117)
+++ include/util_ldap.h (working copy)
@@ -45,6 +45,10 @@
/* this whole thing disappears if LDAP is not enabled */
#if APR_HAS_LDAP
+#ifndef APR_HAS_LDAP_INITIALIZE
+#define APR_HAS_LDAP_INITIALIZE 0
+#endif
+
#if defined(LDAP_UNAVAILABLE) || APR_HAS_MICROSOFT_LDAPSDK
#define AP_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN \
||(s) == LDAP_UNAVAILABLE)
@@ -126,8 +130,8 @@
const char *reason; /* Reason for an error failure */
struct util_ldap_connection_t *next;
- struct util_ldap_state_t *st; /* The LDAP vhost config this connection belongs to */
- int keep; /* Will this connection be kept when it's unlocked */
+ struct util_ldap_state_t *st; /* The LDAP vhost config this connection belongs to */
+ int keep; /* Will this connection be kept when it's unlocked */
int ChaseReferrals; /* [on|off] (default = AP_LDAP_CHASEREFERRALS_ON)*/
int ReferralHopLimit; /* # of referral hops to follow (default = AP_LDAP_DEFAULT_HOPLIMIT) */
@@ -136,6 +140,12 @@
int must_rebind; /* The connection was last bound with other then binddn/bindpw */
request_rec *r; /* request_rec used to find this util_ldap_connection_t */
apr_time_t last_backend_conn; /* the approximate time of the last backend LDAP request */
+
+#if APR_HAS_LDAP_INITIALIZE
+ apr_ldap_err_t result; /* result of prior operations on this connection */
+ const char *url; /* URL of the LDAP server (or space separated list) */
+ apr_ldap_t *ld;
+#endif
} util_ldap_connection_t;
typedef struct util_ldap_config_t {
@@ -241,6 +251,7 @@
* @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)
+ * @deprecated Replaced by uldap_connection_find_ex()
*/
APR_DECLARE_OPTIONAL_FN(util_ldap_connection_t *,uldap_connection_find,(request_rec *r, const char *host, int port,
const char *binddn, const char *bindpw, deref_options deref,
@@ -247,6 +258,26 @@
int secure));
/**
+ * Find a connection in a list of connections
+ * @param r The request record
+ * @param url The URL to connect to (multiple URLs space separated)
+ * @param binddn The DN to bind with
+ * @param bindpw The password to bind with
+ * @param deref The dereferencing behavior
+ * @param secure use SSL on the connection
+ * @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.
+ * @fn util_ldap_connection_t *util_ldap_connection_find_ex(request_rec *r, const char *url,
+ * const char *binddn, const char *bindpw, deref_options deref,
+ * int netscapessl, int starttls)
+ */
+APR_DECLARE_OPTIONAL_FN(util_ldap_connection_t *,uldap_connection_find_ex,(request_rec *r, const char *url,
+ const char *binddn, const char *bindpw, deref_options deref,
+ int secure));
+
+/**
* Compare two DNs for sameness
* @param r The request record
* @param ldc The LDAP connection being used.
Index: modules/aaa/mod_authnz_ldap.c
===================================================================
--- modules/aaa/mod_authnz_ldap.c (revision 1909117)
+++ modules/aaa/mod_authnz_ldap.c (working copy)
@@ -104,7 +104,7 @@
module AP_MODULE_DECLARE_DATA authnz_ldap_module;
static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close;
-static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find;
+static APR_OPTIONAL_FN_TYPE(uldap_connection_find_ex) *util_ldap_connection_find_ex;
static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn;
static APR_OPTIONAL_FN_TYPE(uldap_cache_compare) *util_ldap_cache_compare;
static APR_OPTIONAL_FN_TYPE(uldap_cache_check_subgroups) *util_ldap_cache_check_subgroups;
@@ -453,9 +453,7 @@
bindpw = req->password;
}
- return util_ldap_connection_find(r, sec->host, sec->port,
- binddn, bindpw,
- sec->deref, sec->secure);
+ return util_ldap_connection_find_ex(r, sec->url, binddn, bindpw, sec->deref, sec->secure);
}
/*
* Authentication Phase
@@ -527,7 +525,7 @@
}
/* There is a good AuthLDAPURL, right? */
- if (sec->host) {
+ if (sec->url) {
const char *binddn = sec->binddn;
const char *bindpw = sec->bindpw;
if (sec->initial_bind_as_user) {
@@ -535,13 +533,13 @@
binddn = ldap_determine_binddn(r, user);
}
- ldc = util_ldap_connection_find(r, sec->host, sec->port,
- binddn, bindpw,
- sec->deref, sec->secure);
+ ldc = util_ldap_connection_find_ex(r, sec->url,
+ binddn, bindpw,
+ sec->deref, sec->secure);
}
else {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01690)
- "auth_ldap authenticate: no sec->host - weird...?");
+ "auth_ldap authenticate: no sec->url - weird...?");
return AUTH_GENERAL_ERROR;
}
@@ -1436,13 +1434,14 @@
* host and port.
*/
static const char *mod_auth_ldap_parse_url(cmd_parms *cmd,
- void *config,
- const char *url,
- const char *mode)
+ void *config,
+ const char *url,
+ const char *mode)
{
- int rc;
+ int rc, i;
apr_ldap_url_desc_t *urld;
apr_ldap_err_t *result;
+ const char *end = url;
authn_ldap_config_t *sec = config;
@@ -1450,8 +1449,18 @@
if (rc != APR_SUCCESS) {
return result->reason;
}
- sec->url = apr_pstrdup(cmd->pool, url);
+ /* isolate the host/port part of the URL */
+ for (i = 0; end && i < 3; i++) {
+ end = strchr((char *)end + 1, '/');
+ }
+ if (end) {
+ sec->url = apr_pstrndup(cmd->pool, url, end - url);
+ }
+ else {
+ sec->url = apr_pstrdup(cmd->pool, url);
+ }
+
/* Set all the values, or at least some sane defaults */
if (sec->host) {
sec->host = apr_pstrcat(cmd->pool, urld->lud_host, " ", sec->host, NULL);
@@ -1528,9 +1537,10 @@
sec->have_ldap_url = 1;
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, cmd->server,
- "auth_ldap url parse: `%s', Host: %s, Port: %d, DN: %s, "
+ "auth_ldap url parse: `%s', Url: %s, Host: %s, Port: %d, DN: %s, "
"attrib: %s, scope: %s, filter: %s, connection mode: %s",
url,
+ sec->url,
urld->lud_host,
urld->lud_port,
urld->lud_dn,
@@ -1921,13 +1931,13 @@
static void ImportULDAPOptFn(void)
{
- util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close);
- util_ldap_connection_find = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_find);
- util_ldap_cache_comparedn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_comparedn);
- util_ldap_cache_compare = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_compare);
- util_ldap_cache_checkuserid = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_checkuserid);
- util_ldap_cache_getuserdn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_getuserdn);
- util_ldap_ssl_supported = APR_RETRIEVE_OPTIONAL_FN(uldap_ssl_supported);
+ util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close);
+ util_ldap_connection_find_ex = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_find_ex);
+ util_ldap_cache_comparedn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_comparedn);
+ util_ldap_cache_compare = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_compare);
+ util_ldap_cache_checkuserid = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_checkuserid);
+ util_ldap_cache_getuserdn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_getuserdn);
+ util_ldap_ssl_supported = APR_RETRIEVE_OPTIONAL_FN(uldap_ssl_supported);
util_ldap_cache_check_subgroups = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_check_subgroups);
}
Index: modules/ldap/util_ldap.c
===================================================================
--- modules/ldap/util_ldap.c (revision 1909117)
+++ modules/ldap/util_ldap.c (working copy)
@@ -285,6 +285,25 @@
(util_ldap_state_t *)ap_get_module_config(r->server->module_config,
&ldap_module);
int have_client_certs = !apr_is_empty_array(ldc->client_certs);
+
+#if APR_HAS_LDAP_INITIALIZE
+
+ apr_ldap_initialize(ldc->pool, ldc->url, &(ldc->ld), &(ldc->result));
+
+ if (ldc->ld) {
+ apr_ldap_opt_t opt;
+
+ apr_ldap_get_option_ex(ldc->ld, APR_LDAP_OPT_HANDLE, &opt, &(ldc->result));
+
+ ldc->ldap = opt.handle;
+ }
+
+ result = &ldc->result;
+
+#else
+
+ /* remove after apr-util v1.7 */
+
#if !APR_HAS_SOLARIS_LDAPSDK
/*
* Normally we enable SSL/TLS with apr_ldap_set_option(), except
@@ -322,7 +341,9 @@
return(APR_EGENERAL);
}
- if (result->rc) {
+#endif
+
+ if (result && result->rc) {
ldc->reason = result->reason;
ldc->bound = 0;
return result->rc;
@@ -697,19 +718,12 @@
}
-/*
- * Find an existing ldap connection struct that matches the
- * provided ldap connection parameters.
- *
- * If not found in the cache, a new ldc structure will be allocated
- * from st->pool and returned to the caller. If found in the cache,
- * a pointer to the existing ldc structure will be returned.
- */
static util_ldap_connection_t *
- uldap_connection_find(request_rec *r,
- const char *host, int port,
- const char *binddn, const char *bindpw,
- deref_options deref, int secure)
+ connection_find(request_rec *r,
+ const char *url,
+ const char *host, int port,
+ const char *binddn, const char *bindpw,
+ deref_options deref, int secure)
{
struct util_ldap_connection_t *l, *p; /* To traverse the linked list */
int secureflag = secure;
@@ -737,12 +751,16 @@
#if APR_HAS_THREADS
if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
#endif
- if ( (l->port == port) && (strcmp(l->host, host) == 0)
- && ((!l->binddn && !binddn) || (l->binddn && binddn
- && !strcmp(l->binddn, binddn)))
- && ((!l->bindpw && !bindpw) || (l->bindpw && bindpw
- && !strcmp(l->bindpw, bindpw)))
- && (l->deref == deref) && (l->secure == secureflag)
+ if ( (l->port == port)
+ && ((!url && !l->url) || (url && l->url
+ && !strcmp(url, l->url)))
+ && ((!host && !l->host) || (host && l->host
+ && !strcmp(l->host, host)))
+ && ((!binddn && !l->binddn) || (binddn && l->binddn
+ && !strcmp(binddn, l->binddn)))
+ && ((!bindpw && !l->bindpw) || (bindpw && l->bindpw
+ && !strcmp(bindpw, l->bindpw)))
+ && (deref == l->deref) && (secureflag == l->secure)
&& !compare_client_certs(dc->client_certs, l->client_certs))
{
if (st->connection_pool_ttl > 0) {
@@ -779,9 +797,13 @@
if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
#endif
- if ((l->port == port) && (strcmp(l->host, host) == 0) &&
- (l->deref == deref) && (l->secure == secureflag) &&
- !compare_client_certs(dc->client_certs, l->client_certs))
+ if ((port == l->port)
+ && ((!url && !l->url) || (url && l->url
+ && !strcmp(url, l->url)))
+ && ((!host && !l->host) || (host && l->host
+ && !strcmp(host, l->host)))
+ && (deref == l->deref) && (secureflag == l->secure)
+ && !compare_client_certs(dc->client_certs, l->client_certs))
{
if (st->connection_pool_ttl > 0) {
if (l->bound && (now - l->last_backend_conn) > st->connection_pool_ttl) {
@@ -849,6 +871,7 @@
apr_thread_mutex_lock(l->lock);
#endif
l->bound = 0;
+ l->url = apr_pstrdup(l->pool, url);
l->host = apr_pstrdup(l->pool, host);
l->port = port;
l->deref = deref;
@@ -897,6 +920,42 @@
return l;
}
+/*
+ * Find an existing ldap connection struct that matches the
+ * provided ldap connection parameters.
+ *
+ * If not found in the cache, a new ldc structure will be allocated
+ * from st->pool and returned to the caller. If found in the cache,
+ * a pointer to the existing ldc structure will be returned.
+ *
+ * Deprecated: replaced by uldap_connection_find_ex()
+ */
+static util_ldap_connection_t *
+ uldap_connection_find(request_rec *r,
+ const char *host, int port,
+ const char *binddn, const char *bindpw,
+ deref_options deref, int secure)
+{
+ return connection_find(r, NULL, host, port, binddn, bindpw, deref, secure);
+}
+
+/*
+ * Find an existing ldap connection struct that matches the
+ * provided ldap connection parameters.
+ *
+ * If not found in the cache, a new ldc structure will be allocated
+ * from st->pool and returned to the caller. If found in the cache,
+ * a pointer to the existing ldc structure will be returned.
+ */
+static util_ldap_connection_t *
+ uldap_connection_find_ex(request_rec *r,
+ const char *url,
+ const char *binddn, const char *bindpw,
+ deref_options deref, int secure)
+{
+ return connection_find(r, url, NULL, 0, binddn, bindpw, deref, secure);
+}
+
/* ------------------------------------------------------------------ */
/*
@@ -3216,6 +3275,7 @@
APR_REGISTER_OPTIONAL_FN(uldap_connection_close);
APR_REGISTER_OPTIONAL_FN(uldap_connection_unbind);
APR_REGISTER_OPTIONAL_FN(uldap_connection_find);
+ APR_REGISTER_OPTIONAL_FN(uldap_connection_find_ex);
APR_REGISTER_OPTIONAL_FN(uldap_cache_comparedn);
APR_REGISTER_OPTIONAL_FN(uldap_cache_compare);
APR_REGISTER_OPTIONAL_FN(uldap_cache_checkuserid);
This is a patch for httpd that adds support for ldapi:// URLs to mod_ldap and friends.
It depends on a patch for apr-util posted to the dev@apr list.
Regards,
Graham
—
Index: include/util_ldap.h
===================================================================
--- include/util_ldap.h (revision 1909117)
+++ include/util_ldap.h (working copy)
@@ -45,6 +45,10 @@
/* this whole thing disappears if LDAP is not enabled */
#if APR_HAS_LDAP
+#ifndef APR_HAS_LDAP_INITIALIZE
+#define APR_HAS_LDAP_INITIALIZE 0
+#endif
+
#if defined(LDAP_UNAVAILABLE) || APR_HAS_MICROSOFT_LDAPSDK
#define AP_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN \
||(s) == LDAP_UNAVAILABLE)
@@ -126,8 +130,8 @@
const char *reason; /* Reason for an error failure */
struct util_ldap_connection_t *next;
- struct util_ldap_state_t *st; /* The LDAP vhost config this connection belongs to */
- int keep; /* Will this connection be kept when it's unlocked */
+ struct util_ldap_state_t *st; /* The LDAP vhost config this connection belongs to */
+ int keep; /* Will this connection be kept when it's unlocked */
int ChaseReferrals; /* [on|off] (default = AP_LDAP_CHASEREFERRALS_ON)*/
int ReferralHopLimit; /* # of referral hops to follow (default = AP_LDAP_DEFAULT_HOPLIMIT) */
@@ -136,6 +140,12 @@
int must_rebind; /* The connection was last bound with other then binddn/bindpw */
request_rec *r; /* request_rec used to find this util_ldap_connection_t */
apr_time_t last_backend_conn; /* the approximate time of the last backend LDAP request */
+
+#if APR_HAS_LDAP_INITIALIZE
+ apr_ldap_err_t result; /* result of prior operations on this connection */
+ const char *url; /* URL of the LDAP server (or space separated list) */
+ apr_ldap_t *ld;
+#endif
} util_ldap_connection_t;
typedef struct util_ldap_config_t {
@@ -241,6 +251,7 @@
* @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)
+ * @deprecated Replaced by uldap_connection_find_ex()
*/
APR_DECLARE_OPTIONAL_FN(util_ldap_connection_t *,uldap_connection_find,(request_rec *r, const char *host, int port,
const char *binddn, const char *bindpw, deref_options deref,
@@ -247,6 +258,26 @@
int secure));
/**
+ * Find a connection in a list of connections
+ * @param r The request record
+ * @param url The URL to connect to (multiple URLs space separated)
+ * @param binddn The DN to bind with
+ * @param bindpw The password to bind with
+ * @param deref The dereferencing behavior
+ * @param secure use SSL on the connection
+ * @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.
+ * @fn util_ldap_connection_t *util_ldap_connection_find_ex(request_rec *r, const char *url,
+ * const char *binddn, const char *bindpw, deref_options deref,
+ * int netscapessl, int starttls)
+ */
+APR_DECLARE_OPTIONAL_FN(util_ldap_connection_t *,uldap_connection_find_ex,(request_rec *r, const char *url,
+ const char *binddn, const char *bindpw, deref_options deref,
+ int secure));
+
+/**
* Compare two DNs for sameness
* @param r The request record
* @param ldc The LDAP connection being used.
Index: modules/aaa/mod_authnz_ldap.c
===================================================================
--- modules/aaa/mod_authnz_ldap.c (revision 1909117)
+++ modules/aaa/mod_authnz_ldap.c (working copy)
@@ -104,7 +104,7 @@
module AP_MODULE_DECLARE_DATA authnz_ldap_module;
static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close;
-static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find;
+static APR_OPTIONAL_FN_TYPE(uldap_connection_find_ex) *util_ldap_connection_find_ex;
static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn;
static APR_OPTIONAL_FN_TYPE(uldap_cache_compare) *util_ldap_cache_compare;
static APR_OPTIONAL_FN_TYPE(uldap_cache_check_subgroups) *util_ldap_cache_check_subgroups;
@@ -453,9 +453,7 @@
bindpw = req->password;
}
- return util_ldap_connection_find(r, sec->host, sec->port,
- binddn, bindpw,
- sec->deref, sec->secure);
+ return util_ldap_connection_find_ex(r, sec->url, binddn, bindpw, sec->deref, sec->secure);
}
/*
* Authentication Phase
@@ -527,7 +525,7 @@
}
/* There is a good AuthLDAPURL, right? */
- if (sec->host) {
+ if (sec->url) {
const char *binddn = sec->binddn;
const char *bindpw = sec->bindpw;
if (sec->initial_bind_as_user) {
@@ -535,13 +533,13 @@
binddn = ldap_determine_binddn(r, user);
}
- ldc = util_ldap_connection_find(r, sec->host, sec->port,
- binddn, bindpw,
- sec->deref, sec->secure);
+ ldc = util_ldap_connection_find_ex(r, sec->url,
+ binddn, bindpw,
+ sec->deref, sec->secure);
}
else {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01690)
- "auth_ldap authenticate: no sec->host - weird...?");
+ "auth_ldap authenticate: no sec->url - weird...?");
return AUTH_GENERAL_ERROR;
}
@@ -1436,13 +1434,14 @@
* host and port.
*/
static const char *mod_auth_ldap_parse_url(cmd_parms *cmd,
- void *config,
- const char *url,
- const char *mode)
+ void *config,
+ const char *url,
+ const char *mode)
{
- int rc;
+ int rc, i;
apr_ldap_url_desc_t *urld;
apr_ldap_err_t *result;
+ const char *end = url;
authn_ldap_config_t *sec = config;
@@ -1450,8 +1449,18 @@
if (rc != APR_SUCCESS) {
return result->reason;
}
- sec->url = apr_pstrdup(cmd->pool, url);
+ /* isolate the host/port part of the URL */
+ for (i = 0; end && i < 3; i++) {
+ end = strchr((char *)end + 1, '/');
+ }
+ if (end) {
+ sec->url = apr_pstrndup(cmd->pool, url, end - url);
+ }
+ else {
+ sec->url = apr_pstrdup(cmd->pool, url);
+ }
+
/* Set all the values, or at least some sane defaults */
if (sec->host) {
sec->host = apr_pstrcat(cmd->pool, urld->lud_host, " ", sec->host, NULL);
@@ -1528,9 +1537,10 @@
sec->have_ldap_url = 1;
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, cmd->server,
- "auth_ldap url parse: `%s', Host: %s, Port: %d, DN: %s, "
+ "auth_ldap url parse: `%s', Url: %s, Host: %s, Port: %d, DN: %s, "
"attrib: %s, scope: %s, filter: %s, connection mode: %s",
url,
+ sec->url,
urld->lud_host,
urld->lud_port,
urld->lud_dn,
@@ -1921,13 +1931,13 @@
static void ImportULDAPOptFn(void)
{
- util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close);
- util_ldap_connection_find = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_find);
- util_ldap_cache_comparedn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_comparedn);
- util_ldap_cache_compare = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_compare);
- util_ldap_cache_checkuserid = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_checkuserid);
- util_ldap_cache_getuserdn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_getuserdn);
- util_ldap_ssl_supported = APR_RETRIEVE_OPTIONAL_FN(uldap_ssl_supported);
+ util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close);
+ util_ldap_connection_find_ex = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_find_ex);
+ util_ldap_cache_comparedn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_comparedn);
+ util_ldap_cache_compare = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_compare);
+ util_ldap_cache_checkuserid = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_checkuserid);
+ util_ldap_cache_getuserdn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_getuserdn);
+ util_ldap_ssl_supported = APR_RETRIEVE_OPTIONAL_FN(uldap_ssl_supported);
util_ldap_cache_check_subgroups = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_check_subgroups);
}
Index: modules/ldap/util_ldap.c
===================================================================
--- modules/ldap/util_ldap.c (revision 1909117)
+++ modules/ldap/util_ldap.c (working copy)
@@ -285,6 +285,25 @@
(util_ldap_state_t *)ap_get_module_config(r->server->module_config,
&ldap_module);
int have_client_certs = !apr_is_empty_array(ldc->client_certs);
+
+#if APR_HAS_LDAP_INITIALIZE
+
+ apr_ldap_initialize(ldc->pool, ldc->url, &(ldc->ld), &(ldc->result));
+
+ if (ldc->ld) {
+ apr_ldap_opt_t opt;
+
+ apr_ldap_get_option_ex(ldc->ld, APR_LDAP_OPT_HANDLE, &opt, &(ldc->result));
+
+ ldc->ldap = opt.handle;
+ }
+
+ result = &ldc->result;
+
+#else
+
+ /* remove after apr-util v1.7 */
+
#if !APR_HAS_SOLARIS_LDAPSDK
/*
* Normally we enable SSL/TLS with apr_ldap_set_option(), except
@@ -322,7 +341,9 @@
return(APR_EGENERAL);
}
- if (result->rc) {
+#endif
+
+ if (result && result->rc) {
ldc->reason = result->reason;
ldc->bound = 0;
return result->rc;
@@ -697,19 +718,12 @@
}
-/*
- * Find an existing ldap connection struct that matches the
- * provided ldap connection parameters.
- *
- * If not found in the cache, a new ldc structure will be allocated
- * from st->pool and returned to the caller. If found in the cache,
- * a pointer to the existing ldc structure will be returned.
- */
static util_ldap_connection_t *
- uldap_connection_find(request_rec *r,
- const char *host, int port,
- const char *binddn, const char *bindpw,
- deref_options deref, int secure)
+ connection_find(request_rec *r,
+ const char *url,
+ const char *host, int port,
+ const char *binddn, const char *bindpw,
+ deref_options deref, int secure)
{
struct util_ldap_connection_t *l, *p; /* To traverse the linked list */
int secureflag = secure;
@@ -737,12 +751,16 @@
#if APR_HAS_THREADS
if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
#endif
- if ( (l->port == port) && (strcmp(l->host, host) == 0)
- && ((!l->binddn && !binddn) || (l->binddn && binddn
- && !strcmp(l->binddn, binddn)))
- && ((!l->bindpw && !bindpw) || (l->bindpw && bindpw
- && !strcmp(l->bindpw, bindpw)))
- && (l->deref == deref) && (l->secure == secureflag)
+ if ( (l->port == port)
+ && ((!url && !l->url) || (url && l->url
+ && !strcmp(url, l->url)))
+ && ((!host && !l->host) || (host && l->host
+ && !strcmp(l->host, host)))
+ && ((!binddn && !l->binddn) || (binddn && l->binddn
+ && !strcmp(binddn, l->binddn)))
+ && ((!bindpw && !l->bindpw) || (bindpw && l->bindpw
+ && !strcmp(bindpw, l->bindpw)))
+ && (deref == l->deref) && (secureflag == l->secure)
&& !compare_client_certs(dc->client_certs, l->client_certs))
{
if (st->connection_pool_ttl > 0) {
@@ -779,9 +797,13 @@
if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
#endif
- if ((l->port == port) && (strcmp(l->host, host) == 0) &&
- (l->deref == deref) && (l->secure == secureflag) &&
- !compare_client_certs(dc->client_certs, l->client_certs))
+ if ((port == l->port)
+ && ((!url && !l->url) || (url && l->url
+ && !strcmp(url, l->url)))
+ && ((!host && !l->host) || (host && l->host
+ && !strcmp(host, l->host)))
+ && (deref == l->deref) && (secureflag == l->secure)
+ && !compare_client_certs(dc->client_certs, l->client_certs))
{
if (st->connection_pool_ttl > 0) {
if (l->bound && (now - l->last_backend_conn) > st->connection_pool_ttl) {
@@ -849,6 +871,7 @@
apr_thread_mutex_lock(l->lock);
#endif
l->bound = 0;
+ l->url = apr_pstrdup(l->pool, url);
l->host = apr_pstrdup(l->pool, host);
l->port = port;
l->deref = deref;
@@ -897,6 +920,42 @@
return l;
}
+/*
+ * Find an existing ldap connection struct that matches the
+ * provided ldap connection parameters.
+ *
+ * If not found in the cache, a new ldc structure will be allocated
+ * from st->pool and returned to the caller. If found in the cache,
+ * a pointer to the existing ldc structure will be returned.
+ *
+ * Deprecated: replaced by uldap_connection_find_ex()
+ */
+static util_ldap_connection_t *
+ uldap_connection_find(request_rec *r,
+ const char *host, int port,
+ const char *binddn, const char *bindpw,
+ deref_options deref, int secure)
+{
+ return connection_find(r, NULL, host, port, binddn, bindpw, deref, secure);
+}
+
+/*
+ * Find an existing ldap connection struct that matches the
+ * provided ldap connection parameters.
+ *
+ * If not found in the cache, a new ldc structure will be allocated
+ * from st->pool and returned to the caller. If found in the cache,
+ * a pointer to the existing ldc structure will be returned.
+ */
+static util_ldap_connection_t *
+ uldap_connection_find_ex(request_rec *r,
+ const char *url,
+ const char *binddn, const char *bindpw,
+ deref_options deref, int secure)
+{
+ return connection_find(r, url, NULL, 0, binddn, bindpw, deref, secure);
+}
+
/* ------------------------------------------------------------------ */
/*
@@ -3216,6 +3275,7 @@
APR_REGISTER_OPTIONAL_FN(uldap_connection_close);
APR_REGISTER_OPTIONAL_FN(uldap_connection_unbind);
APR_REGISTER_OPTIONAL_FN(uldap_connection_find);
+ APR_REGISTER_OPTIONAL_FN(uldap_connection_find_ex);
APR_REGISTER_OPTIONAL_FN(uldap_cache_comparedn);
APR_REGISTER_OPTIONAL_FN(uldap_cache_compare);
APR_REGISTER_OPTIONAL_FN(uldap_cache_checkuserid);