diff --git a/backport-KCM-Fix-a-memory-leak.patch b/backport-KCM-Fix-a-memory-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..2698a22fbaeaff7db884699d671843b098004271 --- /dev/null +++ b/backport-KCM-Fix-a-memory-leak.patch @@ -0,0 +1,44 @@ +From cbae6855320b53f3f2bdc0e11c5a9c8eb84daf87 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alejandro=20L=C3=B3pez?= +Date: Mon, 18 Dec 2023 11:37:29 +0100 +Subject: [PATCH] KCM: Fix a memory "leak" + +When an operation is processed, a buffer is allocated for the reply +and its parent is the client context (struct cli_ctx). This buffer +is not explicitly freed but it is released when the client context is +freed. With each operation a new buffer is allocated and the +previous one gets "lost." + +This is not an actual leak because the lost buffers are released by +talloc once the client context is freed, when the connection is closed. +But on long-lived connections this can consume a large amount of memory +before the connection is closed. + +To solve this, the request context (struct kcm_req_ctx) is the new +parent of the buffer. The request is freed as soon as the operation is +completed and no buffer gets lost. + +Resolves: https://github.com/SSSD/sssd/issues/7072 + +Reviewed-by: Iker Pedrosa +Reviewed-by: Sumit Bose +--- + src/responder/kcm/kcmsrv_cmd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/responder/kcm/kcmsrv_cmd.c b/src/responder/kcm/kcmsrv_cmd.c +index 1f60d1a14..9c37e3cf0 100644 +--- a/src/responder/kcm/kcmsrv_cmd.c ++++ b/src/responder/kcm/kcmsrv_cmd.c +@@ -350,7 +350,7 @@ static void kcm_send_reply(struct kcm_req_ctx *req_ctx) + + cctx = req_ctx->cctx; + +- ret = kcm_output_construct(cctx, &req_ctx->op_io, &req_ctx->repbuf); ++ ret = kcm_output_construct(req_ctx, &req_ctx->op_io, &req_ctx->repbuf); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Cannot construct the reply buffer, terminating client\n"); +-- +2.33.0 + diff --git a/backport-KCM-Fixed-a-wrong-check.patch b/backport-KCM-Fixed-a-wrong-check.patch new file mode 100644 index 0000000000000000000000000000000000000000..e3a425154a5f9b0d84f3fbc86e75661c9f6cd948 --- /dev/null +++ b/backport-KCM-Fixed-a-wrong-check.patch @@ -0,0 +1,35 @@ +From 3cba6d1153c102f9596335db28cc017e8338e868 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alejandro=20L=C3=B3pez?= +Date: Fri, 3 Nov 2023 15:31:46 +0100 +Subject: [PATCH] KCM: Fixed a wrong check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The pointer to the newly allocated iobuffer is stored into +state->op_ctx->reply but the check for NULL is done on state->reply, +which we already know is not NULL because it was checked before and +not modified after that. + +Reviewed-by: Alexey Tikhonov +Reviewed-by: Tomáš Halman +--- + src/responder/kcm/kcmsrv_ops.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c +index 33d7cd506..dab96b486 100644 +--- a/src/responder/kcm/kcmsrv_ops.c ++++ b/src/responder/kcm/kcmsrv_ops.c +@@ -161,7 +161,7 @@ struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx, + state, + KCM_REPLY_MAX - 2*sizeof(uint32_t), + KCM_REPLY_MAX - 2*sizeof(uint32_t)); +- if (state->reply == NULL) { ++ if (state->op_ctx->reply == NULL) { + ret = ENOMEM; + goto immediate; + } +-- +2.33.0 + diff --git a/backport-LOGROTATE-logrotate-should-also-signal-sssd_kcm.patch b/backport-LOGROTATE-logrotate-should-also-signal-sssd_kcm.patch new file mode 100644 index 0000000000000000000000000000000000000000..5d57358da46fa22cc1a7719e47e0a8a09f626273 --- /dev/null +++ b/backport-LOGROTATE-logrotate-should-also-signal-sssd_kcm.patch @@ -0,0 +1,42 @@ +From 230e7757a7805c7c530d0914936f353882bd504e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alejandro=20L=C3=B3pez?= +Date: Fri, 10 Nov 2023 14:07:49 +0100 +Subject: [PATCH] LOGROTATE: logrotate should also signal sssd_kcm +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +sssd_kcm is not registered with SSSD's monitor, so it is not signaled +when it must restart the log. Adding this command will directly signal +sssd_kcm (in addition to the monitor). + +If sssd_kcm is also running in one or more containers, they will also +receive the signal. Because only the log files in the host where rotated, +the instances in the containers will go on using the same log files. +Nothing will happen except for the "Received SIGHUP. Rotating logfiles." +message in the log files. If we want to avoid this, we should implement +a PID file. + +Reviewed-by: Sumit Bose +Reviewed-by: Tomáš Halman +--- + contrib/sssd.spec.in | 1 + + src/examples/logrotate | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/examples/logrotate b/src/examples/logrotate +index ecf0c6102..6e769451c 100644 +--- a/src/examples/logrotate ++++ b/src/examples/logrotate +@@ -7,6 +7,7 @@ + compress + delaycompress + postrotate +- /bin/kill -HUP `cat /var/run/sssd.pid 2>/dev/null` 2> /dev/null || true ++ /bin/kill -HUP `cat /var/run/sssd.pid 2>/dev/null` 2> /dev/null || true ++ /bin/pkill -HUP sssd_kcm 2> /dev/null || true + endscript + } +-- +2.33.0 + diff --git a/backport-nssidmap-fix-sss_nss_getgrouplist_timeout-with-empty.patch b/backport-nssidmap-fix-sss_nss_getgrouplist_timeout-with-empty.patch new file mode 100644 index 0000000000000000000000000000000000000000..5f62d0ab141548a99d0080279d042efbdfbf0700 --- /dev/null +++ b/backport-nssidmap-fix-sss_nss_getgrouplist_timeout-with-empty.patch @@ -0,0 +1,121 @@ +From cffe6e09c6b4cd8afa049365bbd432ace5d2a9d9 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 26 Oct 2023 14:09:48 +0200 +Subject: [PATCH] nssidmap: fix sss_nss_getgrouplist_timeout() with empty + secondary group list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +sss_nss_getgrouplist_timeout() is intended as a replacement for +getgrouplist() which only gets secondary groups from SSSD. Currently it +returns an ENOENT error if there are no secondary groups returned by +SSSD. However, as with getgrouplist(), there is the second parameter +which expects a single GID which will be added to the result. This means +that sss_nss_getgrouplist_timeout() will always return at least this GID +as a result and an ENOENT error does not make sense. + +With this patch sss_nss_getgrouplist_timeout() will not return an error +anymore if there are no secondary groups but just a result with the +single GID from the second parameter. + +Reviewed-by: Alejandro López +Reviewed-by: Tomáš Halman +--- + src/sss_client/idmap/sss_nss_ex.c | 5 ++-- + src/tests/cmocka/sss_nss_idmap-tests.c | 32 ++++++++++++++++++++++++++ + 2 files changed, 35 insertions(+), 2 deletions(-) + +diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c +index b5230d6b7..24e2a6be9 100644 +--- a/src/sss_client/idmap/sss_nss_ex.c ++++ b/src/sss_client/idmap/sss_nss_ex.c +@@ -241,8 +241,9 @@ static int sss_get_ex(struct nss_input *inp, uint32_t flags, + /* Get number of results from repbuf. */ + SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); + +- /* no results if not found */ +- if (num_results == 0) { ++ /* no results if not found, INITGR requests are handled separately */ ++ if (num_results == 0 && inp->cmd != SSS_NSS_INITGR ++ && inp->cmd != SSS_NSS_INITGR_EX) { + ret = ENOENT; + goto out; + } +diff --git a/src/tests/cmocka/sss_nss_idmap-tests.c b/src/tests/cmocka/sss_nss_idmap-tests.c +index 880bab0e5..30b24a57e 100644 +--- a/src/tests/cmocka/sss_nss_idmap-tests.c ++++ b/src/tests/cmocka/sss_nss_idmap-tests.c +@@ -30,6 +30,7 @@ + #include "util/util.h" + #include "util/sss_endian.h" + ++#define IPA_389DS_PLUGIN_HELPER_CALLS 1 + #include "sss_client/idmap/sss_nss_idmap.h" + #include "tests/cmocka/common_mock.h" + +@@ -50,6 +51,8 @@ uint8_t buf3[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x + uint8_t buf4[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 'x'}; + + uint8_t buf_orig1[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 'k', 'e', 'y', 0x00, 'v', 'a', 'l', 'u', 'e', 0x00}; ++ ++uint8_t buf_initgr[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00}; + #elif (__BYTE_ORDER == __BIG_ENDIAN) + uint8_t buf1[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; + uint8_t buf2[] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; +@@ -57,10 +60,14 @@ uint8_t buf3[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x + uint8_t buf4[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 'x'}; + + uint8_t buf_orig1[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'k', 'e', 'y', 0x00, 'v', 'a', 'l', 'u', 'e', 0x00}; ++ ++uint8_t buf_initgr[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde}; + #else + #error "unknow endianess" + #endif + ++uint8_t buf_initgr_no_gr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++ + enum nss_status __wrap_sss_nss_make_request_timeout(enum sss_cli_command cmd, + struct sss_cli_req_data *rd, + int timeout, +@@ -148,12 +155,37 @@ void test_getorigbyname(void **state) + sss_nss_free_kv(kv_list); + } + ++void test_sss_nss_getgrouplist_timeout(void **state) ++{ ++ int ret; ++ gid_t groups[10]; ++ int ngroups = sizeof(groups); ++ struct sss_nss_make_request_test_data d = {buf_initgr, sizeof(buf_initgr), 0, NSS_STATUS_SUCCESS}; ++ ++ will_return(__wrap_sss_nss_make_request_timeout, &d); ++ ret = sss_nss_getgrouplist_timeout("test", 111, groups, &ngroups, 0, 0); ++ assert_int_equal(ret, EOK); ++ assert_int_equal(ngroups, 2); ++ assert_int_equal(groups[0], 111); ++ assert_int_equal(groups[1], 222); ++ ++ d.repbuf = buf_initgr_no_gr; ++ d.replen = sizeof(buf_initgr_no_gr); ++ ++ will_return(__wrap_sss_nss_make_request_timeout, &d); ++ ret = sss_nss_getgrouplist_timeout("test", 111, groups, &ngroups, 0, 0); ++ assert_int_equal(ret, EOK); ++ assert_int_equal(ngroups, 1); ++ assert_int_equal(groups[0], 111); ++} ++ + int main(int argc, const char *argv[]) + { + + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_getsidbyname), + cmocka_unit_test(test_getorigbyname), ++ cmocka_unit_test(test_sss_nss_getgrouplist_timeout), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +-- +2.33.0 + diff --git a/backport-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch b/backport-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch new file mode 100644 index 0000000000000000000000000000000000000000..86246950f53d0397d677a00773a564103470d720 --- /dev/null +++ b/backport-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch @@ -0,0 +1,112 @@ +From ae6b9163be0a5a8846e8dbf2e0da2c29221781b9 Mon Sep 17 00:00:00 2001 +From: Petr Mikhalicin +Date: Fri, 10 Nov 2023 15:24:48 +0600 +Subject: [PATCH] pam_sss: fix passthrow of old authtok from another pam + modules at PAM_PRELIM_CHECK + +pam_sss ignored old authtoks passed from another pam modules + +Resolves: https://github.com/SSSD/sssd/issues/7007 +Resolves: https://github.com/SSSD/sssd/issues/5418 + +Reviewed-by: Iker Pedrosa +Reviewed-by: Sumit Bose +--- + src/sss_client/pam_sss.c | 75 ++++++++++++++++++++++++---------------- + 1 file changed, 45 insertions(+), 30 deletions(-) + +diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c +index a1c353604..47f3f6bd3 100644 +--- a/src/sss_client/pam_sss.c ++++ b/src/sss_client/pam_sss.c +@@ -2728,42 +2728,57 @@ static int get_authtok_for_password_change(pam_handle_t *pamh, + exp_data = NULL; + } + +- /* we query for the old password during PAM_PRELIM_CHECK to make +- * pam_sss work e.g. with pam_cracklib */ + if (pam_flags & PAM_PRELIM_CHECK) { +- if ( (getuid() != 0 || exp_data ) && !(flags & PAM_CLI_FLAGS_USE_FIRST_PASS)) { +- if (flags & PAM_CLI_FLAGS_USE_2FA +- || (pi->otp_vendor != NULL && pi->otp_token_id != NULL +- && pi->otp_challenge != NULL)) { +- if (pi->password_prompting) { +- ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "), +- _("Second Factor (optional): ")); +- } else { +- ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "), +- _("Second Factor: ")); +- } ++ if (getuid() == 0 && !exp_data ) ++ return PAM_SUCCESS; ++ ++ if (flags & PAM_CLI_FLAGS_USE_2FA ++ || (pi->otp_vendor != NULL && pi->otp_token_id != NULL ++ && pi->otp_challenge != NULL)) { ++ if (pi->password_prompting) { ++ ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "), ++ _("Second Factor (optional): ")); + } else { +- ret = prompt_password(pamh, pi, _("Current Password: ")); ++ ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "), ++ _("Second Factor: ")); + } +- if (ret != PAM_SUCCESS) { +- D(("failed to get credentials from user")); +- return ret; ++ } else if ((flags & PAM_CLI_FLAGS_USE_FIRST_PASS) ++ && check_authtok_data(pamh, pi) != 0) { ++ if (pi->pamstack_oldauthtok == NULL) { ++ pi->pam_authtok_type = SSS_AUTHTOK_TYPE_EMPTY; ++ pi->pam_authtok = NULL; ++ pi->pam_authtok_size = 0; ++ } else { ++ pi->pam_authtok = strdup(pi->pamstack_oldauthtok); ++ if (pi->pam_authtok == NULL) { ++ D(("strdup failed")); ++ return PAM_BUF_ERR; ++ } ++ pi->pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD; ++ pi->pam_authtok_size = strlen(pi->pam_authtok); + } ++ ret = PAM_SUCCESS; ++ } else { ++ ret = prompt_password(pamh, pi, _("Current Password: ")); ++ } ++ if (ret != PAM_SUCCESS) { ++ D(("failed to get credentials from user")); ++ return ret; ++ } + +- ret = pam_set_item(pamh, PAM_OLDAUTHTOK, pi->pam_authtok); +- if (ret != PAM_SUCCESS) { +- D(("Failed to set PAM_OLDAUTHTOK [%s], " +- "oldauthtok may not be available", +- pam_strerror(pamh,ret))); +- return ret; +- } ++ ret = pam_set_item(pamh, PAM_OLDAUTHTOK, pi->pam_authtok); ++ if (ret != PAM_SUCCESS) { ++ D(("Failed to set PAM_OLDAUTHTOK [%s], " ++ "oldauthtok may not be available", ++ pam_strerror(pamh,ret))); ++ return ret; ++ } + +- if (pi->pam_authtok_type == SSS_AUTHTOK_TYPE_2FA) { +- ret = keep_authtok_data(pamh, pi); +- if (ret != 0) { +- D(("Failed to store authtok data to pam handle. Password " +- "change might fail.")); +- } ++ if (pi->pam_authtok_type == SSS_AUTHTOK_TYPE_2FA) { ++ ret = keep_authtok_data(pamh, pi); ++ if (ret != 0) { ++ D(("Failed to store authtok data to pam handle. Password " ++ "change might fail.")); + } + } + +-- +2.33.0 + diff --git a/sssd.spec b/sssd.spec index 808aa8ccf2a4b71ae857dc0822f744fc10fbd122..5c231d15cc27e697a6fcba10a3db91696f1d307a 100644 --- a/sssd.spec +++ b/sssd.spec @@ -1,6 +1,6 @@ Name: sssd Version: 2.6.1 -Release: 12 +Release: 13 Summary: System Security Services Daemon License: GPLv3+ and LGPLv3+ URL: https://pagure.io/SSSD/sssd/ @@ -43,6 +43,11 @@ Patch6033: backport-cli-caculate-the-wait_time-in-milliseconds.patch Patch6034: backport-dyndns-PTR-record-updates-separately.patch Patch6035: backport-ipa-do-not-go-offline-if-group-does-not-have-SID.patch Patch6036: backport-KCM-Display-in-the-log-the-limit-as-set-by-the-user.patch +Patch6037: backport-LOGROTATE-logrotate-should-also-signal-sssd_kcm.patch +Patch6038: backport-KCM-Fixed-a-wrong-check.patch +Patch6039: backport-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch +Patch6040: backport-nssidmap-fix-sss_nss_getgrouplist_timeout-with-empty.patch +Patch6041: backport-KCM-Fix-a-memory-leak.patch Requires: python3-sssd = %{version}-%{release} Requires: libldb @@ -550,6 +555,9 @@ fi %systemd_postun_with_restart sssd.service %changelog +* Thu Feb 22 2024 wangcheng - 2.6.1-13 +- backport upstream patches + * Tue Nov 28 2023 wangcheng - 2.6.1-12 - backport upstream patches