From cac78825ba2fcb2efcd7ff2e58b562b370bbb28c Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Mon, 30 Oct 2017 20:51:40 +0100 Subject: [PATCH 75/83] RESP: Expose DP method getAccountDomain() to responders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a tevent request that calls the getAccountDomain DP method. This request will be used by responders to locate an object's domain. At the moment, only looking up UIDs and GIDs is supported. Internally, until we switch to the rdp_ interface everywhere, this interface hooks into the sss_dp_issue_request(). When we switch to the rdp_ interface, we'll be able to provide a nicer method parameters as well. Reviewed-by: Pavel Březina Reviewed-by: Sumit Bose (cherry picked from commit 95fd82a4d7b50e64fed6906bc5345f271e8247d9) --- src/responder/common/responder.h | 36 +++++++ src/responder/common/responder_get_domains.c | 155 +++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 9a57df558994c418d440eabf4a29f69c4a47faa5..9400e4b60d9fc77c23710174e4c00a83f6395985 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -375,6 +375,42 @@ struct tevent_req *sss_dp_get_domains_send(TALLOC_CTX *mem_ctx, errno_t sss_dp_get_domains_recv(struct tevent_req *req); +/* + * Call a getAccountDomain request + * + * Only requests by ID are supported. + * + * @param mem_ctx Parent memory context + * @param rctx Responder context + * @param domain The SSSD domain we're querying. The response can + * be either NULL or come from any of domain's subdomains + * or domain itself + * @param type Either SSS_DP_USER or SSS_DP_GROUP, other types + * are not supported at the moment + * @param opt_id The ID number we're trying to locate + * + * @return A tevent request or NULL if allocating the request fails. + */ +struct tevent_req *sss_dp_get_account_domain_send(TALLOC_CTX *mem_ctx, + struct resp_ctx *rctx, + struct sss_domain_info *domain, + enum sss_dp_acct_type type, + uint32_t opt_id); + +/* Receive a getAccountDomain request result + * + * @param mem_ctx The memory context that will own the contents of _domain + * @param req The request that had finished + * @para _domain Either NULL (the request did not match any domain) or + * a string that corresponds to either the input domain + * or any of its subdomains + * + * @return EOK on success, errno otherwise + */ +errno_t sss_dp_get_account_domain_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_domain); + errno_t schedule_get_domains_task(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c index 4955af064040e03372e9a47fb264499d9a23b828..d69bce2300580beb42d3af8e66ff467db890f284 100644 --- a/src/responder/common/responder_get_domains.c +++ b/src/responder/common/responder_get_domains.c @@ -642,3 +642,158 @@ errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, return state->error; } + +/* ========== Get domain of an ccount ================= */ +struct sss_dp_get_account_domain_info { + struct sss_domain_info *dom; + enum sss_dp_acct_type type; + uint32_t opt_id; +}; + +static DBusMessage *sss_dp_get_account_domain_msg(void *pvt); + +struct tevent_req *sss_dp_get_account_domain_send(TALLOC_CTX *mem_ctx, + struct resp_ctx *rctx, + struct sss_domain_info *dom, + enum sss_dp_acct_type type, + uint32_t opt_id) +{ + struct tevent_req *req; + struct sss_dp_get_account_domain_info *info; + struct sss_dp_req_state *state; + char *key; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct sss_dp_req_state); + if (!req) { + return NULL; + } + + info = talloc_zero(state, struct sss_dp_get_account_domain_info); + if (info == NULL) { + ret = ENOMEM; + goto immediately; + } + info->type = type; + info->opt_id = opt_id; + info->dom = dom; + + key = talloc_asprintf(state, "%d: %"SPRIuid"@%s", type, opt_id, dom->name); + if (key == NULL) { + ret = ENOMEM; + goto immediately; + } + + ret = sss_dp_issue_request(state, rctx, key, dom, + sss_dp_get_account_domain_msg, + info, req); + talloc_free(key); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Could not issue DP request [%d]: %s\n", + ret, sss_strerror(ret)); + goto immediately; + } + + return req; + +immediately: + if (ret == EOK) { + tevent_req_done(req); + } else { + tevent_req_error(req, ret); + } + tevent_req_post(req, rctx->ev); + return req; +} + +static DBusMessage * +sss_dp_get_account_domain_msg(void *pvt) +{ + DBusMessage *msg; + dbus_bool_t dbret; + struct sss_dp_get_account_domain_info *info; + uint32_t entry_type; + char *filter; + + info = talloc_get_type(pvt, struct sss_dp_get_account_domain_info); + + switch (info->type) { + case SSS_DP_USER: + entry_type = BE_REQ_USER; + break; + case SSS_DP_GROUP: + entry_type = BE_REQ_GROUP; + break; + case SSS_DP_USER_AND_GROUP: + entry_type = BE_REQ_USER_AND_GROUP; + break; + default: + DEBUG(SSSDBG_OP_FAILURE, + "Unsupported lookup type %X for this request\n", info->type); + return NULL; + } + + filter = talloc_asprintf(info, "idnumber=%u", info->opt_id); + if (!filter) { + DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); + return NULL; + } + + msg = dbus_message_new_method_call(NULL, + DP_PATH, + IFACE_DP, + IFACE_DP_GETACCOUNTDOMAIN); + if (msg == NULL) { + talloc_free(filter); + DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); + return NULL; + } + + /* create the message */ + DEBUG(SSSDBG_TRACE_FUNC, + "Creating request for [%s][%#x][%s][%s:-]\n", + info->dom->name, entry_type, be_req2str(entry_type), filter); + + dbret = dbus_message_append_args(msg, + DBUS_TYPE_UINT32, &entry_type, + DBUS_TYPE_STRING, &filter, + DBUS_TYPE_INVALID); + talloc_free(filter); + if (!dbret) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n"); + dbus_message_unref(msg); + return NULL; + } + + return msg; +} + +errno_t sss_dp_get_account_domain_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + char **_domain) +{ + errno_t ret; + dbus_uint16_t err_maj; + dbus_uint32_t err_min; + char *msg; + + ret = sss_dp_req_recv(mem_ctx, req, &err_maj, &err_min, &msg); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Could not get account info [%d]: %s\n", + ret, sss_strerror(ret)); + return ret; + } + + if (err_maj != DP_ERR_OK) { + DEBUG(SSSDBG_OP_FAILURE, + "Data Provider Error: %u, %u\n", + (unsigned int)err_maj, (unsigned int)err_min); + talloc_free(msg); + return err_min ? err_min : EIO; + } + + *_domain = msg; + return EOK; +} -- 2.14.3