You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
894 lines
29 KiB
894 lines
29 KiB
From 5124220f12a157ff285072a4f786db2c94c3ca8a Mon Sep 17 00:00:00 2001 |
|
From: Ray Strode <rstrode@redhat.com> |
|
Date: Thu, 14 Jan 2021 15:07:34 -0500 |
|
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. |
|
--- |
|
.../com.redhat.AccountsServiceUser.System.xml | 10 ++ |
|
data/meson.build | 1 + |
|
meson.build | 1 + |
|
meson_post_install.py | 15 +++ |
|
src/libaccountsservice/act-user-manager.c | 123 ++++++++++++++++++ |
|
src/libaccountsservice/meson.build | 7 + |
|
6 files changed, 157 insertions(+) |
|
create mode 100644 data/com.redhat.AccountsServiceUser.System.xml |
|
|
|
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/data/meson.build b/data/meson.build |
|
index 4987937..2dc57c2 100644 |
|
--- a/data/meson.build |
|
+++ b/data/meson.build |
|
@@ -1,33 +1,34 @@ |
|
ifaces = files( |
|
act_namespace + '.xml', |
|
act_namespace + '.User.xml', |
|
+ 'com.redhat.AccountsServiceUser.System.xml', |
|
) |
|
|
|
install_data( |
|
ifaces, |
|
install_dir: dbus_ifaces_dir, |
|
) |
|
|
|
install_data( |
|
act_namespace + '.conf', |
|
install_dir: dbus_conf_dir, |
|
) |
|
|
|
service_conf = configuration_data() |
|
service_conf.set('libexecdir', act_libexecdir) |
|
|
|
service = act_namespace + '.service' |
|
|
|
configure_file( |
|
input: service + '.in', |
|
output: service, |
|
configuration: service_conf, |
|
install: true, |
|
install_dir: dbus_sys_dir, |
|
) |
|
|
|
policy = act_namespace.to_lower() + '.policy' |
|
|
|
i18n.merge_file( |
|
policy, |
|
input: policy + '.in', |
|
diff --git a/meson.build b/meson.build |
|
index 4465a26..e37c451 100644 |
|
--- a/meson.build |
|
+++ b/meson.build |
|
@@ -174,38 +174,39 @@ assert(not enable_systemd or not enable_elogind, 'systemd and elogind support re |
|
if enable_systemd |
|
logind_dep = dependency('libsystemd', version: '>= 186') |
|
endif |
|
|
|
if enable_elogind |
|
logind_dep = dependency('libelogind', version: '>= 229.4') |
|
endif |
|
config_h.set('WITH_SYSTEMD', enable_systemd or enable_elogind) |
|
|
|
subdir('data') |
|
subdir('src') |
|
subdir('po') |
|
|
|
enable_docbook = get_option('docbook') |
|
if enable_docbook |
|
subdir('doc/dbus') |
|
endif |
|
|
|
if get_option('gtk_doc') |
|
subdir('doc/libaccountsservice') |
|
endif |
|
|
|
configure_file( |
|
output: 'config.h', |
|
configuration: config_h, |
|
) |
|
|
|
meson.add_install_script( |
|
'meson_post_install.py', |
|
act_localstatedir, |
|
+ act_datadir, |
|
) |
|
|
|
output = '\n' + meson.project_name() + ' was configured with the following options:\n' |
|
output += '** DocBook documentation build: ' + enable_docbook.to_string() + '\n' |
|
output += '** Administrator group: ' + admin_group + '\n' |
|
output += '** Extra administrator groups: ' + extra_admin_groups + '\n' |
|
output += '** GDM configuration: ' + gdm_conf_file |
|
message(output) |
|
diff --git a/meson_post_install.py b/meson_post_install.py |
|
index 5cc2dc4..e1d5a71 100644 |
|
--- a/meson_post_install.py |
|
+++ b/meson_post_install.py |
|
@@ -1,18 +1,33 @@ |
|
#!/usr/bin/env python3 |
|
|
|
import os |
|
import sys |
|
|
|
destdir = os.environ.get('DESTDIR', '') |
|
localstatedir = os.path.normpath(destdir + os.sep + sys.argv[1]) |
|
+datadir = os.path.normpath(destdir + os.sep + sys.argv[2]) |
|
+interfacedir = os.path.join(datadir, 'accountsservice', 'interfaces') |
|
|
|
# FIXME: meson will not track the creation of these directories |
|
# https://github.com/mesonbuild/meson/blob/master/mesonbuild/scripts/uninstall.py#L39 |
|
dst_dirs = [ |
|
(os.path.join(localstatedir, 'lib', 'AccountsService', 'icons'), 0o775), |
|
(os.path.join(localstatedir, 'lib', 'AccountsService', 'users'), 0o700), |
|
+ (interfacedir, 0o775), |
|
] |
|
|
|
for (dst_dir, dst_dir_mode) in dst_dirs: |
|
if not os.path.exists(dst_dir): |
|
os.makedirs(dst_dir, mode=dst_dir_mode) |
|
+ |
|
+interface_files = [ |
|
+ 'com.redhat.AccountsServiceUser.System.xml', |
|
+] |
|
+ |
|
+for interface_file in interface_files: |
|
+ src_path = os.path.join('../../dbus-1/interfaces', interface_file) |
|
+ dst_path = os.path.join(interfacedir, interface_file) |
|
+ if not os.path.exists(dst_path): |
|
+ os.symlink(src_path, dst_path) |
|
+ |
|
+ |
|
diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c |
|
index 1b5298d..f4598c4 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 |
|
@@ -165,60 +166,63 @@ typedef struct |
|
ActUser *user; |
|
ActUserManagerFetchUserRequestType type; |
|
union { |
|
char *username; |
|
uid_t uid; |
|
}; |
|
char *object_path; |
|
char *description; |
|
} ActUserManagerFetchUserRequest; |
|
|
|
typedef struct |
|
{ |
|
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; |
|
} ActUserManagerPrivate; |
|
|
|
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); |
|
|
|
@@ -2942,100 +2946,173 @@ 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 (priv->accounts_proxy), G_MAXINT); |
|
|
|
g_object_bind_property (G_OBJECT (priv->accounts_proxy), |
|
"has-multiple-users", |
|
G_OBJECT (manager), |
|
"has-multiple-users", |
|
G_BINDING_SYNC_CREATE); |
|
|
|
g_signal_connect (priv->accounts_proxy, |
|
"user-added", |
|
G_CALLBACK (on_new_user_in_accounts_service), |
|
manager); |
|
g_signal_connect (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 = act_user_manager_get_instance_private (manager); |
|
+ 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) |
|
{ |
|
ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager); |
|
g_autoptr(GError) error = NULL; |
|
|
|
act_user_manager_error_quark (); /* register dbus errors */ |
|
|
|
/* sessions */ |
|
priv->sessions = g_hash_table_new_full (g_str_hash, |
|
g_str_equal, |
|
g_free, |
|
g_object_unref); |
|
|
|
/* users */ |
|
priv->normal_users_by_name = g_hash_table_new_full (g_str_hash, |
|
g_str_equal, |
|
g_free, |
|
g_object_unref); |
|
priv->system_users_by_name = g_hash_table_new_full (g_str_hash, |
|
g_str_equal, |
|
g_free, |
|
g_object_unref); |
|
priv->users_by_object_path = g_hash_table_new_full (g_str_hash, |
|
g_str_equal, |
|
NULL, |
|
g_object_unref); |
|
|
|
priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); |
|
if (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); |
|
+ |
|
priv->seat.state = ACT_USER_MANAGER_SEAT_STATE_UNLOADED; |
|
} |
|
|
|
static void |
|
act_user_manager_finalize (GObject *object) |
|
{ |
|
ActUserManager *manager = ACT_USER_MANAGER (object); |
|
ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager); |
|
GSList *node; |
|
|
|
g_debug ("ActUserManager: finalizing user manager"); |
|
|
|
g_slist_foreach (priv->new_sessions, |
|
(GFunc) unload_new_session, NULL); |
|
g_slist_free (priv->new_sessions); |
|
|
|
g_slist_foreach (priv->fetch_user_requests, |
|
(GFunc) free_fetch_user_request, NULL); |
|
g_slist_free (priv->fetch_user_requests); |
|
|
|
g_slist_free (priv->new_users_inhibiting_load); |
|
|
|
node = priv->new_users; |
|
while (node != NULL) { |
|
ActUser *user; |
|
GSList *next_node; |
|
|
|
user = ACT_USER (node->data); |
|
next_node = node->next; |
|
|
|
@@ -3071,143 +3148,181 @@ act_user_manager_finalize (GObject *object) |
|
|
|
#ifdef WITH_SYSTEMD |
|
if (priv->seat.session_monitor != NULL) { |
|
sd_login_monitor_unref (priv->seat.session_monitor); |
|
} |
|
|
|
if (priv->seat.session_monitor_stream != NULL) { |
|
g_object_unref (priv->seat.session_monitor_stream); |
|
} |
|
|
|
if (priv->seat.session_monitor_source_id != 0) { |
|
g_source_remove (priv->seat.session_monitor_source_id); |
|
} |
|
#endif |
|
|
|
if (priv->accounts_proxy != NULL) { |
|
g_object_unref (priv->accounts_proxy); |
|
} |
|
|
|
if (priv->load_id > 0) { |
|
g_source_remove (priv->load_id); |
|
priv->load_id = 0; |
|
} |
|
|
|
g_hash_table_destroy (priv->sessions); |
|
|
|
g_hash_table_destroy (priv->normal_users_by_name); |
|
g_hash_table_destroy (priv->system_users_by_name); |
|
g_hash_table_destroy (priv->users_by_object_path); |
|
|
|
+ g_free (priv->os_id); |
|
+ g_free (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) |
|
{ |
|
ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager); |
|
return priv->accounts_proxy == NULL; |
|
} |
|
|
|
+static void |
|
+save_system_info (ActUserManager *manager, |
|
+ const char *user_path) |
|
+{ |
|
+ ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager); |
|
+ 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) |
|
{ |
|
ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager); |
|
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 (priv->accounts_proxy != NULL); |
|
|
|
res = accounts_accounts_call_create_user_sync (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. |
|
* |
|
@@ -3253,106 +3368,111 @@ act_user_manager_create_user_async (ActUserManager *manager, |
|
* @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) |
|
{ |
|
ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager); |
|
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 (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) |
|
{ |
|
ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager); |
|
GError *local_error = NULL; |
|
gboolean res; |
|
g_autofree gchar *path = NULL; |
|
|
|
g_debug ("ActUserManager: Caching user '%s'", |
|
username); |
|
|
|
g_assert (priv->accounts_proxy != NULL); |
|
|
|
res = accounts_accounts_call_cache_user_sync (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) |
|
{ |
|
ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager); |
|
@@ -3378,60 +3498,63 @@ act_user_manager_cache_user_async (ActUserManager *manager, |
|
* @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) |
|
{ |
|
ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager); |
|
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 (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) |
|
{ |
|
ActUserManagerPrivate *priv = act_user_manager_get_instance_private (manager); |
|
diff --git a/src/libaccountsservice/meson.build b/src/libaccountsservice/meson.build |
|
index 4e134db..9e85bba 100644 |
|
--- a/src/libaccountsservice/meson.build |
|
+++ b/src/libaccountsservice/meson.build |
|
@@ -21,60 +21,67 @@ enum_types = 'act-user-enum-types' |
|
|
|
enum_sources = gnome.mkenums( |
|
enum_types, |
|
sources: headers, |
|
c_template: enum_types + '.c.template', |
|
h_template: enum_types + '.h.template', |
|
install_header: true, |
|
install_dir: join_paths(act_pkgincludedir, subdir), |
|
) |
|
|
|
dbus_sources = [] |
|
|
|
ifaces = [ |
|
'Manager', |
|
'Seat', |
|
'Session', |
|
] |
|
|
|
namespace = 'ConsoleKit' |
|
prefix = 'org.freedesktop.' + namespace |
|
|
|
foreach iface: ifaces |
|
dbus_sources += gnome.gdbus_codegen( |
|
'ck-@0@-generated'.format(iface.to_lower()), |
|
'@0@.@1@.xml'.format(prefix, iface), |
|
interface_prefix: prefix, |
|
namespace: namespace, |
|
) |
|
endforeach |
|
|
|
+dbus_sources += gnome.gdbus_codegen( |
|
+ 'com.redhat.AccountsServiceUser.System', |
|
+ join_paths(data_dir, 'com.redhat.AccountsServiceUser.System.xml'), |
|
+ interface_prefix: 'com.redhat.AccountsService', |
|
+ namespace: 'Act', |
|
+) |
|
+ |
|
deps = [ |
|
crypt_dep, |
|
gio_unix_dep, |
|
glib_dep, |
|
libaccounts_generated_dep, |
|
] |
|
|
|
symbol_map = join_paths(meson.current_source_dir(), 'symbol.map') |
|
ldflags = cc.get_supported_link_arguments('-Wl,--version-script,@0@'.format(symbol_map)) |
|
|
|
if enable_systemd or enable_elogind |
|
deps += logind_dep |
|
endif |
|
|
|
libaccountsservice = shared_library( |
|
act_name, |
|
sources: sources + enum_sources + dbus_sources, |
|
version: libversion, |
|
include_directories: top_inc, |
|
dependencies: deps, |
|
c_args: '-DG_LOG_DOMAIN="@0@"'.format(meson.project_name()), |
|
link_args: ldflags, |
|
link_depends: symbol_map, |
|
install: true, |
|
) |
|
|
|
libaccountsservice_dep = declare_dependency( |
|
sources: enum_sources[1], |
|
include_directories: include_directories('.'), |
|
dependencies: [gio_dep, glib_dep], |
|
-- |
|
2.27.0 |
|
|
|
|