From 5e7617d4efadd5d99362ae8996d6e46b04a67207 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 06 2018 18:38:45 +0000 Subject: import sssd-1.15.2-50.el7_4.11 --- diff --git a/SOURCES/0200-cache_req-Correction-of-cache_req-debug-string-ID-fo.patch b/SOURCES/0200-cache_req-Correction-of-cache_req-debug-string-ID-fo.patch new file mode 100644 index 0000000..fd77137 --- /dev/null +++ b/SOURCES/0200-cache_req-Correction-of-cache_req-debug-string-ID-fo.patch @@ -0,0 +1,68 @@ +From 9c22ba8f68b48aff49bcdc8af67964a8852e998c Mon Sep 17 00:00:00 2001 +From: amitkuma +Date: Tue, 14 Nov 2017 13:59:12 +0530 +Subject: [PATCH 200/201] cache_req: Correction of cache_req debug string ID + format +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The cache-req debug string representation uses a wrong format +specifier for by-ID requests. +data->id (uint32_t) should be replaced with %"PRIu32" +in cache_req_group_by_id.c, cache_req_object_by_id.c & +cache_req_user_by_id.c. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3570 + +Reviewed-by: Lukáš Slebodník +(cherry picked from commit d25646c64a7117a6551468256efa82d01647751e) +--- + src/responder/common/cache_req/plugins/cache_req_group_by_id.c | 2 +- + src/responder/common/cache_req/plugins/cache_req_object_by_id.c | 2 +- + src/responder/common/cache_req/plugins/cache_req_user_by_id.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c +index 5ca64283a781318bc4e4d6920fff989c3f3919b4..121f95abe86d2466aaea69f0fe68dfb33b1fee9e 100644 +--- a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c ++++ b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c +@@ -31,7 +31,7 @@ cache_req_group_by_id_create_debug_name(TALLOC_CTX *mem_ctx, + struct cache_req_data *data, + struct sss_domain_info *domain) + { +- return talloc_asprintf(mem_ctx, "GID:%d@%s", data->id, domain->name); ++ return talloc_asprintf(mem_ctx, "GID:%"PRIu32"@%s", data->id, domain->name); + } + + static errno_t +diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c +index 339bd4f5fef827acc1aa3c123d041e426d9e4782..4c88e1035b41969703c1c38d740e15516ac0d622 100644 +--- a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c ++++ b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c +@@ -31,7 +31,7 @@ cache_req_object_by_id_create_debug_name(TALLOC_CTX *mem_ctx, + struct cache_req_data *data, + struct sss_domain_info *domain) + { +- return talloc_asprintf(mem_ctx, "ID:%d@%s", data->id, domain->name); ++ return talloc_asprintf(mem_ctx, "ID:%"PRIu32"@%s", data->id, domain->name); + } + + static errno_t +diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c +index 913f9be5bcc2dfd074b52cb3b15fb6948826e831..3c25c7631b3da4a829ab577629334a7ee97980da 100644 +--- a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c ++++ b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c +@@ -31,7 +31,7 @@ cache_req_user_by_id_create_debug_name(TALLOC_CTX *mem_ctx, + struct cache_req_data *data, + struct sss_domain_info *domain) + { +- return talloc_asprintf(mem_ctx, "UID:%d@%s", data->id, domain->name); ++ return talloc_asprintf(mem_ctx, "UID:%"PRIu32"@%s", data->id, domain->name); + } + + static errno_t +-- +2.14.3 + diff --git a/SOURCES/0201-cache-Check-for-max_id-min_id-in-cache_req.patch b/SOURCES/0201-cache-Check-for-max_id-min_id-in-cache_req.patch new file mode 100644 index 0000000..1186293 --- /dev/null +++ b/SOURCES/0201-cache-Check-for-max_id-min_id-in-cache_req.patch @@ -0,0 +1,318 @@ +From 7618d442a25a16940f0842d2ad4ae34e60079844 Mon Sep 17 00:00:00 2001 +From: amitkuma +Date: Thu, 30 Nov 2017 22:18:39 +0530 +Subject: [PATCH 201/201] cache: Check for max_id/min_id in cache_req +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The cache_req code doesn't check the min_id/max_id +boundaries for requests by ID. +Extending the .lookup_fn function in each plugin +that searches by ID for a check that returns non-zero +if the entry is out of the range and 0 if not. + +Resolves: https://pagure.io/SSSD/sssd/issue/3569 + +Reviewed-by: Jakub Hrozek +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit 2af80640f18966d65cf82106059ce3c060df93bf) +--- + src/responder/common/cache_req/cache_req.c | 1 + + src/responder/common/cache_req/cache_req_private.h | 2 + + src/responder/common/cache_req/cache_req_search.c | 5 ++ + .../common/cache_req/plugins/cache_req_common.c | 11 +++ + .../cache_req/plugins/cache_req_group_by_id.c | 6 ++ + .../cache_req/plugins/cache_req_object_by_id.c | 6 ++ + .../cache_req/plugins/cache_req_user_by_id.c | 5 ++ + src/tests/cmocka/test_responder_cache_req.c | 81 +++++++++++++++++++++- + src/util/util_errors.c | 1 + + src/util/util_errors.h | 1 + + 10 files changed, 117 insertions(+), 2 deletions(-) + +diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c +index 83eab8ed2de0b5c7d25306d853aadc9b53cb4842..3ebf64af24bb9a2a67165dd17d27fd25fc7915c2 100644 +--- a/src/responder/common/cache_req/cache_req.c ++++ b/src/responder/common/cache_req/cache_req.c +@@ -574,6 +574,7 @@ static void cache_req_search_domains_done(struct tevent_req *subreq) + } + + break; ++ case ERR_ID_OUTSIDE_RANGE: + case ENOENT: + if (state->check_next == false) { + /* Not found. */ +diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h +index c0ee5f969f2a171b8a6eb396b3d14b593d157b76..5b79d9429bc29c47c28e0b5a6367a6e7035ca1c3 100644 +--- a/src/responder/common/cache_req/cache_req_private.h ++++ b/src/responder/common/cache_req/cache_req_private.h +@@ -165,4 +165,6 @@ bool + cache_req_common_dp_recv(struct tevent_req *subreq, + struct cache_req *cr); + ++errno_t cache_req_idminmax_check(struct cache_req_data *data, ++ struct sss_domain_info *domain); + #endif /* _CACHE_REQ_PRIVATE_H_ */ +diff --git a/src/responder/common/cache_req/cache_req_search.c b/src/responder/common/cache_req/cache_req_search.c +index 56d0345cd8f98de574961d3c9628ae7a4c24f9be..ba25dcf578ef80aa8597bccb41da839d7bd146b3 100644 +--- a/src/responder/common/cache_req/cache_req_search.c ++++ b/src/responder/common/cache_req/cache_req_search.c +@@ -197,6 +197,11 @@ static errno_t cache_req_search_cache(TALLOC_CTX *mem_ctx, + + *_result = result; + break; ++ case ERR_ID_OUTSIDE_RANGE: ++ CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, ++ "ID [%s] was filtered out\n", ++ cr->debugobj); ++ break; + case ENOENT: + CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, + "Object [%s] was not found in cache\n", +diff --git a/src/responder/common/cache_req/plugins/cache_req_common.c b/src/responder/common/cache_req/plugins/cache_req_common.c +index b80f310feeebbdbc824db441ff5313632585d3fb..d7c6ab2eac412042f90d491eb8428116156f512b 100644 +--- a/src/responder/common/cache_req/plugins/cache_req_common.c ++++ b/src/responder/common/cache_req/plugins/cache_req_common.c +@@ -26,6 +26,17 @@ + #include "providers/data_provider.h" + #include "responder/common/cache_req/cache_req_plugin.h" + ++errno_t cache_req_idminmax_check(struct cache_req_data *data, ++ struct sss_domain_info *domain) ++{ ++ if (((domain->id_min != 0) && (data->id < domain->id_min)) || ++ ((domain->id_max != 0) && (data->id > domain->id_max))) { ++ DEBUG(SSSDBG_FUNC_DATA, "id exceeds min/max boundaries\n"); ++ return ERR_ID_OUTSIDE_RANGE; ++ } ++ return EOK; ++} ++ + static struct ldb_message * + cache_req_well_known_sid_msg(TALLOC_CTX *mem_ctx, + const char *sid, +diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c +index 121f95abe86d2466aaea69f0fe68dfb33b1fee9e..04e085456f38e154a04ce0a803f2ba22830c1827 100644 +--- a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c ++++ b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c +@@ -64,6 +64,12 @@ cache_req_group_by_id_lookup(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_result **_result) + { ++ errno_t ret; ++ ++ ret = cache_req_idminmax_check(data, domain); ++ if (ret != EOK) { ++ return ret; ++ } + return sysdb_getgrgid_with_views(mem_ctx, domain, data->id, _result); + } + +diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c +index 4c88e1035b41969703c1c38d740e15516ac0d622..50c149e8795a61307e445d4c063dc0df1166519c 100644 +--- a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c ++++ b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c +@@ -90,6 +90,12 @@ cache_req_object_by_id_lookup(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_result **_result) + { ++ errno_t ret; ++ ++ ret = cache_req_idminmax_check(data, domain); ++ if (ret != EOK) { ++ return ret; ++ } + return sysdb_search_object_by_id(mem_ctx, domain, data->id, + data->attrs, _result); + } +diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c +index 3c25c7631b3da4a829ab577629334a7ee97980da..05add9564f57655bb53520b848971286bba6cab5 100644 +--- a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c ++++ b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c +@@ -64,6 +64,11 @@ cache_req_user_by_id_lookup(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_result **_result) + { ++ errno_t ret; ++ ret = cache_req_idminmax_check(data, domain); ++ if (ret != EOK) { ++ return ret; ++ } + return sysdb_getpwuid_with_views(mem_ctx, domain, data->id, _result); + } + +diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c +index 80086232fd437876c2b190fb972c2ee3194d9efd..82ba4125265d0bacd44a9f0082d588eef673a6f0 100644 +--- a/src/tests/cmocka/test_responder_cache_req.c ++++ b/src/tests/cmocka/test_responder_cache_req.c +@@ -58,6 +58,11 @@ struct test_group { + test_single_domain_setup, \ + test_single_domain_teardown) + ++#define new_single_domain_id_limit_test(test) \ ++ cmocka_unit_test_setup_teardown(test_ ## test, \ ++ test_single_domain_id_limits_setup, \ ++ test_single_domain_teardown) ++ + #define new_multi_domain_test(test) \ + cmocka_unit_test_setup_teardown(test_ ## test, \ + test_multi_domain_setup, \ +@@ -451,7 +456,8 @@ __wrap_sss_dp_get_account_send(TALLOC_CTX *mem_ctx, + return test_req_succeed_send(mem_ctx, rctx->ev); + } + +-static int test_single_domain_setup(void **state) ++static int test_single_domain_setup_common(void **state, ++ struct sss_test_conf_param *params) + { + struct cache_req_test_ctx *test_ctx = NULL; + errno_t ret; +@@ -465,7 +471,7 @@ static int test_single_domain_setup(void **state) + *state = test_ctx; + + test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, +- TEST_DOM_NAME, TEST_ID_PROVIDER, NULL); ++ TEST_DOM_NAME, TEST_ID_PROVIDER, params); + assert_non_null(test_ctx->tctx); + + test_ctx->rctx = mock_rctx(test_ctx, test_ctx->tctx->ev, +@@ -480,6 +486,11 @@ static int test_single_domain_setup(void **state) + return 0; + } + ++static int test_single_domain_setup(void **state) ++{ ++ return test_single_domain_setup_common(state, NULL); ++} ++ + static int test_single_domain_teardown(void **state) + { + struct cache_req_test_ctx *test_ctx; +@@ -495,6 +506,16 @@ static int test_single_domain_teardown(void **state) + return 0; + } + ++static int test_single_domain_id_limits_setup(void **state) ++{ ++ struct sss_test_conf_param params[] = { ++ { "min_id", "100" }, ++ { "max_id", "10000" }, ++ { NULL, NULL }, /* Sentinel */ ++ }; ++ return test_single_domain_setup_common(state, params); ++} ++ + static int test_multi_domain_setup(void **state) + { + struct cache_req_test_ctx *test_ctx = NULL; +@@ -526,6 +547,32 @@ static int test_multi_domain_setup(void **state) + return 0; + } + ++void test_user_by_id_below_id_range(void **state) ++{ ++ struct cache_req_test_ctx *test_ctx = NULL; ++ ++ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); ++ ++ /* Test. */ ++ run_cache_req(test_ctx, cache_req_user_by_id_send, ++ cache_req_user_by_id_test_done, test_ctx->tctx->dom, ++ 0, 10, ENOENT); ++ assert_false(test_ctx->dp_called); ++} ++ ++void test_user_by_id_above_id_range(void **state) ++{ ++ struct cache_req_test_ctx *test_ctx = NULL; ++ ++ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); ++ ++ /* Test. */ ++ run_cache_req(test_ctx, cache_req_user_by_id_send, ++ cache_req_user_by_id_test_done, test_ctx->tctx->dom, ++ 0, 100000, ENOENT); ++ assert_false(test_ctx->dp_called); ++} ++ + static int test_multi_domain_teardown(void **state) + { + struct cache_req_test_ctx *test_ctx; +@@ -1084,6 +1131,32 @@ void test_group_by_name_multiple_domains_found(void **state) + check_group(test_ctx, &groups[0], domain); + } + ++void test_group_by_id_below_id_range(void **state) ++{ ++ struct cache_req_test_ctx *test_ctx = NULL; ++ ++ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); ++ ++ /* Test. */ ++ run_cache_req(test_ctx, cache_req_group_by_id_send, ++ cache_req_group_by_id_test_done, test_ctx->tctx->dom, ++ 0, 10, ENOENT); ++ assert_false(test_ctx->dp_called); ++} ++ ++void test_group_by_id_above_id_range(void **state) ++{ ++ struct cache_req_test_ctx *test_ctx = NULL; ++ ++ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); ++ ++ /* Test. */ ++ run_cache_req(test_ctx, cache_req_group_by_id_send, ++ cache_req_group_by_id_test_done, test_ctx->tctx->dom, ++ 0, 100000, ENOENT); ++ assert_false(test_ctx->dp_called); ++} ++ + void test_group_by_name_multiple_domains_notfound(void **state) + { + struct cache_req_test_ctx *test_ctx = NULL; +@@ -2170,6 +2243,8 @@ int main(int argc, const char *argv[]) + new_single_domain_test(user_by_id_missing_notfound), + new_multi_domain_test(user_by_id_multiple_domains_found), + new_multi_domain_test(user_by_id_multiple_domains_notfound), ++ new_single_domain_id_limit_test(user_by_id_below_id_range), ++ new_single_domain_id_limit_test(user_by_id_above_id_range), + + new_single_domain_test(group_by_name_cache_valid), + new_single_domain_test(group_by_name_cache_expired), +@@ -2180,6 +2255,8 @@ int main(int argc, const char *argv[]) + new_multi_domain_test(group_by_name_multiple_domains_found), + new_multi_domain_test(group_by_name_multiple_domains_notfound), + new_multi_domain_test(group_by_name_multiple_domains_parse), ++ new_single_domain_id_limit_test(group_by_id_below_id_range), ++ new_single_domain_id_limit_test(group_by_id_above_id_range), + + new_single_domain_test(group_by_id_cache_valid), + new_single_domain_test(group_by_id_cache_expired), +diff --git a/src/util/util_errors.c b/src/util/util_errors.c +index 97eaf160f20bcc8cfe52254070a2d182e19addd4..9f6e413f0414f38dee4f0ee6b5f3fbeaac5d6612 100644 +--- a/src/util/util_errors.c ++++ b/src/util/util_errors.c +@@ -116,6 +116,7 @@ struct err_string error_to_str[] = { + { "Unable to initialize SSL" }, /* ERR_SSL_FAILURE */ + { "Unable to verify peer" }, /* ERR_UNABLE_TO_VERIFY_PEER */ + { "Unable to resolve host" }, /* ERR_UNABLE_TO_RESOLVE_HOST */ ++ { "ID is outside the allowed range" }, /* ERR_ID_OUTSIDE_RANGE */ + { "ERR_LAST" } /* ERR_LAST */ + }; + +diff --git a/src/util/util_errors.h b/src/util/util_errors.h +index 4a250bf0339ba689680c155fa8e6d43f42c2467e..051111ea7c249a5d8e4f302022898648ba2ffdd2 100644 +--- a/src/util/util_errors.h ++++ b/src/util/util_errors.h +@@ -138,6 +138,7 @@ enum sssd_errors { + ERR_SSL_FAILURE, + ERR_UNABLE_TO_VERIFY_PEER, + ERR_UNABLE_TO_RESOLVE_HOST, ++ ERR_ID_OUTSIDE_RANGE, + ERR_LAST /* ALWAYS LAST */ + }; + +-- +2.14.3 + diff --git a/SOURCES/0202-sudo-always-use-srv_opts-from-id-context.patch b/SOURCES/0202-sudo-always-use-srv_opts-from-id-context.patch new file mode 100644 index 0000000..a22ead0 --- /dev/null +++ b/SOURCES/0202-sudo-always-use-srv_opts-from-id-context.patch @@ -0,0 +1,64 @@ +From fbfb378def4ce7b807685b6d5391a9f3a2ef26d5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Thu, 19 Oct 2017 10:39:21 +0200 +Subject: [PATCH 202/202] sudo: always use srv_opts from id context + +Prior this patch, we remember id_ctx->srv_opts in sudo request to switch +the latest usn values. This works fine most of the time but it may cause +a crash. + +If we have two concurrent sudo refresh and one of these fails, it causes +failover to try the next server and possibly replacing the old srv_opts +with new one and it causes an access after free in the other refresh. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3562 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 2ee201dcf6bbe52abbbed3c2fc4c35ca2e0c8a43) +--- + src/providers/ldap/sdap_async_sudo.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c +index 3c69837fda313b2645c3a8497252670312f600ea..88a387422d5c9ae86cea583bb38dadf90cba37f3 100644 +--- a/src/providers/ldap/sdap_async_sudo.c ++++ b/src/providers/ldap/sdap_async_sudo.c +@@ -279,7 +279,6 @@ done: + struct sdap_sudo_refresh_state { + struct sdap_sudo_ctx *sudo_ctx; + struct tevent_context *ev; +- struct sdap_server_opts *srv_opts; + struct sdap_options *opts; + struct sdap_id_op *sdap_op; + struct sysdb_ctx *sysdb; +@@ -405,9 +404,6 @@ static void sdap_sudo_refresh_connect_done(struct tevent_req *subreq) + + DEBUG(SSSDBG_TRACE_FUNC, "SUDO LDAP connection successful\n"); + +- /* Obtain srv_opts here in case of first connection. */ +- state->srv_opts = state->sudo_ctx->id_ctx->srv_opts; +- + /* Renew host information if needed. */ + if (state->sudo_ctx->run_hostinfo) { + subreq = sdap_sudo_get_hostinfo_send(state, state->opts, +@@ -586,7 +582,6 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq) + goto done; + } + +- + /* start transaction */ + ret = sysdb_transaction_start(state->sysdb); + if (ret != EOK) { +@@ -621,7 +616,7 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq) + /* remember new usn */ + ret = sysdb_get_highest_usn(state, rules, rules_count, &usn); + if (ret == EOK) { +- sdap_sudo_set_usn(state->srv_opts, usn); ++ sdap_sudo_set_usn(state->sudo_ctx->id_ctx->srv_opts, usn); + } else { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get highest USN [%d]: %s\n", + ret, sss_strerror(ret)); +-- +2.14.3 + diff --git a/SOURCES/0203-SELINUX-Use-getseuserbyname-to-get-IPA-seuser.patch b/SOURCES/0203-SELINUX-Use-getseuserbyname-to-get-IPA-seuser.patch new file mode 100644 index 0000000..927f159 --- /dev/null +++ b/SOURCES/0203-SELINUX-Use-getseuserbyname-to-get-IPA-seuser.patch @@ -0,0 +1,182 @@ +From 0006bd76856787614f961001929fea95d0669fe5 Mon Sep 17 00:00:00 2001 +From: Justin Stephenson +Date: Thu, 9 Mar 2017 17:21:37 -0500 +Subject: [PATCH 203/205] SELINUX: Use getseuserbyname to get IPA seuser +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The libselinux function getseuserbyname is more reliable method to retrieve +SELinux usernames then functions from libsemanage `semanage_user_query` +and is recommended by libsemanage developers. +Replace get_seuser function with getseuserbyname. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3308 + +Reviewed-by: Michal Židek +Reviewed-by: Jakub Hrozek +Reviewed-by: Petr Lautrbach +(cherry picked from commit cfe87ca0c4fded9cbf907697d08fa0e6c8f8ebce) +--- + Makefile.am | 1 + + src/providers/ipa/selinux_child.c | 12 +++---- + src/util/sss_semanage.c | 73 --------------------------------------- + src/util/util.h | 2 -- + 4 files changed, 7 insertions(+), 81 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index cdd517d50679b876814303fb7d6c63d49bcd8d38..1eb398830e4817d4da0878a6577b45df101e920d 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -4094,6 +4094,7 @@ selinux_child_LDADD = \ + $(POPT_LIBS) \ + $(DHASH_LIBS) \ + $(SEMANAGE_LIBS) \ ++ $(SELINUX_LIBS) \ + $(NULL) + endif + +diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c +index f8dd3954a7244df2dcbb910aabf8888f41306c09..073475094ee491bd5453898c6ba65214fa14fe59 100644 +--- a/src/providers/ipa/selinux_child.c ++++ b/src/providers/ipa/selinux_child.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + #include "util/util.h" + #include "util/child_common.h" +@@ -172,11 +173,10 @@ static bool seuser_needs_update(struct input_buffer *ibuf) + char *db_mls_range = NULL; + errno_t ret; + +- ret = get_seuser(ibuf, ibuf->username, &db_seuser, &db_mls_range); ++ ret = getseuserbyname(ibuf->username, &db_seuser, &db_mls_range); + DEBUG(SSSDBG_TRACE_INTERNAL, +- "get_seuser: ret: %d msg: [%s] seuser: %s mls: %s\n", +- ret, sss_strerror(ret), +- db_seuser ? db_seuser : "unknown", ++ "getseuserbyname: ret: %d seuser: %s mls: %s\n", ++ ret, db_seuser ? db_seuser : "unknown", + db_mls_range ? db_mls_range : "unknown"); + if (ret == EOK && db_seuser && db_mls_range && + strcmp(db_seuser, ibuf->seuser) == 0 && +@@ -188,8 +188,8 @@ static bool seuser_needs_update(struct input_buffer *ibuf) + needs_update = false; + } + +- talloc_free(db_seuser); +- talloc_free(db_mls_range); ++ free(db_seuser); ++ free(db_mls_range); + return needs_update; + } + +diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c +index 0da97aad4d8eba733b131c2749932e03ca4242c4..37278cc986a1ea49dc2218a635d52b9d54ca089d 100644 +--- a/src/util/sss_semanage.c ++++ b/src/util/sss_semanage.c +@@ -382,73 +382,6 @@ done: + sss_semanage_close(handle); + return ret; + } +- +-int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name, +- char **_seuser, char **_mls_range) +-{ +- errno_t ret; +- const char *seuser; +- const char *mls_range; +- semanage_handle_t *sm_handle = NULL; +- semanage_seuser_t *sm_user = NULL; +- semanage_seuser_key_t *sm_key = NULL; +- +- ret = sss_semanage_init(&sm_handle); +- if (ret == ERR_SELINUX_NOT_MANAGED) { +- goto done; +- } else if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux handle\n"); +- goto done; +- } +- +- ret = semanage_seuser_key_create(sm_handle, login_name, &sm_key); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create key for %s\n", login_name); +- ret = EIO; +- goto done; +- } +- +- ret = semanage_seuser_query(sm_handle, sm_key, &sm_user); +- if (ret < 0) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot query for %s\n", login_name); +- ret = EIO; +- goto done; +- } +- +- seuser = semanage_seuser_get_sename(sm_user); +- if (seuser != NULL) { +- *_seuser = talloc_strdup(mem_ctx, seuser); +- if (*_seuser == NULL) { +- ret = ENOMEM; +- goto done; +- } +- DEBUG(SSSDBG_OP_FAILURE, +- "SELinux user for %s: %s\n", login_name, *_seuser); +- } else { +- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get sename for %s\n", login_name); +- } +- +- mls_range = semanage_seuser_get_mlsrange(sm_user); +- if (mls_range != NULL) { +- *_mls_range = talloc_strdup(mem_ctx, mls_range); +- if (*_mls_range == NULL) { +- ret = ENOMEM; +- goto done; +- } +- DEBUG(SSSDBG_OP_FAILURE, +- "SELinux range for %s: %s\n", login_name, *_mls_range); +- } else { +- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get mlsrange for %s\n", login_name); +- } +- +- ret = EOK; +-done: +- semanage_seuser_key_free(sm_key); +- semanage_seuser_free(sm_user); +- sss_semanage_close(sm_handle); +- return ret; +-} +- + #else /* HAVE_SEMANAGE */ + int set_seuser(const char *login_name, const char *seuser_name, + const char *mls) +@@ -460,10 +393,4 @@ int del_seuser(const char *login_name) + { + return EOK; + } +- +-int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name, +- char **_seuser, char **_mls_range) +-{ +- return EOK; +-} + #endif /* HAVE_SEMANAGE */ +diff --git a/src/util/util.h b/src/util/util.h +index 72d4116e1206e9cc69715edc45bf5b9b91e37e6b..1719d8eec1b6b05877b9be3382589e442bff85be 100644 +--- a/src/util/util.h ++++ b/src/util/util.h +@@ -658,8 +658,6 @@ errno_t restore_creds(struct sss_creds *saved_creds); + int set_seuser(const char *login_name, const char *seuser_name, + const char *mlsrange); + int del_seuser(const char *login_name); +-int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name, +- char **_seuser, char **_mls_range); + + /* convert time from generalized form to unix time */ + errno_t sss_utc_to_time_t(const char *str, const char *format, time_t *unix_time); +-- +2.14.3 + diff --git a/SOURCES/0204-SELINUX-Check-if-SELinux-is-managed-in-selinux_child.patch b/SOURCES/0204-SELINUX-Check-if-SELinux-is-managed-in-selinux_child.patch new file mode 100644 index 0000000..3c6c46d --- /dev/null +++ b/SOURCES/0204-SELINUX-Check-if-SELinux-is-managed-in-selinux_child.patch @@ -0,0 +1,203 @@ +From 8db75e9ebbdaec1dde836380ca38d8cfec61cf3d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20=C5=BDidek?= +Date: Thu, 1 Feb 2018 11:34:21 +0100 +Subject: [PATCH 204/205] SELINUX: Check if SELinux is managed in selinux_child +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If SELinux policy is not managed at all, don't call any SELinux user +handling functions and instead return that no update is needed. + +Pair-Programmed-With: Jakub Hrozek +Reviewed-by: Lukáš Slebodník +Reviewed-by: Fabiano Fidêncio + +Resolves: +https://pagure.io/SSSD/sssd/issue/3618 +(cherry picked from commit 450b472a68abf442479755c7916c757907b35ea5) +--- + src/providers/ipa/selinux_child.c | 3 +- + src/util/sss_semanage.c | 82 +++++++++++++++++++++++++++++++-------- + src/util/util.h | 3 ++ + 3 files changed, 70 insertions(+), 18 deletions(-) + +diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c +index 073475094ee491bd5453898c6ba65214fa14fe59..bc9460e122ce991087a744fd5335e6c468c6a64b 100644 +--- a/src/providers/ipa/selinux_child.c ++++ b/src/providers/ipa/selinux_child.c +@@ -27,7 +27,6 @@ + #include + #include + #include +-#include + + #include "util/util.h" + #include "util/child_common.h" +@@ -173,7 +172,7 @@ static bool seuser_needs_update(struct input_buffer *ibuf) + char *db_mls_range = NULL; + errno_t ret; + +- ret = getseuserbyname(ibuf->username, &db_seuser, &db_mls_range); ++ ret = sss_get_seuser(ibuf->username, &db_seuser, &db_mls_range); + DEBUG(SSSDBG_TRACE_INTERNAL, + "getseuserbyname: ret: %d seuser: %s mls: %s\n", + ret, db_seuser ? db_seuser : "unknown", +diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c +index 37278cc986a1ea49dc2218a635d52b9d54ca089d..25b6bcdad2ad7e7ac710497f13d6a6e22360b0dd 100644 +--- a/src/util/sss_semanage.c ++++ b/src/util/sss_semanage.c +@@ -22,8 +22,9 @@ + #include "config.h" + + #include +-#ifdef HAVE_SEMANAGE ++#if defined(HAVE_SEMANAGE) && defined(HAVE_SELINUX) + #include ++#include + #endif + + #include "util/util.h" +@@ -32,7 +33,7 @@ + #define DEFAULT_SERANGE "s0" + #endif + +-#ifdef HAVE_SEMANAGE ++#if defined(HAVE_SEMANAGE) && defined(HAVE_SELINUX) + /* turn libselinux messages into SSSD DEBUG() calls */ + static void sss_semanage_error_callback(void *varg, + semanage_handle_t *handle, +@@ -73,33 +74,47 @@ static void sss_semanage_close(semanage_handle_t *handle) + semanage_handle_destroy(handle); + } + +-static int sss_semanage_init(semanage_handle_t **_handle) ++static int sss_is_selinux_managed(semanage_handle_t *handle) + { + int ret; +- semanage_handle_t *handle = NULL; + +- handle = semanage_handle_create(); +- if (!handle) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n"); +- ret = EIO; +- goto done; ++ if (handle == NULL) { ++ return EINVAL; + } + +- semanage_msg_set_callback(handle, +- sss_semanage_error_callback, +- NULL); +- + ret = semanage_is_managed(handle); + if (ret == 0) { + DEBUG(SSSDBG_TRACE_FUNC, "SELinux policy not managed via libsemanage\n"); +- ret = ERR_SELINUX_NOT_MANAGED; +- goto done; ++ return ERR_SELINUX_NOT_MANAGED; + } else if (ret == -1) { + DEBUG(SSSDBG_CRIT_FAILURE, "Call to semanage_is_managed failed\n"); ++ return EIO; ++ } ++ ++ return EOK; ++} ++ ++static int sss_semanage_init(semanage_handle_t **_handle) ++{ ++ int ret; ++ semanage_handle_t *handle = NULL; ++ ++ handle = semanage_handle_create(); ++ if (!handle) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n"); + ret = EIO; + goto done; + } + ++ semanage_msg_set_callback(handle, ++ sss_semanage_error_callback, ++ NULL); ++ ++ ret = sss_is_selinux_managed(handle); ++ if (ret != EOK) { ++ goto done; ++ } ++ + ret = semanage_access_check(handle); + if (ret < SEMANAGE_CAN_READ) { + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot read SELinux policy store\n"); +@@ -229,6 +244,34 @@ done: + return ret; + } + ++int sss_get_seuser(const char *linuxuser, ++ char **selinuxuser, ++ char **level) ++{ ++ int ret; ++ semanage_handle_t *handle; ++ ++ handle = semanage_handle_create(); ++ if (handle == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n"); ++ return EIO; ++ } ++ ++ semanage_msg_set_callback(handle, ++ sss_semanage_error_callback, ++ NULL); ++ ++ /* We only needed the handle for this call. Close the handle right ++ * after it */ ++ ret = sss_is_selinux_managed(handle); ++ sss_semanage_close(handle); ++ if (ret != EOK) { ++ return ret; ++ } ++ ++ return getseuserbyname(linuxuser, selinuxuser, level); ++} ++ + int set_seuser(const char *login_name, const char *seuser_name, + const char *mls) + { +@@ -382,7 +425,7 @@ done: + sss_semanage_close(handle); + return ret; + } +-#else /* HAVE_SEMANAGE */ ++#else /* HAVE_SEMANAGE && HAVE_SELINUX */ + int set_seuser(const char *login_name, const char *seuser_name, + const char *mls) + { +@@ -393,4 +436,11 @@ int del_seuser(const char *login_name) + { + return EOK; + } ++ ++int sss_get_seuser(const char *linuxuser, ++ char **selinuxuser, ++ char **level) ++{ ++ return EOK; ++} + #endif /* HAVE_SEMANAGE */ +diff --git a/src/util/util.h b/src/util/util.h +index 1719d8eec1b6b05877b9be3382589e442bff85be..74ce2dcecfe17d1cea96cfb5c4b7edb8fd46f09f 100644 +--- a/src/util/util.h ++++ b/src/util/util.h +@@ -658,6 +658,9 @@ errno_t restore_creds(struct sss_creds *saved_creds); + int set_seuser(const char *login_name, const char *seuser_name, + const char *mlsrange); + int del_seuser(const char *login_name); ++int sss_get_seuser(const char *linuxuser, ++ char **selinuxuser, ++ char **level); + + /* convert time from generalized form to unix time */ + errno_t sss_utc_to_time_t(const char *str, const char *format, time_t *unix_time); +-- +2.14.3 + diff --git a/SOURCES/0205-util-Add-sss_-prefix-to-some-functions.patch b/SOURCES/0205-util-Add-sss_-prefix-to-some-functions.patch new file mode 100644 index 0000000..020f747 --- /dev/null +++ b/SOURCES/0205-util-Add-sss_-prefix-to-some-functions.patch @@ -0,0 +1,142 @@ +From da163073db166a8f3acc07391ccdaedc8aa70230 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20=C5=BDidek?= +Date: Tue, 6 Feb 2018 19:17:55 +0100 +Subject: [PATCH 205/205] util: Add sss_ prefix to some functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add sss_ prefix to del_seuser and set_seuser for consistency +with sss_get_seuser. Also sss_ prefix makes it clear that +these functions come from SSSD. + +Reviewed-by: Lukáš Slebodník + +Resolves: +https://pagure.io/SSSD/sssd/issue/3618 +(cherry picked from commit 6b9c38df5712b951e31800efea2df0802e333e08) +--- + src/providers/ipa/selinux_child.c | 4 ++-- + src/tools/sss_useradd.c | 2 +- + src/tools/sss_userdel.c | 2 +- + src/tools/sss_usermod.c | 2 +- + src/util/sss_semanage.c | 12 ++++++------ + src/util/util.h | 6 +++--- + 6 files changed, 14 insertions(+), 14 deletions(-) + +diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c +index bc9460e122ce991087a744fd5335e6c468c6a64b..701be4b35b0f9a9afd9c58eae724d3b8615d0b8c 100644 +--- a/src/providers/ipa/selinux_child.c ++++ b/src/providers/ipa/selinux_child.c +@@ -157,9 +157,9 @@ static int sc_set_seuser(const char *login_name, const char *seuser_name, + * default. We need to remove the SELinux user from the DB + * in that case + */ +- ret = del_seuser(login_name); ++ ret = sss_del_seuser(login_name); + } else { +- ret = set_seuser(login_name, seuser_name, mls); ++ ret = sss_set_seuser(login_name, seuser_name, mls); + } + umask(old_mask); + return ret; +diff --git a/src/tools/sss_useradd.c b/src/tools/sss_useradd.c +index 8521b83011b42c9e2acca4136f154acb3919440c..ca2cbd6c119e5a1735e5b3b524cddeccb68a2578 100644 +--- a/src/tools/sss_useradd.c ++++ b/src/tools/sss_useradd.c +@@ -205,7 +205,7 @@ int main(int argc, const char **argv) + + /* Set SELinux login context - must be done after transaction is done + * b/c libselinux calls getpwnam */ +- ret = set_seuser(tctx->octx->name, pc_selinux_user, NULL); ++ ret = sss_set_seuser(tctx->octx->name, pc_selinux_user, NULL); + if (ret != EOK) { + ERROR("Cannot set SELinux login context\n"); + ret = EXIT_FAILURE; +diff --git a/src/tools/sss_userdel.c b/src/tools/sss_userdel.c +index d085dc3cabd31b2ee82b13c6cbc39c7658b071d1..fb0f2c2ab6163738da2dcf4177c06cd5dc524345 100644 +--- a/src/tools/sss_userdel.c ++++ b/src/tools/sss_userdel.c +@@ -254,7 +254,7 @@ int main(int argc, const char **argv) + + /* Set SELinux login context - must be done after transaction is done + * b/c libselinux calls getpwnam */ +- ret = del_seuser(tctx->octx->name); ++ ret = sss_del_seuser(tctx->octx->name); + if (ret != EOK) { + ERROR("Cannot reset SELinux login context\n"); + ret = EXIT_FAILURE; +diff --git a/src/tools/sss_usermod.c b/src/tools/sss_usermod.c +index 55e94394766f5f46bb3c14c231186f2d79d6b6ab..6a818f13ad2a7e087e23fa2190b83aeb1eabdbac 100644 +--- a/src/tools/sss_usermod.c ++++ b/src/tools/sss_usermod.c +@@ -300,7 +300,7 @@ int main(int argc, const char **argv) + + /* Set SELinux login context - must be done after transaction is done + * b/c libselinux calls getpwnam */ +- ret = set_seuser(tctx->octx->name, pc_selinux_user, NULL); ++ ret = sss_set_seuser(tctx->octx->name, pc_selinux_user, NULL); + if (ret != EOK) { + ERROR("Cannot set SELinux login context\n"); + ret = EXIT_FAILURE; +diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c +index 25b6bcdad2ad7e7ac710497f13d6a6e22360b0dd..1150b6236c2c227fe2fc69f2505b6e254a1e64ec 100644 +--- a/src/util/sss_semanage.c ++++ b/src/util/sss_semanage.c +@@ -272,8 +272,8 @@ int sss_get_seuser(const char *linuxuser, + return getseuserbyname(linuxuser, selinuxuser, level); + } + +-int set_seuser(const char *login_name, const char *seuser_name, +- const char *mls) ++int sss_set_seuser(const char *login_name, const char *seuser_name, ++ const char *mls) + { + semanage_handle_t *handle = NULL; + semanage_seuser_key_t *key = NULL; +@@ -346,7 +346,7 @@ done: + return ret; + } + +-int del_seuser(const char *login_name) ++int sss_del_seuser(const char *login_name) + { + semanage_handle_t *handle = NULL; + semanage_seuser_key_t *key = NULL; +@@ -426,13 +426,13 @@ done: + return ret; + } + #else /* HAVE_SEMANAGE && HAVE_SELINUX */ +-int set_seuser(const char *login_name, const char *seuser_name, +- const char *mls) ++int sss_set_seuser(const char *login_name, const char *seuser_name, ++ const char *mls) + { + return EOK; + } + +-int del_seuser(const char *login_name) ++int sss_del_seuser(const char *login_name) + { + return EOK; + } +diff --git a/src/util/util.h b/src/util/util.h +index 74ce2dcecfe17d1cea96cfb5c4b7edb8fd46f09f..e816ba8462afb907e291aaa1692208ccb822205c 100644 +--- a/src/util/util.h ++++ b/src/util/util.h +@@ -655,9 +655,9 @@ errno_t restore_creds(struct sss_creds *saved_creds); + * certain permissions. Therefore the caller should make sure the umask is + * not too restricted (especially when called from the daemon code). + */ +-int set_seuser(const char *login_name, const char *seuser_name, +- const char *mlsrange); +-int del_seuser(const char *login_name); ++int sss_set_seuser(const char *login_name, const char *seuser_name, ++ const char *mlsrange); ++int sss_del_seuser(const char *login_name); + int sss_get_seuser(const char *linuxuser, + char **selinuxuser, + char **level); +-- +2.14.3 + diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec index b6134a5..e957397 100644 --- a/SPECS/sssd.spec +++ b/SPECS/sssd.spec @@ -40,7 +40,7 @@ Name: sssd Version: 1.15.2 -Release: 50%{?dist}.8 +Release: 50%{?dist}.11 Group: Applications/System Summary: System Security Services Daemon License: GPLv3+ @@ -248,6 +248,12 @@ Patch0196: 0196-sssd_client-add-mutex-protected-call-to-the-PAC-resp.patch Patch0197: 0197-sysdb-sanitize-search-filter-input.patch Patch0198: 0198-ipa-make-sure-view-name-is-initialized-at-startup.patch Patch0199: 0199-CACHE_REQ-Copy-the-cr_domain-list-for-each-request.patch +Patch0200: 0200-cache_req-Correction-of-cache_req-debug-string-ID-fo.patch +Patch0201: 0201-cache-Check-for-max_id-min_id-in-cache_req.patch +Patch0202: 0202-sudo-always-use-srv_opts-from-id-context.patch +Patch0203: 0203-SELINUX-Use-getseuserbyname-to-get-IPA-seuser.patch +Patch0204: 0204-SELINUX-Check-if-SELinux-is-managed-in-selinux_child.patch +Patch0205: 0205-util-Add-sss_-prefix-to-some-functions.patch #This patch should not be removed in RHEL-7 Patch999: 0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec @@ -1387,6 +1393,20 @@ fi } %changelog +* Tue Feb 13 2018 Fabiano Fidêncio - 1.15.2-50-11 +- Resolves: rhbz#1516700 - SELINUX: Use getseuserbyname to get IPA + seuser [rhel-7.4.z] + +* Sun Jan 07 2018 Fabiano Fidêncio - 1.15.2-50-10 +- Resolves: rhbz#1530975 - sssd_be stuck in an infinite loop after + completing full refresh of sudo rules + [rhel-7.4.z] + +* Fri Jan 05 2018 Fabiano Fidêncio - 1.15.2-50.9 +- Resolves: rhbz#1525110 - NSS by-id requests are not checked against + max_id/min_id ranges before triggering the + backend [rhel-7.4.z] + * Fri Nov 03 2017 Fabiano Fidêncio - 1.15.2-50.8 - Resolves: rhbz#1508972 - Accessing IdM kerberos ticket fails while id mapping is applied [rhel-7.4.z]