From f024b5e46b62ad49f0099ed8db8155e7ea475639 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 28 Nov 2018 21:22:22 +0100 Subject: [PATCH 22/23] KCM: Configurable quotas for the secdb ccache back end MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Related: https://pagure.io/SSSD/sssd/issue/3386 Exposes three new options for the [kcm] responder to set the global ccache limit, the per-uid ccache limit and the payload size. Reviewed-by: Michal Židek --- src/confdb/confdb.h | 3 ++ src/config/cfg_rules.ini | 3 ++ src/man/sssd-kcm.8.xml | 37 +++++++++++++++ src/responder/kcm/kcmsrv_ccache_secdb.c | 61 ++++++++++++++++++++++++- 4 files changed, 103 insertions(+), 1 deletion(-) diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index d09d6b4c3..727841659 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -266,6 +266,9 @@ #define CONFDB_KCM_CONF_ENTRY "config/kcm" #define CONFDB_KCM_SOCKET "socket_path" #define CONFDB_KCM_DB "ccache_storage" /* Undocumented on purpose */ +#define CONFDB_KCM_MAX_CCACHES "max_ccaches" +#define CONFDB_KCM_MAX_UID_CCACHES "max_uid_ccaches" +#define CONFDB_KCM_MAX_CCACHE_SIZE "max_ccache_size" /* Certificate mapping rules */ #define CONFDB_CERTMAP_BASEDN "cn=certmap,cn=config" diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini index 30040b595..59d6cc512 100644 --- a/src/config/cfg_rules.ini +++ b/src/config/cfg_rules.ini @@ -312,6 +312,9 @@ option = description option = socket_path option = ccache_storage option = responder_idle_timeout +option = max_ccaches +option = max_uid_ccaches +option = max_ccache_size # Session recording [rule/allowed_session_recording_options] diff --git a/src/man/sssd-kcm.8.xml b/src/man/sssd-kcm.8.xml index 4e4aaa38e..2f66e56a4 100644 --- a/src/man/sssd-kcm.8.xml +++ b/src/man/sssd-kcm.8.xml @@ -201,6 +201,43 @@ systemctl restart sssd-kcm.service + + max_ccaches (integer) + + + How many credential caches does the KCM database allow + for all users. + + + Default: 0 (unlimited, only the per-UID quota is enforced) + + + + + max_uid_ccaches (integer) + + + How many credential caches does the KCM database allow + per UID. This is equivalent to with how many + principals you can kinit. + + + Default: 64 + + + + + max_ccache_size (integer) + + + How big can a credential cache be per ccache. Each + service ticket accounts into this quota. + + + Default: 65536 + + + diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c index d0d9a7e4c..dc9cefb32 100644 --- a/src/responder/kcm/kcmsrv_ccache_secdb.c +++ b/src/responder/kcm/kcmsrv_ccache_secdb.c @@ -526,13 +526,72 @@ static errno_t ccdb_secdb_init(struct kcm_ccdb *db, { struct ccdb_secdb *secdb = NULL; errno_t ret; + struct sss_sec_hive_config **kcm_section_quota; + struct sss_sec_quota_opt dfl_kcm_nest_level = { + .opt_name = CONFDB_SEC_CONTAINERS_NEST_LEVEL, + .default_value = DEFAULT_SEC_CONTAINERS_NEST_LEVEL, + }; + struct sss_sec_quota_opt dfl_kcm_max_secrets = { + .opt_name = CONFDB_KCM_MAX_CCACHES, + .default_value = DEFAULT_SEC_KCM_MAX_SECRETS, + }; + struct sss_sec_quota_opt dfl_kcm_max_uid_secrets = { + .opt_name = CONFDB_KCM_MAX_UID_CCACHES, + .default_value = DEFAULT_SEC_KCM_MAX_UID_SECRETS, + }; + struct sss_sec_quota_opt dfl_kcm_max_payload_size = { + .opt_name = CONFDB_KCM_MAX_CCACHE_SIZE, + .default_value = DEFAULT_SEC_KCM_MAX_PAYLOAD_SIZE, + }; + secdb = talloc_zero(db, struct ccdb_secdb); if (secdb == NULL) { return ENOMEM; } - ret = sss_sec_init(db, NULL, &secdb->sctx); + kcm_section_quota = talloc_zero_array(secdb, + struct sss_sec_hive_config *, + 2); + if (kcm_section_quota == NULL) { + talloc_free(secdb); + return ENOMEM; + } + + kcm_section_quota[0] = talloc_zero(kcm_section_quota, + struct sss_sec_hive_config); + if (kcm_section_quota == NULL) { + talloc_free(secdb); + return ENOMEM; + } + kcm_section_quota[0]->hive_name = "kcm"; + + ret = sss_sec_get_quota(cdb, + confdb_service_path, + &dfl_kcm_nest_level, + &dfl_kcm_max_secrets, + &dfl_kcm_max_uid_secrets, + &dfl_kcm_max_payload_size, + &kcm_section_quota[0]->quota); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Failed to get KCM global quotas [%d]: %s\n", + ret, sss_strerror(ret)); + talloc_free(secdb); + return ret; + } + + if (kcm_section_quota[0]->quota.max_uid_secrets > 0) { + /* Even cn=default is considered a secret that adds up to + * the quota. To avoid off-by-one-confusion, increase + * the quota by two to 1) account for the cn=default object + * and 2) always allow writing to cn=defaults even if we + * are exactly at the quota limit + */ + kcm_section_quota[0]->quota.max_uid_secrets += 2; + } + + ret = sss_sec_init(db, kcm_section_quota, &secdb->sctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot initialize the security database\n"); -- 2.20.1