diff --git a/configure.ac b/configure.ac
index afc55de..43dbeb5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -332,30 +332,35 @@ fi
 PKG_CHECK_MODULES(SYSTEMD_200, [systemd >= 200], [have_systemd_200=yes],[have_systemd_200=no])
 AM_CONDITIONAL(HAVE_SYSTEMD_200, test "${have_systemd_200}" = "yes")
 
-# session tracking support
-AC_MSG_CHECKING([Session tracking support])
-AC_ARG_WITH(session-tracking, AS_HELP_STRING([--with-session-tracking=systemd|consolekit|no],
-	[Select session tracking support (default: consolekit)]))
-# default to consolekit
-AS_IF([test -z "$with_session_tracking"], with_session_tracking=consolekit)
-AS_IF([test "$with_session_tracking" = "ck"], with_session_tracking=consolekit)
-AS_IF([test "$with_session_tracking" = "none"], with_session_tracking=no)
-# check value
-AS_IF([! (echo "$with_session_tracking" | grep -q -E "^(systemd|consolekit|no)$")],
-	AC_MSG_ERROR([--with-session-tracking must be systemd/consolekit/no, not $with_session_tracking]))
-# add conditionals and subtitutions
-AM_CONDITIONAL(SESSION_TRACKING_CK, test "$with_session_tracking" = "consolekit")
-AM_CONDITIONAL(SESSION_TRACKING_SYSTEMD, test "$with_session_tracking" = "systemd")
-if test "$with_session_tracking" = "systemd"; then
-	PKG_CHECK_MODULES(SYSTEMD_LOGIN, [libsystemd],,
-	                  [PKG_CHECK_MODULES(SYSTEMD_LOGIN, [libsystemd-login])])
+# Session tracking support
+AC_ARG_WITH(systemd-logind, AS_HELP_STRING([--with-systemd-logind=yes|no],
+	[Support systemd session tracking]))
+AC_ARG_WITH(consolekit, AS_HELP_STRING([--with-consolekit=yes|no],
+	[Support consolekit session tracking]))
+# defaults
+AS_IF([test -z "$with_systemd_logind"], [with_systemd_logind="yes"])
+AS_IF([test -z "$with_consolekit"], [with_consolekit="yes"])
+# backwards compatibility
+AS_IF([test "$with_session_tracking" = "ck"], [with_consolekit="yes" with_systemd_login="no"])
+AS_IF([test "$with_session_tracking" = "consolekit"], [with_consolekit="yes" with_systemd_login="no"])
+AS_IF([test "$with_session_tracking" = "systemd"], [with_consolekit="no" with_systemd_login="yes"])
+AS_IF([test "$with_session_tracking" = "none"], [with_consolekit="no" with_systemd_login="no"])
+# output
+session_tracking=
+if test "$with_systemd_logind" = "yes"; then
+	PKG_CHECK_MODULES(SYSTEMD_LOGIN, [libsystemd >= 209],,
+	                  [PKG_CHECK_MODULES(SYSTEMD_LOGIN, [libsystemd-login >= 183])])
 	AC_SUBST(SYSTEMD_LOGIN_CFLAGS)
 	AC_SUBST(SYSTEMD_LOGIN_LIBS)
+	AC_DEFINE([SESSION_TRACKING_SYSTEMD], 1, [Define to 1 if libsystemd-login is available])
+	session_tracking="$session_tracking, systemd-logind"
 fi
-if test "$with_session_tracking" = "consolekit"; then
-	AC_SUBST(CKDB_PATH, /var/run/ConsoleKit/database)
+if test "$with_consolekit" = "yes"; then
+	AC_DEFINE([SESSION_TRACKING_CONSOLEKIT], 1, [Define to 1 if ConsoleKit is available])
+	AC_DEFINE([CKDB_PATH], "/var/run/ConsoleKit/database", [Path to ConsoleKit database])
+	session_tracking="$session_tracking, consolekit"
 fi
-AC_MSG_RESULT($with_session_tracking)
+session_tracking=${session_tracking:2}
 
 AC_ARG_WITH(suspend-resume, AS_HELP_STRING([--with-suspend-resume=upower|systemd], [Build NetworkManager with specific suspend/resume support]))
 if test "z$with_suspend_resume" = "z"; then
@@ -1022,7 +1027,7 @@ echo "  nmrundir: $nmrundir"
 echo
 
 echo "Platform:"
-echo "  session tracking: $with_session_tracking"
+echo "  session tracking: $session_tracking"
 echo "  suspend/resume: $with_suspend_resume"
 if test "${enable_polkit}" = "yes"; then
 	if test "${enable_modify_system}" = "yes"; then
diff --git a/src/Makefile.am b/src/Makefile.am
index 808e59e..e9cedd9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -327,22 +327,12 @@ nm_sources = \
 	nm-rfkill-manager.c \
 	nm-rfkill-manager.h \
 	nm-session-monitor.h \
-	nm-session-utils.c \
-	nm-session-utils.h \
+	nm-session-monitor.c \
 	nm-sleep-monitor.h \
 	nm-types.h \
 	NetworkManagerUtils.c \
 	NetworkManagerUtils.h
 
-if SESSION_TRACKING_SYSTEMD
-nm_sources += nm-session-monitor-systemd.c
-else
-if SESSION_TRACKING_CK
-nm_sources += nm-session-monitor-ck.c
-else
-nm_sources += nm-session-monitor-null.c
-endif
-endif
 
 if SUSPEND_RESUME_SYSTEMD
 nm_sources += nm-sleep-monitor-systemd.c
@@ -433,10 +423,6 @@ AM_CPPFLAGS += \
 	\
 	$(NULL)
 
-if SESSION_TRACKING_CK
-AM_CPPFLAGS += -DCKDB_PATH=\"${CKDB_PATH}\"
-endif
-
 libNetworkManager_la_SOURCES = \
 	$(nm_sources) \
 	$(glue_sources)
diff --git a/src/nm-auth-utils.c b/src/nm-auth-utils.c
index 9ace162..62d2938 100644
--- a/src/nm-auth-utils.c
+++ b/src/nm-auth-utils.c
@@ -443,22 +443,16 @@ nm_auth_is_subject_in_acl (NMConnection *connection,
 		return TRUE;
 
 	/* Reject the request if the request comes from no session at all */
-	if (!nm_session_monitor_uid_has_session (smon, uid, &user, &local)) {
-		if (out_error_desc) {
-			*out_error_desc = g_strdup_printf ("No session found for uid %lu (%s)",
+	user = nm_session_monitor_uid_to_user (uid, &local);
+	if (!user) {
+		if (out_error_desc)
+			*out_error_desc = g_strdup_printf ("Could not determine username for uid %lu (%s)",
 			                                   uid,
 			                                   local && local->message ? local->message : "unknown");
-		}
 		g_clear_error (&local);
 		return FALSE;
 	}
 
-	if (!user) {
-		if (out_error_desc)
-			*out_error_desc = g_strdup_printf ("Could not determine username for uid %lu", uid);
-		return FALSE;
-	}
-
 	s_con = nm_connection_get_setting_connection (connection);
 	if (!s_con) {
 		/* This can only happen when called from AddAndActivate, so we know
diff --git a/src/nm-session-monitor-ck.c b/src/nm-session-monitor-ck.c
deleted file mode 100644
index 964874b..0000000
--- a/src/nm-session-monitor-ck.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 - 2010 Red Hat, Inc.
- * Author: David Zeuthen <davidz@redhat.com>
- * Author: Dan Williams <dcbw@redhat.com>
- */
-
-#include "config.h"
-
-#include <errno.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <gio/gio.h>
-#include "nm-logging.h"
-
-#include "nm-session-utils.h"
-#include "nm-session-monitor.h"
-#include "nm-errors.h"
-
-/* <internal>
- * SECTION:nm-session-monitor
- * @title: NMSessionMonitor
- * @short_description: Monitor sessions
- *
- * The #NMSessionMonitor class is a utility class to track and monitor sessions.
- */
-
-struct _NMSessionMonitor {
-	GObject parent_instance;
-
-	GKeyFile *database;
-	GFileMonitor *database_monitor;
-	time_t database_mtime;
-	GHashTable *sessions_by_uid;
-	GHashTable *sessions_by_user;
-};
-
-struct _NMSessionMonitorClass {
-	GObjectClass parent_class;
-
-	void (*changed) (NMSessionMonitor *monitor);
-};
-
-
-enum {
-	CHANGED,
-	LAST_SIGNAL,
-};
-static guint signals[LAST_SIGNAL] = {0};
-
-G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT);
-
-/********************************************************************/
-
-typedef struct {
-	char *user;
-	uid_t uid;
-	gboolean local;
-	gboolean active;
-} Session;
-
-static void
-session_free (Session *s)
-{
-	g_free (s->user);
-	memset (s, 0, sizeof (Session));
-	g_free (s);
-}
-
-static gboolean
-check_key (GKeyFile *keyfile, const char *group, const char *key, GError **error)
-{
-	if (g_key_file_has_key (keyfile, group, key, error))
-		return TRUE;
-
-	if (!error) {
-		g_set_error (error,
-			         NM_MANAGER_ERROR,
-			         NM_MANAGER_ERROR_FAILED,
-			         "ConsoleKit database " CKDB_PATH " group '%s' had no '%s' key",
-			         group, key);
-	}
-	return FALSE;
-}
-
-static Session *
-session_new (GKeyFile *keyfile, const char *group, GError **error)
-{
-	GError *local = NULL;
-	Session *s;
-	const char *uname = NULL;
-
-	s = g_new0 (Session, 1);
-	g_assert (s);
-
-	s->uid = G_MAXUINT; /* paranoia */
-	if (!check_key (keyfile, group, "uid", &local))
-		goto error;
-	s->uid = (uid_t) g_key_file_get_integer (keyfile, group, "uid", &local);
-	if (local)
-		goto error;
-
-	if (!check_key (keyfile, group, "is_active", &local))
-		goto error;
-	s->active = g_key_file_get_boolean (keyfile, group, "is_active", &local);
-	if (local)
-		goto error;
-
-	if (!check_key (keyfile, group, "is_local", &local))
-		goto error;
-	s->local = g_key_file_get_boolean (keyfile, group, "is_local", &local);
-	if (local)
-		goto error;
-
-	if (!nm_session_uid_to_user (s->uid, &uname, error))
-		return FALSE;
-	s->user = g_strdup (uname);
-
-	return s;
-
-error:
-	session_free (s);
-	g_propagate_error (error, local);
-	return NULL;
-}
-
-static void
-session_merge (Session *src, Session *dest)
-{
-	g_return_if_fail (src != NULL);
-	g_return_if_fail (dest != NULL);
-
-	g_warn_if_fail (g_strcmp0 (src->user, dest->user) == 0);
-	g_warn_if_fail (src->uid == dest->uid);
-
-	dest->local = (dest->local || src->local);
-	dest->active = (dest->active || src->active);
-}
-
-/********************************************************************/
-
-static void
-free_database (NMSessionMonitor *self)
-{
-	if (self->database != NULL) {
-		g_key_file_free (self->database);
-		self->database = NULL;
-	}
-
-	g_hash_table_remove_all (self->sessions_by_uid);
-	g_hash_table_remove_all (self->sessions_by_user);
-}
-
-static gboolean
-reload_database (NMSessionMonitor *self, GError **error)
-{
-	struct stat statbuf;
-	char **groups = NULL;
-	gsize len = 0, i;
-	Session *s;
-
-	free_database (self);
-
-	errno = 0;
-	if (stat (CKDB_PATH, &statbuf) != 0) {
-		g_set_error (error,
-		             NM_MANAGER_ERROR,
-		             NM_MANAGER_ERROR_FAILED,
-		             "Error statting file " CKDB_PATH ": %s",
-		             strerror (errno));
-		goto error;
-	}
-	self->database_mtime = statbuf.st_mtime;
-
-	self->database = g_key_file_new ();
-	if (!g_key_file_load_from_file (self->database, CKDB_PATH, G_KEY_FILE_NONE, error))
-		goto error;
-
-	groups = g_key_file_get_groups (self->database, &len);
-	if (!groups) {
-		g_set_error_literal (error,
-		                     NM_MANAGER_ERROR,
-		                     NM_MANAGER_ERROR_FAILED,
-		                     "Could not load groups from " CKDB_PATH "");
-		goto error;
-	}
-
-	for (i = 0; i < len; i++) {
-		Session *found;
-
-		if (!g_str_has_prefix (groups[i], "Session "))
-			continue;
-
-		s = session_new (self->database, groups[i], error);
-		if (!s)
-			goto error;
-
-		found = g_hash_table_lookup (self->sessions_by_user, (gpointer) s->user);
-		if (found) {
-			session_merge (s, found);
-			session_free (s);
-		} else {
-			/* Entirely new user */
-			g_hash_table_insert (self->sessions_by_user, (gpointer) s->user, s);
-			g_hash_table_insert (self->sessions_by_uid, GUINT_TO_POINTER (s->uid), s);
-		}
-	}
-
-	g_strfreev (groups);
-	return TRUE;
-
-error:
-	if (groups)
-		g_strfreev (groups);
-	free_database (self);
-	return FALSE;
-}
-
-static gboolean
-ensure_database (NMSessionMonitor *self, GError **error)
-{
-	gboolean ret = FALSE;
-
-	if (self->database != NULL) {
-		struct stat statbuf;
-
-		errno = 0;
-		if (stat (CKDB_PATH, &statbuf) != 0) {
-			g_set_error (error,
-			             NM_MANAGER_ERROR,
-			             NM_MANAGER_ERROR_FAILED,
-			             "Error statting file " CKDB_PATH " to check timestamp: %s",
-			             strerror (errno));
-			goto out;
-		}
-
-		if (statbuf.st_mtime == self->database_mtime) {
-			ret = TRUE;
-			goto out;
-		}
-	}
-
-	ret = reload_database (self, error);
-
-out:
-	return ret;
-}
-
-static void
-on_file_monitor_changed (GFileMonitor *    file_monitor,
-                         GFile *           file,
-                         GFile *           other_file,
-                         GFileMonitorEvent event_type,
-                         gpointer          user_data)
-{
-	NMSessionMonitor *self = NM_SESSION_MONITOR (user_data);
-
-	/* throw away cache */
-	free_database (self);
-
-	g_signal_emit (self, signals[CHANGED], 0);
-}
-
-static void
-nm_session_monitor_init (NMSessionMonitor *self)
-{
-	GError *error = NULL;
-	GFile *file;
-
-	/* Sessions-by-user is responsible for destroying the Session objects */
-	self->sessions_by_user = g_hash_table_new_full (g_str_hash, g_str_equal,
-	                                                NULL, (GDestroyNotify) session_free);
-	self->sessions_by_uid = g_hash_table_new (g_direct_hash, g_direct_equal);
-
-
-	if (!ensure_database (self, &error)) {
-		nm_log_dbg (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message);
-
-		/* Ignore the first error, the CK database might not exist yet */
-		g_error_free (error);
-		error = NULL;
-	}
-
-	file = g_file_new_for_path (CKDB_PATH);
-	self->database_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
-	g_object_unref (file);
-	if (self->database_monitor == NULL) {
-		nm_log_err (LOGD_CORE, "Error monitoring " CKDB_PATH ": %s", error->message);
-		g_error_free (error);
-	} else {
-		g_signal_connect (self->database_monitor,
-		                  "changed",
-		                  G_CALLBACK (on_file_monitor_changed),
-		                  self);
-	}
-}
-
-static void
-finalize (GObject *object)
-{
-	NMSessionMonitor *self = NM_SESSION_MONITOR (object);
-
-	if (self->database_monitor != NULL)
-		g_object_unref (self->database_monitor);
-
-	free_database (self);
-
-	if (G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize != NULL)
-		G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize (object);
-}
-
-static void
-nm_session_monitor_class_init (NMSessionMonitorClass *klass)
-{
-	GObjectClass *gobject_class;
-
-	gobject_class = G_OBJECT_CLASS (klass);
-
-	gobject_class->finalize = finalize;
-
-	/**
-	 * NMSessionMonitor::changed:
-	 * @monitor: A #NMSessionMonitor
-	 *
-	 * Emitted when something changes.
-	 */
-	signals[CHANGED] = g_signal_new (NM_SESSION_MONITOR_CHANGED,
-	                                 NM_TYPE_SESSION_MONITOR,
-	                                 G_SIGNAL_RUN_LAST,
-	                                 G_STRUCT_OFFSET (NMSessionMonitorClass, changed),
-	                                 NULL,                   /* accumulator      */
-	                                 NULL,                   /* accumulator data */
-	                                 g_cclosure_marshal_VOID__VOID,
-	                                 G_TYPE_NONE, 0);
-}
-
-NMSessionMonitor *
-nm_session_monitor_get (void)
-{
-	static NMSessionMonitor *singleton = NULL;
-
-	if (!singleton)
-		singleton = NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL));
-	return singleton;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-/**
- * nm_session_monitor_user_has_session:
- * @monitor: A #NMSessionMonitor.
- * @username: A username.
- * @error: Return location for error.
- *
- * Checks whether the given @username is logged into a session or not.
- *
- * Returns: %FALSE if @error is set otherwise %TRUE if the given @username is
- * currently logged into a session.
- */
-gboolean
-nm_session_monitor_user_has_session (NMSessionMonitor *monitor,
-                                     const char *username,
-                                     uid_t *out_uid,
-                                     GError **error)
-{
-	Session *s;
-
-	if (!ensure_database (monitor, error))
-		return FALSE;
-
-	s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username);
-	if (!s) {
-		g_set_error (error,
-		             NM_MANAGER_ERROR,
-		             NM_MANAGER_ERROR_FAILED,
-		             "No session found for user '%s'",
-		             username);
-		return FALSE;
-	}
-
-	if (out_uid)
-		*out_uid = s->uid;
-	return TRUE;
-}
-
-/**
- * nm_session_monitor_uid_has_session:
- * @monitor: A #NMSessionMonitor.
- * @uid: A user ID.
- * @error: Return location for error.
- *
- * Checks whether the given @uid is logged into a session or not.
- *
- * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is
- * currently logged into a session.
- */
-gboolean
-nm_session_monitor_uid_has_session (NMSessionMonitor *monitor,
-                                    uid_t uid,
-                                    const char **out_user,
-                                    GError **error)
-{
-	Session *s;
-
-	if (!ensure_database (monitor, error))
-		return FALSE;
-
-	s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid));
-	if (!s) {
-		g_set_error (error,
-		             NM_MANAGER_ERROR,
-		             NM_MANAGER_ERROR_FAILED,
-		             "No session found for uid %d",
-		             uid);
-		return FALSE;
-	}
-
-	if (out_user)
-		*out_user = s->user;
-	return TRUE;
-}
-
-/**
- * nm_session_monitor_user_active:
- * @monitor: A #NMSessionMonitor.
- * @username: A username.
- * @error: Return location for error.
- *
- * Checks whether the given @username is logged into a active session or not.
- *
- * Returns: %FALSE if @error is set otherwise %TRUE if the given @username is
- * logged into an active session.
- */
-gboolean
-nm_session_monitor_user_active (NMSessionMonitor *monitor,
-                                const char *username,
-                                GError **error)
-{
-	Session *s;
-
-	if (!ensure_database (monitor, error))
-		return FALSE;
-
-	s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username);
-	if (!s) {
-		g_set_error (error,
-		             NM_MANAGER_ERROR,
-		             NM_MANAGER_ERROR_FAILED,
-		             "No session found for user '%s'",
-		             username);
-		return FALSE;
-	}
-
-	return s->active;
-}
-
-/**
- * nm_session_monitor_uid_active:
- * @monitor: A #NMSessionMonitor.
- * @uid: A user ID.
- * @error: Return location for error.
- *
- * Checks whether the given @uid is logged into a active session or not.
- *
- * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is
- * logged into an active session.
- */
-gboolean
-nm_session_monitor_uid_active (NMSessionMonitor *monitor,
-                               uid_t uid,
-                               GError **error)
-{
-	Session *s;
-
-	if (!ensure_database (monitor, error))
-		return FALSE;
-
-	s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid));
-	if (!s) {
-		g_set_error (error,
-		             NM_MANAGER_ERROR,
-		             NM_MANAGER_ERROR_FAILED,
-		             "No session found for uid '%d'",
-		             uid);
-		return FALSE;
-	}
-
-	return s->active;
-}
-
diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c
new file mode 100644
index 0000000..6e14327
--- /dev/null
+++ b/src/nm-session-monitor.c
@@ -0,0 +1,638 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 - 2014 Red Hat, Inc.
+ * Author: David Zeuthen <davidz@redhat.com>
+ * Author: Dan Williams <dcbw@redhat.com>
+ * Author: Matthias Clasen
+ * Author: Pavel Šimerda <psimerda@redhat.com>
+ */
+#include "config.h"
+
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+#include <stdlib.h>
+
+#ifdef SESSION_TRACKING_SYSTEMD
+#include <systemd/sd-login.h>
+#endif
+
+#include "nm-session-monitor.h"
+#include "nm-errors.h"
+#include "nm-logging.h"
+
+/********************************************************************/
+
+/* <internal>
+ * SECTION:nm-session-monitor
+ * @title: NMSessionMonitor
+ * @short_description: Monitor sessions
+ *
+ * The #NMSessionMonitor class is a utility class to track and monitor sessions.
+ */
+
+struct _NMSessionMonitor {
+	GObject parent_instance;
+
+#ifdef SESSION_TRACKING_SYSTEMD
+	struct {
+		GSource *source;
+	} sd;
+#endif
+
+#ifdef SESSION_TRACKING_CONSOLEKIT
+	struct {
+		GKeyFile *database;
+		GFileMonitor *database_monitor;
+		time_t database_mtime;
+		GHashTable *sessions_by_uid;
+	} ck;
+#endif
+
+};
+
+struct _NMSessionMonitorClass {
+	GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT);
+
+enum {
+	CHANGED,
+	LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+/********************************************************************/
+
+#ifdef SESSION_TRACKING_SYSTEMD
+typedef struct {
+	GSource source;
+	GPollFD pollfd;
+	sd_login_monitor *monitor;
+} SdSource;
+
+static gboolean
+sd_source_prepare (GSource *source, gint *timeout)
+{
+	*timeout = -1;
+	return FALSE;
+}
+
+static gboolean
+sd_source_check (GSource *source)
+{
+	SdSource *sd_source = (SdSource *) source;
+
+	return sd_source->pollfd.revents != 0;
+}
+
+static gboolean
+sd_source_dispatch (GSource     *source,
+                    GSourceFunc  callback,
+                    gpointer     user_data)
+
+{
+	SdSource *sd_source = (SdSource *)source;
+	gboolean ret;
+
+	g_warn_if_fail (callback != NULL);
+	ret = (*callback) (user_data);
+	sd_login_monitor_flush (sd_source->monitor);
+	return ret;
+}
+
+static void
+sd_source_finalize (GSource *source)
+{
+	SdSource *sd_source = (SdSource*) source;
+
+	sd_login_monitor_unref (sd_source->monitor);
+}
+
+static GSourceFuncs sd_source_funcs = {
+	.prepare = sd_source_prepare,
+	.check = sd_source_check,
+	.dispatch = sd_source_dispatch,
+	.finalize = sd_source_finalize
+};
+
+static GSource *
+sd_source_new (void)
+{
+	GSource *source;
+	SdSource *sd_source;
+	int ret;
+
+	source = g_source_new (&sd_source_funcs, sizeof (SdSource));
+	sd_source = (SdSource *)source;
+
+	ret = sd_login_monitor_new (NULL, &sd_source->monitor);
+	if (ret < 0)
+		g_printerr ("Error getting login monitor: %d", ret);
+	else {
+		sd_source->pollfd.fd = sd_login_monitor_get_fd (sd_source->monitor);
+		sd_source->pollfd.events = G_IO_IN;
+		g_source_add_poll (source, &sd_source->pollfd);
+	}
+
+	return source;
+}
+
+static gboolean
+sd_sessions_changed (gpointer user_data)
+{
+	g_signal_emit (NM_SESSION_MONITOR (user_data), signals[CHANGED], 0);
+	return TRUE;
+}
+
+static gboolean
+sd_lookup (uid_t uid, gboolean active, GError **error)
+{
+	int status;
+
+	status = sd_uid_get_sessions (uid, active, NULL) > 0;
+	if (status < 0) {
+		nm_log_warn (LOGD_CORE, "Failed to get systemd sessions for uid %d: %d",
+		             uid, status);
+		return FALSE;
+	}
+	return status > 0 ? TRUE : FALSE;
+}
+
+static void
+sd_init (NMSessionMonitor *monitor)
+{
+	if (access("/run/systemd/seats/", F_OK) < 0)
+		return;
+
+	monitor->sd.source = sd_source_new ();
+	g_source_set_callback (monitor->sd.source, sd_sessions_changed, monitor, NULL);
+	g_source_attach (monitor->sd.source, NULL);
+}
+
+static void
+sd_finalize (NMSessionMonitor *monitor)
+{
+	if (!monitor->sd.source)
+		return;
+
+	g_source_destroy (monitor->sd.source);
+	g_source_unref (monitor->sd.source);
+	monitor->sd.source = NULL;
+}
+#endif /* SESSION_TRACKING_SYSTEMD */
+
+/********************************************************************/
+
+#ifdef SESSION_TRACKING_CONSOLEKIT
+typedef struct {
+	uid_t uid;
+	gboolean local;
+	gboolean active;
+} CkSession;
+
+static void
+ck_session_free (CkSession *session)
+{
+	memset (session, 0, sizeof (CkSession));
+	g_free (session);
+}
+
+static gboolean
+ck_check_key (GKeyFile *keyfile, const char *group, const char *key, GError **error)
+{
+	if (g_key_file_has_key (keyfile, group, key, error))
+		return TRUE;
+
+	if (!error) {
+		g_set_error (error,
+		             NM_MANAGER_ERROR,
+		             NM_MANAGER_ERROR_FAILED,
+		             "ConsoleKit database " CKDB_PATH " group '%s' had no '%s' key",
+		             group, key);
+	}
+	return FALSE;
+}
+
+static CkSession *
+ck_session_new (GKeyFile *keyfile, const char *group, GError **error)
+{
+	GError *local = NULL;
+	CkSession *session;
+
+	session = g_new0 (CkSession, 1);
+	g_assert (session);
+
+	session->uid = G_MAXUINT; /* paranoia */
+	if (!ck_check_key (keyfile, group, "uid", &local))
+		goto error;
+	session->uid = (uid_t) g_key_file_get_integer (keyfile, group, "uid", &local);
+	if (local)
+		goto error;
+
+	if (!ck_check_key (keyfile, group, "is_active", &local))
+		goto error;
+	session->active = g_key_file_get_boolean (keyfile, group, "is_active", &local);
+	if (local)
+		goto error;
+
+	if (!ck_check_key (keyfile, group, "is_local", &local))
+		goto error;
+	session->local = g_key_file_get_boolean (keyfile, group, "is_local", &local);
+	if (local)
+		goto error;
+
+	return session;
+
+error:
+	ck_session_free (session);
+	g_propagate_error (error, local);
+	return NULL;
+}
+
+static void
+ck_session_merge (CkSession *src, CkSession *dest)
+{
+	g_return_if_fail (src != NULL);
+	g_return_if_fail (dest != NULL);
+
+	g_warn_if_fail (src->uid == dest->uid);
+
+	dest->local = (dest->local || src->local);
+	dest->active = (dest->active || src->active);
+}
+
+static void
+ck_free_database (NMSessionMonitor *self)
+{
+	if (self->ck.database != NULL) {
+		g_key_file_free (self->ck.database);
+		self->ck.database = NULL;
+	}
+
+	if (self->ck.sessions_by_uid)
+		g_hash_table_remove_all (self->ck.sessions_by_uid);
+}
+
+static gboolean
+ck_reload_database (NMSessionMonitor *self, GError **error)
+{
+	struct stat statbuf;
+	char **groups = NULL;
+	gsize len = 0, i;
+	CkSession *session;
+
+	ck_free_database (self);
+
+	errno = 0;
+	if (stat (CKDB_PATH, &statbuf) != 0) {
+		g_set_error (error,
+		             NM_MANAGER_ERROR,
+		             NM_MANAGER_ERROR_FAILED,
+		             "Error statting file " CKDB_PATH ": %s",
+		             strerror (errno));
+		goto error;
+	}
+	self->ck.database_mtime = statbuf.st_mtime;
+
+	self->ck.database = g_key_file_new ();
+	if (!g_key_file_load_from_file (self->ck.database, CKDB_PATH, G_KEY_FILE_NONE, error))
+		goto error;
+
+	groups = g_key_file_get_groups (self->ck.database, &len);
+	if (!groups) {
+		g_set_error_literal (error,
+		                     NM_MANAGER_ERROR,
+		                     NM_MANAGER_ERROR_FAILED,
+		                     "Could not load groups from " CKDB_PATH "");
+		goto error;
+	}
+
+	for (i = 0; i < len; i++) {
+		CkSession *found;
+
+		if (!g_str_has_prefix (groups[i], "Session "))
+			continue;
+
+		session = ck_session_new (self->ck.database, groups[i], error);
+		if (!session)
+			goto error;
+
+		found = g_hash_table_lookup (self->ck.sessions_by_uid, GUINT_TO_POINTER (session->uid));
+		if (found) {
+			ck_session_merge (session, found);
+			ck_session_free (session);
+		} else {
+			/* Entirely new user */
+			g_hash_table_insert (self->ck.sessions_by_uid, GUINT_TO_POINTER (session->uid), session);
+		}
+	}
+
+	g_strfreev (groups);
+	return TRUE;
+
+error:
+	if (groups)
+		g_strfreev (groups);
+	ck_free_database (self);
+	return FALSE;
+}
+
+static gboolean
+ck_ensure_database (NMSessionMonitor *self, GError **error)
+{
+	gboolean ret = FALSE;
+
+	if (self->ck.database != NULL) {
+		struct stat statbuf;
+
+		errno = 0;
+		if (stat (CKDB_PATH, &statbuf) != 0) {
+			g_set_error (error,
+			             NM_MANAGER_ERROR,
+			             NM_MANAGER_ERROR_FAILED,
+			             "Error statting file " CKDB_PATH " to check timestamp: %s",
+			             strerror (errno));
+			goto out;
+		}
+
+		if (statbuf.st_mtime == self->ck.database_mtime) {
+			ret = TRUE;
+			goto out;
+		}
+	}
+
+	ret = ck_reload_database (self, error);
+
+out:
+	return ret;
+}
+
+static void
+ck_on_file_monitor_changed (GFileMonitor *    file_monitor,
+                            GFile *           file,
+                            GFile *           other_file,
+                            GFileMonitorEvent event_type,
+                            gpointer          user_data)
+{
+	NMSessionMonitor *self = NM_SESSION_MONITOR (user_data);
+
+	/* throw away cache */
+	ck_free_database (self);
+
+	g_signal_emit (self, signals[CHANGED], 0);
+}
+
+static gboolean
+ck_lookup (NMSessionMonitor *monitor, uid_t uid, gboolean active, GError **error)
+{
+	CkSession *session;
+
+	if (!ck_ensure_database (monitor, error))
+		return FALSE;
+
+	session = g_hash_table_lookup (monitor->ck.sessions_by_uid, GUINT_TO_POINTER (uid));
+	if (!session) {
+		g_set_error (error,
+		             NM_MANAGER_ERROR,
+		             NM_MANAGER_ERROR_FAILED,
+		             "No session found for uid %d",
+		             uid);
+		return FALSE;
+	}
+
+	if (active && !session->active)
+		return FALSE;
+
+	return TRUE;
+}
+
+static void
+ck_init (NMSessionMonitor *monitor)
+{
+	GError *error = NULL;
+	GFile *file;
+
+	/* Sessions-by-user is responsible for destroying the Session objects */
+	monitor->ck.sessions_by_uid = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+	                                                      NULL, (GDestroyNotify) ck_session_free);
+
+	if (!ck_ensure_database (monitor, &error)) {
+		nm_log_dbg (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message);
+		g_clear_error (&error);
+	}
+
+	file = g_file_new_for_path (CKDB_PATH);
+	monitor->ck.database_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
+	g_object_unref (file);
+	if (monitor->ck.database_monitor == NULL) {
+		nm_log_err (LOGD_CORE, "Error monitoring " CKDB_PATH ": %s", error->message);
+		g_clear_error (&error);
+	} else {
+		g_signal_connect (monitor->ck.database_monitor,
+		                  "changed",
+		                  G_CALLBACK (ck_on_file_monitor_changed),
+		                  monitor);
+	}
+}
+
+static void
+ck_finalize (NMSessionMonitor *monitor)
+{
+	g_clear_object (&monitor->ck.database_monitor);
+	ck_free_database (monitor);
+	g_hash_table_destroy (monitor->ck.sessions_by_uid);
+	monitor->ck.sessions_by_uid = NULL;
+}
+#endif /* SESSION_TRACKING_CONSOLEKIT */
+
+/********************************************************************/
+
+static gboolean
+nm_session_monitor_user_to_uid (const char *user, uid_t *out_uid, GError **error)
+{
+	struct passwd *pw;
+
+	pw = getpwnam (user);
+	if (!pw) {
+		g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
+		             "Could not get UID for username '%s'",
+		             user);
+		return FALSE;
+	}
+
+	if (out_uid)
+		*out_uid = pw->pw_uid;
+	return TRUE;
+}
+
+const char *
+nm_session_monitor_uid_to_user (uid_t uid, GError **error)
+{
+	struct passwd *pw;
+
+	pw = getpwuid (uid);
+	if (!pw) {
+		g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
+		             "Could not get username for UID %d",
+		             uid);
+		return NULL;
+	}
+
+	return pw->pw_name;
+}
+
+static gboolean
+nm_session_monitor_lookup (uid_t uid, gboolean active, GError **error)
+{
+	NMSessionMonitor *monitor = nm_session_monitor_get ();
+
+#ifdef SESSION_TRACKING_SYSTEMD
+	if (monitor->sd.source)
+		return sd_lookup (uid, active, error);
+#endif
+
+#ifdef SESSION_TRACKING_CONSOLEKIT
+	if (monitor->ck.database)
+		return ck_lookup (monitor, uid, active, error);
+#endif
+
+	/* If no session tracking method is available, always give a positive
+	 * answer. Please note that this means session tracking cannot be used
+	 * for security purposes.
+	 */
+	return TRUE;
+}
+
+/**
+ * nm_session_monitor_uid_active:
+ * @uid: A user ID.
+ * @error: Return location for error.
+ *
+ * Checks whether the given @uid is logged into a active session or not.
+ *
+ * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is
+ * logged into an active session.
+ */
+gboolean
+nm_session_monitor_uid_active (uid_t uid, GError **error)
+{
+	return nm_session_monitor_lookup (uid, TRUE, error);
+}
+
+/**
+ * nm_session_monitor_uid_has_session:
+ * @monitor: A #NMSessionMonitor.
+ * @uid: A user ID.
+ * @error: Return location for error.
+ *
+ * Checks whether the given @uid is logged into a session or not.
+ *
+ * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is
+ * currently logged into a session.
+ */
+gboolean
+nm_session_monitor_user_has_session (const char *username, GError **error)
+{
+	uid_t uid = G_MAXUINT32;
+
+	g_return_val_if_fail (username != NULL, FALSE);
+
+	if (!nm_session_monitor_user_to_uid (username, &uid, error))
+		return FALSE;
+
+	return nm_session_monitor_lookup (uid, FALSE, error);
+}
+
+/********************************************************************/
+
+NMSessionMonitor *
+nm_session_monitor_get (void)
+{
+	static NMSessionMonitor *singleton = NULL;
+
+	if (!singleton)
+		singleton = NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL));
+
+	return singleton;
+}
+
+gulong
+nm_session_monitor_connect (NMSessionCallback callback, gpointer user_data)
+{
+	return g_signal_connect (nm_session_monitor_get (),
+	                         NM_SESSION_MONITOR_CHANGED,
+	                         G_CALLBACK (callback),
+	                         user_data);
+}
+
+void
+nm_session_monitor_disconnect (gulong handler_id)
+{
+	g_signal_handler_disconnect (nm_session_monitor_get (), handler_id);
+}
+
+static void
+nm_session_monitor_init (NMSessionMonitor *monitor)
+{
+#ifdef SESSION_TRACKING_SYSTEMD
+	sd_init (monitor);
+#endif
+
+#ifdef SESSION_TRACKING_CONSOLEKIT
+	ck_init (monitor);
+#endif
+}
+
+static void
+nm_session_monitor_finalize (GObject *object)
+{
+#ifdef SESSION_TRACKING_SYSTEMD
+	sd_finalize (NM_SESSION_MONITOR (object));
+#endif
+
+#ifdef SESSION_TRACKING_CONSOLEKIT
+	ck_finalize (NM_SESSION_MONITOR (object));
+#endif
+
+	G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize (object);
+}
+
+static void
+nm_session_monitor_class_init (NMSessionMonitorClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	gobject_class->finalize = nm_session_monitor_finalize;
+
+	/**
+	 * NMSessionMonitor::changed:
+	 * @monitor: A #NMSessionMonitor
+	 *
+	 * Emitted when something changes.
+	 */
+	signals[CHANGED] = g_signal_new (NM_SESSION_MONITOR_CHANGED,
+	                                 NM_TYPE_SESSION_MONITOR,
+	                                 G_SIGNAL_RUN_LAST,
+	                                 0, NULL, NULL, NULL,
+	                                 G_TYPE_NONE, 0);
+}
diff --git a/src/nm-session-monitor.h b/src/nm-session-monitor.h
index 3efe6ec..6481935 100644
--- a/src/nm-session-monitor.h
+++ b/src/nm-session-monitor.h
@@ -21,6 +21,7 @@
 #ifndef __NETWORKMANAGER_SESSION_MONITOR_H__
 #define __NETWORKMANAGER_SESSION_MONITOR_H__
 
+#include <unistd.h>
 #include <glib-object.h>
 
 #include "nm-types.h"
@@ -38,25 +39,20 @@ G_BEGIN_DECLS
 
 typedef struct _NMSessionMonitorClass    NMSessionMonitorClass;
 
-GType             nm_session_monitor_get_type     (void) G_GNUC_CONST;
-NMSessionMonitor *nm_session_monitor_get          (void);
+typedef void (*NMSessionCallback) (NMSessionMonitor *monitor, gpointer user_data);
 
-gboolean          nm_session_monitor_user_has_session (NMSessionMonitor *monitor,
-                                                       const char *username,
-                                                       uid_t *out_uid,
-                                                       GError **error);
+GType             nm_session_monitor_get_type     (void) G_GNUC_CONST;
 
-gboolean          nm_session_monitor_uid_has_session  (NMSessionMonitor *monitor,
-                                                       uid_t uid,
-                                                       const char **out_user,
-                                                       GError **error);
+NMSessionMonitor *nm_session_monitor_get          (void);
+gulong            nm_session_monitor_connect      (NMSessionCallback callback,
+                                                   gpointer user_data);
+void              nm_session_monitor_disconnect   (gulong handler_id);
 
-gboolean          nm_session_monitor_user_active      (NMSessionMonitor *monitor,
-                                                       const char *username,
-                                                       GError **error);
+const char *      nm_session_monitor_uid_to_user  (uid_t uid, GError **error);
+gboolean          nm_session_monitor_uid_active   (uid_t uid,
+                                                   GError **error);
 
-gboolean          nm_session_monitor_uid_active       (NMSessionMonitor *monitor,
-                                                       uid_t uid,
+gboolean          nm_session_monitor_user_has_session (const char *username,
                                                        GError **error);
 
 G_END_DECLS
diff --git a/src/nm-session-utils.h b/src/nm-session-utils.h
deleted file mode 100644
index e626f52..0000000
--- a/src/nm-session-utils.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2012 Red Hat, Inc.
- * Author: Dan Williams <dcbw@redhat.com>
- */
-
-#ifndef __NETWORKMANAGER_SESSION_UTILS_H__
-#define __NETWORKMANAGER_SESSION_UTILS_H__
-
-#include <glib.h>
-#include <glib-object.h>
-
-gboolean nm_session_uid_to_user (uid_t uid, const char **out_user, GError **error);
-
-gboolean nm_session_user_to_uid (const char *user, uid_t *out_uid, GError **error);
-
-#endif  /* NM_SESSION_UTILS_H */
diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c
index 117fb21..eafaf06 100644
--- a/src/settings/nm-agent-manager.c
+++ b/src/settings/nm-agent-manager.c
@@ -273,7 +273,7 @@ impl_agent_manager_register_with_capabilities (NMAgentManager *self,
 	NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
 	NMAuthSubject *subject;
 	gulong sender_uid = G_MAXULONG;
-	GError *error = NULL, *local = NULL;
+	GError *error = NULL;
 	NMSecretAgent *agent;
 	NMAuthChain *chain;
 
@@ -286,17 +286,6 @@ impl_agent_manager_register_with_capabilities (NMAgentManager *self,
 	}
 	sender_uid = nm_auth_subject_get_unix_process_uid (subject);
 
-	if (   0 != sender_uid
-	    && !nm_session_monitor_uid_has_session (nm_session_monitor_get (),
-	                                            sender_uid,
-	                                            NULL,
-	                                            &local)) {
-		error = g_error_new_literal (NM_AGENT_MANAGER_ERROR,
-		                             NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED,
-		                             local && local->message ? local->message : "Session not found");
-		goto done;
-	}
-
 	/* Validate the identifier */
 	if (!validate_identifier (identifier, &error))
 		goto done;
@@ -339,7 +328,6 @@ done:
 	if (error)
 		dbus_g_method_return_error (context, error);
 	g_clear_error (&error);
-	g_clear_error (&local);
 	g_clear_object (&subject);
 }
 
@@ -530,11 +518,9 @@ agent_compare_func (gconstpointer aa, gconstpointer bb, gpointer user_data)
 	}
 
 	/* Prefer agents in active sessions */
-	a_active = nm_session_monitor_uid_active (nm_session_monitor_get (),
-	                                          nm_secret_agent_get_owner_uid (a),
+	a_active = nm_session_monitor_uid_active (nm_secret_agent_get_owner_uid (a),
 	                                          NULL);
-	b_active = nm_session_monitor_uid_active (nm_session_monitor_get (),
-	                                          nm_secret_agent_get_owner_uid (b),
+	b_active = nm_session_monitor_uid_active (nm_secret_agent_get_owner_uid (b),
 	                                          NULL);
 	if (a_active && !b_active)
 		return -1;
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 78a830b..1be1b81 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -95,7 +95,6 @@ static guint signals[LAST_SIGNAL] = { 0 };
 
 typedef struct {
 	NMAgentManager *agent_mgr;
-	NMSessionMonitor *session_monitor;
 	guint session_changed_id;
 
 	NMSettingsConnectionFlags flags;
@@ -265,7 +264,7 @@ nm_settings_connection_recheck_visibility (NMSettingsConnection *self)
 		const char *puser;
 
 		if (nm_setting_connection_get_permission (s_con, i, NULL, &puser, NULL)) {
-			if (nm_session_monitor_user_has_session (priv->session_monitor, puser, NULL, NULL)) {
+			if (nm_session_monitor_user_has_session (puser, NULL)) {
 				set_visible (self, TRUE);
 				return;
 			}
@@ -1067,7 +1066,7 @@ auth_start (NMSettingsConnection *self,
 
 	/* Ensure the caller can view this connection */
 	if (!nm_auth_is_subject_in_acl (NM_CONNECTION (self),
-	                                priv->session_monitor,
+	                                nm_session_monitor_get (),
 	                                subject,
 	                                &error_desc)) {
 		error = g_error_new_literal (NM_SETTINGS_ERROR,
@@ -1424,7 +1423,7 @@ impl_settings_connection_update_helper (NMSettingsConnection *self,
 	 * invisible to yourself.
 	 */
 	if (!nm_auth_is_subject_in_acl (tmp ? tmp : NM_CONNECTION (self),
-	                                priv->session_monitor,
+	                                nm_session_monitor_get (),
 	                                subject,
 	                                &error_desc)) {
 		error = g_error_new_literal (NM_SETTINGS_ERROR,
@@ -2168,11 +2167,7 @@ nm_settings_connection_init (NMSettingsConnection *self)
 
 	priv->visible = FALSE;
 
-	priv->session_monitor = nm_session_monitor_get ();
-	priv->session_changed_id = g_signal_connect (priv->session_monitor,
-	                                             NM_SESSION_MONITOR_CHANGED,
-	                                             G_CALLBACK (session_changed_cb),
-	                                             self);
+	priv->session_changed_id = nm_session_monitor_connect (session_changed_cb, self);
 
 	priv->agent_mgr = nm_agent_manager_get ();
 
@@ -2223,7 +2218,7 @@ dispose (GObject *object)
 	set_visible (self, FALSE);
 
 	if (priv->session_changed_id) {
-		g_signal_handler_disconnect (priv->session_monitor, priv->session_changed_id);
+		g_signal_handler_disconnect (nm_session_monitor_get (), priv->session_changed_id);
 		priv->session_changed_id = 0;
 	}
 	g_clear_object (&priv->agent_mgr);
