-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 10/16/2012 09:32 AM, Jim Meyering wrote:
> Daniel J Walsh wrote:
>> On 10/09/2012 08:54 AM, Jim Meyering wrote:
>>> Pádraig Brady wrote:
>>>> On 10/08/2012 09:24 PM, Daniel J Walsh wrote:
> ...
>>> [in a follow-up]
>>>> Thinking further, --context without an option, is not too clear to
>>>> the user. They might think they were copying the original context
>>>> rather than setting a new context.
>>>
>>>> Pity the long option wasn't called --new-context. I suppose we could
>>>> have that as an alias for --context and deprecate the former?
>>>
>>> Sounds reasonable. Adjust the other --context=CTX commands, mkdir,
>>> mkfifo, mknod at the same time.
>>
>> I just want to make sure that you guys are expecting a patch from me?
>
> I am. That'd be great, especially if you can add NEWS entries and tests to
> exercise the new code.
>
Here is what I have thus far. Major problem I have not figured out yet is how
to get selinux.c code to work in the library, so it is hacked to just be
included as part of the selinux.h file.
Just looking to get feedback that I am not going down the wrong path.
Made -Z and --context take optional context for apps that have had these flags
for a while
mkdir, mkfifo, mknod and cp
Added -Z --context to mv without optional flag. ( I would love to dump the
optional flag but it has been in place for years.)
Not sure how man pages get created so I modified in patch. Also modified info
stuff.
Basically there are two new functions, restorecon which fixed file labels
after they are created, this is not optimal since there is a potential race
condition, but since mv does a rename this is all we can do.
defaultcon will tell SELinux what to label a file before it is created.
I have added the function mode_to_security_class to libselinux for Fedora 18,
but it is not in all versions of libselinux. I can back port this, but for
now left it in patch.
This patch is based off of fedora package, not sure if I should have merged
all SELinux changes into patch to send upstream.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://www.enigmail.net/
iEYEARECAAYFAlCBy7AACgkQrlYvE4MpobPloACbBa6uiXbKzUs50is4rylABr6u
lXAAmQGsBJ0RYCiHBcHcCPdmUGz84IjD
=Q+pd
-----END PGP SIGNATURE-----
diff -up coreutils-8.19/doc/coreutils.texi.restorecon coreutils-8.19/doc/coreutils.texi
--- coreutils-8.19/doc/coreutils.texi.restorecon 2012-10-19 17:41:30.073219080 -0400
+++ coreutils-8.19/doc/coreutils.texi 2012-10-19 17:41:31.151219479 -0400
@@ -8629,13 +8629,13 @@ Program used to strip binaries.
@opindex --verbose
Print the name of each file before copying it.
-@item -Z @var{context}
-@itemx --context=@var{context}
+@item -Z [@var{context}]
+@itemx --context[=@var{context}]
@opindex -Z
@opindex --context
@cindex SELinux
@cindex security context
-Set the default SELinux security context to be used for any
+Use the default SELinux security context or use specified context to be used for any
created files and directories. If SELinux is disabled then
print a warning and ignore the option.
@@ -8652,7 +8652,7 @@ print a warning and ignore the option.
@command{mv} moves or renames files (or directories). Synopses:
@example
-mv [@var{option}]@dots{} [-T] @var{source} @var{dest}
+mv [@var{option}]@dots{} [-Z] [-T] @var{source} @var{dest}
mv [@var{option}]@dots{} @var{source}@dots{} @var{directory}
mv [@var{option}]@dots{} -t @var{directory} @var{source}@dots{}
@end example
@@ -8762,6 +8762,15 @@ same source and destination.
@opindex --verbose
Print the name of each file before moving it.
+@item -Z [@var{context}]
+@itemx --context[=@var{context}]
+@opindex -Z
+@opindex --context
+@cindex SELinux
+@cindex security context
+Set the default SELinux security context on the destination. If SELinux is disabled then
+print a warning and ignore the option.
+
@optStripTrailingSlashes
@optBackupSuffix
@@ -9557,13 +9566,13 @@ newly-created parent directories are inh
Print a message for each created directory. This is most useful with
@option{--parents}.
-@item -Z @var{context}
-@itemx --context=@var{context}
+@item -Z [@var{context}]
+@itemx --context[=@var{context}]
@opindex -Z
@opindex --context
@cindex SELinux
@cindex security context
-Set the default SELinux security context to be used for created directories.
+Set the default SELinux security context or use specified context for created directories.
@end table
@@ -9604,13 +9613,13 @@ Set the mode of created FIFOs to @var{mo
for the point of departure. @var{mode} should specify only file
permission bits. @xref{File permissions}.
-@item -Z @var{context}
-@itemx --context=@var{context}
+@item -Z [@var{context}]
+@itemx --context[=@var{context}]
@opindex -Z
@opindex --context
@cindex SELinux
@cindex security context
-Set the default SELinux security context to be used for created FIFOs.
+Set the default SELinux security context or use specified context for created FIFOs.
@end table
@@ -9687,13 +9696,13 @@ Set the mode of created files to @var{mo
@var{mode} should specify only file permission bits.
@xref{File permissions}.
-@item -Z @var{context}
-@itemx --context=@var{context}
+@item -Z [@var{context}]
+@itemx --context[=@var{context}]
@opindex -Z
@opindex --context
@cindex SELinux
@cindex security context
-Set the default SELinux security context to be used for created files.
+Set the default SELinux security context or use specified context for created files.
@end table
diff -up coreutils-8.19/lib/selinux.c.restorecon coreutils-8.19/lib/selinux.c
--- coreutils-8.19/lib/selinux.c.restorecon 2012-10-19 15:37:13.460218486 -0400
+++ coreutils-8.19/lib/selinux.c 2012-10-19 15:37:13.461218487 -0400
@@ -0,0 +1,181 @@
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+#include <libgen.h>
+#include "fts.h"
+security_class_t mode_to_security_class(mode_t m) {
+
+ if (S_ISREG(m))
+ return string_to_security_class("file");
+ if (S_ISDIR(m))
+ return string_to_security_class("dir");
+ if (S_ISCHR(m))
+ return string_to_security_class("chr_file");
+ if (S_ISBLK(m))
+ return string_to_security_class("blk_file");
+ if (S_ISFIFO(m))
+ return string_to_security_class("fifo_file");
+ if (S_ISLNK(m))
+ return string_to_security_class("lnk_file");
+ if (S_ISSOCK(m))
+ return string_to_security_class("sock_file");
+
+ errno=EINVAL;
+ return 0;
+}
+
+static int computecon(char const *path, mode_t mode, security_context_t *con) {
+ security_context_t scon = NULL;
+ security_context_t tcon = NULL;
+ security_class_t tclass;
+ int rc = -1;
+
+ char *dir = strdup(path);
+ if (!dir)
+ goto quit;
+ if (getcon(&scon) < 0)
+ goto quit;
+ if (getfilecon(dirname((char *) dir), &tcon) < 0)
+ goto quit;
+ tclass = mode_to_security_class(mode);
+ if (!tclass)
+ goto quit;
+ rc = security_compute_create(scon, tcon, tclass, con);
+
+quit:
+ free(dir);
+ freecon(scon);
+ freecon(tcon);
+ return rc;
+}
+
+int defaultcon (char const *path, mode_t mode) {
+ int rc = -1;
+ struct stat sb;
+ security_context_t scon = NULL, tcon = NULL;
+ context_t scontext = NULL, tcontext = NULL;
+ int fd;
+
+ rc = matchpathcon(path, mode, &scon);
+ if (rc < 0)
+ goto quit;
+ rc = computecon(path, mode, &tcon);
+ if (rc < 0)
+ goto quit;
+ scontext = context_new(scon);
+ rc = -1;
+ if (!scontext)
+ goto quit;
+ tcontext = context_new(tcon);
+ if (!tcontext)
+ goto quit;
+
+ context_type_set(tcontext, context_type_get(scontext));
+ rc = setfscreatecon (context_str(tcontext));
+// printf("defaultcon %s %s\n", path, context_str(tcontext));
+quit:
+ close(fd);
+ if (scontext)
+ context_free(scontext);
+ if (scontext)
+ context_free(tcontext);
+ freecon(scon);
+ freecon(tcon);
+ return rc;
+}
+
+static int restorecon_private (char const *path) {
+ int rc = -1;
+ int link_file = false;
+ struct stat sb;
+ security_context_t scon = NULL, tcon = NULL;
+ context_t scontext = NULL, tcontext = NULL;
+ int fd;
+ fd = open (path, O_RDONLY | O_NOFOLLOW);
+ if (!fd && (errno != ELOOP))
+ goto quit;
+
+ if (fd) {
+ rc = fstat (fd, &sb);
+ if (rc < 0)
+ goto quit;
+ } else {
+ rc = lstat (path, &sb);
+ if (rc < 0)
+ goto quit;
+ }
+
+ rc = matchpathcon(path, sb.st_mode, &scon);
+ if (rc < 0)
+ goto quit;
+ scontext = context_new(scon);
+ rc = -1;
+ if (!scontext)
+ goto quit;
+
+ if (fd) {
+ rc = fgetfilecon (fd, &tcon);
+ if (!rc)
+ goto quit;
+ } else {
+ rc = lgetfilecon (path, &tcon);
+ if (!rc)
+ goto quit;
+ }
+ tcontext = context_new(tcon);
+ if (!tcontext)
+ goto quit;
+
+ context_type_set(tcontext, context_type_get(scontext));
+
+ if (fd)
+ rc = fsetfilecon (fd, context_str(tcontext));
+ else
+ rc = lsetfilecon (path, context_str(tcontext));
+
+// printf("restorcon %s %s\n", path, context_str(tcontext));
+quit:
+ close(fd);
+ if (scontext)
+ context_free(scontext);
+ if (scontext)
+ context_free(tcontext);
+ freecon(scon);
+ freecon(tcon);
+ return rc;
+}
+
+int restorecon (char const *path, int recurse) {
+ if (!recurse)
+ return restorecon_private(path);
+ const char *mypath[2] = { path, NULL };
+
+ FTS *fts = fts_open ((char *const *)mypath, FTS_PHYSICAL, NULL);
+ bool ok = true;
+
+ while (1)
+ {
+ FTSENT *ent;
+
+ ent = fts_read (fts);
+ if (ent == NULL)
+ {
+ if (errno != 0)
+ {
+ /* FIXME: try to give a better message */
+ error (0, errno, _("fts_read failed"));
+ ok = false;
+ }
+ break;
+ }
+
+ ok &= restorecon_private(fts->fts_path);
+ }
+
+ if (fts_close (fts) != 0)
+ {
+ error (0, errno, _("fts_close failed"));
+ ok = false;
+ }
+
+ return ok;
+}
diff -up coreutils-8.19/lib/selinux.h.restorecon coreutils-8.19/lib/selinux.h
--- coreutils-8.19/lib/selinux.h.restorecon 2012-10-19 15:37:13.461218487 -0400
+++ coreutils-8.19/lib/selinux.h 2012-10-19 15:37:13.462218488 -0400
@@ -0,0 +1,28 @@
+/* Handle SELinux Labeling
+
+ Copyright (C) 2012 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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Daniel Walsh <[email protected]>. */
+
+#ifndef _GL_SELINUX_H
+#define _GL_SELINUX_H
+
+#include <sys/stat.h>
+int restorecon (char const *path, int recurse);
+int defaultcon (char const *path, mode_t mode);
+#include "selinux.c"
+#endif
diff -up coreutils-8.19/man/cp.1.restorecon coreutils-8.19/man/cp.1
--- coreutils-8.19/man/cp.1.restorecon 2012-08-20 02:14:14.000000000 -0400
+++ coreutils-8.19/man/cp.1 2012-10-19 17:14:38.831525002 -0400
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.35.
-.TH CP "1" "August 2012" "GNU coreutils 8.19" "User Commands"
+.TH CP "1" "October 2012" "GNU coreutils 8.19" "User Commands"
.SH NAME
cp \- copy files and directories
.SH SYNOPSIS
@@ -70,6 +70,9 @@ mode,ownership,timestamps), if possible
additional attributes: context, links, xattr,
all
.TP
+\fB\-c\fR
+same as \fB\-\-preserve\fR=\fIcontext\fR
+.TP
\fB\-\-no\-preserve\fR=\fIATTR_LIST\fR
don't preserve the specified attributes
.TP
@@ -116,6 +119,9 @@ explain what is being done
\fB\-x\fR, \fB\-\-one\-file\-system\fR
stay on this file system
.TP
+\fB\-Z\fR, \fB\-\-context[\fR=\fICONTEXT\fR]
+set default SELinux security context or specified CONTEXT on DEST
+.TP
\fB\-\-help\fR
display this help and exit
.TP
diff -up coreutils-8.19/man/mkdir.1.restorecon coreutils-8.19/man/mkdir.1
--- coreutils-8.19/man/mkdir.1.restorecon 2012-08-20 02:14:14.000000000 -0400
+++ coreutils-8.19/man/mkdir.1 2012-10-19 17:16:15.433585135 -0400
@@ -21,9 +21,9 @@ no error if existing, make parent direct
\fB\-v\fR, \fB\-\-verbose\fR
print a message for each created directory
.TP
-\fB\-Z\fR, \fB\-\-context\fR=\fICTX\fR
-set the SELinux security context of each created
-directory to CTX
+\fB\-Z\fR, \fB\-\-context\fR[=\fICTX\fR]
+set default SELinux security context or specified CTX on each created
+directory
.TP
\fB\-\-help\fR
display this help and exit
diff -up coreutils-8.19/man/mkfifo.1.restorecon coreutils-8.19/man/mkfifo.1
--- coreutils-8.19/man/mkfifo.1.restorecon 2012-08-20 02:14:14.000000000 -0400
+++ coreutils-8.19/man/mkfifo.1 2012-10-19 17:16:39.195594030 -0400
@@ -15,8 +15,9 @@ Mandatory arguments to long options are
\fB\-m\fR, \fB\-\-mode\fR=\fIMODE\fR
set file permission bits to MODE, not a=rw \- umask
.TP
-\fB\-Z\fR, \fB\-\-context\fR=\fICTX\fR
-set the SELinux security context of each NAME to CTX
+\fB\-Z\fR, \fB\-\-context\fR[=\fICTX\fR]
+set default SELinux security context or specified CTX on each created
+fifo
.TP
\fB\-\-help\fR
display this help and exit
diff -up coreutils-8.19/man/mknod.1.restorecon coreutils-8.19/man/mknod.1
--- coreutils-8.19/man/mknod.1.restorecon 2012-08-20 02:14:14.000000000 -0400
+++ coreutils-8.19/man/mknod.1 2012-10-19 17:17:51.271623069 -0400
@@ -15,8 +15,9 @@ Mandatory arguments to long options are
\fB\-m\fR, \fB\-\-mode\fR=\fIMODE\fR
set file permission bits to MODE, not a=rw \- umask
.TP
-\fB\-Z\fR, \fB\-\-context\fR=\fICTX\fR
-set the SELinux security context of NAME to CTX
+\fB\-Z\fR, \fB\-\-context\fR[=\fICTX\fR]
+set default SELinux security context or specified CTX on each created
+special file
.TP
\fB\-\-help\fR
display this help and exit
diff -up coreutils-8.19/man/mv.1.restorecon coreutils-8.19/man/mv.1
--- coreutils-8.19/man/mv.1.restorecon 2012-10-19 17:08:27.601158408 -0400
+++ coreutils-8.19/man/mv.1 2012-10-19 17:11:47.591357536 -0400
@@ -56,6 +56,9 @@ destination file is missing
\fB\-v\fR, \fB\-\-verbose\fR
explain what is being done
.TP
+\fB\-Z\fR, \fB\-\-context
+set default SELinux security context on DEST
+.TP
\fB\-\-help\fR
display this help and exit
.TP
diff -up coreutils-8.19/src/copy.c.restorecon coreutils-8.19/src/copy.c
--- coreutils-8.19/src/copy.c.restorecon 2012-10-19 15:37:13.452218478 -0400
+++ coreutils-8.19/src/copy.c 2012-10-19 15:37:13.466218492 -0400
@@ -22,6 +22,7 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <selinux/selinux.h>
+#include <selinux/context.h>
#if HAVE_HURD_H
# include <hurd.h>
@@ -60,6 +61,7 @@
#include "write-any-file.h"
#include "areadlink.h"
#include "yesno.h"
+#include "selinux.h"
#if USE_XATTR
# include <attr/error_context.h>
@@ -844,34 +846,37 @@ copy_reg (char const *src_name, char con
bool some_errors = !all_errors && !x->reduce_diagnostics;
security_context_t con = NULL;
- if (getfscreatecon (&con) < 0)
- {
- if (all_errors || (some_errors && !errno_unsupported (errno)))
- error (0, errno, _("failed to get file system create context"));
- if (x->require_preserve_context)
- {
- return_val = false;
- goto close_src_and_dst_desc;
- }
- }
+ if (x->preserve_security_context) {
+ if (getfscreatecon (&con) < 0)
+ {
+ if (all_errors || (some_errors && !errno_unsupported (errno)))
+ error (0, errno, _("failed to get file system create context"));
+ return_val = false;
+ goto close_src_and_dst_desc;
+ }
+ } else {
+ if (matchpathcon(dst_name, dst_mode, &con) < 0) {
+ if (all_errors || (some_errors && !errno_unsupported (errno)))
+ error (0, errno, _("failed to get file system create context"));
+ return_val = false;
+ goto close_src_and_dst_desc;
+ }
+ }
- if (con)
- {
- if (fsetfilecon (dest_desc, con) < 0)
- {
+ if (fsetfilecon (dest_desc, con) < 0)
+ {
if (all_errors || (some_errors && !errno_unsupported (errno)))
- error (0, errno,
- _("failed to set the security context of %s to %s"),
- quote_n (0, dst_name), quote_n (1, con));
+ 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;
- freecon (con);
- goto close_src_and_dst_desc;
- }
- }
- freecon (con);
- }
+ {
+ return_val = false;
+ freecon (con);
+ goto close_src_and_dst_desc;
+ }
+ }
+ freecon (con);
}
if (dest_desc < 0 && x->unlink_dest_after_failed_open)
@@ -892,6 +897,9 @@ copy_reg (char const *src_name, char con
if (*new_dst)
{
+ if (x->set_security_context && (! x->require_preserve_context))
+ defaultcon(dst_name, dst_mode);
+
open_with_O_CREAT:;
int open_flags = O_WRONLY | O_CREAT | O_BINARY;
@@ -936,6 +944,7 @@ copy_reg (char const *src_name, char con
if (dest_desc < 0 && dest_errno == EISDIR
&& *dst_name && dst_name[strlen (dst_name) - 1] == '/')
dest_errno = ENOTDIR;
+
}
else
{
@@ -974,6 +983,9 @@ copy_reg (char const *src_name, char con
goto close_src_and_dst_desc;
}
+ if (x->set_security_context && ! x->preserve_security_context)
+ restorecon(dst_name, 1);
+
/* --attributes-only overrides --reflink. */
if (data_copy_required && x->reflink_mode)
{
@@ -2087,6 +2099,9 @@ copy_internal (char const *src_name, cha
emit_verbose (src_name, dst_name,
backup_succeeded ? dst_backup : NULL);
+ if (x->set_security_context)
+ restorecon(dst_name, 1);
+
if (rename_succeeded)
*rename_succeeded = true;
@@ -2226,6 +2241,11 @@ copy_internal (char const *src_name, cha
return false;
}
}
+ else
+ {
+ if (x->set_security_context)
+ restorecon(dst_name, 1);
+ }
if (S_ISDIR (src_mode))
{
diff -up coreutils-8.19/src/cp.c.restorecon coreutils-8.19/src/cp.c
--- coreutils-8.19/src/cp.c.restorecon 2012-10-19 15:37:13.453218479 -0400
+++ coreutils-8.19/src/cp.c 2012-10-19 15:37:13.467218493 -0400
@@ -141,7 +141,7 @@ static struct option const long_opts[] =
{"target-directory", required_argument, NULL, 't'},
{"update", no_argument, NULL, 'u'},
{"verbose", no_argument, NULL, 'v'},
- {"context", required_argument, NULL, 'Z'},
+ {GETOPT_SELINUX_CONTEXT_OPTION_DECL},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -233,7 +233,7 @@ Mandatory arguments to long options are
destination file is missing\n\
-v, --verbose explain what is being done\n\
-x, --one-file-system stay on this file system\n\
- -Z, --context=CONTEXT set security context of copy to CONTEXT\n\
+ -Z, --context[=CONTEXT] set security context of destination file to default type or to CONTEXT if specified\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -881,8 +881,10 @@ decode_preserve_arg (char const *arg, st
break;
case PRESERVE_CONTEXT:
- x->preserve_security_context = on_off;
- x->require_preserve_context = on_off;
+ if (! x->set_security_context) {
+ x->preserve_security_context = on_off;
+ x->require_preserve_context = on_off;
+ }
break;
case PRESERVE_XATTR:
@@ -895,7 +897,7 @@ decode_preserve_arg (char const *arg, st
x->preserve_timestamps = on_off;
x->preserve_ownership = on_off;
x->preserve_links = on_off;
- if (selinux_enabled)
+ if (selinux_enabled && (! x->set_security_context))
x->preserve_security_context = on_off;
x->preserve_xattr = on_off;
break;
@@ -938,7 +940,7 @@ main (int argc, char **argv)
we'll actually use backup_suffix_string. */
backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
- while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ:",
+ while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ::",
long_opts, NULL))
!= -1)
{
@@ -965,7 +967,7 @@ main (int argc, char **argv)
x.preserve_mode = true;
x.preserve_timestamps = true;
x.require_preserve = true;
- if (selinux_enabled)
+ if (selinux_enabled && (! x.set_security_context))
x.preserve_security_context = true;
x.preserve_xattr = true;
x.reduce_diagnostics = true;
@@ -1113,18 +1115,16 @@ main (int argc, char **argv)
"It requires a SELinux enabled kernel.\n" );
break;
}
- if ( x.preserve_security_context ) {
- (void) fprintf(stderr, "%s: cannot force target context to '%s' and preserve it\n", argv[0], optarg);
- exit( 1 );
- }
+ if (optarg) {
+ /* if there's a security_context given set new path
+ components to that context, too */
+ if ( setfscreatecon(optarg) < 0 ) {
+ (void) fprintf(stderr, _("cannot set default security context %s\n"), optarg);
+ exit( 1 );
+ }
+ }
x.set_security_context = true;
- (void) fprintf(stderr, _("Warning, -Z/--context option is deprecated and will be removed soon!\nPlease use 'install' utility instead of cp for this functionality.\n"));
- /* if there's a security_context given set new path
- components to that context, too */
- if ( setfscreatecon(optarg) < 0 ) {
- (void) fprintf(stderr, _("cannot set default security context %s\n"), optarg);
- exit( 1 );
- }
+ x.preserve_security_context = false;
break;
case 'S':
diff -up coreutils-8.19/src/install.c.restorecon coreutils-8.19/src/install.c
--- coreutils-8.19/src/install.c.restorecon 2012-10-19 15:37:13.415218441 -0400
+++ coreutils-8.19/src/install.c 2012-10-19 15:37:13.468218494 -0400
@@ -641,7 +641,7 @@ Mandatory arguments to long options are
"), stdout);
fputs (_("\
-P, --preserve-context preserve SELinux security context\n\
- -Z, --context=CONTEXT set SELinux security context of files and directories\
+ -Z, --context[=CONTEXT] set SELinux security context of files and directories\
\n\
"), stdout);
@@ -783,7 +783,7 @@ main (int argc, char **argv)
we'll actually use backup_suffix_string. */
backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
- while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z:", long_options,
+ while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z::", long_options,
NULL)) != -1)
{
switch (optc)
@@ -861,12 +861,11 @@ main (int argc, char **argv)
"this kernel is not SELinux-enabled"));
break;
}
- if ( x.set_security_context ) {
+ if ( x.set_security_context || scontext ) {
(void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]);
exit( 1 );
}
x.preserve_security_context = true;
- use_default_selinux_context = false;
break;
case 'Z':
if ( ! selinux_enabled)
@@ -875,9 +874,10 @@ main (int argc, char **argv)
"this kernel is not SELinux-enabled"));
break;
}
- scontext = optarg;
- x.set_security_context = true;
- use_default_selinux_context = false;
+ if (optarg)
+ scontext = optarg;
+ else
+ x.set_security_context = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
diff -up coreutils-8.19/src/mkdir.c.restorecon coreutils-8.19/src/mkdir.c
--- coreutils-8.19/src/mkdir.c.restorecon 2012-10-19 15:37:13.420218446 -0400
+++ coreutils-8.19/src/mkdir.c 2012-10-19 15:37:13.469218495 -0400
@@ -29,6 +29,7 @@
#include "prog-fprintf.h"
#include "quote.h"
#include "savewd.h"
+#include "selinux.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "mkdir"
@@ -38,7 +39,6 @@
static struct option const longopts[] =
{
{GETOPT_SELINUX_CONTEXT_OPTION_DECL},
- {"context", required_argument, NULL, 'Z'},
{"mode", required_argument, NULL, 'm'},
{"parents", no_argument, NULL, 'p'},
{"verbose", no_argument, NULL, 'v'},
@@ -66,8 +66,8 @@ Mandatory arguments to long options are
-m, --mode=MODE set file mode (as in chmod), not a=rwx - umask\n\
-p, --parents no error if existing, make parent directories as needed\n\
-v, --verbose print a message for each created directory\n\
- -Z, --context=CTX set the SELinux security context of each created\n\
- directory to CTX\n\
+ -Z, --context[=CTX] set the SELinux security context of each created\n\
+ directory to default type or to CTX if specified\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -92,6 +92,9 @@ struct mkdir_options
/* File mode bits affected by MODE. */
mode_t mode_bits;
+ /* Set the SELinux File Context. */
+ int set_security_context;
+
/* If not null, format to use when reporting newly made directories. */
char const *created_directory_format;
};
@@ -114,6 +117,9 @@ static int
make_ancestor (char const *dir, char const *component, void *options)
{
struct mkdir_options const *o = options;
+
+ if (o->set_security_context)
+ defaultcon(dir, S_IFDIR);
int r = mkdir (component, o->ancestor_mode);
if (r == 0)
{
@@ -147,6 +153,7 @@ main (int argc, char **argv)
options.mode = S_IRWXUGO;
options.mode_bits = 0;
options.created_directory_format = NULL;
+ options.set_security_context = false;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -156,7 +163,7 @@ main (int argc, char **argv)
atexit (close_stdout);
- while ((optc = getopt_long (argc, argv, "pm:vZ:", longopts, NULL)) != -1)
+ while ((optc = getopt_long (argc, argv, "pm:vZ::", longopts, NULL)) != -1)
{
switch (optc)
{
@@ -170,7 +177,10 @@ main (int argc, char **argv)
options.created_directory_format = _("created directory %s");
break;
case 'Z':
- scontext = optarg;
+ if (optarg)
+ scontext = optarg;
+ else
+ options.set_security_context = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
diff -up coreutils-8.19/src/mkfifo.c.restorecon coreutils-8.19/src/mkfifo.c
--- coreutils-8.19/src/mkfifo.c.restorecon 2012-07-21 10:54:31.000000000 -0400
+++ coreutils-8.19/src/mkfifo.c 2012-10-19 15:37:13.470218496 -0400
@@ -26,6 +26,7 @@
#include "error.h"
#include "modechange.h"
#include "quote.h"
+#include "selinux.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "mkfifo"
@@ -60,7 +61,7 @@ Mandatory arguments to long options are
-m, --mode=MODE set file permission bits to MODE, not a=rw - umask\n\
"), stdout);
fputs (_("\
- -Z, --context=CTX set the SELinux security context of each NAME to CTX\n\
+ -Z, --context[=CTX] set the SELinux security context of each NAME to default type or CTX if specified\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -74,6 +75,7 @@ main (int argc, char **argv)
{
mode_t newmode;
char const *specified_mode = NULL;
+ int set_security_context = false;
int exit_status = EXIT_SUCCESS;
int optc;
security_context_t scontext = NULL;
@@ -86,7 +88,7 @@ main (int argc, char **argv)
atexit (close_stdout);
- while ((optc = getopt_long (argc, argv, "m:Z:", longopts, NULL)) != -1)
+ while ((optc = getopt_long (argc, argv, "m:Z::", longopts, NULL)) != -1)
{
switch (optc)
{
@@ -94,7 +96,10 @@ main (int argc, char **argv)
specified_mode = optarg;
break;
case 'Z':
- scontext = optarg;
+ if (optarg)
+ scontext = optarg;
+ else
+ set_security_context = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -128,6 +133,8 @@ main (int argc, char **argv)
}
for (; optind < argc; ++optind)
+ if (set_security_context)
+ defaultcon(argv[optind], S_IFIFO);
if (mkfifo (argv[optind], newmode) != 0)
{
error (0, errno, _("cannot create fifo %s"), quote (argv[optind]));
diff -up coreutils-8.19/src/mknod.c.restorecon coreutils-8.19/src/mknod.c
--- coreutils-8.19/src/mknod.c.restorecon 2012-10-19 15:37:13.420218446 -0400
+++ coreutils-8.19/src/mknod.c 2012-10-19 15:37:13.471218497 -0400
@@ -27,6 +27,7 @@
#include "modechange.h"
#include "quote.h"
#include "xstrtol.h"
+#include "selinux.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "mknod"
@@ -62,7 +63,7 @@ Mandatory arguments to long options are
-m, --mode=MODE set file permission bits to MODE, not a=rw - umask\n\
"), stdout);
fputs (_("\
- -Z, --context=CTX set the SELinux security context of NAME to CTX\n\
+ -Z, --context[=CTX] set the SELinux security context of NAME to default type or to CTX if specified\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -94,6 +95,7 @@ main (int argc, char **argv)
int expected_operands;
mode_t node_type;
security_context_t scontext = NULL;
+ int set_security_context = false;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -103,7 +105,7 @@ main (int argc, char **argv)
atexit (close_stdout);
- while ((optc = getopt_long (argc, argv, "m:Z:", longopts, NULL)) != -1)
+ while ((optc = getopt_long (argc, argv, "m:Z::", longopts, NULL)) != -1)
{
switch (optc)
{
@@ -111,7 +113,10 @@ main (int argc, char **argv)
specified_mode = optarg;
break;
case 'Z':
- scontext = optarg;
+ if (optarg)
+ scontext = optarg;
+ else
+ set_security_context = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -212,6 +217,9 @@ main (int argc, char **argv)
error (EXIT_FAILURE, 0, _("invalid device %s %s"), s_major, s_minor);
#endif
+ if (set_security_context)
+ defaultcon(argv[optind], node_type);
+
if (mknod (argv[optind], newmode | node_type, device) != 0)
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
}
diff -up coreutils-8.19/src/mv.c.restorecon coreutils-8.19/src/mv.c
--- coreutils-8.19/src/mv.c.restorecon 2012-10-19 15:37:13.421218447 -0400
+++ coreutils-8.19/src/mv.c 2012-10-19 15:37:13.472218498 -0400
@@ -55,6 +55,7 @@ static bool remove_trailing_slashes;
static struct option const long_options[] =
{
{"backup", optional_argument, NULL, 'b'},
+ {"context", no_argument, NULL, 'Z'},
{"force", no_argument, NULL, 'f'},
{"interactive", no_argument, NULL, 'i'},
{"no-clobber", no_argument, NULL, 'n'},
@@ -351,6 +352,7 @@ main (int argc, char **argv)
bool no_target_directory = false;
int n_files;
char **file;
+ bool selinux_enabled = (0 < is_selinux_enabled ());
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -369,7 +371,7 @@ main (int argc, char **argv)
we'll actually use backup_suffix_string. */
backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
- while ((c = getopt_long (argc, argv, "bfint:uvS:T", long_options, NULL))
+ while ((c = getopt_long (argc, argv, "bfint:uvS:TZ", long_options, NULL))
!= -1)
{
switch (c)
@@ -418,6 +420,16 @@ main (int argc, char **argv)
make_backups = true;
backup_suffix_string = optarg;
break;
+ case 'Z':
+ /* politely decline if we're not on a selinux-enabled kernel. */
+ if( !selinux_enabled ) {
+ fprintf( stderr, "Warning: ignoring --context (-Z). "
+ "It requires a SELinux enabled kernel.\n" );
+ break;
+ }
+ x.preserve_security_context = false;
+ x.set_security_context = true;
+ break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
diff -up coreutils-8.19/src/system.h.restorecon coreutils-8.19/src/system.h
--- coreutils-8.19/src/system.h.restorecon 2012-07-23 06:05:16.000000000 -0400
+++ coreutils-8.19/src/system.h 2012-10-19 15:37:13.473218499 -0400
@@ -330,7 +330,7 @@ enum
#define GETOPT_VERSION_OPTION_DECL \
"version", no_argument, NULL, GETOPT_VERSION_CHAR
#define GETOPT_SELINUX_CONTEXT_OPTION_DECL \
- "context", required_argument, NULL, 'Z'
+ "context", optional_argument, NULL, 'Z'
#define case_GETOPT_HELP_CHAR \
case GETOPT_HELP_CHAR: \