From cbb73503b07ef3776a72f90c6f4e2a34c9a3323a Mon Sep 17 00:00:00 2001
From: Petr Cech <pcech@redhat.com>
Date: Fri, 22 Apr 2016 04:27:47 -0400
Subject: [PATCH 1/8] NEGCACHE: Adding timeout to struct sss_nc_ctx

It adds timeout of negative cache to handling
struct sss_nc_ctx.

There is one change in API of negatice cache:
 * int sss_ncache_init(TALLOC_CTX *memctx,
                       uint32_t timeout,  <----- new
                       struct sss_nc_ctx **_ctx);

There is also one new function in common/responder:
*  int responder_get_neg_timeout_from_confdb(struct confdb_ctx *cdb,
                                             uint32_t *neg_timeout);

Resolves:
https://fedorahosted.org/sssd/ticket/2317
---
 src/responder/common/negcache.c             |  6 +++++-
 src/responder/common/negcache.h             |  3 ++-
 src/responder/common/responder.h            |  4 ++++
 src/responder/common/responder_common.c     | 28 ++++++++++++++++++++++++++++
 src/responder/ifp/ifpsrv.c                  |  6 +++++-
 src/responder/nss/nsssrv.c                  |  6 +++++-
 src/responder/pac/pacsrv.c                  |  6 +++++-
 src/responder/pam/pamsrv.c                  |  6 +++++-
 src/responder/sudo/sudosrv.c                |  6 +++++-
 src/tests/cmocka/test_negcache.c            |  6 +++---
 src/tests/cmocka/test_nss_srv.c             |  2 +-
 src/tests/cmocka/test_pam_srv.c             |  2 +-
 src/tests/cmocka/test_responder_cache_req.c |  4 ++--
 13 files changed, 71 insertions(+), 14 deletions(-)

diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index 1617bf8c5cf7d36e7091a000f6473d1bcfe44f3f..57d1969023d109a6e9ec88c95ae902a7e01f4e0d 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -39,6 +39,7 @@
 
 struct sss_nc_ctx {
     struct tdb_context *tdb;
+    uint32_t timeout;
 };
 
 typedef int (*ncache_set_byname_fn_t)(struct sss_nc_ctx *, bool,
@@ -58,7 +59,8 @@ static int string_to_tdb_data(char *str, TDB_DATA *ret)
     return EOK;
 }
 
-int sss_ncache_init(TALLOC_CTX *memctx, struct sss_nc_ctx **_ctx)
+int sss_ncache_init(TALLOC_CTX *memctx,  uint32_t timeout,
+                    struct sss_nc_ctx **_ctx)
 {
     struct sss_nc_ctx *ctx;
 
@@ -70,6 +72,8 @@ int sss_ncache_init(TALLOC_CTX *memctx, struct sss_nc_ctx **_ctx)
     ctx->tdb = tdb_open("memcache", 0, TDB_INTERNAL, O_RDWR|O_CREAT, 0);
     if (!ctx->tdb) return errno;
 
+    ctx->timeout = timeout;
+
     *_ctx = ctx;
     return EOK;
 };
diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h
index 46e66d503e45da0ee61735a17e88cbb84bd4ea49..bad8e5109de3b11672a3698dc91d1d1ee622376e 100644
--- a/src/responder/common/negcache.h
+++ b/src/responder/common/negcache.h
@@ -25,7 +25,8 @@
 struct sss_nc_ctx;
 
 /* init the in memory negative cache */
-int sss_ncache_init(TALLOC_CTX *memctx, struct sss_nc_ctx **_ctx);
+int sss_ncache_init(TALLOC_CTX *memctx, uint32_t 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, int ttl,
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index 1fa6fc60c62986a9b58c19f97c00e3ad0efc728e..fc07c60b776a291d33c28146db776bd7765c9c26 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -344,4 +344,8 @@ errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 
 const char **parse_attr_list_ex(TALLOC_CTX *mem_ctx, const char *conf_str,
                                 const char **defaults);
+
+int responder_get_neg_timeout_from_confdb(struct confdb_ctx *cdb,
+                                          uint32_t *neg_timeout);
+
 #endif /* __SSS_RESPONDER_H__ */
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 982318647ee9ee7d6795621c03ad8cf53fb78f43..c55b55f15622d819c70357835a4561fd5efe5366 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -1082,3 +1082,31 @@ void responder_set_fd_limit(rlim_t fd_limit)
                "Proceeding with system values\n");
     }
 }
+
+int responder_get_neg_timeout_from_confdb(struct confdb_ctx *cdb,
+                                          uint32_t *neg_timeout)
+{
+    int value;
+    int ret = EOK;
+
+    ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY,
+                         CONFDB_NSS_ENTRY_NEG_TIMEOUT, 15,
+                         &value);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              "Fatal failure of setup negative cache timeout.\n");
+        ret = ENOENT;
+        goto done;
+    }
+
+    if (value < 0) {
+        ret = EINVAL;
+        goto done;
+    }
+
+    *neg_timeout = value;
+    ret = EOK;
+
+done:
+    return ret;
+}
diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c
index 83e5ad3959aa75758402cb85b69bbc30fd4e5706..969dbcd31ff3df661b163845242c8390bb8f4bd2 100644
--- a/src/responder/ifp/ifpsrv.c
+++ b/src/responder/ifp/ifpsrv.c
@@ -227,6 +227,7 @@ int ifp_process_init(TALLOC_CTX *mem_ctx,
     struct be_conn *iter;
     int ret;
     int max_retries;
+    uint32_t neg_timeout;
     char *uid_str;
     char *attr_list_str;
     char *wildcard_limit_str;
@@ -290,7 +291,10 @@ int ifp_process_init(TALLOC_CTX *mem_ctx,
         goto fail;
     }
 
-    ret = sss_ncache_init(rctx, &ifp_ctx->ncache);
+    ret = responder_get_neg_timeout_from_confdb(cdb, &neg_timeout);
+    if (ret != EOK) goto fail;
+
+    ret = sss_ncache_init(rctx, neg_timeout, &ifp_ctx->ncache);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, "fatal error initializing negcache\n");
         goto fail;
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index d8eff7968c4929663412aa56d08414689b921a22..5dfee5a3209b3c5056093fbfbdc54046136a2e5e 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -416,6 +416,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
     enum idmap_error_code err;
     int hret;
     int fd_limit;
+    uint32_t neg_timeout;
 
     nss_cmds = get_nss_cmds();
 
@@ -440,7 +441,10 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
         goto fail;
     }
 
-    ret = sss_ncache_init(rctx, &nctx->ncache);
+    ret = responder_get_neg_timeout_from_confdb(cdb, &neg_timeout);
+    if (ret != EOK) goto fail;
+
+    ret = sss_ncache_init(rctx, neg_timeout, &nctx->ncache);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               "fatal error initializing negative cache\n");
diff --git a/src/responder/pac/pacsrv.c b/src/responder/pac/pacsrv.c
index 683dca7b980e191472794c411b4950a71340edb9..d58350631338f3fb6210ce80e4dc29a498f8954d 100644
--- a/src/responder/pac/pacsrv.c
+++ b/src/responder/pac/pacsrv.c
@@ -111,6 +111,7 @@ int pac_process_init(TALLOC_CTX *mem_ctx,
     struct be_conn *iter;
     struct pac_ctx *pac_ctx;
     int ret, max_retries;
+    uint32_t neg_timeout;
     enum idmap_error_code err;
     int fd_limit;
     char *uid_str;
@@ -205,7 +206,10 @@ int pac_process_init(TALLOC_CTX *mem_ctx,
         goto fail;
     }
 
-    ret = sss_ncache_init(pac_ctx, &pac_ctx->ncache);
+    ret = responder_get_neg_timeout_from_confdb(cdb, &neg_timeout);
+    if (ret != EOK) goto fail;
+
+    ret = sss_ncache_init(pac_ctx, neg_timeout, &pac_ctx->ncache);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               "Failed to initializing negative cache\n");
diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
index a63b52ec173342b6089adb5d7131cdc2d8a526d2..4c41517f95ba30e675ade020684d3f68378cd89b 100644
--- a/src/responder/pam/pamsrv.c
+++ b/src/responder/pam/pamsrv.c
@@ -191,6 +191,7 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
     struct be_conn *iter;
     struct pam_ctx *pctx;
     int ret, max_retries;
+    uint32_t neg_timeout;
     int id_timeout;
     int fd_limit;
 
@@ -264,7 +265,10 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
 
     pctx->id_timeout = (size_t)id_timeout;
 
-    ret = sss_ncache_init(pctx, &pctx->ncache);
+    ret = responder_get_neg_timeout_from_confdb(cdb, &neg_timeout);
+    if (ret != EOK) goto done;
+
+    ret = sss_ncache_init(pctx, neg_timeout, &pctx->ncache);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               "fatal error initializing negative cache\n");
diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c
index ff5d92e7005db9f6e883c78cf1a6218e9a150e0a..6cee1678cb391a6b4708ef6671bd7e1194dd0a46 100644
--- a/src/responder/sudo/sudosrv.c
+++ b/src/responder/sudo/sudosrv.c
@@ -90,6 +90,7 @@ int sudo_process_init(TALLOC_CTX *mem_ctx,
     struct be_conn *iter;
     int ret;
     int max_retries;
+    uint32_t neg_timeout;
 
     sudo_cmds = get_sudo_cmds();
     ret = sss_process_init(mem_ctx, ev, cdb,
@@ -114,7 +115,10 @@ int sudo_process_init(TALLOC_CTX *mem_ctx,
         goto fail;
     }
 
-    ret = sss_ncache_init(rctx, &sudo_ctx->ncache);
+    ret = responder_get_neg_timeout_from_confdb(cdb, &neg_timeout);
+    if (ret != EOK) goto fail;
+
+    ret = sss_ncache_init(rctx, neg_timeout, &sudo_ctx->ncache);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               "fatal error initializing ncache\n");
diff --git a/src/tests/cmocka/test_negcache.c b/src/tests/cmocka/test_negcache.c
index 45dcd43c89f036aa758b0669f319ad13431efa9c..ba5824a15b1f84901309e2299c799d11a77c01f2 100644
--- a/src/tests/cmocka/test_negcache.c
+++ b/src/tests/cmocka/test_negcache.c
@@ -80,7 +80,7 @@ mock_nctx(TALLOC_CTX *mem_ctx)
         return NULL;
     }
 
-    ret = sss_ncache_init(nctx, &nctx->ncache);
+    ret = sss_ncache_init(nctx, SHORTSPAN, &nctx->ncache);
     if (ret != EOK) {
         talloc_free(nctx);
         return NULL;
@@ -140,7 +140,7 @@ static int setup(void **state)
     ts = talloc(NULL, struct test_state);
     assert_non_null(ts);
 
-    ret  = sss_ncache_init(ts, &ts->ctx);
+    ret  = sss_ncache_init(ts, SHORTSPAN, &ts->ctx);
     assert_int_equal(ret, EOK);
     assert_non_null(ts->ctx);
 
@@ -164,7 +164,7 @@ static void test_sss_ncache_init(void **state)
     memctx = talloc_new(NULL);
     assert_non_null(memctx);
 
-    ret = sss_ncache_init(memctx, &ctx );
+    ret = sss_ncache_init(memctx, SHORTSPAN, &ctx );
     assert_int_equal(ret, EOK);
     assert_non_null(ctx);
 
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
index f05b55e461d9a058a4894800b2efae3417c8dc01..30df38b324f5a57d408fb52fc2c30c5577c8ef40 100644
--- a/src/tests/cmocka/test_nss_srv.c
+++ b/src/tests/cmocka/test_nss_srv.c
@@ -70,7 +70,7 @@ mock_nctx(TALLOC_CTX *mem_ctx)
         return NULL;
     }
 
-    ret = sss_ncache_init(nctx, &nctx->ncache);
+    ret = sss_ncache_init(nctx, 10, &nctx->ncache);
     if (ret != EOK) {
         talloc_free(nctx);
         return NULL;
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index 202e970a658c3a6d1daa0e87d1fc42ada541ad23..75c3ddcf5fd4a0a349e906cacfe1a64dc814375c 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -177,7 +177,7 @@ struct pam_ctx *mock_pctx(TALLOC_CTX *mem_ctx)
     pctx = talloc_zero(mem_ctx, struct pam_ctx);
     assert_non_null(pctx);
 
-    ret = sss_ncache_init(pctx, &pctx->ncache);
+    ret = sss_ncache_init(pctx, 10, &pctx->ncache);
     assert_int_equal(ret, EOK);
 
     pctx->neg_timeout = 10;
diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c
index fe1c4c0a5fd10413cd81a4219b69d934fcd486c5..679e2c1eb2ae2b81976c299daf4653230624a0e9 100644
--- a/src/tests/cmocka/test_responder_cache_req.c
+++ b/src/tests/cmocka/test_responder_cache_req.c
@@ -434,7 +434,7 @@ static int test_single_domain_setup(void **state)
                                test_ctx->tctx->dom, NULL);
     assert_non_null(test_ctx->rctx);
 
-    ret = sss_ncache_init(test_ctx, &test_ctx->ncache);
+    ret = sss_ncache_init(test_ctx, 10, &test_ctx->ncache);
     assert_int_equal(ret, EOK);
 
     check_leaks_push(test_ctx);
@@ -480,7 +480,7 @@ static int test_multi_domain_setup(void **state)
                                test_ctx->tctx->dom, NULL);
     assert_non_null(test_ctx->rctx);
 
-    ret = sss_ncache_init(test_ctx, &test_ctx->ncache);
+    ret = sss_ncache_init(test_ctx, 10, &test_ctx->ncache);
     assert_int_equal(ret, EOK);
 
     check_leaks_push(test_ctx);
-- 
2.5.5

