From: Stefan Metzmacher Date: Wed, 12 Feb 2025 11:35:20 +0000 (+0100) Subject: s3:rpc_client: Add cli_rpc_pipe_reopen_np_noauth() X-Git-Tag: tevent-0.17.0~760 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d2ac6221db48b93581d7ce48d31f8851c88b77bc;p=thirdparty%2Fsamba.git s3:rpc_client: Add cli_rpc_pipe_reopen_np_noauth() BUG: https://bugzilla.samba.org/show_bug.cgi?id=15680 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index e83d31bd703..23adbbc62fa 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -4254,6 +4254,94 @@ NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli, presult); } +/**************************************************************************** + * Reopen a connection with the same parameters. + * + * This is useful if we try an RPC function the server doesn't know about and + * disconnects us. + ****************************************************************************/ +NTSTATUS cli_rpc_pipe_reopen_np_noauth(struct rpc_pipe_client *rpccli) +{ + TALLOC_CTX *frame = talloc_stackframe(); + enum dcerpc_transport_t transport; + struct cli_state *cli = NULL; + struct rpc_client_association *assoc = NULL; + struct rpc_client_connection *new_conn = NULL; + struct pipe_auth_data *new_auth = NULL; + NTSTATUS status; + + if (rpccli->assoc == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + transport = dcerpc_binding_get_transport(rpccli->assoc->binding); + if (transport != NCACN_NP) { + TALLOC_FREE(frame); + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + if (rpccli->np_cli == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_INVALID_PARAMETER_MIX; + } + cli = rpccli->np_cli; + + /* + * close the old connection + */ + TALLOC_FREE(rpccli->conn); + + /* + * Free the auth context + */ + TALLOC_FREE(rpccli->auth); + + /* + * Reset the association + */ + assoc = talloc_move(frame, &rpccli->assoc); + status = dcerpc_binding_set_assoc_group_id(assoc->binding, 0); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + assoc->features.negotiated = 0; + if (assoc->features.client != 0) { + assoc->features.negotiation_done = false; + } + assoc->next_call_id = 0; + + status = rpc_client_connection_np(cli, + assoc, + &new_conn); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + rpccli->assoc = talloc_move(rpccli, &assoc); + rpccli->conn = talloc_move(rpccli, &new_conn); + + /* rpc_pipe_bind_send should allocate an id... */ + rpccli->pres_context_id = UINT16_MAX; + rpccli->verified_pcontext = false; + + status = rpccli_anon_bind_data(rpccli, &new_auth); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + status = rpc_pipe_bind(rpccli, new_auth); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + TALLOC_FREE(frame); + return NT_STATUS_OK; +} + /**************************************************************************** Open a named pipe to an SMB server and bind using the mech specified diff --git a/source3/rpc_client/cli_pipe.h b/source3/rpc_client/cli_pipe.h index d6e472afcf6..e90dd3b9446 100644 --- a/source3/rpc_client/cli_pipe.h +++ b/source3/rpc_client/cli_pipe.h @@ -81,6 +81,8 @@ 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_reopen_np_noauth(struct rpc_pipe_client *rpccli); + NTSTATUS cli_rpc_pipe_client_prepare_alter(struct rpc_pipe_client *p, bool new_auth_context, const struct ndr_interface_table *table,