return -1;
}
+static int skel_rename_stream(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
static struct tevent_req *skel_fsync_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
.sendfile_fn = skel_sendfile,
.recvfile_fn = skel_recvfile,
.renameat_fn = skel_renameat,
+ .rename_stream_fn = skel_rename_stream,
.fsync_send_fn = skel_fsync_send,
.fsync_recv_fn = skel_fsync_recv,
.stat_fn = skel_stat,
how);
}
+static int skel_rename_stream(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists)
+{
+ return SMB_VFS_NEXT_RENAME_STREAM(handle,
+ src_fsp,
+ dst_name,
+ replace_if_exists);
+}
+
struct skel_fsync_state {
int ret;
struct vfs_aio_state vfs_aio_state;
.sendfile_fn = skel_sendfile,
.recvfile_fn = skel_recvfile,
.renameat_fn = skel_renameat,
+ .rename_stream_fn = skel_rename_stream,
.fsync_send_fn = skel_fsync_send,
.fsync_recv_fn = skel_fsync_recv,
.stat_fn = skel_stat,
SMBPROFILE_STATS_BYTES(syscall_sendfile) \
SMBPROFILE_STATS_BYTES(syscall_recvfile) \
SMBPROFILE_STATS_BASIC(syscall_renameat) \
+ SMBPROFILE_STATS_BASIC(syscall_rename_stream) \
SMBPROFILE_STATS_BYTES(syscall_asys_fsync) \
SMBPROFILE_STATS_BASIC(syscall_stat) \
SMBPROFILE_STATS_BASIC(syscall_fstat) \
* Version 50 - Add struct files_struct.fsp_flags.posix_append
* Change to Version 51 - will ship with 4.23
* Version 51 - Add ntcreatex_deny_[dos|fcb] and ntcreatex_stream_baseopen
+ * Change to Version 52 - will ship with 4.24
+ * Version 52 - Add rename_stream
*/
#define SMB_VFS_INTERFACE_VERSION 51
struct files_struct *dstdir_fsp,
const struct smb_filename *smb_fname_dst,
const struct vfs_rename_how *how);
+ int (*rename_stream_fn)(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists);
struct tevent_req *(*fsync_send_fn)(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct files_struct *dstfsp,
const struct smb_filename *smb_fname_dst,
const struct vfs_rename_how *how);
+int smb_vfs_call_rename_stream(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists);
struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
files_struct *dstfsp,
const struct smb_filename *smb_fname_dst,
const struct vfs_rename_how *how);
+int vfs_not_implemented_rename_stream(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists);
struct tevent_req *vfs_not_implemented_fsync_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
#define SMB_VFS_NEXT_RENAMEAT(handle, oldfsp, old, newfsp, newname, how) \
smb_vfs_call_renameat((handle)->next, (oldfsp), (old), (newfsp), (newname), (how))
+#define SMB_VFS_RENAME_STREAM(conn, src_fsp, dst_name, replace_if_exists) \
+ smb_vfs_call_rename_stream((conn)->vfs_handles, \
+ (src_fsp), \
+ (dst_name), \
+ (replace_if_exists))
+#define SMB_VFS_NEXT_RENAME_STREAM(handle, \
+ src_fsp, \
+ dst_name, \
+ replace_if_exists) \
+ smb_vfs_call_rename_stream((handle)->next, \
+ (src_fsp), \
+ (dst_name), \
+ (replace_if_exists))
+
#define SMB_VFS_FSYNC_SEND(mem_ctx, ev, fsp) \
smb_vfs_call_fsync_send((fsp)->conn->vfs_handles, (mem_ctx), (ev), \
(fsp))
return result;
}
+static int vfswrap_rename_stream(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists)
+{
+ int result = -1;
+ START_PROFILE_X(SNUM(handle->conn), syscall_rename_stream);
+ errno = ENOSYS;
+ END_PROFILE_X(syscall_rename_stream);
+ return result;
+}
+
static int vfswrap_stat(vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
.sendfile_fn = vfswrap_sendfile,
.recvfile_fn = vfswrap_recvfile,
.renameat_fn = vfswrap_renameat,
+ .rename_stream_fn = vfswrap_rename_stream,
.fsync_send_fn = vfswrap_fsync_send,
.fsync_recv_fn = vfswrap_fsync_recv,
.stat_fn = vfswrap_stat,
SMB_VFS_OP_SENDFILE,
SMB_VFS_OP_RECVFILE,
SMB_VFS_OP_RENAMEAT,
+ SMB_VFS_OP_RENAME_STREAM,
SMB_VFS_OP_FSYNC_SEND,
SMB_VFS_OP_FSYNC_RECV,
SMB_VFS_OP_STAT,
SMB_VFS_OP_FSETXATTR,
/* aio operations */
- SMB_VFS_OP_AIO_FORCE,
+ SMB_VFS_OP_AIO_FORCE,
/* offline operations */
SMB_VFS_OP_IS_OFFLINE,
{ SMB_VFS_OP_SENDFILE, "sendfile" },
{ SMB_VFS_OP_RECVFILE, "recvfile" },
{ SMB_VFS_OP_RENAMEAT, "renameat" },
+ { SMB_VFS_OP_RENAME_STREAM, "rename_stream" },
{ SMB_VFS_OP_FSYNC_SEND, "fsync_send" },
{ SMB_VFS_OP_FSYNC_RECV, "fsync_recv" },
{ SMB_VFS_OP_STAT, "stat" },
return result;
}
+static int smb_full_audit_rename_stream(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists)
+{
+ int result;
+ int saved_errno;
+
+ result = SMB_VFS_NEXT_RENAME_STREAM(handle,
+ src_fsp,
+ dst_name,
+ replace_if_exists);
+ saved_errno = errno;
+
+ do_log(SMB_VFS_OP_RENAME_STREAM,
+ (result >= 0),
+ handle,
+ "%s|%s",
+ fsp_str_do_log(src_fsp),
+ dst_name);
+
+ if (result == -1) {
+ errno = saved_errno;
+ }
+ return result;
+}
+
struct smb_full_audit_fsync_state {
vfs_handle_struct *handle;
files_struct *fsp;
.sendfile_fn = smb_full_audit_sendfile,
.recvfile_fn = smb_full_audit_recvfile,
.renameat_fn = smb_full_audit_renameat,
+ .rename_stream_fn = smb_full_audit_rename_stream,
.fsync_send_fn = smb_full_audit_fsync_send,
.fsync_recv_fn = smb_full_audit_fsync_recv,
.stat_fn = smb_full_audit_stat,
return -1;
}
+_PUBLIC_
+int vfs_not_implemented_rename_stream(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
_PUBLIC_
struct tevent_req *vfs_not_implemented_fsync_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
.sendfile_fn = vfs_not_implemented_sendfile,
.recvfile_fn = vfs_not_implemented_recvfile,
.renameat_fn = vfs_not_implemented_renameat,
+ .rename_stream_fn = vfs_not_implemented_rename_stream,
.fsync_send_fn = vfs_not_implemented_fsync_send,
.fsync_recv_fn = vfs_not_implemented_fsync_recv,
.stat_fn = vfs_not_implemented_stat,
return ret;
}
+static int streams_depot_rename_stream(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
static bool add_one_stream(TALLOC_CTX *mem_ctx, unsigned int *num_streams,
struct stream_struct **streams,
const char *name, off_t size,
.fstatat_fn = streams_depot_fstatat,
.unlinkat_fn = streams_depot_unlinkat,
.renameat_fn = streams_depot_renameat,
+ .rename_stream_fn = streams_depot_rename_stream,
.fstreaminfo_fn = streams_depot_fstreaminfo,
};
return ret;
}
+static int streams_xattr_rename_stream(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
static NTSTATUS walk_xattr_streams(vfs_handle_struct *handle,
files_struct *fsp,
const struct smb_filename *smb_fname,
.pwrite_recv_fn = streams_xattr_pwrite_recv,
.unlinkat_fn = streams_xattr_unlinkat,
.renameat_fn = streams_xattr_renameat,
+ .rename_stream_fn = streams_xattr_rename_stream,
.ftruncate_fn = streams_xattr_ftruncate,
.fallocate_fn = streams_xattr_fallocate,
.fstreaminfo_fn = streams_xattr_fstreaminfo,
return result;
}
+static int smb_time_audit_rename_stream(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists)
+{
+ int result;
+ struct timespec ts1, ts2;
+ double timediff;
+ char *msg = NULL;
+
+ clock_gettime_mono(&ts1);
+ result = SMB_VFS_NEXT_RENAME_STREAM(handle,
+ src_fsp,
+ dst_name,
+ replace_if_exists);
+ clock_gettime_mono(&ts2);
+ timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9;
+
+ if (timediff > audit_timeout) {
+ msg = talloc_asprintf(talloc_tos(),
+ "%s -> %s",
+ fsp_str_dbg(src_fsp),
+ dst_name);
+ if (msg != NULL) {
+ smb_time_audit_log_msg("rename_stream", timediff, msg);
+ TALLOC_FREE(msg);
+ }
+ }
+
+ return result;
+}
+
struct smb_time_audit_fsync_state {
struct files_struct *fsp;
int ret;
.sendfile_fn = smb_time_audit_sendfile,
.recvfile_fn = smb_time_audit_recvfile,
.renameat_fn = smb_time_audit_renameat,
+ .rename_stream_fn = smb_time_audit_rename_stream,
.fsync_send_fn = smb_time_audit_fsync_send,
.fsync_recv_fn = smb_time_audit_fsync_recv,
.stat_fn = smb_time_audit_stat,
.freaddir_attr_fn = smb_time_audit_freaddir_attr,
};
-
static_decl_vfs;
NTSTATUS vfs_time_audit_init(TALLOC_CTX *ctx)
{
how);
}
+int smb_vfs_call_rename_stream(struct vfs_handle_struct *handle,
+ struct files_struct *src_fsp,
+ const char *dst_name,
+ bool replace_if_exists)
+{
+ VFS_FIND(rename_stream);
+ return handle->fns->rename_stream_fn(handle,
+ src_fsp,
+ dst_name,
+ replace_if_exists);
+}
+
struct smb_vfs_call_fsync_state {
int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
int retval;