Blame SOURCES/0039-IPA-Implement-background-refresh-for-IPA-domains.patch

d6181b
From 3847082fe85520ab86cefcf78d9ffe6c6df0a04f Mon Sep 17 00:00:00 2001
d6181b
From: Jakub Hrozek <jhrozek@redhat.com>
d6181b
Date: Wed, 8 May 2019 14:39:23 +0200
d6181b
Subject: [PATCH 39/48] IPA: Implement background refresh for IPA domains
d6181b
d6181b
Split out the actual useful functionality from the IPA account lookup
d6181b
handler into a tevent request. This tevent request is then used in a new
d6181b
ipa_refresh module.
d6181b
d6181b
Related:
d6181b
https://pagure.io/SSSD/sssd/issue/4012
d6181b
d6181b
Reviewed-by: Sumit Bose <sbose@redhat.com>
d6181b
---
d6181b
 Makefile.am                     |   1 +
d6181b
 src/providers/ipa/ipa_common.h  |   3 +
d6181b
 src/providers/ipa/ipa_id.c      | 140 +++++++++++++----
d6181b
 src/providers/ipa/ipa_id.h      |   8 +
d6181b
 src/providers/ipa/ipa_init.c    |   2 +-
d6181b
 src/providers/ipa/ipa_refresh.c | 264 ++++++++++++++++++++++++++++++++
d6181b
 6 files changed, 386 insertions(+), 32 deletions(-)
d6181b
 create mode 100644 src/providers/ipa/ipa_refresh.c
d6181b
d6181b
diff --git a/Makefile.am b/Makefile.am
d6181b
index f9f17904e..cbd6bbfdb 100644
d6181b
--- a/Makefile.am
d6181b
+++ b/Makefile.am
d6181b
@@ -4430,6 +4430,7 @@ libsss_ipa_la_SOURCES = \
d6181b
     src/providers/ipa/ipa_srv.c \
d6181b
     src/providers/ipa/ipa_idmap.c \
d6181b
     src/providers/ipa/ipa_dn.c \
d6181b
+    src/providers/ipa/ipa_refresh.c \
d6181b
     src/providers/ad/ad_opts.c \
d6181b
     src/providers/ad/ad_common.c \
d6181b
     src/providers/ad/ad_dyndns.c \
d6181b
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
d6181b
index 31e671eb5..6bb1739ef 100644
d6181b
--- a/src/providers/ipa/ipa_common.h
d6181b
+++ b/src/providers/ipa/ipa_common.h
d6181b
@@ -301,4 +301,7 @@ errno_t ipa_get_host_attrs(struct dp_option *ipa_options,
d6181b
                            struct sysdb_attrs **hosts,
d6181b
                            struct sysdb_attrs **_ipa_host);
d6181b
 
d6181b
+errno_t ipa_refresh_init(struct be_ctx *be_ctx,
d6181b
+                         struct ipa_id_ctx *id_ctx);
d6181b
+
d6181b
 #endif /* _IPA_COMMON_H_ */
d6181b
diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c
d6181b
index e644af5ff..9abee34cb 100644
d6181b
--- a/src/providers/ipa/ipa_id.c
d6181b
+++ b/src/providers/ipa/ipa_id.c
d6181b
@@ -1344,43 +1344,39 @@ ipa_decide_account_info_type(struct dp_id_data *data, struct be_ctx *be_ctx)
d6181b
     return IPA_ACCOUNT_INFO_OTHER;
d6181b
 }
d6181b
 
d6181b
-struct ipa_account_info_handler_state {
d6181b
+struct ipa_account_info_state {
d6181b
     enum ipa_account_info_type type;
d6181b
-    struct dp_reply_std reply;
d6181b
+
d6181b
+    const char *err_msg;
d6181b
+    int dp_error;
d6181b
 };
d6181b
 
d6181b
-static void ipa_account_info_handler_done(struct tevent_req *subreq);
d6181b
+static void ipa_account_info_done(struct tevent_req *subreq);
d6181b
 
d6181b
 struct tevent_req *
d6181b
-ipa_account_info_handler_send(TALLOC_CTX *mem_ctx,
d6181b
-                              struct ipa_id_ctx *id_ctx,
d6181b
-                              struct dp_id_data *data,
d6181b
-                              struct dp_req_params *params)
d6181b
+ipa_account_info_send(TALLOC_CTX *mem_ctx,
d6181b
+                      struct be_ctx *be_ctx,
d6181b
+                      struct ipa_id_ctx *id_ctx,
d6181b
+                      struct dp_id_data *data)
d6181b
 {
d6181b
-    struct ipa_account_info_handler_state *state;
d6181b
+    struct ipa_account_info_state *state = NULL;
d6181b
+    struct tevent_req *req = NULL;
d6181b
     struct tevent_req *subreq = NULL;
d6181b
-    struct tevent_req *req;
d6181b
     errno_t ret;
d6181b
 
d6181b
     req = tevent_req_create(mem_ctx, &state,
d6181b
-                            struct ipa_account_info_handler_state);
d6181b
+                            struct ipa_account_info_state);
d6181b
     if (req == NULL) {
d6181b
         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
d6181b
         return NULL;
d6181b
     }
d6181b
 
d6181b
-    state->type = ipa_decide_account_info_type(data, params->be_ctx);
d6181b
-
d6181b
-    if (sdap_is_enum_request(data)) {
d6181b
-        DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n");
d6181b
-        ret = EOK;
d6181b
-        goto immediately;
d6181b
-    }
d6181b
+    state->type = ipa_decide_account_info_type(data, be_ctx);
d6181b
 
d6181b
     switch (state->type) {
d6181b
     case IPA_ACCOUNT_INFO_SUBDOMAIN:
d6181b
         /* Subdomain lookups are handled differently on server and client. */
d6181b
-        subreq = ipa_subdomain_account_send(state, params->ev, id_ctx, data);
d6181b
+        subreq = ipa_subdomain_account_send(state, be_ctx->ev, id_ctx, data);
d6181b
         break;
d6181b
     case IPA_ACCOUNT_INFO_NETGROUP:
d6181b
         if (data->filter_type != BE_FILTER_NAME) {
d6181b
@@ -1388,11 +1384,11 @@ ipa_account_info_handler_send(TALLOC_CTX *mem_ctx,
d6181b
             goto immediately;
d6181b
         }
d6181b
 
d6181b
-        subreq = ipa_id_get_netgroup_send(state, params->ev, id_ctx,
d6181b
+        subreq = ipa_id_get_netgroup_send(state, be_ctx->ev, id_ctx,
d6181b
                                           data->filter_value);
d6181b
         break;
d6181b
     case IPA_ACCOUNT_INFO_OTHER:
d6181b
-        subreq = ipa_id_get_account_info_send(state, params->ev, id_ctx, data);
d6181b
+        subreq = ipa_id_get_account_info_send(state, be_ctx->ev, id_ctx, data);
d6181b
         break;
d6181b
     }
d6181b
 
d6181b
@@ -1400,7 +1396,99 @@ ipa_account_info_handler_send(TALLOC_CTX *mem_ctx,
d6181b
         ret = ENOMEM;
d6181b
         goto immediately;
d6181b
     }
d6181b
+    tevent_req_set_callback(subreq, ipa_account_info_done, req);
d6181b
+    return req;
d6181b
+
d6181b
+immediately:
d6181b
+    tevent_req_error(req, ret);
d6181b
+    tevent_req_post(req, be_ctx->ev);
d6181b
+    return req;
d6181b
+}
d6181b
+
d6181b
+static void ipa_account_info_done(struct tevent_req *subreq)
d6181b
+{
d6181b
+    struct ipa_account_info_state *state = NULL;
d6181b
+    struct tevent_req *req = NULL;
d6181b
+    errno_t ret;
d6181b
+
d6181b
+    req = tevent_req_callback_data(subreq, struct tevent_req);
d6181b
+    state = tevent_req_data(req, struct ipa_account_info_state);
d6181b
+
d6181b
+    switch (state->type) {
d6181b
+    case IPA_ACCOUNT_INFO_SUBDOMAIN:
d6181b
+        ret = ipa_subdomain_account_recv(subreq, &state->dp_error);
d6181b
+        break;
d6181b
+    case IPA_ACCOUNT_INFO_NETGROUP:
d6181b
+        ret = ipa_id_get_netgroup_recv(subreq, &state->dp_error);
d6181b
+        break;
d6181b
+    case IPA_ACCOUNT_INFO_OTHER:
d6181b
+        ret = ipa_id_get_account_info_recv(subreq, &state->dp_error);
d6181b
+        break;
d6181b
+    default:
d6181b
+        ret = EINVAL;
d6181b
+        break;
d6181b
+    }
d6181b
+    talloc_zfree(subreq);
d6181b
+
d6181b
+    if (ret != EOK) {
d6181b
+        tevent_req_error(req, ret);
d6181b
+        return;
d6181b
+    }
d6181b
+
d6181b
+    tevent_req_done(req);
d6181b
+}
d6181b
 
d6181b
+errno_t ipa_account_info_recv(struct tevent_req *req,
d6181b
+                              int *_dp_error)
d6181b
+{
d6181b
+    struct ipa_account_info_state *state = NULL;
d6181b
+
d6181b
+    state = tevent_req_data(req, struct ipa_account_info_state);
d6181b
+
d6181b
+    /* Fail the request after collecting the dp_error */
d6181b
+    if (_dp_error) {
d6181b
+        *_dp_error = state->dp_error;
d6181b
+    }
d6181b
+
d6181b
+    TEVENT_REQ_RETURN_ON_ERROR(req);
d6181b
+    return EOK;
d6181b
+}
d6181b
+
d6181b
+struct ipa_account_info_handler_state {
d6181b
+    struct dp_reply_std reply;
d6181b
+};
d6181b
+
d6181b
+static void ipa_account_info_handler_done(struct tevent_req *subreq);
d6181b
+
d6181b
+struct tevent_req *
d6181b
+ipa_account_info_handler_send(TALLOC_CTX *mem_ctx,
d6181b
+                              struct ipa_id_ctx *id_ctx,
d6181b
+                              struct dp_id_data *data,
d6181b
+                              struct dp_req_params *params)
d6181b
+{
d6181b
+    struct ipa_account_info_handler_state *state;
d6181b
+    struct tevent_req *subreq = NULL;
d6181b
+    struct tevent_req *req;
d6181b
+    errno_t ret;
d6181b
+
d6181b
+    req = tevent_req_create(mem_ctx, &state,
d6181b
+                            struct ipa_account_info_handler_state);
d6181b
+    if (req == NULL) {
d6181b
+        DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
d6181b
+        return NULL;
d6181b
+    }
d6181b
+
d6181b
+    if (sdap_is_enum_request(data)) {
d6181b
+        DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n");
d6181b
+        ret = EOK;
d6181b
+        goto immediately;
d6181b
+    }
d6181b
+
d6181b
+    subreq = ipa_account_info_send(state, params->be_ctx, id_ctx, data);
d6181b
+    if (subreq == NULL) {
d6181b
+        ret = ENOMEM;
d6181b
+        goto immediately;
d6181b
+    }
d6181b
     tevent_req_set_callback(subreq, ipa_account_info_handler_done, req);
d6181b
 
d6181b
     return req;
d6181b
@@ -1425,17 +1513,7 @@ static void ipa_account_info_handler_done(struct tevent_req *subreq)
d6181b
     req = tevent_req_callback_data(subreq, struct tevent_req);
d6181b
     state = tevent_req_data(req, struct ipa_account_info_handler_state);
d6181b
 
d6181b
-    switch (state->type) {
d6181b
-    case IPA_ACCOUNT_INFO_SUBDOMAIN:
d6181b
-        ret = ipa_subdomain_account_recv(subreq, &dp_error);
d6181b
-        break;
d6181b
-    case IPA_ACCOUNT_INFO_NETGROUP:
d6181b
-        ret = ipa_id_get_netgroup_recv(subreq, &dp_error);
d6181b
-        break;
d6181b
-    case IPA_ACCOUNT_INFO_OTHER:
d6181b
-        ret = ipa_id_get_account_info_recv(subreq, &dp_error);
d6181b
-        break;
d6181b
-    }
d6181b
+    ret = ipa_account_info_recv(subreq, &dp_error);
d6181b
     talloc_zfree(subreq);
d6181b
 
d6181b
     /* TODO For backward compatibility we always return EOK to DP now. */
d6181b
diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h
d6181b
index 4b2549882..fe9acfeef 100644
d6181b
--- a/src/providers/ipa/ipa_id.h
d6181b
+++ b/src/providers/ipa/ipa_id.h
d6181b
@@ -33,6 +33,14 @@
d6181b
 
d6181b
 #define IPA_DEFAULT_VIEW_NAME "Default Trust View"
d6181b
 
d6181b
+struct tevent_req *
d6181b
+ipa_account_info_send(TALLOC_CTX *mem_ctx,
d6181b
+                      struct be_ctx *be_ctx,
d6181b
+                      struct ipa_id_ctx *id_ctx,
d6181b
+                      struct dp_id_data *data);
d6181b
+errno_t ipa_account_info_recv(struct tevent_req *req,
d6181b
+                              int *_dp_error);
d6181b
+
d6181b
 struct tevent_req *
d6181b
 ipa_account_info_handler_send(TALLOC_CTX *mem_ctx,
d6181b
                               struct ipa_id_ctx *id_ctx,
d6181b
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
d6181b
index b3060e228..cdfd11d7a 100644
d6181b
--- a/src/providers/ipa/ipa_init.c
d6181b
+++ b/src/providers/ipa/ipa_init.c
d6181b
@@ -594,7 +594,7 @@ static errno_t ipa_init_misc(struct be_ctx *be_ctx,
d6181b
         }
d6181b
     }
d6181b
 
d6181b
-    ret = sdap_refresh_init(be_ctx, sdap_id_ctx);
d6181b
+    ret = ipa_refresh_init(be_ctx, ipa_id_ctx);
d6181b
     if (ret != EOK && ret != EEXIST) {
d6181b
         DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh "
d6181b
               "will not work [%d]: %s\n", ret, sss_strerror(ret));
d6181b
diff --git a/src/providers/ipa/ipa_refresh.c b/src/providers/ipa/ipa_refresh.c
d6181b
new file mode 100644
d6181b
index 000000000..72051cfdd
d6181b
--- /dev/null
d6181b
+++ b/src/providers/ipa/ipa_refresh.c
d6181b
@@ -0,0 +1,264 @@
d6181b
+/*
d6181b
+    Copyright (C) 2019 Red Hat
d6181b
+
d6181b
+    This program is free software; you can redistribute it and/or modify
d6181b
+    it under the terms of the GNU General Public License as published by
d6181b
+    the Free Software Foundation; either version 3 of the License, or
d6181b
+    (at your option) any later version.
d6181b
+
d6181b
+    This program is distributed in the hope that it will be useful,
d6181b
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
d6181b
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
d6181b
+    GNU General Public License for more details.
d6181b
+
d6181b
+    You should have received a copy of the GNU General Public License
d6181b
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
d6181b
+*/
d6181b
+
d6181b
+#include <talloc.h>
d6181b
+#include <tevent.h>
d6181b
+
d6181b
+#include "providers/ipa/ipa_common.h"
d6181b
+#include "providers/ipa/ipa_id.h"
d6181b
+
d6181b
+struct ipa_refresh_state {
d6181b
+    struct tevent_context *ev;
d6181b
+    struct be_ctx *be_ctx;
d6181b
+    struct dp_id_data *account_req;
d6181b
+    struct ipa_id_ctx *id_ctx;
d6181b
+    char **names;
d6181b
+    size_t index;
d6181b
+};
d6181b
+
d6181b
+static errno_t ipa_refresh_step(struct tevent_req *req);
d6181b
+static void ipa_refresh_done(struct tevent_req *subreq);
d6181b
+
d6181b
+static struct tevent_req *ipa_refresh_send(TALLOC_CTX *mem_ctx,
d6181b
+                                            struct tevent_context *ev,
d6181b
+                                            struct be_ctx *be_ctx,
d6181b
+                                            struct sss_domain_info *domain,
d6181b
+                                            int entry_type,
d6181b
+                                            char **names,
d6181b
+                                            void *pvt)
d6181b
+{
d6181b
+    struct ipa_refresh_state *state = NULL;
d6181b
+    struct tevent_req *req = NULL;
d6181b
+    errno_t ret;
d6181b
+
d6181b
+    req = tevent_req_create(mem_ctx, &state,
d6181b
+                            struct ipa_refresh_state);
d6181b
+    if (req == NULL) {
d6181b
+        DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
d6181b
+        return NULL;
d6181b
+    }
d6181b
+
d6181b
+    if (names == NULL) {
d6181b
+        ret = EOK;
d6181b
+        goto immediately;
d6181b
+    }
d6181b
+
d6181b
+    state->ev = ev;
d6181b
+    state->be_ctx = be_ctx;
d6181b
+    state->id_ctx = talloc_get_type(pvt, struct ipa_id_ctx);
d6181b
+    state->names = names;
d6181b
+    state->index = 0;
d6181b
+
d6181b
+    state->account_req = be_refresh_acct_req(state, entry_type,
d6181b
+                                             BE_FILTER_NAME, domain);
d6181b
+    if (state->account_req == NULL) {
d6181b
+        ret = ENOMEM;
d6181b
+        goto immediately;
d6181b
+    }
d6181b
+
d6181b
+    ret = ipa_refresh_step(req);
d6181b
+    if (ret == EOK) {
d6181b
+        DEBUG(SSSDBG_TRACE_FUNC, "Nothing to refresh\n");
d6181b
+        goto immediately;
d6181b
+    } else if (ret != EAGAIN) {
d6181b
+        DEBUG(SSSDBG_CRIT_FAILURE, "ipa_refresh_step() failed "
d6181b
+                                   "[%d]: %s\n", ret, sss_strerror(ret));
d6181b
+        goto immediately;
d6181b
+    }
d6181b
+
d6181b
+    return req;
d6181b
+
d6181b
+immediately:
d6181b
+    if (ret == EOK) {
d6181b
+        tevent_req_done(req);
d6181b
+    } else {
d6181b
+        tevent_req_error(req, ret);
d6181b
+    }
d6181b
+    tevent_req_post(req, ev);
d6181b
+
d6181b
+    return req;
d6181b
+}
d6181b
+
d6181b
+static errno_t ipa_refresh_step(struct tevent_req *req)
d6181b
+{
d6181b
+    struct ipa_refresh_state *state = NULL;
d6181b
+    struct tevent_req *subreq = NULL;
d6181b
+    errno_t ret;
d6181b
+
d6181b
+    state = tevent_req_data(req, struct ipa_refresh_state);
d6181b
+
d6181b
+    if (state->names == NULL) {
d6181b
+        ret = EOK;
d6181b
+        goto done;
d6181b
+    }
d6181b
+
d6181b
+    state->account_req->filter_value = state->names[state->index];
d6181b
+    if (state->account_req->filter_value == NULL) {
d6181b
+        ret = EOK;
d6181b
+        goto done;
d6181b
+    }
d6181b
+
d6181b
+    subreq = ipa_account_info_send(state, state->be_ctx, state->id_ctx,
d6181b
+                                  state->account_req);
d6181b
+    if (subreq == NULL) {
d6181b
+        ret = ENOMEM;
d6181b
+        goto done;
d6181b
+    }
d6181b
+
d6181b
+    tevent_req_set_callback(subreq, ipa_refresh_done, req);
d6181b
+
d6181b
+    state->index++;
d6181b
+    ret = EAGAIN;
d6181b
+
d6181b
+done:
d6181b
+    return ret;
d6181b
+}
d6181b
+
d6181b
+static void ipa_refresh_done(struct tevent_req *subreq)
d6181b
+{
d6181b
+    struct ipa_refresh_state *state = NULL;
d6181b
+    struct tevent_req *req = NULL;
d6181b
+    errno_t dp_error;
d6181b
+    errno_t ret;
d6181b
+
d6181b
+    req = tevent_req_callback_data(subreq, struct tevent_req);
d6181b
+    state = tevent_req_data(req, struct ipa_refresh_state);
d6181b
+
d6181b
+    ret = ipa_account_info_recv(subreq, &dp_error);
d6181b
+    talloc_zfree(subreq);
d6181b
+    if (ret != EOK) {
d6181b
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to refresh %s [dp_error: %d, "
d6181b
+              "errno: %d]\n", be_req2str(state->account_req->entry_type),
d6181b
+              dp_error, ret);
d6181b
+        goto done;
d6181b
+    }
d6181b
+
d6181b
+    ret = ipa_refresh_step(req);
d6181b
+    if (ret == EAGAIN) {
d6181b
+        return;
d6181b
+    }
d6181b
+
d6181b
+done:
d6181b
+    if (ret != EOK) {
d6181b
+        tevent_req_error(req, ret);
d6181b
+        return;
d6181b
+    }
d6181b
+
d6181b
+    tevent_req_done(req);
d6181b
+}
d6181b
+
d6181b
+static errno_t ipa_refresh_recv(struct tevent_req *req)
d6181b
+{
d6181b
+    TEVENT_REQ_RETURN_ON_ERROR(req);
d6181b
+
d6181b
+    return EOK;
d6181b
+}
d6181b
+
d6181b
+static struct tevent_req *
d6181b
+ipa_refresh_users_send(TALLOC_CTX *mem_ctx,
d6181b
+                        struct tevent_context *ev,
d6181b
+                        struct be_ctx *be_ctx,
d6181b
+                        struct sss_domain_info *domain,
d6181b
+                        char **names,
d6181b
+                        void *pvt)
d6181b
+{
d6181b
+    return ipa_refresh_send(mem_ctx, ev, be_ctx, domain,
d6181b
+                           BE_REQ_USER, names, pvt);
d6181b
+}
d6181b
+
d6181b
+static errno_t ipa_refresh_users_recv(struct tevent_req *req)
d6181b
+{
d6181b
+    return ipa_refresh_recv(req);
d6181b
+}
d6181b
+
d6181b
+static struct tevent_req *
d6181b
+ipa_refresh_groups_send(TALLOC_CTX *mem_ctx,
d6181b
+                         struct tevent_context *ev,
d6181b
+                         struct be_ctx *be_ctx,
d6181b
+                         struct sss_domain_info *domain,
d6181b
+                         char **names,
d6181b
+                         void *pvt)
d6181b
+{
d6181b
+    return ipa_refresh_send(mem_ctx, ev, be_ctx, domain,
d6181b
+                           BE_REQ_GROUP, names, pvt);
d6181b
+}
d6181b
+
d6181b
+static errno_t ipa_refresh_groups_recv(struct tevent_req *req)
d6181b
+{
d6181b
+    return ipa_refresh_recv(req);
d6181b
+}
d6181b
+
d6181b
+static struct tevent_req *
d6181b
+ipa_refresh_netgroups_send(TALLOC_CTX *mem_ctx,
d6181b
+                            struct tevent_context *ev,
d6181b
+                            struct be_ctx *be_ctx,
d6181b
+                            struct sss_domain_info *domain,
d6181b
+                            char **names,
d6181b
+                            void *pvt)
d6181b
+{
d6181b
+    return ipa_refresh_send(mem_ctx, ev, be_ctx, domain,
d6181b
+                           BE_REQ_NETGROUP, names, pvt);
d6181b
+}
d6181b
+
d6181b
+static errno_t ipa_refresh_netgroups_recv(struct tevent_req *req)
d6181b
+{
d6181b
+    return ipa_refresh_recv(req);
d6181b
+}
d6181b
+
d6181b
+errno_t ipa_refresh_init(struct be_ctx *be_ctx,
d6181b
+                         struct ipa_id_ctx *id_ctx)
d6181b
+{
d6181b
+    errno_t ret;
d6181b
+
d6181b
+    ret = be_refresh_ctx_init(be_ctx, SYSDB_NAME);
d6181b
+    if (ret != EOK) {
d6181b
+        DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n");
d6181b
+        return ENOMEM;
d6181b
+    }
d6181b
+
d6181b
+    ret = be_refresh_add_cb(be_ctx->refresh_ctx,
d6181b
+                            BE_REFRESH_TYPE_USERS,
d6181b
+                            ipa_refresh_users_send,
d6181b
+                            ipa_refresh_users_recv,
d6181b
+                            id_ctx);
d6181b
+    if (ret != EOK && ret != EEXIST) {
d6181b
+        DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users "
d6181b
+              "will not work [%d]: %s\n", ret, strerror(ret));
d6181b
+    }
d6181b
+
d6181b
+    ret = be_refresh_add_cb(be_ctx->refresh_ctx,
d6181b
+                            BE_REFRESH_TYPE_GROUPS,
d6181b
+                            ipa_refresh_groups_send,
d6181b
+                            ipa_refresh_groups_recv,
d6181b
+                            id_ctx);
d6181b
+    if (ret != EOK && ret != EEXIST) {
d6181b
+        DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of groups "
d6181b
+              "will not work [%d]: %s\n", ret, strerror(ret));
d6181b
+    }
d6181b
+
d6181b
+    ret = be_refresh_add_cb(be_ctx->refresh_ctx,
d6181b
+                            BE_REFRESH_TYPE_NETGROUPS,
d6181b
+                            ipa_refresh_netgroups_send,
d6181b
+                            ipa_refresh_netgroups_recv,
d6181b
+                            id_ctx);
d6181b
+    if (ret != EOK && ret != EEXIST) {
d6181b
+        DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups "
d6181b
+              "will not work [%d]: %s\n", ret, strerror(ret));
d6181b
+    }
d6181b
+
d6181b
+    return ret;
d6181b
+}
d6181b
-- 
d6181b
2.20.1
d6181b