Revert "s4:librpc/rpc: remove dcerpc_shutdown_pipe() layer"
authorStefan Metzmacher <metze@samba.org>
Tue, 18 Mar 2014 05:50:50 +0000 (06:50 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 10:43:20 +0000 (12:43 +0200)
This reverts commit f9dfae142d580c288951c41eccbe481c326c7ca1.

source4/librpc/rpc/dcerpc.c

index 109b3fab8a03f7c1d7b0a2ede1e9305321ce47e3..a0b00aff817d4b3215410f5e473158124d10e52b 100644 (file)
@@ -103,6 +103,7 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcecli_connection *c,
                                        ndr_push_flags_fn_t ndr_push,
                                        ndr_pull_flags_fn_t ndr_pull,
                                        ndr_print_function_t ndr_print);
+static NTSTATUS dcerpc_shutdown_pipe(struct dcecli_connection *p, NTSTATUS status);
 static NTSTATUS dcerpc_send_request(struct dcecli_connection *p, DATA_BLOB *data,
                             bool trigger_read);
 static NTSTATUS dcerpc_send_read(struct dcecli_connection *p);
@@ -855,7 +856,6 @@ static int dcerpc_req_dequeue(struct rpc_request *req)
        return 0;
 }
 
-static void dcerpc_transport_dead(struct dcecli_connection *c, NTSTATUS status);
 
 /*
   mark the dcerpc connection dead. All outstanding requests get an error
@@ -869,7 +869,7 @@ static void dcerpc_connection_dead(struct dcecli_connection *conn, NTSTATUS stat
        TALLOC_FREE(conn->io_trigger);
        conn->io_trigger_pending = false;
 
-       dcerpc_transport_dead(conn, status);
+       dcerpc_shutdown_pipe(conn, status);
 
        /* all pending requests get the error */
        while (conn->pending) {
@@ -2337,6 +2337,63 @@ static void dcerpc_transport_dead(struct dcecli_connection *c, NTSTATUS status)
        dcerpc_recv_data(c, NULL, status);
 }
 
+
+/*
+   shutdown SMB pipe connection
+*/
+struct dcerpc_shutdown_pipe_state {
+       struct dcecli_connection *c;
+       NTSTATUS status;
+};
+
+static void dcerpc_shutdown_pipe_done(struct tevent_req *subreq);
+
+static NTSTATUS dcerpc_shutdown_pipe(struct dcecli_connection *c, NTSTATUS status)
+{
+       struct dcerpc_shutdown_pipe_state *state;
+       struct tevent_req *subreq;
+
+       if (c->transport.stream == NULL) {
+               return NT_STATUS_OK;
+       }
+
+       state = talloc_zero(c, struct dcerpc_shutdown_pipe_state);
+       if (state == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       state->c = c;
+       state->status = status;
+
+       subreq = tstream_disconnect_send(state, c->event_ctx, c->transport.stream);
+       if (subreq == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       tevent_req_set_callback(subreq, dcerpc_shutdown_pipe_done, state);
+
+       return status;
+}
+
+static void dcerpc_shutdown_pipe_done(struct tevent_req *subreq)
+{
+       struct dcerpc_shutdown_pipe_state *state =
+               tevent_req_callback_data(subreq, struct dcerpc_shutdown_pipe_state);
+       struct dcecli_connection *c = state->c;
+       NTSTATUS status = state->status;
+       int error;
+
+       /*
+        * here we ignore the return values...
+        */
+       tstream_disconnect_recv(subreq, &error);
+       TALLOC_FREE(subreq);
+
+       TALLOC_FREE(state);
+
+       dcerpc_transport_dead(c, status);
+}
+
+
+
 struct dcerpc_send_read_state {
        struct dcecli_connection *p;
 };