Blame restorecond/restore.c

Packit f2ed7b
#include "restore.h"
Packit f2ed7b
#include <glob.h>
Packit f2ed7b
Packit f2ed7b
#ifndef GLOB_TILDE
Packit f2ed7b
#define GLOB_TILDE 0
Packit f2ed7b
#endif
Packit f2ed7b
Packit f2ed7b
#ifndef GLOB_BRACE
Packit f2ed7b
#define GLOB_BRACE 0
Packit f2ed7b
#endif
Packit f2ed7b
Packit f2ed7b
char **exclude_list;
Packit f2ed7b
int exclude_count;
Packit f2ed7b
Packit f2ed7b
void restore_init(struct restore_opts *opts)
Packit f2ed7b
{
Packit f2ed7b
	int rc;
Packit f2ed7b
Packit f2ed7b
	struct selinux_opt selinux_opts[] = {
Packit f2ed7b
		{ SELABEL_OPT_VALIDATE, opts->selabel_opt_validate },
Packit f2ed7b
		{ SELABEL_OPT_PATH, opts->selabel_opt_path },
Packit f2ed7b
		{ SELABEL_OPT_DIGEST, opts->selabel_opt_digest }
Packit f2ed7b
	};
Packit f2ed7b
Packit f2ed7b
	opts->hnd = selabel_open(SELABEL_CTX_FILE, selinux_opts, 3);
Packit f2ed7b
	if (!opts->hnd) {
Packit f2ed7b
		perror(opts->selabel_opt_path);
Packit f2ed7b
		exit(1);
Packit f2ed7b
	}
Packit f2ed7b
Packit f2ed7b
	opts->restorecon_flags = 0;
Packit f2ed7b
	opts->restorecon_flags = opts->nochange | opts->verbose |
Packit f2ed7b
			   opts->progress | opts->set_specctx  |
Packit f2ed7b
			   opts->add_assoc | opts->ignore_digest |
Packit f2ed7b
			   opts->recurse | opts->userealpath |
Packit f2ed7b
			   opts->xdev | opts->abort_on_error |
Packit f2ed7b
			   opts->syslog_changes | opts->log_matches |
Packit f2ed7b
			   opts->ignore_noent | opts->ignore_mounts;
Packit f2ed7b
Packit f2ed7b
	/* Use setfiles, restorecon and restorecond own handles */
Packit f2ed7b
	selinux_restorecon_set_sehandle(opts->hnd);
Packit f2ed7b
Packit f2ed7b
	if (opts->rootpath) {
Packit f2ed7b
		rc = selinux_restorecon_set_alt_rootpath(opts->rootpath);
Packit f2ed7b
		if (rc) {
Packit f2ed7b
			fprintf(stderr,
Packit f2ed7b
				"selinux_restorecon_set_alt_rootpath error: %s.\n",
Packit f2ed7b
				strerror(errno));
Packit f2ed7b
			exit(-1);
Packit f2ed7b
		}
Packit f2ed7b
	}
Packit f2ed7b
Packit f2ed7b
	if (exclude_list)
Packit f2ed7b
		selinux_restorecon_set_exclude_list
Packit f2ed7b
						 ((const char **)exclude_list);
Packit f2ed7b
}
Packit f2ed7b
Packit f2ed7b
void restore_finish(void)
Packit f2ed7b
{
Packit f2ed7b
	int i;
Packit f2ed7b
Packit f2ed7b
	if (exclude_list) {
Packit f2ed7b
		for (i = 0; exclude_list[i]; i++)
Packit f2ed7b
			free(exclude_list[i]);
Packit f2ed7b
		free(exclude_list);
Packit f2ed7b
	}
Packit f2ed7b
}
Packit f2ed7b
Packit f2ed7b
int process_glob(char *name, struct restore_opts *opts)
Packit f2ed7b
{
Packit f2ed7b
	glob_t globbuf;
Packit f2ed7b
	size_t i = 0;
Packit f2ed7b
	int len, rc, errors;
Packit f2ed7b
Packit f2ed7b
	memset(&globbuf, 0, sizeof(globbuf));
Packit f2ed7b
Packit f2ed7b
	errors = glob(name, GLOB_TILDE | GLOB_PERIOD |
Packit f2ed7b
			  GLOB_NOCHECK | GLOB_BRACE, NULL, &globbuf);
Packit f2ed7b
	if (errors)
Packit f2ed7b
		return errors;
Packit f2ed7b
Packit f2ed7b
	for (i = 0; i < globbuf.gl_pathc; i++) {
Packit f2ed7b
		len = strlen(globbuf.gl_pathv[i]) - 2;
Packit f2ed7b
		if (len > 0 && strcmp(&globbuf.gl_pathv[i][len--], "/.") == 0)
Packit f2ed7b
			continue;
Packit f2ed7b
		if (len > 0 && strcmp(&globbuf.gl_pathv[i][len], "/..") == 0)
Packit f2ed7b
			continue;
Packit f2ed7b
		rc = selinux_restorecon(globbuf.gl_pathv[i],
Packit f2ed7b
					opts->restorecon_flags);
Packit f2ed7b
		if (rc < 0)
Packit f2ed7b
			errors = rc;
Packit f2ed7b
	}
Packit f2ed7b
Packit f2ed7b
	globfree(&globbuf);
Packit f2ed7b
Packit f2ed7b
	return errors;
Packit f2ed7b
}
Packit f2ed7b
Packit f2ed7b
void add_exclude(const char *directory)
Packit f2ed7b
{
Packit f2ed7b
	char **tmp_list;
Packit f2ed7b
Packit f2ed7b
	if (directory == NULL || directory[0] != '/') {
Packit f2ed7b
		fprintf(stderr, "Full path required for exclude: %s.\n",
Packit f2ed7b
			    directory);
Packit f2ed7b
		exit(-1);
Packit f2ed7b
	}
Packit f2ed7b
Packit f2ed7b
	/* Add another two entries, one for directory, and the other to
Packit f2ed7b
	 * terminate the list.
Packit f2ed7b
	 */
Packit f2ed7b
	tmp_list = realloc(exclude_list, sizeof(char *) * (exclude_count + 2));
Packit f2ed7b
	if (!tmp_list) {
Packit f2ed7b
		fprintf(stderr, "realloc failed while excluding %s.\n",
Packit f2ed7b
			    directory);
Packit f2ed7b
		exit(-1);
Packit f2ed7b
	}
Packit f2ed7b
	exclude_list = tmp_list;
Packit f2ed7b
Packit f2ed7b
	exclude_list[exclude_count] = strdup(directory);
Packit f2ed7b
	if (!exclude_list[exclude_count]) {
Packit f2ed7b
		fprintf(stderr, "strdup failed while excluding %s.\n",
Packit f2ed7b
			    directory);
Packit f2ed7b
		exit(-1);
Packit f2ed7b
	}
Packit f2ed7b
	exclude_count++;
Packit f2ed7b
	exclude_list[exclude_count] = NULL;
Packit f2ed7b
}