From: Stefan Metzmacher Date: Mon, 13 Jan 2014 15:42:35 +0000 (+0100) Subject: STEP01: librpc/rpc/dcerpc_connection.c active X-Git-Url: http://git.samba.org/?p=metze%2Fsamba%2Fwip.git;a=commitdiff_plain;h=59200557219a873524f0b781b3a44997daab3650 STEP01: librpc/rpc/dcerpc_connection.c active --- diff --git a/librpc/rpc/dcerpc_connection.c b/librpc/rpc/dcerpc_connection.c index f674d9d3055f..c72ac47c7eba 100644 --- a/librpc/rpc/dcerpc_connection.c +++ b/librpc/rpc/dcerpc_connection.c @@ -1669,6 +1669,7 @@ struct dcerpc_do_request_state { } request; bool verify_bitmask1; bool verify_pcontext; + bool got_first; struct dcerpc_do_request_out_frag *out_frag; struct { DATA_BLOB blob; @@ -1763,6 +1764,9 @@ static void dcerpc_do_request_cleanup(struct tevent_req *req, } if (state->call != NULL) { + if (state->call == state->conn->calls.active) { + state->conn->calls.active = NULL; + } ZERO_STRUCT(state->call->incoming); DLIST_REMOVE(state->conn->calls.list, state->call); state->call = NULL; @@ -2331,12 +2335,55 @@ static NTSTATUS dcerpc_do_request_handle_in_frag(void *private_data, return error; } - if (state->verify_bitmask1) { - state->call->sec->verified_bitmask1 = true; + if (!state->got_first) { + state->got_first = true; + + if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + + state->conn->calls.active = state->call; + + if (pkt->drep[0] & DCERPC_DREP_LE) { + state->response.bigendian = false; + } else { + state->response.bigendian = true; + } + + if (state->verify_bitmask1) { + state->call->sec->verified_bitmask1 = true; + } + + if (state->verify_pcontext) { + state->call->pres->verified_pcontext = true; + } + } else { + if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + } + + if (state->response.bigendian) { + if (pkt->drep[0] != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + } else { + if (pkt->drep[0] != DCERPC_DREP_LE) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + } + if (pkt->drep[1] != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (pkt->drep[2] != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; + } + if (pkt->drep[3] != 0) { + return NT_STATUS_RPC_PROTOCOL_ERROR; } - if (state->verify_pcontext) { - state->call->pres->verified_pcontext = true; + if (pkt->u.response.context_id != state->call->pres->context_id) { + return NT_STATUS_RPC_PROTOCOL_ERROR; } if (frag.length < DCERPC_RESPONSE_LENGTH + pad_len) { @@ -2358,14 +2405,6 @@ static NTSTATUS dcerpc_do_request_handle_in_frag(void *private_data, payload.length = frag.length - DCERPC_RESPONSE_LENGTH; } - if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) { - if (pkt->drep[0] & DCERPC_DREP_LE) { - state->response.bigendian = false; - } else { - state->response.bigendian = true; - } - } - DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n", (long unsigned int)frag.length, (long unsigned int)payload.length,