#include "restore.h" #include <glob.h> #ifndef GLOB_TILDE #define GLOB_TILDE 0 #endif #ifndef GLOB_BRACE #define GLOB_BRACE 0 #endif char **exclude_list; int exclude_count; void restore_init(struct restore_opts *opts) { int rc; struct selinux_opt selinux_opts[] = { { SELABEL_OPT_VALIDATE, opts->selabel_opt_validate }, { SELABEL_OPT_PATH, opts->selabel_opt_path }, { SELABEL_OPT_DIGEST, opts->selabel_opt_digest } }; opts->hnd = selabel_open(SELABEL_CTX_FILE, selinux_opts, 3); if (!opts->hnd) { perror(opts->selabel_opt_path); exit(1); } opts->restorecon_flags = 0; opts->restorecon_flags = opts->nochange | opts->verbose | opts->progress | opts->set_specctx | opts->add_assoc | opts->ignore_digest | opts->recurse | opts->userealpath | opts->xdev | opts->abort_on_error | opts->syslog_changes | opts->log_matches | opts->ignore_noent | opts->ignore_mounts; /* Use setfiles, restorecon and restorecond own handles */ selinux_restorecon_set_sehandle(opts->hnd); if (opts->rootpath) { rc = selinux_restorecon_set_alt_rootpath(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; 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], 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; }