From: Stefan Metzmacher Date: Fri, 11 Sep 2020 13:42:42 +0000 (+0200) Subject: CVE-2020-25717 winbindd: defer the setup_child() from init_idmap_child() X-Git-Tag: samba-4.13.14~252 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3812930e641d10d1ead10b52ddc7240dd585d0f6;p=thirdparty%2Fsamba.git CVE-2020-25717 winbindd: defer the setup_child() from init_idmap_child() At startup we trigger a wb_parent_idmap_setup_send() and make sure setup_child() is called just before wb_parent_idmap_setup_recv() finished. This makes sure our view of the idmap config in the parent matches what we have in the child. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 Signed-off-by: Stefan Metzmacher Reviewed-by: Gary Lockyer BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556 (cherry picked from commit 28e020c0a863411cfa95e3b1ed943d922b8635bd) --- diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c index 14836e3b8a0..3e2461478a9 100644 --- a/source3/winbindd/winbindd_idmap.c +++ b/source3/winbindd/winbindd_idmap.c @@ -81,11 +81,44 @@ static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = { } }; +static void init_idmap_child_done(struct tevent_req *subreq); + void init_idmap_child(void) { - setup_child(NULL, &static_idmap_child, - idmap_dispatch_table, - "log.winbindd", "idmap"); + struct tevent_req *subreq = NULL; + + subreq = wb_parent_idmap_setup_send(global_event_context(), + global_event_context()); + if (subreq == NULL) { + /* + * This is only an optimization, so we're free to + * to ignore errors + */ + DBG_ERR("wb_parent_idmap_setup_send() failed\n"); + return; + } + tevent_req_set_callback(subreq, init_idmap_child_done, NULL); + DBG_DEBUG("wb_parent_idmap_setup_send() started\n"); +} + +static void init_idmap_child_done(struct tevent_req *subreq) +{ + const struct wb_parent_idmap_config *cfg = NULL; + NTSTATUS status; + + status = wb_parent_idmap_setup_recv(subreq, &cfg); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + /* + * This is only an optimization, so we're free to + * to ignore errors + */ + DBG_ERR("wb_parent_idmap_setup_recv() failed %s\n", + nt_errstr(status)); + return; + } + + DBG_DEBUG("wb_parent_idmap_setup_recv() finished\n"); } struct wb_parent_idmap_setup_state { @@ -306,6 +339,12 @@ static void wb_parent_idmap_setup_lookupname_next(struct tevent_req *req) next_domain: if (state->dom_idx == state->cfg->num_doms) { + /* + * We're done, so start the idmap child + */ + setup_child(NULL, &static_idmap_child, + idmap_dispatch_table, + "log.winbindd", "idmap"); tevent_req_done(req); return; }