Blame SOURCES/0057-AD-Implement-background-refresh-for-AD-domains.patch

5fca41
From 6777831bc1b0d1218d635d2913326883f509f3e8 Mon Sep 17 00:00:00 2001
5fca41
From: Jakub Hrozek <jhrozek@redhat.com>
5fca41
Date: Wed, 24 Apr 2019 20:52:11 +0200
5fca41
Subject: [PATCH 57/64] AD: Implement background refresh for AD domains
5fca41
5fca41
Split out the actual useful functionality from the AD account handler
5fca41
into a tevent request. This tevent request is then subsequently used by
5fca41
a new ad_refresh module.
5fca41
5fca41
Related:
5fca41
https://pagure.io/SSSD/sssd/issue/4012
5fca41
5fca41
Reviewed-by: Sumit Bose <sbose@redhat.com>
5fca41
(cherry picked from commit b72adfcc332b13489931483201bcc4c7ecf9ecb6)
5fca41
5fca41
Reviewed-by: Sumit Bose <sbose@redhat.com>
5fca41
---
5fca41
 Makefile.am                   |   5 +-
5fca41
 src/providers/ad/ad_common.h  |   4 +
5fca41
 src/providers/ad/ad_id.c      | 140 +++++++++++++----
5fca41
 src/providers/ad/ad_id.h      |  10 ++
5fca41
 src/providers/ad/ad_init.c    |   2 +-
5fca41
 src/providers/ad/ad_refresh.c | 283 ++++++++++++++++++++++++++++++++++
5fca41
 6 files changed, 412 insertions(+), 32 deletions(-)
5fca41
 create mode 100644 src/providers/ad/ad_refresh.c
5fca41
5fca41
diff --git a/Makefile.am b/Makefile.am
5fca41
index 0c24ae664..7d83b6847 100644
5fca41
--- a/Makefile.am
5fca41
+++ b/Makefile.am
5fca41
@@ -4243,7 +4243,10 @@ libsss_ad_la_SOURCES = \
5fca41
     src/providers/ad/ad_gpo_ndr.c \
5fca41
     src/providers/ad/ad_srv.c \
5fca41
     src/providers/ad/ad_subdomains.c \
5fca41
-    src/providers/ad/ad_domain_info.c
5fca41
+    src/providers/ad/ad_domain_info.c \
5fca41
+    src/providers/ad/ad_refresh.c \
5fca41
+    $(NULL)
5fca41
+
5fca41
 
5fca41
 if BUILD_SUDO
5fca41
 libsss_ad_la_SOURCES += \
5fca41
diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
5fca41
index 2f624df3d..44369288e 100644
5fca41
--- a/src/providers/ad/ad_common.h
5fca41
+++ b/src/providers/ad/ad_common.h
5fca41
@@ -221,4 +221,8 @@ errno_t ad_inherit_opts_if_needed(struct dp_option *parent_opts,
5fca41
                                   struct confdb_ctx *cdb,
5fca41
                                   const char *subdom_conf_path,
5fca41
                                   int opt_id);
5fca41
+
5fca41
+errno_t ad_refresh_init(struct be_ctx *be_ctx,
5fca41
+                        struct ad_id_ctx *id_ctx);
5fca41
+
5fca41
 #endif /* AD_COMMON_H_ */
5fca41
diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
5fca41
index c3bda1662..eb6e36824 100644
5fca41
--- a/src/providers/ad/ad_id.c
5fca41
+++ b/src/providers/ad/ad_id.c
5fca41
@@ -360,44 +360,36 @@ get_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx,
5fca41
     return clist;
5fca41
 }
5fca41
 
5fca41
-struct ad_account_info_handler_state {
5fca41
-    struct sss_domain_info *domain;
5fca41
-    struct dp_reply_std reply;
5fca41
+struct ad_account_info_state {
5fca41
+    const char *err_msg;
5fca41
+    int dp_error;
5fca41
 };
5fca41
 
5fca41
-static void ad_account_info_handler_done(struct tevent_req *subreq);
5fca41
+static void ad_account_info_done(struct tevent_req *subreq);
5fca41
 
5fca41
 struct tevent_req *
5fca41
-ad_account_info_handler_send(TALLOC_CTX *mem_ctx,
5fca41
-                              struct ad_id_ctx *id_ctx,
5fca41
-                              struct dp_id_data *data,
5fca41
-                              struct dp_req_params *params)
5fca41
+ad_account_info_send(TALLOC_CTX *mem_ctx,
5fca41
+                     struct be_ctx *be_ctx,
5fca41
+                     struct ad_id_ctx *id_ctx,
5fca41
+                     struct dp_id_data *data)
5fca41
 {
5fca41
-    struct ad_account_info_handler_state *state;
5fca41
-    struct sdap_id_conn_ctx **clist;
5fca41
-    struct sdap_id_ctx *sdap_id_ctx;
5fca41
-    struct sss_domain_info *domain;
5fca41
+    struct sss_domain_info *domain = NULL;
5fca41
+    struct ad_account_info_state *state = NULL;
5fca41
+    struct tevent_req *req = NULL;
5fca41
+    struct tevent_req *subreq = NULL;
5fca41
+    struct sdap_id_conn_ctx **clist = NULL;
5fca41
+    struct sdap_id_ctx *sdap_id_ctx = NULL;
5fca41
     struct sdap_domain *sdom;
5fca41
-    struct tevent_req *subreq;
5fca41
-    struct tevent_req *req;
5fca41
-    struct be_ctx *be_ctx;
5fca41
     errno_t ret;
5fca41
 
5fca41
-    sdap_id_ctx = id_ctx->sdap_id_ctx;
5fca41
-    be_ctx = params->be_ctx;
5fca41
-
5fca41
     req = tevent_req_create(mem_ctx, &state,
5fca41
-                            struct ad_account_info_handler_state);
5fca41
+                            struct ad_account_info_state);
5fca41
     if (req == NULL) {
5fca41
         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
5fca41
         return NULL;
5fca41
     }
5fca41
 
5fca41
-    if (sdap_is_enum_request(data)) {
5fca41
-        DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n");
5fca41
-        ret = EOK;
5fca41
-        goto immediately;
5fca41
-    }
5fca41
+    sdap_id_ctx = id_ctx->sdap_id_ctx;
5fca41
 
5fca41
     domain = be_ctx->domain;
5fca41
     if (strcasecmp(data->domain, be_ctx->domain->name) != 0) {
5fca41
@@ -406,6 +398,7 @@ ad_account_info_handler_send(TALLOC_CTX *mem_ctx,
5fca41
     }
5fca41
 
5fca41
     if (domain == NULL) {
5fca41
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unknown domain\n");
5fca41
         ret = EINVAL;
5fca41
         goto immediately;
5fca41
     }
5fca41
@@ -413,6 +406,7 @@ ad_account_info_handler_send(TALLOC_CTX *mem_ctx,
5fca41
     /* Determine whether to connect to GC, LDAP or try both. */
5fca41
     clist = get_conn_list(state, id_ctx, domain, data);
5fca41
     if (clist == NULL) {
5fca41
+        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create conn list\n");
5fca41
         ret = EIO;
5fca41
         goto immediately;
5fca41
     }
5fca41
@@ -423,14 +417,100 @@ ad_account_info_handler_send(TALLOC_CTX *mem_ctx,
5fca41
         goto immediately;
5fca41
     }
5fca41
 
5fca41
-    state->domain = sdom->dom;
5fca41
-
5fca41
     subreq = ad_handle_acct_info_send(state, data, sdap_id_ctx,
5fca41
                                       id_ctx->ad_options, sdom, clist);
5fca41
     if (subreq == NULL) {
5fca41
         ret = ENOMEM;
5fca41
         goto immediately;
5fca41
     }
5fca41
+    tevent_req_set_callback(subreq, ad_account_info_done, req);
5fca41
+    return req;
5fca41
+
5fca41
+immediately:
5fca41
+    tevent_req_error(req, ret);
5fca41
+    tevent_req_post(req, be_ctx->ev);
5fca41
+    return req;
5fca41
+}
5fca41
+
5fca41
+static void ad_account_info_done(struct tevent_req *subreq)
5fca41
+{
5fca41
+    struct ad_account_info_state *state = NULL;
5fca41
+    struct tevent_req *req = NULL;
5fca41
+    errno_t ret;
5fca41
+
5fca41
+    req = tevent_req_callback_data(subreq, struct tevent_req);
5fca41
+    state = tevent_req_data(req, struct ad_account_info_state);
5fca41
+
5fca41
+    ret = ad_handle_acct_info_recv(subreq, &state->dp_error, &state->err_msg);
5fca41
+    if (ret != EOK) {
5fca41
+        DEBUG(SSSDBG_OP_FAILURE,
5fca41
+              "ad_handle_acct_info_recv failed [%d]: %s\n",
5fca41
+              ret, sss_strerror(ret));
5fca41
+        /* The caller wouldn't fail either, just report the error up */
5fca41
+    }
5fca41
+    talloc_zfree(subreq);
5fca41
+    tevent_req_done(req);
5fca41
+}
5fca41
+
5fca41
+errno_t ad_account_info_recv(struct tevent_req *req,
5fca41
+                             int *_dp_error,
5fca41
+                             const char **_err_msg)
5fca41
+{
5fca41
+    struct ad_account_info_state *state = NULL;
5fca41
+
5fca41
+    state = tevent_req_data(req, struct ad_account_info_state);
5fca41
+
5fca41
+    if (_err_msg != NULL) {
5fca41
+        *_err_msg = state->err_msg;
5fca41
+    }
5fca41
+
5fca41
+    if (_dp_error) {
5fca41
+        *_dp_error = state->dp_error;
5fca41
+    }
5fca41
+
5fca41
+
5fca41
+    TEVENT_REQ_RETURN_ON_ERROR(req);
5fca41
+
5fca41
+    return EOK;
5fca41
+}
5fca41
+
5fca41
+struct ad_account_info_handler_state {
5fca41
+    struct sss_domain_info *domain;
5fca41
+    struct dp_reply_std reply;
5fca41
+};
5fca41
+
5fca41
+static void ad_account_info_handler_done(struct tevent_req *subreq);
5fca41
+
5fca41
+struct tevent_req *
5fca41
+ad_account_info_handler_send(TALLOC_CTX *mem_ctx,
5fca41
+                              struct ad_id_ctx *id_ctx,
5fca41
+                              struct dp_id_data *data,
5fca41
+                              struct dp_req_params *params)
5fca41
+{
5fca41
+    struct ad_account_info_handler_state *state;
5fca41
+    struct tevent_req *subreq;
5fca41
+    struct tevent_req *req;
5fca41
+    errno_t ret;
5fca41
+
5fca41
+
5fca41
+    req = tevent_req_create(mem_ctx, &state,
5fca41
+                            struct ad_account_info_handler_state);
5fca41
+    if (req == NULL) {
5fca41
+        DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
5fca41
+        return NULL;
5fca41
+    }
5fca41
+
5fca41
+    if (sdap_is_enum_request(data)) {
5fca41
+        DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n");
5fca41
+        ret = EOK;
5fca41
+        goto immediately;
5fca41
+    }
5fca41
+
5fca41
+    subreq = ad_account_info_send(state, params->be_ctx, id_ctx, data);
5fca41
+    if (subreq == NULL) {
5fca41
+        ret = ENOMEM;
5fca41
+        goto immediately;
5fca41
+    }
5fca41
 
5fca41
     tevent_req_set_callback(subreq, ad_account_info_handler_done, req);
5fca41
 
5fca41
@@ -451,13 +531,13 @@ static void ad_account_info_handler_done(struct tevent_req *subreq)
5fca41
     struct ad_account_info_handler_state *state;
5fca41
     struct tevent_req *req;
5fca41
     const char *err_msg;
5fca41
-    int dp_error;
5fca41
+    int dp_error = DP_ERR_FATAL;
5fca41
     errno_t ret;
5fca41
 
5fca41
     req = tevent_req_callback_data(subreq, struct tevent_req);
5fca41
     state = tevent_req_data(req, struct ad_account_info_handler_state);
5fca41
 
5fca41
-    ret = ad_handle_acct_info_recv(subreq, &dp_error, &err_msg);
5fca41
+    ret = ad_account_info_recv(subreq, &dp_error, &err_msg);
5fca41
     talloc_zfree(subreq);
5fca41
 
5fca41
     /* TODO For backward compatibility we always return EOK to DP now. */
5fca41
@@ -466,8 +546,8 @@ static void ad_account_info_handler_done(struct tevent_req *subreq)
5fca41
 }
5fca41
 
5fca41
 errno_t ad_account_info_handler_recv(TALLOC_CTX *mem_ctx,
5fca41
-                                      struct tevent_req *req,
5fca41
-                                      struct dp_reply_std *data)
5fca41
+                                     struct tevent_req *req,
5fca41
+                                     struct dp_reply_std *data)
5fca41
 {
5fca41
     struct ad_account_info_handler_state *state = NULL;
5fca41
 
5fca41
diff --git a/src/providers/ad/ad_id.h b/src/providers/ad/ad_id.h
5fca41
index 5154393c5..19cc54eec 100644
5fca41
--- a/src/providers/ad/ad_id.h
5fca41
+++ b/src/providers/ad/ad_id.h
5fca41
@@ -33,6 +33,16 @@ errno_t ad_account_info_handler_recv(TALLOC_CTX *mem_ctx,
5fca41
                                       struct tevent_req *req,
5fca41
                                       struct dp_reply_std *data);
5fca41
 
5fca41
+struct tevent_req *
5fca41
+ad_account_info_send(TALLOC_CTX *mem_ctx,
5fca41
+                     struct be_ctx *be_ctx,
5fca41
+                     struct ad_id_ctx *id_ctx,
5fca41
+                     struct dp_id_data *data);
5fca41
+
5fca41
+errno_t ad_account_info_recv(struct tevent_req *req,
5fca41
+                             int *_dp_error,
5fca41
+                             const char **_err_msg);
5fca41
+
5fca41
 struct tevent_req *
5fca41
 ad_handle_acct_info_send(TALLOC_CTX *mem_ctx,
5fca41
                          struct dp_id_data *ar,
5fca41
diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
5fca41
index 42c2f150a..f5aea8904 100644
5fca41
--- a/src/providers/ad/ad_init.c
5fca41
+++ b/src/providers/ad/ad_init.c
5fca41
@@ -408,7 +408,7 @@ static errno_t ad_init_misc(struct be_ctx *be_ctx,
5fca41
         return ret;
5fca41
     }
5fca41
 
5fca41
-    ret = sdap_refresh_init(be_ctx, sdap_id_ctx);
5fca41
+    ret = ad_refresh_init(be_ctx, ad_id_ctx);
5fca41
     if (ret != EOK && ret != EEXIST) {
5fca41
         DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh "
5fca41
               "will not work [%d]: %s\n", ret, sss_strerror(ret));
5fca41
diff --git a/src/providers/ad/ad_refresh.c b/src/providers/ad/ad_refresh.c
5fca41
new file mode 100644
5fca41
index 000000000..ee541056f
5fca41
--- /dev/null
5fca41
+++ b/src/providers/ad/ad_refresh.c
5fca41
@@ -0,0 +1,283 @@
5fca41
+/*
5fca41
+    Copyright (C) 2019 Red Hat
5fca41
+
5fca41
+    This program is free software; you can redistribute it and/or modify
5fca41
+    it under the terms of the GNU General Public License as published by
5fca41
+    the Free Software Foundation; either version 3 of the License, or
5fca41
+    (at your option) any later version.
5fca41
+
5fca41
+    This program is distributed in the hope that it will be useful,
5fca41
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
5fca41
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5fca41
+    GNU General Public License for more details.
5fca41
+
5fca41
+    You should have received a copy of the GNU General Public License
5fca41
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
5fca41
+*/
5fca41
+
5fca41
+#include <talloc.h>
5fca41
+#include <tevent.h>
5fca41
+
5fca41
+#include "providers/ad/ad_common.h"
5fca41
+#include "providers/ad/ad_id.h"
5fca41
+
5fca41
+struct ad_refresh_state {
5fca41
+    struct tevent_context *ev;
5fca41
+    struct be_ctx *be_ctx;
5fca41
+    struct dp_id_data *account_req;
5fca41
+    struct ad_id_ctx *id_ctx;
5fca41
+    char **names;
5fca41
+    size_t index;
5fca41
+};
5fca41
+
5fca41
+static errno_t ad_refresh_step(struct tevent_req *req);
5fca41
+static void ad_refresh_done(struct tevent_req *subreq);
5fca41
+
5fca41
+static struct tevent_req *ad_refresh_send(TALLOC_CTX *mem_ctx,
5fca41
+                                            struct tevent_context *ev,
5fca41
+                                            struct be_ctx *be_ctx,
5fca41
+                                            struct sss_domain_info *domain,
5fca41
+                                            int entry_type,
5fca41
+                                            char **names,
5fca41
+                                            void *pvt)
5fca41
+{
5fca41
+    struct ad_refresh_state *state = NULL;
5fca41
+    struct tevent_req *req = NULL;
5fca41
+    errno_t ret;
5fca41
+    uint32_t filter_type;
5fca41
+
5fca41
+    req = tevent_req_create(mem_ctx, &state,
5fca41
+                            struct ad_refresh_state);
5fca41
+    if (req == NULL) {
5fca41
+        DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
5fca41
+        return NULL;
5fca41
+    }
5fca41
+
5fca41
+    if (names == NULL) {
5fca41
+        ret = EOK;
5fca41
+        goto immediately;
5fca41
+    }
5fca41
+
5fca41
+    state->ev = ev;
5fca41
+    state->be_ctx = be_ctx;
5fca41
+    state->id_ctx = talloc_get_type(pvt, struct ad_id_ctx);
5fca41
+    state->names = names;
5fca41
+    state->index = 0;
5fca41
+
5fca41
+    switch (entry_type) {
5fca41
+    case BE_REQ_NETGROUP:
5fca41
+        filter_type = BE_FILTER_NAME;
5fca41
+        break;
5fca41
+    case BE_REQ_USER:
5fca41
+    case BE_REQ_GROUP:
5fca41
+        filter_type = BE_FILTER_SECID;
5fca41
+        break;
5fca41
+    default:
5fca41
+        ret = EINVAL;
5fca41
+        goto immediately;
5fca41
+    }
5fca41
+
5fca41
+    state->account_req = be_refresh_acct_req(state, entry_type,
5fca41
+                                             filter_type, domain);
5fca41
+    if (state->account_req == NULL) {
5fca41
+        ret = ENOMEM;
5fca41
+        goto immediately;
5fca41
+    }
5fca41
+
5fca41
+    ret = ad_refresh_step(req);
5fca41
+    if (ret == EOK) {
5fca41
+        DEBUG(SSSDBG_TRACE_FUNC, "Nothing to refresh\n");
5fca41
+        goto immediately;
5fca41
+    } else if (ret != EAGAIN) {
5fca41
+        DEBUG(SSSDBG_CRIT_FAILURE, "ad_refresh_step() failed "
5fca41
+                                   "[%d]: %s\n", ret, sss_strerror(ret));
5fca41
+        goto immediately;
5fca41
+    }
5fca41
+
5fca41
+    return req;
5fca41
+
5fca41
+immediately:
5fca41
+    if (ret == EOK) {
5fca41
+        tevent_req_done(req);
5fca41
+    } else {
5fca41
+        tevent_req_error(req, ret);
5fca41
+    }
5fca41
+    tevent_req_post(req, ev);
5fca41
+
5fca41
+    return req;
5fca41
+}
5fca41
+
5fca41
+static errno_t ad_refresh_step(struct tevent_req *req)
5fca41
+{
5fca41
+    struct ad_refresh_state *state = NULL;
5fca41
+    struct tevent_req *subreq = NULL;
5fca41
+    errno_t ret;
5fca41
+
5fca41
+    state = tevent_req_data(req, struct ad_refresh_state);
5fca41
+
5fca41
+    if (state->names == NULL) {
5fca41
+        ret = EOK;
5fca41
+        goto done;
5fca41
+    }
5fca41
+
5fca41
+    state->account_req->filter_value = state->names[state->index];
5fca41
+    if (state->account_req->filter_value == NULL) {
5fca41
+        ret = EOK;
5fca41
+        goto done;
5fca41
+    }
5fca41
+
5fca41
+    DEBUG(SSSDBG_TRACE_FUNC, "Issuing refresh of %s %s\n",
5fca41
+          be_req2str(state->account_req->entry_type),
5fca41
+          state->account_req->filter_value);
5fca41
+
5fca41
+    subreq = ad_account_info_send(state, state->be_ctx, state->id_ctx,
5fca41
+                                  state->account_req);
5fca41
+    if (subreq == NULL) {
5fca41
+        ret = ENOMEM;
5fca41
+        goto done;
5fca41
+    }
5fca41
+
5fca41
+    tevent_req_set_callback(subreq, ad_refresh_done, req);
5fca41
+
5fca41
+    state->index++;
5fca41
+    ret = EAGAIN;
5fca41
+
5fca41
+done:
5fca41
+    return ret;
5fca41
+}
5fca41
+
5fca41
+static void ad_refresh_done(struct tevent_req *subreq)
5fca41
+{
5fca41
+    struct ad_refresh_state *state = NULL;
5fca41
+    struct tevent_req *req = NULL;
5fca41
+    const char *err_msg = NULL;
5fca41
+    errno_t dp_error;
5fca41
+    errno_t ret;
5fca41
+
5fca41
+    req = tevent_req_callback_data(subreq, struct tevent_req);
5fca41
+    state = tevent_req_data(req, struct ad_refresh_state);
5fca41
+
5fca41
+    ret = ad_account_info_recv(subreq, &dp_error, &err_msg);
5fca41
+    talloc_zfree(subreq);
5fca41
+    if (ret != EOK) {
5fca41
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to refresh %s [dp_error: %d, "
5fca41
+              "errno: %d]: %s\n", be_req2str(state->account_req->entry_type),
5fca41
+              dp_error, ret, err_msg);
5fca41
+        goto done;
5fca41
+    }
5fca41
+
5fca41
+    ret = ad_refresh_step(req);
5fca41
+    if (ret == EAGAIN) {
5fca41
+        return;
5fca41
+    }
5fca41
+
5fca41
+done:
5fca41
+    if (ret != EOK) {
5fca41
+        tevent_req_error(req, ret);
5fca41
+        return;
5fca41
+    }
5fca41
+
5fca41
+    tevent_req_done(req);
5fca41
+}
5fca41
+
5fca41
+static errno_t ad_refresh_recv(struct tevent_req *req)
5fca41
+{
5fca41
+    TEVENT_REQ_RETURN_ON_ERROR(req);
5fca41
+
5fca41
+    return EOK;
5fca41
+}
5fca41
+
5fca41
+static struct tevent_req *
5fca41
+ad_refresh_users_send(TALLOC_CTX *mem_ctx,
5fca41
+                      struct tevent_context *ev,
5fca41
+                      struct be_ctx *be_ctx,
5fca41
+                      struct sss_domain_info *domain,
5fca41
+                      char **names,
5fca41
+                      void *pvt)
5fca41
+{
5fca41
+    return ad_refresh_send(mem_ctx, ev, be_ctx, domain,
5fca41
+                           BE_REQ_USER, names, pvt);
5fca41
+}
5fca41
+
5fca41
+static errno_t ad_refresh_users_recv(struct tevent_req *req)
5fca41
+{
5fca41
+    return ad_refresh_recv(req);
5fca41
+}
5fca41
+
5fca41
+static struct tevent_req *
5fca41
+ad_refresh_groups_send(TALLOC_CTX *mem_ctx,
5fca41
+                       struct tevent_context *ev,
5fca41
+                       struct be_ctx *be_ctx,
5fca41
+                       struct sss_domain_info *domain,
5fca41
+                       char **names,
5fca41
+                       void *pvt)
5fca41
+{
5fca41
+    return ad_refresh_send(mem_ctx, ev, be_ctx, domain,
5fca41
+                           BE_REQ_GROUP, names, pvt);
5fca41
+}
5fca41
+
5fca41
+static errno_t ad_refresh_groups_recv(struct tevent_req *req)
5fca41
+{
5fca41
+    return ad_refresh_recv(req);
5fca41
+}
5fca41
+
5fca41
+static struct tevent_req *
5fca41
+ad_refresh_netgroups_send(TALLOC_CTX *mem_ctx,
5fca41
+                          struct tevent_context *ev,
5fca41
+                          struct be_ctx *be_ctx,
5fca41
+                          struct sss_domain_info *domain,
5fca41
+                          char **names,
5fca41
+                          void *pvt)
5fca41
+{
5fca41
+    return ad_refresh_send(mem_ctx, ev, be_ctx, domain,
5fca41
+                           BE_REQ_NETGROUP, names, pvt);
5fca41
+}
5fca41
+
5fca41
+static errno_t ad_refresh_netgroups_recv(struct tevent_req *req)
5fca41
+{
5fca41
+    return ad_refresh_recv(req);
5fca41
+}
5fca41
+
5fca41
+errno_t ad_refresh_init(struct be_ctx *be_ctx,
5fca41
+                        struct ad_id_ctx *id_ctx)
5fca41
+{
5fca41
+    errno_t ret;
5fca41
+
5fca41
+    ret = be_refresh_ctx_init(be_ctx, SYSDB_SID_STR);
5fca41
+    if (ret != EOK) {
5fca41
+        DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n");
5fca41
+        return ret;
5fca41
+    }
5fca41
+
5fca41
+    ret = be_refresh_add_cb(be_ctx->refresh_ctx,
5fca41
+                            BE_REFRESH_TYPE_USERS,
5fca41
+                            ad_refresh_users_send,
5fca41
+                            ad_refresh_users_recv,
5fca41
+                            id_ctx);
5fca41
+    if (ret != EOK && ret != EEXIST) {
5fca41
+        DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users "
5fca41
+              "will not work [%d]: %s\n", ret, strerror(ret));
5fca41
+    }
5fca41
+
5fca41
+    ret = be_refresh_add_cb(be_ctx->refresh_ctx,
5fca41
+                            BE_REFRESH_TYPE_GROUPS,
5fca41
+                            ad_refresh_groups_send,
5fca41
+                            ad_refresh_groups_recv,
5fca41
+                            id_ctx);
5fca41
+    if (ret != EOK && ret != EEXIST) {
5fca41
+        DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of groups "
5fca41
+              "will not work [%d]: %s\n", ret, strerror(ret));
5fca41
+    }
5fca41
+
5fca41
+    ret = be_refresh_add_cb(be_ctx->refresh_ctx,
5fca41
+                            BE_REFRESH_TYPE_NETGROUPS,
5fca41
+                            ad_refresh_netgroups_send,
5fca41
+                            ad_refresh_netgroups_recv,
5fca41
+                            id_ctx);
5fca41
+    if (ret != EOK && ret != EEXIST) {
5fca41
+        DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups "
5fca41
+              "will not work [%d]: %s\n", ret, strerror(ret));
5fca41
+    }
5fca41
+
5fca41
+    return ret;
5fca41
+}
5fca41
-- 
5fca41
2.20.1
5fca41