sssd/0045-IPA_ACCESS-Make-hbac_g...

361 lines
13 KiB
Diff

From e17e37cd0e2109e7f1bd4ae48edfc8cca85b3f93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Mon, 10 Apr 2017 13:49:48 +0200
Subject: [PATCH 45/93] IPA_ACCESS: Make hbac_get_cache_rules() more generic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This method can also be reused in the future for new backend modules.
In order to make it more generic, let's just move it to
ipa_rules_common.[ch], rename it to ipa_common_get_cached_rules() and
make the rule, subtree name and the attributes to be searched new
parameters of this method.
In order to not be declaring the enourmous list of attributes HBAC uses
when calling this method, a new hbac_get_attrs_to_get_cached_rules()
method has been introduced.
Related:
https://pagure.io/SSSD/sssd/issue/2995
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/providers/ipa/ipa_access.c | 77 ++++++------------------------------
src/providers/ipa/ipa_access.h | 5 ---
src/providers/ipa/ipa_hbac_common.c | 30 ++++++++++++++
src/providers/ipa/ipa_hbac_private.h | 3 ++
src/providers/ipa/ipa_rules_common.c | 61 ++++++++++++++++++++++++++++
src/providers/ipa/ipa_rules_common.h | 9 +++++
src/providers/ipa/ipa_selinux.c | 33 ++++++++++++----
7 files changed, 141 insertions(+), 77 deletions(-)
diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c
index 262f146dae788a68a394cc44e3719f5e16ef5f03..58c4992e0381f443d942c9c8a63216587de5ac1d 100644
--- a/src/providers/ipa/ipa_access.c
+++ b/src/providers/ipa/ipa_access.c
@@ -591,6 +591,7 @@ errno_t ipa_hbac_evaluate_rules(struct be_ctx *be_ctx,
struct hbac_eval_req *eval_req;
enum hbac_eval_result result;
struct hbac_info *info = NULL;
+ const char **attrs_get_cached_rules;
errno_t ret;
tmp_ctx = talloc_new(NULL);
@@ -603,8 +604,17 @@ errno_t ipa_hbac_evaluate_rules(struct be_ctx *be_ctx,
hbac_ctx.pd = pd;
/* Get HBAC rules from the sysdb */
- ret = hbac_get_cached_rules(tmp_ctx, be_ctx->domain,
- &hbac_ctx.rule_count, &hbac_ctx.rules);
+ attrs_get_cached_rules = hbac_get_attrs_to_get_cached_rules(tmp_ctx);
+ if (attrs_get_cached_rules == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "hbac_get_attrs_to_get_cached_rules() failed\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = ipa_common_get_cached_rules(tmp_ctx, be_ctx->domain,
+ IPA_HBAC_RULE, HBAC_RULES_SUBDIR,
+ attrs_get_cached_rules,
+ &hbac_ctx.rule_count, &hbac_ctx.rules);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Could not retrieve rules from the cache\n");
goto done;
@@ -649,69 +659,6 @@ done:
return ret;
}
-errno_t hbac_get_cached_rules(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- size_t *_rule_count,
- struct sysdb_attrs ***_rules)
-{
- errno_t ret;
- struct ldb_message **msgs;
- struct sysdb_attrs **rules;
- size_t rule_count;
- TALLOC_CTX *tmp_ctx;
- char *filter;
- const char *attrs[] = { OBJECTCLASS,
- IPA_CN,
- SYSDB_ORIG_DN,
- IPA_UNIQUE_ID,
- IPA_ENABLED_FLAG,
- IPA_ACCESS_RULE_TYPE,
- IPA_MEMBER_USER,
- IPA_USER_CATEGORY,
- IPA_MEMBER_SERVICE,
- IPA_SERVICE_CATEGORY,
- IPA_SOURCE_HOST,
- IPA_SOURCE_HOST_CATEGORY,
- IPA_EXTERNAL_HOST,
- IPA_MEMBER_HOST,
- IPA_HOST_CATEGORY,
- NULL };
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) return ENOMEM;
-
- filter = talloc_asprintf(tmp_ctx, "(objectClass=%s)", IPA_HBAC_RULE);
- if (filter == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = sysdb_search_custom(tmp_ctx, domain, filter,
- HBAC_RULES_SUBDIR, attrs,
- &rule_count, &msgs);
- if (ret != EOK && ret != ENOENT) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up HBAC rules\n");
- goto done;
- } if (ret == ENOENT) {
- rule_count = 0;
- }
-
- ret = sysdb_msg2attrs(tmp_ctx, rule_count, msgs, &rules);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Could not convert ldb message to sysdb_attrs\n");
- goto done;
- }
-
- if (_rules) *_rules = talloc_steal(mem_ctx, rules);
- if (_rule_count) *_rule_count = rule_count;
-
- ret = EOK;
-done:
- talloc_free(tmp_ctx);
- return ret;
-}
-
struct ipa_pam_access_handler_state {
struct tevent_context *ev;
struct be_ctx *be_ctx;
diff --git a/src/providers/ipa/ipa_access.h b/src/providers/ipa/ipa_access.h
index eb19fc43819ad67be2128457365e18a91dd15b4a..de690350218bd47165a2b48c10059b8de96b718a 100644
--- a/src/providers/ipa/ipa_access.h
+++ b/src/providers/ipa/ipa_access.h
@@ -63,9 +63,4 @@ ipa_pam_access_handler_recv(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
struct pam_data **_data);
-errno_t hbac_get_cached_rules(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- size_t *_rule_count,
- struct sysdb_attrs ***_rules);
-
#endif /* _IPA_ACCESS_H_ */
diff --git a/src/providers/ipa/ipa_hbac_common.c b/src/providers/ipa/ipa_hbac_common.c
index 2dba314962bd76c669b1bdbb33f2bb1858fe43c1..9414419122a201c00dccf65e6ee88a0bcaa38477 100644
--- a/src/providers/ipa/ipa_hbac_common.c
+++ b/src/providers/ipa/ipa_hbac_common.c
@@ -716,3 +716,33 @@ done:
talloc_free(tmp_ctx);
return ret;
}
+
+const char **
+hbac_get_attrs_to_get_cached_rules(TALLOC_CTX *mem_ctx)
+{
+ const char **attrs = talloc_zero_array(mem_ctx, const char *, 16);
+ if (attrs == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array() failed\n");
+ goto done;
+ }
+
+ attrs[0] = OBJECTCLASS;
+ attrs[1] = IPA_CN;
+ attrs[2] = SYSDB_ORIG_DN;
+ attrs[3] = IPA_UNIQUE_ID;
+ attrs[4] = IPA_ENABLED_FLAG;
+ attrs[5] = IPA_ACCESS_RULE_TYPE;
+ attrs[6] = IPA_MEMBER_USER;
+ attrs[7] = IPA_USER_CATEGORY;
+ attrs[8] = IPA_MEMBER_SERVICE;
+ attrs[9] = IPA_SERVICE_CATEGORY;
+ attrs[10] = IPA_SOURCE_HOST;
+ attrs[11] = IPA_SOURCE_HOST_CATEGORY;
+ attrs[12] = IPA_EXTERNAL_HOST;
+ attrs[13] = IPA_MEMBER_HOST;
+ attrs[14] = IPA_HOST_CATEGORY;
+ attrs[15] = NULL;
+
+done:
+ return attrs;
+}
diff --git a/src/providers/ipa/ipa_hbac_private.h b/src/providers/ipa/ipa_hbac_private.h
index 7d8b1ed2f82a5d4502a47f51ddd4f19171430688..b11814b83cc7498476d8624b3b2e298437738299 100644
--- a/src/providers/ipa/ipa_hbac_private.h
+++ b/src/providers/ipa/ipa_hbac_private.h
@@ -89,6 +89,9 @@ get_ipa_hostgroupname(TALLOC_CTX *mem_ctx,
const char *host_dn,
char **hostgroupname);
+const char **
+hbac_get_attrs_to_get_cached_rules(TALLOC_CTX *mem_ctx);
+
/* From ipa_hbac_services.c */
struct tevent_req *
ipa_hbac_service_info_send(TALLOC_CTX *mem_ctx,
diff --git a/src/providers/ipa/ipa_rules_common.c b/src/providers/ipa/ipa_rules_common.c
index 056d04dd1b622284634995f21dc0f2f0087c7741..6964e93fb338fd17916a7130eea55b98974837ec 100644
--- a/src/providers/ipa/ipa_rules_common.c
+++ b/src/providers/ipa/ipa_rules_common.c
@@ -161,3 +161,64 @@ done:
}
return ret;
}
+
+errno_t
+ipa_common_get_cached_rules(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *rule,
+ const char *subtree_name,
+ const char **attrs,
+ size_t *_rule_count,
+ struct sysdb_attrs ***_rules)
+{
+ errno_t ret;
+ struct ldb_message **msgs;
+ struct sysdb_attrs **rules;
+ size_t rule_count;
+ TALLOC_CTX *tmp_ctx;
+ char *filter;
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ filter = talloc_asprintf(tmp_ctx, "(objectClass=%s)", rule);
+ if (filter == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_search_custom(tmp_ctx, domain, filter,
+ subtree_name, attrs,
+ &rule_count, &msgs);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up HBAC rules\n");
+ goto done;
+ }
+
+ if (ret == ENOENT) {
+ rule_count = 0;
+ }
+
+ ret = sysdb_msg2attrs(tmp_ctx, rule_count, msgs, &rules);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Could not convert ldb message to sysdb_attrs\n");
+ goto done;
+ }
+
+ if (_rules) {
+ *_rules = talloc_steal(mem_ctx, rules);
+ }
+
+ if (_rule_count) {
+ *_rule_count = rule_count;
+ }
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/src/providers/ipa/ipa_rules_common.h b/src/providers/ipa/ipa_rules_common.h
index b5e05b039836902ac4ce0bc61b0fbc98648db974..9ccff7f71c73417cf9c3897d202009c54dc471d4 100644
--- a/src/providers/ipa/ipa_rules_common.h
+++ b/src/providers/ipa/ipa_rules_common.h
@@ -49,4 +49,13 @@ ipa_common_entries_and_groups_sysdb_save(struct sss_domain_info *domain,
size_t group_count,
struct sysdb_attrs **groups);
+errno_t
+ipa_common_get_cached_rules(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *rule,
+ const char *subtree_name,
+ const char **attrs,
+ size_t *_rule_count,
+ struct sysdb_attrs ***_rules);
+
#endif /* IPA_RULES_COMMON_H_ */
diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c
index e9cc33953ea4f10e1fb4cf0b2db3c2d15777b519..2c61bac374ab52c765d78ae7034299c49d91f80f 100644
--- a/src/providers/ipa/ipa_selinux.c
+++ b/src/providers/ipa/ipa_selinux.c
@@ -1009,6 +1009,7 @@ ipa_get_selinux_maps_offline(struct tevent_req *req)
SYSDB_SELINUX_SEEALSO,
SYSDB_SELINUX_USER,
NULL };
+ const char **attrs_get_cached_rules;
const char *default_user;
const char *order;
@@ -1066,10 +1067,20 @@ ipa_get_selinux_maps_offline(struct tevent_req *req)
state->nmaps = nmaps;
/* read all the HBAC rules */
- ret = hbac_get_cached_rules(state, state->be_ctx->domain,
- &state->hbac_rule_count, &state->hbac_rules);
+ attrs_get_cached_rules = hbac_get_attrs_to_get_cached_rules(state);
+ if (attrs_get_cached_rules == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "hbac_get_attrs_to_get_cached_rules() failed\n");
+ return ENOMEM;
+ }
+
+ ret = ipa_common_get_cached_rules(state, state->be_ctx->domain,
+ IPA_HBAC_RULE, HBAC_RULES_SUBDIR,
+ attrs_get_cached_rules,
+ &state->hbac_rule_count,
+ &state->hbac_rules);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "hbac_get_cached_rules failed [%d]: %s\n",
+ DEBUG(SSSDBG_OP_FAILURE, "ipa_common_get_cached_rules failed [%d]: %s\n",
ret, strerror(ret));
return ret;
}
@@ -1168,7 +1179,7 @@ static void ipa_get_selinux_maps_done(struct tevent_req *subreq)
struct ipa_id_ctx *id_ctx;
struct dp_module *access_mod;
struct dp_module *selinux_mod;
-
+ const char **attrs_get_cached_rules;
const char *tmp_str;
bool check_hbac;
errno_t ret;
@@ -1208,9 +1219,17 @@ static void ipa_get_selinux_maps_done(struct tevent_req *subreq)
access_mod = dp_target_module(state->be_ctx->provider, DPT_ACCESS);
selinux_mod = dp_target_module(state->be_ctx->provider, DPT_SELINUX);
if (access_mod == selinux_mod) {
- ret = hbac_get_cached_rules(state, state->be_ctx->domain,
- &state->hbac_rule_count,
- &state->hbac_rules);
+ attrs_get_cached_rules = hbac_get_attrs_to_get_cached_rules(state);
+ if (attrs_get_cached_rules == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ipa_common_get_cached_rules(state, state->be_ctx->domain,
+ IPA_HBAC_RULE, HBAC_RULES_SUBDIR,
+ attrs_get_cached_rules,
+ &state->hbac_rule_count,
+ &state->hbac_rules);
/* Terminates the request */
goto done;
}
--
2.14.1