1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-26 10:04:02 +03:00

winbindd: cleanup client connection if the client closes the connection

This patch allows for early cleanup of client connections if the client
has given up.
Before this patch, any received request would be processed, and then only
upon transmitting the result to the client would winbindd find out the
client is no longer with us, possibly leading to a situation where the
same client tries over and over and increases the number of client
connections.

This patch monitors the client socket for readability while the request
is being processed, and closes the client connection if the socket
becomes readable. The client is not supposed to be writing anything to
the socket while it is waiting, so readability means either that the client
has closed the connection, or that it has broken the protocol.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11397

Signed-off-by: Uri Simchoni <urisimchoni@gmail.com>
Reviewed-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Uri Simchoni 2015-06-25 08:59:20 +03:00 committed by Jeremy Allison
parent 6da042d7c6
commit 28e1cae491

View File

@ -42,6 +42,7 @@
#include "source4/lib/messaging/irpc.h"
#include "source4/lib/messaging/messaging.h"
#include "lib/param/param.h"
#include "lib/async_req/async_sock.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
@ -809,11 +810,15 @@ static void request_finished(struct winbindd_cli_state *state);
static void winbind_client_request_read(struct tevent_req *req);
static void winbind_client_response_written(struct tevent_req *req);
static void winbind_client_activity(struct tevent_req *req);
static void request_finished(struct winbindd_cli_state *state)
{
struct tevent_req *req;
/* free client socket monitoring request */
TALLOC_FREE(state->io_req);
TALLOC_FREE(state->request);
req = wb_resp_write_send(state, winbind_event_context(),
@ -966,9 +971,32 @@ static void winbind_client_request_read(struct tevent_req *req)
remove_client(state);
return;
}
req = wait_for_read_send(state, winbind_event_context(), state->sock);
if (req == NULL) {
DEBUG(0, ("winbind_client_request_read[%d:%s]:"
" wait_for_read_send failed - removing client\n",
(int)state->pid, state->cmd_name));
remove_client(state);
return;
}
tevent_req_set_callback(req, winbind_client_activity, state);
state->io_req = req;
process_request(state);
}
static void winbind_client_activity(struct tevent_req *req)
{
struct winbindd_cli_state *state =
tevent_req_callback_data(req, struct winbindd_cli_state);
int err;
wait_for_read_recv(req, &err);
remove_client(state);
}
/* Remove a client connection from client connection list */
static void remove_client(struct winbindd_cli_state *state)