From bc854800cc67271205d63136daaf68d7863cea6b Mon Sep 17 00:00:00 2001 From: Justin Stephenson Date: Oct 19 2017 11:36:26 +0000 Subject: IPA: Add threshold for sudo searches Apply the sudo threshold to IPA provider sudo command and command group searches to prevent SSSD from creating large search filters. The IPA sudo threshold value will utilize the sudo responder sudo_threshold value. If the threshold is exceeded, a basic search filter will be used as a fallback to retrieve all IPA sudo commands or command groups. Resolves: https://pagure.io/SSSD/sssd/issue/3507 Reviewed-by: Pavel Březina --- diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml index 1149634..7752e45 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -1413,7 +1413,9 @@ pam_account_locked_message = Account locked, please contact help desk. with rules refresh mechanism. If the threshold is exceeded a full refresh of sudo rules is - triggered instead. + triggered instead. This threshold number also + applies to IPA sudo command and command group + searches. Default: 50 diff --git a/src/providers/ipa/ipa_sudo.c b/src/providers/ipa/ipa_sudo.c index c93d8ca..f2c9112 100644 --- a/src/providers/ipa/ipa_sudo.c +++ b/src/providers/ipa/ipa_sudo.c @@ -245,6 +245,14 @@ ipa_sudo_init_ipa_schema(TALLOC_CTX *mem_ctx, goto done; } + ret = confdb_get_int(be_ctx->cdb, CONFDB_SUDO_CONF_ENTRY, + CONFDB_SUDO_THRESHOLD, CONFDB_DEFAULT_SUDO_THRESHOLD, + &sudo_ctx->sudocmd_threshold); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Could not parse sudo search base\n"); + return ret; + } + ret = sdap_parse_search_base(sudo_ctx, sudo_ctx->sdap_opts->basic, SDAP_SUDO_SEARCH_BASE, &sudo_ctx->sudo_sb); diff --git a/src/providers/ipa/ipa_sudo.h b/src/providers/ipa/ipa_sudo.h index 49b6c56..5fc2b9a 100644 --- a/src/providers/ipa/ipa_sudo.h +++ b/src/providers/ipa/ipa_sudo.h @@ -33,6 +33,7 @@ struct ipa_sudo_ctx { struct sdap_attr_map *sudorule_map; struct sdap_attr_map *sudocmd_map; struct sdap_search_base **sudo_sb; + int sudocmd_threshold; }; errno_t @@ -105,13 +106,21 @@ ipa_sudo_conv_has_cmdgroups(struct ipa_sudo_conv *conv); bool ipa_sudo_conv_has_cmds(struct ipa_sudo_conv *conv); +bool +ipa_sudo_cmdgroups_exceed_threshold(struct ipa_sudo_conv *conv, int threshold); + +bool +ipa_sudo_cmds_exceed_threshold(struct ipa_sudo_conv *conv, int threshold); + char * ipa_sudo_conv_cmdgroup_filter(TALLOC_CTX *mem_ctx, - struct ipa_sudo_conv *conv); + struct ipa_sudo_conv *conv, + int cmd_threshold); char * ipa_sudo_conv_cmd_filter(TALLOC_CTX *mem_ctx, - struct ipa_sudo_conv *conv); + struct ipa_sudo_conv *conv, + int cmd_threshold); errno_t ipa_sudo_conv_result(TALLOC_CTX *mem_ctx, diff --git a/src/providers/ipa/ipa_sudo_async.c b/src/providers/ipa/ipa_sudo_async.c index 9ed1218..e24deb6 100644 --- a/src/providers/ipa/ipa_sudo_async.c +++ b/src/providers/ipa/ipa_sudo_async.c @@ -379,6 +379,7 @@ struct ipa_sudo_fetch_state { struct ipa_sudo_conv *conv; struct sysdb_attrs **rules; size_t num_rules; + int cmd_threshold; char *usn; }; @@ -430,6 +431,7 @@ ipa_sudo_fetch_send(TALLOC_CTX *mem_ctx, state->map_rule = sudo_ctx->sudorule_map; state->map_cmd = sudo_ctx->sudocmd_map; state->sudo_sb = sudo_ctx->sudo_sb; + state->cmd_threshold = sudo_ctx->sudocmd_threshold; state->conv = ipa_sudo_conv_init(state, domain, state->map_rule, state->map_cmdgroup, state->map_cmd, @@ -648,7 +650,9 @@ ipa_sudo_fetch_cmdgroups(struct tevent_req *req) return ipa_sudo_fetch_cmds(req); } - filter = ipa_sudo_conv_cmdgroup_filter(state, state->conv); + filter = ipa_sudo_conv_cmdgroup_filter(state, state->conv, + state->cmd_threshold); + if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n"); return ENOMEM; @@ -727,7 +731,8 @@ ipa_sudo_fetch_cmds(struct tevent_req *req) return EOK; } - filter = ipa_sudo_conv_cmd_filter(state, state->conv); + filter = ipa_sudo_conv_cmd_filter(state, state->conv, state->cmd_threshold); + if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n"); return ENOMEM; diff --git a/src/providers/ipa/ipa_sudo_conversion.c b/src/providers/ipa/ipa_sudo_conversion.c index f6d17d8..0df0db2 100644 --- a/src/providers/ipa/ipa_sudo_conversion.c +++ b/src/providers/ipa/ipa_sudo_conversion.c @@ -576,6 +576,17 @@ ipa_sudo_conv_has_cmds(struct ipa_sudo_conv *conv) return hash_count(conv->cmds) == 0; } +bool +ipa_sudo_cmdgroups_exceed_threshold(struct ipa_sudo_conv *conv, int threshold) +{ + return (hash_count(conv->cmdgroups)) > threshold; +} +bool +ipa_sudo_cmds_exceed_threshold(struct ipa_sudo_conv *conv, int threshold) +{ + return (hash_count(conv->cmds)) > threshold; +} + typedef errno_t (*ipa_sudo_conv_rdn_fn)(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, struct sysdb_ctx *sysdb, @@ -722,18 +733,36 @@ done: char * ipa_sudo_conv_cmdgroup_filter(TALLOC_CTX *mem_ctx, - struct ipa_sudo_conv *conv) + struct ipa_sudo_conv *conv, + int cmd_threshold) { - return build_filter(mem_ctx, conv->dom->sysdb, conv->cmdgroups, - conv->map_cmdgroup, get_sudo_cmdgroup_rdn); + if (ipa_sudo_cmdgroups_exceed_threshold(conv, cmd_threshold)) { + DEBUG(SSSDBG_TRACE_FUNC, + "Command threshold [%d] exceeded, retrieving all sudo command " + "groups\n", cmd_threshold); + return talloc_asprintf(mem_ctx, "(objectClass=%s)", + conv->map_cmdgroup->name); + } else { + return build_filter(mem_ctx, conv->dom->sysdb, conv->cmdgroups, + conv->map_cmdgroup, get_sudo_cmdgroup_rdn); + } } char * ipa_sudo_conv_cmd_filter(TALLOC_CTX *mem_ctx, - struct ipa_sudo_conv *conv) + struct ipa_sudo_conv *conv, + int cmd_threshold) { - return build_filter(mem_ctx, conv->dom->sysdb, conv->cmds, + if (ipa_sudo_cmdgroups_exceed_threshold(conv, cmd_threshold)) { + DEBUG(SSSDBG_TRACE_FUNC, + "Command threshold [%d] exceeded, retrieving all sudo commands\n", + cmd_threshold); + return talloc_asprintf(mem_ctx, "(objectClass=%s)", + conv->map_cmd->name); + } else { + return build_filter(mem_ctx, conv->dom->sysdb, conv->cmds, conv->map_cmd, get_sudo_cmd_rdn); + } } struct ipa_sudo_conv_result_ctx {