URL: https://github.com/SSSD/sssd/pull/36 Author: fidencio Title: #36: Partial fix for #3169 Action: synchronized
To pull the PR as Git branch: git remote add ghsssd https://github.com/SSSD/sssd git fetch ghsssd pull/36/head:pr36 git checkout pr36
From 3595d4c8f2ae2439c35ffe9401e3ca5f5ff19fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fiden...@redhat.com> Date: Fri, 30 Sep 2016 16:48:47 +0200 Subject: [PATCH] SECRETS: Add a configurable limit of secrets that can be stored Related: https://fedorahosted.org/sssd/ticket/3169 --- src/confdb/confdb.h | 1 + src/config/SSSDConfig/__init__.py.in | 1 + src/config/cfg_rules.ini | 1 + src/config/etc/sssd.api.conf | 1 + src/man/sssd-secrets.5.xml | 12 +++++++++ src/responder/secrets/local.c | 46 ++++++++++++++++++++++++++++++++++ src/responder/secrets/providers.c | 4 +++ src/responder/secrets/secsrv.c | 13 ++++++++++ src/responder/secrets/secsrv.h | 1 + src/responder/secrets/secsrv_private.h | 1 + src/tests/intg/test_secrets.py | 16 ++++++++++++ src/util/util_errors.c | 1 + src/util/util_errors.h | 1 + 13 files changed, 99 insertions(+) diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index dfbdbc7..011792f 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -224,6 +224,7 @@ /* Secrets Service */ #define CONFDB_SEC_CONF_ENTRY "config/secrets" #define CONFDB_SEC_CONTAINERS_NEST_LEVEL "containers_nest_level" +#define CONFDB_SEC_MAX_SECRETS "max_secrets" struct confdb_ctx; diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in index 74c2ca5..cde1964 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -121,6 +121,7 @@ option_strings = { # [secrets] 'provider': _('The provider where the secrets will be stored in'), 'containers_nest_level': _('The maximum allowed number of nested containers'), + 'max_secrets': _('The maximum number of secrets that can be stored'), # secrets - proxy 'proxy_url': _('The URL Custodia server is listening on'), 'auth_type': _('The method to use when authenticating to a Custodia server'), diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini index e6f23ff..b6316be 100644 --- a/src/config/cfg_rules.ini +++ b/src/config/cfg_rules.ini @@ -229,6 +229,7 @@ option = description # Secrets service option = provider option = containers_nest_level +option = max_secrets # Secrets service - proxy option = proxy_url option = auth_type diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf index a7757dc..567d52e 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -98,6 +98,7 @@ user_attributes = str, None, false # Secrets service provider = str, None, false containers_nest_level = int, None, false +max_secrets = int, None, false # Secrets service - proxy proxy_url = str, None, false auth_type = str, None, false diff --git a/src/man/sssd-secrets.5.xml b/src/man/sssd-secrets.5.xml index 1acaa98..7ec54c2 100644 --- a/src/man/sssd-secrets.5.xml +++ b/src/man/sssd-secrets.5.xml @@ -156,6 +156,18 @@ systemctl enable sssd-secrets.service </para> </listitem> </varlistentry> + <varlistentry> + <term>max_secrets (integer)</term> + <listitem> + <para> + This option specifies the maximum number of secrets that + can be stored. + </para> + <para> + Default: 1024 + </para> + </listitem> + </varlistentry> </variablelist> <para> The following options are only applicable for configurations that diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c index 295001c..f6c936f 100644 --- a/src/responder/secrets/local.c +++ b/src/responder/secrets/local.c @@ -30,6 +30,7 @@ struct local_context { struct ldb_context *ldb; struct sec_data master_key; int containers_nest_level; + int max_secrets; }; static int local_decrypt(struct local_context *lctx, TALLOC_CTX *mem_ctx, @@ -413,6 +414,42 @@ static int local_db_check_containers_nest_level(struct local_context *lctx, return EOK; } +static int local_db_check_number_of_secrets(TALLOC_CTX *mem_ctx, + struct local_context *lctx) +{ + TALLOC_CTX *tmp_ctx; + static const char *attrs[] = { NULL }; + struct ldb_result *res = NULL; + struct ldb_dn *dn; + int ret; + + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) return ENOMEM; + + dn = ldb_dn_new(tmp_ctx, lctx->ldb, "cn=secrets"); + if (!dn) { + ret = ENOMEM; + goto done; + } + + ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE, + attrs, LOCAL_SIMPLE_FILTER); + if (res->count >= lctx->max_secrets) { + DEBUG(SSSDBG_OP_FAILURE, + "Cannot store any more secrets as the maximum allowed limit (%d) " + "has been reached\n", lctx->max_secrets); + + ret = ERR_SEC_INVALID_TOO_MANY_SECRETS; + goto done; + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + static int local_db_put_simple(TALLOC_CTX *mem_ctx, struct local_context *lctx, const char *req_path, @@ -447,6 +484,14 @@ static int local_db_put_simple(TALLOC_CTX *mem_ctx, goto done; } + ret = local_db_check_number_of_secrets(msg, lctx); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "local_db_check_number_of_secrets failed [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + ret = local_encrypt(lctx, msg, secret, enctype, &enc_secret); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, @@ -927,6 +972,7 @@ int local_secrets_provider_handle(struct sec_ctx *sctx, } lctx->containers_nest_level = sctx->containers_nest_level; + lctx->max_secrets = sctx->max_secrets; lctx->master_key.data = talloc_size(lctx, MKEY_SIZE); if (!lctx->master_key.data) return ENOMEM; diff --git a/src/responder/secrets/providers.c b/src/responder/secrets/providers.c index 8cbc615..5f4b0fc 100644 --- a/src/responder/secrets/providers.c +++ b/src/responder/secrets/providers.c @@ -182,6 +182,8 @@ static struct sec_http_status_format_table { "The server encountered an internal error." }, { 504, "Gateway timeout", "No response from a proxy server." }, + { 507, "Insufficient Storage", + "The server is unable to store the resource needed to complete the request." }, }; int sec_http_status_reply(TALLOC_CTX *mem_ctx, struct sec_data *reply, @@ -352,6 +354,8 @@ enum sec_http_status_codes sec_errno_to_http_status(errno_t err) return STATUS_409; case ERR_SEC_NO_PROXY: return STATUS_504; + case ERR_SEC_INVALID_TOO_MANY_SECRETS: + return STATUS_507; default: return STATUS_500; } diff --git a/src/responder/secrets/secsrv.c b/src/responder/secrets/secsrv.c index 4bbc1dc..4c0824b 100644 --- a/src/responder/secrets/secsrv.c +++ b/src/responder/secrets/secsrv.c @@ -30,6 +30,7 @@ #define DEFAULT_SEC_FD_LIMIT 2048 #define DEFAULT_SEC_CONTAINERS_NEST_LEVEL 4 +#define DEFAULT_SEC_MAX_SECRETS 1024 static int sec_get_config(struct sec_ctx *sctx) { @@ -58,6 +59,18 @@ static int sec_get_config(struct sec_ctx *sctx) goto fail; } + ret = confdb_get_int(sctx->rctx->cdb, + sctx->rctx->confdb_service_path, + CONFDB_SEC_MAX_SECRETS, + DEFAULT_SEC_MAX_SECRETS, + &sctx->max_secrets); + + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Failed to get maximum number of entries\n"); + goto fail; + } + ret = confdb_get_int(sctx->rctx->cdb, sctx->rctx->confdb_service_path, CONFDB_RESPONDER_CLI_IDLE_TIMEOUT, CONFDB_RESPONDER_CLI_IDLE_DEFAULT_TIMEOUT, diff --git a/src/responder/secrets/secsrv.h b/src/responder/secrets/secsrv.h index 8ef89ab..972d342 100644 --- a/src/responder/secrets/secsrv.h +++ b/src/responder/secrets/secsrv.h @@ -39,6 +39,7 @@ struct sec_ctx { struct resp_ctx *rctx; int fd_limit; int containers_nest_level; + int max_secrets; struct provider_handle **providers; }; diff --git a/src/responder/secrets/secsrv_private.h b/src/responder/secrets/secsrv_private.h index ef7e299..4129fe6 100644 --- a/src/responder/secrets/secsrv_private.h +++ b/src/responder/secrets/secsrv_private.h @@ -48,6 +48,7 @@ enum sec_http_status_codes { STATUS_409, STATUS_500, STATUS_504, + STATUS_507, }; struct sec_proto_ctx { diff --git a/src/tests/intg/test_secrets.py b/src/tests/intg/test_secrets.py index c77c2a4..b2beb5b 100644 --- a/src/tests/intg/test_secrets.py +++ b/src/tests/intg/test_secrets.py @@ -84,6 +84,9 @@ def setup_for_secrets(request): [domain/local] id_provider = local + + [secrets] + max_secrets = 10 """).format(**locals()) create_conf_fixture(request, conf) @@ -136,6 +139,19 @@ def test_crd_ops(setup_for_secrets, secrets_cli): cli.del_secret("foo") assert str(err404.value).startswith("404") + # Don't allow storing more secrets after reaching the max + # number of entries. + MAX_SECRETS = 10 + + sec_value = "value" + for x in xrange(MAX_SECRETS): + cli.set_secret(str(x), sec_value) + + with pytest.raises(HTTPError) as err507: + cli.set_secret(str(MAX_SECRETS), sec_value) + print >>stderr,str(err507.value) + assert str(err507.value).startswith("507") + def test_containers(setup_for_secrets, secrets_cli): """ diff --git a/src/util/util_errors.c b/src/util/util_errors.c index 9cd562c..db5130c 100644 --- a/src/util/util_errors.c +++ b/src/util/util_errors.c @@ -100,6 +100,7 @@ struct err_string error_to_str[] = { { "The internal name format cannot be parsed" }, /* ERR_WRONG_NAME_FORMAT */ { "The maximum level of nested containers has been reached" }, /* ERR_SEC_INVALID_CONTAINERS_NEST_LEVEL */ { "No proxy server for secrets available"}, /* ERR_SEC_NO_PROXY */ + { "The maximum number of stored secrets has been reached" }, /* ERR_SEC_INVALID_TOO_MANY_SECRETS */ { "ERR_LAST" } /* ERR_LAST */ }; diff --git a/src/util/util_errors.h b/src/util/util_errors.h index ebb9920..3690b7e 100644 --- a/src/util/util_errors.h +++ b/src/util/util_errors.h @@ -122,6 +122,7 @@ enum sssd_errors { ERR_WRONG_NAME_FORMAT, ERR_SEC_INVALID_CONTAINERS_NEST_LEVEL, ERR_SEC_NO_PROXY, + ERR_SEC_INVALID_TOO_MANY_SECRETS, ERR_LAST /* ALWAYS LAST */ };
_______________________________________________ sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org