1 struct semanage_fcontext;
2 struct semanage_fcontext_key;
3 typedef struct semanage_fcontext record_t;
4 typedef struct semanage_fcontext_key record_key_t;
5 #define DBASE_RECORD_DEFINED
6
7 #include <stdlib.h>
8 #include <string.h>
9 #include "fcontext_internal.h"
10 #include "debug.h"
11
12 struct semanage_fcontext {
13
14 /* Matching expression */
15 char *expr;
16
17 /* Type of object */
18 int type;
19
20 /* Context */
21 semanage_context_t *con;
22 };
23
24 struct semanage_fcontext_key {
25
26 /* Matching expression */
27 char *expr;
28
29 /* Type of object */
30 int type;
31 };
32
33 /* Key */
semanage_fcontext_key_create(semanage_handle_t * handle,const char * expr,int type,semanage_fcontext_key_t ** key_ptr)34 int semanage_fcontext_key_create(semanage_handle_t * handle,
35 const char *expr,
36 int type, semanage_fcontext_key_t ** key_ptr)
37 {
38
39 semanage_fcontext_key_t *tmp_key =
40 (semanage_fcontext_key_t *) malloc(sizeof(semanage_fcontext_key_t));
41
42 if (!tmp_key) {
43 ERR(handle, "out of memory, could not "
44 "create file context key");
45 return STATUS_ERR;
46 }
47 tmp_key->expr = strdup(expr);
48 if (!tmp_key->expr) {
49 ERR(handle, "out of memory, could not create file context key.");
50 free(tmp_key);
51 return STATUS_ERR;
52 }
53 tmp_key->type = type;
54
55 *key_ptr = tmp_key;
56 return STATUS_SUCCESS;
57 }
58
59
semanage_fcontext_key_extract(semanage_handle_t * handle,const semanage_fcontext_t * fcontext,semanage_fcontext_key_t ** key_ptr)60 int semanage_fcontext_key_extract(semanage_handle_t * handle,
61 const semanage_fcontext_t * fcontext,
62 semanage_fcontext_key_t ** key_ptr)
63 {
64
65 if (semanage_fcontext_key_create(handle, fcontext->expr,
66 fcontext->type, key_ptr) < 0) {
67 ERR(handle, "could not extract key from "
68 "file context %s (%s)", fcontext->expr,
69 semanage_fcontext_get_type_str(fcontext->type));
70 return STATUS_ERR;
71 }
72
73 return STATUS_SUCCESS;
74 }
75
76
semanage_fcontext_key_free(semanage_fcontext_key_t * key)77 void semanage_fcontext_key_free(semanage_fcontext_key_t * key)
78 {
79 free(key->expr);
80 free(key);
81 }
82
83
semanage_fcontext_compare(const semanage_fcontext_t * fcontext,const semanage_fcontext_key_t * key)84 int semanage_fcontext_compare(const semanage_fcontext_t * fcontext,
85 const semanage_fcontext_key_t * key)
86 {
87
88 int rv = strcmp(fcontext->expr, key->expr);
89 if (rv != 0)
90 return rv;
91 else {
92 if (fcontext->type < key->type)
93 return -1;
94
95 else if (key->type < fcontext->type)
96 return 1;
97
98 else
99 return 0;
100 }
101 }
102
103
semanage_fcontext_compare2(const semanage_fcontext_t * fcontext,const semanage_fcontext_t * fcontext2)104 int semanage_fcontext_compare2(const semanage_fcontext_t * fcontext,
105 const semanage_fcontext_t * fcontext2)
106 {
107
108 int rv = strcmp(fcontext->expr, fcontext2->expr);
109 if (rv != 0)
110 return rv;
111 else {
112 if (fcontext->type < fcontext2->type)
113 return -1;
114
115 else if (fcontext2->type < fcontext->type)
116 return 1;
117
118 else
119 return 0;
120 }
121 }
122
123
semanage_fcontext_compare2_qsort(const semanage_fcontext_t ** fcontext,const semanage_fcontext_t ** fcontext2)124 static int semanage_fcontext_compare2_qsort(const semanage_fcontext_t **
125 fcontext,
126 const semanage_fcontext_t **
127 fcontext2)
128 {
129
130 return semanage_fcontext_compare2(*fcontext, *fcontext2);
131 }
132
133 /* Create */
semanage_fcontext_create(semanage_handle_t * handle,semanage_fcontext_t ** fcontext)134 int semanage_fcontext_create(semanage_handle_t * handle,
135 semanage_fcontext_t ** fcontext)
136 {
137
138 semanage_fcontext_t *tmp_fcontext =
139 (semanage_fcontext_t *) malloc(sizeof(semanage_fcontext_t));
140
141 if (!tmp_fcontext) {
142 ERR(handle, "out of memory, could not create "
143 "file context record");
144 return STATUS_ERR;
145 }
146
147 tmp_fcontext->expr = NULL;
148 tmp_fcontext->type = SEMANAGE_FCONTEXT_ALL;
149 tmp_fcontext->con = NULL;
150 *fcontext = tmp_fcontext;
151
152 return STATUS_SUCCESS;
153 }
154
155
156 /* Regexp */
semanage_fcontext_get_expr(const semanage_fcontext_t * fcontext)157 const char *semanage_fcontext_get_expr(const semanage_fcontext_t * fcontext)
158 {
159
160 return fcontext->expr;
161 }
162
163
semanage_fcontext_set_expr(semanage_handle_t * handle,semanage_fcontext_t * fcontext,const char * expr)164 int semanage_fcontext_set_expr(semanage_handle_t * handle,
165 semanage_fcontext_t * fcontext, const char *expr)
166 {
167
168 char *tmp_expr = strdup(expr);
169 if (!tmp_expr) {
170 ERR(handle, "out of memory, " "could not set regexp string");
171 return STATUS_ERR;
172 }
173 free(fcontext->expr);
174 fcontext->expr = tmp_expr;
175 return STATUS_SUCCESS;
176 }
177
178
179 /* Type */
semanage_fcontext_get_type(const semanage_fcontext_t * fcontext)180 int semanage_fcontext_get_type(const semanage_fcontext_t * fcontext)
181 {
182
183 return fcontext->type;
184 }
185
186
semanage_fcontext_get_type_str(int type)187 const char *semanage_fcontext_get_type_str(int type)
188 {
189
190 switch (type) {
191 case SEMANAGE_FCONTEXT_ALL:
192 return "all files";
193 case SEMANAGE_FCONTEXT_REG:
194 return "regular file";
195 case SEMANAGE_FCONTEXT_DIR:
196 return "directory";
197 case SEMANAGE_FCONTEXT_CHAR:
198 return "character device";
199 case SEMANAGE_FCONTEXT_BLOCK:
200 return "block device";
201 case SEMANAGE_FCONTEXT_SOCK:
202 return "socket";
203 case SEMANAGE_FCONTEXT_LINK:
204 return "symbolic link";
205 case SEMANAGE_FCONTEXT_PIPE:
206 return "named pipe";
207 default:
208 return "????";
209 }
210 }
211
212
semanage_fcontext_set_type(semanage_fcontext_t * fcontext,int type)213 void semanage_fcontext_set_type(semanage_fcontext_t * fcontext, int type)
214 {
215
216 fcontext->type = type;
217 }
218
219
220 /* Context */
semanage_fcontext_get_con(const semanage_fcontext_t * fcontext)221 semanage_context_t *semanage_fcontext_get_con(const semanage_fcontext_t *
222 fcontext)
223 {
224
225 return fcontext->con;
226 }
227
228
semanage_fcontext_set_con(semanage_handle_t * handle,semanage_fcontext_t * fcontext,semanage_context_t * con)229 int semanage_fcontext_set_con(semanage_handle_t * handle,
230 semanage_fcontext_t * fcontext,
231 semanage_context_t * con)
232 {
233
234 semanage_context_t *newcon;
235
236 if (semanage_context_clone(handle, con, &newcon) < 0) {
237 ERR(handle, "out of memory, could not set file context");
238 return STATUS_ERR;
239 }
240
241 semanage_context_free(fcontext->con);
242 fcontext->con = newcon;
243 return STATUS_SUCCESS;
244 }
245
246
247 /* Deep copy clone */
semanage_fcontext_clone(semanage_handle_t * handle,const semanage_fcontext_t * fcontext,semanage_fcontext_t ** fcontext_ptr)248 int semanage_fcontext_clone(semanage_handle_t * handle,
249 const semanage_fcontext_t * fcontext,
250 semanage_fcontext_t ** fcontext_ptr)
251 {
252
253 semanage_fcontext_t *new_fcontext = NULL;
254 if (semanage_fcontext_create(handle, &new_fcontext) < 0)
255 goto err;
256
257 if (semanage_fcontext_set_expr(handle, new_fcontext, fcontext->expr) <
258 0)
259 goto err;
260
261 new_fcontext->type = fcontext->type;
262
263 if (fcontext->con &&
264 (semanage_context_clone(handle, fcontext->con, &new_fcontext->con) <
265 0))
266 goto err;
267
268 *fcontext_ptr = new_fcontext;
269 return STATUS_SUCCESS;
270
271 err:
272 ERR(handle, "could not clone file context record");
273 semanage_fcontext_free(new_fcontext);
274 return STATUS_ERR;
275 }
276
277
278 /* Destroy */
semanage_fcontext_free(semanage_fcontext_t * fcontext)279 void semanage_fcontext_free(semanage_fcontext_t * fcontext)
280 {
281
282 if (!fcontext)
283 return;
284
285 free(fcontext->expr);
286 semanage_context_free(fcontext->con);
287 free(fcontext);
288 }
289
290
291 /* Record base functions */
292 record_table_t SEMANAGE_FCONTEXT_RTABLE = {
293 .create = semanage_fcontext_create,
294 .key_extract = semanage_fcontext_key_extract,
295 .key_free = semanage_fcontext_key_free,
296 .clone = semanage_fcontext_clone,
297 .compare = semanage_fcontext_compare,
298 .compare2 = semanage_fcontext_compare2,
299 .compare2_qsort = semanage_fcontext_compare2_qsort,
300 .free = semanage_fcontext_free,
301 };
302