[SCM] Samba Shared Repository - branch v3-4-test updated

Karolin Seeger kseeger at samba.org
Tue Apr 13 12:20:40 MDT 2010


The branch, v3-4-test has been updated
       via  6d24f28... s3:winbindd: correctly retry if the netlogon pipe gets disconnected during a logon call
       via  30c048c... s3:winbindd_reconnect: don't only reconnect on NT_STATUS_UNSUCCESSFUL
       via  61a3538... s3:winbindd_cm: invalidate connection if cm_connect_netlogon() fails
       via  4ef6370... s3:winbindd: consistently use TALLOC_FREE(conn->foo_pipe) is we create a new connection
       via  ff9277f... s3:winbindd_cm: use rpccli_is_connected() helper function
       via  21afa22... s3:winbindd_cm: use cli_state_is_connected() helper function
       via  5ae76f3... s3:rpc_client: return at least 10 sec as old timeout in rpccli_set_timeout() instead of 0
       via  b462bc1... s3:rpc_client: add set_timeout hook to rpc_cli_transport
       via  a8a1a6c... s3:rpc_client: add rpccli_is_connected()
       via  582b1cd... s3:rpc_client: don't mix layers and keep a reference to cli_state in the caller
       via  3ea35cd... s3:rpc_transport_np: use cli_state_is_connected() helper
       via  5a4bdb7... s3:libsmb: add cli_state_is_connected() function
       via  e6d5238... s3:libsmb: don't let cli_shutdown() segfault with a NULL cli_state
       via  2ce1bcd... s3:rpc_transport_np: handle trans rdata like the output of a normal read
       via  6166e18... s3: Fix infinite loop in NCACN_IP_TCP asa there is no timeout. Assume lsa_pipe_tcp is ok but network is down, then send request is ok, but select() on writeable fds loops forever since there is no response.
       via  67b51cc... Fix broken pipe handling
       via  407b957... s3:rpc_client: close the socket when pipe is broken
       via  be9a46c... s3: fix crash in winbindd (similar to commit f8cc0e88fbbb082ead023e0cb437b1e12cf35459)
      from  1038d91... s3-docs: Fix typo in man idmap_ad.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-4-test


- Log -----------------------------------------------------------------
commit 6d24f28f52fb0e21943a1639c426cf7f825d15e7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 29 22:03:55 2010 +0200

    s3:winbindd: correctly retry if the netlogon pipe gets disconnected during a logon call
    
    This fixes hopefully the last part of bug #7295.
    
    metze
    (cherry picked from commit 4c6cde99c0751a073120d8bc36d40922d8027344)
    (cherry picked from commit 482518fcafb18bda1f084ebf1906a2ad02436b80)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 30c048c124ece9648e0ec00991780b57af90201e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 6 14:45:19 2010 +0200

    s3:winbindd_reconnect: don't only reconnect on NT_STATUS_UNSUCCESSFUL
    
    metze
    (cherry picked from commit 6bd5a2a3739938f95fce23ab2da652c9b5a48111)
    (cherry picked from commit 169628fcb656ba5987a99bd50c7f588b731eae51)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 61a353807ccefef98fa83e5abcebfe879cdf4337
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 25 15:25:47 2010 +0100

    s3:winbindd_cm: invalidate connection if cm_connect_netlogon() fails
    
    metze
    (cherry picked from commit 94a4bcd2f0c0464e192556679c6636639cb307ea)
    (cherry picked from commit c046ae8428fb62ff2749689e7c738f1a2e8f8251)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 4ef6370eaaa307ccfd74012a4b9397312ff747eb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 25 15:17:07 2010 +0100

    s3:winbindd: consistently use TALLOC_FREE(conn->foo_pipe) is we create a new connection
    
    metze
    (cherry picked from commit 4f391fedac7111683d13f2d79fee7c0dbc27f86e)
    (cherry picked from commit c462e54142c00fdd81c2847d16a75119b1cc89fc)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit ff9277fb804e7d99a7e80d67c70b962b6199a4e3
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 6 14:42:04 2010 +0200

    s3:winbindd_cm: use rpccli_is_connected() helper function
    
    metze
    (cherry picked from commit d980c06a994d032a833adc8d56d2f2c037f8fdaf)
    (cherry picked from commit aa7d54ed04585a183a88363406ed7f3244b24d85)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 21afa222ab9502ecb33decd16fe540d6d855ff13
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 25 15:14:02 2010 +0100

    s3:winbindd_cm: use cli_state_is_connected() helper function
    
    metze
    (cherry picked from commit 408a3eb35a0e61b5d66a3b48ebbd1a6796672d0f)
    (cherry picked from commit 00a93190d2cae31cd2213b810ea348c055670399)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 5ae76f3beac43e7064b0304df24be84642882372
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sun Mar 28 19:34:34 2010 +0200

    s3:rpc_client: return at least 10 sec as old timeout in rpccli_set_timeout() instead of 0
    
    metze
    (cherry picked from commit 3e70da3f470eeb122f95477fb48d89939f501b3e)
    (cherry picked from commit 60861fba533027b6c9a0ff704b95dcf631ea3ca3)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit b462bc1724b3bdf9052566e683f9748ea6730169
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 6 14:31:17 2010 +0200

    s3:rpc_client: add set_timeout hook to rpc_cli_transport
    
    metze
    (cherry picked from commit 99664ad15460530b6fb44957b6c57823f09884bf)
    (cherry picked from commit 89164eb8363ffc0b951256578be48d37ddba46b1)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit a8a1a6c77a2148a729f6b285f3f945ffd5501256
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 6 14:26:29 2010 +0200

    s3:rpc_client: add rpccli_is_connected()
    
    metze
    (cherry picked from commit 4f41b53487ac9bc96c7960e8edab464558656373)
    (similar to commit 958b49323968740e2cbf69dc2a0a5dd57d5bcf87)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 582b1cdeb6c0b2145b55930421e8d48ad4754d04
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 29 14:58:19 2010 +0200

    s3:rpc_client: don't mix layers and keep a reference to cli_state in the caller
    
    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
    (cherry picked from commit dc09b12681ea0e6d4c2b0f1c99dfeb1f23019c65)
    (cherry picked from commit 1e2e47da82aeb249dce431541738a62cb139aebb)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 3ea35cd6bb61806ed502e4cd3f386c35a6f58156
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 6 12:23:39 2010 +0200

    s3:rpc_transport_np: use cli_state_is_connected() helper
    
    metze
    (cherry picked from commit b862351da8624df893ec77e020a456c1d23c58ed)
    (cherry picked from commit 8c2f4426ce178ac33748cfba01532ec2fd205710)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 5a4bdb706b97857da67c791b81039b4bc4031c76
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 25 13:20:56 2010 +0100

    s3:libsmb: add cli_state_is_connected() function
    
    metze
    (cherry picked from commit d7bf30ef92031ffddcde3680b38e602510bcae24)
    (cherry picked from commit 589f73924273e8a9b54669f42a92381661dcb33f)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit e6d5238c8403e848a43e6c7a2d3ca6422e8becd4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 29 18:23:40 2010 +0200

    s3:libsmb: don't let cli_shutdown() segfault with a NULL cli_state
    
    metze
    (similar to commit 47e10ab9a85960c78af807b66b99bcd139713644)
    (cherry picked from commit 957c0d4a5ee67ac70e576155a0f2f6f84cdb1596)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 2ce1bcd4e4430f311decb73b659c9b615d5bb4e9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 6 12:22:54 2010 +0200

    s3:rpc_transport_np: handle trans rdata like the output of a normal read
    
    Inspired by bug #7159.
    
    metze
    (cherry picked from commit 911287285cc4c8485b75edfad3c1ece901a69b0b)
    (cherry picked from commit e2739a2bf37e654c37cbea6e510f63a7ce4adfea)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 6166e1809516e6ab5911b56b20a4128b088828cf
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 6 14:14:53 2010 +0200

    s3: Fix infinite loop in NCACN_IP_TCP asa there is no timeout. Assume lsa_pipe_tcp is ok but network is down, then send request is ok, but select() on writeable fds loops forever since there is no response.
    
    Signed-off-by: Bo Yang <boyang at samba.org>
    (cherry picked from commit 36493bf2f6634b84c57107bcb86bcbf3e82e80fc)
    (similar to commit b58b359881c91ec382cfa1d6ba3007b8354b29cb)
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 67b51cc9e773fcbbc2b942a1de256e2c5b695008
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 6 14:06:39 2010 +0200

    Fix broken pipe handling
    
    Metze is right: If we have *any* error at the socket level, we just can
    not continue.
    
    Also, apply some defensive programming: With this async stuff someone else
    might already have closed the socket.
    (cherry picked from commit f140bf2e6578e45b8603d4a6c5feef9a3b735804)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 407b9577febff6dfbe29106d783d64c41d6fe4e4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 6 14:04:33 2010 +0200

    s3:rpc_client: close the socket when pipe is broken
    
    Signed-off-by: Bo Yang <boyang at samba.org>
    (similar to commit aa70e44cd0576e5280e24cf35000369a47dd958f)
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit be9a46c9cae2d05a7eb54e871e05480bd8caa609
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 6 11:53:33 2010 +0200

    s3: fix crash in winbindd (similar to commit f8cc0e88fbbb082ead023e0cb437b1e12cf35459)
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/include/client.h                |    4 +
 source3/include/proto.h                 |    2 +
 source3/libsmb/async_smb.c              |   11 +++-
 source3/libsmb/clientgen.c              |    4 +
 source3/libsmb/clierror.c               |   18 +++++
 source3/rpc_client/cli_pipe.c           |   58 ++++++++++++---
 source3/rpc_client/rpc_transport_np.c   |  118 +++++++++++++++++++++++++++++++
 source3/rpc_client/rpc_transport_smbd.c |  101 +++++++++++++++++++++++++--
 source3/rpc_client/rpc_transport_sock.c |   75 +++++++++++++++++++-
 source3/winbindd/winbindd_cm.c          |   36 ++++-----
 source3/winbindd/winbindd_pam.c         |    4 +-
 source3/winbindd/winbindd_reconnect.c   |   73 +++++++++++++++----
 12 files changed, 446 insertions(+), 58 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/client.h b/source3/include/client.h
index 1914210..d80989d 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -110,6 +110,10 @@ struct rpc_cli_transport {
 	 */
 	NTSTATUS (*trans_recv)(struct async_req *req, TALLOC_CTX *mem_ctx,
 			       uint8_t **prdata, uint32_t *prdata_len);
+
+	bool (*is_connected)(void *priv);
+	unsigned int (*set_timeout)(void *priv, unsigned int timeout);
+
 	void *priv;
 };
 
diff --git a/source3/include/proto.h b/source3/include/proto.h
index f078844..b22c530 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2456,6 +2456,7 @@ bool cli_is_dos_error(struct cli_state *cli);
 NTSTATUS cli_get_nt_error(struct cli_state *cli);
 void cli_set_nt_error(struct cli_state *cli, NTSTATUS status);
 void cli_reset_error(struct cli_state *cli);
+bool cli_state_is_connected(struct cli_state *cli);
 
 /* The following definitions come from libsmb/clifile.c  */
 
@@ -5274,6 +5275,7 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
 		       struct cli_pipe_auth_data *auth);
 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
 				unsigned int timeout);
+bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli);
 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16]);
 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
 			       struct cli_pipe_auth_data **presult);
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index 07d832e..e683e37 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -1010,6 +1010,11 @@ static void cli_state_handler(struct event_context *event_ctx,
 
 	DEBUG(11, ("cli_state_handler called with flags %d\n", flags));
 
+	if (cli->fd == -1) {
+		status = NT_STATUS_CONNECTION_INVALID;
+		goto sock_error;
+	}
+
 	if (flags & EVENT_FD_WRITE) {
 		size_t to_send;
 		ssize_t sent;
@@ -1123,6 +1128,8 @@ static void cli_state_handler(struct event_context *event_ctx,
 		}
 	}
 	TALLOC_FREE(cli->fd_event);
-	close(cli->fd);
-	cli->fd = -1;
+	if (cli->fd != -1) {
+		close(cli->fd);
+		cli->fd = -1;
+	}
 }
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 356db57..5dc43e9 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -599,6 +599,10 @@ void cli_nt_pipes_close(struct cli_state *cli)
 
 void cli_shutdown(struct cli_state *cli)
 {
+	if (cli == NULL) {
+		return;
+	}
+
 	if (cli->prev == NULL) {
 		/*
 		 * Possible head of a DFS list,
diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c
index 54f8a7a..015afb1 100644
--- a/source3/libsmb/clierror.c
+++ b/source3/libsmb/clierror.c
@@ -359,3 +359,21 @@ void cli_reset_error(struct cli_state *cli)
 		SSVAL(cli->inbuf,smb_err,0);
 	}
 }
+
+bool cli_state_is_connected(struct cli_state *cli)
+{
+	if (cli == NULL) {
+		return false;
+	}
+
+	if (!cli->initialised) {
+		return false;
+	}
+
+	if (cli->fd == -1) {
+		return false;
+	}
+
+	return true;
+}
+
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 323f861..22794bc 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -2950,15 +2950,40 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
 	return status;
 }
 
+#define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
+
 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
 				unsigned int timeout)
 {
-	struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
+	unsigned int old;
 
-	if (cli == NULL) {
-		return 0;
+	if (rpc_cli->transport == NULL) {
+		return RPCCLI_DEFAULT_TIMEOUT;
+	}
+
+	if (rpc_cli->transport->set_timeout == NULL) {
+		return RPCCLI_DEFAULT_TIMEOUT;
+	}
+
+	old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
+	if (old == 0) {
+		return RPCCLI_DEFAULT_TIMEOUT;
+	}
+
+	return old;
+}
+
+bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
+{
+	if (rpc_cli == NULL) {
+		return false;
 	}
-	return cli_set_timeout(cli, timeout);
+
+	if (rpc_cli->transport == NULL) {
+		return false;
+	}
+
+	return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
 }
 
 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
@@ -3464,14 +3489,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;
 }
 
@@ -3494,6 +3519,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 */
 
@@ -3530,8 +3556,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;
diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c
index 4ea361b..5d01871 100644
--- a/source3/rpc_client/rpc_transport_np.c
+++ b/source3/rpc_client/rpc_transport_np.c
@@ -28,9 +28,52 @@ struct rpc_transport_np_state {
 	uint16_t fnum;
 };
 
+static bool rpc_np_is_connected(void *priv)
+{
+	struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
+		priv, struct rpc_transport_np_state);
+	bool ok;
+
+	if (np_transport->cli == NULL) {
+		return false;
+	}
+
+	ok = cli_state_is_connected(np_transport->cli);
+	if (!ok) {
+		np_transport->cli = NULL;
+		return false;
+	}
+
+	return true;
+}
+
+static unsigned int rpc_np_set_timeout(void *priv, unsigned int timeout)
+{
+	struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
+		priv, struct rpc_transport_np_state);
+	bool ok;
+
+	if (np_transport->cli == NULL) {
+		return false;
+	}
+
+	ok = rpc_np_is_connected(np_transport);
+	if (!ok) {
+		return 0;
+	}
+
+	return cli_set_timeout(np_transport->cli, timeout);
+}
+
 static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s)
 {
 	bool ret;
+
+	if (!rpc_np_is_connected(s)) {
+		DEBUG(10, ("socket was closed, no need to send close request.\n"));
+		return 0;
+	}
+
 	ret = cli_close(s->cli, s->fnum);
 	if (!ret) {
 		DEBUG(1, ("rpc_transport_np_state_destructor: cli_close "
@@ -45,6 +88,7 @@ static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s)
 }
 
 struct rpc_np_write_state {
+	struct rpc_transport_np_state *np_transport;
 	size_t size;
 	size_t written;
 };
@@ -60,13 +104,26 @@ static struct async_req *rpc_np_write_send(TALLOC_CTX *mem_ctx,
 		priv, struct rpc_transport_np_state);
 	struct async_req *result, *subreq;
 	struct rpc_np_write_state *state;
+	bool ok;
 
 	if (!async_req_setup(mem_ctx, &result, &state,
 			     struct rpc_np_write_state)) {
 		return NULL;
 	}
+
+	ok = rpc_np_is_connected(np_transport);
+	if (!ok) {
+		ok = async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID);
+		if (!ok) {
+			goto fail;
+		}
+		return result;
+	}
+
+	state->np_transport = np_transport;
 	state->size = size;
 
+
 	subreq = cli_write_andx_send(mem_ctx, ev, np_transport->cli,
 				     np_transport->fnum,
 				     8, /* 8 means message mode. */
@@ -93,6 +150,7 @@ static void rpc_np_write_done(struct async_req *subreq)
 	status = cli_write_andx_recv(subreq, &state->written);
 	TALLOC_FREE(subreq);
 	if (!NT_STATUS_IS_OK(status)) {
+		state->np_transport->cli = NULL;
 		async_req_nterror(req, status);
 		return;
 	}
@@ -113,6 +171,7 @@ static NTSTATUS rpc_np_write_recv(struct async_req *req, ssize_t *pwritten)
 }
 
 struct rpc_np_read_state {
+	struct rpc_transport_np_state *np_transport;
 	uint8_t *data;
 	size_t size;
 	ssize_t received;
@@ -129,11 +188,23 @@ static struct async_req *rpc_np_read_send(TALLOC_CTX *mem_ctx,
 		priv, struct rpc_transport_np_state);
 	struct async_req *result, *subreq;
 	struct rpc_np_read_state *state;
+	bool ok;
 
 	if (!async_req_setup(mem_ctx, &result, &state,
 			     struct rpc_np_read_state)) {
 		return NULL;
 	}
+
+	ok = rpc_np_is_connected(np_transport);
+	if (!ok) {
+		ok = async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID);
+		if (!ok) {
+			goto fail;
+		}
+		return result;
+	}
+
+	state->np_transport = np_transport;
 	state->data = data;
 	state->size = size;
 
@@ -172,18 +243,21 @@ static void rpc_np_read_done(struct async_req *subreq)
 	}
 	if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(subreq);
+		state->np_transport->cli = NULL;
 		async_req_nterror(req, status);
 		return;
 	}
 
 	if (state->received > state->size) {
 		TALLOC_FREE(subreq);
+		state->np_transport->cli = NULL;
 		async_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
 		return;
 	}
 
 	if (state->received == 0) {
 		TALLOC_FREE(subreq);
+		state->np_transport->cli = NULL;
 		async_req_nterror(req, NT_STATUS_PIPE_BROKEN);
 		return;
 	}
@@ -207,7 +281,9 @@ static NTSTATUS rpc_np_read_recv(struct async_req *req, ssize_t *preceived)
 }
 
 struct rpc_np_trans_state {
+	struct rpc_transport_np_state *np_transport;
 	uint16_t setup[2];
+	uint32_t max_rdata_len;
 	uint8_t *rdata;
 	uint32_t rdata_len;
 };
@@ -224,12 +300,25 @@ static struct async_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx,
 		priv, struct rpc_transport_np_state);
 	struct async_req *result, *subreq;
 	struct rpc_np_trans_state *state;
+	bool ok;
 
 	if (!async_req_setup(mem_ctx, &result, &state,
 			     struct rpc_np_trans_state)) {
 		return NULL;
 	}
 
+	ok = rpc_np_is_connected(np_transport);
+	if (!ok) {
+		ok = async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID);
+		if (!ok) {
+			goto fail;
+		}
+		return result;
+	}
+
+	state->np_transport = np_transport;
+	state->max_rdata_len = max_rdata_len;
+
 	SSVAL(state->setup+0, 0, TRANSACT_DCERPCCMD);
 	SSVAL(state->setup+1, 0, np_transport->fnum);
 
@@ -260,10 +349,27 @@ static void rpc_np_trans_done(struct async_req *subreq)
 	status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
 				&state->rdata, &state->rdata_len);
 	TALLOC_FREE(subreq);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
+		status = NT_STATUS_OK;
+	}
 	if (!NT_STATUS_IS_OK(status)) {
+		state->np_transport->cli = NULL;
 		async_req_nterror(req, status);
 		return;
 	}
+
+	if (state->rdata_len > state->max_rdata_len) {
+		state->np_transport->cli = NULL;
+		async_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+		return;
+	}
+
+	if (state->rdata_len == 0) {
+		state->np_transport->cli = NULL;
+		async_req_nterror(req, NT_STATUS_PIPE_BROKEN);
+		return;
+	}
+
 	async_req_done(req);
 }
 
@@ -296,12 +402,22 @@ struct async_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
 {
 	struct async_req *result, *subreq;
 	struct rpc_transport_np_init_state *state;
+	bool ok;
 
 	if (!async_req_setup(mem_ctx, &result, &state,
 			     struct rpc_transport_np_init_state)) {
 		return NULL;
 	}
 
+	ok = cli_state_is_connected(cli);
+	if (!ok) {
+		ok = async_post_ntstatus(result, ev, NT_STATUS_CONNECTION_INVALID);
+		if (!ok) {
+			goto fail;
+		}
+		return result;
+	}
+
 	state->transport = talloc(state, struct rpc_cli_transport);
 	if (state->transport == NULL) {
 		goto fail;
@@ -371,6 +487,8 @@ NTSTATUS rpc_transport_np_init_recv(struct async_req *req,
 	state->transport->read_recv = rpc_np_read_recv;
 	state->transport->trans_send = rpc_np_trans_send;
 	state->transport->trans_recv = rpc_np_trans_recv;
+	state->transport->is_connected = rpc_np_is_connected;
+	state->transport->set_timeout = rpc_np_set_timeout;
 
 	*presult = talloc_move(mem_ctx, &state->transport);
 	return NT_STATUS_OK;
diff --git a/source3/rpc_client/rpc_transport_smbd.c b/source3/rpc_client/rpc_transport_smbd.c
index 823f216..f461fb8 100644
--- a/source3/rpc_client/rpc_transport_smbd.c
+++ b/source3/rpc_client/rpc_transport_smbd.c
@@ -429,8 +429,71 @@ NTSTATUS rpc_cli_smbd_conn_init(TALLOC_CTX *mem_ctx,
 	return status;
 }
 
+static void rpc_smbd_disconnect(struct rpc_transport_smbd_state *transp)
+{
+	if (transp == NULL) {
+		return;
+	}
+
+	if (transp->conn == NULL) {
+		return;
+	}
+
+	if (transp->conn->cli == NULL) {
+		return;
+	}
+
+	if (transp->conn->cli->fd != -1) {
+		close(transp->conn->cli->fd);
+		transp->conn->cli->fd = -1;
+	}
+
+	transp->conn = NULL;
+}
+
+static bool rpc_smbd_is_connected(void *priv)
+{
+	struct rpc_transport_smbd_state *transp = talloc_get_type_abort(
+		priv, struct rpc_transport_smbd_state);
+	bool ok;
+
+	if (transp->conn == NULL) {
+		return false;
+	}
+
+	if (transp->sub_transp == NULL) {
+		return false;
+	}
+
+	ok = transp->sub_transp->is_connected(transp->sub_transp->priv);
+	if (!ok) {
+		rpc_smbd_disconnect(transp);
+		return false;
+	}
+


-- 
Samba Shared Repository


More information about the samba-cvs mailing list