Blob Blame History Raw
From 3891e94330a5df632a8db1a6f1d642cf2fa96579 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Wed, 24 May 2017 21:32:28 +0200
Subject: [PATCH 163/166] IFP: Resolve group names from GIDs if required
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The AD provider only converts SIDs to GIDs during initgroups
to improve performance. But this is not sufficient for the
org.freedesktop.sssd.infopipe.GetUserGroups method, which needs to return
names.

We need to resolve the GIDs to names ourselves in that method.

Resolves:
https://pagure.io/SSSD/sssd/issue/3392

Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
 src/responder/ifp/ifpsrv_cmd.c | 115 +++++++++++++++++++++++++++++++----------
 1 file changed, 89 insertions(+), 26 deletions(-)

diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c
index 915f77e38e94c703f6c67e8d5fdcc59d189943be..70728e1bb656fd032b7f1c240683e8aa3b91a726 100644
--- a/src/responder/ifp/ifpsrv_cmd.c
+++ b/src/responder/ifp/ifpsrv_cmd.c
@@ -259,7 +259,18 @@ ifp_user_get_attr_handle_reply(struct sss_domain_info *domain,
     return sbus_request_finish(ireq->dbus_req, reply);
 }
 
+struct ifp_user_get_groups_state {
+    struct resp_ctx *rctx;
+
+    struct ifp_attr_req *group_attr_req;
+
+    struct ldb_result *res;
+    struct ldb_result *res_names;
+    struct sss_domain_info *dom;
+};
+
 static void ifp_user_get_groups_process(struct tevent_req *req);
+static void ifp_user_get_groups_names_resolved(struct tevent_req *req);
 static errno_t ifp_user_get_groups_reply(struct sss_domain_info *domain,
                                          struct ifp_req *ireq,
                                          struct ldb_result *res);
@@ -269,7 +280,7 @@ int ifp_user_get_groups(struct sbus_request *dbus_req,
 {
     struct ifp_req *ireq;
     struct ifp_ctx *ifp_ctx;
-    struct ifp_attr_req *group_req;
+    struct ifp_user_get_groups_state *state;
     struct tevent_req *req;
     errno_t ret;
 
@@ -284,68 +295,120 @@ int ifp_user_get_groups(struct sbus_request *dbus_req,
         return ifp_req_create_handle_failure(dbus_req, ret);
     }
 
-    group_req = talloc_zero(ireq, struct ifp_attr_req);
-    if (group_req == NULL) {
+    state = talloc_zero(ireq, struct ifp_user_get_groups_state);
+    if (state == NULL) {
         return sbus_request_finish(dbus_req, NULL);
     }
-    group_req->ireq = ireq;
-    group_req->name = arg_user;
+    state->rctx = ifp_ctx->rctx;
 
-    group_req->attrs = talloc_zero_array(group_req, const char *, 2);
-    if (group_req->attrs == NULL) {
+    state->group_attr_req = talloc_zero(state, struct ifp_attr_req);
+    if (state->group_attr_req == NULL) {
         return sbus_request_finish(dbus_req, NULL);
     }
+    state->group_attr_req->ireq = ireq;
+    state->group_attr_req->name = arg_user;
 
-    group_req->attrs[0] = talloc_strdup(group_req->attrs, SYSDB_MEMBEROF);
-    if (group_req->attrs[0] == NULL) {
+    state->group_attr_req->attrs = talloc_zero_array(state->group_attr_req,
+                                                     const char *, 2);
+    if (state->group_attr_req->attrs == NULL) {
+        return sbus_request_finish(dbus_req, NULL);
+    }
+
+    state->group_attr_req->attrs[0] = talloc_strdup(state->group_attr_req->attrs,
+                                                    SYSDB_MEMBEROF);
+    if (state->group_attr_req->attrs[0] == NULL) {
         return sbus_request_finish(dbus_req, NULL);
     }
 
     DEBUG(SSSDBG_FUNC_DATA,
           "Looking up groups of user [%s] on behalf of %"PRIi64"\n",
-          group_req->name, group_req->ireq->dbus_req->client);
+          state->group_attr_req->name,
+          state->group_attr_req->ireq->dbus_req->client);
 
     req = ifp_user_get_attr_send(ireq, ifp_ctx->rctx,
                                  ifp_ctx->rctx->ncache, SSS_DP_INITGROUPS,
-                                 group_req->name, group_req->attrs);
+                                 state->group_attr_req->name,
+                                 state->group_attr_req->attrs);
     if (req == NULL) {
         return sbus_request_finish(dbus_req, NULL);
     }
-    tevent_req_set_callback(req, ifp_user_get_groups_process, group_req);
+    tevent_req_set_callback(req,
+                            ifp_user_get_groups_process,
+                            state);
     return EOK;
 }
 
 static void ifp_user_get_groups_process(struct tevent_req *req)
 {
-    struct ifp_attr_req *group_req;
+    struct ifp_user_get_groups_state *state;
+    struct ifp_attr_req *group_attr_req;
     errno_t ret;
-    struct ldb_result *res;
-    struct sss_domain_info *dom;
 
-    group_req = tevent_req_callback_data(req, struct ifp_attr_req);
+    state = tevent_req_callback_data(req, struct ifp_user_get_groups_state);
+    group_attr_req = state->group_attr_req;
 
-    ret = ifp_user_get_attr_recv(group_req, req, &res, &dom);
+    ret = ifp_user_get_attr_recv(group_attr_req, req, &state->res, &state->dom);
     talloc_zfree(req);
     if (ret == ENOENT) {
-        sbus_request_fail_and_finish(group_req->ireq->dbus_req,
-                               sbus_error_new(group_req->ireq->dbus_req,
+        sbus_request_fail_and_finish(group_attr_req->ireq->dbus_req,
+                               sbus_error_new(group_attr_req->ireq->dbus_req,
                                               DBUS_ERROR_FAILED,
                                               "No such user\n"));
         return;
     } else if (ret != EOK) {
-        sbus_request_fail_and_finish(group_req->ireq->dbus_req,
-                               sbus_error_new(group_req->ireq->dbus_req,
+        sbus_request_fail_and_finish(group_attr_req->ireq->dbus_req,
+                               sbus_error_new(group_attr_req->ireq->dbus_req,
                                               DBUS_ERROR_FAILED,
                                               "Failed to read attribute\n"));
         return;
     }
 
-    ret = ifp_user_get_groups_reply(dom, group_req->ireq, res);
+    req = resp_resolve_group_names_send(state,
+                                        state->rctx->ev,
+                                        state->rctx,
+                                        state->dom,
+                                        state->res);
+    if (req == NULL) {
+        sbus_request_finish(group_attr_req->ireq->dbus_req, NULL);
+        return;
+    }
+    tevent_req_set_callback(req,
+                            ifp_user_get_groups_names_resolved,
+                            state);
+}
+
+static void ifp_user_get_groups_names_resolved(struct tevent_req *req)
+{
+    struct ifp_user_get_groups_state *state;
+    struct ifp_attr_req *group_attr_req;
+    errno_t ret;
+
+    state = tevent_req_callback_data(req, struct ifp_user_get_groups_state);
+    group_attr_req = state->group_attr_req;
+
+    ret = resp_resolve_group_names_recv(state, req, &state->res_names);
+    talloc_zfree(req);
     if (ret != EOK) {
-        sbus_request_fail_and_finish(group_req->ireq->dbus_req,
-                               sbus_error_new(group_req->ireq->dbus_req,
-                                              DBUS_ERROR_FAILED,
-                                              "Failed to build a reply\n"));
+        sbus_request_fail_and_finish(group_attr_req->ireq->dbus_req,
+                            sbus_error_new(group_attr_req->ireq->dbus_req,
+                                           DBUS_ERROR_FAILED,
+                                           "Failed to resolve groupnames\n"));
+        return;
+    }
+
+    if (state->res_names == NULL) {
+        state->res_names = state->res;
+    }
+
+    ret = ifp_user_get_groups_reply(state->dom,
+                                    group_attr_req->ireq,
+                                    state->res_names);
+    if (ret != EOK) {
+        sbus_request_fail_and_finish(group_attr_req->ireq->dbus_req,
+                                     sbus_error_new(
+                                            group_attr_req->ireq->dbus_req,
+                                            DBUS_ERROR_FAILED,
+                                            "Failed to build a reply\n"));
         return;
     }
 }
-- 
2.9.4