* sepgsql_compute_avd * * It actually asks SELinux what permissions are allowed on a pair of * the security contexts and object class. It also returns what permissions * should be audited on access violation or allowed. * In most cases, subject's security context (scontext) is a client, and * target security context (tcontext) is a database object. * * The access control decision shall be
| 730 | * to suggest a set of allowed actions in this object class. |
| 731 | */ |
| 732 | void |
| 733 | sepgsql_compute_avd(const char *scontext, |
| 734 | const char *tcontext, |
| 735 | uint16 tclass, |
| 736 | struct av_decision *avd) |
| 737 | { |
| 738 | const char *tclass_name; |
| 739 | security_class_t tclass_ex; |
| 740 | struct av_decision avd_ex; |
| 741 | int i, |
| 742 | deny_unknown = security_deny_unknown(); |
| 743 | |
| 744 | /* Get external code of the object class */ |
| 745 | Assert(tclass < SEPG_CLASS_MAX); |
| 746 | Assert(tclass == selinux_catalog[tclass].class_code); |
| 747 | |
| 748 | tclass_name = selinux_catalog[tclass].class_name; |
| 749 | tclass_ex = string_to_security_class(tclass_name); |
| 750 | |
| 751 | if (tclass_ex == 0) |
| 752 | { |
| 753 | /* |
| 754 | * If the current security policy does not support permissions |
| 755 | * corresponding to database objects, we fill up them with dummy data. |
| 756 | * If security_deny_unknown() returns positive value, undefined |
| 757 | * permissions should be denied. Otherwise, allowed |
| 758 | */ |
| 759 | avd->allowed = (security_deny_unknown() > 0 ? 0 : ~0); |
| 760 | avd->auditallow = 0U; |
| 761 | avd->auditdeny = ~0U; |
| 762 | avd->flags = 0; |
| 763 | |
| 764 | return; |
| 765 | } |
| 766 | |
| 767 | /* |
| 768 | * Ask SELinux what is allowed set of permissions on a pair of the |
| 769 | * security contexts and the given object class. |
| 770 | */ |
| 771 | if (security_compute_av_flags_raw(scontext, |
| 772 | tcontext, |
| 773 | tclass_ex, 0, &avd_ex) < 0) |
| 774 | ereport(ERROR, |
| 775 | (errcode(ERRCODE_INTERNAL_ERROR), |
| 776 | errmsg("SELinux could not compute av_decision: " |
| 777 | "scontext=%s tcontext=%s tclass=%s: %m", |
| 778 | scontext, tcontext, tclass_name))); |
| 779 | |
| 780 | /* |
| 781 | * SELinux returns its access control decision as a set of permissions |
| 782 | * represented in external code which depends on run-time environment. So, |
| 783 | * we need to translate it to the internal representation before returning |
| 784 | * results for the caller. |
| 785 | */ |
| 786 | memset(avd, 0, sizeof(struct av_decision)); |
| 787 | |
| 788 | for (i = 0; selinux_catalog[tclass].av[i].av_name; i++) |
| 789 | { |
no test coverage detected