summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--server/providers/data_provider.c86
-rw-r--r--server/providers/data_provider_be.c92
-rw-r--r--server/responder/common/responder.h2
-rw-r--r--server/responder/common/responder_common.c16
-rw-r--r--server/responder/nss/nsssrv.c79
-rw-r--r--server/responder/pam/pamsrv.c77
-rw-r--r--server/sbus/sssd_dbus_connection.c7
11 files changed, 421 insertions, 507 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_ */
diff --git a/server/providers/data_provider.c b/server/providers/data_provider.c
index f0ecd30bb..7fcd168db 100644
--- a/server/providers/data_provider.c
+++ b/server/providers/data_provider.c
@@ -31,11 +31,6 @@
#include <errno.h>
#include <security/pam_modules.h>
-/* Needed for res_init() */
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-
#include "popt.h"
#include "util/util.h"
#include "confdb/confdb.h"
@@ -84,16 +79,12 @@ struct dp_frontend {
static int dp_backend_destructor(void *ctx);
static int dp_frontend_destructor(void *ctx);
-static int service_identity(DBusMessage *message, struct sbus_connection *conn);
-static int service_pong(DBusMessage *message, struct sbus_connection *conn);
static int service_reload(DBusMessage *message, struct sbus_connection *conn);
-static int service_res_init(DBusMessage *message, struct sbus_connection *conn);
struct sbus_method monitor_dp_methods[] = {
- { MON_CLI_METHOD_IDENTITY, service_identity },
- { MON_CLI_METHOD_PING, service_pong },
+ { MON_CLI_METHOD_PING, monitor_common_pong },
{ MON_CLI_METHOD_RELOAD, service_reload },
- { MON_CLI_METHOD_RES_INIT, service_res_init },
+ { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
{ NULL, NULL }
};
@@ -136,55 +127,6 @@ struct dp_be_request {
struct dp_backend *be;
};
-static int service_identity(DBusMessage *message, struct sbus_connection *conn)
-{
- dbus_uint16_t version = DATA_PROVIDER_VERSION;
- const char *name = DATA_PROVIDER_SERVICE_NAME;
- DBusMessage *reply;
- dbus_bool_t ret;
-
- DEBUG(4, ("Sending identity data [%s,%d]\n", name, version));
-
- reply = dbus_message_new_method_return(message);
- if (!reply) return ENOMEM;
-
- ret = dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_UINT16, &version,
- 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;
-}
-
-static int service_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;
-}
-
static int service_reload(DBusMessage *message, struct sbus_connection *conn)
{
/* Monitor calls this function when we need to reload
@@ -193,19 +135,7 @@ static int service_reload(DBusMessage *message, struct sbus_connection *conn)
*/
/* Send an empty reply to acknowledge receipt */
- return service_pong(message, conn);
-}
-
-static int service_res_init(DBusMessage *message, struct sbus_connection *conn)
-{
- int ret;
-
- ret = res_init();
- if(ret != 0) {
- return EIO;
- }
-
- return service_pong(message, conn);
+ return monitor_common_pong(message, conn);
}
static int dp_monitor_init(struct dp_ctx *dpctx)
@@ -229,8 +159,14 @@ static int dp_monitor_init(struct dp_ctx *dpctx)
return ret;
}
- /* Set up DP-specific listeners */
- /* None currently used */
+ /* Identify ourselves to the monitor */
+ ret = monitor_common_send_id(conn,
+ DATA_PROVIDER_SERVICE_NAME,
+ DATA_PROVIDER_VERSION);
+ if (ret != EOK) {
+ DEBUG(0, ("Failed to identify to the monitor!\n"));
+ return ret;
+ }
return EOK;
}
diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c
index 49885edc6..46f8db51d 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -34,11 +34,6 @@
#include <security/pam_appl.h>
#include <security/pam_modules.h>
-/* Needed for res_init() */
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-
#include "popt.h"
#include "util/util.h"
#include "confdb/confdb.h"
@@ -53,14 +48,9 @@
#define BE_CONF_ENTRY "config/domains/%s"
-static int service_identity(DBusMessage *message, struct sbus_connection *conn);
-static int service_pong(DBusMessage *message, struct sbus_connection *conn);
-static int service_res_init(DBusMessage *message, struct sbus_connection *conn);
-
struct sbus_method monitor_be_methods[] = {
- { MON_CLI_METHOD_IDENTITY, service_identity },
- { MON_CLI_METHOD_PING, service_pong },
- { MON_CLI_METHOD_RES_INIT, service_res_init },
+ { MON_CLI_METHOD_PING, monitor_common_pong },
+ { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
{ NULL, NULL }
};
@@ -102,75 +92,6 @@ static struct bet_data bet_data[] = {
{BET_MAX, NULL, NULL}
};
-
-
-static int service_identity(DBusMessage *message, struct sbus_connection *conn)
-{
- dbus_uint16_t version = DATA_PROVIDER_VERSION;
- struct be_ctx *ctx;
- DBusMessage *reply;
- dbus_bool_t ret;
- void *user_data;
-
- user_data = sbus_conn_get_private_data(conn);
- if (!user_data) return EINVAL;
- ctx = talloc_get_type(user_data, struct be_ctx);
- if (!ctx) return EINVAL;
-
- DEBUG(4,("Sending ID reply: (%s,%d)\n", ctx->identity, version));
-
- reply = dbus_message_new_method_return(message);
- if (!reply) return ENOMEM;
-
- ret = dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &ctx->identity,
- DBUS_TYPE_UINT16, &version,
- 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;
-}
-
-static int service_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;
-}
-
-static int service_res_init(DBusMessage *message, struct sbus_connection *conn)
-{
- int ret;
-
- ret = res_init();
- if(ret != 0) {
- return EIO;
- }
-
- return service_pong(message, conn);
-}
-
static int be_identity(DBusMessage *message, struct sbus_connection *conn)
{
dbus_uint16_t version = DATA_PROVIDER_VERSION;
@@ -704,6 +625,15 @@ static int mon_cli_init(struct be_ctx *ctx)
return ret;
}
+ /* Identify ourselves to the monitor */
+ ret = monitor_common_send_id(ctx->mon_conn,
+ ctx->identity,
+ DATA_PROVIDER_VERSION);
+ if (ret != EOK) {
+ DEBUG(0, ("Failed to identify to the monitor!\n"));
+ return ret;
+ }
+
return EOK;
}
diff --git a/server/responder/common/responder.h b/server/responder/common/responder.h
index 0f0908317..f41876508 100644
--- a/server/responder/common/responder.h
+++ b/server/responder/common/responder.h
@@ -102,6 +102,8 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
const char *sss_pipe_name,
const char *sss_priv_pipe_name,
const char *confdb_service_path,
+ const char *svc_name,
+ uint16_t svc_version,
struct sbus_interface *dp_intf,
struct sbus_interface *monitor_intf,
struct resp_ctx **responder_ctx);
diff --git a/server/responder/common/responder_common.c b/server/responder/common/responder_common.c
index f3df7c65c..75e721030 100644
--- a/server/responder/common/responder_common.c
+++ b/server/responder/common/responder_common.c
@@ -286,7 +286,9 @@ static void accept_fd_handler(struct tevent_context *ev,
}
static int sss_monitor_init(struct resp_ctx *rctx,
- struct sbus_interface *intf)
+ struct sbus_interface *intf,
+ const char *svc_name,
+ uint16_t svc_version)
{
char *sbus_address;
int ret;
@@ -306,8 +308,12 @@ static int sss_monitor_init(struct resp_ctx *rctx,
return ret;
}
- /* Set up NSS-specific listeners */
- /* None currently used */
+ /* Identify ourselves to the monitor */
+ ret = monitor_common_send_id(rctx->mon_conn, svc_name, svc_version);
+ if (ret != EOK) {
+ DEBUG(0, ("Failed to identify to the monitor!\n"));
+ return ret;
+ }
return EOK;
}
@@ -447,6 +453,8 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
const char *sss_pipe_name,
const char *sss_priv_pipe_name,
const char *confdb_service_path,
+ const char *svc_name,
+ uint16_t svc_version,
struct sbus_interface *dp_intf,
struct sbus_interface *monitor_intf,
struct resp_ctx **responder_ctx)
@@ -472,7 +480,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- ret = sss_monitor_init(rctx, monitor_intf);
+ ret = sss_monitor_init(rctx, monitor_intf, svc_name, svc_version);
if (ret != EOK) {
DEBUG(0, ("fatal error setting up message bus\n"));
return ret;
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c
index 418e2f9f6..e4b121bf2 100644
--- a/server/responder/nss/nsssrv.c
+++ b/server/responder/nss/nsssrv.c
@@ -30,11 +30,6 @@
#include <sys/time.h>
#include <errno.h>
-/* Needed for res_init() */
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-
#include "popt.h"
#include "util/util.h"
#include "responder/nss/nsssrv.h"
@@ -52,16 +47,12 @@
#define SSS_NSS_PIPE_NAME "nss"
-static int service_identity(DBusMessage *message, struct sbus_connection *conn);
-static int service_pong(DBusMessage *message, struct sbus_connection *conn);
static int service_reload(DBusMessage *message, struct sbus_connection *conn);
-static int service_res_init(DBusMessage *message, struct sbus_connection *conn);
struct sbus_method monitor_nss_methods[] = {
- { MON_CLI_METHOD_IDENTITY, service_identity },
- { MON_CLI_METHOD_PING, service_pong },
+ { MON_CLI_METHOD_PING, monitor_common_pong },
{ MON_CLI_METHOD_RELOAD, service_reload },
- { MON_CLI_METHOD_RES_INIT, service_res_init },
+ { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
{ NULL, NULL }
};
@@ -73,56 +64,6 @@ struct sbus_interface monitor_nss_interface = {
NULL
};
-static int service_identity(DBusMessage *message, struct sbus_connection *conn)
-{
- dbus_uint16_t version = NSS_SBUS_SERVICE_VERSION;
- const char *name = NSS_SBUS_SERVICE_NAME;
- DBusMessage *reply;
- dbus_bool_t ret;
-
- DEBUG(4,("Sending ID reply: (%s,%d)\n",
- name, version));
-
- reply = dbus_message_new_method_return(message);
- if (!reply) return ENOMEM;
-
- ret = dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_UINT16, &version,
- 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;
-}
-
-static int service_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;
-}
-
static int service_reload(DBusMessage *message, struct sbus_connection *conn)
{
/* Monitor calls this function when we need to reload
@@ -131,19 +72,7 @@ static int service_reload(DBusMessage *message, struct sbus_connection *conn)
*/
/* Send an empty reply to acknowledge receipt */
- return service_pong(message, conn);
-}
-
-static int service_res_init(DBusMessage *message, struct sbus_connection *conn)
-{
- int ret;
-
- ret = res_init();
- if(ret != 0) {
- return EIO;
- }
-
- return service_pong(message, conn);
+ return monitor_common_pong(message, conn);
}
static int nss_get_config(struct nss_ctx *nctx,
@@ -303,6 +232,8 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
nss_cmds,
SSS_NSS_SOCKET_NAME, NULL,
NSS_SRV_CONFIG,
+ NSS_SBUS_SERVICE_NAME,
+ NSS_SBUS_SERVICE_VERSION,
nss_dp_interface,
&monitor_nss_interface,
&nctx->rctx);
diff --git a/server/responder/pam/pamsrv.c b/server/responder/pam/pamsrv.c
index bff2f7cc9..c0f0ca40e 100644
--- a/server/responder/pam/pamsrv.c
+++ b/server/responder/pam/pamsrv.c
@@ -31,11 +31,6 @@
#include <sys/time.h>
#include <errno.h>
-/* Needed for res_init() */
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-
#include "popt.h"
#include "util/util.h"
#include "db/sysdb.h"
@@ -54,16 +49,12 @@
#define PAM_SBUS_SERVICE_NAME "pam"
#define PAM_SRV_CONFIG "config/services/pam"
-static int service_identity(DBusMessage *message, struct sbus_connection *conn);
-static int service_pong(DBusMessage *message, struct sbus_connection *conn);
static int service_reload(DBusMessage *message, struct sbus_connection *conn);
-static int service_res_init(DBusMessage *message, struct sbus_connection *conn);
struct sbus_method monitor_pam_methods[] = {
- { MON_CLI_METHOD_IDENTITY, service_identity },
- { MON_CLI_METHOD_PING, service_pong },
+ { MON_CLI_METHOD_PING, monitor_common_pong },
{ MON_CLI_METHOD_RELOAD, service_reload },
- { MON_CLI_METHOD_RES_INIT, service_res_init },
+ { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
{ NULL, NULL }
};
@@ -75,66 +66,6 @@ struct sbus_interface monitor_pam_interface = {
NULL
};
-static int service_identity(DBusMessage *message, struct sbus_connection *conn)
-{
- dbus_uint16_t version = PAM_SBUS_SERVICE_VERSION;
- const char *name = PAM_SBUS_SERVICE_NAME;
- DBusMessage *reply;
- dbus_bool_t ret;
-
- DEBUG(4,("Sending ID reply: (%s,%d)\n", name, version));
-
- reply = dbus_message_new_method_return(message);
- if (!reply) return ENOMEM;
-
- ret = dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_UINT16, &version,
- 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;
-}
-
-static int service_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) {
- return EIO;
- }
-
- /* send reply back */
- sbus_conn_send_reply(conn, reply);
- dbus_message_unref(reply);
-
- return EOK;
-}
-
-static int service_res_init(DBusMessage *message, struct sbus_connection *conn)
-{
- int ret;
-
- ret = res_init();
- if(ret != 0) {
- return EIO;
- }
-
- return service_pong(message, conn);
-}
-
static void pam_shutdown(struct resp_ctx *ctx);
static int service_reload(DBusMessage *message, struct sbus_connection *conn) {
@@ -144,7 +75,7 @@ static int service_reload(DBusMessage *message, struct sbus_connection *conn) {
*/
/* Send an empty reply to acknowledge receipt */
- return service_pong(message, conn);
+ return monitor_common_pong(message, conn);
}
static void pam_dp_reconnect_init(struct sbus_connection *conn, int status, void *pvt)
@@ -242,6 +173,8 @@ int main(int argc, const char *argv[])
SSS_PAM_SOCKET_NAME,
SSS_PAM_PRIV_SOCKET_NAME,
PAM_SRV_CONFIG,
+ PAM_SBUS_SERVICE_NAME,
+ PAM_SBUS_SERVICE_VERSION,
pam_dp_interface,
&monitor_pam_interface,
&rctx);
diff --git a/server/sbus/sssd_dbus_connection.c b/server/sbus/sssd_dbus_connection.c
index ab414da05..396a1f27f 100644
--- a/server/sbus/sssd_dbus_connection.c
+++ b/server/sbus/sssd_dbus_connection.c
@@ -111,7 +111,8 @@ static void sbus_conn_wakeup_main(void *data)
struct tevent_timer *te;
conn = talloc_get_type(data, struct sbus_connection);
- gettimeofday(&tv, NULL);
+
+ tv = tevent_timeval_current();
/* D-BUS calls this function when it is time to do a dispatch */
te = tevent_add_timer(conn->ev, conn, tv, sbus_dispatch, conn);
@@ -147,13 +148,13 @@ int sbus_init_connection(TALLOC_CTX *ctx,
conn->dbus.conn = dbus_conn;
conn->connection_type = connection_type;
- ret = sbus_conn_set_fns(conn);
+ ret = sbus_conn_add_interface(conn, intf);
if (ret != EOK) {
talloc_free(conn);
return ret;
}
- ret = sbus_conn_add_interface(conn, intf);
+ ret = sbus_conn_set_fns(conn);
if (ret != EOK) {
talloc_free(conn);
return ret;