summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/copy.c21
-rw-r--r--src/copy.h22
-rw-r--r--src/cp.c2
-rw-r--r--src/install.c1
-rw-r--r--src/mv.c1
5 files changed, 35 insertions, 12 deletions
diff --git a/src/copy.c b/src/copy.c
index f60fa55bd..d2088ae46 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -310,8 +310,11 @@ copy_reg (char const *src_name, char const *dst_name,
if (getfscreatecon (&con) < 0)
{
error (0, errno, _("failed to get file system create context"));
- return_val = false;
- goto close_src_desc;
+ if (x->require_preserve_context)
+ {
+ return_val = false;
+ goto close_src_desc;
+ }
}
if (con)
@@ -321,9 +324,12 @@ copy_reg (char const *src_name, char const *dst_name,
error (0, errno,
_("failed to set the security context of %s to %s"),
quote_n (0, dst_name), quote_n (1, con));
- return_val = false;
- freecon (con);
- goto close_src_desc;
+ if (x->require_preserve_context)
+ {
+ return_val = false;
+ freecon (con);
+ goto close_src_desc;
+ }
}
freecon(con);
}
@@ -1590,7 +1596,7 @@ copy_internal (char const *src_name, char const *dst_name,
error (0, errno,
_("failed to set default file creation context to %s"),
quote (con));
- if (x->require_preserve)
+ if (x->require_preserve_context)
{
freecon (con);
return false;
@@ -1605,7 +1611,8 @@ copy_internal (char const *src_name, char const *dst_name,
error (0, errno,
_("failed to get security context of %s"),
quote (src_name));
- return false;
+ if (x->require_preserve_context)
+ return false;
}
}
}
diff --git a/src/copy.h b/src/copy.h
index eab6c8678..0d6233f95 100644
--- a/src/copy.h
+++ b/src/copy.h
@@ -127,9 +127,6 @@ struct cp_options
bool preserve_ownership;
bool preserve_mode;
bool preserve_timestamps;
- /* If true, attempt to preserve the SELinux security context, too.
- Set this only if the kernel is SELinux enabled. */
- bool preserve_security_context;
/* Enabled for mv, and for cp by the --preserve=links option.
If true, attempt to preserve in the destination files any
@@ -145,10 +142,25 @@ struct cp_options
/* If true and any of the above (for preserve) file attributes cannot
be applied to a destination file, treat it as a failure and return
- nonzero immediately. E.g. cp -p requires this be nonzero, mv requires
- it be zero. */
+ nonzero immediately. E.g. for cp -p this must be true, for mv it
+ must be false. */
bool require_preserve;
+ /* If true, attempt to preserve the SELinux security context, too.
+ Set this only if the kernel is SELinux enabled. */
+ bool preserve_security_context;
+
+ /* Useful only when preserve_security_context is true.
+ If true, a failed attempt to preserve a file's security context
+ propagates failure "out" to the caller. If false, a failure to
+ preserve a file's security context does not change the invoking
+ application's exit status. Give diagnostics for failed syscalls
+ regardless of this setting. For example, with "cp --preserve=context"
+ this flag is "true", while with "cp -a", it is false. That means
+ "cp -a" attempts to preserve any security context, but does not
+ fail if it is unable to do so. */
+ bool require_preserve_context;
+
/* If true, copy directories recursively and copy special files
as themselves rather than copying their contents. */
bool recursive;
diff --git a/src/cp.c b/src/cp.c
index c63e047d9..35c487b9f 100644
--- a/src/cp.c
+++ b/src/cp.c
@@ -754,6 +754,7 @@ cp_option_init (struct cp_options *x)
x->preserve_mode = false;
x->preserve_timestamps = false;
x->preserve_security_context = false;
+ x->require_preserve_context = false;
x->require_preserve = false;
x->recursive = false;
@@ -832,6 +833,7 @@ decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)
case PRESERVE_CONTEXT:
x->preserve_security_context = on_off;
+ x->require_preserve_context = on_off;
break;
case PRESERVE_ALL:
diff --git a/src/install.c b/src/install.c
index f6152f355..dc7ff0141 100644
--- a/src/install.c
+++ b/src/install.c
@@ -174,6 +174,7 @@ cp_option_init (struct cp_options *x)
x->preserve_mode = false;
x->preserve_timestamps = false;
x->require_preserve = false;
+ x->require_preserve_context = false;
x->recursive = false;
x->sparse_mode = SPARSE_AUTO;
x->symbolic_link = false;
diff --git a/src/mv.c b/src/mv.c
index 90387f79b..5ffe2ae23 100644
--- a/src/mv.c
+++ b/src/mv.c
@@ -131,6 +131,7 @@ cp_option_init (struct cp_options *x)
x->preserve_timestamps = true;
x->preserve_security_context = selinux_enabled;
x->require_preserve = false; /* FIXME: maybe make this an option */
+ x->require_preserve_context = false;
x->recursive = true;
x->sparse_mode = SPARSE_AUTO; /* FIXME: maybe make this an option */
x->symbolic_link = false;