From d21f344af52c4f2579278fefc3c15866f4d1a818 Mon Sep 17 00:00:00 2001 From: Julien Kerihuel Date: Mon, 6 Apr 2015 11:26:58 +0200 Subject: [PATCH 2/2] s4:rpc_server: Add DCERPC flag to call unbind hooks without destroying the connection itself upon termination of a connection with outstanding pending calls. Reviewed-by: Stefan Metzmacher Reviewed-by: Jelmer Vernooij Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Tue Apr 14 20:39:34 CEST 2015 on sn-devel-104 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11226 (cherry picked from commit fd90d270c7e97a639f42a96b674a674d1b51aa0d) --- source4/rpc_server/dcerpc_server.c | 21 +++++++++++++++++++++ source4/rpc_server/dcerpc_server.h | 1 + 2 files changed, 22 insertions(+) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 39de1b2..8c0a101 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -500,6 +500,7 @@ static int dcesrv_connection_context_destructor(struct dcesrv_connection_context if (c->iface && c->iface->unbind) { c->iface->unbind(c, c->iface); + c->iface = NULL; } return 0; @@ -622,6 +623,10 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) extra_flags |= DCERPC_PFC_FLAG_CONC_MPX; } + if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) { + call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL; + } + /* handle any authentication that is being requested */ if (!dcesrv_auth_bind(call)) { talloc_free(call->context); @@ -841,6 +846,10 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) } } + if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) { + call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL; + } + /* setup a alter_resp */ dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); pkt.auth_length = 0; @@ -1320,6 +1329,18 @@ static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx) cur = next; next = cur->next; + if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) { + struct dcesrv_connection_context *context_cur, *context_next; + + context_next = cur->contexts; + while (context_next != NULL) { + context_cur = context_next; + context_next = context_cur->next; + + dcesrv_connection_context_destructor(context_cur); + } + } + dcesrv_terminate_connection(cur, cur->terminate); } } diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index e2c9898..bf8799a 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -103,6 +103,7 @@ struct dcesrv_call_state { #define DCESRV_CALL_STATE_FLAG_MAY_ASYNC (1<<1) #define DCESRV_CALL_STATE_FLAG_HEADER_SIGNING (1<<2) #define DCESRV_CALL_STATE_FLAG_MULTIPLEXED (1<<3) +#define DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL (1<<4) uint32_t state_flags; /* the time the request arrived in the server */ -- 1.9.1