>From 8f57214c3005beb5b9f42bb76ea57432d60a968b Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 22 Apr 2014 15:38:08 +0200 Subject: [PATCH 1/2] IFP: Get and list domain objects --- src/responder/ifp/ifp_iface.xml | 9 ++ src/responder/ifp/ifp_iface_generated.c | 46 ++++++++ src/responder/ifp/ifp_iface_generated.h | 10 ++ src/responder/ifp/ifp_private.h | 7 ++ src/responder/ifp/ifpsrv.c | 2 + src/responder/ifp/ifpsrv_cmd.c | 202 ++++++++++++++++++++++++++++++++ 6 files changed, 276 insertions(+) diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml index 4893e2df5bd23ff8c3a445e7a665b374586eb90f..af75ae88de060b731f14a01b2e99349719817aa9 100644 --- a/src/responder/ifp/ifp_iface.xml +++ b/src/responder/ifp/ifp_iface.xml @@ -21,5 +21,14 @@ + + + + + + + + + diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c index 0788787ce8b693209c635e995bff70ac77e8640c..1e0c8087d6f51e9dc144a359cbd93f81d7faab08 100644 --- a/src/responder/ifp/ifp_iface_generated.c +++ b/src/responder/ifp/ifp_iface_generated.c @@ -40,6 +40,38 @@ int infopipe_iface_GetUserGroups_finish(struct sbus_request *req, const char *ar DBUS_TYPE_INVALID); } +/* arguments for org.freedesktop.sssd.infopipe.FindDomainByName */ +const struct sbus_arg_meta infopipe_iface_FindDomainByName__in[] = { + { "name", "s" }, + { NULL, } +}; + +/* arguments for org.freedesktop.sssd.infopipe.FindDomainByName */ +const struct sbus_arg_meta infopipe_iface_FindDomainByName__out[] = { + { "domain", "o" }, + { NULL, } +}; + +int infopipe_iface_FindDomainByName_finish(struct sbus_request *req, const char *arg_domain) +{ + return sbus_request_return_and_finish(req, + DBUS_TYPE_OBJECT_PATH, &arg_domain, + DBUS_TYPE_INVALID); +} + +/* arguments for org.freedesktop.sssd.infopipe.ListDomains */ +const struct sbus_arg_meta infopipe_iface_ListDomains__out[] = { + { "domain", "ao" }, + { NULL, } +}; + +int infopipe_iface_ListDomains_finish(struct sbus_request *req, const char *arg_domain[], int len_domain) +{ + return sbus_request_return_and_finish(req, + DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_domain, len_domain, + DBUS_TYPE_INVALID); +} + /* methods for org.freedesktop.sssd.infopipe */ const struct sbus_method_meta infopipe_iface__methods[] = { { @@ -63,6 +95,20 @@ const struct sbus_method_meta infopipe_iface__methods[] = { offsetof(struct infopipe_iface, GetUserGroups), invoke_s_method, }, + { + "FindDomainByName", /* name */ + infopipe_iface_FindDomainByName__in, + infopipe_iface_FindDomainByName__out, + offsetof(struct infopipe_iface, FindDomainByName), + invoke_s_method, + }, + { + "ListDomains", /* name */ + NULL, /* no in_args */ + infopipe_iface_ListDomains__out, + offsetof(struct infopipe_iface, ListDomains), + NULL, /* no invoker */ + }, { NULL, } }; diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h index 9b92b9b071a85bc073f13114923c4cf4903d9bdf..ca0e1c3668f94ceb57c77306552866ff59370df4 100644 --- a/src/responder/ifp/ifp_iface_generated.h +++ b/src/responder/ifp/ifp_iface_generated.h @@ -16,6 +16,8 @@ #define INFOPIPE_IFACE_PING "Ping" #define INFOPIPE_IFACE_GETUSERATTR "GetUserAttr" #define INFOPIPE_IFACE_GETUSERGROUPS "GetUserGroups" +#define INFOPIPE_IFACE_FINDDOMAINBYNAME "FindDomainByName" +#define INFOPIPE_IFACE_LISTDOMAINS "ListDomains" /* ------------------------------------------------------------------------ * DBus handlers @@ -41,11 +43,19 @@ struct infopipe_iface { sbus_msg_handler_fn Ping; sbus_msg_handler_fn GetUserAttr; int (*GetUserGroups)(struct sbus_request *req, void *data, const char *arg_user); + int (*FindDomainByName)(struct sbus_request *req, void *data, const char *arg_name); + int (*ListDomains)(struct sbus_request *req, void *data); }; /* finish function for GetUserGroups */ int infopipe_iface_GetUserGroups_finish(struct sbus_request *req, const char *arg_values[], int len_values); +/* finish function for FindDomainByName */ +int infopipe_iface_FindDomainByName_finish(struct sbus_request *req, const char *arg_domain); + +/* finish function for ListDomains */ +int infopipe_iface_ListDomains_finish(struct sbus_request *req, const char *arg_domain[], int len_domain); + /* ------------------------------------------------------------------------ * DBus Interface Metadata * diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h index bf2015a9722ff4b4f831cb63cd528881f0f259a8..239172df739b284cd19534bcaccb0dc3962674d3 100644 --- a/src/responder/ifp/ifp_private.h +++ b/src/responder/ifp/ifp_private.h @@ -55,6 +55,13 @@ int ifp_user_get_attr(struct sbus_request *dbus_req, void *data); int ifp_user_get_groups(struct sbus_request *req, void *data, const char *arg_user); +#define INFOPIPE_DOM_INTERFACE "org.freedesktop.sssd.infopipe.Domains" +#define INFOPIPE_DOM_PATH "/org/freedesktop/sssd/infopipe/Domains" + +int ifp_list_domains(struct sbus_request *dbus_req, void *data); +int ifp_find_domain_by_name(struct sbus_request *dbus_req, + void *data, const char *arg_name); + /* == Utility functions == */ struct ifp_req { struct sbus_request *dbus_req; diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c index c6a50623a4d5ce87b9cc27c001734b88bbf32743..babd2b5849bb4b3eb631390c600a94386b731362 100644 --- a/src/responder/ifp/ifpsrv.c +++ b/src/responder/ifp/ifpsrv.c @@ -68,6 +68,8 @@ struct infopipe_iface ifp_iface = { .Ping = ifp_ping, .GetUserAttr = ifp_user_get_attr, .GetUserGroups = ifp_user_get_groups, + .ListDomains = ifp_list_domains, + .FindDomainByName = ifp_find_domain_by_name, }; struct sysbus_iface { diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c index 50483933188cfe9cf1a855bf3505f7e24a91b975..e8752fff707458ff105a707d330db2b4b04db8c9 100644 --- a/src/responder/ifp/ifpsrv_cmd.c +++ b/src/responder/ifp/ifpsrv_cmd.c @@ -24,6 +24,208 @@ #include "responder/ifp/ifp_private.h" +static void ifp_find_domain_by_name_process(struct tevent_req *req); + +struct ifp_get_domain_state { + const char *name; + struct ifp_req *ireq; +}; + +int ifp_find_domain_by_name(struct sbus_request *dbus_req, + void *data, const char *arg_name) +{ + struct ifp_ctx *ifp_ctx; + struct ifp_req *ireq; + struct tevent_req *req; + struct ifp_get_domain_state *state; + errno_t ret; + + ifp_ctx = talloc_get_type(data, struct ifp_ctx); + if (ifp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); + } + + ret = ifp_req_create(dbus_req, ifp_ctx, &ireq); + if (ret != EOK) { + return sbus_request_fail_and_finish(ireq->dbus_req, + sbus_error_new(ireq->dbus_req, + DBUS_ERROR_FAILED, + sss_strerror(ret))); + } + + state = talloc_zero(ireq, struct ifp_get_domain_state); + if (state == NULL) { + return sbus_request_finish(dbus_req, NULL); + } + state->name = arg_name; + state->ireq = ireq; + + req = sss_dp_get_domains_send(ireq, ifp_ctx->rctx, false, NULL); + if (req == NULL) { + return sbus_request_finish(dbus_req, NULL); + } + tevent_req_set_callback(req, ifp_find_domain_by_name_process, state); + return EOK; +} + + +static void ifp_find_domain_by_name_process(struct tevent_req *req) +{ + errno_t ret; + struct ifp_req *ireq; + struct ifp_get_domain_state *state; + struct sss_domain_info *iter; + const char *path; + + state = tevent_req_callback_data(req, struct ifp_get_domain_state); + ireq = state->ireq; + + ret = sss_dp_get_domains_recv(req); + talloc_free(req); + if (ret != EOK) { + sbus_request_fail_and_finish(ireq->dbus_req, + sbus_error_new(ireq->dbus_req, + DBUS_ERROR_FAILED, + "Failed to refresh domain objects\n")); + return; + } + + ret = sysdb_master_domain_update(ireq->ifp_ctx->rctx->domains); + if (ret != EOK) { + sbus_request_fail_and_finish(ireq->dbus_req, + sbus_error_new(ireq->dbus_req, + DBUS_ERROR_FAILED, + "Failed to refresh subdomain list\n")); + return; + } + + /* Reply with the domain that was asked for */ + for (iter = ireq->ifp_ctx->rctx->domains; + iter != NULL; + iter = get_next_domain(iter, true)) { + if (strcasecmp(iter->name, state->name) == 0) { + break; + } + } + + if (iter == NULL) { + sbus_request_fail_and_finish(ireq->dbus_req, + sbus_error_new(ireq->dbus_req, + DBUS_ERROR_FAILED, + "No such domain\n")); + return; + } + + path = ifp_reply_objpath(ireq, INFOPIPE_DOM_PATH, iter->name); + if (path == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Could not create path for dom %s, skipping\n", iter->name); + sbus_request_finish(ireq->dbus_req, NULL); + return; + } + + ret = infopipe_iface_FindDomainByName_finish(ireq->dbus_req, path); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Could not finish request!\n"); + } +} + +static void ifp_list_domains_process(struct tevent_req *req); + +int ifp_list_domains(struct sbus_request *dbus_req, void *data) +{ + struct ifp_ctx *ifp_ctx; + struct ifp_req *ireq; + struct tevent_req *req; + errno_t ret; + + ifp_ctx = talloc_get_type(data, struct ifp_ctx); + if (ifp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); + } + + ret = ifp_req_create(dbus_req, ifp_ctx, &ireq); + if (ret != EOK) { + return sbus_request_fail_and_finish(ireq->dbus_req, + sbus_error_new(ireq->dbus_req, + DBUS_ERROR_FAILED, + sss_strerror(ret))); + } + + req = sss_dp_get_domains_send(ireq, ifp_ctx->rctx, false, NULL); + if (req == NULL) { + return sbus_request_finish(dbus_req, NULL); + } + tevent_req_set_callback(req, ifp_list_domains_process, ireq); + return EOK; +} + +static void ifp_list_domains_process(struct tevent_req *req) +{ + errno_t ret; + struct ifp_req *ireq; + const char **paths; + char *p; + size_t num_domains; + size_t pi; + struct sss_domain_info *dom; + + ireq = tevent_req_callback_data(req, struct ifp_req); + + ret = sss_dp_get_domains_recv(req); + talloc_free(req); + if (ret != EOK) { + sbus_request_fail_and_finish(ireq->dbus_req, + sbus_error_new(ireq->dbus_req, + DBUS_ERROR_FAILED, + "Failed to refresh domain objects\n")); + return; + } + + ret = sysdb_master_domain_update(ireq->ifp_ctx->rctx->domains); + if (ret != EOK) { + sbus_request_fail_and_finish(ireq->dbus_req, + sbus_error_new(ireq->dbus_req, + DBUS_ERROR_FAILED, + "Failed to refresh subdomain list\n")); + return; + } + + num_domains = 0; + for (dom = ireq->ifp_ctx->rctx->domains; + dom != NULL; + dom = get_next_domain(dom, true)) { + num_domains++; + } + + paths = talloc_zero_array(ireq, const char *, num_domains); + if (paths == NULL) { + sbus_request_finish(ireq->dbus_req, NULL); + return; + } + + pi = 0; + for (dom = ireq->ifp_ctx->rctx->domains; + dom != NULL; + dom = get_next_domain(dom, true)) { + p = ifp_reply_objpath(ireq, INFOPIPE_DOM_PATH, dom->name); + if (p == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Could not create path for dom %s, skipping\n", dom->name); + continue; + } + paths[pi] = p; + pi++; + } + + ret = infopipe_iface_ListDomains_finish(ireq->dbus_req, paths, num_domains); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Could not finish request!\n"); + } +} + struct ifp_attr_req { const char *name; const char **attrs; -- 1.9.0