diff options
author | Stefan Metzmacher <metze@samba.org> | 2015-10-06 12:25:53 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2016-10-26 11:20:13 +0200 |
commit | 6917a1c28fd3e7f3522e81b7370e04913d7b755d (patch) | |
tree | 67e1f39c7c1230c621dff0e66d68fddc3f555006 /source4/librpc/rpc/dcerpc.c | |
parent | 3d51359c86c05ec74220afb122d806fa5045c65f (diff) | |
download | samba-6917a1c28fd3e7f3522e81b7370e04913d7b755d.tar.gz |
s4:librpc/rpc: implement bind_time_feature negotiation
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'source4/librpc/rpc/dcerpc.c')
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index edb4e7e852c..362de03469b 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1180,6 +1180,11 @@ struct tevent_req *dcerpc_bind_send(TALLOC_CTX *mem_ctx, NTSTATUS status; struct rpc_request *subreq; uint32_t flags; + struct ndr_syntax_id bind_time_features; + + bind_time_features = dcerpc_construct_bind_time_features( + DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING | + DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN); req = tevent_req_create(mem_ctx, &state, struct dcerpc_bind_state); @@ -1213,8 +1218,9 @@ struct tevent_req *dcerpc_bind_send(TALLOC_CTX *mem_ctx, pkt.u.bind.max_xmit_frag = p->conn->srv_max_xmit_frag; pkt.u.bind.max_recv_frag = p->conn->srv_max_recv_frag; pkt.u.bind.assoc_group_id = dcerpc_binding_get_assoc_group_id(p->binding); - pkt.u.bind.num_contexts = 1; - pkt.u.bind.ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1); + pkt.u.bind.num_contexts = 2; + pkt.u.bind.ctx_list = talloc_zero_array(state, struct dcerpc_ctx_list, + pkt.u.bind.num_contexts); if (tevent_req_nomem(pkt.u.bind.ctx_list, req)) { return tevent_req_post(req, ev); } @@ -1222,6 +1228,10 @@ struct tevent_req *dcerpc_bind_send(TALLOC_CTX *mem_ctx, pkt.u.bind.ctx_list[0].num_transfer_syntaxes = 1; pkt.u.bind.ctx_list[0].abstract_syntax = p->syntax; pkt.u.bind.ctx_list[0].transfer_syntaxes = &p->transfer_syntax; + pkt.u.bind.ctx_list[1].context_id = p->context_id + 1; + pkt.u.bind.ctx_list[1].num_transfer_syntaxes = 1; + pkt.u.bind.ctx_list[1].abstract_syntax = p->syntax; + pkt.u.bind.ctx_list[1].transfer_syntaxes = &bind_time_features; pkt.u.bind.auth_info = data_blob(NULL, 0); /* construct the NDR form of the packet */ @@ -1346,7 +1356,7 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, return; } - if (pkt->u.bind_ack.num_results != 1) { + if (pkt->u.bind_ack.num_results < 1) { state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR; tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT); return; @@ -1361,6 +1371,18 @@ static void dcerpc_bind_recv_handler(struct rpc_request *subreq, return; } + if (pkt->u.bind_ack.num_results >= 2) { + if (pkt->u.bind_ack.ctx_list[1].result == DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) { + conn->bind_time_features = pkt->u.bind_ack.ctx_list[1].reason.negotiate; + } else { + status = dcerpc_map_ack_reason(&pkt->u.bind_ack.ctx_list[1]); + DEBUG(10,("dcerpc: bind_time_feature failed - reason %d - %s\n", + pkt->u.bind_ack.ctx_list[1].reason.value, + nt_errstr(status))); + status = NT_STATUS_OK; + } + } + /* * DCE-RPC 1.1 (c706) specifies * CONST_MUST_RCV_FRAG_SIZE as 1432 @@ -2258,7 +2280,8 @@ struct tevent_req *dcerpc_alter_context_send(TALLOC_CTX *mem_ctx, pkt.u.alter.max_recv_frag = p->conn->srv_max_recv_frag; pkt.u.alter.assoc_group_id = dcerpc_binding_get_assoc_group_id(p->binding); pkt.u.alter.num_contexts = 1; - pkt.u.alter.ctx_list = talloc_array(state, struct dcerpc_ctx_list, 1); + pkt.u.alter.ctx_list = talloc_zero_array(state, struct dcerpc_ctx_list, + pkt.u.alter.num_contexts); if (tevent_req_nomem(pkt.u.alter.ctx_list, req)) { return tevent_req_post(req, ev); } |