Blame SOURCES/0001-user-add-new-Session-SessionType-properties-to-repla.patch

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