From 7c8a7e8a15b433cd151afff0b52e9e5096a2c230 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Oct 2020 11:42:14 +0200 Subject: [PATCH] librpc/dcesrv_core: move two rpcint_dispatch() copies into dcesrv_call_dispatch_local() We only need this function once, so that we need to fix bugs only once... BUG: https://bugzilla.samba.org/show_bug.cgi?id=14551 Signed-off-by: Stefan Metzmacher Reviewed-by: Samuel Cabrero --- librpc/rpc/dcesrv_core.c | 63 +++++++++++++++++++++++++++ librpc/rpc/dcesrv_core.h | 2 + source3/rpc_server/rpc_ncacn_np.c | 65 +--------------------------- source3/winbindd/winbindd_dual_ndr.c | 65 +--------------------------- 4 files changed, 67 insertions(+), 128 deletions(-) diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c index a12bf134077..d39dbb43687 100644 --- a/librpc/rpc/dcesrv_core.c +++ b/librpc/rpc/dcesrv_core.c @@ -2971,3 +2971,66 @@ _PUBLIC_ NTSTATUS dcesrv_connection_loop_start(struct dcesrv_connection *conn) return NT_STATUS_OK; } + +_PUBLIC_ NTSTATUS dcesrv_call_dispatch_local(struct dcesrv_call_state *call) +{ + NTSTATUS status; + struct ndr_pull *pull = NULL; + struct ndr_push *push = NULL; + struct data_blob_list_item *rep = NULL; + + pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, + call); + if (pull == NULL) { + return NT_STATUS_NO_MEMORY; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + + call->ndr_pull = pull; + + /* unravel the NDR for the packet */ + status = call->context->iface->ndr_pull(call, call, pull, &call->r); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n", + call->context->iface->name, + call->pkt.u.request.opnum, + dcerpc_errstr(call, call->fault_code)); + return status; + } + + status = call->context->iface->local(call, call, call->r); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n", + call->context->iface->name, + call->pkt.u.request.opnum, + dcerpc_errstr(call, call->fault_code)); + return status; + } + + push = ndr_push_init_ctx(call); + if (push == NULL) { + return NT_STATUS_NO_MEMORY; + } + + push->ptr_count = call->ndr_pull->ptr_count; + + status = call->context->iface->ndr_push(call, call, push, call->r); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n", + call->context->iface->name, + call->pkt.u.request.opnum, + dcerpc_errstr(call, call->fault_code)); + return status; + } + + rep = talloc_zero(call, struct data_blob_list_item); + if (rep == NULL) { + return NT_STATUS_NO_MEMORY; + } + + rep->blob = ndr_push_blob(push); + DLIST_ADD_END(call->replies, rep); + + return NT_STATUS_OK; +} diff --git a/librpc/rpc/dcesrv_core.h b/librpc/rpc/dcesrv_core.h index c1234980b82..399c4ea8056 100644 --- a/librpc/rpc/dcesrv_core.h +++ b/librpc/rpc/dcesrv_core.h @@ -624,6 +624,8 @@ _PUBLIC_ void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn) _PUBLIC_ NTSTATUS dcesrv_connection_loop_start(struct dcesrv_connection *conn); +_PUBLIC_ NTSTATUS dcesrv_call_dispatch_local(struct dcesrv_call_state *call); + _PUBLIC_ const struct dcesrv_interface *find_interface_by_uuid( const struct dcesrv_endpoint *endpoint, const struct GUID *uuid, uint32_t if_version); diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c index 625b28c9209..d80c62e75d7 100644 --- a/source3/rpc_server/rpc_ncacn_np.c +++ b/source3/rpc_server/rpc_ncacn_np.c @@ -421,69 +421,6 @@ fail: return status; } -static NTSTATUS rpcint_dispatch(struct dcesrv_call_state *call) -{ - NTSTATUS status; - struct ndr_pull *pull = NULL; - struct ndr_push *push = NULL; - struct data_blob_list_item *rep = NULL; - - pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, - call); - if (pull == NULL) { - return NT_STATUS_NO_MEMORY; - } - - pull->flags |= LIBNDR_FLAG_REF_ALLOC; - - call->ndr_pull = pull; - - /* unravel the NDR for the packet */ - status = call->context->iface->ndr_pull(call, call, pull, &call->r); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n", - call->context->iface->name, - call->pkt.u.request.opnum, - dcerpc_errstr(call, call->fault_code)); - return status; - } - - status = call->context->iface->local(call, call, call->r); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n", - call->context->iface->name, - call->pkt.u.request.opnum, - dcerpc_errstr(call, call->fault_code)); - return status; - } - - push = ndr_push_init_ctx(call); - if (push == NULL) { - return NT_STATUS_NO_MEMORY; - } - - push->ptr_count = call->ndr_pull->ptr_count; - - status = call->context->iface->ndr_push(call, call, push, call->r); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n", - call->context->iface->name, - call->pkt.u.request.opnum, - dcerpc_errstr(call, call->fault_code)); - return status; - } - - rep = talloc_zero(call, struct data_blob_list_item); - if (rep == NULL) { - return NT_STATUS_NO_MEMORY; - } - - rep->blob = ndr_push_blob(push); - DLIST_ADD_END(call->replies, rep); - - return NT_STATUS_OK; -} - struct rpcint_bh_state { struct dcesrv_connection *conn; }; @@ -567,7 +504,7 @@ static struct tevent_req *rpcint_bh_raw_call_send(TALLOC_CTX *mem_ctx, state->call->pkt.u.request.stub_and_verifier.length = in_length; /* TODO: allow async */ - status = rpcint_dispatch(state->call); + status = dcesrv_call_dispatch_local(state->call); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); return tevent_req_post(req, ev); diff --git a/source3/winbindd/winbindd_dual_ndr.c b/source3/winbindd/winbindd_dual_ndr.c index f2d8c815dca..f0b8588f6a0 100644 --- a/source3/winbindd/winbindd_dual_ndr.c +++ b/source3/winbindd/winbindd_dual_ndr.c @@ -475,69 +475,6 @@ struct dcerpc_binding_handle *wbint_binding_handle(TALLOC_CTX *mem_ctx, return h; } -static NTSTATUS rpcint_dispatch(struct dcesrv_call_state *call) -{ - NTSTATUS status; - struct ndr_pull *pull = NULL; - struct ndr_push *push = NULL; - struct data_blob_list_item *rep = NULL; - - pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, - call); - if (pull == NULL) { - return NT_STATUS_NO_MEMORY; - } - - pull->flags |= LIBNDR_FLAG_REF_ALLOC; - - call->ndr_pull = pull; - - /* unravel the NDR for the packet */ - status = call->context->iface->ndr_pull(call, call, pull, &call->r); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n", - call->context->iface->name, - call->pkt.u.request.opnum, - dcerpc_errstr(call, call->fault_code)); - return status; - } - - status = call->context->iface->local(call, call, call->r); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n", - call->context->iface->name, - call->pkt.u.request.opnum, - dcerpc_errstr(call, call->fault_code)); - return status; - } - - push = ndr_push_init_ctx(call); - if (push == NULL) { - return NT_STATUS_NO_MEMORY; - } - - push->ptr_count = call->ndr_pull->ptr_count; - - status = call->context->iface->ndr_push(call, call, push, call->r); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n", - call->context->iface->name, - call->pkt.u.request.opnum, - dcerpc_errstr(call, call->fault_code)); - return status; - } - - rep = talloc_zero(call, struct data_blob_list_item); - if (rep == NULL) { - return NT_STATUS_NO_MEMORY; - } - - rep->blob = ndr_push_blob(push); - DLIST_ADD_END(call->replies, rep); - - return NT_STATUS_OK; -} - enum winbindd_result winbindd_dual_ndrcmd(struct winbindd_domain *domain, struct winbindd_cli_state *state) { @@ -599,7 +536,7 @@ enum winbindd_result winbindd_dual_ndrcmd(struct winbindd_domain *domain, data_blob_const(state->request->extra_data.data, state->request->extra_len); - status = rpcint_dispatch(dcesrv_call); + status = dcesrv_call_dispatch_local(dcesrv_call); if (!NT_STATUS_IS_OK(status)) { goto out; } -- 2.34.1