summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2017-02-22 14:34:06 +0100
committerLukas Slebodnik <lslebodn@redhat.com>2017-03-02 12:48:37 +0100
commit54039570d26e29444c398aa4ad6ba638f1713566 (patch)
treedcf6fa586fe284bed0c4dc435e838791fbd1c9e8
parent6dd271fdcf6ceb0afd77e703c98897672da3671a (diff)
downloadsssd-54039570d26e29444c398aa4ad6ba638f1713566.tar.gz
sssd-54039570d26e29444c398aa4ad6ba638f1713566.tar.xz
sssd-54039570d26e29444c398aa4ad6ba638f1713566.zip
cache_req: use own namespace for UPNs
If the UPN use the same domain name as the configured domain an unsuccessful lookup by name will already create an entry in the negative cache. If the lookup by UPN would use the same namespace the lookup will immediately be finished because there would already be an entry in the negative cache. Resolves: https://pagure.io/SSSD/sssd/issue/3313 Reviewed-by: Pavel Březina <pbrezina@redhat.com>
-rw-r--r--Makefile.am1
-rw-r--r--src/responder/common/cache_req/plugins/cache_req_user_by_upn.c4
-rw-r--r--src/responder/common/negcache.c36
-rw-r--r--src/responder/common/negcache.h4
-rw-r--r--src/tests/cmocka/test_nss_srv.c49
-rw-r--r--src/tests/cmocka/test_responder_cache_req.c6
6 files changed, 95 insertions, 5 deletions
diff --git a/Makefile.am b/Makefile.am
index 30ee5e590..182a84e3a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2192,6 +2192,7 @@ nss_srv_tests_CFLAGS = \
$(AM_CFLAGS)
nss_srv_tests_LDFLAGS = \
-Wl,-wrap,sss_ncache_check_user \
+ -Wl,-wrap,sss_ncache_check_upn \
-Wl,-wrap,sss_ncache_check_uid \
-Wl,-wrap,sss_ncache_check_sid \
-Wl,-wrap,sss_ncache_check_cert \
diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c b/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c
index f496479a3..9c6957309 100644
--- a/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c
+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c
@@ -66,7 +66,7 @@ cache_req_user_by_upn_ncache_check(struct sss_nc_ctx *ncache,
struct sss_domain_info *domain,
struct cache_req_data *data)
{
- return sss_ncache_check_user(ncache, domain, data->name.lookup);
+ return sss_ncache_check_upn(ncache, domain, data->name.lookup);
}
static errno_t
@@ -74,7 +74,7 @@ cache_req_user_by_upn_ncache_add(struct sss_nc_ctx *ncache,
struct sss_domain_info *domain,
struct cache_req_data *data)
{
- return sss_ncache_set_user(ncache, false, domain, data->name.lookup);
+ return sss_ncache_set_upn(ncache, false, domain, data->name.lookup);
}
static errno_t
diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index 944a06e15..084c47aa8 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -289,6 +289,24 @@ int sss_ncache_check_user(struct sss_nc_ctx *ctx, struct sss_domain_info *dom,
return sss_cache_check_ent(ctx, dom, name, sss_ncache_check_user_int);
}
+int sss_ncache_check_upn(struct sss_nc_ctx *ctx, struct sss_domain_info *dom,
+ const char *name)
+{
+ char *neg_cache_name = NULL;
+ errno_t ret;
+
+ neg_cache_name = talloc_asprintf(ctx, "@%s", name);
+ if (neg_cache_name == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sss_cache_check_ent(ctx, dom, neg_cache_name,
+ sss_ncache_check_user_int);
+ talloc_free(neg_cache_name);
+
+ return ret;
+}
+
int sss_ncache_check_group(struct sss_nc_ctx *ctx, struct sss_domain_info *dom,
const char *name)
{
@@ -540,6 +558,24 @@ int sss_ncache_set_user(struct sss_nc_ctx *ctx, bool permanent,
return sss_ncache_set_ent(ctx, permanent, dom, name, sss_ncache_set_user_int);
}
+int sss_ncache_set_upn(struct sss_nc_ctx *ctx, bool permanent,
+ struct sss_domain_info *dom, const char *name)
+{
+ char *neg_cache_name = NULL;
+ errno_t ret;
+
+ neg_cache_name = talloc_asprintf(ctx, "@%s", name);
+ if (neg_cache_name == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sss_ncache_set_ent(ctx, permanent, dom, neg_cache_name,
+ sss_ncache_set_user_int);
+ talloc_free(neg_cache_name);
+
+ return ret;
+}
+
int sss_ncache_set_group(struct sss_nc_ctx *ctx, bool permanent,
struct sss_domain_info *dom, const char *name)
{
diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h
index 8af736a67..782ec140f 100644
--- a/src/responder/common/negcache.h
+++ b/src/responder/common/negcache.h
@@ -33,6 +33,8 @@ uint32_t sss_ncache_get_timeout(struct sss_nc_ctx *ctx);
/* check if the user is expired according to the passed in time to live */
int sss_ncache_check_user(struct sss_nc_ctx *ctx, struct sss_domain_info *dom,
const char *name);
+int sss_ncache_check_upn(struct sss_nc_ctx *ctx, struct sss_domain_info *dom,
+ const char *name);
int sss_ncache_check_group(struct sss_nc_ctx *ctx, struct sss_domain_info *dom,
const char *name);
int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, struct sss_domain_info *dom,
@@ -59,6 +61,8 @@ int sss_ncache_check_service_port(struct sss_nc_ctx *ctx,
* users and groups) */
int sss_ncache_set_user(struct sss_nc_ctx *ctx, bool permanent,
struct sss_domain_info *dom, const char *name);
+int sss_ncache_set_upn(struct sss_nc_ctx *ctx, bool permanent,
+ struct sss_domain_info *dom, const char *name);
int sss_ncache_set_group(struct sss_nc_ctx *ctx, bool permanent,
struct sss_domain_info *dom, const char *name);
int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent,
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
index 715a61e53..8942788b0 100644
--- a/src/tests/cmocka/test_nss_srv.c
+++ b/src/tests/cmocka/test_nss_srv.c
@@ -171,6 +171,21 @@ int __wrap_sss_ncache_check_user(struct sss_nc_ctx *ctx,
return ret;
}
+int __real_sss_ncache_check_upn(struct sss_nc_ctx *ctx,
+ struct sss_domain_info *dom, const char *name);
+
+int __wrap_sss_ncache_check_upn(struct sss_nc_ctx *ctx,
+ struct sss_domain_info *dom, const char *name)
+{
+ int ret;
+
+ ret = __real_sss_ncache_check_upn(ctx, dom, name);
+ if (ret == EEXIST) {
+ nss_test_ctx->ncache_hits++;
+ }
+ return ret;
+}
+
int __real_sss_ncache_check_uid(struct sss_nc_ctx *ctx,
struct sss_domain_info *dom, uid_t uid);
@@ -2558,6 +2573,38 @@ void test_nss_getpwnam_upn(void **state)
assert_int_equal(ret, EOK);
}
+void test_nss_getpwnam_upn_same_domain(void **state)
+{
+ errno_t ret;
+ struct sysdb_attrs *attrs;
+
+ attrs = sysdb_new_attrs(nss_test_ctx);
+ assert_non_null(attrs);
+
+ ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, "upnuser_upn@" TEST_DOM_NAME);
+ assert_int_equal(ret, EOK);
+
+ /* Prime the cache with a valid user */
+ ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom,
+ &upn_user, attrs, 0);
+ assert_int_equal(ret, EOK);
+
+ mock_input_user_or_group("upnuser_upn@" TEST_DOM_NAME);
+ mock_account_recv_simple();
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM);
+ mock_fill_user();
+
+ /* Query for that user, call a callback when command finishes */
+ set_cmd_cb(test_nss_getpwnam_upn_check);
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM,
+ nss_test_ctx->nss_cmds);
+ assert_int_equal(ret, EOK);
+
+ /* Wait until the test finishes with EOK */
+ ret = test_ev_loop(nss_test_ctx->tctx);
+ assert_int_equal(ret, EOK);
+}
+
/* Test that searching for a nonexistant user yields ENOENT.
* Account callback will be called
*/
@@ -3743,6 +3790,8 @@ int main(int argc, const char *argv[])
nss_test_teardown),
cmocka_unit_test_setup_teardown(test_nss_getpwnam_upn,
nss_test_setup, nss_test_teardown),
+ cmocka_unit_test_setup_teardown(test_nss_getpwnam_upn_same_domain,
+ nss_test_setup, nss_test_teardown),
cmocka_unit_test_setup_teardown(test_nss_getpwnam_upn_neg,
nss_test_setup, nss_test_teardown),
cmocka_unit_test_setup_teardown(test_nss_initgroups,
diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c
index 94a902c03..5f1e5350e 100644
--- a/src/tests/cmocka/test_responder_cache_req.c
+++ b/src/tests/cmocka/test_responder_cache_req.c
@@ -839,9 +839,9 @@ void test_user_by_upn_ncache(void **state)
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, users[0].upn);
+ /* Setup user's UPN. */
+ ret = sss_ncache_set_upn(test_ctx->ncache, false,
+ test_ctx->tctx->dom, users[0].upn);
assert_int_equal(ret, EOK);
/* Mock values. */