From: Samuel Cabrero Date: Tue, 28 May 2019 10:05:45 +0000 (+0200) Subject: s3:rpc_server: Dispatch local calls through interfaces local handler X-Git-Tag: ldb-2.2.0~1315 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60fa8e255254d38e9443bf96f2c0f31430be6ab8;p=thirdparty%2Fsamba.git s3:rpc_server: Dispatch local calls through interfaces local handler Signed-off-by: Samuel Cabrero Reviewed-by: Andrew Bartlett --- diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c index 4fc6a756353..7f80fd0490f 100644 --- a/source3/rpc_server/rpc_ncacn_np.c +++ b/source3/rpc_server/rpc_ncacn_np.c @@ -297,61 +297,46 @@ static NTSTATUS make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx, } static NTSTATUS rpcint_dispatch(struct pipes_struct *p, + const struct ndr_interface_table *ndr_table, TALLOC_CTX *mem_ctx, uint32_t opnum, const DATA_BLOB *in_data, DATA_BLOB *out_data) { - struct pipe_rpc_fns *fns = find_pipe_fns_by_context(p->contexts, 0); - uint32_t num_cmds = fns->n_cmds; - const struct api_struct *cmds = fns->cmds; - uint32_t i; + NTSTATUS status; + const struct dcesrv_endpoint_server *ep_server = NULL; + struct dcesrv_interface iface; + const struct ndr_syntax_id *abstract_syntax = &ndr_table->syntax_id; bool ok; - /* set opnum */ - p->opnum = opnum; - - for (i = 0; i < num_cmds; i++) { - if (cmds[i].opnum == opnum && cmds[i].fn != NULL) { - break; - } - } - - if (i == num_cmds) { - return NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE; + ep_server = dcesrv_ep_server_byname(ndr_table->name); + if (ep_server == NULL) { + DBG_ERR("Failed to get DCE/RPC endpoint server '%s'\n", + ndr_table->name); + return NT_STATUS_NOT_FOUND; } - p->in_data.data = *in_data; - p->out_data.rdata = data_blob_null; - - ok = cmds[i].fn(p); - p->in_data.data = data_blob_null; + ok = ep_server->interface_by_uuid(&iface, &abstract_syntax->uuid, + abstract_syntax->if_version); if (!ok) { - data_blob_free(&p->out_data.rdata); - talloc_free_children(p->mem_ctx); - return NT_STATUS_RPC_CALL_FAILED; + DBG_ERR("Failed to get DCE/RPC interface\n"); + return NT_STATUS_NOT_FOUND; } - if (p->fault_state) { - NTSTATUS status; - - status = NT_STATUS(p->fault_state); - p->fault_state = 0; - data_blob_free(&p->out_data.rdata); - talloc_free_children(p->mem_ctx); + status = iface.local(p, opnum, mem_ctx, in_data, out_data); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n", + iface.name, opnum, + dcerpc_errstr(mem_ctx, p->fault_state)); return status; } - *out_data = p->out_data.rdata; - talloc_steal(mem_ctx, out_data->data); - p->out_data.rdata = data_blob_null; - - talloc_free_children(p->mem_ctx); return NT_STATUS_OK; } struct rpcint_bh_state { struct pipes_struct *p; + const struct ndr_interface_table *ndr_table; }; static bool rpcint_bh_is_connected(struct dcerpc_binding_handle *h) @@ -411,7 +396,10 @@ static struct tevent_req *rpcint_bh_raw_call_send(TALLOC_CTX *mem_ctx, } /* TODO: allow async */ - status = rpcint_dispatch(hs->p, state, opnum, + status = rpcint_dispatch(hs->p, + hs->ndr_table, + state, + opnum, &state->in_data, &state->out_data); if (!NT_STATUS_IS_OK(status)) { @@ -567,6 +555,8 @@ static NTSTATUS rpcint_binding_handle_ex(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } + hs->ndr_table = ndr_table; + status = make_internal_rpc_pipe_p(hs, abstract_syntax, remote_address,