From 90baf40fa91a51b088f02a74f0380416992952dc Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Wed, 13 Jun 2012 13:59:28 +0200 Subject: [PATCH] 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 | 13 +++++------ src/libaccountsservice/act-user.c | 37 ++++++++++++++++++++++++++++++++ src/libaccountsservice/act-user.h | 1 + src/user.c | 23 +++++++++++++++++++- src/user.h | 3 +++ 6 files changed, 80 insertions(+), 7 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 ddbcbf0..0467bc4 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -288,8 +288,6 @@ entry_generator_wtmp (GHashTable *users, #endif /* HAVE_UTMPX_H */ -#ifdef HAVE_FGETPWENT - static struct passwd * entry_generator_fgetpwent (GHashTable *users, gpointer *state) @@ -318,8 +316,6 @@ entry_generator_fgetpwent (GHashTable *users, return NULL; } -#else /* !HAVE_FGETPWENT */ - static struct passwd * entry_generator_getpwent (GHashTable *users, gpointer *state) @@ -342,8 +338,6 @@ entry_generator_getpwent (GHashTable *users, return NULL; } -#endif /* !HAVE_FGETPWENT */ - static struct passwd * entry_generator_cachedir (GHashTable *users, gpointer *state) @@ -448,6 +442,12 @@ load_entries (Daemon *daemon, g_object_freeze_notify (G_OBJECT (user)); user_update_from_pwent (user, pwent); + /* Mark this user as a local user if it came from /etc/passwd */ + if (entry_generator == entry_generator_fgetpwent || + entry_generator == entry_generator_getpwent) { + user_update_set_local (user, TRUE); + } + g_hash_table_insert (users, g_strdup (user_get_user_name (user)), user); g_debug ("loaded user: %s", user_get_user_name (user)); } @@ -1060,6 +1060,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 02c1070..6453c04 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 e299021..59b86fb 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) { @@ -1825,6 +1843,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.10.2