summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-06-11 22:28:27 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:23:15 -0500
commit24e05d4df2d791ae8f36dcc092915f12b992c3d6 (patch)
tree7d8f2cb1aabb8ea634329b611d82b457fdc5a081
parent0d5265e9d4e7bb0800490fd100e1f0998b9add06 (diff)
downloadsamba-24e05d4df2d791ae8f36dcc092915f12b992c3d6.tar.gz
samba-24e05d4df2d791ae8f36dcc092915f12b992c3d6.tar.bz2
samba-24e05d4df2d791ae8f36dcc092915f12b992c3d6.zip
r23424: Thanks to Jerry, we finally tracked down the :
winbindd: Exceeding 200 client connections, no idle connection found" bug #3204. This fixes it in Jerry's testing ! Jeremy. (This used to be commit 0c7ce6a68286fa98258828545fc869aaac19a028)
-rw-r--r--source3/nsswitch/winbindd_dual.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/source3/nsswitch/winbindd_dual.c b/source3/nsswitch/winbindd_dual.c
index 90046572bc..54525f8da1 100644
--- a/source3/nsswitch/winbindd_dual.c
+++ b/source3/nsswitch/winbindd_dual.c
@@ -96,6 +96,7 @@ struct winbindd_async_request {
struct winbindd_request *request;
struct winbindd_response *response;
void (*continuation)(void *private_data, BOOL success);
+ struct timed_event *reply_timeout_event;
void *private_data;
};
@@ -160,8 +161,38 @@ static void async_main_request_sent(void *private_data, BOOL success)
async_request_sent, state);
}
+/****************************************************************
+ Handler triggered if the child winbindd doesn't respond within
+ a given timeout.
+****************************************************************/
+
+static void async_request_timeout_handler(struct event_context *ctx,
+ struct timed_event *te,
+ const struct timeval *now,
+ void *private_data)
+{
+ struct winbindd_async_request *state =
+ talloc_get_type_abort(private_data, struct winbindd_async_request);
+
+ /* Deal with the reply - set to error. */
+
+ async_reply_recv(private_data, False);
+
+ /*
+ * Close the socket to the child. Should cause the
+ * child to exit.
+ */
+
+ DEBUG(0,("async_request_timeout_handler: child pid %u is not responding. "
+ "Closing connection to it.\n",
+ state->child->pid ));
+
+ winbind_child_died(state->child->pid);
+}
+
static void async_request_sent(void *private_data_data, BOOL success)
{
+ uint32_t timeout = 30;
struct winbindd_async_request *state =
talloc_get_type_abort(private_data_data, struct winbindd_async_request);
@@ -180,6 +211,33 @@ static void async_request_sent(void *private_data_data, BOOL success)
&state->response->result,
sizeof(state->response->result),
async_reply_recv, state);
+
+ /*
+ * Normal timeouts are 30s, but auth requests may take a long
+ * time to timeout.
+ */
+
+ if (state->request->cmd == WINBINDD_PAM_AUTH ||
+ state->request->cmd == WINBINDD_PAM_AUTH_CRAP ) {
+
+ timeout = 300;
+ }
+
+ /*
+ * Set up a timeout of 1 minute for the response.
+ * If we don't get it close the child socket and
+ * report failure.
+ */
+
+ state->reply_timeout_event = event_add_timed(winbind_event_context(),
+ NULL,
+ timeval_current_ofs(timeout,0),
+ "async_request_timeout",
+ async_request_timeout_handler,
+ state);
+ if (!state->reply_timeout_event) {
+ smb_panic("async_request_sent: failed to add timeout handler.\n");
+ }
}
static void async_reply_recv(void *private_data, BOOL success)
@@ -188,6 +246,10 @@ static void async_reply_recv(void *private_data, BOOL success)
talloc_get_type_abort(private_data, struct winbindd_async_request);
struct winbindd_child *child = state->child;
+ if (state->reply_timeout_event) {
+ TALLOC_FREE(state->reply_timeout_event);
+ }
+
state->response->length = sizeof(struct winbindd_response);
if (!success) {