From 7c37a5dd8987597ecb3cd6c09a6b691db5fd4c72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Mon, 13 May 2013 10:30:48 +0200
Subject: [PATCH 3/4] back end: add refresh expired records periodic task

https://fedorahosted.org/sssd/ticket/1713

Add new option refresh_expired_interval.
---
 Makefile.am                          |  2 ++
 src/confdb/confdb.c                  | 11 +++++++++++
 src/confdb/confdb.h                  |  3 +++
 src/config/SSSDConfig/__init__.py.in |  1 +
 src/config/SSSDConfigTest.py         |  2 ++
 src/config/etc/sssd.api.conf         |  1 +
 src/man/sssd.conf.5.xml              | 18 ++++++++++++++++++
 src/providers/data_provider_be.c     | 23 +++++++++++++++++++++++
 src/providers/dp_backend.h           |  3 +++
 src/providers/dp_ptask.h             |  3 +++
 src/providers/dp_refresh.h           |  3 +++
 11 files changed, 70 insertions(+)

diff --git a/Makefile.am b/Makefile.am
index e5aadd6f0eeb51d09e5b092cb3c737824ae0cd6d..65a9216aba9760bb79b0e91394d0bac042a41018 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1081,6 +1081,8 @@ simple_access_tests_SOURCES = \
     src/providers/data_provider_fo.c \
     src/providers/data_provider_opts.c \
     src/providers/data_provider_callbacks.c \
+    src/providers/dp_ptask.c \
+    src/providers/dp_refresh.c \
     $(SSSD_FAILOVER_OBJ)
 simple_access_tests_CFLAGS = \
     $(AM_CFLAGS) \
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index e1888678eaf45446a89c4a290d55356deae0afdf..693118e79ae0e0b1a828c748b88e242b4fd02547 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1020,6 +1020,17 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
         goto done;
     }
 
+    /* Set refresh_expired_interval, if specified */
+    ret = get_entry_as_uint32(res->msgs[0], &domain->refresh_expired_interval,
+                              CONFDB_DOMAIN_REFRESH_EXPIRED_INTERVAL,
+                              0);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              ("Invalid value for [%s]\n",
+               CONFDB_DOMAIN_REFRESH_EXPIRED_INTERVAL));
+        goto done;
+    }
+
     /* Set the PAM warning time, if specified. If not specified, pass on
      * the "not set" value of "-1" which means "use provider default". The
      * value 0 means "always display the warning if server sends one" */
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 1d9647394ce59f12f59d55f22c6d42e669c39a11..e1111025703260d2583cfdde6128993db574a60f 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -167,6 +167,7 @@
 #define CONFDB_DOMAIN_AUTOFS_CACHE_TIMEOUT "entry_cache_autofs_timeout"
 #define CONFDB_DOMAIN_SUDO_CACHE_TIMEOUT "entry_cache_sudo_timeout"
 #define CONFDB_DOMAIN_PWD_EXPIRATION_WARNING "pwd_expiration_warning"
+#define CONFDB_DOMAIN_REFRESH_EXPIRED_INTERVAL "refresh_expired_interval"
 
 /* Local Provider */
 #define CONFDB_LOCAL_DEFAULT_SHELL   "default_shell"
@@ -220,6 +221,8 @@ struct sss_domain_info {
     uint32_t autofsmap_timeout;
     uint32_t sudo_timeout;
 
+    uint32_t refresh_expired_interval;
+
     int pwd_expiration_warning;
 
     struct sysdb_ctx *sysdb;
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 8e1142f2a8ca7388cf4f867962217478700050da..b6e722fc2f1b8cabf4671253a3c9d4a20edb9b1e 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -125,6 +125,7 @@ option_strings = {
     'entry_cache_service_timeout' : _('Entry cache timeout length (seconds)'),
     'entry_cache_autofs_timeout' : _('Entry cache timeout length (seconds)'),
     'entry_cache_sudo_timeout' : _('Entry cache timeout length (seconds)'),
+    'refresh_expired_interval' : _('How often should expired entries be refreshed in background'),
     'dyndns_update' : _("Whether to automatically update the client's DNS entry"),
     'dyndns_ttl' : _("The TTL to apply to the client's DNS entry after updating it"),
     'dyndns_iface' : _("The interface whose IP should be used for dynamic DNS updates"),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index f44f903e9f694a6593ac231d990bc3d750ab4872..f44fac7270a8a9bbb8dbf855dc3365ad21d96912 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -504,6 +504,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
             'entry_cache_service_timeout',
             'entry_cache_autofs_timeout',
             'entry_cache_sudo_timeout',
+            'refresh_expired_interval',
             'lookup_family_order',
             'account_cache_expiration',
             'dns_resolver_timeout',
@@ -855,6 +856,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
             'entry_cache_service_timeout',
             'entry_cache_autofs_timeout',
             'entry_cache_sudo_timeout',
+            'refresh_expired_interval',
             'account_cache_expiration',
             'lookup_family_order',
             'dns_resolver_timeout',
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index 0c21bf99b2a99d7523cd545a3e2c714f26481af8..5c095c188aca1a0a358848b350b3fc32e5a36a1e 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -123,6 +123,7 @@ entry_cache_netgroup_timeout = int, None, false
 entry_cache_service_timeout = int, None, false
 entry_cache_autofs_timeout = int, None, false
 entry_cache_sudo_timeout = int, None, false
+refresh_expired_interval = int, None, false
 
 # Dynamic DNS updates
 dyndns_update = bool, None, false
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index c2e475b5a37153262b40066cc1df53a567204a3b..d3e393c83e3ba130bab35a4d2153560710e16ba6 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1078,6 +1078,24 @@ override_homedir = /home/%u
                 </varlistentry>
 
                 <varlistentry>
+                    <term>refresh_expired_interval (integer)</term>
+                    <listitem>
+                        <para>
+                            Specifies how many seconds SSSD has to wait
+                            before refreshing expired records. Currently
+                            only refreshing expired netgroups is supported.
+                        </para>
+                        <para>
+                            You can consider setting this value to
+                            3/4 * entry_cache_timeout.
+                        </para>
+                        <para>
+                            Default: 0 (disabled)
+                        </para>
+                    </listitem>
+                </varlistentry>
+
+                <varlistentry>
                     <term>cache_credentials (bool)</term>
                     <listitem>
                         <para>
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index f3b50af7e14ac2adc4dd2b061bdc960a709d5a65..1e11bfd24083abeb067ccfda27cf1d10f2669041 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -42,6 +42,8 @@
 #include "sbus/sssd_dbus.h"
 #include "providers/dp_backend.h"
 #include "providers/fail_over.h"
+#include "providers/dp_refresh.h"
+#include "providers/dp_ptask.h"
 #include "util/child_common.h"
 #include "resolv/async_resolv.h"
 #include "monitor/monitor_interfaces.h"
@@ -2657,6 +2659,27 @@ int be_process_init(TALLOC_CTX *mem_ctx,
         goto fail;
     }
 
+    /* Initialize be_refresh periodic task. */
+    ctx->refresh_ctx = be_refresh_ctx_init(ctx);
+    if (ctx->refresh_ctx == NULL) {
+        DEBUG(SSSDBG_FATAL_FAILURE, ("Unable to initialize refresh_ctx\n"));
+        ret = ENOMEM;
+        goto fail;
+    }
+
+    if (ctx->domain->refresh_expired_interval > 0) {
+        ret = be_ptask_create(ctx, ctx, ctx->domain->refresh_expired_interval,
+                              30, 5, ctx->domain->refresh_expired_interval,
+                              BE_PTASK_OFFLINE_SKIP,
+                              be_refresh_send, be_refresh_recv,
+                              ctx->refresh_ctx, "Refresh Records", NULL);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_FATAL_FAILURE,
+                  ("Unable to initialize refresh periodic task\n"));
+            goto fail;
+        }
+    }
+
     ret = load_backend_module(ctx, BET_ID,
                               &ctx->bet_info[BET_ID], NULL);
     if (ret != EOK) {
diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
index 9a8df4cd8ece1a2bb1a7265fb141b65d6f99a3a6..638b878c298ee5cf540dbb09ca7c69304822f088 100644
--- a/src/providers/dp_backend.h
+++ b/src/providers/dp_backend.h
@@ -24,6 +24,7 @@
 
 #include "providers/data_provider.h"
 #include "providers/fail_over.h"
+#include "providers/dp_refresh.h"
 #include "util/child_common.h"
 #include "db/sysdb.h"
 
@@ -141,6 +142,8 @@ struct be_ctx {
     struct loaded_be loaded_be[BET_MAX];
     struct bet_info bet_info[BET_MAX];
 
+    struct be_refresh_ctx *refresh_ctx;
+
     size_t check_online_ref_count;
 };
 
diff --git a/src/providers/dp_ptask.h b/src/providers/dp_ptask.h
index 5a1d62c8321b64d3ab0caaa346318d60ebd41c56..ae5f78d586df69bdcfa34bb35f032ad1dbd1b983 100644
--- a/src/providers/dp_ptask.h
+++ b/src/providers/dp_ptask.h
@@ -27,6 +27,9 @@
 
 #include "providers/dp_backend.h"
 
+/* solve circular dependency */
+struct be_ctx;
+
 struct be_ptask;
 
 /**
diff --git a/src/providers/dp_refresh.h b/src/providers/dp_refresh.h
index cae2f7876bbd6a98b8c4710c41687fce617396f2..a7b324702b0546d8156e8fa395b39fa58b52812d 100644
--- a/src/providers/dp_refresh.h
+++ b/src/providers/dp_refresh.h
@@ -27,6 +27,9 @@
 #include "providers/dp_backend.h"
 #include "providers/dp_ptask.h"
 
+/* solve circular dependency */
+struct be_ctx;
+
 /**
  * name_list contains SYSDB_NAME of all expired records.
  */
-- 
1.7.11.7

