From 741d6b5d65fcf46ef4385c2027df141730cc6847 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Jun 2016 16:58:03 +0200 Subject: [PATCH 1/4] dcerpc.idl: add DCERPC_NCACN_{REQUEST,RESPONSE}_DEFAULT_MAX_SIZE This will replace DCERPC_NCACN_PAYLOAD_MAX_SIZE (4 MByte), this limit is too strict for some workloads, e.g. DRSUAPI replication with large objects. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11948 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 281e11b53f676647997fb9ce21227782529a62ad) --- librpc/idl/dcerpc.idl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl index 015eb3d..5e0f919 100644 --- a/librpc/idl/dcerpc.idl +++ b/librpc/idl/dcerpc.idl @@ -537,6 +537,23 @@ interface dcerpc const uint8 DCERPC_NCACN_PAYLOAD_OFFSET = 16; const uint32 DCERPC_NCACN_PAYLOAD_MAX_SIZE = 0x400000; /* 4 MByte */ + /* + * See [MS-RPCE] 3.3.3.5.4 Maximum Server Input Data Size + * 4 MByte is the default limit of reassembled request payload + */ + const uint32 DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE = 0x400000; + + /* + * See [MS-RPCE] 3.3.2.5.2 Handling Responses + * + * Indicates that Windows accepts up to 0x7FFFFFFF ~2 GByte + * + * talloc has a limit of 256 MByte, so we need to use something smaller. + * + * For now we try our luck with 240 MByte. + */ + const uint32 DCERPC_NCACN_RESPONSE_DEFAULT_MAX_SIZE = 0xf000000; /* 240 MByte */ + /* little-endian flag */ const uint8 DCERPC_DREP_LE = 0x10; -- 1.9.1 From 7decc5bc7ded4287974651d4eca05ac769f0ca70 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Jun 2016 17:18:28 +0200 Subject: [PATCH 2/4] s4:librpc/rpc: allow a total reassembled response payload of 240 MBytes This will replace DCERPC_NCACN_PAYLOAD_MAX_SIZE (4 MByte), The limit of DCERPC_NCACN_PAYLOAD_MAX_SIZE (4 MByte) was too strict for some workloads, e.g. DRSUAPI replication with large objects. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11948 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett (cherry picked from commit 7413e73c5331b760dc84b3843059230ec5fcfc7b) --- source4/librpc/rpc/dcerpc.c | 5 +++-- source4/librpc/rpc/dcerpc.h | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 464ae95..55b4385 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -155,6 +155,7 @@ static struct dcecli_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx, */ c->srv_max_xmit_frag = 5840; c->srv_max_recv_frag = 5840; + c->max_total_response_size = DCERPC_NCACN_RESPONSE_DEFAULT_MAX_SIZE; c->pending = NULL; c->io_trigger = tevent_create_immediate(c); @@ -1577,10 +1578,10 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c, length = pkt->u.response.stub_and_verifier.length; - if (req->payload.length + length > DCERPC_NCACN_PAYLOAD_MAX_SIZE) { + if (req->payload.length + length > c->max_total_response_size) { DEBUG(2,("Unexpected total payload 0x%X > 0x%X dcerpc response\n", (unsigned)req->payload.length + length, - DCERPC_NCACN_PAYLOAD_MAX_SIZE)); + (unsigned)c->max_total_response_size)); dcerpc_connection_dead(c, NT_STATUS_RPC_PROTOCOL_ERROR); return; } diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 39d28a6..24c7948 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -107,6 +107,9 @@ struct dcecli_connection { /* the next context_id to be assigned */ uint32_t next_context_id; + + /* The maximum total payload of reassembled response pdus */ + size_t max_total_response_size; }; /* -- 1.9.1 From a7d5c8dbed6108b6ce12a04f180b6684cb51833c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Jun 2016 17:18:28 +0200 Subject: [PATCH 3/4] s4:rpc_server: use a variable for the max total reassembled request payload We still use the same limit of 4 MByte (DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE) by default. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11948 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Thu Jun 23 04:51:16 CEST 2016 on sn-devel-144 (cherry picked from commit 3f36d31c848496bf509db573e4c12821905b448d) --- source4/rpc_server/dcerpc_server.c | 5 +++-- source4/rpc_server/dcerpc_server.h | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 8c69351..ea29d9d 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -408,6 +408,7 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->allow_bind = true; p->max_recv_frag = 5840; p->max_xmit_frag = 5840; + p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE; *_p = p; return NT_STATUS_OK; @@ -1532,7 +1533,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, /* * Up to 4 MByte are allowed by all fragments */ - available = DCERPC_NCACN_PAYLOAD_MAX_SIZE; + available = dce_conn->max_total_request_size; if (er->stub_and_verifier.length > available) { dcesrv_call_disconnect_after(existing, "dcesrv_auth_request - existing payload too large"); @@ -1585,7 +1586,7 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, /* * Up to 4 MByte are allowed by all fragments */ - if (call->pkt.u.request.alloc_hint > DCERPC_NCACN_PAYLOAD_MAX_SIZE) { + if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) { dcesrv_call_disconnect_after(call, "dcesrv_auth_request - initial alloc hint too large"); return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 7e8b18a..b6fac6c 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -273,6 +273,9 @@ struct dcesrv_connection { /* the association group the connection belongs to */ struct dcesrv_assoc_group *assoc_group; + + /* The maximum total payload of reassembled request pdus */ + size_t max_total_request_size; }; -- 1.9.1 From 2a55eef7add106fa0cdf20096495eed5b21281af Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Jun 2016 20:38:01 +0200 Subject: [PATCH 4/4] dcerpc.idl: remove unused DCERPC_NCACN_PAYLOAD_MAX_SIZE BUG: https://bugzilla.samba.org/show_bug.cgi?id=11948 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme (cherry picked from commit d9e242e9035c15e49b041afc61e5a4a08877f289) --- librpc/idl/dcerpc.idl | 1 - 1 file changed, 1 deletion(-) diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl index 5e0f919..527804d 100644 --- a/librpc/idl/dcerpc.idl +++ b/librpc/idl/dcerpc.idl @@ -535,7 +535,6 @@ interface dcerpc const uint32 DCERPC_FRAG_MAX_SIZE = 5840; const uint8 DCERPC_AUTH_LEN_OFFSET = 10; const uint8 DCERPC_NCACN_PAYLOAD_OFFSET = 16; - const uint32 DCERPC_NCACN_PAYLOAD_MAX_SIZE = 0x400000; /* 4 MByte */ /* * See [MS-RPCE] 3.3.3.5.4 Maximum Server Input Data Size -- 1.9.1