1*2d543d20SAndroid Build Coastguard Worker #include "restore.h"
2*2d543d20SAndroid Build Coastguard Worker #include <glob.h>
3*2d543d20SAndroid Build Coastguard Worker
4*2d543d20SAndroid Build Coastguard Worker #ifndef GLOB_TILDE
5*2d543d20SAndroid Build Coastguard Worker #define GLOB_TILDE 0
6*2d543d20SAndroid Build Coastguard Worker #endif
7*2d543d20SAndroid Build Coastguard Worker
8*2d543d20SAndroid Build Coastguard Worker #ifndef GLOB_BRACE
9*2d543d20SAndroid Build Coastguard Worker #define GLOB_BRACE 0
10*2d543d20SAndroid Build Coastguard Worker #endif
11*2d543d20SAndroid Build Coastguard Worker
12*2d543d20SAndroid Build Coastguard Worker char **exclude_list;
13*2d543d20SAndroid Build Coastguard Worker int exclude_count;
14*2d543d20SAndroid Build Coastguard Worker
restore_init(struct restore_opts * opts)15*2d543d20SAndroid Build Coastguard Worker void restore_init(struct restore_opts *opts)
16*2d543d20SAndroid Build Coastguard Worker {
17*2d543d20SAndroid Build Coastguard Worker int rc;
18*2d543d20SAndroid Build Coastguard Worker
19*2d543d20SAndroid Build Coastguard Worker struct selinux_opt selinux_opts[] = {
20*2d543d20SAndroid Build Coastguard Worker { SELABEL_OPT_VALIDATE, opts->selabel_opt_validate },
21*2d543d20SAndroid Build Coastguard Worker { SELABEL_OPT_PATH, opts->selabel_opt_path },
22*2d543d20SAndroid Build Coastguard Worker { SELABEL_OPT_DIGEST, opts->selabel_opt_digest }
23*2d543d20SAndroid Build Coastguard Worker };
24*2d543d20SAndroid Build Coastguard Worker
25*2d543d20SAndroid Build Coastguard Worker opts->hnd = selabel_open(SELABEL_CTX_FILE, selinux_opts, 3);
26*2d543d20SAndroid Build Coastguard Worker if (!opts->hnd) {
27*2d543d20SAndroid Build Coastguard Worker perror(opts->selabel_opt_path);
28*2d543d20SAndroid Build Coastguard Worker exit(1);
29*2d543d20SAndroid Build Coastguard Worker }
30*2d543d20SAndroid Build Coastguard Worker
31*2d543d20SAndroid Build Coastguard Worker opts->restorecon_flags = 0;
32*2d543d20SAndroid Build Coastguard Worker opts->restorecon_flags = opts->nochange | opts->verbose |
33*2d543d20SAndroid Build Coastguard Worker opts->progress | opts->set_specctx |
34*2d543d20SAndroid Build Coastguard Worker opts->add_assoc | opts->ignore_digest |
35*2d543d20SAndroid Build Coastguard Worker opts->recurse | opts->userealpath |
36*2d543d20SAndroid Build Coastguard Worker opts->xdev | opts->abort_on_error |
37*2d543d20SAndroid Build Coastguard Worker opts->syslog_changes | opts->log_matches |
38*2d543d20SAndroid Build Coastguard Worker opts->ignore_noent | opts->ignore_mounts;
39*2d543d20SAndroid Build Coastguard Worker
40*2d543d20SAndroid Build Coastguard Worker /* Use setfiles, restorecon and restorecond own handles */
41*2d543d20SAndroid Build Coastguard Worker selinux_restorecon_set_sehandle(opts->hnd);
42*2d543d20SAndroid Build Coastguard Worker
43*2d543d20SAndroid Build Coastguard Worker if (opts->rootpath) {
44*2d543d20SAndroid Build Coastguard Worker rc = selinux_restorecon_set_alt_rootpath(opts->rootpath);
45*2d543d20SAndroid Build Coastguard Worker if (rc) {
46*2d543d20SAndroid Build Coastguard Worker fprintf(stderr,
47*2d543d20SAndroid Build Coastguard Worker "selinux_restorecon_set_alt_rootpath error: %s.\n",
48*2d543d20SAndroid Build Coastguard Worker strerror(errno));
49*2d543d20SAndroid Build Coastguard Worker exit(-1);
50*2d543d20SAndroid Build Coastguard Worker }
51*2d543d20SAndroid Build Coastguard Worker }
52*2d543d20SAndroid Build Coastguard Worker
53*2d543d20SAndroid Build Coastguard Worker if (exclude_list)
54*2d543d20SAndroid Build Coastguard Worker selinux_restorecon_set_exclude_list
55*2d543d20SAndroid Build Coastguard Worker ((const char **)exclude_list);
56*2d543d20SAndroid Build Coastguard Worker }
57*2d543d20SAndroid Build Coastguard Worker
restore_finish(void)58*2d543d20SAndroid Build Coastguard Worker void restore_finish(void)
59*2d543d20SAndroid Build Coastguard Worker {
60*2d543d20SAndroid Build Coastguard Worker int i;
61*2d543d20SAndroid Build Coastguard Worker
62*2d543d20SAndroid Build Coastguard Worker if (exclude_list) {
63*2d543d20SAndroid Build Coastguard Worker for (i = 0; exclude_list[i]; i++)
64*2d543d20SAndroid Build Coastguard Worker free(exclude_list[i]);
65*2d543d20SAndroid Build Coastguard Worker free(exclude_list);
66*2d543d20SAndroid Build Coastguard Worker }
67*2d543d20SAndroid Build Coastguard Worker }
68*2d543d20SAndroid Build Coastguard Worker
process_glob(char * name,struct restore_opts * opts)69*2d543d20SAndroid Build Coastguard Worker int process_glob(char *name, struct restore_opts *opts)
70*2d543d20SAndroid Build Coastguard Worker {
71*2d543d20SAndroid Build Coastguard Worker glob_t globbuf;
72*2d543d20SAndroid Build Coastguard Worker size_t i = 0;
73*2d543d20SAndroid Build Coastguard Worker int len, rc, errors;
74*2d543d20SAndroid Build Coastguard Worker
75*2d543d20SAndroid Build Coastguard Worker memset(&globbuf, 0, sizeof(globbuf));
76*2d543d20SAndroid Build Coastguard Worker
77*2d543d20SAndroid Build Coastguard Worker errors = glob(name, GLOB_TILDE | GLOB_PERIOD |
78*2d543d20SAndroid Build Coastguard Worker GLOB_NOCHECK | GLOB_BRACE, NULL, &globbuf);
79*2d543d20SAndroid Build Coastguard Worker if (errors)
80*2d543d20SAndroid Build Coastguard Worker return errors;
81*2d543d20SAndroid Build Coastguard Worker
82*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < globbuf.gl_pathc; i++) {
83*2d543d20SAndroid Build Coastguard Worker len = strlen(globbuf.gl_pathv[i]) - 2;
84*2d543d20SAndroid Build Coastguard Worker if (len > 0 && strcmp(&globbuf.gl_pathv[i][len--], "/.") == 0)
85*2d543d20SAndroid Build Coastguard Worker continue;
86*2d543d20SAndroid Build Coastguard Worker if (len > 0 && strcmp(&globbuf.gl_pathv[i][len], "/..") == 0)
87*2d543d20SAndroid Build Coastguard Worker continue;
88*2d543d20SAndroid Build Coastguard Worker rc = selinux_restorecon(globbuf.gl_pathv[i],
89*2d543d20SAndroid Build Coastguard Worker opts->restorecon_flags);
90*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
91*2d543d20SAndroid Build Coastguard Worker errors = rc;
92*2d543d20SAndroid Build Coastguard Worker }
93*2d543d20SAndroid Build Coastguard Worker
94*2d543d20SAndroid Build Coastguard Worker globfree(&globbuf);
95*2d543d20SAndroid Build Coastguard Worker
96*2d543d20SAndroid Build Coastguard Worker return errors;
97*2d543d20SAndroid Build Coastguard Worker }
98*2d543d20SAndroid Build Coastguard Worker
add_exclude(const char * directory)99*2d543d20SAndroid Build Coastguard Worker void add_exclude(const char *directory)
100*2d543d20SAndroid Build Coastguard Worker {
101*2d543d20SAndroid Build Coastguard Worker char **tmp_list;
102*2d543d20SAndroid Build Coastguard Worker
103*2d543d20SAndroid Build Coastguard Worker if (directory == NULL || directory[0] != '/') {
104*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "Full path required for exclude: %s.\n",
105*2d543d20SAndroid Build Coastguard Worker directory);
106*2d543d20SAndroid Build Coastguard Worker exit(-1);
107*2d543d20SAndroid Build Coastguard Worker }
108*2d543d20SAndroid Build Coastguard Worker
109*2d543d20SAndroid Build Coastguard Worker /* Add another two entries, one for directory, and the other to
110*2d543d20SAndroid Build Coastguard Worker * terminate the list.
111*2d543d20SAndroid Build Coastguard Worker */
112*2d543d20SAndroid Build Coastguard Worker tmp_list = realloc(exclude_list, sizeof(char *) * (exclude_count + 2));
113*2d543d20SAndroid Build Coastguard Worker if (!tmp_list) {
114*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "realloc failed while excluding %s.\n",
115*2d543d20SAndroid Build Coastguard Worker directory);
116*2d543d20SAndroid Build Coastguard Worker exit(-1);
117*2d543d20SAndroid Build Coastguard Worker }
118*2d543d20SAndroid Build Coastguard Worker exclude_list = tmp_list;
119*2d543d20SAndroid Build Coastguard Worker
120*2d543d20SAndroid Build Coastguard Worker exclude_list[exclude_count] = strdup(directory);
121*2d543d20SAndroid Build Coastguard Worker if (!exclude_list[exclude_count]) {
122*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "strdup failed while excluding %s.\n",
123*2d543d20SAndroid Build Coastguard Worker directory);
124*2d543d20SAndroid Build Coastguard Worker exit(-1);
125*2d543d20SAndroid Build Coastguard Worker }
126*2d543d20SAndroid Build Coastguard Worker exclude_count++;
127*2d543d20SAndroid Build Coastguard Worker exclude_list[exclude_count] = NULL;
128*2d543d20SAndroid Build Coastguard Worker }
129