From 2b05f1098187e00166649c8ea7c63e6901b9d242 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Mar 2018 14:48:46 +0100 Subject: [PATCH] s3:messages: allow messaging_filtered_read_send() to use wrapper tevent_context As it gets 'messaging_context' as argument, we're sure a messaging context with a raw tevent context already exist. It means we can allow a wrapper tevent context that wrapps the main tevent context of the messaging context. The use of tevent_req_defer_callback() makes sure that the callers callback function calls messaging_filtered_read_recv() from the correct "wrapped" environment. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source3/lib/messages.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/source3/lib/messages.c b/source3/lib/messages.c index 1a5ea4659aa..dab53f1c48e 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -206,7 +206,7 @@ static bool messaging_register_event_context(struct messaging_context *ctx, continue; } - if (reg->ev == ev) { + if (tevent_context_same_loop(reg->ev, ev)) { reg->refcount += 1; return true; } @@ -255,7 +255,7 @@ static bool messaging_deregister_event_context(struct messaging_context *ctx, continue; } - if (reg->ev == ev) { + if (tevent_context_same_loop(reg->ev, ev)) { reg->refcount -= 1; if (reg->refcount == 0) { @@ -1034,7 +1034,9 @@ struct tevent_req *messaging_filtered_read_send( state->filter = filter; state->private_data = private_data; - if (tevent_context_is_wrapper(ev)) { + if (tevent_context_is_wrapper(ev) && + !tevent_context_same_loop(ev, msg_ctx->event_ctx)) + { /* This is really a programmer error! */ DBG_ERR("Wrapper tevent context doesn't use main context.\n"); tevent_req_error(req, EINVAL); @@ -1043,7 +1045,11 @@ struct tevent_req *messaging_filtered_read_send( /* * We have to defer the callback here, as we might be called from - * within a different tevent_context than state->ev + * within a different tevent_context than state->ev. + * + * This is important for two cases: + * 1. nested event contexts, used by blocking ctdb calls + * 2. possible impersonation using wrapper tevent contexts. */ tevent_req_defer_callback(req, state->ev); @@ -1339,7 +1345,7 @@ static bool messaging_dispatch_waiters(struct messaging_context *msg_ctx, state = tevent_req_data( req, struct messaging_filtered_read_state); - if ((ev == state->ev) && + if (tevent_context_same_loop(ev, state->ev) && state->filter(rec, state->private_data)) { messaging_filtered_read_done(req, rec); return true; -- 2.11.4.GIT