[SCM] Samba Shared Repository - branch master updated

Günther Deschner gd at samba.org
Thu Sep 19 19:37:02 UTC 2024


The branch, master has been updated
       via  2ff3b9bc0d2 smbd: remove just created sharemode entry in the error codepaths
       via  a91457f97c9 smbd: consolidate DH reconnect failure code
       via  14875448ca0 s3:tests: let test_durable_handle_reconnect.sh run smb2.durable-v2-regressions.durable_v2_reconnect_bug15624
       via  ef4ef04e7f8 s4:torture/smb2: add smb2.durable-v2-regressions.durable_v2_reconnect_bug15624
       via  692ed832dff vfs_error_inject: add 'error_inject:durable_reconnect = st_ex_nlink'
       via  90d776cb183 smbd: add option "smbd:debug events" for tevent handling duration threshold warnings
       via  679e12aee2f smbd: move trace_state variable behind tv variable
       via  d8613d7ee23 smbd: add option "smbd lease break:debug hung procs"
       via  b45e78871aa smbd: log share_mode_watch_recv() errors as errors
       via  7add7dbf1ae s3/lib: add option "serverid watch:debug script"
       via  5c57e840527 s3/lib: add option "serverid watch:debug = yes" to print kernel stack of hanging process
       via  d76edcd4843 s3/lib: add next helper variable in server_id_watch_*
      from  a14320461e3 s4:lib/messaging: fix interaction between imessaging_reinit and irpc_destructor

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 2ff3b9bc0d254a63a913ff9084de3d794fee27d0
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Apr 9 14:53:32 2024 +0200

    smbd: remove just created sharemode entry in the error codepaths
    
    Without this we leave stale sharemode entries around that can lead to all sorts
    of havoc.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    
    Autobuild-User(master): Günther Deschner <gd at samba.org>
    Autobuild-Date(master): Thu Sep 19 19:36:19 UTC 2024 on atb-devel-224

commit a91457f97c98fcec1ed062514c364271af1df669
Author: Ralph Boehme <slow at samba.org>
Date:   Tue Apr 9 14:52:44 2024 +0200

    smbd: consolidate DH reconnect failure code
    
    No change in behaviour, except that we now
    also call fd_close() if vfs_default_durable_cookie()
    failed.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 14875448ca06a3a28800343a3a326f1a66bccec0
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Aug 26 14:42:12 2024 +0200

    s3:tests: let test_durable_handle_reconnect.sh run smb2.durable-v2-regressions.durable_v2_reconnect_bug15624
    
    This demonstrates the dead lock after a durable reconnect failed
    because the stat info changed, the file can't be accessed anymore
    as we leak the incomplete share mode entry in a still running
    process.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit ef4ef04e7f83b1029446ff8b5fc5fdf4ab33edbd
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Aug 26 14:42:02 2024 +0200

    s4:torture/smb2: add smb2.durable-v2-regressions.durable_v2_reconnect_bug15624
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 692ed832dfff61ad1c9b646b5c8d6f85f25efb99
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Aug 26 14:11:02 2024 +0200

    vfs_error_inject: add 'error_inject:durable_reconnect = st_ex_nlink'
    
    This allows to simulate durable reconnect failures because the stat
    information of the file changed.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 90d776cb18395ed804f0ab4fd13ef571fc0ad827
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Mar 20 14:28:43 2024 +0100

    smbd: add option "smbd:debug events" for tevent handling duration threshold warnings
    
    Can be used to enable printing an error message if tevent event handlers ran
    longer then three seconds. Also logs a message with a loglevel of 3 if there
    were no events at hall.
    
    Enabled by default with 'log level = 10' or
    'smbd profiling level = on'...
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 679e12aee2f0c283a6f9b9c6008c549a6ca9633e
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Mar 20 14:27:27 2024 +0100

    smbd: move trace_state variable behind tv variable
    
    Next commit adds timestamp variables to trace_state that want to be initialized
    with the current time, so moving behind tv we can then just reuse tv for that.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit d8613d7ee23c4e990285a387eb9ac2eeefff9749
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Apr 4 19:18:19 2024 +0200

    smbd: add option "smbd lease break:debug hung procs"
    
    By enabling this a process sending a lease break message to another process
    holding a lease will start watching that process and if that process didn't
    process the lease break within 10 seconds (cf server_id_watch_waited()), we log
    a kernel stack backtrace of that process.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit b45e78871aadca6ae33475bee890736838f44219
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Apr 5 12:15:28 2024 +0200

    smbd: log share_mode_watch_recv() errors as errors
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 7add7dbf1aee13b4d9ab70d1a5312c8ff30d9e00
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Apr 25 15:17:08 2024 +0200

    s3/lib: add option "serverid watch:debug script"
    
    This takes just PID and NODE:PID on a cluster.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 5c57e840527432c4b1a7ec94894939022a9e9622
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Apr 4 12:31:05 2024 +0200

    s3/lib: add option "serverid watch:debug = yes" to print kernel stack of hanging process
    
    We only do if sys_have_proc_fds() returns true, so it's most likely
    linux...
    
    Enabled by default with log level 10...
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit d76edcd48437715c7541b5b1e6a56245c25f460b
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Apr 25 15:24:57 2024 +0200

    s3/lib: add next helper variable in server_id_watch_*
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

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

Summary of changes:
 selftest/skip                                      |   1 +
 source3/lib/server_id_watch.c                      | 129 +++++++++++++++++-
 source3/modules/vfs_error_inject.c                 |  76 +++++++++++
 .../script/tests/test_durable_handle_reconnect.sh  |  18 +++
 source3/smbd/durable.c                             | 150 ++++++++-------------
 source3/smbd/open.c                                | 115 ++++++++++++++--
 source3/smbd/smb2_process.c                        |  72 +++++++++-
 source4/torture/smb2/durable_v2_open.c             | 118 ++++++++++++++++
 source4/torture/smb2/smb2.c                        |   2 +
 9 files changed, 565 insertions(+), 116 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/skip b/selftest/skip
index b5266bb16d8..c539243ab8e 100644
--- a/selftest/skip
+++ b/selftest/skip
@@ -147,3 +147,4 @@ bench # don't run benchmarks in our selftest
 ^samba4.smb2.tcon.*\(ad_dc_ntvfs\)$ # Ignore ad_dc_ntvfs since this is a new test
 ^samba4.smb2.mkdir.*\(ad_dc_ntvfs\)$ # Ignore ad_dc_ntvfs since this is a new test
 ^samba3.blackbox.open-eintr.*
+smb2.durable-v2-regressions # Only used in blackbox tests
diff --git a/source3/lib/server_id_watch.c b/source3/lib/server_id_watch.c
index f0189e0e896..77b1952f9eb 100644
--- a/source3/lib/server_id_watch.c
+++ b/source3/lib/server_id_watch.c
@@ -17,16 +17,19 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "replace.h"
-#include <tevent.h>
-#include <talloc.h>
+#include "includes.h"
 #include "serverid.h"
 #include "server_id_watch.h"
+#include "lib/util/server_id.h"
 #include "lib/util/tevent_unix.h"
+#include "lib/util/util_file.h"
 
 struct server_id_watch_state {
 	struct tevent_context *ev;
 	struct server_id pid;
+	struct timeval start;
+	struct timeval warn;
+	bool debug;
 };
 
 static void server_id_watch_waited(struct tevent_req *subreq);
@@ -37,6 +40,7 @@ struct tevent_req *server_id_watch_send(TALLOC_CTX *mem_ctx,
 {
 	struct tevent_req *req, *subreq;
 	struct server_id_watch_state *state;
+	struct timeval next;
 
 	req = tevent_req_create(mem_ctx, &state, struct server_id_watch_state);
 	if (req == NULL) {
@@ -44,14 +48,21 @@ struct tevent_req *server_id_watch_send(TALLOC_CTX *mem_ctx,
 	}
 	state->ev = ev;
 	state->pid = pid;
+	state->start = tevent_timeval_current();
+	state->warn = tevent_timeval_add(&state->start, 10, 0);
+
+	state->debug = lp_parm_bool(GLOBAL_SECTION_SNUM,
+				    "serverid watch",
+				    "debug",
+				    CHECK_DEBUGLVL(DBGLVL_DEBUG));
 
 	if (!serverid_exists(&state->pid)) {
 		tevent_req_done(req);
 		return tevent_req_post(req, ev);
 	}
 
-	subreq = tevent_wakeup_send(
-		state, ev, tevent_timeval_current_ofs(0, 500000));
+	next = tevent_timeval_add(&state->start, 0, 500000);
+	subreq = tevent_wakeup_send(state, ev, next);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
@@ -66,6 +77,8 @@ static void server_id_watch_waited(struct tevent_req *subreq)
 		subreq, struct tevent_req);
 	struct server_id_watch_state *state = tevent_req_data(
 		req, struct server_id_watch_state);
+	struct timeval now;
+	struct timeval next;
 	bool ok;
 
 	ok = tevent_wakeup_recv(subreq);
@@ -80,8 +93,110 @@ static void server_id_watch_waited(struct tevent_req *subreq)
 		return;
 	}
 
-	subreq = tevent_wakeup_send(
-		state, state->ev, tevent_timeval_current_ofs(0, 500000));
+	now = tevent_timeval_current();
+
+	if (!state->debug) {
+		goto next;
+	}
+
+	if (timeval_compare(&state->warn, &now) == -1) {
+		double duration = timeval_elapsed2(&state->start, &now);
+		const char *cmd = NULL;
+		char proc_path[64] = { 0, };
+		char *kstack = NULL;
+		struct server_id_buf buf;
+		const char *pid = server_id_str_buf(state->pid, &buf);
+		int ret;
+
+		state->warn = tevent_timeval_add(&now, 10, 0);
+
+		cmd = lp_parm_const_string(GLOBAL_SECTION_SNUM,
+					   "serverid watch",
+					   "debug script",
+					   NULL);
+		if (cmd != NULL) {
+			char *cmdstr = NULL;
+			char *output = NULL;
+			int fd;
+
+			/*
+			 * Note in a cluster setup pid will be
+			 * a NOTE:PID like '1:3978365'
+			 *
+			 * Without clustering it is just '3978365'
+			 */
+			cmdstr = talloc_asprintf(state, "%s %s", cmd, pid);
+			if (cmdstr == NULL) {
+				DBG_ERR("Process %s hanging for %f seconds?\n"
+					"talloc_asprintf failed\n",
+					pid, duration);
+				goto next;
+			}
+
+			become_root();
+			ret = smbrun(cmdstr, &fd, NULL);
+			unbecome_root();
+			if (ret != 0) {
+				DBG_ERR("Process %s hanging for %f seconds?\n"
+					"smbrun('%s') failed\n",
+					pid, duration, cmdstr);
+				TALLOC_FREE(cmdstr);
+				goto next;
+			}
+
+			output = fd_load(fd, NULL, 0, state);
+			close(fd);
+			if (output == NULL) {
+				DBG_ERR("Process %s hanging for %f seconds?\n"
+					"fd_load() of smbrun('%s') failed\n",
+					pid, duration, cmdstr);
+				TALLOC_FREE(cmdstr);
+				goto next;
+			}
+			DBG_ERR("Process %s hanging for %f seconds?\n"
+				"%s returned:\n%s",
+				pid, duration, cmdstr, output);
+			TALLOC_FREE(cmdstr);
+			TALLOC_FREE(output);
+			goto next;
+		}
+
+		if (!procid_is_local(&state->pid) || !sys_have_proc_fds()) {
+			DBG_ERR("Process %s hanging for %f seconds?\n",
+				pid, duration);
+			goto next;
+		}
+
+		ret = snprintf(proc_path,
+			       ARRAY_SIZE(proc_path),
+			       "/proc/%" PRIu64 "/stack",
+			       state->pid.pid);
+		if (ret < 0) {
+			DBG_ERR("Process %s hanging for %f seconds?\n"
+				"snprintf failed\n",
+				pid, duration);
+			goto next;
+		}
+
+		become_root();
+		kstack = file_load(proc_path, NULL, 0, state);
+		unbecome_root();
+		if (kstack == NULL) {
+			DBG_ERR("Process %s hanging for %f seconds?\n"
+				"file_load [%s] failed\n",
+				pid, duration, proc_path);
+			goto next;
+		}
+
+		DBG_ERR("Process %s hanging for %f seconds?\n"
+			"%s:\n%s",
+			pid, duration, proc_path, kstack);
+		TALLOC_FREE(kstack);
+	}
+
+next:
+	next = tevent_timeval_add(&now, 0, 500000);
+	subreq = tevent_wakeup_send(state, state->ev, next);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
 	}
diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c
index 529504fd8d5..dcf0de0a2d9 100644
--- a/source3/modules/vfs_error_inject.c
+++ b/source3/modules/vfs_error_inject.c
@@ -19,6 +19,7 @@
 
 #include "includes.h"
 #include "smbd/smbd.h"
+#include "librpc/gen_ndr/ndr_open_files.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
@@ -204,11 +205,86 @@ static int vfs_error_inject_unlinkat(struct vfs_handle_struct *handle,
 	return -1;
 }
 
+static NTSTATUS vfs_error_inject_durable_reconnect(struct vfs_handle_struct *handle,
+						   struct smb_request *smb1req,
+						   struct smbXsrv_open *op,
+						   const DATA_BLOB old_cookie,
+						   TALLOC_CTX *mem_ctx,
+						   struct files_struct **fsp,
+						   DATA_BLOB *new_cookie)
+{
+	const char *vfs_func = "durable_reconnect";
+	const char *err_str = NULL;
+	NTSTATUS status;
+	enum ndr_err_code ndr_err;
+	struct vfs_default_durable_cookie cookie;
+	DATA_BLOB modified_cookie = data_blob_null;
+
+	err_str = lp_parm_const_string(SNUM(handle->conn),
+				       "error_inject",
+				       vfs_func,
+				       NULL);
+	if (err_str == NULL) {
+		return SMB_VFS_NEXT_DURABLE_RECONNECT(handle,
+						      smb1req,
+						      op,
+						      old_cookie,
+						      mem_ctx,
+						      fsp,
+						      new_cookie);
+	}
+
+	ndr_err = ndr_pull_struct_blob(&old_cookie, talloc_tos(), &cookie,
+			(ndr_pull_flags_fn_t)ndr_pull_vfs_default_durable_cookie);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		status = ndr_map_error2ntstatus(ndr_err);
+		return status;
+	}
+
+	if (strcmp(cookie.magic, VFS_DEFAULT_DURABLE_COOKIE_MAGIC) != 0) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (cookie.version != VFS_DEFAULT_DURABLE_COOKIE_VERSION) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (strequal(err_str, "st_ex_nlink")) {
+		cookie.stat_info.st_ex_nlink += 1;
+	} else {
+		DBG_ERR("Unknown error inject %s requested "
+			"for vfs function %s\n", err_str, vfs_func);
+		return SMB_VFS_NEXT_DURABLE_RECONNECT(handle,
+						      smb1req,
+						      op,
+						      old_cookie,
+						      mem_ctx,
+						      fsp,
+						      new_cookie);
+	}
+
+	ndr_err = ndr_push_struct_blob(&modified_cookie, talloc_tos(), &cookie,
+			(ndr_push_flags_fn_t)ndr_push_vfs_default_durable_cookie);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		status = ndr_map_error2ntstatus(ndr_err);
+		return status;
+	}
+
+	return SMB_VFS_NEXT_DURABLE_RECONNECT(handle,
+					      smb1req,
+					      op,
+					      modified_cookie,
+					      mem_ctx,
+					      fsp,
+					      new_cookie);
+}
+
 static struct vfs_fn_pointers vfs_error_inject_fns = {
 	.chdir_fn = vfs_error_inject_chdir,
 	.pwrite_fn = vfs_error_inject_pwrite,
 	.openat_fn = vfs_error_inject_openat,
 	.unlinkat_fn = vfs_error_inject_unlinkat,
+	.durable_reconnect_fn = vfs_error_inject_durable_reconnect,
 };
 
 static_decl_vfs;
diff --git a/source3/script/tests/test_durable_handle_reconnect.sh b/source3/script/tests/test_durable_handle_reconnect.sh
index 0ab32974824..fd5c156956f 100755
--- a/source3/script/tests/test_durable_handle_reconnect.sh
+++ b/source3/script/tests/test_durable_handle_reconnect.sh
@@ -33,4 +33,22 @@ testit "durable_v2_delay.durable_v2_reconnect_delay_msec" $VALGRIND \
 
 rm $delay_inject_conf
 
+error_inject_conf=$(dirname $SMB_CONF_PATH)/error_inject.conf
+
+cat > $error_inject_conf << _EOF
+	kernel share modes = no
+	kernel oplocks = no
+	posix locking = no
+	error_inject:durable_reconnect = st_ex_nlink
+_EOF
+
+testit "durable-v2-regressions.durable_v2_reconnect_bug15624" \
+	$VALGRIND $BINDIR/smbtorture //$SERVER_IP/error_inject \
+	-U$USERNAME%$PASSWORD \
+	--option=torture:bug15624=yes \
+	smb2.durable-v2-regressions.durable_v2_reconnect_bug15624 ||
+	failed=$(expr $failed + 1)
+
+rm $error_inject_conf
+
 testok $0 $failed
diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c
index 5f55ff658bb..dfb87dd3775 100644
--- a/source3/smbd/durable.c
+++ b/source3/smbd/durable.c
@@ -538,6 +538,7 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 	enum ndr_err_code ndr_err;
 	struct vfs_default_durable_cookie cookie;
 	DATA_BLOB new_cookie_blob = data_blob_null;
+	bool have_share_mode_entry = false;
 
 	*result = NULL;
 	*new_cookie = data_blob_null;
@@ -624,22 +625,22 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 	ok = share_mode_forall_entries(lck, durable_reconnect_fn, &e);
 	if (!ok) {
 		DBG_WARNING("share_mode_forall_entries failed\n");
-		TALLOC_FREE(lck);
-		return NT_STATUS_INTERNAL_DB_ERROR;
+		status = NT_STATUS_INTERNAL_DB_ERROR;
+		goto fail;
 	}
 
 	if (e.pid.pid == 0) {
 		DBG_WARNING("Did not find a unique valid share mode entry\n");
-		TALLOC_FREE(lck);
-		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+		status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+		goto fail;
 	}
 
 	if (!server_id_is_disconnected(&e.pid)) {
 		DEBUG(5, ("vfs_default_durable_reconnect: denying durable "
 			  "reconnect for handle that was not marked "
 			  "disconnected (e.g. smbd or cluster node died)\n"));
-		TALLOC_FREE(lck);
-		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+		status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+		goto fail;
 	}
 
 	if (e.share_file_id != op->global->open_persistent_id) {
@@ -648,8 +649,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 			 "(e.g. another client had opened the file)\n",
 			 e.share_file_id,
 			 op->global->open_persistent_id);
-		TALLOC_FREE(lck);
-		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+		status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+		goto fail;
 	}
 
 	if ((e.access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) &&
@@ -658,8 +659,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 		DEBUG(5, ("vfs_default_durable_reconnect: denying durable "
 			  "share[%s] is not writeable anymore\n",
 			  lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
-		TALLOC_FREE(lck);
-		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+		status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+		goto fail;
 	}
 
 	/*
@@ -670,8 +671,7 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("vfs_default_durable_reconnect: failed to create "
 			  "new fsp: %s\n", nt_errstr(status)));
-		TALLOC_FREE(lck);
-		return status;
+		goto fail;
 	}
 
 	fh_set_private_options(fsp->fh, e.private_options);
@@ -714,9 +714,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 		 */
 		if (!GUID_equal(fsp_client_guid(fsp),
 				&e.client_guid)) {
-			TALLOC_FREE(lck);
-			file_free(smb1req, fsp);
-			return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+			status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+			goto fail;
 		}
 
 		status = leases_db_get(
@@ -730,9 +729,7 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 			&lease_version, /* lease_version */
 			&epoch); /* epoch */
 		if (!NT_STATUS_IS_OK(status)) {
-			TALLOC_FREE(lck);
-			file_free(smb1req, fsp);
-			return status;
+			goto fail;
 		}
 
 		fsp->lease = find_fsp_lease(
@@ -742,9 +739,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 			lease_version,
 			epoch);
 		if (fsp->lease == NULL) {
-			TALLOC_FREE(lck);
-			file_free(smb1req, fsp);
-			return NT_STATUS_NO_MEMORY;
+			status = NT_STATUS_NO_MEMORY;
+			goto fail;
 		}
 	}
 
@@ -760,12 +756,10 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 
 	status = fsp_set_smb_fname(fsp, smb_fname);
 	if (!NT_STATUS_IS_OK(status)) {
-		TALLOC_FREE(lck);
-		file_free(smb1req, fsp);
 		DEBUG(0, ("vfs_default_durable_reconnect: "
 			  "fsp_set_smb_fname failed: %s\n",
 			  nt_errstr(status)));
-		return status;
+		goto fail;
 	}
 
 	op->compat = fsp;
@@ -780,12 +774,10 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 		fh_get_gen_id(fsp->fh));
 	if (!ok) {
 		DBG_DEBUG("Could not set new share_mode_entry values\n");
-		TALLOC_FREE(lck);
-		op->compat = NULL;
-		fsp->op = NULL;
-		file_free(smb1req, fsp);
-		return NT_STATUS_INTERNAL_ERROR;
+		status = NT_STATUS_INTERNAL_ERROR;
+		goto fail;
 	}
+	have_share_mode_entry = true;
 
 	ok = brl_reconnect_disconnected(fsp);
 	if (!ok) {
@@ -793,11 +785,7 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 		DEBUG(1, ("vfs_default_durable_reconnect: "
 			  "failed to reopen brlocks: %s\n",
 			  nt_errstr(status)));
-		TALLOC_FREE(lck);
-		op->compat = NULL;
-		fsp->op = NULL;
-		file_free(smb1req, fsp);
-		return status;
+		goto fail;
 	}
 
 	/*
@@ -813,13 +801,9 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 
 	status = fd_openat(conn->cwd_fsp, fsp->fsp_name, fsp, &how);
 	if (!NT_STATUS_IS_OK(status)) {
-		TALLOC_FREE(lck);
 		DEBUG(1, ("vfs_default_durable_reconnect: failed to open "
 			  "file: %s\n", nt_errstr(status)));
-		op->compat = NULL;
-		fsp->op = NULL;
-		file_free(smb1req, fsp);
-		return status;
+		goto fail;
 	}
 
 	/*
@@ -833,48 +817,22 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 
 	ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
 	if (ret == -1) {
-		NTSTATUS close_status;
 		status = map_nt_error_from_unix_common(errno);
 		DEBUG(1, ("Unable to fstat stream: %s => %s\n",
 			  smb_fname_str_dbg(smb_fname),
 			  nt_errstr(status)));
-		close_status = fd_close(fsp);
-		if (!NT_STATUS_IS_OK(close_status)) {
-			DBG_ERR("fd_close failed (%s) - leaking file "
-				"descriptor\n", nt_errstr(close_status));
-		}
-		TALLOC_FREE(lck);
-		op->compat = NULL;
-		fsp->op = NULL;
-		file_free(smb1req, fsp);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list