From 664ae9d2247b5139d2286975228baa0cea39a8e4 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Wed, 20 Oct 2021 13:59:40 +0200 Subject: [PATCH 81/83] ad: make ad_srv_plugin_ctx_switch_site() public MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the name of the AD DCs are given explicitly with the ad_server option the forest and site lookups are not done in the discovery phase, which is skipped, but with a netlogon query on the current connection. This patch makes sure the results are stored in the same way as during the discovery step. Resolves: https://github.com/SSSD/sssd/issues/5820 Reviewed-by: Pavel Březina (cherry picked from commit 918abaf37d7f13d72b29863933e133bcbd24d87c) Reviewed-by: Pavel Březina --- src/providers/ad/ad_common.c | 48 +++++++++++++++++++++ src/providers/ad/ad_common.h | 3 ++ src/providers/ad/ad_domain_info.h | 1 - src/providers/ad/ad_srv.c | 70 ++++++------------------------- src/providers/ad/ad_subdomains.c | 34 ++++++++++++++- 5 files changed, 96 insertions(+), 60 deletions(-) diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c index c99c4d110..4463349e4 100644 --- a/src/providers/ad/ad_common.c +++ b/src/providers/ad/ad_common.c @@ -1554,3 +1554,51 @@ done: return ret; } + +errno_t +ad_options_switch_site(struct ad_options *ad_options, struct be_ctx *be_ctx, + const char *new_site, const char *new_forest) +{ + const char *site; + const char *forest; + errno_t ret; + + /* Switch forest. */ + if (new_forest != NULL + && (ad_options->current_forest == NULL + || strcmp(ad_options->current_forest, new_forest) != 0)) { + forest = talloc_strdup(ad_options, new_forest); + if (forest == NULL) { + return ENOMEM; + } + + talloc_zfree(ad_options->current_forest); + ad_options->current_forest = forest; + } + + if (new_site == NULL) { + return EOK; + } + + if (ad_options->current_site != NULL + && strcmp(ad_options->current_site, new_site) == 0) { + return EOK; + } + + site = talloc_strdup(ad_options, new_site); + if (site == NULL) { + return ENOMEM; + } + + talloc_zfree(ad_options->current_site); + ad_options->current_site = site; + + ret = sysdb_set_site(be_ctx->domain, ad_options->current_site); + if (ret != EOK) { + /* Not fatal. */ + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to store site information " + "[%d]: %s\n", ret, sss_strerror(ret)); + } + + return EOK; +} diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h index 311b84f4c..08fcc00fd 100644 --- a/src/providers/ad/ad_common.h +++ b/src/providers/ad/ad_common.h @@ -238,4 +238,7 @@ errno_t ad_inherit_opts_if_needed(struct dp_option *parent_opts, errno_t ad_refresh_init(struct be_ctx *be_ctx, struct ad_id_ctx *id_ctx); +errno_t +ad_options_switch_site(struct ad_options *ad_options, struct be_ctx *be_ctx, + const char *new_site, const char *new_forest); #endif /* AD_COMMON_H_ */ diff --git a/src/providers/ad/ad_domain_info.h b/src/providers/ad/ad_domain_info.h index 631e543f5..cf601cff6 100644 --- a/src/providers/ad/ad_domain_info.h +++ b/src/providers/ad/ad_domain_info.h @@ -39,5 +39,4 @@ ad_domain_info_recv(struct tevent_req *req, char **_id, char **_site, char **_forest); - #endif /* _AD_DOMAIN_INFO_H_ */ diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c index a10c6a247..d45f1601e 100644 --- a/src/providers/ad/ad_srv.c +++ b/src/providers/ad/ad_srv.c @@ -196,55 +196,6 @@ fail: return NULL; } -static errno_t -ad_srv_plugin_ctx_switch_site(struct ad_srv_plugin_ctx *ctx, - const char *new_site, - const char *new_forest) -{ - const char *site; - const char *forest; - errno_t ret; - - /* Switch forest. */ - if (new_forest != NULL - && (ctx->ad_options->current_forest == NULL - || strcmp(ctx->ad_options->current_forest, new_forest) != 0)) { - forest = talloc_strdup(ctx->ad_options, new_forest); - if (forest == NULL) { - return ENOMEM; - } - - talloc_zfree(ctx->ad_options->current_forest); - ctx->ad_options->current_forest = forest; - } - - if (new_site == NULL) { - return EOK; - } - - if (ctx->ad_options->current_site != NULL - && strcmp(ctx->ad_options->current_site, new_site) == 0) { - return EOK; - } - - site = talloc_strdup(ctx->ad_options, new_site); - if (site == NULL) { - return ENOMEM; - } - - talloc_zfree(ctx->ad_options->current_site); - ctx->ad_options->current_site = site; - - ret = sysdb_set_site(ctx->be_ctx->domain, ctx->ad_options->current_site); - if (ret != EOK) { - /* Not fatal. */ - DEBUG(SSSDBG_MINOR_FAILURE, "Unable to store site information " - "[%d]: %s\n", ret, sss_strerror(ret)); - } - - return EOK; -} - struct ad_srv_plugin_state { struct tevent_context *ev; struct ad_srv_plugin_ctx *ctx; @@ -382,16 +333,19 @@ static void ad_srv_plugin_ping_done(struct tevent_req *subreq) /* Remember current site so it can be used during next lookup so * we can contact directory controllers within a known reachable * site first. */ - ret = ad_srv_plugin_ctx_switch_site(state->ctx, state->site, - state->forest); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set site [%d]: %s\n", - ret, sss_strerror(ret)); - goto done; - } + if (state->site != NULL) { + ret = ad_options_switch_site(state->ctx->ad_options, + state->ctx->be_ctx, + state->site, state->forest); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set site [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } - /* Do not renew the site again unless we go offline. */ - state->ctx->renew_site = false; + /* Do not renew the site again unless we go offline. */ + state->ctx->renew_site = false; + } if (strcmp(state->service, "gc") == 0) { if (state->forest != NULL) { diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c index 562047a02..e4e248c1d 100644 --- a/src/providers/ad/ad_subdomains.c +++ b/src/providers/ad/ad_subdomains.c @@ -2080,13 +2080,15 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq) const char *realm; char *master_sid; char *flat_name; + char *site = NULL; errno_t ret; + char *ad_site_override = NULL; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_subdomains_refresh_state); ret = ad_domain_info_recv(subreq, state, &flat_name, &master_sid, - NULL, &state->forest); + &site, &state->forest); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get master domain information " @@ -2112,6 +2114,36 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq) } } + /* If the site was not discovered during the DNS discovery, e.g. because + * the server name was given explicitly in sssd.conf, we try to set the + * site here. */ + if (state->ad_options->current_site == NULL) { + /* Ignore AD site found in netlogon attribute if specific site is set in + * configuration file. */ + ad_site_override = dp_opt_get_string(state->ad_options->basic, AD_SITE); + if (ad_site_override != NULL) { + DEBUG(SSSDBG_TRACE_INTERNAL, + "Ignoring AD site found by DNS discovery: '%s', " + "using configured value: '%s' instead.\n", + site, ad_site_override); + site = ad_site_override; + } + + if (site != NULL) { + ret = ad_options_switch_site(state->ad_options, state->be_ctx, site, + state->forest); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Failed to store forest and site name, " + "will try again after a new lookup.\n"); + } + } else { + DEBUG(SSSDBG_MINOR_FAILURE, + "Site name currently not available will try again later. " + "The site name can be added manually my setting 'ad_site' " + "in sssd.conf.\n"); + } + } + realm = dp_opt_get_cstring(state->ad_options->basic, AD_KRB5_REALM); if (realm == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm.\n"); -- 2.26.3