diff --git a/0014-ad-gpo-use-hash-to-store-intermediate-results.patch b/0014-ad-gpo-use-hash-to-store-intermediate-results.patch new file mode 100644 index 0000000..5bb0332 --- /dev/null +++ b/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/0015-tests-Drop-extensions-from-openssl-command-if-there-.patch b/0015-tests-Drop-extensions-from-openssl-command-if-there-.patch new file mode 100644 index 0000000..e7ddccc --- /dev/null +++ b/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/sssd.spec b/sssd.spec index 3952e17..bc684b2 100644 --- a/sssd.spec +++ b/sssd.spec @@ -27,7 +27,7 @@ Name: sssd Version: 2.9.4 -Release: 5%{?dist} +Release: 6%{?dist} Summary: System Security Services Daemon License: GPLv3+ URL: https://github.com/SSSD/sssd/ @@ -47,6 +47,8 @@ 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 ### @@ -1096,6 +1098,9 @@ fi %systemd_postun_with_restart sssd.service %changelog +* 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