tevent_req_data(req,
struct dcerpc_do_bind_state);
NTSTATUS status;
+ struct dcerpc_presentation *last_pres = NULL;
+ size_t num_pres_ok = 0;
size_t i;
/* Ensure we have the correct type. */
struct dcerpc_ack_ctx *ack = &pkt->u.bind_ack.ctx_list[i];
if (i < state->num_pres) {
- state->pres[i]->negotiate.ack = *ack;
+ struct dcerpc_ack_ctx *pack =
+ &state->pres[i]->negotiate.ack;
+
+ if (ack->result == DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) {
+ return NT_STATUS_RPC_PROTOCOL_ERROR;
+ }
+
+ if (ack->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
+ *pack = *ack;
+ num_pres_ok += 1;
+ continue;
+ }
+
+ if (pack->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
+ /*
+ * if a presentation context was valid it must
+ * be valid for the lifetime of the connection
+ */
+ return NT_STATUS_RPC_PROTOCOL_ERROR;
+ }
+
+ *pack = *ack;
+ last_pres = state->pres[i];
continue;
}
}
}
+ if (num_pres_ok == 0 && last_pres != NULL) {
+ status = dcerpc_presentation_status(last_pres);
+ tevent_req_nterror(req, status);
+ return NT_STATUS_OK;
+ }
+
if (pkt->auth_length >= 8) {
struct tevent_req *subreq;