summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2004-07-26 07:41:16 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:52:16 -0500
commitec1bbbf85890dee1fa68046f5c7f15967536079e (patch)
treed0f32077fa98dc447cd27e0cbfad63fdeba2e036 /source3
parent2e6f3398d61237e04452530a1415f3e0bd8df3b5 (diff)
downloadsamba-ec1bbbf85890dee1fa68046f5c7f15967536079e.tar.gz
samba-ec1bbbf85890dee1fa68046f5c7f15967536079e.tar.bz2
samba-ec1bbbf85890dee1fa68046f5c7f15967536079e.zip
r1588: This is one of the more pathetic patches I ever checked in. Many hours of
coding have passed, but I could not find a way to get the OpenLDAP libraries to reliably time out on any of the queries we make, *and* get correct error returns. No, async calls and ldap_result does NOT work, or I was simply too stupid to correctly interpret the OpenLDAP manpage and source. We can not allow to hang indefinitely in an ldap query, especially not for winbindd. "ldap timeout" now specifies the overall timeout for the complete operation, that's why I increased that to 15 seconds. Volker (This used to be commit 269f0750872e5f8757e0a9667e007a0410319fcd)
Diffstat (limited to 'source3')
-rw-r--r--source3/include/smbldap.h2
-rw-r--r--source3/lib/smbldap.c167
2 files changed, 73 insertions, 96 deletions
diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h
index b94577178b..6046af464e 100644
--- a/source3/include/smbldap.h
+++ b/source3/include/smbldap.h
@@ -154,6 +154,6 @@ struct smbldap_state {
struct smbldap_state;
-#define LDAP_CONNECT_DEFAULT_TIMEOUT 5
+#define LDAP_CONNECT_DEFAULT_TIMEOUT 15
#endif /* _SMBLDAP_H */
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index a1a3117d88..0980b763ad 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -879,37 +879,69 @@ static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
return NT_STATUS_OK;
}
-int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts)
+static BOOL got_alarm;
+
+static void (*old_handler)(int);
+
+static void gotalarm_sig(int dummy)
{
- int rc;
+ got_alarm = True;
+}
- SMB_ASSERT(ldap_state && attempts);
-
- if (*attempts != 0) {
- unsigned int sleep_time;
- uint8 rand_byte;
-
- /* Sleep for a random timeout */
- rand_byte = (char)(sys_random());
-
- sleep_time = (((*attempts)*(*attempts))/2)*rand_byte*2;
- /* we retry after (0.5, 1, 2, 3, 4.5, 6) seconds
- on average.
- */
- DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n",
- sleep_time));
- smb_msleep(sleep_time);
+static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,
+ int *attempts, time_t endtime)
+{
+ time_t now = time(NULL);
+ int open_rc = LDAP_SERVER_DOWN;
+
+ if (*rc != LDAP_SERVER_DOWN)
+ goto no_next;
+
+ now = time(NULL);
+
+ if (now >= endtime) {
+ smbldap_close(ldap_state);
+ *rc = LDAP_TIMEOUT;
+ goto no_next;
}
- (*attempts)++;
- if ((rc = smbldap_open(ldap_state))) {
- DEBUG(1,("Connection to LDAP Server failed for the %d try!\n",*attempts));
- return rc;
- }
-
- return LDAP_SUCCESS;
-}
+ if (*attempts == 0) {
+ got_alarm = False;
+ old_handler = CatchSignal(SIGALRM, gotalarm_sig);
+ alarm(endtime - now);
+ }
+
+ while (1) {
+
+ if (*attempts != 0)
+ smb_msleep(1000);
+ *attempts += 1;
+
+ open_rc = smbldap_open(ldap_state);
+
+ if (open_rc == LDAP_SUCCESS) {
+ ldap_state->last_use = now;
+ return True;
+ }
+
+ if (got_alarm) {
+ *rc = LDAP_TIMEOUT;
+ break;
+ }
+
+ if (open_rc != LDAP_SUCCESS) {
+ DEBUG(1, ("Connection to LDAP server failed for the "
+ "%d try!\n", *attempts));
+ }
+ }
+
+ no_next:
+ CatchSignal(SIGALRM, old_handler);
+ alarm(0);
+ ldap_state->last_use = now;
+ return False;
+}
/*********************************************************************
********************************************************************/
@@ -922,6 +954,7 @@ int smbldap_search(struct smbldap_state *ldap_state,
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_filter;
+ time_t endtime = time(NULL)+lp_ldap_timeout();
SMB_ASSERT(ldap_state);
@@ -955,22 +988,10 @@ int smbldap_search(struct smbldap_state *ldap_state,
return LDAP_NO_MEMORY;
}
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
utf8_filter, attrs, attrsonly, res);
- }
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
SAFE_FREE(utf8_filter);
return rc;
}
@@ -980,6 +1001,7 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_dn;
+ time_t endtime = time(NULL)+lp_ldap_timeout();
SMB_ASSERT(ldap_state);
@@ -989,21 +1011,9 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
return LDAP_NO_MEMORY;
}
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
+
SAFE_FREE(utf8_dn);
return rc;
}
@@ -1013,6 +1023,7 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_dn;
+ time_t endtime = time(NULL)+lp_ldap_timeout();
SMB_ASSERT(ldap_state);
@@ -1022,21 +1033,9 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
return LDAP_NO_MEMORY;
}
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
- }
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
SAFE_FREE(utf8_dn);
return rc;
}
@@ -1046,6 +1045,7 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_dn;
+ time_t endtime = time(NULL)+lp_ldap_timeout();
SMB_ASSERT(ldap_state);
@@ -1055,21 +1055,9 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
return LDAP_NO_MEMORY;
}
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
- }
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
SAFE_FREE(utf8_dn);
return rc;
}
@@ -1081,26 +1069,15 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state,
{
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
+ time_t endtime = time(NULL)+lp_ldap_timeout();
if (!ldap_state)
return (-1);
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata,
- serverctrls, clientctrls, retoidp, retdatap);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid,
+ reqdata, serverctrls,
+ clientctrls, retoidp, retdatap);
return rc;
}