[SCM] Samba Shared Repository - branch master updated
Andreas Schneider
asn at samba.org
Mon Jun 29 06:01:04 MDT 2015
The branch, master has been updated
via eaf9920 winbindd: disconnect child process if request is cancelled at main process
from e3373e9 Revert "lib: Fix deps for LIBCRYPTO"
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit eaf99203093cabc3069f1c69345d38d739b0663d
Author: Uri Simchoni <urisimchoni at gmail.com>
Date: Wed Jun 24 10:55:06 2015 +0300
winbindd: disconnect child process if request is cancelled at main process
When cancelling a request at the main winbindd process, that is currently
being served by a child winbindd process, just freeing all objects related
to the request is not enough, as the next bytes to come through the pipe
from the child process are the response to the cancelled request, and the
object reading those bytes will be the next request. This breaks the protocol.
This change, upon canceling a request that is being served, closes the
connection to the child process, causing the next request to be served
by a new child process (and the detached child to die eventually).
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11358
Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
Autobuild-User(master): Andreas Schneider <asn at cryptomilk.org>
Autobuild-Date(master): Mon Jun 29 14:00:24 CEST 2015 on sn-devel-104
-----------------------------------------------------------------------
Summary of changes:
source3/winbindd/winbindd_dual.c | 50 +++++++++++++++++++++++++++++++++-------
1 file changed, 42 insertions(+), 8 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 5bb7cd0..350ec7d 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -119,6 +119,7 @@ static NTSTATUS child_write_response(int sock, struct winbindd_response *wrsp)
struct wb_child_request_state {
struct tevent_context *ev;
+ struct tevent_req *subreq;
struct winbindd_child *child;
struct winbindd_request *request;
struct winbindd_response *response;
@@ -130,6 +131,9 @@ static void wb_child_request_trigger(struct tevent_req *req,
void *private_data);
static void wb_child_request_done(struct tevent_req *subreq);
+static void wb_child_request_cleanup(struct tevent_req *req,
+ enum tevent_req_state req_state);
+
struct tevent_req *wb_child_request_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct winbindd_child *child,
@@ -153,6 +157,9 @@ struct tevent_req *wb_child_request_send(TALLOC_CTX *mem_ctx,
tevent_req_oom(req);
return tevent_req_post(req, ev);
}
+
+ tevent_req_set_cleanup_fn(req, wb_child_request_cleanup);
+
return req;
}
@@ -173,6 +180,8 @@ static void wb_child_request_trigger(struct tevent_req *req,
if (tevent_req_nomem(subreq, req)) {
return;
}
+
+ state->subreq = subreq;
tevent_req_set_callback(subreq, wb_child_request_done, req);
tevent_req_set_endtime(req, state->ev, timeval_current_ofs(300, 0));
}
@@ -186,15 +195,11 @@ static void wb_child_request_done(struct tevent_req *subreq)
int ret, err;
ret = wb_simple_trans_recv(subreq, state, &state->response, &err);
- TALLOC_FREE(subreq);
+ /* Freeing the subrequest is deferred until the cleanup function,
+ * which has to know whether a subrequest exists, and consequently
+ * decide whether to shut down the pipe to the child process.
+ */
if (ret == -1) {
- /*
- * The basic parent/child communication broke, close
- * our socket
- */
- close(state->child->sock);
- state->child->sock = -1;
- DLIST_REMOVE(winbindd_children, state->child);
tevent_req_error(req, err);
return;
}
@@ -214,6 +219,35 @@ int wb_child_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
return 0;
}
+static void wb_child_request_cleanup(struct tevent_req *req,
+ enum tevent_req_state req_state)
+{
+ struct wb_child_request_state *state =
+ tevent_req_data(req, struct wb_child_request_state);
+
+ if (state->subreq == NULL) {
+ /* nothing to cleanup */
+ return;
+ }
+
+ TALLOC_FREE(state->subreq);
+
+ if (req_state == TEVENT_REQ_DONE) {
+ /* transmitted request and got response */
+ return;
+ }
+
+ /*
+ * Failed to transmit and receive response, or request
+ * cancelled while being serviced.
+ * The basic parent/child communication broke, close
+ * our socket
+ */
+ close(state->child->sock);
+ state->child->sock = -1;
+ DLIST_REMOVE(winbindd_children, state->child);
+}
+
static bool winbindd_child_busy(struct winbindd_child *child)
{
return tevent_queue_length(child->queue) > 0;
--
Samba Shared Repository
More information about the samba-cvs
mailing list