751739
From c66cee942242a731082f0fac649f3f9569ae99a3 Mon Sep 17 00:00:00 2001
751739
From: Ray Strode <rstrode@redhat.com>
751739
Date: Wed, 8 Aug 2018 16:11:56 -0400
751739
Subject: [PATCH 1/2] user: add new Session/SessionType properties to replace
751739
 XSession
751739
751739
Having a property called XSession in the API makes little
751739
sense when wayland has taken the world by storm.
751739
751739
This commit adds new "Session" property without the "X" in the name,
751739
and an additional property "SessionType" that can be either
751739
"wayland" or "x11".
751739
---
751739
 data/org.freedesktop.Accounts.User.xml | 103 +++++++++++++++++++++
751739
 src/libaccountsservice/act-user.c      |  93 +++++++++++++++++++
751739
 src/libaccountsservice/act-user.h      |   6 ++
751739
 src/user.c                             | 121 +++++++++++++++++++++++++
751739
 4 files changed, 323 insertions(+)
751739
751739
diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml
751739
index 4ab989a..7fc3c61 100644
751739
--- a/data/org.freedesktop.Accounts.User.xml
751739
+++ b/data/org.freedesktop.Accounts.User.xml
751739
@@ -141,60 +141,143 @@
751739
             <doc:term>org.freedesktop.accounts.user-administration</doc:term>
751739
             <doc:definition>To change the language of another user</doc:definition>
751739
           </doc:item>
751739
         </doc:list>
751739
       </doc:permission>
751739
       <doc:errors>
751739
         <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
751739
         <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
751739
       </doc:errors>
751739
     </doc:doc>
751739
   </method>
751739
 
751739
   <method name="SetXSession">
751739
     <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
751739
     <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="user_set_x_session"/>
751739
     <arg name="x_session" direction="in" type="s">
751739
       <doc:doc>
751739
         <doc:summary>
751739
           The new xsession to start (e.g. "gnome")
751739
         </doc:summary>
751739
       </doc:doc>
751739
     </arg>
751739
     <doc:doc>
751739
       <doc:description>
751739
         <doc:para>
751739
           Sets the users x session.
751739
         </doc:para>
751739
         <doc:para>
751739
           The expectation is that display managers will log the user in to this
751739
           specified session, if available.
751739
+
751739
+          Note this call is deprecated and has been superceded by SetSession since
751739
+          not all graphical sessions use X as the display server.
751739
+        </doc:para>
751739
+      </doc:description>
751739
+      <doc:permission>
751739
+        The caller needs one of the following PolicyKit authorizations:
751739
+        <doc:list>
751739
+          <doc:item>
751739
+            <doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
751739
+            <doc:definition>To change his own language</doc:definition>
751739
+          </doc:item>
751739
+          <doc:item>
751739
+            <doc:term>org.freedesktop.accounts.user-administration</doc:term>
751739
+            <doc:definition>To change the language of another user</doc:definition>
751739
+          </doc:item>
751739
+        </doc:list>
751739
+      </doc:permission>
751739
+      <doc:errors>
751739
+        <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
751739
+        <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
751739
+      </doc:errors>
751739
+   </doc:doc>
751739
+  </method>
751739
+
751739
+  <method name="SetSession">
751739
+    <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
751739
+    <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="user_set_session"/>
751739
+    <arg name="session" direction="in" type="s">
751739
+      <doc:doc>
751739
+        <doc:summary>
751739
+          The new session to start (e.g. "gnome-xorg")
751739
+        </doc:summary>
751739
+      </doc:doc>
751739
+    </arg>
751739
+    <doc:doc>
751739
+      <doc:description>
751739
+        <doc:para>
751739
+          Sets the users wayland or x session.
751739
+        </doc:para>
751739
+        <doc:para>
751739
+          The expectation is that display managers will log the user in to this
751739
+          specified session, if available.
751739
+        </doc:para>
751739
+      </doc:description>
751739
+      <doc:permission>
751739
+        The caller needs one of the following PolicyKit authorizations:
751739
+        <doc:list>
751739
+          <doc:item>
751739
+            <doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
751739
+            <doc:definition>To change his own language</doc:definition>
751739
+          </doc:item>
751739
+          <doc:item>
751739
+            <doc:term>org.freedesktop.accounts.user-administration</doc:term>
751739
+            <doc:definition>To change the language of another user</doc:definition>
751739
+          </doc:item>
751739
+        </doc:list>
751739
+      </doc:permission>
751739
+      <doc:errors>
751739
+        <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
751739
+        <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
751739
+      </doc:errors>
751739
+   </doc:doc>
751739
+  </method>
751739
+
751739
+  <method name="SetSessionType">
751739
+    <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
751739
+    <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="user_set_session_type"/>
751739
+    <arg name="session_type" direction="in" type="s">
751739
+      <doc:doc>
751739
+        <doc:summary>
751739
+          The type of the new session to start (e.g. "wayland" or "x11")
751739
+        </doc:summary>
751739
+      </doc:doc>
751739
+    </arg>
751739
+    <doc:doc>
751739
+      <doc:description>
751739
+        <doc:para>
751739
+          Sets the session type of the users session.
751739
+        </doc:para>
751739
+        <doc:para>
751739
+          Display managers may use this property to decide what type of display server to use when
751739
+          loading the session
751739
         </doc:para>
751739
       </doc:description>
751739
       <doc:permission>
751739
         The caller needs one of the following PolicyKit authorizations:
751739
         <doc:list>
751739
           <doc:item>
751739
             <doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
751739
             <doc:definition>To change his own language</doc:definition>
751739
           </doc:item>
751739
           <doc:item>
751739
             <doc:term>org.freedesktop.accounts.user-administration</doc:term>
751739
             <doc:definition>To change the language of another user</doc:definition>
751739
           </doc:item>
751739
         </doc:list>
751739
       </doc:permission>
751739
       <doc:errors>
751739
         <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
751739
         <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
751739
       </doc:errors>
751739
    </doc:doc>
751739
   </method>
751739
 
751739
   <method name="SetLocation">
751739
     <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
751739
     <arg name="location" direction="in" type="s">
751739
       <doc:doc>
751739
         <doc:summary>
751739
           The new location as a freeform string.
751739
         </doc:summary>
751739
       </doc:doc>
751739
@@ -641,60 +724,80 @@
751739
   <property name="Shell" type="s" access="read">
751739
     <doc:doc>
751739
       <doc:description>
751739
         <doc:para>
751739
           The users shell.
751739
         </doc:para>
751739
       </doc:description>
751739
     </doc:doc>
751739
   </property>
751739
 
751739
   <property name="Email" type="s" access="read">
751739
     <doc:doc>
751739
       <doc:description>
751739
         <doc:para>
751739
           The email address.
751739
         </doc:para>
751739
       </doc:description>
751739
     </doc:doc>
751739
   </property>
751739
 
751739
   <property name="Language" type="s" access="read">
751739
     <doc:doc>
751739
       <doc:description>
751739
         <doc:para>
751739
           The users language, as a locale specification like "de_DE.UTF-8".
751739
         </doc:para>
751739
       </doc:description>
751739
     </doc:doc>
751739
   </property>
751739
 
751739
+  <property name="Session" type="s" access="read">
751739
+    <doc:doc>
751739
+      <doc:description>
751739
+        <doc:para>
751739
+          The users Wayland or X session.
751739
+        </doc:para>
751739
+      </doc:description>
751739
+    </doc:doc>
751739
+  </property>
751739
+
751739
+  <property name="SessionType" type="s" access="read">
751739
+    <doc:doc>
751739
+      <doc:description>
751739
+        <doc:para>
751739
+          The type of session the user should use (e.g. "wayland" or "x11")
751739
+        </doc:para>
751739
+      </doc:description>
751739
+    </doc:doc>
751739
+  </property>
751739
+
751739
   <property name="XSession" type="s" access="read">
751739
     <doc:doc>
751739
       <doc:description>
751739
         <doc:para>
751739
           The users x session.
751739
         </doc:para>
751739
       </doc:description>
751739
     </doc:doc>
751739
   </property>
751739
 
751739
   <property name="Location" type="s" access="read">
751739
     <doc:doc>
751739
       <doc:description>
751739
         <doc:para>
751739
           The users location.
751739
         </doc:para>
751739
       </doc:description>
751739
     </doc:doc>
751739
   </property>
751739
 
751739
   <property name="LoginFrequency" type="t" access="read">
751739
     <doc:doc>
751739
       <doc:description>
751739
         <doc:para>
751739
           How often the user has logged in.
751739
         </doc:para>
751739
       </doc:description>
751739
     </doc:doc>
751739
   </property>
751739
 
751739
diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c
751739
index 7162221..dd8f81b 100644
751739
--- a/src/libaccountsservice/act-user.c
751739
+++ b/src/libaccountsservice/act-user.c
751739
@@ -999,60 +999,98 @@ act_user_get_icon_file (ActUser *user)
751739
 const char *
751739
 act_user_get_language (ActUser *user)
751739
 {
751739
         g_return_val_if_fail (ACT_IS_USER (user), NULL);
751739
 
751739
         if (user->accounts_proxy == NULL)
751739
                 return NULL;
751739
 
751739
         return accounts_user_get_language (user->accounts_proxy);
751739
 }
751739
 
751739
 /**
751739
  * act_user_get_x_session:
751739
  * @user: a #ActUser
751739
  *
751739
  * Returns the path to the configured X session for @user.
751739
  *
751739
  * Returns: (transfer none): a path to an icon
751739
  */
751739
 const char *
751739
 act_user_get_x_session (ActUser *user)
751739
 {
751739
         g_return_val_if_fail (ACT_IS_USER (user), NULL);
751739
 
751739
         if (user->accounts_proxy == NULL)
751739
                 return NULL;
751739
 
751739
         return accounts_user_get_xsession (user->accounts_proxy);
751739
 }
751739
 
751739
+/**
751739
+ * act_user_get_session:
751739
+ * @user: a #ActUser
751739
+ *
751739
+ * Returns the path to the configured session for @user.
751739
+ *
751739
+ * Returns: (transfer none): a path to an icon
751739
+ */
751739
+const char *
751739
+act_user_get_session (ActUser *user)
751739
+{
751739
+        g_return_val_if_fail (ACT_IS_USER (user), NULL);
751739
+
751739
+        if (user->accounts_proxy == NULL)
751739
+                return NULL;
751739
+
751739
+        return accounts_user_get_session (user->accounts_proxy);
751739
+}
751739
+
751739
+/**
751739
+ * act_user_get_session_type:
751739
+ * @user: a #ActUser
751739
+ *
751739
+ * Returns the type of the configured session for @user.
751739
+ *
751739
+ * Returns: (transfer none): a path to an icon
751739
+ */
751739
+const char *
751739
+act_user_get_session_type (ActUser *user)
751739
+{
751739
+        g_return_val_if_fail (ACT_IS_USER (user), NULL);
751739
+
751739
+        if (user->accounts_proxy == NULL)
751739
+                return NULL;
751739
+
751739
+        return accounts_user_get_session_type (user->accounts_proxy);
751739
+}
751739
+
751739
 /**
751739
  * act_user_get_object_path:
751739
  * @user: a #ActUser
751739
  *
751739
  * Returns the user accounts service object path of @user,
751739
  * or %NULL if @user doesn't have an object path associated
751739
  * with it.
751739
  *
751739
  * Returns: (transfer none): the object path of the user
751739
  */
751739
 const char *
751739
 act_user_get_object_path (ActUser *user)
751739
 {
751739
         g_return_val_if_fail (ACT_IS_USER (user), NULL);
751739
 
751739
         if (user->accounts_proxy == NULL)
751739
                 return NULL;
751739
 
751739
         return g_dbus_proxy_get_object_path (G_DBUS_PROXY (user->accounts_proxy));
751739
 }
751739
 
751739
 /**
751739
  * act_user_get_primary_session_id:
751739
  * @user: a #ActUser
751739
  *
751739
  * Returns the id of the primary session of @user, or %NULL if @user
751739
  * has no primary session.  The primary session will always be
751739
  * graphical and will be chosen from the sessions on the same seat as
751739
  * the seat of the session of the calling process.
751739
  *
751739
@@ -1310,60 +1348,115 @@ act_user_set_language (ActUser    *user,
751739
 }
751739
 
751739
 /**
751739
  * act_user_set_x_session:
751739
  * @user: the user object to alter.
751739
  * @x_session: an x session (e.g. gnome)
751739
  *
751739
  * Assigns a new x session for @user.
751739
  *
751739
  * Note this function is synchronous and ignores errors.
751739
  **/
751739
 void
751739
 act_user_set_x_session (ActUser    *user,
751739
                         const char *x_session)
751739
 {
751739
         g_autoptr(GError) error = NULL;
751739
 
751739
         g_return_if_fail (ACT_IS_USER (user));
751739
         g_return_if_fail (x_session != NULL);
751739
         g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
751739
 
751739
         if (!accounts_user_call_set_xsession_sync (user->accounts_proxy,
751739
                                                    x_session,
751739
                                                    NULL,
751739
                                                    &error)) {
751739
                 g_warning ("SetXSession call failed: %s", error->message);
751739
                 return;
751739
         }
751739
 }
751739
 
751739
+/**
751739
+ * act_user_set_session:
751739
+ * @user: the user object to alter.
751739
+ * @session: a session (e.g. gnome)
751739
+ *
751739
+ * Assigns a new session for @user.
751739
+ *
751739
+ * Note this function is synchronous and ignores errors.
751739
+ **/
751739
+void
751739
+act_user_set_session (ActUser    *user,
751739
+                      const char *session)
751739
+{
751739
+        g_autoptr(GError) error = NULL;
751739
+
751739
+        g_return_if_fail (ACT_IS_USER (user));
751739
+        g_return_if_fail (session != NULL);
751739
+        g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
751739
+
751739
+        if (!accounts_user_call_set_session_sync (user->accounts_proxy,
751739
+                                                  session,
751739
+                                                  NULL,
751739
+                                                  &error)) {
751739
+                g_warning ("SetSession call failed: %s", error->message);
751739
+                return;
751739
+        }
751739
+}
751739
+
751739
+/**
751739
+ * act_user_set_session_type:
751739
+ * @user: the user object to alter.
751739
+ * @session_type: a type of session (e.g. "wayland" or "x11")
751739
+ *
751739
+ * Assigns a type to the session for @user.
751739
+ *
751739
+ * Note this function is synchronous and ignores errors.
751739
+ **/
751739
+void
751739
+act_user_set_session_type (ActUser    *user,
751739
+                           const char *session_type)
751739
+{
751739
+        g_autoptr(GError) error = NULL;
751739
+
751739
+        g_return_if_fail (ACT_IS_USER (user));
751739
+        g_return_if_fail (session_type != NULL);
751739
+        g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
751739
+
751739
+        if (!accounts_user_call_set_session_type_sync (user->accounts_proxy,
751739
+                                                       session_type,
751739
+                                                       NULL,
751739
+                                                       &error)) {
751739
+                g_warning ("SetSessionType call failed: %s", error->message);
751739
+                return;
751739
+        }
751739
+}
751739
 
751739
 /**
751739
  * act_user_set_location:
751739
  * @user: the user object to alter.
751739
  * @location: a location
751739
  *
751739
  * Assigns a new location for @user.
751739
  *
751739
  * Note this function is synchronous and ignores errors.
751739
  **/
751739
 void
751739
 act_user_set_location (ActUser    *user,
751739
                        const char *location)
751739
 {
751739
         g_autoptr(GError) error = NULL;
751739
 
751739
         g_return_if_fail (ACT_IS_USER (user));
751739
         g_return_if_fail (location != NULL);
751739
         g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
751739
 
751739
         if (!accounts_user_call_set_location_sync (user->accounts_proxy,
751739
                                                    location,
751739
                                                    NULL,
751739
                                                    &error)) {
751739
                 g_warning ("SetLocation call failed: %s", error->message);
751739
                 return;
751739
         }
751739
 }
751739
 
751739
 /**
751739
diff --git a/src/libaccountsservice/act-user.h b/src/libaccountsservice/act-user.h
751739
index c685fcc..2ef13b1 100644
751739
--- a/src/libaccountsservice/act-user.h
751739
+++ b/src/libaccountsservice/act-user.h
751739
@@ -51,79 +51,85 @@ typedef struct _ActUserClass ActUserClass;
751739
 
751739
 GType          act_user_get_type                  (void) G_GNUC_CONST;
751739
 
751739
 const char    *act_user_get_object_path           (ActUser *user);
751739
 
751739
 uid_t          act_user_get_uid                   (ActUser   *user);
751739
 const char    *act_user_get_user_name             (ActUser   *user);
751739
 const char    *act_user_get_real_name             (ActUser   *user);
751739
 ActUserAccountType act_user_get_account_type      (ActUser   *user);
751739
 ActUserPasswordMode act_user_get_password_mode    (ActUser   *user);
751739
 const char    *act_user_get_password_hint         (ActUser   *user);
751739
 const char    *act_user_get_home_dir              (ActUser   *user);
751739
 const char    *act_user_get_shell                 (ActUser   *user);
751739
 const char    *act_user_get_email                 (ActUser   *user);
751739
 const char    *act_user_get_location              (ActUser   *user);
751739
 guint          act_user_get_num_sessions          (ActUser   *user);
751739
 guint          act_user_get_num_sessions_anywhere (ActUser   *user);
751739
 gboolean       act_user_is_logged_in              (ActUser   *user);
751739
 gboolean       act_user_is_logged_in_anywhere     (ActUser   *user);
751739
 int            act_user_get_login_frequency       (ActUser   *user);
751739
 gint64         act_user_get_login_time            (ActUser   *user);
751739
 const GVariant*act_user_get_login_history         (ActUser   *user);
751739
 gboolean       act_user_get_locked                (ActUser   *user);
751739
 gboolean       act_user_get_automatic_login       (ActUser   *user);
751739
 gboolean       act_user_is_system_account         (ActUser   *user);
751739
 gboolean       act_user_is_local_account          (ActUser   *user);
751739
 gboolean       act_user_is_nonexistent            (ActUser   *user);
751739
 const char    *act_user_get_icon_file             (ActUser   *user);
751739
 const char    *act_user_get_language              (ActUser   *user);
751739
 const char    *act_user_get_x_session             (ActUser   *user);
751739
+const char    *act_user_get_session               (ActUser   *user);
751739
+const char    *act_user_get_session_type          (ActUser   *user);
751739
 const char    *act_user_get_primary_session_id    (ActUser   *user);
751739
 
751739
 gint           act_user_collate                   (ActUser   *user1,
751739
                                                    ActUser   *user2);
751739
 gboolean       act_user_is_loaded                 (ActUser   *user);
751739
 
751739
 void           act_user_get_password_expiration_policy (ActUser   *user,
751739
                                                         gint64    *expiration_time,
751739
                                                         gint64    *last_change_time,
751739
                                                         gint64    *min_days_between_changes,
751739
                                                         gint64    *max_days_between_changes,
751739
                                                         gint64    *days_to_warn,
751739
                                                         gint64    *days_after_expiration_until_lock);
751739
 
751739
 void           act_user_set_email                 (ActUser    *user,
751739
                                                    const char *email);
751739
 void           act_user_set_language              (ActUser    *user,
751739
                                                    const char *language);
751739
 void           act_user_set_x_session             (ActUser    *user,
751739
                                                    const char *x_session);
751739
+void           act_user_set_session               (ActUser    *user,
751739
+                                                   const char *session);
751739
+void           act_user_set_session_type          (ActUser    *user,
751739
+                                                   const char *session_type);
751739
 void           act_user_set_location              (ActUser    *user,
751739
                                                    const char *location);
751739
 void           act_user_set_user_name             (ActUser    *user,
751739
                                                    const char  *user_name);
751739
 void           act_user_set_real_name             (ActUser    *user,
751739
                                                    const char *real_name);
751739
 void           act_user_set_icon_file             (ActUser    *user,
751739
                                                    const char *icon_file);
751739
 void           act_user_set_account_type          (ActUser    *user,
751739
                                                    ActUserAccountType account_type);
751739
 void           act_user_set_password              (ActUser     *user,
751739
                                                    const gchar *password,
751739
                                                    const gchar *hint);
751739
 void           act_user_set_password_hint         (ActUser             *user,
751739
                                                    const gchar *hint);
751739
 void           act_user_set_password_mode         (ActUser             *user,
751739
                                                    ActUserPasswordMode  password_mode);
751739
 void           act_user_set_locked                (ActUser    *user,
751739
                                                    gboolean    locked);
751739
 void           act_user_set_automatic_login       (ActUser   *user,
751739
                                                    gboolean  enabled);
751739
 
751739
 #if GLIB_CHECK_VERSION(2, 44, 0)
751739
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (ActUser, g_object_unref)
751739
 #endif
751739
 
751739
 G_END_DECLS
751739
 
751739
 #endif /* __ACT_USER_H__ */
751739
diff --git a/src/user.c b/src/user.c
751739
index 174530f..94c0244 100644
751739
--- a/src/user.c
751739
+++ b/src/user.c
751739
@@ -232,60 +232,75 @@ user_update_from_pwent (User          *user,
751739
                 user->account_expiration_policy_known = TRUE;
751739
         }
751739
 
751739
         accounts_user_set_password_mode (ACCOUNTS_USER (user), mode);
751739
         is_system_account = !user_classify_is_human (accounts_user_get_uid (ACCOUNTS_USER (user)),
751739
                                                      accounts_user_get_user_name (ACCOUNTS_USER (user)),
751739
                                                      accounts_user_get_shell (ACCOUNTS_USER (user)),
751739
                                                      passwd);
751739
         accounts_user_set_system_account (ACCOUNTS_USER (user), is_system_account);
751739
 
751739
         g_object_thaw_notify (G_OBJECT (user));
751739
 }
751739
 
751739
 void
751739
 user_update_from_keyfile (User     *user,
751739
                           GKeyFile *keyfile)
751739
 {
751739
         gchar *s;
751739
 
751739
         g_object_freeze_notify (G_OBJECT (user));
751739
 
751739
         s = g_key_file_get_string (keyfile, "User", "Language", NULL);
751739
         if (s != NULL) {
751739
                 accounts_user_set_language (ACCOUNTS_USER (user), s);
751739
                 g_clear_pointer (&s, g_free);
751739
         }
751739
 
751739
         s = g_key_file_get_string (keyfile, "User", "XSession", NULL);
751739
         if (s != NULL) {
751739
                 accounts_user_set_xsession (ACCOUNTS_USER (user), s);
751739
+
751739
+                /* for backward compat */
751739
+                accounts_user_set_session (ACCOUNTS_USER (user), s);
751739
+                g_clear_pointer (&s, g_free);
751739
+        }
751739
+
751739
+        s = g_key_file_get_string (keyfile, "User", "Session", NULL);
751739
+        if (s != NULL) {
751739
+                accounts_user_set_session (ACCOUNTS_USER (user), s);
751739
+                g_clear_pointer (&s, g_free);
751739
+        }
751739
+
751739
+        s = g_key_file_get_string (keyfile, "User", "SessionType", NULL);
751739
+        if (s != NULL) {
751739
+                accounts_user_set_session_type (ACCOUNTS_USER (user), s);
751739
                 g_clear_pointer (&s, g_free);
751739
         }
751739
 
751739
         s = g_key_file_get_string (keyfile, "User", "Email", NULL);
751739
         if (s != NULL) {
751739
                 accounts_user_set_email (ACCOUNTS_USER (user), s);
751739
                 g_clear_pointer (&s, g_free);
751739
         }
751739
 
751739
         s = g_key_file_get_string (keyfile, "User", "Location", NULL);
751739
         if (s != NULL) {
751739
                 accounts_user_set_location (ACCOUNTS_USER (user), s);
751739
                 g_clear_pointer (&s, g_free);
751739
         }
751739
 
751739
         s = g_key_file_get_string (keyfile, "User", "PasswordHint", NULL);
751739
         if (s != NULL) {
751739
                 accounts_user_set_password_hint (ACCOUNTS_USER (user), s);
751739
                 g_clear_pointer (&s, g_free);
751739
         }
751739
 
751739
         s = g_key_file_get_string (keyfile, "User", "Icon", NULL);
751739
         if (s != NULL) {
751739
                 accounts_user_set_icon_file (ACCOUNTS_USER (user), s);
751739
                 g_clear_pointer (&s, g_free);
751739
         }
751739
 
751739
         if (g_key_file_has_key (keyfile, "User", "SystemAccount", NULL)) {
751739
             gboolean system_account;
751739
 
751739
@@ -299,60 +314,66 @@ user_update_from_keyfile (User     *user,
751739
 
751739
         g_object_thaw_notify (G_OBJECT (user));
751739
 }
751739
 
751739
 void
751739
 user_update_local_account_property (User          *user,
751739
                                     gboolean       local)
751739
 {
751739
         accounts_user_set_local_account (ACCOUNTS_USER (user), local);
751739
 }
751739
 
751739
 void
751739
 user_update_system_account_property (User          *user,
751739
                                      gboolean       system)
751739
 {
751739
         accounts_user_set_system_account (ACCOUNTS_USER (user), system);
751739
 }
751739
 
751739
 static void
751739
 user_save_to_keyfile (User     *user,
751739
                       GKeyFile *keyfile)
751739
 {
751739
         g_key_file_remove_group (keyfile, "User", NULL);
751739
 
751739
         if (accounts_user_get_email (ACCOUNTS_USER (user)))
751739
                 g_key_file_set_string (keyfile, "User", "Email", accounts_user_get_email (ACCOUNTS_USER (user)));
751739
 
751739
         if (accounts_user_get_language (ACCOUNTS_USER (user)))
751739
                 g_key_file_set_string (keyfile, "User", "Language", accounts_user_get_language (ACCOUNTS_USER (user)));
751739
 
751739
+        if (accounts_user_get_session (ACCOUNTS_USER (user)))
751739
+                g_key_file_set_string (keyfile, "User", "Session", accounts_user_get_session (ACCOUNTS_USER (user)));
751739
+
751739
+        if (accounts_user_get_session_type (ACCOUNTS_USER (user)))
751739
+                g_key_file_set_string (keyfile, "User", "SessionType", accounts_user_get_session_type (ACCOUNTS_USER (user)));
751739
+
751739
         if (accounts_user_get_xsession (ACCOUNTS_USER (user)))
751739
                 g_key_file_set_string (keyfile, "User", "XSession", accounts_user_get_xsession (ACCOUNTS_USER (user)));
751739
 
751739
         if (accounts_user_get_location (ACCOUNTS_USER (user)))
751739
                 g_key_file_set_string (keyfile, "User", "Location", accounts_user_get_location (ACCOUNTS_USER (user)));
751739
 
751739
         if (accounts_user_get_password_hint (ACCOUNTS_USER (user)))
751739
                 g_key_file_set_string (keyfile, "User", "PasswordHint", accounts_user_get_password_hint (ACCOUNTS_USER (user)));
751739
 
751739
         if (accounts_user_get_icon_file (ACCOUNTS_USER (user)))
751739
                 g_key_file_set_string (keyfile, "User", "Icon", accounts_user_get_icon_file (ACCOUNTS_USER (user)));
751739
 
751739
         g_key_file_set_boolean (keyfile, "User", "SystemAccount", accounts_user_get_system_account (ACCOUNTS_USER (user)));
751739
 
751739
         user_set_cached (user, TRUE);
751739
 }
751739
 
751739
 static void
751739
 save_extra_data (User *user)
751739
 {
751739
         g_autofree gchar *data = NULL;
751739
         g_autofree gchar *filename = NULL;
751739
         g_autoptr(GError) error = NULL;
751739
 
751739
         user_save_to_keyfile (user, user->keyfile);
751739
 
751739
         data = g_key_file_to_data (user->keyfile, NULL, &error);
751739
         if (data == NULL) {
751739
                 g_warning ("Saving data for user %s failed: %s",
751739
                            accounts_user_get_user_name (ACCOUNTS_USER (user)), error->message);
751739
@@ -996,60 +1017,158 @@ static gboolean
751739
 user_set_language (AccountsUser          *auser,
751739
                    GDBusMethodInvocation *context,
751739
                    const gchar           *language)
751739
 {
751739
         User *user = (User*)auser;
751739
         int uid;
751739
         const gchar *action_id;
751739
 
751739
         if (!get_caller_uid (context, &uid)) {
751739
                 throw_error (context, ERROR_FAILED, "identifying caller failed");
751739
                 return FALSE;
751739
         }
751739
 
751739
         if (accounts_user_get_uid (ACCOUNTS_USER (user)) == (uid_t) uid)
751739
                 action_id = "org.freedesktop.accounts.change-own-user-data";
751739
         else
751739
                 action_id = "org.freedesktop.accounts.user-administration";
751739
 
751739
         daemon_local_check_auth (user->daemon,
751739
                                  user,
751739
                                  action_id,
751739
                                  TRUE,
751739
                                  user_change_language_authorized_cb,
751739
                                  context,
751739
                                  g_strdup (language),
751739
                                  (GDestroyNotify)g_free);
751739
 
751739
         return TRUE;
751739
 }
751739
 
751739
+static void
751739
+user_change_session_authorized_cb (Daemon                *daemon,
751739
+                                   User                  *user,
751739
+                                   GDBusMethodInvocation *context,
751739
+                                   gpointer               user_data)
751739
+
751739
+{
751739
+        const gchar *session = user_data;
751739
+
751739
+        if (g_strcmp0 (accounts_user_get_session (ACCOUNTS_USER (user)), session) != 0) {
751739
+                accounts_user_set_session (ACCOUNTS_USER (user), session);
751739
+
751739
+                save_extra_data (user);
751739
+        }
751739
+
751739
+        accounts_user_complete_set_session (ACCOUNTS_USER (user), context);
751739
+}
751739
+
751739
+static gboolean
751739
+user_set_session (AccountsUser          *auser,
751739
+                  GDBusMethodInvocation *context,
751739
+                  const gchar           *session)
751739
+{
751739
+        User *user = (User*)auser;
751739
+        int uid;
751739
+        const gchar *action_id;
751739
+
751739
+        if (!get_caller_uid (context, &uid)) {
751739
+                throw_error (context, ERROR_FAILED, "identifying caller failed");
751739
+                return FALSE;
751739
+        }
751739
+
751739
+        if (accounts_user_get_uid (ACCOUNTS_USER (user)) == (uid_t) uid)
751739
+                action_id = "org.freedesktop.accounts.change-own-user-data";
751739
+        else
751739
+                action_id = "org.freedesktop.accounts.user-administration";
751739
+
751739
+        daemon_local_check_auth (user->daemon,
751739
+                                 user,
751739
+                                 action_id,
751739
+                                 TRUE,
751739
+                                 user_change_session_authorized_cb,
751739
+                                 context,
751739
+                                 g_strdup (session),
751739
+                                 (GDestroyNotify) g_free);
751739
+
751739
+        return TRUE;
751739
+}
751739
+
751739
+static void
751739
+user_change_session_type_authorized_cb (Daemon                *daemon,
751739
+                                        User                  *user,
751739
+                                        GDBusMethodInvocation *context,
751739
+                                        gpointer               user_data)
751739
+
751739
+{
751739
+        const gchar *session_type = user_data;
751739
+
751739
+        if (g_strcmp0 (accounts_user_get_session_type (ACCOUNTS_USER (user)), session_type) != 0) {
751739
+                accounts_user_set_session_type (ACCOUNTS_USER (user), session_type);
751739
+
751739
+                save_extra_data (user);
751739
+        }
751739
+
751739
+        accounts_user_complete_set_session_type (ACCOUNTS_USER (user), context);
751739
+}
751739
+
751739
+static gboolean
751739
+user_set_session_type (AccountsUser          *auser,
751739
+                       GDBusMethodInvocation *context,
751739
+                       const gchar           *session_type)
751739
+{
751739
+        User *user = (User*)auser;
751739
+        int uid;
751739
+        const gchar *action_id;
751739
+
751739
+        if (!get_caller_uid (context, &uid)) {
751739
+                throw_error (context, ERROR_FAILED, "identifying caller failed");
751739
+                return FALSE;
751739
+        }
751739
+
751739
+        if (accounts_user_get_uid (ACCOUNTS_USER (user)) == (uid_t) uid)
751739
+                action_id = "org.freedesktop.accounts.change-own-user-data";
751739
+        else
751739
+                action_id = "org.freedesktop.accounts.user-administration";
751739
+
751739
+        daemon_local_check_auth (user->daemon,
751739
+                                 user,
751739
+                                 action_id,
751739
+                                 TRUE,
751739
+                                 user_change_session_type_authorized_cb,
751739
+                                 context,
751739
+                                 g_strdup (session_type),
751739
+                                 (GDestroyNotify) g_free);
751739
+
751739
+        return TRUE;
751739
+}
751739
+
751739
 static void
751739
 user_change_x_session_authorized_cb (Daemon                *daemon,
751739
                                      User                  *user,
751739
                                      GDBusMethodInvocation *context,
751739
                                      gpointer               data)
751739
 
751739
 {
751739
         gchar *x_session = data;
751739
 
751739
         if (g_strcmp0 (accounts_user_get_xsession (ACCOUNTS_USER (user)), x_session) != 0) {
751739
                 accounts_user_set_xsession (ACCOUNTS_USER (user), x_session);
751739
 
751739
                 save_extra_data (user);
751739
         }
751739
 
751739
         accounts_user_complete_set_xsession (ACCOUNTS_USER (user), context);
751739
 }
751739
 
751739
 static gboolean
751739
 user_set_x_session (AccountsUser          *auser,
751739
                     GDBusMethodInvocation *context,
751739
                     const gchar           *x_session)
751739
 {
751739
         User *user = (User*)auser;
751739
         int uid;
751739
         const gchar *action_id;
751739
 
751739
         if (!get_caller_uid (context, &uid)) {
751739
                 throw_error (context, ERROR_FAILED, "identifying caller failed");
751739
                 return FALSE;
751739
@@ -1966,41 +2085,43 @@ user_finalize (GObject *object)
751739
 }
751739
 
751739
 static void
751739
 user_class_init (UserClass *class)
751739
 {
751739
         GObjectClass *gobject_class;
751739
 
751739
         gobject_class = G_OBJECT_CLASS (class);
751739
 
751739
         gobject_class->finalize = user_finalize;
751739
 }
751739
 
751739
 static void
751739
 user_accounts_user_iface_init (AccountsUserIface *iface)
751739
 {
751739
         iface->handle_set_account_type = user_set_account_type;
751739
         iface->handle_set_automatic_login = user_set_automatic_login;
751739
         iface->handle_set_email = user_set_email;
751739
         iface->handle_set_home_directory = user_set_home_directory;
751739
         iface->handle_set_icon_file = user_set_icon_file;
751739
         iface->handle_set_language = user_set_language;
751739
         iface->handle_set_location = user_set_location;
751739
         iface->handle_set_locked = user_set_locked;
751739
         iface->handle_set_password = user_set_password;
751739
         iface->handle_set_password_mode = user_set_password_mode;
751739
         iface->handle_set_password_hint = user_set_password_hint;
751739
         iface->handle_set_real_name = user_set_real_name;
751739
         iface->handle_set_shell = user_set_shell;
751739
         iface->handle_set_user_name = user_set_user_name;
751739
         iface->handle_set_xsession = user_set_x_session;
751739
+        iface->handle_set_session = user_set_session;
751739
+        iface->handle_set_session_type = user_set_session_type;
751739
         iface->handle_get_password_expiration_policy = user_get_password_expiration_policy;
751739
 }
751739
 
751739
 static void
751739
 user_init (User *user)
751739
 {
751739
         user->system_bus_connection = NULL;
751739
         user->default_icon_file = NULL;
751739
         user->login_history = NULL;
751739
         user->keyfile = g_key_file_new ();
751739
 }
751739
-- 
751739
2.17.1
751739