From 069a9c7f44d70a13969c633fa2802f4f96bcc4b0 Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Wed, 1 May 2024 04:03:53 +0300 Subject: [PATCH] import sssd-2.9.4-6.el9_4 --- .gitignore | 2 +- .sssd.metadata | 2 +- ...sssd-adding-mail-as-case-insensitive.patch | 144 +++ ...m_watchdog-and-disarm_watchdog-calls.patch | 106 --- ...-watchdog-for-sbus_connect_init_send.patch | 53 -- ..._bases-option-to-groups_by_user_send.patch | 154 ++++ ...cover-from-invalid-memory-cache-size.patch | 224 ----- ...context-as-new-member-of-struct-sdap.patch | 194 ++++ ...with-multiple-certs-and-missing-logi.patch | 233 +++++ ...iface-do-not-add-cli_id-to-chain-key.patch | 404 -------- ...rb5-1.21-for-building-the-PAC-plugin.patch | 34 - ...lient-handle-key-value-in-destructor.patch | 50 + ...dditions-to-recover-from-invalid-mem.patch | 336 ------- ...fallback-between-responder-questions.patch | 104 +++ ...lace-__thread-with-pthread_-specific.patch | 388 -------- ...Add-fallback-password-change-support.patch | 206 +++++ ...vel-in-case-a-responder-asks-for-unk.patch | 32 - .../0008-pam-fix-invalid-if-condition.patch | 30 + ...-case-mem-cache-file-validation-fail.patch | 49 - ...5-add-OTP-to-krb5-response-selection.patch | 185 ++++ ...T-check-if-mem-cache-fd-was-hijacked.patch | 86 -- ...nswer_pkinit-use-matching-debug-mess.patch | 119 +++ ...heck-if-reponder-socket-was-hijacked.patch | 44 - ...er-and-pre-auth-debug-message-less-i.patch | 67 ++ ...make-groups_by_user_send-recv-public.patch | 73 -- ..._sss-prefer-Smartcard-authentication.patch | 70 ++ SOURCES/0013-ad-gpo-evalute-host-groups.patch | 627 ------------- ...-storing-auth-types-for-offline-auth.patch | 57 ++ ...e-hash-to-store-intermediate-results.patch | 218 +++++ ...0014-sysdb-remove-sysdb_computer.-ch.patch | 307 ------ ...015-sdap-add-set_non_posix-parameter.patch | 351 ------- ...sions-from-openssl-command-if-there-.patch | 49 + ...SSKEY-conditional-for-passkey-codepa.patch | 59 -- ...0017-pam-Conditionalize-passkey-code.patch | 872 ------------------ ...le-Respect-BUILD_PASSKEY-conditional.patch | 80 -- SPECS/sssd.spec | 125 ++- 36 files changed, 1967 insertions(+), 4167 deletions(-) create mode 100644 SOURCES/0001-sssd-adding-mail-as-case-insensitive.patch delete mode 100644 SOURCES/0001-watchdog-add-arm_watchdog-and-disarm_watchdog-calls.patch delete mode 100644 SOURCES/0002-sbus-arm-watchdog-for-sbus_connect_init_send.patch create mode 100644 SOURCES/0002-sdap-add-search_bases-option-to-groups_by_user_send.patch delete mode 100644 SOURCES/0003-mc-recover-from-invalid-memory-cache-size.patch create mode 100644 SOURCES/0003-sdap-add-naming_context-as-new-member-of-struct-sdap.patch create mode 100644 SOURCES/0004-pam-fix-SC-auth-with-multiple-certs-and-missing-logi.patch delete mode 100644 SOURCES/0004-sss_iface-do-not-add-cli_id-to-chain-key.patch delete mode 100644 SOURCES/0005-BUILD-Accept-krb5-1.21-for-building-the-PAC-plugin.patch create mode 100644 SOURCES/0005-sss-client-handle-key-value-in-destructor.patch delete mode 100644 SOURCES/0006-MC-a-couple-of-additions-to-recover-from-invalid-mem.patch create mode 100644 SOURCES/0006-krb5-Allow-fallback-between-responder-questions.patch delete mode 100644 SOURCES/0007-SSS_CLIENT-replace-__thread-with-pthread_-specific.patch create mode 100644 SOURCES/0007-krb5-Add-fallback-password-change-support.patch delete mode 100644 SOURCES/0008-DP-reduce-log-level-in-case-a-responder-asks-for-unk.patch create mode 100644 SOURCES/0008-pam-fix-invalid-if-condition.patch delete mode 100644 SOURCES/0009-SSS_CLIENT-MC-in-case-mem-cache-file-validation-fail.patch create mode 100644 SOURCES/0009-krb5-add-OTP-to-krb5-response-selection.patch delete mode 100644 SOURCES/0010-SSS_CLIENT-check-if-mem-cache-fd-was-hijacked.patch create mode 100644 SOURCES/0010-krb5-make-sure-answer_pkinit-use-matching-debug-mess.patch delete mode 100644 SOURCES/0011-SSS_CLIENT-check-if-reponder-socket-was-hijacked.patch create mode 100644 SOURCES/0011-krb5-make-prompter-and-pre-auth-debug-message-less-i.patch delete mode 100644 SOURCES/0012-LDAP-make-groups_by_user_send-recv-public.patch create mode 100644 SOURCES/0012-pam_sss-prefer-Smartcard-authentication.patch delete mode 100644 SOURCES/0013-ad-gpo-evalute-host-groups.patch create mode 100644 SOURCES/0013-pam-fix-storing-auth-types-for-offline-auth.patch create mode 100644 SOURCES/0014-ad-gpo-use-hash-to-store-intermediate-results.patch delete mode 100644 SOURCES/0014-sysdb-remove-sysdb_computer.-ch.patch delete mode 100644 SOURCES/0015-sdap-add-set_non_posix-parameter.patch create mode 100644 SOURCES/0015-tests-Drop-extensions-from-openssl-command-if-there-.patch delete mode 100644 SOURCES/0016-ipa-Add-BUILD_PASSKEY-conditional-for-passkey-codepa.patch delete mode 100644 SOURCES/0017-pam-Conditionalize-passkey-code.patch delete mode 100644 SOURCES/0018-Makefile-Respect-BUILD_PASSKEY-conditional.patch diff --git a/.gitignore b/.gitignore index 4714c8c..d510690 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/sssd-2.9.1.tar.gz +SOURCES/sssd-2.9.4.tar.gz diff --git a/.sssd.metadata b/.sssd.metadata index 9b2fbfd..eaa72f2 100644 --- a/.sssd.metadata +++ b/.sssd.metadata @@ -1 +1 @@ -5eb0d3e600aed685a7e3ea49154dadef52361f84 SOURCES/sssd-2.9.1.tar.gz +574f6cec9ee12dd943e4305286845343ab7bb891 SOURCES/sssd-2.9.4.tar.gz diff --git a/SOURCES/0001-sssd-adding-mail-as-case-insensitive.patch b/SOURCES/0001-sssd-adding-mail-as-case-insensitive.patch new file mode 100644 index 0000000..1e12d0b --- /dev/null +++ b/SOURCES/0001-sssd-adding-mail-as-case-insensitive.patch @@ -0,0 +1,144 @@ +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/0001-watchdog-add-arm_watchdog-and-disarm_watchdog-calls.patch b/SOURCES/0001-watchdog-add-arm_watchdog-and-disarm_watchdog-calls.patch deleted file mode 100644 index 6a77149..0000000 --- a/SOURCES/0001-watchdog-add-arm_watchdog-and-disarm_watchdog-calls.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 2cd5a6a2c8fd1826177d6bb51e7d4f4ad368bcfb Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 9 Jun 2023 12:31:39 +0200 -Subject: [PATCH 1/2] watchdog: add arm_watchdog() and disarm_watchdog() calls -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Those two new calls can be used if there are requests stuck by e.g. -waiting on replies where there is no other way to handle the timeout and -get the system back into a stable state. They should be only used as a -last resort. - -Resolves: https://github.com/SSSD/sssd/issues/6803 - -Reviewed-by: Alexey Tikhonov -Reviewed-by: Pavel Březina -(cherry picked from commit 75f2b35ad3b9256de905d05c5108400d35688554) ---- - src/util/util.h | 12 ++++++++++++ - src/util/util_watchdog.c | 28 ++++++++++++++++++++++++++-- - 2 files changed, 38 insertions(+), 2 deletions(-) - -diff --git a/src/util/util.h b/src/util/util.h -index a8356e0cd..9dbcf3301 100644 ---- a/src/util/util.h -+++ b/src/util/util.h -@@ -756,6 +756,18 @@ int setup_watchdog(struct tevent_context *ev, int interval); - void teardown_watchdog(void); - int get_watchdog_ticks(void); - -+/* The arm_watchdog() and disarm_watchdog() calls will disable and re-enable -+ * the watchdog reset, respectively. This means that after arm_watchdog() is -+ * called the watchdog will not be resetted anymore and it will kill the -+ * process if disarm_watchdog() wasn't called before. -+ * Those calls should only be used when there is no other way to handle -+ * waiting request and recover into a stable state. -+ * Those calls cannot be nested, i.e. after calling arm_watchdog() it should -+ * not be called a second time in a different request because then -+ * disarm_watchdog() will disable the watchdog coverage for both. */ -+void arm_watchdog(void); -+void disarm_watchdog(void); -+ - /* from files.c */ - int sss_remove_tree(const char *root); - int sss_remove_subtree(const char *root); -diff --git a/src/util/util_watchdog.c b/src/util/util_watchdog.c -index b1534e499..abafd94b9 100644 ---- a/src/util/util_watchdog.c -+++ b/src/util/util_watchdog.c -@@ -40,6 +40,7 @@ struct watchdog_ctx { - time_t timestamp; - struct tevent_fd *tfd; - int pipefd[2]; -+ bool armed; /* if 'true' ticks counter will not be reset */ - } watchdog_ctx; - - static void watchdog_detect_timeshift(void) -@@ -89,8 +90,13 @@ static void watchdog_event_handler(struct tevent_context *ev, - struct timeval current_time, - void *private_data) - { -- /* first thing reset the watchdog ticks */ -- watchdog_reset(); -+ if (!watchdog_ctx.armed) { -+ /* first thing reset the watchdog ticks */ -+ watchdog_reset(); -+ } else { -+ DEBUG(SSSDBG_IMPORTANT_INFO, -+ "Watchdog armed, process might be terminated soon.\n"); -+ } - - /* then set a new watchodg event */ - watchdog_ctx.te = tevent_add_timer(ev, ev, -@@ -197,6 +203,7 @@ int setup_watchdog(struct tevent_context *ev, int interval) - watchdog_ctx.ev = ev; - watchdog_ctx.input_interval = interval; - watchdog_ctx.timestamp = time(NULL); -+ watchdog_ctx.armed = false; - - ret = pipe(watchdog_ctx.pipefd); - if (ret == -1) { -@@ -264,3 +271,20 @@ int get_watchdog_ticks(void) - { - return __sync_add_and_fetch(&watchdog_ctx.ticks, 0); - } -+ -+void arm_watchdog(void) -+{ -+ if (watchdog_ctx.armed) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "arm_watchdog() is called although the watchdog is already armed. " -+ "This indicates a programming error and should be avoided because " -+ "it will most probably not work as expected.\n"); -+ } -+ -+ watchdog_ctx.armed = true; -+} -+ -+void disarm_watchdog(void) -+{ -+ watchdog_ctx.armed = false; -+} --- -2.38.1 - diff --git a/SOURCES/0002-sbus-arm-watchdog-for-sbus_connect_init_send.patch b/SOURCES/0002-sbus-arm-watchdog-for-sbus_connect_init_send.patch deleted file mode 100644 index 99e7c04..0000000 --- a/SOURCES/0002-sbus-arm-watchdog-for-sbus_connect_init_send.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 55564defec8fdbb4d9df6b0124a8b18b31743230 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 9 Jun 2023 13:01:47 +0200 -Subject: [PATCH 2/2] sbus: arm watchdog for sbus_connect_init_send() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There seem to be conditions where the reply in the -sbus_call_DBus_Hello_send() request gets lost and the backend cannot -properly initialize its sbus/DBus server. Since the backend cannot be -connected by the frontends in this state the best way to recover would -be a restart. Since the event-loop is active in this state, e.g. waiting -for the reply, the watchdog will not consider the process as hung and -will not restart the process. - -To make the watchdog handle this case arm_watchdog() and -disarm_watchdog() are called before and after the request, respectively. - -Resolves: https://github.com/SSSD/sssd/issues/6803 - -Reviewed-by: Alexey Tikhonov -Reviewed-by: Pavel Březina -(cherry picked from commit cca9361d92501e0be34d264d370fe897a0c970af) ---- - src/sbus/connection/sbus_connection_connect.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/sbus/connection/sbus_connection_connect.c b/src/sbus/connection/sbus_connection_connect.c -index 45a0fa491..edc090e15 100644 ---- a/src/sbus/connection/sbus_connection_connect.c -+++ b/src/sbus/connection/sbus_connection_connect.c -@@ -67,6 +67,8 @@ sbus_connect_init_send(TALLOC_CTX *mem_ctx, - - tevent_req_set_callback(subreq, sbus_connect_init_hello_done, req); - -+ arm_watchdog(); -+ - return req; - } - -@@ -111,6 +113,8 @@ static void sbus_connect_init_done(struct tevent_req *subreq) - uint32_t res; - errno_t ret; - -+ disarm_watchdog(); -+ - req = tevent_req_callback_data(subreq, struct tevent_req); - - ret = sbus_call_DBus_RequestName_recv(subreq, &res); --- -2.38.1 - 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 new file mode 100644 index 0000000..e7f048f --- /dev/null +++ b/SOURCES/0002-sdap-add-search_bases-option-to-groups_by_user_send.patch @@ -0,0 +1,154 @@ +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/0003-mc-recover-from-invalid-memory-cache-size.patch b/SOURCES/0003-mc-recover-from-invalid-memory-cache-size.patch deleted file mode 100644 index de35768..0000000 --- a/SOURCES/0003-mc-recover-from-invalid-memory-cache-size.patch +++ /dev/null @@ -1,224 +0,0 @@ -From be1ff918d0fd1701a21c3688daad0a90682a1f1d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Fri, 4 Aug 2023 12:19:49 +0200 -Subject: [PATCH] mc: recover from invalid memory cache size - -If we access the mmap file outside its boundaries a SIGBUS is raised. -We can now safely recover if the file has unexpected size. - -Reviewed-by: Alexey Tikhonov -Reviewed-by: Sumit Bose -(cherry picked from commit 641e5f73d3bd5b3d32cafd551013d3bfd2a52732) ---- - src/responder/nss/nsssrv_mmap_cache.c | 86 +++++++++++++++++++++------ - src/sss_client/nss_mc_common.c | 42 +++++++++---- - 2 files changed, 100 insertions(+), 28 deletions(-) - -diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c -index 12c299659..bd814f3bc 100644 ---- a/src/responder/nss/nsssrv_mmap_cache.c -+++ b/src/responder/nss/nsssrv_mmap_cache.c -@@ -722,6 +722,57 @@ static errno_t sss_mmap_cache_invalidate(struct sss_mc_ctx *mcc, - return EOK; - } - -+static errno_t sss_mmap_cache_validate_or_reinit(struct sss_mc_ctx **_mcc) -+{ -+ struct sss_mc_ctx *mcc = *_mcc; -+ struct stat fdstat; -+ bool reinit = false; -+ errno_t ret; -+ -+ /* No mcc initialized? Memory cache may be disabled. */ -+ if (mcc == NULL || mcc->fd < 0) { -+ ret = EINVAL; -+ reinit = false; -+ goto done; -+ } -+ -+ if (fstat(mcc->fd, &fdstat) == -1) { -+ ret = errno; -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Unable to stat memory cache [file=%s, fd=%d] [%d]: %s\n", -+ mcc->file, mcc->fd, ret, sss_strerror(ret)); -+ reinit = true; -+ goto done; -+ } -+ -+ if (fdstat.st_nlink == 0) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Memory cache file was removed\n"); -+ ret = ENOENT; -+ reinit = true; -+ goto done; -+ } -+ -+ if (fdstat.st_size != mcc->mmap_size) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Memory cache is corrupted, invalid size [file=%s, fd=%d, " -+ "expected_size=%zu, real_size=%zu]\n", -+ mcc->file, mcc->fd, mcc->mmap_size, fdstat.st_size); -+ ret = EINVAL; -+ reinit = true; -+ goto done; -+ } -+ -+ ret = EOK; -+ reinit = false; -+ -+done: -+ if (reinit) { -+ return sss_mmap_cache_reinit(talloc_parent(mcc), -1, -1, -1, -1, _mcc); -+ } -+ -+ return ret; -+} -+ - /*************************************************************************** - * passwd map - ***************************************************************************/ -@@ -744,9 +795,9 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc, - size_t pos; - int ret; - -- if (mcc == NULL) { -- /* cache not initialized? */ -- return EINVAL; -+ ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ if (ret != EOK) { -+ return ret; - } - - ret = snprintf(uidstr, 11, "%ld", (long)uid); -@@ -815,9 +866,9 @@ errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid) - char *uidstr; - errno_t ret; - -- if (mcc == NULL) { -- /* cache not initialized? */ -- return EINVAL; -+ ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ if (ret != EOK) { -+ return ret; - } - - uidstr = talloc_asprintf(NULL, "%ld", (long)uid); -@@ -886,9 +937,9 @@ int sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc, - size_t pos; - int ret; - -- if (mcc == NULL) { -- /* cache not initialized? */ -- return EINVAL; -+ ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ if (ret != EOK) { -+ return ret; - } - - ret = snprintf(gidstr, 11, "%ld", (long)gid); -@@ -953,9 +1004,9 @@ errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid) - char *gidstr; - errno_t ret; - -- if (mcc == NULL) { -- /* cache not initialized? */ -- return EINVAL; -+ ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ if (ret != EOK) { -+ return ret; - } - - gidstr = talloc_asprintf(NULL, "%ld", (long)gid); -@@ -1018,9 +1069,9 @@ errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc, - size_t pos; - int ret; - -- if (mcc == NULL) { -- /* cache not initialized? */ -- return EINVAL; -+ ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ if (ret != EOK) { -+ return ret; - } - - /* array of gids + name + unique_name */ -@@ -1087,8 +1138,9 @@ errno_t sss_mmap_cache_sid_store(struct sss_mc_ctx **_mcc, - size_t rec_len; - int ret; - -- if (mcc == NULL) { -- return EINVAL; -+ ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ if (ret != EOK) { -+ return ret; - } - - ret = snprintf(idkey, sizeof(idkey), "%d-%ld", -diff --git a/src/sss_client/nss_mc_common.c b/src/sss_client/nss_mc_common.c -index 3128861bf..e227c0bae 100644 ---- a/src/sss_client/nss_mc_common.c -+++ b/src/sss_client/nss_mc_common.c -@@ -69,13 +69,43 @@ static void sss_mt_unlock(struct sss_cli_mc_ctx *ctx) - #endif - } - -+static errno_t sss_nss_mc_validate(struct sss_cli_mc_ctx *ctx) -+{ -+ struct stat fdstat; -+ -+ /* No mc ctx initialized?*/ -+ if (ctx == NULL || ctx->fd < 0) { -+ return EINVAL; -+ } -+ -+ if (fstat(ctx->fd, &fdstat) == -1) { -+ return errno; -+ } -+ -+ /* Memcache was removed. */ -+ if (fdstat.st_nlink == 0) { -+ return ENOENT; -+ } -+ -+ /* Invalid size. */ -+ if (fdstat.st_size != ctx->mmap_size) { -+ return ERANGE; -+ } -+ -+ return EOK; -+} -+ - errno_t sss_nss_check_header(struct sss_cli_mc_ctx *ctx) - { - struct sss_mc_header h; - bool copy_ok; - int count; - int ret; -- struct stat fdstat; -+ -+ ret = sss_nss_mc_validate(ctx); -+ if (ret != EOK) { -+ return ret; -+ } - - /* retry barrier protected reading max 5 times then give up */ - for (count = 5; count > 0; count--) { -@@ -115,16 +145,6 @@ errno_t sss_nss_check_header(struct sss_cli_mc_ctx *ctx) - } - } - -- ret = fstat(ctx->fd, &fdstat); -- if (ret == -1) { -- return EIO; -- } -- -- if (fdstat.st_nlink == 0) { -- /* memory cache was removed; we need to reinitialize it. */ -- return EINVAL; -- } -- - return 0; - } - --- -2.41.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 new file mode 100644 index 0000000..a7ff19e --- /dev/null +++ b/SOURCES/0003-sdap-add-naming_context-as-new-member-of-struct-sdap.patch @@ -0,0 +1,194 @@ +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-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 new file mode 100644 index 0000000..7ba9ba5 --- /dev/null +++ b/SOURCES/0004-pam-fix-SC-auth-with-multiple-certs-and-missing-logi.patch @@ -0,0 +1,233 @@ +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/0004-sss_iface-do-not-add-cli_id-to-chain-key.patch b/SOURCES/0004-sss_iface-do-not-add-cli_id-to-chain-key.patch deleted file mode 100644 index b87470a..0000000 --- a/SOURCES/0004-sss_iface-do-not-add-cli_id-to-chain-key.patch +++ /dev/null @@ -1,404 +0,0 @@ -From adbd7c6e6b872d24784e3073bbdc44418af9ea45 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Mon, 4 Sep 2023 14:12:58 +0200 -Subject: [PATCH] sss_iface: do not add cli_id to chain key - -Otherwise we only chain identical requests from the same client -which effectively renders chaining not functional. - -Resolves: https://github.com/SSSD/sssd/issues/6911 - -Reviewed-by: Alexey Tikhonov -Reviewed-by: Justin Stephenson -(cherry picked from commit 1e5dfc187c7659cca567d2f7d5592e72794ef13c) ---- - src/sss_iface/sbus_sss_client_async.c | 12 +++---- - src/sss_iface/sbus_sss_interface.h | 24 ++++++------- - src/sss_iface/sbus_sss_keygens.c | 50 +++++++++++++-------------- - src/sss_iface/sbus_sss_keygens.h | 10 +++--- - src/sss_iface/sss_iface.xml | 12 +++---- - 5 files changed, 54 insertions(+), 54 deletions(-) - -diff --git a/src/sss_iface/sbus_sss_client_async.c b/src/sss_iface/sbus_sss_client_async.c -index 042d1b7b3..5ca925283 100644 ---- a/src/sss_iface/sbus_sss_client_async.c -+++ b/src/sss_iface/sbus_sss_client_async.c -@@ -1861,7 +1861,7 @@ sbus_call_dp_autofs_Enumerate_send - const char * arg_mapname, - uint32_t arg_cli_id) - { -- return sbus_method_in_usu_out__send(mem_ctx, conn, _sbus_sss_key_usu_0_1_2, -+ return sbus_method_in_usu_out__send(mem_ctx, conn, _sbus_sss_key_usu_0_1, - busname, object_path, "sssd.DataProvider.Autofs", "Enumerate", arg_dp_flags, arg_mapname, arg_cli_id); - } - -@@ -1883,7 +1883,7 @@ sbus_call_dp_autofs_GetEntry_send - const char * arg_entryname, - uint32_t arg_cli_id) - { -- return sbus_method_in_ussu_out__send(mem_ctx, conn, _sbus_sss_key_ussu_0_1_2_3, -+ return sbus_method_in_ussu_out__send(mem_ctx, conn, _sbus_sss_key_ussu_0_1_2, - busname, object_path, "sssd.DataProvider.Autofs", "GetEntry", arg_dp_flags, arg_mapname, arg_entryname, arg_cli_id); - } - -@@ -1904,7 +1904,7 @@ sbus_call_dp_autofs_GetMap_send - const char * arg_mapname, - uint32_t arg_cli_id) - { -- return sbus_method_in_usu_out__send(mem_ctx, conn, _sbus_sss_key_usu_0_1_2, -+ return sbus_method_in_usu_out__send(mem_ctx, conn, _sbus_sss_key_usu_0_1, - busname, object_path, "sssd.DataProvider.Autofs", "GetMap", arg_dp_flags, arg_mapname, arg_cli_id); - } - -@@ -2142,7 +2142,7 @@ sbus_call_dp_dp_getAccountDomain_send - const char * arg_filter, - uint32_t arg_cli_id) - { -- return sbus_method_in_uusu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uusu_0_1_2_3, -+ return sbus_method_in_uusu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uusu_0_1_2, - busname, object_path, "sssd.dataprovider", "getAccountDomain", arg_dp_flags, arg_entry_type, arg_filter, arg_cli_id); - } - -@@ -2170,7 +2170,7 @@ sbus_call_dp_dp_getAccountInfo_send - const char * arg_extra, - uint32_t arg_cli_id) - { -- return sbus_method_in_uusssu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uusssu_0_1_2_3_4_5, -+ return sbus_method_in_uusssu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uusssu_0_1_2_3_4, - busname, object_path, "sssd.dataprovider", "getAccountInfo", arg_dp_flags, arg_entry_type, arg_filter, arg_domain, arg_extra, arg_cli_id); - } - -@@ -2267,7 +2267,7 @@ sbus_call_dp_dp_resolverHandler_send - const char * arg_filter_value, - uint32_t arg_cli_id) - { -- return sbus_method_in_uuusu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uuusu_0_1_2_3_4, -+ return sbus_method_in_uuusu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uuusu_0_1_2_3, - busname, object_path, "sssd.dataprovider", "resolverHandler", arg_dp_flags, arg_entry_type, arg_filter_type, arg_filter_value, arg_cli_id); - } - -diff --git a/src/sss_iface/sbus_sss_interface.h b/src/sss_iface/sbus_sss_interface.h -index fc86c71d9..5b4d1c362 100644 ---- a/src/sss_iface/sbus_sss_interface.h -+++ b/src/sss_iface/sbus_sss_interface.h -@@ -166,7 +166,7 @@ - &_sbus_sss_args_sssd_DataProvider_Autofs_Enumerate, \ - NULL, \ - _sbus_sss_invoke_in_usu_out__send, \ -- _sbus_sss_key_usu_0_1_2, \ -+ _sbus_sss_key_usu_0_1, \ - (handler), (data)); \ - }) - -@@ -177,7 +177,7 @@ - &_sbus_sss_args_sssd_DataProvider_Autofs_Enumerate, \ - NULL, \ - _sbus_sss_invoke_in_usu_out__send, \ -- _sbus_sss_key_usu_0_1_2, \ -+ _sbus_sss_key_usu_0_1, \ - (handler_send), (handler_recv), (data)); \ - }) - -@@ -188,7 +188,7 @@ - &_sbus_sss_args_sssd_DataProvider_Autofs_GetEntry, \ - NULL, \ - _sbus_sss_invoke_in_ussu_out__send, \ -- _sbus_sss_key_ussu_0_1_2_3, \ -+ _sbus_sss_key_ussu_0_1_2, \ - (handler), (data)); \ - }) - -@@ -199,7 +199,7 @@ - &_sbus_sss_args_sssd_DataProvider_Autofs_GetEntry, \ - NULL, \ - _sbus_sss_invoke_in_ussu_out__send, \ -- _sbus_sss_key_ussu_0_1_2_3, \ -+ _sbus_sss_key_ussu_0_1_2, \ - (handler_send), (handler_recv), (data)); \ - }) - -@@ -210,7 +210,7 @@ - &_sbus_sss_args_sssd_DataProvider_Autofs_GetMap, \ - NULL, \ - _sbus_sss_invoke_in_usu_out__send, \ -- _sbus_sss_key_usu_0_1_2, \ -+ _sbus_sss_key_usu_0_1, \ - (handler), (data)); \ - }) - -@@ -221,7 +221,7 @@ - &_sbus_sss_args_sssd_DataProvider_Autofs_GetMap, \ - NULL, \ - _sbus_sss_invoke_in_usu_out__send, \ -- _sbus_sss_key_usu_0_1_2, \ -+ _sbus_sss_key_usu_0_1, \ - (handler_send), (handler_recv), (data)); \ - }) - -@@ -522,7 +522,7 @@ - &_sbus_sss_args_sssd_dataprovider_getAccountDomain, \ - NULL, \ - _sbus_sss_invoke_in_uusu_out_qus_send, \ -- _sbus_sss_key_uusu_0_1_2_3, \ -+ _sbus_sss_key_uusu_0_1_2, \ - (handler), (data)); \ - }) - -@@ -533,7 +533,7 @@ - &_sbus_sss_args_sssd_dataprovider_getAccountDomain, \ - NULL, \ - _sbus_sss_invoke_in_uusu_out_qus_send, \ -- _sbus_sss_key_uusu_0_1_2_3, \ -+ _sbus_sss_key_uusu_0_1_2, \ - (handler_send), (handler_recv), (data)); \ - }) - -@@ -544,7 +544,7 @@ - &_sbus_sss_args_sssd_dataprovider_getAccountInfo, \ - NULL, \ - _sbus_sss_invoke_in_uusssu_out_qus_send, \ -- _sbus_sss_key_uusssu_0_1_2_3_4_5, \ -+ _sbus_sss_key_uusssu_0_1_2_3_4, \ - (handler), (data)); \ - }) - -@@ -555,7 +555,7 @@ - &_sbus_sss_args_sssd_dataprovider_getAccountInfo, \ - NULL, \ - _sbus_sss_invoke_in_uusssu_out_qus_send, \ -- _sbus_sss_key_uusssu_0_1_2_3_4_5, \ -+ _sbus_sss_key_uusssu_0_1_2_3_4, \ - (handler_send), (handler_recv), (data)); \ - }) - -@@ -632,7 +632,7 @@ - &_sbus_sss_args_sssd_dataprovider_resolverHandler, \ - NULL, \ - _sbus_sss_invoke_in_uuusu_out_qus_send, \ -- _sbus_sss_key_uuusu_0_1_2_3_4, \ -+ _sbus_sss_key_uuusu_0_1_2_3, \ - (handler), (data)); \ - }) - -@@ -643,7 +643,7 @@ - &_sbus_sss_args_sssd_dataprovider_resolverHandler, \ - NULL, \ - _sbus_sss_invoke_in_uuusu_out_qus_send, \ -- _sbus_sss_key_uuusu_0_1_2_3_4, \ -+ _sbus_sss_key_uuusu_0_1_2_3, \ - (handler_send), (handler_recv), (data)); \ - }) - -diff --git a/src/sss_iface/sbus_sss_keygens.c b/src/sss_iface/sbus_sss_keygens.c -index 1bffc1360..0bded60f8 100644 ---- a/src/sss_iface/sbus_sss_keygens.c -+++ b/src/sss_iface/sbus_sss_keygens.c -@@ -90,86 +90,86 @@ _sbus_sss_key_ussu_0_1 - } - - const char * --_sbus_sss_key_ussu_0_1_2_3 -+_sbus_sss_key_ussu_0_1_2 - (TALLOC_CTX *mem_ctx, - struct sbus_request *sbus_req, - struct _sbus_sss_invoker_args_ussu *args) - { - if (sbus_req->sender == NULL) { -- return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%s:%s:%" PRIu32 "", -+ return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%s:%s", - sbus_req->type, sbus_req->interface, sbus_req->member, -- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3); -+ sbus_req->path, args->arg0, args->arg1, args->arg2); - } - -- return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%s:%s:%" PRIu32 "", -+ return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%s:%s", - sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member, -- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3); -+ sbus_req->path, args->arg0, args->arg1, args->arg2); - } - - const char * --_sbus_sss_key_usu_0_1_2 -+_sbus_sss_key_usu_0_1 - (TALLOC_CTX *mem_ctx, - struct sbus_request *sbus_req, - struct _sbus_sss_invoker_args_usu *args) - { - if (sbus_req->sender == NULL) { -- return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%s:%" PRIu32 "", -+ return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%s", - sbus_req->type, sbus_req->interface, sbus_req->member, -- sbus_req->path, args->arg0, args->arg1, args->arg2); -+ sbus_req->path, args->arg0, args->arg1); - } - -- return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%s:%" PRIu32 "", -+ return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%s", - sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member, -- sbus_req->path, args->arg0, args->arg1, args->arg2); -+ sbus_req->path, args->arg0, args->arg1); - } - - const char * --_sbus_sss_key_uusssu_0_1_2_3_4_5 -+_sbus_sss_key_uusssu_0_1_2_3_4 - (TALLOC_CTX *mem_ctx, - struct sbus_request *sbus_req, - struct _sbus_sss_invoker_args_uusssu *args) - { - if (sbus_req->sender == NULL) { -- return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%s:%s:%" PRIu32 "", -+ return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%s:%s", - sbus_req->type, sbus_req->interface, sbus_req->member, -- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4, args->arg5); -+ sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4); - } - -- return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%s:%s:%" PRIu32 "", -+ return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%s:%s", - sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member, -- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4, args->arg5); -+ sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4); - } - - const char * --_sbus_sss_key_uusu_0_1_2_3 -+_sbus_sss_key_uusu_0_1_2 - (TALLOC_CTX *mem_ctx, - struct sbus_request *sbus_req, - struct _sbus_sss_invoker_args_uusu *args) - { - if (sbus_req->sender == NULL) { -- return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%" PRIu32 "", -+ return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s", - sbus_req->type, sbus_req->interface, sbus_req->member, -- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3); -+ sbus_req->path, args->arg0, args->arg1, args->arg2); - } - -- return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%" PRIu32 "", -+ return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s", - sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member, -- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3); -+ sbus_req->path, args->arg0, args->arg1, args->arg2); - } - - const char * --_sbus_sss_key_uuusu_0_1_2_3_4 -+_sbus_sss_key_uuusu_0_1_2_3 - (TALLOC_CTX *mem_ctx, - struct sbus_request *sbus_req, - struct _sbus_sss_invoker_args_uuusu *args) - { - if (sbus_req->sender == NULL) { -- return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%s:%" PRIu32 "", -+ return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%s", - sbus_req->type, sbus_req->interface, sbus_req->member, -- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4); -+ sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3); - } - -- return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%s:%" PRIu32 "", -+ return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%s", - sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member, -- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4); -+ sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3); - } -diff --git a/src/sss_iface/sbus_sss_keygens.h b/src/sss_iface/sbus_sss_keygens.h -index 8f09b46de..7e42c2c53 100644 ---- a/src/sss_iface/sbus_sss_keygens.h -+++ b/src/sss_iface/sbus_sss_keygens.h -@@ -49,31 +49,31 @@ _sbus_sss_key_ussu_0_1 - struct _sbus_sss_invoker_args_ussu *args); - - const char * --_sbus_sss_key_ussu_0_1_2_3 -+_sbus_sss_key_ussu_0_1_2 - (TALLOC_CTX *mem_ctx, - struct sbus_request *sbus_req, - struct _sbus_sss_invoker_args_ussu *args); - - const char * --_sbus_sss_key_usu_0_1_2 -+_sbus_sss_key_usu_0_1 - (TALLOC_CTX *mem_ctx, - struct sbus_request *sbus_req, - struct _sbus_sss_invoker_args_usu *args); - - const char * --_sbus_sss_key_uusssu_0_1_2_3_4_5 -+_sbus_sss_key_uusssu_0_1_2_3_4 - (TALLOC_CTX *mem_ctx, - struct sbus_request *sbus_req, - struct _sbus_sss_invoker_args_uusssu *args); - - const char * --_sbus_sss_key_uusu_0_1_2_3 -+_sbus_sss_key_uusu_0_1_2 - (TALLOC_CTX *mem_ctx, - struct sbus_request *sbus_req, - struct _sbus_sss_invoker_args_uusu *args); - - const char * --_sbus_sss_key_uuusu_0_1_2_3_4 -+_sbus_sss_key_uuusu_0_1_2_3 - (TALLOC_CTX *mem_ctx, - struct sbus_request *sbus_req, - struct _sbus_sss_invoker_args_uuusu *args); -diff --git a/src/sss_iface/sss_iface.xml b/src/sss_iface/sss_iface.xml -index 6709c4e48..82c65aa0b 100644 ---- a/src/sss_iface/sss_iface.xml -+++ b/src/sss_iface/sss_iface.xml -@@ -91,18 +91,18 @@ - - - -- -+ - - - - - -- -+ - - - - -- -+ - - - -@@ -133,7 +133,7 @@ - - - -- -+ - - - -@@ -150,7 +150,7 @@ - - - -- -+ - - - -@@ -159,7 +159,7 @@ - - - -- -+ - - - --- -2.41.0 - diff --git a/SOURCES/0005-BUILD-Accept-krb5-1.21-for-building-the-PAC-plugin.patch b/SOURCES/0005-BUILD-Accept-krb5-1.21-for-building-the-PAC-plugin.patch deleted file mode 100644 index b4bdeb3..0000000 --- a/SOURCES/0005-BUILD-Accept-krb5-1.21-for-building-the-PAC-plugin.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 2e6d43635dd79e55a24d66a003a2e869d1964db4 Mon Sep 17 00:00:00 2001 -From: Alexey Tikhonov -Date: Thu, 15 Jun 2023 12:05:03 +0200 -Subject: [PATCH] BUILD: Accept krb5 1.21 for building the PAC plugin -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Reviewed-by: Alejandro López -Reviewed-by: Sumit Bose -(cherry picked from commit 74d0f4538deb766592079b1abca0d949d6dea105) - -Reviewed-by: Sumit Bose ---- - src/external/pac_responder.m4 | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/external/pac_responder.m4 b/src/external/pac_responder.m4 -index 3cbe3c9cf..90727185b 100644 ---- a/src/external/pac_responder.m4 -+++ b/src/external/pac_responder.m4 -@@ -22,7 +22,8 @@ then - Kerberos\ 5\ release\ 1.17* | \ - Kerberos\ 5\ release\ 1.18* | \ - Kerberos\ 5\ release\ 1.19* | \ -- Kerberos\ 5\ release\ 1.20*) -+ Kerberos\ 5\ release\ 1.20* | \ -+ Kerberos\ 5\ release\ 1.21*) - krb5_version_ok=yes - AC_MSG_RESULT([yes]) - ;; --- -2.41.0 - diff --git a/SOURCES/0005-sss-client-handle-key-value-in-destructor.patch b/SOURCES/0005-sss-client-handle-key-value-in-destructor.patch new file mode 100644 index 0000000..227157b --- /dev/null +++ b/SOURCES/0005-sss-client-handle-key-value-in-destructor.patch @@ -0,0 +1,50 @@ +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-MC-a-couple-of-additions-to-recover-from-invalid-mem.patch b/SOURCES/0006-MC-a-couple-of-additions-to-recover-from-invalid-mem.patch deleted file mode 100644 index bf02868..0000000 --- a/SOURCES/0006-MC-a-couple-of-additions-to-recover-from-invalid-mem.patch +++ /dev/null @@ -1,336 +0,0 @@ -From da2d480ff66a912a528fb4b9b4a0c64a3b0e5cce Mon Sep 17 00:00:00 2001 -From: Alexey Tikhonov -Date: Mon, 25 Sep 2023 12:36:09 +0200 -Subject: [PATCH] MC: a couple of additions to 'recover from invalid memory - cache size' patch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Additions to 641e5f73d3bd5b3d32cafd551013d3bfd2a52732 : - - - handle all invalidations consistently - - supply a valid pointer to `sss_mmap_cache_validate_or_reinit()`, - not a pointer to a local var - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit 88d8afbb115f18007dcc11f7ebac1b238c3ebd98) ---- - src/responder/nss/nss_get_object.c | 10 ++--- - src/responder/nss/nss_iface.c | 8 ++-- - src/responder/nss/nsssrv_mmap_cache.c | 64 ++++++++++++++++++--------- - src/responder/nss/nsssrv_mmap_cache.h | 10 ++--- - 4 files changed, 56 insertions(+), 36 deletions(-) - -diff --git a/src/responder/nss/nss_get_object.c b/src/responder/nss/nss_get_object.c -index 5d62dd098..29f9cb59b 100644 ---- a/src/responder/nss/nss_get_object.c -+++ b/src/responder/nss/nss_get_object.c -@@ -34,13 +34,13 @@ memcache_delete_entry_by_name(struct sss_nss_ctx *nss_ctx, - - switch (type) { - case SSS_MC_PASSWD: -- ret = sss_mmap_cache_pw_invalidate(nss_ctx->pwd_mc_ctx, name); -+ ret = sss_mmap_cache_pw_invalidate(&nss_ctx->pwd_mc_ctx, name); - break; - case SSS_MC_GROUP: -- ret = sss_mmap_cache_gr_invalidate(nss_ctx->grp_mc_ctx, name); -+ ret = sss_mmap_cache_gr_invalidate(&nss_ctx->grp_mc_ctx, name); - break; - case SSS_MC_INITGROUPS: -- ret = sss_mmap_cache_initgr_invalidate(nss_ctx->initgr_mc_ctx, name); -+ ret = sss_mmap_cache_initgr_invalidate(&nss_ctx->initgr_mc_ctx, name); - break; - default: - return EINVAL; -@@ -66,10 +66,10 @@ memcache_delete_entry_by_id(struct sss_nss_ctx *nss_ctx, - - switch (type) { - case SSS_MC_PASSWD: -- ret = sss_mmap_cache_pw_invalidate_uid(nss_ctx->pwd_mc_ctx, (uid_t)id); -+ ret = sss_mmap_cache_pw_invalidate_uid(&nss_ctx->pwd_mc_ctx, (uid_t)id); - break; - case SSS_MC_GROUP: -- ret = sss_mmap_cache_gr_invalidate_gid(nss_ctx->grp_mc_ctx, (gid_t)id); -+ ret = sss_mmap_cache_gr_invalidate_gid(&nss_ctx->grp_mc_ctx, (gid_t)id); - break; - default: - return EINVAL; -diff --git a/src/responder/nss/nss_iface.c b/src/responder/nss/nss_iface.c -index 07e91aa81..db743f8b7 100644 ---- a/src/responder/nss/nss_iface.c -+++ b/src/responder/nss/nss_iface.c -@@ -78,7 +78,7 @@ sss_nss_update_initgr_memcache(struct sss_nss_ctx *nctx, - - if (ret == ENOENT || res->count == 0) { - /* The user is gone. Invalidate the mc record */ -- ret = sss_mmap_cache_pw_invalidate(nctx->pwd_mc_ctx, delete_name); -+ ret = sss_mmap_cache_pw_invalidate(&nctx->pwd_mc_ctx, delete_name); - if (ret != EOK && ret != ENOENT) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Internal failure in memory cache code: %d [%s]\n", -@@ -125,7 +125,7 @@ sss_nss_update_initgr_memcache(struct sss_nss_ctx *nctx, - for (i = 0; i < gnum; i++) { - id = groups[i]; - -- ret = sss_mmap_cache_gr_invalidate_gid(nctx->grp_mc_ctx, id); -+ ret = sss_mmap_cache_gr_invalidate_gid(&nctx->grp_mc_ctx, id); - if (ret != EOK && ret != ENOENT) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Internal failure in memory cache code: %d [%s]\n", -@@ -134,7 +134,7 @@ sss_nss_update_initgr_memcache(struct sss_nss_ctx *nctx, - } - - to_sized_string(delete_name, fq_name); -- ret = sss_mmap_cache_initgr_invalidate(nctx->initgr_mc_ctx, -+ ret = sss_mmap_cache_initgr_invalidate(&nctx->initgr_mc_ctx, - delete_name); - if (ret != EOK && ret != ENOENT) { - DEBUG(SSSDBG_CRIT_FAILURE, -@@ -208,7 +208,7 @@ sss_nss_memorycache_invalidate_group_by_id(TALLOC_CTX *mem_ctx, - DEBUG(SSSDBG_TRACE_LIBS, - "Invalidating group %u from memory cache\n", gid); - -- sss_mmap_cache_gr_invalidate_gid(nctx->grp_mc_ctx, gid); -+ sss_mmap_cache_gr_invalidate_gid(&nctx->grp_mc_ctx, gid); - - return EOK; - } -diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c -index bd814f3bc..cacdc7cc5 100644 ---- a/src/responder/nss/nsssrv_mmap_cache.c -+++ b/src/responder/nss/nsssrv_mmap_cache.c -@@ -701,16 +701,22 @@ static inline void sss_mmap_chain_in_rec(struct sss_mc_ctx *mcc, - * generic invalidation - ***************************************************************************/ - --static errno_t sss_mmap_cache_invalidate(struct sss_mc_ctx *mcc, -+static errno_t sss_mmap_cache_validate_or_reinit(struct sss_mc_ctx **_mcc); -+ -+static errno_t sss_mmap_cache_invalidate(struct sss_mc_ctx **_mcc, - const struct sized_string *key) - { -+ struct sss_mc_ctx *mcc; - struct sss_mc_rec *rec; -+ int ret; - -- if (mcc == NULL) { -- /* cache not initialized? */ -- return EINVAL; -+ ret = sss_mmap_cache_validate_or_reinit(_mcc); -+ if (ret != EOK) { -+ return ret; - } - -+ mcc = *_mcc; -+ - rec = sss_mc_find_record(mcc, key); - if (rec == NULL) { - /* nothing to invalidate */ -@@ -785,7 +791,7 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc, - const struct sized_string *homedir, - const struct sized_string *shell) - { -- struct sss_mc_ctx *mcc = *_mcc; -+ struct sss_mc_ctx *mcc; - struct sss_mc_rec *rec; - struct sss_mc_pwd_data *data; - struct sized_string uidkey; -@@ -795,11 +801,13 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc, - size_t pos; - int ret; - -- ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ ret = sss_mmap_cache_validate_or_reinit(_mcc); - if (ret != EOK) { - return ret; - } - -+ mcc = *_mcc; -+ - ret = snprintf(uidstr, 11, "%ld", (long)uid); - if (ret > 10) { - return EINVAL; -@@ -851,14 +859,15 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc, - return EOK; - } - --errno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx *mcc, -+errno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx **_mcc, - const struct sized_string *name) - { -- return sss_mmap_cache_invalidate(mcc, name); -+ return sss_mmap_cache_invalidate(_mcc, name); - } - --errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid) -+errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx **_mcc, uid_t uid) - { -+ struct sss_mc_ctx *mcc; - struct sss_mc_rec *rec = NULL; - struct sss_mc_pwd_data *data; - uint32_t hash; -@@ -866,11 +875,13 @@ errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid) - char *uidstr; - errno_t ret; - -- ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ ret = sss_mmap_cache_validate_or_reinit(_mcc); - if (ret != EOK) { - return ret; - } - -+ mcc = *_mcc; -+ - uidstr = talloc_asprintf(NULL, "%ld", (long)uid); - if (!uidstr) { - return ENOMEM; -@@ -927,7 +938,7 @@ int sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc, - gid_t gid, size_t memnum, - const char *membuf, size_t memsize) - { -- struct sss_mc_ctx *mcc = *_mcc; -+ struct sss_mc_ctx *mcc; - struct sss_mc_rec *rec; - struct sss_mc_grp_data *data; - struct sized_string gidkey; -@@ -937,11 +948,13 @@ int sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc, - size_t pos; - int ret; - -- ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ ret = sss_mmap_cache_validate_or_reinit(_mcc); - if (ret != EOK) { - return ret; - } - -+ mcc = *_mcc; -+ - ret = snprintf(gidstr, 11, "%ld", (long)gid); - if (ret > 10) { - return EINVAL; -@@ -989,14 +1002,15 @@ int sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc, - return EOK; - } - --errno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx *mcc, -+errno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx **_mcc, - const struct sized_string *name) - { -- return sss_mmap_cache_invalidate(mcc, name); -+ return sss_mmap_cache_invalidate(_mcc, name); - } - --errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid) -+errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx **_mcc, gid_t gid) - { -+ struct sss_mc_ctx *mcc; - struct sss_mc_rec *rec = NULL; - struct sss_mc_grp_data *data; - uint32_t hash; -@@ -1004,11 +1018,13 @@ errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid) - char *gidstr; - errno_t ret; - -- ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ ret = sss_mmap_cache_validate_or_reinit(_mcc); - if (ret != EOK) { - return ret; - } - -+ mcc = *_mcc; -+ - gidstr = talloc_asprintf(NULL, "%ld", (long)gid); - if (!gidstr) { - return ENOMEM; -@@ -1061,7 +1077,7 @@ errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc, - uint32_t num_groups, - const uint8_t *gids_buf) - { -- struct sss_mc_ctx *mcc = *_mcc; -+ struct sss_mc_ctx *mcc; - struct sss_mc_rec *rec; - struct sss_mc_initgr_data *data; - size_t data_len; -@@ -1069,11 +1085,13 @@ errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc, - size_t pos; - int ret; - -- ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ ret = sss_mmap_cache_validate_or_reinit(_mcc); - if (ret != EOK) { - return ret; - } - -+ mcc = *_mcc; -+ - /* array of gids + name + unique_name */ - data_len = num_groups * sizeof(uint32_t) + name->len + unique_name->len; - rec_len = sizeof(struct sss_mc_rec) + sizeof(struct sss_mc_initgr_data) -@@ -1119,10 +1137,10 @@ errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc, - return EOK; - } - --errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx *mcc, -+errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx **_mcc, - const struct sized_string *name) - { -- return sss_mmap_cache_invalidate(mcc, name); -+ return sss_mmap_cache_invalidate(_mcc, name); - } - - errno_t sss_mmap_cache_sid_store(struct sss_mc_ctx **_mcc, -@@ -1131,18 +1149,20 @@ errno_t sss_mmap_cache_sid_store(struct sss_mc_ctx **_mcc, - uint32_t type, - bool explicit_lookup) - { -- struct sss_mc_ctx *mcc = *_mcc; -+ struct sss_mc_ctx *mcc; - struct sss_mc_rec *rec; - struct sss_mc_sid_data *data; - char idkey[16]; - size_t rec_len; - int ret; - -- ret = sss_mmap_cache_validate_or_reinit(&mcc); -+ ret = sss_mmap_cache_validate_or_reinit(_mcc); - if (ret != EOK) { - return ret; - } - -+ mcc = *_mcc; -+ - ret = snprintf(idkey, sizeof(idkey), "%d-%ld", - (type == SSS_ID_TYPE_GID) ? SSS_ID_TYPE_GID : SSS_ID_TYPE_UID, - (long)id); -diff --git a/src/responder/nss/nsssrv_mmap_cache.h b/src/responder/nss/nsssrv_mmap_cache.h -index 686b8e1b2..28ee5adb6 100644 ---- a/src/responder/nss/nsssrv_mmap_cache.h -+++ b/src/responder/nss/nsssrv_mmap_cache.h -@@ -63,17 +63,17 @@ errno_t sss_mmap_cache_sid_store(struct sss_mc_ctx **_mcc, - uint32_t type, /* enum sss_id_type*/ - bool explicit_lookup); /* false ~ by_id(), true ~ by_uid/gid() */ - --errno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx *mcc, -+errno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx **_mcc, - const struct sized_string *name); - --errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid); -+errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx **_mcc, uid_t uid); - --errno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx *mcc, -+errno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx **_mcc, - const struct sized_string *name); - --errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid); -+errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx **_mcc, gid_t gid); - --errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx *mcc, -+errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx **_mcc, - const struct sized_string *name); - - errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, --- -2.41.0 - diff --git a/SOURCES/0006-krb5-Allow-fallback-between-responder-questions.patch b/SOURCES/0006-krb5-Allow-fallback-between-responder-questions.patch new file mode 100644 index 0000000..f8dda3e --- /dev/null +++ b/SOURCES/0006-krb5-Allow-fallback-between-responder-questions.patch @@ -0,0 +1,104 @@ +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/0007-SSS_CLIENT-replace-__thread-with-pthread_-specific.patch b/SOURCES/0007-SSS_CLIENT-replace-__thread-with-pthread_-specific.patch deleted file mode 100644 index c29e496..0000000 --- a/SOURCES/0007-SSS_CLIENT-replace-__thread-with-pthread_-specific.patch +++ /dev/null @@ -1,388 +0,0 @@ -From ef5370e96bff79025cb9a0f9e62c4d3684f55512 Mon Sep 17 00:00:00 2001 -From: Alexey Tikhonov -Date: Mon, 23 Oct 2023 16:11:17 +0200 -Subject: [PATCH] SSS_CLIENT: replace `__thread` with `pthread_*specific()` - -in sss_client code to properly handle OOM condition (with `__thread` -glibc terminates process in this case). - -Solution relies on the fact that `sss_cli_check_socket()` is always -executed first, before touching socket. -Nonetheless, there are sanity guards in setters/getters just in case. - -It's possible to move context initialization code into a separate -function and call it in every getter/setter, but probably not worth it. - -Reviewed-by: Sumit Bose -Reviewed-by: Carlos O'Donell -(cherry picked from commit b0212b04f109875936612a52a7b30a80e5a85ee5) ---- - src/sss_client/common.c | 202 ++++++++++++++++++++++++++++++++-------- - 1 file changed, 164 insertions(+), 38 deletions(-) - -diff --git a/src/sss_client/common.c b/src/sss_client/common.c -index c80c8e74b..1075af941 100644 ---- a/src/sss_client/common.c -+++ b/src/sss_client/common.c -@@ -62,22 +62,31 @@ - - /* common functions */ - -+static int sss_cli_sd_get(void); -+static void sss_cli_sd_set(int sd); -+static const struct stat *sss_cli_sb_get(void); -+static int sss_cli_sb_set_by_sd(int sd); -+ - #ifdef HAVE_PTHREAD_EXT - static pthread_key_t sss_sd_key; - static pthread_once_t sss_sd_key_init = PTHREAD_ONCE_INIT; - static atomic_bool sss_sd_key_initialized = false; --static __thread int sss_cli_sd = -1; /* the sss client socket descriptor */ --static __thread struct stat sss_cli_sb; /* the sss client stat buffer */ -+struct sss_socket_descriptor_t { -+ int sd; -+ struct stat sb; -+}; - #else --static int sss_cli_sd = -1; /* the sss client socket descriptor */ --static struct stat sss_cli_sb; /* the sss client stat buffer */ -+static int _sss_cli_sd = -1; /* the sss client socket descriptor */ -+static struct stat _sss_cli_sb; /* the sss client stat buffer */ - #endif - - void sss_cli_close_socket(void) - { -- if (sss_cli_sd != -1) { -- close(sss_cli_sd); -- sss_cli_sd = -1; -+ int sd = sss_cli_sd_get(); -+ -+ if (sd != -1) { -+ close(sd); -+ sss_cli_sd_set(-1); - } - } - -@@ -85,25 +94,30 @@ void sss_cli_close_socket(void) - static void sss_at_thread_exit(void *v) - { - sss_cli_close_socket(); -+ free(v); -+ pthread_setspecific(sss_sd_key, NULL); - } - - static void init_sd_key(void) - { -- pthread_key_create(&sss_sd_key, sss_at_thread_exit); -- sss_sd_key_initialized = true; -+ if (pthread_key_create(&sss_sd_key, sss_at_thread_exit) == 0) { -+ sss_sd_key_initialized = true; -+ } - } - #endif - - #if HAVE_FUNCTION_ATTRIBUTE_DESTRUCTOR - __attribute__((destructor)) void sss_at_lib_unload(void) - { -+ sss_cli_close_socket(); - #ifdef HAVE_PTHREAD_EXT - if (sss_sd_key_initialized) { - sss_sd_key_initialized = false; -+ free(pthread_getspecific(sss_sd_key)); -+ pthread_setspecific(sss_sd_key, NULL); - pthread_key_delete(sss_sd_key); - } - #endif -- sss_cli_close_socket(); - } - #endif - -@@ -137,7 +151,7 @@ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd, - int res, error; - - *errnop = 0; -- pfd.fd = sss_cli_sd; -+ pfd.fd = sss_cli_sd_get(); - pfd.events = POLLOUT; - - do { -@@ -163,7 +177,7 @@ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd, - *errnop = EPIPE; - } else if (pfd.revents & POLLNVAL) { - /* Invalid request: fd is not opened */ -- sss_cli_sd = -1; -+ sss_cli_sd_set(-1); - *errnop = EPIPE; - } else if (!(pfd.revents & POLLOUT)) { - *errnop = EBUSY; -@@ -180,13 +194,13 @@ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd, - - errno = 0; - if (datasent < SSS_NSS_HEADER_SIZE) { -- res = send(sss_cli_sd, -+ res = send(sss_cli_sd_get(), - (char *)header + datasent, - SSS_NSS_HEADER_SIZE - datasent, - SSS_DEFAULT_WRITE_FLAGS); - } else { - rdsent = datasent - SSS_NSS_HEADER_SIZE; -- res = send(sss_cli_sd, -+ res = send(sss_cli_sd_get(), - (const char *)rd->data + rdsent, - rd->len - rdsent, - SSS_DEFAULT_WRITE_FLAGS); -@@ -249,7 +263,7 @@ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd, - int bufrecv; - int res, error; - -- pfd.fd = sss_cli_sd; -+ pfd.fd = sss_cli_sd_get(); - pfd.events = POLLIN; - - do { -@@ -278,7 +292,7 @@ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd, - *errnop = EPIPE; - } else if (pfd.revents & POLLNVAL) { - /* Invalid request: fd is not opened */ -- sss_cli_sd = -1; -+ sss_cli_sd_set(-1); - *errnop = EPIPE; - } else if (!(pfd.revents & POLLIN)) { - *errnop = EBUSY; -@@ -296,12 +310,12 @@ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd, - - errno = 0; - if (datarecv < SSS_NSS_HEADER_SIZE) { -- res = read(sss_cli_sd, -+ res = read(sss_cli_sd_get(), - (char *)header + datarecv, - SSS_NSS_HEADER_SIZE - datarecv); - } else { - bufrecv = datarecv - SSS_NSS_HEADER_SIZE; -- res = read(sss_cli_sd, -+ res = read(sss_cli_sd_get(), - (char *) buf + bufrecv, - header[0] - datarecv); - } -@@ -591,16 +605,6 @@ static int sss_cli_open_socket(int *errnop, const char *socket_name, int timeout - return -1; - } - --#ifdef HAVE_PTHREAD_EXT -- pthread_once(&sss_sd_key_init, init_sd_key); /* once for all threads */ -- -- /* It actually doesn't matter what value to set for a key. -- * The only important thing: key must be non-NULL to ensure -- * destructor is executed at thread exit. -- */ -- pthread_setspecific(sss_sd_key, &sss_cli_sd); --#endif -- - /* set as non-blocking, close on exec, and make sure standard - * descriptors are not used */ - sd = make_safe_fd(sd); -@@ -670,7 +674,7 @@ static int sss_cli_open_socket(int *errnop, const char *socket_name, int timeout - return -1; - } - -- ret = fstat(sd, &sss_cli_sb); -+ ret = sss_cli_sb_set_by_sd(sd); - if (ret != 0) { - close(sd); - return -1; -@@ -686,33 +690,69 @@ static enum sss_status sss_cli_check_socket(int *errnop, - static pid_t mypid_s; - static ino_t myself_ino; - struct stat mypid_sb, myself_sb; -+ const struct stat *sss_cli_sb = NULL; - pid_t mypid_d; - int mysd; - int ret; -+#ifdef HAVE_PTHREAD_EXT -+ struct sss_socket_descriptor_t *descriptor = NULL; -+ -+ ret = pthread_once(&sss_sd_key_init, init_sd_key); /* once for all threads */ -+ if (ret != 0) { -+ *errnop = EFAULT; -+ return SSS_STATUS_UNAVAIL; -+ } -+ if (!sss_sd_key_initialized) { -+ /* pthread_once::init_sd_key::pthread_key_create failed -- game over? */ -+ *errnop = EFAULT; -+ return SSS_STATUS_UNAVAIL; -+ } -+ -+ if (pthread_getspecific(sss_sd_key) == NULL) { /* for every thread */ -+ descriptor = (struct sss_socket_descriptor_t *) -+ calloc(1, sizeof(struct sss_socket_descriptor_t)); -+ if (descriptor == NULL) { -+ *errnop = ENOMEM; -+ return SSS_STATUS_UNAVAIL; -+ } -+ descriptor->sd = -1; -+ ret = pthread_setspecific(sss_sd_key, descriptor); -+ if (ret != 0) { -+ free(descriptor); -+ *errnop = ENOMEM; -+ return SSS_STATUS_UNAVAIL; -+ } -+ } -+#endif -+ sss_cli_sb = sss_cli_sb_get(); -+ if (sss_cli_sb == NULL) { -+ *errnop = EFAULT; -+ return SSS_STATUS_UNAVAIL; -+ } - - ret = lstat("/proc/self/", &myself_sb); - mypid_d = getpid(); - if (mypid_d != mypid_s || (ret == 0 && myself_sb.st_ino != myself_ino)) { -- ret = fstat(sss_cli_sd, &mypid_sb); -+ ret = fstat(sss_cli_sd_get(), &mypid_sb); - if (ret == 0) { - if (S_ISSOCK(mypid_sb.st_mode) && -- mypid_sb.st_dev == sss_cli_sb.st_dev && -- mypid_sb.st_ino == sss_cli_sb.st_ino) { -+ mypid_sb.st_dev == sss_cli_sb->st_dev && -+ mypid_sb.st_ino == sss_cli_sb->st_ino) { - sss_cli_close_socket(); - } - } -- sss_cli_sd = -1; -+ sss_cli_sd_set(-1); - mypid_s = mypid_d; - myself_ino = myself_sb.st_ino; - } - - /* check if the socket has been closed on the other side */ -- if (sss_cli_sd != -1) { -+ if (sss_cli_sd_get() != -1) { - struct pollfd pfd; - int res, error; - - *errnop = 0; -- pfd.fd = sss_cli_sd; -+ pfd.fd = sss_cli_sd_get(); - pfd.events = POLLIN | POLLOUT; - - do { -@@ -738,7 +778,7 @@ static enum sss_status sss_cli_check_socket(int *errnop, - *errnop = EPIPE; - } else if (pfd.revents & POLLNVAL) { - /* Invalid request: fd is not opened */ -- sss_cli_sd = -1; -+ sss_cli_sd_set(-1); - *errnop = EPIPE; - } else if (!(pfd.revents & (POLLIN | POLLOUT))) { - *errnop = EBUSY; -@@ -760,7 +800,7 @@ static enum sss_status sss_cli_check_socket(int *errnop, - return SSS_STATUS_UNAVAIL; - } - -- sss_cli_sd = mysd; -+ sss_cli_sd_set(mysd); - - if (sss_cli_check_version(socket_name, timeout)) { - return SSS_STATUS_SUCCESS; -@@ -1015,7 +1055,7 @@ int sss_pam_make_request(enum sss_cli_command cmd, - goto out; - } - -- error = check_server_cred(sss_cli_sd); -+ error = check_server_cred(sss_cli_sd_get()); - if (error != 0) { - sss_cli_close_socket(); - *errnop = error; -@@ -1307,3 +1347,89 @@ errno_t sss_readrep_copy_string(const char *in, - - return EOK; - } -+ -+#ifdef HAVE_PTHREAD_EXT -+ -+static int sss_cli_sd_get(void) -+{ -+ if (!sss_sd_key_initialized) { -+ return -1; -+ } -+ -+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key); -+ -+ if (descriptor == NULL) { /* sanity check */ -+ return -1; -+ } -+ -+ return descriptor->sd; -+} -+ -+static void sss_cli_sd_set(int sd) -+{ -+ if (!sss_sd_key_initialized) { -+ return; -+ } -+ -+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key); -+ -+ if (descriptor == NULL) { /* sanity check */ -+ return; -+ } -+ -+ descriptor->sd = sd; -+} -+ -+static const struct stat *sss_cli_sb_get(void) -+{ -+ if (!sss_sd_key_initialized) { -+ return NULL; -+ } -+ -+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key); -+ -+ if (descriptor == NULL) { /* sanity check */ -+ return NULL; -+ } -+ -+ return &descriptor->sb; -+} -+ -+static int sss_cli_sb_set_by_sd(int sd) -+{ -+ if (!sss_sd_key_initialized) { -+ return -1; -+ } -+ -+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key); -+ -+ if (descriptor == NULL) { /* sanity check */ -+ return -1; -+ } -+ -+ return fstat(sd, &descriptor->sb); -+} -+ -+#else -+ -+static int sss_cli_sd_get(void) -+{ -+ return _sss_cli_sd; -+} -+ -+static void sss_cli_sd_set(int sd) -+{ -+ _sss_cli_sd = sd; -+} -+ -+static const struct stat *sss_cli_sb_get(void) -+{ -+ return &_sss_cli_sb; -+} -+ -+static int sss_cli_sb_set_by_sd(int sd) -+{ -+ return fstat(sd, &_sss_cli_sb); -+} -+ -+#endif --- -2.41.0 - diff --git a/SOURCES/0007-krb5-Add-fallback-password-change-support.patch b/SOURCES/0007-krb5-Add-fallback-password-change-support.patch new file mode 100644 index 0000000..875d831 --- /dev/null +++ b/SOURCES/0007-krb5-Add-fallback-password-change-support.patch @@ -0,0 +1,206 @@ +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/0008-DP-reduce-log-level-in-case-a-responder-asks-for-unk.patch b/SOURCES/0008-DP-reduce-log-level-in-case-a-responder-asks-for-unk.patch deleted file mode 100644 index 40cc2bc..0000000 --- a/SOURCES/0008-DP-reduce-log-level-in-case-a-responder-asks-for-unk.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 6959dc6aadbe77edc3d0915ae006848309c20662 Mon Sep 17 00:00:00 2001 -From: Alexey Tikhonov -Date: Thu, 7 Dec 2023 09:47:25 +0100 -Subject: [PATCH] DP: reduce log level in case a responder asks for unknown - domain - -Since 9358a74d3a56c738890353aaf6bc956bfe72df99 a domain might be -skipped by 'ad_enabled_domains' option - -Reviewed-by: Sumit Bose -(cherry picked from commit 39cd0baa06742b349ed763aa40ea4de366e80f1a) ---- - src/providers/data_provider/dp_request.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/providers/data_provider/dp_request.c b/src/providers/data_provider/dp_request.c -index df2db2666..9c0fcf1f5 100644 ---- a/src/providers/data_provider/dp_request.c -+++ b/src/providers/data_provider/dp_request.c -@@ -204,7 +204,8 @@ dp_req_new(TALLOC_CTX *mem_ctx, - if (domainname != NULL) { - dp_req->domain = find_domain_by_name(be_ctx->domain, domainname, true); - if (dp_req->domain == NULL) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unknown domain: %s\n", domainname); -+ /* domain might be skipped by 'ad_enabled_domains' option */ -+ DEBUG(SSSDBG_CONF_SETTINGS, "Unknown domain: %s\n", domainname); - return ERR_DOMAIN_NOT_FOUND; - } - } --- -2.41.0 - diff --git a/SOURCES/0008-pam-fix-invalid-if-condition.patch b/SOURCES/0008-pam-fix-invalid-if-condition.patch new file mode 100644 index 0000000..53fccda --- /dev/null +++ b/SOURCES/0008-pam-fix-invalid-if-condition.patch @@ -0,0 +1,30 @@ +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/0009-SSS_CLIENT-MC-in-case-mem-cache-file-validation-fail.patch b/SOURCES/0009-SSS_CLIENT-MC-in-case-mem-cache-file-validation-fail.patch deleted file mode 100644 index e04ca5b..0000000 --- a/SOURCES/0009-SSS_CLIENT-MC-in-case-mem-cache-file-validation-fail.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 160738ee8e4eaf59cf81eae13fa65a4b53700c0d Mon Sep 17 00:00:00 2001 -From: Alexey Tikhonov -Date: Fri, 8 Dec 2023 19:02:24 +0100 -Subject: [PATCH 09/11] SSS_CLIENT: MC: in case mem-cache file validation - fails, -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -don't return anything but EINVAL, because `_nss_sss_*()` functions -can have a special handling for other error codes (for ERANGE in -particular). - -Reviewed-by: Alejandro López -Reviewed-by: Sumit Bose -Reviewed-by: Tomáš Halman -(cherry picked from commit 958a5e25c447dc502e8f8fbecf3253e62f92b0b2) ---- - src/sss_client/nss_mc_common.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/sss_client/nss_mc_common.c b/src/sss_client/nss_mc_common.c -index e227c0bae..37119fa8d 100644 ---- a/src/sss_client/nss_mc_common.c -+++ b/src/sss_client/nss_mc_common.c -@@ -79,17 +79,17 @@ static errno_t sss_nss_mc_validate(struct sss_cli_mc_ctx *ctx) - } - - if (fstat(ctx->fd, &fdstat) == -1) { -- return errno; -+ return EINVAL; - } - - /* Memcache was removed. */ - if (fdstat.st_nlink == 0) { -- return ENOENT; -+ return EINVAL; - } - - /* Invalid size. */ - if (fdstat.st_size != ctx->mmap_size) { -- return ERANGE; -+ return EINVAL; - } - - return EOK; --- -2.41.0 - diff --git a/SOURCES/0009-krb5-add-OTP-to-krb5-response-selection.patch b/SOURCES/0009-krb5-add-OTP-to-krb5-response-selection.patch new file mode 100644 index 0000000..87fbf45 --- /dev/null +++ b/SOURCES/0009-krb5-add-OTP-to-krb5-response-selection.patch @@ -0,0 +1,185 @@ +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/0010-SSS_CLIENT-check-if-mem-cache-fd-was-hijacked.patch b/SOURCES/0010-SSS_CLIENT-check-if-mem-cache-fd-was-hijacked.patch deleted file mode 100644 index 327575c..0000000 --- a/SOURCES/0010-SSS_CLIENT-check-if-mem-cache-fd-was-hijacked.patch +++ /dev/null @@ -1,86 +0,0 @@ -From a186224d6e1ce0c91507df58fec424209a307fe3 Mon Sep 17 00:00:00 2001 -From: Alexey Tikhonov -Date: Fri, 15 Dec 2023 14:52:51 +0100 -Subject: [PATCH 10/11] SSS_CLIENT: check if mem-cache fd was hijacked -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Real life example would be: -https://github.com/TigerVNC/tigervnc/blob/effd854bfd19654fa67ff3d39514a91a246b8ae6/unix/xserver/hw/vnc/xvnc.c#L369 - - TigerVNC unconditionally overwrites fd=3 - -Resolves: https://github.com/SSSD/sssd/issues/6986 - -Reviewed-by: Alejandro López -Reviewed-by: Sumit Bose -Reviewed-by: Tomáš Halman -(cherry picked from commit 0344c41aca0d6fcaa33e081ed77297607e48ced4) ---- - src/sss_client/nss_mc.h | 6 ++++-- - src/sss_client/nss_mc_common.c | 10 ++++++++++ - 2 files changed, 14 insertions(+), 2 deletions(-) - -diff --git a/src/sss_client/nss_mc.h b/src/sss_client/nss_mc.h -index 9ab2736fa..646861ba5 100644 ---- a/src/sss_client/nss_mc.h -+++ b/src/sss_client/nss_mc.h -@@ -53,6 +53,8 @@ struct sss_cli_mc_ctx { - pthread_mutex_t *mutex; - #endif - int fd; -+ ino_t fd_inode; -+ dev_t fd_device; - - uint32_t seed; /* seed from the tables header */ - -@@ -69,9 +71,9 @@ struct sss_cli_mc_ctx { - }; - - #if HAVE_PTHREAD --#define SSS_CLI_MC_CTX_INITIALIZER(mtx) {UNINITIALIZED, (mtx), -1, 0, NULL, 0, NULL, 0, NULL, 0, 0} -+#define SSS_CLI_MC_CTX_INITIALIZER(mtx) {UNINITIALIZED, (mtx), -1, 0, 0, 0, NULL, 0, NULL, 0, NULL, 0, 0} - #else --#define SSS_CLI_MC_CTX_INITIALIZER {UNINITIALIZED, -1, 0, NULL, 0, NULL, 0, NULL, 0, 0} -+#define SSS_CLI_MC_CTX_INITIALIZER {UNINITIALIZED, -1, 0, 0, 0, NULL, 0, NULL, 0, NULL, 0, 0} - #endif - - errno_t sss_nss_mc_get_ctx(const char *name, struct sss_cli_mc_ctx *ctx); -diff --git a/src/sss_client/nss_mc_common.c b/src/sss_client/nss_mc_common.c -index 37119fa8d..17683ac0e 100644 ---- a/src/sss_client/nss_mc_common.c -+++ b/src/sss_client/nss_mc_common.c -@@ -87,6 +87,12 @@ static errno_t sss_nss_mc_validate(struct sss_cli_mc_ctx *ctx) - return EINVAL; - } - -+ /* FD was hijacked */ -+ if ((fdstat.st_dev != ctx->fd_device) || (fdstat.st_ino != ctx->fd_inode)) { -+ ctx->fd = -1; /* don't ruin app even if it's misbehaving */ -+ return EINVAL; -+ } -+ - /* Invalid size. */ - if (fdstat.st_size != ctx->mmap_size) { - return EINVAL; -@@ -161,6 +167,8 @@ static void sss_nss_mc_destroy_ctx(struct sss_cli_mc_ctx *ctx) - close(ctx->fd); - } - ctx->fd = -1; -+ ctx->fd_inode = 0; -+ ctx->fd_device = 0; - - ctx->seed = 0; - ctx->data_table = NULL; -@@ -202,6 +210,8 @@ static errno_t sss_nss_mc_init_ctx(const char *name, - ret = EIO; - goto done; - } -+ ctx->fd_inode = fdstat.st_ino; -+ ctx->fd_device = fdstat.st_dev; - - if (fdstat.st_size < MC_HEADER_SIZE) { - ret = ENOMEM; --- -2.41.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 new file mode 100644 index 0000000..db83f42 --- /dev/null +++ b/SOURCES/0010-krb5-make-sure-answer_pkinit-use-matching-debug-mess.patch @@ -0,0 +1,119 @@ +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/0011-SSS_CLIENT-check-if-reponder-socket-was-hijacked.patch b/SOURCES/0011-SSS_CLIENT-check-if-reponder-socket-was-hijacked.patch deleted file mode 100644 index 6a078ab..0000000 --- a/SOURCES/0011-SSS_CLIENT-check-if-reponder-socket-was-hijacked.patch +++ /dev/null @@ -1,44 +0,0 @@ -From abb146e1487598c0e4fa2cdc826b7388db46f9bc Mon Sep 17 00:00:00 2001 -From: Alexey Tikhonov -Date: Wed, 20 Dec 2023 09:43:48 +0100 -Subject: [PATCH 11/11] SSS_CLIENT: check if reponder socket was hijacked -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Real life example would be: -https://github.com/TigerVNC/tigervnc/blob/effd854bfd19654fa67ff3d39514a91a246b8ae6/unix/xserver/hw/vnc/xvnc.c#L369 - - TigerVNC unconditionally overwrites fd=3 - -Reviewed-by: Alejandro López -Reviewed-by: Sumit Bose -Reviewed-by: Tomáš Halman -(cherry picked from commit 2bcfb7f9238c27025e99e6445e9ba799e0bde7b8) ---- - src/sss_client/common.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/src/sss_client/common.c b/src/sss_client/common.c -index 1075af941..702d0597d 100644 ---- a/src/sss_client/common.c -+++ b/src/sss_client/common.c -@@ -746,6 +746,16 @@ static enum sss_status sss_cli_check_socket(int *errnop, - myself_ino = myself_sb.st_ino; - } - -+ /* check if the socket has been hijacked */ -+ if (sss_cli_sd_get() != -1) { -+ ret = fstat(sss_cli_sd_get(), &mypid_sb); -+ if ((ret != 0) || (!S_ISSOCK(mypid_sb.st_mode)) -+ || (mypid_sb.st_dev != sss_cli_sb->st_dev) -+ || (mypid_sb.st_ino != sss_cli_sb->st_ino)) { -+ sss_cli_sd_set(-1); /* don't ruin app even if it's misbehaving */ -+ } -+ } -+ - /* check if the socket has been closed on the other side */ - if (sss_cli_sd_get() != -1) { - struct pollfd pfd; --- -2.41.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 new file mode 100644 index 0000000..5126106 --- /dev/null +++ b/SOURCES/0011-krb5-make-prompter-and-pre-auth-debug-message-less-i.patch @@ -0,0 +1,67 @@ +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-LDAP-make-groups_by_user_send-recv-public.patch b/SOURCES/0012-LDAP-make-groups_by_user_send-recv-public.patch deleted file mode 100644 index 4f35641..0000000 --- a/SOURCES/0012-LDAP-make-groups_by_user_send-recv-public.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 936b828161810bef53525d72291cf029ad3ce317 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 3 Nov 2023 18:43:13 +0100 -Subject: [PATCH 12/15] LDAP: make groups_by_user_send/recv public -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Resolves: https://github.com/SSSD/sssd/issues/5708 - -Reviewed-by: Justin Stephenson -Reviewed-by: Tomáš Halman -(cherry picked from commit 9b73614c49aeb3cfc3208dba5f472354086180b5) ---- - src/providers/ldap/ldap_common.h | 12 ++++++++++++ - src/providers/ldap/ldap_id.c | 18 +++++++++--------- - 2 files changed, 21 insertions(+), 9 deletions(-) - -diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h -index 1b35cbd20..6df7b3df4 100644 ---- a/src/providers/ldap/ldap_common.h -+++ b/src/providers/ldap/ldap_common.h -@@ -298,6 +298,18 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, - bool no_members); - int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret); - -+struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, -+ struct tevent_context *ev, -+ struct sdap_id_ctx *ctx, -+ struct sdap_domain *sdom, -+ struct sdap_id_conn_ctx *conn, -+ const char *filter_value, -+ int filter_type, -+ const char *extra_value, -+ bool noexist_delete); -+ -+int groups_by_user_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret); -+ - struct tevent_req *ldap_netgroup_get_send(TALLOC_CTX *memctx, - struct tevent_context *ev, - struct sdap_id_ctx *ctx, -diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c -index a60aed068..fb81a1793 100644 ---- a/src/providers/ldap/ldap_id.c -+++ b/src/providers/ldap/ldap_id.c -@@ -1151,15 +1151,15 @@ static int groups_by_user_retry(struct tevent_req *req); - static void groups_by_user_connect_done(struct tevent_req *subreq); - static void groups_by_user_done(struct tevent_req *subreq); - --static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, -- struct tevent_context *ev, -- struct sdap_id_ctx *ctx, -- struct sdap_domain *sdom, -- struct sdap_id_conn_ctx *conn, -- const char *filter_value, -- int filter_type, -- const char *extra_value, -- bool noexist_delete) -+struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, -+ struct tevent_context *ev, -+ struct sdap_id_ctx *ctx, -+ struct sdap_domain *sdom, -+ struct sdap_id_conn_ctx *conn, -+ const char *filter_value, -+ int filter_type, -+ const char *extra_value, -+ bool noexist_delete) - { - struct tevent_req *req; - struct groups_by_user_state *state; --- -2.41.0 - diff --git a/SOURCES/0012-pam_sss-prefer-Smartcard-authentication.patch b/SOURCES/0012-pam_sss-prefer-Smartcard-authentication.patch new file mode 100644 index 0000000..90e27c9 --- /dev/null +++ b/SOURCES/0012-pam_sss-prefer-Smartcard-authentication.patch @@ -0,0 +1,70 @@ +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-ad-gpo-evalute-host-groups.patch b/SOURCES/0013-ad-gpo-evalute-host-groups.patch deleted file mode 100644 index 649586f..0000000 --- a/SOURCES/0013-ad-gpo-evalute-host-groups.patch +++ /dev/null @@ -1,627 +0,0 @@ -From 09dcc73ed4d8db8f30df27bfc7df68bf0a48de11 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 6 Nov 2023 18:17:28 +0100 -Subject: [PATCH 13/15] ad: gpo evalute host groups -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With this patch the group-memberships of the client running SSSD are -included in the evaluation of the security filtering. Similar as in AD -the host object is more or less handled as a user object which allows -to skip some code dedicated to computers only. - -Resolves: https://github.com/SSSD/sssd/issues/5708 - -Reviewed-by: Justin Stephenson -Reviewed-by: Tomáš Halman -(cherry picked from commit c02e09afe9610d872121708893db8a21fb201b12) ---- - src/providers/ad/ad_gpo.c | 332 +++++++++++---------------------- - src/tests/cmocka/test_ad_gpo.c | 25 ++- - 2 files changed, 134 insertions(+), 223 deletions(-) - -diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c -index b119aa377..1c731b222 100644 ---- a/src/providers/ad/ad_gpo.c -+++ b/src/providers/ad/ad_gpo.c -@@ -661,6 +661,8 @@ ad_gpo_ace_includes_client_sid(const char *user_sid, - const char *host_sid, - const char **group_sids, - int group_size, -+ const char **host_group_sids, -+ int host_group_size, - struct dom_sid ace_dom_sid, - struct sss_idmap_ctx *idmap_ctx, - bool *_included) -@@ -718,6 +720,22 @@ ad_gpo_ace_includes_client_sid(const char *user_sid, - } - } - -+ for (i = 0; i < host_group_size; i++) { -+ err = sss_idmap_sid_to_smb_sid(idmap_ctx, host_group_sids[i], &group_dom_sid); -+ if (err != IDMAP_SUCCESS) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "sss_idmap_sid_to_smb_sid() failed for group_sid '%s': %d\n", -+ group_sids[i], err); -+ return EFAULT; -+ } -+ included = ad_gpo_dom_sid_equal(&ace_dom_sid, group_dom_sid); -+ sss_idmap_free_smb_sid(idmap_ctx, group_dom_sid); -+ if (included) { -+ *_included = true; -+ return EOK; -+ } -+ } -+ - *_included = false; - return EOK; - } -@@ -770,7 +788,9 @@ static enum ace_eval_agp_status ad_gpo_evaluate_ace(struct security_ace *ace, - const char *user_sid, - const char *host_sid, - const char **group_sids, -- int group_size) -+ int group_size, -+ const char **host_group_sids, -+ int host_group_size) - { - bool included = false; - int ret = 0; -@@ -782,9 +802,9 @@ static enum ace_eval_agp_status ad_gpo_evaluate_ace(struct security_ace *ace, - } - - ret = ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids, -- group_size, ace->trustee, idmap_ctx, -- &included); -- -+ group_size, host_group_sids, -+ host_group_size, ace->trustee, -+ idmap_ctx, &included); - if (ret != EOK) { - return AD_GPO_ACE_DENIED; - } -@@ -844,6 +864,8 @@ static errno_t ad_gpo_simple_evaluate_ace(struct security_ace *ace, - const char *host_sid, - const char **group_sids, - int group_size, -+ const char **host_group_sids, -+ int host_group_size, - uint32_t *_gpo_access_granted_status, - uint32_t *_gpo_access_denied_status) - { -@@ -856,6 +878,7 @@ static errno_t ad_gpo_simple_evaluate_ace(struct security_ace *ace, - } - - ret = ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids, group_size, -+ host_group_sids, host_group_size, - ace->trustee, idmap_ctx, &included); - - if (ret != EOK || !included) { -@@ -895,6 +918,8 @@ static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl, - const char *host_sid, - const char **group_sids, - int group_size, -+ const char **host_group_sids, -+ int host_group_size, - bool *_dacl_access_allowed) - { - uint32_t num_aces = 0; -@@ -931,6 +956,7 @@ static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl, - - ret = ad_gpo_simple_evaluate_ace(ace, idmap_ctx, user_sid, host_sid, - group_sids, group_size, -+ host_group_sids, host_group_size, - &access_granted_status, - &access_denied_status); - -@@ -963,7 +989,8 @@ static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl, - } - - ace_status = ad_gpo_evaluate_ace(ace, idmap_ctx, user_sid, host_sid, -- group_sids, group_size); -+ group_sids, group_size, -+ host_group_sids, host_group_size); - - switch (ace_status) { - case AD_GPO_ACE_NEUTRAL: -@@ -1016,8 +1043,9 @@ static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl, - static errno_t - ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx, - const char *user, -- const char *host_sid, -+ const char *host_fqdn, - struct sss_domain_info *domain, -+ struct sss_domain_info *host_domain, - struct sss_idmap_ctx *idmap_ctx, - struct gp_gpo **candidate_gpos, - int num_candidate_gpos, -@@ -1033,6 +1061,9 @@ ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx, - const char *user_sid = NULL; - const char **group_sids = NULL; - int group_size = 0; -+ const char *host_sid = NULL; -+ const char **host_group_sids = NULL; -+ int host_group_size = 0; - int gpo_dn_idx = 0; - bool access_allowed = false; - struct gp_gpo **dacl_filtered_gpos = NULL; -@@ -1052,6 +1083,15 @@ ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx, - goto done; - } - -+ ret = ad_gpo_get_sids(tmp_ctx, host_fqdn, host_domain, &host_sid, -+ &host_group_sids, &host_group_size); -+ if (ret != EOK) { -+ ret = ERR_NO_SIDS; -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Unable to retrieve host SIDs: [%d](%s)\n", ret, sss_strerror(ret)); -+ goto done; -+ } -+ - dacl_filtered_gpos = talloc_array(tmp_ctx, - struct gp_gpo *, - num_candidate_gpos + 1); -@@ -1096,7 +1136,8 @@ ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx, - - if ((sd->type & SEC_DESC_DACL_PRESENT) && (dacl != NULL)) { - ret = ad_gpo_evaluate_dacl(dacl, idmap_ctx, user_sid, host_sid, -- group_sids, group_size, &access_allowed); -+ group_sids, group_size, host_group_sids, -+ host_group_size, &access_allowed); - if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, - "Could not determine if GPO is applicable\n"); -@@ -1773,6 +1814,8 @@ struct ad_gpo_access_state { - int timeout; - struct sss_domain_info *user_domain; - struct sss_domain_info *host_domain; -+ const char *host_sam_account_name; -+ char *host_fqdn; - const char *user; - int gpo_timeout_option; - const char *ad_hostname; -@@ -1793,7 +1836,6 @@ static void ad_gpo_process_gpo_done(struct tevent_req *subreq); - - static errno_t ad_gpo_cse_step(struct tevent_req *req); - static void ad_gpo_cse_done(struct tevent_req *subreq); --static void ad_gpo_get_host_sid_retrieval_done(struct tevent_req *subreq); - - struct tevent_req * - ad_gpo_access_send(TALLOC_CTX *mem_ctx, -@@ -1967,15 +2009,11 @@ ad_gpo_connect_done(struct tevent_req *subreq) - { - struct tevent_req *req; - struct ad_gpo_access_state *state; -- char *filter; -- const char *sam_account_name; -- char *domain_dn; - int dp_error; - errno_t ret; - char *server_uri; - LDAPURLDesc *lud; -- -- const char *attrs[] = {AD_AT_DN, AD_AT_UAC, NULL}; -+ struct sdap_domain *sdom; - - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct ad_gpo_access_state); -@@ -2041,47 +2079,40 @@ ad_gpo_connect_done(struct tevent_req *subreq) - - /* SDAP_SASL_AUTHID contains the name used for kinit and SASL bind which - * in the AD case is the NetBIOS name. */ -- sam_account_name = dp_opt_get_string(state->opts->basic, SDAP_SASL_AUTHID); -- if (sam_account_name == NULL) { -+ state->host_sam_account_name = dp_opt_get_string(state->opts->basic, -+ SDAP_SASL_AUTHID); -+ if (state->host_sam_account_name == NULL) { - ret = ENOMEM; - goto done; - } - -- DEBUG(SSSDBG_TRACE_FUNC, "sam_account_name is %s\n", sam_account_name); -+ DEBUG(SSSDBG_TRACE_FUNC, "sam_account_name is %s\n", -+ state->host_sam_account_name); - -- /* Convert the domain name into domain DN */ -- ret = domain_to_basedn(state, state->ad_domain, &domain_dn); -- if (ret != EOK) { -+ state->host_fqdn = sss_create_internal_fqname(state, state->host_sam_account_name, -+ state->host_domain->name); -+ if (state->host_fqdn == NULL) { - DEBUG(SSSDBG_OP_FAILURE, -- "Cannot convert domain name [%s] to base DN [%d]: %s\n", -- state->ad_domain, ret, sss_strerror(ret)); -- goto done; -- } -- -- /* SDAP_OC_USER objectclass covers both users and computers */ -- filter = talloc_asprintf(state, -- "(&(objectclass=%s)(%s=%s))", -- state->opts->user_map[SDAP_OC_USER].name, -- AD_AT_SAMACCOUNTNAME, -- sam_account_name); -- if (filter == NULL) { -+ "Failed to create fully-qualified host name.\n"); - ret = ENOMEM; - goto done; - } - -- subreq = sdap_get_generic_send(state, state->ev, state->opts, -- sdap_id_op_handle(state->sdap_op), -- domain_dn, LDAP_SCOPE_SUBTREE, -- filter, attrs, NULL, 0, -- state->timeout, -- false); -- -- if (subreq == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); -+ /* AD handle computers the same as users */ -+ sdom = sdap_domain_get(state->access_ctx->ad_id_ctx->sdap_id_ctx->opts, -+ state->host_domain); -+ if (sdom == NULL) { - ret = EIO; - goto done; - } - -+ subreq = groups_by_user_send(state, state->ev, -+ state->access_ctx->ad_id_ctx->sdap_id_ctx, -+ sdom, state->conn, -+ state->host_fqdn, -+ BE_FILTER_NAME, -+ NULL, -+ true); - tevent_req_set_callback(subreq, ad_gpo_target_dn_retrieval_done, req); - - ret = EOK; -@@ -2100,22 +2131,20 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq) - struct ad_gpo_access_state *state; - int ret; - int dp_error; -- size_t reply_count; -- struct sysdb_attrs **reply; -+ int sdap_ret; - const char *target_dn = NULL; - uint32_t uac; -- const char *attrs[] = {AD_AT_SID, NULL}; -- struct ldb_message *msg; -- static const char *host_attrs[] = { SYSDB_SID_STR, NULL }; -+ static const char *host_attrs[] = { SYSDB_ORIG_DN, SYSDB_AD_USER_ACCOUNT_CONTROL, SYSDB_SID_STR, NULL }; -+ struct ldb_result *res = NULL; -+ const char *tmp = NULL; -+ char *endptr; - - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct ad_gpo_access_state); -- ret = sdap_get_generic_recv(subreq, state, -- &reply_count, &reply); -+ ret = groups_by_user_recv(subreq, &dp_error, &sdap_ret); - talloc_zfree(subreq); - if (ret != EOK) { -- ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); -- if (ret == EAGAIN && dp_error == DP_ERR_OFFLINE) { -+ if (sdap_ret == EAGAIN && dp_error == DP_ERR_OFFLINE) { - DEBUG(SSSDBG_TRACE_FUNC, "Preparing for offline operation.\n"); - ret = process_offline_gpos(state, - state->user, -@@ -2144,27 +2173,25 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq) - goto done; - } - -- /* make sure there is only one non-NULL reply returned */ -- -- if (reply_count < 1) { -- DEBUG(SSSDBG_OP_FAILURE, "No DN retrieved for policy target.\n"); -- ret = ENOENT; -- goto done; -- } else if (reply_count > 1) { -- DEBUG(SSSDBG_OP_FAILURE, "Multiple replies for policy target\n"); -- ret = ERR_INTERNAL; -+ ret = sysdb_get_user_attr(state, state->host_domain, -+ state->host_fqdn, -+ host_attrs, &res); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to read host attributes.\n"); - goto done; -- } else if (reply == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "reply_count is 1, but reply is NULL\n"); -- ret = ERR_INTERNAL; -+ } -+ if (res->count != 1) { -+ DEBUG(SSSDBG_OP_FAILURE, "Unexpected number [%d] of results searching " -+ "for [%s], expected 1.\n", res->count, -+ state->host_sam_account_name); -+ ret = EINVAL; - goto done; - } - -- /* reply[0] holds requested attributes of single reply */ -- ret = sysdb_attrs_get_string(reply[0], AD_AT_DN, &target_dn); -- if (ret != EOK) { -+ target_dn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_ORIG_DN, NULL); -+ if (target_dn == NULL) { - DEBUG(SSSDBG_OP_FAILURE, -- "sysdb_attrs_get_string failed: [%d](%s)\n", -+ "ldb_msg_find_attr_as_string failed: [%d](%s)\n", - ret, sss_strerror(ret)); - goto done; - } -@@ -2174,14 +2201,29 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq) - goto done; - } - -- ret = sysdb_attrs_get_uint32_t(reply[0], AD_AT_UAC, &uac); -- if (ret != EOK) { -+ tmp = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_AD_USER_ACCOUNT_CONTROL, -+ NULL); -+ if (tmp == NULL) { - DEBUG(SSSDBG_OP_FAILURE, -- "sysdb_attrs_get_uint32_t failed: [%d](%s)\n", -+ "ldb_msg_find_attr_as_string failed: [%d](%s)\n", - ret, sss_strerror(ret)); - goto done; - } - -+ uac = strtouint32(tmp, &endptr, 10); -+ if (errno != 0) { -+ ret = errno; -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to convert UAC [%s] into uint32_t.\n", -+ tmp); -+ goto done; -+ } -+ if (*endptr != '\0') { -+ ret = EINVAL; -+ DEBUG(SSSDBG_OP_FAILURE, "UAC [%s] is not a pure numerical value.\n", -+ tmp); -+ goto done; -+ } -+ - /* we only support computer policy targets, not users */ - if (!(uac & UAC_WORKSTATION_TRUST_ACCOUNT || - uac & UAC_SERVER_TRUST_ACCOUNT)) { -@@ -2192,36 +2234,8 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq) - goto done; - } - -- /* Check if computer exists in cache */ -- ret = sysdb_get_computer(state, state->user_domain, state->ad_hostname, -- host_attrs, &msg); -- if (ret == ENOENT) { -- /* The computer is not in cache so query LDAP server */ -- subreq = sdap_get_generic_send(state, state->ev, state->opts, -- sdap_id_op_handle(state->sdap_op), -- state->target_dn, LDAP_SCOPE_BASE, -- "(&)", attrs, NULL, 0, -- state->timeout, -- false); -- -- if (subreq == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); -- ret = ENOMEM; -- goto done; -- } -- -- tevent_req_set_callback(subreq, ad_gpo_get_host_sid_retrieval_done, req); -- return; -- } else if (ret != EOK) { -- ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); -- goto done; -- } -- -- /* The computer exists in the cache, there is no need to query LDAP. -- * Store the retrieved host sid from cache in the state to avoid querying -- * the cache again in ad_gpo_get_sids. -- */ -- state->host_sid = ldb_msg_find_attr_as_string(msg, SYSDB_SID_STR, NULL); -+ state->host_sid = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SID_STR, -+ NULL); - talloc_steal(state, state->host_sid); - - subreq = ad_gpo_process_som_send(state, -@@ -2251,125 +2265,6 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq) - - } - --enum ndr_err_code --ndr_pull_dom_sid(struct ndr_pull *ndr, -- int ndr_flags, -- struct dom_sid *r); -- --static void ad_gpo_get_host_sid_retrieval_done(struct tevent_req *subreq) --{ -- struct tevent_req *req; -- struct ad_gpo_access_state *state; -- int ret; -- int dp_error; -- size_t reply_count; -- struct sysdb_attrs **reply; -- struct ldb_message_element *el = NULL; -- enum ndr_err_code ndr_err; -- struct dom_sid host_sid; -- char *sid_str; -- -- req = tevent_req_callback_data(subreq, struct tevent_req); -- state = tevent_req_data(req, struct ad_gpo_access_state); -- -- ret = sdap_get_generic_recv(subreq, state, -- &reply_count, &reply); -- talloc_zfree(subreq); -- -- if (ret != EOK) { -- ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); -- -- DEBUG(SSSDBG_OP_FAILURE, -- "sdap_get_generic_recv failed: [%d](%s)\n", -- ret, sss_strerror(ret)); -- ret = ENOENT; -- tevent_req_error(req, ret); -- return; -- } -- -- if (reply_count == 0 || !reply) { -- DEBUG(SSSDBG_OP_FAILURE, -- "sdap_get_generic_recv failed to receive host sid\n"); -- ret = EIO; -- goto done; -- } -- -- /* reply[0] holds the requested attribute */ -- ret = sysdb_attrs_get_el(reply[0], AD_AT_SID, &el); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- "sysdb_attrs_get_el failed: [%d](%s)\n", -- ret, sss_strerror(ret)); -- goto done; -- } -- if (el->num_values != 1) { -- DEBUG(SSSDBG_OP_FAILURE, -- "ad_gpo_get_host_sid_retrieval_done failed: sid not present\n"); -- ret = EIO; -- goto done; -- } -- -- /* parse the dom_sid from the ldb blob */ -- ndr_err = ndr_pull_struct_blob_all((DATA_BLOB*)&(el->values[0]), -- subreq, &host_sid, -- (ndr_pull_flags_fn_t)ndr_pull_dom_sid); -- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { -- DEBUG(SSSDBG_OP_FAILURE, -- "ndr_pull_struct_blob_all failed: [%d]\n", -- ndr_err); -- ret = EIO; -- goto done; -- } -- -- /* Convert the dom_sid to a sid string */ -- ret = sss_idmap_smb_sid_to_sid(state->opts->idmap_ctx->map, -- &host_sid, &sid_str); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- "sss_idmap_smb_sid_to_sid failed: [%d](%s)\n", -- ret, sss_strerror(ret)); -- goto done; -- } -- state->host_sid = talloc_steal(state, sid_str); -- -- /* Put the sid string in the sysdb */ -- ret = sysdb_set_computer(subreq, state->user_domain, -- state->ad_hostname, state->host_sid, -- state->user_domain->computer_timeout, -- time(NULL)); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- "sysdb_set_computer failed: [%d](%s)\n", -- ret, sss_strerror(ret)); -- goto done; -- } -- -- subreq = ad_gpo_process_som_send(state, -- state->ev, -- state->conn, -- state->ldb_ctx, -- state->sdap_op, -- state->opts, -- state->access_ctx->ad_options, -- state->timeout, -- state->target_dn, -- state->ad_domain); -- if (subreq == NULL) { -- ret = ENOMEM; -- goto done; -- } -- -- tevent_req_set_callback(subreq, ad_gpo_process_som_done, req); -- -- ret = EOK; -- -- done: -- -- if (ret != EOK) { -- tevent_req_error(req, ret); -- } --} -- - static void - ad_gpo_process_som_done(struct tevent_req *subreq) - { -@@ -2487,8 +2382,9 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq) - goto done; - } - -- ret = ad_gpo_filter_gpos_by_dacl(state, state->user, state->host_sid, -+ ret = ad_gpo_filter_gpos_by_dacl(state, state->user, state->host_fqdn, - state->user_domain, -+ state->host_domain, - state->opts->idmap_ctx->map, - candidate_gpos, num_candidate_gpos, - &state->dacl_filtered_gpos, -diff --git a/src/tests/cmocka/test_ad_gpo.c b/src/tests/cmocka/test_ad_gpo.c -index 8660b0510..d49f6c54c 100644 ---- a/src/tests/cmocka/test_ad_gpo.c -+++ b/src/tests/cmocka/test_ad_gpo.c -@@ -270,6 +270,8 @@ static void test_ad_gpo_ace_includes_client_sid(const char *user_sid, - const char *host_sid, - const char **group_sids, - int group_size, -+ const char **host_group_sids, -+ int host_group_size, - struct dom_sid ace_dom_sid, - bool expected) - { -@@ -288,8 +290,9 @@ static void test_ad_gpo_ace_includes_client_sid(const char *user_sid, - assert_int_equal(err, IDMAP_SUCCESS); - - ret = ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids, -- group_size, ace_dom_sid, idmap_ctx, -- &includes_client_sid); -+ group_size, host_group_sids, -+ host_group_size, ace_dom_sid, -+ idmap_ctx, &includes_client_sid); - talloc_free(idmap_ctx); - - assert_int_equal(ret, EOK); -@@ -312,8 +315,12 @@ void test_ad_gpo_ace_includes_client_sid_true(void **state) - const char *group_sids[] = {"S-1-5-21-2-3-4", - "S-1-5-21-2-3-5"}; - -+ int host_group_size = 0; -+ const char *host_group_sids[] = { NULL }; -+ - test_ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids, -- group_size, ace_dom_sid, true); -+ group_size, host_group_sids, -+ host_group_size, ace_dom_sid, true); - } - - void test_ad_gpo_ace_includes_client_sid_false(void **state) -@@ -328,8 +335,12 @@ void test_ad_gpo_ace_includes_client_sid_false(void **state) - const char *group_sids[] = {"S-1-5-21-2-3-5", - "S-1-5-21-2-3-6"}; - -+ int host_group_size = 0; -+ const char *host_group_sids[] = { NULL }; -+ - test_ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids, -- group_size, ace_dom_sid, false); -+ group_size, host_group_sids, -+ host_group_size, ace_dom_sid, false); - } - - void test_ad_gpo_ace_includes_host_sid_true(void **state) -@@ -343,8 +354,12 @@ void test_ad_gpo_ace_includes_host_sid_true(void **state) - int group_size = 0; - const char *group_sids[] = {}; - -+ int host_group_size = 0; -+ const char *host_group_sids[] = { NULL }; -+ - test_ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids, -- group_size, ace_dom_sid, true); -+ group_size, host_group_sids, -+ host_group_size, ace_dom_sid, true); - } - - uint8_t test_sid_data[] = { --- -2.41.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 new file mode 100644 index 0000000..e9220d5 --- /dev/null +++ b/SOURCES/0013-pam-fix-storing-auth-types-for-offline-auth.patch @@ -0,0 +1,57 @@ +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 new file mode 100644 index 0000000..5bb0332 --- /dev/null +++ b/SOURCES/0014-ad-gpo-use-hash-to-store-intermediate-results.patch @@ -0,0 +1,218 @@ +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/0014-sysdb-remove-sysdb_computer.-ch.patch b/SOURCES/0014-sysdb-remove-sysdb_computer.-ch.patch deleted file mode 100644 index d935224..0000000 --- a/SOURCES/0014-sysdb-remove-sysdb_computer.-ch.patch +++ /dev/null @@ -1,307 +0,0 @@ -From dda0f2e0b0288b5516409c3ee6548ecc5f4ff407 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 17 Nov 2023 19:09:05 +0100 -Subject: [PATCH 14/15] sysdb: remove sysdb_computer.[ch] -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The related calls are not needed anymore. - -Resolves: https://github.com/SSSD/sssd/issues/5708 - -Reviewed-by: Justin Stephenson -Reviewed-by: Tomáš Halman -(cherry picked from commit ff23e7e2879f94a907d05b615dbdb547aaa2e542) ---- - Makefile.am | 2 - - src/db/sysdb_computer.c | 185 -------------------------------------- - src/db/sysdb_computer.h | 51 ----------- - src/providers/ad/ad_gpo.c | 1 - - 4 files changed, 239 deletions(-) - delete mode 100644 src/db/sysdb_computer.c - delete mode 100644 src/db/sysdb_computer.h - -diff --git a/Makefile.am b/Makefile.am -index 66f3141d1..f0b072fdb 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -810,7 +810,6 @@ dist_noinst_HEADERS = \ - src/db/sysdb_subid.h \ - src/db/sysdb_domain_resolution_order.h \ - src/db/sysdb_passkey_user_verification.h \ -- src/db/sysdb_computer.h \ - src/db/sysdb_iphosts.h \ - src/db/sysdb_ipnetworks.h \ - src/confdb/confdb.h \ -@@ -1249,7 +1248,6 @@ libsss_util_la_SOURCES = \ - src/db/sysdb_iphosts.c \ - src/db/sysdb_ipnetworks.c \ - src/util/sss_pam_data.c \ -- src/db/sysdb_computer.c \ - src/db/sysdb_subid.c \ - src/util/util.c \ - src/util/util_ext.c \ -diff --git a/src/db/sysdb_computer.c b/src/db/sysdb_computer.c -deleted file mode 100644 -index 9fcaf5a7c..000000000 ---- a/src/db/sysdb_computer.c -+++ /dev/null -@@ -1,185 +0,0 @@ --/* -- SSSD -- -- Authors: -- Samuel Cabrero -- David Mulder -- -- Copyright (C) 2019 SUSE LINUX GmbH, Nuernberg, Germany. -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . --*/ -- --#include -- --#include "db/sysdb.h" --#include "db/sysdb_private.h" --#include "db/sysdb_computer.h" -- --static errno_t --sysdb_search_computer(TALLOC_CTX *mem_ctx, -- struct sss_domain_info *domain, -- const char *filter, -- const char **attrs, -- size_t *_num_hosts, -- struct ldb_message ***_hosts) --{ -- errno_t ret; -- TALLOC_CTX *tmp_ctx; -- struct ldb_message **results; -- size_t num_results; -- -- tmp_ctx = talloc_new(NULL); -- if (!tmp_ctx) { -- return ENOMEM; -- } -- -- ret = sysdb_search_custom(tmp_ctx, domain, filter, -- COMPUTERS_SUBDIR, attrs, -- &num_results, &results); -- if (ret != EOK && ret != ENOENT) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "Error looking up host [%d]: %s\n", -- ret, strerror(ret)); -- goto done; -- } else if (ret == ENOENT) { -- DEBUG(SSSDBG_TRACE_FUNC, "No such host\n"); -- *_hosts = NULL; -- *_num_hosts = 0; -- goto done; -- } -- -- *_hosts = talloc_steal(mem_ctx, results); -- *_num_hosts = num_results; -- ret = EOK; -- --done: -- talloc_free(tmp_ctx); -- -- return ret; --} -- --int --sysdb_get_computer(TALLOC_CTX *mem_ctx, -- struct sss_domain_info *domain, -- const char *computer_name, -- const char **attrs, -- struct ldb_message **_computer) --{ -- TALLOC_CTX *tmp_ctx; -- errno_t ret; -- const char *filter; -- struct ldb_message **hosts; -- size_t num_hosts; -- -- tmp_ctx = talloc_new(NULL); -- if (!tmp_ctx) { -- return ENOMEM; -- } -- -- filter = talloc_asprintf(tmp_ctx, SYSDB_COMP_FILTER, computer_name); -- if (!filter) { -- ret = ENOMEM; -- goto done; -- } -- -- ret = sysdb_search_computer(tmp_ctx, domain, filter, attrs, -- &num_hosts, &hosts); -- if (ret != EOK) { -- goto done; -- } -- -- if (num_hosts != 1) { -- ret = EINVAL; -- DEBUG(SSSDBG_CRIT_FAILURE, -- "Did not find a single host with name %s\n", computer_name); -- goto done; -- } -- -- *_computer = talloc_steal(mem_ctx, hosts[0]); -- ret = EOK; -- --done: -- talloc_free(tmp_ctx); -- -- return ret; --} -- --int --sysdb_set_computer(TALLOC_CTX *mem_ctx, -- struct sss_domain_info *domain, -- const char *computer_name, -- const char *sid_str, -- int cache_timeout, -- time_t now) --{ -- TALLOC_CTX *tmp_ctx; -- int ret; -- struct sysdb_attrs *attrs; -- -- tmp_ctx = talloc_new(NULL); -- if (!tmp_ctx) { -- return ENOMEM; -- } -- -- attrs = sysdb_new_attrs(tmp_ctx); -- if (!attrs) { -- ret = ENOMEM; -- goto done; -- } -- -- ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, sid_str); -- if (ret) goto done; -- -- ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, SYSDB_COMPUTER_CLASS); -- if (ret) goto done; -- -- ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, computer_name); -- if (ret) goto done; -- -- /* creation time */ -- ret = sysdb_attrs_add_time_t(attrs, SYSDB_CREATE_TIME, now); -- if (ret) goto done; -- -- /* Set a cache expire time. There is a periodic task that cleans up -- * expired entries from the cache even when enumeration is disabled */ -- ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, -- cache_timeout ? (now + cache_timeout) : 0); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "Could not set sysdb cache expire [%d]: %s\n", -- ret, strerror(ret)); -- goto done; -- } -- -- ret = sysdb_store_custom(domain, computer_name, COMPUTERS_SUBDIR, attrs); -- if (ret) goto done; -- -- /* FIXME As a future improvement we have to extend domain enumeration. -- * When 'enumerate = true' for a domain, sssd starts a periodic task -- * that brings all users and groups to the cache, cleaning up -- * stale objects after each run. If enumeration is disabled, the cleanup -- * task for expired entries is started instead. -- * -- * We have to extend the enumeration task to fetch 'computer' -- * objects as well (see ad_id_enumeration_send, the entry point of the -- * enumeration task for the id provider). -- */ --done: -- if (ret) { -- DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); -- } -- talloc_zfree(tmp_ctx); -- -- return ret; --} -diff --git a/src/db/sysdb_computer.h b/src/db/sysdb_computer.h -deleted file mode 100644 -index 4be67fdf5..000000000 ---- a/src/db/sysdb_computer.h -+++ /dev/null -@@ -1,51 +0,0 @@ --/* -- SSSD -- -- Authors: -- Samuel Cabrero -- David Mulder -- -- Copyright (C) 2019 SUSE LINUX GmbH, Nuernberg, Germany. -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . --*/ -- --#ifndef SYSDB_COMPUTERS_H_ --#define SYSDB_COMPUTERS_H_ -- --#include "db/sysdb.h" -- --#define COMPUTERS_SUBDIR "computers" --#define SYSDB_COMPUTER_CLASS "computer" --#define SYSDB_COMPUTERS_CONTAINER "cn="COMPUTERS_SUBDIR --#define SYSDB_TMPL_COMPUTER_BASE SYSDB_COMPUTERS_CONTAINER","SYSDB_DOM_BASE --#define SYSDB_TMPL_COMPUTER SYSDB_NAME"=%s,"SYSDB_TMPL_COMPUTER_BASE --#define SYSDB_COMP_FILTER "(&("SYSDB_NAME"=%s)("SYSDB_OBJECTCLASS"="SYSDB_COMPUTER_CLASS"))" -- --int --sysdb_get_computer(TALLOC_CTX *mem_ctx, -- struct sss_domain_info *domain, -- const char *computer_name, -- const char **attrs, -- struct ldb_message **computer); -- --int --sysdb_set_computer(TALLOC_CTX *mem_ctx, -- struct sss_domain_info *domain, -- const char *computer_name, -- const char *sid_str, -- int cache_timeout, -- time_t now); -- --#endif /* SYSDB_COMPUTERS_H_ */ -diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c -index 1c731b222..f78f17f7b 100644 ---- a/src/providers/ad/ad_gpo.c -+++ b/src/providers/ad/ad_gpo.c -@@ -53,7 +53,6 @@ - #include "util/sss_chain_id.h" - #include - #include --#include - - /* == gpo-ldap constants =================================================== */ - --- -2.41.0 - diff --git a/SOURCES/0015-sdap-add-set_non_posix-parameter.patch b/SOURCES/0015-sdap-add-set_non_posix-parameter.patch deleted file mode 100644 index e796983..0000000 --- a/SOURCES/0015-sdap-add-set_non_posix-parameter.patch +++ /dev/null @@ -1,351 +0,0 @@ -From f5ce7c1dae2725df54a36e79ac06d1b48da54f5d Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 9 Jan 2024 11:14:42 +0100 -Subject: [PATCH 15/15] sdap: add set_non_posix parameter -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds a new parameter set_non_posix to the user and group -lookup calls. Currently the domain type is used to determine if the -search should be restricted to POSIX objects or not. The new option -allows to drop this restriction explicitly to look up non-POSIX objects. - -Resolves: https://github.com/SSSD/sssd/issues/5708 - -Reviewed-by: Justin Stephenson -Reviewed-by: Tomáš Halman -(cherry picked from commit 5f63d9bfc71b271844db1ee122172630be1afed0) ---- - src/providers/ad/ad_gpo.c | 1 + - src/providers/ipa/ipa_subdomains_ext_groups.c | 2 +- - src/providers/ldap/ldap_common.h | 6 ++- - src/providers/ldap/ldap_id.c | 38 +++++++++++-------- - src/providers/ldap/sdap_async.h | 3 +- - src/providers/ldap/sdap_async_initgroups.c | 9 +++-- - src/providers/ldap/sdap_async_initgroups_ad.c | 2 +- - src/providers/ldap/sdap_async_users.c | 9 +++-- - src/providers/ldap/sdap_users.h | 3 +- - 9 files changed, 44 insertions(+), 29 deletions(-) - -diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c -index f78f17f7b..336d475d1 100644 ---- a/src/providers/ad/ad_gpo.c -+++ b/src/providers/ad/ad_gpo.c -@@ -2111,6 +2111,7 @@ ad_gpo_connect_done(struct tevent_req *subreq) - state->host_fqdn, - BE_FILTER_NAME, - NULL, -+ true, - true); - tevent_req_set_callback(subreq, ad_gpo_target_dn_retrieval_done, req); - -diff --git a/src/providers/ipa/ipa_subdomains_ext_groups.c b/src/providers/ipa/ipa_subdomains_ext_groups.c -index b385c2f27..f4f84749a 100644 ---- a/src/providers/ipa/ipa_subdomains_ext_groups.c -+++ b/src/providers/ipa/ipa_subdomains_ext_groups.c -@@ -883,7 +883,7 @@ static void ipa_add_ad_memberships_get_next(struct tevent_req *req) - state->sdap_id_ctx->conn, - fq_name, - BE_FILTER_NAME, -- false, false); -+ false, false, false); - if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "groups_get_send failed.\n"); - ret = ENOMEM; -diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h -index 6df7b3df4..7159d6356 100644 ---- a/src/providers/ldap/ldap_common.h -+++ b/src/providers/ldap/ldap_common.h -@@ -295,7 +295,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, - const char *name, - int filter_type, - bool noexist_delete, -- bool no_members); -+ bool no_members, -+ bool set_non_posix); - int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret); - - struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, -@@ -306,7 +307,8 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, - const char *filter_value, - int filter_type, - const char *extra_value, -- bool noexist_delete); -+ bool noexist_delete, -+ bool set_non_posix); - - int groups_by_user_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret); - -diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c -index fb81a1793..da54816bd 100644 ---- a/src/providers/ldap/ldap_id.c -+++ b/src/providers/ldap/ldap_id.c -@@ -165,7 +165,8 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, - const char *filter_value, - int filter_type, - const char *extra_value, -- bool noexist_delete) -+ bool noexist_delete, -+ bool set_non_posix) - { - struct tevent_req *req; - struct users_get_state *state; -@@ -202,7 +203,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, - state->filter_value = filter_value; - state->filter_type = filter_type; - -- if (state->domain->type == DOM_TYPE_APPLICATION) { -+ if (state->domain->type == DOM_TYPE_APPLICATION || set_non_posix) { - state->non_posix = true; - } - -@@ -582,7 +583,8 @@ static void users_get_done(struct tevent_req *subreq) - ret = sdap_fallback_local_user(state, state->shortname, uid, &usr_attrs); - if (ret == EOK) { - ret = sdap_save_user(state, state->ctx->opts, state->domain, -- usr_attrs[0], NULL, NULL, 0); -+ usr_attrs[0], NULL, NULL, 0, -+ state->non_posix); - } - } - } -@@ -665,7 +667,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, - const char *filter_value, - int filter_type, - bool noexist_delete, -- bool no_members) -+ bool no_members, -+ bool set_non_posix) - { - struct tevent_req *req; - struct groups_get_state *state; -@@ -703,7 +706,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, - state->filter_value = filter_value; - state->filter_type = filter_type; - -- if (state->domain->type == DOM_TYPE_APPLICATION) { -+ if (state->domain->type == DOM_TYPE_APPLICATION || set_non_posix) { - state->non_posix = true; - } - -@@ -991,7 +994,8 @@ static void groups_get_done(struct tevent_req *subreq) - state->filter_value, - state->filter_type, - NULL, -- state->noexist_delete); -+ state->noexist_delete, -+ false); - if (subreq == NULL) { - tevent_req_error(req, ENOMEM); - return; -@@ -1159,7 +1163,8 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, - const char *filter_value, - int filter_type, - const char *extra_value, -- bool noexist_delete) -+ bool noexist_delete, -+ bool set_non_posix) - { - struct tevent_req *req; - struct groups_by_user_state *state; -@@ -1188,7 +1193,7 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, - state->domain = sdom->dom; - state->sysdb = sdom->dom->sysdb; - -- if (state->domain->type == DOM_TYPE_APPLICATION) { -+ if (state->domain->type == DOM_TYPE_APPLICATION || set_non_posix) { - state->non_posix = true; - } - -@@ -1252,7 +1257,8 @@ static void groups_by_user_connect_done(struct tevent_req *subreq) - state->filter_value, - state->filter_type, - state->extra_value, -- state->attrs); -+ state->attrs, -+ state->non_posix); - if (!subreq) { - tevent_req_error(req, ENOMEM); - return; -@@ -1421,7 +1427,8 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, - ar->filter_value, - ar->filter_type, - ar->extra_value, -- noexist_delete); -+ noexist_delete, -+ false); - break; - - case BE_REQ_GROUP: /* group */ -@@ -1429,7 +1436,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, - sdom, conn, - ar->filter_value, - ar->filter_type, -- noexist_delete, false); -+ noexist_delete, false, false); - break; - - case BE_REQ_INITGROUPS: /* init groups for user */ -@@ -1446,7 +1453,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, - ar->filter_value, - ar->filter_type, - ar->extra_value, -- noexist_delete); -+ noexist_delete, false); - break; - - case BE_REQ_SUBID_RANGES: -@@ -1545,7 +1552,8 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, - ar->filter_value, - ar->filter_type, - ar->extra_value, -- noexist_delete); -+ noexist_delete, -+ false); - break; - - default: /*fail*/ -@@ -1741,7 +1749,7 @@ static struct tevent_req *get_user_and_group_send(TALLOC_CTX *memctx, - subreq = groups_get_send(req, state->ev, state->id_ctx, - state->sdom, state->conn, - state->filter_val, state->filter_type, -- state->noexist_delete, false); -+ state->noexist_delete, false, false); - if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "groups_get_send failed.\n"); - ret = ENOMEM; -@@ -1795,7 +1803,7 @@ static void get_user_and_group_groups_done(struct tevent_req *subreq) - subreq = users_get_send(req, state->ev, state->id_ctx, - state->sdom, user_conn, - state->filter_val, state->filter_type, NULL, -- state->noexist_delete); -+ state->noexist_delete, false); - if (subreq == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "users_get_send failed.\n"); - tevent_req_error(req, ENOMEM); -diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h -index a7b0f6912..5458d21f1 100644 ---- a/src/providers/ldap/sdap_async.h -+++ b/src/providers/ldap/sdap_async.h -@@ -161,7 +161,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, - const char *name, - int filter_type, - const char *extra_value, -- const char **grp_attrs); -+ const char **grp_attrs, -+ bool set_non_posix); - int sdap_get_initgr_recv(struct tevent_req *req); - - struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx, -diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c -index 4c8538e8a..97be594a3 100644 ---- a/src/providers/ldap/sdap_async_initgroups.c -+++ b/src/providers/ldap/sdap_async_initgroups.c -@@ -2735,7 +2735,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, - const char *filter_value, - int filter_type, - const char *extra_value, -- const char **grp_attrs) -+ const char **grp_attrs, -+ bool set_non_posix) - { - struct tevent_req *req; - struct sdap_get_initgr_state *state; -@@ -2771,7 +2772,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, - goto done; - } - -- if (state->dom->type == DOM_TYPE_APPLICATION) { -+ if (state->dom->type == DOM_TYPE_APPLICATION || set_non_posix) { - state->non_posix = true; - } - -@@ -3099,7 +3100,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq) - DEBUG(SSSDBG_TRACE_ALL, "Storing the user\n"); - - ret = sdap_save_user(state, state->opts, state->dom, state->orig_user, -- NULL, NULL, 0); -+ NULL, NULL, 0, state->non_posix); - if (ret) { - goto fail; - } -@@ -3435,7 +3436,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq) - subreq = groups_get_send(req, state->ev, state->id_ctx, - state->id_ctx->opts->sdom, state->conn, - gid, BE_FILTER_IDNUM, false, -- false); -+ false, false); - if (!subreq) { - ret = ENOMEM; - goto done; -diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c -index bb18f35dc..fb80c9242 100644 ---- a/src/providers/ldap/sdap_async_initgroups_ad.c -+++ b/src/providers/ldap/sdap_async_initgroups_ad.c -@@ -346,7 +346,7 @@ static errno_t sdap_ad_resolve_sids_step(struct tevent_req *req) - - subreq = groups_get_send(state, state->ev, state->id_ctx, sdap_domain, - state->conn, state->current_sid, -- BE_FILTER_SECID, false, true); -+ BE_FILTER_SECID, false, true, false); - if (subreq == NULL) { - return ENOMEM; - } -diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c -index 9dcb59e23..728295d9d 100644 ---- a/src/providers/ldap/sdap_async_users.c -+++ b/src/providers/ldap/sdap_async_users.c -@@ -175,7 +175,8 @@ int sdap_save_user(TALLOC_CTX *memctx, - struct sysdb_attrs *attrs, - struct sysdb_attrs *mapped_attrs, - char **_usn_value, -- time_t now) -+ time_t now, -+ bool set_non_posix) - { - struct ldb_message_element *el; - int ret; -@@ -352,7 +353,7 @@ int sdap_save_user(TALLOC_CTX *memctx, - ret = sysdb_attrs_get_uint32_t(attrs, - opts->user_map[SDAP_AT_USER_UID].sys_name, - &uid); -- if (ret == ENOENT && dom->type == DOM_TYPE_APPLICATION) { -+ if (ret == ENOENT && (dom->type == DOM_TYPE_APPLICATION || set_non_posix)) { - DEBUG(SSSDBG_TRACE_INTERNAL, - "Marking object as non-POSIX and setting ID=0!\n"); - ret = sdap_set_non_posix_flag(user_attrs, -@@ -450,7 +451,7 @@ int sdap_save_user(TALLOC_CTX *memctx, - ret = sysdb_attrs_get_uint32_t(attrs, - opts->user_map[SDAP_AT_USER_GID].sys_name, - &gid); -- if (ret == ENOENT && dom->type == DOM_TYPE_APPLICATION) { -+ if (ret == ENOENT && (dom->type == DOM_TYPE_APPLICATION || set_non_posix)) { - DEBUG(SSSDBG_TRACE_INTERNAL, - "Marking object as non-POSIX and setting ID=0!\n"); - ret = sdap_set_non_posix_flag(attrs, -@@ -696,7 +697,7 @@ int sdap_save_users(TALLOC_CTX *memctx, - usn_value = NULL; - - ret = sdap_save_user(tmpctx, opts, dom, users[i], mapped_attrs, -- &usn_value, now); -+ &usn_value, now, false); - - /* Do not fail completely on errors. - * Just report the failure to save and go on */ -diff --git a/src/providers/ldap/sdap_users.h b/src/providers/ldap/sdap_users.h -index a6d088a6d..74284cd0a 100644 ---- a/src/providers/ldap/sdap_users.h -+++ b/src/providers/ldap/sdap_users.h -@@ -36,6 +36,7 @@ int sdap_save_user(TALLOC_CTX *memctx, - struct sysdb_attrs *attrs, - struct sysdb_attrs *mapped_attrs, - char **_usn_value, -- time_t now); -+ time_t now, -+ bool set_non_posix); - - #endif /* _SDAP_USERS_H_ */ --- -2.41.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 new file mode 100644 index 0000000..e7ddccc --- /dev/null +++ b/SOURCES/0015-tests-Drop-extensions-from-openssl-command-if-there-.patch @@ -0,0 +1,49 @@ +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/SOURCES/0016-ipa-Add-BUILD_PASSKEY-conditional-for-passkey-codepa.patch b/SOURCES/0016-ipa-Add-BUILD_PASSKEY-conditional-for-passkey-codepa.patch deleted file mode 100644 index 8c54a11..0000000 --- a/SOURCES/0016-ipa-Add-BUILD_PASSKEY-conditional-for-passkey-codepa.patch +++ /dev/null @@ -1,59 +0,0 @@ -From e98bdad5a1f6f1c9dccbabc0751c1d4cf270e0f3 Mon Sep 17 00:00:00 2001 -From: Justin Stephenson -Date: Wed, 10 Jan 2024 09:24:22 -0500 -Subject: [PATCH 16/18] ipa: Add BUILD_PASSKEY conditional for passkey codepath - ---- - Makefile.am | 3 ++- - src/providers/ipa/ipa_subdomains.c | 4 ++++ - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/Makefile.am b/Makefile.am -index 3e36ec9f7..e5271c4a5 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -4568,9 +4568,10 @@ if BUILD_SSH - libsss_ipa_la_SOURCES += src/providers/ipa/ipa_hostid.c - endif - -+if BUILD_PASSKEY - libsss_ipa_la_SOURCES += \ - src/providers/ipa/ipa_subdomains_passkey.c -- -+endif - - libsss_ad_la_SOURCES = \ - src/providers/ad/ad_opts.c \ -diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c -index 34cedc036..e19343a77 100644 ---- a/src/providers/ipa/ipa_subdomains.c -+++ b/src/providers/ipa/ipa_subdomains.c -@@ -30,7 +30,9 @@ - #include "providers/ipa/ipa_id.h" - #include "providers/ipa/ipa_opts.h" - #include "providers/ipa/ipa_config.h" -+#ifdef BUILD_PASSKEY - #include "providers/ipa/ipa_subdomains_passkey.h" -+#endif /* BUILD_PASSKEY */ - - #include - -@@ -2762,6 +2764,7 @@ static void ipa_subdomains_refresh_certmap_done(struct tevent_req *subreq) - /* Not good, but let's try to continue with other server side options */ - } - -+#ifdef BUILD_PASSKEY - subreq = ipa_subdomains_passkey_send(state, state->ev, state->sd_ctx, - sdap_id_op_handle(state->sdap_op)); - if (subreq == NULL) { -@@ -2792,6 +2795,7 @@ static void ipa_subdomains_refresh_passkey_done(struct tevent_req *subreq) - DEBUG(SSSDBG_IMPORTANT_INFO, "Passkey feature is not configured " - "on IPA server"); - } -+#endif /* BUILD_PASSKEY */ - - subreq = ipa_subdomains_master_send(state, state->ev, state->sd_ctx, - sdap_id_op_handle(state->sdap_op)); --- -2.41.0 - diff --git a/SOURCES/0017-pam-Conditionalize-passkey-code.patch b/SOURCES/0017-pam-Conditionalize-passkey-code.patch deleted file mode 100644 index 8638379..0000000 --- a/SOURCES/0017-pam-Conditionalize-passkey-code.patch +++ /dev/null @@ -1,872 +0,0 @@ -From 4ef0519f19ffe116960e161bdab8826630847c24 Mon Sep 17 00:00:00 2001 -From: Justin Stephenson -Date: Wed, 10 Jan 2024 09:41:00 -0500 -Subject: [PATCH 17/18] pam: Conditionalize passkey code - ---- - Makefile.am | 4 +- - src/responder/pam/pamsrv_cmd.c | 359 +---------------------------- - src/responder/pam/pamsrv_passkey.c | 350 ++++++++++++++++++++++++++++ - src/responder/pam/pamsrv_passkey.h | 8 + - 4 files changed, 367 insertions(+), 354 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index e5271c4a5..c58e336eb 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1558,8 +1558,10 @@ sssd_pam_SOURCES = \ - src/responder/pam/pam_prompting_config.c \ - src/sss_client/pam_sss_prompt_config.c \ - src/responder/pam/pam_helpers.c \ -- src/responder/pam/pamsrv_passkey.c \ - $(SSSD_RESPONDER_OBJ) -+if BUILD_PASSKEY -+ sssd_pam_SOURCES += src/responder/pam/pamsrv_passkey.c -+endif - sssd_pam_CFLAGS = \ - $(AM_CFLAGS) \ - $(GSSAPI_KRB5_CFLAGS) \ -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index 171b8f1ab..08b796c6d 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -50,12 +50,6 @@ struct pam_initgroup_enum_str { - const char *option; - }; - --struct pam_passkey_table_data { -- hash_table_t *table; -- char *key; -- struct pk_child_user_data *data; --}; -- - struct pam_initgroup_enum_str pam_initgroup_enum_str[] = { - { PAM_INITGR_NEVER, "never" }, - { PAM_INITGR_NO_SESSION, "no_session" }, -@@ -105,10 +99,6 @@ static errno_t check_cert(TALLOC_CTX *mctx, - struct pam_auth_req *preq, - struct pam_data *pd); - --errno_t passkey_kerberos(struct pam_ctx *pctx, -- struct pam_data *pd, -- struct pam_auth_req *preq); -- - int pam_check_user_done(struct pam_auth_req *preq, int ret); - - static errno_t pack_user_info_msg(TALLOC_CTX *mem_ctx, -@@ -871,228 +861,6 @@ done: - return ret; - } - --errno_t decode_pam_passkey_msg(TALLOC_CTX *mem_ctx, -- uint8_t *buf, -- size_t len, -- struct pk_child_user_data **_data) --{ -- -- size_t p = 0; -- size_t pctr = 0; -- errno_t ret; -- size_t offset; -- struct pk_child_user_data *data = NULL; -- TALLOC_CTX *tmp_ctx; -- -- tmp_ctx = talloc_new(NULL); -- if (tmp_ctx == NULL) { -- return ENOMEM; -- } -- -- data = talloc_zero(tmp_ctx, struct pk_child_user_data); -- if (data == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "Failed to talloc passkey data.\n"); -- ret = ENOMEM; -- goto done; -- } -- -- data->user_verification = talloc_strdup(data, (char *) &buf[p]); -- if (data->user_verification == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey prompt.\n"); -- ret = ENOMEM; -- goto done; -- } -- -- offset = strlen(data->user_verification) + 1; -- if (offset >= len) { -- DEBUG(SSSDBG_OP_FAILURE, "passkey prompt offset failure.\n"); -- ret = EIO; -- goto done; -- } -- -- data->crypto_challenge = talloc_strdup(data, (char *) &buf[p + offset]); -- if (data->crypto_challenge == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey challenge.\n"); -- ret = ENOMEM; -- goto done; -- } -- -- offset += strlen(data->crypto_challenge) + 1; -- if (offset >= len) { -- DEBUG(SSSDBG_OP_FAILURE, "passkey challenge offset failure.\n"); -- ret = EIO; -- goto done; -- } -- -- -- data->domain = talloc_strdup(data, (char *) &buf[p] + offset); -- if (data->domain == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey domain.\n"); -- ret = ENOMEM; -- goto done; -- } -- -- offset += strlen(data->domain) + 1; -- if (offset >= len) { -- DEBUG(SSSDBG_OP_FAILURE, "passkey domain offset failure.\n"); -- ret = EIO; -- goto done; -- } -- -- SAFEALIGN_COPY_UINT32(&data->num_credentials, &buf[p + offset], &pctr); -- size_t list_sz = (size_t) data->num_credentials; -- -- offset += sizeof(uint32_t); -- -- data->key_handles = talloc_zero_array(data, const char *, list_sz); -- -- for (int i = 0; i < list_sz; i++) { -- data->key_handles[i] = talloc_strdup(data->key_handles, (char *) &buf[p + offset]); -- if (data->key_handles[i] == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey list.\n"); -- ret = ENOMEM; -- goto done; -- } -- -- offset += strlen(data->key_handles[i]) + 1; -- } -- -- *_data = talloc_steal(mem_ctx, data); -- -- ret = EOK; --done: -- talloc_free(tmp_ctx); -- return ret; --} -- -- --errno_t save_passkey_data(TALLOC_CTX *mem_ctx, -- struct pam_ctx *pctx, -- struct pk_child_user_data *data, -- struct pam_auth_req *preq) --{ -- char *pk_key; -- errno_t ret; -- TALLOC_CTX *tmp_ctx; -- -- tmp_ctx = talloc_new(NULL); -- if (tmp_ctx == NULL) { -- return ENOMEM; -- } -- -- /* Passkey data (pk_table_data) is stolen onto client ctx, it will -- * be freed when the client closes, and the sss_ptr_hash interface -- * takes care of automatically removing it from the hash table then */ -- pctx->pk_table_data = talloc_zero(tmp_ctx, struct pam_passkey_table_data); -- if (pctx->pk_table_data == NULL) { -- return ENOMEM; -- } -- -- if (pctx->pk_table_data->table == NULL) { -- pctx->pk_table_data->table = sss_ptr_hash_create(pctx->pk_table_data, -- NULL, NULL); -- if (pctx->pk_table_data->table == NULL) { -- ret = ENOMEM; -- goto done; -- } -- } -- -- pk_key = talloc_asprintf(tmp_ctx, "%s", data->crypto_challenge); -- if (pk_key == NULL) { -- ret = ENOMEM; -- goto done; -- } -- -- pctx->pk_table_data->key = talloc_strdup(pctx->pk_table_data, pk_key); -- if (pctx->pk_table_data->key == NULL) { -- ret = ENOMEM; -- goto done; -- } -- -- ret = sss_ptr_hash_add(pctx->pk_table_data->table, pk_key, data, -- struct pk_child_user_data); -- if (ret == EEXIST) { -- DEBUG(SSSDBG_TRACE_FUNC, "pk_table key [%s] already exists\n", -- pk_key); -- goto done; -- } else if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "Unable to add pk data to hash table " -- "[%d]: %s\n", ret, sss_strerror(ret)); -- goto done; -- } -- -- talloc_steal(mem_ctx, pctx->pk_table_data); -- pctx->pk_table_data->data = talloc_steal(mem_ctx, data); -- -- ret = EOK; -- --done: -- talloc_free(tmp_ctx); -- -- return ret; --} -- --errno_t pam_eval_passkey_response(struct pam_ctx *pctx, -- struct pam_data *pd, -- struct pam_auth_req *preq, -- bool *_pk_preauth_done) --{ -- struct response_data *pk_resp; -- struct pk_child_user_data *pk_data; -- errno_t ret; -- TALLOC_CTX *tmp_ctx; -- -- tmp_ctx = talloc_new(NULL); -- if (tmp_ctx == NULL) { -- return ENOMEM; -- } -- -- pk_resp = pd->resp_list; -- -- while (pk_resp != NULL) { -- switch (pk_resp->type) { -- case SSS_PAM_PASSKEY_KRB_INFO: -- if (!pctx->passkey_auth) { -- /* Passkey auth is disabled. To avoid passkey prompts appearing, -- * don't send SSS_PAM_PASSKEY_KRB_INFO to the client and -- * add a dummy response to fallback to normal auth */ -- pk_resp->do_not_send_to_client = true; -- ret = pam_add_response(pd, SSS_OTP, 0, NULL); -- if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); -- goto done; -- } -- break; -- } -- ret = decode_pam_passkey_msg(tmp_ctx, pk_resp->data, pk_resp->len, &pk_data); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "Failed to decode passkey msg\n"); -- ret = EIO; -- goto done; -- } -- -- ret = save_passkey_data(preq->cctx, pctx, pk_data, preq); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "Failed to save passkey msg\n"); -- ret = EIO; -- goto done; -- } -- break; -- /* Passkey non-kerberos preauth has already run */ -- case SSS_PAM_PASSKEY_INFO: -- *_pk_preauth_done = true; -- default: -- break; -- } -- pk_resp = pk_resp->next; -- } -- -- ret = EOK; --done: -- talloc_free(tmp_ctx); -- -- return ret; --} - - void pam_reply(struct pam_auth_req *preq) - { -@@ -1342,6 +1110,7 @@ void pam_reply(struct pam_auth_req *preq) - "using defaults.\n"); - } - -+#ifdef BUILD_PASSKEY - ret = pam_eval_passkey_response(pctx, pd, preq, &pk_preauth_done); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "Failed to eval passkey response\n"); -@@ -1353,6 +1122,7 @@ void pam_reply(struct pam_auth_req *preq) - pam_check_user_done(preq, ret); - return; - } -+#endif /* BUILD_PASSKEY */ - } - - /* -@@ -1810,6 +1580,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd) - * It is checked in pam_reply() to avoid an endless loop */ - preq->passkey_data_exists = true; - -+#ifdef BUILD_PASSKEY - if ((pd->cmd == SSS_PAM_AUTHENTICATE)) { - if (may_do_passkey_auth(pctx, pd)) { - if (sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_PASSKEY_KRB) { -@@ -1822,6 +1593,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd) - } - } - } -+#endif /* BUILD_PASSKEY */ - - ret = pam_check_user_search(preq); - -@@ -2220,6 +1992,7 @@ static void pam_forwarder_cb(struct tevent_req *req) - goto done; - } - -+#ifdef BUILD_PASSKEY - /* This is set to false inside passkey_non_kerberos() if no passkey data is found. - * It is checked in pam_reply() to avoid an endless loop */ - preq->passkey_data_exists = true; -@@ -2236,6 +2009,7 @@ static void pam_forwarder_cb(struct tevent_req *req) - } - } - } -+#endif /* BUILD_PASSKEY */ - - ret = pam_check_user_search(preq); - -@@ -2557,127 +2331,6 @@ static bool pam_can_user_cache_auth(struct sss_domain_info *domain, - return result; - } - --void passkey_kerberos_cb(struct tevent_req *req) --{ -- struct pam_auth_req *preq = tevent_req_callback_data(req, -- struct pam_auth_req); -- errno_t ret = EOK; -- int child_status; -- -- ret = pam_passkey_auth_recv(req, &child_status); -- talloc_free(req); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "PAM passkey auth failed [%d]: %s\n", -- ret, sss_strerror(ret)); -- goto done; -- } -- -- DEBUG(SSSDBG_TRACE_FUNC, "passkey child finished with status [%d]\n", child_status); -- -- pam_check_user_search(preq); -- --done: -- pam_check_user_done(preq, ret); --} -- --errno_t passkey_kerberos(struct pam_ctx *pctx, -- struct pam_data *pd, -- struct pam_auth_req *preq) --{ -- errno_t ret; -- const char *prompt; -- const char *key; -- const char *pin; -- size_t pin_len; -- struct pk_child_user_data *data; -- struct tevent_req *req; -- int timeout; -- char *verify_opts; -- bool debug_libfido2; -- enum passkey_user_verification verification; -- -- ret = sss_authtok_get_passkey(preq, preq->pd->authtok, -- &prompt, &key, &pin, &pin_len); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Failure to get passkey authtok\n"); -- return EIO; -- } -- -- if (prompt == NULL || key == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Passkey prompt and key are missing or invalid.\n"); -- return EIO; -- } -- -- data = sss_ptr_hash_lookup(pctx->pk_table_data->table, key, -- struct pk_child_user_data); -- if (data == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Failed to lookup passkey authtok\n"); -- return EIO; -- } -- -- ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, -- CONFDB_PAM_PASSKEY_CHILD_TIMEOUT, PASSKEY_CHILD_TIMEOUT_DEFAULT, -- &timeout); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Failed to read passkey_child_timeout from confdb: [%d]: %s\n", -- ret, sss_strerror(ret)); -- goto done; -- } -- -- ret = confdb_get_string(pctx->rctx->cdb, preq, CONFDB_MONITOR_CONF_ENTRY, -- CONFDB_MONITOR_PASSKEY_VERIFICATION, NULL, -- &verify_opts); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Failed to read '"CONFDB_MONITOR_PASSKEY_VERIFICATION"' from confdb: [%d]: %s\n", -- ret, sss_strerror(ret)); -- goto done; -- } -- -- /* Always use verification sent from passkey krb5 plugin */ -- ret = read_passkey_conf_verification(preq, verify_opts, NULL); -- if (ret != EOK) { -- DEBUG(SSSDBG_MINOR_FAILURE, "Unable to parse passkey verificaton options.\n"); -- } -- -- if (strcasecmp(data->user_verification, "false") == 0) { -- verification = PAM_PASSKEY_VERIFICATION_OFF; -- } else { -- verification = PAM_PASSKEY_VERIFICATION_ON; -- } -- -- ret = confdb_get_bool(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, -- CONFDB_PAM_PASSKEY_DEBUG_LIBFIDO2, false, -- &debug_libfido2); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Failed to read '"CONFDB_PAM_PASSKEY_DEBUG_LIBFIDO2"' from confdb: [%d]: %s\n", -- ret, sss_strerror(ret)); -- goto done; -- } -- -- req = pam_passkey_auth_send(preq->cctx, preq->cctx->ev, timeout, debug_libfido2, -- verification, pd, data, true); -- if (req == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "passkey auth send failed [%d]: [%s]\n", -- ret, sss_strerror(ret)); -- goto done; -- } -- -- tevent_req_set_callback(req, passkey_kerberos_cb, preq); -- -- ret = EAGAIN; -- --done: -- -- return ret; -- --} -- - static void pam_dom_forwarder(struct pam_auth_req *preq) - { - int ret; -diff --git a/src/responder/pam/pamsrv_passkey.c b/src/responder/pam/pamsrv_passkey.c -index d884a7670..50386ea9a 100644 ---- a/src/responder/pam/pamsrv_passkey.c -+++ b/src/responder/pam/pamsrv_passkey.c -@@ -32,6 +32,12 @@ struct pam_passkey_verification_enum_str { - const char *option; - }; - -+struct pam_passkey_table_data { -+ hash_table_t *table; -+ char *key; -+ struct pk_child_user_data *data; -+}; -+ - struct pam_passkey_verification_enum_str pam_passkey_verification_enum_str[] = { - { PAM_PASSKEY_VERIFICATION_ON, "on" }, - { PAM_PASSKEY_VERIFICATION_OFF, "off" }, -@@ -85,6 +91,127 @@ struct passkey_get_mapping_state { - struct cache_req_result *result; - }; - -+void passkey_kerberos_cb(struct tevent_req *req) -+{ -+ struct pam_auth_req *preq = tevent_req_callback_data(req, -+ struct pam_auth_req); -+ errno_t ret = EOK; -+ int child_status; -+ -+ ret = pam_passkey_auth_recv(req, &child_status); -+ talloc_free(req); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "PAM passkey auth failed [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ goto done; -+ } -+ -+ DEBUG(SSSDBG_TRACE_FUNC, "passkey child finished with status [%d]\n", child_status); -+ -+ pam_check_user_search(preq); -+ -+done: -+ pam_check_user_done(preq, ret); -+} -+ -+errno_t passkey_kerberos(struct pam_ctx *pctx, -+ struct pam_data *pd, -+ struct pam_auth_req *preq) -+{ -+ errno_t ret; -+ const char *prompt; -+ const char *key; -+ const char *pin; -+ size_t pin_len; -+ struct pk_child_user_data *data; -+ struct tevent_req *req; -+ int timeout; -+ char *verify_opts; -+ bool debug_libfido2; -+ enum passkey_user_verification verification; -+ -+ ret = sss_authtok_get_passkey(preq, preq->pd->authtok, -+ &prompt, &key, &pin, &pin_len); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Failure to get passkey authtok\n"); -+ return EIO; -+ } -+ -+ if (prompt == NULL || key == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Passkey prompt and key are missing or invalid.\n"); -+ return EIO; -+ } -+ -+ data = sss_ptr_hash_lookup(pctx->pk_table_data->table, key, -+ struct pk_child_user_data); -+ if (data == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Failed to lookup passkey authtok\n"); -+ return EIO; -+ } -+ -+ ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, -+ CONFDB_PAM_PASSKEY_CHILD_TIMEOUT, PASSKEY_CHILD_TIMEOUT_DEFAULT, -+ &timeout); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Failed to read passkey_child_timeout from confdb: [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ goto done; -+ } -+ -+ ret = confdb_get_string(pctx->rctx->cdb, preq, CONFDB_MONITOR_CONF_ENTRY, -+ CONFDB_MONITOR_PASSKEY_VERIFICATION, NULL, -+ &verify_opts); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Failed to read '"CONFDB_MONITOR_PASSKEY_VERIFICATION"' from confdb: [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ goto done; -+ } -+ -+ /* Always use verification sent from passkey krb5 plugin */ -+ ret = read_passkey_conf_verification(preq, verify_opts, NULL); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to parse passkey verificaton options.\n"); -+ } -+ -+ if (strcasecmp(data->user_verification, "false") == 0) { -+ verification = PAM_PASSKEY_VERIFICATION_OFF; -+ } else { -+ verification = PAM_PASSKEY_VERIFICATION_ON; -+ } -+ -+ ret = confdb_get_bool(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, -+ CONFDB_PAM_PASSKEY_DEBUG_LIBFIDO2, false, -+ &debug_libfido2); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Failed to read '"CONFDB_PAM_PASSKEY_DEBUG_LIBFIDO2"' from confdb: [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ goto done; -+ } -+ -+ req = pam_passkey_auth_send(preq->cctx, preq->cctx->ev, timeout, debug_libfido2, -+ verification, pd, data, true); -+ if (req == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "passkey auth send failed [%d]: [%s]\n", -+ ret, sss_strerror(ret)); -+ goto done; -+ } -+ -+ tevent_req_set_callback(req, passkey_kerberos_cb, preq); -+ -+ ret = EAGAIN; -+ -+done: -+ -+ return ret; -+ -+} -+ - errno_t passkey_non_kerberos(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct pam_ctx *pam_ctx, -@@ -994,6 +1121,229 @@ errno_t pam_passkey_auth_recv(struct tevent_req *req, - return EOK; - } - -+errno_t decode_pam_passkey_msg(TALLOC_CTX *mem_ctx, -+ uint8_t *buf, -+ size_t len, -+ struct pk_child_user_data **_data) -+{ -+ -+ size_t p = 0; -+ size_t pctr = 0; -+ errno_t ret; -+ size_t offset; -+ struct pk_child_user_data *data = NULL; -+ TALLOC_CTX *tmp_ctx; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ return ENOMEM; -+ } -+ -+ data = talloc_zero(tmp_ctx, struct pk_child_user_data); -+ if (data == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to talloc passkey data.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ data->user_verification = talloc_strdup(data, (char *) &buf[p]); -+ if (data->user_verification == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey prompt.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ offset = strlen(data->user_verification) + 1; -+ if (offset >= len) { -+ DEBUG(SSSDBG_OP_FAILURE, "passkey prompt offset failure.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ data->crypto_challenge = talloc_strdup(data, (char *) &buf[p + offset]); -+ if (data->crypto_challenge == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey challenge.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ offset += strlen(data->crypto_challenge) + 1; -+ if (offset >= len) { -+ DEBUG(SSSDBG_OP_FAILURE, "passkey challenge offset failure.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ -+ data->domain = talloc_strdup(data, (char *) &buf[p] + offset); -+ if (data->domain == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey domain.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ offset += strlen(data->domain) + 1; -+ if (offset >= len) { -+ DEBUG(SSSDBG_OP_FAILURE, "passkey domain offset failure.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ SAFEALIGN_COPY_UINT32(&data->num_credentials, &buf[p + offset], &pctr); -+ size_t list_sz = (size_t) data->num_credentials; -+ -+ offset += sizeof(uint32_t); -+ -+ data->key_handles = talloc_zero_array(data, const char *, list_sz); -+ -+ for (int i = 0; i < list_sz; i++) { -+ data->key_handles[i] = talloc_strdup(data->key_handles, (char *) &buf[p + offset]); -+ if (data->key_handles[i] == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey list.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ offset += strlen(data->key_handles[i]) + 1; -+ } -+ -+ *_data = talloc_steal(mem_ctx, data); -+ -+ ret = EOK; -+done: -+ talloc_free(tmp_ctx); -+ return ret; -+} -+ -+ -+errno_t save_passkey_data(TALLOC_CTX *mem_ctx, -+ struct pam_ctx *pctx, -+ struct pk_child_user_data *data, -+ struct pam_auth_req *preq) -+{ -+ char *pk_key; -+ errno_t ret; -+ TALLOC_CTX *tmp_ctx; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ return ENOMEM; -+ } -+ -+ /* Passkey data (pk_table_data) is stolen onto client ctx, it will -+ * be freed when the client closes, and the sss_ptr_hash interface -+ * takes care of automatically removing it from the hash table then */ -+ pctx->pk_table_data = talloc_zero(tmp_ctx, struct pam_passkey_table_data); -+ if (pctx->pk_table_data == NULL) { -+ return ENOMEM; -+ } -+ -+ if (pctx->pk_table_data->table == NULL) { -+ pctx->pk_table_data->table = sss_ptr_hash_create(pctx->pk_table_data, -+ NULL, NULL); -+ if (pctx->pk_table_data->table == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ } -+ -+ pk_key = talloc_asprintf(tmp_ctx, "%s", data->crypto_challenge); -+ if (pk_key == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ pctx->pk_table_data->key = talloc_strdup(pctx->pk_table_data, pk_key); -+ if (pctx->pk_table_data->key == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = sss_ptr_hash_add(pctx->pk_table_data->table, pk_key, data, -+ struct pk_child_user_data); -+ if (ret == EEXIST) { -+ DEBUG(SSSDBG_TRACE_FUNC, "pk_table key [%s] already exists\n", -+ pk_key); -+ goto done; -+ } else if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Unable to add pk data to hash table " -+ "[%d]: %s\n", ret, sss_strerror(ret)); -+ goto done; -+ } -+ -+ talloc_steal(mem_ctx, pctx->pk_table_data); -+ pctx->pk_table_data->data = talloc_steal(mem_ctx, data); -+ -+ ret = EOK; -+ -+done: -+ talloc_free(tmp_ctx); -+ -+ return ret; -+} -+ -+errno_t pam_eval_passkey_response(struct pam_ctx *pctx, -+ struct pam_data *pd, -+ struct pam_auth_req *preq, -+ bool *_pk_preauth_done) -+{ -+ struct response_data *pk_resp; -+ struct pk_child_user_data *pk_data; -+ errno_t ret; -+ TALLOC_CTX *tmp_ctx; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ return ENOMEM; -+ } -+ -+ pk_resp = pd->resp_list; -+ -+ while (pk_resp != NULL) { -+ switch (pk_resp->type) { -+ case SSS_PAM_PASSKEY_KRB_INFO: -+ if (!pctx->passkey_auth) { -+ /* Passkey auth is disabled. To avoid passkey prompts appearing, -+ * don't send SSS_PAM_PASSKEY_KRB_INFO to the client and -+ * add a dummy response to fallback to normal auth */ -+ pk_resp->do_not_send_to_client = true; -+ ret = pam_add_response(pd, SSS_OTP, 0, NULL); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); -+ goto done; -+ } -+ break; -+ } -+ ret = decode_pam_passkey_msg(tmp_ctx, pk_resp->data, pk_resp->len, &pk_data); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to decode passkey msg\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ ret = save_passkey_data(preq->cctx, pctx, pk_data, preq); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to save passkey msg\n"); -+ ret = EIO; -+ goto done; -+ } -+ break; -+ /* Passkey non-kerberos preauth has already run */ -+ case SSS_PAM_PASSKEY_INFO: -+ *_pk_preauth_done = true; -+ default: -+ break; -+ } -+ pk_resp = pk_resp->next; -+ } -+ -+ ret = EOK; -+done: -+ talloc_free(tmp_ctx); -+ -+ return ret; -+} -+ - static void - pam_passkey_auth_done(int child_status, - struct tevent_signal *sige, -diff --git a/src/responder/pam/pamsrv_passkey.h b/src/responder/pam/pamsrv_passkey.h -index e799d951f..91fa7cfe1 100644 ---- a/src/responder/pam/pamsrv_passkey.h -+++ b/src/responder/pam/pamsrv_passkey.h -@@ -23,6 +23,7 @@ - - #include - #include "util/util.h" -+#include "util/sss_ptr_hash.h" - #include "responder/common/responder.h" - #include "responder/common/cache_req/cache_req.h" - #include "responder/pam/pamsrv.h" -@@ -40,6 +41,9 @@ errno_t passkey_non_kerberos(TALLOC_CTX *mem_ctx, - struct pam_ctx *pam_ctx, - struct pam_auth_req *preq, - struct pam_data *pd); -+errno_t passkey_kerberos(struct pam_ctx *pctx, -+ struct pam_data *pd, -+ struct pam_auth_req *preq); - - struct pk_child_user_data { - /* Both Kerberos and non-kerberos */ -@@ -69,6 +73,10 @@ struct tevent_req *pam_passkey_auth_send(TALLOC_CTX *mem_ctx, - bool kerberos_pa); - errno_t pam_passkey_auth_recv(struct tevent_req *req, - int *child_status); -+errno_t pam_eval_passkey_response(struct pam_ctx *pctx, -+ struct pam_data *pd, -+ struct pam_auth_req *preq, -+ bool *_pk_preauth_done); - bool may_do_passkey_auth(struct pam_ctx *pctx, - struct pam_data *pd); - --- -2.41.0 - diff --git a/SOURCES/0018-Makefile-Respect-BUILD_PASSKEY-conditional.patch b/SOURCES/0018-Makefile-Respect-BUILD_PASSKEY-conditional.patch deleted file mode 100644 index 24018b2..0000000 --- a/SOURCES/0018-Makefile-Respect-BUILD_PASSKEY-conditional.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 11ed21e8e22188cbfb12fc3cd5e561fc78b3d5ad Mon Sep 17 00:00:00 2001 -From: Justin Stephenson -Date: Wed, 10 Jan 2024 09:45:22 -0500 -Subject: [PATCH 18/18] Makefile: Respect BUILD_PASSKEY conditional - ---- - Makefile.am | 10 ++++++++-- - src/providers/krb5/krb5_child.c | 5 +++++ - 2 files changed, 13 insertions(+), 2 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index c58e336eb..1ff88dfce 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1315,7 +1315,9 @@ endif - if BUILD_SYSTEMTAP - libsss_util_la_LIBADD += stap_generated_probes.lo - endif -+if BUILD_PASSKEY - libsss_util_la_SOURCES += src/db/sysdb_passkey_user_verification.c -+endif # BUILD_PASSKEY - libsss_util_la_LDFLAGS = -avoid-version - - pkglib_LTLIBRARIES += libsss_semanage.la -@@ -2616,7 +2618,6 @@ pam_srv_tests_SOURCES = \ - src/responder/pam/pamsrv_cmd.c \ - src/responder/pam/pamsrv_p11.c \ - src/responder/pam/pamsrv_gssapi.c \ -- src/responder/pam/pamsrv_passkey.c \ - src/responder/pam/pam_helpers.c \ - src/responder/pam/pamsrv_dp.c \ - src/responder/pam/pam_prompting_config.c \ -@@ -2650,6 +2651,9 @@ pam_srv_tests_LDADD = \ - libsss_iface.la \ - libsss_sbus.la \ - $(NULL) -+if BUILD_PASSKEY -+ pam_srv_tests_SOURCES += src/responder/pam/pamsrv_passkey.c -+endif # BUILD_PASSKEY - - EXTRA_ssh_srv_tests_DEPENDENCIES = \ - $(ldblib_LTLIBRARIES) \ -@@ -4656,8 +4660,10 @@ krb5_child_SOURCES = \ - src/sss_client/common.c \ - src/krb5_plugin/common/utils.c \ - src/krb5_plugin/idp/idp_utils.c \ -- src/krb5_plugin/passkey/passkey_utils.c \ - $(NULL) -+if BUILD_PASSKEY -+ krb5_child_SOURCES += src/krb5_plugin/passkey/passkey_utils.c -+endif # BUILD_PASSKEY - krb5_child_CFLAGS = \ - $(AM_CFLAGS) \ - $(POPT_CFLAGS) \ -diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c -index ae2c23aa9..5f868fc57 100644 ---- a/src/providers/krb5/krb5_child.c -+++ b/src/providers/krb5/krb5_child.c -@@ -999,6 +999,10 @@ static krb5_error_code answer_passkey(krb5_context kctx, - struct krb5_req *kr, - krb5_responder_context rctx) - { -+#ifndef BUILD_PASSKEY -+ DEBUG(SSSDBG_TRACE_FUNC, "Passkey auth not possible, SSSD built without passkey support!\n"); -+ return EINVAL; -+#else - enum sss_authtok_type type; - struct sss_passkey_message *msg; - struct sss_passkey_message *reply_msg = NULL; -@@ -1090,6 +1094,7 @@ done: - } - - return kerr; -+#endif /* BUILD_PASSKEY */ - } - - static krb5_error_code sss_krb5_responder(krb5_context ctx, --- -2.41.0 - diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec index 010b8cd..bc684b2 100644 --- a/SPECS/sssd.spec +++ b/SPECS/sssd.spec @@ -26,32 +26,29 @@ %global samba_package_version %(rpm -q samba-devel --queryformat %{version}-%{release}) Name: sssd -Version: 2.9.1 -Release: 4%{?dist}.5 +Version: 2.9.4 +Release: 6%{?dist} 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-watchdog-add-arm_watchdog-and-disarm_watchdog-calls.patch -Patch0002: 0002-sbus-arm-watchdog-for-sbus_connect_init_send.patch -Patch0003: 0003-mc-recover-from-invalid-memory-cache-size.patch -Patch0004: 0004-sss_iface-do-not-add-cli_id-to-chain-key.patch -Patch0005: 0005-BUILD-Accept-krb5-1.21-for-building-the-PAC-plugin.patch -Patch0006: 0006-MC-a-couple-of-additions-to-recover-from-invalid-mem.patch -Patch0007: 0007-SSS_CLIENT-replace-__thread-with-pthread_-specific.patch -Patch0008: 0008-DP-reduce-log-level-in-case-a-responder-asks-for-unk.patch -Patch0009: 0009-SSS_CLIENT-MC-in-case-mem-cache-file-validation-fail.patch -Patch0010: 0010-SSS_CLIENT-check-if-mem-cache-fd-was-hijacked.patch -Patch0011: 0011-SSS_CLIENT-check-if-reponder-socket-was-hijacked.patch -Patch0012: 0012-LDAP-make-groups_by_user_send-recv-public.patch -Patch0013: 0013-ad-gpo-evalute-host-groups.patch -Patch0014: 0014-sysdb-remove-sysdb_computer.-ch.patch -Patch0015: 0015-sdap-add-set_non_posix-parameter.patch -Patch0016: 0016-ipa-Add-BUILD_PASSKEY-conditional-for-passkey-codepa.patch -Patch0017: 0017-pam-Conditionalize-passkey-code.patch -Patch0018: 0018-Makefile-Respect-BUILD_PASSKEY-conditional.patch +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 ### Dependencies ### @@ -101,6 +98,7 @@ BuildRequires: krb5-devel BuildRequires: krb5-libs >= 1.18.2-11 BuildRequires: libcmocka-devel >= 1.0.0 BuildRequires: libdhash-devel >= 0.4.2 +BuildRequires: libfido2-devel BuildRequires: libini_config-devel >= 1.1 BuildRequires: libldb-devel >= %{ldb_version} BuildRequires: libnfsidmap-devel @@ -341,6 +339,7 @@ identity data from and authenticate against an Active Directory server. Summary: The proxy back end of the SSSD License: GPLv3+ Requires: sssd-common = %{version}-%{release} +Requires: libsss_certmap = %{version}-%{release} %description proxy Provides the proxy back end which can be used to wrap an existing NSS and/or @@ -509,6 +508,16 @@ This package provides Kerberos plugins that are required to enable authentication against external identity providers. Additionally a helper program to handle the OAuth 2.0 Device Authorization Grant is provided. +%package passkey +Summary: SSSD helpers and plugins needed for authentication with passkey token +License: GPLv3+ +Requires: sssd-common = %{version}-%{release} +Requires: libfido2 + +%description passkey +This package provides helper processes and Kerberos plugins that are required to +enable authentication with passkey token. + %prep %autosetup -p1 @@ -540,6 +549,7 @@ autoreconf -ivf --with-subid \ --with-files-provider \ --with-libsifp \ + --with-passkey \ %if 0%{?fedora} --disable-polkit-rules-path \ %endif @@ -584,6 +594,10 @@ cp $RPM_BUILD_ROOT/%{_datadir}/sssd-kcm/kcm_default_ccache \ cp $RPM_BUILD_ROOT/%{_datadir}/sssd/krb5-snippets/sssd_enable_idp \ $RPM_BUILD_ROOT/%{_sysconfdir}/krb5.conf.d/sssd_enable_idp +# Enable krb5 passkey plugins by default (when sssd-passkey package is installed) +cp $RPM_BUILD_ROOT/%{_datadir}/sssd/krb5-snippets/sssd_enable_passkey \ + $RPM_BUILD_ROOT/%{_sysconfdir}/krb5.conf.d/sssd_enable_passkey + # krb5 configuration snippet cp $RPM_BUILD_ROOT/%{_datadir}/sssd/krb5-snippets/enable_sssd_conf_dir \ $RPM_BUILD_ROOT/%{_sysconfdir}/krb5.conf.d/enable_sssd_conf_dir @@ -989,6 +1003,12 @@ done %{_datadir}/sssd/krb5-snippets/sssd_enable_idp %config(noreplace) %{_sysconfdir}/krb5.conf.d/sssd_enable_idp +%files passkey +%attr(755,%{sssd_user},%{sssd_user}) %{_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 + %if 0%{?rhel} %pre common getent group sssd >/dev/null || groupadd -r sssd @@ -1078,27 +1098,52 @@ fi %systemd_postun_with_restart sssd.service %changelog -* Wed Jan 10 2024 Alexey Tikhonov - 2.9.1-4.5 -- Resolves: RHEL-21165 - Make sure 8.9.z/9.3.z doesn't build 'passkey' code [rhel-9.3.0.z] - -* Tue Jan 9 2024 Alexey Tikhonov - 2.9.1-4.3 -- Resolves: RHEL-21089 - SSSD GPO lacks group resolution on hosts [rhel-9.3.0.z] - -* Tue Jan 2 2024 Alexey Tikhonov - 2.9.1-4.2 -- Resolves: RHEL-19213 - Excessive logging to sssd_nss and sssd_be in multi-domain AD forest [rhel-9.3.0.z] -- Resolves: RHEL-19993 - latest sssd breaks logging in via XDMCP for LDAP/Kerberos users [rhel-9.3.0.z] - -* Sat Nov 11 2023 Alexey Tikhonov - 2.9.1-4.1 -- Resolves: RHEL-15431 - HANA validation on RHEL 9.2 issue possibly related to libc/nss_sss behaviour [rhel-9.3.0.z] - -* Mon Oct 02 2023 Eduardo Lima (Etrunko) - 2.9.1-4 -- Related: rhbz#2236236 - dbus and crond getting terminated with SIGBUS in sss_client code - Handle all invalidations consistently - Supply a valid pointer to `sss_mmap_cache_validate_or_reinit()`, not a pointer to a local var +* 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] + +* Mon Mar 25 2024 Alexey Tikhonov - 2.9.4-5 +- Resolves: RHEL-28161 - Passkey cannot fall back to password + +* Thu Mar 21 2024 Alexey Tikhonov - 2.9.4-4 +- Resolves: RHEL-28161 - Passkey cannot fall back to password + +* Wed Mar 13 2024 Alexey Tikhonov - 2.9.4-3 +- Resolves: RHEL-22340 - socket leak +- Resolves: RHEL-28161 - Passkey cannot fall back to password + +* Mon Feb 12 2024 Alexey Tikhonov - 2.9.4-2 +- Resolves: RHEL-12503 - AD users are unable to log in due to case sensitivity of user because the domain is found as an alias to the email address. +- Resolves: RHEL-22288 - ssh pubkey stored in ldap/AD no longer works to authenticate via sssd +- Resolves: RHEL-22194 - gdm smartcard login fails with sssd-2.9.3 in case of multiple identities + +* Fri Jan 12 2024 Alexey Tikhonov - 2.9.4-1 +- Resolves: RHEL-2632 - Rebase SSSD for RHEL 9.4 +- Resolves: RHEL-18395 - latest sssd breaks logging in via XDMCP for LDAP/Kerberos users +- Resolves: RHEL-17498 - New sssd.conf seems not to be backwards compatible (wrt SmartCard auth of local users using 'files provider') [rhel-9] +- Resolves: RHEL-21079 - SSSD GPO lacks group resolution on hosts [rhel-9] +- Resolves: RHEL-19211 - Excessive logging to sssd_nss and sssd_be in multi-domain AD forest [rhel-9] + +* Mon Nov 13 2023 Alexey Tikhonov - 2.9.3-2 +- Resolves: RHEL-2632 - Rebase SSSD for RHEL 9.4 + +* Mon Nov 13 2023 Alexey Tikhonov - 2.9.3-1 +- Resolves: RHEL-2632 - Rebase SSSD for RHEL 9.4 +- Resolves: RHEL-14427 - Expected cn in RDN, got uid +- Resolves: RHEL-12229 - HANA validation on RHEL 9.2 issue possibly related to libc/nss_sss behaviour +- Resolves: RHEL-3925 - SSSD goes offline when, while reading a single user, misses a required attribute (i.e. SID) +- Resolves: RHEL-2319 - Passkey authentication for centrally managed users +- Resolves: RHEL-4146 - Incorrect handling of reverse IPv6 update results in update failure +- Resolves: RHEL-4971 - sssd-kcm does not appear to expire Kerberos tickets (RFE: sssd_kcm should have the option to automatically delete the expired tickets) + +* Thu Oct 5 2023 Alexey Tikhonov - 2.9.2-2 +- Resolves: RHEL-2319 - Passkey authentication for centrally managed users + +* Fri Sep 8 2023 Alexey Tikhonov - 2.9.2-1 +- Resolves: RHEL-2632 - Rebase SSSD for RHEL 9.4 +- Resolves: RHEL-2319 - Passkey authentication for centrally managed users +- Resolves: rhbz#2234829 - SSSD runs multiples lookup search for each NFS request (SBUS req chaining stopped working) +- Resolves: rhbz#2236119 - dbus and crond getting terminated with SIGBUS in sss_client code -* Tue Sep 12 2023 Eduardo Lima (Etrunko) - 2.9.1-3 -- Resolves: rhbz#2236236 - dbus and crond getting terminated with SIGBUS in sss_client code -- Resolves: rhbz#2237301 - SSSD runs multiples lookup search for each NFS request (SBUS req chaining stopped working in sssd-2.7) * Mon Jul 10 2023 Alexey Tikhonov - 2.9.1-2 - Resolves: rhbz#2218858 - [sssd] SSSD enters failed state after heavy load in the system