Blame SOURCES/0022-KCM-Configurable-quotas-for-the-secdb-ccache-back-en.patch

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