|
|
c90517 |
From 0f1826708cc233bb9e538c029afa96c85ef62d56 Mon Sep 17 00:00:00 2001
|
|
|
c90517 |
From: Ray Strode <rstrode@redhat.com>
|
|
|
c90517 |
Date: Thu, 6 Sep 2018 19:31:50 -0400
|
|
|
c90517 |
Subject: [PATCH 39/48] manager: do initial-setup post work in manager code
|
|
|
c90517 |
|
|
|
c90517 |
Right now we do the initial-setup related post work
|
|
|
c90517 |
when stopping the greeter, but the problem is we delay
|
|
|
c90517 |
stopping the greeter now until after the user session
|
|
|
c90517 |
is started.
|
|
|
c90517 |
|
|
|
c90517 |
That post-work needs to be done before the user session
|
|
|
c90517 |
is started.
|
|
|
c90517 |
|
|
|
c90517 |
This commit moves the code to a more logical place.
|
|
|
c90517 |
---
|
|
|
c90517 |
daemon/gdm-display.c | 132 -------------------------------------------
|
|
|
c90517 |
daemon/gdm-manager.c | 132 +++++++++++++++++++++++++++++++++++++++++++
|
|
|
c90517 |
2 files changed, 132 insertions(+), 132 deletions(-)
|
|
|
c90517 |
|
|
|
c90517 |
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
|
|
|
c90517 |
index 875534272..1cef8c7c1 100644
|
|
|
c90517 |
--- a/daemon/gdm-display.c
|
|
|
c90517 |
+++ b/daemon/gdm-display.c
|
|
|
c90517 |
@@ -22,61 +22,60 @@
|
|
|
c90517 |
|
|
|
c90517 |
#include <stdlib.h>
|
|
|
c90517 |
#include <stdio.h>
|
|
|
c90517 |
#include <stdint.h>
|
|
|
c90517 |
#include <fcntl.h>
|
|
|
c90517 |
#include <unistd.h>
|
|
|
c90517 |
#include <string.h>
|
|
|
c90517 |
#include <signal.h>
|
|
|
c90517 |
#include <sys/stat.h>
|
|
|
c90517 |
#include <sys/types.h>
|
|
|
c90517 |
|
|
|
c90517 |
#include <glib.h>
|
|
|
c90517 |
#include <glib/gi18n.h>
|
|
|
c90517 |
#include <glib-object.h>
|
|
|
c90517 |
|
|
|
c90517 |
#include <xcb/xcb.h>
|
|
|
c90517 |
#include <X11/Xlib.h>
|
|
|
c90517 |
|
|
|
c90517 |
#include "gdm-common.h"
|
|
|
c90517 |
#include "gdm-display.h"
|
|
|
c90517 |
#include "gdm-display-glue.h"
|
|
|
c90517 |
#include "gdm-display-access-file.h"
|
|
|
c90517 |
#include "gdm-launch-environment.h"
|
|
|
c90517 |
|
|
|
c90517 |
#include "gdm-settings-direct.h"
|
|
|
c90517 |
#include "gdm-settings-keys.h"
|
|
|
c90517 |
|
|
|
c90517 |
#include "gdm-launch-environment.h"
|
|
|
c90517 |
#include "gdm-dbus-util.h"
|
|
|
c90517 |
|
|
|
c90517 |
-#define INITIAL_SETUP_USERNAME "gnome-initial-setup"
|
|
|
c90517 |
#define GNOME_SESSION_SESSIONS_PATH DATADIR "/gnome-session/sessions"
|
|
|
c90517 |
|
|
|
c90517 |
#define GDM_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY, GdmDisplayPrivate))
|
|
|
c90517 |
|
|
|
c90517 |
struct GdmDisplayPrivate
|
|
|
c90517 |
{
|
|
|
c90517 |
char *id;
|
|
|
c90517 |
char *seat_id;
|
|
|
c90517 |
char *session_id;
|
|
|
c90517 |
char *session_class;
|
|
|
c90517 |
char *session_type;
|
|
|
c90517 |
|
|
|
c90517 |
char *remote_hostname;
|
|
|
c90517 |
int x11_display_number;
|
|
|
c90517 |
char *x11_display_name;
|
|
|
c90517 |
int status;
|
|
|
c90517 |
time_t creation_time;
|
|
|
c90517 |
GTimer *server_timer;
|
|
|
c90517 |
|
|
|
c90517 |
char *x11_cookie;
|
|
|
c90517 |
gsize x11_cookie_size;
|
|
|
c90517 |
GdmDisplayAccessFile *access_file;
|
|
|
c90517 |
|
|
|
c90517 |
guint finish_idle_id;
|
|
|
c90517 |
|
|
|
c90517 |
xcb_connection_t *xcb_connection;
|
|
|
c90517 |
int xcb_screen_number;
|
|
|
c90517 |
|
|
|
c90517 |
GDBusConnection *connection;
|
|
|
c90517 |
GdmDisplayAccessFile *user_access_file;
|
|
|
c90517 |
@@ -98,131 +97,60 @@ enum {
|
|
|
c90517 |
PROP_0,
|
|
|
c90517 |
PROP_ID,
|
|
|
c90517 |
PROP_STATUS,
|
|
|
c90517 |
PROP_SEAT_ID,
|
|
|
c90517 |
PROP_SESSION_ID,
|
|
|
c90517 |
PROP_SESSION_CLASS,
|
|
|
c90517 |
PROP_SESSION_TYPE,
|
|
|
c90517 |
PROP_REMOTE_HOSTNAME,
|
|
|
c90517 |
PROP_X11_DISPLAY_NUMBER,
|
|
|
c90517 |
PROP_X11_DISPLAY_NAME,
|
|
|
c90517 |
PROP_X11_COOKIE,
|
|
|
c90517 |
PROP_X11_AUTHORITY_FILE,
|
|
|
c90517 |
PROP_IS_CONNECTED,
|
|
|
c90517 |
PROP_IS_LOCAL,
|
|
|
c90517 |
PROP_LAUNCH_ENVIRONMENT,
|
|
|
c90517 |
PROP_IS_INITIAL,
|
|
|
c90517 |
PROP_ALLOW_TIMED_LOGIN,
|
|
|
c90517 |
PROP_HAVE_EXISTING_USER_ACCOUNTS,
|
|
|
c90517 |
PROP_DOING_INITIAL_SETUP,
|
|
|
c90517 |
};
|
|
|
c90517 |
|
|
|
c90517 |
static void gdm_display_class_init (GdmDisplayClass *klass);
|
|
|
c90517 |
static void gdm_display_init (GdmDisplay *self);
|
|
|
c90517 |
static void gdm_display_finalize (GObject *object);
|
|
|
c90517 |
static void queue_finish (GdmDisplay *self);
|
|
|
c90517 |
static void _gdm_display_set_status (GdmDisplay *self,
|
|
|
c90517 |
int status);
|
|
|
c90517 |
static gboolean wants_initial_setup (GdmDisplay *self);
|
|
|
c90517 |
G_DEFINE_ABSTRACT_TYPE (GdmDisplay, gdm_display, G_TYPE_OBJECT)
|
|
|
c90517 |
|
|
|
c90517 |
-static gboolean
|
|
|
c90517 |
-chown_file (GFile *file,
|
|
|
c90517 |
- uid_t uid,
|
|
|
c90517 |
- gid_t gid,
|
|
|
c90517 |
- GError **error)
|
|
|
c90517 |
-{
|
|
|
c90517 |
- if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_UID, uid,
|
|
|
c90517 |
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
|
c90517 |
- NULL, error)) {
|
|
|
c90517 |
- return FALSE;
|
|
|
c90517 |
- }
|
|
|
c90517 |
- if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_GID, gid,
|
|
|
c90517 |
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
|
c90517 |
- NULL, error)) {
|
|
|
c90517 |
- return FALSE;
|
|
|
c90517 |
- }
|
|
|
c90517 |
- return TRUE;
|
|
|
c90517 |
-}
|
|
|
c90517 |
-
|
|
|
c90517 |
-static gboolean
|
|
|
c90517 |
-chown_recursively (GFile *dir,
|
|
|
c90517 |
- uid_t uid,
|
|
|
c90517 |
- gid_t gid,
|
|
|
c90517 |
- GError **error)
|
|
|
c90517 |
-{
|
|
|
c90517 |
- GFile *file = NULL;
|
|
|
c90517 |
- GFileInfo *info = NULL;
|
|
|
c90517 |
- GFileEnumerator *enumerator = NULL;
|
|
|
c90517 |
- gboolean retval = FALSE;
|
|
|
c90517 |
-
|
|
|
c90517 |
- if (chown_file (dir, uid, gid, error) == FALSE) {
|
|
|
c90517 |
- goto out;
|
|
|
c90517 |
- }
|
|
|
c90517 |
-
|
|
|
c90517 |
- enumerator = g_file_enumerate_children (dir,
|
|
|
c90517 |
- G_FILE_ATTRIBUTE_STANDARD_TYPE","
|
|
|
c90517 |
- G_FILE_ATTRIBUTE_STANDARD_NAME,
|
|
|
c90517 |
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
|
c90517 |
- NULL, error);
|
|
|
c90517 |
- if (!enumerator) {
|
|
|
c90517 |
- goto out;
|
|
|
c90517 |
- }
|
|
|
c90517 |
-
|
|
|
c90517 |
- while ((info = g_file_enumerator_next_file (enumerator, NULL, error)) != NULL) {
|
|
|
c90517 |
- file = g_file_get_child (dir, g_file_info_get_name (info));
|
|
|
c90517 |
-
|
|
|
c90517 |
- if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
|
|
|
c90517 |
- if (chown_recursively (file, uid, gid, error) == FALSE) {
|
|
|
c90517 |
- goto out;
|
|
|
c90517 |
- }
|
|
|
c90517 |
- } else if (chown_file (file, uid, gid, error) == FALSE) {
|
|
|
c90517 |
- goto out;
|
|
|
c90517 |
- }
|
|
|
c90517 |
-
|
|
|
c90517 |
- g_clear_object (&file;;
|
|
|
c90517 |
- g_clear_object (&info;;
|
|
|
c90517 |
- }
|
|
|
c90517 |
-
|
|
|
c90517 |
- if (*error) {
|
|
|
c90517 |
- goto out;
|
|
|
c90517 |
- }
|
|
|
c90517 |
-
|
|
|
c90517 |
- retval = TRUE;
|
|
|
c90517 |
-out:
|
|
|
c90517 |
- g_clear_object (&file;;
|
|
|
c90517 |
- g_clear_object (&info;;
|
|
|
c90517 |
- g_clear_object (&enumerator);
|
|
|
c90517 |
-
|
|
|
c90517 |
- return retval;
|
|
|
c90517 |
-}
|
|
|
c90517 |
-
|
|
|
c90517 |
GQuark
|
|
|
c90517 |
gdm_display_error_quark (void)
|
|
|
c90517 |
{
|
|
|
c90517 |
static GQuark ret = 0;
|
|
|
c90517 |
if (ret == 0) {
|
|
|
c90517 |
ret = g_quark_from_static_string ("gdm_display_error");
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
return ret;
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
time_t
|
|
|
c90517 |
gdm_display_get_creation_time (GdmDisplay *self)
|
|
|
c90517 |
{
|
|
|
c90517 |
g_return_val_if_fail (GDM_IS_DISPLAY (self), 0);
|
|
|
c90517 |
|
|
|
c90517 |
return self->priv->creation_time;
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
int
|
|
|
c90517 |
gdm_display_get_status (GdmDisplay *self)
|
|
|
c90517 |
{
|
|
|
c90517 |
g_return_val_if_fail (GDM_IS_DISPLAY (self), 0);
|
|
|
c90517 |
|
|
|
c90517 |
return self->priv->status;
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
const char *
|
|
|
c90517 |
gdm_display_get_session_id (GdmDisplay *self)
|
|
|
c90517 |
{
|
|
|
c90517 |
@@ -1649,145 +1577,85 @@ gdm_display_start_greeter_session (GdmDisplay *self)
|
|
|
c90517 |
G_CALLBACK (on_launch_environment_session_stopped),
|
|
|
c90517 |
self, 0);
|
|
|
c90517 |
g_signal_connect_object (self->priv->launch_environment,
|
|
|
c90517 |
"exited",
|
|
|
c90517 |
G_CALLBACK (on_launch_environment_session_exited),
|
|
|
c90517 |
self, 0);
|
|
|
c90517 |
g_signal_connect_object (self->priv->launch_environment,
|
|
|
c90517 |
"died",
|
|
|
c90517 |
G_CALLBACK (on_launch_environment_session_died),
|
|
|
c90517 |
self, 0);
|
|
|
c90517 |
|
|
|
c90517 |
if (auth_file != NULL) {
|
|
|
c90517 |
g_object_set (self->priv->launch_environment,
|
|
|
c90517 |
"x11-authority-file", auth_file,
|
|
|
c90517 |
NULL);
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
gdm_launch_environment_start (self->priv->launch_environment);
|
|
|
c90517 |
|
|
|
c90517 |
session = gdm_launch_environment_get_session (self->priv->launch_environment);
|
|
|
c90517 |
g_object_set (G_OBJECT (session),
|
|
|
c90517 |
"display-is-initial", self->priv->is_initial,
|
|
|
c90517 |
NULL);
|
|
|
c90517 |
|
|
|
c90517 |
g_free (display_name);
|
|
|
c90517 |
g_free (seat_id);
|
|
|
c90517 |
g_free (hostname);
|
|
|
c90517 |
g_free (auth_file);
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
-static void
|
|
|
c90517 |
-chown_initial_setup_home_dir (void)
|
|
|
c90517 |
-{
|
|
|
c90517 |
- GFile *dir;
|
|
|
c90517 |
- GError *error;
|
|
|
c90517 |
- char *gis_dir_path;
|
|
|
c90517 |
- char *gis_uid_path;
|
|
|
c90517 |
- char *gis_uid_contents;
|
|
|
c90517 |
- struct passwd *pwe;
|
|
|
c90517 |
- uid_t uid;
|
|
|
c90517 |
-
|
|
|
c90517 |
- if (!gdm_get_pwent_for_name (INITIAL_SETUP_USERNAME, &pwe)) {
|
|
|
c90517 |
- g_warning ("Unknown user %s", INITIAL_SETUP_USERNAME);
|
|
|
c90517 |
- return;
|
|
|
c90517 |
- }
|
|
|
c90517 |
-
|
|
|
c90517 |
- gis_dir_path = g_strdup (pwe->pw_dir);
|
|
|
c90517 |
-
|
|
|
c90517 |
- gis_uid_path = g_build_filename (gis_dir_path,
|
|
|
c90517 |
- "gnome-initial-setup-uid",
|
|
|
c90517 |
- NULL);
|
|
|
c90517 |
- if (!g_file_get_contents (gis_uid_path, &gis_uid_contents, NULL, NULL)) {
|
|
|
c90517 |
- g_warning ("Unable to read %s", gis_uid_path);
|
|
|
c90517 |
- goto out;
|
|
|
c90517 |
- }
|
|
|
c90517 |
-
|
|
|
c90517 |
- uid = (uid_t) atoi (gis_uid_contents);
|
|
|
c90517 |
- pwe = getpwuid (uid);
|
|
|
c90517 |
- if (uid == 0 || pwe == NULL) {
|
|
|
c90517 |
- g_warning ("UID '%s' in %s is not valid", gis_uid_contents, gis_uid_path);
|
|
|
c90517 |
- goto out;
|
|
|
c90517 |
- }
|
|
|
c90517 |
-
|
|
|
c90517 |
- error = NULL;
|
|
|
c90517 |
- dir = g_file_new_for_path (gis_dir_path);
|
|
|
c90517 |
- if (!chown_recursively (dir, pwe->pw_uid, pwe->pw_gid, &error)) {
|
|
|
c90517 |
- g_warning ("Failed to change ownership for %s: %s", gis_dir_path, error->message);
|
|
|
c90517 |
- g_error_free (error);
|
|
|
c90517 |
- }
|
|
|
c90517 |
- g_object_unref (dir);
|
|
|
c90517 |
-out:
|
|
|
c90517 |
- g_free (gis_uid_contents);
|
|
|
c90517 |
- g_free (gis_uid_path);
|
|
|
c90517 |
- g_free (gis_dir_path);
|
|
|
c90517 |
-}
|
|
|
c90517 |
-
|
|
|
c90517 |
void
|
|
|
c90517 |
gdm_display_stop_greeter_session (GdmDisplay *self)
|
|
|
c90517 |
{
|
|
|
c90517 |
GError *error = NULL;
|
|
|
c90517 |
|
|
|
c90517 |
if (self->priv->launch_environment != NULL) {
|
|
|
c90517 |
|
|
|
c90517 |
g_signal_handlers_disconnect_by_func (self->priv->launch_environment,
|
|
|
c90517 |
G_CALLBACK (on_launch_environment_session_opened),
|
|
|
c90517 |
self);
|
|
|
c90517 |
g_signal_handlers_disconnect_by_func (self->priv->launch_environment,
|
|
|
c90517 |
G_CALLBACK (on_launch_environment_session_started),
|
|
|
c90517 |
self);
|
|
|
c90517 |
g_signal_handlers_disconnect_by_func (self->priv->launch_environment,
|
|
|
c90517 |
G_CALLBACK (on_launch_environment_session_stopped),
|
|
|
c90517 |
self);
|
|
|
c90517 |
g_signal_handlers_disconnect_by_func (self->priv->launch_environment,
|
|
|
c90517 |
G_CALLBACK (on_launch_environment_session_exited),
|
|
|
c90517 |
self);
|
|
|
c90517 |
g_signal_handlers_disconnect_by_func (self->priv->launch_environment,
|
|
|
c90517 |
G_CALLBACK (on_launch_environment_session_died),
|
|
|
c90517 |
self);
|
|
|
c90517 |
gdm_launch_environment_stop (self->priv->launch_environment);
|
|
|
c90517 |
g_clear_object (&self->priv->launch_environment);
|
|
|
c90517 |
}
|
|
|
c90517 |
-
|
|
|
c90517 |
- if (self->priv->doing_initial_setup) {
|
|
|
c90517 |
- chown_initial_setup_home_dir ();
|
|
|
c90517 |
-
|
|
|
c90517 |
- if (!g_file_set_contents (ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT,
|
|
|
c90517 |
- "1",
|
|
|
c90517 |
- 1,
|
|
|
c90517 |
- &error)) {
|
|
|
c90517 |
- g_warning ("GdmDisplay: Could not write initial-setup-done marker to %s: %s",
|
|
|
c90517 |
- ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT,
|
|
|
c90517 |
- error->message);
|
|
|
c90517 |
- g_clear_error (&error);
|
|
|
c90517 |
- }
|
|
|
c90517 |
- }
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
static xcb_window_t
|
|
|
c90517 |
get_root_window (xcb_connection_t *connection,
|
|
|
c90517 |
int screen_number)
|
|
|
c90517 |
{
|
|
|
c90517 |
xcb_screen_t *screen = NULL;
|
|
|
c90517 |
xcb_screen_iterator_t iter;
|
|
|
c90517 |
|
|
|
c90517 |
iter = xcb_setup_roots_iterator (xcb_get_setup (connection));
|
|
|
c90517 |
while (iter.rem) {
|
|
|
c90517 |
if (screen_number == 0)
|
|
|
c90517 |
screen = iter.data;
|
|
|
c90517 |
screen_number--;
|
|
|
c90517 |
xcb_screen_next (&iter);
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
if (screen != NULL) {
|
|
|
c90517 |
return screen->root;
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
return XCB_WINDOW_NONE;
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
static void
|
|
|
c90517 |
gdm_display_set_windowpath (GdmDisplay *self)
|
|
|
c90517 |
{
|
|
|
c90517 |
/* setting WINDOWPATH for clients */
|
|
|
c90517 |
xcb_intern_atom_cookie_t atom_cookie;
|
|
|
c90517 |
xcb_intern_atom_reply_t *atom_reply = NULL;
|
|
|
c90517 |
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
|
|
c90517 |
index 0823e8638..cf982870c 100644
|
|
|
c90517 |
--- a/daemon/gdm-manager.c
|
|
|
c90517 |
+++ b/daemon/gdm-manager.c
|
|
|
c90517 |
@@ -35,60 +35,61 @@
|
|
|
c90517 |
#include <glib-object.h>
|
|
|
c90517 |
|
|
|
c90517 |
#include <act/act-user-manager.h>
|
|
|
c90517 |
|
|
|
c90517 |
#include <systemd/sd-login.h>
|
|
|
c90517 |
|
|
|
c90517 |
#include "gdm-common.h"
|
|
|
c90517 |
|
|
|
c90517 |
#include "gdm-dbus-util.h"
|
|
|
c90517 |
#include "gdm-manager.h"
|
|
|
c90517 |
#include "gdm-manager-glue.h"
|
|
|
c90517 |
#include "gdm-display-store.h"
|
|
|
c90517 |
#include "gdm-display-factory.h"
|
|
|
c90517 |
#include "gdm-launch-environment.h"
|
|
|
c90517 |
#include "gdm-local-display.h"
|
|
|
c90517 |
#include "gdm-local-display-factory.h"
|
|
|
c90517 |
#include "gdm-session.h"
|
|
|
c90517 |
#include "gdm-session-record.h"
|
|
|
c90517 |
#include "gdm-settings-direct.h"
|
|
|
c90517 |
#include "gdm-settings-keys.h"
|
|
|
c90517 |
#include "gdm-xdmcp-display-factory.h"
|
|
|
c90517 |
#include "gdm-xdmcp-chooser-display.h"
|
|
|
c90517 |
|
|
|
c90517 |
#define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate))
|
|
|
c90517 |
|
|
|
c90517 |
#define GDM_DBUS_PATH "/org/gnome/DisplayManager"
|
|
|
c90517 |
#define GDM_MANAGER_PATH GDM_DBUS_PATH "/Manager"
|
|
|
c90517 |
#define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays"
|
|
|
c90517 |
|
|
|
c90517 |
#define INITIAL_SETUP_USERNAME "gnome-initial-setup"
|
|
|
c90517 |
+#define ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT GDM_RUN_DIR "/gdm.ran-initial-setup"
|
|
|
c90517 |
|
|
|
c90517 |
typedef struct
|
|
|
c90517 |
{
|
|
|
c90517 |
GdmManager *manager;
|
|
|
c90517 |
GdmSession *session;
|
|
|
c90517 |
char *service_name;
|
|
|
c90517 |
guint idle_id;
|
|
|
c90517 |
} StartUserSessionOperation;
|
|
|
c90517 |
|
|
|
c90517 |
struct GdmManagerPrivate
|
|
|
c90517 |
{
|
|
|
c90517 |
GdmDisplayStore *display_store;
|
|
|
c90517 |
GdmLocalDisplayFactory *local_factory;
|
|
|
c90517 |
#ifdef HAVE_LIBXDMCP
|
|
|
c90517 |
GdmXdmcpDisplayFactory *xdmcp_factory;
|
|
|
c90517 |
#endif
|
|
|
c90517 |
GdmDisplay *automatic_login_display;
|
|
|
c90517 |
GList *user_sessions;
|
|
|
c90517 |
GHashTable *transient_sessions;
|
|
|
c90517 |
GHashTable *open_reauthentication_requests;
|
|
|
c90517 |
gboolean xdmcp_enabled;
|
|
|
c90517 |
|
|
|
c90517 |
gboolean started;
|
|
|
c90517 |
gboolean show_local_greeter;
|
|
|
c90517 |
|
|
|
c90517 |
GDBusConnection *connection;
|
|
|
c90517 |
GDBusObjectManagerServer *object_manager;
|
|
|
c90517 |
|
|
|
c90517 |
#ifdef WITH_PLYMOUTH
|
|
|
c90517 |
guint plymouth_is_running : 1;
|
|
|
c90517 |
@@ -1630,130 +1631,261 @@ start_user_session (GdmManager *manager,
|
|
|
c90517 |
|
|
|
c90517 |
destroy_start_user_session_operation (operation);
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
static void
|
|
|
c90517 |
create_display_for_user_session (GdmManager *self,
|
|
|
c90517 |
GdmSession *session,
|
|
|
c90517 |
const char *session_id)
|
|
|
c90517 |
{
|
|
|
c90517 |
GdmDisplay *display;
|
|
|
c90517 |
/* at the moment we only create GdmLocalDisplay objects on seat0 */
|
|
|
c90517 |
const char *seat_id = "seat0";
|
|
|
c90517 |
|
|
|
c90517 |
display = gdm_local_display_new ();
|
|
|
c90517 |
|
|
|
c90517 |
g_object_set (G_OBJECT (display),
|
|
|
c90517 |
"session-class", "user",
|
|
|
c90517 |
"seat-id", seat_id,
|
|
|
c90517 |
"session-id", session_id,
|
|
|
c90517 |
NULL);
|
|
|
c90517 |
gdm_display_store_add (self->priv->display_store,
|
|
|
c90517 |
display);
|
|
|
c90517 |
g_object_set_data (G_OBJECT (session), "gdm-display", display);
|
|
|
c90517 |
g_object_set_data_full (G_OBJECT (display),
|
|
|
c90517 |
"gdm-user-session",
|
|
|
c90517 |
g_object_ref (session),
|
|
|
c90517 |
(GDestroyNotify)
|
|
|
c90517 |
clean_user_session);
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
+static gboolean
|
|
|
c90517 |
+chown_file (GFile *file,
|
|
|
c90517 |
+ uid_t uid,
|
|
|
c90517 |
+ gid_t gid,
|
|
|
c90517 |
+ GError **error)
|
|
|
c90517 |
+{
|
|
|
c90517 |
+ if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_UID, uid,
|
|
|
c90517 |
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
|
c90517 |
+ NULL, error)) {
|
|
|
c90517 |
+ return FALSE;
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+ if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_GID, gid,
|
|
|
c90517 |
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
|
c90517 |
+ NULL, error)) {
|
|
|
c90517 |
+ return FALSE;
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+ return TRUE;
|
|
|
c90517 |
+}
|
|
|
c90517 |
+
|
|
|
c90517 |
+static gboolean
|
|
|
c90517 |
+chown_recursively (GFile *dir,
|
|
|
c90517 |
+ uid_t uid,
|
|
|
c90517 |
+ gid_t gid,
|
|
|
c90517 |
+ GError **error)
|
|
|
c90517 |
+{
|
|
|
c90517 |
+ GFile *file = NULL;
|
|
|
c90517 |
+ GFileInfo *info = NULL;
|
|
|
c90517 |
+ GFileEnumerator *enumerator = NULL;
|
|
|
c90517 |
+ gboolean retval = FALSE;
|
|
|
c90517 |
+
|
|
|
c90517 |
+ if (chown_file (dir, uid, gid, error) == FALSE) {
|
|
|
c90517 |
+ goto out;
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+
|
|
|
c90517 |
+ enumerator = g_file_enumerate_children (dir,
|
|
|
c90517 |
+ G_FILE_ATTRIBUTE_STANDARD_TYPE","
|
|
|
c90517 |
+ G_FILE_ATTRIBUTE_STANDARD_NAME,
|
|
|
c90517 |
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
|
c90517 |
+ NULL, error);
|
|
|
c90517 |
+ if (!enumerator) {
|
|
|
c90517 |
+ goto out;
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+
|
|
|
c90517 |
+ while ((info = g_file_enumerator_next_file (enumerator, NULL, error)) != NULL) {
|
|
|
c90517 |
+ file = g_file_get_child (dir, g_file_info_get_name (info));
|
|
|
c90517 |
+
|
|
|
c90517 |
+ if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
|
|
|
c90517 |
+ if (chown_recursively (file, uid, gid, error) == FALSE) {
|
|
|
c90517 |
+ goto out;
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+ } else if (chown_file (file, uid, gid, error) == FALSE) {
|
|
|
c90517 |
+ goto out;
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+
|
|
|
c90517 |
+ g_clear_object (&file;;
|
|
|
c90517 |
+ g_clear_object (&info;;
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+
|
|
|
c90517 |
+ if (*error) {
|
|
|
c90517 |
+ goto out;
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+
|
|
|
c90517 |
+ retval = TRUE;
|
|
|
c90517 |
+out:
|
|
|
c90517 |
+ g_clear_object (&file;;
|
|
|
c90517 |
+ g_clear_object (&info;;
|
|
|
c90517 |
+ g_clear_object (&enumerator);
|
|
|
c90517 |
+
|
|
|
c90517 |
+ return retval;
|
|
|
c90517 |
+}
|
|
|
c90517 |
+
|
|
|
c90517 |
+static void
|
|
|
c90517 |
+chown_initial_setup_home_dir (void)
|
|
|
c90517 |
+{
|
|
|
c90517 |
+ GFile *dir;
|
|
|
c90517 |
+ GError *error;
|
|
|
c90517 |
+ char *gis_dir_path;
|
|
|
c90517 |
+ char *gis_uid_path;
|
|
|
c90517 |
+ char *gis_uid_contents;
|
|
|
c90517 |
+ struct passwd *pwe;
|
|
|
c90517 |
+ uid_t uid;
|
|
|
c90517 |
+
|
|
|
c90517 |
+ if (!gdm_get_pwent_for_name (INITIAL_SETUP_USERNAME, &pwe)) {
|
|
|
c90517 |
+ g_warning ("Unknown user %s", INITIAL_SETUP_USERNAME);
|
|
|
c90517 |
+ return;
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+
|
|
|
c90517 |
+ gis_dir_path = g_strdup (pwe->pw_dir);
|
|
|
c90517 |
+
|
|
|
c90517 |
+ gis_uid_path = g_build_filename (gis_dir_path,
|
|
|
c90517 |
+ "gnome-initial-setup-uid",
|
|
|
c90517 |
+ NULL);
|
|
|
c90517 |
+ if (!g_file_get_contents (gis_uid_path, &gis_uid_contents, NULL, NULL)) {
|
|
|
c90517 |
+ g_warning ("Unable to read %s", gis_uid_path);
|
|
|
c90517 |
+ goto out;
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+
|
|
|
c90517 |
+ uid = (uid_t) atoi (gis_uid_contents);
|
|
|
c90517 |
+ pwe = getpwuid (uid);
|
|
|
c90517 |
+ if (uid == 0 || pwe == NULL) {
|
|
|
c90517 |
+ g_warning ("UID '%s' in %s is not valid", gis_uid_contents, gis_uid_path);
|
|
|
c90517 |
+ goto out;
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+
|
|
|
c90517 |
+ error = NULL;
|
|
|
c90517 |
+ dir = g_file_new_for_path (gis_dir_path);
|
|
|
c90517 |
+ if (!chown_recursively (dir, pwe->pw_uid, pwe->pw_gid, &error)) {
|
|
|
c90517 |
+ g_warning ("Failed to change ownership for %s: %s", gis_dir_path, error->message);
|
|
|
c90517 |
+ g_error_free (error);
|
|
|
c90517 |
+ }
|
|
|
c90517 |
+ g_object_unref (dir);
|
|
|
c90517 |
+out:
|
|
|
c90517 |
+ g_free (gis_uid_contents);
|
|
|
c90517 |
+ g_free (gis_uid_path);
|
|
|
c90517 |
+ g_free (gis_dir_path);
|
|
|
c90517 |
+}
|
|
|
c90517 |
+
|
|
|
c90517 |
static gboolean
|
|
|
c90517 |
on_start_user_session (StartUserSessionOperation *operation)
|
|
|
c90517 |
{
|
|
|
c90517 |
GdmManager *self = operation->manager;
|
|
|
c90517 |
gboolean migrated;
|
|
|
c90517 |
gboolean fail_if_already_switched = TRUE;
|
|
|
c90517 |
gboolean doing_initial_setup = FALSE;
|
|
|
c90517 |
GdmDisplay *display;
|
|
|
c90517 |
const char *session_id;
|
|
|
c90517 |
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
|
|
|
c90517 |
g_autofree char *display_session_type = NULL;
|
|
|
c90517 |
#endif
|
|
|
c90517 |
|
|
|
c90517 |
g_debug ("GdmManager: start or jump to session");
|
|
|
c90517 |
|
|
|
c90517 |
/* If there's already a session running, jump to it.
|
|
|
c90517 |
* If the only session running is the one we just opened,
|
|
|
c90517 |
* start a session on it.
|
|
|
c90517 |
*/
|
|
|
c90517 |
migrated = switch_to_compatible_user_session (operation->manager, operation->session, fail_if_already_switched);
|
|
|
c90517 |
|
|
|
c90517 |
g_debug ("GdmManager: migrated: %d", migrated);
|
|
|
c90517 |
if (migrated) {
|
|
|
c90517 |
/* We don't stop the manager here because
|
|
|
c90517 |
when Xorg exits it switches to the VT it was
|
|
|
c90517 |
started from. That interferes with fast
|
|
|
c90517 |
user switching. */
|
|
|
c90517 |
gdm_session_reset (operation->session);
|
|
|
c90517 |
destroy_start_user_session_operation (operation);
|
|
|
c90517 |
goto out;
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
display = get_display_for_user_session (operation->session);
|
|
|
c90517 |
|
|
|
c90517 |
g_object_get (G_OBJECT (display),
|
|
|
c90517 |
"doing-initial-setup", &doing_initial_setup,
|
|
|
c90517 |
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
|
|
|
c90517 |
"session-type", &display_session_type,
|
|
|
c90517 |
#endif
|
|
|
c90517 |
NULL);
|
|
|
c90517 |
|
|
|
c90517 |
session_id = gdm_session_get_conversation_session_id (operation->session,
|
|
|
c90517 |
operation->service_name);
|
|
|
c90517 |
|
|
|
c90517 |
if (gdm_session_get_display_mode (operation->session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) {
|
|
|
c90517 |
/* In this case, the greeter's display is morphing into
|
|
|
c90517 |
* the user session display. Kill the greeter on this session
|
|
|
c90517 |
* and let the user session follow the same display. */
|
|
|
c90517 |
gdm_display_stop_greeter_session (display);
|
|
|
c90517 |
g_object_set (G_OBJECT (display),
|
|
|
c90517 |
"session-class", "user",
|
|
|
c90517 |
"session-id", session_id,
|
|
|
c90517 |
NULL);
|
|
|
c90517 |
} else {
|
|
|
c90517 |
uid_t allowed_uid;
|
|
|
c90517 |
|
|
|
c90517 |
g_object_ref (display);
|
|
|
c90517 |
if (doing_initial_setup) {
|
|
|
c90517 |
+ g_autoptr(GError) error = NULL;
|
|
|
c90517 |
+
|
|
|
c90517 |
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
|
|
|
c90517 |
if (g_strcmp0 (display_session_type, "wayland") == 0) {
|
|
|
c90517 |
g_debug ("GdmManager: closing down initial setup display in background");
|
|
|
c90517 |
g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL);
|
|
|
c90517 |
}
|
|
|
c90517 |
#endif
|
|
|
c90517 |
if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) {
|
|
|
c90517 |
g_debug ("GdmManager: closing down initial setup display");
|
|
|
c90517 |
gdm_display_stop_greeter_session (display);
|
|
|
c90517 |
gdm_display_unmanage (display);
|
|
|
c90517 |
gdm_display_finish (display);
|
|
|
c90517 |
}
|
|
|
c90517 |
+
|
|
|
c90517 |
+ chown_initial_setup_home_dir ();
|
|
|
c90517 |
+
|
|
|
c90517 |
+ if (!g_file_set_contents (ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT,
|
|
|
c90517 |
+ "1",
|
|
|
c90517 |
+ 1,
|
|
|
c90517 |
+ &error)) {
|
|
|
c90517 |
+ g_warning ("GdmDisplay: Could not write initial-setup-done marker to %s: %s",
|
|
|
c90517 |
+ ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT,
|
|
|
c90517 |
+ error->message);
|
|
|
c90517 |
+ g_clear_error (&error);
|
|
|
c90517 |
+ }
|
|
|
c90517 |
} else {
|
|
|
c90517 |
g_debug ("GdmManager: session has its display server, reusing our server for another login screen");
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
/* The user session is going to follow the session worker
|
|
|
c90517 |
* into the new display. Untie it from this display and
|
|
|
c90517 |
* create a new session for a future user login. */
|
|
|
c90517 |
allowed_uid = gdm_session_get_allowed_user (operation->session);
|
|
|
c90517 |
g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL);
|
|
|
c90517 |
g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL);
|
|
|
c90517 |
create_user_session_for_display (operation->manager, display, allowed_uid);
|
|
|
c90517 |
|
|
|
c90517 |
/* Give the user session a new display object for bookkeeping purposes */
|
|
|
c90517 |
create_display_for_user_session (operation->manager,
|
|
|
c90517 |
operation->session,
|
|
|
c90517 |
session_id);
|
|
|
c90517 |
|
|
|
c90517 |
if ((g_strcmp0 (operation->service_name, "gdm-autologin") == 0) &&
|
|
|
c90517 |
!gdm_session_client_is_connected (operation->session)) {
|
|
|
c90517 |
/* remove the unused prepared greeter display since we're not going
|
|
|
c90517 |
* to have a greeter */
|
|
|
c90517 |
gdm_display_store_remove (self->priv->display_store, display);
|
|
|
c90517 |
g_object_unref (display);
|
|
|
c90517 |
|
|
|
c90517 |
self->priv->automatic_login_display = g_object_get_data (G_OBJECT (operation->session), "gdm-display");
|
|
|
c90517 |
g_object_add_weak_pointer (G_OBJECT (self->priv->automatic_login_display), (gpointer *) &self->priv->automatic_login_display);
|
|
|
c90517 |
}
|
|
|
c90517 |
}
|
|
|
c90517 |
|
|
|
c90517 |
start_user_session (operation->manager, operation);
|
|
|
c90517 |
--
|
|
|
c90517 |
2.26.0
|
|
|
c90517 |
|