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

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