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