From 8214510f125879c3b1d247f2ce981ee20b5375d1 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Mon, 6 Jan 2014 15:15:40 +0100 Subject: IFP: Connect to the system bus Related: https://fedorahosted.org/sssd/ticket/2072 Adds the possibility for the InfoPipe responder to connect to the system bus. At the moment, only a dummy method "Ping" is provided. The method only accepts a single string parameter that has to be 'ping'. --- src/responder/ifp/ifp_iface.xml | 10 ++ src/responder/ifp/ifp_iface_generated.c | 25 +++++ src/responder/ifp/ifp_iface_generated.h | 49 +++++++++ src/responder/ifp/ifp_private.h | 14 +++ src/responder/ifp/ifpsrv.c | 110 ++++++++++++++++++++- src/responder/ifp/ifpsrv_cmd.c | 36 +++++++ .../ifp/org.freedesktop.sssd.infopipe.conf | 22 +++++ 7 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 src/responder/ifp/ifp_iface.xml create mode 100644 src/responder/ifp/ifp_iface_generated.c create mode 100644 src/responder/ifp/ifp_iface_generated.h create mode 100644 src/responder/ifp/org.freedesktop.sssd.infopipe.conf (limited to 'src/responder/ifp') diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml new file mode 100644 index 000000000..e3221b577 --- /dev/null +++ b/src/responder/ifp/ifp_iface.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c new file mode 100644 index 000000000..db5e0e545 --- /dev/null +++ b/src/responder/ifp/ifp_iface_generated.c @@ -0,0 +1,25 @@ +/* The following definitions are auto-generated from ifp_iface.xml */ + +#include "util/util.h" +#include "sbus/sssd_dbus.h" +#include "sbus/sssd_dbus_meta.h" +#include "ifp_iface_generated.h" + +/* methods for org.freedesktop.sssd.infopipe */ +const struct sbus_method_meta infopipe_iface__methods[] = { + { + "Ping", /* name */ + NULL, /* no in_args */ + NULL, /* no out_args */ + offsetof(struct infopipe_iface, Ping), + }, + { NULL, } +}; + +/* interface info for org.freedesktop.sssd.infopipe */ +const struct sbus_interface_meta infopipe_iface_meta = { + "org.freedesktop.sssd.infopipe", /* name */ + infopipe_iface__methods, + NULL, /* no signals */ + NULL, /* no propetries */ +}; diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h new file mode 100644 index 000000000..8db83fc11 --- /dev/null +++ b/src/responder/ifp/ifp_iface_generated.h @@ -0,0 +1,49 @@ +/* The following declarations are auto-generated from ifp_iface.xml */ + +#ifndef __IFP_IFACE_XML__ +#define __IFP_IFACE_XML__ + +#include "sbus/sssd_dbus.h" + +/* ------------------------------------------------------------------------ + * DBus Constants + * + * Various constants of interface and method names mostly for use by clients + */ + +/* constants for org.freedesktop.sssd.infopipe */ +#define INFOPIPE_IFACE "org.freedesktop.sssd.infopipe" +#define INFOPIPE_IFACE_PING "Ping" + +/* ------------------------------------------------------------------------ + * DBus Vtable handler structures + * + * These structures are filled in by implementors of the different + * dbus interfaces to handle method calls. + * + * Handler functions of type sbus_msg_handler_fn accept raw messages, + * other handlers will be typed appropriately. If a handler that is + * set to NULL is invoked it will result in a + * org.freedesktop.DBus.Error.NotSupported error for the caller. + */ + +/* vtable for org.freedesktop.sssd.infopipe */ +struct infopipe_iface { + struct sbus_vtable vtable; /* derive from sbus_vtable */ + sbus_msg_handler_fn Ping; +}; + +/* ------------------------------------------------------------------------ + * DBus Interface Metadata + * + * These structure definitions are filled in with the information about + * the interfaces, methods, properties and so on. + * + * The actual definitions are found in the accompanying C file next + * to this header. + */ + +/* interface info for org.freedesktop.sssd.infopipe */ +extern const struct sbus_interface_meta infopipe_iface_meta; + +#endif /* __IFP_IFACE_XML__ */ diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h index 32c7281ea..b97cb8a7d 100644 --- a/src/responder/ifp/ifp_private.h +++ b/src/responder/ifp/ifp_private.h @@ -26,10 +26,24 @@ #include "responder/common/responder.h" #include "providers/data_provider.h" +#include "responder/ifp/ifp_iface_generated.h" + +#define INFOPIPE_PATH "/org/freedesktop/sssd/infopipe" + +struct sysbus_ctx { + struct sbus_connection *conn; + char *introspect_xml; +}; struct ifp_ctx { struct resp_ctx *rctx; struct sss_names_ctx *snctx; + + struct sysbus_ctx *sysbus; }; +/* This is a throwaway method to ease the review of the patch. + * It will be removed later */ +int ifp_ping(struct sbus_request *dbus_req, void *data); + #endif /* _IFPSRV_PRIVATE_H_ */ diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c index 06434c328..accf679ef 100644 --- a/src/responder/ifp/ifpsrv.c +++ b/src/responder/ifp/ifpsrv.c @@ -61,6 +61,11 @@ static struct data_provider_iface ifp_dp_methods = { .getAccountInfo = NULL, }; +struct infopipe_iface ifp_iface = { + { &infopipe_iface_meta, 0 }, + .Ping = ifp_ping, +}; + struct sss_cmd_table *get_ifp_cmds(void) { static struct sss_cmd_table ifp_cmds[] = { @@ -97,6 +102,95 @@ static void ifp_dp_reconnect_init(struct sbus_connection *conn, be_conn->domain->name); } +static errno_t +sysbus_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + const char *dbus_name, + const char *dbus_path, + struct sbus_vtable *iface_vtable, + void *pvt, + struct sysbus_ctx **sysbus) +{ + DBusError dbus_error; + DBusConnection *conn = NULL; + struct sysbus_ctx *system_bus = NULL; + struct sbus_interface *sif; + errno_t ret; + + system_bus = talloc_zero(mem_ctx, struct sysbus_ctx); + if (system_bus == NULL) { + return ENOMEM; + } + + dbus_error_init(&dbus_error); + + /* Connect to the well-known system bus */ + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error); + if (conn == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Failed to connect to D-BUS system bus.\n")); + ret = EIO; + goto fail; + } + dbus_connection_set_exit_on_disconnect(conn, FALSE); + + ret = dbus_bus_request_name(conn, dbus_name, + /* We want exclusive access */ + DBUS_NAME_FLAG_DO_NOT_QUEUE, + &dbus_error); + if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + /* We were unable to register on the system bus */ + DEBUG(SSSDBG_CRIT_FAILURE, + ("Unable to request name on the system bus.\n")); + ret = EIO; + goto fail; + } + + DEBUG(SSSDBG_TRACE_FUNC, "Listening on %s\n", dbus_name); + + /* Integrate with tevent loop */ + ret = sbus_init_connection(system_bus, ev, conn, + SBUS_CONN_TYPE_SHARED, + &system_bus->conn); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not integrate D-BUS into mainloop.\n"); + goto fail; + } + + sif = sbus_new_interface(system_bus->conn, + dbus_path, + iface_vtable, + pvt); + if (sif == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not add the sbus interface\n"); + goto fail; + } + + ret = sbus_conn_add_interface(system_bus->conn, sif); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not add the interface\n"); + goto fail; + } + + *sysbus = system_bus; + return EOK; + +fail: + if (dbus_error_is_set(&dbus_error)) { + DEBUG(SSSDBG_OP_FAILURE, + "DBus error message: %s\n", dbus_error.message); + dbus_error_free(&dbus_error); + } + + if (conn) dbus_connection_unref(conn); + + talloc_free(system_bus); + return ret; +} + int ifp_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb) @@ -158,9 +252,23 @@ int ifp_process_init(TALLOC_CTX *mem_ctx, ifp_dp_reconnect_init, iter); } + /* Connect to the D-BUS system bus and set up methods */ + ret = sysbus_init(ifp_ctx, ifp_ctx->rctx->ev, + INFOPIPE_IFACE, + INFOPIPE_PATH, + &ifp_iface.vtable, + ifp_ctx, &ifp_ctx->sysbus); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Failed to connect to the system message bus\n"); + talloc_free(ifp_ctx); + return EIO; + } + ret = schedule_get_domains_task(rctx, rctx->ev, rctx); if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); + DEBUG(SSSDBG_FATAL_FAILURE, + "schedule_get_domains_tasks failed.\n"); goto fail; } diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c index b9641ff60..4f73342dd 100644 --- a/src/responder/ifp/ifpsrv_cmd.c +++ b/src/responder/ifp/ifpsrv_cmd.c @@ -30,3 +30,39 @@ struct cli_protocol_version *register_cli_protocol_version(void) return ssh_cli_protocol_version; } + +/* This is a throwaway method to ease the review of the patch. + * It will be removed later */ +int ifp_ping(struct sbus_request *dbus_req, void *data) +{ + struct ifp_ctx *ifp_ctx = talloc_get_type(data, struct ifp_ctx); + static const char *pong = "PONG"; + const char *request; + DBusError dberr; + + if (ifp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); + } + + + if (!sbus_request_parse_or_finish(dbus_req, + DBUS_TYPE_STRING, &request, + DBUS_TYPE_INVALID)) { + return EOK; /* handled */ + } + + DEBUG(SSSDBG_CONF_SETTINGS, "Got request for [%s]\n", request); + + if (strcasecmp(request, "ping") != 0) { + dbus_error_init(&dberr); + dbus_set_error_const(&dberr, + DBUS_ERROR_INVALID_ARGS, + "Ping() only accepts ping as a param\n"); + return sbus_request_fail_and_finish(dbus_req, &dberr); + } + + return sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_STRING, &pong, + DBUS_TYPE_INVALID); +} diff --git a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf new file mode 100644 index 000000000..fea847cee --- /dev/null +++ b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + -- cgit