1 /* Authors: Christopher Ashworth <cashworth@tresys.com>
2 * Caleb Case <ccase@tresys.com>
3 * Chris PeBenito <cpebenito@tresys.com>
4 *
5 * Copyright (C) 2006 Tresys Technology, LLC
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /* The purpose of this file is to provide unit tests of the functions in:
23 *
24 * libsemanage/src/semanage_store.c
25 *
26 */
27
28 #include "handle.h"
29 #include "semanage_store.h"
30
31 #include "utilities.h"
32 #include "test_semanage_store.h"
33
34 #include <libgen.h>
35 #include <limits.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/mman.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <fcntl.h>
43 #include <unistd.h>
44 #include <CUnit/Basic.h>
45
46 semanage_handle_t *sh = NULL;
47 const char *rootpath = "./test-policy";
48 const char *polpath = "./test-policy/store/";
49 const char *readlockpath = "./test-policy/store/semanage.read.LOCK";
50 const char *translockpath = "./test-policy/store/semanage.trans.LOCK";
51 const char *actpath = "./test-policy/store/active";
52 const char *modpath = "./test-policy/store/active/modules";
53
54 /* The suite initialization function.
55 * Returns zero on success, non-zero otherwise.
56 */
semanage_store_test_init(void)57 int semanage_store_test_init(void)
58 {
59 int err;
60
61 /* create directories */
62 err = mkdir(rootpath, S_IRUSR | S_IWUSR | S_IXUSR);
63 if (err != 0)
64 return -1;
65
66 err = mkdir(polpath, S_IRUSR | S_IWUSR | S_IXUSR);
67 if (err != 0)
68 return -1;
69
70 err = mkdir(actpath, S_IRUSR | S_IWUSR | S_IXUSR);
71 if (err != 0)
72 return -1;
73
74 err = mkdir(modpath, S_IRUSR | S_IWUSR | S_IXUSR);
75 if (err != 0)
76 return -1;
77
78 /* initialize the handle */
79 sh = semanage_handle_create();
80 if (sh == NULL)
81 return -1;
82
83 /* hide error messages */
84 sh->msg_callback = test_msg_handler;
85
86 /* use our own policy store */
87 free(sh->conf->store_path);
88 sh->conf->store_path = strdup("store");
89
90 /* initialize paths */
91 err = semanage_check_init(sh, rootpath);
92 if (err != 0)
93 return -1;
94
95 return 0;
96 }
97
98 /* The suite cleanup function.
99 * Returns zero on success, non-zero otherwise.
100 */
semanage_store_test_cleanup(void)101 int semanage_store_test_cleanup(void)
102 {
103 int err;
104
105 /* remove the test policy directories */
106 err = rmdir(modpath);
107 if (err != 0)
108 return -1;
109
110 err = rmdir(actpath);
111 if (err != 0)
112 return -1;
113
114 err = rmdir(polpath);
115 if (err != 0)
116 return -1;
117
118 err = rmdir(rootpath);
119 if (err != 0)
120 return -1;
121
122 /* cleanup the handle */
123 semanage_handle_destroy(sh);
124 return 0;
125 }
126
127 /* Adds all the tests needed for this suite.
128 */
semanage_store_add_tests(CU_pSuite suite)129 int semanage_store_add_tests(CU_pSuite suite)
130 {
131 if (NULL ==
132 CU_add_test(suite, "semanage_store_access_check",
133 test_semanage_store_access_check)) {
134 CU_cleanup_registry();
135 return CU_get_error();
136 }
137
138 if (NULL ==
139 CU_add_test(suite, "semanage_get_lock", test_semanage_get_lock)) {
140 CU_cleanup_registry();
141 return CU_get_error();
142 }
143
144 if (NULL ==
145 CU_add_test(suite, "semanage_nc_sort", test_semanage_nc_sort)) {
146 CU_cleanup_registry();
147 return CU_get_error();
148 }
149
150 return 0;
151 }
152
153 /* Tests the semanage_store_access_check function in semanage_store.c
154 */
test_semanage_store_access_check(void)155 void test_semanage_store_access_check(void)
156 {
157 int err;
158
159 /* create lock file */
160 err = mknod(readlockpath, S_IRUSR | S_IWUSR, S_IFREG);
161
162 /* check with permissions 000 */
163 err = chmod(modpath, 0);
164 CU_ASSERT(err == 0);
165 err = chmod(readlockpath, 0);
166 CU_ASSERT(err == 0);
167 err = chmod(polpath, 0);
168 CU_ASSERT(err == 0);
169
170 err = semanage_store_access_check();
171 CU_ASSERT(err == -1);
172
173 /* check with permissions 500 */
174 err = chmod(polpath, S_IRUSR | S_IXUSR);
175 CU_ASSERT(err == 0);
176 err = chmod(readlockpath, S_IRUSR);
177 CU_ASSERT(err == 0);
178 err = chmod(modpath, S_IRUSR | S_IXUSR);
179 CU_ASSERT(err == 0);
180
181 err = semanage_store_access_check();
182 CU_ASSERT(err == SEMANAGE_CAN_READ);
183
184 /* check with permissions 700 */
185 err = chmod(polpath, S_IRUSR | S_IWUSR | S_IXUSR);
186 CU_ASSERT(err == 0);
187 err = chmod(readlockpath, S_IRUSR | S_IWUSR);
188 CU_ASSERT(err == 0);
189 err = chmod(modpath, S_IRUSR | S_IWUSR | S_IXUSR);
190 CU_ASSERT(err == 0);
191
192 err = semanage_store_access_check();
193 CU_ASSERT(err == SEMANAGE_CAN_WRITE);
194
195 /* check with lock file 000 and others 500 */
196 err = chmod(polpath, S_IRUSR | S_IXUSR);
197 CU_ASSERT(err == 0);
198 err = chmod(readlockpath, 0);
199 CU_ASSERT(err == 0);
200 err = chmod(modpath, S_IRUSR | S_IXUSR);
201 CU_ASSERT(err == 0);
202
203 err = semanage_store_access_check();
204 CU_ASSERT(err == 0);
205
206 /* check with lock file 000 and others 700 */
207 err = chmod(polpath, S_IRUSR | S_IWUSR | S_IXUSR);
208 CU_ASSERT(err == 0);
209 err = chmod(readlockpath, 0);
210 CU_ASSERT(err == 0);
211 err = chmod(modpath, S_IRUSR | S_IWUSR | S_IXUSR);
212 CU_ASSERT(err == 0);
213
214 err = semanage_store_access_check();
215 CU_ASSERT(err == 0);
216
217 /* remove lock file */
218 err = remove(readlockpath);
219 CU_ASSERT(err == 0);
220
221 /* check with no lock file and 000 */
222 err = chmod(modpath, 0);
223 CU_ASSERT(err == 0);
224 err = chmod(polpath, 0);
225 CU_ASSERT(err == 0);
226
227 err = semanage_store_access_check();
228 CU_ASSERT(err == -1);
229
230 /* check with no lock file and 500 */
231 err = chmod(polpath, S_IRUSR | S_IXUSR);
232 CU_ASSERT(err == 0);
233 err = chmod(modpath, S_IRUSR | S_IXUSR);
234 CU_ASSERT(err == 0);
235
236 err = semanage_store_access_check();
237 CU_ASSERT(err == 0);
238
239 /* check with no lock file but write in polpath */
240 err = chmod(polpath, S_IRUSR | S_IWUSR | S_IXUSR);
241 CU_ASSERT(err == 0);
242
243 err = semanage_store_access_check();
244 CU_ASSERT(err == SEMANAGE_CAN_READ);
245
246 /* check with no lock file and 700 */
247 err = chmod(polpath, S_IRUSR | S_IWUSR | S_IXUSR);
248 CU_ASSERT(err == 0);
249 err = chmod(modpath, S_IRUSR | S_IWUSR | S_IXUSR);
250 CU_ASSERT(err == 0);
251
252 err = semanage_store_access_check();
253 CU_ASSERT(err == SEMANAGE_CAN_WRITE);
254 }
255
256 /* Tests the semanage_get_lock functions in semanage_store.c
257 */
test_semanage_get_lock(void)258 void test_semanage_get_lock(void)
259 {
260 int err;
261
262 /* attempt to get an active lock */
263 err = semanage_get_active_lock(sh);
264 CU_ASSERT(err == 0);
265
266 /* attempt to get the lock again */
267 err = semanage_get_active_lock(sh);
268 CU_ASSERT(err == 0);
269
270 /* attempt to release the active lock */
271 semanage_release_active_lock(sh);
272
273 /* attempt to get an active lock */
274 err = semanage_get_active_lock(sh);
275 CU_ASSERT(err == 0);
276
277 /* attempt to release the active lock */
278 semanage_release_active_lock(sh);
279
280 /* attempt to get a trans lock */
281 err = semanage_get_trans_lock(sh);
282 CU_ASSERT(err == 0);
283
284 /* attempt to get the lock again */
285 err = semanage_get_trans_lock(sh);
286 CU_ASSERT(err == 0);
287
288 /* attempt to release the trans lock */
289 semanage_release_trans_lock(sh);
290
291 /* attempt to get a trans lock */
292 err = semanage_get_trans_lock(sh);
293 CU_ASSERT(err == 0);
294
295 /* attempt to release the trans lock */
296 semanage_release_trans_lock(sh);
297
298 /* remove the lock files */
299 err = remove(readlockpath);
300 CU_ASSERT(err == 0);
301 err = remove(translockpath);
302 CU_ASSERT(err == 0);
303 }
304
305 /* Tests the semanage_nc_sort function in semanage_store.c
306 */
test_semanage_nc_sort(void)307 void test_semanage_nc_sort(void)
308 {
309 char *source_buf, *sorted_buf = NULL, *good_buf, *bad_buf;
310 size_t source_buf_len, sorted_buf_len, good_buf_len, bad_buf_len;
311 int sourcefd, goodfd, badfd, err;
312 struct stat sb;
313
314 /* open source file */
315 sourcefd = open("nc_sort_unsorted", O_RDONLY);
316 if (sourcefd < 0) {
317 CU_FAIL("Missing nc_sort_unsorted test file.");
318 return;
319 }
320 fstat(sourcefd, &sb);
321 source_buf_len = sb.st_size;
322 source_buf =
323 (char *)mmap(NULL, source_buf_len, PROT_READ, MAP_PRIVATE, sourcefd,
324 0);
325
326 /* open good result file */
327 goodfd = open("nc_sort_sorted", O_RDONLY);
328 if (goodfd < 0) {
329 CU_FAIL("Missing nc_sort_sorted test file.");
330 goto out2;
331 }
332 fstat(goodfd, &sb);
333 good_buf_len = sb.st_size;
334 good_buf =
335 (char *)mmap(NULL, good_buf_len, PROT_READ, MAP_PRIVATE, goodfd, 0);
336
337 /* open malformed source file (missing priorities) */
338 badfd = open("nc_sort_malformed", O_RDONLY);
339 if (badfd < 0) {
340 CU_FAIL("Missing nc_sort_malformed test file.");
341 goto out1;
342 }
343 fstat(badfd, &sb);
344 bad_buf_len = sb.st_size;
345 bad_buf =
346 (char *)mmap(NULL, bad_buf_len, PROT_READ, MAP_PRIVATE, badfd, 0);
347
348 /* sort test file */
349 err =
350 semanage_nc_sort(sh, source_buf, source_buf_len, &sorted_buf,
351 &sorted_buf_len);
352 CU_ASSERT_FALSE(err);
353 CU_ASSERT_STRING_EQUAL(sorted_buf, good_buf);
354
355 /* reset for reuse in next test */
356 free(sorted_buf);
357 sorted_buf = NULL;
358
359 /* sort malformed source file */
360 err =
361 semanage_nc_sort(sh, bad_buf, bad_buf_len, &sorted_buf,
362 &sorted_buf_len);
363 CU_ASSERT_EQUAL(err, -1);
364
365 free(sorted_buf);
366
367 munmap(bad_buf, bad_buf_len);
368 close(badfd);
369 out1:
370 munmap(good_buf, good_buf_len);
371 close(goodfd);
372 out2:
373 munmap(source_buf, source_buf_len);
374 close(sourcefd);
375 }
376