1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

winbind: protect a pending wb_child_request against a talloc_free()

If the (winbind) client gave up we call TALLOC_FREE(state->mem_ctx)
in remove_client(). This triggers a recursive talloc_free() for all
in flight requests.

In order to maintain the winbindd parent-child protocol, we need
to keep the orphaned wb_simple_trans request until the parent
got the response from the child.

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
This commit is contained in:
Stefan Metzmacher 2018-02-16 15:05:57 +01:00
parent d29dda141e
commit 43af57d872

View File

@ -130,6 +130,7 @@ static bool fork_domain_child(struct winbindd_child *child);
static void wb_child_request_waited(struct tevent_req *subreq);
static void wb_child_request_done(struct tevent_req *subreq);
static void wb_child_request_orphaned(struct tevent_req *subreq);
static void wb_child_request_cleanup(struct tevent_req *req,
enum tevent_req_state req_state);
@ -220,6 +221,12 @@ static void wb_child_request_done(struct tevent_req *subreq)
tevent_req_done(req);
}
static void wb_child_request_orphaned(struct tevent_req *subreq)
{
DBG_WARNING("cleanup orphaned subreq[%p]\n", subreq);
TALLOC_FREE(subreq);
}
int wb_child_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
struct winbindd_response **presponse, int *err)
{
@ -244,6 +251,28 @@ static void wb_child_request_cleanup(struct tevent_req *req,
return;
}
if (req_state == TEVENT_REQ_RECEIVED) {
struct tevent_req *subreq = NULL;
/*
* Our caller gave up, but we need to keep
* the low level request (wb_simple_trans)
* in order to maintain the parent child protocol.
*
* We also need to keep the child queue blocked
* until we got the response from the child.
*/
subreq = talloc_move(state->child->queue, &state->subreq);
talloc_move(subreq, &state->queue_subreq);
tevent_req_set_callback(subreq,
wb_child_request_orphaned,
NULL);
DBG_WARNING("keep orphaned subreq[%p]\n", subreq);
return;
}
TALLOC_FREE(state->subreq);
TALLOC_FREE(state->queue_subreq);