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
44struct cil_args_copy {
45	struct cil_tree_node *dest;
46	struct cil_db *db;
47};
48
49void 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
86int 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
98int 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
116int 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
130int 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
145int 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
163int 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
181void 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
188void 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
194void 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
216int 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
233int 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
255int 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
270int 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_copy_classperms_list(orig->classperms, &new->classperms);
286
287	*copy = new;
288
289	return SEPOL_OK;
290}
291
292int cil_copy_classpermissionset(__attribute__((unused)) struct cil_db *db, void *data, void **copy,  __attribute__((unused)) symtab_t *symtab)
293{
294	struct cil_classpermissionset *orig = data;
295	struct cil_classpermissionset *new = NULL;
296
297	new->set_str = orig->set_str;
298
299	cil_copy_classperms_list(orig->classperms, &new->classperms);
300
301	*copy = new;
302
303	return SEPOL_OK;
304}
305
306int cil_copy_classcommon(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
307{
308	struct cil_classcommon *orig = data;
309	struct cil_classcommon *new = NULL;
310
311	cil_classcommon_init(&new);
312
313	new->class_str = orig->class_str;
314	new->common_str = orig->common_str;
315
316	*copy = new;
317
318	return SEPOL_OK;
319}
320
321int cil_copy_sid(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
322{
323	struct cil_sid *orig = data;
324	char *key = orig->datum.name;
325	struct cil_symtab_datum *datum = NULL;
326
327	cil_symtab_get_datum(symtab, key, &datum);
328	if (datum == NULL) {
329		struct cil_sid *new;
330		cil_sid_init(&new);
331		*copy = new;
332	} else {
333		*copy = datum;
334	}
335
336	return SEPOL_OK;
337}
338
339int cil_copy_sidcontext(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
340{
341	struct cil_sidcontext *orig = data;
342	struct cil_sidcontext *new = NULL;
343
344	cil_sidcontext_init(&new);
345
346	if (orig->context_str != NULL) {
347		new->context_str = orig->context_str;
348	} else {
349		cil_context_init(&new->context);
350		cil_copy_fill_context(db, orig->context, new->context);
351	}
352
353	*copy = new;
354
355	return SEPOL_OK;
356}
357
358int cil_copy_sidorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
359{
360	struct cil_sidorder *orig = data;
361	struct cil_sidorder *new = NULL;
362
363	cil_sidorder_init(&new);
364	if (orig->sid_list_str != NULL) {
365		cil_copy_list(orig->sid_list_str, &new->sid_list_str);
366	}
367
368	*copy = new;
369
370	return SEPOL_OK;
371}
372
373int cil_copy_user(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
374{
375	struct cil_user *orig = data;
376	char *key = orig->datum.name;
377	struct cil_symtab_datum *datum = NULL;
378
379	cil_symtab_get_datum(symtab, key, &datum);
380	if (datum == NULL) {
381		struct cil_user *new;
382		cil_user_init(&new);
383		*copy = new;
384	} else {
385		*copy = datum;
386	}
387
388	return SEPOL_OK;
389}
390
391int cil_copy_userrole(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
392{
393	struct cil_userrole *orig = data;
394	struct cil_userrole *new = NULL;
395
396	cil_userrole_init(&new);
397
398	new->user_str = orig->user_str;
399	new->role_str = orig->role_str;
400
401	*copy = new;
402
403	return SEPOL_OK;
404}
405
406int cil_copy_userlevel(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
407{
408	struct cil_userlevel *orig = data;
409	struct cil_userlevel *new = NULL;
410
411	cil_userlevel_init(&new);
412
413	new->user_str = orig->user_str;
414
415	if (orig->level_str != NULL) {
416		new->level_str = orig->level_str;
417	} else {
418		cil_copy_fill_level(db, orig->level, &new->level);
419	}
420
421	*copy = new;
422
423	return SEPOL_OK;
424}
425
426int cil_copy_userrange(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
427{
428	struct cil_userrange *orig = data;
429	struct cil_userrange *new = NULL;
430
431	cil_userrange_init(&new);
432
433	new->user_str = orig->user_str;
434
435	if (orig->range_str != NULL) {
436		new->range_str = orig->range_str;
437	} else {
438		cil_levelrange_init(&new->range);
439		cil_copy_fill_levelrange(db, orig->range, new->range);
440	}
441
442	*copy = new;
443
444	return SEPOL_OK;
445}
446
447int cil_copy_userprefix(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
448{
449	struct cil_userprefix *orig = data;
450	struct cil_userprefix *new = NULL;
451
452	cil_userprefix_init(&new);
453
454	new->user_str = orig->user_str;
455	new->prefix_str = orig->prefix_str;
456
457	*copy = new;
458
459	return SEPOL_OK;
460}
461
462int cil_copy_role(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
463{
464	struct cil_role *orig = data;
465	char *key = orig->datum.name;
466	struct cil_symtab_datum *datum = NULL;
467
468	cil_symtab_get_datum(symtab, key, &datum);
469	if (datum == NULL) {
470		struct cil_role *new;
471		cil_role_init(&new);
472		*copy = new;
473	} else {
474		*copy = datum;
475	}
476
477	return SEPOL_OK;
478}
479
480int cil_copy_roletype(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
481{
482	struct cil_roletype *orig = data;
483	struct cil_roletype *new = NULL;
484
485	cil_roletype_init(&new);
486
487	new->role_str = orig->role_str;
488	new->type_str = orig->type_str;
489
490	*copy = new;
491
492	return SEPOL_OK;
493}
494
495int cil_copy_roleattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
496{
497	struct cil_roleattribute *orig = data;
498	char *key = orig->datum.name;
499	struct cil_symtab_datum *datum = NULL;
500
501	cil_symtab_get_datum(symtab, key, &datum);
502	if (datum == NULL) {
503		struct cil_roleattribute *new;
504		cil_roleattribute_init(&new);
505		*copy = new;
506	} else {
507		*copy = datum;
508	}
509
510	return SEPOL_OK;
511}
512
513int cil_copy_roleattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
514{
515	struct cil_roleattributeset *orig = data;
516	struct cil_roleattributeset *new = NULL;
517
518	cil_roleattributeset_init(&new);
519
520	new->attr_str = orig->attr_str;
521
522	cil_copy_expr(db, orig->str_expr, &new->str_expr);
523	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
524
525	*copy = new;
526
527	return SEPOL_OK;
528}
529
530int cil_copy_roleallow(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
531{
532	struct cil_roleallow *orig = data;
533	struct cil_roleallow *new = NULL;
534
535	cil_roleallow_init(&new);
536
537	new->src_str = orig->src_str;
538	new->tgt_str = orig->tgt_str;
539
540	*copy = new;
541
542	return SEPOL_OK;
543}
544
545int cil_copy_type(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
546{
547	struct cil_type *orig = data;
548	char *key = orig->datum.name;
549	struct cil_symtab_datum *datum = NULL;
550
551	cil_symtab_get_datum(symtab, key, &datum);
552	if (datum == NULL) {
553		struct cil_type *new;
554		cil_type_init(&new);
555		*copy = new;
556	} else {
557		*copy = datum;
558	}
559
560	return SEPOL_OK;
561}
562
563int cil_copy_typepermissive(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
564{
565	struct cil_typepermissive *orig = data;
566	struct cil_typepermissive *new = NULL;
567
568	cil_typepermissive_init(&new);
569
570	new->type_str = orig->type_str;
571
572	*copy = new;
573
574	return SEPOL_OK;
575}
576
577int cil_copy_typeattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
578{
579	struct cil_typeattribute *orig = data;
580	char *key = orig->datum.name;
581	struct cil_symtab_datum *datum = NULL;
582
583	cil_symtab_get_datum(symtab, key, &datum);
584	if (datum == NULL) {
585		struct cil_typeattribute *new;
586		cil_typeattribute_init(&new);
587		*copy = new;
588	} else {
589		*copy = datum;
590	}
591
592	return SEPOL_OK;
593}
594
595int cil_copy_typeattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
596{
597	struct cil_typeattributeset *orig = data;
598	struct cil_typeattributeset *new = NULL;
599
600	cil_typeattributeset_init(&new);
601
602	new->attr_str = orig->attr_str;
603
604	cil_copy_expr(db, orig->str_expr, &new->str_expr);
605	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
606
607	*copy = new;
608
609	return SEPOL_OK;
610}
611
612int cil_copy_alias(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
613{
614	struct cil_alias *orig = data;
615	struct cil_alias *new = NULL;
616	char *key = orig->datum.name;
617	struct cil_symtab_datum *datum = NULL;
618
619	cil_symtab_get_datum(symtab, key, &datum);
620	if (datum != NULL) {
621		cil_log(CIL_INFO, "cil_copy_alias: alias cannot be redefined\n");
622		return SEPOL_ERR;
623	}
624
625	cil_alias_init(&new);
626
627	*copy = new;
628
629	return SEPOL_OK;
630}
631
632int cil_copy_aliasactual(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused))symtab_t *symtab)
633{
634	struct cil_aliasactual *orig = data;
635	struct cil_aliasactual *new = NULL;
636
637	cil_aliasactual_init(&new);
638
639	new->alias_str = orig->alias_str;
640	new->actual_str = orig->actual_str;
641
642	*copy = new;
643
644	return SEPOL_OK;
645}
646
647int cil_copy_roletransition(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
648{
649	struct cil_roletransition *orig = data;
650	struct cil_roletransition *new = NULL;
651
652	cil_roletransition_init(&new);
653
654	new->src_str = orig->src_str;
655	new->tgt_str = orig->tgt_str;
656	new->obj_str = orig->obj_str;
657	new->result_str = orig->result_str;
658
659	*copy = new;
660
661	return SEPOL_OK;
662}
663
664int cil_copy_nametypetransition(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
665{
666	struct cil_nametypetransition *orig = data;
667	struct cil_nametypetransition *new = NULL;
668
669	cil_nametypetransition_init(&new);
670
671	new->src_str = orig->src_str;
672	new->tgt_str = orig->tgt_str;
673	new->obj_str = orig->obj_str;
674	new->name_str = orig->name_str;
675	new->result_str = orig->result_str;
676
677
678	*copy = new;
679
680	return SEPOL_OK;
681}
682
683int cil_copy_rangetransition(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
684{
685	struct cil_rangetransition *orig = data;
686	struct cil_rangetransition *new = NULL;
687
688	cil_rangetransition_init(&new);
689
690	new->src_str = orig->src_str;
691	new->exec_str = orig->exec_str;
692	new->obj_str = orig->obj_str;
693
694	if (orig->range_str != NULL) {
695		new->range_str = orig->range_str;
696	} else {
697		cil_levelrange_init(&new->range);
698		cil_copy_fill_levelrange(db, orig->range, new->range);
699	}
700
701	*copy = new;
702
703	return SEPOL_OK;
704}
705
706int cil_copy_bool(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
707{
708	struct cil_bool *orig = data;
709	struct cil_bool *new = NULL;
710	char *key = orig->datum.name;
711	struct cil_symtab_datum *datum = NULL;
712
713	cil_symtab_get_datum(symtab, key, &datum);
714	if (datum != NULL) {
715		cil_log(CIL_INFO, "cil_copy_bool: boolean cannot be redefined\n");
716		return SEPOL_ERR;
717	}
718
719	cil_bool_init(&new);
720	new->value = orig->value;
721	*copy = new;
722
723	return SEPOL_OK;
724}
725
726int cil_copy_tunable(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
727{
728	struct cil_tunable *orig = data;
729	struct cil_tunable *new = NULL;
730	char *key = orig->datum.name;
731	struct cil_symtab_datum *datum = NULL;
732
733	cil_symtab_get_datum(symtab, key, &datum);
734	if (datum != NULL) {
735		cil_log(CIL_INFO, "cil_copy_tunable: tunable cannot be redefined\n");
736		return SEPOL_ERR;
737	}
738
739	cil_tunable_init(&new);
740	new->value = orig->value;
741	*copy = new;
742
743	return SEPOL_OK;
744}
745
746int cil_copy_avrule(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
747{
748	struct cil_avrule *orig = data;
749	struct cil_avrule *new = NULL;
750
751	cil_avrule_init(&new);
752
753	new->rule_kind = orig->rule_kind;
754	new->src_str = orig->src_str;
755	new->tgt_str = orig->tgt_str;
756	cil_copy_classperms_list(orig->classperms, &new->classperms);
757
758	*copy = new;
759
760	return SEPOL_OK;
761}
762
763int cil_copy_type_rule(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
764{
765	struct cil_type_rule  *orig = data;
766	struct cil_type_rule *new = NULL;
767
768	cil_type_rule_init(&new);
769
770	new->rule_kind = orig->rule_kind;
771	new->src_str = orig->src_str;
772	new->tgt_str = orig->tgt_str;
773	new->obj_str = orig->obj_str;
774	new->result_str = orig->result_str;
775
776	*copy = new;
777
778	return SEPOL_OK;
779}
780
781int cil_copy_sens(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
782{
783	struct cil_sens *orig = data;
784	char *key = orig->datum.name;
785	struct cil_symtab_datum *datum = NULL;
786
787	cil_symtab_get_datum(symtab, key, &datum);
788	if (datum == NULL) {
789		struct cil_sens *new;
790		cil_sens_init(&new);
791		*copy = new;
792	} else {
793		*copy = datum;
794	}
795
796	return SEPOL_OK;
797}
798
799int cil_copy_cat(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
800{
801	struct cil_cat *orig = data;
802	char *key = orig->datum.name;
803	struct cil_symtab_datum *datum = NULL;
804
805	cil_symtab_get_datum(symtab, key, &datum);
806	if (datum == NULL) {
807		struct cil_cat *new;
808		cil_cat_init(&new);
809		*copy = new;
810	} else {
811		*copy = datum;
812	}
813
814	return SEPOL_OK;
815}
816
817void cil_copy_cats(struct cil_db *db, struct cil_cats *orig, struct cil_cats **new)
818{
819	cil_cats_init(new);
820	cil_copy_expr(db, orig->str_expr, &(*new)->str_expr);
821	cil_copy_expr(db, orig->datum_expr, &(*new)->datum_expr);
822}
823
824int cil_copy_catset(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
825{
826	struct cil_catset *orig = data;
827	struct cil_catset *new = NULL;
828	char *key = orig->datum.name;
829	struct cil_symtab_datum *datum = NULL;
830
831	cil_symtab_get_datum(symtab, key, &datum);
832	if (datum != NULL) {
833		cil_log(CIL_INFO, "cil_copy_catset: categoryset cannot be redefined\n");
834		return SEPOL_ERR;
835	}
836
837	cil_catset_init(&new);
838
839	cil_copy_cats(db, orig->cats, &new->cats);
840
841	*copy = new;
842
843	return SEPOL_OK;
844}
845
846int cil_copy_senscat(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
847{
848	struct cil_senscat *orig = data;
849	struct cil_senscat *new = NULL;
850
851	cil_senscat_init(&new);
852
853	new->sens_str = orig->sens_str;
854
855	cil_copy_cats(db, orig->cats, &new->cats);
856
857	*copy = new;
858
859	return SEPOL_OK;
860}
861
862int cil_copy_catorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
863{
864	struct cil_catorder *orig = data;
865	struct cil_catorder *new = NULL;
866
867	cil_catorder_init(&new);
868	if (orig->cat_list_str != NULL) {
869		cil_copy_list(orig->cat_list_str, &new->cat_list_str);
870	}
871
872	*copy = new;
873
874	return SEPOL_OK;
875}
876
877int cil_copy_sensitivityorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
878{
879	struct cil_sensorder *orig = data;
880	struct cil_sensorder *new = NULL;
881
882	cil_sensorder_init(&new);
883	if (orig->sens_list_str != NULL) {
884		cil_copy_list(orig->sens_list_str, &new->sens_list_str);
885	}
886
887	*copy = new;
888
889	return SEPOL_OK;
890}
891
892void cil_copy_fill_level(struct cil_db *db, struct cil_level *orig, struct cil_level **new)
893{
894	cil_level_init(new);
895
896	(*new)->sens_str = orig->sens_str;
897
898	if (orig->cats != NULL) {
899		cil_copy_cats(db, orig->cats, &(*new)->cats);
900	}
901}
902
903int cil_copy_level(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
904{
905	struct cil_level *orig = data;
906	struct cil_level *new = NULL;
907	char *key = orig->datum.name;
908	struct cil_symtab_datum *datum = NULL;
909
910	if (key != NULL) {
911		cil_symtab_get_datum(symtab, key, &datum);
912		if (datum != NULL) {
913			cil_log(CIL_INFO, "cil_copy_level: level cannot be redefined\n");
914			return SEPOL_ERR;
915		}
916	}
917
918	cil_copy_fill_level(db, orig, &new);
919
920	*copy = new;
921
922	return SEPOL_OK;
923}
924
925void cil_copy_fill_levelrange(struct cil_db *db, struct cil_levelrange *data, struct cil_levelrange *new)
926{
927	if (data->low_str != NULL) {
928		new->low_str = data->low_str;
929	} else {
930		cil_copy_fill_level(db, data->low, &new->low);
931	}
932
933	if (data->high_str != NULL) {
934		new->high_str = data->high_str;
935	} else {
936		cil_copy_fill_level(db, data->high, &new->high);
937	}
938}
939
940int cil_copy_levelrange(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
941{
942	struct cil_levelrange *orig = data;
943	struct cil_levelrange *new = NULL;
944	char *key = orig->datum.name;
945	struct cil_symtab_datum *datum = NULL;
946
947	if (key != NULL) {
948		cil_symtab_get_datum(symtab, key, &datum);
949		if (datum != NULL) {
950			cil_log(CIL_INFO, "cil_copy_levelrange: levelrange cannot be redefined\n");
951			return SEPOL_ERR;
952		}
953	}
954
955	cil_levelrange_init(&new);
956	cil_copy_fill_levelrange(db, orig, new);
957
958	*copy = new;
959
960	return SEPOL_OK;
961}
962
963void cil_copy_fill_context(struct cil_db *db, struct cil_context *data, struct cil_context *new)
964{
965	new->user_str = data->user_str;
966	new->role_str = data->role_str;
967	new->type_str = data->type_str;
968
969	if (data->range_str != NULL) {
970		new->range_str = data->range_str;
971	} else {
972		cil_levelrange_init(&new->range);
973		cil_copy_fill_levelrange(db, data->range, new->range);
974	}
975}
976
977int cil_copy_context(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
978{
979	struct cil_context *orig = data;
980	struct cil_context *new = NULL;
981	char *key = orig->datum.name;
982	struct cil_symtab_datum *datum = NULL;
983
984	if (key != NULL) {
985		cil_symtab_get_datum(symtab, key, &datum);
986		if (datum != NULL) {
987			cil_log(CIL_INFO, "cil_copy_context: context cannot be redefined\n");
988			return SEPOL_ERR;
989		}
990	}
991
992	cil_context_init(&new);
993	cil_copy_fill_context(db, orig, new);
994
995	*copy = new;
996
997	return SEPOL_OK;
998}
999
1000int cil_copy_netifcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1001{
1002	struct cil_netifcon *orig = data;
1003	struct cil_netifcon *new = NULL;
1004
1005	cil_netifcon_init(&new);
1006
1007	new->interface_str = orig->interface_str;
1008
1009	if (orig->if_context_str != NULL) {
1010		new->if_context_str = orig->if_context_str;
1011	} else {
1012		cil_context_init(&new->if_context);
1013		cil_copy_fill_context(db, orig->if_context, new->if_context);
1014	}
1015
1016	if (orig->packet_context_str != NULL) {
1017		new->packet_context_str = orig->packet_context_str;
1018	} else {
1019		cil_context_init(&new->packet_context);
1020		cil_copy_fill_context(db, orig->packet_context, new->packet_context);
1021	}
1022
1023	*copy = new;
1024
1025	return SEPOL_OK;
1026}
1027
1028int cil_copy_genfscon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1029{
1030	struct cil_genfscon *orig = data;
1031	struct cil_genfscon *new = NULL;
1032
1033	cil_genfscon_init(&new);
1034
1035	new->fs_str = orig->fs_str;
1036	new->path_str = orig->path_str;
1037
1038	if (orig->context_str != NULL) {
1039		new->context_str = orig->context_str;
1040	} else {
1041		cil_context_init(&new->context);
1042		cil_copy_fill_context(db, orig->context, new->context);
1043	}
1044
1045	*copy = new;
1046
1047	return SEPOL_OK;
1048}
1049
1050int cil_copy_filecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1051{
1052	struct cil_filecon *orig = data;
1053	struct cil_filecon *new = NULL;
1054
1055	cil_filecon_init(&new);
1056
1057	new->path_str = orig->path_str;
1058	new->type = orig->type;
1059
1060	if (orig->context_str != NULL) {
1061		new->context_str = orig->context_str;
1062	} else if (orig->context != NULL) {
1063		cil_context_init(&new->context);
1064		cil_copy_fill_context(db, orig->context, new->context);
1065	}
1066
1067	*copy = new;
1068
1069	return SEPOL_OK;
1070}
1071
1072int cil_copy_nodecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1073{
1074	struct cil_nodecon *orig = data;
1075	struct cil_nodecon *new = NULL;
1076
1077	cil_nodecon_init(&new);
1078
1079	if (orig->addr_str != NULL) {
1080		new->addr_str = orig->addr_str;
1081	} else {
1082		cil_ipaddr_init(&new->addr);
1083		cil_copy_fill_ipaddr(orig->addr, new->addr);
1084	}
1085
1086	if (orig->mask_str != NULL) {
1087		new->mask_str = orig->mask_str;
1088	} else {
1089		cil_ipaddr_init(&new->mask);
1090		cil_copy_fill_ipaddr(orig->mask, new->mask);
1091	}
1092
1093	if (orig->context_str != NULL) {
1094		new->context_str = orig->context_str;
1095	} else {
1096		cil_context_init(&new->context);
1097		cil_copy_fill_context(db, orig->context, new->context);
1098	}
1099
1100	*copy = new;
1101
1102	return SEPOL_OK;
1103}
1104
1105int cil_copy_portcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1106{
1107	struct cil_portcon *orig = data;
1108	struct cil_portcon *new = NULL;
1109
1110	cil_portcon_init(&new);
1111
1112	new->proto = orig->proto;
1113	new->port_low = orig->port_low;
1114	new->port_high = orig->port_high;
1115
1116	if (orig->context_str != NULL) {
1117		new->context_str = orig->context_str;
1118	} else {
1119		cil_context_init(&new->context);
1120		cil_copy_fill_context(db, orig->context, new->context);
1121	}
1122
1123	*copy = new;
1124
1125	return SEPOL_OK;
1126}
1127
1128int cil_copy_pirqcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1129{
1130	struct cil_pirqcon *orig = data;
1131	struct cil_pirqcon *new = NULL;
1132
1133	cil_pirqcon_init(&new);
1134
1135	new->pirq = orig->pirq;
1136
1137	if (orig->context_str != NULL) {
1138		new->context_str = orig->context_str;
1139	} else {
1140		cil_context_init(&new->context);
1141		cil_copy_fill_context(db, orig->context, new->context);
1142	}
1143
1144	*copy = new;
1145
1146	return SEPOL_OK;
1147}
1148
1149int cil_copy_iomemcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1150{
1151	struct cil_iomemcon *orig = data;
1152	struct cil_iomemcon *new = NULL;
1153
1154	cil_iomemcon_init(&new);
1155
1156	new->iomem_low = orig->iomem_low;
1157	new->iomem_high = orig->iomem_high;
1158
1159	if (orig->context_str != NULL) {
1160		new->context_str = orig->context_str;
1161	} else {
1162		cil_context_init(&new->context);
1163		cil_copy_fill_context(db, orig->context, new->context);
1164	}
1165
1166	*copy = new;
1167
1168	return SEPOL_OK;
1169}
1170
1171int cil_copy_ioportcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1172{
1173	struct cil_ioportcon *orig = data;
1174	struct cil_ioportcon *new = NULL;
1175
1176	cil_ioportcon_init(&new);
1177
1178	new->ioport_low = orig->ioport_low;
1179	new->ioport_high = orig->ioport_high;
1180
1181	if (orig->context_str != NULL) {
1182		new->context_str = orig->context_str;
1183	} else {
1184		cil_context_init(&new->context);
1185		cil_copy_fill_context(db, orig->context, new->context);
1186	}
1187
1188	*copy = new;
1189
1190	return SEPOL_OK;
1191}
1192
1193int cil_copy_pcidevicecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1194{
1195	struct cil_pcidevicecon *orig = data;
1196	struct cil_pcidevicecon *new = NULL;
1197
1198	cil_pcidevicecon_init(&new);
1199
1200	new->dev = orig->dev;
1201
1202	if (orig->context_str != NULL) {
1203		new->context_str = orig->context_str;
1204	} else {
1205		cil_context_init(&new->context);
1206		cil_copy_fill_context(db, orig->context, new->context);
1207	}
1208
1209	*copy = new;
1210
1211	return SEPOL_OK;
1212}
1213
1214int cil_copy_devicetreecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1215{
1216	struct cil_devicetreecon *orig = data;
1217	struct cil_devicetreecon *new = NULL;
1218
1219	cil_devicetreecon_init(&new);
1220
1221	new->path = orig->path;
1222
1223	if (orig->context_str != NULL) {
1224		new->context_str = orig->context_str;
1225	} else {
1226		cil_context_init(&new->context);
1227		cil_copy_fill_context(db, orig->context, new->context);
1228	}
1229
1230	*copy = new;
1231
1232	return SEPOL_OK;
1233}
1234
1235int cil_copy_fsuse(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1236{
1237	struct cil_fsuse *orig = data;
1238	struct cil_fsuse *new = NULL;
1239
1240	cil_fsuse_init(&new);
1241
1242	new->type = orig->type;
1243	new->fs_str = orig->fs_str;
1244
1245	if (orig->context_str != NULL) {
1246		new->context_str = orig->context_str;
1247	} else {
1248		cil_context_init(&new->context);
1249		cil_copy_fill_context(db, orig->context, new->context);
1250	}
1251
1252	*copy = new;
1253
1254	return SEPOL_OK;
1255}
1256
1257int cil_copy_expr(struct cil_db *db, struct cil_list *orig, struct cil_list **new)
1258{
1259	struct cil_list_item *curr;
1260
1261	if (orig == NULL) {
1262		*new = NULL;
1263		return SEPOL_OK;
1264	}
1265
1266	cil_list_init(new, orig->flavor);
1267
1268	cil_list_for_each(curr, orig) {
1269		switch (curr->flavor) {
1270		case CIL_LIST: {
1271			struct cil_list *sub_list;
1272			cil_copy_expr(db, curr->data, &sub_list);
1273			cil_list_append(*new, CIL_LIST, sub_list);
1274			break;
1275		}
1276		case CIL_STRING:
1277			cil_list_append(*new, CIL_STRING, curr->data);
1278			break;
1279		case CIL_DATUM:
1280			cil_list_append(*new, curr->flavor, curr->data);
1281			break;
1282		case CIL_OP:
1283			cil_list_append(*new, curr->flavor, curr->data);
1284			break;
1285		case CIL_CONS_OPERAND:
1286			cil_list_append(*new, curr->flavor, curr->data);
1287			break;
1288		default:
1289			cil_log(CIL_INFO, "Unknown flavor %d in expression being copied\n",curr->flavor);
1290			cil_list_append(*new, curr->flavor, curr->data);
1291			break;
1292		}
1293	}
1294
1295	return SEPOL_OK;
1296}
1297
1298int cil_copy_constrain(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1299{
1300	struct cil_constrain *orig = data;
1301	struct cil_constrain *new = NULL;
1302
1303	cil_constrain_init(&new);
1304	cil_copy_classperms_list(orig->classperms, &new->classperms);
1305
1306	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1307	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1308
1309	*copy = new;
1310
1311	return SEPOL_OK;
1312}
1313
1314int cil_copy_validatetrans(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1315{
1316	struct cil_validatetrans *orig = data;
1317	struct cil_validatetrans *new = NULL;
1318
1319	cil_validatetrans_init(&new);
1320
1321	new->class_str = orig->class_str;
1322
1323	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1324	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1325
1326	*copy = new;
1327
1328	return SEPOL_OK;
1329}
1330
1331int cil_copy_call(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1332{
1333	struct cil_call *orig = data;
1334	struct cil_call *new = NULL;
1335	int rc = SEPOL_ERR;
1336
1337	cil_call_init(&new);
1338
1339	new->macro_str = orig->macro_str;
1340	new->macro = orig->macro;
1341
1342	if (orig->args_tree != NULL) {
1343		cil_tree_init(&new->args_tree);
1344		rc = cil_copy_ast(db, orig->args_tree->root, new->args_tree->root);
1345		if (rc != SEPOL_OK) {
1346			goto exit;
1347		}
1348	}
1349
1350	new->copied = orig->copied;
1351
1352	*copy = new;
1353
1354	return SEPOL_OK;
1355
1356exit:
1357	cil_destroy_call(new);
1358	return rc;
1359}
1360
1361int cil_copy_macro(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1362{
1363	struct cil_macro *orig = data;
1364	char *key = orig->datum.name;
1365	struct cil_symtab_datum *datum = NULL;
1366
1367	cil_symtab_get_datum(symtab, key, &datum);
1368	if (datum == NULL) {
1369		struct cil_macro *new;
1370		cil_macro_init(&new);
1371		if (orig->params != NULL) {
1372			cil_copy_list(orig->params, &new->params);
1373		}
1374
1375		*copy = new;
1376
1377	} else {
1378		struct cil_list_item *curr_orig = NULL;
1379		struct cil_list_item *curr_new = NULL;
1380		struct cil_param *param_orig = NULL;
1381		struct cil_param *param_new = NULL;
1382
1383		if (((struct cil_macro*)datum)->params != NULL) {
1384			curr_new = ((struct cil_macro*)datum)->params->head;
1385		}
1386
1387		if (orig->params != NULL) {
1388			curr_orig = orig->params->head;
1389		}
1390
1391		if (curr_orig != NULL && curr_new != NULL) {
1392			while (curr_orig != NULL) {
1393				if (curr_new == NULL) {
1394					goto exit;
1395				}
1396
1397				param_orig = (struct cil_param*)curr_orig->data;
1398				param_new = (struct cil_param*)curr_new->data;
1399				if (param_orig->str != param_new->str) {
1400					goto exit;
1401				} else if (param_orig->flavor != param_new->flavor) {
1402					goto exit;
1403				}
1404
1405				curr_orig = curr_orig->next;
1406				curr_new = curr_new->next;
1407			}
1408
1409			if (curr_new != NULL) {
1410				goto exit;
1411			}
1412		} else if (!(curr_orig == NULL && curr_new == NULL)) {
1413			goto exit;
1414		}
1415
1416		*copy = datum;
1417	}
1418
1419	return SEPOL_OK;
1420
1421exit:
1422	cil_log(CIL_INFO, "cil_copy_macro: macro cannot be redefined\n");
1423	return SEPOL_ERR;
1424}
1425
1426int cil_copy_optional(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1427{
1428	struct cil_optional *orig = data;
1429	char *key = orig->datum.name;
1430	struct cil_symtab_datum *datum = NULL;
1431
1432	cil_symtab_get_datum(symtab, key, &datum);
1433	if (datum == NULL) {
1434		struct cil_optional *new;
1435		cil_optional_init(&new);
1436		*copy = new;
1437	} else {
1438		*copy = datum;
1439	}
1440
1441	return SEPOL_OK;
1442}
1443
1444void cil_copy_fill_ipaddr(struct cil_ipaddr *data, struct cil_ipaddr *new)
1445{
1446	new->family = data->family;
1447	memcpy(&new->ip, &data->ip, sizeof(data->ip));
1448}
1449
1450int cil_copy_ipaddr(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1451{
1452	struct cil_ipaddr *orig = data;
1453	struct cil_ipaddr *new = NULL;
1454	char * key = orig->datum.name;
1455	struct cil_symtab_datum *datum = NULL;
1456
1457	cil_symtab_get_datum(symtab, key, &datum);
1458	if (datum != NULL) {
1459		cil_log(CIL_INFO, "cil_copy_ipaddr: ipaddress cannot be redefined\n");
1460		return SEPOL_ERR;
1461	}
1462
1463	cil_ipaddr_init(&new);
1464	cil_copy_fill_ipaddr(orig, new);
1465
1466	*copy = new;
1467
1468	return SEPOL_OK;
1469}
1470
1471int cil_copy_condblock(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1472{
1473	struct cil_condblock *orig = data;
1474	struct cil_condblock *new = *copy;
1475	cil_condblock_init(&new);
1476	new->flavor = orig->flavor;
1477	*copy = new;
1478
1479	return SEPOL_OK;
1480}
1481
1482int cil_copy_boolif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1483{
1484	struct cil_booleanif *orig = data;
1485	struct cil_booleanif *new = NULL;
1486
1487	cil_boolif_init(&new);
1488
1489	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1490	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1491	new->preserved_tunable = orig->preserved_tunable;
1492
1493	*copy = new;
1494
1495	return SEPOL_OK;
1496}
1497
1498int cil_copy_tunif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1499{
1500	struct cil_tunableif *orig = data;
1501	struct cil_tunableif *new = NULL;
1502
1503	cil_tunif_init(&new);
1504
1505	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1506	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1507
1508	*copy = new;
1509
1510	return SEPOL_OK;
1511}
1512
1513int cil_copy_default(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1514{
1515	struct cil_default *orig = data;
1516	struct cil_default *new = NULL;
1517
1518	cil_default_init(&new);
1519
1520	new->flavor = orig->flavor;
1521
1522	if (orig->class_strs != NULL) {
1523		cil_copy_list(orig->class_strs, &new->class_strs);
1524	}
1525
1526	new->object = orig->object;
1527
1528	*copy = new;
1529
1530	return SEPOL_OK;
1531}
1532
1533int cil_copy_defaultrange(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1534{
1535	struct cil_defaultrange *orig = data;
1536	struct cil_defaultrange *new = NULL;
1537
1538	cil_defaultrange_init(&new);
1539
1540	if (orig->class_strs != NULL) {
1541		cil_copy_list(orig->class_strs, &new->class_strs);
1542	}
1543
1544	new->object_range = orig->object_range;
1545
1546	*copy = new;
1547
1548	return SEPOL_OK;
1549}
1550
1551int cil_copy_handleunknown(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1552{
1553	struct cil_handleunknown *orig = data;
1554	struct cil_handleunknown *new = NULL;
1555
1556	cil_handleunknown_init(&new);
1557	new->handle_unknown = orig->handle_unknown;
1558	*copy = new;
1559
1560	return SEPOL_OK;
1561}
1562
1563int cil_copy_mls(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1564{
1565	struct cil_mls *orig = data;
1566	struct cil_mls *new = NULL;
1567
1568	cil_mls_init(&new);
1569	new->value = orig->value;
1570	*copy = new;
1571
1572	return SEPOL_OK;
1573}
1574
1575int cil_copy_bounds(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1576{
1577	struct cil_bounds *orig = data;
1578	struct cil_bounds *new = NULL;
1579
1580	cil_bounds_init(&new);
1581
1582	new->parent_str = orig->parent_str;
1583	new->child_str = orig->child_str;
1584
1585	*copy = new;
1586
1587	return SEPOL_OK;
1588}
1589
1590int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) uint32_t *finished, void *extra_args)
1591{
1592	int rc = SEPOL_ERR;
1593	struct cil_tree_node *parent = NULL;
1594	struct cil_tree_node *new = NULL;
1595	struct cil_db *db = NULL;
1596	struct cil_args_copy *args = NULL;
1597	struct cil_tree_node *namespace = NULL;
1598	struct cil_param *param = NULL;
1599	enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
1600	symtab_t *symtab = NULL;
1601	void *data = NULL;
1602	int (*copy_func)(struct cil_db *db, void *data, void **copy, symtab_t *symtab) = NULL;
1603	struct cil_blockinherit *blockinherit = NULL;
1604
1605	if (orig == NULL || extra_args == NULL) {
1606		goto exit;
1607	}
1608
1609	args = extra_args;
1610	parent = args->dest;
1611	db = args->db;
1612
1613
1614	switch (orig->flavor) {
1615	case CIL_BLOCK:
1616		copy_func = &cil_copy_block;
1617		break;
1618	case CIL_BLOCKABSTRACT:
1619		copy_func = &cil_copy_blockabstract;
1620		break;
1621	case CIL_BLOCKINHERIT:
1622		copy_func = &cil_copy_blockinherit;
1623		break;
1624	case CIL_POLICYCAP:
1625		copy_func = &cil_copy_policycap;
1626		break;
1627	case CIL_PERM:
1628	case CIL_MAP_PERM:
1629		copy_func = &cil_copy_perm;
1630		break;
1631	case CIL_CLASSMAPPING:
1632		copy_func = &cil_copy_classmapping;
1633		break;
1634	case CIL_CLASS:
1635	case CIL_COMMON:
1636	case CIL_MAP_CLASS:
1637		copy_func = &cil_copy_class;
1638		break;
1639	case CIL_CLASSORDER:
1640		copy_func = &cil_copy_classorder;
1641		break;
1642	case CIL_CLASSPERMISSION:
1643		copy_func = &cil_copy_classpermission;
1644		break;
1645	case CIL_CLASSPERMISSIONSET:
1646		copy_func = &cil_copy_classpermissionset;
1647		break;
1648	case CIL_CLASSCOMMON:
1649		copy_func = &cil_copy_classcommon;
1650		break;
1651	case CIL_SID:
1652		copy_func = &cil_copy_sid;
1653		break;
1654	case CIL_SIDCONTEXT:
1655		copy_func = &cil_copy_sidcontext;
1656		break;
1657	case CIL_SIDORDER:
1658		copy_func = &cil_copy_sidorder;
1659		break;
1660	case CIL_USER:
1661		copy_func = &cil_copy_user;
1662		break;
1663	case CIL_USERROLE:
1664		copy_func = &cil_copy_userrole;
1665		break;
1666	case CIL_USERLEVEL:
1667		copy_func = &cil_copy_userlevel;
1668		break;
1669	case CIL_USERRANGE:
1670		copy_func = &cil_copy_userrange;
1671		break;
1672	case CIL_USERBOUNDS:
1673		copy_func = &cil_copy_bounds;
1674		break;
1675	case CIL_USERPREFIX:
1676		copy_func = &cil_copy_userprefix;
1677		break;
1678	case CIL_ROLE:
1679		copy_func = &cil_copy_role;
1680		break;
1681	case CIL_ROLETYPE:
1682		copy_func = &cil_copy_roletype;
1683		break;
1684	case CIL_ROLEBOUNDS:
1685		copy_func = &cil_copy_bounds;
1686		break;
1687	case CIL_ROLEATTRIBUTE:
1688		copy_func = &cil_copy_roleattribute;
1689		break;
1690	case CIL_ROLEATTRIBUTESET:
1691		copy_func = &cil_copy_roleattributeset;
1692		break;
1693	case CIL_ROLEALLOW:
1694		copy_func = &cil_copy_roleallow;
1695		break;
1696	case CIL_TYPE:
1697		copy_func = &cil_copy_type;
1698		break;
1699	case CIL_TYPEBOUNDS:
1700		copy_func = &cil_copy_bounds;
1701		break;
1702	case CIL_TYPEPERMISSIVE:
1703		copy_func = cil_copy_typepermissive;
1704		break;
1705	case CIL_TYPEATTRIBUTE:
1706		copy_func = &cil_copy_typeattribute;
1707		break;
1708	case CIL_TYPEATTRIBUTESET:
1709		copy_func = &cil_copy_typeattributeset;
1710		break;
1711	case CIL_TYPEALIAS:
1712		copy_func = &cil_copy_alias;
1713		break;
1714	case CIL_TYPEALIASACTUAL:
1715		copy_func = &cil_copy_aliasactual;
1716		break;
1717	case CIL_ROLETRANSITION:
1718		copy_func = &cil_copy_roletransition;
1719		break;
1720	case CIL_NAMETYPETRANSITION:
1721		copy_func = &cil_copy_nametypetransition;
1722		break;
1723	case CIL_RANGETRANSITION:
1724		copy_func = &cil_copy_rangetransition;
1725		break;
1726	case CIL_TUNABLE:
1727		copy_func = &cil_copy_tunable;
1728		break;
1729	case CIL_BOOL:
1730		copy_func = &cil_copy_bool;
1731		break;
1732	case CIL_AVRULE:
1733		copy_func = &cil_copy_avrule;
1734		break;
1735	case CIL_TYPE_RULE:
1736		copy_func = &cil_copy_type_rule;
1737		break;
1738	case CIL_SENS:
1739		copy_func = &cil_copy_sens;
1740		break;
1741	case CIL_SENSALIAS:
1742		copy_func = &cil_copy_alias;
1743		break;
1744	case CIL_SENSALIASACTUAL:
1745		copy_func = &cil_copy_aliasactual;
1746		break;
1747	case CIL_CAT:
1748		copy_func = &cil_copy_cat;
1749		break;
1750	case CIL_CATALIAS:
1751		copy_func = &cil_copy_alias;
1752		break;
1753	case CIL_CATALIASACTUAL:
1754		copy_func = &cil_copy_aliasactual;
1755		break;
1756	case CIL_CATSET:
1757		copy_func = &cil_copy_catset;
1758		break;
1759	case CIL_SENSCAT:
1760		copy_func = &cil_copy_senscat;
1761		break;
1762	case CIL_CATORDER:
1763		copy_func = &cil_copy_catorder;
1764		break;
1765	case CIL_SENSITIVITYORDER:
1766		copy_func = &cil_copy_sensitivityorder;
1767		break;
1768	case CIL_LEVEL:
1769		copy_func = &cil_copy_level;
1770		break;
1771	case CIL_LEVELRANGE:
1772		copy_func = &cil_copy_levelrange;
1773		break;
1774	case CIL_CONTEXT:
1775		copy_func = &cil_copy_context;
1776		break;
1777	case CIL_NETIFCON:
1778		copy_func = &cil_copy_netifcon;
1779		break;
1780	case CIL_GENFSCON:
1781		copy_func = &cil_copy_genfscon;
1782		break;
1783	case CIL_FILECON:
1784		copy_func = &cil_copy_filecon;
1785		break;
1786	case CIL_NODECON:
1787		copy_func = &cil_copy_nodecon;
1788		break;
1789	case CIL_PORTCON:
1790		copy_func = &cil_copy_portcon;
1791		break;
1792	case CIL_PIRQCON:
1793		copy_func = &cil_copy_pirqcon;
1794		break;
1795	case CIL_IOMEMCON:
1796		copy_func = &cil_copy_iomemcon;
1797		break;
1798	case CIL_IOPORTCON:
1799		copy_func = &cil_copy_ioportcon;
1800		break;
1801	case CIL_PCIDEVICECON:
1802		copy_func = &cil_copy_pcidevicecon;
1803		break;
1804	case CIL_DEVICETREECON:
1805		copy_func = &cil_copy_devicetreecon;
1806		break;
1807	case CIL_FSUSE:
1808		copy_func = &cil_copy_fsuse;
1809		break;
1810	case CIL_CONSTRAIN:
1811	case CIL_MLSCONSTRAIN:
1812		copy_func = &cil_copy_constrain;
1813		break;
1814	case CIL_VALIDATETRANS:
1815	case CIL_MLSVALIDATETRANS:
1816		copy_func = &cil_copy_validatetrans;
1817		break;
1818	case CIL_CALL:
1819		copy_func = &cil_copy_call;
1820		break;
1821	case CIL_MACRO:
1822		copy_func = &cil_copy_macro;
1823		break;
1824	case CIL_NODE:
1825		copy_func = &cil_copy_node;
1826		break;
1827	case CIL_OPTIONAL:
1828		copy_func = &cil_copy_optional;
1829		break;
1830	case CIL_IPADDR:
1831		copy_func = &cil_copy_ipaddr;
1832		break;
1833	case CIL_CONDBLOCK:
1834		copy_func = &cil_copy_condblock;
1835		break;
1836	case CIL_BOOLEANIF:
1837		copy_func = &cil_copy_boolif;
1838		break;
1839	case CIL_TUNABLEIF:
1840		copy_func = &cil_copy_tunif;
1841		break;
1842	case CIL_DEFAULTUSER:
1843	case CIL_DEFAULTROLE:
1844	case CIL_DEFAULTTYPE:
1845		copy_func = &cil_copy_default;
1846		break;
1847	case CIL_DEFAULTRANGE:
1848		copy_func = &cil_copy_defaultrange;
1849		break;
1850	case CIL_HANDLEUNKNOWN:
1851		copy_func = &cil_copy_handleunknown;
1852		break;
1853	case CIL_MLS:
1854		copy_func = &cil_copy_mls;
1855		break;
1856	default:
1857		goto exit;
1858	}
1859
1860	if (orig->flavor >= CIL_MIN_DECLARATIVE) {
1861		rc = cil_flavor_to_symtab_index(orig->flavor, &sym_index);
1862		if (rc != SEPOL_OK) {
1863			goto exit;
1864		}
1865
1866		rc = cil_get_symtab(parent, &symtab, sym_index);
1867		if (rc != SEPOL_OK) {
1868			goto exit;
1869		}
1870	}
1871
1872	rc = (*copy_func)(db, orig->data, &data, symtab);
1873	if (rc == SEPOL_OK) {
1874		cil_tree_node_init(&new);
1875
1876		new->parent = parent;
1877		new->line = orig->line;
1878		new->path = orig->path;
1879		new->flavor = orig->flavor;
1880		new->data = data;
1881
1882		if (orig->flavor >= CIL_MIN_DECLARATIVE) {
1883			rc = cil_symtab_insert(symtab, ((struct cil_symtab_datum*)orig->data)->name, ((struct cil_symtab_datum*)data), new);
1884
1885			namespace = new;
1886			while (namespace->flavor != CIL_MACRO && namespace->flavor != CIL_BLOCK && namespace->flavor != CIL_ROOT) {
1887				namespace = namespace->parent;
1888			}
1889
1890			if (namespace->flavor == CIL_MACRO) {
1891				struct cil_macro *macro = namespace->data;
1892				struct cil_list *param_list = macro->params;
1893				if (param_list != NULL) {
1894					struct cil_list_item *item;
1895					cil_list_for_each(item, param_list) {
1896						param = item->data;
1897						if (param->flavor == new->flavor) {
1898							if (param->str == ((struct cil_symtab_datum*)new->data)->name) {
1899								cil_log(CIL_ERR, "%s %s shadows a macro parameter (%s line:%d)\n", cil_node_to_string(new), ((struct cil_symtab_datum*)orig->data)->name, orig->path, orig->line);
1900								cil_log(CIL_ERR, "Note: macro declaration (%s line:%d)\n", namespace->path, namespace->line);
1901								rc = SEPOL_ERR;
1902								goto exit;
1903							}
1904						}
1905					}
1906				}
1907			}
1908		}
1909
1910		if (new->flavor == CIL_BLOCKINHERIT) {
1911			blockinherit = new->data;
1912			cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new);
1913		}
1914
1915		if (parent->cl_head == NULL) {
1916			parent->cl_head = new;
1917			parent->cl_tail = new;
1918		} else {
1919			parent->cl_tail->next = new;
1920			parent->cl_tail = new;
1921		}
1922
1923		if (orig->cl_head != NULL) {
1924			args->dest = new;
1925		}
1926	} else {
1927		goto exit;
1928	}
1929
1930	return SEPOL_OK;
1931
1932exit:
1933	cil_tree_node_destroy(&new);
1934	return rc;
1935}
1936
1937int __cil_copy_last_child_helper(__attribute__((unused)) struct cil_tree_node *orig, void *extra_args)
1938{
1939	struct cil_tree_node *node = NULL;
1940	struct cil_args_copy *args = NULL;
1941
1942	args = extra_args;
1943	node = args->dest;
1944
1945	if (node->flavor != CIL_ROOT) {
1946		args->dest = node->parent;
1947	}
1948
1949	return SEPOL_OK;
1950}
1951
1952// dest is the parent node to copy into
1953// if the copy is for a call to a macro, dest should be a pointer to the call
1954int cil_copy_ast(struct cil_db *db, struct cil_tree_node *orig, struct cil_tree_node *dest)
1955{
1956	int rc = SEPOL_ERR;
1957	struct cil_args_copy extra_args;
1958
1959	extra_args.dest = dest;
1960	extra_args.db = db;
1961
1962	rc = cil_tree_walk(orig, __cil_copy_node_helper, NULL,  __cil_copy_last_child_helper, &extra_args);
1963	if (rc != SEPOL_OK) {
1964		cil_log(CIL_INFO, "cil_tree_walk failed, rc: %d\n", rc);
1965		goto exit;
1966	}
1967
1968	return SEPOL_OK;
1969
1970exit:
1971	return rc;
1972}
1973
1974