Blame SOURCES/0059-BE-IPA-AD-LDAP-Add-inigroups-refresh-support.patch

8d3578
From a8212a7884175fe32dccc29f3fed3688f81c76fe Mon Sep 17 00:00:00 2001
8d3578
From: Jakub Hrozek <jhrozek@redhat.com>
8d3578
Date: Tue, 25 Jun 2019 14:16:31 +0200
8d3578
Subject: [PATCH 59/64] BE/IPA/AD/LDAP: Add inigroups refresh support
8d3578
8d3578
Related: https://pagure.io/SSSD/sssd/issue/4012
8d3578
8d3578
In addition to refreshing users, groups and netgroups, this patch adds
8d3578
the ability to also refresh initgroups. The refresh is ran for any users
8d3578
that have the initgrExpireTimestamp attribute close to expiration.
8d3578
8d3578
This request is ran as the first one, because the initgroups operation
8d3578
refreshes the user entry and can touch groups as well.
8d3578
8d3578
Reviewed-by: Sumit Bose <sbose@redhat.com>
8d3578
(cherry picked from commit 1d0e75e9c5db0acf946f82705a4640063ea5aea9)
8d3578
8d3578
Reviewed-by: Sumit Bose <sbose@redhat.com>
8d3578
---
8d3578
 src/providers/ad/ad_refresh.c     | 28 +++++++++++++++++++++++
8d3578
 src/providers/be_refresh.c        | 37 +++++++++++++++++++++++--------
8d3578
 src/providers/be_refresh.h        |  1 +
8d3578
 src/providers/ipa/ipa_refresh.c   | 27 ++++++++++++++++++++++
8d3578
 src/providers/ldap/sdap_refresh.c | 17 ++++++++++++++
8d3578
 5 files changed, 101 insertions(+), 9 deletions(-)
8d3578
8d3578
diff --git a/src/providers/ad/ad_refresh.c b/src/providers/ad/ad_refresh.c
8d3578
index ee541056f..f0130cbaf 100644
8d3578
--- a/src/providers/ad/ad_refresh.c
8d3578
+++ b/src/providers/ad/ad_refresh.c
8d3578
@@ -65,6 +65,7 @@ static struct tevent_req *ad_refresh_send(TALLOC_CTX *mem_ctx,
8d3578
     state->index = 0;
8d3578
 
8d3578
     switch (entry_type) {
8d3578
+    case BE_REQ_INITGROUPS:
8d3578
     case BE_REQ_NETGROUP:
8d3578
         filter_type = BE_FILTER_NAME;
8d3578
         break;
8d3578
@@ -187,6 +188,23 @@ static errno_t ad_refresh_recv(struct tevent_req *req)
8d3578
     return EOK;
8d3578
 }
8d3578
 
8d3578
+static struct tevent_req *
8d3578
+ad_refresh_initgroups_send(TALLOC_CTX *mem_ctx,
8d3578
+                           struct tevent_context *ev,
8d3578
+                           struct be_ctx *be_ctx,
8d3578
+                           struct sss_domain_info *domain,
8d3578
+                           char **names,
8d3578
+                           void *pvt)
8d3578
+{
8d3578
+    return ad_refresh_send(mem_ctx, ev, be_ctx, domain,
8d3578
+                           BE_REQ_INITGROUPS, names, pvt);
8d3578
+}
8d3578
+
8d3578
+static errno_t ad_refresh_initgroups_recv(struct tevent_req *req)
8d3578
+{
8d3578
+    return ad_refresh_recv(req);
8d3578
+}
8d3578
+
8d3578
 static struct tevent_req *
8d3578
 ad_refresh_users_send(TALLOC_CTX *mem_ctx,
8d3578
                       struct tevent_context *ev,
8d3578
@@ -249,6 +267,16 @@ errno_t ad_refresh_init(struct be_ctx *be_ctx,
8d3578
         return ret;
8d3578
     }
8d3578
 
8d3578
+    ret = be_refresh_add_cb(be_ctx->refresh_ctx,
8d3578
+                            BE_REFRESH_TYPE_INITGROUPS,
8d3578
+                            ad_refresh_initgroups_send,
8d3578
+                            ad_refresh_initgroups_recv,
8d3578
+                            id_ctx);
8d3578
+    if (ret != EOK && ret != EEXIST) {
8d3578
+        DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users "
8d3578
+              "will not work [%d]: %s\n", ret, strerror(ret));
8d3578
+    }
8d3578
+
8d3578
     ret = be_refresh_add_cb(be_ctx->refresh_ctx,
8d3578
                             BE_REFRESH_TYPE_USERS,
8d3578
                             ad_refresh_users_send,
8d3578
diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c
8d3578
index a9d4295ec..6945ca9e3 100644
8d3578
--- a/src/providers/be_refresh.c
8d3578
+++ b/src/providers/be_refresh.c
8d3578
@@ -33,11 +33,12 @@ static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx,
8d3578
                                         struct sss_domain_info *domain,
8d3578
                                         time_t period,
8d3578
                                         struct ldb_dn *base_dn,
8d3578
-                                        const char *attr,
8d3578
+                                        const char *key_attr,
8d3578
+                                        const char *value_attr,
8d3578
                                         char ***_values)
8d3578
 {
8d3578
     TALLOC_CTX *tmp_ctx = NULL;
8d3578
-    const char *attrs[] = {attr, NULL};
8d3578
+    const char *attrs[] = {value_attr, NULL};
8d3578
     const char *filter = NULL;
8d3578
     char **values = NULL;
8d3578
     struct sysdb_attrs **records = NULL;
8d3578
@@ -45,13 +46,17 @@ static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx,
8d3578
     time_t now = time(NULL);
8d3578
     errno_t ret;
8d3578
 
8d3578
+    if (key_attr == NULL || domain == NULL || base_dn == NULL) {
8d3578
+        return EINVAL;
8d3578
+    }
8d3578
+
8d3578
     tmp_ctx = talloc_new(NULL);
8d3578
     if (tmp_ctx == NULL) {
8d3578
         return ENOMEM;
8d3578
     }
8d3578
 
8d3578
     filter = talloc_asprintf(tmp_ctx, "(&(%s<=%lld))",
8d3578
-                             SYSDB_CACHE_EXPIRE, (long long) now + period);
8d3578
+                             key_attr, (long long) now + period);
8d3578
     if (filter == NULL) {
8d3578
         ret = ENOMEM;
8d3578
         goto done;
8d3578
@@ -73,7 +78,7 @@ static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx,
8d3578
         goto done;
8d3578
     }
8d3578
 
8d3578
-    ret = sysdb_attrs_to_list(tmp_ctx, records, res->count, attr, &values);
8d3578
+    ret = sysdb_attrs_to_list(tmp_ctx, records, res->count, value_attr, &values);
8d3578
     if (ret != EOK) {
8d3578
         goto done;
8d3578
     }
8d3578
@@ -96,18 +101,27 @@ static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx,
8d3578
 {
8d3578
     struct ldb_dn *base_dn = NULL;
8d3578
     errno_t ret;
8d3578
+    const char *key_attr;
8d3578
 
8d3578
     switch (type) {
8d3578
+    case BE_REFRESH_TYPE_INITGROUPS:
8d3578
+        key_attr = SYSDB_INITGR_EXPIRE;
8d3578
+        base_dn = sysdb_user_base_dn(mem_ctx, domain);
8d3578
+        break;
8d3578
     case BE_REFRESH_TYPE_USERS:
8d3578
+        key_attr = SYSDB_CACHE_EXPIRE;
8d3578
         base_dn = sysdb_user_base_dn(mem_ctx, domain);
8d3578
         break;
8d3578
     case BE_REFRESH_TYPE_GROUPS:
8d3578
+        key_attr = SYSDB_CACHE_EXPIRE;
8d3578
         base_dn = sysdb_group_base_dn(mem_ctx, domain);
8d3578
         break;
8d3578
     case BE_REFRESH_TYPE_NETGROUPS:
8d3578
+        key_attr = SYSDB_CACHE_EXPIRE;
8d3578
         base_dn = sysdb_netgroup_base_dn(mem_ctx, domain);
8d3578
         break;
8d3578
-    case BE_REFRESH_TYPE_SENTINEL:
8d3578
+    default:
8d3578
+        DEBUG(SSSDBG_CRIT_FAILURE, "Uknown or unsupported refresh type\n");
8d3578
         return ERR_INTERNAL;
8d3578
         break;
8d3578
     }
8d3578
@@ -117,7 +131,8 @@ static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx,
8d3578
     }
8d3578
 
8d3578
     ret = be_refresh_get_values_ex(mem_ctx, domain, period,
8d3578
-                                   base_dn, attr_name, _values);
8d3578
+                                   base_dn, key_attr,
8d3578
+                                   attr_name, _values);
8d3578
 
8d3578
     talloc_free(base_dn);
8d3578
     return ret;
8d3578
@@ -125,6 +140,7 @@ static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx,
8d3578
 
8d3578
 struct be_refresh_cb {
8d3578
     const char *name;
8d3578
+    const char *attr_name;
8d3578
     bool enabled;
8d3578
     be_refresh_send_t send_fn;
8d3578
     be_refresh_recv_t recv_fn;
8d3578
@@ -132,7 +148,6 @@ struct be_refresh_cb {
8d3578
 };
8d3578
 
8d3578
 struct be_refresh_ctx {
8d3578
-    const char *attr_name;
8d3578
     struct be_refresh_cb callbacks[BE_REFRESH_TYPE_SENTINEL];
8d3578
 };
8d3578
 
8d3578
@@ -148,10 +163,14 @@ errno_t be_refresh_ctx_init(struct be_ctx *be_ctx,
8d3578
         return ENOMEM;
8d3578
     }
8d3578
 
8d3578
-    ctx->attr_name = attr_name;
8d3578
+    ctx->callbacks[BE_REFRESH_TYPE_INITGROUPS].name = "initgroups";
8d3578
+    ctx->callbacks[BE_REFRESH_TYPE_INITGROUPS].attr_name = SYSDB_NAME;
8d3578
     ctx->callbacks[BE_REFRESH_TYPE_USERS].name = "users";
8d3578
+    ctx->callbacks[BE_REFRESH_TYPE_USERS].attr_name = attr_name;
8d3578
     ctx->callbacks[BE_REFRESH_TYPE_GROUPS].name = "groups";
8d3578
+    ctx->callbacks[BE_REFRESH_TYPE_GROUPS].attr_name = attr_name;
8d3578
     ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].name = "netgroups";
8d3578
+    ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].attr_name = SYSDB_NAME;
8d3578
 
8d3578
     refresh_interval = be_ctx->domain->refresh_expired_interval;
8d3578
     if (refresh_interval > 0) {
8d3578
@@ -310,7 +329,7 @@ static errno_t be_refresh_step(struct tevent_req *req)
8d3578
         }
8d3578
 
8d3578
         talloc_zfree(state->refresh_values);
8d3578
-        ret = be_refresh_get_values(state, state->index, state->ctx->attr_name,
8d3578
+        ret = be_refresh_get_values(state, state->index, state->cb->attr_name,
8d3578
                                     state->domain, state->period,
8d3578
                                     &state->refresh_values);
8d3578
         if (ret != EOK) {
8d3578
diff --git a/src/providers/be_refresh.h b/src/providers/be_refresh.h
8d3578
index c7b4872df..4ac5b70c2 100644
8d3578
--- a/src/providers/be_refresh.h
8d3578
+++ b/src/providers/be_refresh.h
8d3578
@@ -44,6 +44,7 @@ typedef errno_t
8d3578
 (*be_refresh_recv_t)(struct tevent_req *req);
8d3578
 
8d3578
 enum be_refresh_type {
8d3578
+    BE_REFRESH_TYPE_INITGROUPS,
8d3578
     BE_REFRESH_TYPE_USERS,
8d3578
     BE_REFRESH_TYPE_GROUPS,
8d3578
     BE_REFRESH_TYPE_NETGROUPS,
8d3578
diff --git a/src/providers/ipa/ipa_refresh.c b/src/providers/ipa/ipa_refresh.c
8d3578
index 72051cfdd..bb47b0edf 100644
8d3578
--- a/src/providers/ipa/ipa_refresh.c
8d3578
+++ b/src/providers/ipa/ipa_refresh.c
8d3578
@@ -168,6 +168,23 @@ static errno_t ipa_refresh_recv(struct tevent_req *req)
8d3578
     return EOK;
8d3578
 }
8d3578
 
8d3578
+static struct tevent_req *
8d3578
+ipa_refresh_initgroups_send(TALLOC_CTX *mem_ctx,
8d3578
+                            struct tevent_context *ev,
8d3578
+                            struct be_ctx *be_ctx,
8d3578
+                            struct sss_domain_info *domain,
8d3578
+                            char **names,
8d3578
+                            void *pvt)
8d3578
+{
8d3578
+    return ipa_refresh_send(mem_ctx, ev, be_ctx, domain,
8d3578
+                           BE_REQ_INITGROUPS, names, pvt);
8d3578
+}
8d3578
+
8d3578
+static errno_t ipa_refresh_initgroups_recv(struct tevent_req *req)
8d3578
+{
8d3578
+    return ipa_refresh_recv(req);
8d3578
+}
8d3578
+
8d3578
 static struct tevent_req *
8d3578
 ipa_refresh_users_send(TALLOC_CTX *mem_ctx,
8d3578
                         struct tevent_context *ev,
8d3578
@@ -230,6 +247,16 @@ errno_t ipa_refresh_init(struct be_ctx *be_ctx,
8d3578
         return ENOMEM;
8d3578
     }
8d3578
 
8d3578
+    ret = be_refresh_add_cb(be_ctx->refresh_ctx,
8d3578
+                            BE_REFRESH_TYPE_USERS,
8d3578
+                            ipa_refresh_initgroups_send,
8d3578
+                            ipa_refresh_initgroups_recv,
8d3578
+                            id_ctx);
8d3578
+    if (ret != EOK && ret != EEXIST) {
8d3578
+        DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of initgroups "
8d3578
+              "will not work [%d]: %s\n", ret, strerror(ret));
8d3578
+    }
8d3578
+
8d3578
     ret = be_refresh_add_cb(be_ctx->refresh_ctx,
8d3578
                             BE_REFRESH_TYPE_USERS,
8d3578
                             ipa_refresh_users_send,
8d3578
diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c
8d3578
index 2206d6670..3ceddb61e 100644
8d3578
--- a/src/providers/ldap/sdap_refresh.c
8d3578
+++ b/src/providers/ldap/sdap_refresh.c
8d3578
@@ -186,6 +186,23 @@ static errno_t sdap_refresh_recv(struct tevent_req *req)
8d3578
     return EOK;
8d3578
 }
8d3578
 
8d3578
+static struct tevent_req *
8d3578
+sdap_refresh_initgroups_send(TALLOC_CTX *mem_ctx,
8d3578
+                        struct tevent_context *ev,
8d3578
+                        struct be_ctx *be_ctx,
8d3578
+                        struct sss_domain_info *domain,
8d3578
+                        char **names,
8d3578
+                        void *pvt)
8d3578
+{
8d3578
+    return sdap_refresh_send(mem_ctx, ev, be_ctx, domain,
8d3578
+                             BE_REQ_INITGROUPS, names, pvt);
8d3578
+}
8d3578
+
8d3578
+static errno_t sdap_refresh_initgroups_recv(struct tevent_req *req)
8d3578
+{
8d3578
+    return sdap_refresh_recv(req);
8d3578
+}
8d3578
+
8d3578
 static struct tevent_req *
8d3578
 sdap_refresh_users_send(TALLOC_CTX *mem_ctx,
8d3578
                         struct tevent_context *ev,
8d3578
-- 
8d3578
2.20.1
8d3578