summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2012-03-07 16:54:18 +0100
committerStefan Metzmacher <metze@samba.org>2012-03-07 18:44:24 +0100
commit7b1fb088421565f1752acde02377237e4ca19248 (patch)
treecbba0899de6e78c4df31be7196fb78f4353b7058 /source4
parent01c404a67c3321c8959b47841db5c1900b4ebac4 (diff)
downloadsamba-7b1fb088421565f1752acde02377237e4ca19248.tar.gz
samba-7b1fb088421565f1752acde02377237e4ca19248.tar.bz2
samba-7b1fb088421565f1752acde02377237e4ca19248.zip
s4:librpc/rpc: make dcerpc_bh_raw_call_* more robust against disconnects and timeouts
Using tevent_req_defer_callback() should make the situation a bit better, until we have a common robust low level dcerpc library. metze Autobuild-User: Stefan Metzmacher <metze@samba.org> Autobuild-Date: Wed Mar 7 18:44:24 CET 2012 on sn-devel-104
Diffstat (limited to 'source4')
-rw-r--r--source4/librpc/rpc/dcerpc.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index 8317778bc8..599ad786c6 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -194,6 +194,7 @@ static uint32_t dcerpc_bh_set_timeout(struct dcerpc_binding_handle *h,
}
struct dcerpc_bh_raw_call_state {
+ struct tevent_context *ev;
struct dcerpc_binding_handle *h;
DATA_BLOB in_data;
DATA_BLOB out_data;
@@ -223,6 +224,7 @@ static struct tevent_req *dcerpc_bh_raw_call_send(TALLOC_CTX *mem_ctx,
if (req == NULL) {
return NULL;
}
+ state->ev = ev;
state->h = h;
state->in_data.data = discard_const_p(uint8_t, in_data);
state->in_data.length = in_length;
@@ -268,6 +270,19 @@ static void dcerpc_bh_raw_call_done(struct rpc_request *subreq)
if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
status = dcerpc_fault_to_nt_status(fault_code);
}
+
+ /*
+ * We trigger the callback in the next event run
+ * because the code in this file might trigger
+ * multiple request callbacks from within a single
+ * while loop.
+ *
+ * In order to avoid segfaults from within
+ * dcerpc_connection_dead() we call
+ * tevent_req_defer_callback().
+ */
+ tevent_req_defer_callback(req, state->ev);
+
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return;