winbind: improve wb_domain_request_send() to use wb_dsgetdcname_send() for a foreign...
authorStefan Metzmacher <metze@samba.org>
Wed, 14 Feb 2018 14:11:50 +0000 (15:11 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 23 Feb 2018 03:09:18 +0000 (04:09 +0100)
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 <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source3/winbindd/winbindd_dual.c

index cd67aece66495c4e32cddd68ed7562796c90676d..1dd8b6f42e9d6a247d97e86620ba6c2cb8458969 100644 (file)
@@ -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);