252 lines
8.9 KiB
Diff
252 lines
8.9 KiB
Diff
From 109ed7ca1a82420798efdc6a9b019675a5bd0f4f Mon Sep 17 00:00:00 2001
|
|
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
Date: Wed, 7 Jun 2017 17:20:43 +0200
|
|
Subject: [PATCH 93/93] SECRETS: Support 0 as unlimited for the quotas
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Add a special value for all the quota-like settings that means 'no
|
|
limit'.
|
|
|
|
Because the responder also had a global limit on the size of the
|
|
accepted body (64kiB), this patch also removes the hardcoded limit and
|
|
instead keep track of the biggest quota value on startup.
|
|
|
|
Reviewed-by: Simo Sorce <simo@redhat.com>
|
|
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
|
|
---
|
|
src/man/sssd-secrets.5.xml | 3 +-
|
|
src/responder/secrets/local.c | 16 ++++++++++
|
|
src/responder/secrets/secsrv.c | 15 ++++++++++
|
|
src/responder/secrets/secsrv.h | 1 +
|
|
src/responder/secrets/secsrv_cmd.c | 6 +++-
|
|
src/responder/secrets/secsrv_private.h | 2 +-
|
|
src/tests/intg/test_secrets.py | 55 ++++++++++++++++++++++++++++++++++
|
|
7 files changed, 95 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/src/man/sssd-secrets.5.xml b/src/man/sssd-secrets.5.xml
|
|
index c74894c62ed70764ca680c3b1cfe7f903d280277..d43dcf21c6174f0e0780a76d831a1fd957358b51 100644
|
|
--- a/src/man/sssd-secrets.5.xml
|
|
+++ b/src/man/sssd-secrets.5.xml
|
|
@@ -173,7 +173,8 @@ systemctl enable sssd-secrets.service
|
|
</variablelist>
|
|
<para>
|
|
The following options affect only the secrets <quote>hive</quote>
|
|
- and therefore should be set in a per-hive subsection.
|
|
+ and therefore should be set in a per-hive subsection. Setting the
|
|
+ option to 0 means "unlimited".
|
|
</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
|
|
index 5e491ba98fdc5612db0c303258513302c1f1d9e3..5a8b67731137dd2597211dedf817b8a92a62aa05 100644
|
|
--- a/src/responder/secrets/local.c
|
|
+++ b/src/responder/secrets/local.c
|
|
@@ -397,6 +397,10 @@ static int local_db_check_containers_nest_level(struct local_db_req *lc_req,
|
|
{
|
|
int nest_level;
|
|
|
|
+ if (lc_req->quota->containers_nest_level == 0) {
|
|
+ return EOK;
|
|
+ }
|
|
+
|
|
/* We need do not care for the synthetic containers that constitute the
|
|
* base path (cn=<uidnumber>,cn=user,cn=secrets). */
|
|
nest_level = ldb_dn_get_comp_num(leaf_dn) - 3;
|
|
@@ -456,6 +460,10 @@ static int local_db_check_peruid_number_of_secrets(TALLOC_CTX *mem_ctx,
|
|
struct ldb_dn *cli_basedn = NULL;
|
|
int ret;
|
|
|
|
+ if (lc_req->quota->max_uid_secrets == 0) {
|
|
+ return EOK;
|
|
+ }
|
|
+
|
|
tmp_ctx = talloc_new(mem_ctx);
|
|
if (tmp_ctx == NULL) {
|
|
return ENOMEM;
|
|
@@ -501,6 +509,10 @@ static int local_db_check_number_of_secrets(TALLOC_CTX *mem_ctx,
|
|
struct ldb_dn *dn;
|
|
int ret;
|
|
|
|
+ if (lc_req->quota->max_secrets == 0) {
|
|
+ return EOK;
|
|
+ }
|
|
+
|
|
tmp_ctx = talloc_new(mem_ctx);
|
|
if (!tmp_ctx) return ENOMEM;
|
|
|
|
@@ -538,6 +550,10 @@ static int local_check_max_payload_size(struct local_db_req *lc_req,
|
|
{
|
|
int max_payload_size;
|
|
|
|
+ if (lc_req->quota->max_payload_size == 0) {
|
|
+ return EOK;
|
|
+ }
|
|
+
|
|
max_payload_size = lc_req->quota->max_payload_size * 1024; /* kb */
|
|
if (payload_size > max_payload_size) {
|
|
DEBUG(SSSDBG_OP_FAILURE,
|
|
diff --git a/src/responder/secrets/secsrv.c b/src/responder/secrets/secsrv.c
|
|
index 36b257c463ccaa1f552b2b4985932dc0d3b125aa..2b661b165ef0c174557f53012b2dbaa236a6e359 100644
|
|
--- a/src/responder/secrets/secsrv.c
|
|
+++ b/src/responder/secrets/secsrv.c
|
|
@@ -146,6 +146,16 @@ static int sec_get_hive_config(struct sec_ctx *sctx,
|
|
goto done;
|
|
}
|
|
|
|
+ if (hive_config->quota.max_payload_size == 0
|
|
+ || (sctx->max_payload_size != 0
|
|
+ && hive_config->quota.max_payload_size > sctx->max_payload_size)) {
|
|
+ /* If the quota is unlimited or it's larger than what
|
|
+ * we already have, save the total limit so we know how much to
|
|
+ * accept from clients
|
|
+ */
|
|
+ sctx->max_payload_size = hive_config->quota.max_payload_size;
|
|
+ }
|
|
+
|
|
ret = EOK;
|
|
|
|
done:
|
|
@@ -168,6 +178,11 @@ static int sec_get_config(struct sec_ctx *sctx)
|
|
goto fail;
|
|
}
|
|
|
|
+ /* Set the global max_payload to ridiculously small value so that either 0 (unlimited)
|
|
+ * or any sensible value overwrite it
|
|
+ */
|
|
+ sctx->max_payload_size = 1;
|
|
+
|
|
/* Read the global quota first -- this should be removed in a future release */
|
|
/* Note that this sets the defaults for the sec_config quota to be used
|
|
* in sec_get_hive_config()
|
|
diff --git a/src/responder/secrets/secsrv.h b/src/responder/secrets/secsrv.h
|
|
index afdd731fbd44d7bb280ffc0e55db9c39a926bf22..3023116402f8540dcf4436dcc0b6ea030d892468 100644
|
|
--- a/src/responder/secrets/secsrv.h
|
|
+++ b/src/responder/secrets/secsrv.h
|
|
@@ -49,6 +49,7 @@ struct sec_ctx {
|
|
|
|
struct sec_hive_config sec_config;
|
|
struct sec_hive_config kcm_config;
|
|
+ int max_payload_size;
|
|
|
|
struct provider_handle **providers;
|
|
};
|
|
diff --git a/src/responder/secrets/secsrv_cmd.c b/src/responder/secrets/secsrv_cmd.c
|
|
index b88680c3d7c3105d160de5c78e6d981b852318b9..fa5970504d9f67c6341ebd8276da76f0b608fd55 100644
|
|
--- a/src/responder/secrets/secsrv_cmd.c
|
|
+++ b/src/responder/secrets/secsrv_cmd.c
|
|
@@ -178,7 +178,8 @@ static void sec_append_string(TALLOC_CTX *memctx, char **dest,
|
|
static bool sec_too_much_data(struct sec_req_ctx *req, size_t length)
|
|
{
|
|
req->total_size += length;
|
|
- if (req->total_size > SEC_REQUEST_MAX_SIZE) {
|
|
+ if (req->max_payload_size > 0
|
|
+ && req->total_size > req->max_payload_size) {
|
|
DEBUG(SSSDBG_FATAL_FAILURE,
|
|
"Request too big, aborting client!\n");
|
|
return true;
|
|
@@ -513,6 +514,8 @@ static void sec_recv(struct cli_ctx *cctx)
|
|
{
|
|
struct sec_proto_ctx *prctx;
|
|
struct sec_req_ctx *req;
|
|
+ struct sec_ctx *sec_ctx = talloc_get_type(cctx->rctx->pvt_ctx,
|
|
+ struct sec_ctx);
|
|
char buffer[SEC_PACKET_MAX_RECV_SIZE];
|
|
struct sec_data data = { buffer,
|
|
SEC_PACKET_MAX_RECV_SIZE };
|
|
@@ -531,6 +534,7 @@ static void sec_recv(struct cli_ctx *cctx)
|
|
return;
|
|
}
|
|
req->cctx = cctx;
|
|
+ req->max_payload_size = sec_ctx->max_payload_size;
|
|
cctx->state_ctx = req;
|
|
http_parser_init(&prctx->parser, HTTP_REQUEST);
|
|
prctx->parser.data = req;
|
|
diff --git a/src/responder/secrets/secsrv_private.h b/src/responder/secrets/secsrv_private.h
|
|
index 2e68628f61a0a8e79cd48fb5a510221e6fc36c70..c4a0c5745e8db092d28cf1ef9cb397af0c7314cb 100644
|
|
--- a/src/responder/secrets/secsrv_private.h
|
|
+++ b/src/responder/secrets/secsrv_private.h
|
|
@@ -75,6 +75,7 @@ struct sec_req_ctx {
|
|
bool complete;
|
|
|
|
size_t total_size;
|
|
+ size_t max_payload_size;
|
|
|
|
char *request_url;
|
|
char *mapped_path;
|
|
@@ -151,7 +152,6 @@ bool sec_req_has_header(struct sec_req_ctx *req,
|
|
const char *name, const char *value);
|
|
|
|
/* secsrv_cmd.c */
|
|
-#define SEC_REQUEST_MAX_SIZE 65536
|
|
#define SEC_PACKET_MAX_RECV_SIZE 8192
|
|
|
|
int sec_send_data(int fd, struct sec_data *data);
|
|
diff --git a/src/tests/intg/test_secrets.py b/src/tests/intg/test_secrets.py
|
|
index 957a0a8ff9ce5e966b77ddf048eefc282b2711b6..15caa69582ea6fe5031df8150343412f0e68bd5e 100644
|
|
--- a/src/tests/intg/test_secrets.py
|
|
+++ b/src/tests/intg/test_secrets.py
|
|
@@ -545,3 +545,58 @@ def test_per_uid_limit(setup_for_uid_limit, secrets_cli):
|
|
# FIXME - at this point, it would be nice to test that another UID can
|
|
# still store secrets, but sadly socket_wrapper doesn't allow us to fake
|
|
# UIDs yet
|
|
+
|
|
+
|
|
+@pytest.fixture
|
|
+def setup_for_unlimited_quotas(request):
|
|
+ conf = unindent("""\
|
|
+ [sssd]
|
|
+ domains = local
|
|
+ services = nss
|
|
+
|
|
+ [domain/local]
|
|
+ id_provider = local
|
|
+
|
|
+ [secrets]
|
|
+ debug_level = 10
|
|
+
|
|
+ [secrets/secrets]
|
|
+ max_secrets = 0
|
|
+ max_uid_secrets = 0
|
|
+ max_payload_size = 0
|
|
+ containers_nest_level = 0
|
|
+ """).format(**locals())
|
|
+
|
|
+ create_conf_fixture(request, conf)
|
|
+ create_sssd_secrets_fixture(request)
|
|
+ return None
|
|
+
|
|
+
|
|
+def test_unlimited_quotas(setup_for_unlimited_quotas, secrets_cli):
|
|
+ """
|
|
+ Test that setting quotas to zero disabled any checks and lets
|
|
+ store whatever.
|
|
+ """
|
|
+ cli = secrets_cli
|
|
+
|
|
+ # test much larger amount of secrets that we allow by default
|
|
+ sec_value = "value"
|
|
+ for i in range(2048):
|
|
+ cli.set_secret(str(i), sec_value)
|
|
+
|
|
+ # test a much larger secret size than the default one
|
|
+ KILOBYTE = 1024
|
|
+ payload_size = 32 * KILOBYTE
|
|
+
|
|
+ sec_value = "x" * payload_size
|
|
+ cli.set_secret("foo", sec_value)
|
|
+
|
|
+ fooval = cli.get_secret("foo")
|
|
+ assert fooval == sec_value
|
|
+
|
|
+ # test a deep secret nesting structure
|
|
+ DEFAULT_CONTAINERS_NEST_LEVEL = 128
|
|
+ container = "mycontainer"
|
|
+ for i in range(DEFAULT_CONTAINERS_NEST_LEVEL):
|
|
+ container += "%s/" % str(i)
|
|
+ cli.create_container(container)
|
|
--
|
|
2.14.1
|
|
|