>From 8bd9598701a342ca158f15a9469737e70f529920 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Wed, 9 Sep 2015 14:37:48 +0200
Subject: [PATCH 1/2] util: Update get_next_domain's interface

Update get next domain to be able to
include disbled domains and change the
interface to accept flags instead of
multiple booleans.

Ticket:
https://fedorahosted.org/sssd/ticket/2673
---
 src/confdb/confdb.c                          |  2 +-
 src/db/sysdb_subdomains.c                    |  7 +--
 src/monitor/monitor.c                        | 10 ++--
 src/providers/ad/ad_subdomains.c             |  4 +-
 src/providers/dp_refresh.c                   |  2 +-
 src/providers/ipa/ipa_subdomains.c           |  4 +-
 src/providers/ipa/ipa_subdomains_server.c    |  4 +-
 src/providers/ldap/sdap_domain.c             |  4 +-
 src/responder/autofs/autofssrv_cmd.c         |  6 +--
 src/responder/common/negcache.c              |  8 +--
 src/responder/common/responder_cache_req.c   |  4 +-
 src/responder/common/responder_common.c      |  8 +--
 src/responder/common/responder_get_domains.c |  9 ++--
 src/responder/ifp/ifp_cache.c                |  2 +-
 src/responder/ifp/ifp_domains.c              |  9 ++--
 src/responder/ifp/ifp_groups.c               |  2 +-
 src/responder/ifp/ifp_users.c                |  2 +-
 src/responder/nss/nsssrv_cmd.c               | 81 ++++++++++++++--------------
 src/responder/nss/nsssrv_netgroup.c          |  8 +--
 src/responder/nss/nsssrv_services.c          | 20 +++----
 src/responder/pam/pamsrv_cmd.c               |  6 +--
 src/responder/sudo/sudosrv_get_sudorules.c   |  6 +--
 src/tests/cmocka/test_utils.c                | 23 ++++----
 src/tools/common/sss_tools.c                 |  6 ++-
 src/tools/sss_cache.c                        |  5 +-
 src/tools/sss_debuglevel.c                   |  4 +-
 src/tools/sss_override.c                     |  4 +-
 src/util/domain_info_utils.c                 | 33 +++++++-----
 src/util/usertools.c                         |  4 +-
 src/util/util.h                              |  4 +-
 30 files changed, 159 insertions(+), 132 deletions(-)

diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index 3a8a1c0..b5aae84 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1431,7 +1431,7 @@ int confdb_get_domain(struct confdb_ctx *cdb,
         return ret;
     }
 
-    for (dom = doms; dom; dom = get_next_domain(dom, false)) {
+    for (dom = doms; dom; dom = get_next_domain(dom, 0)) {
         if (strcasecmp(dom->name, name) == 0) {
             *_domain = dom;
             return EOK;
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index 142520c..e70d5f7 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -189,12 +189,13 @@ static void link_forest_roots(struct sss_domain_info *domain)
 {
     struct sss_domain_info *d;
     struct sss_domain_info *dd;
+    uint32_t gnd_flags = SSS_GND_DESCEND;
 
-    for (d = domain; d; d = get_next_domain(d, true)) {
+    for (d = domain; d; d = get_next_domain(d, gnd_flags)) {
         d->forest_root = NULL;
     }
 
-    for (d = domain; d; d = get_next_domain(d, true)) {
+    for (d = domain; d; d = get_next_domain(d, gnd_flags)) {
         if (d->forest_root != NULL) {
             continue;
         }
@@ -203,7 +204,7 @@ static void link_forest_roots(struct sss_domain_info *domain)
             d->forest_root = d;
             DEBUG(SSSDBG_TRACE_INTERNAL, "[%s] is a forest root\n", d->name);
 
-            for (dd = domain; dd; dd = get_next_domain(dd, true)) {
+            for (dd = domain; dd; dd = get_next_domain(dd, gnd_flags)) {
                 if (dd->forest_root != NULL) {
                     continue;
                 }
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 02fd072..3776cab 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -805,7 +805,7 @@ static int check_domain_ranges(struct sss_domain_info *domains)
     uint32_t id_min, id_max;
 
     while (dom) {
-        other = get_next_domain(dom, false);
+        other = get_next_domain(dom, 0);
         if (dom->id_max && dom->id_min > dom->id_max) {
             DEBUG(SSSDBG_CRIT_FAILURE,
                   "Domain '%s' does not have a valid ID range\n", dom->name);
@@ -821,9 +821,9 @@ static int check_domain_ranges(struct sss_domain_info *domains)
                       "Domains '%s' and '%s' overlap in range %u - %u\n",
                       dom->name, other->name, id_min, id_max);
             }
-            other = get_next_domain(other, false);
+            other = get_next_domain(other, 0);
         }
-        dom = get_next_domain(dom, false);
+        dom = get_next_domain(dom, 0);
     }
 
     return EOK;
@@ -844,7 +844,7 @@ static int check_local_domain_unique(struct sss_domain_info *domains)
             break;
         }
 
-        dom = get_next_domain(dom, false);
+        dom = get_next_domain(dom, 0);
     }
 
     if (count > 1) {
@@ -2424,7 +2424,7 @@ static int monitor_process_init(struct mt_ctx *ctx,
 
     /* start providers */
     num_providers = 0;
-    for (dom = ctx->domains; dom; dom = get_next_domain(dom, false)) {
+    for (dom = ctx->domains; dom; dom = get_next_domain(dom, 0)) {
         ret = add_new_provider(ctx, dom->name, 0);
         if (ret != EOK && ret != ENOENT) {
             return ret;
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 9b42f03..63ac3f4 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -349,9 +349,9 @@ static errno_t ad_subdomains_refresh(struct ad_subdomains_ctx *ctx,
     }
 
     /* check existing subdomains */
-    for (dom = get_next_domain(domain, true);
+    for (dom = get_next_domain(domain, SSS_GND_DESCEND);
          dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
-         dom = get_next_domain(dom, false)) {
+         dom = get_next_domain(dom, 0)) {
 
         /* If we are handling root domain, skip all the other domains. We don't
          * want to accidentally remove non-root domains
diff --git a/src/providers/dp_refresh.c b/src/providers/dp_refresh.c
index 76c092b..589c280 100644
--- a/src/providers/dp_refresh.c
+++ b/src/providers/dp_refresh.c
@@ -261,7 +261,7 @@ static errno_t be_refresh_step(struct tevent_req *req)
 
         /* if not found than continue with next domain */
         if (state->index == BE_REFRESH_TYPE_SENTINEL) {
-            state->domain = get_next_domain(state->domain, false);
+            state->domain = get_next_domain(state->domain, 0);
             continue;
         }
 
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index b2e2fec..52a1ee7 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -509,9 +509,9 @@ static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx,
     h = 0;
 
     /* check existing subdomains */
-    for (dom = get_next_domain(parent, true);
+    for (dom = get_next_domain(parent, SSS_GND_DESCEND);
          dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
-         dom = get_next_domain(dom, false)) {
+         dom = get_next_domain(dom, 0)) {
         for (c = 0; c < count; c++) {
             if (handled[c]) {
                 continue;
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
index dfecab1..b37d28b 100644
--- a/src/providers/ipa/ipa_subdomains_server.c
+++ b/src/providers/ipa/ipa_subdomains_server.c
@@ -866,9 +866,9 @@ static errno_t ipa_server_create_trusts_step(struct tevent_req *req)
 
     state = tevent_req_data(req, struct ipa_server_create_trusts_state);
 
-    for (state->domiter = get_next_domain(state->domiter, true);
+    for (state->domiter = get_next_domain(state->domiter, SSS_GND_DESCEND);
          state->domiter && IS_SUBDOMAIN(state->domiter);
-         state->domiter = get_next_domain(state->domiter, false)) {
+         state->domiter = get_next_domain(state->domiter, 0)) {
 
         /* Check if we already have an ID context for this subdomain */
         DLIST_FOR_EACH(trust_iter, state->id_ctx->server_mode->trusts) {
diff --git a/src/providers/ldap/sdap_domain.c b/src/providers/ldap/sdap_domain.c
index d7e3dc3..5cba9df 100644
--- a/src/providers/ldap/sdap_domain.c
+++ b/src/providers/ldap/sdap_domain.c
@@ -132,9 +132,9 @@ sdap_domain_subdom_add(struct sdap_id_ctx *sdap_id_ctx,
     struct sdap_domain *sdom, *sditer;
     errno_t ret;
 
-    for (dom = get_next_domain(parent, true);
+    for (dom = get_next_domain(parent, SSS_GND_DESCEND);
          dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
-         dom = get_next_domain(dom, false)) {
+         dom = get_next_domain(dom, 0)) {
 
         DLIST_FOR_EACH(sditer, sdom_list) {
             if (sditer->dom == dom) {
diff --git a/src/responder/autofs/autofssrv_cmd.c b/src/responder/autofs/autofssrv_cmd.c
index 27b6617..82f2f86 100644
--- a/src/responder/autofs/autofssrv_cmd.c
+++ b/src/responder/autofs/autofssrv_cmd.c
@@ -661,7 +661,7 @@ lookup_automntmap_step(struct setautomntent_lookup_ctx *lookup_ctx)
             if (!dctx->check_provider) {
                 if (dctx->cmd_ctx->check_next) {
                     DEBUG(SSSDBG_TRACE_INTERNAL, "Moving on to next domain\n");
-                    dom = get_next_domain(dom, false);
+                    dom = get_next_domain(dom, 0);
                     continue;
                 }
                 else break;
@@ -868,8 +868,8 @@ static void lookup_automntmap_cache_updated(uint16_t err_maj, uint32_t err_min,
                "Will try to return what we have in cache\n",
                (unsigned int)err_maj, (unsigned int)err_min, err_msg);
         /* Loop to the next domain if possible */
-        if (dctx->cmd_ctx->check_next && get_next_domain(dctx->domain, false)) {
-            dctx->domain = get_next_domain(dctx->domain, false);
+        if (dctx->cmd_ctx->check_next && get_next_domain(dctx->domain, 0)) {
+            dctx->domain = get_next_domain(dctx->domain, 0);
             dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
         }
     }
diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index fc482c4..f7af9e0 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -664,7 +664,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
     int i;
 
     /* Populate domain-specific negative cache entries */
-    for (dom = domain_list; dom; dom = get_next_domain(dom, false)) {
+    for (dom = domain_list; dom; dom = get_next_domain(dom, 0)) {
         conf_path = talloc_asprintf(tmpctx, CONFDB_DOMAIN_PATH_TMPL,
                                     dom->name);
         if (!conf_path) {
@@ -765,7 +765,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
                 continue;
             }
         } else {
-            for (dom = domain_list; dom; dom = get_next_domain(dom, false)) {
+            for (dom = domain_list; dom; dom = get_next_domain(dom, 0)) {
                 ret = sss_ncache_set_user(ncache, true, dom, name);
                 if (ret != EOK) {
                    DEBUG(SSSDBG_CRIT_FAILURE,
@@ -780,7 +780,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
     }
 
     filter_set = false;
-    for (dom = domain_list; dom; dom = get_next_domain(dom, false)) {
+    for (dom = domain_list; dom; dom = get_next_domain(dom, 0)) {
         conf_path = talloc_asprintf(tmpctx, CONFDB_DOMAIN_PATH_TMPL, dom->name);
         if (!conf_path) {
             ret = ENOMEM;
@@ -873,7 +873,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
                 continue;
             }
         } else {
-            for (dom = domain_list; dom; dom = get_next_domain(dom, false)) {
+            for (dom = domain_list; dom; dom = get_next_domain(dom, 0)) {
                 ret = sss_ncache_set_group(ncache, true, dom, name);
                 if (ret != EOK) {
                    DEBUG(SSSDBG_CRIT_FAILURE,
diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c
index d0a90d2..eefd090 100644
--- a/src/responder/common/responder_cache_req.c
+++ b/src/responder/common/responder_cache_req.c
@@ -883,7 +883,7 @@ static errno_t cache_req_next_domain(struct tevent_req *req)
         * qualified names instead. */
         while (state->domain != NULL && state->check_next
                 && state->domain->fqnames) {
-            state->domain = get_next_domain(state->domain, false);
+            state->domain = get_next_domain(state->domain, 0);
         }
 
         state->selected_domain = state->domain;
@@ -910,7 +910,7 @@ static errno_t cache_req_next_domain(struct tevent_req *req)
 
         /* we will continue with the following domain the next time */
         if (state->check_next) {
-            state->domain = get_next_domain(state->domain, false);
+            state->domain = get_next_domain(state->domain, 0);
         }
 
         return EAGAIN;
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 36e7f15..671ba53 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -844,7 +844,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
         goto fail;
     }
 
-    for (dom = rctx->domains; dom; dom = get_next_domain(dom, false)) {
+    for (dom = rctx->domains; dom; dom = get_next_domain(dom, 0)) {
         ret = sss_names_init(rctx->cdb, rctx->cdb, dom->name, &dom->names);
         if (ret != EOK) {
             DEBUG(SSSDBG_FATAL_FAILURE,
@@ -922,7 +922,8 @@ responder_get_domain(struct resp_ctx *rctx, const char *name)
     struct sss_domain_info *dom;
     struct sss_domain_info *ret_dom = NULL;
 
-    for (dom = rctx->domains; dom; dom = get_next_domain(dom, true)) {
+    for (dom = rctx->domains; dom;
+            dom = get_next_domain(dom, SSS_GND_DESCEND)) {
         if (dom->disabled) {
             continue;
         }
@@ -957,7 +958,8 @@ errno_t responder_get_domain_by_id(struct resp_ctx *rctx, const char *id,
 
     id_len = strlen(id);
 
-    for (dom = rctx->domains; dom; dom = get_next_domain(dom, true)) {
+    for (dom = rctx->domains; dom;
+            dom = get_next_domain(dom, SSS_GND_DESCEND)) {
         if (dom->disabled || dom->domain_id == NULL) {
             continue;
         }
diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c
index 8fbab08..46de88b 100644
--- a/src/responder/common/responder_get_domains.c
+++ b/src/responder/common/responder_get_domains.c
@@ -186,7 +186,7 @@ struct tevent_req *sss_dp_get_domains_send(TALLOC_CTX *mem_ctx,
 
     state->dom = rctx->domains;
     while(state->dom != NULL && !NEED_CHECK_PROVIDER(state->dom->provider)) {
-        state->dom = get_next_domain(state->dom, false);
+        state->dom = get_next_domain(state->dom, 0);
     }
 
     if (state->dom == NULL) {
@@ -242,11 +242,11 @@ sss_dp_get_domains_process(struct tevent_req *subreq)
     }
 
     /* Advance to the next domain */
-    state->dom = get_next_domain(state->dom, false);
+    state->dom = get_next_domain(state->dom, 0);
 
     /* Skip local domains */
     while(state->dom != NULL && !NEED_CHECK_PROVIDER(state->dom->provider)) {
-        state->dom = get_next_domain(state->dom, false);
+        state->dom = get_next_domain(state->dom, 0);
     }
 
     if (state->dom == NULL) {
@@ -345,7 +345,8 @@ static errno_t check_last_request(struct resp_ctx *rctx, const char *hint)
     }
 
     if (hint != NULL) {
-        for (dom = rctx->domains; dom; dom = get_next_domain(dom, true)) {
+        for (dom = rctx->domains; dom;
+                dom = get_next_domain(dom, SSS_GND_DESCEND)) {
             if (!IS_SUBDOMAIN(dom)) {
                 diff = now - dom->subdomains_last_checked.tv_sec;
                 /* not a subdomain */
diff --git a/src/responder/ifp/ifp_cache.c b/src/responder/ifp/ifp_cache.c
index a109ac0..8ea2d80 100644
--- a/src/responder/ifp/ifp_cache.c
+++ b/src/responder/ifp/ifp_cache.c
@@ -190,7 +190,7 @@ errno_t ifp_cache_list_domains(TALLOC_CTX *mem_ctx,
 
         num_paths += num_tmp_paths;
 
-        domain = get_next_domain(domain, true);
+        domain = get_next_domain(domain, SSS_GND_DESCEND);
     }
 
     if (_paths != NULL) {
diff --git a/src/responder/ifp/ifp_domains.c b/src/responder/ifp/ifp_domains.c
index 3605766..5ad9952 100644
--- a/src/responder/ifp/ifp_domains.c
+++ b/src/responder/ifp/ifp_domains.c
@@ -111,7 +111,7 @@ static void ifp_list_domains_process(struct tevent_req *req)
     num_domains = 0;
     for (dom = ireq->ifp_ctx->rctx->domains;
             dom != NULL;
-            dom = get_next_domain(dom, true)) {
+            dom = get_next_domain(dom, SSS_GND_DESCEND)) {
         num_domains++;
     }
 
@@ -124,7 +124,7 @@ static void ifp_list_domains_process(struct tevent_req *req)
     pi = 0;
     for (dom = ireq->ifp_ctx->rctx->domains;
             dom != NULL;
-            dom = get_next_domain(dom, true)) {
+            dom = get_next_domain(dom, SSS_GND_DESCEND)) {
         p = sbus_opath_compose(ireq, IFP_PATH_DOMAINS, dom->name);
         if (p == NULL) {
             DEBUG(SSSDBG_MINOR_FAILURE,
@@ -221,7 +221,7 @@ static void ifp_find_domain_by_name_process(struct tevent_req *req)
     /* Reply with the domain that was asked for */
     for (iter = ireq->ifp_ctx->rctx->domains;
             iter != NULL;
-            iter = get_next_domain(iter, true)) {
+            iter = get_next_domain(iter, SSS_GND_DESCEND)) {
         if (strcasecmp(iter->name, state->name) == 0) {
             break;
         }
@@ -271,7 +271,8 @@ get_domain_info_from_req(struct sbus_request *dbus_req, void *data)
     DEBUG(SSSDBG_TRACE_INTERNAL, "Looking for domain %s\n", name);
 
     domains = ctx->rctx->domains;
-    for (iter = domains; iter != NULL; iter = get_next_domain(iter, true)) {
+    for (iter = domains; iter != NULL;
+            iter = get_next_domain(iter, SSS_GND_DESCEND)) {
         if (strcasecmp(iter->name, name) == 0) {
             break;
         }
diff --git a/src/responder/ifp/ifp_groups.c b/src/responder/ifp/ifp_groups.c
index 3060035..88c6ce6 100644
--- a/src/responder/ifp/ifp_groups.c
+++ b/src/responder/ifp/ifp_groups.c
@@ -315,7 +315,7 @@ static void ifp_groups_list_by_name_done(struct tevent_req *req)
         return;
     }
 
-    list_ctx->dom = get_next_domain(list_ctx->dom, true);
+    list_ctx->dom = get_next_domain(list_ctx->dom, SSS_GND_DESCEND);
     if (list_ctx->dom == NULL) {
         return ifp_groups_list_by_name_reply(list_ctx);
     }
diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c
index effefdc..96d4f81 100644
--- a/src/responder/ifp/ifp_users.c
+++ b/src/responder/ifp/ifp_users.c
@@ -403,7 +403,7 @@ static void ifp_users_list_by_name_done(struct tevent_req *req)
         return;
     }
 
-    list_ctx->dom = get_next_domain(list_ctx->dom, true);
+    list_ctx->dom = get_next_domain(list_ctx->dom, SSS_GND_DESCEND);
     if (list_ctx->dom == NULL) {
         return ifp_users_list_by_name_reply(list_ctx);
     }
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index ec7e728..c48b51a 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -135,7 +135,7 @@ void nss_update_pw_memcache(struct nss_ctx *nctx)
 
     now = time(NULL);
 
-    for (dom = nctx->rctx->domains; dom; dom = get_next_domain(dom, false)) {
+    for (dom = nctx->rctx->domains; dom; dom = get_next_domain(dom, 0)) {
         ret = sysdb_enumpwent_with_views(nctx, dom, &res);
         if (ret != EOK) {
             DEBUG(SSSDBG_CRIT_FAILURE,
@@ -857,7 +857,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx)
          * qualified names instead */
         while (dom && cmdctx->check_next && dom->fqnames
                 && !cmdctx->name_is_upn) {
-            dom = get_next_domain(dom, false);
+            dom = get_next_domain(dom, 0);
         }
 
         if (!dom) break;
@@ -895,7 +895,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx)
                    name, dom->name);
             /* if a multidomain search, try with next */
             if (cmdctx->check_next) {
-                dom = get_next_domain(dom, false);
+                dom = get_next_domain(dom, 0);
                 continue;
             }
             /* There are no further domains or this was a
@@ -970,7 +970,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx)
 
             /* if a multidomain search, try with next */
             if (cmdctx->check_next) {
-                dom = get_next_domain(dom, false);
+                dom = get_next_domain(dom, 0);
                 if (dom) continue;
             }
 
@@ -1087,7 +1087,7 @@ static void nss_cmd_getby_dp_callback(uint16_t err_maj, uint32_t err_min,
     struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
     struct cli_ctx *cctx = cmdctx->cctx;
     int ret;
-    bool check_subdomains;
+    uint32_t gnd_flags;
     struct nss_ctx *nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
 
     if (err_maj) {
@@ -1133,7 +1133,7 @@ static void nss_cmd_getby_dp_callback(uint16_t err_maj, uint32_t err_min,
 
         /* Since subdomain users and groups are fully qualified they are
          * typically not subject of multi-domain searches. But since POSIX
-         * ID do not contain a domain name we have to decend to subdomains
+         * ID do not contain a domain name we have to descend to subdomains
          * here. */
         switch (dctx->cmdctx->cmd) {
         case SSS_NSS_GETPWUID:
@@ -1144,7 +1144,7 @@ static void nss_cmd_getby_dp_callback(uint16_t err_maj, uint32_t err_min,
                       "Cannot set negative cache for UID %"PRIu32"\n",
                       cmdctx->id);
             }
-            check_subdomains = true;
+            gnd_flags = SSS_GND_DESCEND;
             break;
         case SSS_NSS_GETGRGID:
             ret = sss_ncache_set_gid(nctx->ncache, false, dctx->domain,
@@ -1154,7 +1154,7 @@ static void nss_cmd_getby_dp_callback(uint16_t err_maj, uint32_t err_min,
                       "Cannot set negative cache for GID %"PRIu32"\n",
                       cmdctx->id);
             }
-            check_subdomains = true;
+            gnd_flags = SSS_GND_DESCEND;
             break;
         case SSS_NSS_GETSIDBYID:
             ret = sss_ncache_set_uid(nctx->ncache, false, dctx->domain,
@@ -1171,16 +1171,17 @@ static void nss_cmd_getby_dp_callback(uint16_t err_maj, uint32_t err_min,
                       "Cannot set negative cache for GID %"PRIu32"\n",
                       cmdctx->id);
             }
-            check_subdomains = true;
+            gnd_flags = SSS_GND_DESCEND;
             break;
         default:
-            check_subdomains = false;
+            /* Do not descend to subdomains */
+            gnd_flags = 0;
         }
 
         /* no previous results, just loop to next domain if possible */
         if (cmdctx->check_next &&
-            get_next_domain(dctx->domain, check_subdomains)) {
-            dctx->domain = get_next_domain(dctx->domain, check_subdomains);
+            get_next_domain(dctx->domain, gnd_flags)) {
+            dctx->domain = get_next_domain(dctx->domain, gnd_flags);
             dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
         } else {
             /* nothing available */
@@ -1652,7 +1653,7 @@ static int nss_cmd_getpwuid_search(struct nss_dom_ctx *dctx)
                       "(id out of range)\n",
                       cmdctx->id, dom->name);
             if (cmdctx->check_next) {
-                dom = get_next_domain(dom, true);
+                dom = get_next_domain(dom, SSS_GND_DESCEND);
                 continue;
             }
             ret = ENOENT;
@@ -1699,7 +1700,7 @@ static int nss_cmd_getpwuid_search(struct nss_dom_ctx *dctx)
         if (dctx->res->count == 0 && !dctx->check_provider) {
             /* if a multidomain search, try with next */
             if (cmdctx->check_next) {
-                dom = get_next_domain(dom, true);
+                dom = get_next_domain(dom, SSS_GND_DESCEND);
                 continue;
             }
 
@@ -2057,7 +2058,8 @@ struct tevent_req *nss_cmd_setpwent_send(TALLOC_CTX *mem_ctx,
     }
 
     /* check if enumeration is enabled in any domain */
-    for (dom = client->rctx->domains; dom; dom = get_next_domain(dom, true)) {
+    for (dom = client->rctx->domains; dom;
+            dom = get_next_domain(dom, SSS_GND_DESCEND)) {
         if (dom->enumerate == true) break;
     }
     state->dctx->domain = dom;
@@ -2169,7 +2171,7 @@ static errno_t nss_cmd_setpwent_step(struct setent_step_ctx *step_ctx)
 
     while (dom) {
         while (dom && dom->enumerate == false) {
-            dom = get_next_domain(dom, true);
+            dom = get_next_domain(dom, SSS_GND_DESCEND);
         }
 
         if (!dom) break;
@@ -2229,14 +2231,14 @@ static errno_t nss_cmd_setpwent_step(struct setent_step_ctx *step_ctx)
             DEBUG(SSSDBG_CRIT_FAILURE,
                   "Enum from cache failed, skipping domain [%s]\n",
                       dom->name);
-            dom = get_next_domain(dom, true);
+            dom = get_next_domain(dom, SSS_GND_DESCEND);
             continue;
         }
 
         if (res->count == 0) {
             DEBUG(SSSDBG_CONF_SETTINGS,
                   "Domain [%s] has no users, skipping.\n", dom->name);
-            dom = get_next_domain(dom, true);
+            dom = get_next_domain(dom, SSS_GND_DESCEND);
             continue;
         }
 
@@ -2254,7 +2256,7 @@ static errno_t nss_cmd_setpwent_step(struct setent_step_ctx *step_ctx)
         nctx->pctx->num++;
 
         /* do not reply until all domain searches are done */
-        dom = get_next_domain(dom, true);
+        dom = get_next_domain(dom, SSS_GND_DESCEND);
     }
 
     /* We've finished all our lookups
@@ -2556,7 +2558,7 @@ void nss_update_gr_memcache(struct nss_ctx *nctx)
 
     now = time(NULL);
 
-    for (dom = nctx->rctx->domains; dom; dom = get_next_domain(dom, false)) {
+    for (dom = nctx->rctx->domains; dom; dom = get_next_domain(dom, 0)) {
         ret = sysdb_enumgrent_with_views(nctx, dom, &res);
         if (ret != EOK) {
             DEBUG(SSSDBG_CRIT_FAILURE,
@@ -3062,7 +3064,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx)
        /* if it is a domainless search, skip domains that require fully
          * qualified names instead */
         while (dom && cmdctx->check_next && dom->fqnames) {
-            dom = get_next_domain(dom, false);
+            dom = get_next_domain(dom, 0);
         }
 
         if (!dom) break;
@@ -3100,7 +3102,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx)
                    name, dom->name);
             /* if a multidomain search, try with next */
             if (cmdctx->check_next) {
-                dom = get_next_domain(dom, false);
+                dom = get_next_domain(dom, 0);
                 continue;
             }
             /* There are no further domains or this was a
@@ -3145,7 +3147,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx)
 
             /* if a multidomain search, try with next */
             if (cmdctx->check_next) {
-                dom = get_next_domain(dom, false);
+                dom = get_next_domain(dom, 0);
                 if (dom) continue;
             }
 
@@ -3233,7 +3235,7 @@ static int nss_cmd_getgrgid_search(struct nss_dom_ctx *dctx)
                       "(id out of range)\n",
                       cmdctx->id, dom->name);
             if (cmdctx->check_next) {
-                dom = get_next_domain(dom, true);
+                dom = get_next_domain(dom, SSS_GND_DESCEND);
                 continue;
             }
             ret = ENOENT;
@@ -3280,7 +3282,7 @@ static int nss_cmd_getgrgid_search(struct nss_dom_ctx *dctx)
         if (dctx->res->count == 0 && !dctx->check_provider) {
             /* if a multidomain search, try with next */
             if (cmdctx->check_next) {
-                dom = get_next_domain(dom, true);
+                dom = get_next_domain(dom, SSS_GND_DESCEND);
                 continue;
             }
 
@@ -3418,7 +3420,8 @@ struct tevent_req *nss_cmd_setgrent_send(TALLOC_CTX *mem_ctx,
     }
 
     /* check if enumeration is enabled in any domain */
-    for (dom = client->rctx->domains; dom; dom = get_next_domain(dom, true)) {
+    for (dom = client->rctx->domains; dom;
+            dom = get_next_domain(dom, SSS_GND_DESCEND)) {
         if (dom->enumerate == true) break;
     }
     state->dctx->domain = dom;
@@ -3530,7 +3533,7 @@ static errno_t nss_cmd_setgrent_step(struct setent_step_ctx *step_ctx)
 
     while (dom) {
         while (dom && dom->enumerate == false) {
-            dom = get_next_domain(dom, true);
+            dom = get_next_domain(dom, SSS_GND_DESCEND);
         }
 
         if (!dom) break;
@@ -3590,14 +3593,14 @@ static errno_t nss_cmd_setgrent_step(struct setent_step_ctx *step_ctx)
             DEBUG(SSSDBG_CRIT_FAILURE,
                   "Enum from cache failed, skipping domain [%s]\n",
                       dom->name);
-            dom = get_next_domain(dom, true);
+            dom = get_next_domain(dom, SSS_GND_DESCEND);
             continue;
         }
 
         if (res->count == 0) {
             DEBUG(SSSDBG_CONF_SETTINGS,
                   "Domain [%s] has no groups, skipping.\n", dom->name);
-            dom = get_next_domain(dom, true);
+            dom = get_next_domain(dom, SSS_GND_DESCEND);
             continue;
         }
 
@@ -3615,7 +3618,7 @@ static errno_t nss_cmd_setgrent_step(struct setent_step_ctx *step_ctx)
         nctx->gctx->num++;
 
         /* do not reply until all domain searches are done */
-        dom = get_next_domain(dom, true);
+        dom = get_next_domain(dom, SSS_GND_DESCEND);
     }
 
     /* We've finished all our lookups
@@ -3907,7 +3910,7 @@ void nss_update_initgr_memcache(struct nss_ctx *nctx,
     int ret;
     int i, j;
 
-    for (dom = nctx->rctx->domains; dom; dom = get_next_domain(dom, false)) {
+    for (dom = nctx->rctx->domains; dom; dom = get_next_domain(dom, 0)) {
         if (strcasecmp(dom->name, domain) == 0) {
             break;
         }
@@ -4176,7 +4179,7 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx)
          * qualified names instead */
         while (dom && cmdctx->check_next && dom->fqnames
                 && !cmdctx->name_is_upn) {
-            dom = get_next_domain(dom, false);
+            dom = get_next_domain(dom, 0);
         }
 
         if (!dom) break;
@@ -4216,7 +4219,7 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx)
                    name, dom->name);
             /* if a multidomain search, try with next */
             if (cmdctx->check_next) {
-                dom = get_next_domain(dom, false);
+                dom = get_next_domain(dom, 0);
                 continue;
             }
             /* There are no further domains or this was a
@@ -4290,7 +4293,7 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx)
 
             /* if a multidomain search, try with next */
             if (cmdctx->check_next) {
-                dom = get_next_domain(dom, false);
+                dom = get_next_domain(dom, 0);
                 if (dom) continue;
             }
 
@@ -4387,7 +4390,7 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
                        "(id out of range)\n",
                        cmdctx->id, dom->name);
                 if (cmdctx->check_next) {
-                    dom = get_next_domain(dom, true);
+                    dom = get_next_domain(dom, SSS_GND_DESCEND);
                     continue;
                 }
                 ret = ENOENT;
@@ -4397,7 +4400,7 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
            /* if it is a domainless search, skip domains that require fully
             * qualified names instead */
             while (dom && cmdctx->check_next && dom->fqnames) {
-                dom = get_next_domain(dom, false);
+                dom = get_next_domain(dom, 0);
             }
 
             if (!dom) break;
@@ -4428,7 +4431,7 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
                     /* if a multidomain search, try with next, including
                      * sub-domains */
                     if (cmdctx->check_next) {
-                        dom = get_next_domain(dom, true);
+                        dom = get_next_domain(dom, SSS_GND_DESCEND);
                         continue;
                     }
                     /* There are no further domains. */
@@ -4484,7 +4487,7 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
                            name, dom->name);
                     /* if a multidomain search, try with next */
                     if (cmdctx->check_next) {
-                        dom = get_next_domain(dom, false);
+                        dom = get_next_domain(dom, 0);
                         continue;
                     }
                     /* There are no further domains or this was a
@@ -4613,7 +4616,7 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
             }
             /* if a multidomain search, try with next */
             if (cmdctx->check_next) {
-                dom = get_next_domain(dom, true);
+                dom = get_next_domain(dom, SSS_GND_DESCEND);
                 continue;
             }
 
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index c710438..bee4552 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -525,7 +525,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
             /* This netgroup was not found in this domain */
             if (!step_ctx->dctx->check_provider) {
                 if (step_ctx->check_next) {
-                    dom = get_next_domain(dom, false);
+                    dom = get_next_domain(dom, 0);
                     continue;
                 } else {
                     break;
@@ -556,7 +556,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
 
             if (!step_ctx->dctx->check_provider) {
                 if (step_ctx->check_next) {
-                    dom = get_next_domain(dom, false);
+                    dom = get_next_domain(dom, 0);
                     continue;
                 }
                 else break;
@@ -646,8 +646,8 @@ static void lookup_netgr_dp_callback(uint16_t err_maj, uint32_t err_min,
                   "Will try to return what we have in cache\n",
                   (unsigned int)err_maj, (unsigned int)err_min, err_msg);
         /* Loop to the next domain if possible */
-        if (cmdctx->check_next && get_next_domain(dctx->domain, false)) {
-            dctx->domain = get_next_domain(dctx->domain, false);
+        if (cmdctx->check_next && get_next_domain(dctx->domain, 0)) {
+            dctx->domain = get_next_domain(dctx->domain, 0);
             dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
         }
     }
diff --git a/src/responder/nss/nsssrv_services.c b/src/responder/nss/nsssrv_services.c
index f6abc44..a9fdeb6 100644
--- a/src/responder/nss/nsssrv_services.c
+++ b/src/responder/nss/nsssrv_services.c
@@ -97,7 +97,7 @@ getserv_send(TALLOC_CTX *mem_ctx,
     if (!req) return NULL;
     state->dctx = dctx;
 
-    for (dom = cctx->rctx->domains; dom; dom = get_next_domain(dom, false)) {
+    for (dom = cctx->rctx->domains; dom; dom = get_next_domain(dom, 0)) {
         num_domains++;
     }
 
@@ -160,7 +160,7 @@ getserv_send(TALLOC_CTX *mem_ctx,
         /* if it is a domainless search, skip domains that require fully
           * qualified names instead */
          while (dom && cmdctx->check_next && dom->fqnames) {
-             dom = get_next_domain(dom, false);
+             dom = get_next_domain(dom, 0);
          }
          if (!dom) break;
 
@@ -190,7 +190,7 @@ getserv_send(TALLOC_CTX *mem_ctx,
 
                  /* If this is a multi-domain search, try the next one */
                  if (cmdctx->check_next) {
-                     dom = get_next_domain(dom, false);
+                     dom = get_next_domain(dom, 0);
                  } else {
                      /* This was a single-domain search.
                       * exit the loop. Since it was negatively-
@@ -231,7 +231,7 @@ getserv_send(TALLOC_CTX *mem_ctx,
 
                  /* If this is a multi-domain search, try the next one */
                  if (cmdctx->check_next) {
-                     dom = get_next_domain(dom, false);
+                     dom = get_next_domain(dom, 0);
                  } else {
                      /* This was a single-domain search.
                       * exit the loop. Since it was negatively-
@@ -298,7 +298,7 @@ getserv_send(TALLOC_CTX *mem_ctx,
 
              /* If this is a multi-domain search, try the next one */
              if (cmdctx->check_next) {
-                 dom = get_next_domain(dom, false);
+                 dom = get_next_domain(dom, 0);
              } else {
                  /* This was a single-domain search.
                   * exit the loop.
@@ -380,7 +380,7 @@ getserv_send(TALLOC_CTX *mem_ctx,
 
              /* If this is a multi-domain search, try the next one */
              if (cmdctx->check_next) {
-                 dom = get_next_domain(dom, false);
+                 dom = get_next_domain(dom, 0);
              } else {
                  /* This was a single-domain search.
                   * exit the loop.
@@ -1258,7 +1258,7 @@ setservent_send(TALLOC_CTX *mem_ctx, struct cli_ctx *cctx)
     num_domains = 0;
     for (dom = state->cctx->rctx->domains;
          dom;
-         dom = get_next_domain(dom, false)) {
+         dom = get_next_domain(dom, 0)) {
         num_domains++;
     }
 
@@ -1305,7 +1305,7 @@ setservent_send(TALLOC_CTX *mem_ctx, struct cli_ctx *cctx)
               "Error [%s] requesting info from domain [%s]. Skipping.\n",
                strerror(ret), step_ctx->dctx->domain->name);
 
-        step_ctx->dctx->domain = get_next_domain(step_ctx->dctx->domain, false);
+        step_ctx->dctx->domain = get_next_domain(step_ctx->dctx->domain, 0);
     }
 
     /* All domains failed */
@@ -1500,7 +1500,7 @@ setservent_step_done(struct tevent_req *req)
         svcctx->num++;
     }
 
-    step_ctx->dctx->domain = get_next_domain(step_ctx->dctx->domain, false);
+    step_ctx->dctx->domain = get_next_domain(step_ctx->dctx->domain, 0);
 
     while (step_ctx->dctx->domain) {
         /* There are more domains to check */
@@ -1514,7 +1514,7 @@ setservent_step_done(struct tevent_req *req)
               "Error [%s] requesting info from domain [%s]. Skipping.\n",
                strerror(ret), step_ctx->dctx->domain->name);
 
-        step_ctx->dctx->domain = get_next_domain(step_ctx->dctx->domain, false);
+        step_ctx->dctx->domain = get_next_domain(step_ctx->dctx->domain, 0);
     }
 
     /* All domains have been checked */
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index aa5c209..504e8e6 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1099,7 +1099,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
         } else {
             for (dom = preq->cctx->rctx->domains;
                  dom;
-                 dom = get_next_domain(dom, false)) {
+                 dom = get_next_domain(dom, 0)) {
                 if (dom->fqnames) continue;
 
                 ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout,
@@ -1384,7 +1384,7 @@ static int pam_check_user_search(struct pam_auth_req *preq)
         * qualified names instead */
         while (dom && !preq->pd->domain && !preq->pd->name_is_upn
                && dom->fqnames) {
-            dom = get_next_domain(dom, false);
+            dom = get_next_domain(dom, 0);
         }
 
         if (!dom) break;
@@ -1480,7 +1480,7 @@ static int pam_check_user_search(struct pam_auth_req *preq)
 
             /* if a multidomain search, try with next */
             if (!preq->pd->domain) {
-                dom = get_next_domain(dom, false);
+                dom = get_next_domain(dom, 0);
                 continue;
             }
 
diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
index a0b09e6..33236e0 100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -93,7 +93,7 @@ static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx)
        /* if it is a domainless search, skip domains that require fully
         * qualified names instead */
         while (dom && cmd_ctx->check_next && dom->fqnames) {
-            dom = get_next_domain(dom, false);
+            dom = get_next_domain(dom, 0);
         }
 
         if (!dom) break;
@@ -140,7 +140,7 @@ static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx)
             /* if a multidomain search, try with next */
             if (cmd_ctx->check_next) {
                 dctx->check_provider = true;
-                dom = get_next_domain(dom, false);
+                dom = get_next_domain(dom, 0);
                 if (dom) continue;
             }
 
@@ -200,7 +200,7 @@ static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx)
             /* if a multidomain search, try with next */
             if (cmd_ctx->check_next) {
                 dctx->check_provider = true;
-                dom = get_next_domain(dom, false);
+                dom = get_next_domain(dom, 0);
                 if (dom) continue;
             }
 
diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c
index c7ebe09..576969e 100644
--- a/src/tests/cmocka/test_utils.c
+++ b/src/tests/cmocka/test_utils.c
@@ -537,11 +537,11 @@ static void test_get_next_domain(void **state)
                                                       struct dom_list_test_ctx);
     struct sss_domain_info *dom = NULL;
 
-    dom = get_next_domain(test_ctx->dom_list, false);
+    dom = get_next_domain(test_ctx->dom_list, 0);
     assert_non_null(dom);
     assert_string_equal(dom->name, "dom2");
 
-    dom = get_next_domain(dom, false);
+    dom = get_next_domain(dom, 0);
     assert_null(dom);
 }
 
@@ -551,23 +551,23 @@ static void test_get_next_domain_descend(void **state)
                                                       struct dom_list_test_ctx);
     struct sss_domain_info *dom = NULL;
 
-    dom = get_next_domain(test_ctx->dom_list, true);
+    dom = get_next_domain(test_ctx->dom_list, SSS_GND_DESCEND);
     assert_non_null(dom);
     assert_string_equal(dom->name, "sub1a");
 
-    dom = get_next_domain(dom, true);
+    dom = get_next_domain(dom, SSS_GND_DESCEND);
     assert_non_null(dom);
     assert_string_equal(dom->name, "dom2");
 
-    dom = get_next_domain(dom, true);
+    dom = get_next_domain(dom, SSS_GND_DESCEND);
     assert_non_null(dom);
     assert_string_equal(dom->name, "sub2a");
 
-    dom = get_next_domain(dom, true);
+    dom = get_next_domain(dom, SSS_GND_DESCEND);
     assert_non_null(dom);
     assert_string_equal(dom->name, "sub2b");
 
-    dom = get_next_domain(dom, false);
+    dom = get_next_domain(dom, 0);
     assert_null(dom);
 }
 
@@ -577,12 +577,17 @@ static void test_get_next_domain_disabled(void **state)
                                                       struct dom_list_test_ctx);
     struct sss_domain_info *dom = NULL;
 
-    for (dom = test_ctx->dom_list; dom; dom = get_next_domain(dom, true)) {
+    for (dom = test_ctx->dom_list; dom;
+            dom = get_next_domain(dom, SSS_GND_DESCEND)) {
         dom->disabled = true;
     }
 
-    dom = get_next_domain(test_ctx->dom_list, true);
+    dom = get_next_domain(test_ctx->dom_list, SSS_GND_DESCEND);
     assert_null(dom);
+
+    dom = get_next_domain(test_ctx->dom_list,
+                          SSS_GND_DESCEND | SSS_GND_INCLUDE_DISABLED);
+    assert_non_null(dom);
 }
 
 struct name_init_test_ctx {
diff --git a/src/tools/common/sss_tools.c b/src/tools/common/sss_tools.c
index d50e9af..5733242 100644
--- a/src/tools/common/sss_tools.c
+++ b/src/tools/common/sss_tools.c
@@ -121,7 +121,8 @@ static errno_t sss_tool_domains_init(TALLOC_CTX *mem_ctx,
         return ret;
     }
 
-    for (dom = domains; dom != NULL; dom = get_next_domain(dom, true)) {
+    for (dom = domains; dom != NULL;
+            dom = get_next_domain(dom, SSS_GND_DESCEND)) {
         if (!IS_SUBDOMAIN(dom)) {
             /* Update list of subdomains for this domain */
             ret = sysdb_update_subdomains(dom);
@@ -133,7 +134,8 @@ static errno_t sss_tool_domains_init(TALLOC_CTX *mem_ctx,
         }
     }
 
-    for (dom = domains; dom != NULL; dom = get_next_domain(dom, true)) {
+    for (dom = domains; dom != NULL;
+            dom = get_next_domain(dom, SSS_GND_DESCEND)) {
         ret = sss_names_init(mem_ctx, confdb, dom->name, &dom->names);
         if (ret != EOK) {
             DEBUG(SSSDBG_CRIT_FAILURE, "sss_names_init() failed\n");
diff --git a/src/tools/sss_cache.c b/src/tools/sss_cache.c
index c9bf249..88895e8 100644
--- a/src/tools/sss_cache.c
+++ b/src/tools/sss_cache.c
@@ -128,7 +128,8 @@ int main(int argc, const char *argv[])
         goto done;
     }
 
-    for (dinfo = tctx->domains; dinfo; dinfo = get_next_domain(dinfo, true)) {
+    for (dinfo = tctx->domains; dinfo;
+            dinfo = get_next_domain(dinfo, SSS_GND_DESCEND)) {
         if (!IS_SUBDOMAIN(dinfo)) {
             /* Update list of subdomains for this domain */
             ret = sysdb_update_subdomains(dinfo);
@@ -555,7 +556,7 @@ errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain)
         }
     }
 
-    for (dinfo = ctx->domains; dinfo; dinfo = get_next_domain(dinfo, false)) {
+    for (dinfo = ctx->domains; dinfo; dinfo = get_next_domain(dinfo, 0)) {
         ret = sss_names_init(ctx, ctx->confdb, dinfo->name, &dinfo->names);
         if (ret != EOK) {
             DEBUG(SSSDBG_CRIT_FAILURE, "sss_names_init() failed\n");
diff --git a/src/tools/sss_debuglevel.c b/src/tools/sss_debuglevel.c
index 333de21..e1467c0 100644
--- a/src/tools/sss_debuglevel.c
+++ b/src/tools/sss_debuglevel.c
@@ -261,7 +261,7 @@ errno_t get_confdb_sections(TALLOC_CTX *ctx, struct confdb_ctx *confdb,
 
     for (domain = domain_list;
          domain;
-         domain = get_next_domain(domain, false)) {
+         domain = get_next_domain(domain, 0)) {
         domain_count++;
     }
 
@@ -286,7 +286,7 @@ errno_t get_confdb_sections(TALLOC_CTX *ctx, struct confdb_ctx *confdb,
 
     for (domain = domain_list;
          domain;
-         domain = get_next_domain(domain, false), i++) {
+         domain = get_next_domain(domain, 0), i++) {
         sections[i] = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL,
                                       domain->name);
         if (sections[i] == NULL) {
diff --git a/src/tools/sss_override.c b/src/tools/sss_override.c
index ee8351e..e115af2 100644
--- a/src/tools/sss_override.c
+++ b/src/tools/sss_override.c
@@ -1199,7 +1199,7 @@ static int override_user_export(struct sss_cmdline *cmdline,
 
         /* All overrides are under the same subtree, so we don't want to
          * descent into subdomains. */
-        dom = get_next_domain(dom, false);
+        dom = get_next_domain(dom, 0);
     } while (dom != NULL);
 
     exit = EXIT_SUCCESS;
@@ -1400,7 +1400,7 @@ static int override_group_export(struct sss_cmdline *cmdline,
 
         /* All overrides are under the same subtree, so we don't want to
          * descent into subdomains. */
-        dom = get_next_domain(dom, false);
+        dom = get_next_domain(dom, 0);
     } while (dom != NULL);
 
     exit = EXIT_SUCCESS;
diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
index 4eabcff..ecd0389 100644
--- a/src/util/domain_info_utils.c
+++ b/src/util/domain_info_utils.c
@@ -35,9 +35,11 @@ struct sss_domain_info *get_domains_head(struct sss_domain_info *domain)
 }
 
 struct sss_domain_info *get_next_domain(struct sss_domain_info *domain,
-                                        bool descend)
+                                        uint32_t gnd_flags)
 {
     struct sss_domain_info *dom;
+    bool descend = gnd_flags & SSS_GND_DESCEND;
+    bool include_disabled = gnd_flags & SSS_GND_INCLUDE_DISABLED;
 
     dom = domain;
     while (dom) {
@@ -50,7 +52,14 @@ struct sss_domain_info *get_next_domain(struct sss_domain_info *domain,
         } else {
             dom = NULL;
         }
-        if (dom && !dom->disabled) break;
+        if (dom) {
+            if (dom->disabled && !include_disabled) {
+                continue;
+            } else {
+                /* Next domain found. */
+                break;
+            }
+        }
     }
 
     return dom;
@@ -92,7 +101,7 @@ struct sss_domain_info *find_domain_by_name(struct sss_domain_info *domain,
     }
 
     while (dom && dom->disabled) {
-        dom = get_next_domain(dom, true);
+        dom = get_next_domain(dom, SSS_GND_DESCEND);
     }
     while (dom) {
         if (strcasecmp(dom->name, name) == 0 ||
@@ -100,7 +109,7 @@ struct sss_domain_info *find_domain_by_name(struct sss_domain_info *domain,
              (strcasecmp(dom->flat_name, name) == 0))) {
             return dom;
         }
-        dom = get_next_domain(dom, true);
+        dom = get_next_domain(dom, SSS_GND_DESCEND);
     }
 
     return NULL;
@@ -120,7 +129,7 @@ struct sss_domain_info *find_domain_by_sid(struct sss_domain_info *domain,
     sid_len = strlen(sid);
 
     while (dom && dom->disabled) {
-        dom = get_next_domain(dom, true);
+        dom = get_next_domain(dom, SSS_GND_DESCEND);
     }
 
     while (dom) {
@@ -141,7 +150,7 @@ struct sss_domain_info *find_domain_by_sid(struct sss_domain_info *domain,
             }
         }
 
-        dom = get_next_domain(dom, true);
+        dom = get_next_domain(dom, SSS_GND_DESCEND);
     }
 
     return NULL;
@@ -344,9 +353,9 @@ sss_write_domain_mappings(struct sss_domain_info *domain)
         goto done;
     }
 
-    for (dom = get_next_domain(domain, true);
+    for (dom = get_next_domain(domain, SSS_GND_DESCEND);
          dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
-         dom = get_next_domain(dom, false)) {
+         dom = get_next_domain(dom, 0)) {
         ret = fprintf(fstream, ".%s = %s\n%s = %s\n",
                                dom->name, dom->realm, dom->name, dom->realm);
         if (ret < 0) {
@@ -363,9 +372,9 @@ sss_write_domain_mappings(struct sss_domain_info *domain)
         goto done;
     }
 
-    for (dom = get_next_domain(domain, true);
+    for (dom = get_next_domain(domain, SSS_GND_DESCEND);
             dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
-            dom = get_next_domain(dom, false)) {
+            dom = get_next_domain(dom, 0)) {
 
         if (dom->forest == NULL) {
             continue;
@@ -479,7 +488,7 @@ errno_t get_dom_names(TALLOC_CTX *mem_ctx,
     dom = start_dom;
     while (dom) {
         count++;
-        dom = get_next_domain(dom, false);
+        dom = get_next_domain(dom, 0);
     }
 
     dom_names = talloc_array(tmp_ctx, char*, count);
@@ -497,7 +506,7 @@ errno_t get_dom_names(TALLOC_CTX *mem_ctx,
             ret = ENOMEM;
             goto done;
         }
-        dom = get_next_domain(dom, false);
+        dom = get_next_domain(dom, 0);
         i++;
     }
 
diff --git a/src/util/usertools.c b/src/util/usertools.c
index ccbf7a0..18639d9 100644
--- a/src/util/usertools.c
+++ b/src/util/usertools.c
@@ -423,7 +423,7 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx,
     rname = NULL;
     rdomain = NULL;
 
-    for (dom = domains; dom != NULL; dom = get_next_domain(dom, false)) {
+    for (dom = domains; dom != NULL; dom = get_next_domain(dom, 0)) {
         ret = sss_parse_name(tmp_ctx, dom->names, orig, &dmatch, &nmatch);
         if (ret == EOK) {
             /*
@@ -481,7 +481,7 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx,
                     goto done;
                 }
 
-                for (dom = domains; dom != NULL; dom = get_next_domain(dom, false)) {
+                for (dom = domains; dom != NULL; dom = get_next_domain(dom, 0)) {
                     match = match_any_domain_or_subdomain_name(dom, rdomain);
                     if (match != NULL) {
                         break;
diff --git a/src/util/util.h b/src/util/util.h
index 3e29e74..3ed7f12 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -559,8 +559,10 @@ void to_sized_string(struct sized_string *out, const char *in);
 /* from domain_info.c */
 struct sss_domain_info *get_domains_head(struct sss_domain_info *domain);
 
+#define SSS_GND_DESCEND 0x01
+#define SSS_GND_INCLUDE_DISABLED 0x02
 struct sss_domain_info *get_next_domain(struct sss_domain_info *domain,
-                                        bool descend);
+                                        uint32_t gnd_flags);
 struct sss_domain_info *find_domain_by_name(struct sss_domain_info *domain,
                                             const char *name,
                                             bool match_any);
-- 
2.1.0

