From 6fe2bfce9fb9bb1564be8257cccc52bcec589de4 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 24 Oct 2008 19:09:44 +0200 Subject: D-BUS integration style changes. Rework interfaces a bit to simplify and uniform function names so that they use a well defined namespace (sssd_*). Simplify headers file, split them into a private and a public one only. Make static all file private functions. Rename sssd_dbus_client.c to sssd_dbus_connection.c to reflect it's function, as it is is used by both a server and a client. Introduce a function table to know where to dipatch messages. Fix coding style issues, and start pointing out where clean-up fucntions are missing. --- server/dbus/sssd_dbus.h | 48 ++++++ server/dbus/sssd_dbus_client.c | 237 ----------------------------- server/dbus/sssd_dbus_client.h | 67 -------- server/dbus/sssd_dbus_common.c | 4 +- server/dbus/sssd_dbus_common.h | 14 -- server/dbus/sssd_dbus_connection.c | 303 +++++++++++++++++++++++++++++++++++++ server/dbus/sssd_dbus_private.h | 11 ++ server/dbus/sssd_dbus_server.c | 300 +++++++++++++++++++++++++----------- server/dbus/sssd_dbus_server.h | 69 --------- server/dbus/tests/test_client.c | 126 ++++++++++----- server/monitor.c | 167 +++++++++----------- server/monitor.h | 21 +-- server/server.mk | 11 +- 13 files changed, 737 insertions(+), 641 deletions(-) create mode 100644 server/dbus/sssd_dbus.h delete mode 100644 server/dbus/sssd_dbus_client.c delete mode 100644 server/dbus/sssd_dbus_client.h delete mode 100644 server/dbus/sssd_dbus_common.h create mode 100644 server/dbus/sssd_dbus_connection.c create mode 100644 server/dbus/sssd_dbus_private.h delete mode 100644 server/dbus/sssd_dbus_server.h diff --git a/server/dbus/sssd_dbus.h b/server/dbus/sssd_dbus.h new file mode 100644 index 000000000..00a665bc1 --- /dev/null +++ b/server/dbus/sssd_dbus.h @@ -0,0 +1,48 @@ +/* + SSSD + + SSSD - D-BUS interface + + Copyright (C) Stephen Gallagher 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _SSSD_DBUS_H_ +#define _SSSD_DBUS_H_ + +typedef int (*sssd_dbus_msg_handler_fn)(DBusMessage *msg, void *data, + DBusMessage **reply); + +struct sssd_dbus_method { + const char *method; + sssd_dbus_msg_handler_fn fn; +}; + +struct sssd_dbus_ctx { + struct event_context *ev; + char *name; + char *path; + struct sssd_dbus_method *methods; +}; + +/* Server Functions */ +int sssd_new_dbus_server(struct sssd_dbus_ctx *ctx, const char *address); + +/* Connection Functions */ +int sssd_new_dbus_connection(struct sssd_dbus_ctx *ctx, const char *address, + DBusConnection **connection); + + +#endif /* _SSSD_DBUS_H_*/ diff --git a/server/dbus/sssd_dbus_client.c b/server/dbus/sssd_dbus_client.c deleted file mode 100644 index 48f1ae456..000000000 --- a/server/dbus/sssd_dbus_client.c +++ /dev/null @@ -1,237 +0,0 @@ -#include "dbus/sssd_dbus_common.h" -#include "dbus/sssd_dbus_client.h" -#include "util/util.h" -#include -#include "events.h" - -const char* print_status(int status) { - switch (status){ - case DBUS_DISPATCH_DATA_REMAINS: - return "DBUS_DISPATCH_DATA_REMAINS"; - case DBUS_DISPATCH_COMPLETE: - return "DBUS_DISPATCH_COMPLETE"; - case DBUS_DISPATCH_NEED_MEMORY: - return "DBUS_DISPATCH_NEED_MEMORY"; - default: - return "ERROR"; - } -} - -void do_dispatch(struct event_context *ev, - struct timed_event *te, - struct timeval t, void *ptr) { - struct timed_event *new_event; - DBusConnection *conn = (DBusConnection *)ptr; - - /* Dispatch only once each time through the mainloop to avoid - * starving other features - */ - if(dbus_connection_get_dispatch_status(conn) != DBUS_DISPATCH_COMPLETE) { - DEBUG(2,("Dispatching.\n")); - dbus_connection_dispatch(conn); - } - /* If other dispatches are waiting, queue up the do_dispatch function - * for the next loop. - */ - if(dbus_connection_get_dispatch_status(conn) != DBUS_DISPATCH_COMPLETE) { - new_event = event_add_timed(ev, ev, t, do_dispatch, conn); - if (new_event == NULL) { - DEBUG(0,("Could not add dispatch event!\n")); - exit(1); - } - } -} - -/* - * integrate_connection_with_event_loop - * Set up a D-BUS connection to use the libevents mainloop - * for handling file descriptor and timed events - */ -int integrate_connection_with_event_loop(struct event_context *event_ctx, - DBusConnection *dbus_conn) { - struct dbus_connection_toplevel_context *dt_ctx; - dt_ctx = talloc_zero(event_ctx, struct dbus_connection_toplevel_context); - dt_ctx->ev = event_ctx; - dt_ctx->conn = dbus_conn; - - /* Set up DBusWatch functions */ - if (!dbus_connection_set_watch_functions(dt_ctx->conn, add_connection_watch, - remove_watch, toggle_connection_watch, dt_ctx, NULL)) { - DEBUG(0,("Error setting up D-BUS connection watch functions\n")); - return -1; - } - - /* Set up DBusTimeout functions */ - if (!dbus_connection_set_timeout_functions(dt_ctx->conn, add_connection_timeout, - remove_timeout, toggle_connection_timeout, dt_ctx, NULL)) { - DEBUG(0,("Error setting up D-BUS server timeout functions\n")); - return -1; - } - - /* Set up dispatch handler */ - dbus_connection_set_wakeup_main_function(dt_ctx->conn, - dbus_connection_wakeup_main, dt_ctx, NULL); - - /* Attempt to dispatch immediately in case of opportunistic - * services connecting before the handlers were all up. - * If there are no messages to be dispatched, this will do - * nothing. - */ - dbus_connection_wakeup_main(dt_ctx); - - return 0; -} - -/* - * add_connection_watch - * Set up hooks into the libevents mainloop for - * D-BUS to add file descriptor-based events - */ -dbus_bool_t add_connection_watch(DBusWatch *watch, void *data) { - unsigned int flags; - unsigned int event_flags; - struct dbus_connection_toplevel_context *dt_ctx; - struct dbus_connection_watch_context *conn_w_ctx; - - if (!dbus_watch_get_enabled(watch)) { - return TRUE; - } - - dt_ctx = talloc_get_type(data, struct dbus_connection_toplevel_context); - - conn_w_ctx = talloc_zero(dt_ctx, struct dbus_connection_watch_context); - conn_w_ctx->top = dt_ctx; - conn_w_ctx->watch = watch; - - flags = dbus_watch_get_flags(watch); - conn_w_ctx->fd = dbus_watch_get_unix_fd(watch); - - event_flags = 0; - - if (flags & DBUS_WATCH_READABLE) - event_flags |= EVENT_FD_READ; - - if (flags & DBUS_WATCH_WRITABLE) - event_flags |= EVENT_FD_WRITE; - - if (event_flags == 0) - return FALSE; - - /* Add the file descriptor to the event loop */ - conn_w_ctx->fde = event_add_fd(conn_w_ctx->top->ev, conn_w_ctx, conn_w_ctx->fd, - event_flags, dbus_connection_read_write_handler, conn_w_ctx); - - /* Save the event to the watch object so it can be removed later */ - dbus_watch_set_data(conn_w_ctx->watch,conn_w_ctx->fde,NULL); - - return TRUE; -} - - -/* - * toggle_connection_watch - * Hook for D-BUS to toggle the enabled/disabled state of - * an event in the mainloop - */ -void toggle_connection_watch(DBusWatch *watch, void *data) { - if (dbus_watch_get_enabled(watch)) - add_connection_watch(watch, data); - else - remove_watch(watch, data); -} - -/* - * add_connection_timeout - * Hook for D-BUS to add time-based events to the mainloop - */ -dbus_bool_t add_connection_timeout(DBusTimeout *timeout, void *data) { - struct dbus_connection_toplevel_context *dt_ctx; - struct dbus_connection_timeout_context *conn_t_ctx; - struct timeval tv; - - if (!dbus_timeout_get_enabled(timeout)) - return TRUE; - - dt_ctx = talloc_get_type(data, struct dbus_connection_toplevel_context); - - conn_t_ctx = talloc_zero(dt_ctx,struct dbus_connection_timeout_context); - conn_t_ctx->top = dt_ctx; - conn_t_ctx->timeout = timeout; - - tv = _dbus_timeout_get_interval_tv(dbus_timeout_get_interval(timeout)); - - struct timeval rightnow; - gettimeofday(&rightnow, NULL); - - conn_t_ctx->te = event_add_timed(conn_t_ctx->top->ev, conn_t_ctx, tv, - dbus_connection_timeout_handler, conn_t_ctx); - - /* Save the event to the watch object so it can be removed later */ - dbus_timeout_set_data(conn_t_ctx->timeout,conn_t_ctx->te,NULL); - - return TRUE; -} - -/* - * toggle_connection_timeout - * Hook for D-BUS to toggle the enabled/disabled state of a mainloop - * event - */ -void toggle_connection_timeout(DBusTimeout *timeout, void *data) { - if (dbus_timeout_get_enabled(timeout)) - add_connection_timeout(timeout, data); - else - remove_timeout(timeout, data); -} - -/* - * dbus_connection_read_write_handler - * Callback for D-BUS to handle messages on a file-descriptor - */ - -void dbus_connection_read_write_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *ptr) { - struct dbus_connection_watch_context *conn_w_ctx; - conn_w_ctx = talloc_get_type(ptr,struct dbus_connection_watch_context); - - dbus_connection_ref(conn_w_ctx->top->conn); - if (flags & EVENT_FD_READ) { - dbus_watch_handle(conn_w_ctx->watch, DBUS_WATCH_READABLE); - } - if (flags & EVENT_FD_WRITE) { - dbus_watch_handle(conn_w_ctx->watch, DBUS_WATCH_WRITABLE); - } - dbus_connection_ref(conn_w_ctx->top->conn); -} -/* - * dbus_connection_timeout_handler - * Callback for D-BUS to handle timed events - */ -void dbus_connection_timeout_handler(struct event_context *ev, struct timed_event *te, - struct timeval t, void *data) { - struct dbus_connection_timeout_context *conn_t_ctx; - conn_t_ctx = talloc_get_type(data, struct dbus_connection_timeout_context); - dbus_timeout_handle(conn_t_ctx->timeout); -} - -/* dbus_connection_wakeup_main - * D-BUS makes a callback to the wakeup_main function when - * it has data available for dispatching. - * In order to avoid blocking, this function will create a now() - * timed event to perform the dispatch during the next iteration - * through the mainloop - */ -void dbus_connection_wakeup_main(void *data) { - struct dbus_connection_toplevel_context *dct_ctx; - struct timeval tv; - struct timed_event *te; - dct_ctx = talloc_get_type(data, struct dbus_connection_toplevel_context); - gettimeofday(&tv, NULL); - - /* D-BUS calls this function when it is time to do a dispatch */ - te = event_add_timed(dct_ctx->ev, dct_ctx->ev, tv, do_dispatch, dct_ctx->conn); - if (te == NULL) { - DEBUG(0,("Could not add dispatch event!\n")); - exit(1); - } -} diff --git a/server/dbus/sssd_dbus_client.h b/server/dbus/sssd_dbus_client.h deleted file mode 100644 index 8e1bc876f..000000000 --- a/server/dbus/sssd_dbus_client.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef CLIENT_DBUS_H_ -#define CLIENT_DBUS_H_ -/* - SSSD - - Service monitor - D-BUS features - - Copyright (C) Stephen Gallagher 2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -#include "dbus/dbus.h" -#include "events.h" - -/* Types */ -struct dbus_connection_toplevel_context { - DBusConnection *conn; - struct event_context *ev; -}; - -struct dbus_connection_watch_context { - DBusWatch *watch; - int fd; - struct fd_event *fde; - struct dbus_connection_toplevel_context *top; -}; - -struct dbus_connection_timeout_context { - DBusTimeout *timeout; - struct timed_event *te; - struct dbus_connection_toplevel_context *top; -}; -/* Functions */ -int integrate_connection_with_event_loop(struct event_context *event_ctx, - DBusConnection *dbus_conn); -void dbus_connection_wakeup_main_setup(struct dbus_connection_toplevel_context *dct_ctx); - -dbus_bool_t add_connection_watch(DBusWatch *watch, void *data); -void toggle_connection_watch(DBusWatch *watch, void *data); - -dbus_bool_t add_connection_timeout(DBusTimeout *timeout, void *data); -void toggle_connection_timeout(DBusTimeout *timeout, void *data); -void dbus_connection_wakeup_main(void *data); - -void dbus_connection_read_write_handler(struct event_context *ev, struct fd_event *fde, uint16_t flags, void *ptr); -void dbus_connection_timeout_handler(struct event_context *ev, struct timed_event *te, struct timeval t, void *data); -void dbus_connection_wakeup_main_handler(struct event_context *ev_ctx, - struct signal_event *se, int signum, - int count, void *_info, void *data); - -void do_dispatch(struct event_context *ev, - struct timed_event *te, - struct timeval t, void *ptr); - -const char* print_status(int status); -#endif /*CLIENT_DBUS_H_*/ diff --git a/server/dbus/sssd_dbus_common.c b/server/dbus/sssd_dbus_common.c index 140d2f1a7..188192ddd 100644 --- a/server/dbus/sssd_dbus_common.c +++ b/server/dbus/sssd_dbus_common.c @@ -1,6 +1,6 @@ #include -#include "dbus/sssd_dbus_common.h" #include "events.h" +#include "dbus/dbus.h" struct timeval _dbus_timeout_get_interval_tv(int interval) { struct timeval tv; @@ -37,4 +37,4 @@ void remove_timeout(DBusTimeout *timeout, void *data) { /* Freeing the event object will remove it from the event loop */ talloc_free(te); -} \ No newline at end of file +} diff --git a/server/dbus/sssd_dbus_common.h b/server/dbus/sssd_dbus_common.h deleted file mode 100644 index e0683be8f..000000000 --- a/server/dbus/sssd_dbus_common.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef SSSD_DBUS_COMMON_H_ -#define SSSD_DBUS_COMMON_H_ - -#include "dbus/dbus.h" - -/* TODO: get this value from LDB */ -#define DBUS_ADDRESS "unix:path=/tmp/dbus-sgallagh.sock" - -/* Functions */ -struct timeval _dbus_timeout_get_interval_tv(int interval); -void remove_watch(DBusWatch *watch, void *data); -void remove_timeout(DBusTimeout *timeout, void *data); - -#endif /*SSSD_DBUS_COMMON_H_*/ diff --git a/server/dbus/sssd_dbus_connection.c b/server/dbus/sssd_dbus_connection.c new file mode 100644 index 000000000..f1675ff31 --- /dev/null +++ b/server/dbus/sssd_dbus_connection.c @@ -0,0 +1,303 @@ +#include +#include "events.h" +#include "util/util.h" +#include "dbus/dbus.h" +#include "dbus/sssd_dbus.h" +#include "dbus/sssd_dbus_private.h" + +/* Types */ +struct dbus_connection_toplevel_context { + DBusConnection *conn; + struct event_context *ev; +}; + +struct dbus_connection_watch_context { + DBusWatch *watch; + int fd; + struct fd_event *fde; + struct dbus_connection_toplevel_context *top; +}; + +struct dbus_connection_timeout_context { + DBusTimeout *timeout; + struct timed_event *te; + struct dbus_connection_toplevel_context *top; +}; + +static void do_dispatch(struct event_context *ev, + struct timed_event *te, + struct timeval tv, void *data) +{ + struct timed_event *new_event; + DBusConnection *conn; + int ret; + + conn = (DBusConnection *)data; + + /* Dispatch only once each time through the mainloop to avoid + * starving other features + */ + ret = dbus_connection_get_dispatch_status(conn); + if (ret != DBUS_DISPATCH_COMPLETE) { + DEBUG(2,("Dispatching.\n")); + dbus_connection_dispatch(conn); + } + /* If other dispatches are waiting, queue up the do_dispatch function + * for the next loop. + */ + ret = dbus_connection_get_dispatch_status(conn); + if (ret != DBUS_DISPATCH_COMPLETE) { + new_event = event_add_timed(ev, ev, tv, do_dispatch, conn); + if (new_event == NULL) { + DEBUG(0,("Could not add dispatch event!\n")); + exit(1); + } + } +} + +/* + * dbus_connection_read_write_handler + * Callback for D-BUS to handle messages on a file-descriptor + */ + +static void dbus_connection_read_write_handler(struct event_context *ev, + struct fd_event *fde, + uint16_t flags, void *data) +{ + struct dbus_connection_watch_context *conn_w_ctx; + conn_w_ctx = talloc_get_type(data, struct dbus_connection_watch_context); + + dbus_connection_ref(conn_w_ctx->top->conn); + if (flags & EVENT_FD_READ) { + dbus_watch_handle(conn_w_ctx->watch, DBUS_WATCH_READABLE); + } + if (flags & EVENT_FD_WRITE) { + dbus_watch_handle(conn_w_ctx->watch, DBUS_WATCH_WRITABLE); + } + dbus_connection_unref(conn_w_ctx->top->conn); +} + +/* + * add_connection_watch + * Set up hooks into the libevents mainloop for + * D-BUS to add file descriptor-based events + */ +static dbus_bool_t add_connection_watch(DBusWatch *watch, void *data) +{ + unsigned int flags; + unsigned int event_flags; + struct dbus_connection_toplevel_context *dt_ctx; + struct dbus_connection_watch_context *conn_w_ctx; + + if (!dbus_watch_get_enabled(watch)) { + return TRUE; + } + + dt_ctx = talloc_get_type(data, struct dbus_connection_toplevel_context); + + conn_w_ctx = talloc_zero(dt_ctx, struct dbus_connection_watch_context); + conn_w_ctx->top = dt_ctx; + conn_w_ctx->watch = watch; + + flags = dbus_watch_get_flags(watch); + conn_w_ctx->fd = dbus_watch_get_unix_fd(watch); + + event_flags = 0; + + if (flags & DBUS_WATCH_READABLE) + event_flags |= EVENT_FD_READ; + + if (flags & DBUS_WATCH_WRITABLE) + event_flags |= EVENT_FD_WRITE; + + if (event_flags == 0) + return FALSE; + + /* Add the file descriptor to the event loop */ + conn_w_ctx->fde = event_add_fd(conn_w_ctx->top->ev, conn_w_ctx, + conn_w_ctx->fd, event_flags, + dbus_connection_read_write_handler, + conn_w_ctx); + + /* Save the event to the watch object so it can be removed later */ + dbus_watch_set_data(conn_w_ctx->watch,conn_w_ctx->fde,NULL); + + return TRUE; +} + +/* + * toggle_connection_watch + * Hook for D-BUS to toggle the enabled/disabled state of + * an event in the mainloop + */ +static void toggle_connection_watch(DBusWatch *watch, void *data) +{ + if (dbus_watch_get_enabled(watch)) { + add_connection_watch(watch, data); + } else { + remove_watch(watch, data); + } +} + +/* + * dbus_connection_timeout_handler + * Callback for D-BUS to handle timed events + */ +static void dbus_connection_timeout_handler(struct event_context *ev, + struct timed_event *te, + struct timeval t, void *data) +{ + struct dbus_connection_timeout_context *conn_t_ctx; + conn_t_ctx = talloc_get_type(data, struct dbus_connection_timeout_context); + + dbus_timeout_handle(conn_t_ctx->timeout); +} + + +/* + * add_connection_timeout + * Hook for D-BUS to add time-based events to the mainloop + */ +static dbus_bool_t add_connection_timeout(DBusTimeout *timeout, void *data) +{ + struct dbus_connection_toplevel_context *dt_ctx; + struct dbus_connection_timeout_context *conn_t_ctx; + struct timeval tv; + + if (!dbus_timeout_get_enabled(timeout)) + return TRUE; + + dt_ctx = talloc_get_type(data, struct dbus_connection_toplevel_context); + + conn_t_ctx = talloc_zero(dt_ctx,struct dbus_connection_timeout_context); + conn_t_ctx->top = dt_ctx; + conn_t_ctx->timeout = timeout; + + tv = _dbus_timeout_get_interval_tv(dbus_timeout_get_interval(timeout)); + + struct timeval rightnow; + gettimeofday(&rightnow, NULL); + + conn_t_ctx->te = event_add_timed(conn_t_ctx->top->ev, conn_t_ctx, tv, + dbus_connection_timeout_handler, conn_t_ctx); + + /* Save the event to the watch object so it can be removed later */ + dbus_timeout_set_data(conn_t_ctx->timeout,conn_t_ctx->te,NULL); + + return TRUE; +} + +/* + * toggle_connection_timeout + * Hook for D-BUS to toggle the enabled/disabled state of a mainloop + * event + */ +void toggle_connection_timeout(DBusTimeout *timeout, void *data) +{ + if (dbus_timeout_get_enabled(timeout)) { + add_connection_timeout(timeout, data); + } else { + remove_timeout(timeout, data); + } +} + +/* dbus_connection_wakeup_main + * D-BUS makes a callback to the wakeup_main function when + * it has data available for dispatching. + * In order to avoid blocking, this function will create a now() + * timed event to perform the dispatch during the next iteration + * through the mainloop + */ +static void dbus_connection_wakeup_main(void *data) { + struct dbus_connection_toplevel_context *dct_ctx; + struct timeval tv; + struct timed_event *te; + dct_ctx = talloc_get_type(data, struct dbus_connection_toplevel_context); + gettimeofday(&tv, NULL); + + /* D-BUS calls this function when it is time to do a dispatch */ + te = event_add_timed(dct_ctx->ev, dct_ctx->ev, + tv, do_dispatch, dct_ctx->conn); + if (te == NULL) { + DEBUG(0,("Could not add dispatch event!\n")); + exit(1); + } +} + +/* + * integrate_connection_with_event_loop + * Set up a D-BUS connection to use the libevents mainloop + * for handling file descriptor and timed events + */ +int sssd_add_dbus_connection(struct sssd_dbus_ctx *ctx, + DBusConnection *dbus_conn) +{ + struct dbus_connection_toplevel_context *dt_ctx; + dbus_bool_t dbret; + + dt_ctx = talloc_zero(ctx, struct dbus_connection_toplevel_context); + dt_ctx->ev = ctx->ev; + dt_ctx->conn = dbus_conn; + + /* Set up DBusWatch functions */ + dbret = dbus_connection_set_watch_functions(dt_ctx->conn, + add_connection_watch, + remove_watch, + toggle_connection_watch, + dt_ctx, NULL); + if (!dbret) { + DEBUG(0,("Error setting up D-BUS connection watch functions\n")); + return EIO; + } + + /* Set up DBusTimeout functions */ + dbret = dbus_connection_set_timeout_functions(dt_ctx->conn, + add_connection_timeout, + remove_timeout, + toggle_connection_timeout, + dt_ctx, NULL); + if (!dbret) { + DEBUG(0,("Error setting up D-BUS server timeout functions\n")); + /* FIXME: free resources ? */ + return EIO; + } + + /* Set up dispatch handler */ + dbus_connection_set_wakeup_main_function(dt_ctx->conn, + dbus_connection_wakeup_main, + dt_ctx, NULL); + + /* Attempt to dispatch immediately in case of opportunistic + * services connecting before the handlers were all up. + * If there are no messages to be dispatched, this will do + * nothing. + */ + dbus_connection_wakeup_main(dt_ctx); + + return EOK; +} + +int sssd_new_dbus_connection(struct sssd_dbus_ctx *ctx, const char *address, + DBusConnection **connection) +{ + DBusConnection *dbus_conn; + DBusError dbus_error; + int ret; + + dbus_error_init(&dbus_error); + dbus_conn = dbus_connection_open(address, &dbus_error); + if (!dbus_conn) { + DEBUG(0, ("Failed to open connection: name=%s, message=%s\n", + dbus_error.name, dbus_error.message)); + return EIO; + } + + ret = sssd_add_dbus_connection(ctx, dbus_conn); + if (ret == EOK) { + *connection = dbus_conn; + } else { + /* FIXME: release resources */ + } + + return ret; +} diff --git a/server/dbus/sssd_dbus_private.h b/server/dbus/sssd_dbus_private.h new file mode 100644 index 000000000..ae3540bd5 --- /dev/null +++ b/server/dbus/sssd_dbus_private.h @@ -0,0 +1,11 @@ +#ifndef _SSSD_DBUS_PRIVATE_H_ +#define _SSSD_DBUS_PRIVATE_H_ + +int sssd_add_dbus_connection(struct sssd_dbus_ctx *ctx, + DBusConnection *dbus_conn); + +struct timeval _dbus_timeout_get_interval_tv(int interval); +void remove_watch(DBusWatch *watch, void *data); +void remove_timeout(DBusTimeout *timeout, void *data); + +#endif /* _SSSD_DBUS_PRIVATE_H_ */ diff --git a/server/dbus/sssd_dbus_server.c b/server/dbus/sssd_dbus_server.c index 288a33338..113866fa6 100644 --- a/server/dbus/sssd_dbus_server.c +++ b/server/dbus/sssd_dbus_server.c @@ -19,73 +19,50 @@ along with this program. If not, see . */ #include -#include "dbus/dbus.h" -#include "monitor.h" -#include "dbus/sssd_dbus_common.h" -#include "dbus/sssd_dbus_server.h" -#include "dbus/sssd_dbus_client.h" #include "events.h" #include "util/util.h" +#include "dbus/dbus.h" +#include "dbus/sssd_dbus.h" +#include "dbus/sssd_dbus_private.h" + +/* Types */ +struct dbus_server_toplevel_context { + DBusServer *server; + struct sssd_dbus_ctx *sd_ctx; +}; + +struct dbus_server_watch_context { + DBusWatch *watch; + int fd; + struct fd_event *fde; + struct dbus_server_toplevel_context *top; +}; + +struct dbus_server_timeout_context { + DBusTimeout *timeout; + struct timed_event *te; + struct dbus_server_toplevel_context *top; +}; /* - * integrate_server_with_event_loop - * Set up a D-BUS server to use the libevents mainloop - * for handling file descriptor and timed events + * dbus_server_read_write_handler + * Callback for D-BUS to handle messages on a file-descriptor */ -int integrate_server_with_event_loop(struct event_context *event_ctx, - DBusServer *dbus_server, - void(*server_connection_setup)(DBusConnection *conn, struct event_context *)) { - struct dbus_server_toplevel_context *dt_ctx; - dt_ctx = talloc_zero(event_ctx, struct dbus_server_toplevel_context); - dt_ctx->ev = event_ctx; - dt_ctx->server = dbus_server; - dt_ctx->server_connection_setup = server_connection_setup; - - /* Set up D-BUS new connection handler */ - dbus_server_set_new_connection_function(dt_ctx->server, - new_connection_callback, dt_ctx, NULL); - - /* Set up DBusWatch functions */ - if (!dbus_server_set_watch_functions(dt_ctx->server, add_server_watch, - remove_watch, toggle_server_watch, dt_ctx, NULL)) { - DEBUG(0,("Error setting up D-BUS server watch functions")); - return -1; - } +static void dbus_server_read_write_handler(struct event_context *ev, + struct fd_event *fde, + uint16_t flags, void *data) +{ + struct dbus_server_watch_context *svw_ctx; + svw_ctx = talloc_get_type(data, struct dbus_server_watch_context); - /* Set up DBusTimeout functions */ - if (!dbus_server_set_timeout_functions(dt_ctx->server, add_server_timeout, - remove_timeout, toggle_server_timeout, dt_ctx, NULL)) { - DEBUG(0,("Error setting up D-BUS server timeout functions")); - return -1; + dbus_server_ref(svw_ctx->top->server); + if (flags & EVENT_FD_READ) { + dbus_watch_handle(svw_ctx->watch, DBUS_WATCH_READABLE); } - - return 0; -} - -/* - * new_connection_callback - * Actions to be run upon each new client connection - * Must either perform dbus_connection_ref() on the - * new connection or else close the connection with - * dbus_connection_close() - */ -void new_connection_callback(DBusServer *server, - DBusConnection *new_connection, void *data) { - - struct dbus_server_toplevel_context *dst_ctx; - dst_ctx = talloc_get_type(data,struct dbus_server_toplevel_context); - - if(integrate_connection_with_event_loop(dst_ctx->ev,new_connection) != 0) { - dbus_connection_close(new_connection); - DEBUG(0,("Closing connection (failed setup)")); - return; + if (flags & EVENT_FD_WRITE) { + dbus_watch_handle(svw_ctx->watch, DBUS_WATCH_WRITABLE); } - dbus_connection_ref(new_connection); - - /* Run connection setup function */ - DEBUG(3,("Got a connection\n")); - dst_ctx->server_connection_setup(new_connection, dst_ctx->ev); - DEBUG(3,("New connection set up.\n")); + dbus_server_unref(svw_ctx->top->server); } /* @@ -93,7 +70,8 @@ void new_connection_callback(DBusServer *server, * Set up hooks into the libevents mainloop for * D-BUS to add file descriptor-based events */ -dbus_bool_t add_server_watch(DBusWatch *watch, void *data) { +static dbus_bool_t add_server_watch(DBusWatch *watch, void *data) +{ unsigned int flags; unsigned int event_flags; struct dbus_server_toplevel_context *dt_ctx; @@ -121,11 +99,13 @@ dbus_bool_t add_server_watch(DBusWatch *watch, void *data) { if (flags & DBUS_WATCH_WRITABLE) { event_flags |= EVENT_FD_WRITE; } - svw_ctx->fde = event_add_fd(svw_ctx->top->ev, svw_ctx, svw_ctx->fd, - event_flags, dbus_server_read_write_handler, svw_ctx); + + svw_ctx->fde = event_add_fd(dt_ctx->sd_ctx->ev, svw_ctx, svw_ctx->fd, + event_flags, dbus_server_read_write_handler, + svw_ctx); /* Save the event to the watch object so it can be removed later */ - dbus_watch_set_data(svw_ctx->watch,svw_ctx->fde,NULL); + dbus_watch_set_data(svw_ctx->watch, svw_ctx->fde, NULL); return TRUE; } @@ -135,18 +115,30 @@ dbus_bool_t add_server_watch(DBusWatch *watch, void *data) { * Hook for D-BUS to toggle the enabled/disabled state of * an event in the mainloop */ -void toggle_server_watch(DBusWatch *watch, void *data) { - if (dbus_watch_get_enabled(watch)) +static void toggle_server_watch(DBusWatch *watch, void *data) +{ + if (dbus_watch_get_enabled(watch)) { add_server_watch(watch, data); - else + } else { remove_watch(watch, data); + } +} + +static void dbus_server_timeout_handler(struct event_context *ev, + struct timed_event *te, + struct timeval t, void *data) +{ + struct dbus_server_timeout_context *svt_ctx; + svt_ctx = talloc_get_type(data, struct dbus_server_timeout_context); + dbus_timeout_handle(svt_ctx->timeout); } /* * add_server_timeout * Hook for D-BUS to add time-based events to the mainloop */ -dbus_bool_t add_server_timeout(DBusTimeout *timeout, void *data) { +static dbus_bool_t add_server_timeout(DBusTimeout *timeout, void *data) +{ struct dbus_server_toplevel_context *dt_ctx; struct dbus_server_timeout_context *svt_ctx; struct timeval tv; @@ -162,11 +154,11 @@ dbus_bool_t add_server_timeout(DBusTimeout *timeout, void *data) { tv = _dbus_timeout_get_interval_tv(dbus_timeout_get_interval(timeout)); - svt_ctx->te = event_add_timed(svt_ctx->top->ev, svt_ctx, tv, - dbus_server_timeout_handler, svt_ctx); + svt_ctx->te = event_add_timed(dt_ctx->sd_ctx->ev, svt_ctx, tv, + dbus_server_timeout_handler, svt_ctx); /* Save the event to the watch object so it can be removed later */ - dbus_timeout_set_data(svt_ctx->timeout,svt_ctx->te,NULL); + dbus_timeout_set_data(svt_ctx->timeout, svt_ctx->te, NULL); return TRUE; } @@ -176,35 +168,161 @@ dbus_bool_t add_server_timeout(DBusTimeout *timeout, void *data) { * Hook for D-BUS to toggle the enabled/disabled state of a mainloop * event */ -void toggle_server_timeout(DBusTimeout *timeout, void *data) { - if (dbus_timeout_get_enabled(timeout)) +static void toggle_server_timeout(DBusTimeout *timeout, void *data) +{ + if (dbus_timeout_get_enabled(timeout)) { add_server_timeout(timeout, data); - else + } else { remove_timeout(timeout, data); + } } -/* - * dbus_server_read_write_handler - * Callback for D-BUS to handle messages on a file-descriptor +/* messsage_handler + * Receive messages and process them */ -void dbus_server_read_write_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *ptr) { - struct dbus_server_watch_context *svw_ctx; - svw_ctx = talloc_get_type(ptr,struct dbus_server_watch_context); +static DBusHandlerResult message_handler(DBusConnection *conn, + DBusMessage *message, + void *user_data) +{ + struct sssd_dbus_ctx *ctx; + const char *method; + const char *path; + const char *msg_interface; + DBusMessage *reply = NULL; + int i, ret; + + ctx = talloc_get_type(user_data, struct sssd_dbus_ctx); + + method = dbus_message_get_member(message); + path = dbus_message_get_path(message); + msg_interface = dbus_message_get_interface(message); + + if (!method || !path || !msg_interface) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + /* Validate the method interface */ + if (strcmp(msg_interface, ctx->name) != 0) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + /* Validate the D-BUS path */ + if (strcmp(path, ctx->path) == 0) { + for (i = 0; ctx->methods[i].method != NULL; i++) { + if (strcmp(method, ctx->methods[i].method) == 0) { + ret = ctx->methods[i].fn(message, ctx, &reply); + /* FIXME: check error */ + break; + } + } + /* FIXME: check if we didn't find any matching method */ + } - dbus_server_ref(svw_ctx->top->server); - if (flags & EVENT_FD_READ) { - dbus_watch_handle(svw_ctx->watch, DBUS_WATCH_READABLE); + if (reply) { + dbus_connection_send(conn, reply, NULL); + dbus_message_unref(reply); } - if (flags & EVENT_FD_WRITE) { - dbus_watch_handle(svw_ctx->watch, DBUS_WATCH_WRITABLE); + + return reply ? DBUS_HANDLER_RESULT_HANDLED : + DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +/* + * new_connection_callback + * Actions to be run upon each new client connection + * Must either perform dbus_connection_ref() on the + * new connection or else close the connection with + * dbus_connection_close() + */ +static void new_connection_callback(DBusServer *server, DBusConnection *conn, + void *data) +{ + struct dbus_server_toplevel_context *dst_ctx; + DBusObjectPathVTable *monitor_vtable; + int ret; + + dst_ctx = talloc_get_type(data,struct dbus_server_toplevel_context); + + ret = sssd_add_dbus_connection(dst_ctx->sd_ctx, conn); + if (ret != 0) { + dbus_connection_close(conn); + DEBUG(0,("Closing connection (failed setup)")); + return; } - dbus_server_ref(svw_ctx->top->server); + + dbus_connection_ref(conn); + + DEBUG(3,("Got a connection\n")); + + monitor_vtable = talloc_zero(dst_ctx, DBusObjectPathVTable); + + DEBUG (3,("Initializing D-BUS methods.\n")); + monitor_vtable->message_function = message_handler; + + dbus_connection_register_object_path(conn, dst_ctx->sd_ctx->path, + monitor_vtable, dst_ctx->sd_ctx); + + DEBUG(3,("D-BUS method initialization complete.\n")); } -void dbus_server_timeout_handler(struct event_context *ev, struct timed_event *te, - struct timeval t, void *data) { - struct dbus_server_timeout_context *svt_ctx; - svt_ctx = talloc_get_type(data, struct dbus_server_timeout_context); - dbus_timeout_handle(svt_ctx->timeout); +/* + * dbus_new_server + * Set up a D-BUS server, integrate with the event loop + * for handling file descriptor and timed events + */ +int sssd_new_dbus_server(struct sssd_dbus_ctx *ctx, const char *address) +{ + struct dbus_server_toplevel_context *dt_ctx; + DBusServer *dbus_server; + DBusError dbus_error; + dbus_bool_t dbret; + + /* Set up D-BUS server */ + dbus_error_init(&dbus_error); + dbus_server = dbus_server_listen(address, &dbus_error); + if (!dbus_server) { + DEBUG(0,("dbus_server_listen failed! (name=%s, message=%s)\n", + dbus_error.name, dbus_error.message)); + return EIO; + } + + /* TODO: remove debug */ + DEBUG(2, ("D-BUS Server listening on %s\n", + dbus_server_get_address(dbus_server))); + + dt_ctx = talloc_zero(ctx, struct dbus_server_toplevel_context); + if (!dt_ctx) { + /* FIXME: free DBusServer resources */ + return ENOMEM; + } + dt_ctx->server = dbus_server; + dt_ctx->sd_ctx = ctx; + + /* Set up D-BUS new connection handler */ + /* FIXME: set free_data_function */ + dbus_server_set_new_connection_function(dt_ctx->server, + new_connection_callback, + dt_ctx, NULL); + + /* Set up DBusWatch functions */ + dbret = dbus_server_set_watch_functions(dt_ctx->server, add_server_watch, + remove_watch, toggle_server_watch, + dt_ctx, NULL); + if (!dbret) { + DEBUG(0, ("Error setting up D-BUS server watch functions")); + /* FIXME: free DBusServer resources */ + return EIO; + } + + /* Set up DBusTimeout functions */ + dbret = dbus_server_set_timeout_functions(dt_ctx->server, + add_server_timeout, + remove_timeout, + toggle_server_timeout, + dt_ctx, NULL); + if (!dbret) { + DEBUG(0,("Error setting up D-BUS server timeout functions")); + /* FIXME: free DBusServer resources */ + return EIO; + } + + return EOK; } diff --git a/server/dbus/sssd_dbus_server.h b/server/dbus/sssd_dbus_server.h deleted file mode 100644 index 85fc12c6a..000000000 --- a/server/dbus/sssd_dbus_server.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - SSSD - - Service monitor - D-BUS features - - Copyright (C) Stephen Gallagher 2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef MONITORDBUS_H_ -#define MONITORDBUS_H_ - -#include "dbus/dbus.h" -#include "monitor.h" -#include "events.h" -#include "sssd_dbus_common.h" - -/* Types */ -struct dbus_server_toplevel_context { - DBusServer *server; - struct event_context *ev; - void (*server_connection_setup)(DBusConnection *conn, struct event_context *); -}; - -struct dbus_server_watch_context { - DBusWatch *watch; - int fd; - struct fd_event *fde; - struct dbus_server_toplevel_context *top; -}; - -struct dbus_server_timeout_context { - DBusTimeout *timeout; - struct timed_event *te; - struct dbus_server_toplevel_context *top; -}; - -/* Functions */ -int integrate_server_with_event_loop( - struct event_context *event_ctx, - DBusServer *dbus_server, - void (*server_connection_setup)(DBusConnection *conn, struct event_context *) -); - -void new_connection_callback(DBusServer *server, - DBusConnection *new_connection, void *data); - -dbus_bool_t add_server_watch(DBusWatch *watch, void *data); -void toggle_server_watch(DBusWatch *watch, void *data); - -dbus_bool_t add_server_timeout(DBusTimeout *timeout, void *data); -void toggle_server_timeout(DBusTimeout *timeout, void *data); - -void dbus_server_read_write_handler(struct event_context *ev, struct fd_event *fde, uint16_t flags, void *ptr); -void dbus_server_timeout_handler(struct event_context *ev, struct timed_event *te, struct timeval t, void *data); - -#endif /*MONITORDBUS_H_*/ diff --git a/server/dbus/tests/test_client.c b/server/dbus/tests/test_client.c index 8a82284c8..30401991d 100644 --- a/server/dbus/tests/test_client.c +++ b/server/dbus/tests/test_client.c @@ -2,16 +2,27 @@ #include #include #include "events.h" -#include "dbus/dbus.h" -#include "monitor.h" -#include "dbus/sssd_dbus_common.h" -#include "dbus/sssd_dbus_client.h" #include "util/util.h" +#include "dbus/dbus.h" +#include "dbus/sssd_dbus.h" -static void request_version_timed(struct event_context *ev, - DBusConnection *conn); +/* TODO: get this value from LDB */ +#define DBUS_ADDRESS "unix:path=/var/lib/sss/pipes/private/dbus" -static void print_version (DBusPendingCall *pending, void *ptr) { +/* Monitor Interface */ +#define MONITOR_DBUS_INTERFACE "org.freeipa.sssd.monitor" +#define MONITOR_DBUS_PATH "/org/freeipa/sssd/monitor" +#define MONITOR_METHOD_VERSION "getVersion" + +struct test_cli_ctx { + struct sssd_dbus_ctx *sd_ctx; + DBusConnection *conn; +}; + +static void request_version_timed(struct test_cli_ctx *ctx); + +static void print_version(DBusPendingCall *pending, void *data) +{ DBusMessage *reply; DBusError error; const char *version_string; @@ -25,25 +36,27 @@ static void print_version (DBusPendingCall *pending, void *ptr) { * until reply is valid. If reply is NULL here, something is seriously * wrong and we should bail out. */ - DEBUG(0,("Serious error. A reply callback was called but no reply was received")); + DEBUG(0, ("Serious error. A reply callback was called but no reply was received")); exit(3); } type = dbus_message_get_type(reply); - if (type == DBUS_MESSAGE_TYPE_METHOD_RETURN) { - if(dbus_message_get_args(reply, &error, DBUS_TYPE_STRING, &version_string, DBUS_TYPE_INVALID)) { + switch (type) { + case DBUS_MESSAGE_TYPE_METHOD_RETURN: + if (dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, + &version_string, + DBUS_TYPE_INVALID)) { fprintf(stdout, "Version: %s\n", version_string); fflush(stdout); - } - else { + } else { DEBUG(0, ("Error getting arguments in print_version")); } - } - else if (type == DBUS_MESSAGE_TYPE_ERROR) { - - } - else { + break; + case DBUS_MESSAGE_TYPE_ERROR: + break; + default: DEBUG(0, ("Received unexpected message")); exit(4); } @@ -51,22 +64,29 @@ static void print_version (DBusPendingCall *pending, void *ptr) { static void test_timed_handler(struct event_context *ev, struct timed_event *te, - struct timeval t, void *ptr) { - DBusConnection *conn; + struct timeval tv, void *data) +{ + struct test_cli_ctx *test_ctx; + struct sssd_dbus_ctx *ctx; DBusPendingCall *pending_reply; - DBusMessage *version_request; + DBusMessage *vmsg; DBusError error; - conn = (DBusConnection *) ptr; + dbus_bool_t dbret; + + test_ctx = talloc_get_type(data, struct test_cli_ctx); + ctx = test_ctx->sd_ctx; fprintf(stdout, "."); fflush(stdout); dbus_error_init(&error); - version_request = dbus_message_new_method_call( - NULL, MONITOR_DBUS_PATH, MONITOR_DBUS_INTERFACE, - MONITOR_METHOD_VERSION); + vmsg = dbus_message_new_method_call(NULL, + ctx->path, ctx->name, + MONITOR_METHOD_VERSION); - if(!dbus_connection_send_with_reply(conn, version_request, &pending_reply, -1)){ + dbret = dbus_connection_send_with_reply(test_ctx->conn, vmsg, + &pending_reply, -1); + if (!dbret) { /* Critical failure */ DEBUG(0,("Failed to send version_request")); exit(2); @@ -74,50 +94,76 @@ static void test_timed_handler(struct event_context *ev, dbus_pending_call_set_notify(pending_reply, print_version, NULL, NULL); - dbus_message_unref(version_request); + dbus_message_unref(vmsg); - request_version_timed(ev,conn); + request_version_timed(test_ctx); } -static void request_version_timed(struct event_context *ev, DBusConnection *conn) { +static void request_version_timed(struct test_cli_ctx *ctx) +{ struct timed_event *te = NULL; struct timeval tv; gettimeofday(&tv, NULL); tv.tv_sec += 5; tv.tv_usec = 0; - te = event_add_timed(ev, ev, tv, test_timed_handler, conn); + te = event_add_timed(ctx->sd_ctx->ev, ctx, tv, test_timed_handler, ctx); if (te == NULL) { DEBUG(0, ("failed to add event!\n")); exit(1); } } -int main (int argc, const char *argv[]) { - DBusError dbus_error; - DBusConnection *dbus_conn; +int main (int argc, const char *argv[]) +{ struct event_context *event_ctx; + struct sssd_dbus_ctx *ctx; + struct test_cli_ctx *test_ctx; + DBusConnection *dbus_conn; + int ret; event_ctx = event_context_init(talloc_autofree_context()); + if (!event_ctx) { + printf("Out of memory!?\n"); + exit(1); + } + + ctx = talloc_zero(event_ctx, struct sssd_dbus_ctx); + if (!ctx) { + printf("Out of memory!?\n"); + exit(1); + } + ctx->ev = event_ctx; + ctx->name = talloc_strdup(ctx, MONITOR_DBUS_INTERFACE); + ctx->path = talloc_strdup(ctx, MONITOR_DBUS_PATH); + if (!ctx->name || !ctx->path) { + printf("Out of memory!?\n"); + exit(1); + } + + ret = sssd_new_dbus_connection(ctx, DBUS_ADDRESS, &dbus_conn); + if (ret != EOK) { + exit(1); + } - dbus_error_init(&dbus_error); - dbus_conn = dbus_connection_open(DBUS_ADDRESS, &dbus_error); - if (dbus_conn == NULL) { - printf ("Error: name=%s, message=%s\n", dbus_error.name, dbus_error.message); + test_ctx = talloc(ctx, struct test_cli_ctx); + if (!test_ctx) { + printf("Out of memory!?\n"); exit(1); } + test_ctx->sd_ctx = ctx; + test_ctx->conn = dbus_conn; - integrate_connection_with_event_loop(event_ctx,dbus_conn); - dbus_connection_set_exit_on_disconnect (dbus_conn, TRUE); + dbus_connection_set_exit_on_disconnect(dbus_conn, TRUE); /* Set up a timed event to request the server version every * five seconds and print it to the screen. */ - request_version_timed(event_ctx,dbus_conn); + request_version_timed(test_ctx); /* Enter the main loop (and hopefully never return) */ event_loop_wait(event_ctx); talloc_free(event_ctx); return EXIT_SUCCESS; -} \ No newline at end of file +} diff --git a/server/monitor.c b/server/monitor.c index 45b21cd56..0f92eceb4 100644 --- a/server/monitor.c +++ b/server/monitor.c @@ -27,9 +27,19 @@ #include "util/util.h" #include "service.h" #include "confdb/confdb.h" +#include "monitor.h" #include "dbus/dbus.h" -#include "dbus/sssd_dbus_server.h" -#include "dbus/sssd_dbus_client.h" +#include "dbus/sssd_dbus.h" + + +/* TODO: get this value from LDB */ +#define DBUS_ADDRESS "unix:path=/var/lib/sss/pipes/private/dbus" + +struct mt_ctx { + struct event_context *ev; + struct confdb_ctx *cdb; + char **services; +}; struct mt_srv { const char *name; @@ -39,6 +49,64 @@ struct mt_srv { int restarts; }; +/* dbus_get_monitor_version + * Return the monitor version over D-BUS */ +static int dbus_get_monitor_version(DBusMessage *message, + void *data, + DBusMessage **r) +{ + const char *version = MONITOR_VERSION; + DBusMessage *reply; + dbus_bool_t ret; + + reply = dbus_message_new_method_return(message); + ret = dbus_message_append_args(reply, DBUS_TYPE_STRING, + &version, DBUS_TYPE_INVALID); + + if (!ret) { + return EIO; + } + + *r = reply; + return EOK; +} + +struct sssd_dbus_method monitor_methods[] = { + { MONITOR_METHOD_VERSION, dbus_get_monitor_version}, + {NULL, NULL} +}; + +/* monitor_dbus_init + * Set up the monitor service as a D-BUS Server */ +static int monitor_dbus_init(struct mt_ctx *ctx) +{ + struct sssd_dbus_ctx *sd_ctx; + int ret; + + sd_ctx = talloc(ctx, struct sssd_dbus_ctx); + if (!sd_ctx) { + return ENOMEM; + } + + sd_ctx->ev = ctx->ev; + sd_ctx->name = talloc_strdup(sd_ctx, MONITOR_DBUS_INTERFACE); + if (!sd_ctx->name) { + talloc_free(sd_ctx); + return ENOMEM; + } + sd_ctx->path = talloc_strdup(sd_ctx, MONITOR_DBUS_PATH); + if (!sd_ctx->path) { + talloc_free(sd_ctx); + return ENOMEM; + } + sd_ctx->methods = monitor_methods; + + ret = sssd_new_dbus_server(sd_ctx, DBUS_ADDRESS); + + return ret; +} + + static void set_tasks_checker(struct mt_srv *srv); static void tasks_check_handler(struct event_context *ev, @@ -139,7 +207,7 @@ int start_monitor(TALLOC_CTX *mem_ctx, /* Initialize D-BUS Server * The monitor will act as a D-BUS server for all * SSSD processes */ - monitor_dbus_init(event_ctx); + monitor_dbus_init(ctx); for (i = 0; ctx->services[i]; i++) { @@ -163,96 +231,3 @@ int start_monitor(TALLOC_CTX *mem_ctx, return EOK; } - -/* - * monitor_dbus_init - * Set up the monitor service as a D-BUS Server - */ -int monitor_dbus_init(struct event_context *event_ctx) { - DBusError dbus_error; - DBusServer *dbus_server; - - /* Set up D-BUS server */ - dbus_error_init(&dbus_error); - dbus_server = dbus_server_listen(DBUS_ADDRESS, &dbus_error); - if (dbus_server == NULL) { - DEBUG(0,("Error: name=%s, message=%s\n", dbus_error.name, - dbus_error.message)); - } - - /* TODO: remove debug */ - DEBUG(2,("Server listening on %s\n", dbus_server_get_address(dbus_server))); - - integrate_server_with_event_loop(event_ctx, dbus_server, monitor_dbus_method_init); - - return 0; -} - -/* monitor_messsage_handler - * Receive messages and process them - */ -DBusHandlerResult monitor_message_handler(DBusConnection *conn, - DBusMessage *message, void *user_data) { - const char *method; - const char *path; - const char *msg_interface; - DBusMessage *reply = NULL; - - method = dbus_message_get_member(message); - path = dbus_message_get_path(message); - msg_interface = dbus_message_get_interface(message); - - if (!method || !path || !msg_interface) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - /* Validate the method interface */ - if (strcmp(msg_interface, MONITOR_DBUS_INTERFACE) != 0) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - /* Validate the D-BUS path */ - if (strcmp(path, MONITOR_DBUS_PATH) == 0) { - /* TODO Fill in methods */ - if(strcmp(method,MONITOR_METHOD_VERSION) == 0) { - reply = dbus_get_monitor_version(message); - } - } - - if(reply) { - dbus_connection_send(conn,reply, NULL); - dbus_message_unref(reply); - } - - return reply ? DBUS_HANDLER_RESULT_HANDLED : - DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -/* dbus_get_monitor_version - * Return the monitor version over D-BUS - */ -DBusMessage *dbus_get_monitor_version(DBusMessage *message) { - DBusMessage *reply; - const char *version = MONITOR_VERSION; - - reply = dbus_message_new_method_return(message); - dbus_message_append_args(reply,DBUS_TYPE_STRING, &version, DBUS_TYPE_INVALID); - - return reply; -} - -/* monitor_dbus_method_init - * Initialize D-BUS methods on the monitor - * Sets up a callback to monitor_message_handler - */ -void monitor_dbus_method_init(DBusConnection *conn, struct event_context *event_ctx) { - DBusObjectPathVTable *monitor_vtable; - monitor_vtable = talloc_zero(event_ctx, DBusObjectPathVTable); - - DEBUG (3,("Initializing D-BUS methods.\n")); - monitor_vtable->message_function = monitor_message_handler; - - dbus_connection_register_object_path( - conn, MONITOR_DBUS_PATH, - monitor_vtable, event_ctx); - - DEBUG(3,("D-BUS method initialization complete.\n")); -} diff --git a/server/monitor.h b/server/monitor.h index 074c5a81c..8d9e026df 100644 --- a/server/monitor.h +++ b/server/monitor.h @@ -1,9 +1,5 @@ -#ifndef MONITOR_H_ -#define MONITOR_H_ - -#include "talloc.h" -#include "service_task.h" -#include "dbus/dbus.h" +#ifndef _MONITOR_H_ +#define _MONITOR_H_ #define MONITOR_VERSION "0.1" #define MONITOR_DBUS_INTERFACE "org.freeipa.sssd.monitor" @@ -12,19 +8,8 @@ /* D-BUS Methods */ #define MONITOR_METHOD_VERSION "getVersion" -struct mt_ctx { - struct event_context *ev; - struct confdb_ctx *cdb; - char **services; -}; - int start_monitor(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, struct confdb_ctx *cdb); -int monitor_dbus_init(struct event_context *event_ctx); -void monitor_dbus_method_init(DBusConnection *conn, struct event_context *event_ctx); -DBusHandlerResult monitor_message_handler(DBusConnection *conn, - DBusMessage *message, void *user_data); -DBusMessage *dbus_get_monitor_version(DBusMessage *message); -#endif /* MONITOR_H */ +#endif /* _MONITOR_H */ diff --git a/server/server.mk b/server/server.mk index 655b4fe31..f49a7b041 100644 --- a/server/server.mk +++ b/server/server.mk @@ -12,13 +12,13 @@ SERVER_OBJ = \ nss/nsssrv_packet.o \ nss/nsssrv_cmd.o \ nss/nsssrv_ldb.o \ - dbus/sssd_dbus_server.o \ - dbus/sssd_dbus_client.o \ - dbus/sssd_dbus_common.o + dbus/sssd_dbus_common.o \ + dbus/sssd_dbus_connection.o \ + dbus/sssd_dbus_server.o CLIENT_OBJ = \ dbus/sssd_dbus_common.o \ - dbus/sssd_dbus_client.o \ + dbus/sssd_dbus_connection.o \ util/debug.o \ dbus/tests/test_client.o @@ -26,9 +26,6 @@ install:: all ${INSTALLCMD} -d $(DESTDIR)$(sbindir) ${INSTALLCMD} -m 755 sssd $(DESTDIR)$(sbindir) -clean:: - rm -f *~ $(SERVER_OBJS) - sbin/sssd: $(SERVER_OBJ) $(CC) -o sbin/sssd $(SERVER_OBJ) $(LDFLAGS) $(LIBS) -- cgit