SPLIT: get async winbind child building
authorDavid Disseldorp <ddiss@samba.org>
Thu, 18 Apr 2013 13:39:58 +0000 (15:39 +0200)
committerDavid Disseldorp <ddiss@samba.org>
Thu, 18 Apr 2013 13:39:58 +0000 (15:39 +0200)
source3/winbindd/winbindd.h
source3/winbindd/winbindd_domain.c
source3/winbindd/winbindd_dual.c
source3/winbindd/winbindd_dual_ndr.c
source3/winbindd/winbindd_idmap.c
source3/winbindd/winbindd_locator.c
source3/winbindd/winbindd_proto.h

index f36e7fd2885d972439dbd98f8ea43f99c90fe5e3..7c229254fe82e8dffc1885d5fcd2c6482a99b0ad 100644 (file)
@@ -137,8 +137,10 @@ struct winbindd_child_dispatch_table {
                        struct tevent_req *(*struct_fn_send)(TALLOC_CTX *mem_ctx,
                                                             struct tevent_context *ev,
                                                             struct winbindd_domain *domain,
-                                                            struct winbindd_cli_state *state);
-                       enum winbindd_result (*struct_fn_recv)(struct tevent_req *req);
+                                                            struct winbindd_request *wb_req);
+                       NTSTATUS (*struct_fn_recv)(struct tevent_req *req,
+                                                  TALLOC_CTX *mem_ctx,
+                                                  struct winbindd_response *wb_rsp);
                } async;
        };
 };
index e8bf92e29431307f9c1c5ac847e7664044b344e4..249def4b11d56317fbe0a24a1a62b9220949a99e 100644 (file)
@@ -69,8 +69,9 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
        },{
                .name           = "NDRCMD",
                .struct_cmd     = WINBINDD_DUAL_NDRCMD,
-               .type           = WINBINDD_CHILD_DISPATCH_SYNC,
-               .sync.struct_fn = winbindd_dual_ndrcmd,
+               .type           = WINBINDD_CHILD_DISPATCH_ASYNC,
+               .async.struct_fn_send = winbindd_dual_ndrcmd_send,
+               .async.struct_fn_recv = winbindd_dual_ndrcmd_recv,
        },{
                .name           = NULL,
        }
index 9a8f2482f9c6a876285063df8f58263bcff1ecd4..ea7b99ff81a6d986ed8539c395b224196bf1f3b2 100644 (file)
@@ -494,7 +494,8 @@ static struct tevent_req *child_process_request_send(TALLOC_CTX *mem_ctx,
                } else if (table->type == WINBINDD_CHILD_DISPATCH_ASYNC) {
                        struct tevent_req *subreq;
                        subreq = table->async.struct_fn_send(cr_state, ev,
-                                                            domain, state);
+                                                            domain,
+                                                            state->request);
                        if (tevent_req_nomem(subreq, req)) {
                                return tevent_req_post(req, ev);
                        }
@@ -516,19 +517,26 @@ static struct tevent_req *child_process_request_send(TALLOC_CTX *mem_ctx,
 /* only used for async dispatch table entries */
 static void child_process_request_done(struct tevent_req *subreq)
 {
+       NTSTATUS status;
        struct tevent_req *req = tevent_req_callback_data(
                subreq, struct tevent_req);
        struct child_req_state *cr_state = tevent_req_data(req,
                                                        struct child_req_state);
 
        SMB_ASSERT(cr_state->table->type == WINBINDD_CHILD_DISPATCH_ASYNC);
-       cr_state->response->result = cr_state->table->async.struct_fn_recv(subreq);
+       /* use response as memory context, should not be freed with req */
+       status = cr_state->table->async.struct_fn_recv(subreq,
+                                                      cr_state->response,
+                                                      cr_state->response);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
        tevent_req_done(req);
 }
 
 /*
  * TODO: child_process_request_send code path fills state->response, nothing to
- * do here until async support is added.
+ * do here.
  */
 static NTSTATUS child_process_request_recv(struct tevent_req *req,
                                           struct winbindd_response *rsp)
@@ -540,6 +548,7 @@ static NTSTATUS child_process_request_recv(struct tevent_req *req,
                return status;
        }
 
+       tevent_req_received(req);
        return NT_STATUS_OK;
 }
 
@@ -1674,11 +1683,17 @@ static void domain_child_loop_done(struct tevent_req *req)
        DEBUG(4, ("Finished processing child request %d\n",
                  (int)state->request->cmd));
 
-       child_process_request_recv(req, state->response);
+       status = child_process_request_recv(req, state->response);
        talloc_free(req);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("child request failed: %s\n", nt_errstr(status)));
+               /* state->response->result set on error */
+       }
 
        status = child_write_response(state->sock, state->response);
        if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("exiting, child failed to write response: %s\n",
+                         nt_errstr(status)));
                _exit(1);
        }
        TALLOC_FREE(state->mem_ctx);
index e6959e2104779aa579f1c472f702c7ad1c3fdf22..b07262487ec28a8a210914ac9c769518c060c5b9 100644 (file)
@@ -296,58 +296,97 @@ struct dcerpc_binding_handle *wbint_binding_handle(TALLOC_CTX *mem_ctx,
        return h;
 }
 
-enum winbindd_result winbindd_dual_ndrcmd(struct winbindd_domain *domain,
-                                         struct winbindd_cli_state *state)
-{
+struct winbindd_dual_ndrcmd_state {
+       struct api_struct *fn;
+       bool fn_ret;
        struct pipes_struct p;
+};
+static void winbindd_dual_ndrcmd_done(struct tevent_req *subreq);
+
+struct tevent_req *winbindd_dual_ndrcmd_send(TALLOC_CTX *mem_ctx,
+                                            struct tevent_context *ev,
+                                            struct winbindd_domain *domain,
+                                            struct winbindd_request *wb_req)
+{
+       struct winbindd_dual_ndrcmd_state *nc_state;
        struct api_struct *fns;
        int num_fns;
-       bool ret;
+       struct tevent_req *req;
        struct tevent_req *subreq;
-       struct tevent_context *ev = winbind_event_context();
+
+       req = tevent_req_create(mem_ctx, &nc_state,
+                               struct winbindd_dual_ndrcmd_state);
+       if (req == NULL) {
+               return NULL;
+       }
 
        wbint_get_pipe_fns(&fns, &num_fns);
 
-       if (state->request->data.ndrcmd >= num_fns) {
-               return WINBINDD_ERROR;
+       if (wb_req->data.ndrcmd >= num_fns) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return tevent_req_post(req, ev);
        }
+       nc_state->fn = &fns[wb_req->data.ndrcmd];
 
        DEBUG(10, ("winbindd_dual_ndrcmd: Running command %s (%s)\n",
-                  fns[state->request->data.ndrcmd].name,
+                  nc_state->fn->name,
                   domain ? domain->name : "no domain"));
 
-       ZERO_STRUCT(p);
-       p.mem_ctx = talloc_stackframe();
-       p.in_data.data = data_blob_const(state->request->extra_data.data,
-                                        state->request->extra_len);
+       nc_state->p.mem_ctx = nc_state;
+       nc_state->p.in_data.data = data_blob_const(wb_req->extra_data.data,
+                                                      wb_req->extra_len);
 
-       subreq = fns[state->request->data.ndrcmd].fn_send(ev, p.mem_ctx, &p);
-       if (subreq == NULL) {
-               TALLOC_FREE(p.mem_ctx);
-               return WINBINDD_ERROR;
+       subreq = nc_state->fn->fn_send(ev, nc_state, &nc_state->p);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
        }
 
-       ret = tevent_req_poll(subreq, ev);
-       if (!ret) {
-               TALLOC_FREE(p.mem_ctx);
-               return WINBINDD_ERROR;
-       }
+       tevent_req_set_callback(subreq,
+                               winbindd_dual_ndrcmd_done,
+                               req);
+       return req;
+}
 
-       ret = fns[state->request->data.ndrcmd].fn_recv(subreq);
-       if (!ret) {
-               TALLOC_FREE(p.mem_ctx);
-               return WINBINDD_ERROR;
-       }
+static void winbindd_dual_ndrcmd_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_dual_ndrcmd_state *nc_state = tevent_req_data(req,
+                                       struct winbindd_dual_ndrcmd_state);
 
-       state->response->extra_data.data =
-               talloc_move(state->mem_ctx, &p.out_data.rdata.data);
-       state->response->length += p.out_data.rdata.length;
-       p.out_data.rdata.length = 0;
+       /* response stored in nc_state->p */
+       nc_state->fn_ret = nc_state->fn->fn_recv(subreq);
+       tevent_req_done(req);
+}
 
-       TALLOC_FREE(p.mem_ctx);
+NTSTATUS winbindd_dual_ndrcmd_recv(struct tevent_req *req,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct winbindd_response *wb_rsp)
+{
+       NTSTATUS status;
+       struct winbindd_dual_ndrcmd_state *nc_state = tevent_req_data(req,
+                                       struct winbindd_dual_ndrcmd_state);
+
+       if (tevent_req_is_nterror(req, &status)) {
+               wb_rsp->result = WINBINDD_ERROR;
+               goto out_recvd;
+       } else if (!nc_state->fn_ret) {
+               wb_rsp->result = WINBINDD_ERROR;
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out_recvd;
+       }
 
-       if (state->response->extra_data.data == NULL) {
-               return WINBINDD_ERROR;
+       wb_rsp->extra_data.data = talloc_move(mem_ctx,
+                                       &nc_state->p.out_data.rdata.data);
+       if (wb_rsp->extra_data.data == NULL) {
+               wb_rsp->result = WINBINDD_ERROR;
+               status = NT_STATUS_NO_MEMORY;
+               goto out_recvd;
        }
-       return WINBINDD_OK;
+       wb_rsp->length += nc_state->p.out_data.rdata.length;
+       status = NT_STATUS_OK;
+
+out_recvd:
+       tevent_req_received(req);
+       return status;
 }
index 21b5ae1b6d5a04e09ac10642a63093efe7d3f95f..dc1b2d18dc276a4f012a721d6a4736fc116f9017 100644 (file)
@@ -43,8 +43,9 @@ static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = {
        },{
                .name           = "NDRCMD",
                .struct_cmd     = WINBINDD_DUAL_NDRCMD,
-               .type           = WINBINDD_CHILD_DISPATCH_SYNC,
-               .sync.struct_fn = winbindd_dual_ndrcmd,
+               .type           = WINBINDD_CHILD_DISPATCH_ASYNC,
+               .async.struct_fn_send = winbindd_dual_ndrcmd_send,
+               .async.struct_fn_recv = winbindd_dual_ndrcmd_recv,
        },{
                .name           = NULL,
        }
index 11545703d8cf3bc45aea1bd310f60f8a7dcd8a3f..eb6bb35d132d1ab3af1faf889a602d277c9e9cdf 100644 (file)
@@ -43,8 +43,9 @@ static const struct winbindd_child_dispatch_table locator_dispatch_table[] = {
        },{
                .name           = "NDRCMD",
                .struct_cmd     = WINBINDD_DUAL_NDRCMD,
-               .type           = WINBINDD_CHILD_DISPATCH_SYNC,
-               .sync.struct_fn = winbindd_dual_ndrcmd,
+               .type           = WINBINDD_CHILD_DISPATCH_ASYNC,
+               .async.struct_fn_send = winbindd_dual_ndrcmd_send,
+               .async.struct_fn_recv = winbindd_dual_ndrcmd_recv,
        },{
                .name           = NULL,
        }
index 41aa9ac10d2f3a71c06905bd8f7846fcc096f4db..f48245a0682aa7436729167cab60eb743c5242dd 100644 (file)
@@ -458,8 +458,13 @@ enum winbindd_result winbindd_dual_ping(struct winbindd_domain *domain,
 struct dcerpc_binding_handle *wbint_binding_handle(TALLOC_CTX *mem_ctx,
                                                struct winbindd_domain *domain,
                                                struct winbindd_child *child);
-enum winbindd_result winbindd_dual_ndrcmd(struct winbindd_domain *domain,
-                                         struct winbindd_cli_state *state);
+struct tevent_req *winbindd_dual_ndrcmd_send(TALLOC_CTX *mem_ctx,
+                                            struct tevent_context *ev,
+                                            struct winbindd_domain *domain,
+                                            struct winbindd_request *request);
+NTSTATUS winbindd_dual_ndrcmd_recv(struct tevent_req *req,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct winbindd_response *response);
 
 struct tevent_req *wb_lookupsid_send(TALLOC_CTX *mem_ctx,
                                     struct tevent_context *ev,