summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-08-10 16:58:31 -0400
committerStephen Gallagher <sgallagh@redhat.com>2009-08-11 12:29:36 -0400
commit06a3b13134e29b75971970aa45ba14576a4f6ced (patch)
tree32c82e27f6020dad8134d80d09d22d6d94cbd5b1
parent38268cfc515e1f136cabfbcc9a620a2d9c929cda (diff)
downloadsssd-06a3b13134e29b75971970aa45ba14576a4f6ced.tar.gz
sssd-06a3b13134e29b75971970aa45ba14576a4f6ced.tar.bz2
sssd-06a3b13134e29b75971970aa45ba14576a4f6ced.zip
Change services identification mechanism
Let services identify themselves voiluntarily as the first operation instead of polling from the monitor. Also consolidate some common functions and make them available as monitor helpers.
-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 ead921c0..f9dc9b0c 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 5c58066d..211c25dd 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 817b42ae..777a47fe 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 bc36e88e..d84954bd 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 f0ecd30b..7fcd168d 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 49885edc..46f8db51 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 0f090831..f4187650 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 f3df7c65..75e72103 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 418e2f9f..e4b121bf 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 bff2f7cc..c0f0ca40 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 ab414da0..396a1f27 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;