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_alias(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
652{
653	struct cil_alias *orig = data;
654	struct cil_alias *new = NULL;
655	char *key = orig->datum.name;
656	struct cil_symtab_datum *datum = NULL;
657
658	cil_symtab_get_datum(symtab, key, &datum);
659	if (datum != NULL) {
660		cil_log(CIL_INFO, "cil_copy_alias: alias cannot be redefined\n");
661		return SEPOL_ERR;
662	}
663
664	cil_alias_init(&new);
665
666	*copy = new;
667
668	return SEPOL_OK;
669}
670
671int cil_copy_aliasactual(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused))symtab_t *symtab)
672{
673	struct cil_aliasactual *orig = data;
674	struct cil_aliasactual *new = NULL;
675
676	cil_aliasactual_init(&new);
677
678	new->alias_str = orig->alias_str;
679	new->actual_str = orig->actual_str;
680
681	*copy = new;
682
683	return SEPOL_OK;
684}
685
686int cil_copy_roletransition(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
687{
688	struct cil_roletransition *orig = data;
689	struct cil_roletransition *new = NULL;
690
691	cil_roletransition_init(&new);
692
693	new->src_str = orig->src_str;
694	new->tgt_str = orig->tgt_str;
695	new->obj_str = orig->obj_str;
696	new->result_str = orig->result_str;
697
698	*copy = new;
699
700	return SEPOL_OK;
701}
702
703int cil_copy_nametypetransition(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
704{
705	struct cil_nametypetransition *orig = data;
706	struct cil_nametypetransition *new = NULL;
707
708	cil_nametypetransition_init(&new);
709
710	new->src_str = orig->src_str;
711	new->tgt_str = orig->tgt_str;
712	new->obj_str = orig->obj_str;
713	new->name_str = orig->name_str;
714	new->result_str = orig->result_str;
715
716
717	*copy = new;
718
719	return SEPOL_OK;
720}
721
722int cil_copy_rangetransition(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
723{
724	struct cil_rangetransition *orig = data;
725	struct cil_rangetransition *new = NULL;
726
727	cil_rangetransition_init(&new);
728
729	new->src_str = orig->src_str;
730	new->exec_str = orig->exec_str;
731	new->obj_str = orig->obj_str;
732
733	if (orig->range_str != NULL) {
734		new->range_str = orig->range_str;
735	} else {
736		cil_levelrange_init(&new->range);
737		cil_copy_fill_levelrange(db, orig->range, new->range);
738	}
739
740	*copy = new;
741
742	return SEPOL_OK;
743}
744
745int cil_copy_bool(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
746{
747	struct cil_bool *orig = data;
748	struct cil_bool *new = NULL;
749	char *key = orig->datum.name;
750	struct cil_symtab_datum *datum = NULL;
751
752	cil_symtab_get_datum(symtab, key, &datum);
753	if (datum != NULL) {
754		cil_log(CIL_INFO, "cil_copy_bool: boolean cannot be redefined\n");
755		return SEPOL_ERR;
756	}
757
758	cil_bool_init(&new);
759	new->value = orig->value;
760	*copy = new;
761
762	return SEPOL_OK;
763}
764
765int cil_copy_tunable(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
766{
767	struct cil_tunable *orig = data;
768	struct cil_tunable *new = NULL;
769	char *key = orig->datum.name;
770	struct cil_symtab_datum *datum = NULL;
771
772	cil_symtab_get_datum(symtab, key, &datum);
773	if (datum != NULL) {
774		cil_log(CIL_INFO, "cil_copy_tunable: tunable cannot be redefined\n");
775		return SEPOL_ERR;
776	}
777
778	cil_tunable_init(&new);
779	new->value = orig->value;
780	*copy = new;
781
782	return SEPOL_OK;
783}
784
785void cil_copy_fill_permissionx(struct cil_db *db, struct cil_permissionx *orig, struct cil_permissionx *new)
786{
787	new->kind = orig->kind;
788	new->obj_str = orig->obj_str;
789	cil_copy_expr(db, orig->expr_str, &new->expr_str);
790}
791
792int cil_copy_avrule(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
793{
794	struct cil_avrule *orig = data;
795	struct cil_avrule *new = NULL;
796
797	cil_avrule_init(&new);
798
799	new->is_extended = orig->is_extended;
800	new->rule_kind = orig->rule_kind;
801	new->src_str = orig->src_str;
802	new->tgt_str = orig->tgt_str;
803
804	if (!new->is_extended) {
805		cil_copy_classperms_list(orig->perms.classperms, &new->perms.classperms);
806	} else {
807		if (new->perms.x.permx_str != NULL) {
808			new->perms.x.permx_str = orig->perms.x.permx_str;
809		} else {
810			cil_permissionx_init(&new->perms.x.permx);
811			cil_copy_fill_permissionx(db, orig->perms.x.permx, new->perms.x.permx);
812		}
813	}
814
815	*copy = new;
816
817	return SEPOL_OK;
818}
819
820int cil_copy_permissionx(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
821{
822	struct cil_permissionx *orig = data;
823	struct cil_permissionx *new = NULL;
824	char *key = orig->datum.name;
825	struct cil_symtab_datum *datum = NULL;
826
827
828	cil_symtab_get_datum(symtab, key, &datum);
829	if (datum != NULL) {
830		cil_log(CIL_INFO, "cil_copy_permissionx: permissionx cannot be redefined\n");
831		return SEPOL_ERR;
832	}
833
834	cil_permissionx_init(&new);
835	cil_copy_fill_permissionx(db, orig, new);
836
837	*copy = new;
838
839	return SEPOL_OK;
840}
841
842int cil_copy_type_rule(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
843{
844	struct cil_type_rule  *orig = data;
845	struct cil_type_rule *new = NULL;
846
847	cil_type_rule_init(&new);
848
849	new->rule_kind = orig->rule_kind;
850	new->src_str = orig->src_str;
851	new->tgt_str = orig->tgt_str;
852	new->obj_str = orig->obj_str;
853	new->result_str = orig->result_str;
854
855	*copy = new;
856
857	return SEPOL_OK;
858}
859
860int cil_copy_sens(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
861{
862	struct cil_sens *orig = data;
863	char *key = orig->datum.name;
864	struct cil_symtab_datum *datum = NULL;
865
866	cil_symtab_get_datum(symtab, key, &datum);
867	if (datum == NULL) {
868		struct cil_sens *new;
869		cil_sens_init(&new);
870		*copy = new;
871	} else {
872		*copy = datum;
873	}
874
875	return SEPOL_OK;
876}
877
878int cil_copy_cat(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
879{
880	struct cil_cat *orig = data;
881	char *key = orig->datum.name;
882	struct cil_symtab_datum *datum = NULL;
883
884	cil_symtab_get_datum(symtab, key, &datum);
885	if (datum == NULL) {
886		struct cil_cat *new;
887		cil_cat_init(&new);
888		*copy = new;
889	} else {
890		*copy = datum;
891	}
892
893	return SEPOL_OK;
894}
895
896void cil_copy_cats(struct cil_db *db, struct cil_cats *orig, struct cil_cats **new)
897{
898	cil_cats_init(new);
899	cil_copy_expr(db, orig->str_expr, &(*new)->str_expr);
900	cil_copy_expr(db, orig->datum_expr, &(*new)->datum_expr);
901}
902
903int cil_copy_catset(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
904{
905	struct cil_catset *orig = data;
906	struct cil_catset *new = NULL;
907	char *key = orig->datum.name;
908	struct cil_symtab_datum *datum = NULL;
909
910	cil_symtab_get_datum(symtab, key, &datum);
911	if (datum != NULL) {
912		cil_log(CIL_INFO, "cil_copy_catset: categoryset cannot be redefined\n");
913		return SEPOL_ERR;
914	}
915
916	cil_catset_init(&new);
917
918	cil_copy_cats(db, orig->cats, &new->cats);
919
920	*copy = new;
921
922	return SEPOL_OK;
923}
924
925int cil_copy_senscat(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
926{
927	struct cil_senscat *orig = data;
928	struct cil_senscat *new = NULL;
929
930	cil_senscat_init(&new);
931
932	new->sens_str = orig->sens_str;
933
934	cil_copy_cats(db, orig->cats, &new->cats);
935
936	*copy = new;
937
938	return SEPOL_OK;
939}
940
941int cil_copy_catorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
942{
943	struct cil_catorder *orig = data;
944	struct cil_catorder *new = NULL;
945
946	cil_catorder_init(&new);
947	if (orig->cat_list_str != NULL) {
948		cil_copy_list(orig->cat_list_str, &new->cat_list_str);
949	}
950
951	*copy = new;
952
953	return SEPOL_OK;
954}
955
956int cil_copy_sensitivityorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
957{
958	struct cil_sensorder *orig = data;
959	struct cil_sensorder *new = NULL;
960
961	cil_sensorder_init(&new);
962	if (orig->sens_list_str != NULL) {
963		cil_copy_list(orig->sens_list_str, &new->sens_list_str);
964	}
965
966	*copy = new;
967
968	return SEPOL_OK;
969}
970
971void cil_copy_fill_level(struct cil_db *db, struct cil_level *orig, struct cil_level **new)
972{
973	cil_level_init(new);
974
975	(*new)->sens_str = orig->sens_str;
976
977	if (orig->cats != NULL) {
978		cil_copy_cats(db, orig->cats, &(*new)->cats);
979	}
980}
981
982int cil_copy_level(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
983{
984	struct cil_level *orig = data;
985	struct cil_level *new = NULL;
986	char *key = orig->datum.name;
987	struct cil_symtab_datum *datum = NULL;
988
989	if (key != NULL) {
990		cil_symtab_get_datum(symtab, key, &datum);
991		if (datum != NULL) {
992			cil_log(CIL_INFO, "cil_copy_level: level cannot be redefined\n");
993			return SEPOL_ERR;
994		}
995	}
996
997	cil_copy_fill_level(db, orig, &new);
998
999	*copy = new;
1000
1001	return SEPOL_OK;
1002}
1003
1004void cil_copy_fill_levelrange(struct cil_db *db, struct cil_levelrange *data, struct cil_levelrange *new)
1005{
1006	if (data->low_str != NULL) {
1007		new->low_str = data->low_str;
1008	} else {
1009		cil_copy_fill_level(db, data->low, &new->low);
1010	}
1011
1012	if (data->high_str != NULL) {
1013		new->high_str = data->high_str;
1014	} else {
1015		cil_copy_fill_level(db, data->high, &new->high);
1016	}
1017}
1018
1019int cil_copy_levelrange(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1020{
1021	struct cil_levelrange *orig = data;
1022	struct cil_levelrange *new = NULL;
1023	char *key = orig->datum.name;
1024	struct cil_symtab_datum *datum = NULL;
1025
1026	if (key != NULL) {
1027		cil_symtab_get_datum(symtab, key, &datum);
1028		if (datum != NULL) {
1029			cil_log(CIL_INFO, "cil_copy_levelrange: levelrange cannot be redefined\n");
1030			return SEPOL_ERR;
1031		}
1032	}
1033
1034	cil_levelrange_init(&new);
1035	cil_copy_fill_levelrange(db, orig, new);
1036
1037	*copy = new;
1038
1039	return SEPOL_OK;
1040}
1041
1042void cil_copy_fill_context(struct cil_db *db, struct cil_context *data, struct cil_context *new)
1043{
1044	new->user_str = data->user_str;
1045	new->role_str = data->role_str;
1046	new->type_str = data->type_str;
1047
1048	if (data->range_str != NULL) {
1049		new->range_str = data->range_str;
1050	} else {
1051		cil_levelrange_init(&new->range);
1052		cil_copy_fill_levelrange(db, data->range, new->range);
1053	}
1054}
1055
1056int cil_copy_context(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1057{
1058	struct cil_context *orig = data;
1059	struct cil_context *new = NULL;
1060	char *key = orig->datum.name;
1061	struct cil_symtab_datum *datum = NULL;
1062
1063	if (key != NULL) {
1064		cil_symtab_get_datum(symtab, key, &datum);
1065		if (datum != NULL) {
1066			cil_log(CIL_INFO, "cil_copy_context: context cannot be redefined\n");
1067			return SEPOL_ERR;
1068		}
1069	}
1070
1071	cil_context_init(&new);
1072	cil_copy_fill_context(db, orig, new);
1073
1074	*copy = new;
1075
1076	return SEPOL_OK;
1077}
1078
1079int cil_copy_netifcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1080{
1081	struct cil_netifcon *orig = data;
1082	struct cil_netifcon *new = NULL;
1083
1084	cil_netifcon_init(&new);
1085
1086	new->interface_str = orig->interface_str;
1087
1088	if (orig->if_context_str != NULL) {
1089		new->if_context_str = orig->if_context_str;
1090	} else {
1091		cil_context_init(&new->if_context);
1092		cil_copy_fill_context(db, orig->if_context, new->if_context);
1093	}
1094
1095	if (orig->packet_context_str != NULL) {
1096		new->packet_context_str = orig->packet_context_str;
1097	} else {
1098		cil_context_init(&new->packet_context);
1099		cil_copy_fill_context(db, orig->packet_context, new->packet_context);
1100	}
1101
1102	*copy = new;
1103
1104	return SEPOL_OK;
1105}
1106
1107int cil_copy_genfscon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1108{
1109	struct cil_genfscon *orig = data;
1110	struct cil_genfscon *new = NULL;
1111
1112	cil_genfscon_init(&new);
1113
1114	new->fs_str = orig->fs_str;
1115	new->path_str = orig->path_str;
1116
1117	if (orig->context_str != NULL) {
1118		new->context_str = orig->context_str;
1119	} else {
1120		cil_context_init(&new->context);
1121		cil_copy_fill_context(db, orig->context, new->context);
1122	}
1123
1124	*copy = new;
1125
1126	return SEPOL_OK;
1127}
1128
1129int cil_copy_filecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1130{
1131	struct cil_filecon *orig = data;
1132	struct cil_filecon *new = NULL;
1133
1134	cil_filecon_init(&new);
1135
1136	new->path_str = orig->path_str;
1137	new->type = orig->type;
1138
1139	if (orig->context_str != NULL) {
1140		new->context_str = orig->context_str;
1141	} else if (orig->context != NULL) {
1142		cil_context_init(&new->context);
1143		cil_copy_fill_context(db, orig->context, new->context);
1144	}
1145
1146	*copy = new;
1147
1148	return SEPOL_OK;
1149}
1150
1151int cil_copy_nodecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1152{
1153	struct cil_nodecon *orig = data;
1154	struct cil_nodecon *new = NULL;
1155
1156	cil_nodecon_init(&new);
1157
1158	if (orig->addr_str != NULL) {
1159		new->addr_str = orig->addr_str;
1160	} else {
1161		cil_ipaddr_init(&new->addr);
1162		cil_copy_fill_ipaddr(orig->addr, new->addr);
1163	}
1164
1165	if (orig->mask_str != NULL) {
1166		new->mask_str = orig->mask_str;
1167	} else {
1168		cil_ipaddr_init(&new->mask);
1169		cil_copy_fill_ipaddr(orig->mask, new->mask);
1170	}
1171
1172	if (orig->context_str != NULL) {
1173		new->context_str = orig->context_str;
1174	} else {
1175		cil_context_init(&new->context);
1176		cil_copy_fill_context(db, orig->context, new->context);
1177	}
1178
1179	*copy = new;
1180
1181	return SEPOL_OK;
1182}
1183
1184int cil_copy_portcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1185{
1186	struct cil_portcon *orig = data;
1187	struct cil_portcon *new = NULL;
1188
1189	cil_portcon_init(&new);
1190
1191	new->proto = orig->proto;
1192	new->port_low = orig->port_low;
1193	new->port_high = orig->port_high;
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_pirqcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1208{
1209	struct cil_pirqcon *orig = data;
1210	struct cil_pirqcon *new = NULL;
1211
1212	cil_pirqcon_init(&new);
1213
1214	new->pirq = orig->pirq;
1215
1216	if (orig->context_str != NULL) {
1217		new->context_str = orig->context_str;
1218	} else {
1219		cil_context_init(&new->context);
1220		cil_copy_fill_context(db, orig->context, new->context);
1221	}
1222
1223	*copy = new;
1224
1225	return SEPOL_OK;
1226}
1227
1228int cil_copy_iomemcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1229{
1230	struct cil_iomemcon *orig = data;
1231	struct cil_iomemcon *new = NULL;
1232
1233	cil_iomemcon_init(&new);
1234
1235	new->iomem_low = orig->iomem_low;
1236	new->iomem_high = orig->iomem_high;
1237
1238	if (orig->context_str != NULL) {
1239		new->context_str = orig->context_str;
1240	} else {
1241		cil_context_init(&new->context);
1242		cil_copy_fill_context(db, orig->context, new->context);
1243	}
1244
1245	*copy = new;
1246
1247	return SEPOL_OK;
1248}
1249
1250int cil_copy_ioportcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1251{
1252	struct cil_ioportcon *orig = data;
1253	struct cil_ioportcon *new = NULL;
1254
1255	cil_ioportcon_init(&new);
1256
1257	new->ioport_low = orig->ioport_low;
1258	new->ioport_high = orig->ioport_high;
1259
1260	if (orig->context_str != NULL) {
1261		new->context_str = orig->context_str;
1262	} else {
1263		cil_context_init(&new->context);
1264		cil_copy_fill_context(db, orig->context, new->context);
1265	}
1266
1267	*copy = new;
1268
1269	return SEPOL_OK;
1270}
1271
1272int cil_copy_pcidevicecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1273{
1274	struct cil_pcidevicecon *orig = data;
1275	struct cil_pcidevicecon *new = NULL;
1276
1277	cil_pcidevicecon_init(&new);
1278
1279	new->dev = orig->dev;
1280
1281	if (orig->context_str != NULL) {
1282		new->context_str = orig->context_str;
1283	} else {
1284		cil_context_init(&new->context);
1285		cil_copy_fill_context(db, orig->context, new->context);
1286	}
1287
1288	*copy = new;
1289
1290	return SEPOL_OK;
1291}
1292
1293int cil_copy_devicetreecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1294{
1295	struct cil_devicetreecon *orig = data;
1296	struct cil_devicetreecon *new = NULL;
1297
1298	cil_devicetreecon_init(&new);
1299
1300	new->path = orig->path;
1301
1302	if (orig->context_str != NULL) {
1303		new->context_str = orig->context_str;
1304	} else {
1305		cil_context_init(&new->context);
1306		cil_copy_fill_context(db, orig->context, new->context);
1307	}
1308
1309	*copy = new;
1310
1311	return SEPOL_OK;
1312}
1313
1314int cil_copy_fsuse(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1315{
1316	struct cil_fsuse *orig = data;
1317	struct cil_fsuse *new = NULL;
1318
1319	cil_fsuse_init(&new);
1320
1321	new->type = orig->type;
1322	new->fs_str = orig->fs_str;
1323
1324	if (orig->context_str != NULL) {
1325		new->context_str = orig->context_str;
1326	} else {
1327		cil_context_init(&new->context);
1328		cil_copy_fill_context(db, orig->context, new->context);
1329	}
1330
1331	*copy = new;
1332
1333	return SEPOL_OK;
1334}
1335
1336int cil_copy_expr(struct cil_db *db, struct cil_list *orig, struct cil_list **new)
1337{
1338	struct cil_list_item *curr;
1339
1340	if (orig == NULL) {
1341		*new = NULL;
1342		return SEPOL_OK;
1343	}
1344
1345	cil_list_init(new, orig->flavor);
1346
1347	cil_list_for_each(curr, orig) {
1348		switch (curr->flavor) {
1349		case CIL_LIST: {
1350			struct cil_list *sub_list;
1351			cil_copy_expr(db, curr->data, &sub_list);
1352			cil_list_append(*new, CIL_LIST, sub_list);
1353			break;
1354		}
1355		case CIL_STRING:
1356			cil_list_append(*new, CIL_STRING, curr->data);
1357			break;
1358		case CIL_DATUM:
1359			cil_list_append(*new, curr->flavor, curr->data);
1360			break;
1361		case CIL_OP:
1362			cil_list_append(*new, curr->flavor, curr->data);
1363			break;
1364		case CIL_CONS_OPERAND:
1365			cil_list_append(*new, curr->flavor, curr->data);
1366			break;
1367		default:
1368			cil_log(CIL_INFO, "Unknown flavor %d in expression being copied\n",curr->flavor);
1369			cil_list_append(*new, curr->flavor, curr->data);
1370			break;
1371		}
1372	}
1373
1374	return SEPOL_OK;
1375}
1376
1377int cil_copy_constrain(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1378{
1379	struct cil_constrain *orig = data;
1380	struct cil_constrain *new = NULL;
1381
1382	cil_constrain_init(&new);
1383	cil_copy_classperms_list(orig->classperms, &new->classperms);
1384
1385	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1386	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1387
1388	*copy = new;
1389
1390	return SEPOL_OK;
1391}
1392
1393int cil_copy_validatetrans(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1394{
1395	struct cil_validatetrans *orig = data;
1396	struct cil_validatetrans *new = NULL;
1397
1398	cil_validatetrans_init(&new);
1399
1400	new->class_str = orig->class_str;
1401
1402	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1403	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1404
1405	*copy = new;
1406
1407	return SEPOL_OK;
1408}
1409
1410int cil_copy_call(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1411{
1412	struct cil_call *orig = data;
1413	struct cil_call *new = NULL;
1414	int rc = SEPOL_ERR;
1415
1416	cil_call_init(&new);
1417
1418	new->macro_str = orig->macro_str;
1419	new->macro = orig->macro;
1420
1421	if (orig->args_tree != NULL) {
1422		cil_tree_init(&new->args_tree);
1423		rc = cil_copy_ast(db, orig->args_tree->root, new->args_tree->root);
1424		if (rc != SEPOL_OK) {
1425			goto exit;
1426		}
1427	}
1428
1429	new->copied = orig->copied;
1430
1431	*copy = new;
1432
1433	return SEPOL_OK;
1434
1435exit:
1436	cil_destroy_call(new);
1437	return rc;
1438}
1439
1440int cil_copy_macro(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1441{
1442	struct cil_macro *orig = data;
1443	char *key = orig->datum.name;
1444	struct cil_symtab_datum *datum = NULL;
1445
1446	cil_symtab_get_datum(symtab, key, &datum);
1447	if (datum == NULL) {
1448		struct cil_macro *new;
1449		cil_macro_init(&new);
1450		if (orig->params != NULL) {
1451			cil_copy_list(orig->params, &new->params);
1452		}
1453
1454		*copy = new;
1455
1456	} else {
1457		struct cil_list_item *curr_orig = NULL;
1458		struct cil_list_item *curr_new = NULL;
1459		struct cil_param *param_orig = NULL;
1460		struct cil_param *param_new = NULL;
1461
1462		if (((struct cil_macro*)datum)->params != NULL) {
1463			curr_new = ((struct cil_macro*)datum)->params->head;
1464		}
1465
1466		if (orig->params != NULL) {
1467			curr_orig = orig->params->head;
1468		}
1469
1470		if (curr_orig != NULL && curr_new != NULL) {
1471			while (curr_orig != NULL) {
1472				if (curr_new == NULL) {
1473					goto exit;
1474				}
1475
1476				param_orig = (struct cil_param*)curr_orig->data;
1477				param_new = (struct cil_param*)curr_new->data;
1478				if (param_orig->str != param_new->str) {
1479					goto exit;
1480				} else if (param_orig->flavor != param_new->flavor) {
1481					goto exit;
1482				}
1483
1484				curr_orig = curr_orig->next;
1485				curr_new = curr_new->next;
1486			}
1487
1488			if (curr_new != NULL) {
1489				goto exit;
1490			}
1491		} else if (!(curr_orig == NULL && curr_new == NULL)) {
1492			goto exit;
1493		}
1494
1495		*copy = datum;
1496	}
1497
1498	return SEPOL_OK;
1499
1500exit:
1501	cil_log(CIL_INFO, "cil_copy_macro: macro cannot be redefined\n");
1502	return SEPOL_ERR;
1503}
1504
1505int cil_copy_optional(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1506{
1507	struct cil_optional *orig = data;
1508	char *key = orig->datum.name;
1509	struct cil_symtab_datum *datum = NULL;
1510
1511	cil_symtab_get_datum(symtab, key, &datum);
1512	if (datum == NULL) {
1513		struct cil_optional *new;
1514		cil_optional_init(&new);
1515		*copy = new;
1516	} else {
1517		*copy = datum;
1518	}
1519
1520	return SEPOL_OK;
1521}
1522
1523void cil_copy_fill_ipaddr(struct cil_ipaddr *data, struct cil_ipaddr *new)
1524{
1525	new->family = data->family;
1526	memcpy(&new->ip, &data->ip, sizeof(data->ip));
1527}
1528
1529int cil_copy_ipaddr(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
1530{
1531	struct cil_ipaddr *orig = data;
1532	struct cil_ipaddr *new = NULL;
1533	char * key = orig->datum.name;
1534	struct cil_symtab_datum *datum = NULL;
1535
1536	cil_symtab_get_datum(symtab, key, &datum);
1537	if (datum != NULL) {
1538		cil_log(CIL_INFO, "cil_copy_ipaddr: ipaddress cannot be redefined\n");
1539		return SEPOL_ERR;
1540	}
1541
1542	cil_ipaddr_init(&new);
1543	cil_copy_fill_ipaddr(orig, new);
1544
1545	*copy = new;
1546
1547	return SEPOL_OK;
1548}
1549
1550int cil_copy_condblock(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1551{
1552	struct cil_condblock *orig = data;
1553	struct cil_condblock *new = *copy;
1554	cil_condblock_init(&new);
1555	new->flavor = orig->flavor;
1556	*copy = new;
1557
1558	return SEPOL_OK;
1559}
1560
1561int cil_copy_boolif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1562{
1563	struct cil_booleanif *orig = data;
1564	struct cil_booleanif *new = NULL;
1565
1566	cil_boolif_init(&new);
1567
1568	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1569	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1570	new->preserved_tunable = orig->preserved_tunable;
1571
1572	*copy = new;
1573
1574	return SEPOL_OK;
1575}
1576
1577int cil_copy_tunif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1578{
1579	struct cil_tunableif *orig = data;
1580	struct cil_tunableif *new = NULL;
1581
1582	cil_tunif_init(&new);
1583
1584	cil_copy_expr(db, orig->str_expr, &new->str_expr);
1585	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1586
1587	*copy = new;
1588
1589	return SEPOL_OK;
1590}
1591
1592int cil_copy_default(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1593{
1594	struct cil_default *orig = data;
1595	struct cil_default *new = NULL;
1596
1597	cil_default_init(&new);
1598
1599	new->flavor = orig->flavor;
1600
1601	if (orig->class_strs != NULL) {
1602		cil_copy_list(orig->class_strs, &new->class_strs);
1603	}
1604
1605	new->object = orig->object;
1606
1607	*copy = new;
1608
1609	return SEPOL_OK;
1610}
1611
1612int cil_copy_defaultrange(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1613{
1614	struct cil_defaultrange *orig = data;
1615	struct cil_defaultrange *new = NULL;
1616
1617	cil_defaultrange_init(&new);
1618
1619	if (orig->class_strs != NULL) {
1620		cil_copy_list(orig->class_strs, &new->class_strs);
1621	}
1622
1623	new->object_range = orig->object_range;
1624
1625	*copy = new;
1626
1627	return SEPOL_OK;
1628}
1629
1630int cil_copy_handleunknown(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1631{
1632	struct cil_handleunknown *orig = data;
1633	struct cil_handleunknown *new = NULL;
1634
1635	cil_handleunknown_init(&new);
1636	new->handle_unknown = orig->handle_unknown;
1637	*copy = new;
1638
1639	return SEPOL_OK;
1640}
1641
1642int cil_copy_mls(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1643{
1644	struct cil_mls *orig = data;
1645	struct cil_mls *new = NULL;
1646
1647	cil_mls_init(&new);
1648	new->value = orig->value;
1649	*copy = new;
1650
1651	return SEPOL_OK;
1652}
1653
1654int cil_copy_bounds(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1655{
1656	struct cil_bounds *orig = data;
1657	struct cil_bounds *new = NULL;
1658
1659	cil_bounds_init(&new);
1660
1661	new->parent_str = orig->parent_str;
1662	new->child_str = orig->child_str;
1663
1664	*copy = new;
1665
1666	return SEPOL_OK;
1667}
1668
1669int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) uint32_t *finished, void *extra_args)
1670{
1671	int rc = SEPOL_ERR;
1672	struct cil_tree_node *parent = NULL;
1673	struct cil_tree_node *new = NULL;
1674	struct cil_db *db = NULL;
1675	struct cil_args_copy *args = NULL;
1676	struct cil_tree_node *namespace = NULL;
1677	struct cil_param *param = NULL;
1678	enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
1679	symtab_t *symtab = NULL;
1680	void *data = NULL;
1681	int (*copy_func)(struct cil_db *db, void *data, void **copy, symtab_t *symtab) = NULL;
1682	struct cil_blockinherit *blockinherit = NULL;
1683
1684	if (orig == NULL || extra_args == NULL) {
1685		goto exit;
1686	}
1687
1688	args = extra_args;
1689	parent = args->dest;
1690	db = args->db;
1691
1692
1693	switch (orig->flavor) {
1694	case CIL_BLOCK:
1695		copy_func = &cil_copy_block;
1696		break;
1697	case CIL_BLOCKABSTRACT:
1698		copy_func = &cil_copy_blockabstract;
1699		break;
1700	case CIL_BLOCKINHERIT:
1701		copy_func = &cil_copy_blockinherit;
1702		break;
1703	case CIL_POLICYCAP:
1704		copy_func = &cil_copy_policycap;
1705		break;
1706	case CIL_PERM:
1707	case CIL_MAP_PERM:
1708		copy_func = &cil_copy_perm;
1709		break;
1710	case CIL_CLASSMAPPING:
1711		copy_func = &cil_copy_classmapping;
1712		break;
1713	case CIL_CLASS:
1714	case CIL_COMMON:
1715	case CIL_MAP_CLASS:
1716		copy_func = &cil_copy_class;
1717		break;
1718	case CIL_CLASSORDER:
1719		copy_func = &cil_copy_classorder;
1720		break;
1721	case CIL_CLASSPERMISSION:
1722		copy_func = &cil_copy_classpermission;
1723		break;
1724	case CIL_CLASSPERMISSIONSET:
1725		copy_func = &cil_copy_classpermissionset;
1726		break;
1727	case CIL_CLASSCOMMON:
1728		copy_func = &cil_copy_classcommon;
1729		break;
1730	case CIL_SID:
1731		copy_func = &cil_copy_sid;
1732		break;
1733	case CIL_SIDCONTEXT:
1734		copy_func = &cil_copy_sidcontext;
1735		break;
1736	case CIL_SIDORDER:
1737		copy_func = &cil_copy_sidorder;
1738		break;
1739	case CIL_USER:
1740		copy_func = &cil_copy_user;
1741		break;
1742	case CIL_USERATTRIBUTE:
1743		copy_func = &cil_copy_userattribute;
1744		break;
1745	case CIL_USERATTRIBUTESET:
1746		copy_func = &cil_copy_userattributeset;
1747		break;
1748	case CIL_USERROLE:
1749		copy_func = &cil_copy_userrole;
1750		break;
1751	case CIL_USERLEVEL:
1752		copy_func = &cil_copy_userlevel;
1753		break;
1754	case CIL_USERRANGE:
1755		copy_func = &cil_copy_userrange;
1756		break;
1757	case CIL_USERBOUNDS:
1758		copy_func = &cil_copy_bounds;
1759		break;
1760	case CIL_USERPREFIX:
1761		copy_func = &cil_copy_userprefix;
1762		break;
1763	case CIL_ROLE:
1764		copy_func = &cil_copy_role;
1765		break;
1766	case CIL_ROLETYPE:
1767		copy_func = &cil_copy_roletype;
1768		break;
1769	case CIL_ROLEBOUNDS:
1770		copy_func = &cil_copy_bounds;
1771		break;
1772	case CIL_ROLEATTRIBUTE:
1773		copy_func = &cil_copy_roleattribute;
1774		break;
1775	case CIL_ROLEATTRIBUTESET:
1776		copy_func = &cil_copy_roleattributeset;
1777		break;
1778	case CIL_ROLEALLOW:
1779		copy_func = &cil_copy_roleallow;
1780		break;
1781	case CIL_TYPE:
1782		copy_func = &cil_copy_type;
1783		break;
1784	case CIL_TYPEBOUNDS:
1785		copy_func = &cil_copy_bounds;
1786		break;
1787	case CIL_TYPEPERMISSIVE:
1788		copy_func = cil_copy_typepermissive;
1789		break;
1790	case CIL_TYPEATTRIBUTE:
1791		copy_func = &cil_copy_typeattribute;
1792		break;
1793	case CIL_TYPEATTRIBUTESET:
1794		copy_func = &cil_copy_typeattributeset;
1795		break;
1796	case CIL_TYPEALIAS:
1797		copy_func = &cil_copy_alias;
1798		break;
1799	case CIL_TYPEALIASACTUAL:
1800		copy_func = &cil_copy_aliasactual;
1801		break;
1802	case CIL_ROLETRANSITION:
1803		copy_func = &cil_copy_roletransition;
1804		break;
1805	case CIL_NAMETYPETRANSITION:
1806		copy_func = &cil_copy_nametypetransition;
1807		break;
1808	case CIL_RANGETRANSITION:
1809		copy_func = &cil_copy_rangetransition;
1810		break;
1811	case CIL_TUNABLE:
1812		copy_func = &cil_copy_tunable;
1813		break;
1814	case CIL_BOOL:
1815		copy_func = &cil_copy_bool;
1816		break;
1817	case CIL_AVRULE:
1818	case CIL_AVRULEX:
1819		copy_func = &cil_copy_avrule;
1820		break;
1821	case CIL_PERMISSIONX:
1822		copy_func = &cil_copy_permissionx;
1823		break;
1824	case CIL_TYPE_RULE:
1825		copy_func = &cil_copy_type_rule;
1826		break;
1827	case CIL_SENS:
1828		copy_func = &cil_copy_sens;
1829		break;
1830	case CIL_SENSALIAS:
1831		copy_func = &cil_copy_alias;
1832		break;
1833	case CIL_SENSALIASACTUAL:
1834		copy_func = &cil_copy_aliasactual;
1835		break;
1836	case CIL_CAT:
1837		copy_func = &cil_copy_cat;
1838		break;
1839	case CIL_CATALIAS:
1840		copy_func = &cil_copy_alias;
1841		break;
1842	case CIL_CATALIASACTUAL:
1843		copy_func = &cil_copy_aliasactual;
1844		break;
1845	case CIL_CATSET:
1846		copy_func = &cil_copy_catset;
1847		break;
1848	case CIL_SENSCAT:
1849		copy_func = &cil_copy_senscat;
1850		break;
1851	case CIL_CATORDER:
1852		copy_func = &cil_copy_catorder;
1853		break;
1854	case CIL_SENSITIVITYORDER:
1855		copy_func = &cil_copy_sensitivityorder;
1856		break;
1857	case CIL_LEVEL:
1858		copy_func = &cil_copy_level;
1859		break;
1860	case CIL_LEVELRANGE:
1861		copy_func = &cil_copy_levelrange;
1862		break;
1863	case CIL_CONTEXT:
1864		copy_func = &cil_copy_context;
1865		break;
1866	case CIL_NETIFCON:
1867		copy_func = &cil_copy_netifcon;
1868		break;
1869	case CIL_GENFSCON:
1870		copy_func = &cil_copy_genfscon;
1871		break;
1872	case CIL_FILECON:
1873		copy_func = &cil_copy_filecon;
1874		break;
1875	case CIL_NODECON:
1876		copy_func = &cil_copy_nodecon;
1877		break;
1878	case CIL_PORTCON:
1879		copy_func = &cil_copy_portcon;
1880		break;
1881	case CIL_PIRQCON:
1882		copy_func = &cil_copy_pirqcon;
1883		break;
1884	case CIL_IOMEMCON:
1885		copy_func = &cil_copy_iomemcon;
1886		break;
1887	case CIL_IOPORTCON:
1888		copy_func = &cil_copy_ioportcon;
1889		break;
1890	case CIL_PCIDEVICECON:
1891		copy_func = &cil_copy_pcidevicecon;
1892		break;
1893	case CIL_DEVICETREECON:
1894		copy_func = &cil_copy_devicetreecon;
1895		break;
1896	case CIL_FSUSE:
1897		copy_func = &cil_copy_fsuse;
1898		break;
1899	case CIL_CONSTRAIN:
1900	case CIL_MLSCONSTRAIN:
1901		copy_func = &cil_copy_constrain;
1902		break;
1903	case CIL_VALIDATETRANS:
1904	case CIL_MLSVALIDATETRANS:
1905		copy_func = &cil_copy_validatetrans;
1906		break;
1907	case CIL_CALL:
1908		copy_func = &cil_copy_call;
1909		break;
1910	case CIL_MACRO:
1911		copy_func = &cil_copy_macro;
1912		break;
1913	case CIL_NODE:
1914		copy_func = &cil_copy_node;
1915		break;
1916	case CIL_OPTIONAL:
1917		copy_func = &cil_copy_optional;
1918		break;
1919	case CIL_IPADDR:
1920		copy_func = &cil_copy_ipaddr;
1921		break;
1922	case CIL_CONDBLOCK:
1923		copy_func = &cil_copy_condblock;
1924		break;
1925	case CIL_BOOLEANIF:
1926		copy_func = &cil_copy_boolif;
1927		break;
1928	case CIL_TUNABLEIF:
1929		copy_func = &cil_copy_tunif;
1930		break;
1931	case CIL_DEFAULTUSER:
1932	case CIL_DEFAULTROLE:
1933	case CIL_DEFAULTTYPE:
1934		copy_func = &cil_copy_default;
1935		break;
1936	case CIL_DEFAULTRANGE:
1937		copy_func = &cil_copy_defaultrange;
1938		break;
1939	case CIL_HANDLEUNKNOWN:
1940		copy_func = &cil_copy_handleunknown;
1941		break;
1942	case CIL_MLS:
1943		copy_func = &cil_copy_mls;
1944		break;
1945	default:
1946		goto exit;
1947	}
1948
1949	if (orig->flavor >= CIL_MIN_DECLARATIVE) {
1950		rc = cil_flavor_to_symtab_index(orig->flavor, &sym_index);
1951		if (rc != SEPOL_OK) {
1952			goto exit;
1953		}
1954
1955		rc = cil_get_symtab(parent, &symtab, sym_index);
1956		if (rc != SEPOL_OK) {
1957			goto exit;
1958		}
1959	}
1960
1961	rc = (*copy_func)(db, orig->data, &data, symtab);
1962	if (rc == SEPOL_OK) {
1963		cil_tree_node_init(&new);
1964
1965		new->parent = parent;
1966		new->line = orig->line;
1967		new->path = orig->path;
1968		new->flavor = orig->flavor;
1969		new->data = data;
1970
1971		if (orig->flavor >= CIL_MIN_DECLARATIVE) {
1972			rc = cil_symtab_insert(symtab, ((struct cil_symtab_datum*)orig->data)->name, ((struct cil_symtab_datum*)data), new);
1973
1974			namespace = new;
1975			while (namespace->flavor != CIL_MACRO && namespace->flavor != CIL_BLOCK && namespace->flavor != CIL_ROOT) {
1976				namespace = namespace->parent;
1977			}
1978
1979			if (namespace->flavor == CIL_MACRO) {
1980				struct cil_macro *macro = namespace->data;
1981				struct cil_list *param_list = macro->params;
1982				if (param_list != NULL) {
1983					struct cil_list_item *item;
1984					cil_list_for_each(item, param_list) {
1985						param = item->data;
1986						if (param->flavor == new->flavor) {
1987							if (param->str == ((struct cil_symtab_datum*)new->data)->name) {
1988								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);
1989								cil_log(CIL_ERR, "Note: macro declaration (%s line:%d)\n", namespace->path, namespace->line);
1990								rc = SEPOL_ERR;
1991								goto exit;
1992							}
1993						}
1994					}
1995				}
1996			}
1997		}
1998
1999		if (new->flavor == CIL_BLOCKINHERIT) {
2000			blockinherit = new->data;
2001			// if a blockinherit statement is copied before blockinherit are
2002			// resolved (like in an in-statement), the block will not have been
2003			// resolved yet, so there's nothing to append yet. This is fine,
2004			// the copied blockinherit statement will be handled later, as if
2005			// it wasn't in an in-statement
2006			if (blockinherit->block != NULL) {
2007				cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new);
2008			}
2009		}
2010
2011		if (parent->cl_head == NULL) {
2012			parent->cl_head = new;
2013			parent->cl_tail = new;
2014		} else {
2015			parent->cl_tail->next = new;
2016			parent->cl_tail = new;
2017		}
2018
2019		if (orig->cl_head != NULL) {
2020			args->dest = new;
2021		}
2022	} else {
2023		goto exit;
2024	}
2025
2026	return SEPOL_OK;
2027
2028exit:
2029	cil_tree_node_destroy(&new);
2030	return rc;
2031}
2032
2033int __cil_copy_last_child_helper(__attribute__((unused)) struct cil_tree_node *orig, void *extra_args)
2034{
2035	struct cil_tree_node *node = NULL;
2036	struct cil_args_copy *args = NULL;
2037
2038	args = extra_args;
2039	node = args->dest;
2040
2041	if (node->flavor != CIL_ROOT) {
2042		args->dest = node->parent;
2043	}
2044
2045	return SEPOL_OK;
2046}
2047
2048// dest is the parent node to copy into
2049// if the copy is for a call to a macro, dest should be a pointer to the call
2050int cil_copy_ast(struct cil_db *db, struct cil_tree_node *orig, struct cil_tree_node *dest)
2051{
2052	int rc = SEPOL_ERR;
2053	struct cil_args_copy extra_args;
2054
2055	extra_args.dest = dest;
2056	extra_args.db = db;
2057
2058	rc = cil_tree_walk(orig, __cil_copy_node_helper, NULL,  __cil_copy_last_child_helper, &extra_args);
2059	if (rc != SEPOL_OK) {
2060		cil_log(CIL_INFO, "cil_tree_walk failed, rc: %d\n", rc);
2061		goto exit;
2062	}
2063
2064	return SEPOL_OK;
2065
2066exit:
2067	return rc;
2068}
2069
2070