blob: e353ef348578f3e0439e6dfd985856b3e689636b [file] [log] [blame]
Joshua Brindle13cd4c82008-08-19 15:30:36 -04001#include <stdio.h>
2#include <stdlib.h>
3#include <ctype.h>
4#include <errno.h>
5
6#include <sepol/policydb/policydb.h>
7#include <sepol/policydb/conditional.h>
8
9#include "debug.h"
10#include "private.h"
11#include "dso.h"
12
13/* -- Deprecated -- */
14
15static char *strtrim(char *dest, char *source, int size)
16{
17 int i = 0;
18 char *ptr = source;
19 i = 0;
20 while (isspace(*ptr) && i < size) {
21 ptr++;
22 i++;
23 }
24 strncpy(dest, ptr, size);
25 for (i = strlen(dest) - 1; i > 0; i--) {
26 if (!isspace(dest[i]))
27 break;
28 }
29 dest[i + 1] = '\0';
30 return dest;
31}
32
33static int process_boolean(char *buffer, char *name, int namesize, int *val)
34{
35 char name1[BUFSIZ];
36 char *ptr;
37 char *tok = strtok_r(buffer, "=", &ptr);
38 if (tok) {
39 strncpy(name1, tok, BUFSIZ - 1);
40 strtrim(name, name1, namesize - 1);
41 if (name[0] == '#')
42 return 0;
43 tok = strtok_r(NULL, "\0", &ptr);
44 if (tok) {
45 while (isspace(*tok))
46 tok++;
47 *val = -1;
48 if (isdigit(tok[0]))
49 *val = atoi(tok);
50 else if (!strncasecmp(tok, "true", sizeof("true") - 1))
51 *val = 1;
52 else if (!strncasecmp
53 (tok, "false", sizeof("false") - 1))
54 *val = 0;
55 if (*val != 0 && *val != 1) {
56 ERR(NULL, "illegal value for boolean "
57 "%s=%s", name, tok);
58 return -1;
59 }
60
61 }
62 }
63 return 1;
64}
65
66static int load_booleans(struct policydb *policydb, const char *path,
67 int *changesp)
68{
69 FILE *boolf;
70 char *buffer = NULL;
71 size_t size = 0;
72 char localbools[BUFSIZ];
73 char name[BUFSIZ];
74 int val;
75 int errors = 0, changes = 0;
76 struct cond_bool_datum *datum;
77
78 boolf = fopen(path, "r");
79 if (boolf == NULL)
80 goto localbool;
81
82 while (getline(&buffer, &size, boolf) > 0) {
83 int ret = process_boolean(buffer, name, sizeof(name), &val);
84 if (ret == -1)
85 errors++;
86 if (ret == 1) {
87 datum = hashtab_search(policydb->p_bools.table, name);
88 if (!datum) {
89 ERR(NULL, "unknown boolean %s", name);
90 errors++;
91 continue;
92 }
93 if (datum->state != val) {
94 datum->state = val;
95 changes++;
96 }
97 }
98 }
99 fclose(boolf);
100 localbool:
101 snprintf(localbools, sizeof(localbools), "%s.local", path);
102 boolf = fopen(localbools, "r");
103 if (boolf != NULL) {
104 while (getline(&buffer, &size, boolf) > 0) {
105 int ret =
106 process_boolean(buffer, name, sizeof(name), &val);
107 if (ret == -1)
108 errors++;
109 if (ret == 1) {
110 datum =
111 hashtab_search(policydb->p_bools.table,
112 name);
113 if (!datum) {
114 ERR(NULL, "unknown boolean %s", name);
115 errors++;
116 continue;
117 }
118 if (datum->state != val) {
119 datum->state = val;
120 changes++;
121 }
122 }
123 }
124 fclose(boolf);
125 }
126 free(buffer);
127 if (errors)
128 errno = EINVAL;
129 *changesp = changes;
130 return errors ? -1 : 0;
131}
132
133int sepol_genbools(void *data, size_t len, char *booleans)
134{
135 struct policydb policydb;
136 struct policy_file pf;
137 int rc, changes = 0;
138
139 if (policydb_init(&policydb))
140 goto err;
141 if (policydb_from_image(NULL, data, len, &policydb) < 0)
142 goto err;
143
144 if (load_booleans(&policydb, booleans, &changes) < 0) {
145 WARN(NULL, "error while reading %s", booleans);
146 }
147
148 if (!changes)
149 goto out;
150
151 if (evaluate_conds(&policydb) < 0) {
152 ERR(NULL, "error while re-evaluating conditionals");
153 errno = EINVAL;
154 goto err_destroy;
155 }
156
157 policy_file_init(&pf);
158 pf.type = PF_USE_MEMORY;
159 pf.data = data;
160 pf.len = len;
161 rc = policydb_write(&policydb, &pf);
162 if (rc) {
163 ERR(NULL, "unable to write new binary policy image");
164 errno = EINVAL;
165 goto err_destroy;
166 }
167
168 out:
169 policydb_destroy(&policydb);
170 return 0;
171
172 err_destroy:
173 policydb_destroy(&policydb);
174
175 err:
176 return -1;
177}
178
179int hidden sepol_genbools_policydb(policydb_t * policydb, const char *booleans)
180{
181 int rc, changes = 0;
182
183 rc = load_booleans(policydb, booleans, &changes);
184 if (!rc && changes)
185 rc = evaluate_conds(policydb);
186 if (rc)
187 errno = EINVAL;
188 return rc;
189}
190
191/* -- End Deprecated -- */
192
193int sepol_genbools_array(void *data, size_t len, char **names, int *values,
194 int nel)
195{
196 struct policydb policydb;
197 struct policy_file pf;
198 int rc, i, errors = 0;
199 struct cond_bool_datum *datum;
200
201 /* Create policy database from image */
202 if (policydb_init(&policydb))
203 goto err;
204 if (policydb_from_image(NULL, data, len, &policydb) < 0)
205 goto err;
206
207 for (i = 0; i < nel; i++) {
208 datum = hashtab_search(policydb.p_bools.table, names[i]);
209 if (!datum) {
210 ERR(NULL, "boolean %s no longer in policy", names[i]);
211 errors++;
212 continue;
213 }
214 if (values[i] != 0 && values[i] != 1) {
215 ERR(NULL, "illegal value %d for boolean %s",
216 values[i], names[i]);
217 errors++;
218 continue;
219 }
220 datum->state = values[i];
221 }
222
223 if (evaluate_conds(&policydb) < 0) {
224 ERR(NULL, "error while re-evaluating conditionals");
225 errno = EINVAL;
226 goto err_destroy;
227 }
228
229 policy_file_init(&pf);
230 pf.type = PF_USE_MEMORY;
231 pf.data = data;
232 pf.len = len;
233 rc = policydb_write(&policydb, &pf);
234 if (rc) {
235 ERR(NULL, "unable to write binary policy");
236 errno = EINVAL;
237 goto err_destroy;
238 }
239 if (errors) {
240 errno = EINVAL;
241 goto err_destroy;
242 }
243
244 policydb_destroy(&policydb);
245 return 0;
246
247 err_destroy:
248 policydb_destroy(&policydb);
249
250 err:
251 return -1;
252}