From 5bf386ad98350aae18eff7d016aa96f3ec44ae7e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 1 Oct 2010 08:54:54 +0200 Subject: [PATCH] librpc/rpc: add dcerpc_binding_handle_call_params* This function will allow to add dcerpc pipes support later. metze --- librpc/rpc/binding_handle.c | 143 ++++++++++++++++++++++++++++-------- librpc/rpc/rpc_common.h | 17 +++++ 2 files changed, 129 insertions(+), 31 deletions(-) diff --git a/librpc/rpc/binding_handle.c b/librpc/rpc/binding_handle.c index bb5245772e1c..c42b4e9900ca 100644 --- a/librpc/rpc/binding_handle.c +++ b/librpc/rpc/binding_handle.c @@ -344,35 +344,33 @@ NTSTATUS dcerpc_binding_handle_disconnect_recv(struct tevent_req *req) return NT_STATUS_OK; } -struct dcerpc_binding_handle_call_state { +struct dcerpc_binding_handle_call_params_state { struct dcerpc_binding_handle *h; const struct ndr_interface_call *call; - TALLOC_CTX *r_mem; - void *r_ptr; + struct dcerpc_binding_handle_call_params *params; struct ndr_push *push; DATA_BLOB request; DATA_BLOB response; struct ndr_pull *pull; }; -static void dcerpc_binding_handle_call_done(struct tevent_req *subreq); +static void dcerpc_binding_handle_call_params_done(struct tevent_req *subreq); -struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct dcerpc_binding_handle *h, - const struct GUID *object, - const struct ndr_interface_table *table, - uint32_t opnum, - TALLOC_CTX *r_mem, - void *r_ptr) +struct tevent_req *dcerpc_binding_handle_call_params_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct dcerpc_binding_handle *h, + const struct GUID *object, + const struct ndr_interface_table *table, + uint32_t opnum, + struct dcerpc_binding_handle_call_params *params) { struct tevent_req *req; - struct dcerpc_binding_handle_call_state *state; + struct dcerpc_binding_handle_call_params_state *state; struct tevent_req *subreq; enum ndr_err_code ndr_err; req = tevent_req_create(mem_ctx, &state, - struct dcerpc_binding_handle_call_state); + struct dcerpc_binding_handle_call_params_state); if (req == NULL) { return NULL; } @@ -389,9 +387,27 @@ struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx, state->h = h; state->call = &table->calls[opnum]; + state->params = params; + + if (params->in.num_pipes != state->call->in_pipes.num_pipes) { + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return tevent_req_post(req, ev); + } + + if (params->out.num_pipes != state->call->out_pipes.num_pipes) { + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return tevent_req_post(req, ev); + } - state->r_mem = r_mem; - state->r_ptr = r_ptr; + if (params->in.num_pipes != 0) { + tevent_req_nterror(req, NT_STATUS_RPC_CANNOT_SUPPORT); + return tevent_req_post(req, ev); + } + + if (params->out.num_pipes != 0) { + tevent_req_nterror(req, NT_STATUS_RPC_CANNOT_SUPPORT); + return tevent_req_post(req, ev); + } /* setup for a ndr_push_* call */ state->push = ndr_push_init_ctx(state); @@ -413,17 +429,17 @@ struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx, if (h->ops->do_ndr_print) { h->ops->do_ndr_print(h, NDR_IN | NDR_SET_VALUES, - state->r_ptr, state->call); + state->params->r_ptr, state->call); } /* push the structure into a blob */ - ndr_err = state->call->ndr_push(state->push, NDR_IN, state->r_ptr); + ndr_err = state->call->ndr_push(state->push, NDR_IN, state->params->r_ptr); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS error; error = ndr_map_error2ntstatus(ndr_err); if (h->ops->ndr_push_failed) { h->ops->ndr_push_failed(h, error, - state->r_ptr, + state->params->r_ptr, state->call); } tevent_req_nterror(req, error); @@ -452,18 +468,18 @@ struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, dcerpc_binding_handle_call_done, req); + tevent_req_set_callback(subreq, dcerpc_binding_handle_call_params_done, req); return req; } -static void dcerpc_binding_handle_call_done(struct tevent_req *subreq) +static void dcerpc_binding_handle_call_params_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - struct dcerpc_binding_handle_call_state *state = + struct dcerpc_binding_handle_call_params_state *state = tevent_req_data(req, - struct dcerpc_binding_handle_call_state); + struct dcerpc_binding_handle_call_params_state); struct dcerpc_binding_handle *h = state->h; NTSTATUS error; uint32_t out_flags = 0; @@ -490,10 +506,11 @@ static void dcerpc_binding_handle_call_done(struct tevent_req *subreq) state->pull->flags &= ~LIBNDR_FLAG_BIGENDIAN; } - state->pull->current_mem_ctx = state->r_mem; + state->pull->current_mem_ctx = state->params->r_mem; /* pull the structure from the blob */ - ndr_err = state->call->ndr_pull(state->pull, NDR_OUT, state->r_ptr); + ndr_err = state->call->ndr_pull(state->pull, NDR_OUT, + state->params->r_ptr); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { error = ndr_map_error2ntstatus(ndr_err); if (h->ops->ndr_pull_failed) { @@ -507,13 +524,13 @@ static void dcerpc_binding_handle_call_done(struct tevent_req *subreq) if (h->ops->do_ndr_print) { h->ops->do_ndr_print(h, NDR_OUT, - state->r_ptr, state->call); + state->params->r_ptr, state->call); } if (h->ops->ndr_validate_out) { error = h->ops->ndr_validate_out(h, state->pull, - state->r_ptr, + state->params->r_ptr, state->call); if (!NT_STATUS_IS_OK(error)) { tevent_req_nterror(req, error); @@ -524,6 +541,65 @@ static void dcerpc_binding_handle_call_done(struct tevent_req *subreq) tevent_req_done(req); } +NTSTATUS dcerpc_binding_handle_call_params_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +struct dcerpc_binding_handle_call_state { + struct dcerpc_binding_handle_call_params params; +}; + +static void dcerpc_binding_handle_call_done(struct tevent_req *subreq); + +struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct dcerpc_binding_handle *h, + const struct GUID *object, + const struct ndr_interface_table *table, + uint32_t opnum, + TALLOC_CTX *r_mem, + void *r_ptr) +{ + struct tevent_req *req; + struct dcerpc_binding_handle_call_state *state; + struct tevent_req *subreq; + + req = tevent_req_create(mem_ctx, &state, + struct dcerpc_binding_handle_call_state); + if (req == NULL) { + return NULL; + } + + state->params.r_mem = r_mem; + state->params.r_ptr = r_ptr; + + subreq = dcerpc_binding_handle_call_params_send(state, ev, h, + object, table, opnum, + &state->params); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, dcerpc_binding_handle_call_done, req); + + return req; +} + +static void dcerpc_binding_handle_call_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + NTSTATUS error; + + error = dcerpc_binding_handle_call_params_recv(subreq); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, error)) { + return; + } + + tevent_req_done(req); +} + NTSTATUS dcerpc_binding_handle_call_recv(struct tevent_req *req) { return tevent_req_simple_recv_ntstatus(req); @@ -539,6 +615,7 @@ NTSTATUS dcerpc_binding_handle_call(struct dcerpc_binding_handle *h, TALLOC_CTX *frame = talloc_stackframe(); struct tevent_context *ev; struct tevent_req *subreq; + struct dcerpc_binding_handle_call_params params; NTSTATUS status = NT_STATUS_NO_MEMORY; /* @@ -554,9 +631,13 @@ NTSTATUS dcerpc_binding_handle_call(struct dcerpc_binding_handle *h, goto fail; } - subreq = dcerpc_binding_handle_call_send(frame, ev, - h, object, table, - opnum, r_mem, r_ptr); + ZERO_STRUCT(params); + params.r_mem = r_mem; + params.r_ptr = r_ptr; + + subreq = dcerpc_binding_handle_call_params_send(frame, ev, h, + object, table, opnum, + ¶ms); if (subreq == NULL) { goto fail; } @@ -565,7 +646,7 @@ NTSTATUS dcerpc_binding_handle_call(struct dcerpc_binding_handle *h, goto fail; } - status = dcerpc_binding_handle_call_recv(subreq); + status = dcerpc_binding_handle_call_params_recv(subreq); fail: TALLOC_FREE(frame); return status; diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h index e2ea739cf3d1..8a8d3be6c3ee 100644 --- a/librpc/rpc/rpc_common.h +++ b/librpc/rpc/rpc_common.h @@ -366,6 +366,23 @@ struct tevent_req *dcerpc_binding_handle_disconnect_send(TALLOC_CTX *mem_ctx, struct dcerpc_binding_handle *h); NTSTATUS dcerpc_binding_handle_disconnect_recv(struct tevent_req *req); +struct dcerpc_binding_handle_call_params { + TALLOC_CTX *r_mem; + void *r_ptr; + struct { + uint32_t num_pipes; + struct dcerpc_pipe_handle_connection **pipes; + } in, out; +}; + +struct tevent_req *dcerpc_binding_handle_call_params_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct dcerpc_binding_handle *h, + const struct GUID *object, + const struct ndr_interface_table *table, + uint32_t opnum, + struct dcerpc_binding_handle_call_params *params); +NTSTATUS dcerpc_binding_handle_call_params_recv(struct tevent_req *req); struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct dcerpc_binding_handle *h, -- 2.34.1