From ca2c2f36f83cdf4e940d7ac91b5e961e61f8450e Mon Sep 17 00:00:00 2001 From: eabdullin Date: Tue, 12 Nov 2024 10:52:48 +0000 Subject: [PATCH] import CS sssd-2.9.5-4.el9_5.1 --- .gitignore | 2 +- .sssd.metadata | 2 +- ...0001-spec-change-passkey_child-owner.patch | 34 ++ ...sssd-adding-mail-as-case-insensitive.patch | 144 -------- ..._bases-option-to-groups_by_user_send.patch | 154 --------- ...l-to-add-non-posix-user-to-MPG-domai.patch | 58 ++++ ...use-right-memory-context-in-GPO-code.patch | 37 +++ ...context-as-new-member-of-struct-sdap.patch | 194 ----------- ...ever-try-to-upgrade-timestamps-cache.patch | 208 ++++++++++++ ...with-multiple-certs-and-missing-logi.patch | 233 ------------- ...-remove-index-on-dataExpireTimestamp.patch | 147 +++++++++ ...lient-handle-key-value-in-destructor.patch | 50 --- ...fallback-between-responder-questions.patch | 104 ------ ...throw-of-old-authtok-from-another-pa.patch | 115 +++++++ ...Add-fallback-password-change-support.patch | 206 ------------ ..._child-do-not-try-passwords-with-OTP.patch | 178 ++++++++++ .../0008-pam-fix-invalid-if-condition.patch | 30 -- ...missing-optional-2nd-factor-handling.patch | 45 +++ ...5-add-OTP-to-krb5-response-selection.patch | 185 ----------- ...DB_LOCAL_SMARTCARD_AUTH-to-true-but-.patch | 58 ++++ ...nswer_pkinit-use-matching-debug-mess.patch | 119 ------- ...ovide-user_map-when-looking-up-group.patch | 307 ++++++++++++++++++ ...ser_map-when-looking-of-host-groups-.patch | 77 +++++ ...er-and-pre-auth-debug-message-less-i.patch | 67 ---- ..._sss-prefer-Smartcard-authentication.patch | 70 ---- ...-storing-auth-types-for-offline-auth.patch | 57 ---- ...e-hash-to-store-intermediate-results.patch | 218 ------------- ...sions-from-openssl-command-if-there-.patch | 49 --- SPECS/sssd.spec | 63 +++- 29 files changed, 1311 insertions(+), 1900 deletions(-) create mode 100644 SOURCES/0001-spec-change-passkey_child-owner.patch delete mode 100644 SOURCES/0001-sssd-adding-mail-as-case-insensitive.patch delete mode 100644 SOURCES/0002-sdap-add-search_bases-option-to-groups_by_user_send.patch create mode 100644 SOURCES/0002-sysdb-do-not-fail-to-add-non-posix-user-to-MPG-domai.patch create mode 100644 SOURCES/0003-ad-use-right-memory-context-in-GPO-code.patch delete mode 100644 SOURCES/0003-sdap-add-naming_context-as-new-member-of-struct-sdap.patch create mode 100644 SOURCES/0004-TS_CACHE-never-try-to-upgrade-timestamps-cache.patch delete mode 100644 SOURCES/0004-pam-fix-SC-auth-with-multiple-certs-and-missing-logi.patch create mode 100644 SOURCES/0005-SYSDB-remove-index-on-dataExpireTimestamp.patch delete mode 100644 SOURCES/0005-sss-client-handle-key-value-in-destructor.patch delete mode 100644 SOURCES/0006-krb5-Allow-fallback-between-responder-questions.patch create mode 100644 SOURCES/0006-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch delete mode 100644 SOURCES/0007-krb5-Add-fallback-password-change-support.patch create mode 100644 SOURCES/0007-krb5_child-do-not-try-passwords-with-OTP.patch delete mode 100644 SOURCES/0008-pam-fix-invalid-if-condition.patch create mode 100644 SOURCES/0008-pam_sss-add-missing-optional-2nd-factor-handling.patch delete mode 100644 SOURCES/0009-krb5-add-OTP-to-krb5-response-selection.patch create mode 100644 SOURCES/0009-pam-only-set-SYSDB_LOCAL_SMARTCARD_AUTH-to-true-but-.patch delete mode 100644 SOURCES/0010-krb5-make-sure-answer_pkinit-use-matching-debug-mess.patch create mode 100644 SOURCES/0010-sdap-allow-to-provide-user_map-when-looking-up-group.patch create mode 100644 SOURCES/0011-ad-use-default-user_map-when-looking-of-host-groups-.patch delete mode 100644 SOURCES/0011-krb5-make-prompter-and-pre-auth-debug-message-less-i.patch delete mode 100644 SOURCES/0012-pam_sss-prefer-Smartcard-authentication.patch delete mode 100644 SOURCES/0013-pam-fix-storing-auth-types-for-offline-auth.patch delete mode 100644 SOURCES/0014-ad-gpo-use-hash-to-store-intermediate-results.patch delete mode 100644 SOURCES/0015-tests-Drop-extensions-from-openssl-command-if-there-.patch diff --git a/.gitignore b/.gitignore index d510690..76c0ba9 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/sssd-2.9.4.tar.gz +SOURCES/sssd-2.9.5.tar.gz diff --git a/.sssd.metadata b/.sssd.metadata index eaa72f2..7896512 100644 --- a/.sssd.metadata +++ b/.sssd.metadata @@ -1 +1 @@ -574f6cec9ee12dd943e4305286845343ab7bb891 SOURCES/sssd-2.9.4.tar.gz +f6704a9df1303e154ef8526f9f21e2b72879c046 SOURCES/sssd-2.9.5.tar.gz diff --git a/SOURCES/0001-spec-change-passkey_child-owner.patch b/SOURCES/0001-spec-change-passkey_child-owner.patch new file mode 100644 index 0000000..dac8b4b --- /dev/null +++ b/SOURCES/0001-spec-change-passkey_child-owner.patch @@ -0,0 +1,34 @@ +From ee8de7e404ba65062e0b373f2badc0475835bbde Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Tue, 11 Jun 2024 15:57:23 +0200 +Subject: [PATCH] spec: change passkey_child owner + +passkey_child owner was incorrectly set to $sssd_user:$sssd_user, when +it should be root:root. Correcting it. + +Fixes: 30daa0ccdae5 ("spec: update to include passkey") + +Signed-off-by: Iker Pedrosa + +Reviewed-by: Alexey Tikhonov +(cherry picked from commit bb72b53d3a222f016d882853a619bd74c237edf9) +--- + contrib/sssd.spec.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in +index 03171a872..3735d4f06 100644 +--- a/contrib/sssd.spec.in ++++ b/contrib/sssd.spec.in +@@ -998,7 +998,7 @@ done + + %if %{build_passkey} + %files passkey +-%attr(755,%{sssd_user},%{sssd_user}) %{_libexecdir}/%{servicename}/passkey_child ++%{_libexecdir}/%{servicename}/passkey_child + %{_libdir}/%{name}/modules/sssd_krb5_passkey_plugin.so + %{_datadir}/sssd/krb5-snippets/sssd_enable_passkey + %config(noreplace) %{_sysconfdir}/krb5.conf.d/sssd_enable_passkey +-- +2.44.0 + diff --git a/SOURCES/0001-sssd-adding-mail-as-case-insensitive.patch b/SOURCES/0001-sssd-adding-mail-as-case-insensitive.patch deleted file mode 100644 index 1e12d0b..0000000 --- a/SOURCES/0001-sssd-adding-mail-as-case-insensitive.patch +++ /dev/null @@ -1,144 +0,0 @@ -From dd0f63246aa75d5f53b44cbc185e88833e79976e Mon Sep 17 00:00:00 2001 -From: Andre Boscatto -Date: Wed, 7 Feb 2024 12:28:28 +0100 -Subject: [PATCH] sssd: adding mail as case insensitive -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Resolves: https://github.com/SSSD/sssd/issues/7173 - -Reviewed-by: Iker Pedrosa -Reviewed-by: Tomáš Halman -(cherry picked from commit 945cebcf72ef53ea0368f19c09e710f7fff11b51) ---- - src/db/sysdb_init.c | 7 ++++++ - src/db/sysdb_private.h | 5 +++- - src/db/sysdb_upgrade.c | 56 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 67 insertions(+), 1 deletion(-) - -diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c -index c2ea6c369..38a9cd64a 100644 ---- a/src/db/sysdb_init.c -+++ b/src/db/sysdb_init.c -@@ -603,6 +603,13 @@ static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx, - } - } - -+ if (strcmp(version, SYSDB_VERSION_0_23) == 0) { -+ ret = sysdb_upgrade_23(sysdb, &version); -+ if (ret != EOK) { -+ goto done; -+ } -+ } -+ - ret = EOK; - done: - sysdb->ldb = save_ldb; -diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h -index 1f55007bc..63f7b5601 100644 ---- a/src/db/sysdb_private.h -+++ b/src/db/sysdb_private.h -@@ -23,6 +23,7 @@ - #ifndef __INT_SYS_DB_H__ - #define __INT_SYS_DB_H__ - -+#define SYSDB_VERSION_0_24 "0.24" - #define SYSDB_VERSION_0_23 "0.23" - #define SYSDB_VERSION_0_22 "0.22" - #define SYSDB_VERSION_0_21 "0.21" -@@ -47,7 +48,7 @@ - #define SYSDB_VERSION_0_2 "0.2" - #define SYSDB_VERSION_0_1 "0.1" - --#define SYSDB_VERSION SYSDB_VERSION_0_23 -+#define SYSDB_VERSION SYSDB_VERSION_0_24 - - #define SYSDB_BASE_LDIF \ - "dn: @ATTRIBUTES\n" \ -@@ -60,6 +61,7 @@ - "objectclass: CASE_INSENSITIVE\n" \ - "ipHostNumber: CASE_INSENSITIVE\n" \ - "ipNetworkNumber: CASE_INSENSITIVE\n" \ -+ "mail: CASE_INSENSITIVE\n" \ - "\n" \ - "dn: @INDEXLIST\n" \ - "@IDXATTR: cn\n" \ -@@ -191,6 +193,7 @@ int sysdb_upgrade_19(struct sysdb_ctx *sysdb, const char **ver); - int sysdb_upgrade_20(struct sysdb_ctx *sysdb, const char **ver); - int sysdb_upgrade_21(struct sysdb_ctx *sysdb, const char **ver); - int sysdb_upgrade_22(struct sysdb_ctx *sysdb, const char **ver); -+int sysdb_upgrade_23(struct sysdb_ctx *sysdb, const char **ver); - - int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver); - -diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c -index 346a1cb0b..56083e6be 100644 ---- a/src/db/sysdb_upgrade.c -+++ b/src/db/sysdb_upgrade.c -@@ -2718,6 +2718,62 @@ done: - return ret; - } - -+int sysdb_upgrade_23(struct sysdb_ctx *sysdb, const char **ver) -+{ -+ TALLOC_CTX *tmp_ctx; -+ int ret; -+ struct ldb_message *msg; -+ struct upgrade_ctx *ctx; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (!tmp_ctx) { -+ return ENOMEM; -+ } -+ -+ ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_24, &ctx); -+ if (ret) { -+ return ret; -+ } -+ -+ /* Add new indexes */ -+ msg = ldb_msg_new(tmp_ctx); -+ if (!msg) { -+ ret = ENOMEM; -+ goto done; -+ } -+ msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); -+ if (!msg->dn) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ /* Case insensitive search for mail */ -+ ret = ldb_msg_add_empty(msg, SYSDB_USER_EMAIL, LDB_FLAG_MOD_ADD, NULL); -+ if (ret != LDB_SUCCESS) { -+ ret = ENOMEM; -+ goto done; -+ } -+ ret = ldb_msg_add_string(msg, SYSDB_USER_EMAIL, "CASE_INSENSITIVE"); -+ if (ret != LDB_SUCCESS) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = ldb_modify(sysdb->ldb, msg); -+ if (ret != LDB_SUCCESS) { -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ -+ /* conversion done, update version number */ -+ ret = update_version(ctx); -+ -+done: -+ ret = finish_upgrade(ret, &ctx, ver); -+ talloc_free(tmp_ctx); -+ return ret; -+} -+ - int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver) - { - struct upgrade_ctx *ctx; --- -2.41.0 - diff --git a/SOURCES/0002-sdap-add-search_bases-option-to-groups_by_user_send.patch b/SOURCES/0002-sdap-add-search_bases-option-to-groups_by_user_send.patch deleted file mode 100644 index e7f048f..0000000 --- a/SOURCES/0002-sdap-add-search_bases-option-to-groups_by_user_send.patch +++ /dev/null @@ -1,154 +0,0 @@ -From a7621a5b464af7a3c8409dcbde038b35fee2c895 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 23 Jan 2024 13:47:53 +0100 -Subject: [PATCH 2/3] sdap: add search_bases option to groups_by_user_send() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -AD handles users and computer objects very similar and so does SSSD's -GPO code when lookup up the host's group-memberships. But users and -computers might be stored in different sub-tree of the AD LDAP tree and -if a dedicated user search base is given with the ldap_user_search_base -option in sssd.conf the host object might be in a different sub-tree. To -make sure the host can still be found this patch uses the base DN of -the LDAP tree when searching for hosts in the GPO code. - -Resolves: https://github.com/SSSD/sssd/issues/5708 - -Reviewed-by: Alejandro López -Reviewed-by: Tomáš Halman -(cherry picked from commit 29a77c6e79020d7e8cb474b4d3b394d390eba196) ---- - src/providers/ad/ad_gpo.c | 10 ++++++++++ - src/providers/ldap/ldap_common.h | 1 + - src/providers/ldap/ldap_id.c | 6 +++++- - src/providers/ldap/sdap_async.h | 1 + - src/providers/ldap/sdap_async_initgroups.c | 4 +++- - 5 files changed, 20 insertions(+), 2 deletions(-) - -diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c -index 94959c36b..b0ee3e616 100644 ---- a/src/providers/ad/ad_gpo.c -+++ b/src/providers/ad/ad_gpo.c -@@ -2091,6 +2091,7 @@ ad_gpo_connect_done(struct tevent_req *subreq) - char *server_uri; - LDAPURLDesc *lud; - struct sdap_domain *sdom; -+ struct sdap_search_base **search_bases; - - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct ad_gpo_access_state); -@@ -2184,9 +2185,18 @@ ad_gpo_connect_done(struct tevent_req *subreq) - goto done; - } - -+ ret = common_parse_search_base(state, sdom->basedn, state->ldb_ctx, -+ "AD_HOSTS", NULL, &search_bases); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Failed to create dedicated search base for host lookups, " -+ "trying with user search base."); -+ } -+ - subreq = groups_by_user_send(state, state->ev, - state->access_ctx->ad_id_ctx->sdap_id_ctx, - sdom, state->conn, -+ search_bases, - state->host_fqdn, - BE_FILTER_NAME, - NULL, -diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h -index 7159d6356..2c984ef50 100644 ---- a/src/providers/ldap/ldap_common.h -+++ b/src/providers/ldap/ldap_common.h -@@ -304,6 +304,7 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, - struct sdap_id_ctx *ctx, - struct sdap_domain *sdom, - struct sdap_id_conn_ctx *conn, -+ struct sdap_search_base **search_bases, - const char *filter_value, - int filter_type, - const char *extra_value, -diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c -index da54816bd..b3ea2333f 100644 ---- a/src/providers/ldap/ldap_id.c -+++ b/src/providers/ldap/ldap_id.c -@@ -1139,6 +1139,7 @@ struct groups_by_user_state { - struct sdap_id_op *op; - struct sysdb_ctx *sysdb; - struct sss_domain_info *domain; -+ struct sdap_search_base **search_bases; - - const char *filter_value; - int filter_type; -@@ -1160,6 +1161,7 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, - struct sdap_id_ctx *ctx, - struct sdap_domain *sdom, - struct sdap_id_conn_ctx *conn, -+ struct sdap_search_base **search_bases, - const char *filter_value, - int filter_type, - const char *extra_value, -@@ -1192,6 +1194,7 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, - state->extra_value = extra_value; - state->domain = sdom->dom; - state->sysdb = sdom->dom->sysdb; -+ state->search_bases = search_bases; - - if (state->domain->type == DOM_TYPE_APPLICATION || set_non_posix) { - state->non_posix = true; -@@ -1254,6 +1257,7 @@ static void groups_by_user_connect_done(struct tevent_req *subreq) - sdap_id_op_handle(state->op), - state->ctx, - state->conn, -+ state->search_bases, - state->filter_value, - state->filter_type, - state->extra_value, -@@ -1449,7 +1453,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, - } - - subreq = groups_by_user_send(state, be_ctx->ev, id_ctx, -- sdom, conn, -+ sdom, conn, NULL, - ar->filter_value, - ar->filter_type, - ar->extra_value, -diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h -index 5458d21f1..89245f41f 100644 ---- a/src/providers/ldap/sdap_async.h -+++ b/src/providers/ldap/sdap_async.h -@@ -158,6 +158,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, - struct sdap_handle *sh, - struct sdap_id_ctx *id_ctx, - struct sdap_id_conn_ctx *conn, -+ struct sdap_search_base **search_bases, - const char *name, - int filter_type, - const char *extra_value, -diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c -index 97be594a3..fb3d8fe24 100644 ---- a/src/providers/ldap/sdap_async_initgroups.c -+++ b/src/providers/ldap/sdap_async_initgroups.c -@@ -2732,6 +2732,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, - struct sdap_handle *sh, - struct sdap_id_ctx *id_ctx, - struct sdap_id_conn_ctx *conn, -+ struct sdap_search_base **search_bases, - const char *filter_value, - int filter_type, - const char *extra_value, -@@ -2764,7 +2765,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, - state->orig_user = NULL; - state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT); - state->user_base_iter = 0; -- state->user_search_bases = sdom->user_search_bases; -+ state->user_search_bases = (search_bases == NULL) ? sdom->user_search_bases -+ : search_bases; - if (!state->user_search_bases) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Initgroups lookup request without a user search base\n"); --- -2.41.0 - diff --git a/SOURCES/0002-sysdb-do-not-fail-to-add-non-posix-user-to-MPG-domai.patch b/SOURCES/0002-sysdb-do-not-fail-to-add-non-posix-user-to-MPG-domai.patch new file mode 100644 index 0000000..503738e --- /dev/null +++ b/SOURCES/0002-sysdb-do-not-fail-to-add-non-posix-user-to-MPG-domai.patch @@ -0,0 +1,58 @@ +From d234cf5d6e793daf2c96856887acb641c4dff407 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 14 Jun 2024 16:10:34 +0200 +Subject: [PATCH] sysdb: do not fail to add non-posix user to MPG domain +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +SSSD does not handle the root user (UID==0) and treats all accounts with +UID 0 as non-Posix accounts. The primary GID of those accounts is 0 as +well and as a result for those accounts in MPG domains the check for a +collisions of the primary GID should be skipped. The current code might +e.g. cause issues during GPO evaluation when adding a host account into +the cache which does not have any UID or GID set in AD and SSSD is +configured to read UID and GID from AD. + +Resolves: https://github.com/SSSD/sssd/issues/7451 + +Reviewed-by: Alejandro López +Reviewed-by: Tomáš Halman +(cherry picked from commit 986bb726202e69b05f861c14c3a220379baf9bd1) +--- + src/db/sysdb_ops.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c +index 0f62e3b1a..76f4580aa 100644 +--- a/src/db/sysdb_ops.c ++++ b/src/db/sysdb_ops.c +@@ -1914,15 +1914,17 @@ int sysdb_add_user(struct sss_domain_info *domain, + goto done; + } + +- ret = sysdb_search_group_by_gid(tmp_ctx, domain, uid, NULL, &msg); +- if (ret != ENOENT) { +- if (ret == EOK) { +- DEBUG(SSSDBG_OP_FAILURE, +- "Group with GID [%"SPRIgid"] already exists in an " +- "MPG domain\n", gid); +- ret = EEXIST; ++ if (uid != 0) { /* uid == 0 means non-POSIX object */ ++ ret = sysdb_search_group_by_gid(tmp_ctx, domain, uid, NULL, &msg); ++ if (ret != ENOENT) { ++ if (ret == EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Group with GID [%"SPRIgid"] already exists in an " ++ "MPG domain\n", uid); ++ ret = EEXIST; ++ } ++ goto done; + } +- goto done; + } + } + +-- +2.44.0 + diff --git a/SOURCES/0003-ad-use-right-memory-context-in-GPO-code.patch b/SOURCES/0003-ad-use-right-memory-context-in-GPO-code.patch new file mode 100644 index 0000000..29401e6 --- /dev/null +++ b/SOURCES/0003-ad-use-right-memory-context-in-GPO-code.patch @@ -0,0 +1,37 @@ +From 723a30b45ba4cbd9a4913fd37d68e392dcfc16ba Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 7 Jun 2024 18:04:00 +0200 +Subject: [PATCH] ad: use right memory context in GPO code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The original primary SID is allocated on a temporary context and must be +move to be longer living one to still be available when the SID is +evaluated later in the code. + +Resolves: https://github.com/SSSD/sssd/issues/7411 + +Reviewed-by: Alexey Tikhonov +Reviewed-by: Tomáš Halman +(cherry picked from commit b25e510ad60f6ce0b57063cce648c3aa48b21241) +--- + src/providers/ad/ad_gpo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c +index b879b0a08..ed664ec83 100644 +--- a/src/providers/ad/ad_gpo.c ++++ b/src/providers/ad/ad_gpo.c +@@ -711,7 +711,7 @@ ad_gpo_get_sids(TALLOC_CTX *mem_ctx, + } + group_sids[i++] = talloc_strdup(group_sids, AD_AUTHENTICATED_USERS_SID); + if (orig_gid_sid != NULL) { +- group_sids[i++] = orig_gid_sid; ++ group_sids[i++] = talloc_steal(group_sids, orig_gid_sid); + } + group_sids[i] = NULL; + +-- +2.44.0 + diff --git a/SOURCES/0003-sdap-add-naming_context-as-new-member-of-struct-sdap.patch b/SOURCES/0003-sdap-add-naming_context-as-new-member-of-struct-sdap.patch deleted file mode 100644 index a7ff19e..0000000 --- a/SOURCES/0003-sdap-add-naming_context-as-new-member-of-struct-sdap.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 6a8e60df84d5d2565bec36be19c2def25a6ece1f Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 24 Jan 2024 14:21:12 +0100 -Subject: [PATCH 3/3] sdap: add naming_context as new member of struct - sdap_domain -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The naming_context could be a more reliable source than basedn for the -actual base DN because basedn is set very early from the domain name -given in sssd.conf. Although it is recommended to use the fully -qualified DNS domain name here it is not required. As a result basedn -might not reflect the actual based DN of the LDAP server. Also pure LDAP -server (i.e. not AD or FreeIPA) might use different schemes to set the -base DN which will not be based on the DNS domain of the LDAP server. - -Resolves: https://github.com/SSSD/sssd/issues/5708 - -Reviewed-by: Alejandro López -Reviewed-by: Tomáš Halman -(cherry picked from commit a153f13f296401247a862df2b99048bb1bbb8e2e) ---- - src/providers/ad/ad_gpo.c | 6 ++++-- - src/providers/ldap/sdap.c | 36 +++++++++++++----------------------- - src/providers/ldap/sdap.h | 11 +++++++++++ - 3 files changed, 28 insertions(+), 25 deletions(-) - -diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c -index b0ee3e616..3d1ad39c7 100644 ---- a/src/providers/ad/ad_gpo.c -+++ b/src/providers/ad/ad_gpo.c -@@ -2185,8 +2185,10 @@ ad_gpo_connect_done(struct tevent_req *subreq) - goto done; - } - -- ret = common_parse_search_base(state, sdom->basedn, state->ldb_ctx, -- "AD_HOSTS", NULL, &search_bases); -+ ret = common_parse_search_base(state, -+ sdom->naming_context == NULL ? sdom->basedn -+ : sdom->naming_context, -+ state->ldb_ctx, "AD_HOSTS", NULL, &search_bases); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to create dedicated search base for host lookups, " -diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c -index f5637c5fb..956eba93a 100644 ---- a/src/providers/ldap/sdap.c -+++ b/src/providers/ldap/sdap.c -@@ -1252,19 +1252,10 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, - struct sdap_domain *sdom) - { - int ret; -- char *naming_context = NULL; - -- if (!sdom->search_bases -- || !sdom->user_search_bases -- || !sdom->group_search_bases -- || !sdom->netgroup_search_bases -- || !sdom->host_search_bases -- || !sdom->sudo_search_bases -- || !sdom->iphost_search_bases -- || !sdom->ipnetwork_search_bases -- || !sdom->autofs_search_bases) { -- naming_context = get_naming_context(opts->basic, rootdse); -- if (naming_context == NULL) { -+ if (!sdom->naming_context) { -+ sdom->naming_context = get_naming_context(sdom, rootdse); -+ if (sdom->naming_context == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "get_naming_context failed.\n"); - - /* This has to be non-fatal, since some servers offer -@@ -1280,7 +1271,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, - if (!sdom->search_bases) { - ret = sdap_set_search_base(opts, sdom, - SDAP_SEARCH_BASE, -- naming_context); -+ sdom->naming_context); - if (ret != EOK) goto done; - } - -@@ -1288,7 +1279,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, - if (!sdom->user_search_bases) { - ret = sdap_set_search_base(opts, sdom, - SDAP_USER_SEARCH_BASE, -- naming_context); -+ sdom->naming_context); - if (ret != EOK) goto done; - } - -@@ -1296,7 +1287,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, - if (!sdom->group_search_bases) { - ret = sdap_set_search_base(opts, sdom, - SDAP_GROUP_SEARCH_BASE, -- naming_context); -+ sdom->naming_context); - if (ret != EOK) goto done; - } - -@@ -1304,7 +1295,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, - if (!sdom->netgroup_search_bases) { - ret = sdap_set_search_base(opts, sdom, - SDAP_NETGROUP_SEARCH_BASE, -- naming_context); -+ sdom->naming_context); - if (ret != EOK) goto done; - } - -@@ -1312,7 +1303,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, - if (!sdom->host_search_bases) { - ret = sdap_set_search_base(opts, sdom, - SDAP_HOST_SEARCH_BASE, -- naming_context); -+ sdom->naming_context); - if (ret != EOK) goto done; - } - -@@ -1320,7 +1311,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, - if (!sdom->sudo_search_bases) { - ret = sdap_set_search_base(opts, sdom, - SDAP_SUDO_SEARCH_BASE, -- naming_context); -+ sdom->naming_context); - if (ret != EOK) goto done; - } - -@@ -1328,7 +1319,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, - if (!sdom->service_search_bases) { - ret = sdap_set_search_base(opts, sdom, - SDAP_SERVICE_SEARCH_BASE, -- naming_context); -+ sdom->naming_context); - if (ret != EOK) goto done; - } - -@@ -1336,7 +1327,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, - if (!sdom->autofs_search_bases) { - ret = sdap_set_search_base(opts, sdom, - SDAP_AUTOFS_SEARCH_BASE, -- naming_context); -+ sdom->naming_context); - if (ret != EOK) goto done; - } - -@@ -1344,7 +1335,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, - if (!sdom->iphost_search_bases) { - ret = sdap_set_search_base(opts, sdom, - SDAP_IPHOST_SEARCH_BASE, -- naming_context); -+ sdom->naming_context); - if (ret != EOK) goto done; - } - -@@ -1352,14 +1343,13 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, - if (!sdom->ipnetwork_search_bases) { - ret = sdap_set_search_base(opts, sdom, - SDAP_IPNETWORK_SEARCH_BASE, -- naming_context); -+ sdom->naming_context); - if (ret != EOK) goto done; - } - - ret = EOK; - - done: -- talloc_free(naming_context); - return ret; - } - -diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h -index 161bc5c26..103d50ed4 100644 ---- a/src/providers/ldap/sdap.h -+++ b/src/providers/ldap/sdap.h -@@ -454,6 +454,17 @@ struct sdap_domain { - - char *basedn; - -+ /* The naming_context could be a more reliable source than basedn for the -+ * actual base DN because basedn is set very early from the domain name -+ * given in sssd.conf. Although it is recommended to use the fully -+ * qualified DNS domain name here it is not required. As a result basedn -+ * might not reflect the actual based DN of the LDAP server. Also pure -+ * LDAP server (i.e. not AD or FreeIPA) might use different schemes to set -+ * the base DN which will not be based on the DNS domain of the LDAP -+ * server. naming_context might be NULL even after connection to an LDAP -+ * server. */ -+ char *naming_context; -+ - struct sdap_search_base **search_bases; - struct sdap_search_base **user_search_bases; - struct sdap_search_base **group_search_bases; --- -2.41.0 - diff --git a/SOURCES/0004-TS_CACHE-never-try-to-upgrade-timestamps-cache.patch b/SOURCES/0004-TS_CACHE-never-try-to-upgrade-timestamps-cache.patch new file mode 100644 index 0000000..60f5383 --- /dev/null +++ b/SOURCES/0004-TS_CACHE-never-try-to-upgrade-timestamps-cache.patch @@ -0,0 +1,208 @@ +From 09b23e78806d8930c3f1b9e411dc8cf464c18998 Mon Sep 17 00:00:00 2001 +From: Alexey Tikhonov +Date: Tue, 16 Jul 2024 13:08:02 +0200 +Subject: [PATCH 4/5] TS_CACHE: never try to upgrade timestamps cache +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It's easier and more consistent to recreate it instead. + +This is a natural extension of 3b67fc6488ac10ca13561d9032f59951f82203e6 + +Reviewed-by: Alejandro López +Reviewed-by: Sumit Bose +Reviewed-by: Tomáš Halman +(cherry picked from commit fc2a26c306e51b66680aef85aa0d2c41d8049a7f) +--- + src/db/sysdb_init.c | 103 +---------------------------------------- + src/db/sysdb_upgrade.c | 45 ------------------ + 2 files changed, 1 insertion(+), 147 deletions(-) + +diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c +index 38a9cd64a..a1d02d49c 100644 +--- a/src/db/sysdb_init.c ++++ b/src/db/sysdb_init.c +@@ -376,57 +376,6 @@ static errno_t sysdb_cache_create_empty(struct ldb_context *ldb, + return EOK; + } + +-static errno_t sysdb_ts_cache_upgrade(TALLOC_CTX *mem_ctx, +- struct sysdb_ctx *sysdb, +- struct ldb_context *ldb, +- struct sss_domain_info *domain, +- const char *cur_version, +- const char **_new_version) +-{ +- errno_t ret; +- TALLOC_CTX *tmp_ctx; +- const char *version; +- struct ldb_context *save_ldb; +- +- tmp_ctx = talloc_new(NULL); +- if (tmp_ctx == NULL) { +- return ENOMEM; +- } +- +- /* The upgrade process depends on having ldb around, yet the upgrade +- * function shouldn't set the ldb pointer, only the connect function +- * should after it's successful. To avoid hard refactoring, save the +- * ldb pointer here and restore in the 'done' handler +- */ +- save_ldb = sysdb->ldb; +- sysdb->ldb = ldb; +- +- version = talloc_strdup(tmp_ctx, cur_version); +- if (version == NULL) { +- ret = ENOMEM; +- goto done; +- } +- +- DEBUG(SSSDBG_CONF_SETTINGS, +- "Upgrading timstamp cache of DB [%s] from version: %s\n", +- domain->name, version); +- +- if (strcmp(version, SYSDB_TS_VERSION_0_1) == 0) { +- ret = sysdb_ts_upgrade_01(sysdb, &version); +- if (ret != EOK) { +- goto done; +- } +- } +- +- ret = EOK; +- +-done: +- sysdb->ldb = save_ldb; +- *_new_version = version; +- talloc_free(tmp_ctx); +- return ret; +-} +- + static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sysdb_dom_upgrade_ctx *upgrade_ctx, +@@ -884,56 +833,6 @@ static int sysdb_timestamp_cache_connect(struct sysdb_ctx *sysdb, + } + + ret = sysdb_ts_cache_connect(tmp_ctx, sysdb, domain, &ldb, &version); +- switch (ret) { +- case ERR_SYSDB_VERSION_TOO_OLD: +- if (upgrade_ctx == NULL) { +- DEBUG(SSSDBG_FATAL_FAILURE, +- "DB version too old [%s], expected [%s] for domain %s!\n", +- version, SYSDB_VERSION, domain->name); +- break; +- } +- +- ret = sysdb_ts_cache_upgrade(tmp_ctx, sysdb, ldb, domain, version, +- &version); +- if (ret != EOK) { +- DEBUG(SSSDBG_MINOR_FAILURE, +- "Could not upgrade the timestamp ldb file (%d) (%s)\n", +- ret, sss_strerror(ret)); +- break; +- } +- +- /* The version should now match SYSDB_VERSION. +- * If not, it means we didn't match any of the +- * known older versions. The DB might be +- * corrupt or generated by a newer version of +- * SSSD. +- */ +- ret = sysdb_version_check(SYSDB_TS_VERSION, version); +- if (ret == EOK) { +- /* The cache has been upgraded. +- * We need to reopen the LDB to ensure that +- * any changes made above take effect. +- */ +- ret = sysdb_ldb_reconnect(tmp_ctx, +- sysdb->ldb_ts_file, +- LDB_FLG_NOSYNC, +- &ldb); +- if (ret != EOK) { +- DEBUG(SSSDBG_MINOR_FAILURE, +- "Could not reopen the timestamp ldb file (%d) (%s)\n", +- ret, sss_strerror(ret)); +- } +- } +- break; +- case ERR_SYSDB_VERSION_TOO_NEW: +- DEBUG(SSSDBG_MINOR_FAILURE, +- "DB version too new [%s], expected [%s] for domain %s!\n", +- version, SYSDB_TS_VERSION, domain->name); +- break; +- default: +- break; +- } +- + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "The timestamps cache could not be opened. " +@@ -953,7 +852,7 @@ static int sysdb_timestamp_cache_connect(struct sysdb_ctx *sysdb, + ret = sysdb_ts_cache_connect(tmp_ctx, sysdb, domain, &ldb, &version); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, +- "Could not delete the timestamp ldb file (%d) (%s)\n", ++ "sysdb_ts_cache_connect() failed after cache deletion [%d]: %s\n", + ret, sss_strerror(ret)); + } + } +diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c +index 328bd2962..37c0007cb 100644 +--- a/src/db/sysdb_upgrade.c ++++ b/src/db/sysdb_upgrade.c +@@ -2774,51 +2774,6 @@ done: + return ret; + } + +-int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver) +-{ +- struct upgrade_ctx *ctx; +- errno_t ret; +- struct ldb_message *msg = NULL; +- +- ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_TS_VERSION_0_2, &ctx); +- if (ret) { +- return ret; +- } +- +- /* Remove @IDXONE from index */ +- talloc_free(msg); +- msg = ldb_msg_new(ctx); +- if (msg == NULL) { +- ret = ENOMEM; +- goto done; +- } +- +- msg->dn = ldb_dn_new(msg, sysdb->ldb, "@INDEXLIST"); +- if (msg->dn == NULL) { +- ret = ENOMEM; +- goto done; +- } +- +- ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_DELETE, NULL); +- if (ret != LDB_SUCCESS) { +- ret = ENOMEM; +- goto done; +- } +- +- ret = ldb_modify(sysdb->ldb, msg); +- if (ret != LDB_SUCCESS) { +- ret = sysdb_error_to_errno(ret); +- goto done; +- } +- +- /* conversion done, update version number */ +- ret = update_version(ctx); +- +-done: +- ret = finish_upgrade(ret, &ctx, ver); +- return ret; +-} +- + /* + * Example template for future upgrades. + * Copy and change version numbers as appropriate. +-- +2.45.2 + diff --git a/SOURCES/0004-pam-fix-SC-auth-with-multiple-certs-and-missing-logi.patch b/SOURCES/0004-pam-fix-SC-auth-with-multiple-certs-and-missing-logi.patch deleted file mode 100644 index 7ba9ba5..0000000 --- a/SOURCES/0004-pam-fix-SC-auth-with-multiple-certs-and-missing-logi.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 50077c3255177fe1b01837fbe31a7f8fd47dee74 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 18 Jan 2024 13:08:17 +0100 -Subject: [PATCH] pam: fix SC auth with multiple certs and missing login name - -While introducing the local_auth_policy option a quite specific use-case -was not covered correctly. If there are multiple matching certificates -on the Smartcard, 'local_auth_policy = only' is set and GDM's Smartcard -mode was used for login, i.e. there is no user name given and the user -has to be derived from the certificate used for login, authentication -failed. The main reason for the failure is that in this case the -Smartcard interaction and the user mapping has to be done first to -determine the user before local_auth_policy is evaluated. As a result -when checking if the authentication can be finished the request was in -an unexpected state because the indicator for local Smartcard -authentication was not enabled. - -Resolves: https://github.com/SSSD/sssd/issues/7109 - -Reviewed-by: Justin Stephenson -Reviewed-by: Scott Poore -(cherry picked from commit 44ec3e4638b0c6f7f45a3390a28c2e8745d52bc3) ---- - src/responder/pam/pamsrv.h | 10 ++++ - src/responder/pam/pamsrv_cmd.c | 17 +++++-- - src/tests/intg/Makefile.am | 2 + - src/tests/intg/test_pam_responder.py | 74 +++++++++++++++++++++++++++- - 4 files changed, 96 insertions(+), 7 deletions(-) - -diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h -index 7013a8edd..618836189 100644 ---- a/src/responder/pam/pamsrv.h -+++ b/src/responder/pam/pamsrv.h -@@ -93,7 +93,17 @@ struct pam_auth_req { - struct ldb_message *user_obj; - struct cert_auth_info *cert_list; - struct cert_auth_info *current_cert; -+ /* Switched to 'true' if the backend indicates that it cannot handle -+ * Smartcard authentication, but Smartcard authentication is -+ * possible and local Smartcard authentication is allowed. */ - bool cert_auth_local; -+ /* Switched to 'true' if authentication (not pre-authentication) was -+ * started without a login name and the name had to be lookup up with the -+ * certificate used for authentication. Since reading the certificate from -+ * the Smartcard already involves the PIN validation in this case there -+ * would be no need for an additional Smartcard interaction if only local -+ * Smartcard authentication is possible. */ -+ bool initial_cert_auth_successful; - - bool passkey_data_exists; - uint32_t client_id_num; -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index c23ea7ba4..a7c181733 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -2200,8 +2200,8 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - ret = ENOENT; - goto done; - } -- -- if (cert_count > 1) { -+ /* Multiple certificates are only expected during pre-auth */ -+ if (cert_count > 1 && preq->pd->cmd == SSS_PAM_PREAUTH) { - for (preq->current_cert = preq->cert_list; - preq->current_cert != NULL; - preq->current_cert = sss_cai_get_next(preq->current_cert)) { -@@ -2285,7 +2285,9 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - } - - /* If logon_name was not given during authentication add a -- * SSS_PAM_CERT_INFO message to send the name to the caller. */ -+ * SSS_PAM_CERT_INFO message to send the name to the caller. -+ * Additionally initial_cert_auth_successful is set to -+ * indicate that the user is already authenticated. */ - if (preq->pd->cmd == SSS_PAM_AUTHENTICATE - && preq->pd->logon_name == NULL) { - ret = add_pam_cert_response(preq->pd, -@@ -2297,6 +2299,8 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL; - goto done; - } -+ -+ preq->initial_cert_auth_successful = true; - } - - /* cert_user will be returned to the PAM client as user name, so -@@ -2851,12 +2855,15 @@ static void pam_dom_forwarder(struct pam_auth_req *preq) - if (found) { - if (local_policy != NULL && strcasecmp(local_policy, "only") == 0) { - talloc_free(tmp_ctx); -- DEBUG(SSSDBG_IMPORTANT_INFO, "Local auth only set, skipping online auth\n"); -+ DEBUG(SSSDBG_IMPORTANT_INFO, -+ "Local auth only set and matching certificate was found, " -+ "skipping online auth\n"); - if (preq->pd->cmd == SSS_PAM_PREAUTH) { - preq->pd->pam_status = PAM_SUCCESS; - } else if (preq->pd->cmd == SSS_PAM_AUTHENTICATE - && IS_SC_AUTHTOK(preq->pd->authtok) -- && preq->cert_auth_local) { -+ && (preq->cert_auth_local -+ || preq->initial_cert_auth_successful)) { - preq->pd->pam_status = PAM_SUCCESS; - preq->callback = pam_reply; - } -diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am -index 3866d3ca6..0cfd268dc 100644 ---- a/src/tests/intg/Makefile.am -+++ b/src/tests/intg/Makefile.am -@@ -199,6 +199,7 @@ clean-local: - - PAM_CERT_DB_PATH="$(abs_builddir)/../test_CA/SSSD_test_CA.pem" - SOFTHSM2_CONF="$(abs_builddir)/../test_CA/softhsm2_one.conf" -+SOFTHSM2_TWO_CONF="$(abs_builddir)/../test_CA/softhsm2_two.conf" - - intgcheck-installed: config.py passwd group pam_sss_service pam_sss_alt_service pam_sss_sc_required pam_sss_try_sc pam_sss_allow_missing_name pam_sss_domains sss_netgroup_thread_test - pipepath="$(DESTDIR)$(pipepath)"; \ -@@ -233,6 +234,7 @@ intgcheck-installed: config.py passwd group pam_sss_service pam_sss_alt_service - PAM_CERT_DB_PATH=$(PAM_CERT_DB_PATH) \ - ABS_SRCDIR=$(abs_srcdir) \ - SOFTHSM2_CONF=$(SOFTHSM2_CONF) \ -+ SOFTHSM2_TWO_CONF=$(SOFTHSM2_TWO_CONF) \ - KCM_RENEW=$(KCM_RENEW) \ - FILES_PROVIDER=$(FILES_PROVIDER) \ - DBUS_SOCK_DIR="$(DESTDIR)$(runstatedir)/dbus/" \ -diff --git a/src/tests/intg/test_pam_responder.py b/src/tests/intg/test_pam_responder.py -index 1fc3937e6..0fbf8065e 100644 ---- a/src/tests/intg/test_pam_responder.py -+++ b/src/tests/intg/test_pam_responder.py -@@ -168,7 +168,7 @@ def format_pam_cert_auth_conf(config, provider): - {provider.p} - - [certmap/auth_only/user1] -- matchrule = .*CN=SSSD test cert 0001.* -+ matchrule = .*CN=SSSD test cert 000[12].* - """).format(**locals()) - - -@@ -201,7 +201,7 @@ def format_pam_cert_auth_conf_name_format(config, provider): - {provider.p} - - [certmap/auth_only/user1] -- matchrule = .*CN=SSSD test cert 0001.* -+ matchrule = .*CN=SSSD test cert 000[12].* - """).format(**locals()) - - -@@ -380,6 +380,28 @@ def simple_pam_cert_auth_no_cert(request, passwd_ops_setup): - return None - - -+@pytest.fixture -+def simple_pam_cert_auth_two_certs(request, passwd_ops_setup): -+ """Setup SSSD with pam_cert_auth=True""" -+ config.PAM_CERT_DB_PATH = os.environ['PAM_CERT_DB_PATH'] -+ -+ old_softhsm2_conf = os.environ['SOFTHSM2_CONF'] -+ softhsm2_two_conf = os.environ['SOFTHSM2_TWO_CONF'] -+ os.environ['SOFTHSM2_CONF'] = softhsm2_two_conf -+ -+ conf = format_pam_cert_auth_conf(config, provider_switch(request.param)) -+ create_conf_fixture(request, conf) -+ create_sssd_fixture(request) -+ -+ os.environ['SOFTHSM2_CONF'] = old_softhsm2_conf -+ -+ passwd_ops_setup.useradd(**USER1) -+ passwd_ops_setup.useradd(**USER2) -+ sync_files_provider(USER2['name']) -+ -+ return None -+ -+ - @pytest.fixture - def simple_pam_cert_auth_name_format(request, passwd_ops_setup): - """Setup SSSD with pam_cert_auth=True and full_name_format""" -@@ -522,6 +544,54 @@ def test_sc_auth(simple_pam_cert_auth, env_for_sssctl): - assert err.find("pam_authenticate for user [user1]: Success") != -1 - - -+@pytest.mark.parametrize('simple_pam_cert_auth_two_certs', provider_list(), indirect=True) -+def test_sc_auth_two(simple_pam_cert_auth_two_certs, env_for_sssctl): -+ -+ sssctl = subprocess.Popen(["sssctl", "user-checks", "user1", -+ "--action=auth", "--service=pam_sss_service"], -+ universal_newlines=True, -+ env=env_for_sssctl, stdin=subprocess.PIPE, -+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ -+ try: -+ out, err = sssctl.communicate(input="2\n123456") -+ except Exception: -+ sssctl.kill() -+ out, err = sssctl.communicate() -+ -+ sssctl.stdin.close() -+ sssctl.stdout.close() -+ -+ if sssctl.wait() != 0: -+ raise Exception("sssctl failed") -+ -+ assert err.find("pam_authenticate for user [user1]: Success") != -1 -+ -+ -+@pytest.mark.parametrize('simple_pam_cert_auth_two_certs', provider_list(), indirect=True) -+def test_sc_auth_two_missing_name(simple_pam_cert_auth_two_certs, env_for_sssctl): -+ -+ sssctl = subprocess.Popen(["sssctl", "user-checks", "", -+ "--action=auth", "--service=pam_sss_allow_missing_name"], -+ universal_newlines=True, -+ env=env_for_sssctl, stdin=subprocess.PIPE, -+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ -+ try: -+ out, err = sssctl.communicate(input="2\n123456") -+ except Exception: -+ sssctl.kill() -+ out, err = sssctl.communicate() -+ -+ sssctl.stdin.close() -+ sssctl.stdout.close() -+ -+ if sssctl.wait() != 0: -+ raise Exception("sssctl failed") -+ -+ assert err.find("pam_authenticate for user [user1]: Success") != -1 -+ -+ - @pytest.mark.parametrize('simple_pam_cert_auth', ['proxy_password'], indirect=True) - def test_sc_proxy_password_fallback(simple_pam_cert_auth, env_for_sssctl): - """ --- -2.41.0 - diff --git a/SOURCES/0005-SYSDB-remove-index-on-dataExpireTimestamp.patch b/SOURCES/0005-SYSDB-remove-index-on-dataExpireTimestamp.patch new file mode 100644 index 0000000..ee1a718 --- /dev/null +++ b/SOURCES/0005-SYSDB-remove-index-on-dataExpireTimestamp.patch @@ -0,0 +1,147 @@ +From 13e3d0390b9aaf72a855b857857c3cdd6eb6252a Mon Sep 17 00:00:00 2001 +From: Alexey Tikhonov +Date: Fri, 21 Jun 2024 19:09:29 +0200 +Subject: [PATCH 5/5] SYSDB: remove index on `dataExpireTimestamp` +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This index was only used in cleanup tasks that don't run often. +On the other hand, this index is huge and degrades performance of libldb +in general. + +Reviewed-by: Alejandro López +Reviewed-by: Sumit Bose +Reviewed-by: Tomáš Halman +(cherry picked from commit f0d45464cee1d2a6a2719dbffe5bbf6189d0554a) +--- + src/db/sysdb_init.c | 8 ++++++++ + src/db/sysdb_private.h | 9 +++++---- + src/db/sysdb_upgrade.c | 27 +++++++++++++++++++++++++++ + 3 files changed, 40 insertions(+), 4 deletions(-) + +diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c +index a1d02d49c..68b9744dd 100644 +--- a/src/db/sysdb_init.c ++++ b/src/db/sysdb_init.c +@@ -559,6 +559,13 @@ static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx, + } + } + ++ if (strcmp(version, SYSDB_VERSION_0_24) == 0) { ++ ret = sysdb_upgrade_24(sysdb, &version); ++ if (ret != EOK) { ++ goto done; ++ } ++ } ++ + ret = EOK; + done: + sysdb->ldb = save_ldb; +@@ -765,6 +772,7 @@ static int sysdb_domain_cache_connect(struct sysdb_ctx *sysdb, + ret = sysdb_domain_cache_upgrade(tmp_ctx, sysdb, upgrade_ctx, + ldb, domain, version, &version); + if (ret != EOK) { ++ DEBUG(SSSDBG_TRACE_FUNC, "sysdb_domain_cache_upgrade() failed\n"); + goto done; + } + +diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h +index 63f7b5601..b814f97a5 100644 +--- a/src/db/sysdb_private.h ++++ b/src/db/sysdb_private.h +@@ -23,6 +23,7 @@ + #ifndef __INT_SYS_DB_H__ + #define __INT_SYS_DB_H__ + ++#define SYSDB_VERSION_0_25 "0.25" + #define SYSDB_VERSION_0_24 "0.24" + #define SYSDB_VERSION_0_23 "0.23" + #define SYSDB_VERSION_0_22 "0.22" +@@ -48,7 +49,7 @@ + #define SYSDB_VERSION_0_2 "0.2" + #define SYSDB_VERSION_0_1 "0.1" + +-#define SYSDB_VERSION SYSDB_VERSION_0_24 ++#define SYSDB_VERSION SYSDB_VERSION_0_25 + + #define SYSDB_BASE_LDIF \ + "dn: @ATTRIBUTES\n" \ +@@ -72,7 +73,6 @@ + "@IDXATTR: uidNumber\n" \ + "@IDXATTR: gidNumber\n" \ + "@IDXATTR: lastUpdate\n" \ +- "@IDXATTR: dataExpireTimestamp\n" \ + "@IDXATTR: originalDN\n" \ + "@IDXATTR: nameAlias\n" \ + "@IDXATTR: servicePort\n" \ +@@ -104,10 +104,11 @@ + "\n" + + /* The timestamp cache has its own versioning */ ++#define SYSDB_TS_VERSION_0_3 "0.3" + #define SYSDB_TS_VERSION_0_2 "0.2" + #define SYSDB_TS_VERSION_0_1 "0.1" + +-#define SYSDB_TS_VERSION SYSDB_TS_VERSION_0_2 ++#define SYSDB_TS_VERSION SYSDB_TS_VERSION_0_3 + + #define SYSDB_TS_BASE_LDIF \ + "dn: @ATTRIBUTES\n" \ +@@ -115,7 +116,6 @@ + "\n" \ + "dn: @INDEXLIST\n" \ + "@IDXATTR: lastUpdate\n" \ +- "@IDXATTR: dataExpireTimestamp\n" \ + "\n" \ + "dn: cn=sysdb\n" \ + "cn: sysdb\n" \ +@@ -194,6 +194,7 @@ int sysdb_upgrade_20(struct sysdb_ctx *sysdb, const char **ver); + int sysdb_upgrade_21(struct sysdb_ctx *sysdb, const char **ver); + int sysdb_upgrade_22(struct sysdb_ctx *sysdb, const char **ver); + int sysdb_upgrade_23(struct sysdb_ctx *sysdb, const char **ver); ++int sysdb_upgrade_24(struct sysdb_ctx *sysdb, const char **ver); + + int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver); + +diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c +index 37c0007cb..b010488ca 100644 +--- a/src/db/sysdb_upgrade.c ++++ b/src/db/sysdb_upgrade.c +@@ -2774,6 +2774,33 @@ done: + return ret; + } + ++int sysdb_upgrade_24(struct sysdb_ctx *sysdb, const char **ver) ++{ ++ struct upgrade_ctx *ctx; ++ errno_t ret; ++ ++ ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_25, &ctx); ++ if (ret) { ++ return ret; ++ } ++ ++ ret = sysdb_ldb_mod_index(sysdb, SYSDB_IDX_DELETE, sysdb->ldb, "dataExpireTimestamp"); ++ if (ret == ENOENT) { /*nothing to delete */ ++ ret = EOK; ++ } ++ if (ret != EOK) { ++ DEBUG(SSSDBG_TRACE_FUNC, "sysdb_ldb_mod_index() failed [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ goto done; ++ } ++ ++ ret = update_version(ctx); ++ ++done: ++ ret = finish_upgrade(ret, &ctx, ver); ++ return ret; ++} ++ + /* + * Example template for future upgrades. + * Copy and change version numbers as appropriate. +-- +2.45.2 + diff --git a/SOURCES/0005-sss-client-handle-key-value-in-destructor.patch b/SOURCES/0005-sss-client-handle-key-value-in-destructor.patch deleted file mode 100644 index 227157b..0000000 --- a/SOURCES/0005-sss-client-handle-key-value-in-destructor.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 8bf31924265baf81372fe42580dee4064a642375 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -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 -Reviewed-by: Iker Pedrosa -(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 - diff --git a/SOURCES/0006-krb5-Allow-fallback-between-responder-questions.patch b/SOURCES/0006-krb5-Allow-fallback-between-responder-questions.patch deleted file mode 100644 index f8dda3e..0000000 --- a/SOURCES/0006-krb5-Allow-fallback-between-responder-questions.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 23849f751315ea218e125f35cd419cce55d27355 Mon Sep 17 00:00:00 2001 -From: Justin Stephenson -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 -Reviewed-by: Iker Pedrosa -(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 - diff --git a/SOURCES/0006-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch b/SOURCES/0006-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch new file mode 100644 index 0000000..43f9e2d --- /dev/null +++ b/SOURCES/0006-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch @@ -0,0 +1,115 @@ +From 39cbb8df402f59b4df2442eb291600773e7062cc Mon Sep 17 00:00:00 2001 +From: Petr Mikhalicin +Date: Fri, 10 Nov 2023 15:24:48 +0600 +Subject: [PATCH 6/8] 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 +(cherry picked from commit ae6b9163be0a5a8846e8dbf2e0da2c29221781b9) + +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 41a528dda..5171e58ec 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.45.2 + diff --git a/SOURCES/0007-krb5-Add-fallback-password-change-support.patch b/SOURCES/0007-krb5-Add-fallback-password-change-support.patch deleted file mode 100644 index 875d831..0000000 --- a/SOURCES/0007-krb5-Add-fallback-password-change-support.patch +++ /dev/null @@ -1,206 +0,0 @@ -From 8d9ae754b50dffafef719ad3fa44e5dd1dde47b3 Mon Sep 17 00:00:00 2001 -From: Justin Stephenson -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 -Reviewed-by: Iker Pedrosa -(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 - diff --git a/SOURCES/0007-krb5_child-do-not-try-passwords-with-OTP.patch b/SOURCES/0007-krb5_child-do-not-try-passwords-with-OTP.patch new file mode 100644 index 0000000..27c987f --- /dev/null +++ b/SOURCES/0007-krb5_child-do-not-try-passwords-with-OTP.patch @@ -0,0 +1,178 @@ +From ef375cdd67b51d8fb63cae4d3cd40f3a5c2bc173 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Mon, 1 Jul 2024 20:40:30 +0200 +Subject: [PATCH 7/8] krb5_child: do not try passwords with OTP +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +During two-factor authentication (OTP) krb5_child should use use the +dedicated OTP auth types SSS_AUTHTOK_TYPE_2FA and +SSS_AUTHTOK_TYPE_2FA_SINGLE exclusively and should not try password or +other types. + +The special handling needed of ssh under certain conditions are +documented in the code and the man page. + +Resolves: https://github.com/SSSD/sssd/issues/7456 + +Reviewed-by: Justin Stephenson +Reviewed-by: Tomáš Halman +(cherry picked from commit af799964e5fa1264467b49988021c054586eff27) + +Reviewed-by: Sumit Bose +--- + src/man/sssd.conf.5.xml | 11 +++++++++ + src/providers/krb5/krb5_child.c | 11 +-------- + src/sss_client/pam_sss.c | 44 ++++++++++++++++++++++++--------- + 3 files changed, 44 insertions(+), 22 deletions(-) + +diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml +index fb86a4e41..8ac1a4418 100644 +--- a/src/man/sssd.conf.5.xml ++++ b/src/man/sssd.conf.5.xml +@@ -4559,6 +4559,17 @@ ldap_user_extra_attrs = phone:telephoneNumber + to log in either only with the password or with both factors + two-step prompting has to be used. + ++ ++ Some clients, such as SSH with ++ 'PasswordAuthentication yes', generate their own prompts ++ and do not use prompts provided by SSSD or other PAM ++ modules. Additionally, for SSH with ++ PasswordAuthentication, if two-factor authentication is ++ available, SSSD expects that the ++ credentials entered by the user at the SSH password prompt ++ will always be the two factors in a single string, even if ++ two-factor authentication is optional. ++ + + + +diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c +index 494711de9..cb9a9ce73 100644 +--- a/src/providers/krb5/krb5_child.c ++++ b/src/providers/krb5/krb5_child.c +@@ -536,15 +536,6 @@ static krb5_error_code tokeninfo_matches(TALLOC_CTX *mem_ctx, + size_t fa2_len; + + switch (sss_authtok_get_type(auth_tok)) { +- case SSS_AUTHTOK_TYPE_PASSWORD: +- ret = sss_authtok_get_password(auth_tok, &pwd, &len); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_password failed.\n"); +- return ret; +- } +- +- return tokeninfo_matches_pwd(mem_ctx, ti, pwd, len, out_token, out_pin); +- break; + case SSS_AUTHTOK_TYPE_2FA_SINGLE: + ret = sss_authtok_get_2fa_single(auth_tok, &pwd, &len); + if (ret != EOK) { +@@ -569,7 +560,7 @@ static krb5_error_code tokeninfo_matches(TALLOC_CTX *mem_ctx, + "Unsupported authtok type %d\n", sss_authtok_get_type(auth_tok)); + } + +- return EINVAL; ++ return EAGAIN; + } + + static krb5_error_code answer_otp(krb5_context ctx, +diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c +index 5171e58ec..d43bd0f55 100644 +--- a/src/sss_client/pam_sss.c ++++ b/src/sss_client/pam_sss.c +@@ -1656,6 +1656,7 @@ static int prompt_password(pam_handle_t *pamh, struct pam_items *pi, + } + + static int prompt_2fa(pam_handle_t *pamh, struct pam_items *pi, ++ bool second_factor_optional, + const char *prompt_fa1, const char *prompt_fa2) + { + int ret; +@@ -1706,13 +1707,30 @@ static int prompt_2fa(pam_handle_t *pamh, struct pam_items *pi, + goto done; + } + +- if (resp[1].resp == NULL || *(resp[1].resp) == '\0' +- || (pi->pam_service != NULL && strcmp(pi->pam_service, "sshd") == 0 +- && strcmp(resp[0].resp, resp[1].resp) == 0)) { ++ if (resp[1].resp == NULL || *(resp[1].resp) == '\0') { + /* Missing second factor, assume first factor contains combined 2FA +- * credentials. +- * Special handling for SSH with password authentication. Combined +- * 2FA credentials are used but SSH puts them in both responses. */ ++ * credentials if the second factor is not optional. If it is optional ++ * then it is assumed that the first factor contain the password. */ ++ pi->pam_authtok = strndup(resp[0].resp, MAX_AUTHTOK_SIZE); ++ if (pi->pam_authtok == NULL) { ++ D(("strndup failed.")); ++ ret = PAM_BUF_ERR; ++ goto done; ++ } ++ pi->pam_authtok_size = strlen(pi->pam_authtok) + 1; ++ pi->pam_authtok_type = second_factor_optional ++ ? SSS_AUTHTOK_TYPE_PASSWORD ++ : SSS_AUTHTOK_TYPE_2FA_SINGLE; ++ } else if (pi->pam_service != NULL && strcmp(pi->pam_service, "sshd") == 0 ++ && strcmp(resp[0].resp, resp[1].resp) == 0) { ++ /* Special handling for SSH with password authentication (ssh's ++ * 'PasswordAuthentication' option. In this mode the ssh client ++ * directly prompts the user for a password and the prompts we are ++ * sending are ignored. Since we send two prompts ssh * will create two ++ * response as well with the same content. We assume that the combined ++ * 2FA credentials are used even if the second factor is optional ++ * because there is no indication about the intention of the user. As a ++ * result we prefer the more secure variant. */ + + pi->pam_authtok = strndup(resp[0].resp, MAX_AUTHTOK_SIZE); + if (pi->pam_authtok == NULL) { +@@ -1721,7 +1739,7 @@ static int prompt_2fa(pam_handle_t *pamh, struct pam_items *pi, + goto done; + } + pi->pam_authtok_size = strlen(pi->pam_authtok) + 1; +- pi->pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD; ++ pi->pam_authtok_type = SSS_AUTHTOK_TYPE_2FA_SINGLE; + } else { + + ret = sss_auth_pack_2fa_blob(resp[0].resp, 0, resp[1].resp, 0, NULL, 0, +@@ -2487,7 +2505,7 @@ static int prompt_by_config(pam_handle_t *pamh, struct pam_items *pi) + ret = prompt_password(pamh, pi, pc_get_password_prompt(pi->pc[c])); + break; + case PC_TYPE_2FA: +- ret = prompt_2fa(pamh, pi, pc_get_2fa_1st_prompt(pi->pc[c]), ++ ret = prompt_2fa(pamh, pi, false, pc_get_2fa_1st_prompt(pi->pc[c]), + pc_get_2fa_2nd_prompt(pi->pc[c])); + break; + case PC_TYPE_2FA_SINGLE: +@@ -2564,10 +2582,10 @@ static int get_authtok_for_authentication(pam_handle_t *pamh, + || (pi->otp_vendor != NULL && pi->otp_token_id != NULL + && pi->otp_challenge != NULL)) { + if (pi->password_prompting) { +- ret = prompt_2fa(pamh, pi, _("First Factor: "), ++ ret = prompt_2fa(pamh, pi, true, _("First Factor: "), + _("Second Factor (optional): ")); + } else { +- ret = prompt_2fa(pamh, pi, _("First Factor: "), ++ ret = prompt_2fa(pamh, pi, false, _("First Factor: "), + _("Second Factor: ")); + } + } else if (pi->passkey_prompt_pin) { +@@ -2736,10 +2754,12 @@ static int get_authtok_for_password_change(pam_handle_t *pamh, + || (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): "), ++ ret = prompt_2fa(pamh, pi, true, ++ _("First Factor (Current Password): "), + _("Second Factor (optional): ")); + } else { +- ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "), ++ ret = prompt_2fa(pamh, pi, false, ++ _("First Factor (Current Password): "), + _("Second Factor: ")); + } + } else if ((flags & PAM_CLI_FLAGS_USE_FIRST_PASS) +-- +2.45.2 + diff --git a/SOURCES/0008-pam-fix-invalid-if-condition.patch b/SOURCES/0008-pam-fix-invalid-if-condition.patch deleted file mode 100644 index 53fccda..0000000 --- a/SOURCES/0008-pam-fix-invalid-if-condition.patch +++ /dev/null @@ -1,30 +0,0 @@ -From bebb150720620aae97dcae5c11e0b9bea0119b5b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -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 -(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 - diff --git a/SOURCES/0008-pam_sss-add-missing-optional-2nd-factor-handling.patch b/SOURCES/0008-pam_sss-add-missing-optional-2nd-factor-handling.patch new file mode 100644 index 0000000..62c1ec4 --- /dev/null +++ b/SOURCES/0008-pam_sss-add-missing-optional-2nd-factor-handling.patch @@ -0,0 +1,45 @@ +From 7e76396a891b4c704f1db8c71a217f869bef0ec3 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 12 Jul 2024 13:46:00 +0200 +Subject: [PATCH 8/8] pam_sss: add missing optional 2nd factor handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is a follow up to pull-request #7462 and adds the proper handling of +an optional second factor in case the prompting is configured. + +Resolves: https://github.com/SSSD/sssd/issues/7456 + +Reviewed-by: Justin Stephenson +Reviewed-by: Tomáš Halman +(cherry picked from commit 077d2993a1b306e7cfe61618cbd5d03c602572f8) + +Reviewed-by: Sumit Bose +--- + src/sss_client/pam_sss.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c +index d43bd0f55..d1101e16c 100644 +--- a/src/sss_client/pam_sss.c ++++ b/src/sss_client/pam_sss.c +@@ -2505,8 +2505,13 @@ static int prompt_by_config(pam_handle_t *pamh, struct pam_items *pi) + ret = prompt_password(pamh, pi, pc_get_password_prompt(pi->pc[c])); + break; + case PC_TYPE_2FA: +- ret = prompt_2fa(pamh, pi, false, pc_get_2fa_1st_prompt(pi->pc[c]), +- pc_get_2fa_2nd_prompt(pi->pc[c])); ++ if (pi->password_prompting) { ++ ret = prompt_2fa(pamh, pi, true, pc_get_2fa_1st_prompt(pi->pc[c]), ++ pc_get_2fa_2nd_prompt(pi->pc[c])); ++ } else { ++ ret = prompt_2fa(pamh, pi, false, pc_get_2fa_1st_prompt(pi->pc[c]), ++ pc_get_2fa_2nd_prompt(pi->pc[c])); ++ } + break; + case PC_TYPE_2FA_SINGLE: + ret = prompt_2fa_single(pamh, pi, +-- +2.45.2 + diff --git a/SOURCES/0009-krb5-add-OTP-to-krb5-response-selection.patch b/SOURCES/0009-krb5-add-OTP-to-krb5-response-selection.patch deleted file mode 100644 index 87fbf45..0000000 --- a/SOURCES/0009-krb5-add-OTP-to-krb5-response-selection.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 5b9bc0a1a6116e6fb001c7dce7497854fcdd40c4 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 14 Mar 2024 09:18:45 +0100 -Subject: [PATCH 09/12] krb5: add OTP to krb5 response selection -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Originally where there was only password and OTP authentication we -checked for password authentication and used OTP as a fallback. This was -continued as other (pre)-authentication types were added. But so far -only one authentication type was returned. - -This changed recently to allow the user a better selection and as a -result OTP cannot be handled as a fallback anymore but has to be added -to the selection. In case there are no types (questions) available now -password is used as a fallback. - -Resolves: https://github.com/SSSD/sssd/issues/7152 - -Reviewed-by: Alejandro López -Reviewed-by: Justin Stephenson -(cherry picked from commit bf6cb6dcdd94d9f47e4e74acd51e30f86b488943) ---- - src/providers/krb5/krb5_child.c | 107 ++++++++++++++++++++++---------- - 1 file changed, 75 insertions(+), 32 deletions(-) - -diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c -index b8acae7d7..116f2adda 100644 ---- a/src/providers/krb5/krb5_child.c -+++ b/src/providers/krb5/krb5_child.c -@@ -1200,6 +1200,44 @@ done: - #endif /* BUILD_PASSKEY */ - } - -+static krb5_error_code answer_password(krb5_context kctx, -+ struct krb5_req *kr, -+ krb5_responder_context rctx) -+{ -+ krb5_error_code kerr; -+ int ret; -+ const char *pwd; -+ -+ kr->password_prompting = true; -+ -+ if ((kr->pd->cmd == SSS_PAM_AUTHENTICATE -+ || kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM -+ || kr->pd->cmd == SSS_PAM_CHAUTHTOK) -+ && sss_authtok_get_type(kr->pd->authtok) -+ == SSS_AUTHTOK_TYPE_PASSWORD) { -+ ret = sss_authtok_get_password(kr->pd->authtok, &pwd, NULL); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sss_authtok_get_password failed.\n"); -+ return ret; -+ } -+ -+ kerr = krb5_responder_set_answer(kctx, rctx, -+ KRB5_RESPONDER_QUESTION_PASSWORD, -+ pwd); -+ if (kerr != 0) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "krb5_responder_set_answer failed.\n"); -+ } -+ -+ return kerr; -+ } -+ -+ /* For SSS_PAM_PREAUTH and the other remaining commands the caller should -+ * continue to iterate over the available authentication methods. */ -+ return EAGAIN; -+} -+ - static krb5_error_code sss_krb5_responder(krb5_context ctx, - void *data, - krb5_responder_context rctx) -@@ -1207,9 +1245,7 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx, - struct krb5_req *kr = talloc_get_type(data, struct krb5_req); - const char * const *question_list; - size_t c; -- const char *pwd; -- int ret; -- krb5_error_code kerr; -+ krb5_error_code kerr = EINVAL; - - if (kr == NULL) { - return EINVAL; -@@ -1221,34 +1257,18 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx, - for (c = 0; question_list[c] != NULL; c++) { - DEBUG(SSSDBG_TRACE_ALL, "Got question [%s].\n", question_list[c]); - -+ /* 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. */ - if (strcmp(question_list[c], - KRB5_RESPONDER_QUESTION_PASSWORD) == 0) { -- kr->password_prompting = true; -- -- if ((kr->pd->cmd == SSS_PAM_AUTHENTICATE -- || kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM -- || kr->pd->cmd == SSS_PAM_CHAUTHTOK) -- && sss_authtok_get_type(kr->pd->authtok) -- == SSS_AUTHTOK_TYPE_PASSWORD) { -- ret = sss_authtok_get_password(kr->pd->authtok, &pwd, NULL); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- "sss_authtok_get_password failed.\n"); -- return ret; -- } -- -- kerr = krb5_responder_set_answer(ctx, rctx, -- KRB5_RESPONDER_QUESTION_PASSWORD, -- pwd); -- if (kerr != 0) { -- DEBUG(SSSDBG_OP_FAILURE, -- "krb5_responder_set_answer failed.\n"); -- } -- -- return kerr; -- } -- -- kerr = EOK; -+ kerr = answer_password(ctx, kr, rctx); - } else if (strcmp(question_list[c], - KRB5_RESPONDER_QUESTION_PKINIT) == 0 - && (sss_authtok_get_type(kr->pd->authtok) -@@ -1265,6 +1285,8 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx, - continue; - } - kerr = answer_passkey(ctx, kr, rctx); -+ } else if (strcmp(question_list[c], KRB5_RESPONDER_QUESTION_OTP) == 0) { -+ kerr = answer_otp(ctx, kr, rctx); - } else { - DEBUG(SSSDBG_MINOR_FAILURE, "Unknown question type [%s]\n", question_list[c]); - kerr = EINVAL; -@@ -1274,16 +1296,37 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx, - * 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]); -+ /* During pre-auth iterating over all authentication methods -+ * is expected and no message will be displayed. */ -+ if (kr->pd->cmd == SSS_PAM_AUTHENTICATE) { -+ 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; - } - } -+ } else { -+ kerr = answer_password(ctx, kr, rctx); - } - -- return answer_otp(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. -+ */ -+ if (kr->pd->cmd == SSS_PAM_PREAUTH) { -+ return kerr == EAGAIN ? 0 : kerr; -+ } else { -+ return kerr; -+ } - } - #endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_RESPONDER */ - --- -2.42.0 - diff --git a/SOURCES/0009-pam-only-set-SYSDB_LOCAL_SMARTCARD_AUTH-to-true-but-.patch b/SOURCES/0009-pam-only-set-SYSDB_LOCAL_SMARTCARD_AUTH-to-true-but-.patch new file mode 100644 index 0000000..e069a48 --- /dev/null +++ b/SOURCES/0009-pam-only-set-SYSDB_LOCAL_SMARTCARD_AUTH-to-true-but-.patch @@ -0,0 +1,58 @@ +From b4c496856d466ff00d06cd5177cb216110f5e3b3 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Wed, 18 Sep 2024 15:18:14 +0200 +Subject: [PATCH] pam: only set SYSDB_LOCAL_SMARTCARD_AUTH to 'true' but never + to 'false'. + +The krb5 backend will only returns that Smartcard authentication is +available if a Smartcard is present. That means if the user +authenticates with a different method and a Smartcard is not present at +this time 'sc_allow' will be 'false' and might overwrite a 'true' value +written during a previous authentication attempt where a Smartcard was +present. To avoid this we only write 'true' values. Since the default if +SYSDB_LOCAL_SMARTCARD_AUTH is missing is 'false' local Smartcard +authentication (offline) will still only be enabled if online Smartcard +authentication was detected. + +Resolves: https://github.com/SSSD/sssd/issues/7532 + +Reviewed-by: Iker Pedrosa +Reviewed-by: Justin Stephenson +(cherry picked from commit 67ba42c48abb9270982836310488e35d9fc1d451) +--- + src/responder/pam/pamsrv_cmd.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c +index 1394147a0..941446d94 100644 +--- a/src/responder/pam/pamsrv_cmd.c ++++ b/src/responder/pam/pamsrv_cmd.c +@@ -554,9 +554,22 @@ static errno_t set_local_auth_type(struct pam_auth_req *preq, + goto fail; + } + +- ret = sysdb_attrs_add_bool(attrs, SYSDB_LOCAL_SMARTCARD_AUTH, sc_allow); +- if (ret != EOK) { +- goto fail; ++ if (sc_allow) { ++ /* Only set SYSDB_LOCAL_SMARTCARD_AUTH to 'true' but never to ++ * 'false'. The krb5 backend will only returns that Smartcard ++ * authentication is available if a Smartcard is present. That means ++ * if the user authenticates with a different method and a Smartcard ++ * is not present at this time 'sc_allow' will be 'false' and might ++ * overwrite a 'true' value written during a previous authentication ++ * attempt where a Smartcard was present. To avoid this we only write ++ * 'true' values. Since the default if SYSDB_LOCAL_SMARTCARD_AUTH is ++ * missing is 'false' local Smartcard authentication (offline) will ++ * still only be enabled if online Smartcard authentication was ++ * detected. */ ++ ret = sysdb_attrs_add_bool(attrs, SYSDB_LOCAL_SMARTCARD_AUTH, sc_allow); ++ if (ret != EOK) { ++ goto fail; ++ } + } + + ret = sysdb_attrs_add_bool(attrs, SYSDB_LOCAL_PASSKEY_AUTH, passkey_allow); +-- +2.45.0 + diff --git a/SOURCES/0010-krb5-make-sure-answer_pkinit-use-matching-debug-mess.patch b/SOURCES/0010-krb5-make-sure-answer_pkinit-use-matching-debug-mess.patch deleted file mode 100644 index db83f42..0000000 --- a/SOURCES/0010-krb5-make-sure-answer_pkinit-use-matching-debug-mess.patch +++ /dev/null @@ -1,119 +0,0 @@ -From c3725a13ef694c2c34813953153f33ebfbaf1c27 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 15 Mar 2024 11:29:47 +0100 -Subject: [PATCH 10/12] krb5: make sure answer_pkinit() use matching debug - messages -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Resolves: https://github.com/SSSD/sssd/issues/7152 - -Reviewed-by: Alejandro López -Reviewed-by: Justin Stephenson -(cherry picked from commit 7c33f9d57cebfff80778f930ff0cc3144a7cc261) ---- - src/providers/krb5/krb5_child.c | 77 ++++++++++++++++++--------------- - 1 file changed, 42 insertions(+), 35 deletions(-) - -diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c -index 116f2adda..926109588 100644 ---- a/src/providers/krb5/krb5_child.c -+++ b/src/providers/krb5/krb5_child.c -@@ -745,51 +745,58 @@ static krb5_error_code answer_pkinit(krb5_context ctx, - DEBUG(SSSDBG_TRACE_ALL, "Setting pkinit_prompting.\n"); - kr->pkinit_prompting = true; - -- if (kr->pd->cmd == SSS_PAM_AUTHENTICATE -- && (sss_authtok_get_type(kr->pd->authtok) -+ if (kr->pd->cmd == SSS_PAM_AUTHENTICATE) { -+ if ((sss_authtok_get_type(kr->pd->authtok) - == SSS_AUTHTOK_TYPE_SC_PIN - || sss_authtok_get_type(kr->pd->authtok) - == SSS_AUTHTOK_TYPE_SC_KEYPAD)) { -- kerr = sss_authtok_get_sc(kr->pd->authtok, &pin, NULL, -- &token_name, NULL, -- &module_name, NULL, -- NULL, NULL, NULL, NULL); -- if (kerr != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- "sss_authtok_get_sc failed.\n"); -- goto done; -- } -+ kerr = sss_authtok_get_sc(kr->pd->authtok, &pin, NULL, -+ &token_name, NULL, -+ &module_name, NULL, -+ NULL, NULL, NULL, NULL); -+ if (kerr != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sss_authtok_get_sc failed.\n"); -+ goto done; -+ } - -- for (c = 0; chl->identities[c] != NULL; c++) { -- if (chl->identities[c]->identity != NULL -- && pkinit_identity_matches(chl->identities[c]->identity, -- token_name, module_name)) { -- break; -+ for (c = 0; chl->identities[c] != NULL; c++) { -+ if (chl->identities[c]->identity != NULL -+ && pkinit_identity_matches(chl->identities[c]->identity, -+ token_name, module_name)) { -+ break; -+ } - } -- } - -- if (chl->identities[c] == NULL) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "No matching identity for [%s][%s] found in pkinit challenge.\n", -- token_name, module_name); -- kerr = EINVAL; -- goto done; -- } -+ if (chl->identities[c] == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "No matching identity for [%s][%s] found in pkinit " -+ "challenge.\n", token_name, module_name); -+ kerr = EINVAL; -+ goto done; -+ } - -- kerr = krb5_responder_pkinit_set_answer(ctx, rctx, -- chl->identities[c]->identity, -- pin); -- if (kerr != 0) { -- DEBUG(SSSDBG_OP_FAILURE, -- "krb5_responder_set_answer failed.\n"); -- } -+ kerr = krb5_responder_pkinit_set_answer(ctx, rctx, -+ chl->identities[c]->identity, -+ pin); -+ if (kerr != 0) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "krb5_responder_set_answer failed.\n"); -+ } - -- goto done; -+ 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; -+ } - } else { -- DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected authentication token type [%s]\n", -- sss_authtok_type_to_str(sss_authtok_get_type(kr->pd->authtok))); -+ /* 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; -- goto done; - } - - done: --- -2.42.0 - diff --git a/SOURCES/0010-sdap-allow-to-provide-user_map-when-looking-up-group.patch b/SOURCES/0010-sdap-allow-to-provide-user_map-when-looking-up-group.patch new file mode 100644 index 0000000..1286417 --- /dev/null +++ b/SOURCES/0010-sdap-allow-to-provide-user_map-when-looking-up-group.patch @@ -0,0 +1,307 @@ +From 321ca19ae09609ac4195f323b696bdcd7ee573e4 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 6 Sep 2024 14:27:19 +0200 +Subject: [PATCH 10/11] sdap: allow to provide user_map when looking up group + memberships +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +To allow to lookup group memberships of other objects similar to user +objects but with different attribute mappings, e.g. host objects in AD, +a new option to provide an alternative attribute map is added. + +Resolves: https://github.com/SSSD/sssd/issues/7590 + +Reviewed-by: Justin Stephenson +Reviewed-by: Tomáš Halman +(cherry picked from commit 69f63f1fa64bd9cc7c2ee1f8e8d736727b13b3be) +--- + src/providers/ad/ad_gpo.c | 2 +- + src/providers/ldap/ldap_common.h | 2 + + src/providers/ldap/ldap_id.c | 9 ++++ + src/providers/ldap/sdap_async.h | 2 + + src/providers/ldap/sdap_async_initgroups.c | 51 ++++++++++++++-------- + 5 files changed, 48 insertions(+), 18 deletions(-) + +diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c +index ed664ec83..fa68d814f 100644 +--- a/src/providers/ad/ad_gpo.c ++++ b/src/providers/ad/ad_gpo.c +@@ -2244,7 +2244,7 @@ ad_gpo_connect_done(struct tevent_req *subreq) + search_bases, + state->host_fqdn, + BE_FILTER_NAME, +- NULL, ++ NULL, NULL, 0, + true, + true); + tevent_req_set_callback(subreq, ad_gpo_target_dn_retrieval_done, req); +diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h +index 2c984ef50..61a35553b 100644 +--- a/src/providers/ldap/ldap_common.h ++++ b/src/providers/ldap/ldap_common.h +@@ -308,6 +308,8 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, + const char *filter_value, + int filter_type, + const char *extra_value, ++ struct sdap_attr_map *user_map, ++ size_t user_map_cnt, + bool noexist_delete, + bool set_non_posix); + +diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c +index b3ea2333f..0596ad4cf 100644 +--- a/src/providers/ldap/ldap_id.c ++++ b/src/providers/ldap/ldap_id.c +@@ -1144,6 +1144,8 @@ struct groups_by_user_state { + const char *filter_value; + int filter_type; + const char *extra_value; ++ struct sdap_attr_map *user_map; ++ size_t user_map_cnt; + const char **attrs; + bool non_posix; + +@@ -1165,6 +1167,8 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, + const char *filter_value, + int filter_type, + const char *extra_value, ++ struct sdap_attr_map *user_map, ++ size_t user_map_cnt, + bool noexist_delete, + bool set_non_posix) + { +@@ -1192,6 +1196,8 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, + state->filter_value = filter_value; + state->filter_type = filter_type; + state->extra_value = extra_value; ++ state->user_map = user_map; ++ state->user_map_cnt = user_map_cnt; + state->domain = sdom->dom; + state->sysdb = sdom->dom->sysdb; + state->search_bases = search_bases; +@@ -1256,6 +1262,8 @@ static void groups_by_user_connect_done(struct tevent_req *subreq) + state->sdom, + sdap_id_op_handle(state->op), + state->ctx, ++ state->user_map, ++ state->user_map_cnt, + state->conn, + state->search_bases, + state->filter_value, +@@ -1457,6 +1465,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, + ar->filter_value, + ar->filter_type, + ar->extra_value, ++ NULL, 0, + noexist_delete, false); + break; + +diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h +index 89245f41f..a45e057d0 100644 +--- a/src/providers/ldap/sdap_async.h ++++ b/src/providers/ldap/sdap_async.h +@@ -157,6 +157,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + struct sdap_domain *sdom, + struct sdap_handle *sh, + struct sdap_id_ctx *id_ctx, ++ struct sdap_attr_map *user_map, ++ size_t user_map_cnt, + struct sdap_id_conn_ctx *conn, + struct sdap_search_base **search_bases, + const char *name, +diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c +index fb3d8fe24..8ce1f6cd4 100644 +--- a/src/providers/ldap/sdap_async_initgroups.c ++++ b/src/providers/ldap/sdap_async_initgroups.c +@@ -785,6 +785,8 @@ struct sdap_initgr_nested_state { + struct tevent_context *ev; + struct sysdb_ctx *sysdb; + struct sdap_options *opts; ++ struct sdap_attr_map *user_map; ++ size_t user_map_cnt; + struct sss_domain_info *dom; + struct sdap_handle *sh; + +@@ -812,6 +814,8 @@ static void sdap_initgr_nested_store(struct tevent_req *req); + static struct tevent_req *sdap_initgr_nested_send(TALLOC_CTX *memctx, + struct tevent_context *ev, + struct sdap_options *opts, ++ struct sdap_attr_map *user_map, ++ size_t user_map_cnt, + struct sysdb_ctx *sysdb, + struct sss_domain_info *dom, + struct sdap_handle *sh, +@@ -828,6 +832,8 @@ static struct tevent_req *sdap_initgr_nested_send(TALLOC_CTX *memctx, + + state->ev = ev; + state->opts = opts; ++ state->user_map = user_map; ++ state->user_map_cnt = user_map_cnt; + state->sysdb = sysdb; + state->dom = dom; + state->sh = sh; +@@ -968,7 +974,7 @@ static errno_t sdap_initgr_nested_deref_search(struct tevent_req *req) + + subreq = sdap_deref_search_send(state, state->ev, state->opts, + state->sh, state->orig_dn, +- state->opts->user_map[SDAP_AT_USER_MEMBEROF].name, ++ state->user_map[SDAP_AT_USER_MEMBEROF].name, + sdap_attrs, num_maps, maps, timeout); + if (!subreq) { + ret = EIO; +@@ -2697,6 +2703,8 @@ struct sdap_get_initgr_state { + struct tevent_context *ev; + struct sysdb_ctx *sysdb; + struct sdap_options *opts; ++ struct sdap_attr_map *user_map; ++ size_t user_map_cnt; + struct sss_domain_info *dom; + struct sdap_domain *sdom; + struct sdap_handle *sh; +@@ -2731,6 +2739,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + struct sdap_domain *sdom, + struct sdap_handle *sh, + struct sdap_id_ctx *id_ctx, ++ struct sdap_attr_map *user_map, ++ size_t user_map_cnt, + struct sdap_id_conn_ctx *conn, + struct sdap_search_base **search_bases, + const char *filter_value, +@@ -2754,6 +2764,12 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + + state->ev = ev; + state->opts = id_ctx->opts; ++ state->user_map = user_map; ++ state->user_map_cnt = user_map_cnt; ++ if (state->user_map == NULL) { ++ state->user_map = id_ctx->opts->user_map; ++ state->user_map_cnt = id_ctx->opts->user_map_cnt; ++ } + state->dom = sdom->dom; + state->sysdb = sdom->dom->sysdb; + state->sdom = sdom; +@@ -2785,7 +2801,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + + switch (filter_type) { + case BE_FILTER_SECID: +- search_attr = state->opts->user_map[SDAP_AT_USER_OBJECTSID].name; ++ search_attr = state->user_map[SDAP_AT_USER_OBJECTSID].name; + + ret = sss_filter_sanitize(state, state->filter_value, &clean_name); + if (ret != EOK) { +@@ -2794,7 +2810,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + } + break; + case BE_FILTER_UUID: +- search_attr = state->opts->user_map[SDAP_AT_USER_UUID].name; ++ search_attr = state->user_map[SDAP_AT_USER_UUID].name; + + ret = sss_filter_sanitize(state, state->filter_value, &clean_name); + if (ret != EOK) { +@@ -2812,23 +2828,23 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + } + + ep_filter = get_enterprise_principal_string_filter(state, +- state->opts->user_map[SDAP_AT_USER_PRINC].name, ++ state->user_map[SDAP_AT_USER_PRINC].name, + clean_name, state->opts->basic); + state->user_base_filter = + talloc_asprintf(state, + "(&(|(%s=%s)(%s=%s)%s)(objectclass=%s)", +- state->opts->user_map[SDAP_AT_USER_PRINC].name, ++ state->user_map[SDAP_AT_USER_PRINC].name, + clean_name, +- state->opts->user_map[SDAP_AT_USER_EMAIL].name, ++ state->user_map[SDAP_AT_USER_EMAIL].name, + clean_name, + ep_filter == NULL ? "" : ep_filter, +- state->opts->user_map[SDAP_OC_USER].name); ++ state->user_map[SDAP_OC_USER].name); + if (state->user_base_filter == NULL) { + talloc_zfree(req); + return NULL; + } + } else { +- search_attr = state->opts->user_map[SDAP_AT_USER_NAME].name; ++ search_attr = state->user_map[SDAP_AT_USER_NAME].name; + + ret = sss_parse_internal_fqname(state, filter_value, + &state->shortname, NULL); +@@ -2860,7 +2876,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + state->user_base_filter = + talloc_asprintf(state, "(&(%s=%s)(objectclass=%s)", + search_attr, clean_name, +- state->opts->user_map[SDAP_OC_USER].name); ++ state->user_map[SDAP_OC_USER].name); + if (!state->user_base_filter) { + talloc_zfree(req); + return NULL; +@@ -2877,14 +2893,14 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + */ + state->user_base_filter = talloc_asprintf_append(state->user_base_filter, + "(%s=*))", +- id_ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name); ++ state->user_map[SDAP_AT_USER_OBJECTSID].name); + } else { + /* When not ID-mapping or looking up app users, make sure there + * is a non-NULL UID */ + state->user_base_filter = talloc_asprintf_append(state->user_base_filter, + "(&(%s=*)(!(%s=0))))", +- id_ctx->opts->user_map[SDAP_AT_USER_UID].name, +- id_ctx->opts->user_map[SDAP_AT_USER_UID].name); ++ state->user_map[SDAP_AT_USER_UID].name, ++ state->user_map[SDAP_AT_USER_UID].name); + } + if (!state->user_base_filter) { + talloc_zfree(req); +@@ -2892,8 +2908,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, + } + + ret = build_attrs_from_map(state, +- state->opts->user_map, +- state->opts->user_map_cnt, ++ state->user_map, ++ state->user_map_cnt, + NULL, &state->user_attrs, NULL); + if (ret) { + talloc_zfree(req); +@@ -2990,7 +3006,7 @@ static errno_t sdap_get_initgr_next_base(struct tevent_req *req) + state->user_search_bases[state->user_base_iter]->basedn, + state->user_search_bases[state->user_base_iter]->scope, + state->filter, state->user_attrs, +- state->opts->user_map, state->opts->user_map_cnt, ++ state->user_map, state->user_map_cnt, + state->timeout, + false); + if (!subreq) { +@@ -3179,6 +3195,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq) + + case SDAP_SCHEMA_IPA_V1: + subreq = sdap_initgr_nested_send(state, state->ev, state->opts, ++ state->user_map, state->user_map_cnt, + state->sysdb, state->dom, state->sh, + state->orig_user, state->grp_attrs); + if (!subreq) { +@@ -3377,7 +3394,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq) + */ + ret = sdap_attrs_get_sid_str( + tmp_ctx, opts->idmap_ctx, state->orig_user, +- opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name, ++ state->user_map[SDAP_AT_USER_OBJECTSID].sys_name, + &sid_str); + if (ret != EOK) goto done; + +@@ -3392,7 +3409,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq) + + ret = sysdb_attrs_get_uint32_t( + state->orig_user, +- opts->user_map[SDAP_AT_USER_PRIMARY_GROUP].sys_name, ++ state->user_map[SDAP_AT_USER_PRIMARY_GROUP].sys_name, + &primary_gid); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, +-- +2.45.0 + diff --git a/SOURCES/0011-ad-use-default-user_map-when-looking-of-host-groups-.patch b/SOURCES/0011-ad-use-default-user_map-when-looking-of-host-groups-.patch new file mode 100644 index 0000000..6318be3 --- /dev/null +++ b/SOURCES/0011-ad-use-default-user_map-when-looking-of-host-groups-.patch @@ -0,0 +1,77 @@ +From 2c233636c093708d5cdd7ddb69af9b0ecde633bd Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 6 Sep 2024 14:37:05 +0200 +Subject: [PATCH 11/11] ad: use default user_map when looking of host groups + for GPO +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use the default AD user attribute map to lookup the group membership of +the AD host object. This should help to avoid issues if user attributes +are overwritten in the user attribute map. + +Resolves: https://github.com/SSSD/sssd/issues/7590 + +Reviewed-by: Justin Stephenson +Reviewed-by: Tomáš Halman +(cherry picked from commit 5f5077ac1158deff6fbb51722d37b9c5f8b05cf7) +--- + src/providers/ad/ad_access.h | 1 + + src/providers/ad/ad_gpo.c | 15 ++++++++++++++- + 2 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/src/providers/ad/ad_access.h b/src/providers/ad/ad_access.h +index 34d5597da..c54b53eed 100644 +--- a/src/providers/ad/ad_access.h ++++ b/src/providers/ad/ad_access.h +@@ -49,6 +49,7 @@ struct ad_access_ctx { + } gpo_map_type; + hash_table_t *gpo_map_options_table; + enum gpo_map_type gpo_default_right; ++ struct sdap_attr_map *host_attr_map; + }; + + struct tevent_req * +diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c +index fa68d814f..6b154f71d 100644 +--- a/src/providers/ad/ad_gpo.c ++++ b/src/providers/ad/ad_gpo.c +@@ -45,6 +45,7 @@ + #include "providers/ad/ad_common.h" + #include "providers/ad/ad_domain_info.h" + #include "providers/ad/ad_gpo.h" ++#include "providers/ad/ad_opts.h" + #include "providers/ldap/sdap_access.h" + #include "providers/ldap/sdap_async.h" + #include "providers/ldap/sdap.h" +@@ -2238,13 +2239,25 @@ ad_gpo_connect_done(struct tevent_req *subreq) + "trying with user search base."); + } + ++ if (state->access_ctx->host_attr_map == NULL) { ++ ret = sdap_copy_map(state->access_ctx, ++ ad_2008r2_user_map, SDAP_OPTS_USER, ++ &state->access_ctx->host_attr_map); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "Failed to copy user map.\n"); ++ goto done; ++ } ++ } ++ + subreq = groups_by_user_send(state, state->ev, + state->access_ctx->ad_id_ctx->sdap_id_ctx, + sdom, state->conn, + search_bases, + state->host_fqdn, + BE_FILTER_NAME, +- NULL, NULL, 0, ++ NULL, ++ state->access_ctx->host_attr_map, ++ SDAP_OPTS_USER, + true, + true); + tevent_req_set_callback(subreq, ad_gpo_target_dn_retrieval_done, req); +-- +2.45.0 + diff --git a/SOURCES/0011-krb5-make-prompter-and-pre-auth-debug-message-less-i.patch b/SOURCES/0011-krb5-make-prompter-and-pre-auth-debug-message-less-i.patch deleted file mode 100644 index 5126106..0000000 --- a/SOURCES/0011-krb5-make-prompter-and-pre-auth-debug-message-less-i.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 87b54bd8448760241e7071a585f95b3e2604355a Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 15 Mar 2024 12:35:00 +0100 -Subject: [PATCH 11/12] krb5: make prompter and pre-auth debug message less - irritating -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Resolves: https://github.com/SSSD/sssd/issues/7152 - -Reviewed-by: Alejandro López -Reviewed-by: Justin Stephenson -(cherry picked from commit e26cc69341bcfd2bbc758eca30df296431c70a28) ---- - src/providers/krb5/krb5_child.c | 15 +++++++++++---- - 1 file changed, 11 insertions(+), 4 deletions(-) - -diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c -index 926109588..494711de9 100644 ---- a/src/providers/krb5/krb5_child.c -+++ b/src/providers/krb5/krb5_child.c -@@ -1355,13 +1355,14 @@ static krb5_error_code sss_krb5_prompter(krb5_context context, void *data, - int ret; - size_t c; - struct krb5_req *kr = talloc_get_type(data, struct krb5_req); -+ const char *err_msg; - - if (kr == NULL) { - return EINVAL; - } - - DEBUG(SSSDBG_TRACE_ALL, -- "sss_krb5_prompter name [%s] banner [%s] num_prompts [%d] EINVAL.\n", -+ "sss_krb5_prompter name [%s] banner [%s] num_prompts [%d].\n", - name, banner, num_prompts); - - if (num_prompts != 0) { -@@ -1370,7 +1371,12 @@ static krb5_error_code sss_krb5_prompter(krb5_context context, void *data, - prompts[c].prompt); - } - -- DEBUG(SSSDBG_FUNC_DATA, "Prompter interface isn't used for password prompts by SSSD.\n"); -+ err_msg = krb5_get_error_message(context, KRB5_LIBOS_CANTREADPWD); -+ DEBUG(SSSDBG_FUNC_DATA, -+ "Prompter interface isn't used for prompting by SSSD." -+ "Returning the expected error [%ld/%s].\n", -+ KRB5_LIBOS_CANTREADPWD, err_msg); -+ krb5_free_error_message(context, err_msg); - return KRB5_LIBOS_CANTREADPWD; - } - -@@ -2839,8 +2845,9 @@ static errno_t tgt_req_child(struct krb5_req *kr) - * should now know which authentication methods are available to - * update the password. */ - DEBUG(SSSDBG_TRACE_FUNC, -- "krb5_get_init_creds_password returned [%d] during pre-auth, " -- "ignored.\n", kerr); -+ "krb5_get_init_creds_password returned [%d] while collecting " -+ "available authentication types, errors are expected " -+ "and ignored.\n", kerr); - ret = pam_add_prompting(kr); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_prompting failed.\n"); --- -2.42.0 - diff --git a/SOURCES/0012-pam_sss-prefer-Smartcard-authentication.patch b/SOURCES/0012-pam_sss-prefer-Smartcard-authentication.patch deleted file mode 100644 index 90e27c9..0000000 --- a/SOURCES/0012-pam_sss-prefer-Smartcard-authentication.patch +++ /dev/null @@ -1,70 +0,0 @@ -From d06b4a3eda612d1a54b6bdb3c3b779543bc23b0f Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 20 Mar 2024 11:26:16 +0100 -Subject: [PATCH 12/12] pam_sss: prefer Smartcard authentication -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The current behavior is that Smartcard authentication is preferred if -possible, i.e. if a Smartcard is present. Since the Smartcard (or -equivalent) must be inserted manually the assumption is that if the user -has inserted it they most probably want to use it for authentication. - -With the latest patches pam_sss might receive multiple available -authentication methods. With this patch the checks for available -authentication types start Smartcard authentication to mimic the -existing behavior. - -Resolves: https://github.com/SSSD/sssd/issues/7152 - -Reviewed-by: Alejandro López -Reviewed-by: Justin Stephenson -(cherry picked from commit 0d5e8f11714e8e6cc0ad28e03fecf0f5732528b3) ---- - src/sss_client/pam_sss.c | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - -diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c -index a1c353604..41a528dda 100644 ---- a/src/sss_client/pam_sss.c -+++ b/src/sss_client/pam_sss.c -@@ -2544,17 +2544,7 @@ static int get_authtok_for_authentication(pam_handle_t *pamh, - } else if (pi->pc != NULL) { - ret = prompt_by_config(pamh, pi); - } else { -- 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: "), -- _("Second Factor (optional): ")); -- } else { -- ret = prompt_2fa(pamh, pi, _("First Factor: "), -- _("Second Factor: ")); -- } -- } else if (pi->cert_list != NULL) { -+ if (pi->cert_list != NULL) { - if (pi->cert_list->next == NULL) { - /* Only one certificate */ - pi->selected_cert = pi->cert_list; -@@ -2570,6 +2560,16 @@ static int get_authtok_for_authentication(pam_handle_t *pamh, - || (pi->flags & PAM_CLI_FLAGS_REQUIRE_CERT_AUTH)) { - /* Use pin prompt as fallback for gdm-smartcard */ - ret = prompt_sc_pin(pamh, pi); -+ } else 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: "), -+ _("Second Factor (optional): ")); -+ } else { -+ ret = prompt_2fa(pamh, pi, _("First Factor: "), -+ _("Second Factor: ")); -+ } - } else if (pi->passkey_prompt_pin) { - ret = prompt_passkey(pamh, pi, - _("Insert your passkey device, then press ENTER."), --- -2.42.0 - diff --git a/SOURCES/0013-pam-fix-storing-auth-types-for-offline-auth.patch b/SOURCES/0013-pam-fix-storing-auth-types-for-offline-auth.patch deleted file mode 100644 index e9220d5..0000000 --- a/SOURCES/0013-pam-fix-storing-auth-types-for-offline-auth.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 163db8465e815984abac0ba9af097589045791da Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 22 Mar 2024 19:53:29 +0100 -Subject: [PATCH] pam: fix storing auth types for offline auth - -Before the recent patches which allow krb5_child to iterate over all -available authentication methods typically only one method was returned. -E.g. is Smartcard authentication (pkinit) was possible it was typically -the first method the in question list and the result of the -answer_pkinit() function was immediately returned. As a result only the -Smartcard authentication type was set and a missing password -authentication type while others were present might have been a -reasonable indicator for the online state. - -With the recent patches, all available methods, including password -authentication if available, are return and a new indicator is needed. ---- - src/responder/pam/pamsrv.h | 1 + - src/responder/pam/pamsrv_cmd.c | 3 ++- - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h -index 618836189..2aa14ae02 100644 ---- a/src/responder/pam/pamsrv.h -+++ b/src/responder/pam/pamsrv.h -@@ -114,6 +114,7 @@ struct pam_resp_auth_type { - bool otp_auth; - bool cert_auth; - bool passkey_auth; -+ bool backend_returned_no_auth_type; - }; - - struct sss_cmd_table *get_pam_cmds(void); -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index 13ba13131..94895d48e 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -915,6 +915,7 @@ errno_t pam_get_auth_types(struct pam_data *pd, - /* If the backend cannot determine which authentication types are - * available the default would be to prompt for a password. */ - types.password_auth = true; -+ types.backend_returned_no_auth_type = true; - } - - DEBUG(SSSDBG_TRACE_ALL, "Authentication types for user [%s] and service " -@@ -1002,7 +1003,7 @@ static errno_t pam_eval_local_auth_policy(TALLOC_CTX *mem_ctx, - } - - /* Store the local auth types, in case we go offline */ -- if (!auth_types.password_auth) { -+ if (!auth_types.backend_returned_no_auth_type) { - ret = set_local_auth_type(preq, sc_allow, passkey_allow); - if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, --- -2.42.0 - diff --git a/SOURCES/0014-ad-gpo-use-hash-to-store-intermediate-results.patch b/SOURCES/0014-ad-gpo-use-hash-to-store-intermediate-results.patch deleted file mode 100644 index 5bb0332..0000000 --- a/SOURCES/0014-ad-gpo-use-hash-to-store-intermediate-results.patch +++ /dev/null @@ -1,218 +0,0 @@ -From e1bfbc2493c4194988acc3b2413df3dde0735ae3 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 8 Nov 2023 14:50:24 +0100 -Subject: [PATCH] ad-gpo: use hash to store intermediate results -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently after the evaluation of a single GPO file the intermediate -results are stored in the cache and this cache entry is updated until -all applicable GPO files are evaluated. Finally the data in the cache is -used to make the decision of access is granted or rejected. - -If there are two or more access-control request running in parallel one -request might overwrite the cache object with intermediate data while -another request reads the cached data for the access decision and as a -result will do this decision based on intermediate data. - -To avoid this the intermediate results are not stored in the cache -anymore but in hash tables which are specific to the request. Only the -final result is written to the cache to have it available for offline -authentication. - -Reviewed-by: Alexey Tikhonov -Reviewed-by: Tomáš Halman -(cherry picked from commit d7db7971682da2dbf7642ac94940d6b0577ec35a) ---- - src/providers/ad/ad_gpo.c | 116 +++++++++++++++++++++++++++++++++----- - 1 file changed, 102 insertions(+), 14 deletions(-) - -diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c -index 3d1ad39c7..b879b0a08 100644 ---- a/src/providers/ad/ad_gpo.c -+++ b/src/providers/ad/ad_gpo.c -@@ -1431,6 +1431,33 @@ ad_gpo_extract_policy_setting(TALLOC_CTX *mem_ctx, - return ret; - } - -+static errno_t -+add_result_to_hash(hash_table_t *hash, const char *key, char *value) -+{ -+ int hret; -+ hash_key_t k; -+ hash_value_t v; -+ -+ if (hash == NULL || key == NULL || value == NULL) { -+ return EINVAL; -+ } -+ -+ k.type = HASH_KEY_CONST_STRING; -+ k.c_str = key; -+ -+ v.type = HASH_VALUE_PTR; -+ v.ptr = value; -+ -+ hret = hash_enter(hash, &k, &v); -+ if (hret != HASH_SUCCESS) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to add [%s][%s] to hash: [%s].\n", -+ key, value, hash_error_string(hret)); -+ return EIO; -+ } -+ -+ return EOK; -+} -+ - /* - * This function parses the cse-specific (GP_EXT_GUID_SECURITY) filename, - * and stores the allow_key and deny_key of all of the gpo_map_types present -@@ -1438,6 +1465,7 @@ ad_gpo_extract_policy_setting(TALLOC_CTX *mem_ctx, - */ - static errno_t - ad_gpo_store_policy_settings(struct sss_domain_info *domain, -+ hash_table_t *allow_maps, hash_table_t *deny_maps, - const char *filename) - { - struct ini_cfgfile *file_ctx = NULL; -@@ -1571,14 +1599,14 @@ ad_gpo_store_policy_settings(struct sss_domain_info *domain, - goto done; - } else if (ret != ENOENT) { - const char *value = allow_value ? allow_value : empty_val; -- ret = sysdb_gpo_store_gpo_result_setting(domain, -- allow_key, -- value); -+ ret = add_result_to_hash(allow_maps, allow_key, -+ talloc_strdup(allow_maps, value)); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "sysdb_gpo_store_gpo_result_setting failed for key:" -- "'%s' value:'%s' [%d][%s]\n", allow_key, allow_value, -- ret, sss_strerror(ret)); -+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add key: [%s] " -+ "value: [%s] to allow maps " -+ "[%d][%s].\n", -+ allow_key, value, ret, -+ sss_strerror(ret)); - goto done; - } - } -@@ -1598,14 +1626,14 @@ ad_gpo_store_policy_settings(struct sss_domain_info *domain, - goto done; - } else if (ret != ENOENT) { - const char *value = deny_value ? deny_value : empty_val; -- ret = sysdb_gpo_store_gpo_result_setting(domain, -- deny_key, -- value); -+ ret = add_result_to_hash(deny_maps, deny_key, -+ talloc_strdup(deny_maps, value)); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "sysdb_gpo_store_gpo_result_setting failed for key:" -- "'%s' value:'%s' [%d][%s]\n", deny_key, deny_value, -- ret, sss_strerror(ret)); -+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add key: [%s] " -+ "value: [%s] to deny maps " -+ "[%d][%s].\n", -+ deny_key, value, ret, -+ sss_strerror(ret)); - goto done; - } - } -@@ -1902,6 +1930,8 @@ struct ad_gpo_access_state { - int num_cse_filtered_gpos; - int cse_gpo_index; - const char *ad_domain; -+ hash_table_t *allow_maps; -+ hash_table_t *deny_maps; - }; - - static void ad_gpo_connect_done(struct tevent_req *subreq); -@@ -2023,6 +2053,19 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx, - goto immediately; - } - -+ ret = sss_hash_create(state, 0, &state->allow_maps); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_FATAL_FAILURE, "Could not create allow maps " -+ "hash table [%d]: %s\n", ret, sss_strerror(ret)); -+ goto immediately; -+ } -+ -+ ret = sss_hash_create(state, 0, &state->deny_maps); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_FATAL_FAILURE, "Could not create deny maps " -+ "hash table [%d]: %s\n", ret, sss_strerror(ret)); -+ goto immediately; -+ } - - subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); - if (subreq == NULL) { -@@ -2713,6 +2756,43 @@ ad_gpo_cse_step(struct tevent_req *req) - return EAGAIN; - } - -+static errno_t -+store_hash_maps_in_cache(struct sss_domain_info *domain, -+ hash_table_t *allow_maps, hash_table_t *deny_maps) -+{ -+ int ret; -+ struct hash_iter_context_t *iter; -+ hash_entry_t *entry; -+ size_t c; -+ hash_table_t *hash_list[] = { allow_maps, deny_maps, NULL}; -+ -+ -+ for (c = 0; hash_list[c] != NULL; c++) { -+ iter = new_hash_iter_context(hash_list[c]); -+ if (iter == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to create hash iterator.\n"); -+ return EINVAL; -+ } -+ -+ while ((entry = iter->next(iter)) != NULL) { -+ ret = sysdb_gpo_store_gpo_result_setting(domain, -+ entry->key.c_str, -+ entry->value.ptr); -+ if (ret != EOK) { -+ free(iter); -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sysdb_gpo_store_gpo_result_setting failed for key:" -+ "[%s] value:[%s] [%d][%s]\n", entry->key.c_str, -+ (char *) entry->value.ptr, ret, sss_strerror(ret)); -+ return ret; -+ } -+ } -+ talloc_free(iter); -+ } -+ -+ return EOK; -+} -+ - /* - * This cse-specific function (GP_EXT_GUID_SECURITY) increments the - * cse_gpo_index until the policy settings for all applicable GPOs have been -@@ -2754,6 +2834,7 @@ ad_gpo_cse_done(struct tevent_req *subreq) - * (as part of the GPO Result object in the sysdb cache). - */ - ret = ad_gpo_store_policy_settings(state->host_domain, -+ state->allow_maps, state->deny_maps, - cse_filtered_gpo->policy_filename); - if (ret != EOK && ret != ENOENT) { - DEBUG(SSSDBG_OP_FAILURE, -@@ -2767,6 +2848,13 @@ ad_gpo_cse_done(struct tevent_req *subreq) - - if (ret == EOK) { - /* ret is EOK only after all GPO policy files have been downloaded */ -+ ret = store_hash_maps_in_cache(state->host_domain, -+ state->allow_maps, state->deny_maps); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to store evaluated GPO maps " -+ "[%d][%s].\n", ret, sss_strerror(ret)); -+ goto done; -+ } - ret = ad_gpo_perform_hbac_processing(state, - state->gpo_mode, - state->gpo_map_type, --- -2.44.0 - diff --git a/SOURCES/0015-tests-Drop-extensions-from-openssl-command-if-there-.patch b/SOURCES/0015-tests-Drop-extensions-from-openssl-command-if-there-.patch deleted file mode 100644 index e7ddccc..0000000 --- a/SOURCES/0015-tests-Drop-extensions-from-openssl-command-if-there-.patch +++ /dev/null @@ -1,49 +0,0 @@ -From a453f9625b40a0a1fbcf055ffa196121f2b248b5 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 24 Jan 2024 23:03:04 +0100 -Subject: [PATCH] tests: Drop -extensions from openssl command if there is no - -x509 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The 'openssl req' ignores the '-extensions' option without '-x509'. -OpenSSL versions prior 3.2 simply ignored it. Starting with version 3.2 -an error is generated: - -| /usr/bin/openssl req -batch -config -| ../../../../../src/tests/test_CA/intermediate_CA/SSSD_test_intermediate_CA.config -| -new -nodes -key -| …/build/../src/tests/test_CA/intermediate_CA/SSSD_test_intermediate_CA_key.pem --sha256 -extensions v3_ca -out SSSD_test_intermediate_CA_req.pem -| Error adding request extensions from section v3_ca -| 003163BAB27F0000:error:11000079:X509 V3 routines:v2i_AUTHORITY_KEYID:no issuer certificate:../crypto/x509/v3_akid.c:156: -| 003163BAB27F0000:error:11000080:X509 V3 routines:X509V3_EXT_nconf_int:error in extension:../crypto/x509/v3_conf.c:48:section=v3_ca, name=authorityKeyIdentifier, value=keyid:always,issuer:always -| - -Remove the '-extensions' option. - -Signed-off-by: Sebastian Andrzej Siewior - -Reviewed-by: Sumit Bose -(cherry picked from commit 32b72c7c3303edb2bf55ae9a22e8db7855f3d7d1) ---- - src/tests/test_CA/intermediate_CA/Makefile.am | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/tests/test_CA/intermediate_CA/Makefile.am b/src/tests/test_CA/intermediate_CA/Makefile.am -index b439f82cb..50fcddb8d 100644 ---- a/src/tests/test_CA/intermediate_CA/Makefile.am -+++ b/src/tests/test_CA/intermediate_CA/Makefile.am -@@ -33,7 +33,7 @@ SSSD_test_CA.pem: - ln -s $(builddir)/../$@ - - SSSD_test_intermediate_CA_req.pem: $(openssl_intermediate_ca_key) $(openssl_intermediate_ca_config) SSSD_test_CA.pem -- $(OPENSSL) req -batch -config ${openssl_intermediate_ca_config} -new -nodes -key $< -sha256 -extensions v3_ca -out $@ -+ $(OPENSSL) req -batch -config ${openssl_intermediate_ca_config} -new -nodes -key $< -sha256 -out $@ - - SSSD_test_intermediate_CA.pem: SSSD_test_intermediate_CA_req.pem $(openssl_root_ca_config) $(openssl_root_ca_key) - cd .. && $(OPENSSL) ca -config ${openssl_root_ca_config} -batch -notext -keyfile $(openssl_root_ca_key) -in $(abs_builddir)/$< -days 200 -extensions v3_intermediate_ca -out $(abs_builddir)/$@ --- -2.44.0 - diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec index bc684b2..0686bc1 100644 --- a/SPECS/sssd.spec +++ b/SPECS/sssd.spec @@ -26,29 +26,25 @@ %global samba_package_version %(rpm -q samba-devel --queryformat %{version}-%{release}) Name: sssd -Version: 2.9.4 -Release: 6%{?dist} +Version: 2.9.5 +Release: 4%{?dist}.1 Summary: System Security Services Daemon License: GPLv3+ URL: https://github.com/SSSD/sssd/ Source0: https://github.com/SSSD/sssd/releases/download/%{version}/sssd-%{version}.tar.gz ### Patches ### -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 -Patch0009: 0009-krb5-add-OTP-to-krb5-response-selection.patch -Patch0010: 0010-krb5-make-sure-answer_pkinit-use-matching-debug-mess.patch -Patch0011: 0011-krb5-make-prompter-and-pre-auth-debug-message-less-i.patch -Patch0012: 0012-pam_sss-prefer-Smartcard-authentication.patch -Patch0013: 0013-pam-fix-storing-auth-types-for-offline-auth.patch -Patch0014: 0014-ad-gpo-use-hash-to-store-intermediate-results.patch -Patch0015: 0015-tests-Drop-extensions-from-openssl-command-if-there-.patch +Patch0001: 0001-spec-change-passkey_child-owner.patch +Patch0002: 0002-sysdb-do-not-fail-to-add-non-posix-user-to-MPG-domai.patch +Patch0003: 0003-ad-use-right-memory-context-in-GPO-code.patch +Patch0004: 0004-TS_CACHE-never-try-to-upgrade-timestamps-cache.patch +Patch0005: 0005-SYSDB-remove-index-on-dataExpireTimestamp.patch +Patch0006: 0006-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch +Patch0007: 0007-krb5_child-do-not-try-passwords-with-OTP.patch +Patch0008: 0008-pam_sss-add-missing-optional-2nd-factor-handling.patch +Patch0009: 0009-pam-only-set-SYSDB_LOCAL_SMARTCARD_AUTH-to-true-but-.patch +Patch0010: 0010-sdap-allow-to-provide-user_map-when-looking-up-group.patch +Patch0011: 0011-ad-use-default-user_map-when-looking-of-host-groups-.patch ### Dependencies ### @@ -1004,7 +1000,7 @@ done %config(noreplace) %{_sysconfdir}/krb5.conf.d/sssd_enable_idp %files passkey -%attr(755,%{sssd_user},%{sssd_user}) %{_libexecdir}/%{servicename}/passkey_child +%{_libexecdir}/%{servicename}/passkey_child %{_libdir}/%{name}/modules/sssd_krb5_passkey_plugin.so %{_datadir}/sssd/krb5-snippets/sssd_enable_passkey %config(noreplace) %{_sysconfdir}/krb5.conf.d/sssd_enable_passkey @@ -1098,6 +1094,37 @@ fi %systemd_postun_with_restart sssd.service %changelog +* Tue Sep 24 2024 Alexey Tikhonov - 2.9.5-4.1 +- Resolves: RHEL-59876 - EL9/CentOS Stream 9 lost offline smart card authentication +- Resolves: RHEL-50912 - possible regression of rhbz#2196521 + +* Thu Jul 18 2024 Alexey Tikhonov - 2.9.5-4 +- Resolves: RHEL-49711 - SYSDB: remove index on dataExpireTimestamp +- Resolves: RHEL-49811 - 2FA is being enforced after upgrading 2.9.1->2.9.4 + +* Mon Jul 8 2024 Alexey Tikhonov - 2.9.5-3 +- Resolves: RHEL-40742 - passkey_child with wrong owner + +* Mon Jun 24 2024 Alexey Tikhonov - 2.9.5-2 +- Resolves: RHEL-40742 - passkey_child with wrong owner +- Resolves: RHEL-41047 - sssd is skipping GPO evaluation with auto_private_groups +- Resolves: RHEL-40570 - GPO access the wrong memory location + +* Thu May 16 2024 Alexey Tikhonov - 2.9.5-1 +- Resolves: RHEL-36586 - Rebase SSSD for RHEL 9.5 +- Resolves: RHEL-27716 - SSSD fails to process AD groups with 'Global Scope' correctly causing incomplete group-membership on RHEL if cache is empty +- Resolves: RHEL-17659 - [RfE] SSSD Failover Enhancements +- Resolves: RHEL-35781 - Passkey errors when handling multiple altSecurityIdentities values +- Resolves: RHEL-30142 - sssd_pac is crashing +- Resolves: RHEL-22206 - Errors in krb5_child.log every time a user authenticates - Pre-authentication failed: No pkinit_anchors supplied +- Resolves: RHEL-32595 - Excessive "Domain not found' messages logged to sssd_nss & sssd_be in multidomain AD forest +- Resolves: RHEL-28666 - sssctl config-check is reporting false positive error msg +- Resolves: RHEL-29454 - NULL dereference in inotify handling +- Resolves: RHEL-1654 - Improve documentation for allowing e-mail address as username + +* Mon Apr 29 2024 Alexey Tikhonov - 2.9.4-7 +- Relates: RHEL-33645 - Rebase Samba to the latest 4.20.x release + * Thu Apr 18 2024 Alexey Tikhonov - 2.9.4-6 - Resolves: RHEL-27209 - Race condition during authorization leads to GPO policies functioning inconsistently [rhel-9.4.0]