Blob Blame History Raw
From 4ff821a9a37cb43f9c34faef4b5ccbdc8dc6a7e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Wed, 22 Mar 2017 13:40:20 +0100
Subject: [PATCH 48/54] IPA: Get ipaDomainsResolutionOrder from ipaConfig
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

ipaDomainsResolutionOrder provides a list of domains that have to be
looked up firstly during cache_req searches.

This commit only fetches this list from the server and stores its value
at sysdb so we can make use of it later on this patch series.

There are no tests for newly introduced sysdb methods are those are
basically only calling sysdb_update_domain_resolution_order(),
sysdb_get_domain_resolution_order() and
sysdb_get_use_domain_resolution_order() which are have tests written
for.

Related:
https://pagure.io/SSSD/sssd/issue/3001

Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>

Reviewed-by: Sumit Bose <sbose@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
 src/db/sysdb.h                     |  11 +++
 src/db/sysdb_subdomains.c          |  67 +++++++++++++++
 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 42d2857ed7765c17e7d84b0da93ed07758fbe012..75a07d4d2effb028ec654342113f8478e1eba10e 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 916dbba153d8c08837425f6fd29a20f5a6aa9fc9..e2a4f7bb1fcdf20b6b7e04efc7f396d1c3d08f0f 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 a07b88fe2f499353293ba90345552413c9792f4b..01a0ce812d861b24565d2f71f27d6b8ceb2965bc 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);
 }
 
-- 
2.9.3