From: Stefan Metzmacher Date: Thu, 18 Apr 2024 23:22:17 +0000 (+0200) Subject: s3:rpc_client: implement bind time feature negotiation X-Git-Url: http://git.samba.org/samba.git/?p=metze%2Fsamba-autobuild%2F.git;a=commitdiff_plain;h=HEAD s3:rpc_client: implement bind time feature negotiation This is not strictly needed as we don't use any of the optional features yet. But it will make it easier to add bind time features we'll actually use later. Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett --- diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 15103093224..cf551f6f548 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1130,17 +1130,28 @@ static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx, { uint16_t auth_len = auth_info->length; NTSTATUS status; - struct dcerpc_ctx_list ctx_list = { - .context_id = 0, - .num_transfer_syntaxes = 1, - .abstract_syntax = *abstract, - .transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer), + struct ndr_syntax_id bind_time_features = dcerpc_construct_bind_time_features( + DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING | + DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN); + struct dcerpc_ctx_list ctx_list[2] = { + [0] = { + .context_id = 0, + .num_transfer_syntaxes = 1, + .abstract_syntax = *abstract, + .transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer), + }, + [1] = { + .context_id = 1, + .num_transfer_syntaxes = 1, + .abstract_syntax = *abstract, + .transfer_syntaxes = &bind_time_features, + }, }; union dcerpc_payload u = { .bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN, .bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN, - .bind.num_contexts = 1, - .bind.ctx_list = &ctx_list, + .bind.num_contexts = ptype == DCERPC_PKT_BIND ? 2 : 1, + .bind.ctx_list = ctx_list, .bind.auth_info = *auth_info, }; uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; @@ -1685,6 +1696,18 @@ static bool check_bind_response(const struct dcerpc_bind_ack *r, return false; } + if (r->num_results >= 2) { + const struct dcerpc_ack_ctx *neg = &r->ctx_list[1]; + + if (neg->result == DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) { + cli->bind_time_features = neg->reason.negotiate; + } else { + DBG_DEBUG("bind_time_feature failed - " + "result: %d reason %x\n", + neg->result, neg->reason.value); + } + } + DEBUG(5,("check_bind_response: accepted!\n")); return True; } diff --git a/source3/rpc_client/rpc_client.h b/source3/rpc_client/rpc_client.h index f1be075fea9..55eb4dec90b 100644 --- a/source3/rpc_client/rpc_client.h +++ b/source3/rpc_client/rpc_client.h @@ -37,6 +37,13 @@ struct rpc_pipe_client { struct rpc_cli_transport *transport; struct dcerpc_binding_handle *binding_handle; + /* + * This is per association_group, but + * for now we only have one connection + * per association_group. + */ + uint16_t bind_time_features; + struct ndr_syntax_id abstract_syntax; struct ndr_syntax_id transfer_syntax; bool verified_pcontext;