• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Authors: Jan Zarsky <jzarsky@redhat.com>
3  *
4  * Copyright (C) 2019 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20 
21 #include "utilities.h"
22 #include "test_fcontext.h"
23 
24 char FCONTEXTS[] =
25     "/etc/selinux(/.*) -s system_u:object_r:first_t:s0\n"
26     "/etc/selinux/targeted -- system_u:object_r:second_t:s0\n"
27     "/etc/selinux(/.*) -b system_u:object_r:third_t:s0\n";
28 unsigned int FCONTEXTS_LEN = sizeof(FCONTEXTS);
29 
30 #define FCONTEXTS_COUNT 3
31 
32 #define FCONTEXT1_EXPR "/etc/selinux(/.*)"
33 #define FCONTEXT1_TYPE SEMANAGE_FCONTEXT_SOCK
34 #define FCONTEXT1_CON "system_u:object_r:first_t:s0"
35 
36 #define FCONTEXT2_EXPR "/etc/selinux/targeted"
37 #define FCONTEXT2_TYPE SEMANAGE_FCONTEXT_REG
38 #define FCONTEXT2_CON "system_u:object_r:second_t:s0"
39 
40 #define FCONTEXT3_EXPR "/etc/selinux(/.*)"
41 #define FCONTEXT3_TYPE SEMANAGE_FCONTEXT_BLOCK
42 #define FCONTEXT3_CON "system_u:object_r:third_t:s0"
43 
44 #define FCONTEXT_NONEXISTENT_EXPR "/asdf"
45 #define FCONTEXT_NONEXISTENT_TYPE SEMANAGE_FCONTEXT_ALL
46 
47 /* fcontext_record.h */
48 void test_fcontext_compare(void);
49 void test_fcontext_compare2(void);
50 void test_fcontext_key_create(void);
51 void test_fcontext_key_extract(void);
52 void test_fcontext_get_set_expr(void);
53 void test_fcontext_get_set_type(void);
54 void test_fcontext_get_type_str(void);
55 void test_fcontext_get_set_con(void);
56 void test_fcontext_create(void);
57 void test_fcontext_clone(void);
58 
59 /* fcontext_policy.h */
60 void test_fcontext_query(void);
61 void test_fcontext_exists(void);
62 void test_fcontext_count(void);
63 void test_fcontext_iterate(void);
64 void test_fcontext_list(void);
65 
66 /* fcontext_local.h */
67 void test_fcontext_modify_del_local(void);
68 void test_fcontext_query_local(void);
69 void test_fcontext_exists_local(void);
70 void test_fcontext_count_local(void);
71 void test_fcontext_iterate_local(void);
72 void test_fcontext_list_local(void);
73 
74 extern semanage_handle_t *sh;
75 
get_type(char * t)76 int get_type(char *t)
77 {
78 	if (strcmp(t, "--") == 0)
79 		return SEMANAGE_FCONTEXT_ALL;
80 	else if (strcmp(t, "-f") == 0)
81 		return SEMANAGE_FCONTEXT_REG;
82 	else if (strcmp(t, "-d") == 0)
83 		return SEMANAGE_FCONTEXT_DIR;
84 	else if (strcmp(t, "-c") == 0)
85 		return SEMANAGE_FCONTEXT_CHAR;
86 	else if (strcmp(t, "-b") == 0)
87 		return SEMANAGE_FCONTEXT_BLOCK;
88 	else if (strcmp(t, "-s") == 0)
89 		return SEMANAGE_FCONTEXT_SOCK;
90 	else if (strcmp(t, "-l") == 0)
91 		return SEMANAGE_FCONTEXT_LINK;
92 	else if (strcmp(t, "-p") == 0)
93 		return SEMANAGE_FCONTEXT_PIPE;
94 	else
95 		return -1;
96 }
97 
write_file_contexts(const char * data,unsigned int data_len)98 int write_file_contexts(const char *data, unsigned int data_len)
99 {
100 	FILE *fptr = fopen("test-policy/store/active/file_contexts", "w+");
101 
102 	if (!fptr) {
103 		perror("fopen");
104 		return -1;
105 	}
106 
107 	if (fwrite(data, data_len, 1, fptr) != 1) {
108 		perror("fwrite");
109 		fclose(fptr);
110 		return -1;
111 	}
112 
113 	fclose(fptr);
114 
115 	return 0;
116 }
117 
fcontext_test_init(void)118 int fcontext_test_init(void)
119 {
120 	if (create_test_store() < 0) {
121 		fprintf(stderr, "Could not create test store\n");
122 		return 1;
123 	}
124 
125 	if (write_test_policy_from_file("test_fcontext.policy") < 0) {
126 		fprintf(stderr, "Could not write test policy\n");
127 		return 1;
128 	}
129 
130 	if (write_file_contexts(FCONTEXTS, FCONTEXTS_LEN) < 0) {
131 		fprintf(stderr, "Could not write file contexts\n");
132 		return 1;
133 	}
134 
135 	return 0;
136 }
137 
fcontext_test_cleanup(void)138 int fcontext_test_cleanup(void)
139 {
140 	if (destroy_test_store() < 0) {
141 		fprintf(stderr, "Could not destroy test store\n");
142 		return 1;
143 	}
144 
145 	return 0;
146 }
147 
fcontext_add_tests(CU_pSuite suite)148 int fcontext_add_tests(CU_pSuite suite)
149 {
150 	CU_add_test(suite, "test_fcontext_compare", test_fcontext_compare);
151 	CU_add_test(suite, "test_fcontext_compare2", test_fcontext_compare2);
152 	CU_add_test(suite, "test_fcontext_key_create",
153 		    test_fcontext_key_create);
154 	CU_add_test(suite, "test_fcontext_key_extract",
155 		    test_fcontext_key_extract);
156 	CU_add_test(suite, "test_fcontext_get_set_expr",
157 		    test_fcontext_get_set_expr);
158 	CU_add_test(suite, "test_fcontext_get_set_type",
159 		    test_fcontext_get_set_type);
160 	CU_add_test(suite, "test_fcontext_get_type_str",
161 		    test_fcontext_get_type_str);
162 	CU_add_test(suite, "test_fcontext_get_set_con",
163 		    test_fcontext_get_set_con);
164 	CU_add_test(suite, "test_fcontext_create", test_fcontext_create);
165 	CU_add_test(suite, "test_fcontext_clone", test_fcontext_clone);
166 
167 	CU_add_test(suite, "test_fcontext_query", test_fcontext_query);
168 	CU_add_test(suite, "test_fcontext_exists", test_fcontext_exists);
169 	CU_add_test(suite, "test_fcontext_count", test_fcontext_count);
170 	CU_add_test(suite, "test_fcontext_iterate", test_fcontext_iterate);
171 	CU_add_test(suite, "test_fcontext_list", test_fcontext_list);
172 	CU_add_test(suite, "test_fcontext_modify_del_local",
173 		    test_fcontext_modify_del_local);
174 	CU_add_test(suite, "test_fcontext_query_local",
175 		    test_fcontext_query_local);
176 	CU_add_test(suite, "test_fcontext_exists_local",
177 		    test_fcontext_exists_local);
178 	CU_add_test(suite, "test_fcontext_count_local",
179 		    test_fcontext_count_local);
180 	CU_add_test(suite, "test_fcontext_iterate_local",
181 		    test_fcontext_iterate_local);
182 	CU_add_test(suite, "test_fcontext_list_local",
183 		    test_fcontext_list_local);
184 
185 	return 0;
186 }
187 
188 /* Helpers */
189 
get_fcontext_new(void)190 semanage_fcontext_t *get_fcontext_new(void)
191 {
192 	semanage_fcontext_t *fcontext;
193 
194 	CU_ASSERT_FATAL(semanage_fcontext_create(sh, &fcontext) >= 0);
195 
196 	return fcontext;
197 }
198 
get_fcontext_nth(int idx)199 semanage_fcontext_t *get_fcontext_nth(int idx)
200 {
201 	semanage_fcontext_t **records;
202 	semanage_fcontext_t *fcontext;
203 	unsigned int count;
204 
205 	if (idx == I_NULL)
206 		return NULL;
207 
208 	CU_ASSERT_FATAL(semanage_fcontext_list(sh, &records, &count) >= 0);
209 	CU_ASSERT_FATAL(count >= (unsigned int) idx + 1);
210 
211 	fcontext = records[idx];
212 
213 	for (unsigned int i = 0; i < count; i++)
214 		if (i != (unsigned int) idx)
215 			semanage_fcontext_free(records[i]);
216 
217 	free(records);
218 
219 	return fcontext;
220 }
221 
get_fcontext_key_nth(int idx)222 semanage_fcontext_key_t *get_fcontext_key_nth(int idx)
223 {
224 	semanage_fcontext_key_t *key;
225 	semanage_fcontext_t *fcontext;
226 
227 	if (idx == I_NULL)
228 		return NULL;
229 
230 	fcontext = get_fcontext_nth(idx);
231 
232 	CU_ASSERT_FATAL(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
233 	CU_ASSERT_PTR_NOT_NULL_FATAL(key);
234 
235 	semanage_fcontext_free(fcontext);
236 
237 	return key;
238 }
239 
add_local_fcontext(int fcontext_idx)240 void add_local_fcontext(int fcontext_idx)
241 {
242 	semanage_fcontext_t *fcontext;
243 	semanage_fcontext_key_t *key = NULL;
244 
245 	CU_ASSERT_FATAL(fcontext_idx != I_NULL);
246 
247 	fcontext = get_fcontext_nth(fcontext_idx);
248 
249 	CU_ASSERT_FATAL(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
250 	CU_ASSERT_PTR_NOT_NULL_FATAL(key);
251 
252 	CU_ASSERT_FATAL(semanage_fcontext_modify_local(sh, key, fcontext) >= 0);
253 
254 	/* cleanup */
255 	semanage_fcontext_key_free(key);
256 	semanage_fcontext_free(fcontext);
257 }
258 
delete_local_fcontext(int fcontext_idx)259 void delete_local_fcontext(int fcontext_idx)
260 {
261 	semanage_fcontext_key_t *key = NULL;
262 
263 	CU_ASSERT_FATAL(fcontext_idx != I_NULL);
264 
265 	key = get_fcontext_key_nth(fcontext_idx);
266 
267 	CU_ASSERT_FATAL(semanage_fcontext_del_local(sh, key) >= 0);
268 
269 	semanage_fcontext_key_free(key);
270 }
271 
get_fcontext_key_from_str(const char * str,int type)272 semanage_fcontext_key_t *get_fcontext_key_from_str(const char *str, int type)
273 {
274 	semanage_fcontext_key_t *key;
275 	int res;
276 
277 	if (str == NULL)
278 		return NULL;
279 
280 	res = semanage_fcontext_key_create(sh, str, type, &key);
281 
282 	CU_ASSERT_FATAL(res >= 0);
283 	CU_ASSERT_PTR_NOT_NULL_FATAL(key);
284 
285 	return key;
286 }
287 
288 /* Function semanage_fcontext_compare */
test_fcontext_compare(void)289 void test_fcontext_compare(void)
290 {
291 	semanage_fcontext_t *fcontext;
292 	semanage_fcontext_key_t *key1;
293 	semanage_fcontext_key_t *key2;
294 	semanage_fcontext_key_t *key3;
295 
296 	/* setup */
297 	setup_handle(SH_CONNECT);
298 
299 	fcontext = get_fcontext_nth(I_FIRST);
300 
301 	key1 = get_fcontext_key_nth(I_FIRST);
302 	key2 = get_fcontext_key_nth(I_SECOND);
303 	key3 = get_fcontext_key_nth(I_THIRD);
304 
305 	/* test */
306 	CU_ASSERT(semanage_fcontext_compare(fcontext, key1) == 0);
307 	CU_ASSERT(semanage_fcontext_compare(fcontext, key2) < 0);
308 	CU_ASSERT(semanage_fcontext_compare(fcontext, key3) > 0);
309 
310 	/* cleanup */
311 	semanage_fcontext_free(fcontext);
312 	semanage_fcontext_key_free(key1);
313 	semanage_fcontext_key_free(key2);
314 	semanage_fcontext_key_free(key3);
315 	cleanup_handle(SH_CONNECT);
316 }
317 
318 /* Function semanage_fcontext_compare2 */
test_fcontext_compare2(void)319 void test_fcontext_compare2(void)
320 {
321 	semanage_fcontext_t *fcontext;
322 	semanage_fcontext_t *fcontext1;
323 	semanage_fcontext_t *fcontext2;
324 	semanage_fcontext_t *fcontext3;
325 
326 	/* setup */
327 	setup_handle(SH_CONNECT);
328 
329 	fcontext = get_fcontext_nth(I_FIRST);
330 	fcontext1 = get_fcontext_nth(I_FIRST);
331 	fcontext2 = get_fcontext_nth(I_SECOND);
332 	fcontext3 = get_fcontext_nth(I_THIRD);
333 
334 	/* test */
335 	CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext1) == 0);
336 	CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext2) < 0);
337 	CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext3) > 0);
338 
339 	/* cleanup */
340 	semanage_fcontext_free(fcontext);
341 	semanage_fcontext_free(fcontext1);
342 	semanage_fcontext_free(fcontext2);
343 	semanage_fcontext_free(fcontext3);
344 	cleanup_handle(SH_CONNECT);
345 }
346 
347 /* Function semanage_fcontext_key_create */
test_fcontext_key_create(void)348 void test_fcontext_key_create(void)
349 {
350 	semanage_fcontext_key_t *key = NULL;
351 
352 	/* setup */
353 	setup_handle(SH_CONNECT);
354 
355 	/* test */
356 	CU_ASSERT(semanage_fcontext_key_create(sh, "", SEMANAGE_FCONTEXT_ALL,
357 					       &key) >= 0);
358 	CU_ASSERT_PTR_NOT_NULL(key);
359 
360 	semanage_fcontext_key_free(key);
361 
362 	key = NULL;
363 
364 	CU_ASSERT(semanage_fcontext_key_create(sh, "testfcontext",
365 					     SEMANAGE_FCONTEXT_ALL, &key) >= 0);
366 	CU_ASSERT_PTR_NOT_NULL(key);
367 
368 	semanage_fcontext_key_free(key);
369 
370 	/* cleanup */
371 	cleanup_handle(SH_CONNECT);
372 }
373 
374 /* Function semanage_fcontext_key_extract */
test_fcontext_key_extract(void)375 void test_fcontext_key_extract(void)
376 {
377 	semanage_fcontext_t *fcontext;
378 	semanage_fcontext_key_t *key;
379 
380 	/* setup */
381 	setup_handle(SH_CONNECT);
382 	fcontext = get_fcontext_nth(I_FIRST);
383 
384 	/* test */
385 	CU_ASSERT(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
386 	CU_ASSERT_PTR_NOT_NULL(key);
387 
388 	/* cleanup */
389 	semanage_fcontext_key_free(key);
390 	semanage_fcontext_free(fcontext);
391 	cleanup_handle(SH_CONNECT);
392 }
393 
394 /* Function semanage_fcontext_get_expr, semanage_fcontext_set_expr */
test_fcontext_get_set_expr(void)395 void test_fcontext_get_set_expr(void)
396 {
397 	semanage_fcontext_t *fcontext;
398 	const char *expr = NULL;
399 	const char *expr_exp = "/asdf";
400 
401 	/* setup */
402 	setup_handle(SH_CONNECT);
403 	fcontext = get_fcontext_nth(I_FIRST);
404 
405 	/* test */
406 	CU_ASSERT(semanage_fcontext_set_expr(sh, fcontext, expr_exp) >= 0);
407 	expr = semanage_fcontext_get_expr(fcontext);
408 	CU_ASSERT_PTR_NOT_NULL(expr);
409 	assert(expr);
410 	CU_ASSERT_STRING_EQUAL(expr, expr_exp);
411 
412 	/* cleanup */
413 	semanage_fcontext_free(fcontext);
414 	cleanup_handle(SH_CONNECT);
415 }
416 
417 /* Function semanage_fcontext_get_type, semanage_fcontext_set_type */
test_fcontext_get_set_type(void)418 void test_fcontext_get_set_type(void)
419 {
420 	semanage_fcontext_t *fcontext;
421 	int type_exp = SEMANAGE_FCONTEXT_SOCK;
422 	int type;
423 
424 	/* setup */
425 	setup_handle(SH_CONNECT);
426 	fcontext = get_fcontext_nth(I_FIRST);
427 
428 	/* test */
429 	semanage_fcontext_set_type(fcontext, type_exp);
430 	type = semanage_fcontext_get_type(fcontext);
431 	CU_ASSERT(type == type_exp);
432 
433 	/* cleanup */
434 	semanage_fcontext_free(fcontext);
435 	cleanup_handle(SH_CONNECT);
436 }
437 
438 /* Function semanage_fcontext_get_type_str */
helper_fcontext_get_type_str(int type,const char * exp_str)439 void helper_fcontext_get_type_str(int type, const char *exp_str)
440 {
441 	CU_ASSERT_STRING_EQUAL(semanage_fcontext_get_type_str(type), exp_str);
442 }
443 
test_fcontext_get_type_str(void)444 void test_fcontext_get_type_str(void)
445 {
446 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_ALL, "all files");
447 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_REG, "regular file");
448 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_DIR, "directory");
449 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_CHAR,
450 				     "character device");
451 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_BLOCK, "block device");
452 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_SOCK, "socket");
453 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_LINK, "symbolic link");
454 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_PIPE, "named pipe");
455 
456 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_ALL - 1, "????");
457 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_PIPE + 1, "????");
458 }
459 
460 /* Function semanage_fcontext_get_con, semanage_fcontext_set_con */
helper_fcontext_get_set_con(level_t level,int fcontext_idx,const char * con_str)461 void helper_fcontext_get_set_con(level_t level, int fcontext_idx,
462 				 const char *con_str)
463 {
464 	semanage_fcontext_t *fcontext;
465 	semanage_context_t *con = NULL;
466 	semanage_context_t *new_con = NULL;
467 
468 	/* setup */
469 	setup_handle(level);
470 	fcontext = get_fcontext_nth(fcontext_idx);
471 
472 	if (con_str != NULL) {
473 		CU_ASSERT(semanage_context_from_string(sh, con_str, &con) >= 0);
474 		CU_ASSERT_PTR_NOT_NULL(con);
475 	} else {
476 		con = NULL;
477 	}
478 
479 	/* test */
480 	CU_ASSERT(semanage_fcontext_set_con(sh, fcontext, con) >= 0);
481 	new_con = semanage_fcontext_get_con(fcontext);
482 
483 	if (con_str != NULL) {
484 		CU_ASSERT_CONTEXT_EQUAL(con, new_con);
485 	} else {
486 		CU_ASSERT_PTR_NULL(new_con);
487 	}
488 
489 	/* cleanup */
490 	semanage_context_free(con);
491 	semanage_fcontext_free(fcontext);
492 	cleanup_handle(level);
493 }
494 
test_fcontext_get_set_con(void)495 void test_fcontext_get_set_con(void)
496 {
497 	helper_fcontext_get_set_con(SH_CONNECT, I_FIRST, NULL);
498 	helper_fcontext_get_set_con(SH_CONNECT, I_FIRST,
499 				    "user_u:role_r:type_t:s0");
500 	helper_fcontext_get_set_con(SH_CONNECT, I_SECOND,
501 				    "user_u:role_r:type_t:s0");
502 	helper_fcontext_get_set_con(SH_TRANS, I_FIRST, NULL);
503 	helper_fcontext_get_set_con(SH_TRANS, I_FIRST,
504 				    "user_u:role_r:type_t:s0");
505 	helper_fcontext_get_set_con(SH_TRANS, I_SECOND,
506 				    "user_u:role_r:type_t:s0");
507 }
508 
509 /* Function semanage_fcontext_create */
helper_fcontext_create(level_t level)510 void helper_fcontext_create(level_t level)
511 {
512 	semanage_fcontext_t *fcontext;
513 
514 	/* setup */
515 	setup_handle(level);
516 
517 	/* test */
518 	CU_ASSERT(semanage_fcontext_create(sh, &fcontext) >= 0);
519 	CU_ASSERT_PTR_NULL(semanage_fcontext_get_expr(fcontext));
520 	CU_ASSERT(semanage_fcontext_get_type(fcontext)
521 		  == SEMANAGE_FCONTEXT_ALL);
522 	CU_ASSERT_PTR_NULL(semanage_fcontext_get_con(fcontext));
523 
524 	/* cleanup */
525 	semanage_fcontext_free(fcontext);
526 	cleanup_handle(level);
527 }
528 
test_fcontext_create(void)529 void test_fcontext_create(void)
530 {
531 	helper_fcontext_create(SH_NULL);
532 	helper_fcontext_create(SH_HANDLE);
533 	helper_fcontext_create(SH_CONNECT);
534 	helper_fcontext_create(SH_TRANS);
535 }
536 
537 /* Function semanage_fcontext_clone */
helper_fcontext_clone(level_t level,int fcontext_idx)538 void helper_fcontext_clone(level_t level, int fcontext_idx)
539 {
540 	semanage_fcontext_t *fcontext;
541 	semanage_fcontext_t *fcontext_clone;
542 	const char *expr;
543 	const char *expr_clone;
544 	int type;
545 	int type_clone;
546 	semanage_context_t *con;
547 	semanage_context_t *con_clone;
548 
549 	/* setup */
550 	setup_handle(level);
551 	fcontext = get_fcontext_nth(fcontext_idx);
552 
553 	/* test */
554 	CU_ASSERT(semanage_fcontext_clone(sh, fcontext, &fcontext_clone) >= 0);
555 
556 	expr = semanage_fcontext_get_expr(fcontext);
557 	expr_clone = semanage_fcontext_get_expr(fcontext_clone);
558 	CU_ASSERT_STRING_EQUAL(expr, expr_clone);
559 
560 	type = semanage_fcontext_get_type(fcontext);
561 	type_clone = semanage_fcontext_get_type(fcontext_clone);
562 	CU_ASSERT_EQUAL(type, type_clone);
563 
564 	con = semanage_fcontext_get_con(fcontext);
565 	con_clone = semanage_fcontext_get_con(fcontext_clone);
566 	CU_ASSERT_CONTEXT_EQUAL(con, con_clone);
567 
568 	/* cleanup */
569 	semanage_fcontext_free(fcontext);
570 	semanage_fcontext_free(fcontext_clone);
571 	cleanup_handle(level);
572 }
573 
test_fcontext_clone(void)574 void test_fcontext_clone(void)
575 {
576 	helper_fcontext_clone(SH_CONNECT, I_FIRST);
577 	helper_fcontext_clone(SH_CONNECT, I_SECOND);
578 	helper_fcontext_clone(SH_TRANS, I_FIRST);
579 	helper_fcontext_clone(SH_TRANS, I_SECOND);
580 }
581 
582 /* Function semanage_fcontext_query */
helper_fcontext_query(level_t level,const char * fcontext_expr,int fcontext_type,int exp_res)583 void helper_fcontext_query(level_t level, const char *fcontext_expr,
584 			   int fcontext_type, int exp_res)
585 {
586 	semanage_fcontext_key_t *key;
587 	semanage_fcontext_t *resp = (void *) 42;
588 	int res;
589 
590 	/* setup */
591 	setup_handle(level);
592 	key = get_fcontext_key_from_str(fcontext_expr, fcontext_type);
593 
594 	/* test */
595 	res = semanage_fcontext_query(sh, key, &resp);
596 
597 	if (exp_res >= 0) {
598 		CU_ASSERT(res >= 0);
599 		const char *expr = semanage_fcontext_get_expr(resp);
600 		CU_ASSERT_STRING_EQUAL(expr, fcontext_expr);
601 		semanage_fcontext_free(resp);
602 	} else {
603 		CU_ASSERT(res < 0);
604 		CU_ASSERT(resp == (void *) 42);
605 	}
606 
607 	/* cleanup */
608 	semanage_fcontext_key_free(key);
609 	cleanup_handle(level);
610 }
611 
test_fcontext_query(void)612 void test_fcontext_query(void)
613 {
614 	helper_fcontext_query(SH_CONNECT, FCONTEXT_NONEXISTENT_EXPR,
615 			      FCONTEXT_NONEXISTENT_TYPE, -1);
616 	helper_fcontext_query(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT1_TYPE, -1);
617 	helper_fcontext_query(SH_CONNECT, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
618 	helper_fcontext_query(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
619 	helper_fcontext_query(SH_TRANS, FCONTEXT_NONEXISTENT_EXPR,
620 			      FCONTEXT_NONEXISTENT_TYPE, -1);
621 	helper_fcontext_query(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT1_TYPE, -1);
622 	helper_fcontext_query(SH_TRANS, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
623 	helper_fcontext_query(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
624 }
625 
626 /* Function semanage_fcontext_exists */
helper_fcontext_exists(level_t level,const char * fcontext_expr,int fcontext_type,int exp_resp)627 void helper_fcontext_exists(level_t level, const char *fcontext_expr,
628 			    int fcontext_type, int exp_resp)
629 {
630 	semanage_fcontext_key_t *key;
631 	int resp;
632 
633 	/* setup */
634 	setup_handle(level);
635 	key = get_fcontext_key_from_str(fcontext_expr, fcontext_type);
636 
637 	/* test */
638 	CU_ASSERT(semanage_fcontext_exists(sh, key, &resp) >= 0);
639 	CU_ASSERT(resp == exp_resp);
640 
641 	/* cleanup */
642 	semanage_fcontext_key_free(key);
643 	cleanup_handle(level);
644 }
645 
test_fcontext_exists(void)646 void test_fcontext_exists(void)
647 {
648 	helper_fcontext_exists(SH_CONNECT, FCONTEXT_NONEXISTENT_EXPR,
649 			       FCONTEXT_NONEXISTENT_TYPE, 0);
650 	helper_fcontext_exists(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT1_TYPE, 0);
651 	helper_fcontext_exists(SH_CONNECT, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
652 	helper_fcontext_exists(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
653 	helper_fcontext_exists(SH_TRANS, FCONTEXT_NONEXISTENT_EXPR,
654 			       FCONTEXT_NONEXISTENT_TYPE, 0);
655 	helper_fcontext_exists(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT1_TYPE, 0);
656 	helper_fcontext_exists(SH_TRANS, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
657 	helper_fcontext_exists(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
658 }
659 
660 /* Function semanage_fcontext_count */
test_fcontext_count(void)661 void test_fcontext_count(void)
662 {
663 	unsigned int resp;
664 
665 	/* handle */
666 	setup_handle(SH_HANDLE);
667 	CU_ASSERT(semanage_fcontext_count(sh, &resp) < 0);
668 	CU_ASSERT(semanage_fcontext_count(sh, NULL) < 0);
669 	cleanup_handle(SH_HANDLE);
670 
671 	/* connect */
672 	resp = 0;
673 	setup_handle(SH_CONNECT);
674 	CU_ASSERT(semanage_fcontext_count(sh, &resp) >= 0);
675 	CU_ASSERT(resp == FCONTEXTS_COUNT);
676 	cleanup_handle(SH_CONNECT);
677 
678 	/* trans */
679 	resp = 0;
680 	setup_handle(SH_TRANS);
681 	CU_ASSERT(semanage_fcontext_count(sh, &resp) >= 0);
682 	CU_ASSERT(resp == FCONTEXTS_COUNT);
683 	cleanup_handle(SH_TRANS);
684 }
685 
686 /* Function semanage_fcontext_iterate */
687 unsigned int counter_fcontext_iterate = 0;
688 
handler_fcontext_iterate(const semanage_fcontext_t * record,void * varg)689 int handler_fcontext_iterate(const semanage_fcontext_t *record, void *varg)
690 {
691 	CU_ASSERT_PTR_NOT_NULL(record);
692 	counter_fcontext_iterate++;
693 	return 0;
694 }
695 
helper_fcontext_iterate_invalid(void)696 void helper_fcontext_iterate_invalid(void)
697 {
698 	/* setup */
699 	setup_handle(SH_HANDLE);
700 
701 	/* test */
702 	CU_ASSERT(semanage_fcontext_iterate(sh, &handler_fcontext_iterate,
703 				            NULL) < 0);
704 	CU_ASSERT(semanage_fcontext_iterate(sh, NULL, NULL) < 0);
705 
706 	/* cleanup */
707 	cleanup_handle(SH_HANDLE);
708 }
709 
helper_fcontext_iterate(level_t level)710 void helper_fcontext_iterate(level_t level)
711 {
712 	/* setup */
713 	setup_handle(level);
714 	counter_fcontext_iterate = 0;
715 
716 	/* test */
717 	CU_ASSERT(semanage_fcontext_iterate(sh, &handler_fcontext_iterate,
718 					    NULL) >= 0);
719 	CU_ASSERT(counter_fcontext_iterate == FCONTEXTS_COUNT);
720 
721 	/* cleanup */
722 	cleanup_handle(level);
723 }
724 
test_fcontext_iterate(void)725 void test_fcontext_iterate(void)
726 {
727 	helper_fcontext_iterate_invalid();
728 	helper_fcontext_iterate(SH_CONNECT);
729 	helper_fcontext_iterate(SH_TRANS);
730 }
731 
732 /* Function semanage_fcontext_list */
helper_fcontext_list_invalid(void)733 void helper_fcontext_list_invalid(void)
734 {
735 	semanage_fcontext_t **records;
736 	unsigned int count;
737 
738 	/* setup */
739 	setup_handle(SH_HANDLE);
740 
741 	/* test */
742 	CU_ASSERT(semanage_fcontext_list(sh, &records, &count) < 0);
743 	CU_ASSERT(semanage_fcontext_list(sh, NULL, &count) < 0);
744 	CU_ASSERT(semanage_fcontext_list(sh, &records, NULL) < 0);
745 
746 	/* cleanup */
747 	cleanup_handle(SH_HANDLE);
748 }
749 
helper_fcontext_list(level_t level)750 void helper_fcontext_list(level_t level)
751 {
752 	semanage_fcontext_t **records;
753 	unsigned int count;
754 
755 	/* setup */
756 	setup_handle(level);
757 
758 	/* test */
759 	CU_ASSERT(semanage_fcontext_list(sh, &records, &count) >= 0);
760 	CU_ASSERT(count == FCONTEXTS_COUNT);
761 
762 	for (unsigned int i = 0; i < count; i++)
763 		CU_ASSERT_PTR_NOT_NULL(records[i]);
764 
765 	for (unsigned int i = 0; i < count; i++)
766 		semanage_fcontext_free(records[i]);
767 
768 	free(records);
769 
770 	/* cleanup */
771 	cleanup_handle(level);
772 }
773 
test_fcontext_list(void)774 void test_fcontext_list(void)
775 {
776 	helper_fcontext_list_invalid();
777 	helper_fcontext_list(SH_CONNECT);
778 	helper_fcontext_list(SH_TRANS);
779 }
780 
781 /* Function semanage_fcontext_modify_local, semanage_fcontext_del_local */
helper_fcontext_modify_del_local(level_t level,int fcontext_idx,const char * con_str,int exp_res)782 void helper_fcontext_modify_del_local(level_t level, int fcontext_idx,
783 				      const char *con_str, int exp_res)
784 {
785 	semanage_fcontext_t *fcontext;
786 	semanage_fcontext_t *fcontext_local = NULL;
787 	semanage_fcontext_key_t *key = NULL;
788 	semanage_context_t *con = NULL;
789 	int res;
790 
791 	/* setup */
792 	setup_handle(level);
793 	fcontext = get_fcontext_nth(fcontext_idx);
794 	CU_ASSERT(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
795 	CU_ASSERT_PTR_NOT_NULL(key);
796 
797 	if (con_str != NULL) {
798 		CU_ASSERT(semanage_context_from_string(sh, con_str, &con) >= 0);
799 		CU_ASSERT_PTR_NOT_NULL(con);
800 	} else {
801 		con = NULL;
802 	}
803 
804 	CU_ASSERT(semanage_fcontext_set_con(sh, fcontext, con) >= 0);
805 
806 	/* test */
807 	res = semanage_fcontext_modify_local(sh, key, fcontext);
808 
809 	if (exp_res >= 0) {
810 		CU_ASSERT(res >= 0);
811 
812 		if (level == SH_TRANS) {
813 			helper_commit();
814 			helper_begin_transaction();
815 		}
816 
817 		CU_ASSERT(semanage_fcontext_query_local(sh, key,
818 					                &fcontext_local) >= 0);
819 		CU_ASSERT(semanage_fcontext_compare2(fcontext_local,
820 						     fcontext) == 0);
821 		semanage_fcontext_free(fcontext_local);
822 
823 		CU_ASSERT(semanage_fcontext_del_local(sh, key) >= 0);
824 		CU_ASSERT(semanage_fcontext_query_local(sh, key,
825 					                &fcontext_local) < 0);
826 	} else {
827 		CU_ASSERT(res < 0);
828 	}
829 
830 	/* cleanup */
831 	semanage_context_free(con);
832 	semanage_fcontext_key_free(key);
833 	semanage_fcontext_free(fcontext);
834 	cleanup_handle(level);
835 }
836 
test_fcontext_modify_del_local(void)837 void test_fcontext_modify_del_local(void)
838 {
839 	helper_fcontext_modify_del_local(SH_CONNECT, I_FIRST,
840 					 "system_u:object_r:tmp_t:s0", -1);
841 	helper_fcontext_modify_del_local(SH_CONNECT, I_SECOND,
842 					 "system_u:object_r:tmp_t:s0", -1);
843 	helper_fcontext_modify_del_local(SH_TRANS, I_FIRST,
844 					 "system_u:object_r:tmp_t:s0", 1);
845 	helper_fcontext_modify_del_local(SH_TRANS, I_SECOND,
846 					 "system_u:object_r:tmp_t:s0", 1);
847 }
848 
849 /* Function semanage_fcontext_query_local */
test_fcontext_query_local(void)850 void test_fcontext_query_local(void)
851 {
852 	semanage_fcontext_key_t *key = NULL;
853 	semanage_fcontext_t *resp = NULL;
854 
855 	/* connect */
856 	setup_handle(SH_CONNECT);
857 
858 	key = get_fcontext_key_nth(I_FIRST);
859 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) < 0);
860 	CU_ASSERT_PTR_NULL(resp);
861 
862 	cleanup_handle(SH_CONNECT);
863 
864 	/* transaction */
865 	setup_handle(SH_TRANS);
866 
867 	semanage_fcontext_key_free(key);
868 	key = get_fcontext_key_nth(I_FIRST);
869 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) < 0);
870 	CU_ASSERT_PTR_NULL(resp);
871 
872 	add_local_fcontext(I_FIRST);
873 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) >= 0);
874 	CU_ASSERT_PTR_NOT_NULL(resp);
875 	semanage_fcontext_free(resp);
876 	resp = NULL;
877 
878 	semanage_fcontext_key_free(key);
879 	key = get_fcontext_key_nth(I_SECOND);
880 	add_local_fcontext(I_SECOND);
881 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) >= 0);
882 	CU_ASSERT_PTR_NOT_NULL(resp);
883 	semanage_fcontext_free(resp);
884 	resp = NULL;
885 
886 	/* cleanup */
887 	semanage_fcontext_key_free(key);
888 	delete_local_fcontext(I_FIRST);
889 	delete_local_fcontext(I_SECOND);
890 	cleanup_handle(SH_TRANS);
891 }
892 
893 /* Function semanage_fcontext_exists_local */
test_fcontext_exists_local(void)894 void test_fcontext_exists_local(void)
895 {
896 	int resp = -1;
897 	semanage_fcontext_key_t *key;
898 
899 	/* setup */
900 	setup_handle(SH_TRANS);
901 	key = get_fcontext_key_nth(I_FIRST);
902 
903 	/* test */
904 	CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0);
905 	CU_ASSERT(resp == 0);
906 
907 	add_local_fcontext(I_FIRST);
908 	resp = -1;
909 
910 	CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0);
911 	CU_ASSERT(resp == 1);
912 
913 	delete_local_fcontext(I_FIRST);
914 	resp = -1;
915 
916 	CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0);
917 	CU_ASSERT(resp == 0);
918 
919 	resp = -1;
920 
921 	CU_ASSERT(semanage_fcontext_exists_local(sh, NULL, &resp) >= 0);
922 	CU_ASSERT(resp == 0);
923 
924 	/* cleanup */
925 	semanage_fcontext_key_free(key);
926 	cleanup_handle(SH_TRANS);
927 }
928 
929 /* Function semanage_fcontext_count_local */
test_fcontext_count_local(void)930 void test_fcontext_count_local(void)
931 {
932 	unsigned int resp;
933 
934 	/* handle */
935 	setup_handle(SH_HANDLE);
936 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) < 0);
937 	cleanup_handle(SH_HANDLE);
938 
939 	/* connect */
940 	setup_handle(SH_CONNECT);
941 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
942 	CU_ASSERT(resp == 0);
943 	cleanup_handle(SH_CONNECT);
944 
945 	/* transaction */
946 	setup_handle(SH_TRANS);
947 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
948 	CU_ASSERT(resp == 0);
949 
950 	add_local_fcontext(I_FIRST);
951 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
952 	CU_ASSERT(resp == 1);
953 
954 	add_local_fcontext(I_SECOND);
955 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
956 	CU_ASSERT(resp == 2);
957 
958 	delete_local_fcontext(I_SECOND);
959 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
960 	CU_ASSERT(resp == 1);
961 
962 	/* cleanup */
963 	delete_local_fcontext(I_FIRST);
964 	cleanup_handle(SH_TRANS);
965 }
966 
967 /* Function semanage_fcontext_iterate_local */
968 unsigned int counter_fcontext_iterate_local = 0;
969 
handler_fcontext_iterate_local(const semanage_fcontext_t * record,void * varg)970 int handler_fcontext_iterate_local(const semanage_fcontext_t *record,
971 				   void *varg)
972 {
973 	CU_ASSERT_PTR_NOT_NULL(record);
974 	counter_fcontext_iterate_local++;
975 	return 0;
976 }
977 
test_fcontext_iterate_local(void)978 void test_fcontext_iterate_local(void)
979 {
980 	/* handle */
981 	setup_handle(SH_HANDLE);
982 
983 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
984 				    &handler_fcontext_iterate_local, NULL) < 0);
985 	CU_ASSERT(semanage_fcontext_iterate_local(sh, NULL, NULL) < 0);
986 
987 	cleanup_handle(SH_HANDLE);
988 
989 	/* connect */
990 	setup_handle(SH_CONNECT);
991 
992 	counter_fcontext_iterate_local = 0;
993 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
994 				   &handler_fcontext_iterate_local, NULL) >= 0);
995 	CU_ASSERT(counter_fcontext_iterate_local == 0);
996 	CU_ASSERT(semanage_fcontext_iterate_local(sh, NULL, NULL) >= 0);
997 
998 	cleanup_handle(SH_CONNECT);
999 
1000 	/* transaction */
1001 	setup_handle(SH_TRANS);
1002 
1003 	counter_fcontext_iterate_local = 0;
1004 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
1005 				   &handler_fcontext_iterate_local, NULL) >= 0);
1006 	CU_ASSERT(counter_fcontext_iterate_local == 0);
1007 
1008 	add_local_fcontext(I_FIRST);
1009 	counter_fcontext_iterate_local = 0;
1010 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
1011 				   &handler_fcontext_iterate_local, NULL) >= 0);
1012 	CU_ASSERT(counter_fcontext_iterate_local == 1);
1013 
1014 	add_local_fcontext(I_SECOND);
1015 	counter_fcontext_iterate_local = 0;
1016 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
1017 				   &handler_fcontext_iterate_local, NULL) >= 0);
1018 	CU_ASSERT(counter_fcontext_iterate_local == 2);
1019 
1020 	/* cleanup */
1021 	delete_local_fcontext(I_FIRST);
1022 	delete_local_fcontext(I_SECOND);
1023 	cleanup_handle(SH_TRANS);
1024 }
1025 
1026 /* Function semanage_fcontext_list_local */
test_fcontext_list_local(void)1027 void test_fcontext_list_local(void)
1028 {
1029 	semanage_fcontext_t **records;
1030 	unsigned int count;
1031 
1032 	/* handle */
1033 	setup_handle(SH_HANDLE);
1034 
1035 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) < 0);
1036 	CU_ASSERT(semanage_fcontext_list_local(sh, NULL, &count) < 0);
1037 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, NULL) < 0);
1038 
1039 	cleanup_handle(SH_HANDLE);
1040 
1041 	/* connect */
1042 	setup_handle(SH_CONNECT);
1043 
1044 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1045 	CU_ASSERT(count == 0);
1046 
1047 	cleanup_handle(SH_CONNECT);
1048 
1049 	/* transaction */
1050 	setup_handle(SH_TRANS);
1051 
1052 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1053 	CU_ASSERT(count == 0);
1054 
1055 	add_local_fcontext(I_FIRST);
1056 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1057 	CU_ASSERT(count == 1);
1058 	CU_ASSERT_PTR_NOT_NULL(records[0]);
1059 	semanage_fcontext_free(records[0]);
1060 	free(records);
1061 
1062 	add_local_fcontext(I_SECOND);
1063 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1064 	CU_ASSERT(count == 2);
1065 	CU_ASSERT_PTR_NOT_NULL(records[0]);
1066 	CU_ASSERT_PTR_NOT_NULL(records[1]);
1067 	semanage_fcontext_free(records[0]);
1068 	semanage_fcontext_free(records[1]);
1069 	free(records);
1070 
1071 	/* cleanup */
1072 	delete_local_fcontext(I_FIRST);
1073 	delete_local_fcontext(I_SECOND);
1074 	cleanup_handle(SH_TRANS);
1075 }
1076