summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2015-01-23 15:32:55 +0100
committerJakub Hrozek <jhrozek@redhat.com>2015-03-13 09:56:06 +0100
commit3a5ea81007bd38ce511c37f65cc45d4b6b95ec44 (patch)
tree4e819e0c42fb5b085315d5f522e10e299f41b0b8
parent665bc06b1a39c64227de74ecbba3db1c4c104ccf (diff)
downloadsssd-3a5ea81007bd38ce511c37f65cc45d4b6b95ec44.tar.gz
sssd-3a5ea81007bd38ce511c37f65cc45d4b6b95ec44.tar.xz
sssd-3a5ea81007bd38ce511c37f65cc45d4b6b95ec44.zip
cache_req: add support for user by uid
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r--src/responder/common/responder_cache_req.c105
-rw-r--r--src/responder/common/responder_cache_req.h17
-rw-r--r--src/responder/ifp/ifpsrv_cmd.c4
-rw-r--r--src/tests/cmocka/test_responder_cache_req.c370
4 files changed, 485 insertions, 11 deletions
diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c
index b60f91c2c..5eb23f8dd 100644
--- a/src/responder/common/responder_cache_req.c
+++ b/src/responder/common/responder_cache_req.c
@@ -33,6 +33,7 @@ struct cache_req_input {
/* Provided input. */
const char *orig_name;
+ uint32_t id;
/* Data Provider request type resolved from @type.
* FIXME: This is currently needed for data provider calls. We should
@@ -54,7 +55,8 @@ struct cache_req_input {
struct cache_req_input *
cache_req_input_create(TALLOC_CTX *mem_ctx,
enum cache_req_type type,
- const char *name)
+ const char *name,
+ uint32_t id)
{
struct cache_req_input *input;
@@ -79,11 +81,20 @@ cache_req_input_create(TALLOC_CTX *mem_ctx,
goto fail;
}
break;
+ case CACHE_REQ_USER_BY_ID:
+ if (id == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0!\n");
+ goto fail;
+ }
+
+ input->id = id;
+ break;
}
/* Resolve Data Provider request type. */
switch (type) {
case CACHE_REQ_USER_BY_NAME:
+ case CACHE_REQ_USER_BY_ID:
input->dp_type = SSS_DP_USER;
break;
@@ -140,6 +151,14 @@ cache_req_input_set_domain(struct cache_req_input *input,
}
break;
+
+ case CACHE_REQ_USER_BY_ID:
+ fqn = talloc_asprintf(tmp_ctx, "UID:%d@%s", input->id, domain->name);
+ if (fqn == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ break;
}
input->domain = domain;
@@ -165,6 +184,9 @@ static errno_t cache_req_check_ncache(struct cache_req_input *input,
ret = sss_ncache_check_user(ncache, neg_timeout,
input->domain, input->dom_objname);
break;
+ case CACHE_REQ_USER_BY_ID:
+ ret = sss_ncache_check_uid(ncache, neg_timeout, input->id);
+ break;
default:
ret = EINVAL;
DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported cache request type\n");
@@ -190,6 +212,43 @@ static void cache_req_add_to_ncache(struct cache_req_input *input,
ret = sss_ncache_set_user(ncache, false, input->domain,
input->dom_objname);
break;
+ case CACHE_REQ_USER_BY_ID:
+ /* Nothing to do. Those types must be unique among all domains so
+ * the don't contain domain part. Therefore they must be set only
+ * if all domains are search and the entry is not found. */
+ ret = EOK;
+ break;
+ default:
+ ret = EINVAL;
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported cache request type\n");
+ break;
+ }
+
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for [%s] [%d]: %s\n",
+ input->debug_fqn, ret, sss_strerror(ret));
+
+ /* not fatal */
+ }
+
+ return;
+}
+
+static void cache_req_add_to_ncache_global(struct cache_req_input *input,
+ struct sss_nc_ctx *ncache)
+{
+ errno_t ret;
+
+ switch (input->type) {
+ case CACHE_REQ_USER_BY_NAME:
+ case CACHE_REQ_INITGROUPS:
+ /* Nothing to do. Those types are already in ncache for selected
+ * domains. */
+ ret = EOK;
+ break;
+ case CACHE_REQ_USER_BY_ID:
+ ret = sss_ncache_set_uid(ncache, false, input->id);
+ break;
default:
ret = EINVAL;
DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported cache request type\n");
@@ -222,6 +281,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_ID:
+ one_item_only = true;
+ ret = sysdb_getpwuid_with_views(mem_ctx, input->domain,
+ input->id, &result);
+ break;
case CACHE_REQ_INITGROUPS:
one_item_only = false;
ret = sysdb_initgroups_with_views(mem_ctx, input->domain,
@@ -385,7 +449,8 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
subreq = sss_dp_get_account_send(state, state->rctx,
state->input->domain, true,
state->input->dp_type,
- state->input->dom_objname, 0, NULL);
+ state->input->dom_objname,
+ state->input->id, NULL);
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band "
"data provider request\n");
@@ -406,8 +471,8 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
subreq = sss_dp_get_account_send(state, state->rctx,
state->input->domain, true,
state->input->dp_type,
- state->input->dom_objname, 0,
- extra_flag);
+ state->input->dom_objname,
+ state->input->id, extra_flag);
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Out of memory sending data provider request\n");
@@ -612,6 +677,12 @@ static errno_t cache_req_next_domain(struct tevent_req *req)
return EAGAIN;
}
+ /* If the object searched has to be unique among all maintained domains,
+ * we have to add it into negative cache here when all domains have
+ * been searched. */
+
+ cache_req_add_to_ncache_global(state->input, state->ncache);
+
return ENOENT;
}
@@ -700,7 +771,29 @@ cache_req_user_by_name_send(TALLOC_CTX *mem_ctx,
{
struct cache_req_input *input;
- input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_NAME, name);
+ input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_NAME, name, 0);
+ if (input == NULL) {
+ return NULL;
+ }
+
+ return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache,
+ neg_timeout, cache_refresh_percent,
+ domain, input);
+}
+
+struct tevent_req *
+cache_req_user_by_id_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct resp_ctx *rctx,
+ struct sss_nc_ctx *ncache,
+ int neg_timeout,
+ int cache_refresh_percent,
+ const char *domain,
+ uid_t uid)
+{
+ struct cache_req_input *input;
+
+ input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_ID, NULL, uid);
if (input == NULL) {
return NULL;
}
@@ -722,7 +815,7 @@ cache_req_initgr_by_name_send(TALLOC_CTX *mem_ctx,
{
struct cache_req_input *input;
- input = cache_req_input_create(mem_ctx, CACHE_REQ_INITGROUPS, name);
+ input = cache_req_input_create(mem_ctx, CACHE_REQ_INITGROUPS, name, 0);
if (input == NULL) {
return NULL;
}
diff --git a/src/responder/common/responder_cache_req.h b/src/responder/common/responder_cache_req.h
index 3d11cd234..3ebcd1e8e 100644
--- a/src/responder/common/responder_cache_req.h
+++ b/src/responder/common/responder_cache_req.h
@@ -29,6 +29,7 @@
enum cache_req_type {
CACHE_REQ_USER_BY_NAME,
+ CACHE_REQ_USER_BY_ID,
CACHE_REQ_INITGROUPS
};
@@ -37,7 +38,8 @@ struct cache_req_input;
struct cache_req_input *
cache_req_input_create(TALLOC_CTX *mem_ctx,
enum cache_req_type type,
- const char *name);
+ const char *name,
+ uint32_t id);
/**
* Currently only SSS_DP_USER and SSS_DP_INITGROUPS are supported.
@@ -72,6 +74,19 @@ cache_req_user_by_name_send(TALLOC_CTX *mem_ctx,
cache_req_recv(mem_ctx, req, _result, _domain)
struct tevent_req *
+cache_req_user_by_id_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct resp_ctx *rctx,
+ struct sss_nc_ctx *ncache,
+ int neg_timeout,
+ int cache_refresh_percent,
+ const char *domain,
+ uid_t uid);
+
+#define cache_req_user_by_id_recv(mem_ctx, req, _result, _domain) \
+ cache_req_recv(mem_ctx, req, _result, _domain)
+
+struct tevent_req *
cache_req_initgr_by_name_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct resp_ctx *rctx,
diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c
index b57a33a8d..0a4bd0530 100644
--- a/src/responder/ifp/ifpsrv_cmd.c
+++ b/src/responder/ifp/ifpsrv_cmd.c
@@ -494,11 +494,11 @@ ifp_user_get_attr_lookup(struct tevent_req *subreq)
switch (state->search_type) {
case SSS_DP_USER:
input = cache_req_input_create(state, CACHE_REQ_USER_BY_NAME,
- state->name);
+ state->name, 0);
break;
case SSS_DP_INITGROUPS:
input = cache_req_input_create(state, CACHE_REQ_INITGROUPS,
- state->name);
+ state->name, 0);
break;
default:
DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported search type [%d]!\n",
diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c
index ece436add..f2e1b85f6 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_USER_ID 1000
#define new_single_domain_test(test) \
cmocka_unit_test_setup_teardown(test_ ## test, \
@@ -89,7 +90,7 @@ __wrap_sss_dp_get_account_send(TALLOC_CTX *mem_ctx,
if (ctx->create_user) {
ret = sysdb_store_user(ctx->tctx->dom, TEST_USER_NAME, "pwd",
- 1000, 1000, NULL, NULL, NULL,
+ TEST_USER_ID, 1000, NULL, NULL, NULL,
"cn=test-user,dc=test", NULL, NULL,
1000, time(NULL));
assert_int_equal(ret, EOK);
@@ -111,6 +112,19 @@ static void cache_req_user_by_name_test_done(struct tevent_req *req)
ctx->tctx->done = true;
}
+static void cache_req_user_by_id_test_done(struct tevent_req *req)
+{
+ struct cache_req_test_ctx *ctx = NULL;
+
+ ctx = tevent_req_callback_data(req, struct cache_req_test_ctx);
+
+ ctx->tctx->error = cache_req_user_by_id_recv(ctx, req,
+ &ctx->result, &ctx->domain);
+ talloc_zfree(req);
+
+ ctx->tctx->done = true;
+}
+
static int test_single_domain_setup(void **state)
{
struct cache_req_test_ctx *test_ctx = NULL;
@@ -488,6 +502,349 @@ void test_user_by_name_missing_notfound(void **state)
assert_true(test_ctx->dp_called);
}
+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);
+
+ 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);
+
+ 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));
+
+ 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);
+}
+
+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);
+
+ 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));
+
+ 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);
+
+ 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);
+}
+
+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);
+
+ 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();
+
+ 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_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);
+}
+
+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);
+
+ /* 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));
+
+ 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);
+}
+
+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, uid);
+ 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));
+
+ 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);
+
+ 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));
+
+ 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);
+}
+
+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);
+
+ 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));
+
+ assert_true(test_ctx->dp_called);
+}
+
int main(int argc, const char *argv[])
{
poptContext pc;
@@ -506,7 +863,16 @@ int main(int argc, const char *argv[])
new_single_domain_test(user_by_name_missing_found),
new_single_domain_test(user_by_name_missing_notfound),
new_multi_domain_test(user_by_name_multiple_domains_found),
- new_multi_domain_test(user_by_name_multiple_domains_notfound)
+ new_multi_domain_test(user_by_name_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),
+ new_single_domain_test(user_by_id_ncache),
+ new_single_domain_test(user_by_id_missing_found),
+ new_single_domain_test(user_by_id_missing_notfound),
+ new_multi_domain_test(user_by_id_multiple_domains_found),
+ new_multi_domain_test(user_by_id_multiple_domains_notfound)
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */