summaryrefslogtreecommitdiffstats
path: root/src/responder
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2017-04-04 15:33:38 +0200
committerLukas Slebodnik <lslebodn@redhat.com>2017-09-01 20:26:23 +0200
commit197da163943868216f704fb34031e7d5576e8aee (patch)
tree3987bbfb931f057945107dd760452e40285aecef /src/responder
parent392f48c039d7a6d70bce6ae2d122042391653566 (diff)
downloadsssd-197da163943868216f704fb34031e7d5576e8aee.tar.gz
sssd-197da163943868216f704fb34031e7d5576e8aee.tar.xz
sssd-197da163943868216f704fb34031e7d5576e8aee.zip
SECRETS: Use separate quotas for /kcm and /secrets hives
This would differentiate between out-of-capacity errors for secrets and for KCM as they are two independent trees as far as sssd-secrets is concerned. The quotas for /kcm are also different in their defaults. For the /secrets hive, we presume a large amount of small secrets. For the /kcm hive, we presume a small amount of large secrets, because the secret is a ccache which contains multiple credentials. The operations are also passed in a struct quota from the local request context instead of local_context. The quota is assigned to the request context when the hive is selected. Reviewed-by: Simo Sorce <simo@redhat.com> Reviewed-by: Fabiano FidĂȘncio <fidencio@redhat.com>
Diffstat (limited to 'src/responder')
-rw-r--r--src/responder/secrets/local.c46
-rw-r--r--src/responder/secrets/secsrv.c20
-rw-r--r--src/responder/secrets/secsrv.h1
3 files changed, 47 insertions, 20 deletions
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
index c833f1d27..58e70f8b6 100644
--- a/src/responder/secrets/local.c
+++ b/src/responder/secrets/local.c
@@ -36,6 +36,7 @@ struct local_context {
struct sec_data master_key;
struct sec_quota *quota_secrets;
+ struct sec_quota *quota_kcm;
};
static int local_decrypt(struct local_context *lctx, TALLOC_CTX *mem_ctx,
@@ -206,7 +207,9 @@ static char *local_dn_to_path(TALLOC_CTX *mem_ctx,
struct local_db_req {
char *path;
+ const char *basedn;
struct ldb_dn *req_dn;
+ struct sec_quota *quota;
};
#define LOCAL_SIMPLE_FILTER "(type=simple)"
@@ -389,7 +392,7 @@ done:
return ret;
}
-static int local_db_check_containers_nest_level(struct local_context *lctx,
+static int local_db_check_containers_nest_level(struct local_db_req *lc_req,
struct ldb_dn *leaf_dn)
{
int nest_level;
@@ -397,11 +400,11 @@ static int local_db_check_containers_nest_level(struct local_context *lctx,
/* 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->quota_secrets->containers_nest_level) {
+ if (nest_level > lc_req->quota->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->quota_secrets->containers_nest_level);
+ nest_level, lc_req->quota->containers_nest_level);
return ERR_SEC_INVALID_CONTAINERS_NEST_LEVEL;
}
@@ -410,7 +413,8 @@ static int local_db_check_containers_nest_level(struct local_context *lctx,
}
static int local_db_check_number_of_secrets(TALLOC_CTX *mem_ctx,
- struct local_context *lctx)
+ struct local_context *lctx,
+ struct local_db_req *lc_req)
{
TALLOC_CTX *tmp_ctx;
static const char *attrs[] = { NULL };
@@ -421,7 +425,7 @@ static int local_db_check_number_of_secrets(TALLOC_CTX *mem_ctx,
tmp_ctx = talloc_new(mem_ctx);
if (!tmp_ctx) return ENOMEM;
- dn = ldb_dn_new(tmp_ctx, lctx->ldb, "cn=secrets");
+ dn = ldb_dn_new(tmp_ctx, lctx->ldb, lc_req->basedn);
if (!dn) {
ret = ENOMEM;
goto done;
@@ -429,11 +433,10 @@ static int local_db_check_number_of_secrets(TALLOC_CTX *mem_ctx,
ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE,
attrs, LOCAL_SIMPLE_FILTER);
- if (res->count >= lctx->quota_secrets->max_secrets) {
+ if (res->count >= lc_req->quota->max_secrets) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot store any more secrets as the maximum allowed limit (%d) "
- "has been reached\n", lctx->quota_secrets->max_secrets);
-
+ "has been reached\n", lc_req->quota->max_secrets);
ret = ERR_SEC_INVALID_TOO_MANY_SECRETS;
goto done;
}
@@ -445,19 +448,19 @@ done:
return ret;
}
-static int local_check_max_payload_size(struct local_context *lctx,
+static int local_check_max_payload_size(struct local_db_req *lc_req,
int payload_size)
{
int max_payload_size;
- max_payload_size = lctx->quota_secrets->max_payload_size * 1024; /* kb */
+ max_payload_size = lc_req->quota->max_payload_size * 1024; /* kb */
if (payload_size > max_payload_size) {
DEBUG(SSSDBG_OP_FAILURE,
"Secrets' payload size [%d kb (%d)] exceeds the maximum allowed "
"payload size [%d kb (%d)]\n",
payload_size * 1024, /* kb */
payload_size,
- lctx->quota_secrets->max_payload_size, /* kb */
+ lc_req->quota->max_payload_size, /* kb */
max_payload_size);
return ERR_SEC_PAYLOAD_SIZE_IS_TOO_LARGE;
@@ -494,7 +497,7 @@ static int local_db_put_simple(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = local_db_check_number_of_secrets(msg, lctx);
+ ret = local_db_check_number_of_secrets(msg, lctx, lc_req);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"local_db_check_number_of_secrets failed [%d]: %s\n",
@@ -502,7 +505,7 @@ static int local_db_put_simple(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = local_check_max_payload_size(lctx, strlen(secret));
+ ret = local_check_max_payload_size(lc_req, strlen(secret));
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"local_check_max_payload_size failed [%d]: %s\n",
@@ -656,7 +659,7 @@ static int local_db_create(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = local_db_check_containers_nest_level(lctx, msg->dn);
+ ret = local_db_check_containers_nest_level(lc_req, msg->dn);
if (ret != EOK) goto done;
ret = ldb_msg_add_string(msg, "type", "container");
@@ -698,13 +701,13 @@ done:
}
static int local_secrets_map_path(TALLOC_CTX *mem_ctx,
- struct ldb_context *ldb,
+ struct local_context *lctx,
struct sec_req_ctx *secreq,
struct local_db_req **_lc_req)
{
int ret;
struct local_db_req *lc_req;
- const char *basedn;
+ struct ldb_context *ldb = lctx->ldb;
/* be strict for now */
if (secreq->parsed_url.fragment != NULL) {
@@ -742,12 +745,14 @@ static int local_secrets_map_path(TALLOC_CTX *mem_ctx,
SEC_BASEPATH, sizeof(SEC_BASEPATH) - 1) == 0) {
lc_req->path = talloc_strdup(lc_req,
secreq->mapped_path + (sizeof(SEC_BASEPATH) - 1));
- basedn = SECRETS_BASEDN;
+ lc_req->basedn = SECRETS_BASEDN;
+ lc_req->quota = lctx->quota_secrets;
} else if (strncmp(secreq->mapped_path,
SEC_KCM_BASEPATH, sizeof(SEC_KCM_BASEPATH) - 1) == 0) {
lc_req->path = talloc_strdup(lc_req,
secreq->mapped_path + (sizeof(SEC_KCM_BASEPATH) - 1));
- basedn = KCM_BASEDN;
+ lc_req->basedn = KCM_BASEDN;
+ lc_req->quota = lctx->quota_kcm;
} else {
ret = EINVAL;
goto done;
@@ -760,7 +765,7 @@ static int local_secrets_map_path(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = local_db_dn(mem_ctx, ldb, basedn, lc_req->path, &lc_req->req_dn);
+ ret = local_db_dn(mem_ctx, ldb, lc_req->basedn, lc_req->path, &lc_req->req_dn);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Failed to map request to local db DN\n");
@@ -829,7 +834,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
}
DEBUG(SSSDBG_TRACE_LIBS, "Content-Type: %s\n", content_type);
- ret = local_secrets_map_path(state, lctx->ldb, secreq, &lc_req);
+ ret = local_secrets_map_path(state, lctx, secreq, &lc_req);
if (ret) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot map request path to local path\n");
goto done;
@@ -1019,6 +1024,7 @@ int local_secrets_provider_handle(struct sec_ctx *sctx,
}
lctx->quota_secrets = &sctx->sec_config.quota;
+ lctx->quota_kcm = &sctx->kcm_config.quota;
lctx->master_key.data = talloc_size(lctx, MKEY_SIZE);
if (!lctx->master_key.data) return ENOMEM;
diff --git a/src/responder/secrets/secsrv.c b/src/responder/secrets/secsrv.c
index db12cbbc3..2fcdf8e6c 100644
--- a/src/responder/secrets/secsrv.c
+++ b/src/responder/secrets/secsrv.c
@@ -30,9 +30,17 @@
#define DEFAULT_SEC_FD_LIMIT 2048
#define DEFAULT_SEC_CONTAINERS_NEST_LEVEL 4
+
#define DEFAULT_SEC_MAX_SECRETS 1024
#define DEFAULT_SEC_MAX_PAYLOAD_SIZE 16
+/* The number of secrets in the /kcm hive should be quite small,
+ * but the secret size must be large because one secret in the /kcm
+ * hive holds the whole ccache which consists of several credentials
+ */
+#define DEFAULT_SEC_KCM_MAX_SECRETS 256
+#define DEFAULT_SEC_KCM_MAX_PAYLOAD_SIZE 65536
+
static int sec_get_quota(struct sec_ctx *sctx,
const char *section_config_path,
int default_max_containers_nest_level,
@@ -171,6 +179,18 @@ static int sec_get_config(struct sec_ctx *sctx)
goto fail;
}
+ ret = sec_get_hive_config(sctx,
+ "kcm",
+ &sctx->kcm_config,
+ DEFAULT_SEC_CONTAINERS_NEST_LEVEL,
+ DEFAULT_SEC_KCM_MAX_SECRETS,
+ DEFAULT_SEC_KCM_MAX_PAYLOAD_SIZE);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Failed to get configuration of the secrets hive\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 629b027f6..afc092764 100644
--- a/src/responder/secrets/secsrv.h
+++ b/src/responder/secrets/secsrv.h
@@ -47,6 +47,7 @@ struct sec_ctx {
int fd_limit;
struct sec_hive_config sec_config;
+ struct sec_hive_config kcm_config;
struct provider_handle **providers;
};