URL: https://github.com/SSSD/sssd/pull/187
Author: fidencio
 Title: #187: Add support to lookup for users/groups in subdomains just by the 
user shortname
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/187/head:pr187
git checkout pr187
From 87a447bb7c101eda7a44c3b280208d4ca5362689 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <[email protected]>
Date: Fri, 24 Feb 2017 21:58:45 +0100
Subject: [PATCH 1/7] CACHE_REQ: Move cache_req_next_domain() into a new tevent
 request
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This change prepares for the upcoming patch, which will have to support
more than one iteration over all domains, leaving us with a better
control of the whole logic around this iteration.

Related:
https://pagure.io/SSSD/sssd/issue/3001

Signed-off-by: Fabiano Fidêncio <[email protected]>
---
 src/responder/common/cache_req/cache_req.c | 504 +++++++++++++++++++----------
 1 file changed, 334 insertions(+), 170 deletions(-)

diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c
index 16429c6..a88ee22 100644
--- a/src/responder/common/cache_req/cache_req.c
+++ b/src/responder/common/cache_req/cache_req.c
@@ -307,7 +307,7 @@ cache_req_assume_upn(struct cache_req *cr)
     return true;
 }
 
-struct cache_req_state {
+struct cache_req_search_domains_state {
     /* input data */
     struct tevent_context *ev;
     struct cache_req *cr;
@@ -321,6 +321,312 @@ struct cache_req_state {
     bool dp_success;
 };
 
+static struct tevent_req *
+cache_req_search_domains_send(TALLOC_CTX *mem_ctx,
+                              struct tevent_context *ev,
+                              struct cache_req *cr,
+                              struct sss_domain_info *domain,
+                              bool check_next);
+
+static errno_t cache_req_search_domains_next(struct tevent_req *req);
+
+static errno_t cache_req_select_domains(struct tevent_req *req,
+                                        const char *domain_name);
+
+static void cache_req_search_domains_done(struct tevent_req *subreq);
+
+static errno_t
+cache_req_search_domains_add_result(
+                                struct cache_req_search_domains_state *state,
+                                struct cache_req_result *new)
+{
+    struct cache_req_result **results = state->results;
+    size_t index;
+    size_t count;
+
+    /* Make space for new results. */
+    index = state->num_results;
+    count = state->num_results + 1;
+
+    results = talloc_realloc(state, results, struct cache_req_result *, count + 1);
+    if (results == NULL) {
+        return ENOMEM;
+    }
+
+    results[index] = talloc_steal(results, new);
+    results[index + 1] = NULL;
+    state->results = results;
+    state->num_results = count;
+
+    return EOK;
+}
+
+static errno_t
+cache_req_search_domains_create_and_add_result(
+                                struct cache_req_search_domains_state *state,
+                                struct sss_domain_info *domain,
+                                struct ldb_result *ldb_result,
+                                const char *name)
+{
+    struct cache_req_result *item;
+    errno_t ret;
+
+    CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
+                    "Found %u entries in domain %s\n",
+                    ldb_result->count, domain->name);
+
+    item = cache_req_create_result(state, domain, ldb_result, name, NULL);
+    if (item == NULL) {
+        return ENOMEM;
+    }
+
+    ret = cache_req_search_domains_add_result(state, item);
+    if (ret != EOK) {
+        talloc_free(item);
+    }
+
+    return ret;
+}
+
+struct tevent_req *cache_req_search_domains_send(TALLOC_CTX *mem_ctx,
+                                                 struct tevent_context *ev,
+                                                 struct cache_req *cr,
+                                                 struct sss_domain_info *domain,
+                                                 bool check_next)
+{
+    struct tevent_req *req;
+    struct cache_req_search_domains_state *state = NULL;
+    errno_t ret;
+
+    req = tevent_req_create(mem_ctx,
+                            &state,
+                            struct cache_req_search_domains_state);
+    if (req == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
+        return NULL;
+    }
+
+    state->ev = ev;
+    state->cr = cr;
+
+    state->domain = domain;
+    state->check_next = check_next;
+    state->dp_success = true;
+
+    ret = cache_req_search_domains_next(req);
+    if (ret == EAGAIN) {
+        return req;
+    }
+
+    if (ret == EOK) {
+        tevent_req_done(req);
+    } else {
+        tevent_req_error(req, ret);
+    }
+
+    tevent_req_post(req, ev);
+    return req;
+}
+
+static errno_t cache_req_search_domains_next(struct tevent_req *req)
+{
+    struct cache_req_search_domains_state *state;
+    struct tevent_req *subreq;
+    struct cache_req *cr;
+    uint32_t next_domain_flag;
+    bool is_domain_valid;
+    bool allow_no_fqn;
+    errno_t ret;
+
+    state = tevent_req_data(req, struct cache_req_search_domains_state);
+    cr = state->cr;
+
+    next_domain_flag = cr->plugin->get_next_domain_flags;
+    allow_no_fqn = cr->plugin->allow_missing_fqn;
+
+    while (state->domain != NULL) {
+        /* Check if this domain is valid for this request. */
+        is_domain_valid = cache_req_validate_domain(cr, state->domain);
+        if (!is_domain_valid) {
+            state->domain = get_next_domain(state->domain, next_domain_flag);
+            continue;
+        }
+
+        /* If not specified otherwise, we skip domains that require fully
+         * qualified names on domain less search. We do not descend into
+         * subdomains here since those are implicitly qualified.
+         */
+        if (state->check_next && !allow_no_fqn && state->domain->fqnames) {
+            state->domain = get_next_domain(state->domain, 0);
+            continue;
+        }
+
+        state->selected_domain = state->domain;
+
+        if (state->domain == NULL) {
+            break;
+        }
+
+        ret = cache_req_set_domain(cr, state->domain);
+        if (ret != EOK) {
+            return ret;
+        }
+
+        subreq = cache_req_search_send(state, state->ev, cr);
+        if (subreq == NULL) {
+            return ENOMEM;
+        }
+
+        tevent_req_set_callback(subreq, cache_req_search_domains_done, req);
+
+        /* we will continue with the following domain the next time */
+        if (state->check_next) {
+            state->domain = get_next_domain(state->domain,
+                                            cr->plugin->get_next_domain_flags);
+        }
+
+        return EAGAIN;
+    }
+
+    /* If we've got some result from previous searches we want to return
+     * EOK here so the whole cache request is successfully finished. */
+    if (state->num_results > 0) {
+        return EOK;
+    }
+
+    /* We have searched all available domains and no result was found.
+     *
+     * If the plug-in uses a negative cache which is shared among all domains
+     * (e.g. unique identifiers such as user or group id or sid), we add it
+     * here and return object not found error.
+     *
+     * However, we can only set the negative cache if all data provider
+     * requests succeeded because only then we can be sure that it does
+     * not exist-
+     */
+    if (state->dp_success) {
+        cache_req_global_ncache_add(cr);
+    }
+
+    return ENOENT;
+}
+
+static void cache_req_search_domains_done(struct tevent_req *subreq)
+{
+    struct cache_req_search_domains_state *state;
+    struct ldb_result *result;
+    struct tevent_req *req;
+    struct tevent_req *req_send;
+    bool dp_success;
+    errno_t ret;
+
+    req = tevent_req_callback_data(subreq, struct tevent_req);
+    state = tevent_req_data(req, struct cache_req_search_domains_state);
+
+    ret = cache_req_search_recv(state, subreq, &result, &dp_success);
+    talloc_zfree(subreq);
+
+    /* Remember if any DP request fails. */
+    state->dp_success = !dp_success ? false : state->dp_success;
+
+    switch (ret) {
+    case EOK:
+        /* We got some data from this search. Save it. */
+        ret = cache_req_search_domains_create_and_add_result(
+                                                state,
+                                                state->selected_domain,
+                                                result,
+                                                state->cr->data->name.lookup);
+        if (ret != EOK) {
+            /* We were unable to save data. */
+            goto done;
+        }
+
+        if (!state->check_next || !state->cr->plugin->search_all_domains) {
+            /* We are not interested in more results. */
+            ret = EOK;
+            goto done;
+        }
+
+        break;
+    case ENOENT:
+        if (state->check_next == false) {
+            /* Lookup domain was specified as input.
+             * We don't want to try the next domain,
+             * but we may want to try UPN search. */
+
+            if (cache_req_assume_upn(state->cr)) {
+                /* Here we need to access the request created by cache_req_send()
+                 * in order to pass it down to cache_req_select_domains() */
+                req_send = tevent_req_callback_data(req, struct tevent_req);
+
+                /* Try UPN now. */
+                ret = cache_req_select_domains(req_send, NULL);
+                goto done;
+            }
+
+            /* Not found. */
+            ret = ENOENT;
+            goto done;
+        }
+
+        break;
+    default:
+        /* Some serious error has happened. Finish. */
+        goto done;
+    }
+
+    /* This is a domain less search, continue with the next domain. */
+    ret = cache_req_search_domains_next(req);
+
+done:
+    if (ret == ENOENT && state->results != NULL) {
+        /* We have at least one result. */
+        ret = EOK;
+    }
+
+    switch (ret) {
+    case EOK:
+        tevent_req_done(req);
+        break;
+    case EAGAIN:
+        break;
+    default:
+        tevent_req_error(req, ret);
+        break;
+    }
+
+    return;
+}
+
+static errno_t
+cache_req_search_domains_recv(TALLOC_CTX *mem_ctx,
+                              struct tevent_req *req,
+                              struct cache_req_result ***_results)
+{
+    struct cache_req_search_domains_state *state;
+
+    state = tevent_req_data(req, struct cache_req_search_domains_state);
+
+    TEVENT_REQ_RETURN_ON_ERROR(req);
+
+    if (_results != NULL) {
+        *_results = talloc_steal(mem_ctx, state->results);
+    }
+
+    return EOK;
+}
+
+struct cache_req_state {
+    /* input data */
+    struct tevent_context *ev;
+    struct cache_req *cr;
+
+    /* work data */
+    struct cache_req_result **results;
+    size_t num_results;
+};
+
 static errno_t cache_req_add_result(struct cache_req_state *state,
                                     struct cache_req_result *new);
 
@@ -331,10 +637,9 @@ static errno_t cache_req_process_input(TALLOC_CTX *mem_ctx,
 
 static void cache_req_input_parsed(struct tevent_req *subreq);
 
-static errno_t cache_req_select_domains(struct tevent_req *req,
-                                        const char *domain);
-
-static errno_t cache_req_next_domain(struct tevent_req *req);
+static errno_t cache_req_search_domains(struct tevent_req *req,
+                                        struct sss_domain_info *domain,
+                                        bool check_next);
 
 static void cache_req_done(struct tevent_req *subreq);
 
@@ -359,7 +664,6 @@ struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx,
     }
 
     state->ev = ev;
-    state->dp_success = true;
     state->cr = cr = cache_req_create(state, rctx, data, ncache, midpoint);
     if (state->cr == NULL) {
         ret = ENOMEM;
@@ -477,114 +781,55 @@ static void cache_req_input_parsed(struct tevent_req *subreq)
 }
 
 static errno_t cache_req_select_domains(struct tevent_req *req,
-                                        const char *domain)
+                                        const char *domain_name)
 {
     struct cache_req_state *state = NULL;
+    struct sss_domain_info *domain;
+    bool check_next;
 
     state = tevent_req_data(req, struct cache_req_state);
 
-    if (domain != NULL) {
+    if (domain_name != NULL) {
         CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
                         "Performing a single domain search\n");
 
-        state->domain = responder_get_domain(state->cr->rctx, domain);
-        if (state->domain == NULL) {
+        domain = responder_get_domain(state->cr->rctx, domain_name);
+        if (domain == NULL) {
             return ERR_DOMAIN_NOT_FOUND;
         }
 
-        state->check_next = false;
+        check_next = false;
     } else {
         CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
                         "Performing a multi-domain search\n");
 
-        state->domain = state->cr->rctx->domains;
-        state->check_next = true;
+        domain = state->cr->rctx->domains;
+        check_next = true;
     }
 
-    return cache_req_next_domain(req);
+    return cache_req_search_domains(req, domain, check_next);
 }
 
-static errno_t cache_req_next_domain(struct tevent_req *req)
+static errno_t cache_req_search_domains(struct tevent_req *req,
+                                        struct sss_domain_info *domain,
+                                        bool check_next)
 {
-    struct cache_req_state *state;
     struct tevent_req *subreq;
-    struct cache_req *cr;
-    uint32_t next_domain_flag;
-    bool is_domain_valid;
-    bool allow_no_fqn;
-    errno_t ret;
+    struct cache_req_state *state = NULL;
 
     state = tevent_req_data(req, struct cache_req_state);
-    cr = state->cr;
-
-    next_domain_flag = cr->plugin->get_next_domain_flags;
-    allow_no_fqn = cr->plugin->allow_missing_fqn;
 
-    while (state->domain != NULL) {
-        /* Check if this domain is valid for this request. */
-        is_domain_valid = cache_req_validate_domain(cr, state->domain);
-        if (!is_domain_valid) {
-            state->domain = get_next_domain(state->domain, next_domain_flag);
-            continue;
-        }
-
-        /* If not specified otherwise, we skip domains that require fully
-         * qualified names on domain less search. We do not descend into
-         * subdomains here since those are implicitly qualified.
-         */
-        if (state->check_next && !allow_no_fqn && state->domain->fqnames) {
-            state->domain = get_next_domain(state->domain, 0);
-            continue;
-        }
-
-        state->selected_domain = state->domain;
-
-        if (state->domain == NULL) {
-            break;
-        }
-
-        ret = cache_req_set_domain(cr, state->domain);
-        if (ret != EOK) {
-            return ret;
-        }
-
-        subreq = cache_req_search_send(state, state->ev, cr);
-        if (subreq == NULL) {
-            return ENOMEM;
-        }
-
-        tevent_req_set_callback(subreq, cache_req_done, req);
-
-        /* we will continue with the following domain the next time */
-        if (state->check_next) {
-            state->domain = get_next_domain(state->domain,
-                                            cr->plugin->get_next_domain_flags);
-        }
-
-        return EAGAIN;
-    }
-
-    /* If we've got some result from previous searches we want to return
-     * EOK here so the whole cache request is successfully finished. */
-    if (state->num_results > 0) {
-        return EOK;
-    }
-
-    /* We have searched all available domains and no result was found.
-     *
-     * If the plug-in uses a negative cache which is shared among all domains
-     * (e.g. unique identifiers such as user or group id or sid), we add it
-     * here and return object not found error.
-     *
-     * However, we can only set the negative cache if all data provider
-     * requests succeeded because only then we can be sure that it does
-     * not exist-
-     */
-    if (state->dp_success) {
-        cache_req_global_ncache_add(cr);
+    subreq = cache_req_search_domains_send(state,
+                                           state->ev,
+                                           state->cr,
+                                           domain,
+                                           check_next);
+    if (subreq == NULL) {
+        return ENOMEM;
     }
 
-    return ENOENT;
+    tevent_req_set_callback(subreq, cache_req_done, req);
+    return EAGAIN;
 }
 
 static errno_t
@@ -612,99 +857,18 @@ cache_req_add_result(struct cache_req_state *state,
     return EOK;
 }
 
-static errno_t
-cache_req_create_and_add_result(struct cache_req_state *state,
-                                struct sss_domain_info *domain,
-                                struct ldb_result *ldb_result,
-                                const char *name)
-{
-    struct cache_req_result *item;
-    errno_t ret;
-
-    CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
-                    "Found %u entries in domain %s\n",
-                    ldb_result->count, domain->name);
-
-    item = cache_req_create_result(state, domain, ldb_result, name, NULL);
-    if (item == NULL) {
-        return ENOMEM;
-    }
-
-    ret = cache_req_add_result(state, item);
-    if (ret != EOK) {
-        talloc_free(item);
-    }
-
-    return ret;
-}
-
 static void cache_req_done(struct tevent_req *subreq)
 {
     struct cache_req_state *state;
-    struct ldb_result *result;
     struct tevent_req *req;
-    bool dp_success;
     errno_t ret;
 
     req = tevent_req_callback_data(subreq, struct tevent_req);
     state = tevent_req_data(req, struct cache_req_state);
 
-    ret = cache_req_search_recv(state, subreq, &result, &dp_success);
+    ret = cache_req_search_domains_recv(state, subreq, &state->results);
     talloc_zfree(subreq);
 
-    /* Remember if any DP request fails. */
-    state->dp_success = !dp_success ? false : state->dp_success;
-
-    switch (ret) {
-    case EOK:
-        /* We got some data from this search. Save it. */
-        ret = cache_req_create_and_add_result(state, state->selected_domain,
-                                              result,
-                                              state->cr->data->name.lookup);
-        if (ret != EOK) {
-            /* We were unable to save data. */
-            goto done;
-        }
-
-        if (!state->check_next || !state->cr->plugin->search_all_domains) {
-            /* We are not interested in more results. */
-            ret = EOK;
-            goto done;
-        }
-
-        break;
-    case ENOENT:
-        if (state->check_next == false) {
-            /* Lookup domain was specified as input.
-             * We don't want to try the next domain,
-             * but we may want to try UPN search. */
-
-            if (cache_req_assume_upn(state->cr)) {
-                /* Try UPN now. */
-                ret = cache_req_select_domains(req, NULL);
-                goto done;
-            }
-
-            /* Not found. */
-            ret = ENOENT;
-            goto done;
-        }
-
-        break;
-    default:
-        /* Some serious error has happened. Finish. */
-        goto done;
-    }
-
-    /* This is a domain less search, continue with the next domain. */
-    ret = cache_req_next_domain(req);
-
-done:
-    if (ret == ENOENT && state->results != NULL) {
-        /* We have at least one result. */
-        ret = EOK;
-    }
-
     switch (ret) {
     case EOK:
         CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, "Finished: Success\n");

From bd9bcb78e4fbdad1da13b00312eaa091a63bf69f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <[email protected]>
Date: Wed, 22 Feb 2017 08:07:45 +0100
Subject: [PATCH 2/7] CACHE_REQ: Confront caches first
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch introduces a new configurable option to define whether the
responder should query all domains' caches before querying the Data
Providers.

This new option is called confront_caches_first and, by default, it's
disabled, meaning that, for each provider, the responder may contact the
cache and the data provider in the same iteration.

Related:
https://pagure.io/SSSD/sssd/issue/3001

Signed-off-by: Fabiano Fidêncio <[email protected]>
---
 src/confdb/confdb.h                                |  1 +
 src/config/SSSDConfig/__init__.py.in               |  1 +
 src/config/SSSDConfigTest.py                       |  1 +
 src/config/cfg_rules.ini                           |  7 ++++
 src/config/etc/sssd.api.conf                       |  1 +
 src/man/sssd.conf.5.xml                            | 12 ++++++
 src/responder/common/cache_req/cache_req.c         | 44 ++++++++++++++++++++--
 src/responder/common/cache_req/cache_req_private.h |  6 ++-
 src/responder/common/cache_req/cache_req_search.c  | 21 +++++++++--
 src/responder/common/responder.h                   |  1 +
 src/responder/common/responder_common.c            | 11 ++++++
 11 files changed, 98 insertions(+), 8 deletions(-)

diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 89b89bf..6e54b72 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -88,6 +88,7 @@
 #define CONFDB_RESPONDER_LOCAL_NEG_TIMEOUT "local_negative_timeout"
 #define CONFDB_RESPONDER_IDLE_TIMEOUT "responder_idle_timeout"
 #define CONFDB_RESPONDER_IDLE_DEFAULT_TIMEOUT 300
+#define CONFDB_RESPONDER_CONFRONT_CACHES_FIRST "confront_caches_first"
 
 /* NSS */
 #define CONFDB_NSS_CONF_ENTRY "config/nss"
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 44fb777..0cb8ef3 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -51,6 +51,7 @@ option_strings = {
     'fd_limit' : _('The number of file descriptors that may be opened by this responder'),
     'client_idle_timeout' : _('Idle time before automatic disconnection of a client'),
     'responder_idle_timeout' : _('Idle time before automatic shutdown of the responder'),
+    'confront_caches_first': _('Always query all the caches before querying the Data Providers'),
 
     # [sssd]
     'services' : _('SSSD Services to start'),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 8cb03ad..b6d3a18 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -309,6 +309,7 @@ def testListOptions(self):
             'fd_limit',
             'client_idle_timeout',
             'responder_idle_timeout',
+            'confront_caches_first',
             'description',
             'certificate_verification',
             'override_space',
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index c01aa85..78e62b3 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -59,6 +59,7 @@ option = fd_limit
 option = client_idle_timeout
 option = description
 option = responder_idle_timeout
+option = confront_caches_first
 
 # Name service
 option = user_attributes
@@ -97,6 +98,7 @@ option = fd_limit
 option = client_idle_timeout
 option = description
 option = responder_idle_timeout
+option = confront_caches_first
 
 # Authentication service
 option = offline_credentials_expiration
@@ -131,6 +133,7 @@ option = fd_limit
 option = client_idle_timeout
 option = description
 option = responder_idle_timeout
+option = confront_caches_first
 
 # sudo service
 option = sudo_timed
@@ -152,6 +155,7 @@ option = fd_limit
 option = client_idle_timeout
 option = description
 option = responder_idle_timeout
+option = confront_caches_first
 
 # autofs service
 option = autofs_negative_timeout
@@ -172,6 +176,7 @@ option = fd_limit
 option = client_idle_timeout
 option = description
 option = responder_idle_timeout
+option = confront_caches_first
 
 # ssh service
 option = ssh_hash_known_hosts
@@ -194,6 +199,7 @@ option = fd_limit
 option = client_idle_timeout
 option = description
 option = responder_idle_timeout
+option = confront_caches_first
 
 # PAC responder
 option = allowed_uids
@@ -215,6 +221,7 @@ option = fd_limit
 option = client_idle_timeout
 option = description
 option = responder_idle_timeout
+option = confront_caches_first
 
 # InfoPipe responder
 option = allowed_uids
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index 7d21d6b..a786483 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -14,6 +14,7 @@ reconnection_retries = int, None, false
 fd_limit = int, None, false
 client_idle_timeout = int, None, false
 responder_idle_timeout = int, None, false
+confront_caches_first = int, None, false
 description = str, None, false
 
 [sssd]
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 2a2ef69..429d896 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -662,6 +662,18 @@
                         </para>
                     </listitem>
                 </varlistentry>
+                <varlistentry>
+                    <term>confront_caches_first</term>
+                    <listitem>
+                        <para>
+                            This option specifies whether the responder should
+                            query all caches before querying the Data Providers.
+                        </para>
+                        <para>
+                            Default: false
+                        </para>
+                    </listitem>
+                </varlistentry>
             </variablelist>
         </refsect2>
 
diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c
index a88ee22..613a937 100644
--- a/src/responder/common/cache_req/cache_req.c
+++ b/src/responder/common/cache_req/cache_req.c
@@ -118,6 +118,9 @@ cache_req_create(TALLOC_CTX *mem_ctx,
         return NULL;
     }
 
+    cr->confront_caches_first = rctx->confront_caches_first;
+    cr->bypass_cache = cr->plugin->bypass_cache || cr->data->bypass_cache;
+
     return cr;
 }
 
@@ -319,6 +322,8 @@ struct cache_req_search_domains_state {
     size_t num_results;
     bool check_next;
     bool dp_success;
+    bool bypass_cache;
+    bool bypass_dp;
 };
 
 static struct tevent_req *
@@ -326,7 +331,9 @@ cache_req_search_domains_send(TALLOC_CTX *mem_ctx,
                               struct tevent_context *ev,
                               struct cache_req *cr,
                               struct sss_domain_info *domain,
-                              bool check_next);
+                              bool check_next,
+                              bool bypass_cache,
+                              bool bypass_dp);
 
 static errno_t cache_req_search_domains_next(struct tevent_req *req);
 
@@ -392,7 +399,9 @@ struct tevent_req *cache_req_search_domains_send(TALLOC_CTX *mem_ctx,
                                                  struct tevent_context *ev,
                                                  struct cache_req *cr,
                                                  struct sss_domain_info *domain,
-                                                 bool check_next)
+                                                 bool check_next,
+                                                 bool bypass_cache,
+                                                 bool bypass_dp)
 {
     struct tevent_req *req;
     struct cache_req_search_domains_state *state = NULL;
@@ -412,6 +421,8 @@ struct tevent_req *cache_req_search_domains_send(TALLOC_CTX *mem_ctx,
     state->domain = domain;
     state->check_next = check_next;
     state->dp_success = true;
+    state->bypass_cache = bypass_cache;
+    state->bypass_dp = bypass_dp;
 
     ret = cache_req_search_domains_next(req);
     if (ret == EAGAIN) {
@@ -472,7 +483,8 @@ static errno_t cache_req_search_domains_next(struct tevent_req *req)
             return ret;
         }
 
-        subreq = cache_req_search_send(state, state->ev, cr);
+        subreq = cache_req_search_send(state, state->ev, cr,
+                                       state->bypass_cache, state->bypass_dp);
         if (subreq == NULL) {
             return ENOMEM;
         }
@@ -621,10 +633,12 @@ struct cache_req_state {
     /* input data */
     struct tevent_context *ev;
     struct cache_req *cr;
+    const char *domain_name;
 
     /* work data */
     struct cache_req_result **results;
     size_t num_results;
+    bool bypass_cache;
 };
 
 static errno_t cache_req_add_result(struct cache_req_state *state,
@@ -685,6 +699,7 @@ struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
+    state->domain_name = domain;
     ret = cache_req_select_domains(req, domain);
 
 done:
@@ -773,6 +788,7 @@ static void cache_req_input_parsed(struct tevent_req *subreq)
         return;
     }
 
+    state->domain_name = domain;
     ret = cache_req_select_domains(req, domain);
     if (ret != EAGAIN) {
         tevent_req_error(req, ret);
@@ -816,14 +832,27 @@ static errno_t cache_req_search_domains(struct tevent_req *req,
 {
     struct tevent_req *subreq;
     struct cache_req_state *state = NULL;
+    bool bypass_dp;
 
     state = tevent_req_data(req, struct cache_req_state);
 
+    bypass_dp = false;
+    if (state->cr->confront_caches_first) {
+        bypass_dp = !state->bypass_cache;
+    }
+
+    CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
+                    "Search will %s the cache and %s the data provider\n",
+                    state->bypass_cache ? "bypass" : "confront",
+                    bypass_dp ? "bypass" : "confront");
+
     subreq = cache_req_search_domains_send(state,
                                            state->ev,
                                            state->cr,
                                            domain,
-                                           check_next);
+                                           check_next,
+                                           state->bypass_cache,
+                                           bypass_dp);
     if (subreq == NULL) {
         return ENOMEM;
     }
@@ -869,6 +898,13 @@ static void cache_req_done(struct tevent_req *subreq)
     ret = cache_req_search_domains_recv(state, subreq, &state->results);
     talloc_zfree(subreq);
 
+    if (state->cr->confront_caches_first && !state->bypass_cache) {
+        if (ret == ENOENT) {
+            state->bypass_cache = true;
+            ret = cache_req_select_domains(req, state->domain_name);
+        }
+    }
+
     switch (ret) {
     case EOK:
         CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, "Finished: Success\n");
diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h
index 3839f5a..8af2bdf 100644
--- a/src/responder/common/cache_req/cache_req_private.h
+++ b/src/responder/common/cache_req/cache_req_private.h
@@ -40,6 +40,8 @@ struct cache_req {
 
     /* Domain related informations. */
     struct sss_domain_info *domain;
+    bool confront_caches_first;
+    bool bypass_cache;
 
     /* Debug information */
     uint32_t reqid;
@@ -91,7 +93,9 @@ struct cache_req_data {
 struct tevent_req *
 cache_req_search_send(TALLOC_CTX *mem_ctx,
                       struct tevent_context *ev,
-                      struct cache_req *cr);
+                      struct cache_req *cr,
+                      bool bypass_cache,
+                      bool bypass_dp);
 
 errno_t cache_req_search_recv(TALLOC_CTX *mem_ctx,
                               struct tevent_req *req,
diff --git a/src/responder/common/cache_req/cache_req_search.c b/src/responder/common/cache_req/cache_req_search.c
index 612f194..f80ed00 100644
--- a/src/responder/common/cache_req/cache_req_search.c
+++ b/src/responder/common/cache_req/cache_req_search.c
@@ -181,7 +181,9 @@ static void cache_req_search_done(struct tevent_req *subreq);
 struct tevent_req *
 cache_req_search_send(TALLOC_CTX *mem_ctx,
                       struct tevent_context *ev,
-                      struct cache_req *cr)
+                      struct cache_req *cr,
+                      bool bypass_cache,
+                      bool bypass_dp)
 {
     struct cache_req_search_state *state;
     enum cache_object_status status;
@@ -214,12 +216,18 @@ cache_req_search_send(TALLOC_CTX *mem_ctx,
      */
     state->result = NULL;
     status = CACHE_OBJECT_MISSING;
-    if (!cr->plugin->bypass_cache && !cr->data->bypass_cache) {
+    if (!bypass_cache) {
         ret = cache_req_search_cache(state, cr, &state->result);
         if (ret != EOK && ret != ENOENT) {
             goto done;
         }
 
+        if (cr->confront_caches_first && ret == EOK) {
+            CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
+                            "Returning [%s] from cache\n", cr->debugobj);
+            goto done;
+        }
+
         status = cache_req_expiration_status(cr, state->result);
         if (status == CACHE_OBJECT_VALID) {
             CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr,
@@ -227,9 +235,16 @@ cache_req_search_send(TALLOC_CTX *mem_ctx,
             ret = EOK;
             goto done;
         }
+
+        if (cr->confront_caches_first && ret == ENOENT) {
+            goto done;
+        }
+    }
+
+    if (!bypass_dp) {
+        ret = cache_req_search_dp(req, status);
     }
 
-    ret = cache_req_search_dp(req, status);
     if (ret != EAGAIN) {
         goto done;
     }
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index 5717d6a..a22de7d 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -138,6 +138,7 @@ struct resp_ctx {
     bool shutting_down;
     bool socket_activated;
     bool dbus_activated;
+    bool confront_caches_first;
 };
 
 struct cli_creds;
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 5c59f0d..006853b 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -1101,6 +1101,17 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
         }
     }
 
+    ret = confdb_get_bool(rctx->cdb, rctx->confdb_service_path,
+                          CONFDB_RESPONDER_CONFRONT_CACHES_FIRST,
+                          false, &rctx->confront_caches_first);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE,
+              "Cannot get \"confront_caches_option\".\n"
+              "Querying the caches first before querying the "
+              "Data Providers will not be enforced [%d]: %s.\n",
+              ret, sss_strerror(ret));
+    }
+
     ret = confdb_get_int(rctx->cdb, rctx->confdb_service_path,
                          CONFDB_RESPONDER_GET_DOMAINS_TIMEOUT,
                          GET_DOMAINS_DEFAULT_TIMEOUT, &rctx->domains_timeout);

From 3a4623df16ba6cc6312b4a85ddb00ae1aa9ba438 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <[email protected]>
Date: Wed, 1 Mar 2017 08:34:57 +0000
Subject: [PATCH 3/7] CACHE_REQ: Descend into subdomains on lookups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Let's make all plugins, but the "host_by_name", to descend into the
subdomains on lookups.

This patch basically prepares the field for the coming up patches that
will allow group/user resolution in all domains (or a subset of the
domains) to be possible by only using the short names without the domain
component.

The "host_by_name" plugin was not changed as it's a specific IPA plugin
and won't find anything on its subdomains.

Related:
https://pagure.io/SSSD/sssd/issue/3001

Signed-off-by: Fabiano Fidêncio <[email protected]>
---
 src/responder/common/cache_req/plugins/cache_req_enum_svc.c           | 2 +-
 src/responder/common/cache_req/plugins/cache_req_group_by_filter.c    | 2 +-
 src/responder/common/cache_req/plugins/cache_req_group_by_name.c      | 2 +-
 src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c | 2 +-
 src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c   | 2 +-
 src/responder/common/cache_req/plugins/cache_req_object_by_name.c     | 2 +-
 src/responder/common/cache_req/plugins/cache_req_svc_by_name.c        | 2 +-
 src/responder/common/cache_req/plugins/cache_req_svc_by_port.c        | 2 +-
 src/responder/common/cache_req/plugins/cache_req_user_by_filter.c     | 2 +-
 src/responder/common/cache_req/plugins/cache_req_user_by_name.c       | 2 +-
 10 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/responder/common/cache_req/plugins/cache_req_enum_svc.c b/src/responder/common/cache_req/plugins/cache_req_enum_svc.c
index 2c4917c..28dea33 100644
--- a/src/responder/common/cache_req/plugins/cache_req_enum_svc.c
+++ b/src/responder/common/cache_req/plugins/cache_req_enum_svc.c
@@ -68,7 +68,7 @@ const struct cache_req_plugin cache_req_enum_svc = {
     .allow_missing_fqn = true,
     .allow_switch_to_upn = false,
     .upn_equivalent = CACHE_REQ_SENTINEL,
-    .get_next_domain_flags = 0,
+    .get_next_domain_flags = SSS_GND_DESCEND,
 
     .is_well_known_fn = NULL,
     .prepare_domain_data_fn = NULL,
diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c b/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c
index 88e1137..6ce6ae0 100644
--- a/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c
+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c
@@ -123,7 +123,7 @@ const struct cache_req_plugin cache_req_group_by_filter = {
     .allow_missing_fqn = false,
     .allow_switch_to_upn = false,
     .upn_equivalent = CACHE_REQ_SENTINEL,
-    .get_next_domain_flags = 0,
+    .get_next_domain_flags = SSS_GND_DESCEND,
 
     .is_well_known_fn = NULL,
     .prepare_domain_data_fn = cache_req_group_by_filter_prepare_domain_data,
diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_name.c b/src/responder/common/cache_req/plugins/cache_req_group_by_name.c
index be1eb9b..af6f23c 100644
--- a/src/responder/common/cache_req/plugins/cache_req_group_by_name.c
+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_name.c
@@ -186,7 +186,7 @@ const struct cache_req_plugin cache_req_group_by_name = {
     .allow_missing_fqn = false,
     .allow_switch_to_upn = false,
     .upn_equivalent = CACHE_REQ_SENTINEL,
-    .get_next_domain_flags = 0,
+    .get_next_domain_flags = SSS_GND_DESCEND,
 
     .is_well_known_fn = NULL,
     .prepare_domain_data_fn = cache_req_group_by_name_prepare_domain_data,
diff --git a/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c b/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c
index 10fb67c..307b65a 100644
--- a/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c
+++ b/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c
@@ -201,7 +201,7 @@ const struct cache_req_plugin cache_req_initgroups_by_name = {
     .allow_missing_fqn = false,
     .allow_switch_to_upn = true,
     .upn_equivalent = CACHE_REQ_INITGROUPS_BY_UPN,
-    .get_next_domain_flags = 0,
+    .get_next_domain_flags = SSS_GND_DESCEND,
 
     .is_well_known_fn = NULL,
     .prepare_domain_data_fn = cache_req_initgroups_by_name_prepare_domain_data,
diff --git a/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c b/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c
index bc6fc9a..e49d6d8 100644
--- a/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c
+++ b/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c
@@ -120,7 +120,7 @@ const struct cache_req_plugin cache_req_netgroup_by_name = {
     .allow_missing_fqn = true,
     .allow_switch_to_upn = false,
     .upn_equivalent = CACHE_REQ_SENTINEL,
-    .get_next_domain_flags = 0,
+    .get_next_domain_flags = SSS_GND_DESCEND,
 
     .is_well_known_fn = NULL,
     .prepare_domain_data_fn = cache_req_netgroup_by_name_prepare_domain_data,
diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_name.c b/src/responder/common/cache_req/plugins/cache_req_object_by_name.c
index 2b2caee..74d2b3d 100644
--- a/src/responder/common/cache_req/plugins/cache_req_object_by_name.c
+++ b/src/responder/common/cache_req/plugins/cache_req_object_by_name.c
@@ -196,7 +196,7 @@ const struct cache_req_plugin cache_req_object_by_name = {
     .allow_missing_fqn = false,
     .allow_switch_to_upn = true,
     .upn_equivalent = CACHE_REQ_USER_BY_UPN,
-    .get_next_domain_flags = 0,
+    .get_next_domain_flags = SSS_GND_DESCEND,
 
     .is_well_known_fn = cache_req_object_by_name_well_known,
     .prepare_domain_data_fn = cache_req_object_by_name_prepare_domain_data,
diff --git a/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c b/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c
index cbb186d..ef13f09 100644
--- a/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c
+++ b/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c
@@ -144,7 +144,7 @@ const struct cache_req_plugin cache_req_svc_by_name = {
     .allow_missing_fqn = false,
     .allow_switch_to_upn = false,
     .upn_equivalent = CACHE_REQ_SENTINEL,
-    .get_next_domain_flags = 0,
+    .get_next_domain_flags = SSS_GND_DESCEND,
 
     .is_well_known_fn = NULL,
     .prepare_domain_data_fn = cache_req_svc_by_name_prepare_domain_data,
diff --git a/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c b/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c
index 1da23d4..afa2eee 100644
--- a/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c
+++ b/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c
@@ -117,7 +117,7 @@ const struct cache_req_plugin cache_req_svc_by_port = {
     .allow_missing_fqn = false,
     .allow_switch_to_upn = false,
     .upn_equivalent = CACHE_REQ_SENTINEL,
-    .get_next_domain_flags = 0,
+    .get_next_domain_flags = SSS_GND_DESCEND,
 
     .is_well_known_fn = NULL,
     .prepare_domain_data_fn = cache_req_svc_by_port_prepare_domain_data,
diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c b/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c
index ee7e693..eb71b42 100644
--- a/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c
+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c
@@ -123,7 +123,7 @@ const struct cache_req_plugin cache_req_user_by_filter = {
     .allow_missing_fqn = false,
     .allow_switch_to_upn = false,
     .upn_equivalent = CACHE_REQ_SENTINEL,
-    .get_next_domain_flags = 0,
+    .get_next_domain_flags = SSS_GND_DESCEND,
 
     .is_well_known_fn = NULL,
     .prepare_domain_data_fn = cache_req_user_by_filter_prepare_domain_data,
diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_name.c b/src/responder/common/cache_req/plugins/cache_req_user_by_name.c
index 4289f5f..0670feb 100644
--- a/src/responder/common/cache_req/plugins/cache_req_user_by_name.c
+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_name.c
@@ -191,7 +191,7 @@ const struct cache_req_plugin cache_req_user_by_name = {
     .allow_missing_fqn = false,
     .allow_switch_to_upn = true,
     .upn_equivalent = CACHE_REQ_USER_BY_UPN,
-    .get_next_domain_flags = 0,
+    .get_next_domain_flags = SSS_GND_DESCEND,
 
     .is_well_known_fn = NULL,
     .prepare_domain_data_fn = cache_req_user_by_name_prepare_domain_data,

From dbc1bf20ac0845b23ce6ff22b5c6255c5b663480 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <[email protected]>
Date: Mon, 27 Feb 2017 16:50:41 +0000
Subject: [PATCH 4/7] Allow subdomains to inherit "use_fully_qualified_names"
 option
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This commit introduces the possibility to have subdomains inheriting the
"use_fully_qualified_names" option from its parent domain.

The intention behind this change is to allow user and group resolution
and user authentication in all the domains or a subset of the domains to
be possible by using only the short names without the domain component.

Related:
https://pagure.io/SSSD/sssd/issue/3001

Signed-off-by: Fabiano Fidêncio <[email protected]>
---
 src/db/sysdb_subdomains.c | 7 ++++++-
 src/man/sssd.conf.5.xml   | 3 +++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index 01f4976..6b501e8 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -118,7 +118,6 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
     }
 
     dom->enumerate = enumerate;
-    dom->fqnames = true;
     dom->mpg = mpg;
     dom->state = DOM_ACTIVE;
 
@@ -147,6 +146,12 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
     dom->service_timeout = parent->service_timeout;
     dom->names = parent->names;
 
+    /* If the parent domain requires fully-qualified names, the subdomain should
+     * do as well */
+    inherit_option = string_in_list(CONFDB_DOMAIN_FQ,
+                                    parent->sd_inherit, false);
+    dom->fqnames = inherit_option ? parent->fqnames : true;
+
     dom->override_homedir = parent->override_homedir;
     dom->fallback_homedir = parent->fallback_homedir;
     dom->subdomain_homedir = parent->subdomain_homedir;
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 429d896..6c30580 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -2491,6 +2491,9 @@ pam_account_locked_message = Account locked, please contact help desk.
                             ldap_user_principal
                         </para>
                         <para>
+                            use_fully_qualified_names
+                        </para>
+                        <para>
                             ldap_krb5_keytab (the value of krb5_keytab will be
                             used if ldap_krb5_keytab is not set explicitly)
                         </para>

From 81b17d8e167ed9b391bb7f8f2cac0e47ab9279a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Wed, 1 Mar 2017 13:21:19 +0000
Subject: [PATCH 5/7] NSS/TESTS: Fix subdomains attribution
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Related:
https://pagure.io/SSSD/sssd/issue/3001

Reviewed-by: Fabiano Fidêncio <[email protected]>
---
 src/tests/cmocka/test_nss_srv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
index 72bbaf9..d06326e 100644
--- a/src/tests/cmocka/test_nss_srv.c
+++ b/src/tests/cmocka/test_nss_srv.c
@@ -3217,7 +3217,7 @@ static int nss_subdom_test_setup(void **state)
     ret = sysdb_update_subdomains(nss_test_ctx->tctx->dom);
     assert_int_equal(ret, EOK);
 
-    nss_test_ctx->subdom = subdomain;
+    nss_test_ctx->subdom = nss_test_ctx->tctx->dom->subdomains;
     return 0;
 }
 

From 7a9efa7a3a24efd7fdb74790a568be0153463c10 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <[email protected]>
Date: Wed, 1 Mar 2017 20:46:10 +0000
Subject: [PATCH 6/7] NSS/TESTS: Improve setup/teardown for subdomains tests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch basically makes the getgrnam_members_subdom(),
getgrnam_mix_dom(), getgrnam_mix_dom_fqdn() and getgrnam_mix_subdom()
more independent of each other.

Related:
https://pagure.io/SSSD/sssd/issue/3001

Signed-off-by: Fabiano Fidêncio <[email protected]>
---
 src/tests/cmocka/test_nss_srv.c | 182 +++++++++++++++++++++++++++++++++-------
 1 file changed, 150 insertions(+), 32 deletions(-)

diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
index d06326e..ff740c7 100644
--- a/src/tests/cmocka/test_nss_srv.c
+++ b/src/tests/cmocka/test_nss_srv.c
@@ -418,6 +418,26 @@ static errno_t store_user(struct nss_test_ctx *ctx,
     return ret;
 }
 
+static errno_t delete_user(struct nss_test_ctx *ctx,
+                           struct sss_domain_info *dom,
+                           struct passwd *user)
+{
+    errno_t ret;
+    char *fqname;
+
+    fqname = sss_create_internal_fqname(ctx,
+                                        user->pw_name,
+                                        dom->name);
+    if (fqname == NULL) {
+        return ENOMEM;
+    }
+
+    ret = sysdb_delete_user(dom, fqname, user->pw_uid);
+
+    talloc_free(fqname);
+    return ret;
+}
+
 static errno_t set_user_attr(struct nss_test_ctx *ctx,
                              struct sss_domain_info *dom,
                              struct passwd *user,
@@ -491,6 +511,27 @@ static errno_t store_group(struct nss_test_ctx *ctx,
     return ret;
 }
 
+static errno_t delete_group(struct nss_test_ctx *ctx,
+                            struct sss_domain_info *dom,
+                            struct group *group)
+{
+    errno_t ret;
+    char *fqname;
+
+    fqname = sss_create_internal_fqname(ctx,
+                                        group->gr_name,
+                                        dom->name);
+
+    if (fqname == NULL) {
+        return ENOMEM;
+    }
+
+    ret = sysdb_delete_group(dom, fqname, group->gr_gid);
+
+    talloc_free(fqname);
+    return ret;
+}
+
 static void assert_groups_equal(struct group *expected,
                                 struct group *gr, const int nmem)
 {
@@ -540,6 +581,42 @@ static errno_t store_group_member(struct nss_test_ctx *ctx,
     return ret;
 }
 
+static errno_t remove_group_member(struct nss_test_ctx *ctx,
+                                   const char *shortname_group,
+                                   struct sss_domain_info *group_dom,
+                                   const char *shortname_member,
+                                   struct sss_domain_info *member_dom,
+                                   enum sysdb_member_type type)
+{
+    errno_t ret;
+    char *group_fqname = NULL;
+    char *member_fqname = NULL;
+
+    group_fqname = sss_create_internal_fqname(ctx,
+                                        shortname_group,
+                                        group_dom->name);
+    if (group_fqname == NULL) {
+        return ENOMEM;
+    }
+
+    member_fqname = sss_create_internal_fqname(ctx,
+                                        shortname_member,
+                                        member_dom->name);
+    if (member_fqname == NULL) {
+        talloc_free(group_fqname);
+        return ENOMEM;
+    }
+
+    ret = sysdb_remove_group_member(group_dom,
+                                    group_fqname,
+                                    member_fqname,
+                                    type,
+                                    false);
+
+    talloc_free(group_fqname);
+    talloc_free(member_fqname);
+    return ret;
+}
 
 /* ====================== The tests =============================== */
 struct passwd getpwnam_usr = {
@@ -1599,34 +1676,6 @@ void test_nss_getgrnam_members_subdom(void **state)
 {
     errno_t ret;
 
-    ret = store_group(nss_test_ctx, nss_test_ctx->subdom,
-                      &testsubdomgroup, 0);
-    assert_int_equal(ret, EOK);
-
-    ret = store_user(nss_test_ctx, nss_test_ctx->subdom,
-                     &submember1, NULL, 0);
-    assert_int_equal(ret, EOK);
-
-    ret = store_user(nss_test_ctx, nss_test_ctx->subdom,
-                     &submember2, NULL, 0);
-    assert_int_equal(ret, EOK);
-
-    ret = store_group_member(nss_test_ctx,
-                             testsubdomgroup.gr_name,
-                             nss_test_ctx->subdom,
-                             submember1.pw_name,
-                             nss_test_ctx->subdom,
-                             SYSDB_MEMBER_USER);
-    assert_int_equal(ret, EOK);
-
-    ret = store_group_member(nss_test_ctx,
-                             testsubdomgroup.gr_name,
-                             nss_test_ctx->subdom,
-                             submember2.pw_name,
-                             nss_test_ctx->subdom,
-                             SYSDB_MEMBER_USER);
-    assert_int_equal(ret, EOK);
-
     mock_input_user_or_group("testsubdomgroup@"TEST_SUBDOM_NAME);
     will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
     will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1757,6 +1806,14 @@ void test_nss_getgrnam_mix_dom_fqdn(void **state)
 {
     errno_t ret;
 
+    ret = store_group_member(nss_test_ctx,
+                             testgroup_members.gr_name,
+                             nss_test_ctx->tctx->dom,
+                             submember1.pw_name,
+                             nss_test_ctx->subdom,
+                             SYSDB_MEMBER_USER);
+    assert_int_equal(ret, EOK);
+
     nss_test_ctx->tctx->dom->fqnames = true;
 
     mock_input_user_or_group("testgroup_members@"TEST_DOM_NAME);
@@ -3218,6 +3275,35 @@ static int nss_subdom_test_setup(void **state)
     assert_int_equal(ret, EOK);
 
     nss_test_ctx->subdom = nss_test_ctx->tctx->dom->subdomains;
+
+    ret = store_group(nss_test_ctx, nss_test_ctx->subdom,
+                      &testsubdomgroup, 0);
+    assert_int_equal(ret, EOK);
+
+    ret = store_user(nss_test_ctx, nss_test_ctx->subdom,
+                     &submember1, NULL, 0);
+    assert_int_equal(ret, EOK);
+
+    ret = store_user(nss_test_ctx, nss_test_ctx->subdom,
+                     &submember2, NULL, 0);
+    assert_int_equal(ret, EOK);
+
+    ret = store_group_member(nss_test_ctx,
+                             testsubdomgroup.gr_name,
+                             nss_test_ctx->subdom,
+                             submember1.pw_name,
+                             nss_test_ctx->subdom,
+                             SYSDB_MEMBER_USER);
+    assert_int_equal(ret, EOK);
+
+    ret = store_group_member(nss_test_ctx,
+                             testsubdomgroup.gr_name,
+                             nss_test_ctx->subdom,
+                             submember2.pw_name,
+                             nss_test_ctx->subdom,
+                             SYSDB_MEMBER_USER);
+    assert_int_equal(ret, EOK);
+
     return 0;
 }
 
@@ -3239,6 +3325,38 @@ static int nss_test_teardown(void **state)
     return 0;
 }
 
+static int nss_subdom_test_teardown(void **state)
+{
+    errno_t ret;
+
+    ret = remove_group_member(nss_test_ctx,
+                              testsubdomgroup.gr_name,
+                              nss_test_ctx->subdom,
+                              submember2.pw_name,
+                              nss_test_ctx->subdom,
+                              SYSDB_MEMBER_USER);
+    assert_int_equal(ret, EOK);
+
+    ret = remove_group_member(nss_test_ctx,
+                              testsubdomgroup.gr_name,
+                              nss_test_ctx->subdom,
+                              submember1.pw_name,
+                              nss_test_ctx->subdom,
+                              SYSDB_MEMBER_USER);
+    assert_int_equal(ret, EOK);
+
+    ret = delete_user(nss_test_ctx, nss_test_ctx->subdom, &submember2);
+    assert_int_equal(ret, EOK);
+
+    ret = delete_user(nss_test_ctx, nss_test_ctx->subdom, &submember1);
+    assert_int_equal(ret, EOK);
+
+    ret = delete_group(nss_test_ctx, nss_test_ctx->subdom, &testsubdomgroup);
+    assert_int_equal(ret, EOK);
+
+    return nss_test_teardown(state);
+}
+
 struct passwd testbysid = {
     .pw_name = discard_const("testsiduser"),
     .pw_uid = 12345,
@@ -3748,16 +3866,16 @@ int main(int argc, const char *argv[])
                                         nss_fqdn_test_setup, nss_test_teardown),
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_subdom,
                                         nss_subdom_test_setup,
-                                        nss_test_teardown),
+                                        nss_subdom_test_teardown),
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom,
                                         nss_subdom_test_setup,
-                                        nss_test_teardown),
+                                        nss_subdom_test_teardown),
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom_fqdn,
                                         nss_subdom_test_setup,
-                                        nss_test_teardown),
+                                        nss_subdom_test_teardown),
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_subdom,
                                         nss_subdom_test_setup,
-                                        nss_test_teardown),
+                                        nss_subdom_test_teardown),
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_space,
                                         nss_test_setup, nss_test_teardown),
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_space_sub,

From d2a1c9bc0bad05f2e1a253f386e14e65126e9c1f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <[email protected]>
Date: Wed, 1 Mar 2017 08:33:06 +0000
Subject: [PATCH 7/7] NSS/TESTS: Include searches for non-fqnames members of a
 subdomain
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Let's extend the NSS tests in order to also test looking up users, from
a subdomain, by their short names (non fully qualified names).

Related:
https://pagure.io/SSSD/sssd/issue/3001

Signed-off-by: Fabiano Fidêncio <[email protected]>
---
 src/tests/cmocka/test_nss_srv.c | 250 ++++++++++++++++++++++++++++++++++------
 1 file changed, 213 insertions(+), 37 deletions(-)

diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
index ff740c7..f065ac3 100644
--- a/src/tests/cmocka/test_nss_srv.c
+++ b/src/tests/cmocka/test_nss_srv.c
@@ -1648,16 +1648,29 @@ static int test_nss_getgrnam_members_check_subdom(uint32_t status,
     tmp_ctx = talloc_new(nss_test_ctx);
     assert_non_null(tmp_ctx);
 
-    exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
-                                   nss_test_ctx->subdom, submember1.pw_name);
-    assert_non_null(exp_members[0]);
-    exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
-                                   nss_test_ctx->subdom, submember2.pw_name);
-    assert_non_null(exp_members[1]);
-
-    expected.gr_name = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
-                                     nss_test_ctx->subdom, testsubdomgroup.gr_name);
-    assert_non_null(expected.gr_name);
+    if (nss_test_ctx->subdom->fqnames) {
+        exp_members[0] = sss_tc_fqname(tmp_ctx,
+                                       nss_test_ctx->subdom->names,
+                                       nss_test_ctx->subdom,
+                                       submember1.pw_name);
+        assert_non_null(exp_members[0]);
+
+        exp_members[1] = sss_tc_fqname(tmp_ctx,
+                                       nss_test_ctx->subdom->names,
+                                       nss_test_ctx->subdom,
+                                       submember2.pw_name);
+        assert_non_null(exp_members[1]);
+
+        expected.gr_name = sss_tc_fqname(tmp_ctx,
+                                         nss_test_ctx->subdom->names,
+                                         nss_test_ctx->subdom,
+                                         testsubdomgroup.gr_name);
+        assert_non_null(expected.gr_name);
+    } else {
+        exp_members[0] = submember1.pw_name;
+        exp_members[1] = submember2.pw_name;
+        expected.gr_name = testsubdomgroup.gr_name;
+    }
 
     assert_int_equal(status, EOK);
 
@@ -1692,6 +1705,29 @@ void test_nss_getgrnam_members_subdom(void **state)
     assert_int_equal(ret, EOK);
 }
 
+void test_nss_getgrnam_members_subdom_nonfqnames(void **state)
+{
+    errno_t ret;
+
+    nss_test_ctx->subdom->fqnames = false;
+
+    mock_input_user_or_group("testsubdomgroup");
+    mock_account_recv_simple();
+    will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
+    will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+    /* Query for that group, call a callback when command finishes */
+    set_cmd_cb(test_nss_getgrnam_members_check_subdom);
+    ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
+                          nss_test_ctx->nss_cmds);
+    assert_int_equal(ret, EOK);
+
+    /* Wait until the test finishes with EOK */
+    ret = test_ev_loop(nss_test_ctx->tctx);
+
+    assert_int_equal(ret, EOK);
+}
+
 static int test_nss_getgrnam_check_mix_dom(uint32_t status,
                                            uint8_t *body, size_t blen)
 {
@@ -1710,9 +1746,15 @@ static int test_nss_getgrnam_check_mix_dom(uint32_t status,
     tmp_ctx = talloc_new(nss_test_ctx);
     assert_non_null(tmp_ctx);
 
-    exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
-                                   nss_test_ctx->subdom, submember1.pw_name);
-    assert_non_null(exp_members[0]);
+    if (nss_test_ctx->subdom->fqnames) {
+        exp_members[0] = sss_tc_fqname(tmp_ctx,
+                                       nss_test_ctx->subdom->names,
+                                       nss_test_ctx->subdom,
+                                       submember1.pw_name);
+        assert_non_null(exp_members[0]);
+    } else {
+        exp_members[0] = submember1.pw_name;
+    }
     exp_members[1] = testmember1.pw_name;
     exp_members[2] = testmember2.pw_name;
 
@@ -1756,6 +1798,35 @@ void test_nss_getgrnam_mix_dom(void **state)
     assert_int_equal(ret, EOK);
 }
 
+void test_nss_getgrnam_mix_dom_nonfqnames(void **state)
+{
+    errno_t ret;
+
+    nss_test_ctx->subdom->fqnames = false;
+
+    ret = store_group_member(nss_test_ctx,
+                             testgroup_members.gr_name,
+                             nss_test_ctx->tctx->dom,
+                             submember1.pw_name,
+                             nss_test_ctx->subdom,
+                             SYSDB_MEMBER_USER);
+    assert_int_equal(ret, EOK);
+
+    mock_input_user_or_group("testgroup_members");
+    will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
+    will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+    /* Query for that group, call a callback when command finishes */
+    set_cmd_cb(test_nss_getgrnam_check_mix_dom);
+    ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
+                          nss_test_ctx->nss_cmds);
+    assert_int_equal(ret, EOK);
+
+    /* Wait until the test finishes with EOK */
+    ret = test_ev_loop(nss_test_ctx->tctx);
+    assert_int_equal(ret, EOK);
+}
+
 static int test_nss_getgrnam_check_mix_dom_fqdn(uint32_t status,
                                                 uint8_t *body, size_t blen)
 {
@@ -1773,21 +1844,33 @@ static int test_nss_getgrnam_check_mix_dom_fqdn(uint32_t status,
     tmp_ctx = talloc_new(nss_test_ctx);
     assert_non_null(tmp_ctx);
 
-    exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
-                                   nss_test_ctx->subdom, submember1.pw_name);
-    assert_non_null(exp_members[0]);
-    exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names,
-                                   nss_test_ctx->tctx->dom, testmember1.pw_name);
-    assert_non_null(exp_members[1]);
-    exp_members[2] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names,
-                                   nss_test_ctx->tctx->dom, testmember2.pw_name);
-    assert_non_null(exp_members[2]);
-
-    expected.gr_name = sss_tc_fqname(tmp_ctx,
-                                     nss_test_ctx->tctx->dom->names,
-                                     nss_test_ctx->tctx->dom,
-                                     testgroup_members.gr_name);
-    assert_non_null(expected.gr_name);
+    if (nss_test_ctx->subdom->fqnames) {
+        exp_members[0] = sss_tc_fqname(tmp_ctx,
+                                       nss_test_ctx->subdom->names,
+                                       nss_test_ctx->subdom,
+                                       submember1.pw_name);
+        assert_non_null(exp_members[0]);
+    } else {
+        exp_members[0] = submember1.pw_name;
+    }
+    if (nss_test_ctx->tctx->dom->fqnames) {
+        exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names,
+                                       nss_test_ctx->tctx->dom, testmember1.pw_name);
+        assert_non_null(exp_members[1]);
+        exp_members[2] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names,
+                                       nss_test_ctx->tctx->dom, testmember2.pw_name);
+        assert_non_null(exp_members[2]);
+
+        expected.gr_name = sss_tc_fqname(tmp_ctx,
+                                         nss_test_ctx->tctx->dom->names,
+                                         nss_test_ctx->tctx->dom,
+                                         testgroup_members.gr_name);
+        assert_non_null(expected.gr_name);
+    } else {
+        exp_members[1] = testmember1.pw_name;
+        exp_members[2] = testmember2.pw_name;
+        expected.gr_name = testgroup_members.gr_name;
+    }
 
     assert_int_equal(status, EOK);
 
@@ -1834,6 +1917,40 @@ void test_nss_getgrnam_mix_dom_fqdn(void **state)
     assert_int_equal(ret, EOK);
 }
 
+void test_nss_getgrnam_mix_dom_fqdn_nonfqnames(void **state)
+{
+    errno_t ret;
+
+    ret = store_group_member(nss_test_ctx,
+                             testgroup_members.gr_name,
+                             nss_test_ctx->tctx->dom,
+                             submember1.pw_name,
+                             nss_test_ctx->subdom,
+                             SYSDB_MEMBER_USER);
+    assert_int_equal(ret, EOK);
+
+    nss_test_ctx->tctx->dom->fqnames = false;
+    nss_test_ctx->subdom->fqnames = false;
+
+
+    mock_input_user_or_group("testgroup_members");
+    will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
+    will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+    /* Query for that group, call a callback when command finishes */
+    set_cmd_cb(test_nss_getgrnam_check_mix_dom_fqdn);
+    ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
+                          nss_test_ctx->nss_cmds);
+    assert_int_equal(ret, EOK);
+
+    /* Wait until the test finishes with EOK */
+    ret = test_ev_loop(nss_test_ctx->tctx);
+
+    /* Restore FQDN settings */
+    nss_test_ctx->tctx->dom->fqnames = false;
+    assert_int_equal(ret, EOK);
+}
+
 static int test_nss_getgrnam_check_mix_subdom(uint32_t status,
                                               uint8_t *body, size_t blen)
 {
@@ -1851,20 +1968,37 @@ static int test_nss_getgrnam_check_mix_subdom(uint32_t status,
     tmp_ctx = talloc_new(nss_test_ctx);
     assert_non_null(tmp_ctx);
 
-    exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
-                                   nss_test_ctx->subdom, submember1.pw_name);
-    assert_non_null(exp_members[0]);
-    exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
-                                   nss_test_ctx->subdom, submember2.pw_name);
-    assert_non_null(exp_members[1]);
+    if (nss_test_ctx->subdom->fqnames) {
+        exp_members[0] = sss_tc_fqname(tmp_ctx,
+                                       nss_test_ctx->subdom->names,
+                                       nss_test_ctx->subdom,
+                                       submember1.pw_name);
+        assert_non_null(exp_members[0]);
+
+        exp_members[1] = sss_tc_fqname(tmp_ctx,
+                                       nss_test_ctx->subdom->names,
+                                       nss_test_ctx->subdom,
+                                       submember2.pw_name);
+        assert_non_null(exp_members[1]);
+    } else {
+        exp_members[0] = submember1.pw_name;
+        exp_members[1] = submember2.pw_name;
+    }
+
     /* Important: this member is from a non-qualified domain, so his name will
      * not be qualified either
      */
     exp_members[2] = testmember1.pw_name;
 
-    expected.gr_name = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
-                                     nss_test_ctx->subdom, testsubdomgroup.gr_name);
-    assert_non_null(expected.gr_name);
+    if (nss_test_ctx->subdom->fqnames) {
+        expected.gr_name = sss_tc_fqname(tmp_ctx,
+                                         nss_test_ctx->subdom->names,
+                                         nss_test_ctx->subdom,
+                                         testsubdomgroup.gr_name);
+        assert_non_null(expected.gr_name);
+    } else {
+        expected.gr_name = testsubdomgroup.gr_name;
+    }
 
     assert_int_equal(status, EOK);
 
@@ -1906,6 +2040,36 @@ void test_nss_getgrnam_mix_subdom(void **state)
     assert_int_equal(ret, EOK);
 }
 
+void test_nss_getgrnam_mix_subdom_nonfqnames(void **state)
+{
+    errno_t ret;
+
+    nss_test_ctx->subdom->fqnames = false;
+
+    ret = store_group_member(nss_test_ctx,
+                             testsubdomgroup.gr_name,
+                             nss_test_ctx->subdom,
+                             testmember1.pw_name,
+                             nss_test_ctx->tctx->dom,
+                             SYSDB_MEMBER_USER);
+    assert_int_equal(ret, EOK);
+
+    mock_input_user_or_group("testsubdomgroup");
+    mock_account_recv_simple();
+    will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
+    will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+    /* Query for that group, call a callback when command finishes */
+    set_cmd_cb(test_nss_getgrnam_check_mix_subdom);
+    ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
+                          nss_test_ctx->nss_cmds);
+    assert_int_equal(ret, EOK);
+
+    /* Wait until the test finishes with EOK */
+    ret = test_ev_loop(nss_test_ctx->tctx);
+    assert_int_equal(ret, EOK);
+}
+
 struct group space_group = {
     .gr_gid = 2123,
     .gr_name = discard_const("space group"),
@@ -3867,15 +4031,27 @@ int main(int argc, const char *argv[])
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_subdom,
                                         nss_subdom_test_setup,
                                         nss_subdom_test_teardown),
+        cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_subdom_nonfqnames,
+                                        nss_subdom_test_setup,
+                                        nss_subdom_test_teardown),
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom,
                                         nss_subdom_test_setup,
                                         nss_subdom_test_teardown),
+        cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom_nonfqnames,
+                                        nss_subdom_test_setup,
+                                        nss_subdom_test_teardown),
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom_fqdn,
                                         nss_subdom_test_setup,
                                         nss_subdom_test_teardown),
+        cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom_fqdn_nonfqnames,
+                                        nss_subdom_test_setup,
+                                        nss_subdom_test_teardown),
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_subdom,
                                         nss_subdom_test_setup,
                                         nss_subdom_test_teardown),
+        cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_subdom_nonfqnames,
+                                        nss_subdom_test_setup,
+                                        nss_subdom_test_teardown),
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_space,
                                         nss_test_setup, nss_test_teardown),
         cmocka_unit_test_setup_teardown(test_nss_getgrnam_space_sub,
_______________________________________________
sssd-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to