From 9d96864ada935f8951d62c85bebd81d5d7df7a9f Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 7 Nov 2025 19:22:11 +0100 Subject: [PATCH 1/3] utils: add new error code ERR_CHECK_NEXT_AUTH_TYPE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This error code should be used if another authentication type should be checked. Resolves: https://github.com/SSSD/sssd/issues/8108 Reviewed-by: Iker Pedrosa Reviewed-by: Tomáš Halman --- src/util/util_errors.c | 1 + src/util/util_errors.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/util/util_errors.c b/src/util/util_errors.c index bb2103f5198..691e9509d67 100644 --- a/src/util/util_errors.c +++ b/src/util/util_errors.c @@ -131,6 +131,7 @@ struct err_string error_to_str[] = { { "Unsupported range type" }, /* ERR_UNSUPPORTED_RANGE_TYPE */ { "proxy_child terminated by a signal" }, /* ERR_PROXY_CHILD_SIGNAL */ { "PAC check failed" }, /* ERR_CHECK_PAC_FAILED */ + { "Check next authentication type" }, /* ERR_CHECK_NEXT_AUTH_TYPE */ /* DBUS Errors */ { "Connection was killed on demand" }, /* ERR_SBUS_KILL_CONNECTION */ diff --git a/src/util/util_errors.h b/src/util/util_errors.h index 32836f42b25..358f51f3e1b 100644 --- a/src/util/util_errors.h +++ b/src/util/util_errors.h @@ -156,6 +156,7 @@ enum sssd_errors { ERR_UNSUPPORTED_RANGE_TYPE, ERR_PROXY_CHILD_SIGNAL, ERR_CHECK_PAC_FAILED, + ERR_CHECK_NEXT_AUTH_TYPE, /* DBUS Errors */ ERR_SBUS_KILL_CONNECTION, From 72178eb7399e1fed96f1c94a8519632d036d2234 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 7 Nov 2025 19:24:08 +0100 Subject: [PATCH 2/3] krb5_child: use ERR_CHECK_NEXT_AUTH_TYPE instead of EAGAIN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch used the new error code ERR_CHECK_NEXT_AUTH_TYPE while processing different authentication types instead of EAGAIN because EAGAIN might have side effects when returned to the callers. Resolves: https://github.com/SSSD/sssd/issues/8108 Reviewed-by: Iker Pedrosa Reviewed-by: Tomáš Halman --- src/providers/krb5/krb5_child.c | 47 +++++++++++++++++---------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index f5660cae7d5..90055e0a9e0 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -553,7 +553,7 @@ static krb5_error_code tokeninfo_matches(TALLOC_CTX *mem_ctx, "Unsupported authtok type %d\n", sss_authtok_get_type(auth_tok)); } - return EAGAIN; + return ERR_CHECK_NEXT_AUTH_TYPE; } static krb5_error_code answer_otp(krb5_context ctx, @@ -603,7 +603,7 @@ static krb5_error_code answer_otp(krb5_context ctx, /* Allocation errors are ignored on purpose */ DEBUG(SSSDBG_TRACE_INTERNAL, "Exit answer_otp during pre-auth.\n"); - return EAGAIN; + return ERR_CHECK_NEXT_AUTH_TYPE; } /* Find the first supported tokeninfo which matches our authtoken. */ @@ -773,14 +773,14 @@ static krb5_error_code answer_pkinit(krb5_context ctx, DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected authentication token type [%s]\n", sss_authtok_type_to_str(sss_authtok_get_type(kr->pd->authtok))); - kerr = EAGAIN; + kerr = ERR_CHECK_NEXT_AUTH_TYPE; goto done; } } else { /* We only expect SSS_PAM_PREAUTH here, but also for all other * commands the graceful solution would be to let the caller * check other authentication methods as well. */ - kerr = EAGAIN; + kerr = ERR_CHECK_NEXT_AUTH_TYPE; } done: @@ -910,7 +910,7 @@ static krb5_error_code answer_idp_oauth2(krb5_context kctx, if (type != SSS_AUTHTOK_TYPE_OAUTH2) { DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected authentication token type [%s]\n", sss_authtok_type_to_str(type)); - kerr = EAGAIN; + kerr = ERR_CHECK_NEXT_AUTH_TYPE; goto done; } @@ -1137,7 +1137,7 @@ static krb5_error_code answer_passkey(krb5_context kctx, if (type != SSS_AUTHTOK_TYPE_PASSKEY_REPLY) { DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected authentication token type [%s]\n", sss_authtok_type_to_str(type)); - kerr = EAGAIN; + kerr = ERR_CHECK_NEXT_AUTH_TYPE; goto done; } @@ -1228,7 +1228,7 @@ static krb5_error_code answer_password(krb5_context kctx, /* For SSS_PAM_PREAUTH and the other remaining commands the caller should * continue to iterate over the available authentication methods. */ - return EAGAIN; + return ERR_CHECK_NEXT_AUTH_TYPE; } static krb5_error_code sss_krb5_responder(krb5_context ctx, @@ -1253,12 +1253,12 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx, /* It is expected that the answer_*() functions only return EOK * (success) if the authentication was successful, i.e. during * SSS_PAM_AUTHENTICATE. In all other cases, e.g. during - * SSS_PAM_PREAUTH either EAGAIN should be returned to indicate - * that the other available authentication methods should be - * checked as well. Or some other error code to indicate a fatal - * error where no other methods should be tried. - * Especially if setting the answer failed neither EOK nor EAGAIN - * should be returned. */ + * SSS_PAM_PREAUTH either ERR_CHECK_NEXT_AUTH_TYPE should be + * returned to indicate that the other available authentication + * methods should be checked as well. Or some other error code to + * indicate a fatal error where no other methods should be tried. + * Especially if setting the answer failed neither EOK nor + * ERR_CHECK_NEXT_AUTH_TYPE should be returned. */ if (strcmp(question_list[c], KRB5_RESPONDER_QUESTION_PASSWORD) == 0) { kerr = answer_password(ctx, kr, rctx); @@ -1288,7 +1288,7 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx, /* 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) { + if (kerr == ERR_CHECK_NEXT_AUTH_TYPE) { /* During pre-auth iterating over all authentication methods * is expected and no message will be displayed. */ if (kr->pd->cmd == SSS_PAM_AUTHENTICATE) { @@ -1306,17 +1306,18 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx, kerr = answer_password(ctx, kr, rctx); } - /* During SSS_PAM_PREAUTH 'EAGAIN' is expected because we will run - * through all offered authentication methods and all are expect to return - * 'EAGAIN' in the positive case to indicate that the other methods should - * be checked as well. If all methods are checked we are done and should - * return success. - * In the other steps, especially SSS_PAM_AUTHENTICATE, having 'EAGAIN' at - * this stage would mean that no method feels responsible for the provided - * credentials i.e. authentication failed and we should return an error. + /* During SSS_PAM_PREAUTH 'ERR_CHECK_NEXT_AUTH_TYPE' is expected because we + * will run through all offered authentication methods and all are expect to + * return 'ERR_CHECK_NEXT_AUTH_TYPE' in the positive case to indicate that + * the other methods should be checked as well. If all methods are checked + * we are done and should return success. + * In the other steps, especially SSS_PAM_AUTHENTICATE, having + * 'ERR_CHECK_NEXT_AUTH_TYPE' at this stage would mean that no method feels + * responsible for the provided credentials i.e. authentication failed and + * we should return an error. */ if (kr->pd->cmd == SSS_PAM_PREAUTH) { - return kerr == EAGAIN ? 0 : kerr; + return kerr == ERR_CHECK_NEXT_AUTH_TYPE ? 0 : kerr; } else { return kerr; } From 89db64f03f7cf9b02865fd5418dfeaba4f41bcfb Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 7 Nov 2025 19:32:24 +0100 Subject: [PATCH 3/3] krb5_child: clarify EAGAIN returned by krb5_get_init_creds_password() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Iker Pedrosa Reviewed-by: Tomáš Halman --- src/providers/krb5/krb5_child.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index 90055e0a9e0..82ec4541363 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -2323,6 +2323,11 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr, KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); if (kerr == EAGAIN) { + /* The most probable reason for krb5_get_init_creds_password() + * to return EAGAIN is a temporary failure getaddrinfo() i.e. + * DNS currently does not work reliable. In this case it makes + * sense to return KRB5_KDC_UNREACH to tell the backend to try + * other KDCs or switch into offline mode. */ kerr = KRB5_KDC_UNREACH; }