From b49f1fa6a35e60201f882e86e6da676850cf1bd4 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 13 Nov 2015 12:15:52 +0100
Subject: [PATCH 2/2] initgr: only search for primary group if it is not
 already cached

Related to https://fedorahosted.org/sssd/ticket/2868

Reviewed-by: Pavel Reichl <preichl@redhat.com>
(cherry picked from commit e182d98a391b5f6d3562e442748254cdbcef0b81)
---
 src/providers/ldap/sdap_async_initgroups.c | 54 +++++++++++++++++++-----------
 1 file changed, 34 insertions(+), 20 deletions(-)

diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index e9d1f3cc9..eaf558676 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2799,6 +2799,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
     char *group_sid_str;
     struct sdap_options *opts = state->opts;
     bool use_id_mapping = dp_opt_get_bool(opts->basic, SDAP_ID_MAPPING);
+    struct ldb_message *msg;
 
     DEBUG(9, ("Initgroups done\n"));
 
@@ -2842,7 +2843,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
     if (ret) {
         DEBUG(9, ("Error in initgroups: [%d][%s]\n",
                   ret, strerror(ret)));
-        goto fail;
+        goto done;
     }
 
     /* We also need to update the user's primary group, since
@@ -2865,7 +2866,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
                 tmp_ctx, opts->idmap_ctx, state->orig_user,
                 opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
                 &sid_str);
-        if (ret != EOK) goto fail;
+        if (ret != EOK) goto done;
 
         /* Get the domain SID from the user SID */
         ret = sdap_idmap_get_dom_sid_from_object(tmp_ctx, sid_str,
@@ -2873,7 +2874,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
         if (ret != EOK) {
             DEBUG(SSSDBG_MINOR_FAILURE,
                   ("Could not parse domain SID from [%s]\n", sid_str));
-            goto fail;
+            goto done;
         }
 
         ret = sysdb_attrs_get_uint32_t(
@@ -2884,7 +2885,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
             DEBUG(SSSDBG_MINOR_FAILURE,
                   ("no primary group ID provided\n"));
             ret = EINVAL;
-            goto fail;
+            goto done;
         }
 
         /* Add the RID to the end */
@@ -2893,42 +2894,55 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
                                         (unsigned long)primary_gid);
         if (!group_sid_str) {
             ret = ENOMEM;
-            goto fail;
+            goto done;
         }
 
         /* Convert the SID into a UNIX group ID */
         ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &primary_gid);
-        if (ret != EOK) goto fail;
+        if (ret != EOK) goto done;
     } else {
         ret = sysdb_attrs_get_uint32_t(state->orig_user, SYSDB_GIDNUM,
                                        &primary_gid);
         if (ret != EOK) {
             DEBUG(6, ("Could not find user's primary GID\n"));
-            goto fail;
+            goto done;
         }
     }
 
-    gid = talloc_asprintf(state, "%lu", (unsigned long)primary_gid);
-    if (gid == NULL) {
-        ret = ENOMEM;
-        goto fail;
-    }
+    ret = sysdb_search_group_by_gid(tmp_ctx, state->sysdb, primary_gid, NULL,
+                                    &msg);
+    if (ret == EOK) {
+        DEBUG(SSSDBG_TRACE_FUNC,
+              ("Primary group already cached, nothing to do.\n"));
+        ret = EOK;
+        goto done;
+    } else {
+        gid = talloc_asprintf(state, "%lu", (unsigned long)primary_gid);
+        if (gid == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
 
-    subreq = groups_get_send(req, state->ev, state->id_ctx, gid,
-                             BE_FILTER_IDNUM, BE_ATTR_ALL);
-    if (!subreq) {
-        ret = ENOMEM;
-        goto fail;
+        subreq = groups_get_send(req, state->ev, state->id_ctx, gid,
+                                 BE_FILTER_IDNUM, BE_ATTR_ALL);
+        if (!subreq) {
+            ret = ENOMEM;
+            goto done;
+        }
+        tevent_req_set_callback(subreq, sdap_get_initgr_pgid, req);
     }
-    tevent_req_set_callback(subreq, sdap_get_initgr_pgid, req);
 
     talloc_free(tmp_ctx);
     tevent_req_done(req);
     return;
 
-fail:
+done:
     talloc_free(tmp_ctx);
-    tevent_req_error(req, ret);
+    if (ret == EOK) {
+        tevent_req_done(req);
+    } else {
+        tevent_req_error(req, ret);
+    }
     return;
 }
 
-- 
2.16.2

