TALLOC_FREE(frag);
}
+struct dcerpc_submit_shutdown_frag {
+ struct dcerpc_connection *conn;
+ DATA_BLOB blob;
+ struct iovec vector;
+};
+
+static void dcerpc_submit_shutdown_done(struct tevent_req *subreq);
+
+static NTSTATUS dcerpc_submit_shutdown(struct dcerpc_connection *conn,
+ struct tevent_context *ev)
+{
+ struct dcerpc_submit_shutdown_frag *frag;
+ NTSTATUS error;
+ union dcerpc_payload u;
+ struct tevent_req *subreq;
+
+ if (!dcerpc_connection_is_connected(conn)) {
+ return NT_STATUS_OK;
+ }
+
+ TALLOC_FREE(conn->loop.subreq);
+
+ /*
+ * the fragment belongs to the connection instead of the request
+ * because it has to remain in case the request is canceled
+ */
+ frag = talloc_zero(conn, struct dcerpc_submit_shutdown_frag);
+ if (frag == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ frag->conn = conn;
+
+ ZERO_STRUCT(u.shutdown);
+
+ error = dcerpc_ncacn_packet_blob(frag,
+ DCERPC_PKT_SHUTDOWN,
+ DCERPC_PFC_FLAG_FIRST |
+ DCERPC_PFC_FLAG_LAST,
+ 0, /* auth_length */
+ 0, /* call_id */
+ &u,
+ &frag->blob);
+ if (!NT_STATUS_IS_OK(error)) {
+ TALLOC_FREE(frag);
+ return error;
+ }
+
+ /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
+ * compute it right for requests because the auth trailer is missing
+ * at this stage */
+ //dcerpc_set_frag_length(&frag->blob, frag_len);
+
+ /*
+ * We need to add a dcerpc_write_fragment_queue_send/recv()
+ */
+
+ frag->vector.iov_base = frag->blob.data;
+ frag->vector.iov_len = frag->blob.length;
+ subreq = tstream_writev_queue_send(frag, ev,
+ conn->transport.stream,
+ conn->transport.write_queue,
+ &frag->vector, 1);
+ if (subreq == NULL) {
+ TALLOC_FREE(frag);
+ return NT_STATUS_NO_MEMORY;
+ }
+ tevent_req_set_callback(subreq,
+ dcerpc_submit_shutdown_done,
+ frag);
+
+ conn->loop.subreq = subreq;
+
+ return NT_STATUS_OK;
+}
+
+static void dcerpc_submit_shutdown_done(struct tevent_req *subreq)
+{
+ struct dcerpc_submit_shutdown_frag *frag =
+ tevent_req_callback_data(subreq,
+ struct dcerpc_submit_shutdown_frag);
+ struct dcerpc_connection *conn = frag->conn;
+
+ TALLOC_FREE(subreq);
+
+ TALLOC_FREE(frag);
+
+ dcerpc_connection_dead(conn, NT_STATUS_LOCAL_DISCONNECT);
+}
+
struct dcerpc_server_connection_loop_state {
struct tevent_context *ev;
struct dcerpc_connection *conn;