Blame SOURCES/0120-AD-connect-to-forest-root-when-downloading-the-list-.patch

2fc102
From d97ff9abd276e9216e5868be37c3762d208b36c0 Mon Sep 17 00:00:00 2001
2fc102
From: Jakub Hrozek <jhrozek@redhat.com>
2fc102
Date: Tue, 1 Apr 2014 13:51:49 -0400
2fc102
Subject: [PATCH 120/120] AD: connect to forest root when downloading the list
2fc102
 of subdomains
2fc102
2fc102
https://fedorahosted.org/sssd/ticket/2285
2fc102
2fc102
Only the forest root has the knowledge about all the domains in the forest,
2fc102
the forest leaves only see themselves and the forest root.
2fc102
2fc102
This patch switches to connecting to the forest root for downloading the
2fc102
trusted domains instead of the server we are connected to.
2fc102
---
2fc102
 src/providers/ad/ad_subdomains.c | 372 ++++++++++++++++++++++++++++++++++++++-
2fc102
 1 file changed, 363 insertions(+), 9 deletions(-)
2fc102
2fc102
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
2fc102
index 0d9652b5c615add47958cfdc61eba862a332ae4d..3c841788d5d88069d79a9438b72f57c8c2e0ffda 100644
2fc102
--- a/src/providers/ad/ad_subdomains.c
2fc102
+++ b/src/providers/ad/ad_subdomains.c
2fc102
@@ -54,7 +54,9 @@
2fc102
  * the same forest. See http://msdn.microsoft.com/en-us/library/cc223786.aspx
2fc102
  * for more information.
2fc102
  */
2fc102
-#define SLAVE_DOMAIN_FILTER "(&(objectclass=trustedDomain)(trustType=2)(!(msDS-TrustForestTrustInfo=*)))"
2fc102
+#define SLAVE_DOMAIN_FILTER_BASE "(objectclass=trustedDomain)(trustType=2)(!(msDS-TrustForestTrustInfo=*))"
2fc102
+#define SLAVE_DOMAIN_FILTER      "(&"SLAVE_DOMAIN_FILTER_BASE")"
2fc102
+#define FOREST_ROOT_FILTER_FMT   "(&"SLAVE_DOMAIN_FILTER_BASE"(cn=%s))"
2fc102
 
2fc102
 /* do not refresh more often than every 5 seconds for now */
2fc102
 #define AD_SUBDOMAIN_REFRESH_LIMIT 5
2fc102
@@ -80,6 +82,11 @@ struct ad_subdomains_req_ctx {
2fc102
     char *current_filter;
2fc102
     size_t base_iter;
2fc102
 
2fc102
+    struct ad_id_ctx *root_id_ctx;
2fc102
+    struct sdap_id_op *root_op;
2fc102
+    size_t root_base_iter;
2fc102
+    struct sysdb_attrs *root_domain;
2fc102
+
2fc102
     size_t reply_count;
2fc102
     struct sysdb_attrs **reply;
2fc102
 
2fc102
@@ -461,6 +468,7 @@ static errno_t ad_subdom_reinit(struct ad_subdomains_ctx *ctx)
2fc102
 
2fc102
 static void ad_subdomains_get_conn_done(struct tevent_req *req);
2fc102
 static void ad_subdomains_master_dom_done(struct tevent_req *req);
2fc102
+static errno_t ad_subdomains_get_root(struct ad_subdomains_req_ctx *ctx);
2fc102
 static errno_t ad_subdomains_get_slave(struct ad_subdomains_req_ctx *ctx);
2fc102
 
2fc102
 static void ad_subdomains_retrieve(struct ad_subdomains_ctx *ctx,
2fc102
@@ -481,6 +489,10 @@ static void ad_subdomains_retrieve(struct ad_subdomains_ctx *ctx,
2fc102
     req_ctx->sd_ctx = ctx;
2fc102
     req_ctx->current_filter = NULL;
2fc102
     req_ctx->base_iter = 0;
2fc102
+    req_ctx->root_base_iter = 0;
2fc102
+    req_ctx->root_id_ctx = NULL;
2fc102
+    req_ctx->root_op = NULL;
2fc102
+    req_ctx->root_domain = NULL;
2fc102
     req_ctx->reply_count = 0;
2fc102
     req_ctx->reply = NULL;
2fc102
 
2fc102
@@ -575,7 +587,20 @@ static void ad_subdomains_master_dom_done(struct tevent_req *req)
2fc102
         goto done;
2fc102
     }
2fc102
 
2fc102
-    ret = ad_subdomains_get_slave(ctx);
2fc102
+    if (strcasecmp(ctx->sd_ctx->be_ctx->domain->name, ctx->forest) != 0) {
2fc102
+        DEBUG(SSSDBG_TRACE_FUNC,
2fc102
+              ("SSSD needs to look up the forest root domain\n"));
2fc102
+        ret = ad_subdomains_get_root(ctx);
2fc102
+    } else {
2fc102
+        DEBUG(SSSDBG_TRACE_FUNC,
2fc102
+              ("Connected to forest root, looking up child domains..\n"));
2fc102
+
2fc102
+        ctx->root_op = ctx->sdap_op;
2fc102
+        ctx->root_id_ctx = ctx->sd_ctx->ad_id_ctx;
2fc102
+
2fc102
+        ret = ad_subdomains_get_slave(ctx);
2fc102
+    }
2fc102
+
2fc102
     if (ret == EAGAIN) {
2fc102
         return;
2fc102
     } else if (ret != EOK) {
2fc102
@@ -586,6 +611,244 @@ done:
2fc102
     be_req_terminate(ctx->be_req, DP_ERR_FATAL, ret, NULL);
2fc102
 }
2fc102
 
2fc102
+static void ad_subdomains_get_root_domain_done(struct tevent_req *req);
2fc102
+
2fc102
+static errno_t ad_subdomains_get_root(struct ad_subdomains_req_ctx *ctx)
2fc102
+{
2fc102
+    struct tevent_req *req;
2fc102
+    struct sdap_search_base *base;
2fc102
+    struct sdap_id_ctx *sdap_id_ctx;
2fc102
+    char *filter;
2fc102
+    const char *forest_root_attrs[] = { AD_AT_FLATNAME, AD_AT_TRUST_PARTNER,
2fc102
+                                        AD_AT_SID, AD_AT_TRUST_TYPE,
2fc102
+                                        AD_AT_TRUST_ATTRS, NULL };
2fc102
+
2fc102
+    sdap_id_ctx = ctx->sd_ctx->sdap_id_ctx;
2fc102
+    base = sdap_id_ctx->opts->sdom->search_bases[ctx->root_base_iter];
2fc102
+    if (base == NULL) {
2fc102
+        return EOK;
2fc102
+    }
2fc102
+
2fc102
+    filter = talloc_asprintf(ctx, FOREST_ROOT_FILTER_FMT, ctx->forest);
2fc102
+    if (filter == NULL) {
2fc102
+        return ENOMEM;
2fc102
+    }
2fc102
+
2fc102
+    req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev,
2fc102
+                                sdap_id_ctx->opts,
2fc102
+                                sdap_id_op_handle(ctx->sdap_op),
2fc102
+                                base->basedn, LDAP_SCOPE_SUBTREE,
2fc102
+                                filter, forest_root_attrs,
2fc102
+                                NULL, 0,
2fc102
+                                dp_opt_get_int(sdap_id_ctx->opts->basic,
2fc102
+                                                SDAP_SEARCH_TIMEOUT),
2fc102
+                                false);
2fc102
+
2fc102
+    if (req == NULL) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send failed.\n"));
2fc102
+        return ENOMEM;
2fc102
+    }
2fc102
+
2fc102
+    tevent_req_set_callback(req, ad_subdomains_get_root_domain_done, ctx);
2fc102
+    return EAGAIN;
2fc102
+}
2fc102
+
2fc102
+static struct ad_id_ctx *ads_get_root_id_ctx(struct ad_subdomains_req_ctx *ctx);
2fc102
+static void ad_subdomains_root_conn_done(struct tevent_req *req);
2fc102
+
2fc102
+static void ad_subdomains_get_root_domain_done(struct tevent_req *req)
2fc102
+{
2fc102
+    int ret;
2fc102
+    size_t reply_count;
2fc102
+    struct sysdb_attrs **reply = NULL;
2fc102
+    struct ad_subdomains_req_ctx *ctx;
2fc102
+    int dp_error = DP_ERR_FATAL;
2fc102
+    bool has_changes;
2fc102
+
2fc102
+    ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx);
2fc102
+
2fc102
+    ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
2fc102
+    talloc_zfree(req);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
2fc102
+        goto fail;
2fc102
+    }
2fc102
+
2fc102
+    if (reply_count == 0) {
2fc102
+        /* If no root domain was found in the default search base, try the
2fc102
+         * next one, if available
2fc102
+         */
2fc102
+        ctx->root_base_iter++;
2fc102
+        ret = ad_subdomains_get_root(ctx);
2fc102
+        if (ret == EAGAIN) {
2fc102
+            return;
2fc102
+        }
2fc102
+
2fc102
+        goto fail;
2fc102
+    } else if (reply_count > 1) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE,
2fc102
+              ("Multiple results for root domain search, "
2fc102
+               "domain list might be incomplete!\n"));
2fc102
+
2fc102
+        ctx->root_op = ctx->sdap_op;
2fc102
+        ctx->root_id_ctx = ctx->sd_ctx->ad_id_ctx;
2fc102
+
2fc102
+        ret = ad_subdomains_get_slave(ctx);
2fc102
+        if (ret == EAGAIN) {
2fc102
+            return;
2fc102
+        }
2fc102
+
2fc102
+        goto fail;
2fc102
+    }
2fc102
+    /* Exactly one result, good. */
2fc102
+
2fc102
+    /* We won't use the operation to the local LDAP anymore, but
2fc102
+     * read from the forest root
2fc102
+     */
2fc102
+    ret = sdap_id_op_done(ctx->sdap_op, ret, &dp_error);
2fc102
+    if (ret != EOK) {
2fc102
+        if (dp_error == DP_ERR_OFFLINE) {
2fc102
+            DEBUG(SSSDBG_MINOR_FAILURE,
2fc102
+                  ("No AD server is available, cannot get the "
2fc102
+                   "subdomain list while offline\n"));
2fc102
+        } else {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE,
2fc102
+                  ("Failed to search the AD server: [%d](%s)\n",
2fc102
+                  ret, strerror(ret)));
2fc102
+        }
2fc102
+        goto fail;
2fc102
+    }
2fc102
+
2fc102
+    ret = ad_subdomains_refresh(ctx->sd_ctx, 1, reply, &has_changes);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE, ("ad_subdomains_refresh failed.\n"));
2fc102
+        goto fail;
2fc102
+    }
2fc102
+
2fc102
+    if (has_changes) {
2fc102
+        ret = ad_subdom_reinit(ctx->sd_ctx);
2fc102
+        if (ret != EOK) {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE, ("Could not reinitialize subdomains\n"));
2fc102
+            goto fail;
2fc102
+        }
2fc102
+    }
2fc102
+
2fc102
+    ctx->root_domain = reply[0];
2fc102
+    ctx->root_id_ctx = ads_get_root_id_ctx(ctx);
2fc102
+    if (ctx->root_id_ctx == NULL) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE,
2fc102
+              ("Cannot create id ctx for the root domain\n"));
2fc102
+        ret = EFAULT;
2fc102
+        goto fail;
2fc102
+    }
2fc102
+
2fc102
+    ctx->root_op = sdap_id_op_create(ctx,
2fc102
+                                     ctx->root_id_ctx->ldap_ctx->conn_cache);
2fc102
+    if (ctx->root_op == NULL) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_create failed.\n"));
2fc102
+        ret = ENOMEM;
2fc102
+        goto fail;
2fc102
+    }
2fc102
+
2fc102
+    req = sdap_id_op_connect_send(ctx->root_op, ctx, &ret;;
2fc102
+    if (req == NULL) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_connect_send failed: %d(%s).\n",
2fc102
+                                   ret, strerror(ret)));
2fc102
+        goto fail;
2fc102
+    }
2fc102
+
2fc102
+    tevent_req_set_callback(req, ad_subdomains_root_conn_done, ctx);
2fc102
+    return;
2fc102
+
2fc102
+fail:
2fc102
+    if (ret == EOK) {
2fc102
+        ctx->sd_ctx->last_refreshed = time(NULL);
2fc102
+        dp_error = DP_ERR_OK;
2fc102
+    }
2fc102
+    be_req_terminate(ctx->be_req, dp_error, ret, NULL);
2fc102
+}
2fc102
+
2fc102
+static struct ad_id_ctx *ads_get_root_id_ctx(struct ad_subdomains_req_ctx *ctx)
2fc102
+{
2fc102
+    errno_t ret;
2fc102
+    const char *name;
2fc102
+    struct sss_domain_info *root;
2fc102
+    struct sdap_domain *sdom;
2fc102
+    struct ad_id_ctx *root_id_ctx;
2fc102
+
2fc102
+    ret = sysdb_attrs_get_string(ctx->root_domain, AD_AT_TRUST_PARTNER, &name);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
2fc102
+        return NULL;
2fc102
+    }
2fc102
+
2fc102
+    /* With a subsequent run, the root should already be known */
2fc102
+    root = find_subdomain_by_name(ctx->sd_ctx->be_ctx->domain,
2fc102
+                                  name, false);
2fc102
+    if (root == NULL) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE, ("Could not find the root domain\n"));
2fc102
+        return NULL;
2fc102
+    }
2fc102
+
2fc102
+    sdom = sdap_domain_get(ctx->sd_ctx->ad_id_ctx->sdap_id_ctx->opts, root);
2fc102
+    if (sdom == NULL) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE,
2fc102
+              ("Cannot get the sdom for %s!\n", root->name));
2fc102
+        return NULL;
2fc102
+    }
2fc102
+
2fc102
+    if (sdom->pvt == NULL) {
2fc102
+        ret = ad_subdom_ad_ctx_new(ctx->sd_ctx->be_ctx,
2fc102
+                                   ctx->sd_ctx->ad_id_ctx,
2fc102
+                                   root,
2fc102
+                                   &root_id_ctx);
2fc102
+        if (ret != EOK) {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE, ("ad_subdom_ad_ctx_new failed.\n"));
2fc102
+            return NULL;
2fc102
+        }
2fc102
+        sdom->pvt = root_id_ctx;
2fc102
+    } else {
2fc102
+        root_id_ctx = sdom->pvt;
2fc102
+    }
2fc102
+
2fc102
+    return root_id_ctx;
2fc102
+}
2fc102
+
2fc102
+static void ad_subdomains_root_conn_done(struct tevent_req *req)
2fc102
+{
2fc102
+    int ret;
2fc102
+    int dp_error = DP_ERR_FATAL;
2fc102
+    struct ad_subdomains_req_ctx *ctx;
2fc102
+
2fc102
+    ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx);
2fc102
+
2fc102
+    ret = sdap_id_op_connect_recv(req, &dp_error);
2fc102
+    talloc_zfree(req);
2fc102
+    if (ret) {
2fc102
+        if (dp_error == DP_ERR_OFFLINE) {
2fc102
+            DEBUG(SSSDBG_MINOR_FAILURE,
2fc102
+                  ("No AD server is available, cannot get the "
2fc102
+                   "subdomain list while offline\n"));
2fc102
+        } else {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE,
2fc102
+                  ("Failed to connect to AD server: [%d](%s)\n",
2fc102
+                  ret, strerror(ret)));
2fc102
+        }
2fc102
+
2fc102
+        goto fail;
2fc102
+    }
2fc102
+
2fc102
+    ret = ad_subdomains_get_slave(ctx);
2fc102
+    if (ret == EAGAIN) {
2fc102
+        return;
2fc102
+    } else if (ret != EOK) {
2fc102
+        goto fail;
2fc102
+    }
2fc102
+
2fc102
+fail:
2fc102
+    be_req_terminate(ctx->be_req, dp_error, ret, NULL);
2fc102
+}
2fc102
+
2fc102
 static void ad_subdomains_get_slave_domain_done(struct tevent_req *req);
2fc102
 
2fc102
 static errno_t ad_subdomains_get_slave(struct ad_subdomains_req_ctx *ctx)
2fc102
@@ -596,18 +859,18 @@ static errno_t ad_subdomains_get_slave(struct ad_subdomains_req_ctx *ctx)
2fc102
                                       AD_AT_SID, AD_AT_TRUST_TYPE,
2fc102
                                       AD_AT_TRUST_ATTRS, NULL };
2fc102
 
2fc102
-    base = ctx->sd_ctx->sdap_id_ctx->opts->sdom->search_bases[ctx->base_iter];
2fc102
+    base = ctx->root_id_ctx->sdap_id_ctx->opts->sdom->search_bases[ctx->base_iter];
2fc102
     if (base == NULL) {
2fc102
         return EOK;
2fc102
     }
2fc102
 
2fc102
     req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev,
2fc102
-                           ctx->sd_ctx->sdap_id_ctx->opts,
2fc102
-                           sdap_id_op_handle(ctx->sdap_op),
2fc102
+                           ctx->root_id_ctx->sdap_id_ctx->opts,
2fc102
+                           sdap_id_op_handle(ctx->root_op),
2fc102
                            base->basedn, LDAP_SCOPE_SUBTREE,
2fc102
                            SLAVE_DOMAIN_FILTER, slave_dom_attrs,
2fc102
                            NULL, 0,
2fc102
-                           dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic,
2fc102
+                           dp_opt_get_int(ctx->root_id_ctx->sdap_id_ctx->opts->basic,
2fc102
                                           SDAP_SEARCH_TIMEOUT),
2fc102
                            false);
2fc102
 
2fc102
@@ -620,6 +883,68 @@ static errno_t ad_subdomains_get_slave(struct ad_subdomains_req_ctx *ctx)
2fc102
     return EAGAIN;
2fc102
 }
2fc102
 
2fc102
+static errno_t ad_subdomains_process(TALLOC_CTX *mem_ctx,
2fc102
+                                     struct sss_domain_info *domain,
2fc102
+                                     size_t nsd, struct sysdb_attrs **sd,
2fc102
+                                     struct sysdb_attrs *root,
2fc102
+                                     size_t *_nsd_out,
2fc102
+                                     struct sysdb_attrs ***_sd_out)
2fc102
+{
2fc102
+    size_t i, sdi;
2fc102
+    struct sysdb_attrs **sd_out;
2fc102
+    const char *sd_name;
2fc102
+    errno_t ret;
2fc102
+
2fc102
+    if (root == NULL) {
2fc102
+        /* We are connected directly to the root domain. The 'sd'
2fc102
+         * list is complete and we can just use it
2fc102
+         */
2fc102
+        *_nsd_out = nsd;
2fc102
+        *_sd_out = sd;
2fc102
+        return EOK;
2fc102
+    }
2fc102
+
2fc102
+    /* If we searched for root separately, we must:
2fc102
+     *  a) treat the root domain as a subdomain
2fc102
+     *  b) filter the subdomain we are connected to from the subdomain
2fc102
+     *     list, from our point of view, it's the master domain
2fc102
+     */
2fc102
+    sd_out = talloc_zero_array(mem_ctx, struct sysdb_attrs *, nsd+1);
2fc102
+    if (sd_out == NULL) {
2fc102
+        return ENOMEM;
2fc102
+    }
2fc102
+
2fc102
+    sdi = 0;
2fc102
+    for (i = 0; i < nsd; i++) {
2fc102
+        ret = sysdb_attrs_get_string(sd[i], AD_AT_TRUST_PARTNER, &sd_name);
2fc102
+        if (ret != EOK) {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
2fc102
+            goto fail;
2fc102
+        }
2fc102
+
2fc102
+        if (strcasecmp(sd_name, domain->name) == 0) {
2fc102
+            DEBUG(SSSDBG_TRACE_INTERNAL,
2fc102
+                  ("Not including primary domain %s in the subdomain list\n",
2fc102
+                  domain->name));
2fc102
+            continue;
2fc102
+        }
2fc102
+
2fc102
+        sd_out[sdi] = talloc_steal(sd_out, sd[i]);
2fc102
+        sdi++;
2fc102
+    }
2fc102
+
2fc102
+    /* Now include the root */
2fc102
+    sd_out[sdi] = talloc_steal(sd_out, root);
2fc102
+
2fc102
+    *_nsd_out = sdi+1;
2fc102
+    *_sd_out = sd_out;
2fc102
+    return EOK;
2fc102
+
2fc102
+fail:
2fc102
+    talloc_free(sd_out);
2fc102
+    return ret;
2fc102
+}
2fc102
+
2fc102
 static void ad_subdomains_get_slave_domain_done(struct tevent_req *req)
2fc102
 {
2fc102
     int ret;
2fc102
@@ -628,6 +953,8 @@ static void ad_subdomains_get_slave_domain_done(struct tevent_req *req)
2fc102
     struct ad_subdomains_req_ctx *ctx;
2fc102
     int dp_error = DP_ERR_FATAL;
2fc102
     bool refresh_has_changes = false;
2fc102
+    size_t nsubdoms;
2fc102
+    struct sysdb_attrs **subdoms;
2fc102
 
2fc102
     ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx);
2fc102
 
2fc102
@@ -653,13 +980,40 @@ static void ad_subdomains_get_slave_domain_done(struct tevent_req *req)
2fc102
     ctx->base_iter++;
2fc102
     ret = ad_subdomains_get_slave(ctx);
2fc102
     if (ret == EAGAIN) {
2fc102
+        /* Search in progress */
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
+    ret = sdap_id_op_done(ctx->root_op, ret, &dp_error);
2fc102
+    if (ret != EOK) {
2fc102
+        if (dp_error == DP_ERR_OFFLINE) {
2fc102
+            DEBUG(SSSDBG_MINOR_FAILURE,
2fc102
+                  ("No AD server is available, cannot get the "
2fc102
+                   "subdomain list while offline\n"));
2fc102
+        } else {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE,
2fc102
+                  ("Failed to search the AD server: [%d](%s)\n",
2fc102
+                  ret, strerror(ret)));
2fc102
+        }
2fc102
+        tevent_req_error(req, ret);
2fc102
+        return;
2fc102
+    }
2fc102
+
2fc102
+    /* Based on whether we are connected to the forest root or not, we might
2fc102
+     * need to exclude the subdomain we are connected to from the list of
2fc102
+     * subdomains
2fc102
+     */
2fc102
+    ret = ad_subdomains_process(ctx, ctx->sd_ctx->be_ctx->domain,
2fc102
+                                ctx->reply_count, ctx->reply,
2fc102
+                                ctx->root_domain, &nsubdoms, &subdoms);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE, ("Cannot process subdomain list\n"));
2fc102
+        tevent_req_error(req, ret);
2fc102
         return;
2fc102
-    } else if (ret != EOK) {
2fc102
-        goto done;
2fc102
     }
2fc102
 
2fc102
     /* Got all the subdomains, let's process them */
2fc102
-    ret = ad_subdomains_refresh(ctx->sd_ctx, ctx->reply_count, ctx->reply,
2fc102
+    ret = ad_subdomains_refresh(ctx->sd_ctx, nsubdoms, subdoms,
2fc102
                                 &refresh_has_changes);
2fc102
     if (ret != EOK) {
2fc102
         DEBUG(SSSDBG_OP_FAILURE, ("Failed to refresh subdomains.\n"));
2fc102
-- 
2fc102
1.9.0
2fc102