Blame SOURCES/0002-user-export-new-Saved-property.patch

ece282
From 14bb1237f71e38749558c74963032a0387eecec0 Mon Sep 17 00:00:00 2001
ece282
From: Ray Strode <rstrode@redhat.com>
ece282
Date: Wed, 15 Aug 2018 16:04:42 -0400
ece282
Subject: [PATCH 2/2] user: export new Saved property
ece282
ece282
accountsservice maintains a state file for some users, if those users
ece282
have selected a specific session or language.
ece282
ece282
There's no good way, at the moment, for an application to check if a
ece282
specific user has saved state.
ece282
ece282
This commit exports the Saved property on the User object.
ece282
---
ece282
 data/org.freedesktop.Accounts.User.xml | 10 ++++++++++
ece282
 src/daemon.c                           |  3 +++
ece282
 src/libaccountsservice/act-user.c      | 19 +++++++++++++++++++
ece282
 src/libaccountsservice/act-user.h      |  1 +
ece282
 src/user.c                             | 10 ++++++++++
ece282
 src/user.h                             |  2 ++
ece282
 6 files changed, 45 insertions(+)
ece282
ece282
diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml
ece282
index 7fc3c61..8d3fe1c 100644
ece282
--- a/data/org.freedesktop.Accounts.User.xml
ece282
+++ b/data/org.freedesktop.Accounts.User.xml
ece282
@@ -811,60 +811,70 @@
ece282
     </doc:doc>
ece282
   </property>
ece282
 
ece282
   <property name="LoginHistory" type="a(xxa{sv})" access="read">
ece282
     <doc:doc>
ece282
       <doc:description>
ece282
         <doc:para>
ece282
           The login history for this user.
ece282
           Each entry in the array represents a login session. The first two
ece282
           members are the login time and logout time, as timestamps (seconds since the epoch). If the session is still running, the logout time
ece282
           is 0.
ece282
         </doc:para>
ece282
         <doc:para>
ece282
           The a{sv} member is a dictionary containing additional information
ece282
           about the session. Possible members include 'type' (with values like ':0', 'tty0', 'pts/0' etc).
ece282
         </doc:para>
ece282
       </doc:description>
ece282
     </doc:doc>
ece282
   </property>
ece282
 
ece282
   <property name="IconFile" type="s" access="read">
ece282
     <doc:doc>
ece282
       <doc:description>
ece282
         <doc:para>
ece282
            The filename of a png file containing the users icon.
ece282
         </doc:para>
ece282
       </doc:description>
ece282
     </doc:doc>
ece282
   </property>
ece282
 
ece282
+  <property name="Saved" type="b" access="read">
ece282
+    <doc:doc>
ece282
+      <doc:description>
ece282
+        <doc:para>
ece282
+           Whether the users account has retained state
ece282
+        </doc:para>
ece282
+      </doc:description>
ece282
+    </doc:doc>
ece282
+  </property>
ece282
+
ece282
   <property name="Locked" type="b" access="read">
ece282
     <doc:doc>
ece282
       <doc:description>
ece282
         <doc:para>
ece282
            Whether the users account is locked.
ece282
         </doc:para>
ece282
       </doc:description>
ece282
     </doc:doc>
ece282
   </property>
ece282
 
ece282
   <property name="PasswordMode" type="i" access="read">
ece282
     <doc:doc>
ece282
       <doc:description>
ece282
         <doc:para>
ece282
           The password mode for the user account, encoded as an integer:
ece282
           <doc:list>
ece282
             <doc:item>
ece282
               <doc:term>0</doc:term>
ece282
               <doc:definition>Regular password</doc:definition>
ece282
             </doc:item>
ece282
             <doc:item>
ece282
               <doc:term>1</doc:term>
ece282
               <doc:definition>Password must be set at next login</doc:definition>
ece282
             </doc:item>
ece282
             <doc:item>
ece282
               <doc:term>2</doc:term>
ece282
               <doc:definition>No password</doc:definition>
ece282
             </doc:item>
ece282
           </doc:list>
ece282
         </doc:para>
ece282
diff --git a/src/daemon.c b/src/daemon.c
ece282
index 2851ed6..2587b8a 100644
ece282
--- a/src/daemon.c
ece282
+++ b/src/daemon.c
ece282
@@ -1187,60 +1187,61 @@ daemon_cache_user (AccountsAccounts      *accounts,
ece282
                                  context,
ece282
                                  g_strdup (user_name),
ece282
                                  g_free);
ece282
 
ece282
         return TRUE;
ece282
 }
ece282
 
ece282
 static void
ece282
 daemon_uncache_user_authorized_cb (Daemon                *daemon,
ece282
                                    User                  *dummy,
ece282
                                    GDBusMethodInvocation *context,
ece282
                                    gpointer               data)
ece282
 {
ece282
         const gchar *user_name = data;
ece282
         User        *user;
ece282
 
ece282
         sys_log (context, "uncache user '%s'", user_name);
ece282
 
ece282
         user = daemon_local_find_user_by_name (daemon, user_name);
ece282
         if (user == NULL) {
ece282
                 throw_error (context, ERROR_USER_DOES_NOT_EXIST,
ece282
                              "No user with the name %s found", user_name);
ece282
                 return;
ece282
         }
ece282
 
ece282
         /* Always use the canonical user name looked up */
ece282
         user_name = user_get_user_name (user);
ece282
 
ece282
         remove_cache_files (user_name);
ece282
 
ece282
+        user_set_saved (user, FALSE);
ece282
         user_set_cached (user, FALSE);
ece282
 
ece282
         accounts_accounts_complete_uncache_user (NULL, context);
ece282
 
ece282
         queue_reload_users (daemon);
ece282
 }
ece282
 
ece282
 static gboolean
ece282
 daemon_uncache_user (AccountsAccounts      *accounts,
ece282
                      GDBusMethodInvocation *context,
ece282
                      const gchar           *user_name)
ece282
 {
ece282
         Daemon *daemon = (Daemon*)accounts;
ece282
 
ece282
         daemon_local_check_auth (daemon,
ece282
                                  NULL,
ece282
                                  "org.freedesktop.accounts.user-administration",
ece282
                                  TRUE,
ece282
                                  daemon_uncache_user_authorized_cb,
ece282
                                  context,
ece282
                                  g_strdup (user_name),
ece282
                                  g_free);
ece282
 
ece282
         return TRUE;
ece282
 }
ece282
 
ece282
 typedef struct {
ece282
         uid_t uid;
ece282
         gboolean remove_files;
ece282
 } DeleteUserData;
ece282
@@ -1252,60 +1253,62 @@ daemon_delete_user_authorized_cb (Daemon                *daemon,
ece282
                                   gpointer               data)
ece282
 
ece282
 {
ece282
         DeleteUserData *ud = data;
ece282
         g_autoptr(GError) error = NULL;
ece282
         struct passwd *pwent;
ece282
         const gchar *argv[6];
ece282
         User *user;
ece282
 
ece282
         pwent = getpwuid (ud->uid);
ece282
 
ece282
         if (pwent == NULL) {
ece282
                 throw_error (context, ERROR_USER_DOES_NOT_EXIST, "No user with uid %d found", ud->uid);
ece282
                 return;
ece282
         }
ece282
 
ece282
         sys_log (context, "delete user '%s' (%d)", pwent->pw_name, ud->uid);
ece282
 
ece282
         user = daemon_local_find_user_by_id (daemon, ud->uid);
ece282
 
ece282
         if (user != NULL) {
ece282
                 user_set_cached (user, FALSE);
ece282
 
ece282
                 if (daemon->priv->autologin == user) {
ece282
                         daemon_local_set_automatic_login (daemon, user, FALSE, NULL);
ece282
                 }
ece282
         }
ece282
 
ece282
         remove_cache_files (pwent->pw_name);
ece282
 
ece282
+        user_set_saved (user, FALSE);
ece282
+
ece282
         argv[0] = "/usr/sbin/userdel";
ece282
         if (ud->remove_files) {
ece282
                 argv[1] = "-f";
ece282
                 argv[2] = "-r";
ece282
                 argv[3] = "--";
ece282
                 argv[4] = pwent->pw_name;
ece282
                 argv[5] = NULL;
ece282
         }
ece282
         else {
ece282
                 argv[1] = "-f";
ece282
                 argv[2] = "--";
ece282
                 argv[3] = pwent->pw_name;
ece282
                 argv[4] = NULL;
ece282
         }
ece282
 
ece282
         if (!spawn_with_login_uid (context, argv, &error)) {
ece282
                 throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
ece282
                 return;
ece282
         }
ece282
 
ece282
         accounts_accounts_complete_delete_user (NULL, context);
ece282
 }
ece282
 
ece282
 
ece282
 static gboolean
ece282
 daemon_delete_user (AccountsAccounts      *accounts,
ece282
                     GDBusMethodInvocation *context,
ece282
                     gint64                 uid,
ece282
                     gboolean               remove_files)
ece282
 {
ece282
diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c
ece282
index dd8f81b..540ffe7 100644
ece282
--- a/src/libaccountsservice/act-user.c
ece282
+++ b/src/libaccountsservice/act-user.c
ece282
@@ -849,60 +849,79 @@ act_user_collate (ActUser *user1,
ece282
  *
ece282
  * Returns whether or not #ActUser is currently graphically logged in
ece282
  * on the same seat as the seat of the session of the calling process.
ece282
  *
ece282
  * Returns: %TRUE or %FALSE
ece282
  */
ece282
 gboolean
ece282
 act_user_is_logged_in (ActUser *user)
ece282
 {
ece282
         return user->our_sessions != NULL;
ece282
 }
ece282
 
ece282
 /**
ece282
  * act_user_is_logged_in_anywhere:
ece282
  * @user: a #ActUser
ece282
  *
ece282
  * Returns whether or not #ActUser is currently logged in in any way
ece282
  * whatsoever.  See also act_user_is_logged_in().
ece282
  *
ece282
  * (Currently, this function is only implemented for systemd-logind.
ece282
  * For ConsoleKit, it is equivalent to act_user_is_logged_in.)
ece282
  *
ece282
  * Returns: %TRUE or %FALSE
ece282
  */
ece282
 gboolean
ece282
 act_user_is_logged_in_anywhere (ActUser *user)
ece282
 {
ece282
         return user->our_sessions != NULL || user->other_sessions != NULL;
ece282
 }
ece282
 
ece282
+/**
ece282
+ * act_user_get_saved:
ece282
+ * @user: a #ActUser
ece282
+ *
ece282
+ * Returns whether or not the #ActUser account has retained state in accountsservice.
ece282
+ *
ece282
+ * Returns: %TRUE or %FALSE
ece282
+ */
ece282
+gboolean
ece282
+act_user_get_saved (ActUser *user)
ece282
+{
ece282
+        g_return_val_if_fail (ACT_IS_USER (user), TRUE);
ece282
+
ece282
+        if (user->accounts_proxy == NULL)
ece282
+                return FALSE;
ece282
+
ece282
+        return accounts_user_get_saved (user->accounts_proxy);
ece282
+}
ece282
+
ece282
 /**
ece282
  * act_user_get_locked:
ece282
  * @user: a #ActUser
ece282
  *
ece282
  * Returns whether or not the #ActUser account is locked.
ece282
  *
ece282
  * Returns: %TRUE or %FALSE
ece282
  */
ece282
 gboolean
ece282
 act_user_get_locked (ActUser *user)
ece282
 {
ece282
         g_return_val_if_fail (ACT_IS_USER (user), TRUE);
ece282
 
ece282
         if (user->accounts_proxy == NULL)
ece282
                 return TRUE;
ece282
 
ece282
         return accounts_user_get_locked (user->accounts_proxy);
ece282
 }
ece282
 
ece282
 /**
ece282
  * act_user_get_automatic_login:
ece282
  * @user: a #ActUser
ece282
  *
ece282
  * Returns whether or not #ActUser is automatically logged in at boot time.
ece282
  *
ece282
  * Returns: %TRUE or %FALSE
ece282
  */
ece282
 gboolean
ece282
 act_user_get_automatic_login (ActUser *user)
ece282
 {
ece282
diff --git a/src/libaccountsservice/act-user.h b/src/libaccountsservice/act-user.h
ece282
index 2ef13b1..34d7fe3 100644
ece282
--- a/src/libaccountsservice/act-user.h
ece282
+++ b/src/libaccountsservice/act-user.h
ece282
@@ -43,60 +43,61 @@ typedef enum {
ece282
 typedef enum {
ece282
         ACT_USER_PASSWORD_MODE_REGULAR,
ece282
         ACT_USER_PASSWORD_MODE_SET_AT_LOGIN,
ece282
         ACT_USER_PASSWORD_MODE_NONE,
ece282
 } ActUserPasswordMode;
ece282
 
ece282
 typedef struct _ActUser ActUser;
ece282
 typedef struct _ActUserClass ActUserClass;
ece282
 
ece282
 GType          act_user_get_type                  (void) G_GNUC_CONST;
ece282
 
ece282
 const char    *act_user_get_object_path           (ActUser *user);
ece282
 
ece282
 uid_t          act_user_get_uid                   (ActUser   *user);
ece282
 const char    *act_user_get_user_name             (ActUser   *user);
ece282
 const char    *act_user_get_real_name             (ActUser   *user);
ece282
 ActUserAccountType act_user_get_account_type      (ActUser   *user);
ece282
 ActUserPasswordMode act_user_get_password_mode    (ActUser   *user);
ece282
 const char    *act_user_get_password_hint         (ActUser   *user);
ece282
 const char    *act_user_get_home_dir              (ActUser   *user);
ece282
 const char    *act_user_get_shell                 (ActUser   *user);
ece282
 const char    *act_user_get_email                 (ActUser   *user);
ece282
 const char    *act_user_get_location              (ActUser   *user);
ece282
 guint          act_user_get_num_sessions          (ActUser   *user);
ece282
 guint          act_user_get_num_sessions_anywhere (ActUser   *user);
ece282
 gboolean       act_user_is_logged_in              (ActUser   *user);
ece282
 gboolean       act_user_is_logged_in_anywhere     (ActUser   *user);
ece282
 int            act_user_get_login_frequency       (ActUser   *user);
ece282
 gint64         act_user_get_login_time            (ActUser   *user);
ece282
 const GVariant*act_user_get_login_history         (ActUser   *user);
ece282
+gboolean       act_user_get_saved                 (ActUser   *user);
ece282
 gboolean       act_user_get_locked                (ActUser   *user);
ece282
 gboolean       act_user_get_automatic_login       (ActUser   *user);
ece282
 gboolean       act_user_is_system_account         (ActUser   *user);
ece282
 gboolean       act_user_is_local_account          (ActUser   *user);
ece282
 gboolean       act_user_is_nonexistent            (ActUser   *user);
ece282
 const char    *act_user_get_icon_file             (ActUser   *user);
ece282
 const char    *act_user_get_language              (ActUser   *user);
ece282
 const char    *act_user_get_x_session             (ActUser   *user);
ece282
 const char    *act_user_get_session               (ActUser   *user);
ece282
 const char    *act_user_get_session_type          (ActUser   *user);
ece282
 const char    *act_user_get_primary_session_id    (ActUser   *user);
ece282
 
ece282
 gint           act_user_collate                   (ActUser   *user1,
ece282
                                                    ActUser   *user2);
ece282
 gboolean       act_user_is_loaded                 (ActUser   *user);
ece282
 
ece282
 void           act_user_get_password_expiration_policy (ActUser   *user,
ece282
                                                         gint64    *expiration_time,
ece282
                                                         gint64    *last_change_time,
ece282
                                                         gint64    *min_days_between_changes,
ece282
                                                         gint64    *max_days_between_changes,
ece282
                                                         gint64    *days_to_warn,
ece282
                                                         gint64    *days_after_expiration_until_lock);
ece282
 
ece282
 void           act_user_set_email                 (ActUser    *user,
ece282
                                                    const char *email);
ece282
 void           act_user_set_language              (ActUser    *user,
ece282
                                                    const char *language);
ece282
 void           act_user_set_x_session             (ActUser    *user,
ece282
                                                    const char *x_session);
ece282
diff --git a/src/user.c b/src/user.c
ece282
index 94c0244..93afadc 100644
ece282
--- a/src/user.c
ece282
+++ b/src/user.c
ece282
@@ -284,60 +284,61 @@ user_update_from_keyfile (User     *user,
ece282
         }
ece282
 
ece282
         s = g_key_file_get_string (keyfile, "User", "Location", NULL);
ece282
         if (s != NULL) {
ece282
                 accounts_user_set_location (ACCOUNTS_USER (user), s);
ece282
                 g_clear_pointer (&s, g_free);
ece282
         }
ece282
 
ece282
         s = g_key_file_get_string (keyfile, "User", "PasswordHint", NULL);
ece282
         if (s != NULL) {
ece282
                 accounts_user_set_password_hint (ACCOUNTS_USER (user), s);
ece282
                 g_clear_pointer (&s, g_free);
ece282
         }
ece282
 
ece282
         s = g_key_file_get_string (keyfile, "User", "Icon", NULL);
ece282
         if (s != NULL) {
ece282
                 accounts_user_set_icon_file (ACCOUNTS_USER (user), s);
ece282
                 g_clear_pointer (&s, g_free);
ece282
         }
ece282
 
ece282
         if (g_key_file_has_key (keyfile, "User", "SystemAccount", NULL)) {
ece282
             gboolean system_account;
ece282
 
ece282
             system_account = g_key_file_get_boolean (keyfile, "User", "SystemAccount", NULL);
ece282
             accounts_user_set_system_account (ACCOUNTS_USER (user), system_account);
ece282
         }
ece282
 
ece282
         g_clear_pointer (&user->keyfile, g_key_file_unref);
ece282
         user->keyfile = g_key_file_ref (keyfile);
ece282
         user_set_cached (user, TRUE);
ece282
+        user_set_saved (user, TRUE);
ece282
 
ece282
         g_object_thaw_notify (G_OBJECT (user));
ece282
 }
ece282
 
ece282
 void
ece282
 user_update_local_account_property (User          *user,
ece282
                                     gboolean       local)
ece282
 {
ece282
         accounts_user_set_local_account (ACCOUNTS_USER (user), local);
ece282
 }
ece282
 
ece282
 void
ece282
 user_update_system_account_property (User          *user,
ece282
                                      gboolean       system)
ece282
 {
ece282
         accounts_user_set_system_account (ACCOUNTS_USER (user), system);
ece282
 }
ece282
 
ece282
 static void
ece282
 user_save_to_keyfile (User     *user,
ece282
                       GKeyFile *keyfile)
ece282
 {
ece282
         g_key_file_remove_group (keyfile, "User", NULL);
ece282
 
ece282
         if (accounts_user_get_email (ACCOUNTS_USER (user)))
ece282
                 g_key_file_set_string (keyfile, "User", "Email", accounts_user_get_email (ACCOUNTS_USER (user)));
ece282
 
ece282
         if (accounts_user_get_language (ACCOUNTS_USER (user)))
ece282
                 g_key_file_set_string (keyfile, "User", "Language", accounts_user_get_language (ACCOUNTS_USER (user)));
ece282
 
ece282
@@ -357,60 +358,62 @@ user_save_to_keyfile (User     *user,
ece282
                 g_key_file_set_string (keyfile, "User", "PasswordHint", accounts_user_get_password_hint (ACCOUNTS_USER (user)));
ece282
 
ece282
         if (accounts_user_get_icon_file (ACCOUNTS_USER (user)))
ece282
                 g_key_file_set_string (keyfile, "User", "Icon", accounts_user_get_icon_file (ACCOUNTS_USER (user)));
ece282
 
ece282
         g_key_file_set_boolean (keyfile, "User", "SystemAccount", accounts_user_get_system_account (ACCOUNTS_USER (user)));
ece282
 
ece282
         user_set_cached (user, TRUE);
ece282
 }
ece282
 
ece282
 static void
ece282
 save_extra_data (User *user)
ece282
 {
ece282
         g_autofree gchar *data = NULL;
ece282
         g_autofree gchar *filename = NULL;
ece282
         g_autoptr(GError) error = NULL;
ece282
 
ece282
         user_save_to_keyfile (user, user->keyfile);
ece282
 
ece282
         data = g_key_file_to_data (user->keyfile, NULL, &error);
ece282
         if (data == NULL) {
ece282
                 g_warning ("Saving data for user %s failed: %s",
ece282
                            accounts_user_get_user_name (ACCOUNTS_USER (user)), error->message);
ece282
                 return;
ece282
         }
ece282
 
ece282
         filename = g_build_filename (USERDIR,
ece282
                                      accounts_user_get_user_name (ACCOUNTS_USER (user)),
ece282
                                      NULL);
ece282
         g_file_set_contents (filename, data, -1, &error);
ece282
+
ece282
+        user_set_saved (user, TRUE);
ece282
 }
ece282
 
ece282
 static void
ece282
 move_extra_data (const gchar *old_name,
ece282
                  const gchar *new_name)
ece282
 {
ece282
         g_autofree gchar *old_filename = NULL;
ece282
         g_autofree gchar *new_filename = NULL;
ece282
 
ece282
         old_filename = g_build_filename (USERDIR,
ece282
                                          old_name, NULL);
ece282
         new_filename = g_build_filename (USERDIR,
ece282
                                          new_name, NULL);
ece282
 
ece282
         g_rename (old_filename, new_filename);
ece282
 }
ece282
 
ece282
 static GVariant *
ece282
 user_extension_get_value (User                    *user,
ece282
                           GDBusInterfaceInfo      *interface,
ece282
                           const GDBusPropertyInfo *property)
ece282
 {
ece282
         const GVariantType *type = G_VARIANT_TYPE (property->signature);
ece282
         GVariant *value;
ece282
         g_autofree gchar *printed = NULL;
ece282
         gint i;
ece282
 
ece282
         /* First, try to get the value from the keyfile */
ece282
         printed = g_key_file_get_value (user->keyfile, interface->name, property->name, NULL);
ece282
         if (printed) {
ece282
@@ -773,60 +776,67 @@ const gchar *
ece282
 user_get_object_path (User *user)
ece282
 {
ece282
         return g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (user));
ece282
 }
ece282
 
ece282
 uid_t
ece282
 user_get_uid (User *user)
ece282
 {
ece282
         return accounts_user_get_uid (ACCOUNTS_USER (user));
ece282
 }
ece282
 
ece282
 const gchar *
ece282
 user_get_shell(User *user)
ece282
 {
ece282
 	return accounts_user_get_shell (ACCOUNTS_USER (user));
ece282
 }
ece282
 
ece282
 gboolean
ece282
 user_get_cached (User *user)
ece282
 {
ece282
         return user->cached;
ece282
 }
ece282
 
ece282
 void
ece282
 user_set_cached (User     *user,
ece282
                  gboolean  cached)
ece282
 {
ece282
         user->cached = cached;
ece282
 }
ece282
 
ece282
+void
ece282
+user_set_saved (User     *user,
ece282
+                gboolean  saved)
ece282
+{
ece282
+        accounts_user_set_saved (ACCOUNTS_USER (user), saved);
ece282
+}
ece282
+
ece282
 static void
ece282
 throw_error (GDBusMethodInvocation *context,
ece282
              gint                   error_code,
ece282
              const gchar           *format,
ece282
              ...)
ece282
 {
ece282
         va_list args;
ece282
         g_autofree gchar *message = NULL;
ece282
 
ece282
         va_start (args, format);
ece282
         message = g_strdup_vprintf (format, args);
ece282
         va_end (args);
ece282
 
ece282
         g_dbus_method_invocation_return_error (context, ERROR, error_code, "%s", message);
ece282
 }
ece282
 
ece282
 static void
ece282
 user_change_real_name_authorized_cb (Daemon                *daemon,
ece282
                                      User                  *user,
ece282
                                      GDBusMethodInvocation *context,
ece282
                                      gpointer               data)
ece282
 
ece282
 {
ece282
         gchar *name = data;
ece282
         g_autoptr(GError) error = NULL;
ece282
         const gchar *argv[6];
ece282
 
ece282
         if (g_strcmp0 (accounts_user_get_real_name (ACCOUNTS_USER (user)), name) != 0) {
ece282
                 sys_log (context,
ece282
                          "change real name of user '%s' (%d) to '%s'",
ece282
diff --git a/src/user.h b/src/user.h
ece282
index 39c6f13..b3b3380 100644
ece282
--- a/src/user.h
ece282
+++ b/src/user.h
ece282
@@ -39,47 +39,49 @@ typedef enum {
ece282
         ACCOUNT_TYPE_STANDARD,
ece282
         ACCOUNT_TYPE_ADMINISTRATOR,
ece282
 #define ACCOUNT_TYPE_LAST ACCOUNT_TYPE_ADMINISTRATOR
ece282
 } AccountType;
ece282
 
ece282
 typedef enum {
ece282
         PASSWORD_MODE_REGULAR,
ece282
         PASSWORD_MODE_SET_AT_LOGIN,
ece282
         PASSWORD_MODE_NONE,
ece282
 #define PASSWORD_MODE_LAST PASSWORD_MODE_NONE
ece282
 } PasswordMode;
ece282
 
ece282
 /* local methods */
ece282
 
ece282
 GType          user_get_type                (void) G_GNUC_CONST;
ece282
 User *         user_new                     (Daemon        *daemon,
ece282
                                              uid_t          uid);
ece282
 
ece282
 void           user_update_from_pwent       (User          *user,
ece282
                                              struct passwd *pwent,
ece282
                                              struct spwd   *spent);
ece282
 void           user_update_from_keyfile     (User          *user,
ece282
                                              GKeyFile      *keyfile);
ece282
 void           user_update_local_account_property (User          *user,
ece282
                                                    gboolean       local);
ece282
 void           user_update_system_account_property (User          *user,
ece282
                                                     gboolean       system);
ece282
 gboolean       user_get_cached              (User          *user);
ece282
 void           user_set_cached              (User          *user,
ece282
                                              gboolean       cached);
ece282
+void           user_set_saved               (User          *user,
ece282
+                                             gboolean       saved);
ece282
 
ece282
 void           user_register                (User          *user);
ece282
 void           user_unregister              (User          *user);
ece282
 void           user_changed                 (User          *user);
ece282
 
ece282
 void           user_save                    (User          *user);
ece282
 
ece282
 const gchar *  user_get_user_name           (User          *user);
ece282
 gboolean       user_get_system_account      (User          *user);
ece282
 gboolean       user_get_local_account       (User          *user);
ece282
 const gchar *  user_get_object_path         (User          *user);
ece282
 uid_t          user_get_uid                 (User          *user);
ece282
 const gchar *  user_get_shell               (User          *user);
ece282
 
ece282
 G_END_DECLS
ece282
 
ece282
 #endif
ece282
-- 
ece282
2.17.1
ece282