diff options
-rw-r--r-- | server/monitor/monitor.c | 7 | ||||
-rw-r--r-- | server/providers/data_provider.c | 20 | ||||
-rw-r--r-- | server/providers/data_provider_be.c | 14 | ||||
-rw-r--r-- | server/responder/common/responder_common.c | 4 | ||||
-rw-r--r-- | server/responder/common/responder_dp.c | 4 | ||||
-rw-r--r-- | server/sbus/sbus_client.c | 2 | ||||
-rw-r--r-- | server/sbus/sbus_client.h | 2 | ||||
-rw-r--r-- | server/sbus/sssd_dbus.h | 11 | ||||
-rw-r--r-- | server/sbus/sssd_dbus_common.c | 31 | ||||
-rw-r--r-- | server/sbus/sssd_dbus_connection.c | 282 | ||||
-rw-r--r-- | server/sbus/sssd_dbus_private.h | 36 | ||||
-rw-r--r-- | server/sbus/sssd_dbus_server.c | 101 |
12 files changed, 228 insertions, 286 deletions
diff --git a/server/monitor/monitor.c b/server/monitor/monitor.c index a2b2de58..7a27c4ec 100644 --- a/server/monitor/monitor.c +++ b/server/monitor/monitor.c @@ -113,7 +113,7 @@ struct mt_ctx { TALLOC_CTX *service_ctx; /* Memory context for services */ char **services; struct mt_svc *svc_list; - struct sbus_srv_ctx *sbus_srv; + struct sbus_connection *sbus_srv; struct config_file_ctx *file_ctx; int inotify_fd; int service_id_timeout; @@ -180,7 +180,6 @@ struct sbus_method monitor_methods[] = { static int monitor_dbus_init(struct mt_ctx *ctx) { struct sbus_method_ctx *sd_ctx; - struct sbus_srv_ctx *sbus_srv; char *monitor_address; int ret; @@ -210,8 +209,8 @@ static int monitor_dbus_init(struct mt_ctx *ctx) sd_ctx->methods = monitor_methods; sd_ctx->message_handler = sbus_message_handler; - ret = sbus_new_server(ctx, ctx->ev, sd_ctx, &sbus_srv, monitor_address, dbus_service_init, ctx); - ctx->sbus_srv = sbus_srv; + ret = sbus_new_server(ctx, ctx->ev, monitor_address, sd_ctx, + &ctx->sbus_srv, dbus_service_init, ctx); talloc_free(monitor_address); diff --git a/server/providers/data_provider.c b/server/providers/data_provider.c index 29bfe946..c844f644 100644 --- a/server/providers/data_provider.c +++ b/server/providers/data_provider.c @@ -55,7 +55,7 @@ struct dp_frontend; struct dp_ctx { struct tevent_context *ev; struct confdb_ctx *cdb; - struct sbus_srv_ctx *sbus_srv; + struct sbus_connection *sbus_srv; struct dp_backend *be_list; struct dp_frontend *fe_list; }; @@ -212,14 +212,8 @@ static int dp_monitor_init(struct dp_ctx *dpctx) return ret; } - /* FIXME: remove this */ - if (talloc_reference(dpctx, sm_ctx) == NULL) { - DEBUG(0, ("Failed to take memory reference\n")); - return ENOMEM; - } - - ret = sbus_client_init(dpctx, dpctx->ev, sm_ctx, - sbus_address, &conn, + ret = sbus_client_init(dpctx, dpctx->ev, sbus_address, + sm_ctx, &conn, NULL, NULL); if (ret != EOK) { DEBUG(0, ("Failed to connect to monitor services.\n")); @@ -997,7 +991,6 @@ static int dp_frontend_destructor(void *ctx) static int dp_srv_init(struct dp_ctx *dpctx) { TALLOC_CTX *tmp_ctx; - struct sbus_srv_ctx *sbus_srv; struct sbus_method_ctx *sd_ctx; char *dpbus_address; char *default_dp_address; @@ -1041,14 +1034,11 @@ static int dp_srv_init(struct dp_ctx *dpctx) sd_ctx->methods = dp_sbus_methods; sd_ctx->message_handler = sbus_message_handler; - ret = sbus_new_server(dpctx, - dpctx->ev, sd_ctx, - &sbus_srv, dpbus_address, - dbus_dp_init, dpctx); + ret = sbus_new_server(dpctx, dpctx->ev, dpbus_address, sd_ctx, + &dpctx->sbus_srv, dbus_dp_init, dpctx); if (ret != EOK) { goto done; } - dpctx->sbus_srv = sbus_srv; talloc_steal(dpctx, sd_ctx); done: diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c index 7db2047f..ecd20ad9 100644 --- a/server/providers/data_provider_be.c +++ b/server/providers/data_provider_be.c @@ -693,8 +693,8 @@ static int mon_cli_init(struct be_ctx *ctx) return ENOMEM; } - ret = sbus_client_init(ctx, ctx->ev, ctx->mon_sm_ctx, - sbus_address, &ctx->mon_conn, + ret = sbus_client_init(ctx, ctx->ev, sbus_address, + ctx->mon_sm_ctx, &ctx->mon_conn, NULL, ctx); if (ret != EOK) { DEBUG(0, ("Failed to connect to monitor services.\n")); @@ -726,14 +726,8 @@ static int be_cli_init(struct be_ctx *ctx) return ret; } - /* FIXME: remove this */ - if (talloc_reference(ctx, ctx->dp_sm_ctx) == NULL) { - DEBUG(0, ("Failed to take memory reference\n")); - return ENOMEM; - } - - ret = sbus_client_init(ctx, ctx->ev, ctx->dp_sm_ctx, - sbus_address, &ctx->dp_conn, + ret = sbus_client_init(ctx, ctx->ev, sbus_address, + ctx->dp_sm_ctx, &ctx->dp_conn, NULL, ctx); if (ret != EOK) { DEBUG(0, ("Failed to connect to monitor services.\n")); diff --git a/server/responder/common/responder_common.c b/server/responder/common/responder_common.c index 1fd66907..c8e5d818 100644 --- a/server/responder/common/responder_common.c +++ b/server/responder/common/responder_common.c @@ -310,8 +310,8 @@ static int sss_sbus_init(struct resp_ctx *rctx) return ENOMEM; } - ret = sbus_client_init(rctx, rctx->ev, rctx->sm_ctx, - sbus_address, &rctx->conn, + ret = sbus_client_init(rctx, rctx->ev, sbus_address, + rctx->sm_ctx, &rctx->conn, NULL, NULL); if (ret != EOK) { DEBUG(0, ("Failed to connect to monitor services.\n")); diff --git a/server/responder/common/responder_dp.c b/server/responder/common/responder_dp.c index bdd9a9ef..547cb272 100644 --- a/server/responder/common/responder_dp.c +++ b/server/responder/common/responder_dp.c @@ -61,8 +61,8 @@ static void sss_dp_conn_reconnect(struct sss_dp_pvt_ctx *pvt) return; } - ret = sbus_client_init(rctx, rctx->ev, rctx->sm_ctx, - sbus_address, &rctx->conn, + ret = sbus_client_init(rctx, rctx->ev, sbus_address, + rctx->sm_ctx, &rctx->conn, sss_dp_conn_destructor, pvt); if (ret != EOK) { DEBUG(4, ("Failed to reconnect [%d(%s)]!\n", ret, strerror(ret))); diff --git a/server/sbus/sbus_client.c b/server/sbus/sbus_client.c index 990f21b0..82021d6e 100644 --- a/server/sbus/sbus_client.c +++ b/server/sbus/sbus_client.c @@ -25,8 +25,8 @@ int sbus_client_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct sbus_method_ctx *sm_ctx, const char *server_address, + struct sbus_method_ctx *sm_ctx, struct sbus_connection **_conn, sbus_conn_destructor_fn destructor, void *conn_pvt_data) diff --git a/server/sbus/sbus_client.h b/server/sbus/sbus_client.h index b49dd66e..bce8f821 100644 --- a/server/sbus/sbus_client.h +++ b/server/sbus/sbus_client.h @@ -27,8 +27,8 @@ int sbus_client_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct sbus_method_ctx *sm_ctx, const char *server_address, + struct sbus_method_ctx *sm_ctx, struct sbus_connection **_conn, sbus_conn_destructor_fn destructor, void *conn_pvt_data); diff --git a/server/sbus/sssd_dbus.h b/server/sbus/sssd_dbus.h index 41282038..6487ced6 100644 --- a/server/sbus/sssd_dbus.h +++ b/server/sbus/sssd_dbus.h @@ -23,7 +23,6 @@ #define _SSSD_DBUS_H_ struct sbus_connection; -struct sbus_srv_ctx; #include "dbus/dbus.h" @@ -66,7 +65,6 @@ struct sbus_method { }; struct sbus_method_ctx { - struct sbus_method_ctx *prev, *next; char *interface; char *path; DBusObjectPathMessageFunction message_handler; @@ -76,8 +74,10 @@ struct sbus_method_ctx { /* Server Functions */ int sbus_new_server(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, struct sbus_method_ctx *ctx, - struct sbus_srv_ctx **server_ctx, const char *address, + struct tevent_context *ev, + const char *address, + struct sbus_method_ctx *ctx, + struct sbus_connection **server, sbus_server_conn_init_fn init_fn, void *init_pvt_data); /* Connection Functions */ @@ -89,7 +89,8 @@ int sbus_new_server(TALLOC_CTX *mem_ctx, * call sbus_add_connection to integrate with the main * loop. */ -int sbus_new_connection(TALLOC_CTX *ctx, struct tevent_context *ev, +int sbus_new_connection(TALLOC_CTX *ctx, + struct tevent_context *ev, const char *address, struct sbus_connection **conn); diff --git a/server/sbus/sssd_dbus_common.c b/server/sbus/sssd_dbus_common.c index 6a710768..0c16f9f5 100644 --- a/server/sbus/sssd_dbus_common.c +++ b/server/sbus/sssd_dbus_common.c @@ -20,10 +20,10 @@ static void sbus_watch_handler(struct tevent_context *ev, struct sbus_watch_ctx); /* Take a reference while handling watch */ - if (watch->dbus_type == SBUS_SERVER) { - dbus_server_ref(watch->dbus.server); + if (watch->conn->type == SBUS_SERVER) { + dbus_server_ref(watch->conn->dbus.server); } else { - dbus_connection_ref(watch->dbus.conn); + dbus_connection_ref(watch->conn->dbus.conn); } /* Fire if readable */ @@ -37,10 +37,10 @@ static void sbus_watch_handler(struct tevent_context *ev, } /* Release reference once done */ - if (watch->dbus_type == SBUS_SERVER) { - dbus_server_unref(watch->dbus.server); + if (watch->conn->type == SBUS_SERVER) { + dbus_server_unref(watch->conn->dbus.server); } else { - dbus_connection_unref(watch->dbus.conn); + dbus_connection_unref(watch->conn->dbus.conn); } } @@ -53,20 +53,19 @@ dbus_bool_t sbus_add_watch(DBusWatch *dbus_watch, void *data) { unsigned int flags; uint16_t event_flags; - struct sbus_generic_dbus_ctx *gen_ctx; + struct sbus_connection *conn; struct sbus_watch_ctx *watch; int fd; - gen_ctx = talloc_get_type(data, struct sbus_generic_dbus_ctx); + conn = talloc_get_type(data, struct sbus_connection); - watch = talloc_zero(gen_ctx, struct sbus_watch_ctx); + watch = talloc_zero(conn, struct sbus_watch_ctx); if (!watch) { DEBUG(0, ("Outr of Memory!\n")); return FALSE; } watch->dbus_watch = dbus_watch; - watch->dbus_type = gen_ctx->type; - watch->dbus = gen_ctx->dbus; + watch->conn = conn; #ifdef HAVE_DBUS_WATCH_GET_UNIX_FD fd = dbus_watch_get_unix_fd(dbus_watch); @@ -92,7 +91,7 @@ dbus_bool_t sbus_add_watch(DBusWatch *dbus_watch, void *data) ((event_flags & TEVENT_FD_WRITE)?"W":"-"))); /* Add the file descriptor to the event loop */ - watch->fde = tevent_add_fd(gen_ctx->ev, + watch->fde = tevent_add_fd(conn->ev, watch, fd, event_flags, sbus_watch_handler, watch); if (!watch->fde) { @@ -206,7 +205,7 @@ static void sbus_timeout_handler(struct tevent_context *ev, */ dbus_bool_t sbus_add_timeout(DBusTimeout *dbus_timeout, void *data) { - struct sbus_generic_dbus_ctx *gen_ctx; + struct sbus_connection *conn; struct sbus_timeout_ctx *timeout; struct timeval tv; @@ -216,9 +215,9 @@ dbus_bool_t sbus_add_timeout(DBusTimeout *dbus_timeout, void *data) return TRUE; } - gen_ctx = talloc_get_type(data, struct sbus_generic_dbus_ctx); + conn = talloc_get_type(data, struct sbus_connection); - timeout = talloc_zero(gen_ctx, struct sbus_timeout_ctx); + timeout = talloc_zero(conn, struct sbus_timeout_ctx); if (!timeout) { DEBUG(0, ("Outr of Memory!\n")); return FALSE; @@ -226,7 +225,7 @@ dbus_bool_t sbus_add_timeout(DBusTimeout *dbus_timeout, void *data) timeout->dbus_timeout = dbus_timeout; tv = _get_interval_tv(dbus_timeout_get_interval(dbus_timeout)); - timeout->te = tevent_add_timer(gen_ctx->ev, timeout, tv, + timeout->te = tevent_add_timer(conn->ev, timeout, tv, sbus_timeout_handler, timeout); if (!timeout->te) { DEBUG(0, ("Failed to set up timeout event!\n")); diff --git a/server/sbus/sssd_dbus_connection.c b/server/sbus/sssd_dbus_connection.c index 8e4c3048..f2435bfb 100644 --- a/server/sbus/sssd_dbus_connection.c +++ b/server/sbus/sssd_dbus_connection.c @@ -7,30 +7,14 @@ /* Types */ struct dbus_ctx_list; -struct sbus_connection { - struct tevent_context *ev; - DBusConnection *dbus_conn; - char *address; - int connection_type; - int disconnect; - struct sbus_method_ctx *method_ctx_list; - sbus_conn_destructor_fn destructor; - void *pvt_data; /* Private data for this connection */ - - int retries; - int max_retries; - sbus_conn_reconn_callback_fn reconnect_callback; - /* Private data needed to reinit after reconnection */ - void *reconnect_pvt; -}; - -struct sbus_message_handler_ctx { +struct method_holder { + struct method_holder *prev, *next; struct sbus_connection *conn; struct sbus_method_ctx *method_ctx; + DBusObjectPathVTable *dbus_vtable; }; -static int _method_list_contains_path(struct sbus_method_ctx *list, - struct sbus_method_ctx *method); +static bool path_in_method_list(struct method_holder *list, const char *path); static void sbus_unreg_object_paths(struct sbus_connection *conn); static int sbus_auto_reconnect(struct sbus_connection *conn); @@ -48,7 +32,7 @@ static void sbus_dispatch(struct tevent_context *ev, conn = talloc_get_type(data, struct sbus_connection); - dbus_conn = conn->dbus_conn; + dbus_conn = conn->dbus.conn; DEBUG(6, ("dbus conn: %lX\n", dbus_conn)); if (conn->retries > 0) { @@ -138,7 +122,7 @@ static void sbus_conn_wakeup_main(void *data) } } -static int sbus_add_connection_int(struct sbus_connection **conn); +static int sbus_conn_set_fns(struct sbus_connection *conn); /* * integrate_connection_with_event_loop @@ -158,31 +142,22 @@ int sbus_add_connection(TALLOC_CTX *ctx, conn = talloc_zero(ctx, struct sbus_connection); conn->ev = ev; - conn->dbus_conn = dbus_conn; + conn->type = SBUS_CONNECTION; + conn->dbus.conn = dbus_conn; conn->connection_type = connection_type; - conn->disconnect = 0; - - /* This will be replaced on the first call to sbus_conn_add_method_ctx() */ - conn->method_ctx_list = NULL; - - /* This can be overridden by a call to sbus_reconnect_init() */ - conn->retries = 0; - conn->max_retries = 0; - conn->reconnect_callback = NULL; - *_conn = conn; - - ret = sbus_add_connection_int(_conn); + ret = sbus_conn_set_fns(conn); if (ret != EOK) { talloc_free(conn); } + + *_conn = conn; + return ret; } -static int sbus_add_connection_int(struct sbus_connection **_conn) +static int sbus_conn_set_fns(struct sbus_connection *conn) { - struct sbus_connection *conn = *_conn; - struct sbus_generic_dbus_ctx *gen_ctx; dbus_bool_t dbret; /* @@ -192,32 +167,23 @@ static int sbus_add_connection_int(struct sbus_connection **_conn) */ sbus_conn_set_destructor(conn, NULL); - gen_ctx = talloc_zero(conn, struct sbus_generic_dbus_ctx); - if (!gen_ctx) { - DEBUG(0, ("Out of memory!\n")); - return ENOMEM; - } - gen_ctx->ev = conn->ev; - gen_ctx->type = SBUS_CONNECTION; - gen_ctx->dbus.conn = conn->dbus_conn; - /* Set up DBusWatch functions */ - dbret = dbus_connection_set_watch_functions(conn->dbus_conn, + dbret = dbus_connection_set_watch_functions(conn->dbus.conn, sbus_add_watch, sbus_remove_watch, sbus_toggle_watch, - gen_ctx, NULL); + conn, NULL); if (!dbret) { DEBUG(2,("Error setting up D-BUS connection watch functions\n")); return EIO; } /* Set up DBusTimeout functions */ - dbret = dbus_connection_set_timeout_functions(conn->dbus_conn, + dbret = dbus_connection_set_timeout_functions(conn->dbus.conn, sbus_add_timeout, sbus_remove_timeout, sbus_toggle_timeout, - gen_ctx, NULL); + conn, NULL); if (!dbret) { DEBUG(2,("Error setting up D-BUS server timeout functions\n")); /* FIXME: free resources ? */ @@ -225,7 +191,7 @@ static int sbus_add_connection_int(struct sbus_connection **_conn) } /* Set up dispatch handler */ - dbus_connection_set_wakeup_main_function(conn->dbus_conn, + dbus_connection_set_wakeup_main_function(conn->dbus.conn, sbus_conn_wakeup_main, conn, NULL); @@ -238,9 +204,6 @@ static int sbus_add_connection_int(struct sbus_connection **_conn) */ sbus_conn_wakeup_main(conn); - /* Return the new toplevel object */ - *_conn = conn; - return EOK; } @@ -272,7 +235,7 @@ int sbus_new_connection(TALLOC_CTX *ctx, struct tevent_context *ev, /* Store the address for later reconnection */ (*conn)->address = talloc_strdup((*conn), address); - dbus_connection_set_exit_on_disconnect((*conn)->dbus_conn, FALSE); + dbus_connection_set_exit_on_disconnect((*conn)->dbus.conn, FALSE); return ret; } @@ -302,10 +265,10 @@ int sbus_default_connection_destructor(void *ctx) conn = talloc_get_type(ctx, struct sbus_connection); DEBUG(5, ("Invoking default destructor on connection %lX\n", - conn->dbus_conn)); + conn->dbus.conn)); if (conn->connection_type == SBUS_CONN_TYPE_PRIVATE) { /* Private connections must be closed explicitly */ - dbus_connection_close(conn->dbus_conn); + dbus_connection_close(conn->dbus.conn); } else if (conn->connection_type == SBUS_CONN_TYPE_SHARED) { /* Shared connections are destroyed when their last reference is removed */ @@ -319,7 +282,7 @@ int sbus_default_connection_destructor(void *ctx) /* Remove object path */ /* TODO: Remove object paths */ - dbus_connection_unref(conn->dbus_conn); + dbus_connection_unref(conn->dbus.conn); return 0; } @@ -330,7 +293,7 @@ int sbus_default_connection_destructor(void *ctx) */ DBusConnection *sbus_get_connection(struct sbus_connection *conn) { - return conn->dbus_conn; + return conn->dbus.conn; } void sbus_disconnect (struct sbus_connection *conn) @@ -339,11 +302,11 @@ void sbus_disconnect (struct sbus_connection *conn) return; } - DEBUG(5,("Disconnecting %lX\n", conn->dbus_conn)); + DEBUG(5,("Disconnecting %lX\n", conn->dbus.conn)); /******************************* - * Referencing conn->dbus_conn */ - dbus_connection_ref(conn->dbus_conn); + * Referencing conn->dbus.conn */ + dbus_connection_ref(conn->dbus.conn); conn->disconnect = 1; @@ -356,30 +319,30 @@ void sbus_disconnect (struct sbus_connection *conn) sbus_unreg_object_paths(conn); /* Disable watch functions */ - dbus_connection_set_watch_functions(conn->dbus_conn, + dbus_connection_set_watch_functions(conn->dbus.conn, NULL, NULL, NULL, NULL, NULL); /* Disable timeout functions */ - dbus_connection_set_timeout_functions(conn->dbus_conn, + dbus_connection_set_timeout_functions(conn->dbus.conn, NULL, NULL, NULL, NULL, NULL); /* Disable dispatch status function */ - dbus_connection_set_dispatch_status_function(conn->dbus_conn, + dbus_connection_set_dispatch_status_function(conn->dbus.conn, NULL, NULL, NULL); /* Disable wakeup main function */ - dbus_connection_set_wakeup_main_function(conn->dbus_conn, + dbus_connection_set_wakeup_main_function(conn->dbus.conn, NULL, NULL, NULL); /* Finalize the connection */ sbus_default_connection_destructor(conn); - dbus_connection_unref(conn->dbus_conn); + dbus_connection_unref(conn->dbus.conn); /* Unreferenced conn->dbus_conn * ******************************/ - DEBUG(5,("Disconnected %lX\n", conn->dbus_conn)); + DEBUG(5,("Disconnected %lX\n", conn->dbus.conn)); } static int sbus_reply_internal_error(DBusMessage *message, @@ -401,7 +364,7 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, DBusMessage *message, void *user_data) { - struct sbus_message_handler_ctx *ctx; + struct method_holder *ctx; const char *method; const char *path; const char *msg_interface; @@ -412,7 +375,7 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, if (!user_data) { return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - ctx = talloc_get_type(user_data, struct sbus_message_handler_ctx); + ctx = talloc_get_type(user_data, struct method_holder); method = dbus_message_get_member(message); DEBUG(9, ("Received SBUS method [%s]\n", method)); @@ -433,8 +396,9 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, if (strcmp(method, ctx->method_ctx->methods[i].method) == 0) { found = 1; ret = ctx->method_ctx->methods[i].fn(message, ctx->conn); - if (ret != EOK) return sbus_reply_internal_error(message, - ctx->conn); + if (ret != EOK) { + return sbus_reply_internal_error(message, ctx->conn); + } break; } } @@ -459,8 +423,9 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, * an introspection function registered, user that. */ ret = ctx->method_ctx->introspect_fn(message, ctx->conn); - if (ret != EOK) return sbus_reply_internal_error(message, - ctx->conn); + if (ret != EOK) { + return sbus_reply_internal_error(message, ctx->conn); + } } } else @@ -476,50 +441,46 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, int sbus_conn_add_method_ctx(struct sbus_connection *conn, struct sbus_method_ctx *method_ctx) { - DBusObjectPathVTable *connection_vtable; - struct sbus_message_handler_ctx *msg_handler_ctx; - TALLOC_CTX *tmp_ctx; - + struct method_holder *mh; dbus_bool_t dbret; - if (!conn || !method_ctx) { - return EINVAL; - } + const char *path; - if (_method_list_contains_path(conn->method_ctx_list, method_ctx)) { - DEBUG(0, ("Cannot add method context with identical path.\n")); + if (!conn || !method_ctx || !method_ctx->message_handler) { return EINVAL; } - if (method_ctx->message_handler == NULL) { + path = method_ctx->path; + + if (path_in_method_list(conn->method_list, path)) { + DEBUG(0, ("Cannot add method context with identical path.\n")); return EINVAL; } - DLIST_ADD(conn->method_ctx_list, method_ctx); - tmp_ctx = talloc_reference(conn, method_ctx); - if (tmp_ctx != method_ctx) { - /* talloc_reference only fails on insufficient memory */ + mh = talloc_zero(conn, struct method_holder); + if (!mh) { return ENOMEM; } + mh->conn = conn; /* Set up the vtable for the object path */ - connection_vtable = talloc_zero(conn, DBusObjectPathVTable); - if (!connection_vtable) { + mh->dbus_vtable = talloc_zero(conn, DBusObjectPathVTable); + if (!mh->dbus_vtable) { + talloc_free(mh); return ENOMEM; } - connection_vtable->message_function = method_ctx->message_handler; + mh->dbus_vtable->message_function = method_ctx->message_handler; - msg_handler_ctx = talloc_zero(conn, struct sbus_message_handler_ctx); - if (!msg_handler_ctx) { - talloc_free(connection_vtable); + mh->method_ctx = talloc_reference(mh, method_ctx); + if (!mh->method_ctx) { + /* talloc_reference only fails on insufficient memory */ + talloc_free(mh); return ENOMEM; } - msg_handler_ctx->conn = conn; - msg_handler_ctx->method_ctx = method_ctx; - dbret = dbus_connection_register_object_path(conn->dbus_conn, - method_ctx->path, - connection_vtable, - msg_handler_ctx); + DLIST_ADD(conn->method_list, mh); + + dbret = dbus_connection_register_object_path(conn->dbus.conn, + path, mh->dbus_vtable, mh); if (!dbret) { DEBUG(0, ("Could not register object path to the connection.\n")); return ENOMEM; @@ -528,38 +489,37 @@ int sbus_conn_add_method_ctx(struct sbus_connection *conn, return EOK; } -static int _method_list_contains_path(struct sbus_method_ctx *list, - struct sbus_method_ctx *method) +static bool path_in_method_list(struct method_holder *list, const char *path) { - struct sbus_method_ctx *iter; + struct method_holder *iter; - if (!list || !method) { - return 0; /* FALSE */ + if (!list || !path) { + return false; } iter = list; while (iter != NULL) { - if (strcmp(iter->path, method->path) == 0) - return 1; /* TRUE */ - + if (strcmp(iter->method_ctx->path, path) == 0) { + return true; + } iter = iter->next; } - return 0; /* FALSE */ + return false; } static void sbus_unreg_object_paths(struct sbus_connection *conn) { - struct sbus_method_ctx *iter = conn->method_ctx_list; - struct sbus_method_ctx *purge; + struct method_holder *iter = conn->method_list; + struct method_holder *purge; while (iter != NULL) { - dbus_connection_unregister_object_path(conn->dbus_conn, - iter->path); - DLIST_REMOVE(conn->method_ctx_list, iter); + dbus_connection_unregister_object_path(conn->dbus.conn, + iter->method_ctx->path); + DLIST_REMOVE(conn->method_list, iter); purge = iter; iter = iter->next; - talloc_unlink(conn, purge); + talloc_free(purge); } } @@ -577,38 +537,39 @@ static void sbus_reconnect(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *data) { - struct sbus_connection *conn = talloc_get_type(data, struct sbus_connection); - DBusConnection *dbus_conn; + struct sbus_connection *conn; + struct method_holder *mh; DBusError dbus_error; - struct tevent_timer *event; - struct sbus_method_ctx *iter; - struct sbus_method_ctx *purge; + dbus_bool_t dbret; int ret; + conn = talloc_get_type(data, struct sbus_connection); + dbus_error_init(&dbus_error); + DEBUG(3, ("Making reconnection attempt %d to [%s]\n", conn->retries, conn->address)); - /* Make a new connection to the D-BUS address */ - dbus_error_init(&dbus_error); - dbus_conn = dbus_connection_open(conn->address, &dbus_error); - if (dbus_conn) { - /* We successfully reconnected. Set up mainloop - * integration. - */ + conn->dbus.conn = dbus_connection_open(conn->address, &dbus_error); + if (conn->dbus.conn) { + /* We successfully reconnected. Set up mainloop integration. */ DEBUG(3, ("Reconnected to [%s]\n", conn->address)); - conn->dbus_conn = dbus_conn; - ret = sbus_add_connection_int(&conn); + ret = sbus_conn_set_fns(conn); if (ret != EOK) { - dbus_connection_unref(dbus_conn); + dbus_connection_unref(conn->dbus.conn); goto failed; } - /* Remove object paths (the reconnection callback must re-add these */ - iter = conn->method_ctx_list; - while (iter != NULL) { - DLIST_REMOVE(conn->method_ctx_list, iter); - purge = iter; - iter = iter->next; - talloc_unlink(conn, purge); + /* Re-register object paths */ + mh = conn->method_list; + while (mh) { + dbret = dbus_connection_register_object_path(conn->dbus.conn, + mh->method_ctx->path, + mh->dbus_vtable, mh); + if (!dbret) { + DEBUG(0, ("Could not register object path.\n")); + dbus_connection_unref(conn->dbus.conn); + goto failed; + } + mh = mh->next; } /* Reset retries to 0 to resume dispatch processing */ @@ -618,8 +579,8 @@ static void sbus_reconnect(struct tevent_context *ev, * reconnection was successful */ conn->reconnect_callback(conn, - SBUS_RECONNECT_SUCCESS, - conn->reconnect_pvt); + SBUS_RECONNECT_SUCCESS, + conn->reconnect_pvt); return; } @@ -634,28 +595,30 @@ failed: /* Check if we've passed our last chance or if we've lost track of * our retry count somehow */ - if (((conn->max_retries > 0) && - (conn->retries > conn->max_retries)) || - conn->retries <= 0) { + if ((conn->retries > conn->max_retries) || (conn->retries <= 0)) { conn->reconnect_callback(conn, - SBUS_RECONNECT_EXCEEDED_RETRIES, - conn->reconnect_pvt); + SBUS_RECONNECT_EXCEEDED_RETRIES, + conn->reconnect_pvt); } if (conn->retries == 2) { - tv.tv_sec += 3; /* Wait 3 seconds before the second reconnect attempt */ + /* Wait 3 seconds before the second reconnect attempt */ + tv.tv_sec += 3; } else if (conn->retries == 3) { - tv.tv_sec += 10; /* Wait 10 seconds before the third reconnect attempt */ + /* Wait 10 seconds before the third reconnect attempt */ + tv.tv_sec += 10; } else { - tv.tv_sec += 30; /* Wait 30 seconds before all subsequent reconnect attempts */ + /* Wait 30 seconds before all subsequent reconnect attempts */ + tv.tv_sec += 30; } - event = tevent_add_timer(conn->ev, conn, tv, sbus_reconnect, conn); - if (event == NULL) { + + te = tevent_add_timer(conn->ev, conn, tv, sbus_reconnect, conn); + if (!te) { conn->reconnect_callback(conn, - SBUS_RECONNECT_ERROR, - conn->reconnect_pvt); + SBUS_RECONNECT_ERROR, + conn->reconnect_pvt); } } @@ -670,18 +633,19 @@ static int sbus_auto_reconnect(struct sbus_connection *conn) struct timeval tv; conn->retries++; - if ((conn->max_retries > 0) && - (conn->retries >= conn->max_retries)) { - /* Return EAGAIN (to tell the calling process it + if (conn->retries >= conn->max_retries) { + /* Return EIO (to tell the calling process it * needs to create a new connection from scratch */ - return EAGAIN; + return EIO; } gettimeofday(&tv, NULL); tv.tv_sec += 1; /* Wait 1 second before the first reconnect attempt */ te = tevent_add_timer(conn->ev, conn, tv, sbus_reconnect, conn); - if (te == NULL) return EAGAIN; + if (!te) { + return EIO; + } return EOK; } @@ -692,7 +656,7 @@ void sbus_reconnect_init(struct sbus_connection *conn, sbus_conn_reconn_callback_fn callback, void *pvt) { - if(max_retries == 0 || callback == NULL) return; + if (max_retries < 0 || callback == NULL) return; conn->retries = 0; conn->max_retries = max_retries; @@ -708,6 +672,6 @@ bool sbus_conn_disconnecting(struct sbus_connection *conn) void sbus_conn_send_reply(struct sbus_connection *conn, DBusMessage *reply) { - dbus_connection_send(conn->dbus_conn, reply, NULL); + dbus_connection_send(conn->dbus.conn, reply, NULL); } diff --git a/server/sbus/sssd_dbus_private.h b/server/sbus/sssd_dbus_private.h index fdee121e..01eaf00d 100644 --- a/server/sbus/sssd_dbus_private.h +++ b/server/sbus/sssd_dbus_private.h @@ -1,27 +1,49 @@ #ifndef _SSSD_DBUS_PRIVATE_H_ #define _SSSD_DBUS_PRIVATE_H_ -union dbus_pointer { +union dbus_conn_pointer { DBusServer *server; DBusConnection *conn; }; -enum dbus_pointer_type { +enum dbus_conn_type { SBUS_SERVER, SBUS_CONNECTION }; -struct sbus_generic_dbus_ctx { +struct sbus_connection { struct tevent_context *ev; - enum dbus_pointer_type type; - union dbus_pointer dbus; + + enum dbus_conn_type type; + union dbus_conn_pointer dbus; + + char *address; + int connection_type; + int disconnect; + + sbus_conn_destructor_fn destructor; + void *pvt_data; /* Private data for this connection */ + + /* dbus tables and handlers */ + struct method_holder *method_list; + + /* reconnect settings */ + int retries; + int max_retries; + sbus_conn_reconn_callback_fn reconnect_callback; + /* Private data needed to reinit after reconnection */ + void *reconnect_pvt; + + /* server related stuff */ + struct sbus_method_ctx *server_method; + sbus_server_conn_init_fn srv_init_fn; + void *srv_init_data; }; /* =Watches=============================================================== */ struct sbus_watch_ctx { DBusWatch *dbus_watch; - enum dbus_pointer_type dbus_type; - union dbus_pointer dbus; + struct sbus_connection *conn; struct tevent_fd *fde; }; diff --git a/server/sbus/sssd_dbus_server.c b/server/sbus/sssd_dbus_server.c index 5c247fcc..8a123d6d 100644 --- a/server/sbus/sssd_dbus_server.c +++ b/server/sbus/sssd_dbus_server.c @@ -25,24 +25,6 @@ #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_private.h" -/* Types */ -struct sbus_srv_ctx { - DBusServer *dbus_server; - /* - * 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 tevent_context *ev; - struct sbus_method_ctx *sd_ctx; - sbus_server_conn_init_fn init_fn; - void *init_pvt_data; -}; - static int sbus_server_destructor(void *ctx); /* @@ -56,19 +38,18 @@ static void sbus_server_init_new_connection(DBusServer *dbus_server, DBusConnection *dbus_conn, void *data) { - struct sbus_srv_ctx *srv_ctx; + struct sbus_connection *server; struct sbus_connection *conn; - struct sbus_method_ctx *iter; int ret; DEBUG(5,("Entering.\n")); - srv_ctx = talloc_get_type(data, struct sbus_srv_ctx); - if (srv_ctx == NULL) { + server = talloc_get_type(data, struct sbus_connection); + if (!server) { return; } DEBUG(5,("Adding connection %lX.\n", conn)); - ret = sbus_add_connection(srv_ctx, srv_ctx->ev, dbus_conn, + ret = sbus_add_connection(server, server->ev, dbus_conn, &conn, SBUS_CONN_TYPE_PRIVATE); if (ret != 0) { dbus_connection_close(dbus_conn); @@ -80,12 +61,7 @@ static void sbus_server_init_new_connection(DBusServer *dbus_server, DEBUG(5,("Got a connection\n")); - /* Set up global methods */ - iter = srv_ctx->sd_ctx; - while (iter != NULL) { - sbus_conn_add_method_ctx(conn, iter); - iter = iter->next; - } + sbus_conn_add_method_ctx(conn, server->server_method); /* * Initialize connection-specific features @@ -95,9 +71,11 @@ static void sbus_server_init_new_connection(DBusServer *dbus_server, * This function (or its callbacks) should also * set up connection-specific methods. */ - ret = srv_ctx->init_fn(conn, srv_ctx->init_pvt_data); + ret = server->srv_init_fn(conn, server->srv_init_data); if (ret != EOK) { DEBUG(1,("Initialization failed!\n")); + dbus_connection_close(dbus_conn); + talloc_zfree(conn); } } @@ -107,18 +85,19 @@ static void sbus_server_init_new_connection(DBusServer *dbus_server, * for handling file descriptor and timed events */ int sbus_new_server(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, struct sbus_method_ctx *ctx, - struct sbus_srv_ctx **_srv_ctx, const char *address, + struct tevent_context *ev, + const char *address, + struct sbus_method_ctx *method, + struct sbus_connection **_server, sbus_server_conn_init_fn init_fn, void *init_pvt_data) { - struct sbus_generic_dbus_ctx *gen_ctx; - struct sbus_srv_ctx *srv_ctx; + struct sbus_connection *server; DBusServer *dbus_server; DBusError dbus_error; dbus_bool_t dbret; char *tmp; - *_srv_ctx = NULL; + *_server = NULL; /* Set up D-BUS server */ dbus_error_init(&dbus_error); @@ -134,66 +113,60 @@ int sbus_new_server(TALLOC_CTX *mem_ctx, DEBUG(3, ("D-BUS Server listening on %s\n", tmp)); free(tmp); - srv_ctx = talloc_zero(mem_ctx, struct sbus_srv_ctx); - if (!srv_ctx) { + server = talloc_zero(mem_ctx, struct sbus_connection); + if (!server) { return ENOMEM; } - srv_ctx->ev = ev; - srv_ctx->dbus_server = dbus_server; - srv_ctx->sd_ctx = ctx; - srv_ctx->init_fn = init_fn; - srv_ctx->init_pvt_data = init_pvt_data; + server->ev = ev; + server->type = SBUS_SERVER; + server->dbus.server = dbus_server; + server->server_method = method; + server->srv_init_fn = init_fn; + server->srv_init_data = init_pvt_data; - gen_ctx = talloc_zero(srv_ctx, struct sbus_generic_dbus_ctx); - if (!gen_ctx) { - talloc_free(srv_ctx); - return ENOMEM; - } - gen_ctx->ev = ev; - gen_ctx->type = SBUS_SERVER; - gen_ctx->dbus.server = dbus_server; - - talloc_set_destructor((TALLOC_CTX *)srv_ctx, sbus_server_destructor); + talloc_set_destructor((TALLOC_CTX *)server, sbus_server_destructor); /* Set up D-BUS new connection handler */ - dbus_server_set_new_connection_function(srv_ctx->dbus_server, + dbus_server_set_new_connection_function(server->dbus.server, sbus_server_init_new_connection, - srv_ctx, NULL); + server, NULL); /* Set up DBusWatch functions */ - dbret = dbus_server_set_watch_functions(srv_ctx->dbus_server, + dbret = dbus_server_set_watch_functions(server->dbus.server, sbus_add_watch, sbus_remove_watch, sbus_toggle_watch, - gen_ctx, NULL); + server, NULL); if (!dbret) { DEBUG(4, ("Error setting up D-BUS server watch functions")); - talloc_free(srv_ctx); + talloc_free(server); return EIO; } /* Set up DBusTimeout functions */ - dbret = dbus_server_set_timeout_functions(srv_ctx->dbus_server, + dbret = dbus_server_set_timeout_functions(server->dbus.server, sbus_add_timeout, sbus_remove_timeout, sbus_toggle_timeout, - gen_ctx, NULL); + server, NULL); if (!dbret) { DEBUG(4,("Error setting up D-BUS server timeout functions")); - dbus_server_set_watch_functions(srv_ctx->dbus_server, + dbus_server_set_watch_functions(server->dbus.server, NULL, NULL, NULL, NULL, NULL); - talloc_free(srv_ctx); + talloc_free(server); return EIO; } - *_srv_ctx = srv_ctx; + *_server = server; return EOK; } static int sbus_server_destructor(void *ctx) { - struct sbus_srv_ctx *srv_ctx = talloc_get_type(ctx, struct sbus_srv_ctx); - dbus_server_disconnect(srv_ctx->dbus_server); + struct sbus_connection *server; + + server = talloc_get_type(ctx, struct sbus_connection); + dbus_server_disconnect(server->dbus.server); return 0; } |