On 10/01/2015 05:06 PM, Sumit Bose wrote:
On Thu, Sep 17, 2015 at 11:06:30AM +0200, Pavel Březina wrote:
On 09/17/2015 10:32 AM, Petr Cech wrote:
Hi Pavel!

There is some code between my last end and this continuation. I was read
it and did't find anything wrong.

Hi Petr,
thank you for you review. New patches are attached. All comments from the
previous mail should be addressed.



[PATCH 2/3] cache_req: add support for UPN

diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c
index 
5f33b225a31e1c1add7f776215d500fb09e127ca..a72a8bac594dc10ff9aa337399f27d9936830a8e
 100644
--- a/src/db/sysdb_search.c
+++ b/src/db/sysdb_search.c
@@ -295,6 +295,59 @@ static char *enum_filter(TALLOC_CTX *mem_ctx,
      return filter;
  }

+int sysdb_getpwupn(TALLOC_CTX *mem_ctx,
+                   struct sss_domain_info *domain,
+                   const char *upn,
+                   struct ldb_result **_res)
+{
+    TALLOC_CTX *tmp_ctx;
+    struct ldb_message *msg;
+    struct ldb_result *res;
+    static const char *attrs[] = SYSDB_PW_ATTRS;
+    errno_t ret;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+        return ENOMEM;
+    }
+
+    ret = sysdb_search_user_by_upn(tmp_ctx, domain, upn, attrs, &msg);
+    if (ret != EOK && ret != ENOENT) {
+        DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn() failed.\n");
+        goto done;
+    }

The call stack here would be

sysdb_getpwupn()->sysdb_search_user_by_upn()->sysdb_search_entry()->ldb_search()

and the returned results, starting from ldb_search()

ldb_result -> ldb_message (array) -> ldb_message -> ldb_result

I think it would be easier and safe some allocations if it would be

sysdb_search_user_by_upn()->sysdb_getpwupn()->ldb_search() .

Do you think this change makes sense?

Hi, thanks for the review. Done.

Although I created a new function sysdb_search_user_by_upn_res since you can't pass attrs into sysdb_getpwnupn (unless we are inconsistent with api).


       const char *orig_name;

Instead of adding a new member which again will hold the originally
provided name I would suggest to refactor the change added by
e87b2a6e94c1066b3044fe683825ff5b4f8716c2 (cache_req: parse input name if
needed) by introducing a member called e.g. parsed_name which keeps the
name returned by sss_parse_inp_recv() and return it in cache_req_recv().

In e87b2a6e94c1066b3044fe683825ff5b4f8716c2 it made sense to overwrite
orig_name because no additional member was needed. But now I think the
code would be more clear if orig_name will be kept unmodified.

Done in separate patch so the changes are more visible. It can be squashed to the second patch.



bye,
Sumit
_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel


>From a4cb7fb90fb21d435c00a4951deedddf5bdb259c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Thu, 7 May 2015 13:01:44 +0200
Subject: [PATCH 1/4] cache_req: provide extra flag for oob request

---
 src/responder/common/responder_cache_req.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c
index d0a90d2c94b7f990a46af488a08dd386854384e0..fba5001476481040ed962dbbd9b01cc16fe0ba74 100644
--- a/src/responder/common/responder_cache_req.c
+++ b/src/responder/common/responder_cache_req.c
@@ -615,6 +615,11 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
     if (state->input->type == CACHE_REQ_USER_BY_CERT) {
         search_str = state->input->cert;
     }
+
+    if (DOM_HAS_VIEWS(state->input->domain)) {
+        extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
+    }
+
     switch (ret) {
     case EOK:
         DEBUG(SSSDBG_TRACE_FUNC, "Cached entry is valid, returning...\n");
@@ -629,7 +634,7 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
                                          state->input->domain, true,
                                          state->input->dp_type,
                                          search_str,
-                                         state->input->id, NULL);
+                                         state->input->id, extra_flag);
         if (subreq == NULL) {
             DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band "
                                        "data provider request\n");
@@ -643,10 +648,6 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
         /* Cache miss or the cache is expired. We need to get the updated
          * information before returning it. */
 
-        if (DOM_HAS_VIEWS(state->input->domain)) {
-            extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
-        }
-
         subreq = sss_dp_get_account_send(state, state->rctx,
                                          state->input->domain, true,
                                          state->input->dp_type,
-- 
1.9.3

>From 0df20e8ddfe84bf411fda55218341a81d710c9b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Wed, 6 May 2015 12:16:46 +0200
Subject: [PATCH 2/4] cache_req: add support for UPN

---
 src/db/sysdb.h                               |  16 ++
 src/db/sysdb_ops.c                           |  71 +++--
 src/db/sysdb_search.c                        |  93 +++++++
 src/responder/common/responder_cache_req.c   | 116 +++++++-
 src/responder/common/responder_cache_req.h   |   4 +-
 src/responder/common/responder_get_domains.c |  21 +-
 src/tests/cmocka/common_mock_resp.h          |   2 +-
 src/tests/cmocka/common_mock_resp_dp.c       |   5 +-
 src/tests/cmocka/test_responder_cache_req.c  | 388 ++++++++++++++++++++++++++-
 9 files changed, 674 insertions(+), 42 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 3c76fb0ce849ad03c7848dfb43dbbfeac6bce7c2..4f488c0880f4c7642677ac76f745b32708c68195 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -609,6 +609,11 @@ int sysdb_getpwuid(TALLOC_CTX *mem_ctx,
                    uid_t uid,
                    struct ldb_result **res);
 
+int sysdb_getpwupn(TALLOC_CTX *mem_ctx,
+                   struct sss_domain_info *domain,
+                   const char *upn,
+                   struct ldb_result **res);
+
 int sysdb_enumpwent(TALLOC_CTX *mem_ctx,
                     struct sss_domain_info *domain,
                     struct ldb_result **res);
@@ -681,6 +686,11 @@ int sysdb_initgroups(TALLOC_CTX *mem_ctx,
                      const char *name,
                      struct ldb_result **res);
 
+int sysdb_initgroups_by_upn(TALLOC_CTX *mem_ctx,
+                            struct sss_domain_info *domain,
+                            const char *upn,
+                            struct ldb_result **res);
+
 int sysdb_initgroups_with_views(TALLOC_CTX *mem_ctx,
                                 struct sss_domain_info *domain,
                                 const char *name,
@@ -768,6 +778,12 @@ int sysdb_search_user_by_sid_str(TALLOC_CTX *mem_ctx,
                                  const char **attrs,
                                  struct ldb_message **msg);
 
+int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx,
+                                 struct sss_domain_info *domain,
+                                 const char *upn,
+                                 const char **attrs,
+                                 struct ldb_result **out_res);
+
 int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx,
                              struct sss_domain_info *domain,
                              const char *sid_str,
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 38e7021908bb7842a35a302ddbd50867407c9cab..aedf78d2fdf82843d88b30826bb7cb040f1c2d00 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -474,28 +474,28 @@ int sysdb_search_user_by_sid_str(TALLOC_CTX *mem_ctx,
                                         sid_str, attrs, msg);
 }
 
-int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx,
-                             struct sss_domain_info *domain,
-                             const char *upn,
-                             const char **attrs,
-                             struct ldb_message **msg)
+int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx,
+                                 struct sss_domain_info *domain,
+                                 const char *upn,
+                                 const char **attrs,
+                                 struct ldb_result **out_res)
 {
     TALLOC_CTX *tmp_ctx;
+    struct ldb_result *res;
+    struct ldb_dn *base_dn;
+    char *filter;
+    int ret;
     const char *def_attrs[] = { SYSDB_NAME, SYSDB_UPN, SYSDB_CANONICAL_UPN,
                                 NULL };
-    struct ldb_message **msgs = NULL;
-    struct ldb_dn *basedn;
-    size_t msgs_count = 0;
-    char *filter;
-    int ret;
 
     tmp_ctx = talloc_new(NULL);
     if (tmp_ctx == NULL) {
-        return ENOMEM;
+        ret = ENOMEM;
+        goto done;
     }
 
-    basedn = sysdb_user_base_dn(tmp_ctx, domain);
-    if (basedn == NULL) {
+    base_dn = sysdb_user_base_dn(tmp_ctx, domain);
+    if (base_dn == NULL) {
         ret = ENOMEM;
         goto done;
     }
@@ -506,29 +506,64 @@ int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    ret = sysdb_search_entry(tmp_ctx, domain->sysdb, basedn, LDB_SCOPE_SUBTREE,
-                             filter, attrs?attrs:def_attrs, &msgs_count,
-                             &msgs);
+    ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res,
+                     base_dn, LDB_SCOPE_SUBTREE, attrs ? attrs : def_attrs,
+                     filter);
     if (ret != EOK) {
+        ret = sysdb_error_to_errno(ret);
         goto done;
     }
 
-    if (msgs_count > 1) {
+    if (res->count == 0) {
+        /* set result anyway */
+        *out_res = talloc_steal(mem_ctx, res);
+        ret = ENOENT;
+        goto done;
+    } else if (res->count > 1) {
         DEBUG(SSSDBG_OP_FAILURE,
               "Search for upn [%s] returns more than one result.\n", upn);
         ret = EINVAL;
         goto done;
     }
 
-    *msg = talloc_steal(mem_ctx, msgs[0]);
+    *out_res = talloc_steal(mem_ctx, res);
+    ret = EOK;
 
 done:
+    talloc_zfree(tmp_ctx);
+    return ret;
+}
+
+int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx,
+                             struct sss_domain_info *domain,
+                             const char *upn,
+                             const char **attrs,
+                             struct ldb_message **msg)
+{
+    TALLOC_CTX *tmp_ctx;
+    struct ldb_result *res;
+    errno_t ret;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = sysdb_search_user_by_upn_res(tmp_ctx, domain, upn, attrs, &res);
     if (ret == ENOENT) {
         DEBUG(SSSDBG_TRACE_FUNC, "No entry with upn [%s] found.\n", upn);
+        goto done;
     } else if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret));
+        goto done;
     }
 
+    *msg = talloc_steal(mem_ctx, res->msgs[0]);
+
+    ret = EOK;
+
+done:
     talloc_zfree(tmp_ctx);
     return ret;
 }
diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c
index ab72addbc65b1055eedea149a9d1513be4b86d99..1e403119131a7704a1f36ca2fd597d9ee64b9319 100644
--- a/src/db/sysdb_search.c
+++ b/src/db/sysdb_search.c
@@ -295,6 +295,35 @@ static char *enum_filter(TALLOC_CTX *mem_ctx,
     return filter;
 }
 
+int sysdb_getpwupn(TALLOC_CTX *mem_ctx,
+                   struct sss_domain_info *domain,
+                   const char *upn,
+                   struct ldb_result **_res)
+{
+    TALLOC_CTX *tmp_ctx;
+    struct ldb_result *res;
+    static const char *attrs[] = SYSDB_PW_ATTRS;
+    errno_t ret;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+        return ENOMEM;
+    }
+
+    ret = sysdb_search_user_by_upn_res(tmp_ctx, domain, upn, attrs, &res);
+    if (ret != EOK && ret != ENOENT) {
+        DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn_res() failed.\n");
+        goto done;
+    }
+
+    *_res = talloc_steal(mem_ctx, res);
+
+done:
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
 int sysdb_enumpwent_filter(TALLOC_CTX *mem_ctx,
                            struct sss_domain_info *domain,
                            const char *name_filter,
@@ -957,6 +986,70 @@ done:
     return ret;
 }
 
+int sysdb_initgroups_by_upn(TALLOC_CTX *mem_ctx,
+                             struct sss_domain_info *domain,
+                             const char *upn,
+                             struct ldb_result **_res)
+{
+    TALLOC_CTX *tmp_ctx;
+    struct ldb_message *msg;
+    struct ldb_result *res;
+    const char *sysdb_name;
+    static const char *attrs[] = SYSDB_INITGR_ATTRS;
+    size_t i;
+    errno_t ret;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+        return ENOMEM;
+    }
+
+    ret = sysdb_search_user_by_upn(tmp_ctx, domain, upn, attrs, &msg);
+    if (ret != EOK && ret != ENOENT) {
+        DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn() failed.\n");
+        goto done;
+    }
+
+    res = talloc_zero(tmp_ctx, struct ldb_result);
+    if (res == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "talloc_zero() failed.\n");
+        ret = ENOMEM;
+        goto done;
+    }
+
+    if (ret == ENOENT) {
+        res->count = 0;
+        res->msgs = NULL;
+    } else {
+        sysdb_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
+        if (sysdb_name == NULL) {
+            DEBUG(SSSDBG_OP_FAILURE, "Sysdb entry does not have a name.\n");
+            return EINVAL;
+        }
+
+        ret = sysdb_initgroups(tmp_ctx, domain, sysdb_name, &res);
+        if (ret == EOK && DOM_HAS_VIEWS(domain)) {
+            for (i = 0; i < res->count; i++) {
+                ret = sysdb_add_overrides_to_object(domain, res->msgs[i],
+                                                    NULL, NULL);
+                if (ret != EOK) {
+                    DEBUG(SSSDBG_OP_FAILURE,
+                        "sysdb_add_overrides_to_object() failed.\n");
+                    return ret;
+                }
+            }
+        }
+    }
+
+    *_res = talloc_steal(mem_ctx, res);
+    ret = EOK;
+
+done:
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
 int sysdb_initgroups_with_views(TALLOC_CTX *mem_ctx,
                                 struct sss_domain_info *domain,
                                 const char *name,
diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c
index fba5001476481040ed962dbbd9b01cc16fe0ba74..70a3010eb697cf14874bd1a950cb7a874bc060b4 100644
--- a/src/responder/common/responder_cache_req.c
+++ b/src/responder/common/responder_cache_req.c
@@ -70,6 +70,7 @@ struct cache_req_input {
     enum cache_req_type type;
 
     /* Provided input. */
+    const char *raw_name;
     const char *orig_name;
     uint32_t id;
     const char *cert;
@@ -113,15 +114,22 @@ cache_req_input_create(TALLOC_CTX *mem_ctx,
     /* Check that input parameters match selected type. */
     switch (input->type) {
     case CACHE_REQ_USER_BY_NAME:
+    case CACHE_REQ_USER_BY_UPN:
     case CACHE_REQ_GROUP_BY_NAME:
     case CACHE_REQ_USER_BY_FILTER:
     case CACHE_REQ_GROUP_BY_FILTER:
     case CACHE_REQ_INITGROUPS:
+    case CACHE_REQ_INITGROUPS_BY_UPN:
         if (name == NULL) {
             DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL!\n");
             goto fail;
         }
 
+        input->raw_name = talloc_strdup(input, name);
+        if (input->raw_name == NULL) {
+            goto fail;
+        }
+
         input->orig_name = talloc_strdup(input, name);
         if (input->orig_name == NULL) {
             goto fail;
@@ -152,6 +160,7 @@ cache_req_input_create(TALLOC_CTX *mem_ctx,
     /* Resolve Data Provider request type. */
     switch (type) {
     case CACHE_REQ_USER_BY_NAME:
+    case CACHE_REQ_USER_BY_UPN:
     case CACHE_REQ_USER_BY_ID:
         input->dp_type = SSS_DP_USER;
         break;
@@ -162,6 +171,7 @@ cache_req_input_create(TALLOC_CTX *mem_ctx,
         break;
 
     case CACHE_REQ_INITGROUPS:
+    case CACHE_REQ_INITGROUPS_BY_UPN:
         input->dp_type = SSS_DP_INITGROUPS;
         break;
 
@@ -222,10 +232,12 @@ cache_req_input_set_domain(struct cache_req_input *input,
 
     switch (input->type) {
     case CACHE_REQ_USER_BY_NAME:
+    case CACHE_REQ_USER_BY_UPN:
     case CACHE_REQ_GROUP_BY_NAME:
     case CACHE_REQ_USER_BY_FILTER:
     case CACHE_REQ_GROUP_BY_FILTER:
     case CACHE_REQ_INITGROUPS:
+    case CACHE_REQ_INITGROUPS_BY_UPN:
         name = sss_get_cased_name(tmp_ctx, input->orig_name,
                                   domain->case_sensitive);
         if (name == NULL) {
@@ -286,6 +298,56 @@ done:
     return ret;
 }
 
+static bool
+cache_req_input_is_upn(struct cache_req_input *input)
+{
+    switch (input->type) {
+    case CACHE_REQ_USER_BY_UPN:
+    case CACHE_REQ_INITGROUPS_BY_UPN:
+        return true;
+    default:
+        return false;
+    }
+}
+
+static bool
+cache_req_input_assume_upn(struct cache_req_input *input)
+{
+    errno_t ret;
+    bool bret;
+
+    if (input->raw_name == NULL || strchr(input->raw_name, '@') == NULL) {
+        return false;
+    }
+
+    switch (input->type) {
+    case CACHE_REQ_USER_BY_NAME:
+        input->type = CACHE_REQ_USER_BY_UPN;
+        bret = true;
+        break;
+    case CACHE_REQ_INITGROUPS:
+        input->type = CACHE_REQ_INITGROUPS_BY_UPN;
+        bret = true;
+        break;
+    default:
+        bret = false;
+        break;
+    }
+
+    if (bret == true) {
+        ret = cache_req_input_set_orig_name(input, input->raw_name);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "cache_req_input_set_orig_name() failed\n");
+            return false;
+        }
+
+        DEBUG(SSSDBG_TRACE_FUNC, "Assuming UPN %s\n", input->raw_name);
+    }
+
+    return bret;
+}
+
 static errno_t cache_req_check_ncache(struct cache_req_input *input,
                                       struct sss_nc_ctx *ncache,
                                       int neg_timeout)
@@ -294,7 +356,9 @@ static errno_t cache_req_check_ncache(struct cache_req_input *input,
 
     switch (input->type) {
     case CACHE_REQ_USER_BY_NAME:
+    case CACHE_REQ_USER_BY_UPN:
     case CACHE_REQ_INITGROUPS:
+    case CACHE_REQ_INITGROUPS_BY_UPN:
         ret = sss_ncache_check_user(ncache, neg_timeout,
                                     input->domain, input->dom_objname);
         break;
@@ -332,7 +396,9 @@ static void cache_req_add_to_ncache(struct cache_req_input *input,
 
     switch (input->type) {
     case CACHE_REQ_USER_BY_NAME:
+    case CACHE_REQ_USER_BY_UPN:
     case CACHE_REQ_INITGROUPS:
+    case CACHE_REQ_INITGROUPS_BY_UPN:
         ret = sss_ncache_set_user(ncache, false, input->domain,
                                   input->dom_objname);
         break;
@@ -375,8 +441,10 @@ static void cache_req_add_to_ncache_global(struct cache_req_input *input,
         /* Nothing to do, adding a wildcard request to ncache doesn't
          * make sense */
     case CACHE_REQ_USER_BY_NAME:
+    case CACHE_REQ_USER_BY_UPN:
     case CACHE_REQ_GROUP_BY_NAME:
     case CACHE_REQ_INITGROUPS:
+    case CACHE_REQ_INITGROUPS_BY_UPN:
         /* Nothing to do. Those types are already in ncache for selected
          * domains. */
         ret = EOK;
@@ -418,6 +486,11 @@ static errno_t cache_req_get_object(TALLOC_CTX *mem_ctx,
         ret = sysdb_getpwnam_with_views(mem_ctx, input->domain,
                                         input->dom_objname, &result);
         break;
+    case CACHE_REQ_USER_BY_UPN:
+        one_item_only = true;
+        ret = sysdb_getpwupn(mem_ctx, input->domain,
+                             input->dom_objname, &result);
+        break;
     case CACHE_REQ_USER_BY_ID:
         one_item_only = true;
         ret = sysdb_getpwuid_with_views(mem_ctx, input->domain,
@@ -438,6 +511,11 @@ static errno_t cache_req_get_object(TALLOC_CTX *mem_ctx,
         ret = sysdb_initgroups_with_views(mem_ctx, input->domain,
                                           input->dom_objname, &result);
         break;
+    case CACHE_REQ_INITGROUPS_BY_UPN:
+        one_item_only = false;
+        ret = sysdb_initgroups_by_upn(mem_ctx, input->domain,
+                                      input->dom_objname, &result);
+        break;
     case CACHE_REQ_USER_BY_CERT:
         one_item_only = true;
         ret = sysdb_search_user_by_cert(mem_ctx, input->domain,
@@ -618,6 +696,8 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
 
     if (DOM_HAS_VIEWS(state->input->domain)) {
         extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
+    } else if (cache_req_input_is_upn(state->input)) {
+        extra_flag = EXTRA_NAME_IS_UPN;
     }
 
     switch (ret) {
@@ -821,23 +901,35 @@ static void cache_req_input_parsed(struct tevent_req *subreq)
     char *name;
     char *domain;
     errno_t ret;
+    bool maybe_upn;
 
     req = tevent_req_callback_data(subreq, struct tevent_req);
     state = tevent_req_data(req, struct cache_req_state);
 
     ret = sss_parse_inp_recv(subreq, state, &name, &domain);
-    if (ret != EOK) {
-        tevent_req_error(req, ret);
-        return;
-    }
-
-    if (strcmp(name, state->input->orig_name) != 0) {
-        /* The name has changed during input parse phase. */
-        ret = cache_req_input_set_orig_name(state->input, name);
-        if (ret != EOK) {
+    switch (ret) {
+    case EOK:
+        if (strcmp(name, state->input->orig_name) != 0) {
+            /* The name has changed during input parse phase. */
+            ret = cache_req_input_set_orig_name(state->input, name);
+            if (ret != EOK) {
+                tevent_req_error(req, ret);
+                return;
+            }
+        }
+        break;
+    case ERR_DOMAIN_NOT_FOUND:
+        maybe_upn = cache_req_input_assume_upn(state->input);
+        if (!maybe_upn) {
             tevent_req_error(req, ret);
             return;
         }
+
+        domain = NULL;
+        break;
+    default:
+        tevent_req_error(req, ret);
+        return;
     }
 
     ret = cache_req_select_domains(req, domain);
@@ -943,6 +1035,12 @@ static void cache_req_done(struct tevent_req *subreq)
     }
 
     if (state->check_next == false) {
+        if (ret == ENOENT && cache_req_input_assume_upn(state->input)) {
+            /* search by upn now */
+            cache_req_select_domains(req, NULL);
+            return;
+        }
+
         tevent_req_error(req, ret);
         return;
     }
diff --git a/src/responder/common/responder_cache_req.h b/src/responder/common/responder_cache_req.h
index 9e3f88a1427f3dcbde9f81df2ec647821b7aa931..474d42647586c044925c83a0641200d065862b87 100644
--- a/src/responder/common/responder_cache_req.h
+++ b/src/responder/common/responder_cache_req.h
@@ -29,13 +29,15 @@
 
 enum cache_req_type {
     CACHE_REQ_USER_BY_NAME,
+    CACHE_REQ_USER_BY_UPN,
     CACHE_REQ_USER_BY_ID,
     CACHE_REQ_GROUP_BY_NAME,
     CACHE_REQ_GROUP_BY_ID,
     CACHE_REQ_INITGROUPS,
+    CACHE_REQ_INITGROUPS_BY_UPN,
     CACHE_REQ_USER_BY_CERT,
     CACHE_REQ_USER_BY_FILTER,
-    CACHE_REQ_GROUP_BY_FILTER,
+    CACHE_REQ_GROUP_BY_FILTER
 };
 
 struct cache_req_input;
diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c
index 8fbab082aee02f6d5fae85b04bab047e59d20b44..7fd0b48eef12c741349996ff582b44202de3f090 100644
--- a/src/responder/common/responder_get_domains.c
+++ b/src/responder/common/responder_get_domains.c
@@ -446,6 +446,7 @@ struct sss_parse_inp_state {
 
     char *name;
     char *domname;
+    errno_t error;
 };
 
 static void sss_parse_inp_done(struct tevent_req *subreq);
@@ -527,14 +528,24 @@ static void sss_parse_inp_done(struct tevent_req *subreq)
         return;
     }
 
+    state->error = ERR_OK;
+
     ret = sss_parse_name_for_domains(state, state->rctx->domains,
                                      state->rctx->default_domain,
                                      state->rawinp,
                                      &state->domname, &state->name);
-    if (ret != EOK) {
+    if (ret == EAGAIN && state->domname != NULL && state->name == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE,
+              "Unknown domain in [%s]\n", state->rawinp);
+        state->error = ERR_DOMAIN_NOT_FOUND;
+    } else if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE,
               "Invalid name received [%s]\n", state->rawinp);
-        tevent_req_error(req, ERR_INPUT_PARSE);
+        state->error = ERR_INPUT_PARSE;
+    }
+
+    if (state->error != ERR_OK) {
+        tevent_req_error(req, state->error);
         return;
     }
 
@@ -548,7 +559,9 @@ errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     struct sss_parse_inp_state *state = tevent_req_data(req,
                                                 struct sss_parse_inp_state);
 
-    TEVENT_REQ_RETURN_ON_ERROR(req);
+    if (state->error != ERR_DOMAIN_NOT_FOUND) {
+        TEVENT_REQ_RETURN_ON_ERROR(req);
+    }
 
     if (_name) {
         *_name = talloc_steal(mem_ctx, state->name);
@@ -558,5 +571,5 @@ errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
         *_domname = talloc_steal(mem_ctx, state->domname);
     }
 
-    return EOK;
+    return state->error;
 }
diff --git a/src/tests/cmocka/common_mock_resp.h b/src/tests/cmocka/common_mock_resp.h
index 88c09c88d9f39c6335b8c857319cca42cba9be4f..a4d8f55c701ee0c2fa6f0b9d8c34fdaf518a95a9 100644
--- a/src/tests/cmocka/common_mock_resp.h
+++ b/src/tests/cmocka/common_mock_resp.h
@@ -59,6 +59,6 @@ void mock_account_recv(uint16_t dp_err, uint32_t dp_ret, char *msg,
 
 void mock_account_recv_simple(void);
 
-void mock_parse_inp(const char *name, const char *domname);
+void mock_parse_inp(const char *name, const char *domname, errno_t ret);
 
 #endif /* __COMMON_MOCK_RESP_H_ */
diff --git a/src/tests/cmocka/common_mock_resp_dp.c b/src/tests/cmocka/common_mock_resp_dp.c
index a67ceee4a43184d9894c19a5c11161aca4e1caff..f62606eb8a33b6417bbd32a7dccdbeaabd05818f 100644
--- a/src/tests/cmocka/common_mock_resp_dp.c
+++ b/src/tests/cmocka/common_mock_resp_dp.c
@@ -92,13 +92,14 @@ errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     *_name = sss_mock_ptr_type(char *);
     *_domname = sss_mock_ptr_type(char *);
 
-    return test_request_recv(req);
+    return sss_mock_type(errno_t);
 }
 
-void mock_parse_inp(const char *name, const char *domname)
+void mock_parse_inp(const char *name, const char *domname, errno_t ret)
 {
     will_return(sss_parse_inp_recv, name);
     will_return(sss_parse_inp_recv, domname);
+    will_return(sss_parse_inp_recv, ret);
 }
 
 /* Mock subdomain requests */
diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c
index 5fd43940d4fa960e58d5dd820f10c7749f19f5cc..b4018ba331dde9a384fbd39321c8314137ba4e5c 100644
--- a/src/tests/cmocka/test_responder_cache_req.c
+++ b/src/tests/cmocka/test_responder_cache_req.c
@@ -34,6 +34,7 @@
 #define TEST_ID_PROVIDER "ldap"
 
 #define TEST_USER_NAME "test-user"
+#define TEST_UPN "u...@upndomain.com"
 #define TEST_USER_ID 1000
 #define TEST_GROUP_NAME "test-group"
 #define TEST_GROUP_ID 1000
@@ -89,6 +90,7 @@ __wrap_sss_dp_get_account_send(TALLOC_CTX *mem_ctx,
                                uint32_t opt_id,
                                const char *extra)
 {
+    struct sysdb_attrs *attrs = NULL;
     struct cache_req_test_ctx *ctx = NULL;
     errno_t ret;
 
@@ -96,9 +98,15 @@ __wrap_sss_dp_get_account_send(TALLOC_CTX *mem_ctx,
     ctx->dp_called = true;
 
     if (ctx->create_user) {
+        attrs = sysdb_new_attrs(ctx);
+        assert_non_null(attrs);
+
+        ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, TEST_UPN);
+        assert_int_equal(ret, EOK);
+
         ret = sysdb_store_user(ctx->tctx->dom, TEST_USER_NAME, "pwd",
                                TEST_USER_ID, 1000, NULL, NULL, NULL,
-                               "cn=test-user,dc=test", NULL, NULL,
+                               "cn=test-user,dc=test", attrs, NULL,
                                1000, time(NULL));
         assert_int_equal(ret, EOK);
     }
@@ -257,7 +265,7 @@ void test_user_by_name_multiple_domains_found(void **state)
 
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
-    mock_parse_inp(name, NULL);
+    mock_parse_inp(name, NULL, ERR_OK);
 
     req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
                                       test_ctx->rctx, test_ctx->ncache, 10, 0,
@@ -300,7 +308,7 @@ void test_user_by_name_multiple_domains_notfound(void **state)
 
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
-    mock_parse_inp(name, NULL);
+    mock_parse_inp(name, NULL, ERR_OK);
 
     req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
                                       test_ctx->rctx, test_ctx->ncache, 10, 0,
@@ -360,7 +368,7 @@ void test_user_by_name_multiple_domains_parse(void **state)
     req_mem_ctx = talloc_new(global_talloc_context);
     check_leaks_push(req_mem_ctx);
 
-    mock_parse_inp(name, "responder_cache_req_test_d");
+    mock_parse_inp(name, "responder_cache_req_test_d", ERR_OK);
 
     req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
                                       test_ctx->rctx, test_ctx->ncache, 10, 0,
@@ -626,6 +634,363 @@ void test_user_by_name_missing_notfound(void **state)
     assert_true(test_ctx->dp_called);
 }
 
+void test_user_by_upn_multiple_domains_found(void **state)
+{
+    struct cache_req_test_ctx *test_ctx = NULL;
+    struct sysdb_attrs *attrs = NULL;
+    struct sss_domain_info *domain = NULL;
+    TALLOC_CTX *req_mem_ctx = NULL;
+    struct tevent_req *req = NULL;
+    const char *name = TEST_USER_NAME;
+    const char *upn = TEST_UPN;
+    const char *ldbname = NULL;
+    errno_t ret;
+
+    test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
+
+    domain = find_domain_by_name(test_ctx->tctx->dom,
+                                 "responder_cache_req_test_d", true);
+    assert_non_null(domain);
+
+    attrs = sysdb_new_attrs(test_ctx);
+    assert_non_null(attrs);
+
+    ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, upn);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_store_user(domain, name, "pwd", 1000, 1000,
+                           NULL, NULL, NULL, "cn=test-user,dc=test", attrs,
+                           NULL, 1000, time(NULL));
+    assert_int_equal(ret, EOK);
+
+    req_mem_ctx = talloc_new(global_talloc_context);
+    check_leaks_push(req_mem_ctx);
+
+    will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
+    will_return_always(sss_dp_get_account_recv, 0);
+    mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
+
+    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
+                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
+                                      NULL, upn);
+    assert_non_null(req);
+    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
+
+    ret = test_ev_loop(test_ctx->tctx);
+    assert_int_equal(ret, ERR_OK);
+    assert_true(check_leaks_pop(req_mem_ctx));
+
+    assert_true(test_ctx->dp_called);
+
+    assert_non_null(test_ctx->result);
+    assert_int_equal(test_ctx->result->count, 1);
+    assert_non_null(test_ctx->result->msgs);
+    assert_non_null(test_ctx->result->msgs[0]);
+
+    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
+                                          SYSDB_NAME, NULL);
+    assert_non_null(ldbname);
+    assert_string_equal(ldbname, name);
+
+    assert_non_null(test_ctx->domain);
+    assert_string_equal(domain->name, test_ctx->domain->name);
+}
+
+void test_user_by_upn_multiple_domains_notfound(void **state)
+{
+    struct cache_req_test_ctx *test_ctx = NULL;
+    TALLOC_CTX *req_mem_ctx = NULL;
+    struct tevent_req *req = NULL;
+    const char *upn = TEST_UPN;
+    errno_t ret;
+
+    test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
+
+    req_mem_ctx = talloc_new(global_talloc_context);
+    check_leaks_push(req_mem_ctx);
+
+    will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
+    will_return_always(sss_dp_get_account_recv, 0);
+    mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
+
+    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
+                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
+                                      NULL, upn);
+    assert_non_null(req);
+    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
+
+    ret = test_ev_loop(test_ctx->tctx);
+    assert_int_equal(ret, ENOENT);
+    assert_true(check_leaks_pop(req_mem_ctx));
+
+    assert_true(test_ctx->dp_called);
+}
+
+void test_user_by_upn_cache_valid(void **state)
+{
+    struct cache_req_test_ctx *test_ctx = NULL;
+    struct sysdb_attrs *attrs = NULL;
+    TALLOC_CTX *req_mem_ctx = NULL;
+    struct tevent_req *req = NULL;
+    const char *name = TEST_USER_NAME;
+    const char *upn = TEST_UPN;
+    const char *ldbname = NULL;
+    errno_t ret;
+
+    test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
+
+    attrs = sysdb_new_attrs(test_ctx);
+    assert_non_null(attrs);
+
+    ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, upn);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", 1000, 1000,
+                           NULL, NULL, NULL, "cn=test-user,dc=test", attrs,
+                           NULL, 1000, time(NULL));
+    assert_int_equal(ret, EOK);
+
+    req_mem_ctx = talloc_new(global_talloc_context);
+    check_leaks_push(req_mem_ctx);
+
+    mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
+
+    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
+                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
+                                      NULL, upn);
+    assert_non_null(req);
+    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
+
+    ret = test_ev_loop(test_ctx->tctx);
+    assert_int_equal(ret, ERR_OK);
+    assert_true(check_leaks_pop(req_mem_ctx));
+
+    assert_non_null(test_ctx->result);
+    assert_int_equal(test_ctx->result->count, 1);
+    assert_non_null(test_ctx->result->msgs);
+    assert_non_null(test_ctx->result->msgs[0]);
+
+    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
+                                          SYSDB_NAME, NULL);
+    assert_non_null(ldbname);
+    assert_string_equal(ldbname, name);
+}
+
+void test_user_by_upn_cache_expired(void **state)
+{
+    struct cache_req_test_ctx *test_ctx = NULL;
+    struct sysdb_attrs *attrs = NULL;
+    TALLOC_CTX *req_mem_ctx = NULL;
+    struct tevent_req *req = NULL;
+    const char *name = TEST_USER_NAME;
+    const char *upn = TEST_UPN;
+    const char *ldbname = NULL;
+    errno_t ret;
+
+    test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
+
+    attrs = sysdb_new_attrs(test_ctx);
+    assert_non_null(attrs);
+
+    ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, upn);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", 1000, 1000,
+                           NULL, NULL, NULL, "cn=test-user,dc=test", attrs,
+                           NULL, -1000, time(NULL));
+    assert_int_equal(ret, EOK);
+
+    req_mem_ctx = talloc_new(global_talloc_context);
+    check_leaks_push(req_mem_ctx);
+
+    /* DP should be contacted */
+    will_return(__wrap_sss_dp_get_account_send, test_ctx);
+    mock_account_recv_simple();
+    mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
+
+    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
+                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
+                                      NULL, upn);
+    assert_non_null(req);
+    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
+
+    ret = test_ev_loop(test_ctx->tctx);
+    assert_int_equal(ret, ERR_OK);
+    assert_true(check_leaks_pop(req_mem_ctx));
+
+    assert_true(test_ctx->dp_called);
+
+    assert_non_null(test_ctx->result);
+    assert_int_equal(test_ctx->result->count, 1);
+    assert_non_null(test_ctx->result->msgs);
+    assert_non_null(test_ctx->result->msgs[0]);
+
+    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
+                                          SYSDB_NAME, NULL);
+    assert_non_null(ldbname);
+    assert_string_equal(ldbname, name);
+}
+
+void test_user_by_upn_cache_midpoint(void **state)
+{
+    struct cache_req_test_ctx *test_ctx = NULL;
+    TALLOC_CTX *req_mem_ctx = NULL;
+    struct tevent_req *req = NULL;
+    struct sysdb_attrs *attrs = NULL;
+    const char *upn = TEST_UPN;
+    const char *name = TEST_USER_NAME;
+    const char *ldbname = NULL;
+    errno_t ret;
+
+    test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
+
+    attrs = sysdb_new_attrs(test_ctx);
+    assert_non_null(attrs);
+
+    ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, upn);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", 1000, 1000,
+                           NULL, NULL, NULL, "cn=test-user,dc=test", attrs,
+                           NULL, 50, time(NULL) - 26);
+    assert_int_equal(ret, EOK);
+
+    req_mem_ctx = talloc_new(global_talloc_context);
+    check_leaks_push(req_mem_ctx);
+
+    /* DP should be contacted without callback */
+    will_return(__wrap_sss_dp_get_account_send, test_ctx);
+    mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
+
+    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
+                                      test_ctx->rctx, test_ctx->ncache, 10, 50,
+                                      NULL, upn);
+    assert_non_null(req);
+    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
+
+    ret = test_ev_loop(test_ctx->tctx);
+    assert_int_equal(ret, ERR_OK);
+    assert_true(check_leaks_pop(req_mem_ctx));
+
+    assert_true(test_ctx->dp_called);
+
+    assert_non_null(test_ctx->result);
+    assert_int_equal(test_ctx->result->count, 1);
+    assert_non_null(test_ctx->result->msgs);
+    assert_non_null(test_ctx->result->msgs[0]);
+
+    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
+                                          SYSDB_NAME, NULL);
+    assert_non_null(ldbname);
+    assert_string_equal(ldbname, name);
+}
+
+void test_user_by_upn_ncache(void **state)
+{
+    struct cache_req_test_ctx *test_ctx = NULL;
+    TALLOC_CTX *req_mem_ctx = NULL;
+    struct tevent_req *req = NULL;
+    const char *upn = TEST_UPN;
+    errno_t ret;
+
+    test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
+
+    ret = sss_ncache_set_user(test_ctx->ncache, false,
+                              test_ctx->tctx->dom, upn);
+    assert_int_equal(ret, EOK);
+
+    req_mem_ctx = talloc_new(global_talloc_context);
+    check_leaks_push(req_mem_ctx);
+
+    mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
+
+    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
+                                      test_ctx->rctx, test_ctx->ncache, 100, 0,
+                                      NULL, upn);
+    assert_non_null(req);
+    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
+
+    ret = test_ev_loop(test_ctx->tctx);
+    assert_int_equal(ret, ENOENT);
+    assert_true(check_leaks_pop(req_mem_ctx));
+
+    assert_false(test_ctx->dp_called);
+}
+
+void test_user_by_upn_missing_found(void **state)
+{
+    struct cache_req_test_ctx *test_ctx = NULL;
+    TALLOC_CTX *req_mem_ctx = NULL;
+    struct tevent_req *req = NULL;
+    const char *upn = TEST_UPN;
+    const char *name = TEST_USER_NAME;
+    const char *ldbname = NULL;
+    errno_t ret;
+
+    test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
+
+    req_mem_ctx = talloc_new(global_talloc_context);
+    check_leaks_push(req_mem_ctx);
+
+    will_return(__wrap_sss_dp_get_account_send, test_ctx);
+    mock_account_recv_simple();
+    mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
+
+    test_ctx->create_user = true;
+
+    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
+                                      test_ctx->rctx, test_ctx->ncache, 100, 0,
+                                      NULL, upn);
+    assert_non_null(req);
+    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
+
+    ret = test_ev_loop(test_ctx->tctx);
+    assert_int_equal(ret, ERR_OK);
+    assert_true(check_leaks_pop(req_mem_ctx));
+
+    assert_true(test_ctx->dp_called);
+
+    assert_non_null(test_ctx->result);
+    assert_int_equal(test_ctx->result->count, 1);
+    assert_non_null(test_ctx->result->msgs);
+    assert_non_null(test_ctx->result->msgs[0]);
+
+    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
+                                          SYSDB_NAME, NULL);
+    assert_non_null(ldbname);
+    assert_string_equal(ldbname, name);
+}
+
+void test_user_by_upn_missing_notfound(void **state)
+{
+    struct cache_req_test_ctx *test_ctx = NULL;
+    TALLOC_CTX *req_mem_ctx = NULL;
+    struct tevent_req *req = NULL;
+    const char *upn = TEST_UPN;
+    errno_t ret;
+
+    test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
+
+    req_mem_ctx = talloc_new(global_talloc_context);
+    check_leaks_push(req_mem_ctx);
+
+    will_return(__wrap_sss_dp_get_account_send, test_ctx);
+    mock_account_recv_simple();
+    mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
+
+    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
+                                      test_ctx->rctx, test_ctx->ncache, 100, 0,
+                                      NULL, upn);
+    assert_non_null(req);
+    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
+
+    ret = test_ev_loop(test_ctx->tctx);
+    assert_int_equal(ret, ENOENT);
+    assert_true(check_leaks_pop(req_mem_ctx));
+
+    assert_true(test_ctx->dp_called);
+}
+
 void test_user_by_id_multiple_domains_found(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
@@ -994,7 +1359,7 @@ void test_group_by_name_multiple_domains_found(void **state)
 
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
-    mock_parse_inp(name, NULL);
+    mock_parse_inp(name, NULL, ERR_OK);
 
     req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
                                        test_ctx->rctx, test_ctx->ncache, 10, 0,
@@ -1037,7 +1402,7 @@ void test_group_by_name_multiple_domains_notfound(void **state)
 
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
-    mock_parse_inp(name, NULL);
+    mock_parse_inp(name, NULL, ERR_OK);
 
     req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
                                        test_ctx->rctx, test_ctx->ncache, 10, 0,
@@ -1095,7 +1460,7 @@ void test_group_by_name_multiple_domains_parse(void **state)
     req_mem_ctx = talloc_new(global_talloc_context);
     check_leaks_push(req_mem_ctx);
 
-    mock_parse_inp(name, "responder_cache_req_test_d");
+    mock_parse_inp(name, "responder_cache_req_test_d", ERR_OK);
 
     req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
                                        test_ctx->rctx, test_ctx->ncache, 10, 0,
@@ -1910,6 +2275,15 @@ int main(int argc, const char *argv[])
         new_multi_domain_test(user_by_name_multiple_domains_notfound),
         new_multi_domain_test(user_by_name_multiple_domains_parse),
 
+        new_single_domain_test(user_by_upn_cache_valid),
+        new_single_domain_test(user_by_upn_cache_expired),
+        new_single_domain_test(user_by_upn_cache_midpoint),
+        new_single_domain_test(user_by_upn_ncache),
+        new_single_domain_test(user_by_upn_missing_found),
+        new_single_domain_test(user_by_upn_missing_notfound),
+        new_multi_domain_test(user_by_upn_multiple_domains_found),
+        new_multi_domain_test(user_by_upn_multiple_domains_notfound),
+
         new_single_domain_test(user_by_id_cache_valid),
         new_single_domain_test(user_by_id_cache_expired),
         new_single_domain_test(user_by_id_cache_midpoint),
-- 
1.9.3

>From 75b3e7930a05976a60aac783151ad4bfbe4064ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Mon, 14 Sep 2015 11:06:45 +0200
Subject: [PATCH 3/4] cache_req tests: reduce code duplication

---
 src/tests/cmocka/test_responder_cache_req.c | 1624 +++++++--------------------
 1 file changed, 394 insertions(+), 1230 deletions(-)

diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c
index b4018ba331dde9a384fbd39321c8314137ba4e5c..bb79fd10eefd7186f17a1f9306b57ddca2e3279f 100644
--- a/src/tests/cmocka/test_responder_cache_req.c
+++ b/src/tests/cmocka/test_responder_cache_req.c
@@ -52,6 +52,27 @@
                                     test_multi_domain_setup, \
                                     test_multi_domain_teardown)
 
+#define run_cache_req(ctx, send_fn, done_fn, dom, crp, lookup, expret) do { \
+    TALLOC_CTX *req_mem_ctx;                                                \
+    struct tevent_req *req;                                                 \
+    errno_t ret;                                                            \
+                                                                            \
+    req_mem_ctx = talloc_new(global_talloc_context);                        \
+    check_leaks_push(req_mem_ctx);                                          \
+                                                                            \
+    req = send_fn(req_mem_ctx, ctx->tctx->ev, ctx->rctx,                    \
+                  ctx->ncache, 10, crp,                                     \
+                  (dom == NULL ? NULL : dom->name), lookup);                \
+    assert_non_null(req);                                                   \
+    tevent_req_set_callback(req, done_fn, ctx);                             \
+                                                                            \
+    ret = test_ev_loop(ctx->tctx);                                          \
+    assert_int_equal(ret, expret);                                          \
+    assert_true(check_leaks_pop(req_mem_ctx));                              \
+                                                                            \
+    talloc_free(req_mem_ctx);                                               \
+} while (0)
+
 struct cache_req_test_ctx {
     struct sss_test_ctx *tctx;
     struct resp_ctx *rctx;
@@ -80,46 +101,6 @@ struct cli_protocol_version *register_cli_protocol_version(void)
     return version;
 }
 
-struct tevent_req *
-__wrap_sss_dp_get_account_send(TALLOC_CTX *mem_ctx,
-                               struct resp_ctx *rctx,
-                               struct sss_domain_info *dom,
-                               bool fast_reply,
-                               enum sss_dp_acct_type type,
-                               const char *opt_name,
-                               uint32_t opt_id,
-                               const char *extra)
-{
-    struct sysdb_attrs *attrs = NULL;
-    struct cache_req_test_ctx *ctx = NULL;
-    errno_t ret;
-
-    ctx = sss_mock_ptr_type(struct cache_req_test_ctx*);
-    ctx->dp_called = true;
-
-    if (ctx->create_user) {
-        attrs = sysdb_new_attrs(ctx);
-        assert_non_null(attrs);
-
-        ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, TEST_UPN);
-        assert_int_equal(ret, EOK);
-
-        ret = sysdb_store_user(ctx->tctx->dom, TEST_USER_NAME, "pwd",
-                               TEST_USER_ID, 1000, NULL, NULL, NULL,
-                               "cn=test-user,dc=test", attrs, NULL,
-                               1000, time(NULL));
-        assert_int_equal(ret, EOK);
-    }
-
-    if (ctx->create_group) {
-        ret = sysdb_store_group(ctx->tctx->dom, TEST_GROUP_NAME,
-                                TEST_GROUP_ID, NULL, 1000, time(NULL));
-        assert_int_equal(ret, EOK);
-    }
-
-    return test_req_succeed_send(mem_ctx, rctx->ev);
-}
-
 static void cache_req_user_by_name_test_done(struct tevent_req *req)
 {
     struct cache_req_test_ctx *ctx = NULL;
@@ -176,6 +157,173 @@ static void cache_req_group_by_id_test_done(struct tevent_req *req)
     ctx->tctx->done = true;
 }
 
+static void prepare_user(TALLOC_CTX *mem_ctx,
+                         struct sss_domain_info *domain,
+                         uint64_t timeout,
+                         time_t time)
+{
+    struct sysdb_attrs *attrs;
+    errno_t ret;
+
+    attrs = sysdb_new_attrs(mem_ctx);
+    assert_non_null(attrs);
+
+    ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, TEST_UPN);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_store_user(domain, TEST_USER_NAME, "pwd",
+                           TEST_USER_ID, TEST_GROUP_ID, NULL, NULL, NULL,
+                           "cn=test-user,dc=test", attrs, NULL,
+                           timeout, time);
+    assert_int_equal(ret, EOK);
+}
+
+static void run_user_by_name(struct cache_req_test_ctx *test_ctx,
+                             struct sss_domain_info *domain,
+                             int cache_refresh_percent,
+                             errno_t exp_ret)
+{
+    run_cache_req(test_ctx, cache_req_user_by_name_send,
+                  cache_req_user_by_name_test_done, domain,
+                  cache_refresh_percent, TEST_USER_NAME, exp_ret);
+}
+
+static errno_t run_user_by_upn(struct cache_req_test_ctx *test_ctx,
+                               struct sss_domain_info *domain,
+                               int cache_refresh_percent,
+                               errno_t exp_ret)
+{
+    run_cache_req(test_ctx, cache_req_user_by_name_send,
+                  cache_req_user_by_name_test_done, domain,
+                  cache_refresh_percent, TEST_UPN, exp_ret);
+}
+
+static errno_t run_user_by_id(struct cache_req_test_ctx *test_ctx,
+                              struct sss_domain_info *domain,
+                              int cache_refresh_percent,
+                              errno_t exp_ret)
+{
+    run_cache_req(test_ctx, cache_req_user_by_id_send,
+                  cache_req_user_by_id_test_done, domain,
+                  cache_refresh_percent, TEST_USER_ID, exp_ret);
+}
+
+static void check_user(struct cache_req_test_ctx *test_ctx,
+                       struct sss_domain_info *exp_dom)
+{
+    const char *ldbname;
+    const char *ldbupn;
+    uid_t ldbuid;
+
+    assert_non_null(test_ctx->result);
+    assert_int_equal(test_ctx->result->count, 1);
+    assert_non_null(test_ctx->result->msgs);
+    assert_non_null(test_ctx->result->msgs[0]);
+
+    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
+                                          SYSDB_NAME, NULL);
+    assert_non_null(ldbname);
+    assert_string_equal(ldbname, TEST_USER_NAME);
+
+    ldbupn = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
+                                         SYSDB_UPN, NULL);
+    assert_non_null(ldbupn);
+    assert_string_equal(ldbupn, TEST_UPN);
+
+    ldbuid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
+                                       SYSDB_UIDNUM, 0);
+    assert_int_equal(ldbuid, TEST_USER_ID);
+
+    assert_non_null(test_ctx->domain);
+    assert_string_equal(exp_dom->name, test_ctx->domain->name);
+}
+
+static void prepare_group(TALLOC_CTX *mem_ctx,
+                         struct sss_domain_info *domain,
+                         uint64_t timeout,
+                         time_t time)
+{
+    errno_t ret;
+
+    ret = sysdb_store_group(domain, TEST_GROUP_NAME, TEST_GROUP_ID, NULL,
+                            timeout, time);
+    assert_int_equal(ret, EOK);
+}
+
+static void run_group_by_name(struct cache_req_test_ctx *test_ctx,
+                              struct sss_domain_info *domain,
+                              int cache_refresh_percent,
+                              errno_t exp_ret)
+{
+    run_cache_req(test_ctx, cache_req_group_by_name_send,
+                  cache_req_group_by_name_test_done, domain,
+                  cache_refresh_percent, TEST_GROUP_NAME, exp_ret);
+}
+
+static void run_group_by_id(struct cache_req_test_ctx *test_ctx,
+                            struct sss_domain_info *domain,
+                            int cache_refresh_percent,
+                            errno_t exp_ret)
+{
+    run_cache_req(test_ctx, cache_req_group_by_id_send,
+                  cache_req_group_by_id_test_done, domain,
+                  cache_refresh_percent, TEST_GROUP_ID, exp_ret);
+}
+
+static void check_group(struct cache_req_test_ctx *test_ctx,
+                        struct sss_domain_info *exp_dom)
+{
+    const char *ldbname;
+    gid_t ldbgid;
+
+    assert_non_null(test_ctx->result);
+    assert_int_equal(test_ctx->result->count, 1);
+    assert_non_null(test_ctx->result->msgs);
+    assert_non_null(test_ctx->result->msgs[0]);
+
+    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
+                                          SYSDB_NAME, NULL);
+    assert_non_null(ldbname);
+    assert_string_equal(ldbname, TEST_GROUP_NAME);
+
+    ldbgid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
+                                       SYSDB_GIDNUM, 0);
+    assert_int_equal(ldbgid, TEST_USER_ID);
+
+    assert_non_null(test_ctx->domain);
+    assert_string_equal(exp_dom->name, test_ctx->domain->name);
+}
+
+
+struct tevent_req *
+__wrap_sss_dp_get_account_send(TALLOC_CTX *mem_ctx,
+                               struct resp_ctx *rctx,
+                               struct sss_domain_info *dom,
+                               bool fast_reply,
+                               enum sss_dp_acct_type type,
+                               const char *opt_name,
+                               uint32_t opt_id,
+                               const char *extra)
+{
+    struct cache_req_test_ctx *ctx = NULL;
+    errno_t ret;
+
+    ctx = sss_mock_ptr_type(struct cache_req_test_ctx*);
+    ctx->dp_called = true;
+
+    if (ctx->create_user) {
+        prepare_user(ctx, ctx->tctx->dom, 1000, time(NULL));
+    }
+
+    if (ctx->create_group) {
+        ret = sysdb_store_group(ctx->tctx->dom, TEST_GROUP_NAME,
+                                TEST_GROUP_ID, NULL, 1000, time(NULL));
+        assert_int_equal(ret, EOK);
+    }
+
+    return test_req_succeed_send(mem_ctx, rctx->ev);
+}
+
 static int test_single_domain_setup(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
@@ -243,83 +391,40 @@ void test_user_by_name_multiple_domains_found(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
     struct sss_domain_info *domain = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
+    /* Setup user. */
     domain = find_domain_by_name(test_ctx->tctx->dom,
                                  "responder_cache_req_test_d", true);
     assert_non_null(domain);
 
-    ret = sysdb_store_user(domain, name, "pwd", 1000, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", NULL,
-                           NULL, 1000, time(NULL));
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    prepare_user(test_ctx, domain, 1000, time(NULL));
 
+    /* Mock values. */
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
-    mock_parse_inp(name, NULL, ERR_OK);
-
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                      NULL, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
+    mock_parse_inp(TEST_USER_NAME, NULL, ERR_OK);
 
+    /* Test. */
+    run_user_by_name(test_ctx, NULL, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    assert_non_null(test_ctx->domain);
-    assert_string_equal(domain->name, test_ctx->domain->name);
+    check_user(test_ctx, domain);
 }
 
 void test_user_by_name_multiple_domains_notfound(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
-    mock_parse_inp(name, NULL, ERR_OK);
-
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                      NULL, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
+    mock_parse_inp(TEST_USER_NAME, NULL, ERR_OK);
 
+    /* Test. */
+    run_user_by_name(test_ctx, NULL, 0, ENOENT);
     assert_true(test_ctx->dp_called);
 }
 
@@ -331,45 +436,41 @@ void test_user_by_name_multiple_domains_parse(void **state)
     struct tevent_req *req = NULL;
     const char *name = TEST_USER_NAME;
     const char *fqn = NULL;
-    const char *ldbname = NULL;
-    uid_t uid = 2000;
-    uid_t ldbuid;
     errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    /* Add user to the first domain. */
+    /* Add user to the first domain with different uid then test user. */
     domain = find_domain_by_name(test_ctx->tctx->dom,
                                  "responder_cache_req_test_a", true);
     assert_non_null(domain);
 
-    ret = sysdb_store_user(domain, name, "pwd", 1000, 1000,
+    ret = sysdb_store_user(domain, name, "pwd", 2000, 1000,
                            NULL, NULL, NULL, "cn=test-user,dc=test", NULL,
                            NULL, 1000, time(NULL));
     assert_int_equal(ret, EOK);
 
-    /* Add user to the last domain, with different uid. */
+    /* Add test user to the last domain. */
 
     domain = find_domain_by_name(test_ctx->tctx->dom,
                                  "responder_cache_req_test_d", true);
     assert_non_null(domain);
 
-    ret = sysdb_store_user(domain, name, "pwd", uid, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", NULL,
-                           NULL, 1000, time(NULL));
-    assert_int_equal(ret, EOK);
+    prepare_user(test_ctx, domain, 1000, time(NULL));
 
     /* Append domain name to the username. */
     fqn = talloc_asprintf(test_ctx, "%s@%s", name,
                           "responder_cache_req_test_d");
     assert_non_null(fqn);
 
+    /* Mock values. */
+    mock_parse_inp(name, "responder_cache_req_test_d", ERR_OK);
+
+
     /* Test. */
     req_mem_ctx = talloc_new(global_talloc_context);
     check_leaks_push(req_mem_ctx);
 
-    mock_parse_inp(name, "responder_cache_req_test_d", ERR_OK);
-
     req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
                                       test_ctx->rctx, test_ctx->ncache, 10, 0,
                                       NULL, fqn);
@@ -381,22 +482,7 @@ void test_user_by_name_multiple_domains_parse(void **state)
     assert_true(check_leaks_pop(req_mem_ctx));
     assert_false(test_ctx->dp_called);
 
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbuid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_UIDNUM, 0);
-    assert_int_equal(ldbuid, uid);
-
-    assert_non_null(test_ctx->domain);
-    assert_string_equal(domain->name, test_ctx->domain->name);
+    check_user(test_ctx, domain);
 
     assert_non_null(test_ctx->name);
     assert_string_equal(name, test_ctx->name);
@@ -405,589 +491,257 @@ void test_user_by_name_multiple_domains_parse(void **state)
 void test_user_by_name_cache_valid(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", 1000, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", NULL,
-                           NULL, 1000, time(NULL));
-    assert_int_equal(ret, EOK);
+    /* Setup user. */
+    prepare_user(test_ctx, test_ctx->tctx->dom, 1000, time(NULL));
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                      test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    /* Test. */
+    run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_name_cache_expired(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", 1000, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", NULL,
-                           NULL, -1000, time(NULL));
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    /* Setup user. */
+    prepare_user(test_ctx, test_ctx->tctx->dom, -1000, time(NULL));
 
+    /* Mock values. */
     /* DP should be contacted */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                      test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_name_cache_midpoint(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", 1000, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", NULL,
-                           NULL, 50, time(NULL) - 26);
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    /* Setup user. */
+    prepare_user(test_ctx, test_ctx->tctx->dom, 50, time(NULL) - 26);
 
+    /* Mock values. */
     /* DP should be contacted without callback */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 10, 50,
-                                      test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_name(test_ctx, test_ctx->tctx->dom, 50, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_name_ncache(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
     errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
+    /* Setup user. */
     ret = sss_ncache_set_user(test_ctx->ncache, false,
-                              test_ctx->tctx->dom, name);
+                              test_ctx->tctx->dom, TEST_USER_NAME);
     assert_int_equal(ret, EOK);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                      test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
     assert_false(test_ctx->dp_called);
 }
 
 void test_user_by_name_missing_found(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
     test_ctx->create_user = true;
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                      test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_name_missing_notfound(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                      test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
     assert_true(test_ctx->dp_called);
 }
 
 void test_user_by_upn_multiple_domains_found(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    struct sysdb_attrs *attrs = NULL;
     struct sss_domain_info *domain = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *upn = TEST_UPN;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
+    /* Setup user. */
     domain = find_domain_by_name(test_ctx->tctx->dom,
                                  "responder_cache_req_test_d", true);
     assert_non_null(domain);
 
-    attrs = sysdb_new_attrs(test_ctx);
-    assert_non_null(attrs);
-
-    ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, upn);
-    assert_int_equal(ret, EOK);
-
-    ret = sysdb_store_user(domain, name, "pwd", 1000, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", attrs,
-                           NULL, 1000, time(NULL));
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    prepare_user(test_ctx, domain, 1000, time(NULL));
 
+    /* Mock values. */
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
     mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                      NULL, upn);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_upn(test_ctx, NULL, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    assert_non_null(test_ctx->domain);
-    assert_string_equal(domain->name, test_ctx->domain->name);
+    check_user(test_ctx, domain);
 }
 
 void test_user_by_upn_multiple_domains_notfound(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *upn = TEST_UPN;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
     mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                      NULL, upn);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_upn(test_ctx, NULL, 0, ENOENT);
     assert_true(test_ctx->dp_called);
 }
 
 void test_user_by_upn_cache_valid(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    struct sysdb_attrs *attrs = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *upn = TEST_UPN;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    attrs = sysdb_new_attrs(test_ctx);
-    assert_non_null(attrs);
-
-    ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, upn);
-    assert_int_equal(ret, EOK);
-
-    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", 1000, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", attrs,
-                           NULL, 1000, time(NULL));
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    /* Setup user. */
+    prepare_user(test_ctx, test_ctx->tctx->dom, 1000, time(NULL));
 
+    /* Mock values. */
     mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                      NULL, upn);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    /* Test. */
+    run_user_by_upn(test_ctx, NULL, 0, ERR_OK);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_upn_cache_expired(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    struct sysdb_attrs *attrs = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *upn = TEST_UPN;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    attrs = sysdb_new_attrs(test_ctx);
-    assert_non_null(attrs);
-
-    ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, upn);
-    assert_int_equal(ret, EOK);
-
-    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", 1000, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", attrs,
-                           NULL, -1000, time(NULL));
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    /* Setup user. */
+    prepare_user(test_ctx, test_ctx->tctx->dom, -1000, time(NULL));
 
+    /* Mock values. */
     /* DP should be contacted */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
     mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                      NULL, upn);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_upn(test_ctx, NULL, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_upn_cache_midpoint(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    struct sysdb_attrs *attrs = NULL;
-    const char *upn = TEST_UPN;
-    const char *name = TEST_USER_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    attrs = sysdb_new_attrs(test_ctx);
-    assert_non_null(attrs);
-
-    ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, upn);
-    assert_int_equal(ret, EOK);
-
-    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", 1000, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", attrs,
-                           NULL, 50, time(NULL) - 26);
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    /* Setup user. */
+    prepare_user(test_ctx, test_ctx->tctx->dom, 50, time(NULL) - 26);
 
+    /* Mock values. */
     /* DP should be contacted without callback */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 10, 50,
-                                      NULL, upn);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_upn(test_ctx, NULL, 50, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_upn_ncache(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *upn = TEST_UPN;
     errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
+    /* Setup user. */
     ret = sss_ncache_set_user(test_ctx->ncache, false,
-                              test_ctx->tctx->dom, upn);
+                              test_ctx->tctx->dom, TEST_UPN);
     assert_int_equal(ret, EOK);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                      NULL, upn);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_upn(test_ctx, NULL, 0, ENOENT);
     assert_false(test_ctx->dp_called);
 }
 
 void test_user_by_upn_missing_found(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *upn = TEST_UPN;
-    const char *name = TEST_USER_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
     mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
 
     test_ctx->create_user = true;
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                      NULL, upn);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_upn(test_ctx, NULL, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_upn_missing_notfound(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *upn = TEST_UPN;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
     mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND);
 
-    req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                      test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                      NULL, upn);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_upn(test_ctx, NULL, 0, ENOENT);
     assert_true(test_ctx->dp_called);
 }
 
@@ -995,342 +749,140 @@ void test_user_by_id_multiple_domains_found(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
     struct sss_domain_info *domain = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    uid_t uid = TEST_USER_ID;
-    const char *ldbname = NULL;
-    uid_t ldbuid;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
+    /* Setup user. */
     domain = find_domain_by_name(test_ctx->tctx->dom,
                                  "responder_cache_req_test_d", true);
     assert_non_null(domain);
 
-    ret = sysdb_store_user(domain, name, "pwd", uid, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", NULL,
-                           NULL, 1000, time(NULL));
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    prepare_user(test_ctx, domain, 1000, time(NULL));
 
+    /* Mock values. */
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
 
-    req = cache_req_user_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                    test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                    NULL, uid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_id(test_ctx, NULL, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbuid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_UIDNUM, 0);
-    assert_int_equal(ldbuid, uid);
-
-    assert_non_null(test_ctx->domain);
-    assert_string_equal(domain->name, test_ctx->domain->name);
+    check_user(test_ctx, domain);
 }
 
 void test_user_by_id_multiple_domains_notfound(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    uid_t uid = TEST_USER_ID;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
 
-    req = cache_req_user_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                    test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                    NULL, uid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_id(test_ctx, NULL, 0, ENOENT);
     assert_true(test_ctx->dp_called);
 }
 
 void test_user_by_id_cache_valid(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *ldbname = NULL;
-    uid_t uid = TEST_USER_ID;
-    uid_t ldbuid;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", uid, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", NULL,
-                           NULL, 1000, time(NULL));
-    assert_int_equal(ret, EOK);
+    /* Setup user. */
+    prepare_user(test_ctx, test_ctx->tctx->dom, 1000, time(NULL));
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
-    req = cache_req_user_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                    test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                    test_ctx->tctx->dom->name, uid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbuid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_UIDNUM, 0);
-    assert_int_equal(ldbuid, uid);
+    /* Test. */
+    run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_id_cache_expired(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *ldbname = NULL;
-    uid_t uid = TEST_USER_ID;
-    uid_t ldbuid;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", uid, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", NULL,
-                           NULL, -1000, time(NULL));
-    assert_int_equal(ret, EOK);
+    /* Setup user. */
+    prepare_user(test_ctx, test_ctx->tctx->dom, -1000, time(NULL));
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
-    /* DP should be contacted */
+    /* Mock values. */
+    /* DP should be contacted. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
-    req = cache_req_user_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                    test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                    test_ctx->tctx->dom->name, uid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbuid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_UIDNUM, 0);
-    assert_int_equal(ldbuid, uid);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_id_cache_midpoint(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *ldbname = NULL;
-    uid_t uid = TEST_USER_ID;
-    uid_t ldbuid;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_user(test_ctx->tctx->dom, name, "pwd", uid, 1000,
-                           NULL, NULL, NULL, "cn=test-user,dc=test", NULL,
-                           NULL, 50, time(NULL) - 26);
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    /* Setup user. */
+    prepare_user(test_ctx, test_ctx->tctx->dom, 50, time(NULL) - 26);
 
+    /* Mock values. */
     /* DP should be contacted without callback */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
 
-    req = cache_req_user_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                    test_ctx->rctx, test_ctx->ncache, 10, 50,
-                                    test_ctx->tctx->dom->name, uid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_id(test_ctx, test_ctx->tctx->dom, 50, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbuid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_UIDNUM, 0);
-    assert_int_equal(ldbuid, uid);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_id_ncache(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    uid_t uid = TEST_USER_ID;
     errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sss_ncache_set_uid(test_ctx->ncache, false, NULL, uid);
+    /* Setup user. */
+    ret = sss_ncache_set_uid(test_ctx->ncache, false, NULL, TEST_USER_ID);
     assert_int_equal(ret, EOK);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
-    req = cache_req_user_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                    test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                    test_ctx->tctx->dom->name, uid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
     assert_false(test_ctx->dp_called);
 }
 
 void test_user_by_id_missing_found(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_USER_NAME;
-    const char *ldbname = NULL;
-    uid_t uid = TEST_USER_ID;
-    uid_t ldbuid;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
     test_ctx->create_user = true;
 
-    req = cache_req_user_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                    test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                    test_ctx->tctx->dom->name, uid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbuid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_UIDNUM, 0);
-    assert_int_equal(ldbuid, uid);
+    check_user(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_user_by_id_missing_notfound(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    uid_t uid = TEST_USER_ID;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
-    req = cache_req_user_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                    test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                    test_ctx->tctx->dom->name, uid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_user_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
     assert_true(test_ctx->dp_called);
 }
 
@@ -1338,82 +890,39 @@ void test_group_by_name_multiple_domains_found(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
     struct sss_domain_info *domain = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
+    /* Setup group. */
     domain = find_domain_by_name(test_ctx->tctx->dom,
                                  "responder_cache_req_test_d", true);
     assert_non_null(domain);
+    prepare_group(test_ctx, domain, 1000, time(NULL));
 
-    ret = sysdb_store_group(domain, name, TEST_GROUP_ID, NULL,
-                            1000, time(NULL));
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
-    mock_parse_inp(name, NULL, ERR_OK);
-
-    req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                       test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                       NULL, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
+    mock_parse_inp(TEST_GROUP_NAME, NULL, ERR_OK);
 
+    /* Test. */
+    run_group_by_name(test_ctx, NULL, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    assert_non_null(test_ctx->domain);
-    assert_string_equal(domain->name, test_ctx->domain->name);
+    check_group(test_ctx, domain);
 }
 
 void test_group_by_name_multiple_domains_notfound(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
-    mock_parse_inp(name, NULL, ERR_OK);
-
-    req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                       test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                       NULL, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
+    mock_parse_inp(TEST_GROUP_NAME, NULL, ERR_OK);
 
+    /* Test. */
+    run_group_by_name(test_ctx, NULL, 0, ENOENT);
     assert_true(test_ctx->dp_called);
 }
 
@@ -1425,31 +934,26 @@ void test_group_by_name_multiple_domains_parse(void **state)
     struct tevent_req *req = NULL;
     const char *name = TEST_GROUP_NAME;
     const char *fqn = NULL;
-    const char *ldbname = NULL;
-    uid_t gid = 2000;
-    uid_t ldbgid;
     errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    /* Add user to the first domain. */
+    /* Add group to the first domain. */
     domain = find_domain_by_name(test_ctx->tctx->dom,
                                  "responder_cache_req_test_a", true);
     assert_non_null(domain);
 
-    ret = sysdb_store_group(domain, name, 1000, NULL,
+    ret = sysdb_store_group(domain, name, 2000, NULL,
                             1000, time(NULL));
     assert_int_equal(ret, EOK);
 
-    /* Add user to the last domain, with different uid. */
+    /* Add group to the last domain, with different gid. */
 
     domain = find_domain_by_name(test_ctx->tctx->dom,
                                  "responder_cache_req_test_d", true);
     assert_non_null(domain);
 
-    ret = sysdb_store_group(domain, name, gid, NULL,
-                            1000, time(NULL));
-    assert_int_equal(ret, EOK);
+    prepare_group(test_ctx, domain, 1000, time(NULL));
 
     /* Append domain name to the username. */
     fqn = talloc_asprintf(test_ctx, "%s@%s", name,
@@ -1473,22 +977,7 @@ void test_group_by_name_multiple_domains_parse(void **state)
     assert_true(check_leaks_pop(req_mem_ctx));
     assert_false(test_ctx->dp_called);
 
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbgid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_GIDNUM, 0);
-    assert_int_equal(ldbgid, gid);
-
-    assert_non_null(test_ctx->domain);
-    assert_string_equal(domain->name, test_ctx->domain->name);
+    check_group(test_ctx, domain);
 
     assert_non_null(test_ctx->name);
     assert_string_equal(name, test_ctx->name);
@@ -1497,229 +986,103 @@ void test_group_by_name_multiple_domains_parse(void **state)
 void test_group_by_name_cache_valid(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_group(test_ctx->tctx->dom, name, TEST_GROUP_ID, NULL,
-                            1000, time(NULL));
-    assert_int_equal(ret, EOK);
+    /* Setup group. */
+    prepare_group(test_ctx, test_ctx->tctx->dom, 1000, time(NULL));
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
-    req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                       test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                       test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    /* Test. */
+    run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
+    check_group(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_group_by_name_cache_expired(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_group(test_ctx->tctx->dom, name, TEST_GROUP_ID, NULL,
-                            -1000, time(NULL));
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    /* Setup group. */
+    prepare_group(test_ctx, test_ctx->tctx->dom, -1000, time(NULL));
 
+    /* Mock values. */
     /* DP should be contacted */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
-    req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                       test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                       test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    check_group(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_group_by_name_cache_midpoint(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_group(test_ctx->tctx->dom, name, TEST_GROUP_ID, NULL,
-                            50, time(NULL) - 26);
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    /* Setup group. */
+    prepare_group(test_ctx, test_ctx->tctx->dom, 50, time(NULL) - 26);
 
+    /* Mock values. */
     /* DP should be contacted without callback */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
 
-    req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                       test_ctx->rctx, test_ctx->ncache, 10, 50,
-                                       test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_name(test_ctx, test_ctx->tctx->dom, 50, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    check_group(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_group_by_name_ncache(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
     errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
+    /* Setup group. */
     ret = sss_ncache_set_group(test_ctx->ncache, false,
-                               test_ctx->tctx->dom, name);
+                               test_ctx->tctx->dom, TEST_GROUP_NAME);
     assert_int_equal(ret, EOK);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
-    req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                       test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                       test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
     assert_false(test_ctx->dp_called);
 }
 
 void test_group_by_name_missing_found(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    const char *ldbname = NULL;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
     test_ctx->create_group = true;
 
-    req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                       test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                       test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
+    check_group(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_group_by_name_missing_notfound(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
-    req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
-                                       test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                       test_ctx->tctx->dom->name, name);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_name_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
     assert_true(test_ctx->dp_called);
 }
 
@@ -1727,338 +1090,139 @@ void test_group_by_id_multiple_domains_found(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
     struct sss_domain_info *domain = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    const char *ldbname = NULL;
-    gid_t gid = TEST_GROUP_ID;
-    gid_t ldbgid;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
+    /* Setup group. */
     domain = find_domain_by_name(test_ctx->tctx->dom,
                                  "responder_cache_req_test_d", true);
     assert_non_null(domain);
+    prepare_group(test_ctx, domain, 1000, time(NULL));
 
-    ret = sysdb_store_group(domain, name, gid, NULL,
-                            1000, time(NULL));
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
 
-    req = cache_req_group_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                     test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                     NULL, gid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_id(test_ctx, NULL, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbgid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_GIDNUM, 0);
-    assert_int_equal(ldbgid, gid);
-
-    assert_non_null(test_ctx->domain);
-    assert_string_equal(domain->name, test_ctx->domain->name);
+    check_group(test_ctx, domain);
 }
 
 void test_group_by_id_multiple_domains_notfound(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    gid_t gid = TEST_GROUP_ID;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return_always(__wrap_sss_dp_get_account_send, test_ctx);
     will_return_always(sss_dp_get_account_recv, 0);
 
-    req = cache_req_group_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                     test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                     NULL, gid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_id(test_ctx, NULL, 0, ENOENT);
     assert_true(test_ctx->dp_called);
 }
 
 void test_group_by_id_cache_valid(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    const char *ldbname = NULL;
-    gid_t gid = TEST_GROUP_ID;
-    gid_t ldbgid;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_group(test_ctx->tctx->dom, name, gid, NULL,
-                            1000, time(NULL));
-    assert_int_equal(ret, EOK);
+    /* Setup group. */
+    prepare_group(test_ctx, test_ctx->tctx->dom, 1000, time(NULL));
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
-    req = cache_req_group_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                     test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                     test_ctx->tctx->dom->name, gid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbgid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_GIDNUM, 0);
-    assert_int_equal(ldbgid, gid);
+    /* Test. */
+    run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
+    check_group(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_group_by_id_cache_expired(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    const char *ldbname = NULL;
-    gid_t gid = TEST_GROUP_ID;
-    gid_t ldbgid;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_group(test_ctx->tctx->dom, name, gid, NULL,
-                            -1000, time(NULL));
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    /* Setup group. */
+    prepare_group(test_ctx, test_ctx->tctx->dom, -1000, time(NULL));
 
+    /* Mock values. */
     /* DP should be contacted */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
-    req = cache_req_group_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                     test_ctx->rctx, test_ctx->ncache, 10, 0,
-                                     test_ctx->tctx->dom->name, gid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbgid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_GIDNUM, 0);
-    assert_int_equal(ldbgid, gid);
+    check_group(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_group_by_id_cache_midpoint(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    const char *ldbname = NULL;
-    gid_t gid = TEST_GROUP_ID;
-    gid_t ldbgid;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sysdb_store_group(test_ctx->tctx->dom, name, gid, NULL,
-                            50, time(NULL) - 26);
-    assert_int_equal(ret, EOK);
-
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
+    /* Setup group. */
+    prepare_group(test_ctx, test_ctx->tctx->dom, 50, time(NULL) - 26);
 
+    /* Mock values. */
     /* DP should be contacted without callback */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
 
-    req = cache_req_group_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                     test_ctx->rctx, test_ctx->ncache, 10, 50,
-                                     test_ctx->tctx->dom->name, gid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_id(test_ctx, test_ctx->tctx->dom, 50, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbgid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_GIDNUM, 0);
-    assert_int_equal(ldbgid, gid);
+    check_group(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_group_by_id_ncache(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    gid_t gid = TEST_GROUP_ID;
     errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    ret = sss_ncache_set_gid(test_ctx->ncache, false, NULL, gid);
+    /* Setup group. */
+    ret = sss_ncache_set_gid(test_ctx->ncache, false, NULL, TEST_GROUP_ID);
     assert_int_equal(ret, EOK);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
-    req = cache_req_group_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                     test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                     test_ctx->tctx->dom->name, gid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
     assert_false(test_ctx->dp_called);
 }
 
 void test_group_by_id_missing_found(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    const char *name = TEST_GROUP_NAME;
-    const char *ldbname = NULL;
-    gid_t gid = TEST_GROUP_ID;
-    gid_t ldbgid;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
     test_ctx->create_group = true;
 
-    req = cache_req_group_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                     test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                     test_ctx->tctx->dom->name, gid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ERR_OK);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
     assert_true(test_ctx->dp_called);
-
-    assert_non_null(test_ctx->result);
-    assert_int_equal(test_ctx->result->count, 1);
-    assert_non_null(test_ctx->result->msgs);
-    assert_non_null(test_ctx->result->msgs[0]);
-
-    ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0],
-                                          SYSDB_NAME, NULL);
-    assert_non_null(ldbname);
-    assert_string_equal(ldbname, name);
-
-    ldbgid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0],
-                                       SYSDB_GIDNUM, 0);
-    assert_int_equal(ldbgid, gid);
+    check_group(test_ctx, test_ctx->tctx->dom);
 }
 
 void test_group_by_id_missing_notfound(void **state)
 {
     struct cache_req_test_ctx *test_ctx = NULL;
-    TALLOC_CTX *req_mem_ctx = NULL;
-    struct tevent_req *req = NULL;
-    gid_t gid = TEST_GROUP_ID;
-    errno_t ret;
 
     test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
 
-    req_mem_ctx = talloc_new(global_talloc_context);
-    check_leaks_push(req_mem_ctx);
-
+    /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
 
-    req = cache_req_group_by_id_send(req_mem_ctx, test_ctx->tctx->ev,
-                                     test_ctx->rctx, test_ctx->ncache, 100, 0,
-                                     test_ctx->tctx->dom->name, gid);
-    assert_non_null(req);
-    tevent_req_set_callback(req, cache_req_group_by_id_test_done, test_ctx);
-
-    ret = test_ev_loop(test_ctx->tctx);
-    assert_int_equal(ret, ENOENT);
-    assert_true(check_leaks_pop(req_mem_ctx));
-
+    /* Test. */
+    run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
     assert_true(test_ctx->dp_called);
 }
 
-- 
1.9.3

>From 425eaf360c00a3195021abf228168b03b695ae45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Tue, 6 Oct 2015 15:07:48 +0200
Subject: [PATCH 4/4] cache_req: remove raw_name and do not touch orig_name

Parsed name or UPN is now stored in input->name instead of touching
orig_name and storing the original name in raw_name.
---
 src/responder/common/responder_cache_req.c | 43 +++++++++++++++---------------
 1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c
index 70a3010eb697cf14874bd1a950cb7a874bc060b4..f69a55726acf7cc4e95b851bef122a5462575753 100644
--- a/src/responder/common/responder_cache_req.c
+++ b/src/responder/common/responder_cache_req.c
@@ -70,11 +70,13 @@ struct cache_req_input {
     enum cache_req_type type;
 
     /* Provided input. */
-    const char *raw_name;
     const char *orig_name;
     uint32_t id;
     const char *cert;
 
+    /* Parsed name or UPN. */
+    const char *name;
+
     /* Data Provider request type resolved from @type.
      * FIXME: This is currently needed for data provider calls. We should
      * refactor responder_dp.c to get rid of this member. */
@@ -125,11 +127,6 @@ cache_req_input_create(TALLOC_CTX *mem_ctx,
             goto fail;
         }
 
-        input->raw_name = talloc_strdup(input, name);
-        if (input->raw_name == NULL) {
-            goto fail;
-        }
-
         input->orig_name = talloc_strdup(input, name);
         if (input->orig_name == NULL) {
             goto fail;
@@ -196,8 +193,8 @@ fail:
 }
 
 static errno_t
-cache_req_input_set_orig_name(struct cache_req_input *input,
-                              const char *name)
+cache_req_input_set_name(struct cache_req_input *input,
+                         const char *name)
 {
     const char *dup;
 
@@ -206,8 +203,8 @@ cache_req_input_set_orig_name(struct cache_req_input *input,
         return ENOMEM;
     }
 
-    talloc_zfree(input->orig_name);
-    input->orig_name = dup;
+    talloc_zfree(input->name);
+    input->name = dup;
 
     return EOK;
 }
@@ -238,8 +235,13 @@ cache_req_input_set_domain(struct cache_req_input *input,
     case CACHE_REQ_GROUP_BY_FILTER:
     case CACHE_REQ_INITGROUPS:
     case CACHE_REQ_INITGROUPS_BY_UPN:
-        name = sss_get_cased_name(tmp_ctx, input->orig_name,
-                                  domain->case_sensitive);
+        if (input->name == NULL) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "Bug: input->name is NULL?\n");
+            ret = ERR_INTERNAL;
+            goto done;
+        }
+
+        name = sss_get_cased_name(tmp_ctx, input->name, domain->case_sensitive);
         if (name == NULL) {
             ret = ENOMEM;
             goto done;
@@ -316,7 +318,7 @@ cache_req_input_assume_upn(struct cache_req_input *input)
     errno_t ret;
     bool bret;
 
-    if (input->raw_name == NULL || strchr(input->raw_name, '@') == NULL) {
+    if (input->orig_name == NULL || strchr(input->orig_name, '@') == NULL) {
         return false;
     }
 
@@ -335,14 +337,14 @@ cache_req_input_assume_upn(struct cache_req_input *input)
     }
 
     if (bret == true) {
-        ret = cache_req_input_set_orig_name(input, input->raw_name);
+        ret = cache_req_input_set_name(input, input->orig_name);
         if (ret != EOK) {
             DEBUG(SSSDBG_CRIT_FAILURE,
                   "cache_req_input_set_orig_name() failed\n");
             return false;
         }
 
-        DEBUG(SSSDBG_TRACE_FUNC, "Assuming UPN %s\n", input->raw_name);
+        DEBUG(SSSDBG_TRACE_FUNC, "Assuming UPN %s\n", input->orig_name);
     }
 
     return bret;
@@ -909,13 +911,10 @@ static void cache_req_input_parsed(struct tevent_req *subreq)
     ret = sss_parse_inp_recv(subreq, state, &name, &domain);
     switch (ret) {
     case EOK:
-        if (strcmp(name, state->input->orig_name) != 0) {
-            /* The name has changed during input parse phase. */
-            ret = cache_req_input_set_orig_name(state->input, name);
-            if (ret != EOK) {
-                tevent_req_error(req, ret);
-                return;
-            }
+        ret = cache_req_input_set_name(state->input, name);
+        if (ret != EOK) {
+            tevent_req_error(req, ret);
+            return;
         }
         break;
     case ERR_DOMAIN_NOT_FOUND:
-- 
1.9.3

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to