winbind: Maintain a binding handle per domain and always go via wb_domain_request_send()
authorVolker Lendecke <vl@samba.org>
Tue, 13 Feb 2018 15:04:44 +0000 (16:04 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 23 Feb 2018 03:09:18 +0000 (04:09 +0100)
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Volker Lendecke <vl@samba.org>
source3/winbindd/winbindd.h
source3/winbindd/winbindd_dual.c
source3/winbindd/winbindd_dual_ndr.c
source3/winbindd/winbindd_util.c

index 3e4b256ef32ed344b93cad388c305fe217e21d75..8a44f37789b52c92fa11e6e3b17258160bb298a5 100644 (file)
@@ -184,6 +184,8 @@ struct winbindd_domain {
 
        struct winbindd_child *children;
 
+       struct dcerpc_binding_handle *binding_handle;
+
        /* Callback we use to try put us back online. */
 
        uint32_t check_online_timeout;
index 21fe3c29fc1cf4e1fe35e845d44d7034caf5c12a..a30ac36a8b0c65b0aadf00f4225c3fb6ba00195f 100644 (file)
@@ -321,10 +321,7 @@ static struct winbindd_child *choose_domain_child(struct winbindd_domain *domain
 
 struct dcerpc_binding_handle *dom_child_handle(struct winbindd_domain *domain)
 {
-       struct winbindd_child *child;
-
-       child = choose_domain_child(domain);
-       return child->binding_handle;
+       return domain->binding_handle;
 }
 
 struct wb_domain_request_state {
@@ -608,8 +605,10 @@ void setup_child(struct winbindd_domain *domain, struct winbindd_child *child,
        child->table = table;
        child->queue = tevent_queue_create(NULL, "winbind_child");
        SMB_ASSERT(child->queue != NULL);
-       child->binding_handle = wbint_binding_handle(NULL, domain, child);
-       SMB_ASSERT(child->binding_handle != NULL);
+       if (domain == NULL) {
+               child->binding_handle = wbint_binding_handle(NULL, NULL, child);
+               SMB_ASSERT(child->binding_handle != NULL);
+       }
 }
 
 void winbind_child_died(pid_t pid)
index 00c7df1f863f6c956ab6f66274d93ba7ca0dc3f2..25e7445edc6aac532dc05e7809019000ddca99ae 100644 (file)
@@ -42,7 +42,7 @@ static bool wbint_bh_is_connected(struct dcerpc_binding_handle *h)
        struct wbint_bh_state *hs = dcerpc_binding_handle_data(h,
                                     struct wbint_bh_state);
 
-       if (!hs->child) {
+       if ((hs->domain == NULL) && (hs->child == NULL)) {
                return false;
        }
 
@@ -65,7 +65,8 @@ struct wbint_bh_raw_call_state {
        DATA_BLOB out_data;
 };
 
-static void wbint_bh_raw_call_done(struct tevent_req *subreq);
+static void wbint_bh_raw_call_child_done(struct tevent_req *subreq);
+static void wbint_bh_raw_call_domain_done(struct tevent_req *subreq);
 
 static struct tevent_req *wbint_bh_raw_call_send(TALLOC_CTX *mem_ctx,
                                                  struct tevent_context *ev,
@@ -114,17 +115,28 @@ static struct tevent_req *wbint_bh_raw_call_send(TALLOC_CTX *mem_ctx,
        state->request.extra_data.data = (char *)state->in_data.data;
        state->request.extra_len = state->in_data.length;
 
-       subreq = wb_child_request_send(state, ev, hs->child,
-                                      &state->request);
+       if (hs->child != NULL) {
+               subreq = wb_child_request_send(state, ev, hs->child,
+                                              &state->request);
+               if (tevent_req_nomem(subreq, req)) {
+                       return tevent_req_post(req, ev);
+               }
+               tevent_req_set_callback(
+                       subreq, wbint_bh_raw_call_child_done, req);
+               return req;
+       }
+
+       subreq = wb_domain_request_send(state, ev, hs->domain,
+                                       &state->request);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       tevent_req_set_callback(subreq, wbint_bh_raw_call_done, req);
+       tevent_req_set_callback(subreq, wbint_bh_raw_call_domain_done, req);
 
        return req;
 }
 
-static void wbint_bh_raw_call_done(struct tevent_req *subreq)
+static void wbint_bh_raw_call_child_done(struct tevent_req *subreq)
 {
        struct tevent_req *req =
                tevent_req_callback_data(subreq,
@@ -158,6 +170,40 @@ static void wbint_bh_raw_call_done(struct tevent_req *subreq)
        tevent_req_done(req);
 }
 
+static void wbint_bh_raw_call_domain_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req =
+               tevent_req_callback_data(subreq,
+               struct tevent_req);
+       struct wbint_bh_raw_call_state *state =
+               tevent_req_data(req,
+               struct wbint_bh_raw_call_state);
+       int ret, err;
+
+       ret = wb_domain_request_recv(subreq, state, &state->response, &err);
+       TALLOC_FREE(subreq);
+       if (ret == -1) {
+               NTSTATUS status = map_nt_error_from_unix(err);
+               tevent_req_nterror(req, status);
+               return;
+       }
+
+       state->out_data = data_blob_talloc(state,
+               state->response->extra_data.data,
+               state->response->length - sizeof(struct winbindd_response));
+       if (state->response->extra_data.data && !state->out_data.data) {
+               tevent_req_oom(req);
+               return;
+       }
+
+       if (state->domain != NULL) {
+               wcache_store_ndr(state->domain, state->opnum,
+                                &state->in_data, &state->out_data);
+       }
+
+       tevent_req_done(req);
+}
+
 static NTSTATUS wbint_bh_raw_call_recv(struct tevent_req *req,
                                        TALLOC_CTX *mem_ctx,
                                        uint8_t **out_data,
@@ -209,9 +255,8 @@ static struct tevent_req *wbint_bh_disconnect_send(TALLOC_CTX *mem_ctx,
 
        /*
         * TODO: do a real async disconnect ...
-        *
-        * For now the caller needs to free rpc_cli
         */
+       hs->domain = NULL;
        hs->child = NULL;
 
        tevent_req_done(req);
index 9950c669629da80001a747efdfe729f44a2bfd90..78f526cdea894cc73e9178b3676b2fe5de329897 100644 (file)
@@ -228,6 +228,12 @@ static NTSTATUS add_trusted_domain(const char *domain_name,
                return NT_STATUS_NO_MEMORY;
        }
 
+       domain->binding_handle = wbint_binding_handle(domain, domain, NULL);
+       if (domain->binding_handle == NULL) {
+               TALLOC_FREE(domain);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        domain->name = talloc_strdup(domain, domain_name);
        if (domain->name == NULL) {
                TALLOC_FREE(domain);