diff options
author | Jan Zeleny <jzeleny@redhat.com> | 2012-01-18 11:08:06 -0500 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2012-02-06 08:25:22 -0500 |
commit | 71ad247500b417836a1a2edec257a4433a7c415f (patch) | |
tree | 55ce381a9f7444b8aaea8d70ed02db2a9477b7e1 | |
parent | 8a36504008872f03d1b1ca980adeceba28c331f5 (diff) | |
download | sssd-71ad247500b417836a1a2edec257a4433a7c415f.tar.gz sssd-71ad247500b417836a1a2edec257a4433a7c415f.tar.bz2 sssd-71ad247500b417836a1a2edec257a4433a7c415f.zip |
Implemented support for multiple search bases in HBAC rules and services
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/providers/ipa/ipa_access.c | 34 | ||||
-rw-r--r-- | src/providers/ipa/ipa_access.h | 3 | ||||
-rw-r--r-- | src/providers/ipa/ipa_common.c | 25 | ||||
-rw-r--r-- | src/providers/ipa/ipa_common.h | 1 | ||||
-rw-r--r-- | src/providers/ipa/ipa_hbac_private.h | 18 | ||||
-rw-r--r-- | src/providers/ipa/ipa_hbac_rules.c | 157 | ||||
-rw-r--r-- | src/providers/ipa/ipa_hbac_rules.h | 42 | ||||
-rw-r--r-- | src/providers/ipa/ipa_hbac_services.c | 199 | ||||
-rw-r--r-- | src/providers/ipa/ipa_init.c | 1 |
10 files changed, 365 insertions, 116 deletions
diff --git a/Makefile.am b/Makefile.am index 97d2bff4..29df594f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1067,6 +1067,7 @@ libsss_ipa_la_SOURCES = \ src/providers/ipa/ipa_hbac_hosts.c \ src/providers/ipa/ipa_hbac_private.h \ src/providers/ipa/ipa_hbac_rules.c \ + src/providers/ipa/ipa_hbac_rules.h \ src/providers/ipa/ipa_hbac_services.c \ src/providers/ipa/ipa_hbac_users.c \ src/providers/ipa/ipa_hbac_common.c \ diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c index 4ee3d82a..7d42e8b4 100644 --- a/src/providers/ipa/ipa_access.c +++ b/src/providers/ipa/ipa_access.c @@ -31,30 +31,7 @@ #include "providers/ipa/ipa_access.h" #include "providers/ipa/ipa_hbac.h" #include "providers/ipa/ipa_hbac_private.h" - -static char *get_hbac_search_base(TALLOC_CTX *mem_ctx, - struct dp_option *ipa_options) -{ - char *base; - int ret; - - base = dp_opt_get_string(ipa_options, IPA_HBAC_SEARCH_BASE); - if (base != NULL) { - return talloc_strdup(mem_ctx, base); - } - - DEBUG(9, ("ipa_hbac_search_base not available, trying base DN.\n")); - - ret = domain_to_basedn(mem_ctx, - dp_opt_get_string(ipa_options, IPA_KRB5_REALM), - &base); - if (ret != EOK) { - DEBUG(1, ("domain_to_basedn failed.\n")); - return NULL; - } - - return base; -} +#include "providers/ipa/ipa_hbac_rules.h" static void ipa_access_reply(struct hbac_ctx *hbac_ctx, int pam_status) { @@ -119,9 +96,8 @@ void ipa_access_handler(struct be_req *be_req) hbac_ctx->sdap_ctx = ipa_access_ctx->sdap_ctx; hbac_ctx->ipa_options = ipa_access_ctx->ipa_options; hbac_ctx->tr_ctx = ipa_access_ctx->tr_ctx; - hbac_ctx->hbac_search_base = get_hbac_search_base(hbac_ctx, - hbac_ctx->ipa_options); - if (hbac_ctx->hbac_search_base == NULL) { + hbac_ctx->search_bases = ipa_access_ctx->hbac_search_bases; + if (hbac_ctx->search_bases == NULL) { DEBUG(1, ("No HBAC search base found.\n")); goto fail; } @@ -334,7 +310,7 @@ static void hbac_get_service_info_step(struct tevent_req *req) hbac_ctx_sysdb(hbac_ctx), sdap_id_op_handle(hbac_ctx->sdap_op), hbac_ctx_sdap_id_ctx(hbac_ctx)->opts, - hbac_ctx->hbac_search_base); + hbac_ctx->search_bases); if (req == NULL) { DEBUG(1,("Could not get service info\n")); goto fail; @@ -399,7 +375,7 @@ static void hbac_get_rule_info_step(struct tevent_req *req) hbac_ctx_ev(hbac_ctx), sdap_id_op_handle(hbac_ctx->sdap_op), hbac_ctx_sdap_id_ctx(hbac_ctx)->opts, - hbac_ctx->hbac_search_base, + hbac_ctx->search_bases, hbac_ctx->ipa_host); if (req == NULL) { DEBUG(1, ("Could not get rules\n")); diff --git a/src/providers/ipa/ipa_access.h b/src/providers/ipa/ipa_access.h index e695acd8..65571013 100644 --- a/src/providers/ipa/ipa_access.h +++ b/src/providers/ipa/ipa_access.h @@ -46,6 +46,7 @@ struct ipa_access_ctx { time_t last_update; struct sdap_search_base **host_search_bases; + struct sdap_search_base **hbac_search_bases; }; struct hbac_ctx { @@ -57,7 +58,7 @@ struct hbac_ctx { struct be_req *be_req; struct pam_data *pd; - char *hbac_search_base; + struct sdap_search_base **search_bases; /* Hosts */ size_t host_count; diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c index 2e6dad8a..9f1178a9 100644 --- a/src/providers/ipa/ipa_common.c +++ b/src/providers/ipa/ipa_common.c @@ -572,7 +572,7 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, goto done; } - DEBUG(6, ("Option %s set to %s\n", + DEBUG(SSSDBG_CONF_SETTINGS, ("Option %s set to %s\n", ipa_opts->basic[IPA_HOST_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->basic, IPA_HOST_SEARCH_BASE))); @@ -582,6 +582,29 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, &ipa_opts->host_search_bases); if (ret != EOK) goto done; + if (NULL == dp_opt_get_string(ipa_opts->basic, + IPA_HBAC_SEARCH_BASE)) { + value = talloc_asprintf(tmpctx, "cn=hbac,%s", basedn); + if (!value) { + ret = ENOMEM; + goto done; + } + + ret = dp_opt_set_string(ipa_opts->basic, IPA_HBAC_SEARCH_BASE, value); + if (ret != EOK) { + goto done; + } + + DEBUG(6, ("Option %s set to %s\n", + ipa_opts->basic[IPA_HBAC_SEARCH_BASE].opt_name, + dp_opt_get_string(ipa_opts->basic, + IPA_HBAC_SEARCH_BASE))); + } + ret = sdap_parse_search_base(ipa_opts->basic, ipa_opts->basic, + IPA_HBAC_SEARCH_BASE, + &ipa_opts->hbac_search_bases); + if (ret != EOK) goto done; + value = dp_opt_get_string(ipa_opts->id->basic, SDAP_DEREF); if (value != NULL) { ret = deref_string_to_val(value, &i); diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h index 9cbd993f..49afe74d 100644 --- a/src/providers/ipa/ipa_common.h +++ b/src/providers/ipa/ipa_common.h @@ -98,6 +98,7 @@ struct ipa_options { struct dp_option *basic; struct sdap_search_base **host_search_bases; + struct sdap_search_base **hbac_search_bases; struct ipa_service *service; /* id provider */ diff --git a/src/providers/ipa/ipa_hbac_private.h b/src/providers/ipa/ipa_hbac_private.h index 6920f9e1..8d735b8b 100644 --- a/src/providers/ipa/ipa_hbac_private.h +++ b/src/providers/ipa/ipa_hbac_private.h @@ -144,7 +144,7 @@ ipa_hbac_service_info_send(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sdap_handle *sh, struct sdap_options *opts, - const char *search_base); + struct sdap_search_base **search_bases); errno_t ipa_hbac_service_info_recv(struct tevent_req *req, @@ -166,22 +166,6 @@ get_ipa_servicegroupname(TALLOC_CTX *mem_ctx, const char *service_dn, char **servicename); -/* From ipa_hbac_rules.c */ -struct tevent_req * -ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx, - bool get_deny_rules, - struct tevent_context *ev, - struct sdap_handle *sh, - struct sdap_options *opts, - const char *search_base, - struct sysdb_attrs *ipa_host); - -errno_t -ipa_hbac_rule_info_recv(struct tevent_req *req, - TALLOC_CTX *mem_ctx, - size_t *rule_count, - struct sysdb_attrs ***rules); - /* From ipa_hbac_users.c */ errno_t hbac_user_attrs_to_rule(TALLOC_CTX *mem_ctx, diff --git a/src/providers/ipa/ipa_hbac_rules.c b/src/providers/ipa/ipa_hbac_rules.c index 0b567dab..c07cf332 100644 --- a/src/providers/ipa/ipa_hbac_rules.c +++ b/src/providers/ipa/ipa_hbac_rules.c @@ -22,15 +22,28 @@ #include "util/util.h" #include "providers/ipa/ipa_hbac_private.h" +#include "providers/ipa/ipa_hbac_rules.h" #include "providers/ldap/sdap_async.h" struct ipa_hbac_rule_state { + struct tevent_context *ev; + struct sdap_handle *sh; struct sdap_options *opts; + int search_base_iter; + struct sdap_search_base **search_bases; + + const char **attrs; + char *rules_filter; + char *cur_filter; + size_t rule_count; struct sysdb_attrs **rules; }; +static errno_t +ipa_hbac_rule_info_next(struct tevent_req *req, + struct ipa_hbac_rule_state *state); static void ipa_hbac_rule_info_done(struct tevent_req *subreq); @@ -40,13 +53,12 @@ ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, struct sdap_options *opts, - const char *search_base, + struct sdap_search_base **search_bases, struct sysdb_attrs *ipa_host) { errno_t ret; size_t i; struct tevent_req *req = NULL; - struct tevent_req *subreq; struct ipa_hbac_rule_state *state; TALLOC_CTX *tmp_ctx; const char *host_dn; @@ -54,21 +66,6 @@ ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx, char *host_group_clean; char *rule_filter; const char **memberof_list; - const char *rule_attrs[] = { OBJECTCLASS, - IPA_CN, - 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 }; if (ipa_host == NULL) { DEBUG(1, ("Missing host\n")); @@ -93,7 +90,31 @@ ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx, return NULL; } + state->ev = ev; + state->sh = sh; state->opts = opts; + state->search_bases = search_bases; + state->search_base_iter = 0; + state->attrs = talloc_zero_array(state, const char *, 15); + if (state->attrs == NULL) { + ret = ENOMEM; + goto immediate; + } + state->attrs[0] = OBJECTCLASS; + state->attrs[1] = IPA_CN; + state->attrs[2] = IPA_UNIQUE_ID; + state->attrs[3] = IPA_ENABLED_FLAG; + state->attrs[4] = IPA_ACCESS_RULE_TYPE; + state->attrs[5] = IPA_MEMBER_USER; + state->attrs[6] = IPA_USER_CATEGORY; + state->attrs[7] = IPA_MEMBER_SERVICE; + state->attrs[8] = IPA_SERVICE_CATEGORY; + state->attrs[9] = IPA_SOURCE_HOST; + state->attrs[10] = IPA_SOURCE_HOST_CATEGORY; + state->attrs[11] = IPA_EXTERNAL_HOST; + state->attrs[12] = IPA_MEMBER_HOST; + state->attrs[13] = IPA_HOST_CATEGORY; + state->attrs[14] = NULL; if (get_deny_rules) { rule_filter = talloc_asprintf(tmp_ctx, @@ -154,19 +175,16 @@ ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx, ret = ENOMEM; goto immediate; } - talloc_steal(state, rule_filter); + state->rules_filter = talloc_steal(state, rule_filter); - subreq = sdap_get_generic_send(state, ev, opts, sh, search_base, - LDAP_SCOPE_SUB, rule_filter, rule_attrs, - NULL, 0, - dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); - if (subreq == NULL) { - DEBUG(1, ("sdap_get_generic_send failed.\n")); - ret = ENOMEM; + ret = ipa_hbac_rule_info_next(req, state); + if (ret == EOK) { + ret = EINVAL; + } + + if (ret != EAGAIN) { goto immediate; } - tevent_req_set_callback(subreq, ipa_hbac_rule_info_done, req); talloc_free(tmp_ctx); return req; @@ -186,6 +204,45 @@ error: return NULL; } +static errno_t +ipa_hbac_rule_info_next(struct tevent_req *req, + struct ipa_hbac_rule_state *state) +{ + struct tevent_req *subreq; + struct sdap_search_base *base; + + base = state->search_bases[state->search_base_iter]; + if (base == NULL) { + return EOK; + } + + talloc_zfree(state->cur_filter); + state->cur_filter = sdap_get_id_specific_filter(state, + state->rules_filter, + base->filter); + if (state->cur_filter == NULL) { + return ENOMEM; + } + + DEBUG(SSSDBG_TRACE_FUNC, ("Sending request for next search base: " + "[%s][%d][%s]\n", base->basedn, base->scope, + base->filter)); + + subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, + base->basedn, base->scope, + state->cur_filter, state->attrs, + NULL, 0, + dp_opt_get_int(state->opts->basic, + SDAP_ENUM_SEARCH_TIMEOUT)); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("sdap_get_generic_send failed.\n")); + return ENOMEM; + } + tevent_req_set_callback(subreq, ipa_hbac_rule_info_done, req); + + return EAGAIN; +} + static void ipa_hbac_rule_info_done(struct tevent_req *subreq) { @@ -194,21 +251,59 @@ ipa_hbac_rule_info_done(struct tevent_req *subreq) tevent_req_callback_data(subreq, struct tevent_req); struct ipa_hbac_rule_state *state = tevent_req_data(req, struct ipa_hbac_rule_state); + int i; + size_t rule_count; + size_t total_count; + struct sysdb_attrs **rules; + struct sysdb_attrs **target; ret = sdap_get_generic_recv(subreq, state, - &state->rule_count, - &state->rules); + &rule_count, + &rules); if (ret != EOK) { DEBUG(3, ("Could not retrieve HBAC rules\n")); - tevent_req_error(req, ret); + goto fail; + } + + if (rule_count > 0) { + total_count = rule_count + state->rule_count; + state->rules = talloc_realloc(state, state->rules, + struct sysdb_attrs *, + total_count); + if (state->rules == NULL) { + ret = ENOMEM; + goto fail; + } + + i = 0; + while (state->rule_count < total_count) { + target = &state->rules[state->rule_count]; + *target = talloc_steal(state->rules, rules[i]); + + state->rule_count++; + i++; + } + } + + state->search_base_iter++; + ret = ipa_hbac_rule_info_next(req, state); + if (ret == EAGAIN) { return; - } else if (state->rule_count == 0) { + } else if (ret != EOK) { + goto fail; + } else if (ret == EOK && state->rule_count == 0) { DEBUG(3, ("No rules apply to this host\n")); tevent_req_error(req, ENOENT); return; } + /* We went through all search bases and we have some results */ tevent_req_done(req); + + return; + +fail: + tevent_req_error(req, ret); } errno_t diff --git a/src/providers/ipa/ipa_hbac_rules.h b/src/providers/ipa/ipa_hbac_rules.h new file mode 100644 index 00000000..31ff3048 --- /dev/null +++ b/src/providers/ipa/ipa_hbac_rules.h @@ -0,0 +1,42 @@ +/* + SSSD + + Authors: + Jan Zeleny <jzeleny@redhat.com> + + Copyright (C) 2012 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef IPA_HBAC_RULES_H_ +#define IPA_HBAC_RULES_H_ + +/* From ipa_hbac_rules.c */ +struct tevent_req * +ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx, + bool get_deny_rules, + struct tevent_context *ev, + struct sdap_handle *sh, + struct sdap_options *opts, + struct sdap_search_base **search_bases, + struct sysdb_attrs *ipa_host); + +errno_t +ipa_hbac_rule_info_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + size_t *rule_count, + struct sysdb_attrs ***rules); + +#endif /* IPA_HBAC_RULES_H_ */ diff --git a/src/providers/ipa/ipa_hbac_services.c b/src/providers/ipa/ipa_hbac_services.c index cc4e6dea..3bbdc8ba 100644 --- a/src/providers/ipa/ipa_hbac_services.c +++ b/src/providers/ipa/ipa_hbac_services.c @@ -29,9 +29,14 @@ struct ipa_hbac_service_state { struct sysdb_ctx *sysdb; struct sdap_handle *sh; struct sdap_options *opts; - const char *search_base; const char **attrs; + char *service_filter; + char *cur_filter; + + struct sdap_search_base **search_bases; + int search_base_iter; + /* Return values */ size_t service_count; struct sysdb_attrs **services; @@ -40,8 +45,14 @@ struct ipa_hbac_service_state { struct sysdb_attrs **servicegroups; }; +static errno_t +ipa_hbac_service_info_next(struct tevent_req *req, + struct ipa_hbac_service_state *state); static void ipa_hbac_service_info_done(struct tevent_req *subreq); +static errno_t +ipa_hbac_servicegroup_info_next(struct tevent_req *req, + struct ipa_hbac_service_state *state); static void ipa_hbac_servicegroup_info_done(struct tevent_req *subreq); @@ -51,12 +62,11 @@ ipa_hbac_service_info_send(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sdap_handle *sh, struct sdap_options *opts, - const char *search_base) + struct sdap_search_base **search_bases) { errno_t ret; struct ipa_hbac_service_state *state; struct tevent_req *req; - struct tevent_req *subreq; char *service_filter; req = tevent_req_create(mem_ctx, &state, struct ipa_hbac_service_state); @@ -69,7 +79,9 @@ ipa_hbac_service_info_send(TALLOC_CTX *mem_ctx, state->sysdb = sysdb; state->sh = sh; state->opts = opts; - state->search_base = search_base; + + state->search_bases = search_bases; + state->search_base_iter = 0; service_filter = talloc_asprintf(state, "(objectClass=%s)", IPA_HBAC_SERVICE); @@ -78,6 +90,9 @@ ipa_hbac_service_info_send(TALLOC_CTX *mem_ctx, goto immediate; } + state->service_filter = service_filter; + state->cur_filter = NULL; + state->attrs = talloc_array(state, const char *, 6); if (state->attrs == NULL) { DEBUG(1, ("Failed to allocate service attribute list.\n")); @@ -91,17 +106,14 @@ ipa_hbac_service_info_send(TALLOC_CTX *mem_ctx, state->attrs[4] = IPA_MEMBEROF; state->attrs[5] = NULL; - subreq = sdap_get_generic_send(state, ev, opts, sh, search_base, - LDAP_SCOPE_SUB, service_filter, - state->attrs, NULL, 0, - dp_opt_get_int(opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); - if (subreq == NULL) { - DEBUG(1, ("Error requesting service info\n")); - ret = EIO; + ret = ipa_hbac_service_info_next(req, state); + if (ret == EOK) { + ret = EINVAL; + } + + if (ret != EAGAIN) { goto immediate; } - tevent_req_set_callback(subreq, ipa_hbac_service_info_done, req); return req; @@ -115,6 +127,43 @@ immediate: return req; } +static errno_t ipa_hbac_service_info_next(struct tevent_req *req, + struct ipa_hbac_service_state *state) +{ + struct tevent_req *subreq; + struct sdap_search_base *base; + + base = state->search_bases[state->search_base_iter]; + if (base == NULL) { + return EOK; + } + + talloc_zfree(state->cur_filter); + state->cur_filter = sdap_get_id_specific_filter(state, + state->service_filter, + base->filter); + if (state->cur_filter == NULL) { + return ENOMEM; + } + + DEBUG(SSSDBG_TRACE_FUNC, ("Sending request for next search base: " + "[%s][%d][%s]\n", base->basedn, base->scope, + base->filter)); + subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, + base->basedn, base->scope, + state->cur_filter, + state->attrs, NULL, 0, + dp_opt_get_int(state->opts->basic, + SDAP_ENUM_SEARCH_TIMEOUT)); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Error requesting service info\n")); + return EIO; + } + tevent_req_set_callback(subreq, ipa_hbac_service_info_done, req); + + return EAGAIN; +} + static void ipa_hbac_service_info_done(struct tevent_req *subreq) { @@ -141,9 +190,14 @@ ipa_hbac_service_info_done(struct tevent_req *subreq) * There's no reason to try to process groups */ + state->search_base_iter++; + ret = ipa_hbac_service_info_next(req, state); + if (ret == EAGAIN) { + return; + } + state->service_count = 0; state->services = NULL; - ret = EOK; goto done; } @@ -162,18 +216,18 @@ ipa_hbac_service_info_done(struct tevent_req *subreq) goto done; } - /* Look up service groups */ - subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, - state->search_base, LDAP_SCOPE_SUB, - servicegroup_filter, state->attrs, NULL, 0, - dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); - if (subreq == NULL) { - DEBUG(1, ("Error requesting host info\n")); - ret = EIO; + talloc_zfree(state->service_filter); + state->service_filter = servicegroup_filter; + + state->search_base_iter = 0; + ret = ipa_hbac_servicegroup_info_next(req, state); + if (ret == EOK) { + ret = EINVAL; + } + + if (ret != EAGAIN) { goto done; } - tevent_req_set_callback(subreq, ipa_hbac_servicegroup_info_done, req); return; @@ -185,6 +239,44 @@ done: } } +static errno_t +ipa_hbac_servicegroup_info_next(struct tevent_req *req, + struct ipa_hbac_service_state *state) +{ + struct tevent_req *subreq; + struct sdap_search_base *base; + + base = state->search_bases[state->search_base_iter]; + if (base == NULL) { + return EOK; + } + + talloc_zfree(state->cur_filter); + state->cur_filter = sdap_get_id_specific_filter(state, + state->service_filter, + base->filter); + if (state->cur_filter == NULL) { + return ENOMEM; + } + + /* Look up service groups */ + DEBUG(SSSDBG_TRACE_FUNC, ("Sending request for next search base: " + "[%s][%d][%s]\n", base->basedn, base->scope, + base->filter)); + subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, + base->basedn, base->scope, + state->cur_filter, state->attrs, NULL, 0, + dp_opt_get_int(state->opts->basic, + SDAP_ENUM_SEARCH_TIMEOUT)); + if (subreq == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Error requesting servicegroup info\n")); + return EIO; + } + tevent_req_set_callback(subreq, ipa_hbac_servicegroup_info_done, req); + + return EAGAIN; +} + static void ipa_hbac_servicegroup_info_done(struct tevent_req *subreq) { @@ -193,28 +285,61 @@ ipa_hbac_servicegroup_info_done(struct tevent_req *subreq) tevent_req_callback_data(subreq, struct tevent_req); struct ipa_hbac_service_state *state = tevent_req_data(req, struct ipa_hbac_service_state); + size_t total_count; + size_t group_count; + struct sysdb_attrs **groups; + struct sysdb_attrs **target; + int i; ret = sdap_get_generic_recv(subreq, state, - &state->servicegroup_count, - &state->servicegroups); + &group_count, + &groups); talloc_zfree(subreq); if (ret != EOK) { goto done; } - ret = replace_attribute_name(IPA_MEMBER, SYSDB_ORIG_MEMBER, - state->servicegroup_count, - state->servicegroups); - if (ret != EOK) { - DEBUG(1, ("Could not replace attribute names\n")); - goto done; + if (group_count > 0) { + ret = replace_attribute_name(IPA_MEMBER, SYSDB_ORIG_MEMBER, + group_count, + groups); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Could not replace attribute names\n")); + goto done; + } + + ret = replace_attribute_name(IPA_MEMBEROF, SYSDB_ORIG_MEMBEROF, + state->servicegroup_count, + state->servicegroups); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Could not replace attribute names\n")); + goto done; + } + + total_count = state->servicegroup_count + group_count; + state->servicegroups = talloc_realloc(state, state->servicegroups, + struct sysdb_attrs *, + total_count); + if (state->servicegroups == NULL) { + ret = ENOMEM; + goto done; + } + + i = 0; + while (state->servicegroup_count < total_count) { + target = &state->servicegroups[state->servicegroup_count]; + *target = talloc_steal(state->servicegroups, groups[i]); + + state->servicegroup_count++; + i++; + } } - ret = replace_attribute_name(IPA_MEMBEROF, SYSDB_ORIG_MEMBEROF, - state->servicegroup_count, - state->servicegroups); - if (ret != EOK) { - DEBUG(1, ("Could not replace attribute names\n")); + state->search_base_iter++; + ret = ipa_hbac_servicegroup_info_next(req, state); + if (ret == EAGAIN) { + return; + } else if (ret != EOK) { goto done; } diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c index 78a102ae..b3544f74 100644 --- a/src/providers/ipa/ipa_init.c +++ b/src/providers/ipa/ipa_init.c @@ -375,6 +375,7 @@ int sssm_ipa_access_init(struct be_ctx *bectx, } ipa_access_ctx->sdap_ctx = id_ctx->sdap_id_ctx; ipa_access_ctx->host_search_bases = id_ctx->ipa_options->host_search_bases; + ipa_access_ctx->hbac_search_bases = id_ctx->ipa_options->hbac_search_bases; ret = dp_copy_options(ipa_access_ctx, ipa_options->basic, IPA_OPTS_BASIC, &ipa_access_ctx->ipa_options); |