]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:rpc_client: add cli_rpc_pipe_client_prepare_alter() helper
authorStefan Metzmacher <metze@samba.org>
Tue, 17 Sep 2024 03:54:05 +0000 (05:54 +0200)
committerJule Anger <janger@samba.org>
Thu, 12 Jun 2025 11:27:15 +0000 (11:27 +0000)
This will allow to do an alter context if security context multiplexing
is negotiated or opening a new connection in the same association group.

The old connection will be kept open, but not used anymore...

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
(cherry picked from commit dd7980841593d18081216e6eb3e1b0fb9bd9c757)

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

index 1d48dab85b3cc2b44dadaeca99055d23fd46d962..143a91138331a57c72590faf0a8e5820fd41a358 100644 (file)
@@ -4045,6 +4045,87 @@ static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
        return NT_STATUS_OK;
 }
 
+static NTSTATUS cli_rpc_pipe_client_reconnect(struct rpc_pipe_client *p)
+{
+       enum dcerpc_transport_t transport =
+               dcerpc_binding_get_transport(p->assoc->binding);
+       NTSTATUS status;
+
+       switch (transport) {
+       case NCACN_IP_TCP:
+               status = rpc_pipe_open_tcp_port(p,
+                                               p->assoc,
+                                               &p->conn);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+               break;
+       case NCACN_NP:
+               status = rpc_client_connection_np(p->np_cli,
+                                                 p->assoc,
+                                                 &p->conn);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+               talloc_steal(p, p->conn);
+               break;
+       default:
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
+       return NT_STATUS_OK;
+}
+
+NTSTATUS cli_rpc_pipe_client_prepare_alter(struct rpc_pipe_client *p,
+                                          bool new_auth_context,
+                                          const struct ndr_interface_table *table,
+                                          bool new_pres_context)
+{
+       uint32_t f = p->assoc->features.negotiated;
+       NTSTATUS status;
+
+       if (!new_auth_context && !new_pres_context) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       TALLOC_FREE(p->binding_handle);
+
+       if (new_auth_context) {
+               p->auth = NULL;
+       }
+
+       if (new_auth_context &&
+           !(f & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING))
+       {
+               /*
+                * new auth context without
+                * security context multiplexing.
+                *
+                * We need to create a new transport
+                * connection is the same association
+                * group
+                *
+                * We need to keep the old connection alive
+                * in order to connect to the existing association
+                * group..., so no TALLOC_FREE(p->conn)
+                */
+               p->conn = NULL;
+               status = cli_rpc_pipe_client_reconnect(p);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+       }
+
+       if (new_pres_context) {
+               /* rpc_pipe_bind_send should allocate an id... */
+               p->pres_context_id = UINT16_MAX;
+               p->table = table;
+               p->transfer_syntax = ndr_transfer_syntax_ndr;
+       }
+
+       return NT_STATUS_OK;
+}
+
 /****************************************************************************
  Open a named pipe to an SMB server and bind anonymously.
  ****************************************************************************/
index 9dc46e755ead569212588f8234dff10ac2334a0b..006a30684b0a40b3da1b8ba6cbb700e0c2caff61 100644 (file)
@@ -81,6 +81,11 @@ NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
                                  const struct ndr_interface_table *table,
                                  struct rpc_pipe_client **presult);
 
+NTSTATUS cli_rpc_pipe_client_prepare_alter(struct rpc_pipe_client *p,
+                                          bool new_auth_context,
+                                          const struct ndr_interface_table *table,
+                                          bool new_pres_context);
+
 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
                                            enum dcerpc_transport_t transport,
                                            const struct ndr_interface_table *table,