[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Fri Oct 19 10:57:03 MDT 2012


The branch, master has been updated
       via  7d05ff7 s3:smbd:durable: store stat info for disconnected durables and check at reconnect.
       via  a6726f9 s3:open_files.idl: add stat-info to vfs_default_durable_cookie.
       via  660e90d s3:smbd/durable: remove an extra blank line from vfs_default_durable_reconnect()
      from  24d225f s3:smbd/durable: add write_time specific stuff to vfs_default_durable_cookie

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


- Log -----------------------------------------------------------------
commit 7d05ff77264cf48d1ee82ca19c8c7e6951e64cf5
Author: Michael Adam <obnox at samba.org>
Date:   Fri Oct 19 16:00:05 2012 +0200

    s3:smbd:durable: store stat info for disconnected durables and check at reconnect.
    
    At durable reconnect, we check the stat info stored in the cookie against the
    current stat data from the file we just opened.  If any detail differs, we deny
    the durable reconnect, because in that case it is very likely that someone
    opened the file while the handle was disconnected, which has to be interpreted
    as an oplock break.
    
    Pair-programmed-with: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Fri Oct 19 18:56:19 CEST 2012 on sn-devel-104

commit a6726f9023c899415441a619473ea9a7819d7c36
Author: Michael Adam <obnox at samba.org>
Date:   Fri Oct 19 15:57:24 2012 +0200

    s3:open_files.idl: add stat-info to vfs_default_durable_cookie.
    
    Pair-programmed-with: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit 660e90d39174fbfea0e93f40adfe03fefb86916f
Author: Michael Adam <obnox at samba.org>
Date:   Fri Oct 19 15:53:50 2012 +0200

    s3:smbd/durable: remove an extra blank line from vfs_default_durable_reconnect()
    
    Pair-programmed-with: Stefan Metzmacher <metze at samba.org>
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

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

Summary of changes:
 source3/librpc/idl/open_files.idl |   23 ++
 source3/smbd/durable.c            |  457 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 479 insertions(+), 1 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/librpc/idl/open_files.idl b/source3/librpc/idl/open_files.idl
index 0dd9859..fa87bc7 100644
--- a/source3/librpc/idl/open_files.idl
+++ b/source3/librpc/idl/open_files.idl
@@ -52,6 +52,28 @@ interface open_files
 		"VFS_DEFAULT_DURABLE_COOKIE_MAGIC                ";
 	const uint32 VFS_DEFAULT_DURABLE_COOKIE_VERSION = 0;
 
+	/* this corresponds to struct stat_ex (SMB_STRUCT_STAT) */
+	typedef struct {
+		hyper		st_ex_dev;
+		hyper		st_ex_ino;
+		hyper		st_ex_mode;
+		hyper		st_ex_nlink;
+		hyper		st_ex_uid;
+		hyper		st_ex_gid;
+		hyper		st_ex_rdev;
+		hyper		st_ex_size;
+		timespec	st_ex_atime;
+		timespec	st_ex_mtime;
+		timespec	st_ex_ctime;
+		timespec	st_ex_btime;
+		boolean8	st_ex_calculated_birthtime;
+		hyper		st_ex_blksize;
+		hyper		st_ex_blocks;
+		uint32		st_ex_flags;
+		uint32		st_ex_mask;
+		hyper		vfs_private;
+	} vfs_default_durable_stat;
+
 	typedef [public] struct {
 		[value(VFS_DEFAULT_DURABLE_COOKIE_MAGIC),charset(DOS)] uint8 magic[0x30];
 		[value(VFS_DEFAULT_DURABLE_COOKIE_VERSION)] uint32 version;
@@ -65,5 +87,6 @@ interface open_files
 		boolean8 update_write_time_on_close;
 		boolean8 write_time_forced;
 		timespec close_write_time;
+		vfs_default_durable_stat stat_info;
 	} vfs_default_durable_cookie;
 }
diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c
index 348135c..4c6ff67 100644
--- a/source3/smbd/durable.c
+++ b/source3/smbd/durable.c
@@ -104,6 +104,25 @@ NTSTATUS vfs_default_durable_cookie(struct files_struct *fsp,
 	cookie.write_time_forced = fsp->write_time_forced;
 	cookie.close_write_time = fsp->close_write_time;
 
+	cookie.stat_info.st_ex_dev = fsp->fsp_name->st.st_ex_dev;
+	cookie.stat_info.st_ex_ino = fsp->fsp_name->st.st_ex_ino;
+	cookie.stat_info.st_ex_mode = fsp->fsp_name->st.st_ex_mode;
+	cookie.stat_info.st_ex_nlink = fsp->fsp_name->st.st_ex_nlink;
+	cookie.stat_info.st_ex_uid = fsp->fsp_name->st.st_ex_uid;
+	cookie.stat_info.st_ex_gid = fsp->fsp_name->st.st_ex_gid;
+	cookie.stat_info.st_ex_rdev = fsp->fsp_name->st.st_ex_rdev;
+	cookie.stat_info.st_ex_size = fsp->fsp_name->st.st_ex_size;
+	cookie.stat_info.st_ex_atime = fsp->fsp_name->st.st_ex_atime;
+	cookie.stat_info.st_ex_mtime = fsp->fsp_name->st.st_ex_mtime;
+	cookie.stat_info.st_ex_ctime = fsp->fsp_name->st.st_ex_ctime;
+	cookie.stat_info.st_ex_btime = fsp->fsp_name->st.st_ex_btime;
+	cookie.stat_info.st_ex_calculated_birthtime = fsp->fsp_name->st.st_ex_calculated_birthtime;
+	cookie.stat_info.st_ex_blksize = fsp->fsp_name->st.st_ex_blksize;
+	cookie.stat_info.st_ex_blocks = fsp->fsp_name->st.st_ex_blocks;
+	cookie.stat_info.st_ex_flags = fsp->fsp_name->st.st_ex_flags;
+	cookie.stat_info.st_ex_mask = fsp->fsp_name->st.st_ex_mask;
+	cookie.stat_info.vfs_private = fsp->fsp_name->st.vfs_private;
+
 	ndr_err = ndr_push_struct_blob(cookie_blob, mem_ctx, &cookie,
 			(ndr_push_flags_fn_t)ndr_push_vfs_default_durable_cookie);
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -226,6 +245,11 @@ NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp,
 	}
 	TALLOC_FREE(lck);
 
+	status = vfs_stat_fsp(fsp);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	ZERO_STRUCT(cookie);
 	cookie.allow_reconnect = true;
 	cookie.id = fsp->file_id;
@@ -238,6 +262,25 @@ NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp,
 	cookie.write_time_forced = fsp->write_time_forced;
 	cookie.close_write_time = fsp->close_write_time;
 
+	cookie.stat_info.st_ex_dev = fsp->fsp_name->st.st_ex_dev;
+	cookie.stat_info.st_ex_ino = fsp->fsp_name->st.st_ex_ino;
+	cookie.stat_info.st_ex_mode = fsp->fsp_name->st.st_ex_mode;
+	cookie.stat_info.st_ex_nlink = fsp->fsp_name->st.st_ex_nlink;
+	cookie.stat_info.st_ex_uid = fsp->fsp_name->st.st_ex_uid;
+	cookie.stat_info.st_ex_gid = fsp->fsp_name->st.st_ex_gid;
+	cookie.stat_info.st_ex_rdev = fsp->fsp_name->st.st_ex_rdev;
+	cookie.stat_info.st_ex_size = fsp->fsp_name->st.st_ex_size;
+	cookie.stat_info.st_ex_atime = fsp->fsp_name->st.st_ex_atime;
+	cookie.stat_info.st_ex_mtime = fsp->fsp_name->st.st_ex_mtime;
+	cookie.stat_info.st_ex_ctime = fsp->fsp_name->st.st_ex_ctime;
+	cookie.stat_info.st_ex_btime = fsp->fsp_name->st.st_ex_btime;
+	cookie.stat_info.st_ex_calculated_birthtime = fsp->fsp_name->st.st_ex_calculated_birthtime;
+	cookie.stat_info.st_ex_blksize = fsp->fsp_name->st.st_ex_blksize;
+	cookie.stat_info.st_ex_blocks = fsp->fsp_name->st.st_ex_blocks;
+	cookie.stat_info.st_ex_flags = fsp->fsp_name->st.st_ex_flags;
+	cookie.stat_info.st_ex_mask = fsp->fsp_name->st.st_ex_mask;
+	cookie.stat_info.vfs_private = fsp->fsp_name->st.vfs_private;
+
 	ndr_err = ndr_push_struct_blob(&new_cookie_blob, mem_ctx, &cookie,
 			(ndr_push_flags_fn_t)ndr_push_vfs_default_durable_cookie);
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -516,6 +559,15 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 		return status;
 	}
 
+	/*
+	 * We now check the stat info stored in the cookie against
+	 * the current stat data from the file we just opened.
+	 * If any detail differs, we deny the durable reconnect,
+	 * because in that case it is very likely that someone
+	 * opened the file while the handle was disconnected,
+	 * which has to be interpreted as an oplock break.
+	 */
+
 	ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
 	if (ret == -1) {
 		status = map_nt_error_from_unix_common(errno);
@@ -532,7 +584,6 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 		op->compat = NULL;
 		fsp_free(fsp);
 		return status;
-
 	}
 
 	if (!S_ISREG(fsp->fsp_name->st.st_ex_mode)) {
@@ -562,6 +613,410 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
 		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 	}
 
+	if (cookie.stat_info.st_ex_dev != fsp->fsp_name->st.st_ex_dev) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_dev",
+			  (unsigned long long)cookie.stat_info.st_ex_dev,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_dev));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_ino != fsp->fsp_name->st.st_ex_ino) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_ino",
+			  (unsigned long long)cookie.stat_info.st_ex_ino,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_ino));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_mode != fsp->fsp_name->st.st_ex_mode) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_mode",
+			  (unsigned long long)cookie.stat_info.st_ex_mode,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_mode));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_nlink != fsp->fsp_name->st.st_ex_nlink) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_nlink",
+			  (unsigned long long)cookie.stat_info.st_ex_nlink,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_nlink));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_uid != fsp->fsp_name->st.st_ex_uid) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_uid",
+			  (unsigned long long)cookie.stat_info.st_ex_uid,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_uid));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_gid != fsp->fsp_name->st.st_ex_gid) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_gid",
+			  (unsigned long long)cookie.stat_info.st_ex_gid,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_gid));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_rdev != fsp->fsp_name->st.st_ex_rdev) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_rdev",
+			  (unsigned long long)cookie.stat_info.st_ex_rdev,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_rdev));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_size != fsp->fsp_name->st.st_ex_size) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_size",
+			  (unsigned long long)cookie.stat_info.st_ex_size,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_size));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	ret = timespec_compare(&cookie.stat_info.st_ex_atime,
+			       &fsp->fsp_name->st.st_ex_atime);
+	if (ret != 0) {
+		struct timeval tc, ts;
+		tc = convert_timespec_to_timeval(cookie.stat_info.st_ex_atime);
+		ts = convert_timespec_to_timeval(fsp->fsp_name->st.st_ex_atime);
+
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:'%s' != stat:'%s', "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_atime",
+			  timeval_string(talloc_tos(), &tc, true),
+			  timeval_string(talloc_tos(), &ts, true)));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	ret = timespec_compare(&cookie.stat_info.st_ex_mtime,
+			       &fsp->fsp_name->st.st_ex_mtime);
+	if (ret != 0) {
+		struct timeval tc, ts;
+		tc = convert_timespec_to_timeval(cookie.stat_info.st_ex_mtime);
+		ts = convert_timespec_to_timeval(fsp->fsp_name->st.st_ex_mtime);
+
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:'%s' != stat:'%s', "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_mtime",
+			  timeval_string(talloc_tos(), &tc, true),
+			  timeval_string(talloc_tos(), &ts, true)));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	ret = timespec_compare(&cookie.stat_info.st_ex_ctime,
+			       &fsp->fsp_name->st.st_ex_ctime);
+	if (ret != 0) {
+		struct timeval tc, ts;
+		tc = convert_timespec_to_timeval(cookie.stat_info.st_ex_ctime);
+		ts = convert_timespec_to_timeval(fsp->fsp_name->st.st_ex_ctime);
+
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:'%s' != stat:'%s', "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_ctime",
+			  timeval_string(talloc_tos(), &tc, true),
+			  timeval_string(talloc_tos(), &ts, true)));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	ret = timespec_compare(&cookie.stat_info.st_ex_btime,
+			       &fsp->fsp_name->st.st_ex_btime);
+	if (ret != 0) {
+		struct timeval tc, ts;
+		tc = convert_timespec_to_timeval(cookie.stat_info.st_ex_btime);
+		ts = convert_timespec_to_timeval(fsp->fsp_name->st.st_ex_btime);
+
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:'%s' != stat:'%s', "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_btime",
+			  timeval_string(talloc_tos(), &tc, true),
+			  timeval_string(talloc_tos(), &ts, true)));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_calculated_birthtime !=
+	    fsp->fsp_name->st.st_ex_calculated_birthtime)
+	{
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_calculated_birthtime",
+			  (unsigned long long)cookie.stat_info.st_ex_calculated_birthtime,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_calculated_birthtime));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_blksize != fsp->fsp_name->st.st_ex_blksize) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_blksize",
+			  (unsigned long long)cookie.stat_info.st_ex_blksize,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_blksize));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_blocks != fsp->fsp_name->st.st_ex_blocks) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_blocks",
+			  (unsigned long long)cookie.stat_info.st_ex_blocks,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_blocks));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_flags != fsp->fsp_name->st.st_ex_flags) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "
+			  "stat_ex.%s differs: "
+			  "cookie:%llu != stat:%llu, "
+			  "denying durable reconnect\n",
+			  fsp_str_dbg(fsp),
+			  "st_ex_flags",
+			  (unsigned long long)cookie.stat_info.st_ex_flags,
+			  (unsigned long long)fsp->fsp_name->st.st_ex_flags));
+		ret = SMB_VFS_CLOSE(fsp);
+		if (ret == -1) {
+			DEBUG(0, ("vfs_default_durable_reconnect: "
+				  "SMB_VFS_CLOSE failed (%s) - leaking file "
+				  "descriptor\n", strerror(errno)));
+		}
+		TALLOC_FREE(lck);
+		op->compat = NULL;
+		fsp_free(fsp);
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
+
+	if (cookie.stat_info.st_ex_mask != fsp->fsp_name->st.st_ex_mask) {
+		DEBUG(1, ("vfs_default_durable_reconnect (%s): "


-- 
Samba Shared Repository


More information about the samba-cvs mailing list