#include "includes.h"
#include "system/filesys.h"
+#include "lib/util/server_id.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "libcli/security/security.h"
#include "librpc/gen_ndr/ndr_open_files.h"
#include "serverid.h"
#include "fake_file.h"
+#include "locking/leases_db.h"
NTSTATUS vfs_default_durable_cookie(struct files_struct *fsp,
TALLOC_CTX *mem_ctx,
return NT_STATUS_NOT_SUPPORTED;
}
- if (fsp->is_directory) {
+ if (fsp->fsp_flags.is_directory) {
return NT_STATUS_NOT_SUPPORTED;
}
cookie.base_name = fsp->fsp_name->base_name;
cookie.initial_allocation_size = fsp->initial_allocation_size;
cookie.position_information = fsp->fh->position_information;
- cookie.update_write_time_triggered = fsp->update_write_time_triggered;
- cookie.update_write_time_on_close = fsp->update_write_time_on_close;
- cookie.write_time_forced = fsp->write_time_forced;
- cookie.close_write_time = fsp->close_write_time;
+ cookie.update_write_time_triggered =
+ fsp->fsp_flags.update_write_time_triggered;
+ cookie.update_write_time_on_close =
+ fsp->fsp_flags.update_write_time_on_close;
+ cookie.write_time_forced = fsp->fsp_flags.write_time_forced;
+ cookie.close_write_time = full_timespec_to_nt_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_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_iflags = fsp->fsp_name->st.st_ex_iflags;
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);
return NT_STATUS_INVALID_PARAMETER;
}
- if (!BATCH_OPLOCK_TYPE(fsp->oplock_type)) {
- return NT_STATUS_NOT_SUPPORTED;
- }
-
- if (fsp->num_pending_break_messages > 0) {
+ if ((fsp_lease_type(fsp) & SMB2_LEASE_HANDLE) == 0) {
return NT_STATUS_NOT_SUPPORTED;
}
* For now let it be simple and do not keep
* delete on close files durable open
*/
- if (fsp->initial_delete_on_close) {
+ if (fsp->fsp_flags.initial_delete_on_close) {
return NT_STATUS_NOT_SUPPORTED;
}
- if (fsp->delete_on_close) {
+ if (fsp->fsp_flags.delete_on_close) {
return NT_STATUS_NOT_SUPPORTED;
}
/* Ensure any pending write time updates are done. */
if (fsp->update_write_time_event) {
- update_write_time_handler(fsp->conn->sconn->ev_ctx,
- fsp->update_write_time_event,
- timeval_current(),
- (void *)fsp);
+ fsp_flush_write_time_update(fsp);
}
/*
if (lck != NULL) {
struct smb_file_time ft;
- ZERO_STRUCT(ft);
+ init_smb_file_time(&ft);
- if (fsp->write_time_forced) {
- ft.mtime = lck->data->changed_write_time;
- } else if (fsp->update_write_time_on_close) {
- if (null_timespec(fsp->close_write_time)) {
+ if (fsp->fsp_flags.write_time_forced) {
+ ft.mtime = nt_time_to_full_timespec(
+ lck->data->changed_write_time);
+ } else if (fsp->fsp_flags.update_write_time_on_close) {
+ if (is_omit_timespec(&fsp->close_write_time)) {
ft.mtime = timespec_current();
} else {
ft.mtime = fsp->close_write_time;
}
}
- if (!null_timespec(ft.mtime)) {
+ if (!is_omit_timespec(&ft.mtime)) {
round_timespec(conn->ts_res, &ft.mtime);
file_ntimes(conn, fsp->fsp_name, &ft);
}
cookie.base_name = fsp->fsp_name->base_name;
cookie.initial_allocation_size = fsp->initial_allocation_size;
cookie.position_information = fsp->fh->position_information;
- cookie.update_write_time_triggered = fsp->update_write_time_triggered;
- cookie.update_write_time_on_close = fsp->update_write_time_on_close;
- cookie.write_time_forced = fsp->write_time_forced;
- cookie.close_write_time = fsp->close_write_time;
+ cookie.update_write_time_triggered =
+ fsp->fsp_flags.update_write_time_triggered;
+ cookie.update_write_time_on_close =
+ fsp->fsp_flags.update_write_time_on_close;
+ cookie.write_time_forced = fsp->fsp_flags.write_time_forced;
+ cookie.close_write_time = full_timespec_to_nt_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_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_iflags = fsp->fsp_name->st.st_ex_iflags;
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);
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_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_iflags != fsp_st->st_ex_iflags) {
+ 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_iflags,
+ (unsigned long long)fsp_st->st_ex_iflags));
+ 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;
+ }
+
+ return true;
+}
+
+static bool durable_reconnect_fn(
+ struct share_mode_entry *e,
+ bool *modified,
+ void *private_data)
+{
+ struct share_mode_entry *dst_e = private_data;
+
+ if (dst_e->pid.pid != 0) {
+ DBG_INFO("Found more than one entry, invalidating previous\n");
+ dst_e->pid.pid = 0;
+ return true; /* end the loop through share mode entries */
+ }
+ *dst_e = *e;
+ return false; /* Look at potential other entries */
+}
+
NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
struct smb_request *smb1req,
struct smbXsrv_open *op,
files_struct **result,
DATA_BLOB *new_cookie)
{
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
struct share_mode_lock *lck;
- struct share_mode_entry *e;
+ struct share_mode_entry e;
struct files_struct *fsp = NULL;
NTSTATUS status;
bool ok;
* call below.
*/
- ZERO_STRUCT(cookie);
-
- ndr_err = ndr_pull_struct_blob(&old_cookie, talloc_tos(), &cookie,
- (ndr_pull_flags_fn_t)ndr_pull_vfs_default_durable_cookie);
+ ndr_err = ndr_pull_struct_blob_all(
+ &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;
}
/* Create an smb_filename with stream_name == NULL. */
- status = create_synthetic_smb_fname(talloc_tos(),
- cookie.base_name,
- NULL, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ smb_fname = synthetic_smb_fname(talloc_tos(),
+ cookie.base_name,
+ NULL,
+ NULL,
+ 0,
+ 0);
+ if (smb_fname == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
ret = SMB_VFS_LSTAT(conn, smb_fname);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- if (lck->data->num_share_modes == 0) {
- DEBUG(1, ("vfs_default_durable_reconnect: Error: no share-mode "
- "entry in existing share mode lock\n"));
+ e = (struct share_mode_entry) { .pid.pid = 0 };
+
+ 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;
}
- if (lck->data->num_share_modes > 1) {
- /*
- * It can't be durable if there is more than one handle
- * on the file.
- */
- DEBUG(5, ("vfs_default_durable_reconnect: more than one "
- "share-mode entry - can not be durable\n"));
+ 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;
}
- e = &lck->data->share_modes[0];
-
- if (!server_id_is_disconnected(&e->pid)) {
+ 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"));
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- if (e->share_file_id != op->global->open_persistent_id) {
- DEBUG(5, ("vfs_default_durable_reconnect: denying durable "
- "share_file_id changed %llu != %llu"
- "(e.g. another client had opened the file)\n",
- (unsigned long long)e->share_file_id,
- (unsigned long long)op->global->open_persistent_id));
+ if (e.share_file_id != op->global->open_persistent_id) {
+ DBG_INFO("denying durable "
+ "share_file_id changed %"PRIu64" != %"PRIu64" "
+ "(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;
}
- if ((e->access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) &&
+ if ((e.access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) &&
!CAN_WRITE(conn))
{
DEBUG(5, ("vfs_default_durable_reconnect: denying durable "
"share[%s] is not writeable anymore\n",
- lp_servicename(talloc_tos(), SNUM(conn))));
+ lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
TALLOC_FREE(lck);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- /*
- * TODO:
- * add scavenger timer functionality
- *
- * For now we always allow the reconnect
- */
-#if 0
- expire_time = op->global->disconnect_time;
- expire_time += NTTIME_MAGIC(op->global->durable_timeout_msec);
- if (expire < now) {
- //TODO reopen and close before telling the client...
- }
-#endif
-
/*
* 2. proceed with opening file
*/
return status;
}
- fsp->fh->private_options = e->private_options;
- fsp->fh->gen_id = smbXsrv_open_hash(op);
+ fsp->fh->private_options = e.private_options;
fsp->file_id = file_id;
fsp->file_pid = smb1req->smbpid;
fsp->vuid = smb1req->vuid;
- fsp->open_time = e->time;
- fsp->access_mask = e->access_mask;
- fsp->share_access = e->share_access;
- fsp->can_read = ((fsp->access_mask & (FILE_READ_DATA)) != 0);
- fsp->can_write = ((fsp->access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) != 0);
+ fsp->open_time = e.time;
+ fsp->access_mask = e.access_mask;
+ fsp->fsp_flags.can_read = ((fsp->access_mask & FILE_READ_DATA) != 0);
+ fsp->fsp_flags.can_write = ((fsp->access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) != 0);
+ fsp->fnum = op->local_id;
+ fsp_set_gen_id(fsp);
/*
* TODO:
* Do we need to store the modified flag in the DB?
- * How to handle update_write_time and friends
- * during a disconnected client on a durable handle?
*/
- fsp->modified = false;
+ fsp->fsp_flags.modified = false;
/*
* no durables for directories
*/
- fsp->is_directory = false;
+ fsp->fsp_flags.is_directory = false;
/*
* For normal files, can_lock == !is_directory
*/
- fsp->can_lock = true;
+ fsp->fsp_flags.can_lock = true;
/*
* We do not support aio write behind for smb2
*/
- fsp->aio_write_behind = false;
- fsp->oplock_type = e->op_type;
+ fsp->fsp_flags.aio_write_behind = false;
+ fsp->oplock_type = e.op_type;
+
+ if (fsp->oplock_type == LEASE_OPLOCK) {
+ uint32_t current_state;
+ uint16_t lease_version, epoch;
+
+ /*
+ * Ensure the existing client guid matches the
+ * stored one in the share_mode_entry.
+ */
+ if (!GUID_equal(fsp_client_guid(fsp),
+ &e.client_guid)) {
+ TALLOC_FREE(lck);
+ fsp_free(fsp);
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ status = leases_db_get(
+ &e.client_guid,
+ &e.lease_key,
+ &file_id,
+ ¤t_state, /* current_state */
+ NULL, /* breaking */
+ NULL, /* breaking_to_requested */
+ NULL, /* breaking_to_required */
+ &lease_version, /* lease_version */
+ &epoch); /* epoch */
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(lck);
+ fsp_free(fsp);
+ return status;
+ }
+
+ fsp->lease = find_fsp_lease(
+ fsp,
+ &e.lease_key,
+ current_state,
+ lease_version,
+ epoch);
+ if (fsp->lease == NULL) {
+ TALLOC_FREE(lck);
+ fsp_free(fsp);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
fsp->initial_allocation_size = cookie.initial_allocation_size;
fsp->fh->position_information = cookie.position_information;
- fsp->update_write_time_triggered = cookie.update_write_time_triggered;
- fsp->update_write_time_on_close = cookie.update_write_time_on_close;
- fsp->write_time_forced = cookie.write_time_forced;
- fsp->close_write_time = cookie.close_write_time;
+ fsp->fsp_flags.update_write_time_triggered =
+ cookie.update_write_time_triggered;
+ fsp->fsp_flags.update_write_time_on_close =
+ cookie.update_write_time_on_close;
+ fsp->fsp_flags.write_time_forced = cookie.write_time_forced;
+ fsp->close_write_time = nt_time_to_full_timespec(
+ cookie.close_write_time);
status = fsp_set_smb_fname(fsp, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
op->compat = fsp;
fsp->op = op;
- e->pid = messaging_server_id(conn->sconn->msg_ctx);
- e->op_mid = smb1req->mid;
- e->share_file_id = fsp->fh->gen_id;
+ ok = reset_share_mode_entry(
+ lck,
+ e.pid,
+ e.share_file_id,
+ messaging_server_id(conn->sconn->msg_ctx),
+ smb1req->mid,
+ fsp->fh->gen_id);
+ if (!ok) {
+ DBG_DEBUG("Could not set new share_mode_entry values\n");
+ TALLOC_FREE(lck);
+ op->compat = NULL;
+ fsp_free(fsp);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
ok = brl_reconnect_disconnected(fsp);
if (!ok) {
/*
* TODO: properly calculate open flags
*/
- if (fsp->can_write && fsp->can_read) {
+ if (fsp->fsp_flags.can_write && fsp->fsp_flags.can_read) {
flags = O_RDWR;
- } else if (fsp->can_write) {
+ } else if (fsp->fsp_flags.can_write) {
flags = O_WRONLY;
- } else if (fsp->can_read) {
+ } else if (fsp->fsp_flags.can_read) {
flags = O_RDONLY;
}
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);
+ (void)dos_mode(fsp->conn, fsp->fsp_name);
- 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: "
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- status = set_file_oplock(fsp, e->op_type);
+ status = set_file_oplock(fsp);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("vfs_default_durable_reconnect failed to set oplock "
"after opening file: %s\n", nt_errstr(status)));