diff --git a/docs-xml/manpages/vfs_full_audit.8.xml b/docs-xml/manpages/vfs_full_audit.8.xml index 7107fcb69ef8..bc69618e24eb 100644 --- a/docs-xml/manpages/vfs_full_audit.8.xml +++ b/docs-xml/manpages/vfs_full_audit.8.xml @@ -96,6 +96,9 @@ set_nt_acl set_quota setxattr + snap_check_path + snap_create + snap_delete stat statvfs symlink diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index b6b1aefe5b00..a9cbabf80573 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -102,6 +102,33 @@ static DIR *skel_opendir(vfs_handle_struct *handle, const char *fname, return NULL; } +static NTSTATUS skel_snap_check_path(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *service_path, + char **base_volume) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +static NTSTATUS skel_snap_create(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *base_volume, + time_t *tstamp, + bool rw, + char **base_path, + char **snap_path) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +static NTSTATUS skel_snap_delete(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + char *base_path, + char *snap_path) +{ + return NT_STATUS_NOT_SUPPORTED; +} + static DIR *skel_fdopendir(vfs_handle_struct *handle, files_struct *fsp, const char *mask, uint32 attr) { @@ -830,6 +857,9 @@ struct vfs_fn_pointers skel_opaque_fns = { .statvfs_fn = skel_statvfs, .fs_capabilities_fn = skel_fs_capabilities, .get_dfs_referrals_fn = skel_get_dfs_referrals, + .snap_check_path_fn = skel_snap_check_path, + .snap_create_fn = skel_snap_create, + .snap_delete_fn = skel_snap_delete, /* Directory operations */ diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index f7ed537025e9..651eb2f840d7 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -100,6 +100,35 @@ static DIR *skel_opendir(vfs_handle_struct *handle, const char *fname, return SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); } +static NTSTATUS skel_snap_check_path(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *service_path, + char **base_volume) +{ + return SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path, + base_volume); +} + +static NTSTATUS skel_snap_create(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *base_volume, + time_t *tstamp, + bool rw, + char **base_path, + char **snap_path) +{ + return SMB_VFS_NEXT_SNAP_CREATE(handle, mem_ctx, base_volume, tstamp, + rw, base_path, snap_path); +} + +static NTSTATUS skel_snap_delete(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + char *base_path, + char *snap_path) +{ + return SMB_VFS_NEXT_SNAP_DELETE(handle, mem_ctx, base_path, snap_path); +} + static DIR *skel_fdopendir(vfs_handle_struct *handle, files_struct *fsp, const char *mask, uint32 attr) { @@ -939,6 +968,9 @@ struct vfs_fn_pointers skel_transparent_fns = { .statvfs_fn = skel_statvfs, .fs_capabilities_fn = skel_fs_capabilities, .get_dfs_referrals_fn = skel_get_dfs_referrals, + .snap_check_path_fn = skel_snap_check_path, + .snap_create_fn = skel_snap_create, + .snap_delete_fn = skel_snap_delete, /* Directory operations */ diff --git a/source3/include/vfs.h b/source3/include/vfs.h index b2880b76253c..5dcb894c0386 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -164,6 +164,7 @@ /* Version 32 - Remove unnecessary SMB_VFS_DISK_FREE() small_query parameter */ /* Bump to version 33 - Samba 4.3 will ship with that. */ /* Version 33 - change fallocate mode flags param from enum->uint32_t */ +/* Version 33 - Add snapshot create/delete calls */ #define SMB_VFS_INTERFACE_VERSION 33 @@ -656,6 +657,21 @@ struct vfs_fn_pointers { TALLOC_CTX *mem_ctx, struct files_struct *fsp, uint16_t compression_fmt); + NTSTATUS (*snap_check_path_fn)(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *service_path, + char **base_volume); + NTSTATUS (*snap_create_fn)(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *base_volume, + time_t *tstamp, + bool rw, + char **base_path, + char **snap_path); + NTSTATUS (*snap_delete_fn)(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + char *base_path, + char *snap_path); NTSTATUS (*streaminfo_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, @@ -1151,6 +1167,21 @@ NTSTATUS smb_vfs_call_set_compression(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, struct files_struct *fsp, uint16_t compression_fmt); +NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *service_path, + char **base_volume); +NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *base_volume, + time_t *tstamp, + bool rw, + char **base_path, + char **snap_path); +NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + char *base_path, + char *snap_path); NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 0cc442e01047..9a686c9ad225 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -422,6 +422,21 @@ #define SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp, compression_fmt) \ smb_vfs_call_set_compression((handle)->next, (mem_ctx), (fsp), (compression_fmt)) +#define SMB_VFS_SNAP_CHECK_PATH(conn, mem_ctx, service_path, base_volume) \ + smb_vfs_call_snap_check_path((conn)->vfs_handles, (mem_ctx), (service_path), (base_volume)) +#define SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path, base_volume) \ + smb_vfs_call_snap_check_path((handle)->next, (mem_ctx), (service_path), (base_volume)) + +#define SMB_VFS_SNAP_CREATE(conn, mem_ctx, base_volume, tstamp, rw, base_path, snap_path) \ + smb_vfs_call_snap_create((conn)->vfs_handles, (mem_ctx), (base_volume), (tstamp), (rw), (base_path), (snap_path)) +#define SMB_VFS_NEXT_SNAP_CREATE(handle, mem_ctx, base_volume, tstamp, rw, base_path, snap_path) \ + smb_vfs_call_snap_create((handle)->next, (mem_ctx), (base_volume), (tstamp), (rw), (base_path), (snap_path)) + +#define SMB_VFS_SNAP_DELETE(conn, mem_ctx, base_path, snap_path) \ + smb_vfs_call_snap_delete((conn)->vfs_handles, (mem_ctx), (base_path), (snap_path)) +#define SMB_VFS_NEXT_SNAP_DELETE(handle, mem_ctx, base_path, snap_path) \ + smb_vfs_call_snap_delete((handle)->next, (mem_ctx), (base_path), (snap_path)) + #define SMB_VFS_FGET_NT_ACL(fsp, security_info, mem_ctx, ppdesc) \ smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (mem_ctx), (ppdesc)) #define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, mem_ctx, ppdesc) \ diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index fdb90e410922..dbcd6016af7f 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -342,6 +342,33 @@ static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle, return NT_STATUS_OK; } +static NTSTATUS vfswrap_snap_check_path(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *service_path, + char **base_volume) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +static NTSTATUS vfswrap_snap_create(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *base_volume, + time_t *tstamp, + bool rw, + char **base_path, + char **snap_path) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +static NTSTATUS vfswrap_snap_delete(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + char *base_path, + char *snap_path) +{ + return NT_STATUS_NOT_SUPPORTED; +} + /* Directory operations */ static DIR *vfswrap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) @@ -2544,6 +2571,9 @@ static struct vfs_fn_pointers vfs_default_fns = { .statvfs_fn = vfswrap_statvfs, .fs_capabilities_fn = vfswrap_fs_capabilities, .get_dfs_referrals_fn = vfswrap_get_dfs_referrals, + .snap_check_path_fn = vfswrap_snap_check_path, + .snap_create_fn = vfswrap_snap_create, + .snap_delete_fn = vfswrap_snap_delete, /* Directory operations */ diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 87a2f9c3bc4d..c8cef605b31a 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -97,6 +97,9 @@ typedef enum _vfs_op_type { SMB_VFS_OP_GET_SHADOW_COPY_DATA, SMB_VFS_OP_STATVFS, SMB_VFS_OP_FS_CAPABILITIES, + SMB_VFS_OP_SNAP_CHECK_PATH, + SMB_VFS_OP_SNAP_CREATE, + SMB_VFS_OP_SNAP_DELETE, /* Directory operations */ @@ -228,6 +231,9 @@ static struct { { SMB_VFS_OP_GET_SHADOW_COPY_DATA, "get_shadow_copy_data" }, { SMB_VFS_OP_STATVFS, "statvfs" }, { SMB_VFS_OP_FS_CAPABILITIES, "fs_capabilities" }, + { SMB_VFS_OP_SNAP_CHECK_PATH, "snap_check_path" }, + { SMB_VFS_OP_SNAP_CREATE, "snap_create" }, + { SMB_VFS_OP_SNAP_DELETE, "snap_delete" }, { SMB_VFS_OP_OPENDIR, "opendir" }, { SMB_VFS_OP_FDOPENDIR, "fdopendir" }, { SMB_VFS_OP_READDIR, "readdir" }, @@ -674,7 +680,6 @@ static int smb_full_audit_get_quota(struct vfs_handle_struct *handle, return result; } - static int smb_full_audit_set_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) @@ -726,6 +731,52 @@ static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle, return result; } +static NTSTATUS smb_full_audit_snap_check_path(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *service_path, + char **base_volume) +{ + NTSTATUS status; + + status = SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path, + base_volume); + do_log(SMB_VFS_OP_SNAP_CHECK_PATH, NT_STATUS_IS_OK(status), + handle, ""); + + return status; +} + +static NTSTATUS smb_full_audit_snap_create(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *base_volume, + time_t *tstamp, + bool rw, + char **base_path, + char **snap_path) +{ + NTSTATUS status; + + status = SMB_VFS_NEXT_SNAP_CREATE(handle, mem_ctx, base_volume, tstamp, + rw, base_path, snap_path); + do_log(SMB_VFS_OP_SNAP_CREATE, NT_STATUS_IS_OK(status), handle, ""); + + return status; +} + +static NTSTATUS smb_full_audit_snap_delete(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + char *base_path, + char *snap_path) +{ + NTSTATUS status; + + status = SMB_VFS_NEXT_SNAP_DELETE(handle, mem_ctx, base_path, + snap_path); + do_log(SMB_VFS_OP_SNAP_DELETE, NT_STATUS_IS_OK(status), handle, ""); + + return status; +} + static DIR *smb_full_audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr) { @@ -2199,6 +2250,9 @@ static struct vfs_fn_pointers vfs_full_audit_fns = { .get_shadow_copy_data_fn = smb_full_audit_get_shadow_copy_data, .statvfs_fn = smb_full_audit_statvfs, .fs_capabilities_fn = smb_full_audit_fs_capabilities, + .snap_check_path_fn = smb_full_audit_snap_check_path, + .snap_create_fn = smb_full_audit_snap_create, + .snap_delete_fn = smb_full_audit_snap_delete, .opendir_fn = smb_full_audit_opendir, .fdopendir_fn = smb_full_audit_fdopendir, .readdir_fn = smb_full_audit_readdir, diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index 45e30acfd17b..eebd8cec0335 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -277,9 +277,78 @@ static uint32_t smb_time_audit_fs_capabilities(struct vfs_handle_struct *handle, return result; } +static NTSTATUS smb_time_audit_snap_check_path(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *service_path, + char **base_volume) +{ + NTSTATUS status; + struct timespec ts1,ts2; + double timediff; + + clock_gettime_mono(&ts1); + status = SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path, + base_volume); + clock_gettime_mono(&ts2); + timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9; + + if (timediff > audit_timeout) { + smb_time_audit_log("snap_check_path", timediff); + } + + return status; +} + +static NTSTATUS smb_time_audit_snap_create(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *base_volume, + time_t *tstamp, + bool rw, + char **base_path, + char **snap_path) +{ + NTSTATUS status; + struct timespec ts1,ts2; + double timediff; + + clock_gettime_mono(&ts1); + status = SMB_VFS_NEXT_SNAP_CREATE(handle, mem_ctx, base_volume, tstamp, + rw, base_path, snap_path); + clock_gettime_mono(&ts2); + timediff = nsec_time_diff(&ts2 ,&ts1) * 1.0e-9; + + if (timediff > audit_timeout) { + smb_time_audit_log("snap_create", timediff); + } + + return status; +} + +static NTSTATUS smb_time_audit_snap_delete(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + char *base_path, + char *snap_path) +{ + NTSTATUS status; + struct timespec ts1,ts2; + double timediff; + + clock_gettime_mono(&ts1); + status = SMB_VFS_NEXT_SNAP_DELETE(handle, mem_ctx, base_path, + snap_path); + clock_gettime_mono(&ts2); + timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9; + + if (timediff > audit_timeout) { + smb_time_audit_log("snap_delete", timediff); + } + + return status; +} + static DIR *smb_time_audit_opendir(vfs_handle_struct *handle, - const char *fname, - const char *mask, uint32 attr) + const char *fname, + const char *mask, uint32 attr) { DIR *result; struct timespec ts1,ts2; @@ -2383,6 +2452,9 @@ static struct vfs_fn_pointers vfs_time_audit_fns = { .get_shadow_copy_data_fn = smb_time_audit_get_shadow_copy_data, .statvfs_fn = smb_time_audit_statvfs, .fs_capabilities_fn = smb_time_audit_fs_capabilities, + .snap_check_path_fn = smb_time_audit_snap_check_path, + .snap_create_fn = smb_time_audit_snap_create, + .snap_delete_fn = smb_time_audit_snap_delete, .opendir_fn = smb_time_audit_opendir, .fdopendir_fn = smb_time_audit_fdopendir, .readdir_fn = smb_time_audit_readdir, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 1e20963da1a2..ebd3440e73f6 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -2227,6 +2227,39 @@ NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle, compression_fmt); } +NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *service_path, + char **base_volume) +{ + VFS_FIND(snap_check_path); + return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path, + base_volume); +} + +NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + const char *base_volume, + time_t *tstamp, + bool rw, + char **base_path, + char **snap_path) +{ + VFS_FIND(snap_create); + return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp, + rw, base_path, snap_path); +} + +NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + char *base_path, + char *snap_path) +{ + VFS_FIND(snap_delete); + return handle->fns->snap_delete_fn(handle, mem_ctx, base_path, + snap_path); +} + NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info,