From cca83fafa69eb26db458714830b77498b88af8a4 Mon Sep 17 00:00:00 2001 From: Ondřej Vašík Date: Mon, 14 Sep 2009 14:12:01 +0100 Subject: cp,mv: preserve extended attributes even for read-only files * src/copy.c (copy_reg): Temporarily set u+rw on the destination file to allow GNU/Linux to set xattrs. * tests/misc/xattr: Test that change. * NEWS (Bug fixes): Mention it. Reported by Ernest N. Mamikonyan. --- src/copy.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/copy.c b/src/copy.c index f3ff5a286..ad2060b9c 100644 --- a/src/copy.c +++ b/src/copy.c @@ -834,6 +834,24 @@ copy_reg (char const *src_name, char const *dst_name, } } + /* To allow copying xattrs on read-only files, temporarily chmod u+rw. + This workaround is required as an inode permission check is done + by xattr_permission() in fs/xattr.c of the GNU/Linux kernel tree. */ + if (x->preserve_xattr) + { + bool access_changed = true; + + if (!(sb.st_mode & S_IWUSR) && geteuid() != 0) + access_changed = fchmod_or_lchmod (dest_desc, dst_name, 0600) == 0; + + if (!copy_attr_by_fd (src_name, source_desc, dst_name, dest_desc, x) + && x->require_preserve_xattr) + return_val = false; + + if (access_changed) + fchmod_or_lchmod (dest_desc, dst_name, dst_mode & ~omitted_permissions); + } + if (x->preserve_ownership && ! SAME_OWNER_AND_GROUP (*src_sb, sb)) { switch (set_owner (x, dst_name, dest_desc, src_sb, *new_dst, &sb)) @@ -850,11 +868,6 @@ copy_reg (char const *src_name, char const *dst_name, set_author (dst_name, dest_desc, src_sb); - if (x->preserve_xattr && ! copy_attr_by_fd (src_name, source_desc, - dst_name, dest_desc, x) - && x->require_preserve_xattr) - return_val = false; - if (x->preserve_mode || x->move_mode) { if (copy_acl (src_name, source_desc, dst_name, dest_desc, src_mode) != 0 -- cgit v1.2.3-54-g00ecf