STEP01x: start with dcerpc_server_connection_loop_send/recv
authorStefan Metzmacher <metze@samba.org>
Wed, 22 Jan 2014 13:54:40 +0000 (14:54 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 10:45:39 +0000 (12:45 +0200)
librpc/rpc/dcerpc_connection.c
librpc/rpc/dcerpc_connection.h

index 7b40e0bdca44c7041b6f572ab7fe8e026d6f6f68..161841625f126c2a8de96a4abc0a9d734a9450c9 100644 (file)
@@ -35,6 +35,7 @@ struct dcerpc_connection;
 struct dcerpc_security;
 struct dcerpc_presentation;
 struct dcerpc_call;
+struct dcerpc_server;
 
 struct dcerpc_association {
        uint32_t assoc_group_id;
@@ -112,6 +113,9 @@ struct dcerpc_call {
        } incoming;
 };
 
+struct dcerpc_server {
+};
+
 struct dcerpc_association *dcerpc_association_create(TALLOC_CTX *mem_ctx,
                                                     uint16_t client_features)
 {
@@ -2739,3 +2743,122 @@ NTSTATUS dcerpc_do_request_recv(struct tevent_req *req,
        tevent_req_received(req);
        return NT_STATUS_OK;
 }
+
+struct dcerpc_server_connection_loop_state {
+       struct tevent_context *ev;
+       struct dcerpc_connection *conn;
+
+       struct dcerpc_server *server;
+
+       struct dcerpc_server_association *assoc;
+
+       uint32_t last_call_id;
+
+       size_t num_secs;
+       struct db_context *secs;
+
+       size_t num_pres;
+       struct db_context *pres;
+};
+
+static void dcerpc_server_connection_loop_cleanup(struct tevent_req *req,
+                                     enum tevent_req_state req_state);
+
+static NTSTATUS dcerpc_server_connection_loop_handle_in_frag(struct tevent_req *req,
+                                                            struct ncacn_packet *pkt,
+                                                            DATA_BLOB frag);
+
+struct tevent_req *dcerpc_server_connection_loop_send(TALLOC_CTX *mem_ctx,
+                               struct tevent_context *ev,
+                               struct dcerpc_connection *conn,
+                               struct dcerpc_server *server)
+{
+       struct tevent_req *req;
+       struct dcerpc_server_connection_loop_state *state;
+       struct dcerpc_call *call;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct dcerpc_server_connection_loop_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       state->ev = ev;
+       state->conn = conn;
+
+       if (state->conn->calls.new_call != NULL) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
+               return tevent_req_post(req, ev);
+       }
+
+       call = talloc_zero(state, struct dcerpc_call);
+       if (call == NULL) {
+               return NULL;
+       }
+
+       call->incoming.req = req;
+       call->incoming.handler = dcerpc_server_connection_loop_handle_in_frag;
+       conn->calls.new_call = call;
+       tevent_req_defer_callback(req, ev);
+       tevent_req_set_cleanup_fn(req, dcerpc_server_connection_loop_cleanup);
+
+       //TODO different dcerpc_connection_dead() behavior as server?
+
+       return req;
+}
+
+static void dcerpc_server_connection_loop_cleanup(struct tevent_req *req,
+                                                 enum tevent_req_state req_state)
+{
+       struct dcerpc_server_connection_loop_state *state =
+               tevent_req_data(req,
+               struct dcerpc_server_connection_loop_state);
+
+       if (state->conn != NULL) {
+               TALLOC_FREE(state->conn->calls.new_call);
+               state->conn = NULL;
+       }
+}
+
+static NTSTATUS dcerpc_server_connection_loop_handle_in_frag(struct tevent_req *req,
+                                                            struct ncacn_packet *pkt,
+                                                            DATA_BLOB frag)
+{
+       struct dcerpc_server_connection_loop_state *state =
+               tevent_req_data(req,
+               struct dcerpc_server_connection_loop_state);
+
+       /* Ensure we have the correct type. */
+       switch (pkt->ptype) {
+       case DCERPC_PKT_BIND:
+               if (state->conn->features.bind_done) {
+                       return NT_STATUS_RPC_PROTOCOL_ERROR;
+               }
+               state->conn->features.bind_done = true;
+               break;
+
+       case DCERPC_PKT_ALTER:
+               if (!state->conn->features.bind_done) {
+                       return NT_STATUS_RPC_PROTOCOL_ERROR;
+               }
+               break;
+
+       case DCERPC_PKT_REQUEST:
+               if (!state->conn->features.bind_done) {
+                       return NT_STATUS_RPC_PROTOCOL_ERROR;
+               }
+               break;
+
+       default:
+               DEBUG(0, ("Unknown packet type %u received from %s!\n",
+                         (unsigned int)pkt->ptype,
+                        "TODO"));
+               return NT_STATUS_RPC_PROTOCOL_ERROR;
+       }
+
+       return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS dcerpc_server_connection_loop_recv(struct tevent_req *req)
+{
+       return tevent_req_simple_recv_ntstatus(req);
+}
index 477fa399a92e9ed35beb49af62699e84ba12e1b9..266158addc282ad0b058f4bc51c275188f2880eb 100644 (file)
@@ -31,6 +31,7 @@ struct dcerpc_connection;
 struct dcerpc_security;
 struct dcerpc_presentation;
 struct dcerpc_call;
+struct dcerpc_server;
 
 struct dcerpc_association *dcerpc_association_create(TALLOC_CTX *mem_ctx,
                                                     uint16_t client_features);
@@ -91,4 +92,10 @@ NTSTATUS dcerpc_do_request_recv(struct tevent_req *req,
                                DATA_BLOB *response,
                                bool *bigendian);
 
+struct tevent_req *dcerpc_server_connection_loop_send(TALLOC_CTX *mem_ctx,
+                               struct tevent_context *ev,
+                               struct dcerpc_connection *conn,
+                               struct dcerpc_server *server);
+NTSTATUS dcerpc_server_connection_loop_recv(struct tevent_req *req);
+
 #endif /* _LIBRPC_RPC_DCERPC_CONNECTION_H_ */