s3:rpc_client: implement bind time feature negotiation
authorStefan Metzmacher <metze@samba.org>
Thu, 18 Apr 2024 23:22:17 +0000 (01:22 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 23 Apr 2024 17:29:55 +0000 (17:29 +0000)
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 <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Tue Apr 23 17:29:55 UTC 2024 on atb-devel-224

source3/rpc_client/cli_pipe.c
source3/rpc_client/rpc_client.h

index 15103093224fadef42ee847a5328046491b4c26e..cf551f6f548fa9c63867d16369c1104bc142b5e9 100644 (file)
@@ -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;
 }
index f1be075fea9125a4a549c7b0d6bbf686a0ca7f33..55eb4dec90bbe8e2701c8de1887dd25f0f7c36c2 100644 (file)
@@ -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;