From 512c156f5f18cdf5d053fa434ce5b7d26c3c91da Mon Sep 17 00:00:00 2001 From: Justin Stephenson Date: Wed, 5 Nov 2025 10:13:26 -0500 Subject: [PATCH 1/4] pam: Remove PAM_PASSKEY_VERIFICATION_OMIT mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove support of ambiguous "unset" state of passkey user verification. pam_sss prompting is binary, either on or off. The use of 'unset' passkey user verification state allows for ambiguous behavior in SSSD. For example, passkey_child may perform undefined behavior when '--user-verification' argument is not set, now SSSD will always send '--user-verification=false/true' to passkey_child. Reviewed-by: Iker Pedrosa Reviewed-by: Tomáš Halman --- src/responder/pam/pamsrv_passkey.c | 6 ++---- src/responder/pam/pamsrv_passkey.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/responder/pam/pamsrv_passkey.c b/src/responder/pam/pamsrv_passkey.c index 15787173b16..c61b5e2d066 100644 --- a/src/responder/pam/pamsrv_passkey.c +++ b/src/responder/pam/pamsrv_passkey.c @@ -43,7 +43,6 @@ struct pam_passkey_table_data { struct pam_passkey_verification_enum_str pam_passkey_verification_enum_str[] = { { PAM_PASSKEY_VERIFICATION_ON, "on" }, { PAM_PASSKEY_VERIFICATION_OFF, "off" }, - { PAM_PASSKEY_VERIFICATION_OMIT, "unset" }, { PAM_PASSKEY_VERIFICATION_INVALID, NULL } }; @@ -395,7 +394,7 @@ static errno_t passkey_local_verification(TALLOC_CTX *mem_ctx, const char *verification_from_ldap; char *verify_opts = NULL; bool debug_libfido2 = false; - enum passkey_user_verification verification = PAM_PASSKEY_VERIFICATION_OMIT; + enum passkey_user_verification verification = PAM_PASSKEY_VERIFICATION_ON; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { @@ -624,7 +623,7 @@ void pam_passkey_get_user_done(struct tevent_req *req) int timeout; struct cache_req_result *result = NULL; struct pk_child_user_data *pk_data = NULL; - enum passkey_user_verification verification = PAM_PASSKEY_VERIFICATION_OMIT; + enum passkey_user_verification verification = PAM_PASSKEY_VERIFICATION_ON; pctx = tevent_req_callback_data(req, struct passkey_ctx); @@ -984,7 +983,6 @@ pam_passkey_auth_send(TALLOC_CTX *mem_ctx, DEBUG(SSSDBG_TRACE_FUNC, "Calling child with user-verification false\n"); break; default: - DEBUG(SSSDBG_TRACE_FUNC, "Calling child with user-verification unset\n"); break; } diff --git a/src/responder/pam/pamsrv_passkey.h b/src/responder/pam/pamsrv_passkey.h index 06f35208f78..b74aca4ac77 100644 --- a/src/responder/pam/pamsrv_passkey.h +++ b/src/responder/pam/pamsrv_passkey.h @@ -32,7 +32,6 @@ enum passkey_user_verification { PAM_PASSKEY_VERIFICATION_ON, PAM_PASSKEY_VERIFICATION_OFF, - PAM_PASSKEY_VERIFICATION_OMIT, PAM_PASSKEY_VERIFICATION_INVALID }; From 8f8947c43260ea548616125f76f66cd1d1167941 Mon Sep 17 00:00:00 2001 From: Justin Stephenson Date: Wed, 5 Nov 2025 13:33:36 -0500 Subject: [PATCH 2/4] pam: Skip passkey_local() in Kerberos auth flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Local auth functions should only be reached in AD/LDAP auth flows. Reviewed-by: Iker Pedrosa Reviewed-by: Tomáš Halman --- src/responder/pam/pamsrv_cmd.c | 5 ++++- src/responder/pam/pamsrv_passkey.c | 5 ++++- src/responder/pam/pamsrv_passkey.h | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c index e0099941091..fd55ac01503 100644 --- a/src/responder/pam/pamsrv_cmd.c +++ b/src/responder/pam/pamsrv_cmd.c @@ -1251,6 +1251,7 @@ void pam_reply(struct pam_auth_req *preq) struct prompt_config **pc_list = NULL; #ifdef BUILD_PASSKEY bool pk_preauth_done = false; + bool pk_kerberos = false; #endif /* BUILD_PASSKEY */ pd = preq->pd; @@ -1533,7 +1534,8 @@ void pam_reply(struct pam_auth_req *preq) } #ifdef BUILD_PASSKEY - ret = pam_eval_passkey_response(pctx, pd, preq, &pk_preauth_done); + ret = pam_eval_passkey_response(pctx, pd, preq, &pk_preauth_done, + &pk_kerberos); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to eval passkey response\n"); goto done; @@ -1541,6 +1543,7 @@ void pam_reply(struct pam_auth_req *preq) if (may_do_passkey_auth(pctx, pd) && !pk_preauth_done + && !pk_kerberos && preq->passkey_data_exists && local_passkey_auth_allow) { ret = passkey_local(cctx, cctx->ev, pctx, preq, pd); diff --git a/src/responder/pam/pamsrv_passkey.c b/src/responder/pam/pamsrv_passkey.c index c61b5e2d066..af6c0d41c44 100644 --- a/src/responder/pam/pamsrv_passkey.c +++ b/src/responder/pam/pamsrv_passkey.c @@ -1254,7 +1254,8 @@ errno_t save_passkey_data(TALLOC_CTX *mem_ctx, errno_t pam_eval_passkey_response(struct pam_ctx *pctx, struct pam_data *pd, struct pam_auth_req *preq, - bool *_pk_preauth_done) + bool *_pk_preauth_done, + bool *_kerberos) { struct response_data *pk_resp; struct pk_child_user_data *pk_data; @@ -1271,6 +1272,8 @@ errno_t pam_eval_passkey_response(struct pam_ctx *pctx, while (pk_resp != NULL) { switch (pk_resp->type) { case SSS_PAM_PASSKEY_KRB_INFO: + *_kerberos = true; + if (!pctx->passkey_auth) { /* Passkey auth is disabled. To avoid passkey prompts appearing, * don't send SSS_PAM_PASSKEY_KRB_INFO to the client and diff --git a/src/responder/pam/pamsrv_passkey.h b/src/responder/pam/pamsrv_passkey.h index b74aca4ac77..a52579ec560 100644 --- a/src/responder/pam/pamsrv_passkey.h +++ b/src/responder/pam/pamsrv_passkey.h @@ -79,7 +79,8 @@ errno_t decode_pam_passkey_msg(TALLOC_CTX *mem_ctx, errno_t pam_eval_passkey_response(struct pam_ctx *pctx, struct pam_data *pd, struct pam_auth_req *preq, - bool *_pk_preauth_done); + bool *_pk_preauth_done, + bool *_kerberos); errno_t process_passkey_data(TALLOC_CTX *mem_ctx, struct ldb_message *user_mesg, const char *domain, From f63fc182e554ffba40a98c7a586504f0777bd333 Mon Sep 17 00:00:00 2001 From: Justin Stephenson Date: Wed, 5 Nov 2025 14:07:03 -0500 Subject: [PATCH 3/4] passkey: Remove SYSDB_PASSKEY_USER_VERIFICATION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove SYSDB_PASSKEY_USER_VERIFICATION and related functions. In phase 1 of passkey implementation we read passkey user verification from IPA LDAP tree, however now user verification is sent to the SSSD krb5 plugin from ipa-otpd. Reviewed-by: Iker Pedrosa Reviewed-by: Tomáš Halman --- Makefile.am | 10 - src/db/sysdb.h | 1 - src/db/sysdb_passkey_user_verification.c | 236 --------------------- src/db/sysdb_passkey_user_verification.h | 49 ----- src/providers/ipa/ipa_subdomains.c | 41 ---- src/providers/ipa/ipa_subdomains_passkey.c | 148 ------------- src/providers/ipa/ipa_subdomains_passkey.h | 45 ---- src/responder/pam/pamsrv_passkey.c | 53 ++--- src/tests/cmocka/test_pam_srv.c | 33 --- 9 files changed, 15 insertions(+), 601 deletions(-) delete mode 100644 src/db/sysdb_passkey_user_verification.c delete mode 100644 src/db/sysdb_passkey_user_verification.h delete mode 100644 src/providers/ipa/ipa_subdomains_passkey.c delete mode 100644 src/providers/ipa/ipa_subdomains_passkey.h diff --git a/Makefile.am b/Makefile.am index 60a1ab7c88b..4bc4e28a9fc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -817,7 +817,6 @@ dist_noinst_HEADERS = \ src/db/sysdb_ssh.h \ src/db/sysdb_subid.h \ src/db/sysdb_domain_resolution_order.h \ - src/db/sysdb_passkey_user_verification.h \ src/db/sysdb_iphosts.h \ src/db/sysdb_ipnetworks.h \ src/confdb/confdb.h \ @@ -879,7 +878,6 @@ dist_noinst_HEADERS = \ src/providers/ipa/ipa_auth.h \ src/providers/ipa/ipa_dyndns.h \ src/providers/ipa/ipa_subdomains.h \ - src/providers/ipa/ipa_subdomains_passkey.h \ src/providers/ipa/ipa_id.h \ src/providers/ipa/ipa_opts.h \ src/providers/ipa/ipa_srv.h \ @@ -1326,9 +1324,6 @@ endif if BUILD_SYSTEMTAP libsss_util_la_LIBADD += stap_generated_probes.lo endif -if BUILD_PASSKEY -libsss_util_la_SOURCES += src/db/sysdb_passkey_user_verification.c -endif # BUILD_PASSKEY libsss_util_la_LDFLAGS = -avoid-version SSSD_INTERNAL_LTLIBS = \ @@ -4549,11 +4544,6 @@ if BUILD_SSH libsss_ipa_la_SOURCES += src/providers/ipa/ipa_hostid.c endif -if BUILD_PASSKEY -libsss_ipa_la_SOURCES += \ - src/providers/ipa/ipa_subdomains_passkey.c -endif # BUILD_PASSKEY - libsss_ad_la_SOURCES = \ src/providers/ad/ad_opts.c \ src/providers/ad/ad_common.c \ diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 4494f6ed2e6..9e6f6969312 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -215,7 +215,6 @@ #define SYSDB_DOMAIN_RESOLUTION_ORDER "domainResolutionOrder" #define SYSDB_DOMAIN_TEMPLATE_SHELL "templateLoginShell" #define SYSDB_DOMAIN_TEMPLATE_HOMEDIR "templateHomeDirectory" -#define SYSDB_PASSKEY_USER_VERIFICATION "passkeyUserVerification" #define SYSDB_SESSION_RECORDING "sessionRecording" #define SYSDB_NEXTID_FILTER "("SYSDB_NEXTID"=*)" diff --git a/src/db/sysdb_passkey_user_verification.c b/src/db/sysdb_passkey_user_verification.c deleted file mode 100644 index 428225b75a1..00000000000 --- a/src/db/sysdb_passkey_user_verification.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - Authors: - Justin Stephenson - - Copyright (C) 2022 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 - -#include "db/sysdb.h" -#include "db/sysdb_private.h" - -static errno_t -sysdb_get_passkey_user_verification_string_attr(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - struct ldb_dn *dn, - const char **_attr) -{ - TALLOC_CTX *tmp_ctx; - struct ldb_result *res; - const char *attr; - const char *attrs[] = { SYSDB_PASSKEY_USER_VERIFICATION, NULL }; - errno_t ret; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - ret = ldb_search(sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, - NULL); - if (ret != LDB_SUCCESS) { - ret = EIO; - goto done; - } - - if (res->count > 1) { - DEBUG(SSSDBG_OP_FAILURE, - "Base search returned [%d] results, expected 1.\n", res->count); - ret = EINVAL; - goto done; - } else if (res->count == 0) { - ret = ENOENT; - goto done; - } else { - /* res->count == 1 */ - attr = ldb_msg_find_attr_as_string(res->msgs[0], - SYSDB_PASSKEY_USER_VERIFICATION, - NULL); - if (attr == NULL) { - ret = ENOENT; - goto done; - } - } - - *_attr = talloc_steal(mem_ctx, attr); - - ret = EOK; - -done: - talloc_free(tmp_ctx); - return ret; -} - -errno_t -sysdb_get_passkey_user_verification(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - struct ldb_dn *dn, - const char **_passkey_user_verification) -{ - TALLOC_CTX *tmp_ctx; - const char *passkey_user_verification = NULL; - errno_t ret; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - ret = sysdb_get_passkey_user_verification_string_attr( - tmp_ctx, sysdb, dn, &passkey_user_verification); - if (ret != EOK && ret != ENOENT) { - DEBUG(SSSDBG_OP_FAILURE, - "sysdb_get_passkey_user_verification_string_attr() failed " - "[%d]: [%s]", - ret, sss_strerror(ret)); - goto done; - } else if (ret == ENOENT) { - *_passkey_user_verification = NULL; - goto done; - } else { - /* ret == EOK */ - *_passkey_user_verification = talloc_steal(mem_ctx, - passkey_user_verification); - } - - ret = EOK; - -done: - talloc_free(tmp_ctx); - return ret; -} - -errno_t -sysdb_update_passkey_user_verification(struct sysdb_ctx *sysdb, - struct ldb_dn *dn, - const char *passkey_user_verification) -{ - TALLOC_CTX *tmp_ctx; - struct ldb_message *msg; - errno_t ret; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - msg = ldb_msg_new(tmp_ctx); - if (msg == NULL) { - ret = ENOMEM; - goto done; - } - - msg->dn = dn; - - ret = ldb_msg_add_empty(msg, SYSDB_PASSKEY_USER_VERIFICATION, - LDB_FLAG_MOD_REPLACE, NULL); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - if (passkey_user_verification != NULL) { - ret = ldb_msg_add_string(msg, SYSDB_PASSKEY_USER_VERIFICATION, - passkey_user_verification); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - } - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, - "ldb_modify()_failed: [%s][%d][%s]\n", - ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); - ret = sysdb_error_to_errno(ret); - goto done; - } - - - ret = EOK; - -done: - talloc_free(tmp_ctx); - return ret; -} - -errno_t -sysdb_domain_get_passkey_user_verification(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - const char *domain_name, - const char **_user_verification) -{ - TALLOC_CTX *tmp_ctx; - struct ldb_dn *dn; - errno_t ret; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, domain_name); - if (dn == NULL) { - ret = ENOMEM; - goto done; - } - - ret = sysdb_get_passkey_user_verification(mem_ctx, sysdb, dn, - _user_verification); - -done: - talloc_free(tmp_ctx); - return ret; -} - -errno_t -sysdb_domain_update_passkey_user_verification(struct sysdb_ctx *sysdb, - const char *domain_name, - const char *user_verification) -{ - - TALLOC_CTX *tmp_ctx; - struct ldb_dn *dn; - errno_t ret; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, domain_name); - if (dn == NULL) { - ret = ENOMEM; - goto done; - } - - ret = sysdb_update_passkey_user_verification(sysdb, dn, - user_verification); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "sysdb_update_passkey_user_verification() failed [%d]: [%s].\n", - ret, sss_strerror(ret)); - goto done; - } - - ret = EOK; - -done: - talloc_free(tmp_ctx); - return ret; -} diff --git a/src/db/sysdb_passkey_user_verification.h b/src/db/sysdb_passkey_user_verification.h deleted file mode 100644 index 5644c3c688e..00000000000 --- a/src/db/sysdb_passkey_user_verification.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Authors: - Justin Stephenson - - Copyright (C) 2022 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 . -*/ - -#ifndef _SYSDB_PASSKEY_USER_VERIFICATION_H_ -#define _SYSDB_PASSKEY_USER_VERIFICATION_H_ - -#include "db/sysdb.h" - -/* Retrieve passkey user verification value from sysdb */ -errno_t sysdb_get_passkey_user_verification(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - struct ldb_dn *dn, - const char **_user_verification); - -/* Replace passkey user verification value in sysdb with - * user_verification argument value */ -errno_t sysdb_update_passkey_user_verification(struct sysdb_ctx *sysdb, - struct ldb_dn *dn, - const char *user_verification); - -/* For a given domain, retrieve passkey user verification value from sysdb */ -errno_t sysdb_domain_get_passkey_user_verification(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - const char *domain_name, - const char **_user_verification); - -/* For a given domain, replace passkey user verification value from sysdb - * with user_verification argument value */ -errno_t sysdb_domain_update_passkey_user_verification(struct sysdb_ctx *sysdb, - const char *domain_name, - const char *user_verification); -#endif /* _SYSDB_PASSKEY_USER_VERIFICATION_H_ */ diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index 40cb90b01cc..6c93c847689 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -30,9 +30,6 @@ #include "providers/ipa/ipa_id.h" #include "providers/ipa/ipa_opts.h" #include "providers/ipa/ipa_config.h" -#ifdef BUILD_PASSKEY -#include "providers/ipa/ipa_subdomains_passkey.h" -#endif /* BUILD_PASSKEY */ #include @@ -67,8 +64,6 @@ #define IPA_ENABLED_FLAG "ipaEnabledFlag" #define IPA_TRUE_VALUE "TRUE" #define IPA_ASSOCIATED_DOMAIN "associatedDomain" -#define IPA_PASSKEY_VERIFICATION "ipaRequireUserVerification" -#define IPA_PASSKEY_CONFIG_FILTER "cn=passkeyconfig" #define OBJECTCLASS "objectClass" @@ -2885,9 +2880,6 @@ static errno_t ipa_subdomains_refresh_retry(struct tevent_req *req); static void ipa_subdomains_refresh_connect_done(struct tevent_req *subreq); static void ipa_subdomains_refresh_ranges_done(struct tevent_req *subreq); static void ipa_subdomains_refresh_certmap_done(struct tevent_req *subreq); -#ifdef BUILD_PASSKEY -static void ipa_subdomains_refresh_passkey_done(struct tevent_req *subreq); -#endif /* BUILD_PASSKEY */ static void ipa_subdomains_refresh_master_done(struct tevent_req *subreq); static void ipa_subdomains_refresh_slave_done(struct tevent_req *subreq); static void ipa_subdomains_refresh_view_name_done(struct tevent_req *subreq); @@ -3042,39 +3034,6 @@ static void ipa_subdomains_refresh_certmap_done(struct tevent_req *subreq) /* Not good, but let's try to continue with other server side options */ } -#ifdef BUILD_PASSKEY - subreq = ipa_subdomains_passkey_send(state, state->ev, state->sd_ctx, - sdap_id_op_handle(state->sdap_op)); - if (subreq == NULL) { - tevent_req_error(req, ENOMEM); - return; - } - - tevent_req_set_callback(subreq, ipa_subdomains_refresh_passkey_done, req); - return; -} - -static void ipa_subdomains_refresh_passkey_done(struct tevent_req *subreq) -{ - - struct ipa_subdomains_refresh_state *state; - struct tevent_req *req; - errno_t ret; - - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct ipa_subdomains_refresh_state); - - ret = ipa_subdomains_passkey_recv(subreq); - talloc_zfree(subreq); - if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get passkey configuration " - "[%d]: %s\n", ret, sss_strerror(ret)); - /* Not good, but let's try to continue with other server side options */ - DEBUG(SSSDBG_IMPORTANT_INFO, "Passkey feature is not configured " - "on IPA server\n"); - } -#endif /* BUILD_PASSKEY */ - subreq = ipa_subdomains_master_send(state, state->ev, state->sd_ctx, sdap_id_op_handle(state->sdap_op)); if (subreq == NULL) { diff --git a/src/providers/ipa/ipa_subdomains_passkey.c b/src/providers/ipa/ipa_subdomains_passkey.c deleted file mode 100644 index 55d951f1540..00000000000 --- a/src/providers/ipa/ipa_subdomains_passkey.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - SSSD - - IPA Subdomains Passkey Module - - Authors: - Justin Stephenson - - Copyright (C) 2022 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 "providers/ldap/sdap_async.h" -#include "providers/ldap/sdap_idmap.h" -#include "providers/ldap/sdap_ops.h" -#include "providers/ipa/ipa_subdomains.h" -#include "providers/ipa/ipa_common.h" -#include "providers/ipa/ipa_id.h" -#include "providers/ipa/ipa_opts.h" -#include "providers/ipa/ipa_config.h" -#include "providers/ipa/ipa_subdomains_passkey.h" -#include "db/sysdb_passkey_user_verification.h" - -#include -#define IPA_PASSKEY_VERIFICATION "ipaRequireUserVerification" -#define IPA_PASSKEY_CONFIG_FILTER "cn=passkeyconfig" - -void ipa_subdomains_passkey_done(struct tevent_req *subreq); - -struct tevent_req * -ipa_subdomains_passkey_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct ipa_subdomains_ctx *sd_ctx, - struct sdap_handle *sh) -{ - struct ipa_subdomains_passkey_state *state; - struct tevent_req *subreq; - struct tevent_req *req; - errno_t ret; - static const char *attrs[] = { IPA_PASSKEY_VERIFICATION, NULL }; - - req = tevent_req_create(mem_ctx, &state, - struct ipa_subdomains_passkey_state); - if (req == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); - return NULL; - } - - state->domain = sd_ctx->be_ctx->domain; - state->sdap_opts = sd_ctx->sdap_id_ctx->opts; - - subreq = ipa_get_config_send(state, ev, sh, sd_ctx->sdap_id_ctx->opts, - state->domain->name, attrs, IPA_PASSKEY_CONFIG_FILTER, NULL); - - if (subreq == NULL) { - ret = ENOMEM; - goto immediately; - } - - tevent_req_set_callback(subreq, ipa_subdomains_passkey_done, req); - - return req; - -immediately: - tevent_req_error(req, ret); - tevent_req_post(req, ev); - - return req; -} - -void ipa_subdomains_passkey_done(struct tevent_req *subreq) -{ - struct ipa_subdomains_passkey_state *state; - struct tevent_req *req; - struct sysdb_attrs *config; - const char *user_verification = NULL; - errno_t ret; - - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct ipa_subdomains_passkey_state); - - ret = ipa_get_config_recv(subreq, state, &config); - talloc_zfree(subreq); - if (ret == ENOENT) { - config = NULL; - } if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "Unable to get data from LDAP [%d]: %s\n", - ret, sss_strerror(ret)); - goto done; - } - - if (config != NULL) { - ret = sysdb_attrs_get_string(config, IPA_PASSKEY_VERIFICATION, - &user_verification); - if (ret == EOK) { - DEBUG(SSSDBG_TRACE_ALL, "Retrieved [%s] from [%s] attribute.\n", - user_verification, IPA_PASSKEY_VERIFICATION); - } - if (ret != EOK && ret != ENOENT) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to get passkey user verification " - "value [%d]: %s\n", - ret, sss_strerror(ret)); - goto done; - } else if (ret == ENOENT) { - user_verification = NULL; - } - } - - ret = sysdb_domain_update_passkey_user_verification( - state->domain->sysdb, state->domain->name, - user_verification); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "sysdb_domain_passkey_user_verification() [%d]: [%s].\n", - ret, sss_strerror(ret)); - goto done; - } - - ret = EOK; - -done: - if (ret != EOK) { - tevent_req_error(req, ret); - return; - } - - tevent_req_done(req); -} - -errno_t ipa_subdomains_passkey_recv(struct tevent_req *req) -{ - TEVENT_REQ_RETURN_ON_ERROR(req); - - return EOK; -} diff --git a/src/providers/ipa/ipa_subdomains_passkey.h b/src/providers/ipa/ipa_subdomains_passkey.h deleted file mode 100644 index ecbf2391349..00000000000 --- a/src/providers/ipa/ipa_subdomains_passkey.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - SSSD - - IPA Subdomains Passkey Module - - Authors: - Justin Stephenson - - Copyright (C) 2022 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 . -*/ - -#ifndef _IPA_SUBDOMAINS_PASSKEY_H_ -#define _IPA_SUBDOMAINS_PASSKEY_H_ - -#include "providers/backend.h" -#include "providers/ipa/ipa_common.h" -#include "config.h" - -struct ipa_subdomains_passkey_state { - struct sss_domain_info *domain; - struct sdap_options *sdap_opts; -}; - -struct tevent_req * -ipa_subdomains_passkey_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct ipa_subdomains_ctx *sd_ctx, - struct sdap_handle *sh); - -errno_t ipa_subdomains_passkey_recv(struct tevent_req *req); - -#endif /* _IPA_SUBDOMAINS_PASSKEY_H_ */ diff --git a/src/responder/pam/pamsrv_passkey.c b/src/responder/pam/pamsrv_passkey.c index af6c0d41c44..f11a80a275f 100644 --- a/src/responder/pam/pamsrv_passkey.c +++ b/src/responder/pam/pamsrv_passkey.c @@ -24,7 +24,6 @@ #include "util/child_common.h" #include "util/authtok.h" #include "db/sysdb.h" -#include "db/sysdb_passkey_user_verification.h" #include "responder/pam/pamsrv.h" #include "responder/pam/pamsrv_passkey.h" @@ -391,7 +390,6 @@ static errno_t passkey_local_verification(TALLOC_CTX *mem_ctx, { TALLOC_CTX *tmp_ctx; errno_t ret; - const char *verification_from_ldap; char *verify_opts = NULL; bool debug_libfido2 = false; enum passkey_user_verification verification = PAM_PASSKEY_VERIFICATION_ON; @@ -401,17 +399,6 @@ static errno_t passkey_local_verification(TALLOC_CTX *mem_ctx, return ENOMEM; } - ret = sysdb_domain_get_passkey_user_verification(tmp_ctx, sysdb, domain_name, - &verification_from_ldap); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to read passkeyUserVerification from sysdb: [%d]: %s\n", - ret, sss_strerror(ret)); - /* This is expected for AD and LDAP */ - ret = EOK; - goto done; - } - ret = confdb_get_bool(pctx->pam_ctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_PASSKEY_DEBUG_LIBFIDO2, false, &debug_libfido2); @@ -422,34 +409,24 @@ static errno_t passkey_local_verification(TALLOC_CTX *mem_ctx, goto done; } - /* If require user verification setting is set in LDAP, use it */ - if (verification_from_ldap != NULL) { - if (strcasecmp(verification_from_ldap, "true") == 0) { - verification = PAM_PASSKEY_VERIFICATION_ON; - } else if (strcasecmp(verification_from_ldap, "false") == 0) { - verification = PAM_PASSKEY_VERIFICATION_OFF; - } - DEBUG(SSSDBG_TRACE_FUNC, "Passkey verification is being enforced from LDAP\n"); - } else { - /* No verification set in LDAP, fallback to local sssd.conf setting */ - ret = confdb_get_string(pctx->pam_ctx->rctx->cdb, tmp_ctx, CONFDB_MONITOR_CONF_ENTRY, - CONFDB_MONITOR_PASSKEY_VERIFICATION, NULL, - &verify_opts); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to read '"CONFDB_MONITOR_PASSKEY_VERIFICATION"' from confdb: [%d]: %s\n", - ret, sss_strerror(ret)); - goto done; - } + /* Check local sssd.conf setting */ + ret = confdb_get_string(pctx->pam_ctx->rctx->cdb, tmp_ctx, CONFDB_MONITOR_CONF_ENTRY, + CONFDB_MONITOR_PASSKEY_VERIFICATION, NULL, + &verify_opts); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Failed to read '"CONFDB_MONITOR_PASSKEY_VERIFICATION"' from confdb: [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } - ret = read_passkey_conf_verification(tmp_ctx, verify_opts, &verification); - if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, "Unable to parse passkey verificaton options.\n"); - /* Continue anyway */ - } - DEBUG(SSSDBG_TRACE_FUNC, "Passkey verification is being enforced from local configuration\n"); + ret = read_passkey_conf_verification(tmp_ctx, verify_opts, &verification); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to parse passkey verificaton options.\n"); + /* Continue anyway */ } + DEBUG(SSSDBG_TRACE_FUNC, "Passkey verification is being enforced from local configuration\n"); DEBUG(SSSDBG_TRACE_FUNC, "Passkey verification setting [%s]\n", pam_passkey_verification_enum_to_string(verification)); diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c index c4b5512989e..193df234aaa 100644 --- a/src/tests/cmocka/test_pam_srv.c +++ b/src/tests/cmocka/test_pam_srv.c @@ -36,7 +36,6 @@ #include "confdb/confdb.h" #ifdef BUILD_PASSKEY #include "src/responder/pam/pamsrv_passkey.h" -#include "db/sysdb_passkey_user_verification.h" #endif #include "util/crypto/sss_crypto.h" @@ -4690,17 +4689,9 @@ void test_pam_passkey_preauth_found(void **state) struct sysdb_attrs *attrs; const char *passkey = SSSD_TEST_PASSKEY; size_t pk_size; - const char *user_verification = "on"; set_passkey_auth_param(pam_test_ctx->pctx); - /* Add user verification attribute */ - ret = sysdb_domain_update_passkey_user_verification( - pam_test_ctx->tctx->dom->sysdb, - pam_test_ctx->tctx->dom->name, - user_verification); - assert_int_equal(ret, EOK); - mock_input_pam_passkey(pam_test_ctx, "pamuser", "1234", NULL, NULL, SSSD_TEST_PASSKEY); mock_parse_inp("pamuser", NULL, EOK); @@ -4741,17 +4732,9 @@ void test_pam_passkey_auth(void **state) struct sysdb_attrs *attrs; const char *passkey = SSSD_TEST_PASSKEY; size_t pk_size; - const char *user_verification = "on"; set_passkey_auth_param(pam_test_ctx->pctx); - /* Add user verification attribute */ - ret = sysdb_domain_update_passkey_user_verification( - pam_test_ctx->tctx->dom->sysdb, - pam_test_ctx->tctx->dom->name, - user_verification); - assert_int_equal(ret, EOK); - mock_input_pam_passkey(pam_test_ctx, "pamuser", "1234", NULL, NULL, SSSD_TEST_PASSKEY); @@ -4789,17 +4772,9 @@ void test_pam_passkey_pubkey_mapping(void **state) struct sysdb_attrs *attrs; const char *pubkey = SSSD_TEST_PUBKEY; size_t pk_size; - const char *user_verification = "on"; set_passkey_auth_param(pam_test_ctx->pctx); - /* Add user verification attribute */ - ret = sysdb_domain_update_passkey_user_verification( - pam_test_ctx->tctx->dom->sysdb, - pam_test_ctx->tctx->dom->name, - user_verification); - assert_int_equal(ret, EOK); - mock_input_pam_passkey(pam_test_ctx, "pamuser", "1234", NULL, NULL, SSSD_TEST_PASSKEY); mock_parse_inp("pamuser", NULL, EOK); @@ -4835,7 +4810,6 @@ void test_pam_passkey_pubkey_mapping(void **state) void test_pam_passkey_preauth_mapping_multi(void **state) { int ret; - const char *user_verification = "on"; struct sysdb_attrs *attrs; const char *passkey = SSSD_TEST_PASSKEY; const char *pubkey = SSSD_TEST_PUBKEY; @@ -4844,13 +4818,6 @@ void test_pam_passkey_preauth_mapping_multi(void **state) set_passkey_auth_param(pam_test_ctx->pctx); - /* Add user verification attribute */ - ret = sysdb_domain_update_passkey_user_verification( - pam_test_ctx->tctx->dom->sysdb, - pam_test_ctx->tctx->dom->name, - user_verification); - assert_int_equal(ret, EOK); - mock_input_pam_passkey(pam_test_ctx, "pamuser", "1234", NULL, NULL, SSSD_TEST_PASSKEY); From 9a1841e8783e8fae6877165e0bc9bb217cd1ed35 Mon Sep 17 00:00:00 2001 From: Justin Stephenson Date: Mon, 10 Nov 2025 16:03:44 -0500 Subject: [PATCH 4/4] authtok: Set Kerberos passkey PIN to NULL when UV is false MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Iker Pedrosa Reviewed-by: Tomáš Halman --- src/util/authtok-utils.c | 6 +----- src/util/authtok.c | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/util/authtok-utils.c b/src/util/authtok-utils.c index ac3c8bb6631..f6b205e25b6 100644 --- a/src/util/authtok-utils.c +++ b/src/util/authtok-utils.c @@ -122,12 +122,8 @@ errno_t sss_auth_pack_passkey_blob(uint8_t *buf, /* Add provided PIN */ if (pin != NULL) { pin_len = strlen(pin) + 1; - /* User verification is false */ - } else { - pin = ""; - pin_len = 0; + memcpy(buf + len, pin, pin_len); } - memcpy(buf + len, pin, pin_len); return EOK; } diff --git a/src/util/authtok.c b/src/util/authtok.c index ca9a44e73b8..4c2d7ca4d24 100644 --- a/src/util/authtok.c +++ b/src/util/authtok.c @@ -716,12 +716,16 @@ errno_t sss_auth_unpack_passkey_blob(TALLOC_CTX *mem_ctx, } len += strlen(key) + 1; - pin = talloc_strdup(mem_ctx, (const char *) blob + len); - if (pin == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup pin failed.\n"); - talloc_free(prompt); - talloc_free(key); - return ENOMEM; + if ((strcasecmp(prompt, "true") == 0)) { + pin = talloc_strdup(mem_ctx, (const char *) blob + len); + if (pin == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup pin failed.\n"); + talloc_free(prompt); + talloc_free(key); + return ENOMEM; + } + } else { + pin = NULL; } *_prompt = prompt; @@ -858,7 +862,9 @@ errno_t sss_authtok_get_passkey(TALLOC_CTX *mem_ctx, goto done; } - pin_len = strlen(pin); + if (pin != NULL) { + pin_len = strlen(pin); + } *_prompt = prompt; *_key = key;