Resolves: RHEL-22340 - socket leak

Resolves: RHEL-28161 - Passkey cannot fall back to password
This commit is contained in:
Alexey Tikhonov 2024-03-13 15:59:01 +01:00
parent 9e669db919
commit ea62250f41
5 changed files with 399 additions and 1 deletions

View File

@ -0,0 +1,50 @@
From 8bf31924265baf81372fe42580dee4064a642375 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 23 Jan 2024 09:28:26 +0100
Subject: [PATCH] sss-client: handle key value in destructor
When the pthread key destructor is called the key value is already set
to NULL by the caller. As a result the data stored in the value can only
be accessed by the first argument passed to the destructor and not by
pthread_getspecific() as the previous code did.
Resolves: https://github.com/SSSD/sssd/issues/7189
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
(cherry picked from commit b439847bc88ad7b89f0596af822c0ffbf2a579df)
---
src/sss_client/common.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
index 702d0597d..32555edf3 100644
--- a/src/sss_client/common.c
+++ b/src/sss_client/common.c
@@ -93,8 +93,22 @@ void sss_cli_close_socket(void)
#ifdef HAVE_PTHREAD_EXT
static void sss_at_thread_exit(void *v)
{
- sss_cli_close_socket();
+ /* At this point the key value is already set to NULL and the only way to
+ * access the data from the value is via the argument passed to the
+ * destructor (sss_at_thread_exit). See e.g.
+ * https://www.man7.org/linux/man-pages/man3/pthread_key_create.3p.html
+ * for details. */
+
+ struct sss_socket_descriptor_t *descriptor = (struct sss_socket_descriptor_t *) v;
+
+ if (descriptor->sd != -1) {
+ close(descriptor->sd);
+ descriptor->sd = -1;
+ }
+
free(v);
+
+ /* Most probably redudant, but better safe than sorry. */
pthread_setspecific(sss_sd_key, NULL);
}
--
2.42.0

View File

@ -0,0 +1,104 @@
From 23849f751315ea218e125f35cd419cce55d27355 Mon Sep 17 00:00:00 2001
From: Justin Stephenson <jstephen@redhat.com>
Date: Thu, 1 Feb 2024 14:22:09 -0500
Subject: [PATCH 6/7] krb5: Allow fallback between responder questions
Add support to try the next Preauth type when answering
krb5 questions. Fixes an issue when an IPA user has
both authtype passkey and authtype password set at
the same time.
Resolves: https://github.com/SSSD/sssd/issues/7152
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
(cherry picked from commit c9a333c5215b9ee6080038881a249c329141d0cf)
---
src/providers/krb5/krb5_child.c | 37 +++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 9 deletions(-)
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index d3e3d859a..26b0090b4 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -784,11 +784,14 @@ static krb5_error_code answer_pkinit(krb5_context ctx,
"krb5_responder_set_answer failed.\n");
}
+ goto done;
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected authentication token type [%s]\n",
+ sss_authtok_type_to_str(sss_authtok_get_type(kr->pd->authtok)));
+ kerr = EAGAIN;
goto done;
}
- kerr = EOK;
-
done:
krb5_responder_pkinit_challenge_free(ctx, rctx, chl);
@@ -914,9 +917,9 @@ static krb5_error_code answer_idp_oauth2(krb5_context kctx,
type = sss_authtok_get_type(kr->pd->authtok);
if (type != SSS_AUTHTOK_TYPE_OAUTH2) {
- DEBUG(SSSDBG_OP_FAILURE, "Unexpected authentication token type [%s]\n",
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected authentication token type [%s]\n",
sss_authtok_type_to_str(type));
- kerr = EINVAL;
+ kerr = EAGAIN;
goto done;
}
@@ -1141,9 +1144,9 @@ static krb5_error_code answer_passkey(krb5_context kctx,
type = sss_authtok_get_type(kr->pd->authtok);
if (type != SSS_AUTHTOK_TYPE_PASSKEY_REPLY) {
- DEBUG(SSSDBG_OP_FAILURE, "Unexpected authentication token type [%s]\n",
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected authentication token type [%s]\n",
sss_authtok_type_to_str(type));
- kerr = EINVAL;
+ kerr = EAGAIN;
goto done;
}
@@ -1244,17 +1247,33 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx,
return kerr;
}
+
+ kerr = EOK;
} else if (strcmp(question_list[c],
KRB5_RESPONDER_QUESTION_PKINIT) == 0
&& (sss_authtok_get_type(kr->pd->authtok)
== SSS_AUTHTOK_TYPE_SC_PIN
|| sss_authtok_get_type(kr->pd->authtok)
== SSS_AUTHTOK_TYPE_SC_KEYPAD)) {
- return answer_pkinit(ctx, kr, rctx);
+ kerr = answer_pkinit(ctx, kr, rctx);
} else if (strcmp(question_list[c], SSSD_IDP_OAUTH2_QUESTION) == 0) {
- return answer_idp_oauth2(ctx, kr, rctx);
+ kerr = answer_idp_oauth2(ctx, kr, rctx);
} else if (strcmp(question_list[c], SSSD_PASSKEY_QUESTION) == 0) {
- return answer_passkey(ctx, kr, rctx);
+ kerr = answer_passkey(ctx, kr, rctx);
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unknown question type [%s]\n", question_list[c]);
+ kerr = EINVAL;
+ }
+
+ /* Continue to the next question when the given authtype cannot be
+ * handled by the answer_* function. This allows fallback between auth
+ * types, such as passkey -> password. */
+ if (kerr == EAGAIN) {
+ DEBUG(SSSDBG_TRACE_ALL, "Auth type [%s] could not be handled by answer function, "
+ "continuing to next question.\n", question_list[c]);
+ continue;
+ } else {
+ return kerr;
}
}
}
--
2.42.0

View File

@ -0,0 +1,206 @@
From 8d9ae754b50dffafef719ad3fa44e5dd1dde47b3 Mon Sep 17 00:00:00 2001
From: Justin Stephenson <jstephen@redhat.com>
Date: Fri, 1 Mar 2024 14:31:25 -0500
Subject: [PATCH 7/7] krb5: Add fallback password change support
handle password changes for IPA users with multiple auth types set
(passkey, password)
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
(cherry picked from commit 6c1272edf174eb4bdf236dc1ffd4287b71a43392)
---
src/krb5_plugin/passkey/passkey_clpreauth.c | 5 ++
src/providers/ipa/ipa_auth.c | 13 +++++
src/providers/krb5/krb5_auth.c | 12 +++++
src/providers/krb5/krb5_auth.h | 3 ++
src/providers/krb5/krb5_child.c | 5 ++
src/providers/krb5/krb5_child_handler.c | 53 +++++++++++++++++++++
src/responder/pam/pamsrv_cmd.c | 10 ++++
7 files changed, 101 insertions(+)
diff --git a/src/krb5_plugin/passkey/passkey_clpreauth.c b/src/krb5_plugin/passkey/passkey_clpreauth.c
index d2dfe6fe1..35b6a3fed 100644
--- a/src/krb5_plugin/passkey/passkey_clpreauth.c
+++ b/src/krb5_plugin/passkey/passkey_clpreauth.c
@@ -279,6 +279,11 @@ sss_passkeycl_process(krb5_context context,
goto done;
}
+ if (prompter == NULL) {
+ ret = EINVAL;
+ goto done;
+ }
+
/* Get FAST armor key. */
as_key = cb->fast_armor(context, rock);
if (as_key == NULL) {
diff --git a/src/providers/ipa/ipa_auth.c b/src/providers/ipa/ipa_auth.c
index 1d61a1052..e5e1bf30c 100644
--- a/src/providers/ipa/ipa_auth.c
+++ b/src/providers/ipa/ipa_auth.c
@@ -258,6 +258,19 @@ static void ipa_pam_auth_handler_krb5_done(struct tevent_req *subreq)
if (dp_err != DP_ERR_OK) {
goto done;
}
+ if (state->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM
+ && state->pd->pam_status == PAM_TRY_AGAIN) {
+ /* Reset this to fork a new krb5_child in handle_child_send() */
+ state->pd->child_pid = 0;
+ subreq = krb5_auth_queue_send(state, state->ev, state->be_ctx, state->pd,
+ state->auth_ctx->krb5_auth_ctx);
+ if (subreq == NULL) {
+ goto done;
+ }
+
+ tevent_req_set_callback(subreq, ipa_pam_auth_handler_retry_done, req);
+ return;
+ }
if (state->pd->cmd == SSS_PAM_AUTHENTICATE
&& state->pd->pam_status == PAM_CRED_ERR
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
index be34880b4..e34943b82 100644
--- a/src/providers/krb5/krb5_auth.c
+++ b/src/providers/krb5/krb5_auth.c
@@ -532,6 +532,18 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
ret = EOK;
goto done;
}
+
+ /* If krb5_child is still running from SSS_PAM_PREAUTH,
+ * terminate the waiting krb5_child and send the
+ * CHAUTHTOK_PRELIM request again */
+ if (pd->child_pid != 0) {
+ soft_terminate_krb5_child(state, pd, krb5_ctx);
+ state->pam_status = PAM_TRY_AGAIN;
+ state->dp_err = DP_ERR_OK;
+ ret = EOK;
+ goto done;
+ }
+
break;
case SSS_CMD_RENEW:
if (authtok_type != SSS_AUTHTOK_TYPE_CCFILE) {
diff --git a/src/providers/krb5/krb5_auth.h b/src/providers/krb5/krb5_auth.h
index bbdbf61fc..783292bc0 100644
--- a/src/providers/krb5/krb5_auth.h
+++ b/src/providers/krb5/krb5_auth.h
@@ -135,6 +135,9 @@ errno_t init_renew_tgt(struct krb5_ctx *krb5_ctx, struct be_ctx *be_ctx,
errno_t add_tgt_to_renew_table(struct krb5_ctx *krb5_ctx, const char *ccfile,
struct tgt_times *tgtt, struct pam_data *pd,
const char *upn);
+errno_t soft_terminate_krb5_child(TALLOC_CTX *mem_ctx,
+ struct pam_data *pd,
+ struct krb5_ctx *krb5_ctx);
/* krb5_access.c */
struct tevent_req *krb5_access_send(TALLOC_CTX *mem_ctx,
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 26b0090b4..b8acae7d7 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -1259,6 +1259,11 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx,
} else if (strcmp(question_list[c], SSSD_IDP_OAUTH2_QUESTION) == 0) {
kerr = answer_idp_oauth2(ctx, kr, rctx);
} else if (strcmp(question_list[c], SSSD_PASSKEY_QUESTION) == 0) {
+ /* Skip answer_passkey for expired password changes, e.g. user with auth types
+ * passkey AND password set */
+ if (kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM || kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
+ continue;
+ }
kerr = answer_passkey(ctx, kr, rctx);
} else {
DEBUG(SSSDBG_MINOR_FAILURE, "Unknown question type [%s]\n", question_list[c]);
diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c
index 54088e4d6..cab84b37d 100644
--- a/src/providers/krb5/krb5_child_handler.c
+++ b/src/providers/krb5/krb5_child_handler.c
@@ -1020,3 +1020,56 @@ parse_krb5_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, ssize_t len,
*_res = res;
return EOK;
}
+
+/* Closes the write end of waiting krb5_child */
+errno_t soft_terminate_krb5_child(TALLOC_CTX *mem_ctx,
+ struct pam_data *pd,
+ struct krb5_ctx *krb5_ctx)
+{
+ char *io_key;
+ struct child_io_fds *io;
+ TALLOC_CTX *tmp_ctx;
+ int ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ if (pd->child_pid == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Expected waiting krb5_child.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ io_key = talloc_asprintf(tmp_ctx, "%d", pd->child_pid);
+ if (io_key == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ io = sss_ptr_hash_lookup(krb5_ctx->io_table, io_key,
+ struct child_io_fds);
+ if (io == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "PTR hash lookup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ if (io->write_to_child_fd != -1) {
+ ret = close(io->write_to_child_fd);
+ io->write_to_child_fd = -1;
+ if (ret != EOK) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "close failed [%d][%s].\n", ret, strerror(ret));
+ }
+ }
+
+ ret = EOK;
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index a7c181733..de408ced8 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1418,6 +1418,15 @@ void pam_reply(struct pam_auth_req *preq)
goto done;
}
+#if BUILD_PASSKEY
+ if(pd->cmd == SSS_PAM_AUTHENTICATE &&
+ pd->pam_status == PAM_NEW_AUTHTOK_REQD &&
+ sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_PASSKEY_REPLY) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Passkey authentication reply, ignoring "
+ "new authtok required status\n");
+ pd->pam_status = PAM_SUCCESS;
+ }
+
/* Passkey auth user notification if no TGT is granted */
if (pd->cmd == SSS_PAM_AUTHENTICATE &&
pd->pam_status == PAM_SUCCESS &&
@@ -1429,6 +1438,7 @@ void pam_reply(struct pam_auth_req *preq)
"User [%s] logged in with local passkey authentication, single "
"sign on ticket is not obtained.\n", pd->user);
}
+#endif /* BUILD_PASSKEY */
/* Account expiration warning is printed for sshd. If pam_verbosity
* is equal or above PAM_VERBOSITY_INFO then all services are informed
--
2.42.0

View File

@ -0,0 +1,30 @@
From bebb150720620aae97dcae5c11e0b9bea0119b5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 13 Mar 2024 13:27:02 +0100
Subject: [PATCH] pam: fix invalid #if condition
ifdef should be used as anywhere else, otherwise we hit a build
error if sssd is being built without passkey.
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
(cherry picked from commit 603399a43d7bd0b8b6de3b512388b08abb9521ed)
---
src/responder/pam/pamsrv_cmd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index de408ced8..13ba13131 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1418,7 +1418,7 @@ void pam_reply(struct pam_auth_req *preq)
goto done;
}
-#if BUILD_PASSKEY
+#ifdef BUILD_PASSKEY
if(pd->cmd == SSS_PAM_AUTHENTICATE &&
pd->pam_status == PAM_NEW_AUTHTOK_REQD &&
sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_PASSKEY_REPLY) {
--
2.42.0

View File

@ -27,7 +27,7 @@
Name: sssd
Version: 2.9.4
Release: 2%{?dist}
Release: 3%{?dist}
Summary: System Security Services Daemon
License: GPLv3+
URL: https://github.com/SSSD/sssd/
@ -38,6 +38,10 @@ Patch0001: 0001-sssd-adding-mail-as-case-insensitive.patch
Patch0002: 0002-sdap-add-search_bases-option-to-groups_by_user_send.patch
Patch0003: 0003-sdap-add-naming_context-as-new-member-of-struct-sdap.patch
Patch0004: 0004-pam-fix-SC-auth-with-multiple-certs-and-missing-logi.patch
Patch0005: 0005-sss-client-handle-key-value-in-destructor.patch
Patch0006: 0006-krb5-Allow-fallback-between-responder-questions.patch
Patch0007: 0007-krb5-Add-fallback-password-change-support.patch
Patch0008: 0008-pam-fix-invalid-if-condition.patch
### Dependencies ###
@ -1087,6 +1091,10 @@ fi
%systemd_postun_with_restart sssd.service
%changelog
* Wed Mar 13 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.4-3
- Resolves: RHEL-22340 - socket leak
- Resolves: RHEL-28161 - Passkey cannot fall back to password
* Mon Feb 12 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.4-2
- Resolves: RHEL-12503 - AD users are unable to log in due to case sensitivity of user because the domain is found as an alias to the email address.
- Resolves: RHEL-22288 - ssh pubkey stored in ldap/AD no longer works to authenticate via sssd