>From 5ef57784a8fb70877e1b200e8167d5e1164c0d36 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 23 Apr 2014 02:58:24 +0200 Subject: [PATCH 2/2] IFP: Implement two getters for domain objects --- src/responder/ifp/ifp_iface.xml | 7 ++ src/responder/ifp/ifp_iface_generated.c | 119 ++++++++++++++++++++++++++++++++ src/responder/ifp/ifp_iface_generated.h | 15 ++++ src/responder/ifp/ifp_private.h | 9 ++- src/responder/ifp/ifpsrv.c | 7 ++ src/responder/ifp/ifpsrv_cmd.c | 105 ++++++++++++++++++++++++++-- 6 files changed, 256 insertions(+), 6 deletions(-) diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml index af75ae88de060b731f14a01b2e99349719817aa9..5a3972d14e6962e84ce86c1d00fc646f4c253c01 100644 --- a/src/responder/ifp/ifp_iface.xml +++ b/src/responder/ifp/ifp_iface.xml @@ -31,4 +31,11 @@ + + + + + + + diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c index 1e0c8087d6f51e9dc144a359cbd93f81d7faab08..f353afae9e09e6c48841ee42e4847dbad4c4f152 100644 --- a/src/responder/ifp/ifp_iface_generated.c +++ b/src/responder/ifp/ifp_iface_generated.c @@ -7,6 +7,8 @@ /* invokes a handler with a 's' DBus signature */ static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_s(struct sbus_request *dbus_req, void *function_ptr); +static int invoke_get_b(struct sbus_request *dbus_req, void *function_ptr); /* arguments for org.freedesktop.sssd.infopipe.GetUserAttr */ const struct sbus_arg_meta infopipe_iface_GetUserAttr__in[] = { @@ -121,6 +123,95 @@ const struct sbus_interface_meta infopipe_iface_meta = { NULL, /* no GetAll invoker */ }; +/* invokes GetAll for the 'org.freedesktop.sssd.infopipe.Domain' interface */ +static int invoke_infopipe_domain_get_all(struct sbus_request *dbus_req, void *function_ptr) +{ + struct sbus_interface *intf = dbus_req->intf; + const struct sbus_property_meta *property; + DBusMessage *reply; + dbus_bool_t dbret; + DBusMessageIter iter; + DBusMessageIter iter_dict; + int ret; + const char * s_prop_val; + const char * s_out_val; + void (*s_handler)(struct sbus_request *, void *data, const char * *); + bool b_prop_val; + dbus_bool_t b_out_val; + void (*b_handler)(struct sbus_request *, void *data, bool *); + + reply = dbus_message_new_method_return(dbus_req->message); + if (!reply) return ENOMEM; + dbus_message_iter_init_append(reply, &iter); + dbret = dbus_message_iter_open_container( + &iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &iter_dict); + if (!dbret) return ENOMEM; + + property = sbus_meta_find_property(intf->vtable->meta, "name"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + s_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (s_handler) { + (s_handler)(dbus_req, dbus_req->intf->instance_data, &s_prop_val); + s_out_val = s_prop_val == NULL ? "" : s_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "name", DBUS_TYPE_STRING, &s_out_val); + if (ret != EOK) return ret; + } + } + + property = sbus_meta_find_property(intf->vtable->meta, "subdomain"); + if (property != NULL && property->flags & SBUS_PROPERTY_READABLE) { + b_handler = VTABLE_FUNC(intf->vtable, property->vtable_offset_get); + if (b_handler) { + (b_handler)(dbus_req, dbus_req->intf->instance_data, &b_prop_val); + b_out_val = b_prop_val; + ret = sbus_add_variant_to_dict(&iter_dict, "subdomain", DBUS_TYPE_BOOLEAN, &b_out_val); + if (ret != EOK) return ret; + } + } + + dbret = dbus_message_iter_close_container(&iter, &iter_dict); + if (!dbret) return ENOMEM; + + return sbus_request_finish(dbus_req, reply); +} + +/* property info for org.freedesktop.sssd.infopipe.Domain */ +const struct sbus_property_meta infopipe_domain__properties[] = { + { + "name", /* name */ + "s", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct infopipe_domain, infopipe_domain_get_name), + invoke_get_s, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { + "subdomain", /* name */ + "b", /* type */ + SBUS_PROPERTY_READABLE, + offsetof(struct infopipe_domain, infopipe_domain_get_subdomain), + invoke_get_b, + 0, /* not writable */ + NULL, /* no invoker */ + }, + { NULL, } +}; + +/* interface info for org.freedesktop.sssd.infopipe.Domain */ +const struct sbus_interface_meta infopipe_domain_meta = { + "org.freedesktop.sssd.infopipe.Domain", /* name */ + NULL, /* no methods */ + NULL, /* no signals */ + infopipe_domain__properties, + invoke_infopipe_domain_get_all, /* GetAll invoker */ +}; + /* invokes a handler with a 's' DBus signature */ static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr) { @@ -136,3 +227,31 @@ static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr) return (handler)(dbus_req, dbus_req->intf->instance_data, arg_0); } + +/* invokes a getter with a 'const char *' DBus type */ +static int invoke_get_s(struct sbus_request *dbus_req, void *function_ptr) +{ + const char * prop_val; + const char * out_val; + + void (*handler)(struct sbus_request *, void *data, const char * *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val == NULL ? "" : prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_STRING, &out_val); +} + +/* invokes a getter with a 'dbus_bool_t' DBus type */ +static int invoke_get_b(struct sbus_request *dbus_req, void *function_ptr) +{ + bool prop_val; + dbus_bool_t out_val; + + void (*handler)(struct sbus_request *, void *data, bool *) = function_ptr; + + (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val); + + out_val = prop_val; + return sbus_request_return_as_variant(dbus_req, DBUS_TYPE_BOOLEAN, &out_val); +} diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h index ca0e1c3668f94ceb57c77306552866ff59370df4..e88d9c969eb8b308277bf270ee91013f28857522 100644 --- a/src/responder/ifp/ifp_iface_generated.h +++ b/src/responder/ifp/ifp_iface_generated.h @@ -19,6 +19,11 @@ #define INFOPIPE_IFACE_FINDDOMAINBYNAME "FindDomainByName" #define INFOPIPE_IFACE_LISTDOMAINS "ListDomains" +/* constants for org.freedesktop.sssd.infopipe.Domain */ +#define INFOPIPE_DOMAIN "org.freedesktop.sssd.infopipe.Domain" +#define INFOPIPE_DOMAIN_NAME "name" +#define INFOPIPE_DOMAIN_SUBDOMAIN "subdomain" + /* ------------------------------------------------------------------------ * DBus handlers * @@ -56,6 +61,13 @@ int infopipe_iface_FindDomainByName_finish(struct sbus_request *req, const char /* finish function for ListDomains */ int infopipe_iface_ListDomains_finish(struct sbus_request *req, const char *arg_domain[], int len_domain); +/* vtable for org.freedesktop.sssd.infopipe.Domain */ +struct infopipe_domain { + struct sbus_vtable vtable; /* derive from sbus_vtable */ + void (*infopipe_domain_get_name)(struct sbus_request *, void *data, const char * *); + void (*infopipe_domain_get_subdomain)(struct sbus_request *, void *data, bool *); +}; + /* ------------------------------------------------------------------------ * DBus Interface Metadata * @@ -69,4 +81,7 @@ int infopipe_iface_ListDomains_finish(struct sbus_request *req, const char *arg_ /* interface info for org.freedesktop.sssd.infopipe */ extern const struct sbus_interface_meta infopipe_iface_meta; +/* interface info for org.freedesktop.sssd.infopipe.Domain */ +extern const struct sbus_interface_meta infopipe_domain_meta; + #endif /* __IFP_IFACE_XML__ */ diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h index 239172df739b284cd19534bcaccb0dc3962674d3..c556e61a1d82a1d76ff67ac53ee6bd6fc833819b 100644 --- a/src/responder/ifp/ifp_private.h +++ b/src/responder/ifp/ifp_private.h @@ -55,13 +55,18 @@ 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" +#define INFOPIPE_DOM_PATH_PFX "/org/freedesktop/sssd/infopipe/Domains" +#define INFOPIPE_DOM_PATH INFOPIPE_DOM_PATH_PFX"*" 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); +void ifp_dom_get_name(struct sbus_request *dbus_req, void *data, + const char **name); +void ifp_dom_get_subdomain(struct sbus_request *dbus_req, void *data, + bool *is_subdomain); + /* == 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 babd2b5849bb4b3eb631390c600a94386b731362..85dcd38914fb873e4500a2b6999f64f460d7d4b4 100644 --- a/src/responder/ifp/ifpsrv.c +++ b/src/responder/ifp/ifpsrv.c @@ -72,6 +72,12 @@ struct infopipe_iface ifp_iface = { .FindDomainByName = ifp_find_domain_by_name, }; +struct infopipe_domain ifp_domain = { + { &infopipe_domain_meta, 0 }, + .infopipe_domain_get_name = ifp_dom_get_name, + .infopipe_domain_get_subdomain = ifp_dom_get_subdomain +}; + struct sysbus_iface { const char *path; struct sbus_vtable *iface_vtable; @@ -79,6 +85,7 @@ struct sysbus_iface { static struct sysbus_iface ifp_ifaces[] = { { INFOPIPE_PATH, &ifp_iface.vtable }, + { INFOPIPE_DOM_PATH, &ifp_domain.vtable }, { NULL, NULL }, }; diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c index e8752fff707458ff105a707d330db2b4b04db8c9..8eb9e18fb162a9d4fe822150eb548bfb6d6573bf 100644 --- a/src/responder/ifp/ifpsrv_cmd.c +++ b/src/responder/ifp/ifpsrv_cmd.c @@ -24,6 +24,101 @@ #include "responder/ifp/ifp_private.h" +/* Object access handlers */ +static const char *domname_from_msgpath(const char *path) +{ + return ifp_path_strip_prefix(path, INFOPIPE_DOM_PATH_PFX"/"); +} + +static struct sss_domain_info *dom_by_name(struct ifp_ctx *ifp_ctx, + const char *name) +{ + struct sss_domain_info *iter; + + DEBUG(SSSDBG_TRACE_INTERNAL, "Looking for domain %s\n", name); + + for (iter = ifp_ctx->rctx->domains; + iter != NULL; + iter = get_next_domain(iter, true)) { + if (strcasecmp(iter->name, name) == 0) { + break; + } + } + + return iter; +} + +static void ifp_dom_get_prop_and_path(DBusMessage *message, + const char **path, + const char **property_name) +{ + DBusMessageIter iter; + const char *interface_name; + + dbus_message_iter_init(message, &iter); + dbus_message_iter_get_basic(&iter, &interface_name); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, property_name); + + *path = dbus_message_get_path(message); +} + +static struct sss_domain_info * +ifp_dom_getter_prep(struct sbus_request *dbus_req, + void *data) +{ + struct ifp_ctx *ifp_ctx = talloc_get_type(data, struct ifp_ctx); + const char *domname; + const char *path; + const char *property_name; + + if (ifp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); + return NULL; + } + + + ifp_dom_get_prop_and_path(dbus_req->message, &path, &property_name); + if (path == NULL || property_name == NULL) { + return NULL; + } + + domname = domname_from_msgpath(path); + if (domname == NULL) { + return NULL; + } + + return dom_by_name(ifp_ctx, domname); +} + +void ifp_dom_get_name(struct sbus_request *dbus_req, void *data, const char **name) +{ + struct sss_domain_info *dom; + + *name = NULL; + + dom = ifp_dom_getter_prep(dbus_req, data); + if (dom == NULL) { + return; + } + + *name = dom->name; +} + +void ifp_dom_get_subdomain(struct sbus_request *dbus_req, void *data, bool *is_subdomain) +{ + struct sss_domain_info *dom; + + *is_subdomain = NULL; + + dom = ifp_dom_getter_prep(dbus_req, data); + if (dom == NULL) { + return; + } + + *is_subdomain = dom->parent ? TRUE : FALSE; +} + static void ifp_find_domain_by_name_process(struct tevent_req *req); struct ifp_get_domain_state { @@ -48,9 +143,10 @@ int ifp_find_domain_by_name(struct sbus_request *dbus_req, 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, + return sbus_request_fail_and_finish(dbus_req, + sbus_error_new(dbus_req, DBUS_ERROR_FAILED, + "%s\n", sss_strerror(ret))); } @@ -117,7 +213,7 @@ static void ifp_find_domain_by_name_process(struct tevent_req *req) return; } - path = ifp_reply_objpath(ireq, INFOPIPE_DOM_PATH, iter->name); + path = ifp_reply_objpath(ireq, INFOPIPE_DOM_PATH_PFX, iter->name); if (path == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not create path for dom %s, skipping\n", iter->name); @@ -151,6 +247,7 @@ int ifp_list_domains(struct sbus_request *dbus_req, void *data) return sbus_request_fail_and_finish(ireq->dbus_req, sbus_error_new(ireq->dbus_req, DBUS_ERROR_FAILED, + "%s\n", sss_strerror(ret))); } @@ -210,7 +307,7 @@ static void ifp_list_domains_process(struct tevent_req *req) 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); + p = ifp_reply_objpath(ireq, INFOPIPE_DOM_PATH_PFX, dom->name); if (p == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not create path for dom %s, skipping\n", dom->name); -- 1.9.0