diff options
author | Fabiano FidĂȘncio <fidencio@redhat.com> | 2016-09-23 15:23:23 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2016-10-03 15:32:33 +0200 |
commit | efc65e78fa4e01e6cecc8690a9899af61213be62 (patch) | |
tree | 2093b436620d0164bfc352aac3a1981a6c438baf /src | |
parent | d806427f200dc1ffd44d37724eb40125af5cc8c2 (diff) | |
download | sssd-efc65e78fa4e01e6cecc8690a9899af61213be62.tar.gz sssd-efc65e78fa4e01e6cecc8690a9899af61213be62.tar.xz sssd-efc65e78fa4e01e6cecc8690a9899af61213be62.zip |
SECRETS: Add a configurable depth limit for nested containers
Resolves:
https://fedorahosted.org/sssd/ticket/3168
Signed-off-by: Fabiano FidĂȘncio <fidencio@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/confdb/confdb.h | 1 | ||||
-rw-r--r-- | src/config/SSSDConfig/__init__.py.in | 1 | ||||
-rw-r--r-- | src/config/cfg_rules.ini | 1 | ||||
-rw-r--r-- | src/config/etc/sssd.api.conf | 1 | ||||
-rw-r--r-- | src/man/sssd-secrets.5.xml | 12 | ||||
-rw-r--r-- | src/responder/secrets/local.c | 26 | ||||
-rw-r--r-- | src/responder/secrets/providers.c | 1 | ||||
-rw-r--r-- | src/responder/secrets/secsrv.c | 13 | ||||
-rw-r--r-- | src/responder/secrets/secsrv.h | 1 | ||||
-rw-r--r-- | src/tests/intg/test_secrets.py | 12 | ||||
-rw-r--r-- | src/util/util_errors.c | 1 | ||||
-rw-r--r-- | src/util/util_errors.h | 1 |
12 files changed, 71 insertions, 0 deletions
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index 36a2f21a0..dfbdbc7b9 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -223,6 +223,7 @@ /* Secrets Service */ #define CONFDB_SEC_CONF_ENTRY "config/secrets" +#define CONFDB_SEC_CONTAINERS_NEST_LEVEL "containers_nest_level" struct confdb_ctx; diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in index 15b9cd195..74c2ca5a7 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -120,6 +120,7 @@ option_strings = { # [secrets] 'provider': _('The provider where the secrets will be stored in'), + 'containers_nest_level': _('The maximum allowed number of nested containers'), # 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 4d9acf8da..e6f23ff34 100644 --- a/src/config/cfg_rules.ini +++ b/src/config/cfg_rules.ini @@ -228,6 +228,7 @@ option = description # Secrets service option = provider +option = containers_nest_level # 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 f94c8d17f..a7757dc13 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -97,6 +97,7 @@ user_attributes = str, None, false [secrets] # Secrets service provider = str, None, false +containers_nest_level = 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 71a79f5dd..1acaa987b 100644 --- a/src/man/sssd-secrets.5.xml +++ b/src/man/sssd-secrets.5.xml @@ -144,6 +144,18 @@ systemctl enable sssd-secrets.service </para> </listitem> </varlistentry> + <varlistentry> + <term>containers_nest_level (integer)</term> + <listitem> + <para> + This option specifies the maximum allowed number of nested + containers. + </para> + <para> + Default: 4 + </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 484e40643..ec8453798 100644 --- a/src/responder/secrets/local.c +++ b/src/responder/secrets/local.c @@ -29,6 +29,7 @@ struct local_context { struct ldb_context *ldb; struct sec_data master_key; + int containers_nest_level; }; static int local_decrypt(struct local_context *lctx, TALLOC_CTX *mem_ctx, @@ -332,6 +333,26 @@ done: return ret; } +static int local_db_check_containers_nest_level(struct local_context *lctx, + struct ldb_dn *leaf_dn) +{ + int nest_level; + + /* 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; + if (nest_level > lctx->containers_nest_level) { + DEBUG(SSSDBG_OP_FAILURE, + "Cannot create a nested container of depth %d as the maximum" + "allowed number of nested containers is %d.\n", + nest_level, lctx->containers_nest_level); + + return ERR_SEC_INVALID_CONTAINERS_NEST_LEVEL; + } + + return EOK; +} + static int local_db_put_simple(TALLOC_CTX *mem_ctx, struct local_context *lctx, const char *req_path, @@ -447,6 +468,9 @@ static int local_db_create(TALLOC_CTX *mem_ctx, ret = local_db_check_containers(msg, lctx, msg->dn); if (ret != EOK) goto done; + ret = local_db_check_containers_nest_level(lctx, msg->dn); + if (ret != EOK) goto done; + ret = ldb_msg_add_string(msg, "type", "container"); if (ret != EOK) goto done; @@ -708,6 +732,8 @@ int local_secrets_provider_handle(struct sec_ctx *sctx, return EIO; } + lctx->containers_nest_level = sctx->containers_nest_level; + lctx->master_key.data = talloc_size(lctx, MKEY_SIZE); if (!lctx->master_key.data) return ENOMEM; lctx->master_key.length = MKEY_SIZE; diff --git a/src/responder/secrets/providers.c b/src/responder/secrets/providers.c index 4c6019886..aedb49a15 100644 --- a/src/responder/secrets/providers.c +++ b/src/responder/secrets/providers.c @@ -306,6 +306,7 @@ enum sec_http_status_codes sec_errno_to_http_status(errno_t err) case EISDIR: return STATUS_405; case EMEDIUMTYPE: + case ERR_SEC_INVALID_CONTAINERS_NEST_LEVEL: return STATUS_406; case EEXIST: return STATUS_409; diff --git a/src/responder/secrets/secsrv.c b/src/responder/secrets/secsrv.c index eb194a179..4bbc1dc90 100644 --- a/src/responder/secrets/secsrv.c +++ b/src/responder/secrets/secsrv.c @@ -29,6 +29,7 @@ #include "resolv/async_resolv.h" #define DEFAULT_SEC_FD_LIMIT 2048 +#define DEFAULT_SEC_CONTAINERS_NEST_LEVEL 4 static int sec_get_config(struct sec_ctx *sctx) { @@ -45,6 +46,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_CONTAINERS_NEST_LEVEL, + DEFAULT_SEC_CONTAINERS_NEST_LEVEL, + &sctx->containers_nest_level); + + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Failed to get containers' maximum depth\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 ace30f86a..8ef89ab2e 100644 --- a/src/responder/secrets/secsrv.h +++ b/src/responder/secrets/secsrv.h @@ -38,6 +38,7 @@ struct sec_ctx { struct resolv_ctx *resctx; struct resp_ctx *rctx; int fd_limit; + int containers_nest_level; struct provider_handle **providers; }; diff --git a/src/tests/intg/test_secrets.py b/src/tests/intg/test_secrets.py index e394d1275..c77c2a470 100644 --- a/src/tests/intg/test_secrets.py +++ b/src/tests/intg/test_secrets.py @@ -160,3 +160,15 @@ def test_containers(setup_for_secrets, secrets_cli): # Try removing the secret first, then the container cli.del_secret("mycontainer/foo") cli.del_secret("mycontainer/") + + # Don't allow creating a container after reaching the max nested level + DEFAULT_CONTAINERS_NEST_LEVEL = 4 + container = "mycontainer" + for x in xrange(DEFAULT_CONTAINERS_NEST_LEVEL): + container += "%s/" % str(x) + cli.create_container(container) + + container += "%s/" % str(DEFAULT_CONTAINERS_NEST_LEVEL) + with pytest.raises(HTTPError) as err406: + cli.create_container(container) + assert str(err406.value).startswith("406") diff --git a/src/util/util_errors.c b/src/util/util_errors.c index 620be3c0a..7d4a7f559 100644 --- a/src/util/util_errors.c +++ b/src/util/util_errors.c @@ -98,6 +98,7 @@ struct err_string error_to_str[] = { { "Dereference threshold reached" }, /* ERR_DEREF_THRESHOLD */ { "The user is not handled by SSSD" }, /* ERR_NON_SSSD_USER */ { "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 */ { "ERR_LAST" } /* ERR_LAST */ }; diff --git a/src/util/util_errors.h b/src/util/util_errors.h index 1f00ba348..2cd55e19a 100644 --- a/src/util/util_errors.h +++ b/src/util/util_errors.h @@ -120,6 +120,7 @@ enum sssd_errors { ERR_DEREF_THRESHOLD, ERR_NON_SSSD_USER, ERR_WRONG_NAME_FORMAT, + ERR_SEC_INVALID_CONTAINERS_NEST_LEVEL, ERR_LAST /* ALWAYS LAST */ }; |