summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2017-05-24 21:32:28 +0200
committerLukas Slebodnik <lslebodn@redhat.com>2017-05-31 14:32:06 +0200
commit95acbbb3fbfe972fecd3d8dcbc40d6b1d6b1d354 (patch)
tree86fe47c4d31f91bd8efe68e3e020f8d05b53c8fa
parentc59b7362644efb4546e7fae029b846b53bf48109 (diff)
downloadsssd-95acbbb3fbfe972fecd3d8dcbc40d6b1d6b1d354.tar.gz
sssd-95acbbb3fbfe972fecd3d8dcbc40d6b1d6b1d354.tar.xz
sssd-95acbbb3fbfe972fecd3d8dcbc40d6b1d6b1d354.zip
IFP: Resolve group names from GIDs if required
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>
-rw-r--r--src/responder/ifp/ifpsrv_cmd.c115
1 files changed, 89 insertions, 26 deletions
diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c
index 915f77e38..70728e1bb 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;
}
}