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

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