From: Jeremy Allison Date: Fri, 27 Jan 2017 01:19:24 +0000 (-0800) Subject: s3: VFS: Don't allow symlink, link or rename on already converted paths. X-Git-Tag: samba-4.4.10~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=81231afc2f968582fb1998b227713b34e74d9a7f;p=thirdparty%2Fsamba.git s3: VFS: Don't allow symlink, link or rename on already converted paths. Snapshot paths are a read-only filesystem. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 Signed-off-by: Jeremy Allison Reviewed-by: Uri Simchoni Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Mon Jan 30 22:26:29 CET 2017 on sn-devel-144 (backported from commit 0e1deb77f2b310ad7e5dd784174207adacf1c981) --- diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index f773d4f98c2..1345ca24d45 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -903,15 +903,17 @@ static int shadow_copy2_rename(vfs_handle_struct *handle, { time_t timestamp_src = 0; time_t timestamp_dst = 0; + char *snappath_src = NULL; + char *snappath_dst = NULL; - if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, + if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, smb_fname_src->base_name, - ×tamp_src, NULL)) { + ×tamp_src, NULL, &snappath_src)) { return -1; } - if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, + if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, smb_fname_dst->base_name, - ×tamp_dst, NULL)) { + ×tamp_dst, NULL, &snappath_dst)) { return -1; } if (timestamp_src != 0) { @@ -922,6 +924,17 @@ static int shadow_copy2_rename(vfs_handle_struct *handle, errno = EROFS; return -1; } + /* + * Don't allow rename on already converted paths. + */ + if (snappath_src != NULL) { + errno = EXDEV; + return -1; + } + if (snappath_dst != NULL) { + errno = EROFS; + return -1; + } return SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst); } @@ -930,19 +943,28 @@ static int shadow_copy2_symlink(vfs_handle_struct *handle, { time_t timestamp_old = 0; time_t timestamp_new = 0; + char *snappath_old = NULL; + char *snappath_new = NULL; - if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, oldname, - ×tamp_old, NULL)) { + if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname, + ×tamp_old, NULL, &snappath_old)) { return -1; } - if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, newname, - ×tamp_new, NULL)) { + if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname, + ×tamp_new, NULL, &snappath_new)) { return -1; } if ((timestamp_old != 0) || (timestamp_new != 0)) { errno = EROFS; return -1; } + /* + * Don't allow symlinks on already converted paths. + */ + if ((snappath_old != NULL) || (snappath_new != NULL)) { + errno = EROFS; + return -1; + } return SMB_VFS_NEXT_SYMLINK(handle, oldname, newname); } @@ -951,19 +973,28 @@ static int shadow_copy2_link(vfs_handle_struct *handle, { time_t timestamp_old = 0; time_t timestamp_new = 0; + char *snappath_old = NULL; + char *snappath_new = NULL; - if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, oldname, - ×tamp_old, NULL)) { + if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname, + ×tamp_old, NULL, &snappath_old)) { return -1; } - if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, newname, - ×tamp_new, NULL)) { + if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname, + ×tamp_new, NULL, &snappath_new)) { return -1; } if ((timestamp_old != 0) || (timestamp_new != 0)) { errno = EROFS; return -1; } + /* + * Don't allow links on already converted paths. + */ + if ((snappath_old != NULL) || (snappath_new != NULL)) { + errno = EROFS; + return -1; + } return SMB_VFS_NEXT_LINK(handle, oldname, newname); }