From 1777d0dfe34dc4d8c148a34a96eb92c6036ff7bd Mon Sep 17 00:00:00 2001 From: Pádraig Brady
Date: Fri, 16 Apr 2010 08:39:11 +0100
Subject: 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.
---
NEWS | 2 ++
src/copy.c | 30 ++++++++++++++--------------
tests/Makefile.am | 1 +
tests/cp/capability | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 75 insertions(+), 14 deletions(-)
create mode 100755 tests/cp/capability
diff --git a/NEWS b/NEWS
index 2be9633a0..867589c52 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@ GNU coreutils NEWS -*- outline -*-
** Bug fixes
+ cp now preserves "capabilities" also when preserving file ownership.
+
ls --color once again honors the 'NORMAL' dircolors directive.
[bug introduced in coreutils-6.11]
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)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index db1610d6b..a943ff3ab 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -23,6 +23,7 @@ root_tests = \
cp/preserve-gid \
cp/special-bits \
cp/cp-mv-enotsup-xattr \
+ cp/capability \
dd/skip-seek-past-dev \
install/install-C-root \
ls/capability \
diff --git a/tests/cp/capability b/tests/cp/capability
new file mode 100755
index 000000000..f4ee227f5
--- /dev/null
+++ b/tests/cp/capability
@@ -0,0 +1,56 @@
+#!/bin/sh
+# Ensure cp --preserves copies capabilities
+
+# Copyright (C) 2010 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see