mirror of
https://github.com/coreutils/coreutils.git
synced 2024-11-24 10:23:31 +08:00
cp: -a now preserves SELinux context, with reduced diagnostics
* copy.c (copy_reg): Reduce SELinux context diagnostics for 'cp -a'. (copy_internal): Likewise * copy.h (cp_options): Add boolean reduce_diagnostics. * cp.c (usage): Say that --archive (-a) behaves like -dR --preserve=all. (cp_option_init): Initialize added reduce_diagnostics. (main): Add reduce_diagnostics for the -a option, and preserve SELinux context, if possible. * mv.c (cp_options_init): Initialize new cp_options booleans. * install.c (cp_option_init): Likewise. * NEWS: Mention those behaviour changes. * doc/coreutils.texi: Document --preserve=context, document that diagnostics are not shown for failures of non-mandatory attributes (just SELinux at the moment). * tests/cp/cp-a-selinux: Check not only failures, but succesful use of preserving SELinux context in cp.
This commit is contained in:
parent
86cef85b36
commit
8c243ff965
5
NEWS
5
NEWS
@ -6,7 +6,7 @@ GNU coreutils NEWS -*- outline -*-
|
||||
|
||||
Add extended attribute support available on certain filesystems like ext2
|
||||
and XFS.
|
||||
cp: Tries to copy xattrs when --preserve=xattr specified
|
||||
cp: Tries to copy xattrs when --preserve=xattr or --preserve=all specified
|
||||
mv: Always tries to copy xattrs
|
||||
install: Never copies xattrs
|
||||
|
||||
@ -32,6 +32,9 @@ GNU coreutils NEWS -*- outline -*-
|
||||
|
||||
cp uses much less memory in some situations
|
||||
|
||||
cp -a now correctly tries to preserve SELinux context (announced in 6.9.90),
|
||||
doesn't inform about failure, unlike with --preserve=all
|
||||
|
||||
du --files0-from=FILE no longer reads all of FILE into RAM before
|
||||
processing the first file name
|
||||
|
||||
|
@ -7262,7 +7262,10 @@ Preserve as much as possible of the structure and attributes of the
|
||||
original files in the copy (but do not attempt to preserve internal
|
||||
directory structure; i.e., @samp{ls -U} may list the entries in a copied
|
||||
directory in a different order).
|
||||
Equivalent to @option{-dpR}.
|
||||
Try to preserve SELinux security context, but ignore any failure to do that
|
||||
and print no corresponding diagnostic.
|
||||
This option does not preserve extended attributes(xattr) at the moment.
|
||||
Equivalent to @option{-dR --preserve=all} with a few exceptions.
|
||||
|
||||
@item -b
|
||||
@itemx @w{@kbd{--backup}[=@var{method}]}
|
||||
@ -7404,6 +7407,9 @@ Preserve in the destination files
|
||||
any links between corresponding source files.
|
||||
@c Give examples illustrating how hard links are preserved.
|
||||
@c Also, show how soft links map to hard links with -L and -H.
|
||||
@itemx context
|
||||
Preserve SELinux security context of the file. @command{cp} will fail
|
||||
if the preserving of SELinux security context is not succesful.
|
||||
@itemx xattr
|
||||
Preserve extended attributes if @command{cp} is built with xattr support,
|
||||
and xattrs are supported and enabled on your file system.
|
||||
@ -7411,7 +7417,10 @@ If SELinux context and/or ACLs are implemented using xattrs,
|
||||
they are preserved by this option as well.
|
||||
@itemx all
|
||||
Preserve all file attributes.
|
||||
Equivalent to specifying all of the above.
|
||||
Equivalent to specifying all of the above, but with the difference
|
||||
that failure to preserve SELinux security context or extended attributes
|
||||
does not change @command{cp}'s exit status.
|
||||
@command{cp} does diagnose such failures.
|
||||
@end table
|
||||
|
||||
Using @option{--preserve} with no @var{attribute_list} is equivalent
|
||||
|
28
src/copy.c
28
src/copy.c
@ -450,7 +450,8 @@ copy_reg (char const *src_name, char const *dst_name,
|
||||
security_context_t con = NULL;
|
||||
if (getfscreatecon (&con) < 0)
|
||||
{
|
||||
error (0, errno, _("failed to get file system create context"));
|
||||
if (!x->reduce_diagnostics)
|
||||
error (0, errno, _("failed to get file system create context"));
|
||||
if (x->require_preserve_context)
|
||||
{
|
||||
return_val = false;
|
||||
@ -462,9 +463,10 @@ copy_reg (char const *src_name, char const *dst_name,
|
||||
{
|
||||
if (fsetfilecon (dest_desc, con) < 0)
|
||||
{
|
||||
error (0, errno,
|
||||
_("failed to set the security context of %s to %s"),
|
||||
quote_n (0, dst_name), quote_n (1, con));
|
||||
if (!x->reduce_diagnostics)
|
||||
error (0, errno,
|
||||
_("failed to set the security context of %s to %s"),
|
||||
quote_n (0, dst_name), quote_n (1, con));
|
||||
if (x->require_preserve_context)
|
||||
{
|
||||
return_val = false;
|
||||
@ -472,7 +474,7 @@ copy_reg (char const *src_name, char const *dst_name,
|
||||
goto close_src_and_dst_desc;
|
||||
}
|
||||
}
|
||||
freecon(con);
|
||||
freecon (con);
|
||||
}
|
||||
}
|
||||
|
||||
@ -495,7 +497,7 @@ copy_reg (char const *src_name, char const *dst_name,
|
||||
if (*new_dst)
|
||||
{
|
||||
int open_flags = O_WRONLY | O_CREAT | O_BINARY;
|
||||
dest_desc = open (dst_name, open_flags | O_EXCL ,
|
||||
dest_desc = open (dst_name, open_flags | O_EXCL,
|
||||
dst_mode & ~omitted_permissions);
|
||||
dest_errno = errno;
|
||||
|
||||
@ -1721,9 +1723,10 @@ copy_internal (char const *src_name, char const *dst_name,
|
||||
{
|
||||
if (setfscreatecon (con) < 0)
|
||||
{
|
||||
error (0, errno,
|
||||
_("failed to set default file creation context to %s"),
|
||||
quote (con));
|
||||
if (!x->reduce_diagnostics)
|
||||
error (0, errno,
|
||||
_("failed to set default file creation context to %s"),
|
||||
quote (con));
|
||||
if (x->require_preserve_context)
|
||||
{
|
||||
freecon (con);
|
||||
@ -1736,9 +1739,10 @@ copy_internal (char const *src_name, char const *dst_name,
|
||||
{
|
||||
if (errno != ENOTSUP && errno != ENODATA)
|
||||
{
|
||||
error (0, errno,
|
||||
_("failed to get security context of %s"),
|
||||
quote (src_name));
|
||||
if (!x->reduce_diagnostics)
|
||||
error (0, errno,
|
||||
_("failed to get security context of %s"),
|
||||
quote (src_name));
|
||||
if (x->require_preserve_context)
|
||||
return false;
|
||||
}
|
||||
|
@ -186,6 +186,12 @@ struct cp_options
|
||||
this flag is "true", while with "cp --preserve=all", it is false. */
|
||||
bool require_preserve_xattr;
|
||||
|
||||
/* Used as difference boolean between cp -a and cp -dR --preserve=all.
|
||||
If true, non-mandatory failure diagnostics are not displayed. This
|
||||
should prevent poluting cp -a output.
|
||||
*/
|
||||
bool reduce_diagnostics;
|
||||
|
||||
/* If true, copy directories recursively and copy special files
|
||||
as themselves rather than copying their contents. */
|
||||
bool recursive;
|
||||
|
8
src/cp.c
8
src/cp.c
@ -160,7 +160,7 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
|
||||
Mandatory arguments to long options are mandatory for short options too.\n\
|
||||
"), stdout);
|
||||
fputs (_("\
|
||||
-a, --archive same as -dpR\n\
|
||||
-a, --archive same as -dR --preserve=all\n\
|
||||
--backup[=CONTROL] make a backup of each existing destination file\n\
|
||||
-b like --backup but does not accept an argument\n\
|
||||
--copy-contents copy contents of special files when recursive\n\
|
||||
@ -766,6 +766,7 @@ cp_option_init (struct cp_options *x)
|
||||
x->preserve_security_context = false;
|
||||
x->require_preserve_context = false;
|
||||
x->preserve_xattr = false;
|
||||
x->reduce_diagnostics = false;
|
||||
x->require_preserve_xattr = false;
|
||||
|
||||
x->require_preserve = false;
|
||||
@ -921,13 +922,16 @@ main (int argc, char **argv)
|
||||
sparse_type_string, sparse_type);
|
||||
break;
|
||||
|
||||
case 'a': /* Like -dpR. */
|
||||
case 'a': /* Like -dR --preserve=all with reduced failure diagnostics. */
|
||||
x.dereference = DEREF_NEVER;
|
||||
x.preserve_links = true;
|
||||
x.preserve_ownership = true;
|
||||
x.preserve_mode = true;
|
||||
x.preserve_timestamps = true;
|
||||
x.require_preserve = true;
|
||||
if (selinux_enabled)
|
||||
x.preserve_security_context = true;
|
||||
x.reduce_diagnostics = true;
|
||||
x.recursive = true;
|
||||
break;
|
||||
|
||||
|
@ -289,8 +289,10 @@ cp_option_init (struct cp_options *x)
|
||||
x->preserve_links = false;
|
||||
x->preserve_mode = false;
|
||||
x->preserve_timestamps = false;
|
||||
x->reduce_diagnostics=false;
|
||||
x->require_preserve = false;
|
||||
x->require_preserve_context = false;
|
||||
x->require_preserve_xattr = false;
|
||||
x->recursive = false;
|
||||
x->sparse_mode = SPARSE_AUTO;
|
||||
x->symbolic_link = false;
|
||||
|
2
src/mv.c
2
src/mv.c
@ -122,9 +122,11 @@ cp_option_init (struct cp_options *x)
|
||||
x->preserve_mode = true;
|
||||
x->preserve_timestamps = true;
|
||||
x->preserve_security_context = selinux_enabled;
|
||||
x->reduce_diagnostics = false;
|
||||
x->require_preserve = false; /* FIXME: maybe make this an option */
|
||||
x->require_preserve_context = false;
|
||||
x->preserve_xattr = true;
|
||||
x->require_preserve_xattr = false;
|
||||
x->recursive = true;
|
||||
x->sparse_mode = SPARSE_AUTO; /* FIXME: maybe make this an option */
|
||||
x->symbolic_link = false;
|
||||
|
@ -1,8 +1,10 @@
|
||||
#!/bin/sh
|
||||
# Ensure that cp -a and cp --preserve=context work properly.
|
||||
# In particular, test on a writable NFS partition.
|
||||
# Check also locally if --preserve=context, -a and --preserve=all
|
||||
# does work
|
||||
|
||||
# Copyright (C) 2007-2008 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2007-2009 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
|
||||
@ -29,6 +31,21 @@ require_selinux_
|
||||
cwd=`pwd`
|
||||
cleanup_() { cd /; umount "$cwd/mnt"; }
|
||||
|
||||
# This context is special: it works even when mcstransd isn't running.
|
||||
ctx=root:object_r:tmp_t:s0
|
||||
|
||||
# Check basic functionality - before check on fixed context mount
|
||||
touch c || framework_failure
|
||||
chcon $ctx c || framework_failure
|
||||
cp -a c d 2>err || framework_failure
|
||||
cp --preserve=context c e || framework_failure
|
||||
cp --preserve=all c f || framework_failure
|
||||
ls -Z d | grep $ctx || fail=1
|
||||
test -s err && fail=1 #there must be no stderr output for -a
|
||||
ls -Z e | grep $ctx || fail=1
|
||||
ls -Z f | grep $ctx || fail=1
|
||||
|
||||
|
||||
# Create a file system, then mount it with the context=... option.
|
||||
dd if=/dev/zero of=blob bs=8192 count=200 > /dev/null 2>&1 \
|
||||
|| framework_failure
|
||||
@ -36,9 +53,6 @@ mkdir mnt || framework_failure
|
||||
mkfs -t ext2 -F blob ||
|
||||
skip_test_ "failed to create an ext2 file system"
|
||||
|
||||
# This context is special: it works even when mcstransd isn't running.
|
||||
ctx=root:object_r:tmp_t:s0
|
||||
|
||||
mount -oloop,context=$ctx blob mnt || framework_failure
|
||||
cd mnt || framework_failure
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user