diff options
author | Pádraig Brady <P@draigBrady.com> | 2010-04-16 08:39:11 +0100 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2010-04-16 23:02:02 +0100 |
commit | 1777d0dfe34dc4d8c148a34a96eb92c6036ff7bd (patch) | |
tree | 6238e6b29bbc3a3d10e96c6f7f9b5a6bcc661ab1 /src | |
parent | 56fce1aed76fa8d2ceaff8a9c4046204493adffe (diff) | |
download | coreutils-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.c | 30 |
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) |