Skip to content

Commit

Permalink
KCM: Configurable quotas for the secdb ccache back end
Browse files Browse the repository at this point in the history
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 <mzidek@redhat.com>
  • Loading branch information
jhrozek committed Aug 7, 2019
1 parent f00db73 commit f024b5e
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/confdb/confdb.h
Expand Up @@ -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"
Expand Down
3 changes: 3 additions & 0 deletions src/config/cfg_rules.ini
Expand Up @@ -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]
Expand Down
37 changes: 37 additions & 0 deletions src/man/sssd-kcm.8.xml
Expand Up @@ -201,6 +201,43 @@ systemctl restart sssd-kcm.service
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>max_ccaches (integer)</term>
<listitem>
<para>
How many credential caches does the KCM database allow
for all users.
</para>
<para>
Default: 0 (unlimited, only the per-UID quota is enforced)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>max_uid_ccaches (integer)</term>
<listitem>
<para>
How many credential caches does the KCM database allow
per UID. This is equivalent to <quote>with how many
principals you can kinit</quote>.
</para>
<para>
Default: 64
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>max_ccache_size (integer)</term>
<listitem>
<para>
How big can a credential cache be per ccache. Each
service ticket accounts into this quota.
</para>
<para>
Default: 65536
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

Expand Down
61 changes: 60 additions & 1 deletion src/responder/kcm/kcmsrv_ccache_secdb.c
Expand Up @@ -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");
Expand Down

0 comments on commit f024b5e

Please sign in to comment.