diff options
-rw-r--r-- | src/db/sysdb.h | 11 | ||||
-rw-r--r-- | src/db/sysdb_subdomains.c | 67 | ||||
-rw-r--r-- | src/providers/ipa/ipa_subdomains.c | 168 |
3 files changed, 234 insertions, 12 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 42d2857ed..75a07d4d2 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -489,6 +489,17 @@ int sysdb_transaction_cancel(struct sysdb_ctx *sysdb); /* functions related to subdomains */ errno_t sysdb_domain_create(struct sysdb_ctx *sysdb, const char *domain_name); +errno_t sysdb_domain_get_domain_resolution_order( + TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *domain_name, + const char **_domain_resolution_order); + +errno_t sysdb_domain_update_domain_resolution_order( + struct sysdb_ctx *sysdb, + const char *domain_name, + const char *domain_resolution_order); + errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, const char *name, const char *realm, const char *flat_name, const char *domain_id, diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c index 916dbba15..e2a4f7bb1 100644 --- a/src/db/sysdb_subdomains.c +++ b/src/db/sysdb_subdomains.c @@ -22,6 +22,7 @@ #include "util/util.h" #include "db/sysdb_private.h" +#include "db/sysdb_domain_resolution_order.h" static errno_t check_subdom_config_file(struct confdb_ctx *confdb, @@ -1210,3 +1211,69 @@ done: talloc_free(tmp_ctx); return ret; } + +errno_t +sysdb_domain_get_domain_resolution_order(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *domain_name, + const char **_domain_resolution_order) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_dn *dn; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, domain_name); + if (dn == NULL) { + ret = ENOMEM; + goto done; + } + + ret = sysdb_get_domain_resolution_order(mem_ctx, sysdb, dn, + _domain_resolution_order); + +done: + talloc_free(tmp_ctx); + return ret; +} + +errno_t +sysdb_domain_update_domain_resolution_order(struct sysdb_ctx *sysdb, + const char *domain_name, + const char *domain_resolution_order) +{ + + TALLOC_CTX *tmp_ctx; + struct ldb_dn *dn; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, domain_name); + if (dn == NULL) { + ret = ENOMEM; + goto done; + } + + ret = sysdb_update_domain_resolution_order(sysdb, dn, + domain_resolution_order); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "sysdb_update_domain_resolution_order() failed [%d]: [%s].\n", + ret, sss_strerror(ret)); + goto done; + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index a07b88fe2..01a0ce812 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -29,6 +29,7 @@ #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_id.h" #include "providers/ipa/ipa_opts.h" +#include "providers/ipa/ipa_config.h" #include <ctype.h> @@ -51,6 +52,8 @@ #define IPA_ASSIGNED_ID_VIEW "ipaAssignedIDView" +#define IPA_DOMAIN_RESOLUTION_ORDER "ipaDomainResolutionOrder" + /* do not refresh more often than every 5 seconds for now */ #define IPA_SUBDOMAIN_REFRESH_LIMIT 5 @@ -1681,6 +1684,117 @@ static errno_t ipa_subdomains_view_name_recv(struct tevent_req *req) return EOK; } +struct ipa_domain_resolution_order_state { + struct sss_domain_info *domain; +}; + +static void ipa_domain_resolution_order_done(struct tevent_req *subreq); + +static struct tevent_req * +ipa_domain_resolution_order_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct ipa_subdomains_ctx *sd_ctx, + struct sdap_handle *sh) +{ + struct ipa_domain_resolution_order_state *state; + struct tevent_req *subreq; + struct tevent_req *req; + const char *attrs[] = {IPA_DOMAIN_RESOLUTION_ORDER, NULL}; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, + struct ipa_domain_resolution_order_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); + return NULL; + } + + state->domain = sd_ctx->be_ctx->domain; + + subreq = ipa_get_config_send(state, ev, sh, sd_ctx->sdap_id_ctx->opts, + state->domain->name, attrs); + if (subreq == NULL) { + ret = ENOMEM; + goto immediately; + } + + tevent_req_set_callback(subreq, ipa_domain_resolution_order_done, req); + + return req; + +immediately: + if (ret == EOK) { + tevent_req_done(req); + } else { + tevent_req_error(req, ret); + } + tevent_req_post(req, ev); + + return req; +} + +static void ipa_domain_resolution_order_done(struct tevent_req *subreq) +{ + struct ipa_domain_resolution_order_state *state; + struct tevent_req *req; + struct sysdb_attrs *config = NULL; + const char *domain_resolution_order = NULL; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ipa_domain_resolution_order_state); + + ret = ipa_get_config_recv(subreq, state, &config); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Failed to get the domains' resolution order configuration " + "from the server [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + if (config != NULL) { + ret = sysdb_attrs_get_string(config, IPA_DOMAIN_RESOLUTION_ORDER, + &domain_resolution_order); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_OP_FAILURE, + "Failed to get the domains' resolution order configuration " + "value [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } else if (ret == ENOENT) { + domain_resolution_order = NULL; + } + } + + ret = sysdb_domain_update_domain_resolution_order( + state->domain->sysdb, state->domain->name, + domain_resolution_order); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "sysdb_domain_update_resolution_order() [%d]: [%s].\n", + ret, sss_strerror(ret)); + goto done; + } + + ret = EOK; + +done: + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); +} + +static errno_t ipa_domain_resolution_order_recv(struct tevent_req *req) +{ + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; +} struct ipa_subdomains_refresh_state { struct tevent_context *ev; @@ -1695,6 +1809,7 @@ static void ipa_subdomains_refresh_certmap_done(struct tevent_req *subreq); static void ipa_subdomains_refresh_master_done(struct tevent_req *subreq); static void ipa_subdomains_refresh_slave_done(struct tevent_req *subreq); static void ipa_subdomains_refresh_view_done(struct tevent_req *subreq); +static void ipa_domain_refresh_resolution_order_done(struct tevent_req *subreq); static struct tevent_req * ipa_subdomains_refresh_send(TALLOC_CTX *mem_ctx, @@ -1916,7 +2031,6 @@ static void ipa_subdomains_refresh_view_done(struct tevent_req *subreq) { struct ipa_subdomains_refresh_state *state; struct tevent_req *req; - int dp_error; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); @@ -1924,24 +2038,55 @@ static void ipa_subdomains_refresh_view_done(struct tevent_req *subreq) ret = ipa_subdomains_view_name_recv(subreq); talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to get view name [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + + subreq = ipa_domain_resolution_order_send(state, state->ev, state->sd_ctx, + sdap_id_op_handle(state->sdap_op)); + if (subreq == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + + tevent_req_set_callback(subreq, + ipa_domain_refresh_resolution_order_done, + req); +} + +static void +ipa_domain_refresh_resolution_order_done(struct tevent_req *subreq) +{ + struct ipa_subdomains_refresh_state *state; + struct tevent_req *req; + int dp_error; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ipa_subdomains_refresh_state); + + ret = ipa_domain_resolution_order_recv(subreq); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Unable to get the domains order resolution [%d]: %s\n", + ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = ipa_subdomains_refresh_retry(req); - if (ret != EOK) { - goto done; - } - return; } else if (dp_error == DP_ERR_OFFLINE) { ret = ERR_OFFLINE; - goto done; - } else if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get view name " - "[%d]: %s\n", ret, sss_strerror(ret)); - goto done; } -done: if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Unable to refresh subdomains [%d]: %s\n", ret, sss_strerror(ret)); @@ -1949,7 +2094,6 @@ done: return; } - DEBUG(SSSDBG_TRACE_FUNC, "Subdomains refreshed.\n"); tevent_req_done(req); } |