From 44801294127f5b1e42f1a36faa0ba2700a4753ff Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Tue, 8 Nov 2016 14:21:10 -0500 Subject: [PATCH] restorecond: break source dependency on policycoreutils/setfiles Now that restorecond is separated from policycoreutils, we should not retain a build dependency on the policycoreutils/setfiles source files. Fork the restore.[ch] files for restorecond. Signed-off-by: Stephen Smalley --- restorecond/Makefile | 6 +- restorecond/restore.c | 129 ++++++++++++++++++++++++++++++++++++++ restorecond/restore.h | 61 ++++++++++++++++++ restorecond/restorecond.c | 5 -- restorecond/watch.c | 2 +- 5 files changed, 193 insertions(+), 10 deletions(-) create mode 100644 restorecond/restore.c create mode 100644 restorecond/restore.h diff --git a/restorecond/Makefile b/restorecond/Makefile index 7a517171..02b70113 100644 --- a/restorecond/Makefile +++ b/restorecond/Makefile @@ -16,10 +16,8 @@ SELINUXDIR = $(DESTDIR)/etc/selinux DBUSFLAGS = -DHAVE_DBUS $(shell $(PKG_CONFIG) --cflags dbus-glib-1) DBUSLIB = $(shell $(PKG_CONFIG) --libs dbus-glib-1) -SETFILESDIR ?= ../policycoreutils/setfiles - CFLAGS ?= -g -Werror -Wall -W -override CFLAGS += -I$(PREFIX)/include $(DBUSFLAGS) -I$(SETFILESDIR) +override CFLAGS += -I$(PREFIX)/include $(DBUSFLAGS) USE_PCRE2 ?= n ifeq ($(USE_PCRE2),y) @@ -34,7 +32,7 @@ all: restorecond restorecond.o utmpwatcher.o stringslist.o user.o watch.o: restorecond.h -restorecond: $(SETFILESDIR)/restore.o restorecond.o utmpwatcher.o stringslist.o user.o watch.o +restorecond: restore.o restorecond.o utmpwatcher.o stringslist.o user.o watch.o $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) install: all diff --git a/restorecond/restore.c b/restorecond/restore.c new file mode 100644 index 00000000..cf04e962 --- /dev/null +++ b/restorecond/restore.c @@ -0,0 +1,129 @@ +/* + * Note that the restorecond(8) service build links with these functions. + * Therefore any changes here should also be tested against that utility. + */ + +#include "restore.h" +#include + +char **exclude_list; +int exclude_count; + +struct restore_opts *r_opts; + +void restore_init(struct restore_opts *opts) +{ + int rc; + + r_opts = opts; + struct selinux_opt selinux_opts[] = { + { SELABEL_OPT_VALIDATE, r_opts->selabel_opt_validate }, + { SELABEL_OPT_PATH, r_opts->selabel_opt_path }, + { SELABEL_OPT_DIGEST, r_opts->selabel_opt_digest } + }; + + r_opts->hnd = selabel_open(SELABEL_CTX_FILE, selinux_opts, 3); + if (!r_opts->hnd) { + perror(r_opts->selabel_opt_path); + exit(1); + } + + r_opts->restorecon_flags = 0; + r_opts->restorecon_flags = r_opts->nochange | r_opts->verbose | + r_opts->progress | r_opts->set_specctx | + r_opts->add_assoc | r_opts->ignore_digest | + r_opts->recurse | r_opts->userealpath | + r_opts->xdev | r_opts->abort_on_error | + r_opts->syslog_changes | r_opts->log_matches | + r_opts->ignore_noent | r_opts->ignore_mounts; + + /* Use setfiles, restorecon and restorecond own handles */ + selinux_restorecon_set_sehandle(r_opts->hnd); + + if (r_opts->rootpath) { + rc = selinux_restorecon_set_alt_rootpath(r_opts->rootpath); + if (rc) { + fprintf(stderr, + "selinux_restorecon_set_alt_rootpath error: %s.\n", + strerror(errno)); + exit(-1); + } + } + + if (exclude_list) + selinux_restorecon_set_exclude_list + ((const char **)exclude_list); +} + +void restore_finish(void) +{ + int i; + + if (exclude_list) { + for (i = 0; exclude_list[i]; i++) + free(exclude_list[i]); + free(exclude_list); + } +} + +int process_glob(char *name, struct restore_opts *opts) +{ + glob_t globbuf; + size_t i = 0; + int len, rc, errors; + + r_opts = opts; + memset(&globbuf, 0, sizeof(globbuf)); + + errors = glob(name, GLOB_TILDE | GLOB_PERIOD | + GLOB_NOCHECK | GLOB_BRACE, NULL, &globbuf); + if (errors) + return errors; + + for (i = 0; i < globbuf.gl_pathc; i++) { + len = strlen(globbuf.gl_pathv[i]) - 2; + if (len > 0 && strcmp(&globbuf.gl_pathv[i][len--], "/.") == 0) + continue; + if (len > 0 && strcmp(&globbuf.gl_pathv[i][len], "/..") == 0) + continue; + rc = selinux_restorecon(globbuf.gl_pathv[i], + r_opts->restorecon_flags); + if (rc < 0) + errors = rc; + } + + globfree(&globbuf); + + return errors; +} + +void add_exclude(const char *directory) +{ + char **tmp_list; + + if (directory == NULL || directory[0] != '/') { + fprintf(stderr, "Full path required for exclude: %s.\n", + directory); + exit(-1); + } + + /* Add another two entries, one for directory, and the other to + * terminate the list. + */ + tmp_list = realloc(exclude_list, sizeof(char *) * (exclude_count + 2)); + if (!tmp_list) { + fprintf(stderr, "realloc failed while excluding %s.\n", + directory); + exit(-1); + } + exclude_list = tmp_list; + + exclude_list[exclude_count] = strdup(directory); + if (!exclude_list[exclude_count]) { + fprintf(stderr, "strdup failed while excluding %s.\n", + directory); + exit(-1); + } + exclude_count++; + exclude_list[exclude_count] = NULL; +} diff --git a/restorecond/restore.h b/restorecond/restore.h new file mode 100644 index 00000000..97fbdf4d --- /dev/null +++ b/restorecond/restore.h @@ -0,0 +1,61 @@ +#ifndef RESTORE_H +#define RESTORE_H +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * STAR_COUNT is also defined in libselinux/src/selinux_restorecon.c where it + * is used to output "*" for each number of files processed. Defined here for + * inclusion in man pages. +*/ +#define STAR_COUNT 1000 + +/* Things that need to be init'd */ +struct restore_opts { + unsigned int nochange; + unsigned int verbose; + unsigned int progress; + unsigned int set_specctx; + unsigned int add_assoc; + unsigned int ignore_digest; + unsigned int recurse; + unsigned int userealpath; + unsigned int xdev; + unsigned int abort_on_error; + unsigned int syslog_changes; + unsigned int log_matches; + unsigned int ignore_noent; + unsigned int ignore_mounts; + /* restorecon_flags holds | of above for restore_init() */ + unsigned int restorecon_flags; + char *rootpath; + char *progname; + struct selabel_handle *hnd; + const char *selabel_opt_validate; + const char *selabel_opt_path; + const char *selabel_opt_digest; + int debug; + FILE *outfile; +}; + +void restore_init(struct restore_opts *opts); +void restore_finish(void); +void add_exclude(const char *directory); +int process_glob(char *name, struct restore_opts *opts); +extern char **exclude_list; + +#endif diff --git a/restorecond/restorecond.c b/restorecond/restorecond.c index 4c8c99cf..f379db1e 100644 --- a/restorecond/restorecond.c +++ b/restorecond/restorecond.c @@ -42,11 +42,6 @@ * */ -/* - * Note that the restorecond(8) service build links with functions provided - * by ../setfiles/restore.c - */ - #define _GNU_SOURCE #include #include diff --git a/restorecond/watch.c b/restorecond/watch.c index bdfc99db..2be45d4f 100644 --- a/restorecond/watch.c +++ b/restorecond/watch.c @@ -8,7 +8,7 @@ #include #include #include -#include "../setfiles/restore.h" +#include "restore.h" #include #include #include