mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-03 13:38:04 +02:00
core: optionally use systemd for session tracking instead of ConsoleKit
When configured with --enable-systemd, this patch makes NetworkManager use systemd for session tracking instead of ConsoleKit.
This commit is contained in:
parent
c09a59da4b
commit
3b75a97ab0
3 changed files with 350 additions and 8 deletions
28
configure.ac
28
configure.ac
|
|
@ -322,6 +322,8 @@ if test "x$with_systemdsystemunitdir" != xno; then
|
|||
fi
|
||||
AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
|
||||
|
||||
SESSION_TRACKING=none
|
||||
|
||||
dnl
|
||||
dnl Disable ConsoleKit support
|
||||
dnl
|
||||
|
|
@ -332,9 +334,25 @@ if test x"$with_ck" = x"no"; then
|
|||
no_ck="1"
|
||||
else
|
||||
with_ck="yes"
|
||||
SESSION_TRACKING=ConsoleKit
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(NO_CONSOLEKIT, $no_ck, [Define to disable use of ConsoleKit])
|
||||
|
||||
# systemd session tracking
|
||||
AC_ARG_ENABLE([systemd],
|
||||
AS_HELP_STRING([--enable-systemd], [Use systemd for session tracking]),
|
||||
[with_systemd=$enableval],
|
||||
[with_systemd=no])
|
||||
if test "$with_systemd" = "yes" ; then
|
||||
PKG_CHECK_MODULES(SYSTEMD, [libsystemd-login])
|
||||
SESSION_TRACKING=systemd
|
||||
fi
|
||||
|
||||
AC_SUBST(SYSTEMD_CFLAGS)
|
||||
AC_SUBST(SYSTEMD_LIBS)
|
||||
|
||||
|
||||
AM_CONDITIONAL(WITH_SYSTEMD, [test "$with_systemd" = "yes"], [Using systemd])
|
||||
have_libnl="no"
|
||||
PKG_CHECK_MODULES(LIBNL3, libnl-3.0, [have_libnl3=yes], [have_libnl3=no])
|
||||
PKG_CHECK_MODULES(LIBNL_ROUTE3, libnl-route-3.0, [have_libnl_route3=yes], [have_libnl_route3=no])
|
||||
|
|
@ -777,9 +795,9 @@ else
|
|||
fi
|
||||
|
||||
if test -n "${with_systemdsystemunitdir}"; then
|
||||
echo systemd support: ${with_systemdsystemunitdir}
|
||||
echo systemd unit support: ${with_systemdsystemunitdir}
|
||||
else
|
||||
echo systemd support: no
|
||||
echo systemd unit support: no
|
||||
fi
|
||||
|
||||
if test "${enable_polkit}" = "yes"; then
|
||||
|
|
@ -788,11 +806,7 @@ else
|
|||
echo PolicyKit support: no
|
||||
fi
|
||||
|
||||
if test -n "${with_ck}"; then
|
||||
echo ConsoleKit support: ${with_ck}
|
||||
else
|
||||
echo ConsoleKit support: no
|
||||
fi
|
||||
echo Session tracking: ${SESSION_TRACKING}
|
||||
|
||||
if test "${enable_wimax}" = "yes"; then
|
||||
echo WiMAX support: yes
|
||||
|
|
|
|||
|
|
@ -183,9 +183,17 @@ NetworkManager_SOURCES = \
|
|||
nm-dhcp6-config.c \
|
||||
nm-dhcp6-config.h \
|
||||
nm-rfkill.h \
|
||||
nm-session-monitor.c \
|
||||
nm-session-monitor.h
|
||||
|
||||
if WITH_SYSTEMD
|
||||
NetworkManager_SOURCES += \
|
||||
nm-session-monitor-systemd.c
|
||||
|
||||
else
|
||||
NetworkManager_SOURCES += \
|
||||
nm-session-monitor.c
|
||||
endif
|
||||
|
||||
nm-access-point-glue.h: $(top_srcdir)/introspection/nm-access-point.xml
|
||||
$(AM_V_GEN) dbus-binding-tool --prefix=nm_access_point --mode=glib-server --output=$@ $<
|
||||
|
||||
|
|
@ -251,6 +259,7 @@ NetworkManager_CPPFLAGS = \
|
|||
$(LIBNL_CFLAGS) \
|
||||
$(GMODULE_CFLAGS) \
|
||||
$(POLKIT_CFLAGS) \
|
||||
$(SYSTEMD_CFLAGS) \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
-DBINDIR=\"$(bindir)\" \
|
||||
-DSBINDIR=\"$(sbindir)\" \
|
||||
|
|
@ -285,6 +294,7 @@ NetworkManager_LDADD = \
|
|||
$(LIBNL_LIBS) \
|
||||
$(GMODULE_LIBS) \
|
||||
$(POLKIT_LIBS) \
|
||||
$(SYSTEMD_LIBS) \
|
||||
$(LIBM) \
|
||||
$(LIBDL)
|
||||
|
||||
|
|
|
|||
318
src/nm-session-monitor-systemd.c
Normal file
318
src/nm-session-monitor-systemd.c
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <string.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <systemd/sd-login.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nm-session-monitor.h"
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
#define NM_SESSION_MONITOR_ERROR (nm_session_monitor_error_quark ())
|
||||
GQuark nm_session_monitor_error_quark (void) G_GNUC_CONST;
|
||||
GType nm_session_monitor_error_get_type (void) G_GNUC_CONST;
|
||||
|
||||
typedef enum {
|
||||
NM_SESSION_MONITOR_ERROR_UNKNOWN_USER
|
||||
} NMSessionMonitorError;
|
||||
|
||||
GQuark
|
||||
nm_session_monitor_error_quark (void)
|
||||
{
|
||||
static GQuark ret = 0;
|
||||
|
||||
if (G_UNLIKELY (ret == 0))
|
||||
ret = g_quark_from_static_string ("nm-session-monitor-error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
|
||||
|
||||
GType
|
||||
nm_session_monitor_error_get_type (void)
|
||||
{
|
||||
static GType etype = 0;
|
||||
|
||||
if (etype == 0) {
|
||||
static const GEnumValue values[] = {
|
||||
/* Username or UID could could not be found */
|
||||
ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "UnknownUser"),
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
etype = g_enum_register_static ("NMSessionMonitorError", values);
|
||||
}
|
||||
return etype;
|
||||
}
|
||||
/********************************************************************/
|
||||
|
||||
|
||||
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 = {
|
||||
sd_source_prepare,
|
||||
sd_source_check,
|
||||
sd_source_dispatch,
|
||||
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;
|
||||
|
||||
if ((ret = sd_login_monitor_new (NULL, &sd_source->monitor)) < 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;
|
||||
}
|
||||
|
||||
struct _NMSessionMonitor
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GSource *sd_source;
|
||||
};
|
||||
|
||||
struct _NMSessionMonitorClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*changed) (NMSessionMonitor *monitor);
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
CHANGED_SIGNAL,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = {0};
|
||||
|
||||
G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
sessions_changed (gpointer user_data)
|
||||
{
|
||||
NMSessionMonitor *monitor = NM_SESSION_MONITOR (user_data);
|
||||
|
||||
g_signal_emit (monitor, signals[CHANGED_SIGNAL], 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nm_session_monitor_init (NMSessionMonitor *monitor)
|
||||
{
|
||||
monitor->sd_source = sd_source_new ();
|
||||
g_source_set_callback (monitor->sd_source, sessions_changed, monitor, NULL);
|
||||
g_source_attach (monitor->sd_source, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_session_monitor_finalize (GObject *object)
|
||||
{
|
||||
NMSessionMonitor *monitor = NM_SESSION_MONITOR (object);
|
||||
|
||||
if (monitor->sd_source != NULL)
|
||||
{
|
||||
g_source_destroy (monitor->sd_source);
|
||||
g_source_unref (monitor->sd_source);
|
||||
}
|
||||
|
||||
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 = nm_session_monitor_finalize;
|
||||
|
||||
/**
|
||||
* NMSessionMonitor::changed:
|
||||
* @monitor: A #NMSessionMonitor
|
||||
*
|
||||
* Emitted when something changes.
|
||||
*/
|
||||
signals[CHANGED_SIGNAL] = g_signal_new ("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)
|
||||
return g_object_ref (singleton);
|
||||
|
||||
singleton = NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL));
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
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_SESSION_MONITOR_ERROR,
|
||||
NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
|
||||
"Could not get UID for username '%s'",
|
||||
user);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (out_uid)
|
||||
*out_uid = pw->pw_uid;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_session_monitor_user_has_session (NMSessionMonitor *monitor,
|
||||
const char *username,
|
||||
uid_t *out_uid,
|
||||
GError **error)
|
||||
{
|
||||
uid_t uid;
|
||||
|
||||
if (!user_to_uid (username, &uid, error))
|
||||
return FALSE;
|
||||
|
||||
if (out_uid)
|
||||
*out_uid = uid;
|
||||
|
||||
return nm_session_monitor_uid_has_session (monitor, uid, NULL, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_session_monitor_user_active (NMSessionMonitor *monitor,
|
||||
const char *username,
|
||||
GError **error)
|
||||
{
|
||||
uid_t uid;
|
||||
|
||||
if (!user_to_uid (username, &uid, error))
|
||||
return FALSE;
|
||||
|
||||
return nm_session_monitor_uid_active (monitor, uid, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_session_monitor_uid_has_session (NMSessionMonitor *monitor,
|
||||
uid_t uid,
|
||||
const char **out_user,
|
||||
GError **error)
|
||||
{
|
||||
return sd_uid_get_sessions (uid, FALSE, NULL) > 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_session_monitor_uid_active (NMSessionMonitor *monitor,
|
||||
uid_t uid,
|
||||
GError **error)
|
||||
{
|
||||
return sd_uid_get_sessions (uid, TRUE, NULL) > 0;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue