import accountsservice-0.6.50-7.el8
This commit is contained in:
commit
3c5b0febb0
1
.accountsservice.metadata
Normal file
1
.accountsservice.metadata
Normal file
@ -0,0 +1 @@
|
||||
8d59b9cdc4121b34748442ee653b92d60607f2cb SOURCES/accountsservice-0.6.50.tar.xz
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
SOURCES/accountsservice-0.6.50.tar.xz
|
349
SOURCES/0001-daemon-Fix-warnings-about-type-punning.patch
Normal file
349
SOURCES/0001-daemon-Fix-warnings-about-type-punning.patch
Normal file
@ -0,0 +1,349 @@
|
||||
From dee5f443807fee3b5b279d0488df617eeed52230 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Ancell <robert.ancell@canonical.com>
|
||||
Date: Thu, 6 Sep 2018 14:37:39 +1200
|
||||
Subject: [PATCH] daemon: Fix warnings about type-punning
|
||||
|
||||
---
|
||||
src/daemon.c | 26 +++++++++++++++-----------
|
||||
1 file changed, 15 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/daemon.c b/src/daemon.c
|
||||
index 2587b8a..00dff51 100644
|
||||
--- a/src/daemon.c
|
||||
+++ b/src/daemon.c
|
||||
@@ -232,117 +232,118 @@ entry_generator_fgetpwent (Daemon *daemon,
|
||||
pwent = fgetpwent (generator_state->fp);
|
||||
if (pwent != NULL) {
|
||||
shadow_entry_buffers = g_hash_table_lookup (generator_state->users, pwent->pw_name);
|
||||
|
||||
if (shadow_entry_buffers != NULL) {
|
||||
*spent = &shadow_entry_buffers->spbuf;
|
||||
}
|
||||
return pwent;
|
||||
}
|
||||
}
|
||||
|
||||
/* Last iteration */
|
||||
fclose (generator_state->fp);
|
||||
g_hash_table_unref (generator_state->users);
|
||||
g_free (generator_state);
|
||||
*state = NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
entry_generator_cachedir (Daemon *daemon,
|
||||
GHashTable *users,
|
||||
gpointer *state,
|
||||
struct spwd **shadow_entry)
|
||||
{
|
||||
struct passwd *pwent;
|
||||
g_autoptr(GError) error = NULL;
|
||||
gboolean regular;
|
||||
GHashTableIter iter;
|
||||
- const gchar *name;
|
||||
- User *user;
|
||||
+ gpointer key, value;
|
||||
GDir *dir;
|
||||
|
||||
/* First iteration */
|
||||
if (*state == NULL) {
|
||||
*state = g_dir_open (USERDIR, 0, &error);
|
||||
if (error != NULL) {
|
||||
if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
|
||||
g_warning ("couldn't list user cache directory: %s", USERDIR);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Every iteration */
|
||||
|
||||
/*
|
||||
* Use names of files of regular type to lookup information
|
||||
* about each user. Loop until we find something valid.
|
||||
*/
|
||||
dir = *state;
|
||||
while (TRUE) {
|
||||
const gchar *name;
|
||||
g_autofree gchar *filename = NULL;
|
||||
|
||||
name = g_dir_read_name (dir);
|
||||
if (name == NULL)
|
||||
break;
|
||||
|
||||
/* Only load files in this directory */
|
||||
filename = g_build_filename (USERDIR, name, NULL);
|
||||
regular = g_file_test (filename, G_FILE_TEST_IS_REGULAR);
|
||||
|
||||
if (regular) {
|
||||
errno = 0;
|
||||
pwent = getpwnam (name);
|
||||
if (pwent != NULL) {
|
||||
*shadow_entry = getspnam (pwent->pw_name);
|
||||
|
||||
return pwent;
|
||||
} else if (errno == 0) {
|
||||
g_debug ("user '%s' in cache dir but not present on system, removing", name);
|
||||
remove_cache_files (name);
|
||||
}
|
||||
else {
|
||||
g_warning ("failed to check if user '%s' in cache dir is present on system: %s",
|
||||
name, g_strerror (errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Last iteration */
|
||||
g_dir_close (dir);
|
||||
|
||||
/* Update all the users from the files in the cache dir */
|
||||
g_hash_table_iter_init (&iter, users);
|
||||
- while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&user)) {
|
||||
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
+ const gchar *name = key;
|
||||
+ User *user = value;
|
||||
g_autofree gchar *filename = NULL;
|
||||
g_autoptr(GKeyFile) key_file = NULL;
|
||||
|
||||
filename = g_build_filename (USERDIR, name, NULL);
|
||||
key_file = g_key_file_new ();
|
||||
if (g_key_file_load_from_file (key_file, filename, 0, NULL))
|
||||
user_update_from_keyfile (user, key_file);
|
||||
}
|
||||
|
||||
*state = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
entry_generator_requested_users (Daemon *daemon,
|
||||
GHashTable *users,
|
||||
gpointer *state,
|
||||
struct spwd **shadow_entry)
|
||||
{
|
||||
struct passwd *pwent;
|
||||
GList *node;
|
||||
|
||||
/* First iteration */
|
||||
if (*state == NULL) {
|
||||
*state = daemon->priv->explicitly_requested_users;
|
||||
}
|
||||
|
||||
/* Every iteration */
|
||||
|
||||
if (g_hash_table_size (users) < MAX_LOCAL_USERS) {
|
||||
@@ -423,129 +424,131 @@ load_entries (Daemon *daemon,
|
||||
}
|
||||
|
||||
if (!explicitly_requested) {
|
||||
user_set_cached (user, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Generator should have cleaned up */
|
||||
g_assert (generator_state == NULL);
|
||||
}
|
||||
|
||||
static GHashTable *
|
||||
create_users_hash_table (void)
|
||||
{
|
||||
return g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_users (Daemon *daemon)
|
||||
{
|
||||
AccountsAccounts *accounts = ACCOUNTS_ACCOUNTS (daemon);
|
||||
gboolean had_no_users, has_no_users, had_multiple_users, has_multiple_users;
|
||||
GHashTable *users;
|
||||
GHashTable *old_users;
|
||||
GHashTable *local;
|
||||
GHashTableIter iter;
|
||||
gsize number_of_normal_users = 0;
|
||||
- gpointer name;
|
||||
- User *user;
|
||||
+ gpointer name, value;
|
||||
|
||||
/* Track the users that we saw during our (re)load */
|
||||
users = create_users_hash_table ();
|
||||
|
||||
/*
|
||||
* NOTE: As we load data from all the sources, notifies are
|
||||
* frozen in load_entries() and then thawed as we process
|
||||
* them below.
|
||||
*/
|
||||
|
||||
/* Load the local users into our hash table */
|
||||
load_entries (daemon, users, FALSE, entry_generator_fgetpwent);
|
||||
local = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
g_hash_table_iter_init (&iter, users);
|
||||
while (g_hash_table_iter_next (&iter, &name, NULL))
|
||||
g_hash_table_add (local, name);
|
||||
|
||||
/* and add users to hash table that were explicitly requested */
|
||||
load_entries (daemon, users, TRUE, entry_generator_requested_users);
|
||||
|
||||
/* Now add/update users from other sources, possibly non-local */
|
||||
load_entries (daemon, users, FALSE, entry_generator_cachedir);
|
||||
|
||||
wtmp_helper_update_login_frequencies (users);
|
||||
|
||||
/* Count the non-system users. Mark which users are local, which are not. */
|
||||
g_hash_table_iter_init (&iter, users);
|
||||
- while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) {
|
||||
+ while (g_hash_table_iter_next (&iter, &name, &value)) {
|
||||
+ User *user = value;
|
||||
if (!user_get_system_account (user))
|
||||
number_of_normal_users++;
|
||||
user_update_local_account_property (user, g_hash_table_lookup (local, name) != NULL);
|
||||
}
|
||||
g_hash_table_destroy (local);
|
||||
|
||||
had_no_users = accounts_accounts_get_has_no_users (accounts);
|
||||
has_no_users = number_of_normal_users == 0;
|
||||
|
||||
if (had_no_users != has_no_users)
|
||||
accounts_accounts_set_has_no_users (accounts, has_no_users);
|
||||
|
||||
had_multiple_users = accounts_accounts_get_has_multiple_users (accounts);
|
||||
has_multiple_users = number_of_normal_users > 1;
|
||||
|
||||
if (had_multiple_users != has_multiple_users)
|
||||
accounts_accounts_set_has_multiple_users (accounts, has_multiple_users);
|
||||
|
||||
/* Swap out the users */
|
||||
old_users = daemon->priv->users;
|
||||
daemon->priv->users = users;
|
||||
|
||||
/* Remove all the old users */
|
||||
g_hash_table_iter_init (&iter, old_users);
|
||||
- while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) {
|
||||
+ while (g_hash_table_iter_next (&iter, &name, &value)) {
|
||||
+ User *user = value;
|
||||
User *refreshed_user;
|
||||
|
||||
refreshed_user = g_hash_table_lookup (users, name);
|
||||
|
||||
if (!refreshed_user || (user_get_cached (user) && !user_get_cached (refreshed_user))) {
|
||||
accounts_accounts_emit_user_deleted (ACCOUNTS_ACCOUNTS (daemon),
|
||||
user_get_object_path (user));
|
||||
user_unregister (user);
|
||||
}
|
||||
}
|
||||
|
||||
/* Register all the new users */
|
||||
g_hash_table_iter_init (&iter, users);
|
||||
- while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) {
|
||||
+ while (g_hash_table_iter_next (&iter, &name, &value)) {
|
||||
+ User *user = value;
|
||||
User *stale_user;
|
||||
|
||||
stale_user = g_hash_table_lookup (old_users, name);
|
||||
|
||||
if (!stale_user || (!user_get_cached (stale_user) && user_get_cached (user))) {
|
||||
user_register (user);
|
||||
accounts_accounts_emit_user_added (ACCOUNTS_ACCOUNTS (daemon),
|
||||
user_get_object_path (user));
|
||||
}
|
||||
g_object_thaw_notify (G_OBJECT (user));
|
||||
}
|
||||
|
||||
g_hash_table_destroy (old_users);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
reload_users_timeout (Daemon *daemon)
|
||||
{
|
||||
reload_users (daemon);
|
||||
daemon->priv->reload_id = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean load_autologin (Daemon *daemon,
|
||||
gchar **name,
|
||||
gboolean *enabled,
|
||||
GError **error);
|
||||
|
||||
static gboolean
|
||||
@@ -932,69 +935,70 @@ typedef struct {
|
||||
} ListUserData;
|
||||
|
||||
|
||||
static ListUserData *
|
||||
list_user_data_new (Daemon *daemon,
|
||||
GDBusMethodInvocation *context)
|
||||
{
|
||||
ListUserData *data;
|
||||
|
||||
data = g_new0 (ListUserData, 1);
|
||||
|
||||
data->daemon = g_object_ref (daemon);
|
||||
data->context = context;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
list_user_data_free (ListUserData *data)
|
||||
{
|
||||
g_object_unref (data->daemon);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
finish_list_cached_users (gpointer user_data)
|
||||
{
|
||||
ListUserData *data = user_data;
|
||||
g_autoptr(GPtrArray) object_paths = NULL;
|
||||
GHashTableIter iter;
|
||||
- const gchar *name;
|
||||
- User *user;
|
||||
+ gpointer key, value;
|
||||
uid_t uid;
|
||||
const gchar *shell;
|
||||
|
||||
object_paths = g_ptr_array_new ();
|
||||
|
||||
g_hash_table_iter_init (&iter, data->daemon->priv->users);
|
||||
- while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&user)) {
|
||||
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
+ const gchar *name = key;
|
||||
+ User *user = value;
|
||||
uid = user_get_uid (user);
|
||||
shell = user_get_shell (user);
|
||||
|
||||
if (!user_classify_is_human (uid, name, shell, NULL)) {
|
||||
g_debug ("user %s %ld excluded", name, (long) uid);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!user_get_cached (user)) {
|
||||
g_debug ("user %s %ld not cached", name, (long) uid);
|
||||
continue;
|
||||
}
|
||||
|
||||
g_debug ("user %s %ld not excluded", name, (long) uid);
|
||||
g_ptr_array_add (object_paths, (gpointer) user_get_object_path (user));
|
||||
}
|
||||
g_ptr_array_add (object_paths, NULL);
|
||||
|
||||
accounts_accounts_complete_list_cached_users (NULL, data->context, (const gchar * const *) object_paths->pdata);
|
||||
|
||||
list_user_data_free (data);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
daemon_list_cached_users (AccountsAccounts *accounts,
|
||||
GDBusMethodInvocation *context)
|
||||
{
|
||||
Daemon *daemon = (Daemon*)accounts;
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,88 @@
|
||||
From b4f85d66280affcb52e998661f782c2ab4f806a7 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Thu, 9 May 2019 14:58:34 -0400
|
||||
Subject: [PATCH] data: don't send change updates for login-history
|
||||
|
||||
The login-history property of user objects can be quite large.
|
||||
If wtmp is changed frequently, that can lead to memory fragmentation
|
||||
in clients.
|
||||
|
||||
Furthermore, most clients never check login-history, so it's
|
||||
wasted memory and wasted cpu.
|
||||
|
||||
This commit disables change notification for that property. If
|
||||
a client really needs to get updates, they can manually refresh
|
||||
their cache when appropriate.
|
||||
---
|
||||
data/org.freedesktop.Accounts.User.xml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml
|
||||
index 8d3fe1c..3b839a3 100644
|
||||
--- a/data/org.freedesktop.Accounts.User.xml
|
||||
+++ b/data/org.freedesktop.Accounts.User.xml
|
||||
@@ -785,60 +785,61 @@
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The users location.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="LoginFrequency" type="t" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
How often the user has logged in.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="LoginTime" type="x" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The last login time.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="LoginHistory" type="a(xxa{sv})" access="read">
|
||||
+ <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The login history for this user.
|
||||
Each entry in the array represents a login session. The first two
|
||||
members are the login time and logout time, as timestamps (seconds since the epoch). If the session is still running, the logout time
|
||||
is 0.
|
||||
</doc:para>
|
||||
<doc:para>
|
||||
The a{sv} member is a dictionary containing additional information
|
||||
about the session. Possible members include 'type' (with values like ':0', 'tty0', 'pts/0' etc).
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="IconFile" type="s" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The filename of a png file containing the users icon.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="Saved" type="b" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,90 @@
|
||||
From c7fa612023a163e8b2352e1170c6df3fceb19b27 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Thu, 19 Jul 2018 13:14:09 -0400
|
||||
Subject: [PATCH] lib: don't set loaded state until seat is fetched
|
||||
|
||||
At the moment we set is-loaded on the user-manager
|
||||
object as soon as we start fetching the seat, but
|
||||
we should waiting until the seat is fetched, so
|
||||
that can_switch() will return the correct value
|
||||
if the caller waited until the loaded signal
|
||||
to use it.
|
||||
|
||||
This commit changes the >= to > which I believe
|
||||
was the original intention anyway.
|
||||
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=107298
|
||||
---
|
||||
src/libaccountsservice/act-user-manager.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c
|
||||
index 325421b..e7e26b1 100644
|
||||
--- a/src/libaccountsservice/act-user-manager.c
|
||||
+++ b/src/libaccountsservice/act-user-manager.c
|
||||
@@ -2355,61 +2355,61 @@ act_user_manager_list_users (ActUserManager *manager)
|
||||
queue_load_seat_incrementally (manager);
|
||||
}
|
||||
|
||||
retval = NULL;
|
||||
g_hash_table_foreach (manager->priv->normal_users_by_name, listify_hash_values_hfunc, &retval);
|
||||
|
||||
return g_slist_sort (retval, (GCompareFunc) act_user_collate);
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_set_is_loaded (ActUserManager *manager)
|
||||
{
|
||||
if (manager->priv->is_loaded) {
|
||||
g_debug ("ActUserManager: already loaded, so not setting loaded property");
|
||||
return;
|
||||
}
|
||||
|
||||
if (manager->priv->getting_sessions) {
|
||||
g_debug ("ActUserManager: GetSessions call pending, so not setting loaded property");
|
||||
return;
|
||||
}
|
||||
|
||||
if (manager->priv->new_users_inhibiting_load != NULL) {
|
||||
g_debug ("ActUserManager: Loading new users, so not setting loaded property");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't set is_loaded yet unless the seat is already loaded enough
|
||||
* or failed to load.
|
||||
*/
|
||||
- if (manager->priv->seat.state >= ACT_USER_MANAGER_SEAT_STATE_GET_ID) {
|
||||
+ if (manager->priv->seat.state > ACT_USER_MANAGER_SEAT_STATE_GET_ID) {
|
||||
g_debug ("ActUserManager: Seat loaded, so now setting loaded property");
|
||||
} else if (manager->priv->seat.state == ACT_USER_MANAGER_SEAT_STATE_UNLOADED) {
|
||||
g_debug ("ActUserManager: Seat wouldn't load, so giving up on it and setting loaded property");
|
||||
} else {
|
||||
g_debug ("ActUserManager: Seat still actively loading, so not setting loaded property");
|
||||
return;
|
||||
}
|
||||
|
||||
set_is_loaded (manager, TRUE);
|
||||
}
|
||||
|
||||
|
||||
static GSList *
|
||||
slist_deep_copy (const GSList *list)
|
||||
{
|
||||
GSList *retval;
|
||||
GSList *l;
|
||||
|
||||
if (list == NULL)
|
||||
return NULL;
|
||||
|
||||
retval = g_slist_copy ((GSList *) list);
|
||||
for (l = retval; l != NULL; l = l->next) {
|
||||
l->data = g_strdup (l->data);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
--
|
||||
2.17.1
|
||||
|
844
SOURCES/0001-lib-save-os-when-creating-user.patch
Normal file
844
SOURCES/0001-lib-save-os-when-creating-user.patch
Normal file
@ -0,0 +1,844 @@
|
||||
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
|
||||
|
@ -0,0 +1,910 @@
|
||||
From c66cee942242a731082f0fac649f3f9569ae99a3 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Wed, 8 Aug 2018 16:11:56 -0400
|
||||
Subject: [PATCH 1/2] user: add new Session/SessionType properties to replace
|
||||
XSession
|
||||
|
||||
Having a property called XSession in the API makes little
|
||||
sense when wayland has taken the world by storm.
|
||||
|
||||
This commit adds new "Session" property without the "X" in the name,
|
||||
and an additional property "SessionType" that can be either
|
||||
"wayland" or "x11".
|
||||
---
|
||||
data/org.freedesktop.Accounts.User.xml | 103 +++++++++++++++++++++
|
||||
src/libaccountsservice/act-user.c | 93 +++++++++++++++++++
|
||||
src/libaccountsservice/act-user.h | 6 ++
|
||||
src/user.c | 121 +++++++++++++++++++++++++
|
||||
4 files changed, 323 insertions(+)
|
||||
|
||||
diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml
|
||||
index 4ab989a..7fc3c61 100644
|
||||
--- a/data/org.freedesktop.Accounts.User.xml
|
||||
+++ b/data/org.freedesktop.Accounts.User.xml
|
||||
@@ -141,60 +141,143 @@
|
||||
<doc:term>org.freedesktop.accounts.user-administration</doc:term>
|
||||
<doc:definition>To change the language of another user</doc:definition>
|
||||
</doc:item>
|
||||
</doc:list>
|
||||
</doc:permission>
|
||||
<doc:errors>
|
||||
<doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
|
||||
<doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
|
||||
</doc:errors>
|
||||
</doc:doc>
|
||||
</method>
|
||||
|
||||
<method name="SetXSession">
|
||||
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="user_set_x_session"/>
|
||||
<arg name="x_session" direction="in" type="s">
|
||||
<doc:doc>
|
||||
<doc:summary>
|
||||
The new xsession to start (e.g. "gnome")
|
||||
</doc:summary>
|
||||
</doc:doc>
|
||||
</arg>
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
Sets the users x session.
|
||||
</doc:para>
|
||||
<doc:para>
|
||||
The expectation is that display managers will log the user in to this
|
||||
specified session, if available.
|
||||
+
|
||||
+ Note this call is deprecated and has been superceded by SetSession since
|
||||
+ not all graphical sessions use X as the display server.
|
||||
+ </doc:para>
|
||||
+ </doc:description>
|
||||
+ <doc:permission>
|
||||
+ The caller needs one of the following PolicyKit authorizations:
|
||||
+ <doc:list>
|
||||
+ <doc:item>
|
||||
+ <doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
|
||||
+ <doc:definition>To change his own language</doc:definition>
|
||||
+ </doc:item>
|
||||
+ <doc:item>
|
||||
+ <doc:term>org.freedesktop.accounts.user-administration</doc:term>
|
||||
+ <doc:definition>To change the language of another user</doc:definition>
|
||||
+ </doc:item>
|
||||
+ </doc:list>
|
||||
+ </doc:permission>
|
||||
+ <doc:errors>
|
||||
+ <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
|
||||
+ <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
|
||||
+ </doc:errors>
|
||||
+ </doc:doc>
|
||||
+ </method>
|
||||
+
|
||||
+ <method name="SetSession">
|
||||
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="user_set_session"/>
|
||||
+ <arg name="session" direction="in" type="s">
|
||||
+ <doc:doc>
|
||||
+ <doc:summary>
|
||||
+ The new session to start (e.g. "gnome-xorg")
|
||||
+ </doc:summary>
|
||||
+ </doc:doc>
|
||||
+ </arg>
|
||||
+ <doc:doc>
|
||||
+ <doc:description>
|
||||
+ <doc:para>
|
||||
+ Sets the users wayland or x session.
|
||||
+ </doc:para>
|
||||
+ <doc:para>
|
||||
+ The expectation is that display managers will log the user in to this
|
||||
+ specified session, if available.
|
||||
+ </doc:para>
|
||||
+ </doc:description>
|
||||
+ <doc:permission>
|
||||
+ The caller needs one of the following PolicyKit authorizations:
|
||||
+ <doc:list>
|
||||
+ <doc:item>
|
||||
+ <doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
|
||||
+ <doc:definition>To change his own language</doc:definition>
|
||||
+ </doc:item>
|
||||
+ <doc:item>
|
||||
+ <doc:term>org.freedesktop.accounts.user-administration</doc:term>
|
||||
+ <doc:definition>To change the language of another user</doc:definition>
|
||||
+ </doc:item>
|
||||
+ </doc:list>
|
||||
+ </doc:permission>
|
||||
+ <doc:errors>
|
||||
+ <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
|
||||
+ <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
|
||||
+ </doc:errors>
|
||||
+ </doc:doc>
|
||||
+ </method>
|
||||
+
|
||||
+ <method name="SetSessionType">
|
||||
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="user_set_session_type"/>
|
||||
+ <arg name="session_type" direction="in" type="s">
|
||||
+ <doc:doc>
|
||||
+ <doc:summary>
|
||||
+ The type of the new session to start (e.g. "wayland" or "x11")
|
||||
+ </doc:summary>
|
||||
+ </doc:doc>
|
||||
+ </arg>
|
||||
+ <doc:doc>
|
||||
+ <doc:description>
|
||||
+ <doc:para>
|
||||
+ Sets the session type of the users session.
|
||||
+ </doc:para>
|
||||
+ <doc:para>
|
||||
+ Display managers may use this property to decide what type of display server to use when
|
||||
+ loading the session
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
<doc:permission>
|
||||
The caller needs one of the following PolicyKit authorizations:
|
||||
<doc:list>
|
||||
<doc:item>
|
||||
<doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
|
||||
<doc:definition>To change his own language</doc:definition>
|
||||
</doc:item>
|
||||
<doc:item>
|
||||
<doc:term>org.freedesktop.accounts.user-administration</doc:term>
|
||||
<doc:definition>To change the language of another user</doc:definition>
|
||||
</doc:item>
|
||||
</doc:list>
|
||||
</doc:permission>
|
||||
<doc:errors>
|
||||
<doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
|
||||
<doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
|
||||
</doc:errors>
|
||||
</doc:doc>
|
||||
</method>
|
||||
|
||||
<method name="SetLocation">
|
||||
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||
<arg name="location" direction="in" type="s">
|
||||
<doc:doc>
|
||||
<doc:summary>
|
||||
The new location as a freeform string.
|
||||
</doc:summary>
|
||||
</doc:doc>
|
||||
@@ -641,60 +724,80 @@
|
||||
<property name="Shell" type="s" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The users shell.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="Email" type="s" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The email address.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="Language" type="s" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The users language, as a locale specification like "de_DE.UTF-8".
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
+ <property name="Session" type="s" access="read">
|
||||
+ <doc:doc>
|
||||
+ <doc:description>
|
||||
+ <doc:para>
|
||||
+ The users Wayland or X session.
|
||||
+ </doc:para>
|
||||
+ </doc:description>
|
||||
+ </doc:doc>
|
||||
+ </property>
|
||||
+
|
||||
+ <property name="SessionType" type="s" access="read">
|
||||
+ <doc:doc>
|
||||
+ <doc:description>
|
||||
+ <doc:para>
|
||||
+ The type of session the user should use (e.g. "wayland" or "x11")
|
||||
+ </doc:para>
|
||||
+ </doc:description>
|
||||
+ </doc:doc>
|
||||
+ </property>
|
||||
+
|
||||
<property name="XSession" type="s" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The users x session.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="Location" type="s" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The users location.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="LoginFrequency" type="t" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
How often the user has logged in.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c
|
||||
index 7162221..dd8f81b 100644
|
||||
--- a/src/libaccountsservice/act-user.c
|
||||
+++ b/src/libaccountsservice/act-user.c
|
||||
@@ -999,60 +999,98 @@ act_user_get_icon_file (ActUser *user)
|
||||
const char *
|
||||
act_user_get_language (ActUser *user)
|
||||
{
|
||||
g_return_val_if_fail (ACT_IS_USER (user), NULL);
|
||||
|
||||
if (user->accounts_proxy == NULL)
|
||||
return NULL;
|
||||
|
||||
return accounts_user_get_language (user->accounts_proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* act_user_get_x_session:
|
||||
* @user: a #ActUser
|
||||
*
|
||||
* Returns the path to the configured X session for @user.
|
||||
*
|
||||
* Returns: (transfer none): a path to an icon
|
||||
*/
|
||||
const char *
|
||||
act_user_get_x_session (ActUser *user)
|
||||
{
|
||||
g_return_val_if_fail (ACT_IS_USER (user), NULL);
|
||||
|
||||
if (user->accounts_proxy == NULL)
|
||||
return NULL;
|
||||
|
||||
return accounts_user_get_xsession (user->accounts_proxy);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * act_user_get_session:
|
||||
+ * @user: a #ActUser
|
||||
+ *
|
||||
+ * Returns the path to the configured session for @user.
|
||||
+ *
|
||||
+ * Returns: (transfer none): a path to an icon
|
||||
+ */
|
||||
+const char *
|
||||
+act_user_get_session (ActUser *user)
|
||||
+{
|
||||
+ g_return_val_if_fail (ACT_IS_USER (user), NULL);
|
||||
+
|
||||
+ if (user->accounts_proxy == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return accounts_user_get_session (user->accounts_proxy);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * act_user_get_session_type:
|
||||
+ * @user: a #ActUser
|
||||
+ *
|
||||
+ * Returns the type of the configured session for @user.
|
||||
+ *
|
||||
+ * Returns: (transfer none): a path to an icon
|
||||
+ */
|
||||
+const char *
|
||||
+act_user_get_session_type (ActUser *user)
|
||||
+{
|
||||
+ g_return_val_if_fail (ACT_IS_USER (user), NULL);
|
||||
+
|
||||
+ if (user->accounts_proxy == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return accounts_user_get_session_type (user->accounts_proxy);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* act_user_get_object_path:
|
||||
* @user: a #ActUser
|
||||
*
|
||||
* Returns the user accounts service object path of @user,
|
||||
* or %NULL if @user doesn't have an object path associated
|
||||
* with it.
|
||||
*
|
||||
* Returns: (transfer none): the object path of the user
|
||||
*/
|
||||
const char *
|
||||
act_user_get_object_path (ActUser *user)
|
||||
{
|
||||
g_return_val_if_fail (ACT_IS_USER (user), NULL);
|
||||
|
||||
if (user->accounts_proxy == NULL)
|
||||
return NULL;
|
||||
|
||||
return g_dbus_proxy_get_object_path (G_DBUS_PROXY (user->accounts_proxy));
|
||||
}
|
||||
|
||||
/**
|
||||
* act_user_get_primary_session_id:
|
||||
* @user: a #ActUser
|
||||
*
|
||||
* Returns the id of the primary session of @user, or %NULL if @user
|
||||
* has no primary session. The primary session will always be
|
||||
* graphical and will be chosen from the sessions on the same seat as
|
||||
* the seat of the session of the calling process.
|
||||
*
|
||||
@@ -1310,60 +1348,115 @@ act_user_set_language (ActUser *user,
|
||||
}
|
||||
|
||||
/**
|
||||
* act_user_set_x_session:
|
||||
* @user: the user object to alter.
|
||||
* @x_session: an x session (e.g. gnome)
|
||||
*
|
||||
* Assigns a new x session for @user.
|
||||
*
|
||||
* Note this function is synchronous and ignores errors.
|
||||
**/
|
||||
void
|
||||
act_user_set_x_session (ActUser *user,
|
||||
const char *x_session)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_return_if_fail (ACT_IS_USER (user));
|
||||
g_return_if_fail (x_session != NULL);
|
||||
g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
|
||||
|
||||
if (!accounts_user_call_set_xsession_sync (user->accounts_proxy,
|
||||
x_session,
|
||||
NULL,
|
||||
&error)) {
|
||||
g_warning ("SetXSession call failed: %s", error->message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * act_user_set_session:
|
||||
+ * @user: the user object to alter.
|
||||
+ * @session: a session (e.g. gnome)
|
||||
+ *
|
||||
+ * Assigns a new session for @user.
|
||||
+ *
|
||||
+ * Note this function is synchronous and ignores errors.
|
||||
+ **/
|
||||
+void
|
||||
+act_user_set_session (ActUser *user,
|
||||
+ const char *session)
|
||||
+{
|
||||
+ g_autoptr(GError) error = NULL;
|
||||
+
|
||||
+ g_return_if_fail (ACT_IS_USER (user));
|
||||
+ g_return_if_fail (session != NULL);
|
||||
+ g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
|
||||
+
|
||||
+ if (!accounts_user_call_set_session_sync (user->accounts_proxy,
|
||||
+ session,
|
||||
+ NULL,
|
||||
+ &error)) {
|
||||
+ g_warning ("SetSession call failed: %s", error->message);
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * act_user_set_session_type:
|
||||
+ * @user: the user object to alter.
|
||||
+ * @session_type: a type of session (e.g. "wayland" or "x11")
|
||||
+ *
|
||||
+ * Assigns a type to the session for @user.
|
||||
+ *
|
||||
+ * Note this function is synchronous and ignores errors.
|
||||
+ **/
|
||||
+void
|
||||
+act_user_set_session_type (ActUser *user,
|
||||
+ const char *session_type)
|
||||
+{
|
||||
+ g_autoptr(GError) error = NULL;
|
||||
+
|
||||
+ g_return_if_fail (ACT_IS_USER (user));
|
||||
+ g_return_if_fail (session_type != NULL);
|
||||
+ g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
|
||||
+
|
||||
+ if (!accounts_user_call_set_session_type_sync (user->accounts_proxy,
|
||||
+ session_type,
|
||||
+ NULL,
|
||||
+ &error)) {
|
||||
+ g_warning ("SetSessionType call failed: %s", error->message);
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
|
||||
/**
|
||||
* act_user_set_location:
|
||||
* @user: the user object to alter.
|
||||
* @location: a location
|
||||
*
|
||||
* Assigns a new location for @user.
|
||||
*
|
||||
* Note this function is synchronous and ignores errors.
|
||||
**/
|
||||
void
|
||||
act_user_set_location (ActUser *user,
|
||||
const char *location)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_return_if_fail (ACT_IS_USER (user));
|
||||
g_return_if_fail (location != NULL);
|
||||
g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
|
||||
|
||||
if (!accounts_user_call_set_location_sync (user->accounts_proxy,
|
||||
location,
|
||||
NULL,
|
||||
&error)) {
|
||||
g_warning ("SetLocation call failed: %s", error->message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/src/libaccountsservice/act-user.h b/src/libaccountsservice/act-user.h
|
||||
index c685fcc..2ef13b1 100644
|
||||
--- a/src/libaccountsservice/act-user.h
|
||||
+++ b/src/libaccountsservice/act-user.h
|
||||
@@ -51,79 +51,85 @@ typedef struct _ActUserClass ActUserClass;
|
||||
|
||||
GType act_user_get_type (void) G_GNUC_CONST;
|
||||
|
||||
const char *act_user_get_object_path (ActUser *user);
|
||||
|
||||
uid_t act_user_get_uid (ActUser *user);
|
||||
const char *act_user_get_user_name (ActUser *user);
|
||||
const char *act_user_get_real_name (ActUser *user);
|
||||
ActUserAccountType act_user_get_account_type (ActUser *user);
|
||||
ActUserPasswordMode act_user_get_password_mode (ActUser *user);
|
||||
const char *act_user_get_password_hint (ActUser *user);
|
||||
const char *act_user_get_home_dir (ActUser *user);
|
||||
const char *act_user_get_shell (ActUser *user);
|
||||
const char *act_user_get_email (ActUser *user);
|
||||
const char *act_user_get_location (ActUser *user);
|
||||
guint act_user_get_num_sessions (ActUser *user);
|
||||
guint act_user_get_num_sessions_anywhere (ActUser *user);
|
||||
gboolean act_user_is_logged_in (ActUser *user);
|
||||
gboolean act_user_is_logged_in_anywhere (ActUser *user);
|
||||
int act_user_get_login_frequency (ActUser *user);
|
||||
gint64 act_user_get_login_time (ActUser *user);
|
||||
const GVariant*act_user_get_login_history (ActUser *user);
|
||||
gboolean act_user_get_locked (ActUser *user);
|
||||
gboolean act_user_get_automatic_login (ActUser *user);
|
||||
gboolean act_user_is_system_account (ActUser *user);
|
||||
gboolean act_user_is_local_account (ActUser *user);
|
||||
gboolean act_user_is_nonexistent (ActUser *user);
|
||||
const char *act_user_get_icon_file (ActUser *user);
|
||||
const char *act_user_get_language (ActUser *user);
|
||||
const char *act_user_get_x_session (ActUser *user);
|
||||
+const char *act_user_get_session (ActUser *user);
|
||||
+const char *act_user_get_session_type (ActUser *user);
|
||||
const char *act_user_get_primary_session_id (ActUser *user);
|
||||
|
||||
gint act_user_collate (ActUser *user1,
|
||||
ActUser *user2);
|
||||
gboolean act_user_is_loaded (ActUser *user);
|
||||
|
||||
void act_user_get_password_expiration_policy (ActUser *user,
|
||||
gint64 *expiration_time,
|
||||
gint64 *last_change_time,
|
||||
gint64 *min_days_between_changes,
|
||||
gint64 *max_days_between_changes,
|
||||
gint64 *days_to_warn,
|
||||
gint64 *days_after_expiration_until_lock);
|
||||
|
||||
void act_user_set_email (ActUser *user,
|
||||
const char *email);
|
||||
void act_user_set_language (ActUser *user,
|
||||
const char *language);
|
||||
void act_user_set_x_session (ActUser *user,
|
||||
const char *x_session);
|
||||
+void act_user_set_session (ActUser *user,
|
||||
+ const char *session);
|
||||
+void act_user_set_session_type (ActUser *user,
|
||||
+ const char *session_type);
|
||||
void act_user_set_location (ActUser *user,
|
||||
const char *location);
|
||||
void act_user_set_user_name (ActUser *user,
|
||||
const char *user_name);
|
||||
void act_user_set_real_name (ActUser *user,
|
||||
const char *real_name);
|
||||
void act_user_set_icon_file (ActUser *user,
|
||||
const char *icon_file);
|
||||
void act_user_set_account_type (ActUser *user,
|
||||
ActUserAccountType account_type);
|
||||
void act_user_set_password (ActUser *user,
|
||||
const gchar *password,
|
||||
const gchar *hint);
|
||||
void act_user_set_password_hint (ActUser *user,
|
||||
const gchar *hint);
|
||||
void act_user_set_password_mode (ActUser *user,
|
||||
ActUserPasswordMode password_mode);
|
||||
void act_user_set_locked (ActUser *user,
|
||||
gboolean locked);
|
||||
void act_user_set_automatic_login (ActUser *user,
|
||||
gboolean enabled);
|
||||
|
||||
#if GLIB_CHECK_VERSION(2, 44, 0)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ActUser, g_object_unref)
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __ACT_USER_H__ */
|
||||
diff --git a/src/user.c b/src/user.c
|
||||
index 174530f..94c0244 100644
|
||||
--- a/src/user.c
|
||||
+++ b/src/user.c
|
||||
@@ -232,60 +232,75 @@ user_update_from_pwent (User *user,
|
||||
user->account_expiration_policy_known = TRUE;
|
||||
}
|
||||
|
||||
accounts_user_set_password_mode (ACCOUNTS_USER (user), mode);
|
||||
is_system_account = !user_classify_is_human (accounts_user_get_uid (ACCOUNTS_USER (user)),
|
||||
accounts_user_get_user_name (ACCOUNTS_USER (user)),
|
||||
accounts_user_get_shell (ACCOUNTS_USER (user)),
|
||||
passwd);
|
||||
accounts_user_set_system_account (ACCOUNTS_USER (user), is_system_account);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (user));
|
||||
}
|
||||
|
||||
void
|
||||
user_update_from_keyfile (User *user,
|
||||
GKeyFile *keyfile)
|
||||
{
|
||||
gchar *s;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (user));
|
||||
|
||||
s = g_key_file_get_string (keyfile, "User", "Language", NULL);
|
||||
if (s != NULL) {
|
||||
accounts_user_set_language (ACCOUNTS_USER (user), s);
|
||||
g_clear_pointer (&s, g_free);
|
||||
}
|
||||
|
||||
s = g_key_file_get_string (keyfile, "User", "XSession", NULL);
|
||||
if (s != NULL) {
|
||||
accounts_user_set_xsession (ACCOUNTS_USER (user), s);
|
||||
+
|
||||
+ /* for backward compat */
|
||||
+ accounts_user_set_session (ACCOUNTS_USER (user), s);
|
||||
+ g_clear_pointer (&s, g_free);
|
||||
+ }
|
||||
+
|
||||
+ s = g_key_file_get_string (keyfile, "User", "Session", NULL);
|
||||
+ if (s != NULL) {
|
||||
+ accounts_user_set_session (ACCOUNTS_USER (user), s);
|
||||
+ g_clear_pointer (&s, g_free);
|
||||
+ }
|
||||
+
|
||||
+ s = g_key_file_get_string (keyfile, "User", "SessionType", NULL);
|
||||
+ if (s != NULL) {
|
||||
+ accounts_user_set_session_type (ACCOUNTS_USER (user), s);
|
||||
g_clear_pointer (&s, g_free);
|
||||
}
|
||||
|
||||
s = g_key_file_get_string (keyfile, "User", "Email", NULL);
|
||||
if (s != NULL) {
|
||||
accounts_user_set_email (ACCOUNTS_USER (user), s);
|
||||
g_clear_pointer (&s, g_free);
|
||||
}
|
||||
|
||||
s = g_key_file_get_string (keyfile, "User", "Location", NULL);
|
||||
if (s != NULL) {
|
||||
accounts_user_set_location (ACCOUNTS_USER (user), s);
|
||||
g_clear_pointer (&s, g_free);
|
||||
}
|
||||
|
||||
s = g_key_file_get_string (keyfile, "User", "PasswordHint", NULL);
|
||||
if (s != NULL) {
|
||||
accounts_user_set_password_hint (ACCOUNTS_USER (user), s);
|
||||
g_clear_pointer (&s, g_free);
|
||||
}
|
||||
|
||||
s = g_key_file_get_string (keyfile, "User", "Icon", NULL);
|
||||
if (s != NULL) {
|
||||
accounts_user_set_icon_file (ACCOUNTS_USER (user), s);
|
||||
g_clear_pointer (&s, g_free);
|
||||
}
|
||||
|
||||
if (g_key_file_has_key (keyfile, "User", "SystemAccount", NULL)) {
|
||||
gboolean system_account;
|
||||
|
||||
@@ -299,60 +314,66 @@ user_update_from_keyfile (User *user,
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (user));
|
||||
}
|
||||
|
||||
void
|
||||
user_update_local_account_property (User *user,
|
||||
gboolean local)
|
||||
{
|
||||
accounts_user_set_local_account (ACCOUNTS_USER (user), local);
|
||||
}
|
||||
|
||||
void
|
||||
user_update_system_account_property (User *user,
|
||||
gboolean system)
|
||||
{
|
||||
accounts_user_set_system_account (ACCOUNTS_USER (user), system);
|
||||
}
|
||||
|
||||
static void
|
||||
user_save_to_keyfile (User *user,
|
||||
GKeyFile *keyfile)
|
||||
{
|
||||
g_key_file_remove_group (keyfile, "User", NULL);
|
||||
|
||||
if (accounts_user_get_email (ACCOUNTS_USER (user)))
|
||||
g_key_file_set_string (keyfile, "User", "Email", accounts_user_get_email (ACCOUNTS_USER (user)));
|
||||
|
||||
if (accounts_user_get_language (ACCOUNTS_USER (user)))
|
||||
g_key_file_set_string (keyfile, "User", "Language", accounts_user_get_language (ACCOUNTS_USER (user)));
|
||||
|
||||
+ if (accounts_user_get_session (ACCOUNTS_USER (user)))
|
||||
+ g_key_file_set_string (keyfile, "User", "Session", accounts_user_get_session (ACCOUNTS_USER (user)));
|
||||
+
|
||||
+ if (accounts_user_get_session_type (ACCOUNTS_USER (user)))
|
||||
+ g_key_file_set_string (keyfile, "User", "SessionType", accounts_user_get_session_type (ACCOUNTS_USER (user)));
|
||||
+
|
||||
if (accounts_user_get_xsession (ACCOUNTS_USER (user)))
|
||||
g_key_file_set_string (keyfile, "User", "XSession", accounts_user_get_xsession (ACCOUNTS_USER (user)));
|
||||
|
||||
if (accounts_user_get_location (ACCOUNTS_USER (user)))
|
||||
g_key_file_set_string (keyfile, "User", "Location", accounts_user_get_location (ACCOUNTS_USER (user)));
|
||||
|
||||
if (accounts_user_get_password_hint (ACCOUNTS_USER (user)))
|
||||
g_key_file_set_string (keyfile, "User", "PasswordHint", accounts_user_get_password_hint (ACCOUNTS_USER (user)));
|
||||
|
||||
if (accounts_user_get_icon_file (ACCOUNTS_USER (user)))
|
||||
g_key_file_set_string (keyfile, "User", "Icon", accounts_user_get_icon_file (ACCOUNTS_USER (user)));
|
||||
|
||||
g_key_file_set_boolean (keyfile, "User", "SystemAccount", accounts_user_get_system_account (ACCOUNTS_USER (user)));
|
||||
|
||||
user_set_cached (user, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
save_extra_data (User *user)
|
||||
{
|
||||
g_autofree gchar *data = NULL;
|
||||
g_autofree gchar *filename = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
user_save_to_keyfile (user, user->keyfile);
|
||||
|
||||
data = g_key_file_to_data (user->keyfile, NULL, &error);
|
||||
if (data == NULL) {
|
||||
g_warning ("Saving data for user %s failed: %s",
|
||||
accounts_user_get_user_name (ACCOUNTS_USER (user)), error->message);
|
||||
@@ -996,60 +1017,158 @@ static gboolean
|
||||
user_set_language (AccountsUser *auser,
|
||||
GDBusMethodInvocation *context,
|
||||
const gchar *language)
|
||||
{
|
||||
User *user = (User*)auser;
|
||||
int uid;
|
||||
const gchar *action_id;
|
||||
|
||||
if (!get_caller_uid (context, &uid)) {
|
||||
throw_error (context, ERROR_FAILED, "identifying caller failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (accounts_user_get_uid (ACCOUNTS_USER (user)) == (uid_t) uid)
|
||||
action_id = "org.freedesktop.accounts.change-own-user-data";
|
||||
else
|
||||
action_id = "org.freedesktop.accounts.user-administration";
|
||||
|
||||
daemon_local_check_auth (user->daemon,
|
||||
user,
|
||||
action_id,
|
||||
TRUE,
|
||||
user_change_language_authorized_cb,
|
||||
context,
|
||||
g_strdup (language),
|
||||
(GDestroyNotify)g_free);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static void
|
||||
+user_change_session_authorized_cb (Daemon *daemon,
|
||||
+ User *user,
|
||||
+ GDBusMethodInvocation *context,
|
||||
+ gpointer user_data)
|
||||
+
|
||||
+{
|
||||
+ const gchar *session = user_data;
|
||||
+
|
||||
+ if (g_strcmp0 (accounts_user_get_session (ACCOUNTS_USER (user)), session) != 0) {
|
||||
+ accounts_user_set_session (ACCOUNTS_USER (user), session);
|
||||
+
|
||||
+ save_extra_data (user);
|
||||
+ }
|
||||
+
|
||||
+ accounts_user_complete_set_session (ACCOUNTS_USER (user), context);
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+user_set_session (AccountsUser *auser,
|
||||
+ GDBusMethodInvocation *context,
|
||||
+ const gchar *session)
|
||||
+{
|
||||
+ User *user = (User*)auser;
|
||||
+ int uid;
|
||||
+ const gchar *action_id;
|
||||
+
|
||||
+ if (!get_caller_uid (context, &uid)) {
|
||||
+ throw_error (context, ERROR_FAILED, "identifying caller failed");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (accounts_user_get_uid (ACCOUNTS_USER (user)) == (uid_t) uid)
|
||||
+ action_id = "org.freedesktop.accounts.change-own-user-data";
|
||||
+ else
|
||||
+ action_id = "org.freedesktop.accounts.user-administration";
|
||||
+
|
||||
+ daemon_local_check_auth (user->daemon,
|
||||
+ user,
|
||||
+ action_id,
|
||||
+ TRUE,
|
||||
+ user_change_session_authorized_cb,
|
||||
+ context,
|
||||
+ g_strdup (session),
|
||||
+ (GDestroyNotify) g_free);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+user_change_session_type_authorized_cb (Daemon *daemon,
|
||||
+ User *user,
|
||||
+ GDBusMethodInvocation *context,
|
||||
+ gpointer user_data)
|
||||
+
|
||||
+{
|
||||
+ const gchar *session_type = user_data;
|
||||
+
|
||||
+ if (g_strcmp0 (accounts_user_get_session_type (ACCOUNTS_USER (user)), session_type) != 0) {
|
||||
+ accounts_user_set_session_type (ACCOUNTS_USER (user), session_type);
|
||||
+
|
||||
+ save_extra_data (user);
|
||||
+ }
|
||||
+
|
||||
+ accounts_user_complete_set_session_type (ACCOUNTS_USER (user), context);
|
||||
+}
|
||||
+
|
||||
+static gboolean
|
||||
+user_set_session_type (AccountsUser *auser,
|
||||
+ GDBusMethodInvocation *context,
|
||||
+ const gchar *session_type)
|
||||
+{
|
||||
+ User *user = (User*)auser;
|
||||
+ int uid;
|
||||
+ const gchar *action_id;
|
||||
+
|
||||
+ if (!get_caller_uid (context, &uid)) {
|
||||
+ throw_error (context, ERROR_FAILED, "identifying caller failed");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (accounts_user_get_uid (ACCOUNTS_USER (user)) == (uid_t) uid)
|
||||
+ action_id = "org.freedesktop.accounts.change-own-user-data";
|
||||
+ else
|
||||
+ action_id = "org.freedesktop.accounts.user-administration";
|
||||
+
|
||||
+ daemon_local_check_auth (user->daemon,
|
||||
+ user,
|
||||
+ action_id,
|
||||
+ TRUE,
|
||||
+ user_change_session_type_authorized_cb,
|
||||
+ context,
|
||||
+ g_strdup (session_type),
|
||||
+ (GDestroyNotify) g_free);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
user_change_x_session_authorized_cb (Daemon *daemon,
|
||||
User *user,
|
||||
GDBusMethodInvocation *context,
|
||||
gpointer data)
|
||||
|
||||
{
|
||||
gchar *x_session = data;
|
||||
|
||||
if (g_strcmp0 (accounts_user_get_xsession (ACCOUNTS_USER (user)), x_session) != 0) {
|
||||
accounts_user_set_xsession (ACCOUNTS_USER (user), x_session);
|
||||
|
||||
save_extra_data (user);
|
||||
}
|
||||
|
||||
accounts_user_complete_set_xsession (ACCOUNTS_USER (user), context);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
user_set_x_session (AccountsUser *auser,
|
||||
GDBusMethodInvocation *context,
|
||||
const gchar *x_session)
|
||||
{
|
||||
User *user = (User*)auser;
|
||||
int uid;
|
||||
const gchar *action_id;
|
||||
|
||||
if (!get_caller_uid (context, &uid)) {
|
||||
throw_error (context, ERROR_FAILED, "identifying caller failed");
|
||||
return FALSE;
|
||||
@@ -1966,41 +2085,43 @@ user_finalize (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
user_class_init (UserClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
gobject_class->finalize = user_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
user_accounts_user_iface_init (AccountsUserIface *iface)
|
||||
{
|
||||
iface->handle_set_account_type = user_set_account_type;
|
||||
iface->handle_set_automatic_login = user_set_automatic_login;
|
||||
iface->handle_set_email = user_set_email;
|
||||
iface->handle_set_home_directory = user_set_home_directory;
|
||||
iface->handle_set_icon_file = user_set_icon_file;
|
||||
iface->handle_set_language = user_set_language;
|
||||
iface->handle_set_location = user_set_location;
|
||||
iface->handle_set_locked = user_set_locked;
|
||||
iface->handle_set_password = user_set_password;
|
||||
iface->handle_set_password_mode = user_set_password_mode;
|
||||
iface->handle_set_password_hint = user_set_password_hint;
|
||||
iface->handle_set_real_name = user_set_real_name;
|
||||
iface->handle_set_shell = user_set_shell;
|
||||
iface->handle_set_user_name = user_set_user_name;
|
||||
iface->handle_set_xsession = user_set_x_session;
|
||||
+ iface->handle_set_session = user_set_session;
|
||||
+ iface->handle_set_session_type = user_set_session_type;
|
||||
iface->handle_get_password_expiration_policy = user_get_password_expiration_policy;
|
||||
}
|
||||
|
||||
static void
|
||||
user_init (User *user)
|
||||
{
|
||||
user->system_bus_connection = NULL;
|
||||
user->default_icon_file = NULL;
|
||||
user->login_history = NULL;
|
||||
user->keyfile = g_key_file_new ();
|
||||
}
|
||||
--
|
||||
2.17.1
|
||||
|
629
SOURCES/0002-user-export-new-Saved-property.patch
Normal file
629
SOURCES/0002-user-export-new-Saved-property.patch
Normal file
@ -0,0 +1,629 @@
|
||||
From 14bb1237f71e38749558c74963032a0387eecec0 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Wed, 15 Aug 2018 16:04:42 -0400
|
||||
Subject: [PATCH 2/2] user: export new Saved property
|
||||
|
||||
accountsservice maintains a state file for some users, if those users
|
||||
have selected a specific session or language.
|
||||
|
||||
There's no good way, at the moment, for an application to check if a
|
||||
specific user has saved state.
|
||||
|
||||
This commit exports the Saved property on the User object.
|
||||
---
|
||||
data/org.freedesktop.Accounts.User.xml | 10 ++++++++++
|
||||
src/daemon.c | 3 +++
|
||||
src/libaccountsservice/act-user.c | 19 +++++++++++++++++++
|
||||
src/libaccountsservice/act-user.h | 1 +
|
||||
src/user.c | 10 ++++++++++
|
||||
src/user.h | 2 ++
|
||||
6 files changed, 45 insertions(+)
|
||||
|
||||
diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml
|
||||
index 7fc3c61..8d3fe1c 100644
|
||||
--- a/data/org.freedesktop.Accounts.User.xml
|
||||
+++ b/data/org.freedesktop.Accounts.User.xml
|
||||
@@ -811,60 +811,70 @@
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="LoginHistory" type="a(xxa{sv})" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The login history for this user.
|
||||
Each entry in the array represents a login session. The first two
|
||||
members are the login time and logout time, as timestamps (seconds since the epoch). If the session is still running, the logout time
|
||||
is 0.
|
||||
</doc:para>
|
||||
<doc:para>
|
||||
The a{sv} member is a dictionary containing additional information
|
||||
about the session. Possible members include 'type' (with values like ':0', 'tty0', 'pts/0' etc).
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="IconFile" type="s" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The filename of a png file containing the users icon.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
+ <property name="Saved" type="b" access="read">
|
||||
+ <doc:doc>
|
||||
+ <doc:description>
|
||||
+ <doc:para>
|
||||
+ Whether the users account has retained state
|
||||
+ </doc:para>
|
||||
+ </doc:description>
|
||||
+ </doc:doc>
|
||||
+ </property>
|
||||
+
|
||||
<property name="Locked" type="b" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
Whether the users account is locked.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<property name="PasswordMode" type="i" access="read">
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The password mode for the user account, encoded as an integer:
|
||||
<doc:list>
|
||||
<doc:item>
|
||||
<doc:term>0</doc:term>
|
||||
<doc:definition>Regular password</doc:definition>
|
||||
</doc:item>
|
||||
<doc:item>
|
||||
<doc:term>1</doc:term>
|
||||
<doc:definition>Password must be set at next login</doc:definition>
|
||||
</doc:item>
|
||||
<doc:item>
|
||||
<doc:term>2</doc:term>
|
||||
<doc:definition>No password</doc:definition>
|
||||
</doc:item>
|
||||
</doc:list>
|
||||
</doc:para>
|
||||
diff --git a/src/daemon.c b/src/daemon.c
|
||||
index 2851ed6..2587b8a 100644
|
||||
--- a/src/daemon.c
|
||||
+++ b/src/daemon.c
|
||||
@@ -1187,60 +1187,61 @@ daemon_cache_user (AccountsAccounts *accounts,
|
||||
context,
|
||||
g_strdup (user_name),
|
||||
g_free);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
daemon_uncache_user_authorized_cb (Daemon *daemon,
|
||||
User *dummy,
|
||||
GDBusMethodInvocation *context,
|
||||
gpointer data)
|
||||
{
|
||||
const gchar *user_name = data;
|
||||
User *user;
|
||||
|
||||
sys_log (context, "uncache user '%s'", user_name);
|
||||
|
||||
user = daemon_local_find_user_by_name (daemon, user_name);
|
||||
if (user == NULL) {
|
||||
throw_error (context, ERROR_USER_DOES_NOT_EXIST,
|
||||
"No user with the name %s found", user_name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Always use the canonical user name looked up */
|
||||
user_name = user_get_user_name (user);
|
||||
|
||||
remove_cache_files (user_name);
|
||||
|
||||
+ user_set_saved (user, FALSE);
|
||||
user_set_cached (user, FALSE);
|
||||
|
||||
accounts_accounts_complete_uncache_user (NULL, context);
|
||||
|
||||
queue_reload_users (daemon);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
daemon_uncache_user (AccountsAccounts *accounts,
|
||||
GDBusMethodInvocation *context,
|
||||
const gchar *user_name)
|
||||
{
|
||||
Daemon *daemon = (Daemon*)accounts;
|
||||
|
||||
daemon_local_check_auth (daemon,
|
||||
NULL,
|
||||
"org.freedesktop.accounts.user-administration",
|
||||
TRUE,
|
||||
daemon_uncache_user_authorized_cb,
|
||||
context,
|
||||
g_strdup (user_name),
|
||||
g_free);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uid_t uid;
|
||||
gboolean remove_files;
|
||||
} DeleteUserData;
|
||||
@@ -1252,60 +1253,62 @@ daemon_delete_user_authorized_cb (Daemon *daemon,
|
||||
gpointer data)
|
||||
|
||||
{
|
||||
DeleteUserData *ud = data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
struct passwd *pwent;
|
||||
const gchar *argv[6];
|
||||
User *user;
|
||||
|
||||
pwent = getpwuid (ud->uid);
|
||||
|
||||
if (pwent == NULL) {
|
||||
throw_error (context, ERROR_USER_DOES_NOT_EXIST, "No user with uid %d found", ud->uid);
|
||||
return;
|
||||
}
|
||||
|
||||
sys_log (context, "delete user '%s' (%d)", pwent->pw_name, ud->uid);
|
||||
|
||||
user = daemon_local_find_user_by_id (daemon, ud->uid);
|
||||
|
||||
if (user != NULL) {
|
||||
user_set_cached (user, FALSE);
|
||||
|
||||
if (daemon->priv->autologin == user) {
|
||||
daemon_local_set_automatic_login (daemon, user, FALSE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
remove_cache_files (pwent->pw_name);
|
||||
|
||||
+ user_set_saved (user, FALSE);
|
||||
+
|
||||
argv[0] = "/usr/sbin/userdel";
|
||||
if (ud->remove_files) {
|
||||
argv[1] = "-f";
|
||||
argv[2] = "-r";
|
||||
argv[3] = "--";
|
||||
argv[4] = pwent->pw_name;
|
||||
argv[5] = NULL;
|
||||
}
|
||||
else {
|
||||
argv[1] = "-f";
|
||||
argv[2] = "--";
|
||||
argv[3] = pwent->pw_name;
|
||||
argv[4] = NULL;
|
||||
}
|
||||
|
||||
if (!spawn_with_login_uid (context, argv, &error)) {
|
||||
throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
accounts_accounts_complete_delete_user (NULL, context);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
daemon_delete_user (AccountsAccounts *accounts,
|
||||
GDBusMethodInvocation *context,
|
||||
gint64 uid,
|
||||
gboolean remove_files)
|
||||
{
|
||||
diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c
|
||||
index dd8f81b..540ffe7 100644
|
||||
--- a/src/libaccountsservice/act-user.c
|
||||
+++ b/src/libaccountsservice/act-user.c
|
||||
@@ -849,60 +849,79 @@ act_user_collate (ActUser *user1,
|
||||
*
|
||||
* Returns whether or not #ActUser is currently graphically logged in
|
||||
* on the same seat as the seat of the session of the calling process.
|
||||
*
|
||||
* Returns: %TRUE or %FALSE
|
||||
*/
|
||||
gboolean
|
||||
act_user_is_logged_in (ActUser *user)
|
||||
{
|
||||
return user->our_sessions != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* act_user_is_logged_in_anywhere:
|
||||
* @user: a #ActUser
|
||||
*
|
||||
* Returns whether or not #ActUser is currently logged in in any way
|
||||
* whatsoever. See also act_user_is_logged_in().
|
||||
*
|
||||
* (Currently, this function is only implemented for systemd-logind.
|
||||
* For ConsoleKit, it is equivalent to act_user_is_logged_in.)
|
||||
*
|
||||
* Returns: %TRUE or %FALSE
|
||||
*/
|
||||
gboolean
|
||||
act_user_is_logged_in_anywhere (ActUser *user)
|
||||
{
|
||||
return user->our_sessions != NULL || user->other_sessions != NULL;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * act_user_get_saved:
|
||||
+ * @user: a #ActUser
|
||||
+ *
|
||||
+ * Returns whether or not the #ActUser account has retained state in accountsservice.
|
||||
+ *
|
||||
+ * Returns: %TRUE or %FALSE
|
||||
+ */
|
||||
+gboolean
|
||||
+act_user_get_saved (ActUser *user)
|
||||
+{
|
||||
+ g_return_val_if_fail (ACT_IS_USER (user), TRUE);
|
||||
+
|
||||
+ if (user->accounts_proxy == NULL)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return accounts_user_get_saved (user->accounts_proxy);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* act_user_get_locked:
|
||||
* @user: a #ActUser
|
||||
*
|
||||
* Returns whether or not the #ActUser account is locked.
|
||||
*
|
||||
* Returns: %TRUE or %FALSE
|
||||
*/
|
||||
gboolean
|
||||
act_user_get_locked (ActUser *user)
|
||||
{
|
||||
g_return_val_if_fail (ACT_IS_USER (user), TRUE);
|
||||
|
||||
if (user->accounts_proxy == NULL)
|
||||
return TRUE;
|
||||
|
||||
return accounts_user_get_locked (user->accounts_proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* act_user_get_automatic_login:
|
||||
* @user: a #ActUser
|
||||
*
|
||||
* Returns whether or not #ActUser is automatically logged in at boot time.
|
||||
*
|
||||
* Returns: %TRUE or %FALSE
|
||||
*/
|
||||
gboolean
|
||||
act_user_get_automatic_login (ActUser *user)
|
||||
{
|
||||
diff --git a/src/libaccountsservice/act-user.h b/src/libaccountsservice/act-user.h
|
||||
index 2ef13b1..34d7fe3 100644
|
||||
--- a/src/libaccountsservice/act-user.h
|
||||
+++ b/src/libaccountsservice/act-user.h
|
||||
@@ -43,60 +43,61 @@ typedef enum {
|
||||
typedef enum {
|
||||
ACT_USER_PASSWORD_MODE_REGULAR,
|
||||
ACT_USER_PASSWORD_MODE_SET_AT_LOGIN,
|
||||
ACT_USER_PASSWORD_MODE_NONE,
|
||||
} ActUserPasswordMode;
|
||||
|
||||
typedef struct _ActUser ActUser;
|
||||
typedef struct _ActUserClass ActUserClass;
|
||||
|
||||
GType act_user_get_type (void) G_GNUC_CONST;
|
||||
|
||||
const char *act_user_get_object_path (ActUser *user);
|
||||
|
||||
uid_t act_user_get_uid (ActUser *user);
|
||||
const char *act_user_get_user_name (ActUser *user);
|
||||
const char *act_user_get_real_name (ActUser *user);
|
||||
ActUserAccountType act_user_get_account_type (ActUser *user);
|
||||
ActUserPasswordMode act_user_get_password_mode (ActUser *user);
|
||||
const char *act_user_get_password_hint (ActUser *user);
|
||||
const char *act_user_get_home_dir (ActUser *user);
|
||||
const char *act_user_get_shell (ActUser *user);
|
||||
const char *act_user_get_email (ActUser *user);
|
||||
const char *act_user_get_location (ActUser *user);
|
||||
guint act_user_get_num_sessions (ActUser *user);
|
||||
guint act_user_get_num_sessions_anywhere (ActUser *user);
|
||||
gboolean act_user_is_logged_in (ActUser *user);
|
||||
gboolean act_user_is_logged_in_anywhere (ActUser *user);
|
||||
int act_user_get_login_frequency (ActUser *user);
|
||||
gint64 act_user_get_login_time (ActUser *user);
|
||||
const GVariant*act_user_get_login_history (ActUser *user);
|
||||
+gboolean act_user_get_saved (ActUser *user);
|
||||
gboolean act_user_get_locked (ActUser *user);
|
||||
gboolean act_user_get_automatic_login (ActUser *user);
|
||||
gboolean act_user_is_system_account (ActUser *user);
|
||||
gboolean act_user_is_local_account (ActUser *user);
|
||||
gboolean act_user_is_nonexistent (ActUser *user);
|
||||
const char *act_user_get_icon_file (ActUser *user);
|
||||
const char *act_user_get_language (ActUser *user);
|
||||
const char *act_user_get_x_session (ActUser *user);
|
||||
const char *act_user_get_session (ActUser *user);
|
||||
const char *act_user_get_session_type (ActUser *user);
|
||||
const char *act_user_get_primary_session_id (ActUser *user);
|
||||
|
||||
gint act_user_collate (ActUser *user1,
|
||||
ActUser *user2);
|
||||
gboolean act_user_is_loaded (ActUser *user);
|
||||
|
||||
void act_user_get_password_expiration_policy (ActUser *user,
|
||||
gint64 *expiration_time,
|
||||
gint64 *last_change_time,
|
||||
gint64 *min_days_between_changes,
|
||||
gint64 *max_days_between_changes,
|
||||
gint64 *days_to_warn,
|
||||
gint64 *days_after_expiration_until_lock);
|
||||
|
||||
void act_user_set_email (ActUser *user,
|
||||
const char *email);
|
||||
void act_user_set_language (ActUser *user,
|
||||
const char *language);
|
||||
void act_user_set_x_session (ActUser *user,
|
||||
const char *x_session);
|
||||
diff --git a/src/user.c b/src/user.c
|
||||
index 94c0244..93afadc 100644
|
||||
--- a/src/user.c
|
||||
+++ b/src/user.c
|
||||
@@ -284,60 +284,61 @@ user_update_from_keyfile (User *user,
|
||||
}
|
||||
|
||||
s = g_key_file_get_string (keyfile, "User", "Location", NULL);
|
||||
if (s != NULL) {
|
||||
accounts_user_set_location (ACCOUNTS_USER (user), s);
|
||||
g_clear_pointer (&s, g_free);
|
||||
}
|
||||
|
||||
s = g_key_file_get_string (keyfile, "User", "PasswordHint", NULL);
|
||||
if (s != NULL) {
|
||||
accounts_user_set_password_hint (ACCOUNTS_USER (user), s);
|
||||
g_clear_pointer (&s, g_free);
|
||||
}
|
||||
|
||||
s = g_key_file_get_string (keyfile, "User", "Icon", NULL);
|
||||
if (s != NULL) {
|
||||
accounts_user_set_icon_file (ACCOUNTS_USER (user), s);
|
||||
g_clear_pointer (&s, g_free);
|
||||
}
|
||||
|
||||
if (g_key_file_has_key (keyfile, "User", "SystemAccount", NULL)) {
|
||||
gboolean system_account;
|
||||
|
||||
system_account = g_key_file_get_boolean (keyfile, "User", "SystemAccount", NULL);
|
||||
accounts_user_set_system_account (ACCOUNTS_USER (user), system_account);
|
||||
}
|
||||
|
||||
g_clear_pointer (&user->keyfile, g_key_file_unref);
|
||||
user->keyfile = g_key_file_ref (keyfile);
|
||||
user_set_cached (user, TRUE);
|
||||
+ user_set_saved (user, TRUE);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (user));
|
||||
}
|
||||
|
||||
void
|
||||
user_update_local_account_property (User *user,
|
||||
gboolean local)
|
||||
{
|
||||
accounts_user_set_local_account (ACCOUNTS_USER (user), local);
|
||||
}
|
||||
|
||||
void
|
||||
user_update_system_account_property (User *user,
|
||||
gboolean system)
|
||||
{
|
||||
accounts_user_set_system_account (ACCOUNTS_USER (user), system);
|
||||
}
|
||||
|
||||
static void
|
||||
user_save_to_keyfile (User *user,
|
||||
GKeyFile *keyfile)
|
||||
{
|
||||
g_key_file_remove_group (keyfile, "User", NULL);
|
||||
|
||||
if (accounts_user_get_email (ACCOUNTS_USER (user)))
|
||||
g_key_file_set_string (keyfile, "User", "Email", accounts_user_get_email (ACCOUNTS_USER (user)));
|
||||
|
||||
if (accounts_user_get_language (ACCOUNTS_USER (user)))
|
||||
g_key_file_set_string (keyfile, "User", "Language", accounts_user_get_language (ACCOUNTS_USER (user)));
|
||||
|
||||
@@ -357,60 +358,62 @@ user_save_to_keyfile (User *user,
|
||||
g_key_file_set_string (keyfile, "User", "PasswordHint", accounts_user_get_password_hint (ACCOUNTS_USER (user)));
|
||||
|
||||
if (accounts_user_get_icon_file (ACCOUNTS_USER (user)))
|
||||
g_key_file_set_string (keyfile, "User", "Icon", accounts_user_get_icon_file (ACCOUNTS_USER (user)));
|
||||
|
||||
g_key_file_set_boolean (keyfile, "User", "SystemAccount", accounts_user_get_system_account (ACCOUNTS_USER (user)));
|
||||
|
||||
user_set_cached (user, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
save_extra_data (User *user)
|
||||
{
|
||||
g_autofree gchar *data = NULL;
|
||||
g_autofree gchar *filename = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
user_save_to_keyfile (user, user->keyfile);
|
||||
|
||||
data = g_key_file_to_data (user->keyfile, NULL, &error);
|
||||
if (data == NULL) {
|
||||
g_warning ("Saving data for user %s failed: %s",
|
||||
accounts_user_get_user_name (ACCOUNTS_USER (user)), error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
filename = g_build_filename (USERDIR,
|
||||
accounts_user_get_user_name (ACCOUNTS_USER (user)),
|
||||
NULL);
|
||||
g_file_set_contents (filename, data, -1, &error);
|
||||
+
|
||||
+ user_set_saved (user, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
move_extra_data (const gchar *old_name,
|
||||
const gchar *new_name)
|
||||
{
|
||||
g_autofree gchar *old_filename = NULL;
|
||||
g_autofree gchar *new_filename = NULL;
|
||||
|
||||
old_filename = g_build_filename (USERDIR,
|
||||
old_name, NULL);
|
||||
new_filename = g_build_filename (USERDIR,
|
||||
new_name, NULL);
|
||||
|
||||
g_rename (old_filename, new_filename);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
user_extension_get_value (User *user,
|
||||
GDBusInterfaceInfo *interface,
|
||||
const GDBusPropertyInfo *property)
|
||||
{
|
||||
const GVariantType *type = G_VARIANT_TYPE (property->signature);
|
||||
GVariant *value;
|
||||
g_autofree gchar *printed = NULL;
|
||||
gint i;
|
||||
|
||||
/* First, try to get the value from the keyfile */
|
||||
printed = g_key_file_get_value (user->keyfile, interface->name, property->name, NULL);
|
||||
if (printed) {
|
||||
@@ -773,60 +776,67 @@ const gchar *
|
||||
user_get_object_path (User *user)
|
||||
{
|
||||
return g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (user));
|
||||
}
|
||||
|
||||
uid_t
|
||||
user_get_uid (User *user)
|
||||
{
|
||||
return accounts_user_get_uid (ACCOUNTS_USER (user));
|
||||
}
|
||||
|
||||
const gchar *
|
||||
user_get_shell(User *user)
|
||||
{
|
||||
return accounts_user_get_shell (ACCOUNTS_USER (user));
|
||||
}
|
||||
|
||||
gboolean
|
||||
user_get_cached (User *user)
|
||||
{
|
||||
return user->cached;
|
||||
}
|
||||
|
||||
void
|
||||
user_set_cached (User *user,
|
||||
gboolean cached)
|
||||
{
|
||||
user->cached = cached;
|
||||
}
|
||||
|
||||
+void
|
||||
+user_set_saved (User *user,
|
||||
+ gboolean saved)
|
||||
+{
|
||||
+ accounts_user_set_saved (ACCOUNTS_USER (user), saved);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
throw_error (GDBusMethodInvocation *context,
|
||||
gint error_code,
|
||||
const gchar *format,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
g_autofree gchar *message = NULL;
|
||||
|
||||
va_start (args, format);
|
||||
message = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
|
||||
g_dbus_method_invocation_return_error (context, ERROR, error_code, "%s", message);
|
||||
}
|
||||
|
||||
static void
|
||||
user_change_real_name_authorized_cb (Daemon *daemon,
|
||||
User *user,
|
||||
GDBusMethodInvocation *context,
|
||||
gpointer data)
|
||||
|
||||
{
|
||||
gchar *name = data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
const gchar *argv[6];
|
||||
|
||||
if (g_strcmp0 (accounts_user_get_real_name (ACCOUNTS_USER (user)), name) != 0) {
|
||||
sys_log (context,
|
||||
"change real name of user '%s' (%d) to '%s'",
|
||||
diff --git a/src/user.h b/src/user.h
|
||||
index 39c6f13..b3b3380 100644
|
||||
--- a/src/user.h
|
||||
+++ b/src/user.h
|
||||
@@ -39,47 +39,49 @@ typedef enum {
|
||||
ACCOUNT_TYPE_STANDARD,
|
||||
ACCOUNT_TYPE_ADMINISTRATOR,
|
||||
#define ACCOUNT_TYPE_LAST ACCOUNT_TYPE_ADMINISTRATOR
|
||||
} AccountType;
|
||||
|
||||
typedef enum {
|
||||
PASSWORD_MODE_REGULAR,
|
||||
PASSWORD_MODE_SET_AT_LOGIN,
|
||||
PASSWORD_MODE_NONE,
|
||||
#define PASSWORD_MODE_LAST PASSWORD_MODE_NONE
|
||||
} PasswordMode;
|
||||
|
||||
/* local methods */
|
||||
|
||||
GType user_get_type (void) G_GNUC_CONST;
|
||||
User * user_new (Daemon *daemon,
|
||||
uid_t uid);
|
||||
|
||||
void user_update_from_pwent (User *user,
|
||||
struct passwd *pwent,
|
||||
struct spwd *spent);
|
||||
void user_update_from_keyfile (User *user,
|
||||
GKeyFile *keyfile);
|
||||
void user_update_local_account_property (User *user,
|
||||
gboolean local);
|
||||
void user_update_system_account_property (User *user,
|
||||
gboolean system);
|
||||
gboolean user_get_cached (User *user);
|
||||
void user_set_cached (User *user,
|
||||
gboolean cached);
|
||||
+void user_set_saved (User *user,
|
||||
+ gboolean saved);
|
||||
|
||||
void user_register (User *user);
|
||||
void user_unregister (User *user);
|
||||
void user_changed (User *user);
|
||||
|
||||
void user_save (User *user);
|
||||
|
||||
const gchar * user_get_user_name (User *user);
|
||||
gboolean user_get_system_account (User *user);
|
||||
gboolean user_get_local_account (User *user);
|
||||
const gchar * user_get_object_path (User *user);
|
||||
uid_t user_get_uid (User *user);
|
||||
const gchar * user_get_shell (User *user);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
--
|
||||
2.17.1
|
||||
|
357
SPECS/accountsservice.spec
Normal file
357
SPECS/accountsservice.spec
Normal file
@ -0,0 +1,357 @@
|
||||
%global _hardened_build 1
|
||||
|
||||
Name: accountsservice
|
||||
Version: 0.6.50
|
||||
Release: 7%{?dist}
|
||||
Summary: D-Bus interfaces for querying and manipulating user account information
|
||||
License: GPLv3+
|
||||
URL: https://www.freedesktop.org/wiki/Software/AccountsService/
|
||||
|
||||
#VCS: git:git://git.freedesktop.org/accountsservice
|
||||
Source0: http://www.freedesktop.org/software/accountsservice/accountsservice-%{version}.tar.xz
|
||||
|
||||
BuildRequires: glib2-devel
|
||||
BuildRequires: polkit-devel
|
||||
BuildRequires: libtool, automake, autoconf, gettext-devel, intltool
|
||||
BuildRequires: systemd
|
||||
BuildRequires: systemd-devel
|
||||
BuildRequires: gobject-introspection-devel
|
||||
BuildRequires: gtk-doc
|
||||
BuildRequires: git
|
||||
|
||||
Patch01: 0001-user-add-new-Session-SessionType-properties-to-repla.patch
|
||||
Patch02: 0002-user-export-new-Saved-property.patch
|
||||
|
||||
Patch10: 0001-daemon-Fix-warnings-about-type-punning.patch
|
||||
|
||||
Patch20: 0001-lib-don-t-set-loaded-state-until-seat-is-fetched.patch
|
||||
|
||||
Patch30: 0001-data-don-t-send-change-updates-for-login-history.patch
|
||||
|
||||
Patch90: 0001-lib-save-os-when-creating-user.patch
|
||||
|
||||
Requires: polkit
|
||||
Requires: shadow-utils
|
||||
%{?systemd_requires}
|
||||
|
||||
%description
|
||||
The accountsservice project provides a set of D-Bus interfaces for
|
||||
querying and manipulating user account information and an implementation
|
||||
of these interfaces, based on the useradd, usermod and userdel commands.
|
||||
|
||||
%package libs
|
||||
Summary: Client-side library to talk to accountsservice
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
|
||||
%description libs
|
||||
The accountsservice-libs package contains a library that can
|
||||
be used by applications that want to interact with the accountsservice
|
||||
daemon.
|
||||
|
||||
%package devel
|
||||
Summary: Development files for accountsservice-libs
|
||||
Requires: %{name}-libs = %{version}-%{release}
|
||||
|
||||
%description devel
|
||||
The accountsservice-devel package contains headers and other
|
||||
files needed to build applications that use accountsservice-libs.
|
||||
|
||||
|
||||
%prep
|
||||
%autosetup -S git
|
||||
autoreconf -f -i
|
||||
|
||||
%build
|
||||
export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
|
||||
%configure --enable-user-heuristics
|
||||
make %{?_smp_mflags}
|
||||
|
||||
|
||||
%install
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
rm $RPM_BUILD_ROOT%{_libdir}/*.la
|
||||
rm $RPM_BUILD_ROOT%{_libdir}/*.a
|
||||
%find_lang accounts-service
|
||||
|
||||
%ldconfig_scriptlets libs
|
||||
|
||||
%post
|
||||
%systemd_post accounts-daemon.service
|
||||
|
||||
%preun
|
||||
%systemd_preun accounts-daemon.service
|
||||
|
||||
%postun
|
||||
%systemd_postun accounts-daemon.service
|
||||
|
||||
%files -f accounts-service.lang
|
||||
%license COPYING
|
||||
%doc README AUTHORS
|
||||
%{_sysconfdir}/dbus-1/system.d/org.freedesktop.Accounts.conf
|
||||
%{_libexecdir}/accounts-daemon
|
||||
%{_datadir}/dbus-1/interfaces/org.freedesktop.Accounts.xml
|
||||
%{_datadir}/dbus-1/interfaces/org.freedesktop.Accounts.User.xml
|
||||
%{_datadir}/dbus-1/system-services/org.freedesktop.Accounts.service
|
||||
%{_datadir}/polkit-1/actions/org.freedesktop.accounts.policy
|
||||
%{_datadir}/accountsservice/interfaces/com.redhat.AccountsServiceUser.System.xml
|
||||
%{_datadir}/dbus-1/interfaces/com.redhat.AccountsServiceUser.System.xml
|
||||
%dir %{_localstatedir}/lib/AccountsService/
|
||||
%dir %{_localstatedir}/lib/AccountsService/users
|
||||
%dir %{_localstatedir}/lib/AccountsService/icons
|
||||
%{_unitdir}/accounts-daemon.service
|
||||
|
||||
%files libs
|
||||
%{_libdir}/libaccountsservice.so.*
|
||||
%{_libdir}/girepository-1.0/AccountsService-1.0.typelib
|
||||
|
||||
%files devel
|
||||
%{_includedir}/accountsservice-1.0
|
||||
%{_libdir}/libaccountsservice.so
|
||||
%{_libdir}/pkgconfig/accountsservice.pc
|
||||
%{_datadir}/gir-1.0/AccountsService-1.0.gir
|
||||
%dir %{_datadir}/gtk-doc/html/libaccountsservice
|
||||
%{_datadir}/gtk-doc/html/libaccountsservice/*
|
||||
|
||||
%changelog
|
||||
* Mon Jun 17 2019 Ray Strode <rstrode@redhat.com> - 0.6.50-7
|
||||
- Don't send change updates for login history changes
|
||||
Resolves: #1713080
|
||||
|
||||
* Mon Nov 26 2018 Ray Strode <rstrode@redhat.com> - 0.6.50-6
|
||||
- Fix user switching before screen lock
|
||||
Resolves: #1653263
|
||||
|
||||
* Mon Oct 15 2018 Ray Strode <rstrode@redhat.com> - 0.6.50-5
|
||||
- Turn off aliasing optimizations until glib codegen is fixed
|
||||
Related: #1628060 1639428
|
||||
|
||||
* Fri Oct 12 2018 Ray Strode <rstrode@redhat.com> - 0.6.50-4
|
||||
Correct rpmdiff complaints
|
||||
Related: #1628060
|
||||
|
||||
* Fri Oct 12 2018 Ray Strode <rstrode@redhat.com> - 0.6.50-3
|
||||
- Record OS in user data when creating new users
|
||||
Related: #1628060
|
||||
|
||||
* Mon Aug 20 2018 Ray Strode <rstrode@redhat.com> - 0.6.50-2
|
||||
- add new api needed for handling upgrades from RHEL 7
|
||||
Related: #1612915 1595825
|
||||
|
||||
* Fri Jul 13 2018 Ray Strode <rstrode@redhat.com> - 0.6.50-1
|
||||
- Update to 0.6.50
|
||||
Related: #1597499
|
||||
|
||||
* Tue Apr 24 2018 Ray Strode <rstrode@redhat.com> - 0.6.47-1
|
||||
- Update to 0.6.47
|
||||
|
||||
* Sat Apr 21 2018 Peter Robinson <pbrobinson@fedoraproject.org> 0.4.46-1
|
||||
- Update to 0.6.46
|
||||
- Spec cleanup, use %%license
|
||||
|
||||
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.6.42-9
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
||||
|
||||
* Sun Feb 04 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 0.6.42-8
|
||||
- Switch to %%ldconfig_scriptlets
|
||||
|
||||
* Thu Jan 25 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 0.6.42-7
|
||||
- Fix systemd executions/requirements
|
||||
|
||||
* Wed Jan 24 2018 Ray Strode <rstrode@redhat.com> - 0.6.42-6
|
||||
- Fix crash introduced by glibc/libxcrypt change
|
||||
https://fedoraproject.org/wiki/Changes/Replace_glibc_libcrypt_with_libxcrypt
|
||||
Resolves: #1538181
|
||||
|
||||
* Sat Jan 20 2018 Björn Esser <besser82@fedoraproject.org> - 0.6.42-5
|
||||
- Rebuilt for switch to libxcrypt
|
||||
|
||||
* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.6.42-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
|
||||
|
||||
* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.6.42-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
|
||||
|
||||
* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.6.42-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
|
||||
|
||||
* Thu Jun 09 2016 Ray Strode <rstrode@redhat.com> - 0.6.42-1
|
||||
- Update to 0.6.42
|
||||
- Fixes systemd incompatibility
|
||||
|
||||
* Tue May 31 2016 Ray Strode <rstrode@redhat.com> - 0.6.40-4
|
||||
- Don't create /root/.cache at startup
|
||||
Resolves: #1331926
|
||||
|
||||
* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 0.6.40-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
|
||||
|
||||
* Tue Jun 16 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.40-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
|
||||
|
||||
* Fri Jan 23 2015 Ray Strode <rstrode@redhat.com> 0.6.40-1
|
||||
- Update to 0.6.40
|
||||
|
||||
* Fri Oct 17 2014 Ray Strode <rstrode@redhat.com> 0.6.39-2
|
||||
- More ListCachedUsers race fixes (this time with SSSD)
|
||||
Related: #1147504
|
||||
|
||||
* Thu Oct 16 2014 Ray Strode <rstrode@redhat.com> 0.6.39-1
|
||||
- Update to 0.6.39
|
||||
- Fixes ListCachedUsers race at startup
|
||||
|
||||
* Thu Sep 18 2014 Stef Walter <stefw@redhat.com> - 0.6.38-1
|
||||
- Update to 0.6.38
|
||||
- Fixes polkit policy rhbz#1094138
|
||||
- Remove dbus-glib-devel dependency, accountsservice uses gdbus now
|
||||
|
||||
* Fri Aug 15 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.37-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
|
||||
|
||||
* Tue Jul 22 2014 Kalev Lember <kalevlember@gmail.com> - 0.6.37-2
|
||||
- Rebuilt for gobject-introspection 1.41.4
|
||||
|
||||
* Sat Jun 07 2014 Kalev Lember <kalevlember@gmail.com> - 0.6.37-1
|
||||
- Update to 0.6.37, drop upstreamed patches
|
||||
|
||||
* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.35-5
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
|
||||
|
||||
* Fri Jan 10 2014 Matthias Clasen <mclasen@redhat.com> - 0.6.35-4
|
||||
- Consistently call userdel with -f
|
||||
|
||||
* Wed Nov 20 2013 Ray Strode <rstrode@redhat.com> 0.6.35-3
|
||||
- Only treat users < 1000 as system users
|
||||
- only use user heuristics on the range 500-1000
|
||||
|
||||
* Mon Nov 11 2013 Ray Strode <rstrode@redhat.com> 0.6.35-2
|
||||
- pass --enable-user-heuristics which fedora needs so users
|
||||
with UIDs less than 1000 show up in the user list.
|
||||
|
||||
* Mon Oct 28 2013 Ray Strode <rstrode@redhat.com> 0.6.35-1
|
||||
- Update to 0.6.35
|
||||
Related: #1013721
|
||||
|
||||
* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.34-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
|
||||
|
||||
* Tue Jun 11 2013 Ray Strode <rstrode@redhat.com> 0.6.34-1
|
||||
- Update to 0.6.34
|
||||
|
||||
* Tue Jun 11 2013 Matthias Clasen <mclasen@redhat.com> - 0.6.33-1
|
||||
- Update to 0.6.33
|
||||
|
||||
* Tue May 14 2013 Matthias Clasen <mclasen@redhat.com> - 0.6.32-1
|
||||
- Update to 0.6.32
|
||||
|
||||
* Thu Apr 18 2013 Matthias Clasen <mclasen@redhat.com> - 0.6.31-2
|
||||
- Hardened build
|
||||
|
||||
* Tue Apr 16 2013 Matthias Clasen <mclasen@redhat.com> - 0.6.31-1
|
||||
- Update to 0.6.31
|
||||
|
||||
* Wed Feb 13 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.30-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
|
||||
|
||||
* Wed Jan 16 2013 Richard Hughes <rhughes@redhat.com> - 0.6.30-1
|
||||
- Update to 0.6.30
|
||||
|
||||
* Fri Nov 16 2012 Matthias Clasen <mclasen@redhat.com> - 0.6.26-1
|
||||
- Update to 0.6.26
|
||||
|
||||
* Tue Oct 2 2012 Matthias Clasen <mclasen@redhat.com> - 0.6.25-2
|
||||
- Update to 0.6.25
|
||||
- Use systemd scriptlets (#856649)
|
||||
|
||||
* Wed Jul 18 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.22-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
|
||||
|
||||
* Sat Jul 14 2012 Ville Skyttä <ville.skytta@iki.fi> - 0.6.22-2
|
||||
- Add ldconfig scriptlets to -libs.
|
||||
|
||||
* Thu Jun 28 2012 Ray Strode <rstrode@redhat.com> 0.6.22-1
|
||||
- Update to 0.6.22.
|
||||
- Fixes CVE-2012-2737 - local file disclosure
|
||||
Related: #832532
|
||||
|
||||
* Thu May 30 2012 Matthias Clasen <mclasen@redhatcom> 0.6.21-1
|
||||
- Update to 0.6.21
|
||||
|
||||
* Fri May 04 2012 Ray Strode <rstrode@redhat.com> 0.6.20-1
|
||||
- Update to 0.6.20. Should fix user list.
|
||||
Related: #814690
|
||||
|
||||
* Thu May 03 2012 Ray Strode <rstrode@redhat.com> 0.6.19-1
|
||||
- Update to 0.6.19
|
||||
Allows user deletion of logged in users
|
||||
Related: #814690
|
||||
|
||||
* Wed Apr 11 2012 Matthias Clasen <mclsaen@redhat.com> - 0.6.18-1
|
||||
- Update to 0.6.18
|
||||
|
||||
* Tue Mar 27 2012 Ray Strode <rstrode@redhat.com> 0.6.17-1
|
||||
- Update to latest release
|
||||
|
||||
* Sun Mar 4 2012 Peter Robinson <pbrobinson@fedoraproject.org> - 0.6.15-4
|
||||
- Fix unitdir with usrmove
|
||||
|
||||
* Thu Jan 12 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.15-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
|
||||
|
||||
* Tue Nov 29 2011 Matthias Clasen <mclasen@redhat.com> 0.6.15-2
|
||||
- Make resetting user icons work
|
||||
- Update to 0.6.15
|
||||
- Fixes session chooser at login screen when logged into vt
|
||||
|
||||
* Wed Sep 21 2011 Ray Strode <rstrode@redhat.com> 0.6.14-2
|
||||
- Fix wtmp loading so users coming from the network are
|
||||
remembered in the user list in subsequent boots
|
||||
|
||||
* Wed Sep 21 2011 Ray Strode <rstrode@redhat.com> 0.6.14-1
|
||||
- Update to 0.6.14
|
||||
|
||||
* Sun Sep 4 2011 Matthias Clasen <mclasen@redhat.com> - 0.6.13-3
|
||||
- Fix fast user switching
|
||||
|
||||
* Mon Aug 15 2011 Kalev Lember <kalevlember@gmail.com> - 0.6.13-2
|
||||
- Rebuilt for rpm bug #728707
|
||||
|
||||
* Tue Jul 19 2011 Matthias Clasen <mclasen@redhat.com> - 0.6.13-1
|
||||
- Update to 0.6.13
|
||||
- Drop ConsoleKit dependency
|
||||
|
||||
* Mon Jun 06 2011 Ray Strode <rstrode@redhat.com> 0.6.12-1
|
||||
- Update to latest release
|
||||
|
||||
* Wed May 18 2011 Matthias Clasen <mclasen@redhat.com> 0.6.11-1
|
||||
- Update to 0.6.11
|
||||
|
||||
* Mon Feb 07 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.3-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
|
||||
|
||||
* Wed Feb 02 2011 Ray Strode <rstrode@redhat.com> 0.6.3-1
|
||||
- Update to 0.6.3
|
||||
|
||||
* Thu Jan 27 2011 Matthias Clasen <mclasen@redhat.com> 0.6.2-1
|
||||
- Update to 0.6.2
|
||||
|
||||
* Wed Jul 21 2010 Matthias Clasen <mclasen@redhat.com> 0.6.1-1
|
||||
- Update to 0.6.1
|
||||
- Install systemd unit file
|
||||
|
||||
* Mon Apr 5 2010 Matthias Clasen <mclasen@redhat.com> 0.6-2
|
||||
- Always emit changed signal on icon change
|
||||
|
||||
* Tue Mar 30 2010 Matthias Clasen <mclasen@redhat.com> 0.6-1
|
||||
- Update to 0.6
|
||||
|
||||
* Mon Mar 22 2010 Matthias Clasen <mclasen@redhat.com> 0.5-1
|
||||
- Update to 0.5
|
||||
|
||||
* Mon Feb 22 2010 Bastien Nocera <bnocera@redhat.com> 0.4-3
|
||||
- Fix directory ownership
|
||||
|
||||
* Mon Feb 22 2010 Bastien Nocera <bnocera@redhat.com> 0.4-2
|
||||
- Add missing directories to the filelist
|
||||
|
||||
* Fri Jan 29 2010 Matthias Clasen <mclasen@redhat.com> 0.4-1
|
||||
- Initial packaging, based on work by Richard Hughes
|
Loading…
Reference in New Issue
Block a user