summaryrefslogtreecommitdiffstats
path: root/server/monitor
diff options
context:
space:
mode:
Diffstat (limited to 'server/monitor')
-rw-r--r--server/monitor/monitor.c397
-rw-r--r--server/monitor/monitor_interfaces.h12
-rw-r--r--server/monitor/monitor_sbus.c154
-rw-r--r--server/monitor/monitor_sbus.h6
4 files changed, 371 insertions, 198 deletions
diff --git a/server/monitor/monitor.c b/server/monitor/monitor.c
index ead921c06..f9dc9b0cb 100644
--- a/server/monitor/monitor.c
+++ b/server/monitor/monitor.c
@@ -58,16 +58,15 @@
#define MONITOR_DEF_PING_TIME 10
#define MONITOR_CONF_ENTRY "config/services/monitor"
-struct mt_conn {
- struct sbus_connection *conn;
- struct mt_svc *svc_ptr;
-};
+struct svc_spy;
struct mt_svc {
struct mt_svc *prev;
struct mt_svc *next;
- struct mt_conn *mt_conn;
+ struct sbus_connection *conn;
+ struct svc_spy *conn_spy;
+
struct mt_ctx *mt_ctx;
char *provider;
@@ -121,8 +120,7 @@ struct mt_ctx {
static int start_service(struct mt_svc *mt_svc);
-static int dbus_service_init(struct sbus_connection *conn, void *data);
-static void identity_check(DBusPendingCall *pending, void *data);
+static int monitor_service_init(struct sbus_connection *conn, void *data);
static int service_send_ping(struct mt_svc *svc);
static void ping_check(DBusPendingCall *pending, void *data);
@@ -147,17 +145,18 @@ static int monitor_cleanup(void);
/* dbus_get_monitor_version
* Return the monitor version over D-BUS */
-static int dbus_get_monitor_version(DBusMessage *message,
- struct sbus_connection *conn)
+static int get_monitor_version(DBusMessage *message,
+ struct sbus_connection *conn)
{
- const char *version = MONITOR_VERSION;
+ dbus_uint16_t version = MONITOR_VERSION;
DBusMessage *reply;
dbus_bool_t ret;
reply = dbus_message_new_method_return(message);
if (!reply) return ENOMEM;
- ret = dbus_message_append_args(reply, DBUS_TYPE_STRING,
- &version, DBUS_TYPE_INVALID);
+ ret = dbus_message_append_args(reply,
+ DBUS_TYPE_UINT16, &version,
+ DBUS_TYPE_INVALID);
if (!ret) {
dbus_message_unref(reply);
return EIO;
@@ -170,14 +169,164 @@ static int dbus_get_monitor_version(DBusMessage *message,
return EOK;
}
+struct mon_init_conn {
+ struct mt_ctx *ctx;
+ struct sbus_connection *conn;
+ struct tevent_timer *timeout;
+};
+
+static int add_svc_conn_spy(struct mt_svc *svc);
+
+/* registers a new client.
+ * if operation is successful also sends back the Monitor version */
+static int client_registration(DBusMessage *message,
+ struct sbus_connection *conn)
+{
+ dbus_uint16_t version = MONITOR_VERSION;
+ struct mon_init_conn *mini;
+ struct mt_svc *svc;
+ void *data;
+ DBusMessage *reply;
+ DBusError dbus_error;
+ dbus_uint16_t svc_ver;
+ char *svc_name;
+ dbus_bool_t dbret;
+ int ret;
+
+ data = sbus_conn_get_private_data(conn);
+ mini = talloc_get_type(data, struct mon_init_conn);
+ if (!mini) {
+ DEBUG(0, ("Connection holds no valid init data\n"));
+ return EINVAL;
+ }
+
+ /* First thing, cancel the timeout */
+ talloc_zfree(mini->timeout);
+
+ dbus_error_init(&dbus_error);
+
+ dbret = dbus_message_get_args(message, &dbus_error,
+ DBUS_TYPE_STRING, &svc_name,
+ DBUS_TYPE_UINT16, &svc_ver,
+ DBUS_TYPE_INVALID);
+ if (!dbret) {
+ DEBUG(1, ("Failed to parse message, killing connection\n"));
+ if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
+ sbus_disconnect(conn);
+ /* FIXME: should we just talloc_zfree(conn) ? */
+ goto done;
+ }
+
+ DEBUG(4, ("Received ID registration: (%s,%d)\n", svc_name, svc_ver));
+
+ /* search this service in the list */
+ svc = mini->ctx->svc_list;
+ while (svc) {
+ ret = strcasecmp(svc->identity, svc_name);
+ if (ret == 0) {
+ break;
+ }
+ svc = svc->next;
+ }
+ if (!svc) {
+ DEBUG(0, ("Unable to find peer [%s] in list of services,"
+ " killing connection!\n", svc_name));
+ sbus_disconnect(conn);
+ /* FIXME: should we just talloc_zfree(conn) ? */
+ goto done;
+ }
+
+ /* Fill in svc structure with connection data */
+ svc->conn = mini->conn;
+
+ /* we need to attach a spy to the connection structure so that if some code
+ * frees it we can zero it out in the service structure. Otherwise we may
+ * try to access or even free, freed memory. */
+ ret = add_svc_conn_spy(svc);
+ if (ret) {
+ DEBUG(0, ("Failed to attch spy\n"));
+ goto done;
+ }
+
+ /* reply that all is ok */
+ reply = dbus_message_new_method_return(message);
+ if (!reply) return ENOMEM;
+
+ dbret = dbus_message_append_args(reply,
+ DBUS_TYPE_UINT16, &version,
+ DBUS_TYPE_INVALID);
+ if (!dbret) {
+ dbus_message_unref(reply);
+ return EIO;
+ }
+
+ /* send reply back */
+ sbus_conn_send_reply(conn, reply);
+ dbus_message_unref(reply);
+
+done:
+ /* init complete, get rid of temp init context */
+ talloc_zfree(mini);
+
+ return EOK;
+}
+
+struct svc_spy {
+ struct mt_svc *svc;
+};
+
+static int svc_destructor(void *mem)
+{
+ struct mt_svc *svc = talloc_get_type(mem, struct mt_svc);
+ if (!svc) {
+ /* ?!?!? */
+ return 0;
+ }
+
+ /* svc is beeing freed, neutralize the spy */
+ if (svc->conn_spy) {
+ talloc_set_destructor((TALLOC_CTX *)svc->conn_spy, NULL);
+ talloc_zfree(svc->conn_spy);
+ }
+ return 0;
+}
+
+static int svc_spy_destructor(void *mem)
+{
+ struct svc_spy *spy = talloc_get_type(mem, struct svc_spy);
+ if (!spy) {
+ /* ?!?!? */
+ return 0;
+ }
+
+ /* svc->conn has been freed, NULL the pointer in svc */
+ spy->svc->conn = NULL;
+ return 0;
+}
+
+static int add_svc_conn_spy(struct mt_svc *svc)
+{
+ struct svc_spy *spy;
+
+ spy = talloc(svc->conn, struct svc_spy);
+ if (!spy) return ENOMEM;
+
+ spy->svc = svc;
+ talloc_set_destructor((TALLOC_CTX *)spy, svc_spy_destructor);
+ svc->conn_spy = spy;
+
+ return EOK;
+}
+
struct sbus_method monitor_methods[] = {
- { MON_SRV_METHOD_VERSION, dbus_get_monitor_version },
+ { MON_SRV_METHOD_VERSION, get_monitor_version },
+ { MON_SRV_METHOD_REGISTER, client_registration },
{ NULL, NULL }
};
struct sbus_interface monitor_server_interface = {
- MONITOR_DBUS_INTERFACE,
- MONITOR_DBUS_PATH,
+ MON_SRV_INTERFACE,
+ MON_SRV_PATH,
SBUS_DEFAULT_VTABLE,
monitor_methods,
NULL
@@ -198,7 +347,7 @@ static int monitor_dbus_init(struct mt_ctx *ctx)
ret = sbus_new_server(ctx, ctx->ev,
monitor_address, &monitor_server_interface,
- &ctx->sbus_srv, dbus_service_init, ctx);
+ &ctx->sbus_srv, monitor_service_init, ctx);
talloc_free(monitor_address);
@@ -394,10 +543,8 @@ static void shutdown_reply(DBusPendingCall *pending, void *data)
{
DBusMessage *reply;
int type;
- struct sbus_connection *conn;
struct mt_svc *svc = talloc_get_type(data, struct mt_svc);
- conn = svc->mt_conn->conn;
reply = dbus_pending_call_steal_reply(pending);
if (!reply) {
/* reply should never be null. This function shouldn't be called
@@ -448,7 +595,7 @@ static int monitor_shutdown_service(struct mt_svc *svc)
/* Stop the service checker */
- dbus_conn = sbus_get_connection(svc->mt_conn->conn);
+ dbus_conn = sbus_get_connection(svc->conn);
/* Construct a shutdown message */
msg = dbus_message_new_method_call(NULL,
@@ -482,10 +629,8 @@ static int monitor_shutdown_service(struct mt_svc *svc)
static void reload_reply(DBusPendingCall *pending, void *data)
{
DBusMessage *reply;
- struct sbus_connection *conn;
struct mt_svc *svc = talloc_get_type(data, struct mt_svc);
- conn = svc->mt_conn->conn;
reply = dbus_pending_call_steal_reply(pending);
if (!reply) {
/* reply should never be null. This function shouldn't be called
@@ -496,7 +641,7 @@ static void reload_reply(DBusPendingCall *pending, void *data)
" and no timeout occurred\n"));
/* Destroy this connection */
- sbus_disconnect(conn);
+ sbus_disconnect(svc->conn);
goto done;
}
@@ -558,7 +703,7 @@ static int service_signal(struct mt_svc *svc, const char *svc_signal)
return EOK;
}
- if (!svc->mt_conn) {
+ if (!svc->conn) {
/* Avoid a race condition where we are trying to
* order a service to reload that hasn't started
* yet.
@@ -567,7 +712,7 @@ static int service_signal(struct mt_svc *svc, const char *svc_signal)
return EIO;
}
- dbus_conn = sbus_get_connection(svc->mt_conn->conn);
+ dbus_conn = sbus_get_connection(svc->conn);
msg = dbus_message_new_method_call(NULL,
MONITOR_PATH,
MONITOR_INTERFACE,
@@ -809,6 +954,8 @@ static int get_provider_config(struct mt_ctx *ctx, const char *name,
}
svc->mt_ctx = ctx;
+ talloc_set_destructor((TALLOC_CTX *)svc, svc_destructor);
+
svc->name = talloc_strdup(svc, name);
if (!svc->name) {
talloc_free(svc);
@@ -1745,195 +1892,60 @@ int monitor_process_init(TALLOC_CTX *mem_ctx,
return EOK;
}
-static int mt_conn_destructor(void *ptr)
+static void init_timeout(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval t, void *ptr)
{
- struct mt_conn *mt_conn;
- struct mt_svc *svc;
+ struct mon_init_conn *mini;
- mt_conn = talloc_get_type(ptr, struct mt_conn);
- svc = mt_conn->svc_ptr;
+ DEBUG(2, ("Client timed out before Identification!\n"));
- /* now clear up so that the rest of the code will know there
- * is no connection attached to the service anymore */
- svc->mt_conn = NULL;
+ mini = talloc_get_type(ptr, struct mon_init_conn);
- return 0;
+ sbus_disconnect(mini->conn);
+ talloc_zfree(mini);
}
/*
- * dbus_service_init
- * This function should initiate a query to the newly connected
- * service to discover the service's identity (invoke the getIdentity
- * method on the new client). The reply callback for this request
- * should set the connection destructor appropriately.
+ * monitor_service_init
+ * Set up a timeout function and temporary connection structure.
+ * If the client does not identify before the timeout kicks in,
+ * the client is forcibly disconnected.
*/
-static int dbus_service_init(struct sbus_connection *conn, void *data)
+static int monitor_service_init(struct sbus_connection *conn, void *data)
{
struct mt_ctx *ctx;
- struct mt_svc *svc;
- struct mt_conn *mt_conn;
- DBusMessage *msg;
- DBusPendingCall *pending_reply;
- DBusConnection *dbus_conn;
- dbus_bool_t dbret;
+ struct mon_init_conn *mini;
+ struct timeval tv;
DEBUG(3, ("Initializing D-BUS Service\n"));
ctx = talloc_get_type(data, struct mt_ctx);
- dbus_conn = sbus_get_connection(conn);
- /* hang off this memory to the connection so that when the connection
- * is freed we can call a destructor to clear up the structure and
- * have a way to know we need to restart the service */
- mt_conn = talloc(conn, struct mt_conn);
- if (!mt_conn) {
+ mini = talloc(conn, struct mon_init_conn);
+ if (!mini) {
DEBUG(0,("Out of memory?!\n"));
- talloc_free(conn);
- return ENOMEM;
- }
- mt_conn->conn = conn;
-
- /* at this stage we still do not know what service is this
- * we will know only after we get its identity, so we make
- * up a temporary fake service and complete the operation
- * when we receive the reply */
- svc = talloc_zero(mt_conn, struct mt_svc);
- if (!svc) {
- talloc_free(conn);
+ talloc_zfree(conn);
return ENOMEM;
}
- svc->mt_ctx = ctx;
- svc->mt_conn = mt_conn;
+ mini->ctx = ctx;
+ mini->conn = conn;
- mt_conn->svc_ptr = svc;
- talloc_set_destructor((TALLOC_CTX *)mt_conn, mt_conn_destructor);
+ /* 5 seconds should be plenty */
+ tv = tevent_timeval_current_ofs(5, 0);
- /*
- * Set up identity request
- * This should be a well-known path and method
- * for all services
- */
- msg = dbus_message_new_method_call(NULL,
- MONITOR_PATH,
- MONITOR_INTERFACE,
- MON_CLI_METHOD_IDENTITY);
- if (msg == NULL) {
+ mini->timeout = tevent_add_timer(ctx->ev, mini, tv, init_timeout, mini);
+ if (!mini->timeout) {
DEBUG(0,("Out of memory?!\n"));
- talloc_free(conn);
+ talloc_zfree(conn);
return ENOMEM;
}
- dbret = dbus_connection_send_with_reply(dbus_conn, msg, &pending_reply,
- ctx->service_id_timeout);
- if (!dbret || pending_reply == NULL) {
- /*
- * Critical Failure
- * We can't communicate on this connection
- * We'll drop it using the default destructor.
- */
- DEBUG(0, ("D-BUS send failed.\n"));
- dbus_message_unref(msg);
- talloc_free(conn);
- return EIO;
- }
- /* Set up the reply handler */
- dbus_pending_call_set_notify(pending_reply, identity_check, svc, NULL);
- dbus_message_unref(msg);
+ sbus_conn_set_private_data(conn, mini);
return EOK;
}
-static void identity_check(DBusPendingCall *pending, void *data)
-{
- struct mt_svc *fake_svc;
- struct mt_svc *svc;
- struct sbus_connection *conn;
- DBusMessage *reply;
- DBusError dbus_error;
- dbus_uint16_t svc_ver;
- char *svc_name;
- dbus_bool_t ret;
- int type;
-
- fake_svc = talloc_get_type(data, struct mt_svc);
- conn = fake_svc->mt_conn->conn;
- dbus_error_init(&dbus_error);
-
- reply = dbus_pending_call_steal_reply(pending);
- if (!reply) {
- /* reply should never be null. This function shouldn't be called
- * until reply is valid or timeout has occurred. 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 and no timeout occurred\n"));
-
- /* Destroy this connection */
- sbus_disconnect(conn);
- goto done;
- }
-
- type = dbus_message_get_type(reply);
- switch (type) {
- case DBUS_MESSAGE_TYPE_METHOD_RETURN:
- ret = dbus_message_get_args(reply, &dbus_error,
- DBUS_TYPE_STRING, &svc_name,
- DBUS_TYPE_UINT16, &svc_ver,
- DBUS_TYPE_INVALID);
- if (!ret) {
- DEBUG(1,("Failed, to parse message, killing connection\n"));
- if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
- sbus_disconnect(conn);
- goto done;
- }
-
- DEBUG(4,("Received ID reply: (%s,%d)\n", svc_name, svc_ver));
-
- /* search this service in the list */
- svc = fake_svc->mt_ctx->svc_list;
- while (svc) {
- ret = strcasecmp(svc->identity, svc_name);
- if (ret == 0) {
- break;
- }
- svc = svc->next;
- }
- if (!svc) {
- DEBUG(0,("Unable to find peer [%s] in list of services, killing connection!\n", svc_name));
- sbus_disconnect(conn);
- goto done;
- }
-
- /* transfer all from the fake service and get rid of it */
- fake_svc->mt_conn->svc_ptr = svc;
- svc->mt_conn = fake_svc->mt_conn;
- talloc_free(fake_svc);
-
- DEBUG(1, ("Service %s connected\n", svc->name));
-
- /* Set up the destructor for this service */
- break;
-
- case DBUS_MESSAGE_TYPE_ERROR:
- DEBUG(0,("getIdentity returned an error [%s], closing connection.\n",
- dbus_message_get_error_name(reply)));
- /* Falling through to default intentionally*/
- default:
- /*
- * Timeout or other error occurred or something
- * unexpected happened.
- * It doesn't matter which, because either way we
- * know that this connection isn't trustworthy.
- * We'll destroy it now.
- */
- sbus_disconnect(conn);
- return;
- }
-
-done:
- dbus_pending_call_unref(pending);
- dbus_message_unref(reply);
-}
-
/* service_send_ping
* this function send a dbus ping to a service.
* It returns EOK if all is fine or ENXIO if the connection is
@@ -1947,13 +1959,14 @@ static int service_send_ping(struct mt_svc *svc)
DBusConnection *dbus_conn;
dbus_bool_t dbret;
- if (!svc->mt_conn) {
+ if (!svc->conn) {
+ DEBUG(8, ("Service not yet initialized\n"));
return ENXIO;
}
DEBUG(4,("Pinging %s\n", svc->name));
- dbus_conn = sbus_get_connection(svc->mt_conn->conn);
+ dbus_conn = sbus_get_connection(svc->conn);
/*
* Set up identity request
@@ -1966,7 +1979,7 @@ static int service_send_ping(struct mt_svc *svc)
MON_CLI_METHOD_PING);
if (!msg) {
DEBUG(0,("Out of memory?!\n"));
- talloc_free(svc->mt_conn->conn);
+ talloc_zfree(svc->conn);
return ENOMEM;
}
@@ -1979,7 +1992,7 @@ static int service_send_ping(struct mt_svc *svc)
* We'll drop it using the default destructor.
*/
DEBUG(0, ("D-BUS send failed.\n"));
- talloc_free(svc->mt_conn->conn);
+ talloc_zfree(svc->conn);
return EIO;
}
@@ -1993,13 +2006,11 @@ static int service_send_ping(struct mt_svc *svc)
static void ping_check(DBusPendingCall *pending, void *data)
{
struct mt_svc *svc;
- struct sbus_connection *conn;
DBusMessage *reply;
const char *dbus_error_name;
int type;
svc = talloc_get_type(data, struct mt_svc);
- conn = svc->mt_conn->conn;
reply = dbus_pending_call_steal_reply(pending);
if (!reply) {
@@ -2011,7 +2022,7 @@ static void ping_check(DBusPendingCall *pending, void *data)
" and no timeout occurred\n"));
/* Destroy this connection */
- sbus_disconnect(conn);
+ sbus_disconnect(svc->conn);
goto done;
}
@@ -2045,7 +2056,7 @@ static void ping_check(DBusPendingCall *pending, void *data)
* know that this connection isn't trustworthy.
* We'll destroy it now.
*/
- sbus_disconnect(conn);
+ sbus_disconnect(svc->conn);
}
done:
diff --git a/server/monitor/monitor_interfaces.h b/server/monitor/monitor_interfaces.h
index 5c58066d5..211c25dd2 100644
--- a/server/monitor/monitor_interfaces.h
+++ b/server/monitor/monitor_interfaces.h
@@ -21,15 +21,17 @@
/*** Monitor ***/
-#define MONITOR_VERSION "0.1"
-#define MONITOR_DBUS_INTERFACE "org.freedesktop.sssd.monitor"
-#define MONITOR_DBUS_PATH "/org/freedesktop/sssd/monitor"
+#define MONITOR_VERSION 0x0001
+
+/*** Monitor SRV Interface ***/
+#define MON_SRV_PATH "/org/freedesktop/sssd/monitor"
+#define MON_SRV_INTERFACE "org.freedesktop.sssd.monitor"
/* Monitor SRV Methods */
#define MON_SRV_METHOD_VERSION "getVersion"
+#define MON_SRV_METHOD_REGISTER "RegisterService"
-/*** Monitor Interface ***/
-
+/*** Monitor CLI Interface ***/
#define MONITOR_PATH "/org/freedesktop/sssd/service"
#define MONITOR_INTERFACE "org.freedesktop.sssd.service"
diff --git a/server/monitor/monitor_sbus.c b/server/monitor/monitor_sbus.c
index 817b42ae6..777a47fed 100644
--- a/server/monitor/monitor_sbus.c
+++ b/server/monitor/monitor_sbus.c
@@ -19,6 +19,11 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/* Needed for res_init() */
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
#include "util/util.h"
#include "confdb/confdb.h"
#include "sbus/sssd_dbus.h"
@@ -54,3 +59,152 @@ done:
return ret;
}
+static void id_callback(DBusPendingCall *pending, void *ptr)
+{
+ DBusMessage *reply;
+ DBusError dbus_error;
+ dbus_bool_t ret;
+ dbus_uint16_t mon_ver;
+ int type;
+
+ dbus_error_init(&dbus_error);
+
+ reply = dbus_pending_call_steal_reply(pending);
+ if (!reply) {
+ /* reply should never be null. This function shouldn't be called
+ * until reply is valid or timeout has occurred. If reply is NULL
+ * here, something is seriously wrong and we should bail out.
+ */
+ DEBUG(0, ("Severe error. A reply callback was called but no"
+ " reply was received and no timeout occurred\n"));
+
+ /* FIXME: Destroy this connection ? */
+ goto done;
+ }
+
+ type = dbus_message_get_type(reply);
+ switch (type) {
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ ret = dbus_message_get_args(reply, &dbus_error,
+ DBUS_TYPE_UINT16, &mon_ver,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ DEBUG(1, ("Failed to parse message\n"));
+ if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
+ /* FIXME: Destroy this connection ? */
+ goto done;
+ }
+
+ DEBUG(4, ("Got id ack and version (%d) from Monitor\n", mon_ver));
+
+ break;
+
+ case DBUS_MESSAGE_TYPE_ERROR:
+ DEBUG(0,("The Monitor returned an error [%s]\n",
+ dbus_message_get_error_name(reply)));
+ /* Falling through to default intentionally*/
+ default:
+ /*
+ * Timeout or other error occurred or something
+ * unexpected happened.
+ * It doesn't matter which, because either way we
+ * know that this connection isn't trustworthy.
+ * We'll destroy it now.
+ */
+
+ /* FIXME: Destroy this connection ? */
+ break;
+ }
+
+done:
+ dbus_pending_call_unref(pending);
+ dbus_message_unref(reply);
+}
+
+int monitor_common_send_id(struct sbus_connection *conn,
+ const char *name, uint16_t version)
+{
+ DBusPendingCall *pending_reply;
+ DBusConnection *dbus_conn;
+ DBusMessage *msg;
+ dbus_bool_t ret;
+
+ dbus_conn = sbus_get_connection(conn);
+
+ /* create the message */
+ msg = dbus_message_new_method_call(NULL,
+ MON_SRV_PATH,
+ MON_SRV_INTERFACE,
+ MON_SRV_METHOD_REGISTER);
+ if (msg == NULL) {
+ DEBUG(0, ("Out of memory?!\n"));
+ return ENOMEM;
+ }
+
+ DEBUG(4, ("Sending ID: (%s,%d)\n", name, version));
+
+ ret = dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_UINT16, &version,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ DEBUG(1, ("Failed to build message\n"));
+ return EIO;
+ }
+
+ ret = dbus_connection_send_with_reply(dbus_conn, msg, &pending_reply,
+ 30000 /* TODO: set timeout */);
+ if (!ret || !pending_reply) {
+ /*
+ * Critical Failure
+ * We can't communicate on this connection
+ * We'll drop it using the default destructor.
+ */
+ DEBUG(0, ("D-BUS send failed.\n"));
+ dbus_message_unref(msg);
+ return EIO;
+ }
+
+ /* Set up the reply handler */
+ dbus_pending_call_set_notify(pending_reply, id_callback, NULL, NULL);
+ dbus_message_unref(msg);
+
+ return EOK;
+}
+
+int monitor_common_pong(DBusMessage *message,
+ struct sbus_connection *conn)
+{
+ DBusMessage *reply;
+ dbus_bool_t ret;
+
+ reply = dbus_message_new_method_return(message);
+ if (!reply) return ENOMEM;
+
+ ret = dbus_message_append_args(reply, DBUS_TYPE_INVALID);
+ if (!ret) {
+ dbus_message_unref(reply);
+ return EIO;
+ }
+
+ /* send reply back */
+ sbus_conn_send_reply(conn, reply);
+ dbus_message_unref(reply);
+
+ return EOK;
+}
+
+int monitor_common_res_init(DBusMessage *message,
+ struct sbus_connection *conn)
+{
+ int ret;
+
+ ret = res_init();
+ if(ret != 0) {
+ return EIO;
+ }
+
+ /* Send an empty reply to acknowledge receipt */
+ return monitor_common_pong(message, conn);
+}
+
diff --git a/server/monitor/monitor_sbus.h b/server/monitor/monitor_sbus.h
index bc36e88eb..d84954bd1 100644
--- a/server/monitor/monitor_sbus.h
+++ b/server/monitor/monitor_sbus.h
@@ -24,5 +24,11 @@
int monitor_get_sbus_address(TALLOC_CTX *mem_ctx, struct confdb_ctx *confdb,
char **address);
+int monitor_common_send_id(struct sbus_connection *conn,
+ const char *name, uint16_t version);
+int monitor_common_pong(DBusMessage *message,
+ struct sbus_connection *conn);
+int monitor_common_res_init(DBusMessage *message,
+ struct sbus_connection *conn);
#endif /* MONITOR_SBUS_H_ */