Blob Blame History Raw
From cac78825ba2fcb2efcd7ff2e58b562b370bbb28c Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
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 <pbrezina@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
(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