diff --git a/.gdm.metadata b/.gdm.metadata index 4cd8773..bc466e4 100644 --- a/.gdm.metadata +++ b/.gdm.metadata @@ -1 +1 @@ -53e7f640a9a73e986efbf2e6d9796e6b40b9107b SOURCES/gdm-3.14.2.tar.xz +19582495748efdf3d4a20cf8b0e90d0d17c57558 SOURCES/gdm-3.22.3.tar.xz diff --git a/.gitignore b/.gitignore index 4253822..f652268 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/gdm-3.14.2.tar.xz +SOURCES/gdm-3.22.3.tar.xz diff --git a/SOURCES/0001-Honor-initial-setup-being-disabled-by-distro-install.patch b/SOURCES/0001-Honor-initial-setup-being-disabled-by-distro-install.patch new file mode 100644 index 0000000..96a78f5 --- /dev/null +++ b/SOURCES/0001-Honor-initial-setup-being-disabled-by-distro-install.patch @@ -0,0 +1,82 @@ +From fa5733788ae5f8e8caeb07e956be370e96f9b6b1 Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Mon, 23 Jan 2017 20:19:51 +0100 +Subject: [PATCH] Honor initial setup being disabled by distro installer + +Sysadmins might want to disable any kind of initial setup for their +users, perhaps because they pre-configure their environments. We +already provide a configuration file option for this but distro +installers might have their own way of requesting this. + +At least the anaconda installer provides an option to skip any kind +post-install setup tools so, for now we're only adding support for +that but more might be added in the future. + +https://bugzilla.gnome.org/show_bug.cgi?id=777708 +--- + daemon/Makefile.am | 1 + + daemon/gdm-display.c | 29 +++++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+) + +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index ab5dda0..786e0c5 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -14,6 +14,7 @@ AM_CPPFLAGS = \ + -DLOCALSTATEDIR=\"$(localstatedir)\" \ + -DLOGDIR=\"$(logdir)\" \ + -DSBINDIR=\"$(sbindir)\" \ ++ -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ + -DGDM_RUN_DIR=\"$(GDM_RUN_DIR)\" \ + -DGDM_XAUTH_DIR=\"$(GDM_XAUTH_DIR)\" \ +diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c +index 0057e2c..2af8e13 100644 +--- a/daemon/gdm-display.c ++++ b/daemon/gdm-display.c +@@ -1456,6 +1456,31 @@ can_create_environment (const char *session_id) + } + + static gboolean ++initial_setup_disabled_by_anaconda (void) ++{ ++ GKeyFile *key_file; ++ const gchar *file_name = SYSCONFDIR "/sysconfig/anaconda"; ++ gboolean disabled = FALSE; ++ GError *error = NULL; ++ ++ key_file = g_key_file_new (); ++ if (!g_key_file_load_from_file (key_file, file_name, G_KEY_FILE_NONE, &error)) { ++ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) && ++ !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) { ++ g_warning ("Could not read %s: %s", file_name, error->message); ++ } ++ g_error_free (error); ++ goto out; ++ } ++ ++ disabled = g_key_file_get_boolean (key_file, "General", ++ "post_install_tools_disabled", NULL); ++ out: ++ g_key_file_unref (key_file); ++ return disabled; ++} ++ ++static gboolean + wants_initial_setup (GdmDisplay *self) + { + gboolean enabled = FALSE; +@@ -1480,6 +1505,10 @@ wants_initial_setup (GdmDisplay *self) + return FALSE; + } + ++ if (initial_setup_disabled_by_anaconda ()) { ++ return FALSE; ++ } ++ + return enabled; + } + +-- +2.9.3 + diff --git a/SOURCES/0001-Revert-session-forward-is-initial-from-display-to-wo.patch b/SOURCES/0001-Revert-session-forward-is-initial-from-display-to-wo.patch new file mode 100644 index 0000000..8067b65 --- /dev/null +++ b/SOURCES/0001-Revert-session-forward-is-initial-from-display-to-wo.patch @@ -0,0 +1,1061 @@ +From 6df33bb3293d220bcdff7abc68f61ebad841ffe1 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 12 May 2017 10:11:09 -0400 +Subject: [PATCH] Revert "session: forward is-initial from display to worker" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reverts commit 7a4e34049c79e907d1a027390c5d3a8dcdc11977. + +It breaks login screen until reboot on 7.3→7.4 upgrade. +--- + daemon/gdm-display.c | 6 ------ + daemon/gdm-session-worker.c | 21 +++++---------------- + daemon/gdm-session-worker.xml | 3 --- + daemon/gdm-session.c | 25 ------------------------- + 4 files changed, 5 insertions(+), 50 deletions(-) + +diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c +index 2af8e13e..c44e4941 100644 +--- a/daemon/gdm-display.c ++++ b/daemon/gdm-display.c +@@ -1488,119 +1488,113 @@ wants_initial_setup (GdmDisplay *self) + /* don't run initial-setup on remote displays + */ + if (!self->priv->is_local) { + return FALSE; + } + + /* don't run if the system has existing users */ + if (self->priv->have_existing_user_accounts) { + return FALSE; + } + + /* don't run if initial-setup is unavailable */ + if (!can_create_environment ("gnome-initial-setup")) { + return FALSE; + } + + if (!gdm_settings_direct_get_boolean (GDM_KEY_INITIAL_SETUP_ENABLE, &enabled)) { + return FALSE; + } + + if (initial_setup_disabled_by_anaconda ()) { + return FALSE; + } + + return enabled; + } + + void + gdm_display_start_greeter_session (GdmDisplay *self) + { +- GdmSession *session; + char *display_name; + char *seat_id; + char *hostname; + char *auth_file = NULL; + + g_return_if_fail (g_strcmp0 (self->priv->session_class, "greeter") == 0); + + g_debug ("GdmDisplay: Running greeter"); + + display_name = NULL; + seat_id = NULL; + hostname = NULL; + + g_object_get (self, + "x11-display-name", &display_name, + "seat-id", &seat_id, + "remote-hostname", &hostname, + NULL); + if (self->priv->access_file != NULL) { + auth_file = gdm_display_access_file_get_path (self->priv->access_file); + } + + g_debug ("GdmDisplay: Creating greeter for %s %s", display_name, hostname); + + g_signal_connect_object (self->priv->launch_environment, + "opened", + G_CALLBACK (on_launch_environment_session_opened), + self, 0); + g_signal_connect_object (self->priv->launch_environment, + "started", + G_CALLBACK (on_launch_environment_session_started), + self, 0); + g_signal_connect_object (self->priv->launch_environment, + "stopped", + G_CALLBACK (on_launch_environment_session_stopped), + self, 0); + g_signal_connect_object (self->priv->launch_environment, + "exited", + G_CALLBACK (on_launch_environment_session_exited), + self, 0); + g_signal_connect_object (self->priv->launch_environment, + "died", + G_CALLBACK (on_launch_environment_session_died), + self, 0); + + if (auth_file != NULL) { + g_object_set (self->priv->launch_environment, + "x11-authority-file", auth_file, + NULL); + } + + gdm_launch_environment_start (self->priv->launch_environment); + +- session = gdm_launch_environment_get_session (self->priv->launch_environment); +- g_object_set (G_OBJECT (session), +- "display-is-initial", self->priv->is_initial, +- NULL); +- + g_free (display_name); + g_free (seat_id); + g_free (hostname); + g_free (auth_file); + } + + static void + chown_initial_setup_home_dir (void) + { + GFile *dir; + GError *error; + char *gis_dir_path; + char *gis_uid_path; + char *gis_uid_contents; + struct passwd *pwe; + uid_t uid; + + if (!gdm_get_pwent_for_name (INITIAL_SETUP_USERNAME, &pwe)) { + g_warning ("Unknown user %s", INITIAL_SETUP_USERNAME); + return; + } + + gis_dir_path = g_strdup (pwe->pw_dir); + + gis_uid_path = g_build_filename (gis_dir_path, + "gnome-initial-setup-uid", + NULL); + if (!g_file_get_contents (gis_uid_path, &gis_uid_contents, NULL, NULL)) { + g_warning ("Unable to read %s", gis_uid_path); + goto out; +diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c +index d97b02b5..dffc8917 100644 +--- a/daemon/gdm-session-worker.c ++++ b/daemon/gdm-session-worker.c +@@ -134,61 +134,60 @@ struct GdmSessionWorkerPrivate + pam_handle_t *pam_handle; + + GPid child_pid; + guint child_watch_id; + + /* from Setup */ + char *service; + char *x11_display_name; + char *x11_authority_file; + char *display_device; + char *display_seat_id; + char *hostname; + char *username; + char *log_file; + char *session_id; + uid_t uid; + gid_t gid; + gboolean password_is_required; + + int cred_flags; + int login_vt; + int session_vt; + int session_tty_fd; + + char **arguments; + guint32 cancelled : 1; + guint32 timed_out : 1; + guint32 is_program_session : 1; + guint32 is_reauth_session : 1; + guint32 display_is_local : 1; +- guint32 display_is_initial : 1; + guint state_change_idle_id; + GdmSessionDisplayMode display_mode; + + char *server_address; + GDBusConnection *connection; + GdmDBusWorkerManager *manager; + + GHashTable *reauthentication_requests; + + GdmSessionAuditor *auditor; + GdmSessionSettings *user_settings; + + GDBusMethodInvocation *pending_invocation; + }; + + enum { + PROP_0, + PROP_SERVER_ADDRESS, + PROP_IS_REAUTH_SESSION, + }; + + static void gdm_session_worker_class_init (GdmSessionWorkerClass *klass); + static void gdm_session_worker_init (GdmSessionWorker *session_worker); + static void gdm_session_worker_finalize (GObject *object); + + static void gdm_session_worker_set_environment_variable (GdmSessionWorker *worker, + const char *key, + const char *value); + + static void queue_state_change (GdmSessionWorker *worker); +@@ -2057,67 +2056,63 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, + g_assert (sizeof (GPid) <= sizeof (int)); + + g_debug ("GdmSessionWorker: state SESSION_STARTED"); + worker->priv->state = GDM_SESSION_WORKER_STATE_SESSION_STARTED; + + gdm_session_worker_watch_child (worker); + + out: + if (error_code != PAM_SUCCESS) { + gdm_session_worker_uninitialize_pam (worker, error_code); + return FALSE; + } + + return TRUE; + } + + static gboolean + set_up_for_new_vt (GdmSessionWorker *worker) + { + int fd; + char vt_string[256], tty_string[256]; + int session_vt = 0; + + fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); + + if (fd < 0) { + g_debug ("GdmSessionWorker: couldn't open VT master: %m"); + return FALSE; + } + +- if (worker->priv->display_is_initial) { +- session_vt = atoi (GDM_INITIAL_VT); +- } else { +- if (ioctl(fd, VT_OPENQRY, &session_vt) < 0) { +- g_debug ("GdmSessionWorker: couldn't open new VT: %m"); +- goto fail; +- } ++ if (ioctl(fd, VT_OPENQRY, &session_vt) < 0) { ++ g_debug ("GdmSessionWorker: couldn't open new VT: %m"); ++ goto fail; + } + + worker->priv->session_vt = session_vt; + + close (fd); + fd = -1; + + g_assert (session_vt > 0); + + g_snprintf (vt_string, sizeof (vt_string), "%d", session_vt); + + /* Set the VTNR. This is used by logind to configure a session in + * the logind-managed case, but it doesn't hurt to set it always. + * When logind gains support for XDG_VTNR=auto, we can make the + * OPENQRY and this whole path only used by the new VT code. */ + gdm_session_worker_set_environment_variable (worker, + "XDG_VTNR", + vt_string); + + g_snprintf (tty_string, 256, "/dev/tty%d", session_vt); + worker->priv->session_tty_fd = open (tty_string, O_RDWR | O_NOCTTY); + pam_set_item (worker->priv->pam_handle, PAM_TTY, tty_string); + + return TRUE; + + fail: + close (fd); + return FALSE; + } + +@@ -2795,166 +2790,160 @@ gdm_session_worker_handle_establish_credentials (GdmDBusWorker *object, + GdmSessionWorker *worker = GDM_SESSION_WORKER (object); + validate_and_queue_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_ACCREDITED); + + if (!worker->priv->is_reauth_session) { + worker->priv->cred_flags = PAM_ESTABLISH_CRED; + } else { + worker->priv->cred_flags = PAM_REINITIALIZE_CRED; + } + + return TRUE; + } + + static gboolean + gdm_session_worker_handle_open (GdmDBusWorker *object, + GDBusMethodInvocation *invocation) + { + GdmSessionWorker *worker = GDM_SESSION_WORKER (object); + validate_and_queue_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED); + return TRUE; + } + + static gboolean + gdm_session_worker_handle_setup (GdmDBusWorker *object, + GDBusMethodInvocation *invocation, + const char *service, + const char *x11_display_name, + const char *x11_authority_file, + const char *console, + const char *seat_id, + const char *hostname, +- gboolean display_is_local, +- gboolean display_is_initial) ++ gboolean display_is_local) + { + GdmSessionWorker *worker = GDM_SESSION_WORKER (object); + validate_and_queue_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE); + + worker->priv->service = g_strdup (service); + worker->priv->x11_display_name = g_strdup (x11_display_name); + worker->priv->x11_authority_file = g_strdup (x11_authority_file); + worker->priv->display_device = g_strdup (console); + worker->priv->display_seat_id = g_strdup (seat_id); + worker->priv->hostname = g_strdup (hostname); + worker->priv->display_is_local = display_is_local; +- worker->priv->display_is_initial = display_is_initial; + worker->priv->username = NULL; + + g_signal_connect_swapped (worker->priv->user_settings, + "notify::language-name", + G_CALLBACK (on_saved_language_name_read), + worker); + + g_signal_connect_swapped (worker->priv->user_settings, + "notify::session-name", + G_CALLBACK (on_saved_session_name_read), + worker); + return TRUE; + } + + static gboolean + gdm_session_worker_handle_setup_for_user (GdmDBusWorker *object, + GDBusMethodInvocation *invocation, + const char *service, + const char *username, + const char *x11_display_name, + const char *x11_authority_file, + const char *console, + const char *seat_id, + const char *hostname, +- gboolean display_is_local, +- gboolean display_is_initial) ++ gboolean display_is_local) + { + GdmSessionWorker *worker = GDM_SESSION_WORKER (object); + + if (!validate_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE)) + return TRUE; + + worker->priv->service = g_strdup (service); + worker->priv->x11_display_name = g_strdup (x11_display_name); + worker->priv->x11_authority_file = g_strdup (x11_authority_file); + worker->priv->display_device = g_strdup (console); + worker->priv->display_seat_id = g_strdup (seat_id); + worker->priv->hostname = g_strdup (hostname); + worker->priv->display_is_local = display_is_local; +- worker->priv->display_is_initial = display_is_initial; + worker->priv->username = g_strdup (username); + + g_signal_connect_swapped (worker->priv->user_settings, + "notify::language-name", + G_CALLBACK (on_saved_language_name_read), + worker); + + g_signal_connect_swapped (worker->priv->user_settings, + "notify::session-name", + G_CALLBACK (on_saved_session_name_read), + worker); + + /* Load settings from accounts daemon before continuing + */ + worker->priv->pending_invocation = invocation; + if (gdm_session_settings_load (worker->priv->user_settings, username)) { + queue_state_change (worker); + } else { + g_signal_connect (G_OBJECT (worker->priv->user_settings), + "notify::is-loaded", + G_CALLBACK (on_settings_is_loaded_changed), + worker); + } + + return TRUE; + } + + static gboolean + gdm_session_worker_handle_setup_for_program (GdmDBusWorker *object, + GDBusMethodInvocation *invocation, + const char *service, + const char *username, + const char *x11_display_name, + const char *x11_authority_file, + const char *console, + const char *seat_id, + const char *hostname, + gboolean display_is_local, +- gboolean display_is_initial, + const char *log_file) + { + GdmSessionWorker *worker = GDM_SESSION_WORKER (object); + validate_and_queue_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE); + + worker->priv->service = g_strdup (service); + worker->priv->x11_display_name = g_strdup (x11_display_name); + worker->priv->x11_authority_file = g_strdup (x11_authority_file); + worker->priv->display_device = g_strdup (console); + worker->priv->display_seat_id = g_strdup (seat_id); + worker->priv->hostname = g_strdup (hostname); + worker->priv->display_is_local = display_is_local; +- worker->priv->display_is_initial = display_is_initial; + worker->priv->username = g_strdup (username); + worker->priv->log_file = g_strdup (log_file); + worker->priv->is_program_session = TRUE; + + return TRUE; + } + + static gboolean + gdm_session_worker_handle_start_program (GdmDBusWorker *object, + GDBusMethodInvocation *invocation, + const char *text) + { + GdmSessionWorker *worker = GDM_SESSION_WORKER (object); + GError *parse_error = NULL; + validate_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SESSION_STARTED); + + if (worker->priv->is_reauth_session) { + g_dbus_method_invocation_return_error (invocation, + GDM_SESSION_WORKER_ERROR, + GDM_SESSION_WORKER_ERROR_IN_REAUTH_SESSION, + "Cannot start a program while in a reauth session"); + return TRUE; + } + + g_debug ("GdmSessionWorker: start program: %s", text); + + g_clear_pointer (&worker->priv->arguments, (GDestroyNotify) g_strfreev); + if (! g_shell_parse_argv (text, NULL, &worker->priv->arguments, &parse_error)) { + g_dbus_method_invocation_take_error (invocation, parse_error); + return TRUE; +diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml +index 9f6d8b35..f7d1dc2d 100644 +--- a/daemon/gdm-session-worker.xml ++++ b/daemon/gdm-session-worker.xml +@@ -5,83 +5,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +- + + + + + + + + + + +- + + + + + + + + + + +- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c +index e69291fb..1dfbef64 100644 +--- a/daemon/gdm-session.c ++++ b/daemon/gdm-session.c +@@ -103,74 +103,72 @@ struct _GdmSessionPrivate + GdmDBusUserVerifier *user_verifier_interface; + GdmDBusGreeter *greeter_interface; + GdmDBusRemoteGreeter *remote_greeter_interface; + GdmDBusChooser *chooser_interface; + + GList *pending_worker_connections; + GList *outside_connections; + + GPid session_pid; + + /* object lifetime scope */ + char *session_type; + char *display_name; + char *display_hostname; + char *display_device; + char *display_seat_id; + char *display_x11_authority_file; + gboolean display_is_local; + + GdmSessionVerificationMode verification_mode; + + uid_t allowed_user; + + char *fallback_session_name; + + GDBusServer *worker_server; + GDBusServer *outside_server; + GHashTable *environment; + + guint32 is_program_session : 1; +- guint32 display_is_initial : 1; + #ifdef ENABLE_WAYLAND_SUPPORT + guint32 ignore_wayland : 1; + #endif + }; + + enum { + PROP_0, + PROP_VERIFICATION_MODE, + PROP_ALLOWED_USER, + PROP_DISPLAY_NAME, + PROP_DISPLAY_HOSTNAME, + PROP_DISPLAY_IS_LOCAL, +- PROP_DISPLAY_IS_INITIAL, + PROP_SESSION_TYPE, + PROP_DISPLAY_DEVICE, + PROP_DISPLAY_SEAT_ID, + PROP_DISPLAY_X11_AUTHORITY_FILE, + PROP_USER_X11_AUTHORITY_FILE, + PROP_CONVERSATION_ENVIRONMENT, + #ifdef ENABLE_WAYLAND_SUPPORT + PROP_IGNORE_WAYLAND, + #endif + }; + + enum { + CONVERSATION_STARTED = 0, + CONVERSATION_STOPPED, + SETUP_COMPLETE, + CANCELLED, + HOSTNAME_SELECTED, + CLIENT_REJECTED, + CLIENT_CONNECTED, + CLIENT_DISCONNECTED, + CLIENT_READY_FOR_SESSION_TO_START, + DISCONNECTED, + AUTHENTICATION_FAILED, + VERIFICATION_COMPLETE, + SESSION_OPENED, + SESSION_STARTED, + SESSION_START_FAILED, + SESSION_EXITED, + SESSION_DIED, + REAUTHENTICATION_STARTED, +@@ -2118,61 +2116,60 @@ send_setup (GdmSession *self, + display_hostname = ""; + } + if (self->priv->display_device != NULL) { + display_device = self->priv->display_device; + } else { + display_device = ""; + } + if (self->priv->display_seat_id != NULL) { + display_seat_id = self->priv->display_seat_id; + } else { + display_seat_id = ""; + } + if (self->priv->display_x11_authority_file != NULL) { + display_x11_authority_file = self->priv->display_x11_authority_file; + } else { + display_x11_authority_file = ""; + } + + g_debug ("GdmSession: Beginning setup"); + + conversation = find_conversation_by_name (self, service_name); + if (conversation != NULL) { + gdm_dbus_worker_call_setup (conversation->worker_proxy, + service_name, + display_name, + display_x11_authority_file, + display_device, + display_seat_id, + display_hostname, + self->priv->display_is_local, +- self->priv->display_is_initial, + conversation->worker_cancellable, + (GAsyncReadyCallback) on_setup_complete_cb, + conversation); + } + } + + static void + send_setup_for_user (GdmSession *self, + const char *service_name) + { + const char *display_name; + const char *display_device; + const char *display_seat_id; + const char *display_hostname; + const char *display_x11_authority_file; + const char *selected_user; + GdmSessionConversation *conversation; + + g_assert (service_name != NULL); + + conversation = find_conversation_by_name (self, service_name); + + if (self->priv->display_name != NULL) { + display_name = self->priv->display_name; + } else { + display_name = ""; + } + if (self->priv->display_hostname != NULL) { + display_hostname = self->priv->display_hostname; + } else { +@@ -2184,122 +2181,120 @@ send_setup_for_user (GdmSession *self, + display_device = ""; + } + if (self->priv->display_seat_id != NULL) { + display_seat_id = self->priv->display_seat_id; + } else { + display_seat_id = ""; + } + if (self->priv->display_x11_authority_file != NULL) { + display_x11_authority_file = self->priv->display_x11_authority_file; + } else { + display_x11_authority_file = ""; + } + if (self->priv->selected_user != NULL) { + selected_user = self->priv->selected_user; + } else { + selected_user = ""; + } + + g_debug ("GdmSession: Beginning setup for user %s", self->priv->selected_user); + + if (conversation != NULL) { + gdm_dbus_worker_call_setup_for_user (conversation->worker_proxy, + service_name, + selected_user, + display_name, + display_x11_authority_file, + display_device, + display_seat_id, + display_hostname, + self->priv->display_is_local, +- self->priv->display_is_initial, + conversation->worker_cancellable, + (GAsyncReadyCallback) on_setup_complete_cb, + conversation); + } + } + + static void + send_setup_for_program (GdmSession *self, + const char *service_name, + const char *username, + const char *log_file) + { + const char *display_name; + const char *display_device; + const char *display_seat_id; + const char *display_hostname; + const char *display_x11_authority_file; + GdmSessionConversation *conversation; + + g_assert (service_name != NULL); + + if (self->priv->display_name != NULL) { + display_name = self->priv->display_name; + } else { + display_name = ""; + } + if (self->priv->display_hostname != NULL) { + display_hostname = self->priv->display_hostname; + } else { + display_hostname = ""; + } + if (self->priv->display_device != NULL) { + display_device = self->priv->display_device; + } else { + display_device = ""; + } + if (self->priv->display_seat_id != NULL) { + display_seat_id = self->priv->display_seat_id; + } else { + display_seat_id = ""; + } + if (self->priv->display_x11_authority_file != NULL) { + display_x11_authority_file = self->priv->display_x11_authority_file; + } else { + display_x11_authority_file = ""; + } + + g_debug ("GdmSession: Beginning setup for session for program using PAM service %s", service_name); + + conversation = find_conversation_by_name (self, service_name); + if (conversation != NULL) { + gdm_dbus_worker_call_setup_for_program (conversation->worker_proxy, + service_name, + username, + display_name, + display_x11_authority_file, + display_device, + display_seat_id, + display_hostname, + self->priv->display_is_local, +- self->priv->display_is_initial, + log_file, + conversation->worker_cancellable, + (GAsyncReadyCallback) on_setup_complete_cb, + conversation); + } + } + + void + gdm_session_setup (GdmSession *self, + const char *service_name) + { + + g_return_if_fail (GDM_IS_SESSION (self)); + + send_setup (self, service_name); + gdm_session_defaults_changed (self); + } + + + void + gdm_session_setup_for_user (GdmSession *self, + const char *service_name, + const char *username) + { + + g_return_if_fail (GDM_IS_SESSION (self)); + g_return_if_fail (username != NULL); + + gdm_session_select_user (self, username); + +@@ -3217,67 +3212,60 @@ set_display_seat_id (GdmSession *self, + const char *name) + { + g_free (self->priv->display_seat_id); + self->priv->display_seat_id = g_strdup (name); + } + + static void + set_user_x11_authority_file (GdmSession *self, + const char *name) + { + g_free (self->priv->user_x11_authority_file); + self->priv->user_x11_authority_file = g_strdup (name); + } + + static void + set_display_x11_authority_file (GdmSession *self, + const char *name) + { + g_free (self->priv->display_x11_authority_file); + self->priv->display_x11_authority_file = g_strdup (name); + } + + static void + set_display_is_local (GdmSession *self, + gboolean is_local) + { + self->priv->display_is_local = is_local; + } + + static void +-set_display_is_initial (GdmSession *self, +- gboolean is_initial) +-{ +- self->priv->display_is_initial = is_initial; +-} +- +-static void + set_verification_mode (GdmSession *self, + GdmSessionVerificationMode verification_mode) + { + self->priv->verification_mode = verification_mode; + } + + static void + set_allowed_user (GdmSession *self, + uid_t allowed_user) + { + self->priv->allowed_user = allowed_user; + } + + static void + set_conversation_environment (GdmSession *self, + char **environment) + { + g_strfreev (self->priv->conversation_environment); + self->priv->conversation_environment = g_strdupv (environment); + } + + static void + set_session_type (GdmSession *self, + const char *session_type) + { + + if (g_strcmp0 (self->priv->session_type, session_type) != 0) { + g_debug ("GdmSession: setting session to type '%s'", session_type? session_type : ""); + g_free (self->priv->session_type); + self->priv->session_type = g_strdup (session_type); +@@ -3292,121 +3280,115 @@ gdm_session_set_property (GObject *object, + { + GdmSession *self; + + self = GDM_SESSION (object); + + switch (prop_id) { + case PROP_SESSION_TYPE: + set_session_type (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_NAME: + set_display_name (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_HOSTNAME: + set_display_hostname (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_DEVICE: + set_display_device (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_SEAT_ID: + set_display_seat_id (self, g_value_get_string (value)); + break; + case PROP_USER_X11_AUTHORITY_FILE: + set_user_x11_authority_file (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_X11_AUTHORITY_FILE: + set_display_x11_authority_file (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_IS_LOCAL: + set_display_is_local (self, g_value_get_boolean (value)); + break; +- case PROP_DISPLAY_IS_INITIAL: +- set_display_is_initial (self, g_value_get_boolean (value)); +- break; + case PROP_VERIFICATION_MODE: + set_verification_mode (self, g_value_get_enum (value)); + break; + case PROP_ALLOWED_USER: + set_allowed_user (self, g_value_get_uint (value)); + break; + case PROP_CONVERSATION_ENVIRONMENT: + set_conversation_environment (self, g_value_get_pointer (value)); + break; + #ifdef ENABLE_WAYLAND_SUPPORT + case PROP_IGNORE_WAYLAND: + gdm_session_set_ignore_wayland (self, g_value_get_boolean (value)); + break; + #endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + } + + static void + gdm_session_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) + { + GdmSession *self; + + self = GDM_SESSION (object); + + switch (prop_id) { + case PROP_SESSION_TYPE: + g_value_set_string (value, self->priv->session_type); + break; + case PROP_DISPLAY_NAME: + g_value_set_string (value, self->priv->display_name); + break; + case PROP_DISPLAY_HOSTNAME: + g_value_set_string (value, self->priv->display_hostname); + break; + case PROP_DISPLAY_DEVICE: + g_value_set_string (value, self->priv->display_device); + break; + case PROP_DISPLAY_SEAT_ID: + g_value_set_string (value, self->priv->display_seat_id); + break; + case PROP_USER_X11_AUTHORITY_FILE: + g_value_set_string (value, self->priv->user_x11_authority_file); + break; + case PROP_DISPLAY_X11_AUTHORITY_FILE: + g_value_set_string (value, self->priv->display_x11_authority_file); + break; + case PROP_DISPLAY_IS_LOCAL: + g_value_set_boolean (value, self->priv->display_is_local); + break; +- case PROP_DISPLAY_IS_INITIAL: +- g_value_set_boolean (value, self->priv->display_is_initial); +- break; + case PROP_VERIFICATION_MODE: + g_value_set_enum (value, self->priv->verification_mode); + break; + case PROP_ALLOWED_USER: + g_value_set_uint (value, self->priv->allowed_user); + break; + case PROP_CONVERSATION_ENVIRONMENT: + g_value_set_pointer (value, self->priv->environment); + break; + #ifdef ENABLE_WAYLAND_SUPPORT + case PROP_IGNORE_WAYLAND: + g_value_set_boolean (value, self->priv->ignore_wayland); + break; + #endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + } + + static void + gdm_session_dispose (GObject *object) + { + GdmSession *self; + + self = GDM_SESSION (object); + + g_debug ("GdmSession: Disposing session"); + + gdm_session_close (self); +@@ -3749,67 +3731,60 @@ gdm_session_class_init (GdmSessionClass *session_class) + + g_object_class_install_property (object_class, + PROP_SESSION_TYPE, + g_param_spec_string ("session-type", + NULL, + NULL, + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_DISPLAY_NAME, + g_param_spec_string ("display-name", + "display name", + "display name", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_DISPLAY_HOSTNAME, + g_param_spec_string ("display-hostname", + "display hostname", + "display hostname", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_DISPLAY_IS_LOCAL, + g_param_spec_boolean ("display-is-local", + "display is local", + "display is local", + TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, +- PROP_DISPLAY_IS_INITIAL, +- g_param_spec_boolean ("display-is-initial", +- "display is initial", +- "display is initial", +- FALSE, +- G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); +- g_object_class_install_property (object_class, + PROP_DISPLAY_X11_AUTHORITY_FILE, + g_param_spec_string ("display-x11-authority-file", + "display x11 authority file", + "display x11 authority file", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /* not construct only */ + g_object_class_install_property (object_class, + PROP_USER_X11_AUTHORITY_FILE, + g_param_spec_string ("user-x11-authority-file", + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_DISPLAY_DEVICE, + g_param_spec_string ("display-device", + "display device", + "display device", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (object_class, + PROP_DISPLAY_SEAT_ID, + g_param_spec_string ("display-seat-id", + "display seat id", + "display seat id", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + +-- +2.12.2 + diff --git a/SOURCES/0001-gdm.conf-custom.in-strip-out-reference-to-wayland.patch b/SOURCES/0001-gdm.conf-custom.in-strip-out-reference-to-wayland.patch new file mode 100644 index 0000000..901c86f --- /dev/null +++ b/SOURCES/0001-gdm.conf-custom.in-strip-out-reference-to-wayland.patch @@ -0,0 +1,33 @@ +From 539b8a08787f86586eabe8fd502ec2faff5a74d9 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 16 Mar 2017 10:52:41 -0400 +Subject: [PATCH] gdm.conf-custom.in: strip out reference to wayland + +--- + data/gdm.conf-custom.in | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/data/gdm.conf-custom.in b/data/gdm.conf-custom.in +index 67ebca39..73d0b5f4 100644 +--- a/data/gdm.conf-custom.in ++++ b/data/gdm.conf-custom.in +@@ -1,16 +1,14 @@ + # GDM configuration storage + + [daemon] +-# Uncoment the line below to force the login screen to use Xorg +-#WaylandEnable=false + + [security] + + [xdmcp] + + [chooser] + + [debug] + # Uncomment the line below to turn on debugging + #Enable=true + +-- +2.11.1 + diff --git a/SOURCES/0001-local-display-factory-add-missing-comma-to-fix-user-.patch b/SOURCES/0001-local-display-factory-add-missing-comma-to-fix-user-.patch new file mode 100644 index 0000000..6a59dca --- /dev/null +++ b/SOURCES/0001-local-display-factory-add-missing-comma-to-fix-user-.patch @@ -0,0 +1,87 @@ +From 4b07f66e36bb00d022494c9118e4dc12921bce6d Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 3 Apr 2017 13:25:58 -0400 +Subject: [PATCH] local-display-factory: add missing comma to fix user + switching + +commit 4b47633b36a22195e7976a8e597862eff695ca86 refactored some code +and inadvertently dropped an important comma, which broke user +switching. + +This commit reintroduces the comma. + +https://bugzilla.gnome.org/show_bug.cgi?id=780879 +--- + daemon/gdm-local-display-factory.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c +index 70987c71..7a4643d0 100644 +--- a/daemon/gdm-local-display-factory.c ++++ b/daemon/gdm-local-display-factory.c +@@ -192,61 +192,61 @@ store_display (GdmLocalDisplayFactory *factory, + /org/gnome/DisplayManager/Manager \ + org.gnome.DisplayManager.Manager.GetDisplays + */ + gboolean + gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory, + char **id, + GError **error) + { + gboolean ret; + GdmDisplay *display = NULL; + + g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); + + ret = FALSE; + + g_debug ("GdmLocalDisplayFactory: Creating transient display"); + + #ifdef ENABLE_USER_DISPLAY_SERVER + display = gdm_local_display_new (); + #else + if (display == NULL) { + guint32 num; + + num = take_next_display_number (factory); + + display = gdm_legacy_display_new (num); + } + #endif + + g_object_set (display, +- "seat-id", "seat0" ++ "seat-id", "seat0", + "allow-timed-login", FALSE, + NULL); + + store_display (factory, display); + + if (! gdm_display_manage (display)) { + display = NULL; + goto out; + } + + if (! gdm_display_get_id (display, id, NULL)) { + display = NULL; + goto out; + } + + ret = TRUE; + out: + /* ref either held by store or not at all */ + g_object_unref (display); + + return ret; + } + + static void + on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmLocalDisplayFactory *factory) + { + int status; + GdmDisplayStore *store; +-- +2.12.0 + diff --git a/SOURCES/0001-manager-be-more-robust-against-autologin-having-an-i.patch b/SOURCES/0001-manager-be-more-robust-against-autologin-having-an-i.patch new file mode 100644 index 0000000..aeb46c4 --- /dev/null +++ b/SOURCES/0001-manager-be-more-robust-against-autologin-having-an-i.patch @@ -0,0 +1,430 @@ +From 5afc4cd548f3ae8db9fbaab32fe2189efff37677 Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Tue, 12 Jan 2016 21:42:15 -0600 +Subject: [PATCH 01/13] manager: be more robust against autologin having an + invalid user + +If the configured autologin user does not exist, fall back to a +greeter session. + +https://bugzilla.gnome.org/show_bug.cgi?id=695250 +--- + configure.ac | 2 +- + daemon/gdm-manager.c | 115 +++++++++++++++++++++++++++++++++++++-------------- + 2 files changed, 86 insertions(+), 31 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 6613097b..119297c5 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -36,61 +36,61 @@ AC_SUBST(LT_AGE) + + AC_HEADER_STDC + + AC_SUBST(VERSION) + + AC_CONFIG_HEADERS(config.h) + AC_CONFIG_MACRO_DIR([m4]) + + # Documentation + enable_documentation=no + m4_ifdef([YELP_HELP_INIT],[ + YELP_HELP_INIT + enable_documentation=yes + ]) + AM_CONDITIONAL(ENABLE_DOCUMENTATION, test x$enable_documentation = xyes) + + # i18n stuff + IT_PROG_INTLTOOL([0.40.0]) + + GETTEXT_PACKAGE=gdm + AC_SUBST(GETTEXT_PACKAGE) + AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [gettext package]) + + dnl --------------------------------------------------------------------------- + dnl - Dependencies + dnl --------------------------------------------------------------------------- + + GLIB_REQUIRED_VERSION=2.36.0 + GTK_REQUIRED_VERSION=2.91.1 + LIBCANBERRA_GTK_REQUIRED_VERSION=0.4 +-ACCOUNTS_SERVICE_REQUIRED_VERSION=0.6.12 ++ACCOUNTS_SERVICE_REQUIRED_VERSION=0.6.35 + + EXTRA_COMPILE_WARNINGS(yes) + + PKG_CHECK_MODULES(GTHREAD, gthread-2.0) + AC_SUBST(GTHREAD_CFLAGS) + AC_SUBST(GTHREAD_LIBS) + + PKG_CHECK_MODULES(COMMON, + gobject-2.0 >= $GLIB_REQUIRED_VERSION + gio-2.0 >= $GLIB_REQUIRED_VERSION + gio-unix-2.0 >= $GLIB_REQUIRED_VERSION + ) + AC_SUBST(COMMON_CFLAGS) + AC_SUBST(COMMON_LIBS) + + PKG_CHECK_MODULES(DAEMON, + gobject-2.0 >= $GLIB_REQUIRED_VERSION + gio-2.0 >= $GLIB_REQUIRED_VERSION + gio-unix-2.0 >= $GLIB_REQUIRED_VERSION + accountsservice >= $ACCOUNTS_SERVICE_REQUIRED_VERSION + xcb + ) + AC_SUBST(DAEMON_CFLAGS) + AC_SUBST(DAEMON_LIBS) + + GLIB_GSETTINGS + + PKG_CHECK_MODULES(XLIB, x11 xau, , + [AC_PATH_XTRA + if test "x$no_x" = xyes; then +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 35a7a0fe..e78228b4 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -7,60 +7,62 @@ + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + #include "config.h" + + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + ++#include ++ + #include + + #include "gdm-common.h" + + #include "gdm-dbus-util.h" + #include "gdm-manager.h" + #include "gdm-manager-glue.h" + #include "gdm-display-store.h" + #include "gdm-display-factory.h" + #include "gdm-local-display.h" + #include "gdm-local-display-factory.h" + #include "gdm-session.h" + #include "gdm-session-record.h" + #include "gdm-settings-direct.h" + #include "gdm-settings-keys.h" + #include "gdm-xdmcp-display-factory.h" + + #define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate)) + + #define GDM_DBUS_PATH "/org/gnome/DisplayManager" + #define GDM_MANAGER_PATH GDM_DBUS_PATH "/Manager" + #define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays" + + #define INITIAL_SETUP_USERNAME "gnome-initial-setup" + + typedef struct + { + GdmManager *manager; + GdmSession *session; + char *service_name; +@@ -1227,79 +1229,60 @@ get_automatic_login_details (GdmManager *manager, + if (res && enabled) { + res = gdm_settings_direct_get_string (GDM_KEY_AUTO_LOGIN_USER, &username); + } + + if (enabled && res && username != NULL && username[0] != '\0') { + goto out; + } + + g_free (username); + username = NULL; + enabled = FALSE; + + out: + if (enabled) { + g_debug ("GdmDisplay: Got automatic login details for display: %d %s", + enabled, + username); + } else { + g_debug ("GdmDisplay: Got automatic login details for display: 0"); + } + + if (usernamep != NULL) { + *usernamep = username; + } else { + g_free (username); + } + + return enabled; + } + +-static gboolean +-display_should_autologin (GdmManager *manager, +- GdmDisplay *display) +-{ +- gboolean enabled = FALSE; +- +- if (manager->priv->ran_once) { +- return FALSE; +- } +- +- if (!display_is_on_seat0 (display)) { +- return FALSE; +- } +- +- enabled = get_automatic_login_details (manager, NULL); +- +- return enabled; +-} +- + static void + maybe_start_pending_initial_login (GdmManager *manager, + GdmDisplay *greeter_display) + { + StartUserSessionOperation *operation; + char *greeter_seat_id = NULL; + char *user_session_seat_id = NULL; + + /* There may be a user session waiting to be started. + * This would happen if we couldn't start it earlier because + * the login screen X server was coming up and two X servers + * can't be started on the same seat at the same time. + */ + + if (manager->priv->initial_login_operation == NULL) { + return; + } + + operation = manager->priv->initial_login_operation; + + g_object_get (G_OBJECT (greeter_display), + "seat-id", &greeter_seat_id, + NULL); + g_object_get (G_OBJECT (operation->session), + "display-seat-id", &user_session_seat_id, + NULL); + + if (g_strcmp0 (greeter_seat_id, user_session_seat_id) == 0) { + start_user_session (manager, operation); + manager->priv->initial_login_operation = NULL; +@@ -1347,114 +1330,186 @@ set_up_automatic_login_session (GdmManager *manager, + g_object_set (G_OBJECT (session), + "display-is-initial", is_initial, + NULL); + + g_debug ("GdmManager: Starting automatic login conversation"); + gdm_session_start_conversation (session, "gdm-autologin"); + } + + static void + set_up_greeter_session (GdmManager *manager, + GdmDisplay *display) + { + const char *allowed_user; + struct passwd *passwd_entry; + + allowed_user = get_username_for_greeter_display (manager, display); + + if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) { + g_warning ("GdmManager: couldn't look up username %s", + allowed_user); + gdm_display_unmanage (display); + gdm_display_finish (display); + return; + } + + create_embryonic_user_session_for_display (manager, display, passwd_entry->pw_uid); + gdm_display_start_greeter_session (display); + } + + static void ++set_up_automatic_login_session_if_user_exists (GdmManager *manager, ++ GdmDisplay *display, ++ ActUser *user) ++{ ++ if (act_user_is_nonexistent (user)) ++ set_up_greeter_session (manager, display); ++ else ++ set_up_automatic_login_session (manager, display); ++} ++ ++typedef struct { ++ GdmManager *manager; ++ GdmDisplay *display; ++ char *username; ++} UsernameLookupOperation; ++ ++static void ++destroy_username_lookup_operation (UsernameLookupOperation *operation) ++{ ++ g_object_unref (operation->manager); ++ g_object_unref (operation->display); ++ g_free (operation->username); ++ g_free (operation); ++} ++ ++static void ++on_user_is_loaded_changed (ActUser *user, ++ GParamSpec *pspec, ++ UsernameLookupOperation *operation) ++{ ++ if (act_user_is_loaded (user)) { ++ set_up_automatic_login_session_if_user_exists (operation->manager, operation->display, user); ++ g_signal_handlers_disconnect_by_func (G_OBJECT (user), ++ G_CALLBACK (on_user_is_loaded_changed), ++ operation); ++ destroy_username_lookup_operation (operation); ++ } ++} ++ ++static void ++set_up_session (GdmManager *manager, ++ GdmDisplay *display) ++{ ++ ActUserManager *user_manager; ++ ActUser *user; ++ gboolean loaded; ++ gboolean autologin_enabled = FALSE; ++ char *username = NULL; ++ ++ if (!manager->priv->ran_once && display_is_on_seat0 (display)) ++ autologin_enabled = get_automatic_login_details (manager, &username); ++ ++ if (!autologin_enabled) { ++ set_up_greeter_session (manager, display); ++ g_free (username); ++ return; ++ } ++ ++ /* Check whether the user really exists before committing to autologin. */ ++ user_manager = act_user_manager_get_default (); ++ user = act_user_manager_get_user (user_manager, username); ++ g_object_get (user_manager, "is-loaded", &loaded, NULL); ++ ++ if (loaded) { ++ set_up_automatic_login_session_if_user_exists (manager, display, user); ++ } else { ++ UsernameLookupOperation *operation; ++ ++ operation = g_new (UsernameLookupOperation, 1); ++ operation->manager = g_object_ref (manager); ++ operation->display = g_object_ref (display); ++ operation->username = username; ++ ++ g_signal_connect (user, ++ "notify::is-loaded", ++ G_CALLBACK (on_user_is_loaded_changed), ++ operation); ++ } ++} ++ ++static void + greeter_display_started (GdmManager *manager, + GdmDisplay *display) + { + if (manager->priv->ran_once) { + return; + } + + maybe_start_pending_initial_login (manager, display); + + manager->priv->ran_once = TRUE; + } + + static void + on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmManager *manager) + { + int status; + int display_number = -1; + #ifdef WITH_PLYMOUTH + gboolean display_is_local = FALSE; + gboolean quit_plymouth = FALSE; + + g_object_get (display, + "is-local", &display_is_local, + NULL); + quit_plymouth = display_is_local && manager->priv->plymouth_is_running; + #endif + + g_object_get (display, "x11-display-number", &display_number, NULL); + + status = gdm_display_get_status (display); + + switch (status) { + case GDM_DISPLAY_PREPARED: + case GDM_DISPLAY_MANAGED: + if ((display_number == -1 && status == GDM_DISPLAY_PREPARED) || + (display_number != -1 && status == GDM_DISPLAY_MANAGED)) { + char *session_class; + + g_object_get (display, + "session-class", &session_class, + NULL); +- if (g_strcmp0 (session_class, "greeter") == 0) { +- gboolean will_autologin; +- +- will_autologin = display_should_autologin (manager, display); +- +- if (will_autologin) { +- set_up_automatic_login_session (manager, display); +- } else { +- set_up_greeter_session (manager, display); +- } +- } ++ if (g_strcmp0 (session_class, "greeter") == 0) ++ set_up_session (manager, display); + g_free (session_class); + } + + if (status == GDM_DISPLAY_MANAGED) { + greeter_display_started (manager, display); + } + break; + case GDM_DISPLAY_FAILED: + case GDM_DISPLAY_UNMANAGED: + case GDM_DISPLAY_FINISHED: + #ifdef WITH_PLYMOUTH + if (quit_plymouth) { + plymouth_quit_without_transition (); + manager->priv->plymouth_is_running = FALSE; + } + #endif + + maybe_start_pending_initial_login (manager, display); + break; + default: + break; + } + + } + + static void + on_display_removed (GdmDisplayStore *display_store, + const char *id, + GdmManager *manager) + { +-- +2.12.0 + diff --git a/SOURCES/0001-manager-make-sure-we-end-up-on-a-login-screen.patch b/SOURCES/0001-manager-make-sure-we-end-up-on-a-login-screen.patch new file mode 100644 index 0000000..bd03bdb --- /dev/null +++ b/SOURCES/0001-manager-make-sure-we-end-up-on-a-login-screen.patch @@ -0,0 +1,169 @@ +From 73ebe0f786241e262ebf4358cc5638ffcb35f8a1 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 4 Apr 2017 17:07:04 -0400 +Subject: [PATCH 1/2] manager: make sure we end up on a login screen + +If we're running in legacy mode where VT1 is not necessarily a login +screen, then we can end up in a situation where logging out leaves us +sitting on the wrong vt. + +1) log in to user 1 on vt 1 +2) switch user to login screen on vt 2 and log in as user 2 on vt 2 +3) switch user to login screen on vt 3 and unlock user 1 back on vt 1 +4) log out of user 1 on vt 1 +5) now sitting at blank vt 1 + +This commit makes sure in that case we jump to a login screen +--- + daemon/gdm-manager.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 128 insertions(+) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 373778d..6ffb842 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1312,6 +1312,133 @@ maybe_start_pending_initial_login (GdmManager *manager, + g_free (user_session_seat_id); + } + ++static gboolean ++get_login_window_session_id (const char *seat_id, ++ char **session_id) ++{ ++ gboolean ret; ++ int res, i; ++ char **sessions; ++ char *service_id; ++ char *service_class; ++ char *state; ++ ++ res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL); ++ if (res < 0) { ++ g_debug ("Failed to determine sessions: %s", strerror (-res)); ++ return FALSE; ++ } ++ ++ if (sessions == NULL || sessions[0] == NULL) { ++ *session_id = NULL; ++ ret = TRUE; ++ goto out; ++ } ++ ++ for (i = 0; sessions[i]; i ++) { ++ ++ res = sd_session_get_class (sessions[i], &service_class); ++ if (res < 0) { ++ g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); ++ ret = FALSE; ++ goto out; ++ } ++ ++ if (strcmp (service_class, "greeter") != 0) { ++ free (service_class); ++ continue; ++ } ++ ++ free (service_class); ++ ++ ret = sd_session_get_state (sessions[i], &state); ++ if (ret < 0) { ++ g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res)); ++ ret = FALSE; ++ goto out; ++ } ++ ++ if (g_strcmp0 (state, "closing") == 0) { ++ free (state); ++ continue; ++ } ++ free (state); ++ ++ res = sd_session_get_service (sessions[i], &service_id); ++ if (res < 0) { ++ g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); ++ ret = FALSE; ++ goto out; ++ } ++ ++ if (strcmp (service_id, "gdm-launch-environment") == 0) { ++ *session_id = g_strdup (sessions[i]); ++ ret = TRUE; ++ ++ free (service_id); ++ goto out; ++ } ++ ++ free (service_id); ++ } ++ ++ *session_id = NULL; ++ ret = TRUE; ++ ++out: ++ if (sessions) { ++ for (i = 0; sessions[i]; i ++) { ++ free (sessions[i]); ++ } ++ ++ free (sessions); ++ } ++ ++ return ret; ++} ++ ++static void ++activate_login_window_session_on_seat (GdmManager *self, ++ const char *seat_id) ++{ ++ char *session_id; ++ ++ if (!get_login_window_session_id (seat_id, &session_id)) { ++ return; ++ } ++ ++ activate_session_id (self, seat_id, session_id); ++} ++ ++static void ++maybe_activate_other_session (GdmManager *self, ++ GdmDisplay *old_display) ++{ ++ char *seat_id = NULL; ++ char *session_id; ++ int ret; ++ ++ g_object_get (G_OBJECT (old_display), ++ "seat-id", &seat_id, ++ NULL); ++ ++ ret = sd_seat_get_active (seat_id, &session_id, NULL); ++ ++ if (ret == 0) { ++ GdmDisplay *display; ++ ++ display = gdm_display_store_find (self->priv->display_store, ++ lookup_by_session_id, ++ (gpointer) session_id); ++ ++ if (display == NULL) { ++ activate_login_window_session_on_seat (self, seat_id); ++ } ++ } ++ ++ g_free (seat_id); ++} ++ + static const char * + get_username_for_greeter_display (GdmManager *manager, + GdmDisplay *display) +@@ -1545,6 +1672,7 @@ on_display_status_changed (GdmDisplay *display, + #endif + + maybe_start_pending_initial_login (manager, display); ++ maybe_activate_other_session (manager, display); + break; + default: + break; +-- +1.8.3.1 + diff --git a/SOURCES/0001-manager-update-session-id-property-when-reusing-disp.patch b/SOURCES/0001-manager-update-session-id-property-when-reusing-disp.patch new file mode 100644 index 0000000..585fd65 --- /dev/null +++ b/SOURCES/0001-manager-update-session-id-property-when-reusing-disp.patch @@ -0,0 +1,161 @@ +From b1e364e4f5651888be7a075dad044b445e0f0236 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 4 May 2017 15:34:33 -0400 +Subject: [PATCH] manager: update session-id property when reusing display + +If a display starts out its life as a greeter display, and then +gets reused for the user session, we need to update the session-id +property on the display to match its new session. + +This is important so the reauthentication process match the +session with existing display and run in the proper context. +--- + daemon/gdm-manager.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 9201b9f8..3eef745f 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1750,130 +1750,134 @@ start_user_session (GdmManager *manager, + static void + create_display_for_user_session (GdmManager *self, + GdmSession *session, + const char *session_id) + { + GdmDisplay *display; + /* at the moment we only create GdmLocalDisplay objects on seat0 */ + const char *seat_id = "seat0"; + + display = gdm_local_display_new (); + + g_object_set (G_OBJECT (display), + "session-class", "user", + "seat-id", seat_id, + "session-id", session_id, + NULL); + gdm_display_store_add (self->priv->display_store, + display); + g_object_set_data (G_OBJECT (session), "gdm-display", display); + } + + static gboolean + on_start_user_session (StartUserSessionOperation *operation) + { + GdmManager *self = operation->manager; + gboolean migrated; + gboolean fail_if_already_switched = TRUE; + gboolean doing_initial_setup = FALSE; + gboolean starting_user_session_right_away = TRUE; + GdmDisplay *display; ++ const char *session_id; + + g_debug ("GdmManager: start or jump to session"); + + /* If there's already a session running, jump to it. + * If the only session running is the one we just opened, + * start a session on it. + */ + migrated = switch_to_compatible_user_session (operation->manager, operation->session, fail_if_already_switched); + + g_debug ("GdmManager: migrated: %d", migrated); + if (migrated) { + /* We don't stop the manager here because + when Xorg exits it switches to the VT it was + started from. That interferes with fast + user switching. */ + gdm_session_reset (operation->session); + destroy_start_user_session_operation (operation); + goto out; + } + + display = get_display_for_user_session (operation->session); + + g_object_get (G_OBJECT (display), "doing-initial-setup", &doing_initial_setup, NULL); + ++ session_id = gdm_session_get_conversation_session_id (operation->session, ++ operation->service_name); ++ + if (gdm_session_get_display_mode (operation->session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { + /* In this case, the greeter's display is morphing into + * the user session display. Kill the greeter on this session + * and let the user session follow the same display. */ + gdm_display_stop_greeter_session (display); +- g_object_set (G_OBJECT (display), "session-class", "user", NULL); ++ g_object_set (G_OBJECT (display), ++ "session-class", "user", ++ "session-id", session_id, ++ NULL); + } else { +- const char *session_id; + uid_t allowed_uid; + + g_object_ref (display); + if (doing_initial_setup) { + g_debug ("GdmManager: closing down initial setup display"); + gdm_display_stop_greeter_session (display); + gdm_display_unmanage (display); + gdm_display_finish (display); + + /* We can't start the user session until the finished display + * starts to respawn (since starting an X server and bringing + * one down at the same time is a no go) + */ + g_assert (self->priv->initial_login_operation == NULL); + self->priv->initial_login_operation = operation; + starting_user_session_right_away = FALSE; + } else { + g_debug ("GdmManager: session has its display server, reusing our server for another login screen"); + } + + /* The user session is going to follow the session worker + * into the new display. Untie it from this display and + * create a new embryonic session for a future user login. */ + allowed_uid = gdm_session_get_allowed_user (operation->session); + g_object_set_data (G_OBJECT (display), "gdm-embryonic-user-session", NULL); + g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL); + create_embryonic_user_session_for_display (operation->manager, display, allowed_uid); + + if (g_strcmp0 (operation->service_name, "gdm-autologin") == 0) { + /* remove the unused prepared greeter display since we're not going + * to have a greeter */ + gdm_display_store_remove (self->priv->display_store, display); + g_object_unref (display); + } + + /* Give the user session a new display object for bookkeeping purposes */ +- session_id = gdm_session_get_conversation_session_id (operation->session, +- operation->service_name); + create_display_for_user_session (operation->manager, + operation->session, + session_id); + } + + if (starting_user_session_right_away) { + start_user_session (operation->manager, operation); + } + + out: + return G_SOURCE_REMOVE; + } + + static void + queue_start_user_session (GdmManager *manager, + GdmSession *session, + const char *service_name) + { + StartUserSessionOperation *operation; + + operation = g_slice_new0 (StartUserSessionOperation); + operation->manager = manager; + operation->session = g_object_ref (session); + operation->service_name = g_strdup (service_name); + + operation->idle_id = g_idle_add ((GSourceFunc) on_start_user_session, operation); + g_object_set_data (G_OBJECT (session), "start-user-session-operation", operation); + } + + static void +-- +2.12.2 + diff --git a/SOURCES/0001-worker-add-compat-patch-to-make-new-worker-work-with.patch b/SOURCES/0001-worker-add-compat-patch-to-make-new-worker-work-with.patch new file mode 100644 index 0000000..fa796d3 --- /dev/null +++ b/SOURCES/0001-worker-add-compat-patch-to-make-new-worker-work-with.patch @@ -0,0 +1,104 @@ +From cc1eef39a91bdff761791a4ccb6074cca0888ea1 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 12 May 2017 15:20:14 -0400 +Subject: [PATCH] worker: add compat patch to make new worker work with old + daemon + +--- + daemon/gdm-session-worker.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c +index dffc8917..81aaa5e7 100644 +--- a/daemon/gdm-session-worker.c ++++ b/daemon/gdm-session-worker.c +@@ -2897,69 +2897,86 @@ gdm_session_worker_handle_setup_for_user (GdmDBusWorker *object, + static gboolean + gdm_session_worker_handle_setup_for_program (GdmDBusWorker *object, + GDBusMethodInvocation *invocation, + const char *service, + const char *username, + const char *x11_display_name, + const char *x11_authority_file, + const char *console, + const char *seat_id, + const char *hostname, + gboolean display_is_local, + const char *log_file) + { + GdmSessionWorker *worker = GDM_SESSION_WORKER (object); + validate_and_queue_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE); + + worker->priv->service = g_strdup (service); + worker->priv->x11_display_name = g_strdup (x11_display_name); + worker->priv->x11_authority_file = g_strdup (x11_authority_file); + worker->priv->display_device = g_strdup (console); + worker->priv->display_seat_id = g_strdup (seat_id); + worker->priv->hostname = g_strdup (hostname); + worker->priv->display_is_local = display_is_local; + worker->priv->username = g_strdup (username); + worker->priv->log_file = g_strdup (log_file); + worker->priv->is_program_session = TRUE; + + return TRUE; + } + ++static void ++fix_environment_if_old_gdm_daemon_running (GdmSessionWorker *worker) ++{ ++ const char *daemon_version; ++ const char *username; ++ ++ daemon_version = gdm_session_worker_get_environment_variable (worker, "GDM_VERSION"); ++ username = gdm_session_worker_get_environment_variable (worker, "USERNAME"); ++ ++ if (g_strcmp0 (daemon_version, "3.14.2") == 0 && ++ g_strcmp0 (username, "gdm") == 0) { ++ gdm_session_worker_set_environment_variable (worker, "GNOME_SHELL_SESSION_MODE", "gdm"); ++ } ++} ++ + static gboolean + gdm_session_worker_handle_start_program (GdmDBusWorker *object, + GDBusMethodInvocation *invocation, + const char *text) + { + GdmSessionWorker *worker = GDM_SESSION_WORKER (object); + GError *parse_error = NULL; + validate_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SESSION_STARTED); + ++ fix_environment_if_old_gdm_daemon_running (worker); ++ + if (worker->priv->is_reauth_session) { + g_dbus_method_invocation_return_error (invocation, + GDM_SESSION_WORKER_ERROR, + GDM_SESSION_WORKER_ERROR_IN_REAUTH_SESSION, + "Cannot start a program while in a reauth session"); + return TRUE; + } + + g_debug ("GdmSessionWorker: start program: %s", text); + + g_clear_pointer (&worker->priv->arguments, (GDestroyNotify) g_strfreev); + if (! g_shell_parse_argv (text, NULL, &worker->priv->arguments, &parse_error)) { + g_dbus_method_invocation_take_error (invocation, parse_error); + return TRUE; + } + + worker->priv->pending_invocation = invocation; + queue_state_change (worker); + + return TRUE; + } + + static void + on_reauthentication_client_connected (GdmSession *session, + GCredentials *credentials, + GPid pid_of_client, + ReauthenticationRequest *request) + { + g_debug ("GdmSessionWorker: client connected to reauthentication server"); + } +-- +2.12.2 + diff --git a/SOURCES/0002-manager-stop-transient-greeter-session-when-done-wit.patch b/SOURCES/0002-manager-stop-transient-greeter-session-when-done-wit.patch new file mode 100644 index 0000000..c2ba6f6 --- /dev/null +++ b/SOURCES/0002-manager-stop-transient-greeter-session-when-done-wit.patch @@ -0,0 +1,51 @@ +From 66250ce6402087d2e08f2008782edc02a0d013b0 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 5 Apr 2017 12:11:20 -0400 +Subject: [PATCH 2/2] manager: stop transient greeter session when done with it + +If we're running in legacy display mode, we currently can +end up with a leaked greeter following user switching. +That can happen if a user with an already running session +is reauthenticated (so the login screen won't morph into the +use session). + +This commit makes sure we kill the greeter session off in that +case. +--- + daemon/gdm-manager.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 6ffb842..9201b9f 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -2010,6 +2010,26 @@ on_session_reauthenticated (GdmSession *session, + GdmManager *manager) + { + gboolean fail_if_already_switched = FALSE; ++ ++ if (gdm_session_get_display_mode (session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { ++ const char *seat_id; ++ char *session_id; ++ ++ seat_id = gdm_session_get_display_seat_id (session); ++ if (get_login_window_session_id (seat_id, &session_id)) { ++ GdmDisplay *display = gdm_display_store_find (manager->priv->display_store, ++ lookup_by_session_id, ++ (gpointer) session_id); ++ ++ if (display != NULL) { ++ gdm_display_stop_greeter_session (display); ++ gdm_display_unmanage (display); ++ gdm_display_finish (display); ++ } ++ } ++ g_free (session_id); ++ } ++ + /* There should already be a session running, so jump to its + * VT. In the event we're already on the right VT, (i.e. user + * used an unlock screen instead of a user switched login screen), +-- +1.8.3.1 + diff --git a/SOURCES/0003-launch-environment-fix-crasher-when-session-mode-isn.patch b/SOURCES/0003-launch-environment-fix-crasher-when-session-mode-isn.patch new file mode 100644 index 0000000..f9ce1d4 --- /dev/null +++ b/SOURCES/0003-launch-environment-fix-crasher-when-session-mode-isn.patch @@ -0,0 +1,94 @@ +From c29c4587ffc1ac7b923a2725a9f8fee0579124d1 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 27 Mar 2017 16:56:29 -0400 +Subject: [PATCH 03/13] launch-environment: fix crasher when session-mode isn't + set + +This commit fixes a crasher when starting the indirect chooser. +--- + daemon/gdm-launch-environment.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c +index a30276b4..4372ac29 100644 +--- a/daemon/gdm-launch-environment.c ++++ b/daemon/gdm-launch-environment.c +@@ -128,68 +128,69 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment, + "XDG_CONFIG_DIRS", NULL + }; + char *system_data_dirs; + int i; + + /* create a hash table of current environment, then update keys has necessary */ + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + for (i = 0; optional_environment[i] != NULL; i++) { + if (g_getenv (optional_environment[i]) == NULL) { + continue; + } + + g_hash_table_insert (hash, + g_strdup (optional_environment[i]), + g_strdup (g_getenv (optional_environment[i]))); + } + + system_data_dirs = g_strjoinv (":", (char **) g_get_system_data_dirs ()); + + g_hash_table_insert (hash, + g_strdup ("XDG_DATA_DIRS"), + g_strdup_printf ("%s:%s", + DATADIR "/gdm/greeter", + system_data_dirs)); + g_free (system_data_dirs); + + if (launch_environment->priv->x11_authority_file != NULL) + g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (launch_environment->priv->x11_authority_file)); + +- if (launch_environment->priv->session_mode != NULL) ++ if (launch_environment->priv->session_mode != NULL) { + g_hash_table_insert (hash, g_strdup ("GNOME_SHELL_SESSION_MODE"), g_strdup (launch_environment->priv->session_mode)); + +- /* Inital setup needs gvfs for fetching remote avatars. */ +- if (strcmp (launch_environment->priv->session_mode, INITIAL_SETUP_SESSION_MODE) != 0) { +- g_hash_table_insert (hash, g_strdup ("GVFS_DISABLE_FUSE"), g_strdup ("1")); +- g_hash_table_insert (hash, g_strdup ("GIO_USE_VFS"), g_strdup ("local")); +- g_hash_table_insert (hash, g_strdup ("GVFS_REMOTE_VOLUME_MONITOR_IGNORE"), g_strdup ("1")); ++ /* Inital setup needs gvfs for fetching remote avatars. */ ++ if (strcmp (launch_environment->priv->session_mode, INITIAL_SETUP_SESSION_MODE) != 0) { ++ g_hash_table_insert (hash, g_strdup ("GVFS_DISABLE_FUSE"), g_strdup ("1")); ++ g_hash_table_insert (hash, g_strdup ("GIO_USE_VFS"), g_strdup ("local")); ++ g_hash_table_insert (hash, g_strdup ("GVFS_REMOTE_VOLUME_MONITOR_IGNORE"), g_strdup ("1")); ++ } + } + + g_hash_table_insert (hash, g_strdup ("LOGNAME"), g_strdup (launch_environment->priv->user_name)); + g_hash_table_insert (hash, g_strdup ("USER"), g_strdup (launch_environment->priv->user_name)); + g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (launch_environment->priv->user_name)); + + g_hash_table_insert (hash, g_strdup ("GDM_VERSION"), g_strdup (VERSION)); + g_hash_table_remove (hash, "MAIL"); + + g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup ("/")); + g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup ("/")); + g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup ("/bin/sh")); + + gdm_get_pwent_for_name (launch_environment->priv->user_name, &pwent); + if (pwent != NULL) { + if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') { + g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup (pwent->pw_dir)); + g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup (pwent->pw_dir)); + } + + g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup (pwent->pw_shell)); + } + + if (start_session && launch_environment->priv->x11_display_seat_id != NULL) { + char *seat_id; + + seat_id = launch_environment->priv->x11_display_seat_id; + + g_hash_table_insert (hash, g_strdup ("GDM_SEAT_ID"), g_strdup (seat_id)); + } +-- +2.12.0 + diff --git a/SOURCES/0004-manager-drop-some-erroneous-code.patch b/SOURCES/0004-manager-drop-some-erroneous-code.patch new file mode 100644 index 0000000..f8cb492 --- /dev/null +++ b/SOURCES/0004-manager-drop-some-erroneous-code.patch @@ -0,0 +1,98 @@ +From 7eae5842599eca46e14d57641f6629c60fe7a354 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 31 Mar 2017 14:56:46 -0400 +Subject: [PATCH 04/13] manager: drop some erroneous code + +This is commit 82296a3350b64d0ed5ae3b9f6983466c60dd8a53 all over +again. The code snuck back in during a refactor ! +--- + daemon/gdm-manager.c | 18 ------------------ + 1 file changed, 18 deletions(-) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index e78228b4..3014dad3 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1903,79 +1903,61 @@ on_session_client_connected (GdmSession *session, + } + #endif + + g_object_get (G_OBJECT (display), "allow-timed-login", &allow_timed_login, NULL); + + if (!allow_timed_login) { + return; + } + + enabled = get_timed_login_details (manager, &username, &delay); + + if (! enabled) { + return; + } + + gdm_session_set_timed_login_details (session, username, delay); + + g_debug ("GdmManager: Starting automatic login conversation (for timed login)"); + gdm_session_start_conversation (session, "gdm-autologin"); + + g_free (username); + + } + + static void + on_session_client_disconnected (GdmSession *session, + GCredentials *credentials, + GPid pid_of_client, + GdmManager *manager) + { +- GdmDisplay *display; +- gboolean display_is_local; +- + g_debug ("GdmManager: client disconnected"); +- +- display = get_display_for_user_session (session); +- +- if (display == NULL) { +- return; +- } +- +- g_object_get (G_OBJECT (display), +- "is-local", &display_is_local, +- NULL); +- +- if ( ! display_is_local && gdm_session_is_running (session)) { +- gdm_display_unmanage (display); +- gdm_display_finish (display); +- } + } + + typedef struct + { + GdmManager *manager; + GdmSession *session; + guint idle_id; + } ResetSessionOperation; + + static void + destroy_reset_session_operation (ResetSessionOperation *operation) + { + g_object_set_data (G_OBJECT (operation->session), + "reset-session-operation", + NULL); + g_object_unref (operation->session); + g_slice_free (ResetSessionOperation, operation); + } + + static gboolean + on_reset_session (ResetSessionOperation *operation) + { + gdm_session_reset (operation->session); + + destroy_reset_session_operation (operation); + + return G_SOURCE_REMOVE; + } + + static void +-- +2.12.0 + diff --git a/SOURCES/0005-launch-environment-implement-hostname-selected-signa.patch b/SOURCES/0005-launch-environment-implement-hostname-selected-signa.patch new file mode 100644 index 0000000..ac4324e --- /dev/null +++ b/SOURCES/0005-launch-environment-implement-hostname-selected-signa.patch @@ -0,0 +1,356 @@ +From 239bc98692187ca42dca7cf1a19800415afcf6cf Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 31 Mar 2017 15:01:06 -0400 +Subject: [PATCH 05/13] launch-environment: implement hostname-selected signal + +We're connecting to a signal that isn't implemented. This +commit adds the implementation. + +A slightly better fix might be to cut out some of the layers, +of middle men passing around hostname-selected, but for now this +is fine. +--- + daemon/gdm-launch-environment.c | 27 +++++++++++++++++++++++++++ + daemon/gdm-launch-environment.h | 2 ++ + 2 files changed, 29 insertions(+) + +diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c +index 4372ac29..a7ae6728 100644 +--- a/daemon/gdm-launch-environment.c ++++ b/daemon/gdm-launch-environment.c +@@ -76,60 +76,61 @@ struct GdmLaunchEnvironmentPrivate + char *x11_display_name; + char *x11_display_seat_id; + char *x11_display_device; + char *x11_display_hostname; + char *x11_authority_file; + gboolean x11_display_is_local; + }; + + enum { + PROP_0, + PROP_VERIFICATION_MODE, + PROP_SESSION_TYPE, + PROP_SESSION_MODE, + PROP_X11_DISPLAY_NAME, + PROP_X11_DISPLAY_SEAT_ID, + PROP_X11_DISPLAY_DEVICE, + PROP_X11_DISPLAY_HOSTNAME, + PROP_X11_AUTHORITY_FILE, + PROP_X11_DISPLAY_IS_LOCAL, + PROP_USER_NAME, + PROP_RUNTIME_DIR, + PROP_COMMAND, + }; + + enum { + OPENED, + STARTED, + STOPPED, + EXITED, + DIED, ++ HOSTNAME_SELECTED, + LAST_SIGNAL + }; + + static guint signals [LAST_SIGNAL] = { 0, }; + + static void gdm_launch_environment_class_init (GdmLaunchEnvironmentClass *klass); + static void gdm_launch_environment_init (GdmLaunchEnvironment *launch_environment); + static void gdm_launch_environment_finalize (GObject *object); + + G_DEFINE_TYPE (GdmLaunchEnvironment, gdm_launch_environment, G_TYPE_OBJECT) + + static GHashTable * + build_launch_environment (GdmLaunchEnvironment *launch_environment, + gboolean start_session) + { + GHashTable *hash; + struct passwd *pwent; + static const char * const optional_environment[] = { + "LANG", "LANGUAGE", "LC_CTYPE", "LC_NUMERIC", "LC_TIME", + "LC_COLLATE", "LC_MONETARY", "LC_MESSAGES", "LC_PAPER", + "LC_NAME", "LC_ADDRESS", "LC_TELEPHONE", "LC_MEASUREMENT", + "LC_IDENTIFICATION", "LC_ALL", "WINDOWPATH", "XCURSOR_PATH", + "XDG_CONFIG_DIRS", NULL + }; + char *system_data_dirs; + int i; + + /* create a hash table of current environment, then update keys has necessary */ + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + +@@ -237,60 +238,69 @@ static void + on_session_started (GdmSession *session, + const char *service_name, + int pid, + GdmLaunchEnvironment *launch_environment) + { + launch_environment->priv->pid = pid; + g_signal_emit (G_OBJECT (launch_environment), signals [STARTED], 0); + } + + static void + on_session_exited (GdmSession *session, + int exit_code, + GdmLaunchEnvironment *launch_environment) + { + gdm_session_stop_conversation (launch_environment->priv->session, "gdm-launch-environment"); + + g_signal_emit (G_OBJECT (launch_environment), signals [EXITED], 0, exit_code); + } + + static void + on_session_died (GdmSession *session, + int signal_number, + GdmLaunchEnvironment *launch_environment) + { + gdm_session_stop_conversation (launch_environment->priv->session, "gdm-launch-environment"); + + g_signal_emit (G_OBJECT (launch_environment), signals [DIED], 0, signal_number); + } + + static void ++on_hostname_selected (GdmSession *session, ++ const char *hostname, ++ GdmLaunchEnvironment *launch_environment) ++{ ++ g_debug ("GdmSession: hostname selected: %s", hostname); ++ g_signal_emit (launch_environment, signals [HOSTNAME_SELECTED], 0, hostname); ++} ++ ++static void + on_conversation_started (GdmSession *session, + const char *service_name, + GdmLaunchEnvironment *launch_environment) + { + char *log_path; + char *log_file; + + log_file = g_strdup_printf ("%s-greeter.log", launch_environment->priv->x11_display_name); + log_path = g_build_filename (LOGDIR, log_file, NULL); + g_free (log_file); + + gdm_session_setup_for_program (launch_environment->priv->session, + "gdm-launch-environment", + launch_environment->priv->user_name, + log_path); + g_free (log_path); + } + + static void + on_conversation_stopped (GdmSession *session, + const char *service_name, + GdmLaunchEnvironment *launch_environment) + { + GdmSession *conversation_session; + + conversation_session = launch_environment->priv->session; + launch_environment->priv->session = NULL; + + g_debug ("GdmLaunchEnvironment: conversation stopped"); + +@@ -382,60 +392,65 @@ gdm_launch_environment_start (GdmLaunchEnvironment *launch_environment) + g_signal_connect_object (launch_environment->priv->session, + "conversation-stopped", + G_CALLBACK (on_conversation_stopped), + launch_environment, + 0); + g_signal_connect_object (launch_environment->priv->session, + "setup-complete", + G_CALLBACK (on_session_setup_complete), + launch_environment, + 0); + g_signal_connect_object (launch_environment->priv->session, + "session-opened", + G_CALLBACK (on_session_opened), + launch_environment, + 0); + g_signal_connect_object (launch_environment->priv->session, + "session-started", + G_CALLBACK (on_session_started), + launch_environment, + 0); + g_signal_connect_object (launch_environment->priv->session, + "session-exited", + G_CALLBACK (on_session_exited), + launch_environment, + 0); + g_signal_connect_object (launch_environment->priv->session, + "session-died", + G_CALLBACK (on_session_died), + launch_environment, + 0); ++ g_signal_connect_object (launch_environment->priv->session, ++ "hostname-selected", ++ G_CALLBACK (on_hostname_selected), ++ launch_environment, ++ 0); + + gdm_session_start_conversation (launch_environment->priv->session, "gdm-launch-environment"); + gdm_session_select_program (launch_environment->priv->session, launch_environment->priv->command); + + if (launch_environment->priv->session_type != NULL) { + g_object_set (G_OBJECT (launch_environment->priv->session), + "session-type", + launch_environment->priv->session_type, + NULL); + } + + res = TRUE; + out: + if (local_error) { + g_critical ("GdmLaunchEnvironment: %s", local_error->message); + g_clear_error (&local_error); + } + return res; + } + + gboolean + gdm_launch_environment_stop (GdmLaunchEnvironment *launch_environment) + { + if (launch_environment->priv->pid > 1) { + gdm_signal_pid (-launch_environment->priv->pid, SIGTERM); + } + + if (launch_environment->priv->session != NULL) { + gdm_session_close (launch_environment->priv->session); + +@@ -780,60 +795,72 @@ gdm_launch_environment_class_init (GdmLaunchEnvironmentClass *klass) + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GdmLaunchEnvironmentClass, stopped), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + signals [EXITED] = + g_signal_new ("exited", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GdmLaunchEnvironmentClass, exited), + NULL, + NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, + 1, + G_TYPE_INT); + signals [DIED] = + g_signal_new ("died", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GdmLaunchEnvironmentClass, died), + NULL, + NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, + 1, + G_TYPE_INT); ++ ++ signals [HOSTNAME_SELECTED] = ++ g_signal_new ("hostname-selected", ++ G_OBJECT_CLASS_TYPE (object_class), ++ G_SIGNAL_RUN_FIRST, ++ G_STRUCT_OFFSET (GdmLaunchEnvironmentClass, hostname_selected), ++ NULL, ++ NULL, ++ g_cclosure_marshal_VOID__STRING, ++ G_TYPE_NONE, ++ 1, ++ G_TYPE_STRING); + } + + static void + gdm_launch_environment_init (GdmLaunchEnvironment *launch_environment) + { + + launch_environment->priv = GDM_LAUNCH_ENVIRONMENT_GET_PRIVATE (launch_environment); + + launch_environment->priv->command = NULL; + launch_environment->priv->session = NULL; + } + + static void + gdm_launch_environment_finalize (GObject *object) + { + GdmLaunchEnvironment *launch_environment; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_LAUNCH_ENVIRONMENT (object)); + + launch_environment = GDM_LAUNCH_ENVIRONMENT (object); + + g_return_if_fail (launch_environment->priv != NULL); + + gdm_launch_environment_stop (launch_environment); + + if (launch_environment->priv->session) { + g_object_unref (launch_environment->priv->session); + } + +diff --git a/daemon/gdm-launch-environment.h b/daemon/gdm-launch-environment.h +index 3fd875c2..c2a09d1c 100644 +--- a/daemon/gdm-launch-environment.h ++++ b/daemon/gdm-launch-environment.h +@@ -32,55 +32,57 @@ G_BEGIN_DECLS + #define GDM_LAUNCH_ENVIRONMENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_LAUNCH_ENVIRONMENT, GdmLaunchEnvironmentClass)) + #define GDM_IS_LAUNCH_ENVIRONMENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_LAUNCH_ENVIRONMENT)) + #define GDM_IS_LAUNCH_ENVIRONMENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_LAUNCH_ENVIRONMENT)) + #define GDM_LAUNCH_ENVIRONMENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_LAUNCH_ENVIRONMENT, GdmLaunchEnvironmentClass)) + + typedef struct GdmLaunchEnvironmentPrivate GdmLaunchEnvironmentPrivate; + + typedef struct + { + GObject parent; + GdmLaunchEnvironmentPrivate *priv; + } GdmLaunchEnvironment; + + typedef struct + { + GObjectClass parent_class; + + /* methods */ + gboolean (*start) (GdmLaunchEnvironment *launch_environment); + gboolean (*stop) (GdmLaunchEnvironment *launch_environment); + + + /* signals */ + void (* opened) (GdmLaunchEnvironment *launch_environment); + void (* started) (GdmLaunchEnvironment *launch_environment); + void (* stopped) (GdmLaunchEnvironment *launch_environment); + void (* exited) (GdmLaunchEnvironment *launch_environment, + int exit_code); + void (* died) (GdmLaunchEnvironment *launch_environment, + int signal_number); ++ void (* hostname_selected) (GdmLaunchEnvironment *launch_environment, ++ const char *hostname); + } GdmLaunchEnvironmentClass; + + GType gdm_launch_environment_get_type (void); + + gboolean gdm_launch_environment_start (GdmLaunchEnvironment *launch_environment); + gboolean gdm_launch_environment_stop (GdmLaunchEnvironment *launch_environment); + GdmSession * gdm_launch_environment_get_session (GdmLaunchEnvironment *launch_environment); + char * gdm_launch_environment_get_session_id (GdmLaunchEnvironment *launch_environment); + + GdmLaunchEnvironment *gdm_create_greeter_launch_environment (const char *display_name, + const char *seat_id, + const char *session_type, + const char *display_hostname, + gboolean display_is_local); + GdmLaunchEnvironment *gdm_create_initial_setup_launch_environment (const char *display_name, + const char *seat_id, + const char *display_hostname, + gboolean display_is_local); + GdmLaunchEnvironment *gdm_create_chooser_launch_environment (const char *display_name, + const char *seat_id, + const char *display_hostname); + + G_END_DECLS + + #endif /* __GDM_LAUNCH_ENVIRONMENT_H */ +-- +2.12.0 + diff --git a/SOURCES/0006-manager-fix-up-support-for-chooser.patch b/SOURCES/0006-manager-fix-up-support-for-chooser.patch new file mode 100644 index 0000000..c68bf23 --- /dev/null +++ b/SOURCES/0006-manager-fix-up-support-for-chooser.patch @@ -0,0 +1,355 @@ +From 60a03333bec4f7904a2cfddb291d22ce493e1ced Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 31 Mar 2017 14:54:44 -0400 +Subject: [PATCH 06/13] manager: fix up support for chooser + +We were missing some chunks of code to handle dealing with +the chooser. + +This commit adds in the necessary bits to start the chooser, +and deal with the choice. +--- + daemon/gdm-manager.c | 62 ++++++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 53 insertions(+), 9 deletions(-) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 3014dad3..373778d9 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -18,67 +18,69 @@ + * + */ + + #include "config.h" + + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + + #include + + #include + + #include "gdm-common.h" + + #include "gdm-dbus-util.h" + #include "gdm-manager.h" + #include "gdm-manager-glue.h" + #include "gdm-display-store.h" + #include "gdm-display-factory.h" ++#include "gdm-launch-environment.h" + #include "gdm-local-display.h" + #include "gdm-local-display-factory.h" + #include "gdm-session.h" + #include "gdm-session-record.h" + #include "gdm-settings-direct.h" + #include "gdm-settings-keys.h" + #include "gdm-xdmcp-display-factory.h" ++#include "gdm-xdmcp-chooser-display.h" + + #define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate)) + + #define GDM_DBUS_PATH "/org/gnome/DisplayManager" + #define GDM_MANAGER_PATH GDM_DBUS_PATH "/Manager" + #define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays" + + #define INITIAL_SETUP_USERNAME "gnome-initial-setup" + + typedef struct + { + GdmManager *manager; + GdmSession *session; + char *service_name; + guint idle_id; + } StartUserSessionOperation; + + struct GdmManagerPrivate + { + GdmDisplayStore *display_store; + GdmLocalDisplayFactory *local_factory; + #ifdef HAVE_LIBXDMCP + GdmXdmcpDisplayFactory *xdmcp_factory; + #endif + GList *user_sessions; + GHashTable *transient_sessions; + GHashTable *open_reauthentication_requests; + gboolean xdmcp_enabled; + GCancellable *cancellable; + +@@ -793,89 +795,107 @@ gdm_manager_handle_register_display (GdmDBusManager *manager, + /* FIXME: this should happen in gdm-session.c when the session is opened + */ + if (tty != NULL) + g_object_set (G_OBJECT (session), "display-device", tty, NULL); + + pid = gdm_session_get_pid (session); + + if (pid > 0) { + add_session_record (self, session, pid, SESSION_RECORD_LOGIN); + } + } + + g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL); + + gdm_dbus_manager_complete_register_display (GDM_DBUS_MANAGER (manager), + invocation); + + g_clear_pointer (&x11_display_name, g_free); + g_clear_pointer (&tty, g_free); + return TRUE; + } + + static gboolean + gdm_manager_handle_open_session (GdmDBusManager *manager, + GDBusMethodInvocation *invocation) + { + GdmManager *self = GDM_MANAGER (manager); + const char *sender; + GDBusConnection *connection; + GdmDisplay *display = NULL; +- GdmSession *session; ++ GdmSession *session = NULL; + const char *address; + GPid pid = 0; + uid_t uid = (uid_t) -1; + uid_t allowed_user; + + g_debug ("GdmManager: trying to open new session"); + + sender = g_dbus_method_invocation_get_sender (invocation); + connection = g_dbus_method_invocation_get_connection (invocation); + get_display_and_details_for_bus_sender (self, connection, sender, &display, NULL, NULL, NULL, &pid, &uid, NULL, NULL); + + if (display == NULL) { + g_dbus_method_invocation_return_error_literal (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + _("No session available")); + + return TRUE; + } + +- session = get_embryonic_user_session_for_display (display); ++ if (GDM_IS_XDMCP_CHOOSER_DISPLAY (display)) { ++ GdmLaunchEnvironment *launch_environment; + +- if (gdm_session_is_running (session)) { +- g_dbus_method_invocation_return_error_literal (invocation, +- G_DBUS_ERROR, +- G_DBUS_ERROR_ACCESS_DENIED, +- _("Can only be called before user is logged in")); +- return TRUE; ++ g_object_get (display, "launch-environment", &launch_environment, NULL); ++ ++ if (launch_environment != NULL) { ++ session = gdm_launch_environment_get_session (launch_environment); ++ } ++ ++ if (session == NULL) { ++ g_dbus_method_invocation_return_error_literal (invocation, ++ G_DBUS_ERROR, ++ G_DBUS_ERROR_ACCESS_DENIED, ++ _("Chooser session unavailable")); ++ return TRUE; ++ } ++ } else { ++ session = get_embryonic_user_session_for_display (display); ++ ++ if (gdm_session_is_running (session)) { ++ g_dbus_method_invocation_return_error_literal (invocation, ++ G_DBUS_ERROR, ++ G_DBUS_ERROR_ACCESS_DENIED, ++ _("Can only be called before user is logged in")); ++ return TRUE; ++ } + } + + allowed_user = gdm_session_get_allowed_user (session); + + if (uid != allowed_user) { + g_dbus_method_invocation_return_error_literal (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + _("Caller not GDM")); + return TRUE; + } + + address = gdm_session_get_server_address (session); + + if (address == NULL) { + g_dbus_method_invocation_return_error_literal (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + _("Unable to open private communication channel")); + return TRUE; + } + + gdm_dbus_manager_complete_open_session (GDM_DBUS_MANAGER (manager), + invocation, + address); + return TRUE; + } + + static void + close_transient_session (GdmManager *self, +@@ -1309,60 +1329,80 @@ get_username_for_greeter_display (GdmManager *manager, + } + } + + static void + set_up_automatic_login_session (GdmManager *manager, + GdmDisplay *display) + { + GdmSession *session; + char *display_session_type = NULL; + gboolean is_initial; + + /* 0 is root user; since the daemon talks to the session object + * directly, itself, for automatic login + */ + session = create_embryonic_user_session_for_display (manager, display, 0); + + g_object_get (G_OBJECT (display), + "is-initial", &is_initial, + "session-type", &display_session_type, + NULL); + + g_object_set (G_OBJECT (session), + "display-is-initial", is_initial, + NULL); + + g_debug ("GdmManager: Starting automatic login conversation"); + gdm_session_start_conversation (session, "gdm-autologin"); + } + + static void ++set_up_chooser_session (GdmManager *manager, ++ GdmDisplay *display) ++{ ++ const char *allowed_user; ++ struct passwd *passwd_entry; ++ ++ allowed_user = get_username_for_greeter_display (manager, display); ++ ++ if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) { ++ g_warning ("GdmManager: couldn't look up username %s", ++ allowed_user); ++ gdm_display_unmanage (display); ++ gdm_display_finish (display); ++ return; ++ } ++ ++ gdm_display_start_greeter_session (display); ++} ++ ++static void + set_up_greeter_session (GdmManager *manager, + GdmDisplay *display) + { + const char *allowed_user; + struct passwd *passwd_entry; + + allowed_user = get_username_for_greeter_display (manager, display); + + if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) { + g_warning ("GdmManager: couldn't look up username %s", + allowed_user); + gdm_display_unmanage (display); + gdm_display_finish (display); + return; + } + + create_embryonic_user_session_for_display (manager, display, passwd_entry->pw_uid); + gdm_display_start_greeter_session (display); + } + + static void + set_up_automatic_login_session_if_user_exists (GdmManager *manager, + GdmDisplay *display, + ActUser *user) + { + if (act_user_is_nonexistent (user)) + set_up_greeter_session (manager, display); + else + set_up_automatic_login_session (manager, display); + } +@@ -1383,61 +1423,65 @@ destroy_username_lookup_operation (UsernameLookupOperation *operation) + } + + static void + on_user_is_loaded_changed (ActUser *user, + GParamSpec *pspec, + UsernameLookupOperation *operation) + { + if (act_user_is_loaded (user)) { + set_up_automatic_login_session_if_user_exists (operation->manager, operation->display, user); + g_signal_handlers_disconnect_by_func (G_OBJECT (user), + G_CALLBACK (on_user_is_loaded_changed), + operation); + destroy_username_lookup_operation (operation); + } + } + + static void + set_up_session (GdmManager *manager, + GdmDisplay *display) + { + ActUserManager *user_manager; + ActUser *user; + gboolean loaded; + gboolean autologin_enabled = FALSE; + char *username = NULL; + + if (!manager->priv->ran_once && display_is_on_seat0 (display)) + autologin_enabled = get_automatic_login_details (manager, &username); + + if (!autologin_enabled) { +- set_up_greeter_session (manager, display); ++ if (GDM_IS_XDMCP_CHOOSER_DISPLAY (display)) { ++ set_up_chooser_session (manager, display); ++ } else { ++ set_up_greeter_session (manager, display); ++ } + g_free (username); + return; + } + + /* Check whether the user really exists before committing to autologin. */ + user_manager = act_user_manager_get_default (); + user = act_user_manager_get_user (user_manager, username); + g_object_get (user_manager, "is-loaded", &loaded, NULL); + + if (loaded) { + set_up_automatic_login_session_if_user_exists (manager, display, user); + } else { + UsernameLookupOperation *operation; + + operation = g_new (UsernameLookupOperation, 1); + operation->manager = g_object_ref (manager); + operation->display = g_object_ref (display); + operation->username = username; + + g_signal_connect (user, + "notify::is-loaded", + G_CALLBACK (on_user_is_loaded_changed), + operation); + } + } + + static void + greeter_display_started (GdmManager *manager, + GdmDisplay *display) + { +-- +2.12.0 + diff --git a/SOURCES/0007-xdmcp-display-don-t-set-MANAGED-until-we-ve-connecte.patch b/SOURCES/0007-xdmcp-display-don-t-set-MANAGED-until-we-ve-connecte.patch new file mode 100644 index 0000000..c12e90b --- /dev/null +++ b/SOURCES/0007-xdmcp-display-don-t-set-MANAGED-until-we-ve-connecte.patch @@ -0,0 +1,104 @@ +From 9367cdcb777cabacc5cb436155e4ab7c32dc74ef Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 31 Mar 2017 14:52:23 -0400 +Subject: [PATCH 07/13] xdmcp-display: don't set MANAGED until we've connected + +We don't want to start the greeter session until we've +successfully connected to the display ourselves! + +This prevents a race where session processes may inadvertently + get the initial connection to the display server, causing +premature resets. +--- + daemon/gdm-xdmcp-display.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/daemon/gdm-xdmcp-display.c b/daemon/gdm-xdmcp-display.c +index c9f9c3d2..630844f2 100644 +--- a/daemon/gdm-xdmcp-display.c ++++ b/daemon/gdm-xdmcp-display.c +@@ -166,80 +166,79 @@ gdm_xdmcp_display_prepare (GdmDisplay *display) + NULL); + + if (launch_environment == NULL) { + launch_environment = gdm_create_greeter_launch_environment (display_name, + seat_id, + NULL, + hostname, + FALSE); + g_object_set (self, "launch-environment", launch_environment, NULL); + g_object_unref (launch_environment); + } + + if (!gdm_display_create_authority (display)) { + g_warning ("Unable to set up access control for display %s", + display_name); + return FALSE; + } + + return GDM_DISPLAY_CLASS (gdm_xdmcp_display_parent_class)->prepare (display); + } + + static gboolean + idle_connect_to_display (GdmXdmcpDisplay *self) + { + gboolean res; + + self->priv->connection_attempts++; + + res = gdm_display_connect (GDM_DISPLAY (self)); + if (res) { ++ g_object_set (G_OBJECT (self), "status", GDM_DISPLAY_MANAGED, NULL); + } else { + if (self->priv->connection_attempts >= MAX_CONNECT_ATTEMPTS) { + g_warning ("Unable to connect to display after %d tries - bailing out", self->priv->connection_attempts); + gdm_display_unmanage (GDM_DISPLAY (self)); + return FALSE; + } + return TRUE; + } + + return FALSE; + } + + static void + gdm_xdmcp_display_manage (GdmDisplay *display) + { + GdmXdmcpDisplay *self = GDM_XDMCP_DISPLAY (display); + + g_timeout_add (500, (GSourceFunc)idle_connect_to_display, self); +- +- g_object_set (G_OBJECT (self), "status", GDM_DISPLAY_MANAGED, NULL); + } + + static void + gdm_xdmcp_display_class_init (GdmXdmcpDisplayClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdmDisplayClass *display_class = GDM_DISPLAY_CLASS (klass); + + object_class->get_property = gdm_xdmcp_display_get_property; + object_class->set_property = gdm_xdmcp_display_set_property; + + display_class->prepare = gdm_xdmcp_display_prepare; + display_class->manage = gdm_xdmcp_display_manage; + + g_type_class_add_private (klass, sizeof (GdmXdmcpDisplayPrivate)); + + g_object_class_install_property (object_class, + PROP_REMOTE_ADDRESS, + g_param_spec_boxed ("remote-address", + "Remote address", + "Remote address", + GDM_TYPE_ADDRESS, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_SESSION_NUMBER, + g_param_spec_int ("session-number", + "session-number", + "session-number", + G_MININT, +-- +2.12.0 + diff --git a/SOURCES/0008-xdmcp-display-factory-fix-signal-prototype.patch b/SOURCES/0008-xdmcp-display-factory-fix-signal-prototype.patch new file mode 100644 index 0000000..8afb79b --- /dev/null +++ b/SOURCES/0008-xdmcp-display-factory-fix-signal-prototype.patch @@ -0,0 +1,82 @@ +From af841691f3e48ff7635df21703115c5b109ba9dc Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 31 Mar 2017 14:58:26 -0400 +Subject: [PATCH 08/13] xdmcp-display-factory: fix signal prototype + +The callback was getting called with the wrong arguments leading +to spew in the logs and necessary code not getting run! +--- + daemon/gdm-xdmcp-display-factory.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c +index b9ab921c..c5f7ddb4 100644 +--- a/daemon/gdm-xdmcp-display-factory.c ++++ b/daemon/gdm-xdmcp-display-factory.c +@@ -2023,61 +2023,62 @@ on_hostname_selected (GdmXdmcpChooserDisplay *display, + #ifdef AI_V4MAPPED + hints.ai_flags = AI_V4MAPPED; + #endif + + xdmcp_port = g_strdup_printf ("%d", XDM_UDP_PORT); + if ((gaierr = getaddrinfo (hostname, xdmcp_port, &hints, &ai_list)) != 0) { + g_warning ("Unable to get address: %s", gai_strerror (gaierr)); + g_free (xdmcp_port); + return; + } + g_free (xdmcp_port); + + /* just take the first one */ + ai = ai_list; + + if (ai != NULL) { + char *ip; + ic->chosen_address = gdm_address_new_from_sockaddr (ai->ai_addr, ai->ai_addrlen); + + ip = NULL; + gdm_address_get_numeric_info (ic->chosen_address, &ip, NULL); + g_debug ("GdmXdmcpDisplayFactory: hostname resolves to %s", + ip ? ip : "(null)"); + g_free (ip); + } + + freeaddrinfo (ai_list); + } + + static void +-on_client_disconnected (GdmDisplay *display) ++on_client_disconnected (GdmSession *session, ++ GdmDisplay *display) + { + if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) + return; + + gdm_display_unmanage (display); + gdm_display_finish (display); + } + + static void + on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmXdmcpDisplayFactory *factory) + { + int status; + GdmDisplayStore *store; + GdmLaunchEnvironment *launch_environment; + GdmSession *session; + GdmAddress *address; + gint32 session_number; + int display_number; + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + + launch_environment = NULL; + g_object_get (display, "launch-environment", &launch_environment, NULL); + + session = NULL; + if (launch_environment != NULL) { + session = gdm_launch_environment_get_session (launch_environment); + } +-- +2.12.0 + diff --git a/SOURCES/0009-xdmcp-display-factory-explicitly-stop-greeter-sessio.patch b/SOURCES/0009-xdmcp-display-factory-explicitly-stop-greeter-sessio.patch new file mode 100644 index 0000000..ee65a9e --- /dev/null +++ b/SOURCES/0009-xdmcp-display-factory-explicitly-stop-greeter-sessio.patch @@ -0,0 +1,80 @@ +From 1dc72abeb4419027f649d67fd95b302c8233335d Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 31 Mar 2017 14:59:05 -0400 +Subject: [PATCH 09/13] xdmcp-display-factory: explicitly stop greeter session + on disconnect + +If the client disconnects, we should kill off the necessary processes. +--- + daemon/gdm-xdmcp-display-factory.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c +index c5f7ddb4..3a8506ce 100644 +--- a/daemon/gdm-xdmcp-display-factory.c ++++ b/daemon/gdm-xdmcp-display-factory.c +@@ -2029,60 +2029,61 @@ on_hostname_selected (GdmXdmcpChooserDisplay *display, + g_warning ("Unable to get address: %s", gai_strerror (gaierr)); + g_free (xdmcp_port); + return; + } + g_free (xdmcp_port); + + /* just take the first one */ + ai = ai_list; + + if (ai != NULL) { + char *ip; + ic->chosen_address = gdm_address_new_from_sockaddr (ai->ai_addr, ai->ai_addrlen); + + ip = NULL; + gdm_address_get_numeric_info (ic->chosen_address, &ip, NULL); + g_debug ("GdmXdmcpDisplayFactory: hostname resolves to %s", + ip ? ip : "(null)"); + g_free (ip); + } + + freeaddrinfo (ai_list); + } + + static void + on_client_disconnected (GdmSession *session, + GdmDisplay *display) + { + if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) + return; + ++ gdm_display_stop_greeter_session (display); + gdm_display_unmanage (display); + gdm_display_finish (display); + } + + static void + on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmXdmcpDisplayFactory *factory) + { + int status; + GdmDisplayStore *store; + GdmLaunchEnvironment *launch_environment; + GdmSession *session; + GdmAddress *address; + gint32 session_number; + int display_number; + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + + launch_environment = NULL; + g_object_get (display, "launch-environment", &launch_environment, NULL); + + session = NULL; + if (launch_environment != NULL) { + session = gdm_launch_environment_get_session (launch_environment); + } + + status = gdm_display_get_status (display); + + g_debug ("GdmXdmcpDisplayFactory: xdmcp display status changed: %d", status); +-- +2.12.0 + diff --git a/SOURCES/0010-chooser-fix-duplicate-entry-in-the-list.patch b/SOURCES/0010-chooser-fix-duplicate-entry-in-the-list.patch new file mode 100644 index 0000000..7d4d0f9 --- /dev/null +++ b/SOURCES/0010-chooser-fix-duplicate-entry-in-the-list.patch @@ -0,0 +1,80 @@ +From e3530d3ee97df1f78c15172abb0511ce12f1175b Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 31 Mar 2017 15:11:03 -0400 +Subject: [PATCH 10/13] chooser: fix duplicate entry in the list + +--- + chooser/gdm-host-chooser-widget.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/chooser/gdm-host-chooser-widget.c b/chooser/gdm-host-chooser-widget.c +index f9200aa0..b8924618 100644 +--- a/chooser/gdm-host-chooser-widget.c ++++ b/chooser/gdm-host-chooser-widget.c +@@ -246,62 +246,62 @@ decode_packet (GIOChannel *source, + } + + if (! XdmcpReadARRAY8 (&buf, &stat)) { + goto done; + } + + status = g_strndup ((char *) stat.data, MIN (stat.length, 256)); + } else if (header.opcode == UNWILLING) { + /* immaterial, will not be shown */ + status = NULL; + } else { + goto done; + } + + g_debug ("STATUS: %s", status); + + chooser_host = find_known_host (widget, address); + if (chooser_host == NULL) { + chooser_host = g_object_new (GDM_TYPE_CHOOSER_HOST, + "address", address, + "description", status, + "willing", (header.opcode == WILLING), + "kind", GDM_CHOOSER_HOST_KIND_XDMCP, + NULL); + chooser_host_add (widget, chooser_host); + browser_add_host (widget, chooser_host); + } else { + /* server changed it's mind */ + if (header.opcode == WILLING + && ! gdm_chooser_host_get_willing (chooser_host)) { +- g_object_set (chooser_host, "willing", TRUE, NULL); + browser_add_host (widget, chooser_host); ++ g_object_set (chooser_host, "willing", TRUE, NULL); + } + /* FIXME: handle unwilling? */ + } + + done: + if (header.opcode == WILLING) { + XdmcpDisposeARRAY8 (&auth); + XdmcpDisposeARRAY8 (&host); + XdmcpDisposeARRAY8 (&stat); + } + + g_free (status); + gdm_address_free (address); + + return TRUE; + } + + static void + do_ping (GdmHostChooserWidget *widget, + gboolean full) + { + GSList *l; + + g_debug ("do ping full:%d", full); + + for (l = widget->priv->broadcast_addresses; l != NULL; l = l->next) { + GdmAddress *address; + int res; + + address = l->data; +-- +2.12.0 + diff --git a/SOURCES/0011-chooser-make-host-list-fill-the-dialog.patch b/SOURCES/0011-chooser-make-host-list-fill-the-dialog.patch new file mode 100644 index 0000000..4c53b85 --- /dev/null +++ b/SOURCES/0011-chooser-make-host-list-fill-the-dialog.patch @@ -0,0 +1,79 @@ +From c77f0cd06eb26716ba03c79a4a47c76e334faec4 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 31 Mar 2017 15:21:45 -0400 +Subject: [PATCH 11/13] chooser: make host list fill the dialog + +--- + chooser/gdm-host-chooser-dialog.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/chooser/gdm-host-chooser-dialog.c b/chooser/gdm-host-chooser-dialog.c +index 02169502..b9581a34 100644 +--- a/chooser/gdm-host-chooser-dialog.c ++++ b/chooser/gdm-host-chooser-dialog.c +@@ -106,61 +106,61 @@ gdm_host_chooser_dialog_get_property (GObject *object, + } + } + + static void + on_response (GdmHostChooserDialog *dialog, + gint response_id) + { + switch (response_id) { + case GTK_RESPONSE_APPLY: + gdm_host_chooser_widget_refresh (GDM_HOST_CHOOSER_WIDGET (dialog->priv->chooser_widget)); + g_signal_stop_emission_by_name (dialog, "response"); + break; + default: + break; + } + } + + static GObject * + gdm_host_chooser_dialog_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) + { + GdmHostChooserDialog *dialog; + + dialog = GDM_HOST_CHOOSER_DIALOG (G_OBJECT_CLASS (gdm_host_chooser_dialog_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + + dialog->priv->chooser_widget = gdm_host_chooser_widget_new (dialog->priv->kind_mask); +- gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), dialog->priv->chooser_widget); ++ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), dialog->priv->chooser_widget, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (dialog->priv->chooser_widget), 5); + + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_REFRESH, GTK_RESPONSE_APPLY, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_CONNECT, GTK_RESPONSE_OK, + NULL); + + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 12); + gtk_window_set_title (GTK_WINDOW (dialog), _("Select System")); + gtk_window_set_icon_name (GTK_WINDOW (dialog), "computer"); + + g_signal_connect (dialog, + "response", + G_CALLBACK (on_response), + dialog); + + gtk_widget_show_all (GTK_WIDGET (dialog)); + + return G_OBJECT (dialog); + } + + static void + gdm_host_chooser_dialog_dispose (GObject *object) + { + g_debug ("Disposing host_chooser_dialog"); + + G_OBJECT_CLASS (gdm_host_chooser_dialog_parent_class)->dispose (object); + } +-- +2.12.0 + diff --git a/SOURCES/0012-chooser-switch-to-browse-selection-mode.patch b/SOURCES/0012-chooser-switch-to-browse-selection-mode.patch new file mode 100644 index 0000000..9fac97b --- /dev/null +++ b/SOURCES/0012-chooser-switch-to-browse-selection-mode.patch @@ -0,0 +1,178 @@ +From bead5672f65d9a579143de16a7c72e701a346cce Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 31 Mar 2017 15:22:06 -0400 +Subject: [PATCH 12/13] chooser: switch to browse selection mode + +The chooser is a host browser after all. It makes not sense to +have an unselected item. +--- + chooser/gdm-host-chooser-widget.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/chooser/gdm-host-chooser-widget.c b/chooser/gdm-host-chooser-widget.c +index b8924618..f8aabf3e 100644 +--- a/chooser/gdm-host-chooser-widget.c ++++ b/chooser/gdm-host-chooser-widget.c +@@ -124,89 +124,96 @@ find_known_host (GdmHostChooserWidget *widget, + GdmAddress *address) + { + GSList *li; + GdmChooserHost *host; + + for (li = widget->priv->chooser_hosts; li != NULL; li = li->next) { + host = li->data; + if (gdm_address_equal (gdm_chooser_host_get_address (host), address)) { + goto out; + } + } + + host = NULL; + out: + + return host; + } + + static void + browser_add_host (GdmHostChooserWidget *widget, + GdmChooserHost *host) + { + char *hostname; + char *name; + char *desc; + char *label; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean res; + ++ GtkTreeSelection *selection; ++ + g_assert (host != NULL); + + if (! gdm_chooser_host_get_willing (host)) { + gtk_widget_set_sensitive (GTK_WIDGET (widget), TRUE); + return; + } + + res = gdm_address_get_hostname (gdm_chooser_host_get_address (host), &hostname); + if (! res) { + gdm_address_get_numeric_info (gdm_chooser_host_get_address (host), &hostname, NULL); + } + + name = g_markup_escape_text (hostname, -1); + desc = g_markup_escape_text (gdm_chooser_host_get_description (host), -1); + label = g_strdup_printf ("%s\n%s", name, desc); + g_free (name); + g_free (desc); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget->priv->treeview)); + + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + gtk_list_store_set (GTK_LIST_STORE (model), + &iter, + CHOOSER_LIST_ICON_COLUMN, NULL, + CHOOSER_LIST_LABEL_COLUMN, label, + CHOOSER_LIST_HOST_COLUMN, host, + -1); + g_free (label); + ++ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget->priv->treeview)); ++ if (!gtk_tree_selection_get_selected (selection, NULL, NULL)) { ++ gtk_tree_selection_select_iter (selection, &iter); ++ } ++ + } + + static gboolean + decode_packet (GIOChannel *source, + GIOCondition condition, + GdmHostChooserWidget *widget) + { + struct sockaddr_storage clnt_ss; + GdmAddress *address; + int ss_len; + XdmcpHeader header; + int res; + static XdmcpBuffer buf; + ARRAY8 auth = {0}; + ARRAY8 host = {0}; + ARRAY8 stat = {0}; + char *status; + GdmChooserHost *chooser_host; + + status = NULL; + address = NULL; + + g_debug ("decode_packet: GIOCondition %d", (int)condition); + + if ( ! (condition & G_IO_IN)) { + return TRUE; + } + + ss_len = (int) sizeof (clnt_ss); + +@@ -777,61 +784,61 @@ on_row_activated (GtkTreeView *tree_view, + { + g_signal_emit (widget, signals[HOST_ACTIVATED], 0); + } + + static void + gdm_host_chooser_widget_init (GdmHostChooserWidget *widget) + { + GtkWidget *scrolled; + GtkTreeSelection *selection; + GtkTreeViewColumn *column; + GtkTreeModel *model; + + widget->priv = GDM_HOST_CHOOSER_WIDGET_GET_PRIVATE (widget); + + scrolled = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (widget), scrolled, TRUE, TRUE, 0); + + widget->priv->treeview = gtk_tree_view_new (); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget->priv->treeview), FALSE); + g_signal_connect (widget->priv->treeview, + "row-activated", + G_CALLBACK (on_row_activated), + widget); + gtk_container_add (GTK_CONTAINER (scrolled), widget->priv->treeview); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget->priv->treeview)); +- gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); ++ gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + g_signal_connect (selection, "changed", + G_CALLBACK (on_host_selected), + widget); + + model = (GtkTreeModel *)gtk_list_store_new (3, + GDK_TYPE_PIXBUF, + G_TYPE_STRING, + G_TYPE_POINTER); + gtk_tree_view_set_model (GTK_TREE_VIEW (widget->priv->treeview), model); + + column = gtk_tree_view_column_new_with_attributes ("Icon", + gtk_cell_renderer_pixbuf_new (), + "pixbuf", CHOOSER_LIST_ICON_COLUMN, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (widget->priv->treeview), column); + + column = gtk_tree_view_column_new_with_attributes ("Hostname", + gtk_cell_renderer_text_new (), + "markup", CHOOSER_LIST_LABEL_COLUMN, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (widget->priv->treeview), column); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), + CHOOSER_LIST_LABEL_COLUMN, + GTK_SORT_ASCENDING); + } + + static void + gdm_host_chooser_widget_finalize (GObject *object) + { +-- +2.12.0 + diff --git a/SOURCES/0013-chooser-filter-out-duplicate-hostnames.patch b/SOURCES/0013-chooser-filter-out-duplicate-hostnames.patch new file mode 100644 index 0000000..c0abd1e --- /dev/null +++ b/SOURCES/0013-chooser-filter-out-duplicate-hostnames.patch @@ -0,0 +1,125 @@ +From d32365ddb729e94f7ebf650ef526f7f5319dfe4c Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 31 Mar 2017 15:40:21 -0400 +Subject: [PATCH 13/13] chooser: filter out duplicate hostnames + +One host may report itself on multiple interfaces. +GDM only supports based on hostname not interface, +so that leads duplicate entries in the list. + +This commit filters out the dupes. +--- + chooser/gdm-host-chooser-widget.c | 34 +++++++++++++++++++++++++++++++++- + 1 file changed, 33 insertions(+), 1 deletion(-) + +diff --git a/chooser/gdm-host-chooser-widget.c b/chooser/gdm-host-chooser-widget.c +index f8aabf3e..e2507900 100644 +--- a/chooser/gdm-host-chooser-widget.c ++++ b/chooser/gdm-host-chooser-widget.c +@@ -92,70 +92,102 @@ static void gdm_host_chooser_widget_finalize (GObject * + + G_DEFINE_TYPE (GdmHostChooserWidget, gdm_host_chooser_widget, GTK_TYPE_VBOX) + + #define GDM_XDMCP_PROTOCOL_VERSION 1001 + #define SCAN_TIMEOUT 30 + #define PING_TIMEOUT 2 + #define PING_TRIES 3 + + enum { + CHOOSER_LIST_ICON_COLUMN = 0, + CHOOSER_LIST_LABEL_COLUMN, + CHOOSER_LIST_HOST_COLUMN + }; + + static void + chooser_host_add (GdmHostChooserWidget *widget, + GdmChooserHost *host) + { + widget->priv->chooser_hosts = g_slist_prepend (widget->priv->chooser_hosts, host); + } + + #if 0 + static void + chooser_host_remove (GdmHostChooserWidget *widget, + GdmChooserHost *host) + { + widget->priv->chooser_hosts = g_slist_remove (widget->priv->chooser_hosts, host); + } + #endif + ++static gboolean ++address_hostnames_equal (GdmAddress *address, ++ GdmAddress *other_address) ++{ ++ char *hostname, *other_hostname; ++ gboolean are_equal; ++ ++ if (gdm_address_equal (address, other_address)) { ++ return TRUE; ++ } ++ ++ if (!gdm_address_get_hostname (address, &hostname)) { ++ gdm_address_get_numeric_info (address, &hostname, NULL); ++ } ++ ++ if (!gdm_address_get_hostname (other_address, &other_hostname)) { ++ gdm_address_get_numeric_info (other_address, &other_hostname, NULL); ++ } ++ ++ are_equal = g_strcmp0 (hostname, other_hostname) == 0; ++ ++ g_free (hostname); ++ g_free (other_hostname); ++ ++ return are_equal; ++} ++ + static GdmChooserHost * + find_known_host (GdmHostChooserWidget *widget, + GdmAddress *address) + { + GSList *li; + GdmChooserHost *host; + + for (li = widget->priv->chooser_hosts; li != NULL; li = li->next) { ++ GdmAddress *other_address; ++ + host = li->data; +- if (gdm_address_equal (gdm_chooser_host_get_address (host), address)) { ++ ++ other_address = gdm_chooser_host_get_address (host); ++ ++ if (address_hostnames_equal (address, other_address)) { + goto out; + } + } + + host = NULL; + out: + + return host; + } + + static void + browser_add_host (GdmHostChooserWidget *widget, + GdmChooserHost *host) + { + char *hostname; + char *name; + char *desc; + char *label; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean res; + + GtkTreeSelection *selection; + + g_assert (host != NULL); + + if (! gdm_chooser_host_get_willing (host)) { + gtk_widget_set_sensitive (GTK_WIDGET (widget), TRUE); + return; + } +-- +2.12.0 + diff --git a/SOURCES/add-postlogin.patch b/SOURCES/add-postlogin.patch deleted file mode 100644 index 3d16090..0000000 --- a/SOURCES/add-postlogin.patch +++ /dev/null @@ -1,174 +0,0 @@ -From e92b0e3c56df36e8291a2f3dbef45e8332fab8ab Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 16 Jan 2015 09:46:26 -0500 -Subject: [PATCH] Revert "pam: drop postlogin from fedora pam config" - -This reverts commit 76d26d8c1c37c6bd38bcac082d5cc62670fe5d39. - -It breaks pam_ecryptfs. -Downstream: https://bugzilla.redhat.com/show_bug.cgi?id=1174366 - -https://bugzilla.gnome.org/show_bug.cgi?id=743045 ---- - data/pam-redhat/gdm-autologin.pam | 2 ++ - data/pam-redhat/gdm-fingerprint.pam | 2 ++ - data/pam-redhat/gdm-launch-environment.pam | 2 ++ - data/pam-redhat/gdm-password.pam | 2 ++ - data/pam-redhat/gdm-pin.pam | 2 ++ - data/pam-redhat/gdm-smartcard.pam | 2 ++ - data/pam-redhat/gdm.pam | 3 +++ - 7 files changed, 15 insertions(+) - -diff --git a/data/pam-redhat/gdm-autologin.pam b/data/pam-redhat/gdm-autologin.pam -index 08d4543..0616e66 100644 ---- a/data/pam-redhat/gdm-autologin.pam -+++ b/data/pam-redhat/gdm-autologin.pam -@@ -1,14 +1,16 @@ - #%PAM-1.0 - auth required pam_env.so - auth required pam_permit.so -+auth include postlogin - account required pam_nologin.so - account include system-auth - password include system-auth - session required pam_selinux.so close - session required pam_loginuid.so - session optional pam_console.so - -session optional pam_ck_connector.so - session required pam_selinux.so open - session optional pam_keyinit.so force revoke - session required pam_namespace.so - session include system-auth -+session include postlogin -diff --git a/data/pam-redhat/gdm-fingerprint.pam b/data/pam-redhat/gdm-fingerprint.pam -index ee0635d..c5a3598 100644 ---- a/data/pam-redhat/gdm-fingerprint.pam -+++ b/data/pam-redhat/gdm-fingerprint.pam -@@ -1,15 +1,17 @@ - auth substack fingerprint-auth -+auth include postlogin - - account required pam_nologin.so - account include fingerprint-auth - - password include fingerprint-auth - - session required pam_selinux.so close - session required pam_loginuid.so - session optional pam_console.so - -session optional pam_ck_connector.so - session required pam_selinux.so open - session optional pam_keyinit.so force revoke - session required pam_namespace.so - session include fingerprint-auth -+session include postlogin -diff --git a/data/pam-redhat/gdm-launch-environment.pam b/data/pam-redhat/gdm-launch-environment.pam -index f1811f1..a5130ea 100644 ---- a/data/pam-redhat/gdm-launch-environment.pam -+++ b/data/pam-redhat/gdm-launch-environment.pam -@@ -1,7 +1,9 @@ - #%PAM-1.0 - auth required pam_env.so - auth required pam_permit.so -+auth include postlogin - account include system-auth - password include system-auth - session optional pam_keyinit.so force revoke - session include system-auth -+session include postlogin -diff --git a/data/pam-redhat/gdm-password.pam b/data/pam-redhat/gdm-password.pam -index b95ca16..3006d0c 100644 ---- a/data/pam-redhat/gdm-password.pam -+++ b/data/pam-redhat/gdm-password.pam -@@ -1,19 +1,21 @@ - auth [success=done ignore=ignore default=bad] pam_selinux_permit.so - auth substack password-auth - auth optional pam_gnome_keyring.so -+auth include postlogin - - account required pam_nologin.so - account include password-auth - - password substack password-auth - -password optional pam_gnome_keyring.so use_authtok - - session required pam_selinux.so close - session required pam_loginuid.so - session optional pam_console.so - -session optional pam_ck_connector.so - session required pam_selinux.so open - session optional pam_keyinit.so force revoke - session required pam_namespace.so - session include password-auth - session optional pam_gnome_keyring.so auto_start -+session include postlogin -diff --git a/data/pam-redhat/gdm-pin.pam b/data/pam-redhat/gdm-pin.pam -index d0a4e71..7594653 100644 ---- a/data/pam-redhat/gdm-pin.pam -+++ b/data/pam-redhat/gdm-pin.pam -@@ -1,20 +1,22 @@ - auth [success=done ignore=ignore default=bad] pam_selinux_permit.so - auth requisite pam_pin.so - auth substack password-auth - auth optional pam_gnome_keyring.so -+auth include postlogin - - account required pam_nologin.so - account include password-auth - - password include password-auth - password optional pam_pin.so - - session required pam_selinux.so close - session required pam_loginuid.so - session optional pam_console.so - -session optional pam_ck_connector.so - session required pam_selinux.so open - session optional pam_keyinit.so force revoke - session required pam_namespace.so - session include password-auth - session optional pam_gnome_keyring.so auto_start -+session include postlogin -diff --git a/data/pam-redhat/gdm-smartcard.pam b/data/pam-redhat/gdm-smartcard.pam -index d49eef9..c91cf0d 100644 ---- a/data/pam-redhat/gdm-smartcard.pam -+++ b/data/pam-redhat/gdm-smartcard.pam -@@ -1,15 +1,17 @@ - auth substack smartcard-auth -+auth include postlogin - - account required pam_nologin.so - account include smartcard-auth - - password include smartcard-auth - - session required pam_selinux.so close - session required pam_loginuid.so - session optional pam_console.so - -session optional pam_ck_connector.so - session required pam_selinux.so open - session optional pam_keyinit.so force revoke - session required pam_namespace.so - session include smartcard-auth -+session include postlogin -diff --git a/data/pam-redhat/gdm.pam b/data/pam-redhat/gdm.pam -index 9d95a51..baa058b 100644 ---- a/data/pam-redhat/gdm.pam -+++ b/data/pam-redhat/gdm.pam -@@ -1,10 +1,13 @@ - #%PAM-1.0 - auth required pam_env.so - auth sufficient pam_succeed_if.so user ingroup nopasswdlogin -+auth include postlogin - auth include system-auth -+account required pam_nologin.so - account include system-auth - password include system-auth - session optional pam_keyinit.so force revoke - session include system-auth - session required pam_loginuid.so - session optional pam_console.so -+session include postlogin --- -2.3.7 - diff --git a/SOURCES/audit-4.patch b/SOURCES/audit-4.patch index 00a1b8f..54d5b1d 100644 --- a/SOURCES/audit-4.patch +++ b/SOURCES/audit-4.patch @@ -1,17 +1,18 @@ -From 461f55218867e7e8e25ab85dc93faf8193cbe243 Mon Sep 17 00:00:00 2001 +From 328f7544bf77891b76af091af8e179f4e003050a Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 3 Jul 2015 14:39:33 -0400 Subject: [PATCH] server: add -audit 4 to default flags --- - daemon/gdm-server.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + daemon/gdm-server.c | 2 +- + daemon/gdm-x-session.c | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c -index ccb26a3..b52465e 100644 +index 6357d344..2e8c0562 100644 --- a/daemon/gdm-server.c +++ b/daemon/gdm-server.c -@@ -249,61 +249,61 @@ gdm_server_launch_sigusr1_thread_if_needed (void) +@@ -199,61 +199,61 @@ gdm_server_launch_sigusr1_thread_if_needed (void) static GThread *sigusr1_thread; if (sigusr1_thread == NULL) { @@ -45,8 +46,6 @@ index ccb26a3..b52465e 100644 -#define X_SERVER_ARG_FORMAT " -background none -noreset -verbose %s%s" +#define X_SERVER_ARG_FORMAT " -background none -noreset -audit 4 -verbose %s%s" - #ifdef WITH_SYSTEMD - /* This is a temporary hack to work around the fact that XOrg * currently lacks support for multi-seat hotplugging for * display devices. This bit should be removed as soon as XOrg @@ -61,10 +60,6 @@ index ccb26a3..b52465e 100644 * wasn't booted using systemd, or b) the wrapper tool is * missing, or c) we are running for the main seat 'seat0'. */ - if (!LOGIND_RUNNING()) { - goto fallback; - } - #ifdef ENABLE_SYSTEMD_JOURNAL /* For systemd, we don't have a log file but instead log to stdout, so set it to the xserver's built-in default verbosity */ @@ -74,6 +69,79 @@ index ccb26a3..b52465e 100644 verbosity = "3 -logfile /dev/null"; #endif + if (g_access (SYSTEMD_X_SERVER, X_OK) < 0) { + goto fallback; + } + + if (server->priv->display_seat_id == NULL || + strcmp (server->priv->display_seat_id, "seat0") == 0) { +diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c +index b919e6e9..80fc09b8 100644 +--- a/daemon/gdm-x-session.c ++++ b/daemon/gdm-x-session.c +@@ -247,60 +247,62 @@ spawn_x_server (State *state, + } + + g_ptr_array_add (arguments, "-displayfd"); + g_ptr_array_add (arguments, display_fd_string); + + g_ptr_array_add (arguments, "-auth"); + g_ptr_array_add (arguments, auth_file); + + /* If we were compiled with Xserver >= 1.17 we need to specify + * '-listen tcp' as the X server dosen't listen on tcp sockets + * by default anymore. In older versions we need to pass + * -nolisten tcp to disable listening on tcp sockets. + */ + #ifdef HAVE_XSERVER_THAT_DEFAULTS_TO_LOCAL_ONLY + if (allow_remote_connections) { + g_ptr_array_add (arguments, "-listen"); + g_ptr_array_add (arguments, "tcp"); + } + #else + if (!allow_remote_connections) { + g_ptr_array_add (arguments, "-nolisten"); + g_ptr_array_add (arguments, "tcp"); + } + #endif + + g_ptr_array_add (arguments, "-background"); + g_ptr_array_add (arguments, "none"); + + g_ptr_array_add (arguments, "-noreset"); + g_ptr_array_add (arguments, "-keeptty"); ++ g_ptr_array_add (arguments, "-audit"); ++ g_ptr_array_add (arguments, "4"); + + g_ptr_array_add (arguments, "-verbose"); + if (state->debug_enabled) { + g_ptr_array_add (arguments, "7"); + } else { + g_ptr_array_add (arguments, "3"); + } + + if (state->debug_enabled) { + g_ptr_array_add (arguments, "-core"); + } + g_ptr_array_add (arguments, NULL); + + subprocess = g_subprocess_launcher_spawnv (launcher, + (const char * const *) arguments->pdata, + &error); + g_free (display_fd_string); + g_clear_object (&launcher); + g_ptr_array_free (arguments, TRUE); + + if (subprocess == NULL) { + g_debug ("could not start X server: %s", error->message); + goto out; + } + + input_stream = g_unix_input_stream_new (pipe_fds[0], TRUE); + data_stream = g_data_input_stream_new (input_stream); + g_clear_object (&input_stream); + + display_number = g_data_input_stream_read_line (data_stream, -- -2.3.7 +2.11.1 diff --git a/SOURCES/classic-session.patch b/SOURCES/classic-session.patch index 9c8d34e..ddaeae7 100644 --- a/SOURCES/classic-session.patch +++ b/SOURCES/classic-session.patch @@ -1,4 +1,4 @@ -From be12e2373f73c900de9eedde4ce2c85821bfdd3f Mon Sep 17 00:00:00 2001 +From b8c0d62a660b7a48993feef40947a79be80f729f Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 3 Apr 2013 10:28:09 -0400 Subject: [PATCH] session: change default session @@ -10,10 +10,37 @@ by /etc/sysconfig/desktop 1 file changed, 100 insertions(+) diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index 4cc0879..b89364d 100644 +index e69291fb..81341554 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c -@@ -540,9 +540,89 @@ get_default_language_name (GdmSession *self) +@@ -492,75 +492,175 @@ get_session_command_for_name (GdmSession *self, + gboolean res; + char *filename; + + filename = g_strdup_printf ("%s.desktop", name); + res = get_session_command_for_file (self, filename, command); + g_free (filename); + + return res; + } + + static const char * + get_default_language_name (GdmSession *self) + { + const char *default_language; + + if (self->priv->saved_language != NULL) { + return self->priv->saved_language; + } + + default_language = g_hash_table_lookup (self->priv->environment, + "LANG"); + + if (default_language != NULL) { + return default_language; + } + + return setlocale (LC_MESSAGES, NULL); } static const char * @@ -103,14 +130,19 @@ index 4cc0879..b89364d 100644 int i; char *name; GSequence *sessions; -@@ -555,6 +635,26 @@ get_fallback_session_name (GdmSession *self) + GSequenceIter *session; + + if (self->priv->fallback_session_name != NULL) { + /* verify that the cached version still exists */ + if (get_session_command_for_name (self, self->priv->fallback_session_name, NULL)) { + goto out; } } + configured_session = get_configured_default_session_name (self); + + name = g_strdup (configured_session); -+ if (get_session_command_for_name (name, NULL)) { ++ if (get_session_command_for_name (self, name, NULL)) { + g_free (self->priv->fallback_session_name); + self->priv->fallback_session_name = name; + goto out; @@ -119,7 +151,7 @@ index 4cc0879..b89364d 100644 + + if (g_strcmp0 (configured_session, "gnome-classic") != 0) { + name = g_strdup ("gnome-classic"); -+ if (get_session_command_for_name (name, NULL)) { ++ if (get_session_command_for_name (self, name, NULL)) { + g_free (self->priv->fallback_session_name); + self->priv->fallback_session_name = name; + goto out; @@ -128,8 +160,35 @@ index 4cc0879..b89364d 100644 + } + name = g_strdup ("gnome"); - if (get_session_command_for_name (name, NULL)) { + if (get_session_command_for_name (self, name, NULL)) { g_free (self->priv->fallback_session_name); + self->priv->fallback_session_name = name; + goto out; + } + g_free (name); + + sessions = g_sequence_new (g_free); + + search_dirs = get_system_session_dirs (self); + for (i = 0; search_dirs[i] != NULL; i++) { + GDir *dir; + const char *base_name; + + dir = g_dir_open (search_dirs[i], 0, NULL); + + if (dir == NULL) { + continue; + } + + do { + base_name = g_dir_read_name (dir); + + if (base_name == NULL) { + break; + } + + if (!g_str_has_suffix (base_name, ".desktop")) { + continue; -- -2.3.7 +2.11.1 diff --git a/SOURCES/clear-screen.patch b/SOURCES/clear-screen.patch index ecf9644..b262864 100644 --- a/SOURCES/clear-screen.patch +++ b/SOURCES/clear-screen.patch @@ -1,7 +1,7 @@ -From 6415083d3913e8f0da43161fb8c493ff3bfdfcee Mon Sep 17 00:00:00 2001 +From ff7510f5594fe62b82c811c166713eecd916c27b Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 14 Mar 2014 11:04:49 -0400 -Subject: [PATCH 1/2] systemd: clear terminal after starting +Subject: [PATCH] systemd: clear terminal after starting This helps with flicker when the X server shuts down. --- @@ -9,67 +9,7 @@ This helps with flicker when the X server shuts down. 1 file changed, 1 insertion(+) diff --git a/data/gdm.service.in b/data/gdm.service.in -index 9090cf4..87785b8 100644 ---- a/data/gdm.service.in -+++ b/data/gdm.service.in -@@ -1,32 +1,33 @@ - [Unit] - Description=GNOME Display Manager - - # replaces the getty - Conflicts=getty@tty@GDM_INITIAL_VT@.service - After=getty@tty@GDM_INITIAL_VT@.service - - # replaces plymouth-quit since it quits plymouth on its own - Conflicts=plymouth-quit.service - After=plymouth-quit.service - - # Needs all the dependencies of the services it's replacing - # pulled from getty@.service and plymouth-quit.service - # (except for plymouth-quit-wait.service since it waits until - # plymouth is quit, which we do) - After=rc-local.service plymouth-start.service systemd-user-sessions.service - - # GDM takes responsibility for stopping plymouth, so if it fails - # for any reason, make sure plymouth still stops - OnFailure=plymouth-quit.service - - [Service] - ExecStart=@sbindir@/gdm -+ExecStartPost=-/bin/bash -c "TERM=linux /usr/bin/clear > /dev/tty1" - Restart=always - IgnoreSIGPIPE=no - BusName=org.gnome.DisplayManager - StandardOutput=syslog - StandardError=inherit - EnvironmentFile=-@LANG_CONFIG_FILE@ - - [Install] - Alias=display-manager.service --- -2.3.7 - - -From 729d74412cee774c5ccd2b8a7d82eda6e3fc65b2 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 30 Mar 2015 21:53:33 -0400 -Subject: [PATCH 2/2] systemd: change to KillMode=mixed - -By default systemd will kill the entire control-group in one fell -swoop. The problem is, things don't get shutdown in the right -order then, and there's a race where GDM will begin restarting -X servers as soon as they're killed. - -This commit tells systemd to just kill the main GDM process, and -let it handle killing all its children on its own. - -https://bugzilla.gnome.org/show_bug.cgi?id=747088 ---- - data/gdm.service.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/data/gdm.service.in b/data/gdm.service.in -index 87785b8..47cdcf2 100644 +index fb0ffdcf..9c876c70 100644 --- a/data/gdm.service.in +++ b/data/gdm.service.in @@ -1,33 +1,34 @@ @@ -81,11 +21,11 @@ index 87785b8..47cdcf2 100644 After=getty@tty@GDM_INITIAL_VT@.service # replaces plymouth-quit since it quits plymouth on its own - Conflicts=plymouth-quit.service - After=plymouth-quit.service + Conflicts=@PLYMOUTH_QUIT_SERVICE@ + After=@PLYMOUTH_QUIT_SERVICE@ # Needs all the dependencies of the services it's replacing - # pulled from getty@.service and plymouth-quit.service + # pulled from getty@.service and @PLYMOUTH_QUIT_SERVICE@ # (except for plymouth-quit-wait.service since it waits until # plymouth is quit, which we do) After=rc-local.service plymouth-start.service systemd-user-sessions.service @@ -96,8 +36,8 @@ index 87785b8..47cdcf2 100644 [Service] ExecStart=@sbindir@/gdm - ExecStartPost=-/bin/bash -c "TERM=linux /usr/bin/clear > /dev/tty1" -+KillMode=mixed ++ExecStartPost=-/bin/bash -c "TERM=linux /usr/bin/clear > /dev/tty1" + KillMode=mixed Restart=always IgnoreSIGPIPE=no BusName=org.gnome.DisplayManager @@ -108,5 +48,5 @@ index 87785b8..47cdcf2 100644 [Install] Alias=display-manager.service -- -2.3.7 +2.11.1 diff --git a/SOURCES/dont-require-working-rdns.patch b/SOURCES/dont-require-working-rdns.patch deleted file mode 100644 index 231effb..0000000 --- a/SOURCES/dont-require-working-rdns.patch +++ /dev/null @@ -1,290 +0,0 @@ -From 8ab57ebcf775bf97fc99c0315a4b7b29435c34c2 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 20 Apr 2016 17:07:53 -0400 -Subject: [PATCH] common: limit potentially expensive name lookups - -Right now we're doing name look ups when we don't have to. These -name look ups can cause lengthy timeouts in misconfigured environments. - -This commit reduces the name looks used by GDM to make it more resiliant -to failure. - -Ported from RHEL 6 to RHEL 7 by Ashish Shah ---- - common/gdm-address.c | 24 ++++++++++++------------ - 1 file changed, 12 insertions(+), 12 deletions(-) - -diff --git a/common/gdm-address.c b/common/gdm-address.c -index 3448038..a8b73e2 100644 ---- a/common/gdm-address.c -+++ b/common/gdm-address.c -@@ -193,159 +193,160 @@ gdm_address_equal (GdmAddress *a, - return FALSE; - } - - /* for debugging */ - static const char * - address_family_str (GdmAddress *address) - { - const char *str; - switch (address->ss->ss_family) { - case AF_INET: - str = "inet"; - break; - case AF_INET6: - str = "inet6"; - break; - case AF_UNIX: - str = "unix"; - break; - case AF_UNSPEC: - str = "unspecified"; - break; - default: - str = "unknown"; - break; - } - return str; - } - - static void - _gdm_address_debug (GdmAddress *address, -- const char *hostname, - const char *host, - const char *port) - { -- g_debug ("Address family:%d (%s) hostname:%s host:%s port:%s local:%d loopback:%d", -+ g_debug ("Address family:%d (%s) host:%s port:%s local:%d loopback:%d", -+ - address->ss->ss_family, - address_family_str (address) ? address_family_str (address) : "(null)", -- hostname ? hostname : "(null)", - host ? host : "(null)", - port ? port : "(null)", - gdm_address_is_local (address), - gdm_address_is_loopback (address)); - } - - void - gdm_address_debug (GdmAddress *address) - { -- char *hostname; -- char *host; -- char *port; -+ char *hostname = NULL; -+ char *host = NULL; -+ char *port = NULL; - -- gdm_address_get_hostname (address, &hostname); - gdm_address_get_numeric_info (address, &host, &port); - -+ _gdm_address_debug (address, host, port); -+ - g_free (hostname); - g_free (host); - g_free (port); - } - - gboolean - gdm_address_get_hostname (GdmAddress *address, - char **hostnamep) - { - char host [NI_MAXHOST]; - int res; - gboolean ret; - - g_return_val_if_fail (address != NULL, FALSE); - g_return_val_if_fail (address->ss != NULL, FALSE); - - ret = FALSE; - - host [0] = '\0'; - res = getnameinfo ((const struct sockaddr *)address->ss, - (int) gdm_sockaddr_len (address->ss), - host, sizeof (host), - NULL, 0, - 0); - if (res == 0) { - ret = TRUE; - goto done; - } else { - const char *err_msg; - - err_msg = gai_strerror (res); - g_warning ("Unable to lookup hostname: %s", - err_msg ? err_msg : "(null)"); -- _gdm_address_debug (address, NULL, NULL, NULL); -+ _gdm_address_debug (address, NULL, NULL); -+ - } - - /* try numeric? */ - - done: - if (hostnamep != NULL) { - *hostnamep = g_strdup (host); - } - - return ret; - } - - gboolean - gdm_address_get_numeric_info (GdmAddress *address, - char **hostp, - char **servp) - { - char host [NI_MAXHOST]; - char serv [NI_MAXSERV]; - int res; - gboolean ret; - - g_return_val_if_fail (address != NULL, FALSE); - g_return_val_if_fail (address->ss != NULL, FALSE); - - ret = FALSE; - - host [0] = '\0'; - serv [0] = '\0'; - res = getnameinfo ((const struct sockaddr *)address->ss, - (int) gdm_sockaddr_len (address->ss), - host, sizeof (host), - serv, sizeof (serv), - NI_NUMERICHOST | NI_NUMERICSERV); - if (res != 0) { - const char *err_msg; - - err_msg = gai_strerror (res); - g_warning ("Unable to lookup numeric info: %s", - err_msg ? err_msg : "(null)"); -- _gdm_address_debug (address, NULL, NULL, NULL); -+ _gdm_address_debug (address, NULL, NULL); - } else { - ret = TRUE; - } - - if (servp != NULL) { - if (g_str_has_prefix (serv, "::ffff:")) { - *servp = g_strdup (serv + 7); - } else { - *servp = g_strdup (serv); - } - } - if (hostp != NULL) { - if (g_str_has_prefix (host, "::ffff:")) { - *hostp = g_strdup (host + 7); - } else { - *hostp = g_strdup (host); - } - } - - return ret; - } - - gboolean - gdm_address_is_loopback (GdmAddress *address) - { - g_return_val_if_fail (address != NULL, FALSE); - g_return_val_if_fail (address->ss != NULL, FALSE); - - switch (address->ss->ss_family){ - #ifdef AF_INET6 -@@ -377,94 +378,93 @@ add_local_siocgifconf (GList **list) - perror ("socket"); - return; - } - - ifc.ifc_len = sizeof (buf); - ifc.ifc_buf = buf; - if (ioctl (sock, SIOCGIFCONF, (char *) &ifc) < 0) { - perror ("SIOCGIFCONF"); - close (sock); - return; - } - - /* Get IP address of each active IP network interface. */ - the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - - for (ifr = ifc.ifc_req; ifr < the_end; ifr++) { - if (ifr->ifr_addr.sa_family == AF_INET) { - /* IP net interface */ - ifreq = *ifr; - - if (ioctl (sock, SIOCGIFFLAGS, (char *) &ifreq) < 0) { - perror("SIOCGIFFLAGS"); - } else if (ifreq.ifr_flags & IFF_UP) { /* active interface */ - if (ioctl (sock, SIOCGIFADDR, (char *) &ifreq) < 0) { - perror("SIOCGIFADDR"); - } else { - GdmAddress *address; - address = gdm_address_new_from_sockaddr ((struct sockaddr *)&ifreq.ifr_addr, - sizeof (struct sockaddr)); - -- gdm_address_debug (address); -- - *list = g_list_append (*list, address); - } - } - } - - /* Support for variable-length addresses. */ - #ifdef HAS_SA_LEN - ifr = (struct ifreq *) ((caddr_t) ifr - + ifr->ifr_addr.sa_len - sizeof(struct sockaddr)); - #endif - } - - close (sock); - } - - static void - add_local_addrinfo (GList **list) - { - char hostbuf[BUFSIZ]; - struct addrinfo *result; - struct addrinfo *res; - struct addrinfo hints; - - hostbuf[BUFSIZ-1] = '\0'; - if (gethostname (hostbuf, BUFSIZ-1) != 0) { - g_debug ("%s: Could not get server hostname, using localhost", "gdm_peek_local_address_list"); - snprintf (hostbuf, BUFSIZ-1, "localhost"); - } - - memset (&hints, 0, sizeof (hints)); - hints.ai_family = AF_UNSPEC; -- hints.ai_flags = AI_CANONNAME; -+ hints.ai_flags = AI_CANONNAME | AI_NUMERICHOST; -+ - - g_debug ("GdmAddress: looking up hostname: %s", hostbuf); - result = NULL; - if (getaddrinfo (hostbuf, NULL, &hints, &result) != 0) { - g_debug ("%s: Could not get address from hostname!", "gdm_peek_local_address_list"); - - return; - } - - for (res = result; res != NULL; res = res->ai_next) { - GdmAddress *address; - - g_debug ("family=%d sock_type=%d protocol=%d flags=0x%x canonname=%s\n", - res->ai_family, - res->ai_socktype, - res->ai_protocol, - res->ai_flags, - res->ai_canonname ? res->ai_canonname : "(null)"); - address = gdm_address_new_from_sockaddr (res->ai_addr, res->ai_addrlen); - *list = g_list_append (*list, address); - } - - if (result != NULL) { - freeaddrinfo (result); - result = NULL; - } - } - - const GList * - gdm_address_peek_local_list (void) --- -2.8.1 - diff --git a/SOURCES/fix-headless.patch b/SOURCES/fix-headless.patch deleted file mode 100644 index 39493ea..0000000 --- a/SOURCES/fix-headless.patch +++ /dev/null @@ -1,64 +0,0 @@ -diff -up gdm-3.14.2/daemon/gdm-session-worker.c.fix-headless gdm-3.14.2/daemon/gdm-session-worker.c ---- gdm-3.14.2/daemon/gdm-session-worker.c.fix-headless 2015-06-23 10:42:17.802937143 -0400 -+++ gdm-3.14.2/daemon/gdm-session-worker.c 2015-06-23 10:52:26.055317210 -0400 -@@ -2059,6 +2059,43 @@ fail: - } - #endif - -+#ifdef __linux__ -+static gboolean -+set_xdg_vtnr_to_current_vt (GdmSessionWorker *worker) -+{ -+ int fd; -+ char vt_string[256]; -+ struct vt_stat vt_state = { 0 }; -+ -+ fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); -+ -+ if (fd < 0) { -+ g_debug ("GdmSessionWorker: couldn't open VT master: %m"); -+ return FALSE; -+ } -+ -+ if (ioctl (fd, VT_GETSTATE, &vt_state) < 0) { -+ g_debug ("GdmSessionWorker: couldn't get current VT: %m"); -+ goto fail; -+ } -+ -+ close (fd); -+ fd = -1; -+ -+ g_snprintf (vt_string, sizeof (vt_string), "%d", vt_state.v_active); -+ -+ gdm_session_worker_set_environment_variable (worker, -+ "XDG_VTNR", -+ vt_string); -+ -+ return TRUE; -+ -+fail: -+ close (fd); -+ return FALSE; -+} -+#endif -+ - static gboolean - set_up_for_current_vt (GdmSessionWorker *worker, - GError **error) -@@ -2124,6 +2161,16 @@ set_up_for_current_vt (GdmSessionWorker - g_free (pam_xauth); - } - #endif -+ -+#ifdef __linux__ -+ if (g_strcmp0 (worker->priv->display_seat_id, "seat0") == 0) { -+ g_debug ("GdmSessionWorker: setting XDG_VTNR to current vt"); -+ set_xdg_vtnr_to_current_vt (worker); -+ } else { -+ g_debug ("GdmSessionWorker: not setting XDG_VTNR since not seat0"); -+ } -+#endif -+ - return TRUE; - out: - return FALSE; diff --git a/SOURCES/fix-lang-changes.patch b/SOURCES/fix-lang-changes.patch deleted file mode 100644 index bc308da..0000000 --- a/SOURCES/fix-lang-changes.patch +++ /dev/null @@ -1,291 +0,0 @@ -From b58a964bfac6d6af19a5e4d8b74508d06705909f Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 2 Jul 2015 13:08:05 -0400 -Subject: [PATCH] session: load locale.conf from gdm-session.c - -Right now we're not picking up changes to locale.conf completely -at runtime. - -This commit moves reading locale.conf to a different place in the -code, so that it's more effectively read and used. ---- - daemon/gdm-launch-environment.c | 106 ---------------------------------------- - daemon/gdm-session.c | 102 ++++++++++++++++++++++++++++++++++++-- - 2 files changed, 99 insertions(+), 109 deletions(-) - -diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c -index e6b16dd..4aee187 100644 ---- a/daemon/gdm-launch-environment.c -+++ b/daemon/gdm-launch-environment.c -@@ -107,109 +107,6 @@ static void gdm_launch_environment_finalize (GObject - - G_DEFINE_TYPE (GdmLaunchEnvironment, gdm_launch_environment, G_TYPE_OBJECT) - --static void --load_lang_config_file (const char *config_file, -- const char **str_array) --{ -- gchar *contents = NULL; -- gchar *p; -- gchar *str_joinv; -- gchar *pattern; -- gchar *key; -- gchar *value; -- gsize length; -- GError *error; -- GString *line; -- GRegex *re; -- -- g_return_if_fail (config_file != NULL); -- g_return_if_fail (str_array != NULL); -- -- if (!g_file_test (config_file, G_FILE_TEST_EXISTS)) { -- g_debug ("Cannot access '%s'", config_file); -- return; -- } -- -- error = NULL; -- if (!g_file_get_contents (config_file, &contents, &length, &error)) { -- g_debug ("Failed to parse '%s': %s", -- config_file, -- (error && error->message) ? error->message : "(null)"); -- g_error_free (error); -- return; -- } -- -- if (!g_utf8_validate (contents, length, NULL)) { -- g_warning ("Invalid UTF-8 in '%s'", config_file); -- g_free (contents); -- return; -- } -- -- str_joinv = g_strjoinv ("|", (char **) str_array); -- if (str_joinv == NULL) { -- g_warning ("Error in joined"); -- g_free (contents); -- return; -- } -- -- pattern = g_strdup_printf ("(?P(%s))=(\")?(?P[^\"]*)?(\")?", -- str_joinv); -- error = NULL; -- re = g_regex_new (pattern, 0, 0, &error); -- g_free (pattern); -- g_free (str_joinv); -- if (re == NULL) { -- g_warning ("Failed to regex: %s", -- (error && error->message) ? error->message : "(null)"); -- g_error_free (error); -- g_free (contents); -- return; -- } -- -- line = g_string_new (""); -- for (p = contents; p && *p; p = g_utf8_find_next_char (p, NULL)) { -- gunichar ch; -- GMatchInfo *match_info = NULL; -- -- ch = g_utf8_get_char (p); -- if ((ch != '\n') && (ch != '\0')) { -- g_string_append_unichar (line, ch); -- continue; -- } -- -- if (line->str && g_utf8_get_char (line->str) == '#') { -- goto next_line; -- } -- -- if (!g_regex_match (re, line->str, 0, &match_info)) { -- goto next_line; -- } -- -- if (!g_match_info_matches (match_info)) { -- goto next_line; -- } -- -- key = g_match_info_fetch_named (match_info, "key"); -- value = g_match_info_fetch_named (match_info, "value"); -- -- if (key && *key && value && *value) { -- g_setenv (key, value, TRUE); -- } else if (key && *key) { -- g_unsetenv (key); -- } -- -- g_free (key); -- g_free (value); --next_line: -- g_match_info_free (match_info); -- g_string_set_size (line, 0); -- } -- -- g_string_free (line, TRUE); -- g_regex_unref (re); -- g_free (contents); --} -- - static GHashTable * - build_launch_environment (GdmLaunchEnvironment *launch_environment, - gboolean start_session) -@@ -226,9 +123,6 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment, - char *system_data_dirs; - int i; - -- load_lang_config_file (LANG_CONFIG_FILE, -- (const char **) optional_environment); -- - /* create a hash table of current environment, then update keys has necessary */ - hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - -diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index 1674bb6..d3643c2 100644 ---- a/daemon/gdm-session.c -+++ b/daemon/gdm-session.c -@@ -523,8 +523,17 @@ get_session_command_for_name (const char *name, - static const char * - get_default_language_name (GdmSession *self) - { -+ const char *default_language; -+ - if (self->priv->saved_language != NULL) { -- return self->priv->saved_language; -+ return self->priv->saved_language; -+ } -+ -+ default_language = g_hash_table_lookup (self->priv->environment, -+ "LANG"); -+ -+ if (default_language != NULL) { -+ return default_language; - } - - return setlocale (LC_MESSAGES, NULL); -@@ -1705,6 +1714,90 @@ free_conversation (GdmSessionConversation *conversation) - } - - static void -+load_lang_config_file (GdmSession *self) -+{ -+ static const char *config_file = LANG_CONFIG_FILE; -+ gchar *contents = NULL; -+ gchar *p; -+ gchar *key; -+ gchar *value; -+ gsize length; -+ GError *error; -+ GString *line; -+ GRegex *re; -+ -+ if (!g_file_test (config_file, G_FILE_TEST_EXISTS)) { -+ g_debug ("Cannot access '%s'", config_file); -+ return; -+ } -+ -+ error = NULL; -+ if (!g_file_get_contents (config_file, &contents, &length, &error)) { -+ g_debug ("Failed to parse '%s': %s", -+ LANG_CONFIG_FILE, -+ (error && error->message) ? error->message : "(null)"); -+ g_error_free (error); -+ return; -+ } -+ -+ if (!g_utf8_validate (contents, length, NULL)) { -+ g_warning ("Invalid UTF-8 in '%s'", config_file); -+ g_free (contents); -+ return; -+ } -+ -+ re = g_regex_new ("(?P(LANG|LANGUAGE|LC_CTYPE|LC_NUMERIC|LC_TIME|LC_COLLATE|LC_MONETARY|LC_MESSAGES|LC_PAPER|LC_NAME|LC_ADDRESS|LC_TELEPHONE|LC_MEASUREMENT|LC_IDENTIFICATION|LC_ALL))=(\")?(?P[^\"]*)?(\")?", 0, 0, &error); -+ if (re == NULL) { -+ g_warning ("Failed to regex: %s", -+ (error && error->message) ? error->message : "(null)"); -+ g_error_free (error); -+ g_free (contents); -+ return; -+ } -+ -+ line = g_string_new (""); -+ for (p = contents; p && *p; p = g_utf8_find_next_char (p, NULL)) { -+ gunichar ch; -+ GMatchInfo *match_info = NULL; -+ -+ ch = g_utf8_get_char (p); -+ if ((ch != '\n') && (ch != '\0')) { -+ g_string_append_unichar (line, ch); -+ continue; -+ } -+ -+ if (line->str && g_utf8_get_char (line->str) == '#') { -+ goto next_line; -+ } -+ -+ if (!g_regex_match (re, line->str, 0, &match_info)) { -+ goto next_line; -+ } -+ -+ if (!g_match_info_matches (match_info)) { -+ goto next_line; -+ } -+ -+ key = g_match_info_fetch_named (match_info, "key"); -+ value = g_match_info_fetch_named (match_info, "value"); -+ -+ if (key && *key && value && *value) { -+ g_setenv (key, value, TRUE); -+ } -+ -+ g_free (key); -+ g_free (value); -+next_line: -+ g_match_info_free (match_info); -+ g_string_set_size (line, 0); -+ } -+ -+ g_string_free (line, TRUE); -+ g_regex_unref (re); -+ g_free (contents); -+} -+ -+static void - gdm_session_init (GdmSession *self) - { - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, -@@ -1734,6 +1827,7 @@ gdm_session_init (GdmSession *self) - (GDestroyNotify) g_free, - (GDestroyNotify) g_free); - -+ load_lang_config_file (self); - setup_worker_server (self); - setup_outside_server (self); - } -@@ -2396,7 +2490,7 @@ set_up_session_environment (GdmSession *self) - { - GdmSessionDisplayMode display_mode; - gchar *desktop_names; -- const char *locale; -+ char *locale; - - gdm_session_set_environment_variable (self, - "GDMSESSION", -@@ -2415,7 +2509,7 @@ set_up_session_environment (GdmSession *self) - - set_up_session_language (self); - -- locale = get_default_language_name (self); -+ locale = g_strdup (get_default_language_name (self)); - - if (locale != NULL && locale[0] != '\0') { - gdm_session_set_environment_variable (self, -@@ -2426,6 +2520,8 @@ set_up_session_environment (GdmSession *self) - locale); - } - -+ g_free (locale); -+ - display_mode = gdm_session_get_display_mode (self); - if (display_mode == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { - gdm_session_set_environment_variable (self, --- -1.8.3.1 - diff --git a/SOURCES/fix-language-chooser.patch b/SOURCES/fix-language-chooser.patch deleted file mode 100644 index 072c778..0000000 --- a/SOURCES/fix-language-chooser.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 2d6d95e4e90fae014fc5615ab39fe64ba49d9a29 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 21 Jan 2016 10:27:58 -0500 -Subject: [PATCH] session: make sure greeter is GNOME session even if gnome - isn't installed - -We figure out the XDG_CURRENT_DESKTOP by looking at the session that's -use for login. For the greeter, we don't use a session, at all, but -instead a directly specified program. Still, we're determining the -XDG_CURRENT_DESKTOP for the greeter based on what default session -gets picked. On KDE only setups, the greeter will get marked as -a KDE session which will prevent gnome-settings-daemon from starting -properly. - -This commit changes the code so that greeter sessions, don't rely -on the default session desktop file. - -https://bugzilla.gnome.org/show_bug.cgi?id=760943 ---- - daemon/gdm-session.c | 24 +++++++++++++++--------- - 1 file changed, 15 insertions(+), 9 deletions(-) - -diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index 647db86..ae94999 100644 ---- a/daemon/gdm-session.c -+++ b/daemon/gdm-session.c -@@ -2502,60 +2502,64 @@ get_session_name (GdmSession *self) - - return get_default_session_name (self); - } - - static char * - get_session_command (GdmSession *self) - { - gboolean res; - char *command; - const char *session_name; - - session_name = get_session_name (self); - - command = NULL; - res = get_session_command_for_name (session_name, &command); - if (! res) { - g_critical ("Cannot find a command for specified session: %s", session_name); - exit (1); - } - - return command; - } - - static gchar * - get_session_desktop_names (GdmSession *self) - { - gchar *filename; - GKeyFile *keyfile; - gchar *desktop_names = NULL; - -+ if (self->priv->selected_program != NULL) { -+ return g_strdup ("GNOME-Greeter:GNOME"); -+ } -+ - filename = g_strdup_printf ("%s.desktop", get_session_name (self)); - keyfile = load_key_file_for_file (filename, NULL); - if (keyfile != NULL) { - gchar **names; - - names = g_key_file_get_string_list (keyfile, G_KEY_FILE_DESKTOP_GROUP, - "DesktopNames", NULL, NULL); - if (names != NULL) { - desktop_names = g_strjoinv (":", names); - - g_strfreev (names); - } - } - - g_key_file_free (keyfile); - g_free (filename); - return desktop_names; - } - - void - gdm_session_set_environment_variable (GdmSession *self, - const char *key, - const char *value) - { - g_return_if_fail (key != NULL); - g_return_if_fail (value != NULL); - - g_hash_table_replace (self->priv->environment, - g_strdup (key), - g_strdup (value)); -@@ -2565,69 +2569,71 @@ static void - set_up_session_language (GdmSession *self) - { - char **environment; - int i; - const char *value; - - environment = g_listenv (); - for (i = 0; environment[i] != NULL; i++) { - if (strcmp (environment[i], "LANG") != 0 && - strcmp (environment[i], "LANGUAGE") != 0 && - !g_str_has_prefix (environment[i], "LC_")) { - continue; - } - - value = g_getenv (environment[i]); - - gdm_session_set_environment_variable (self, - environment[i], - value); - } - g_strfreev (environment); - } - - static void - set_up_session_environment (GdmSession *self) - { - GdmSessionDisplayMode display_mode; - gchar *desktop_names; - char *locale; - -- gdm_session_set_environment_variable (self, -- "GDMSESSION", -- get_session_name (self)); -- gdm_session_set_environment_variable (self, -- "DESKTOP_SESSION", -- get_session_name (self)); -- gdm_session_set_environment_variable (self, -- "XDG_SESSION_DESKTOP", -- get_session_name (self)); -+ if (self->priv->selected_program == NULL) { -+ gdm_session_set_environment_variable (self, -+ "GDMSESSION", -+ get_session_name (self)); -+ gdm_session_set_environment_variable (self, -+ "DESKTOP_SESSION", -+ get_session_name (self)); -+ gdm_session_set_environment_variable (self, -+ "XDG_SESSION_DESKTOP", -+ get_session_name (self)); -+ } - - desktop_names = get_session_desktop_names (self); - if (desktop_names != NULL) { - gdm_session_set_environment_variable (self, "XDG_CURRENT_DESKTOP", desktop_names); - } - - set_up_session_language (self); - - locale = g_strdup (get_default_language_name (self)); - - if (locale != NULL && locale[0] != '\0') { - gdm_session_set_environment_variable (self, - "LANG", - locale); - gdm_session_set_environment_variable (self, - "GDM_LANG", - locale); - } - - g_free (locale); - - display_mode = gdm_session_get_display_mode (self); - if (display_mode == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { - gdm_session_set_environment_variable (self, - "DISPLAY", - self->priv->display_name); - - if (self->priv->user_x11_authority_file != NULL) { - gdm_session_set_environment_variable (self, - "XAUTHORITY", --- -2.8.1 - diff --git a/SOURCES/fix-post-login.patch b/SOURCES/fix-post-login.patch deleted file mode 100644 index 27356e9..0000000 --- a/SOURCES/fix-post-login.patch +++ /dev/null @@ -1,350 +0,0 @@ -From c3f39b437f6ef32174f322bd107071cdf1379d12 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 18 Apr 2016 16:09:08 -0400 -Subject: [PATCH 1/2] worker: run PostLogin/PreSession scripts later - -Right now we run them while the login screen is still up, so -they have no way of showing UI to the user. - -This commit moves them until after the login screen is torn -down. ---- - daemon/gdm-session-worker.c | 34 ++++++++++++++++++---------------- - 1 file changed, 18 insertions(+), 16 deletions(-) - -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index acc826b..e07d32e 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -1793,60 +1793,78 @@ out: - } - - static gboolean - gdm_session_worker_start_session (GdmSessionWorker *worker, - GError **error) - { - struct passwd *passwd_entry; - pid_t session_pid; - int error_code; - - gdm_get_pwent_for_name (worker->priv->username, &passwd_entry); - if (worker->priv->is_program_session) { - g_debug ("GdmSessionWorker: opening session for program '%s'", - worker->priv->arguments[0]); - } else { - g_debug ("GdmSessionWorker: opening user session with program '%s'", - worker->priv->arguments[0]); - } - - error_code = PAM_SUCCESS; - - #ifdef ENABLE_WAYLAND_SUPPORT - /* If we're in new vt mode, jump to the new vt now. There's no need to jump for - * the other two modes: in the logind case, the session will activate itself when - * ready, and in the reuse server case, we're already on the correct VT. */ - if (worker->priv->display_mode == GDM_SESSION_DISPLAY_MODE_NEW_VT) { - jump_to_vt (worker, worker->priv->session_vt); - } - #endif - -+ if (!worker->priv->is_program_session && !run_script (worker, GDMCONFDIR "/PostLogin")) { -+ g_set_error (error, -+ GDM_SESSION_WORKER_ERROR, -+ GDM_SESSION_WORKER_ERROR_OPENING_SESSION, -+ "Failed to execute PostLogin script"); -+ error_code = PAM_ABORT; -+ goto out; -+ } -+ -+ if (!worker->priv->is_program_session && !run_script (worker, GDMCONFDIR "/PreSession")) { -+ g_set_error (error, -+ GDM_SESSION_WORKER_ERROR, -+ GDM_SESSION_WORKER_ERROR_OPENING_SESSION, -+ "Failed to execute PreSession script"); -+ error_code = PAM_ABORT; -+ goto out; -+ } -+ - session_pid = fork (); - - if (session_pid < 0) { - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_OPENING_SESSION, - "%s", g_strerror (errno)); - error_code = PAM_ABORT; - goto out; - } - - if (session_pid == 0) { - const char * const * environment; - char *home_dir; - int stdin_fd = -1, stdout_fd = -1, stderr_fd = -1; - gboolean has_journald = FALSE; - sigset_t mask; - - /* Leak the TTY into the session as stdin so that it stays open - * without any races. */ - if (worker->priv->session_tty_fd > 0) { - dup2 (worker->priv->session_tty_fd, STDIN_FILENO); - close (worker->priv->session_tty_fd); - worker->priv->session_tty_fd = -1; - } else { - stdin_fd = open ("/dev/null", O_RDWR); - dup2 (stdin_fd, STDIN_FILENO); - close (stdin_fd); - } - -@@ -2186,93 +2204,77 @@ gdm_session_worker_open_session (GdmSessionWorker *worker, - - g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED); - g_assert (geteuid () == 0); - - switch (worker->priv->display_mode) { - case GDM_SESSION_DISPLAY_MODE_REUSE_VT: - if (!set_up_for_current_vt (worker, error)) { - return FALSE; - } - break; - #ifdef ENABLE_WAYLAND_SUPPORT - case GDM_SESSION_DISPLAY_MODE_NEW_VT: - case GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED: - if (!set_up_for_new_vt (worker)) { - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_OPENING_SESSION, - "Unable to open VT"); - return FALSE; - } - break; - #endif - } - - flags = 0; - - if (worker->priv->is_program_session) { - flags |= PAM_SILENT; - } - -- if (!run_script (worker, GDMCONFDIR "/PostLogin")) { -- g_set_error (error, -- GDM_SESSION_WORKER_ERROR, -- GDM_SESSION_WORKER_ERROR_OPENING_SESSION, -- "Failed to execute PostLogin script"); -- return FALSE; -- } -- - error_code = pam_open_session (worker->priv->pam_handle, flags); - - if (error_code != PAM_SUCCESS) { - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_OPENING_SESSION, - "%s", pam_strerror (worker->priv->pam_handle, error_code)); - goto out; - } - - g_debug ("GdmSessionWorker: state SESSION_OPENED"); - worker->priv->state = GDM_SESSION_WORKER_STATE_SESSION_OPENED; - - #ifdef WITH_SYSTEMD - session_id = gdm_session_worker_get_environment_variable (worker, "XDG_SESSION_ID"); - #endif - -- /* FIXME: should we do something here? -- * Note that error return status from PreSession script should -- * be ignored in the case of a X-GDM-BypassXsession session, which can -- * be checked by calling: -- * gdm_session_bypasses_xsession (session) -- */ -- run_script (worker, GDMCONFDIR "/PreSession"); -- - #ifdef WITH_CONSOLE_KIT - register_ck_session (worker); - - if (session_id == NULL) { - session_id = get_ck_session_id (worker); - } - #endif - - if (session_id != NULL) { - g_free (worker->priv->session_id); - worker->priv->session_id = session_id; - } - - out: - if (error_code != PAM_SUCCESS) { - gdm_session_worker_uninitialize_pam (worker, error_code); - return FALSE; - } - - gdm_session_worker_get_username (worker, NULL); - gdm_session_auditor_report_login (worker->priv->auditor); - - return TRUE; - } - - static void - gdm_session_worker_set_server_address (GdmSessionWorker *worker, - const char *address) - { - g_free (worker->priv->server_address); --- -2.8.1 - - -From ebc5a37f8f4a287df4255cbcdf5d51f7a8fe9b44 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 19 Apr 2016 11:02:08 -0400 -Subject: [PATCH 2/2] manager: handle session failing to start - -Right now if a session fails really early in the start up -process, we fail to handle it. - -This commit fixes that. ---- - daemon/gdm-manager.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 33064ea..72ea968 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1475,60 +1475,69 @@ on_session_started (GdmSession *session, - - session_id = gdm_session_get_session_id (session); - g_object_set (GDM_SLAVE (slave), "session-id", session_id, NULL); - } - } - - static void - remove_user_session (GdmManager *manager, - GdmSession *session) - { - GList *node; - GdmDisplay *display; - - display = get_display_for_user_session (session); - - if (display != NULL) { - gdm_display_unmanage (display); - gdm_display_finish (display); - } - - node = g_list_find (manager->priv->user_sessions, session); - - if (node != NULL) { - manager->priv->user_sessions = g_list_delete_link (manager->priv->user_sessions, node); - gdm_session_close (session); - g_object_unref (session); - } - } - - static void -+on_session_start_failed (GdmSession *session, -+ const char *service_name, -+ GdmManager *manager) -+{ -+ g_debug ("GdmManager: session failed to start"); -+ remove_user_session (manager, session); -+} -+ -+static void - on_user_session_exited (GdmSession *session, - int code, - GdmManager *manager) - { - g_debug ("GdmManager: session exited with status %d", code); - remove_user_session (manager, session); - } - - static void - on_user_session_died (GdmSession *session, - int signal_number, - GdmManager *manager) - { - g_debug ("GdmManager: session died with signal %s", strsignal (signal_number)); - remove_user_session (manager, session); - } - - static char * - query_ck_for_display_device (GdmManager *manager, - GdmDisplay *display) - { - char *out; - char *command; - char *display_name = NULL; - int status; - gboolean res; - GError *error; - - g_object_get (G_OBJECT (display), - "x11-display-name", &display_name, -@@ -1894,60 +1903,64 @@ create_seed_session_for_display (GdmManager *manager, - manager); - g_signal_connect (session, - "client-connected", - G_CALLBACK (on_session_client_connected), - manager); - g_signal_connect (session, - "client-disconnected", - G_CALLBACK (on_session_client_disconnected), - manager); - g_signal_connect (session, - "cancelled", - G_CALLBACK (on_session_cancelled), - manager); - g_signal_connect (session, - "conversation-started", - G_CALLBACK (on_session_conversation_started), - manager); - g_signal_connect (session, - "conversation-stopped", - G_CALLBACK (on_session_conversation_stopped), - manager); - g_signal_connect (session, - "session-opened", - G_CALLBACK (on_session_opened), - manager); - g_signal_connect (session, - "session-started", - G_CALLBACK (on_session_started), - manager); - g_signal_connect (session, -+ "session-start-failed", -+ G_CALLBACK (on_session_start_failed), -+ manager); -+ g_signal_connect (session, - "session-exited", - G_CALLBACK (on_user_session_exited), - manager); - g_signal_connect (session, - "session-died", - G_CALLBACK (on_user_session_died), - manager); - g_object_set_data (G_OBJECT (session), "gdm-display", display); - g_object_set_data_full (G_OBJECT (display), "gdm-seed-session", g_object_ref (session), (GDestroyNotify) g_object_unref); - - start_autologin_conversation_if_necessary (manager, display, session); - } - - static void - on_display_added (GdmDisplayStore *display_store, - const char *id, - GdmManager *manager) - { - GdmDisplay *display; - - display = gdm_display_store_lookup (display_store, id); - - if (display != NULL) { - g_dbus_object_manager_server_export (manager->priv->object_manager, - gdm_display_get_object_skeleton (display)); - - g_signal_connect (display, "notify::status", - G_CALLBACK (on_display_status_changed), - manager); - g_signal_emit (manager, signals[DISPLAY_ADDED], 0, id); --- -2.8.1 - diff --git a/SOURCES/fix-restarts.patch b/SOURCES/fix-restarts.patch deleted file mode 100644 index 4b31218..0000000 --- a/SOURCES/fix-restarts.patch +++ /dev/null @@ -1,447 +0,0 @@ -From 46fadc83c114540c0ec0adb191e0a8f7a7d897c7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= -Date: Fri, 10 Jul 2015 12:52:04 -0400 -Subject: [PATCH 1/3] Make gdm-session-worker exit cleanly - -Calling gdm_session_stop_conversation() in gdm_launch_environment_stop() -sends a SIGTERM to gdm-session-worker without waiting for it to die. The -next step is calling gdm_session_close() to close the session, which -stops all conversations of that session object, sending a 2nd SIGTERM to -gdm-session-worker, this time waiting on its PID. - -On gdm-session-worker side, the first SIGTERM is caught by -on_shutdown_signal(), its custom SIGTERM handler, which quits the -mainloop and unrefs the worker object. Quiting the mainloop replaces the -custom SIGTERM handler with the system default one (exit immediately). -During the worker object class finalization gdm-session-worker may -receive the 2nd SIGTERM, which leads to its immediate termination, -without waiting for its children, which in turn leads to the main gdm -process exit. - -Since systemd relies on the SIGCHLD from the main gdm process to tell -when the service has stopped, this behavior breaks any unit that has a -Conflicts=gdm.service entry and relies on the X server not being around -when it is started. - -This commit removes the call to gdm_session_stop_conversation() in -gdm_launch_environment_stop() and leaves it to be stopped in -gdm_session_close(). - -[endlessm/eos-shell#4921] - -https://bugzilla.gnome.org/show_bug.cgi?id=752388 ---- - daemon/gdm-launch-environment.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c -index 4aee187..af3bf87 100644 ---- a/daemon/gdm-launch-environment.c -+++ b/daemon/gdm-launch-environment.c -@@ -402,61 +402,60 @@ gdm_launch_environment_start (GdmLaunchEnvironment *launch_environment) - - gdm_session_start_conversation (launch_environment->priv->session, "gdm-launch-environment"); - - if (launch_environment->priv->dbus_session_bus_address) { - gdm_session_select_program (launch_environment->priv->session, launch_environment->priv->command); - } else { - /* wrap it in dbus-launch */ - char *command = g_strdup_printf ("%s %s", DBUS_LAUNCH_COMMAND, launch_environment->priv->command); - - gdm_session_select_program (launch_environment->priv->session, command); - g_free (command); - } - - res = TRUE; - out: - if (local_error) { - g_critical ("GdmLaunchEnvironment: %s", local_error->message); - g_clear_error (&local_error); - } - return res; - } - - gboolean - gdm_launch_environment_stop (GdmLaunchEnvironment *launch_environment) - { - if (launch_environment->priv->pid > 1) { - gdm_signal_pid (-launch_environment->priv->pid, SIGTERM); - } - - if (launch_environment->priv->session != NULL) { -- gdm_session_stop_conversation (launch_environment->priv->session, "gdm-launch-environment"); - gdm_session_close (launch_environment->priv->session); - - g_clear_object (&launch_environment->priv->session); - } - - g_signal_emit (G_OBJECT (launch_environment), signals [STOPPED], 0); - - return TRUE; - } - - GdmSession * - gdm_launch_environment_get_session (GdmLaunchEnvironment *launch_environment) - { - return launch_environment->priv->session; - } - - char * - gdm_launch_environment_get_session_id (GdmLaunchEnvironment *launch_environment) - { - return g_strdup (launch_environment->priv->session_id); - } - - static void - _gdm_launch_environment_set_verification_mode (GdmLaunchEnvironment *launch_environment, - GdmSessionVerificationMode verification_mode) - { - launch_environment->priv->verification_mode = verification_mode; - } - - static void --- -2.3.7 - - -From 92564b47a85f9a308f7bfc34b8017f2767bf4677 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 4 Mar 2015 11:12:24 -0500 -Subject: [PATCH 2/3] manager: clean up manager in dispose not finalize - -Seems more appropriate. - -https://bugzilla.gnome.org/show_bug.cgi?id=745975 ---- - daemon/gdm-manager.c | 19 ++++++++++++------- - 1 file changed, 12 insertions(+), 7 deletions(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index f060135..e0af40c 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -75,61 +75,61 @@ struct GdmManagerPrivate - GHashTable *transient_sessions; - GHashTable *open_reauthentication_requests; - gboolean xdmcp_enabled; - GCancellable *cancellable; - - gboolean started; - gboolean wait_for_go; - gboolean show_local_greeter; - - GDBusProxy *bus_proxy; - GDBusConnection *connection; - GDBusObjectManagerServer *object_manager; - }; - - enum { - PROP_0, - PROP_XDMCP_ENABLED, - PROP_SHOW_LOCAL_GREETER - }; - - enum { - DISPLAY_ADDED, - DISPLAY_REMOVED, - LAST_SIGNAL - }; - - static guint signals [LAST_SIGNAL] = { 0, }; - - static void gdm_manager_class_init (GdmManagerClass *klass); - static void gdm_manager_init (GdmManager *manager); --static void gdm_manager_finalize (GObject *object); -+static void gdm_manager_dispose (GObject *object); - static void create_seed_session_for_display (GdmManager *manager, - GdmDisplay *display, - uid_t allowed_user); - static void touch_ran_once_marker_file (GdmManager *manager); - - static gpointer manager_object = NULL; - - static void manager_interface_init (GdmDBusManagerIface *interface); - - G_DEFINE_TYPE_WITH_CODE (GdmManager, - gdm_manager, - GDM_DBUS_TYPE_MANAGER_SKELETON, - G_IMPLEMENT_INTERFACE (GDM_DBUS_TYPE_MANAGER, - manager_interface_init)); - - #ifdef WITH_SYSTEMD - static char * - get_session_id_for_pid_systemd (pid_t pid, - GError **error) - { - char *session, *gsession; - int ret; - - session = NULL; - ret = sd_pid_get_session (pid, &session); - if (ret < 0) { - g_set_error (error, - GDM_DISPLAY_ERROR, - GDM_DISPLAY_ERROR_GETTING_SESSION_INFO, - "Error getting session id from systemd: %s", -@@ -2186,61 +2186,61 @@ gdm_manager_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) - { - GdmManager *manager; - - manager = GDM_MANAGER (G_OBJECT_CLASS (gdm_manager_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - - gdm_dbus_manager_set_version (GDM_DBUS_MANAGER (manager), PACKAGE_VERSION); - - manager->priv->local_factory = gdm_local_display_factory_new (manager->priv->display_store); - - #ifdef HAVE_LIBXDMCP - if (manager->priv->xdmcp_enabled) { - manager->priv->xdmcp_factory = gdm_xdmcp_display_factory_new (manager->priv->display_store); - } - #endif - - return G_OBJECT (manager); - } - - static void - gdm_manager_class_init (GdmManagerClass *klass) - { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = gdm_manager_get_property; - object_class->set_property = gdm_manager_set_property; - object_class->constructor = gdm_manager_constructor; -- object_class->finalize = gdm_manager_finalize; -+ object_class->dispose = gdm_manager_dispose; - - signals [DISPLAY_ADDED] = - g_signal_new ("display-added", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdmManagerClass, display_added), - NULL, - NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, - 1, G_TYPE_STRING); - signals [DISPLAY_REMOVED] = - g_signal_new ("display-removed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdmManagerClass, display_removed), - NULL, - NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, - 1, G_TYPE_STRING); - - g_object_class_install_property (object_class, - PROP_XDMCP_ENABLED, - g_param_spec_boolean ("xdmcp-enabled", - NULL, - NULL, - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - -@@ -2271,100 +2271,105 @@ gdm_manager_init (GdmManager *manager) - "display-added", - G_CALLBACK (on_display_added), - manager); - - g_signal_connect (G_OBJECT (manager->priv->display_store), - "display-removed", - G_CALLBACK (on_display_removed), - manager); - } - - static void - unexport_display (const char *id, - GdmDisplay *display, - GdmManager *manager) - { - if (!g_dbus_connection_is_closed (manager->priv->connection)) - g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); - } - - static void - finish_display (const char *id, - GdmDisplay *display, - GdmManager *manager) - { - if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) - gdm_display_unmanage (display); - gdm_display_finish (display); - } - - static void --gdm_manager_finalize (GObject *object) -+gdm_manager_dispose (GObject *object) - { - GdmManager *manager; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_MANAGER (object)); - - manager = GDM_MANAGER (object); - - g_return_if_fail (manager->priv != NULL); - - #ifdef HAVE_LIBXDMCP - g_clear_object (&manager->priv->xdmcp_factory); - #endif - g_clear_object (&manager->priv->local_factory); -- g_hash_table_unref (manager->priv->open_reauthentication_requests); -- g_hash_table_unref (manager->priv->transient_sessions); -+ g_clear_pointer (&manager->priv->open_reauthentication_requests, -+ (GDestroyNotify) -+ g_hash_table_unref); -+ g_clear_pointer (&manager->priv->transient_sessions, -+ (GDestroyNotify) -+ g_hash_table_unref); -+ - g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref); - manager->priv->user_sessions = NULL; - - g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), - G_CALLBACK (on_display_added), - manager); - g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), - G_CALLBACK (on_display_removed), - manager); - - if (!g_dbus_connection_is_closed (manager->priv->connection)) { - gdm_display_store_foreach (manager->priv->display_store, - (GdmDisplayStoreFunc)unexport_display, - manager); - g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager)); - } - - gdm_display_store_foreach (manager->priv->display_store, - (GdmDisplayStoreFunc) finish_display, - manager); - - gdm_display_store_clear (manager->priv->display_store); - - g_dbus_object_manager_server_set_connection (manager->priv->object_manager, NULL); - - g_clear_object (&manager->priv->connection); - g_clear_object (&manager->priv->object_manager); - -- g_object_unref (manager->priv->display_store); -+ g_clear_object (&manager->priv->display_store); - -- G_OBJECT_CLASS (gdm_manager_parent_class)->finalize (object); -+ G_OBJECT_CLASS (gdm_manager_parent_class)->dispose (object); - } - - GdmManager * - gdm_manager_new (void) - { - if (manager_object != NULL) { - g_object_ref (manager_object); - } else { - gboolean res; - - manager_object = g_object_new (GDM_TYPE_MANAGER, NULL); - g_object_add_weak_pointer (manager_object, - (gpointer *) &manager_object); - res = register_manager (manager_object); - if (! res) { - g_object_unref (manager_object); - return NULL; - } - } - - return GDM_MANAGER (manager_object); - } --- -2.3.7 - - -From c6243ccc362cb51bb87043e18108d99117abd6c1 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 4 Mar 2015 11:17:05 -0500 -Subject: [PATCH 3/3] manager: make sure to explicitly close user sessions in - dispose - -We don't want ref count leaks to lead to unkilled sessions. - -https://bugzilla.gnome.org/show_bug.cgi?id=745975 ---- - daemon/gdm-manager.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index e0af40c..12520ac 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -2293,60 +2293,63 @@ finish_display (const char *id, - GdmManager *manager) - { - if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) - gdm_display_unmanage (display); - gdm_display_finish (display); - } - - static void - gdm_manager_dispose (GObject *object) - { - GdmManager *manager; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_MANAGER (object)); - - manager = GDM_MANAGER (object); - - g_return_if_fail (manager->priv != NULL); - - #ifdef HAVE_LIBXDMCP - g_clear_object (&manager->priv->xdmcp_factory); - #endif - g_clear_object (&manager->priv->local_factory); - g_clear_pointer (&manager->priv->open_reauthentication_requests, - (GDestroyNotify) - g_hash_table_unref); - g_clear_pointer (&manager->priv->transient_sessions, - (GDestroyNotify) - g_hash_table_unref); - -+ g_list_foreach (manager->priv->user_sessions, -+ (GFunc) gdm_session_close, -+ NULL); - g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref); - manager->priv->user_sessions = NULL; - - g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), - G_CALLBACK (on_display_added), - manager); - g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), - G_CALLBACK (on_display_removed), - manager); - - if (!g_dbus_connection_is_closed (manager->priv->connection)) { - gdm_display_store_foreach (manager->priv->display_store, - (GdmDisplayStoreFunc)unexport_display, - manager); - g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager)); - } - - gdm_display_store_foreach (manager->priv->display_store, - (GdmDisplayStoreFunc) finish_display, - manager); - - gdm_display_store_clear (manager->priv->display_store); - - g_dbus_object_manager_server_set_connection (manager->priv->object_manager, NULL); - - g_clear_object (&manager->priv->connection); - g_clear_object (&manager->priv->object_manager); - - g_clear_object (&manager->priv->display_store); - --- -2.3.7 - diff --git a/SOURCES/fix-xdmcp-unlock.patch b/SOURCES/fix-xdmcp-unlock.patch deleted file mode 100644 index f3f6c6f..0000000 --- a/SOURCES/fix-xdmcp-unlock.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0b10f4d8e8ef2e6db519a1e5f8884e71c08403d9 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 1 Aug 2016 11:25:47 -0400 -Subject: [PATCH] manager: don't try to activate session if session not on seat - -If a session is not associated with a seat (because it's remote), -then we shouldn't try to activate the session. Activating sessions, -really only means anything on seat0 (where it means to change -the active VT). - -This prevents premature failure before unlock on XDMCP. ---- - daemon/gdm-manager.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 72ea968..ed9a437 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -851,64 +851,66 @@ get_display_and_details_for_bus_sender (GdmManager *self, - } - out: - g_free (session_id); - } - - static gboolean - switch_to_compatible_user_session (GdmManager *manager, - GdmSession *session, - gboolean fail_if_already_switched) - { - gboolean res; - gboolean ret; - const char *username; - const char *seat_id; - const char *ssid_to_activate; - GdmSession *existing_session; - - ret = FALSE; - - username = gdm_session_get_username (session); - seat_id = gdm_session_get_display_seat_id (session); - - if (!fail_if_already_switched) { - session = NULL; - } - - existing_session = find_session_for_user_on_seat (manager, username, seat_id, session); - - if (existing_session != NULL) { - ssid_to_activate = gdm_session_get_session_id (existing_session); -- res = activate_session_id (manager, seat_id, ssid_to_activate); -- if (! res) { -- g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate); -- goto out; -+ if (seat_id != NULL) { -+ res = activate_session_id (manager, seat_id, ssid_to_activate); -+ if (! res) { -+ g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate); -+ goto out; -+ } - } - - res = session_unlock (manager, ssid_to_activate); - if (!res) { - /* this isn't fatal */ - g_debug ("GdmManager: unable to unlock session: %s", ssid_to_activate); - } - } else { - goto out; - } - - ret = TRUE; - - out: - return ret; - } - - static GdmDisplay * - get_display_for_user_session (GdmSession *session) - { - return g_object_get_data (G_OBJECT (session), "gdm-display"); - } - - static GdmSession * - get_seed_session_for_display (GdmDisplay *display) - { - if (display == NULL) { - return NULL; - } - --- -2.7.4 - diff --git a/SOURCES/ja.po b/SOURCES/ja.po new file mode 100644 index 0000000..5b95641 --- /dev/null +++ b/SOURCES/ja.po @@ -0,0 +1,424 @@ +# gdm ja.po. +# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# Yukihiro Nakai , 1999. +# ITANI Eiichiro , 1999. +# Takayuki KUSANO , 2000, 2010, 2012. +# Yukihior Nakai , 2000-2002. +# Taku YASUI , 2001. +# SATO Satoru , 2001, 2006. +# Akira TAGOH , 2001. +# KAMAGASAKO Masatoshi , 2003. +# Takeshi AIHANA , 2004-2009. +# Ryoichi INAGAKI , 2004. +# Hideki Yamane (Debian-JP) , 2009. +# Hideki Yamane , 2011. +# Noriko Mizumoto , 2012. +# Jiro Matsuzawa , 2013, 2014. +# Hajime Taira , 2015. +# kmoriguc , 2017. #zanata +# ljanda , 2017. #zanata +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-05-16 15:21+0200\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"PO-Revision-Date: 2017-05-22 12:35+0000\n" +"Last-Translator: kmoriguc \n" +"Language-Team: Japanese \n" +"Language: ja\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Zanata 4.1.1\n" + +#: ../chooser/gdm-host-chooser-dialog.c:147 +msgid "Select System" +msgstr "システムの選択" + +#: ../chooser/gdm-host-chooser-widget.c:254 +msgid "XDMCP: Could not create XDMCP buffer!" +msgstr "XDMCP: XDMCP のバッファーを生成できませんでした" + +#: ../chooser/gdm-host-chooser-widget.c:260 +msgid "XDMCP: Could not read XDMCP header!" +msgstr "XDMCP: XDMCP のヘッダーを読み取れませんでした" + +#: ../chooser/gdm-host-chooser-widget.c:266 +msgid "XDMCP: Incorrect XDMCP version!" +msgstr "XDMCP: XDMCP のバージョンが間違っています!" + +#: ../chooser/gdm-host-chooser-widget.c:272 +msgid "XDMCP: Unable to parse address" +msgstr "XDMCP: アドレスを解析できません" + +#: ../common/gdm-common.c:298 +#, c-format +msgid "/dev/urandom is not a character device" +msgstr "/dev/urandom はキャラクターデバイスではありません" + +#: ../common/gdm-common.c:468 ../libgdm/gdm-user-switching.c:209 +#, c-format +msgid "Could not identify the current session." +msgstr "現在のセッションを取得できませんでした。" + +#: ../common/gdm-common.c:477 ../libgdm/gdm-user-switching.c:218 +#, c-format +msgid "Could not identify the current seat." +msgstr "現在のシートを識別できませんでした。" + +#: ../common/gdm-common.c:487 ../libgdm/gdm-user-switching.c:228 +#, c-format +msgid "" +"The system is unable to determine whether to switch to an existing login " +"screen or start up a new login screen." +msgstr "既存のログイン画面に切り替えるか、新しいログイン画面を起動するのかを、システムが決定することができませんでした。" + +#: ../common/gdm-common.c:495 ../libgdm/gdm-user-switching.c:236 +#, c-format +msgid "The system is unable to start up a new login screen." +msgstr "新しいログイン画面を起動できません。" + +#: ../daemon/gdm-display-access-file.c:300 +#, c-format +msgid "could not find user \"%s\" on system" +msgstr "システムに \"%s\" というユーザーは見つかりませんでした" + +#: ../daemon/gdm-legacy-display.c:235 +msgid "" +"Could not start the X server (your graphical environment) due to an internal " +"error. Please contact your system administrator or check your syslog to " +"diagnose. In the meantime this display will be disabled. Please restart GDM " +"when the problem is corrected." +msgstr "" +"何らかの内部エラーが原因で、X サーバー(グラフィカル環境)を起動できませんでした。システム管理者に問い合わせるか、syslog " +"の内容をチェックして調査してみてください。とりあえず、このディスプレイを無効にします。問題が解決したら GDM を再起動してください。" + +#: ../daemon/gdm-manager.c:772 +msgid "No display available" +msgstr "利用できるディスプレイがありません" + +#: ../daemon/gdm-manager.c:841 ../daemon/gdm-manager.c:1114 +msgid "No session available" +msgstr "利用できるセッションがありません" + +#: ../daemon/gdm-manager.c:859 +msgid "Chooser session unavailable" +msgstr "選択したセッションは利用できません" + +#: ../daemon/gdm-manager.c:869 +msgid "Can only be called before user is logged in" +msgstr "ユーザーがログインする前にしか呼び出しできません" + +#: ../daemon/gdm-manager.c:880 +msgid "Caller not GDM" +msgstr "呼び出し側が GDM ではありません" + +#: ../daemon/gdm-manager.c:890 +msgid "Unable to open private communication channel" +msgstr "プライベートコミュニケーションチャンネルを開けません" + +#: ../daemon/gdm-server.c:391 +#, c-format +msgid "Server was to be spawned by user %s but that user doesn't exist" +msgstr "ユーザー %s としてサーバーを起動しようとしましたが、そのようなユーザーは存在しません" + +#: ../daemon/gdm-server.c:402 ../daemon/gdm-server.c:422 +#, c-format +msgid "Couldn't set groupid to %d" +msgstr "グループ ID を %d に設定できませんでした" + +#: ../daemon/gdm-server.c:408 +#, c-format +msgid "initgroups () failed for %s" +msgstr "%s に対する initgroups () の呼び出しに失敗しました" + +#: ../daemon/gdm-server.c:414 +#, c-format +msgid "Couldn't set userid to %d" +msgstr "ユーザー ID を %d に設定できませんでした" + +#: ../daemon/gdm-server.c:492 +#, c-format +msgid "%s: Could not open log file for display %s!" +msgstr "%s: ディスプレイ (%s) のログファイルを開けません!" + +#: ../daemon/gdm-server.c:513 ../daemon/gdm-server.c:519 +#: ../daemon/gdm-server.c:525 +#, c-format +msgid "%s: Error setting %s to %s" +msgstr "%s: %s を %s に設定する際にエラー" + +#: ../daemon/gdm-server.c:545 +#, c-format +msgid "%s: Server priority couldn't be set to %d: %s" +msgstr "%s: サーバーの優先度を %d にセットできませんでした: %s" + +#: ../daemon/gdm-server.c:697 +#, c-format +msgid "%s: Empty server command for display %s" +msgstr "%s: ディスプレイ (%s) のサーバーコマンドが空です" + +#: ../daemon/gdm-session-auditor.c:90 +msgid "Username" +msgstr "ユーザー名" + +#: ../daemon/gdm-session-auditor.c:91 +msgid "The username" +msgstr "ユーザー名です" + +#: ../daemon/gdm-session-auditor.c:95 +msgid "Hostname" +msgstr "ホスト名" + +#: ../daemon/gdm-session-auditor.c:96 +msgid "The hostname" +msgstr "ホスト名です" + +#: ../daemon/gdm-session-auditor.c:101 +msgid "Display Device" +msgstr "ディスプレイのデバイス" + +#: ../daemon/gdm-session-auditor.c:102 +msgid "The display device" +msgstr "ディスプレイのデバイスです" + +#: ../daemon/gdm-session.c:1314 +msgid "Could not create authentication helper process" +msgstr "認証ヘルパーのプロセスを作成できませんでした" + +#: ../daemon/gdm-session-worker.c:641 +msgid "Your account was given a time limit that's now passed." +msgstr "アカウントに設定されていた有効期限が切れました。" + +#: ../daemon/gdm-session-worker.c:648 +msgid "Sorry, that didn't work. Please try again." +msgstr "認証に失敗しました。やり直してください。" + +#: ../daemon/gdm-session-worker.c:1036 +msgid "Username:" +msgstr "ユーザー名:" + +#: ../daemon/gdm-session-worker.c:1538 ../daemon/gdm-session-worker.c:1555 +#, c-format +msgid "no user account available" +msgstr "利用できるアカウントがありません" + +#: ../daemon/gdm-session-worker.c:1582 +msgid "Unable to change to user" +msgstr "ユーザーを変更できません" + +#: ../daemon/gdm-wayland-session.c:470 +msgid "GNOME Display Manager Wayland Session Launcher" +msgstr "GNOME ディスプレイマネージャー Wayland セッションランチャー" + +#: ../daemon/gdm-xdmcp-display-factory.c:612 +msgid "Could not create socket!" +msgstr "ソケットを生成できませんでした" + +#: ../daemon/gdm-x-session.c:814 +msgid "Run program through /etc/gdm/Xsession wrapper script" +msgstr "/etc/gdm/Xsession のラッパースクリプトを介してプログラムを起動する" + +#: ../daemon/gdm-x-session.c:815 +msgid "Listen on TCP socket" +msgstr "TCP ソケットでリッスンする" + +#: ../daemon/gdm-x-session.c:826 +msgid "GNOME Display Manager X Session Launcher" +msgstr "GNOME ディスプレイマネージャー X セッションランチャー" + +#: ../daemon/main.c:125 ../daemon/main.c:138 +#, c-format +msgid "Cannot write PID file %s: possibly out of disk space: %s" +msgstr "PID ファイル %s に書き込めません; ディスクの空き容量が足りないようです: %s" + +#: ../daemon/main.c:182 +#, c-format +msgid "Failed to create ran once marker dir %s: %s" +msgstr "起動済みマーカーディレクトリ %s の作成に失敗しました: %s" + +#: ../daemon/main.c:188 +#, c-format +msgid "Failed to create LogDir %s: %s" +msgstr "ログディレクトリ %s の作成に失敗しました: %s" + +#: ../daemon/main.c:223 +#, c-format +msgid "Can't find the GDM user '%s'. Aborting!" +msgstr "GDM ユーザー '%s' が見つからないので処理を中止します!" + +#: ../daemon/main.c:229 +msgid "The GDM user should not be root. Aborting!" +msgstr "root を GDM ユーザーにしないでください; 処理を中止します!" + +#: ../daemon/main.c:235 +#, c-format +msgid "Can't find the GDM group '%s'. Aborting!" +msgstr "GDM グループ '%s' が見つからないので処理を中止します!" + +#: ../daemon/main.c:241 +msgid "The GDM group should not be root. Aborting!" +msgstr "root を GDM グループにしないでください; 処理を中止します!" + +#: ../daemon/main.c:318 +msgid "Make all warnings fatal" +msgstr "警告をすべて致命的にする" + +#: ../daemon/main.c:319 +msgid "Exit after a time (for debugging)" +msgstr "時間が経過したら終了する (デバッグ用)" + +#: ../daemon/main.c:320 +msgid "Print GDM version" +msgstr "GDM のバージョンを表示する" + +#: ../daemon/main.c:333 +msgid "GNOME Display Manager" +msgstr "GNOME ディスプレイマネージャー" + +#. make sure the pid file doesn't get wiped +#: ../daemon/main.c:381 +msgid "Only the root user can run GDM" +msgstr "root ユーザーのみが GDM を起動できます" + +#. Translators: worker is a helper process that does the work +#. of starting up a session +#: ../daemon/session-worker-main.c:94 +msgid "GNOME Display Manager Session Worker" +msgstr "GDM セッションワーカー" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:1 +msgid "Whether or not to allow fingerprint readers for login" +msgstr "指紋リーダーによるログイン認証を許可する" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:2 +msgid "" +"The login screen can optionally allow users who have enrolled their " +"fingerprints to log in using those prints." +msgstr "ログイン画面では、指紋を登録したユーザーがそれを使ってログインするのを任意に許可することができます。" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:3 +msgid "Whether or not to allow smartcard readers for login" +msgstr "スマートカードリーダーによるログイン認証を許可する" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:4 +msgid "" +"The login screen can optionally allow users who have smartcards to log in " +"using those smartcards." +msgstr "ログイン画面では、スマートカードを持つユーザーがスマートカードを使ってログインするのを任意に許可することができます。" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:5 +msgid "Whether or not to allow passwords for login" +msgstr "パスワードによるログイン認証を許可する" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:6 +msgid "" +"The login screen can be configured to disallow password authentication, " +"forcing the user to use smartcard or fingerprint authentication." +msgstr "ログイン画面では、パスワード認証を無効化して、スマートカードや指紋による認証をユーザーに強制するよう設定できます。" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:7 +msgid "Path to small image at top of user list" +msgstr "ユーザーリストの一番上にある小さな画像へのパス" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:8 +msgid "" +"The login screen can optionally show a small image to provide site " +"administrators and distributions a way to display branding." +msgstr "ログイン画面では、サイトの管理者やディストリビューションがブランドを示す方法として、小さな画像を任意で表示できます。" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:9 +msgid "" +"The fallback login screen can optionally show a small image to provide site " +"administrators and distributions a way to display branding." +msgstr "フォールバックログイン画面では、サイトの管理者やディストリビューションがブランドを示す方法として、小さな画像を表示することもできます。" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:10 +msgid "Avoid showing user list" +msgstr "ユーザー一覧を表示しない" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:11 +msgid "" +"The login screen normally shows a list of available users to log in as. This " +"setting can be toggled to disable showing the user list." +msgstr "ログインスクリーンでは、利用可能なユーザーが通常表示されています。この設定ではユーザー一覧表示を無効に設定可能です。" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:12 +msgid "Enable showing the banner message" +msgstr "バナーメッセージを表示するかどうか" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:13 +msgid "Set to true to show the banner message text." +msgstr "true にすると、バナーメッセージを表示します。" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:14 +msgid "Banner message text" +msgstr "バナーメッセージの文字列" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:15 +msgid "Text banner message to show in the login window." +msgstr "ログインウィンドウに表示するバナーメッセージの文字列です。" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:16 +msgid "Disable showing the restart buttons" +msgstr "再起動のボタンを表示しないかどうか" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:17 +msgid "" +"Set to true to disable showing the restart buttons in the login window." +msgstr "true にすると、ログインウィンドウに再起動のボタンが表示されなくなります。" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:18 +msgid "Number of allowed authentication failures" +msgstr "許容できる認証失敗の回数です" + +#: ../data/org.gnome.login-screen.gschema.xml.in.h:19 +msgid "" +"The number of times a user is allowed to attempt authentication, before " +"giving up and going back to user selection." +msgstr "ユーザーが認証を試行できる回数です。この回数を失敗すると、ユーザー選択に戻ることになります。" + +#: ../libgdm/gdm-user-switching.c:59 +msgid "Unable to create transient display: " +msgstr "一時的なディスプレイを作成できません:" + +#: ../libgdm/gdm-user-switching.c:90 +msgid "Unable to activate session: " +msgstr "セッションを開始することができません:" + +#: ../utils/gdmflexiserver.c:45 +msgid "Only the VERSION command is supported" +msgstr "VERSION コマンドのみがサポートされています" + +#: ../utils/gdmflexiserver.c:45 +msgid "COMMAND" +msgstr "COMMAND" + +#: ../utils/gdmflexiserver.c:46 ../utils/gdmflexiserver.c:47 +#: ../utils/gdmflexiserver.c:49 ../utils/gdmflexiserver.c:50 +msgid "Ignored — retained for compatibility" +msgstr "無視しました - 下位互換のために残してあるだけです" + +#: ../utils/gdmflexiserver.c:48 ../utils/gdm-screenshot.c:43 +msgid "Debugging output" +msgstr "デバッグ情報を出力する" + +#: ../utils/gdmflexiserver.c:52 +msgid "Version of this application" +msgstr "バージョンを表示する" + +#. Option parsing +#: ../utils/gdmflexiserver.c:137 +msgid "- New GDM login" +msgstr "- 新しい GDM のログイン" + +#: ../utils/gdm-screenshot.c:212 +msgid "Screenshot taken" +msgstr "スクリーンショットの撮影" + +#. Option parsing +#: ../utils/gdm-screenshot.c:279 +msgid "Take a picture of the screen" +msgstr "画面のスクリーンショットを撮る" + diff --git a/SOURCES/notify-xdmcp-about-session-end.patch b/SOURCES/notify-xdmcp-about-session-end.patch deleted file mode 100644 index 40d9e73..0000000 --- a/SOURCES/notify-xdmcp-about-session-end.patch +++ /dev/null @@ -1,1184 +0,0 @@ -From 4e4918c7d6dea3f03f3ae49f2d5721beb03936f2 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 19 Jul 2016 16:54:43 -0400 -Subject: [PATCH 1/5] xdmcp-display-factory: notify remote display when session - ended - -gnome-shell and the session dbus daemon don't automatically exit -when gnome-session does. They, instead, wait for the display to -exit or regenerate. If the display is remote, that won't happen -until the keep alive timeout. - -This commit changes GDM to explicitly notify the remote display -when the session is over, so that it can regenerate immediately. ---- - daemon/gdm-xdmcp-display-factory.c | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - -diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c -index d01f7ff..4132dd1 100644 ---- a/daemon/gdm-xdmcp-display-factory.c -+++ b/daemon/gdm-xdmcp-display-factory.c -@@ -183,61 +183,64 @@ struct GdmXdmcpDisplayFactoryPrivate - /* configuration */ - guint port; - gboolean use_multicast; - char *multicast_address; - gboolean honor_indirect; - char *willing_script; - guint max_displays_per_host; - guint max_displays; - guint max_pending_displays; - guint max_wait; - guint max_wait_indirect; - }; - - enum { - PROP_0, - PROP_PORT, - PROP_USE_MULTICAST, - PROP_MULTICAST_ADDRESS, - PROP_HONOR_INDIRECT, - PROP_WILLING_SCRIPT, - PROP_MAX_DISPLAYS_PER_HOST, - PROP_MAX_DISPLAYS, - PROP_MAX_PENDING_DISPLAYS, - PROP_MAX_WAIT, - PROP_MAX_WAIT_INDIRECT, - }; - - static void gdm_xdmcp_display_factory_class_init (GdmXdmcpDisplayFactoryClass *klass); - static void gdm_xdmcp_display_factory_init (GdmXdmcpDisplayFactory *manager); - static void gdm_xdmcp_display_factory_finalize (GObject *object); -- -+static void gdm_xdmcp_send_alive (GdmXdmcpDisplayFactory *factory, -+ GdmAddress *address, -+ CARD16 dspnum, -+ CARD32 sessid); - static gpointer xdmcp_display_factory_object = NULL; - - G_DEFINE_TYPE (GdmXdmcpDisplayFactory, gdm_xdmcp_display_factory, GDM_TYPE_DISPLAY_FACTORY) - - /* Theory of operation: - * - * Process idles waiting for UDP packets on port 177. - * Incoming packets are decoded and checked against tcp_wrapper. - * - * A typical session looks like this: - * - * Display sends Query/BroadcastQuery to Manager. - * - * Manager selects an appropriate authentication scheme from the - * display's list of supported ones and sends Willing/Unwilling. - * - * Assuming the display accepts the auth. scheme it sends back a - * Request. - * - * If the manager accepts to service the display (i.e. loadavg is low) - * it sends back an Accept containing a unique SessionID. The - * SessionID is stored in an accept queue by the Manager. Should the - * manager refuse to start a session a Decline is sent to the display. - * - * The display returns a Manage request containing the supplied - * SessionID. The manager will then start a session on the display. In - * case the SessionID is not on the accept queue the manager returns - * Refuse. If the manager fails to open the display for connections - * Failed is returned. - * -@@ -2026,68 +2029,78 @@ on_hostname_selected (GdmXdmcpChooserDisplay *display, - g_warning ("Unable to get address: %s", gai_strerror (gaierr)); - g_free (xdmcp_port); - return; - } - g_free (xdmcp_port); - - /* just take the first one */ - ai = ai_list; - - if (ai != NULL) { - char *ip; - ic->chosen_address = gdm_address_new_from_sockaddr (ai->ai_addr, ai->ai_addrlen); - - ip = NULL; - gdm_address_get_numeric_info (ic->chosen_address, &ip, NULL); - g_debug ("GdmXdmcpDisplayFactory: hostname resolves to %s", - ip ? ip : "(null)"); - g_free (ip); - } - - freeaddrinfo (ai_list); - } - - static void - on_display_status_changed (GdmDisplay *display, - GParamSpec *arg1, - GdmXdmcpDisplayFactory *factory) - { - int status; - GdmDisplayStore *store; -+ GdmAddress *address; -+ gint32 session_number; -+ int display_number; - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - - status = gdm_display_get_status (display); - - g_debug ("GdmXdmcpDisplayFactory: xdmcp display status changed: %d", status); - switch (status) { - case GDM_DISPLAY_FINISHED: -+ g_object_get (display, -+ "remote-address", &address, -+ "x11-display-number", &display_number, -+ "session-number", &session_number, -+ NULL); -+ gdm_xdmcp_send_alive (factory, address, display_number, session_number); -+ - gdm_display_store_remove (store, display); - break; - case GDM_DISPLAY_FAILED: - gdm_display_store_remove (store, display); - break; - case GDM_DISPLAY_UNMANAGED: - break; - case GDM_DISPLAY_PREPARED: - break; - case GDM_DISPLAY_MANAGED: - break; - default: - g_assert_not_reached (); - break; - } - } - - static GdmDisplay * - gdm_xdmcp_display_create (GdmXdmcpDisplayFactory *factory, - const char *hostname, - GdmAddress *address, - int displaynum) - { - GdmDisplay *display; - GdmDisplayStore *store; - gboolean use_chooser; - - g_debug ("GdmXdmcpDisplayFactory: Creating xdmcp display for %s:%d", - hostname ? hostname : "(null)", displaynum); - --- -2.9.3 - - -From 7b9f559b6b5c8217840e3441b4eb5a29080a19c4 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 20 Jul 2016 11:43:45 -0400 -Subject: [PATCH 2/5] worker: kill process group when session exits - -Send a hangup signal to the session pg when it exits, so things -have a chance to get cleaned up. ---- - daemon/gdm-session-worker.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index f37b92a..ffb728f 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -1603,60 +1603,62 @@ run_script (GdmSessionWorker *worker, - worker->priv->username, - worker->priv->x11_display_name, - worker->priv->display_is_local? NULL : worker->priv->hostname, - worker->priv->x11_authority_file); - } - - static void - session_worker_child_watch (GPid pid, - int status, - GdmSessionWorker *worker) - { - g_debug ("GdmSessionWorker: child (pid:%d) done (%s:%d)", - (int) pid, - WIFEXITED (status) ? "status" - : WIFSIGNALED (status) ? "signal" - : "unknown", - WIFEXITED (status) ? WEXITSTATUS (status) - : WIFSIGNALED (status) ? WTERMSIG (status) - : -1); - - #ifdef WITH_CONSOLE_KIT - close_ck_session (worker); - #endif - - gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS); - - gdm_dbus_worker_emit_session_exited (GDM_DBUS_WORKER (worker), - worker->priv->service, - status); - -+ killpg (pid, SIGHUP); -+ - worker->priv->child_pid = -1; - - run_script (worker, GDMCONFDIR "/PostSession"); - } - - static void - gdm_session_worker_watch_child (GdmSessionWorker *worker) - { - g_debug ("GdmSession worker: watching pid %d", worker->priv->child_pid); - worker->priv->child_watch_id = g_child_watch_add (worker->priv->child_pid, - (GChildWatchFunc)session_worker_child_watch, - worker); - - } - - static gboolean - _is_loggable_file (const char* filename) - { - struct stat file_info; - - if (g_lstat (filename, &file_info) < 0) { - return FALSE; - } - - return S_ISREG (file_info.st_mode) && g_access (filename, R_OK | W_OK) == 0; - } - - static void - rotate_logs (const char *path, - guint n_copies) --- -2.9.3 - - -From ede6833989a691b0ee4a27834c572814564fc541 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 12 Dec 2016 10:35:32 -0500 -Subject: [PATCH 3/5] display: port GdmDisplay to xcb - -Xlib will kill the process if it notices the display connection has -gone away. This is suboptimal for the main gdm process! - -This commit ports the Xlib code to xcb, so it won't have the above -fragility. - -https://bugzilla.gnome.org/show_bug.cgi?id=776059 ---- - configure.ac | 1 + - daemon/gdm-slave.c | 312 ++++++++++++++++++++++++----------------------------- - 2 files changed, 142 insertions(+), 171 deletions(-) - -diff --git a/configure.ac b/configure.ac -index a131535..f9ad18a 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -57,60 +57,61 @@ AC_SUBST(GETTEXT_PACKAGE) - AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [gettext package]) - - dnl --------------------------------------------------------------------------- - dnl - Dependencies - dnl --------------------------------------------------------------------------- - - GLIB_REQUIRED_VERSION=2.36.0 - GTK_REQUIRED_VERSION=2.91.1 - LIBCANBERRA_GTK_REQUIRED_VERSION=0.4 - ACCOUNTS_SERVICE_REQUIRED_VERSION=0.6.12 - - EXTRA_COMPILE_WARNINGS(yes) - - PKG_CHECK_MODULES(GTHREAD, gthread-2.0) - AC_SUBST(GTHREAD_CFLAGS) - AC_SUBST(GTHREAD_LIBS) - - PKG_CHECK_MODULES(COMMON, - gobject-2.0 >= $GLIB_REQUIRED_VERSION - gio-2.0 >= $GLIB_REQUIRED_VERSION - gio-unix-2.0 >= $GLIB_REQUIRED_VERSION - ) - AC_SUBST(COMMON_CFLAGS) - AC_SUBST(COMMON_LIBS) - - PKG_CHECK_MODULES(DAEMON, - gobject-2.0 >= $GLIB_REQUIRED_VERSION - gio-2.0 >= $GLIB_REQUIRED_VERSION - gio-unix-2.0 >= $GLIB_REQUIRED_VERSION - accountsservice >= $ACCOUNTS_SERVICE_REQUIRED_VERSION -+ xcb - ) - AC_SUBST(DAEMON_CFLAGS) - AC_SUBST(DAEMON_LIBS) - - GLIB_GSETTINGS - - PKG_CHECK_MODULES(XLIB, x11 xau xrandr, , - [AC_PATH_XTRA - if test "x$no_x" = xyes; then - AC_MSG_ERROR("no (requires X development libraries)") - else - XLIB_LIBS="$X_PRE_LIBS $X_LIBS -lXau -lX11 -lXext -lXrandr $X_EXTRA_LIBS" - XLIB_CFLAGS=$X_CFLAGS - fi]) - AC_SUBST(XLIB_CFLAGS) - AC_SUBST(XLIB_LIBS) - - PKG_CHECK_MODULES(GTK, - gtk+-3.0 >= $GTK_REQUIRED_VERSION - ) - AC_SUBST(GTK_CFLAGS) - AC_SUBST(GTK_LIBS) - - PKG_CHECK_MODULES(CANBERRA_GTK, - libcanberra-gtk3 >= $LIBCANBERRA_GTK_REQUIRED_VERSION - ) - AC_SUBST(CANBERRA_GTK_CFLAGS) - AC_SUBST(CANBERRA_GTK_LIBS) - - AC_ARG_WITH(selinux, -diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c -index b4bbcfd..c0a53fe 100644 ---- a/daemon/gdm-slave.c -+++ b/daemon/gdm-slave.c -@@ -10,398 +10,358 @@ - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - - #include "config.h" - - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include - #include - #include - #include - --#include /* for Display */ --#include /* for XA_PIXMAP */ -+#include -+ - #include /* for watch cursor */ - #include - #include - - #ifdef WITH_SYSTEMD - #include - #endif - - #include "gdm-common.h" - #include "gdm-xerrors.h" - - #include "gdm-slave.h" - #include "gdm-display.h" - #include "gdm-display-glue.h" - - #include "gdm-server.h" - - #define GDM_SLAVE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SLAVE, GdmSlavePrivate)) - - struct GdmSlavePrivate - { - GPid pid; - guint output_watch_id; - guint error_watch_id; - -- Display *server_display; -+ xcb_connection_t *xcb_connection; -+ int xcb_screen_number; - - char *session_id; - - GdmDisplay *display; - - /* cached display values */ - char *display_name; - int display_number; - char *display_hostname; - gboolean display_is_local; - char *display_seat_id; - char *display_x11_authority_file; - char *windowpath; - GBytes *display_x11_cookie; - gboolean display_is_initial; - }; - - enum { - PROP_0, - PROP_SESSION_ID, - PROP_DISPLAY, - PROP_DISPLAY_NAME, - PROP_DISPLAY_NUMBER, - PROP_DISPLAY_HOSTNAME, - PROP_DISPLAY_IS_LOCAL, - PROP_DISPLAY_SEAT_ID, - PROP_DISPLAY_X11_AUTHORITY_FILE, - PROP_DISPLAY_IS_INITIAL, - }; - - enum { - STARTED, - STOPPED, - LAST_SIGNAL - }; - - static guint signals [LAST_SIGNAL] = { 0, }; - - static void gdm_slave_class_init (GdmSlaveClass *klass); - static void gdm_slave_init (GdmSlave *slave); - static void gdm_slave_finalize (GObject *object); - - G_DEFINE_ABSTRACT_TYPE (GdmSlave, gdm_slave, G_TYPE_OBJECT) - - #define CURSOR_WATCH XC_watch - - GQuark - gdm_slave_error_quark (void) - { - static GQuark ret = 0; - if (ret == 0) { - ret = g_quark_from_static_string ("gdm-slave-error-quark"); - } - - return ret; - } - --static XRRScreenResources * --get_screen_resources (Display *dpy) -+static xcb_screen_t * -+get_screen (xcb_connection_t *connection, -+ int screen_number) - { -- int major = 0, minor = 0; -+ xcb_screen_t *screen = NULL; -+ xcb_screen_iterator_t iter; - -- if (!XRRQueryVersion(dpy, &major, &minor)) { -- return NULL; -+ iter = xcb_setup_roots_iterator (xcb_get_setup (connection)); -+ while (iter.rem) { -+ if (screen_number == 0) -+ screen = iter.data; -+ screen_number--; -+ xcb_screen_next (&iter); - } - -- if (major > 1) { -- return NULL; -+ if (screen != NULL) { -+ return screen; - } - -- if (minor >= 3) { -- return XRRGetScreenResourcesCurrent (dpy, -- DefaultRootWindow (dpy)); -+ return NULL; -+} -+ -+static xcb_window_t -+get_root_window (xcb_connection_t *connection, -+ int screen_number) -+{ -+ xcb_screen_t *screen = NULL; -+ -+ screen = get_screen (connection, screen_number); -+ -+ if (screen != NULL) { -+ return screen->root; - } - -- return XRRGetScreenResources (dpy, DefaultRootWindow (dpy)); -+ return XCB_WINDOW_NONE; - } - - static void - determine_initial_cursor_position (GdmSlave *slave, - int *x, - int *y) - { -- XRRScreenResources *resources; -- RROutput primary_output; -- int i; -- -- /* If this function fails for whatever reason, -- * put the pointer in the lower right corner of the screen. -- */ -- *x = .9 * DisplayWidth (slave->priv->server_display, -- DefaultScreen (slave->priv->server_display)); -- *y = .9 * DisplayHeight (slave->priv->server_display, -- DefaultScreen (slave->priv->server_display)); -- -- gdm_error_trap_push (); -- resources = get_screen_resources (slave->priv->server_display); -- primary_output = XRRGetOutputPrimary (slave->priv->server_display, -- DefaultRootWindow (slave->priv->server_display)); -- gdm_error_trap_pop (); -- -- if (resources == NULL) { -- return; -- } -- -- for (i = 0; i < resources->noutput; i++) { -- XRROutputInfo *output_info; -- -- if (primary_output == None) { -- primary_output = resources->outputs[0]; -- } -- -- if (resources->outputs[i] != primary_output) { -- continue; -- } -- -- output_info = XRRGetOutputInfo (slave->priv->server_display, -- resources, -- resources->outputs[i]); -- -- if (output_info->connection != RR_Disconnected && -- output_info->crtc != 0) { -- XRRCrtcInfo *crtc_info; -- -- crtc_info = XRRGetCrtcInfo (slave->priv->server_display, -- resources, -- output_info->crtc); -- /* position it sort of in the lower right -- */ -- *x = crtc_info->x + .9 * crtc_info->width; -- *y = crtc_info->y + .9 * crtc_info->height; -- XRRFreeCrtcInfo (crtc_info); -- } -- -- XRRFreeOutputInfo (output_info); -- break; -- } -- -- XRRFreeScreenResources (resources); -+ *x = 50; -+ *y = 50; - } - - void - gdm_slave_set_initial_cursor_position (GdmSlave *slave) - { -- if (slave->priv->server_display != NULL) { -+ if (slave->priv->xcb_connection != NULL) { - int x, y; -+ xcb_window_t root_window = XCB_WINDOW_NONE; - - determine_initial_cursor_position (slave, &x, &y); -- XWarpPointer(slave->priv->server_display, -- None, -- DefaultRootWindow (slave->priv->server_display), -- 0, 0, -- 0, 0, -- x, y); -+ -+ root_window = get_root_window (slave->priv->xcb_connection, -+ slave->priv->xcb_screen_number); -+ -+ if (root_window != XCB_WINDOW_NONE) { -+ xcb_warp_pointer (slave->priv->xcb_connection, -+ XCB_WINDOW_NONE, -+ root_window, -+ 0, 0, -+ 0, 0, -+ x, y); -+ } - } - } - - static void --gdm_slave_setup_xhost_auth (XHostAddress *host_entries, XServerInterpretedAddress *si_entries) -+gdm_slave_setup_xhost_auth (XHostAddress *host_entries) - { -- si_entries[0].type = "localuser"; -- si_entries[0].typelength = strlen ("localuser"); -- si_entries[1].type = "localuser"; -- si_entries[1].typelength = strlen ("localuser"); -- si_entries[2].type = "localuser"; -- si_entries[2].typelength = strlen ("localuser"); -- -- si_entries[0].value = "root"; -- si_entries[0].valuelength = strlen ("root"); -- si_entries[1].value = GDM_USERNAME; -- si_entries[1].valuelength = strlen (GDM_USERNAME); -- si_entries[2].value = "gnome-initial-setup"; -- si_entries[2].valuelength = strlen ("gnome-initial-setup"); -- - host_entries[0].family = FamilyServerInterpreted; -- host_entries[0].address = (char *) &si_entries[0]; -- host_entries[0].length = sizeof (XServerInterpretedAddress); -+ host_entries[0].address = "localuser\0root"; -+ host_entries[0].length = sizeof ("localuser\0root"); - host_entries[1].family = FamilyServerInterpreted; -- host_entries[1].address = (char *) &si_entries[1]; -- host_entries[1].length = sizeof (XServerInterpretedAddress); -+ host_entries[1].address = "localuser\0" GDM_USERNAME; -+ host_entries[1].length = sizeof ("localuser\0" GDM_USERNAME); - host_entries[2].family = FamilyServerInterpreted; -- host_entries[2].address = (char *) &si_entries[2]; -- host_entries[2].length = sizeof (XServerInterpretedAddress); -+ host_entries[2].address = "localuser\0gnome-initial-setup"; -+ host_entries[2].length = sizeof ("localuser\0gnome-initial-setup"); - } - - static void - gdm_slave_set_windowpath (GdmSlave *slave) - { - /* setting WINDOWPATH for clients */ -- Atom prop; -- Atom actualtype; -- int actualformat; -- unsigned long nitems; -- unsigned long bytes_after; -- unsigned char *buf; -+ xcb_intern_atom_cookie_t atom_cookie; -+ xcb_intern_atom_reply_t *atom_reply = NULL; -+ xcb_get_property_cookie_t get_property_cookie; -+ xcb_get_property_reply_t *get_property_reply = NULL; -+ xcb_window_t root_window = XCB_WINDOW_NONE; - const char *windowpath; - char *newwindowpath; -- unsigned long num; -+ uint32_t num; - char nums[10]; - int numn; - -- prop = XInternAtom (slave->priv->server_display, "XFree86_VT", False); -- if (prop == None) { -+ atom_cookie = xcb_intern_atom (slave->priv->xcb_connection, 0, strlen("XFree86_VT"), "XFree86_VT"); -+ atom_reply = xcb_intern_atom_reply (slave->priv->xcb_connection, atom_cookie, NULL); -+ -+ if (atom_reply == NULL) { - g_debug ("no XFree86_VT atom\n"); -- return; -+ -+ goto out; -+ } -+ -+ root_window = get_root_window (slave->priv->xcb_connection, -+ slave->priv->xcb_screen_number); -+ -+ if (root_window == XCB_WINDOW_NONE) { -+ g_debug ("couldn't find root window\n"); -+ goto out; - } -- if (XGetWindowProperty (slave->priv->server_display, -- DefaultRootWindow (slave->priv->server_display), prop, 0, 1, -- False, AnyPropertyType, &actualtype, &actualformat, -- &nitems, &bytes_after, &buf)) { -+ -+ get_property_cookie = xcb_get_property (slave->priv->xcb_connection, -+ FALSE, -+ root_window, -+ atom_reply->atom, -+ XCB_ATOM_INTEGER, -+ 0, -+ 1); -+ -+ get_property_reply = xcb_get_property_reply (slave->priv->xcb_connection, get_property_cookie, NULL); -+ -+ if (get_property_reply == NULL) { - g_debug ("no XFree86_VT property\n"); -- return; -- } -- -- if (nitems != 1) { -- g_debug ("%lu items in XFree86_VT property!\n", nitems); -- XFree (buf); -- return; -- } -- -- switch (actualtype) { -- case XA_CARDINAL: -- case XA_INTEGER: -- case XA_WINDOW: -- switch (actualformat) { -- case 8: -- num = (*(uint8_t *)(void *)buf); -- break; -- case 16: -- num = (*(uint16_t *)(void *)buf); -- break; -- case 32: -- num = (*(long *)(void *)buf); -- break; -- default: -- g_debug ("format %d in XFree86_VT property!\n", actualformat); -- XFree (buf); -- return; -- } -- break; -- default: -- g_debug ("type %lx in XFree86_VT property!\n", actualtype); -- XFree (buf); -- return; -+ goto out; - } -- XFree (buf); -+ -+ num = ((uint32_t *) xcb_get_property_value (get_property_reply))[0]; - - windowpath = getenv ("WINDOWPATH"); -- numn = snprintf (nums, sizeof (nums), "%lu", num); -+ -+ numn = snprintf (nums, sizeof (nums), "%u", num); - if (!windowpath) { - newwindowpath = malloc (numn + 1); - sprintf (newwindowpath, "%s", nums); - } else { - newwindowpath = malloc (strlen (windowpath) + 1 + numn + 1); - sprintf (newwindowpath, "%s:%s", windowpath, nums); - } - -- slave->priv->windowpath = newwindowpath; -- - g_setenv ("WINDOWPATH", newwindowpath, TRUE); -+out: -+ g_clear_pointer (&atom_reply, free); -+ g_clear_pointer (&get_property_reply, free); - } - - gboolean - gdm_slave_connect_to_x11_display (GdmSlave *slave) - { -+ xcb_auth_info_t *auth_info = NULL; - gboolean ret; - - ret = FALSE; - - /* We keep our own (windowless) connection (dsp) open to avoid the - * X server resetting due to lack of active connections. */ - - g_debug ("GdmSlave: Server is ready - opening display %s", slave->priv->display_name); - - /* Give slave access to the display independent of current hostname */ - if (slave->priv->display_x11_cookie != NULL) { -- XSetAuthorization ("MIT-MAGIC-COOKIE-1", -- strlen ("MIT-MAGIC-COOKIE-1"), -- (gpointer) -- g_bytes_get_data (slave->priv->display_x11_cookie, NULL), -- g_bytes_get_size (slave->priv->display_x11_cookie)); -+ auth_info = g_alloca (sizeof (xcb_auth_info_t)); -+ -+ auth_info->namelen = strlen ("MIT-MAGIC-COOKIE-1"); -+ auth_info->name = "MIT-MAGIC-COOKIE-1"; -+ auth_info->datalen = g_bytes_get_size (slave->priv->display_x11_cookie); -+ auth_info->data = (gpointer) g_bytes_get_data (slave->priv->display_x11_cookie, NULL); - } - -- slave->priv->server_display = XOpenDisplay (slave->priv->display_name); -+ slave->priv->xcb_connection = xcb_connect_to_display_with_auth_info (slave->priv->display_name, -+ auth_info, -+ &slave->priv->xcb_screen_number); - -- if (slave->priv->server_display == NULL) { -+ if (xcb_connection_has_error (slave->priv->xcb_connection)) { -+ g_clear_pointer (&slave->priv->xcb_connection, xcb_disconnect); - g_warning ("Unable to connect to display %s", slave->priv->display_name); - ret = FALSE; - } else if (slave->priv->display_is_local) { -- XServerInterpretedAddress si_entries[3]; - XHostAddress host_entries[3]; -+ xcb_void_cookie_t cookies[3]; - int i; - - g_debug ("GdmSlave: Connected to display %s", slave->priv->display_name); - ret = TRUE; - - /* Give programs run by the slave and greeter access to the - * display independent of current hostname - */ -- gdm_slave_setup_xhost_auth (host_entries, si_entries); -- -- gdm_error_trap_push (); -+ gdm_slave_setup_xhost_auth (host_entries); - - for (i = 0; i < G_N_ELEMENTS (host_entries); i++) { -- XAddHost (slave->priv->server_display, &host_entries[i]); -+ cookies[i] = xcb_change_hosts_checked (slave->priv->xcb_connection, -+ XCB_HOST_MODE_INSERT, -+ host_entries[i].family, -+ host_entries[i].length, -+ (uint8_t *) host_entries[i].address); - } - -- XSync (slave->priv->server_display, False); -- if (gdm_error_trap_pop ()) { -- g_warning ("Failed to give slave programs access to the display. Trying to proceed."); -+ for (i = 0; i < G_N_ELEMENTS (cookies); i++) { -+ xcb_generic_error_t *xcb_error; -+ -+ xcb_error = xcb_request_check (slave->priv->xcb_connection, cookies[i]); -+ -+ if (xcb_error != NULL) { -+ g_debug ("Failed to give system user '%s' access to the display. Trying to proceed.", host_entries[i].address + sizeof ("localuser")); -+ free (xcb_error); -+ } else { -+ g_debug ("Gave system user '%s' access to the display.", host_entries[i].address + sizeof ("localuser")); -+ } - } - - gdm_slave_set_windowpath (slave); - } else { - g_debug ("GdmSlave: Connected to display %s", slave->priv->display_name); - ret = TRUE; - } - - if (ret) { - g_signal_emit (slave, signals [STARTED], 0); - } - - return ret; - } - - static gboolean - gdm_slave_real_start (GdmSlave *slave) - { - gboolean res; - GError *error; - const char *x11_cookie; - gsize x11_cookie_size; - - g_debug ("GdmSlave: Starting slave"); - - /* cache some values up front */ - error = NULL; - res = gdm_display_is_local (slave->priv->display, &slave->priv->display_is_local, &error); - if (! res) { - g_warning ("Failed to get value: %s", error->message); -@@ -495,104 +455,114 @@ gdm_slave_start (GdmSlave *slave) - g_object_ref (slave); - ret = GDM_SLAVE_GET_CLASS (slave)->start (slave); - g_object_unref (slave); - - return ret; - } - - gboolean - gdm_slave_stop (GdmSlave *slave) - { - gboolean ret; - - g_return_val_if_fail (GDM_IS_SLAVE (slave), FALSE); - - g_debug ("GdmSlave: stopping slave"); - - g_object_ref (slave); - - ret = GDM_SLAVE_GET_CLASS (slave)->stop (slave); - g_signal_emit (slave, signals [STOPPED], 0); - - g_object_unref (slave); - return ret; - } - - gboolean - gdm_slave_add_user_authorization (GdmSlave *slave, - const char *username, - char **filenamep) - { -- XServerInterpretedAddress si_entries[3]; - XHostAddress host_entries[3]; -+ xcb_void_cookie_t cookies[3]; - int i; - gboolean res; - GError *error; - char *filename; - - filename = NULL; - - if (filenamep != NULL) { - *filenamep = NULL; - } - - g_debug ("GdmSlave: Requesting user authorization"); - - error = NULL; - res = gdm_display_add_user_authorization (slave->priv->display, - username, - &filename, - &error); - - if (! res) { - g_warning ("Failed to add user authorization: %s", error->message); - g_error_free (error); - } else { - g_debug ("GdmSlave: Got user authorization: %s", filename); - } - - if (filenamep != NULL) { - *filenamep = g_strdup (filename); - } - g_free (filename); - - /* Remove access for the programs run by slave and greeter now that the - * user session is starting. - */ -- gdm_slave_setup_xhost_auth (host_entries, si_entries); -- gdm_error_trap_push (); -+ gdm_slave_setup_xhost_auth (host_entries); - for (i = 0; i < G_N_ELEMENTS (host_entries); i++) { -- XRemoveHost (slave->priv->server_display, &host_entries[i]); -+ cookies[i] = xcb_change_hosts_checked (slave->priv->xcb_connection, -+ XCB_HOST_MODE_DELETE, -+ host_entries[i].family, -+ host_entries[i].length, -+ (uint8_t *) host_entries[i].address); - } -- XSync (slave->priv->server_display, False); -- if (gdm_error_trap_pop ()) { -- g_warning ("Failed to remove slave program access to the display. Trying to proceed."); -+ -+ for (i = 0; i < G_N_ELEMENTS (cookies); i++) { -+ xcb_generic_error_t *xcb_error; -+ -+ xcb_error = xcb_request_check (slave->priv->xcb_connection, cookies[i]); -+ -+ if (xcb_error != NULL) { -+ g_warning ("Failed to remove greeter program access to the display. Trying to proceed."); -+ free (xcb_error); -+ } - } - - return res; - } - - static char * - gdm_slave_parse_enriched_login (GdmSlave *slave, - const char *username) - { - char **argv; - int username_len; - GPtrArray *env; - GError *error; - gboolean res; - char *parsed_username; - char *command; - char *std_output; - char *std_error; - - parsed_username = NULL; - - if (username == NULL || username[0] == '\0') { - return NULL; - } - - /* A script may be used to generate the automatic/timed login name - based on the display/host by ending the name with the pipe symbol - '|'. */ - - username_len = strlen (username); --- -2.9.3 - - -From 89b3bc7ba5fbfa0948a02644cbe031961435e23d Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 19 Dec 2016 10:56:27 -0500 -Subject: [PATCH 4/5] slave: close display connection when done with it - ---- - daemon/gdm-slave.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c -index c0a53fe..cd26965 100644 ---- a/daemon/gdm-slave.c -+++ b/daemon/gdm-slave.c -@@ -411,60 +411,61 @@ gdm_slave_real_start (GdmSlave *slave) - if (! res) { - g_warning ("Failed to get value: %s", error->message); - g_error_free (error); - return FALSE; - } - - error = NULL; - res = gdm_display_get_seat_id (slave->priv->display, &slave->priv->display_seat_id, &error); - if (! res) { - g_warning ("Failed to get value: %s", error->message); - g_error_free (error); - return FALSE; - } - - error = NULL; - res = gdm_display_is_initial (slave->priv->display, &slave->priv->display_is_initial, &error); - if (! res) { - g_warning ("Failed to get value: %s", error->message); - g_error_free (error); - return FALSE; - } - - return TRUE; - } - - static gboolean - gdm_slave_real_stop (GdmSlave *slave) - { - g_debug ("GdmSlave: Stopping slave"); - -+ g_clear_pointer (&slave->priv->xcb_connection, xcb_disconnect); - g_clear_object (&slave->priv->display); - - return TRUE; - } - - gboolean - gdm_slave_start (GdmSlave *slave) - { - gboolean ret; - - g_return_val_if_fail (GDM_IS_SLAVE (slave), FALSE); - - g_debug ("GdmSlave: starting slave"); - - g_object_ref (slave); - ret = GDM_SLAVE_GET_CLASS (slave)->start (slave); - g_object_unref (slave); - - return ret; - } - - gboolean - gdm_slave_stop (GdmSlave *slave) - { - gboolean ret; - - g_return_val_if_fail (GDM_IS_SLAVE (slave), FALSE); - - g_debug ("GdmSlave: stopping slave"); - --- -2.9.3 - - -From 122433b95dd3e099b300bce97ce1a5c99d7e2ccd Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 20 Jul 2016 17:23:05 -0400 -Subject: [PATCH 5/5] slave: kill off clients from display when finished - -When we're done with the display we need to kill off any clients -that are lingering and close our own connection to the display. - -This is so, for instance, processes from the session don't -stick around on a -noreset Xvnc server (or something) - -https://bugzilla.gnome.org/show_bug.cgi?id=776059 ---- - daemon/gdm-slave.c | 32 +++++++++++++++++++++++++++++--- - 1 file changed, 29 insertions(+), 3 deletions(-) - -diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c -index cd26965..d965d4c 100644 ---- a/daemon/gdm-slave.c -+++ b/daemon/gdm-slave.c -@@ -411,64 +411,90 @@ gdm_slave_real_start (GdmSlave *slave) - if (! res) { - g_warning ("Failed to get value: %s", error->message); - g_error_free (error); - return FALSE; - } - - error = NULL; - res = gdm_display_get_seat_id (slave->priv->display, &slave->priv->display_seat_id, &error); - if (! res) { - g_warning ("Failed to get value: %s", error->message); - g_error_free (error); - return FALSE; - } - - error = NULL; - res = gdm_display_is_initial (slave->priv->display, &slave->priv->display_is_initial, &error); - if (! res) { - g_warning ("Failed to get value: %s", error->message); - g_error_free (error); - return FALSE; - } - - return TRUE; - } - - static gboolean - gdm_slave_real_stop (GdmSlave *slave) - { - g_debug ("GdmSlave: Stopping slave"); - -- g_clear_pointer (&slave->priv->xcb_connection, xcb_disconnect); -- g_clear_object (&slave->priv->display); -+ if (slave->priv->xcb_connection) { -+ const xcb_setup_t *setup; - -- return TRUE; -+ /* These 3 bits are reserved/unused by the X protocol */ -+ guint32 unused_bits = 0b11100000000000000000000000000000; -+ XID highest_client, client; -+ guint32 client_increment; -+ -+ setup = xcb_get_setup (slave->priv->xcb_connection); -+ -+ /* resource_id_mask is the bits given to each client for -+ * addressing resources */ -+ highest_client = (XID) ~unused_bits & ~setup->resource_id_mask; -+ client_increment = setup->resource_id_mask + 1; -+ -+ /* Kill every client but ourselves, then close our own connection -+ */ -+ for (client = 0; -+ client <= highest_client; -+ client += client_increment) { -+ -+ if (client != setup->resource_id_base) -+ xcb_kill_client (slave->priv->xcb_connection, client); -+ } -+ xcb_flush (slave->priv->xcb_connection); -+ g_clear_pointer (&slave->priv->xcb_connection, xcb_disconnect); -+ } -+ g_clear_object (&slave->priv->display); -+ -+ return TRUE; - } - - gboolean - gdm_slave_start (GdmSlave *slave) - { - gboolean ret; - - g_return_val_if_fail (GDM_IS_SLAVE (slave), FALSE); - - g_debug ("GdmSlave: starting slave"); - - g_object_ref (slave); - ret = GDM_SLAVE_GET_CLASS (slave)->start (slave); - g_object_unref (slave); - - return ret; - } - - gboolean - gdm_slave_stop (GdmSlave *slave) - { - gboolean ret; - - g_return_val_if_fail (GDM_IS_SLAVE (slave), FALSE); - - g_debug ("GdmSlave: stopping slave"); - - g_object_ref (slave); - - ret = GDM_SLAVE_GET_CLASS (slave)->stop (slave); --- -2.9.3 - diff --git a/SOURCES/system-dconf.patch b/SOURCES/system-dconf.patch index 54f7781..617817c 100644 --- a/SOURCES/system-dconf.patch +++ b/SOURCES/system-dconf.patch @@ -1,15 +1,15 @@ -From 70f82c5749c14a900b95980118a26eda3a58e654 Mon Sep 17 00:00:00 2001 +From 29d374ce6781df6f3b168a8c57163ddb582c998a Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 31 Jul 2013 17:32:55 -0400 Subject: [PATCH] data: add system dconf databases to gdm profile This way system settings can affect the login screen. --- - data/dconf/gdm.in | 3 +++ - 1 file changed, 3 insertions(+) + data/dconf/gdm.in | 4 ++++ + 1 file changed, 4 insertions(+) diff --git a/data/dconf/gdm.in b/data/dconf/gdm.in -index 4d8bf17..510ca31 100644 +index 4d8bf174..9694078f 100644 --- a/data/dconf/gdm.in +++ b/data/dconf/gdm.in @@ -1,2 +1,6 @@ @@ -20,5 +20,5 @@ index 4d8bf17..510ca31 100644 +system-db:distro file-db:@DATADIR@/@PACKAGE@/greeter-dconf-defaults -- -1.8.3.1 +2.11.1 diff --git a/SPECS/gdm.spec b/SPECS/gdm.spec index 865230f..b340ef4 100644 --- a/SPECS/gdm.spec +++ b/SPECS/gdm.spec @@ -11,60 +11,74 @@ Summary: The GNOME Display Manager Name: gdm -Version: 3.14.2 -Release: 20%{?dist} +Version: 3.22.3 +Release: 11%{?dist} Epoch: 1 License: GPLv2+ Group: User Interface/X URL: http://download.gnome.org/sources/gdm #VCS: git:git://git.gnome.org/gdm -Source: http://download.gnome.org/sources/gdm/3.14/gdm-%{version}.tar.xz +Source: http://download.gnome.org/sources/gdm/3.22/gdm-%{version}.tar.xz Source1: org.gnome.login-screen.gschema.override -Patch0: add-postlogin.patch -Patch1: fix-headless.patch -Patch2: fix-lang-changes.patch -Patch3: audit-4.patch -Patch4: fix-restarts.patch -Patch10: clear-screen.patch -Patch11: fix-post-login.patch -Patch12: fix-language-chooser.patch -Patch13: dont-require-working-rdns.patch -Patch14: notify-xdmcp-about-session-end.patch -Patch15: fix-xdmcp-unlock.patch +Source2: ja.po +Patch0: 0001-Honor-initial-setup-being-disabled-by-distro-install.patch +Patch1: 0001-manager-be-more-robust-against-autologin-having-an-i.patch +Patch2: 0003-launch-environment-fix-crasher-when-session-mode-isn.patch +Patch3: 0004-manager-drop-some-erroneous-code.patch +Patch4: 0005-launch-environment-implement-hostname-selected-signa.patch +Patch5: 0006-manager-fix-up-support-for-chooser.patch +Patch6: 0007-xdmcp-display-don-t-set-MANAGED-until-we-ve-connecte.patch +Patch7: 0008-xdmcp-display-factory-fix-signal-prototype.patch +Patch8: 0009-xdmcp-display-factory-explicitly-stop-greeter-sessio.patch +Patch9: 0010-chooser-fix-duplicate-entry-in-the-list.patch +Patch10: 0011-chooser-make-host-list-fill-the-dialog.patch +Patch11: 0012-chooser-switch-to-browse-selection-mode.patch +Patch12: 0013-chooser-filter-out-duplicate-hostnames.patch + +Patch13: 0001-local-display-factory-add-missing-comma-to-fix-user-.patch + +Patch14: 0001-manager-make-sure-we-end-up-on-a-login-screen.patch +Patch15: 0002-manager-stop-transient-greeter-session-when-done-wit.patch +Patch16: 0001-manager-update-session-id-property-when-reusing-disp.patch + +Patch80: 0001-Revert-session-forward-is-initial-from-display-to-wo.patch +Patch81: 0001-worker-add-compat-patch-to-make-new-worker-work-with.patch + +Patch95: audit-4.patch +Patch96: clear-screen.patch +Patch97: 0001-gdm.conf-custom.in-strip-out-reference-to-wayland.patch Patch98: system-dconf.patch Patch99: classic-session.patch -BuildRequires: pkgconfig(libcanberra-gtk) -BuildRequires: pango-devel >= 0:%{pango_version} -BuildRequires: gtk3-devel >= 0:%{gtk3_version} +BuildRequires: git BuildRequires: pam-devel >= 0:%{pam_version} -BuildRequires: fontconfig >= 0:%{fontconfig_version} BuildRequires: desktop-file-utils >= %{desktop_file_utils_version} BuildRequires: libtool automake autoconf BuildRequires: libattr-devel BuildRequires: gettext BuildRequires: libdmx-devel BuildRequires: audit-libs-devel >= %{libauditver} -BuildRequires: gobject-introspection-devel BuildRequires: autoconf automake libtool BuildRequires: intltool %ifnarch s390 s390x ppc ppc64 BuildRequires: xorg-x11-server-Xorg %endif BuildRequires: nss-devel >= %{nss_version} -BuildRequires: libselinux-devel -BuildRequires: check-devel -BuildRequires: iso-codes-devel -BuildRequires: libxklavier-devel >= 4.0 -BuildRequires: upower-devel >= 0.9.7 -BuildRequires: libXdmcp-devel -BuildRequires: dbus-glib-devel -BuildRequires: GConf2-devel BuildRequires: pkgconfig(accountsservice) >= 0.6.3 -BuildRequires: pkgconfig(libsystemd-login) -BuildRequires: pkgconfig(libsystemd-daemon) +BuildRequires: pkgconfig(check) +BuildRequires: pkgconfig(gobject-introspection-1.0) +BuildRequires: pkgconfig(gtk+-3.0) >= %{gtk3_version} +BuildRequires: pkgconfig(iso-codes) +BuildRequires: pkgconfig(libcanberra-gtk3) +BuildRequires: pkgconfig(libselinux) +BuildRequires: pkgconfig(libsystemd) BuildRequires: pkgconfig(ply-boot-client) +BuildRequires: pkgconfig(systemd) +BuildRequires: pkgconfig(x11) +BuildRequires: pkgconfig(xau) +BuildRequires: libXdmcp-devel BuildRequires: systemd +BuildRequires: keyutils-libs-devel BuildRequires: dconf Requires(pre): /usr/sbin/useradd @@ -81,7 +95,7 @@ Requires: dconf Requires: gnome-keyring-pam Requires: gnome-session Requires: gnome-settings-daemon >= 2.21.92 -Requires: gnome-shell >= 3.14.2 +Requires: gnome-shell Requires: iso-codes # We need 1.0.4-5 since it lets us use "localhost" in auth cookies Requires: libXau >= 1.0.4-4 @@ -118,23 +132,12 @@ The gdm-devel package contains headers and other files needed to build custom greeters. %prep -%setup -q -%patch0 -p1 -b .add-postlogin -%patch1 -p1 -b .fix-headless -%patch2 -p1 -b .fix-lang-changes -%patch3 -p1 -b .audit-4 -%patch4 -p1 -b .fix-restarts -%patch10 -p1 -b .clear-screen -%patch11 -p1 -b .fix-post-login -%patch12 -p1 -b .fix-language-chooser -%patch13 -p1 -b .dont-require-working-rdns -%patch14 -p1 -b .notify-xdmcp-about-session-end -%patch15 -p1 -b .fix-xdmcp-unlock -%patch98 -p1 -b .system-dconf -%patch99 -p1 -b .classic-session - -autoreconf -i -f -intltoolize -f +%autosetup -S git + +cp -f $RPM_SOURCE_DIR/ja.po po + +intltoolize --force --copy --automake +autoreconf --force --install --verbose %build @@ -146,6 +149,7 @@ intltoolize -f --enable-console-helper \ --with-plymouth \ --disable-systemd-journal \ + --disable-user-display-server \ --with-selinux # drop unneeded direct library deps with --as-needed @@ -165,7 +169,7 @@ make install DESTDIR=$RPM_BUILD_ROOT rm -f $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/gdm # add logo to shell greeter -cp $RPM_SOURCE_DIR/org.gnome.login-screen.gschema.override $RPM_BUILD_ROOT%{_datadir}/glib-2.0/schemas +cp %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/glib-2.0/schemas mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/dconf/db/gdm.d/locks @@ -294,13 +298,14 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : %dir %{_sysconfdir}/gdm/PreSession %dir %{_sysconfdir}/gdm/PostSession %dir %{_sysconfdir}/gdm/PostLogin -%{_datadir}/gnome-session/sessions/gdm-shell.session %{_datadir}/pixmaps/*.png %{_datadir}/glib-2.0/schemas/org.gnome.login-screen.gschema.xml %{_datadir}/glib-2.0/schemas/org.gnome.login-screen.gschema.override %{_libexecdir}/gdm-host-chooser %{_libexecdir}/gdm-session-worker %{_libexecdir}/gdm-simple-chooser +%{_libexecdir}/gdm-wayland-session +%{_libexecdir}/gdm-x-session %{_sbindir}/gdm %{_bindir}/gdmflexiserver %{_bindir}/gdm-screenshot @@ -311,6 +316,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : %{_datadir}/gdm/locale.alias %{_datadir}/gdm/gdb-cmd %{_libdir}/girepository-1.0/Gdm-1.0.typelib +%{_libdir}/security/pam_gdm.so %{_libdir}/libgdm*.so* %dir %{_localstatedir}/log/gdm %attr(1770, gdm, gdm) %dir %{_localstatedir}/lib/gdm @@ -332,9 +338,53 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : %{_libdir}/pkgconfig/gdm.pc %changelog -* Fri Mar 17 2017 Ray Strode - 3.14.2-20 -- Fix bug where console user is logged out when XDMCP user logs off - Resolves: #1431662 +* Tue May 30 2017 Ray Strode - 3.22.3-11 +- Add japanese translation + Resolves: #1449632 + +* Fri May 12 2017 Ray Strode - 3.22.3-10 +- Add patches to try to maintain some semblance of compatibility + when live upgrading between 7.3 and 7.4 + Related: #1448786 + +* Thu May 04 2017 Ray Strode - 3.22.3-9 +- Make sure reauthentication is run within the user + session. + Resolves:#1448209 + +* Wed Apr 05 2017 Ray Strode 3.22.3-8 +- Reap transient login screens when they are no longer needed +- Jump to login screen if we end up on a blank VT + Resolves: #1301028 + +* Mon Apr 03 2017 Ray Strode - 3.22.3-7 +- Fix user switching + Related: #1386862 + +* Fri Mar 31 2017 Ray Strode - 3.22.3-6 +- Fix indirect XDMCP + Resolves: #1273156 + +* Thu Mar 16 2017 Ray Strode - 3.22.3-5 +- Attempt to fix po file installation + Related: #1386862 + +* Thu Mar 16 2017 Ray Strode - 3.22.3-4 +- Drop reference to wayland in config file +- use autosetup to simplify spec maintenance + Related: #1386862 + +* Fri Mar 10 2017 Ray Strode - 3.22.3-3 +- Don't fall over if autologin user isn't available + Resolves #1373837 + +* Thu Mar 9 2017 Rui Matos - 1:3.22.3-2 +- Honor anaconda's firstboot being disabled + Resolves: #1226819 + +* Mon Mar 06 2017 Ray Strode - 3.22.3-1 +- Rebase to 3.22.3 + Resolves: #1386862 * Wed Sep 21 2016 Ray Strode - 3.14.2-19 - Add error traps around XKillClient calls, fixes regression