From b89a082f1a66e4ffbf24f31b47f61f266cd0ab77 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Wed, 13 Jun 2012 13:59:28 +0200 Subject: [PATCH 2/2] Add User.Local dbus property This property describes whether the user account is local to the machine or not, and thus can be managed with usermod, userdel and so on. We currently implement this as a heuristic. If it's found in /etc/passwd then we treat it as 'local' https://bugs.freedesktop.org/show_bug.cgi?id=51037 --- data/org.freedesktop.Accounts.User.xml | 10 +++++++++ src/daemon.c | 23 ++++++++++++++++++++- src/libaccountsservice/act-user.c | 37 ++++++++++++++++++++++++++++++++++ src/libaccountsservice/act-user.h | 1 + src/user.c | 23 ++++++++++++++++++++- src/user.h | 3 +++ 6 files changed, 95 insertions(+), 2 deletions(-) diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml index 6ac7186..deab745 100644 --- a/data/org.freedesktop.Accounts.User.xml +++ b/data/org.freedesktop.Accounts.User.xml @@ -729,6 +729,16 @@ + + + + + Whether the user is a local account or not. + + + + + diff --git a/src/daemon.c b/src/daemon.c index a298a0b..90ad741 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -444,6 +444,7 @@ reload_users (Daemon *daemon) { GHashTable *users; GHashTable *old_users; + GHashTable *local; GHashTableIter iter; gpointer name; User *user; @@ -451,13 +452,32 @@ reload_users (Daemon *daemon) /* Track the users that we saw during our (re)load */ users = create_users_hash_table (); - /* Load data from all the sources, and freeze notifies */ + /* + * 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, 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); + + /* Now add/update users from other sources, possibly non-local */ #ifdef HAVE_UTMPX_H load_entries (daemon, users, entry_generator_wtmp); #endif load_entries (daemon, users, entry_generator_cachedir); + /* 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)) + user_update_set_local (user, g_hash_table_lookup (local, name) != NULL); + + g_hash_table_destroy (local); + /* Swap out the users */ old_users = daemon->priv->users; daemon->priv->users = users; @@ -1039,6 +1059,7 @@ daemon_create_user_authorized_cb (Daemon *daemon, } user = daemon_local_find_user_by_name (daemon, cd->user_name); + user_update_set_local (user, TRUE); accounts_accounts_complete_create_user (NULL, context, user_get_object_path (user)); } diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c index f42d00d..583bf28 100644 --- a/src/libaccountsservice/act-user.c +++ b/src/libaccountsservice/act-user.c @@ -55,6 +55,7 @@ enum { PROP_LOCKED, PROP_AUTOMATIC_LOGIN, PROP_SYSTEM_ACCOUNT, + PROP_LOCAL_ACCOUNT, PROP_LOGIN_FREQUENCY, PROP_ICON_FILE, PROP_LANGUAGE, @@ -98,6 +99,7 @@ struct _ActUser { guint locked : 1; guint automatic_login : 1; guint system_account : 1; + guint local_account : 1; }; struct _ActUserClass @@ -248,6 +250,9 @@ act_user_get_property (GObject *object, case PROP_SYSTEM_ACCOUNT: g_value_set_boolean (value, user->system_account); break; + case PROP_LOCAL_ACCOUNT: + g_value_set_boolean (value, user->local_account); + break; case PROP_IS_LOADED: g_value_set_boolean (value, user->is_loaded); break; @@ -400,6 +405,14 @@ act_user_class_init (ActUserClass *class) G_PARAM_READABLE)); g_object_class_install_property (gobject_class, + PROP_LOCAL_ACCOUNT, + g_param_spec_boolean ("local-account", + "Local Account", + "Local Account", + FALSE, + G_PARAM_READABLE)); + + g_object_class_install_property (gobject_class, PROP_SYSTEM_ACCOUNT, g_param_spec_boolean ("system-account", "System Account", @@ -804,6 +817,22 @@ act_user_is_system_account (ActUser *user) } /** + * act_user_is_local_account: + * @user: the user object to examine. + * + * Retrieves whether the user is a local account or not. + * + * Returns: (transfer none): %TRUE if the user is local + **/ +gboolean +act_user_is_local_account (ActUser *user) +{ + g_return_val_if_fail (ACT_IS_USER (user), FALSE); + + return user->local_account; +} + +/** * act_user_get_icon_file: * @user: a #ActUser * @@ -1009,6 +1038,14 @@ collect_props (const gchar *key, user->system_account = new_system_account_state; g_object_notify (G_OBJECT (user), "system-account"); } + } else if (strcmp (key, "LocalAccount") == 0) { + gboolean new_local; + + new_local = g_variant_get_boolean (value); + if (user->local_account != new_local) { + user->local_account = new_local; + g_object_notify (G_OBJECT (user), "local-account"); + } } else if (strcmp (key, "LoginFrequency") == 0) { int new_login_frequency; diff --git a/src/libaccountsservice/act-user.h b/src/libaccountsservice/act-user.h index 7ce49fd..c01c1e9 100644 --- a/src/libaccountsservice/act-user.h +++ b/src/libaccountsservice/act-user.h @@ -69,6 +69,7 @@ int act_user_get_login_frequency (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); 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); diff --git a/src/user.c b/src/user.c index 0910232..7dc9bfd 100644 --- a/src/user.c +++ b/src/user.c @@ -64,7 +64,8 @@ enum { PROP_PASSWORD_MODE, PROP_PASSWORD_HINT, PROP_AUTOMATIC_LOGIN, - PROP_SYSTEM_ACCOUNT + PROP_SYSTEM_ACCOUNT, + PROP_LOCAL_ACCOUNT, }; struct User { @@ -94,6 +95,7 @@ struct User { gboolean locked; gboolean automatic_login; gboolean system_account; + gboolean local_account; }; typedef struct UserClass @@ -337,6 +339,16 @@ user_update_from_keyfile (User *user, g_object_thaw_notify (G_OBJECT (user)); } +void +user_update_set_local (User *user, + gboolean local) +{ + if (local == user->local_account) + return; + user->local_account = local; + g_object_notify (G_OBJECT (user), "local-account"); +} + static void user_save_to_keyfile (User *user, GKeyFile *keyfile) @@ -476,6 +488,12 @@ user_get_system_account (User *user) return user->system_account; } +gboolean +user_get_local_account (User *user) +{ + return user->local_account; +} + const gchar * user_get_object_path (User *user) { @@ -1831,6 +1849,9 @@ user_get_property (GObject *object, case PROP_SYSTEM_ACCOUNT: g_value_set_boolean (value, user->system_account); break; + case PROP_LOCAL_ACCOUNT: + g_value_set_boolean (value, user->local_account); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; diff --git a/src/user.h b/src/user.h index f85c815..ec06df2 100644 --- a/src/user.h +++ b/src/user.h @@ -57,12 +57,15 @@ void user_update_from_pwent (User *user, struct passwd *pwent); void user_update_from_keyfile (User *user, GKeyFile *keyfile); +void user_update_set_local (User *user, + gboolean local); void user_register (User *user); void user_unregister (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); -- 1.7.11.4