| | 565 | /** For all symbols that are multiply defined (such as roles and users), |
|---|
| | 566 | * union the relevant sets of types and roles from each declaration. |
|---|
| | 567 | * @param policy The policy containig the symbols to union. |
|---|
| | 568 | * @return 0 on success, non-zero on error; if the call fails, |
|---|
| | 569 | * errno will be set, and the policy should be considered invalid. |
|---|
| | 570 | */ |
|---|
| | 571 | static int union_multiply_declared_symbols(qpol_policy_t * policy) { |
|---|
| | 572 | /* general structure of this function: |
|---|
| | 573 | walk role and user symbol tables for each role/user |
|---|
| | 574 | get datum from symtab, get key from array |
|---|
| | 575 | look up symbol in scope table |
|---|
| | 576 | foreach decl_id in scope entry |
|---|
| | 577 | union types/roles bitmap with datum's copy |
|---|
| | 578 | */ |
|---|
| | 579 | qpol_iterator_t * iter = NULL; |
|---|
| | 580 | int error = 0; |
|---|
| | 581 | if (qpol_policy_get_role_iter(policy, &iter)) { |
|---|
| | 582 | return 1; |
|---|
| | 583 | } |
|---|
| | 584 | for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { |
|---|
| | 585 | role_datum_t *role; |
|---|
| | 586 | if (qpol_iterator_get_item(iter, (void**)&role)) { |
|---|
| | 587 | error = errno; |
|---|
| | 588 | goto err; |
|---|
| | 589 | } |
|---|
| | 590 | const char *name; |
|---|
| | 591 | if (qpol_role_get_name(policy, (qpol_role_t*)role, &name)) { |
|---|
| | 592 | error = errno; |
|---|
| | 593 | goto err; |
|---|
| | 594 | } |
|---|
| | 595 | policydb_t *db = &policy->p->p; |
|---|
| | 596 | scope_datum_t* scope_datum = hashtab_search(db->scope[SYM_ROLES].table, (const hashtab_key_t)name); |
|---|
| | 597 | if (scope_datum == NULL) { |
|---|
| | 598 | ERR(policy, "could not find scope datum for role %s", name); |
|---|
| | 599 | error = ENOENT; |
|---|
| | 600 | goto err; |
|---|
| | 601 | } |
|---|
| | 602 | for (uint32_t i = 0; i < scope_datum->decl_ids_len; i++) |
|---|
| | 603 | { |
|---|
| | 604 | if (db->decl_val_to_struct[scope_datum->decl_ids[i] - 1]->enabled == 0) |
|---|
| | 605 | continue; /* block is disabled */ |
|---|
| | 606 | role_datum_t *internal_datum = hashtab_search(db->decl_val_to_struct[scope_datum->decl_ids[i] - 1]->symtab[SYM_ROLES].table, (const hashtab_key_t)name); |
|---|
| | 607 | if (internal_datum == NULL) { |
|---|
| | 608 | continue; /* not declared here */ |
|---|
| | 609 | } |
|---|
| | 610 | if (ebitmap_union(&role->types.types, &internal_datum->types.types) || ebitmap_union(&role->dominates, &internal_datum->dominates)) |
|---|
| | 611 | { |
|---|
| | 612 | error = errno; |
|---|
| | 613 | ERR(policy, "could not merge declarations for role %s", name); |
|---|
| | 614 | goto err; |
|---|
| | 615 | } |
|---|
| | 616 | } |
|---|
| | 617 | } |
|---|
| | 618 | qpol_iterator_destroy(&iter); |
|---|
| | 619 | |
|---|
| | 620 | /* repeat for users */ |
|---|
| | 621 | if (qpol_policy_get_user_iter(policy, &iter)) { |
|---|
| | 622 | return 1; |
|---|
| | 623 | } |
|---|
| | 624 | for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { |
|---|
| | 625 | user_datum_t *user; |
|---|
| | 626 | if (qpol_iterator_get_item(iter, (void**)&user)) { |
|---|
| | 627 | error = errno; |
|---|
| | 628 | goto err; |
|---|
| | 629 | } |
|---|
| | 630 | const char *name; |
|---|
| | 631 | if (qpol_user_get_name(policy, (qpol_user_t*)user, &name)) { |
|---|
| | 632 | error = errno; |
|---|
| | 633 | goto err; |
|---|
| | 634 | } |
|---|
| | 635 | policydb_t *db = &policy->p->p; |
|---|
| | 636 | scope_datum_t* scope_datum = hashtab_search(db->scope[SYM_USERS].table, (const hashtab_key_t)name); |
|---|
| | 637 | if (scope_datum == NULL) { |
|---|
| | 638 | ERR(policy, "could not find scope datum for user %s", name); |
|---|
| | 639 | error = ENOENT; |
|---|
| | 640 | goto err; |
|---|
| | 641 | } |
|---|
| | 642 | for (uint32_t i = 0; i < scope_datum->decl_ids_len; i++) |
|---|
| | 643 | { |
|---|
| | 644 | if (db->decl_val_to_struct[scope_datum->decl_ids[i] - 1]->enabled == 0) |
|---|
| | 645 | continue; /* block is disabled */ |
|---|
| | 646 | user_datum_t *internal_datum = hashtab_search(db->decl_val_to_struct[scope_datum->decl_ids[i]]->symtab[SYM_USERS].table, (const hashtab_key_t)name); |
|---|
| | 647 | if (internal_datum == NULL) { |
|---|
| | 648 | continue; /* not declared here */ |
|---|
| | 649 | } |
|---|
| | 650 | if (ebitmap_union(&user->roles.roles, &internal_datum->roles.roles)) |
|---|
| | 651 | { |
|---|
| | 652 | error = errno; |
|---|
| | 653 | ERR(policy, "could not merge declarations for user %s", name); |
|---|
| | 654 | goto err; |
|---|
| | 655 | } |
|---|
| | 656 | } |
|---|
| | 657 | } |
|---|
| | 658 | qpol_iterator_destroy(&iter); |
|---|
| | 659 | |
|---|
| | 660 | return 0; |
|---|
| | 661 | err: |
|---|
| | 662 | qpol_iterator_destroy(&iter); |
|---|
| | 663 | errno = error; |
|---|
| | 664 | return 1; |
|---|
| | 665 | } |
|---|
| | 666 | |
|---|