From a13c3b1c3ddce35a681c568a84484627d513b303 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 4cbd4a0b9a669411440b24f90d7daacec74d6386..539eae6677f7204850bf5c8a25b6c2fc2d6a22ed 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1017,6 +1017,8 @@ simple_access_tests_SOURCES = \
     src/providers/data_provider_be.c \
     src/providers/data_provider_fo.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 2a12f805582de7ff0edf5f32221061487994f520..72c74fee02c7f38737a852b2b12c1154a0b19231 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1017,6 +1017,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 eb16d01e0289dfe29dfa8ad42a59cc78fabcf71b..775959815cff7a3d038ece31b4f5e8ad23865ce7 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -171,6 +171,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"
@@ -223,6 +224,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 9235ebd55ba338a853a7d6ea519e427be66a8848..c5e768f71d07a05847d03af88cce008d70e0ebdf 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'),
 
     # [provider/ipa]
     'ipa_domain' : _('IPA domain'),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 4f85629fa7b18d4d98de15470056bc5a34442b80..a156a0b85d34cc6671feabbbfbb360da68dd0109 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -503,6 +503,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',
@@ -844,6 +845,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 3ed9d583ccbfd8f148d5a2c79f9c658d8fd7d8f1..2b86e76b78293bc1a1ef799c98e8ba863881bf5b 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -120,6 +120,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
 
 # Special providers
 [provider/permit]
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index a7e9f2b4ea81fd667da119ede9ae2beb814d08ac..27d52032724f42582334d3291bb6727c96634331 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1100,6 +1100,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 33590aeef0231427642916c6a2f9bc391c165c21..3354695cfd2656bd7bd3c0ecf93fd348f27e46cf 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"
@@ -2494,6 +2496,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 743b6f4ffe73fe9ec7404218184a7133aba054c6..a2af785ca4adc0762a7b4a7cb072f31219e09e01 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"
 
@@ -123,6 +124,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 52d26701f262e60c0bd128d1d86dff382aaf3cb3..7e45862e46c5d9da4eaedca5312e25dcc0eb8abe 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 affe14b84a127cfeb03b0141390203a45d357942..0dedbc3c14bfb661ebf296a9021fa397769dee66 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

