|
|
f83012 |
From e625a214d531635db1e48b2dc51ed0e09ef8005b Mon Sep 17 00:00:00 2001
|
|
|
f83012 |
From: Ray Strode <rstrode@redhat.com>
|
|
|
f83012 |
Date: Tue, 14 Aug 2018 14:52:41 -0400
|
|
|
f83012 |
Subject: [PATCH 2/4] session: support new accountsservice Session and
|
|
|
f83012 |
SessionType props
|
|
|
f83012 |
|
|
|
f83012 |
At the moment the user's session is stored in a property called
|
|
|
f83012 |
"XSession". This is pretty weird if the user is using wayland.
|
|
|
f83012 |
|
|
|
f83012 |
AccountService now supports a more generic property "Session" and
|
|
|
f83012 |
a related "SessionType" property to replace "XSession".
|
|
|
f83012 |
|
|
|
f83012 |
This commit switches GDM over to use the new properties.
|
|
|
f83012 |
---
|
|
|
f83012 |
daemon/gdm-session-settings.c | 61 ++++++++++++++++++++++++---
|
|
|
f83012 |
daemon/gdm-session-settings.h | 3 ++
|
|
|
f83012 |
daemon/gdm-session-worker.c | 28 +++++++++++++
|
|
|
f83012 |
daemon/gdm-session-worker.xml | 3 ++
|
|
|
f83012 |
daemon/gdm-session.c | 78 ++++++++++++++++++++++++++---------
|
|
|
f83012 |
5 files changed, 148 insertions(+), 25 deletions(-)
|
|
|
f83012 |
|
|
|
f83012 |
diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c
|
|
|
f83012 |
index 933f095bc..8463fad32 100644
|
|
|
f83012 |
--- a/daemon/gdm-session-settings.c
|
|
|
f83012 |
+++ b/daemon/gdm-session-settings.c
|
|
|
f83012 |
@@ -12,114 +12,121 @@
|
|
|
f83012 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
f83012 |
* GNU General Public License for more details.
|
|
|
f83012 |
*
|
|
|
f83012 |
* You should have received a copy of the GNU General Public License
|
|
|
f83012 |
* along with this program; if not, write to the Free Software
|
|
|
f83012 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
f83012 |
* 02110-1301, USA.
|
|
|
f83012 |
*
|
|
|
f83012 |
* Written by: Ray Strode <rstrode@redhat.com>
|
|
|
f83012 |
*/
|
|
|
f83012 |
#include "config.h"
|
|
|
f83012 |
#include "gdm-session-settings.h"
|
|
|
f83012 |
|
|
|
f83012 |
#include <errno.h>
|
|
|
f83012 |
#include <pwd.h>
|
|
|
f83012 |
#include <string.h>
|
|
|
f83012 |
#include <sys/types.h>
|
|
|
f83012 |
#include <unistd.h>
|
|
|
f83012 |
|
|
|
f83012 |
#include <glib.h>
|
|
|
f83012 |
#include <glib-object.h>
|
|
|
f83012 |
#include <glib/gi18n.h>
|
|
|
f83012 |
|
|
|
f83012 |
#include <act/act-user-manager.h>
|
|
|
f83012 |
|
|
|
f83012 |
struct _GdmSessionSettingsPrivate
|
|
|
f83012 |
{
|
|
|
f83012 |
ActUserManager *user_manager;
|
|
|
f83012 |
ActUser *user;
|
|
|
f83012 |
char *session_name;
|
|
|
f83012 |
+ char *session_type;
|
|
|
f83012 |
char *language_name;
|
|
|
f83012 |
};
|
|
|
f83012 |
|
|
|
f83012 |
static void gdm_session_settings_finalize (GObject *object);
|
|
|
f83012 |
static void gdm_session_settings_class_install_properties (GdmSessionSettingsClass *
|
|
|
f83012 |
settings_class);
|
|
|
f83012 |
|
|
|
f83012 |
static void gdm_session_settings_set_property (GObject *object,
|
|
|
f83012 |
guint prop_id,
|
|
|
f83012 |
const GValue *value,
|
|
|
f83012 |
GParamSpec *pspec);
|
|
|
f83012 |
static void gdm_session_settings_get_property (GObject *object,
|
|
|
f83012 |
guint prop_id,
|
|
|
f83012 |
GValue *value,
|
|
|
f83012 |
GParamSpec *pspec);
|
|
|
f83012 |
|
|
|
f83012 |
enum {
|
|
|
f83012 |
PROP_0 = 0,
|
|
|
f83012 |
PROP_SESSION_NAME,
|
|
|
f83012 |
+ PROP_SESSION_TYPE,
|
|
|
f83012 |
PROP_LANGUAGE_NAME,
|
|
|
f83012 |
PROP_IS_LOADED
|
|
|
f83012 |
};
|
|
|
f83012 |
|
|
|
f83012 |
G_DEFINE_TYPE (GdmSessionSettings, gdm_session_settings, G_TYPE_OBJECT)
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
gdm_session_settings_class_init (GdmSessionSettingsClass *settings_class)
|
|
|
f83012 |
{
|
|
|
f83012 |
GObjectClass *object_class;
|
|
|
f83012 |
|
|
|
f83012 |
object_class = G_OBJECT_CLASS (settings_class);
|
|
|
f83012 |
|
|
|
f83012 |
object_class->finalize = gdm_session_settings_finalize;
|
|
|
f83012 |
|
|
|
f83012 |
gdm_session_settings_class_install_properties (settings_class);
|
|
|
f83012 |
|
|
|
f83012 |
g_type_class_add_private (settings_class, sizeof (GdmSessionSettingsPrivate));
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
gdm_session_settings_class_install_properties (GdmSessionSettingsClass *settings_class)
|
|
|
f83012 |
{
|
|
|
f83012 |
GObjectClass *object_class;
|
|
|
f83012 |
GParamSpec *param_spec;
|
|
|
f83012 |
|
|
|
f83012 |
object_class = G_OBJECT_CLASS (settings_class);
|
|
|
f83012 |
object_class->set_property = gdm_session_settings_set_property;
|
|
|
f83012 |
object_class->get_property = gdm_session_settings_get_property;
|
|
|
f83012 |
|
|
|
f83012 |
param_spec = g_param_spec_string ("session-name", "Session Name",
|
|
|
f83012 |
"The name of the session",
|
|
|
f83012 |
NULL, G_PARAM_READWRITE);
|
|
|
f83012 |
g_object_class_install_property (object_class, PROP_SESSION_NAME, param_spec);
|
|
|
f83012 |
|
|
|
f83012 |
+ param_spec = g_param_spec_string ("session-type", "Session Type",
|
|
|
f83012 |
+ "The type of the session",
|
|
|
f83012 |
+ NULL, G_PARAM_READWRITE);
|
|
|
f83012 |
+ g_object_class_install_property (object_class, PROP_SESSION_TYPE, param_spec);
|
|
|
f83012 |
+
|
|
|
f83012 |
param_spec = g_param_spec_string ("language-name", "Language Name",
|
|
|
f83012 |
"The name of the language",
|
|
|
f83012 |
NULL,
|
|
|
f83012 |
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
|
|
f83012 |
g_object_class_install_property (object_class, PROP_LANGUAGE_NAME, param_spec);
|
|
|
f83012 |
|
|
|
f83012 |
param_spec = g_param_spec_boolean ("is-loaded", NULL, NULL,
|
|
|
f83012 |
FALSE, G_PARAM_READABLE);
|
|
|
f83012 |
g_object_class_install_property (object_class, PROP_IS_LOADED, param_spec);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
gdm_session_settings_init (GdmSessionSettings *settings)
|
|
|
f83012 |
{
|
|
|
f83012 |
settings->priv = G_TYPE_INSTANCE_GET_PRIVATE (settings,
|
|
|
f83012 |
GDM_TYPE_SESSION_SETTINGS,
|
|
|
f83012 |
GdmSessionSettingsPrivate);
|
|
|
f83012 |
|
|
|
f83012 |
settings->priv->user_manager = act_user_manager_get_default ();
|
|
|
f83012 |
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
gdm_session_settings_finalize (GObject *object)
|
|
|
f83012 |
{
|
|
|
f83012 |
GdmSessionSettings *settings;
|
|
|
f83012 |
GObjectClass *parent_class;
|
|
|
f83012 |
|
|
|
f83012 |
settings = GDM_SESSION_SETTINGS (object);
|
|
|
f83012 |
|
|
|
f83012 |
@@ -136,172 +143,212 @@ gdm_session_settings_finalize (GObject *object)
|
|
|
f83012 |
parent_class->finalize (object);
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
void
|
|
|
f83012 |
gdm_session_settings_set_language_name (GdmSessionSettings *settings,
|
|
|
f83012 |
const char *language_name)
|
|
|
f83012 |
{
|
|
|
f83012 |
g_return_if_fail (GDM_IS_SESSION_SETTINGS (settings));
|
|
|
f83012 |
|
|
|
f83012 |
if (settings->priv->language_name == NULL ||
|
|
|
f83012 |
strcmp (settings->priv->language_name, language_name) != 0) {
|
|
|
f83012 |
settings->priv->language_name = g_strdup (language_name);
|
|
|
f83012 |
g_object_notify (G_OBJECT (settings), "language-name");
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
void
|
|
|
f83012 |
gdm_session_settings_set_session_name (GdmSessionSettings *settings,
|
|
|
f83012 |
const char *session_name)
|
|
|
f83012 |
{
|
|
|
f83012 |
g_return_if_fail (GDM_IS_SESSION_SETTINGS (settings));
|
|
|
f83012 |
|
|
|
f83012 |
if (settings->priv->session_name == NULL ||
|
|
|
f83012 |
strcmp (settings->priv->session_name, session_name) != 0) {
|
|
|
f83012 |
settings->priv->session_name = g_strdup (session_name);
|
|
|
f83012 |
g_object_notify (G_OBJECT (settings), "session-name");
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
+void
|
|
|
f83012 |
+gdm_session_settings_set_session_type (GdmSessionSettings *settings,
|
|
|
f83012 |
+ const char *session_type)
|
|
|
f83012 |
+{
|
|
|
f83012 |
+ g_return_if_fail (GDM_IS_SESSION_SETTINGS (settings));
|
|
|
f83012 |
+
|
|
|
f83012 |
+ if (settings->priv->session_type == NULL ||
|
|
|
f83012 |
+ g_strcmp0 (settings->priv->session_type, session_type) != 0) {
|
|
|
f83012 |
+ settings->priv->session_type = g_strdup (session_type);
|
|
|
f83012 |
+ g_object_notify (G_OBJECT (settings), "session-type");
|
|
|
f83012 |
+ }
|
|
|
f83012 |
+}
|
|
|
f83012 |
+
|
|
|
f83012 |
char *
|
|
|
f83012 |
gdm_session_settings_get_language_name (GdmSessionSettings *settings)
|
|
|
f83012 |
{
|
|
|
f83012 |
g_return_val_if_fail (GDM_IS_SESSION_SETTINGS (settings), NULL);
|
|
|
f83012 |
return g_strdup (settings->priv->language_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
char *
|
|
|
f83012 |
gdm_session_settings_get_session_name (GdmSessionSettings *settings)
|
|
|
f83012 |
{
|
|
|
f83012 |
g_return_val_if_fail (GDM_IS_SESSION_SETTINGS (settings), NULL);
|
|
|
f83012 |
return g_strdup (settings->priv->session_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
+char *
|
|
|
f83012 |
+gdm_session_settings_get_session_type (GdmSessionSettings *settings)
|
|
|
f83012 |
+{
|
|
|
f83012 |
+ g_return_val_if_fail (GDM_IS_SESSION_SETTINGS (settings), NULL);
|
|
|
f83012 |
+ return g_strdup (settings->priv->session_type);
|
|
|
f83012 |
+}
|
|
|
f83012 |
+
|
|
|
f83012 |
static void
|
|
|
f83012 |
gdm_session_settings_set_property (GObject *object,
|
|
|
f83012 |
guint prop_id,
|
|
|
f83012 |
const GValue *value,
|
|
|
f83012 |
GParamSpec *pspec)
|
|
|
f83012 |
{
|
|
|
f83012 |
GdmSessionSettings *settings;
|
|
|
f83012 |
|
|
|
f83012 |
settings = GDM_SESSION_SETTINGS (object);
|
|
|
f83012 |
|
|
|
f83012 |
switch (prop_id) {
|
|
|
f83012 |
case PROP_LANGUAGE_NAME:
|
|
|
f83012 |
gdm_session_settings_set_language_name (settings, g_value_get_string (value));
|
|
|
f83012 |
break;
|
|
|
f83012 |
|
|
|
f83012 |
case PROP_SESSION_NAME:
|
|
|
f83012 |
gdm_session_settings_set_session_name (settings, g_value_get_string (value));
|
|
|
f83012 |
break;
|
|
|
f83012 |
|
|
|
f83012 |
+ case PROP_SESSION_TYPE:
|
|
|
f83012 |
+ gdm_session_settings_set_session_type (settings, g_value_get_string (value));
|
|
|
f83012 |
+ break;
|
|
|
f83012 |
+
|
|
|
f83012 |
default:
|
|
|
f83012 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
gdm_session_settings_get_property (GObject *object,
|
|
|
f83012 |
guint prop_id,
|
|
|
f83012 |
GValue *value,
|
|
|
f83012 |
GParamSpec *pspec)
|
|
|
f83012 |
{
|
|
|
f83012 |
GdmSessionSettings *settings;
|
|
|
f83012 |
|
|
|
f83012 |
settings = GDM_SESSION_SETTINGS (object);
|
|
|
f83012 |
|
|
|
f83012 |
switch (prop_id) {
|
|
|
f83012 |
case PROP_SESSION_NAME:
|
|
|
f83012 |
g_value_set_string (value, settings->priv->session_name);
|
|
|
f83012 |
break;
|
|
|
f83012 |
|
|
|
f83012 |
+ case PROP_SESSION_TYPE:
|
|
|
f83012 |
+ g_value_set_string (value, settings->priv->session_type);
|
|
|
f83012 |
+ break;
|
|
|
f83012 |
+
|
|
|
f83012 |
case PROP_LANGUAGE_NAME:
|
|
|
f83012 |
g_value_set_string (value, settings->priv->language_name);
|
|
|
f83012 |
break;
|
|
|
f83012 |
|
|
|
f83012 |
case PROP_IS_LOADED:
|
|
|
f83012 |
g_value_set_boolean (value, gdm_session_settings_is_loaded (settings));
|
|
|
f83012 |
break;
|
|
|
f83012 |
|
|
|
f83012 |
default:
|
|
|
f83012 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
GdmSessionSettings *
|
|
|
f83012 |
gdm_session_settings_new (void)
|
|
|
f83012 |
{
|
|
|
f83012 |
GdmSessionSettings *settings;
|
|
|
f83012 |
|
|
|
f83012 |
settings = g_object_new (GDM_TYPE_SESSION_SETTINGS,
|
|
|
f83012 |
NULL);
|
|
|
f83012 |
|
|
|
f83012 |
return settings;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
gboolean
|
|
|
f83012 |
gdm_session_settings_is_loaded (GdmSessionSettings *settings)
|
|
|
f83012 |
{
|
|
|
f83012 |
if (settings->priv->user == NULL) {
|
|
|
f83012 |
return FALSE;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
return act_user_is_loaded (settings->priv->user);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
load_settings_from_user (GdmSessionSettings *settings)
|
|
|
f83012 |
{
|
|
|
f83012 |
const char *session_name;
|
|
|
f83012 |
+ const char *session_type;
|
|
|
f83012 |
const char *language_name;
|
|
|
f83012 |
|
|
|
f83012 |
if (!act_user_is_loaded (settings->priv->user)) {
|
|
|
f83012 |
g_warning ("GdmSessionSettings: trying to load user settings from unloaded user");
|
|
|
f83012 |
return;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
- session_name = act_user_get_x_session (settings->priv->user);
|
|
|
f83012 |
- g_debug ("GdmSessionSettings: saved session is %s", session_name);
|
|
|
f83012 |
+ /* if the user doesn't have saved state, they don't have any settings worth reading */
|
|
|
f83012 |
+ if (!act_user_get_saved (settings->priv->user))
|
|
|
f83012 |
+ goto out;
|
|
|
f83012 |
+
|
|
|
f83012 |
+ session_type = act_user_get_session_type (settings->priv->user);
|
|
|
f83012 |
+ session_name = act_user_get_session (settings->priv->user);
|
|
|
f83012 |
|
|
|
f83012 |
- if (session_name != NULL) {
|
|
|
f83012 |
+ g_debug ("GdmSessionSettings: saved session is %s (type %s)", session_name, session_type);
|
|
|
f83012 |
+
|
|
|
f83012 |
+ if (session_type != NULL && session_type[0] != '\0') {
|
|
|
f83012 |
+ gdm_session_settings_set_session_type (settings, session_type);
|
|
|
f83012 |
+ }
|
|
|
f83012 |
+
|
|
|
f83012 |
+ if (session_name != NULL && session_name[0] != '\0') {
|
|
|
f83012 |
gdm_session_settings_set_session_name (settings, session_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
language_name = act_user_get_language (settings->priv->user);
|
|
|
f83012 |
|
|
|
f83012 |
g_debug ("GdmSessionSettings: saved language is %s", language_name);
|
|
|
f83012 |
- if (language_name != NULL) {
|
|
|
f83012 |
+ if (language_name != NULL && language_name[0] != '\0') {
|
|
|
f83012 |
gdm_session_settings_set_language_name (settings, language_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
+out:
|
|
|
f83012 |
g_object_notify (G_OBJECT (settings), "is-loaded");
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
on_user_is_loaded_changed (ActUser *user,
|
|
|
f83012 |
GParamSpec *pspec,
|
|
|
f83012 |
GdmSessionSettings *settings)
|
|
|
f83012 |
{
|
|
|
f83012 |
if (act_user_is_loaded (settings->priv->user)) {
|
|
|
f83012 |
load_settings_from_user (settings);
|
|
|
f83012 |
g_signal_handlers_disconnect_by_func (G_OBJECT (settings->priv->user),
|
|
|
f83012 |
G_CALLBACK (on_user_is_loaded_changed),
|
|
|
f83012 |
settings);
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
gboolean
|
|
|
f83012 |
gdm_session_settings_load (GdmSessionSettings *settings,
|
|
|
f83012 |
const char *username)
|
|
|
f83012 |
{
|
|
|
f83012 |
ActUser *old_user;
|
|
|
f83012 |
|
|
|
f83012 |
g_return_val_if_fail (settings != NULL, FALSE);
|
|
|
f83012 |
g_return_val_if_fail (username != NULL, FALSE);
|
|
|
f83012 |
g_return_val_if_fail (!gdm_session_settings_is_loaded (settings), FALSE);
|
|
|
f83012 |
|
|
|
f83012 |
if (settings->priv->user != NULL) {
|
|
|
f83012 |
old_user = settings->priv->user;
|
|
|
f83012 |
|
|
|
f83012 |
g_signal_handlers_disconnect_by_func (G_OBJECT (settings->priv->user),
|
|
|
f83012 |
@@ -322,40 +369,44 @@ gdm_session_settings_load (GdmSessionSettings *settings,
|
|
|
f83012 |
G_CALLBACK (on_user_is_loaded_changed),
|
|
|
f83012 |
settings);
|
|
|
f83012 |
return FALSE;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
load_settings_from_user (settings);
|
|
|
f83012 |
|
|
|
f83012 |
return TRUE;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
gboolean
|
|
|
f83012 |
gdm_session_settings_save (GdmSessionSettings *settings,
|
|
|
f83012 |
const char *username)
|
|
|
f83012 |
{
|
|
|
f83012 |
ActUser *user;
|
|
|
f83012 |
|
|
|
f83012 |
g_return_val_if_fail (GDM_IS_SESSION_SETTINGS (settings), FALSE);
|
|
|
f83012 |
g_return_val_if_fail (username != NULL, FALSE);
|
|
|
f83012 |
g_return_val_if_fail (gdm_session_settings_is_loaded (settings), FALSE);
|
|
|
f83012 |
|
|
|
f83012 |
user = act_user_manager_get_user (settings->priv->user_manager,
|
|
|
f83012 |
username);
|
|
|
f83012 |
|
|
|
f83012 |
|
|
|
f83012 |
if (!act_user_is_loaded (user)) {
|
|
|
f83012 |
g_object_unref (user);
|
|
|
f83012 |
return FALSE;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
if (settings->priv->session_name != NULL) {
|
|
|
f83012 |
- act_user_set_x_session (user, settings->priv->session_name);
|
|
|
f83012 |
+ act_user_set_session (user, settings->priv->session_name);
|
|
|
f83012 |
+ }
|
|
|
f83012 |
+
|
|
|
f83012 |
+ if (settings->priv->session_type != NULL) {
|
|
|
f83012 |
+ act_user_set_session_type (user, settings->priv->session_type);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
if (settings->priv->language_name != NULL) {
|
|
|
f83012 |
act_user_set_language (user, settings->priv->language_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
g_object_unref (user);
|
|
|
f83012 |
|
|
|
f83012 |
return TRUE;
|
|
|
f83012 |
}
|
|
|
f83012 |
diff --git a/daemon/gdm-session-settings.h b/daemon/gdm-session-settings.h
|
|
|
f83012 |
index 20946bff1..db38ffc72 100644
|
|
|
f83012 |
--- a/daemon/gdm-session-settings.h
|
|
|
f83012 |
+++ b/daemon/gdm-session-settings.h
|
|
|
f83012 |
@@ -33,37 +33,40 @@ G_BEGIN_DECLS
|
|
|
f83012 |
#define GDM_IS_SESSION_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_SESSION_SETTINGS))
|
|
|
f83012 |
#define GDM_SESSION_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SESSION_SETTINGS, GdmSessionSettingsClass))
|
|
|
f83012 |
#define GDM_SESSION_SETTINGS_ERROR (gdm_session_settings_error_quark ())
|
|
|
f83012 |
typedef struct _GdmSessionSettings GdmSessionSettings;
|
|
|
f83012 |
typedef struct _GdmSessionSettingsClass GdmSessionSettingsClass;
|
|
|
f83012 |
typedef struct _GdmSessionSettingsPrivate GdmSessionSettingsPrivate;
|
|
|
f83012 |
|
|
|
f83012 |
struct _GdmSessionSettings
|
|
|
f83012 |
{
|
|
|
f83012 |
GObject parent;
|
|
|
f83012 |
|
|
|
f83012 |
/*< private > */
|
|
|
f83012 |
GdmSessionSettingsPrivate *priv;
|
|
|
f83012 |
};
|
|
|
f83012 |
|
|
|
f83012 |
struct _GdmSessionSettingsClass
|
|
|
f83012 |
{
|
|
|
f83012 |
GObjectClass parent_class;
|
|
|
f83012 |
};
|
|
|
f83012 |
|
|
|
f83012 |
GType gdm_session_settings_get_type (void);
|
|
|
f83012 |
GdmSessionSettings *gdm_session_settings_new (void);
|
|
|
f83012 |
|
|
|
f83012 |
gboolean gdm_session_settings_load (GdmSessionSettings *settings,
|
|
|
f83012 |
const char *username);
|
|
|
f83012 |
gboolean gdm_session_settings_save (GdmSessionSettings *settings,
|
|
|
f83012 |
const char *username);
|
|
|
f83012 |
gboolean gdm_session_settings_is_loaded (GdmSessionSettings *settings);
|
|
|
f83012 |
char *gdm_session_settings_get_language_name (GdmSessionSettings *settings);
|
|
|
f83012 |
char *gdm_session_settings_get_session_name (GdmSessionSettings *settings);
|
|
|
f83012 |
+char *gdm_session_settings_get_session_type (GdmSessionSettings *settings);
|
|
|
f83012 |
void gdm_session_settings_set_language_name (GdmSessionSettings *settings,
|
|
|
f83012 |
const char *language_name);
|
|
|
f83012 |
void gdm_session_settings_set_session_name (GdmSessionSettings *settings,
|
|
|
f83012 |
const char *session_name);
|
|
|
f83012 |
+void gdm_session_settings_set_session_type (GdmSessionSettings *settings,
|
|
|
f83012 |
+ const char *session_type);
|
|
|
f83012 |
|
|
|
f83012 |
G_END_DECLS
|
|
|
f83012 |
#endif /* GDM_SESSION_SETTINGS_H */
|
|
|
f83012 |
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
|
|
|
f83012 |
index e79073996..ae86d28ac 100644
|
|
|
f83012 |
--- a/daemon/gdm-session-worker.c
|
|
|
f83012 |
+++ b/daemon/gdm-session-worker.c
|
|
|
f83012 |
@@ -2539,60 +2539,74 @@ gdm_session_worker_handle_set_language_name (GdmDBusWorker *object,
|
|
|
f83012 |
gdm_dbus_worker_complete_set_language_name (object, invocation);
|
|
|
f83012 |
return TRUE;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
on_saved_language_name_read (GdmSessionWorker *worker)
|
|
|
f83012 |
{
|
|
|
f83012 |
char *language_name;
|
|
|
f83012 |
|
|
|
f83012 |
language_name = gdm_session_settings_get_language_name (worker->priv->user_settings);
|
|
|
f83012 |
|
|
|
f83012 |
g_debug ("GdmSessionWorker: Saved language is %s", language_name);
|
|
|
f83012 |
gdm_dbus_worker_emit_saved_language_name_read (GDM_DBUS_WORKER (worker),
|
|
|
f83012 |
language_name);
|
|
|
f83012 |
g_free (language_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
on_saved_session_name_read (GdmSessionWorker *worker)
|
|
|
f83012 |
{
|
|
|
f83012 |
char *session_name;
|
|
|
f83012 |
|
|
|
f83012 |
session_name = gdm_session_settings_get_session_name (worker->priv->user_settings);
|
|
|
f83012 |
|
|
|
f83012 |
g_debug ("GdmSessionWorker: Saved session is %s", session_name);
|
|
|
f83012 |
gdm_dbus_worker_emit_saved_session_name_read (GDM_DBUS_WORKER (worker),
|
|
|
f83012 |
session_name);
|
|
|
f83012 |
g_free (session_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
+static void
|
|
|
f83012 |
+on_saved_session_type_read (GdmSessionWorker *worker)
|
|
|
f83012 |
+{
|
|
|
f83012 |
+ char *session_type;
|
|
|
f83012 |
+
|
|
|
f83012 |
+ session_type = gdm_session_settings_get_session_type (worker->priv->user_settings);
|
|
|
f83012 |
+
|
|
|
f83012 |
+ g_debug ("GdmSessionWorker: Saved session type is %s", session_type);
|
|
|
f83012 |
+ gdm_dbus_worker_emit_saved_session_type_read (GDM_DBUS_WORKER (worker),
|
|
|
f83012 |
+ session_type);
|
|
|
f83012 |
+ g_free (session_type);
|
|
|
f83012 |
+}
|
|
|
f83012 |
+
|
|
|
f83012 |
+
|
|
|
f83012 |
static void
|
|
|
f83012 |
do_setup (GdmSessionWorker *worker)
|
|
|
f83012 |
{
|
|
|
f83012 |
GError *error;
|
|
|
f83012 |
gboolean res;
|
|
|
f83012 |
|
|
|
f83012 |
error = NULL;
|
|
|
f83012 |
res = gdm_session_worker_initialize_pam (worker,
|
|
|
f83012 |
worker->priv->service,
|
|
|
f83012 |
(const char **) worker->priv->extensions,
|
|
|
f83012 |
worker->priv->username,
|
|
|
f83012 |
worker->priv->hostname,
|
|
|
f83012 |
worker->priv->display_is_local,
|
|
|
f83012 |
worker->priv->x11_display_name,
|
|
|
f83012 |
worker->priv->x11_authority_file,
|
|
|
f83012 |
worker->priv->display_device,
|
|
|
f83012 |
worker->priv->display_seat_id,
|
|
|
f83012 |
&error);
|
|
|
f83012 |
|
|
|
f83012 |
if (res) {
|
|
|
f83012 |
g_dbus_method_invocation_return_value (worker->priv->pending_invocation, NULL);
|
|
|
f83012 |
} else {
|
|
|
f83012 |
g_dbus_method_invocation_take_error (worker->priv->pending_invocation, error);
|
|
|
f83012 |
}
|
|
|
f83012 |
worker->priv->pending_invocation = NULL;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
do_authenticate (GdmSessionWorker *worker)
|
|
|
f83012 |
{
|
|
|
f83012 |
@@ -3001,158 +3015,172 @@ gdm_session_worker_handle_initialize (GdmDBusWorker *object,
|
|
|
f83012 |
} else if (g_strcmp0 (key, "x11-authority-file") == 0) {
|
|
|
f83012 |
worker->priv->x11_authority_file = g_variant_dup_string (value, NULL);
|
|
|
f83012 |
} else if (g_strcmp0 (key, "console") == 0) {
|
|
|
f83012 |
worker->priv->display_device = g_variant_dup_string (value, NULL);
|
|
|
f83012 |
} else if (g_strcmp0 (key, "seat-id") == 0) {
|
|
|
f83012 |
worker->priv->display_seat_id = g_variant_dup_string (value, NULL);
|
|
|
f83012 |
} else if (g_strcmp0 (key, "hostname") == 0) {
|
|
|
f83012 |
worker->priv->hostname = g_variant_dup_string (value, NULL);
|
|
|
f83012 |
} else if (g_strcmp0 (key, "display-is-local") == 0) {
|
|
|
f83012 |
worker->priv->display_is_local = g_variant_get_boolean (value);
|
|
|
f83012 |
} else if (g_strcmp0 (key, "display-is-initial") == 0) {
|
|
|
f83012 |
worker->priv->display_is_initial = g_variant_get_boolean (value);
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
worker->priv->pending_invocation = invocation;
|
|
|
f83012 |
|
|
|
f83012 |
if (!worker->priv->is_program_session) {
|
|
|
f83012 |
worker->priv->user_settings = gdm_session_settings_new ();
|
|
|
f83012 |
|
|
|
f83012 |
g_signal_connect_swapped (worker->priv->user_settings,
|
|
|
f83012 |
"notify::language-name",
|
|
|
f83012 |
G_CALLBACK (on_saved_language_name_read),
|
|
|
f83012 |
worker);
|
|
|
f83012 |
|
|
|
f83012 |
g_signal_connect_swapped (worker->priv->user_settings,
|
|
|
f83012 |
"notify::session-name",
|
|
|
f83012 |
G_CALLBACK (on_saved_session_name_read),
|
|
|
f83012 |
worker);
|
|
|
f83012 |
|
|
|
f83012 |
+ g_signal_connect_swapped (worker->priv->user_settings,
|
|
|
f83012 |
+ "notify::session-type",
|
|
|
f83012 |
+ G_CALLBACK (on_saved_session_type_read),
|
|
|
f83012 |
+ worker);
|
|
|
f83012 |
+
|
|
|
f83012 |
if (worker->priv->username) {
|
|
|
f83012 |
wait_for_settings = !gdm_session_settings_load (worker->priv->user_settings,
|
|
|
f83012 |
worker->priv->username);
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
if (wait_for_settings) {
|
|
|
f83012 |
/* Load settings from accounts daemon before continuing
|
|
|
f83012 |
*/
|
|
|
f83012 |
g_signal_connect (G_OBJECT (worker->priv->user_settings),
|
|
|
f83012 |
"notify::is-loaded",
|
|
|
f83012 |
G_CALLBACK (on_settings_is_loaded_changed),
|
|
|
f83012 |
worker);
|
|
|
f83012 |
} else {
|
|
|
f83012 |
queue_state_change (worker);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
return TRUE;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static gboolean
|
|
|
f83012 |
gdm_session_worker_handle_setup (GdmDBusWorker *object,
|
|
|
f83012 |
GDBusMethodInvocation *invocation,
|
|
|
f83012 |
const char *service,
|
|
|
f83012 |
const char *x11_display_name,
|
|
|
f83012 |
const char *x11_authority_file,
|
|
|
f83012 |
const char *console,
|
|
|
f83012 |
const char *seat_id,
|
|
|
f83012 |
const char *hostname,
|
|
|
f83012 |
gboolean display_is_local,
|
|
|
f83012 |
gboolean display_is_initial)
|
|
|
f83012 |
{
|
|
|
f83012 |
GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
|
|
|
f83012 |
validate_and_queue_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE);
|
|
|
f83012 |
|
|
|
f83012 |
worker->priv->service = g_strdup (service);
|
|
|
f83012 |
worker->priv->x11_display_name = g_strdup (x11_display_name);
|
|
|
f83012 |
worker->priv->x11_authority_file = g_strdup (x11_authority_file);
|
|
|
f83012 |
worker->priv->display_device = g_strdup (console);
|
|
|
f83012 |
worker->priv->display_seat_id = g_strdup (seat_id);
|
|
|
f83012 |
worker->priv->hostname = g_strdup (hostname);
|
|
|
f83012 |
worker->priv->display_is_local = display_is_local;
|
|
|
f83012 |
worker->priv->display_is_initial = display_is_initial;
|
|
|
f83012 |
worker->priv->username = NULL;
|
|
|
f83012 |
|
|
|
f83012 |
worker->priv->user_settings = gdm_session_settings_new ();
|
|
|
f83012 |
|
|
|
f83012 |
g_signal_connect_swapped (worker->priv->user_settings,
|
|
|
f83012 |
"notify::language-name",
|
|
|
f83012 |
G_CALLBACK (on_saved_language_name_read),
|
|
|
f83012 |
worker);
|
|
|
f83012 |
|
|
|
f83012 |
g_signal_connect_swapped (worker->priv->user_settings,
|
|
|
f83012 |
"notify::session-name",
|
|
|
f83012 |
G_CALLBACK (on_saved_session_name_read),
|
|
|
f83012 |
worker);
|
|
|
f83012 |
+ g_signal_connect_swapped (worker->priv->user_settings,
|
|
|
f83012 |
+ "notify::session-type",
|
|
|
f83012 |
+ G_CALLBACK (on_saved_session_type_read),
|
|
|
f83012 |
+ worker);
|
|
|
f83012 |
+
|
|
|
f83012 |
return TRUE;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static gboolean
|
|
|
f83012 |
gdm_session_worker_handle_setup_for_user (GdmDBusWorker *object,
|
|
|
f83012 |
GDBusMethodInvocation *invocation,
|
|
|
f83012 |
const char *service,
|
|
|
f83012 |
const char *username,
|
|
|
f83012 |
const char *x11_display_name,
|
|
|
f83012 |
const char *x11_authority_file,
|
|
|
f83012 |
const char *console,
|
|
|
f83012 |
const char *seat_id,
|
|
|
f83012 |
const char *hostname,
|
|
|
f83012 |
gboolean display_is_local,
|
|
|
f83012 |
gboolean display_is_initial)
|
|
|
f83012 |
{
|
|
|
f83012 |
GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
|
|
|
f83012 |
|
|
|
f83012 |
if (!validate_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE))
|
|
|
f83012 |
return TRUE;
|
|
|
f83012 |
|
|
|
f83012 |
worker->priv->service = g_strdup (service);
|
|
|
f83012 |
worker->priv->x11_display_name = g_strdup (x11_display_name);
|
|
|
f83012 |
worker->priv->x11_authority_file = g_strdup (x11_authority_file);
|
|
|
f83012 |
worker->priv->display_device = g_strdup (console);
|
|
|
f83012 |
worker->priv->display_seat_id = g_strdup (seat_id);
|
|
|
f83012 |
worker->priv->hostname = g_strdup (hostname);
|
|
|
f83012 |
worker->priv->display_is_local = display_is_local;
|
|
|
f83012 |
worker->priv->display_is_initial = display_is_initial;
|
|
|
f83012 |
worker->priv->username = g_strdup (username);
|
|
|
f83012 |
|
|
|
f83012 |
worker->priv->user_settings = gdm_session_settings_new ();
|
|
|
f83012 |
|
|
|
f83012 |
g_signal_connect_swapped (worker->priv->user_settings,
|
|
|
f83012 |
"notify::language-name",
|
|
|
f83012 |
G_CALLBACK (on_saved_language_name_read),
|
|
|
f83012 |
worker);
|
|
|
f83012 |
|
|
|
f83012 |
g_signal_connect_swapped (worker->priv->user_settings,
|
|
|
f83012 |
"notify::session-name",
|
|
|
f83012 |
G_CALLBACK (on_saved_session_name_read),
|
|
|
f83012 |
worker);
|
|
|
f83012 |
+ g_signal_connect_swapped (worker->priv->user_settings,
|
|
|
f83012 |
+ "notify::session-type",
|
|
|
f83012 |
+ G_CALLBACK (on_saved_session_type_read),
|
|
|
f83012 |
+ worker);
|
|
|
f83012 |
|
|
|
f83012 |
/* Load settings from accounts daemon before continuing
|
|
|
f83012 |
*/
|
|
|
f83012 |
worker->priv->pending_invocation = invocation;
|
|
|
f83012 |
if (gdm_session_settings_load (worker->priv->user_settings, username)) {
|
|
|
f83012 |
queue_state_change (worker);
|
|
|
f83012 |
} else {
|
|
|
f83012 |
g_signal_connect (G_OBJECT (worker->priv->user_settings),
|
|
|
f83012 |
"notify::is-loaded",
|
|
|
f83012 |
G_CALLBACK (on_settings_is_loaded_changed),
|
|
|
f83012 |
worker);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
return TRUE;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static gboolean
|
|
|
f83012 |
gdm_session_worker_handle_setup_for_program (GdmDBusWorker *object,
|
|
|
f83012 |
GDBusMethodInvocation *invocation,
|
|
|
f83012 |
const char *service,
|
|
|
f83012 |
const char *username,
|
|
|
f83012 |
const char *x11_display_name,
|
|
|
f83012 |
const char *x11_authority_file,
|
|
|
f83012 |
const char *console,
|
|
|
f83012 |
const char *seat_id,
|
|
|
f83012 |
const char *hostname,
|
|
|
f83012 |
gboolean display_is_local,
|
|
|
f83012 |
gboolean display_is_initial,
|
|
|
f83012 |
const char *log_file)
|
|
|
f83012 |
{
|
|
|
f83012 |
diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml
|
|
|
f83012 |
index 4280fe095..a215779c8 100644
|
|
|
f83012 |
--- a/daemon/gdm-session-worker.xml
|
|
|
f83012 |
+++ b/daemon/gdm-session-worker.xml
|
|
|
f83012 |
@@ -51,40 +51,43 @@
|
|
|
f83012 |
<method name="SetupForProgram">
|
|
|
f83012 |
<arg name="service_name" direction="in" type="s"/>
|
|
|
f83012 |
<arg name="user_name" direction="in" type="s"/>
|
|
|
f83012 |
<arg name="x11_display_name" direction="in" type="s"/>
|
|
|
f83012 |
<arg name="x11_authority_file" direction="in" type="s"/>
|
|
|
f83012 |
<arg name="display_device" direction="in" type="s"/>
|
|
|
f83012 |
<arg name="display_seat" direction="in" type="s"/>
|
|
|
f83012 |
<arg name="hostname" direction="in" type="s"/>
|
|
|
f83012 |
<arg name="display_is_local" direction="in" type="b"/>
|
|
|
f83012 |
<arg name="display_is_initial" direction="in" type="b"/>
|
|
|
f83012 |
<arg name="log_file" direction="in" type="s"/>
|
|
|
f83012 |
</method>
|
|
|
f83012 |
<method name="StartReauthentication">
|
|
|
f83012 |
<arg name="pid_of_caller" direction="in" type="i"/>
|
|
|
f83012 |
<arg name="uid_of_caller" direction="in" type="i"/>
|
|
|
f83012 |
<arg name="address" direction="out" type="s"/>
|
|
|
f83012 |
</method>
|
|
|
f83012 |
|
|
|
f83012 |
<signal name="SessionExited">
|
|
|
f83012 |
<arg name="service_name" type="s" />
|
|
|
f83012 |
|
|
|
f83012 |
signal. Use macros in sys/wait.h to handle it. -->
|
|
|
f83012 |
<arg name="status" type="i" />
|
|
|
f83012 |
</signal>
|
|
|
f83012 |
<signal name="SavedLanguageNameRead">
|
|
|
f83012 |
<arg name="language_name" type="s"/>
|
|
|
f83012 |
</signal>
|
|
|
f83012 |
<signal name="SavedSessionNameRead">
|
|
|
f83012 |
<arg name="session_name" type="s"/>
|
|
|
f83012 |
</signal>
|
|
|
f83012 |
+ <signal name="SavedSessionTypeRead">
|
|
|
f83012 |
+ <arg name="session_type" type="s"/>
|
|
|
f83012 |
+ </signal>
|
|
|
f83012 |
<signal name="UsernameChanged">
|
|
|
f83012 |
<arg name="new_username" type="s"/>
|
|
|
f83012 |
</signal>
|
|
|
f83012 |
<signal name="Reauthenticated">
|
|
|
f83012 |
<arg name="service_name" type="s"/>
|
|
|
f83012 |
</signal>
|
|
|
f83012 |
<signal name="CancelPendingQuery">
|
|
|
f83012 |
</signal>
|
|
|
f83012 |
</interface>
|
|
|
f83012 |
</node>
|
|
|
f83012 |
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
|
|
f83012 |
index 19d26c92e..e6640aac7 100644
|
|
|
f83012 |
--- a/daemon/gdm-session.c
|
|
|
f83012 |
+++ b/daemon/gdm-session.c
|
|
|
f83012 |
@@ -59,60 +59,61 @@
|
|
|
f83012 |
|
|
|
f83012 |
#define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel"
|
|
|
f83012 |
#define GDM_SESSION_DBUS_OBJECT_PATH "/org/gnome/DisplayManager/Session"
|
|
|
f83012 |
|
|
|
f83012 |
#define GDM_WORKER_DBUS_PATH "/org/gnome/DisplayManager/Worker"
|
|
|
f83012 |
|
|
|
f83012 |
typedef struct
|
|
|
f83012 |
{
|
|
|
f83012 |
GdmSession *session;
|
|
|
f83012 |
GdmSessionWorkerJob *job;
|
|
|
f83012 |
GPid worker_pid;
|
|
|
f83012 |
char *service_name;
|
|
|
f83012 |
GDBusMethodInvocation *starting_invocation;
|
|
|
f83012 |
char *starting_username;
|
|
|
f83012 |
GDBusMethodInvocation *pending_invocation;
|
|
|
f83012 |
GdmDBusWorkerManager *worker_manager_interface;
|
|
|
f83012 |
GdmDBusWorker *worker_proxy;
|
|
|
f83012 |
GCancellable *worker_cancellable;
|
|
|
f83012 |
char *session_id;
|
|
|
f83012 |
guint32 is_stopping : 1;
|
|
|
f83012 |
|
|
|
f83012 |
GPid reauth_pid_of_caller;
|
|
|
f83012 |
} GdmSessionConversation;
|
|
|
f83012 |
|
|
|
f83012 |
struct _GdmSessionPrivate
|
|
|
f83012 |
{
|
|
|
f83012 |
/* per open scope */
|
|
|
f83012 |
char *selected_program;
|
|
|
f83012 |
char *selected_session;
|
|
|
f83012 |
char *saved_session;
|
|
|
f83012 |
+ char *saved_session_type;
|
|
|
f83012 |
char *saved_language;
|
|
|
f83012 |
char *selected_user;
|
|
|
f83012 |
char *user_x11_authority_file;
|
|
|
f83012 |
|
|
|
f83012 |
char *timed_login_username;
|
|
|
f83012 |
int timed_login_delay;
|
|
|
f83012 |
GList *pending_timed_login_invocations;
|
|
|
f83012 |
|
|
|
f83012 |
GHashTable *conversations;
|
|
|
f83012 |
|
|
|
f83012 |
GdmSessionConversation *session_conversation;
|
|
|
f83012 |
|
|
|
f83012 |
char **conversation_environment;
|
|
|
f83012 |
|
|
|
f83012 |
GdmDBusUserVerifier *user_verifier_interface;
|
|
|
f83012 |
GHashTable *user_verifier_extensions;
|
|
|
f83012 |
GdmDBusGreeter *greeter_interface;
|
|
|
f83012 |
GdmDBusRemoteGreeter *remote_greeter_interface;
|
|
|
f83012 |
GdmDBusChooser *chooser_interface;
|
|
|
f83012 |
|
|
|
f83012 |
GList *pending_worker_connections;
|
|
|
f83012 |
GList *outside_connections;
|
|
|
f83012 |
|
|
|
f83012 |
GPid session_pid;
|
|
|
f83012 |
|
|
|
f83012 |
/* object lifetime scope */
|
|
|
f83012 |
char *session_type;
|
|
|
f83012 |
char *display_name;
|
|
|
f83012 |
char *display_hostname;
|
|
|
f83012 |
char *display_device;
|
|
|
f83012 |
@@ -312,295 +313,310 @@ on_establish_credentials_cb (GdmDBusWorker *proxy,
|
|
|
f83012 |
return;
|
|
|
f83012 |
|
|
|
f83012 |
self = g_object_ref (conversation->session);
|
|
|
f83012 |
service_name = g_strdup (conversation->service_name);
|
|
|
f83012 |
|
|
|
f83012 |
if (worked) {
|
|
|
f83012 |
if (self->priv->user_verifier_interface != NULL) {
|
|
|
f83012 |
gdm_dbus_user_verifier_emit_verification_complete (self->priv->user_verifier_interface,
|
|
|
f83012 |
service_name);
|
|
|
f83012 |
g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
switch (self->priv->verification_mode) {
|
|
|
f83012 |
case GDM_SESSION_VERIFICATION_MODE_LOGIN:
|
|
|
f83012 |
case GDM_SESSION_VERIFICATION_MODE_CHOOSER:
|
|
|
f83012 |
gdm_session_open_session (self, service_name);
|
|
|
f83012 |
break;
|
|
|
f83012 |
case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE:
|
|
|
f83012 |
default:
|
|
|
f83012 |
break;
|
|
|
f83012 |
}
|
|
|
f83012 |
} else {
|
|
|
f83012 |
report_and_stop_conversation (self, service_name, error);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
g_free (service_name);
|
|
|
f83012 |
g_object_unref (self);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static char **
|
|
|
f83012 |
-get_system_session_dirs (GdmSession *self)
|
|
|
f83012 |
+get_system_session_dirs (GdmSession *self,
|
|
|
f83012 |
+ const char *type)
|
|
|
f83012 |
{
|
|
|
f83012 |
GArray *search_array = NULL;
|
|
|
f83012 |
char **search_dirs;
|
|
|
f83012 |
|
|
|
f83012 |
static const char *x_search_dirs[] = {
|
|
|
f83012 |
"/etc/X11/sessions/",
|
|
|
f83012 |
DMCONFDIR "/Sessions/",
|
|
|
f83012 |
DATADIR "/gdm/BuiltInSessions/",
|
|
|
f83012 |
DATADIR "/xsessions/",
|
|
|
f83012 |
};
|
|
|
f83012 |
|
|
|
f83012 |
static const char *wayland_search_dir = DATADIR "/wayland-sessions/";
|
|
|
f83012 |
|
|
|
f83012 |
search_array = g_array_new (TRUE, TRUE, sizeof (char *));
|
|
|
f83012 |
|
|
|
f83012 |
- g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
|
|
|
f83012 |
+ if (type == NULL || strcmp (type, "x11") == 0)
|
|
|
f83012 |
+ g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
|
|
|
f83012 |
|
|
|
f83012 |
#ifdef ENABLE_WAYLAND_SUPPORT
|
|
|
f83012 |
- if (!self->priv->ignore_wayland) {
|
|
|
f83012 |
+ if ((!self->priv->ignore_wayland && type == NULL) || g_strcmp0 (type, "wayland") == 0) {
|
|
|
f83012 |
#ifdef ENABLE_USER_DISPLAY_SERVER
|
|
|
f83012 |
g_array_prepend_val (search_array, wayland_search_dir);
|
|
|
f83012 |
#else
|
|
|
f83012 |
g_array_append_val (search_array, wayland_search_dir);
|
|
|
f83012 |
#endif
|
|
|
f83012 |
}
|
|
|
f83012 |
#endif
|
|
|
f83012 |
|
|
|
f83012 |
search_dirs = g_strdupv ((char **) search_array->data);
|
|
|
f83012 |
|
|
|
f83012 |
g_array_free (search_array, TRUE);
|
|
|
f83012 |
|
|
|
f83012 |
return search_dirs;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static gboolean
|
|
|
f83012 |
is_prog_in_path (const char *prog)
|
|
|
f83012 |
{
|
|
|
f83012 |
char *f;
|
|
|
f83012 |
gboolean ret;
|
|
|
f83012 |
|
|
|
f83012 |
f = g_find_program_in_path (prog);
|
|
|
f83012 |
ret = (f != NULL);
|
|
|
f83012 |
g_free (f);
|
|
|
f83012 |
return ret;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static GKeyFile *
|
|
|
f83012 |
load_key_file_for_file (GdmSession *self,
|
|
|
f83012 |
const char *file,
|
|
|
f83012 |
+ const char *type,
|
|
|
f83012 |
char **full_path)
|
|
|
f83012 |
{
|
|
|
f83012 |
GKeyFile *key_file;
|
|
|
f83012 |
- GError *error;
|
|
|
f83012 |
+ GError *error = NULL;
|
|
|
f83012 |
gboolean res;
|
|
|
f83012 |
char **search_dirs;
|
|
|
f83012 |
|
|
|
f83012 |
key_file = g_key_file_new ();
|
|
|
f83012 |
|
|
|
f83012 |
- search_dirs = get_system_session_dirs (self),
|
|
|
f83012 |
+ search_dirs = get_system_session_dirs (self, type);
|
|
|
f83012 |
+
|
|
|
f83012 |
error = NULL;
|
|
|
f83012 |
res = g_key_file_load_from_dirs (key_file,
|
|
|
f83012 |
file,
|
|
|
f83012 |
(const char **) search_dirs,
|
|
|
f83012 |
full_path,
|
|
|
f83012 |
G_KEY_FILE_NONE,
|
|
|
f83012 |
&error);
|
|
|
f83012 |
if (! res) {
|
|
|
f83012 |
- g_debug ("GdmSession: File '%s' not found: %s", file, error->message);
|
|
|
f83012 |
- g_error_free (error);
|
|
|
f83012 |
+ g_debug ("GdmSession: File '%s' not found in search dirs", file);
|
|
|
f83012 |
+ if (error != NULL) {
|
|
|
f83012 |
+ g_debug ("GdmSession: %s", error->message);
|
|
|
f83012 |
+ g_error_free (error);
|
|
|
f83012 |
+ }
|
|
|
f83012 |
g_key_file_free (key_file);
|
|
|
f83012 |
key_file = NULL;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
g_strfreev (search_dirs);
|
|
|
f83012 |
|
|
|
f83012 |
return key_file;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static gboolean
|
|
|
f83012 |
get_session_command_for_file (GdmSession *self,
|
|
|
f83012 |
const char *file,
|
|
|
f83012 |
+ const char *type,
|
|
|
f83012 |
char **command)
|
|
|
f83012 |
{
|
|
|
f83012 |
GKeyFile *key_file;
|
|
|
f83012 |
GError *error;
|
|
|
f83012 |
char *exec;
|
|
|
f83012 |
gboolean ret;
|
|
|
f83012 |
gboolean res;
|
|
|
f83012 |
|
|
|
f83012 |
exec = NULL;
|
|
|
f83012 |
ret = FALSE;
|
|
|
f83012 |
if (command != NULL) {
|
|
|
f83012 |
*command = NULL;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
+ if (self->priv->ignore_wayland && g_strcmp0 (type, "wayland") == 0) {
|
|
|
f83012 |
+ g_debug ("GdmSession: ignoring wayland session command request for file '%s'",
|
|
|
f83012 |
+ file);
|
|
|
f83012 |
+ goto out;
|
|
|
f83012 |
+ }
|
|
|
f83012 |
+
|
|
|
f83012 |
g_debug ("GdmSession: getting session command for file '%s'", file);
|
|
|
f83012 |
- key_file = load_key_file_for_file (self, file, NULL);
|
|
|
f83012 |
+ key_file = load_key_file_for_file (self, file, type, NULL);
|
|
|
f83012 |
if (key_file == NULL) {
|
|
|
f83012 |
goto out;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
error = NULL;
|
|
|
f83012 |
res = g_key_file_get_boolean (key_file,
|
|
|
f83012 |
G_KEY_FILE_DESKTOP_GROUP,
|
|
|
f83012 |
G_KEY_FILE_DESKTOP_KEY_HIDDEN,
|
|
|
f83012 |
&error);
|
|
|
f83012 |
if (error == NULL && res) {
|
|
|
f83012 |
g_debug ("GdmSession: Session %s is marked as hidden", file);
|
|
|
f83012 |
goto out;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
exec = g_key_file_get_string (key_file,
|
|
|
f83012 |
G_KEY_FILE_DESKTOP_GROUP,
|
|
|
f83012 |
G_KEY_FILE_DESKTOP_KEY_TRY_EXEC,
|
|
|
f83012 |
NULL);
|
|
|
f83012 |
if (exec != NULL) {
|
|
|
f83012 |
res = is_prog_in_path (exec);
|
|
|
f83012 |
g_free (exec);
|
|
|
f83012 |
exec = NULL;
|
|
|
f83012 |
|
|
|
f83012 |
if (! res) {
|
|
|
f83012 |
g_debug ("GdmSession: Command not found: %s",
|
|
|
f83012 |
G_KEY_FILE_DESKTOP_KEY_TRY_EXEC);
|
|
|
f83012 |
goto out;
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
error = NULL;
|
|
|
f83012 |
exec = g_key_file_get_string (key_file,
|
|
|
f83012 |
G_KEY_FILE_DESKTOP_GROUP,
|
|
|
f83012 |
G_KEY_FILE_DESKTOP_KEY_EXEC,
|
|
|
f83012 |
&error);
|
|
|
f83012 |
if (error != NULL) {
|
|
|
f83012 |
g_debug ("GdmSession: %s key not found: %s",
|
|
|
f83012 |
G_KEY_FILE_DESKTOP_KEY_EXEC,
|
|
|
f83012 |
error->message);
|
|
|
f83012 |
g_error_free (error);
|
|
|
f83012 |
goto out;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
if (command != NULL) {
|
|
|
f83012 |
*command = g_strdup (exec);
|
|
|
f83012 |
}
|
|
|
f83012 |
ret = TRUE;
|
|
|
f83012 |
|
|
|
f83012 |
out:
|
|
|
f83012 |
g_free (exec);
|
|
|
f83012 |
|
|
|
f83012 |
return ret;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static gboolean
|
|
|
f83012 |
get_session_command_for_name (GdmSession *self,
|
|
|
f83012 |
const char *name,
|
|
|
f83012 |
+ const char *type,
|
|
|
f83012 |
char **command)
|
|
|
f83012 |
{
|
|
|
f83012 |
gboolean res;
|
|
|
f83012 |
char *filename;
|
|
|
f83012 |
|
|
|
f83012 |
filename = g_strdup_printf ("%s.desktop", name);
|
|
|
f83012 |
- res = get_session_command_for_file (self, filename, command);
|
|
|
f83012 |
+ res = get_session_command_for_file (self, filename, type, command);
|
|
|
f83012 |
g_free (filename);
|
|
|
f83012 |
|
|
|
f83012 |
return res;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static const char *
|
|
|
f83012 |
get_default_language_name (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
const char *default_language;
|
|
|
f83012 |
|
|
|
f83012 |
if (self->priv->saved_language != NULL) {
|
|
|
f83012 |
return self->priv->saved_language;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
default_language = g_hash_table_lookup (self->priv->environment,
|
|
|
f83012 |
"LANG");
|
|
|
f83012 |
|
|
|
f83012 |
if (default_language != NULL) {
|
|
|
f83012 |
return default_language;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
return setlocale (LC_MESSAGES, NULL);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static const char *
|
|
|
f83012 |
get_fallback_session_name (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
char **search_dirs;
|
|
|
f83012 |
int i;
|
|
|
f83012 |
char *name;
|
|
|
f83012 |
GSequence *sessions;
|
|
|
f83012 |
GSequenceIter *session;
|
|
|
f83012 |
|
|
|
f83012 |
if (self->priv->fallback_session_name != NULL) {
|
|
|
f83012 |
/* verify that the cached version still exists */
|
|
|
f83012 |
- if (get_session_command_for_name (self, self->priv->fallback_session_name, NULL)) {
|
|
|
f83012 |
+ if (get_session_command_for_name (self, self->priv->fallback_session_name, NULL, NULL)) {
|
|
|
f83012 |
goto out;
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
name = g_strdup ("gnome");
|
|
|
f83012 |
- if (get_session_command_for_name (self, name, NULL)) {
|
|
|
f83012 |
+ if (get_session_command_for_name (self, name, NULL, NULL)) {
|
|
|
f83012 |
g_free (self->priv->fallback_session_name);
|
|
|
f83012 |
self->priv->fallback_session_name = name;
|
|
|
f83012 |
goto out;
|
|
|
f83012 |
}
|
|
|
f83012 |
g_free (name);
|
|
|
f83012 |
|
|
|
f83012 |
sessions = g_sequence_new (g_free);
|
|
|
f83012 |
|
|
|
f83012 |
- search_dirs = get_system_session_dirs (self);
|
|
|
f83012 |
+ search_dirs = get_system_session_dirs (self, NULL);
|
|
|
f83012 |
for (i = 0; search_dirs[i] != NULL; i++) {
|
|
|
f83012 |
GDir *dir;
|
|
|
f83012 |
const char *base_name;
|
|
|
f83012 |
|
|
|
f83012 |
dir = g_dir_open (search_dirs[i], 0, NULL);
|
|
|
f83012 |
|
|
|
f83012 |
if (dir == NULL) {
|
|
|
f83012 |
continue;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
do {
|
|
|
f83012 |
base_name = g_dir_read_name (dir);
|
|
|
f83012 |
|
|
|
f83012 |
if (base_name == NULL) {
|
|
|
f83012 |
break;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
if (!g_str_has_suffix (base_name, ".desktop")) {
|
|
|
f83012 |
continue;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
- if (get_session_command_for_file (self, base_name, NULL)) {
|
|
|
f83012 |
+ if (get_session_command_for_file (self, base_name, NULL, NULL)) {
|
|
|
f83012 |
name = g_strndup (base_name, strlen (base_name) - strlen (".desktop"));
|
|
|
f83012 |
g_sequence_insert_sorted (sessions, name, (GCompareDataFunc) g_strcmp0, NULL);
|
|
|
f83012 |
}
|
|
|
f83012 |
} while (base_name != NULL);
|
|
|
f83012 |
|
|
|
f83012 |
g_dir_close (dir);
|
|
|
f83012 |
}
|
|
|
f83012 |
g_strfreev (search_dirs);
|
|
|
f83012 |
|
|
|
f83012 |
name = NULL;
|
|
|
f83012 |
session = g_sequence_get_begin_iter (sessions);
|
|
|
f83012 |
|
|
|
f83012 |
if (g_sequence_iter_is_end (session))
|
|
|
f83012 |
g_error ("GdmSession: no session desktop files installed, aborting...");
|
|
|
f83012 |
|
|
|
f83012 |
do {
|
|
|
f83012 |
name = g_sequence_get (session);
|
|
|
f83012 |
if (name) {
|
|
|
f83012 |
break;
|
|
|
f83012 |
}
|
|
|
f83012 |
session = g_sequence_iter_next (session);
|
|
|
f83012 |
} while (!g_sequence_iter_is_end (session));
|
|
|
f83012 |
|
|
|
f83012 |
g_free (self->priv->fallback_session_name);
|
|
|
f83012 |
self->priv->fallback_session_name = g_strdup (name);
|
|
|
f83012 |
|
|
|
f83012 |
g_sequence_free (sessions);
|
|
|
f83012 |
|
|
|
f83012 |
out:
|
|
|
f83012 |
return self->priv->fallback_session_name;
|
|
|
f83012 |
@@ -616,60 +632,63 @@ get_default_session_name (GdmSession *self)
|
|
|
f83012 |
return get_fallback_session_name (self);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
gdm_session_defaults_changed (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
|
|
|
f83012 |
update_session_type (self);
|
|
|
f83012 |
|
|
|
f83012 |
if (self->priv->greeter_interface != NULL) {
|
|
|
f83012 |
gdm_dbus_greeter_emit_default_language_name_changed (self->priv->greeter_interface,
|
|
|
f83012 |
get_default_language_name (self));
|
|
|
f83012 |
gdm_dbus_greeter_emit_default_session_name_changed (self->priv->greeter_interface,
|
|
|
f83012 |
get_default_session_name (self));
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
void
|
|
|
f83012 |
gdm_session_select_user (GdmSession *self,
|
|
|
f83012 |
const char *text)
|
|
|
f83012 |
{
|
|
|
f83012 |
|
|
|
f83012 |
g_debug ("GdmSession: Setting user: '%s'", text);
|
|
|
f83012 |
|
|
|
f83012 |
g_free (self->priv->selected_user);
|
|
|
f83012 |
self->priv->selected_user = g_strdup (text);
|
|
|
f83012 |
|
|
|
f83012 |
g_free (self->priv->saved_session);
|
|
|
f83012 |
self->priv->saved_session = NULL;
|
|
|
f83012 |
|
|
|
f83012 |
+ g_free (self->priv->saved_session_type);
|
|
|
f83012 |
+ self->priv->saved_session_type = NULL;
|
|
|
f83012 |
+
|
|
|
f83012 |
g_free (self->priv->saved_language);
|
|
|
f83012 |
self->priv->saved_language = NULL;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
cancel_pending_query (GdmSessionConversation *conversation)
|
|
|
f83012 |
{
|
|
|
f83012 |
if (conversation->pending_invocation == NULL) {
|
|
|
f83012 |
return;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
g_debug ("GdmSession: Cancelling pending query");
|
|
|
f83012 |
|
|
|
f83012 |
g_dbus_method_invocation_return_dbus_error (conversation->pending_invocation,
|
|
|
f83012 |
GDM_SESSION_DBUS_ERROR_CANCEL,
|
|
|
f83012 |
"Operation cancelled");
|
|
|
f83012 |
conversation->pending_invocation = NULL;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
answer_pending_query (GdmSessionConversation *conversation,
|
|
|
f83012 |
const char *answer)
|
|
|
f83012 |
{
|
|
|
f83012 |
g_dbus_method_invocation_return_value (conversation->pending_invocation,
|
|
|
f83012 |
g_variant_new ("(s)", answer));
|
|
|
f83012 |
conversation->pending_invocation = NULL;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
set_pending_query (GdmSessionConversation *conversation,
|
|
|
f83012 |
@@ -936,80 +955,91 @@ worker_on_reauthenticated (GdmDBusWorker *worker,
|
|
|
f83012 |
GdmSession *self = conversation->session;
|
|
|
f83012 |
g_debug ("GdmSession: Emitting 'reauthenticated' signal ");
|
|
|
f83012 |
g_signal_emit (self, signals[REAUTHENTICATED], 0, service_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
worker_on_saved_language_name_read (GdmDBusWorker *worker,
|
|
|
f83012 |
const char *language_name,
|
|
|
f83012 |
GdmSessionConversation *conversation)
|
|
|
f83012 |
{
|
|
|
f83012 |
GdmSession *self = conversation->session;
|
|
|
f83012 |
|
|
|
f83012 |
if (strlen (language_name) > 0) {
|
|
|
f83012 |
g_free (self->priv->saved_language);
|
|
|
f83012 |
self->priv->saved_language = g_strdup (language_name);
|
|
|
f83012 |
|
|
|
f83012 |
if (self->priv->greeter_interface != NULL) {
|
|
|
f83012 |
gdm_dbus_greeter_emit_default_language_name_changed (self->priv->greeter_interface,
|
|
|
f83012 |
language_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
worker_on_saved_session_name_read (GdmDBusWorker *worker,
|
|
|
f83012 |
const char *session_name,
|
|
|
f83012 |
GdmSessionConversation *conversation)
|
|
|
f83012 |
{
|
|
|
f83012 |
GdmSession *self = conversation->session;
|
|
|
f83012 |
|
|
|
f83012 |
- if (! get_session_command_for_name (self, session_name, NULL)) {
|
|
|
f83012 |
+ if (! get_session_command_for_name (self, session_name, self->priv->saved_session_type, NULL)) {
|
|
|
f83012 |
/* ignore sessions that don't exist */
|
|
|
f83012 |
g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name);
|
|
|
f83012 |
g_free (self->priv->saved_session);
|
|
|
f83012 |
self->priv->saved_session = NULL;
|
|
|
f83012 |
} else if (strcmp (session_name,
|
|
|
f83012 |
get_default_session_name (self)) != 0) {
|
|
|
f83012 |
g_free (self->priv->saved_session);
|
|
|
f83012 |
self->priv->saved_session = g_strdup (session_name);
|
|
|
f83012 |
|
|
|
f83012 |
if (self->priv->greeter_interface != NULL) {
|
|
|
f83012 |
gdm_dbus_greeter_emit_default_session_name_changed (self->priv->greeter_interface,
|
|
|
f83012 |
session_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
update_session_type (self);
|
|
|
f83012 |
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
+static void
|
|
|
f83012 |
+worker_on_saved_session_type_read (GdmDBusWorker *worker,
|
|
|
f83012 |
+ const char *session_type,
|
|
|
f83012 |
+ GdmSessionConversation *conversation)
|
|
|
f83012 |
+{
|
|
|
f83012 |
+ GdmSession *self = conversation->session;
|
|
|
f83012 |
+
|
|
|
f83012 |
+ g_free (self->priv->saved_session_type);
|
|
|
f83012 |
+ self->priv->saved_session_type = g_strdup (session_type);
|
|
|
f83012 |
+}
|
|
|
f83012 |
+
|
|
|
f83012 |
static GdmSessionConversation *
|
|
|
f83012 |
find_conversation_by_pid (GdmSession *self,
|
|
|
f83012 |
GPid pid)
|
|
|
f83012 |
{
|
|
|
f83012 |
GHashTableIter iter;
|
|
|
f83012 |
gpointer key, value;
|
|
|
f83012 |
|
|
|
f83012 |
g_hash_table_iter_init (&iter, self->priv->conversations);
|
|
|
f83012 |
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
|
f83012 |
GdmSessionConversation *conversation;
|
|
|
f83012 |
|
|
|
f83012 |
conversation = (GdmSessionConversation *) value;
|
|
|
f83012 |
|
|
|
f83012 |
if (conversation->worker_pid == pid) {
|
|
|
f83012 |
return conversation;
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
return NULL;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static gboolean
|
|
|
f83012 |
allow_worker_function (GDBusAuthObserver *observer,
|
|
|
f83012 |
GIOStream *stream,
|
|
|
f83012 |
GCredentials *credentials,
|
|
|
f83012 |
GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
uid_t connecting_user;
|
|
|
f83012 |
|
|
|
f83012 |
connecting_user = g_credentials_get_unix_user (credentials, NULL);
|
|
|
f83012 |
@@ -1089,60 +1119,63 @@ register_worker (GdmDBusWorkerManager *worker_manager_interface,
|
|
|
f83012 |
g_dbus_method_invocation_return_value (invocation, NULL);
|
|
|
f83012 |
|
|
|
f83012 |
conversation->worker_proxy = gdm_dbus_worker_proxy_new_sync (connection,
|
|
|
f83012 |
G_DBUS_PROXY_FLAGS_NONE,
|
|
|
f83012 |
NULL,
|
|
|
f83012 |
GDM_WORKER_DBUS_PATH,
|
|
|
f83012 |
NULL, NULL);
|
|
|
f83012 |
/* drop the reference we stole from the pending connections list
|
|
|
f83012 |
* since the proxy owns the connection now */
|
|
|
f83012 |
g_object_unref (connection);
|
|
|
f83012 |
|
|
|
f83012 |
g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (conversation->worker_proxy), G_MAXINT);
|
|
|
f83012 |
|
|
|
f83012 |
conversation->worker_cancellable = g_cancellable_new ();
|
|
|
f83012 |
|
|
|
f83012 |
g_signal_connect (conversation->worker_proxy,
|
|
|
f83012 |
"username-changed",
|
|
|
f83012 |
G_CALLBACK (worker_on_username_changed), conversation);
|
|
|
f83012 |
g_signal_connect (conversation->worker_proxy,
|
|
|
f83012 |
"session-exited",
|
|
|
f83012 |
G_CALLBACK (worker_on_session_exited), conversation);
|
|
|
f83012 |
g_signal_connect (conversation->worker_proxy,
|
|
|
f83012 |
"reauthenticated",
|
|
|
f83012 |
G_CALLBACK (worker_on_reauthenticated), conversation);
|
|
|
f83012 |
g_signal_connect (conversation->worker_proxy,
|
|
|
f83012 |
"saved-language-name-read",
|
|
|
f83012 |
G_CALLBACK (worker_on_saved_language_name_read), conversation);
|
|
|
f83012 |
g_signal_connect (conversation->worker_proxy,
|
|
|
f83012 |
"saved-session-name-read",
|
|
|
f83012 |
G_CALLBACK (worker_on_saved_session_name_read), conversation);
|
|
|
f83012 |
+ g_signal_connect (conversation->worker_proxy,
|
|
|
f83012 |
+ "saved-session-type-read",
|
|
|
f83012 |
+ G_CALLBACK (worker_on_saved_session_type_read), conversation);
|
|
|
f83012 |
g_signal_connect (conversation->worker_proxy,
|
|
|
f83012 |
"cancel-pending-query",
|
|
|
f83012 |
G_CALLBACK (worker_on_cancel_pending_query), conversation);
|
|
|
f83012 |
|
|
|
f83012 |
conversation->worker_manager_interface = g_object_ref (worker_manager_interface);
|
|
|
f83012 |
g_debug ("GdmSession: worker connection is %p", connection);
|
|
|
f83012 |
|
|
|
f83012 |
g_debug ("GdmSession: Emitting conversation-started signal");
|
|
|
f83012 |
g_signal_emit (self, signals[CONVERSATION_STARTED], 0, conversation->service_name);
|
|
|
f83012 |
|
|
|
f83012 |
if (self->priv->user_verifier_interface != NULL) {
|
|
|
f83012 |
gdm_dbus_user_verifier_emit_conversation_started (self->priv->user_verifier_interface,
|
|
|
f83012 |
conversation->service_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
if (conversation->starting_invocation != NULL) {
|
|
|
f83012 |
if (conversation->starting_username != NULL) {
|
|
|
f83012 |
gdm_session_setup_for_user (self, conversation->service_name, conversation->starting_username);
|
|
|
f83012 |
|
|
|
f83012 |
g_clear_pointer (&conversation->starting_username,
|
|
|
f83012 |
(GDestroyNotify)
|
|
|
f83012 |
g_free);
|
|
|
f83012 |
} else {
|
|
|
f83012 |
gdm_session_setup (self, conversation->service_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
g_debug ("GdmSession: Conversation started");
|
|
|
f83012 |
|
|
|
f83012 |
return TRUE;
|
|
|
f83012 |
@@ -1804,60 +1837,63 @@ static void
|
|
|
f83012 |
free_conversation (GdmSessionConversation *conversation)
|
|
|
f83012 |
{
|
|
|
f83012 |
if (conversation->job != NULL) {
|
|
|
f83012 |
g_warning ("Freeing conversation '%s' with active job", conversation->service_name);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
g_free (conversation->service_name);
|
|
|
f83012 |
g_free (conversation->starting_username);
|
|
|
f83012 |
g_free (conversation->session_id);
|
|
|
f83012 |
g_clear_object (&conversation->worker_manager_interface);
|
|
|
f83012 |
|
|
|
f83012 |
g_cancellable_cancel (conversation->worker_cancellable);
|
|
|
f83012 |
g_clear_object (&conversation->worker_cancellable);
|
|
|
f83012 |
|
|
|
f83012 |
if (conversation->worker_proxy != NULL) {
|
|
|
f83012 |
g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
|
|
|
f83012 |
G_CALLBACK (worker_on_username_changed),
|
|
|
f83012 |
conversation);
|
|
|
f83012 |
g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
|
|
|
f83012 |
G_CALLBACK (worker_on_session_exited),
|
|
|
f83012 |
conversation);
|
|
|
f83012 |
g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
|
|
|
f83012 |
G_CALLBACK (worker_on_reauthenticated),
|
|
|
f83012 |
conversation);
|
|
|
f83012 |
g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
|
|
|
f83012 |
G_CALLBACK (worker_on_saved_language_name_read),
|
|
|
f83012 |
conversation);
|
|
|
f83012 |
g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
|
|
|
f83012 |
G_CALLBACK (worker_on_saved_session_name_read),
|
|
|
f83012 |
conversation);
|
|
|
f83012 |
+ g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
|
|
|
f83012 |
+ G_CALLBACK (worker_on_saved_session_type_read),
|
|
|
f83012 |
+ conversation);
|
|
|
f83012 |
g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
|
|
|
f83012 |
G_CALLBACK (worker_on_cancel_pending_query),
|
|
|
f83012 |
conversation);
|
|
|
f83012 |
g_clear_object (&conversation->worker_proxy);
|
|
|
f83012 |
}
|
|
|
f83012 |
g_clear_object (&conversation->session);
|
|
|
f83012 |
g_free (conversation);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
load_lang_config_file (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
static const char *config_file = LANG_CONFIG_FILE;
|
|
|
f83012 |
gchar *contents = NULL;
|
|
|
f83012 |
gchar *p;
|
|
|
f83012 |
gchar *key;
|
|
|
f83012 |
gchar *value;
|
|
|
f83012 |
gsize length;
|
|
|
f83012 |
GError *error;
|
|
|
f83012 |
GString *line;
|
|
|
f83012 |
GRegex *re;
|
|
|
f83012 |
|
|
|
f83012 |
if (!g_file_test (config_file, G_FILE_TEST_EXISTS)) {
|
|
|
f83012 |
g_debug ("Cannot access '%s'", config_file);
|
|
|
f83012 |
return;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
error = NULL;
|
|
|
f83012 |
if (!g_file_get_contents (config_file, &contents, &length, &error)) {
|
|
|
f83012 |
g_debug ("Failed to parse '%s': %s",
|
|
|
f83012 |
@@ -2412,83 +2448,83 @@ gdm_session_send_environment (GdmSession *self,
|
|
|
f83012 |
g_return_if_fail (GDM_IS_SESSION (self));
|
|
|
f83012 |
|
|
|
f83012 |
conversation = find_conversation_by_name (self, service_name);
|
|
|
f83012 |
if (conversation != NULL) {
|
|
|
f83012 |
send_environment (self, conversation);
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static const char *
|
|
|
f83012 |
get_session_name (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
/* FIXME: test the session names before we use them? */
|
|
|
f83012 |
|
|
|
f83012 |
if (self->priv->selected_session != NULL) {
|
|
|
f83012 |
return self->priv->selected_session;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
return get_default_session_name (self);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static char *
|
|
|
f83012 |
get_session_command (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
gboolean res;
|
|
|
f83012 |
char *command;
|
|
|
f83012 |
const char *session_name;
|
|
|
f83012 |
|
|
|
f83012 |
session_name = get_session_name (self);
|
|
|
f83012 |
|
|
|
f83012 |
command = NULL;
|
|
|
f83012 |
- res = get_session_command_for_name (self, session_name, &command);
|
|
|
f83012 |
+ res = get_session_command_for_name (self, session_name, NULL, &command);
|
|
|
f83012 |
if (! res) {
|
|
|
f83012 |
g_critical ("Cannot find a command for specified session: %s", session_name);
|
|
|
f83012 |
exit (EXIT_FAILURE);
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
return command;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static gchar *
|
|
|
f83012 |
get_session_desktop_names (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
gchar *filename;
|
|
|
f83012 |
GKeyFile *keyfile;
|
|
|
f83012 |
gchar *desktop_names = NULL;
|
|
|
f83012 |
|
|
|
f83012 |
if (self->priv->selected_program != NULL) {
|
|
|
f83012 |
return g_strdup ("GNOME-Greeter:GNOME");
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
filename = g_strdup_printf ("%s.desktop", get_session_name (self));
|
|
|
f83012 |
g_debug ("GdmSession: getting desktop names for file '%s'", filename);
|
|
|
f83012 |
- keyfile = load_key_file_for_file (self, filename, NULL);
|
|
|
f83012 |
+ keyfile = load_key_file_for_file (self, filename, NULL, NULL);
|
|
|
f83012 |
if (keyfile != NULL) {
|
|
|
f83012 |
gchar **names;
|
|
|
f83012 |
|
|
|
f83012 |
names = g_key_file_get_string_list (keyfile, G_KEY_FILE_DESKTOP_GROUP,
|
|
|
f83012 |
"DesktopNames", NULL, NULL);
|
|
|
f83012 |
if (names != NULL) {
|
|
|
f83012 |
desktop_names = g_strjoinv (":", names);
|
|
|
f83012 |
|
|
|
f83012 |
g_strfreev (names);
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
g_key_file_free (keyfile);
|
|
|
f83012 |
g_free (filename);
|
|
|
f83012 |
return desktop_names;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
void
|
|
|
f83012 |
gdm_session_set_environment_variable (GdmSession *self,
|
|
|
f83012 |
const char *key,
|
|
|
f83012 |
const char *value)
|
|
|
f83012 |
{
|
|
|
f83012 |
g_return_if_fail (key != NULL);
|
|
|
f83012 |
g_return_if_fail (value != NULL);
|
|
|
f83012 |
|
|
|
f83012 |
g_hash_table_replace (self->priv->environment,
|
|
|
f83012 |
g_strdup (key),
|
|
|
f83012 |
g_strdup (value));
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
@@ -3008,115 +3044,117 @@ gdm_session_get_conversation_session_id (GdmSession *self,
|
|
|
f83012 |
|
|
|
f83012 |
conversation = find_conversation_by_name (self, service_name);
|
|
|
f83012 |
|
|
|
f83012 |
if (conversation == NULL) {
|
|
|
f83012 |
return NULL;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
return conversation->session_id;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
static char *
|
|
|
f83012 |
get_session_filename (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
return g_strdup_printf ("%s.desktop", get_session_name (self));
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
#ifdef ENABLE_WAYLAND_SUPPORT
|
|
|
f83012 |
static gboolean
|
|
|
f83012 |
gdm_session_is_wayland_session (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
GKeyFile *key_file;
|
|
|
f83012 |
gboolean is_wayland_session = FALSE;
|
|
|
f83012 |
char *filename;
|
|
|
f83012 |
char *full_path = NULL;
|
|
|
f83012 |
|
|
|
f83012 |
g_return_val_if_fail (self != NULL, FALSE);
|
|
|
f83012 |
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
|
|
|
f83012 |
|
|
|
f83012 |
filename = get_session_filename (self);
|
|
|
f83012 |
|
|
|
f83012 |
- key_file = load_key_file_for_file (self, filename, &full_path);
|
|
|
f83012 |
+ key_file = load_key_file_for_file (self, filename, "wayland", &full_path);
|
|
|
f83012 |
|
|
|
f83012 |
if (key_file == NULL) {
|
|
|
f83012 |
goto out;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) {
|
|
|
f83012 |
is_wayland_session = TRUE;
|
|
|
f83012 |
}
|
|
|
f83012 |
g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no");
|
|
|
f83012 |
|
|
|
f83012 |
out:
|
|
|
f83012 |
g_clear_pointer (&key_file, (GDestroyNotify) g_key_file_free);
|
|
|
f83012 |
g_free (filename);
|
|
|
f83012 |
return is_wayland_session;
|
|
|
f83012 |
}
|
|
|
f83012 |
#endif
|
|
|
f83012 |
|
|
|
f83012 |
static void
|
|
|
f83012 |
update_session_type (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
#ifdef ENABLE_WAYLAND_SUPPORT
|
|
|
f83012 |
- gboolean is_wayland_session;
|
|
|
f83012 |
+ gboolean is_wayland_session = FALSE;
|
|
|
f83012 |
+
|
|
|
f83012 |
+ if (!self->priv->ignore_wayland)
|
|
|
f83012 |
+ is_wayland_session = gdm_session_is_wayland_session (self);
|
|
|
f83012 |
|
|
|
f83012 |
- is_wayland_session = gdm_session_is_wayland_session (self);
|
|
|
f83012 |
if (is_wayland_session) {
|
|
|
f83012 |
set_session_type (self, "wayland");
|
|
|
f83012 |
} else {
|
|
|
f83012 |
set_session_type (self, NULL);
|
|
|
f83012 |
}
|
|
|
f83012 |
#endif
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
gboolean
|
|
|
f83012 |
gdm_session_bypasses_xsession (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
GError *error;
|
|
|
f83012 |
GKeyFile *key_file;
|
|
|
f83012 |
gboolean res;
|
|
|
f83012 |
gboolean bypasses_xsession = FALSE;
|
|
|
f83012 |
char *filename = NULL;
|
|
|
f83012 |
|
|
|
f83012 |
g_return_val_if_fail (self != NULL, FALSE);
|
|
|
f83012 |
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
|
|
|
f83012 |
|
|
|
f83012 |
#ifdef ENABLE_WAYLAND_SUPPORT
|
|
|
f83012 |
if (gdm_session_is_wayland_session (self)) {
|
|
|
f83012 |
bypasses_xsession = TRUE;
|
|
|
f83012 |
goto out;
|
|
|
f83012 |
}
|
|
|
f83012 |
#endif
|
|
|
f83012 |
|
|
|
f83012 |
filename = get_session_filename (self);
|
|
|
f83012 |
|
|
|
f83012 |
- key_file = load_key_file_for_file (self, filename, NULL);
|
|
|
f83012 |
+ key_file = load_key_file_for_file (self, filename, "x11", NULL);
|
|
|
f83012 |
|
|
|
f83012 |
error = NULL;
|
|
|
f83012 |
res = g_key_file_has_key (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-BypassXsession", NULL);
|
|
|
f83012 |
if (!res) {
|
|
|
f83012 |
goto out;
|
|
|
f83012 |
} else {
|
|
|
f83012 |
bypasses_xsession = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-BypassXsession", &error);
|
|
|
f83012 |
if (error) {
|
|
|
f83012 |
bypasses_xsession = FALSE;
|
|
|
f83012 |
g_error_free (error);
|
|
|
f83012 |
goto out;
|
|
|
f83012 |
}
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
out:
|
|
|
f83012 |
if (bypasses_xsession) {
|
|
|
f83012 |
g_debug ("GdmSession: Session %s bypasses Xsession wrapper script", filename);
|
|
|
f83012 |
}
|
|
|
f83012 |
g_free (filename);
|
|
|
f83012 |
return bypasses_xsession;
|
|
|
f83012 |
}
|
|
|
f83012 |
|
|
|
f83012 |
GdmSessionDisplayMode
|
|
|
f83012 |
gdm_session_get_display_mode (GdmSession *self)
|
|
|
f83012 |
{
|
|
|
f83012 |
g_debug ("GdmSession: type %s, program? %s, seat %s",
|
|
|
f83012 |
self->priv->session_type,
|
|
|
f83012 |
self->priv->is_program_session? "yes" : "no",
|
|
|
f83012 |
self->priv->display_seat_id);
|
|
|
f83012 |
|
|
|
f83012 |
--
|
|
|
f83012 |
2.17.1
|
|
|
f83012 |
|