From a443003cbe91b763af2719a80663bb007e851064 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 19 Oct 2012 15:53:50 +0200 Subject: [PATCH 1/4] s3:smbd/durable: remove an extra blank line from vfs_default_durable_reconnect() Pair-programmed-with: Stefan Metzmacher Signed-off-by: Michael Adam Signed-off-by: Stefan Metzmacher (cherry picked from commit 660e90d39174fbfea0e93f40adfe03fefb86916f) Signed-off-by: Stefan Metzmacher --- source3/smbd/durable.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c index 348135c..e4393a9 100644 --- a/source3/smbd/durable.c +++ b/source3/smbd/durable.c @@ -532,7 +532,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)) { -- 1.7.9.5 From 9c1bf9f76acc3f56b3e4efbd904aa49ef9a00814 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 19 Oct 2012 15:57:24 +0200 Subject: [PATCH 2/4] s3:open_files.idl: add stat-info to vfs_default_durable_cookie. Pair-programmed-with: Stefan Metzmacher Signed-off-by: Michael Adam Signed-off-by: Stefan Metzmacher (cherry picked from commit a6726f9023c899415441a619473ea9a7819d7c36) Signed-off-by: Stefan Metzmacher --- source3/librpc/idl/open_files.idl | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) 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; } -- 1.7.9.5 From 7eb22c19e3288ac80d13f9bff03344f55d9a2807 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 19 Oct 2012 16:00:05 +0200 Subject: [PATCH 3/4] 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 Signed-off-by: Michael Adam Signed-off-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Fri Oct 19 18:56:19 CEST 2012 on sn-devel-104 (cherry picked from commit 7d05ff77264cf48d1ee82ca19c8c7e6951e64cf5) Signed-off-by: Stefan Metzmacher --- source3/smbd/durable.c | 456 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 456 insertions(+) diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c index e4393a9..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); @@ -561,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): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + fsp_str_dbg(fsp), + "st_ex_mask", + (unsigned long long)cookie.stat_info.st_ex_mask, + (unsigned long long)fsp->fsp_name->st.st_ex_mask)); + 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.vfs_private != fsp->fsp_name->st.vfs_private) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + fsp_str_dbg(fsp), + "vfs_private", + (unsigned long long)cookie.stat_info.vfs_private, + (unsigned long long)fsp->fsp_name->st.vfs_private)); + 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; + } + status = set_file_oplock(fsp, e->op_type); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("vfs_default_durable_reconnect failed to set oplock " -- 1.7.9.5 From 4d6029d938c400454cb4eac83bd5e30e964085a7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 23 Oct 2012 13:00:02 +0200 Subject: [PATCH 4/4] s3:smbd:durable: factor stat checks out into vfs_default_durable_reconnect_check_stat() This makes vfs_default_durable_reconnect() simpler to read and it reduces code duplication in the failure case handling. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Thu Oct 25 23:03:13 CEST 2012 on sn-devel-104 (cherry picked from commit 52ace6767fddb389e3393c4b19685e59782c6a90) --- source3/smbd/durable.c | 653 +++++++++++++++++++----------------------------- 1 file changed, 261 insertions(+), 392 deletions(-) diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c index 4c6ff67..5d276f3 100644 --- a/source3/smbd/durable.c +++ b/source3/smbd/durable.c @@ -298,6 +298,263 @@ NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp, return NT_STATUS_OK; } + +/** + * Check whether a cookie-stored struct info is the same + * as a given SMB_STRUCT_STAT, as coming with the fsp. + */ +static bool vfs_default_durable_reconnect_check_stat( + struct vfs_default_durable_stat *cookie_st, + SMB_STRUCT_STAT *fsp_st, + const char *name) +{ + int ret; + + if (cookie_st->st_ex_dev != fsp_st->st_ex_dev) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_dev", + (unsigned long long)cookie_st->st_ex_dev, + (unsigned long long)fsp_st->st_ex_dev)); + return false; + } + + if (cookie_st->st_ex_ino != fsp_st->st_ex_ino) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_ino", + (unsigned long long)cookie_st->st_ex_ino, + (unsigned long long)fsp_st->st_ex_ino)); + return false; + } + + if (cookie_st->st_ex_mode != fsp_st->st_ex_mode) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_mode", + (unsigned long long)cookie_st->st_ex_mode, + (unsigned long long)fsp_st->st_ex_mode)); + return false; + } + + if (cookie_st->st_ex_nlink != fsp_st->st_ex_nlink) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_nlink", + (unsigned long long)cookie_st->st_ex_nlink, + (unsigned long long)fsp_st->st_ex_nlink)); + return false; + } + + if (cookie_st->st_ex_uid != fsp_st->st_ex_uid) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_uid", + (unsigned long long)cookie_st->st_ex_uid, + (unsigned long long)fsp_st->st_ex_uid)); + return false; + } + + if (cookie_st->st_ex_gid != fsp_st->st_ex_gid) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_gid", + (unsigned long long)cookie_st->st_ex_gid, + (unsigned long long)fsp_st->st_ex_gid)); + return false; + } + + if (cookie_st->st_ex_rdev != fsp_st->st_ex_rdev) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_rdev", + (unsigned long long)cookie_st->st_ex_rdev, + (unsigned long long)fsp_st->st_ex_rdev)); + return false; + } + + if (cookie_st->st_ex_size != fsp_st->st_ex_size) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_size", + (unsigned long long)cookie_st->st_ex_size, + (unsigned long long)fsp_st->st_ex_size)); + return false; + } + + ret = timespec_compare(&cookie_st->st_ex_atime, + &fsp_st->st_ex_atime); + if (ret != 0) { + struct timeval tc, ts; + tc = convert_timespec_to_timeval(cookie_st->st_ex_atime); + ts = convert_timespec_to_timeval(fsp_st->st_ex_atime); + + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:'%s' != stat:'%s', " + "denying durable reconnect\n", + name, + "st_ex_atime", + timeval_string(talloc_tos(), &tc, true), + timeval_string(talloc_tos(), &ts, true))); + return false; + } + + ret = timespec_compare(&cookie_st->st_ex_mtime, + &fsp_st->st_ex_mtime); + if (ret != 0) { + struct timeval tc, ts; + tc = convert_timespec_to_timeval(cookie_st->st_ex_mtime); + ts = convert_timespec_to_timeval(fsp_st->st_ex_mtime); + + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:'%s' != stat:'%s', " + "denying durable reconnect\n", + name, + "st_ex_mtime", + timeval_string(talloc_tos(), &tc, true), + timeval_string(talloc_tos(), &ts, true))); + return false; + } + + ret = timespec_compare(&cookie_st->st_ex_ctime, + &fsp_st->st_ex_ctime); + if (ret != 0) { + struct timeval tc, ts; + tc = convert_timespec_to_timeval(cookie_st->st_ex_ctime); + ts = convert_timespec_to_timeval(fsp_st->st_ex_ctime); + + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:'%s' != stat:'%s', " + "denying durable reconnect\n", + name, + "st_ex_ctime", + timeval_string(talloc_tos(), &tc, true), + timeval_string(talloc_tos(), &ts, true))); + return false; + } + + ret = timespec_compare(&cookie_st->st_ex_btime, + &fsp_st->st_ex_btime); + if (ret != 0) { + struct timeval tc, ts; + tc = convert_timespec_to_timeval(cookie_st->st_ex_btime); + ts = convert_timespec_to_timeval(fsp_st->st_ex_btime); + + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:'%s' != stat:'%s', " + "denying durable reconnect\n", + name, + "st_ex_btime", + timeval_string(talloc_tos(), &tc, true), + timeval_string(talloc_tos(), &ts, true))); + return false; + } + + if (cookie_st->st_ex_calculated_birthtime != + fsp_st->st_ex_calculated_birthtime) + { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_calculated_birthtime", + (unsigned long long)cookie_st->st_ex_calculated_birthtime, + (unsigned long long)fsp_st->st_ex_calculated_birthtime)); + return false; + } + + if (cookie_st->st_ex_blksize != fsp_st->st_ex_blksize) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_blksize", + (unsigned long long)cookie_st->st_ex_blksize, + (unsigned long long)fsp_st->st_ex_blksize)); + return false; + } + + if (cookie_st->st_ex_blocks != fsp_st->st_ex_blocks) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_blocks", + (unsigned long long)cookie_st->st_ex_blocks, + (unsigned long long)fsp_st->st_ex_blocks)); + return false; + } + + if (cookie_st->st_ex_flags != fsp_st->st_ex_flags) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_flags", + (unsigned long long)cookie_st->st_ex_flags, + (unsigned long long)fsp_st->st_ex_flags)); + return false; + } + + if (cookie_st->st_ex_mask != fsp_st->st_ex_mask) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "st_ex_mask", + (unsigned long long)cookie_st->st_ex_mask, + (unsigned long long)fsp_st->st_ex_mask)); + return false; + } + + if (cookie_st->vfs_private != fsp_st->vfs_private) { + DEBUG(1, ("vfs_default_durable_reconnect (%s): " + "stat_ex.%s differs: " + "cookie:%llu != stat:%llu, " + "denying durable reconnect\n", + name, + "vfs_private", + (unsigned long long)cookie_st->vfs_private, + (unsigned long long)fsp_st->vfs_private)); + return false; + } + + return true; +} + NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, struct smb_request *smb1req, struct smbXsrv_open *op, @@ -613,398 +870,10 @@ 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): " - "stat_ex.%s differs: " - "cookie:%llu != stat:%llu, " - "denying durable reconnect\n", - fsp_str_dbg(fsp), - "st_ex_mask", - (unsigned long long)cookie.stat_info.st_ex_mask, - (unsigned long long)fsp->fsp_name->st.st_ex_mask)); - 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.vfs_private != fsp->fsp_name->st.vfs_private) { - DEBUG(1, ("vfs_default_durable_reconnect (%s): " - "stat_ex.%s differs: " - "cookie:%llu != stat:%llu, " - "denying durable reconnect\n", - fsp_str_dbg(fsp), - "vfs_private", - (unsigned long long)cookie.stat_info.vfs_private, - (unsigned long long)fsp->fsp_name->st.vfs_private)); + ok = vfs_default_durable_reconnect_check_stat(&cookie.stat_info, + &fsp->fsp_name->st, + fsp_str_dbg(fsp)); + if (!ok) { ret = SMB_VFS_CLOSE(fsp); if (ret == -1) { DEBUG(0, ("vfs_default_durable_reconnect: " -- 1.7.9.5