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