diff --git a/.gitignore b/.gitignore index 40ea95a..c06b2bb 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/0001-BUILD-fixes-gpo_child-linking-issue.patch b/0001-BUILD-fixes-gpo_child-linking-issue.patch new file mode 100644 index 0000000..b365cf5 --- /dev/null +++ b/0001-BUILD-fixes-gpo_child-linking-issue.patch @@ -0,0 +1,49 @@ +From cf308d6c0e763336526b2e6295f1a075b217900f Mon Sep 17 00:00:00 2001 +From: Alexey Tikhonov +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 + diff --git a/0001-kcm-fix-typos-in-debug-messages.patch b/0001-kcm-fix-typos-in-debug-messages.patch deleted file mode 100644 index 399c6c6..0000000 --- a/0001-kcm-fix-typos-in-debug-messages.patch +++ /dev/null @@ -1,53 +0,0 @@ -From b768a37d3f908a37f4c490a30df6559bc14c7451 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0002-kcm-avoid-name-confusion-in-GET_CRED_UUID_LIST-handl.patch b/0002-kcm-avoid-name-confusion-in-GET_CRED_UUID_LIST-handl.patch deleted file mode 100644 index e686442..0000000 --- a/0002-kcm-avoid-name-confusion-in-GET_CRED_UUID_LIST-handl.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a0e3759b733a5b5db82bea2ef35e1519ea8a9b1c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0003-kcm-disable-encryption.patch b/0003-kcm-disable-encryption.patch deleted file mode 100644 index 882a018..0000000 --- a/0003-kcm-disable-encryption.patch +++ /dev/null @@ -1,509 +0,0 @@ -From 426947971cd94cc93dd120ca8ad9bcbeb47059c4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0004-kcm-avoid-multiple-debug-messages-if-sss_sec_put-fai.patch b/0004-kcm-avoid-multiple-debug-messages-if-sss_sec_put-fai.patch deleted file mode 100644 index b1d810c..0000000 --- a/0004-kcm-avoid-multiple-debug-messages-if-sss_sec_put-fai.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b8dd3fa32cef423217859a1ef04ec30dfef30fb2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0005-secrets-allow-to-specify-secret-s-data-format.patch b/0005-secrets-allow-to-specify-secret-s-data-format.patch deleted file mode 100644 index 9de5bf0..0000000 --- a/0005-secrets-allow-to-specify-secret-s-data-format.patch +++ /dev/null @@ -1,225 +0,0 @@ -From e05dfeca855986cd11674a64ef6333c2d67e9bc7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0006-secrets-accept-binary-data-instead-of-string.patch b/0006-secrets-accept-binary-data-instead-of-string.patch deleted file mode 100644 index e92be25..0000000 --- a/0006-secrets-accept-binary-data-instead-of-string.patch +++ /dev/null @@ -1,450 +0,0 @@ -From 63cbb2aee2c6277ecd9e38fb32713e0ba3db4bb4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0007-iobuf-add-more-iobuf-functions.patch b/0007-iobuf-add-more-iobuf-functions.patch deleted file mode 100644 index 6566cc8..0000000 --- a/0007-iobuf-add-more-iobuf-functions.patch +++ /dev/null @@ -1,265 +0,0 @@ -From 51c8dda998c5b7bfa08362a13915fcff265a6f8f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0008-kcm-add-json-suffix-to-existing-searialization-funct.patch b/0008-kcm-add-json-suffix-to-existing-searialization-funct.patch deleted file mode 100644 index dbaa796..0000000 --- a/0008-kcm-add-json-suffix-to-existing-searialization-funct.patch +++ /dev/null @@ -1,292 +0,0 @@ -From 27968f52eb57391ae64df57d29cf9911fc59d161 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0009-kcm-move-sec-key-parser-to-separate-file-so-it-can-b.patch b/0009-kcm-move-sec-key-parser-to-separate-file-so-it-can-b.patch deleted file mode 100644 index fe14533..0000000 --- a/0009-kcm-move-sec-key-parser-to-separate-file-so-it-can-b.patch +++ /dev/null @@ -1,404 +0,0 @@ -From 23273319b546d034d31ffe3824b954659d20d104 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 . -+*/ -+ -+#include "config.h" -+ -+#include -+#include -+ -+#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 - diff --git a/0010-kcm-avoid-suppression-of-cppcheck-warning.patch b/0010-kcm-avoid-suppression-of-cppcheck-warning.patch deleted file mode 100644 index 47eda0f..0000000 --- a/0010-kcm-avoid-suppression-of-cppcheck-warning.patch +++ /dev/null @@ -1,30 +0,0 @@ -From efd57d2a6001b7015095f7ff5bbd0c55764e22ab Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0011-kcm-add-spaces-around-operators-in-kcmsrv_ccache_key.patch b/0011-kcm-add-spaces-around-operators-in-kcmsrv_ccache_key.patch deleted file mode 100644 index 78a9458..0000000 --- a/0011-kcm-add-spaces-around-operators-in-kcmsrv_ccache_key.patch +++ /dev/null @@ -1,42 +0,0 @@ -From d51819e51fca80675b9915863e72d835c9e0a0fe Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0012-kcm-use-binary-format-to-store-ccache-instead-of-jso.patch b/0012-kcm-use-binary-format-to-store-ccache-instead-of-jso.patch deleted file mode 100644 index a684f0b..0000000 --- a/0012-kcm-use-binary-format-to-store-ccache-instead-of-jso.patch +++ /dev/null @@ -1,741 +0,0 @@ -From 94ceb85465dbf052f681bbd6c8ebced4d2d97f92 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 -+ -+ 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 . -+*/ -+ -+#include "config.h" -+ -+#include -+#include -+ -+#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 - diff --git a/0013-kcm-add-per-connection-data-to-be-shared-between-req.patch b/0013-kcm-add-per-connection-data-to-be-shared-between-req.patch deleted file mode 100644 index a7ff7b2..0000000 --- a/0013-kcm-add-per-connection-data-to-be-shared-between-req.patch +++ /dev/null @@ -1,131 +0,0 @@ -From ae6898e7dc60d7067f0d71212c7ed28fc9e8e285 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0014-sss_ptr_hash-fix-double-free-for-circular-dependenci.patch b/0014-sss_ptr_hash-fix-double-free-for-circular-dependenci.patch deleted file mode 100644 index 9f154fc..0000000 --- a/0014-sss_ptr_hash-fix-double-free-for-circular-dependenci.patch +++ /dev/null @@ -1,165 +0,0 @@ -From f1db05d8839b39fd48471dcb29881c12ed27a434 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0015-kcm-store-credentials-list-in-hash-table-to-avoid-ca.patch b/0015-kcm-store-credentials-list-in-hash-table-to-avoid-ca.patch deleted file mode 100644 index da81b49..0000000 --- a/0015-kcm-store-credentials-list-in-hash-table-to-avoid-ca.patch +++ /dev/null @@ -1,551 +0,0 @@ -From 9ffc2c6447f2177ff406a9f4d17d8413967ab7ad Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 -+#include - - #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 - #include - #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 - diff --git a/0016-secrets-fix-may_payload_size-exceeded-debug-message.patch b/0016-secrets-fix-may_payload_size-exceeded-debug-message.patch deleted file mode 100644 index e3ee22d..0000000 --- a/0016-secrets-fix-may_payload_size-exceeded-debug-message.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 24a6888e38fb9d11bf173eb06e400678388bce49 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0017-secrets-default-to-plaintext-if-enctype-attr-is-miss.patch b/0017-secrets-default-to-plaintext-if-enctype-attr-is-miss.patch deleted file mode 100644 index 13efbcd..0000000 --- a/0017-secrets-default-to-plaintext-if-enctype-attr-is-miss.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 36e4dc6c9a48ee62345839a9df14e0494c99bf59 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0018-secrets-move-attrs-names-to-macros.patch b/0018-secrets-move-attrs-names-to-macros.patch deleted file mode 100644 index a03eca3..0000000 --- a/0018-secrets-move-attrs-names-to-macros.patch +++ /dev/null @@ -1,183 +0,0 @@ -From b18f0f87948d44f1d99dd4da0ac1affcbb8c53e8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0019-secrets-remove-base64-enctype.patch b/0019-secrets-remove-base64-enctype.patch deleted file mode 100644 index 915d049..0000000 --- a/0019-secrets-remove-base64-enctype.patch +++ /dev/null @@ -1,75 +0,0 @@ -From bca694200748354c7ee3e51084586d30b9b0164b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 - diff --git a/0020-kcm-decode-base64-encoded-secret-on-upgrade-path.patch b/0020-kcm-decode-base64-encoded-secret-on-upgrade-path.patch deleted file mode 100644 index 6c45514..0000000 --- a/0020-kcm-decode-base64-encoded-secret-on-upgrade-path.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 18b98836ef8e337992f0ecb239a32b9c3cedb750 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 ---- - 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 - diff --git a/sources b/sources index 869c58d..dbd8cba 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (sssd-2.4.0.tar.gz) = d9a4b17665ce3a1ea51cfe2fdb53818ac1e265a33c61f657f61699ecc716e1244e45b5b628aeae6c54e601383084f3cac327cb3edd7bea80bca397b1fbe4ab72 +SHA512 (sssd-2.4.1.tar.gz) = 27b53585c43ee8387fda85afd894bcbd2aa037e8b7e05ffb68a17232fcc6a8b4aaf5f83eda65b91f656de3f040372ddfa49d0a905ff37b1064b6e22544025669 diff --git a/sssd.spec b/sssd.spec index f73e535..3c4fc38 100644 --- a/sssd.spec +++ b/sssd.spec @@ -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 - 2.4.1-1 +- Rebase to SSSD 2.4.1 + +* Wed Jan 27 2021 Fedora Release Engineering - 2.4.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + * Fri Dec 11 2020 Pavel Březina - 2.4.0-6 - Improve sssd-kcm performance, fix upgrade with existing credentials (rhbz#1645624)