diff --git a/SOURCES/0047-SELINUX-Always-add-SELinux-user-to-the-semanage-data.patch b/SOURCES/0047-SELINUX-Always-add-SELinux-user-to-the-semanage-data.patch new file mode 100644 index 0000000..66dbbbe --- /dev/null +++ b/SOURCES/0047-SELINUX-Always-add-SELinux-user-to-the-semanage-data.patch @@ -0,0 +1,146 @@ +From e7e942ceb1f8402d00f5f14a9e065d3fc434b711 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Thu, 23 Aug 2018 13:55:51 +0200 +Subject: [PATCH] SELINUX: Always add SELinux user to the semanage database if + it doesn't exist +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Previously, we tried to optimize too much and only set the SELinux user +to Linux user mapping in case the SELinux user was different from the +system default. But this doesn't work for the case where the Linux user +has a non-standard home directory, because then SELinux would not have +any idea that this user's home directory should be labeled as a home +directory. + +This patch relaxes the optimization in the sense that on the first +login, the SELinux context is saved regardless of whether it is the same +as the default or different. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3819 + +Reviewed-by: Michal Židek +(cherry picked from commit 945865ae16120ffade267227ca48cefd58822fd2) +--- + src/providers/ipa/selinux_child.c | 10 ++++++++-- + src/util/sss_semanage.c | 30 ++++++++++++++++++++++++++++++ + src/util/util.h | 1 + + src/util/util_errors.c | 1 + + src/util/util_errors.h | 1 + + 5 files changed, 41 insertions(+), 2 deletions(-) + +diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c +index d061417..925591e 100644 +--- a/src/providers/ipa/selinux_child.c ++++ b/src/providers/ipa/selinux_child.c +@@ -176,13 +176,16 @@ static bool seuser_needs_update(const char *username, + + ret = sss_get_seuser(username, &db_seuser, &db_mls_range); + DEBUG(SSSDBG_TRACE_INTERNAL, +- "getseuserbyname: ret: %d seuser: %s mls: %s\n", ++ "sss_get_seuser: 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, seuser) == 0 && + strcmp(db_mls_range, mls_range) == 0) { +- needs_update = false; ++ ret = sss_seuser_exists(username); ++ if (ret == EOK) { ++ needs_update = false; ++ } + } + /* OR */ + if (ret == ERR_SELINUX_NOT_MANAGED) { +@@ -191,6 +194,9 @@ static bool seuser_needs_update(const char *username, + + free(db_seuser); + free(db_mls_range); ++ DEBUG(SSSDBG_TRACE_FUNC, ++ "The SELinux user does %sneed an update\n", ++ needs_update ? "" : "not "); + return needs_update; + } + +diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c +index bcce57b..aea0385 100644 +--- a/src/util/sss_semanage.c ++++ b/src/util/sss_semanage.c +@@ -248,6 +248,36 @@ done: + return ret; + } + ++int sss_seuser_exists(const char *linuxuser) ++{ ++ int ret; ++ int exists; ++ semanage_seuser_key_t *sm_key = NULL; ++ semanage_handle_t *sm_handle = NULL; ++ ++ ret = sss_semanage_init(&sm_handle); ++ if (ret != EOK) { ++ return ret; ++ } ++ ++ ret = semanage_seuser_key_create(sm_handle, linuxuser, &sm_key); ++ if (ret < 0) { ++ sss_semanage_close(sm_handle); ++ return EIO; ++ } ++ ++ ret = semanage_seuser_exists(sm_handle, sm_key, &exists); ++ semanage_seuser_key_free(sm_key); ++ sss_semanage_close(sm_handle); ++ if (ret < 0) { ++ return EIO; ++ } ++ ++ DEBUG(SSSDBG_TRACE_FUNC, "seuser exists: %s\n", exists ? "yes" : "no"); ++ ++ return exists ? EOK : ERR_SELINUX_USER_NOT_FOUND; ++} ++ + int sss_get_seuser(const char *linuxuser, + char **selinuxuser, + char **level) +diff --git a/src/util/util.h b/src/util/util.h +index bc89ecb..c78615b 100644 +--- a/src/util/util.h ++++ b/src/util/util.h +@@ -660,6 +660,7 @@ int sss_del_seuser(const char *login_name); + int sss_get_seuser(const char *linuxuser, + char **selinuxuser, + char **level); ++int sss_seuser_exists(const char *linuxuser); + + /* 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); +diff --git a/src/util/util_errors.c b/src/util/util_errors.c +index e2bb2a0..e5c5bd1 100644 +--- a/src/util/util_errors.c ++++ b/src/util/util_errors.c +@@ -75,6 +75,7 @@ struct err_string error_to_str[] = { + { "LDAP search returned a referral" }, /* ERR_REFERRAL */ + { "Error setting SELinux user context" }, /* ERR_SELINUX_CONTEXT */ + { "SELinux is not managed by libsemanage" }, /* ERR_SELINUX_NOT_MANAGED */ ++ { "SELinux user does not exist" }, /* ERR_SELINUX_USER_NOT_FOUND */ + { "Username format not allowed by re_expression" }, /* ERR_REGEX_NOMATCH */ + { "Time specification not supported" }, /* ERR_TIMESPEC_NOT_SUPPORTED */ + { "Invalid SSSD configuration detected" }, /* ERR_INVALID_CONFIG */ +diff --git a/src/util/util_errors.h b/src/util/util_errors.h +index 4950172..a4760a1 100644 +--- a/src/util/util_errors.h ++++ b/src/util/util_errors.h +@@ -97,6 +97,7 @@ enum sssd_errors { + ERR_REFERRAL, + ERR_SELINUX_CONTEXT, + ERR_SELINUX_NOT_MANAGED, ++ ERR_SELINUX_USER_NOT_FOUND, + ERR_REGEX_NOMATCH, + ERR_TIMESPEC_NOT_SUPPORTED, + ERR_INVALID_CONFIG, +-- +2.9.5 + diff --git a/SOURCES/0048-sudo-respect-case-sensitivity-in-sudo-responder.patch b/SOURCES/0048-sudo-respect-case-sensitivity-in-sudo-responder.patch new file mode 100644 index 0000000..dcbe819 --- /dev/null +++ b/SOURCES/0048-sudo-respect-case-sensitivity-in-sudo-responder.patch @@ -0,0 +1,69 @@ +From 2d9286102f23ea9d13213f1176ba669b9315a75f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Thu, 6 Sep 2018 13:38:56 +0200 +Subject: [PATCH] sudo: respect case sensitivity in sudo responder +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If the domain is not case sensitive and the case of the original user +or group name differs from the name in the rule we failed to find the +rule. + +Now we filter the rule only with lower cased values in such domain. + +Steps to reproduce: +1. Add user/group with upper case, e.g. USER-1 +2. Add sudo rule with lower cased name, e.g. sudoUser: user-1 +3. Login to system with lower case, e.g. user-1 +4. Run sudo -l + +Without the patch, rule is not found. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3820 + +Reviewed-by: Michal Židek +(cherry picked from commit d7f0b58e2896ed2ef9ed5a390815c1e4df6caaee) +--- + src/db/sysdb_sudo.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c +index 3ad462d8f..19ed97b86 100644 +--- a/src/db/sysdb_sudo.c ++++ b/src/db/sysdb_sudo.c +@@ -418,7 +418,17 @@ sysdb_get_sudo_user_info(TALLOC_CTX *mem_ctx, + ret = EINVAL; + goto done; + } +- DEBUG(SSSDBG_TRACE_FUNC, "original name: %s\n", orig_name); ++ ++ DEBUG(SSSDBG_TRACE_FUNC, "Original name: %s\n", orig_name); ++ ++ orig_name = sss_get_cased_name(tmp_ctx, orig_name, domain->case_sensitive); ++ if (orig_name == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory!\n"); ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ DEBUG(SSSDBG_TRACE_FUNC, "Cased name: %s\n", orig_name); + + if (_uid != NULL) { + uid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM, 0); +@@ -450,8 +460,9 @@ sysdb_get_sudo_user_info(TALLOC_CTX *mem_ctx, + continue; + } + +- sysdb_groupnames[num_groups] = talloc_strdup(sysdb_groupnames, +- groupname); ++ sysdb_groupnames[num_groups] = \ ++ sss_get_cased_name(sysdb_groupnames, groupname, ++ domain->case_sensitive); + if (sysdb_groupnames[num_groups] == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, "Cannot strdup %s\n", groupname); + continue; +-- +2.19.1 + diff --git a/SOURCES/0049-nss-use-enumeration-context-as-talloc-parent-for-cac.patch b/SOURCES/0049-nss-use-enumeration-context-as-talloc-parent-for-cac.patch new file mode 100644 index 0000000..eb552b5 --- /dev/null +++ b/SOURCES/0049-nss-use-enumeration-context-as-talloc-parent-for-cac.patch @@ -0,0 +1,146 @@ +From 720a423a0119f23606c6029c3f48be98841ca910 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Tue, 30 Oct 2018 13:21:28 +0100 +Subject: [PATCH] nss: use enumeration context as talloc parent for cache req + result + +Otherwise we end up with memory leak since the result is never freed. + +We need to convert nctx->*ent structures into talloc pointer so +we can use enum_ctx as parent. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3870 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 406b731ddfbeb62623640cc37a7adc76af0a4b22) +--- + src/responder/nss/nss_cmd.c | 12 ++++++------ + src/responder/nss/nss_enum.c | 2 +- + src/responder/nss/nss_private.h | 6 +++--- + src/responder/nss/nsssrv.c | 21 +++++++++++++++++++++ + 4 files changed, 31 insertions(+), 10 deletions(-) + +diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c +index 9ee6ca805..25e663ed5 100644 +--- a/src/responder/nss/nss_cmd.c ++++ b/src/responder/nss/nss_cmd.c +@@ -942,7 +942,7 @@ static errno_t nss_cmd_setpwent(struct cli_ctx *cli_ctx) + + nss_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct nss_ctx); + +- return nss_setent(cli_ctx, CACHE_REQ_ENUM_USERS, &nss_ctx->pwent); ++ return nss_setent(cli_ctx, CACHE_REQ_ENUM_USERS, nss_ctx->pwent); + } + + static errno_t nss_cmd_getpwent(struct cli_ctx *cli_ctx) +@@ -955,7 +955,7 @@ static errno_t nss_cmd_getpwent(struct cli_ctx *cli_ctx) + + return nss_getent(cli_ctx, CACHE_REQ_ENUM_USERS, + &state_ctx->pwent, nss_protocol_fill_pwent, +- &nss_ctx->pwent); ++ nss_ctx->pwent); + } + + static errno_t nss_cmd_endpwent(struct cli_ctx *cli_ctx) +@@ -998,7 +998,7 @@ static errno_t nss_cmd_setgrent(struct cli_ctx *cli_ctx) + + nss_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct nss_ctx); + +- return nss_setent(cli_ctx, CACHE_REQ_ENUM_GROUPS, &nss_ctx->grent); ++ return nss_setent(cli_ctx, CACHE_REQ_ENUM_GROUPS, nss_ctx->grent); + } + + static errno_t nss_cmd_getgrent(struct cli_ctx *cli_ctx) +@@ -1011,7 +1011,7 @@ static errno_t nss_cmd_getgrent(struct cli_ctx *cli_ctx) + + return nss_getent(cli_ctx, CACHE_REQ_ENUM_GROUPS, + &state_ctx->grent, nss_protocol_fill_grent, +- &nss_ctx->grent); ++ nss_ctx->grent); + } + + static errno_t nss_cmd_endgrent(struct cli_ctx *cli_ctx) +@@ -1093,7 +1093,7 @@ static errno_t nss_cmd_setservent(struct cli_ctx *cli_ctx) + + nss_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct nss_ctx); + +- return nss_setent(cli_ctx, CACHE_REQ_ENUM_SVC, &nss_ctx->svcent); ++ return nss_setent(cli_ctx, CACHE_REQ_ENUM_SVC, nss_ctx->svcent); + } + + static errno_t nss_cmd_getservent(struct cli_ctx *cli_ctx) +@@ -1106,7 +1106,7 @@ static errno_t nss_cmd_getservent(struct cli_ctx *cli_ctx) + + return nss_getent(cli_ctx, CACHE_REQ_ENUM_SVC, + &state_ctx->svcent, nss_protocol_fill_svcent, +- &nss_ctx->svcent); ++ nss_ctx->svcent); + } + + static errno_t nss_cmd_endservent(struct cli_ctx *cli_ctx) +diff --git a/src/responder/nss/nss_enum.c b/src/responder/nss/nss_enum.c +index a45b65233..9588943c9 100644 +--- a/src/responder/nss/nss_enum.c ++++ b/src/responder/nss/nss_enum.c +@@ -138,7 +138,7 @@ static void nss_setent_internal_done(struct tevent_req *subreq) + switch (ret) { + case EOK: + talloc_zfree(state->enum_ctx->result); +- state->enum_ctx->result = talloc_steal(state->nss_ctx, result); ++ state->enum_ctx->result = talloc_steal(state->enum_ctx, result); + + if (state->type == CACHE_REQ_NETGROUP_BY_NAME) { + /* We need to expand the netgroup into triples and members. */ +diff --git a/src/responder/nss/nss_private.h b/src/responder/nss/nss_private.h +index aa8d8e9cd..cd0d35517 100644 +--- a/src/responder/nss/nss_private.h ++++ b/src/responder/nss/nss_private.h +@@ -78,9 +78,9 @@ struct nss_ctx { + const char **extra_attributes; + + /* Enumeration. */ +- struct nss_enum_ctx pwent; +- struct nss_enum_ctx grent; +- struct nss_enum_ctx svcent; ++ struct nss_enum_ctx *pwent; ++ struct nss_enum_ctx *grent; ++ struct nss_enum_ctx *svcent; + hash_table_t *netgrent; + + /* Memory cache. */ +diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c +index 004e6c1a1..d6c5a08a9 100644 +--- a/src/responder/nss/nsssrv.c ++++ b/src/responder/nss/nsssrv.c +@@ -378,6 +378,27 @@ int nss_process_init(TALLOC_CTX *mem_ctx, + goto fail; + } + ++ nctx->pwent = talloc_zero(nctx, struct nss_enum_ctx); ++ if (nctx->pwent == NULL) { ++ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize pwent context!\n"); ++ ret = ENOMEM; ++ goto fail; ++ } ++ ++ nctx->grent = talloc_zero(nctx, struct nss_enum_ctx); ++ if (nctx->grent == NULL) { ++ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize grent context!\n"); ++ ret = ENOMEM; ++ goto fail; ++ } ++ ++ nctx->svcent = talloc_zero(nctx, struct nss_enum_ctx); ++ if (nctx->svcent == NULL) { ++ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize svcent context!\n"); ++ ret = ENOMEM; ++ goto fail; ++ } ++ + nctx->netgrent = sss_ptr_hash_create(nctx, NULL, NULL); + if (nctx->netgrent == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize netgroups table!\n"); +-- +2.19.1 + diff --git a/SOURCES/0050-Revert-IPA-use-forest-name-when-looking-up-the-Globa.patch b/SOURCES/0050-Revert-IPA-use-forest-name-when-looking-up-the-Globa.patch new file mode 100644 index 0000000..4483916 --- /dev/null +++ b/SOURCES/0050-Revert-IPA-use-forest-name-when-looking-up-the-Globa.patch @@ -0,0 +1,30 @@ +From d33ec64423087261fcc14acb5922793fadb83342 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 4 Dec 2018 13:08:11 +0100 +Subject: [PATCH 50/51] Revert "IPA: use forest name when looking up the Global + Catalog" + +This reverts commit 149174acae677d1e72a0da431bf0850d55f2ccb4. + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 9096fc01cca8fcaeb19c36a27f3a9fa09d60772a) +--- + src/providers/ipa/ipa_subdomains_server.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c +index e5ea4bd02..43a3053cb 100644 +--- a/src/providers/ipa/ipa_subdomains_server.c ++++ b/src/providers/ipa/ipa_subdomains_server.c +@@ -266,7 +266,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx, + DEBUG(SSSDBG_TRACE_ALL, "No extra attrs set.\n"); + } + +- gc_service_name = talloc_asprintf(ad_options, "sd_gc_%s", subdom->forest); ++ gc_service_name = talloc_asprintf(ad_options, "sd_gc_%s", subdom->name); + if (gc_service_name == NULL) { + talloc_free(ad_options); + return ENOMEM; +-- +2.19.1 + diff --git a/SOURCES/0051-ipa-use-only-the-global-catalog-service-of-the-fores.patch b/SOURCES/0051-ipa-use-only-the-global-catalog-service-of-the-fores.patch new file mode 100644 index 0000000..1ad7603 --- /dev/null +++ b/SOURCES/0051-ipa-use-only-the-global-catalog-service-of-the-fores.patch @@ -0,0 +1,104 @@ +From 74568bdde833f752187cb1a38b39715556c91279 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 4 Dec 2018 13:06:23 +0100 +Subject: [PATCH 51/51] ipa: use only the global catalog service of the forest + root + +While creating the domains and sub-domains each domain gets a global +catalog services assigned but only one should be used because the global +catalog is by definition responsible for the whole forest so it does not +make sense to use a global catalog service for each domain and in the +worst case connect to the same GC multiple times. + +In the AD provider this is simple because the GC service of the +configured domain AD_GC_SERVICE_NAME ("AD_GC") can be used. In the IPA +case all domains from the trusted forest are on the level of sub-domains +so we have to pick one. Since the forest root is linked from all domain +of the same forest it will be the most straight forward choice. + +Related to https://pagure.io/SSSD/sssd/issue/3902 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 62d671b874a66101c0f4bff39fc6d7f49cb8fca6) +--- + src/providers/ipa/ipa_subdomains_id.c | 50 +++++++++++++++++++++++++-- + 1 file changed, 47 insertions(+), 3 deletions(-) + +diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c +index a16eed284..48cf74460 100644 +--- a/src/providers/ipa/ipa_subdomains_id.c ++++ b/src/providers/ipa/ipa_subdomains_id.c +@@ -713,6 +713,52 @@ int ipa_get_subdom_acct_recv(struct tevent_req *req, int *dp_error_out) + return EOK; + } + ++static struct ad_id_ctx *ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx, ++ struct sss_domain_info *dom); ++ ++static struct sdap_id_conn_ctx ** ++ipa_ad_gc_conn_list(TALLOC_CTX *mem_ctx, struct ipa_id_ctx *ipa_ctx, ++ struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom) ++{ ++ struct ad_id_ctx *forest_root_ad_id_ctx; ++ struct sdap_id_conn_ctx **clist; ++ int cindex = 0; ++ ++ /* While creating the domains and sub-domains each domain gets a global ++ * catalog services assigned but only one should be used because the ++ * global catalog is by definition responsible for the whole forest so it ++ * does not make sense to use a global catalog service for each domain and ++ * in the worst case connect to the same GC multiple times. ++ * ++ * In the AD provider this is simple because the GC service of the ++ * configured domain AD_GC_SERVICE_NAME ("AD_GC") can be used. In the IPA ++ * case all domains from the trusted forest are on the level of ++ * sub-domains so we have to pick one. Since the forest root is linked ++ * from all domain of the same forest it will be the most straight forward ++ * choice. */ ++ forest_root_ad_id_ctx = ipa_get_ad_id_ctx(ipa_ctx, dom->forest_root); ++ if (forest_root_ad_id_ctx == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "Missing ad_id_ctx for forest root.\n"); ++ return NULL; ++ } ++ ++ clist = talloc_zero_array(mem_ctx, struct sdap_id_conn_ctx *, 3); ++ if (clist == NULL) return NULL; ++ ++ /* Always try GC first */ ++ if (dp_opt_get_bool(forest_root_ad_id_ctx->ad_options->basic, ++ AD_ENABLE_GC)) { ++ clist[cindex] = forest_root_ad_id_ctx->gc_ctx; ++ clist[cindex]->ignore_mark_offline = true; ++ clist[cindex]->no_mpg_user_fallback = true; ++ cindex++; ++ } ++ ++ clist[cindex] = ad_get_dom_ldap_conn(ad_ctx, dom); ++ ++ return clist; ++} ++ + /* IPA lookup for server mode. Directly to AD. */ + struct ipa_get_ad_acct_state { + int dp_error; +@@ -731,8 +777,6 @@ static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req); + static errno_t ipa_get_ad_ipa_membership_step(struct tevent_req *req); + static void ipa_id_get_groups_overrides_done(struct tevent_req *subreq); + static void ipa_get_ad_acct_done(struct tevent_req *subreq); +-static struct ad_id_ctx *ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx, +- struct sss_domain_info *dom); + + static struct tevent_req * + ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx, +@@ -785,7 +829,7 @@ ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx, + case BE_REQ_INITGROUPS: + case BE_REQ_BY_SECID: + case BE_REQ_GROUP: +- clist = ad_gc_conn_list(req, ad_id_ctx, state->obj_dom); ++ clist = ipa_ad_gc_conn_list(req, ipa_ctx, ad_id_ctx, state->obj_dom); + break; + default: + clist = ad_ldap_conn_list(req, ad_id_ctx, state->obj_dom); +-- +2.19.1 + diff --git a/SOURCES/0052-LDAP-minor-refactoring-in-auth_send-to-conform-to-ou.patch b/SOURCES/0052-LDAP-minor-refactoring-in-auth_send-to-conform-to-ou.patch new file mode 100644 index 0000000..c06a179 --- /dev/null +++ b/SOURCES/0052-LDAP-minor-refactoring-in-auth_send-to-conform-to-ou.patch @@ -0,0 +1,72 @@ +From 876f1cb87d1649d0681bf6475ab589287f15babb Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Thu, 22 Nov 2018 12:51:14 +0100 +Subject: [PATCH 52/54] LDAP: minor refactoring in auth_send() to conform to + our coding style + +Related: +https://pagure.io/SSSD/sssd/issue/3451 + +A tevent _send() function should only return NULL on ENOMEM, otherwise +it should mark the request as failed but return the req pointer. This +was not much of an issue, before, but the next patch will add another +function call to the auth_send call which would make error handling +awkward. + +Reviewed-by: Sumit Bose +(cherry picked from commit 09091b4b60456a989ecc8c3b6f76661a14c108ba) +--- + src/providers/ldap/ldap_auth.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c +index d40bc9414..c409353d9 100644 +--- a/src/providers/ldap/ldap_auth.c ++++ b/src/providers/ldap/ldap_auth.c +@@ -636,6 +636,7 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, + { + struct tevent_req *req; + struct auth_state *state; ++ errno_t ret; + + req = tevent_req_create(memctx, &state, struct auth_state); + if (!req) return NULL; +@@ -645,11 +646,11 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, + if (sss_authtok_get_type(authtok) == SSS_AUTHTOK_TYPE_SC_PIN + || sss_authtok_get_type(authtok) == SSS_AUTHTOK_TYPE_SC_KEYPAD) { + /* Tell frontend that we do not support Smartcard authentication */ +- tevent_req_error(req, ERR_SC_AUTH_NOT_SUPPORTED); ++ ret = ERR_SC_AUTH_NOT_SUPPORTED; + } else { +- tevent_req_error(req, ERR_AUTH_FAILED); ++ ret = ERR_AUTH_FAILED; + } +- return tevent_req_post(req, ev); ++ goto fail; + } + + state->ev = ev; +@@ -663,13 +664,17 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, + state->sdap_service = ctx->service; + } + +- if (!auth_connect_send(req)) goto fail; ++ if (auth_connect_send(req) == NULL) { ++ ret = ENOMEM; ++ goto fail; ++ } + + return req; + + fail: +- talloc_zfree(req); +- return NULL; ++ tevent_req_error(req, ret); ++ tevent_req_post(req, ev); ++ return req; + } + + static struct tevent_req *auth_connect_send(struct tevent_req *req) +-- +2.19.1 + diff --git a/SOURCES/0053-LDAP-Only-authenticate-the-auth-connection-if-we-nee.patch b/SOURCES/0053-LDAP-Only-authenticate-the-auth-connection-if-we-nee.patch new file mode 100644 index 0000000..7c781e7 --- /dev/null +++ b/SOURCES/0053-LDAP-Only-authenticate-the-auth-connection-if-we-nee.patch @@ -0,0 +1,131 @@ +From 7eb18ab68762d1b1ddbcbdc32dbcbd0df183d4f1 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Thu, 22 Nov 2018 12:17:51 +0100 +Subject: [PATCH 53/54] LDAP: Only authenticate the auth connection if we need + to look up user information + +Related: +https://pagure.io/SSSD/sssd/issue/3451 + +Commit add72860c7a7a2c418f4d8b6790b5caeaf7dfb7b initially addressed #3451 by +using the full sdap_cli_connect() request during LDAP authentication. This +was a good idea as it addressed the case where the authentication connection +must also look up some user information (typically with id_provider=proxy +where you don't know the DN to bind as during authentication), but this +approach also broke the use-case of id_provider=ldap and auth_provider=ldap +with ldap_sasl_auth=gssapi. + +This is because (for reason I don't know) AD doesn't like if you use +both GSSAPI and startTLS on the same connection. But the code would +force TLS during the authentication as a general measure to not transmit +passwords in the clear, but then, the connection would also see that +ldap_sasl_auth=gssapi is set and also bind with GSSAPI. + +This patch checks if the user DN is already known and if yes, then +doesn't authenticate the connection as the connection will then only be +used for the user simple bind. + +Reviewed-by: Sumit Bose +(cherry picked from commit 57fc60c9dc77698cf824813c36eb0f90d767b315) +--- + src/providers/ldap/ldap_auth.c | 53 +++++++++++++++++++++++++++------- + 1 file changed, 42 insertions(+), 11 deletions(-) + +diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c +index c409353d9..b4d045a65 100644 +--- a/src/providers/ldap/ldap_auth.c ++++ b/src/providers/ldap/ldap_auth.c +@@ -664,6 +664,18 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, + state->sdap_service = ctx->service; + } + ++ ret = get_user_dn(state, state->ctx->be->domain, ++ state->ctx->opts, state->username, &state->dn, ++ &state->pw_expire_type, &state->pw_expire_data); ++ if (ret == EAGAIN) { ++ DEBUG(SSSDBG_TRACE_FUNC, ++ "Need to look up the DN of %s later\n", state->username); ++ } else if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Cannot get user DN [%d]: %s\n", ret, sss_strerror(ret)); ++ goto fail; ++ } ++ + if (auth_connect_send(req) == NULL) { + ret = ENOMEM; + goto fail; +@@ -683,6 +695,8 @@ static struct tevent_req *auth_connect_send(struct tevent_req *req) + struct auth_state *state = tevent_req_data(req, + struct auth_state); + bool use_tls; ++ bool skip_conn_auth = false; ++ const char *sasl_mech; + + /* Check for undocumented debugging feature to disable TLS + * for authentication. This should never be used in production +@@ -695,10 +709,33 @@ static struct tevent_req *auth_connect_send(struct tevent_req *req) + "for debugging purposes only."); + } + ++ if (state->dn != NULL) { ++ /* In case the user's DN is known, the connection will only be used ++ * to bind as the user to perform the authentication. In that case, ++ * we don't need to authenticate the connection, because we're not ++ * looking up any information using the connection. This might be ++ * needed e.g. in case both ID and AUTH providers are set to LDAP ++ * and the server is AD, because otherwise the connection would ++ * both do a startTLS and later bind using GSSAPI which doesn't work ++ * well with AD. ++ */ ++ skip_conn_auth = true; ++ } ++ ++ if (skip_conn_auth == false) { ++ sasl_mech = dp_opt_get_string(state->ctx->opts->basic, ++ SDAP_SASL_MECH); ++ if (sasl_mech && strcasecmp(sasl_mech, "GSSAPI") == 0) { ++ /* Don't force TLS on if we're told to use GSSAPI */ ++ use_tls = false; ++ } ++ } ++ + subreq = sdap_cli_connect_send(state, state->ev, state->ctx->opts, + state->ctx->be, + state->sdap_service, false, +- use_tls ? CON_TLS_ON : CON_TLS_OFF, false); ++ use_tls ? CON_TLS_ON : CON_TLS_OFF, ++ skip_conn_auth); + + if (subreq == NULL) { + tevent_req_error(req, ENOMEM); +@@ -739,15 +776,7 @@ static void auth_connect_done(struct tevent_req *subreq) + return; + } + +- ret = get_user_dn(state, state->ctx->be->domain, +- state->ctx->opts, state->username, &state->dn, +- &state->pw_expire_type, &state->pw_expire_data); +- if (ret == EOK) { +- /* All required user data was pre-cached during an identity lookup. +- * We can proceed with the bind */ +- auth_do_bind(req); +- return; +- } else if (ret == EAGAIN) { ++ if (state->dn == NULL) { + /* The cached user entry was missing the bind DN. Need to look + * it up based on user name in order to perform the bind */ + subreq = get_user_dn_send(req, state->ev, state->ctx->be->domain, +@@ -760,7 +789,9 @@ static void auth_connect_done(struct tevent_req *subreq) + return; + } + +- tevent_req_error(req, ret); ++ /* All required user data was pre-cached during an identity lookup. ++ * We can proceed with the bind */ ++ auth_do_bind(req); + return; + } + +-- +2.19.1 + diff --git a/SOURCES/0054-LDAP-Log-the-encryption-used-during-LDAP-authenticat.patch b/SOURCES/0054-LDAP-Log-the-encryption-used-during-LDAP-authenticat.patch new file mode 100644 index 0000000..5a1c2bf --- /dev/null +++ b/SOURCES/0054-LDAP-Log-the-encryption-used-during-LDAP-authenticat.patch @@ -0,0 +1,60 @@ +From 1a7c6ab6efce3720d27def426aad49ee99eb339d Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Mon, 26 Nov 2018 12:38:40 +0100 +Subject: [PATCH 54/54] LDAP: Log the encryption used during LDAP + authentication + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 6f113c7ddeaa5c82558e10118b499d22bf7a2b14) +--- + src/providers/ldap/ldap_auth.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c +index b4d045a65..4666dbfbb 100644 +--- a/src/providers/ldap/ldap_auth.c ++++ b/src/providers/ldap/ldap_auth.c +@@ -747,6 +747,31 @@ static struct tevent_req *auth_connect_send(struct tevent_req *req) + return subreq; + } + ++static void check_encryption(LDAP *ldap) ++{ ++ ber_len_t sasl_ssf = 0; ++ int tls_inplace = 0; ++ int ret; ++ ++ ret = ldap_get_option(ldap, LDAP_OPT_X_SASL_SSF, &sasl_ssf); ++ if (ret != LDAP_SUCCESS) { ++ DEBUG(SSSDBG_TRACE_LIBS, "ldap_get_option failed to get sasl ssf, " ++ "assuming SASL is not used.\n"); ++ } ++ ++ tls_inplace = ldap_tls_inplace(ldap); ++ ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Encryption used: SASL SSF [%lu] tls_inplace [%s].\n", sasl_ssf, ++ tls_inplace == 1 ? "TLS inplace" : "TLS NOT inplace"); ++ ++ if (sasl_ssf <= 1 && tls_inplace != 1) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "No encryption detected on LDAP connection.\n"); ++ sss_log(SSS_LOG_CRIT, "No encryption detected on LDAP connection.\n"); ++ } ++} ++ + static void auth_connect_done(struct tevent_req *subreq) + { + struct tevent_req *req = tevent_req_callback_data(subreq, +@@ -776,6 +801,8 @@ static void auth_connect_done(struct tevent_req *subreq) + return; + } + ++ check_encryption(state->sh->ldap); ++ + if (state->dn == NULL) { + /* The cached user entry was missing the bind DN. Need to look + * it up based on user name in order to perform the bind */ +-- +2.19.1 + diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec index 2b87898..75d23a1 100644 --- a/SPECS/sssd.spec +++ b/SPECS/sssd.spec @@ -48,7 +48,7 @@ Name: sssd Version: 1.16.2 -Release: 13%{?dist} +Release: 13%{?dist}.5 Group: Applications/System Summary: System Security Services Daemon License: GPLv3+ @@ -103,6 +103,14 @@ Patch0043: 0043-CRYPTO-Save-prefix-in-s3crypt_sha512.patch Patch0044: 0044-crypto-tests-Add-unit-test-for-s3crypt_sha512.patch Patch0045: 0045-SSS_CERT-Close-file-descriptors-after-executing-p11_.patch Patch0046: 0046-SELINUX-Also-call-is_selinux_enabled-as-a-check-for-.patch +Patch0047: 0047-SELINUX-Always-add-SELinux-user-to-the-semanage-data.patch +Patch0048: 0048-sudo-respect-case-sensitivity-in-sudo-responder.patch +Patch0049: 0049-nss-use-enumeration-context-as-talloc-parent-for-cac.patch +Patch0050: 0050-Revert-IPA-use-forest-name-when-looking-up-the-Globa.patch +Patch0051: 0051-ipa-use-only-the-global-catalog-service-of-the-fores.patch +Patch0052: 0052-LDAP-minor-refactoring-in-auth_send-to-conform-to-ou.patch +Patch0053: 0053-LDAP-Only-authenticate-the-auth-connection-if-we-nee.patch +Patch0054: 0054-LDAP-Log-the-encryption-used-during-LDAP-authenticat.patch #This patch should not be removed in RHEL-7 Patch999: 0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec @@ -1255,6 +1263,25 @@ systemctl try-restart sssd >/dev/null 2>&1 || : } %changelog +* Tue Dec 18 2018 Michal Židek - 1.16.3-5 +- Resolves: rhbz#1659507 - SSSD's LDAP authentication provider does not work + if ID provider is authenticated with GSSAPI [rhel-7.6.z] + +* Tue Dec 18 2018 Michal Židek - 1.16.3-4 +- Resolves: rhbz#1659083 - SSSD must be cleared/restarted periodically in + order to retrieve AD users through IPA Trust [rhel-7.6.z] + +* Tue Dec 18 2018 Michal Židek - 1.16.3-3 +- Resolves: rhbz#1656833 - sssd_nss memory leak [rhel-7.6.z] + +* Wed Nov 28 2018 Michal Židek - 1.16.3-2 +- Resolves: Bug 1649784 - SSSD not fetching all sudo rules from + AD [rhel-7.6.z] + +* Wed Nov 14 2018 Michal Židek - 1.16.3-1 +- Resolves: rhbz#1645047 - sssd only sets the SELinux login context if it + differs from the default [rhel-7.6.z] + * Wed Sep 5 2018 Jakub Hrozek - 1.16.2-13 - Resolves: rhbz#1593756 - sssd needs to require a newer version of libtalloc and libtevent to avoid an issue