|
|
88f331 |
From f86c93014e698d81d43fe1ebaf805fa794e5a984 Mon Sep 17 00:00:00 2001
|
|
|
88f331 |
From: Ray Strode <rstrode@redhat.com>
|
|
|
88f331 |
Date: Tue, 22 Oct 2013 15:42:16 -0400
|
|
|
88f331 |
Subject: [PATCH] daemon: rip out extension interface
|
|
|
88f331 |
|
|
|
88f331 |
It requires newer glib than we're shipping
|
|
|
88f331 |
---
|
|
|
88f331 |
configure.ac | 2 +-
|
|
|
88f331 |
src/Makefile.am | 1 -
|
|
|
88f331 |
src/daemon.c | 11 ---
|
|
|
88f331 |
src/daemon.h | 3 -
|
|
|
88f331 |
src/user.c | 273 --------------------------------------------------------
|
|
|
88f331 |
5 files changed, 1 insertion(+), 289 deletions(-)
|
|
|
88f331 |
|
|
|
88f331 |
diff --git a/configure.ac b/configure.ac
|
|
|
88f331 |
index cb1fcda..a7f4e20 100644
|
|
|
88f331 |
--- a/configure.ac
|
|
|
88f331 |
+++ b/configure.ac
|
|
|
88f331 |
@@ -1,58 +1,58 @@
|
|
|
88f331 |
AC_INIT([AccountsService],[0.6.35])
|
|
|
88f331 |
AM_INIT_AUTOMAKE(no-dist-gzip dist-xz tar-ustar foreign)
|
|
|
88f331 |
|
|
|
88f331 |
GETTEXT_PACKAGE=accounts-service
|
|
|
88f331 |
AC_SUBST(GETTEXT_PACKAGE)
|
|
|
88f331 |
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",
|
|
|
88f331 |
[the gettext translation domain])
|
|
|
88f331 |
|
|
|
88f331 |
# Support silent build rules, requires at least automake-1.11. Enable
|
|
|
88f331 |
# by either passing --enable-silent-rules to configure or passing V=0
|
|
|
88f331 |
# to make
|
|
|
88f331 |
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
|
|
88f331 |
|
|
|
88f331 |
AC_USE_SYSTEM_EXTENSIONS
|
|
|
88f331 |
AC_PROG_CC
|
|
|
88f331 |
PKG_PROG_PKG_CONFIG
|
|
|
88f331 |
AM_GLIB_GNU_GETTEXT
|
|
|
88f331 |
IT_PROG_INTLTOOL([0.40.0])
|
|
|
88f331 |
|
|
|
88f331 |
LT_INIT
|
|
|
88f331 |
LT_CURRENT=0
|
|
|
88f331 |
LT_REVISION=0
|
|
|
88f331 |
LT_AGE=0
|
|
|
88f331 |
AC_SUBST(LT_CURRENT)
|
|
|
88f331 |
AC_SUBST(LT_REVISION)
|
|
|
88f331 |
AC_SUBST(LT_AGE)
|
|
|
88f331 |
|
|
|
88f331 |
-PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.37.3 gio-unix-2.0)
|
|
|
88f331 |
+PKG_CHECK_MODULES(GIO, gio-2.0 gio-unix-2.0)
|
|
|
88f331 |
PKG_CHECK_MODULES(POLKIT, gio-unix-2.0 polkit-gobject-1)
|
|
|
88f331 |
|
|
|
88f331 |
AM_MAINTAINER_MODE([enable])
|
|
|
88f331 |
|
|
|
88f331 |
# client library dependencies
|
|
|
88f331 |
LIBACCOUNTSSERVICE_LIBS="$GIO_LIBS"
|
|
|
88f331 |
AC_SUBST(LIBACCOUNTSSERVICE_LIBS)
|
|
|
88f331 |
LIBACCOUNTSSERVICE_CFLAGS="$GIO_CFLAGS"
|
|
|
88f331 |
AC_SUBST(LIBACCOUNTSSERVICE_CFLAGS)
|
|
|
88f331 |
|
|
|
88f331 |
GOBJECT_INTROSPECTION_CHECK([0.9.12])
|
|
|
88f331 |
|
|
|
88f331 |
dnl ---------------------------------------------------------------------------
|
|
|
88f331 |
dnl - Core configuration
|
|
|
88f331 |
dnl ---------------------------------------------------------------------------
|
|
|
88f331 |
|
|
|
88f331 |
AC_ARG_ENABLE(admin-group,
|
|
|
88f331 |
[AS_HELP_STRING([--enable-admin-group],[Set group for administrative accounts @<:@default=auto@:>@])],
|
|
|
88f331 |
,enable_admin_group=auto)
|
|
|
88f331 |
AS_IF([test x$enable_admin_group = xauto], [
|
|
|
88f331 |
AC_CHECK_FILE(/etc/redhat-release, enable_admin_group=wheel)
|
|
|
88f331 |
AC_CHECK_FILE(/etc/debian_version, enable_admin_group=sudo)
|
|
|
88f331 |
AS_IF([test x$enable_admin_group = xauto], [
|
|
|
88f331 |
enable_admin_group=wheel
|
|
|
88f331 |
])
|
|
|
88f331 |
])
|
|
|
88f331 |
AC_DEFINE_UNQUOTED([ADMIN_GROUP], ["$enable_admin_group"], [Define to the group for administrator users])
|
|
|
88f331 |
|
|
|
88f331 |
AC_ARG_ENABLE(user-heuristics,
|
|
|
88f331 |
[AS_HELP_STRING([--enable-user-heuristics],[Enable heuristics for guessing system vs. human users])],
|
|
|
88f331 |
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
|
88f331 |
index 6940f2d..de57e7a 100644
|
|
|
88f331 |
--- a/src/Makefile.am
|
|
|
88f331 |
+++ b/src/Makefile.am
|
|
|
88f331 |
@@ -7,52 +7,51 @@ INCLUDES = \
|
|
|
88f331 |
-DICONDIR=\"$(localstatedir)/lib/AccountsService/icons\" \
|
|
|
88f331 |
-DUSERDIR=\"$(localstatedir)/lib/AccountsService/users\" \
|
|
|
88f331 |
-I$(srcdir) \
|
|
|
88f331 |
-I$(builddir) \
|
|
|
88f331 |
$(POLKIT_CFLAGS) \
|
|
|
88f331 |
$(WARN_CFLAGS)
|
|
|
88f331 |
|
|
|
88f331 |
noinst_LTLIBRARIES = libaccounts-generated.la
|
|
|
88f331 |
|
|
|
88f331 |
libaccounts_generated_la_SOURCES = \
|
|
|
88f331 |
accounts-generated.c \
|
|
|
88f331 |
accounts-generated.h \
|
|
|
88f331 |
accounts-user-generated.c \
|
|
|
88f331 |
accounts-user-generated.h \
|
|
|
88f331 |
$(NULL)
|
|
|
88f331 |
BUILT_SOURCES += $(libaccounts_generated_la_SOURCES)
|
|
|
88f331 |
|
|
|
88f331 |
accounts-generated.c accounts-generated.h: $(top_srcdir)/data/org.freedesktop.Accounts.xml Makefile
|
|
|
88f331 |
gdbus-codegen --generate-c-code accounts-generated --c-namespace Accounts --interface-prefix=org.freedesktop. $(top_srcdir)/data/org.freedesktop.Accounts.xml
|
|
|
88f331 |
|
|
|
88f331 |
accounts-user-generated.c accounts-user-generated.h: $(top_srcdir)/data/org.freedesktop.Accounts.User.xml Makefile
|
|
|
88f331 |
gdbus-codegen --generate-c-code accounts-user-generated --c-namespace Accounts --interface-prefix=org.freedesktop.Accounts. $(top_srcdir)/data/org.freedesktop.Accounts.User.xml
|
|
|
88f331 |
|
|
|
88f331 |
libexec_PROGRAMS = accounts-daemon
|
|
|
88f331 |
|
|
|
88f331 |
accounts_daemon_SOURCES = \
|
|
|
88f331 |
$(enums_h_sources) \
|
|
|
88f331 |
types.h \
|
|
|
88f331 |
daemon.h \
|
|
|
88f331 |
daemon.c \
|
|
|
88f331 |
- extensions.c \
|
|
|
88f331 |
user-classify.h \
|
|
|
88f331 |
user-classify.c \
|
|
|
88f331 |
user.h \
|
|
|
88f331 |
user.c \
|
|
|
88f331 |
util.h \
|
|
|
88f331 |
util.c \
|
|
|
88f331 |
main.c
|
|
|
88f331 |
|
|
|
88f331 |
accounts_daemon_LDADD = \
|
|
|
88f331 |
libaccounts-generated.la \
|
|
|
88f331 |
$(POLKIT_LIBS)
|
|
|
88f331 |
|
|
|
88f331 |
CLEANFILES = \
|
|
|
88f331 |
$(BUILT_SOURCES) \
|
|
|
88f331 |
*.gcda \
|
|
|
88f331 |
*.gcno \
|
|
|
88f331 |
$(NULL)
|
|
|
88f331 |
|
|
|
88f331 |
install-data-hook:
|
|
|
88f331 |
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/AccountsService/users"
|
|
|
88f331 |
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/AccountsService/icons"
|
|
|
88f331 |
diff --git a/src/daemon.c b/src/daemon.c
|
|
|
88f331 |
index 9c9f617..ea75190 100644
|
|
|
88f331 |
--- a/src/daemon.c
|
|
|
88f331 |
+++ b/src/daemon.c
|
|
|
88f331 |
@@ -53,61 +53,60 @@
|
|
|
88f331 |
#define PATH_GDM_CUSTOM "/etc/gdm/custom.conf"
|
|
|
88f331 |
#ifdef HAVE_UTMPX_H
|
|
|
88f331 |
#define PATH_WTMP _PATH_WTMPX
|
|
|
88f331 |
#endif
|
|
|
88f331 |
|
|
|
88f331 |
enum {
|
|
|
88f331 |
PROP_0,
|
|
|
88f331 |
PROP_DAEMON_VERSION
|
|
|
88f331 |
};
|
|
|
88f331 |
|
|
|
88f331 |
struct DaemonPrivate {
|
|
|
88f331 |
GDBusConnection *bus_connection;
|
|
|
88f331 |
GDBusProxy *bus_proxy;
|
|
|
88f331 |
|
|
|
88f331 |
GHashTable *users;
|
|
|
88f331 |
|
|
|
88f331 |
User *autologin;
|
|
|
88f331 |
|
|
|
88f331 |
GFileMonitor *passwd_monitor;
|
|
|
88f331 |
GFileMonitor *shadow_monitor;
|
|
|
88f331 |
GFileMonitor *group_monitor;
|
|
|
88f331 |
GFileMonitor *gdm_monitor;
|
|
|
88f331 |
#ifdef HAVE_UTMPX_H
|
|
|
88f331 |
GFileMonitor *wtmp_monitor;
|
|
|
88f331 |
#endif
|
|
|
88f331 |
|
|
|
88f331 |
guint reload_id;
|
|
|
88f331 |
guint autologin_id;
|
|
|
88f331 |
|
|
|
88f331 |
PolkitAuthority *authority;
|
|
|
88f331 |
- GHashTable *extension_ifaces;
|
|
|
88f331 |
};
|
|
|
88f331 |
|
|
|
88f331 |
typedef struct passwd * (* EntryGeneratorFunc) (GHashTable *, gpointer *);
|
|
|
88f331 |
|
|
|
88f331 |
static void daemon_accounts_accounts_iface_init (AccountsAccountsIface *iface);
|
|
|
88f331 |
|
|
|
88f331 |
G_DEFINE_TYPE_WITH_CODE (Daemon, daemon, ACCOUNTS_TYPE_ACCOUNTS_SKELETON, G_IMPLEMENT_INTERFACE (ACCOUNTS_TYPE_ACCOUNTS, daemon_accounts_accounts_iface_init));
|
|
|
88f331 |
|
|
|
88f331 |
#define DAEMON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_DAEMON, DaemonPrivate))
|
|
|
88f331 |
|
|
|
88f331 |
static const GDBusErrorEntry accounts_error_entries[] =
|
|
|
88f331 |
{
|
|
|
88f331 |
{ ERROR_FAILED, "org.freedesktop.Accounts.Error.Failed" },
|
|
|
88f331 |
{ ERROR_USER_EXISTS, "org.freedesktop.Accounts.Error.UserExists" },
|
|
|
88f331 |
{ ERROR_USER_DOES_NOT_EXIST, "org.freedesktop.Accounts.Error.UserDoesNotExist" },
|
|
|
88f331 |
{ ERROR_PERMISSION_DENIED, "org.freedesktop.Accounts.Error.PermissionDenied" },
|
|
|
88f331 |
{ ERROR_NOT_SUPPORTED, "org.freedesktop.Accounts.Error.NotSupported" }
|
|
|
88f331 |
};
|
|
|
88f331 |
|
|
|
88f331 |
GQuark
|
|
|
88f331 |
error_quark (void)
|
|
|
88f331 |
{
|
|
|
88f331 |
static volatile gsize quark_volatile = 0;
|
|
|
88f331 |
|
|
|
88f331 |
g_dbus_error_register_error_domain ("accounts_error",
|
|
|
88f331 |
&quark_volatile,
|
|
|
88f331 |
accounts_error_entries,
|
|
|
88f331 |
G_N_ELEMENTS (accounts_error_entries));
|
|
|
88f331 |
|
|
|
88f331 |
return (GQuark) quark_volatile;
|
|
|
88f331 |
@@ -656,107 +655,103 @@ setup_monitor (Daemon *daemon,
|
|
|
88f331 |
FileChangeCallback *callback)
|
|
|
88f331 |
{
|
|
|
88f331 |
GError *error = NULL;
|
|
|
88f331 |
GFile *file;
|
|
|
88f331 |
GFileMonitor *monitor;
|
|
|
88f331 |
|
|
|
88f331 |
file = g_file_new_for_path (path);
|
|
|
88f331 |
monitor = g_file_monitor_file (file,
|
|
|
88f331 |
G_FILE_MONITOR_NONE,
|
|
|
88f331 |
NULL,
|
|
|
88f331 |
&error);
|
|
|
88f331 |
if (monitor != NULL) {
|
|
|
88f331 |
g_signal_connect (monitor,
|
|
|
88f331 |
"changed",
|
|
|
88f331 |
G_CALLBACK (callback),
|
|
|
88f331 |
daemon);
|
|
|
88f331 |
} else {
|
|
|
88f331 |
g_warning ("Unable to monitor %s: %s", path, error->message);
|
|
|
88f331 |
g_error_free (error);
|
|
|
88f331 |
}
|
|
|
88f331 |
g_object_unref (file);
|
|
|
88f331 |
|
|
|
88f331 |
return monitor;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
static void
|
|
|
88f331 |
daemon_init (Daemon *daemon)
|
|
|
88f331 |
{
|
|
|
88f331 |
daemon->priv = DAEMON_GET_PRIVATE (daemon);
|
|
|
88f331 |
|
|
|
88f331 |
- daemon->priv->extension_ifaces = daemon_read_extension_ifaces ();
|
|
|
88f331 |
-
|
|
|
88f331 |
daemon->priv->users = create_users_hash_table ();
|
|
|
88f331 |
|
|
|
88f331 |
daemon->priv->passwd_monitor = setup_monitor (daemon,
|
|
|
88f331 |
PATH_PASSWD,
|
|
|
88f331 |
on_users_monitor_changed);
|
|
|
88f331 |
daemon->priv->shadow_monitor = setup_monitor (daemon,
|
|
|
88f331 |
PATH_SHADOW,
|
|
|
88f331 |
on_users_monitor_changed);
|
|
|
88f331 |
daemon->priv->group_monitor = setup_monitor (daemon,
|
|
|
88f331 |
PATH_GROUP,
|
|
|
88f331 |
on_users_monitor_changed);
|
|
|
88f331 |
|
|
|
88f331 |
#ifdef HAVE_UTMPX_H
|
|
|
88f331 |
daemon->priv->wtmp_monitor = setup_monitor (daemon,
|
|
|
88f331 |
PATH_WTMP,
|
|
|
88f331 |
on_users_monitor_changed);
|
|
|
88f331 |
#endif
|
|
|
88f331 |
|
|
|
88f331 |
daemon->priv->gdm_monitor = setup_monitor (daemon,
|
|
|
88f331 |
PATH_GDM_CUSTOM,
|
|
|
88f331 |
on_gdm_monitor_changed);
|
|
|
88f331 |
|
|
|
88f331 |
queue_reload_users (daemon);
|
|
|
88f331 |
queue_reload_autologin (daemon);
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
static void
|
|
|
88f331 |
daemon_finalize (GObject *object)
|
|
|
88f331 |
{
|
|
|
88f331 |
Daemon *daemon;
|
|
|
88f331 |
|
|
|
88f331 |
g_return_if_fail (IS_DAEMON (object));
|
|
|
88f331 |
|
|
|
88f331 |
daemon = DAEMON (object);
|
|
|
88f331 |
|
|
|
88f331 |
if (daemon->priv->bus_proxy != NULL)
|
|
|
88f331 |
g_object_unref (daemon->priv->bus_proxy);
|
|
|
88f331 |
|
|
|
88f331 |
if (daemon->priv->bus_connection != NULL)
|
|
|
88f331 |
g_object_unref (daemon->priv->bus_connection);
|
|
|
88f331 |
|
|
|
88f331 |
g_hash_table_destroy (daemon->priv->users);
|
|
|
88f331 |
|
|
|
88f331 |
- g_hash_table_unref (daemon->priv->extension_ifaces);
|
|
|
88f331 |
-
|
|
|
88f331 |
G_OBJECT_CLASS (daemon_parent_class)->finalize (object);
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
static gboolean
|
|
|
88f331 |
register_accounts_daemon (Daemon *daemon)
|
|
|
88f331 |
{
|
|
|
88f331 |
GError *error = NULL;
|
|
|
88f331 |
|
|
|
88f331 |
daemon->priv->authority = polkit_authority_get_sync (NULL, &error);
|
|
|
88f331 |
|
|
|
88f331 |
if (daemon->priv->authority == NULL) {
|
|
|
88f331 |
if (error != NULL) {
|
|
|
88f331 |
g_critical ("error getting polkit authority: %s", error->message);
|
|
|
88f331 |
g_error_free (error);
|
|
|
88f331 |
}
|
|
|
88f331 |
goto error;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
daemon->priv->bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
|
|
|
88f331 |
if (daemon->priv->bus_connection == NULL) {
|
|
|
88f331 |
if (error != NULL) {
|
|
|
88f331 |
g_critical ("error getting system bus: %s", error->message);
|
|
|
88f331 |
g_error_free (error);
|
|
|
88f331 |
}
|
|
|
88f331 |
goto error;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (daemon),
|
|
|
88f331 |
daemon->priv->bus_connection,
|
|
|
88f331 |
"/org/freedesktop/Accounts",
|
|
|
88f331 |
@@ -1526,66 +1521,60 @@ daemon_local_set_automatic_login (Daemon *daemon,
|
|
|
88f331 |
{
|
|
|
88f331 |
if (daemon->priv->autologin == user && enabled) {
|
|
|
88f331 |
return TRUE;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
if (daemon->priv->autologin != user && !enabled) {
|
|
|
88f331 |
return TRUE;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
if (!save_autologin (daemon, user_get_user_name (user), enabled, error)) {
|
|
|
88f331 |
return FALSE;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
if (daemon->priv->autologin != NULL) {
|
|
|
88f331 |
g_object_set (daemon->priv->autologin, "automatic-login", FALSE, NULL);
|
|
|
88f331 |
g_signal_emit_by_name (daemon->priv->autologin, "changed", 0);
|
|
|
88f331 |
g_object_unref (daemon->priv->autologin);
|
|
|
88f331 |
daemon->priv->autologin = NULL;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
if (enabled) {
|
|
|
88f331 |
g_object_set (user, "automatic-login", TRUE, NULL);
|
|
|
88f331 |
g_signal_emit_by_name (user, "changed", 0);
|
|
|
88f331 |
g_object_ref (user);
|
|
|
88f331 |
daemon->priv->autologin = user;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
return TRUE;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
-GHashTable *
|
|
|
88f331 |
-daemon_get_extension_ifaces (Daemon *daemon)
|
|
|
88f331 |
-{
|
|
|
88f331 |
- return daemon->priv->extension_ifaces;
|
|
|
88f331 |
-}
|
|
|
88f331 |
-
|
|
|
88f331 |
static void
|
|
|
88f331 |
get_property (GObject *object,
|
|
|
88f331 |
guint prop_id,
|
|
|
88f331 |
GValue *value,
|
|
|
88f331 |
GParamSpec *pspec)
|
|
|
88f331 |
{
|
|
|
88f331 |
switch (prop_id) {
|
|
|
88f331 |
case PROP_DAEMON_VERSION:
|
|
|
88f331 |
g_value_set_string (value, VERSION);
|
|
|
88f331 |
break;
|
|
|
88f331 |
|
|
|
88f331 |
default:
|
|
|
88f331 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
88f331 |
break;
|
|
|
88f331 |
}
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
static void
|
|
|
88f331 |
set_property (GObject *object,
|
|
|
88f331 |
guint prop_id,
|
|
|
88f331 |
const GValue *value,
|
|
|
88f331 |
GParamSpec *pspec)
|
|
|
88f331 |
{
|
|
|
88f331 |
switch (prop_id) {
|
|
|
88f331 |
case PROP_DAEMON_VERSION:
|
|
|
88f331 |
g_assert_not_reached ();
|
|
|
88f331 |
break;
|
|
|
88f331 |
|
|
|
88f331 |
default:
|
|
|
88f331 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
88f331 |
diff --git a/src/daemon.h b/src/daemon.h
|
|
|
88f331 |
index b7e072e..e036407 100644
|
|
|
88f331 |
--- a/src/daemon.h
|
|
|
88f331 |
+++ b/src/daemon.h
|
|
|
88f331 |
@@ -69,36 +69,33 @@ GQuark error_quark (void);
|
|
|
88f331 |
GType daemon_get_type (void) G_GNUC_CONST;
|
|
|
88f331 |
Daemon *daemon_new (void);
|
|
|
88f331 |
|
|
|
88f331 |
/* local methods */
|
|
|
88f331 |
|
|
|
88f331 |
User *daemon_local_find_user_by_id (Daemon *daemon,
|
|
|
88f331 |
uid_t uid);
|
|
|
88f331 |
User *daemon_local_find_user_by_name (Daemon *daemon,
|
|
|
88f331 |
const gchar *name);
|
|
|
88f331 |
User *daemon_local_get_automatic_login_user (Daemon *daemon);
|
|
|
88f331 |
|
|
|
88f331 |
typedef void (*AuthorizedCallback) (Daemon *daemon,
|
|
|
88f331 |
User *user,
|
|
|
88f331 |
GDBusMethodInvocation *context,
|
|
|
88f331 |
gpointer data);
|
|
|
88f331 |
|
|
|
88f331 |
void daemon_local_check_auth (Daemon *daemon,
|
|
|
88f331 |
User *user,
|
|
|
88f331 |
const gchar *action_id,
|
|
|
88f331 |
gboolean allow_interaction,
|
|
|
88f331 |
AuthorizedCallback auth_cb,
|
|
|
88f331 |
GDBusMethodInvocation *context,
|
|
|
88f331 |
gpointer data,
|
|
|
88f331 |
GDestroyNotify destroy_notify);
|
|
|
88f331 |
|
|
|
88f331 |
gboolean daemon_local_set_automatic_login (Daemon *daemon,
|
|
|
88f331 |
User *user,
|
|
|
88f331 |
gboolean enabled,
|
|
|
88f331 |
GError **error);
|
|
|
88f331 |
|
|
|
88f331 |
-GHashTable * daemon_read_extension_ifaces (void);
|
|
|
88f331 |
-GHashTable * daemon_get_extension_ifaces (Daemon *daemon);
|
|
|
88f331 |
-
|
|
|
88f331 |
G_END_DECLS
|
|
|
88f331 |
|
|
|
88f331 |
#endif /* __DAEMON_H__ */
|
|
|
88f331 |
diff --git a/src/user.c b/src/user.c
|
|
|
88f331 |
index 1698eeb..163d136 100644
|
|
|
88f331 |
--- a/src/user.c
|
|
|
88f331 |
+++ b/src/user.c
|
|
|
88f331 |
@@ -77,63 +77,60 @@ struct User {
|
|
|
88f331 |
|
|
|
88f331 |
GDBusConnection *system_bus_connection;
|
|
|
88f331 |
gchar *object_path;
|
|
|
88f331 |
|
|
|
88f331 |
Daemon *daemon;
|
|
|
88f331 |
|
|
|
88f331 |
GKeyFile *keyfile;
|
|
|
88f331 |
|
|
|
88f331 |
uid_t uid;
|
|
|
88f331 |
gid_t gid;
|
|
|
88f331 |
gchar *user_name;
|
|
|
88f331 |
gchar *real_name;
|
|
|
88f331 |
AccountType account_type;
|
|
|
88f331 |
PasswordMode password_mode;
|
|
|
88f331 |
gchar *password_hint;
|
|
|
88f331 |
gchar *home_dir;
|
|
|
88f331 |
gchar *shell;
|
|
|
88f331 |
gchar *email;
|
|
|
88f331 |
gchar *language;
|
|
|
88f331 |
gchar *x_session;
|
|
|
88f331 |
gchar *location;
|
|
|
88f331 |
guint64 login_frequency;
|
|
|
88f331 |
gint64 login_time;
|
|
|
88f331 |
GVariant *login_history;
|
|
|
88f331 |
gchar *icon_file;
|
|
|
88f331 |
gchar *default_icon_file;
|
|
|
88f331 |
gboolean locked;
|
|
|
88f331 |
gboolean automatic_login;
|
|
|
88f331 |
gboolean system_account;
|
|
|
88f331 |
gboolean local_account;
|
|
|
88f331 |
-
|
|
|
88f331 |
- guint *extension_ids;
|
|
|
88f331 |
- guint n_extension_ids;
|
|
|
88f331 |
};
|
|
|
88f331 |
|
|
|
88f331 |
typedef struct UserClass
|
|
|
88f331 |
{
|
|
|
88f331 |
AccountsUserSkeletonClass parent_class;
|
|
|
88f331 |
} UserClass;
|
|
|
88f331 |
|
|
|
88f331 |
static void user_accounts_user_iface_init (AccountsUserIface *iface);
|
|
|
88f331 |
|
|
|
88f331 |
G_DEFINE_TYPE_WITH_CODE (User, user, ACCOUNTS_TYPE_USER_SKELETON, G_IMPLEMENT_INTERFACE (ACCOUNTS_TYPE_USER, user_accounts_user_iface_init));
|
|
|
88f331 |
|
|
|
88f331 |
static gint
|
|
|
88f331 |
account_type_from_pwent (struct passwd *pwent)
|
|
|
88f331 |
{
|
|
|
88f331 |
struct group *grp;
|
|
|
88f331 |
gid_t wheel;
|
|
|
88f331 |
gid_t *groups;
|
|
|
88f331 |
gint ngroups;
|
|
|
88f331 |
gint i;
|
|
|
88f331 |
|
|
|
88f331 |
if (pwent->pw_uid == 0) {
|
|
|
88f331 |
g_debug ("user is root so account type is administrator");
|
|
|
88f331 |
return ACCOUNT_TYPE_ADMINISTRATOR;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
grp = getgrnam (ADMIN_GROUP);
|
|
|
88f331 |
if (grp == NULL) {
|
|
|
88f331 |
g_debug (ADMIN_GROUP " group not found");
|
|
|
88f331 |
return ACCOUNT_TYPE_STANDARD;
|
|
|
88f331 |
}
|
|
|
88f331 |
@@ -436,379 +433,109 @@ save_extra_data (User *user)
|
|
|
88f331 |
user->user_name,
|
|
|
88f331 |
NULL);
|
|
|
88f331 |
g_file_set_contents (filename, data, -1, &error);
|
|
|
88f331 |
g_free (filename);
|
|
|
88f331 |
}
|
|
|
88f331 |
if (error) {
|
|
|
88f331 |
g_warning ("Saving data for user %s failed: %s",
|
|
|
88f331 |
user->user_name, error->message);
|
|
|
88f331 |
g_error_free (error);
|
|
|
88f331 |
}
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
static void
|
|
|
88f331 |
move_extra_data (const gchar *old_name,
|
|
|
88f331 |
const gchar *new_name)
|
|
|
88f331 |
{
|
|
|
88f331 |
gchar *old_filename;
|
|
|
88f331 |
gchar *new_filename;
|
|
|
88f331 |
|
|
|
88f331 |
old_filename = g_build_filename (USERDIR,
|
|
|
88f331 |
old_name, NULL);
|
|
|
88f331 |
new_filename = g_build_filename (USERDIR,
|
|
|
88f331 |
new_name, NULL);
|
|
|
88f331 |
|
|
|
88f331 |
g_rename (old_filename, new_filename);
|
|
|
88f331 |
|
|
|
88f331 |
g_free (old_filename);
|
|
|
88f331 |
g_free (new_filename);
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
-static GVariant *
|
|
|
88f331 |
-user_extension_get_value (User *user,
|
|
|
88f331 |
- GDBusInterfaceInfo *interface,
|
|
|
88f331 |
- const GDBusPropertyInfo *property)
|
|
|
88f331 |
-{
|
|
|
88f331 |
- const GVariantType *type = G_VARIANT_TYPE (property->signature);
|
|
|
88f331 |
- GVariant *value;
|
|
|
88f331 |
- gchar *printed;
|
|
|
88f331 |
- gint i;
|
|
|
88f331 |
-
|
|
|
88f331 |
- /* First, try to get the value from the keyfile */
|
|
|
88f331 |
- printed = g_key_file_get_value (user->keyfile, interface->name, property->name, NULL);
|
|
|
88f331 |
- if (printed) {
|
|
|
88f331 |
- value = g_variant_parse (type, printed, NULL, NULL, NULL);
|
|
|
88f331 |
- g_free (printed);
|
|
|
88f331 |
-
|
|
|
88f331 |
- if (value != NULL)
|
|
|
88f331 |
- return value;
|
|
|
88f331 |
- }
|
|
|
88f331 |
-
|
|
|
88f331 |
- /* If that didn't work, try for a default value annotation */
|
|
|
88f331 |
- for (i = 0; property->annotations && property->annotations[i]; i++) {
|
|
|
88f331 |
- GDBusAnnotationInfo *annotation = property->annotations[i];
|
|
|
88f331 |
-
|
|
|
88f331 |
- if (g_str_equal (annotation->key, "org.freedesktop.Accounts.DefaultValue.String")) {
|
|
|
88f331 |
- if (g_str_equal (property->signature, "s"))
|
|
|
88f331 |
- return g_variant_ref_sink (g_variant_new_string (annotation->value));
|
|
|
88f331 |
- }
|
|
|
88f331 |
- else if (g_str_equal (annotation->key, "org.freedesktop.Accounts.DefaultValue")) {
|
|
|
88f331 |
- value = g_variant_parse (type, annotation->value, NULL, NULL, NULL);
|
|
|
88f331 |
- if (value != NULL)
|
|
|
88f331 |
- return value;
|
|
|
88f331 |
- }
|
|
|
88f331 |
- }
|
|
|
88f331 |
-
|
|
|
88f331 |
- /* Nothing found... */
|
|
|
88f331 |
- return NULL;
|
|
|
88f331 |
-}
|
|
|
88f331 |
-
|
|
|
88f331 |
-static void
|
|
|
88f331 |
-user_extension_get_property (User *user,
|
|
|
88f331 |
- Daemon *daemon,
|
|
|
88f331 |
- GDBusInterfaceInfo *interface,
|
|
|
88f331 |
- GDBusMethodInvocation *invocation)
|
|
|
88f331 |
-{
|
|
|
88f331 |
- const GDBusPropertyInfo *property = g_dbus_method_invocation_get_property_info (invocation);
|
|
|
88f331 |
- GVariant *value;
|
|
|
88f331 |
-
|
|
|
88f331 |
- value = user_extension_get_value (user, interface, property);
|
|
|
88f331 |
-
|
|
|
88f331 |
- if (value) {
|
|
|
88f331 |
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("(v)", value));
|
|
|
88f331 |
- g_variant_unref (value);
|
|
|
88f331 |
- }
|
|
|
88f331 |
- else {
|
|
|
88f331 |
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
|
|
|
88f331 |
- "Key '%s' is not set and has no default value",
|
|
|
88f331 |
- property->name);
|
|
|
88f331 |
- }
|
|
|
88f331 |
-}
|
|
|
88f331 |
-
|
|
|
88f331 |
-static void
|
|
|
88f331 |
-user_extension_get_all_properties (User *user,
|
|
|
88f331 |
- Daemon *daemon,
|
|
|
88f331 |
- GDBusInterfaceInfo *interface,
|
|
|
88f331 |
- GDBusMethodInvocation *invocation)
|
|
|
88f331 |
-{
|
|
|
88f331 |
- GVariantBuilder builder;
|
|
|
88f331 |
- gint i;
|
|
|
88f331 |
-
|
|
|
88f331 |
- g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
|
|
88f331 |
- for (i = 0; interface->properties && interface->properties[i]; i++) {
|
|
|
88f331 |
- GDBusPropertyInfo *property = interface->properties[i];
|
|
|
88f331 |
- GVariant *value;
|
|
|
88f331 |
-
|
|
|
88f331 |
- value = user_extension_get_value (user, interface, property);
|
|
|
88f331 |
-
|
|
|
88f331 |
- if (value) {
|
|
|
88f331 |
- g_variant_builder_add (&builder, "{sv}", property->name, value);
|
|
|
88f331 |
- g_variant_unref (value);
|
|
|
88f331 |
- }
|
|
|
88f331 |
- }
|
|
|
88f331 |
-
|
|
|
88f331 |
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{sv})", &builder));
|
|
|
88f331 |
-}
|
|
|
88f331 |
-
|
|
|
88f331 |
-static void
|
|
|
88f331 |
-user_extension_set_property (User *user,
|
|
|
88f331 |
- Daemon *daemon,
|
|
|
88f331 |
- GDBusInterfaceInfo *interface,
|
|
|
88f331 |
- GDBusMethodInvocation *invocation)
|
|
|
88f331 |
-{
|
|
|
88f331 |
- const GDBusPropertyInfo *property = g_dbus_method_invocation_get_property_info (invocation);
|
|
|
88f331 |
- GVariant *value;
|
|
|
88f331 |
- gchar *printed;
|
|
|
88f331 |
- gchar *prev;
|
|
|
88f331 |
-
|
|
|
88f331 |
- g_variant_get_child (g_dbus_method_invocation_get_parameters (invocation), 2, "v", &value);
|
|
|
88f331 |
-
|
|
|
88f331 |
- /* We'll always have the type when we parse it back so
|
|
|
88f331 |
- * we don't need it to be printed with annotations.
|
|
|
88f331 |
- */
|
|
|
88f331 |
- printed = g_variant_print (value, FALSE);
|
|
|
88f331 |
-
|
|
|
88f331 |
- /* May as well try to avoid the thrashing... */
|
|
|
88f331 |
- prev = g_key_file_get_value (user->keyfile, interface->name, property->name, NULL);
|
|
|
88f331 |
-
|
|
|
88f331 |
- if (!prev || !g_str_equal (printed, prev)) {
|
|
|
88f331 |
- g_key_file_set_value (user->keyfile, interface->name, property->name, printed);
|
|
|
88f331 |
-
|
|
|
88f331 |
- /* Emit a change signal. Use invalidation
|
|
|
88f331 |
- * because the data may not be world-readable.
|
|
|
88f331 |
- */
|
|
|
88f331 |
- g_dbus_connection_emit_signal (g_dbus_method_invocation_get_connection (invocation),
|
|
|
88f331 |
- NULL, /* destination_bus_name */
|
|
|
88f331 |
- g_dbus_method_invocation_get_object_path (invocation),
|
|
|
88f331 |
- "org.freedesktop.DBus.Properties", "PropertiesChanged",
|
|
|
88f331 |
- g_variant_new_parsed ("( %s, %a{sv}, [ %s ] )",
|
|
|
88f331 |
- interface->name, NULL, property->name),
|
|
|
88f331 |
- NULL);
|
|
|
88f331 |
-
|
|
|
88f331 |
- accounts_user_emit_changed (ACCOUNTS_USER (user));
|
|
|
88f331 |
- save_extra_data (user);
|
|
|
88f331 |
- }
|
|
|
88f331 |
-
|
|
|
88f331 |
- g_variant_unref (value);
|
|
|
88f331 |
- g_free (printed);
|
|
|
88f331 |
- g_free (prev);
|
|
|
88f331 |
-
|
|
|
88f331 |
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
|
|
|
88f331 |
-}
|
|
|
88f331 |
-
|
|
|
88f331 |
-static void
|
|
|
88f331 |
-user_extension_authentication_done (Daemon *daemon,
|
|
|
88f331 |
- User *user,
|
|
|
88f331 |
- GDBusMethodInvocation *invocation,
|
|
|
88f331 |
- gpointer user_data)
|
|
|
88f331 |
-{
|
|
|
88f331 |
- GDBusInterfaceInfo *interface = user_data;
|
|
|
88f331 |
- const gchar *method_name;
|
|
|
88f331 |
-
|
|
|
88f331 |
- method_name = g_dbus_method_invocation_get_method_name (invocation);
|
|
|
88f331 |
-
|
|
|
88f331 |
- if (g_str_equal (method_name, "Get"))
|
|
|
88f331 |
- user_extension_get_property (user, daemon, interface, invocation);
|
|
|
88f331 |
- else if (g_str_equal (method_name, "GetAll"))
|
|
|
88f331 |
- user_extension_get_all_properties (user, daemon, interface, invocation);
|
|
|
88f331 |
- else if (g_str_equal (method_name, "Set"))
|
|
|
88f331 |
- user_extension_set_property (user, daemon, interface, invocation);
|
|
|
88f331 |
- else
|
|
|
88f331 |
- g_assert_not_reached ();
|
|
|
88f331 |
-}
|
|
|
88f331 |
-
|
|
|
88f331 |
-static void
|
|
|
88f331 |
-user_extension_method_call (GDBusConnection *connection,
|
|
|
88f331 |
- const gchar *sender,
|
|
|
88f331 |
- const gchar *object_path,
|
|
|
88f331 |
- const gchar *interface_name,
|
|
|
88f331 |
- const gchar *method_name,
|
|
|
88f331 |
- GVariant *parameters,
|
|
|
88f331 |
- GDBusMethodInvocation *invocation,
|
|
|
88f331 |
- gpointer user_data)
|
|
|
88f331 |
-{
|
|
|
88f331 |
- User *user = user_data;
|
|
|
88f331 |
- GDBusInterfaceInfo *iface_info;
|
|
|
88f331 |
- const gchar *annotation_name;
|
|
|
88f331 |
- const gchar *action_id;
|
|
|
88f331 |
- gint uid;
|
|
|
88f331 |
- gint i;
|
|
|
88f331 |
-
|
|
|
88f331 |
- /* We don't allow method calls on extension interfaces, so we
|
|
|
88f331 |
- * should only ever see property calls here.
|
|
|
88f331 |
- */
|
|
|
88f331 |
- g_assert_cmpstr (interface_name, ==, "org.freedesktop.DBus.Properties");
|
|
|
88f331 |
-
|
|
|
88f331 |
- /* Now get the real interface name */
|
|
|
88f331 |
- g_variant_get_child (parameters, 0, "&s", &interface_name);
|
|
|
88f331 |
-
|
|
|
88f331 |
- if (get_caller_uid (invocation, &uid) && (uid_t) uid == user->uid) {
|
|
|
88f331 |
- /* Operation on sender's own User object */
|
|
|
88f331 |
- if (g_str_equal (method_name, "Set")) {
|
|
|
88f331 |
- annotation_name = "org.freedesktop.Accounts.Authentication.ChangeOwn";
|
|
|
88f331 |
- action_id = "org.freedesktop.accounts.change-own-user-data";
|
|
|
88f331 |
- }
|
|
|
88f331 |
- else {
|
|
|
88f331 |
- annotation_name = "org.freedesktop.Accounts.Authentication.ReadOwn";
|
|
|
88f331 |
- action_id = ""; /* reading allowed by default */
|
|
|
88f331 |
- }
|
|
|
88f331 |
- }
|
|
|
88f331 |
- else {
|
|
|
88f331 |
- /* Operation on someone else's User object */
|
|
|
88f331 |
- if (g_str_equal (method_name, "Set")) {
|
|
|
88f331 |
- annotation_name = "org.freedesktop.Accounts.Authentication.ChangeAny";
|
|
|
88f331 |
- action_id = "org.freedesktop.accounts.user-administration";
|
|
|
88f331 |
- }
|
|
|
88f331 |
- else {
|
|
|
88f331 |
- annotation_name = "org.freedesktop.Accounts.Authentication.ReadAny";
|
|
|
88f331 |
- action_id = ""; /* reading allowed by default */
|
|
|
88f331 |
- }
|
|
|
88f331 |
- }
|
|
|
88f331 |
-
|
|
|
88f331 |
- iface_info = g_hash_table_lookup (daemon_get_extension_ifaces (user->daemon), interface_name);
|
|
|
88f331 |
- g_assert (iface_info != NULL);
|
|
|
88f331 |
-
|
|
|
88f331 |
- for (i = 0; iface_info->annotations && iface_info->annotations[i]; i++) {
|
|
|
88f331 |
- if (g_str_equal (iface_info->annotations[i]->key, annotation_name)) {
|
|
|
88f331 |
- action_id = iface_info->annotations[i]->value;
|
|
|
88f331 |
- break;
|
|
|
88f331 |
- }
|
|
|
88f331 |
- }
|
|
|
88f331 |
-
|
|
|
88f331 |
- if (action_id[0] == '\0') {
|
|
|
88f331 |
- /* Should always allow this call, so just do it now */
|
|
|
88f331 |
- user_extension_authentication_done (user->daemon, user, invocation, iface_info);
|
|
|
88f331 |
- }
|
|
|
88f331 |
- else {
|
|
|
88f331 |
- daemon_local_check_auth (user->daemon, user, action_id, TRUE,
|
|
|
88f331 |
- user_extension_authentication_done,
|
|
|
88f331 |
- invocation, iface_info, NULL);
|
|
|
88f331 |
- }
|
|
|
88f331 |
-}
|
|
|
88f331 |
-
|
|
|
88f331 |
-static void
|
|
|
88f331 |
-user_register_extensions (User *user)
|
|
|
88f331 |
-{
|
|
|
88f331 |
- static const GDBusInterfaceVTable vtable = {
|
|
|
88f331 |
- user_extension_method_call,
|
|
|
88f331 |
- NULL /* get_property */,
|
|
|
88f331 |
- NULL /* set_property */
|
|
|
88f331 |
- };
|
|
|
88f331 |
- GHashTable *extensions;
|
|
|
88f331 |
- GHashTableIter iter;
|
|
|
88f331 |
- gpointer iface;
|
|
|
88f331 |
- gint i = 0;
|
|
|
88f331 |
-
|
|
|
88f331 |
- g_assert (user->extension_ids == NULL);
|
|
|
88f331 |
- g_assert (user->n_extension_ids == 0);
|
|
|
88f331 |
-
|
|
|
88f331 |
- extensions = daemon_get_extension_ifaces (user->daemon);
|
|
|
88f331 |
- user->n_extension_ids = g_hash_table_size (extensions);
|
|
|
88f331 |
- user->extension_ids = g_new (guint, user->n_extension_ids);
|
|
|
88f331 |
- g_hash_table_iter_init (&iter, extensions);
|
|
|
88f331 |
-
|
|
|
88f331 |
- /* Ignore errors when registering more interfaces because (a)
|
|
|
88f331 |
- * they won't happen and (b) even if they do, we still want to
|
|
|
88f331 |
- * publish the main user interface.
|
|
|
88f331 |
- */
|
|
|
88f331 |
- while (g_hash_table_iter_next (&iter, NULL, &iface))
|
|
|
88f331 |
- user->extension_ids[i++] = g_dbus_connection_register_object (user->system_bus_connection,
|
|
|
88f331 |
- user->object_path, iface,
|
|
|
88f331 |
- &vtable, user, NULL, NULL);
|
|
|
88f331 |
-}
|
|
|
88f331 |
-
|
|
|
88f331 |
static gchar *
|
|
|
88f331 |
compute_object_path (User *user)
|
|
|
88f331 |
{
|
|
|
88f331 |
gchar *object_path;
|
|
|
88f331 |
|
|
|
88f331 |
object_path = g_strdup_printf ("/org/freedesktop/Accounts/User%ld",
|
|
|
88f331 |
(long) user->uid);
|
|
|
88f331 |
|
|
|
88f331 |
return object_path;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
void
|
|
|
88f331 |
user_register (User *user)
|
|
|
88f331 |
{
|
|
|
88f331 |
GError *error = NULL;
|
|
|
88f331 |
|
|
|
88f331 |
user->system_bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
|
|
|
88f331 |
if (user->system_bus_connection == NULL) {
|
|
|
88f331 |
if (error != NULL) {
|
|
|
88f331 |
g_critical ("error getting system bus: %s", error->message);
|
|
|
88f331 |
g_error_free (error);
|
|
|
88f331 |
}
|
|
|
88f331 |
return;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
user->object_path = compute_object_path (user);
|
|
|
88f331 |
|
|
|
88f331 |
if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (user),
|
|
|
88f331 |
user->system_bus_connection,
|
|
|
88f331 |
user->object_path,
|
|
|
88f331 |
&error)) {
|
|
|
88f331 |
if (error != NULL) {
|
|
|
88f331 |
g_critical ("error exporting user object: %s", error->message);
|
|
|
88f331 |
g_error_free (error);
|
|
|
88f331 |
}
|
|
|
88f331 |
return;
|
|
|
88f331 |
}
|
|
|
88f331 |
-
|
|
|
88f331 |
- user_register_extensions (user);
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
void
|
|
|
88f331 |
user_save (User *user)
|
|
|
88f331 |
{
|
|
|
88f331 |
save_extra_data (user);
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
void
|
|
|
88f331 |
user_unregister (User *user)
|
|
|
88f331 |
{
|
|
|
88f331 |
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (user));
|
|
|
88f331 |
-
|
|
|
88f331 |
- if (user->extension_ids) {
|
|
|
88f331 |
- guint i;
|
|
|
88f331 |
-
|
|
|
88f331 |
- for (i = 0; i < user->n_extension_ids; i++) {
|
|
|
88f331 |
- /* In theory, if an error happened during registration, we could have 0 here. */
|
|
|
88f331 |
- if (user->extension_ids[i] == 0)
|
|
|
88f331 |
- continue;
|
|
|
88f331 |
-
|
|
|
88f331 |
- g_dbus_connection_unregister_object (user->system_bus_connection, user->extension_ids[i]);
|
|
|
88f331 |
- }
|
|
|
88f331 |
-
|
|
|
88f331 |
- g_clear_pointer (&user->extension_ids, g_free);
|
|
|
88f331 |
- user->n_extension_ids = 0;
|
|
|
88f331 |
- }
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
void
|
|
|
88f331 |
user_changed (User *user)
|
|
|
88f331 |
{
|
|
|
88f331 |
accounts_user_emit_changed (ACCOUNTS_USER (user));
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
User *
|
|
|
88f331 |
user_new (Daemon *daemon,
|
|
|
88f331 |
uid_t uid)
|
|
|
88f331 |
{
|
|
|
88f331 |
User *user;
|
|
|
88f331 |
|
|
|
88f331 |
user = g_object_new (TYPE_USER, NULL);
|
|
|
88f331 |
user->daemon = daemon;
|
|
|
88f331 |
user->uid = uid;
|
|
|
88f331 |
|
|
|
88f331 |
return user;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
const gchar *
|
|
|
88f331 |
user_get_user_name (User *user)
|
|
|
88f331 |
{
|
|
|
88f331 |
return user->user_name;
|
|
|
88f331 |
}
|
|
|
88f331 |
|
|
|
88f331 |
gboolean
|
|
|
88f331 |
user_get_system_account (User *user)
|
|
|
88f331 |
{
|
|
|
88f331 |
--
|
|
|
88f331 |
1.8.3.1
|
|
|
88f331 |
|