struct dcerpc_security;
struct dcerpc_presentation;
struct dcerpc_call;
+struct dcerpc_server;
struct dcerpc_association {
uint32_t assoc_group_id;
} incoming;
};
+struct dcerpc_server {
+};
+
struct dcerpc_association *dcerpc_association_create(TALLOC_CTX *mem_ctx,
uint16_t client_features)
{
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);
+}