summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--src/providers/ipa/hbac_evaluator.c51
-rw-r--r--src/providers/ipa/ipa_hbac.h23
-rw-r--r--src/tests/ipa_hbac-tests.c115
4 files changed, 190 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 6647528c..1df6d985 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -378,7 +378,7 @@ dist_pkgconfig_DATA += src/providers/ipa/ipa_hbac.pc
libipa_hbac_la_SOURCES = \
src/providers/ipa/hbac_evaluator.c
libipa_hbac_la_LDFLAGS = \
- -version 0:1:0 \
+ -version 1:0:1 \
-lunistring
include_HEADERS = \
diff --git a/src/providers/ipa/hbac_evaluator.c b/src/providers/ipa/hbac_evaluator.c
index ee39a09a..476ad648 100644
--- a/src/providers/ipa/hbac_evaluator.c
+++ b/src/providers/ipa/hbac_evaluator.c
@@ -52,6 +52,57 @@ enum hbac_eval_result_int {
HBAC_EVAL_UNMATCHED
};
+static bool hbac_rule_element_is_complete(struct hbac_rule_element *el)
+{
+ if (el == NULL) return false;
+ if (el->category == HBAC_CATEGORY_ALL) return true;
+
+ if (el->names == NULL && el->groups == NULL) return false;
+
+ if ((el->names && el->names[0] != NULL)
+ || (el->groups && el->groups[0] != NULL))
+ return true;
+
+ /* If other categories are added, handle them here */
+
+ return false;
+}
+
+bool hbac_rule_is_complete(struct hbac_rule *rule, uint32_t *missing_attrs)
+{
+ bool complete = true;
+
+ *missing_attrs = 0;
+
+ if (rule == NULL) {
+ /* No rule passed in? */
+ return false;
+ }
+
+ /* Make sure we have all elements */
+ if (!hbac_rule_element_is_complete(rule->users)) {
+ complete = false;
+ *missing_attrs |= HBAC_RULE_ELEMENT_USERS;
+ }
+
+ if (!hbac_rule_element_is_complete(rule->services)) {
+ complete = false;
+ *missing_attrs |= HBAC_RULE_ELEMENT_SERVICES;
+ }
+
+ if (!hbac_rule_element_is_complete(rule->targethosts)) {
+ complete = false;
+ *missing_attrs |= HBAC_RULE_ELEMENT_TARGETHOSTS;
+ }
+
+ if (!hbac_rule_element_is_complete(rule->srchosts)) {
+ complete = false;
+ *missing_attrs |= HBAC_RULE_ELEMENT_SOURCEHOSTS;
+ }
+
+ return complete;
+}
+
enum hbac_eval_result_int hbac_evaluate_rule(struct hbac_rule *rule,
struct hbac_eval_req *hbac_req,
enum hbac_error_code *error);
diff --git a/src/providers/ipa/ipa_hbac.h b/src/providers/ipa/ipa_hbac.h
index a1d51378..7de49d1f 100644
--- a/src/providers/ipa/ipa_hbac.h
+++ b/src/providers/ipa/ipa_hbac.h
@@ -151,4 +151,27 @@ const char *hbac_error_string(enum hbac_error_code code);
void hbac_free_info(struct hbac_info *info);
+
+#define HBAC_RULE_ELEMENT_USERS 0x01
+#define HBAC_RULE_ELEMENT_SERVICES 0x02
+#define HBAC_RULE_ELEMENT_TARGETHOSTS 0x04
+#define HBAC_RULE_ELEMENT_SOURCEHOSTS 0x08
+
+/**
+ * @brief Evaluate whether an HBAC rule contains all necessary elements
+ *
+ * @param[in] rule An HBAC rule to evaluate
+ * @param[out] missing_attrs A list of attributes missing from the rule
+ * This is a bitmask that may contain one or more
+ * of HBAC_RULE_ELEMENT_USERS,
+ * HBAC_RULE_ELEMENT_SERVICES,
+ * HBAC_RULE_ELEMENT_TARGETHOSTS and
+ * HBAC_RULE_ELEMENT_SOURCEHOSTS
+ *
+ * @return True if the rule contains all mandatory attributes
+ *
+ * @note This function does not care if the rule is enabled or disabled
+ */
+bool hbac_rule_is_complete(struct hbac_rule *rule, uint32_t *missing_attrs);
+
#endif /* IPA_HBAC_H_ */
diff --git a/src/tests/ipa_hbac-tests.c b/src/tests/ipa_hbac-tests.c
index d3d80387..330e49e7 100644
--- a/src/tests/ipa_hbac-tests.c
+++ b/src/tests/ipa_hbac-tests.c
@@ -188,6 +188,8 @@ START_TEST(ipa_hbac_test_allow_all)
struct hbac_rule **rules;
struct hbac_eval_req *eval_req;
struct hbac_info *info;
+ bool is_valid;
+ uint32_t missing_attrs;
test_ctx = talloc_new(global_talloc_context);
@@ -208,6 +210,11 @@ START_TEST(ipa_hbac_test_allow_all)
fail_if(rules[0]->name == NULL);
rules[1] = NULL;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_ALLOW,
@@ -228,6 +235,8 @@ START_TEST(ipa_hbac_test_allow_user)
struct hbac_rule **rules;
struct hbac_eval_req *eval_req;
struct hbac_info *info;
+ bool is_valid;
+ uint32_t missing_attrs;
test_ctx = talloc_new(global_talloc_context);
@@ -258,6 +267,11 @@ START_TEST(ipa_hbac_test_allow_user)
rules[1] = NULL;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_ALLOW,
@@ -270,6 +284,11 @@ START_TEST(ipa_hbac_test_allow_user)
/* Negative test */
rules[0]->users->names[0] = HBAC_TEST_INVALID_USER;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_DENY,
@@ -290,6 +309,8 @@ START_TEST(ipa_hbac_test_allow_utf8)
struct hbac_rule **rules;
struct hbac_eval_req *eval_req;
struct hbac_info *info;
+ bool is_valid;
+ uint32_t missing_attrs;
test_ctx = talloc_new(global_talloc_context);
@@ -343,6 +364,11 @@ START_TEST(ipa_hbac_test_allow_utf8)
rules[1] = NULL;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_ALLOW,
@@ -369,6 +395,11 @@ START_TEST(ipa_hbac_test_allow_utf8)
eval_req->user->name = (const char *) &user_lowcase_tr;
rules[0]->users->names[0] = (const char *) &user_upcase_tr;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_DENY,
@@ -389,6 +420,8 @@ START_TEST(ipa_hbac_test_allow_group)
struct hbac_rule **rules;
struct hbac_eval_req *eval_req;
struct hbac_info *info;
+ bool is_valid;
+ uint32_t missing_attrs;
test_ctx = talloc_new(global_talloc_context);
@@ -420,6 +453,11 @@ START_TEST(ipa_hbac_test_allow_group)
rules[1] = NULL;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_ALLOW,
@@ -432,6 +470,11 @@ START_TEST(ipa_hbac_test_allow_group)
/* Negative test */
rules[0]->users->groups[0] = HBAC_TEST_INVALID_GROUP;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_DENY,
@@ -452,6 +495,8 @@ START_TEST(ipa_hbac_test_allow_svc)
struct hbac_rule **rules;
struct hbac_eval_req *eval_req;
struct hbac_info *info;
+ bool is_valid;
+ uint32_t missing_attrs;
test_ctx = talloc_new(global_talloc_context);
@@ -482,6 +527,11 @@ START_TEST(ipa_hbac_test_allow_svc)
rules[1] = NULL;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_ALLOW,
@@ -494,6 +544,11 @@ START_TEST(ipa_hbac_test_allow_svc)
/* Negative test */
rules[0]->services->names[0] = HBAC_TEST_INVALID_SERVICE;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_DENY,
@@ -514,6 +569,8 @@ START_TEST(ipa_hbac_test_allow_svcgroup)
struct hbac_rule **rules;
struct hbac_eval_req *eval_req;
struct hbac_info *info;
+ bool is_valid;
+ uint32_t missing_attrs;
test_ctx = talloc_new(global_talloc_context);
@@ -545,6 +602,11 @@ START_TEST(ipa_hbac_test_allow_svcgroup)
rules[1] = NULL;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_ALLOW,
@@ -557,6 +619,11 @@ START_TEST(ipa_hbac_test_allow_svcgroup)
/* Negative test */
rules[0]->services->groups[0] = HBAC_TEST_INVALID_SERVICEGROUP;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_DENY,
@@ -577,6 +644,8 @@ START_TEST(ipa_hbac_test_allow_srchost)
struct hbac_rule **rules;
struct hbac_eval_req *eval_req;
struct hbac_info *info;
+ bool is_valid;
+ uint32_t missing_attrs;
test_ctx = talloc_new(global_talloc_context);
@@ -607,6 +676,11 @@ START_TEST(ipa_hbac_test_allow_srchost)
rules[1] = NULL;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_ALLOW,
@@ -619,6 +693,11 @@ START_TEST(ipa_hbac_test_allow_srchost)
/* Negative test */
rules[0]->srchosts->names[0] = HBAC_TEST_INVALID_SRCHOST;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_DENY,
@@ -639,6 +718,8 @@ START_TEST(ipa_hbac_test_allow_srchostgroup)
struct hbac_rule **rules;
struct hbac_eval_req *eval_req;
struct hbac_info *info;
+ bool is_valid;
+ uint32_t missing_attrs;
test_ctx = talloc_new(global_talloc_context);
@@ -670,6 +751,11 @@ START_TEST(ipa_hbac_test_allow_srchostgroup)
rules[1] = NULL;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_ALLOW,
@@ -682,6 +768,11 @@ START_TEST(ipa_hbac_test_allow_srchostgroup)
/* Negative test */
rules[0]->srchosts->groups[0] = HBAC_TEST_INVALID_SRCHOSTGROUP;
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs);
+ fail_unless(is_valid);
+ fail_unless(missing_attrs == 0);
+
/* Evaluate the rules */
result = hbac_evaluate(rules, eval_req, &info);
fail_unless(result == HBAC_EVAL_DENY,
@@ -695,6 +786,29 @@ START_TEST(ipa_hbac_test_allow_srchostgroup)
}
END_TEST
+START_TEST(ipa_hbac_test_incomplete)
+{
+ TALLOC_CTX *test_ctx;
+ struct hbac_rule *rule;
+ bool is_valid;
+ uint32_t missing_attrs;
+
+ test_ctx = talloc_new(global_talloc_context);
+
+ rule = talloc_zero(test_ctx, struct hbac_rule);
+
+ /* Validate this rule */
+ is_valid = hbac_rule_is_complete(rule, &missing_attrs);
+ fail_if(is_valid);
+ fail_unless(missing_attrs | HBAC_RULE_ELEMENT_USERS);
+ fail_unless(missing_attrs | HBAC_RULE_ELEMENT_SERVICES);
+ fail_unless(missing_attrs | HBAC_RULE_ELEMENT_TARGETHOSTS);
+ fail_unless(missing_attrs | HBAC_RULE_ELEMENT_SOURCEHOSTS);
+
+ talloc_free(test_ctx);
+}
+END_TEST
+
Suite *hbac_test_suite (void)
{
Suite *s = suite_create ("HBAC");
@@ -712,6 +826,7 @@ Suite *hbac_test_suite (void)
tcase_add_test(tc_hbac, ipa_hbac_test_allow_srchost);
tcase_add_test(tc_hbac, ipa_hbac_test_allow_srchostgroup);
tcase_add_test(tc_hbac, ipa_hbac_test_allow_utf8);
+ tcase_add_test(tc_hbac, ipa_hbac_test_incomplete);
suite_add_tcase(s, tc_hbac);
return s;