don't fetch all host groups if this option is set to false https://fedorahosted.org/sssd/ticket/1078
Jan
From fcf9accd7e0b52d56266c2c6426405b41ce418e2 Mon Sep 17 00:00:00 2001 From: Jan Zeleny <jzel...@redhat.com> Date: Fri, 4 Nov 2011 13:16:47 -0400 Subject: [PATCH] Add ipa_hbac_support_srchost option to IPA provider don't fetch all host groups if this option is false https://fedorahosted.org/sssd/ticket/1078 --- src/config/SSSDConfig.py | 1 + src/config/etc/sssd.api.d/sssd-ipa.conf | 1 + src/man/sssd-ipa.5.xml | 12 +++ src/providers/ipa/hbac_evaluator.c | 18 +++-- src/providers/ipa/ipa_access.c | 4 + src/providers/ipa/ipa_common.c | 3 +- src/providers/ipa/ipa_common.h | 1 + src/providers/ipa/ipa_hbac_common.c | 10 ++- src/providers/ipa/ipa_hbac_hosts.c | 119 ++++++++++++++++++++++++++++--- src/providers/ipa/ipa_hbac_private.h | 2 + 10 files changed, 148 insertions(+), 23 deletions(-) diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py index 87b1d63413cd914401aeccdc6ad2eec12af92a66..b6d1b6f070afd73dd0a32b1c58c6e312255c82fa 100644 --- a/src/config/SSSDConfig.py +++ b/src/config/SSSDConfig.py @@ -102,6 +102,7 @@ option_strings = { 'ipa_hbac_search_base' : _("Search base for HBAC related objects"), 'ipa_hbac_refresh' : _("The amount of time between lookups of the HBAC rules against the IPA server"), 'ipa_hbac_treat_deny_as' : _("If DENY rules are present, either DENY_ALL or IGNORE"), + 'ipa_hbac_support_srchost' : _("If set to false, host argument given by PAM will be ignored"), # [provider/krb5] 'krb5_kdcip' : _('Kerberos server address'), diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf index 9ea45285ec93c4afe0ea2210c5a27a68de894b3f..697db819cbb165f1c4febeb2c417607444221bbe 100644 --- a/src/config/etc/sssd.api.d/sssd-ipa.conf +++ b/src/config/etc/sssd.api.d/sssd-ipa.conf @@ -106,6 +106,7 @@ krb5_fast_principal = str, None, false [provider/ipa/access] ipa_hbac_refresh = int, None, false ipa_hbac_treat_deny_as = str, None, false +ipa_hbac_support_srchost = bool, None, false [provider/ipa/chpass] diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml index 2c1a0ed8c37b4429b1929637807d3cbedcca1d68..105f5c7283f70e3cb6fae978f19d966b02460d75 100644 --- a/src/man/sssd-ipa.5.xml +++ b/src/man/sssd-ipa.5.xml @@ -234,6 +234,18 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term>ipa_hbac_support_srchost (boolean)</term> + <listitem> + <para> + If this is set to false, then srchost as given + to SSSD by PAM will be ignored. + </para> + <para> + Default: false + </para> + </listitem> + </varlistentry> </variablelist> </para> diff --git a/src/providers/ipa/hbac_evaluator.c b/src/providers/ipa/hbac_evaluator.c index 476ad6482a697a070102a60c1109a46f2f350af8..b0b97edd67683a792fa7c066e1e6fc01f361d871 100644 --- a/src/providers/ipa/hbac_evaluator.c +++ b/src/providers/ipa/hbac_evaluator.c @@ -221,14 +221,16 @@ enum hbac_eval_result_int hbac_evaluate_rule(struct hbac_rule *rule, } /* Check source hosts */ - ret = hbac_evaluate_element(rule->srchosts, - hbac_req->srchost, - &matched); - if (ret != EOK) { - *error = HBAC_ERROR_UNPARSEABLE_RULE; - return HBAC_EVAL_MATCH_ERROR; - } else if (!matched) { - return HBAC_EVAL_UNMATCHED; + if (hbac_req->srchost) { + ret = hbac_evaluate_element(rule->srchosts, + hbac_req->srchost, + &matched); + if (ret != EOK) { + *error = HBAC_ERROR_UNPARSEABLE_RULE; + return HBAC_EVAL_MATCH_ERROR; + } else if (!matched) { + return HBAC_EVAL_UNMATCHED; + } } return HBAC_EVAL_MATCHED; } diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c index 10f1cb7e6e2685b9dc6ac7f05ae53a37ebce345e..657e1169b6dc9539fbd28f9bae48931f8717875a 100644 --- a/src/providers/ipa/ipa_access.c +++ b/src/providers/ipa/ipa_access.c @@ -299,6 +299,10 @@ static int hbac_get_host_info_step(struct hbac_ctx *hbac_ctx) hbac_ctx_be(hbac_ctx)->domain, sdap_id_op_handle(hbac_ctx->sdap_op), hbac_ctx_sdap_id_ctx(hbac_ctx)->opts, + dp_opt_get_bool(hbac_ctx->ipa_options, + IPA_HBAC_SUPPORT_SRCHOST), + dp_opt_get_string(hbac_ctx->ipa_options, + IPA_HOSTNAME), hbac_ctx->hbac_search_base); if (req == NULL) { DEBUG(1, ("Could not get host info\n")); diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c index 8f9d5d77955cb7b01bfac69fc4ba00b136f866f2..e361b276a769160d9d0ff50a47be819a079f641d 100644 --- a/src/providers/ipa/ipa_common.c +++ b/src/providers/ipa/ipa_common.c @@ -39,7 +39,8 @@ struct dp_option ipa_basic_opts[] = { { "ipa_hbac_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "ipa_hbac_refresh", DP_OPT_NUMBER, { .number = 5 }, NULL_NUMBER }, - { "ipa_hbac_treat_deny_as", DP_OPT_STRING, { "DENY_ALL" }, NULL_STRING } + { "ipa_hbac_treat_deny_as", DP_OPT_STRING, { "DENY_ALL" }, NULL_STRING }, + { "ipa_hbac_support_srchost", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE } }; struct dp_option ipa_def_ldap_opts[] = { diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h index 40c5e53205285d761a43f6f0a77764006a5d79ca..65749216ca02ab761d057a10195dda28dbedd43a 100644 --- a/src/providers/ipa/ipa_common.h +++ b/src/providers/ipa/ipa_common.h @@ -52,6 +52,7 @@ enum ipa_basic_opt { IPA_KRB5_REALM, IPA_HBAC_REFRESH, IPA_HBAC_DENY_METHOD, + IPA_HBAC_SUPPORT_SRCHOST, IPA_OPTS_BASIC /* opts counter */ }; diff --git a/src/providers/ipa/ipa_hbac_common.c b/src/providers/ipa/ipa_hbac_common.c index 8815dae182e9352b321546158ebe535e443f2ab6..1be4d6b6660ad9db7fde3476cefa6526ac9dc17d 100644 --- a/src/providers/ipa/ipa_hbac_common.c +++ b/src/providers/ipa/ipa_hbac_common.c @@ -461,9 +461,13 @@ hbac_ctx_to_eval_request(TALLOC_CTX *mem_ctx, rhost = pd->rhost; } - ret = hbac_eval_host_element(eval_req, sysdb, domain, - rhost, &eval_req->srchost); - if (ret != EOK) goto done; + if (dp_opt_get_bool(hbac_ctx->ipa_options, IPA_HBAC_SUPPORT_SRCHOST)) { + ret = hbac_eval_host_element(eval_req, sysdb, domain, + rhost, &eval_req->srchost); + if (ret != EOK) goto done; + } else { + eval_req->srchost = NULL; + } /* The target host is always the current machine */ thost = dp_opt_get_cstring(hbac_ctx->ipa_options, IPA_HOSTNAME); diff --git a/src/providers/ipa/ipa_hbac_hosts.c b/src/providers/ipa/ipa_hbac_hosts.c index 42a3f5c1b8946341abff1b5a5cafa8a07abfba3c..20bdc3af918d39c28b455ea7743ddaded9692fb7 100644 --- a/src/providers/ipa/ipa_hbac_hosts.c +++ b/src/providers/ipa/ipa_hbac_hosts.c @@ -34,12 +34,25 @@ struct ipa_hbac_host_state { const char *search_base; const char **attrs; + bool support_srchost; + const char *hostname; + /* Return values */ size_t host_count; struct sysdb_attrs **hosts; size_t hostgroup_count; struct sysdb_attrs **hostgroups; + struct sdap_attr_map_info *hostgroup_map; +}; + +#define HOSTGROUP_MAP_ATTRS_COUNT 5 +static struct sdap_attr_map hostgroup_map[] = { + {"objectclass", "ipahostgroup", "hostgroup", NULL}, + {"name_attr", IPA_CN, IPA_CN, NULL}, + {"member", IPA_MEMBER, IPA_MEMBER, NULL}, + {"memberof", IPA_MEMBEROF, IPA_MEMBEROF, NULL}, + {"ipa_id", IPA_UNIQUE_ID IPA_UNIQUE_ID, NULL} }; static void @@ -55,6 +68,8 @@ ipa_hbac_host_info_send(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, struct sdap_handle *sh, struct sdap_options *opts, + bool support_srchost, + const char *hostname, const char *search_base) { errno_t ret; @@ -73,9 +88,20 @@ ipa_hbac_host_info_send(TALLOC_CTX *mem_ctx, state->dom = dom; state->sh = sh; state->opts = opts; + state->support_srchost = support_srchost; + state->hostname = hostname; state->search_base = search_base; - host_filter = talloc_asprintf(state, "(objectClass=%s)", IPA_HOST); + if (support_srchost) { + host_filter = talloc_asprintf(state, "(objectClass=%s)", IPA_HOST); + } else { + if (hostname == NULL) { + ret = EINVAL; + goto immediate; + } + host_filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=%s))", + IPA_HOST, IPA_HOST_FQDN, hostname); + } if (host_filter == NULL) { ret = ENOMEM; goto immediate; @@ -129,6 +155,8 @@ ipa_hbac_host_info_done(struct tevent_req *subreq) struct ipa_hbac_host_state *state = tevent_req_data(req, struct ipa_hbac_host_state); char *hostgroup_filter; + const char *host_dn; + int i; ret = sdap_get_generic_recv(subreq, state, &state->host_count, @@ -161,11 +189,46 @@ ipa_hbac_host_info_done(struct tevent_req *subreq) } /* Look up host groups */ - subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, - state->search_base, LDAP_SCOPE_SUB, - hostgroup_filter, state->attrs, NULL, 0, - dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + if (state->support_srchost) { + subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, + state->search_base, LDAP_SCOPE_SUB, + hostgroup_filter, state->attrs, NULL, 0, + dp_opt_get_int(state->opts->basic, + SDAP_ENUM_SEARCH_TIMEOUT)); + } else { + state->hostgroup_map = talloc_zero(state, struct sdap_attr_map_info); + if (state->hostgroup_map == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + state->hostgroup_map->map = hostgroup_map; + state->hostgroup_map->num_attrs = HOSTGROUP_MAP_ATTRS_COUNT; + + ret = sysdb_attrs_get_string(state->hosts[0], SYSDB_ORIG_DN, &host_dn); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + /* Complete the map */ + for (i = 0; i < HOSTGROUP_MAP_ATTRS_COUNT; i++) { + /* These are allocated on the state, so the next time they'll + * have to be allocated again + */ + hostgroup_map[i].name = talloc_strdup(state, + hostgroup_map[i].def_name); + if (hostgroup_map[i].name == NULL) { + tevent_req_error(req, ret); + return; + } + } + + subreq = sdap_deref_search_send(state, state->ev, state->opts, state->sh, + host_dn, IPA_MEMBEROF, state->attrs, + 1, state->hostgroup_map, + dp_opt_get_int(state->opts->basic, + SDAP_ENUM_SEARCH_TIMEOUT)); + } if (subreq == NULL) { DEBUG(1, ("Error requesting host info\n")); tevent_req_error(req, EIO); @@ -183,11 +246,45 @@ ipa_hbac_hostgroup_info_done(struct tevent_req *subreq) struct ipa_hbac_host_state *state = tevent_req_data(req, struct ipa_hbac_host_state); - ret = sdap_get_generic_recv(subreq, state, - &state->hostgroup_count, - &state->hostgroups); - talloc_zfree(subreq); - if (ret != EOK) goto done; + struct sdap_deref_attrs **deref_result; + const char *hostgroup_name; + int i; + + if (state->support_srchost) { + ret = sdap_get_generic_recv(subreq, state, + &state->hostgroup_count, + &state->hostgroups); + talloc_zfree(subreq); + if (ret != EOK) goto done; + } else { + ret = sdap_deref_search_recv(subreq, state, + &state->hostgroup_count, + &deref_result); + talloc_zfree(subreq); + if (ret != EOK) goto done; + + if (state->hostgroup_count == 0) { + DEBUG(SSSDBG_FUNC_DATA, ("No host groups were dereferenced\n")); + } else { + state->hostgroups = talloc_zero_array(state, struct sysdb_attrs *, + state->hostgroup_count); + if (state->hostgroups == NULL) { + ret = ENOMEM; + goto done; + } + + for (i = 0; i < state->hostgroup_count; i++) { + ret = sysdb_attrs_get_string(deref_result[i]->attrs, + IPA_CN, &hostgroup_name); + if (ret != EOK) goto done; + + DEBUG(SSSDBG_FUNC_DATA, ("Dereferenced host group: %s\n", + hostgroup_name)); + state->hostgroups[i] = talloc_steal(state->hostgroups, + deref_result[i]->attrs); + } + } + } ret = replace_attribute_name(IPA_MEMBER, SYSDB_ORIG_MEMBER, state->hostgroup_count, diff --git a/src/providers/ipa/ipa_hbac_private.h b/src/providers/ipa/ipa_hbac_private.h index 32b5d70ce8f648378cfbcb3edb36b958cf17f60f..d3d881bf1adae64943beee755abdbd9e0fc5dea7 100644 --- a/src/providers/ipa/ipa_hbac_private.h +++ b/src/providers/ipa/ipa_hbac_private.h @@ -106,6 +106,8 @@ ipa_hbac_host_info_send(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, struct sdap_handle *sh, struct sdap_options *opts, + bool support_srchost, + const char *hostname, const char *search_base); errno_t -- 1.7.6.4
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel