summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2008-10-28 09:10:01 -0400
committerSimo Sorce <idra@samba.org>2008-11-03 10:12:29 -0500
commit0d3fad824641eabd2e856f7b4aa7828367bba5fa (patch)
tree78ac333a9e9a5d38962d34a79ea695f1fc17171f
parentf95d98094c3872199eaed59da48a76c44d0e0531 (diff)
downloadsssd-0d3fad824641eabd2e856f7b4aa7828367bba5fa.tar.gz
sssd-0d3fad824641eabd2e856f7b4aa7828367bba5fa.tar.bz2
sssd-0d3fad824641eabd2e856f7b4aa7828367bba5fa.zip
Fixed segfault issue when remote connection is lost.
-rw-r--r--server/dbus/sssd_dbus.h7
-rw-r--r--server/dbus/sssd_dbus_common.c1
-rw-r--r--server/dbus/sssd_dbus_connection.c42
-rw-r--r--server/dbus/sssd_dbus_server.c10
-rw-r--r--server/monitor.c16
5 files changed, 67 insertions, 9 deletions
diff --git a/server/dbus/sssd_dbus.h b/server/dbus/sssd_dbus.h
index 19c05ff5..547aaad2 100644
--- a/server/dbus/sssd_dbus.h
+++ b/server/dbus/sssd_dbus.h
@@ -25,6 +25,13 @@
typedef int (*sssd_dbus_msg_handler_fn)(DBusMessage *msg, void *data,
DBusMessage **reply);
+extern int connection_type_slot;
+
+enum {
+ DBUS_CONNECTION_TYPE_PRIVATE = 1,
+ DBUS_CONNECTION_TYPE_SHARED
+};
+
struct sssd_dbus_method {
const char *method;
sssd_dbus_msg_handler_fn fn;
diff --git a/server/dbus/sssd_dbus_common.c b/server/dbus/sssd_dbus_common.c
index 939e596a..cd6e1f9a 100644
--- a/server/dbus/sssd_dbus_common.c
+++ b/server/dbus/sssd_dbus_common.c
@@ -41,4 +41,5 @@ void remove_timeout(DBusTimeout *timeout, void *data) {
/* Freeing the event object will remove it from the event loop */
talloc_free(te);
+ dbus_timeout_set_data(timeout, NULL, NULL);
}
diff --git a/server/dbus/sssd_dbus_connection.c b/server/dbus/sssd_dbus_connection.c
index d5bd28ff..991a28fe 100644
--- a/server/dbus/sssd_dbus_connection.c
+++ b/server/dbus/sssd_dbus_connection.c
@@ -5,10 +5,14 @@
#include "dbus/sssd_dbus.h"
#include "dbus/sssd_dbus_private.h"
+dbus_int32_t connection_type_slot = -1;
+dbus_int32_t connection_destructor_slot = -1;
+
/* Types */
struct dbus_connection_toplevel_context {
DBusConnection *conn;
struct event_context *ev;
+ /*sssd_dbus_connection_destructor_fn destructor;*/
};
struct dbus_connection_watch_context {
@@ -30,10 +34,31 @@ static void do_dispatch(struct event_context *ev,
{
struct timed_event *new_event;
DBusConnection *conn;
+ int connection_type;
int ret;
conn = (DBusConnection *)data;
+ if(!dbus_connection_get_is_connected(conn)) {
+ DEBUG(0,("Connection is not open for dispatching.\n"));
+ connection_type = *(int *)(dbus_connection_get_data(conn, connection_type_slot));
+ if (connection_type == DBUS_CONNECTION_TYPE_PRIVATE) {
+ /* Private connections must be closed explicitly */
+ dbus_connection_close(conn);
+ dbus_connection_unref(conn);
+ } else if (connection_type == DBUS_CONNECTION_TYPE_SHARED) {
+ /* Shared connections are destroyed when their last reference is removed */
+ dbus_connection_unref(conn);
+ }
+ else {
+ /* Critical Error! */
+ DEBUG(0,("Critical Error, connection_type is neither shared nor private!\n"))
+ }
+ dbus_connection_set_data(conn,connection_type_slot, NULL, NULL);
+
+ return;
+ }
+
/* Dispatch only once each time through the mainloop to avoid
* starving other features
*/
@@ -42,6 +67,7 @@ static void do_dispatch(struct event_context *ev,
DEBUG(2,("Dispatching.\n"));
dbus_connection_dispatch(conn);
}
+
/* If other dispatches are waiting, queue up the do_dispatch function
* for the next loop.
*/
@@ -50,6 +76,8 @@ static void do_dispatch(struct event_context *ev,
new_event = event_add_timed(ev, ev, tv, do_dispatch, conn);
if (new_event == NULL) {
DEBUG(0,("Could not add dispatch event!\n"));
+
+ /* TODO: Calling exit here is bad */
exit(1);
}
}
@@ -59,7 +87,6 @@ static void do_dispatch(struct event_context *ev,
* 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)
@@ -67,6 +94,7 @@ static void dbus_connection_read_write_handler(struct event_context *ev,
struct dbus_connection_watch_context *conn_w_ctx;
conn_w_ctx = talloc_get_type(data, struct dbus_connection_watch_context);
+ DEBUG(0,("Connection is open for read/write.\n"));
dbus_connection_ref(conn_w_ctx->top->conn);
if (flags & EVENT_FD_READ) {
dbus_watch_handle(conn_w_ctx->watch, DBUS_WATCH_READABLE);
@@ -214,6 +242,7 @@ 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);
@@ -284,15 +313,26 @@ int sssd_new_dbus_connection(struct sssd_dbus_ctx *ctx, const char *address,
{
DBusConnection *dbus_conn;
DBusError dbus_error;
+ int connection_type;
int ret;
dbus_error_init(&dbus_error);
+
+ /* Open a shared D-BUS connection to the address */
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;
}
+
+ /* Allocate or increase the reference count of connection_type_slot */
+ if (!dbus_connection_allocate_data_slot(&connection_type_slot)) {
+ return ENOMEM;
+ }
+
+ connection_type = DBUS_CONNECTION_TYPE_SHARED;
+ dbus_connection_set_data(dbus_conn, connection_type_slot, &connection_type, NULL);
ret = sssd_add_dbus_connection(ctx, dbus_conn);
if (ret == EOK) {
diff --git a/server/dbus/sssd_dbus_server.c b/server/dbus/sssd_dbus_server.c
index 6ad8e0dd..c6bc7db9 100644
--- a/server/dbus/sssd_dbus_server.c
+++ b/server/dbus/sssd_dbus_server.c
@@ -252,10 +252,20 @@ static void new_connection_callback(DBusServer *server, DBusConnection *conn,
{
struct dbus_server_toplevel_context *dst_ctx;
DBusObjectPathVTable *monitor_vtable;
+ int *connection_type;
int ret;
dst_ctx = talloc_get_type(data,struct dbus_server_toplevel_context);
+ if (!dbus_connection_allocate_data_slot(&connection_type_slot)) {
+ dbus_connection_close(conn);
+ 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);
if (ret != 0) {
dbus_connection_close(conn);
diff --git a/server/monitor.c b/server/monitor.c
index b11e4e0c..f651b79f 100644
--- a/server/monitor.c
+++ b/server/monitor.c
@@ -204,14 +204,6 @@ int start_monitor(TALLOC_CTX *mem_ctx,
return EINVAL;
}
- /* Initialize D-BUS Server
- * The monitor will act as a D-BUS server for all
- * SSSD processes */
- ret = monitor_dbus_init(ctx);
- if (ret != EOK) {
- return ret;
- }
-
for (i = 0; ctx->services[i]; i++) {
srv = talloc_zero(ctx, struct mt_srv);
@@ -230,6 +222,14 @@ int start_monitor(TALLOC_CTX *mem_ctx,
set_tasks_checker(srv);
}
+
+ /* Initialize D-BUS Server
+ * The monitor will act as a D-BUS server for all
+ * SSSD processes */
+ ret = monitor_dbus_init(ctx);
+ if (ret != EOK) {
+ return ret;
+ }
return EOK;
}