845 lines
30 KiB
Diff
845 lines
30 KiB
Diff
From 4ff9bc526fec4be51f42739b4258529d7e4695a1 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 12 Oct 2018 15:53:52 -0400
|
|
Subject: [PATCH] lib: save os when creating user
|
|
|
|
In order to identify that a user has upgraded from rhel 7 to
|
|
rhel 8, we need to know what os they were using when created.
|
|
|
|
This commit saves that information using a red hat specific
|
|
extension to accountsservice.
|
|
---
|
|
data/Makefile.am | 14 +-
|
|
.../com.redhat.AccountsServiceUser.System.xml | 10 ++
|
|
src/libaccountsservice/Makefile.am | 12 +-
|
|
src/libaccountsservice/act-user-manager.c | 123 ++++++++++++++++++
|
|
4 files changed, 157 insertions(+), 2 deletions(-)
|
|
create mode 100644 data/com.redhat.AccountsServiceUser.System.xml
|
|
|
|
diff --git a/data/Makefile.am b/data/Makefile.am
|
|
index 521c6c2..a441452 100644
|
|
--- a/data/Makefile.am
|
|
+++ b/data/Makefile.am
|
|
@@ -1,44 +1,56 @@
|
|
|
|
dbusifdir = $(datadir)/dbus-1/interfaces
|
|
dbusif_DATA = \
|
|
org.freedesktop.Accounts.xml \
|
|
- org.freedesktop.Accounts.User.xml
|
|
+ org.freedesktop.Accounts.User.xml \
|
|
+ com.redhat.AccountsServiceUser.System.xml
|
|
|
|
dbusconfdir = $(sysconfdir)/dbus-1/system.d
|
|
dbusconf_DATA = org.freedesktop.Accounts.conf
|
|
|
|
+accountsserviceifdir = $(datadir)/accountsservice/interfaces
|
|
+
|
|
servicedir = $(datadir)/dbus-1/system-services
|
|
service_in_files = org.freedesktop.Accounts.service.in
|
|
service_DATA = $(service_in_files:.service.in=.service)
|
|
|
|
$(service_DATA): $(service_in_files) Makefile
|
|
@sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@
|
|
|
|
policydir = $(datadir)/polkit-1/actions
|
|
policy_in_files = org.freedesktop.accounts.policy.in
|
|
policy_DATA = $(policy_in_files:.policy.in=.policy)
|
|
|
|
@INTLTOOL_POLICY_RULE@
|
|
|
|
if HAVE_SYSTEMD
|
|
systemdsystemunit_DATA = \
|
|
accounts-daemon.service
|
|
|
|
accounts-daemon.service: accounts-daemon.service.in
|
|
@sed -e "s|\@libexecdir\@|$(libexecdir)|" $< >$@
|
|
|
|
endif
|
|
|
|
EXTRA_DIST = \
|
|
$(dbusif_DATA) \
|
|
$(dbusconf_DATA) \
|
|
$(service_in_files) \
|
|
$(policy_in_files) \
|
|
accounts-daemon.service.in
|
|
|
|
DISTCLEANFILES = \
|
|
$(service_DATA) \
|
|
$(policy_DATA)
|
|
|
|
CLEANFILES = \
|
|
accounts-daemon.service
|
|
+
|
|
+install-data-hook: com.redhat.AccountsServiceUser.System.xml
|
|
+ if test '!' -d $(DESTDIR)$(accountsserviceifdir); then \
|
|
+ $(mkinstalldirs) $(DESTDIR)$(accountsserviceifdir); \
|
|
+ chmod 755 $(DESTDIR)$(accountsserviceifdir); \
|
|
+ fi
|
|
+ if test '!' -L $(DESTDIR)$(accountsserviceifdir)/com.redhat.AccountsServiceUser.System.xml; then \
|
|
+ (cd $(DESTDIR)$(accountsserviceifdir); $(LN_S) ../../dbus-1/interfaces/com.redhat.AccountsServiceUser.System.xml) \
|
|
+ fi
|
|
diff --git a/data/com.redhat.AccountsServiceUser.System.xml b/data/com.redhat.AccountsServiceUser.System.xml
|
|
new file mode 100644
|
|
index 0000000..67f5f30
|
|
--- /dev/null
|
|
+++ b/data/com.redhat.AccountsServiceUser.System.xml
|
|
@@ -0,0 +1,10 @@
|
|
+<node>
|
|
+ <interface name="com.redhat.AccountsServiceUser.System">
|
|
+
|
|
+ <annotation name="org.freedesktop.Accounts.VendorExtension" value="true"/>
|
|
+
|
|
+ <property name="id" type="s" access="readwrite"/>
|
|
+ <property name="version-id" type="s" access="readwrite"/>
|
|
+
|
|
+ </interface>
|
|
+</node>
|
|
diff --git a/src/libaccountsservice/Makefile.am b/src/libaccountsservice/Makefile.am
|
|
index 408d91f..d711d65 100644
|
|
--- a/src/libaccountsservice/Makefile.am
|
|
+++ b/src/libaccountsservice/Makefile.am
|
|
@@ -20,69 +20,79 @@ act-user-enum-types.h: act-user.h act-user-manager.h
|
|
$(AM_V_GEN) (cd $(srcdir) && \
|
|
glib-mkenums \
|
|
--fhead "#ifndef __ACT_USER_ENUM_TYPES_H__\n#define __ACT_USER_ENUM_TYPES_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
|
|
--fprod "/* enumerations from \"@filename@\" */\n" \
|
|
--vhead "GType @enum_name@_get_type (void);\n#define ACT_USER_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
|
|
--ftail "G_END_DECLS\n\n#endif /* __ACT_USER_ENUM_TYPES_H__ */" \
|
|
$(^F) ) > $@
|
|
|
|
act-user-enum-types.c: act-user.h act-user-manager.h act-user-enum-types.h
|
|
$(AM_V_GEN) (cd $(srcdir) && \
|
|
glib-mkenums \
|
|
--fhead "#include \"act-user.h\"\n" \
|
|
--fhead "#include \"act-user-manager.h\"\n" \
|
|
--fhead "#include \"act-user-enum-types.h\"\n" \
|
|
--fhead "#include <glib-object.h>" \
|
|
--fprod "\n/* enumerations from \"@filename@\" */" \
|
|
--vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \
|
|
--vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
|
|
--vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \
|
|
$(^F) ) > $@
|
|
|
|
ck-manager-generated.c ck-manager-generated.h: org.freedesktop.ConsoleKit.Manager.xml Makefile
|
|
$(AM_V_GEN) gdbus-codegen --generate-c-code ck-manager-generated --c-namespace ConsoleKit --interface-prefix=org.freedesktop.ConsoleKit $(srcdir)/org.freedesktop.ConsoleKit.Manager.xml
|
|
|
|
ck-seat-generated.c ck-seat-generated.h: org.freedesktop.ConsoleKit.Seat.xml Makefile
|
|
$(AM_V_GEN) gdbus-codegen --generate-c-code ck-seat-generated --c-namespace ConsoleKit --interface-prefix=org.freedesktop.ConsoleKit $(srcdir)/org.freedesktop.ConsoleKit.Seat.xml
|
|
|
|
ck-session-generated.c ck-session-generated.h: org.freedesktop.ConsoleKit.Session.xml Makefile
|
|
$(AM_V_GEN) gdbus-codegen --generate-c-code ck-session-generated --c-namespace ConsoleKit --interface-prefix=org.freedesktop.ConsoleKit $(srcdir)/org.freedesktop.ConsoleKit.Session.xml
|
|
|
|
+com.redhat.AccountsServiceUser.System.c com.redhat.AccountsServiceUser.System.h: $(top_srcdir)/data/com.redhat.AccountsServiceUser.System.xml Makefile
|
|
+ $(AM_V_GEN)gdbus-codegen \
|
|
+ --c-namespace=Act \
|
|
+ --interface-prefix=com.redhat.AccountsService \
|
|
+ --generate-c-code=com.redhat.AccountsServiceUser.System \
|
|
+ $(top_srcdir)/data/com.redhat.AccountsServiceUser.System.xml
|
|
+
|
|
+
|
|
BUILT_SOURCES += \
|
|
act-user-enum-types.c \
|
|
act-user-enum-types.h \
|
|
ck-manager-generated.c \
|
|
ck-manager-generated.h \
|
|
ck-seat-generated.c \
|
|
ck-seat-generated.h \
|
|
ck-session-generated.c \
|
|
- ck-session-generated.h
|
|
+ ck-session-generated.h \
|
|
+ com.redhat.AccountsServiceUser.System.h \
|
|
+ com.redhat.AccountsServiceUser.System.c
|
|
|
|
CLEANFILES += $(BUILT_SOURCES)
|
|
|
|
libaccountsservicedir = $(includedir)/accountsservice-1.0/act
|
|
libaccountsservice_headers = \
|
|
act-user.h \
|
|
act-user-manager.h \
|
|
act-user-enum-types.h \
|
|
$(END_OF_LIST)
|
|
|
|
libaccountsservice_HEADERS = \
|
|
act.h \
|
|
$(libaccountsservice_headers) \
|
|
$(END_OF_LIST)
|
|
|
|
|
|
libaccountsservice_la_CFLAGS = $(LIBACCOUNTSSERVICE_CFLAGS)
|
|
libaccountsservice_la_LDFLAGS = \
|
|
-export-symbols-regex '^[^_].*' \
|
|
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
|
|
-no-undefined \
|
|
$(END_OF_LIST)
|
|
|
|
libaccountsservice_la_LIBADD = \
|
|
../libaccounts-generated.la \
|
|
$(LIBACCOUNTSSERVICE_LIBS) \
|
|
-lcrypt \
|
|
$(END_OF_LIST)
|
|
|
|
libaccountsservice_la_sources = \
|
|
diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c
|
|
index 325421b..091b46a 100644
|
|
--- a/src/libaccountsservice/act-user-manager.c
|
|
+++ b/src/libaccountsservice/act-user-manager.c
|
|
@@ -27,60 +27,61 @@
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <errno.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
|
|
#ifdef HAVE_PATHS_H
|
|
#include <paths.h>
|
|
#endif /* HAVE_PATHS_H */
|
|
|
|
#include <glib.h>
|
|
#include <glib/gi18n-lib.h>
|
|
#include <glib/gstdio.h>
|
|
#include <glib-object.h>
|
|
#include <gio/gio.h>
|
|
#include <gio/gunixinputstream.h>
|
|
|
|
#ifdef WITH_SYSTEMD
|
|
#include <systemd/sd-login.h>
|
|
|
|
/* check if logind is running */
|
|
#define LOGIND_RUNNING() (access("/run/systemd/seats/", F_OK) >= 0)
|
|
#endif
|
|
|
|
#include "act-user-manager.h"
|
|
#include "act-user-private.h"
|
|
#include "accounts-generated.h"
|
|
#include "ck-manager-generated.h"
|
|
#include "ck-seat-generated.h"
|
|
#include "ck-session-generated.h"
|
|
+#include "com.redhat.AccountsServiceUser.System.h"
|
|
|
|
/**
|
|
* SECTION:act-user-manager
|
|
* @title: ActUserManager
|
|
* @short_description: manages ActUser objects
|
|
*
|
|
* ActUserManager is a manager object that gives access to user
|
|
* creation, deletion, enumeration, etc.
|
|
*
|
|
* There is typically a singleton ActUserManager object, which
|
|
* can be obtained by act_user_manager_get_default().
|
|
*/
|
|
|
|
/**
|
|
* ActUserManager:
|
|
*
|
|
* A user manager object.
|
|
*/
|
|
|
|
/**
|
|
* ACT_USER_MANAGER_ERROR:
|
|
*
|
|
* The GError domain for #ActUserManagerError errors
|
|
*/
|
|
|
|
/**
|
|
* ActUserManagerError:
|
|
* @ACT_USER_MANAGER_ERROR_FAILED: Generic failure
|
|
* @ACT_USER_MANAGER_ERROR_USER_EXISTS: The user already exists
|
|
* @ACT_USER_MANAGER_ERROR_USER_DOES_NOT_EXIST: The user does not exist
|
|
@@ -167,60 +168,63 @@ typedef struct
|
|
ActUser *user;
|
|
ActUserManagerFetchUserRequestType type;
|
|
union {
|
|
char *username;
|
|
uid_t uid;
|
|
};
|
|
char *object_path;
|
|
char *description;
|
|
} ActUserManagerFetchUserRequest;
|
|
|
|
struct ActUserManagerPrivate
|
|
{
|
|
GHashTable *normal_users_by_name;
|
|
GHashTable *system_users_by_name;
|
|
GHashTable *users_by_object_path;
|
|
GHashTable *sessions;
|
|
GDBusConnection *connection;
|
|
AccountsAccounts *accounts_proxy;
|
|
ConsoleKitManager *ck_manager_proxy;
|
|
|
|
ActUserManagerSeat seat;
|
|
|
|
GSList *new_sessions;
|
|
GSList *new_users;
|
|
GSList *new_users_inhibiting_load;
|
|
GSList *fetch_user_requests;
|
|
|
|
GSList *exclude_usernames;
|
|
GSList *include_usernames;
|
|
|
|
+ char *os_id;
|
|
+ char *os_version_id;
|
|
+
|
|
guint load_id;
|
|
|
|
gboolean is_loaded;
|
|
gboolean has_multiple_users;
|
|
gboolean getting_sessions;
|
|
gboolean list_cached_users_done;
|
|
};
|
|
|
|
enum {
|
|
PROP_0,
|
|
PROP_INCLUDE_USERNAMES_LIST,
|
|
PROP_EXCLUDE_USERNAMES_LIST,
|
|
PROP_IS_LOADED,
|
|
PROP_HAS_MULTIPLE_USERS
|
|
};
|
|
|
|
enum {
|
|
USER_ADDED,
|
|
USER_REMOVED,
|
|
USER_IS_LOGGED_IN_CHANGED,
|
|
USER_CHANGED,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
static guint signals [LAST_SIGNAL] = { 0, };
|
|
|
|
static void act_user_manager_class_init (ActUserManagerClass *klass);
|
|
static void act_user_manager_init (ActUserManager *user_manager);
|
|
static void act_user_manager_finalize (GObject *object);
|
|
|
|
@@ -2763,101 +2767,174 @@ ensure_accounts_proxy (ActUserManager *manager)
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
ACCOUNTS_NAME,
|
|
ACCOUNTS_PATH,
|
|
NULL,
|
|
&error);
|
|
if (error != NULL) {
|
|
g_debug ("ActUserManager: getting account proxy failed: %s", error->message);
|
|
return FALSE;
|
|
}
|
|
|
|
g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (manager->priv->accounts_proxy), G_MAXINT);
|
|
|
|
g_object_bind_property (G_OBJECT (manager->priv->accounts_proxy),
|
|
"has-multiple-users",
|
|
G_OBJECT (manager),
|
|
"has-multiple-users",
|
|
G_BINDING_SYNC_CREATE);
|
|
|
|
g_signal_connect (manager->priv->accounts_proxy,
|
|
"user-added",
|
|
G_CALLBACK (on_new_user_in_accounts_service),
|
|
manager);
|
|
g_signal_connect (manager->priv->accounts_proxy,
|
|
"user-deleted",
|
|
G_CALLBACK (on_user_removed_in_accounts_service),
|
|
manager);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
+static inline gboolean
|
|
+is_valid_char (gchar c,
|
|
+ gboolean first)
|
|
+{
|
|
+ return (!first && g_ascii_isdigit (c)) ||
|
|
+ c == '_' ||
|
|
+ g_ascii_isalpha (c);
|
|
+}
|
|
+
|
|
+static void
|
|
+load_os_release (ActUserManager *manager)
|
|
+{
|
|
+ ActUserManagerPrivate *priv = manager->priv;
|
|
+ g_autoptr(GFile) file = NULL;
|
|
+ g_autoptr(GError) error = NULL;
|
|
+ g_autofree char *contents = NULL;
|
|
+ g_auto(GStrv) lines = NULL;
|
|
+ size_t i;
|
|
+
|
|
+ file = g_file_new_for_path ("/etc/os-release");
|
|
+
|
|
+ if (!g_file_load_contents (file, NULL, &contents, NULL, NULL, &error)) {
|
|
+ g_debug ("ActUserManager: couldn't load /etc/os-release: %s", error->message);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ lines = g_strsplit (contents, "\n", -1);
|
|
+ for (i = 0; lines[i] != NULL; i++) {
|
|
+ char *p, *name, *name_end, *value, *value_end;
|
|
+
|
|
+ p = lines[i];
|
|
+
|
|
+ while (g_ascii_isspace (*p))
|
|
+ p++;
|
|
+
|
|
+ if (*p == '#' || *p == '\0')
|
|
+ continue;
|
|
+ name = p;
|
|
+ while (is_valid_char (*p, p == name))
|
|
+ p++;
|
|
+ name_end = p;
|
|
+ while (g_ascii_isspace (*p))
|
|
+ p++;
|
|
+ if (name == name_end || *p != '=') {
|
|
+ continue;
|
|
+ }
|
|
+ *name_end = '\0';
|
|
+
|
|
+ p++;
|
|
+
|
|
+ while (g_ascii_isspace (*p))
|
|
+ p++;
|
|
+
|
|
+ value = p;
|
|
+ value_end = value + strlen (value) - 1;
|
|
+
|
|
+ if (value != value_end && *value == '"' && *value_end == '"') {
|
|
+ value++;
|
|
+ *value_end = '\0';
|
|
+ }
|
|
+
|
|
+ if (strcmp (name, "ID") == 0) {
|
|
+ g_debug ("ActUserManager: system OS is '%s'", value);
|
|
+ priv->os_id = g_strdup (value);
|
|
+ } else if (strcmp (name, "VERSION_ID") == 0) {
|
|
+ g_debug ("ActUserManager: system OS version is '%s'", value);
|
|
+ priv->os_version_id = g_strdup (value);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
static void
|
|
act_user_manager_init (ActUserManager *manager)
|
|
{
|
|
g_autoptr(GError) error = NULL;
|
|
|
|
manager->priv = ACT_USER_MANAGER_GET_PRIVATE (manager);
|
|
|
|
act_user_manager_error_quark (); /* register dbus errors */
|
|
|
|
/* sessions */
|
|
manager->priv->sessions = g_hash_table_new_full (g_str_hash,
|
|
g_str_equal,
|
|
g_free,
|
|
g_object_unref);
|
|
|
|
/* users */
|
|
manager->priv->normal_users_by_name = g_hash_table_new_full (g_str_hash,
|
|
g_str_equal,
|
|
g_free,
|
|
g_object_unref);
|
|
manager->priv->system_users_by_name = g_hash_table_new_full (g_str_hash,
|
|
g_str_equal,
|
|
g_free,
|
|
g_object_unref);
|
|
manager->priv->users_by_object_path = g_hash_table_new_full (g_str_hash,
|
|
g_str_equal,
|
|
NULL,
|
|
g_object_unref);
|
|
|
|
manager->priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
|
|
if (manager->priv->connection == NULL) {
|
|
if (error != NULL) {
|
|
g_warning ("Failed to connect to the D-Bus daemon: %s", error->message);
|
|
} else {
|
|
g_warning ("Failed to connect to the D-Bus daemon");
|
|
}
|
|
return;
|
|
}
|
|
|
|
ensure_accounts_proxy (manager);
|
|
|
|
+ load_os_release (manager);
|
|
+
|
|
manager->priv->seat.state = ACT_USER_MANAGER_SEAT_STATE_UNLOADED;
|
|
}
|
|
|
|
static void
|
|
act_user_manager_finalize (GObject *object)
|
|
{
|
|
ActUserManager *manager;
|
|
GSList *node;
|
|
|
|
g_debug ("ActUserManager: finalizing user manager");
|
|
|
|
g_return_if_fail (object != NULL);
|
|
g_return_if_fail (ACT_IS_USER_MANAGER (object));
|
|
|
|
manager = ACT_USER_MANAGER (object);
|
|
|
|
g_return_if_fail (manager->priv != NULL);
|
|
|
|
g_slist_foreach (manager->priv->new_sessions,
|
|
(GFunc) unload_new_session, NULL);
|
|
g_slist_free (manager->priv->new_sessions);
|
|
|
|
g_slist_foreach (manager->priv->fetch_user_requests,
|
|
(GFunc) free_fetch_user_request, NULL);
|
|
g_slist_free (manager->priv->fetch_user_requests);
|
|
|
|
g_slist_free (manager->priv->new_users_inhibiting_load);
|
|
|
|
node = manager->priv->new_users;
|
|
while (node != NULL) {
|
|
@@ -2899,141 +2976,179 @@ act_user_manager_finalize (GObject *object)
|
|
|
|
#ifdef WITH_SYSTEMD
|
|
if (manager->priv->seat.session_monitor != NULL) {
|
|
sd_login_monitor_unref (manager->priv->seat.session_monitor);
|
|
}
|
|
|
|
if (manager->priv->seat.session_monitor_stream != NULL) {
|
|
g_object_unref (manager->priv->seat.session_monitor_stream);
|
|
}
|
|
|
|
if (manager->priv->seat.session_monitor_source_id != 0) {
|
|
g_source_remove (manager->priv->seat.session_monitor_source_id);
|
|
}
|
|
#endif
|
|
|
|
if (manager->priv->accounts_proxy != NULL) {
|
|
g_object_unref (manager->priv->accounts_proxy);
|
|
}
|
|
|
|
if (manager->priv->load_id > 0) {
|
|
g_source_remove (manager->priv->load_id);
|
|
manager->priv->load_id = 0;
|
|
}
|
|
|
|
g_hash_table_destroy (manager->priv->sessions);
|
|
|
|
g_hash_table_destroy (manager->priv->normal_users_by_name);
|
|
g_hash_table_destroy (manager->priv->system_users_by_name);
|
|
g_hash_table_destroy (manager->priv->users_by_object_path);
|
|
|
|
+ g_free (manager->priv->os_id);
|
|
+ g_free (manager->priv->os_version_id);
|
|
+
|
|
G_OBJECT_CLASS (act_user_manager_parent_class)->finalize (object);
|
|
}
|
|
|
|
/**
|
|
* act_user_manager_get_default:
|
|
*
|
|
* Returns the user manager singleton instance. Calling this function will
|
|
* automatically being loading the user list if it isn't loaded already.
|
|
* The #ActUserManager:is-loaded property will be set to %TRUE when the users
|
|
* are finished loading and then act_user_manager_list_users() can be called.
|
|
*
|
|
* Returns: (transfer none): user manager object
|
|
*/
|
|
ActUserManager *
|
|
act_user_manager_get_default (void)
|
|
{
|
|
if (user_manager_object == NULL) {
|
|
user_manager_object = g_object_new (ACT_TYPE_USER_MANAGER, NULL);
|
|
g_object_add_weak_pointer (user_manager_object,
|
|
(gpointer *) &user_manager_object);
|
|
act_user_manager_queue_load (user_manager_object);
|
|
}
|
|
|
|
return ACT_USER_MANAGER (user_manager_object);
|
|
}
|
|
|
|
/**
|
|
* act_user_manager_no_service:
|
|
* @manager: a #ActUserManager
|
|
*
|
|
* Check whether or not the accounts service is running.
|
|
*
|
|
* Returns: whether or not accounts service is running
|
|
*/
|
|
gboolean
|
|
act_user_manager_no_service (ActUserManager *manager)
|
|
{
|
|
return manager->priv->accounts_proxy == NULL;
|
|
}
|
|
|
|
+static void
|
|
+save_system_info (ActUserManager *manager,
|
|
+ const char *user_path)
|
|
+{
|
|
+ ActUserManagerPrivate *priv = manager->priv;
|
|
+ ActUserSystem *user_system_proxy = NULL;
|
|
+ g_autoptr(GError) error = NULL;
|
|
+
|
|
+ if (priv->os_id == NULL && priv->os_version_id == NULL)
|
|
+ return;
|
|
+
|
|
+ user_system_proxy = act_user_system_proxy_new_sync (priv->connection,
|
|
+ G_DBUS_PROXY_FLAGS_NONE,
|
|
+ ACCOUNTS_NAME,
|
|
+ user_path,
|
|
+ NULL,
|
|
+ &error);
|
|
+ if (user_system_proxy != NULL) {
|
|
+ if (priv->os_id != NULL)
|
|
+ act_user_system_set_id (user_system_proxy, priv->os_id);
|
|
+
|
|
+ if (priv->os_version_id != NULL)
|
|
+ act_user_system_set_version_id (user_system_proxy, priv->os_version_id);
|
|
+ } else {
|
|
+ /* probably means accountsservice and lib are out of sync */
|
|
+ g_debug ("ActUserManager: failed to create user system proxy: %s",
|
|
+ error? error->message: "");
|
|
+ g_clear_error (&error);
|
|
+ }
|
|
+
|
|
+ g_clear_object (&user_system_proxy);
|
|
+}
|
|
+
|
|
/**
|
|
* act_user_manager_create_user:
|
|
* @manager: a #ActUserManager
|
|
* @username: a unix user name
|
|
* @fullname: a unix GECOS value
|
|
* @accounttype: a #ActUserAccountType
|
|
* @error: a #GError
|
|
*
|
|
* Creates a user account on the system.
|
|
*
|
|
* Returns: (transfer full): user object
|
|
*/
|
|
ActUser *
|
|
act_user_manager_create_user (ActUserManager *manager,
|
|
const char *username,
|
|
const char *fullname,
|
|
ActUserAccountType accounttype,
|
|
GError **error)
|
|
{
|
|
GError *local_error = NULL;
|
|
gboolean res;
|
|
g_autofree gchar *path = NULL;
|
|
ActUser *user;
|
|
|
|
g_debug ("ActUserManager: Creating user '%s', '%s', %d",
|
|
username, fullname, accounttype);
|
|
|
|
g_assert (manager->priv->accounts_proxy != NULL);
|
|
|
|
res = accounts_accounts_call_create_user_sync (manager->priv->accounts_proxy,
|
|
username,
|
|
fullname,
|
|
accounttype,
|
|
&path,
|
|
NULL,
|
|
&local_error);
|
|
if (!res) {
|
|
g_propagate_error (error, local_error);
|
|
return NULL;
|
|
}
|
|
|
|
+ save_system_info (manager, path);
|
|
+
|
|
user = add_new_user_for_object_path (path, manager);
|
|
|
|
return user;
|
|
}
|
|
|
|
static void
|
|
act_user_manager_async_complete_handler (GObject *source,
|
|
GAsyncResult *result,
|
|
gpointer user_data)
|
|
{
|
|
GTask *task = user_data;
|
|
|
|
g_task_return_pointer (task, g_object_ref (result), g_object_unref);
|
|
g_object_unref (task);
|
|
}
|
|
|
|
/**
|
|
* act_user_manager_create_user_async:
|
|
* @manager: a #ActUserManager
|
|
* @username: a unix user name
|
|
* @fullname: a unix GECOS value
|
|
* @accounttype: a #ActUserAccountType
|
|
* @cancellable: (allow-none): optional #GCancellable object,
|
|
* %NULL to ignore
|
|
* @callback: (scope async): a #GAsyncReadyCallback to call
|
|
* when the request is satisfied
|
|
* @user_data: (closure): the data to pass to @callback
|
|
*
|
|
* Asynchronously creates a user account on the system.
|
|
*
|
|
@@ -3077,105 +3192,110 @@ act_user_manager_create_user_async (ActUserManager *manager,
|
|
* act_user_manager_create_user_finish:
|
|
* @manager: a #ActUserManager
|
|
* @result: a #GAsyncResult
|
|
* @error: a #GError
|
|
*
|
|
* Finishes an asynchronous user creation.
|
|
*
|
|
* See act_user_manager_create_user_async().
|
|
*
|
|
* Returns: (transfer full): user object
|
|
*
|
|
* Since: 0.6.27
|
|
*/
|
|
ActUser *
|
|
act_user_manager_create_user_finish (ActUserManager *manager,
|
|
GAsyncResult *result,
|
|
GError **error)
|
|
{
|
|
GAsyncResult *inner_result;
|
|
ActUser *user = NULL;
|
|
g_autofree gchar *path = NULL;
|
|
GError *remote_error = NULL;
|
|
|
|
inner_result = g_task_propagate_pointer (G_TASK (result), error);
|
|
if (inner_result == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (accounts_accounts_call_create_user_finish (manager->priv->accounts_proxy,
|
|
&path, inner_result, &remote_error)) {
|
|
+
|
|
+ save_system_info (manager, path);
|
|
+
|
|
user = add_new_user_for_object_path (path, manager);
|
|
}
|
|
|
|
if (remote_error) {
|
|
g_dbus_error_strip_remote_error (remote_error);
|
|
g_propagate_error (error, remote_error);
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
/**
|
|
* act_user_manager_cache_user:
|
|
* @manager: a #ActUserManager
|
|
* @username: a user name
|
|
* @error: a #GError
|
|
*
|
|
* Caches a user account so it shows up via act_user_manager_list_users().
|
|
*
|
|
* Returns: (transfer full): user object
|
|
*/
|
|
ActUser *
|
|
act_user_manager_cache_user (ActUserManager *manager,
|
|
const char *username,
|
|
GError **error)
|
|
{
|
|
GError *local_error = NULL;
|
|
gboolean res;
|
|
g_autofree gchar *path = NULL;
|
|
|
|
g_debug ("ActUserManager: Caching user '%s'",
|
|
username);
|
|
|
|
g_assert (manager->priv->accounts_proxy != NULL);
|
|
|
|
res = accounts_accounts_call_cache_user_sync (manager->priv->accounts_proxy,
|
|
username,
|
|
&path,
|
|
NULL,
|
|
&local_error);
|
|
if (!res) {
|
|
g_propagate_error (error, local_error);
|
|
return NULL;
|
|
}
|
|
|
|
+ save_system_info (manager, path);
|
|
+
|
|
return add_new_user_for_object_path (path, manager);
|
|
}
|
|
|
|
|
|
/**
|
|
* act_user_manager_cache_user_async:
|
|
* @manager: a #ActUserManager
|
|
* @username: a unix user name
|
|
* @cancellable: (allow-none): optional #GCancellable object,
|
|
* %NULL to ignore
|
|
* @callback: (scope async): a #GAsyncReadyCallback to call
|
|
* when the request is satisfied
|
|
* @user_data: (closure): the data to pass to @callback
|
|
*
|
|
* Asynchronously caches a user account so it shows up via
|
|
* act_user_manager_list_users().
|
|
*
|
|
* For more details, see act_user_manager_cache_user(), which
|
|
* is the synchronous version of this call.
|
|
*
|
|
* Since: 0.6.27
|
|
*/
|
|
void
|
|
act_user_manager_cache_user_async (ActUserManager *manager,
|
|
const char *username,
|
|
GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
GTask *task;
|
|
@@ -3199,60 +3319,63 @@ act_user_manager_cache_user_async (ActUserManager *manager,
|
|
* act_user_manager_cache_user_finish:
|
|
* @manager: a #ActUserManager
|
|
* @result: a #GAsyncResult
|
|
* @error: a #GError
|
|
*
|
|
* Finishes an asynchronous user caching.
|
|
*
|
|
* See act_user_manager_cache_user_async().
|
|
*
|
|
* Returns: (transfer full): user object
|
|
*
|
|
* Since: 0.6.27
|
|
*/
|
|
ActUser *
|
|
act_user_manager_cache_user_finish (ActUserManager *manager,
|
|
GAsyncResult *result,
|
|
GError **error)
|
|
{
|
|
GAsyncResult *inner_result;
|
|
ActUser *user = NULL;
|
|
g_autofree gchar *path = NULL;
|
|
GError *remote_error = NULL;
|
|
|
|
inner_result = g_task_propagate_pointer (G_TASK (result), error);
|
|
if (inner_result == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (accounts_accounts_call_cache_user_finish (manager->priv->accounts_proxy,
|
|
&path, inner_result, &remote_error)) {
|
|
+
|
|
+ save_system_info (manager, path);
|
|
+
|
|
user = add_new_user_for_object_path (path, manager);
|
|
}
|
|
|
|
if (remote_error) {
|
|
g_dbus_error_strip_remote_error (remote_error);
|
|
g_propagate_error (error, remote_error);
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
/**
|
|
* act_user_manager_uncache_user:
|
|
* @manager: a #ActUserManager
|
|
* @username: a user name
|
|
* @error: a #GError
|
|
*
|
|
* Releases all metadata about a user account, including icon,
|
|
* language and session. If the user account is from a remote
|
|
* server and the user has never logged in before, then that
|
|
* account will no longer show up in ListCachedUsers() output.
|
|
*
|
|
* Returns: %TRUE if successful, otherwise %FALSE
|
|
*/
|
|
gboolean
|
|
act_user_manager_uncache_user (ActUserManager *manager,
|
|
const char *username,
|
|
GError **error)
|
|
{
|
|
GError *local_error = NULL;
|
|
--
|
|
2.17.1
|
|
|