summaryrefslogtreecommitdiffstats
path: root/server/dbus/sssd_dbus_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/dbus/sssd_dbus_server.c')
-rw-r--r--server/dbus/sssd_dbus_server.c152
1 files changed, 58 insertions, 94 deletions
diff --git a/server/dbus/sssd_dbus_server.c b/server/dbus/sssd_dbus_server.c
index ebf5a6118..8bdccf8ea 100644
--- a/server/dbus/sssd_dbus_server.c
+++ b/server/dbus/sssd_dbus_server.c
@@ -28,9 +28,18 @@
/* Types */
struct dbus_server_toplevel_context {
DBusServer *server;
- /* talloc context to manage the server object memory*/
- DBusServer **server_talloc;
- struct sssd_dbus_ctx *sd_ctx;
+ /*
+ * sd_ctx here describes the object path that will be
+ * presented to all clients of this server. Additional
+ * connection-specific paths can be specified by the
+ * init_fn, which is called every time a new connection
+ * is established.
+ * There should only be one global object path (for
+ * simplicity's sake)
+ */
+ struct event_context *ev;
+ struct sssd_dbus_method_ctx *sd_ctx;
+ sssd_dbus_server_connection_init_fn init_fn;
};
struct dbus_server_watch_context {
@@ -105,7 +114,7 @@ static dbus_bool_t add_server_watch(DBusWatch *watch, void *data)
}
DEBUG(2,("%lX: %d, %d=%s\n", watch, svw_ctx->fd, event_flags, event_flags==EVENT_FD_READ?"READ":"WRITE"));
- svw_ctx->fde = event_add_fd(dt_ctx->sd_ctx->ev, svw_ctx, svw_ctx->fd,
+ svw_ctx->fde = event_add_fd(dt_ctx->ev, svw_ctx, svw_ctx->fd,
event_flags, dbus_server_read_write_handler,
svw_ctx);
@@ -159,7 +168,7 @@ static 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(dt_ctx->sd_ctx->ev, svt_ctx, tv,
+ svt_ctx->te = event_add_timed(dt_ctx->ev, svt_ctx, tv,
dbus_server_timeout_handler, svt_ctx);
/* Save the event to the watch object so it can be removed later */
@@ -182,54 +191,6 @@ static void toggle_server_timeout(DBusTimeout *timeout, void *data)
}
}
-/* messsage_handler
- * Receive messages and process them
- */
-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 */
- }
-
- if (reply) {
- dbus_connection_send(conn, reply, NULL);
- dbus_message_unref(reply);
- }
-
- return reply ? DBUS_HANDLER_RESULT_HANDLED :
- DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
/*
* new_connection_callback
* Actions to be run upon each new client connection
@@ -241,41 +202,45 @@ static void new_connection_callback(DBusServer *server, DBusConnection *conn,
void *data)
{
struct dbus_server_toplevel_context *dst_ctx;
- DBusObjectPathVTable *monitor_vtable;
- int *connection_type;
+ struct dbus_connection_toplevel_context *dct_ctx;
+ struct sssd_dbus_method_ctx *iter;
+
+ /*DBusObjectPathVTable *connection_vtable;*/
int ret;
-
+ DEBUG(0,("Entering.\n"));
dst_ctx = talloc_get_type(data,struct dbus_server_toplevel_context);
-
- if (!dbus_connection_allocate_data_slot(&connection_type_slot)) {
- dbus_connection_close(conn);
+ if(dst_ctx == NULL) {
return;
}
- connection_type = talloc(dst_ctx, int);
- *connection_type = DBUS_CONNECTION_TYPE_PRIVATE;
- dbus_connection_set_data(conn, connection_type_slot, connection_type, talloc_free);
-
- ret = sssd_add_dbus_connection(dst_ctx->sd_ctx, conn);
+ DEBUG(0,("Adding connection %lX.\n", conn));
+ ret = sssd_add_dbus_connection(dst_ctx, dst_ctx->ev, conn, &dct_ctx, DBUS_CONNECTION_TYPE_PRIVATE);
if (ret != 0) {
dbus_connection_close(conn);
DEBUG(0,("Closing connection (failed setup)"));
return;
}
-
+
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"));
+ /* Set up global methods */
+ iter = dst_ctx->sd_ctx;
+ while (iter != NULL) {
+ dbus_connection_add_method_ctx(dct_ctx, iter);
+ iter = iter->next;
+ }
+
+ /*
+ * Initialize connection-specific features
+ * This may set a more detailed destructor, but
+ * the default destructor will always be chained
+ * to handle connection cleanup.
+ * This function (or its callbacks) should also
+ * set up connection-specific methods.
+ */
+ dst_ctx->init_fn(dct_ctx);
}
/*
@@ -283,9 +248,9 @@ static void new_connection_callback(DBusServer *server, DBusConnection *conn,
* 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)
+int sssd_new_dbus_server(struct event_context *ev, struct sssd_dbus_method_ctx *ctx, const char *address, sssd_dbus_server_connection_init_fn init_fn)
{
- struct dbus_server_toplevel_context *dt_ctx;
+ struct dbus_server_toplevel_context *dst_ctx;
DBusServer *dbus_server;
DBusServer **dbus_server_talloc;
DBusError dbus_error;
@@ -299,47 +264,46 @@ int sssd_new_dbus_server(struct sssd_dbus_ctx *ctx, const char *address)
dbus_error.name, dbus_error.message));
return EIO;
}
- dbus_server_talloc = talloc_takeover(ctx, dbus_server, dbus_server_destructor);
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) {
- talloc_free(dbus_server_talloc);
+ dst_ctx = talloc_zero(ev, struct dbus_server_toplevel_context);
+ if (!dst_ctx) {
return ENOMEM;
}
- dt_ctx->server_talloc = dbus_server_talloc;
- dt_ctx->server = *dbus_server_talloc;
- dt_ctx->sd_ctx = ctx;
+
+ dbus_server_talloc = talloc_takeover(ctx, dbus_server, dbus_server_destructor);
+ dst_ctx->ev = ev;
+ dst_ctx->server = dbus_server;
+ dst_ctx->sd_ctx = ctx;
+ dst_ctx->init_fn = init_fn;
/* Set up D-BUS new connection handler */
- dbus_server_set_new_connection_function(dt_ctx->server,
+ dbus_server_set_new_connection_function(dst_ctx->server,
new_connection_callback,
- dt_ctx, NULL);
+ dst_ctx, NULL);
/* Set up DBusWatch functions */
- dbret = dbus_server_set_watch_functions(dt_ctx->server, add_server_watch,
+ dbret = dbus_server_set_watch_functions(dst_ctx->server, add_server_watch,
remove_watch, toggle_server_watch,
- dt_ctx, NULL);
+ dst_ctx, NULL);
if (!dbret) {
DEBUG(0, ("Error setting up D-BUS server watch functions"));
- talloc_free(dt_ctx->server_talloc);
- dt_ctx->server = NULL;
+ talloc_free(dst_ctx);
return EIO;
}
/* Set up DBusTimeout functions */
- dbret = dbus_server_set_timeout_functions(dt_ctx->server,
+ dbret = dbus_server_set_timeout_functions(dst_ctx->server,
add_server_timeout,
remove_timeout,
toggle_server_timeout,
- dt_ctx, NULL);
+ dst_ctx, NULL);
if (!dbret) {
DEBUG(0,("Error setting up D-BUS server timeout functions"));
- dbus_server_set_watch_functions(dt_ctx->server, NULL, NULL, NULL, NULL, NULL);
- talloc_free(dt_ctx->server_talloc);
- dt_ctx->server = NULL;
+ dbus_server_set_watch_functions(dst_ctx->server, NULL, NULL, NULL, NULL, NULL);
+ talloc_free(dst_ctx);
return EIO;
}