Blob Blame History Raw
From d36c2acde1f29865c2cefedebc214ba48bb227e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Fri, 24 Mar 2017 17:46:04 +0100
Subject: [PATCH 50/54] IPA: Get ipaDomainsResolutionOrder from IPA ID View
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                     |   9 ++
 src/db/sysdb_views.c               |  66 ++++++++++++++
 src/providers/ipa/ipa_subdomains.c | 182 +++++++++++++++++++++++++++++++++++++
 3 files changed, 257 insertions(+)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 75a07d4d2effb028ec654342113f8478e1eba10e..62c561be9452a284a8ddf8ebb45720265852c8b0 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -533,6 +533,15 @@ errno_t sysdb_update_view_name(struct sysdb_ctx *sysdb, const char *view_name);
 errno_t sysdb_get_view_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
                             char **view_name);
 
+errno_t sysdb_update_view_domain_resolution_order(
+                                        struct sysdb_ctx *sysdb,
+                                        const char *domain_resolution_order);
+
+errno_t sysdb_get_view_domain_resolution_order(
+                                        TALLOC_CTX *mem_ctx,
+                                        struct sysdb_ctx *sysdb,
+                                        const char **_domain_resolution_order);
+
 static inline bool is_default_view(const char *view_name)
 {
     /* NULL is treated as default */
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
index 1c416dd14049237e9f35d52f154035e3ff861469..20db9b06183d68b33bb19f498513d7f5cf84b1cf 100644
--- a/src/db/sysdb_views.c
+++ b/src/db/sysdb_views.c
@@ -22,6 +22,9 @@
 #include "util/util.h"
 #include "util/cert.h"
 #include "db/sysdb_private.h"
+#include "db/sysdb_domain_resolution_order.h"
+
+#define SYSDB_VIEWS_BASE "cn=views,cn=sysdb"
 
 /* In general is should not be possible that there is a view container without
  * a view name set. But to be on the safe side we return both information
@@ -179,6 +182,69 @@ done:
     return ret;
 }
 
+errno_t
+sysdb_get_view_domain_resolution_order(TALLOC_CTX *mem_ctx,
+                                       struct sysdb_ctx *sysdb,
+                                       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(tmp_ctx, sysdb->ldb, SYSDB_VIEWS_BASE);
+    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_update_view_domain_resolution_order(struct sysdb_ctx *sysdb,
+                                          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(tmp_ctx, sysdb->ldb, SYSDB_VIEWS_BASE);
+    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;
+}
+
 errno_t sysdb_delete_view_tree(struct sysdb_ctx *sysdb, const char *view_name)
 {
     struct ldb_dn *dn;
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index bf6f6ab1fa8bfff7ea102dd219c9ddbbab065b2b..ef348adf4a36e870f44387bd700f5c2beea3bfd6 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -1684,6 +1684,151 @@ static errno_t ipa_subdomains_view_name_recv(struct tevent_req *req)
     return EOK;
 }
 
+struct ipa_subdomains_view_domain_resolution_order_state {
+    struct sss_domain_info *domain;
+    const char *view_name;
+};
+
+static void
+ipa_subdomains_view_domain_resolution_order_done(struct tevent_req *subreq);
+
+static struct tevent_req *
+ipa_subdomains_view_domain_resolution_order_send(
+                                            TALLOC_CTX *mem_ctx,
+                                            struct tevent_context *ev,
+                                            struct ipa_subdomains_ctx *sd_ctx,
+                                            struct sdap_handle *sh)
+{
+    struct ipa_subdomains_view_domain_resolution_order_state *state;
+    struct tevent_req *subreq;
+    struct tevent_req *req;
+    const char *attrs[] = { IPA_DOMAIN_RESOLUTION_ORDER, NULL };
+    char *ldap_basedn;
+    char *base;
+    errno_t ret;
+
+    req = tevent_req_create(mem_ctx, &state,
+                    struct ipa_subdomains_view_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;
+    state->view_name = sd_ctx->ipa_id_ctx->view_name;
+
+    ret = domain_to_basedn(state, sd_ctx->be_ctx->domain->name, &ldap_basedn);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
+        goto immediately;
+    }
+
+    base = talloc_asprintf(state, "cn=%s,cn=views,cn=accounts,%s",
+                           sd_ctx->ipa_id_ctx->view_name, ldap_basedn);
+    if (base == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
+        ret = ENOMEM;
+        goto immediately;
+    }
+
+    subreq = sdap_get_generic_send(
+                            state, ev, sd_ctx->sdap_id_ctx->opts, sh,
+                            base, LDAP_SCOPE_BASE, NULL, attrs, NULL, 0,
+                            dp_opt_get_int(sd_ctx->sdap_id_ctx->opts->basic,
+                                           SDAP_ENUM_SEARCH_TIMEOUT),
+                            false);
+    if (subreq == NULL) {
+        ret = ENOMEM;
+        goto immediately;
+    }
+
+    tevent_req_set_callback(subreq, ipa_subdomains_view_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_subdomains_view_domain_resolution_order_done(struct tevent_req *subreq)
+{
+    struct ipa_subdomains_view_domain_resolution_order_state *state;
+    struct tevent_req *req;
+    size_t reply_count;
+    struct sysdb_attrs **reply;
+    const char *domain_resolution_order;
+    errno_t ret;
+
+    req = tevent_req_callback_data(subreq, struct tevent_req);
+    state = tevent_req_data(req,
+                    struct ipa_subdomains_view_domain_resolution_order_state);
+
+    ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
+    talloc_zfree(subreq);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "Unable to get view name [%d]: %s\n",
+              ret, sss_strerror(ret));
+        goto done;
+    }
+
+    if (reply_count > 1) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "More than one object returned.\n");
+        ret = EINVAL;
+        goto done;
+    } else if (reply_count == 0) {
+        domain_resolution_order = NULL;
+    } else {
+        /* reply_count == 1 */
+        ret = sysdb_attrs_get_string(reply[0], IPA_DOMAIN_RESOLUTION_ORDER,
+                                     &domain_resolution_order);
+        if (ret != EOK && ret != ENOENT) {
+            DEBUG(SSSDBG_OP_FAILURE,
+                  "Failed to get the view domains' resolution order "
+                  "configuration value for view [%s] [%d]: %s\n",
+                  state->view_name, ret, sss_strerror(ret));
+            goto done;
+        } else if (ret == ENOENT) {
+            domain_resolution_order = NULL;
+        }
+    }
+
+    ret = sysdb_update_view_domain_resolution_order(state->domain->sysdb,
+                                                    domain_resolution_order);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE,
+              "sysdb_update_view_domain_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_subdomains_view_domain_resolution_order_recv(struct tevent_req *req)
+{
+    TEVENT_REQ_RETURN_ON_ERROR(req);
+
+    return EOK;
+}
+
 struct ipa_domain_resolution_order_state {
     struct sss_domain_info *domain;
 };
@@ -1809,6 +1954,8 @@ 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_name_done(struct tevent_req *subreq);
+static void ipa_subdomains_refresh_view_domain_resolution_order_done(
+                                                    struct tevent_req *subreq);
 static void ipa_domain_refresh_resolution_order_done(struct tevent_req *subreq);
 
 static struct tevent_req *
@@ -2047,6 +2194,41 @@ static void ipa_subdomains_refresh_view_name_done(struct tevent_req *subreq)
         return;
     }
 
+    subreq = ipa_subdomains_view_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_subdomains_refresh_view_domain_resolution_order_done,
+                    req);
+}
+
+static void
+ipa_subdomains_refresh_view_domain_resolution_order_done(struct tevent_req *subreq)
+{
+    struct ipa_subdomains_refresh_state *state;
+    struct tevent_req *req;
+    errno_t ret;
+
+    req = tevent_req_callback_data(subreq, struct tevent_req);
+    state = tevent_req_data(req, struct ipa_subdomains_refresh_state);
+
+    ret = ipa_subdomains_view_domain_resolution_order_recv(subreq);
+    talloc_zfree(subreq);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "Unable to get view domain_resolution order [%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) {
-- 
2.9.3