URL: https://github.com/SSSD/sssd/pull/162
Author: sumit-bose
 Title: #162: cache_req: use own namespace for UPNs
Action: opened

PR body:
"""
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://fedorahosted.org/sssd/ticket/3313
"""

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/162/head:pr162
git checkout pr162
From a9c01dfbc0693525d8a0aff736bacc13117702c0 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Wed, 22 Feb 2017 14:34:06 +0100
Subject: [PATCH] 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://fedorahosted.org/sssd/ticket/3313
---
 Makefile.am                                        |  1 +
 .../cache_req/plugins/cache_req_user_by_upn.c      |  4 +-
 src/responder/common/negcache.c                    | 36 ++++++++++++++++
 src/responder/common/negcache.h                    |  4 ++
 src/tests/cmocka/test_nss_srv.c                    | 49 ++++++++++++++++++++++
 5 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index e676e18..8e8eb9a 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 f496479..9c69573 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 944a06e..084c47a 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 8af736a..782ec14 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 715a61e..8942788 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,
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org

Reply via email to