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