1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-08-05 16:19:23 +02:00

maint: port from matchpathcon to selabel_lookup

Ubuntu 20.10 is using a newer version of libselinux that
complains that matchpathcon is obsolete.  Rewrite the code
that it uses the recommended selabel_lookup instead.
* m4/jm-macros.m4 (coreutils_MACROS): Do not check for
matchpathcon_init_prefix, as it is no longer used.
* src/copy.c (set_file_security_ctx): Omit process_local arg,
as it is equivalent to !x->set_security_context.  All callers changed.
* src/copy.h (struct cp_options): set_security_context is now of
type struct selabel_handle *, not bool.  All uses changed.
* src/cp.c, src/install.c, src/mkdir.c, src/mkfifo.c, src/mknod.c:
* src/mv.c: Include selinux/label.h.
(main): Use selabel_open for set_security context.
* src/install.c (matchpathcon_init_prefix): Remove; now unused.
(get_labeling_handle): New static function.
(setdefaultfilecon, main): Use it.
(setdefaultfilecon): Do something regardless of
ENABLE_MATCHPATHCON, which seems to be a revenant macro.
(setdefaultfilecon): Use selabel_lookup instead of the obsolescent
matchpathcon.  Report an error unless it fails due to ENOENT.
* src/local.mk (src_ginstall_CPPFLAGS): Remove.
* src/selinux.c: Include selinux/label.h
Do not include die.h, error.h, canonicalize.h.
(defaultcon, restorecon_private, restorecon):
New arg HANDLE.  All callers changed.
Use selabel_lookup rather than matchpathcon.
(restorecon_private, restorecon): Don’t lose track of errno.
* src/selinux.c, src/selinux.h:
(restorecon): Don’t call ‘error’; that’s the caller’s job.
Use HAVE_SELINUX_LABEL_H, not HAVE_SELINUX_SELINUX_H,
in case there is some weird system with the former but not the latter.
* src/selinux.h (struct selinux_handle): Add forward decl.
This commit is contained in:
Paul Eggert
2020-11-21 16:59:25 -08:00
parent 5c8e2716b3
commit 3aaa42deaa
12 changed files with 144 additions and 216 deletions
+1 -16
View File
@@ -1,4 +1,4 @@
#serial 111 -*- autoconf -*-
#serial 112 -*- autoconf -*-
dnl Misc type-related macros for coreutils.
@@ -52,21 +52,6 @@ AC_DEFUN([coreutils_MACROS],
LIBS="$LIBS $LIB_SELINUX"
# Used by selinux.c.
AC_CHECK_FUNCS([mode_to_security_class], [], [])
# Used by install.c.
AC_CHECK_FUNCS([matchpathcon_init_prefix], [],
[
if test "$with_selinux" != no; then
case "$ac_cv_search_setfilecon:$ac_cv_header_selinux_selinux_h" in
no:*) # SELinux disabled
;;
*:no) # SELinux disabled
;;
*)
AC_MSG_WARN([SELinux enabled, but matchpathcon_init_prefix not found])
AC_MSG_WARN([The install utility may run slowly])
esac
fi
])
LIBS=$coreutils_saved_libs
# Used by sort.c.
+10 -13
View File
@@ -1141,7 +1141,7 @@ set_process_security_ctx (char const *src_name, char const *dst_name,
{
/* With -Z, adjust the default context for the process
to have the type component adjusted as per the destination path. */
if (new_dst && defaultcon (dst_name, mode) < 0
if (new_dst && defaultcon (x->set_security_context, dst_name, mode) < 0
&& ! ignorable_ctx_err (errno))
{
error (0, errno,
@@ -1154,21 +1154,21 @@ set_process_security_ctx (char const *src_name, char const *dst_name,
}
/* Reset the security context of DST_NAME, to that already set
as the process default if PROCESS_LOCAL is true. Otherwise
as the process default if !X->set_security_context. Otherwise
adjust the type component of DST_NAME's security context as
per the system default for that path. Issue warnings upon
failure, when allowed by various settings in CP_OPTIONS.
Return FALSE on failure, TRUE on success. */
failure, when allowed by various settings in X.
Return false on failure, true on success. */
bool
set_file_security_ctx (char const *dst_name, bool process_local,
set_file_security_ctx (char const *dst_name,
bool recurse, const struct cp_options *x)
{
bool all_errors = (!x->data_copy_required
|| x->require_preserve_context);
bool some_errors = !all_errors && !x->reduce_diagnostics;
if (! restorecon (dst_name, recurse, process_local))
if (! restorecon (x->set_security_context, dst_name, recurse))
{
if (all_errors || (some_errors && !errno_unsupported (errno)))
error (0, errno, _("failed to set the security context of %s"),
@@ -1330,8 +1330,7 @@ copy_reg (char const *src_name, char const *dst_name,
if ((x->set_security_context || x->preserve_security_context)
&& 0 <= dest_desc)
{
if (! set_file_security_ctx (dst_name, x->preserve_security_context,
false, x))
if (! set_file_security_ctx (dst_name, false, x))
{
if (x->require_preserve_context)
{
@@ -2609,7 +2608,7 @@ copy_internal (char const *src_name, char const *dst_name,
if (x->set_security_context)
{
/* -Z failures are only warnings currently. */
(void) set_file_security_ctx (dst_name, false, true, x);
(void) set_file_security_ctx (dst_name, true, x);
}
if (rename_succeeded)
@@ -2819,8 +2818,7 @@ copy_internal (char const *src_name, char const *dst_name,
descendents, so use it to set the context for existing dirs here.
This will also give earlier indication of failure to set ctx. */
if (x->set_security_context || x->preserve_security_context)
if (! set_file_security_ctx (dst_name, x->preserve_security_context,
false, x))
if (! set_file_security_ctx (dst_name, false, x))
{
if (x->require_preserve_context)
goto un_backup;
@@ -3020,8 +3018,7 @@ copy_internal (char const *src_name, char const *dst_name,
if (!new_dst && !x->copy_as_regular && !S_ISDIR (src_mode)
&& (x->set_security_context || x->preserve_security_context))
{
if (! set_file_security_ctx (dst_name, x->preserve_security_context,
false, x))
if (! set_file_security_ctx (dst_name, false, x))
{
if (x->require_preserve_context)
goto un_backup;
+5 -3
View File
@@ -22,6 +22,8 @@
# include <stdbool.h>
# include "hash.h"
struct selabel_handle;
/* Control creation of sparse files (files with holes). */
enum Sparse_type
{
@@ -162,8 +164,8 @@ struct cp_options
bool preserve_timestamps;
bool explicit_no_preserve_mode;
/* If true, attempt to set specified security context */
bool set_security_context;
/* If non-null, attempt to set specified security context */
struct selabel_handle *set_security_context;
/* Enabled for mv, and for cp by the --preserve=links option.
If true, attempt to preserve in the destination files any
@@ -294,7 +296,7 @@ extern bool set_process_security_ctx (char const *src_name,
mode_t mode, bool new_dst,
const struct cp_options *x);
extern bool set_file_security_ctx (char const *dst_name, bool process_local,
extern bool set_file_security_ctx (char const *dst_name,
bool recurse, const struct cp_options *x);
void dest_info_init (struct cp_options *);
+12 -8
View File
@@ -20,7 +20,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
#include "system.h"
#include "argmatch.h"
@@ -531,10 +531,9 @@ make_dir_parents_private (char const *const_dir, size_t src_offset,
if (! *new_dst
&& (x->set_security_context || x->preserve_security_context))
{
if (! set_file_security_ctx (dir, x->preserve_security_context,
false, x)
if (! set_file_security_ctx (dir, false, x)
&& x->require_preserve_context)
return false;
return false;
}
*slash++ = '/';
@@ -802,7 +801,7 @@ cp_option_init (struct cp_options *x)
x->explicit_no_preserve_mode = false;
x->preserve_security_context = false; /* -a or --preserve=context. */
x->require_preserve_context = false; /* --preserve=context. */
x->set_security_context = false; /* -Z, set sys default context. */
x->set_security_context = NULL; /* -Z, set sys default context. */
x->preserve_xattr = false;
x->reduce_diagnostics = false;
x->require_preserve_xattr = false;
@@ -1116,7 +1115,12 @@ main (int argc, char **argv)
if (optarg)
scontext = optarg;
else
x.set_security_context = true;
{
x.set_security_context = selabel_open (SELABEL_CTX_FILE,
NULL, 0);
if (! x.set_security_context)
error (0, errno, _("warning: ignoring --context"));
}
}
else if (optarg)
{
@@ -1197,8 +1201,8 @@ main (int argc, char **argv)
/* FIXME: This handles new files. But what about existing files?
I.e., if updating a tree, new files would have the specified context,
but shouldn't existing files be updated for consistency like this?
if (scontext)
restorecon (dst_path, 0, true);
if (scontext && !restorecon (NULL, dst_path, 0))
error (...);
*/
if (scontext && setfscreatecon (se_const (scontext)) < 0)
die (EXIT_FAILURE, errno,
+30 -65
View File
@@ -23,7 +23,7 @@
#include <signal.h>
#include <pwd.h>
#include <grp.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
#include <sys/wait.h>
#include "system.h"
@@ -65,10 +65,6 @@ static bool use_default_selinux_context = true;
# define lchown(name, uid, gid) chown (name, uid, gid)
#endif
#if ! HAVE_MATCHPATHCON_INIT_PREFIX
# define matchpathcon_init_prefix(a, p) /* empty */
#endif
/* The user name that will own the files, or NULL to make the owner
the current user ID. */
static char *owner_name;
@@ -298,24 +294,37 @@ cp_option_init (struct cp_options *x)
x->update = false;
x->require_preserve_context = false; /* Not used by install currently. */
x->preserve_security_context = false; /* Whether to copy context from src. */
x->set_security_context = false; /* Whether to set sys default context. */
x->set_security_context = NULL; /* Whether to set sys default context. */
x->preserve_xattr = false;
x->verbose = false;
x->dest_info = NULL;
x->src_info = NULL;
}
#ifdef ENABLE_MATCHPATHCON
static struct selabel_handle *
get_labeling_handle (void)
{
static bool initialized;
static struct selabel_handle *hnd;
if (!initialized)
{
initialized = true;
hnd = selabel_open (SELABEL_CTX_FILE, NULL, 0);
if (!hnd)
error (0, errno, _("warning: security labeling handle failed"));
}
return hnd;
}
/* Modify file context to match the specified policy.
If an error occurs the file will remain with the default directory
context. Note this sets the context to that returned by matchpathcon,
context. Note this sets the context to that returned by selabel_lookup
and thus discards MLS levels and user identity of the FILE. */
static void
setdefaultfilecon (char const *file)
{
struct stat st;
char *scontext = NULL;
static bool first_call = true;
if (selinux_enabled != 1)
{
@@ -325,51 +334,14 @@ setdefaultfilecon (char const *file)
if (lstat (file, &st) != 0)
return;
if (first_call && IS_ABSOLUTE_FILE_NAME (file))
struct selabel_handle *hnd = get_labeling_handle ();
if (!hnd)
return;
if (selabel_lookup (hnd, &scontext, file, st.st_mode) != 0)
{
/* Calling matchpathcon_init_prefix (NULL, "/first_component/")
is an optimization to minimize the expense of the following
matchpathcon call. Do it only once, just before the first
matchpathcon call. We *could* call matchpathcon_fini after
the final matchpathcon call, but that's not necessary, since
by then we're about to exit, and besides, the buffers it
would free are still reachable. */
char const *p0;
char const *p = file + 1;
while (ISSLASH (*p))
++p;
/* Record final leading slash, for when FILE starts with two or more. */
p0 = p - 1;
if (*p)
{
char *prefix;
do
{
++p;
}
while (*p && !ISSLASH (*p));
prefix = malloc (p - p0 + 2);
if (prefix)
{
stpcpy (stpncpy (prefix, p0, p - p0), "/");
matchpathcon_init_prefix (NULL, prefix);
free (prefix);
}
}
}
first_call = false;
/* If there's an error determining the context, or it has none,
return to allow default context. Note the "<<none>>" check
is only needed for libselinux < 1.20 (2005-01-04). */
if ((matchpathcon (file, st.st_mode, &scontext) != 0)
|| STREQ (scontext, "<<none>>"))
{
if (scontext != NULL)
freecon (scontext);
if (errno != ENOENT)
error (0, errno, _("warning: %s: context lookup failed"),
quotef (file));
return;
}
@@ -379,15 +351,7 @@ setdefaultfilecon (char const *file)
quotef_n (0, file), quote_n (1, scontext));
freecon (scontext);
return;
}
#else
static void
setdefaultfilecon (char const *file)
{
(void) file;
}
#endif
/* FILE is the last operand of this command. Return true if FILE is a
directory. But report an error there is a problem accessing FILE,
@@ -427,7 +391,8 @@ static int
make_ancestor (char const *dir, char const *component, void *options)
{
struct cp_options const *x = options;
if (x->set_security_context && defaultcon (component, S_IFDIR) < 0
if (x->set_security_context
&& defaultcon (x->set_security_context, component, S_IFDIR) < 0
&& ! ignorable_ctx_err (errno))
error (0, errno, _("failed to set default creation context for %s"),
quoteaf (dir));
@@ -457,7 +422,7 @@ process_dir (char *dir, struct savewd *wd, void *options)
and here we set the context for the final component. */
if (ret == EXIT_SUCCESS && x->set_security_context)
{
if (! restorecon (last_component (dir), false, false)
if (! restorecon (x->set_security_context, last_component (dir), false)
&& ! ignorable_ctx_err (errno))
error (0, errno, _("failed to restore context for %s"),
quoteaf (dir));
@@ -902,7 +867,7 @@ main (int argc, char **argv)
/* Disable use of the install(1) specific setdefaultfilecon().
Note setdefaultfilecon() is different from the newer and more
generic restorecon() in that the former sets the context of
the dest files to that returned by matchpathcon directly,
the dest files to that returned by selabel_lookup directly,
thus discarding MLS level and user identity of the file.
TODO: consider removing setdefaultfilecon() in future. */
use_default_selinux_context = false;
@@ -910,7 +875,7 @@ main (int argc, char **argv)
if (optarg)
scontext = optarg;
else
x.set_security_context = true;
x.set_security_context = get_labeling_handle ();
}
else if (optarg)
{
-2
View File
@@ -416,8 +416,6 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS)
src_basenc_SOURCES = src/basenc.c
src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS)
src_ginstall_CPPFLAGS = -DENABLE_MATCHPATHCON=1 $(AM_CPPFLAGS)
src_expand_SOURCES = src/expand.c src/expand-common.c
src_unexpand_SOURCES = src/unexpand.c src/expand-common.c
+15 -8
View File
@@ -20,7 +20,7 @@
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
#include "system.h"
#include "die.h"
@@ -98,7 +98,7 @@ struct mkdir_options
mode_t mode_bits;
/* Set the SELinux File Context. */
bool set_security_context;
struct selabel_handle *set_security_context;
/* If not null, format to use when reporting newly made directories. */
char const *created_directory_format;
@@ -123,7 +123,8 @@ make_ancestor (char const *dir, char const *component, void *options)
{
struct mkdir_options const *o = options;
if (o->set_security_context && defaultcon (component, S_IFDIR) < 0
if (o->set_security_context
&& defaultcon (o->set_security_context, component, S_IFDIR) < 0
&& ! ignorable_ctx_err (errno))
error (0, errno, _("failed to set default creation context for %s"),
quoteaf (dir));
@@ -156,7 +157,8 @@ process_dir (char *dir, struct savewd *wd, void *options)
/* If possible set context before DIR created. */
if (o->set_security_context)
{
if (! o->make_ancestor_function && defaultcon (dir, S_IFDIR) < 0
if (! o->make_ancestor_function
&& defaultcon (o->set_security_context, dir, S_IFDIR) < 0
&& ! ignorable_ctx_err (errno))
error (0, errno, _("failed to set default creation context for %s"),
quoteaf (dir));
@@ -176,7 +178,7 @@ process_dir (char *dir, struct savewd *wd, void *options)
if (ret == EXIT_SUCCESS && o->set_security_context
&& o->make_ancestor_function)
{
if (! restorecon (last_component (dir), false, false)
if (! restorecon (o->set_security_context, last_component (dir), false)
&& ! ignorable_ctx_err (errno))
error (0, errno, _("failed to restore context for %s"),
quoteaf (dir));
@@ -197,7 +199,7 @@ main (int argc, char **argv)
options.mode = S_IRWXUGO;
options.mode_bits = 0;
options.created_directory_format = NULL;
options.set_security_context = false;
options.set_security_context = NULL;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -231,7 +233,12 @@ main (int argc, char **argv)
if (optarg)
scontext = optarg;
else
options.set_security_context = true;
{
options.set_security_context = selabel_open (SELABEL_CTX_FILE,
NULL, 0);
if (! options.set_security_context)
error (0, errno, _("warning: ignoring --context"));
}
}
else if (optarg)
{
@@ -255,7 +262,7 @@ main (int argc, char **argv)
/* FIXME: This assumes mkdir() is done in the same process.
If that's not always the case we would need to call this
like we do when options.set_security_context == true. */
like we do when options.set_security_context. */
if (scontext)
{
int ret = 0;
+9 -4
View File
@@ -20,7 +20,7 @@
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
#include "system.h"
#include "die.h"
@@ -81,7 +81,7 @@ main (int argc, char **argv)
int exit_status = EXIT_SUCCESS;
int optc;
char const *scontext = NULL;
bool set_security_context = false;
struct selabel_handle *set_security_context = NULL;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -109,7 +109,12 @@ main (int argc, char **argv)
if (optarg)
scontext = optarg;
else
set_security_context = true;
{
set_security_context = selabel_open (SELABEL_CTX_FILE,
NULL, 0);
if (! set_security_context)
error (0, errno, _("warning: ignoring --context"));
}
}
else if (optarg)
{
@@ -164,7 +169,7 @@ main (int argc, char **argv)
for (; optind < argc; ++optind)
{
if (set_security_context)
defaultcon (argv[optind], S_IFIFO);
defaultcon (set_security_context, argv[optind], S_IFIFO);
if (mkfifo (argv[optind], newmode) != 0)
{
error (0, errno, _("cannot create fifo %s"), quoteaf (argv[optind]));
+10 -5
View File
@@ -20,7 +20,7 @@
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
#include "system.h"
#include "die.h"
@@ -98,7 +98,7 @@ main (int argc, char **argv)
size_t expected_operands;
mode_t node_type;
char const *scontext = NULL;
bool set_security_context = false;
struct selabel_handle *set_security_context = NULL;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -126,7 +126,12 @@ main (int argc, char **argv)
if (optarg)
scontext = optarg;
else
set_security_context = true;
{
set_security_context = selabel_open (SELABEL_CTX_FILE,
NULL, 0);
if (! set_security_context)
error (0, errno, _("warning: ignoring --context"));
}
}
else if (optarg)
{
@@ -248,7 +253,7 @@ main (int argc, char **argv)
#endif
if (set_security_context)
defaultcon (argv[optind], node_type);
defaultcon (set_security_context, argv[optind], node_type);
if (mknod (argv[optind], newmode | node_type, device) != 0)
die (EXIT_FAILURE, errno, "%s", quotef (argv[optind]));
@@ -257,7 +262,7 @@ main (int argc, char **argv)
case 'p': /* 'pipe' */
if (set_security_context)
defaultcon (argv[optind], S_IFIFO);
defaultcon (set_security_context, argv[optind], S_IFIFO);
if (mkfifo (argv[optind], newmode) != 0)
die (EXIT_FAILURE, errno, "%s", quotef (argv[optind]));
break;
+6 -3
View File
@@ -21,7 +21,7 @@
#include <getopt.h>
#include <sys/types.h>
#include <assert.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
#include "system.h"
#include "backupfile.h"
@@ -125,7 +125,7 @@ cp_option_init (struct cp_options *x)
x->preserve_timestamps = true;
x->explicit_no_preserve_mode= false;
x->preserve_security_context = selinux_enabled;
x->set_security_context = false;
x->set_security_context = NULL;
x->reduce_diagnostics = false;
x->data_copy_required = true;
x->require_preserve = false; /* FIXME: maybe make this an option */
@@ -417,7 +417,10 @@ main (int argc, char **argv)
if (selinux_enabled)
{
x.preserve_security_context = false;
x.set_security_context = true;
x.set_security_context = selabel_open (SELABEL_CTX_FILE,
NULL, 0);
if (! x.set_security_context)
error (0, errno, _("warning: ignoring --context"));
}
break;
case_GETOPT_HELP_CHAR;
+35 -84
View File
@@ -17,18 +17,15 @@
/* Written by Daniel Walsh <dwalsh@redhat.com> */
#include <config.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
#include <selinux/context.h>
#include <sys/types.h>
#include "die.h"
#include "error.h"
#include "system.h"
#include "canonicalize.h"
#include "xfts.h"
#include "selinux.h"
#if HAVE_SELINUX_SELINUX_H
#if HAVE_SELINUX_LABEL_H
# if ! HAVE_MODE_TO_SECURITY_CLASS
/*
@@ -98,16 +95,17 @@ quit:
}
/*
This function takes a path and a mode, it calls computecon to get the
This function takes a handle, path and mode, it calls computecon to get the
label of the path object if the current process created it, then it calls
matchpathcon to get the default type for the object. It substitutes the
selabel_lookup to get the default type for the object. It substitutes the
default type into label. It tells the SELinux Kernel to label all new file
system objects created by the current process with this label.
Returns -1 on failure. errno will be set appropriately.
*/
int
defaultcon (char const *path, mode_t mode)
defaultcon (struct selabel_handle *selabel_handle,
char const *path, mode_t mode)
{
int rc = -1;
char *scon = NULL;
@@ -115,20 +113,8 @@ defaultcon (char const *path, mode_t mode)
context_t scontext = 0, tcontext = 0;
const char *contype;
char *constr;
char *newpath = NULL;
if (! IS_ABSOLUTE_FILE_NAME (path))
{
/* Generate absolute path as required by subsequent matchpathcon(),
with libselinux < 2.1.5 2011-0826. */
newpath = canonicalize_filename_mode (path, CAN_MISSING);
if (! newpath)
die (EXIT_FAILURE, errno, _("error canonicalizing %s"),
quoteaf (path));
path = newpath;
}
if (matchpathcon (path, mode, &scon) < 0)
if (selabel_lookup (selabel_handle, &scon, path, mode) < 0)
{
/* "No such file or directory" is a confusing error,
when processing files, when in fact it was the
@@ -160,25 +146,20 @@ quit:
context_free (tcontext);
freecon (scon);
freecon (tcon);
free (newpath);
return rc;
}
/*
This function takes a PATH of an existing file system object, and a LOCAL
boolean that indicates whether the function should set the object's label
to the default for the local process, or one using system wide settings.
If LOCAL == true, it will ask the SELinux Kernel what the default label
for all objects created should be and then sets the label on the object.
Otherwise it calls matchpathcon on the object to ask the system what the
default label should be, extracts the type field and then modifies the file
If SELABEL_HANDLE is null, set PATH's label to the default to the
local process. Otherwise use selabel_lookup to determine the
default label, extract the type field and then modify the file
system object. Note only the type field is updated, thus preserving MLS
levels and user identity etc. of the PATH.
Returns -1 on failure. errno will be set appropriately.
*/
static int
restorecon_private (char const *path, bool local)
restorecon_private (struct selabel_handle *selabel_handle, char const *path)
{
int rc = -1;
struct stat sb;
@@ -189,7 +170,7 @@ restorecon_private (char const *path, bool local)
char *constr;
int fd;
if (local)
if (!selabel_handle)
{
if (getfscreatecon (&tcon) < 0)
return rc;
@@ -199,7 +180,9 @@ restorecon_private (char const *path, bool local)
return rc;
}
rc = lsetfilecon (path, tcon);
int err = errno;
freecon (tcon);
errno = err;
return rc;
}
@@ -218,13 +201,13 @@ restorecon_private (char const *path, bool local)
goto quit;
}
if (matchpathcon (path, sb.st_mode, &scon) < 0)
if (selabel_lookup (selabel_handle, &scon, path, sb.st_mode) < 0)
{
/* "No such file or directory" is a confusing error,
when processing files, when in fact it was the
associated default context that was not found.
Therefore map the error to something more appropriate
to the context in which we're using matchpathcon(). */
to the context in which we're using selabel_lookup. */
if (errno == ENOENT)
errno = ENODATA;
goto quit;
@@ -258,83 +241,51 @@ restorecon_private (char const *path, bool local)
else
rc = lsetfilecon (path, constr);
quit:
quit:;
int err = errno;
if (fd != -1)
close (fd);
context_free (scontext);
context_free (tcontext);
freecon (scon);
freecon (tcon);
errno = err;
return rc;
}
/*
This function takes three parameters:
SELABEL_HANDLE for selabel_lookup, or null to preserve.
PATH of an existing file system object.
A RECURSE boolean which if the file system object is a directory, will
call restorecon_private on every file system object in the directory.
A LOCAL boolean that indicates whether the function should set object labels
to the default for the local process, or use system wide settings.
Returns false on failure. errno will be set appropriately.
Return false on failure. errno will be set appropriately.
*/
bool
restorecon (char const *path, bool recurse, bool local)
restorecon (struct selabel_handle *selabel_handle,
char const *path, bool recurse)
{
char *newpath = NULL;
FTS *fts;
bool ok = true;
if (! IS_ABSOLUTE_FILE_NAME (path) && ! local)
{
/* Generate absolute path as required by subsequent matchpathcon(),
with libselinux < 2.1.5 2011-0826. Also generating the absolute
path before the fts walk, will generate absolute paths in the
fts entries, which may be quicker to process in any case. */
newpath = canonicalize_filename_mode (path, CAN_MISSING);
if (! newpath)
die (EXIT_FAILURE, errno, _("error canonicalizing %s"),
quoteaf (path));
}
const char *ftspath[2] = { newpath ? newpath : path, NULL };
if (! recurse)
{
ok = restorecon_private (*ftspath, local) != -1;
free (newpath);
return ok;
}
return restorecon_private (selabel_handle, path) == 0;
fts = xfts_open ((char *const *) ftspath, FTS_PHYSICAL, NULL);
while (1)
{
FTSENT *ent;
char const *ftspath[2] = { path, NULL };
FTS *fts = xfts_open ((char *const *) ftspath, FTS_PHYSICAL, NULL);
ent = fts_read (fts);
if (ent == NULL)
{
if (errno != 0)
{
error (0, errno, _("fts_read failed"));
ok = false;
}
break;
}
int err = 0;
for (FTSENT *ent; (ent = fts_read (fts)); )
if (restorecon_private (selabel_handle, fts->fts_path) < 0)
err = errno;
ok &= restorecon_private (fts->fts_path, local) != -1;
}
if (errno != 0)
err = errno;
if (fts_close (fts) != 0)
{
error (0, errno, _("fts_close failed"));
ok = false;
}
err = errno;
free (newpath);
return ok;
return !err;
}
#endif
+11 -5
View File
@@ -19,6 +19,8 @@
#ifndef COREUTILS_SELINUX_H
# define COREUTILS_SELINUX_H
struct selabel_handle;
/* Return true if ERR corresponds to an unsupported request,
or if there is no context or it's inaccessible. */
static inline bool
@@ -27,21 +29,25 @@ ignorable_ctx_err (int err)
return err == ENOTSUP || err == ENODATA;
}
# if HAVE_SELINUX_SELINUX_H
# if HAVE_SELINUX_LABEL_H
extern bool
restorecon (char const *path, bool recurse, bool preserve);
restorecon (struct selabel_handle *selabel_handle,
char const *path, bool recurse);
extern int
defaultcon (char const *path, mode_t mode);
defaultcon (struct selabel_handle *selabel_handle,
char const *path, mode_t mode);
# else
static inline bool
restorecon (char const *path, bool recurse, bool preserve)
restorecon (struct selabel_handle *selabel_handle,
char const *path, bool recurse)
{ errno = ENOTSUP; return false; }
static inline int
defaultcon (char const *path, mode_t mode)
defaultcon (struct selabel_handle *selabel_handle,
char const *path, mode_t mode)
{ errno = ENOTSUP; return -1; }
# endif