1 /*
2  * Copyright 2011 Tresys Technology, LLC. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *    1. Redistributions of source code must retain the above copyright notice,
8  *       this list of conditions and the following disclaimer.
9  *
10  *    2. Redistributions in binary form must reproduce the above copyright notice,
11  *       this list of conditions and the following disclaimer in the documentation
12  *       and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS
15  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17  * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * The views and conclusions contained in the software and documentation are those
26  * of the authors and should not be interpreted as representing official policies,
27  * either expressed or implied, of Tresys Technology, LLC.
28  */
29 
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 
34 #include "cil_internal.h"
35 #include "cil_log.h"
36 #include "cil_mem.h"
37 #include "cil_tree.h"
38 #include "cil_list.h"
39 #include "cil_symtab.h"
40 #include "cil_copy_ast.h"
41 #include "cil_build_ast.h"
42 #include "cil_strpool.h"
43 
44 struct cil_args_copy {
45 	struct cil_tree_node *dest;
46 	struct cil_db *db;
47 };
48 
cil_copy_list(struct cil_list * data,struct cil_list ** copy)49 void cil_copy_list(struct cil_list *data, struct cil_list **copy)
50 {
51 	struct cil_list *new;
52 	struct cil_list_item *orig_item;
53 
54 	cil_list_init(&new, data->flavor);
55 
56 	cil_list_for_each(orig_item, data) {
57 		switch (orig_item->flavor) {
58 		case CIL_STRING:
59 			cil_list_append(new, CIL_STRING, orig_item->data);
60 			break;
61 		case CIL_LIST: {
62 			struct cil_list *new_sub = NULL;
63 			cil_copy_list((struct cil_list*)orig_item->data, &new_sub);
64 			cil_list_append(new, CIL_LIST, new_sub);
65 			break;
66 		}
67 		case CIL_PARAM: {
68 			struct cil_param *po = orig_item->data;
69 			struct cil_param *pn;
70 			cil_param_init(&pn);
71 			pn->str = po->str;
72 			pn->flavor = po->flavor;
73 			cil_list_append(new, CIL_PARAM, pn);
74 		}
75 			break;
76 
77 		default:
78 			cil_list_append(new, orig_item->flavor, orig_item->data);
79 			break;
80 		}
81 	}
82 
83 	*copy = new;
84 }
85 
cil_copy_node(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)86 int cil_copy_node(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
87 {
88 	char *new = NULL;
89 
90 	if (data != NULL) {
91 		new = data;
92 	}
93 	*copy = new;
94 
95 	return SEPOL_OK;
96 }
97 
cil_copy_block(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)98 int cil_copy_block(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
99 {
100 	struct cil_block *orig = data;
101 	char *key = orig->datum.name;
102 	struct cil_symtab_datum *datum = NULL;
103 
104 	cil_symtab_get_datum(symtab, key, &datum);
105 	if (datum == NULL) {
106 		struct cil_block *new;
107 		cil_block_init(&new);
108 		*copy = new;
109 	} else {
110 		*copy = datum;;
111 	}
112 
113 	return SEPOL_OK;
114 }
115 
cil_copy_blockabstract(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)116 int cil_copy_blockabstract(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
117 {
118 	struct cil_blockabstract *orig = data;
119 	struct cil_blockabstract *new = NULL;
120 
121 	cil_blockabstract_init(&new);
122 
123 	new->block_str = orig->block_str;
124 
125 	*copy = new;
126 
127 	return SEPOL_OK;
128 }
129 
cil_copy_blockinherit(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)130 int cil_copy_blockinherit(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
131 {
132 	struct cil_blockinherit *orig = data;
133 	struct cil_blockinherit *new = NULL;
134 
135 	cil_blockinherit_init(&new);
136 
137 	new->block_str = orig->block_str;
138 	new->block = orig->block;
139 
140 	*copy = new;
141 
142 	return SEPOL_OK;
143 }
144 
cil_copy_policycap(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)145 int cil_copy_policycap(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
146 {
147 	struct cil_policycap *orig = data;
148 	char *key = orig->datum.name;
149 	struct cil_symtab_datum *datum = NULL;
150 
151 	cil_symtab_get_datum(symtab, key, &datum);
152 	if (datum == NULL) {
153 		struct cil_policycap *new;
154 		cil_policycap_init(&new);
155 		*copy = new;
156 	} else {
157 		*copy = datum;
158 	}
159 
160 	return SEPOL_OK;
161 }
162 
cil_copy_perm(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)163 int cil_copy_perm(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
164 {
165 	struct cil_perm *orig = data;
166 	char *key = orig->datum.name;
167 	struct cil_symtab_datum *datum = NULL;
168 
169 	cil_symtab_get_datum(symtab, key, &datum);
170 	if (datum == NULL) {
171 		struct cil_perm *new;
172 		cil_perm_init(&new);
173 		*copy = new;
174 	} else {
175 		*copy = datum;
176 	}
177 
178 	return SEPOL_OK;
179 }
180 
cil_copy_classperms(struct cil_classperms * orig,struct cil_classperms ** new)181 void cil_copy_classperms(struct cil_classperms *orig, struct cil_classperms **new)
182 {
183 	cil_classperms_init(new);
184 	(*new)->class_str = orig->class_str;
185 	cil_copy_list(orig->perm_strs, &((*new)->perm_strs));
186 }
187 
cil_copy_classperms_set(struct cil_classperms_set * orig,struct cil_classperms_set ** new)188 void cil_copy_classperms_set(struct cil_classperms_set *orig, struct cil_classperms_set **new)
189 {
190 	cil_classperms_set_init(new);
191 	(*new)->set_str = orig->set_str;
192 }
193 
cil_copy_classperms_list(struct cil_list * orig,struct cil_list ** new)194 void cil_copy_classperms_list(struct cil_list *orig, struct cil_list **new)
195 {
196 	struct cil_list_item *orig_item;
197 
198 	if (orig == NULL) {
199 		return;
200 	}
201 
202 	cil_list_init(new, CIL_LIST_ITEM);
203 	cil_list_for_each(orig_item, orig) {
204 		if (orig_item->flavor == CIL_CLASSPERMS) {
205 			struct cil_classperms *cp;
206 			cil_copy_classperms(orig_item->data, &cp);
207 			cil_list_append(*new, CIL_CLASSPERMS, cp);
208 		} else {
209 			struct cil_classperms_set *cp_set;
210 			cil_copy_classperms_set(orig_item->data, &cp_set);
211 			cil_list_append(*new, CIL_CLASSPERMS_SET, cp_set);
212 		}
213 	}
214 }
215 
cil_copy_classmapping(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)216 int cil_copy_classmapping(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
217 {
218 	struct cil_classmapping *orig = data;
219 	struct cil_classmapping *new = NULL;
220 
221 	cil_classmapping_init(&new);
222 
223 	new->map_class_str = orig->map_class_str;
224 	new->map_perm_str = orig->map_perm_str;
225 
226 	cil_copy_classperms_list(orig->classperms, &new->classperms);
227 
228 	*copy = new;
229 
230 	return SEPOL_OK;
231 }
232 
cil_copy_class(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)233 int cil_copy_class(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
234 {
235 	struct cil_class *orig = data;
236 	struct cil_class *new = NULL;
237 	char *key = orig->datum.name;
238 	struct cil_symtab_datum *datum = NULL;
239 
240 	cil_symtab_get_datum(symtab, key, &datum);
241 	if (datum != NULL) {
242 		cil_log(CIL_INFO, "cil_copy_class: class cannot be redefined\n");
243 		return SEPOL_ERR;
244 	}
245 
246 	cil_class_init(&new);
247 
248 	new->common = NULL;
249 
250 	*copy = new;
251 
252 	return SEPOL_OK;
253 }
254 
cil_copy_classorder(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)255 int cil_copy_classorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
256 {
257 	struct cil_classorder *orig = data;
258 	struct cil_classorder *new = NULL;
259 
260 	cil_classorder_init(&new);
261 	if (orig->class_list_str != NULL) {
262 		cil_copy_list(orig->class_list_str, &new->class_list_str);
263 	}
264 
265 	*copy = new;
266 
267 	return SEPOL_OK;
268 }
269 
cil_copy_classpermission(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)270 int cil_copy_classpermission(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
271 {
272 	struct cil_classpermission *orig = data;
273 	struct cil_classpermission *new = NULL;
274 	char *key = orig->datum.name;
275 	struct cil_symtab_datum *datum = NULL;
276 
277 	if (key != NULL) {
278 		cil_symtab_get_datum(symtab, key, &datum);
279 		if (datum != NULL) {
280 			cil_log(CIL_INFO, "classpermission cannot be redefined\n");
281 			return SEPOL_ERR;
282 		}
283 	}
284 
285 	cil_classpermission_init(&new);
286 
287 	cil_copy_classperms_list(orig->classperms, &new->classperms);
288 
289 	*copy = new;
290 
291 	return SEPOL_OK;
292 }
293 
cil_copy_classpermissionset(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)294 int cil_copy_classpermissionset(__attribute__((unused)) struct cil_db *db, void *data, void **copy,  __attribute__((unused)) symtab_t *symtab)
295 {
296 	struct cil_classpermissionset *orig = data;
297 	struct cil_classpermissionset *new = NULL;
298 
299 	cil_classpermissionset_init(&new);
300 
301 	new->set_str = orig->set_str;
302 
303 	cil_copy_classperms_list(orig->classperms, &new->classperms);
304 
305 	*copy = new;
306 
307 	return SEPOL_OK;
308 }
309 
cil_copy_classcommon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)310 int cil_copy_classcommon(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
311 {
312 	struct cil_classcommon *orig = data;
313 	struct cil_classcommon *new = NULL;
314 
315 	cil_classcommon_init(&new);
316 
317 	new->class_str = orig->class_str;
318 	new->common_str = orig->common_str;
319 
320 	*copy = new;
321 
322 	return SEPOL_OK;
323 }
324 
cil_copy_sid(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)325 int cil_copy_sid(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
326 {
327 	struct cil_sid *orig = data;
328 	char *key = orig->datum.name;
329 	struct cil_symtab_datum *datum = NULL;
330 
331 	cil_symtab_get_datum(symtab, key, &datum);
332 	if (datum == NULL) {
333 		struct cil_sid *new;
334 		cil_sid_init(&new);
335 		*copy = new;
336 	} else {
337 		*copy = datum;
338 	}
339 
340 	return SEPOL_OK;
341 }
342 
cil_copy_sidcontext(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)343 int cil_copy_sidcontext(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
344 {
345 	struct cil_sidcontext *orig = data;
346 	struct cil_sidcontext *new = NULL;
347 
348 	cil_sidcontext_init(&new);
349 
350 	if (orig->context_str != NULL) {
351 		new->context_str = orig->context_str;
352 	} else {
353 		cil_context_init(&new->context);
354 		cil_copy_fill_context(db, orig->context, new->context);
355 	}
356 
357 	*copy = new;
358 
359 	return SEPOL_OK;
360 }
361 
cil_copy_sidorder(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)362 int cil_copy_sidorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
363 {
364 	struct cil_sidorder *orig = data;
365 	struct cil_sidorder *new = NULL;
366 
367 	cil_sidorder_init(&new);
368 	if (orig->sid_list_str != NULL) {
369 		cil_copy_list(orig->sid_list_str, &new->sid_list_str);
370 	}
371 
372 	*copy = new;
373 
374 	return SEPOL_OK;
375 }
376 
cil_copy_user(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)377 int cil_copy_user(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
378 {
379 	struct cil_user *orig = data;
380 	char *key = orig->datum.name;
381 	struct cil_symtab_datum *datum = NULL;
382 
383 	cil_symtab_get_datum(symtab, key, &datum);
384 	if (datum == NULL) {
385 		struct cil_user *new;
386 		cil_user_init(&new);
387 		*copy = new;
388 	} else {
389 		*copy = datum;
390 	}
391 
392 	return SEPOL_OK;
393 }
394 
cil_copy_userattribute(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)395 int cil_copy_userattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
396 {
397 	struct cil_userattribute *orig = data;
398 	struct cil_userattribute *new = NULL;
399 	char *key = orig->datum.name;
400 	struct cil_symtab_datum *datum = NULL;
401 
402 	cil_symtab_get_datum(symtab, key, &datum);
403 	if (datum == NULL) {
404 		cil_userattribute_init(&new);
405 		*copy = new;
406 	} else {
407 		*copy = datum;
408 	}
409 
410 	return SEPOL_OK;
411 }
412 
cil_copy_userattributeset(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)413 int cil_copy_userattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
414 {
415 	struct cil_userattributeset *orig = data;
416 	struct cil_userattributeset *new = NULL;
417 
418 	cil_userattributeset_init(&new);
419 
420 	new->attr_str = orig->attr_str;
421 
422 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
423 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
424 
425 	*copy = new;
426 
427 	return SEPOL_OK;
428 }
429 
cil_copy_userrole(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)430 int cil_copy_userrole(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
431 {
432 	struct cil_userrole *orig = data;
433 	struct cil_userrole *new = NULL;
434 
435 	cil_userrole_init(&new);
436 
437 	new->user_str = orig->user_str;
438 	new->role_str = orig->role_str;
439 
440 	*copy = new;
441 
442 	return SEPOL_OK;
443 }
444 
cil_copy_userlevel(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)445 int cil_copy_userlevel(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
446 {
447 	struct cil_userlevel *orig = data;
448 	struct cil_userlevel *new = NULL;
449 
450 	cil_userlevel_init(&new);
451 
452 	new->user_str = orig->user_str;
453 
454 	if (orig->level_str != NULL) {
455 		new->level_str = orig->level_str;
456 	} else {
457 		cil_copy_fill_level(db, orig->level, &new->level);
458 	}
459 
460 	*copy = new;
461 
462 	return SEPOL_OK;
463 }
464 
cil_copy_userrange(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)465 int cil_copy_userrange(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
466 {
467 	struct cil_userrange *orig = data;
468 	struct cil_userrange *new = NULL;
469 
470 	cil_userrange_init(&new);
471 
472 	new->user_str = orig->user_str;
473 
474 	if (orig->range_str != NULL) {
475 		new->range_str = orig->range_str;
476 	} else {
477 		cil_levelrange_init(&new->range);
478 		cil_copy_fill_levelrange(db, orig->range, new->range);
479 	}
480 
481 	*copy = new;
482 
483 	return SEPOL_OK;
484 }
485 
cil_copy_userprefix(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)486 int cil_copy_userprefix(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
487 {
488 	struct cil_userprefix *orig = data;
489 	struct cil_userprefix *new = NULL;
490 
491 	cil_userprefix_init(&new);
492 
493 	new->user_str = orig->user_str;
494 	new->prefix_str = orig->prefix_str;
495 
496 	*copy = new;
497 
498 	return SEPOL_OK;
499 }
500 
cil_copy_role(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)501 int cil_copy_role(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
502 {
503 	struct cil_role *orig = data;
504 	char *key = orig->datum.name;
505 	struct cil_symtab_datum *datum = NULL;
506 
507 	cil_symtab_get_datum(symtab, key, &datum);
508 	if (datum == NULL) {
509 		struct cil_role *new;
510 		cil_role_init(&new);
511 		*copy = new;
512 	} else {
513 		*copy = datum;
514 	}
515 
516 	return SEPOL_OK;
517 }
518 
cil_copy_roletype(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)519 int cil_copy_roletype(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
520 {
521 	struct cil_roletype *orig = data;
522 	struct cil_roletype *new = NULL;
523 
524 	cil_roletype_init(&new);
525 
526 	new->role_str = orig->role_str;
527 	new->type_str = orig->type_str;
528 
529 	*copy = new;
530 
531 	return SEPOL_OK;
532 }
533 
cil_copy_roleattribute(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)534 int cil_copy_roleattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
535 {
536 	struct cil_roleattribute *orig = data;
537 	char *key = orig->datum.name;
538 	struct cil_symtab_datum *datum = NULL;
539 
540 	cil_symtab_get_datum(symtab, key, &datum);
541 	if (datum == NULL) {
542 		struct cil_roleattribute *new;
543 		cil_roleattribute_init(&new);
544 		*copy = new;
545 	} else {
546 		*copy = datum;
547 	}
548 
549 	return SEPOL_OK;
550 }
551 
cil_copy_roleattributeset(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)552 int cil_copy_roleattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
553 {
554 	struct cil_roleattributeset *orig = data;
555 	struct cil_roleattributeset *new = NULL;
556 
557 	cil_roleattributeset_init(&new);
558 
559 	new->attr_str = orig->attr_str;
560 
561 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
562 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
563 
564 	*copy = new;
565 
566 	return SEPOL_OK;
567 }
568 
cil_copy_roleallow(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)569 int cil_copy_roleallow(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
570 {
571 	struct cil_roleallow *orig = data;
572 	struct cil_roleallow *new = NULL;
573 
574 	cil_roleallow_init(&new);
575 
576 	new->src_str = orig->src_str;
577 	new->tgt_str = orig->tgt_str;
578 
579 	*copy = new;
580 
581 	return SEPOL_OK;
582 }
583 
cil_copy_type(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)584 int cil_copy_type(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
585 {
586 	struct cil_type *orig = data;
587 	char *key = orig->datum.name;
588 	struct cil_symtab_datum *datum = NULL;
589 
590 	cil_symtab_get_datum(symtab, key, &datum);
591 	if (datum == NULL) {
592 		struct cil_type *new;
593 		cil_type_init(&new);
594 		*copy = new;
595 	} else {
596 		*copy = datum;
597 	}
598 
599 	return SEPOL_OK;
600 }
601 
cil_copy_typepermissive(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)602 int cil_copy_typepermissive(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
603 {
604 	struct cil_typepermissive *orig = data;
605 	struct cil_typepermissive *new = NULL;
606 
607 	cil_typepermissive_init(&new);
608 
609 	new->type_str = orig->type_str;
610 
611 	*copy = new;
612 
613 	return SEPOL_OK;
614 }
615 
cil_copy_typeattribute(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)616 int cil_copy_typeattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
617 {
618 	struct cil_typeattribute *orig = data;
619 	char *key = orig->datum.name;
620 	struct cil_symtab_datum *datum = NULL;
621 
622 	cil_symtab_get_datum(symtab, key, &datum);
623 	if (datum == NULL) {
624 		struct cil_typeattribute *new;
625 		cil_typeattribute_init(&new);
626 		*copy = new;
627 	} else {
628 		*copy = datum;
629 	}
630 
631 	return SEPOL_OK;
632 }
633 
cil_copy_typeattributeset(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)634 int cil_copy_typeattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
635 {
636 	struct cil_typeattributeset *orig = data;
637 	struct cil_typeattributeset *new = NULL;
638 
639 	cil_typeattributeset_init(&new);
640 
641 	new->attr_str = orig->attr_str;
642 
643 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
644 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
645 
646 	*copy = new;
647 
648 	return SEPOL_OK;
649 }
650 
cil_copy_expandtypeattribute(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)651 int cil_copy_expandtypeattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
652 {
653 	struct cil_expandtypeattribute *orig = data;
654 	struct cil_expandtypeattribute *new = NULL;
655 
656 	fprintf(stderr, "%s %u\n", __func__, __LINE__);
657 	cil_expandtypeattribute_init(&new);
658 
659 	if (orig->attr_strs != NULL) {
660 		cil_copy_list(orig->attr_strs, &new->attr_strs);
661 	}
662 
663 	if (orig->attr_datums != NULL) {
664 		cil_copy_list(orig->attr_datums, &new->attr_datums);
665 	}
666 
667 	new->expand = orig->expand;
668 
669 	*copy = new;
670 
671 	return SEPOL_OK;
672 }
673 
cil_copy_alias(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)674 int cil_copy_alias(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
675 {
676 	struct cil_alias *orig = data;
677 	struct cil_alias *new = NULL;
678 	char *key = orig->datum.name;
679 	struct cil_symtab_datum *datum = NULL;
680 
681 	cil_symtab_get_datum(symtab, key, &datum);
682 	if (datum != NULL) {
683 		cil_log(CIL_INFO, "cil_copy_alias: alias cannot be redefined\n");
684 		return SEPOL_ERR;
685 	}
686 
687 	cil_alias_init(&new);
688 
689 	*copy = new;
690 
691 	return SEPOL_OK;
692 }
693 
cil_copy_aliasactual(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)694 int cil_copy_aliasactual(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused))symtab_t *symtab)
695 {
696 	struct cil_aliasactual *orig = data;
697 	struct cil_aliasactual *new = NULL;
698 
699 	cil_aliasactual_init(&new);
700 
701 	new->alias_str = orig->alias_str;
702 	new->actual_str = orig->actual_str;
703 
704 	*copy = new;
705 
706 	return SEPOL_OK;
707 }
708 
cil_copy_roletransition(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)709 int cil_copy_roletransition(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
710 {
711 	struct cil_roletransition *orig = data;
712 	struct cil_roletransition *new = NULL;
713 
714 	cil_roletransition_init(&new);
715 
716 	new->src_str = orig->src_str;
717 	new->tgt_str = orig->tgt_str;
718 	new->obj_str = orig->obj_str;
719 	new->result_str = orig->result_str;
720 
721 	*copy = new;
722 
723 	return SEPOL_OK;
724 }
725 
cil_copy_nametypetransition(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)726 int cil_copy_nametypetransition(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
727 {
728 	struct cil_nametypetransition *orig = data;
729 	struct cil_nametypetransition *new = NULL;
730 
731 	cil_nametypetransition_init(&new);
732 
733 	new->src_str = orig->src_str;
734 	new->tgt_str = orig->tgt_str;
735 	new->obj_str = orig->obj_str;
736 	new->name_str = orig->name_str;
737 	new->result_str = orig->result_str;
738 
739 
740 	*copy = new;
741 
742 	return SEPOL_OK;
743 }
744 
cil_copy_rangetransition(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)745 int cil_copy_rangetransition(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
746 {
747 	struct cil_rangetransition *orig = data;
748 	struct cil_rangetransition *new = NULL;
749 
750 	cil_rangetransition_init(&new);
751 
752 	new->src_str = orig->src_str;
753 	new->exec_str = orig->exec_str;
754 	new->obj_str = orig->obj_str;
755 
756 	if (orig->range_str != NULL) {
757 		new->range_str = orig->range_str;
758 	} else {
759 		cil_levelrange_init(&new->range);
760 		cil_copy_fill_levelrange(db, orig->range, new->range);
761 	}
762 
763 	*copy = new;
764 
765 	return SEPOL_OK;
766 }
767 
cil_copy_bool(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)768 int cil_copy_bool(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
769 {
770 	struct cil_bool *orig = data;
771 	struct cil_bool *new = NULL;
772 	char *key = orig->datum.name;
773 	struct cil_symtab_datum *datum = NULL;
774 
775 	cil_symtab_get_datum(symtab, key, &datum);
776 	if (datum != NULL) {
777 		cil_log(CIL_INFO, "cil_copy_bool: boolean cannot be redefined\n");
778 		return SEPOL_ERR;
779 	}
780 
781 	cil_bool_init(&new);
782 	new->value = orig->value;
783 	*copy = new;
784 
785 	return SEPOL_OK;
786 }
787 
cil_copy_tunable(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)788 int cil_copy_tunable(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
789 {
790 	struct cil_tunable *orig = data;
791 	struct cil_tunable *new = NULL;
792 	char *key = orig->datum.name;
793 	struct cil_symtab_datum *datum = NULL;
794 
795 	cil_symtab_get_datum(symtab, key, &datum);
796 	if (datum != NULL) {
797 		cil_log(CIL_INFO, "cil_copy_tunable: tunable cannot be redefined\n");
798 		return SEPOL_ERR;
799 	}
800 
801 	cil_tunable_init(&new);
802 	new->value = orig->value;
803 	*copy = new;
804 
805 	return SEPOL_OK;
806 }
807 
cil_copy_fill_permissionx(struct cil_db * db,struct cil_permissionx * orig,struct cil_permissionx * new)808 void cil_copy_fill_permissionx(struct cil_db *db, struct cil_permissionx *orig, struct cil_permissionx *new)
809 {
810 	new->kind = orig->kind;
811 	new->obj_str = orig->obj_str;
812 	cil_copy_expr(db, orig->expr_str, &new->expr_str);
813 }
814 
cil_copy_avrule(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)815 int cil_copy_avrule(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
816 {
817 	struct cil_avrule *orig = data;
818 	struct cil_avrule *new = NULL;
819 
820 	cil_avrule_init(&new);
821 
822 	new->is_extended = orig->is_extended;
823 	new->rule_kind = orig->rule_kind;
824 	new->src_str = orig->src_str;
825 	new->tgt_str = orig->tgt_str;
826 
827 	if (!new->is_extended) {
828 		cil_copy_classperms_list(orig->perms.classperms, &new->perms.classperms);
829 	} else {
830 		if (orig->perms.x.permx_str != NULL) {
831 			new->perms.x.permx_str = orig->perms.x.permx_str;
832 		} else {
833 			cil_permissionx_init(&new->perms.x.permx);
834 			cil_copy_fill_permissionx(db, orig->perms.x.permx, new->perms.x.permx);
835 		}
836 	}
837 
838 	*copy = new;
839 
840 	return SEPOL_OK;
841 }
842 
cil_copy_permissionx(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)843 int cil_copy_permissionx(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
844 {
845 	struct cil_permissionx *orig = data;
846 	struct cil_permissionx *new = NULL;
847 	char *key = orig->datum.name;
848 	struct cil_symtab_datum *datum = NULL;
849 
850 
851 	cil_symtab_get_datum(symtab, key, &datum);
852 	if (datum != NULL) {
853 		cil_log(CIL_INFO, "cil_copy_permissionx: permissionx cannot be redefined\n");
854 		return SEPOL_ERR;
855 	}
856 
857 	cil_permissionx_init(&new);
858 	cil_copy_fill_permissionx(db, orig, new);
859 
860 	*copy = new;
861 
862 	return SEPOL_OK;
863 }
864 
cil_copy_type_rule(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)865 int cil_copy_type_rule(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
866 {
867 	struct cil_type_rule  *orig = data;
868 	struct cil_type_rule *new = NULL;
869 
870 	cil_type_rule_init(&new);
871 
872 	new->rule_kind = orig->rule_kind;
873 	new->src_str = orig->src_str;
874 	new->tgt_str = orig->tgt_str;
875 	new->obj_str = orig->obj_str;
876 	new->result_str = orig->result_str;
877 
878 	*copy = new;
879 
880 	return SEPOL_OK;
881 }
882 
cil_copy_sens(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)883 int cil_copy_sens(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
884 {
885 	struct cil_sens *orig = data;
886 	char *key = orig->datum.name;
887 	struct cil_symtab_datum *datum = NULL;
888 
889 	cil_symtab_get_datum(symtab, key, &datum);
890 	if (datum == NULL) {
891 		struct cil_sens *new;
892 		cil_sens_init(&new);
893 		*copy = new;
894 	} else {
895 		*copy = datum;
896 	}
897 
898 	return SEPOL_OK;
899 }
900 
cil_copy_cat(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)901 int cil_copy_cat(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
902 {
903 	struct cil_cat *orig = data;
904 	char *key = orig->datum.name;
905 	struct cil_symtab_datum *datum = NULL;
906 
907 	cil_symtab_get_datum(symtab, key, &datum);
908 	if (datum == NULL) {
909 		struct cil_cat *new;
910 		cil_cat_init(&new);
911 		*copy = new;
912 	} else {
913 		*copy = datum;
914 	}
915 
916 	return SEPOL_OK;
917 }
918 
cil_copy_cats(struct cil_db * db,struct cil_cats * orig,struct cil_cats ** new)919 void cil_copy_cats(struct cil_db *db, struct cil_cats *orig, struct cil_cats **new)
920 {
921 	cil_cats_init(new);
922 	cil_copy_expr(db, orig->str_expr, &(*new)->str_expr);
923 	cil_copy_expr(db, orig->datum_expr, &(*new)->datum_expr);
924 }
925 
cil_copy_catset(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)926 int cil_copy_catset(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
927 {
928 	struct cil_catset *orig = data;
929 	struct cil_catset *new = NULL;
930 	char *key = orig->datum.name;
931 	struct cil_symtab_datum *datum = NULL;
932 
933 	cil_symtab_get_datum(symtab, key, &datum);
934 	if (datum != NULL) {
935 		cil_log(CIL_INFO, "cil_copy_catset: categoryset cannot be redefined\n");
936 		return SEPOL_ERR;
937 	}
938 
939 	cil_catset_init(&new);
940 
941 	cil_copy_cats(db, orig->cats, &new->cats);
942 
943 	*copy = new;
944 
945 	return SEPOL_OK;
946 }
947 
cil_copy_senscat(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)948 int cil_copy_senscat(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
949 {
950 	struct cil_senscat *orig = data;
951 	struct cil_senscat *new = NULL;
952 
953 	cil_senscat_init(&new);
954 
955 	new->sens_str = orig->sens_str;
956 
957 	cil_copy_cats(db, orig->cats, &new->cats);
958 
959 	*copy = new;
960 
961 	return SEPOL_OK;
962 }
963 
cil_copy_catorder(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)964 int cil_copy_catorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
965 {
966 	struct cil_catorder *orig = data;
967 	struct cil_catorder *new = NULL;
968 
969 	cil_catorder_init(&new);
970 	if (orig->cat_list_str != NULL) {
971 		cil_copy_list(orig->cat_list_str, &new->cat_list_str);
972 	}
973 
974 	*copy = new;
975 
976 	return SEPOL_OK;
977 }
978 
cil_copy_sensitivityorder(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)979 int cil_copy_sensitivityorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
980 {
981 	struct cil_sensorder *orig = data;
982 	struct cil_sensorder *new = NULL;
983 
984 	cil_sensorder_init(&new);
985 	if (orig->sens_list_str != NULL) {
986 		cil_copy_list(orig->sens_list_str, &new->sens_list_str);
987 	}
988 
989 	*copy = new;
990 
991 	return SEPOL_OK;
992 }
993 
cil_copy_fill_level(struct cil_db * db,struct cil_level * orig,struct cil_level ** new)994 void cil_copy_fill_level(struct cil_db *db, struct cil_level *orig, struct cil_level **new)
995 {
996 	cil_level_init(new);
997 
998 	(*new)->sens_str = orig->sens_str;
999 
1000 	if (orig->cats != NULL) {
1001 		cil_copy_cats(db, orig->cats, &(*new)->cats);
1002 	}
1003 }
1004 
cil_copy_level(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1005 int cil_copy_level(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1006 {
1007 	struct cil_level *orig = data;
1008 	struct cil_level *new = NULL;
1009 	char *key = orig->datum.name;
1010 	struct cil_symtab_datum *datum = NULL;
1011 
1012 	if (key != NULL) {
1013 		cil_symtab_get_datum(symtab, key, &datum);
1014 		if (datum != NULL) {
1015 			cil_log(CIL_INFO, "cil_copy_level: level cannot be redefined\n");
1016 			return SEPOL_ERR;
1017 		}
1018 	}
1019 
1020 	cil_copy_fill_level(db, orig, &new);
1021 
1022 	*copy = new;
1023 
1024 	return SEPOL_OK;
1025 }
1026 
cil_copy_fill_levelrange(struct cil_db * db,struct cil_levelrange * data,struct cil_levelrange * new)1027 void cil_copy_fill_levelrange(struct cil_db *db, struct cil_levelrange *data, struct cil_levelrange *new)
1028 {
1029 	if (data->low_str != NULL) {
1030 		new->low_str = data->low_str;
1031 	} else {
1032 		cil_copy_fill_level(db, data->low, &new->low);
1033 	}
1034 
1035 	if (data->high_str != NULL) {
1036 		new->high_str = data->high_str;
1037 	} else {
1038 		cil_copy_fill_level(db, data->high, &new->high);
1039 	}
1040 }
1041 
cil_copy_levelrange(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1042 int cil_copy_levelrange(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1043 {
1044 	struct cil_levelrange *orig = data;
1045 	struct cil_levelrange *new = NULL;
1046 	char *key = orig->datum.name;
1047 	struct cil_symtab_datum *datum = NULL;
1048 
1049 	if (key != NULL) {
1050 		cil_symtab_get_datum(symtab, key, &datum);
1051 		if (datum != NULL) {
1052 			cil_log(CIL_INFO, "cil_copy_levelrange: levelrange cannot be redefined\n");
1053 			return SEPOL_ERR;
1054 		}
1055 	}
1056 
1057 	cil_levelrange_init(&new);
1058 	cil_copy_fill_levelrange(db, orig, new);
1059 
1060 	*copy = new;
1061 
1062 	return SEPOL_OK;
1063 }
1064 
cil_copy_fill_context(struct cil_db * db,struct cil_context * data,struct cil_context * new)1065 void cil_copy_fill_context(struct cil_db *db, struct cil_context *data, struct cil_context *new)
1066 {
1067 	new->user_str = data->user_str;
1068 	new->role_str = data->role_str;
1069 	new->type_str = data->type_str;
1070 
1071 	if (data->range_str != NULL) {
1072 		new->range_str = data->range_str;
1073 	} else {
1074 		cil_levelrange_init(&new->range);
1075 		cil_copy_fill_levelrange(db, data->range, new->range);
1076 	}
1077 }
1078 
cil_copy_context(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1079 int cil_copy_context(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1080 {
1081 	struct cil_context *orig = data;
1082 	struct cil_context *new = NULL;
1083 	char *key = orig->datum.name;
1084 	struct cil_symtab_datum *datum = NULL;
1085 
1086 	if (key != NULL) {
1087 		cil_symtab_get_datum(symtab, key, &datum);
1088 		if (datum != NULL) {
1089 			cil_log(CIL_INFO, "cil_copy_context: context cannot be redefined\n");
1090 			return SEPOL_ERR;
1091 		}
1092 	}
1093 
1094 	cil_context_init(&new);
1095 	cil_copy_fill_context(db, orig, new);
1096 
1097 	*copy = new;
1098 
1099 	return SEPOL_OK;
1100 }
1101 
cil_copy_netifcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1102 int cil_copy_netifcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1103 {
1104 	struct cil_netifcon *orig = data;
1105 	struct cil_netifcon *new = NULL;
1106 
1107 	cil_netifcon_init(&new);
1108 
1109 	new->interface_str = orig->interface_str;
1110 
1111 	if (orig->if_context_str != NULL) {
1112 		new->if_context_str = orig->if_context_str;
1113 	} else {
1114 		cil_context_init(&new->if_context);
1115 		cil_copy_fill_context(db, orig->if_context, new->if_context);
1116 	}
1117 
1118 	if (orig->packet_context_str != NULL) {
1119 		new->packet_context_str = orig->packet_context_str;
1120 	} else {
1121 		cil_context_init(&new->packet_context);
1122 		cil_copy_fill_context(db, orig->packet_context, new->packet_context);
1123 	}
1124 
1125 	*copy = new;
1126 
1127 	return SEPOL_OK;
1128 }
1129 
cil_copy_genfscon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1130 int cil_copy_genfscon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1131 {
1132 	struct cil_genfscon *orig = data;
1133 	struct cil_genfscon *new = NULL;
1134 
1135 	cil_genfscon_init(&new);
1136 
1137 	new->fs_str = orig->fs_str;
1138 	new->path_str = orig->path_str;
1139 
1140 	if (orig->context_str != NULL) {
1141 		new->context_str = orig->context_str;
1142 	} else {
1143 		cil_context_init(&new->context);
1144 		cil_copy_fill_context(db, orig->context, new->context);
1145 	}
1146 
1147 	*copy = new;
1148 
1149 	return SEPOL_OK;
1150 }
1151 
cil_copy_filecon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1152 int cil_copy_filecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1153 {
1154 	struct cil_filecon *orig = data;
1155 	struct cil_filecon *new = NULL;
1156 
1157 	cil_filecon_init(&new);
1158 
1159 	new->path_str = orig->path_str;
1160 	new->type = orig->type;
1161 
1162 	if (orig->context_str != NULL) {
1163 		new->context_str = orig->context_str;
1164 	} else if (orig->context != NULL) {
1165 		cil_context_init(&new->context);
1166 		cil_copy_fill_context(db, orig->context, new->context);
1167 	}
1168 
1169 	*copy = new;
1170 
1171 	return SEPOL_OK;
1172 }
1173 
cil_copy_nodecon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1174 int cil_copy_nodecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1175 {
1176 	struct cil_nodecon *orig = data;
1177 	struct cil_nodecon *new = NULL;
1178 
1179 	cil_nodecon_init(&new);
1180 
1181 	if (orig->addr_str != NULL) {
1182 		new->addr_str = orig->addr_str;
1183 	} else {
1184 		cil_ipaddr_init(&new->addr);
1185 		cil_copy_fill_ipaddr(orig->addr, new->addr);
1186 	}
1187 
1188 	if (orig->mask_str != NULL) {
1189 		new->mask_str = orig->mask_str;
1190 	} else {
1191 		cil_ipaddr_init(&new->mask);
1192 		cil_copy_fill_ipaddr(orig->mask, new->mask);
1193 	}
1194 
1195 	if (orig->context_str != NULL) {
1196 		new->context_str = orig->context_str;
1197 	} else {
1198 		cil_context_init(&new->context);
1199 		cil_copy_fill_context(db, orig->context, new->context);
1200 	}
1201 
1202 	*copy = new;
1203 
1204 	return SEPOL_OK;
1205 }
1206 
cil_copy_ibpkeycon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1207 int cil_copy_ibpkeycon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1208 {
1209 	struct cil_ibpkeycon *orig = data;
1210 	struct cil_ibpkeycon *new = NULL;
1211 
1212 	cil_ibpkeycon_init(&new);
1213 
1214 	new->subnet_prefix_str = orig->subnet_prefix_str;
1215 	new->pkey_low = orig->pkey_low;
1216 	new->pkey_high = orig->pkey_high;
1217 
1218 	if (orig->context_str) {
1219 		new->context_str = orig->context_str;
1220 	} else {
1221 		cil_context_init(&new->context);
1222 		cil_copy_fill_context(db, orig->context, new->context);
1223 	}
1224 
1225 	*copy = new;
1226 
1227 	return SEPOL_OK;
1228 }
1229 
cil_copy_ibendportcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1230 int cil_copy_ibendportcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1231 {
1232 	struct cil_ibendportcon *orig = data;
1233 	struct cil_ibendportcon *new = NULL;
1234 
1235 	cil_ibendportcon_init(&new);
1236 
1237 	new->dev_name_str = orig->dev_name_str;
1238 	new->port = orig->port;
1239 
1240 	if (orig->context_str) {
1241 		new->context_str = orig->context_str;
1242 	} else {
1243 		cil_context_init(&new->context);
1244 		cil_copy_fill_context(db, orig->context, new->context);
1245 	}
1246 
1247 	*copy = new;
1248 
1249 	return SEPOL_OK;
1250 }
1251 
cil_copy_portcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1252 int cil_copy_portcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1253 {
1254 	struct cil_portcon *orig = data;
1255 	struct cil_portcon *new = NULL;
1256 
1257 	cil_portcon_init(&new);
1258 
1259 	new->proto = orig->proto;
1260 	new->port_low = orig->port_low;
1261 	new->port_high = orig->port_high;
1262 
1263 	if (orig->context_str != NULL) {
1264 		new->context_str = orig->context_str;
1265 	} else {
1266 		cil_context_init(&new->context);
1267 		cil_copy_fill_context(db, orig->context, new->context);
1268 	}
1269 
1270 	*copy = new;
1271 
1272 	return SEPOL_OK;
1273 }
1274 
cil_copy_pirqcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1275 int cil_copy_pirqcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1276 {
1277 	struct cil_pirqcon *orig = data;
1278 	struct cil_pirqcon *new = NULL;
1279 
1280 	cil_pirqcon_init(&new);
1281 
1282 	new->pirq = orig->pirq;
1283 
1284 	if (orig->context_str != NULL) {
1285 		new->context_str = orig->context_str;
1286 	} else {
1287 		cil_context_init(&new->context);
1288 		cil_copy_fill_context(db, orig->context, new->context);
1289 	}
1290 
1291 	*copy = new;
1292 
1293 	return SEPOL_OK;
1294 }
1295 
cil_copy_iomemcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1296 int cil_copy_iomemcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1297 {
1298 	struct cil_iomemcon *orig = data;
1299 	struct cil_iomemcon *new = NULL;
1300 
1301 	cil_iomemcon_init(&new);
1302 
1303 	new->iomem_low = orig->iomem_low;
1304 	new->iomem_high = orig->iomem_high;
1305 
1306 	if (orig->context_str != NULL) {
1307 		new->context_str = orig->context_str;
1308 	} else {
1309 		cil_context_init(&new->context);
1310 		cil_copy_fill_context(db, orig->context, new->context);
1311 	}
1312 
1313 	*copy = new;
1314 
1315 	return SEPOL_OK;
1316 }
1317 
cil_copy_ioportcon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1318 int cil_copy_ioportcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1319 {
1320 	struct cil_ioportcon *orig = data;
1321 	struct cil_ioportcon *new = NULL;
1322 
1323 	cil_ioportcon_init(&new);
1324 
1325 	new->ioport_low = orig->ioport_low;
1326 	new->ioport_high = orig->ioport_high;
1327 
1328 	if (orig->context_str != NULL) {
1329 		new->context_str = orig->context_str;
1330 	} else {
1331 		cil_context_init(&new->context);
1332 		cil_copy_fill_context(db, orig->context, new->context);
1333 	}
1334 
1335 	*copy = new;
1336 
1337 	return SEPOL_OK;
1338 }
1339 
cil_copy_pcidevicecon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1340 int cil_copy_pcidevicecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1341 {
1342 	struct cil_pcidevicecon *orig = data;
1343 	struct cil_pcidevicecon *new = NULL;
1344 
1345 	cil_pcidevicecon_init(&new);
1346 
1347 	new->dev = orig->dev;
1348 
1349 	if (orig->context_str != NULL) {
1350 		new->context_str = orig->context_str;
1351 	} else {
1352 		cil_context_init(&new->context);
1353 		cil_copy_fill_context(db, orig->context, new->context);
1354 	}
1355 
1356 	*copy = new;
1357 
1358 	return SEPOL_OK;
1359 }
1360 
cil_copy_devicetreecon(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1361 int cil_copy_devicetreecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1362 {
1363 	struct cil_devicetreecon *orig = data;
1364 	struct cil_devicetreecon *new = NULL;
1365 
1366 	cil_devicetreecon_init(&new);
1367 
1368 	new->path = orig->path;
1369 
1370 	if (orig->context_str != NULL) {
1371 		new->context_str = orig->context_str;
1372 	} else {
1373 		cil_context_init(&new->context);
1374 		cil_copy_fill_context(db, orig->context, new->context);
1375 	}
1376 
1377 	*copy = new;
1378 
1379 	return SEPOL_OK;
1380 }
1381 
cil_copy_fsuse(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1382 int cil_copy_fsuse(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1383 {
1384 	struct cil_fsuse *orig = data;
1385 	struct cil_fsuse *new = NULL;
1386 
1387 	cil_fsuse_init(&new);
1388 
1389 	new->type = orig->type;
1390 	new->fs_str = orig->fs_str;
1391 
1392 	if (orig->context_str != NULL) {
1393 		new->context_str = orig->context_str;
1394 	} else {
1395 		cil_context_init(&new->context);
1396 		cil_copy_fill_context(db, orig->context, new->context);
1397 	}
1398 
1399 	*copy = new;
1400 
1401 	return SEPOL_OK;
1402 }
1403 
cil_copy_expr(struct cil_db * db,struct cil_list * orig,struct cil_list ** new)1404 int cil_copy_expr(struct cil_db *db, struct cil_list *orig, struct cil_list **new)
1405 {
1406 	struct cil_list_item *curr;
1407 
1408 	if (orig == NULL) {
1409 		*new = NULL;
1410 		return SEPOL_OK;
1411 	}
1412 
1413 	cil_list_init(new, orig->flavor);
1414 
1415 	cil_list_for_each(curr, orig) {
1416 		switch (curr->flavor) {
1417 		case CIL_LIST: {
1418 			struct cil_list *sub_list;
1419 			cil_copy_expr(db, curr->data, &sub_list);
1420 			cil_list_append(*new, CIL_LIST, sub_list);
1421 			break;
1422 		}
1423 		case CIL_STRING:
1424 			cil_list_append(*new, CIL_STRING, curr->data);
1425 			break;
1426 		case CIL_DATUM:
1427 			cil_list_append(*new, curr->flavor, curr->data);
1428 			break;
1429 		case CIL_OP:
1430 			cil_list_append(*new, curr->flavor, curr->data);
1431 			break;
1432 		case CIL_CONS_OPERAND:
1433 			cil_list_append(*new, curr->flavor, curr->data);
1434 			break;
1435 		default:
1436 			cil_log(CIL_INFO, "Unknown flavor %d in expression being copied\n",curr->flavor);
1437 			cil_list_append(*new, curr->flavor, curr->data);
1438 			break;
1439 		}
1440 	}
1441 
1442 	return SEPOL_OK;
1443 }
1444 
cil_copy_constrain(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1445 int cil_copy_constrain(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1446 {
1447 	struct cil_constrain *orig = data;
1448 	struct cil_constrain *new = NULL;
1449 
1450 	cil_constrain_init(&new);
1451 	cil_copy_classperms_list(orig->classperms, &new->classperms);
1452 
1453 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1454 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1455 
1456 	*copy = new;
1457 
1458 	return SEPOL_OK;
1459 }
1460 
cil_copy_validatetrans(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1461 int cil_copy_validatetrans(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1462 {
1463 	struct cil_validatetrans *orig = data;
1464 	struct cil_validatetrans *new = NULL;
1465 
1466 	cil_validatetrans_init(&new);
1467 
1468 	new->class_str = orig->class_str;
1469 
1470 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1471 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1472 
1473 	*copy = new;
1474 
1475 	return SEPOL_OK;
1476 }
1477 
cil_copy_call(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1478 int cil_copy_call(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1479 {
1480 	struct cil_call *orig = data;
1481 	struct cil_call *new = NULL;
1482 	int rc = SEPOL_ERR;
1483 
1484 	cil_call_init(&new);
1485 
1486 	new->macro_str = orig->macro_str;
1487 	new->macro = orig->macro;
1488 
1489 	if (orig->args_tree != NULL) {
1490 		cil_tree_init(&new->args_tree);
1491 		rc = cil_copy_ast(db, orig->args_tree->root, new->args_tree->root);
1492 		if (rc != SEPOL_OK) {
1493 			goto exit;
1494 		}
1495 	}
1496 
1497 	new->copied = orig->copied;
1498 
1499 	*copy = new;
1500 
1501 	return SEPOL_OK;
1502 
1503 exit:
1504 	cil_destroy_call(new);
1505 	return rc;
1506 }
1507 
cil_copy_macro(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1508 int cil_copy_macro(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1509 {
1510 	struct cil_macro *orig = data;
1511 	char *key = orig->datum.name;
1512 	struct cil_symtab_datum *datum = NULL;
1513 
1514 	cil_symtab_get_datum(symtab, key, &datum);
1515 	if (datum == NULL) {
1516 		struct cil_macro *new;
1517 		cil_macro_init(&new);
1518 		if (orig->params != NULL) {
1519 			cil_copy_list(orig->params, &new->params);
1520 		}
1521 
1522 		*copy = new;
1523 
1524 	} else {
1525 		struct cil_list_item *curr_orig = NULL;
1526 		struct cil_list_item *curr_new = NULL;
1527 		struct cil_param *param_orig = NULL;
1528 		struct cil_param *param_new = NULL;
1529 
1530 		if (((struct cil_macro*)datum)->params != NULL) {
1531 			curr_new = ((struct cil_macro*)datum)->params->head;
1532 		}
1533 
1534 		if (orig->params != NULL) {
1535 			curr_orig = orig->params->head;
1536 		}
1537 
1538 		if (curr_orig != NULL && curr_new != NULL) {
1539 			while (curr_orig != NULL) {
1540 				if (curr_new == NULL) {
1541 					goto exit;
1542 				}
1543 
1544 				param_orig = (struct cil_param*)curr_orig->data;
1545 				param_new = (struct cil_param*)curr_new->data;
1546 				if (param_orig->str != param_new->str) {
1547 					goto exit;
1548 				} else if (param_orig->flavor != param_new->flavor) {
1549 					goto exit;
1550 				}
1551 
1552 				curr_orig = curr_orig->next;
1553 				curr_new = curr_new->next;
1554 			}
1555 
1556 			if (curr_new != NULL) {
1557 				goto exit;
1558 			}
1559 		} else if (!(curr_orig == NULL && curr_new == NULL)) {
1560 			goto exit;
1561 		}
1562 
1563 		*copy = datum;
1564 	}
1565 
1566 	return SEPOL_OK;
1567 
1568 exit:
1569 	cil_log(CIL_INFO, "cil_copy_macro: macro cannot be redefined\n");
1570 	return SEPOL_ERR;
1571 }
1572 
cil_copy_optional(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1573 int cil_copy_optional(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1574 {
1575 	struct cil_optional *orig = data;
1576 	char *key = orig->datum.name;
1577 	struct cil_symtab_datum *datum = NULL;
1578 
1579 	cil_symtab_get_datum(symtab, key, &datum);
1580 	if (datum == NULL) {
1581 		struct cil_optional *new;
1582 		cil_optional_init(&new);
1583 		*copy = new;
1584 	} else {
1585 		*copy = datum;
1586 	}
1587 
1588 	return SEPOL_OK;
1589 }
1590 
cil_copy_fill_ipaddr(struct cil_ipaddr * data,struct cil_ipaddr * new)1591 void cil_copy_fill_ipaddr(struct cil_ipaddr *data, struct cil_ipaddr *new)
1592 {
1593 	new->family = data->family;
1594 	memcpy(&new->ip, &data->ip, sizeof(data->ip));
1595 }
1596 
cil_copy_ipaddr(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1597 int cil_copy_ipaddr(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1598 {
1599 	struct cil_ipaddr *orig = data;
1600 	struct cil_ipaddr *new = NULL;
1601 	char * key = orig->datum.name;
1602 	struct cil_symtab_datum *datum = NULL;
1603 
1604 	cil_symtab_get_datum(symtab, key, &datum);
1605 	if (datum != NULL) {
1606 		cil_log(CIL_INFO, "cil_copy_ipaddr: ipaddress cannot be redefined\n");
1607 		return SEPOL_ERR;
1608 	}
1609 
1610 	cil_ipaddr_init(&new);
1611 	cil_copy_fill_ipaddr(orig, new);
1612 
1613 	*copy = new;
1614 
1615 	return SEPOL_OK;
1616 }
1617 
cil_copy_condblock(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1618 int cil_copy_condblock(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1619 {
1620 	struct cil_condblock *orig = data;
1621 	struct cil_condblock *new = *copy;
1622 	cil_condblock_init(&new);
1623 	new->flavor = orig->flavor;
1624 	*copy = new;
1625 
1626 	return SEPOL_OK;
1627 }
1628 
cil_copy_boolif(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1629 int cil_copy_boolif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1630 {
1631 	struct cil_booleanif *orig = data;
1632 	struct cil_booleanif *new = NULL;
1633 
1634 	cil_boolif_init(&new);
1635 
1636 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1637 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1638 	new->preserved_tunable = orig->preserved_tunable;
1639 
1640 	*copy = new;
1641 
1642 	return SEPOL_OK;
1643 }
1644 
cil_copy_tunif(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1645 int cil_copy_tunif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1646 {
1647 	struct cil_tunableif *orig = data;
1648 	struct cil_tunableif *new = NULL;
1649 
1650 	cil_tunif_init(&new);
1651 
1652 	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1653 	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1654 
1655 	*copy = new;
1656 
1657 	return SEPOL_OK;
1658 }
1659 
cil_copy_default(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1660 int cil_copy_default(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1661 {
1662 	struct cil_default *orig = data;
1663 	struct cil_default *new = NULL;
1664 
1665 	cil_default_init(&new);
1666 
1667 	new->flavor = orig->flavor;
1668 
1669 	if (orig->class_strs != NULL) {
1670 		cil_copy_list(orig->class_strs, &new->class_strs);
1671 	}
1672 
1673 	new->object = orig->object;
1674 
1675 	*copy = new;
1676 
1677 	return SEPOL_OK;
1678 }
1679 
cil_copy_defaultrange(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1680 int cil_copy_defaultrange(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1681 {
1682 	struct cil_defaultrange *orig = data;
1683 	struct cil_defaultrange *new = NULL;
1684 
1685 	cil_defaultrange_init(&new);
1686 
1687 	if (orig->class_strs != NULL) {
1688 		cil_copy_list(orig->class_strs, &new->class_strs);
1689 	}
1690 
1691 	new->object_range = orig->object_range;
1692 
1693 	*copy = new;
1694 
1695 	return SEPOL_OK;
1696 }
1697 
cil_copy_handleunknown(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1698 int cil_copy_handleunknown(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1699 {
1700 	struct cil_handleunknown *orig = data;
1701 	struct cil_handleunknown *new = NULL;
1702 
1703 	cil_handleunknown_init(&new);
1704 	new->handle_unknown = orig->handle_unknown;
1705 	*copy = new;
1706 
1707 	return SEPOL_OK;
1708 }
1709 
cil_copy_mls(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1710 int cil_copy_mls(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1711 {
1712 	struct cil_mls *orig = data;
1713 	struct cil_mls *new = NULL;
1714 
1715 	cil_mls_init(&new);
1716 	new->value = orig->value;
1717 	*copy = new;
1718 
1719 	return SEPOL_OK;
1720 }
1721 
cil_copy_bounds(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1722 int cil_copy_bounds(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1723 {
1724 	struct cil_bounds *orig = data;
1725 	struct cil_bounds *new = NULL;
1726 
1727 	cil_bounds_init(&new);
1728 
1729 	new->parent_str = orig->parent_str;
1730 	new->child_str = orig->child_str;
1731 
1732 	*copy = new;
1733 
1734 	return SEPOL_OK;
1735 }
1736 
cil_copy_src_info(struct cil_db * db,void * data,void ** copy,symtab_t * symtab)1737 int cil_copy_src_info(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1738 {
1739 	struct cil_src_info *orig = data;
1740 	struct cil_src_info *new = NULL;
1741 
1742 	cil_src_info_init(&new);
1743 
1744 	new->is_cil = orig->is_cil;
1745 	new->path = orig->path;
1746 
1747 	*copy = new;
1748 
1749 	return SEPOL_OK;
1750 }
1751 
__cil_copy_node_helper(struct cil_tree_node * orig,uint32_t * finished,void * extra_args)1752 int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) uint32_t *finished, void *extra_args)
1753 {
1754 	int rc = SEPOL_ERR;
1755 	struct cil_tree_node *parent = NULL;
1756 	struct cil_tree_node *new = NULL;
1757 	struct cil_db *db = NULL;
1758 	struct cil_args_copy *args = NULL;
1759 	struct cil_tree_node *namespace = NULL;
1760 	struct cil_param *param = NULL;
1761 	enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
1762 	symtab_t *symtab = NULL;
1763 	void *data = NULL;
1764 	int (*copy_func)(struct cil_db *db, void *data, void **copy, symtab_t *symtab) = NULL;
1765 	struct cil_blockinherit *blockinherit = NULL;
1766 
1767 	if (orig == NULL || extra_args == NULL) {
1768 		goto exit;
1769 	}
1770 
1771 	args = extra_args;
1772 	parent = args->dest;
1773 	db = args->db;
1774 
1775 
1776 	switch (orig->flavor) {
1777 	case CIL_BLOCK:
1778 		copy_func = &cil_copy_block;
1779 		break;
1780 	case CIL_BLOCKABSTRACT:
1781 		copy_func = &cil_copy_blockabstract;
1782 		break;
1783 	case CIL_BLOCKINHERIT:
1784 		copy_func = &cil_copy_blockinherit;
1785 		break;
1786 	case CIL_POLICYCAP:
1787 		copy_func = &cil_copy_policycap;
1788 		break;
1789 	case CIL_PERM:
1790 	case CIL_MAP_PERM:
1791 		copy_func = &cil_copy_perm;
1792 		break;
1793 	case CIL_CLASSMAPPING:
1794 		copy_func = &cil_copy_classmapping;
1795 		break;
1796 	case CIL_CLASS:
1797 	case CIL_COMMON:
1798 	case CIL_MAP_CLASS:
1799 		copy_func = &cil_copy_class;
1800 		break;
1801 	case CIL_CLASSORDER:
1802 		copy_func = &cil_copy_classorder;
1803 		break;
1804 	case CIL_CLASSPERMISSION:
1805 		copy_func = &cil_copy_classpermission;
1806 		break;
1807 	case CIL_CLASSPERMISSIONSET:
1808 		copy_func = &cil_copy_classpermissionset;
1809 		break;
1810 	case CIL_CLASSCOMMON:
1811 		copy_func = &cil_copy_classcommon;
1812 		break;
1813 	case CIL_SID:
1814 		copy_func = &cil_copy_sid;
1815 		break;
1816 	case CIL_SIDCONTEXT:
1817 		copy_func = &cil_copy_sidcontext;
1818 		break;
1819 	case CIL_SIDORDER:
1820 		copy_func = &cil_copy_sidorder;
1821 		break;
1822 	case CIL_USER:
1823 		copy_func = &cil_copy_user;
1824 		break;
1825 	case CIL_USERATTRIBUTE:
1826 		copy_func = &cil_copy_userattribute;
1827 		break;
1828 	case CIL_USERATTRIBUTESET:
1829 		copy_func = &cil_copy_userattributeset;
1830 		break;
1831 	case CIL_USERROLE:
1832 		copy_func = &cil_copy_userrole;
1833 		break;
1834 	case CIL_USERLEVEL:
1835 		copy_func = &cil_copy_userlevel;
1836 		break;
1837 	case CIL_USERRANGE:
1838 		copy_func = &cil_copy_userrange;
1839 		break;
1840 	case CIL_USERBOUNDS:
1841 		copy_func = &cil_copy_bounds;
1842 		break;
1843 	case CIL_USERPREFIX:
1844 		copy_func = &cil_copy_userprefix;
1845 		break;
1846 	case CIL_ROLE:
1847 		copy_func = &cil_copy_role;
1848 		break;
1849 	case CIL_ROLETYPE:
1850 		copy_func = &cil_copy_roletype;
1851 		break;
1852 	case CIL_ROLEBOUNDS:
1853 		copy_func = &cil_copy_bounds;
1854 		break;
1855 	case CIL_ROLEATTRIBUTE:
1856 		copy_func = &cil_copy_roleattribute;
1857 		break;
1858 	case CIL_ROLEATTRIBUTESET:
1859 		copy_func = &cil_copy_roleattributeset;
1860 		break;
1861 	case CIL_ROLEALLOW:
1862 		copy_func = &cil_copy_roleallow;
1863 		break;
1864 	case CIL_TYPE:
1865 		copy_func = &cil_copy_type;
1866 		break;
1867 	case CIL_TYPEBOUNDS:
1868 		copy_func = &cil_copy_bounds;
1869 		break;
1870 	case CIL_TYPEPERMISSIVE:
1871 		copy_func = cil_copy_typepermissive;
1872 		break;
1873 	case CIL_TYPEATTRIBUTE:
1874 		copy_func = &cil_copy_typeattribute;
1875 		break;
1876 	case CIL_TYPEATTRIBUTESET:
1877 		copy_func = &cil_copy_typeattributeset;
1878 		break;
1879 	case CIL_EXPANDTYPEATTRIBUTE:
1880 		copy_func = &cil_copy_expandtypeattribute;
1881 		break;
1882 	case CIL_TYPEALIAS:
1883 		copy_func = &cil_copy_alias;
1884 		break;
1885 	case CIL_TYPEALIASACTUAL:
1886 		copy_func = &cil_copy_aliasactual;
1887 		break;
1888 	case CIL_ROLETRANSITION:
1889 		copy_func = &cil_copy_roletransition;
1890 		break;
1891 	case CIL_NAMETYPETRANSITION:
1892 		copy_func = &cil_copy_nametypetransition;
1893 		break;
1894 	case CIL_RANGETRANSITION:
1895 		copy_func = &cil_copy_rangetransition;
1896 		break;
1897 	case CIL_TUNABLE:
1898 		copy_func = &cil_copy_tunable;
1899 		break;
1900 	case CIL_BOOL:
1901 		copy_func = &cil_copy_bool;
1902 		break;
1903 	case CIL_AVRULE:
1904 	case CIL_AVRULEX:
1905 		copy_func = &cil_copy_avrule;
1906 		break;
1907 	case CIL_PERMISSIONX:
1908 		copy_func = &cil_copy_permissionx;
1909 		break;
1910 	case CIL_TYPE_RULE:
1911 		copy_func = &cil_copy_type_rule;
1912 		break;
1913 	case CIL_SENS:
1914 		copy_func = &cil_copy_sens;
1915 		break;
1916 	case CIL_SENSALIAS:
1917 		copy_func = &cil_copy_alias;
1918 		break;
1919 	case CIL_SENSALIASACTUAL:
1920 		copy_func = &cil_copy_aliasactual;
1921 		break;
1922 	case CIL_CAT:
1923 		copy_func = &cil_copy_cat;
1924 		break;
1925 	case CIL_CATALIAS:
1926 		copy_func = &cil_copy_alias;
1927 		break;
1928 	case CIL_CATALIASACTUAL:
1929 		copy_func = &cil_copy_aliasactual;
1930 		break;
1931 	case CIL_CATSET:
1932 		copy_func = &cil_copy_catset;
1933 		break;
1934 	case CIL_SENSCAT:
1935 		copy_func = &cil_copy_senscat;
1936 		break;
1937 	case CIL_CATORDER:
1938 		copy_func = &cil_copy_catorder;
1939 		break;
1940 	case CIL_SENSITIVITYORDER:
1941 		copy_func = &cil_copy_sensitivityorder;
1942 		break;
1943 	case CIL_LEVEL:
1944 		copy_func = &cil_copy_level;
1945 		break;
1946 	case CIL_LEVELRANGE:
1947 		copy_func = &cil_copy_levelrange;
1948 		break;
1949 	case CIL_CONTEXT:
1950 		copy_func = &cil_copy_context;
1951 		break;
1952 	case CIL_NETIFCON:
1953 		copy_func = &cil_copy_netifcon;
1954 		break;
1955 	case CIL_GENFSCON:
1956 		copy_func = &cil_copy_genfscon;
1957 		break;
1958 	case CIL_FILECON:
1959 		copy_func = &cil_copy_filecon;
1960 		break;
1961 	case CIL_NODECON:
1962 		copy_func = &cil_copy_nodecon;
1963 		break;
1964 	case CIL_IBPKEYCON:
1965 		copy_func = &cil_copy_ibpkeycon;
1966 		break;
1967 	case CIL_IBENDPORTCON:
1968 		copy_func = &cil_copy_ibendportcon;
1969 		break;
1970 	case CIL_PORTCON:
1971 		copy_func = &cil_copy_portcon;
1972 		break;
1973 	case CIL_PIRQCON:
1974 		copy_func = &cil_copy_pirqcon;
1975 		break;
1976 	case CIL_IOMEMCON:
1977 		copy_func = &cil_copy_iomemcon;
1978 		break;
1979 	case CIL_IOPORTCON:
1980 		copy_func = &cil_copy_ioportcon;
1981 		break;
1982 	case CIL_PCIDEVICECON:
1983 		copy_func = &cil_copy_pcidevicecon;
1984 		break;
1985 	case CIL_DEVICETREECON:
1986 		copy_func = &cil_copy_devicetreecon;
1987 		break;
1988 	case CIL_FSUSE:
1989 		copy_func = &cil_copy_fsuse;
1990 		break;
1991 	case CIL_CONSTRAIN:
1992 	case CIL_MLSCONSTRAIN:
1993 		copy_func = &cil_copy_constrain;
1994 		break;
1995 	case CIL_VALIDATETRANS:
1996 	case CIL_MLSVALIDATETRANS:
1997 		copy_func = &cil_copy_validatetrans;
1998 		break;
1999 	case CIL_CALL:
2000 		copy_func = &cil_copy_call;
2001 		break;
2002 	case CIL_MACRO:
2003 		copy_func = &cil_copy_macro;
2004 		break;
2005 	case CIL_NODE:
2006 		copy_func = &cil_copy_node;
2007 		break;
2008 	case CIL_OPTIONAL:
2009 		copy_func = &cil_copy_optional;
2010 		break;
2011 	case CIL_IPADDR:
2012 		copy_func = &cil_copy_ipaddr;
2013 		break;
2014 	case CIL_CONDBLOCK:
2015 		copy_func = &cil_copy_condblock;
2016 		break;
2017 	case CIL_BOOLEANIF:
2018 		copy_func = &cil_copy_boolif;
2019 		break;
2020 	case CIL_TUNABLEIF:
2021 		copy_func = &cil_copy_tunif;
2022 		break;
2023 	case CIL_DEFAULTUSER:
2024 	case CIL_DEFAULTROLE:
2025 	case CIL_DEFAULTTYPE:
2026 		copy_func = &cil_copy_default;
2027 		break;
2028 	case CIL_DEFAULTRANGE:
2029 		copy_func = &cil_copy_defaultrange;
2030 		break;
2031 	case CIL_HANDLEUNKNOWN:
2032 		copy_func = &cil_copy_handleunknown;
2033 		break;
2034 	case CIL_MLS:
2035 		copy_func = &cil_copy_mls;
2036 		break;
2037 	case CIL_SRC_INFO:
2038 		copy_func = &cil_copy_src_info;
2039 		break;
2040 	default:
2041 		goto exit;
2042 	}
2043 
2044 	if (orig->flavor >= CIL_MIN_DECLARATIVE) {
2045 		rc = cil_flavor_to_symtab_index(orig->flavor, &sym_index);
2046 		if (rc != SEPOL_OK) {
2047 			goto exit;
2048 		}
2049 
2050 		rc = cil_get_symtab(parent, &symtab, sym_index);
2051 		if (rc != SEPOL_OK) {
2052 			goto exit;
2053 		}
2054 	}
2055 
2056 	rc = (*copy_func)(db, orig->data, &data, symtab);
2057 	if (rc == SEPOL_OK) {
2058 		cil_tree_node_init(&new);
2059 
2060 		new->parent = parent;
2061 		new->line = orig->line;
2062 		new->hll_line = orig->hll_line;
2063 		new->flavor = orig->flavor;
2064 		new->data = data;
2065 
2066 		if (orig->flavor >= CIL_MIN_DECLARATIVE) {
2067 			/* Check the flavor of data if was found in the destination symtab */
2068 			if (DATUM(data)->nodes->head && FLAVOR(data) != orig->flavor) {
2069 				cil_tree_log(orig, CIL_ERR, "Incompatible flavor when trying to copy %s", DATUM(data)->name);
2070 				cil_tree_log(NODE(data), CIL_ERR, "Note: conflicting declaration");
2071 				new->flavor = FLAVOR(data);
2072 				rc = SEPOL_ERR;
2073 				goto exit;
2074 			}
2075 			rc = cil_symtab_insert(symtab, ((struct cil_symtab_datum*)orig->data)->name, ((struct cil_symtab_datum*)data), new);
2076 
2077 			namespace = new;
2078 			while (namespace->flavor != CIL_MACRO && namespace->flavor != CIL_BLOCK && namespace->flavor != CIL_ROOT) {
2079 				namespace = namespace->parent;
2080 			}
2081 
2082 			if (namespace->flavor == CIL_MACRO) {
2083 				struct cil_macro *macro = namespace->data;
2084 				struct cil_list *param_list = macro->params;
2085 				if (param_list != NULL) {
2086 					struct cil_list_item *item;
2087 					cil_list_for_each(item, param_list) {
2088 						param = item->data;
2089 						if (param->flavor == new->flavor) {
2090 							if (param->str == ((struct cil_symtab_datum*)new->data)->name) {
2091 								cil_tree_log(orig, CIL_ERR, "%s %s shadows a macro parameter", cil_node_to_string(new), ((struct cil_symtab_datum*)orig->data)->name);
2092 								cil_tree_log(namespace, CIL_ERR, "Note: macro declaration");
2093 								rc = SEPOL_ERR;
2094 								goto exit;
2095 							}
2096 						}
2097 					}
2098 				}
2099 			}
2100 		}
2101 
2102 		if (new->flavor == CIL_BLOCKINHERIT) {
2103 			blockinherit = new->data;
2104 			// if a blockinherit statement is copied before blockinherit are
2105 			// resolved (like in an in-statement), the block will not have been
2106 			// resolved yet, so there's nothing to append yet. This is fine,
2107 			// the copied blockinherit statement will be handled later, as if
2108 			// it wasn't in an in-statement
2109 			if (blockinherit->block != NULL) {
2110 				cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new);
2111 			}
2112 		}
2113 
2114 		if (parent->cl_head == NULL) {
2115 			parent->cl_head = new;
2116 			parent->cl_tail = new;
2117 		} else {
2118 			parent->cl_tail->next = new;
2119 			parent->cl_tail = new;
2120 		}
2121 
2122 		if (orig->cl_head != NULL) {
2123 			args->dest = new;
2124 		}
2125 	} else {
2126 		goto exit;
2127 	}
2128 
2129 	return SEPOL_OK;
2130 
2131 exit:
2132 	cil_tree_node_destroy(&new);
2133 	return rc;
2134 }
2135 
__cil_copy_last_child_helper(struct cil_tree_node * orig,void * extra_args)2136 int __cil_copy_last_child_helper(__attribute__((unused)) struct cil_tree_node *orig, void *extra_args)
2137 {
2138 	struct cil_tree_node *node = NULL;
2139 	struct cil_args_copy *args = NULL;
2140 
2141 	args = extra_args;
2142 	node = args->dest;
2143 
2144 	if (node->flavor != CIL_ROOT) {
2145 		args->dest = node->parent;
2146 	}
2147 
2148 	return SEPOL_OK;
2149 }
2150 
2151 // dest is the parent node to copy into
2152 // if the copy is for a call to a macro, dest should be a pointer to the call
cil_copy_ast(struct cil_db * db,struct cil_tree_node * orig,struct cil_tree_node * dest)2153 int cil_copy_ast(struct cil_db *db, struct cil_tree_node *orig, struct cil_tree_node *dest)
2154 {
2155 	int rc = SEPOL_ERR;
2156 	struct cil_args_copy extra_args;
2157 
2158 	extra_args.dest = dest;
2159 	extra_args.db = db;
2160 
2161 	rc = cil_tree_walk(orig, __cil_copy_node_helper, NULL,  __cil_copy_last_child_helper, &extra_args);
2162 	if (rc != SEPOL_OK) {
2163 		cil_log(CIL_INFO, "cil_tree_walk failed, rc: %d\n", rc);
2164 		goto exit;
2165 	}
2166 
2167 	return SEPOL_OK;
2168 
2169 exit:
2170 	return rc;
2171 }
2172 
2173