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

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