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