Merged update from upstream sources

This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/sssd.git#9e5dd4b66572aeb348f3cc854ce7fca9f7afd97b
This commit is contained in:
DistroBaker 2021-02-05 19:50:48 +00:00
parent 6601f5da29
commit e9cffb7aa5
24 changed files with 214 additions and 4504 deletions

1
.gitignore vendored
View File

@ -89,3 +89,4 @@ sssd-1.2.91.tar.gz
/sssd-2.3.0.tar.gz
/sssd-2.3.1.tar.gz
/sssd-2.4.0.tar.gz
/sssd-2.4.1.tar.gz

View File

@ -0,0 +1,49 @@
From cf308d6c0e763336526b2e6295f1a075b217900f Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Fri, 5 Feb 2021 14:51:26 +0100
Subject: [PATCH] BUILD: fixes gpo_child linking issue
/usr/bin/ld: src/util/gpo_child-signal.o (symbol from plugin): undefined reference to symbol 'BlockSignals@@SAMBA_UTIL_0.0.1'
Resolves: https://github.com/SSSD/sssd/issues/5385
---
Makefile.am | 3 ++-
src/external/samba.m4 | 8 ++++++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/Makefile.am b/Makefile.am
index f0083ffd7aaec01d87d9e38569b4714b3dbb2caa..41fc6517beec348daf58ce4d41f03a444901c81c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4738,7 +4738,8 @@ gpo_child_LDADD = \
$(POPT_LIBS) \
$(DHASH_LIBS) \
$(INI_CONFIG_LIBS) \
- $(SMBCLIENT_LIBS)
+ $(SMBCLIENT_LIBS) \
+ $(SAMBA_UTIL_LIBS)
proxy_child_SOURCES = \
src/providers/proxy/proxy_child.c \
diff --git a/src/external/samba.m4 b/src/external/samba.m4
index 0bc573a0f28d8b0aecd8953f7485944b8bc71baa..bbfa996048ab5e773b686836cfbb4378d412d1b0 100644
--- a/src/external/samba.m4
+++ b/src/external/samba.m4
@@ -30,6 +30,14 @@ without them. In this case, you will need to execute configure script
with argument --without-samba
]]))
+ PKG_CHECK_MODULES(SAMBA_UTIL, samba-util, ,
+ AC_MSG_ERROR([[Please install libsamba-util development libraries.
+libsamba-util libraries are necessary for building ad and ipa provider.
+If you do not want to build these providers it is possible to build SSSD
+without them. In this case, you will need to execute configure script
+with argument --without-samba
+ ]]))
+
if test x"$HAVE_LIBINI_CONFIG_V1_1" != x1; then
AC_MSG_ERROR([[Please install libini_config development libraries
v1.1.0, or newer. libini_config libraries are necessary for building ipa
--
2.25.4

View File

@ -1,53 +0,0 @@
From b768a37d3f908a37f4c490a30df6559bc14c7451 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Mon, 14 Sep 2020 12:44:57 +0200
Subject: [PATCH 01/19] kcm: fix typos in debug messages
---
src/responder/kcm/kcmsrv_ccache_json.c | 2 +-
src/responder/kcm/kcmsrv_cmd.c | 2 +-
src/responder/kcm/kcmsrv_ops.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c
index f78e9f58cee750f13d1085c3eb4a76235a4bcbb5..38ec53c408c3b9d44f37d102c4a0c976ef32bdfe 100644
--- a/src/responder/kcm/kcmsrv_ccache_json.c
+++ b/src/responder/kcm/kcmsrv_ccache_json.c
@@ -911,7 +911,7 @@ errno_t sec_kv_to_ccache(TALLOC_CTX *mem_ctx,
ret = sec_value_to_json(sec_value, &root);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
- "Cannot store secret to JSN [%d]: %s\n",
+ "Cannot store secret to JSON [%d]: %s\n",
ret, sss_strerror(ret));
goto done;
}
diff --git a/src/responder/kcm/kcmsrv_cmd.c b/src/responder/kcm/kcmsrv_cmd.c
index 421bf4bc5bb14d0ab9de6cd3be0e9d34d871ed9c..99980050f205730169f5907db4018e4fe57b046d 100644
--- a/src/responder/kcm/kcmsrv_cmd.c
+++ b/src/responder/kcm/kcmsrv_cmd.c
@@ -314,7 +314,7 @@ static void kcm_reply_error(struct cli_ctx *cctx,
krb5_error_code kerr;
DEBUG(SSSDBG_OP_FAILURE,
- "KCM operation returs failure [%d]: %s\n",
+ "KCM operation returns failure [%d]: %s\n",
retcode, sss_strerror(retcode));
kerr = sss2krb5_error(retcode);
diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c
index 6ac66c15090422ae83a2f51dbc80144a315a27f4..1e8e4d6a3b4feba5bac3eb0a5fa6a22a588ba985 100644
--- a/src/responder/kcm/kcmsrv_ops.c
+++ b/src/responder/kcm/kcmsrv_ops.c
@@ -1468,7 +1468,7 @@ static void kcm_op_get_cache_by_uuid_done(struct tevent_req *subreq)
talloc_zfree(subreq);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
- "Cannot get ccahe by UUID [%d]: %s\n",
+ "Cannot get ccache by UUID [%d]: %s\n",
ret, sss_strerror(ret));
tevent_req_error(req, ret);
return;
--
2.25.4

View File

@ -1,51 +0,0 @@
From a0e3759b733a5b5db82bea2ef35e1519ea8a9b1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 16 Oct 2020 15:33:42 +0200
Subject: [PATCH 02/19] kcm: avoid name confusion in GET_CRED_UUID_LIST
handlers
The function name did not follow best practices and it got easily confused
with `kcm_op_get_cred_by_uuid_getbyname_done`.
```
kcm_op_get_cred_uuid_getbyname_done
kcm_op_get_cred_by_uuid_getbyname_done
```
---
src/responder/kcm/kcmsrv_ops.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c
index 1e8e4d6a3b4feba5bac3eb0a5fa6a22a588ba985..7fc3b0a5c4e123a398ef103f3ce92b45bc68f5cf 100644
--- a/src/responder/kcm/kcmsrv_ops.c
+++ b/src/responder/kcm/kcmsrv_ops.c
@@ -1072,7 +1072,7 @@ static void kcm_op_get_principal_getbyname_done(struct tevent_req *subreq)
}
/* (name) -> (uuid, ...) */
-static void kcm_op_get_cred_uuid_getbyname_done(struct tevent_req *subreq);
+static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq);
static struct tevent_req *
kcm_op_get_cred_uuid_list_send(TALLOC_CTX *mem_ctx,
@@ -1106,7 +1106,7 @@ kcm_op_get_cred_uuid_list_send(TALLOC_CTX *mem_ctx,
ret = ENOMEM;
goto immediate;
}
- tevent_req_set_callback(subreq, kcm_op_get_cred_uuid_getbyname_done, req);
+ tevent_req_set_callback(subreq, kcm_op_get_cred_uuid_list_getbyname_done, req);
return req;
immediate:
@@ -1115,7 +1115,7 @@ immediate:
return req;
}
-static void kcm_op_get_cred_uuid_getbyname_done(struct tevent_req *subreq)
+static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq)
{
errno_t ret;
struct kcm_ccache *cc;
--
2.25.4

View File

@ -1,509 +0,0 @@
From 426947971cd94cc93dd120ca8ad9bcbeb47059c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Mon, 19 Oct 2020 12:59:48 +0200
Subject: [PATCH 03/19] kcm: disable encryption
Encryption was a huge bottleneck for the secdb backend. This is
backwards compatible and there is no need to destroy existing
ccache. It will be stored unencrypted at first write to the cache.
Note that the encryption did not provide any security as the cache
is accessible only by root and the master key is stored together
with the cache. So once someone gains access to the file it can
be easily decrypted. Additionaly, there was also no encryption at
the memory level.
Resolves: https://github.com/SSSD/sssd/issues/5349
---
src/responder/kcm/kcmsrv_ccache_secdb.c | 94 ++++-----------
src/responder/secrets/local.c | 2 +-
src/util/secrets/secrets.c | 149 +++++++++++++++++-------
src/util/secrets/secrets.h | 13 ++-
4 files changed, 146 insertions(+), 112 deletions(-)
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
index ed1c8247febc0a49dfd35b99a788b60ce8dda109..e6f4f9b05d17956f771ed4db63dc4940be0a838b 100644
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
@@ -35,15 +35,13 @@
#define KCM_SECDB_CCACHE_FMT KCM_SECDB_BASE_FMT"ccache/"
#define KCM_SECDB_DFL_FMT KCM_SECDB_BASE_FMT"default"
-static errno_t sec_get_b64(TALLOC_CTX *mem_ctx,
- struct sss_sec_req *req,
- struct sss_iobuf **_buf)
+static errno_t sec_get(TALLOC_CTX *mem_ctx,
+ struct sss_sec_req *req,
+ struct sss_iobuf **_buf)
{
errno_t ret;
TALLOC_CTX *tmp_ctx;
- char *b64_sec;
- uint8_t *data;
- size_t data_size;
+ char *secret;
struct sss_iobuf *buf;
tmp_ctx = talloc_new(mem_ctx);
@@ -51,21 +49,15 @@ static errno_t sec_get_b64(TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- ret = sss_sec_get(tmp_ctx, req, &b64_sec);
+ ret = sss_sec_get(tmp_ctx, req, &secret);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot retrieve the secret [%d]: %s\n", ret, sss_strerror(ret));
goto done;
}
- data = sss_base64_decode(tmp_ctx, b64_sec, &data_size);
- if (data == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot decode secret from base64\n");
- ret = EIO;
- goto done;
- }
-
- buf = sss_iobuf_init_readonly(tmp_ctx, data, data_size);
+ buf = sss_iobuf_init_readonly(tmp_ctx, (const uint8_t *)secret,
+ strlen(secret) + 1);
if (buf == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init the iobuf\n");
ret = EIO;
@@ -79,73 +71,35 @@ done:
return ret;
}
-static errno_t sec_put_b64(TALLOC_CTX *mem_ctx,
- struct sss_sec_req *req,
- struct sss_iobuf *buf)
+static errno_t sec_put(TALLOC_CTX *mem_ctx,
+ struct sss_sec_req *req,
+ struct sss_iobuf *buf)
{
errno_t ret;
- TALLOC_CTX *tmp_ctx;
- char *secret;
- tmp_ctx = talloc_new(mem_ctx);
- if (tmp_ctx == NULL) {
- return ENOMEM;
- }
-
- secret = sss_base64_encode(tmp_ctx,
- sss_iobuf_get_data(buf),
- sss_iobuf_get_size(buf));
- if (secret == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot encode secret to base64\n");
- ret = EIO;
- goto done;
- }
-
- ret = sss_sec_put(req, secret);
+ ret = sss_sec_put(req, (const char *)sss_iobuf_get_data(buf),
+ SSS_SEC_PLAINTEXT);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
- goto done;
}
- ret = EOK;
-done:
- talloc_free(tmp_ctx);
return ret;
}
-static errno_t sec_update_b64(TALLOC_CTX *mem_ctx,
- struct sss_sec_req *req,
- struct sss_iobuf *buf)
+static errno_t sec_update(TALLOC_CTX *mem_ctx,
+ struct sss_sec_req *req,
+ struct sss_iobuf *buf)
{
errno_t ret;
- TALLOC_CTX *tmp_ctx;
- char *secret;
- tmp_ctx = talloc_new(mem_ctx);
- if (tmp_ctx == NULL) {
- return ENOMEM;
- }
-
- secret = sss_base64_encode(tmp_ctx,
- sss_iobuf_get_data(buf),
- sss_iobuf_get_size(buf));
- if (secret == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot encode secret to base64\n");
- ret = EIO;
- goto done;
- }
-
- ret = sss_sec_update(req, secret);
+ ret = sss_sec_update(req, (const char *)sss_iobuf_get_data(buf),
+ SSS_SEC_PLAINTEXT);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
- goto done;
}
- ret = EOK;
-done:
- talloc_free(tmp_ctx);
return ret;
}
@@ -493,7 +447,7 @@ static errno_t secdb_get_cc(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = sec_get_b64(tmp_ctx, sreq, &ccbuf);
+ ret = sec_get(tmp_ctx, sreq, &ccbuf);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot get the secret [%d][%s]\n", ret, sss_strerror(ret));
@@ -748,9 +702,9 @@ static struct tevent_req *ccdb_secdb_set_default_send(TALLOC_CTX *mem_ctx,
ret = sss_sec_get(state, sreq, &cur_default);
if (ret == ENOENT) {
- ret = sec_put_b64(state, sreq, iobuf);
+ ret = sec_put(state, sreq, iobuf);
} else if (ret == EOK) {
- ret = sec_update_b64(state, sreq, iobuf);
+ ret = sec_update(state, sreq, iobuf);
}
if (ret != EOK) {
@@ -804,7 +758,7 @@ static struct tevent_req *ccdb_secdb_get_default_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = sec_get_b64(state, sreq, &dfl_iobuf);
+ ret = sec_get(state, sreq, &dfl_iobuf);
if (ret == ENOENT) {
uuid_clear(state->uuid);
ret = EOK;
@@ -1230,7 +1184,7 @@ static struct tevent_req *ccdb_secdb_create_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = sec_put_b64(state, ccache_req, ccache_payload);
+ ret = sec_put(state, ccache_req, ccache_payload);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Failed to add the payload\n");
goto immediate;
@@ -1308,7 +1262,7 @@ static struct tevent_req *ccdb_secdb_mod_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = sec_update_b64(state, sreq, payload);
+ ret = sec_update(state, sreq, payload);
if (ret != EOK) {
goto immediate;
}
@@ -1384,7 +1338,7 @@ static struct tevent_req *ccdb_secdb_store_cred_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = sec_update_b64(state, sreq, payload);
+ ret = sec_update(state, sreq, payload);
if (ret != EOK) {
goto immediate;
}
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
index eb37c08b7337c6713c2e74a55363f79ecfefd8c0..815e7507ba6b3e210891c26dd243a2a67d8920f0 100644
--- a/src/responder/secrets/local.c
+++ b/src/responder/secrets/local.c
@@ -168,7 +168,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
}
if (ret) goto done;
- ret = sss_sec_put(ssec_req, secret);
+ ret = sss_sec_put(ssec_req, secret, SSS_SEC_MASTERKEY);
if (ret) goto done;
break;
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
index d701face07aa3ea5dc62371066ba6947d7d496a9..b3d40fdcb4bc2aeeb6aae4e17654ae06b00db876 100644
--- a/src/util/secrets/secrets.c
+++ b/src/util/secrets/secrets.c
@@ -63,19 +63,53 @@ static struct sss_sec_quota default_kcm_quota = {
.containers_nest_level = DEFAULT_SEC_CONTAINERS_NEST_LEVEL,
};
+static const char *sss_sec_enctype_to_str(enum sss_sec_enctype enctype)
+{
+ switch (enctype) {
+ case SSS_SEC_PLAINTEXT:
+ return "plaintext";
+ case SSS_SEC_MASTERKEY:
+ return "masterkey";
+ case SSS_SEC_BASE64:
+ return "base64";
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: unknown encryption type %d\n",
+ enctype);
+ return "unknown";
+ }
+}
+
+static enum sss_sec_enctype sss_sec_str_to_enctype(const char *str)
+{
+ if (strcmp("plaintext", str) == 0) {
+ return SSS_SEC_PLAINTEXT;
+ }
+
+ if (strcmp("masterkey", str) == 0) {
+ return SSS_SEC_MASTERKEY;
+ }
+
+ if (strcmp("base64", str) == 0) {
+ return SSS_SEC_BASE64;
+ }
+
+ return SSS_SEC_ENCTYPE_SENTINEL;
+}
+
static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
- const char *secret, const char *enctype,
+ const char *secret, enum sss_sec_enctype enctype,
char **plain_secret)
{
+ struct sss_sec_data _secret;
+ size_t outlen;
char *output;
+ int ret;
- if (enctype && strcmp(enctype, "masterkey") == 0) {
- DEBUG(SSSDBG_TRACE_INTERNAL, "Decrypting with masterkey\n");
-
- struct sss_sec_data _secret;
- size_t outlen;
- int ret;
-
+ switch (enctype) {
+ case SSS_SEC_PLAINTEXT:
+ output = talloc_strdup(mem_ctx, secret);
+ break;
+ case SSS_SEC_MASTERKEY:
_secret.data = (char *)sss_base64_decode(mem_ctx, secret,
&_secret.length);
if (!_secret.data) {
@@ -83,6 +117,7 @@ static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
return EINVAL;
}
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Decrypting with masterkey\n");
ret = sss_decrypt(mem_ctx, AES256CBC_HMAC_SHA256,
(uint8_t *)sctx->master_key.data,
sctx->master_key.length,
@@ -102,10 +137,17 @@ static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
talloc_free(output);
return EIO;
}
- } else {
- DEBUG(SSSDBG_TRACE_INTERNAL, "Unexpected enctype (not 'masterkey')\n");
- output = talloc_strdup(mem_ctx, secret);
- if (!output) return ENOMEM;
+ break;
+ case SSS_SEC_BASE64:
+ output = (char *)sss_base64_decode(mem_ctx, secret, &_secret.length);
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
+ return EINVAL;
+ }
+
+ if (output == NULL) {
+ return ENOMEM;
}
*plain_secret = output;
@@ -113,39 +155,46 @@ static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
}
static int local_encrypt(struct sss_sec_ctx *sec_ctx, TALLOC_CTX *mem_ctx,
- const char *secret, const char *enctype,
+ const char *secret, enum sss_sec_enctype enctype,
char **ciphertext)
{
struct sss_sec_data _secret;
char *output;
int ret;
- if (enctype == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "No encryption type\n");
- return EINVAL;
- }
+ switch (enctype) {
+ case SSS_SEC_PLAINTEXT:
+ output = talloc_strdup(mem_ctx, secret);
+ break;
+ case SSS_SEC_MASTERKEY:
+ ret = sss_encrypt(mem_ctx, AES256CBC_HMAC_SHA256,
+ (uint8_t *)sec_ctx->master_key.data,
+ sec_ctx->master_key.length,
+ (const uint8_t *)secret, strlen(secret) + 1,
+ (uint8_t **)&_secret.data, &_secret.length);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sss_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
+ return ret;
+ }
- if (strcmp(enctype, "masterkey") != 0) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%s'\n", enctype);
+ output = sss_base64_encode(mem_ctx, (uint8_t *)_secret.data,
+ _secret.length);
+ talloc_free(_secret.data);
+ break;
+ case SSS_SEC_BASE64:
+ output = (char *)sss_base64_encode(mem_ctx, (const uint8_t *)secret,
+ strlen(secret) + 1);
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
return EINVAL;
}
- ret = sss_encrypt(mem_ctx, AES256CBC_HMAC_SHA256,
- (uint8_t *)sec_ctx->master_key.data,
- sec_ctx->master_key.length,
- (const uint8_t *)secret, strlen(secret) + 1,
- (uint8_t **)&_secret.data, &_secret.length);
- if (ret) {
- DEBUG(SSSDBG_OP_FAILURE,
- "sss_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
- return ret;
+ if (output == NULL) {
+ return ENOMEM;
}
- output = sss_base64_encode(mem_ctx,
- (uint8_t *)_secret.data, _secret.length);
- talloc_free(_secret.data);
- if (!output) return ENOMEM;
-
*ciphertext = output;
return EOK;
}
@@ -958,6 +1007,7 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
struct ldb_result *res;
const char *attr_secret;
const char *attr_enctype;
+ enum sss_sec_enctype enctype;
int ret;
if (req == NULL || _secret == NULL) {
@@ -1006,10 +1056,15 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], "enctype", NULL);
if (attr_enctype) {
- ret = local_decrypt(req->sctx, mem_ctx, attr_secret, attr_enctype, _secret);
+ enctype = sss_sec_str_to_enctype(attr_enctype);
+ ret = local_decrypt(req->sctx, mem_ctx, attr_secret, enctype, _secret);
if (ret) goto done;
} else {
*_secret = talloc_strdup(mem_ctx, attr_secret);
+ if (*_secret == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
}
ret = EOK;
@@ -1019,10 +1074,10 @@ done:
}
errno_t sss_sec_put(struct sss_sec_req *req,
- const char *secret)
+ const char *secret,
+ enum sss_sec_enctype enctype)
{
struct ldb_message *msg;
- const char *enctype = "masterkey";
char *enc_secret;
int ret;
@@ -1087,7 +1142,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_string(msg, "enctype", enctype);
+ ret = ldb_msg_add_string(msg, "enctype", sss_sec_enctype_to_str(enctype));
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"ldb_msg_add_string failed adding enctype [%d]: %s\n",
@@ -1132,10 +1187,10 @@ done:
}
errno_t sss_sec_update(struct sss_sec_req *req,
- const char *secret)
+ const char *secret,
+ enum sss_sec_enctype enctype)
{
struct ldb_message *msg;
- const char *enctype = "masterkey";
char *enc_secret;
int ret;
@@ -1192,6 +1247,22 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
+ ret = ldb_msg_add_empty(msg, "enctype", LDB_FLAG_MOD_REPLACE, NULL);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "ldb_msg_add_empty failed: [%s]\n", ldb_strerror(ret));
+ ret = EIO;
+ goto done;
+ }
+
+ ret = ldb_msg_add_string(msg, "enctype", sss_sec_enctype_to_str(enctype));
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "ldb_msg_add_string failed adding enctype [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
/* FIXME - should we have a lastUpdate timestamp? */
ret = ldb_msg_add_empty(msg, "secret", LDB_FLAG_MOD_REPLACE, NULL);
if (ret != LDB_SUCCESS) {
diff --git a/src/util/secrets/secrets.h b/src/util/secrets/secrets.h
index 9cf3975162c40a27ec92691f732a5aca5a5a8473..73f40f7eb620904cec8f1cb7891765323ada08ad 100644
--- a/src/util/secrets/secrets.h
+++ b/src/util/secrets/secrets.h
@@ -43,6 +43,13 @@
#define DEFAULT_SEC_KCM_MAX_UID_SECRETS 64
#define DEFAULT_SEC_KCM_MAX_PAYLOAD_SIZE 65536
+enum sss_sec_enctype {
+ SSS_SEC_PLAINTEXT,
+ SSS_SEC_MASTERKEY,
+ SSS_SEC_BASE64,
+ SSS_SEC_ENCTYPE_SENTINEL
+};
+
struct sss_sec_ctx;
struct sss_sec_req;
@@ -91,10 +98,12 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
char **_secret);
errno_t sss_sec_put(struct sss_sec_req *req,
- const char *secret);
+ const char *secret,
+ enum sss_sec_enctype enctype);
errno_t sss_sec_update(struct sss_sec_req *req,
- const char *secret);
+ const char *secret,
+ enum sss_sec_enctype enctype);
errno_t sss_sec_create_container(struct sss_sec_req *req);
--
2.25.4

View File

@ -1,26 +0,0 @@
From b8dd3fa32cef423217859a1ef04ec30dfef30fb2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 27 Oct 2020 16:45:22 +0100
Subject: [PATCH 04/19] kcm: avoid multiple debug messages if sss_sec_put fails
sec_put() already logs a message if the underlaying function fails
so this debug message is really unnecessary.
---
src/responder/kcm/kcmsrv_ccache_secdb.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
index e6f4f9b05d17956f771ed4db63dc4940be0a838b..f3b9af840381881e99bbead70ea7edabf945a8e2 100644
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
@@ -1186,7 +1186,6 @@ static struct tevent_req *ccdb_secdb_create_send(TALLOC_CTX *mem_ctx,
ret = sec_put(state, ccache_req, ccache_payload);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Failed to add the payload\n");
goto immediate;
}
--
2.25.4

View File

@ -1,225 +0,0 @@
From e05dfeca855986cd11674a64ef6333c2d67e9bc7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 22 Oct 2020 11:18:12 +0200
Subject: [PATCH 05/19] secrets: allow to specify secret's data format
Currently, both KCM and secrets responders store JSON formatted string
in the secrets database. One of the next commits makes KCM to store
binary format instead of JSON string to improve performance. We need
to be able to distinguish the formats to keep KCM update compatible
with existing ccache and also to keep secrets responder working.
---
src/responder/kcm/kcmsrv_ccache_secdb.c | 8 ++--
src/responder/secrets/local.c | 4 +-
src/util/secrets/secrets.c | 57 ++++++++++++++++++++-----
src/util/secrets/secrets.h | 9 ++--
4 files changed, 59 insertions(+), 19 deletions(-)
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
index f3b9af840381881e99bbead70ea7edabf945a8e2..8e5bd4f7376173fd075c1a64785a597bcf2f97ba 100644
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
@@ -49,7 +49,7 @@ static errno_t sec_get(TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- ret = sss_sec_get(tmp_ctx, req, &secret);
+ ret = sss_sec_get(tmp_ctx, req, &secret, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot retrieve the secret [%d]: %s\n", ret, sss_strerror(ret));
@@ -78,7 +78,7 @@ static errno_t sec_put(TALLOC_CTX *mem_ctx,
errno_t ret;
ret = sss_sec_put(req, (const char *)sss_iobuf_get_data(buf),
- SSS_SEC_PLAINTEXT);
+ SSS_SEC_PLAINTEXT, "simple");
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
@@ -94,7 +94,7 @@ static errno_t sec_update(TALLOC_CTX *mem_ctx,
errno_t ret;
ret = sss_sec_update(req, (const char *)sss_iobuf_get_data(buf),
- SSS_SEC_PLAINTEXT);
+ SSS_SEC_PLAINTEXT, "simple");
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
@@ -700,7 +700,7 @@ static struct tevent_req *ccdb_secdb_set_default_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = sss_sec_get(state, sreq, &cur_default);
+ ret = sss_sec_get(state, sreq, &cur_default, NULL);
if (ret == ENOENT) {
ret = sec_put(state, sreq, iobuf);
} else if (ret == EOK) {
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
index 815e7507ba6b3e210891c26dd243a2a67d8920f0..fee52674d73f6f8071b4d66ac91bed3b210c8e23 100644
--- a/src/responder/secrets/local.c
+++ b/src/responder/secrets/local.c
@@ -134,7 +134,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
break;
}
- ret = sss_sec_get(state, ssec_req, &secret);
+ ret = sss_sec_get(state, ssec_req, &secret, NULL);
if (ret) goto done;
if (body_is_json) {
@@ -168,7 +168,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
}
if (ret) goto done;
- ret = sss_sec_put(ssec_req, secret, SSS_SEC_MASTERKEY);
+ ret = sss_sec_put(ssec_req, secret, SSS_SEC_MASTERKEY, "simple");
if (ret) goto done;
break;
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
index b3d40fdcb4bc2aeeb6aae4e17654ae06b00db876..51fc85fb09934c25290c625fe2a2d8090285117d 100644
--- a/src/util/secrets/secrets.c
+++ b/src/util/secrets/secrets.c
@@ -1000,14 +1000,18 @@ done:
errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
struct sss_sec_req *req,
- char **_secret)
+ char **_secret,
+ char **_datatype)
{
TALLOC_CTX *tmp_ctx;
- static const char *attrs[] = { "secret", "enctype", NULL };
+ static const char *attrs[] = { "secret", "enctype", "type", NULL };
struct ldb_result *res;
const char *attr_secret;
const char *attr_enctype;
+ const char *attr_datatype;
enum sss_sec_enctype enctype;
+ char *datatype;
+ char *secret;
int ret;
if (req == NULL || _secret == NULL) {
@@ -1057,15 +1061,30 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
if (attr_enctype) {
enctype = sss_sec_str_to_enctype(attr_enctype);
- ret = local_decrypt(req->sctx, mem_ctx, attr_secret, enctype, _secret);
+ ret = local_decrypt(req->sctx, tmp_ctx, attr_secret, enctype, &secret);
if (ret) goto done;
} else {
- *_secret = talloc_strdup(mem_ctx, attr_secret);
- if (*_secret == NULL) {
+ secret = talloc_strdup(tmp_ctx, attr_secret);
+ if (secret == NULL) {
ret = ENOMEM;
goto done;
}
}
+
+ if (_datatype != NULL) {
+ attr_datatype = ldb_msg_find_attr_as_string(res->msgs[0], "type",
+ "simple");
+ datatype = talloc_strdup(tmp_ctx, attr_datatype);
+ if (datatype == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ *_datatype = talloc_steal(mem_ctx, datatype);
+ }
+
+ *_secret = talloc_steal(mem_ctx, secret);
+
ret = EOK;
done:
@@ -1075,7 +1094,8 @@ done:
errno_t sss_sec_put(struct sss_sec_req *req,
const char *secret,
- enum sss_sec_enctype enctype)
+ enum sss_sec_enctype enctype,
+ const char *datatype)
{
struct ldb_message *msg;
char *enc_secret;
@@ -1134,11 +1154,11 @@ errno_t sss_sec_put(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_string(msg, "type", "simple");
+ ret = ldb_msg_add_string(msg, "type", datatype);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
- "ldb_msg_add_string failed adding type:simple [%d]: %s\n",
- ret, sss_strerror(ret));
+ "ldb_msg_add_string failed adding type:%s [%d]: %s\n",
+ datatype, ret, sss_strerror(ret));
goto done;
}
@@ -1188,7 +1208,8 @@ done:
errno_t sss_sec_update(struct sss_sec_req *req,
const char *secret,
- enum sss_sec_enctype enctype)
+ enum sss_sec_enctype enctype,
+ const char *datatype)
{
struct ldb_message *msg;
char *enc_secret;
@@ -1263,6 +1284,22 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
+ ret = ldb_msg_add_empty(msg, "type", LDB_FLAG_MOD_REPLACE, NULL);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "ldb_msg_add_empty failed: [%s]\n", ldb_strerror(ret));
+ ret = EIO;
+ goto done;
+ }
+
+ ret = ldb_msg_add_string(msg, "type", datatype);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "ldb_msg_add_string failed adding type:%s [%d]: %s\n",
+ datatype, ret, sss_strerror(ret));
+ goto done;
+ }
+
/* FIXME - should we have a lastUpdate timestamp? */
ret = ldb_msg_add_empty(msg, "secret", LDB_FLAG_MOD_REPLACE, NULL);
if (ret != LDB_SUCCESS) {
diff --git a/src/util/secrets/secrets.h b/src/util/secrets/secrets.h
index 73f40f7eb620904cec8f1cb7891765323ada08ad..f73657629f1a0bb614ccd96728852da66cc18791 100644
--- a/src/util/secrets/secrets.h
+++ b/src/util/secrets/secrets.h
@@ -95,15 +95,18 @@ errno_t sss_sec_list(TALLOC_CTX *mem_ctx,
errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
struct sss_sec_req *req,
- char **_secret);
+ char **_secret,
+ char **_datatype);
errno_t sss_sec_put(struct sss_sec_req *req,
const char *secret,
- enum sss_sec_enctype enctype);
+ enum sss_sec_enctype enctype,
+ const char *datatype);
errno_t sss_sec_update(struct sss_sec_req *req,
const char *secret,
- enum sss_sec_enctype enctype);
+ enum sss_sec_enctype enctype,
+ const char *datatype);
errno_t sss_sec_create_container(struct sss_sec_req *req);
--
2.25.4

View File

@ -1,450 +0,0 @@
From 63cbb2aee2c6277ecd9e38fb32713e0ba3db4bb4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 22 Oct 2020 12:18:38 +0200
Subject: [PATCH 06/19] secrets: accept binary data instead of string
Currently, both KCM and secrets responders store JSON formatted string
in the secrets database. One of the next commits makes KCM to store
binary format instead of JSON string to improve performance. We need
to be able to distinguish the formats to keep KCM update compatible
with existing ccache and also to keep secrets responder working.
Secrets responder test had to be ammended to fit into a new maximum
payload which is now reduced by one byte for the secrets responder
to hold the ending zero of a secret string.
This is a corner case in a long deprecated responder that is not even
built by default and has no known consumers so it is fine to fast fix
the test.
---
src/responder/kcm/kcmsrv_ccache_secdb.c | 8 +-
src/responder/secrets/local.c | 5 +-
src/tests/intg/test_secrets.py | 3 +-
src/util/secrets/sec_pvt.h | 2 +-
src/util/secrets/secrets.c | 130 ++++++++++++++----------
src/util/secrets/secrets.h | 9 +-
6 files changed, 91 insertions(+), 66 deletions(-)
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
index 8e5bd4f7376173fd075c1a64785a597bcf2f97ba..f0143e686826e3bf637619efc799e0d2f0715ba4 100644
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
@@ -49,7 +49,7 @@ static errno_t sec_get(TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- ret = sss_sec_get(tmp_ctx, req, &secret, NULL);
+ ret = sss_sec_get(tmp_ctx, req, (uint8_t **)&secret, NULL, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot retrieve the secret [%d]: %s\n", ret, sss_strerror(ret));
@@ -77,7 +77,7 @@ static errno_t sec_put(TALLOC_CTX *mem_ctx,
{
errno_t ret;
- ret = sss_sec_put(req, (const char *)sss_iobuf_get_data(buf),
+ ret = sss_sec_put(req, sss_iobuf_get_data(buf), sss_iobuf_get_size(buf),
SSS_SEC_PLAINTEXT, "simple");
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
@@ -93,7 +93,7 @@ static errno_t sec_update(TALLOC_CTX *mem_ctx,
{
errno_t ret;
- ret = sss_sec_update(req, (const char *)sss_iobuf_get_data(buf),
+ ret = sss_sec_update(req, sss_iobuf_get_data(buf), sss_iobuf_get_size(buf),
SSS_SEC_PLAINTEXT, "simple");
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
@@ -700,7 +700,7 @@ static struct tevent_req *ccdb_secdb_set_default_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = sss_sec_get(state, sreq, &cur_default, NULL);
+ ret = sss_sec_get(state, sreq, (uint8_t**)&cur_default, NULL, NULL);
if (ret == ENOENT) {
ret = sec_put(state, sreq, iobuf);
} else if (ret == EOK) {
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
index fee52674d73f6f8071b4d66ac91bed3b210c8e23..252ef3a1de7ff28b0e9f37479c658a6c59e830f7 100644
--- a/src/responder/secrets/local.c
+++ b/src/responder/secrets/local.c
@@ -134,7 +134,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
break;
}
- ret = sss_sec_get(state, ssec_req, &secret, NULL);
+ ret = sss_sec_get(state, ssec_req, (uint8_t**)&secret, NULL, NULL);
if (ret) goto done;
if (body_is_json) {
@@ -168,7 +168,8 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
}
if (ret) goto done;
- ret = sss_sec_put(ssec_req, secret, SSS_SEC_MASTERKEY, "simple");
+ ret = sss_sec_put(ssec_req, (uint8_t *)secret, strlen(secret) + 1,
+ SSS_SEC_MASTERKEY, "simple");
if (ret) goto done;
break;
diff --git a/src/tests/intg/test_secrets.py b/src/tests/intg/test_secrets.py
index 00933fb346516898448d4285c5c5c9373c48a2a9..18d722c13f36c58423e5caf81881f9ec167faa1e 100644
--- a/src/tests/intg/test_secrets.py
+++ b/src/tests/intg/test_secrets.py
@@ -438,7 +438,8 @@ def run_quota_test(cli, max_secrets, max_payload_size):
KILOBYTE = 1024
kb_payload_size = max_payload_size * KILOBYTE
- sec_value = "x" * kb_payload_size
+ # Adjust payload size to hold terminal zero byte.
+ sec_value = "x" * (kb_payload_size - 1)
cli.set_secret("foo", sec_value)
diff --git a/src/util/secrets/sec_pvt.h b/src/util/secrets/sec_pvt.h
index 92e2b8b259fd7b20e974d5bd4dc41d96ea36ecf1..0e77a660e91ff9e18cce68a7994e3dbbf868c7aa 100644
--- a/src/util/secrets/sec_pvt.h
+++ b/src/util/secrets/sec_pvt.h
@@ -33,7 +33,7 @@
#define SSS_SEC_KCM_BASEPATH "/kcm/"
struct sss_sec_data {
- char *data;
+ uint8_t *data;
size_t length;
};
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
index 51fc85fb09934c25290c625fe2a2d8090285117d..2a7149ae8b1c88623784ffd4f3e7f908be15c662 100644
--- a/src/util/secrets/secrets.c
+++ b/src/util/secrets/secrets.c
@@ -96,22 +96,28 @@ static enum sss_sec_enctype sss_sec_str_to_enctype(const char *str)
return SSS_SEC_ENCTYPE_SENTINEL;
}
-static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
- const char *secret, enum sss_sec_enctype enctype,
- char **plain_secret)
+static int local_decrypt(struct sss_sec_ctx *sctx,
+ TALLOC_CTX *mem_ctx,
+ uint8_t *secret,
+ size_t secret_len,
+ enum sss_sec_enctype enctype,
+ uint8_t **_output,
+ size_t *_output_len)
{
struct sss_sec_data _secret;
- size_t outlen;
- char *output;
+ uint8_t *output;
+ size_t output_len;
int ret;
switch (enctype) {
case SSS_SEC_PLAINTEXT:
- output = talloc_strdup(mem_ctx, secret);
+ output = talloc_memdup(mem_ctx, secret, secret_len);
+ output_len = secret_len;
break;
case SSS_SEC_MASTERKEY:
- _secret.data = (char *)sss_base64_decode(mem_ctx, secret,
- &_secret.length);
+ _secret.data = (uint8_t *)sss_base64_decode(mem_ctx,
+ (const char *)secret,
+ &_secret.length);
if (!_secret.data) {
DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed\n");
return EINVAL;
@@ -119,27 +125,20 @@ static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
DEBUG(SSSDBG_TRACE_INTERNAL, "Decrypting with masterkey\n");
ret = sss_decrypt(mem_ctx, AES256CBC_HMAC_SHA256,
- (uint8_t *)sctx->master_key.data,
+ sctx->master_key.data,
sctx->master_key.length,
- (uint8_t *)_secret.data, _secret.length,
- (uint8_t **)&output, &outlen);
+ _secret.data, _secret.length,
+ &output, &output_len);
talloc_free(_secret.data);
if (ret) {
DEBUG(SSSDBG_OP_FAILURE,
"sss_decrypt failed [%d]: %s\n", ret, sss_strerror(ret));
return ret;
}
-
- if (((strnlen(output, outlen) + 1) != outlen) ||
- output[outlen - 1] != '\0') {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Output length mismatch or output not NULL-terminated\n");
- talloc_free(output);
- return EIO;
- }
break;
case SSS_SEC_BASE64:
- output = (char *)sss_base64_decode(mem_ctx, secret, &_secret.length);
+ output = (uint8_t *)sss_base64_decode(mem_ctx, (const char *)secret,
+ &output_len);
break;
default:
DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
@@ -150,41 +149,52 @@ static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- *plain_secret = output;
+ *_output = output;
+ *_output_len = output_len;
+
return EOK;
}
-static int local_encrypt(struct sss_sec_ctx *sec_ctx, TALLOC_CTX *mem_ctx,
- const char *secret, enum sss_sec_enctype enctype,
- char **ciphertext)
+static int local_encrypt(struct sss_sec_ctx *sec_ctx,
+ TALLOC_CTX *mem_ctx,
+ uint8_t *secret,
+ size_t secret_len,
+ enum sss_sec_enctype enctype,
+ uint8_t **_output,
+ size_t *_output_len)
{
struct sss_sec_data _secret;
- char *output;
+ uint8_t *output;
+ size_t output_len;
+ char *b64;
int ret;
switch (enctype) {
case SSS_SEC_PLAINTEXT:
- output = talloc_strdup(mem_ctx, secret);
+ output = talloc_memdup(mem_ctx, secret, secret_len);
+ output_len = secret_len;
break;
case SSS_SEC_MASTERKEY:
ret = sss_encrypt(mem_ctx, AES256CBC_HMAC_SHA256,
- (uint8_t *)sec_ctx->master_key.data,
- sec_ctx->master_key.length,
- (const uint8_t *)secret, strlen(secret) + 1,
- (uint8_t **)&_secret.data, &_secret.length);
+ sec_ctx->master_key.data,
+ sec_ctx->master_key.length,
+ secret, secret_len,
+ &_secret.data, &_secret.length);
if (ret) {
DEBUG(SSSDBG_OP_FAILURE,
"sss_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
return ret;
}
- output = sss_base64_encode(mem_ctx, (uint8_t *)_secret.data,
- _secret.length);
+ b64 = sss_base64_encode(mem_ctx, _secret.data, _secret.length);
+ output = (uint8_t*)b64;
+ output_len = strlen(b64) + 1;
talloc_free(_secret.data);
break;
case SSS_SEC_BASE64:
- output = (char *)sss_base64_encode(mem_ctx, (const uint8_t *)secret,
- strlen(secret) + 1);
+ b64 = sss_base64_encode(mem_ctx, secret, secret_len);
+ output = (uint8_t*)b64;
+ output_len = strlen(b64) + 1;
break;
default:
DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
@@ -195,7 +205,9 @@ static int local_encrypt(struct sss_sec_ctx *sec_ctx, TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- *ciphertext = output;
+ *_output = output;
+ *_output_len = output_len;
+
return EOK;
}
@@ -1000,18 +1012,20 @@ done:
errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
struct sss_sec_req *req,
- char **_secret,
+ uint8_t **_secret,
+ size_t *_secret_len,
char **_datatype)
{
TALLOC_CTX *tmp_ctx;
static const char *attrs[] = { "secret", "enctype", "type", NULL };
struct ldb_result *res;
- const char *attr_secret;
+ const struct ldb_val *attr_secret;
const char *attr_enctype;
const char *attr_datatype;
enum sss_sec_enctype enctype;
char *datatype;
- char *secret;
+ uint8_t *secret;
+ size_t secret_len;
int ret;
if (req == NULL || _secret == NULL) {
@@ -1050,7 +1064,7 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
goto done;
}
- attr_secret = ldb_msg_find_attr_as_string(res->msgs[0], "secret", NULL);
+ attr_secret = ldb_msg_find_ldb_val(res->msgs[0], "secret");
if (!attr_secret) {
DEBUG(SSSDBG_CRIT_FAILURE, "The 'secret' attribute is missing\n");
ret = ENOENT;
@@ -1061,14 +1075,12 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
if (attr_enctype) {
enctype = sss_sec_str_to_enctype(attr_enctype);
- ret = local_decrypt(req->sctx, tmp_ctx, attr_secret, enctype, &secret);
+ ret = local_decrypt(req->sctx, tmp_ctx, attr_secret->data,
+ attr_secret->length, enctype, &secret, &secret_len);
if (ret) goto done;
} else {
- secret = talloc_strdup(tmp_ctx, attr_secret);
- if (secret == NULL) {
- ret = ENOMEM;
- goto done;
- }
+ secret = talloc_steal(tmp_ctx, attr_secret->data);
+ secret_len = attr_secret->length;
}
if (_datatype != NULL) {
@@ -1085,6 +1097,10 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
*_secret = talloc_steal(mem_ctx, secret);
+ if (_secret_len) {
+ *_secret_len = secret_len;
+ }
+
ret = EOK;
done:
@@ -1093,12 +1109,13 @@ done:
}
errno_t sss_sec_put(struct sss_sec_req *req,
- const char *secret,
+ uint8_t *secret,
+ size_t secret_len,
enum sss_sec_enctype enctype,
const char *datatype)
{
struct ldb_message *msg;
- char *enc_secret;
+ struct ldb_val enc_secret;
int ret;
if (req == NULL || secret == NULL) {
@@ -1139,7 +1156,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
goto done;
}
- ret = local_check_max_payload_size(req, strlen(secret));
+ ret = local_check_max_payload_size(req, secret_len);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"local_check_max_payload_size failed [%d]: %s\n",
@@ -1147,7 +1164,8 @@ errno_t sss_sec_put(struct sss_sec_req *req,
goto done;
}
- ret = local_encrypt(req->sctx, msg, secret, enctype, &enc_secret);
+ ret = local_encrypt(req->sctx, msg, secret, secret_len, enctype,
+ &enc_secret.data, &enc_secret.length);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"local_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
@@ -1170,7 +1188,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_string(msg, "secret", enc_secret);
+ ret = ldb_msg_add_value(msg, "secret", &enc_secret, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"ldb_msg_add_string failed adding secret [%d]: %s\n",
@@ -1207,12 +1225,13 @@ done:
}
errno_t sss_sec_update(struct sss_sec_req *req,
- const char *secret,
+ uint8_t *secret,
+ size_t secret_len,
enum sss_sec_enctype enctype,
const char *datatype)
{
struct ldb_message *msg;
- char *enc_secret;
+ struct ldb_val enc_secret;
int ret;
if (req == NULL || secret == NULL) {
@@ -1253,7 +1272,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
- ret = local_check_max_payload_size(req, strlen(secret));
+ ret = local_check_max_payload_size(req, secret_len);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"local_check_max_payload_size failed [%d]: %s\n",
@@ -1261,7 +1280,8 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
- ret = local_encrypt(req->sctx, msg, secret, enctype, &enc_secret);
+ ret = local_encrypt(req->sctx, msg, secret, secret_len, enctype,
+ &enc_secret.data, &enc_secret.length);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"local_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
@@ -1309,7 +1329,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_string(msg, "secret", enc_secret);
+ ret = ldb_msg_add_value(msg, "secret", &enc_secret, NULL);
if (ret != LDB_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
"ldb_msg_add_string failed: [%s]\n", ldb_strerror(ret));
diff --git a/src/util/secrets/secrets.h b/src/util/secrets/secrets.h
index f73657629f1a0bb614ccd96728852da66cc18791..f8caa53eec376bb0c8d52615ce9111efbbb26393 100644
--- a/src/util/secrets/secrets.h
+++ b/src/util/secrets/secrets.h
@@ -95,16 +95,19 @@ errno_t sss_sec_list(TALLOC_CTX *mem_ctx,
errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
struct sss_sec_req *req,
- char **_secret,
+ uint8_t **_secret,
+ size_t *_secret_len,
char **_datatype);
errno_t sss_sec_put(struct sss_sec_req *req,
- const char *secret,
+ uint8_t *secret,
+ size_t secret_len,
enum sss_sec_enctype enctype,
const char *datatype);
errno_t sss_sec_update(struct sss_sec_req *req,
- const char *secret,
+ uint8_t *secret,
+ size_t secret_len,
enum sss_sec_enctype enctype,
const char *datatype);
--
2.25.4

View File

@ -1,265 +0,0 @@
From 51c8dda998c5b7bfa08362a13915fcff265a6f8f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 23 Oct 2020 13:10:13 +0200
Subject: [PATCH 07/19] iobuf: add more iobuf functions
These will be used in later patches.
---
src/shared/safealign.h | 4 ++
src/util/sss_iobuf.c | 141 +++++++++++++++++++++++++++++++++++++++++
src/util/sss_iobuf.h | 46 ++++++++++++++
3 files changed, 191 insertions(+)
diff --git a/src/shared/safealign.h b/src/shared/safealign.h
index b00c37f5b98bd4bf7ff6cea8e1208d80c77f0228..35909faa25967cefd296808431620f51232f67e2 100644
--- a/src/shared/safealign.h
+++ b/src/shared/safealign.h
@@ -97,6 +97,10 @@ safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter)
#define SAFEALIGN_SETMEM_UINT16(dest, value, pctr) \
SAFEALIGN_SETMEM_VALUE(dest, value, uint16_t, pctr)
+/* SAFEALIGN_SETMEM_UINT8(void *dest, uint8_t value, size_t *pctr) */
+#define SAFEALIGN_SETMEM_UINT8(dest, value, pctr) \
+ SAFEALIGN_SETMEM_VALUE(dest, value, uint8_t, pctr)
+
/* These macros are the same as their equivalents without _CHECK suffix,
* but additionally make the caller return EINVAL immediately if *pctr
* would exceed len. */
diff --git a/src/util/sss_iobuf.c b/src/util/sss_iobuf.c
index 518713e4cc3dd99627a3a4450f235cbbc69ed3a2..3056a7b0db38746cfed154179787e53622e1a041 100644
--- a/src/util/sss_iobuf.c
+++ b/src/util/sss_iobuf.c
@@ -66,6 +66,30 @@ struct sss_iobuf *sss_iobuf_init_readonly(TALLOC_CTX *mem_ctx,
return iobuf;
}
+struct sss_iobuf *sss_iobuf_init_steal(TALLOC_CTX *mem_ctx,
+ uint8_t *data,
+ size_t size)
+{
+ struct sss_iobuf *iobuf;
+
+ iobuf = talloc_zero(mem_ctx, struct sss_iobuf);
+ if (iobuf == NULL) {
+ return NULL;
+ }
+
+ iobuf->data = talloc_steal(iobuf, data);
+ iobuf->size = size;
+ iobuf->capacity = size;
+ iobuf->dp = 0;
+
+ return iobuf;
+}
+
+void sss_iobuf_cursor_reset(struct sss_iobuf *iobuf)
+{
+ iobuf->dp = 0;
+}
+
size_t sss_iobuf_get_len(struct sss_iobuf *iobuf)
{
if (iobuf == NULL) {
@@ -223,6 +247,109 @@ errno_t sss_iobuf_write_len(struct sss_iobuf *iobuf,
return EOK;
}
+errno_t sss_iobuf_read_varlen(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *iobuf,
+ uint8_t **_out,
+ size_t *_len)
+{
+ uint8_t *out;
+ uint32_t len;
+ size_t slen;
+ errno_t ret;
+
+ if (iobuf == NULL || _out == NULL || _len == NULL) {
+ return EINVAL;
+ }
+
+ ret = sss_iobuf_read_uint32(iobuf, &len);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ if (len == 0) {
+ *_out = NULL;
+ *_len = 0;
+ return EOK;
+ }
+
+ out = talloc_array(mem_ctx, uint8_t, len);
+ if (out == NULL) {
+ return ENOMEM;
+ }
+
+ slen = len;
+ ret = sss_iobuf_read_len(iobuf, slen, out);
+ if (ret != EOK) {
+ talloc_free(out);
+ return ret;
+ }
+
+ *_out = out;
+ *_len = slen;
+
+ return EOK;
+}
+
+errno_t sss_iobuf_write_varlen(struct sss_iobuf *iobuf,
+ uint8_t *data,
+ size_t len)
+{
+ errno_t ret;
+
+ if (iobuf == NULL || (data == NULL && len != 0)) {
+ return EINVAL;
+ }
+
+ ret = sss_iobuf_write_uint32(iobuf, len);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ if (len == 0) {
+ return EOK;
+ }
+
+ return sss_iobuf_write_len(iobuf, data, len);
+}
+
+errno_t sss_iobuf_read_iobuf(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *iobuf,
+ struct sss_iobuf **_out)
+{
+ struct sss_iobuf *out;
+ uint8_t *data;
+ size_t len;
+ errno_t ret;
+
+ ret = sss_iobuf_read_varlen(NULL, iobuf, &data, &len);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ out = sss_iobuf_init_steal(mem_ctx, data, len);
+ if (out == NULL) {
+ return ENOMEM;
+ }
+
+ *_out = out;
+
+ return EOK;
+}
+
+errno_t sss_iobuf_write_iobuf(struct sss_iobuf *iobuf,
+ struct sss_iobuf *data)
+{
+ return sss_iobuf_write_varlen(iobuf, data->data, data->size);
+}
+
+errno_t sss_iobuf_read_uint8(struct sss_iobuf *iobuf,
+ uint8_t *_val)
+{
+ SAFEALIGN_COPY_UINT8_CHECK(_val, iobuf_ptr(iobuf),
+ iobuf->capacity, &iobuf->dp);
+ return EOK;
+}
+
errno_t sss_iobuf_read_uint32(struct sss_iobuf *iobuf,
uint32_t *_val)
{
@@ -239,6 +366,20 @@ errno_t sss_iobuf_read_int32(struct sss_iobuf *iobuf,
return EOK;
}
+errno_t sss_iobuf_write_uint8(struct sss_iobuf *iobuf,
+ uint8_t val)
+{
+ errno_t ret;
+
+ ret = ensure_bytes(iobuf, sizeof(uint8_t));
+ if (ret != EOK) {
+ return ret;
+ }
+
+ SAFEALIGN_SETMEM_UINT8(iobuf_ptr(iobuf), val, &iobuf->dp);
+ return EOK;
+}
+
errno_t sss_iobuf_write_uint32(struct sss_iobuf *iobuf,
uint32_t val)
{
diff --git a/src/util/sss_iobuf.h b/src/util/sss_iobuf.h
index cc3dfd1e98eeb49b979ac321bd0253bffa8a6dff..159fbc0b9ff756ca996722a84a1a13635d1aa8de 100644
--- a/src/util/sss_iobuf.h
+++ b/src/util/sss_iobuf.h
@@ -50,6 +50,29 @@ struct sss_iobuf *sss_iobuf_init_readonly(TALLOC_CTX *mem_ctx,
const uint8_t *data,
size_t size);
+/*
+ * @brief Allocate an IO buffer with a fixed size, stealing input data.
+ *
+ * This function is useful for parsing an input buffer from an existing
+ * buffer pointed to by data.
+ *
+ * The iobuf assumes ownership of the data buffer.
+ *
+ * @param[in] mem_ctx The talloc context that owns the iobuf
+ * @param[in] data The data to initialize the IO buffer with.
+ * @param[in] size The size of the data buffer
+ *
+ * @return The newly created buffer on success or NULL on an error.
+ */
+struct sss_iobuf *sss_iobuf_init_steal(TALLOC_CTX *mem_ctx,
+ uint8_t *data,
+ size_t size);
+
+/*
+ * @brief Reset internal cursor of the IO buffer (seek to the start)
+ */
+void sss_iobuf_cursor_reset(struct sss_iobuf *iobuf);
+
/*
* @brief Returns the number of bytes currently stored in the iobuf
*
@@ -131,6 +154,28 @@ errno_t sss_iobuf_write_len(struct sss_iobuf *iobuf,
uint8_t *buf,
size_t len);
+errno_t sss_iobuf_read_varlen(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *iobuf,
+ uint8_t **_out,
+ size_t *_len);
+
+errno_t sss_iobuf_write_varlen(struct sss_iobuf *iobuf,
+ uint8_t *data,
+ size_t len);
+
+errno_t sss_iobuf_read_iobuf(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *iobuf,
+ struct sss_iobuf **_out);
+
+errno_t sss_iobuf_write_iobuf(struct sss_iobuf *iobuf,
+ struct sss_iobuf *data);
+
+errno_t sss_iobuf_read_uint8(struct sss_iobuf *iobuf,
+ uint8_t *_val);
+
+errno_t sss_iobuf_write_uint8(struct sss_iobuf *iobuf,
+ uint8_t val);
+
errno_t sss_iobuf_read_uint32(struct sss_iobuf *iobuf,
uint32_t *_val);
@@ -148,4 +193,5 @@ errno_t sss_iobuf_read_stringz(struct sss_iobuf *iobuf,
errno_t sss_iobuf_write_stringz(struct sss_iobuf *iobuf,
const char *str);
+
#endif /* __SSS_IOBUF_H_ */
--
2.25.4

View File

@ -1,292 +0,0 @@
From 27968f52eb57391ae64df57d29cf9911fc59d161 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 22 Oct 2020 13:34:52 +0200
Subject: [PATCH 08/19] kcm: add json suffix to existing searialization
functions
---
Makefile.am | 10 ++---
src/responder/kcm/kcmsrv_ccache.h | 18 ++++-----
src/responder/kcm/kcmsrv_ccache_json.c | 18 ++++-----
src/responder/kcm/kcmsrv_ccache_secdb.c | 14 +++----
src/responder/kcm/kcmsrv_ccache_secrets.c | 9 ++---
...n_marshalling.c => test_kcm_marshalling.c} | 39 ++++++-------------
6 files changed, 44 insertions(+), 64 deletions(-)
rename src/tests/cmocka/{test_kcm_json_marshalling.c => test_kcm_marshalling.c} (90%)
diff --git a/Makefile.am b/Makefile.am
index 97aa1ec661268aaa7a3f09b5022c5677df19d9da..8ca46bf2f9add08155bfb824444437532c97909c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -311,7 +311,7 @@ endif # HAVE_INOTIFY
if BUILD_KCM
non_interactive_cmocka_based_tests += \
- test_kcm_json \
+ test_kcm_marshalling \
test_kcm_queue \
$(NULL)
endif # BUILD_KCM
@@ -3927,18 +3927,18 @@ test_sssd_krb5_locator_plugin_LDADD = \
$(NULL)
if BUILD_KCM
-test_kcm_json_SOURCES = \
- src/tests/cmocka/test_kcm_json_marshalling.c \
+test_kcm_marshalling_SOURCES = \
+ src/tests/cmocka/test_kcm_marshalling.c \
src/responder/kcm/kcmsrv_ccache_json.c \
src/responder/kcm/kcmsrv_ccache.c \
src/util/sss_krb5.c \
src/util/sss_iobuf.c \
$(NULL)
-test_kcm_json_CFLAGS = \
+test_kcm_marshalling_CFLAGS = \
$(AM_CFLAGS) \
$(UUID_CFLAGS) \
$(NULL)
-test_kcm_json_LDADD = \
+test_kcm_marshalling_LDADD = \
$(JANSSON_LIBS) \
$(UUID_LIBS) \
$(KRB5_LIBS) \
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
index d629923fa140bd30d8a59f56443dea7ce101c33e..5aaded0524d0765dea6bfb962a83cf625f0e85f4 100644
--- a/src/responder/kcm/kcmsrv_ccache.h
+++ b/src/responder/kcm/kcmsrv_ccache.h
@@ -333,16 +333,16 @@ const char *sec_key_create(TALLOC_CTX *mem_ctx,
* sec_key is a concatenation of the ccache's UUID and name
* sec_value is the JSON dump of the ccache contents
*/
-errno_t sec_kv_to_ccache(TALLOC_CTX *mem_ctx,
- const char *sec_key,
- const char *sec_value,
- struct cli_creds *client,
- struct kcm_ccache **_cc);
+errno_t sec_kv_to_ccache_json(TALLOC_CTX *mem_ctx,
+ const char *sec_key,
+ const char *sec_value,
+ struct cli_creds *client,
+ struct kcm_ccache **_cc);
/* Convert a kcm_ccache to a key-value pair to be stored in secrets */
-errno_t kcm_ccache_to_sec_input(TALLOC_CTX *mem_ctx,
- struct kcm_ccache *cc,
- struct cli_creds *client,
- struct sss_iobuf **_payload);
+errno_t kcm_ccache_to_sec_input_json(TALLOC_CTX *mem_ctx,
+ struct kcm_ccache *cc,
+ struct cli_creds *client,
+ struct sss_iobuf **_payload);
#endif /* _KCMSRV_CCACHE_H_ */
diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c
index 38ec53c408c3b9d44f37d102c4a0c976ef32bdfe..8101f5ddc148bfff83cc02cf9b19a3566209e781 100644
--- a/src/responder/kcm/kcmsrv_ccache_json.c
+++ b/src/responder/kcm/kcmsrv_ccache_json.c
@@ -460,10 +460,10 @@ static errno_t ccache_to_sec_val(TALLOC_CTX *mem_ctx,
return EOK;
}
-errno_t kcm_ccache_to_sec_input(TALLOC_CTX *mem_ctx,
- struct kcm_ccache *cc,
- struct cli_creds *client,
- struct sss_iobuf **_payload)
+errno_t kcm_ccache_to_sec_input_json(TALLOC_CTX *mem_ctx,
+ struct kcm_ccache *cc,
+ struct cli_creds *client,
+ struct sss_iobuf **_payload)
{
errno_t ret;
const char *value;
@@ -897,11 +897,11 @@ static errno_t sec_json_value_to_ccache(struct kcm_ccache *cc,
* sec_key is a concatenation of the ccache's UUID and name
* sec_value is the JSON dump of the ccache contents
*/
-errno_t sec_kv_to_ccache(TALLOC_CTX *mem_ctx,
- const char *sec_key,
- const char *sec_value,
- struct cli_creds *client,
- struct kcm_ccache **_cc)
+errno_t sec_kv_to_ccache_json(TALLOC_CTX *mem_ctx,
+ const char *sec_key,
+ const char *sec_value,
+ struct cli_creds *client,
+ struct kcm_ccache **_cc)
{
errno_t ret;
json_t *root = NULL;
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
index f0143e686826e3bf637619efc799e0d2f0715ba4..f5cfe47a7c6deac17031788105ac4235a6aaa9ff 100644
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
@@ -160,7 +160,7 @@ static errno_t kcm_ccache_to_secdb_kv(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = kcm_ccache_to_sec_input(mem_ctx, cc, client, &payload);
+ ret = kcm_ccache_to_sec_input_json(mem_ctx, cc, client, &payload);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Cannot convert ccache to a secret [%d][%s]\n", ret, sss_strerror(ret));
@@ -454,11 +454,9 @@ static errno_t secdb_get_cc(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = sec_kv_to_ccache(tmp_ctx,
- secdb_key,
- (const char *) sss_iobuf_get_data(ccbuf),
- client,
- &cc);
+ ret = sec_kv_to_ccache_json(tmp_ctx, secdb_key,
+ (const char *)sss_iobuf_get_data(ccbuf),
+ client, &cc);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot convert JSON keyval to ccache blob [%d]: %s\n",
@@ -1251,7 +1249,7 @@ static struct tevent_req *ccdb_secdb_mod_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = kcm_ccache_to_sec_input(state, cc, client, &payload);
+ ret = kcm_ccache_to_sec_input_json(state, cc, client, &payload);
if (ret != EOK) {
goto immediate;
}
@@ -1327,7 +1325,7 @@ static struct tevent_req *ccdb_secdb_store_cred_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = kcm_ccache_to_sec_input(state, cc, client, &payload);
+ ret = kcm_ccache_to_sec_input_json(state, cc, client, &payload);
if (ret != EOK) {
goto immediate;
}
diff --git a/src/responder/kcm/kcmsrv_ccache_secrets.c b/src/responder/kcm/kcmsrv_ccache_secrets.c
index 440ab3bb99dd983ba0343f371c0c6470bbd53afc..9d1fe8cad2dc6ed3ab43e181d0db52673d4759cc 100644
--- a/src/responder/kcm/kcmsrv_ccache_secrets.c
+++ b/src/responder/kcm/kcmsrv_ccache_secrets.c
@@ -195,7 +195,7 @@ static errno_t kcm_ccache_to_sec_kv(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = kcm_ccache_to_sec_input(mem_ctx, cc, client, &payload);
+ ret = kcm_ccache_to_sec_input_json(mem_ctx, cc, client, &payload);
if (ret != EOK) {
goto done;
}
@@ -489,11 +489,8 @@ static void sec_get_done(struct tevent_req *subreq)
return;
}
- ret = sec_kv_to_ccache(state,
- state->sec_key,
- sec_value,
- state->client,
- &state->cc);
+ ret = sec_kv_to_ccache_json(state, state->sec_key, sec_value, state->client,
+ &state->cc);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot convert JSON keyval to ccache blob [%d]: %s\n",
diff --git a/src/tests/cmocka/test_kcm_json_marshalling.c b/src/tests/cmocka/test_kcm_marshalling.c
similarity index 90%
rename from src/tests/cmocka/test_kcm_json_marshalling.c
rename to src/tests/cmocka/test_kcm_marshalling.c
index 48ee92bd675780b023b5c8275e5713b91388d06a..f82129974787bba6883662a732311f3370bcc4f1 100644
--- a/src/tests/cmocka/test_kcm_json_marshalling.c
+++ b/src/tests/cmocka/test_kcm_marshalling.c
@@ -154,7 +154,7 @@ static void assert_cc_equal(struct kcm_ccache *cc1,
assert_cc_offset_equal(cc1, cc2);
}
-static void test_kcm_ccache_marshall_unmarshall(void **state)
+static void test_kcm_ccache_marshall_unmarshall_json(void **state)
{
struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state,
struct kcm_marshalling_test_ctx);
@@ -182,10 +182,7 @@ static void test_kcm_ccache_marshall_unmarshall(void **state)
&cc);
assert_int_equal(ret, EOK);
- ret = kcm_ccache_to_sec_input(test_ctx,
- cc,
- &owner,
- &payload);
+ ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &owner, &payload);
assert_int_equal(ret, EOK);
data = sss_iobuf_get_data(payload);
@@ -196,25 +193,19 @@ static void test_kcm_ccache_marshall_unmarshall(void **state)
key = sec_key_create(test_ctx, name, uuid);
assert_non_null(key);
- ret = sec_kv_to_ccache(test_ctx,
- key,
- (const char *) data,
- &owner,
- &cc2);
+ ret = sec_kv_to_ccache_json(test_ctx, key, (const char *)data, &owner,
+ &cc2);
assert_int_equal(ret, EOK);
assert_cc_equal(cc, cc2);
/* This key is exactly one byte shorter than it should be */
- ret = sec_kv_to_ccache(test_ctx,
- TEST_UUID_STR"-",
- (const char *) data,
- &owner,
- &cc2);
+ ret = sec_kv_to_ccache_json(test_ctx, TEST_UUID_STR "-", (const char *)data,
+ &owner, &cc2);
assert_int_equal(ret, EINVAL);
}
-static void test_kcm_ccache_no_princ(void **state)
+static void test_kcm_ccache_no_princ_json(void **state)
{
struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state,
struct kcm_marshalling_test_ctx);
@@ -246,10 +237,7 @@ static void test_kcm_ccache_no_princ(void **state)
princ = kcm_cc_get_client_principal(cc);
assert_null(princ);
- ret = kcm_ccache_to_sec_input(test_ctx,
- cc,
- &owner,
- &payload);
+ ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &owner, &payload);
assert_int_equal(ret, EOK);
data = sss_iobuf_get_data(payload);
@@ -260,11 +248,8 @@ static void test_kcm_ccache_no_princ(void **state)
key = sec_key_create(test_ctx, name, uuid);
assert_non_null(key);
- ret = sec_kv_to_ccache(test_ctx,
- key,
- (const char *) data,
- &owner,
- &cc2);
+ ret = sec_kv_to_ccache_json(test_ctx, key, (const char *)data, &owner,
+ &cc2);
assert_int_equal(ret, EOK);
assert_cc_equal(cc, cc2);
@@ -340,10 +325,10 @@ int main(int argc, const char *argv[])
};
const struct CMUnitTest tests[] = {
- cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall,
+ cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall_json,
setup_kcm_marshalling,
teardown_kcm_marshalling),
- cmocka_unit_test_setup_teardown(test_kcm_ccache_no_princ,
+ cmocka_unit_test_setup_teardown(test_kcm_ccache_no_princ_json,
setup_kcm_marshalling,
teardown_kcm_marshalling),
cmocka_unit_test(test_sec_key_get_uuid),
--
2.25.4

View File

@ -1,404 +0,0 @@
From 23273319b546d034d31ffe3824b954659d20d104 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 27 Oct 2020 16:18:11 +0100
Subject: [PATCH 09/19] kcm: move sec key parser to separate file so it can be
shared
---
Makefile.am | 2 +
src/responder/kcm/kcmsrv_ccache.c | 20 ++++
src/responder/kcm/kcmsrv_ccache.h | 10 ++
src/responder/kcm/kcmsrv_ccache_json.c | 130 +---------------------
src/responder/kcm/kcmsrv_ccache_key.c | 145 +++++++++++++++++++++++++
5 files changed, 179 insertions(+), 128 deletions(-)
create mode 100644 src/responder/kcm/kcmsrv_ccache_key.c
diff --git a/Makefile.am b/Makefile.am
index 8ca46bf2f9add08155bfb824444437532c97909c..ae9bc540a86f2e291dd5b5f66e1ce4f0aacbaf61 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1819,6 +1819,7 @@ sssd_kcm_SOURCES = \
src/responder/kcm/kcmsrv_ccache.c \
src/responder/kcm/kcmsrv_ccache_mem.c \
src/responder/kcm/kcmsrv_ccache_json.c \
+ src/responder/kcm/kcmsrv_ccache_key.c \
src/responder/kcm/kcmsrv_ccache_secdb.c \
src/responder/kcm/kcmsrv_ops.c \
src/responder/kcm/kcmsrv_op_queue.c \
@@ -3930,6 +3931,7 @@ if BUILD_KCM
test_kcm_marshalling_SOURCES = \
src/tests/cmocka/test_kcm_marshalling.c \
src/responder/kcm/kcmsrv_ccache_json.c \
+ src/responder/kcm/kcmsrv_ccache_key.c \
src/responder/kcm/kcmsrv_ccache.c \
src/util/sss_krb5.c \
src/util/sss_iobuf.c \
diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
index 66e2752ba755af3ef1c6c1b21036021a608a94c1..59f8a7293fa7422c199ca2916c8e6ae6039d9312 100644
--- a/src/responder/kcm/kcmsrv_ccache.c
+++ b/src/responder/kcm/kcmsrv_ccache.c
@@ -213,6 +213,26 @@ errno_t kcm_cc_store_creds(struct kcm_ccache *cc,
return EOK;
}
+errno_t kcm_cc_set_header(struct kcm_ccache *cc,
+ const char *sec_key,
+ struct cli_creds *client)
+{
+ errno_t ret;
+
+ ret = sec_key_parse(cc, sec_key, &cc->name, cc->uuid);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ /* We rely on sssd-secrets only searching the user's subtree so we
+ * set the ownership to the client
+ */
+ cc->owner.uid = cli_creds_get_uid(client);
+ cc->owner.gid = cli_creds_get_gid(client);
+
+ return EOK;
+}
+
errno_t kcm_cred_get_uuid(struct kcm_cred *crd, uuid_t _uuid)
{
if (crd == NULL) {
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
index 5aaded0524d0765dea6bfb962a83cf625f0e85f4..892067f3170b19c0e55ceaa75b0c01f772c49d3d 100644
--- a/src/responder/kcm/kcmsrv_ccache.h
+++ b/src/responder/kcm/kcmsrv_ccache.h
@@ -100,6 +100,11 @@ struct kcm_cred *kcm_cred_new(TALLOC_CTX *mem_ctx,
errno_t kcm_cc_store_creds(struct kcm_ccache *cc,
struct kcm_cred *crd);
+/* Set cc header information from sec key and client */
+errno_t kcm_cc_set_header(struct kcm_ccache *cc,
+ const char *sec_key,
+ struct cli_creds *client);
+
errno_t kcm_cred_get_uuid(struct kcm_cred *crd, uuid_t uuid);
/*
@@ -320,6 +325,11 @@ bool sec_key_match_name(const char *sec_key,
bool sec_key_match_uuid(const char *sec_key,
uuid_t uuid);
+errno_t sec_key_parse(TALLOC_CTX *mem_ctx,
+ const char *sec_key,
+ const char **_name,
+ uuid_t uuid);
+
const char *sec_key_get_name(const char *sec_key);
errno_t sec_key_get_uuid(const char *sec_key,
diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c
index 8101f5ddc148bfff83cc02cf9b19a3566209e781..7f73b56bf6c27417271876a989695ff917c3886e 100644
--- a/src/responder/kcm/kcmsrv_ccache_json.c
+++ b/src/responder/kcm/kcmsrv_ccache_json.c
@@ -37,12 +37,6 @@
*/
#define KS_JSON_VERSION 1
-/*
- * The secrets store is a key-value store at heart. We store the UUID
- * and the name in the key to allow easy lookups be either key
- */
-#define SEC_KEY_SEPARATOR '-'
-
/* Compat definition of json_array_foreach for older systems */
#ifndef json_array_foreach
#define json_array_foreach(array, idx, value) \
@@ -51,119 +45,6 @@
idx++)
#endif
-const char *sec_key_create(TALLOC_CTX *mem_ctx,
- const char *name,
- uuid_t uuid)
-{
- char uuid_str[UUID_STR_SIZE];
-
- uuid_unparse(uuid, uuid_str);
- return talloc_asprintf(mem_ctx,
- "%s%c%s", uuid_str, SEC_KEY_SEPARATOR, name);
-}
-
-static bool sec_key_valid(const char *sec_key)
-{
- if (sec_key == NULL) {
- return false;
- }
-
- if (strlen(sec_key) < UUID_STR_SIZE + 1) {
- /* One char for separator (at UUID_STR_SIZE, because strlen doesn't
- * include the '\0', but UUID_STR_SIZE does) and at least one for
- * the name */
- DEBUG(SSSDBG_CRIT_FAILURE, "Key %s is too short\n", sec_key);
- return false;
- }
-
- if (sec_key[UUID_STR_SIZE - 1] != SEC_KEY_SEPARATOR) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
- return false;
- }
-
- return true;
-}
-
-static errno_t sec_key_parse(TALLOC_CTX *mem_ctx,
- const char *sec_key,
- const char **_name,
- uuid_t uuid)
-{
- char uuid_str[UUID_STR_SIZE];
-
- if (!sec_key_valid(sec_key)) {
- return EINVAL;
- }
-
- strncpy(uuid_str, sec_key, sizeof(uuid_str)-1);
- if (sec_key[UUID_STR_SIZE - 1] != SEC_KEY_SEPARATOR) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
- return EINVAL;
- }
- uuid_str[UUID_STR_SIZE-1] = '\0';
-
- *_name = talloc_strdup(mem_ctx, sec_key + UUID_STR_SIZE);
- if (*_name == NULL) {
- return ENOMEM;
- }
- uuid_parse(uuid_str, uuid);
-
- return EOK;
-}
-
-errno_t sec_key_get_uuid(const char *sec_key,
- uuid_t uuid)
-{
- char uuid_str[UUID_STR_SIZE];
-
- if (!sec_key_valid(sec_key)) {
- return EINVAL;
- }
-
- strncpy(uuid_str, sec_key, UUID_STR_SIZE-1);
- uuid_str[UUID_STR_SIZE-1] = '\0';
- uuid_parse(uuid_str, uuid);
- return EOK;
-}
-
-const char *sec_key_get_name(const char *sec_key)
-{
- if (!sec_key_valid(sec_key)) {
- return NULL;
- }
-
- return sec_key + UUID_STR_SIZE;
-}
-
-bool sec_key_match_name(const char *sec_key,
- const char *name)
-{
- if (!sec_key_valid(sec_key) || name == NULL) {
- return false;
- }
-
- return strcmp(sec_key + UUID_STR_SIZE, name) == 0;
-}
-
-bool sec_key_match_uuid(const char *sec_key,
- uuid_t uuid)
-{
- errno_t ret;
- uuid_t key_uuid;
-
- /* `key_uuid` is output arg and isn't read in sec_key_get_uuid() but
- * since libuuid is opaque for cppcheck it generates false positive here
- */
- /* cppcheck-suppress uninitvar */
- ret = sec_key_get_uuid(sec_key, key_uuid);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE, "Cannot convert key to UUID\n");
- return false;
- }
-
- return uuid_compare(key_uuid, uuid) == 0;
-}
-
/*
* Creates an array of principal elements that will be used later
* in the form of:
@@ -928,16 +809,9 @@ errno_t sec_kv_to_ccache_json(TALLOC_CTX *mem_ctx,
goto done;
}
- /* We rely on sssd-secrets only searching the user's subtree so we
- * set the ownership to the client
- */
- cc->owner.uid = cli_creds_get_uid(client);
- cc->owner.gid = cli_creds_get_gid(client);
-
- ret = sec_key_parse(cc, sec_key, &cc->name, cc->uuid);
+ ret = kcm_cc_set_header(cc, sec_key, client);
if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Cannt parse secret key [%d]: %s\n",
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot store ccache header [%d]: %s\n",
ret, sss_strerror(ret));
goto done;
}
diff --git a/src/responder/kcm/kcmsrv_ccache_key.c b/src/responder/kcm/kcmsrv_ccache_key.c
new file mode 100644
index 0000000000000000000000000000000000000000..ba64f2128c0bba62434b4f84d81514e6b52bc2b6
--- /dev/null
+++ b/src/responder/kcm/kcmsrv_ccache_key.c
@@ -0,0 +1,145 @@
+/*
+ SSSD
+
+ Copyright (C) Red Hat, 2020
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <talloc.h>
+
+#include "util/util.h"
+#include "responder/kcm/kcmsrv_ccache_pvt.h"
+
+/*
+ * The secrets store is a key-value store at heart. We store the UUID
+ * and the name in the key to allow easy lookups by either part.
+ */
+#define SEC_KEY_SEPARATOR '-'
+
+const char *sec_key_create(TALLOC_CTX *mem_ctx,
+ const char *name,
+ uuid_t uuid)
+{
+ char uuid_str[UUID_STR_SIZE];
+
+ uuid_unparse(uuid, uuid_str);
+ return talloc_asprintf(mem_ctx,
+ "%s%c%s", uuid_str, SEC_KEY_SEPARATOR, name);
+}
+
+static bool sec_key_valid(const char *sec_key)
+{
+ if (sec_key == NULL) {
+ return false;
+ }
+
+ if (strlen(sec_key) < UUID_STR_SIZE + 1) {
+ /* One char for separator (at UUID_STR_SIZE, because strlen doesn't
+ * include the '\0', but UUID_STR_SIZE does) and at least one for
+ * the name */
+ DEBUG(SSSDBG_CRIT_FAILURE, "Key %s is too short\n", sec_key);
+ return false;
+ }
+
+ if (sec_key[UUID_STR_SIZE - 1] != SEC_KEY_SEPARATOR) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
+ return false;
+ }
+
+ return true;
+}
+
+errno_t sec_key_parse(TALLOC_CTX *mem_ctx,
+ const char *sec_key,
+ const char **_name,
+ uuid_t uuid)
+{
+ char uuid_str[UUID_STR_SIZE];
+
+ if (!sec_key_valid(sec_key)) {
+ return EINVAL;
+ }
+
+ strncpy(uuid_str, sec_key, sizeof(uuid_str)-1);
+ if (sec_key[UUID_STR_SIZE - 1] != SEC_KEY_SEPARATOR) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
+ return EINVAL;
+ }
+ uuid_str[UUID_STR_SIZE-1] = '\0';
+
+ *_name = talloc_strdup(mem_ctx, sec_key + UUID_STR_SIZE);
+ if (*_name == NULL) {
+ return ENOMEM;
+ }
+ uuid_parse(uuid_str, uuid);
+
+ return EOK;
+}
+
+errno_t sec_key_get_uuid(const char *sec_key,
+ uuid_t uuid)
+{
+ char uuid_str[UUID_STR_SIZE];
+
+ if (!sec_key_valid(sec_key)) {
+ return EINVAL;
+ }
+
+ strncpy(uuid_str, sec_key, UUID_STR_SIZE-1);
+ uuid_str[UUID_STR_SIZE-1] = '\0';
+ uuid_parse(uuid_str, uuid);
+ return EOK;
+}
+
+const char *sec_key_get_name(const char *sec_key)
+{
+ if (!sec_key_valid(sec_key)) {
+ return NULL;
+ }
+
+ return sec_key + UUID_STR_SIZE;
+}
+
+bool sec_key_match_name(const char *sec_key,
+ const char *name)
+{
+ if (!sec_key_valid(sec_key) || name == NULL) {
+ return false;
+ }
+
+ return strcmp(sec_key + UUID_STR_SIZE, name) == 0;
+}
+
+bool sec_key_match_uuid(const char *sec_key,
+ uuid_t uuid)
+{
+ errno_t ret;
+ uuid_t key_uuid;
+
+ /* `key_uuid` is output arg and isn't read in sec_key_get_uuid() but
+ * since libuuid is opaque for cppcheck it generates false positive here
+ */
+ /* cppcheck-suppress uninitvar */
+ ret = sec_key_get_uuid(sec_key, key_uuid);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot convert key to UUID\n");
+ return false;
+ }
+
+ return uuid_compare(key_uuid, uuid) == 0;
+}
--
2.25.4

View File

@ -1,30 +0,0 @@
From efd57d2a6001b7015095f7ff5bbd0c55764e22ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 27 Oct 2020 16:37:05 +0100
Subject: [PATCH 10/19] kcm: avoid suppression of cppcheck warning
---
src/responder/kcm/kcmsrv_ccache_key.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/responder/kcm/kcmsrv_ccache_key.c b/src/responder/kcm/kcmsrv_ccache_key.c
index ba64f2128c0bba62434b4f84d81514e6b52bc2b6..4a24c38d45918632201740bfc82579a2449aa8f7 100644
--- a/src/responder/kcm/kcmsrv_ccache_key.c
+++ b/src/responder/kcm/kcmsrv_ccache_key.c
@@ -131,10 +131,9 @@ bool sec_key_match_uuid(const char *sec_key,
errno_t ret;
uuid_t key_uuid;
- /* `key_uuid` is output arg and isn't read in sec_key_get_uuid() but
- * since libuuid is opaque for cppcheck it generates false positive here
- */
- /* cppcheck-suppress uninitvar */
+ /* Clear uuid value to avoid cppcheck warning. */
+ uuid_clear(key_uuid);
+
ret = sec_key_get_uuid(sec_key, key_uuid);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, "Cannot convert key to UUID\n");
--
2.25.4

View File

@ -1,42 +0,0 @@
From d51819e51fca80675b9915863e72d835c9e0a0fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 27 Oct 2020 17:09:43 +0100
Subject: [PATCH 11/19] kcm: add spaces around operators in kcmsrv_ccache_key.c
---
src/responder/kcm/kcmsrv_ccache_key.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/responder/kcm/kcmsrv_ccache_key.c b/src/responder/kcm/kcmsrv_ccache_key.c
index 4a24c38d45918632201740bfc82579a2449aa8f7..59d60453c5d5e28ccda8f98c63125954640d0e8b 100644
--- a/src/responder/kcm/kcmsrv_ccache_key.c
+++ b/src/responder/kcm/kcmsrv_ccache_key.c
@@ -75,12 +75,12 @@ errno_t sec_key_parse(TALLOC_CTX *mem_ctx,
return EINVAL;
}
- strncpy(uuid_str, sec_key, sizeof(uuid_str)-1);
+ strncpy(uuid_str, sec_key, sizeof(uuid_str) - 1);
if (sec_key[UUID_STR_SIZE - 1] != SEC_KEY_SEPARATOR) {
DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
return EINVAL;
}
- uuid_str[UUID_STR_SIZE-1] = '\0';
+ uuid_str[UUID_STR_SIZE - 1] = '\0';
*_name = talloc_strdup(mem_ctx, sec_key + UUID_STR_SIZE);
if (*_name == NULL) {
@@ -100,8 +100,8 @@ errno_t sec_key_get_uuid(const char *sec_key,
return EINVAL;
}
- strncpy(uuid_str, sec_key, UUID_STR_SIZE-1);
- uuid_str[UUID_STR_SIZE-1] = '\0';
+ strncpy(uuid_str, sec_key, UUID_STR_SIZE - 1);
+ uuid_str[UUID_STR_SIZE - 1] = '\0';
uuid_parse(uuid_str, uuid);
return EOK;
}
--
2.25.4

View File

@ -1,741 +0,0 @@
From 94ceb85465dbf052f681bbd6c8ebced4d2d97f92 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 27 Oct 2020 16:21:31 +0100
Subject: [PATCH 12/19] kcm: use binary format to store ccache instead of json
JSON is computationally complex and the parser is a bottleneck which
consumes about 10% of time. It also create the ccache unnecessary
large because it requires lots of unneded character and base64
encoding.
Binary format is fast, simple and small.
This is backwards compatible and there is no need to destroy existing
ccache. It will be stored in binary format at first write to the cache.
Resolves: https://github.com/SSSD/sssd/issues/5349
---
Makefile.am | 2 +
src/responder/kcm/kcmsrv_ccache.h | 16 +-
src/responder/kcm/kcmsrv_ccache_binary.c | 308 ++++++++++++++++++++++
src/responder/kcm/kcmsrv_ccache_json.c | 1 -
src/responder/kcm/kcmsrv_ccache_secdb.c | 49 ++--
src/responder/kcm/kcmsrv_ccache_secrets.c | 2 +-
src/tests/cmocka/test_kcm_marshalling.c | 112 +++++++-
src/tests/multihost/basic/test_kcm.py | 12 +-
src/util/secrets/secrets.c | 2 +-
9 files changed, 476 insertions(+), 28 deletions(-)
create mode 100644 src/responder/kcm/kcmsrv_ccache_binary.c
diff --git a/Makefile.am b/Makefile.am
index ae9bc540a86f2e291dd5b5f66e1ce4f0aacbaf61..430b4e8424d6bde0c7de919c6aceabf3839e3a23 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1817,6 +1817,7 @@ sssd_kcm_SOURCES = \
src/responder/kcm/kcm.c \
src/responder/kcm/kcmsrv_cmd.c \
src/responder/kcm/kcmsrv_ccache.c \
+ src/responder/kcm/kcmsrv_ccache_binary.c \
src/responder/kcm/kcmsrv_ccache_mem.c \
src/responder/kcm/kcmsrv_ccache_json.c \
src/responder/kcm/kcmsrv_ccache_key.c \
@@ -3930,6 +3931,7 @@ test_sssd_krb5_locator_plugin_LDADD = \
if BUILD_KCM
test_kcm_marshalling_SOURCES = \
src/tests/cmocka/test_kcm_marshalling.c \
+ src/responder/kcm/kcmsrv_ccache_binary.c \
src/responder/kcm/kcmsrv_ccache_json.c \
src/responder/kcm/kcmsrv_ccache_key.c \
src/responder/kcm/kcmsrv_ccache.c \
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
index 892067f3170b19c0e55ceaa75b0c01f772c49d3d..b0a7acb9fed8a8f89a3d0e2239ab28c7ce80fa23 100644
--- a/src/responder/kcm/kcmsrv_ccache.h
+++ b/src/responder/kcm/kcmsrv_ccache.h
@@ -352,7 +352,21 @@ errno_t sec_kv_to_ccache_json(TALLOC_CTX *mem_ctx,
/* Convert a kcm_ccache to a key-value pair to be stored in secrets */
errno_t kcm_ccache_to_sec_input_json(TALLOC_CTX *mem_ctx,
struct kcm_ccache *cc,
- struct cli_creds *client,
struct sss_iobuf **_payload);
+/*
+ * sec_key is a concatenation of the ccache's UUID and name
+ * sec_value is the binary representation of ccache.
+ */
+errno_t sec_kv_to_ccache_binary(TALLOC_CTX *mem_ctx,
+ const char *sec_key,
+ struct sss_iobuf *sec_value,
+ struct cli_creds *client,
+ struct kcm_ccache **_cc);
+
+/* Convert a kcm_ccache to its binary representation. */
+errno_t kcm_ccache_to_sec_input_binary(TALLOC_CTX *mem_ctx,
+ struct kcm_ccache *cc,
+ struct sss_iobuf **_payload);
+
#endif /* _KCMSRV_CCACHE_H_ */
diff --git a/src/responder/kcm/kcmsrv_ccache_binary.c b/src/responder/kcm/kcmsrv_ccache_binary.c
new file mode 100644
index 0000000000000000000000000000000000000000..7bfdbf13bfeaa7d45de6352e7b51b781b713b8f2
--- /dev/null
+++ b/src/responder/kcm/kcmsrv_ccache_binary.c
@@ -0,0 +1,308 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2020 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <talloc.h>
+
+#include "util/util.h"
+#include "util/util_creds.h"
+#include "util/crypto/sss_crypto.h"
+#include "responder/kcm/kcmsrv_ccache_pvt.h"
+
+static errno_t krb_data_to_bin(krb5_data *data, struct sss_iobuf *buf)
+{
+ return sss_iobuf_write_varlen(buf, (uint8_t *)data->data, data->length);
+}
+
+static errno_t princ_to_bin(krb5_principal princ, struct sss_iobuf *buf)
+{
+ errno_t ret;
+
+ if (princ == NULL) {
+ return sss_iobuf_write_uint8(buf, 0);
+ }
+
+ /* Mark that principal is not empty. */
+ ret = sss_iobuf_write_uint8(buf, 1);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ ret = krb_data_to_bin(&princ->realm, buf);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ ret = sss_iobuf_write_int32(buf, princ->type);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ ret = sss_iobuf_write_int32(buf, princ->length);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ for (krb5_int32 i = 0; i < princ->length; i++) {
+ ret = krb_data_to_bin(&princ->data[i], buf);
+ if (ret != EOK) {
+ return ret;
+ }
+ }
+
+ return EOK;
+}
+
+static errno_t creds_to_bin(struct kcm_cred *creds, struct sss_iobuf *buf)
+{
+ struct kcm_cred *crd;
+ uint32_t count = 0;
+ errno_t ret;
+
+ DLIST_FOR_EACH(crd, creds) {
+ count++;
+ }
+
+ ret = sss_iobuf_write_uint32(buf, count);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ DLIST_FOR_EACH(crd, creds) {
+ ret = sss_iobuf_write_len(buf, (uint8_t *)crd->uuid, sizeof(uuid_t));
+ if (ret != EOK) {
+ return ret;
+ }
+
+ ret = sss_iobuf_write_iobuf(buf, crd->cred_blob);
+ if (ret != EOK) {
+ return ret;
+ }
+ }
+
+ return EOK;
+}
+
+errno_t kcm_ccache_to_sec_input_binary(TALLOC_CTX *mem_ctx,
+ struct kcm_ccache *cc,
+ struct sss_iobuf **_payload)
+{
+ struct sss_iobuf *buf;
+ errno_t ret;
+
+ buf = sss_iobuf_init_empty(mem_ctx, sizeof(krb5_principal_data), 0);
+ if (buf == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sss_iobuf_write_int32(buf, cc->kdc_offset);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = princ_to_bin(cc->client, buf);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = creds_to_bin(cc->creds, buf);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ *_payload = buf;
+
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ talloc_free(buf);
+ }
+
+ return ret;
+}
+
+static errno_t bin_to_krb_data(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *buf,
+ krb5_data *out)
+{
+ uint8_t *data;
+ size_t len;
+ errno_t ret;
+
+ ret = sss_iobuf_read_varlen(mem_ctx, buf, &data, &len);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ out->magic = 0;
+ out->data = (char*)data;
+ out->length = len;
+
+ return EOK;
+}
+
+static errno_t bin_to_princ(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *buf,
+ krb5_principal *_princ)
+{
+ krb5_principal princ;
+ uint8_t non_empty;
+ krb5_int32 i;
+ errno_t ret;
+
+ ret = sss_iobuf_read_uint8(buf, &non_empty);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ if (non_empty == 0) {
+ *_princ = NULL;
+ return EOK;
+ }
+
+ princ = talloc_zero(mem_ctx, struct krb5_principal_data);
+ if (princ == NULL) {
+ return ENOMEM;
+ }
+ princ->magic = KV5M_PRINCIPAL;
+
+ ret = bin_to_krb_data(princ, buf, &princ->realm);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ ret = sss_iobuf_read_int32(buf, &princ->type);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ ret = sss_iobuf_read_int32(buf, &princ->length);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ princ->data = talloc_zero_array(princ, krb5_data, princ->length);
+ if (princ->length > 0 && princ->data == NULL) {
+ return ENOMEM;
+ }
+
+ for (i = 0; i < princ->length; i++) {
+ ret = bin_to_krb_data(princ, buf, &princ->data[i]);
+ if (ret != EOK) {
+ return ret;
+ }
+ }
+
+ *_princ = princ;
+
+ return EOK;
+}
+
+static errno_t bin_to_creds(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *buf,
+ struct kcm_cred **_creds)
+{
+ struct kcm_cred *creds = NULL;
+ struct kcm_cred *crd;
+ struct sss_iobuf *cred_blob;
+ uint32_t count;
+ uuid_t uuid;
+ errno_t ret;
+
+ ret = sss_iobuf_read_uint32(buf, &count);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ for (uint32_t i = 0; i < count; i++) {
+ ret = sss_iobuf_read_len(buf, sizeof(uuid_t), (uint8_t*)uuid);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ ret = sss_iobuf_read_iobuf(NULL, buf, &cred_blob);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ crd = kcm_cred_new(mem_ctx, uuid, cred_blob);
+ if (crd == NULL) {
+ talloc_free(cred_blob);
+ return ENOMEM;
+ }
+
+ DLIST_ADD(creds, crd);
+ }
+
+ *_creds = creds;
+
+ return EOK;
+}
+
+errno_t sec_kv_to_ccache_binary(TALLOC_CTX *mem_ctx,
+ const char *sec_key,
+ struct sss_iobuf *sec_value,
+ struct cli_creds *client,
+ struct kcm_ccache **_cc)
+{
+ struct kcm_ccache *cc;
+ errno_t ret;
+
+ cc = talloc_zero(mem_ctx, struct kcm_ccache);
+ if (cc == NULL) {
+ return ENOMEM;
+ }
+
+ ret = kcm_cc_set_header(cc, sec_key, client);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot store ccache header [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = sss_iobuf_read_int32(sec_value, &cc->kdc_offset);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = bin_to_princ(cc, sec_value, &cc->client);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = bin_to_creds(cc, sec_value, &cc->creds);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ *_cc = cc;
+
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ talloc_free(cc);
+ }
+
+ return ret;
+}
diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c
index 7f73b56bf6c27417271876a989695ff917c3886e..e790cbea36d57d2ba0d4e25fc8fc249a4e653c3c 100644
--- a/src/responder/kcm/kcmsrv_ccache_json.c
+++ b/src/responder/kcm/kcmsrv_ccache_json.c
@@ -343,7 +343,6 @@ static errno_t ccache_to_sec_val(TALLOC_CTX *mem_ctx,
errno_t kcm_ccache_to_sec_input_json(TALLOC_CTX *mem_ctx,
struct kcm_ccache *cc,
- struct cli_creds *client,
struct sss_iobuf **_payload)
{
errno_t ret;
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
index f5cfe47a7c6deac17031788105ac4235a6aaa9ff..726711ac441c40a6bfc84045e9b3e5b85505c7e0 100644
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
@@ -37,11 +37,14 @@
static errno_t sec_get(TALLOC_CTX *mem_ctx,
struct sss_sec_req *req,
- struct sss_iobuf **_buf)
+ struct sss_iobuf **_buf,
+ char **_datatype)
{
errno_t ret;
TALLOC_CTX *tmp_ctx;
- char *secret;
+ char *datatype;
+ uint8_t *data;
+ size_t len;
struct sss_iobuf *buf;
tmp_ctx = talloc_new(mem_ctx);
@@ -49,23 +52,27 @@ static errno_t sec_get(TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- ret = sss_sec_get(tmp_ctx, req, (uint8_t **)&secret, NULL, NULL);
+ ret = sss_sec_get(tmp_ctx, req, &data, &len, &datatype);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot retrieve the secret [%d]: %s\n", ret, sss_strerror(ret));
goto done;
}
- buf = sss_iobuf_init_readonly(tmp_ctx, (const uint8_t *)secret,
- strlen(secret) + 1);
+ buf = sss_iobuf_init_steal(tmp_ctx, data, len);
if (buf == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init the iobuf\n");
ret = EIO;
goto done;
}
- ret = EOK;
*_buf = talloc_steal(mem_ctx, buf);
+ if (_datatype != NULL) {
+ *_datatype = talloc_steal(mem_ctx, datatype);
+ }
+
+ ret = EOK;
+
done:
talloc_free(tmp_ctx);
return ret;
@@ -78,7 +85,7 @@ static errno_t sec_put(TALLOC_CTX *mem_ctx,
errno_t ret;
ret = sss_sec_put(req, sss_iobuf_get_data(buf), sss_iobuf_get_size(buf),
- SSS_SEC_PLAINTEXT, "simple");
+ SSS_SEC_PLAINTEXT, "binary");
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
@@ -94,7 +101,7 @@ static errno_t sec_update(TALLOC_CTX *mem_ctx,
errno_t ret;
ret = sss_sec_update(req, sss_iobuf_get_data(buf), sss_iobuf_get_size(buf),
- SSS_SEC_PLAINTEXT, "simple");
+ SSS_SEC_PLAINTEXT, "binary");
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
@@ -160,7 +167,7 @@ static errno_t kcm_ccache_to_secdb_kv(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = kcm_ccache_to_sec_input_json(mem_ctx, cc, client, &payload);
+ ret = kcm_ccache_to_sec_input_binary(mem_ctx, cc, &payload);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Cannot convert ccache to a secret [%d][%s]\n", ret, sss_strerror(ret));
@@ -434,6 +441,7 @@ static errno_t secdb_get_cc(TALLOC_CTX *mem_ctx,
struct kcm_ccache *cc = NULL;
struct sss_sec_req *sreq = NULL;
struct sss_iobuf *ccbuf;
+ char *datatype;
tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) {
@@ -447,20 +455,23 @@ static errno_t secdb_get_cc(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = sec_get(tmp_ctx, sreq, &ccbuf);
+ ret = sec_get(tmp_ctx, sreq, &ccbuf, &datatype);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Cannot get the secret [%d][%s]\n", ret, sss_strerror(ret));
goto done;
}
- ret = sec_kv_to_ccache_json(tmp_ctx, secdb_key,
- (const char *)sss_iobuf_get_data(ccbuf),
- client, &cc);
+ if (strcmp(datatype, "binary") == 0) {
+ ret = sec_kv_to_ccache_binary(tmp_ctx, secdb_key, ccbuf, client, &cc);
+ } else {
+ ret = sec_kv_to_ccache_json(tmp_ctx, secdb_key,
+ (const char *)sss_iobuf_get_data(ccbuf),
+ client, &cc);
+ }
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Cannot convert JSON keyval to ccache blob [%d]: %s\n",
- ret, sss_strerror(ret));
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot convert %s data to ccache "
+ "[%d]: %s\n", datatype, ret, sss_strerror(ret));
goto done;
}
@@ -756,7 +767,7 @@ static struct tevent_req *ccdb_secdb_get_default_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = sec_get(state, sreq, &dfl_iobuf);
+ ret = sec_get(state, sreq, &dfl_iobuf, NULL);
if (ret == ENOENT) {
uuid_clear(state->uuid);
ret = EOK;
@@ -1249,7 +1260,7 @@ static struct tevent_req *ccdb_secdb_mod_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = kcm_ccache_to_sec_input_json(state, cc, client, &payload);
+ ret = kcm_ccache_to_sec_input_binary(state, cc, &payload);
if (ret != EOK) {
goto immediate;
}
@@ -1325,7 +1336,7 @@ static struct tevent_req *ccdb_secdb_store_cred_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = kcm_ccache_to_sec_input_json(state, cc, client, &payload);
+ ret = kcm_ccache_to_sec_input_binary(state, cc, &payload);
if (ret != EOK) {
goto immediate;
}
diff --git a/src/responder/kcm/kcmsrv_ccache_secrets.c b/src/responder/kcm/kcmsrv_ccache_secrets.c
index 9d1fe8cad2dc6ed3ab43e181d0db52673d4759cc..f3d69842cf8c230800aaf4fc6554495fcf03f57d 100644
--- a/src/responder/kcm/kcmsrv_ccache_secrets.c
+++ b/src/responder/kcm/kcmsrv_ccache_secrets.c
@@ -195,7 +195,7 @@ static errno_t kcm_ccache_to_sec_kv(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = kcm_ccache_to_sec_input_json(mem_ctx, cc, client, &payload);
+ ret = kcm_ccache_to_sec_input_json(mem_ctx, cc, &payload);
if (ret != EOK) {
goto done;
}
diff --git a/src/tests/cmocka/test_kcm_marshalling.c b/src/tests/cmocka/test_kcm_marshalling.c
index f82129974787bba6883662a732311f3370bcc4f1..cebebac804b0a8a109084b35f58d4aab21e28da2 100644
--- a/src/tests/cmocka/test_kcm_marshalling.c
+++ b/src/tests/cmocka/test_kcm_marshalling.c
@@ -182,7 +182,7 @@ static void test_kcm_ccache_marshall_unmarshall_json(void **state)
&cc);
assert_int_equal(ret, EOK);
- ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &owner, &payload);
+ ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &payload);
assert_int_equal(ret, EOK);
data = sss_iobuf_get_data(payload);
@@ -237,7 +237,7 @@ static void test_kcm_ccache_no_princ_json(void **state)
princ = kcm_cc_get_client_principal(cc);
assert_null(princ);
- ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &owner, &payload);
+ ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &payload);
assert_int_equal(ret, EOK);
data = sss_iobuf_get_data(payload);
@@ -255,6 +255,108 @@ static void test_kcm_ccache_no_princ_json(void **state)
assert_cc_equal(cc, cc2);
}
+static void test_kcm_ccache_marshall_unmarshall_binary(void **state)
+{
+ struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state,
+ struct kcm_marshalling_test_ctx);
+ errno_t ret;
+ struct cli_creds owner;
+ struct kcm_ccache *cc;
+ struct kcm_ccache *cc2;
+ struct sss_iobuf *payload;
+ const char *name;
+ const char *key;
+ uint8_t *data;
+ uuid_t uuid;
+
+ owner.ucred.uid = getuid();
+ owner.ucred.gid = getuid();
+
+ name = talloc_asprintf(test_ctx, "%"SPRIuid, getuid());
+ assert_non_null(name);
+
+ ret = kcm_cc_new(test_ctx,
+ test_ctx->kctx,
+ &owner,
+ name,
+ test_ctx->princ,
+ &cc);
+ assert_int_equal(ret, EOK);
+
+ ret = kcm_ccache_to_sec_input_binary(test_ctx, cc, &payload);
+ assert_int_equal(ret, EOK);
+
+ data = sss_iobuf_get_data(payload);
+ assert_non_null(data);
+
+ ret = kcm_cc_get_uuid(cc, uuid);
+ assert_int_equal(ret, EOK);
+ key = sec_key_create(test_ctx, name, uuid);
+ assert_non_null(key);
+
+ sss_iobuf_cursor_reset(payload);
+ ret = sec_kv_to_ccache_binary(test_ctx, key, payload, &owner, &cc2);
+ assert_int_equal(ret, EOK);
+
+ assert_cc_equal(cc, cc2);
+
+ /* This key is exactly one byte shorter than it should be */
+ sss_iobuf_cursor_reset(payload);
+ ret = sec_kv_to_ccache_binary(test_ctx, TEST_UUID_STR "-", payload, &owner,
+ &cc2);
+ assert_int_equal(ret, EINVAL);
+}
+
+static void test_kcm_ccache_no_princ_binary(void **state)
+{
+ struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state,
+ struct kcm_marshalling_test_ctx);
+ errno_t ret;
+ struct cli_creds owner;
+ const char *name;
+ struct kcm_ccache *cc;
+ krb5_principal princ;
+ struct kcm_ccache *cc2;
+ struct sss_iobuf *payload;
+ const char *key;
+ uint8_t *data;
+ uuid_t uuid;
+
+ owner.ucred.uid = getuid();
+ owner.ucred.gid = getuid();
+
+ name = talloc_asprintf(test_ctx, "%"SPRIuid, getuid());
+ assert_non_null(name);
+
+ ret = kcm_cc_new(test_ctx,
+ test_ctx->kctx,
+ &owner,
+ name,
+ NULL,
+ &cc);
+ assert_int_equal(ret, EOK);
+
+ princ = kcm_cc_get_client_principal(cc);
+ assert_null(princ);
+
+ ret = kcm_ccache_to_sec_input_binary(test_ctx, cc, &payload);
+ assert_int_equal(ret, EOK);
+
+ data = sss_iobuf_get_data(payload);
+ assert_non_null(data);
+
+ ret = kcm_cc_get_uuid(cc, uuid);
+ assert_int_equal(ret, EOK);
+ key = sec_key_create(test_ctx, name, uuid);
+ assert_non_null(key);
+
+ sss_iobuf_cursor_reset(payload);
+ ret = sec_kv_to_ccache_binary(test_ctx, key, payload, &owner, &cc2);
+ assert_int_equal(ret, EOK);
+
+ assert_cc_equal(cc, cc2);
+}
+
void test_sec_key_get_uuid(void **state)
{
errno_t ret;
@@ -325,6 +427,12 @@ int main(int argc, const char *argv[])
};
const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall_binary,
+ setup_kcm_marshalling,
+ teardown_kcm_marshalling),
+ cmocka_unit_test_setup_teardown(test_kcm_ccache_no_princ_binary,
+ setup_kcm_marshalling,
+ teardown_kcm_marshalling),
cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall_json,
setup_kcm_marshalling,
teardown_kcm_marshalling),
diff --git a/src/tests/multihost/basic/test_kcm.py b/src/tests/multihost/basic/test_kcm.py
index e5d315827b31f205216d6a20768533ef50983537..6f65431f88b0e77110c3a89c24363d28027390f6 100644
--- a/src/tests/multihost/basic/test_kcm.py
+++ b/src/tests/multihost/basic/test_kcm.py
@@ -310,6 +310,12 @@ class TestSanityKCM(object):
set_param(multihost, 'kcm', 'max_ccache_size', '1')
self._restart_kcm(multihost)
- with pytest.raises(paramiko.ssh_exception.AuthenticationException):
- ssh_foo3 = SSHClient(multihost.master[0].sys_hostname,
- username='foo3', password='Secret123')
+ # We use kinit to exceed the maximum ccache size as it creates payload
+ # of 1280 bytes by acquiring tgt and also some control credentials.
+ # SSH authentication is not sufficient as it stores only tgt.
+ ssh_foo3 = SSHClient(multihost.master[0].sys_hostname,
+ username='foo3', password='Secret123')
+ (_, _, exit_status) = ssh_foo3.execute_cmd(
+ 'kinit foo3@EXAMPLE.TEST', 'Secret123'
+ )
+ assert exit_status != 0
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
index 2a7149ae8b1c88623784ffd4f3e7f908be15c662..6fd9e0af5bd9986052efdb8e244ddeb9e4fa50ff 100644
--- a/src/util/secrets/secrets.c
+++ b/src/util/secrets/secrets.c
@@ -36,7 +36,7 @@
#define SECRETS_BASEDN "cn=secrets"
#define KCM_BASEDN "cn=kcm"
-#define LOCAL_SIMPLE_FILTER "(type=simple)"
+#define LOCAL_SIMPLE_FILTER "(|(type=simple)(type=binary))"
#define LOCAL_CONTAINER_FILTER "(type=container)"
typedef int (*url_mapper_fn)(TALLOC_CTX *mem_ctx,
--
2.25.4

View File

@ -1,131 +0,0 @@
From ae6898e7dc60d7067f0d71212c7ed28fc9e8e285 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 16 Oct 2020 15:36:51 +0200
Subject: [PATCH 13/19] kcm: add per-connection data to be shared between
requests
Resolves: https://github.com/SSSD/sssd/issues/5349
---
src/responder/kcm/kcmsrv_cmd.c | 21 +++++++++++++++++----
src/responder/kcm/kcmsrv_ops.c | 3 +++
src/responder/kcm/kcmsrv_ops.h | 5 +++++
3 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/src/responder/kcm/kcmsrv_cmd.c b/src/responder/kcm/kcmsrv_cmd.c
index 99980050f205730169f5907db4018e4fe57b046d..a1aa9aa20f7c2b5cd972bd944995286de5e7c1e2 100644
--- a/src/responder/kcm/kcmsrv_cmd.c
+++ b/src/responder/kcm/kcmsrv_cmd.c
@@ -373,13 +373,16 @@ static errno_t kcm_cmd_dispatch(struct kcm_ctx *kctx,
{
struct tevent_req *req;
struct cli_ctx *cctx;
+ struct kcm_conn_data *conn_data;
cctx = req_ctx->cctx;
+ conn_data = talloc_get_type(cctx->state_ctx, struct kcm_conn_data);
req = kcm_cmd_send(req_ctx,
cctx->ev,
kctx->qctx,
req_ctx->kctx->kcm_data,
+ conn_data,
req_ctx->cctx->creds,
&req_ctx->op_io.request,
req_ctx->op_io.op);
@@ -492,7 +495,7 @@ static void kcm_recv(struct cli_ctx *cctx)
int ret;
kctx = talloc_get_type(cctx->rctx->pvt_ctx, struct kcm_ctx);
- req = talloc_get_type(cctx->state_ctx, struct kcm_req_ctx);
+ req = talloc_get_type(cctx->protocol_ctx, struct kcm_req_ctx);
if (req == NULL) {
/* A new request comes in, setup data structures. */
req = kcm_new_req(cctx, kctx);
@@ -503,7 +506,17 @@ static void kcm_recv(struct cli_ctx *cctx)
return;
}
- cctx->state_ctx = req;
+ cctx->protocol_ctx = req;
+ }
+
+ /* Shared data between requests that originates in the same connection. */
+ if (cctx->state_ctx == NULL) {
+ cctx->state_ctx = talloc_zero(cctx, struct kcm_conn_data);
+ if (cctx->state_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set up client state\n");
+ talloc_free(cctx);
+ return;
+ }
}
ret = kcm_recv_data(req, cctx->cfd, &req->reqbuf);
@@ -558,7 +571,7 @@ static int kcm_send_data(struct cli_ctx *cctx)
struct kcm_req_ctx *req;
errno_t ret;
- req = talloc_get_type(cctx->state_ctx, struct kcm_req_ctx);
+ req = talloc_get_type(cctx->protocol_ctx, struct kcm_req_ctx);
ret = kcm_write_iovec(cctx->cfd, &req->repbuf.v_len);
if (ret != EOK) {
@@ -604,7 +617,7 @@ static void kcm_send(struct cli_ctx *cctx)
DEBUG(SSSDBG_TRACE_INTERNAL, "All data sent!\n");
TEVENT_FD_NOT_WRITEABLE(cctx->cfde);
TEVENT_FD_READABLE(cctx->cfde);
- talloc_zfree(cctx->state_ctx);
+ talloc_zfree(cctx->protocol_ctx);
return;
}
diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c
index 7fc3b0a5c4e123a398ef103f3ce92b45bc68f5cf..6ae1f0c647f4d385477ddeadbad93287cba05c55 100644
--- a/src/responder/kcm/kcmsrv_ops.c
+++ b/src/responder/kcm/kcmsrv_ops.c
@@ -38,6 +38,7 @@
struct kcm_op_ctx {
struct kcm_resp_ctx *kcm_data;
+ struct kcm_conn_data *conn_data;
struct cli_creds *client;
struct sss_iobuf *input;
@@ -86,6 +87,7 @@ struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct kcm_ops_queue_ctx *qctx,
struct kcm_resp_ctx *kcm_data,
+ struct kcm_conn_data *conn_data,
struct cli_creds *client,
struct kcm_data *input,
struct kcm_op *op)
@@ -135,6 +137,7 @@ struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
}
state->op_ctx->kcm_data = kcm_data;
+ state->op_ctx->conn_data = conn_data;
state->op_ctx->client = client;
state->op_ctx->input = sss_iobuf_init_readonly(state->op_ctx,
diff --git a/src/responder/kcm/kcmsrv_ops.h b/src/responder/kcm/kcmsrv_ops.h
index 67d9f86026bf949548471f2280c130ebefd2f865..fd2dd03c9da3660e0c1346752e4db59c7cbe2c41 100644
--- a/src/responder/kcm/kcmsrv_ops.h
+++ b/src/responder/kcm/kcmsrv_ops.h
@@ -32,10 +32,15 @@ struct kcm_op;
struct kcm_op *kcm_get_opt(uint16_t opcode);
const char *kcm_opt_name(struct kcm_op *op);
+struct kcm_conn_data {
+ void *data;
+};
+
struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct kcm_ops_queue_ctx *qctx,
struct kcm_resp_ctx *kcm_data,
+ struct kcm_conn_data *conn_data,
struct cli_creds *client,
struct kcm_data *input,
struct kcm_op *op);
--
2.25.4

View File

@ -1,165 +0,0 @@
From f1db05d8839b39fd48471dcb29881c12ed27a434 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 29 Oct 2020 14:57:53 +0100
Subject: [PATCH 14/19] sss_ptr_hash: fix double free for circular dependencies
If the hash table delete callback deletes the stored item,
we can end up in double free in case when we try to override
an existing item (hash_enter(key) where key already exists).
```c
static void delete_cb(hash_entry_t *item,
hash_destroy_enum deltype,
void *pvt)
{
talloc_free(item->value.ptr);
}
hash_enter(key);
hash_enter(key);
```
The doble free it self is fine, since it is done via talloc destructor
and talloc can cope with that. However, the hash table fails to store
the new entry because hash_delete is called twice.
```
_sss_ptr_hash_add -> hash_enter -> hash_delete(old) -> delete_cb -> sss_ptr_hash_value_destructor -> hash_delete
```
---
src/tests/cmocka/test_sss_ptr_hash.c | 39 ++++++++++++++++++++++++++++
src/tests/cmocka/test_utils.c | 3 +++
src/tests/cmocka/test_utils.h | 1 +
src/util/sss_ptr_hash.c | 20 ++++++++++++++
4 files changed, 63 insertions(+)
diff --git a/src/tests/cmocka/test_sss_ptr_hash.c b/src/tests/cmocka/test_sss_ptr_hash.c
index 1458238f537970d0ecde80bd36830b28970ca364..31cf8b705367498822094f8811b393c1b35e12bc 100644
--- a/src/tests/cmocka/test_sss_ptr_hash.c
+++ b/src/tests/cmocka/test_sss_ptr_hash.c
@@ -91,6 +91,45 @@ void test_sss_ptr_hash_with_free_cb(void **state)
assert_int_equal(free_counter, MAX_ENTRIES_AMOUNT*2);
}
+void test_sss_ptr_hash_overwrite_with_free_cb(void **state)
+{
+ hash_table_t *table;
+ int free_counter = 0;
+ unsigned long count;
+ char *payload;
+ char *value;
+ errno_t ret;
+
+ table = sss_ptr_hash_create(global_talloc_context,
+ free_payload_cb,
+ &free_counter);
+ assert_non_null(table);
+
+ payload = talloc_strdup(table, "test_value1");
+ assert_non_null(payload);
+ talloc_set_name_const(payload, "char");
+ ret = sss_ptr_hash_add_or_override(table, "test", payload, char);
+ assert_int_equal(ret, 0);
+ count = hash_count(table);
+ assert_int_equal(count, 1);
+ value = sss_ptr_hash_lookup(table, "test", char);
+ assert_ptr_equal(value, payload);
+
+
+ payload = talloc_strdup(table, "test_value2");
+ assert_non_null(payload);
+ talloc_set_name_const(payload, "char");
+ ret = sss_ptr_hash_add_or_override(table, "test", payload, char);
+ assert_int_equal(ret, 0);
+ count = hash_count(table);
+ assert_int_equal(count, 1);
+ value = sss_ptr_hash_lookup(table, "test", char);
+ assert_ptr_equal(value, payload);
+
+ talloc_free(table);
+ assert_int_equal(free_counter, 2);
+}
+
struct table_wrapper
{
hash_table_t **table;
diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c
index d77a972c1bc93638085c3d49131247fefb333d56..d258622fb50e849a3efabb123960db410eb399e1 100644
--- a/src/tests/cmocka/test_utils.c
+++ b/src/tests/cmocka/test_utils.c
@@ -2144,6 +2144,9 @@ int main(int argc, const char *argv[])
cmocka_unit_test_setup_teardown(test_sss_ptr_hash_with_free_cb,
setup_leak_tests,
teardown_leak_tests),
+ cmocka_unit_test_setup_teardown(test_sss_ptr_hash_overwrite_with_free_cb,
+ setup_leak_tests,
+ teardown_leak_tests),
cmocka_unit_test_setup_teardown(test_sss_ptr_hash_with_lookup_cb,
setup_leak_tests,
teardown_leak_tests),
diff --git a/src/tests/cmocka/test_utils.h b/src/tests/cmocka/test_utils.h
index 44b9479f965ee830ea0937c0fd89b87e35796598..458bcb750569c1f5f346917f29aa8b5500891988 100644
--- a/src/tests/cmocka/test_utils.h
+++ b/src/tests/cmocka/test_utils.h
@@ -35,6 +35,7 @@ void test_concatenate_string_array(void **state);
/* from src/tests/cmocka/test_sss_ptr_hash.c */
void test_sss_ptr_hash_with_free_cb(void **state);
+void test_sss_ptr_hash_overwrite_with_free_cb(void **state);
void test_sss_ptr_hash_with_lookup_cb(void **state);
void test_sss_ptr_hash_without_cb(void **state);
diff --git a/src/util/sss_ptr_hash.c b/src/util/sss_ptr_hash.c
index 6409236c782bac729ec51502019c04c83bce7cab..e3805dac4052b587d395b7163f5c45e1ba0aa6dc 100644
--- a/src/util/sss_ptr_hash.c
+++ b/src/util/sss_ptr_hash.c
@@ -54,6 +54,7 @@ struct sss_ptr_hash_value {
hash_table_t *table;
const char *key;
void *payload;
+ bool delete_in_progress;
};
static int
@@ -61,12 +62,22 @@ sss_ptr_hash_value_destructor(struct sss_ptr_hash_value *value)
{
hash_key_t table_key;
+ /* Do not call hash_delete() if we got here from hash delete callback when
+ * the callback calls talloc_free(payload) which frees the value. This
+ * should not happen since talloc will avoid circular free but let's be
+ * over protective here. */
+ if (value->delete_in_progress) {
+ return 0;
+ }
+
+ value->delete_in_progress = true;
if (value->table && value->key) {
table_key.type = HASH_KEY_STRING;
table_key.str = discard_const_p(char, value->key);
if (hash_delete(value->table, &table_key) != HASH_SUCCESS) {
DEBUG(SSSDBG_CRIT_FAILURE,
"failed to delete entry with key '%s'\n", value->key);
+ value->delete_in_progress = false;
}
}
@@ -127,6 +138,15 @@ sss_ptr_hash_delete_cb(hash_entry_t *item,
callback_entry.key = item->key;
callback_entry.value.type = HASH_VALUE_PTR;
callback_entry.value.ptr = value->payload;
+
+ /* Delete the value in case this callback has been called directly
+ * from dhash (overwriting existing entry) instead of hash_delete()
+ * in value's destructor. */
+ if (!value->delete_in_progress) {
+ talloc_set_destructor(value, NULL);
+ talloc_free(value);
+ }
+
/* Even if execution is already in the context of
* talloc_free(payload) -> talloc_free(value) -> ...
* there still might be legitimate reasons to execute callback.
--
2.25.4

View File

@ -1,551 +0,0 @@
From 9ffc2c6447f2177ff406a9f4d17d8413967ab7ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Mon, 19 Oct 2020 12:40:07 +0200
Subject: [PATCH 15/19] kcm: store credentials list in hash table to avoid
cache lookups
Iteration over ccache requires CRED_UUID_LIST and then calling
CRED_BY_UUID for each uuid in the obtained list. Each CRED_BY_UUID
operation invoked ldb_search and decryption. This was a substantional
bottle neck.
Resolves: https://github.com/SSSD/sssd/issues/5349
:fixes: KCM performance has improved dramatically for cases where
large amount of credentials are stored in the ccache.
---
src/responder/kcm/kcmsrv_ccache.c | 46 +++++
src/responder/kcm/kcmsrv_ccache.h | 7 +
src/responder/kcm/kcmsrv_ccache_mem.c | 30 ++--
src/responder/kcm/kcmsrv_ops.c | 245 +++++++++++++++++++-------
src/responder/kcm/kcmsrv_ops.h | 5 +-
5 files changed, 249 insertions(+), 84 deletions(-)
diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
index 59f8a7293fa7422c199ca2916c8e6ae6039d9312..60eacd4516b1269168caea744d91377686ab03f6 100644
--- a/src/responder/kcm/kcmsrv_ccache.c
+++ b/src/responder/kcm/kcmsrv_ccache.c
@@ -28,6 +28,9 @@
#include "responder/kcm/kcmsrv_ccache_pvt.h"
#include "responder/kcm/kcmsrv_ccache_be.h"
+static struct kcm_cred *kcm_cred_dup(TALLOC_CTX *mem_ctx,
+ struct kcm_cred *crd);
+
static int kcm_cc_destructor(struct kcm_ccache *cc)
{
if (cc == NULL) {
@@ -94,6 +97,33 @@ done:
return ret;
}
+struct kcm_ccache *kcm_cc_dup(TALLOC_CTX *mem_ctx,
+ const struct kcm_ccache *cc)
+{
+ struct kcm_ccache *dup;
+ struct kcm_cred *crd_dup;
+ struct kcm_cred *crd;
+
+ dup = talloc_zero(mem_ctx, struct kcm_ccache);
+ if (dup == NULL) {
+ return NULL;
+ }
+ memcpy(dup, cc, sizeof(struct kcm_ccache));
+
+ dup->creds = NULL;
+ DLIST_FOR_EACH(crd, cc->creds) {
+ crd_dup = kcm_cred_dup(dup, crd);
+ if (crd_dup == NULL) {
+ talloc_free(dup);
+ return NULL;
+ }
+
+ DLIST_ADD(dup->creds, crd_dup);
+ }
+
+ return dup;
+}
+
const char *kcm_cc_get_name(struct kcm_ccache *cc)
{
return cc ? cc->name : NULL;
@@ -204,6 +234,22 @@ struct kcm_cred *kcm_cred_new(TALLOC_CTX *mem_ctx,
return kcreds;
}
+static struct kcm_cred *kcm_cred_dup(TALLOC_CTX *mem_ctx,
+ struct kcm_cred *crd)
+{
+ struct kcm_cred *dup;
+
+ dup = talloc_zero(mem_ctx, struct kcm_cred);
+ if (dup == NULL) {
+ return NULL;
+ }
+
+ uuid_copy(dup->uuid, crd->uuid);
+ dup->cred_blob = crd->cred_blob;
+
+ return dup;
+}
+
/* Add a cred to ccache */
errno_t kcm_cc_store_creds(struct kcm_ccache *cc,
struct kcm_cred *crd)
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
index b0a7acb9fed8a8f89a3d0e2239ab28c7ce80fa23..77cf8f61d563d29afe00d8a04e8053b24547746d 100644
--- a/src/responder/kcm/kcmsrv_ccache.h
+++ b/src/responder/kcm/kcmsrv_ccache.h
@@ -72,6 +72,13 @@ errno_t kcm_cc_new(TALLOC_CTX *mem_ctx,
krb5_principal princ,
struct kcm_ccache **_cc);
+/*
+ * Duplicate the ccache. Only ccache and credentials are duplicated,
+ * but their data are a shallow copy.
+ */
+struct kcm_ccache *kcm_cc_dup(TALLOC_CTX *mem_ctx,
+ const struct kcm_ccache *cc);
+
/*
* Returns true if a client can access a ccache.
*
diff --git a/src/responder/kcm/kcmsrv_ccache_mem.c b/src/responder/kcm/kcmsrv_ccache_mem.c
index baa698054fa4c6952b41b0f25dfdfa825f8e675b..0e3a7b239eda83c9fdec3b116231d4ec1444ef10 100644
--- a/src/responder/kcm/kcmsrv_ccache_mem.c
+++ b/src/responder/kcm/kcmsrv_ccache_mem.c
@@ -49,24 +49,6 @@ struct ccdb_mem {
unsigned int nextid;
};
-/* In order to provide a consistent interface, we need to let the caller
- * of getbyXXX own the ccache, therefore the memory back end returns a shallow
- * copy of the ccache
- */
-static struct kcm_ccache *kcm_ccache_dup(TALLOC_CTX *mem_ctx,
- struct kcm_ccache *in)
-{
- struct kcm_ccache *out;
-
- out = talloc_zero(mem_ctx, struct kcm_ccache);
- if (out == NULL) {
- return NULL;
- }
- memcpy(out, in, sizeof(struct kcm_ccache));
-
- return out;
-}
-
static struct ccache_mem_wrap *memdb_get_by_uuid(struct ccdb_mem *memdb,
struct cli_creds *client,
uuid_t uuid)
@@ -417,7 +399,11 @@ static struct tevent_req *ccdb_mem_getbyuuid_send(TALLOC_CTX *mem_ctx,
ccwrap = memdb_get_by_uuid(memdb, client, uuid);
if (ccwrap != NULL) {
- state->cc = kcm_ccache_dup(state, ccwrap->cc);
+ /* In order to provide a consistent interface, we need to let the caller
+ * of getbyXXX own the ccache, therefore the memory back end returns a shallow
+ * copy of the ccache
+ */
+ state->cc = kcm_cc_dup(state, ccwrap->cc);
if (state->cc == NULL) {
ret = ENOMEM;
goto immediate;
@@ -470,7 +456,11 @@ static struct tevent_req *ccdb_mem_getbyname_send(TALLOC_CTX *mem_ctx,
ccwrap = memdb_get_by_name(memdb, client, name);
if (ccwrap != NULL) {
- state->cc = kcm_ccache_dup(state, ccwrap->cc);
+ /* In order to provide a consistent interface, we need to let the caller
+ * of getbyXXX own the ccache, therefore the memory back end returns a shallow
+ * copy of the ccache
+ */
+ state->cc = kcm_cc_dup(state, ccwrap->cc);
if (state->cc == NULL) {
ret = ENOMEM;
goto immediate;
diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c
index 6ae1f0c647f4d385477ddeadbad93287cba05c55..f458c724b0eaa3d43df4ad30baa3f896b8d87965 100644
--- a/src/responder/kcm/kcmsrv_ops.c
+++ b/src/responder/kcm/kcmsrv_ops.c
@@ -22,9 +22,11 @@
#include "config.h"
#include <krb5/krb5.h>
+#include <dhash.h>
#include "util/sss_iobuf.h"
#include "util/sss_krb5.h"
+#include "util/sss_ptr_hash.h"
#include "util/util_creds.h"
#include "responder/kcm/kcm.h"
#include "responder/kcm/kcmsrv_pvt.h"
@@ -1074,6 +1076,73 @@ static void kcm_op_get_principal_getbyname_done(struct tevent_req *subreq)
tevent_req_done(req);
}
+static void
+kcm_creds_table_delete_cb(hash_entry_t *item,
+ hash_destroy_enum deltype,
+ void *pvt)
+{
+ /* Delete the old credential if it is being overwritten. */
+ talloc_free(item->value.ptr);
+}
+
+/* Store credentials in a hash table.
+ *
+ * If the table already exist we add the new credentials to the table and
+ * overwrite the ones that already exist. This allows us to correctly serve
+ * also parallel GET_CRED_UUID_LIST requests from the same connection since
+ * it will have its own uuid list and cursor on the client side and we make
+ * all uuid (old, updated and newly added) available.
+ */
+static errno_t
+kcm_creds_to_table(TALLOC_CTX *mem_ctx,
+ struct kcm_cred *creds,
+ hash_table_t **_table)
+{
+ char str[UUID_STR_SIZE];
+ uuid_t uuid;
+ errno_t ret;
+
+ if (*_table == NULL) {
+ *_table = sss_ptr_hash_create(mem_ctx, kcm_creds_table_delete_cb, NULL);
+ if (*_table == NULL) {
+ return ENOMEM;
+ }
+ }
+
+ for (struct kcm_cred *crd = creds;
+ crd != NULL;
+ crd = kcm_cc_next_cred(crd)) {
+ ret = kcm_cred_get_uuid(crd, uuid);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Credential has no UUID, skipping\n");
+ continue;
+ }
+ uuid_unparse(uuid, str);
+
+ ret = sss_ptr_hash_add_or_override(*_table, str, crd, struct kcm_cred);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ talloc_steal(*_table, crd);
+ }
+
+ return EOK;
+}
+
+static struct kcm_cred *
+kcm_creds_lookup(hash_table_t *table, uuid_t uuid)
+{
+ char str[UUID_STR_SIZE];
+
+ if (uuid == NULL) {
+ return NULL;
+ }
+
+ uuid_unparse(uuid, str);
+ return sss_ptr_hash_lookup(table, str, struct kcm_cred);
+}
+
/* (name) -> (uuid, ...) */
static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq);
@@ -1123,12 +1192,15 @@ static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq)
errno_t ret;
struct kcm_ccache *cc;
struct kcm_cred *crd;
+ struct kcm_conn_data *conn_data;
uuid_t uuid;
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct kcm_op_common_state *state = tevent_req_data(req,
struct kcm_op_common_state);
+ conn_data = state->op_ctx->conn_data;
+
ret = kcm_ccdb_getbyname_recv(subreq, state, &cc);
talloc_zfree(subreq);
if (ret != EOK) {
@@ -1140,12 +1212,20 @@ static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq)
}
if (cc == NULL) {
- DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
+ DEBUG(SSSDBG_MINOR_FAILURE, "No ccache by that name\n");
state->op_ret = ERR_NO_CREDS;
tevent_req_done(req);
return;
}
+ ret = kcm_creds_to_table(conn_data, kcm_cc_get_cred(cc), &conn_data->creds);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to build credentials hash table "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ tevent_req_error(req, ret);
+ return;
+ }
+
for (crd = kcm_cc_get_cred(cc);
crd != NULL;
crd = kcm_cc_next_cred(crd)) {
@@ -1172,6 +1252,34 @@ static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq)
tevent_req_done(req);
}
+static errno_t
+kcm_op_get_cred_by_uuid_reply(struct kcm_cred *crd,
+ struct sss_iobuf *reply)
+{
+ struct sss_iobuf *cred_blob;
+ errno_t ret;
+
+ cred_blob = kcm_cred_get_creds(crd);
+ if (cred_blob == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Credentials lack the creds blob\n");
+ return ERR_NO_CREDS;
+ }
+
+ ret = sss_iobuf_write_len(reply, sss_iobuf_get_data(cred_blob),
+ sss_iobuf_get_size(cred_blob));
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot write ccache blob [%d]: %s\n",
+ ret, sss_strerror(ret));
+ }
+
+ return ret;
+}
+
+struct kcm_op_get_cred_by_uuid_state {
+ struct kcm_op_common_state common;
+ uuid_t uuid;
+};
+
/* (name, uuid) -> (cred) */
static void kcm_op_get_cred_by_uuid_getbyname_done(struct tevent_req *subreq);
@@ -1182,20 +1290,51 @@ kcm_op_get_cred_by_uuid_send(TALLOC_CTX *mem_ctx,
{
struct tevent_req *req = NULL;
struct tevent_req *subreq = NULL;
- struct kcm_op_common_state *state = NULL;
+ struct kcm_op_get_cred_by_uuid_state *state;
+ struct kcm_cred *crd;
errno_t ret;
const char *name;
- req = tevent_req_create(mem_ctx, &state, struct kcm_op_common_state);
+ req = tevent_req_create(mem_ctx, &state,
+ struct kcm_op_get_cred_by_uuid_state);
if (req == NULL) {
return NULL;
}
- state->op_ctx = op_ctx;
+ state->common.op_ctx = op_ctx;
ret = sss_iobuf_read_stringz(op_ctx->input, &name);
if (ret != EOK) {
goto immediate;
}
+
+ ret = sss_iobuf_read_len(state->common.op_ctx->input, UUID_BYTES,
+ state->uuid);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot read input UUID [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto immediate;
+ }
+
+ if (op_ctx->conn_data->creds != NULL) {
+ crd = kcm_creds_lookup(op_ctx->conn_data->creds, state->uuid);
+ if (crd == NULL) {
+ /* This should not happen, it can only happen if wrong UUID was
+ * requested which suggests bug in the caller application. */
+ DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
+ kcm_debug_uuid(state->uuid);
+ state->common.op_ret = ERR_KCM_CC_END;
+ ret = EOK;
+ goto immediate;
+ } else {
+ ret = kcm_op_get_cred_by_uuid_reply(crd, op_ctx->reply);
+ if (ret == ERR_NO_CREDS) {
+ state->common.op_ret = ret;
+ ret = EOK;
+ }
+ goto immediate;
+ }
+ }
+
DEBUG(SSSDBG_TRACE_LIBS, "Returning creds by UUID for %s\n", name);
subreq = kcm_ccdb_getbyname_send(state, ev,
@@ -1210,7 +1349,11 @@ kcm_op_get_cred_by_uuid_send(TALLOC_CTX *mem_ctx,
return req;
immediate:
- tevent_req_error(req, ret);
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
tevent_req_post(req, ev);
return req;
}
@@ -1219,14 +1362,14 @@ static void kcm_op_get_cred_by_uuid_getbyname_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
- struct kcm_op_common_state *state = tevent_req_data(req,
- struct kcm_op_common_state);
+ struct kcm_op_get_cred_by_uuid_state *state = tevent_req_data(req,
+ struct kcm_op_get_cred_by_uuid_state);
errno_t ret;
struct kcm_ccache *cc;
struct kcm_cred *crd;
- uuid_t uuid_in;
- uuid_t uuid;
- struct sss_iobuf *cred_blob;
+ struct kcm_conn_data *conn_data;
+
+ conn_data = state->common.op_ctx->conn_data;
ret = kcm_ccdb_getbyname_recv(subreq, state, &cc);
talloc_zfree(subreq);
@@ -1238,69 +1381,45 @@ static void kcm_op_get_cred_by_uuid_getbyname_done(struct tevent_req *subreq)
return;
}
- if (cc == NULL) {
- DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that name\n");
- state->op_ret = ERR_NO_MATCHING_CREDS;
- tevent_req_done(req);
- return;
- }
-
- ret = sss_iobuf_read_len(state->op_ctx->input,
- UUID_BYTES, uuid_in);
+ ret = kcm_creds_to_table(conn_data, kcm_cc_get_cred(cc), &conn_data->creds);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Cannot read input UUID [%d]: %s\n",
- ret, sss_strerror(ret));
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to build credentials hash table "
+ "[%d]: %s\n", ret, sss_strerror(ret));
tevent_req_error(req, ret);
return;
}
- for (crd = kcm_cc_get_cred(cc);
- crd != NULL;
- crd = kcm_cc_next_cred(crd)) {
- ret = kcm_cred_get_uuid(crd, uuid);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- "Cannot get UUID from creds, skipping\n");
- continue;
- }
-
- if (uuid_compare(uuid, uuid_in) == 0) {
- break;
+ if (conn_data->creds != NULL) {
+ crd = kcm_creds_lookup(conn_data->creds, state->uuid);
+ if (crd == NULL) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
+ kcm_debug_uuid(state->uuid);
+ state->common.op_ret = ERR_KCM_CC_END;
+ } else {
+ ret = kcm_op_get_cred_by_uuid_reply(crd, state->common.op_ctx->reply);
+ if (ret != EOK && ret != ERR_NO_CREDS) {
+ tevent_req_error(req, ret);
+ return;
+ }
+ state->common.op_ret = ret;
}
- kcm_debug_uuid(uuid);
- }
-
- if (crd == NULL) {
- state->op_ret = ERR_KCM_CC_END;
- DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
- tevent_req_done(req);
- return;
- }
-
- cred_blob = kcm_cred_get_creds(crd);
- if (cred_blob == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Credentials lack the creds blob\n");
- state->op_ret = ERR_NO_CREDS;
- tevent_req_done(req);
- return;
- }
-
- ret = sss_iobuf_write_len(state->op_ctx->reply,
- sss_iobuf_get_data(cred_blob),
- sss_iobuf_get_size(cred_blob));
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Cannot write ccache blob [%d]: %s\n",
- ret, sss_strerror(ret));
- tevent_req_error(req, ret);
- return;
}
- state->op_ret = EOK;
tevent_req_done(req);
}
+static errno_t kcm_op_get_cred_by_uuid_recv(struct tevent_req *req,
+ uint32_t *_op_ret)
+{
+ struct kcm_op_get_cred_by_uuid_state *state;
+
+ state = tevent_req_data(req, struct kcm_op_get_cred_by_uuid_state);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+ *_op_ret = state->common.op_ret;
+ return EOK;
+}
+
/* (name, flags, credtag) -> () */
/* FIXME */
static struct tevent_req *
@@ -2156,7 +2275,7 @@ static struct kcm_op kcm_optable[] = {
{ "RETRIEVE", NULL, NULL },
{ "GET_PRINCIPAL", kcm_op_get_principal_send, NULL },
{ "GET_CRED_UUID_LIST", kcm_op_get_cred_uuid_list_send, NULL },
- { "GET_CRED_BY_UUID", kcm_op_get_cred_by_uuid_send, NULL },
+ { "GET_CRED_BY_UUID", kcm_op_get_cred_by_uuid_send, kcm_op_get_cred_by_uuid_recv },
{ "REMOVE_CRED", kcm_op_remove_cred_send, NULL },
{ "SET_FLAGS", NULL, NULL },
{ "CHOWN", NULL, NULL },
diff --git a/src/responder/kcm/kcmsrv_ops.h b/src/responder/kcm/kcmsrv_ops.h
index fd2dd03c9da3660e0c1346752e4db59c7cbe2c41..ab6c13791baa43837cf84ebd523735b622a24020 100644
--- a/src/responder/kcm/kcmsrv_ops.h
+++ b/src/responder/kcm/kcmsrv_ops.h
@@ -24,6 +24,7 @@
#include "config.h"
+#include <dhash.h>
#include <sys/types.h>
#include "util/sss_iobuf.h"
#include "responder/kcm/kcmsrv_pvt.h"
@@ -33,7 +34,9 @@ struct kcm_op *kcm_get_opt(uint16_t opcode);
const char *kcm_opt_name(struct kcm_op *op);
struct kcm_conn_data {
- void *data;
+ /* Credentials obtained by GET_CRED_UUID_LIST. We use to improve performance
+ * by avoiding ccache lookups in GET_CRED_BY_UUID. */
+ hash_table_t *creds;
};
struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
--
2.25.4

View File

@ -1,38 +0,0 @@
From 24a6888e38fb9d11bf173eb06e400678388bce49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 3 Nov 2020 13:35:33 +0100
Subject: [PATCH 16/19] secrets: fix may_payload_size exceeded debug message
The unit is bytes (B) not bits (b) and the conversion of the input
payload size to KiB was wrong (multiplying bytes * 1024).
---
src/util/secrets/secrets.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
index 6fd9e0af5bd9986052efdb8e244ddeb9e4fa50ff..1000757228bea75bb2d5c48aceb717c9bfe35ffb 100644
--- a/src/util/secrets/secrets.c
+++ b/src/util/secrets/secrets.c
@@ -399,14 +399,14 @@ static int local_check_max_payload_size(struct sss_sec_req *req,
return EOK;
}
- max_payload_size = req->quota->max_payload_size * 1024; /* kb */
+ max_payload_size = req->quota->max_payload_size * 1024; /* KiB */
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 */
+ "Secrets' payload size [%d KiB (%d B)] exceeds the maximum "
+ "allowed payload size [%d KiB (%d B)]\n",
+ payload_size / 1024, /* KiB */
payload_size,
- req->quota->max_payload_size, /* kb */
+ req->quota->max_payload_size, /* KiB */
max_payload_size);
return ERR_SEC_PAYLOAD_SIZE_IS_TOO_LARGE;
--
2.25.4

View File

@ -1,43 +0,0 @@
From 36e4dc6c9a48ee62345839a9df14e0494c99bf59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 26 Nov 2020 11:47:24 +0100
Subject: [PATCH 17/19] secrets: default to "plaintext" if "enctype" attr is
missing
This is a sane fallback behavior, however it should not happen since
the attribute should be always present.
---
src/util/secrets/secrets.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
index 1000757228bea75bb2d5c48aceb717c9bfe35ffb..58c96e18f03865df0249c4c899ad88e385b782c8 100644
--- a/src/util/secrets/secrets.c
+++ b/src/util/secrets/secrets.c
@@ -1071,17 +1071,12 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
goto done;
}
- attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], "enctype", NULL);
-
- if (attr_enctype) {
- enctype = sss_sec_str_to_enctype(attr_enctype);
- ret = local_decrypt(req->sctx, tmp_ctx, attr_secret->data,
- attr_secret->length, enctype, &secret, &secret_len);
- if (ret) goto done;
- } else {
- secret = talloc_steal(tmp_ctx, attr_secret->data);
- secret_len = attr_secret->length;
- }
+ attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], "enctype",
+ "plaintext");
+ enctype = sss_sec_str_to_enctype(attr_enctype);
+ ret = local_decrypt(req->sctx, tmp_ctx, attr_secret->data,
+ attr_secret->length, enctype, &secret, &secret_len);
+ if (ret) goto done;
if (_datatype != NULL) {
attr_datatype = ldb_msg_find_attr_as_string(res->msgs[0], "type",
--
2.25.4

View File

@ -1,183 +0,0 @@
From b18f0f87948d44f1d99dd4da0ac1affcbb8c53e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 26 Nov 2020 11:55:39 +0100
Subject: [PATCH 18/19] secrets: move attrs names to macros
---
src/util/secrets/secrets.c | 42 +++++++++++++++++++++++---------------
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
index 58c96e18f03865df0249c4c899ad88e385b782c8..ae9c7c83f335c8c2d9d97a736700fbcdaf0d36af 100644
--- a/src/util/secrets/secrets.c
+++ b/src/util/secrets/secrets.c
@@ -39,6 +39,11 @@
#define LOCAL_SIMPLE_FILTER "(|(type=simple)(type=binary))"
#define LOCAL_CONTAINER_FILTER "(type=container)"
+#define SEC_ATTR_SECRET "secret"
+#define SEC_ATTR_ENCTYPE "enctype"
+#define SEC_ATTR_TYPE "type"
+#define SEC_ATTR_CTIME "creationTime"
+
typedef int (*url_mapper_fn)(TALLOC_CTX *mem_ctx,
const char *url,
uid_t client,
@@ -465,7 +470,7 @@ static int local_db_create(struct sss_sec_req *req)
ret = local_db_check_containers_nest_level(req, msg->dn);
if (ret != EOK) goto done;
- ret = ldb_msg_add_string(msg, "type", "container");
+ ret = ldb_msg_add_string(msg, SEC_ATTR_TYPE, "container");
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"ldb_msg_add_string failed adding type:container [%d]: %s\n",
@@ -473,7 +478,7 @@ static int local_db_create(struct sss_sec_req *req)
goto done;
}
- ret = ldb_msg_add_fmt(msg, "creationTime", "%lu", time(NULL));
+ ret = ldb_msg_add_fmt(msg, SEC_ATTR_CTIME, "%lu", time(NULL));
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"ldb_msg_add_string failed adding creationTime [%d]: %s\n",
@@ -953,7 +958,7 @@ errno_t sss_sec_list(TALLOC_CTX *mem_ctx,
size_t *_num_keys)
{
TALLOC_CTX *tmp_ctx;
- static const char *attrs[] = { "secret", NULL };
+ static const char *attrs[] = { SEC_ATTR_SECRET, NULL };
struct ldb_result *res;
char **keys;
int ret;
@@ -1017,7 +1022,8 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
char **_datatype)
{
TALLOC_CTX *tmp_ctx;
- static const char *attrs[] = { "secret", "enctype", "type", NULL };
+ static const char *attrs[] = { SEC_ATTR_SECRET, SEC_ATTR_ENCTYPE,
+ SEC_ATTR_TYPE, NULL };
struct ldb_result *res;
const struct ldb_val *attr_secret;
const char *attr_enctype;
@@ -1064,14 +1070,14 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
goto done;
}
- attr_secret = ldb_msg_find_ldb_val(res->msgs[0], "secret");
+ attr_secret = ldb_msg_find_ldb_val(res->msgs[0], SEC_ATTR_SECRET);
if (!attr_secret) {
DEBUG(SSSDBG_CRIT_FAILURE, "The 'secret' attribute is missing\n");
ret = ENOENT;
goto done;
}
- attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], "enctype",
+ attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], SEC_ATTR_ENCTYPE,
"plaintext");
enctype = sss_sec_str_to_enctype(attr_enctype);
ret = local_decrypt(req->sctx, tmp_ctx, attr_secret->data,
@@ -1079,7 +1085,7 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
if (ret) goto done;
if (_datatype != NULL) {
- attr_datatype = ldb_msg_find_attr_as_string(res->msgs[0], "type",
+ attr_datatype = ldb_msg_find_attr_as_string(res->msgs[0], SEC_ATTR_TYPE,
"simple");
datatype = talloc_strdup(tmp_ctx, attr_datatype);
if (datatype == NULL) {
@@ -1167,7 +1173,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_string(msg, "type", datatype);
+ ret = ldb_msg_add_string(msg, SEC_ATTR_TYPE, datatype);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"ldb_msg_add_string failed adding type:%s [%d]: %s\n",
@@ -1175,7 +1181,8 @@ errno_t sss_sec_put(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_string(msg, "enctype", sss_sec_enctype_to_str(enctype));
+ ret = ldb_msg_add_string(msg, SEC_ATTR_ENCTYPE,
+ sss_sec_enctype_to_str(enctype));
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"ldb_msg_add_string failed adding enctype [%d]: %s\n",
@@ -1183,7 +1190,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_value(msg, "secret", &enc_secret, NULL);
+ ret = ldb_msg_add_value(msg, SEC_ATTR_SECRET, &enc_secret, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"ldb_msg_add_string failed adding secret [%d]: %s\n",
@@ -1191,7 +1198,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_fmt(msg, "creationTime", "%lu", time(NULL));
+ ret = ldb_msg_add_fmt(msg, SEC_ATTR_CTIME, "%lu", time(NULL));
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"ldb_msg_add_string failed adding creationTime [%d]: %s\n",
@@ -1283,7 +1290,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_empty(msg, "enctype", LDB_FLAG_MOD_REPLACE, NULL);
+ ret = ldb_msg_add_empty(msg, SEC_ATTR_ENCTYPE, LDB_FLAG_MOD_REPLACE, NULL);
if (ret != LDB_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
"ldb_msg_add_empty failed: [%s]\n", ldb_strerror(ret));
@@ -1291,7 +1298,8 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_string(msg, "enctype", sss_sec_enctype_to_str(enctype));
+ ret = ldb_msg_add_string(msg, SEC_ATTR_ENCTYPE,
+ sss_sec_enctype_to_str(enctype));
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"ldb_msg_add_string failed adding enctype [%d]: %s\n",
@@ -1299,7 +1307,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_empty(msg, "type", LDB_FLAG_MOD_REPLACE, NULL);
+ ret = ldb_msg_add_empty(msg, SEC_ATTR_TYPE, LDB_FLAG_MOD_REPLACE, NULL);
if (ret != LDB_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
"ldb_msg_add_empty failed: [%s]\n", ldb_strerror(ret));
@@ -1307,7 +1315,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_string(msg, "type", datatype);
+ ret = ldb_msg_add_string(msg, SEC_ATTR_TYPE, datatype);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"ldb_msg_add_string failed adding type:%s [%d]: %s\n",
@@ -1316,7 +1324,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
}
/* FIXME - should we have a lastUpdate timestamp? */
- ret = ldb_msg_add_empty(msg, "secret", LDB_FLAG_MOD_REPLACE, NULL);
+ ret = ldb_msg_add_empty(msg, SEC_ATTR_SECRET, LDB_FLAG_MOD_REPLACE, NULL);
if (ret != LDB_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
"ldb_msg_add_empty failed: [%s]\n", ldb_strerror(ret));
@@ -1324,7 +1332,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
- ret = ldb_msg_add_value(msg, "secret", &enc_secret, NULL);
+ ret = ldb_msg_add_value(msg, SEC_ATTR_SECRET, &enc_secret, NULL);
if (ret != LDB_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
"ldb_msg_add_string failed: [%s]\n", ldb_strerror(ret));
--
2.25.4

View File

@ -1,75 +0,0 @@
From bca694200748354c7ee3e51084586d30b9b0164b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 26 Nov 2020 12:07:06 +0100
Subject: [PATCH 19/19] secrets: remove base64 enctype
This was added as part of KCM performance improvements but never used.
Ldb is fully capable of holding binary data without the need for base64
encoding so this is not needed.
---
src/util/secrets/secrets.c | 15 ---------------
src/util/secrets/secrets.h | 1 -
2 files changed, 16 deletions(-)
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
index ae9c7c83f335c8c2d9d97a736700fbcdaf0d36af..c6310b58526d6f4c063d028cd0e78b5e4f2e12db 100644
--- a/src/util/secrets/secrets.c
+++ b/src/util/secrets/secrets.c
@@ -75,8 +75,6 @@ static const char *sss_sec_enctype_to_str(enum sss_sec_enctype enctype)
return "plaintext";
case SSS_SEC_MASTERKEY:
return "masterkey";
- case SSS_SEC_BASE64:
- return "base64";
default:
DEBUG(SSSDBG_CRIT_FAILURE, "Bug: unknown encryption type %d\n",
enctype);
@@ -94,10 +92,6 @@ static enum sss_sec_enctype sss_sec_str_to_enctype(const char *str)
return SSS_SEC_MASTERKEY;
}
- if (strcmp("base64", str) == 0) {
- return SSS_SEC_BASE64;
- }
-
return SSS_SEC_ENCTYPE_SENTINEL;
}
@@ -141,10 +135,6 @@ static int local_decrypt(struct sss_sec_ctx *sctx,
return ret;
}
break;
- case SSS_SEC_BASE64:
- output = (uint8_t *)sss_base64_decode(mem_ctx, (const char *)secret,
- &output_len);
- break;
default:
DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
return EINVAL;
@@ -196,11 +186,6 @@ static int local_encrypt(struct sss_sec_ctx *sec_ctx,
output_len = strlen(b64) + 1;
talloc_free(_secret.data);
break;
- case SSS_SEC_BASE64:
- b64 = sss_base64_encode(mem_ctx, secret, secret_len);
- output = (uint8_t*)b64;
- output_len = strlen(b64) + 1;
- break;
default:
DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
return EINVAL;
diff --git a/src/util/secrets/secrets.h b/src/util/secrets/secrets.h
index f8caa53eec376bb0c8d52615ce9111efbbb26393..f79bfaa4b9dc2df577a815c03b86770e3066de75 100644
--- a/src/util/secrets/secrets.h
+++ b/src/util/secrets/secrets.h
@@ -46,7 +46,6 @@
enum sss_sec_enctype {
SSS_SEC_PLAINTEXT,
SSS_SEC_MASTERKEY,
- SSS_SEC_BASE64,
SSS_SEC_ENCTYPE_SENTINEL
};
--
2.25.4

View File

@ -1,43 +0,0 @@
From 18b98836ef8e337992f0ecb239a32b9c3cedb750 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 9 Dec 2020 14:07:22 +0100
Subject: [PATCH] kcm: decode base64 encoded secret on upgrade path
Previous unefficient code encoded the secret multiple times:
secret -> base64 -> masterkey -> base64
To allow smooth upgrade for already existant ccache we need to also decode
the secret if it is still in the old format (type == simple). Otherwise
users are not able to log in.
Resolves: https://github.com/SSSD/sssd/issues/5349
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
---
src/responder/kcm/kcmsrv_ccache_secdb.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
index 726711ac441c40a6bfc84045e9b3e5b85505c7e0..ea5c8f9ee36ddc6008ea80693d3e28c4de5a00c1 100644
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
@@ -59,6 +59,16 @@ static errno_t sec_get(TALLOC_CTX *mem_ctx,
goto done;
}
+ if (strcmp(datatype, "simple") == 0) {
+ /* The secret is stored in b64 encoding, we need to decode it first. */
+ data = sss_base64_decode(tmp_ctx, (const char*)data, &len);
+ if (data == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot decode secret from base64\n");
+ ret = EIO;
+ goto done;
+ }
+ }
+
buf = sss_iobuf_init_steal(tmp_ctx, data, len);
if (buf == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init the iobuf\n");
--
2.25.4

View File

@ -1 +1 @@
SHA512 (sssd-2.4.0.tar.gz) = d9a4b17665ce3a1ea51cfe2fdb53818ac1e265a33c61f657f61699ecc716e1244e45b5b628aeae6c54e601383084f3cac327cb3edd7bea80bca397b1fbe4ab72
SHA512 (sssd-2.4.1.tar.gz) = 27b53585c43ee8387fda85afd894bcbd2aa037e8b7e05ffb68a17232fcc6a8b4aaf5f83eda65b91f656de3f040372ddfa49d0a905ff37b1064b6e22544025669

349
sssd.spec
View File

@ -1,76 +1,47 @@
%global rhel7_minor %(%{__grep} -o "7.[0-9]*" /etc/redhat-release |%{__sed} -s 's/7.//')
# SSSD SPEC file for Fedora 34+ and RHEL-9+
# define SSSD user
%if 0%{?rhel}
%global sssd_user sssd
%else
%global sssd_user root
%endif
# we don't want to provide private python extension libs
%define __provides_exclude_from %{python3_sitearch}/.*\.so$
# SSSD fails to build with -Wl,-z,defs
%undefine _strict_symbol_defs_build
%define _hardened_build 1
%global enable_polkit_rules_option --disable-polkit-rules-path
# Determine the location of the LDB modules directory
%global ldb_modulesdir %(pkg-config --variable=modulesdir ldb)
%global ldb_version 1.2.0
%global with_cifs_utils_plugin 1
%global enable_systemtap 1
%global enable_systemtap_opt --enable-systemtap
%global with_kcm 1
%global with_gdm_pam_extensions 1
%if (0%{?fedora} > 28) || (0%{?rhel} > 7)
%global use_openssl 1
%endif
%global samba_package_version %(rpm -q samba-devel --queryformat %{version}-%{release})
Name: sssd
Version: 2.4.0
Release: 6%{?dist}
Version: 2.4.1
Release: 1%{?dist}
Summary: System Security Services Daemon
License: GPLv3+
URL: https://github.com/SSSD/sssd/
Source0: https://github.com/SSSD/sssd/releases/download/sssd-2_4_0/sssd-2.4.0.tar.gz
Source0: https://github.com/SSSD/sssd/releases/download/2.4.1/sssd-2.4.1.tar.gz
### Patches ###
Patch0001: 0001-kcm-fix-typos-in-debug-messages.patch
Patch0002: 0002-kcm-avoid-name-confusion-in-GET_CRED_UUID_LIST-handl.patch
Patch0003: 0003-kcm-disable-encryption.patch
Patch0004: 0004-kcm-avoid-multiple-debug-messages-if-sss_sec_put-fai.patch
Patch0005: 0005-secrets-allow-to-specify-secret-s-data-format.patch
Patch0006: 0006-secrets-accept-binary-data-instead-of-string.patch
Patch0007: 0007-iobuf-add-more-iobuf-functions.patch
Patch0008: 0008-kcm-add-json-suffix-to-existing-searialization-funct.patch
Patch0009: 0009-kcm-move-sec-key-parser-to-separate-file-so-it-can-b.patch
Patch0010: 0010-kcm-avoid-suppression-of-cppcheck-warning.patch
Patch0011: 0011-kcm-add-spaces-around-operators-in-kcmsrv_ccache_key.patch
Patch0012: 0012-kcm-use-binary-format-to-store-ccache-instead-of-jso.patch
Patch0013: 0013-kcm-add-per-connection-data-to-be-shared-between-req.patch
Patch0014: 0014-sss_ptr_hash-fix-double-free-for-circular-dependenci.patch
Patch0015: 0015-kcm-store-credentials-list-in-hash-table-to-avoid-ca.patch
Patch0016: 0016-secrets-fix-may_payload_size-exceeded-debug-message.patch
Patch0017: 0017-secrets-default-to-plaintext-if-enctype-attr-is-miss.patch
Patch0018: 0018-secrets-move-attrs-names-to-macros.patch
Patch0019: 0019-secrets-remove-base64-enctype.patch
Patch0020: 0020-kcm-decode-base64-encoded-secret-on-upgrade-path.patch
Patch0001: 0001-BUILD-fixes-gpo_child-linking-issue.patch
### Downstream only patches ###
Patch0502: 0502-SYSTEMD-Use-capabilities.patch
### Dependencies ###
Requires: sssd-common = %{version}-%{release}
Requires: sssd-ldap = %{version}-%{release}
Requires: sssd-krb5 = %{version}-%{release}
Requires: sssd-ipa = %{version}-%{release}
Requires: python3-sssdconfig = %{version}-%{release}
Requires: sssd-ad = %{version}-%{release}
Requires: sssd-common = %{version}-%{release}
Requires: sssd-ipa = %{version}-%{release}
Requires: sssd-krb5 = %{version}-%{release}
Requires: sssd-ldap = %{version}-%{release}
Recommends: sssd-proxy = %{version}-%{release}
Suggests: python3-sssdconfig = %{version}-%{release}
Recommends: logrotate
Suggests: sssd-dbus = %{version}-%{release}
%global servicename sssd
@ -86,89 +57,77 @@ Suggests: sssd-dbus = %{version}-%{release}
### Build Dependencies ###
BuildRequires: make
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: libtool
BuildRequires: m4
BuildRequires: gcc
BuildRequires: popt-devel
BuildRequires: libtalloc-devel
BuildRequires: libtevent-devel
BuildRequires: libtdb-devel
BuildRequires: libldb-devel >= %{ldb_version}
BuildRequires: libdhash-devel >= 0.4.2
BuildRequires: libcollection-devel
BuildRequires: libini_config-devel >= 1.1
BuildRequires: dbus-devel
BuildRequires: dbus-libs
BuildRequires: openldap-devel
BuildRequires: pam-devel
BuildRequires: nss-devel
BuildRequires: nspr-devel
BuildRequires: pcre-devel
BuildRequires: libxslt
BuildRequires: libxml2
BuildRequires: docbook-style-xsl
BuildRequires: krb5-devel
BuildRequires: bind-utils
BuildRequires: c-ares-devel
BuildRequires: python3-devel
BuildRequires: check-devel
BuildRequires: cifs-utils-devel
BuildRequires: dbus-devel
BuildRequires: docbook-style-xsl
BuildRequires: doxygen
BuildRequires: findutils
BuildRequires: gcc
BuildRequires: gdm-pam-extensions-devel
BuildRequires: gettext-devel
BuildRequires: glib2-devel
# required for p11_child smartcard tests
BuildRequires: gnutls-utils
BuildRequires: jansson-devel
BuildRequires: keyutils-libs-devel
BuildRequires: krb5-devel
BuildRequires: libcmocka-devel >= 1.0.0
BuildRequires: libdhash-devel >= 0.4.2
BuildRequires: libini_config-devel >= 1.1
BuildRequires: libldb-devel >= %{ldb_version}
BuildRequires: libnfsidmap-devel
BuildRequires: libnl3-devel
BuildRequires: libselinux-devel
BuildRequires: libsemanage-devel
BuildRequires: bind-utils
BuildRequires: keyutils-libs-devel
BuildRequires: gettext-devel
BuildRequires: pkgconfig
BuildRequires: diffstat
BuildRequires: findutils
BuildRequires: glib2-devel
BuildRequires: selinux-policy-targeted
BuildRequires: libcmocka-devel >= 1.0.0
BuildRequires: uid_wrapper
BuildRequires: nss_wrapper
BuildRequires: pam_wrapper
BuildRequires: libnl3-devel
BuildRequires: systemd-devel
BuildRequires: systemd
BuildRequires: cifs-utils-devel
BuildRequires: libnfsidmap-devel
BuildRequires: samba4-devel
BuildRequires: libsmbclient-devel
BuildRequires: samba-winbind
BuildRequires: systemtap-sdt-devel
BuildRequires: http-parser-devel
BuildRequires: libtalloc-devel
BuildRequires: libtdb-devel
BuildRequires: libtevent-devel
BuildRequires: libtool
BuildRequires: libuuid-devel
BuildRequires: jansson-devel
BuildRequires: libcurl-devel
BuildRequires: gdm-pam-extensions-devel
%if (0%{?use_openssl} == 1)
BuildRequires: p11-kit-devel
BuildRequires: openssl-devel
BuildRequires: gnutls-utils
BuildRequires: softhsm >= 2.1.0
%endif
BuildRequires: openssl
BuildRequires: libxml2
BuildRequires: libxslt
BuildRequires: m4
BuildRequires: make
BuildRequires: nss_wrapper
BuildRequires: openldap-devel
BuildRequires: openssh
BuildRequires: nss-tools
BuildRequires: openssl-devel
BuildRequires: p11-kit-devel
BuildRequires: pam_wrapper
BuildRequires: pam-devel
BuildRequires: pcre-devel
BuildRequires: pkgconfig
BuildRequires: popt-devel
BuildRequires: python3-devel
BuildRequires: samba-devel
# required for idmap_sss.so
BuildRequires: samba-winbind
BuildRequires: selinux-policy-targeted
# required for p11_child smartcard tests
BuildRequires: softhsm >= 2.1.0
BuildRequires: systemd-devel
BuildRequires: systemtap-sdt-devel
BuildRequires: uid_wrapper
%description
Provides a set of daemons to manage access to remote directories and
authentication mechanisms. It provides an NSS and PAM interface toward
the system and a plug-gable back-end system to connect to multiple different
the system and a pluggable back end system to connect to multiple different
account sources. It is also the basis to provide client auditing and policy
services for projects like FreeIPA.
The sssd sub-package is a meta-package that contains the daemon as well as all
The sssd subpackage is a meta-package that contains the daemon as well as all
the existing back ends.
%package common
Summary: Common files for the SSSD
License: GPLv3+
# Conflicts
Conflicts: selinux-policy < 3.10.0-46
Conflicts: sssd < 1.10.0-8%{?dist}.beta2
# Requires
# due to ABI changes in 1.1.30/1.2.0
Requires: libldb >= %{ldb_version}
@ -177,6 +136,10 @@ Recommends: libsss_sudo = %{version}-%{release}
Recommends: libsss_autofs%{?_isa} = %{version}-%{release}
Recommends: sssd-nfs-idmap = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
Requires: libsss_certmap = %{version}-%{release}
%if 0%{?rhel}
Requires(pre): shadow-utils
%endif
%{?systemd_requires}
### Provides ###
@ -186,11 +149,13 @@ Obsoletes: libsss_sudo-devel <= 1.10.0-7%{?dist}.beta1
%description common
Common files for the SSSD. The common package includes all the files needed
to run a particular back end, however, the back ends are packaged in separate
sub-packages such as sssd-ldap.
subpackages such as sssd-ldap.
%package client
Summary: SSSD Client libraries for NSS and PAM
License: LGPLv3+
Requires: libsss_nss_idmap = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
Requires(post): /sbin/ldconfig
Requires(post): /usr/sbin/alternatives
Requires(preun): /usr/sbin/alternatives
@ -222,6 +187,7 @@ Requires: sssd-common = %{version}-%{release}
# required by sss_obfuscate
Requires: python3-sss = %{version}-%{release}
Requires: python3-sssdconfig = %{version}-%{release}
Requires: libsss_certmap = %{version}-%{release}
Recommends: sssd-dbus
%description tools
@ -268,9 +234,10 @@ Provides python3 module for calculating the murmur hash version 3
%package ldap
Summary: The LDAP back end of the SSSD
License: GPLv3+
Conflicts: sssd < 1.10.0-8.beta2
Requires: sssd-common = %{version}-%{release}
Requires: sssd-krb5-common = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
Requires: libsss_certmap = %{version}-%{release}
%description ldap
Provides the LDAP back end that the SSSD can utilize to fetch identity data
@ -279,7 +246,6 @@ from and authenticate against an LDAP server.
%package krb5-common
Summary: SSSD helpers needed for Kerberos and GSSAPI authentication
License: GPLv3+
Conflicts: sssd < 1.10.0-8.beta2
Requires: cyrus-sasl-gssapi%{?_isa}
Requires: sssd-common = %{version}-%{release}
@ -290,7 +256,6 @@ Kerberos user or host authentication.
%package krb5
Summary: The Kerberos authentication back end for the SSSD
License: GPLv3+
Conflicts: sssd < 1.10.0-8.beta2
Requires: sssd-common = %{version}-%{release}
Requires: sssd-krb5-common = %{version}-%{release}
@ -302,6 +267,7 @@ against a Kerberos server.
Summary: Common files needed for supporting PAC processing
License: GPLv3+
Requires: sssd-common = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
%description common-pac
Provides common files needed by SSSD providers such as IPA and Active Directory
@ -310,12 +276,14 @@ for handling Kerberos PACs.
%package ipa
Summary: The IPA back end of the SSSD
License: GPLv3+
Conflicts: sssd < 1.10.0-8.beta2
Requires: samba-client-libs >= %{samba_package_version}
Requires: sssd-common = %{version}-%{release}
Requires: sssd-krb5-common = %{version}-%{release}
Requires: libipa_hbac%{?_isa} = %{version}-%{release}
Requires: libsss_certmap = %{version}-%{release}
Recommends: bind-utils
Requires: sssd-common-pac = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
%description ipa
Provides the IPA back end that the SSSD can utilize to fetch identity data
@ -324,10 +292,12 @@ from and authenticate against an IPA server.
%package ad
Summary: The AD back end of the SSSD
License: GPLv3+
Conflicts: sssd < 1.10.0-8.beta2
Requires: samba-client-libs >= %{samba_package_version}
Requires: sssd-common = %{version}-%{release}
Requires: sssd-krb5-common = %{version}-%{release}
Requires: sssd-common-pac = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
Requires: libsss_certmap = %{version}-%{release}
Recommends: bind-utils
Recommends: adcli
Suggests: sssd-winbind-idmap = %{version}-%{release}
@ -339,7 +309,6 @@ identity data from and authenticate against an Active Directory server.
%package proxy
Summary: The proxy back end of the SSSD
License: GPLv3+
Conflicts: sssd < 1.10.0-8.beta2
Requires: sssd-common = %{version}-%{release}
%description proxy
@ -421,6 +390,19 @@ Requires: sssd-common = %{version}-%{release}
Provides the D-Bus responder of the SSSD, called the InfoPipe, that allows
the information from the SSSD to be transmitted over the system bus.
%if 0%{?rhel}
%package polkit-rules
Summary: Rules for polkit integration for SSSD
Group: Applications/System
License: GPLv3+
Requires: polkit >= 0.106
Requires: sssd-common = %{version}-%{release}
%description polkit-rules
Provides rules for polkit integration with SSSD. This is required
for smartcard support.
%endif
%package -n libsss_simpleifp
Summary: The SSSD D-Bus responder helper library
License: GPLv3+
@ -441,6 +423,8 @@ Provides library that simplifies D-Bus API for the SSSD InfoPipe responder.
%package winbind-idmap
Summary: SSSD's idmap_sss Backend for Winbind
License: GPLv3+ and LGPLv3+
Requires: libsss_nss_idmap = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
Conflicts: sssd-common < %{version}-%{release}
%description winbind-idmap
@ -484,62 +468,38 @@ An implementation of a Kerberos KCM server. Use this package if you want to
use the KCM: Kerberos credentials cache.
%prep
# Update timestamps on the files touched by a patch, to avoid non-equal
# .pyc/.pyo files across the multilib peers within a build, where "Level"
# is the patch prefix option (e.g. -p1)
# Taken from specfile for python-simplejson
UpdateTimestamps() {
Level=$1
PatchFile=$2
# Locate the affected files:
for f in $(diffstat $Level -l $PatchFile); do
# Set the files to have the same timestamp as that of the patch:
touch -r $PatchFile $f
done
}
%setup -q
for p in %patches ; do
%__patch -p1 -i $p
UpdateTimestamps -p1 $p
done
%autosetup -p1
%build
# This package uses -Wl,-wrap to wrap calls at link time. This is incompatible
# with LTO.
# Disable LTO
%define _lto_cflags %{nil}
autoreconf -ivf
%configure \
--with-test-dir=/dev/shm \
--with-db-path=%{dbpath} \
--with-mcache-path=%{mcpath} \
--with-pipe-path=%{pipepath} \
--with-pubconf-path=%{pubconfpath} \
--with-gpo-cache-path=%{gpocachepath} \
--with-init-dir=%{_initrddir} \
--with-krb5-rcache-dir=%{_localstatedir}/cache/krb5rcache \
--with-pid-path=%{_rundir} \
--enable-nsslibdir=%{_libdir} \
--enable-pammoddir=%{_libdir}/security \
--enable-nfsidmaplibdir=%{_libdir}/libnfsidmap \
--disable-static \
--disable-rpath \
--with-initscript=systemd \
--with-syslog=journald \
--without-python2-bindings \
%if (0%{?use_openssl} == 1)
--with-crypto=libcrypto \
%endif
--enable-sss-default-nss-plugin \
--disable-static \
--enable-files-domain \
--enable-gss-spnego-for-zero-maxssf \
%{?with_cifs_utils_plugin_option} \
%{?enable_systemtap_opt}
--enable-nfsidmaplibdir=%{_libdir}/libnfsidmap \
--enable-nsslibdir=%{_libdir} \
--enable-pammoddir=%{_libdir}/security \
--enable-sss-default-nss-plugin \
--enable-systemtap \
--with-db-path=%{dbpath} \
--with-gpo-cache-path=%{gpocachepath} \
--with-init-dir=%{_initrddir} \
--with-initscript=systemd \
--with-krb5-rcache-dir=%{_localstatedir}/cache/krb5rcache \
--with-mcache-path=%{mcpath} \
--with-pid-path=%{_rundir} \
--with-pipe-path=%{pipepath} \
--with-pubconf-path=%{pubconfpath} \
--with-sssd-user=%{sssd_user} \
--with-syslog=journald \
--with-test-dir=/dev/shm \
%if 0%{?fedora}
--disable-polkit-rules-path \
%endif
%{nil}
%make_build all docs runstatedir=%{_rundir}
@ -729,36 +689,32 @@ done
%dir %{sssdstatedir}
%dir %{_localstatedir}/cache/krb5rcache
%attr(700,root,root) %dir %{dbpath}
%attr(775,root,root) %dir %{mcpath}
%attr(700,%{sssd_user},%{sssd_user}) %dir %{dbpath}
%attr(775,%{sssd_user},%{sssd_user}) %dir %{mcpath}
%attr(700,root,root) %dir %{secdbpath}
%attr(751,root,root) %dir %{deskprofilepath}
%ghost %attr(0664,root,root) %verify(not md5 size mtime) %{mcpath}/passwd
%ghost %attr(0664,root,root) %verify(not md5 size mtime) %{mcpath}/group
%ghost %attr(0664,root,root) %verify(not md5 size mtime) %{mcpath}/initgroups
%attr(755,root,root) %dir %{pipepath}
%attr(700,root,root) %dir %{pipepath}/private
%attr(755,root,root) %dir %{pubconfpath}
%attr(755,root,root) %dir %{gpocachepath}
%attr(750,root,root) %dir %{_var}/log/%{name}
%attr(700,root,root) %dir %{_sysconfdir}/sssd
%attr(711,root,root) %dir %{_sysconfdir}/sssd/conf.d
%if (0%{?use_openssl} == 1)
%ghost %attr(0664,%{sssd_user},%{sssd_user}) %verify(not md5 size mtime) %{mcpath}/passwd
%ghost %attr(0664,%{sssd_user},%{sssd_user}) %verify(not md5 size mtime) %{mcpath}/group
%ghost %attr(0664,%{sssd_user},%{sssd_user}) %verify(not md5 size mtime) %{mcpath}/initgroups
%attr(755,%{sssd_user},%{sssd_user}) %dir %{pipepath}
%attr(750,%{sssd_user},root) %dir %{pipepath}/private
%attr(755,%{sssd_user},%{sssd_user}) %dir %{pubconfpath}
%attr(755,%{sssd_user},%{sssd_user}) %dir %{gpocachepath}
%attr(750,%{sssd_user},%{sssd_user}) %dir %{_var}/log/%{name}
%attr(700,%{sssd_user},%{sssd_user}) %dir %{_sysconfdir}/sssd
%attr(711,%{sssd_user},%{sssd_user}) %dir %{_sysconfdir}/sssd/conf.d
%attr(711,root,root) %dir %{_sysconfdir}/sssd/pki
%endif
%ghost %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/sssd/sssd.conf
%dir %{_sysconfdir}/logrotate.d
%config(noreplace) %{_sysconfdir}/logrotate.d/sssd
%dir %{_sysconfdir}/rwtab.d
%config(noreplace) %{_sysconfdir}/rwtab.d/sssd
%dir %{_datadir}/sssd
%{_sysconfdir}/pam.d/sssd-shadowutils
%config(noreplace) %{_sysconfdir}/pam.d/sssd-shadowutils
%dir %{_libdir}/%{name}/conf
%{_libdir}/%{name}/conf/sssd.conf
%{_datadir}/sssd/cfg_rules.ini
%{_datadir}/sssd/sssd.api.conf
%{_datadir}/sssd/sssd.api.d
%{_mandir}/man1/sss_ssh_authorizedkeys.1*
%{_mandir}/man1/sss_ssh_knownhostsproxy.1*
%{_mandir}/man5/sssd.conf.5*
@ -779,6 +735,10 @@ done
%{_datadir}/systemtap/tapset/sssd_functions.stp
%{_mandir}/man5/sssd-systemtap.5*
%if 0%{?rhel}
%files polkit-rules
%{_datadir}/polkit-1/rules.d/*
%endif
%files ldap -f sssd_ldap.lang
%license COPYING
@ -788,9 +748,9 @@ done
%files krb5-common
%license COPYING
%attr(755,root,root) %dir %{pubconfpath}/krb5.include.d
%{_libexecdir}/%{servicename}/ldap_child
%{_libexecdir}/%{servicename}/krb5_child
%attr(755,%{sssd_user},%{sssd_user}) %dir %{pubconfpath}/krb5.include.d
%attr(4750,root,%{sssd_user}) %{_libexecdir}/%{servicename}/ldap_child
%attr(4750,root,%{sssd_user}) %{_libexecdir}/%{servicename}/krb5_child
%files krb5 -f sssd_krb5.lang
%license COPYING
@ -803,9 +763,9 @@ done
%files ipa -f sssd_ipa.lang
%license COPYING
%attr(700,root,root) %dir %{keytabdir}
%attr(700,%{sssd_user},%{sssd_user}) %dir %{keytabdir}
%{_libdir}/%{name}/libsss_ipa.so
%{_libexecdir}/%{servicename}/selinux_child
%attr(4750,root,%{sssd_user}) %{_libexecdir}/%{servicename}/selinux_child
%{_mandir}/man5/sssd-ipa.5*
%files ad -f sssd_ad.lang
@ -816,7 +776,7 @@ done
%files proxy
%license COPYING
%{_libexecdir}/%{servicename}/proxy_child
%attr(4750,root,%{sssd_user}) %{_libexecdir}/%{servicename}/proxy_child
%{_libdir}/%{name}/libsss_proxy.so
%files dbus -f sssd_dbus.lang
@ -842,6 +802,7 @@ done
%license src/sss_client/COPYING src/sss_client/COPYING.LESSER
%{_libdir}/libnss_sss.so.2
%{_libdir}/security/pam_sss.so
%{_libdir}/security/pam_sss_gss.so
%{_libdir}/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so
%{_libdir}/krb5/plugins/authdata/sssd_pac_plugin.so
%dir %{_libdir}/cifs-utils
@ -852,6 +813,7 @@ done
%dir %{_libdir}/%{name}/modules
%{_libdir}/%{name}/modules/sssd_krb5_localauth_plugin.so
%{_mandir}/man8/pam_sss.8*
%{_mandir}/man8/pam_sss_gss.8*
%{_mandir}/man8/sssd_krb5_locator_plugin.8*
%files -n libsss_sudo
@ -881,6 +843,9 @@ done
%{python3_sitelib}/SSSDConfig/*.py*
%dir %{python3_sitelib}/SSSDConfig/__pycache__
%{python3_sitelib}/SSSDConfig/__pycache__/*.py*
%dir %{_datadir}/sssd
%{_datadir}/sssd/sssd.api.conf
%{_datadir}/sssd/sssd.api.d
%files -n python3-sss
%{python3_sitearch}/pysss.so
@ -954,6 +919,12 @@ done
%{_mandir}/man8/sssd-kcm.8*
%{_libdir}/%{name}/libsss_secrets.so
%if 0%{?rhel}
%pre common
getent group sssd >/dev/null || groupadd -r sssd
getent passwd sssd >/dev/null || useradd -r -g sssd -d / -s /sbin/nologin -c "User for sssd" sssd
%endif
%post common
%systemd_post sssd.service
%systemd_post sssd-autofs.socket
@ -1035,6 +1006,12 @@ fi
%systemd_postun_with_restart sssd.service
%changelog
* Fri Feb 5 2021 Pavel Březina <pbrezina@redhat.com> - 2.4.1-1
- Rebase to SSSD 2.4.1
* Wed Jan 27 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2.4.0-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Fri Dec 11 2020 Pavel Březina <pbrezina@redhat.com> - 2.4.0-6
- Improve sssd-kcm performance, fix upgrade with existing credentials (rhbz#1645624)