s3:rpc_client: don't mix layers and keep a reference to cli_state in the caller
authorStefan Metzmacher <metze@samba.org>
Mon, 29 Mar 2010 12:58:19 +0000 (14:58 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 29 Mar 2010 16:11:16 +0000 (18:11 +0200)
We should not rely on the backend to have a reference to the cli_state.
This will make it possible for the backend to set its cli_state reference
to NULL, when the transport is dead.

metze

source3/rpc_client/cli_pipe.c

index af1ebd6f418c3ded3776eef8a55defdc0f134cb2..09874c72cdf34f15d55ed80c16c031ebcef17bca 100644 (file)
@@ -3599,14 +3599,14 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
        return status;
 }
 
-static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
-{
+struct rpc_pipe_client_np_ref {
        struct cli_state *cli;
+       struct rpc_pipe_client *pipe;
+};
 
-       cli = rpc_pipe_np_smb_conn(p);
-       if (cli != NULL) {
-               DLIST_REMOVE(cli->pipe_list, p);
-       }
+static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
+{
+       DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
        return 0;
 }
 
@@ -3629,6 +3629,7 @@ static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
 {
        struct rpc_pipe_client *result;
        NTSTATUS status;
+       struct rpc_pipe_client_np_ref *np_ref;
 
        /* sanity check to protect against crashes */
 
@@ -3667,8 +3668,16 @@ static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
 
        result->transport->transport = NCACN_NP;
 
-       DLIST_ADD(cli->pipe_list, result);
-       talloc_set_destructor(result, rpc_pipe_client_np_destructor);
+       np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
+       if (np_ref == NULL) {
+               TALLOC_FREE(result);
+               return NT_STATUS_NO_MEMORY;
+       }
+       np_ref->cli = 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);
 
        *presult = result;
        return NT_STATUS_OK;