]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:rpc_client: convert rpc_pipe_open_np() to rpc_client_{association,connection}
authorStefan Metzmacher <metze@samba.org>
Mon, 16 Sep 2024 20:09:34 +0000 (22:09 +0200)
committerJule Anger <janger@samba.org>
Thu, 12 Jun 2025 11:27:15 +0000 (11:27 +0000)
This split out rpc_client_connection_np_send/recv, which will
be used as shortcut in a later commit.

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

source3/rpc_client/cli_pipe.c

index 81661ddeae36e69110511ebf0c31bb52f19d0e51..2766ff2f4fd1e78c9f7a4768848c3b72df4c322e 100644 (file)
@@ -3459,33 +3459,115 @@ NTSTATUS rpc_pipe_open_local_np(
        return NT_STATUS_OK;
 }
 
-struct rpc_pipe_client_np_ref {
+struct rpc_client_connection_np_state {
        struct cli_state *cli;
-       struct rpc_pipe_client *pipe;
+       const char *pipe_name;
+       struct rpc_client_connection *conn;
 };
 
-static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
+static void rpc_client_connection_np_done(struct tevent_req *subreq);
+
+static struct tevent_req *rpc_client_connection_np_send(
+       TALLOC_CTX *mem_ctx,
+       struct tevent_context *ev,
+       struct cli_state *cli,
+       const struct rpc_client_association *assoc)
 {
-       DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
-       return 0;
+       struct tevent_req *req = NULL, *subreq = NULL;
+       struct rpc_client_connection_np_state *state = NULL;
+       enum dcerpc_transport_t transport;
+       const char *endpoint = NULL;
+       struct smbXcli_session *session = NULL;
+       NTSTATUS status;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct rpc_client_connection_np_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       transport = dcerpc_binding_get_transport(assoc->binding);
+       if (transport != NCACN_NP) {
+               tevent_req_nterror(req, NT_STATUS_RPC_WRONG_KIND_OF_BINDING);
+               return tevent_req_post(req, ev);
+       }
+
+       endpoint = dcerpc_binding_get_string_option(assoc->binding,
+                                                   "endpoint");
+       if (endpoint == NULL) {
+               tevent_req_nterror(req, NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT);
+               return tevent_req_post(req, ev);
+       }
+
+       status = rpc_client_connection_create(state, &state->conn);
+       if (tevent_req_nterror(req, status)) {
+               return tevent_req_post(req, ev);
+       }
+
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               session = cli->smb2.session;
+       } else {
+               session = cli->smb1.session;
+       }
+
+       status = smbXcli_session_application_key(session, state->conn,
+                                       &state->conn->transport_session_key);
+       if (!NT_STATUS_IS_OK(status)) {
+               state->conn->transport_session_key = data_blob_null;
+       }
+
+       subreq = rpc_transport_np_init_send(state, ev, cli, endpoint);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, rpc_client_connection_np_done, req);
+       return req;
 }
 
-/****************************************************************************
- Open a named pipe over SMB to a remote server.
- *
- * CAVEAT CALLER OF THIS FUNCTION:
- *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
- *    so be sure that this function is called AFTER any structure (vs pointer)
- *    assignment of the cli.  In particular, libsmbclient does structure
- *    assignments of cli, which invalidates the data in the returned
- *    rpc_pipe_client if this function is called before the structure assignment
- *    of cli.
- *
- ****************************************************************************/
+static void rpc_client_connection_np_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct rpc_client_connection_np_state *state = tevent_req_data(
+               req, struct rpc_client_connection_np_state);
+       NTSTATUS status;
+
+       status = rpc_transport_np_init_recv(subreq,
+                                           state->conn,
+                                           &state->conn->transport);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+
+       state->conn->transport->transport = NCACN_NP;
+
+       tevent_req_done(req);
+}
+
+static NTSTATUS rpc_client_connection_np_recv(
+       struct tevent_req *req,
+       TALLOC_CTX *mem_ctx,
+       struct rpc_client_connection **pconn)
+{
+       struct rpc_client_connection_np_state *state = tevent_req_data(
+               req, struct rpc_client_connection_np_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
+       }
+       *pconn = talloc_move(mem_ctx, &state->conn);
+       tevent_req_received(req);
+       return NT_STATUS_OK;
+}
 
 struct rpc_pipe_open_np_state {
        struct cli_state *cli;
        const struct ndr_interface_table *table;
+       struct rpc_client_association *assoc;
+       struct rpc_client_connection *conn;
        struct rpc_pipe_client *result;
 };
 
@@ -3499,8 +3581,11 @@ struct tevent_req *rpc_pipe_open_np_send(
 {
        struct tevent_req *req = NULL, *subreq = NULL;
        struct rpc_pipe_open_np_state *state = NULL;
-       struct rpc_pipe_client *result = NULL;
+       const char *remote_name = NULL;
+       const struct sockaddr_storage *remote_sockaddr = NULL;
+       struct samba_sockaddr saddr = { .sa_socklen = 0, };
        const char *pipe_name = NULL;
+       NTSTATUS status;
 
        req = tevent_req_create(
                mem_ctx, &state, struct rpc_pipe_open_np_state);
@@ -3510,28 +3595,9 @@ struct tevent_req *rpc_pipe_open_np_send(
        state->cli = cli;
        state->table = table;
 
-       state->result = talloc_zero(state, struct rpc_pipe_client);
-       if (tevent_req_nomem(state->result, req)) {
-               return tevent_req_post(req, ev);
-       }
-       result = state->result;
-
-       result->abstract_syntax = table->syntax_id;
-       result->transfer_syntax = ndr_transfer_syntax_ndr;
-
-       result->desthost = talloc_strdup(
-               result, smbXcli_conn_remote_name(cli->conn));
-       if (tevent_req_nomem(result->desthost, req)) {
-               return tevent_req_post(req, ev);
-       }
-
-       result->srv_name_slash = talloc_asprintf_strupper_m(
-               result, "\\\\%s", result->desthost);
-       if (tevent_req_nomem(result->srv_name_slash, req)) {
-               return tevent_req_post(req, ev);
-       }
-
-       result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
+       remote_name = smbXcli_conn_remote_name(cli->conn);
+       remote_sockaddr = smbXcli_conn_remote_sockaddr(cli->conn);
+       saddr.u.ss = *remote_sockaddr;
 
        pipe_name = dcerpc_default_transport_endpoint(state,
                                                      NCACN_NP,
@@ -3540,7 +3606,17 @@ struct tevent_req *rpc_pipe_open_np_send(
                return tevent_req_post(req, ev);
        }
 
-       subreq = rpc_transport_np_init_send(state, ev, cli, pipe_name);
+       status = rpc_client_association_create(state,
+                                              remote_name,
+                                              NCACN_NP,
+                                              &saddr,
+                                              pipe_name,
+                                              &state->assoc);
+       if (tevent_req_nterror(req, status)) {
+               return tevent_req_post(req, ev);
+       }
+
+       subreq = rpc_client_connection_np_send(state, ev, cli, state->assoc);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
@@ -3554,31 +3630,23 @@ static void rpc_pipe_open_np_done(struct tevent_req *subreq)
                subreq, struct tevent_req);
        struct rpc_pipe_open_np_state *state = tevent_req_data(
                req, struct rpc_pipe_open_np_state);
-       struct rpc_pipe_client *result = state->result;
-       struct rpc_pipe_client_np_ref *np_ref = NULL;
        NTSTATUS status;
 
-       status = rpc_transport_np_init_recv(
-               subreq, result, &result->transport);
+       status = rpc_client_connection_np_recv(subreq,
+                                              state,
+                                              &state->conn);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
        }
 
-       result->transport->transport = NCACN_NP;
-
-       np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
-       if (tevent_req_nomem(np_ref, req)) {
-               return;
-       }
-       np_ref->cli = state->cli;
-       np_ref->pipe = result;
-
-       DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
-       talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
-
-       result->binding_handle = rpccli_bh_create(result, NULL, state->table);
-       if (tevent_req_nomem(result->binding_handle, req)) {
+       status = rpc_pipe_wrap_create(state->table,
+                                     state->cli,
+                                     &state->assoc,
+                                     &state->conn,
+                                     state,
+                                     &state->result);
+       if (tevent_req_nterror(req, status)) {
                return;
        }
 
@@ -3595,9 +3663,11 @@ NTSTATUS rpc_pipe_open_np_recv(
        NTSTATUS status;
 
        if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
                return status;
        }
        *_result = talloc_move(mem_ctx, &state->result);
+       tevent_req_received(req);
        return NT_STATUS_OK;
 }
 
@@ -3771,28 +3841,6 @@ NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
                return status;
        }
 
-       /*
-        * This is a bit of an abstraction violation due to the fact that an
-        * anonymous bind on an authenticated SMB inherits the user/domain
-        * from the enclosing SMB creds
-        */
-
-       if (transport == NCACN_NP) {
-               struct smbXcli_session *session;
-
-               if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
-                       session = cli->smb2.session;
-               } else {
-                       session = cli->smb1.session;
-               }
-
-               status = smbXcli_session_application_key(session, result,
-                                               &result->transport_session_key);
-               if (!NT_STATUS_IS_OK(status)) {
-                       result->transport_session_key = data_blob_null;
-               }
-       }
-
        status = rpc_pipe_bind(result, auth);
        if (!NT_STATUS_IS_OK(status)) {
                int lvl = 0;