>From 6bd1079b866e84de292b62e0e68d0ce65bff9c37 Mon Sep 17 00:00:00 2001
From: Simo Sorce <ssorce@redhat.com>
Date: Sat, 24 Oct 2009 13:36:34 -0400
Subject: [PATCH] Move responsibility for entry expiration timeout

The providers are now responsible for determining how long a cached
entry is considered valid. The default is the same as before (600s)
---
 server/confdb/confdb.h                      |    2 +-
 server/config/etc/sssd.api.conf             |    2 +-
 server/config/etc/sssd.api.d/sssd-ldap.conf |    1 -
 server/db/sysdb.h                           |   20 +++++++++------
 server/db/sysdb_ops.c                       |   36 +++++++++++++++++++++++---
 server/man/sssd.conf.5.xml                  |   25 +++++++++---------
 server/providers/ipa/ipa_common.c           |    8 +++---
 server/providers/ipa/ipa_common.h           |    2 +-
 server/providers/ldap/ldap_common.c         |    2 +-
 server/providers/ldap/sdap.h                |    2 +-
 server/providers/ldap/sdap_async.c          |   12 ++++++--
 server/providers/proxy.c                    |   30 ++++++++++++++++------
 server/responder/nss/nsssrv.c               |   10 -------
 server/responder/nss/nsssrv.h               |    1 -
 server/responder/nss/nsssrv_cmd.c           |   16 ++++++------
 server/responder/pam/pamsrv_cmd.c           |   11 +++-----
 server/tests/sysdb-tests.c                  |    4 +-
 17 files changed, 109 insertions(+), 75 deletions(-)

diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h
index e535286..8729aad 100644
--- a/server/confdb/confdb.h
+++ b/server/confdb/confdb.h
@@ -55,7 +55,6 @@
 /* NSS */
 #define CONFDB_NSS_CONF_ENTRY "config/nss"
 #define CONFDB_NSS_ENUM_CACHE_TIMEOUT "enum_cache_timeout"
-#define CONFDB_NSS_ENTRY_CACHE_TIMEOUT "entry_cache_timeout"
 #define CONFDB_NSS_ENTRY_CACHE_NOWAIT_TIMEOUT "entry_cache_nowait_timeout"
 #define CONFDB_NSS_ENTRY_NEG_TIMEOUT "entry_negative_timeout"
 #define CONFDB_NSS_FILTER_USERS_IN_GROUPS "filter_users_in_groups"
@@ -86,6 +85,7 @@
 #define CONFDB_DOMAIN_LEGACY_PASS "store_legacy_passwords"
 #define CONFDB_DOMAIN_MPG "magic_private_groups"
 #define CONFDB_DOMAIN_FQ "use_fully_qualified_names"
+#define CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT "entry_cache_timeout"
 
 /* Local Provider */
 #define CONFDB_LOCAL_DEFAULT_SHELL   "default_shell"
diff --git a/server/config/etc/sssd.api.conf b/server/config/etc/sssd.api.conf
index 8ec6d9c..0450d98 100644
--- a/server/config/etc/sssd.api.conf
+++ b/server/config/etc/sssd.api.conf
@@ -21,7 +21,6 @@ full_name_format = str, None
 
 [nss]
 # Name service
-enum_cache_timeout = int, None
 entry_cache_timeout = int, None
 entry_cache_no_wait_timeout = int, None
 entry_negative_timeout = int, None
@@ -52,3 +51,4 @@ enumerate = bool, None, true
 cache_credentials = bool, None, false
 store_legacy_passwords = bool, None, false
 use_fully_qualified_names = bool, None, false
+enum_cache_timeout = int, None
diff --git a/server/config/etc/sssd.api.d/sssd-ldap.conf b/server/config/etc/sssd.api.d/sssd-ldap.conf
index 3aa1fb0..4ee371e 100644
--- a/server/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/server/config/etc/sssd.api.d/sssd-ldap.conf
@@ -7,7 +7,6 @@ ldap_default_authtok = str, None
 ldap_network_timeout = int, None
 ldap_opt_timeout = int, None
 ldap_offline_timeout = int, None
-ldap_stale_time = int, None
 ldap_tls_cacert = str, None
 ldap_tls_reqcert = str, None
 ldap_sasl_mech = str, None
diff --git a/server/db/sysdb.h b/server/db/sysdb.h
index dfb53aa..e1cff85 100644
--- a/server/db/sysdb.h
+++ b/server/db/sysdb.h
@@ -65,6 +65,7 @@
 #define SYSDB_USERPIC "userPicture"
 
 #define SYSDB_LAST_UPDATE "lastUpdate"
+#define SYSDB_CACHE_EXPIRE "dataExpireTimestamp"
 
 #define SYSDB_CACHEDPWD "cachedPassword"
 
@@ -99,7 +100,7 @@
 #define SYSDB_PW_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \
                         SYSDB_GIDNUM, SYSDB_GECOS, \
                         SYSDB_HOMEDIR, SYSDB_SHELL, \
-                        SYSDB_LAST_UPDATE, \
+                        SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
                         "objectClass", \
                         NULL}
 #define SYSDB_USER_ATTRS {SYSDB_DEFAULTGROUP, \
@@ -112,23 +113,24 @@
                           SYSDB_SESSION, \
                           SYSDB_LAST_LOGIN, \
                           SYSDB_USERPIC, \
-                          SYSDB_LAST_UPDATE, \
+                          SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
                           NULL}
 #define SYSDB_GRSRC_ATTRS {SYSDB_NAME, SYSDB_GIDNUM, \
-                           SYSDB_LAST_UPDATE, \
+                           SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
                            "objectClass", \
                            NULL}
 #define SYSDB_GRPW_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \
-                          SYSDB_LAST_UPDATE, \
+                          SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
                           "objectClass", \
                           NULL}
 #define SYSDB_GRENT_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, SYSDB_MEMBEROF, \
-                           SYSDB_LAST_UPDATE, \
+                           SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
                            "objectClass", \
                            NULL}
 
 #define SYSDB_INITGR_ATTR SYSDB_MEMBEROF
-#define SYSDB_INITGR_ATTRS {SYSDB_GIDNUM, SYSDB_LAST_UPDATE, \
+#define SYSDB_INITGR_ATTRS {SYSDB_GIDNUM, \
+                            SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
                             "objectClass", \
                             NULL}
 
@@ -479,7 +481,8 @@ struct tevent_req *sysdb_store_user_send(TALLOC_CTX *mem_ctx,
                                          const char *gecos,
                                          const char *homedir,
                                          const char *shell,
-                                         struct sysdb_attrs *attrs);
+                                         struct sysdb_attrs *attrs,
+                                         uint64_t cache_timeout);
 int sysdb_store_user_recv(struct tevent_req *req);
 
 struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
@@ -490,7 +493,8 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
                                           gid_t gid,
                                           const char **member_users,
                                           const char **member_groups,
-                                          struct sysdb_attrs *attrs);
+                                          struct sysdb_attrs *attrs,
+                                          uint64_t cache_timeout);
 int sysdb_store_group_recv(struct tevent_req *req);
 
 struct tevent_req *sysdb_add_group_member_send(TALLOC_CTX *mem_ctx,
diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c
index e045ad7..0bb77d1 100644
--- a/server/db/sysdb_ops.c
+++ b/server/db/sysdb_ops.c
@@ -2548,6 +2548,8 @@ struct sysdb_store_user_state {
     const char *homedir;
     const char *shell;
     struct sysdb_attrs *attrs;
+
+    uint64_t cache_timeout;
 };
 
 static void sysdb_store_user_check(struct tevent_req *subreq);
@@ -2564,7 +2566,8 @@ struct tevent_req *sysdb_store_user_send(TALLOC_CTX *mem_ctx,
                                          const char *gecos,
                                          const char *homedir,
                                          const char *shell,
-                                         struct sysdb_attrs *attrs)
+                                         struct sysdb_attrs *attrs,
+                                         uint64_t cache_timeout)
 {
     struct tevent_req *req, *subreq;
     struct sysdb_store_user_state *state;
@@ -2583,6 +2586,7 @@ struct tevent_req *sysdb_store_user_send(TALLOC_CTX *mem_ctx,
     state->homedir = homedir;
     state->shell = shell;
     state->attrs = attrs;
+    state->cache_timeout = cache_timeout;
 
     if (pwd && (domain->legacy_passwords || !*pwd)) {
         ret = sysdb_attrs_add_string(state->attrs, SYSDB_PWD, pwd);
@@ -2612,6 +2616,7 @@ static void sysdb_store_user_check(struct tevent_req *subreq)
     struct sysdb_store_user_state *state = tevent_req_data(req,
                                                struct sysdb_store_user_state);
     struct ldb_message *msg;
+    time_t now = time(NULL);
     int ret;
 
     ret = sysdb_search_user_recv(subreq, state, &msg);
@@ -2702,7 +2707,15 @@ static void sysdb_store_user_check(struct tevent_req *subreq)
         }
     }
 
-    ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_LAST_UPDATE, time(NULL));
+    ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_LAST_UPDATE, now);
+    if (ret) {
+        DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
+        tevent_req_error(req, ret);
+        return;
+    }
+
+    ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_CACHE_EXPIRE,
+                                               now + state->cache_timeout);
     if (ret) {
         DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
         tevent_req_error(req, ret);
@@ -2775,6 +2788,8 @@ struct sysdb_store_group_state {
     const char **member_groups;
 
     struct sysdb_attrs *attrs;
+
+    uint64_t cache_timeout;
 };
 
 static void sysdb_store_group_check(struct tevent_req *subreq);
@@ -2789,7 +2804,8 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
                                           gid_t gid,
                                           const char **member_users,
                                           const char **member_groups,
-                                          struct sysdb_attrs *attrs)
+                                          struct sysdb_attrs *attrs,
+                                          uint64_t cache_timeout)
 {
     struct tevent_req *req, *subreq;
     struct sysdb_store_group_state *state;
@@ -2808,6 +2824,7 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
     state->member_users = member_users;
     state->member_groups = member_groups;
     state->attrs = attrs;
+    state->cache_timeout = cache_timeout;
 
     subreq = sysdb_search_group_by_name_send(state, ev, NULL, handle,
                                              domain, name, src_attrs);
@@ -2832,6 +2849,7 @@ static void sysdb_store_group_check(struct tevent_req *subreq)
     struct sysdb_store_group_state *state = tevent_req_data(req,
                                                struct sysdb_store_group_state);
     struct ldb_message *msg;
+    time_t now = time(NULL);
     bool new_group = false;
     int ret, i;
 
@@ -2906,7 +2924,7 @@ static void sysdb_store_group_check(struct tevent_req *subreq)
     }
 
     if (new_group) {
-        /* groups doesn't exist, turn into adding a group */
+        /* group doesn't exist, turn into adding a group */
         subreq = sysdb_add_group_send(state, state->ev, state->handle,
                                       state->domain, state->name,
                                       state->gid, state->attrs);
@@ -2940,7 +2958,15 @@ static void sysdb_store_group_check(struct tevent_req *subreq)
         }
     }
 
-    ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_LAST_UPDATE, time(NULL));
+    ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_LAST_UPDATE, now);
+    if (ret) {
+        DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
+        tevent_req_error(req, ret);
+        return;
+    }
+
+    ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_CACHE_EXPIRE,
+                                               now + state->cache_timeout);
     if (ret) {
         DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
         tevent_req_error(req, ret);
diff --git a/server/man/sssd.conf.5.xml b/server/man/sssd.conf.5.xml
index f735b07..1e65b60 100644
--- a/server/man/sssd.conf.5.xml
+++ b/server/man/sssd.conf.5.xml
@@ -262,19 +262,6 @@
                     </listitem>
                 </varlistentry>
                 <varlistentry>
-                    <term>entry_cache_timeout (integer)</term>
-                    <listitem>
-                        <para>
-                            How long should nss_sss cache positive cache hits
-                            (that is, queries for valid database entries) before
-                            asking the backend again
-                        </para>
-                        <para>
-                            Default: 600
-                        </para>
-                    </listitem>
-                </varlistentry>
-                <varlistentry>
                     <term>entry_cache_nowait_timeout (integer)</term>
                     <listitem>
                         <para>
@@ -404,6 +391,18 @@
                 </varlistentry>
 
                 <varlistentry>
+                    <term>entry_cache_timeout (integer)</term>
+                    <listitem>
+                        <para>
+                            How long should nss_sss consider entries valid
+                            before asking the backend again
+                        </para>
+                        <para>
+                            Default: 600
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
                     <term>cache_credentials (bool)</term>
                     <listitem>
                         <para>
diff --git a/server/providers/ipa/ipa_common.c b/server/providers/ipa/ipa_common.c
index e87373f..83f3f67 100644
--- a/server/providers/ipa/ipa_common.c
+++ b/server/providers/ipa/ipa_common.c
@@ -34,7 +34,7 @@ struct dp_option ipa_basic_opts[] = {
     { "ipa_opt_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER },
     { "ipa_offline_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER },
     { "ipa_enumeration_refresh_timeout", DP_OPT_NUMBER, { .number = 300 }, NULL_NUMBER },
-    { "ipa_stale_time", DP_OPT_NUMBER, { .number = 1800 }, NULL_NUMBER },
+    { "entry_cache_timeout", DP_OPT_NUMBER, { .number = 1800 }, NULL_NUMBER },
 };
 
 struct dp_option ipa_def_ldap_opts[] = {
@@ -56,7 +56,7 @@ struct dp_option ipa_def_ldap_opts[] = {
     { "ldap_offline_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER },
     { "ldap_force_upper_case_realm", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
     { "ldap_enumeration_refresh_timeout", DP_OPT_NUMBER, { .number = 300 }, NULL_NUMBER },
-    { "ldap_stale_time", DP_OPT_NUMBER, { .number = 1800 }, NULL_NUMBER },
+    { "entry_cache_timeout", DP_OPT_NUMBER, { .number = 1800 }, NULL_NUMBER },
     { "ldap_tls_cacert", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_tls_cacertdir", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_id_use_start_tls", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
@@ -322,9 +322,9 @@ int ipa_get_id_options(TALLOC_CTX *memctx,
                          dp_opt_get_int(ipa_opts->basic,
                                         IPA_ENUM_REFRESH_TIMEOUT));
     ret = dp_opt_set_int(ipa_opts->id->basic,
-                         SDAP_STALE_TIME,
+                         SDAP_ENTRY_CACHE_TIMEOUT,
                          dp_opt_get_int(ipa_opts->basic,
-                                        IPA_STALE_TIME));
+                                        IPA_ENTRY_CACHE_TIMEOUT));
 
     ret = sdap_get_map(ipa_opts->id,
                        cdb, conf_path,
diff --git a/server/providers/ipa/ipa_common.h b/server/providers/ipa/ipa_common.h
index f7d3ab8..83ce488 100644
--- a/server/providers/ipa/ipa_common.h
+++ b/server/providers/ipa/ipa_common.h
@@ -36,7 +36,7 @@ enum ipa_basic_opt {
     IPA_OPT_TIMEOUT,
     IPA_OFFLINE_TIMEOUT,
     IPA_ENUM_REFRESH_TIMEOUT,
-    IPA_STALE_TIME,
+    IPA_ENTRY_CACHE_TIMEOUT,
 
     IPA_OPTS_BASIC /* opts counter */
 };
diff --git a/server/providers/ldap/ldap_common.c b/server/providers/ldap/ldap_common.c
index bb836c1..beb48a4 100644
--- a/server/providers/ldap/ldap_common.c
+++ b/server/providers/ldap/ldap_common.c
@@ -43,7 +43,7 @@ struct dp_option default_basic_opts[] = {
     { "ldap_offline_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER },
     { "ldap_force_upper_case_realm", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
     { "ldap_enumeration_refresh_timeout", DP_OPT_NUMBER, { .number = 300 }, NULL_NUMBER },
-    { "ldap_stale_time", DP_OPT_NUMBER, { .number = 1800 }, NULL_NUMBER },
+    { "entry_cache_timoeut", DP_OPT_NUMBER, { .number = 1800 }, NULL_NUMBER },
     { "ldap_tls_cacert", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_tls_cacertdir", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_id_use_start_tls", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
diff --git a/server/providers/ldap/sdap.h b/server/providers/ldap/sdap.h
index 3768015..8ae9d03 100644
--- a/server/providers/ldap/sdap.h
+++ b/server/providers/ldap/sdap.h
@@ -106,7 +106,7 @@ enum sdap_basic_opt {
     SDAP_OFFLINE_TIMEOUT,
     SDAP_FORCE_UPPER_CASE_REALM,
     SDAP_ENUM_REFRESH_TIMEOUT,
-    SDAP_STALE_TIME,
+    SDAP_ENTRY_CACHE_TIMEOUT,
     SDAP_TLS_CACERT,
     SDAP_TLS_CACERTDIR,
     SDAP_ID_TLS,
diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
index 140f3fa..28e4fa4 100644
--- a/server/providers/ldap/sdap_async.c
+++ b/server/providers/ldap/sdap_async.c
@@ -1509,7 +1509,9 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
     subreq = sysdb_store_user_send(state, state->ev, state->handle,
                                    state->dom, state->name, pwd,
                                    uid, gid, gecos, homedir, shell,
-                                   user_attrs);
+                                   user_attrs,
+                                   dp_opt_get_int(opts->basic,
+                                                  SDAP_ENTRY_CACHE_TIMEOUT));
     if (!subreq) {
         ret = ENOMEM;
         goto fail;
@@ -1933,7 +1935,9 @@ static struct tevent_req *sdap_set_grpmem_send(TALLOC_CTX *memctx,
 
     subreq = sysdb_store_group_send(memctx, ev, handle, dom,
                                     gm->name, 0,
-                                    member_users, member_groups, NULL);
+                                    member_users, member_groups, NULL,
+                                    dp_opt_get_int(opts->basic,
+                                                   SDAP_ENTRY_CACHE_TIMEOUT));
 
     /* steal members on subreq,
      * so they are freed when the request is finished */
@@ -2132,7 +2136,9 @@ static struct tevent_req *sdap_save_group_send(TALLOC_CTX *memctx,
                                     state->handle, state->dom,
                                     state->name, gid,
                                     member_users, member_groups,
-                                    group_attrs);
+                                    group_attrs,
+                                    dp_opt_get_int(opts->basic,
+                                                   SDAP_ENTRY_CACHE_TIMEOUT));
     if (!subreq) {
         ret = ENOMEM;
         goto fail;
diff --git a/server/providers/proxy.c b/server/providers/proxy.c
index e3b31c3..bce6a75 100644
--- a/server/providers/proxy.c
+++ b/server/providers/proxy.c
@@ -58,6 +58,7 @@ struct proxy_nss_ops {
 
 struct proxy_ctx {
     struct be_ctx *be;
+    int entry_cache_timeout;
     struct proxy_nss_ops ops;
 };
 
@@ -415,7 +416,8 @@ static void get_pw_name_process(struct tevent_req *subreq)
                                        state->pwd->pw_gid,
                                        state->pwd->pw_gecos,
                                        state->pwd->pw_dir,
-                                       state->pwd->pw_shell, NULL);
+                                       state->pwd->pw_shell,
+                                       NULL, ctx->entry_cache_timeout);
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
             return;
@@ -607,7 +609,8 @@ static void get_pw_uid_process(struct tevent_req *subreq)
                                        state->pwd->pw_gid,
                                        state->pwd->pw_gecos,
                                        state->pwd->pw_dir,
-                                       state->pwd->pw_shell, NULL);
+                                       state->pwd->pw_shell,
+                                       NULL, ctx->entry_cache_timeout);
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
             return;
@@ -829,7 +832,8 @@ again:
                                        state->pwd->pw_gid,
                                        state->pwd->pw_gecos,
                                        state->pwd->pw_dir,
-                                       state->pwd->pw_shell, NULL);
+                                       state->pwd->pw_shell,
+                                       NULL, ctx->entry_cache_timeout);
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
             return;
@@ -1000,7 +1004,8 @@ again:
                                         state->domain,
                                         state->grp->gr_name,
                                         state->grp->gr_gid,
-                                        members, NULL, NULL);
+                                        members, NULL, NULL,
+                                        ctx->entry_cache_timeout);
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
             return;
@@ -1214,7 +1219,8 @@ again:
                                         state->domain,
                                         state->grp->gr_name,
                                         state->grp->gr_gid,
-                                        members, NULL, NULL);
+                                        members, NULL, NULL,
+                                        ctx->entry_cache_timeout);
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
             return;
@@ -1442,7 +1448,8 @@ again:
                                        state->domain,
                                        state->grp->gr_name,
                                        state->grp->gr_gid,
-                                       members, NULL, NULL);
+                                       members, NULL, NULL,
+                                       ctx->entry_cache_timeout);
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
             return;
@@ -1582,7 +1589,8 @@ static void get_initgr_process(struct tevent_req *subreq)
                                        state->pwd->pw_gid,
                                        state->pwd->pw_gecos,
                                        state->pwd->pw_dir,
-                                       state->pwd->pw_shell, NULL);
+                                       state->pwd->pw_shell,
+                                       NULL, ctx->entry_cache_timeout);
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
             return;
@@ -1893,7 +1901,8 @@ again:
                                         state->grp->gr_name,
                                         state->grp->gr_gid,
                                         (const char **)state->grp->gr_mem,
-                                        NULL, NULL);
+                                        NULL, NULL,
+                                        ctx->entry_cache_timeout);
         if (!subreq) {
             ret = ENOMEM;
             goto fail;
@@ -2233,6 +2242,11 @@ int sssm_proxy_init(struct be_ctx *bectx,
     }
     ctx->be = bectx;
 
+    ret = confdb_get_int(bectx->cdb, ctx, bectx->conf_path,
+                         CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT, 600,
+                         &ctx->entry_cache_timeout);
+    if (ret != EOK) goto done;
+
     ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
                             CONFDB_PROXY_LIBNAME, NULL, &libname);
     if (ret != EOK) goto done;
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c
index 9e93c06..272cd38 100644
--- a/server/responder/nss/nsssrv.c
+++ b/server/responder/nss/nsssrv.c
@@ -92,11 +92,6 @@ static int nss_get_config(struct nss_ctx *nctx,
     if (ret != EOK) goto done;
 
     ret = confdb_get_int(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
-                         CONFDB_NSS_ENTRY_CACHE_TIMEOUT, 600,
-                         &nctx->cache_timeout);
-    if (ret != EOK) goto done;
-
-    ret = confdb_get_int(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
                          CONFDB_NSS_ENTRY_NEG_TIMEOUT, 15,
                          &nctx->neg_timeout);
     if (ret != EOK) goto done;
@@ -111,11 +106,6 @@ static int nss_get_config(struct nss_ctx *nctx,
                          CONFDB_NSS_ENTRY_CACHE_NOWAIT_TIMEOUT, 0,
                          &nctx->cache_refresh_timeout);
     if (ret != EOK) goto done;
-    if (nctx->cache_refresh_timeout >= nctx->cache_timeout) {
-        DEBUG(0,("Configuration error: EntryCacheNoWaitRefreshTimeout exceeds"
-                 "EntryCacheTimeout. Disabling feature.\n"));
-        nctx->cache_refresh_timeout = 0;
-    }
     if (nctx->cache_refresh_timeout < 0) {
         DEBUG(0,("Configuration error: EntryCacheNoWaitRefreshTimeout is"
                  "invalid. Disabling feature.\n"));
diff --git a/server/responder/nss/nsssrv.h b/server/responder/nss/nsssrv.h
index 14d2aad..0c2ea48 100644
--- a/server/responder/nss/nsssrv.h
+++ b/server/responder/nss/nsssrv.h
@@ -47,7 +47,6 @@ struct nss_ctx {
     int neg_timeout;
     struct nss_nc_ctx *ncache;
 
-    int cache_timeout;
     int cache_refresh_timeout;
 
     int enum_cache_timeout;
diff --git a/server/responder/nss/nsssrv_cmd.c b/server/responder/nss/nsssrv_cmd.c
index ebfd1d5..3d4226f 100644
--- a/server/responder/nss/nsssrv_cmd.c
+++ b/server/responder/nss/nsssrv_cmd.c
@@ -281,6 +281,7 @@ static errno_t check_cache(struct nss_dom_ctx *dctx,
     int refresh_timeout;
     time_t now;
     uint64_t lastUpdate;
+    uint64_t cacheExpire;
     struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
     struct cli_ctx *cctx = cmdctx->cctx;
     bool call_provider = false;
@@ -297,13 +298,14 @@ static errno_t check_cache(struct nss_dom_ctx *dctx,
         } else if ((req_type == SSS_DP_GROUP) ||
                    ((req_type == SSS_DP_USER) && (res->count == 1))) {
 
-            timeout = nctx->cache_timeout;
             refresh_timeout = nctx->cache_refresh_timeout;
             now = time(NULL);
 
             lastUpdate = ldb_msg_find_attr_as_uint64(res->msgs[0],
                                                      SYSDB_LAST_UPDATE, 0);
-            if (lastUpdate + timeout < now) {
+            cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+                                                      SYSDB_CACHE_EXPIRE, 0);
+            if (cacheExpire < now) {
                 /* This is a cache miss. We need to get the updated user
                  * information before returning it.
                  */
@@ -2906,7 +2908,7 @@ static void nss_cmd_getinit_callback(void *ptr, int status,
     struct sysdb_ctx *sysdb;
     struct nss_ctx *nctx;
     int timeout;
-    uint64_t lastUpdate;
+    uint64_t cacheExpire;
     uint8_t *body;
     size_t blen;
     bool call_provider = false;
@@ -2932,11 +2934,9 @@ static void nss_cmd_getinit_callback(void *ptr, int status,
             break;
 
         case 1:
-            timeout = nctx->cache_timeout;
-
-            lastUpdate = ldb_msg_find_attr_as_uint64(res->msgs[0],
-                                                     SYSDB_LAST_UPDATE, 0);
-            if (lastUpdate + timeout < time(NULL)) {
+            cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+                                                      SYSDB_CACHE_EXPIRE, 0);
+            if (cacheExpire < time(NULL)) {
                 call_provider = true;
             }
             break;
diff --git a/server/responder/pam/pamsrv_cmd.c b/server/responder/pam/pamsrv_cmd.c
index dfe67cd..df4728b 100644
--- a/server/responder/pam/pamsrv_cmd.c
+++ b/server/responder/pam/pamsrv_cmd.c
@@ -798,10 +798,9 @@ static void pam_check_user_callback(void *ptr, int status,
     struct pam_auth_req *preq = talloc_get_type(ptr, struct pam_auth_req);
     struct sss_domain_info *dom;
     struct sysdb_ctx *sysdb;
-    uint64_t lastUpdate;
+    uint64_t cacheExpire;
     bool call_provider = false;
     time_t timeout;
-    time_t cache_timeout;
     int ret;
 
     if (status != LDB_SUCCESS) {
@@ -819,11 +818,9 @@ static void pam_check_user_callback(void *ptr, int status,
             break;
 
         case 1:
-            cache_timeout = 30; /* FIXME: read from conf */
-
-            lastUpdate = ldb_msg_find_attr_as_uint64(res->msgs[0],
-                                                     SYSDB_LAST_UPDATE, 0);
-            if (lastUpdate + cache_timeout < time(NULL)) {
+            cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+                                                      SYSDB_CACHE_EXPIRE, 0);
+            if (cacheExpire < time(NULL)) {
                 call_provider = true;
             }
             break;
diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c
index ce69aa0..0df9831 100644
--- a/server/tests/sysdb-tests.c
+++ b/server/tests/sysdb-tests.c
@@ -267,7 +267,7 @@ static void test_store_user(struct tevent_req *req)
                                   data->uid, 0,
                                   gecos, homedir,
                                   data->shell ? data->shell : "/bin/bash",
-                                  NULL);
+                                  NULL, -1);
     if (!subreq) {
         test_return(data, ENOMEM);
         return;
@@ -472,7 +472,7 @@ static void test_store_group(struct tevent_req *req)
 
     subreq = sysdb_store_group_send(data, data->ev, data->handle,
                                     data->ctx->domain, data->groupname,
-                                    data->gid, NULL, NULL, NULL);
+                                    data->gid, NULL, NULL, NULL, -1);
     if (!subreq) {
         test_return(data, ret);
     }
-- 
1.6.2.5

