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