From 124083f5801312aeef6f97402dba181d98eb708c Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Mon, 15 Dec 2008 10:12:43 -0500 Subject: Disconnected client SBUS connections would delete the master set of sbus_method_ctx entries, meaning that the next connection to attempt to disconnect would receive a segmentation fault also trying to delete them. They are now talloc_reference()-ed to their connection context and talloc_unlink()-ed upon deletion. I have also modified the sbus_new_server() call to take a reference to an sbus_srv_ctx object as a return argument, so that the calling function can keep track of the SBUS server context if it so chooses. --- server/monitor.c | 18 ++++++++++-------- server/providers/data_provider.c | 6 +++++- server/sbus/sssd_dbus.h | 3 ++- server/sbus/sssd_dbus_connection.c | 3 ++- server/sbus/sssd_dbus_server.c | 7 +++++-- 5 files changed, 24 insertions(+), 13 deletions(-) (limited to 'server') diff --git a/server/monitor.c b/server/monitor.c index 81aadf44b..73f993ed7 100644 --- a/server/monitor.c +++ b/server/monitor.c @@ -67,6 +67,7 @@ struct mt_ctx { struct confdb_ctx *cdb; char **services; struct mt_svc *svc_list; + struct sbus_srv_ctx *sbus_srv; int service_id_timeout; int service_ping_time; @@ -114,6 +115,7 @@ 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 *sbus_address; char *default_monitor_address; int ret; @@ -155,7 +157,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->ev, sd_ctx, sbus_address, dbus_service_init, ctx); + ret = sbus_new_server(ctx->ev, sd_ctx, &sbus_srv, sbus_address, dbus_service_init, ctx); + ctx->sbus_srv = sbus_srv; return ret; } @@ -378,10 +381,10 @@ int monitor_process_init(TALLOC_CTX *mem_ctx, talloc_free(ctx); return ENOMEM; } - svc->name = talloc_strdup(svc, doms[i]); + svc->name = talloc_asprintf(svc, "%%BE_%s", doms[i]); svc->mt_ctx = ctx; - path = talloc_asprintf(svc, "config/domains/%s", svc->name); + path = talloc_asprintf(svc, "config/domains/%s", doms[i]); if (!path) { talloc_free(ctx); return ENOMEM; @@ -389,8 +392,7 @@ int monitor_process_init(TALLOC_CTX *mem_ctx, ret = confdb_get_string(cdb, svc, path, "command", NULL, &svc->command); if (ret != EOK) { - DEBUG(0, ("Failed to find provider [%s] configuration\n", - svc->name)); + DEBUG(0, ("Failed to find provider [%s] configuration\n", doms[i])); talloc_free(svc); continue; } @@ -398,16 +400,16 @@ int monitor_process_init(TALLOC_CTX *mem_ctx, /* if no command is present to not run the domain */ if (svc->command == NULL) { /* the LOCAL domain does not need a backend at the moment */ - if (strcasecmp(svc->name, "LOCAL") != 0) { + if (strcasecmp(doms[i], "LOCAL") != 0) { DEBUG(0, ("Missing command to run provider [%s]\n")); } talloc_free(svc); continue; } - ret = start_service(svc->name, svc->command, &svc->pid); + ret = start_service(doms[i], svc->command, &svc->pid); if (ret != EOK) { - DEBUG(0,("Failed to start provider '%s'\n", svc->name)); + DEBUG(0,("Failed to start provider for '%s'\n", doms[i])); talloc_free(svc); continue; } diff --git a/server/providers/data_provider.c b/server/providers/data_provider.c index 3bd0ef59d..150c6f6ae 100644 --- a/server/providers/data_provider.c +++ b/server/providers/data_provider.c @@ -49,6 +49,7 @@ struct dp_ctx { struct confdb_ctx *cdb; struct ldb_context *ldb; struct service_sbus_ctx *ss_ctx; + struct sbus_srv_ctx *sbus_srv; struct dp_backend *be_list; struct dp_frontend *fe_list; }; @@ -406,6 +407,7 @@ 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; @@ -449,11 +451,13 @@ 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->ev, sd_ctx, dpbus_address, + ret = sbus_new_server(dpctx->ev, sd_ctx, + &sbus_srv, dpbus_address, dbus_dp_init, dpctx); if (ret != EOK) { goto done; } + dpctx->sbus_srv = sbus_srv; talloc_steal(dpctx, sd_ctx); done: diff --git a/server/sbus/sssd_dbus.h b/server/sbus/sssd_dbus.h index 75567ac04..398469945 100644 --- a/server/sbus/sssd_dbus.h +++ b/server/sbus/sssd_dbus.h @@ -23,6 +23,7 @@ #define _SSSD_DBUS_H_ struct sbus_conn_ctx; +struct sbus_srv_ctx; #include "dbus/dbus.h" @@ -67,7 +68,7 @@ struct sbus_message_handler_ctx { /* Server Functions */ int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx, - const char *address, + struct sbus_srv_ctx **server_ctx, const char *address, sbus_server_conn_init_fn init_fn, void *init_pvt_data); /* Connection Functions */ diff --git a/server/sbus/sssd_dbus_connection.c b/server/sbus/sssd_dbus_connection.c index b1c765562..e4e122648 100644 --- a/server/sbus/sssd_dbus_connection.c +++ b/server/sbus/sssd_dbus_connection.c @@ -548,6 +548,7 @@ int sbus_conn_add_method_ctx(struct sbus_conn_ctx *dct_ctx, } DLIST_ADD(dct_ctx->method_ctx_list, method_ctx); + talloc_reference(dct_ctx, method_ctx); /* Set up the vtable for the object path */ connection_vtable = talloc_zero(dct_ctx, DBusObjectPathVTable); @@ -603,7 +604,7 @@ static void sbus_unreg_object_paths(struct sbus_conn_ctx *dct_ctx) DLIST_REMOVE(dct_ctx->method_ctx_list, iter); purge = iter; iter = iter->next; - talloc_free(purge); + talloc_unlink(dct_ctx, purge); } } diff --git a/server/sbus/sssd_dbus_server.c b/server/sbus/sssd_dbus_server.c index 182e31010..d1d937393 100644 --- a/server/sbus/sssd_dbus_server.c +++ b/server/sbus/sssd_dbus_server.c @@ -254,8 +254,8 @@ static void sbus_server_init_new_connection(DBusServer *server, * for handling file descriptor and timed events */ int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx, - const char *address, sbus_server_conn_init_fn init_fn, - void *init_pvt_data) + struct sbus_srv_ctx **server_ctx, const char *address, + sbus_server_conn_init_fn init_fn, void *init_pvt_data) { struct sbus_srv_ctx *srv_ctx; DBusServer *dbus_server; @@ -263,6 +263,8 @@ int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx, dbus_bool_t dbret; char *tmp; + *server_ctx = NULL; + /* Set up D-BUS server */ dbus_error_init(&dbus_error); dbus_server = dbus_server_listen(address, &dbus_error); @@ -320,6 +322,7 @@ int sbus_new_server(struct event_context *ev, struct sbus_method_ctx *ctx, return EIO; } + *server_ctx = srv_ctx; return EOK; } -- cgit