[SCM] Samba Shared Repository - branch v4-8-test updated

Karolin Seeger kseeger at samba.org
Mon May 14 13:12:02 UTC 2018


The branch, v4-8-test has been updated
       via  32a5538 winbindd: Do re-connect if the RPC call fails in the passdb case
       via  7557c5d winbindd: Add a cache of the samr and lsa handles for the passdb domain
       via  54c537a vfs_ceph: add fake async pwrite/pread send/recv hooks
       via  01c335d s3: VFS: Fix memory leak in vfs_ceph.
       via  060a047 s4:lsa_lookup: remove TALLOC_FREE(state) after all dcesrv_lsa_Lookup{Names,Sids}_base_map() calls
       via  234216c s4-lsa: Fix use-after-free in LSA server
       via  1b34b86 s3:cleanupd: sends MSG_SMB_UNLOCK twice to interested peers
      from  bb5cee3 s3:smbspool: Fix cmdline argument handling

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-8-test


- Log -----------------------------------------------------------------
commit 32a5538a525e3a52f2a3b28e623c602ff8a155ce
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Mar 21 20:44:31 2018 +1300

    winbindd: Do re-connect if the RPC call fails in the passdb case
    
    This is very, very unlikely but possible as in the AD case the RPC server is in
    another process that may eventually be able to restart.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13430
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    (cherry picked from commit fc9150dcab231fe9beb72e198b0c2742d5f2505f)
    
    Autobuild-User(v4-8-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-8-test): Mon May 14 15:11:11 CEST 2018 on sn-devel-144

commit 7557c5df797df4d5a0b42bdc7cffc5c02cc5a6a8
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Mar 21 20:43:10 2018 +1300

    winbindd: Add a cache of the samr and lsa handles for the passdb domain
    
    This domain is very close, in AD DC configurations over a internal ncacn_np pipe
    and otherwise in the same process via C linking.  It is however very expensive
    to re-create the binding handle per SID->name lookup, so keep a cache.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13430
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    (cherry picked from commit d418d0ca33afb41a793a2fff19ca68871aa5e9ef)

commit 54c537a0eebc8a4450cc71b25b605719f44e2af0
Author: David Disseldorp <ddiss at samba.org>
Date:   Wed May 9 16:51:34 2018 +0200

    vfs_ceph: add fake async pwrite/pread send/recv hooks
    
    As found by Jeremy, VFS modules that don't provide pread_send() or
    pwrite_send() hooks result in vfs_default fallback, which is
    catastrophic for VFS modules with non-mounted filesystems such as
    vfs_ceph.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13425
    
    Reported-by: Jeremy Allison <jra at samba.org>
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit f0e6453b0420fe9d062936d4ddc05f44b40cf2ba)

commit 01c335ddd88ccbac2210af1c19f80c76326d168b
Author: Vandana Rungta <vrungta at amazon.com>
Date:   Tue May 8 11:27:47 2018 -0700

    s3: VFS: Fix memory leak in vfs_ceph.
    
    Centralize error handling.
    
    https://bugzilla.samba.org/show_bug.cgi?id=13424
    
    Signed-off-by: Vandana Rungta <vrungta at amazon.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: David Disseldorp <ddiss at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Wed May  9 04:28:11 CEST 2018 on sn-devel-144
    
    (cherry picked from commit 4e78aeedb8329953df83fc7f2c191b2c97a051d0)

commit 060a04793c3c5cdc902d71619a2ba32fab0bc7c3
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri May 11 06:43:14 2018 +0200

    s4:lsa_lookup: remove TALLOC_FREE(state) after all dcesrv_lsa_Lookup{Names,Sids}_base_map() calls
    
    This completes the regression fix of commit 7e091e505156381e385235ab4518b4d133a98497.
    
    There might be strings allocated on state, which are part of the
    result.
    
    The reason for the TALLOC_FREE(state) was to cleanup the possible
    irpc_handle before leaving the function. Now we call
    TALLOC_FREE(state->wb.irpc_handle) explicitly in
    dcesrv_lsa_Lookup{Names,Sids}_base_done() instead.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13420
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Sun May 13 10:27:28 CEST 2018 on sn-devel-144
    
    (cherry picked from commit 9a513304adadd79d1c63d55fcf06b67ed45d43ba)

commit 234216c1e02dd45d35179235dcef57948b63abfd
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu May 3 16:22:19 2018 +1200

    s4-lsa: Fix use-after-free in LSA server
    
    This is a regression introduced in ab7988aa2fd1a43f576a4b73a6893c61c7ef1957.
    
    The state variable contains the data to be returned to the client
    and packed into NDR after the function returned.
    
    This memory needs to be kept (on mem_ctx as parent) until that is
    pushed and freed by the caller.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13420
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    (cherry picked from commit 7e091e505156381e385235ab4518b4d133a98497)

commit 1b34b8691896dcfac6be604fdd354c2b2466efb8
Author: Ralph Boehme <slow at samba.org>
Date:   Tue May 1 09:53:36 2018 +0200

    s3:cleanupd: sends MSG_SMB_UNLOCK twice to interested peers
    
    MSG_SMB_UNLOCK should be send to smbd that are waiting on blocked
    byte-range-locks when a lock holder died.
    
    In smbd_cleanupd_unlock() we do this twice: once via a broadcast and
    then again via brl_revalidate() to processes that are actually recorded
    in brlock.tdb.
    
    As brl_revalidate() should already take care of signaling anyone who
    would be interested in the message, there's no need to broadcast.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13416
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Fri May  4 03:02:28 CEST 2018 on sn-devel-144
    
    (cherry picked from commit 53ff08a2cf838c0f1c3f050ac2aa13fc3acc5981)

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

Summary of changes:
 source3/modules/vfs_ceph.c          | 130 +++++++++++-
 source3/smbd/smbd_cleanupd.c        |   2 -
 source3/winbindd/winbindd_samr.c    | 395 ++++++++++++++++++++++++++----------
 source4/rpc_server/lsa/lsa_lookup.c |  11 +-
 4 files changed, 408 insertions(+), 130 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 656ce57..857310c 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -482,6 +482,57 @@ static ssize_t cephwrap_pread(struct vfs_handle_struct *handle, files_struct *fs
 	WRAP_RETURN(result);
 }
 
+struct cephwrap_pread_state {
+	ssize_t bytes_read;
+	struct vfs_aio_state vfs_aio_state;
+};
+
+/*
+ * Fake up an async ceph read by calling the synchronous API.
+ */
+static struct tevent_req *cephwrap_pread_send(struct vfs_handle_struct *handle,
+					      TALLOC_CTX *mem_ctx,
+					      struct tevent_context *ev,
+					      struct files_struct *fsp,
+					      void *data,
+					      size_t n, off_t offset)
+{
+	struct tevent_req *req = NULL;
+	struct cephwrap_pread_state *state = NULL;
+	int ret = -1;
+
+	DBG_DEBUG("[CEPH] %s\n", __func__);
+	req = tevent_req_create(mem_ctx, &state, struct cephwrap_pread_state);
+	if (req == NULL) {
+		return NULL;
+	}
+
+	ret = ceph_read(handle->data, fsp->fh->fd, data, n, offset);
+	if (ret < 0) {
+		/* ceph returns -errno on error. */
+		tevent_req_error(req, -ret);
+		return tevent_req_post(req, ev);
+	}
+
+	state->bytes_read = ret;
+	tevent_req_done(req);
+	/* Return and schedule the completion of the call. */
+	return tevent_req_post(req, ev);
+}
+
+static ssize_t cephwrap_pread_recv(struct tevent_req *req,
+				   struct vfs_aio_state *vfs_aio_state)
+{
+	struct cephwrap_pread_state *state =
+		tevent_req_data(req, struct cephwrap_pread_state);
+
+	DBG_DEBUG("[CEPH] %s\n", __func__);
+	if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
+		return -1;
+	}
+	*vfs_aio_state = state->vfs_aio_state;
+	return state->bytes_read;
+}
 
 static ssize_t cephwrap_write(struct vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n)
 {
@@ -510,6 +561,58 @@ static ssize_t cephwrap_pwrite(struct vfs_handle_struct *handle, files_struct *f
 	WRAP_RETURN(result);
 }
 
+struct cephwrap_pwrite_state {
+	ssize_t bytes_written;
+	struct vfs_aio_state vfs_aio_state;
+};
+
+/*
+ * Fake up an async ceph write by calling the synchronous API.
+ */
+static struct tevent_req *cephwrap_pwrite_send(struct vfs_handle_struct *handle,
+					       TALLOC_CTX *mem_ctx,
+					       struct tevent_context *ev,
+					       struct files_struct *fsp,
+					       const void *data,
+					       size_t n, off_t offset)
+{
+	struct tevent_req *req = NULL;
+	struct cephwrap_pwrite_state *state = NULL;
+	int ret = -1;
+
+	DBG_DEBUG("[CEPH] %s\n", __func__);
+	req = tevent_req_create(mem_ctx, &state, struct cephwrap_pwrite_state);
+	if (req == NULL) {
+		return NULL;
+	}
+
+	ret = ceph_write(handle->data, fsp->fh->fd, data, n, offset);
+	if (ret < 0) {
+		/* ceph returns -errno on error. */
+		tevent_req_error(req, -ret);
+		return tevent_req_post(req, ev);
+	}
+
+	state->bytes_written = ret;
+	tevent_req_done(req);
+	/* Return and schedule the completion of the call. */
+	return tevent_req_post(req, ev);
+}
+
+static ssize_t cephwrap_pwrite_recv(struct tevent_req *req,
+				    struct vfs_aio_state *vfs_aio_state)
+{
+	struct cephwrap_pwrite_state *state =
+		tevent_req_data(req, struct cephwrap_pwrite_state);
+
+	DBG_DEBUG("[CEPH] %s\n", __func__);
+	if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
+		return -1;
+	}
+	*vfs_aio_state = state->vfs_aio_state;
+	return state->bytes_written;
+}
+
 static off_t cephwrap_lseek(struct vfs_handle_struct *handle, files_struct *fsp, off_t offset, int whence)
 {
 	off_t result = 0;
@@ -571,7 +674,7 @@ static int cephwrap_fsync(struct vfs_handle_struct *handle, files_struct *fsp)
 }
 
 /*
- * Fake up an async ceph fsync by calling the sychronous API.
+ * Fake up an async ceph fsync by calling the synchronous API.
  */
 
 static struct tevent_req *cephwrap_fsync_send(struct vfs_handle_struct *handle,
@@ -1252,30 +1355,31 @@ static struct smb_filename *cephwrap_realpath(struct vfs_handle_struct *handle,
 				TALLOC_CTX *ctx,
 				const struct smb_filename *smb_fname)
 {
-	char *result;
+	char *result = NULL;
 	const char *path = smb_fname->base_name;
 	size_t len = strlen(path);
 	struct smb_filename *result_fname = NULL;
+	int r = -1;
 
-	result = SMB_MALLOC_ARRAY(char, PATH_MAX+1);
 	if (len && (path[0] == '/')) {
-		int r = asprintf(&result, "%s", path);
-		if (r < 0) return NULL;
+		r = asprintf(&result, "%s", path);
 	} else if ((len >= 2) && (path[0] == '.') && (path[1] == '/')) {
 		if (len == 2) {
-			int r = asprintf(&result, "%s",
+			r = asprintf(&result, "%s",
 					handle->conn->connectpath);
-			if (r < 0) return NULL;
 		} else {
-			int r = asprintf(&result, "%s/%s",
+			r = asprintf(&result, "%s/%s",
 					handle->conn->connectpath, &path[2]);
-			if (r < 0) return NULL;
 		}
 	} else {
-		int r = asprintf(&result, "%s/%s",
+		r = asprintf(&result, "%s/%s",
 				handle->conn->connectpath, path);
-		if (r < 0) return NULL;
 	}
+
+	if (r < 0) {
+		return NULL;
+	}
+
 	DBG_DEBUG("[CEPH] realpath(%p, %s) = %s\n", handle, path, result);
 	result_fname = synthetic_smb_fname(ctx,
 				result,
@@ -1484,8 +1588,12 @@ static struct vfs_fn_pointers ceph_fns = {
 	.close_fn = cephwrap_close,
 	.read_fn = cephwrap_read,
 	.pread_fn = cephwrap_pread,
+	.pread_send_fn = cephwrap_pread_send,
+	.pread_recv_fn = cephwrap_pread_recv,
 	.write_fn = cephwrap_write,
 	.pwrite_fn = cephwrap_pwrite,
+	.pwrite_send_fn = cephwrap_pwrite_send,
+	.pwrite_recv_fn = cephwrap_pwrite_recv,
 	.lseek_fn = cephwrap_lseek,
 	.sendfile_fn = cephwrap_sendfile,
 	.recvfile_fn = cephwrap_recvfile,
diff --git a/source3/smbd/smbd_cleanupd.c b/source3/smbd/smbd_cleanupd.c
index a9b1e8a..6ed8720 100644
--- a/source3/smbd/smbd_cleanupd.c
+++ b/source3/smbd/smbd_cleanupd.c
@@ -98,8 +98,6 @@ static void smbd_cleanupd_unlock(struct messaging_context *msg,
 	DBG_WARNING("Cleaning up brl and lock database after unclean "
 		    "shutdown\n");
 
-	messaging_send_all(msg, MSG_SMB_UNLOCK, NULL, 0);
-
 	brl_revalidate(msg, private_data, msg_type, server_id, data);
 }
 
diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c
index aedb77b..31720d5 100644
--- a/source3/winbindd/winbindd_samr.c
+++ b/source3/winbindd/winbindd_samr.c
@@ -28,6 +28,7 @@
 #include "winbindd_rpc.h"
 #include "lib/util_unixsids.h"
 #include "rpc_client/rpc_client.h"
+#include "rpc_client/cli_pipe.h"
 #include "../librpc/gen_ndr/ndr_samr_c.h"
 #include "rpc_client/cli_samr.h"
 #include "../librpc/gen_ndr/ndr_lsa_c.h"
@@ -40,6 +41,20 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
+/*
+ * The other end of this won't go away easily, so we can trust it
+ *
+ * It is either a long-lived process with the same lifetime as
+ * winbindd or a part of this process
+ */
+struct winbind_internal_pipes {
+	struct rpc_pipe_client *samr_pipe;
+	struct policy_handle samr_domain_hnd;
+	struct rpc_pipe_client *lsa_pipe;
+	struct policy_handle lsa_hnd;
+};
+
+
 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
 				 struct winbindd_domain *domain,
 				 struct rpc_pipe_client **samr_pipe,
@@ -101,6 +116,96 @@ NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
 	return status;
 }
 
+
+static NTSTATUS open_cached_internal_pipe_conn(
+	struct winbindd_domain *domain,
+	struct rpc_pipe_client **samr_pipe,
+	struct policy_handle *samr_domain_hnd,
+	struct rpc_pipe_client **lsa_pipe,
+	struct policy_handle *lsa_hnd)
+{
+	struct winbind_internal_pipes *internal_pipes = NULL;
+
+	if (domain->private_data == NULL) {
+		TALLOC_CTX *frame = talloc_stackframe();
+		NTSTATUS status;
+
+		internal_pipes = talloc_zero(frame,
+					     struct winbind_internal_pipes);
+
+		status = open_internal_samr_conn(
+			internal_pipes,
+			domain,
+			&internal_pipes->samr_pipe,
+			&internal_pipes->samr_domain_hnd);
+		if (!NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(frame);
+			return status;
+		}
+
+		status = open_internal_lsa_conn(internal_pipes,
+						&internal_pipes->lsa_pipe,
+						&internal_pipes->lsa_hnd);
+
+		if (!NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(frame);
+			return status;
+		}
+
+		domain->private_data = talloc_move(domain, &internal_pipes);
+
+		TALLOC_FREE(frame);
+
+	}
+
+	internal_pipes = talloc_get_type_abort(
+		domain->private_data, struct winbind_internal_pipes);
+
+	if (samr_domain_hnd) {
+		*samr_domain_hnd = internal_pipes->samr_domain_hnd;
+	}
+
+	if (samr_pipe) {
+		*samr_pipe = internal_pipes->samr_pipe;
+	}
+
+	if (lsa_hnd) {
+		*lsa_hnd = internal_pipes->lsa_hnd;
+	}
+
+	if (lsa_pipe) {
+		*lsa_pipe = internal_pipes->lsa_pipe;
+	}
+
+	return NT_STATUS_OK;
+}
+
+static bool reset_connection_on_error(struct winbindd_domain *domain,
+				      struct rpc_pipe_client *p,
+				      NTSTATUS status)
+{
+	struct winbind_internal_pipes *internal_pipes = NULL;
+
+	internal_pipes = talloc_get_type_abort(
+		domain->private_data, struct winbind_internal_pipes);
+
+	if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
+	    NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR))
+	{
+		TALLOC_FREE(internal_pipes);
+		domain->private_data = NULL;
+		return true;
+	}
+
+	if (!rpccli_is_connected(p)) {
+		TALLOC_FREE(internal_pipes);
+		domain->private_data = NULL;
+		return true;
+	}
+
+	return false;
+}
+
 /*********************************************************************
  SAM specific functions.
 *********************************************************************/
@@ -116,8 +221,8 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
 	struct wb_acct_info *info = NULL;
 	uint32_t num_info = 0;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
+	bool retry = false;
 
 	DEBUG(3,("sam_enum_dom_groups\n"));
 
@@ -130,20 +235,31 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+again:
+	status = open_cached_internal_pipe_conn(domain,
+						&samr_pipe,
+						&dom_pol,
+						NULL,
+						NULL);
 	if (!NT_STATUS_IS_OK(status)) {
-		goto error;
+		TALLOC_FREE(tmp_ctx);
+		return status;
 	}
 
-	b = samr_pipe->binding_handle;
-
 	status = rpc_enum_dom_groups(tmp_ctx,
 				     samr_pipe,
 				     &dom_pol,
 				     &num_info,
 				     &info);
+
+	if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+		retry = true;
+		goto again;
+	}
+
 	if (!NT_STATUS_IS_OK(status)) {
-		goto error;
+		TALLOC_FREE(tmp_ctx);
+		return status;
 	}
 
 	if (pnum_info) {
@@ -154,10 +270,6 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
 		*pinfo = talloc_move(mem_ctx, &info);
 	}
 
-error:
-	if (b && is_valid_policy_hnd(&dom_pol)) {
-		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
-	}
 	TALLOC_FREE(tmp_ctx);
 	return status;
 }
@@ -171,8 +283,8 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
 	struct policy_handle dom_pol = { 0 };
 	uint32_t *rids = NULL;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
+	bool retry = false;
 
 	DEBUG(3,("samr_query_user_list\n"));
 
@@ -181,18 +293,26 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+again:
+	status = open_cached_internal_pipe_conn(domain,
+						&samr_pipe,
+						&dom_pol,
+						NULL,
+						NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = samr_pipe->binding_handle;
-
 	status = rpc_query_user_list(tmp_ctx,
 				     samr_pipe,
 				     &dom_pol,
 				     &domain->sid,
 				     &rids);
+	if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+		retry = true;
+		goto again;
+	}
+
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
@@ -202,10 +322,6 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
 	}
 
 done:
-	if (b && is_valid_policy_hnd(&dom_pol)) {
-		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
-	}
-
 	TALLOC_FREE(rids);
 	TALLOC_FREE(tmp_ctx);
 	return status;
@@ -221,8 +337,8 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
 	struct netr_DomainTrust *trusts = NULL;
 	uint32_t num_trusts = 0;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
+	bool retry = false;
 
 	DEBUG(3,("samr: trusted domains\n"));
 
@@ -235,18 +351,27 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
+again:
+	status = open_cached_internal_pipe_conn(domain,
+						NULL,
+						NULL,
+						&lsa_pipe,
+						&lsa_policy);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = lsa_pipe->binding_handle;
-
 	status = rpc_trusted_domains(tmp_ctx,
 				     lsa_pipe,
 				     &lsa_policy,
 				     &num_trusts,
 				     &trusts);
+
+	if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
+		retry = true;
+		goto again;
+	}
+
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
@@ -257,10 +382,6 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
 	}
 
 done:
-	if (b && is_valid_policy_hnd(&lsa_policy)) {
-		dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
-	}
-
 	TALLOC_FREE(tmp_ctx);
 	return status;
 }
@@ -284,8 +405,8 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
 	uint32_t *name_types = NULL;
 
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
+	bool retry = false;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list