• 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 	return fcontext;
218 }
219 
get_fcontext_key_nth(int idx)220 semanage_fcontext_key_t *get_fcontext_key_nth(int idx)
221 {
222 	semanage_fcontext_key_t *key;
223 	semanage_fcontext_t *fcontext;
224 
225 	if (idx == I_NULL)
226 		return NULL;
227 
228 	fcontext = get_fcontext_nth(idx);
229 
230 	CU_ASSERT_FATAL(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
231 	CU_ASSERT_PTR_NOT_NULL_FATAL(key);
232 
233 	return key;
234 }
235 
add_local_fcontext(int fcontext_idx)236 void add_local_fcontext(int fcontext_idx)
237 {
238 	semanage_fcontext_t *fcontext;
239 	semanage_fcontext_key_t *key = NULL;
240 
241 	CU_ASSERT_FATAL(fcontext_idx != I_NULL);
242 
243 	fcontext = get_fcontext_nth(fcontext_idx);
244 
245 	CU_ASSERT_FATAL(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
246 	CU_ASSERT_PTR_NOT_NULL_FATAL(key);
247 
248 	CU_ASSERT_FATAL(semanage_fcontext_modify_local(sh, key, fcontext) >= 0);
249 }
250 
delete_local_fcontext(int fcontext_idx)251 void delete_local_fcontext(int fcontext_idx)
252 {
253 	semanage_fcontext_key_t *key = NULL;
254 
255 	CU_ASSERT_FATAL(fcontext_idx != I_NULL);
256 
257 	key = get_fcontext_key_nth(fcontext_idx);
258 
259 	CU_ASSERT_FATAL(semanage_fcontext_del_local(sh, key) >= 0);
260 }
261 
get_fcontext_key_from_str(const char * str,int type)262 semanage_fcontext_key_t *get_fcontext_key_from_str(const char *str, int type)
263 {
264 	semanage_fcontext_key_t *key;
265 	int res;
266 
267 	if (str == NULL)
268 		return NULL;
269 
270 	res = semanage_fcontext_key_create(sh, str, type, &key);
271 
272 	CU_ASSERT_FATAL(res >= 0);
273 	CU_ASSERT_PTR_NOT_NULL_FATAL(key);
274 
275 	return key;
276 }
277 
278 /* Function semanage_fcontext_compare */
test_fcontext_compare(void)279 void test_fcontext_compare(void)
280 {
281 	semanage_fcontext_t *fcontext;
282 	semanage_fcontext_key_t *key1;
283 	semanage_fcontext_key_t *key2;
284 	semanage_fcontext_key_t *key3;
285 
286 	/* setup */
287 	setup_handle(SH_CONNECT);
288 
289 	fcontext = get_fcontext_nth(I_FIRST);
290 
291 	key1 = get_fcontext_key_nth(I_FIRST);
292 	key2 = get_fcontext_key_nth(I_SECOND);
293 	key3 = get_fcontext_key_nth(I_THIRD);
294 
295 	/* test */
296 	CU_ASSERT(semanage_fcontext_compare(fcontext, key1) == 0);
297 	CU_ASSERT(semanage_fcontext_compare(fcontext, key2) < 0);
298 	CU_ASSERT(semanage_fcontext_compare(fcontext, key3) > 0);
299 
300 	/* cleanup */
301 	semanage_fcontext_free(fcontext);
302 	semanage_fcontext_key_free(key1);
303 	semanage_fcontext_key_free(key2);
304 	semanage_fcontext_key_free(key3);
305 	cleanup_handle(SH_CONNECT);
306 }
307 
308 /* Function semanage_fcontext_compare2 */
test_fcontext_compare2(void)309 void test_fcontext_compare2(void)
310 {
311 	semanage_fcontext_t *fcontext;
312 	semanage_fcontext_t *fcontext1;
313 	semanage_fcontext_t *fcontext2;
314 	semanage_fcontext_t *fcontext3;
315 
316 	/* setup */
317 	setup_handle(SH_CONNECT);
318 
319 	fcontext = get_fcontext_nth(I_FIRST);
320 	fcontext1 = get_fcontext_nth(I_FIRST);
321 	fcontext2 = get_fcontext_nth(I_SECOND);
322 	fcontext3 = get_fcontext_nth(I_THIRD);
323 
324 	/* test */
325 	CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext1) == 0);
326 	CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext2) < 0);
327 	CU_ASSERT(semanage_fcontext_compare2(fcontext, fcontext3) > 0);
328 
329 	/* cleanup */
330 	semanage_fcontext_free(fcontext);
331 	semanage_fcontext_free(fcontext1);
332 	semanage_fcontext_free(fcontext2);
333 	semanage_fcontext_free(fcontext3);
334 	cleanup_handle(SH_CONNECT);
335 }
336 
337 /* Function semanage_fcontext_key_create */
test_fcontext_key_create(void)338 void test_fcontext_key_create(void)
339 {
340 	semanage_fcontext_key_t *key = NULL;
341 
342 	/* setup */
343 	setup_handle(SH_CONNECT);
344 
345 	/* test */
346 	CU_ASSERT(semanage_fcontext_key_create(sh, "", SEMANAGE_FCONTEXT_ALL,
347 					       &key) >= 0);
348 	CU_ASSERT_PTR_NOT_NULL(key);
349 
350 	semanage_fcontext_key_free(key);
351 
352 	key = NULL;
353 
354 	CU_ASSERT(semanage_fcontext_key_create(sh, "testfcontext",
355 					     SEMANAGE_FCONTEXT_ALL, &key) >= 0);
356 	CU_ASSERT_PTR_NOT_NULL(key);
357 
358 	semanage_fcontext_key_free(key);
359 
360 	/* cleanup */
361 	cleanup_handle(SH_CONNECT);
362 }
363 
364 /* Function semanage_fcontext_key_extract */
test_fcontext_key_extract(void)365 void test_fcontext_key_extract(void)
366 {
367 	semanage_fcontext_t *fcontext;
368 	semanage_fcontext_key_t *key;
369 
370 	/* setup */
371 	setup_handle(SH_CONNECT);
372 	fcontext = get_fcontext_nth(I_FIRST);
373 
374 	/* test */
375 	CU_ASSERT(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
376 	CU_ASSERT_PTR_NOT_NULL(key);
377 
378 	/* cleanup */
379 	semanage_fcontext_key_free(key);
380 	semanage_fcontext_free(fcontext);
381 	cleanup_handle(SH_CONNECT);
382 }
383 
384 /* Function semanage_fcontext_get_expr, semanage_fcontext_set_expr */
test_fcontext_get_set_expr(void)385 void test_fcontext_get_set_expr(void)
386 {
387 	semanage_fcontext_t *fcontext;
388 	const char *expr = NULL;
389 	const char *expr_exp = "/asdf";
390 
391 	/* setup */
392 	setup_handle(SH_CONNECT);
393 	fcontext = get_fcontext_nth(I_FIRST);
394 
395 	/* test */
396 	CU_ASSERT(semanage_fcontext_set_expr(sh, fcontext, expr_exp) >= 0);
397 	expr = semanage_fcontext_get_expr(fcontext);
398 	CU_ASSERT_PTR_NOT_NULL(expr);
399 	assert(expr);
400 	CU_ASSERT_STRING_EQUAL(expr, expr_exp);
401 
402 	/* cleanup */
403 	semanage_fcontext_free(fcontext);
404 	cleanup_handle(SH_CONNECT);
405 }
406 
407 /* Function semanage_fcontext_get_type, semanage_fcontext_set_type */
test_fcontext_get_set_type(void)408 void test_fcontext_get_set_type(void)
409 {
410 	semanage_fcontext_t *fcontext;
411 	int type_exp = SEMANAGE_FCONTEXT_SOCK;
412 	int type;
413 
414 	/* setup */
415 	setup_handle(SH_CONNECT);
416 	fcontext = get_fcontext_nth(I_FIRST);
417 
418 	/* test */
419 	semanage_fcontext_set_type(fcontext, type_exp);
420 	type = semanage_fcontext_get_type(fcontext);
421 	CU_ASSERT(type == type_exp);
422 
423 	/* cleanup */
424 	semanage_fcontext_free(fcontext);
425 	cleanup_handle(SH_CONNECT);
426 }
427 
428 /* Function semanage_fcontext_get_type_str */
helper_fcontext_get_type_str(int type,const char * exp_str)429 void helper_fcontext_get_type_str(int type, const char *exp_str)
430 {
431 	CU_ASSERT_STRING_EQUAL(semanage_fcontext_get_type_str(type), exp_str);
432 }
433 
test_fcontext_get_type_str(void)434 void test_fcontext_get_type_str(void)
435 {
436 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_ALL, "all files");
437 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_REG, "regular file");
438 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_DIR, "directory");
439 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_CHAR,
440 				     "character device");
441 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_BLOCK, "block device");
442 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_SOCK, "socket");
443 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_LINK, "symbolic link");
444 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_PIPE, "named pipe");
445 
446 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_ALL - 1, "????");
447 	helper_fcontext_get_type_str(SEMANAGE_FCONTEXT_PIPE + 1, "????");
448 }
449 
450 /* Function semanage_fcontext_get_con, semanage_fcontext_set_con */
helper_fcontext_get_set_con(level_t level,int fcontext_idx,const char * con_str)451 void helper_fcontext_get_set_con(level_t level, int fcontext_idx,
452 				 const char *con_str)
453 {
454 	semanage_fcontext_t *fcontext;
455 	semanage_context_t *con = NULL;
456 	semanage_context_t *new_con = NULL;
457 
458 	/* setup */
459 	setup_handle(level);
460 	fcontext = get_fcontext_nth(fcontext_idx);
461 
462 	if (con_str != NULL) {
463 		CU_ASSERT(semanage_context_from_string(sh, con_str, &con) >= 0);
464 		CU_ASSERT_PTR_NOT_NULL(con);
465 	} else {
466 		con = NULL;
467 	}
468 
469 	/* test */
470 	CU_ASSERT(semanage_fcontext_set_con(sh, fcontext, con) >= 0);
471 	new_con = semanage_fcontext_get_con(fcontext);
472 
473 	if (con_str != NULL) {
474 		CU_ASSERT_CONTEXT_EQUAL(con, new_con);
475 	} else {
476 		CU_ASSERT_PTR_NULL(new_con);
477 	}
478 
479 	/* cleanup */
480 	semanage_fcontext_free(fcontext);
481 	cleanup_handle(level);
482 }
483 
test_fcontext_get_set_con(void)484 void test_fcontext_get_set_con(void)
485 {
486 	helper_fcontext_get_set_con(SH_CONNECT, I_FIRST, NULL);
487 	helper_fcontext_get_set_con(SH_CONNECT, I_FIRST,
488 				    "user_u:role_r:type_t:s0");
489 	helper_fcontext_get_set_con(SH_CONNECT, I_SECOND,
490 				    "user_u:role_r:type_t:s0");
491 	helper_fcontext_get_set_con(SH_TRANS, I_FIRST, NULL);
492 	helper_fcontext_get_set_con(SH_TRANS, I_FIRST,
493 				    "user_u:role_r:type_t:s0");
494 	helper_fcontext_get_set_con(SH_TRANS, I_SECOND,
495 				    "user_u:role_r:type_t:s0");
496 }
497 
498 /* Function semanage_fcontext_create */
helper_fcontext_create(level_t level)499 void helper_fcontext_create(level_t level)
500 {
501 	semanage_fcontext_t *fcontext;
502 
503 	/* setup */
504 	setup_handle(level);
505 
506 	/* test */
507 	CU_ASSERT(semanage_fcontext_create(sh, &fcontext) >= 0);
508 	CU_ASSERT_PTR_NULL(semanage_fcontext_get_expr(fcontext));
509 	CU_ASSERT(semanage_fcontext_get_type(fcontext)
510 		  == SEMANAGE_FCONTEXT_ALL);
511 	CU_ASSERT_PTR_NULL(semanage_fcontext_get_con(fcontext));
512 
513 	/* cleanup */
514 	semanage_fcontext_free(fcontext);
515 	cleanup_handle(level);
516 }
517 
test_fcontext_create(void)518 void test_fcontext_create(void)
519 {
520 	helper_fcontext_create(SH_NULL);
521 	helper_fcontext_create(SH_HANDLE);
522 	helper_fcontext_create(SH_CONNECT);
523 	helper_fcontext_create(SH_TRANS);
524 }
525 
526 /* Function semanage_fcontext_clone */
helper_fcontext_clone(level_t level,int fcontext_idx)527 void helper_fcontext_clone(level_t level, int fcontext_idx)
528 {
529 	semanage_fcontext_t *fcontext;
530 	semanage_fcontext_t *fcontext_clone;
531 	const char *expr;
532 	const char *expr_clone;
533 	int type;
534 	int type_clone;
535 	semanage_context_t *con;
536 	semanage_context_t *con_clone;
537 
538 	/* setup */
539 	setup_handle(level);
540 	fcontext = get_fcontext_nth(fcontext_idx);
541 
542 	/* test */
543 	CU_ASSERT(semanage_fcontext_clone(sh, fcontext, &fcontext_clone) >= 0);
544 
545 	expr = semanage_fcontext_get_expr(fcontext);
546 	expr_clone = semanage_fcontext_get_expr(fcontext_clone);
547 	CU_ASSERT_STRING_EQUAL(expr, expr_clone);
548 
549 	type = semanage_fcontext_get_type(fcontext);
550 	type_clone = semanage_fcontext_get_type(fcontext_clone);
551 	CU_ASSERT_EQUAL(type, type_clone);
552 
553 	con = semanage_fcontext_get_con(fcontext);
554 	con_clone = semanage_fcontext_get_con(fcontext_clone);
555 	CU_ASSERT_CONTEXT_EQUAL(con, con_clone);
556 
557 	/* cleanup */
558 	semanage_fcontext_free(fcontext);
559 	semanage_fcontext_free(fcontext_clone);
560 	cleanup_handle(level);
561 }
562 
test_fcontext_clone(void)563 void test_fcontext_clone(void)
564 {
565 	helper_fcontext_clone(SH_CONNECT, I_FIRST);
566 	helper_fcontext_clone(SH_CONNECT, I_SECOND);
567 	helper_fcontext_clone(SH_TRANS, I_FIRST);
568 	helper_fcontext_clone(SH_TRANS, I_SECOND);
569 }
570 
571 /* Function semanage_fcontext_query */
helper_fcontext_query(level_t level,const char * fcontext_expr,int fcontext_type,int exp_res)572 void helper_fcontext_query(level_t level, const char *fcontext_expr,
573 			   int fcontext_type, int exp_res)
574 {
575 	semanage_fcontext_key_t *key;
576 	semanage_fcontext_t *resp = (void *) 42;
577 	int res;
578 
579 	/* setup */
580 	setup_handle(level);
581 	key = get_fcontext_key_from_str(fcontext_expr, fcontext_type);
582 
583 	/* test */
584 	res = semanage_fcontext_query(sh, key, &resp);
585 
586 	if (exp_res >= 0) {
587 		CU_ASSERT(res >= 0);
588 		const char *expr = semanage_fcontext_get_expr(resp);
589 		CU_ASSERT_STRING_EQUAL(expr, fcontext_expr);
590 	} else {
591 		CU_ASSERT(res < 0);
592 		CU_ASSERT(resp == (void *) 42);
593 	}
594 
595 	/* cleanup */
596 	cleanup_handle(level);
597 }
598 
test_fcontext_query(void)599 void test_fcontext_query(void)
600 {
601 	helper_fcontext_query(SH_CONNECT, FCONTEXT_NONEXISTENT_EXPR,
602 			      FCONTEXT_NONEXISTENT_TYPE, -1);
603 	helper_fcontext_query(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT1_TYPE, -1);
604 	helper_fcontext_query(SH_CONNECT, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
605 	helper_fcontext_query(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
606 	helper_fcontext_query(SH_TRANS, FCONTEXT_NONEXISTENT_EXPR,
607 			      FCONTEXT_NONEXISTENT_TYPE, -1);
608 	helper_fcontext_query(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT1_TYPE, -1);
609 	helper_fcontext_query(SH_TRANS, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
610 	helper_fcontext_query(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
611 }
612 
613 /* Function semanage_fcontext_exists */
helper_fcontext_exists(level_t level,const char * fcontext_expr,int fcontext_type,int exp_resp)614 void helper_fcontext_exists(level_t level, const char *fcontext_expr,
615 			    int fcontext_type, int exp_resp)
616 {
617 	semanage_fcontext_key_t *key;
618 	int resp;
619 
620 	/* setup */
621 	setup_handle(level);
622 	key = get_fcontext_key_from_str(fcontext_expr, fcontext_type);
623 
624 	/* test */
625 	CU_ASSERT(semanage_fcontext_exists(sh, key, &resp) >= 0);
626 	CU_ASSERT(resp == exp_resp);
627 
628 	/* cleanup */
629 	semanage_fcontext_key_free(key);
630 	cleanup_handle(level);
631 }
632 
test_fcontext_exists(void)633 void test_fcontext_exists(void)
634 {
635 	helper_fcontext_exists(SH_CONNECT, FCONTEXT_NONEXISTENT_EXPR,
636 			       FCONTEXT_NONEXISTENT_TYPE, 0);
637 	helper_fcontext_exists(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT1_TYPE, 0);
638 	helper_fcontext_exists(SH_CONNECT, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
639 	helper_fcontext_exists(SH_CONNECT, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
640 	helper_fcontext_exists(SH_TRANS, FCONTEXT_NONEXISTENT_EXPR,
641 			       FCONTEXT_NONEXISTENT_TYPE, 0);
642 	helper_fcontext_exists(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT1_TYPE, 0);
643 	helper_fcontext_exists(SH_TRANS, FCONTEXT1_EXPR, FCONTEXT1_TYPE, 1);
644 	helper_fcontext_exists(SH_TRANS, FCONTEXT2_EXPR, FCONTEXT2_TYPE, 1);
645 }
646 
647 /* Function semanage_fcontext_count */
test_fcontext_count(void)648 void test_fcontext_count(void)
649 {
650 	unsigned int resp;
651 
652 	/* handle */
653 	setup_handle(SH_HANDLE);
654 	CU_ASSERT(semanage_fcontext_count(sh, &resp) < 0);
655 	CU_ASSERT(semanage_fcontext_count(sh, NULL) < 0);
656 	cleanup_handle(SH_HANDLE);
657 
658 	/* connect */
659 	resp = 0;
660 	setup_handle(SH_CONNECT);
661 	CU_ASSERT(semanage_fcontext_count(sh, &resp) >= 0);
662 	CU_ASSERT(resp == FCONTEXTS_COUNT);
663 	cleanup_handle(SH_CONNECT);
664 
665 	/* trans */
666 	resp = 0;
667 	setup_handle(SH_TRANS);
668 	CU_ASSERT(semanage_fcontext_count(sh, &resp) >= 0);
669 	CU_ASSERT(resp == FCONTEXTS_COUNT);
670 	cleanup_handle(SH_TRANS);
671 }
672 
673 /* Function semanage_fcontext_iterate */
674 unsigned int counter_fcontext_iterate = 0;
675 
handler_fcontext_iterate(const semanage_fcontext_t * record,void * varg)676 int handler_fcontext_iterate(const semanage_fcontext_t *record, void *varg)
677 {
678 	CU_ASSERT_PTR_NOT_NULL(record);
679 	counter_fcontext_iterate++;
680 	return 0;
681 }
682 
helper_fcontext_iterate_invalid(void)683 void helper_fcontext_iterate_invalid(void)
684 {
685 	/* setup */
686 	setup_handle(SH_HANDLE);
687 
688 	/* test */
689 	CU_ASSERT(semanage_fcontext_iterate(sh, &handler_fcontext_iterate,
690 				            NULL) < 0);
691 	CU_ASSERT(semanage_fcontext_iterate(sh, NULL, NULL) < 0);
692 
693 	/* cleanup */
694 	cleanup_handle(SH_HANDLE);
695 }
696 
helper_fcontext_iterate(level_t level)697 void helper_fcontext_iterate(level_t level)
698 {
699 	/* setup */
700 	setup_handle(level);
701 	counter_fcontext_iterate = 0;
702 
703 	/* test */
704 	CU_ASSERT(semanage_fcontext_iterate(sh, &handler_fcontext_iterate,
705 					    NULL) >= 0);
706 	CU_ASSERT(counter_fcontext_iterate == FCONTEXTS_COUNT);
707 
708 	/* cleanup */
709 	cleanup_handle(level);
710 }
711 
test_fcontext_iterate(void)712 void test_fcontext_iterate(void)
713 {
714 	helper_fcontext_iterate_invalid();
715 	helper_fcontext_iterate(SH_CONNECT);
716 	helper_fcontext_iterate(SH_TRANS);
717 }
718 
719 /* Function semanage_fcontext_list */
helper_fcontext_list_invalid(void)720 void helper_fcontext_list_invalid(void)
721 {
722 	semanage_fcontext_t **records;
723 	unsigned int count;
724 
725 	/* setup */
726 	setup_handle(SH_HANDLE);
727 
728 	/* test */
729 	CU_ASSERT(semanage_fcontext_list(sh, &records, &count) < 0);
730 	CU_ASSERT(semanage_fcontext_list(sh, NULL, &count) < 0);
731 	CU_ASSERT(semanage_fcontext_list(sh, &records, NULL) < 0);
732 
733 	/* cleanup */
734 	cleanup_handle(SH_HANDLE);
735 }
736 
helper_fcontext_list(level_t level)737 void helper_fcontext_list(level_t level)
738 {
739 	semanage_fcontext_t **records;
740 	unsigned int count;
741 
742 	/* setup */
743 	setup_handle(level);
744 
745 	/* test */
746 	CU_ASSERT(semanage_fcontext_list(sh, &records, &count) >= 0);
747 	CU_ASSERT(count == FCONTEXTS_COUNT);
748 
749 	for (unsigned int i = 0; i < count; i++)
750 		CU_ASSERT_PTR_NOT_NULL(records[i]);
751 
752 	for (unsigned int i = 0; i < count; i++)
753 		semanage_fcontext_free(records[i]);
754 
755 	/* cleanup */
756 	cleanup_handle(level);
757 }
758 
test_fcontext_list(void)759 void test_fcontext_list(void)
760 {
761 	helper_fcontext_list_invalid();
762 	helper_fcontext_list(SH_CONNECT);
763 	helper_fcontext_list(SH_TRANS);
764 }
765 
766 /* 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)767 void helper_fcontext_modify_del_local(level_t level, int fcontext_idx,
768 				      const char *con_str, int exp_res)
769 {
770 	semanage_fcontext_t *fcontext;
771 	semanage_fcontext_t *fcontext_local;
772 	semanage_fcontext_key_t *key = NULL;
773 	semanage_context_t *con = NULL;
774 	int res;
775 
776 	/* setup */
777 	setup_handle(level);
778 	fcontext = get_fcontext_nth(fcontext_idx);
779 	CU_ASSERT(semanage_fcontext_key_extract(sh, fcontext, &key) >= 0);
780 	CU_ASSERT_PTR_NOT_NULL(key);
781 
782 	if (con_str != NULL) {
783 		CU_ASSERT(semanage_context_from_string(sh, con_str, &con) >= 0);
784 		CU_ASSERT_PTR_NOT_NULL(con);
785 	} else {
786 		con = NULL;
787 	}
788 
789 	CU_ASSERT(semanage_fcontext_set_con(sh, fcontext, con) >= 0);
790 
791 	/* test */
792 	res = semanage_fcontext_modify_local(sh, key, fcontext);
793 
794 	if (exp_res >= 0) {
795 		CU_ASSERT(res >= 0);
796 
797 		if (level == SH_TRANS) {
798 			helper_commit();
799 			helper_begin_transaction();
800 		}
801 
802 		CU_ASSERT(semanage_fcontext_query_local(sh, key,
803 					                &fcontext_local) >= 0);
804 		CU_ASSERT(semanage_fcontext_compare2(fcontext_local,
805 						     fcontext) == 0);
806 		CU_ASSERT(semanage_fcontext_del_local(sh, key) >= 0);
807 		CU_ASSERT(semanage_fcontext_query_local(sh, key,
808 					                &fcontext_local) < 0);
809 	} else {
810 		CU_ASSERT(res < 0);
811 	}
812 
813 	/* cleanup */
814 	semanage_fcontext_key_free(key);
815 	semanage_fcontext_free(fcontext);
816 	cleanup_handle(level);
817 }
818 
test_fcontext_modify_del_local(void)819 void test_fcontext_modify_del_local(void)
820 {
821 	helper_fcontext_modify_del_local(SH_CONNECT, I_FIRST,
822 					 "system_u:object_r:tmp_t:s0", -1);
823 	helper_fcontext_modify_del_local(SH_CONNECT, I_SECOND,
824 					 "system_u:object_r:tmp_t:s0", -1);
825 	helper_fcontext_modify_del_local(SH_TRANS, I_FIRST,
826 					 "system_u:object_r:tmp_t:s0", 1);
827 	helper_fcontext_modify_del_local(SH_TRANS, I_SECOND,
828 					 "system_u:object_r:tmp_t:s0", 1);
829 }
830 
831 /* Function semanage_fcontext_query_local */
test_fcontext_query_local(void)832 void test_fcontext_query_local(void)
833 {
834 	semanage_fcontext_key_t *key = NULL;
835 	semanage_fcontext_t *resp = NULL;
836 
837 	/* connect */
838 	setup_handle(SH_CONNECT);
839 
840 	key = get_fcontext_key_nth(I_FIRST);
841 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) < 0);
842 	CU_ASSERT_PTR_NULL(resp);
843 
844 	cleanup_handle(SH_CONNECT);
845 
846 	/* transaction */
847 	setup_handle(SH_TRANS);
848 
849 	key = get_fcontext_key_nth(I_FIRST);
850 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) < 0);
851 	CU_ASSERT_PTR_NULL(resp);
852 
853 	add_local_fcontext(I_FIRST);
854 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) >= 0);
855 	CU_ASSERT_PTR_NOT_NULL(resp);
856 
857 	semanage_fcontext_key_free(key);
858 	key = get_fcontext_key_nth(I_SECOND);
859 	add_local_fcontext(I_SECOND);
860 	CU_ASSERT(semanage_fcontext_query_local(sh, key, &resp) >= 0);
861 	CU_ASSERT_PTR_NOT_NULL(resp);
862 
863 	/* cleanup */
864 	delete_local_fcontext(I_FIRST);
865 	delete_local_fcontext(I_SECOND);
866 	cleanup_handle(SH_TRANS);
867 }
868 
869 /* Function semanage_fcontext_exists_local */
test_fcontext_exists_local(void)870 void test_fcontext_exists_local(void)
871 {
872 	int resp = -1;
873 	semanage_fcontext_key_t *key;
874 
875 	/* setup */
876 	setup_handle(SH_TRANS);
877 	key = get_fcontext_key_nth(I_FIRST);
878 
879 	/* test */
880 	CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0);
881 	CU_ASSERT(resp == 0);
882 
883 	add_local_fcontext(I_FIRST);
884 	resp = -1;
885 
886 	CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0);
887 	CU_ASSERT(resp == 1);
888 
889 	delete_local_fcontext(I_FIRST);
890 	resp = -1;
891 
892 	CU_ASSERT(semanage_fcontext_exists_local(sh, key, &resp) >= 0);
893 	CU_ASSERT(resp == 0);
894 
895 	resp = -1;
896 
897 	CU_ASSERT(semanage_fcontext_exists_local(sh, NULL, &resp) >= 0);
898 	CU_ASSERT(resp == 0);
899 
900 	/* cleanup */
901 	cleanup_handle(SH_TRANS);
902 }
903 
904 /* Function semanage_fcontext_count_local */
test_fcontext_count_local(void)905 void test_fcontext_count_local(void)
906 {
907 	unsigned int resp;
908 
909 	/* handle */
910 	setup_handle(SH_HANDLE);
911 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) < 0);
912 	cleanup_handle(SH_HANDLE);
913 
914 	/* connect */
915 	setup_handle(SH_CONNECT);
916 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
917 	CU_ASSERT(resp == 0);
918 	cleanup_handle(SH_CONNECT);
919 
920 	/* transaction */
921 	setup_handle(SH_TRANS);
922 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
923 	CU_ASSERT(resp == 0);
924 
925 	add_local_fcontext(I_FIRST);
926 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
927 	CU_ASSERT(resp == 1);
928 
929 	add_local_fcontext(I_SECOND);
930 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
931 	CU_ASSERT(resp == 2);
932 
933 	delete_local_fcontext(I_SECOND);
934 	CU_ASSERT(semanage_fcontext_count_local(sh, &resp) >= 0);
935 	CU_ASSERT(resp == 1);
936 
937 	/* cleanup */
938 	delete_local_fcontext(I_FIRST);
939 	cleanup_handle(SH_TRANS);
940 }
941 
942 /* Function semanage_fcontext_iterate_local */
943 unsigned int counter_fcontext_iterate_local = 0;
944 
handler_fcontext_iterate_local(const semanage_fcontext_t * record,void * varg)945 int handler_fcontext_iterate_local(const semanage_fcontext_t *record,
946 				   void *varg)
947 {
948 	CU_ASSERT_PTR_NOT_NULL(record);
949 	counter_fcontext_iterate_local++;
950 	return 0;
951 }
952 
test_fcontext_iterate_local(void)953 void test_fcontext_iterate_local(void)
954 {
955 	/* handle */
956 	setup_handle(SH_HANDLE);
957 
958 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
959 				    &handler_fcontext_iterate_local, NULL) < 0);
960 	CU_ASSERT(semanage_fcontext_iterate_local(sh, NULL, NULL) < 0);
961 
962 	cleanup_handle(SH_HANDLE);
963 
964 	/* connect */
965 	setup_handle(SH_CONNECT);
966 
967 	counter_fcontext_iterate_local = 0;
968 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
969 				   &handler_fcontext_iterate_local, NULL) >= 0);
970 	CU_ASSERT(counter_fcontext_iterate_local == 0);
971 	CU_ASSERT(semanage_fcontext_iterate_local(sh, NULL, NULL) >= 0);
972 
973 	cleanup_handle(SH_CONNECT);
974 
975 	/* transaction */
976 	setup_handle(SH_TRANS);
977 
978 	counter_fcontext_iterate_local = 0;
979 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
980 				   &handler_fcontext_iterate_local, NULL) >= 0);
981 	CU_ASSERT(counter_fcontext_iterate_local == 0);
982 
983 	add_local_fcontext(I_FIRST);
984 	counter_fcontext_iterate_local = 0;
985 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
986 				   &handler_fcontext_iterate_local, NULL) >= 0);
987 	CU_ASSERT(counter_fcontext_iterate_local == 1);
988 
989 	add_local_fcontext(I_SECOND);
990 	counter_fcontext_iterate_local = 0;
991 	CU_ASSERT(semanage_fcontext_iterate_local(sh,
992 				   &handler_fcontext_iterate_local, NULL) >= 0);
993 	CU_ASSERT(counter_fcontext_iterate_local == 2);
994 
995 	/* cleanup */
996 	delete_local_fcontext(I_FIRST);
997 	delete_local_fcontext(I_SECOND);
998 	cleanup_handle(SH_TRANS);
999 }
1000 
1001 /* Function semanage_fcontext_list_local */
test_fcontext_list_local(void)1002 void test_fcontext_list_local(void)
1003 {
1004 	semanage_fcontext_t **records;
1005 	unsigned int count;
1006 
1007 	/* handle */
1008 	setup_handle(SH_HANDLE);
1009 
1010 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) < 0);
1011 	CU_ASSERT(semanage_fcontext_list_local(sh, NULL, &count) < 0);
1012 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, NULL) < 0);
1013 
1014 	cleanup_handle(SH_HANDLE);
1015 
1016 	/* connect */
1017 	setup_handle(SH_CONNECT);
1018 
1019 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1020 	CU_ASSERT(count == 0);
1021 
1022 	cleanup_handle(SH_CONNECT);
1023 
1024 	/* transaction */
1025 	setup_handle(SH_TRANS);
1026 
1027 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1028 	CU_ASSERT(count == 0);
1029 
1030 	add_local_fcontext(I_FIRST);
1031 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1032 	CU_ASSERT(count == 1);
1033 	CU_ASSERT_PTR_NOT_NULL(records[0]);
1034 
1035 	add_local_fcontext(I_SECOND);
1036 	CU_ASSERT(semanage_fcontext_list_local(sh, &records, &count) >= 0);
1037 	CU_ASSERT(count == 2);
1038 	CU_ASSERT_PTR_NOT_NULL(records[0]);
1039 	CU_ASSERT_PTR_NOT_NULL(records[1]);
1040 
1041 	/* cleanup */
1042 	delete_local_fcontext(I_FIRST);
1043 	delete_local_fcontext(I_SECOND);
1044 	cleanup_handle(SH_TRANS);
1045 }
1046