STEP01x: TODO dcerpc_submit_fault
authorStefan Metzmacher <metze@samba.org>
Wed, 19 Mar 2014 12:59:11 +0000 (13:59 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 10:58:04 +0000 (12:58 +0200)
librpc/rpc/dcerpc_connection.c

index 79197b6f9512b4eb43ee9300b247220bd455bc5c..c53b28d2dcc69fe9a94699d71a6dc2f64f286c89 100644 (file)
@@ -2992,3 +2992,76 @@ NTSTATUS dcerpc_server_connection_loop_recv(struct tevent_req *req)
 {
        return tevent_req_simple_recv_ntstatus(req);
 }
+
+struct dcerpc_submit_fault_frag {
+       DATA_BLOB blob;
+       struct iovec vector;
+};
+
+static NTSTATUS dcerpc_submit_fault(struct dcerpc_connection *conn,
+                                   uint32_t call_id,
+                                   uint32_t context_id,
+                                   NTSTATUS nt_status)
+{
+       struct dcerpc_submit_fault_frag *frag;
+       enum dcerpc_nca_status status = DCERPC_NCA_S_PROTO_ERROR;
+       union dcerpc_payload u;
+       struct tevent_req *subreq;
+
+       if (!dcerpc_connection_is_connected(conn)) {
+               return NT_STATUS_OK;
+       }
+
+       // TODO map from NTSTATUS to dcerpc_nca_status
+       if (
+       /*
+        * 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_fault_frag);
+       if (frag == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       ZERO_STRUCT(u.fault);
+       u.fault.context_id = context_id;
+       u.fault.status = status;
+
+       status = dcerpc_ncacn_packet_blob(frag,
+                                         DCERPC_PKT_FAULT,
+                                         DCERPC_PFC_FLAG_FIRST |
+                                         DCERPC_PFC_FLAG_LAST,
+                                         0,
+                                         call_id,
+                                         &u,
+                                         &frag->blob);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frag);
+               return status;
+       }
+
+       /* 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_fault_done,
+                               frag);
+
+       return NT_STATUS_OK;
+}