Hi, the attaches two patches implement DBus methods to retrieve SSSD domains using the system bus as well as two example getters that leverage the infrastructure to Get and GetAll the object properties.
Pavel, I know you have a large patchset in a private tree that implements the other getters and moves the domain methods into a separate file. I'm fine with merging your and mine patches, I just wanted to get the ball rolling on the list. Feel free to reply with your patchset.
>From 8f57214c3005beb5b9f42bb76ea57432d60a968b Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <[email protected]> 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 @@ <arg name="values" type="as" direction="out"/> </method> + <method name="FindDomainByName"> + <arg name="name" type="s" direction="in" /> + <arg name="domain" type="o" direction="out"/> + </method> + + <method name="ListDomains"> + <arg name="domain" type="ao" direction="out"/> + </method> + </interface> </node> 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
>From 5ef57784a8fb70877e1b200e8167d5e1164c0d36 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <[email protected]> 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 @@ </method> </interface> + + <interface name="org.freedesktop.sssd.infopipe.Domain"> + <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="infopipe_domain"/> + + <property name="name" type="s" access="read"/> + <property name="subdomain" type="b" access="read"/> + </interface> </node> 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
_______________________________________________ sssd-devel mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
