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;
};
};
},{
.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,
}
} 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);
}
/* 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)
return status;
}
+ tevent_req_received(req);
return NT_STATUS_OK;
}
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);
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;
}
},{
.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,
}
},{
.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,
}
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,