summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2010-04-16 08:39:11 +0100
committerPádraig Brady <P@draigBrady.com>2010-04-16 23:02:02 +0100
commit1777d0dfe34dc4d8c148a34a96eb92c6036ff7bd (patch)
tree6238e6b29bbc3a3d10e96c6f7f9b5a6bcc661ab1 /src
parent56fce1aed76fa8d2ceaff8a9c4046204493adffe (diff)
downloadcoreutils-1777d0dfe34dc4d8c148a34a96eb92c6036ff7bd.tar.xz
cp: preserve "capabilities" when also preserving file ownership
* src/copy.c (copy_reg): Copy xattrs _after_ setting file ownership so that capabilities are not cleared when setting ownership. * tests/cp/capability: A new root test. * tests/Makefile.am (root_tests): Reference the new test. * NEWS: Mention the fix.
Diffstat (limited to 'src')
-rw-r--r--src/copy.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/src/copy.c b/src/copy.c
index 0fa148e4c..d18fd45ab 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -826,6 +826,22 @@ copy_reg (char const *src_name, char const *dst_name,
}
}
+ /* Set ownership before xattrs as changing owners will
+ clear capabilities. */
+ if (x->preserve_ownership && ! SAME_OWNER_AND_GROUP (*src_sb, sb))
+ {
+ switch (set_owner (x, dst_name, dest_desc, src_sb, *new_dst, &sb))
+ {
+ case -1:
+ return_val = false;
+ goto close_src_and_dst_desc;
+
+ case 0:
+ src_mode &= ~ (S_ISUID | S_ISGID | S_ISVTX);
+ break;
+ }
+ }
+
/* 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. */
@@ -844,20 +860,6 @@ copy_reg (char const *src_name, char const *dst_name,
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))
- {
- case -1:
- return_val = false;
- goto close_src_and_dst_desc;
-
- case 0:
- src_mode &= ~ (S_ISUID | S_ISGID | S_ISVTX);
- break;
- }
- }
-
set_author (dst_name, dest_desc, src_sb);
if (x->preserve_mode || x->move_mode)