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_classpermission_init(&new);
286
287	cil_copy_classperms_list(orig->classperms, &new->classperms);
288
289	*copy = new;
290
291	return SEPOL_OK;
292}
293
294int 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
310int 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
325int 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
343int 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
362int 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
377int 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
395int 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
413int 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
430int 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
445int 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
465int 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
486int 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
501int 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
519int 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
534int 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
552int 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
569int 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
584int 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
602int 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
616int 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
634int 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
651int 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
674int 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
694int 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
709int 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
726int 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
745int 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
768int 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
788int 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
808void 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
815int 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 (new->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
843int 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
865int 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
883int 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
901int 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
919void 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
926int 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
948int 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
964int 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
979int 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
994void 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
1005int 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
1027void 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
1042int 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
1065void 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
1079int 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
1102int 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
1130int 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
1152int 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
1174int 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
1207int cil_copy_portcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1208{
1209	struct cil_portcon *orig = data;
1210	struct cil_portcon *new = NULL;
1211
1212	cil_portcon_init(&new);
1213
1214	new->proto = orig->proto;
1215	new->port_low = orig->port_low;
1216	new->port_high = orig->port_high;
1217
1218	if (orig->context_str != NULL) {
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
1230int cil_copy_pirqcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1231{
1232	struct cil_pirqcon *orig = data;
1233	struct cil_pirqcon *new = NULL;
1234
1235	cil_pirqcon_init(&new);
1236
1237	new->pirq = orig->pirq;
1238
1239	if (orig->context_str != NULL) {
1240		new->context_str = orig->context_str;
1241	} else {
1242		cil_context_init(&new->context);
1243		cil_copy_fill_context(db, orig->context, new->context);
1244	}
1245
1246	*copy = new;
1247
1248	return SEPOL_OK;
1249}
1250
1251int cil_copy_iomemcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1252{
1253	struct cil_iomemcon *orig = data;
1254	struct cil_iomemcon *new = NULL;
1255
1256	cil_iomemcon_init(&new);
1257
1258	new->iomem_low = orig->iomem_low;
1259	new->iomem_high = orig->iomem_high;
1260
1261	if (orig->context_str != NULL) {
1262		new->context_str = orig->context_str;
1263	} else {
1264		cil_context_init(&new->context);
1265		cil_copy_fill_context(db, orig->context, new->context);
1266	}
1267
1268	*copy = new;
1269
1270	return SEPOL_OK;
1271}
1272
1273int cil_copy_ioportcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1274{
1275	struct cil_ioportcon *orig = data;
1276	struct cil_ioportcon *new = NULL;
1277
1278	cil_ioportcon_init(&new);
1279
1280	new->ioport_low = orig->ioport_low;
1281	new->ioport_high = orig->ioport_high;
1282
1283	if (orig->context_str != NULL) {
1284		new->context_str = orig->context_str;
1285	} else {
1286		cil_context_init(&new->context);
1287		cil_copy_fill_context(db, orig->context, new->context);
1288	}
1289
1290	*copy = new;
1291
1292	return SEPOL_OK;
1293}
1294
1295int cil_copy_pcidevicecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1296{
1297	struct cil_pcidevicecon *orig = data;
1298	struct cil_pcidevicecon *new = NULL;
1299
1300	cil_pcidevicecon_init(&new);
1301
1302	new->dev = orig->dev;
1303
1304	if (orig->context_str != NULL) {
1305		new->context_str = orig->context_str;
1306	} else {
1307		cil_context_init(&new->context);
1308		cil_copy_fill_context(db, orig->context, new->context);
1309	}
1310
1311	*copy = new;
1312
1313	return SEPOL_OK;
1314}
1315
1316int cil_copy_devicetreecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1317{
1318	struct cil_devicetreecon *orig = data;
1319	struct cil_devicetreecon *new = NULL;
1320
1321	cil_devicetreecon_init(&new);
1322
1323	new->path = orig->path;
1324
1325	if (orig->context_str != NULL) {
1326		new->context_str = orig->context_str;
1327	} else {
1328		cil_context_init(&new->context);
1329		cil_copy_fill_context(db, orig->context, new->context);
1330	}
1331
1332	*copy = new;
1333
1334	return SEPOL_OK;
1335}
1336
1337int cil_copy_fsuse(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1338{
1339	struct cil_fsuse *orig = data;
1340	struct cil_fsuse *new = NULL;
1341
1342	cil_fsuse_init(&new);
1343
1344	new->type = orig->type;
1345	new->fs_str = orig->fs_str;
1346
1347	if (orig->context_str != NULL) {
1348		new->context_str = orig->context_str;
1349	} else {
1350		cil_context_init(&new->context);
1351		cil_copy_fill_context(db, orig->context, new->context);
1352	}
1353
1354	*copy = new;
1355
1356	return SEPOL_OK;
1357}
1358
1359int cil_copy_expr(struct cil_db *db, struct cil_list *orig, struct cil_list **new)
1360{
1361	struct cil_list_item *curr;
1362
1363	if (orig == NULL) {
1364		*new = NULL;
1365		return SEPOL_OK;
1366	}
1367
1368	cil_list_init(new, orig->flavor);
1369
1370	cil_list_for_each(curr, orig) {
1371		switch (curr->flavor) {
1372		case CIL_LIST: {
1373			struct cil_list *sub_list;
1374			cil_copy_expr(db, curr->data, &sub_list);
1375			cil_list_append(*new, CIL_LIST, sub_list);
1376			break;
1377		}
1378		case CIL_STRING:
1379			cil_list_append(*new, CIL_STRING, curr->data);
1380			break;
1381		case CIL_DATUM:
1382			cil_list_append(*new, curr->flavor, curr->data);
1383			break;
1384		case CIL_OP:
1385			cil_list_append(*new, curr->flavor, curr->data);
1386			break;
1387		case CIL_CONS_OPERAND:
1388			cil_list_append(*new, curr->flavor, curr->data);
1389			break;
1390		default:
1391			cil_log(CIL_INFO, "Unknown flavor %d in expression being copied\n",curr->flavor);
1392			cil_list_append(*new, curr->flavor, curr->data);
1393			break;
1394		}
1395	}
1396
1397	return SEPOL_OK;
1398}
1399
1400int cil_copy_constrain(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1401{
1402	struct cil_constrain *orig = data;
1403	struct cil_constrain *new = NULL;
1404
1405	cil_constrain_init(&new);
1406	cil_copy_classperms_list(orig->classperms, &new->classperms);
1407
1408	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1409	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1410
1411	*copy = new;
1412
1413	return SEPOL_OK;
1414}
1415
1416int cil_copy_validatetrans(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1417{
1418	struct cil_validatetrans *orig = data;
1419	struct cil_validatetrans *new = NULL;
1420
1421	cil_validatetrans_init(&new);
1422
1423	new->class_str = orig->class_str;
1424
1425	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1426	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1427
1428	*copy = new;
1429
1430	return SEPOL_OK;
1431}
1432
1433int cil_copy_call(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1434{
1435	struct cil_call *orig = data;
1436	struct cil_call *new = NULL;
1437	int rc = SEPOL_ERR;
1438
1439	cil_call_init(&new);
1440
1441	new->macro_str = orig->macro_str;
1442	new->macro = orig->macro;
1443
1444	if (orig->args_tree != NULL) {
1445		cil_tree_init(&new->args_tree);
1446		rc = cil_copy_ast(db, orig->args_tree->root, new->args_tree->root);
1447		if (rc != SEPOL_OK) {
1448			goto exit;
1449		}
1450	}
1451
1452	new->copied = orig->copied;
1453
1454	*copy = new;
1455
1456	return SEPOL_OK;
1457
1458exit:
1459	cil_destroy_call(new);
1460	return rc;
1461}
1462
1463int cil_copy_macro(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1464{
1465	struct cil_macro *orig = data;
1466	char *key = orig->datum.name;
1467	struct cil_symtab_datum *datum = NULL;
1468
1469	cil_symtab_get_datum(symtab, key, &datum);
1470	if (datum == NULL) {
1471		struct cil_macro *new;
1472		cil_macro_init(&new);
1473		if (orig->params != NULL) {
1474			cil_copy_list(orig->params, &new->params);
1475		}
1476
1477		*copy = new;
1478
1479	} else {
1480		struct cil_list_item *curr_orig = NULL;
1481		struct cil_list_item *curr_new = NULL;
1482		struct cil_param *param_orig = NULL;
1483		struct cil_param *param_new = NULL;
1484
1485		if (((struct cil_macro*)datum)->params != NULL) {
1486			curr_new = ((struct cil_macro*)datum)->params->head;
1487		}
1488
1489		if (orig->params != NULL) {
1490			curr_orig = orig->params->head;
1491		}
1492
1493		if (curr_orig != NULL && curr_new != NULL) {
1494			while (curr_orig != NULL) {
1495				if (curr_new == NULL) {
1496					goto exit;
1497				}
1498
1499				param_orig = (struct cil_param*)curr_orig->data;
1500				param_new = (struct cil_param*)curr_new->data;
1501				if (param_orig->str != param_new->str) {
1502					goto exit;
1503				} else if (param_orig->flavor != param_new->flavor) {
1504					goto exit;
1505				}
1506
1507				curr_orig = curr_orig->next;
1508				curr_new = curr_new->next;
1509			}
1510
1511			if (curr_new != NULL) {
1512				goto exit;
1513			}
1514		} else if (!(curr_orig == NULL && curr_new == NULL)) {
1515			goto exit;
1516		}
1517
1518		*copy = datum;
1519	}
1520
1521	return SEPOL_OK;
1522
1523exit:
1524	cil_log(CIL_INFO, "cil_copy_macro: macro cannot be redefined\n");
1525	return SEPOL_ERR;
1526}
1527
1528int cil_copy_optional(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1529{
1530	struct cil_optional *orig = data;
1531	char *key = orig->datum.name;
1532	struct cil_symtab_datum *datum = NULL;
1533
1534	cil_symtab_get_datum(symtab, key, &datum);
1535	if (datum == NULL) {
1536		struct cil_optional *new;
1537		cil_optional_init(&new);
1538		*copy = new;
1539	} else {
1540		*copy = datum;
1541	}
1542
1543	return SEPOL_OK;
1544}
1545
1546void cil_copy_fill_ipaddr(struct cil_ipaddr *data, struct cil_ipaddr *new)
1547{
1548	new->family = data->family;
1549	memcpy(&new->ip, &data->ip, sizeof(data->ip));
1550}
1551
1552int cil_copy_ipaddr(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1553{
1554	struct cil_ipaddr *orig = data;
1555	struct cil_ipaddr *new = NULL;
1556	char * key = orig->datum.name;
1557	struct cil_symtab_datum *datum = NULL;
1558
1559	cil_symtab_get_datum(symtab, key, &datum);
1560	if (datum != NULL) {
1561		cil_log(CIL_INFO, "cil_copy_ipaddr: ipaddress cannot be redefined\n");
1562		return SEPOL_ERR;
1563	}
1564
1565	cil_ipaddr_init(&new);
1566	cil_copy_fill_ipaddr(orig, new);
1567
1568	*copy = new;
1569
1570	return SEPOL_OK;
1571}
1572
1573int cil_copy_condblock(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1574{
1575	struct cil_condblock *orig = data;
1576	struct cil_condblock *new = *copy;
1577	cil_condblock_init(&new);
1578	new->flavor = orig->flavor;
1579	*copy = new;
1580
1581	return SEPOL_OK;
1582}
1583
1584int cil_copy_boolif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1585{
1586	struct cil_booleanif *orig = data;
1587	struct cil_booleanif *new = NULL;
1588
1589	cil_boolif_init(&new);
1590
1591	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1592	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1593	new->preserved_tunable = orig->preserved_tunable;
1594
1595	*copy = new;
1596
1597	return SEPOL_OK;
1598}
1599
1600int cil_copy_tunif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1601{
1602	struct cil_tunableif *orig = data;
1603	struct cil_tunableif *new = NULL;
1604
1605	cil_tunif_init(&new);
1606
1607	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1608	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1609
1610	*copy = new;
1611
1612	return SEPOL_OK;
1613}
1614
1615int cil_copy_default(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1616{
1617	struct cil_default *orig = data;
1618	struct cil_default *new = NULL;
1619
1620	cil_default_init(&new);
1621
1622	new->flavor = orig->flavor;
1623
1624	if (orig->class_strs != NULL) {
1625		cil_copy_list(orig->class_strs, &new->class_strs);
1626	}
1627
1628	new->object = orig->object;
1629
1630	*copy = new;
1631
1632	return SEPOL_OK;
1633}
1634
1635int cil_copy_defaultrange(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1636{
1637	struct cil_defaultrange *orig = data;
1638	struct cil_defaultrange *new = NULL;
1639
1640	cil_defaultrange_init(&new);
1641
1642	if (orig->class_strs != NULL) {
1643		cil_copy_list(orig->class_strs, &new->class_strs);
1644	}
1645
1646	new->object_range = orig->object_range;
1647
1648	*copy = new;
1649
1650	return SEPOL_OK;
1651}
1652
1653int cil_copy_handleunknown(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1654{
1655	struct cil_handleunknown *orig = data;
1656	struct cil_handleunknown *new = NULL;
1657
1658	cil_handleunknown_init(&new);
1659	new->handle_unknown = orig->handle_unknown;
1660	*copy = new;
1661
1662	return SEPOL_OK;
1663}
1664
1665int cil_copy_mls(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1666{
1667	struct cil_mls *orig = data;
1668	struct cil_mls *new = NULL;
1669
1670	cil_mls_init(&new);
1671	new->value = orig->value;
1672	*copy = new;
1673
1674	return SEPOL_OK;
1675}
1676
1677int cil_copy_bounds(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1678{
1679	struct cil_bounds *orig = data;
1680	struct cil_bounds *new = NULL;
1681
1682	cil_bounds_init(&new);
1683
1684	new->parent_str = orig->parent_str;
1685	new->child_str = orig->child_str;
1686
1687	*copy = new;
1688
1689	return SEPOL_OK;
1690}
1691
1692int cil_copy_src_info(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1693{
1694	struct cil_src_info *orig = data;
1695	struct cil_src_info *new = NULL;
1696
1697	cil_src_info_init(&new);
1698
1699	new->is_cil = orig->is_cil;
1700	new->path = orig->path;
1701
1702	*copy = new;
1703
1704	return SEPOL_OK;
1705}
1706
1707int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) uint32_t *finished, void *extra_args)
1708{
1709	int rc = SEPOL_ERR;
1710	struct cil_tree_node *parent = NULL;
1711	struct cil_tree_node *new = NULL;
1712	struct cil_db *db = NULL;
1713	struct cil_args_copy *args = NULL;
1714	struct cil_tree_node *namespace = NULL;
1715	struct cil_param *param = NULL;
1716	enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
1717	symtab_t *symtab = NULL;
1718	void *data = NULL;
1719	int (*copy_func)(struct cil_db *db, void *data, void **copy, symtab_t *symtab) = NULL;
1720	struct cil_blockinherit *blockinherit = NULL;
1721
1722	if (orig == NULL || extra_args == NULL) {
1723		goto exit;
1724	}
1725
1726	args = extra_args;
1727	parent = args->dest;
1728	db = args->db;
1729
1730
1731	switch (orig->flavor) {
1732	case CIL_BLOCK:
1733		copy_func = &cil_copy_block;
1734		break;
1735	case CIL_BLOCKABSTRACT:
1736		copy_func = &cil_copy_blockabstract;
1737		break;
1738	case CIL_BLOCKINHERIT:
1739		copy_func = &cil_copy_blockinherit;
1740		break;
1741	case CIL_POLICYCAP:
1742		copy_func = &cil_copy_policycap;
1743		break;
1744	case CIL_PERM:
1745	case CIL_MAP_PERM:
1746		copy_func = &cil_copy_perm;
1747		break;
1748	case CIL_CLASSMAPPING:
1749		copy_func = &cil_copy_classmapping;
1750		break;
1751	case CIL_CLASS:
1752	case CIL_COMMON:
1753	case CIL_MAP_CLASS:
1754		copy_func = &cil_copy_class;
1755		break;
1756	case CIL_CLASSORDER:
1757		copy_func = &cil_copy_classorder;
1758		break;
1759	case CIL_CLASSPERMISSION:
1760		copy_func = &cil_copy_classpermission;
1761		break;
1762	case CIL_CLASSPERMISSIONSET:
1763		copy_func = &cil_copy_classpermissionset;
1764		break;
1765	case CIL_CLASSCOMMON:
1766		copy_func = &cil_copy_classcommon;
1767		break;
1768	case CIL_SID:
1769		copy_func = &cil_copy_sid;
1770		break;
1771	case CIL_SIDCONTEXT:
1772		copy_func = &cil_copy_sidcontext;
1773		break;
1774	case CIL_SIDORDER:
1775		copy_func = &cil_copy_sidorder;
1776		break;
1777	case CIL_USER:
1778		copy_func = &cil_copy_user;
1779		break;
1780	case CIL_USERATTRIBUTE:
1781		copy_func = &cil_copy_userattribute;
1782		break;
1783	case CIL_USERATTRIBUTESET:
1784		copy_func = &cil_copy_userattributeset;
1785		break;
1786	case CIL_USERROLE:
1787		copy_func = &cil_copy_userrole;
1788		break;
1789	case CIL_USERLEVEL:
1790		copy_func = &cil_copy_userlevel;
1791		break;
1792	case CIL_USERRANGE:
1793		copy_func = &cil_copy_userrange;
1794		break;
1795	case CIL_USERBOUNDS:
1796		copy_func = &cil_copy_bounds;
1797		break;
1798	case CIL_USERPREFIX:
1799		copy_func = &cil_copy_userprefix;
1800		break;
1801	case CIL_ROLE:
1802		copy_func = &cil_copy_role;
1803		break;
1804	case CIL_ROLETYPE:
1805		copy_func = &cil_copy_roletype;
1806		break;
1807	case CIL_ROLEBOUNDS:
1808		copy_func = &cil_copy_bounds;
1809		break;
1810	case CIL_ROLEATTRIBUTE:
1811		copy_func = &cil_copy_roleattribute;
1812		break;
1813	case CIL_ROLEATTRIBUTESET:
1814		copy_func = &cil_copy_roleattributeset;
1815		break;
1816	case CIL_ROLEALLOW:
1817		copy_func = &cil_copy_roleallow;
1818		break;
1819	case CIL_TYPE:
1820		copy_func = &cil_copy_type;
1821		break;
1822	case CIL_TYPEBOUNDS:
1823		copy_func = &cil_copy_bounds;
1824		break;
1825	case CIL_TYPEPERMISSIVE:
1826		copy_func = cil_copy_typepermissive;
1827		break;
1828	case CIL_TYPEATTRIBUTE:
1829		copy_func = &cil_copy_typeattribute;
1830		break;
1831	case CIL_TYPEATTRIBUTESET:
1832		copy_func = &cil_copy_typeattributeset;
1833		break;
1834	case CIL_EXPANDTYPEATTRIBUTE:
1835		copy_func = &cil_copy_expandtypeattribute;
1836		break;
1837	case CIL_TYPEALIAS:
1838		copy_func = &cil_copy_alias;
1839		break;
1840	case CIL_TYPEALIASACTUAL:
1841		copy_func = &cil_copy_aliasactual;
1842		break;
1843	case CIL_ROLETRANSITION:
1844		copy_func = &cil_copy_roletransition;
1845		break;
1846	case CIL_NAMETYPETRANSITION:
1847		copy_func = &cil_copy_nametypetransition;
1848		break;
1849	case CIL_RANGETRANSITION:
1850		copy_func = &cil_copy_rangetransition;
1851		break;
1852	case CIL_TUNABLE:
1853		copy_func = &cil_copy_tunable;
1854		break;
1855	case CIL_BOOL:
1856		copy_func = &cil_copy_bool;
1857		break;
1858	case CIL_AVRULE:
1859	case CIL_AVRULEX:
1860		copy_func = &cil_copy_avrule;
1861		break;
1862	case CIL_PERMISSIONX:
1863		copy_func = &cil_copy_permissionx;
1864		break;
1865	case CIL_TYPE_RULE:
1866		copy_func = &cil_copy_type_rule;
1867		break;
1868	case CIL_SENS:
1869		copy_func = &cil_copy_sens;
1870		break;
1871	case CIL_SENSALIAS:
1872		copy_func = &cil_copy_alias;
1873		break;
1874	case CIL_SENSALIASACTUAL:
1875		copy_func = &cil_copy_aliasactual;
1876		break;
1877	case CIL_CAT:
1878		copy_func = &cil_copy_cat;
1879		break;
1880	case CIL_CATALIAS:
1881		copy_func = &cil_copy_alias;
1882		break;
1883	case CIL_CATALIASACTUAL:
1884		copy_func = &cil_copy_aliasactual;
1885		break;
1886	case CIL_CATSET:
1887		copy_func = &cil_copy_catset;
1888		break;
1889	case CIL_SENSCAT:
1890		copy_func = &cil_copy_senscat;
1891		break;
1892	case CIL_CATORDER:
1893		copy_func = &cil_copy_catorder;
1894		break;
1895	case CIL_SENSITIVITYORDER:
1896		copy_func = &cil_copy_sensitivityorder;
1897		break;
1898	case CIL_LEVEL:
1899		copy_func = &cil_copy_level;
1900		break;
1901	case CIL_LEVELRANGE:
1902		copy_func = &cil_copy_levelrange;
1903		break;
1904	case CIL_CONTEXT:
1905		copy_func = &cil_copy_context;
1906		break;
1907	case CIL_NETIFCON:
1908		copy_func = &cil_copy_netifcon;
1909		break;
1910	case CIL_GENFSCON:
1911		copy_func = &cil_copy_genfscon;
1912		break;
1913	case CIL_FILECON:
1914		copy_func = &cil_copy_filecon;
1915		break;
1916	case CIL_NODECON:
1917		copy_func = &cil_copy_nodecon;
1918		break;
1919	case CIL_PORTCON:
1920		copy_func = &cil_copy_portcon;
1921		break;
1922	case CIL_PIRQCON:
1923		copy_func = &cil_copy_pirqcon;
1924		break;
1925	case CIL_IOMEMCON:
1926		copy_func = &cil_copy_iomemcon;
1927		break;
1928	case CIL_IOPORTCON:
1929		copy_func = &cil_copy_ioportcon;
1930		break;
1931	case CIL_PCIDEVICECON:
1932		copy_func = &cil_copy_pcidevicecon;
1933		break;
1934	case CIL_DEVICETREECON:
1935		copy_func = &cil_copy_devicetreecon;
1936		break;
1937	case CIL_FSUSE:
1938		copy_func = &cil_copy_fsuse;
1939		break;
1940	case CIL_CONSTRAIN:
1941	case CIL_MLSCONSTRAIN:
1942		copy_func = &cil_copy_constrain;
1943		break;
1944	case CIL_VALIDATETRANS:
1945	case CIL_MLSVALIDATETRANS:
1946		copy_func = &cil_copy_validatetrans;
1947		break;
1948	case CIL_CALL:
1949		copy_func = &cil_copy_call;
1950		break;
1951	case CIL_MACRO:
1952		copy_func = &cil_copy_macro;
1953		break;
1954	case CIL_NODE:
1955		copy_func = &cil_copy_node;
1956		break;
1957	case CIL_OPTIONAL:
1958		copy_func = &cil_copy_optional;
1959		break;
1960	case CIL_IPADDR:
1961		copy_func = &cil_copy_ipaddr;
1962		break;
1963	case CIL_CONDBLOCK:
1964		copy_func = &cil_copy_condblock;
1965		break;
1966	case CIL_BOOLEANIF:
1967		copy_func = &cil_copy_boolif;
1968		break;
1969	case CIL_TUNABLEIF:
1970		copy_func = &cil_copy_tunif;
1971		break;
1972	case CIL_DEFAULTUSER:
1973	case CIL_DEFAULTROLE:
1974	case CIL_DEFAULTTYPE:
1975		copy_func = &cil_copy_default;
1976		break;
1977	case CIL_DEFAULTRANGE:
1978		copy_func = &cil_copy_defaultrange;
1979		break;
1980	case CIL_HANDLEUNKNOWN:
1981		copy_func = &cil_copy_handleunknown;
1982		break;
1983	case CIL_MLS:
1984		copy_func = &cil_copy_mls;
1985		break;
1986	case CIL_SRC_INFO:
1987		copy_func = &cil_copy_src_info;
1988		break;
1989	default:
1990		goto exit;
1991	}
1992
1993	if (orig->flavor >= CIL_MIN_DECLARATIVE) {
1994		rc = cil_flavor_to_symtab_index(orig->flavor, &sym_index);
1995		if (rc != SEPOL_OK) {
1996			goto exit;
1997		}
1998
1999		rc = cil_get_symtab(parent, &symtab, sym_index);
2000		if (rc != SEPOL_OK) {
2001			goto exit;
2002		}
2003	}
2004
2005	rc = (*copy_func)(db, orig->data, &data, symtab);
2006	if (rc == SEPOL_OK) {
2007		cil_tree_node_init(&new);
2008
2009		new->parent = parent;
2010		new->line = orig->line;
2011		new->hll_line = orig->hll_line;
2012		new->flavor = orig->flavor;
2013		new->data = data;
2014
2015		if (orig->flavor >= CIL_MIN_DECLARATIVE) {
2016			/* Check the flavor of data if was found in the destination symtab */
2017			if (DATUM(data)->nodes->head && FLAVOR(data) != orig->flavor) {
2018				cil_tree_log(orig, CIL_ERR, "Incompatible flavor when trying to copy %s", DATUM(data)->name);
2019				cil_tree_log(NODE(data), CIL_ERR, "Note: conflicting declaration");
2020				new->flavor = FLAVOR(data);
2021				rc = SEPOL_ERR;
2022				goto exit;
2023			}
2024			rc = cil_symtab_insert(symtab, ((struct cil_symtab_datum*)orig->data)->name, ((struct cil_symtab_datum*)data), new);
2025
2026			namespace = new;
2027			while (namespace->flavor != CIL_MACRO && namespace->flavor != CIL_BLOCK && namespace->flavor != CIL_ROOT) {
2028				namespace = namespace->parent;
2029			}
2030
2031			if (namespace->flavor == CIL_MACRO) {
2032				struct cil_macro *macro = namespace->data;
2033				struct cil_list *param_list = macro->params;
2034				if (param_list != NULL) {
2035					struct cil_list_item *item;
2036					cil_list_for_each(item, param_list) {
2037						param = item->data;
2038						if (param->flavor == new->flavor) {
2039							if (param->str == ((struct cil_symtab_datum*)new->data)->name) {
2040								cil_tree_log(orig, CIL_ERR, "%s %s shadows a macro parameter", cil_node_to_string(new), ((struct cil_symtab_datum*)orig->data)->name);
2041								cil_tree_log(namespace, CIL_ERR, "Note: macro declaration");
2042								rc = SEPOL_ERR;
2043								goto exit;
2044							}
2045						}
2046					}
2047				}
2048			}
2049		}
2050
2051		if (new->flavor == CIL_BLOCKINHERIT) {
2052			blockinherit = new->data;
2053			// if a blockinherit statement is copied before blockinherit are
2054			// resolved (like in an in-statement), the block will not have been
2055			// resolved yet, so there's nothing to append yet. This is fine,
2056			// the copied blockinherit statement will be handled later, as if
2057			// it wasn't in an in-statement
2058			if (blockinherit->block != NULL) {
2059				cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new);
2060			}
2061		}
2062
2063		if (parent->cl_head == NULL) {
2064			parent->cl_head = new;
2065			parent->cl_tail = new;
2066		} else {
2067			parent->cl_tail->next = new;
2068			parent->cl_tail = new;
2069		}
2070
2071		if (orig->cl_head != NULL) {
2072			args->dest = new;
2073		}
2074	} else {
2075		goto exit;
2076	}
2077
2078	return SEPOL_OK;
2079
2080exit:
2081	cil_tree_node_destroy(&new);
2082	return rc;
2083}
2084
2085int __cil_copy_last_child_helper(__attribute__((unused)) struct cil_tree_node *orig, void *extra_args)
2086{
2087	struct cil_tree_node *node = NULL;
2088	struct cil_args_copy *args = NULL;
2089
2090	args = extra_args;
2091	node = args->dest;
2092
2093	if (node->flavor != CIL_ROOT) {
2094		args->dest = node->parent;
2095	}
2096
2097	return SEPOL_OK;
2098}
2099
2100// dest is the parent node to copy into
2101// if the copy is for a call to a macro, dest should be a pointer to the call
2102int cil_copy_ast(struct cil_db *db, struct cil_tree_node *orig, struct cil_tree_node *dest)
2103{
2104	int rc = SEPOL_ERR;
2105	struct cil_args_copy extra_args;
2106
2107	extra_args.dest = dest;
2108	extra_args.db = db;
2109
2110	rc = cil_tree_walk(orig, __cil_copy_node_helper, NULL,  __cil_copy_last_child_helper, &extra_args);
2111	if (rc != SEPOL_OK) {
2112		cil_log(CIL_INFO, "cil_tree_walk failed, rc: %d\n", rc);
2113		goto exit;
2114	}
2115
2116	return SEPOL_OK;
2117
2118exit:
2119	return rc;
2120}
2121
2122