mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
s3:rpc_server: Dispatch local calls through interfaces local handler
Signed-off-by: Samuel Cabrero <scabrero@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
42a7e7bcad
commit
60fa8e2552
@ -297,61 +297,46 @@ static NTSTATUS make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS rpcint_dispatch(struct pipes_struct *p,
|
static NTSTATUS rpcint_dispatch(struct pipes_struct *p,
|
||||||
|
const struct ndr_interface_table *ndr_table,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
uint32_t opnum,
|
uint32_t opnum,
|
||||||
const DATA_BLOB *in_data,
|
const DATA_BLOB *in_data,
|
||||||
DATA_BLOB *out_data)
|
DATA_BLOB *out_data)
|
||||||
{
|
{
|
||||||
struct pipe_rpc_fns *fns = find_pipe_fns_by_context(p->contexts, 0);
|
NTSTATUS status;
|
||||||
uint32_t num_cmds = fns->n_cmds;
|
const struct dcesrv_endpoint_server *ep_server = NULL;
|
||||||
const struct api_struct *cmds = fns->cmds;
|
struct dcesrv_interface iface;
|
||||||
uint32_t i;
|
const struct ndr_syntax_id *abstract_syntax = &ndr_table->syntax_id;
|
||||||
bool ok;
|
bool ok;
|
||||||
|
|
||||||
/* set opnum */
|
ep_server = dcesrv_ep_server_byname(ndr_table->name);
|
||||||
p->opnum = opnum;
|
if (ep_server == NULL) {
|
||||||
|
DBG_ERR("Failed to get DCE/RPC endpoint server '%s'\n",
|
||||||
for (i = 0; i < num_cmds; i++) {
|
ndr_table->name);
|
||||||
if (cmds[i].opnum == opnum && cmds[i].fn != NULL) {
|
return NT_STATUS_NOT_FOUND;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == num_cmds) {
|
ok = ep_server->interface_by_uuid(&iface, &abstract_syntax->uuid,
|
||||||
return NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE;
|
abstract_syntax->if_version);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
data_blob_free(&p->out_data.rdata);
|
DBG_ERR("Failed to get DCE/RPC interface\n");
|
||||||
talloc_free_children(p->mem_ctx);
|
return NT_STATUS_NOT_FOUND;
|
||||||
return NT_STATUS_RPC_CALL_FAILED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->fault_state) {
|
status = iface.local(p, opnum, mem_ctx, in_data, out_data);
|
||||||
NTSTATUS status;
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DBG_ERR("DCE/RPC fault in call %s:%02X - %s\n",
|
||||||
status = NT_STATUS(p->fault_state);
|
iface.name, opnum,
|
||||||
p->fault_state = 0;
|
dcerpc_errstr(mem_ctx, p->fault_state));
|
||||||
data_blob_free(&p->out_data.rdata);
|
|
||||||
talloc_free_children(p->mem_ctx);
|
|
||||||
return status;
|
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;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rpcint_bh_state {
|
struct rpcint_bh_state {
|
||||||
struct pipes_struct *p;
|
struct pipes_struct *p;
|
||||||
|
const struct ndr_interface_table *ndr_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool rpcint_bh_is_connected(struct dcerpc_binding_handle *h)
|
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 */
|
/* TODO: allow async */
|
||||||
status = rpcint_dispatch(hs->p, state, opnum,
|
status = rpcint_dispatch(hs->p,
|
||||||
|
hs->ndr_table,
|
||||||
|
state,
|
||||||
|
opnum,
|
||||||
&state->in_data,
|
&state->in_data,
|
||||||
&state->out_data);
|
&state->out_data);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
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;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hs->ndr_table = ndr_table;
|
||||||
|
|
||||||
status = make_internal_rpc_pipe_p(hs,
|
status = make_internal_rpc_pipe_p(hs,
|
||||||
abstract_syntax,
|
abstract_syntax,
|
||||||
remote_address,
|
remote_address,
|
||||||
|
Loading…
Reference in New Issue
Block a user