struct smb_filename *smb_fname = NULL;
time_t timestamp = 0;
char *stripped = NULL;
- bool is_converted = false;
int saved_errno = 0;
int ret;
bool ok;
return -1;
}
- ok = shadow_copy2_strip_snapshot_converted(talloc_tos(),
- handle,
- smb_fname,
- ×tamp,
- &stripped,
- &is_converted);
+ ok = shadow_copy2_strip_snapshot(talloc_tos(),
+ handle,
+ smb_fname,
+ ×tamp,
+ &stripped);
if (!ok) {
TALLOC_FREE(smb_fname);
return -1;
if (timestamp == 0) {
TALLOC_FREE(stripped);
TALLOC_FREE(smb_fname);
- if (is_converted) {
- /*
- * Just pave over the user requested mode and use
- * O_RDONLY. Later attempts by the client to write on
- * the handle will fail in the pwrite() syscall with
- * EINVAL which we carefully map to EROFS. In sum, this
- * matches Windows behaviour.
- */
- how.flags &= ~(O_WRONLY | O_RDWR | O_CREAT);
- }
return SMB_VFS_NEXT_OPENAT(handle,
dirfsp,
smb_fname_in,
}
TALLOC_FREE(stripped);
- /*
- * Just pave over the user requested mode and use O_RDONLY. Later
- * attempts by the client to write on the handle will fail in the
- * pwrite() syscall with EINVAL which we carefully map to EROFS. In sum,
- * this matches Windows behaviour.
- */
- how.flags &= ~(O_WRONLY | O_RDWR | O_CREAT);
-
ret = SMB_VFS_NEXT_OPENAT(handle,
dirfsp,
smb_fname,
}
static int calculate_open_access_flags(uint32_t access_mask,
- uint32_t private_flags)
+ uint32_t private_flags,
+ NTTIME twrp)
{
bool need_write, need_read;
* mean the same thing under DOS and Unix.
*/
+ if (twrp != 0) {
+ /*
+ * Pave over the user requested mode and force O_RDONLY for the
+ * file handle. Windows allows opening a VSS file with O_RDWR,
+ * even though actual writes on the handle will fail.
+ */
+ return O_RDONLY;
+ }
+
need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
if (!need_write) {
return O_RDONLY;
bool posix_open = False;
bool new_file_created = False;
bool first_open_attempt = true;
+ bool is_twrp = (smb_fname_atname->twrp != 0);
NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
mode_t new_unx_mode = (mode_t)0;
mode_t unx_mode = (mode_t)0;
smb_fname_str_dbg(smb_fname) ));
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
+ if (is_twrp) {
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+ }
break;
case FILE_CREATE:
}
return NT_STATUS_OBJECT_NAME_COLLISION;
}
+ if (is_twrp) {
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+ }
break;
case FILE_SUPERSEDE:
case FILE_OVERWRITE_IF:
+ if (is_twrp) {
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+ }
+ break;
case FILE_OPEN_IF:
+ if (is_twrp) {
+ if (!file_existed) {
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+ }
+ create_disposition = FILE_OPEN;
+ }
break;
default:
return NT_STATUS_INVALID_PARAMETER;
* mean the same thing under DOS and Unix.
*/
- flags |= calculate_open_access_flags(access_mask, private_flags);
+ flags |= calculate_open_access_flags(access_mask,
+ private_flags,
+ smb_fname->twrp);
/*
* Currently we only look at FILE_WRITE_THROUGH for create options.
return status;
}
+ if (smb_fname_atname->twrp != 0) {
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+ }
+
status = mkdir_internal(conn,
parent_dir_fname,
smb_fname_atname,
status = NT_STATUS_OK;
info = FILE_WAS_OPENED;
} else {
+ if (smb_fname_atname->twrp != 0) {
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+ }
status = mkdir_internal(conn,
parent_dir_fname,
smb_fname_atname,