Blame SOURCES/0163-IFP-Resolve-group-names-from-GIDs-if-required.patch

bb7cd1
From 3891e94330a5df632a8db1a6f1d642cf2fa96579 Mon Sep 17 00:00:00 2001
bb7cd1
From: Jakub Hrozek <jhrozek@redhat.com>
bb7cd1
Date: Wed, 24 May 2017 21:32:28 +0200
bb7cd1
Subject: [PATCH 163/166] IFP: Resolve group names from GIDs if required
bb7cd1
MIME-Version: 1.0
bb7cd1
Content-Type: text/plain; charset=UTF-8
bb7cd1
Content-Transfer-Encoding: 8bit
bb7cd1
bb7cd1
The AD provider only converts SIDs to GIDs during initgroups
bb7cd1
to improve performance. But this is not sufficient for the
bb7cd1
org.freedesktop.sssd.infopipe.GetUserGroups method, which needs to return
bb7cd1
names.
bb7cd1
bb7cd1
We need to resolve the GIDs to names ourselves in that method.
bb7cd1
bb7cd1
Resolves:
bb7cd1
https://pagure.io/SSSD/sssd/issue/3392
bb7cd1
bb7cd1
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
bb7cd1
---
bb7cd1
 src/responder/ifp/ifpsrv_cmd.c | 115 +++++++++++++++++++++++++++++++----------
bb7cd1
 1 file changed, 89 insertions(+), 26 deletions(-)
bb7cd1
bb7cd1
diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c
bb7cd1
index 915f77e38e94c703f6c67e8d5fdcc59d189943be..70728e1bb656fd032b7f1c240683e8aa3b91a726 100644
bb7cd1
--- a/src/responder/ifp/ifpsrv_cmd.c
bb7cd1
+++ b/src/responder/ifp/ifpsrv_cmd.c
bb7cd1
@@ -259,7 +259,18 @@ ifp_user_get_attr_handle_reply(struct sss_domain_info *domain,
bb7cd1
     return sbus_request_finish(ireq->dbus_req, reply);
bb7cd1
 }
bb7cd1
 
bb7cd1
+struct ifp_user_get_groups_state {
bb7cd1
+    struct resp_ctx *rctx;
bb7cd1
+
bb7cd1
+    struct ifp_attr_req *group_attr_req;
bb7cd1
+
bb7cd1
+    struct ldb_result *res;
bb7cd1
+    struct ldb_result *res_names;
bb7cd1
+    struct sss_domain_info *dom;
bb7cd1
+};
bb7cd1
+
bb7cd1
 static void ifp_user_get_groups_process(struct tevent_req *req);
bb7cd1
+static void ifp_user_get_groups_names_resolved(struct tevent_req *req);
bb7cd1
 static errno_t ifp_user_get_groups_reply(struct sss_domain_info *domain,
bb7cd1
                                          struct ifp_req *ireq,
bb7cd1
                                          struct ldb_result *res);
bb7cd1
@@ -269,7 +280,7 @@ int ifp_user_get_groups(struct sbus_request *dbus_req,
bb7cd1
 {
bb7cd1
     struct ifp_req *ireq;
bb7cd1
     struct ifp_ctx *ifp_ctx;
bb7cd1
-    struct ifp_attr_req *group_req;
bb7cd1
+    struct ifp_user_get_groups_state *state;
bb7cd1
     struct tevent_req *req;
bb7cd1
     errno_t ret;
bb7cd1
 
bb7cd1
@@ -284,68 +295,120 @@ int ifp_user_get_groups(struct sbus_request *dbus_req,
bb7cd1
         return ifp_req_create_handle_failure(dbus_req, ret);
bb7cd1
     }
bb7cd1
 
bb7cd1
-    group_req = talloc_zero(ireq, struct ifp_attr_req);
bb7cd1
-    if (group_req == NULL) {
bb7cd1
+    state = talloc_zero(ireq, struct ifp_user_get_groups_state);
bb7cd1
+    if (state == NULL) {
bb7cd1
         return sbus_request_finish(dbus_req, NULL);
bb7cd1
     }
bb7cd1
-    group_req->ireq = ireq;
bb7cd1
-    group_req->name = arg_user;
bb7cd1
+    state->rctx = ifp_ctx->rctx;
bb7cd1
 
bb7cd1
-    group_req->attrs = talloc_zero_array(group_req, const char *, 2);
bb7cd1
-    if (group_req->attrs == NULL) {
bb7cd1
+    state->group_attr_req = talloc_zero(state, struct ifp_attr_req);
bb7cd1
+    if (state->group_attr_req == NULL) {
bb7cd1
         return sbus_request_finish(dbus_req, NULL);
bb7cd1
     }
bb7cd1
+    state->group_attr_req->ireq = ireq;
bb7cd1
+    state->group_attr_req->name = arg_user;
bb7cd1
 
bb7cd1
-    group_req->attrs[0] = talloc_strdup(group_req->attrs, SYSDB_MEMBEROF);
bb7cd1
-    if (group_req->attrs[0] == NULL) {
bb7cd1
+    state->group_attr_req->attrs = talloc_zero_array(state->group_attr_req,
bb7cd1
+                                                     const char *, 2);
bb7cd1
+    if (state->group_attr_req->attrs == NULL) {
bb7cd1
+        return sbus_request_finish(dbus_req, NULL);
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    state->group_attr_req->attrs[0] = talloc_strdup(state->group_attr_req->attrs,
bb7cd1
+                                                    SYSDB_MEMBEROF);
bb7cd1
+    if (state->group_attr_req->attrs[0] == NULL) {
bb7cd1
         return sbus_request_finish(dbus_req, NULL);
bb7cd1
     }
bb7cd1
 
bb7cd1
     DEBUG(SSSDBG_FUNC_DATA,
bb7cd1
           "Looking up groups of user [%s] on behalf of %"PRIi64"\n",
bb7cd1
-          group_req->name, group_req->ireq->dbus_req->client);
bb7cd1
+          state->group_attr_req->name,
bb7cd1
+          state->group_attr_req->ireq->dbus_req->client);
bb7cd1
 
bb7cd1
     req = ifp_user_get_attr_send(ireq, ifp_ctx->rctx,
bb7cd1
                                  ifp_ctx->rctx->ncache, SSS_DP_INITGROUPS,
bb7cd1
-                                 group_req->name, group_req->attrs);
bb7cd1
+                                 state->group_attr_req->name,
bb7cd1
+                                 state->group_attr_req->attrs);
bb7cd1
     if (req == NULL) {
bb7cd1
         return sbus_request_finish(dbus_req, NULL);
bb7cd1
     }
bb7cd1
-    tevent_req_set_callback(req, ifp_user_get_groups_process, group_req);
bb7cd1
+    tevent_req_set_callback(req,
bb7cd1
+                            ifp_user_get_groups_process,
bb7cd1
+                            state);
bb7cd1
     return EOK;
bb7cd1
 }
bb7cd1
 
bb7cd1
 static void ifp_user_get_groups_process(struct tevent_req *req)
bb7cd1
 {
bb7cd1
-    struct ifp_attr_req *group_req;
bb7cd1
+    struct ifp_user_get_groups_state *state;
bb7cd1
+    struct ifp_attr_req *group_attr_req;
bb7cd1
     errno_t ret;
bb7cd1
-    struct ldb_result *res;
bb7cd1
-    struct sss_domain_info *dom;
bb7cd1
 
bb7cd1
-    group_req = tevent_req_callback_data(req, struct ifp_attr_req);
bb7cd1
+    state = tevent_req_callback_data(req, struct ifp_user_get_groups_state);
bb7cd1
+    group_attr_req = state->group_attr_req;
bb7cd1
 
bb7cd1
-    ret = ifp_user_get_attr_recv(group_req, req, &res, &dom;;
bb7cd1
+    ret = ifp_user_get_attr_recv(group_attr_req, req, &state->res, &state->dom);
bb7cd1
     talloc_zfree(req);
bb7cd1
     if (ret == ENOENT) {
bb7cd1
-        sbus_request_fail_and_finish(group_req->ireq->dbus_req,
bb7cd1
-                               sbus_error_new(group_req->ireq->dbus_req,
bb7cd1
+        sbus_request_fail_and_finish(group_attr_req->ireq->dbus_req,
bb7cd1
+                               sbus_error_new(group_attr_req->ireq->dbus_req,
bb7cd1
                                               DBUS_ERROR_FAILED,
bb7cd1
                                               "No such user\n"));
bb7cd1
         return;
bb7cd1
     } else if (ret != EOK) {
bb7cd1
-        sbus_request_fail_and_finish(group_req->ireq->dbus_req,
bb7cd1
-                               sbus_error_new(group_req->ireq->dbus_req,
bb7cd1
+        sbus_request_fail_and_finish(group_attr_req->ireq->dbus_req,
bb7cd1
+                               sbus_error_new(group_attr_req->ireq->dbus_req,
bb7cd1
                                               DBUS_ERROR_FAILED,
bb7cd1
                                               "Failed to read attribute\n"));
bb7cd1
         return;
bb7cd1
     }
bb7cd1
 
bb7cd1
-    ret = ifp_user_get_groups_reply(dom, group_req->ireq, res);
bb7cd1
+    req = resp_resolve_group_names_send(state,
bb7cd1
+                                        state->rctx->ev,
bb7cd1
+                                        state->rctx,
bb7cd1
+                                        state->dom,
bb7cd1
+                                        state->res);
bb7cd1
+    if (req == NULL) {
bb7cd1
+        sbus_request_finish(group_attr_req->ireq->dbus_req, NULL);
bb7cd1
+        return;
bb7cd1
+    }
bb7cd1
+    tevent_req_set_callback(req,
bb7cd1
+                            ifp_user_get_groups_names_resolved,
bb7cd1
+                            state);
bb7cd1
+}
bb7cd1
+
bb7cd1
+static void ifp_user_get_groups_names_resolved(struct tevent_req *req)
bb7cd1
+{
bb7cd1
+    struct ifp_user_get_groups_state *state;
bb7cd1
+    struct ifp_attr_req *group_attr_req;
bb7cd1
+    errno_t ret;
bb7cd1
+
bb7cd1
+    state = tevent_req_callback_data(req, struct ifp_user_get_groups_state);
bb7cd1
+    group_attr_req = state->group_attr_req;
bb7cd1
+
bb7cd1
+    ret = resp_resolve_group_names_recv(state, req, &state->res_names);
bb7cd1
+    talloc_zfree(req);
bb7cd1
     if (ret != EOK) {
bb7cd1
-        sbus_request_fail_and_finish(group_req->ireq->dbus_req,
bb7cd1
-                               sbus_error_new(group_req->ireq->dbus_req,
bb7cd1
-                                              DBUS_ERROR_FAILED,
bb7cd1
-                                              "Failed to build a reply\n"));
bb7cd1
+        sbus_request_fail_and_finish(group_attr_req->ireq->dbus_req,
bb7cd1
+                            sbus_error_new(group_attr_req->ireq->dbus_req,
bb7cd1
+                                           DBUS_ERROR_FAILED,
bb7cd1
+                                           "Failed to resolve groupnames\n"));
bb7cd1
+        return;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    if (state->res_names == NULL) {
bb7cd1
+        state->res_names = state->res;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = ifp_user_get_groups_reply(state->dom,
bb7cd1
+                                    group_attr_req->ireq,
bb7cd1
+                                    state->res_names);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        sbus_request_fail_and_finish(group_attr_req->ireq->dbus_req,
bb7cd1
+                                     sbus_error_new(
bb7cd1
+                                            group_attr_req->ireq->dbus_req,
bb7cd1
+                                            DBUS_ERROR_FAILED,
bb7cd1
+                                            "Failed to build a reply\n"));
bb7cd1
         return;
bb7cd1
     }
bb7cd1
 }
bb7cd1
-- 
bb7cd1
2.9.4
bb7cd1