Blame SOURCES/0050-IPA-Get-ipaDomainsResolutionOrder-from-IPA-ID-View.patch

ecf709
From d36c2acde1f29865c2cefedebc214ba48bb227e7 Mon Sep 17 00:00:00 2001
ecf709
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
ecf709
Date: Fri, 24 Mar 2017 17:46:04 +0100
ecf709
Subject: [PATCH 50/54] IPA: Get ipaDomainsResolutionOrder from IPA ID View
ecf709
MIME-Version: 1.0
ecf709
Content-Type: text/plain; charset=UTF-8
ecf709
Content-Transfer-Encoding: 8bit
ecf709
ecf709
ipaDomainsResolutionOrder provides a list of domains that have to be
ecf709
looked up firstly during cache_req searches.
ecf709
ecf709
This commit only fetches this list from the server and stores its value
ecf709
at sysdb so we can make use of it later on this patch series.
ecf709
ecf709
There are no tests for newly introduced sysdb methods are those are
ecf709
basically only calling sysdb_update_domain_resolution_order(),
ecf709
sysdb_get_domain_resolution_order() and
ecf709
sysdb_get_use_domain_resolution_order() which are have tests written
ecf709
for.
ecf709
ecf709
Related:
ecf709
https://pagure.io/SSSD/sssd/issue/3001
ecf709
ecf709
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
ecf709
ecf709
Reviewed-by: Sumit Bose <sbose@redhat.com>
ecf709
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
ecf709
---
ecf709
 src/db/sysdb.h                     |   9 ++
ecf709
 src/db/sysdb_views.c               |  66 ++++++++++++++
ecf709
 src/providers/ipa/ipa_subdomains.c | 182 +++++++++++++++++++++++++++++++++++++
ecf709
 3 files changed, 257 insertions(+)
ecf709
ecf709
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
ecf709
index 75a07d4d2effb028ec654342113f8478e1eba10e..62c561be9452a284a8ddf8ebb45720265852c8b0 100644
ecf709
--- a/src/db/sysdb.h
ecf709
+++ b/src/db/sysdb.h
ecf709
@@ -533,6 +533,15 @@ errno_t sysdb_update_view_name(struct sysdb_ctx *sysdb, const char *view_name);
ecf709
 errno_t sysdb_get_view_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
ecf709
                             char **view_name);
ecf709
 
ecf709
+errno_t sysdb_update_view_domain_resolution_order(
ecf709
+                                        struct sysdb_ctx *sysdb,
ecf709
+                                        const char *domain_resolution_order);
ecf709
+
ecf709
+errno_t sysdb_get_view_domain_resolution_order(
ecf709
+                                        TALLOC_CTX *mem_ctx,
ecf709
+                                        struct sysdb_ctx *sysdb,
ecf709
+                                        const char **_domain_resolution_order);
ecf709
+
ecf709
 static inline bool is_default_view(const char *view_name)
ecf709
 {
ecf709
     /* NULL is treated as default */
ecf709
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
ecf709
index 1c416dd14049237e9f35d52f154035e3ff861469..20db9b06183d68b33bb19f498513d7f5cf84b1cf 100644
ecf709
--- a/src/db/sysdb_views.c
ecf709
+++ b/src/db/sysdb_views.c
ecf709
@@ -22,6 +22,9 @@
ecf709
 #include "util/util.h"
ecf709
 #include "util/cert.h"
ecf709
 #include "db/sysdb_private.h"
ecf709
+#include "db/sysdb_domain_resolution_order.h"
ecf709
+
ecf709
+#define SYSDB_VIEWS_BASE "cn=views,cn=sysdb"
ecf709
 
ecf709
 /* In general is should not be possible that there is a view container without
ecf709
  * a view name set. But to be on the safe side we return both information
ecf709
@@ -179,6 +182,69 @@ done:
ecf709
     return ret;
ecf709
 }
ecf709
 
ecf709
+errno_t
ecf709
+sysdb_get_view_domain_resolution_order(TALLOC_CTX *mem_ctx,
ecf709
+                                       struct sysdb_ctx *sysdb,
ecf709
+                                       const char **_domain_resolution_order)
ecf709
+{
ecf709
+    TALLOC_CTX *tmp_ctx;
ecf709
+    struct ldb_dn *dn;
ecf709
+    errno_t ret;
ecf709
+
ecf709
+    tmp_ctx = talloc_new(NULL);
ecf709
+    if (tmp_ctx == NULL) {
ecf709
+        return ENOMEM;
ecf709
+    }
ecf709
+
ecf709
+    dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_VIEWS_BASE);
ecf709
+    if (dn == NULL) {
ecf709
+        ret = ENOMEM;
ecf709
+        goto done;
ecf709
+    }
ecf709
+
ecf709
+    ret = sysdb_get_domain_resolution_order(mem_ctx, sysdb, dn,
ecf709
+                                            _domain_resolution_order);
ecf709
+
ecf709
+done:
ecf709
+    talloc_free(tmp_ctx);
ecf709
+    return ret;
ecf709
+}
ecf709
+
ecf709
+errno_t
ecf709
+sysdb_update_view_domain_resolution_order(struct sysdb_ctx *sysdb,
ecf709
+                                          const char *domain_resolution_order)
ecf709
+{
ecf709
+    TALLOC_CTX *tmp_ctx;
ecf709
+    struct ldb_dn *dn;
ecf709
+    errno_t ret;
ecf709
+
ecf709
+    tmp_ctx = talloc_new(NULL);
ecf709
+    if (tmp_ctx == NULL) {
ecf709
+        return ENOMEM;
ecf709
+    }
ecf709
+
ecf709
+    dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_VIEWS_BASE);
ecf709
+    if (dn == NULL) {
ecf709
+        ret = ENOMEM;
ecf709
+        goto done;
ecf709
+    }
ecf709
+
ecf709
+    ret = sysdb_update_domain_resolution_order(sysdb, dn,
ecf709
+                                               domain_resolution_order);
ecf709
+    if (ret != EOK) {
ecf709
+        DEBUG(SSSDBG_OP_FAILURE,
ecf709
+              "sysdb_update_domain_resolution_order() failed [%d]: [%s].\n",
ecf709
+              ret, sss_strerror(ret));
ecf709
+        goto done;
ecf709
+    }
ecf709
+
ecf709
+    ret = EOK;
ecf709
+
ecf709
+done:
ecf709
+    talloc_free(tmp_ctx);
ecf709
+    return ret;
ecf709
+}
ecf709
+
ecf709
 errno_t sysdb_delete_view_tree(struct sysdb_ctx *sysdb, const char *view_name)
ecf709
 {
ecf709
     struct ldb_dn *dn;
ecf709
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
ecf709
index bf6f6ab1fa8bfff7ea102dd219c9ddbbab065b2b..ef348adf4a36e870f44387bd700f5c2beea3bfd6 100644
ecf709
--- a/src/providers/ipa/ipa_subdomains.c
ecf709
+++ b/src/providers/ipa/ipa_subdomains.c
ecf709
@@ -1684,6 +1684,151 @@ static errno_t ipa_subdomains_view_name_recv(struct tevent_req *req)
ecf709
     return EOK;
ecf709
 }
ecf709
 
ecf709
+struct ipa_subdomains_view_domain_resolution_order_state {
ecf709
+    struct sss_domain_info *domain;
ecf709
+    const char *view_name;
ecf709
+};
ecf709
+
ecf709
+static void
ecf709
+ipa_subdomains_view_domain_resolution_order_done(struct tevent_req *subreq);
ecf709
+
ecf709
+static struct tevent_req *
ecf709
+ipa_subdomains_view_domain_resolution_order_send(
ecf709
+                                            TALLOC_CTX *mem_ctx,
ecf709
+                                            struct tevent_context *ev,
ecf709
+                                            struct ipa_subdomains_ctx *sd_ctx,
ecf709
+                                            struct sdap_handle *sh)
ecf709
+{
ecf709
+    struct ipa_subdomains_view_domain_resolution_order_state *state;
ecf709
+    struct tevent_req *subreq;
ecf709
+    struct tevent_req *req;
ecf709
+    const char *attrs[] = { IPA_DOMAIN_RESOLUTION_ORDER, NULL };
ecf709
+    char *ldap_basedn;
ecf709
+    char *base;
ecf709
+    errno_t ret;
ecf709
+
ecf709
+    req = tevent_req_create(mem_ctx, &state,
ecf709
+                    struct ipa_subdomains_view_domain_resolution_order_state);
ecf709
+    if (req == NULL) {
ecf709
+        DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
ecf709
+        return NULL;
ecf709
+    }
ecf709
+
ecf709
+    state->domain = sd_ctx->be_ctx->domain;
ecf709
+    state->view_name = sd_ctx->ipa_id_ctx->view_name;
ecf709
+
ecf709
+    ret = domain_to_basedn(state, sd_ctx->be_ctx->domain->name, &ldap_basedn);
ecf709
+    if (ret != EOK) {
ecf709
+        DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
ecf709
+        goto immediately;
ecf709
+    }
ecf709
+
ecf709
+    base = talloc_asprintf(state, "cn=%s,cn=views,cn=accounts,%s",
ecf709
+                           sd_ctx->ipa_id_ctx->view_name, ldap_basedn);
ecf709
+    if (base == NULL) {
ecf709
+        DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
ecf709
+        ret = ENOMEM;
ecf709
+        goto immediately;
ecf709
+    }
ecf709
+
ecf709
+    subreq = sdap_get_generic_send(
ecf709
+                            state, ev, sd_ctx->sdap_id_ctx->opts, sh,
ecf709
+                            base, LDAP_SCOPE_BASE, NULL, attrs, NULL, 0,
ecf709
+                            dp_opt_get_int(sd_ctx->sdap_id_ctx->opts->basic,
ecf709
+                                           SDAP_ENUM_SEARCH_TIMEOUT),
ecf709
+                            false);
ecf709
+    if (subreq == NULL) {
ecf709
+        ret = ENOMEM;
ecf709
+        goto immediately;
ecf709
+    }
ecf709
+
ecf709
+    tevent_req_set_callback(subreq, ipa_subdomains_view_domain_resolution_order_done,
ecf709
+                            req);
ecf709
+
ecf709
+    return req;
ecf709
+
ecf709
+immediately:
ecf709
+    if (ret == EOK) {
ecf709
+        tevent_req_done(req);
ecf709
+    } else {
ecf709
+        tevent_req_error(req, ret);
ecf709
+    }
ecf709
+    tevent_req_post(req, ev);
ecf709
+
ecf709
+    return req;
ecf709
+}
ecf709
+
ecf709
+static void
ecf709
+ipa_subdomains_view_domain_resolution_order_done(struct tevent_req *subreq)
ecf709
+{
ecf709
+    struct ipa_subdomains_view_domain_resolution_order_state *state;
ecf709
+    struct tevent_req *req;
ecf709
+    size_t reply_count;
ecf709
+    struct sysdb_attrs **reply;
ecf709
+    const char *domain_resolution_order;
ecf709
+    errno_t ret;
ecf709
+
ecf709
+    req = tevent_req_callback_data(subreq, struct tevent_req);
ecf709
+    state = tevent_req_data(req,
ecf709
+                    struct ipa_subdomains_view_domain_resolution_order_state);
ecf709
+
ecf709
+    ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
ecf709
+    talloc_zfree(subreq);
ecf709
+    if (ret != EOK) {
ecf709
+        DEBUG(SSSDBG_OP_FAILURE, "Unable to get view name [%d]: %s\n",
ecf709
+              ret, sss_strerror(ret));
ecf709
+        goto done;
ecf709
+    }
ecf709
+
ecf709
+    if (reply_count > 1) {
ecf709
+        DEBUG(SSSDBG_CRIT_FAILURE, "More than one object returned.\n");
ecf709
+        ret = EINVAL;
ecf709
+        goto done;
ecf709
+    } else if (reply_count == 0) {
ecf709
+        domain_resolution_order = NULL;
ecf709
+    } else {
ecf709
+        /* reply_count == 1 */
ecf709
+        ret = sysdb_attrs_get_string(reply[0], IPA_DOMAIN_RESOLUTION_ORDER,
ecf709
+                                     &domain_resolution_order);
ecf709
+        if (ret != EOK && ret != ENOENT) {
ecf709
+            DEBUG(SSSDBG_OP_FAILURE,
ecf709
+                  "Failed to get the view domains' resolution order "
ecf709
+                  "configuration value for view [%s] [%d]: %s\n",
ecf709
+                  state->view_name, ret, sss_strerror(ret));
ecf709
+            goto done;
ecf709
+        } else if (ret == ENOENT) {
ecf709
+            domain_resolution_order = NULL;
ecf709
+        }
ecf709
+    }
ecf709
+
ecf709
+    ret = sysdb_update_view_domain_resolution_order(state->domain->sysdb,
ecf709
+                                                    domain_resolution_order);
ecf709
+    if (ret != EOK) {
ecf709
+        DEBUG(SSSDBG_OP_FAILURE,
ecf709
+              "sysdb_update_view_domain_resolution_order() [%d]: [%s].\n",
ecf709
+              ret, sss_strerror(ret));
ecf709
+        goto done;
ecf709
+    }
ecf709
+
ecf709
+    ret = EOK;
ecf709
+
ecf709
+done:
ecf709
+    if (ret != EOK) {
ecf709
+        tevent_req_error(req, ret);
ecf709
+        return;
ecf709
+    }
ecf709
+
ecf709
+    tevent_req_done(req);
ecf709
+}
ecf709
+
ecf709
+static errno_t
ecf709
+ipa_subdomains_view_domain_resolution_order_recv(struct tevent_req *req)
ecf709
+{
ecf709
+    TEVENT_REQ_RETURN_ON_ERROR(req);
ecf709
+
ecf709
+    return EOK;
ecf709
+}
ecf709
+
ecf709
 struct ipa_domain_resolution_order_state {
ecf709
     struct sss_domain_info *domain;
ecf709
 };
ecf709
@@ -1809,6 +1954,8 @@ static void ipa_subdomains_refresh_certmap_done(struct tevent_req *subreq);
ecf709
 static void ipa_subdomains_refresh_master_done(struct tevent_req *subreq);
ecf709
 static void ipa_subdomains_refresh_slave_done(struct tevent_req *subreq);
ecf709
 static void ipa_subdomains_refresh_view_name_done(struct tevent_req *subreq);
ecf709
+static void ipa_subdomains_refresh_view_domain_resolution_order_done(
ecf709
+                                                    struct tevent_req *subreq);
ecf709
 static void ipa_domain_refresh_resolution_order_done(struct tevent_req *subreq);
ecf709
 
ecf709
 static struct tevent_req *
ecf709
@@ -2047,6 +2194,41 @@ static void ipa_subdomains_refresh_view_name_done(struct tevent_req *subreq)
ecf709
         return;
ecf709
     }
ecf709
 
ecf709
+    subreq = ipa_subdomains_view_domain_resolution_order_send(
ecf709
+                                            state,
ecf709
+                                            state->ev,
ecf709
+                                            state->sd_ctx,
ecf709
+                                            sdap_id_op_handle(state->sdap_op));
ecf709
+    if (subreq == NULL) {
ecf709
+        tevent_req_error(req, ENOMEM);
ecf709
+        return;
ecf709
+    }
ecf709
+
ecf709
+    tevent_req_set_callback(subreq,
ecf709
+                    ipa_subdomains_refresh_view_domain_resolution_order_done,
ecf709
+                    req);
ecf709
+}
ecf709
+
ecf709
+static void
ecf709
+ipa_subdomains_refresh_view_domain_resolution_order_done(struct tevent_req *subreq)
ecf709
+{
ecf709
+    struct ipa_subdomains_refresh_state *state;
ecf709
+    struct tevent_req *req;
ecf709
+    errno_t ret;
ecf709
+
ecf709
+    req = tevent_req_callback_data(subreq, struct tevent_req);
ecf709
+    state = tevent_req_data(req, struct ipa_subdomains_refresh_state);
ecf709
+
ecf709
+    ret = ipa_subdomains_view_domain_resolution_order_recv(subreq);
ecf709
+    talloc_zfree(subreq);
ecf709
+    if (ret != EOK) {
ecf709
+        DEBUG(SSSDBG_CRIT_FAILURE,
ecf709
+              "Unable to get view domain_resolution order [%d]: %s\n",
ecf709
+              ret, sss_strerror(ret));
ecf709
+        tevent_req_error(req, ret);
ecf709
+        return;
ecf709
+    }
ecf709
+
ecf709
     subreq = ipa_domain_resolution_order_send(state, state->ev, state->sd_ctx,
ecf709
                                             sdap_id_op_handle(state->sdap_op));
ecf709
     if (subreq == NULL) {
ecf709
-- 
ecf709
2.9.3
ecf709