a1d62218cdb0efd0f02da1b54fd3eda91a681d98nd IPA Backend Module -- Access control
031b91a62d25106ae69d4693475c79618dd5e884fielding Sumit Bose <sbose@redhat.com>
031b91a62d25106ae69d4693475c79618dd5e884fielding Stephen Gallagher <sgallagh@redhat.com>
031b91a62d25106ae69d4693475c79618dd5e884fielding Copyright (C) 2011 Red Hat
031b91a62d25106ae69d4693475c79618dd5e884fielding This program is free software; you can redistribute it and/or modify
acc36ab93565d2880447d535da6ca6e5feac7a70nd it under the terms of the GNU General Public License as published by
acc36ab93565d2880447d535da6ca6e5feac7a70nd the Free Software Foundation; either version 3 of the License, or
acc36ab93565d2880447d535da6ca6e5feac7a70nd (at your option) any later version.
acc36ab93565d2880447d535da6ca6e5feac7a70nd This program is distributed in the hope that it will be useful,
acc36ab93565d2880447d535da6ca6e5feac7a70nd but WITHOUT ANY WARRANTY; without even the implied warranty of
acc36ab93565d2880447d535da6ca6e5feac7a70nd MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
acc36ab93565d2880447d535da6ca6e5feac7a70nd GNU General Public License for more details.
acc36ab93565d2880447d535da6ca6e5feac7a70nd You should have received a copy of the GNU General Public License
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd along with this program. If not, see <http://www.gnu.org/licenses/>.
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd#include "config.h" /* for HAVE_FUNCTION_ATTRIBUTE_FORMAT in "ipa_hbac.h" */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd/* HBAC logging system */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd/* debug macro */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd} while (0)
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd/* static pointer to external logging function */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd/* setup function for external logging function */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakvoid hbac_enable_debug(hbac_debug_fn_t external_debug_fn)
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd/* auxiliary function for hbac_request_element logging */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndstatic void hbac_request_element_debug_print(struct hbac_request_element *el,
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd const char *label);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd/* auxiliary function for hbac_eval_req logging */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndstatic void hbac_req_debug_print(struct hbac_eval_req *req);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd/* auxiliary function for hbac_rule_element logging */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakstatic void hbac_rule_element_debug_print(struct hbac_rule_element *el,
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd const char *label);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd/* auxiliary function for hbac_rule logging */
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniakstatic void hbac_rule_debug_print(struct hbac_rule *rule);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd/* Placeholder structure for future HBAC time-based
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd * evaluation rules
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndstatic bool hbac_rule_element_is_complete(struct hbac_rule_element *el)
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd if (el->names == NULL && el->groups == NULL) return false;
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return true;
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak /* If other categories are added, handle them here */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return false;
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndbool hbac_rule_is_complete(struct hbac_rule *rule, uint32_t *missing_attrs)
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* No rule passed in? */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return false;
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* Make sure we have all elements */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndenum hbac_eval_result_int hbac_evaluate_rule(struct hbac_rule *rule,
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndenum hbac_eval_result hbac_evaluate(struct hbac_rule **rules,
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd for (i = 0; rules[i]; i++) {
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd intermediate_result = hbac_evaluate_rule(rules[i], hbac_req, &ret);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* This rule did not match at all. Skip it */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd HBAC_DEBUG(HBAC_DBG_INFO, "The rule [%s] did not match.\n",
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak HBAC_DEBUG(HBAC_DBG_INFO, "ALLOWED by rule [%s].\n", rules[i]->name);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* An error occurred processing this rule */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd "Error %d occurred during evaluating of rule [%s].\n",
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* Explicitly not checking the result of strdup(), since if
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd * it's NULL, we can't do anything anyway.
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* If we've reached the end of the loop, we have either set the
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd * result to ALLOW explicitly or we'll stick with the default DENY.
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndstatic errno_t hbac_evaluate_element(struct hbac_rule_element *rule_el,
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndenum hbac_eval_result_int hbac_evaluate_rule(struct hbac_rule *rule,
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd HBAC_DEBUG(HBAC_DBG_INFO, "Rule [%s] is not enabled\n", rule->name);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* Make sure we have all elements */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd "Rule [%s] cannot be parsed, some elements are empty\n",
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* Check users */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd "Cannot parse user elements of rule [%s]\n", rule->name);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd } else if (!matched) {
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* Check services */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd "Cannot parse service elements of rule [%s]\n", rule->name);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd } else if (!matched) {
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* Check target hosts */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd "Cannot parse targethost elements of rule [%s]\n",
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak } else if (!matched) {
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* Check source hosts */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd "Cannot parse srchost elements of rule [%s]\n",
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd } else if (!matched) {
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndstatic errno_t hbac_evaluate_element(struct hbac_rule_element *rule_el,
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* First check the name list */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* Do a case-insensitive comparison. */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* Not found in the name list
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd * Check for group membership
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* Do a case-insensitive comparison. */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd /* Not found in groups either */
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndconst char *hbac_result_string(enum hbac_eval_result result)
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd switch (result) {
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return "HBAC_EVAL_ALLOW";
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return "HBAC_EVAL_DENY";
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return "HBAC_EVAL_ERROR";
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return "Could not allocate memory for hbac_info object";
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return "HBAC_EVAL_ERROR";
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd switch (code) {
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return "Success";
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak return "Function is not yet implemented";
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return "Out of memory";
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return "Rule could not be evaluated";
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd return "Unknown error code";
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndstatic void hbac_request_element_debug_print(struct hbac_request_element *el,
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd const char *label)
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd HBAC_DEBUG(HBAC_DBG_TRACE, "\t\t%s [%s]\n", label, el->name);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd HBAC_DEBUG(HBAC_DBG_TRACE, "\t\t\t[%s]\n", el->groups[i]);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd HBAC_DEBUG(HBAC_DBG_TRACE, "\t\t%s_group (none)\n", label);
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak HBAC_DEBUG(HBAC_DBG_TRACE, "\t%s (none)\n", label);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndstatic void hbac_req_debug_print(struct hbac_eval_req *req)
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd hbac_request_element_debug_print(req->service, "service");
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd hbac_request_element_debug_print(req->targethost, "targethost");
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd hbac_request_element_debug_print(req->srchost, "srchost");
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd ret = strftime(time_buff, buff_size, "%Y-%m-%d %H:%M:%S", local_time);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd if (ret <= 0) {
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd HBAC_DEBUG(HBAC_DBG_TRACE, "\t\trequest time %s\n", time_buff);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77ndstatic void hbac_rule_element_debug_print(struct hbac_rule_element *el,
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd const char *label)
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd HBAC_DEBUG(HBAC_DBG_TRACE, "\t\tcategory [%#x] [%s]\n", el->category,
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak (el->category == HBAC_CATEGORY_ALL) ? "ALL" : "NONE");
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd HBAC_DEBUG(HBAC_DBG_TRACE, "\t\t\t[%s]\n", el->names[i]);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd HBAC_DEBUG(HBAC_DBG_TRACE, "\t\t%s_names (none)\n", label);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd HBAC_DEBUG(HBAC_DBG_TRACE, "\t\t\t[%s]\n", el->groups[i]);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd HBAC_DEBUG(HBAC_DBG_TRACE, "\t\t%s_groups (none)\n", label);
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd hbac_rule_element_debug_print(rule->services, "services");
5652dbe450e4fcfdf36d4cfb42d7f2345ded29a4maczniak hbac_rule_element_debug_print(rule->users, "users");
d78d735dbf7c5ce5ae545eecd8ee2c052224db77nd hbac_rule_element_debug_print(rule->targethosts, "targethosts");