1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-03 12:58:35 +03:00

added handling of fragmented requests in the rpc server

now we just need to handle fragmented replies ....
(This used to be commit 14005c95d7c6c68f7da0f1ad7b7d7952a04a125b)
This commit is contained in:
Andrew Tridgell 2003-12-12 05:01:41 +00:00
parent 869df3adbd
commit dab0deae83
2 changed files with 67 additions and 8 deletions

View File

@ -37,6 +37,19 @@ static const struct dcesrv_endpoint_ops *find_endpoint(struct server_context *sm
return NULL;
}
/*
find a call that is pending in our call list
*/
static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_state *dce, uint16 call_id)
{
struct dcesrv_call_state *c;
for (c=dce->call_list;c;c=c->next) {
if (c->pkt.call_id == call_id) {
return c;
}
}
return NULL;
}
/*
register an endpoint server
@ -248,11 +261,6 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
DATA_BLOB stub;
struct dcerpc_packet pkt;
if (call->pkt.pfc_flags != (DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST)) {
/* we don't do fragments in the server yet */
return dcesrv_fault(call, DCERPC_FAULT_TODO);
}
opnum = call->pkt.u.request.opnum;
if (opnum >= call->dce->ndr->num_calls) {
@ -349,6 +357,7 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data)
}
call->mem_ctx = mem_ctx;
call->dce = dce;
call->data = data_blob(NULL, 0);
ndr = ndr_pull_init_blob(data, mem_ctx);
if (!ndr) {
@ -362,10 +371,56 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data)
return status;
}
/* TODO: at this point we should see if the packet is a
continuation of an existing call, but I'm too lazy for that
right now ... maybe tomorrow */
/* see if this is a continued packet */
if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) {
struct dcesrv_call_state *call2 = call;
uint32 alloc_size;
/* we only allow fragmented requests, no other packet types */
if (call->pkt.ptype != DCERPC_PKT_REQUEST) {
return dcesrv_fault(call2, DCERPC_FAULT_TODO);
}
/* this is a continuation of an existing call - find the call then
tack it on the end */
call = dcesrv_find_call(dce, call2->pkt.call_id);
if (!call) {
return dcesrv_fault(call2, DCERPC_FAULT_TODO);
}
if (call->pkt.ptype != call2->pkt.ptype) {
/* trying to play silly buggers are we? */
return dcesrv_fault(call2, DCERPC_FAULT_TODO);
}
alloc_size = call->pkt.u.request.stub_and_verifier.length +
call2->pkt.u.request.stub_and_verifier.length;
if (call->pkt.u.request.alloc_hint > alloc_size) {
alloc_size = call->pkt.u.request.alloc_hint;
}
call->pkt.u.request.stub_and_verifier.data =
talloc_realloc(call->mem_ctx,
call->pkt.u.request.stub_and_verifier.data, alloc_size);
if (!call->pkt.u.request.stub_and_verifier.data) {
return dcesrv_fault(call2, DCERPC_FAULT_TODO);
}
memcpy(call->pkt.u.request.stub_and_verifier.data +
call->pkt.u.request.stub_and_verifier.length,
call2->pkt.u.request.stub_and_verifier.data,
call2->pkt.u.request.stub_and_verifier.length);
call->pkt.u.request.stub_and_verifier.length +=
call2->pkt.u.request.stub_and_verifier.length;
call->pkt.pfc_flags |= (call2->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
}
/* this may not be the last pdu in the chain - if its isn't then
just put it on the call_list and wait for the rest */
if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
DLIST_ADD_END(dce->call_list, call, struct dcesrv_call_state *);
return NT_STATUS_OK;
}
switch (call->pkt.ptype) {
case DCERPC_PKT_BIND:

View File

@ -31,6 +31,10 @@ static NTSTATUS echo_AddOne(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx, struc
static NTSTATUS echo_EchoData(struct dcesrv_state *dce, TALLOC_CTX *mem_ctx, struct echo_EchoData *r)
{
r->out.out_data = talloc(mem_ctx, r->in.len);
if (!r->out.out_data) {
return NT_STATUS_NO_MEMORY;
}
memcpy(r->out.out_data, r->in.in_data, r->in.len);
return NT_STATUS_OK;