mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
mod_ldap: remove hard-coded loops of 10 retries w/o delay with a configurable
number of retries (LDAPRetries, default 3) and configurable delay between retries (LDAPRetryDelay, no delay by default). The LDAP connection is re-initted every other retry, instead of on the fifth retry -- this was a much more recent addition then the basic looping behavior. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1156790 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,6 +1,9 @@
|
|||||||
-*- coding: utf-8 -*-
|
-*- coding: utf-8 -*-
|
||||||
Changes with Apache 2.3.15
|
Changes with Apache 2.3.15
|
||||||
|
|
||||||
|
*) mod_ldap: Change default number of retries from 10 to 3, and add
|
||||||
|
an LDAPRetries and LDAPRetryDelay directives. [Eric Covener]
|
||||||
|
|
||||||
*) mod_authnz_ldap: Don't retry during authentication, because this just
|
*) mod_authnz_ldap: Don't retry during authentication, because this just
|
||||||
multiplies the ample retries already being done by mod_ldap. [Eric Covener]
|
multiplies the ample retries already being done by mod_ldap. [Eric Covener]
|
||||||
|
|
||||||
|
@@ -346,6 +346,7 @@
|
|||||||
* Add member override_list to cmd_parms_struct,
|
* Add member override_list to cmd_parms_struct,
|
||||||
* core_dir_config and htaccess_result
|
* core_dir_config and htaccess_result
|
||||||
* 20110724.1 (2.3.15-dev) add NOT_IN_HTACCESS
|
* 20110724.1 (2.3.15-dev) add NOT_IN_HTACCESS
|
||||||
|
* 20110724.2 (2.3.15-dev) retries and retry_delay in util_ldap_state_t
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
|
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
|
||||||
@@ -353,7 +354,7 @@
|
|||||||
#ifndef MODULE_MAGIC_NUMBER_MAJOR
|
#ifndef MODULE_MAGIC_NUMBER_MAJOR
|
||||||
#define MODULE_MAGIC_NUMBER_MAJOR 20110724
|
#define MODULE_MAGIC_NUMBER_MAJOR 20110724
|
||||||
#endif
|
#endif
|
||||||
#define MODULE_MAGIC_NUMBER_MINOR 1 /* 0...n */
|
#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
|
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
|
||||||
|
@@ -172,6 +172,8 @@ typedef struct util_ldap_state_t {
|
|||||||
|
|
||||||
int debug_level; /* SDK debug level */
|
int debug_level; /* SDK debug level */
|
||||||
apr_interval_time_t connection_pool_ttl;
|
apr_interval_time_t connection_pool_ttl;
|
||||||
|
int retries; /* number of retries for failed bind/search/compare */
|
||||||
|
apr_interval_time_t retry_delay; /* delay between retries of failed bind/search/compare */
|
||||||
} util_ldap_state_t;
|
} util_ldap_state_t;
|
||||||
|
|
||||||
/* Used to store arrays of attribute labels/values. */
|
/* Used to store arrays of attribute labels/values. */
|
||||||
|
@@ -529,10 +529,9 @@ static int uldap_connection_open(request_rec *r,
|
|||||||
st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
|
st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
|
||||||
&ldap_module);
|
&ldap_module);
|
||||||
|
|
||||||
/* loop trying to bind up to 10 times if LDAP_SERVER_DOWN error is
|
/* loop trying to bind up to st->retries times if LDAP_SERVER_DOWN or LDAP_TIMEOUT
|
||||||
* returned. If LDAP_TIMEOUT is returned on the first try, maybe the
|
* are returned. Close the connection before the first retry, and then on every
|
||||||
* connection was idle for a long time and has been dropped by a firewall.
|
* other retry.
|
||||||
* In this case close the connection immediately and try again.
|
|
||||||
*
|
*
|
||||||
* On Success or any other error, break out of the loop.
|
* On Success or any other error, break out of the loop.
|
||||||
*
|
*
|
||||||
@@ -541,33 +540,43 @@ static int uldap_connection_open(request_rec *r,
|
|||||||
* However, the original code looped and it only happens on
|
* However, the original code looped and it only happens on
|
||||||
* the error condition.
|
* the error condition.
|
||||||
*/
|
*/
|
||||||
for (failures=0; failures<10; failures++)
|
|
||||||
{
|
while (failures <= st->retries) {
|
||||||
|
if (failures > 0 && st->retry_delay > 0) {
|
||||||
|
apr_sleep(st->retry_delay);
|
||||||
|
}
|
||||||
rc = uldap_simple_bind(ldc, (char *)ldc->binddn, (char *)ldc->bindpw,
|
rc = uldap_simple_bind(ldc, (char *)ldc->binddn, (char *)ldc->bindpw,
|
||||||
st->opTimeout);
|
st->opTimeout);
|
||||||
if ((AP_LDAP_IS_SERVER_DOWN(rc) && failures == 5) ||
|
|
||||||
(rc == LDAP_TIMEOUT && failures == 0))
|
if (rc == LDAP_SUCCESS) break;
|
||||||
{
|
|
||||||
if (rc == LDAP_TIMEOUT && !new_connection) {
|
failures++;
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
|
|
||||||
"ldap_simple_bind() timed out on reused "
|
if (AP_LDAP_IS_SERVER_DOWN(rc)) {
|
||||||
"connection, dropped by firewall?");
|
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
|
||||||
}
|
"ldap_simple_bind() failed with server down "
|
||||||
|
"(try %d)", failures);
|
||||||
|
}
|
||||||
|
else if (rc == LDAP_TIMEOUT) {
|
||||||
|
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
|
||||||
|
"ldap_simple_bind() timed out on %s "
|
||||||
|
"connection, dropped by firewall?",
|
||||||
|
new_connection ? "new" : "reused");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Other errors not retryable */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(failures % 2)) {
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
|
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
|
||||||
"attempt to re-init the connection");
|
"attempt to re-init the connection");
|
||||||
uldap_connection_unbind( ldc );
|
uldap_connection_unbind(ldc);
|
||||||
rc = uldap_connection_init( r, ldc );
|
if (LDAP_SUCCESS != uldap_connection_init(r, ldc)) {
|
||||||
if (LDAP_SUCCESS != rc)
|
/* leave rc as the initial bind return code */
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!AP_LDAP_IS_SERVER_DOWN(rc)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
|
|
||||||
"ldap_simple_bind() failed with server down "
|
|
||||||
"(try %d)", failures + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free the handle if there was an error
|
/* free the handle if there was an error
|
||||||
@@ -878,11 +887,14 @@ static int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
start_over:
|
start_over:
|
||||||
if (failures++ > 10) {
|
if (failures > st->retries) {
|
||||||
/* too many failures */
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (failures > 0 && st->retry_delay > 0) {
|
||||||
|
apr_sleep(st->retry_delay);
|
||||||
|
}
|
||||||
|
|
||||||
/* make a server connection */
|
/* make a server connection */
|
||||||
if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
|
if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
|
||||||
/* connect to server failed */
|
/* connect to server failed */
|
||||||
@@ -898,6 +910,7 @@ start_over:
|
|||||||
ldc->reason = "DN Comparison ldap_search_ext_s() "
|
ldc->reason = "DN Comparison ldap_search_ext_s() "
|
||||||
"failed with server down";
|
"failed with server down";
|
||||||
uldap_connection_unbind(ldc);
|
uldap_connection_unbind(ldc);
|
||||||
|
failures++;
|
||||||
goto start_over;
|
goto start_over;
|
||||||
}
|
}
|
||||||
if (result == LDAP_TIMEOUT && failures == 0) {
|
if (result == LDAP_TIMEOUT && failures == 0) {
|
||||||
@@ -908,6 +921,7 @@ start_over:
|
|||||||
ldc->reason = "DN Comparison ldap_search_ext_s() "
|
ldc->reason = "DN Comparison ldap_search_ext_s() "
|
||||||
"failed with timeout";
|
"failed with timeout";
|
||||||
uldap_connection_unbind(ldc);
|
uldap_connection_unbind(ldc);
|
||||||
|
failures++;
|
||||||
goto start_over;
|
goto start_over;
|
||||||
}
|
}
|
||||||
if (result != LDAP_SUCCESS) {
|
if (result != LDAP_SUCCESS) {
|
||||||
@@ -1030,11 +1044,14 @@ static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
start_over:
|
start_over:
|
||||||
if (failures++ > 10) {
|
if (failures > st->retries) {
|
||||||
/* too many failures */
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (failures > 0 && st->retry_delay > 0) {
|
||||||
|
apr_sleep(st->retry_delay);
|
||||||
|
}
|
||||||
|
|
||||||
if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
|
if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
|
||||||
/* connect failed */
|
/* connect failed */
|
||||||
return result;
|
return result;
|
||||||
@@ -1048,6 +1065,7 @@ start_over:
|
|||||||
/* connection failed - try again */
|
/* connection failed - try again */
|
||||||
ldc->reason = "ldap_compare_s() failed with server down";
|
ldc->reason = "ldap_compare_s() failed with server down";
|
||||||
uldap_connection_unbind(ldc);
|
uldap_connection_unbind(ldc);
|
||||||
|
failures++;
|
||||||
goto start_over;
|
goto start_over;
|
||||||
}
|
}
|
||||||
if (result == LDAP_TIMEOUT && failures == 0) {
|
if (result == LDAP_TIMEOUT && failures == 0) {
|
||||||
@@ -1057,6 +1075,7 @@ start_over:
|
|||||||
*/
|
*/
|
||||||
ldc->reason = "ldap_compare_s() failed with timeout";
|
ldc->reason = "ldap_compare_s() failed with timeout";
|
||||||
uldap_connection_unbind(ldc);
|
uldap_connection_unbind(ldc);
|
||||||
|
failures++;
|
||||||
goto start_over;
|
goto start_over;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1127,6 +1146,9 @@ static util_compare_subgroup_t* uldap_get_subgroups(request_rec *r,
|
|||||||
LDAPMessage *sga_res, *entry;
|
LDAPMessage *sga_res, *entry;
|
||||||
struct mod_auth_ldap_groupattr_entry_t *sgc_ents;
|
struct mod_auth_ldap_groupattr_entry_t *sgc_ents;
|
||||||
apr_array_header_t *subgroups = apr_array_make(r->pool, 20, sizeof(char *));
|
apr_array_header_t *subgroups = apr_array_make(r->pool, 20, sizeof(char *));
|
||||||
|
util_ldap_state_t *st = (util_ldap_state_t *)
|
||||||
|
ap_get_module_config(r->server->module_config,
|
||||||
|
&ldap_module);
|
||||||
|
|
||||||
sgc_ents = (struct mod_auth_ldap_groupattr_entry_t *) subgroupclasses->elts;
|
sgc_ents = (struct mod_auth_ldap_groupattr_entry_t *) subgroupclasses->elts;
|
||||||
|
|
||||||
@@ -1138,11 +1160,15 @@ start_over:
|
|||||||
/*
|
/*
|
||||||
* 3.B. The cache didn't have any subgrouplist yet. Go check for subgroups.
|
* 3.B. The cache didn't have any subgrouplist yet. Go check for subgroups.
|
||||||
*/
|
*/
|
||||||
if (failures++ > 10) {
|
if (failures > st->retries) {
|
||||||
/* too many failures */
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (failures > 0 && st->retry_delay > 0) {
|
||||||
|
apr_sleep(st->retry_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
|
if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
|
||||||
/* connect failed */
|
/* connect failed */
|
||||||
return res;
|
return res;
|
||||||
@@ -1156,6 +1182,7 @@ start_over:
|
|||||||
ldc->reason = "ldap_search_ext_s() for subgroups failed with server"
|
ldc->reason = "ldap_search_ext_s() for subgroups failed with server"
|
||||||
" down";
|
" down";
|
||||||
uldap_connection_unbind(ldc);
|
uldap_connection_unbind(ldc);
|
||||||
|
failures++;
|
||||||
goto start_over;
|
goto start_over;
|
||||||
}
|
}
|
||||||
if (result == LDAP_TIMEOUT && failures == 0) {
|
if (result == LDAP_TIMEOUT && failures == 0) {
|
||||||
@@ -1165,6 +1192,7 @@ start_over:
|
|||||||
*/
|
*/
|
||||||
ldc->reason = "ldap_search_ext_s() for subgroups failed with timeout";
|
ldc->reason = "ldap_search_ext_s() for subgroups failed with timeout";
|
||||||
uldap_connection_unbind(ldc);
|
uldap_connection_unbind(ldc);
|
||||||
|
failures++;
|
||||||
goto start_over;
|
goto start_over;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1611,9 +1639,14 @@ static int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
|
|||||||
* If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
|
* If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
|
||||||
*/
|
*/
|
||||||
start_over:
|
start_over:
|
||||||
if (failures++ > 10) {
|
if (failures > st->retries) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (failures > 0 && st->retry_delay > 0) {
|
||||||
|
apr_sleep(st->retry_delay);
|
||||||
|
}
|
||||||
|
|
||||||
if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
|
if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1627,6 +1660,7 @@ start_over:
|
|||||||
{
|
{
|
||||||
ldc->reason = "ldap_search_ext_s() for user failed with server down";
|
ldc->reason = "ldap_search_ext_s() for user failed with server down";
|
||||||
uldap_connection_unbind(ldc);
|
uldap_connection_unbind(ldc);
|
||||||
|
failures++;
|
||||||
goto start_over;
|
goto start_over;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1689,6 +1723,7 @@ start_over:
|
|||||||
"timed out";
|
"timed out";
|
||||||
ldap_msgfree(res);
|
ldap_msgfree(res);
|
||||||
uldap_connection_unbind(ldc);
|
uldap_connection_unbind(ldc);
|
||||||
|
failures++;
|
||||||
goto start_over;
|
goto start_over;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1862,9 +1897,14 @@ static int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc,
|
|||||||
* If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
|
* If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
|
||||||
*/
|
*/
|
||||||
start_over:
|
start_over:
|
||||||
if (failures++ > 10) {
|
if (failures > st->retries) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (failures > 0 && st->retry_delay > 0) {
|
||||||
|
apr_sleep(st->retry_delay);
|
||||||
|
}
|
||||||
|
|
||||||
if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
|
if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1878,6 +1918,7 @@ start_over:
|
|||||||
{
|
{
|
||||||
ldc->reason = "ldap_search_ext_s() for user failed with server down";
|
ldc->reason = "ldap_search_ext_s() for user failed with server down";
|
||||||
uldap_connection_unbind(ldc);
|
uldap_connection_unbind(ldc);
|
||||||
|
failures++;
|
||||||
goto start_over;
|
goto start_over;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2599,8 +2640,52 @@ static const char *util_ldap_set_conn_ttl(cmd_parms *cmd,
|
|||||||
st->connection_pool_ttl = timeout;
|
st->connection_pool_ttl = timeout;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
static const char *util_ldap_set_retry_delay(cmd_parms *cmd,
|
||||||
|
void *dummy,
|
||||||
|
const char *val)
|
||||||
|
{
|
||||||
|
apr_interval_time_t timeout;
|
||||||
|
util_ldap_state_t *st =
|
||||||
|
(util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
|
||||||
|
&ldap_module);
|
||||||
|
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
|
||||||
|
|
||||||
|
if (err != NULL) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS) {
|
||||||
|
return "LDAPRetryDelay has wrong format";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout < 0) {
|
||||||
|
return "LDAPRetryDelay must be >= 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
st->retry_delay = timeout;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *util_ldap_set_retries(cmd_parms *cmd,
|
||||||
|
void *dummy,
|
||||||
|
const char *val)
|
||||||
|
{
|
||||||
|
util_ldap_state_t *st =
|
||||||
|
(util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
|
||||||
|
&ldap_module);
|
||||||
|
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
|
||||||
|
|
||||||
|
if (err != NULL) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
st->retries = atoi(val);
|
||||||
|
if (val < 0) {
|
||||||
|
return "LDAPRetries must be >= 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void *util_ldap_create_config(apr_pool_t *p, server_rec *s)
|
static void *util_ldap_create_config(apr_pool_t *p, server_rec *s)
|
||||||
{
|
{
|
||||||
@@ -2631,6 +2716,8 @@ static void *util_ldap_create_config(apr_pool_t *p, server_rec *s)
|
|||||||
st->opTimeout->tv_sec = 60;
|
st->opTimeout->tv_sec = 60;
|
||||||
st->verify_svr_cert = 1;
|
st->verify_svr_cert = 1;
|
||||||
st->connection_pool_ttl = AP_LDAP_CONNPOOL_DEFAULT; /* no limit */
|
st->connection_pool_ttl = AP_LDAP_CONNPOOL_DEFAULT; /* no limit */
|
||||||
|
st->retries = 3;
|
||||||
|
st->retry_delay = 0; /* no delay */
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
@@ -2685,6 +2772,9 @@ static void *util_ldap_merge_config(apr_pool_t *p, void *basev,
|
|||||||
st->connection_pool_ttl = (overrides->connection_pool_ttl == AP_LDAP_CONNPOOL_DEFAULT) ?
|
st->connection_pool_ttl = (overrides->connection_pool_ttl == AP_LDAP_CONNPOOL_DEFAULT) ?
|
||||||
base->connection_pool_ttl : overrides->connection_pool_ttl;
|
base->connection_pool_ttl : overrides->connection_pool_ttl;
|
||||||
|
|
||||||
|
st->retries = base->retries;
|
||||||
|
st->retry_delay = base->retry_delay;
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2967,6 +3057,15 @@ static const command_rec util_ldap_cmds[] = {
|
|||||||
"Specify the maximum amount of time a bound connection can sit "
|
"Specify the maximum amount of time a bound connection can sit "
|
||||||
"idle and still be considered valid for reuse"
|
"idle and still be considered valid for reuse"
|
||||||
"(0 = no pool, -1 = no limit, n = time in seconds). Default: -1"),
|
"(0 = no pool, -1 = no limit, n = time in seconds). Default: -1"),
|
||||||
|
AP_INIT_TAKE1("LDAPRetries", util_ldap_set_retries,
|
||||||
|
NULL, RSRC_CONF,
|
||||||
|
"Specify the number of times a failed LDAP operation should be retried "
|
||||||
|
"(0 = no retries). Default: 3"),
|
||||||
|
AP_INIT_TAKE1("LDAPRetryDelay", util_ldap_set_retry_delay,
|
||||||
|
NULL, RSRC_CONF,
|
||||||
|
"Specify the delay between retries of a failed LDAP operation "
|
||||||
|
"(0 = no delay). Default: 0"),
|
||||||
|
|
||||||
|
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user