mirror of
https://github.com/samba-team/samba.git
synced 2025-08-07 09:49:30 +03:00
s3-dcerpc: Use DATA_BLOB for pipes_struct input data
Signed-off-by: Günther Deschner <gd@samba.org>
This commit is contained in:
committed by
Günther Deschner
parent
8f2bfa88b5
commit
100d37fc46
@ -145,7 +145,6 @@ sub ParseFunction($$)
|
||||
pidl "struct ndr_pull *pull;";
|
||||
pidl "struct ndr_push *push;";
|
||||
pidl "enum ndr_err_code ndr_err;";
|
||||
pidl "DATA_BLOB blob;";
|
||||
pidl "struct $fn->{NAME} *r;";
|
||||
pidl "";
|
||||
pidl "call = &ndr_table_$if->{NAME}.calls[$op];";
|
||||
@ -155,12 +154,7 @@ sub ParseFunction($$)
|
||||
pidl "\treturn false;";
|
||||
pidl "}";
|
||||
pidl "";
|
||||
pidl "if (!prs_data_blob(&p->in_data.data, &blob, r)) {";
|
||||
pidl "\ttalloc_free(r);";
|
||||
pidl "\treturn false;";
|
||||
pidl "}";
|
||||
pidl "";
|
||||
pidl "pull = ndr_pull_init_blob(&blob, r);";
|
||||
pidl "pull = ndr_pull_init_blob(&p->in_data.data, r);";
|
||||
pidl "if (pull == NULL) {";
|
||||
pidl "\ttalloc_free(r);";
|
||||
pidl "\treturn false;";
|
||||
|
@ -105,7 +105,8 @@ typedef struct _input_data {
|
||||
* the rpc headers and auth footers removed.
|
||||
* The maximum length of this (1Mb) is strictly enforced.
|
||||
*/
|
||||
prs_struct data;
|
||||
DATA_BLOB data;
|
||||
|
||||
} input_data;
|
||||
|
||||
struct handle_list;
|
||||
|
@ -1 +0,0 @@
|
||||
This contains the generated files from PIDL for the IDL files in ../idl/*.idl
|
@ -144,20 +144,6 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the incoming RPC data buffer with one PDU worth of memory.
|
||||
* We cheat here and say we're marshalling, as we intend to add incoming
|
||||
* data directly into the prs_struct and we want it to auto grow. We will
|
||||
* change the type to UNMARSALLING before processing the stream.
|
||||
*/
|
||||
|
||||
if(!prs_init(&p->in_data.data, 128, p->mem_ctx, MARSHALL)) {
|
||||
DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
|
||||
close_policy_by_pipe(p);
|
||||
TALLOC_FREE(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p->server_info = copy_serverinfo(p, server_info);
|
||||
if (p->server_info == NULL) {
|
||||
DEBUG(0, ("open_rpc_pipe_p: copy_serverinfo failed\n"));
|
||||
@ -194,8 +180,6 @@ static NTSTATUS internal_ndr_push(TALLOC_CTX *mem_ctx,
|
||||
const struct ndr_interface_call *call;
|
||||
struct ndr_push *push;
|
||||
enum ndr_err_code ndr_err;
|
||||
DATA_BLOB blob;
|
||||
bool ret;
|
||||
|
||||
if (!ndr_syntax_id_equal(&table->syntax_id, &cli->abstract_syntax) ||
|
||||
(opnum >= table->num_calls)) {
|
||||
@ -220,12 +204,10 @@ static NTSTATUS internal_ndr_push(TALLOC_CTX *mem_ctx,
|
||||
return ndr_map_error2ntstatus(ndr_err);
|
||||
}
|
||||
|
||||
blob = ndr_push_blob(push);
|
||||
ret = prs_init_data_blob(&cli->pipes_struct->in_data.data, &blob, mem_ctx);
|
||||
cli->pipes_struct->in_data.data = ndr_push_blob(push);
|
||||
talloc_steal(cli->pipes_struct->mem_ctx,
|
||||
cli->pipes_struct->in_data.data.data);
|
||||
TALLOC_FREE(push);
|
||||
if (!ret) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@ -317,7 +299,7 @@ static NTSTATUS rpc_pipe_internal_dispatch(struct rpc_pipe_client *cli,
|
||||
return status;
|
||||
}
|
||||
|
||||
prs_mem_free(&cli->pipes_struct->in_data.data);
|
||||
data_blob_free(&cli->pipes_struct->in_data.data);
|
||||
data_blob_free(&cli->pipes_struct->out_data.rdata);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
|
@ -1719,7 +1719,9 @@ static bool api_rpcTNP(pipes_struct *p, struct ncacn_packet *pkt,
|
||||
fstring name;
|
||||
slprintf(name, sizeof(name)-1, "in_%s",
|
||||
get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
|
||||
prs_dump(name, pkt->u.request.opnum, &p->in_data.data);
|
||||
prs_dump_region(name, pkt->u.request.opnum,
|
||||
p->in_data.data.data, 0,
|
||||
p->in_data.data.length);
|
||||
}
|
||||
|
||||
for (fn_num = 0; fn_num < n_cmds; fn_num++) {
|
||||
@ -1783,18 +1785,11 @@ static bool api_rpcTNP(pipes_struct *p, struct ncacn_packet *pkt,
|
||||
get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
|
||||
|
||||
/* Check for buffer underflow in rpc parsing */
|
||||
|
||||
if ((DEBUGLEVEL >= 10) &&
|
||||
(prs_offset(&p->in_data.data) != prs_data_size(&p->in_data.data))) {
|
||||
size_t data_len = prs_data_size(&p->in_data.data) - prs_offset(&p->in_data.data);
|
||||
char *data = (char *)SMB_MALLOC(data_len);
|
||||
|
||||
if ((DEBUGLEVEL >= 10) &&
|
||||
(pkt->frag_length < p->in_data.data.length)) {
|
||||
DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
|
||||
if (data) {
|
||||
prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data, (uint32)data_len);
|
||||
SAFE_FREE(data);
|
||||
}
|
||||
|
||||
dump_data(10, p->in_data.data.data + pkt->frag_length,
|
||||
p->in_data.data.length - pkt->frag_length);
|
||||
}
|
||||
|
||||
return True;
|
||||
|
@ -56,7 +56,7 @@ static bool pipe_init_outgoing_data(pipes_struct *p)
|
||||
|
||||
static void set_incoming_fault(pipes_struct *p)
|
||||
{
|
||||
prs_mem_free(&p->in_data.data);
|
||||
data_blob_free(&p->in_data.data);
|
||||
p->in_data.pdu_needed_len = 0;
|
||||
p->in_data.pdu.length = 0;
|
||||
p->fault_state = True;
|
||||
@ -145,21 +145,12 @@ static void free_pipe_context(pipes_struct *p)
|
||||
{
|
||||
data_blob_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.rdata);
|
||||
prs_mem_free(&p->in_data.data);
|
||||
data_blob_free(&p->in_data.data);
|
||||
|
||||
DEBUG(3, ("free_pipe_context: "
|
||||
"destroying talloc pool of size %lu\n",
|
||||
(unsigned long)talloc_total_size(p->mem_ctx)));
|
||||
talloc_free_children(p->mem_ctx);
|
||||
/*
|
||||
* Re-initialize to set back to marshalling and set the
|
||||
* offset back to the start of the buffer.
|
||||
*/
|
||||
if(!prs_init(&p->in_data.data, 128, p->mem_ctx, MARSHALL)) {
|
||||
DEBUG(0, ("free_pipe_context: "
|
||||
"rps_init failed!\n"));
|
||||
p->fault_state = True;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -348,10 +339,10 @@ static bool process_request_pdu(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
* will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
|
||||
*/
|
||||
|
||||
if (prs_offset(&p->in_data.data) + data.length > MAX_RPC_DATA_SIZE) {
|
||||
if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
|
||||
DEBUG(0, ("process_request_pdu: "
|
||||
"rpc data buffer too large (%u) + (%u)\n",
|
||||
(unsigned int)prs_data_size(&p->in_data.data),
|
||||
(unsigned int)p->in_data.data.length,
|
||||
(unsigned int)data.length));
|
||||
set_incoming_fault(p);
|
||||
return False;
|
||||
@ -361,14 +352,16 @@ static bool process_request_pdu(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
* Append the data portion into the buffer and return.
|
||||
*/
|
||||
|
||||
if (!prs_copy_data_in(&p->in_data.data,
|
||||
(char *)data.data, data.length)) {
|
||||
DEBUG(0, ("process_request_pdu: Unable to append data size %u "
|
||||
"to parse buffer of size %u.\n",
|
||||
(unsigned int)data.length,
|
||||
(unsigned int)prs_data_size(&p->in_data.data)));
|
||||
set_incoming_fault(p);
|
||||
return False;
|
||||
if (data.length) {
|
||||
if (!data_blob_append(p->mem_ctx, &p->in_data.data,
|
||||
data.data, data.length)) {
|
||||
DEBUG(0, ("Unable to append data size %u "
|
||||
"to parse buffer of size %u.\n",
|
||||
(unsigned int)data.length,
|
||||
(unsigned int)p->in_data.data.length));
|
||||
set_incoming_fault(p);
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
|
||||
@ -378,31 +371,9 @@ static bool process_request_pdu(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
* Call the rpc command to process it.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ensure the internal prs buffer size is *exactly* the same
|
||||
* size as the current offset.
|
||||
*/
|
||||
|
||||
if (!prs_set_buffer_size(&p->in_data.data,
|
||||
prs_offset(&p->in_data.data))) {
|
||||
DEBUG(0, ("process_request_pdu: "
|
||||
"Call to prs_set_buffer_size failed!\n"));
|
||||
set_incoming_fault(p);
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the parse offset to the start of the data and set the
|
||||
* prs_struct to UNMARSHALL.
|
||||
*/
|
||||
|
||||
prs_set_offset(&p->in_data.data, 0);
|
||||
prs_switch_type(&p->in_data.data, UNMARSHALL);
|
||||
|
||||
/*
|
||||
* Process the complete data stream here.
|
||||
*/
|
||||
|
||||
if (pipe_init_outgoing_data(p)) {
|
||||
ret = api_pipe_request(p, pkt);
|
||||
}
|
||||
@ -454,7 +425,6 @@ static void process_complete_pdu(pipes_struct *p)
|
||||
} else {
|
||||
p->endian = RPC_BIG_ENDIAN;
|
||||
}
|
||||
prs_set_endian_data(&p->in_data.data, p->endian);
|
||||
|
||||
DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
|
||||
|
||||
@ -591,10 +561,6 @@ static void process_complete_pdu(pipes_struct *p)
|
||||
}
|
||||
|
||||
done:
|
||||
/* Reset to little endian.
|
||||
* Probably don't need this but it won't hurt. */
|
||||
prs_set_endian_data(&p->in_data.data, RPC_LITTLE_ENDIAN);
|
||||
|
||||
if (!reply) {
|
||||
DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
|
||||
"pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
|
||||
|
@ -264,8 +264,8 @@ enum winbindd_result winbindd_dual_ndrcmd(struct winbindd_domain *domain,
|
||||
|
||||
ZERO_STRUCT(p);
|
||||
p.mem_ctx = talloc_stackframe();
|
||||
p.in_data.data.buffer_size = state->request->extra_len;
|
||||
p.in_data.data.data_p = state->request->extra_data.data;
|
||||
p.in_data.data = data_blob_const(state->request->extra_data.data,
|
||||
state->request->extra_len);
|
||||
|
||||
ret = fns[state->request->data.ndrcmd].fn(&p);
|
||||
if (!ret) {
|
||||
|
Reference in New Issue
Block a user