From e8dffbf1362b15a6bf5e23afd86c294461585519 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 14 Feb 2018 15:09:51 +0100 Subject: [PATCH 1/2] winbind: use state->{ev,request} in wb_domain_request_send() This will reduce the diff for the following changes. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13295 Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke (cherry picked from commit 4d804f5f3e65df0e2f646d4f88793cab8e2f32d1) --- source3/winbindd/winbindd_dual.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index a5d8eeed465..eafd3d8469e 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -354,11 +354,15 @@ struct tevent_req *wb_domain_request_send(TALLOC_CTX *mem_ctx, return NULL; } + state->domain = domain; + state->ev = ev; + state->request = request; + state->child = choose_domain_child(domain); if (domain->initialized) { - subreq = wb_child_request_send(state, ev, state->child, - request); + subreq = wb_child_request_send(state, state->ev, state->child, + state->request); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -366,10 +370,6 @@ struct tevent_req *wb_domain_request_send(TALLOC_CTX *mem_ctx, return req; } - state->domain = domain; - state->ev = ev; - state->request = request; - state->init_req = talloc_zero(state, struct winbindd_request); if (tevent_req_nomem(state->init_req, req)) { return tevent_req_post(req, ev); @@ -382,7 +382,7 @@ struct tevent_req *wb_domain_request_send(TALLOC_CTX *mem_ctx, state->init_req->data.init_conn.is_primary = domain->primary; fstrcpy(state->init_req->data.init_conn.dcname, ""); - subreq = wb_child_request_send(state, ev, state->child, + subreq = wb_child_request_send(state, state->ev, state->child, state->init_req); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); @@ -403,7 +403,8 @@ struct tevent_req *wb_domain_request_send(TALLOC_CTX *mem_ctx, state->init_req->cmd = WINBINDD_GETDCNAME; fstrcpy(state->init_req->domain_name, domain->name); - subreq = wb_child_request_send(state, ev, state->child, request); + subreq = wb_child_request_send(state, state->ev, state->child, + state->request); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } -- 2.13.6 From fea259a40d53d6713ca595f6825f7c4710279651 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 14 Feb 2018 15:11:50 +0100 Subject: [PATCH 2/2] winbind: improve wb_domain_request_send() to use wb_dsgetdcname_send() for a foreign domain Commit ed3bc614cccec6167c64ac58d78344b6426cd019 got the logic wrong while trying to implement the logic we had in init_child_connection(), which was removed by commit d61f3626b79e0523beadff355453145aa7b0195c. Instead of doing a WINBINDD_GETDCNAME request (which would caused an error because the implementation was removed in commit 958fdaf5c3ba17969a5110e6b2b08babb9096d7e), we sent the callers request and interpreted the result as WINBINDD_GETDCNAME response, which led to an empty dcname variable. As result the domain child opened a connection to the primary domain in order to lookup a dc. If we want to connect the primary domain from the parent via a domain child of the primary domain. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13295 Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke (cherry picked from commit 1f41193e005df37401a28004f0a95d4d73b98ccd) --- source3/winbindd/winbindd_dual.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index eafd3d8469e..3d44e2027ae 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -393,18 +393,18 @@ struct tevent_req *wb_domain_request_send(TALLOC_CTX *mem_ctx, } /* - * Ask our DC for a DC name + * This is *not* the primary domain, + * let's ask our DC about a DC name. + * + * We prefer getting a dns name in dc_unc, + * which is indicated by DS_RETURN_DNS_NAME. + * For NT4 domains we still get the netbios name. */ - domain = find_our_domain(); - - /* This is *not* the primary domain, let's ask our DC about a DC - * name */ - - state->init_req->cmd = WINBINDD_GETDCNAME; - fstrcpy(state->init_req->domain_name, domain->name); - - subreq = wb_child_request_send(state, state->ev, state->child, - state->request); + subreq = wb_dsgetdcname_send(state, state->ev, + state->domain->name, + NULL, /* domain_guid */ + NULL, /* site_name */ + DS_RETURN_DNS_NAME); /* flags */ if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -418,22 +418,26 @@ static void wb_domain_request_gotdc(struct tevent_req *subreq) subreq, struct tevent_req); struct wb_domain_request_state *state = tevent_req_data( req, struct wb_domain_request_state); - struct winbindd_response *response; - int ret, err; + struct netr_DsRGetDCNameInfo *dcinfo = NULL; + NTSTATUS status; + const char *dcname = NULL; - ret = wb_child_request_recv(subreq, talloc_tos(), &response, &err); + status = wb_dsgetdcname_recv(subreq, state, &dcinfo); TALLOC_FREE(subreq); - if (ret == -1) { - tevent_req_error(req, err); + if (tevent_req_nterror(req, status)) { return; } + dcname = dcinfo->dc_unc; + while (dcname != NULL && *dcname == '\\') { + dcname++; + } state->init_req->cmd = WINBINDD_INIT_CONNECTION; fstrcpy(state->init_req->domain_name, state->domain->name); state->init_req->data.init_conn.is_primary = False; fstrcpy(state->init_req->data.init_conn.dcname, - response->data.dc_name); + dcname); - TALLOC_FREE(response); + TALLOC_FREE(dcinfo); subreq = wb_child_request_send(state, state->ev, state->child, state->init_req); -- 2.13.6