From 96cedba3e59aa474f0f040da5108a17bba45ce6c Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Wed, 7 Sep 2011 13:58:24 -0400 Subject: [PATCH] policycoreutils: restorecon: only update type by default This patch allows us to use restorecon on MCS Separated File Systems or MLS Environments, Basically allows a user to check his type enforcement. Signed-off-by: Dan Walsh Signed-off-by: Eric Paris Acked-by: Dan Walsh --- policycoreutils/setfiles/restore.c | 113 +++++++++++++++----------- policycoreutils/setfiles/restorecon.8 | 12 +-- policycoreutils/setfiles/setfiles.8 | 19 +++-- 3 files changed, 83 insertions(+), 61 deletions(-) diff --git a/policycoreutils/setfiles/restore.c b/policycoreutils/setfiles/restore.c index 9a7d315f..3104e402 100644 --- a/policycoreutils/setfiles/restore.c +++ b/policycoreutils/setfiles/restore.c @@ -1,5 +1,6 @@ #include "restore.h" #include +#include #define SKIP -2 #define ERR -1 @@ -33,7 +34,6 @@ struct edir { static file_spec_t *fl_head; static int filespec_add(ino_t ino, const security_context_t con, const char *file); -static int only_changed_user(const char *a, const char *b); struct restore_opts *r_opts = NULL; static void filespec_destroy(void); static void filespec_eval(void); @@ -104,8 +104,7 @@ static int restore(FTSENT *ftsent) { char *my_file = strdupa(ftsent->fts_path); int ret = -1; - char *context, *newcon; - int user_only_changed = 0; + security_context_t curcon = NULL, newcon = NULL; if (match(my_file, ftsent->fts_statp, &newcon) < 0) /* Check for no matching specification. */ @@ -139,74 +138,105 @@ static int restore(FTSENT *ftsent) printf("%s: %s matched by %s\n", r_opts->progname, my_file, newcon); } + /* + * Do not relabel if their is no default specification for this file + */ + + if (strcmp(newcon, "<>") == 0) { + goto out; + } + /* Get the current context of the file. */ - ret = lgetfilecon_raw(ftsent->fts_accpath, &context); + ret = lgetfilecon_raw(ftsent->fts_accpath, &curcon); if (ret < 0) { if (errno == ENODATA) { - context = NULL; + curcon = NULL; } else { fprintf(stderr, "%s get context on %s failed: '%s'\n", r_opts->progname, my_file, strerror(errno)); goto err; } - user_only_changed = 0; - } else - user_only_changed = only_changed_user(context, newcon); + } + /* lgetfilecon returns number of characters and ret needs to be reset * to 0. */ ret = 0; /* - * Do not relabel the file if the matching specification is - * <> or the file is already labeled according to the - * specification. + * Do not relabel the file if the file is already labeled according to + * the specification. */ - if ((strcmp(newcon, "<>") == 0) || - (context && (strcmp(context, newcon) == 0))) { - freecon(context); + if (curcon && (strcmp(curcon, newcon) == 0)) { goto out; } - if (!r_opts->force && context && (is_context_customizable(context) > 0)) { + if (!r_opts->force && curcon && (is_context_customizable(curcon) > 0)) { if (r_opts->verbose > 1) { fprintf(stderr, "%s: %s not reset customized by admin to %s\n", - r_opts->progname, my_file, context); + r_opts->progname, my_file, curcon); } - freecon(context); goto out; } - if (r_opts->verbose) { - /* If we're just doing "-v", trim out any relabels where - * the user has r_opts->changed but the role and type are the - * same. For "-vv", emit everything. */ - if (r_opts->verbose > 1 || !user_only_changed) { - printf("%s reset %s context %s->%s\n", - r_opts->progname, my_file, context ?: "", newcon); + /* + * Do not change label unless this is a force or the type is different + */ + if (!r_opts->force && curcon) { + int types_differ = 0; + context_t cona; + context_t conb; + int err = 0; + cona = context_new(curcon); + if (! cona) { + goto out; + } + conb = context_new(newcon); + if (! conb) { + context_free(cona); + goto out; + } + + types_differ = strcmp(context_type_get(cona), context_type_get(conb)); + if (types_differ) { + err |= context_user_set(conb, context_user_get(cona)); + err |= context_role_set(conb, context_role_get(cona)); + err |= context_range_set(conb, context_range_get(cona)); + if (!err) { + freecon(newcon); + newcon = strdup(context_str(conb)); + } + } + context_free(cona); + context_free(conb); + + if (!types_differ || err) { + goto out; } } - if (r_opts->logging && !user_only_changed) { - if (context) + if (r_opts->verbose) { + printf("%s reset %s context %s->%s\n", + r_opts->progname, my_file, curcon ?: "", newcon); + } + + if (r_opts->logging) { + if (curcon) syslog(LOG_INFO, "relabeling %s from %s to %s\n", - my_file, context, newcon); + my_file, curcon, newcon); else syslog(LOG_INFO, "labeling %s to %s\n", my_file, newcon); } - if (r_opts->outfile && !user_only_changed) + if (r_opts->outfile) fprintf(r_opts->outfile, "%s\n", my_file); - if (context) - freecon(context); - /* * Do not relabel the file if -n was used. */ - if (!r_opts->change || user_only_changed) + if (!r_opts->change) goto out; /* @@ -220,12 +250,15 @@ static int restore(FTSENT *ftsent) } ret = 1; out: + freecon(curcon); freecon(newcon); return ret; skip: + freecon(curcon); freecon(newcon); return SKIP; err: + freecon(curcon); freecon(newcon); return ERR; } @@ -447,22 +480,6 @@ int add_exclude(const char *directory) return 0; } -/* Compare two contexts to see if their differences are "significant", - * or whether the only difference is in the user. */ -static int only_changed_user(const char *a, const char *b) -{ - char *rest_a, *rest_b; /* Rest of the context after the user */ - if (r_opts->force) - return 0; - if (!a || !b) - return 0; - rest_a = strchr(a, ':'); - rest_b = strchr(b, ':'); - if (!rest_a || !rest_b) - return 0; - return (strcmp(rest_a, rest_b) == 0); -} - /* * Evaluate the association hash table distribution. */ diff --git a/policycoreutils/setfiles/restorecon.8 b/policycoreutils/setfiles/restorecon.8 index f765000b..ffbb9d12 100644 --- a/policycoreutils/setfiles/restorecon.8 +++ b/policycoreutils/setfiles/restorecon.8 @@ -21,6 +21,11 @@ It can also be run at any other time to correct inconsistent labels, to add support for newly-installed policy or, by using the \-n option, to passively check whether the file contexts are all set as specified by the active policy (default behavior) or by some other policy (see the \-c option). +.P +If a file object does not have a context, restorecon will write the default +context to the file object's extended attributes. If a file object has a +context, restorecon will only modify the type portion of the security context. +The -F option will force a replacement of the entire context. .SH "OPTIONS" .TP @@ -31,8 +36,8 @@ exclude a directory (repeat the option to exclude more than one directory). infilename contains a list of files to be processed. Use \- for stdin. .TP .B \-F -force reset of context to match file_context for customizable files, or the -user section, if it has changed. +Force reset of context to match file_context for customizable files, and the +default file context, changing the user, role, range portion as well as the type. .TP .B \-h, \-? display usage information and exit. @@ -58,9 +63,6 @@ change files and directories file labels recursively (descend directories). .B \-v show changes in file labels, if type or role are going to be changed. .TP -.B \-vv -show changes in file labels, if type, role or user are going to be changed. -.TP .B \-0 the separator for the input items is assumed to be the null character (instead of the white space). The quotes and the backslash characters are diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8 index bcec84c3..7ff54f99 100644 --- a/policycoreutils/setfiles/setfiles.8 +++ b/policycoreutils/setfiles/setfiles.8 @@ -4,7 +4,7 @@ setfiles \- set SELinux file security contexts. .SH "SYNOPSIS" .B setfiles -.I [\-c policy] [\-d] [\-l] [\-n] [\-e directory] [\-o filename] [\-q] [\-s] [\-v] [\-vv] [\-W] [\-F] spec_file pathname... +.I [\-c policy] [\-d] [\-l] [\-n] [\-e directory] [\-o filename] [\-q] [\-s] [\-v] [\-W] [\-F] spec_file pathname... .SH "DESCRIPTION" This manual page describes the .BR setfiles @@ -19,9 +19,13 @@ It can also be run at any other time to correct inconsistent labels, to add support for newly-installed policy or, by using the \-n option, to passively check whether the file contexts are all set as specified by the active policy (default behavior) or by some other policy (see the \-c option). - +.P +If a file object does not have a context, setfiles will write the default +context to the file object's extended attributes. If a file object has a +context, setfiles will only modify the type portion of the security context. +The -F option will force a replacement of the entire context. .SH "OPTIONS" -.TP +.TP .B \-c check the validity of the contexts against the specified binary policy. .TP @@ -36,7 +40,9 @@ directory to exclude (repeat option for more than one directory). take a list of files to be processed from an input file. .TP .B \-F -force reset of context to match file_context for customizable files. +Force reset of context to match file_context for customizable files, and the +default file context, changing the user, role, range portion as well as the +type. .TP .B \-h, \-? display usage information and exit. @@ -67,10 +73,7 @@ take a list of files from standard input instead of using a pathname from the command line (equivalent to \-f \-). .TP .B \-v -show changes in file labels, if type or role are going to be changed. -.TP -.B \-vv -show changes in file labels, if type, role or user are going to be changed. +show changes in file labels. .TP .B \-W display warnings about entries that had no matching files.