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_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 
    671 int 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 
    686 int 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 
    703 int 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 
    722 int 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 
    745 int 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 
    765 int 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 
    785 void 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 
    792 int 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 
    820 int 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 
    842 int 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 
    860 int 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 
    878 int 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 
    896 void 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 
    903 int 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 
    925 int 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 
    941 int 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 
    956 int 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 
    971 void 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 
    982 int 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 
   1004 void 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 
   1019 int 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 
   1042 void 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 
   1056 int 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 
   1079 int 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 
   1107 int 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 
   1129 int 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 
   1151 int 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 
   1184 int 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 
   1207 int 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 
   1228 int 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 
   1250 int 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 
   1272 int 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 
   1293 int 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 
   1314 int 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 
   1336 int 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 
   1377 int 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 
   1393 int 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 
   1410 int 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 
   1435 exit:
   1436 	cil_destroy_call(new);
   1437 	return rc;
   1438 }
   1439 
   1440 int 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 
   1500 exit:
   1501 	cil_log(CIL_INFO, "cil_copy_macro: macro cannot be redefined\n");
   1502 	return SEPOL_ERR;
   1503 }
   1504 
   1505 int 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 
   1523 void 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 
   1529 int 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 
   1550 int 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 
   1561 int 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 
   1577 int 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 
   1592 int 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 
   1612 int 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 
   1630 int 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 
   1642 int 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 
   1654 int 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 
   1669 int __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 
   2028 exit:
   2029 	cil_tree_node_destroy(&new);
   2030 	return rc;
   2031 }
   2032 
   2033 int __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
   2050 int 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 
   2066 exit:
   2067 	return rc;
   2068 }
   2069 
   2070