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 <dwalsh@redhat.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Dan Walsh <dwalsh@redhat.com>
This commit is contained in:
Dan Walsh 2011-09-07 13:58:24 -04:00 committed by Eric Paris
parent e23c73a167
commit 96cedba3e5
3 changed files with 83 additions and 61 deletions

View File

@ -1,5 +1,6 @@
#include "restore.h"
#include <glob.h>
#include <selinux/context.h>
#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, "<<none>>") == 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
* <<none>> 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, "<<none>>") == 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.
*/

View File

@ -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

View File

@ -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.